- Timestamp:
- Jul 3, 2017, 11:21:16 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/hal/x86_64/core/hal_apic.c
r89 r117 54 54 /* -------------------------------------------------------------------------- */ 55 55 56 uint64_t pit_ticks_base __in_kdata = 0; 57 58 #define PIT_FREQUENCY 1193182 59 #define HZ 100 /* 1/HZ = 10ms */ 60 61 #define PIT_TIMER0 0x40 62 63 #define PIT_CMD 0x43 64 # define CMD_BINARY 0x00 /* Use Binary counter values */ 65 # define CMD_BCD 0x01 /* Use Binary Coded Decimal counter values */ 66 # define CMD_MODE0 0x00 /* Interrupt on Terminal Count */ 67 # define CMD_MODE1 0x02 /* Hardware Retriggerable One-Shot */ 68 # define CMD_MODE2 0x04 /* Rate Generator */ 69 # define CMD_MODE3 0x06 /* Square Wave */ 70 # define CMD_MODE4 0x08 /* Software Trigerred Strobe */ 71 # define CMD_MODE5 0x0a /* Hardware Trigerred Strobe */ 72 # define CMD_LATCH 0x00 /* latch counter for reading */ 73 # define CMD_LSB 0x10 /* LSB, 8 bits */ 74 # define CMD_MSB 0x20 /* MSB, 8 bits */ 75 # define CMD_16BIT 0x30 /* LSB and MSB, 16 bits */ 76 # define CMD_COUNTER0 0x00 77 # define CMD_COUNTER1 0x40 78 # define CMD_COUNTER2 0x80 79 # define CMD_READBACK 0xc0 80 81 void hal_pit_init() 82 { 83 /* Initialize PIT clock 0 to the maximum counter value, 65535. */ 84 out8(PIT_CMD, CMD_COUNTER0|CMD_MODE2|CMD_16BIT); 85 out8(PIT_TIMER0, 0xFF); 86 out8(PIT_TIMER0, 0xFF); 87 } 88 89 uint64_t 90 hal_pit_timer_read() 91 { 92 static uint16_t last; 93 94 uint8_t lo, hi; 95 uint16_t ctr; 96 uint64_t ticks; 97 98 /* Read the current timer counter. */ 99 out8(PIT_CMD, CMD_COUNTER0|CMD_LATCH); 100 lo = in8(PIT_TIMER0); 101 hi = in8(PIT_TIMER0); 102 ctr = (hi << 8) | lo; 103 104 /* If the counter has wrapped, assume we're into the next tick. */ 105 if (ctr > last) 106 pit_ticks_base += 0xFFFF; 107 last = ctr; 108 109 ticks = pit_ticks_base + (0xFFFF - ctr); 110 111 return ticks; 112 } 113 114 /* -------------------------------------------------------------------------- */ 115 56 116 paddr_t ioapic_pa __in_kdata = 0; 57 117 vaddr_t ioapic_va __in_kdata = 0; … … 132 192 { 133 193 return hal_lapic_read(LAPIC_ID) >> LAPIC_ID_SHIFT; 194 } 195 196 /* 197 * Use the PIT, which has a standard clock frequency, to determine the CPU's 198 * exact bus frequency. 199 */ 200 static void hal_lapic_calibrate() 201 { 202 uint64_t pittick, lapictick0, lapictick1; 203 uint32_t lapicticks, lapicstart; 204 205 /* Initialize the LAPIC timer to the maximum value */ 206 hal_lapic_write(LAPIC_ICR_TIMER, 0xFFFFFFFF); 207 208 pittick = hal_pit_timer_read() + 1; 209 while (hal_pit_timer_read() < pittick) { 210 /* Wait until start of a PIT tick */ 211 } 212 213 /* Read base count from LAPIC */ 214 lapictick0 = hal_lapic_read(LAPIC_CCR_TIMER); 215 216 while (hal_pit_timer_read() < pittick + (PIT_FREQUENCY + HZ/2) / HZ) { 217 /* Wait 1/HZ sec = 10ms */ 218 } 219 220 /* Read final count from LAPIC */ 221 lapictick1 = hal_lapic_read(LAPIC_CCR_TIMER); 222 223 /* Total number of LAPIC ticks per 1/HZ tick */ 224 lapicticks = (lapictick1 - lapictick0); 225 226 /* Finally, calibrate the timer, an interrupt each 1s. */ 227 lapicstart = - (lapicticks * 100); 228 hal_lapic_write(LAPIC_ICR_TIMER, lapicstart); 134 229 } 135 230 … … 171 266 hal_lapic_write(LAPIC_LVT_TMR, LAPIC_TMR_TM|LAPIC_TMR_M); 172 267 hal_lapic_write(LAPIC_DCR_TIMER, LAPIC_DCRT_DIV1); 173 hal_lapic_ write(LAPIC_ICR_TIMER, 1000000000); // XXX calibrate268 hal_lapic_calibrate(); 174 269 hal_lapic_write(LAPIC_LVT_TMR, LAPIC_TMR_TM|LAPIC_TIMER_VECTOR); 175 270 }
Note: See TracChangeset
for help on using the changeset viewer.