From: Jacob Potter Date: Fri, 26 Sep 2008 01:40:03 +0000 (-0400) Subject: Merge branch 'master' of /storage/git/netwatch X-Git-Url: http://git.joshuawise.com/netwatch.git/commitdiff_plain/d88bb1f4479b42f9078674c33e6618c27c2c98ce?hp=0889f342f13f65b875e67f78a27ad078f3f55736 Merge branch 'master' of /storage/git/netwatch --- diff --git a/aseg/counter.c b/aseg/counter.c index 895974d..3c22c05 100644 --- a/aseg/counter.c +++ b/aseg/counter.c @@ -3,9 +3,6 @@ #include #include #include - -char thestr[512]; - #include "vga-overlay.h" unsigned int counter = 0; @@ -13,7 +10,6 @@ unsigned long pcisave; unsigned char vgasave; void pci_dump() { - char s[40]; unsigned long cts; static int curdev = 0; /* 0 if kbd, 1 if mouse */ @@ -39,11 +35,8 @@ void pci_dump() { { unsigned char b; - strcpy(s, "WRITxxxxxxxxxxxxxxxx"); b = *(unsigned char*)0xAFFD0 /* EAX */; - tohex(s+4, cts); - tohex(s+12, b); - dolog(s); + dologf("WRITE: %08x (%02x)", cts, b); outb(cts & 0xFFFF, b); break; } @@ -55,25 +48,34 @@ void pci_dump() { outl(0x840, 0x0100); } +void timer_handler(smi_event_t ev) +{ + static unsigned int ticks = 0; + + smi_disable_event(SMI_EVENT_FAST_TIMER); + smi_enable_event(SMI_EVENT_FAST_TIMER); + + outb(0x80, (ticks++) & 0xFF); + + outlog(); +} + +void kbc_handler(smi_event_t ev) +{ + pci_dump(); +} + void smi_entry(void) { + char statstr[512]; + pcisave = inl(0xCF8); vgasave = inb(0x3D4); counter++; - outb(0x80, (counter & 0xFF)); + sprintf(statstr, "15-412! %08x %08x", smi_status(), counter); + strblit(statstr, 0, 0); - sprintf(thestr, "15-412! %08x %08x", smi_status(), counter); - strblit(thestr, 0, 0); - - if (inl(0x834) & 0x1000) - { - if (inl(0x844) & 0x1000) /* devact_sts */ - { - pci_dump(); - outl(0x844, 0x1000); /* ack it */ - } - } if (inl(0x840) & 0x1000) { pci_dump(); @@ -82,7 +84,6 @@ void smi_entry(void) } smi_poll(); - outlog(); outl(0xCF8, pcisave); outb(0x3D4, vgasave); diff --git a/aseg/firstrun.c b/aseg/firstrun.c index 9589a13..ec09a82 100644 --- a/aseg/firstrun.c +++ b/aseg/firstrun.c @@ -7,6 +7,9 @@ extern int _bss, _bssend; +extern void timer_handler(smi_event_t ev); +extern void kbc_handler(smi_event_t ev); + void __firstrun_start() { unsigned char *bp; smram_state_t smram; @@ -26,8 +29,14 @@ void __firstrun_start() { pci_write16(0, 31, 4, 0xC0, 0); /* Turn on the SMIs we want */ - outb(0x830, inb(0x830) | ICH2_SMI_EN_SWSMI_TMR_EN); - outb(0x848, ICH2_DEVTRAP_EN_KBC_TRP_EN); + smi_disable(); + + smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler); + smi_enable_event(SMI_EVENT_FAST_TIMER); + + smi_register_handler(SMI_EVENT_DEVTRAP_KBC, kbc_handler); + smi_enable_event(SMI_EVENT_DEVTRAP_KBC); + smi_enable(); smram_restore_state(smram); diff --git a/ich2/smi.c b/ich2/smi.c index adba74f..0a0ddf4 100644 --- a/ich2/smi.c +++ b/ich2/smi.c @@ -6,6 +6,8 @@ #include #include +static smi_handler_t _handlers[SMI_EVENT_MAX] = {0}; + static uint16_t _get_PMBASE() { static long pmbase = -1; @@ -64,11 +66,11 @@ void smi_poll() if (sts & ICH2_SMI_STS_SWSMI_TMR_STS) // Ack it, then request another. { + if (_handlers[SMI_EVENT_FAST_TIMER] == SMI_HANDLER_NONE) + output("Unhandled: SWSMI_TMR_STS"); + else if (_handlers[SMI_EVENT_FAST_TIMER] != SMI_HANDLER_IGNORE) + _handlers[SMI_EVENT_FAST_TIMER](SMI_EVENT_FAST_TIMER); outl(_get_PMBASE() + ICH2_PMBASE_SMI_STS, ICH2_SMI_STS_SWSMI_TMR_STS); - outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN, - inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) & ~ICH2_SMI_EN_SWSMI_TMR_EN); - outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN, - inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) | ICH2_SMI_EN_SWSMI_TMR_EN); } if (sts & ICH2_SMI_STS_PM1_STS_REG) @@ -127,6 +129,21 @@ void smi_poll() unsigned short mon_smi = inw(_get_PMBASE() + ICH2_PMBASE_MON_SMI); unsigned long devact_sts = inl(_get_PMBASE() + ICH2_PMBASE_DEVACT_STS); unsigned long devtrap_en = inl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN); + + if (devact_sts & ICH2_DEVACT_STS_KBC_ACT_STS) + { + if (_handlers[SMI_EVENT_DEVTRAP_KBC] == SMI_HANDLER_NONE) + output("Unhandled: DEVACT_KBC_ACT_STS"); + else if (_handlers[SMI_EVENT_DEVTRAP_KBC] != SMI_HANDLER_IGNORE) + _handlers[SMI_EVENT_DEVTRAP_KBC](SMI_EVENT_DEVTRAP_KBC); + outl(_get_PMBASE() + ICH2_PMBASE_DEVACT_STS, ICH2_DEVACT_STS_KBC_ACT_STS); + } + + /* Refresh register cache so that we can print unhandleds as needed. */ + mon_smi = inw(_get_PMBASE() + ICH2_PMBASE_MON_SMI); + devact_sts = inl(_get_PMBASE() + ICH2_PMBASE_DEVACT_STS); + devtrap_en = inl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN); + if (((mon_smi & 0x0F00) >> 8) & ((mon_smi & 0xF000) >> 12)) outputf("Unhandled: MON_SMI (%04x)", mon_smi); if (devact_sts & devtrap_en) @@ -165,3 +182,49 @@ void smi_poll() ICH2_SMI_EN_EOS | ICH2_SMI_EN_GBL_SMI_EN); } + +int smi_register_handler(smi_event_t ev, smi_handler_t hnd) +{ + if (ev >= SMI_EVENT_MAX) + return -1; + _handlers[ev] = hnd; + return 0; +} + +int smi_enable_event(smi_event_t ev) +{ + switch(ev) + { + case SMI_EVENT_FAST_TIMER: + outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN, + inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) | + ICH2_SMI_EN_SWSMI_TMR_EN); + return 0; + case SMI_EVENT_DEVTRAP_KBC: + outl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN, + inl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN) | + ICH2_DEVTRAP_EN_KBC_TRP_EN); + return 0; + default: + return -1; + } +} + +int smi_disable_event(smi_event_t ev) +{ + switch(ev) + { + case SMI_EVENT_FAST_TIMER: + outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN, + inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) & + ~ICH2_SMI_EN_SWSMI_TMR_EN); + return 0; + case SMI_EVENT_DEVTRAP_KBC: + outl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN, + inl(_get_PMBASE() + ICH2_PMBASE_DEVTRAP_EN) & + ~ICH2_DEVTRAP_EN_KBC_TRP_EN); + return 0; + default: + return -1; + } +} diff --git a/include/smi.h b/include/smi.h index c669fc2..e0fd0a0 100644 --- a/include/smi.h +++ b/include/smi.h @@ -7,4 +7,20 @@ extern void smi_enable(); extern void smi_poll(); extern unsigned long smi_status(); /* Architecturally defined; for debugging only. */ +typedef enum { + SMI_EVENT_FAST_TIMER = 0, + SMI_EVENT_DEVTRAP_KBC, + SMI_EVENT_MAX +} smi_event_t; + + +typedef void (*smi_handler_t)(smi_event_t); + +#define SMI_HANDLER_NONE ((smi_handler_t)0) +#define SMI_HANDLER_IGNORE ((smi_handler_t)-1) + +extern int smi_register_handler(smi_event_t ev, smi_handler_t hnd); +extern int smi_enable_event(smi_event_t ev); +extern int smi_disable_event(smi_event_t ev); + #endif