ableos/ableos/src/scratchpad.rs

310 lines
8.3 KiB
Rust

use crate::arch::drivers::sysinfo::master;
use crate::arch::interrupts::{reset_pit_for_cpu, set_pit_2};
use crate::image::mono_bitmap::bruh;
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
use crate::time::fetch_time;
use crate::{
arch::shutdown, filesystem::FILE_SYSTEM, rhai_shell::KEYBUFF, vterm::Term,
wasm_jumploader::run_program,
};
use acpi::{AcpiTables, PlatformInfo};
use cpuio::{inb, outb};
use ext2::fs::sync::{DirectoryEntry, Synced};
use ext2::{fs::Ext2, sector::Size1024};
use genfs::{Fs, OpenOptions};
use kernel::allocator::ALLOCATOR;
use spin::Lazy;
use x86_64::instructions::interrupts::{disable, enable};
pub const BANNER_WIDTH: &str =
"================================================================================";
// TODO: move to a better place
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct AcpiStruct {}
impl acpi::AcpiHandler for AcpiStruct {
unsafe fn map_physical_region<T>(
&self,
physical_address: usize,
size: usize,
) -> acpi::PhysicalMapping<Self, T> {
info!("PHYS ADDR: {:?}", physical_address);
info!("Size: {:?}", size);
todo!("map_physical_region");
}
fn unmap_physical_region<T>(_region: &acpi::PhysicalMapping<Self, T>) {
todo!("unmap_physical_region");
}
}
pub static TERM: Lazy<spin::Mutex<Term>> = Lazy::new(|| spin::Mutex::new(Term::new()));
#[derive(Debug)]
pub struct Path {
pub path: Vec<String>,
}
impl Path {
pub fn new(path: String) -> Self {
let mut path_vec_string = vec![];
for part in path.split(&['\\', '/'][..]) {
path_vec_string.push(part.to_string());
}
Path {
path: path_vec_string,
}
}
}
/// Experimental scratchpad for testing.
pub fn scratchpad() {
// bruh();
// panic!(":>");
println!("\0RED\0OHNO\0RESET\0");
// bruh();
disable();
let tick_time = fetch_time();
let allocator = ALLOCATOR.lock();
let size = allocator.size();
let used = allocator.used();
drop(allocator);
enable();
println!(
"{}
,-------. OS: \0BLUE\0AbleOS\0RESET\0
,'\\ _ _`. Host: None
/ \\)_)-)_)-\\ Kernel: \0RED\0AKern-{}-v{}\0RESET\0
: : Uptime: {}
\\ / Packages: None
\\ / Shell: BuiltinShell
`. ,' Resolution: 640x480
`. ,' Terminal: VGABuffer
`.,' CPU: {}
/\\`. ,-._ GPU: VGA Compatible
`-' Memory: {}/{}
{}",
// include_str!("../assets/balloon.txt"),
// kstate.hostname,
BANNER_WIDTH,
RELEASE_TYPE,
KERNEL_VERSION,
tick_time,
master().unwrap().brand_string().unwrap(),
// "",
// mem
used,
size,
BANNER_WIDTH
);
real_shell();
}
pub fn acpi() {
let acpi_handler = AcpiStruct {};
let _table;
unsafe {
_table = AcpiTables::search_for_rsdp_bios(acpi_handler);
}
match _table.unwrap().platform_info().unwrap() {
PlatformInfo {
power_profile,
interrupt_model,
..
} => {
info!("{:?}", power_profile);
info!("{:?}", interrupt_model);
// info!("{:?}", processor_info.unwrap());
// info!("{:?}", pm_timer.unwrap());
}
}
}
pub fn real_shell() {
let prompt = "-> ";
let _current_dir = "/".to_string();
let current_user = "able".to_string();
let mut buf = String::new();
print!("{}", prompt);
// panic!(":<");
loop {
match x86_64::instructions::interrupts::without_interrupts(|| KEYBUFF.lock().pop()) {
Some('\n') => {
// panic!();
println!();
// match engine.eval_with_scope::<rhai::Dynamic>(&mut scope, &buf) {
// Ok(o) => println!("{o}"),
// Err(e) => println!("Eval error: {e}"),
// };
if !buf.is_empty() {
command_parser(current_user.clone(), buf.clone());
}
buf.clear();
print!("{}", prompt);
}
Some('\u{8}') => {
print!("\u{8}");
trace!("");
buf.pop();
}
Some('\u{0009}') => {
buf.push(' ');
buf.push(' ');
buf.push(' ');
buf.push(' ');
}
Some(chr) => {
buf.push(chr);
print!("{}", chr);
}
None => {
// trace!("{}", buf);
}
}
}
}
pub fn command_parser(user: String, command: String) {
let fs = &*FILE_SYSTEM.lock();
let mut iter = command.split_whitespace();
// TODO: update the open() function to take either a ableOS path or a b"/" type path
let current_path = Path::new("/home/able".to_string());
trace!("Current path: {:?}", current_path);
let current_path = b"/home/able/";
let bin_name = iter.next().unwrap();
match bin_name {
// note: able asked for rhaish to stay in the repo but will be removed
// in the future so just comment it out for now
// "rhai" => {
// drop(fs);
// shell();
// }
"list" | "ls" => {
for dir_entry in list_files_in_dir(fs, current_path) {
println!("{}", dir_entry.file_name_string());
}
}
"echo" => {
echo_file(iter.next().unwrap().to_string(), fs);
}
"quit" => shutdown(),
_ => {
let mut options = OpenOptions::new();
options.read(true);
let file = {
let path = format!("/home/{user}/bins/{bin_name}.wasm");
if let Ok(file) = fs.open(&path.as_bytes(), &options) {
file
} else {
let path = format!("/shared/bins/{bin_name}.wasm");
if let Ok(file) = fs.open(&path.as_bytes(), &options) {
file
} else {
let path = format!("/system/bins/{bin_name}.wasm");
match fs.open(&path.as_bytes(), &options) {
Ok(file) => file,
Err(error) => {
trace!("{:?}", error);
println!("No such binary: {}", bin_name);
error!("No such binary: {}", bin_name);
return;
}
}
}
}
};
let mut binary = vec![];
file.read_to_end(&mut binary).unwrap();
let args = iter.collect::<Vec<&str>>();
println!("{:?}", args);
run_program(&binary);
}
}
}
pub fn sound(n_frequency: u32) {
let div: u32;
let tmp: u8;
div = 1193180 / n_frequency;
unsafe {
outb(0xb6, 0x43);
set_pit_2(div);
// And play the sound using the PC speaker
tmp = inb(0x61);
if tmp != (tmp | 3) {
outb(tmp | 3, 0x61);
}
}
}
pub fn sound_off() {
unsafe {
let tmp = inb(0x61) & 0xFC;
outb(tmp, 0x61)
};
reset_pit_for_cpu();
}
pub fn list_files_in_dir(
fs: &Synced<Ext2<Size1024, Vec<u8>>>,
_path: &[u8],
) -> Vec<DirectoryEntry> {
let mut entry_list = vec![];
let dirr = fs.read_dir(b"/").unwrap();
for dir_entry in dirr {
entry_list.push(dir_entry.unwrap());
}
entry_list
}
pub static CURRENT_DIR: Lazy<spin::Mutex<String>> = Lazy::new(|| spin::Mutex::new("/".to_string()));
pub fn echo_file(path: String, fs: &Synced<Ext2<Size1024, Vec<u8>>>) {
let mut current_dir = CURRENT_DIR.lock();
current_dir.push_str(&path);
let file = fs
.open(current_dir.as_bytes(), OpenOptions::new().read(true))
.unwrap();
if file.is_dir() {
// println!("{} is a directory", path);
} else {
let mut file_contents = Vec::new();
let _ret = file.read_to_end(&mut file_contents).unwrap();
let file_contents_str = String::from_utf8_lossy(&file_contents);
println!("{}", file_contents_str);
}
}