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 <[email protected]>

---

Index: src/northbridge/intel/i440bx/northbridge.c
===================================================================
--- src/northbridge/intel/i440bx/northbridge.c.orig     2010-12-01 
19:11:34.000000000 +0100
+++ src/northbridge/intel/i440bx/northbridge.c  2010-12-01 19:11:40.000000000 
+0100
@@ -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
 
Index: src/cpu/intel/car/post_cache_as_ram.c
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ src/cpu/intel/car/post_cache_as_ram.c       2010-12-01 19:11:40.000000000 
+0100
@@ -0,0 +1,248 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * original idea yhlu 6.2005 (assembler code)
+ *
+ * Copyright (C) 2010 Rudolf Marek <[email protected]>
+ *
+ * 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 (;;);
+}
Index: src/cpu/intel/car/cache_as_ram.inc
===================================================================
--- src/cpu/intel/car/cache_as_ram.inc.orig     2010-12-01 19:11:34.000000000 
+0100
+++ src/cpu/intel/car/cache_as_ram.inc  2010-12-01 19:11:40.000000000 +0100
@@ -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:
Index: src/arch/i386/include/arch/acpi.h
===================================================================
--- src/arch/i386/include/arch/acpi.h.orig      2010-12-01 19:11:34.000000000 
+0100
+++ src/arch/i386/include/arch/acpi.h   2010-12-01 19:11:40.000000000 +0100
@@ -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)
Index: src/cpu/intel/Makefile.inc
===================================================================
--- src/cpu/intel/Makefile.inc.orig     2010-12-01 19:11:34.000000000 +0100
+++ src/cpu/intel/Makefile.inc  2010-12-01 19:11:40.000000000 +0100
@@ -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
Index: src/cpu/intel/car/Makefile.inc
===================================================================
--- /dev/null   1970-01-01 00:00:00.000000000 +0000
+++ src/cpu/intel/car/Makefile.inc      2010-12-01 19:11:40.000000000 +0100
@@ -0,0 +1,21 @@
+##
+## This file is part of the coreboot project.
+##
+## Copyright (C) 2010 Tobias Diedrich <[email protected]>
+##
+## 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
Index: src/cpu/intel/Kconfig
===================================================================
--- src/cpu/intel/Kconfig.orig  2010-12-01 19:11:34.000000000 +0100
+++ src/cpu/intel/Kconfig       2010-12-01 19:11:40.000000000 +0100
@@ -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
Index: src/mainboard/asus/p2b/dsdt.asl
===================================================================
--- src/mainboard/asus/p2b/dsdt.asl.orig        2010-12-01 19:11:34.000000000 
+0100
+++ src/mainboard/asus/p2b/dsdt.asl     2010-12-01 19:11:40.000000000 +0100
@@ -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)
Index: src/southbridge/intel/i82371eb/Makefile.inc
===================================================================
--- src/southbridge/intel/i82371eb/Makefile.inc.orig    2010-12-01 
19:11:34.000000000 +0100
+++ src/southbridge/intel/i82371eb/Makefile.inc 2010-12-01 19:11:40.000000000 
+0100
@@ -30,3 +30,4 @@
 
 romstage-y += i82371eb_early_pm.c
 romstage-y += i82371eb_early_smbus.c
+romstage-$(CONFIG_HAVE_ACPI_RESUME) += i82371eb_wakeup.c
Index: src/cpu/intel/slot_1/Kconfig
===================================================================
--- src/cpu/intel/slot_1/Kconfig.orig   2010-12-01 19:11:34.000000000 +0100
+++ src/cpu/intel/slot_1/Kconfig        2010-12-01 19:25:18.000000000 +0100
@@ -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


-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to