5 static uint8_t checksum(void *start, size_t n) {
18 static void *scanfordword(paddr_t start, paddr_t max, size_t by, uint32_t val) {
19 while (start <= max - by) {
20 if (*(uint32_t *)(PHY2VIRTP(start)) == val) {
21 return PHY2VIRTP(start);
29 /* TODO this could probably be a kernel thread, and just power up
30 * processors as though they were hot-plugged. Except that the
31 * local apic on the BSP needs to be configured
35 uint32_t mpsig = 0x5f504d5f;
36 uint32_t tabsig = 0x504d4350;
39 struct mpconfig *config = 0;
42 /* search for base table */
44 /* search first KB of the extended bios data area */
45 bda = PHY2VIRTP(0x40E);
46 mem = (uintptr_t)((*bda) << 4);
48 for (i=0;i <= 1024 - 16 ;i+=16) {
49 mp = PHY2VIRTP(mem+i);
50 if ( mp->signature == mpsig && checksum(mp, 16) == 0) {
55 /* search last kb of base mem, 639-640k */
57 for (i=0;i<1024-16;i+=16) {
58 mp = PHY2VIRTP(mem+i);
59 if ( mp->signature == mpsig && checksum(mp, 16) == 0) {
64 /* search bios rom address space, f0000 - fffff */
66 for (i=0;i<KB(64)-16;i+=16) {
67 mp = PHY2VIRTP(mem+i);
68 if ( mp->signature == mpsig && checksum(mp, 16) == 0) {
73 printk("mpft not found\n");
76 printk("found mpft at %llx: features1 %x, features2 %x\n", (uintptr_t)mp,
77 (uint32_t)mp->features1, (uint32_t)mp->features2);
78 config = PHY2VIRTP(mp->mpconfigptr);
79 if (config->signature != tabsig) {
80 printk("tabsig bad\n");
84 if (checksum(config, (size_t)config->tablelength) != 0) {
85 printk("config table checksum bad\n");
90 vaddr_t entry = (vaddr_t)config + sizeof *config;
91 printk("mpct local apic: %x, entries: %x, len = %x\n", config->localapicaddr, config->entrycount, config->tablelength);
93 for (i=0;i<config->entrycount;i++) {
95 struct processorentry *proc;
98 etype = *(uint8_t *)entry;
100 case 0: /* processor */
101 proc = (struct processorentry *)entry;
102 printk("processor %x, apic = %x:%s%s\n", procnum,
103 (uint32_t)proc->apicid,
104 proc->enabled ? " enabled" : "",
105 proc->bootstrap ? " bsp" : ""
111 //printk("mp bus\n");
114 case 2: /* io apic */
115 io = (struct ioapic *)entry;
117 printk("ioapic %x %llx\n", io->id, io->address);
119 printk("ioapic %x disabledx\n", io->id);
124 //printk(" type: %x\n", etype);