PatchworkOS  3984a1d
A non-POSIX operating system.
Loading...
Searching...
No Matches
trampoline.c
Go to the documentation of this file.
1#include "trampoline.h"
2
3#include <kernel/cpu/cpu.h>
4#include <kernel/cpu/gdt.h>
5#include <kernel/log/log.h>
6#include <kernel/log/panic.h>
7#include <kernel/mem/pmm.h>
8#include <kernel/mem/vmm.h>
10#include <kernel/sched/sched.h>
11#include <kernel/sched/thread.h>
12#include <kernel/sched/timer.h>
13#include <kernel/utils/utils.h>
14
16#include <string.h>
17
18static void* backupBuffer;
19static void* trampolineStack;
20
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
40 NULL, NULL) == NULL)
41 {
42 panic(NULL, "Failed to map trampoline");
43 }
44
49
52
54
55 LOG_DEBUG("trampoline initialized\n");
56}
57
72
85
87{
88 clock_t elapsed = 0;
89
90 while (elapsed < timeout)
91 {
93 {
94 return 0;
95 }
96
98 elapsed += CLOCKS_PER_SEC / 10000;
99 }
100
101 return ERR;
102}
103
104static void trampoline_after_jump(void)
105{
108}
109
111{
112 cpu_init_early(cpu);
113
114 cpu_init(cpu);
115
116 thread_t* thread = sched_thread_unsafe();
117 assert(thread != NULL);
118 assert(sched_is_idle(cpu));
120 thread->frame.rsp = thread->kernelStack.top;
121 thread->frame.cs = GDT_CS_RING0;
122 thread->frame.ss = GDT_SS_RING0;
124 thread_jump(thread);
125}
#define assert(expression)
Definition assert.h:29
int64_t y
Definition main.c:153
#define CLOCKS_PER_SEC
Definition clock_t.h:15
#define GDT_SS_RING0
Value to load into the SS register for kernel data.
Definition gdt.h:36
#define GDT_CS_RING0
Value to load into the CS register for kernel code.
Definition gdt.h:35
void cpu_init(cpu_t *cpu)
Initializes the CPU represented by the cpu_t structure.
Definition cpu.c:78
void cpu_init_early(cpu_t *cpu)
Only initialize the parts of the CPU structure needed for early boot.
Definition cpu.c:30
NORETURN void panic(const interrupt_frame_t *frame, const char *format,...)
Panic the kernel, printing a message and halting.
Definition panic.c:267
#define LOG_DEBUG(format,...)
Definition log.h:85
#define PML_LOWER_TO_HIGHER(addr)
Converts an address from the lower half to the higher half.
#define PML_ENSURE_LOWER_HALF(addr)
Ensures that the given address is in the lower half of the address space.
@ PML_PRESENT
@ PML_WRITE
void pmm_free(void *address)
Frees a single physical page.
Definition pmm.c:220
void * pmm_alloc(void)
Allocates a single physical page.
Definition pmm.c:171
void * vmm_map(space_t *space, void *virtAddr, void *physAddr, size_t length, pml_flags_t flags, space_callback_func_t func, void *private)
Maps physical memory to virtual memory in a given address space.
Definition vmm.c:226
space_t * vmm_kernel_space_get(void)
Retrieves the kernel's address space.
Definition vmm.c:133
void * vmm_unmap(space_t *space, void *virtAddr, size_t length)
Unmaps virtual memory from a given address space.
Definition vmm.c:334
void clock_wait(clock_t nanoseconds)
Wait for a specified number of nanoseconds.
Definition clock.c:130
_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:626
bool sched_is_idle(cpu_t *cpu)
Checks if the CPU is currently idle.
Definition sched.c:604
_NORETURN void sched_idle_loop(void)
The idle loop for the scheduler.
#define PAGE_SIZE
The size of a memory page in bytes.
Definition proc.h:103
#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
void lapic_send_init(lapic_id_t id)
Send an INIT IPI to the specified local APIC.
Definition lapic.c:118
void lapic_send_sipi(lapic_id_t id, void *entryPoint)
Send a Startup IPI (SIPI) to the specified local APIC.
Definition lapic.c:124
uint8_t lapic_id_t
Local APIC ID type.
Definition lapic.h:32
void trampoline_send_startup_ipi(cpu_t *cpu, lapic_id_t lapicId)
Sends the startup IPI to a CPU to start it up.
Definition trampoline.c:73
#define TRAMPOLINE_PML4_OFFSET
Offset within the trampoline page where the PML4 address is stored.
Definition trampoline.h:40
#define TRAMPOLINE_STACK_OFFSET
Offset within the trampoline page where the stack pointer for the trampoline is stored.
Definition trampoline.h:55
#define TRAMPOLINE_SIZE
The size of the trampoline code.
Definition trampoline.h:72
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:27
void trampoline_deinit(void)
Deinitializes the trampoline by restoring the original contents of the trampoline memory location.
Definition trampoline.c:58
#define TRAMPOLINE_ENTRY_OFFSET
Offset within the trampoline page where the entry point to jump to is stored.
Definition trampoline.h:45
#define TRAMPOLINE_CPU_OFFSET
Offset within the trampoline page where the CPU structure pointer is stored.
Definition trampoline.h:50
uint64_t trampoline_wait_ready(clock_t timeout)
Waits for the currently starting CPU to signal that it is ready.
Definition trampoline.c:86
void trampoline_c_entry(cpu_t *cpu)
After the trampoline is done with basic initialization, it calls this C entry point to continue CPU i...
Definition trampoline.c:110
#define TRAMPOLINE_DATA_OFFSET
The offset within the trampoline page where we can store data.
Definition trampoline.h:35
void trampoline_init(void)
Initializes the trampoline by copying the trampoline code to its designated memory location.
Definition trampoline.c:23
#define RFLAGS_INTERRUPT_ENABLE
Definition regs.h:32
#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_VAR_INIT(value)
Definition stdatomic.h:74
#define atomic_init(obj, value)
Definition stdatomic.h:75
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__UINT8_TYPE__ uint8_t
Definition stdint.h:11
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:43
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:61
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
CPU structure.
Definition cpu.h:122
uintptr_t top
The top of the stack, this address is not inclusive.
Thread of execution structure.
Definition thread.h:56
interrupt_frame_t frame
Definition thread.h:80
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:104
static void * trampolineStack
Definition trampoline.c:19
#define WRITE_64(address, value)
Definition utils.h:19