1 // Multiprocessor bootstrap.
2 // Search memory for MP description structures.
3 // http://developer.intel.com/design/pentium/datashts/24201606.pdf
13 struct cpu cpus
[NCPU
];
14 static struct cpu
*bcpu
;
26 sum(uchar
*addr
, int len
)
36 // Look for an MP structure in the len bytes at addr.
38 mpsearch1(uchar
*addr
, int len
)
43 for(p
= addr
; p
< e
; p
+= sizeof(struct mp
))
44 if(memcmp(p
, "_MP_", 4) == 0 && sum(p
, sizeof(struct mp
)) == 0)
49 // Search for the MP Floating Pointer Structure, which according to the
50 // spec is in one of the following three locations:
51 // 1) in the first KB of the EBDA;
52 // 2) in the last KB of system base memory;
53 // 3) in the BIOS ROM between 0xE0000 and 0xFFFFF.
62 if((p
= ((bda
[0x0F]<<8)|bda
[0x0E]) << 4)){
63 if((mp
= mpsearch1((uchar
*)p
, 1024)))
66 p
= ((bda
[0x14]<<8)|bda
[0x13])*1024;
67 if((mp
= mpsearch1((uchar
*)p
-1024, 1024)))
70 return mpsearch1((uchar
*)0xF0000, 0x10000);
73 // Search for an MP configuration table. For now,
74 // don't accept the default configurations (physaddr == 0).
75 // Check for correct signature, calculate the checksum and,
76 // if correct, check the version.
77 // To do: check extended table checksum.
79 mpconfig(struct mp
**pmp
)
84 if((mp
= mpsearch()) == 0 || mp
->physaddr
== 0)
86 conf
= (struct mpconf
*)mp
->physaddr
;
87 if(memcmp(conf
, "PCMP", 4) != 0)
89 if(conf
->version
!= 1 && conf
->version
!= 4)
91 if(sum((uchar
*)conf
, conf
->length
) != 0)
104 struct mpioapic
*ioapic
;
107 if((conf
= mpconfig(&mp
)) == 0)
110 lapic
= (uint
*)conf
->lapicaddr
;
111 for(p
=(uchar
*)(conf
+1), e
=(uchar
*)conf
+conf
->length
; p
<e
; ){
114 proc
= (struct mpproc
*)p
;
115 if(ncpu
!= proc
->apicid
){
116 cprintf("mpinit: ncpu=%d apicid=%d\n", ncpu
, proc
->apicid
);
119 if(proc
->flags
& MPBOOT
)
121 cpus
[ncpu
].id
= ncpu
;
123 p
+= sizeof(struct mpproc
);
126 ioapic
= (struct mpioapic
*)p
;
127 ioapicid
= ioapic
->apicno
;
128 p
+= sizeof(struct mpioapic
);
136 cprintf("mpinit: unknown config type %x\n", *p
);
141 // Didn't like what we found; fall back to no MP.
149 // Bochs doesn't support IMCR, so this doesn't run on Bochs.
150 // But it would on real hardware.
151 outb(0x22, 0x70); // Select IMCR
152 outb(0x23, inb(0x23) | 1); // Mask external interrupts.