Loading [MathJax]/extensions/tex2jax.js
CS350 COS
COS
All Data Structures Files Functions Variables Typedefs Macros
lapic.c File Reference
#include <stdbool.h>
#include <stdint.h>
#include <sys/kassert.h>
#include <sys/kdebug.h>
#include <machine/amd64.h>
#include <machine/amd64op.h>
#include <machine/pmap.h>
#include <machine/trap.h>
Include dependency graph for lapic.c:

Go to the source code of this file.

Macros

#define CPUID_FLAG_APIC   0x100
 
#define IA32_APIC_BASE_MSR   0x1B
 
#define IA32_APIC_BASE_MSR_BSP   0x100
 
#define IA32_APIC_BASE_MSR_ENABLE   0x800
 
#define LAPIC_ID   0x0020 /* CPU ID */
 
#define LAPIC_VERSION   0x0030 /* Version */
 
#define LAPIC_VERSION_LVTMASK   0x00FF0000
 
#define LAPIC_VERSION_LVTSHIFT   0x10
 
#define LAPIC_TPR   0x0080 /* Task Priority Register */
 
#define LAPIC_EOI   0x00B0 /* End of Interrupt */
 
#define LAPIC_SIV   0x00F0 /* Spurious Interrupt Vector */
 
#define LAPIC_SIV_ENABLE   0x100
 
#define LAPIC_ESR   0x0280 /* Error Status Register */
 
#define LAPIC_LVT_CMCI   0x02F0 /* LVT CMCI */
 
#define LAPIC_ICR_LO   0x0300 /* Interrupt Command Register */
 
#define LAPIC_ICR_HI   0x0310 /* Interrupt Command Register */
 
#define LAPIC_ICR_FIXED   0x0000 /* Delivery Mode */
 
#define LAPIC_ICR_NMI   0x0400
 
#define LAPIC_ICR_INIT   0x0500
 
#define LAPIC_ICR_STARTUP   0x0600
 
#define LAPIC_ICR_ASSERT   0x4000
 
#define LAPIC_ICR_TRIG   0x8000
 
#define LAPIC_ICR_SELF   0x00080000 /* Destination */
 
#define LAPIC_ICR_INCSELF   0x00080000
 
#define LAPIC_ICR_EXCSELF   0x000C0000
 
#define LAPIC_ICR_DELIVERY_PENDING   0x1000 /* Delivery Pending */
 
#define LAPIC_LVT_TIMER   0x0320 /* LVT Timer */
 
#define LAPIC_LVT_TIMER_ONESHOT   0x00000000
 
#define LAPIC_LVT_TIMER_PERIODIC   0x00020000
 
#define LAPIC_LVT_TIMER_TSCDEADLINE   0x00040000
 
#define LAPIC_LVT_THERMAL   0x0330 /* LVT Thermal Sensor */
 
#define LAPIC_LVT_PMCR   0x0340 /* LVT Performance Monitoring Counter */
 
#define LAPIC_LVT_LINT0   0x0350 /* LVT LINT0 */
 
#define LAPIC_LVT_LINT1   0x0360 /* LVT LINT1 */
 
#define LAPIC_LVT_ERROR   0x0370 /* LVT Error */
 
#define LAPIC_LVT_FLAG_MASKED   0x00010000 /* Masked */
 
#define LAPIC_LVT_FLAG_NMI   0x00000400 /* NMI */
 
#define LAPIC_LVT_FLAG_EXTINT   0x00000700 /* ExtINT */
 
#define LAPIC_TICR   0x0380 /* Timer Initial Count Register */
 
#define LAPIC_TCCR   0x0390 /* Timer Currnet Count Register */
 
#define LAPIC_TDCR   0x03E0 /* Time Divide Configuration Register */
 
#define LAPIC_TDCR_X1   0x000B /* Divide counts by 1 */
 

Functions

static uint32_tLAPIC_GetBase ()
 
uint32_t LAPIC_Read (uint16_t reg)
 
void LAPIC_Write (uint16_t reg, uint32_t val)
 
uint32_t LAPIC_CPU ()
 
void LAPIC_SendEOI ()
 
void LAPIC_Periodic (uint64_t rate)
 
void LAPIC_StartAP (uint8_t apicid, uint32_t addr)
 
int LAPIC_Broadcast (int vector)
 
int LAPIC_BroadcastNMI (int vector)
 
void LAPIC_Init ()
 
static void Debug_LAPIC (int argc, const char *argv[])
 
 REGISTER_DBGCMD (lapic, "LAPIC Status", Debug_LAPIC)
 

Variables

bool lapicInitialized = false
 

Macro Definition Documentation

◆ CPUID_FLAG_APIC

#define CPUID_FLAG_APIC   0x100

Definition at line 16 of file lapic.c.

◆ IA32_APIC_BASE_MSR

#define IA32_APIC_BASE_MSR   0x1B

Definition at line 18 of file lapic.c.

◆ IA32_APIC_BASE_MSR_BSP

#define IA32_APIC_BASE_MSR_BSP   0x100

Definition at line 19 of file lapic.c.

◆ IA32_APIC_BASE_MSR_ENABLE

#define IA32_APIC_BASE_MSR_ENABLE   0x800

Definition at line 20 of file lapic.c.

◆ LAPIC_EOI

#define LAPIC_EOI   0x00B0 /* End of Interrupt */

Definition at line 27 of file lapic.c.

◆ LAPIC_ESR

#define LAPIC_ESR   0x0280 /* Error Status Register */

Definition at line 31 of file lapic.c.

◆ LAPIC_ICR_ASSERT

#define LAPIC_ICR_ASSERT   0x4000

Definition at line 40 of file lapic.c.

◆ LAPIC_ICR_DELIVERY_PENDING

#define LAPIC_ICR_DELIVERY_PENDING   0x1000 /* Delivery Pending */

Definition at line 45 of file lapic.c.

◆ LAPIC_ICR_EXCSELF

#define LAPIC_ICR_EXCSELF   0x000C0000

Definition at line 44 of file lapic.c.

◆ LAPIC_ICR_FIXED

#define LAPIC_ICR_FIXED   0x0000 /* Delivery Mode */

Definition at line 36 of file lapic.c.

◆ LAPIC_ICR_HI

#define LAPIC_ICR_HI   0x0310 /* Interrupt Command Register */

Definition at line 35 of file lapic.c.

◆ LAPIC_ICR_INCSELF

#define LAPIC_ICR_INCSELF   0x00080000

Definition at line 43 of file lapic.c.

◆ LAPIC_ICR_INIT

#define LAPIC_ICR_INIT   0x0500

Definition at line 38 of file lapic.c.

◆ LAPIC_ICR_LO

#define LAPIC_ICR_LO   0x0300 /* Interrupt Command Register */

Definition at line 34 of file lapic.c.

◆ LAPIC_ICR_NMI

#define LAPIC_ICR_NMI   0x0400

Definition at line 37 of file lapic.c.

◆ LAPIC_ICR_SELF

#define LAPIC_ICR_SELF   0x00080000 /* Destination */

Definition at line 42 of file lapic.c.

◆ LAPIC_ICR_STARTUP

#define LAPIC_ICR_STARTUP   0x0600

Definition at line 39 of file lapic.c.

◆ LAPIC_ICR_TRIG

#define LAPIC_ICR_TRIG   0x8000

Definition at line 41 of file lapic.c.

◆ LAPIC_ID

#define LAPIC_ID   0x0020 /* CPU ID */

Definition at line 22 of file lapic.c.

◆ LAPIC_LVT_CMCI

#define LAPIC_LVT_CMCI   0x02F0 /* LVT CMCI */

Definition at line 32 of file lapic.c.

◆ LAPIC_LVT_ERROR

#define LAPIC_LVT_ERROR   0x0370 /* LVT Error */

Definition at line 55 of file lapic.c.

◆ LAPIC_LVT_FLAG_EXTINT

#define LAPIC_LVT_FLAG_EXTINT   0x00000700 /* ExtINT */

Definition at line 58 of file lapic.c.

◆ LAPIC_LVT_FLAG_MASKED

#define LAPIC_LVT_FLAG_MASKED   0x00010000 /* Masked */

Definition at line 56 of file lapic.c.

◆ LAPIC_LVT_FLAG_NMI

#define LAPIC_LVT_FLAG_NMI   0x00000400 /* NMI */

Definition at line 57 of file lapic.c.

◆ LAPIC_LVT_LINT0

#define LAPIC_LVT_LINT0   0x0350 /* LVT LINT0 */

Definition at line 53 of file lapic.c.

◆ LAPIC_LVT_LINT1

#define LAPIC_LVT_LINT1   0x0360 /* LVT LINT1 */

Definition at line 54 of file lapic.c.

◆ LAPIC_LVT_PMCR

#define LAPIC_LVT_PMCR   0x0340 /* LVT Performance Monitoring Counter */

Definition at line 52 of file lapic.c.

◆ LAPIC_LVT_THERMAL

#define LAPIC_LVT_THERMAL   0x0330 /* LVT Thermal Sensor */

Definition at line 51 of file lapic.c.

◆ LAPIC_LVT_TIMER

#define LAPIC_LVT_TIMER   0x0320 /* LVT Timer */

Definition at line 47 of file lapic.c.

◆ LAPIC_LVT_TIMER_ONESHOT

#define LAPIC_LVT_TIMER_ONESHOT   0x00000000

Definition at line 48 of file lapic.c.

◆ LAPIC_LVT_TIMER_PERIODIC

#define LAPIC_LVT_TIMER_PERIODIC   0x00020000

Definition at line 49 of file lapic.c.

◆ LAPIC_LVT_TIMER_TSCDEADLINE

#define LAPIC_LVT_TIMER_TSCDEADLINE   0x00040000

Definition at line 50 of file lapic.c.

◆ LAPIC_SIV

#define LAPIC_SIV   0x00F0 /* Spurious Interrupt Vector */

Definition at line 28 of file lapic.c.

◆ LAPIC_SIV_ENABLE

#define LAPIC_SIV_ENABLE   0x100

Definition at line 29 of file lapic.c.

◆ LAPIC_TCCR

#define LAPIC_TCCR   0x0390 /* Timer Currnet Count Register */

Definition at line 61 of file lapic.c.

◆ LAPIC_TDCR

#define LAPIC_TDCR   0x03E0 /* Time Divide Configuration Register */

Definition at line 62 of file lapic.c.

◆ LAPIC_TDCR_X1

#define LAPIC_TDCR_X1   0x000B /* Divide counts by 1 */

Definition at line 63 of file lapic.c.

◆ LAPIC_TICR

#define LAPIC_TICR   0x0380 /* Timer Initial Count Register */

Definition at line 60 of file lapic.c.

◆ LAPIC_TPR

#define LAPIC_TPR   0x0080 /* Task Priority Register */

Definition at line 26 of file lapic.c.

◆ LAPIC_VERSION

#define LAPIC_VERSION   0x0030 /* Version */

Definition at line 23 of file lapic.c.

◆ LAPIC_VERSION_LVTMASK

#define LAPIC_VERSION_LVTMASK   0x00FF0000

Definition at line 24 of file lapic.c.

◆ LAPIC_VERSION_LVTSHIFT

#define LAPIC_VERSION_LVTSHIFT   0x10

Definition at line 25 of file lapic.c.

Function Documentation

◆ Debug_LAPIC()

static void Debug_LAPIC ( int  argc,
const char *  argv[] 
)
static

Definition at line 259 of file lapic.c.

260{
263
264 kprintf("LAPIC %d\n", LAPIC_CPU());
265 kprintf("VERSION: %08x\n", LAPIC_Read(LAPIC_VERSION));
266 kprintf("ESR: %08x\n", LAPIC_Read(LAPIC_ESR));
267 kprintf("ICRLO: %08x\n", LAPIC_Read(LAPIC_ICR_LO));
268 kprintf("ICRHI: %08x\n", LAPIC_Read(LAPIC_ICR_HI));
269 kprintf("SIV: %08x\n", LAPIC_Read(LAPIC_SIV));
270 kprintf("ERROR: %08x\n", LAPIC_Read(LAPIC_LVT_ERROR));
271 if (lvts >= 5) {
272 kprintf("THERMAL: %08x\n", LAPIC_Read(LAPIC_LVT_THERMAL));
273 }
274 kprintf("LINT0: %08x\n", LAPIC_Read(LAPIC_LVT_LINT0));
275 kprintf("LINT1: %08x\n", LAPIC_Read(LAPIC_LVT_LINT1));
276 if (lvts >= 4) {
277 kprintf("PMCR: %08x\n", LAPIC_Read(LAPIC_LVT_PMCR));
278 }
279 if (lvts >= 6) {
280 kprintf("CMCI: %08x\n", LAPIC_Read(LAPIC_LVT_CMCI));
281 }
282}
int kprintf(const char *fmt,...)
Definition: printf.c:210
#define LAPIC_LVT_LINT1
Definition: lapic.c:54
#define LAPIC_LVT_THERMAL
Definition: lapic.c:51
#define LAPIC_VERSION_LVTMASK
Definition: lapic.c:24
#define LAPIC_ICR_LO
Definition: lapic.c:34
#define LAPIC_LVT_PMCR
Definition: lapic.c:52
#define LAPIC_VERSION_LVTSHIFT
Definition: lapic.c:25
#define LAPIC_VERSION
Definition: lapic.c:23
uint32_t LAPIC_Read(uint16_t reg)
Definition: lapic.c:76
#define LAPIC_SIV
Definition: lapic.c:28
#define LAPIC_LVT_ERROR
Definition: lapic.c:55
#define LAPIC_ESR
Definition: lapic.c:31
#define LAPIC_LVT_CMCI
Definition: lapic.c:32
uint32_t LAPIC_CPU()
Definition: lapic.c:93
#define LAPIC_LVT_LINT0
Definition: lapic.c:53
#define LAPIC_ICR_HI
Definition: lapic.c:35
unsigned int uint32_t
Definition: types.h:12
Here is the call graph for this function:

◆ LAPIC_Broadcast()

int LAPIC_Broadcast ( int  vector)

Definition at line 143 of file lapic.c.

144{
145 int i = 0;
147
149 pause();
150
151 if (i > 1000000) {
152 kprintf("IPI not delivered?\n");
153 return -1;
154 }
155 }
156
157 return 0;
158}
static INLINE void pause()
Definition: amd64op.h:24
#define LAPIC_ICR_EXCSELF
Definition: lapic.c:44
#define LAPIC_ICR_DELIVERY_PENDING
Definition: lapic.c:45
void LAPIC_Write(uint16_t reg, uint32_t val)
Definition: lapic.c:84
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_BroadcastNMI()

int LAPIC_BroadcastNMI ( int  vector)

Definition at line 161 of file lapic.c.

162{
163 int i = 0;
165
167 pause();
168
169 if (i > 1000000) {
170 kprintf("IPI not delivered?\n");
171 return -1;
172 }
173 }
174
175 return 0;
176}
#define LAPIC_ICR_NMI
Definition: lapic.c:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_CPU()

uint32_t LAPIC_CPU ( )

Definition at line 93 of file lapic.c.

94{
96 return LAPIC_Read(LAPIC_ID) >> 24;
97 else
98 return 0;
99}
bool lapicInitialized
Definition: lapic.c:65
#define LAPIC_ID
Definition: lapic.c:22
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_GetBase()

static uint32_t * LAPIC_GetBase ( )
static

Definition at line 68 of file lapic.c.

69{
70 uint64_t base = rdmsr(IA32_APIC_BASE_MSR) & 0xFFFFFFFFFFFFF000ULL;
71
72 return (uint32_t *)DMPA2VA(base);
73}
static INLINE uint64_t rdmsr(uint32_t addr)
Definition: amd64op.h:114
#define IA32_APIC_BASE_MSR
Definition: lapic.c:18
#define DMPA2VA(pa)
Definition: pmap.h:48
static uint16_t base
Definition: sercons.c:37
unsigned long uint64_t
Definition: types.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_Init()

void LAPIC_Init ( )

Definition at line 179 of file lapic.c.

180{
181 uint32_t version;
182 uint32_t lvts;
183 uint32_t edx;
185
186 cpuid(1, NULL, NULL, NULL, &edx);
187 if ((edx & CPUID_FLAG_APIC) == 0)
188 Panic("APIC is required!\n");
189
190 // Disable ATPIC
191 if (LAPIC_CPU() == 0) {
192 outb(0xA1, 0xFF);
193 outb(0x21, 0xFF);
194 }
195
196 // Enable LAPIC
199
200 // Convert to Direct Map Address
201 base = DMPA2VA(base);
202
203 lapicInitialized = true;
204
205 kprintf("LAPIC: CPU %d found at 0x%016llx\n", LAPIC_CPU(), base);
206
207 version = LAPIC_Read(LAPIC_VERSION);
208 lvts = (version & LAPIC_VERSION_LVTMASK) >> LAPIC_VERSION_LVTSHIFT;
209
210 // Enable interrupts
212
213 // Error Interrupt
215
216 // Setup LINT0/1
217 if (LAPIC_CPU() == 0) {
220 } else {
223 }
224
225 // Performance Counter Interrupt
226 if (lvts >= 4) {
228 }
229
230 // Thermal Interrupt
231 if (lvts >= 5) {
233 }
234
235 // Machine Check Interrupt
236 if (lvts >= 6) {
238 }
239
240 LAPIC_Periodic(10000000); // XXX: 100 Hz (changes must update trap.c as well)
241
242 // Clear any remaining errors
245
249 {
250 // XXX: Timeout
251 }
252
254
256}
static INLINE void outb(uint16_t port, uint8_t data)
Definition: amd64op.h:431
static INLINE void wrmsr(uint32_t addr, uint64_t val)
Definition: amd64op.h:104
static INLINE void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx)
Definition: amd64op.h:85
#define LAPIC_SIV_ENABLE
Definition: lapic.c:29
#define LAPIC_LVT_FLAG_MASKED
Definition: lapic.c:56
#define CPUID_FLAG_APIC
Definition: lapic.c:16
void LAPIC_Periodic(uint64_t rate)
Definition: lapic.c:108
#define LAPIC_TPR
Definition: lapic.c:26
#define LAPIC_LVT_FLAG_NMI
Definition: lapic.c:57
#define LAPIC_LVT_FLAG_EXTINT
Definition: lapic.c:58
#define LAPIC_ICR_TRIG
Definition: lapic.c:41
void LAPIC_SendEOI()
Definition: lapic.c:102
#define IA32_APIC_BASE_MSR_ENABLE
Definition: lapic.c:20
#define LAPIC_ICR_INCSELF
Definition: lapic.c:43
#define LAPIC_ICR_INIT
Definition: lapic.c:38
#define NULL
Definition: stddef.h:6
#define T_IRQ_ERROR
Definition: trap.h:39
#define T_IRQ_THERMAL
Definition: trap.h:40
#define T_IRQ_SPURIOUS
Definition: trap.h:38
void Panic(const char *str)
Definition: vgacons.c:164
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_Periodic()

void LAPIC_Periodic ( uint64_t  rate)

Definition at line 108 of file lapic.c.

109{
112 LAPIC_Write(LAPIC_TICR, rate);
113}
#define LAPIC_TDCR_X1
Definition: lapic.c:63
#define LAPIC_TDCR
Definition: lapic.c:62
#define LAPIC_LVT_TIMER
Definition: lapic.c:47
#define LAPIC_LVT_TIMER_PERIODIC
Definition: lapic.c:49
#define LAPIC_TICR
Definition: lapic.c:60
#define T_IRQ_TIMER
Definition: trap.h:32
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_Read()

uint32_t LAPIC_Read ( uint16_t  reg)

Definition at line 76 of file lapic.c.

77{
78 uint32_t volatile *lapic = (uint32_t volatile *) LAPIC_GetBase();
79
80 return lapic[reg >> 2];
81}
static uint32_t * LAPIC_GetBase()
Definition: lapic.c:68
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_SendEOI()

void LAPIC_SendEOI ( )

Definition at line 102 of file lapic.c.

103{
105}
#define LAPIC_EOI
Definition: lapic.c:27
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_StartAP()

void LAPIC_StartAP ( uint8_t  apicid,
uint32_t  addr 
)

Definition at line 116 of file lapic.c.

117{
118 // Setup CMOS stuff
119 outb(0x70, 0x0F);
120 outb(0x71, 0x0A);
121 uint16_t *cmosStartup = (uint16_t *)DMPA2VA(0x467);
122 cmosStartup[0] = 0;
123 cmosStartup[1] = addr >> 4;
124
125 // Send INIT
126 LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
128 // XXX: Delay
129 LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
131 // XXX: Delay
132
133 // Send STARTUP
134 LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
136 // XXX: Delay
137 LAPIC_Write(LAPIC_ICR_HI, apicid << 24);
139 // XXX: Delay
140}
#define LAPIC_ICR_STARTUP
Definition: lapic.c:39
#define LAPIC_ICR_ASSERT
Definition: lapic.c:40
uint64_t addr
Definition: multiboot.h:1
unsigned short uint16_t
Definition: types.h:11
Here is the call graph for this function:
Here is the caller graph for this function:

◆ LAPIC_Write()

void LAPIC_Write ( uint16_t  reg,
uint32_t  val 
)

Definition at line 84 of file lapic.c.

85{
86 uint32_t volatile *lapic = (uint32_t volatile *)LAPIC_GetBase();
87
88 lapic[reg >> 2] = val;
89 lapic[LAPIC_ID >> 2];
90}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ REGISTER_DBGCMD()

REGISTER_DBGCMD ( lapic  ,
"LAPIC Status"  ,
Debug_LAPIC   
)

Variable Documentation

◆ lapicInitialized

bool lapicInitialized = false

Definition at line 65 of file lapic.c.