|
PatchworkOS
da8a090
A non-POSIX operating system.
|
Task State Segment structure. More...
#include <tss.h>
Data Fields | |
| uint32_t | reserved1 |
| uint64_t | rsp0 |
| Stack pointer to load when switching to ring 0, unused. | |
| uint64_t | rsp1 |
| Stack pointer to load when switching to ring 1, unused. | |
| uint64_t | rsp2 |
| Stack pointer to load when switching to ring 2, unused. | |
| uint64_t | reserved2 |
| uint64_t | ist [TSS_IST_COUNT] |
| Interrupt Stack Table. | |
| uint64_t | reserved3 |
| uint16_t | reserved4 |
| uint16_t | iopb |
| Offset to the I/O permission bitmap, we set this to the size of the TSS to disable the bitmap. | |
| char | todo |
Task State Segment structure.
The rsp* members store the stack to use when switching to a higher privilege level, we dont use these.
Instead we have a total of 4 stacks used while in kernel space, 34 per-cpu stacks and 1 per-thread stack. Of course there is also the user stack used while in user space. But that is not relevant to the TSS and instead handled by the system call code.
The per-cpu stacks are:
We need four stacks as its possible for an exception to occur during an interrupt, for a double fault to occur during an exception, and of course Non-maskable interrupts can occur at any time, therefore we must ensure that in the worst case where each of these occur recursively we have a separate stack for each level.
The per-thread stack is called the "kernel stack" and is used while the thread is in kernel space and NOT handling an exception or interrupt. In effect this is used in system calls, boot, inital thread loading and if the thread is a kernel thread it is used all the time. This stack is not handled by the TSS, instead the system call code is responsible for switching to this stack when entering kernel space from user space.
The IST works by having the CPU check the IST index specified in the IDT gate for that interrupt or exception, if it has a non zero IST index it will then load that stack pointer from ist[index - 1] and switch to that stack before calling the interrupt or exception handler. This happens regardless of the current privilege level.
| uint64_t tss_t::rsp0 |
| uint64_t tss_t::rsp1 |
| uint64_t tss_t::rsp2 |
| uint64_t tss_t::ist[TSS_IST_COUNT] |
| uint16_t tss_t::iopb |