MOS Source Code
Loading...
Searching...
No Matches
descriptors.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4
6#include <mos/syslog/printk.h>
8#include <mos_string.h>
9
10typeof(x86_cpu_descriptor) x86_cpu_descriptor = { 0 };
11
17
25
26typedef enum
27{
31
32static gdt_entry_t *gdt_set_entry(gdt_entry_t *entry, ptr_t base, u32 limit, gdt_entry_type_t entry_type, gdt_ring_t dpl, gdt_gran_t gran)
33{
34 entry->base_low = MASK_BITS(base, 24);
35 entry->base_high = MASK_BITS((base >> 24), 8);
36 entry->base_veryhigh = base >> 32;
37 entry->long_mode_code = entry_type == GDT_ENTRY_CODE;
38 entry->pm32_segment = !entry->long_mode_code; // it's one or the other
39
40 entry->limit_low = MASK_BITS(limit, 16);
41 entry->limit_high = MASK_BITS((limit >> 16), 4);
42 entry->present = 1;
43 entry->available = 1;
44 entry->read_write = true;
45 entry->code_data_segment = true;
46 entry->dpl = dpl;
47 entry->executable = (entry_type == GDT_ENTRY_CODE);
48 entry->granularity = gran;
49 entry->accessed = false; // "Best left clear (0),"
50
51 // ! This has to be false forever, for:
52 // * 1) allow system calls to be executed in ring 0,
53 // * otherwise, it means this segment "can" be executed by all rings outer than `dpl`
54 // * 2) always 0 for a TSS segment.
55 entry->conforming_expand_down = false;
56 return entry;
57}
58
60{
61 x86_cpu_descriptor_t *this_cpu_desc = per_cpu(x86_cpu_descriptor);
62 memzero(this_cpu_desc, sizeof(x86_cpu_descriptor_t));
63
64 // {Kernel,User}{Code,Data} Segments
65 // We are using a flat memory model, so the base is 0 and the limit is all the way up to the end of the address space.
66 gdt_set_entry(&this_cpu_desc->gdt[1], 0x00000000, 0xFFFFFFFF, GDT_ENTRY_CODE, GDT_RING_KERNEL, GDT_GRAN_PAGE);
67 gdt_set_entry(&this_cpu_desc->gdt[2], 0x00000000, 0xFFFFFFFF, GDT_ENTRY_DATA, GDT_RING_KERNEL, GDT_GRAN_PAGE);
68 gdt_set_entry(&this_cpu_desc->gdt[3], 0x00000000, 0xFFFFFFFF, GDT_ENTRY_CODE, GDT_RING_USER, GDT_GRAN_PAGE);
69 gdt_set_entry(&this_cpu_desc->gdt[4], 0x00000000, 0xFFFFFFFF, GDT_ENTRY_DATA, GDT_RING_USER, GDT_GRAN_PAGE);
70
71 // TSS segment
72 gdt_entry_t *tss_seg = gdt_set_entry(&this_cpu_desc->gdt[5], (ptr_t) &this_cpu_desc->tss, sizeof(tss64_t), GDT_ENTRY_CODE, GDT_RING_KERNEL, GDT_GRAN_BYTE);
73
74 // ! Set special attributes for the TSS segment.
75 tss_seg->code_data_segment = 0; // indicates TSS/LDT (see also `accessed`)
76 tss_seg->accessed = 1; // With a system entry (`code_data_segment` = 0), 1 indicates TSS and 0 indicates LDT
77 tss_seg->read_write = 0; // For a TSS, indicates busy (1) or not busy (0).
78 tss_seg->executable = 1; // For a TSS, 1 indicates 32-bit (1) or 16-bit (0).
79 tss_seg->available = 0; // 0 for a TSS
80
81 this_cpu_desc->gdt_ptr.base = this_cpu_desc->gdt;
82 this_cpu_desc->gdt_ptr.limit = sizeof(this_cpu_desc->gdt) - 1;
83 gdt_flush(&this_cpu_desc->gdt_ptr);
84}
85
87{
88 x86_cpu_descriptor_t *this_cpu_desc = per_cpu(x86_cpu_descriptor);
89 memzero(&this_cpu_desc->tss, sizeof(tss64_t));
91}
static gdt_entry_t * gdt_set_entry(gdt_entry_t *entry, ptr_t base, u32 limit, gdt_entry_type_t entry_type, gdt_ring_t dpl, gdt_gran_t gran)
Definition descriptors.c:32
gdt_gran_t
Definition descriptors.c:27
@ GDT_GRAN_BYTE
Definition descriptors.c:28
@ GDT_GRAN_PAGE
Definition descriptors.c:29
gdt_entry_type_t
Definition descriptors.c:13
@ GDT_ENTRY_DATA
Definition descriptors.c:15
@ GDT_ENTRY_CODE
Definition descriptors.c:14
void x86_init_percpu_gdt()
Definition descriptors.c:59
typeof(x86_cpu_descriptor)
Definition descriptors.c:10
gdt_ring_t
Definition descriptors.c:19
@ GDT_RING_1
Definition descriptors.c:21
@ GDT_RING_USER
Definition descriptors.c:23
@ GDT_RING_2
Definition descriptors.c:22
@ GDT_RING_KERNEL
Definition descriptors.c:20
void x86_init_percpu_tss()
Definition descriptors.c:86
void gdt_flush(gdt_ptr_t *gdt_ptr)
#define GDT_SEGMENT_TSS
Definition descriptors.h:21
void tss_flush(u32 tss_selector)
#define MASK_BITS(value, width)
Definition mos_global.h:58
#define per_cpu(var)
Definition platform.h:25
#define memzero(ptr, size)
Definition rpc_client.c:40
Definition descriptors.h:26
u32 long_mode_code
Definition descriptors.h:38
u32 limit_high
Definition descriptors.h:36
u32 base_veryhigh
Definition descriptors.h:42
u32 code_data_segment
Definition descriptors.h:33
u32 pm32_segment
Definition descriptors.h:39
u32 dpl
Definition descriptors.h:34
u32 accessed
Definition descriptors.h:29
u32 executable
Definition descriptors.h:32
u32 available
Definition descriptors.h:37
u32 base_low
Definition descriptors.h:28
u32 conforming_expand_down
Definition descriptors.h:31
u32 read_write
Definition descriptors.h:30
u32 base_high
Definition descriptors.h:41
u32 present
Definition descriptors.h:35
u32 limit_low
Definition descriptors.h:27
u32 granularity
Definition descriptors.h:40
unsigned int u32
Definition types.h:21
unsigned long ptr_t
Definition types.h:25