diff options
-rw-r--r-- | src/arch/i386/boot/acpi.c | 11 | ||||
-rw-r--r-- | src/arch/i386/boot/tables.c | 2 | ||||
-rw-r--r-- | src/cpu/amd/car/post_cache_as_ram.c | 68 | ||||
-rw-r--r-- | src/include/cbmem.h | 4 | ||||
-rw-r--r-- | src/lib/cbmem.c | 33 | ||||
-rw-r--r-- | src/mainboard/asus/a8v-e_deluxe/romstage.c | 1 | ||||
-rw-r--r-- | src/mainboard/asus/a8v-e_se/romstage.c | 1 | ||||
-rw-r--r-- | src/mainboard/asus/m2v-mx_se/Kconfig | 1 | ||||
-rw-r--r-- | src/mainboard/asus/m2v-mx_se/mainboard.c | 7 | ||||
-rw-r--r-- | src/mainboard/asus/m2v-mx_se/romstage.c | 10 | ||||
-rw-r--r-- | src/mainboard/asus/m2v/romstage.c | 1 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/northbridge.c | 3 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/raminit_f.c | 5 | ||||
-rw-r--r-- | src/northbridge/amd/amdk8/raminit_f_dqs.c | 23 | ||||
-rw-r--r-- | src/southbridge/via/k8t890/k8t890.h | 1 | ||||
-rw-r--r-- | src/southbridge/via/k8t890/k8t890_early_car.c | 12 | ||||
-rw-r--r-- | src/southbridge/via/k8t890/k8t890_host_ctrl.c | 10 | ||||
-rw-r--r-- | src/southbridge/via/vt8237r/vt8237r_early_smbus.c | 4 |
18 files changed, 133 insertions, 64 deletions
diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c index 5264e13e0d..957ec4559a 100644 --- a/src/arch/i386/boot/acpi.c +++ b/src/arch/i386/boot/acpi.c @@ -470,17 +470,6 @@ void suspend_resume(void) { void *wake_vec; -#if 0 -#if CONFIG_MEM_TRAIN_SEQ != 0 - #error "So far it works on AMD and CONFIG_MEM_TRAIN_SEQ == 0" -#endif - -#if CONFIG_RAMBASE < 0x1F00000 - #error "For ACPI RESUME you need to have CONFIG_RAMBASE at least 31MB" - #error "Chipset support (S3_NVRAM_EARLY and ACPI_IS_WAKEUP_EARLY functions and memory ctrl)" - #error "And coreboot memory reserved in mainboard.c" -#endif -#endif /* If we happen to be resuming find wakeup vector and jump to OS. */ wake_vec = acpi_find_wakeup_vector(); if (wake_vec) diff --git a/src/arch/i386/boot/tables.c b/src/arch/i386/boot/tables.c index 69e0539126..d816e76750 100644 --- a/src/arch/i386/boot/tables.c +++ b/src/arch/i386/boot/tables.c @@ -214,7 +214,7 @@ struct lb_memory *write_tables(void) * it begin there during reboot time. We don't need the pointer, nor * the result right now. If it fails, ACPI resume will be disabled. */ - cbmem_add(CBMEM_ID_RESUME, 1024 * (1024-64)); + cbmem_add(CBMEM_ID_RESUME, HIGH_MEMORY_SAVE); #endif #if CONFIG_MULTIBOOT 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 diff --git a/src/include/cbmem.h b/src/include/cbmem.h index d814a7285a..933f900e6a 100644 --- a/src/include/cbmem.h +++ b/src/include/cbmem.h @@ -24,7 +24,7 @@ #define HIGH_MEMORY_TABLES ( 64 * 1024 ) #if CONFIG_HAVE_ACPI_RESUME -#define HIGH_MEMORY_SIZE ( 1024 * 1024 ) +#define HIGH_MEMORY_SIZE ((CONFIG_RAMTOP - CONFIG_RAMBASE) + HIGH_MEMORY_TABLES) #define HIGH_MEMORY_SAVE ( HIGH_MEMORY_SIZE - HIGH_MEMORY_TABLES ) #else #define HIGH_MEMORY_SIZE HIGH_MEMORY_TABLES @@ -48,4 +48,6 @@ void *cbmem_find(u32 id); void cbmem_list(void); void cbmem_arch_init(void); +struct cbmem_entry *get_cbmem_toc(void); +void set_cbmem_toc(struct cbmem_entry *); #endif diff --git a/src/lib/cbmem.c b/src/lib/cbmem.c index 5490a1fef6..d85c748810 100644 --- a/src/lib/cbmem.c +++ b/src/lib/cbmem.c @@ -36,11 +36,32 @@ struct cbmem_entry { u64 size; } __attribute__((packed)); -#ifndef __PRE_RAM__ -struct cbmem_entry *bss_cbmem_toc; -#define get_cbmem_toc() bss_cbmem_toc + +#ifdef __PRE_RAM__ + +/* note this should be done as weak function but we do #include + of C files in the romstage breaking this (in same compile + unit is weak and non weak function +struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void) +*/ +#ifndef get_cbmem_toc + #define get_cbmem_toc() (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE) +#endif + #else -#define get_cbmem_toc() (struct cbmem_entry *)(get_top_of_ram() - HIGH_MEMORY_SIZE) + +static struct cbmem_entry *bss_cbmem_toc; + +struct cbmem_entry *__attribute__((weak)) get_cbmem_toc(void) +{ + return bss_cbmem_toc; +} + +void __attribute__((weak)) set_cbmem_toc(struct cbmem_entry * x) +{ + /* do nothing, this should be called by chipset to save TOC in NVRAM */ +} + #endif /** @@ -70,6 +91,10 @@ void cbmem_init(u64 baseaddr, u64 size) for (;;) ; } + /* we don't need to call this in romstage, usefull only from ramstage */ +#ifndef __PRE_RAM__ + set_cbmem_toc((struct cbmem_entry *)(unsigned long)baseaddr); +#endif memset(cbmem_toc, 0, CBMEM_TOC_RESERVED); cbmem_toc[0] = (struct cbmem_entry) { diff --git a/src/mainboard/asus/a8v-e_deluxe/romstage.c b/src/mainboard/asus/a8v-e_deluxe/romstage.c index bf096e1033..1167832c6a 100644 --- a/src/mainboard/asus/a8v-e_deluxe/romstage.c +++ b/src/mainboard/asus/a8v-e_deluxe/romstage.c @@ -79,7 +79,6 @@ void soft_reset(void) } } -// defines S3_NVRAM_EARLY: #include "southbridge/via/k8t890/k8t890_early_car.c" #include "northbridge/amd/amdk8/amdk8.h" #include "northbridge/amd/amdk8/incoherent_ht.c" diff --git a/src/mainboard/asus/a8v-e_se/romstage.c b/src/mainboard/asus/a8v-e_se/romstage.c index bf096e1033..1167832c6a 100644 --- a/src/mainboard/asus/a8v-e_se/romstage.c +++ b/src/mainboard/asus/a8v-e_se/romstage.c @@ -79,7 +79,6 @@ void soft_reset(void) } } -// defines S3_NVRAM_EARLY: #include "southbridge/via/k8t890/k8t890_early_car.c" #include "northbridge/amd/amdk8/amdk8.h" #include "northbridge/amd/amdk8/incoherent_ht.c" diff --git a/src/mainboard/asus/m2v-mx_se/Kconfig b/src/mainboard/asus/m2v-mx_se/Kconfig index 9e3b2649a6..8fd9ec089e 100644 --- a/src/mainboard/asus/m2v-mx_se/Kconfig +++ b/src/mainboard/asus/m2v-mx_se/Kconfig @@ -35,6 +35,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy select RAMINIT_SYSINFO select VGA select TINY_BOOTBLOCK + select HAVE_ACPI_RESUME select HAVE_MAINBOARD_RESOURCES select QRANK_DIMM_SUPPORT select SET_FIDVID diff --git a/src/mainboard/asus/m2v-mx_se/mainboard.c b/src/mainboard/asus/m2v-mx_se/mainboard.c index dcf97c37a7..614af3908e 100644 --- a/src/mainboard/asus/m2v-mx_se/mainboard.c +++ b/src/mainboard/asus/m2v-mx_se/mainboard.c @@ -34,13 +34,6 @@ int add_mainboard_resources(struct lb_memory *mem) lb_add_memory_range(mem, LB_MEM_RESERVED, uma_memory_base, uma_memory_size); #endif - -#if CONFIG_HAVE_ACPI_RESUME == 1 - lb_add_memory_range(mem, LB_MEM_RESERVED, - CONFIG_RAMBASE, ((CONFIG_RAMTOP) - CONFIG_RAMBASE)); - lb_add_memory_range(mem, LB_MEM_RESERVED, - CONFIG_DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_SIZE); -#endif return 0; } diff --git a/src/mainboard/asus/m2v-mx_se/romstage.c b/src/mainboard/asus/m2v-mx_se/romstage.c index 0849c862ba..65fdd115aa 100644 --- a/src/mainboard/asus/m2v-mx_se/romstage.c +++ b/src/mainboard/asus/m2v-mx_se/romstage.c @@ -62,7 +62,6 @@ static inline int spd_read_byte(unsigned device, unsigned address) return smbus_read_byte(device, address); } -// defines S3_NVRAM_EARLY: #include "southbridge/via/k8t890/k8t890_early_car.c" #include "northbridge/amd/amdk8/amdk8.h" #include "northbridge/amd/amdk8/incoherent_ht.c" @@ -75,6 +74,15 @@ static inline int spd_read_byte(unsigned device, unsigned address) #define SB_VFSMAF 0 + +// Now, this needs to be included because it relies on the symbol +// __PRE_RAM__ being set during CAR stage (in order to compile the +// BSS free versions of the functions). Either rewrite the code +// to be always BSS free, or invent a flag that's better suited than +// __PRE_RAM__ to determine whether we're in ram init stage (stage 1) +// +#include "lib/cbmem.c" + /* this function might fail on some K8 CPUs with errata #181 */ static void ldtstop_sb(void) { diff --git a/src/mainboard/asus/m2v/romstage.c b/src/mainboard/asus/m2v/romstage.c index d56ca9ce11..4c86f55657 100644 --- a/src/mainboard/asus/m2v/romstage.c +++ b/src/mainboard/asus/m2v/romstage.c @@ -64,7 +64,6 @@ static inline int spd_read_byte(unsigned device, unsigned address) return smbus_read_byte(device, address); } -// defines S3_NVRAM_EARLY: #include "southbridge/via/k8t890/k8t890_early_car.c" #include "northbridge/amd/amdk8/amdk8.h" #include "northbridge/amd/amdk8/incoherent_ht.c" diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index cc99e5123b..f592880b92 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -819,7 +819,8 @@ static u32 hoist_memory(unsigned long hole_startk, int node_id) #endif #if CONFIG_WRITE_HIGH_TABLES==1 -#define HIGH_TABLES_SIZE 64 /* maximum size of high tables in KB */ +#include <cbmem.h> +#define HIGH_TABLES_SIZE ((HIGH_MEMORY_SIZE + 1024) / 1024) extern uint64_t high_tables_base, high_tables_size; #endif diff --git a/src/northbridge/amd/amdk8/raminit_f.c b/src/northbridge/amd/amdk8/raminit_f.c index 0a1db664e1..fac30a849b 100644 --- a/src/northbridge/amd/amdk8/raminit_f.c +++ b/src/northbridge/amd/amdk8/raminit_f.c @@ -2988,14 +2988,15 @@ static void set_hw_mem_hole(int controllers, const struct mem_controller *ctrl) } #endif - +#if CONFIG_HAVE_ACPI_RESUME == 1 #include "exit_from_self.c" +#endif static void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo) { int i; -#ifdef ACPI_IS_WAKEUP_EARLY +#if CONFIG_HAVE_ACPI_RESUME == 1 int suspend = acpi_is_wakeup_early(); #else int suspend = 0; diff --git a/src/northbridge/amd/amdk8/raminit_f_dqs.c b/src/northbridge/amd/amdk8/raminit_f_dqs.c index 5303a67b32..8ddd44fadb 100644 --- a/src/northbridge/amd/amdk8/raminit_f_dqs.c +++ b/src/northbridge/amd/amdk8/raminit_f_dqs.c @@ -1826,25 +1826,7 @@ static void set_sysinfo_in_ram(unsigned val) set_htic_bit(0, val, 9); } -#ifdef S3_NVRAM_EARLY -// Don't define these prototypes as the real functions are already included -// at this point. -// -//int s3_save_nvram_early(u32 dword, int size, int nvram_pos); -//int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos); -#else -static inline int s3_save_nvram_early(u32 dword, int size, int nvram_pos) -{ - return nvram_pos; -} - -static inline int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) -{ - die("No memory NVRAM loader for DQS data! Unable to restore memory state\n"); - - return nvram_pos; /* Make GCC happy */ -} -#endif +#if CONFIG_HAVE_ACPI_RESUME == 1 #if CONFIG_MEM_TRAIN_SEQ == 0 static int save_index_to_pos(unsigned int dev, int size, int index, int nvram_pos) @@ -1930,6 +1912,7 @@ static void dqs_restore_MC_NVRAM(unsigned int dev) reg |= pci_read_config32(dev, DRAM_CONFIG_HIGH); pci_write_config32(dev, DRAM_CONFIG_HIGH, reg); } +#endif #if CONFIG_MEM_TRAIN_SEQ == 0 #if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1 @@ -1998,7 +1981,9 @@ static void dqs_timing(int controllers, const struct mem_controller *ctrl, struc if(train_DqsRcvrEn(ctrl+i, 2, sysinfo)) goto out; printk(BIOS_DEBUG, " done\n"); sysinfo->mem_trained[i]=1; +#if CONFIG_HAVE_ACPI_RESUME == 1 dqs_save_MC_NVRAM((ctrl+i)->f2); +#endif } out: diff --git a/src/southbridge/via/k8t890/k8t890.h b/src/southbridge/via/k8t890/k8t890.h index ce60d904cc..faa6a81d3d 100644 --- a/src/southbridge/via/k8t890/k8t890.h +++ b/src/southbridge/via/k8t890/k8t890.h @@ -31,6 +31,7 @@ /* The 256 bytes of NVRAM for S3 storage, 256B aligned */ #define K8T890_NVRAM_IO_BASE 0xf00 +#define K8T890_NVRAM_CBMEM_TOC 0xfc #define K8T890_MMCONFIG_MBAR 0x61 #define K8T890_MULTIPLE_FN_EN 0x4f diff --git a/src/southbridge/via/k8t890/k8t890_early_car.c b/src/southbridge/via/k8t890/k8t890_early_car.c index aa224a9469..94162cb90c 100644 --- a/src/southbridge/via/k8t890/k8t890_early_car.c +++ b/src/southbridge/via/k8t890/k8t890_early_car.c @@ -23,16 +23,14 @@ */ #include <stdlib.h> +#include <cbmem.h> +#include <arch/io.h> #include "k8t890.h" /* The 256 bytes of NVRAM for S3 storage, 256B aligned */ #define K8T890_NVRAM_IO_BASE 0xf00 #define K8T890_MULTIPLE_FN_EN 0x4f -/* we provide S3 NVRAM to system */ -#define S3_NVRAM_EARLY 1 - - /* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */ static u8 ldtreg[3] = {0x86, 0xa6, 0xc6}; @@ -155,3 +153,9 @@ static inline int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) printk(BIOS_DEBUG, "Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size); return nvram_pos; } + +/* this should be a function +struct cbmem_entry *get_cbmem_toc(void) { +*/ + +#define get_cbmem_toc() ((struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC)) diff --git a/src/southbridge/via/k8t890/k8t890_host_ctrl.c b/src/southbridge/via/k8t890/k8t890_host_ctrl.c index a1c42b7d59..43d01ee369 100644 --- a/src/southbridge/via/k8t890/k8t890_host_ctrl.c +++ b/src/southbridge/via/k8t890/k8t890_host_ctrl.c @@ -22,6 +22,8 @@ #include <device/pci_ops.h> #include <device/pci_ids.h> #include <console/console.h> +#include <cbmem.h> +#include <arch/io.h> #include "k8t890.h" /* this may be later merged */ @@ -111,6 +113,14 @@ static void host_ctrl_enable_k8m890(struct device *dev) { pci_write_config8(dev, 0xa6, 0x83); } +#if 0 +struct cbmem_entry *get_cbmem_toc(void) { + return (struct cbmem_entry *) inl(K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC); +} +#endif +void set_cbmem_toc(struct cbmem_entry *toc) { + outl((u32) toc, K8T890_NVRAM_IO_BASE+K8T890_NVRAM_CBMEM_TOC); +} static const struct device_operations host_ctrl_ops_t = { .read_resources = pci_dev_read_resources, diff --git a/src/southbridge/via/vt8237r/vt8237r_early_smbus.c b/src/southbridge/via/vt8237r/vt8237r_early_smbus.c index 07dffac4c0..a298e84676 100644 --- a/src/southbridge/via/vt8237r/vt8237r_early_smbus.c +++ b/src/southbridge/via/vt8237r/vt8237r_early_smbus.c @@ -316,9 +316,7 @@ void enable_rom_decode(void) pci_write_config8(dev, 0x41, 0x7f); } -#ifdef CONFIG_NORTHBRIDGE_AMD_K8 /* CN700 doesn't have the support yet */ -#define ACPI_IS_WAKEUP_EARLY 1 - +#if CONFIG_HAVE_ACPI_RESUME == 1 static int acpi_is_wakeup_early(void) { device_t dev; u16 tmp; |