]> Joshua Wise's Git repositories - netwatch.git/blobdiff - netwatch/smi.c
Add TSC checks to measure how much time we spend in SMM.
[netwatch.git] / netwatch / smi.c
index d519341a9370446fdbe8e1e65e56419271f4abb4..3172cfd29d112a7b9e398d34704e8edd14c3414e 100644 (file)
@@ -1,3 +1,13 @@
+/* smi.c
+ * First-run SMI C entry point
+ * NetWatch system management mode administration console
+ *
+ * Copyright (c) 2008 Jacob Potter and Joshua Wise.  All rights reserved.
+ * This program is free software; you can redistribute and/or modify it under
+ * the terms found in the file LICENSE in the root of this source tree.
+ *
+ */
+
 #include <io.h>
 #include <smram.h>
 #include <video_defines.h>
@@ -15,26 +25,56 @@ unsigned int counter = 0;
 unsigned long pcisave = 0;
 unsigned char vgasave = 0;
 
+unsigned long lastentry = 0;
+unsigned long lastlength = 0;
+
+unsigned long rdtsc()
+{
+       unsigned long tsc;
+       asm volatile ("mov %%cr4, %%eax;"
+            "and $~2, %%eax;"
+            "mov %%eax, %%cr4;"
+            "rdtsc" : "=a"(tsc) : : "edx");
+       return tsc;
+}
+
 void smi_entry(void)
 {
        char statstr[512];
+       unsigned long entrytime;
 
        /* Reenable caching on SMRAM. */
        WRMSR(0x202, (RDMSR(0x202) & ~(0xFFULL)) | 0x06ULL);
 
+       entrytime = rdtsc();
+
        pcisave = inl(0xCF8);
        vgasave = inb(0x3D4);
        pci_unbother_all();
        
        serial_init();
-       
+
        if (fb)
                fb->getvmode(fb->priv);
 
        counter++;
        if (!fb || fb->curmode.text)
        {
-               sprintf(statstr, "NetWatch! %08x %08x", smi_status(), counter);
+               int totcyc, pct;
+               
+               if (entrytime < lastentry)
+                       totcyc = entrytime + (0xFFFFFFFFUL - lastentry) + 1;
+               else
+                       totcyc = entrytime - lastentry;
+               if (totcyc == 0)
+                       totcyc = 1;     /* argh */
+               totcyc /= 1000;
+               if (totcyc == 0)
+                       totcyc = 1;
+               
+               pct = lastlength / totcyc;
+               
+               sprintf(statstr, "NetWatch! %08x %08x, %2d.%d%%", smi_status(), counter, pct/10, pct%10);
                strblit(statstr, 0, 0, 0);
        }
        
@@ -56,6 +96,13 @@ void smi_entry(void)
        outl(0xCF8, pcisave);
        outb(0x3D4, vgasave);
        
+       lastentry = entrytime;
+       entrytime = rdtsc();
+       if (entrytime < lastentry)
+               lastlength = entrytime + (0xFFFFFFFFUL - lastentry) + 1;
+       else
+               lastlength = entrytime - lastentry;
+       
        /* Disable caching on SMRAM again, to prevent the user from whacking us. */
        WRMSR(0x202, RDMSR(0x202) & ~(0xFFULL));
 }
@@ -64,14 +111,8 @@ extern void timer_handler(smi_event_t ev);
 extern void kbc_handler(smi_event_t ev);
 extern void gbl_rls_handler(smi_event_t ev);
 
-void __firstrun_stub() {
-
-        /* Try really hard to shut up USB_LEGKEY. */
-        pci_write16(0, 31, 2, 0xC0, pci_read16(0, 31, 2, 0xC0));
-        pci_write16(0, 31, 2, 0xC0, 0);
-        pci_write16(0, 31, 4, 0xC0, pci_read16(0, 31, 4, 0xC0));
-        pci_write16(0, 31, 4, 0xC0, 0);
-
+void __firstrun_stub()
+{
         /* Turn on the SMIs we want */
         smi_disable();
 
This page took 0.025334 seconds and 4 git commands to generate.