MOS Source Code
Loading...
Searching...
No Matches
x86_platform_api.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4#include "mos/platform/platform_defs.hpp"
7
8#include <mos/allocator.hpp>
12#include <mos/mos_global.h>
14#include <mos/platform_syscall.h>
15#include <mos/syslog/printk.hpp>
16#include <mos/tasks/process.hpp>
18#include <mos/x86/cpu/cpu.hpp>
19#include <mos/x86/delays.hpp>
26#include <mos_stdio.hpp>
27#include <mos_stdlib.hpp>
28#include <mos_string.hpp>
29
30[[noreturn]] void platform_shutdown(void)
31{
33 port_outw(0x604, 0x2000);
35 while (1)
36 ;
37}
38
40{
42}
43
45{
46 if (!vaddr)
48 else
49 x86_cpu_invlpg(vaddr);
50}
51
53{
54 return x86_cpuid(b, 1, 0) >> 24;
55}
56
58{
59 __asm__ volatile("hlt");
60}
61
63{
64 return rdtsc();
65}
66
68{
69 static PER_CPU_DECLARE(datetime_str_t, datetime_str);
70
71 timeval_t time;
72 platform_get_time(&time);
73 snprintf(*per_cpu(datetime_str), sizeof(datetime_str_t), "%d-%02d-%02d %02d:%02d:%02d", time.year, time.month, time.day, time.hour, time.minute, time.second);
74 return per_cpu(datetime_str);
75}
76
78{
79 __asm__ volatile("sti");
80}
81
83{
84 __asm__ volatile("cli");
85}
86
91
93{
94 return (platform_regs_t *) (thread->k_stack.top - sizeof(platform_regs_t));
95}
96
98{
99 if (!thread)
100 {
101 pr_warn("thread is null, cannot dump its stack");
102 return;
103 }
104
105 if (thread->state != THREAD_STATE_BLOCKED)
106 {
107 pr_emph("thread %pt is not blocked, cannot dump stack", thread);
108 return;
109 }
110
111 ptr_t *rbp_ptr = (ptr_t *) thread->k_stack.head;
112 rbp_ptr += 6; // 6 registers pushed by x86_context_switch_impl
113 x86_dump_stack_at(*rbp_ptr, false);
114}
115
117{
118 switch (syscall)
119 {
121 {
122 pr_dinfo2(syscall, "enabling IOPL for thread %pt", current_thread);
123 current_process->platform_options.iopl = true;
125 return 0;
126 }
128 {
129 pr_dinfo2(syscall, "disabling IOPL for thread %pt", current_thread);
130 current_process->platform_options.iopl = false;
132 return 0;
133 }
135 {
136 current_thread->platform_options.fs_base = arg1;
138 return 0;
139 }
141 {
142 current_thread->platform_options.gs_base = arg1;
143 // x86_update_current_gsbase();
144 MOS_UNIMPLEMENTED("set_gs_base");
145 return 0;
146 }
147 default:
148 {
149 pr_warn("unknown arch-specific syscall %llu", syscall);
150 return -1;
151 }
152 }
153}
154
162
164{
165 current_thread->u_stack.head = regs->sp - 128;
166
167 // backup previous frame
168 stack_push_val(&current_thread->u_stack, *regs);
169 stack_push_val(&current_thread->u_stack, *sigreturn_data);
170
171 // Set up the new context
172 auto new_regs = mos::make_shared<platform_regs_t>(regs);
173 // *new_regs = *regs;
174
175 new_regs->ip = (ptr_t) sa->handler;
176 stack_push_val(&current_thread->u_stack, (ptr_t) sa->sa_restorer); // the return address
177
178 new_regs->di = sigreturn_data->signal; // arg1
179 new_regs->sp = current_thread->u_stack.head;
180
181 return new_regs;
182}
183
185{
186 current_thread->u_stack.head = (ptr_t) sp;
187 sigreturn_data_t data;
188 platform_regs_t regs;
189 stack_pop_val(&current_thread->u_stack, data);
190 stack_pop_val(&current_thread->u_stack, regs);
191
192 signal_on_returned(&data);
194}
195
197{
198 rtc_read_time(time);
199}
200
202{
203 *timestamp = 0;
204}
205
207{
208 pr_emph("General Purpose Registers:\n"
209 " RAX: " PTR_FMT " RBX: " PTR_FMT " RCX: " PTR_FMT " RDX: " PTR_FMT "\n"
210 " RSI: " PTR_FMT " RDI: " PTR_FMT " RBP: " PTR_FMT " RSP: " PTR_FMT "\n"
211 " R8: " PTR_FMT " R9: " PTR_FMT " R10: " PTR_FMT " R11: " PTR_FMT "\n"
212 " R12: " PTR_FMT " R13: " PTR_FMT " R14: " PTR_FMT " R15: " PTR_FMT "\n"
213 " IP: " PTR_FMT "\n"
214 "Context:\n"
215 " EFLAGS: " PTR_FMT "\n"
216 " Instruction: 0x%lx:" PTR_FMT "\n"
217 " Stack: 0x%lx:" PTR_FMT,
218 frame->ax, frame->bx, frame->cx, frame->dx, //
219 frame->si, frame->di, frame->bp, frame->sp, //
220 frame->r8, frame->r9, frame->r10, frame->r11, //
221 frame->r12, frame->r13, frame->r14, frame->r15, //
222 frame->ip, //
223 frame->eflags, //
224 frame->cs, frame->ip, //
225 frame->ss, frame->sp //
226 );
227}
228
230{
231 regs->ax = syscall_nr;
232 regs->ip -= 2; // replay the 'syscall' or 'int 0x88' instruction
233}
234
236{
237 regs->ax = result;
238}
void lapic_interrupt(u8 vec, u8 dest, lapic_delivery_mode_t delivery_mode, lapic_dest_mode_t dest_mode, lapic_shorthand_t shorthand)
Definition lapic.cpp:111
@ APIC_DELIVER_MODE_NORMAL
Definition apic.hpp:11
@ LAPIC_SHORTHAND_NONE
Definition apic.hpp:28
@ LAPIC_SHORTHAND_ALL_EXCLUDING_SELF
Definition apic.hpp:31
@ LAPIC_DEST_MODE_PHYSICAL
Definition apic.hpp:22
#define MOS_UNIMPLEMENTED(content)
Definition assert.hpp:9
#define MOS_PAGE_SIZE
Definition autoconf.h:6
void x86_set_fsbase(Thread *thread)
Definition context.cpp:146
should_inline u64 rdtsc(void)
Definition delays.hpp:8
#define stack_pop_val(stack, val)
Definition stack.hpp:35
#define stack_push_val(stack, val)
Definition stack.hpp:26
void signal_on_returned(sigreturn_data_t *supplimentary_data)
Return from a signal handler.
Definition signal.cpp:299
ipi_type_t
The type of IPI to send.
Definition ipi.hpp:13
#define TARGET_CPU_ALL
Definition ipi.hpp:22
#define __maybe_unused
Definition mos_global.h:33
shared_ptr< T > make_shared(Args &&...args)
#define PER_CPU_DECLARE(type, name)
Definition platform.hpp:26
#define current_thread
Definition platform.hpp:33
#define per_cpu(var)
Definition platform.hpp:28
char datetime_str_t[32]
Definition platform.hpp:167
@ THREAD_STATE_BLOCKED
thread is blocked by a wait condition
Definition platform.hpp:47
#define current_process
Definition platform.hpp:34
#define pgd_pfn(pgd)
Definition pml_types.hpp:93
should_inline void port_outw(x86_port_t port, u16 value)
Definition port.hpp:36
#define pr_warn(fmt,...)
Definition printk.hpp:38
#define pr_emph(fmt,...)
Definition printk.hpp:37
#define pr_dinfo2(feat, fmt,...)
Definition printk.hpp:27
void rtc_read_time(timeval_t *time)
Definition rtc.cpp:35
mos::shared_ptr< T > ptr
pgd_t pgd
Definition platform.hpp:64
downwards_stack_t k_stack
kernel-mode stack
thread_state_t state
thread state
__sighandler handler
void(* sa_restorer)(void)
signal_t signal
Definition signal.hpp:68
int snprintf(char *__restrict str, size_t size, const char *__restrict format,...)
Definition mos_stdio.cpp:16
uintn reg_t
Definition types.h:47
unsigned int u32
Definition types.h:17
#define PTR_FMT
Definition types.h:29
unsigned long ptr_t
Definition types.h:21
unsigned long long u64
Definition types.h:19
unsigned char u8
Definition types.h:15
#define x86_cpuid(return_reg, leaf, subleaf)
Definition cpu.hpp:28
#define x86_cpu_set_cr3(val)
Definition cpu.hpp:46
should_inline void x86_cpu_invlpg_all(void)
Definition cpu.hpp:54
should_inline void x86_cpu_invlpg(ptr_t addr)
Definition cpu.hpp:49
should_inline void x86_cpu_halt(void)
Definition cpu.hpp:22
@ X86_SYSCALL_SET_FS_BASE
@ X86_SYSCALL_SET_GS_BASE
@ X86_SYSCALL_IOPL_DISABLE
@ X86_SYSCALL_IOPL_ENABLE
#define IPI_BASE
void x86_interrupt_return_impl(const platform_regs_t *regs)
void x86_dump_stack_at(ptr_t this_frame, bool can_access_vmaps)
platform_regs_t * platform_thread_regs(Thread *thread)
void platform_interrupt_disable(void)
void platform_get_time(timeval_t *time)
u32 platform_current_cpu_id(void)
u64 platform_get_timestamp()
void platform_dump_regs(const platform_regs_t *frame)
void platform_interrupt_enable(void)
void platform_switch_mm(const MMContext *mm)
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_dump_thread_kernel_stack(const Thread *thread)
void platform_invalidate_tlb(ptr_t vaddr)
ptr< platform_regs_t > platform_setup_signal_handler_regs(const platform_regs_t *regs, const sigreturn_data_t *sigreturn_data, const sigaction_t *sa)
void platform_ipi_send(u8 target, ipi_type_t type)
datetime_str_t * platform_get_datetime_str(void)
void platform_syscall_store_retval(platform_regs_t *regs, reg_t result)
void platform_cpu_idle(void)
void platform_halt_cpu(void)
void platform_get_unix_timestamp(u64 *timestamp)
u64 platform_arch_syscall(u64 syscall, u64 __maybe_unused arg1, u64 __maybe_unused arg2, u64 __maybe_unused arg3, u64 __maybe_unused arg4)