]> Joshua Wise's Git repositories - netwatch.git/blame_incremental - netwatch/smi.c
Add TSC checks to measure how much time we spend in SMM.
[netwatch.git] / netwatch / smi.c
... / ...
CommitLineData
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
24unsigned int counter = 0;
25unsigned long pcisave = 0;
26unsigned char vgasave = 0;
27
28unsigned long lastentry = 0;
29unsigned long lastlength = 0;
30
31unsigned 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
41void 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 if (inl(0x840) & 0x1000)
84 {
85 /*
86 pci_dump();
87 */
88 outl(0x840, 0x1100);
89 outl(0x840, 0x0100);
90 }
91
92
93 smi_poll();
94
95 pci_bother_all();
96 outl(0xCF8, pcisave);
97 outb(0x3D4, vgasave);
98
99 lastentry = entrytime;
100 entrytime = rdtsc();
101 if (entrytime < lastentry)
102 lastlength = entrytime + (0xFFFFFFFFUL - lastentry) + 1;
103 else
104 lastlength = entrytime - lastentry;
105
106 /* Disable caching on SMRAM again, to prevent the user from whacking us. */
107 WRMSR(0x202, RDMSR(0x202) & ~(0xFFULL));
108}
109
110extern void timer_handler(smi_event_t ev);
111extern void kbc_handler(smi_event_t ev);
112extern void gbl_rls_handler(smi_event_t ev);
113
114void __firstrun_stub()
115{
116 /* Turn on the SMIs we want */
117 smi_disable();
118
119 smi_register_handler(SMI_EVENT_FAST_TIMER, timer_handler);
120 smi_enable_event(SMI_EVENT_FAST_TIMER);
121
122 smi_register_handler(SMI_EVENT_DEVTRAP_KBC, kbc_handler);
123 smi_enable_event(SMI_EVENT_DEVTRAP_KBC);
124
125 smi_register_handler(SMI_EVENT_GBL_RLS, gbl_rls_handler);
126 smi_enable_event(SMI_EVENT_GBL_RLS);
127
128 smi_enable();
129}
This page took 0.022971 seconds and 4 git commands to generate.