blob: 350edac1ab29c5b0e441764e488a0f86f9d3956f (
plain)
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
|
#include <cstdint>
#pragma once
#include <generic/mm/paging.hpp>
#include <drivers/tsc.hpp>
#include <drivers/hpet.hpp>
#include <generic/time.hpp>
#include <etc/logging.hpp>
#include <etc/assembly.hpp>
#include <etc/etc.hpp>
extern "C" void setwp();
namespace arch {
namespace x86_64 {
namespace cpu {
class lapic {
static inline std::uint64_t base() {
return (std::uint64_t)Other::toVirt(__rdmsr(0x1B) & 0xFFFFF000);
}
static inline std::uint32_t read(std::uint32_t reg) {
return *(volatile std::uint32_t*)(base() + reg);
}
static inline void write(std::uint32_t reg,std::uint32_t value) {
*(volatile std::uint32_t*)(base() + reg) = value;
}
public:
static inline std::uint32_t id() {
return read(0x20) >> 24;
}
static inline void eoi() {
write(0xB0,0);
}
static inline void tick(std::uint64_t tick) {
write(0x380,tick);
}
static inline std::uint64_t init(std::uint32_t us) {
__wrmsr(0x1B,__rdmsr(0x1B));
memory::paging::kernelmap(0,__rdmsr(0x1B) & 0xFFFFF000);
write(0xf0,0xff | 0x100);
write(0x3e0,1);
write(0x320,32 | (1 << 16));
write(0x380,0xFFFFFFFF);
time::sleep(us);
std::uint64_t ticks = 0xFFFFFFFF - read(0x390);
write(0x320, 32 | (1 << 17));
write(0x3e0,1);
write(0x380,0);
return ticks;
}
};
};
};
};
|