PatchworkOS
Loading...
Searching...
No Matches
trampoline.c
Go to the documentation of this file.
2
3#include <kernel/cpu/cpu.h>
4#include <kernel/cpu/gdt.h>
7#include <kernel/log/log.h>
8#include <kernel/log/panic.h>
9#include <kernel/mem/pmm.h>
10#include <kernel/mem/vmm.h>
11#include <kernel/sched/sched.h>
12#include <kernel/sched/thread.h>
13#include <kernel/utils/utils.h>
14
16#include <string.h>
17
18static void* backupBuffer;
19static void* trampolineStack;
20
21static atomic_bool cpuReadyFlag;
22
24{
26 if (backupBuffer == NULL)
27 {
28 panic(NULL, "Failed to allocate memory for trampoline backup");
29 }
30
32 if (trampolineStack == NULL)
33 {
34 panic(NULL, "Failed to allocate memory for trampoline stack");
35 }
36
38
42
45
47
48 LOG_DEBUG("trampoline initialized\n");
49}
50
52{
54
59
60 LOG_DEBUG("trampoline deinitialized\n");
61}
62
74
76{
77 clock_t elapsed = 0;
78
79 while (elapsed < timeout)
80 {
82 {
83 return 0;
84 }
85
87 elapsed += CLOCKS_PER_SEC / 10000;
88 }
89
90 return ERR;
91}
92
93static void trampoline_after_jump(void)
94{
97}
98
100{
101 if (cpu_init(cpu, cpuId) == ERR)
102 {
103 panic(NULL, "Failed to initialize CPU %u", cpuId);
104 }
105
106 thread_t* thread = sched_thread_unsafe();
107 assert(thread != NULL);
108 assert(sched_is_idle(cpu));
110 thread->frame.rsp = thread->kernelStack.top;
111 thread->frame.cs = GDT_CS_RING0;
112 thread->frame.ss = GDT_SS_RING0;
114 thread_jump(thread);
115}
#define assert(expression)
Definition assert.h:29
#define CLOCKS_PER_SEC
Definition clock_t.h:15
@ GDT_CS_RING0
Value to load into the CS register for kernel code.
Definition gdt.h:45
@ GDT_SS_RING0
Value to load into the SS register for kernel data.
Definition gdt.h:46
#define TRAMPOLINE_PML4_OFFSET
Offset within the trampoline page where the PML4 address is stored.
Definition trampoline.h:38
void trampoline_send_startup_ipi(cpu_t *cpu, cpuid_t id, lapic_id_t lapicId)
Sends the startup IPI to a CPU to start it up.
Definition trampoline.c:63
#define TRAMPOLINE_STACK_OFFSET
Offset within the trampoline page where the stack pointer for the trampoline is stored.
Definition trampoline.h:58
#define TRAMPOLINE_SIZE
The size of the trampoline code.
Definition trampoline.h:78
void trampoline_start(void)
The start of the trampoline code, defined in trampoline.s.
#define TRAMPOLINE_BASE_ADDR
The physical address where the trampoline code will be copied to and executed from.
Definition trampoline.h:25
void trampoline_deinit(void)
Deinitializes the trampoline by restoring the original contents of the trampoline memory location.
Definition trampoline.c:51
#define TRAMPOLINE_ENTRY_OFFSET
Offset within the trampoline page where the entry point to jump to is stored.
Definition trampoline.h:43
#define TRAMPOLINE_ADDR(offset)
Macro to get a pointer to an address within the trampoline page.
Definition trampoline.h:63
#define TRAMPOLINE_CPU_OFFSET
Offset within the trampoline page where the CPU structure pointer is stored.
Definition trampoline.h:53
uint64_t trampoline_wait_ready(clock_t timeout)
Waits for the currently starting CPU to signal that it is ready.
Definition trampoline.c:75
#define TRAMPOLINE_CPU_ID_OFFSET
Offset within the trampoline page where the CPU id is stored.
Definition trampoline.h:48
#define TRAMPOLINE_DATA_OFFSET
The offset within the trampoline page where we can store data.
Definition trampoline.h:33
void trampoline_init(void)
Initializes the trampoline by copying the trampoline code to its designated memory location.
Definition trampoline.c:23
void trampoline_c_entry(cpu_t *cpu, cpuid_t cpuId)
After the trampoline is done with basic initialization, it calls this C entry point to continue CPU i...
Definition trampoline.c:99
uint64_t cpu_init(cpu_t *cpu, cpuid_t id)
Initializes a CPU structure as part of the boot process.
Definition cpu.c:16
uint16_t cpuid_t
Type used to identify a CPU.
Definition cpu_id.h:29
void lapic_send_init(lapic_id_t id)
Send an INIT IPI to a local apic.
Definition apic.c:201
void lapic_send_sipi(lapic_id_t id, void *entryPoint)
Send a Startup IPI to a local apic.
Definition apic.c:212
uint8_t lapic_id_t
Local APIC ID type.
Definition apic.h:24
void hpet_wait(clock_t nanoseconds)
Wait for a specified number of nanoseconds using the HPET.
Definition hpet.c:104
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:362
#define LOG_DEBUG(format,...)
Definition log.h:81
#define PML_ENSURE_LOWER_HALF(addr)
Ensures that the given address is in the lower half of the address space.
void pmm_free(void *address)
Frees a single physical page.
Definition pmm.c:211
void * pmm_alloc(void)
Allocates a single physical page.
Definition pmm.c:162
space_t * vmm_get_kernel_space(void)
Retrieves the kernel's address space.
Definition vmm.c:138
_NORETURN void thread_jump(thread_t *thread)
Jump to a thread by calling thread_load() and then loading its interrupt frame.
thread_t * sched_thread_unsafe(void)
Retrieves the currently running thread without disabling interrupts.
Definition sched.c:175
bool sched_is_idle(cpu_t *cpu)
Checks if the CPU is idle.
Definition sched.c:149
NORETURN void sched_idle_loop(void)
The idle loop for a CPU.
#define PAGE_SIZE
Memory page size.
Definition proc.h:140
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ clock_t
A nanosecond time.
Definition clock_t.h:13
#define RFLAGS_ALWAYS_SET
Definition regs.h:24
#define atomic_store(object, desired)
Definition stdatomic.h:289
#define atomic_load(object)
Definition stdatomic.h:288
#define atomic_init(obj, value)
Definition stdatomic.h:75
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:4
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
CPU structure.
Definition cpu.h:42
uint64_t rflags
Definition interrupt.h:64
uintptr_t top
The top of the stack, this address is not inclusive.
Thread of execution structure.
Definition thread.h:55
interrupt_frame_t frame
Definition thread.h:79
stack_pointer_t kernelStack
The kernel stack of the thread.
Definition thread.h:68
static atomic_bool cpuReadyFlag
Definition trampoline.c:21
static void * backupBuffer
Definition trampoline.c:18
static void trampoline_after_jump(void)
Definition trampoline.c:93
static void * trampolineStack
Definition trampoline.c:19
#define WRITE_64(address, value)
Definition utils.h:13