1/*
2 * Copyright (c) 2010, ETH Zurich. All rights reserved.
3 *
4 * This file is distributed under the terms in the attached LICENSE file.
5 * If you do not find this file, copies can be found by writing to:
6 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
7 */
8
9/*
10 * x2apic.dev
11 *
12 * DESCRIPTION: Local eXtended (2) APIC hardware description
13 * 
14 * Based on xapic.dev, the local xAPIC specification.  Numbers in
15 * comments in this file refer to the Intel 64 Architecture x2APIC
16 * Specification, Reference Number: 318148-004, March 2010.
17 */
18
19import xapic;
20
21device x2apic lsbfirst () "Local x2APIC" {
22
23    space msr(index) valuewise "Model-specific Registers";
24
25    // 2.4.1
26    register id ro msr(0x802) "Local APIC ID" type(uint32);
27    
28    // 2.5.1
29    register version ro msr(0x803) "Local APIC Version" {
30	ver         8 "version";
31	_           8;
32	max_lvt     8 "max LVT entry";
33	deoi_sup    1 "Directed EOI support";
34	_           7;
35    };
36
37
38    // 2.3.5.2
39    regtype priority "Various priorities" {
40	sub_class   4 "Priority subclass";
41	priority    4 "Priority";
42	_           24;
43    };
44    register tpr rw msr(0x808) "Task priority" type(priority);
45    register ppr ro msr(0x80A) "Processor priority" type(priority);
46
47    // 2.3.5.3
48    // XXX Must be zero!
49    register eoi rwc msr(0x80b) "End Of Interrupt" type(uint32);
50
51    // 2.4.2 
52    register ldr ro msr(0x80d) "Logical Destination" {
53	logical_id  16 "Logical ID";
54	cluster_id  16 "Cluster ID";
55    };
56
57    // 2.5.1
58    register svr rw msr(0x80f) "Spurious Interrupt Vector Register" {
59	vector      8 "Vector";
60	enable      1 "APIC Software Enable/Disable";
61	_	    3;
62	eoibd	    1 "EOI Broadcast Disable";
63	_	    19;
64    };
65    regarray isr ro msr(0x810) [8; 1] "Interrupt Status" type(uint32);
66    regarray tmr ro msr(0x818) [8; 1] "Trigger Mode" type(uint32);
67    regarray irr ro msr(0x820) [8; 1] "Interrupt Request" type(uint32);
68
69    // 2.3.5.4
70    register esr rwc msr(0x828) "Error Status" {
71	_	    4;
72	ripi	    1 "Redirectible IPI";
73	siv         1 "Send illegal vector";
74	riv         1 "Receive illegal vector";
75	ira         1 "Illegal register address";
76	_           24;
77    };
78
79    constants dst_shorthand "Destination shorthand" {
80	none    = 0b00 "No shorthand";
81	self    = 0b01 "Self";
82	all_inc = 0b10 "All including self";
83	all_exc = 0b11 "All excluding self";
84    };
85    
86    constants dst_mode "Destination mode" {
87	dst_phys	= 0b00 "Physical";
88	dst_log	= 0b01 "Logical";
89    };
90    
91    constants int_level "Interrupt level" {
92	lvl_clr	= 0b00 "Clear";
93	lvl_set	= 0b01 "Set";
94    };
95
96    // 2.3.5.1, 2.4.3
97    register icr rw msr(0x830) "Interrupt Command (lo)" {
98	vector      8 "Vector";
99	dlv_mode    3 type(vdm) "Delivery mode";
100	dst_mode    1 type(dst_mode) "Destination mode";
101	_           2;
102	level       1 type(int_level) "Level";
103	trig_mode   1 type(trigm) "Trigger mode";
104	_           2;
105	dst_short   2 type(dst_shorthand) "Destination shorthand";
106	_           12;
107	dest        32 "Destination field";
108    };
109    
110    constants timer_mode "Timer mode" {
111	one_shot	= 0;
112	periodic	= 1;
113    };
114    
115    constants int_mask "Interrupt mask" {
116	not_masked	= 0 "Not masked";
117	masked	= 1 "Masked";
118    };
119    
120    register lvt_timer rw msr(0x832) "LVT Timer" {
121	vector      8 "Vector";
122	_           4;
123	status      1 "Delivery status";
124	_           3;
125	mask        1 type(int_mask) "Masked";
126	mode        1 type(timer_mode) "Mode";
127	_           14;
128    };
129    
130    constants vdm "Vector delivery mode" { 
131	fixed   = 0b000 "Fixed";
132	lowest  = 0b001 "Lowest priority";
133	smi     = 0b010 "SMI";
134	nmi     = 0b100 "NMI";
135	init    = 0b101 "INIT";
136	startup = 0b110 "Start Up";
137	extint  = 0b111 "ExtINT";
138    };
139    
140    constants trigm "Trigger mode" {
141	edge	= 0 "Edge";
142	level	= 1 "Level";
143    };
144
145    regtype lvt_lint "LVT Int" {
146	vector      8 "Vector";
147	dlv_mode    4 type(xapic.vdm) "Delivery mode";
148	_           1;
149	status      1 "Delivery status";
150	pinpol      1 "Pin polarity";
151	rirr        1 "Remote IRR";
152	trig_mode   1 type(trigm) "Trigger mode";
153	mask        1 type(int_mask) "Mask";
154	_           14;
155    };
156
157    regtype lvt_mon "LVT monitor" {
158	vector      8 "Vector";
159	dlv_mode    4 type(vdm) "Delivery mode";
160	_           1;
161	status      1 "Delivery status";
162	_           3;
163	mask        1 type(int_mask) "Mask";
164	_           14;
165    };
166
167    register lvt_thermal rw msr(0x833) type (lvt_mon);
168    register lvt_perfmon rw msr(0x834) type (lvt_mon);
169    register lvt_lint0 rw msr(0x835) type(lvt_lint);
170    register lvt_lint1 rw msr(0x836) type(lvt_lint);
171
172    register lvt_err rw msr(0x837) { 
173	vector      8 "Vector";
174	_           4;
175	status      1 "Delivery status";
176	_           3;
177	mask        1 type(int_mask) "Mask";
178	_           15;
179    };
180    
181    register init_count rw msr(0x838) "Initial Count" type(uint32);
182    register cur_count rw msr(0x839) "Current Count" type(uint32) ;
183    
184    constants divide "Timer Divide values" {
185	by1         = 0b1011;
186	by2         = 0b0000;
187	by4         = 0b0001;
188	by8         = 0b0010;
189	by16        = 0b0011;
190	by32        = 0b1000;
191	by64        = 0b1001;
192	by128       = 0b1010;
193    };
194    register dcr rw msr(0x83e) "Divide Configuration" {
195	div_val     4 type(divide) "Timer divide value";
196	_           28;
197    };
198    
199    // 2.4.5
200    register sipi wo msr(0x83f) "Self IPI" {
201	vector	8 "Vector";
202	_	24;
203    };
204
205};
206