1use core::ptr::{read_volatile, write_volatile};
2
3use alloc::{
4 string::{String, ToString},
5 vec::Vec,
6};
7
8use crate::config::MAX_ARGV;
9
10#[inline(always)]
15pub fn write<T>(addr: usize, content: T) {
16 let cell = (addr) as *mut T;
17 unsafe {
18 write_volatile(cell, content);
19 }
20}
21
22#[inline(always)]
28pub fn read<T>(addr: usize) -> T {
29 let cell = (addr) as *const T;
30 unsafe { read_volatile(cell) }
31}
32
33pub unsafe fn copy_cstr_to_string(ptr: *const u8) -> Result<String, ()> {
36 const MAX_PATH_LEN: usize = 4096;
37 let mut buf: Vec<u8> = Vec::new();
38 let mut p = ptr;
39 for _ in 0..MAX_PATH_LEN {
40 let b = unsafe { core::ptr::read(p) };
42 if b == 0 {
43 return core::str::from_utf8(&buf)
44 .map(|s| s.to_string())
45 .map_err(|_| ());
46 }
47 buf.push(b);
48 p = unsafe { p.add(1) };
49 }
50 Err(())
51}
52
53pub unsafe fn ptr_array_to_vec_strings(ptrs: *const *const u8) -> Result<Vec<String>, ()> {
56 let mut out: Vec<String> = Vec::new();
57 if ptrs.is_null() {
58 return Ok(out);
59 }
60 for i in 0..MAX_ARGV {
61 let p = unsafe { *ptrs.add(i) };
62 if p.is_null() {
63 break;
64 }
65 match unsafe { crate::util::copy_cstr_to_string(p) } {
66 Ok(s) => out.push(s),
67 Err(_) => return Err(()),
68 }
69 }
70 Ok(out)
71}
72
73pub unsafe fn cstr_len(s: *const u8) -> usize {
79 let mut len = 0;
80 let mut p = s;
81 while unsafe { core::ptr::read(p) } != 0 {
82 len += 1;
83 p = unsafe { p.add(1) };
84 }
85 len
86}
87
88pub unsafe fn cstr_equal(s1: *const u8, s2: *const u8) -> bool {
95 let mut p1 = s1;
96 let mut p2 = s2;
97 loop {
98 let b1 = unsafe { core::ptr::read(p1) };
99 let b2 = unsafe { core::ptr::read(p2) };
100 if b1 != b2 {
101 return false;
102 }
103 if b1 == 0 {
104 return true;
105 }
106 p1 = unsafe { p1.add(1) };
107 p2 = unsafe { p2.add(1) };
108 }
109}
110
111pub fn cstr_copy(src: *const u8, dest: &mut [u8], len: usize) {
117 for i in 0..len {
118 let b = unsafe { core::ptr::read(src.add(i)) };
119 dest[i] = b;
120 if b == 0 {
121 break;
122 }
123 }
124}