xref: /plan9/sys/src/9/pc/mp.h (revision 1206f3fc1b0aab3e32fa15899d31a9b5bfa82d9f)
1 /*
2  * MultiProcessor Specification Version 1.[14].
3  */
4 typedef struct {			/* floating pointer */
5 	uchar	signature[4];		/* "_MP_" */
6 	long	physaddr;		/* physical address of MP configuration table */
7 	uchar	length;			/* 1 */
8 	uchar	specrev;		/* [14] */
9 	uchar	checksum;		/* all bytes must add up to 0 */
10 	uchar	type;			/* MP system configuration type */
11 	uchar	imcrp;
12 	uchar	reserved[3];
13 } _MP_;
14 
15 typedef struct {			/* configuration table header */
16 	uchar	signature[4];		/* "PCMP" */
17 	ushort	length;			/* total table length */
18 	uchar	version;		/* [14] */
19 	uchar	checksum;		/* all bytes must add up to 0 */
20 	uchar	product[20];		/* product id */
21 	ulong	oemtable;		/* OEM table pointer */
22 	ushort	oemlength;		/* OEM table length */
23 	ushort	entry;			/* entry count */
24 	ulong	lapicbase;		/* address of local APIC */
25 	ushort	xlength;		/* extended table length */
26 	uchar	xchecksum;		/* extended table checksum */
27 	uchar	reserved;
28 } PCMP;
29 
30 typedef struct {			/* processor table entry */
31 	uchar	type;			/* entry type (0) */
32 	uchar	apicno;			/* local APIC id */
33 	uchar	version;		/* local APIC verison */
34 	uchar	flags;			/* CPU flags */
35 	uchar	signature[4];		/* CPU signature */
36 	ulong	feature;		/* feature flags from CPUID instruction */
37 	uchar	reserved[8];
38 } PCMPprocessor;
39 
40 typedef struct {			/* bus table entry */
41 	uchar	type;			/* entry type (1) */
42 	uchar	busno;			/* bus id */
43 	char	string[6];		/* bus type string */
44 } PCMPbus;
45 
46 typedef struct {			/* I/O APIC table entry */
47 	uchar	type;			/* entry type (2) */
48 	uchar	apicno;			/* I/O APIC id */
49 	uchar	version;		/* I/O APIC version */
50 	uchar	flags;			/* I/O APIC flags */
51 	ulong	addr;			/* I/O APIC address */
52 } PCMPioapic;
53 
54 typedef struct {			/* interrupt table entry */
55 	uchar	type;			/* entry type ([34]) */
56 	uchar	intr;			/* interrupt type */
57 	ushort	flags;			/* interrupt flag */
58 	uchar	busno;			/* source bus id */
59 	uchar	irq;			/* source bus irq */
60 	uchar	apicno;			/* destination APIC id */
61 	uchar	intin;			/* destination APIC [L]INTIN# */
62 } PCMPintr;
63 
64 typedef struct {			/* system address space mapping entry */
65 	uchar	type;			/* entry type (128) */
66 	uchar	length;			/* of this entry (20) */
67 	uchar	busno;			/* bus id */
68 	uchar	addrtype;
69 	ulong	addrbase[2];
70 	ulong	addrlength[2];
71 } PCMPsasm;
72 
73 typedef struct {			/* bus hierarchy descriptor entry */
74 	uchar	type;			/* entry type (129) */
75 	uchar	length;			/* of this entry (8) */
76 	uchar	busno;			/* bus id */
77 	uchar	info;			/* bus info */
78 	uchar	parent;			/* parent bus */
79 	uchar	reserved[3];
80 } PCMPhierarchy;
81 
82 typedef struct {			/* compatibility bus address space modifier entry */
83 	uchar	type;			/* entry type (130) */
84 	uchar	length;			/* of this entry (8) */
85 	uchar	busno;			/* bus id */
86 	uchar	modifier;		/* address modifier */
87 	ulong	range;			/* predefined range list */
88 } PCMPcbasm;
89 
90 enum {					/* table entry types */
91 	PcmpPROCESSOR	= 0x00,		/* one entry per processor */
92 	PcmpBUS		= 0x01,		/* one entry per bus */
93 	PcmpIOAPIC	= 0x02,		/* one entry per I/O APIC */
94 	PcmpIOINTR	= 0x03,		/* one entry per bus interrupt source */
95 	PcmpLINTR	= 0x04,		/* one entry per system interrupt source */
96 
97 	PcmpSASM	= 0x80,
98 	PcmpHIERARCHY	= 0x81,
99 	PcmpCBASM	= 0x82,
100 
101 					/* PCMPprocessor and PCMPioapic flags */
102 	PcmpEN		= 0x01,		/* enabled */
103 	PcmpBP		= 0x02,		/* bootstrap processor */
104 
105 					/* PCMPiointr and PCMPlintr flags */
106 	PcmpPOMASK	= 0x03,		/* polarity conforms to specifications of bus */
107 	PcmpHIGH	= 0x01,		/* active high */
108 	PcmpLOW		= 0x03,		/* active low */
109 	PcmpELMASK	= 0x0C,		/* trigger mode of APIC input signals */
110 	PcmpEDGE	= 0x04,		/* edge-triggered */
111 	PcmpLEVEL	= 0x0C,		/* level-triggered */
112 
113 					/* PCMPiointr and PCMPlintr interrupt type */
114 	PcmpINT		= 0x00,		/* vectored interrupt from APIC Rdt */
115 	PcmpNMI		= 0x01,		/* non-maskable interrupt */
116 	PcmpSMI		= 0x02,		/* system management interrupt */
117 	PcmpExtINT	= 0x03,		/* vectored interrupt from external PIC */
118 
119 					/* PCMPsasm addrtype */
120 	PcmpIOADDR	= 0x00,		/* I/O address */
121 	PcmpMADDR	= 0x01,		/* memory address */
122 	PcmpPADDR	= 0x02,		/* prefetch address */
123 
124 					/* PCMPhierarchy info */
125 	PcmpSD		= 0x01,		/* subtractive decode bus */
126 
127 					/* PCMPcbasm modifier */
128 	PcmpPR		= 0x01,		/* predefined range list */
129 };
130 
131 /*
132  * Condensed form of the MP Configuration Table.
133  * This is created during a single pass through the MP Configuration
134  * table.
135  */
136 typedef struct Aintr Aintr;
137 typedef struct Bus Bus;
138 typedef struct Apic Apic;
139 
140 typedef struct Bus {
141 	uchar	type;
142 	uchar	busno;
143 	uchar	po;
144 	uchar	el;
145 
146 	Aintr*	aintr;			/* interrupts tied to this bus */
147 	Bus*	next;
148 } Bus;
149 
150 typedef struct Aintr {
151 	PCMPintr* intr;
152 	Apic*	apic;
153 	Aintr*	next;
154 };
155 
156 typedef struct Apic {
157 	int	type;
158 	int	apicno;
159 	ulong*	addr;			/* register base address */
160 	ulong	paddr;
161 	int	flags;			/* PcmpBP|PcmpEN */
162 
163 	Lock;				/* I/O APIC: register access */
164 	int	mre;			/* I/O APIC: maximum redirection entry */
165 
166 	int	lintr[2];		/* Local APIC */
167 	int	machno;
168 
169 	int	online;
170 } Apic;
171 
172 enum {
173 	MaxAPICNO	= 254,		/* 255 is physical broadcast */
174 };
175 
176 enum {					/* I/O APIC registers */
177 	IoapicID	= 0x00,		/* ID */
178 	IoapicVER	= 0x01,		/* version */
179 	IoapicARB	= 0x02,		/* arbitration ID */
180 	IoapicRDT	= 0x10,		/* redirection table */
181 };
182 
183 /*
184  * Common bits for
185  *	I/O APIC Redirection Table Entry;
186  *	Local APIC Local Interrupt Vector Table;
187  *	Local APIC Inter-Processor Interrupt;
188  *	Local APIC Timer Vector Table.
189  */
190 enum {
191 	ApicFIXED	= 0x00000000,	/* [10:8] Delivery Mode */
192 	ApicLOWEST	= 0x00000100,	/* Lowest priority */
193 	ApicSMI		= 0x00000200,	/* System Management Interrupt */
194 	ApicRR		= 0x00000300,	/* Remote Read */
195 	ApicNMI		= 0x00000400,
196 	ApicINIT	= 0x00000500,	/* INIT/RESET */
197 	ApicSTARTUP	= 0x00000600,	/* Startup IPI */
198 	ApicExtINT	= 0x00000700,
199 
200 	ApicPHYSICAL	= 0x00000000,	/* [11] Destination Mode (RW) */
201 	ApicLOGICAL	= 0x00000800,
202 
203 	ApicDELIVS	= 0x00001000,	/* [12] Delivery Status (RO) */
204 	ApicHIGH	= 0x00000000,	/* [13] Interrupt Input Pin Polarity (RW) */
205 	ApicLOW		= 0x00002000,
206 	ApicRemoteIRR	= 0x00004000,	/* [14] Remote IRR (RO) */
207 	ApicEDGE	= 0x00000000,	/* [15] Trigger Mode (RW) */
208 	ApicLEVEL	= 0x00008000,
209 	ApicIMASK	= 0x00010000,	/* [16] Interrupt Mask */
210 };
211 
212 extern void ioapicinit(Apic*, int);
213 extern void ioapicrdtr(Apic*, int, int*, int*);
214 extern void ioapicrdtw(Apic*, int, int, int);
215 
216 extern void lapicclock(Ureg*, void*);
217 extern int lapiceoi(int);
218 extern void lapicerror(Ureg*, void*);
219 extern void lapicicrw(ulong, ulong);
220 extern void lapicinit(Apic*);
221 extern void lapicintroff(void);
222 extern void lapicintron(void);
223 extern int lapicisr(int);
224 extern void lapicnmidisable(void);
225 extern void lapicnmienable(void);
226 extern void lapiconline(void);
227 extern void lapicspurious(Ureg*, void*);
228 extern void lapicstartap(Apic*, int);
229 extern void lapictimerset(uvlong);
230 
231 extern void mpinit(void);
232 extern int mpintrenable(Vctl*);
233 extern void mpshutdown(void);
234 
235 extern _MP_ *_mp_;
236