X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fcpu%2Famd%2Fcar%2Fpost_cache_as_ram.c;h=147a56d6183800c4642d73f74aac75b2a790edf4;hb=35ed0e7ea3d9bd6641c719cf4489bfa408e48972;hp=fec59058227ddc0abc604ea5f656d51909651d7d;hpb=806e146e754a44f96c693cde707065b14f80d8a2;p=coreboot.git diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c index fec590582..147a56d61 100644 --- a/src/cpu/amd/car/post_cache_as_ram.c +++ b/src/cpu/amd/car/post_cache_as_ram.c @@ -1,22 +1,40 @@ - +/* 2005.6 by yhlu + * 2006.3 yhlu add copy data from CAR to ram + */ #include "cpu/amd/car/disable_cache_as_ram.c" -#include "cpu/amd/car/clear_1m_ram.c" +#include "cpu/amd/car/clear_init_ram.c" static inline void print_debug_pcar(const char *strval, uint32_t val) { -#if CONFIG_USE_INIT printk_debug("%s%08x\r\n", strval, val); -#else - print_debug(strval); print_debug_hex32(val); print_debug("\r\n"); -#endif } +static void inline __attribute__((always_inline)) memcopy(void *dest, const void *src, unsigned long bytes) +{ + __asm__ volatile( + "cld\n\t" + "rep; movsl\n\t" + : /* No outputs */ + : "S" (src), "D" (dest), "c" ((bytes)>>2) + ); +} +/* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33 */ - -static void post_cache_as_ram(unsigned cpu_reset) +static void vErrata343(void) { +#ifdef BU_CFG2_MSR + msr_t msr; + unsigned int uiMask = 0xFFFFFFF7; + + msr = rdmsr(BU_CFG2_MSR); + msr.hi &= uiMask; // set bit 35 to 0 + wrmsr(BU_CFG2_MSR, msr); +#endif +} +static void post_cache_as_ram(void) +{ #if 1 { @@ -30,66 +48,77 @@ static void post_cache_as_ram(unsigned cpu_reset) } #endif - print_debug_pcar("cpu_reset = ",cpu_reset); + unsigned testx = 0x5a5a5a5a; + print_debug_pcar("testx = ", testx); - 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) - ); + /* copy data from cache as ram to + ram need to set CONFIG_RAMTOP to 2M and use var mtrr instead. + */ +#if CONFIG_RAMTOP <= 0x100000 + #error "You need to set CONFIG_RAMTOP greater than 1M" +#endif + + set_init_ram_access(); /* So we can access RAM from [1M, CONFIG_RAMTOP) */ - disable_cache_as_ram(); +// dump_mem(CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x8000, CONFIG_DCACHE_RAM_BASE+CONFIG_DCACHE_RAM_SIZE-0x7c00); + print_debug("Copying data from cache to RAM -- switching to use RAM as stack... "); - if(cpu_reset==0) { // cpu_reset don't need to clear it - clear_1m_ram(); - } + /* from here don't store more data in CAR */ + vErrata343(); #if 0 - int i; - for(i=0;i<0x800000;i++) { - outb(0x66, 0x80); - } + __asm__ volatile ( + "pushl %eax\n\t" + ); #endif + memcopy((void *)((CONFIG_RAMTOP)-CONFIG_DCACHE_RAM_SIZE), (void *)CONFIG_DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_SIZE); //inline +// dump_mem((CONFIG_RAMTOP) - 0x8000, (CONFIG_RAMTOP) - 0x7c00); + __asm__ volatile ( - /* set new esp */ /* before _RAMBASE */ + /* set new esp */ /* before CONFIG_RAMBASE */ "subl %0, %%ebp\n\t" "subl %0, %%esp\n\t" - ::"a"( (DCACHE_RAM_BASE + DCACHE_RAM_SIZE)- _RAMBASE ) + ::"a"( (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)- (CONFIG_RAMTOP) ) + ); // We need to push %eax to the stack (CAR) before copy stack and pop it later after copy stack and change esp +#if 0 + __asm__ volatile ( + "popl %eax\n\t" ); +#endif - { - unsigned new_cpu_reset; - /* get back cpu_reset from ebx */ - __asm__ volatile ( - "movl %%ebx, %0\n\t" - :"=a" (new_cpu_reset) - ); + /* We can put data to stack again */ - print_debug("Use Ram as Stack now - "); /* but We can not go back any more, we lost old stack data in cache as ram*/ + /* only global variable sysinfo in cache need to be offset */ + print_debug("Done\r\n"); + print_debug_pcar("testx = ", testx); - if(new_cpu_reset==0) { - print_debug("done\r\n"); - } else - { - print_debug("\r\n"); - } + print_debug("Disabling cache as ram now \r\n"); + disable_cache_as_ram_bsp(); - print_debug_pcar("new_cpu_reset = ", new_cpu_reset); + print_debug("Clearing initial memory region: "); + clear_init_ram(); //except the range from [(CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_SIZE, (CONFIG_RAMTOP)) + print_debug("Done\r\n"); +// dump_mem((CONFIG_RAMTOP) - 0x8000, (CONFIG_RAMTOP) - 0x7c00); - /*copy and execute linuxbios_ram */ - copy_and_run(new_cpu_reset); - /* We will not return */ - } +#ifndef CONFIG_MEM_TRAIN_SEQ +#define CONFIG_MEM_TRAIN_SEQ 0 +#endif + set_sysinfo_in_ram(1); // So other core0 could start to train mem + +#if CONFIG_MEM_TRAIN_SEQ == 1 +// struct sys_info *sysinfox = ((CONFIG_RAMTOP) - CONFIG_DCACHE_RAM_GLOBAL_VAR_SIZE); + + // wait for ap memory to trained +// wait_all_core0_mem_trained(sysinfox); // moved to lapic_init_cpus.c +#endif + /*copy and execute coreboot_ram */ + copy_and_run(); + /* We will not return */ - print_debug("should not be here -\r\n"); + print_debug("should not be here -\r\n"); }