+
+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;
+ case SMI_EVENT_GBL_RLS:
+ outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN,
+ inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) |
+ ICH2_SMI_EN_BIOS_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;
+ case SMI_EVENT_GBL_RLS:
+ outl(_get_PMBASE() + ICH2_PMBASE_SMI_EN,
+ inl(_get_PMBASE() + ICH2_PMBASE_SMI_EN) &
+ ~ICH2_SMI_EN_BIOS_EN);
+ return 0;
+ default:
+ return -1;
+ }
+}