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