-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi all,
Here is yet another WIP. I need bit help to solve some issues: 1) include file mess in CAR In src/southbridge/via/k8t890/k8t890_early_car.c I'm not able to include the nb header file. There is a NVRAM base with #define. Now I just duplicated the macro. The reason why it does not go is in the rest of k8t890.h because of prototype for writeback function. Eventually we might get rid of writeback... 2) src/northbridge/amd/amdk8/exit_from_self.c I'm not able to do: ctrl[i].f2->path.pci.devfn Compiler complains dont know why. I solved it like: ctrl[i].node_id + 0x18) << 3) | 0x2 Not ideal but works 3) I have an idea how to do the realmode memory reservation for coreboot. I simply made RSDP table much larger (this table stays below 1MB). during resume I copy there simple trampoline which turns off PE and do the ljmp to waking vector. Unfortunately this does not work for some reason. I believe the CS base of GDT is invalid perhaps I should there base not zero? The code should execute like this: set GDT set LDT jmp ebx -> to code inside the variable jump_to_wakeup. because I cannot do the direct ljmp $0x0008,%0 because rsdp space address is run-time. So inside the jump_to_wakeup I load CS with the new GDT value and jump to the lowmem where I put the simple code: movl %cr0,%eax andb $0xfe,al movl %eax,%cr0 jmp far waking vector It is bit hard to follow but please have a look to a patch. Here is some real example: Trying to find the wakeup vector ... Looking on 000f9560 for valid checksum Checksum 1 passed RSDP found at 000f9560 RSDT found at 1bff0424 ends at 1bff0464 FADT found at 1bff0e62 FACS found at 1bff0480 OS waking vector is 0001a000 The RSDP is at 000f9560 spare memory at: 000f9584 IN ACPI JUMP WAKE TO 1a000 ea 0 0 0 1a ea 84 95 f 0 8 0 (CPU resets here) As I have written I believe that problem is in selector 0x8 which has base 0 and limit 64KB perhaps it should have base f0000 to fit the location of the low table? Hope it is more clear -> I need sleep. Looking forward for suggestions. Oh btw even without this 3) Windows 7 and Linux S3 mode works (I put the trampoline to last bytes of first 4KB). Rudolf -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAknb2CkACgkQ3J9wPJqZRNVz5wCg19DyDMpmifJAJrSmiYSYSQBB oZ8AoKbLNbDG3MYaVyY6/uCDoSKIXNdx =/B0n -----END PGP SIGNATURE-----
Index: src/southbridge/via/vt8237r/vt8237r_early_smbus.c
===================================================================
--- src/southbridge/via/vt8237r/vt8237r_early_smbus.c (revision 4074)
+++ src/southbridge/via/vt8237r/vt8237r_early_smbus.c (working copy)
@@ -294,6 +294,31 @@
pci_write_config8(dev, 0x41, 0x7f);
}
+
+int acpi_is_wakeup_early(void) {
+ device_t dev;
+ u16 tmp;
+
+ print_debug("IN TEST WAKEUP\n");
+ /* Power management controller */
+ dev = pci_locate_device(PCI_ID(PCI_VENDOR_ID_VIA,
+ PCI_DEVICE_ID_VIA_VT8237S_LPC), 0);
+
+ if (dev == PCI_DEV_INVALID)
+ die("Power management controller not found\r\n");
+
+ /* Set ACPI base address to I/O VT8237R_ACPI_IO_BASE. */
+ pci_write_config16(dev, 0x88, VT8237R_ACPI_IO_BASE | 0x1);
+
+ /* Enable ACPI accessm RTC signal gated with PSON. */
+ pci_write_config8(dev, 0x81, 0x84);
+
+ tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
+
+ print_debug_hex8(tmp);
+ return ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
+}
+
#if defined(__GNUC__)
void vt8237_early_spi_init(void)
{
Index: src/southbridge/via/vt8237r/vt8237r_lpc.c
===================================================================
--- src/southbridge/via/vt8237r/vt8237r_lpc.c (revision 4074)
+++ src/southbridge/via/vt8237r/vt8237r_lpc.c (working copy)
@@ -149,8 +149,13 @@
* Set up the power management capabilities directly into ACPI mode.
* This avoids having to handle any System Management Interrupts (SMIs).
*/
+
+extern u8 acpi_slp_type;
+
+
static void setup_pm(device_t dev)
{
+ u16 tmp;
/* Debounce LID and PWRBTN# Inputs for 16ms. */
pci_write_config8(dev, 0x80, 0x20);
@@ -171,10 +176,10 @@
/*
* 7 = SMBus clock from RTC 32.768KHz
- * 5 = Internal PLL reset from susp
- * 2 = GPO2 is GPIO
+ * 5 = Internal PLL reset from susp disabled
+ * 2 = GPO2 is SUSA#
*/
- pci_write_config8(dev, 0x94, 0xa4);
+ pci_write_config8(dev, 0x94, 0xa0);
/*
* 7 = stp to sust delay 1msec
@@ -219,7 +224,17 @@
outb(0x0, VT8237R_ACPI_IO_BASE + 0x42);
/* SCI is generated for RTC/pwrBtn/slpBtn. */
- outw(0x001, VT8237R_ACPI_IO_BASE + 0x04);
+ tmp = inw(VT8237R_ACPI_IO_BASE + 0x04);
+ acpi_slp_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ;
+ printk_debug("SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
+ /* clear sleep */
+ tmp &= ~(7 << 10);
+ tmp |= 1;
+ outw(tmp, VT8237R_ACPI_IO_BASE + 0x04);
+
+
+
+
}
static void vt8237r_init(struct device *dev)
Index: src/southbridge/via/k8t890/k8t890_early_car.c
===================================================================
--- src/southbridge/via/k8t890/k8t890_early_car.c (revision 4074)
+++ src/southbridge/via/k8t890/k8t890_early_car.c (working copy)
@@ -23,7 +23,15 @@
*/
#include <stdlib.h>
+//include "k8t890.h"
+#warning hack the right header here
+/* The 256 bytes of NVRAM for S3 storage, 256B aligned */
+#define K8T890_NVRAM_IO_BASE 0xf00
+#define K8T890_MULTIPLE_FN_EN 0x4f
+
+
+
/* AMD K8 LDT0, LDT1, LDT2 Link Control Registers */
static ldtreg[3] = {0x86, 0xa6, 0xc6};
@@ -33,10 +41,22 @@
u8 k8t890_early_setup_ht(void)
{
- u8 awidth, afreq, cldtfreq;
+ u8 awidth, afreq, cldtfreq, reg;
u8 cldtwidth_in, cldtwidth_out, vldtwidth_in, vldtwidth_out, ldtnr, width;
u16 vldtcaps;
+ /* hack, enable NVRAM in chipset */
+ pci_write_config8(PCI_DEV(0, 0x0, 0), K8T890_MULTIPLE_FN_EN, 0x01);
+
+ /*
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
+ */
+
+ pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+ reg = pci_read_config8(PCI_DEV(0, 0x0, 2), 0xa1);
+ reg |= 0x1;
+ pci_write_config8(PCI_DEV(0, 0x0, 2), 0xa1, reg);
+
/* check if connected non coherent, initcomplete (find the SB on K8 side) */
if (0x7 == pci_read_config8(PCI_DEV(0, 0x18, 0), 0x98)) {
ldtnr = 0;
@@ -90,3 +110,44 @@
return 1;
}
+
+int s3_save_nvram_early(u32 dword, int size, int nvram_pos) {
+
+ printk_debug("Writing %x of size %d to nvram pos: %d\n", dword, size, nvram_pos);
+ switch (size) {
+ case 1:
+ outb((dword & 0xff), K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=1;
+ break;
+ case 2:
+ outw((dword & 0xffff), K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=2;
+ break;
+ default:
+ outl(dword, K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=4;
+ break;
+ }
+ return nvram_pos;
+}
+
+int s3_load_nvram_early(int size, u32 *old_dword, int nvram_pos) {
+ switch (size) {
+ case 1:
+ *old_dword &= ~0xff;
+ *old_dword |= inb(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=1;
+ break;
+ case 2:
+ *old_dword &= ~0xffff;
+ *old_dword |= inw(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=2;
+ break;
+ default:
+ *old_dword = inl(K8T890_NVRAM_IO_BASE+nvram_pos);
+ nvram_pos +=4;
+ break;
+ }
+ printk_debug("Loading %x of size %d to nvram pos:%d\n", * old_dword, size, nvram_pos-size);
+ return nvram_pos;
+}
Index: src/southbridge/via/k8t890/k8t890_host_ctrl.c
===================================================================
--- src/southbridge/via/k8t890/k8t890_host_ctrl.c (revision 4074)
+++ src/southbridge/via/k8t890/k8t890_host_ctrl.c (working copy)
@@ -37,14 +37,14 @@
*/
pci_write_config8(dev, 0xa0, 0x13);
- /* Disable NVRAM and enable non-posted PCI writes. */
- pci_write_config8(dev, 0xa1, 0x8e);
-
/*
- * NVRAM I/O base 0xe00-0xeff, but it is disabled.
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
* Some bits are set and reserved.
*/
- pci_write_config8(dev, 0xa2, 0x0e);
+ pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+
+ /* enable NB NVRAM and enable non-posted PCI writes. */
+ pci_write_config8(dev, 0xa1, 0x8f);
/* Arbitration control, some bits are reserved. */
pci_write_config8(dev, 0xa5, 0x3c);
@@ -95,14 +95,15 @@
*/
pci_write_config8(dev, 0xa0, 0x13);
- /* Disable NVRAM and enable non-posted PCI writes. */
- pci_write_config8(dev, 0xa1, 0x8e);
-
/*
- * NVRAM I/O base 0xe00-0xeff, but it is disabled.
+ * NVRAM I/O base at K8T890_NVRAM_IO_BASE
*/
- pci_write_config8(dev, 0xa2, 0x0e);
+ pci_write_config8(dev, 0xa2, (K8T890_NVRAM_IO_BASE >> 8));
+
+ /* Enable NVRAM and enable non-posted PCI writes. */
+ pci_write_config8(dev, 0xa1, 0x8f);
+
/* Arbitration control */
pci_write_config8(dev, 0xa5, 0x3c);
Index: src/southbridge/via/k8t890/k8t890.h
===================================================================
--- src/southbridge/via/k8t890/k8t890.h (revision 4074)
+++ src/southbridge/via/k8t890/k8t890.h (working copy)
@@ -29,6 +29,9 @@
*/
#define K8T890_APIC_BASE 0xfecc0000
+/* The 256 bytes of NVRAM for S3 storage, 256B aligned */
+#define K8T890_NVRAM_IO_BASE 0xf00
+
#define K8T890_MMCONFIG_MBAR 0x61
#define K8T890_MULTIPLE_FN_EN 0x4f
@@ -36,6 +39,7 @@
#define K8M890_FBSIZEMB 64
#include <device/device.h>
+
extern void writeback(struct device *dev, u16 where, u8 what);
extern void dump_south(device_t dev);
Index: src/superio/ite/it8712f/it8712f_early_serial.c
===================================================================
--- src/superio/ite/it8712f/it8712f_early_serial.c (revision 4074)
+++ src/superio/ite/it8712f/it8712f_early_serial.c (working copy)
@@ -32,6 +32,7 @@
#define IT8712F_CONFIG_REG_CONFIGSEL 0x22 /* Configuration Select. */
#define IT8712F_CONFIG_REG_CLOCKSEL 0x23 /* Clock Selection. */
#define IT8712F_CONFIG_REG_SWSUSP 0x24 /* Software Suspend, Flash I/F. */
+#define IT8712F_CONFIG_REG_MFC 0x2a /* Multi-function control */
#define IT8712F_CONFIG_REG_WATCHDOG 0x72 /* Watchdog control. */
#define IT8712F_CONFIGURATION_PORT 0x2e /* Write-only. */
@@ -78,6 +79,21 @@
}
+static void it8712f_enable_3vsbsw(void) {
+
+ /* We need to set enable 3VSBSW#, this was documented only in IT8712F_V0.9.2!
+ LDN 7, reg 0x2a - needed for S3, or memory power will be cut off.
+ Enable 3VSBSW#. (For System Suspend-to-RAM)
+ 0: 3VSBSW# will be always inactive.
+ 1: 3VSBSW# enabled. It will be (NOT SUSB#) NAND SUSC#.
+ */
+
+ it8712f_enter_conf();
+ it8712f_sio_write(0x07, IT8712F_CONFIG_REG_MFC, 0x80);
+ it8712f_exit_conf();
+}
+
+
static void it8712f_kill_watchdog(void)
{
it8712f_enter_conf();
Index: src/cpu/amd/model_fxx/fidvid.c
===================================================================
--- src/cpu/amd/model_fxx/fidvid.c (revision 4074)
+++ src/cpu/amd/model_fxx/fidvid.c (working copy)
@@ -73,7 +73,8 @@
// dword = 0x00070000; /* enable FID/VID change */
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0x80, dword);
- dword = 0x00132113;
+ //2113_2113h
+ dword = 0x21132113;
pci_write_config32(PCI_DEV(0, 0x18+i, 3), 0x84, dword);
}
Index: src/cpu/amd/car/copy_and_run.c
===================================================================
--- src/cpu/amd/car/copy_and_run.c (revision 4074)
+++ src/cpu/amd/car/copy_and_run.c (working copy)
@@ -21,9 +21,10 @@
static void copy_and_run(void)
{
uint8_t *src, *dst;
+ int i;
+ u32 *p = 4*1024;
unsigned long ilen, olen;
-
#if !CONFIG_COMPRESS
print_debug("Copying coreboot to RAM.\r\n");
__asm__ volatile (
Index: src/cpu/amd/car/clear_init_ram.c
===================================================================
--- src/cpu/amd/car/clear_init_ram.c (revision 4074)
+++ src/cpu/amd/car/clear_init_ram.c (working copy)
@@ -6,8 +6,7 @@
// gcc 3.4.5 will inline the copy_and_run and clear_init_ram in post_cache_as_ram
// will reuse %edi as 0 from clear_memory for copy_and_run part, actually it is increased already
// so noline clear_init_ram
- clear_memory(0, ((CONFIG_LB_MEM_TOPK<<10) - DCACHE_RAM_SIZE));
-
+ clear_memory( _RAMBASE, (CONFIG_LB_MEM_TOPK << 10) - _RAMBASE - DCACHE_RAM_SIZE);
}
/* be warned, this file will be used by core other than core 0/node 0 or core0/node0 when cpu_reset*/
Index: src/cpu/x86/lapic/lapic_cpu_init.c
===================================================================
--- src/cpu/x86/lapic/lapic_cpu_init.c (revision 4074)
+++ src/cpu/x86/lapic/lapic_cpu_init.c (working copy)
@@ -31,6 +31,10 @@
}
#endif
+char *lowmem_backup;
+char *lowmem_backup_ptr;
+int lowmem_backup_size;
+
static void copy_secondary_start_to_1m_below(void)
{
#if _RAMBASE >= 0x100000
@@ -45,6 +49,15 @@
start_eip = get_valid_start_eip((unsigned long)_secondary_start);
code_size = (unsigned long)_secondary_start_end - (unsigned long)_secondary_start;
+ /* need to save it for RAM resume */
+ lowmem_backup_size = code_size;
+ lowmem_backup = malloc(code_size);
+ lowmem_backup_ptr = (unsigned char *)start_eip;
+
+ if (lowmem_backup == NULL)
+ die("Out of backup memory\n");
+
+ memcpy(lowmem_backup, lowmem_backup_ptr, lowmem_backup_size);
/* copy the _secondary_start to the ram below 1M*/
memcpy((unsigned char *)start_eip, (unsigned char *)_secondary_start, code_size);
Index: src/mainboard/asus/m2v-mx_se/Options.lb
===================================================================
--- src/mainboard/asus/m2v-mx_se/Options.lb (revision 4074)
+++ src/mainboard/asus/m2v-mx_se/Options.lb (working copy)
@@ -157,9 +157,9 @@
default STACK_SIZE = 8 * 1024
default HEAP_SIZE = 256 * 1024
# More 1M for pgtbl.
-default CONFIG_LB_MEM_TOPK = 2048
+default CONFIG_LB_MEM_TOPK = 32768
# to 1MB
-default _RAMBASE = 0x100000
+default _RAMBASE = 0x1F00000
# default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
default CONFIG_ROM_PAYLOAD = 1
default CC = "$(CROSS_COMPILE)gcc -m32"
Index: src/mainboard/asus/m2v-mx_se/dsdt.asl
===================================================================
--- src/mainboard/asus/m2v-mx_se/dsdt.asl (revision 4074)
+++ src/mainboard/asus/m2v-mx_se/dsdt.asl (working copy)
@@ -30,8 +30,24 @@
* Any others would involve declaring the wake up methods.
*/
Name (\_S0, Package () { 0x00, 0x00, 0x00, 0x00 })
+ Name (\_S3, Package () { 0x01, 0x01, 0x00, 0x00 })
Name (\_S5, Package () { 0x02, 0x02, 0x00, 0x00 })
+
+ /* blink a LED when entering the sleep (any type) */
+ Method (_PTS, 1, NotSerialized)
+ {
+ Store (0x1, \_SB.PCI0.ISA.LEDR)
+ }
+
+ /* cancel a LED blinking when waking from sleep (any type) */
+ Method (_WAK, 1, NotSerialized)
+ {
+ Store (0x0, \_SB.PCI0.ISA.LEDR)
+ /* wake OK */
+ Return(Package(0x02){0x00, 0x00})
+ }
+
/* Root of the bus hierarchy */
Scope (\_SB)
{
@@ -160,7 +176,14 @@
}
Device (ISA) {
Name (_ADR, 0x00110000)
-
+ OperationRegion (PCIC, PCI_Config, 0x0, 0xff)
+ Field (PCIC, ByteAcc, NoLock, Preserve)
+ {
+ Offset (0x94),
+ /* two LSB bits are blink rate */
+ LEDR, 2,
+ }
+
/* PS/2 keyboard (seems to be important for WinXP install) */
Device (KBD)
{
Index: src/mainboard/asus/m2v-mx_se/mainboard.c
===================================================================
--- src/mainboard/asus/m2v-mx_se/mainboard.c (revision 4074)
+++ src/mainboard/asus/m2v-mx_se/mainboard.c (working copy)
@@ -29,11 +29,25 @@
int add_mainboard_resources(struct lb_memory *mem)
{
+ extern char _secondary_start[];
+ extern char _secondary_start_end[];
+ unsigned long code_size;
+
#if HAVE_HIGH_TABLES == 1
printk_debug("Adding high table area\n");
lb_add_memory_range(mem, LB_MEM_TABLE,
high_tables_base, high_tables_size);
#endif
+ lb_add_memory_range(mem, LB_MEM_RESERVED,
+ _RAMBASE, ((CONFIG_LB_MEM_TOPK<<10) - _RAMBASE));
+ lb_add_memory_range(mem, LB_MEM_RESERVED,
+ DCACHE_RAM_BASE, DCACHE_RAM_SIZE);
+
+ code_size = (unsigned long)_secondary_start_end - (unsigned long)_secondary_start;
+
+ lb_add_memory_range(mem, LB_MEM_RESERVED,
+ _secondary_start, code_size);
+
return 0;
}
Index: src/mainboard/asus/m2v-mx_se/cache_as_ram_auto.c
===================================================================
--- src/mainboard/asus/m2v-mx_se/cache_as_ram_auto.c (revision 4074)
+++ src/mainboard/asus/m2v-mx_se/cache_as_ram_auto.c (working copy)
@@ -242,10 +242,12 @@
struct sys_info *sysinfo =
(DCACHE_RAM_BASE + DCACHE_RAM_SIZE - DCACHE_RAM_GLOBAL_VAR_SIZE);
char *p;
+ u8 reg;
sio_init();
it8712f_enable_serial(SERIAL_DEV, TTYS0_BASE);
it8712f_kill_watchdog();
+ it8712f_enable_3vsbsw();
uart_init();
console_init();
enable_rom_decode();
Index: src/boot/hardwaremain.c
===================================================================
--- src/boot/hardwaremain.c (revision 4074)
+++ src/boot/hardwaremain.c (working copy)
@@ -38,6 +38,162 @@
#include <boot/elf.h>
#include <romfs.h>
+//reboot.c from linux
+
+#include <stdint.h>
+#include <string.h>
+#include <arch/io.h>
+#include <console/console.h>
+
+/* The following code and data reboots the machine by switching to real
+ mode and jumping to the BIOS reset entry point, as if the CPU has
+ really been reset. The previous version asked the keyboard
+ controller to pulse the CPU reset line, which is more thorough, but
+ doesn't work with at least one type of 486 motherboard. It is easy
+ to stop this code working; hence the copious comments. */
+
+static unsigned long long
+real_mode_gdt_entries [3] =
+{
+ 0x0000000000000000ULL, /* Null descriptor */
+ 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */
+ 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */
+};
+
+struct Xgt_desc_struct {
+ unsigned short size;
+ unsigned long address __attribute__((packed));
+ unsigned short pad;
+ } __attribute__ ((packed));
+
+static struct Xgt_desc_struct
+real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, (long)real_mode_gdt_entries },
+real_mode_idt = { 0x3ff, 0 },
+no_idt = { 0, 0 };
+
+
+/* This is 16-bit protected mode code to disable paging and the cache,
+ switch to real mode and jump to the BIOS reset code.
+
+ The instruction that switches to real mode by writing to CR0 must be
+ followed immediately by a far jump instruction, which set CS to a
+ valid value for real mode, and flushes the prefetch queue to avoid
+ running instructions that have already been decoded in protected
+ mode.
+
+ Clears all the flags except ET, especially PG (paging), PE
+ (protected-mode enable) and TS (task switch for coprocessor state
+ save). Flushes the TLB after paging has been disabled. Sets CD and
+ NW, to disable the cache on a 486, and invalidates the cache. This
+ is more like the state of a 486 after reset. I don't know if
+ something else should be done for other chips.
+
+ More could be done here to set up the registers as if a CPU reset had
+ occurred; hopefully real BIOSs don't assume much. */
+
+
+// 0x66, 0x0d, 0x00, 0x00, 0x00, 0x60, /* orl $0x60000000,%eax */
+
+static unsigned char real_mode_switch [] =
+{
+ 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */
+ 0x24, 0xfe, /* andb $0xfe,al */
+ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */
+};
+static unsigned char jump_to_wakeup [] =
+{
+ 0xea, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00 /* ljmp $0xffff,$0x0000 */
+};
+
+/*
+ * Switch to real mode and then execute the code
+ * specified by the code and length parameters.
+ * We assume that length will aways be less that 100!
+ */
+
+
+static void dump_mem(u32 start, u32 end)
+{
+
+ u32 i;
+ print_debug("dump_mem:");
+ for(i=start;i<end;i++) {
+ if((i & 0xf)==0) {
+ printk_debug("\n%08x:", i);
+ }
+ printk_debug(" %02x", (unsigned char)*((unsigned char *)i));
+ }
+ print_debug("\n");
+ }
+
+extern char *lowmem_backup;
+extern char *lowmem_backup_ptr;
+extern int lowmem_backup_size;
+#include <arch/acpi.h>
+
+
+void acpi_jump_wake(u32 vector)
+{
+ acpi_rsdp_t *rsdp = acpi_get_wakeup_rsdp();
+ u8 *p;
+ u8 tmp;
+// int (*jmp_to)(void) = jump_to_wakeup;
+
+ p = (u8 *) rsdp + 36;
+ printk_debug("The RSDP is at %p spare memory at: %p\n", rsdp, p);
+
+ memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size);
+
+ printk_debug("IN ACPI JUMP WAKE TO %x\n", vector);
+ * ((u32 *) (jump_to_wakeup+1)) = ((vector >> 4) << 16) | (vector & 0xf);
+ printk_debug("%x %x %x %x %x\n", jump_to_wakeup[0], jump_to_wakeup[1], jump_to_wakeup[2], jump_to_wakeup[3],jump_to_wakeup[4]);
+
+ memcpy ((void *) p, real_mode_switch, sizeof (real_mode_switch));
+ memcpy ((void *) p + sizeof (real_mode_switch), jump_to_wakeup, sizeof(jump_to_wakeup));
+
+ /* now setup the trampoline for the realmode jump */
+
+ * ((u32 *) (jump_to_wakeup+1)) = p;
+ printk_debug("%x %x %x %x %x %x %x\n", jump_to_wakeup[0], jump_to_wakeup[1], jump_to_wakeup[2],
+ jump_to_wakeup[3],jump_to_wakeup[4],jump_to_wakeup[5],jump_to_wakeup[6] );
+
+
+ /* Set up the IDT for real mode. */
+
+ asm volatile("lidt %0"::"m" (real_mode_idt));
+
+ /* Set up a GDT from which we can load segment descriptors for real
+ mode. The GDT is not used in real mode; it is just needed here to
+ prepare the descriptors. */
+
+ asm volatile("lgdt %0"::"m" (real_mode_gdt));
+
+ /* Load the data segment registers, and thus the descriptors ready for
+ real mode. The base address of each segment is 0x100, 16 times the
+ selector value being loaded here. This is so that the segment
+ registers don't have to be reloaded after switching to real mode:
+ the values are consistent for real mode operation already. */
+
+ __asm__ __volatile__ ("movl $0x0010,%%eax\n"
+ "\tmovl %%eax,%%ds\n"
+ "\tmovl %%eax,%%es\n"
+ "\tmovl %%eax,%%fs\n"
+ "\tmovl %%eax,%%gs\n"
+ "\tmovl %%eax,%%ss\n"
+ "\tjmp %%ebx\n" : : "b" (jump_to_wakeup) : "eax");
+
+ /* Jump to the 16-bit code that we copied earlier. It disables paging
+ and the cache, switches to real mode, and jumps to the BIOS reset
+ entry point. */
+
+// (*jmp_to)();
+
+// __asm__ __volatile__ ("ljmp $0x0008,%0"
+// :
+// : "i" ((void *) 0x1000));
+}
+
+
/**
* @brief Main function of the DRAM part of coreboot.
*
@@ -47,9 +203,13 @@
* Device Enumeration:
* In the dev_enumerate() phase,
*/
+
+#include <arch/acpi.h>
+
void hardwaremain(int boot_complete)
{
struct lb_memory *lb_mem;
+ void *wake_vec;
post_code(0x80);
@@ -87,8 +247,11 @@
/* Now that we have collected all of our information
* write our configuration tables.
*/
+ wake_vec = acpi_find_wakeup_vector();
+ if (wake_vec)
+ acpi_jump_wake(wake_vec);
+
lb_mem = write_tables();
-
#if CONFIG_ROMFS == 1
# if USE_FALLBACK_IMAGE == 1
void (*pl)(void) = romfs_load_payload(lb_mem, "fallback/payload");
Index: src/northbridge/amd/amdk8/raminit.c
===================================================================
--- src/northbridge/amd/amdk8/raminit.c (revision 4074)
+++ src/northbridge/amd/amdk8/raminit.c (working copy)
@@ -2262,6 +2262,8 @@
#endif
+#include "exit_from_self.c"
+
#define TIMEOUT_LOOPS 300000
#if RAMINIT_SYSINFO == 1
static void sdram_enable(int controllers, const struct mem_controller *ctrl, struct sys_info *sysinfo)
Index: src/northbridge/amd/amdk8/exit_from_self.c
===================================================================
--- src/northbridge/amd/amdk8/exit_from_self.c (revision 0)
+++ src/northbridge/amd/amdk8/exit_from_self.c (revision 0)
@@ -0,0 +1,191 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2009 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 v2 as published by
+ * the Free Software Foundation.
+ *
+ * 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
+ */
+
+void exit_from_self(int controllers, const struct mem_controller *ctrl,
+ struct sys_info *sysinfo)
+{
+ int i;
+ u32 dcl, dch;
+ u32 pcidev;
+ u8 bitmask;
+ u8 is_post_rev_g;
+ u32 cpuid;
+
+ for (i = 0; i < controllers; i++) {
+ if (!sysinfo->ctrl_present[i])
+ continue;
+ /* Skip everything if I don't have any memory on this controller */
+ dch = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_HIGH);
+ if (!(dch & DCH_MemClkFreqVal)) {
+ continue;
+ }
+
+ cpuid = pci_read_config32(ctrl[i].f3, 0xfc);
+ is_post_rev_g = ((cpuid & 0xfff00) > 0x50f00);
+
+ /* ChipKill */
+ dcl = pci_read_config32(ctrl[i].f2, DRAM_CONFIG_LOW);
+ if (dcl & DCL_DimmEccEn) {
+ uint32_t mnc;
+ printk_spew("ECC enabled\n");
+ mnc = pci_read_config32(ctrl[i].f3, MCA_NB_CONFIG);
+ mnc |= MNC_ECC_EN;
+ if (dcl & DCL_Width128) {
+ mnc |= MNC_CHIPKILL_EN;
+ }
+ pci_write_config32(ctrl[i].f3, MCA_NB_CONFIG, mnc);
+ }
+
+ printk_debug("before resume errata #%d\n",
+ (is_post_rev_g) ? 270 : 125);
+ /*
+ 1. Restore memory controller registers as normal.
+ 2. Set the DisAutoRefresh bit (Dev:2x8C[18]). (270 only)
+ 3. Set the EnDramInit bit (Dev:2x7C[31]), clear all other bits in the same register).
+ 4. Wait at least 750 us.
+ 5. Clear the EnDramInit bit.
+ 6. Clear the DisAutoRefresh bit. (270 only)
+ 7. Read the value of Dev:2x80 and write that value back to Dev:2x80.
+ 8. Set the exit from the self refresh bit (Dev:2x90[1]).
+ 9. Clear the exit from self refresh bit immediately.
+ Note: Steps 8 and 9 must be executed in a single 64-byte aligned uninterrupted instruction stream.
+ */
+
+ enable_lapic();
+ init_timer();
+
+ printk_debug("before exit errata - timer enabled\n");
+
+ if (is_post_rev_g) {
+ dcl =
+ pci_read_config32(ctrl[i].f2,
+ DRAM_TIMING_HIGH);
+ dcl |= (1 << 18);
+ pci_write_config32(ctrl[i].f2, DRAM_TIMING_HIGH,
+ dcl);
+ }
+
+ dcl = DI_EnDramInit;
+ pci_write_config32(ctrl[i].f2, DRAM_INIT, dcl);
+
+ udelay(800);
+
+ printk_debug("before exit errata - after mdelay\n");
+
+ dcl = pci_read_config32(ctrl[i].f2, DRAM_INIT);
+ dcl &= ~DI_EnDramInit;
+ pci_write_config32(ctrl[i].f2, DRAM_INIT, dcl);
+
+ if (is_post_rev_g) {
+ dcl =
+ pci_read_config32(ctrl[i].f2,
+ DRAM_TIMING_HIGH);
+ dcl &= ~(1 << 18);
+ pci_write_config32(ctrl[i].f2, DRAM_TIMING_HIGH,
+ dcl);
+ }
+
+ dcl = pci_read_config32(ctrl[i].f2, DRAM_BANK_ADDR_MAP);
+ pci_write_config32(ctrl[i].f2, DRAM_BANK_ADDR_MAP, dcl);
+
+ /* I was unable to do that like: ctrl[i].f2->path.pci.devfn << 8 */
+ pcidev =
+ 0x80000000 | ((((ctrl[i].node_id + 0x18) << 3) | 0x2)
+ << 8) | 0x90;
+ printk_debug("pcidev is %x\n", pcidev);
+ bitmask = 2;
+ __asm__ __volatile__("pushl %0\n\t"
+ "movw $0xcf8, %%dx\n\t"
+ "out %%eax, (%%dx)\n\t"
+ "movw $0xcfc, %%dx\n\t"
+ "inb %%dx, %%al\n\t"
+ "orb %1, %%al\n\t"
+ "not %1\n\t"
+ ".align 64\n\t"
+ "out %%al, (%%dx) \n\t"
+ "andb %1, %%al\n\t"
+ "out %%al, (%%dx)\n\t"
+ "popl %0\n\t"::"a"(pcidev),
+ "q"(bitmask):"edx");
+ }
+
+ printk_debug("after exit errata\n");
+
+
+ for (i = 0; i < controllers; i++) {
+ uint32_t dcm;
+ if (!sysinfo->ctrl_present[i])
+ continue;
+ /* Skip everything if I don't have any memory on this controller */
+ if (sysinfo->meminfo[i].dimm_mask == 0x00)
+ continue;
+
+ printk_debug("Exiting memory from self refresh: ");
+ int loops = 0;
+ do {
+ loops++;
+ if ((loops & 1023) == 0) {
+ printk_debug(".");
+ }
+ dcm =
+ pci_read_config32(ctrl[i].f2, DRAM_CTRL_MISC);
+ } while (((dcm & DCM_MemClrStatus) ==
+ 0) /* || ((dcm & DCM_DramEnabled) == 0) */ );
+
+ if (loops >= TIMEOUT_LOOPS) {
+ printk_debug(" failed\n");
+ continue;
+ }
+
+ printk_debug(" done\n");
+ }
+
+#if HW_MEM_HOLE_SIZEK != 0
+ /* init hw mem hole here */
+ /* DramHoleValid bit only can be set after MemClrStatus is set by Hardware */
+ set_hw_mem_hole(controllers, ctrl);
+#endif
+
+ /* store tom to sysinfo, and it will be used by dqs_timing */
+ {
+ msr_t msr;
+ //[1M, TOM)
+ msr = rdmsr(TOP_MEM);
+ sysinfo->tom_k = ((msr.hi << 24) | (msr.lo >> 8)) >> 2;
+
+ //[4G, TOM2)
+ msr = rdmsr(TOP_MEM2);
+ sysinfo->tom2_k = ((msr.hi << 24) | (msr.lo >> 8)) >> 2;
+ }
+
+ for (i = 0; i < controllers; i++) {
+
+ dqs_restore_MC_NVRAM((ctrl + i)->f2);
+
+ sysinfo->mem_trained[i] = 1; // mem was trained
+
+ if (!sysinfo->ctrl_present[i])
+ continue;
+
+ /* Skip everything if I don't have any memory on this controller */
+ if (sysinfo->meminfo[i].dimm_mask == 0x00)
+ continue;
+
+ }
+}
Index: src/northbridge/amd/amdk8/raminit_f.c
===================================================================
--- src/northbridge/amd/amdk8/raminit_f.c (revision 4074)
+++ src/northbridge/amd/amdk8/raminit_f.c (working copy)
@@ -3008,12 +3008,15 @@
}
#endif
+#include "exit_from_self.c"
static void sdram_enable(int controllers, const struct mem_controller *ctrl,
struct sys_info *sysinfo)
{
int i;
+ int s = acpi_is_wakeup_early();
+
#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
unsigned cpu_f0_f1[8];
/* FIXME: How about 32 node machine later? */
@@ -3059,6 +3062,14 @@
printk_debug("\n");
#endif
+ /* lets override the rest of the routine */
+ if (s) {
+ printk_debug("Wakeup!\n");
+ exit_from_self(controllers, ctrl, sysinfo);
+ printk_debug("Mem running !\n");
+ return;
+ }
+
for (i = 0; i < controllers; i++) {
uint32_t dcl, dch;
if (!sysinfo->ctrl_present[ i ])
@@ -3192,7 +3203,11 @@
#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
dqs_timing(controllers, ctrl, tsc0, sysinfo);
#else
+ dump_pci_device_index_wait(ctrl->f2, 0x98);
+
dqs_timing(controllers, ctrl, sysinfo);
+
+ dump_pci_device_index_wait(ctrl->f2, 0x98);
#endif
#else
@@ -3205,7 +3220,6 @@
/* Skip everything if I don't have any memory on this controller */
if (sysinfo->mem_trained[i]!=0x80)
continue;
-
dqs_timing(i, &ctrl[i], sysinfo, 1);
#if MEM_TRAIN_SEQ == 1
@@ -3225,7 +3239,6 @@
}
-
static void fill_mem_ctrl(int controllers, struct mem_controller *ctrl_a,
const uint16_t *spd_addr)
{
Index: src/northbridge/amd/amdk8/raminit_f_dqs.c
===================================================================
--- src/northbridge/amd/amdk8/raminit_f_dqs.c (revision 4074)
+++ src/northbridge/amd/amdk8/raminit_f_dqs.c (working copy)
@@ -1824,7 +1824,84 @@
#if MEM_TRAIN_SEQ == 0
+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);
+static int save_index_to_pos(unsigned int dev, int size, int index, int nvram_pos) {
+ u32 dword = pci_read_config32_index_wait(dev, 0x98, index);
+
+ return s3_save_nvram_early(dword, size, nvram_pos);
+}
+
+static int load_index_to_pos(unsigned int dev, int size, int index, int nvram_pos) {
+
+ u32 old_dword = pci_read_config32_index_wait(dev, 0x98, index);
+ nvram_pos = s3_load_nvram_early(size, &old_dword, nvram_pos);
+ pci_write_config32_index_wait(dev, 0x98, index, old_dword);
+ return nvram_pos;
+}
+
+static int dqs_load_MC_NVRAM_ch(unsigned int dev, int ch, int pos) {
+ /* 30 bytes per channel */
+ ch *= 0x20;
+ pos = load_index_to_pos(dev, 4, 0x00 + ch, pos);
+ pos = load_index_to_pos(dev, 4, 0x01 + ch, pos);
+ pos = load_index_to_pos(dev, 4, 0x02 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x03 + ch, pos);
+ pos = load_index_to_pos(dev, 4, 0x04 + ch, pos);
+ pos = load_index_to_pos(dev, 4, 0x05 + ch, pos);
+ pos = load_index_to_pos(dev, 4, 0x06 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x07 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x10 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x13 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x16 + ch, pos);
+ pos = load_index_to_pos(dev, 1, 0x19 + ch, pos);
+ return pos;
+}
+
+static int dqs_save_MC_NVRAM_ch(unsigned int dev, int ch, int pos) {
+ /* 30 bytes per channel */
+ ch *= 0x20;
+ pos = save_index_to_pos(dev, 4, 0x00 + ch, pos);
+ pos = save_index_to_pos(dev, 4, 0x01 + ch, pos);
+ pos = save_index_to_pos(dev, 4, 0x02 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x03 + ch, pos);
+ pos = save_index_to_pos(dev, 4, 0x04 + ch, pos);
+ pos = save_index_to_pos(dev, 4, 0x05 + ch, pos);
+ pos = save_index_to_pos(dev, 4, 0x06 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x07 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x10 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x13 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x16 + ch, pos);
+ pos = save_index_to_pos(dev, 1, 0x19 + ch, pos);
+ return pos;
+}
+
+static void dqs_save_MC_NVRAM(unsigned int dev) {
+ int pos = 0;
+ u32 reg;
+ printk_debug("DQS SAVE NVRAM: %x\n", dev);
+ pos = dqs_save_MC_NVRAM_ch(dev, 0, pos);
+ pos = dqs_save_MC_NVRAM_ch(dev, 1, pos);
+ /* save the maxasync lat here */
+ reg = pci_read_config32(dev, DRAM_CONFIG_HIGH);
+ pos = s3_save_nvram_early(reg, 4, pos);
+}
+
+static void dqs_restore_MC_NVRAM(unsigned int dev) {
+ int pos = 0;
+ u32 reg;
+
+ printk_debug("DQS RESTORE FROM NVRAM: %x\n", dev);
+ pos = dqs_load_MC_NVRAM_ch(dev, 0, pos);
+ pos = dqs_load_MC_NVRAM_ch(dev, 1, pos);
+ /* save the maxasync lat here */
+ pos = s3_load_nvram_early(4, ®, pos);
+ reg &= (DCH_MaxAsyncLat_MASK <<DCH_MaxAsyncLat_SHIFT);
+ reg |= pci_read_config32(dev, DRAM_CONFIG_HIGH);
+ pci_write_config32(dev, DRAM_CONFIG_HIGH, reg);
+}
+
#if K8_REV_F_SUPPORT_F0_F1_WORKAROUND == 1
static void dqs_timing(int controllers, const struct mem_controller *ctrl, tsc_t *tsc0, struct sys_info *sysinfo)
#else
@@ -1832,7 +1909,6 @@
#endif
{
int i;
-
tsc_t tsc[5];
//need to enable mtrr, so dqs training could access the test address
@@ -1891,13 +1967,13 @@
if(train_DqsRcvrEn(ctrl+i, 2, sysinfo)) goto out;
printk_debug(" done\r\n");
sysinfo->mem_trained[i]=1;
+ dqs_save_MC_NVRAM((ctrl+i)->f2);
}
out:
tsc[4] = rdtsc();
clear_mtrr_dqs(sysinfo->tom2_k);
-
for(i=0;i<5;i++) {
print_debug_dqs_tsc_x("DQS Training:tsc", i, tsc[i].hi, tsc[i].lo);
}
Index: src/arch/i386/boot/acpi.c
===================================================================
--- src/arch/i386/boot/acpi.c (revision 4074)
+++ src/arch/i386/boot/acpi.c (working copy)
@@ -27,6 +27,9 @@
#include <arch/acpigen.h>
#include <device/pci.h>
+/* this is to be filled by SB code - startup value what was found */
+u8 acpi_slp_type;
+
u8 acpi_checksum(u8 *table, u32 length)
{
u8 ret=0;
@@ -324,11 +327,102 @@
header->checksum = acpi_checksum((void *)hpet, sizeof(acpi_hpet_t));
}
+int acpi_get_sleep_type(void) {
+ return acpi_slp_type;
+}
+
+int acpi_is_wakeup(void) {
+ return (acpi_slp_type == 3);
+}
+
+static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) {
+
+ if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0)
+ return NULL;
+
+ printk_debug("Looking on %p for valid checksum\n", rsdp);
+
+ if (acpi_checksum((void *)rsdp, 20) != 0)
+ return NULL;
+ printk_debug("Checksum 1 passed\n");
+
+ /* no check of extended checksum, used as empty space for our code
+ if ((rsdp->revision > 1) && (acpi_checksum((void *)rsdp,
+ rsdp->length) != 0))
+ return NULL;
+ printk_debug("Checksum 2 passed all OK\n");
+ */
+
+ return rsdp;
+}
+
+static acpi_rsdp_t *rsdp;
+
+void *acpi_get_wakeup_rsdp(void) {
+ return rsdp;
+}
+
+void *acpi_find_wakeup_vector(void)
+{
+ char *p, *end;
+
+ acpi_rsdt_t *rsdt;
+ acpi_facs_t *facs;
+ acpi_fadt_t *fadt;
+ void *wake_vec;
+ int i;
+
+ rsdp = NULL;
+
+ if (!acpi_is_wakeup())
+ return NULL;
+
+ printk_debug("Trying to find the wakeup vector ...\n");
+
+ /* find RSDP */
+ for (p = (char *) 0xe0000; p < (char *) 0xfffff; p+=16) {
+ if ((rsdp = valid_rsdp((acpi_rsdp_t *) p)))
+ break;
+ }
+
+ if (rsdp == NULL)
+ return NULL;
+
+ printk_debug("RSDP found at %p\n", rsdp);
+ rsdt = (acpi_rsdt_t *) rsdp->rsdt_address;
+
+ end = (char *) rsdt + rsdt->header.length;
+ printk_debug("RSDT found at %p ends at %p\n", rsdt, end);
+
+ for (i = 0; ((char *) &rsdt->entry[i]) < end; i++) {
+ fadt = (acpi_fadt_t *) rsdt->entry[i];
+ if (strncmp((char *)fadt, FADT_NAME, sizeof(FADT_NAME) - 1) == 0)
+ break;
+ fadt = NULL;
+ }
+
+ if (fadt == NULL)
+ return NULL;
+
+ printk_debug("FADT found at %p\n", fadt);
+ facs = fadt->firmware_ctrl;
+
+ if (facs == NULL)
+ return NULL;
+
+ printk_debug("FACS found at %p\n", facs);
+ wake_vec = (void *) facs->firmware_waking_vector;
+ printk_debug("OS waking vector is %p\n", wake_vec);
+ return wake_vec;
+}
+
+
void acpi_create_facs(acpi_facs_t *facs)
{
+
memset( (void *)facs,0, sizeof(acpi_facs_t));
- memcpy(facs->signature,"FACS",4);
+ memcpy(facs->signature, FACS_NAME, 4);
facs->length = sizeof(acpi_facs_t);
facs->hardware_signature = 0;
facs->firmware_waking_vector = 0;
@@ -365,9 +459,9 @@
{
memcpy(rsdp->signature, RSDP_SIG, 8);
memcpy(rsdp->oem_id, OEM_ID, 6);
-
rsdp->length = sizeof(acpi_rsdp_t);
rsdp->rsdt_address = (u32)rsdt;
+ rsdp->revision = 2;
rsdp->checksum = acpi_checksum((void *)rsdp, 20);
rsdp->ext_checksum = acpi_checksum((void *)rsdp, sizeof(acpi_rsdp_t));
}
Index: src/arch/i386/include/arch/acpi.h
===================================================================
--- src/arch/i386/include/arch/acpi.h (revision 4074)
+++ src/arch/i386/include/arch/acpi.h (working copy)
@@ -16,6 +16,9 @@
#if HAVE_ACPI_TABLES==1
#include <stdint.h>
+
+/* 0 = S0, 1 = S1 ...*/
+extern u8 acpi_slp_type;
#define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */
#define RSDP_NAME "RSDP"
@@ -27,6 +30,8 @@
#define SRAT_NAME "SRAT"
#define SLIT_NAME "SLIT"
#define SSDT_NAME "SSDT"
+#define FACS_NAME "FACS"
+#define FADT_NAME "FACP"
#define RSDT_TABLE "RSDT "
#define HPET_TABLE "AMD64 "
@@ -50,6 +55,7 @@
u64 xsdt_address; /* physical address of XSDT */
u8 ext_checksum; /* chechsum of whole table */
u8 reserved[3];
+ u8 keyhole[1024]; /* realmode trampoline space */
} __attribute__((packed)) acpi_rsdp_t;
/* Generic Address Container */
@@ -328,6 +334,8 @@
void acpi_write_rsdt(acpi_rsdt_t *rsdt);
void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt);
+void *acpi_find_wakeup_vector(void);
+void *acpi_get_wakeup_rsdp(void);
unsigned long acpi_add_ssdt_pstates(acpi_rsdt_t *rsdt, unsigned long current);
Index: targets/asus/m2v-mx_se/Config.lb
===================================================================
--- targets/asus/m2v-mx_se/Config.lb (revision 4074)
+++ targets/asus/m2v-mx_se/Config.lb (working copy)
@@ -21,7 +21,7 @@
mainboard asus/m2v-mx_se
romimage "normal"
- option ROM_SIZE = 512 * 1024
+ option ROM_SIZE = (512 * 1024) - 39424
option USE_FALLBACK_IMAGE = 0
option ROM_IMAGE_SIZE = 128 * 1024
option COREBOOT_EXTRA_VERSION=".0Normal"
s3_stuff_2.patch.sig
Description: Binary data
-- coreboot mailing list: [email protected] http://www.coreboot.org/mailman/listinfo/coreboot

