Changeset 235 for trunk/hal/x86_64


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

Start adding some code for SMP support

Location:
trunk/hal/x86_64/core
Files:
5 edited

Legend:

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

    r234 r235  
    111111static void hal_acpi_parse_madt(madt_t *madt)
    112112{
     113        madt_lapic_t *lapic;
    113114        madt_lapic_override_t *override;
    114115        void *ptr, *end;
     
    133134                        x86_printf("-> found LAPIC override\n");
    134135                } else if (sub->Type == ACPI_MADT_TYPE_LOCAL_APIC) {
     136                        lapic = (madt_lapic_t *)sub;
     137                        cpu_activate(lapic->Id);
     138                        x86_printf("-> found LAPIC %z\n", (uint64_t)lapic->Id);
    135139                        ncpu++;
    136140                }
  • 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{
  • trunk/hal/x86_64/core/hal_cpu.S

    r234 r235  
    153153        ret
    154154
     155ASM_ENTRY(pause)
     156        pause
     157        ret
     158
     159ASM_ENTRY(wbinvd)
     160        wbinvd
     161        ret
     162
    155163/* -------------------------------------------------------------------------- */
    156164
  • trunk/hal/x86_64/core/hal_init.c

    r234 r235  
    313313        hal_enable_irq(&dummy);
    314314
     315while (1);
     316
    315317        kernel_init(&btinfo);
    316318
     
    347349/* x86-specific per-cpu structures */
    348350typedef struct {
     351        bool_t valid;
    349352        struct tss tss;
    350353        struct tls tls;
     
    354357} percpu_archdata_t;
    355358percpu_archdata_t cpudata[CONFIG_MAX_LOCAL_CORES] __in_kdata;
     359
     360void cpu_activate(uint32_t gid)
     361{
     362        cpudata[gid].valid = true;
     363}
    356364
    357365static void
  • trunk/hal/x86_64/core/hal_internal.h

    r203 r235  
    3232
    3333/* hal_init.c */
     34void cpu_activate(uint32_t gid);
    3435int idt_slot_alloc();
    3536void idt_slot_free(int slot);
     
    5354void tlbflushg();
    5455void tlbflush();
     56void pause();
     57void wbinvd();
    5558
    5659uint32_t atomic_cas_32(volatile uint32_t *ptr, uint32_t exp, uint32_t new);
Note: See TracChangeset for help on using the changeset viewer.