From a74a8ffa0702a05eadf92605e77bc8c9a86b377a Mon Sep 17 00:00:00 2001 From: Marc Jones Date: Tue, 22 Apr 2008 23:32:56 +0000 Subject: [PATCH] Clean up and remove late initialization code that is no longer needed. Pstate intialization has moved to early init because it requires a warm reset. Add CPUID setup and disable SMM access to late initialization. Much of this code is leftover from porting from K8. Signed-off-by: Marc Jones Acked-by: Stefan Reinauer git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3252 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/cpu/amd/model_10xxx/Config.lb | 1 - src/cpu/amd/model_10xxx/fidvid_common.c | 312 -------------- src/cpu/amd/model_10xxx/model_10xxx_init.c | 343 +--------------- src/cpu/amd/model_10xxx/pstate.c | 456 --------------------- 4 files changed, 16 insertions(+), 1096 deletions(-) delete mode 100644 src/cpu/amd/model_10xxx/fidvid_common.c delete mode 100644 src/cpu/amd/model_10xxx/pstate.c diff --git a/src/cpu/amd/model_10xxx/Config.lb b/src/cpu/amd/model_10xxx/Config.lb index cf651e052b..406722eaf5 100644 --- a/src/cpu/amd/model_10xxx/Config.lb +++ b/src/cpu/amd/model_10xxx/Config.lb @@ -37,4 +37,3 @@ dir /cpu/amd/microcode driver model_10xxx_init.o object update_microcode.o object apic_timer.o -object pstate.o diff --git a/src/cpu/amd/model_10xxx/fidvid_common.c b/src/cpu/amd/model_10xxx/fidvid_common.c deleted file mode 100644 index aa82323b97..0000000000 --- a/src/cpu/amd/model_10xxx/fidvid_common.c +++ /dev/null @@ -1,312 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - - -#include - - -static u32 get_vstime(u32 nodeid, u32 slam) -{ - u32 val; - u32 v; - device_t dev; - -#if defined(__ROMCC__) - dev = NODE_PCI(nodeid, 3); -#else - dev = get_node_pci(nodeid, 3); -#endif - - val = pci_read_config32(dev, 0xd8); - - val >>= slam?0:4; - val &= 7; - - switch (val) { - case 4: v = 60; break; - case 5: v = 100; break; - case 6: v = 200; break; - case 7: v = 500; break; - default: - v = (val+1)*10; // in us - } - - return v; -} - -static void udelay_tsc(u32 us) -{ - /* Use TSC to delay because it is fixed, ie. it will not changed with p-states. - * Also, We use the APIC TIMER register is to hold flags for AP init. - */ - u32 dword; - tsc_t tsc, tsc1, tscd; - u32 d = 0x00000200; //800Mhz or 200Mhz or 1.6G or get the NBFID at first - u32 dn = 0x1000000/2; // howmany us need to use hi - - tscd.hi = us/dn; - tscd.lo = (us - tscd.hi * dn) * d; - - tsc1 = rdtsc(); - dword = tsc1.lo + tscd.lo; - if((dwordtsc1.hi) || ((tsc.hi==tsc1.hi) && (tsc.lo>tsc1.lo))); - -} - -#ifdef __ROMCC__ -void udelay(u32 usecs) -{ - udelay_tsc(usecs); -} -#endif - -static u32 set_vid(u32 newvid, u32 bit_offset, u32 nodeid, u32 coreid) -{ - u32 val; - msr_t msr; - u32 curvid; - u32 slam; - u32 delay; - u32 count = 3; - device_t dev; - - msr = rdmsr(0xc0010071);//status - curvid = (msr.lo >> bit_offset) & 0x7f; // seven bits - - if(newvid == curvid) return curvid; - -#if defined(__ROMCC__) - dev = NODE_PCI(nodeid, 3); -#else - dev = get_node_pci(nodeid, 3); -#endif - - val = pci_read_config32(dev, 0xa0); - - slam = (val >> 29) & 1; - delay = get_vstime(nodeid, slam); - - if(!slam) { - if(curvid>newvid) { - count = (curvid - newvid) * 2; - } else { - count = (newvid - curvid) * 2; - } - } - - while(count-->0) { - if(slam) { - curvid = newvid; - } - else { //ramp - if(curvid>newvid) { - curvid--; - } else { - curvid++; - } - } - - msr = rdmsr(0xc0010070); //control - msr.lo &= ~(0x7f<> bit_offset) & 0x7f; // seven bits - - if(curvid == newvid) break; - - } - - return curvid; -} - - -static u32 set_nb_vid(u32 newvid, u32 nodeid, u32 coreid) -{ - return set_vid(newvid, 25, nodeid, coreid); -} - - -static u32 set_core_vid(u32 newvid, u32 nodeid, u32 coreid) -{ - return set_vid(newvid, 9, nodeid, coreid); -} - - -static unsigned set_cof(u32 val, u32 mask, u32 nodeid, u32 coreid) -{ - msr_t msr; - int count = 3; - - val &= mask; - - // FIXME: What is count for? Why 3 times? What about node and core id? - while(count-- > 0) { - - msr = rdmsr(0xc0010071); - msr.lo &= mask; - if(msr.lo == val) break; - - msr = rdmsr(0xc0010070); - msr.lo &= ~(mask); - msr.lo |= val; - wrmsr(0xc0010070, msr); - } - - return msr.lo; -} - -static u32 set_core_cof(u32 fid, u32 did, u32 nodeid, u32 coreid) -{ - u32 val; - u32 mask; - - mask = (7<<6) | 0x3f; - val = ((did & 7)<<6) | (fid & 0x3f); - - return set_cof(val, mask, nodeid, coreid); - -} - - -static u32 set_nb_cof(u32 did, u32 nodeid, u32 coreid) // fid need warmreset -{ - u32 val; - u32 mask; - - mask = 1<<22; - val = (did & 1)<<22; - - return set_cof(val, mask, nodeid, coreid); - -} - - -/* set vid and cof for core and nb after warm reset is not started by BIOS */ -static void set_core_nb_max_pstate_after_other_warm_reset(u32 nodeid, u32 coreid) // P0 -{ - msr_t msr; - u32 val; - u32 vid; - u32 mask; - u32 did; - device_t dev; - - msr = rdmsr(0xc0010064); - -#if defined(__ROMCC__) - dev = NODE_PCI(nodeid, 3); -#else - dev = get_node_pci(nodeid, 3); -#endif - - val = pci_read_config32(dev, 0xa0); - if((val>>8) & 1) { // PVI - vid = (msr.lo >> 25) & 0x7f; - } else { //SVI - vid = (msr.lo >> 9) & 0x7f; - } - set_core_vid(vid, nodeid, coreid); - - mask = (0x7<<6) | 0x3f; - val = msr.lo & mask; - set_cof(val, mask, nodeid, coreid); - - //set nb cof and vid - did = (msr.lo >> 22) & 1; - vid = (msr.lo >> 25) & 0x7f; - if(did) { - set_nb_cof(did, nodeid, coreid); - set_nb_vid(vid, nodeid, coreid); - } else { - set_nb_vid(vid, nodeid, coreid); - set_nb_cof(did, nodeid, coreid); - } - - //set the p state - msr.hi = 0; - msr.lo = 0; - wrmsr(0xc0010062, msr); - -} - - -/* set vid and cof for core and nb after warm reset is not started by BIOS */ -static void set_core_nb_min_pstate_after_other_warm_reset(u32 nodeid, u32 coreid) // Px -{ - msr_t msr; - u32 val; - u32 vid; - u32 mask; - u32 did; - u32 pstate; - device_t dev; - -#if defined(__ROMCC__) - dev = NODE_PCI(nodeid, 3); -#else - dev = get_node_pci(nodeid, 3); -#endif - - - val = pci_read_config32(dev, 0xdc); //PstateMaxVal - - pstate = (val >> 8) & 0x7; - - msr = rdmsr(0xc0010064 + pstate); - - mask = (7<<6) | 0x3f; - val = msr.lo & mask; - set_cof(val, mask, nodeid, coreid); - - val = pci_read_config32(dev, 0xa0); - if((val>>8) & 1) { // PVI - vid = (msr.lo>>25) & 0x7f; - } else { //SVI - vid = (msr.lo>>9) & 0x7f; - } - set_core_vid(vid, nodeid, coreid); - - //set nb cof and vid - did = (msr.lo >> 22) & 1; - vid = (msr.lo >> 25) & 0x7f; - if(did) { - set_nb_cof(did, nodeid, coreid); - set_nb_vid(vid, nodeid, coreid); - } else { - set_nb_vid(vid, nodeid, coreid); - set_nb_cof(did, nodeid, coreid); - } - - //set the p state - msr.hi = 0; - msr.lo = pstate; - wrmsr(0xc0010062, msr); -} diff --git a/src/cpu/amd/model_10xxx/model_10xxx_init.c b/src/cpu/amd/model_10xxx/model_10xxx_init.c index 697ab0382c..bf40458c3c 100644 --- a/src/cpu/amd/model_10xxx/model_10xxx_init.c +++ b/src/cpu/amd/model_10xxx/model_10xxx_init.c @@ -35,28 +35,13 @@ #include #include #include - #include - #include -extern void prep_pstates_all(void); -extern void init_pstates(device_t dev, u32 nodeid, u32 coreid); extern device_t get_node_pci(u32 nodeid, u32 fn); -void cpus_ready_for_init(void) -{ - prep_pstates_all(); -#if MEM_TRAIN_SEQ == 1 - struct sys_info *sysinfox = (struct sys_info *)((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_GLOBAL_VAR_SIZE); - // wait for ap memory to trained - wait_all_core0_mem_trained(sysinfox); -#endif -} - - #define MCI_STATUS 0x401 @@ -82,304 +67,18 @@ static inline void wrmsr_amd(u32 index, msr_t msr) } -#define MTRR_COUNT 8 -#define ZERO_CHUNK_KB 0x800UL /* 2M */ -#define TOLM_KB 0x400000UL - -struct mtrr { - msr_t base; - msr_t mask; -}; - - -struct mtrr_state { - struct mtrr mtrrs[MTRR_COUNT]; - msr_t top_mem, top_mem2; - msr_t def_type; -}; - - -static void save_mtrr_state(struct mtrr_state *state) -{ - int i; - for(i = 0; i < MTRR_COUNT; i++) { - state->mtrrs[i].base = rdmsr(MTRRphysBase_MSR(i)); - state->mtrrs[i].mask = rdmsr(MTRRphysMask_MSR(i)); - } - state->top_mem = rdmsr(TOP_MEM); - state->top_mem2 = rdmsr(TOP_MEM2); - state->def_type = rdmsr(MTRRdefType_MSR); -} - - -static void restore_mtrr_state(struct mtrr_state *state) -{ - int i; - disable_cache(); - - for(i = 0; i < MTRR_COUNT; i++) { - wrmsr(MTRRphysBase_MSR(i), state->mtrrs[i].base); - wrmsr(MTRRphysMask_MSR(i), state->mtrrs[i].mask); - } - wrmsr(TOP_MEM, state->top_mem); - wrmsr(TOP_MEM2, state->top_mem2); - wrmsr(MTRRdefType_MSR, state->def_type); - - enable_cache(); -} - - -#if 0 -static void print_mtrr_state(struct mtrr_state *state) -{ - int i; - for(i = 0; i < MTRR_COUNT; i++) { - printk_debug("var mtrr %d: %08x%08x mask: %08x%08x\n", - i, - state->mtrrs[i].base.hi, state->mtrrs[i].base.lo, - state->mtrrs[i].mask.hi, state->mtrrs[i].mask.lo); - } - printk_debug("top_mem: %08x%08x\n", - state->top_mem.hi, state->top_mem.lo); - printk_debug("top_mem2: %08x%08x\n", - state->top_mem2.hi, state->top_mem2.lo); - printk_debug("def_type: %08x%08x\n", - state->def_type.hi, state->def_type.lo); -} -#endif - - -static void set_init_ecc_mtrrs(void) -{ - msr_t msr; - int i; - disable_cache(); - - /* First clear all of the msrs to be safe */ - for(i = 0; i < MTRR_COUNT; i++) { - msr_t zero; - zero.lo = zero.hi = 0; - wrmsr(MTRRphysBase_MSR(i), zero); - wrmsr(MTRRphysMask_MSR(i), zero); - } - - /* Write back cache the first 1MB */ - msr.hi = 0x00000000; - msr.lo = 0x00000000 | MTRR_TYPE_WRBACK; - wrmsr(MTRRphysBase_MSR(0), msr); - msr.hi = 0x000000ff; - msr.lo = ~((CONFIG_LB_MEM_TOPK << 10) - 1) | 0x800; - wrmsr(MTRRphysMask_MSR(0), msr); - - /* Set the default type to write combining */ - msr.hi = 0x00000000; - msr.lo = 0xc00 | MTRR_TYPE_WRCOMB; - wrmsr(MTRRdefType_MSR, msr); - - /* Set TOP_MEM to 4G */ - msr.hi = 0x00000001; - msr.lo = 0x00000000; - wrmsr(TOP_MEM, msr); - - enable_cache(); -} - - -static inline void clear_2M_ram(unsigned long basek, struct mtrr_state *mtrr_state) -{ - unsigned long limitk; - unsigned long size; - void *addr; - - /* Report every 64M */ - if ((basek % (64*1024)) == 0) { - - /* Restore the normal state */ - map_2M_page(0); - restore_mtrr_state(mtrr_state); - enable_lapic(); - - /* Print a status message */ - printk_debug("%c", (basek >= TOLM_KB)?'+':'-'); - - /* Return to the initialization state */ - set_init_ecc_mtrrs(); - disable_lapic(); - - } - - limitk = (basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1); - - size = (limitk - basek) << 10; - addr = map_2M_page(basek >> 11); - if (addr == MAPPING_ERROR) { - printk_err("Cannot map page: %x\n", basek >> 11); - return; - } - - /* clear memory 2M (limitk - basek) */ - addr = (void *)(((u32)addr) | ((basek & 0x7ff) << 10)); - clear_memory(addr, size); -} - - -static void init_ecc_memory(u32 node_id) -{ - unsigned long startk, begink, endk; - unsigned long hole_startk = 0; - unsigned long basek; - struct mtrr_state mtrr_state; - - device_t f1_dev, f2_dev, f3_dev; - int enable_scrubbing; - u32 dcl; - - f1_dev = get_node_pci(node_id, 1); - - if (!f1_dev) { - die("Cannot find cpu function 1\n"); - } - f2_dev = get_node_pci(node_id, 2); - if (!f2_dev) { - die("Cannot find cpu function 2\n"); - } - f3_dev = get_node_pci(node_id, 3); - if (!f3_dev) { - die("Cannot find cpu function 3\n"); - } - - /* See if we scrubbing should be enabled */ - enable_scrubbing = 1; - get_option(&enable_scrubbing, "hw_scrubber"); - - /* Enable cache scrubbing at the lowest possible rate */ - if (enable_scrubbing) { - pci_write_config32(f3_dev, DRAM_SCRUB_RATE_CTRL, - (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_NONE << 0)); - } else { - pci_write_config32(f3_dev, DRAM_SCRUB_RATE_CTRL, - (SCRUB_NONE << 16) | (SCRUB_NONE << 8) | (SCRUB_NONE << 0)); - printk_debug("Scrubbing Disabled\n"); - } - - - /* If ecc support is not enabled don't touch memory */ - dcl = pci_read_config32(f2_dev, DRAM_CONFIG_LOW); - if (!(dcl & DCL_DimmEccEn)) { - printk_debug("ECC Disabled\n"); - return; - } - - startk = (pci_read_config32(f1_dev, 0x40 + (node_id*8)) & 0xffff0000) >> 2; - endk = ((pci_read_config32(f1_dev, 0x44 + (node_id*8)) & 0xffff0000) >> 2) + 0x4000; - -#if HW_MEM_HOLE_SIZEK != 0 - u32 val; - val = pci_read_config32(f1_dev, 0xf0); - if(val & 1) { - hole_startk = ((val & (0xff<<24)) >> 10); - } -#endif - - - /* Don't start too early */ - begink = startk; - if (begink < CONFIG_LB_MEM_TOPK) { - begink = CONFIG_LB_MEM_TOPK; - } - - printk_debug("Clearing memory %uK - %uK: ", begink, endk); - - /* Save the normal state */ - save_mtrr_state(&mtrr_state); - - /* Switch to the init ecc state */ - set_init_ecc_mtrrs(); - disable_lapic(); - - /* Walk through 2M chunks and zero them */ -#if HW_MEM_HOLE_SIZEK != 0 - /* here hole_startk can not be equal to begink, never. Also hole_startk is in 2M boundary, 64M? */ - if ( (hole_startk != 0) && ((begink < hole_startk) && (endk>(4*1024*1024)))) { - for(basek = begink; basek < hole_startk; - basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) - { - clear_2M_ram(basek, &mtrr_state); - } - for(basek = 4*1024*1024; basek < endk; - basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) - { - clear_2M_ram(basek, &mtrr_state); - } - } else -#endif - for(basek = begink; basek < endk; - basek = ((basek + ZERO_CHUNK_KB) & ~(ZERO_CHUNK_KB - 1))) { - clear_2M_ram(basek, &mtrr_state); - } - - - /* Restore the normal state */ - map_2M_page(0); - restore_mtrr_state(&mtrr_state); - enable_lapic(); - - /* Set the scrub base address registers */ - pci_write_config32(f3_dev, DRAM_SCRUB_ADDR_LOW, startk << 10); - pci_write_config32(f3_dev, DRAM_SCRUB_ADDR_HIGH, startk >> 22); - - /* Enable the scrubber? */ - if (enable_scrubbing) { - /* Enable scrubbing at the lowest possible rate */ - pci_write_config32(f3_dev, DRAM_SCRUB_RATE_CTRL, - (SCRUB_84ms << 16) | (SCRUB_84ms << 8) | (SCRUB_84ms << 0)); - } - - printk_debug(" done\n"); -} - - -static inline void fam10_errata(void) -{ - msr_t msr; - /* FIXME: Is doing errata here too late? */ - - /* 298 : FIXME: Fixed in B3/C1 */ -/* msr = rdmsr(0xC0010015); - msr.lo |= 1 << 3; - wrmsr(0xC0010015, msr); - - msr = rdmsr(0xC0010023); - msr.lo |= 1 << 1; - wrmsr(0xC0010023, msr); -*/ -} - -static void smash1Gpages(void) -{ - msr_t msr; - - /* 1G pages are smashed and installed in the TLB as 2M pages. - BIOS must set this bit for revision B. */ - /* FIXME: What about RevC? */ - - msr = rdmsr(0xC001102A); - msr.lo |= 1 << 29; - wrmsr(0xC001102A, msr); - -} - - - void model_10xxx_init(device_t dev) { - unsigned long i; + u8 i; msr_t msr; struct node_core_id id; #if CONFIG_LOGICAL_CPUS == 1 - unsigned siblings; + u32 siblings; #endif + id = get_node_core_id(read_nb_cfg_54()); /* nb_cfg_54 can not be set */ + printk_debug("nodeid = %02d, coreid = %02d\n", id.nodeid, id.coreid); + /* Turn on caching if we haven't already */ x86_enable_cache(); amd_setup_mtrrs(); @@ -394,13 +93,14 @@ void model_10xxx_init(device_t dev) wrmsr(MCI_STATUS + (i * 4),msr); } - fam10_errata(); enable_cache(); /* Enable the local cpu apics */ setup_lapic(); + /* FIXME: Update CPUID name strings here */ + #if CONFIG_LOGICAL_CPUS == 1 siblings = cpuid_ecx(0x80000008) & 0xff; @@ -409,34 +109,23 @@ void model_10xxx_init(device_t dev) msr.lo |= 1 << 28; wrmsr_amd(CPU_ID_FEATURES_MSR, msr); - msr = rdmsr_amd(LOGICAL_CPUS_NUM_MSR); - msr.lo = (siblings+1)<<16; - wrmsr_amd(LOGICAL_CPUS_NUM_MSR, msr); - msr = rdmsr_amd(CPU_ID_EXT_FEATURES_MSR); - msr.hi |= 1<<(33-32); + msr.hi |= 1 << (33-32); wrmsr_amd(CPU_ID_EXT_FEATURES_MSR, msr); } printk_debug("siblings = %02d, ", siblings); #endif - id = get_node_core_id(read_nb_cfg_54()); // pre e0 nb_cfg_54 can not be set + /* DisableCf8ExtCfg */ + msr = rdmsr(NB_CFG_MSR); + msr.hi &= ~(1 << (46-32)); + wrmsr(NB_CFG_MSR, msr); - printk_debug("nodeid = %02d, coreid = %02d\n", id.nodeid, id.coreid); + /* Write protect SMM space with SMMLOCK. */ + msr = rdmsr(HWCR_MSR); + msr.lo |= (1 << 0); + wrmsr(HWCR_MSR, msr); - init_pstates(dev, id.nodeid, id.coreid); // is it a good place? some cores are clearing their ram - - /* Is this a bad location? In particular can another node prefecth - * data from this node before we have initialized it? - */ - if (id.coreid == 0) init_ecc_memory(id.nodeid); // only do it for core 0 - -#if CONFIG_LOGICAL_CPUS==1 - /* Start up my cpu siblings */ -// if(id.coreid==0) amd_sibling_init(dev); // Don't need core1 is already be put in the CPU BUS in bus_cpu_scan -#endif - - smash1Gpages(); } static struct device_operations cpu_dev_ops = { diff --git a/src/cpu/amd/model_10xxx/pstate.c b/src/cpu/amd/model_10xxx/pstate.c deleted file mode 100644 index 240f47e4b2..0000000000 --- a/src/cpu/amd/model_10xxx/pstate.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007 Advanced Micro Devices, Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../../../northbridge/amd/amdfam10/amdfam10.h" - -#include -#include -#include -#include -#include - -#include - -#include -#include - -extern device_t get_node_pci(u32 nodeid, u32 fn); - -#include "fidvid_common.c" - -#define PSTATES_DEBUG 0 - - - -static void inline dump_msr_pstates(u32 nodes) -{ -#if PSTATES_DEBUG==1 - int i, j; - for(j=0; j<5; j++) { - printk_debug("P%d:", j); - for(i=0;i>8)&3) { - case 0: times = 1000; break; - case 1: times = 100; break; - case 2: times = 10; break; - default: - //error - times = 1; - } - - return (val & 0xff) * times; - -} - - -static u32 get_powerstep(u32 val) -{ - u32 time; - if(val<4) {time = (4 - val)*100;} - else if(val<8) { time = (9+4-val)*10;} - else { time = (10+8-val) * 5; } - - return time; - -} - - -static u32 get_plllocktime(u32 val) -{ - u32 time; - switch(val) { - case 0: - case 1: - case 2: - case 3: - time = val+1; break; - case 4: time = 8; break; - case 5: time = 16; break; - default: - //erro2 - time = 1; - } - return time; -} - - -static void disable_pstate(u32 nodes, u32 *p) -{ - int i; - - for(i=0;i> 31); - if(!enable) { - disable_pstate(nodes, p); - return; - } - corecof_min = ((sysconf.msr_pstate[0*5+p[0]].lo & 0x3f) + 0x10)>>((sysconf.msr_pstate[0*5+p[0]].lo>>6) & 7); - pwrval_max = sysconf.msr_pstate[0*5+p[0]].hi & 0x3ff; - pwrvalue_max = get_pwrvalue(pwrval_max); - - for(i=1; i> 31); - if(!enable) { - disable_pstate(nodes, p); - return; - } - - u32 coredid = ((sysconf.msr_pstate[i*5+p[i]].lo>>6) & 7); - u32 corecof = ((sysconf.msr_pstate[i*5+p[i]].lo & 0x3f) + 0x10)>>coredid; - if(corecofpwrvalue_max) { - pwrvalue_max = pwrvalue; - pwrval_max = pwrval; - } - } - - for(i=0; i>6) & 7); - u32 corefid = (corecof_min<>7) & 0x3f; - for(j=0; j<5; j++) { - val = pci_read_config32(f4_dev[i], 0x1e0 + (j<<2)); - nbdid = ((val>>16) & 1); - sysconf.msr_pstate[i*5+j].lo = (val & 0xffff) | (nbdid<<22) | ((nbdid?nbvid1:nbvid0)<<25); - sysconf.msr_pstate[i*5+j].hi = (((val>>17) & 0x3ff) << (32-32)) | (((val>>27) & 1)<<(63-32)); - } - } - - dump_msr_pstates(nodes); - - sysconf.needs_update_pstate_msrs = 0; // normal case for all sockets are installed same conf CPU - - for(i=1; (i>28) & 7)); - if(p_htc[i] == 0) { - val |= 1<<28; - pci_write_config32(f3_dev[i], 0x64, val); - val = pci_read_config32(f3_dev[i], 0x68); //stc - val &= ~(7<<28); - val |= (1<<28); - pci_write_config32(f3_dev[i], 0x68, val); - - p_htc[i] = 1; - } - } - if(htc_cap) { - match_pstate(nodes, p_htc); - - dump_p("P_htc\n", nodes, p_htc); - dump_msr_pstates(nodes); - } - - //p_lowest - for(i=0;i((val>>8) & 7)) { - val &= ~(7<<8); - val |= (p_lowest[i])<<8; - pci_write_config32(f3_dev[i], 0xdc, val); - } - else { - p_lowest[i] = (val>>8) & 7; - } - } - if(htc_cap) { - for(i=0;ihi & (1<<(63-32)) )) continue; - if((msr_pstate->lo & 0x3f) != corefid) { - corefid_equal = 0; - break; - } - } - for(j=0; j<5; j++) { - struct p_state_t *p_state; - msr_t *msr_pstate; - msr_pstate = &sysconf.msr_pstate[i*5+j]; - if(!(msr_pstate->hi & (1<<(63-32)) )) continue; - p_state = &sysconf.p_state[i*5+sysconf.p_state_num]; - u32 coredid = ((msr_pstate->lo>>6) & 7); - u32 corecof = ((msr_pstate->lo & 0x3f) + 0x10)>>coredid; - p_state->corefreq = corecof; - - u32 pwrval, pwrvalue; - pwrval = msr_pstate->hi & 0x3ff; - pwrvalue = get_pwrvalue(pwrval); - p_state->power = pwrvalue; - - u32 lat; - val = pci_read_config32(f3_dev[i], 0xd4); - lat = 15 * (get_powerstep((val>>24)& 0xf)+get_powerstep((val>>20)& 0xf)) /1000; - if(!corefid_equal) { - val = pci_read_config32(f3_dev[i], 0xa0); - lat += get_plllocktime((val >> 11 ) & 7); - } - p_state->transition_lat = lat; - p_state->busmaster_lat = lat; - - p_state->control = j; - p_state->status = j; - - sysconf.p_state_num++; - } - // don't need look at other nodes - if(!sysconf.p_state_num) break; - } -} - - -//it will update pstates info from ram into MSR -void init_pstates(device_t dev, u32 nodeid, u32 coreid) -{ - int j; - msr_t msr; - - if(sysconf.needs_update_pstate_msrs) { - for(j=0; j < 5; j++) { - wrmsr(0xC0010064 + j, sysconf.msr_pstate[nodeid * 5 + j]); - } - } - - /* Set TSC Freq Select: TSC increments at the rate of the core P-state 0 */ - msr = rdmsr(0xC0010015); - msr.lo |= 1 << 24; - wrmsr(0xC0010015, msr); - - // Enter the state P0 - //FIXME I don't think that this works correctly. May depend on early fid/vid setup. - if(sysconf.p_state_num) - set_core_nb_max_pstate_after_other_warm_reset(nodeid, coreid); - -}