Skip to main content

hermit/syscalls/
system.rs

1#[cfg(all(target_arch = "x86_64", feature = "bga"))]
2use core::ffi::c_int;
3
4use crate::arch::mm::paging::{BasePageSize, PageSize};
5
6/// Returns the base page size, in bytes, of the current system.
7#[hermit_macro::system]
8#[unsafe(no_mangle)]
9pub extern "C" fn sys_getpagesize() -> i32 {
10	BasePageSize::SIZE.try_into().unwrap()
11}
12
13// Writes the scancodes from the keyboard buffer into the provided buffer.
14// If 'nonblock' is true, it will return immediately if there are no scancodes available,
15// otherwise it will block until at least one scancode is available.
16// Returns the number of bytes written to the buffer,
17// or a negative error code on failure.
18#[cfg(all(target_arch = "x86_64", feature = "pc-keyboard"))]
19#[hermit_macro::system]
20#[unsafe(no_mangle)]
21pub unsafe extern "C" fn sys_read_keyboard(buffer: *mut u8, size: usize, nonblock: bool) -> isize {
22	if buffer.is_null() {
23		return -(crate::errno::Errno::Fault as isize);
24	}
25	if size == 0 {
26		return 0;
27	}
28	// SAFETY: We have to trust the user input, because we are a unikernel and if the user wants to crash the program
29	// they are free to do so.
30	let buffer_slice: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(buffer, size) };
31	let result = crate::arch::kernel::pc_keyboard::pop_scancodes(buffer_slice, nonblock);
32	if result == 0 && nonblock {
33		-(crate::errno::Errno::Again as isize)
34	} else {
35		result as isize
36	}
37}
38#[cfg(all(target_arch = "x86_64", feature = "bga"))]
39#[repr(C)]
40pub struct FramebufferInfo {
41	pub framebuffer: *mut u8,
42	pub width: u32,
43	pub height: u32,
44	pub bpp: u32,
45}
46
47/// Returns the framebuffer information for the video output device.
48/// Returns 0 on success, or -1 if the BGA device has not yet been initialized.
49#[cfg(all(target_arch = "x86_64", feature = "bga"))]
50#[hermit_macro::system]
51#[unsafe(no_mangle)]
52pub unsafe extern "C" fn sys_get_framebuffer_info(info: *mut FramebufferInfo) -> c_int {
53	if info.is_null() {
54		return -1;
55	};
56
57	let bga_info = crate::arch::kernel::bga::get_framebuffer_info();
58	match bga_info {
59		Some(bga_info) => {
60			let info_c = FramebufferInfo {
61				framebuffer: core::ptr::with_exposed_provenance_mut(
62					bga_info.framebuffer.as_usize(),
63				),
64				width: u32::from(bga_info.width),
65				height: u32::from(bga_info.height),
66				bpp: u32::from(bga_info.bpp),
67			};
68			unsafe {
69				info.write(info_c);
70			}
71			0
72		}
73		None => -1,
74	}
75}
76
77#[cfg(all(target_arch = "x86_64", feature = "bga"))]
78#[hermit_macro::system]
79#[unsafe(no_mangle)]
80pub unsafe extern "C" fn sys_set_resolution(width: u16, height: u16, bpp: u16) -> c_int {
81	crate::arch::kernel::bga::set_resolution(width, height, bpp);
82	0
83}