aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/amd/car
diff options
context:
space:
mode:
authorRudolf Marek <r.marek@assembler.cz>2010-11-22 22:00:52 +0000
committerRudolf Marek <r.marek@assembler.cz>2010-11-22 22:00:52 +0000
commitbcaea142f344389ed0c1857f53b7c8556a804c8d (patch)
treefc693f89ea3e374f7d62dfdaabd46f946350af63 /src/cpu/amd/car
parent9b5295f522fa08b84d222ba08f5801d8e812dbc6 (diff)
1) wraps the s3 parts of chipset code/memory init code with if CONFIG_HAVE_ACPI_RESUME == 1 getting rid of ugly define in romstage.c
2) the patch implements get_cbmem_toc in chipset specific way if defined. On Intel targets it should be unchanged. On K8T890 the the cbmem_toc is read from NVRAM. Why you ask? Because we cannot do it as on intel, because the framebuffer might be there making it hard to look for it in memory (and remember we need it so early that everying is uncached) 3) The patch removes hardcoded limits for suspend/resume save area (it was 1MB) on intel. Now it computes right numbers itself. 4) it impelements saving the memory during CAR to reserved range in sane way. First the sysinfo area (CAR data) is copied, then the rest after car is disabled (cached copy is used). I changed bit also the the copy of CAR area is now done uncached for target which I feel is more right. I think I did not change the Intel suspend/resume behaviour but best would be if someone can test it. Please note this patch was unfinished on my drive since ages and it would be very nice to get it in to prevent bit rotten it again. Now I feel it is done good way and should not break anything. I did a test with abuild and it seems fine. Signed-off-by: Rudolf Marek <r.marek@assembler.cz> Acked-by: Tobias Diedrich <ranma+coreboot@tdiedrich.de> Acked-by: Stefan Reinauer <stepan@coreboot.org> git-svn-id: svn://svn.coreboot.org/coreboot/trunk@6117 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
Diffstat (limited to 'src/cpu/amd/car')
-rw-r--r--src/cpu/amd/car/post_cache_as_ram.c68
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