This source file includes following definitions.
- sum
- mpsearch1
- mpsearch
- mpconfig
- mpinit
1
2
3
4
5 #include "types.h"
6 #include "defs.h"
7 #include "param.h"
8 #include "memlayout.h"
9 #include "mp.h"
10 #include "x86.h"
11 #include "mmu.h"
12 #include "proc.h"
13
14 struct cpu cpus[NCPU];
15 int ncpu;
16 uchar ioapicid;
17
18 static uchar
19 sum(uchar *addr, int len)
20 {
21 int i, sum;
22
23 sum = 0;
24 for(i=0; i<len; i++)
25 sum += addr[i];
26 return sum;
27 }
28
29
30 static struct mp*
31 mpsearch1(uint a, int len)
32 {
33 uchar *e, *p, *addr;
34
35 addr = P2V(a);
36 e = addr+len;
37 for(p = addr; p < e; p += sizeof(struct mp))
38 if(memcmp(p, "_MP_", 4) == 0 && sum(p, sizeof(struct mp)) == 0)
39 return (struct mp*)p;
40 return 0;
41 }
42
43
44
45
46
47
48 static struct mp*
49 mpsearch(void)
50 {
51 uchar *bda;
52 uint p;
53 struct mp *mp;
54
55 bda = (uchar *) P2V(0x400);
56 if((p = ((bda[0x0F]<<8)| bda[0x0E]) << 4)){
57 if((mp = mpsearch1(p, 1024)))
58 return mp;
59 } else {
60 p = ((bda[0x14]<<8)|bda[0x13])*1024;
61 if((mp = mpsearch1(p-1024, 1024)))
62 return mp;
63 }
64 return mpsearch1(0xF0000, 0x10000);
65 }
66
67
68
69
70
71
72 static struct mpconf*
73 mpconfig(struct mp **pmp)
74 {
75 struct mpconf *conf;
76 struct mp *mp;
77
78 if((mp = mpsearch()) == 0 || mp->physaddr == 0)
79 return 0;
80 conf = (struct mpconf*) P2V((uint) mp->physaddr);
81 if(memcmp(conf, "PCMP", 4) != 0)
82 return 0;
83 if(conf->version != 1 && conf->version != 4)
84 return 0;
85 if(sum((uchar*)conf, conf->length) != 0)
86 return 0;
87 *pmp = mp;
88 return conf;
89 }
90
91 void
92 mpinit(void)
93 {
94 uchar *p, *e;
95 int ismp;
96 struct mp *mp;
97 struct mpconf *conf;
98 struct mpproc *proc;
99 struct mpioapic *ioapic;
100
101 if((conf = mpconfig(&mp)) == 0)
102 panic("Expect to run on an SMP");
103 ismp = 1;
104 lapic = (uint*)conf->lapicaddr;
105 for(p=(uchar*)(conf+1), e=(uchar*)conf+conf->length; p<e; ){
106 switch(*p){
107 case MPPROC:
108 proc = (struct mpproc*)p;
109 if(ncpu < NCPU) {
110 cpus[ncpu].apicid = proc->apicid;
111 ncpu++;
112 }
113 p += sizeof(struct mpproc);
114 continue;
115 case MPIOAPIC:
116 ioapic = (struct mpioapic*)p;
117 ioapicid = ioapic->apicno;
118 p += sizeof(struct mpioapic);
119 continue;
120 case MPBUS:
121 case MPIOINTR:
122 case MPLINTR:
123 p += 8;
124 continue;
125 default:
126 ismp = 0;
127 break;
128 }
129 }
130 if(!ismp)
131 panic("Didn't find a suitable machine");
132
133 if(mp->imcrp){
134
135
136 outb(0x22, 0x70);
137 outb(0x23, inb(0x23) | 1);
138 }
139 }