Don't worry, Please stay with the old code.
After LNXI put back apic id lifting back, I will enable the CAR shortly in the public tree.
YH
________________________________
From: linuxbios-bounces@openbios.org [mailto:linuxbios-bounces@openbios.org] On Behalf Of San Mehat Sent: Tuesday, October 25, 2005 4:59 PM To: LinuxBIOS Subject: [LinuxBIOS] Latest commit - clarification
Hey Jason,
Would you mind just chucking up an exec summary of all the changes?.. I'm trying to adapt our port to the new code and am trying to figure out whats going on ;)
Mainly: set_apicid_cpuid_low() = gone start_other_cores() = gone __cpu_reset = gone get_apicid_base() = gone
Actually, the __cpu_reset: thing looks broken on CAR systems... looking at the tyan s4882 board, the Config.lb only brings in arch/i386/lib/cpu_reset.inc if we're NOT CAR....
We're basicaly doing everything as CAR.
Are there more changes comming? or should we just start hacking to pick up the pieces?
thanks man...
;) -san
okay... so we're broken until that gets in the public tree.
On 10/25/05, Lu, Yinghai yinghai.lu@amd.com wrote:
Don't worry, Please stay with the old code.
After LNXI put back apic id lifting back, I will enable the CAR shortly in the public tree.
YH
*From:* linuxbios-bounces@openbios.org [mailto: linuxbios-bounces@openbios.org] *On Behalf Of *San Mehat *Sent:* Tuesday, October 25, 2005 4:59 PM *To:* LinuxBIOS *Subject:* [LinuxBIOS] Latest commit - clarification
Hey Jason,
Would you mind just chucking up an exec summary of all the changes?.. I'm trying to adapt our port to the new code and am trying to figure out whats going on ;)
Mainly: set_apicid_cpuid_low() = gone start_other_cores() = gone __cpu_reset = gone get_apicid_base() = gone
Actually, the __cpu_reset: thing looks broken on CAR systems... looking at the tyan s4882 board, the Config.lbhttp://www.google.com/url?sa=D&q=http%3A%2F%2FConfig.lbonly brings in arch/i386/lib/cpu_reset.inc if we're NOT CAR....
We're basicaly doing everything as CAR.
Are there more changes comming? or should we just start hacking to pick up the pieces?
thanks man...
;) -san
LNXI, LANL, GOOGLE, Please check my patch about reenable CAR. If it is ok, I will populate that from s2895 to others.
YH
cpu/amd/car/cache_as_ram.inc | 64 +-------- cpu/amd/car/cache_as_ram_post.c | 95 -------------- cpu/amd/car/clear_1m_ram.c | 53 ++++++++ cpu/amd/car/disable_cache_as_ram.c | 46 +++++++ cpu/amd/car/post_cache_as_ram.c | 81 ++++++++++++ cpu/amd/dualcore/dualcore.c | 27 ++++ cpu/amd/dualcore/dualcore_id.c | 5 mainboard/tyan/s2895/Options.lb | 4 mainboard/tyan/s2895/cache_as_ram_auto.c | 202 ++----------------------------- northbridge/amd/amdk8/coherent_ht.c | 11 + 10 files changed, 247 insertions(+), 341 deletions(-)
yhlu yinghailu@gmail.com writes:
LNXI, LANL, GOOGLE, Please check my patch about reenable CAR. If it is ok, I will populate that from s2895 to others.
YH
cpu/amd/car/cache_as_ram.inc | 64 +-------- cpu/amd/car/cache_as_ram_post.c | 95 -------------- cpu/amd/car/clear_1m_ram.c | 53 ++++++++ cpu/amd/car/disable_cache_as_ram.c | 46 +++++++ cpu/amd/car/post_cache_as_ram.c | 81 ++++++++++++ cpu/amd/dualcore/dualcore.c | 27 ++++ cpu/amd/dualcore/dualcore_id.c | 5 mainboard/tyan/s2895/Options.lb | 4 mainboard/tyan/s2895/cache_as_ram_auto.c | 202 ++----------------------------- northbridge/amd/amdk8/coherent_ht.c | 11 + 10 files changed, 247 insertions(+), 341 deletions(-)
Ok quick overview.
First this looks like good progress, and getting code working again so quickly is great!
I don't think it's there yet but it looks like we are close.
Index: src/cpu/amd/car/clear_1m_ram.c
--- src/cpu/amd/car/clear_1m_ram.c (revision 0) +++ src/cpu/amd/car/clear_1m_ram.c (revision 0)
I'm not real comfortable with C include files that are simply one big assembly statement. Something just seems wrong.
I can understand the need for control when you are turning cache as ram on and off though.
@@ -0,0 +1,53 @@ +/* by yhlu 6.2005 */ +/* be warned, this file will be used core 0/node 0 only */
__asm__ volatile (
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* enable caching for first 1M using variable mtrr */
"movl $0x200, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0 | 1), %eax\n\t"
+// "movl $(0 | MTRR_TYPE_WRCOMB), %eax\n\t"
"wrmsr\n\t"
"movl $0x201, %ecx\n\t"
"movl $0x0000000f, %edx\n\t"
"movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
/* clear the first 1M */
"movl $0x0, %edi\n\t"
"cld\n\t"
"movl $(0x100000>>2), %ecx\n\t"
"xorl %eax, %eax\n\t"
"rep stosl\n\t"
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* enable caching for first 1M using variable mtrr */
"movl $0x200, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0 | 6), %eax\n\t"
+// "movl $(0 | MTRR_TYPE_WRBACK), %eax\n\t"
"wrmsr\n\t"
"movl $0x201, %ecx\n\t"
"movl $0x0000000f, %edx\n\t"
"movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
/* enable cache */
"movl %cr0, %eax\n\t"
"andl $0x9fffffff,%eax\n\t"
"movl %eax, %cr0\n\t"
- "invd\n\t"
);
Index: src/cpu/amd/car/disable_cache_as_ram.c
--- src/cpu/amd/car/disable_cache_as_ram.c (revision 0) +++ src/cpu/amd/car/disable_cache_as_ram.c (revision 0) @@ -0,0 +1,46 @@ +/* by yhlu 6.2005 */ +/* be warned, this file will be used other cores and core 0 / node 0 */
__asm__ volatile (
- /*
- FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
It is only needed if we want to go back
- */
/* We don't need cache as ram for now on */
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* clear sth */
"movl $0x269, %ecx\n\t" /* fix4k_c8000*/
"xorl %edx, %edx\n\t"
"xorl %eax, %eax\n\t"
- "wrmsr\n\t"
+#if DCACHE_RAM_SIZE > 0x8000
- "movl $0x268, %ecx\n\t" /* fix4k_c0000*/
"wrmsr\n\t"
+#endif
/* disable fixed mtrr from now on, it will be enabled by linuxbios_ram again*/
"movl $0xC0010010, %ecx\n\t"
+// "movl $SYSCFG_MSR, %ecx\n\t"
"rdmsr\n\t"
"andl $(~(3<<18)), %eax\n\t"
+// "andl $(~(SYSCFG_MSR_MtrrFixDramModEn | SYSCFG_MSR_MtrrFixDramEn)), %eax\n\t"
"wrmsr\n\t"
/* Set the default memory type and disable fixed and enable variable MTRRs */
"movl $0x2ff, %ecx\n\t"
+// "movl $MTRRdefType_MSR, %ecx\n\t"
"xorl %edx, %edx\n\t"
/* Enable Variable and Disable Fixed MTRRs */
"movl $0x00000800, %eax\n\t"
"wrmsr\n\t"
/* enable cache */
"movl %cr0, %eax\n\t"
"andl $0x9fffffff,%eax\n\t"
"movl %eax, %cr0\n\t"
);
Index: src/cpu/amd/car/cache_as_ram_post.c
--- src/cpu/amd/car/cache_as_ram_post.c (revision 2079) +++ src/cpu/amd/car/cache_as_ram_post.c (working copy) @@ -1,95 +0,0 @@ -/* by yhlu 6.2005 */ -/* be warned, this file will be used other cores and core0/node0 */
__asm__ volatile (
- /*
- FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
It is only needed if we want to go back
- */
/* We don't need cache as ram for now on */
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* clear sth */
"movl $0x269, %ecx\n\t" /* fix4k_c8000*/
"xorl %edx, %edx\n\t"
"xorl %eax, %eax\n\t"
- "wrmsr\n\t"
-#if DCACHE_RAM_SIZE > 0x8000
- "movl $0x268, %ecx\n\t" /* fix4k_c0000*/
"wrmsr\n\t"
-#endif
/* disable fixed mtrr from now on, it will be enabled by linuxbios_ram again*/
"movl $0xC0010010, %ecx\n\t"
-// "movl $SYSCFG_MSR, %ecx\n\t"
"rdmsr\n\t"
"andl $(~(3<<18)), %eax\n\t"
-// "andl $(~(SYSCFG_MSR_MtrrFixDramModEn | SYSCFG_MSR_MtrrFixDramEn)), %eax\n\t"
"wrmsr\n\t"
/* Set the default memory type and disable fixed and enable variable MTRRs */
"movl $0x2ff, %ecx\n\t"
-// "movl $MTRRdefType_MSR, %ecx\n\t"
"xorl %edx, %edx\n\t"
/* Enable Variable and Disable Fixed MTRRs */
"movl $0x00000800, %eax\n\t"
"wrmsr\n\t"
-#if defined(CLEAR_FIRST_1M_RAM)
/* enable caching for first 1M using variable mtrr */
"movl $0x200, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0 | 1), %eax\n\t"
-// "movl $(0 | MTRR_TYPE_WRCOMB), %eax\n\t"
"wrmsr\n\t"
"movl $0x201, %ecx\n\t"
"movl $0x0000000f, %edx\n\t"
"movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
-#endif
/* enable cache */
"movl %cr0, %eax\n\t"
"andl $0x9fffffff,%eax\n\t"
"movl %eax, %cr0\n\t"
-#if defined(CLEAR_FIRST_1M_RAM)
/* clear the first 1M */
"movl $0x0, %edi\n\t"
"cld\n\t"
"movl $(0x100000>>2), %ecx\n\t"
"xorl %eax, %eax\n\t"
"rep stosl\n\t"
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* enable caching for first 1M using variable mtrr */
"movl $0x200, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0 | 6), %eax\n\t"
-// "movl $(0 | MTRR_TYPE_WRBACK), %eax\n\t"
"wrmsr\n\t"
"movl $0x201, %ecx\n\t"
"movl $0x0000000f, %edx\n\t"
"movl $((~(( 0 + 0x100000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
/* enable cache */
"movl %cr0, %eax\n\t"
"andl $0x9fffffff,%eax\n\t"
"movl %eax, %cr0\n\t"
- "invd\n\t"
- /*
- FIXME: I hope we don't need to change esp and ebp value here, so we can restore value from mmx sse back
But the problem is the range is some io related, So don't go back
- */
-#endif
);
Index: src/cpu/amd/car/post_cache_as_ram.c
--- src/cpu/amd/car/post_cache_as_ram.c (revision 0) +++ src/cpu/amd/car/post_cache_as_ram.c (revision 0) @@ -0,0 +1,81 @@
Testing for CONFIG_USE_INIT in any file that depends on cache_as_ram seems the unnecessary. Am I missing something here?
+static void post_cache_as_ram(unsigned cpu_reset) +{
+#if 1
{
/* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
unsigned v_esp;
__asm__ volatile (
"movl %%esp, %0\n\t"
: "=a" (v_esp)
);
+#if CONFIG_USE_INIT
printk_debug("v_esp=%08x\r\n", v_esp);
+#else
print_debug("v_esp="); print_debug_hex32(v_esp); print_debug("\r\n");
+#endif
}
+#endif
+#if CONFIG_USE_INIT
printk_debug("cpu_reset = %08x\r\n",cpu_reset);
+#else
print_debug("cpu_reset = "); print_debug_hex32(cpu_reset); print_debug("\r\n");
+#endif
if(cpu_reset == 0) {
print_debug("Clearing initial memory region: ");
}
print_debug("No cache as ram now - ");
/* store cpu_reset to ebx */
__asm__ volatile (
"movl %0, %%ebx\n\t"
::"a" (cpu_reset)
);
+#include "cpu/amd/car/disable_cache_as_ram.c"
if(cpu_reset==0) { // cpu_reset don't need to clear it
+#include "cpu/amd/car/clear_1m_ram.c"
}
__asm__ volatile (
/* set new esp */ /* before _RAMBASE */
"subl %0, %%ebp\n\t"
"subl %0, %%esp\n\t"
::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- _RAMBASE )
);
{
unsigned new_cpu_reset;
/* get back cpu_reset from ebx */
__asm__ volatile (
"movl %%ebx, %0\n\t"
:"=a" (new_cpu_reset)
);
print_debug("Use Ram as Stack now - "); /* but We can not go back any more, we lost old stack data in cache as ram*/
if(new_cpu_reset==0) {
print_debug("done\r\n");
} else
{
print_debug("\r\n");
}
+#if CONFIG_USE_INIT
printk_debug("new_cpu_reset = %08x\r\n", new_cpu_reset);
+#else
print_debug("new_cpu_reset = "); print_debug_hex32(new_cpu_reset); print_debug("\r\n");
+#endif
/*copy and execute linuxbios_ram */
copy_and_run(new_cpu_reset);
/* We will not return */
}
- print_debug("should not be here -\r\n");
+}
Index: src/cpu/amd/car/cache_as_ram.inc
--- src/cpu/amd/car/cache_as_ram.inc (revision 2079) +++ src/cpu/amd/car/cache_as_ram.inc (working copy) @@ -8,10 +8,17 @@
/* Save the BIST result */ movl %eax, %ebp
- // for normal part %ebx already contain cpu_init_detected from fallback call
CacheAsRam: /* hope we can skip the double set for normal part */ #if USE_FALLBACK_IMAGE == 1
This looks like a testing/validation problem only enabling cache_as_ram in the fallback image. I would rather continue to compile fallback.c with romcc than to have weird special cases like this.
movl $MTRRdefType_MSR, %ecx
rdmsr
andl $0x00000800, %eax
movl %eax, %ebx ; // We store the status about if cpu_init_detected
/* Set MtrrFixDramModEn for clear fixed mtrr */ xorl %eax, %eax # clear %eax and %edx
@@ -53,7 +60,6 @@ orl $(SYSCFG_MSR_MtrrVarDramEn | SYSCFG_MSR_MtrrFixDramEn), %eax wrmsr
-#if 1 #if CacheSize == 0x10000 /* enable caching for 64K using fixed mtrr */ movl $0x268, %ecx /* fix4k_c0000*/ @@ -86,30 +92,6 @@ xorl %eax, %eax wrmsr
-#else
/* enable caching for 64K using variable mtrr */
movl $0x200, %ecx
xorl %edx, %edx
movl $(CacheBase | MTRR_TYPE_WRBACK), %eax
wrmsr
movl $0x201, %ecx
movl $0x0000000f, %edx /* AMD 40 bit 0xff*/
movl $((~((CacheBase + CacheSize) - 1)) | 0x800), %eax
wrmsr
- /* make it to be IO by clearing RD Dram and WR Dram */
- movl $IORR0_BASE, %ecx
xorl %edx, %edx
movl $CacheBase, %eax /* bit 3, and bit 4 = 0 mean clear RD ram and WR ram */
wrmsr
movl $IORR0_MASK, %ecx
movl $0x000000ff, %edx
movl $(~((CacheBase + CacheSize) - 1) | 0x800), %eax
wrmsr
-#endif
/* enable memory access for 0 - 1MB using top_mem */ movl $TOP_MEM, %ecx xorl %edx, %edx
@@ -145,7 +127,6 @@
#if USE_FALLBACK_IMAGE == 1
/* Read the range with lodsl*/ movl $(CacheBase+CacheSize-4), %esi std
@@ -157,36 +138,6 @@ xorl %eax, %eax rep stosl
-#if 0
- /* check the cache as ram */
- movl $CacheBase, %esi
- movl $(CacheSize>>2), %ecx
-.xin1:
- movl %esi, %eax
- movl %eax, (%esi)
movl $0x1000, %edx
- movb %ah, %al
-.testx1:
outb %al, $0x80
decl %edx
- jnz .testx1
- movl (%esi), %eax
- cmpb 0xff, %al
- je .xin2 /* dont show */
movl $0x1000, %edx
-.testx2:
outb %al, $0x80
decl %edx
jnz .testx2
-.xin2: decl %ecx
je .xout1
add $4, %esi
jmp .xin1
-.xout1:
-#endif #endif /*USE_FALLBACK_IMAGE == 1*/
@@ -198,6 +149,7 @@ movl %ebp, %eax /* We need to set ebp ? No need */ movl %esp, %ebp
- pushl %ebx /* init detected */ pushl %eax /* bist */ call amd64_main /* We will not go back */
Index: src/cpu/amd/dualcore/dualcore.c
--- src/cpu/amd/dualcore/dualcore.c (revision 2079) +++ src/cpu/amd/dualcore/dualcore.c (working copy) @@ -2,6 +2,31 @@
#include "cpu/amd/dualcore/dualcore_id.c"
+static inline unsigned get_core_num_in_bsp(unsigned nodeid) +{
return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) & 3);
+}
+static inline uint8_t set_apicid_cpuid_lo(void) +{
if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) { // disable dual_core
return 0;
}
// set the NB_CFG[54]=1; why the OS will be happy with that ???
msr_t msr;
msr = rdmsr(NB_CFG_MSR);
msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
wrmsr(NB_CFG_MSR, msr);
return 1;
+}
Our code is battling here. The goal of do_k8_init_and_stop_secondaries was to have code that could be shared between the two cases. Even if it isn't so and we need to duplicate the logic it should be as close as possible between the two cases.
Right now we seem to have to totally different ways at looking at the world.
+#if USE_DCACHE_RAM == 0 static void do_k8_init_and_stop_secondaries(void) { struct node_core_id id; @@ -72,3 +97,5 @@
do_k8_init_and_stop_secondaries(); }
+#endif Index: src/cpu/amd/dualcore/dualcore_id.c =================================================================== --- src/cpu/amd/dualcore/dualcore_id.c (revision 2079) +++ src/cpu/amd/dualcore/dualcore_id.c (working copy) @@ -15,6 +15,11 @@ unsigned coreid:8; };
+static inline unsigned get_initial_apicid(void) +{
- return ((cpuid_ebx(1) >> 24) & 0xf);
+}
static inline struct node_core_id get_node_core_id(unsigned nb_cfg_54) { struct node_core_id id; // get the apicid via cpuid(1) ebx[27:24] Index: src/mainboard/tyan/s2895/Options.lb =================================================================== --- src/mainboard/tyan/s2895/Options.lb (revision 2079) +++ src/mainboard/tyan/s2895/Options.lb (working copy) @@ -136,10 +136,10 @@ ## ## enable CACHE_AS_RAM specifics ## -default USE_DCACHE_RAM=0 +default USE_DCACHE_RAM=1 default DCACHE_RAM_BASE=0xcf000 default DCACHE_RAM_SIZE=0x1000 -default CONFIG_USE_INIT=0 +default CONFIG_USE_INIT=1
## ## Build code to setup a generic IOAPIC Index: src/mainboard/tyan/s2895/cache_as_ram_auto.c =================================================================== --- src/mainboard/tyan/s2895/cache_as_ram_auto.c (revision 2079) +++ src/mainboard/tyan/s2895/cache_as_ram_auto.c (working copy) @@ -111,11 +111,7 @@ #include "resourcemap.c"
#if CONFIG_LOGICAL_CPUS==1 -#define SET_NB_CFG_54 1 #include "cpu/amd/dualcore/dualcore.c" -#else -#include "cpu/amd/model_fxx/node_id.c" -#endif
#define FIRST_CPU 1 #define SECOND_CPU 1 @@ -141,6 +137,10 @@
#include "cpu/amd/car/copy_and_run.c"
+#include "cpu/amd/car/post_cache_as_ram.c"
+#include "cpu/amd/model_fxx/init_cpus.c"
#if USE_FALLBACK_IMAGE == 1
#include "southbridge/nvidia/ck804/ck804_enable_rom.c" @@ -180,28 +180,12 @@
}
I'm not yet comfortable with the concept of having the equivalent of failover.c in the primary file. Mostly because using cache_as_ram this early means we can't test changes to it in the normal image.
-void real_main(unsigned long bist); +void real_main(unsigned long bist, unsigned long cpu_init_detectedx);
-void amd64_main(unsigned long bist) +void amd64_main(unsigned long bist, unsigned long cpu_init_detectedx) { -#if CONFIG_LOGICAL_CPUS==1
struct node_core_id id;
-#else
unsigned nodeid;
-#endif
/* Make cerain my local apic is useable */
-// enable_lapic();
-#if CONFIG_LOGICAL_CPUS==1
id = get_node_core_id_x(); /* Is this a cpu only reset? */
if (cpu_init_detected(id.nodeid)) {
-#else -// nodeid = lapicid() & 0xf;
nodeid = get_node_id();
/* Is this a cpu only reset? */
if (cpu_init_detected(nodeid)) {
-#endif
if (cpu_init_detectedx) { if (last_boot_normal()) { goto normal_image; } else {
@@ -242,7 +226,7 @@ normal_image: __asm__ volatile ("jmp __normal_image" : /* outputs */
: "a" (bist) /* inputs */
cpu_reset:: "a" (bist), "b" (cpu_init_detectedx) /* inputs */ );
#if 0 @@ -254,11 +238,11 @@ #endif
fallback_image:
real_main(bist);
real_main(bist, cpu_init_detectedx);
} -void real_main(unsigned long bist) +void real_main(unsigned long bist, unsigned long cpu_init_detectedx) #else -void amd64_main(unsigned long bist) +void amd64_main(unsigned long bist, unsigned long cpu_init_detectedx) #endif { static const struct mem_controller cpu[] = { @@ -291,81 +275,9 @@ unsigned cpu_reset = 0;
if (bist == 0) {
-#if CONFIG_LOGICAL_CPUS==1
struct node_core_id id;
-#else
unsigned nodeid;
-#endif
/* Skip this if there was a built in self test failure */
-// amd_early_mtrr_init(); # don't need, already done in cache_as_ram
-#if CONFIG_LOGICAL_CPUS==1
set_apicid_cpuid_lo();
id = get_node_core_id_x(); // that is initid
#if ENABLE_APIC_EXT_ID == 1
if(id.coreid == 0) {
enable_apic_ext_id(id.nodeid);
}
#endif
-#else
nodeid = get_node_id();
#if ENABLE_APIC_EXT_ID == 1
enable_apic_ext_id(nodeid);
#endif
-#endif
enable_lapic();
-// init_timer();
-#if CONFIG_LOGICAL_CPUS==1
#if ENABLE_APIC_EXT_ID == 1
#if LIFT_BSP_APIC_ID == 0
if( id.nodeid != 0 ) //all except cores in node0
#endif
lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) );
#endif
if(id.coreid == 0) {
if (cpu_init_detected(id.nodeid)) {
-// __asm__ volatile ("jmp __cpu_reset");
cpu_reset = 1;
goto cpu_reset_x;
}
distinguish_cpu_resets(id.nodeid);
-// start_other_core(id.nodeid);
}
-#else
#if ENABLE_APIC_EXT_ID == 1
#if LIFT_BSP_APIC_ID == 0
if(nodeid != 0)
#endif
lapic_write(LAPIC_ID, ( lapic_read(LAPIC_ID) | (APIC_ID_OFFSET<<24) ) ); // CPU apicid is from 0x10
#endif
if (cpu_init_detected(nodeid)) {
-// __asm__ volatile ("jmp __cpu_reset");
cpu_reset = 1;
goto cpu_reset_x;
}
distinguish_cpu_resets(nodeid);
-#endif
if (!boot_cpu()
-#if CONFIG_LOGICAL_CPUS==1
|| (id.coreid != 0)
-#endif
) {
// We need stop the CACHE as RAM for this CPU too
#include "cpu/amd/car/cache_as_ram_post.c"
stop_this_cpu(); // it will stop all cores except core0 of cpu0
}
init_cpus(cpu_init_detectedx, sizeof(cpu)/sizeof(cpu[0]), cpu);
This looks like a good start, there is a lot less duplicate code here.
Why do we need to pass in the cpus? Where is init_cpus defined?
I think we need a little harmonization between this and k8_init_and_stop_secondaries.
}
- init_timer(); // only do it it first CPU
- lpc47b397_enable_serial(SERIAL_DEV, TTYS0_BASE); uart_init(); console_init();
@@ -377,11 +289,6 @@
needs_reset = setup_coherent_ht_domain();
-#if CONFIG_LOGICAL_CPUS==1
// It is said that we should start core1 after all core0 launched
start_other_cores();
-#endif
needs_reset |= ht_setup_chains_x(); needs_reset |= ck804_early_setup_x();
@@ -395,88 +302,7 @@
memreset_setup(); sdram_initialize(sizeof(cpu)/sizeof(cpu[0]), cpu);
- post_cache_as_ram(cpu_reset);
-#if 1
- {
- /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */
- unsigned v_esp;
__asm__ volatile (
"movl %%esp, %0\n\t"
: "=a" (v_esp)
);
-#if CONFIG_USE_INIT
- printk_debug("v_esp=%08x\r\n", v_esp);
-#else
- print_debug("v_esp="); print_debug_hex32(v_esp); print_debug("\r\n");
-#endif
- }
-#endif -#if 1
-cpu_reset_x:
-#if CONFIG_USE_INIT
- printk_debug("cpu_reset = %08x\r\n",cpu_reset);
-#else
- print_debug("cpu_reset = "); print_debug_hex32(cpu_reset); print_debug("\r\n");
-#endif
if(cpu_reset == 0) {
print_debug("Clearing initial memory region: ");
}
print_debug("No cache as ram now - ");
/* store cpu_reset to ebx */
__asm__ volatile (
"movl %0, %%ebx\n\t"
::"a" (cpu_reset)
);
if(cpu_reset==0) {
-#define CLEAR_FIRST_1M_RAM 1 -#include "cpu/amd/car/cache_as_ram_post.c"
}
else {
-#undef CLEAR_FIRST_1M_RAM -#include "cpu/amd/car/cache_as_ram_post.c"
}
__asm__ volatile (
/* set new esp */ /* before _RAMBASE */
"subl %0, %%ebp\n\t"
"subl %0, %%esp\n\t"
::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- _RAMBASE )
);
{
unsigned new_cpu_reset;
/* get back cpu_reset from ebx */
__asm__ volatile (
"movl %%ebx, %0\n\t"
:"=a" (new_cpu_reset)
);
/* We can not go back any more, we lost old stack data in cache as ram*/
if(new_cpu_reset==0) {
print_debug("Use Ram as Stack now - done\r\n");
} else
{
print_debug("Use Ram as Stack now - \r\n");
}
-#if CONFIG_USE_INIT
printk_debug("new_cpu_reset = %08x\r\n", new_cpu_reset);
-#else
print_debug("new_cpu_reset = "); print_debug_hex32(new_cpu_reset); print_debug("\r\n");
-#endif
/*copy and execute linuxbios_ram */
copy_and_run(new_cpu_reset);
/* We will not return */
}
-#endif
print_err("should not be here -\r\n");
} Index: src/northbridge/amd/amdk8/coherent_ht.c =================================================================== --- src/northbridge/amd/amdk8/coherent_ht.c (revision 2079) +++ src/northbridge/amd/amdk8/coherent_ht.c (working copy) @@ -192,6 +192,17 @@ print_spew(" done.\r\n"); }
+static void enable_apic_ext_id(u8 node) +{
- u32 val;
val = pci_read_config32(NODE_HT(node), 0x68);
val |= (HTTC_APIC_EXT_SPUR | HTTC_APIC_EXT_ID | HTTC_APIC_EXT_BRD_CST);
pci_write_config32(NODE_HT(node), 0x68, val);
+}
static void fill_row(u8 node, u8 row, u32 value) { pci_write_config32(NODE_HT(node), 0x40+(row<<2), value);
Eric
Index: src/cpu/amd/car/clear_1m_ram.c
--- src/cpu/amd/car/clear_1m_ram.c (revision 0) +++ src/cpu/amd/car/clear_1m_ram.c (revision 0)
I'm not real comfortable with C include files that are simply one big assembly statement. Something just seems wrong.
I can understand the need for control when you are turning cache as ram on and off though.
YH: that is called after disable cache as ram.
Testing for CONFIG_USE_INIT in any file that depends on cache_as_ram seems the unnecessary. Am I missing something here?
YH: cache_as_ram, there is two way to use it: cache_as_ram_auto.c---> auto.inc or cache_as_ram_auto.c --> auto.o and ....
=================================================================== --- src/cpu/amd/car/cache_as_ram.inc (revision 2079) +++ src/cpu/amd/car/cache_as_ram.inc (working copy) @@ -8,10 +8,17 @@
/* Save the BIST result */ movl %eax, %ebp
- // for normal part %ebx already contain cpu_init_detected from
fallback call
CacheAsRam: /* hope we can skip the double set for normal part */ #if USE_FALLBACK_IMAGE == 1
This looks like a testing/validation problem only enabling cache_as_ram in the fallback image. I would rather continue to compile fallback.c with romcc than to have weird special cases like this.
YH: because it could cause section conflicts that compiling with gcc..
===================================================================
--- src/cpu/amd/dualcore/dualcore.c (revision 2079) +++ src/cpu/amd/dualcore/dualcore.c (working copy) @@ -2,6 +2,31 @@
#include "cpu/amd/dualcore/dualcore_id.c"
+static inline unsigned get_core_num_in_bsp(unsigned nodeid) +{
- return ((pci_read_config32(PCI_DEV(0, 0x18+nodeid, 3), 0xe8)>>12) &
3);
+}
+static inline uint8_t set_apicid_cpuid_lo(void) +{
- if(is_cpu_pre_e0()) return 0; // pre_e0 can not be set
- if(read_option(CMOS_VSTART_dual_core, CMOS_VLEN_dual_core, 0) != 0) {
// disable dual_core
- return 0;
- }
- // set the NB_CFG[54]=1; why the OS will be happy with that ???
- msr_t msr;
- msr = rdmsr(NB_CFG_MSR);
- msr.hi |= (1<<(54-32)); // InitApicIdCpuIdLo
- wrmsr(NB_CFG_MSR, msr);
- return 1;
+}
Our code is battling here. The goal of do_k8_init_and_stop_secondaries was to have code that could be shared between the two cases. Even if it isn't so and we need to duplicate the logic it should be as close as possible between the two cases.
Right now we seem to have to totally different ways at looking at the world.
YH: I use init_cpus for cache_as_ram in cpu/amd/model_fxx/init_cpus.c but it take several function, instead of ..., so it is readable...
}
I'm not yet comfortable with the concept of having the equivalent of failover.c in the primary file. Mostly because using cache_as_ram this early means we can't test changes to it in the normal image.
YH: ???
- stop_this_cpu(); // it will stop all cores except core0 of cpu0
- }
- init_cpus(cpu_init_detectedx, sizeof(cpu)/sizeof(cpu[0]), cpu);
This looks like a good start, there is a lot less duplicate code here.
Why do we need to pass in the cpus? Where is init_cpus defined?
I think we need a little harmonization between this and k8_init_and_stop_secondaries.
YH: cpu/amd/model_fxx/init_cpus.c, I miss it?
}
Eric
new patch with init_cpus.
YH
"Lu, Yinghai" yinghai.lu@amd.com writes:
Don?t worry, Please stay with the old code.
After LNXI put back apic id lifting back, I will enable the CAR shortly in the public tree.
APIC id lifting is in running on every cpu and is enabled unconditionally unless we run into problems with it.
Eric