void nhm_cpu::measurement_start(void) { ifstream file; char filename[4096]; cpu_linux::measurement_start(); last_stamp = 0; aperf_before = get_msr(number, MSR_APERF); mperf_before = get_msr(number, MSR_MPERF); tsc_before = get_msr(number, MSR_TSC); insert_cstate("active", _("C0 active"), 0, aperf_before, 1); sprintf(filename, "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", first_cpu); file.open(filename, ios::in); if (file) { char line[1024]; while (file) { uint64_t f; file.getline(line, 1024); f = strtoull(line, NULL, 10); account_freq(f, 0); } file.close(); } account_freq(0, 0); }
int interrupt_init(void) { int ret; /* call cpu specific function from $(CPU)/interrupts.c */ ret = interrupt_init_cpu(&decrementer_count); if (ret) return ret; decrementer_count = get_tbclk() / CFG_HZ; debug("interrupt init: tbclk() = %d MHz, decrementer_count = %d\n", (get_tbclk() / 1000000), decrementer_count); set_dec(decrementer_count); set_msr(get_msr() | MSR_EE); debug("MSR = 0x%08lx, Decrementer reg = 0x%08lx\n", get_msr(), get_dec()); return 0; }
void nhm_cpu::measurement_end(void) { uint64_t time_delta; double ratio; unsigned int i; aperf_after = get_msr(number, MSR_APERF); mperf_after = get_msr(number, MSR_MPERF); tsc_after = get_msr(number, MSR_TSC); finalize_cstate("active", 0, aperf_after, 1); cpu_linux::measurement_end(); time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; ratio = 1.0 * time_delta / (tsc_after - tsc_before); for (i = 0; i < cstates.size(); i++) { struct idle_state *state = cstates[i]; if (state->line_level != LEVEL_C0) continue; state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; } total_stamp = 0; }
void nhm_package::measurement_start(void) { abstract_cpu::measurement_start(); last_stamp = 0; if (this->has_c2c7_res) c2_before = get_msr(number, MSR_PKG_C2_RESIDENCY); if (this->has_c3_res) c3_before = get_msr(number, MSR_PKG_C3_RESIDENCY); c6_before = get_msr(number, MSR_PKG_C6_RESIDENCY); if (this->has_c2c7_res) c7_before = get_msr(number, MSR_PKG_C7_RESIDENCY); if (this->has_c8c9c10_res) { c8_before = get_msr(number, MSR_PKG_C8_RESIDENCY); c9_before = get_msr(number, MSR_PKG_C9_RESIDENCY); c10_before = get_msr(number, MSR_PKG_C10_RESIDENCY); } tsc_before = get_msr(first_cpu, MSR_TSC); if (this->has_c2c7_res) insert_cstate("pkg c2", "C2 (pc2)", 0, c2_before, 1); if (this->has_c3_res) insert_cstate("pkg c3", "C3 (pc3)", 0, c3_before, 1); insert_cstate("pkg c6", "C6 (pc6)", 0, c6_before, 1); if (this->has_c2c7_res) insert_cstate("pkg c7", "C7 (pc7)", 0, c7_before, 1); if (this->has_c8c9c10_res) { insert_cstate("pkg c8", "C8 (pc8)", 0, c8_before, 1); insert_cstate("pkg c9", "C9 (pc9)", 0, c9_before, 1); insert_cstate("pkg c10", "C10 (pc10)", 0, c10_before, 1); } }
/* returns flag if MSR_EE was set before */ int disable_interrupts (void) { ulong msr = get_msr (); set_msr (msr & ~MSR_EE); return ((msr & MSR_EE) != 0); }
void nhm_core::measurement_start(void) { ifstream file; char filename[PATH_MAX]; /* the abstract function needs to be first since it clears all state */ abstract_cpu::measurement_start(); last_stamp = 0; if (this->has_c1_res) c1_before = get_msr(first_cpu, MSR_CORE_C1_RESIDENCY); if (this->has_c3_res) c3_before = get_msr(first_cpu, MSR_CORE_C3_RESIDENCY); c6_before = get_msr(first_cpu, MSR_CORE_C6_RESIDENCY); if (this->has_c7_res) c7_before = get_msr(first_cpu, MSR_CORE_C7_RESIDENCY); tsc_before = get_msr(first_cpu, MSR_TSC); if (this->has_c1_res) insert_cstate("core c1", "C1 (cc1)", 0, c1_before, 1); if (this->has_c3_res) insert_cstate("core c3", "C3 (cc3)", 0, c3_before, 1); insert_cstate("core c6", "C6 (cc6)", 0, c6_before, 1); if (this->has_c7_res) { insert_cstate("core c7", "C7 (cc7)", 0, c7_before, 1); } snprintf(filename, sizeof(filename), "/sys/devices/system/cpu/cpu%i/cpufreq/stats/time_in_state", first_cpu); file.open(filename, ios::in); if (file) { char line[1024]; while (file) { uint64_t f; file.getline(line, 1024); f = strtoull(line, NULL, 10); account_freq(f, 0); } file.close(); } account_freq(0, 0); }
/*----------------------------------------------------------------------- */ void flash_reset (void) { unsigned long msr; DWORD cmd_reset = 0x00F000F000F000F0LL; if (flash_info[0].flash_id != FLASH_UNKNOWN) { msr = get_msr (); set_msr (msr | MSR_FP); write_via_fpu ((DWORD*)flash_info[0].start[0], &cmd_reset ); set_msr (msr); } }
int interrupt_init (void) { int ret; /* call cpu specific function from $(CPU)/interrupts.c */ ret = interrupt_init_cpu (&decrementer_count); if (ret) return ret; set_dec (decrementer_count); set_msr (get_msr () | MSR_EE); return (0); }
void init_mmu(void) { uint32_t msr; int n; /* switch to ts == 1 if ts == 0 else bail*/ msr = get_msr(); if (msr & (MSR_IS|MSR_DS)) { return ; } /* setup a valid ts1 entry and switch ts*/ write_tlb1_entry(TMP_ENTRY, TS1, 0x00000000, SIZE_256MB, FULL_SUPER, 0); write_tlb1_entry(TMP_ENTRY+1, TS1, 0x40000000, SIZE_256KB, FULL_SUPER, 0); sync(); set_msr(msr | MSR_IS | MSR_DS); isync(); for (n = 0; tlb[n].base != LAST_ENTRY; n++) { write_tlb1_entry(n, TS0, tlb[n].base, tlb[n].size, tlb[n].prot, tlb[n].wimge); } /* invalidate the rest of the entries */ for (; n < 16; n++) { if (n != TMP_ENTRY) { invalidate_tlb1_entry(n); } } /* switch back to ts == 0 */ sync(); set_msr(msr); isync(); invalidate_tlb1_entry(TMP_ENTRY); invalidate_tlb1_entry(TMP_ENTRY+1); sync(); /* invalidate cache */ set_l1csr0(L1CSRX_CFI); while (get_l1csr0() & L1CSRX_CFI) { ; } /* enable */ set_l1csr0(L1CSRX_CE); }
ac_bool test_apic() { ac_bool error = AC_FALSE; initialize_apic(); ac_u64 msr_apic_base = get_msr(MSR_IA32_APIC_BASE); error |= AC_TEST(msr_apic_base != 0); ac_printf("msr_apic_base=0x%llx\n",msr_apic_base); ac_printf(" bsp=%d\n", AC_GET_BITS(ac_u32, msr_apic_base, 8, 1)); ac_printf(" extd=%d\n", AC_GET_BITS(ac_u32, msr_apic_base, 10, 1)); ac_printf(" e=%d\n", AC_GET_BITS(ac_u32, msr_apic_base, 11, 1)); ac_u64 phy_addr = apic_get_physical_addr(); ac_printf(" phy_addr=0x%llx\n", phy_addr); error |= AC_TEST(phy_addr != 0); ac_u32 local_id = apic_get_id(); ac_printf(" local_id=0x%x\n", local_id); return error; }
void nhm_package::measurement_end(void) { uint64_t time_delta; double ratio; unsigned int i, j; for (i = 0; i < children.size(); i++) if (children[i]) children[i]->wiggle(); if (this->has_c2c7_res) c2_after = get_msr(number, MSR_PKG_C2_RESIDENCY); if (this->has_c3_res) c3_after = get_msr(number, MSR_PKG_C3_RESIDENCY); c6_after = get_msr(number, MSR_PKG_C6_RESIDENCY); if (this->has_c2c7_res) c7_after = get_msr(number, MSR_PKG_C7_RESIDENCY); if (has_c8c9c10_res) { c8_after = get_msr(number, MSR_PKG_C8_RESIDENCY); c9_after = get_msr(number, MSR_PKG_C9_RESIDENCY); c10_after = get_msr(number, MSR_PKG_C10_RESIDENCY); } tsc_after = get_msr(first_cpu, MSR_TSC); gettimeofday(&stamp_after, NULL); time_factor = 1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; if (this->has_c2c7_res) finalize_cstate("pkg c2", 0, c2_after, 1); if (this->has_c3_res) finalize_cstate("pkg c3", 0, c3_after, 1); finalize_cstate("pkg c6", 0, c6_after, 1); if (this->has_c2c7_res) finalize_cstate("pkg c7", 0, c7_after, 1); if (has_c8c9c10_res) { finalize_cstate("pkg c8", 0, c8_after, 1); finalize_cstate("pkg c9", 0, c9_after, 1); finalize_cstate("pkg c10", 0, c10_after, 1); } for (i = 0; i < children.size(); i++) if (children[i]) children[i]->measurement_end(); time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; ratio = 1.0 * time_delta / (tsc_after - tsc_before); for (i = 0; i < cstates.size(); i++) { struct idle_state *state = cstates[i]; if (state->after_count == 0) { cout << "after count is 0\n"; continue; } if (state->after_count != state->before_count) { cout << "count mismatch\n"; continue; } state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; } for (i = 0; i < children.size(); i++) if (children[i]) { for (j = 0; j < children[i]->pstates.size(); j++) { struct frequency *state; state = children[i]->pstates[j]; if (!state) continue; update_pstate( state->freq, state->human_name, state->time_before, state->before_count); finalize_pstate(state->freq, state->time_after, state->after_count); } } total_stamp = 0; }
/*----------------------------------------------------------------------- */ ulong flash_get_size (ulong baseaddr, flash_info_t * info) { int i; unsigned long msr; DWORD flashtest; DWORD cmd_select[3] = { 0x00AA00AA00AA00AALL, 0x0055005500550055LL, 0x0090009000900090LL }; /* Enable FPU */ msr = get_msr (); set_msr (msr | MSR_FP); /* Write auto-select command sequence */ write_via_fpu ((DWORD*)(baseaddr + (0x0555 << 3)), &cmd_select[0] ); write_via_fpu ((DWORD*)(baseaddr + (0x02AA << 3)), &cmd_select[1] ); write_via_fpu ((DWORD*)(baseaddr + (0x0555 << 3)), &cmd_select[2] ); /* Restore FPU */ set_msr (msr); /* Read manufacturer ID */ flashtest = *(volatile DWORD*)baseaddr; switch ((int)flashtest) { case AMD_MANUFACT: info->flash_id = FLASH_MAN_AMD; break; case FUJ_MANUFACT: info->flash_id = FLASH_MAN_FUJ; break; default: /* No, faulty or unknown flash */ info->flash_id = FLASH_UNKNOWN; info->sector_count = 0; info->size = 0; return (0); } /* Read device ID */ flashtest = *(volatile DWORD*)(baseaddr + 8); switch ((long)flashtest) { case AMD_ID_LV800T: info->flash_id += FLASH_AM800T; info->sector_count = 19; info->size = 0x00400000; break; case AMD_ID_LV800B: info->flash_id += FLASH_AM800B; info->sector_count = 19; info->size = 0x00400000; break; case AMD_ID_LV160T: info->flash_id += FLASH_AM160T; info->sector_count = 35; info->size = 0x00800000; break; case AMD_ID_LV160B: info->flash_id += FLASH_AM160B; info->sector_count = 35; info->size = 0x00800000; break; case AMD_ID_DL322T: info->flash_id += FLASH_AMDL322T; info->sector_count = 71; info->size = 0x01000000; break; case AMD_ID_DL322B: info->flash_id += FLASH_AMDL322B; info->sector_count = 71; info->size = 0x01000000; break; case AMD_ID_DL323T: info->flash_id += FLASH_AMDL323T; info->sector_count = 71; info->size = 0x01000000; break; case AMD_ID_DL323B: info->flash_id += FLASH_AMDL323B; info->sector_count = 71; info->size = 0x01000000; break; case AMD_ID_LV640U: info->flash_id += FLASH_AM640U; info->sector_count = 128; info->size = 0x02000000; break; default: /* Unknown flash type */ info->flash_id = FLASH_UNKNOWN; return (0); } if ((long)flashtest == AMD_ID_LV640U) { /* set up sector start adress table (uniform sector type) */ for (i = 0; i < info->sector_count; i++) info->start[i] = baseaddr + (i * 0x00040000); } else if (info->flash_id & FLASH_BTYPE) { /* set up sector start adress table (bottom sector type) */ info->start[0] = baseaddr + 0x00000000; info->start[1] = baseaddr + 0x00010000; info->start[2] = baseaddr + 0x00018000; info->start[3] = baseaddr + 0x00020000; for (i = 4; i < info->sector_count; i++) { info->start[i] = baseaddr + (i * 0x00040000) - 0x000C0000; } } else { /* set up sector start adress table (top sector type) */ i = info->sector_count - 1; info->start[i--] = baseaddr + info->size - 0x00010000; info->start[i--] = baseaddr + info->size - 0x00018000; info->start[i--] = baseaddr + info->size - 0x00020000; for (; i >= 0; i--) { info->start[i] = baseaddr + i * 0x00040000; } } /* check for protected sectors */ for (i = 0; i < info->sector_count; i++) { /* read sector protection at sector address, (A7 .. A0) = 0x02 */ if (*(volatile DWORD*)(info->start[i] + 16) & 0x0001000100010001LL) { info->protect[i] = 1; /* D0 = 1 if protected */ } else { info->protect[i] = 0; } } flash_reset (); return (info->size); }
void enable_interrupts (void) { set_msr (get_msr () | MSR_EE); }
void nhm_core::measurement_end(void) { unsigned int i; uint64_t time_delta; double ratio; if (this->has_c1_res) c1_after = get_msr(first_cpu, MSR_CORE_C1_RESIDENCY); if (this->has_c3_res) c3_after = get_msr(first_cpu, MSR_CORE_C3_RESIDENCY); c6_after = get_msr(first_cpu, MSR_CORE_C6_RESIDENCY); if (this->has_c7_res) c7_after = get_msr(first_cpu, MSR_CORE_C7_RESIDENCY); tsc_after = get_msr(first_cpu, MSR_TSC); if (this->has_c1_res) finalize_cstate("core c1", 0, c1_after, 1); if (this->has_c3_res) finalize_cstate("core c3", 0, c3_after, 1); finalize_cstate("core c6", 0, c6_after, 1); if (this->has_c7_res) finalize_cstate("core c7", 0, c7_after, 1); gettimeofday(&stamp_after, NULL); time_factor = 1000000.0 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; for (i = 0; i < children.size(); i++) if (children[i]) { children[i]->measurement_end(); children[i]->wiggle(); } time_delta = 1000000 * (stamp_after.tv_sec - stamp_before.tv_sec) + stamp_after.tv_usec - stamp_before.tv_usec; ratio = 1.0 * time_delta / (tsc_after - tsc_before); for (i = 0; i < cstates.size(); i++) { struct idle_state *state = cstates[i]; if (state->after_count == 0) { cout << "after count is 0\n"; continue; } if (state->after_count != state->before_count) { cout << "count mismatch\n"; continue; } state->usage_delta = ratio * (state->usage_after - state->usage_before) / state->after_count; state->duration_delta = ratio * (state->duration_after - state->duration_before) / state->after_count; } #if 0 for (i = 0; i < children.size(); i++) if (children[i]) { for (j = 0; j < children[i]->pstates.size(); j++) { struct frequency *state; state = children[i]->pstates[j]; if (!state) continue; update_pstate( state->freq, state->human_name, state->time_before, state->before_count); finalize_pstate(state->freq, state->time_after, state->after_count); } } #endif total_stamp = 0; }