diff options
Diffstat (limited to 'src/cpu/amd')
-rw-r--r-- | src/cpu/amd/car/post_cache_as_ram.c | 68 |
1 files changed, 61 insertions, 7 deletions
diff --git a/src/cpu/amd/car/post_cache_as_ram.c b/src/cpu/amd/car/post_cache_as_ram.c index 4a1398a4d3..e8f0c92f45 100644 --- a/src/cpu/amd/car/post_cache_as_ram.c +++ b/src/cpu/amd/car/post_cache_as_ram.c @@ -27,6 +27,45 @@ static void inline __attribute__((always_inline)) memcopy(void *dest, const voi : "0" (bytes / 4), "g" (bytes), "1" ((long)dest), "2" ((long)src) : "memory", "cc"); } + +#if CONFIG_HAVE_ACPI_RESUME == 1 + +static inline void *backup_resume(void) { + unsigned long high_ram_base; + void *resume_backup_memory; + int suspend = acpi_is_wakeup_early(); + + if (!suspend) + return NULL; + + /* Start address of high memory tables */ + high_ram_base = (u32) get_cbmem_toc(); + + print_debug_pcar("CBMEM TOC is at: ", (uint32_t)high_ram_base); + print_debug_pcar("CBMEM TOC 0-size: ",(uint32_t)(high_ram_base + HIGH_MEMORY_SIZE + 4096)); + + cbmem_reinit((u64)high_ram_base); + + resume_backup_memory = cbmem_find(CBMEM_ID_RESUME); + + /* copy 1MB - 64K to high tables ram_base to prevent memory corruption + * through stage 2. We could keep stuff like stack and heap in high tables + * memory completely, but that's a wonderful clean up task for another + * day. + */ + + if (resume_backup_memory) { + print_debug_pcar("Will copy coreboot region to: ", (uint32_t) resume_backup_memory); + /* copy only backup only memory used for CAR */ + memcopy(resume_backup_memory+HIGH_MEMORY_SAVE-CONFIG_DCACHE_RAM_SIZE, + (void *)((CONFIG_RAMTOP)-CONFIG_DCACHE_RAM_SIZE), + CONFIG_DCACHE_RAM_SIZE); //inline + } + + return resume_backup_memory; +} +#endif + /* Disable Erratum 343 Workaround, see RevGuide for Fam10h, Pub#41322 Rev 3.33 */ static void vErrata343(void) @@ -43,7 +82,9 @@ static void vErrata343(void) static void post_cache_as_ram(void) { - +#if CONFIG_HAVE_ACPI_RESUME == 1 + void *resume_backup_memory; +#endif #if 1 { /* Check value of esp to verify if we have enough rom for stack in Cache as RAM */ @@ -66,17 +107,16 @@ static void post_cache_as_ram(void) #error "You need to set CONFIG_RAMTOP greater than 1M" #endif - /* So we can access RAM from [1M, CONFIG_RAMTOP) */ - set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK); +#if CONFIG_HAVE_ACPI_RESUME == 1 + resume_backup_memory = backup_resume(); +#endif -// 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... "); /* from here don't store more data in CAR */ vErrata343(); 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 CONFIG_RAMBASE */ @@ -94,9 +134,25 @@ static void post_cache_as_ram(void) print_debug_pcar("testx = ", testx); print_debug("Disabling cache as ram now \n"); + disable_cache_as_ram_bsp(); + disable_cache(); + set_var_mtrr(0, 0x00000000, CONFIG_RAMTOP, MTRR_TYPE_WRBACK); + enable_cache(); + +#if CONFIG_HAVE_ACPI_RESUME == 1 + /* now copy the rest of the area, using the WB method because we already + run normal RAM */ + if (resume_backup_memory) { + memcopy(resume_backup_memory, + (void *)(CONFIG_RAMBASE), + (CONFIG_RAMTOP) - CONFIG_RAMBASE - CONFIG_DCACHE_RAM_SIZE); + } +#endif + print_debug("Clearing initial memory region: "); + #if CONFIG_HAVE_ACPI_RESUME == 1 /* clear only coreboot used region of memory. Note: this may break ECC enabled boards */ memset((void*) CONFIG_RAMBASE, 0, (CONFIG_RAMTOP) - CONFIG_RAMBASE - CONFIG_DCACHE_RAM_SIZE); @@ -105,8 +161,6 @@ static void post_cache_as_ram(void) #endif print_debug("Done\n"); -// dump_mem((CONFIG_RAMTOP) - 0x8000, (CONFIG_RAMTOP) - 0x7c00); - set_sysinfo_in_ram(1); // So other core0 could start to train mem #if CONFIG_MEM_TRAIN_SEQ == 1 |