/*! * @fn void corei7_unc_Write_PMU(param) * * @param param dummy parameter which is not used * * @return None No return needed * * @brief Initial set up of the PMU registers * * <I>Special Notes</I> * Initial write of PMU registers. * Walk through the enties and write the value of the register accordingly. * Assumption: For CCCR registers the enable bit is set to value 0. * When current_group = 0, then this is the first time this routine is called, * initialize the locks and set up EM tables. */ static VOID corei7_unc_Write_PMU ( VOID *param ) { U32 dev_idx = *((U32*)param); FOR_EACH_REG_ENTRY_UNC(pecb_unc, dev_idx, i) { /* * Writing the GLOBAL Control register enables the PMU to start counting. * So write 0 into the register to prevent any counting from starting. */ if (ECB_entries_reg_id(pecb_unc,i) == UNC_UCLK_PERF_GLOBAL_CTRL) { SYS_Write_MSR(ECB_entries_reg_id(pecb_unc,i), 0LL); continue; } SYS_Write_MSR(ECB_entries_reg_id(pecb_unc,i), ECB_entries_reg_value(pecb_unc,i)); #if defined(MYDEBUG) SEP_PRINT_DEBUG("corei7_UNC_Write_PMU Event_Data_reg = 0x%x --- value 0x%llx\n", ECB_entries_reg_id(pecb_unc,i), ECB_entries_reg_value(pecb_unc,i)); #endif // this is needed for overflow detection of the accumulators. if (LWPMU_DEVICE_counter_mask(&devices[dev_idx]) == 0) { LWPMU_DEVICE_counter_mask(&devices[dev_idx]) = (U64)ECB_entries_max_bits(pecb_unc,i); } } END_FOR_EACH_REG_ENTRY_UNC; return; }
/****************************************************************************************** * @fn static VOID unc_power_snb_Write_PMU(VOID*) * * @brief No registers to write and setup the accumalators with initial values * * @return None * * <I>Special Notes:</I> ******************************************************************************************/ static VOID unc_power_snb_Write_PMU ( VOID *param ) { U32 dev_idx = *((U32*)param); U64 tmp_value = 0; U32 j; U32 event_id = 0; FOR_EACH_REG_ENTRY_UNC(pecb, dev_idx, i) { for ( j = 0; j < (U32)GLOBAL_STATE_num_cpus(driver_state); j++) { tmp_value = SYS_Read_MSR(ECB_entries_reg_id(pecb,i)) & SNB_POWER_MSR_DATA_MASK; LWPMU_DEVICE_prev_val_per_thread(&devices[dev_idx])[j][event_id + 1] = tmp_value; // need to account for group id } // Initialize counter_mask for accumulators if (LWPMU_DEVICE_counter_mask(&devices[dev_idx]) == 0) { LWPMU_DEVICE_counter_mask(&devices[dev_idx]) = (U64)ECB_entries_max_bits(pecb,i); } } END_FOR_EACH_REG_ENTRY_UNC; return; }
/*! * @fn static VOID snbunc_imc_Write_PMU(VOID*) * * @brief Initial write of PMU registers * Walk through the enties and write the value of the register accordingly. * When current_group = 0, then this is the first time this routine is called, * * @param None * * @return None * * <I>Special Notes:</I> */ static VOID snbunc_imc_Write_PMU ( VOID *param ) { DRV_PCI_DEVICE_ENTRY_NODE dpden; U32 pci_address; U32 bar_lo; U64 next_bar_offset; U64 bar_hi; U64 physical_address; U64 final_bar; U32 dev_idx = *((U32*)param); ECB pecb = LWPMU_DEVICE_PMU_register_data(&devices[(dev_idx)])[0]; U32 j; U32 event_id = 0; U32 offset_delta; U32 tmp_value; int me = CONTROL_THIS_CPU(); if (me != invoking_processor_id) { return; } SEP_PRINT_DEBUG("snbunc_imc_Write_PMU Enter\n"); dpden = ECB_pcidev_entry_node(pecb); pci_address = FORM_PCI_ADDR(DRV_PCI_DEVICE_ENTRY_bus_no(&dpden), DRV_PCI_DEVICE_ENTRY_dev_no(&dpden), DRV_PCI_DEVICE_ENTRY_func_no(&dpden), 0); #if defined(MYDEBUG) { U32 device_id = PCI_Read_Ulong(pci_address); SEP_PRINT("Bus no = 0x%x\n",DRV_PCI_DEVICE_ENTRY_bus_no(&dpden)); SEP_PRINT("Dev no = 0x%x\n",DRV_PCI_DEVICE_ENTRY_dev_no(&dpden)); SEP_PRINT("Func no = 0x%x\n",DRV_PCI_DEVICE_ENTRY_func_no(&dpden)); SEP_PRINT("value for device id = 0x%x\n",device_id); } #endif pci_address = FORM_PCI_ADDR(DRV_PCI_DEVICE_ENTRY_bus_no(&dpden), DRV_PCI_DEVICE_ENTRY_dev_no(&dpden), DRV_PCI_DEVICE_ENTRY_func_no(&dpden), DRV_PCI_DEVICE_ENTRY_bar_offset(&dpden)); bar_lo = PCI_Read_Ulong(pci_address); next_bar_offset = DRV_PCI_DEVICE_ENTRY_bar_offset(&dpden) + NEXT_ADDR_OFFSET; pci_address = FORM_PCI_ADDR(DRV_PCI_DEVICE_ENTRY_bus_no(&dpden), DRV_PCI_DEVICE_ENTRY_dev_no(&dpden), DRV_PCI_DEVICE_ENTRY_func_no(&dpden), next_bar_offset); bar_hi = PCI_Read_Ulong(pci_address); final_bar = (bar_hi << SNBUNC_IMC_BAR_ADDR_SHIFT) | bar_lo; final_bar &= SNBUNC_IMC_BAR_ADDR_MASK; DRV_PCI_DEVICE_ENTRY_bar_address(&ECB_pcidev_entry_node(pecb)) = final_bar; physical_address = DRV_PCI_DEVICE_ENTRY_bar_address(&ECB_pcidev_entry_node(pecb)) + DRV_PCI_DEVICE_ENTRY_base_offset_for_mmio(&ECB_pcidev_entry_node(pecb)); virtual_address = ioremap_nocache(physical_address,4096); //Read in the counts into temporary buffer FOR_EACH_PCI_DATA_REG(pecb,i,dev_idx,offset_delta) { event_id = ECB_entries_event_id_index_local(pecb,i); tmp_value = readl((U32*)((char*)(virtual_address) + offset_delta)); for ( j = 0; j < (U32)GLOBAL_STATE_num_cpus(driver_state) ; j++) { LWPMU_DEVICE_prev_val_per_thread(&devices[dev_idx])[j][event_id + 1] = tmp_value; // need to account for group id #if defined(MYDEBUG) SEP_PRINT_DEBUG("initial value for i =%d is 0x%x\n",i,LWPMU_DEVICE_prev_val_per_thread(&devices[dev_idx])[j][i]); #endif } // this is needed for overflow detection of the accumulators. if (LWPMU_DEVICE_counter_mask(&devices[dev_idx]) == 0) { LWPMU_DEVICE_counter_mask(&devices[dev_idx]) = (U64)ECB_entries_max_bits(pecb,i); } } END_FOR_EACH_PCI_DATA_REG;