]> Joshua Wise's Git repositories - netwatch.git/blob - netwatch/smi.c
7a33559ec89dc6ee8bd210449d5e30e6a83cee3a
[netwatch.git] / netwatch / smi.c
1 /* smi.c
2  * First-run SMI C entry point
3  * NetWatch system management mode administration console
4  *
5  * Copyright (c) 2008 Jacob Potter and Joshua Wise.  All rights reserved.
6  * This program is free software; you can redistribute and/or modify it under
7  * the terms found in the file LICENSE in the root of this source tree.
8  *
9  */
10
11 #include <io.h>
12 #include <smram.h>
13 #include <video_defines.h>
14 #include <minilib.h>
15 #include <smi.h>
16 #include <pci-bother.h>
17 #include <serial.h>
18 #include <fb.h>
19 #include <output.h>
20 #include <msr.h>
21 #include "../net/net.h"
22 #include "vga-overlay.h"
23
24 unsigned int counter = 0;
25 unsigned long pcisave = 0;
26 unsigned char vgasave = 0;
27
28 unsigned long lastentry = 0;
29 unsigned long lastlength = 0;
30
31 unsigned long rdtsc()
32 {
33         unsigned long tsc;
34         asm volatile ("mov %%cr4, %%eax;"
35              "and $~2, %%eax;"
36              "mov %%eax, %%cr4;"
37              "rdtsc" : "=a"(tsc) : : "edx");
38         return tsc;
39 }
40
41 void smi_entry(void)
42 {
43         char statstr[512];
44         unsigned long entrytime;
45
46         /* Reenable caching on SMRAM. */
47         WRMSR(0x202, (RDMSR(0x202) & ~(0xFFULL)) | 0x06ULL);
48
49         entrytime = rdtsc();
50
51         pcisave = inl(0xCF8);
52         vgasave = inb(0x3D4);
53         pci_unbother_all();
54         
55         serial_init();
56
57         if (fb)
58                 fb->getvmode(fb->priv);
59
60         counter++;
61         if (!fb || fb->curmode.text)
62         {
63                 int totcyc, pct;
64                 
65                 if (entrytime < lastentry)
66                         totcyc = entrytime + (0xFFFFFFFFUL - lastentry) + 1;
67                 else
68                         totcyc = entrytime - lastentry;
69                 if (totcyc == 0)
70                         totcyc = 1;     /* argh */
71                 totcyc /= 1000;
72                 if (totcyc == 0)
73                         totcyc = 1;
74                 
75                 pct = lastlength / totcyc;
76                 
77                 sprintf(statstr, "NetWatch! %08x %08x, %2d.%d%%", smi_status(), counter, pct/10, pct%10);
78                 strblit(statstr, 0, 0, 0);
79         }
80         
81         eth_poll();
82         
83         smi_poll();
84         
85         pci_bother_all();
86         outl(0xCF8, pcisave);
87         outb(0x3D4, vgasave);
88         
89         lastentry = entrytime;
90         entrytime = rdtsc();
91         if (entrytime < lastentry)
92                 lastlength = entrytime + (0xFFFFFFFFUL - lastentry) + 1;
93         else
94                 lastlength = entrytime - lastentry;
95         
96         /* Disable caching on SMRAM again, to prevent the user from whacking us. */
97         WRMSR(0x202, RDMSR(0x202) & ~(0xFFULL));
98 }
99
100 extern void timer_handler(smi_event_t ev);
101 extern void kbc_handler(smi_event_t ev);
102 extern void gbl_rls_handler(smi_event_t ev);
103
104 void __firstrun_stub()
105 {
106         /* Turn on the SMIs we want */
107         smi_disable();
108
109         smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler);
110         smi_enable_event(SMI_EVENT_FAST_TIMER);
111
112         smi_register_handler(SMI_EVENT_DEVTRAP_KBC, kbc_handler);
113         smi_enable_event(SMI_EVENT_DEVTRAP_KBC);
114
115         smi_register_handler(SMI_EVENT_GBL_RLS, gbl_rls_handler);
116         smi_enable_event(SMI_EVENT_GBL_RLS);
117
118         smi_enable();
119 }
This page took 0.032853 seconds and 4 git commands to generate.