===================================================================
@@ -9,6 +9,7 @@
#include <bitops.h>
#include <cpu/cpu.h>
#include <pc80/keyboard.h>
+#include <cbmem.h>
#include "chip.h"
#include "northbridge.h"
#include "i440bx.h"
@@ -34,7 +35,7 @@
};
#if CONFIG_WRITE_HIGH_TABLES==1
-#define HIGH_TABLES_SIZE 64 // maximum size of high tables in KB
+#define HIGH_TABLES_SIZE ((HIGH_MEMORY_SIZE + 1024) / 1024)
extern uint64_t high_tables_base, high_tables_size;
#endif
===================================================================
@@ -0,0 +1,248 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * original idea yhlu 6.2005 (assembler code)
+ *
+ * Copyright (C) 2010 Rudolf Marek <r.marek@assembler.cz>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * be warned, this file will be used other cores and core 0 / node 0
+ */
+#include <string.h>
+#include <arch/stages.h>
+#include <console/console.h>
+#include <cpu/x86/mtrr.h>
+#include <arch/acpi.h>
+#define get_cbmem_toc get_cbmem_toc
+#include <cbmem.h>
+#include "cpu/x86/mtrr/earlymtrr.c"
+// 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"
+
+#if CONFIG_RAMTOP <= 0x100000
+ #error "You need to set CONFIG_RAMTOP greater than 1M"
+#endif
+
+#define DCACHE_RAM_BASE (CONFIG_DCACHE_RAM_TOP - CONFIG_DCACHE_RAM_SIZE)
+
+static inline void print_debug_pcar(const char *strval, uint32_t val)
+{
+ printk(BIOS_DEBUG, "%s%08x\n", strval, val);
+}
+
+/* from linux kernel 2.6.32 asm/string_32.h */
+
+static void inline __attribute__((always_inline)) memcopy(void *dest, const void *src, unsigned long bytes)
+{
+ int d0, d1, d2;
+ asm volatile("cld ; rep ; movsl\n\t"
+ "movl %4,%%ecx\n\t"
+ "andl $3,%%ecx\n\t"
+ "jz 1f\n\t"
+ "rep ; movsb\n\t"
+ "1:"
+ : "=&c" (d0), "=&D" (d1), "=&S" (d2)
+ : "0" (bytes / 4), "g" (bytes), "1" ((long)dest), "2" ((long)src)
+ : "memory", "cc");
+}
+
+static u8 acpi_checksum(u8 *table, u32 length)
+{
+ u8 ret = 0;
+ while (length--) {
+ ret += *table;
+ table++;
+ }
+ return -ret;
+}
+
+static int valid_rsdp(acpi_rsdp_t *rsdp)
+{
+ unsigned *sig;
+ sig = (void*)rsdp;
+ if (*sig != 0x20445352)
+ return 0;
+ sig++;
+ if (*sig != 0x20525450)
+ return 0;
+
+ print_debug("Looking on ");
+ print_debug_hex32((u32)rsdp);
+ print_debug(" for valid checksum\n");
+
+ if (acpi_checksum((void *)rsdp, 20) != 0)
+ return 0;
+ print_debug("Checksum 1 passed\n");
+
+ if ((rsdp->revision > 1) &&
+ (acpi_checksum((void *)rsdp, rsdp->length) != 0))
+ return 0;
+ print_debug("Checksum 2 passed all OK\n");
+
+ return 1;
+}
+
+struct cbmem_entry *get_cbmem_toc(void)
+{
+ char *p;
+ acpi_rsdp_t *rsdp;
+ cbmem_toc_ptr_t *cbmem_tocp;
+
+ print_debug("Trying to find the backup area pointer...\n");
+
+ /* Find RSDP. */
+ rsdp = NULL;
+ for (p = (char *)0xe0000; p < (char *)0xfffff; p += 16) {
+ rsdp = (acpi_rsdp_t *)p;
+ if (valid_rsdp(rsdp))
+ break;
+ rsdp = NULL;
+ }
+
+ if (rsdp == NULL) {
+ print_debug("RSDP not found\n");
+ return NULL;
+ }
+
+ cbmem_tocp = (cbmem_toc_ptr_t *)(rsdp->rsdt_address - sizeof(cbmem_toc_ptr_t));
+ if (cbmem_tocp->sig != CBMEM_TOC_PTR_SIG) {
+ printk(BIOS_DEBUG, "cbmem toc pointer not found at %p (sig %08x sz %d)\n", cbmem_tocp, cbmem_tocp->sig, sizeof(cbmem_toc_ptr_t));
+ return NULL;
+ }
+
+ return cbmem_tocp->ptr;
+}
+
+static inline void *backup_resume(void) {
+ unsigned long high_ram_base;
+ void *resume_backup_memory;
+
+ /* Start address of high memory tables */
+ high_ram_base = (u32) get_cbmem_toc();
+
+ print_debug_pcar("CBMEM TOC is at: ", high_ram_base);
+ print_debug_pcar("CBMEM TOC 0-size: ", (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;
+}
+
+void enable_pm(void);
+int acpi_get_sleep_type(void);
+
+void* acpi_resume_post_main(void);
+void acpi_resume_post_cache_as_ram(void *resume_backup_memory);
+
+void* acpi_resume_post_main(void)
+{
+ int sleep_type;
+ void *resume_backup_memory = NULL;
+
+ enable_pm();
+ sleep_type = acpi_get_sleep_type();
+
+#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)
+ );
+ print_debug_pcar("v_esp=", v_esp);
+ }
+#endif
+
+ unsigned testx = 0x5a5a5a5a;
+ print_debug_pcar("testx = ", testx);
+
+ /* copy data from cache as ram to
+ ram need to set CONFIG_RAMTOP to 2M and use var mtrr instead.
+ */
+ if (sleep_type == 2 || sleep_type == 3)
+ resume_backup_memory = backup_resume();
+
+ printk(BIOS_DEBUG, "resume_backup_memory=%p\n", resume_backup_memory);
+
+ print_debug("Copying data from cache to RAM -- switching to use RAM as stack... ");
+
+ memcopy((void *)((CONFIG_RAMTOP)-CONFIG_DCACHE_RAM_SIZE), (void *)DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_SIZE); //inline
+
+ __asm__ volatile (
+ /* set new esp */ /* before CONFIG_RAMBASE */
+ "subl %0, %%esp\n\t"
+ ::"a"( (DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)- (CONFIG_RAMTOP) )
+ /* discard all registers (eax is used for %0), so gcc redo everything
+ after the stack is moved */
+ : "cc", "memory", "%ebx", "%ecx", "%edx", "%esi", "%edi", "%ebp"
+ );
+
+ /* We can put data to stack again */
+
+ /* only global variable sysinfo in cache need to be offset */
+ print_debug("Done\n");
+ print_debug_pcar("testx = ", testx);
+
+ return resume_backup_memory;
+}
+
+void acpi_resume_post_cache_as_ram(void *resume_backup_memory)
+{
+ print_debug("After cache as ram disabled \n");
+ printk(BIOS_DEBUG, "resume_backup_memory=%p\n", resume_backup_memory);
+
+ /* 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);
+ }
+
+ print_debug("Clearing initial memory region: ");
+
+ /* 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);
+ print_debug("Done\n");
+
+ /*copy and execute coreboot_ram */
+ copy_and_run(0);
+ /* We will not return */
+
+ print_debug("should not be here -\n");
+ for (;;);
+}
===================================================================
@@ -26,8 +26,12 @@
#include <cpu/x86/mtrr.h>
#include <cpu/x86/lapic_def.h>
+#ifndef CONFIG_DCACHE_RAM_TOP
+#define CONFIG_DCACHE_RAM_TOP 0xd0000
+#endif
+
#define CacheSize CONFIG_DCACHE_RAM_SIZE
-#define CacheBase (0xd0000 - CacheSize)
+#define CacheBase (CONFIG_DCACHE_RAM_TOP - CacheSize)
save_bist_result()
@@ -325,6 +329,11 @@
pushl %eax /* BIST */
call main
+#if CONFIG_HAVE_ACPI_RESUME && CONFIG_POST_CAR_RESUME
+ call acpi_resume_post_main
+ pushl %eax /* save resume_backup_memory pointer */
+#endif
+
/* We don't need CAR from now on. */
disable_cache()
@@ -351,6 +360,13 @@
enable_cache();
+#if CONFIG_HAVE_ACPI_RESUME && CONFIG_POST_CAR_RESUME
+ popl %eax
+ movl %esp, %ebp
+ pushl %eax /* resume_backup_memory pointer */
+ call acpi_resume_post_cache_as_ram
+#endif
+
/* Clear boot_complete flag. */
xorl %ebp, %ebp
__main:
===================================================================
@@ -357,6 +357,8 @@
u8 ec_id[]; /* EC ID */
} __attribute__ ((packed)) acpi_ecdt_t;
+#if !defined(__PRE_RAM__)
+
/* These are implemented by the target port or north/southbridge. */
unsigned long write_acpi_tables(unsigned long addr);
unsigned long acpi_fill_madt(unsigned long current);
@@ -431,6 +433,8 @@
/* cpu/intel/speedstep/acpi.c */
void generate_cpu_entries(void);
+#endif // __PRE_RAM__
+
#else // CONFIG_GENERATE_ACPI_TABLES
#define write_acpi_tables(start) (start)
===================================================================
@@ -16,6 +16,7 @@
subdirs-$(CONFIG_CPU_INTEL_SOCKET_PGA370) += socket_PGA370
subdirs-$(CONFIG_CPU_INTEL_SLOT_2) += slot_2
subdirs-$(CONFIG_CPU_INTEL_SLOT_1) += slot_1
+subdirs-$(CONFIG_CPU_INTEL) += car
#socket_mPGA604_533Mhz
#socket_mPGA604_800Mhz
===================================================================
@@ -0,0 +1,21 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2010 Tobias Diedrich <ranma+coreboot@tdiedrich.de>
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program is distributed in the hope that it will be useful,
+## but WITHOUT ANY WARRANTY; without even the implied warranty of
+## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+## GNU General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program; if not, write to the Free Software
+## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+##
+
+romstage-$(CONFIG_POST_CAR_RESUME) += post_cache_as_ram.c
===================================================================
@@ -28,3 +28,17 @@
source src/cpu/intel/socket_mPGA604/Kconfig
source src/cpu/intel/socket_PGA370/Kconfig
source src/cpu/intel/socket_441/Kconfig
+
+config CPU_INTEL
+ bool
+ default n
+
+config POST_CAR_RESUME
+ bool
+ default n
+
+config DCACHE_RAM_TOP
+ hex
+ default 0xd0000
+ depends on CACHE_AS_RAM
+ depends on CPU_INTEL
===================================================================
@@ -40,6 +40,11 @@
*/
Name (\_S0, Package () { 0x05, 0x05, 0x00, 0x00 })
Name (\_S1, Package () { 0x03, 0x03, 0x00, 0x00 })
+ Name (\_S2, Package () { 0x02, 0x02, 0x00, 0x00 })
+ Name (\_S3, Package () { 0x01, 0x01, 0x00, 0x00 })
+ /* Note: S4 would be suspend to disk, which would require smm code,
+ * but Linux and Windows handle suspend to disk themselves, so we
+ * don't need this */
Name (\_S5, Package () { 0x00, 0x00, 0x00, 0x00 })
OperationRegion (SIO1, SystemIO, Add(DEFAULT_PMBASE, GPO0), 2)
===================================================================
@@ -30,3 +30,4 @@
romstage-y += i82371eb_early_pm.c
romstage-y += i82371eb_early_smbus.c
+romstage-$(CONFIG_HAVE_ACPI_RESUME) += i82371eb_wakeup.c
===================================================================
@@ -20,6 +20,9 @@
config CPU_INTEL_SLOT_1
bool
select CACHE_AS_RAM
+ select CPU_INTEL
+ select POST_CAR_RESUME if GENERATE_ACPI_TABLES
+
config DCACHE_RAM_SIZE
hex
Slot-1 boards: asus/p3b-f asus/p2b-ds asus/p2b-f asus/p2b-d asus/p2b asus/p2b-ls azza/pt-6ibd gigabyte/ga-6bxc gigabyte/ga-6bxe compaq/deskpro_en_sff_p600 a-trend/atc-6220 a-trend/atc-6240 tyan/s1846 msi/ms6119 msi/ms6147 msi/ms6156 soyo/sy-6ba-plus-iii abit/be6-ii_v2_0 biostar/m6tba Slot-1 boards with HAVE_ACPI_TABLES: asus/p2b Abuild-tested. Tested on P2B (Slot1 440BX/82371EB). Tested on M2V (Socket AM2/K8T890/VT8237A) to make sure S3 still works with all 3 patches applied. Signed-off-by: Tobias Diedrich <ranma+coreboot@tdiedrich.de> ---