[Teton] Move console/shell to rust. WIP

This commit is contained in:
Drew Galbraith 2024-08-12 11:35:54 -07:00
parent 76f8795a46
commit 18e512cf1f
17 changed files with 409 additions and 5 deletions

View file

@ -0,0 +1,9 @@
[package]
name = "teton"
version = "0.1.0"
edition = "2021"
[dependencies]
mammoth = { path = "../../lib/mammoth" }
victoriafalls = { path = "../../lib/victoriafalls" }
yellowstone = { path = "../../lib/yellowstone" }

View file

@ -0,0 +1,18 @@
use crate::framebuffer::Framebuffer;
use crate::psf::Psf;
pub struct Console {
framebuffer: Framebuffer,
psf: Psf,
}
impl Console {
pub fn new(framebuffer: Framebuffer, psf: Psf) -> Self {
Self { framebuffer, psf }
}
pub fn write_char(&self, c: char) {
let glyph = self.psf.glyph(c as u32);
self.framebuffer.draw_glyph(glyph, 0, 0)
}
}

View file

@ -0,0 +1,38 @@
use mammoth::{mem::MemoryRegion, zion::ZError};
use yellowstone::FramebufferInfo;
pub struct Framebuffer {
fb_info: FramebufferInfo,
memory_region: MemoryRegion,
}
impl Framebuffer {
pub fn from_info(fb_info: FramebufferInfo) -> Result<Self, ZError> {
let size = fb_info.height * fb_info.pitch;
let memory_region = MemoryRegion::direct_physical(fb_info.address_phys, size)?;
Ok(Self {
fb_info,
memory_region,
})
}
fn draw_pixel(&self, row: u32, col: u32, pixel: u32) {
let index = row * (self.fb_info.pitch as u32 / 4) + col;
self.memory_region.mut_slice()[index as usize] = pixel;
}
pub fn draw_glyph(&self, glyph: &[u8], row: u32, col: u32) {
let gl_width = 8;
let gl_height = 16;
for r in 0..gl_height {
for c in 0..gl_width {
if ((glyph[r] >> c) % 2) == 1 {
self.draw_pixel(row + (r as u32), col + (gl_width - c - 1), 0xFFFFFFFF);
} else {
self.draw_pixel(row + (r as u32), col + (gl_width - c - 1), 0);
}
}
}
}
}

View file

@ -0,0 +1,50 @@
#![no_std]
#![no_main]
extern crate alloc;
mod console;
mod framebuffer;
mod psf;
use mammoth::{debug, define_entry, zion::z_err_t};
define_entry!();
#[no_mangle]
extern "C" fn main() -> z_err_t {
debug!("Teton Starting");
let yellowstone = yellowstone::from_init_endpoint();
let framebuffer_info = yellowstone
.get_framebuffer_info()
.expect("Failed to get framebuffer info.");
debug!(
"FB addr {:#x}, bpp {}, width {} , height {}, pitch {}",
framebuffer_info.address_phys,
framebuffer_info.bpp,
framebuffer_info.width,
framebuffer_info.height,
framebuffer_info.pitch
);
let framebuffer = framebuffer::Framebuffer::from_info(framebuffer_info)
.expect("Failed to create framebuffer");
let psf = psf::Psf::new("/default8x16.psfu").expect("Failed to open font file.");
let console = console::Console::new(framebuffer, psf);
console.write_char('>');
/*
Terminal terminal(console);
terminal.Register();
Thread lthread = terminal.Listen();
check(lthread.Join());
*/
0
}

71
rust/sys/teton/src/psf.rs Normal file
View file

@ -0,0 +1,71 @@
use mammoth::debug;
use mammoth::zion::ZError;
use victoriafalls::file::File;
const MAGIC_HEADER: u32 = 0x864AB572;
#[repr(C)]
struct PsfHeader {
magic: u32, /* magic bytes to identify PSF */
version: u32, /* zero */
headersize: u32, /* offset of bitmaps in file, 32 */
flags: u32, /* 0 if there's no unicode table */
numglyph: u32, /* number of glyphs */
bytes_per_glyph: u32, /* size of each glyph */
height: u32, /* height in pixels */
width: u32, /* width in pixels */
}
pub struct Psf {
file: File,
header: &'static PsfHeader,
}
impl Psf {
pub fn new(path: &str) -> Result<Self, ZError> {
let file = File::open(&path)?;
let header = file
.slice(0, core::mem::size_of::<PsfHeader>())
.as_ptr()
.cast();
let psf = Self {
file,
header: unsafe { &*header },
};
psf.validate()?;
Ok(psf)
}
fn validate(&self) -> Result<(), ZError> {
if self.header.magic != MAGIC_HEADER {
debug!("PSF: Magic value: {:x}", self.header.magic);
return Err(ZError::INVALID_ARGUMENT);
}
if self.header.version != 0 {
debug!("PSF non-zero version");
return Err(ZError::INVALID_ARGUMENT);
}
if self.header.height != 0x10 {
debug!("PSF height other than 16 not handled");
return Err(ZError::UNIMPLEMENTED);
}
if self.header.width != 0x8 {
debug!("PSF width other than 8 not handled");
return Err(ZError::UNIMPLEMENTED);
}
Ok(())
}
pub fn glyph(&self, index: u32) -> &[u8] {
let offset: usize =
(self.header.headersize + (index * self.header.bytes_per_glyph)) as usize;
let len: usize = self.header.bytes_per_glyph as usize;
&self.file.slice(offset, len)
}
}