x86_64: implement TSS initialisation and user/kernel stack pointer switching
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef MANGO_X86_64_INIT_H_
|
||||
#define MANGO_X86_64_INIT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
Reference in New Issue
Block a user