1#![no_std]
2
3mod heap;
4
5extern crate alloc;
6
7use tg_console::log;
8
9pub use tg_console::{print, println};
10pub use tg_syscall::*;
11
12#[no_mangle]
13#[link_section = ".text.entry"]
14pub extern "C" fn _start() -> ! {
15 tg_console::init_console(&Console);
16 tg_console::set_log_level(option_env!("LOG"));
17 heap::init();
18
19 extern "C" {
20 fn main() -> i32;
21 }
22
23 exit(unsafe { main() });
25 unreachable!()
26}
27
28#[panic_handler]
29fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
30 let err = panic_info.message();
31 if let Some(location) = panic_info.location() {
32 log::error!("Panicked at {}:{}, {err}", location.file(), location.line());
33 } else {
34 log::error!("Panicked: {err}");
35 }
36 exit(1);
37 unreachable!()
38}
39
40pub fn getchar() -> u8 {
41 let mut c = [0u8; 1];
42 read(STDIN, &mut c);
43 c[0]
44}
45
46struct Console;
47
48impl tg_console::Console for Console {
49 #[inline]
50 fn put_char(&self, c: u8) {
51 tg_syscall::write(STDOUT, &[c]);
52 }
53
54 #[inline]
55 fn put_str(&self, s: &str) {
56 tg_syscall::write(STDOUT, s.as_bytes());
57 }
58}
59
60pub fn sleep(period_ms: usize) {
61 let mut time: TimeSpec = TimeSpec::ZERO;
62 clock_gettime(ClockId::CLOCK_MONOTONIC, &mut time as *mut _ as _);
63 let time = time + TimeSpec::from_millsecond(period_ms);
64 loop {
65 let mut now: TimeSpec = TimeSpec::ZERO;
66 clock_gettime(ClockId::CLOCK_MONOTONIC, &mut now as *mut _ as _);
67 if now > time {
68 break;
69 }
70 sched_yield();
71 }
72}
73
74pub fn get_time() -> isize {
75 let mut time: TimeSpec = TimeSpec::ZERO;
76 clock_gettime(ClockId::CLOCK_MONOTONIC, &mut time as *mut _ as _);
77 (time.tv_sec * 1000 + time.tv_nsec / 1_000_000) as isize
78}
79
80pub fn trace_read(ptr: *const u8) -> Option<u8> {
81 let ret = trace(0, ptr as usize, 0);
82 if ret >= 0 && ret <= 255 {
83 Some(ret as u8)
84 } else {
85 None
86 }
87}
88
89pub fn trace_write(ptr: *const u8, value: u8) -> isize {
90 trace(1, ptr as usize, value as usize)
91}
92
93pub fn count_syscall(syscall_id: usize) -> isize {
94 trace(2, syscall_id, 0)
95}
96
97pub fn pipe_read(pipe_fd: usize, buffer: &mut [u8]) -> isize {
100 let mut total_read = 0usize;
101 let len = buffer.len();
102 loop {
103 if total_read >= len {
104 return total_read as isize;
105 }
106 let ret = read(pipe_fd, &mut buffer[total_read..]);
107 if ret == -2 {
108 sched_yield();
110 continue;
111 } else if ret == 0 {
112 return total_read as isize;
114 } else if ret < 0 {
115 return ret;
117 } else {
118 total_read += ret as usize;
119 }
120 }
121}
122
123pub fn pipe_write(pipe_fd: usize, buffer: &[u8]) -> isize {
126 let mut total_write = 0usize;
127 let len = buffer.len();
128 loop {
129 if total_write >= len {
130 return total_write as isize;
131 }
132 let ret = write(pipe_fd, &buffer[total_write..]);
133 if ret == -2 {
134 sched_yield();
136 continue;
137 } else if ret < 0 {
138 return ret;
140 } else {
141 total_write += ret as usize;
142 }
143 }
144}