]> Joshua Wise's Git repositories - netwatch.git/blob - hardware/ich2/timer.c
Add TSC checks to measure how much time we spend in SMM.
[netwatch.git] / hardware / ich2 / timer.c
1 /* timer.c
2  * High precision timer routines for ICH2 southbridge
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 <pci.h>
12 #include <io.h>
13 #include <reg-82801b.h>
14
15 static uint16_t _get_PMBASE()
16 {
17         static long pmbase = -1;
18         
19         if (pmbase == -1)       /* Memoize it so that we don't have to hit PCI so often. */
20                 pmbase = pci_read32(ICH2_LPC_BUS, ICH2_LPC_DEV, ICH2_LPC_FN, ICH2_LPC_PCI_PMBASE) & ICH2_PMBASE_MASK;
21         
22         return pmbase;
23 }
24
25 static unsigned long _curtmr()
26 {
27         return inl(_get_PMBASE() + ICH2_PMBASE_PM1_TMR) & 0xFFFFFF;
28 }
29
30 /* This is kind of a heuristic, since we can't get interrupts. */
31 static unsigned long starttmr = 0, endtmr = 0;
32
33 void oneshot_start_ms(unsigned long milliseconds)
34 {
35         starttmr = _curtmr();
36         endtmr = (starttmr + milliseconds*(ICH2_PM1_TMR_FREQ/1000)) & 0xFFFFFF;
37 }
38
39 int oneshot_running(void)
40 {
41         unsigned long time = _curtmr();
42         
43         if (endtmr == 0 && starttmr == 0)
44                 return 0;
45         if ((endtmr < starttmr) && ((time > starttmr) || (time < endtmr)))
46                 return 1;
47         else if ((time < endtmr) && (time > starttmr))
48                 return 1;
49         endtmr = starttmr = 0;
50         return 0;
51 }
This page took 0.030022 seconds and 4 git commands to generate.