1/*
2 * Copyright (c) 2007, 2008, 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 * xapic.dev
11 *
12 * DESCRIPTION: Local eXtended APIC hardware description
13 *
14 * Numbers in comments refer to the Intel Software Development Manual
15 * volume 3, October 2007.
16 */
17
18
19device xapic lsbfirst ( addr base ) "Local APIC" {
20
21  // 8.4.6
22  register id rw addr(base, 0x0020) "Local APIC ID" {
23    _   24;
24    id  8 "apic id";
25  };
26  /*
27   * the xeon phi has a slighly different register layout than normal xapic
28   */
29  register id_xeon_phi rw also addr(base, 0x0020) "Local APIC ID (Xeon Phi)" {
30    _   23;
31    id  9 "apic id";
32  };
33
34  // 8.4.8
35  register version ro addr(base, 0x0030) "Local APIC Version" {
36    ver         8 "version";
37    _           8;
38    max_lvt     8 "max LVT entry";
39    _           8;
40  };
41
42  // 8.5.1
43  constants timer_mode "Timer mode" {
44    one_shot     = 0;
45    periodic     = 1;
46    tsc_deadline = 2;
47  };
48
49  constants int_mask "Interrupt mask" {
50    not_masked	= 0 "Not masked";
51    masked	= 1 "Masked";
52  };
53
54  register lvt_timer rw addr(base, 0x0320) "LVT Timer" {
55    vector      8 "Vector";
56    _           4;
57    status      1 "Delivery status";
58    _           3;
59    mask        1 type(int_mask) "Masked";
60    mode        2 type(timer_mode) "Mode";
61    _           13;
62  };
63
64  constants vdm "Vector delivery mode" {
65    fixed   = 0b000 "Fixed";
66    lowest  = 0b001 "Lowest priority";
67    smi     = 0b010 "SMI";
68    nmi     = 0b100 "NMI";
69    init    = 0b101 "INIT";
70    startup = 0b110 "Start Up";
71    extint  = 0b111 "ExtINT";
72  };
73
74  constants trigm "Trigger mode" {
75    edge	= 0 "Edge";
76    level	= 1 "Level";
77  };
78
79  regtype lvt_lint "LVT Int" {
80    vector      8 "Vector";
81    dlv_mode    4 type(vdm) "Delivery mode";
82    _           1;
83    status      1 "Delivery status";
84    pinpol      1 "Pin polarity";
85    rirr        1 "Remote IRR";
86    trig_mode   1 type(trigm) "Trigger mode";
87    mask        1 type(int_mask) "Mask";
88    _           14;
89  };
90
91  register lvt_lint0 rw addr(base, 0x0350) type (lvt_lint);
92  register lvt_lint1 rw addr(base, 0x0360) type (lvt_lint);
93
94  register lvt_err rw addr(base, 0x0370) {
95    vector      8 "Vector";
96    _           4;
97    status      1 "Delivery status";
98    _           3;
99    mask        1 type(int_mask) "Mask";
100    _           15;
101  };
102
103  regtype lvt_mon "LVT monitor" {
104    vector      8 "Vector";
105    msgType     3;
106    _           1;
107    status      1 "Delivery status";
108    _           3;
109    mask        1 type(int_mask) "Masked";
110    _           15;
111  };
112
113  register lvt_perf_cnt rw addr(base, 0x0340) type (lvt_mon);
114  register lvt_thermal rw addr(base, 0x0330) type (lvt_mon);
115
116  // 8.5.3
117  register esr rw addr(base, 0x0280) "Error Status" {
118    sce         1 "Send checksum error";
119    rce         1 "Receive checksum error";
120    sae         1 "Send accept error";
121    rae         1 "Receive accept error";
122    _           1;
123    siv         1 "Send illegal vector";
124    riv         1 "Receive illegal vector";
125    ira         1 "Illegal register address";
126    _           24;
127  };
128
129  // 8.5.4
130  constants divide "Timer Divide values" {
131    by1         = 0b1011;
132    by2         = 0b0000;
133    by4         = 0b0001;
134    by8         = 0b0010;
135    by16        = 0b0011;
136    by32        = 0b1000;
137    by64        = 0b1001;
138    by128       = 0b1010;
139  };
140  register dcr rw addr(base, 0x03e0) "Divide Configuration" {
141    div_val     4 "Timer divide value";
142    _           28;
143  };
144  register init_count rw addr(base, 0x0380) "Initial Count" type(uint32);
145  register cur_count rw addr(base, 0x0390) "Current Count" type(uint32) ;
146
147  // 8.6.1
148  constants dst_shorthand "Destination shorthand" {
149    none    = 0b00 "No shorthand";
150    self    = 0b01 "Self";
151    all_inc = 0b10 "All including self";
152    all_exc = 0b11 "All excluding self";
153  };
154
155  constants dst_mode "Destination mode" {
156    dst_phys	= 0b00 "Physical";
157    dst_log	= 0b01 "Logical";
158  };
159
160  constants int_level "Interrupt level" {
161    lvl_clr	= 0b00 "Clear";
162    lvl_set	= 0b01 "Set";
163  };
164
165  register icr_lo rw addr(base, 0x0300) "Interrupt Command (lo)" {
166    vector      8 "Vector";
167    dlv_mode    3 type(vdm) "Delivery mode";
168    dst_mode    1 type(dst_mode) "Destination mode";
169    dlv_stat    1 ro "Delivery status";
170    _           1;
171    level       1 type(int_level) "Level";
172    trig_mode   1 type(trigm) "Trigger mode";
173    _           2;
174    dst_short   2 type(dst_shorthand) "Destination shorthand";
175    _           12;
176  };
177  register icr_hi rw addr(base, 0x0310) "Interrupt Commmand (hi)" {
178    _           24;
179    dest        8 "Destination field";
180  };
181
182  /*
183   * the xeon phi has a slightly different register layout than normal apic
184   */
185  register icr_hi_xeon_phi rw also addr(base, 0x0310) "Interrupt Commmand (hi)" {
186    _           16;
187    dest        16 "Destination field";
188  };
189
190  // 8.6.2
191  register ldr rw addr(base, 0x00d0) "Logical Destination" {
192    _           24;
193    log_id      8 "Logical APIC ID";
194  };
195
196  register ldr_xeon_phi rw also  addr(base, 0x00d0) "Logical Destination" {
197    _           16;
198    log_id      16 "Logical APIC ID";
199  };
200  constants model_type "Destination model type" {
201    flat        = 0b1111;
202    cluster     = 0b0000;
203  };
204  register dfr rw addr(base, 0x00e0) "Destination Format" {
205    _           28 mb1;
206    model       4 type(model_type) "Model";
207  };
208  regtype priority "Various priorities" {
209    sub_class   4 "Priority subclass";
210    priority    4 "Priority";
211    _           24;
212  };
213  register apr ro addr(base, 0x0090) "Arbitration priority" type(priority);
214
215  // 8.8.3
216  register tpr rw addr(base, 0x0080) "Task priority" type(priority);
217  register ppr ro addr(base, 0x00A0) "Processor priority" type(priority);
218
219  // 8.8.4
220  regarray isr ro addr(base, 0x0100) [8; 0x10] "ISR" type(uint32);
221  regarray tmr ro addr(base, 0x0180) [8; 0x10] "TMR" type(uint32);
222  regarray irr ro addr(base, 0x0200) [8; 0x10] "IRR" type(uint32);
223
224  // 8.8.5
225  register eoi wo addr(base, 0x00b0) "End Of Interrupt" type(uint32);
226
227  // 8.9
228  register svr rw addr(base, 0x00f0) "Spurious Interrupt Vector Register" {
229    vector      8 "Vector";
230    enable      1 "APIC Software Enable/Disable";
231    focus       1 "Focus Processor Checking";
232    _           22;
233  };
234
235  /*
236   * AMD extensions: see AMD64 Architecture Programmer's Manual,
237   * vol. 2 rev 3.14 (September 2007).
238   */
239
240  // 16.7.1
241  register eafr ro addr(base, 0x0400) "Extended APIC feature" {
242    inc		1 "Interrupt enable register capable";
243    snic	1 "Specific EOI capable";
244    xaidc	1 "Extended APIC ID capability";
245    _		13 mbz;
246    xlc		8 "Extended LVT count";
247    _		8 mbz;
248  };
249
250  // 16.3.5
251  register eacr addr(base, 0x0410) "Extended APIC control" {
252    iern	1 "Enable interrupt enable registers";
253    sn		1 "Enable SEOI generation";
254    xaidn	1 "Extended APIC ID enable";
255    _		29;
256  };
257
258  // 16.7.2
259  register seoi wo addr(base, 0x0420) "Specific end-of-interrupt" {
260    vector	8 "Vector";
261    _		24 mbz;
262  };
263
264  // 16.7.3
265  regarray ier ro addr(base, 0x0480) [8; 0x10] "IER" type(uint32);
266
267};
268