|
PatchworkOS
|
Trampoline for CPU initialization. More...
Macros | |
| #define | TRAMPOLINE_BASE_ADDR 0x8000 |
| The physical address where the trampoline code will be copied to and executed from. | |
| #define | TRAMPOLINE_DATA_OFFSET 0x0F00 |
| The offset within the trampoline page where we can store data. | |
| #define | TRAMPOLINE_PML4_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x00) |
| Offset within the trampoline page where the PML4 address is stored. | |
| #define | TRAMPOLINE_ENTRY_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x08) |
| Offset within the trampoline page where the entry point to jump to is stored. | |
| #define | TRAMPOLINE_CPU_ID_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x10) |
| Offset within the trampoline page where the CPU id is stored. | |
| #define | TRAMPOLINE_CPU_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x18) |
| Offset within the trampoline page where the CPU structure pointer is stored. | |
| #define | TRAMPOLINE_STACK_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x20) |
| Offset within the trampoline page where the stack pointer for the trampoline is stored. | |
| #define | TRAMPOLINE_ADDR(offset) ((void*)(TRAMPOLINE_BASE_ADDR + (offset))) |
| Macro to get a pointer to an address within the trampoline page. | |
| #define | TRAMPOLINE_SIZE ((uintptr_t)trampoline_end - (uintptr_t)trampoline_start) |
| The size of the trampoline code. | |
Functions | |
| void | trampoline_start (void) |
The start of the trampoline code, defined in trampoline.s. | |
| void | trampoline_end (void) |
The end of the trampoline code, defined in trampoline.s. | |
| void | trampoline_init (void) |
| Initializes the trampoline by copying the trampoline code to its designated memory location. | |
| void | trampoline_deinit (void) |
| Deinitializes the trampoline by restoring the original contents of the trampoline memory location. | |
| void | trampoline_send_startup_ipi (cpu_t *cpu, cpuid_t cpuId, lapic_id_t lapicId) |
| Sends the startup IPI to a CPU to start it up. | |
| uint64_t | trampoline_wait_ready (clock_t timeout) |
| Waits for the currently starting CPU to signal that it is ready. | |
| _NORETURN void | trampoline_c_entry (cpu_t *self, cpuid_t cpuId) |
| After the trampoline is done with basic initialization, it calls this C entry point to continue CPU initialization. | |
Trampoline for CPU initialization.
The trampoline is a small piece of code used during the initialization of other CPUs in a multiprocessor system.
The trampoline code must be position-independent and fit within a single memory page, this is why we do all the weird offset stuff.
| #define TRAMPOLINE_ADDR | ( | offset | ) | ((void*)(TRAMPOLINE_BASE_ADDR + (offset))) |
Macro to get a pointer to an address within the trampoline page.
Definition at line 63 of file trampoline.h.
| #define TRAMPOLINE_BASE_ADDR 0x8000 |
The physical address where the trampoline code will be copied to and executed from.
Definition at line 25 of file trampoline.h.
| #define TRAMPOLINE_CPU_ID_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x10) |
Offset within the trampoline page where the CPU id is stored.
Definition at line 48 of file trampoline.h.
| #define TRAMPOLINE_CPU_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x18) |
Offset within the trampoline page where the CPU structure pointer is stored.
Definition at line 53 of file trampoline.h.
| #define TRAMPOLINE_DATA_OFFSET 0x0F00 |
The offset within the trampoline page where we can store data.
This is used to pass data to the trampoline code, such as the stack pointer to use and the entry point to jump to. As it cannot access virtual memory yet.
Definition at line 33 of file trampoline.h.
| #define TRAMPOLINE_ENTRY_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x08) |
Offset within the trampoline page where the entry point to jump to is stored.
Definition at line 43 of file trampoline.h.
| #define TRAMPOLINE_PML4_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x00) |
Offset within the trampoline page where the PML4 address is stored.
Definition at line 38 of file trampoline.h.
| #define TRAMPOLINE_SIZE ((uintptr_t)trampoline_end - (uintptr_t)trampoline_start) |
The size of the trampoline code.
Definition at line 78 of file trampoline.h.
| #define TRAMPOLINE_STACK_OFFSET (TRAMPOLINE_DATA_OFFSET + 0x20) |
Offset within the trampoline page where the stack pointer for the trampoline is stored.
Definition at line 58 of file trampoline.h.
After the trampoline is done with basic initialization, it calls this C entry point to continue CPU initialization.
When this function is called the trampolines stack is still being used, after cpu initalization is done we perform a jump to the idle thread of the CPU.
| self | Pointer to the CPU structure of the current CPU, will still be uninitialized. |
| cpuId | The ID of the current CPU. |
Definition at line 99 of file trampoline.c.
References assert, cpu_init(), interrupt_frame_t::cs, ERR, thread_t::frame, GDT_CS_RING0, GDT_SS_RING0, thread_t::kernelStack, NULL, panic(), interrupt_frame_t::rflags, RFLAGS_ALWAYS_SET, interrupt_frame_t::rip, interrupt_frame_t::rsp, sched_is_idle(), sched_thread_unsafe(), interrupt_frame_t::ss, thread_jump(), stack_pointer_t::top, and trampoline_after_jump().
Referenced by trampoline_init().
| void trampoline_deinit | ( | void | ) |
Deinitializes the trampoline by restoring the original contents of the trampoline memory location.
Definition at line 51 of file trampoline.c.
References backupBuffer, LOG_DEBUG, memcpy(), NULL, PAGE_SIZE, pmm_free(), TRAMPOLINE_BASE_ADDR, and trampolineStack.
Referenced by smp_others_init().
|
extern |
The end of the trampoline code, defined in trampoline.s.
| void trampoline_init | ( | void | ) |
Initializes the trampoline by copying the trampoline code to its designated memory location.
Will also backup the original contents of the trampoline memory location and restore it when trampoline_deinit() is called.
Definition at line 23 of file trampoline.c.
References assert, atomic_init, backupBuffer, cpuReadyFlag, LOG_DEBUG, memcpy(), memset(), NULL, PAGE_SIZE, panic(), PML_ENSURE_LOWER_HALF, pmm_alloc(), TRAMPOLINE_ADDR, TRAMPOLINE_BASE_ADDR, trampoline_c_entry(), TRAMPOLINE_DATA_OFFSET, TRAMPOLINE_ENTRY_OFFSET, TRAMPOLINE_PML4_OFFSET, TRAMPOLINE_SIZE, trampoline_start(), trampolineStack, vmm_get_kernel_space(), and WRITE_64.
Referenced by smp_others_init().
| void trampoline_send_startup_ipi | ( | cpu_t * | cpu, |
| cpuid_t | cpuId, | ||
| lapic_id_t | lapicId | ||
| ) |
Sends the startup IPI to a CPU to start it up.
| cpu | The CPU structure to be initalized as the new CPU. |
| cpuId | The ID to be assigned to the CPU to start. |
| lapicId | The LAPIC ID of the CPU to start. |
Definition at line 63 of file trampoline.c.
References atomic_store, CLOCKS_PER_SEC, cpuReadyFlag, hpet_wait(), lapic_send_init(), lapic_send_sipi(), PAGE_SIZE, TRAMPOLINE_ADDR, TRAMPOLINE_BASE_ADDR, TRAMPOLINE_CPU_ID_OFFSET, TRAMPOLINE_CPU_OFFSET, TRAMPOLINE_STACK_OFFSET, trampolineStack, and WRITE_64.
Referenced by smp_others_init().
|
extern |
The start of the trampoline code, defined in trampoline.s.
Referenced by trampoline_init().
Waits for the currently starting CPU to signal that it is ready.
| timeout | The maximum time to wait in clock ticks. |
0. On timeout, ERR and errno is set. Definition at line 75 of file trampoline.c.
References atomic_load, CLOCKS_PER_SEC, cpuReadyFlag, ERR, and hpet_wait().
Referenced by smp_others_init().