summaryrefslogtreecommitdiffstats
path: root/arch/x86_64/gdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/gdt.c')
-rw-r--r--arch/x86_64/gdt.c42
1 files changed, 29 insertions, 13 deletions
diff --git a/arch/x86_64/gdt.c b/arch/x86_64/gdt.c
index d996dcb..07a8097 100644
--- a/arch/x86_64/gdt.c
+++ b/arch/x86_64/gdt.c
@@ -25,14 +25,15 @@ static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
.limit_0_15 = 0xFFFF,
.base_0_15 = 0,
.base_16_23 = 0,
- .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_CODE_CONFORMING,
+ .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE,
.s = 1,
.dpl = 0,
.p = 1,
.limit_16_19 = 0xF,
+ .avl = 0,
.l = 1,
.d_b = 0,
- .g = 0,
+ .g = 1,
.base_24_31 = 0
},
{ /* Kernel Data (64-bit RW DPL0) */
@@ -44,9 +45,10 @@ static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
.dpl = 0,
.p = 1,
.limit_16_19 = 0xF,
- .l = 1,
- .d_b = 0,
- .g = 0,
+ .avl = 0,
+ .l = 0,
+ .d_b = 1,
+ .g = 1,
.base_24_31 = 0
},
{ 0 }, /* User NULL */
@@ -59,36 +61,38 @@ static struct SegmentDescriptor s_gdtd[GDT_SEGMENT_COUNT] =
.dpl = 3,
.p = 1,
.limit_16_19 = 0xF,
- .l = 1,
- .d_b = 0,
- .g = 0,
+ .avl = 0,
+ .l = 0,
+ .d_b = 1,
+ .g = 1,
.base_24_31 = 0,
},
{ /* User Code (64-bit RO EX DPL3)*/
.limit_0_15 = 0xFFFF,
.base_0_15 = 0,
.base_16_23 = 0,
- .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_CODE_CONFORMING,
+ .type = CD_SEGMENT_TYPE_CODE | CD_SEGMENT_TYPE_WRITEABLE,
.s = 1,
.dpl = 3,
.p = 1,
.limit_16_19 = 0xF,
+ .avl = 0,
.l = 1,
.d_b = 0,
- .g = 0,
+ .g = 1,
.base_24_31 = 0,
},
{ /* TSS Low */
- .limit_0_15 = sizeof(struct TSS),
+ .limit_0_15 = 0,
.base_0_15 = 0,
.base_16_23 = 0,
.type = S_SEGMENT_TYPE_TSS_AVAIL,
- .avl = 1,
+ .avl = 0,
.s = 0,
.dpl = 0,
.p = 1,
.limit_16_19 = 0,
- .l = 1,
+ .l = 0,
.d_b = 0,
.g = 0,
.base_24_31 = 0,
@@ -118,8 +122,20 @@ x86_64_load_gdt(void)
tss_lo->base_24_31 = (tssb >> 24) & 0xFF;
tss_hi->limit_0_15 = (tssb >> 32) & 0xFFFF;
tss_hi->base_0_15 = (tssb >> 48) & 0xFFFF;
+
+ size_t tssl = sizeof(struct TSS) - 1;
+ tss_lo->limit_0_15 = tssl & 0xFFFF;
+ tss_lo->limit_16_19 = (tssl >> 16) & 0xF;
+
+ s_tss.iobp = sizeof(struct TSS);
}
x86_64_lgdt(&s_gdtr);
x86_64_flush_tss();
}
+
+void tss_set_rsp(uint8_t dpl, uintptr_t rsp)
+{
+ s_tss.rsp[dpl][0] = rsp & 0xFFFFFFFF;
+ s_tss.rsp[dpl][1] = (rsp >> 32) & 0xFFFFFFFF;
+}