Ignore:
Timestamp:
Jul 19, 2017, 10:03:41 AM (7 years ago)
Author:
max@…
Message:

Start adding some code for SMP support

File:
1 edited

Legend:

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

    r234 r235  
    5858#define PIT_FREQUENCY   1193182
    5959#define HZ              100 /* 1/HZ = 10ms */
     60#define muHZ            1000000 /* 1/muHZ = 1 microsecond */
    6061
    6162#define PIT_TIMER0      0x40
     
    7980#       define CMD_READBACK     0xc0
    8081
    81 void hal_pit_init()
    82 {
    83         /* Initialize PIT clock 0 to the maximum counter value, 65535. */
     82void hal_pit_reset(uint16_t val)
     83{
     84        pit_ticks_base = 0;
     85
     86        /* Initialize PIT clock 0 to value given. */
    8487        out8(PIT_CMD, CMD_COUNTER0|CMD_MODE2|CMD_16BIT);
    85         out8(PIT_TIMER0, 0xFF);
    86         out8(PIT_TIMER0, 0xFF);
     88        out8(PIT_TIMER0, (val >> 0) & 0xFF);
     89        out8(PIT_TIMER0, (val >> 8) & 0xFF);
    8790}
    8891
     
    110113
    111114        return ticks;
     115}
     116
     117/*
     118 * Wait approximately n microseconds.
     119 */
     120void
     121hal_pit_delay(uint64_t n)
     122{
     123        uint64_t nticks;
     124
     125        nticks = 0;
     126        hal_pit_reset(0);
     127
     128        while (n > 0) {
     129                while (hal_pit_timer_read() - nticks < (PIT_FREQUENCY + muHZ/2) / muHZ) {
     130                        /* Wait 1/muHZ sec = 1 microsecond */
     131                }
     132                nticks++;
     133                n--;
     134        }
    112135}
    113136
     
    345368}
    346369
     370static void hal_lapic_icr_wait()
     371{
     372        while ((hal_lapic_read(LAPIC_ICRLO) & LAPIC_DLSTAT_BUSY) != 0) {
     373                pause();
     374        }
     375}
     376
    347377/*
    348378 * Use the PIT, which has a standard clock frequency, to determine the CPU's
     
    357387        hal_lapic_write(LAPIC_ICR_TIMER, 0xFFFFFFFF);
    358388
    359         /* Initialize the PIT */
    360         hal_pit_init();
     389        /* Reset the PIT */
     390        hal_pit_reset(-1);
    361391
    362392        pittick = hal_pit_timer_read() + 1;
     
    423453/* -------------------------------------------------------------------------- */
    424454
     455static void
     456hal_ipi_init(uint32_t gid)
     457{
     458        /* clear the error status */
     459        hal_lapic_write(LAPIC_ESR, 0);
     460        (void)hal_lapic_read(LAPIC_ESR);
     461
     462        /* send the IPI */
     463        hal_lapic_write(LAPIC_ICRHI, gid << LAPIC_ID_SHIFT);
     464        hal_lapic_write(LAPIC_ICRLO, LAPIC_DLMODE_INIT | LAPIC_LEVEL_ASSERT);
     465        hal_lapic_icr_wait();
     466
     467        /* wait 10ms */
     468        hal_pit_delay(10000);
     469
     470        hal_lapic_write(LAPIC_ICRLO,
     471            LAPIC_DLMODE_INIT | LAPIC_TRIGGER_LEVEL | LAPIC_LEVEL_DEASSERT);
     472        hal_lapic_icr_wait();
     473}
     474
     475static void
     476hal_ipi_startup(uint32_t gid, paddr_t pa)
     477{
     478        /* clear the error status */
     479        hal_lapic_write(LAPIC_ESR, 0);
     480        (void)hal_lapic_read(LAPIC_ESR);
     481
     482        /* send the IPI */
     483        hal_lapic_icr_wait();
     484        hal_lapic_write(LAPIC_ICRHI, gid << LAPIC_ID_SHIFT);
     485        hal_lapic_write(LAPIC_ICRLO, pa | LAPIC_DLMODE_STARTUP |
     486            LAPIC_LEVEL_ASSERT);
     487        hal_lapic_icr_wait();
     488}
     489
     490/* -------------------------------------------------------------------------- */
     491
     492int
     493start_secondary_cpu(uint32_t gid, paddr_t pa)
     494{
     495        /*
     496         * Bootstrap code must be addressable in real mode and it must be
     497         * page-aligned.
     498         */
     499        XASSERT(pa < 0x10000 && pa % PAGE_SIZE == 0);
     500
     501        /*
     502         * Local cache flush, in case the BIOS has left the AP with its cache
     503         * disabled. It may not be able to cope with MP coherency.
     504         */
     505        wbinvd();
     506
     507        hal_ipi_init(gid);
     508        hal_pit_delay(10000);
     509
     510        hal_ipi_startup(gid, pa / PAGE_SIZE);
     511        hal_pit_delay(200);
     512
     513        hal_ipi_startup(gid, pa / PAGE_SIZE);
     514        hal_pit_delay(200);
     515
     516        return 0;
     517}
     518
     519/* -------------------------------------------------------------------------- */
     520
    425521void hal_apic_init()
    426522{
Note: See TracChangeset for help on using the changeset viewer.