From: Joshua Wise Date: Thu, 25 Sep 2008 22:12:28 +0000 (-0400) Subject: Put BSS clearing in firstrun X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/f2b87dd63dc50a707ac102db7afb849b1f4f8db0?ds=sidebyside;hp=efea5b4edd5cc94b4ed0917ebca0efb6bb6a2f82 Put BSS clearing in firstrun --- diff --git a/aseg/aseg.asm b/aseg/aseg.asm index a6f71c2..7380dc0 100644 --- a/aseg/aseg.asm +++ b/aseg/aseg.asm @@ -22,18 +22,8 @@ continue: mov gs, ax mov ss, ax mov esp, [dataptr] ; Load stack pointer. - - mov al, [needclear] ; Has the aseg been run before? - cmp al, 0 ; If so, - jz noclear ; don't clear BSS. - mov al, 0 ; Otherwise, clear BSS. - mov edi, [dataptr+4] - mov ecx, [dataptr+8] - rep stosb - mov [needclear], al -noclear: - mov eax, [dataptr+12] ; Load target jump address + mov eax, [dataptr+4] ; Load target jump address call eax ; then jump into C. rsm ; and leave SMM @@ -48,12 +38,7 @@ gdt: db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x93, 0xCF, 0x00 ; data segment db 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x9B, 0xCF, 0x00 ; code segment -needclear: - db 0x01 - dataptr: ; 4 bytes of stack top - ; 4 bytes of BSS start - ; 4 bytes of BSS length ; 4 bytes of C entry point ; These show up diff --git a/aseg/aseg.lds b/aseg/aseg.lds index e969a54..83afbae 100644 --- a/aseg/aseg.lds +++ b/aseg/aseg.lds @@ -7,8 +7,6 @@ SECTIONS _start = .; aseg.o LONG(_stacktop); - LONG(_bss); - LONG(_bssend - _bss); LONG(smi_entry); *(.text); *(.data); diff --git a/aseg/firstrun.c b/aseg/firstrun.c index c6eab7b..9589a13 100644 --- a/aseg/firstrun.c +++ b/aseg/firstrun.c @@ -3,8 +3,20 @@ #include #include #include "vga-overlay.h" +#include + +extern int _bss, _bssend; void __firstrun_start() { + unsigned char *bp; + smram_state_t smram; + + smram = smram_save_state(); + smram_tseg_set_state(SMRAM_TSEG_OPEN); + + for (bp = (void *)&_bss; (void *)bp < (void *)&_bssend; bp++) + *bp = 0; + dologf("NetWatch running"); /* Try really hard to shut up USB_LEGKEY. */ @@ -17,5 +29,7 @@ void __firstrun_start() { outb(0x830, inb(0x830) | ICH2_SMI_EN_SWSMI_TMR_EN); outb(0x848, ICH2_DEVTRAP_EN_KBC_TRP_EN); smi_enable(); + + smram_restore_state(smram); } diff --git a/grubload/multiboot_c.c b/grubload/multiboot_c.c index 04f9b2f..17c1542 100644 --- a/grubload/multiboot_c.c +++ b/grubload/multiboot_c.c @@ -50,10 +50,10 @@ void c_start(unsigned int magic, struct mb_info *mbinfo) if (mbinfo->mod_cnt != 1) panic("Expected exactly one module; cannot continue."); - + outputf("Current SMRAMC state is: %02x", pci_read8(0, 0, 0, 0x70)); outputf("Current USB state is: %04x %04x", pci_read16(0, 31, 2, 0xC0), pci_read16(0, 31, 4, 0xC0)); outputf("Current SMI state is: %08x", inl(0x830)); - outputf("Current SMRAMC state is: %02x", pci_read8(0, 0, 0, 0x70)); + smi_disable(); @@ -80,6 +80,8 @@ void c_start(unsigned int magic, struct mb_info *mbinfo) info->firstrun(); smram_restore_state(old_smramc); + + outputf("New SMRAMC state is: %02x", pci_read8(0, 0, 0, 0x70)); puts("Waiting for a bit before returning to real mode..."); for (i=0; i<0x500000; i++) diff --git a/grubload/output.c b/grubload/output.c index 6a6ffab..6abc72a 100644 --- a/grubload/output.c +++ b/grubload/output.c @@ -8,7 +8,7 @@ static void safeputs(const char *s) { - unsigned long old = smram_save_state(); + smram_state_t old = smram_save_state(); smram_aseg_set_state(SMRAM_ASEG_SMMONLY); puts(s); smram_restore_state(old); diff --git a/ich2/smram-ich2.c b/ich2/smram-ich2.c index d274c85..edf8ad5 100644 --- a/ich2/smram-ich2.c +++ b/ich2/smram-ich2.c @@ -127,3 +127,25 @@ int smram_aseg_set_state (int open) { return 0; } + +int smram_tseg_set_state (int open) { + unsigned char smramc; + + if (smram_locked()) + return -1; + + smramc = pci_read8(0, 0, 0, SMRAMC); + + switch (open) + { + case SMRAM_TSEG_OPEN: + smramc = (smramc & 0x8F) | 0x00; + break; + default: + return -1; + } + + pci_write8(0, 0, 0, SMRAMC, smramc); + + return 0; +} diff --git a/include/smram.h b/include/smram.h index 6c4ac69..5509d09 100644 --- a/include/smram.h +++ b/include/smram.h @@ -6,11 +6,14 @@ extern int smram_locked(); extern smram_state_t smram_save_state(); extern void smram_restore_state(smram_state_t state); -extern int smram_aseg_set_state (int open); +extern int smram_aseg_set_state(int open); +extern int smram_tseg_set_state(int open); #define SMRAM_ASEG_CLOSED 0 /* SMRAM is not readable. */ #define SMRAM_ASEG_OPEN 1 /* SMRAM is readable by everybody. */ #define SMRAM_ASEG_SMMCODE 2 /* SMRAM is readable as SMM code only. */ #define SMRAM_ASEG_SMMONLY 3 /* SMRAM is readable as SMM code and data only. */ +#define SMRAM_TSEG_OPEN 0 + #endif