MOS Source Code
Loading...
Searching...
No Matches
platform.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
7#include "mos/mm/mm_types.hpp"
10#include "mos/platform/platform_defs.hpp"
11#include "mos/types.hpp"
12
15#include <mos/mm/mm_types.h>
16#include <mos/mos_global.h>
17#include <mos/shared_ptr.hpp>
19
20// clang-format off
21#if MOS_CONFIG(MOS_SMP)
22#define PER_CPU_DECLARE(type, name) struct name { type percpu_value[MOS_MAX_CPU_COUNT]; } name
23#define PER_CPU_VAR_INIT { .percpu_value = { 0 } }
24#define per_cpu(var) (&(var.percpu_value[platform_current_cpu_id()]))
25#else
26#define PER_CPU_DECLARE(type, name) struct name { type percpu_value[1]; } name
27#define PER_CPU_VAR_INIT { .percpu_value = { 0 } }
28#define per_cpu(var) (&(var.percpu_value[0]))
29#endif
30// clang-format on
31
32#define current_cpu per_cpu(platform_info->cpu)
33#define current_thread (current_cpu->thread)
34#define current_process (current_thread->owner)
35#define current_mm (current_cpu->mm_context)
36
37typedef void (*irq_handler)(u32 irq);
38
39struct Thread;
40struct Console;
41
51
58
59MOS_ENUM_FLAGS(ContextSwitchBehavior, ContextSwitchBehaviorFlags);
60
67
69
70struct platform_regs_t;
71
82
92
120
121#define MOS_KERNEL_PFN(vaddr) ((ALIGN_DOWN_TO_PAGE((vaddr) - (platform_info->k_basevaddr)) / MOS_PAGE_SIZE) + (platform_info->k_basepfn))
122
124
125typedef struct _platform_process_options platform_process_options_t;
126typedef struct _platform_thread_options platform_thread_options_t;
127
128// should be defined in platform's linker script
129extern const char __MOS_KERNEL_CODE_START[], __MOS_KERNEL_CODE_END[]; // Kernel text
130extern const char __MOS_KERNEL_RODATA_START[], __MOS_KERNEL_RODATA_END[]; // Kernel rodata
131extern const char __MOS_KERNEL_RW_START[], __MOS_KERNEL_RW_END[]; // Kernel read-write data
132extern const char __MOS_KERNEL_END[]; // Kernel end
133
134extern void mos_start_kernel(void);
135
136#define platform_alias(name) __attribute__((alias("platform_default_" #name)))
137
138// Platform Startup APIs
139[[noreturn]] void platform_ap_entry(u64 arg);
143
144// Platform Machine APIs
145// default implementation panics
146[[noreturn]] void platform_shutdown(void);
147// default implementations do nothing for 4 functions below
148void platform_dump_regs(const platform_regs_t *regs);
149void platform_dump_stack(const platform_regs_t *regs);
151void platform_dump_thread_kernel_stack(const Thread *thread);
152
153// Platform Timer/Clock APIs
154// default implementation does nothing
156void platform_get_unix_timestamp(u64 *timestamp);
157
158// Platform CPU APIs
159// default implementation loops forever
160[[noreturn]] void platform_halt_cpu(void);
161// default implementation does nothing for 4 functions below
164void platform_cpu_idle(void);
166
167typedef char datetime_str_t[32];
169
170// Platform Interrupt APIs
171// default implementation does nothing
174
175// Platform Page Table APIs
176// no default implementation, platform-specific implementations must be provided
177pfn_t platform_pml1e_get_pfn(const pml1e_t *pml1); // returns the physical address contained in the pmlx entry,
178void platform_pml1e_set_pfn(pml1e_t *pml1, pfn_t pfn); // -- which can be a pfn for either a page or another page table
179bool platform_pml1e_get_present(const pml1e_t *pml1); // returns if an entry in this page table is present
180void platform_pml1e_set_flags(pml1e_t *pml1, VMFlags flags); // set bits in the flags field of the pmlx entry
181VMFlags platform_pml1e_get_flags(const pml1e_t *pml1e); // get bits in the flags field of the pmlx entry
182
183#if MOS_PLATFORM_PAGING_LEVELS >= 2
184pml1_t platform_pml2e_get_pml1(const pml2e_t *pml2);
185void platform_pml2e_set_pml1(pml2e_t *pml2, pml1_t pml1, pfn_t pml1_pfn);
186bool platform_pml2e_get_present(const pml2e_t *pml2);
187void platform_pml2e_set_flags(pml2e_t *pml2, VMFlags flags);
188VMFlags platform_pml2e_get_flags(const pml2e_t *pml2e);
189#if MOS_CONFIG(PML2_HUGE_CAPABLE)
190bool platform_pml2e_is_huge(const pml2e_t *pml2);
191void platform_pml2e_set_huge(pml2e_t *pml2, pfn_t pfn);
192pfn_t platform_pml2e_get_huge_pfn(const pml2e_t *pml2);
193#endif
194#endif
195
196#if MOS_PLATFORM_PAGING_LEVELS >= 3
197pml2_t platform_pml3e_get_pml2(const pml3e_t *pml3e);
198void platform_pml3e_set_pml2(pml3e_t *pml3e, pml2_t pml2, pfn_t pml2_pfn);
199bool platform_pml3e_get_present(const pml3e_t *pml3e);
200void platform_pml3e_set_flags(pml3e_t *pml3e, VMFlags flags);
201VMFlags platform_pml3e_get_flags(const pml3e_t *pml3e);
202#if MOS_CONFIG(PML3_HUGE_CAPABLE)
203bool platform_pml3e_is_huge(const pml3e_t *pml3e);
204void platform_pml3e_set_huge(pml3e_t *pml3e, pfn_t pfn);
206#endif
207#endif
208
209#if MOS_PLATFORM_PAGING_LEVELS >= 4
210pml3_t platform_pml4e_get_pml3(const pml4e_t *pml4);
211void platform_pml4e_set_pml3(pml4e_t *pml4, pml3_t pml3, pfn_t pml3_pfn);
212bool platform_pml4e_get_present(const pml4e_t *pml4);
213void platform_pml4e_set_flags(pml4e_t *pml4, VMFlags flags);
214VMFlags platform_pml4e_get_flags(const pml4e_t *pml4e);
215#if MOS_CONFIG(PML4_HUGE_CAPABLE)
216bool platform_pml4e_is_huge(const pml4e_t *pml4);
217void platform_pml4e_set_huge(pml4e_t *pml4, pfn_t pfn);
218pfn_t platform_pml4e_get_huge_pfn(const pml4e_t *pml4);
219#endif
220#endif
221
222// Platform Thread / Process APIs
223// no default implementation, platform-specific implementations must be provided
225void platform_context_setup_main_thread(Thread *thread, ptr_t entry, ptr_t sp, int argc, ptr_t argv, ptr_t envp);
226void platform_context_setup_child_thread(Thread *thread, thread_entry_t entry, void *arg);
227void platform_context_clone(Thread *from, Thread *to);
228void platform_context_cleanup(Thread *thread);
229
230// Platform Context Switching APIs
231// no default implementation, platform-specific implementations must be provided
232void platform_switch_mm(const MMContext *new_mm);
233void platform_switch_to_thread(Thread *current, Thread *new_thread, ContextSwitchBehaviorFlags switch_flags);
234
235// Platform-Specific syscall APIs
236// default implementation does nothing
237u64 platform_arch_syscall(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4);
238
239// Platform-Specific IPI (Inter-Processor Interrupt) APIs
240// default implementation does nothing
241void platform_ipi_send(u8 target_cpu, ipi_type_t type);
242
243// Signal Handler APIs
244// the 4 function below has default implementations that panic if not implemented
245typedef struct _sigreturn_data sigreturn_data_t;
247[[noreturn]] void platform_restore_from_signal_handler(void *sp);
pml1_t platform_pml2e_get_pml1(const pml2e_t *pml2e)
Definition mm.cpp:108
bool platform_pml3e_get_present(const pml3e_t *pml3e)
Definition mm.cpp:171
void platform_pml4e_set_pml3(pml4e_t *pml4e, pml3_t pml3, pfn_t pml3_pfn)
Definition mm.cpp:213
pml3_t platform_pml4e_get_pml3(const pml4e_t *pml4e)
Definition mm.cpp:208
void platform_pml3e_set_flags(pml3e_t *pml3e, VMFlags flags)
Definition mm.cpp:176
VMFlags platform_pml3e_get_flags(const pml3e_t *pml3e)
Definition mm.cpp:182
void platform_pml2e_set_pml1(pml2e_t *pml2e, pml1_t pml1, pfn_t pml1_pfn)
Definition mm.cpp:113
void platform_pml4e_set_flags(pml4e_t *pml4e, VMFlags flags)
Definition mm.cpp:226
VMFlags platform_pml2e_get_flags(const pml2e_t *pml2e)
Definition mm.cpp:132
void platform_pml2e_set_flags(pml2e_t *pml2e, VMFlags flags)
Definition mm.cpp:126
void platform_pml3e_set_pml2(pml3e_t *pml3e, pml2_t pml2, pfn_t pml2_pfn)
Definition mm.cpp:163
bool platform_pml2e_get_present(const pml2e_t *pml2e)
Definition mm.cpp:121
VMFlags platform_pml4e_get_flags(const pml4e_t *pml4e)
Definition mm.cpp:232
bool platform_pml4e_get_present(const pml4e_t *pml4e)
Definition mm.cpp:221
pml2_t platform_pml3e_get_pml2(const pml3e_t *pml3e)
Definition mm.cpp:158
bool platform_pml3e_is_huge(const pml3e_t *pml3e)
Definition paging.cpp:245
pfn_t platform_pml2e_get_huge_pfn(const pml2e_t *pml2)
Definition paging.cpp:182
void platform_pml2e_set_huge(pml2e_t *pml2e, pfn_t pfn)
Definition paging.cpp:173
bool platform_pml2e_is_huge(const pml2e_t *pml2e)
Definition paging.cpp:167
void platform_pml3e_set_huge(pml3e_t *pml3e, pfn_t pfn)
Definition paging.cpp:251
pfn_t platform_pml3e_get_huge_pfn(const pml3e_t *pml3)
Definition paging.cpp:260
#define MOS_MAX_MEMREGIONS
Definition autoconf.h:25
#define MOS_MAX_CMDLINE_COUNT
Definition autoconf.h:24
uint8_t argc
Definition avr_io.c:15
MOSAPI void(1, 2) fatal_abort(const char *fmt
list_node_t list_head
A linked list head.
Definition list.hpp:23
ipi_type_t
The type of IPI to send.
Definition ipi.hpp:13
#define current
platform_regs_t * platform_thread_regs(Thread *thread)
void platform_interrupt_disable(void)
u32 platform_current_cpu_id(void)
void platform_context_cleanup(Thread *thread)
ContextSwitchBehavior
Definition platform.hpp:53
@ SWITCH_REGULAR
Definition platform.hpp:54
@ SWITCH_TO_NEW_KERNEL_THREAD
Definition platform.hpp:56
@ SWITCH_TO_NEW_USER_THREAD
Definition platform.hpp:55
const char __MOS_KERNEL_RODATA_START[]
u64 platform_arch_syscall(u64 syscall, u64 arg1, u64 arg2, u64 arg3, u64 arg4)
void(* irq_handler)(u32 irq)
Definition platform.hpp:37
const char __MOS_KERNEL_CODE_END[]
Definition platform.hpp:129
void platform_pml1e_set_pfn(pml1e_t *pml1, pfn_t pfn)
Definition mm.cpp:84
void platform_startup_setup_kernel_mm()
void platform_pml1e_set_flags(pml1e_t *pml1, VMFlags flags)
Definition mm.cpp:96
#define PER_CPU_DECLARE(type, name)
Definition platform.hpp:26
void platform_interrupt_enable(void)
void platform_syscall_setup_restart_context(platform_regs_t *regs, reg_t syscall_nr)
void platform_restore_from_signal_handler(void *sp)
void platform_shutdown(void)
void platform_switch_mm(const MMContext *new_mm)
void platform_dump_thread_kernel_stack(const Thread *thread)
void platform_ap_entry(u64 arg)
Definition ap.cpp:7
void platform_dump_regs(const platform_regs_t *regs)
VMFlags platform_pml1e_get_flags(const pml1e_t *pml1e)
Definition mm.cpp:102
void platform_context_setup_main_thread(Thread *thread, ptr_t entry, ptr_t sp, int argc, ptr_t argv, ptr_t envp)
u64 platform_get_timestamp(void)
const char __MOS_KERNEL_RW_START[]
void platform_startup_late()
void platform_invalidate_tlb(ptr_t vaddr)
Definition mm.cpp:73
const char __MOS_KERNEL_RODATA_END[]
Definition platform.hpp:130
void platform_ipi_send(u8 target_cpu, ipi_type_t type)
void platform_context_clone(Thread *from, Thread *to)
pfn_t platform_pml1e_get_pfn(const pml1e_t *pml1)
Definition mm.cpp:79
ptr< platform_regs_t > platform_setup_signal_handler_regs(const platform_regs_t *regs, const sigreturn_data_t *sigreturn_data, const sigaction_t *sa)
datetime_str_t * platform_get_datetime_str(void)
void platform_syscall_store_retval(platform_regs_t *regs, reg_t result)
void platform_context_setup_child_thread(Thread *thread, thread_entry_t entry, void *arg)
void platform_cpu_idle(void)
void platform_get_time(timeval_t *val)
bool platform_pml1e_get_present(const pml1e_t *pml1)
Definition mm.cpp:91
void mos_start_kernel(void)
Definition kmain.cpp:130
char datetime_str_t[32]
Definition platform.hpp:167
void platform_startup_early()
MMContext mos_kernel_mm
Definition kmain.cpp:31
thread_state_t
Definition platform.hpp:43
@ THREAD_STATE_READY
thread can be scheduled
Definition platform.hpp:45
@ THREAD_STATE_RUNNING
thread is currently running
Definition platform.hpp:46
@ THREAD_STATE_NONINTERRUPTIBLE
thread is blocked, and cannot be interrupted
Definition platform.hpp:48
@ THREAD_STATE_DEAD
thread is dead, and will be cleaned up soon by the scheduler
Definition platform.hpp:49
@ THREAD_STATE_BLOCKED
thread is blocked by a wait condition
Definition platform.hpp:47
@ THREAD_STATE_CREATED
created or forked, but not ever started
Definition platform.hpp:44
void platform_switch_to_thread(Thread *current, Thread *new_thread, ContextSwitchBehaviorFlags switch_flags)
void platform_halt_cpu(void)
Definition mm.cpp:66
void platform_dump_stack(const platform_regs_t *regs)
const char __MOS_KERNEL_CODE_START[]
const char __MOS_KERNEL_END[]
void platform_get_unix_timestamp(u64 *timestamp)
void platform_dump_current_stack()
const char __MOS_KERNEL_RW_END[]
Definition platform.hpp:131
pml3e_t pml4e_t
Definition pml_types.hpp:72
pml2e_t pml3e_t
Definition pml_types.hpp:60
mos_platform_info_t *const platform_info
mos::shared_ptr< T > ptr
void(* thread_entry_t)(void *arg)
Definition signal_types.h:8
#define SPINLOCK_INIT
Definition spinlock.hpp:31
spinlock_t mm_lock
protects [pgd] and the [mmaps] list (the list itself, not the vmap_t objects)
Definition platform.hpp:63
list_head mmaps
Definition platform.hpp:65
pgd_t pgd
Definition platform.hpp:64
Thread * idle_thread
idle thread for this CPU
Definition platform.hpp:80
platform_regs_t * interrupt_regs
the registers of whatever interrupted this CPU
Definition platform.hpp:78
ptr_t scheduler_stack
Definition platform.hpp:76
Thread * thread
Definition platform.hpp:75
u32 id
Definition platform.hpp:74
MMContext * mm_context
Definition platform.hpp:77
platform_cpuinfo_t cpuinfo
Definition platform.hpp:79
MMContext *const kernel_mm
Definition platform.hpp:102
platform_arch_info_t arch_info
Definition platform.hpp:116
Console * boot_console
Definition platform.hpp:118
pmm_region_t pmm_regions[MOS_MAX_MEMREGIONS]
Definition platform.hpp:108
cmdline_option_t cmdlines[MOS_MAX_CMDLINE_COUNT]
Definition platform.hpp:114
uintn reg_t
Definition types.h:47
unsigned int u32
Definition types.h:17
unsigned long long pfn_t
Definition types.h:37
unsigned short u16
Definition types.h:16
unsigned long ptr_t
Definition types.h:21
unsigned long long u64
Definition types.h:19
unsigned char u8
Definition types.h:15
#define MOS_ENUM_FLAGS(enum, flags)
Definition types.hpp:236