From 07d1dd26f38ed450a9333741337e8091b37b4fc2 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Thu, 25 Sep 2008 20:56:44 -0400 Subject: [PATCH] Initial smi_event infrastructure --- aseg/counter.c | 15 ++++++++++++--- aseg/firstrun.c | 6 +++++- ich2/smi.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- include/smi.h | 15 +++++++++++++++ 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/aseg/counter.c b/aseg/counter.c index 1138e53..85b73eb 100644 --- a/aseg/counter.c +++ b/aseg/counter.c @@ -48,6 +48,18 @@ 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 smi_entry(void) { char statstr[512]; @@ -56,8 +68,6 @@ void smi_entry(void) vgasave = inb(0x3D4); counter++; - outb(0x80, (counter & 0xFF)); - sprintf(statstr, "15-412! %08x %08x", smi_status(), counter); strblit(statstr, 0, 0); @@ -77,7 +87,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..323f1ab 100644 --- a/aseg/firstrun.c +++ b/aseg/firstrun.c @@ -7,6 +7,8 @@ extern int _bss, _bssend; +extern void timer_handler(smi_event_t ev); + void __firstrun_start() { unsigned char *bp; smram_state_t smram; @@ -26,7 +28,9 @@ 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); + smi_disable(); + smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler); + smi_enable_event(SMI_EVENT_FAST_TIMER); outb(0x848, ICH2_DEVTRAP_EN_KBC_TRP_EN); smi_enable(); diff --git a/ich2/smi.c b/ich2/smi.c index adba74f..d255615 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) @@ -165,3 +167,39 @@ 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; + 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; + default: + return -1; + } +} diff --git a/include/smi.h b/include/smi.h index c669fc2..670dc63 100644 --- a/include/smi.h +++ b/include/smi.h @@ -7,4 +7,19 @@ 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_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 -- 2.43.0