[LinuxBIOS] Latest commit - clarification

Eric W. Biederman ebiederman at lnxi.com
Wed Oct 26 08:32:23 CEST 2005


yhlu <yinghailu at 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 */
> +                : "a" (bist), "b" (cpu_init_detectedx) /* inputs */
>                  );
>   cpu_reset:
>  #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




More information about the coreboot mailing list