See patch. This works nicely on two i945 machines I have here (unfortunately not the Kontron 986lcd-m due to some other reason) Probably needs some fixing for the AMD board that Rudolf got running with Resume. Rudolf, can you jump in, I don't have that hardware..
Stefan
* Simplify acpi_add_table * fix some comments * Simplify ACPI wakeup code and make it work without a memory hole * Add resume entries to global GDT so we don't need our own for resume. * add ECDT description to acpi.h for anyone who might need it ;-) * remove rather stupid math to get the right number of MAX_ACPI_TABLES and just define a reasonable maximum for now.
Signed-off-by: Stefan Reinauer stepan@coresystems.de
Index: src/arch/i386/boot/acpi.c =================================================================== --- src/arch/i386/boot/acpi.c (revision 4861) +++ src/arch/i386/boot/acpi.c (working copy) @@ -18,7 +18,8 @@ * write_acpi_tables() * acpi_dump_apics() * - * See AMD Solo, Island Aruma or Via Epia-M port for more details. + * See Kontron 986LCD-M port for a good example of an ACPI implementation + * in coreboot. */
#include <console/console.h> @@ -26,6 +27,7 @@ #include <arch/acpi.h> #include <arch/acpigen.h> #include <device/pci.h> +#include <cbmem.h>
u8 acpi_checksum(u8 *table, u32 length) { @@ -37,54 +39,67 @@ return -ret; }
-/* - * add an acpi table to rsdt structure, and recalculate checksum +/** + * Add an ACPI table to the RSDT (and XSDT) structure, recalculate length and checksum */
void acpi_add_table(acpi_rsdp_t *rsdp, void *table) { - int i; + int i, entries_num; acpi_rsdt_t *rsdt; acpi_xsdt_t *xsdt = NULL;
+ /* The RSDT is mandatory ... */ rsdt = (acpi_rsdt_t *)rsdp->rsdt_address; + + /* ... while the XSDT is not */ if (rsdp->xsdt_address) { xsdt = (acpi_xsdt_t *)((u32)rsdp->xsdt_address); } - int entries_num = ARRAY_SIZE(rsdt->entry); + /* This should always be MAX_ACPI_TABLES */ + entries_num = ARRAY_SIZE(rsdt->entry); - for (i=0; i<entries_num; i++) { - if(rsdt->entry[i]==0) { - rsdt->entry[i]=(u32)table; - /* fix length to stop kernel whining about invalid entries */ - rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1)); - /* fix checksum */ - /* hope this won't get optimized away */ - rsdt->header.checksum=0; - rsdt->header.checksum=acpi_checksum((u8 *)rsdt, - rsdt->header.length); + for (i = 0; i < entries_num; i++) { + if(rsdt->entry[i] == 0) + break; + }
- /* And now the same thing for the XSDT. We use the same - * index as we want the XSDT and RSDT to always be in - * sync in coreboot. - */ - if (xsdt) { - xsdt->entry[i]=(u64)(u32)table; - xsdt->header.length = sizeof(acpi_header_t) + - (sizeof(u64) * (i+1)); - xsdt->header.checksum=0; - xsdt->header.checksum=acpi_checksum((u8 *)xsdt, - xsdt->header.length); - } - - printk_debug("ACPI: added table %d/%d Length now %d\n", - i+1, entries_num, rsdt->header.length); - return; - } + if (i >= entries_num) { + printk_err("ACPI: Error: Could not add ACPI table, too many tables.\n"); + return; }
- printk_err("ACPI: Error: Could not add ACPI table, too many tables.\n"); + /* Add table to the RSDT */ + rsdt->entry[i] = (u32)table; + + /* Fix RSDT length or the kernel will assume invalid entries */ + rsdt->header.length = sizeof(acpi_header_t) + (sizeof(u32) * (i+1)); + + /* Re-calculate checksum */ + rsdt->header.checksum = 0; /* Hope this won't get optimized away */ + rsdt->header.checksum = acpi_checksum((u8 *)rsdt, + rsdt->header.length); + + /* And now the same thing for the XSDT. We use the same index as for + * now we want the XSDT and RSDT to always be in sync in coreboot. + */ + if (xsdt) { + /* Add table to the XSDT */ + xsdt->entry[i]=(u64)(u32)table; + + /* Fix XSDT length */ + xsdt->header.length = sizeof(acpi_header_t) + + (sizeof(u64) * (i+1)); + + /* Re-calculate checksum */ + xsdt->header.checksum=0; + xsdt->header.checksum=acpi_checksum((u8 *)xsdt, + xsdt->header.length); + } + + printk_debug("ACPI: added table %d/%d Length now %d\n", + i+1, entries_num, rsdt->header.length); }
int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u32 base, u16 seg_nr, u8 start, u8 end) @@ -222,7 +237,8 @@ }
/* this can be overriden by platform ACPI setup code, - if it calls acpi_create_ssdt_generator */ + * if it calls acpi_create_ssdt_generator + */ unsigned long __attribute__((weak)) acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id) { return current; @@ -559,10 +575,29 @@ extern char *lowmem_backup_ptr; extern int lowmem_backup_size;
+#define WAKEUP_BASE 0x600 + +void (*acpi_do_wakeup)(u32 vector, u32 backup_source, u32 backup_target, u32 + backup_size) __attribute__((regparm(0))) = (void *)WAKEUP_BASE; + +extern unsigned char __wakeup, __wakeup_size; + void acpi_jump_to_wakeup(void *vector) { + u32 acpi_backup_memory = (u32) cbmem_find(CBMEM_ID_RESUME); + + if (!acpi_backup_memory) { + printk(BIOS_WARNING, "ACPI: Backup memory missing. No S3 Resume.\n"); + return; + } + + // FIXME this should go into the ACPI backup memory, too. No pork saussages. /* just restore the SMP trampoline and continue with wakeup on assembly level */ memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size); - acpi_jmp_to_realm_wakeup((u32) vector); + + /* copy wakeup trampoline in place */ + memcpy(WAKEUP_BASE, &__wakeup, &__wakeup_size); + + acpi_do_wakeup((u32)vector, acpi_backup_memory, CONFIG_RAMBASE, HIGH_MEMORY_SAVE); } #endif Index: src/arch/i386/boot/wakeup.S =================================================================== --- src/arch/i386/boot/wakeup.S (revision 4861) +++ src/arch/i386/boot/wakeup.S (working copy) @@ -2,10 +2,11 @@ * This file is part of the coreboot project. * * Copyright (C) 2009 Rudolf Marek r.marek@assembler.cz + * Copyright (C) 2009 coresystems GmbH * * 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. + * 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 @@ -16,76 +17,89 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - .text + +#define WAKEUP_BASE 0x600 +#define RELOCATED(x) (x - __wakeup + WAKEUP_BASE) + +/* CR0 bits */ +#define PE (1 << 0) + .code32 - .globl acpi_jmp_to_realm_wakeup - /* This function does the PM -> RM switch, but - it can run >1MB even in real mode */ - -acpi_jmp_to_realm_wakeup: - mov 0x4(%esp), %eax + .globl __wakeup +__wakeup: + /* First prepare the jmp to the resume vector */ + mov 0x4(%esp), %eax /* vector */ /* last 4 bits of linear addr are taken as offset */ andw $0x0f, %ax - movw %ax, (jmp_off) + movw %ax, (__wakeup_offset) mov 0x4(%esp), %eax /* the rest is taken as segment */ shr $4, %eax - movw %ax, (jmp_seg) - lgdt gdtaddr_wakeup - movl $0x008,%eax - mov %eax,%ds - movl %eax,%es - movl %eax,%ss - movl %eax,%fs - movl %eax,%gs - ljmp $0x0010,$reload_cs - .code16gcc -reload_cs: - /* switch off PE */ + movw %ax, (__wakeup_segment) + + /* Then overwrite coreboot with our backed up memory */ + movl 8(%esp), %esi + movl 12(%esp), %edi + movl 16(%esp), %ecx + shrl $4, %ecx +1: + movl 0(%esi),%eax + movl 4(%esi),%edx + movl 8(%esi),%ebx + movl 12(%esi),%ebp + addl $16,%esi + subl $1,%ecx + movl %eax,0(%edi) + movl %edx,4(%edi) + movl %ebx,8(%edi) + movl %ebp,12(%edi) + leal 16(%edi),%edi + jne 1b + + /* Activate the right segment descriptor real mode. */ + ljmp $0x28, $RELOCATED(1f) +1: +.code16 + /* 16 bit code from here on... */ + + /* Load the segment registers w/ properly configured + * segment descriptors. They will retain these + * configurations (limits, writability, etc.) once + * protected mode is turned off. + */ + mov $0x30, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + + /* Turn off protection */ movl %cr0, %eax - andb $0xfe,%al + andl $~PE, %eax movl %eax, %cr0 - ljmpl $0x0, $cpu_flushed -cpu_flushed: + + /* Now really going into real mode */ + ljmp $0, $RELOCATED(1f) +1: movw $0x0, %ax movw %ax, %ds movw %ax, %es movw %ax, %ss movw %ax, %fs movw %ax, %gs - /* far jump to OS waking vector. The linear addr is changed to SEG and OFFSET - check ACPI specs or above code for details */ + + /* This is a FAR JMP to the OS waking vector. The C code changed + * the address to be correct. + */ .byte 0xea -jmp_off: - .word 0 -jmp_seg: - .word 0
-.code32 -gdt_wakeup_limit = gdt_wakeup_end - gdt_wakeup - 1 /* compute the table limit */ - gdtaddr_wakeup: - .word gdt_wakeup_limit /* the table limit */ - .long gdt_wakeup /* we know the offset */ +__wakeup_offset = RELOCATED(.) + .word 0x0000
- .data +__wakeup_segment = RELOCATED(.) + .word 0x0000
- /* This is the gdt for GCC part of coreboot. - * It is different from the gdt in ROMCC/ASM part of coreboot - * which is defined in entry32.inc */ -gdt_wakeup: - /* selgdt 0, unused */ - .word 0x0000, 0x0000 /* dummy */ - .byte 0x00, 0x00, 0x00, 0x00 + .globl __wakeup_size +__wakeup_size = ( . - __wakeup)
- /* selgdt 8, flat data segment 16bit */ - .word 0x0000, 0x0000 /* dummy */ - .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ - - /* selgdt 0x10, flat code segment 16bit */ - .word 0xffff, 0x0000 - .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ - -gdt_wakeup_end: - - .previous -.code32 Index: src/arch/i386/include/arch/acpi.h =================================================================== --- src/arch/i386/include/arch/acpi.h (revision 4861) +++ src/arch/i386/include/arch/acpi.h (working copy) @@ -1,16 +1,27 @@ /* * coreboot ACPI Support - headers and defines. - * + * * written by Stefan Reinauer stepan@coresystems.de * Copyright (C) 2004 SUSE LINUX AG + * Copyright (C) 2004 Nick Barker * Copyright (C) 2008-2009 coresystems GmbH * - * The ACPI table structs are based on the Linux kernel sources. - * ACPI FADT & FACS added by Nick Barker nick.barker9@btinternet.com - * those parts (C) 2004 Nick Barker + * 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 */
- #ifndef __ASM_ACPI_H #define __ASM_ACPI_H
@@ -48,6 +59,12 @@ u32 addrh; } __attribute__ ((packed)) acpi_addr_t;
+#define ACPI_ADDRESS_SPACE_MEMORY 0 +#define ACPI_ADDRESS_SPACE_IO 1 +#define ACPI_ADDRESS_SPACE_PCI 2 +#define ACPI_ADDRESS_SPACE_FIXED 0x7f + + /* Generic ACPI Header, provided by (almost) all tables */
typedef struct acpi_table_header /* ACPI common table header */ @@ -63,13 +80,9 @@ u32 asl_compiler_revision; /* ASL compiler revision number */ } __attribute__ ((packed)) acpi_header_t;
-/* FIXME: This is very fragile: - * MCONFIG, HPET, FADT, SRAT, SLIT, MADT(APIC), SSDT, SSDTX, and SSDT for CPU - * pstate - */ +/* A maximum number of 32 ACPI tables ought to be enough for now */ +#define MAX_ACPI_TABLES 32
-#define MAX_ACPI_TABLES (7 + CONFIG_ACPI_SSDTX_NUM + CONFIG_MAX_CPUS) - /* RSDT */ typedef struct acpi_rsdt { struct acpi_table_header header; @@ -330,6 +343,16 @@ // #define ACPI_FACS_S4BIOS_F (1 << 0)
+typedef struct acpi_ecdt { + struct acpi_table_header header; + struct acpi_gen_regaddr ec_control; + struct acpi_gen_regaddr ec_data; + u32 uid; + u8 gpe_bit; + u8 ec_id[]; +} __attribute__ ((packed)) acpi_ecdt_t; + + /* These are implemented by the target port */ unsigned long write_acpi_tables(unsigned long addr); unsigned long acpi_fill_madt(unsigned long current); @@ -382,7 +405,7 @@ void suspend_resume(void); void *acpi_find_wakeup_vector(void); void *acpi_get_wakeup_rsdp(void); -void acpi_jmp_to_realm_wakeup(u32 linear_addr); +void acpi_jmp_to_realm_wakeup(u32 linear_addr) __attribute__((regparm(0))); void acpi_jump_to_wakeup(void *wakeup_addr);
int acpi_get_sleep_type(void); Index: src/arch/i386/lib/c_start.S =================================================================== --- src/arch/i386/lib/c_start.S (revision 4861) +++ src/arch/i386/lib/c_start.S (working copy) @@ -253,7 +253,16 @@
/* This is the gdt for GCC part of coreboot. * It is different from the gdt in ROMCC/ASM part of coreboot - * which is defined in entry32.inc */ /* BUT WHY?? */ + * which is defined in entry32.inc + * + * When the machine is initially started, we use a very simple + * gdt from rom (that in entry32.inc) which only contains those + * entries we need for protected mode. + * + * When we're executing code from RAM, we want to do more complex + * stuff, like initializing PCI option roms in real mode, or doing + * a resume from a suspend to ram. + */ gdt: /* selgdt 0, unused */ .word 0x0000, 0x0000 /* dummy */ @@ -275,6 +284,8 @@ .word 0x0000, 0x0000 /* dummy */ .byte 0x00, 0x00, 0x00, 0x00
+ /* The next two entries are used for executing VGA option ROMs */ + /* selgdt 0x28 16-bit 64k code at 0x00000000 */ .word 0xffff, 0x0000 .byte 0, 0x9a, 0, 0 @@ -282,6 +293,16 @@ /* selgdt 0x30 16-bit 64k data at 0x00000000 */ .word 0xffff, 0x0000 .byte 0, 0x92, 0, 0 + + /* The next two entries are used for ACPI S3 RESUME */ + + /* selgdt 0x38, flat data segment 16bit */ + .word 0x0000, 0x0000 /* dummy */ + .byte 0x00, 0x93, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ + + /* selgdt 0x40, flat code segment 16bit */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0x8f, 0x00 /* G=1 and 0x0f, So we get 4Gbytes for limit */ gdt_end:
idtarg:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi,
I have some questions:
1) is 0x600 as base for lowmem trampoline safe? it always makes me wonder, this was the reason why I did the realmode code which runs above 1MB ;) Maybe we can have that too and only copy the trampoline to the highmem save area and execute it there. This would mean all memory bellow 1MB is untouched.
2)
You seem to follow different way how to detect S3.
I had in the code for all boards (like memory controller init)
ifdef ACPI_IS_WAKEUP_EARLY <------>int suspend = acpi_is_wakeup_early(); #else <------>int suspend = 0; #endif
And for per chipset CAR code I defined a function which is doing it:
define ACPI_IS_WAKEUP_EARLY 1
int acpi_is_wakeup_early(void) { device_t dev; u16 tmp; print_debug("IN TEST WAKEUP\n"); ...
And for the normal ram stage there is:
/* this is to be filled by SB code - startup value what was found */
u8 acpi_slp_type = 0;
int acpi_is_wakeup(void) { <------>return (acpi_slp_type == 3); }
Which is backup what was the sleep type. I think this is how you deal with that using the scratchpads.
3) I think your SMM code corrupts lowmem, or I have not seen any backup of that mem? Maybe I'm wrong?
4) Changes to the stack
I think you changed the stack to some other place, not sure how to change that for K8 CAR? Also there is an remaining issue if CAR gets flushed to memory or not. I think Carl-Daniel had some patch for this.
5) Don't understand much the cbmem_reinit((u64)high_ram_base)) in CAR code, you seem to take the TOM from PCI reg but this gets more complicated for UMA, I dont know how to do that for K8. Partially because the high_ram_base gets dynamically lowered in K8M890 resource code :/ In other words there is no easy way for me to find it in memory. Except some hacks like make the cbmem look like some proprietary ACPI table and walk acpi tables as for we do for resume but in car stage just to find out where the tables are...
I think only issue #5 is a real problem.
Rudolf
Rudolf Marek wrote:
Hi,
I have some questions:
- is 0x600 as base for lowmem trampoline safe? it always makes me
wonder, this was the reason why I did the realmode code which runs above 1MB ;) Maybe we can have that too and only copy the trampoline to the highmem save area and execute it there. This would mean all memory bellow 1MB is untouched.
It should be safe. The lower 4kb are supposed to be untouched by the OS, according to some information I found, including an old mail of yours on S3 Resume.
You seem to follow different way how to detect S3.
Not sure I can follow. I didn't change that part of your code
I had in the code for all boards (like memory controller init)
ifdef ACPI_IS_WAKEUP_EARLY <------>int suspend = acpi_is_wakeup_early(); #else <------>int suspend = 0; #endif
And for per chipset CAR code I defined a function which is doing it:
define ACPI_IS_WAKEUP_EARLY 1
int acpi_is_wakeup_early(void) { device_t dev; u16 tmp; print_debug("IN TEST WAKEUP\n"); ...
Since I only use the value in auto.c I did not put this into a one line function called externally. If that is what you suggest, we can easily do that, though.
And for the normal ram stage there is:
/* this is to be filled by SB code - startup value what was found */
u8 acpi_slp_type = 0;
int acpi_is_wakeup(void) { <------>return (acpi_slp_type == 3); }
Which is backup what was the sleep type. I think this is how you deal with that using the scratchpads.
Yes, I am using your mechanism here. But since it's not safe to leave the value in PM1_CNT (at least on i945), I had to move it somewhere else. SKPAD seemed like a good place to get it over to stage 2.
- I think your SMM code corrupts lowmem, or I have not seen any
backup of that mem? Maybe I'm wrong?
No, that is true... 0x38000 + size of SMM relocator is wiped out.
- Changes to the stack
I think you changed the stack to some other place, not sure how to change that for K8 CAR? Also there is an remaining issue if CAR gets flushed to memory or not. I think Carl-Daniel had some patch for this.
On i945 the cache as ram area is not backed by RAM, so the copy trickery from K8 does not work here.
Stack setup is more than fishy on most platforms, but that's pretty unrelated to my ACPI resume patch.
What patch are you referring to?
- Don't understand much the cbmem_reinit((u64)high_ram_base)) in CAR
code, you seem to take the TOM from PCI reg but this gets more complicated for UMA, I dont know how to do that for K8. Partially because the high_ram_base gets dynamically lowered in K8M890 resource code :/ In other words there is no easy way for me to find it in memory.
Very ugly. Maybe we can fix the K8M890 resource code? What factors influence the high_ram_base on that chipset? How early can we determine them?
Except some hacks like make the cbmem look like some proprietary ACPI table and walk acpi tables as for we do for resume but in car stage just to find out where the tables are...
Speaking of hacks, we could remember the CBMEM base address in the low 4KB so we can find them again...
Stefan
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi Stefan,
- is 0x600 as base for lowmem trampoline safe? it always makes me
wonder, this was the reason why I did the realmode code which runs above 1MB ;) Maybe we can have that too and only copy the trampoline to the highmem save area and execute it there. This would mean all memory bellow 1MB is untouched.
It should be safe. The lower 4kb are supposed to be untouched by the OS, according to some information I found, including an old mail of yours on S3 Resume.
Aha, I think we could rework this and have the trampoline in CBMEM, because the trick to run realmode code over 1MB would work too.
Since I only use the value in auto.c I did not put this into a one line function called externally. If that is what you suggest, we can easily do that, though.
Yes this is just for code to look same...
- I think your SMM code corrupts lowmem, or I have not seen any
backup of that mem? Maybe I'm wrong?
No, that is true... 0x38000 + size of SMM relocator is wiped out.
OK ;)
- Changes to the stack
What patch are you referring to?
Well I think the previous one for CBMEM if I recall correctly or the ICH7 updates stuff.
- Don't understand much the cbmem_reinit((u64)high_ram_base)) in CAR
Very ugly. Maybe we can fix the K8M890 resource code? What factors influence the high_ram_base on that chipset? How early can we determine them?
Yes I tried to fixed it with separate patch.
Except some hacks like make the cbmem look like some proprietary ACPI table and walk acpi tables as for we do for resume but in car stage just to find out where the tables are...
Speaking of hacks, we could remember the CBMEM base address in the low 4KB so we can find them again...
Yes I tried that I used 0:4F0 for the PRT which is some 'user data area'. I'm having trouble with CBMEM refusing me to create the ACPI RESUME table. However the bits I have rewritten to use the 0:4F0 trampoline are OK.
Rudolf
Rudolf Marek wrote:
Yes I tried that I used 0:4F0 for the PRT which is some 'user data area'. I'm having trouble with CBMEM refusing me to create the ACPI RESUME table. However the bits I have rewritten to use the 0:4F0 trampoline are OK.
The high tables area needs to grow from 64KB to 1MB in order for the ACPI RESUME table to fit...
Stefan
Stefan Reinauer wrote:
See patch. This works nicely on two i945 machines I have here (unfortunately not the Kontron 986lcd-m due to some other reason) Probably needs some fixing for the AMD board that Rudolf got running with Resume. Rudolf, can you jump in, I don't have that hardware..
Stefan
- Simplify acpi_add_table
- fix some comments
- Simplify ACPI wakeup code and make it work without a memory hole
- Add resume entries to global GDT so we don't need our own for resume.
- add ECDT description to acpi.h for anyone who might need it ;-)
- remove rather stupid math to get the right number of MAX_ACPI_TABLES and just define a reasonable maximum for now.
Signed-off-by: Stefan Reinauer stepan@coresystems.de
ping?
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi
Sorry I tried to get it working on K8 but got distracted by the network support for SerialICE and network console for coreboot ;)
I think I can Acked-by: Rudolf Marek r.marek@assembler.cz Although I would prefer to have the wakeup trampoline located in the cbmem area. The trick to run in real mode higher than 1MB would work too and make things safer.
Rudolf
On Wed, 04 Nov 2009 23:04:14 +0100, Rudolf Marek r.marek@assembler.cz wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi
Sorry I tried to get it working on K8 but got distracted by the network support for SerialICE and network console for coreboot ;)
Sorry to get off subject, but what is this all about, do tell :-)
Rudolf Marek wrote:
Hi
Sorry I tried to get it working on K8 but got distracted by the network support for SerialICE and network console for coreboot ;)
How's that going?
I think I can Acked-by: Rudolf Marek r.marek@assembler.cz
Thanks, r4932
Although I would prefer to have the wakeup trampoline located in the cbmem area. The trick to run in real mode higher than 1MB would work too and make things safer.
Ok, I'll put that on my stack... If you can come up with a solution quicker, please do..
Stefan