The Pedigree Project 0.1
arm64/state.h
1#ifndef KERNEL_PROCESSOR_ARM64_STATE_H
2#define KERNEL_PROCESSOR_ARM64_STATE_H
3
4#include "pedigree/kernel/compiler.h"
5#include "pedigree/kernel/processor/types.h"
6
8
9// The first 296 bytes are also the exception vector's saved register image.
11 public:
12 uintptr_t getStackPointer() const {
13 return sp;
14 }
15 void setStackPointer(uintptr_t value) {
16 sp = value;
17 }
18 uintptr_t getInstructionPointer() const {
19 return pc;
20 }
21 void setInstructionPointer(uintptr_t value) {
22 pc = value;
23 }
24 uintptr_t getBasePointer() const {
25 return x[29];
26 }
27 void setBasePointer(uintptr_t value) {
28 x[29] = value;
29 }
30
31 size_t getRegisterCount() const {
32 return 34;
33 }
34 processor_register_t getRegister(size_t index) const;
35 void setRegister(size_t index, uintptr_t value);
36 const char* getRegisterName(size_t index) const;
37 size_t getRegisterSize(size_t) const {
38 return sizeof(uint64_t);
39 }
40
41 bool kernelMode() const {
42 return (pstate & 0xf) != 0;
43 }
44 size_t getInterruptNumber() const {
45 return vector;
46 }
47 uintptr_t getErrorCode() const {
48 return esr;
49 }
50 uint64_t getFlags() const {
51 return pstate;
52 }
53 void setFlags(uint64_t value) {
54 pstate = value;
55 }
56
57 static Arm64InterruptState* construct(Arm64ProcessorState& state, bool userMode);
58
59 uint64_t x[31];
60 uint64_t sp;
61 uint64_t pc;
62 uint64_t pstate;
63 uint64_t esr;
64 uint64_t far;
65 uint64_t vector;
66};
67
69 public:
70 // SVC #0 is Linux; SVC #1 carries Pedigree's packed service and number.
71 size_t getSyscallService() const {
72 return (esr & 0xffff) ? (x[8] >> 16) & 0xffff : 0;
73 }
74 size_t getSyscallNumber() const {
75 return (esr & 0xffff) ? x[8] & 0xffff : x[8];
76 }
77 uintptr_t getSyscallParameter(size_t n) const {
78 return n < 6 ? x[n] : (n < 12 ? x[n - 6] : 0);
79 }
80 void setSyscallReturnValue(uintptr_t value) {
81 x[0] = value;
82 }
83 void setSyscallErrno(uintptr_t value) {
84 x[1] = value;
85 }
86};
87
89 public:
90 Arm64ProcessorState() : x{}, sp(0), pc(0), pstate(0) {}
92 *this = state;
93 }
95 *this = state;
96 }
97
98 Arm64ProcessorState& operator=(const Arm64InterruptState& state) {
99 for (size_t i = 0; i < 31; ++i) {
100 x[i] = state.x[i];
101 }
102 sp = state.sp;
103 pc = state.pc;
104 pstate = state.pstate;
105 return *this;
106 }
107
108 uintptr_t getStackPointer() const {
109 return sp;
110 }
111 void setStackPointer(uintptr_t value) {
112 sp = value;
113 }
114 uintptr_t getInstructionPointer() const {
115 return pc;
116 }
117 void setInstructionPointer(uintptr_t value) {
118 pc = value;
119 }
120 uintptr_t getBasePointer() const {
121 return x[29];
122 }
123 void setBasePointer(uintptr_t value) {
124 x[29] = value;
125 }
126
127 uint64_t x[31];
128 uint64_t sp;
129 uint64_t pc;
130 uint64_t pstate;
131};
132
134 public:
135 uintptr_t getInstructionPointer() const {
136 return pc;
137 }
138
139 uint64_t x19ToX30[12];
140 uint64_t sp;
141 uint64_t pc;
142 uint64_t fpcr;
143 uint64_t fpsr;
144 alignas(16) uint8_t q[32][16];
145};
146
147static_assert(sizeof(Arm64InterruptState) == 296);
148static_assert(__builtin_offsetof(Arm64InterruptState, sp) == 248);
149static_assert(__builtin_offsetof(Arm64InterruptState, pc) == 256);
150static_assert(__builtin_offsetof(Arm64InterruptState, pstate) == 264);
151static_assert(__builtin_offsetof(Arm64InterruptState, esr) == 272);
152static_assert(__builtin_offsetof(Arm64InterruptState, far) == 280);
153static_assert(__builtin_offsetof(Arm64InterruptState, vector) == 288);
154static_assert(__builtin_offsetof(Arm64SchedulerState, fpcr) == 112);
155static_assert(__builtin_offsetof(Arm64SchedulerState, fpsr) == 120);
156static_assert(__builtin_offsetof(Arm64SchedulerState, q) == 128);
157
158#endif