aboutsummaryrefslogtreecommitdiff
path: root/sys/arch/amd64/tss.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/amd64/tss.c')
-rw-r--r--sys/arch/amd64/tss.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/sys/arch/amd64/tss.c b/sys/arch/amd64/tss.c
index ba1b0f6..b1b5420 100644
--- a/sys/arch/amd64/tss.c
+++ b/sys/arch/amd64/tss.c
@@ -32,6 +32,8 @@
#include <lib/string.h>
#include <vm/dynalloc.h>
#include <sys/panic.h>
+#include <sys/errno.h>
+#include <assert.h>
__MODULE_NAME("TSS");
__KERNEL_META("$Hyra$: tss.c, Ian Marco Moffett, "
@@ -55,6 +57,78 @@ alloc_resources(struct cpu_info *cpu)
}
}
+/*
+ * Update interrupt stack table entry `istno' with `stack'
+ *
+ * @stack: Interrupt stack.
+ * @istno: IST number, must be 1-based.
+ *
+ * Returns 0 on success.
+ */
+int
+tss_update_ist(struct cpu_info *ci, union tss_stack stack, uint8_t istno)
+{
+ volatile struct tss_entry *tss = ci->tss;
+
+ __assert(tss != NULL);
+
+ switch (istno) {
+ case 1:
+ tss->ist1_lo = stack.top_lo;
+ tss->ist1_hi = stack.top_hi;
+ break;
+ case 2:
+ tss->ist2_lo = stack.top_lo;
+ tss->ist2_hi = stack.top_hi;
+ break;
+ case 3:
+ tss->ist3_lo = stack.top_lo;
+ tss->ist3_hi = stack.top_hi;
+ break;
+ case 4:
+ tss->ist4_lo = stack.top_lo;
+ tss->ist4_hi = stack.top_hi;
+ break;
+ case 5:
+ tss->ist5_lo = stack.top_lo;
+ tss->ist5_hi = stack.top_hi;
+ break;
+ case 6:
+ tss->ist6_lo = stack.top_lo;
+ tss->ist6_hi = stack.top_hi;
+ break;
+ case 7:
+ tss->ist7_lo = stack.top_lo;
+ tss->ist7_hi = stack.top_hi;
+ break;
+ default:
+ return -EXIT_FAILURE;
+ };
+
+ return 0;
+}
+
+/*
+ * Allocates TSS stack.
+ *
+ * Returns 0 on success.
+ *
+ * @entry_out: Pointer to location where allocated entry
+ * will be sent.
+ */
+int
+tss_alloc_stack(union tss_stack *entry_out, size_t size)
+{
+ uintptr_t base = (uintptr_t)dynalloc(size);
+
+ if (base == 0) {
+ return -EXIT_FAILURE;
+ }
+
+ entry_out->top = base + size;
+ return 0;
+}
+
void
write_tss(struct cpu_info *cpu, struct tss_desc *desc)
{