MOS Source Code
Loading...
Searching...
No Matches
x86_platform_api.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
4#include "mos/platform/platform_defs.h"
5#include "mos/tasks/signal.h"
7
10#include <mos/mm/physical/pmm.h>
11#include <mos/mos_global.h>
13#include <mos/platform_syscall.h>
14#include <mos/syslog/printk.h>
15#include <mos/tasks/process.h>
17#include <mos/x86/cpu/cpu.h>
18#include <mos/x86/delays.h>
25#include <mos_stdio.h>
26#include <mos_stdlib.h>
27#include <mos_string.h>
28
29[[noreturn]] void platform_shutdown(void)
30{
32 port_outw(0x604, 0x2000);
34 while (1)
35 ;
36}
37
39{
41}
42
44{
45 if (!vaddr)
47 else
48 x86_cpu_invlpg(vaddr);
49}
50
52{
53 return x86_cpuid(b, 1, 0) >> 24;
54}
55
57{
58 __asm__ volatile("hlt");
59}
60
62{
63 return rdtsc();
64}
65
67{
68 static PER_CPU_DECLARE(datetime_str_t, datetime_str);
69
70 timeval_t time;
71 platform_get_time(&time);
72 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);
73 return per_cpu(datetime_str);
74}
75
77{
78 __asm__ volatile("sti");
79}
80
82{
83 __asm__ volatile("cli");
84}
85
90
92{
93 return (platform_regs_t *) (thread->k_stack.top - sizeof(platform_regs_t));
94}
95
97{
98 if (!thread)
99 {
100 pr_warn("thread is null, cannot dump its stack");
101 return;
102 }
103
104 if (thread->state != THREAD_STATE_BLOCKED)
105 {
106 pr_emph("thread %pt is not blocked, cannot dump stack", (void *) thread);
107 return;
108 }
109
110 ptr_t *rbp_ptr = (ptr_t *) thread->k_stack.head;
111 rbp_ptr += 6; // 6 registers pushed by x86_context_switch_impl
112 x86_dump_stack_at(*rbp_ptr, false);
113}
114
116{
118}
119
121{
122 switch (syscall)
123 {
125 {
126 pr_dinfo2(syscall, "enabling IOPL for thread %pt", (void *) current_thread);
127 current_process->platform_options.iopl = true;
129 return 0;
130 }
132 {
133 pr_dinfo2(syscall, "disabling IOPL for thread %pt", (void *) current_thread);
134 current_process->platform_options.iopl = false;
136 return 0;
137 }
139 {
140 current_thread->platform_options.fs_base = arg1;
142 return 0;
143 }
145 {
146 current_thread->platform_options.gs_base = arg1;
147 // x86_update_current_gsbase();
148 MOS_UNIMPLEMENTED("set_gs_base");
149 return 0;
150 }
151 default:
152 {
153 pr_warn("unknown arch-specific syscall %llu", syscall);
154 return -1;
155 }
156 }
157}
158
166
167void platform_jump_to_signal_handler(const platform_regs_t *regs, const sigreturn_data_t *sigreturn_data, const sigaction_t *sa)
168{
169 current_thread->u_stack.head = regs->sp - 128;
170
171 // backup previous frame
172 stack_push_val(&current_thread->u_stack, *regs);
173 stack_push_val(&current_thread->u_stack, *sigreturn_data);
174
175 // Set up the new context
176 platform_regs_t ret_regs = *regs;
177 ret_regs.ip = (ptr_t) sa->handler;
178 stack_push_val(&current_thread->u_stack, (ptr_t) sa->sa_restorer); // the return address
179
180 ret_regs.di = sigreturn_data->signal; // arg1
181 ret_regs.sp = current_thread->u_stack.head;
182 x86_interrupt_return_impl(&ret_regs);
183}
184
186{
187 current_thread->u_stack.head = (ptr_t) sp;
188 sigreturn_data_t data;
189 platform_regs_t regs;
190 stack_pop_val(&current_thread->u_stack, data);
191 stack_pop_val(&current_thread->u_stack, regs);
192
193 signal_on_returned(&data);
195}
196
198{
199 rtc_read_time(time);
200}
201
203{
204 pr_emph("General Purpose Registers:\n"
205 " RAX: " PTR_FMT " RBX: " PTR_FMT " RCX: " PTR_FMT " RDX: " PTR_FMT "\n"
206 " RSI: " PTR_FMT " RDI: " PTR_FMT " RBP: " PTR_FMT " RSP: " PTR_FMT "\n"
207 " R8: " PTR_FMT " R9: " PTR_FMT " R10: " PTR_FMT " R11: " PTR_FMT "\n"
208 " R12: " PTR_FMT " R13: " PTR_FMT " R14: " PTR_FMT " R15: " PTR_FMT "\n"
209 " IP: " PTR_FMT "\n"
210 "Context:\n"
211 " EFLAGS: " PTR_FMT "\n"
212 " Instruction: 0x%lx:" PTR_FMT "\n"
213 " Stack: 0x%lx:" PTR_FMT,
214 frame->ax, frame->bx, frame->cx, frame->dx, //
215 frame->si, frame->di, frame->bp, frame->sp, //
216 frame->r8, frame->r9, frame->r10, frame->r11, //
217 frame->r12, frame->r13, frame->r14, frame->r15, //
218 frame->ip, //
219 frame->eflags, //
220 frame->cs, frame->ip, //
221 frame->ss, frame->sp //
222 );
223}
224
226{
227 regs->ax = syscall_nr;
228 regs->ip -= 2; // replay the 'syscall' or 'int 0x88' instruction
229}
230
232{
233 regs->ax = result;
234}
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.c:111
@ APIC_DELIVER_MODE_NORMAL
Definition apic.h:11
@ LAPIC_SHORTHAND_NONE
Definition apic.h:28
@ LAPIC_SHORTHAND_ALL_EXCLUDING_SELF
Definition apic.h:31
@ LAPIC_DEST_MODE_PHYSICAL
Definition apic.h:22
#define MOS_UNIMPLEMENTED(content)
Definition assert.h:10
#define MOS_PAGE_SIZE
Definition autoconf.h:6
void x86_set_fsbase(thread_t *thread)
Definition context.c:149
should_inline u64 rdtsc(void)
Definition delays.h:8
#define stack_pop_val(stack, val)
Definition stack.h:35
#define stack_push_val(stack, val)
Definition stack.h:26
void signal_on_returned(sigreturn_data_t *supplimentary_data)
Return from a signal handler.
Definition signal.c:295
ipi_type_t
The type of IPI to send.
Definition ipi.h:12
#define TARGET_CPU_ALL
Definition ipi.h:21
#define __maybe_unused
Definition mos_global.h:33
int snprintf(char *__restrict str, size_t size, const char *__restrict format,...)
Definition mos_stdio.c:16
struct _platform_regs platform_regs_t
Definition platform.h:86
#define PER_CPU_DECLARE(type, name)
Definition platform.h:23
#define current_thread
Definition platform.h:30
#define per_cpu(var)
Definition platform.h:25
char datetime_str_t[32]
Definition platform.h:184
@ THREAD_STATE_BLOCKED
thread is blocked by a wait condition
Definition platform.h:65
#define current_process
Definition platform.h:31
#define pgd_pfn(pgd)
Definition pml_types.h:90
should_inline void port_outw(x86_port_t port, u16 value)
Definition port.h:36
#define pr_warn(fmt,...)
Definition printk.h:38
#define pr_emph(fmt,...)
Definition printk.h:37
#define pr_dinfo2(feat, fmt,...)
Definition printk.h:27
void rtc_read_time(timeval_t *time)
Definition rtc.c:36
pgd_t pgd
Definition platform.h:82
reg_t sp
Definition cpu.h:10
__sighandler handler
void(* sa_restorer)(void)
signal_t signal
Definition signal.h:66
downwards_stack_t k_stack
kernel-mode stack
Definition task_types.h:85
thread_state_t state
thread state
Definition task_types.h:83
uintn reg_t
Definition types.h:51
unsigned int u32
Definition types.h:21
#define PTR_FMT
Definition types.h:33
unsigned long ptr_t
Definition types.h:25
unsigned long long u64
Definition types.h:23
unsigned char u8
Definition types.h:19
#define x86_cpuid(return_reg, leaf, subleaf)
Definition cpu.h:28
#define x86_cpu_set_cr3(val)
Definition cpu.h:46
should_inline void x86_cpu_invlpg_all(void)
Definition cpu.h:54
should_inline void x86_cpu_invlpg(ptr_t addr)
Definition cpu.h:49
should_inline void x86_cpu_halt(void)
Definition cpu.h: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)
void platform_interrupt_disable(void)
void platform_get_time(timeval_t *time)
u32 platform_current_cpu_id(void)
void platform_return_to_userspace(platform_regs_t *regs)
u64 platform_get_timestamp()
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_dump_thread_kernel_stack(const thread_t *thread)
void platform_shutdown(void)
void platform_jump_to_signal_handler(const platform_regs_t *regs, const sigreturn_data_t *sigreturn_data, const sigaction_t *sa)
platform_regs_t * platform_thread_regs(const thread_t *thread)
void platform_switch_mm(const mm_context_t *mm)
void platform_invalidate_tlb(ptr_t vaddr)
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)
u64 platform_arch_syscall(u64 syscall, u64 __maybe_unused arg1, u64 __maybe_unused arg2, u64 __maybe_unused arg3, u64 __maybe_unused arg4)
void platform_dump_regs(platform_regs_t *frame)