AquilaOS documentation
How it works, and its code
Toggle main menu visibility
Loading...
Searching...
No Matches
gdt.c
Go to the documentation of this file.
1
9
10
11
#include <
core/system.h
>
12
#include <
core/panic.h
>
13
#include <
core/assert.h
>
14
#include <
core/string.h
>
15
16
#include <
cpu/msr.h
>
17
#include <
sys/cpu.h
>
18
19
#include "
cpu.h
"
20
21
#define RW_DATA 0x2
22
#define XR_CODE 0xA
23
#define TSS_AVL 0x9
24
25
#define BASE 0
26
#define LIMIT -1
27
28
#define DPL0 0
29
#define DPL3 3
30
31
#if ARCH_BITS==32
32
#define L 0
33
#define D 1
34
#else
35
#define L 1
36
#define D 0
37
#endif
38
39
/* The segments every CPU has; its TSS and its own segment come after. */
40
static
const
struct
x86_gdt_entry
gdt_template
[
X86_GDT_TSS
] = {
41
/* the null segment */
42
{0},
43
44
/* the kernel's code segment */
45
{
LIMIT
,
BASE
,
BASE
,
XR_CODE
, 1,
DPL0
, 1,
LIMIT
, 0,
L
,
D
, 1,
BASE
},
46
47
/* the kernel's data segment */
48
{
LIMIT
,
BASE
,
BASE
,
RW_DATA
, 1,
DPL0
, 1,
LIMIT
, 0,
L
,
D
, 1,
BASE
},
49
50
/* user mode's code segment */
51
{
LIMIT
,
BASE
,
BASE
,
XR_CODE
, 1,
DPL3
, 1,
LIMIT
, 0,
L
,
D
, 1,
BASE
},
52
53
/* user mode's data segment */
54
{
LIMIT
,
BASE
,
BASE
,
RW_DATA
, 1,
DPL3
, 1,
LIMIT
, 0,
L
,
D
, 1,
BASE
},
55
};
56
57
#define MSR_GS_BASE 0xC0000101
58
#define MSR_KERNEL_GS_BASE 0xC0000102
59
62
static
void
segment_set
(
struct
x86_gdt_entry
*e,
uintptr_t
base,
size_t
limit)
63
{
64
e->
limit_lo
= limit & 0xFFFF;
65
e->
base_lo
= base & 0xFFFF;
66
e->
base_mid
= (base >> 16) & 0xFF;
67
e->
limit_hi
= (limit >> 16) & 0xF;
68
e->
base_hi
= (base >> 24) & 0xFF;
69
}
70
79
void
x86_gdt_setup
(
struct
cpu
*
cpu
,
uintptr_t
sp)
80
{
81
struct
arch_cpu
*arch = &
cpu
->
arch
;
82
struct
x86_tss
*tss = &arch->
tss
;
83
84
assert_sizeof
(
struct
x86_gdt_entry
, 8);
85
assert_sizeof
(
struct
x86_tss
, 104);
86
assert_alignof
(arch->
gdt
, 8);
87
assert_alignof
(tss, 8);
88
89
memset
(arch->
gdt
, 0,
sizeof
(arch->
gdt
));
90
memcpy
(arch->
gdt
,
gdt_template
,
sizeof
(
gdt_template
));
91
92
memset
(tss, 0,
sizeof
(*tss));
93
#if ARCH_BITS==32
94
tss->ss = 0x10;
95
#endif
96
tss->
sp
=
sp
;
97
98
/*
99
* The I/O map base (the upper half of the dword at offset 100) must
100
* point past the TSS's limit. Otherwise the TSS's own bytes are used
101
* as the I/O permission bitmap, and user mode could use random I/O
102
* ports.
103
*/
104
#if ARCH_BITS==32
105
tss->
_
[22] = (
uint32_t
)
sizeof
(*tss) << 16;
106
#else
107
tss->
__
[22] = (
uint32_t
)
sizeof
(*tss) << 16;
108
#endif
109
110
/* the TSS's segment */
111
struct
x86_gdt_entry
*e = &arch->
gdt
[
X86_GDT_TSS
];
112
segment_set
(e, (
uintptr_t
) tss,
sizeof
(*tss) - 1);
113
e->
type
=
TSS_AVL
;
114
e->
dpl
=
DPL3
;
115
e->
p
= 1;
116
117
#if ARCH_BITS==64
118
uint32_t
*base_high = (
uint32_t
*) &arch->
gdt
[
X86_GDT_TSS
+ 1];
119
*base_high = (
uintptr_t
) tss >> 32;
120
#else
121
/* the CPU's own segment: %gs:0 is cpu->self */
122
e = &arch->
gdt
[
X86_GDT_CPU
];
123
segment_set
(e, (
uintptr_t
)
cpu
,
sizeof
(*
cpu
) - 1);
124
e->
type
=
RW_DATA
;
125
e->
s
= 1;
126
e->
dpl
=
DPL0
;
127
e->
p
= 1;
128
e->
db
= 1;
129
#endif
130
131
cpu
->
self
=
cpu
;
132
133
x86_lgdt
(
sizeof
(arch->
gdt
) - 1, (
uintptr_t
) arch->
gdt
);
134
x86_ltr
((
X86_GDT_TSS
<< 3) |
DPL3
);
135
136
#if ARCH_BITS==32
137
asm
volatile
(
"movw %w0, %%gs"
::
"r"
(
X86_SEL_CPU
));
138
#else
139
/* the kernel's GS base; user mode's (none yet) is swapped in on the
140
* way out to user mode */
141
msr_write(
MSR_GS_BASE
, (
uintptr_t
)
cpu
);
142
msr_write(
MSR_KERNEL_GS_BASE
, 0);
143
#endif
144
}
145
152
void
x86_kernel_stack_set
(
uintptr_t
sp)
153
{
154
curcpu()->arch.tss.sp = sp;
155
}
cpu.h
x86_ltr
void x86_ltr(uintptr_t)
x86_lgdt
void x86_lgdt(uint16_t, uintptr_t)
X86_GDT_CPU
#define X86_GDT_CPU
Definition
cpu.h:115
X86_GDT_TSS
#define X86_GDT_TSS
Definition
cpu.h:114
X86_SEL_CPU
#define X86_SEL_CPU
Definition
cpu.h:118
assert.h
assert_alignof
#define assert_alignof(o, al)
Definition
assert.h:21
assert_sizeof
#define assert_sizeof(o, sz)
Definition
assert.h:15
segment_set
static void segment_set(struct x86_gdt_entry *e, uintptr_t base, size_t limit)
Sets the base and limit of a system or data segment descriptor, with byte granularity.
Definition
gdt.c:62
TSS_AVL
#define TSS_AVL
Definition
gdt.c:23
gdt_template
static const struct x86_gdt_entry gdt_template[X86_GDT_TSS]
Definition
gdt.c:40
x86_kernel_stack_set
void x86_kernel_stack_set(uintptr_t sp)
Sets the kernel stack that interrupts from user mode switch to, on the running CPU: the thread that i...
Definition
gdt.c:152
LIMIT
#define LIMIT
Definition
gdt.c:26
DPL0
#define DPL0
Definition
gdt.c:28
DPL3
#define DPL3
Definition
gdt.c:29
BASE
#define BASE
Definition
gdt.c:25
XR_CODE
#define XR_CODE
Definition
gdt.c:22
L
#define L
Definition
gdt.c:35
MSR_GS_BASE
#define MSR_GS_BASE
Definition
gdt.c:57
MSR_KERNEL_GS_BASE
#define MSR_KERNEL_GS_BASE
Definition
gdt.c:58
D
#define D
Definition
gdt.c:36
RW_DATA
#define RW_DATA
Definition
gdt.c:21
x86_gdt_setup
void x86_gdt_setup(struct cpu *cpu, uintptr_t sp)
Sets up and loads the running CPU's GDT and TSS, and points gs (or the GS base, on x86_64) at its str...
Definition
gdt.c:79
panic.h
system.h
cpu.h
memset
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition
libc.c:23
memcpy
void * memcpy(void *dst, const void *src, size_t n)
Copies n bytes; dst and src must not overlap.
Definition
libc.c:11
msr.h
uintptr_t
__SIZE_TYPE__ uintptr_t
Definition
stddef.h:12
uint32_t
unsigned int uint32_t
Definition
stddef.h:22
string.h
arch_cpu
A CPU's aarch64 state (struct cpu's arch).
Definition
cpu.h:51
arch_cpu::tss
struct x86_tss tss
Definition
cpu.h:127
arch_cpu::gdt
struct x86_gdt_entry gdt[X86_GDT_NR]
Definition
cpu.h:126
cpu
A processor, and what runs on it.
Definition
cpu.h:11
cpu::self
struct cpu * self
Definition
cpu.h:12
cpu::arch
struct arch_cpu arch
Definition
cpu.h:17
x86_gdt_entry
A segment descriptor, an entry of the GDT.
Definition
cpu.h:74
x86_gdt_entry::s
uint32_t s
Definition
cpu.h:80
x86_gdt_entry::base_lo
uint32_t base_lo
Definition
cpu.h:76
x86_gdt_entry::dpl
uint32_t dpl
Definition
cpu.h:81
x86_gdt_entry::limit_lo
uint32_t limit_lo
Definition
cpu.h:75
x86_gdt_entry::base_mid
uint32_t base_mid
Definition
cpu.h:78
x86_gdt_entry::type
uint32_t type
Definition
cpu.h:79
x86_gdt_entry::base_hi
uint32_t base_hi
Definition
cpu.h:89
x86_gdt_entry::p
uint32_t p
Definition
cpu.h:82
x86_gdt_entry::db
uint32_t db
Definition
cpu.h:87
x86_gdt_entry::limit_hi
uint32_t limit_hi
Definition
cpu.h:84
x86_tss
Definition
cpu.h:102
x86_tss::__
uint32_t __[23]
Definition
cpu.h:105
x86_tss::_
uint32_t _
Definition
cpu.h:103
x86_tss::sp
uint64_t sp
Definition
cpu.h:104
kernel
arch
i386
cpu
gdt.c
Generated by
1.18.0