-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathapic.c
74 lines (63 loc) · 1.47 KB
/
apic.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
* apic.c
*
* Created on: 18.02.2015
* Author: pascal
*/
#include "apic.h"
#include "cpu.h"
#include "memory.h"
#include "vmm.h"
#include "pmm.h"
#define APIC_BASE_MSR 0x1B
#define APIC_REG_SPIV 0xF0
#define APIC_REG_ICR_LOW 0x300
#define APIC_REG_ICR_HIGH 0x310
#define APIC_REG_DIV_CONFIG 0x3E0
#define APIC_REG_LVT_TIMER 0x320
#define APIC_REG_LVT_THERM 0x330
#define APIC_REG_LVT_PERFMON 0x340
#define APIC_REG_LVT_LINT0 0x350
#define APIC_REG_LVT_LINT1 0x360
#define APIC_REG_LVT_ERROR 0x370
typedef struct{
paddr_t physBase;
void *virtBase;
}apic_info_t;
static apic_info_t apic_info;
bool apic_available()
{
return (cpu_cpuid(0x00000001).edx >> 9) & 1;
}
void apic_Init()
{
//Basisaddresse auslesen
apic_info.physBase = cpu_MSRread(APIC_BASE_MSR);
//Speicherbereich mappen
apic_info.virtBase = vmm_Map(&kernel_context, NULL, apic_info.physBase, 1, VMM_FLAGS_GLOBAL | VMM_FLAGS_NX | VMM_FLAGS_WRITE | VMM_FLAGS_NO_CACHE);
//APIC aktivieren
apic_Write(APIC_REG_SPIV, 1 << 8);
}
/*
* Ein APIC-Register auslesen
*
* Parameter: offset = Offset der Speicherstelle
*
* Rückgabe: Wert der Speicherstelle
*/
uint32_t apic_Read(uintptr_t offset)
{
uint32_t *ptr = apic_info.virtBase + offset;
return *ptr;
}
/*
* In ein APIC-Register schreiben
*
* Parameter: offset = Offset der Speicherstelle
* value = Wert der geschrieben werden soll
*/
void apic_Write(uintptr_t offset, uint32_t value)
{
uint32_t *ptr = apic_info.virtBase + offset;
*ptr = value;
}