Changeset 327 for trunk/hal/x86_64


Ignore:
Timestamp:
Aug 6, 2017, 7:58:22 PM (7 years ago)
Author:
max@…
Message:

Clean up, and fix several SMP-related issues. The LAPIC timer is still
drifting away between CPUs in some cases, needs to be investigated.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/x86_64/core/hal_apic.c

    r237 r327  
    4848         * Disable the PIC (8259A). We are going to use IOAPIC instead.
    4949         */
    50         out8(PIC1_DATA, 0xff);
    51         out8(PIC2_DATA, 0xff);
    52 }
    53 
    54 /* -------------------------------------------------------------------------- */
    55 
    56 uint64_t pit_ticks_base __in_kdata = 0;
     50        out8(PIC1_DATA, 0xFF);
     51        out8(PIC2_DATA, 0xFF);
     52}
     53
     54/* -------------------------------------------------------------------------- */
     55
     56static uint64_t pit_ticks_base __in_kdata = 0;
     57static uint16_t pit_ticks_last __in_kdata = 0;
    5758
    5859#define PIT_FREQUENCY   1193182
     
    6970#       define CMD_MODE2        0x04 /* Rate Generator */
    7071#       define CMD_MODE3        0x06 /* Square Wave */
    71 #       define CMD_MODE4        0x08 /* Software Trigerred Strobe */
    72 #       define CMD_MODE5        0x0a /* Hardware Trigerred Strobe */
     72#       define CMD_MODE4        0x08 /* Software Triggered Strobe */
     73#       define CMD_MODE5        0x0a /* Hardware Triggered Strobe */
    7374#       define CMD_LATCH        0x00 /* latch counter for reading */
    7475#       define CMD_LSB          0x10 /* LSB, 8 bits */
     
    8283void hal_pit_reset(uint16_t val)
    8384{
     85        uint8_t lo, hi;
     86
    8487        pit_ticks_base = 0;
    8588
    86         /* Initialize PIT clock 0 to value given. */
     89        /* Set the initial counter value for clock 0. */
    8790        out8(PIT_CMD, CMD_COUNTER0|CMD_MODE2|CMD_16BIT);
    8891        out8(PIT_TIMER0, (val >> 0) & 0xFF);
    8992        out8(PIT_TIMER0, (val >> 8) & 0xFF);
     93
     94        /*
     95         * Read the current value, to initialize pit_ticks_last. Not extremely
     96         * accurate, but fine.
     97         */
     98        out8(PIT_CMD, CMD_COUNTER0|CMD_LATCH);
     99        lo = in8(PIT_TIMER0);
     100        hi = in8(PIT_TIMER0);
     101
     102        pit_ticks_last = (hi << 8) | lo;
    90103}
    91104
     
    93106hal_pit_timer_read()
    94107{
    95         static uint16_t last;
    96 
    97108        uint8_t lo, hi;
    98109        uint16_t ctr;
     
    105116        ctr = (hi << 8) | lo;
    106117
    107         /* If the counter has wrapped, assume we're into the next tick. */
    108         if (ctr > last)
     118        /* If the counter has overflown, assume we're into the next tick. */
     119        if (ctr > pit_ticks_last)
    109120                pit_ticks_base += 0xFFFF;
    110         last = ctr;
     121        pit_ticks_last = ctr;
    111122
    112123        ticks = pit_ticks_base + (0xFFFF - ctr);
     
    124135
    125136        nticks = 0;
    126         hal_pit_reset(0);
     137        hal_pit_reset(0xFFFF);
    127138
    128139        while (n > 0) {
     
    130141                        /* Wait 1/muHZ sec = 1 microsecond */
    131142                }
    132                 nticks++;
     143                nticks++; // ???
    133144                n--;
    134145        }
     
    388399
    389400        /* Reset the PIT */
    390         hal_pit_reset(-1);
     401        hal_pit_reset(0xFFFF);
    391402
    392403        pittick = hal_pit_timer_read() + 1;
     
    405416        lapictick1 = hal_lapic_read(LAPIC_CCR_TIMER);
    406417
     418        if (lapictick1 > lapictick0)
     419                x86_panic("LAPIC tick overflow!");
     420
    407421        /* Total number of LAPIC ticks per 1/HZ tick */
    408         lapicticks = (lapictick1 - lapictick0);
    409 
    410         /* Finally, calibrate the timer, an interrupt each 1s. */
    411         lapicstart = - (lapicticks * 100);
     422        lapicticks = (lapictick0 - lapictick1);
     423
     424        /*
     425         * Finally, calibrate the timer, with an interrupt each 1s (10ms * 100).
     426         */
     427        lapicstart = (lapicticks * 100);
    412428        hal_lapic_write(LAPIC_ICR_TIMER, lapicstart);
     429        x86_printf("-> lapicticks: %z\n", (uint64_t)lapicticks);
    413430}
    414431
Note: See TracChangeset for help on using the changeset viewer.