x86_64: implement TSS initialisation and user/kernel stack pointer switching

This commit is contained in:
2026-02-08 11:34:21 +00:00
parent 564d4f9ba0
commit 4051265876
7 changed files with 178 additions and 6 deletions

View File

@@ -1,6 +1,7 @@
#ifndef ARCH_GDT_H_
#define ARCH_GDT_H_
#include <arch/tss.h>
#include <mango/compiler.h>
#include <stdint.h>
@@ -33,6 +34,7 @@ struct gdt_entry {
struct gdt {
struct gdt_entry g_entries[NR_GDT_ENTRIES];
struct tss_gdt_entry g_tss;
} __packed;
struct gdt_ptr {
@@ -41,6 +43,7 @@ struct gdt_ptr {
} __packed;
extern int gdt_init(struct gdt *gdt, struct gdt_ptr *gdtp);
extern void gdt_write_tss(struct gdt *gdt, struct tss *tss);
extern int gdt_load(struct gdt_ptr *gdtp);
#ifdef __cplusplus

View File

@@ -0,0 +1,55 @@
#ifndef ARCH_TSS_H_
#define ARCH_TSS_H_
#include <mango/compiler.h>
#include <mango/types.h>
#include <stdint.h>
#define TSS_GDT_INDEX 5
struct tss {
uint32_t res0;
uint64_t rsp0;
uint64_t rsp1;
uint64_t rsp2;
uint64_t res1;
uint64_t ist1;
uint64_t ist2;
uint64_t ist3;
uint64_t ist4;
uint64_t ist5;
uint64_t ist6;
uint64_t ist7;
uint64_t res2;
uint16_t res3;
uint16_t iomap_offset;
} __packed;
struct tss_gdt_entry {
/* these fields are copied from struct gdt_entry */
uint16_t ge_limit_low;
uint16_t ge_base_low;
uint8_t ge_base_mid;
uint8_t ge_access;
uint8_t ge_gran;
uint8_t ge_base_hi;
/* these fields are specific to the TSS entry */
uint32_t ge_base_ext;
uint32_t ge_reserved;
} __packed;
struct tss_ptr {
uint16_t tss_limit;
uint64_t tss_base;
} __packed;
extern void tss_init(struct tss *tss, struct tss_ptr *ptr);
extern void tss_load(struct tss *tss);
extern virt_addr_t tss_get_kstack(struct tss *tss);
extern virt_addr_t tss_get_ustack(struct tss *tss);
extern void tss_set_kstack(struct tss *tss, virt_addr_t sp);
extern void tss_set_ustack(struct tss *tss, virt_addr_t sp);
#endif

View File

@@ -21,6 +21,9 @@ typedef struct ml_cpu_block {
struct gdt c_gdt;
struct gdt_ptr c_gdt_ptr;
struct tss c_tss;
struct tss_ptr c_tss_ptr;
struct idt_ptr c_idt_ptr;
unsigned int c_cpu_id;
@@ -45,6 +48,12 @@ extern int ml_init_bootcpu(void);
extern int ml_cpu_block_init(ml_cpu_block *p);
extern int ml_cpu_block_use(ml_cpu_block *p);
extern virt_addr_t ml_cpu_block_get_ustack(ml_cpu_block *p);
extern virt_addr_t ml_cpu_block_get_kstack(ml_cpu_block *p);
extern void ml_cpu_block_set_ustack(ml_cpu_block *p, virt_addr_t sp);
extern void ml_cpu_block_set_kstack(ml_cpu_block *p, virt_addr_t sp);
/* defined in cpu_ctrl.S */
extern void ml_halt_cpu(void);
extern ml_cpu_block *ml_this_cpu(void);

View File

@@ -1,6 +1,7 @@
#ifndef MANGO_X86_64_INIT_H_
#define MANGO_X86_64_INIT_H_
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus