Changeset fe32163 in mainline for kernel/arch/ia32/src/smp/smp.c


Ignore:
Timestamp:
2010-06-29T00:08:48Z (14 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c19aa612
Parents:
9a21f9d
Message:

improve support for inactive CPUs
major revision of MADT and MPS parsing code
limit the number of active CPUs on ia32 and amd64 to 8 (actually the APIC ID of all active CPUs must be in the range 0 .. 7 to avoid tripping on an assertion in APIC code)
fix off-by-one bug in MADT parsing code (missing the last entry)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/ia32/src/smp/smp.c

    r9a21f9d rfe32163  
    6262void smp_init(void)
    6363{
    64         uintptr_t l_apic_address, io_apic_address;
    65 
     64        uintptr_t l_apic_address;
     65        uintptr_t io_apic_address;
     66       
    6667        if (acpi_madt) {
    6768                acpi_madt_parse();
    6869                ops = &madt_config_operations;
    6970        }
     71       
    7072        if (config.cpu_count == 1) {
    7173                mps_init();
    7274                ops = &mps_config_operations;
    7375        }
    74 
     76       
    7577        l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
    7678            FRAME_ATOMIC | FRAME_KA);
    7779        if (!l_apic_address)
    7880                panic("Cannot allocate address for l_apic.");
    79 
     81       
    8082        io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME,
    8183            FRAME_ATOMIC | FRAME_KA);
    8284        if (!io_apic_address)
    8385                panic("Cannot allocate address for io_apic.");
    84 
     86       
    8587        if (config.cpu_count > 1) {
    8688                page_table_lock(AS_KERNEL, true);
     
    9092                    (uintptr_t) io_apic, PAGE_NOT_CACHEABLE | PAGE_WRITE);
    9193                page_table_unlock(AS_KERNEL, true);
    92                                  
     94               
    9395                l_apic = (uint32_t *) l_apic_address;
    9496                io_apic = (uint32_t *) io_apic_address;
     
    108110       
    109111        ASSERT(ops != NULL);
    110 
     112       
    111113        /*
    112114         * We need to access data in frame 0.
    113115         * We boldly make use of kernel address space mapping.
    114116         */
    115 
     117       
    116118        /*
    117119         * Set the warm-reset vector to the real-mode address of 4K-aligned ap_boot()
    118120         */
    119121        *((uint16_t *) (PA2KA(0x467 + 0))) =
    120             (uint16_t) (((uintptr_t) ap_boot) >> 4);    /* segment */
    121         *((uint16_t *) (PA2KA(0x467 + 2))) = 0;         /* offset */
     122            (uint16_t) (((uintptr_t) ap_boot) >> 4);  /* segment */
     123        *((uint16_t *) (PA2KA(0x467 + 2))) = 0;       /* offset */
    122124       
    123125        /*
     
    125127         * BIOS will not do the POST after the INIT signal.
    126128         */
    127         pio_write_8((ioport8_t *)0x70, 0xf);
    128         pio_write_8((ioport8_t *)0x71, 0xa);
    129 
     129        pio_write_8((ioport8_t *) 0x70, 0xf);
     130        pio_write_8((ioport8_t *) 0x71, 0xa);
     131       
    130132        pic_disable_irqs(0xffff);
    131133        apic_init();
    132134       
    133135        uint8_t apic = l_apic_id();
    134 
    135         for (i = 0; i < ops->cpu_count(); i++) {
    136                 descriptor_t *gdt_new;
    137                
     136       
     137        for (i = 0; i < config.cpu_count; i++) {
    138138                /*
    139139                 * Skip processors marked unusable.
     
    141141                if (!ops->cpu_enabled(i))
    142142                        continue;
    143 
     143               
    144144                /*
    145145                 * The bootstrap processor is already up.
     
    147147                if (ops->cpu_bootstrap(i))
    148148                        continue;
    149 
     149               
    150150                if (ops->cpu_apic_id(i) == apic) {
    151151                        printf("%s: bad processor entry #%u, will not send IPI "
     
    162162                 * the memory subsystem
    163163                 */
    164                 gdt_new = (descriptor_t *) malloc(GDT_ITEMS *
    165                     sizeof(descriptor_t), FRAME_ATOMIC);
     164                descriptor_t *gdt_new =
     165                    (descriptor_t *) malloc(GDT_ITEMS * sizeof(descriptor_t),
     166                    FRAME_ATOMIC);
    166167                if (!gdt_new)
    167168                        panic("Cannot allocate memory for GDT.");
    168 
     169               
    169170                memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t));
    170171                memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0);
     
    172173                protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
    173174                gdtr.base = (uintptr_t) gdt_new;
    174 
     175               
    175176                if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) {
    176177                        /*
     
    181182                        if (waitq_sleep_timeout(&ap_completion_wq, 1000000,
    182183                            SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) {
    183                                 unsigned int cpu = (config.cpu_active > i) ?
    184                                     config.cpu_active : i;
    185184                                printf("%s: waiting for cpu%u (APIC ID = %d) "
    186                                     "timed out\n", __FUNCTION__, cpu,
     185                                    "timed out\n", __FUNCTION__, i,
    187186                                    ops->cpu_apic_id(i));
    188187                        }
Note: See TracChangeset for help on using the changeset viewer.