diff options
Diffstat (limited to 'smp.c')
-rw-r--r-- | smp.c | 882 |
1 files changed, 441 insertions, 441 deletions
@@ -35,75 +35,75 @@ void smp_find_cpus(); void barrier_init(int max) { - /* Set the adddress of the barrier structure */ - barr = (struct barrier_s *)((smp_page << 12) + 0x300); - barr->lck.slock = 1; - barr->mutex.slock = 1; - barr->maxproc = max; - barr->count = max; - barr->st1.slock = 1; - barr->st2.slock = 0; + /* Set the adddress of the barrier structure */ + barr = (struct barrier_s *)((smp_page << 12) + 0x300); + barr->lck.slock = 1; + barr->mutex.slock = 1; + barr->maxproc = max; + barr->count = max; + barr->st1.slock = 1; + barr->st2.slock = 0; } void s_barrier_init(int max) { - barr->s_lck.slock = 1; - barr->s_maxproc = max; - barr->s_count = max; - barr->s_st1.slock = 1; - barr->s_st2.slock = 0; + barr->s_lck.slock = 1; + barr->s_maxproc = max; + barr->s_count = max; + barr->s_st1.slock = 1; + barr->s_st2.slock = 0; } void barrier() { - if (num_cpus == 1 || v->fail_safe & 3) { - return; - } - spin_wait(&barr->st1); /* Wait if the barrier is active */ - spin_lock(&barr->lck); /* Get lock for barr struct */ - if (--barr->count == 0) { /* Last process? */ - barr->st1.slock = 0; /* Hold up any processes re-entering */ - barr->st2.slock = 1; /* Release the other processes */ - barr->count++; - spin_unlock(&barr->lck); - } else { - spin_unlock(&barr->lck); - spin_wait(&barr->st2); /* wait for peers to arrive */ - spin_lock(&barr->lck); - if (++barr->count == barr->maxproc) { - barr->st1.slock = 1; - barr->st2.slock = 0; - } - spin_unlock(&barr->lck); + if (num_cpus == 1 || vv->fail_safe & 3) { + return; + } + spin_wait(&barr->st1); /* Wait if the barrier is active */ + spin_lock(&barr->lck); /* Get lock for barr struct */ + if (--barr->count == 0) { /* Last process? */ + barr->st1.slock = 0; /* Hold up any processes re-entering */ + barr->st2.slock = 1; /* Release the other processes */ + barr->count++; + spin_unlock(&barr->lck); + } else { + spin_unlock(&barr->lck); + spin_wait(&barr->st2); /* wait for peers to arrive */ + spin_lock(&barr->lck); + if (++barr->count == barr->maxproc) { + barr->st1.slock = 1; + barr->st2.slock = 0; } + spin_unlock(&barr->lck); + } } void s_barrier() { - if (run_cpus == 1 || v->fail_safe & 3) { - return; - } - spin_wait(&barr->s_st1); /* Wait if the barrier is active */ - spin_lock(&barr->s_lck); /* Get lock for barr struct */ - if (--barr->s_count == 0) { /* Last process? */ - barr->s_st1.slock = 0; /* Hold up any processes re-entering */ - barr->s_st2.slock = 1; /* Release the other processes */ - barr->s_count++; - spin_unlock(&barr->s_lck); - } else { - spin_unlock(&barr->s_lck); - spin_wait(&barr->s_st2); /* wait for peers to arrive */ - spin_lock(&barr->s_lck); - if (++barr->s_count == barr->s_maxproc) { - barr->s_st1.slock = 1; - barr->s_st2.slock = 0; - } - spin_unlock(&barr->s_lck); + if (run_cpus == 1 || vv->fail_safe & 3) { + return; + } + spin_wait(&barr->s_st1); /* Wait if the barrier is active */ + spin_lock(&barr->s_lck); /* Get lock for barr struct */ + if (--barr->s_count == 0) { /* Last process? */ + barr->s_st1.slock = 0; /* Hold up any processes re-entering */ + barr->s_st2.slock = 1; /* Release the other processes */ + barr->s_count++; + spin_unlock(&barr->s_lck); + } else { + spin_unlock(&barr->s_lck); + spin_wait(&barr->s_st2); /* wait for peers to arrive */ + spin_lock(&barr->s_lck); + if (++barr->s_count == barr->s_maxproc) { + barr->s_st1.slock = 1; + barr->s_st2.slock = 0; } + spin_unlock(&barr->s_lck); + } } typedef struct { - bool started; + bool started; } ap_info_t; volatile apic_register_t *APIC = NULL; @@ -113,149 +113,149 @@ volatile ap_info_t AP[MAX_CPUS]; void PUT_MEM16(uintptr_t addr, uint16_t val) { - *((volatile uint16_t *)addr) = val; + *((volatile uint16_t *)addr) = val; } void PUT_MEM32(uintptr_t addr, uint32_t val) { - *((volatile uint32_t *)addr) = val; + *((volatile uint32_t *)addr) = val; } static void inline APIC_WRITE(unsigned reg, uint32_t val) { - APIC[reg][0] = val; + APIC[reg][0] = val; } static inline uint32_t APIC_READ(unsigned reg) { - return APIC[reg][0]; + return APIC[reg][0]; } static void SEND_IPI(unsigned apic_id, unsigned trigger, unsigned level, unsigned mode, - uint8_t vector) + uint8_t vector) { - uint32_t v; - - v = APIC_READ(APICR_ICRHI) & 0x00ffffff; - APIC_WRITE(APICR_ICRHI, v | (apic_id << 24)); - - v = APIC_READ(APICR_ICRLO) & ~0xcdfff; - v |= (APIC_DEST_DEST << APIC_ICRLO_DEST_OFFSET) - | (trigger << APIC_ICRLO_TRIGGER_OFFSET) - | (level << APIC_ICRLO_LEVEL_OFFSET) - | (mode << APIC_ICRLO_DELMODE_OFFSET) - | (vector); - APIC_WRITE(APICR_ICRLO, v); + uint32_t v; + + v = APIC_READ(APICR_ICRHI) & 0x00ffffff; + APIC_WRITE(APICR_ICRHI, v | (apic_id << 24)); + + v = APIC_READ(APICR_ICRLO) & ~0xcdfff; + v |= (APIC_DEST_DEST << APIC_ICRLO_DEST_OFFSET) + | (trigger << APIC_ICRLO_TRIGGER_OFFSET) + | (level << APIC_ICRLO_LEVEL_OFFSET) + | (mode << APIC_ICRLO_DELMODE_OFFSET) + | (vector); + APIC_WRITE(APICR_ICRLO, v); } // Silly way of busywaiting, but we don't have a timer void delay(unsigned us) { - unsigned freq = 1000; // in MHz, assume 1GHz CPU speed - uint64_t cycles = us * freq; - uint64_t t0 = RDTSC(); - uint64_t t1; - volatile unsigned k; - - do { - for (k = 0; k < 1000; k++) continue; - t1 = RDTSC(); - } while (t1 - t0 < cycles); + unsigned freq = 1000; // in MHz, assume 1GHz CPU speed + uint64_t cycles = us * freq; + uint64_t t0 = RDTSC(); + uint64_t t1; + volatile unsigned k; + + do { + for (k = 0; k < 1000; k++) continue; + t1 = RDTSC(); + } while (t1 - t0 < cycles); } static inline void -memset (void *dst, +memset (volatile void *dst, char value, int len) { - int i; - for (i = 0 ; i < len ; i++ ) { - *((char *) dst + i) = value; - } + int i; + for (i = 0 ; i < len ; i++ ) { + *((char *) dst + i) = value; + } } void initialise_cpus(void) { - int i; - - act_cpus = 0; - - if (maxcpus > 1) { - smp_find_cpus(); - /* The total number of CPUs may be limited */ - if (num_cpus > maxcpus) { - num_cpus = maxcpus; - } - /* Determine how many cpus have been selected */ - for(i = 0; i < num_cpus; i++) { - if (cpu_mask[i]) { - act_cpus++; - } - } - } else { - act_cpus = found_cpus = num_cpus = 1; - } - - /* Initialize the barrier before starting AP's */ - barrier_init(act_cpus); - - /* let the BSP initialise the APs. */ - for(i = 1; i < num_cpus; i++) { - /* Only start this CPU if it is selected by the mask */ - if (cpu_mask[i]) { - smp_boot_ap(i); - } - } + int i; + + act_cpus = 0; + + if (maxcpus > 1) { + smp_find_cpus(); + /* The total number of CPUs may be limited */ + if (num_cpus > maxcpus) { + num_cpus = maxcpus; + } + /* Determine how many cpus have been selected */ + for(i = 0; i < num_cpus; i++) { + if (cpu_mask[i]) { + act_cpus++; + } + } + } else { + act_cpus = found_cpus = num_cpus = 1; + } + + /* Initialize the barrier before starting AP's */ + barrier_init(act_cpus); + + /* let the BSP initialise the APs. */ + for(i = 1; i < num_cpus; i++) { + /* Only start this CPU if it is selected by the mask */ + if (cpu_mask[i]) { + smp_boot_ap(i); + } + } } void kick_cpu(unsigned cpu_num) { - unsigned num_sipi, apic_id; - apic_id = cpu_num_to_apic_id[cpu_num]; + unsigned num_sipi, apic_id; + apic_id = cpu_num_to_apic_id[cpu_num]; - // clear the APIC ESR register - APIC_WRITE(APICR_ESR, 0); - APIC_READ(APICR_ESR); + // clear the APIC ESR register + APIC_WRITE(APICR_ESR, 0); + APIC_READ(APICR_ESR); - // asserting the INIT IPI - SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); - delay(100000 / DELAY_FACTOR); + // asserting the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); + delay(100000 / DELAY_FACTOR); - // de-assert the INIT IPI - SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); + // de-assert the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); - for (num_sipi = 0; num_sipi < 2; num_sipi++) { - unsigned timeout; - bool send_pending; - unsigned err; + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; - APIC_WRITE(APICR_ESR, 0); + APIC_WRITE(APICR_ESR, 0); - SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (unsigned)startup_32 >> 12); + SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, (unsigned)startup_32 >> 12); - timeout = 0; - do { - delay(10); - timeout++; - send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; - } while (send_pending && timeout < 1000); + timeout = 0; + do { + delay(10); + timeout++; + send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; + } while (send_pending && timeout < 1000); - if (send_pending) { - cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); - } + if (send_pending) { + cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); + } - delay(100000 / DELAY_FACTOR); - - err = APIC_READ(APICR_ESR) & 0xef; - if (err) { - cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); - hprint(LINE_STATUS+3, COL_MID, err); - } - } + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); + hprint(LINE_STATUS+3, COL_MID, err); + } + } } // These memory locations are used for the trampoline code and data. @@ -266,212 +266,212 @@ void kick_cpu(unsigned cpu_num) void boot_ap(unsigned cpu_num) { - unsigned num_sipi, apic_id; - extern uint8_t gdt; - extern uint8_t _ap_trampoline_start; - extern uint8_t _ap_trampoline_protmode; - unsigned len = &_ap_trampoline_protmode - &_ap_trampoline_start; - apic_id = cpu_num_to_apic_id[cpu_num]; + unsigned num_sipi, apic_id; + extern uint8_t gdt; + extern uint8_t _ap_trampoline_start; + extern uint8_t _ap_trampoline_protmode; + unsigned len = &_ap_trampoline_protmode - &_ap_trampoline_start; + apic_id = cpu_num_to_apic_id[cpu_num]; - memcpy((uint8_t*)BOOTCODESTART, &_ap_trampoline_start, len); + memcpy((uint8_t*)BOOTCODESTART, &_ap_trampoline_start, len); - // Copy a pointer to the temporary GDT to addr GDTPOINTERADDR. - // The temporary gdt is at addr GDTADDR - PUT_MEM16(GDTPOINTERADDR, 4 * 8); - PUT_MEM32(GDTPOINTERADDR + 2, GDTADDR); + // Copy a pointer to the temporary GDT to addr GDTPOINTERADDR. + // The temporary gdt is at addr GDTADDR + PUT_MEM16(GDTPOINTERADDR, 4 * 8); + PUT_MEM32(GDTPOINTERADDR + 2, GDTADDR); - // Copy the first 4 gdt entries from the currently used GDT to the - // temporary GDT. - memcpy((uint8_t *)GDTADDR, &gdt, 32); + // Copy the first 4 gdt entries from the currently used GDT to the + // temporary GDT. + memcpy((uint8_t *)GDTADDR, &gdt, 32); - // clear the APIC ESR register - APIC_WRITE(APICR_ESR, 0); - APIC_READ(APICR_ESR); + // clear the APIC ESR register + APIC_WRITE(APICR_ESR, 0); + APIC_READ(APICR_ESR); - // asserting the INIT IPI - SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); - delay(100000 / DELAY_FACTOR); + // asserting the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 1, APIC_DELMODE_INIT, 0); + delay(100000 / DELAY_FACTOR); - // de-assert the INIT IPI - SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); + // de-assert the INIT IPI + SEND_IPI(apic_id, APIC_TRIGGER_LEVEL, 0, APIC_DELMODE_INIT, 0); - for (num_sipi = 0; num_sipi < 2; num_sipi++) { - unsigned timeout; - bool send_pending; - unsigned err; + for (num_sipi = 0; num_sipi < 2; num_sipi++) { + unsigned timeout; + bool send_pending; + unsigned err; - APIC_WRITE(APICR_ESR, 0); + APIC_WRITE(APICR_ESR, 0); - SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, BOOTCODESTART >> 12); + SEND_IPI(apic_id, 0, 0, APIC_DELMODE_STARTUP, BOOTCODESTART >> 12); - timeout = 0; - do { - delay(10); - timeout++; - send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; - } while (send_pending && timeout < 1000); + timeout = 0; + do { + delay(10); + timeout++; + send_pending = (APIC_READ(APICR_ICRLO) & APIC_ICRLO_STATUS_MASK) != 0; + } while (send_pending && timeout < 1000); - if (send_pending) { - cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); - } + if (send_pending) { + cprint(LINE_STATUS+3, 0, "SMP: STARTUP IPI was never sent"); + } - delay(100000 / DELAY_FACTOR); - - err = APIC_READ(APICR_ESR) & 0xef; - if (err) { - cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); - hprint(LINE_STATUS+3, COL_MID, err); - } - } + delay(100000 / DELAY_FACTOR); + + err = APIC_READ(APICR_ESR) & 0xef; + if (err) { + cprint(LINE_STATUS+3, 0, "SMP: After STARTUP IPI: err = 0x"); + hprint(LINE_STATUS+3, COL_MID, err); + } + } } static int checksum(unsigned char *mp, int len) { - int sum = 0; + int sum = 0; - while (len--) { - sum += *mp++; - } - return (sum & 0xFF); + while (len--) { + sum += *mp++; + } + return (sum & 0xFF); } /* Parse an MP config table for CPU information */ bool read_mp_config_table(uintptr_t addr) { - mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; - uint8_t *tab_entry_ptr; - uint8_t *mpc_table_end; - - if (mpc->signature != MPCSignature) { - return FALSE; - } - if (checksum((unsigned char*)mpc, mpc->length) != 0) { - return FALSE; - } - - /* FIXME: the uintptr_t cast here works around a compilation problem on - * AMD64, but it ignores the real problem, which is that lapic_addr - * is only 32 bits. Maybe that's OK, but it should be investigated. - */ - APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; - - tab_entry_ptr = ((uint8_t*)mpc) + sizeof(mp_config_table_header_t); - mpc_table_end = ((uint8_t*)mpc) + mpc->length; + mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; + uint8_t *tab_entry_ptr; + uint8_t *mpc_table_end; + + if (mpc->signature != MPCSignature) { + return FALSE; + } + if (checksum((unsigned char*)mpc, mpc->length) != 0) { + return FALSE; + } + + /* FIXME: the uintptr_t cast here works around a compilation problem on + * AMD64, but it ignores the real problem, which is that lapic_addr + * is only 32 bits. Maybe that's OK, but it should be investigated. + */ + APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; + + tab_entry_ptr = ((uint8_t*)mpc) + sizeof(mp_config_table_header_t); + mpc_table_end = ((uint8_t*)mpc) + mpc->length; - while (tab_entry_ptr < mpc_table_end) { - switch (*tab_entry_ptr) { - case MP_PROCESSOR: { - mp_processor_entry_t *pe = (mp_processor_entry_t*)tab_entry_ptr; + while (tab_entry_ptr < mpc_table_end) { + switch (*tab_entry_ptr) { + case MP_PROCESSOR: { + mp_processor_entry_t *pe = (mp_processor_entry_t*)tab_entry_ptr; - if (pe->cpu_flag & CPU_BOOTPROCESSOR) { - // BSP is CPU 0 - cpu_num_to_apic_id[0] = pe->apic_id; - } else if (num_cpus < MAX_CPUS) { - cpu_num_to_apic_id[num_cpus] = pe->apic_id; - num_cpus++; - } - found_cpus++; + if (pe->cpu_flag & CPU_BOOTPROCESSOR) { + // BSP is CPU 0 + cpu_num_to_apic_id[0] = pe->apic_id; + } else if (num_cpus < MAX_CPUS) { + cpu_num_to_apic_id[num_cpus] = pe->apic_id; + num_cpus++; + } + found_cpus++; - // we cannot handle non-local 82489DX apics - if ((pe->apic_ver & 0xf0) != 0x10) { - return 0; - } + // we cannot handle non-local 82489DX apics + if ((pe->apic_ver & 0xf0) != 0x10) { + return 0; + } - tab_entry_ptr += sizeof(mp_processor_entry_t); - break; - } - case MP_BUS: { - tab_entry_ptr += sizeof(mp_bus_entry_t); - break; - } - case MP_IOAPIC: { - tab_entry_ptr += sizeof(mp_io_apic_entry_t); - break; - } - case MP_INTSRC: - tab_entry_ptr += sizeof(mp_interrupt_entry_t); - break; - case MP_LINTSRC: - tab_entry_ptr += sizeof(mp_local_interrupt_entry_t); - break; - default: - return FALSE; - } - } - return TRUE; + tab_entry_ptr += sizeof(mp_processor_entry_t); + break; + } + case MP_BUS: { + tab_entry_ptr += sizeof(mp_bus_entry_t); + break; + } + case MP_IOAPIC: { + tab_entry_ptr += sizeof(mp_io_apic_entry_t); + break; + } + case MP_INTSRC: + tab_entry_ptr += sizeof(mp_interrupt_entry_t); + break; + case MP_LINTSRC: + tab_entry_ptr += sizeof(mp_local_interrupt_entry_t); + break; + default: + return FALSE; + } + } + return TRUE; } /* Search for a Floating Pointer structure */ floating_pointer_struct_t * scan_for_floating_ptr_struct(uintptr_t addr, uint32_t length) { - floating_pointer_struct_t *fp; - uintptr_t end = addr + length; - - - while ((uintptr_t)addr < end) { - fp = (floating_pointer_struct_t*)addr; - if (*(unsigned int *)addr == FPSignature && fp->length == 1 && checksum((unsigned char*)addr, 16) == 0 && ((fp->spec_rev == 1) || (fp->spec_rev == 4))) { - return fp; - } - addr += 4; - } - return NULL; + floating_pointer_struct_t *fp; + uintptr_t end = addr + length; + + + while ((uintptr_t)addr < end) { + fp = (floating_pointer_struct_t*)addr; + if (*(unsigned int *)addr == FPSignature && fp->length == 1 && checksum((unsigned char*)addr, 16) == 0 && ((fp->spec_rev == 1) || (fp->spec_rev == 4))) { + return fp; + } + addr += 4; + } + return NULL; } /* Search for a Root System Descriptor Pointer */ rsdp_t *scan_for_rsdp(uintptr_t addr, uint32_t length) { - rsdp_t *rp; - uintptr_t end = addr + length; - - - while ((uintptr_t)addr < end) { - rp = (rsdp_t*)addr; - if (*(unsigned int *)addr == RSDPSignature && - checksum((unsigned char*)addr, rp->length) == 0) { - return rp; - } - addr += 4; - } - return NULL; + rsdp_t *rp; + uintptr_t end = addr + length; + + + while ((uintptr_t)addr < end) { + rp = (rsdp_t*)addr; + if (*(unsigned int *)addr == RSDPSignature && + checksum((unsigned char*)addr, rp->length) == 0) { + return rp; + } + addr += 4; + } + return NULL; } /* Parse a MADT table for processor entries */ int parse_madt(uintptr_t addr) { - mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; - uint8_t *tab_entry_ptr; - uint8_t *mpc_table_end; + mp_config_table_header_t *mpc = (mp_config_table_header_t*)addr; + uint8_t *tab_entry_ptr; + uint8_t *mpc_table_end; - if (checksum((unsigned char*)mpc, mpc->length) != 0) { - return FALSE; - } + if (checksum((unsigned char*)mpc, mpc->length) != 0) { + return FALSE; + } - APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; + APIC = (volatile apic_register_t*)(uintptr_t)mpc->lapic_addr; - tab_entry_ptr = ((uint8_t*)mpc) + sizeof(mp_config_table_header_t); - mpc_table_end = ((uint8_t*)mpc) + mpc->length; - while (tab_entry_ptr < mpc_table_end) { + tab_entry_ptr = ((uint8_t*)mpc) + sizeof(mp_config_table_header_t); + mpc_table_end = ((uint8_t*)mpc) + mpc->length; + while (tab_entry_ptr < mpc_table_end) { - madt_processor_entry_t *pe = (madt_processor_entry_t*)tab_entry_ptr; - if (pe->type == MP_PROCESSOR) { - if (pe->enabled) { - if (num_cpus < MAX_CPUS) { - cpu_num_to_apic_id[num_cpus] = pe->apic_id; + madt_processor_entry_t *pe = (madt_processor_entry_t*)tab_entry_ptr; + if (pe->type == MP_PROCESSOR) { + if (pe->enabled) { + if (num_cpus < MAX_CPUS) { + cpu_num_to_apic_id[num_cpus] = pe->apic_id; - /* the first CPU is the BSP, don't increment */ - if (found_cpus) { - num_cpus++; - } - } - found_cpus++; - } - } - tab_entry_ptr += pe->length; - } - return TRUE; + /* the first CPU is the BSP, don't increment */ + if (found_cpus) { + num_cpus++; + } + } + found_cpus++; + } + } + tab_entry_ptr += pe->length; + } + return TRUE; } /* This is where we search for SMP information in the following order @@ -500,107 +500,107 @@ int parse_madt(uintptr_t addr) { */ void smp_find_cpus() { - floating_pointer_struct_t *fp; - rsdp_t *rp; - rsdt_t *rt; - uint8_t *tab_ptr, *tab_end; - unsigned int *ptr; - unsigned int uiptr; - - if(v->fail_safe & 3) { return; } - - memset(&AP, 0, sizeof AP); - - if(v->fail_safe & 8) - { - // Search for the Floating MP structure pointer - fp = scan_for_floating_ptr_struct(0x0, 0x400); - if (fp == NULL) { - fp = scan_for_floating_ptr_struct(639*0x400, 0x400); - } - if (fp == NULL) { - fp = scan_for_floating_ptr_struct(0xf0000, 0x10000); - } - if (fp == NULL) { - // Search the BIOS ESDS area - unsigned int address = *(unsigned short *)0x40E; - address <<= 4; - if (address) { - fp = scan_for_floating_ptr_struct(address, 0x400); - } - } + floating_pointer_struct_t *fp; + rsdp_t *rp; + rsdt_t *rt; + uint8_t *tab_ptr, *tab_end; + unsigned int *ptr; + unsigned int uiptr; + + if(vv->fail_safe & 3) { return; } + + memset(&AP, 0, sizeof AP); + + if(vv->fail_safe & 8) + { + // Search for the Floating MP structure pointer + fp = scan_for_floating_ptr_struct(0x0, 0x400); + if (fp == NULL) { + fp = scan_for_floating_ptr_struct(639*0x400, 0x400); + } + if (fp == NULL) { + fp = scan_for_floating_ptr_struct(0xf0000, 0x10000); + } + if (fp == NULL) { + // Search the BIOS ESDS area + unsigned int address = *(unsigned short *)0x40E; + address <<= 4; + if (address) { + fp = scan_for_floating_ptr_struct(address, 0x400); + } + } - if (fp != NULL) { - // We have a floating MP pointer - // Is this a default configuration? + if (fp != NULL) { + // We have a floating MP pointer + // Is this a default configuration? - if (fp->feature[0] > 0 && fp->feature[0] <=7) { - // This is a default config so plug in the numbers - num_cpus = 2; - APIC = (volatile apic_register_t*)0xFEE00000; - cpu_num_to_apic_id[0] = 0; - cpu_num_to_apic_id[1] = 1; - return; - } + if (fp->feature[0] > 0 && fp->feature[0] <=7) { + // This is a default config so plug in the numbers + num_cpus = 2; + APIC = (volatile apic_register_t*)0xFEE00000; + cpu_num_to_apic_id[0] = 0; + cpu_num_to_apic_id[1] = 1; + return; + } - // Do we have a pointer to a MP configuration table? - if ( fp->phys_addr != 0) { - if (read_mp_config_table(fp->phys_addr)) { - // Found a good MP table, done - return; - } - } - } - } - - - /* No MP table so far, try to find an ACPI MADT table - * We try to use the MP table first since there is no way to distinguish - * real cores from hyper-threads in the MADT */ - - /* Search for the RSDP */ - rp = scan_for_rsdp(0xE0000, 0x20000); - if (rp == NULL) { + // Do we have a pointer to a MP configuration table? + if ( fp->phys_addr != 0) { + if (read_mp_config_table(fp->phys_addr)) { + // Found a good MP table, done + return; + } + } + } + } + + + /* No MP table so far, try to find an ACPI MADT table + * We try to use the MP table first since there is no way to distinguish + * real cores from hyper-threads in the MADT */ + + /* Search for the RSDP */ + rp = scan_for_rsdp(0xE0000, 0x20000); + if (rp == NULL) { /* Search the BIOS ESDS area */ unsigned int address = *(unsigned short *)0x40E; address <<= 4; - if (address) { - rp = scan_for_rsdp(address, 0x400); + if (address) { + rp = scan_for_rsdp(address, 0x400); } - } + } - if (rp == NULL) { - /* RSDP not found, give up */ - return; - } - - /* Found the RSDP, now get either the RSDT or XSDT */ - if (rp->revision >= 2) { - rt = (rsdt_t *)rp->xrsdt[0]; + if (rp == NULL) { + /* RSDP not found, give up */ + return; + } + + /* Found the RSDP, now get either the RSDT or XSDT */ + if (rp->revision >= 2) { + rt = (rsdt_t *)rp->xrsdt[0]; - if (rt == 0) { - return; - } - // Validate the XSDT - if (*(unsigned int *)rt != XSDTSignature) { - return; - } - if ( checksum((unsigned char*)rt, rt->length) != 0) { - return; - } + if (rt == 0) { + return; + } + // Validate the XSDT + if (*(unsigned int *)rt != XSDTSignature) { + return; + } + if ( checksum((unsigned char*)rt, rt->length) != 0) { + return; + } } else { - rt = (rsdt_t *)rp->rsdt; - if (rt == 0) { - return; - } - /* Validate the RSDT */ - if (*(unsigned int *)rt != RSDTSignature) { - return; - } - if ( checksum((unsigned char*)rt, rt->length) != 0) { - return; - } + rt = (rsdt_t *)rp->rsdt; + if (rt == 0) { + return; + } + /* Validate the RSDT */ + if (*(unsigned int *)rt != RSDTSignature) { + return; + } + if ( checksum((unsigned char*)rt, rt->length) != 0) { + return; + } } /* Scan the RSDT or XSDT for a pointer to the MADT */ @@ -609,62 +609,62 @@ void smp_find_cpus() while (tab_ptr < tab_end) { - uiptr = *((unsigned int *)tab_ptr); - ptr = (unsigned int *)uiptr; - - /* Check for the MADT signature */ - if (ptr && *ptr == MADTSignature) { - /* Found it, now parse it */ - if (parse_madt((uintptr_t)ptr)) { - return; - } - } - tab_ptr += 4; + uiptr = *((unsigned int *)tab_ptr); + ptr = (unsigned int *)uiptr; + + /* Check for the MADT signature */ + if (ptr && *ptr == MADTSignature) { + /* Found it, now parse it */ + if (parse_madt((uintptr_t)ptr)) { + return; + } + } + tab_ptr += 4; } } unsigned my_apic_id() { - return (APIC[APICR_ID][0]) >> 24; + return (APIC[APICR_ID][0]) >> 24; } void smp_ap_booted(unsigned cpu_num) { - AP[cpu_num].started = TRUE; + AP[cpu_num].started = TRUE; } void smp_boot_ap(unsigned cpu_num) { - unsigned timeout; - - boot_ap(cpu_num); - timeout = 0; - do { - delay(1000 / DELAY_FACTOR); - timeout++; - } while (!AP[cpu_num].started && timeout < 100000 / DELAY_FACTOR); - - if (!AP[cpu_num].started) { - cprint(LINE_STATUS+3, 0, "SMP: Boot timeout for"); - dprint(LINE_STATUS+3, COL_MID, cpu_num,2,1); - cprint(LINE_STATUS+3, 26, "Turning off SMP"); - } + unsigned timeout; + + boot_ap(cpu_num); + timeout = 0; + do { + delay(1000 / DELAY_FACTOR); + timeout++; + } while (!AP[cpu_num].started && timeout < 100000 / DELAY_FACTOR); + + if (!AP[cpu_num].started) { + cprint(LINE_STATUS+3, 0, "SMP: Boot timeout for"); + dprint(LINE_STATUS+3, COL_MID, cpu_num,2,1); + cprint(LINE_STATUS+3, 26, "Turning off SMP"); + } } unsigned smp_my_cpu_num() { - unsigned apicid = my_apic_id(); - unsigned i; - - for (i = 0; i < MAX_CPUS; i++) { - if (apicid == cpu_num_to_apic_id[i]) { - break; - } - } - if (i == MAX_CPUS) { - i = 0; - } - return i; + unsigned apicid = my_apic_id(); + unsigned i; + + for (i = 0; i < MAX_CPUS; i++) { + if (apicid == cpu_num_to_apic_id[i]) { + break; + } + } + if (i == MAX_CPUS) { + i = 0; + } + return i; } /* A set of simple functions used to preserve assigned CPU ordinals since @@ -673,19 +673,19 @@ unsigned smp_my_cpu_num() int num_to_ord[MAX_CPUS]; void smp_set_ordinal(int me, int ord) { - num_to_ord[me] = ord; + num_to_ord[me] = ord; } int smp_my_ord_num(int me) { - return num_to_ord[me]; + return num_to_ord[me]; } int smp_ord_to_cpu(int me) { - int i; - for (i=0; i<MAX_CPUS; i++) { - if (num_to_ord[i] == me) return i; - } - return -1; + int i; + for (i=0; i<MAX_CPUS; i++) { + if (num_to_ord[i] == me) return i; + } + return -1; } |