diff --git a/os/Cargo.toml b/os/Cargo.toml index ded2765e87a806b458115c3decce58ef29ec3ee4..d8f42164ea5687b14bcb1246705e41555301d873 100644 --- a/os/Cargo.toml +++ b/os/Cargo.toml @@ -13,10 +13,8 @@ buddy_system_allocator = "0.6" bitflags = "1.2.1" xmas-elf = "0.7.0" volatile = "0.3" -#virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" } -virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "70b5850" } +virtio-drivers = { git = "https://github.com/rcore-os/virtio-drivers", rev = "4ee80e5" } easy-fs = { path = "../easy-fs" } -#virtio-input-decoder = "0.1.4" embedded-graphics = "0.7.1" tinybmp = "0.3.1" diff --git a/os/src/drivers/chardev/ns16550a.rs b/os/src/drivers/chardev/ns16550a.rs index 127a4ce191e2034d8ac366ca779fe3ba38b99744..7122cec121ca3443042ee32bc1066092c2f7b556 100644 --- a/os/src/drivers/chardev/ns16550a.rs +++ b/os/src/drivers/chardev/ns16550a.rs @@ -143,12 +143,13 @@ impl NS16550a { } pub fn read_buffer_is_empty(&self) -> bool { - self.inner.exclusive_session(|inner| inner.read_buffer.is_empty()) + self.inner + .exclusive_session(|inner| inner.read_buffer.is_empty()) } } impl CharDevice for NS16550a { - fn init(&self){ + fn init(&self) { let mut inner = self.inner.exclusive_access(); inner.ns16550a.init(); drop(inner); diff --git a/os/src/drivers/input/mod.rs b/os/src/drivers/input/mod.rs index 857f12a3e185d1a454db5a075a5c5baeb870ea7b..a9f5f0bdadf33ae0915afdf02cbeffb6e86f495f 100644 --- a/os/src/drivers/input/mod.rs +++ b/os/src/drivers/input/mod.rs @@ -16,41 +16,20 @@ struct VirtIOInputInner { struct VirtIOInputWrapper { inner: UPIntrFreeCell, - //condvars: BTreeMap, - //condvar: Arc:: , - condvar:Condvar, + condvar: Condvar, } pub trait InputDevice: Send + Sync + Any { fn read_event(&self) -> u64; fn handle_irq(&self); - // fn events(&self) -> &VecDeque; fn is_empty(&self) -> bool; } lazy_static::lazy_static!( pub static ref KEYBOARD_DEVICE: Arc = Arc::new(VirtIOInputWrapper::new(VIRTIO5)); pub static ref MOUSE_DEVICE: Arc = Arc::new(VirtIOInputWrapper::new(VIRTIO6)); - // pub static ref INPUT_CONDVAR: Arc:: = Arc::new(Condvar::new()); ); -// from virtio-drivers/src/input.rs -//const QUEUE_SIZE: u16 = 32; -// pub fn read_input_event() -> u64 { -// loop { - -// //let mut inner = self.inner.exclusive_access(); -// let kb=KEYBOARD_DEVICE.clone(); -// let evs = kb.events(); -// if let Some(event) = evs.pop_front() { -// return event; -// } else { -// let task_cx_ptr = INPUT_CONDVAR.clone().wait_no_sched(); -// drop(inner); -// schedule(task_cx_ptr); -// } -// } -// } impl VirtIOInputWrapper { pub fn new(addr: usize) -> Self { let inner = VirtIOInputInner { @@ -59,17 +38,8 @@ impl VirtIOInputWrapper { }, events: VecDeque::new(), }; - - // let mut condvars = BTreeMap::new(); - // let channels = QUEUE_SIZE; - // for i in 0..channels { - // let condvar = Condvar::new(); - // condvars.insert(i, condvar); - // } - Self { inner: unsafe { UPIntrFreeCell::new(inner) }, - //condvar: INPUT_CONDVAR.clone(), condvar: Condvar::new(), } } @@ -93,29 +63,20 @@ impl InputDevice for VirtIOInputWrapper { } } - // fn events(&self) -> &VecDeque { - // &self.inner.exclusive_access().events - // } - fn handle_irq(&self) { let mut count = 0; let mut result = 0; - let mut key = 0; self.inner.exclusive_session(|inner| { inner.virtio_input.ack_interrupt(); - while let Some((token, event)) = inner.virtio_input.pop_pending_event() { + while let Some(event) = inner.virtio_input.pop_pending_event() { count += 1; - key = token; result = (event.event_type as u64) << 48 | (event.code as u64) << 32 | (event.value) as u64; inner.events.push_back(result); - // for test - //println!("[KERN] inputdev_handle_irq: event: {:x}", result); } }); if count > 0 { - //self.condvars.get(&key).unwrap().signal(); self.condvar.signal(); }; } diff --git a/os/src/fs/pipe.rs b/os/src/fs/pipe.rs index 531eec491b9829cb12234dbb6762b97ea06f8ce9..d10dc33b73344cb91d8c6ecb5ab7630f62a0c988 100644 --- a/os/src/fs/pipe.rs +++ b/os/src/fs/pipe.rs @@ -170,4 +170,4 @@ impl File for Pipe { } } } -} \ No newline at end of file +} diff --git a/os/src/main.rs b/os/src/main.rs index 7e5a20ac9f13666e1d8ff31dd83cc8770938503e..1103c57009db246ef831f468eada0840ca5cac21 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -29,7 +29,6 @@ mod trap; use crate::drivers::chardev::CharDevice; use crate::drivers::chardev::UART; -//use syscall::create_desktop; //for test core::arch::global_asm!(include_str!("entry.asm")); @@ -59,7 +58,6 @@ pub fn rust_main() -> ! { UART.init(); println!("KERN: init gpu"); let _gpu = GPU_DEVICE.clone(); - //let _input_condvar = INPUT_CONDVAR.clone(); println!("KERN: init keyboard"); let _keyboard = KEYBOARD_DEVICE.clone(); println!("KERN: init mouse"); @@ -70,7 +68,6 @@ pub fn rust_main() -> ! { timer::set_next_trigger(); board::device_init(); fs::list_apps(); - //gui::init_paint(); task::add_initproc(); *DEV_NON_BLOCKING_ACCESS.exclusive_access() = true; task::run_tasks(); diff --git a/os/src/mm/address.rs b/os/src/mm/address.rs index 8792f625b9870ae0c53da6de96ebdfcb6e2fc1ab..cf147a080a36559e1c4540aa86a10bd1b2a8ad26 100644 --- a/os/src/mm/address.rs +++ b/os/src/mm/address.rs @@ -260,4 +260,3 @@ where } } pub type VPNRange = SimpleRange; -pub type PPNRange = SimpleRange; diff --git a/os/src/mm/frame_allocator.rs b/os/src/mm/frame_allocator.rs index 275fb1747eac7877e1dca7011681bc57f204a30a..1ecfe9931b991a31763d4898ca17d8d0fe57bf88 100644 --- a/os/src/mm/frame_allocator.rs +++ b/os/src/mm/frame_allocator.rs @@ -7,7 +7,6 @@ use lazy_static::*; pub struct FrameTracker { pub ppn: PhysPageNum, - pub nodrop: bool, } impl FrameTracker { @@ -17,10 +16,7 @@ impl FrameTracker { for i in bytes_array { *i = 0; } - Self { ppn, nodrop: false } - } - pub fn new_noalloc(ppn: PhysPageNum) -> Self { - Self { ppn, nodrop: true } + Self { ppn } } } @@ -32,9 +28,6 @@ impl Debug for FrameTracker { impl Drop for FrameTracker { fn drop(&mut self) { - if self.nodrop { - return; - } frame_dealloc(self.ppn); } } diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index bec0b93482787b4af41f3358b4b65a7dcca19a19..7cdd394a9eca07b85a2feb3345a91988f429e14a 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -1,7 +1,7 @@ use super::{frame_alloc, FrameTracker}; use super::{PTEFlags, PageTable, PageTableEntry}; use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; -use super::{StepByOne, VPNRange, PPNRange}; +use super::{StepByOne, VPNRange}; use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE}; use crate::sync::UPIntrFreeCell; use alloc::collections::BTreeMap; @@ -71,17 +71,16 @@ impl MemorySet { self.areas.remove(idx); } } - fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) { + /// Add a new MapArea into this MemorySet. + /// Assuming that there are no conflicts in the virtual address + /// space. + pub fn push(&mut self, mut map_area: MapArea, data: Option<&[u8]>) { map_area.map(&mut self.page_table); if let Some(data) = data { map_area.copy_data(&mut self.page_table, data); } self.areas.push(map_area); } - pub fn push_noalloc(&mut self, mut map_area: MapArea, ppn_range: PPNRange) { - map_area.map_noalloc(&mut self.page_table, ppn_range); - self.areas.push(map_area); - } /// Mention that trampoline is not collected by areas. fn map_trampoline(&mut self) { self.page_table.map( @@ -290,8 +289,10 @@ impl MapArea { ppn = frame.ppn; self.data_frames.insert(vpn, frame); } - MapType::Noalloc => { - panic!("Noalloc should not be mapped"); + MapType::Linear(pn_offset) => { + // check for sv39 + assert!(vpn.0 < (1usize << 27)); + ppn = PhysPageNum((vpn.0 as isize + pn_offset) as usize); } } let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap(); @@ -308,14 +309,6 @@ impl MapArea { self.map_one(page_table, vpn); } } - pub fn map_noalloc(&mut self, page_table: &mut PageTable,ppn_range:PPNRange) { - for (vpn,ppn) in core::iter::zip(self.vpn_range,ppn_range) { - self.data_frames.insert(vpn, FrameTracker::new_noalloc(ppn)); - let pte_flags = PTEFlags::from_bits(self.map_perm.bits).unwrap(); - page_table.map(vpn, ppn, pte_flags); - } - } - pub fn unmap(&mut self, page_table: &mut PageTable) { for vpn in self.vpn_range { self.unmap_one(page_table, vpn); @@ -349,7 +342,8 @@ impl MapArea { pub enum MapType { Identical, Framed, - Noalloc, + /// offset of page num + Linear(isize), } bitflags! { diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index 9482a30de872eb145bcf28854c858ce83f00a4ae..77d62f494c40412f165ef82df08a94adc18e953e 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -4,11 +4,11 @@ mod heap_allocator; mod memory_set; mod page_table; -pub use address::{VPNRange, PPNRange}; +pub use address::VPNRange; pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; pub use frame_allocator::{frame_alloc, frame_dealloc, FrameTracker}; pub use memory_set::remap_test; -pub use memory_set::{kernel_token, MapPermission, MemorySet, MapArea, MapType, KERNEL_SPACE}; +pub use memory_set::{kernel_token, MapArea, MapPermission, MapType, MemorySet, KERNEL_SPACE}; use page_table::PTEFlags; pub use page_table::{ translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable, diff --git a/os/src/syscall/fs.rs b/os/src/syscall/fs.rs index af1585c160cb17da3d4c6ab48a1297b21a6485fb..275882570c1f389d9b7a35f98c04281f8dd9d9f5 100644 --- a/os/src/syscall/fs.rs +++ b/os/src/syscall/fs.rs @@ -96,4 +96,4 @@ pub fn sys_dup(fd: usize) -> isize { let new_fd = inner.alloc_fd(); inner.fd_table[new_fd] = Some(Arc::clone(inner.fd_table[fd].as_ref().unwrap())); new_fd as isize -} \ No newline at end of file +} diff --git a/os/src/syscall/gui.rs b/os/src/syscall/gui.rs index 5d41c0c61047053d3dde6d5d8131573d157ecacc..c5ba8a4e482c4a830d2bb7291b50bb10252b4b91 100644 --- a/os/src/syscall/gui.rs +++ b/os/src/syscall/gui.rs @@ -1,37 +1,34 @@ -use crate::mm::{MapArea, MapPermission, MapType, PPNRange, PhysAddr}; -use crate::task::current_process; - -//use crate::gui::*; use crate::drivers::GPU_DEVICE; +use crate::mm::{MapArea, MapPermission, MapType, PhysAddr, VirtAddr}; +use crate::task::current_process; const FB_VADDR: usize = 0x10000000; pub fn sys_framebuffer() -> isize { - let gpu = GPU_DEVICE.clone(); - let fb = gpu.get_framebuffer(); + let fb = GPU_DEVICE.get_framebuffer(); let len = fb.len(); - println!("[kernel] FrameBuffer: addr 0x{:X}, len {}", fb.as_ptr() as usize , len); - let fb_ppn = PhysAddr::from(fb.as_ptr() as usize).floor(); - let fb_end_ppn = PhysAddr::from(fb.as_ptr() as usize + len).ceil(); + // println!("[kernel] FrameBuffer: addr 0x{:X}, len {}", fb.as_ptr() as usize , len); + let fb_start_pa = PhysAddr::from(fb.as_ptr() as usize); + assert!(fb_start_pa.aligned()); + let fb_start_ppn = fb_start_pa.floor(); + let fb_start_vpn = VirtAddr::from(FB_VADDR).floor(); + let pn_offset = fb_start_ppn.0 as isize - fb_start_vpn.0 as isize; let current_process = current_process(); let mut inner = current_process.inner_exclusive_access(); - let mem_set = &mut inner.memory_set; - - mem_set.push_noalloc( + inner.memory_set.push( MapArea::new( (FB_VADDR as usize).into(), (FB_VADDR + len as usize).into(), - MapType::Noalloc, + MapType::Linear(pn_offset), MapPermission::R | MapPermission::W | MapPermission::U, ), - PPNRange::new(fb_ppn, fb_end_ppn), + None, ); FB_VADDR as isize } pub fn sys_framebuffer_flush() -> isize { - let gpu = GPU_DEVICE.clone(); - gpu.flush(); + GPU_DEVICE.flush(); 0 -} \ No newline at end of file +} diff --git a/os/src/syscall/input.rs b/os/src/syscall/input.rs index 7a2825981920485b7b3931d2fe19c540a94a7eb7..ee86bd398ec69a3fda3b119cdd2909b4922196b1 100644 --- a/os/src/syscall/input.rs +++ b/os/src/syscall/input.rs @@ -1,29 +1,28 @@ //use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE,INPUT_CONDVAR,read_input_event}; -use crate::drivers::{KEYBOARD_DEVICE,MOUSE_DEVICE}; +use crate::drivers::{KEYBOARD_DEVICE, MOUSE_DEVICE}; -pub fn sys_event_get() ->isize { +pub fn sys_event_get() -> isize { let kb = KEYBOARD_DEVICE.clone(); let mouse = MOUSE_DEVICE.clone(); //let input=INPUT_CONDVAR.clone(); //read_input_event() as isize - if !kb.is_empty(){ + if !kb.is_empty() { kb.read_event() as isize - } else if !mouse.is_empty() { + } else if !mouse.is_empty() { mouse.read_event() as isize } else { 0 } - } use crate::drivers::chardev::UART; /// check UART's read-buffer is empty or not -pub fn sys_key_pressed() -> isize { - let res =!UART.read_buffer_is_empty(); +pub fn sys_key_pressed() -> isize { + let res = !UART.read_buffer_is_empty(); if res { 1 } else { 0 - } -} \ No newline at end of file + } +} diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index d883d52dd8453fce4c528a093b37a7fd73b166a6..d28073f7ce17cbb7a7a7f0e6e87c2a6c626216a8 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -31,18 +31,18 @@ const SYSCALL_EVENT_GET: usize = 3000; const SYSCALL_KEY_PRESSED: usize = 3001; mod fs; +mod gui; +mod input; mod process; mod sync; mod thread; -mod gui; -mod input; use fs::*; +use gui::*; +use input::*; use process::*; use sync::*; use thread::*; -use gui::*; -use input::*; pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { match syscall_id { diff --git a/user/Cargo.toml b/user/Cargo.toml index 35e06d5dd8e9881bbadeb6fb59bd67a2791869ed..7b1233e008c01c7b3071e538963aa37cd6449cb2 100644 --- a/user/Cargo.toml +++ b/user/Cargo.toml @@ -12,5 +12,7 @@ bitflags = "1.2.1" riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] } embedded-graphics = "0.7.1" oorandom ="11" +virtio-input-decoder = "0.1.4" + [profile.release] debug = true \ No newline at end of file diff --git a/user/src/bin/gui_rect.rs b/user/src/bin/gui_rect.rs index e9007f608797319ca107e1dc0c79d98ff90b3e80..c8696bec0ef13bf98d48fac26ec837e924dc6109 100644 --- a/user/src/bin/gui_rect.rs +++ b/user/src/bin/gui_rect.rs @@ -1,77 +1,19 @@ #![no_std] #![no_main] -#[macro_use] extern crate user_lib; extern crate alloc; -use user_lib::{framebuffer, framebuffer_flush}; +use user_lib::{VIRTGPU_XRES, VIRTGPU_YRES, Display}; use embedded_graphics::pixelcolor::Rgb888; -use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size}; -use embedded_graphics::primitives::Primitive; -use embedded_graphics::primitives::{PrimitiveStyle, Rectangle}; -use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions}; - -pub const VIRTGPU_XRES: usize = 1280; -pub const VIRTGPU_YRES: usize = 800; -pub const VIRTGPU_LEN: usize = VIRTGPU_XRES * VIRTGPU_YRES * 4; +use embedded_graphics::prelude::{DrawTarget, Drawable, Point, RgbColor, Size}; +use embedded_graphics::primitives::{Primitive, PrimitiveStyle, Rectangle}; const INIT_X: i32 = 640; const INIT_Y: i32 = 400; const RECT_SIZE: u32 = 40; -pub struct Display { - pub size: Size, - pub point: Point, - //pub fb: Arc<&'static mut [u8]>, - pub fb: &'static mut [u8], -} - -impl Display { - pub fn new(size: Size, point: Point) -> Self { - let fb_ptr = framebuffer() as *mut u8; - println!( - "Hello world from user mode program! 0x{:X} , len {}", - fb_ptr as usize, VIRTGPU_LEN - ); - let fb = - unsafe { core::slice::from_raw_parts_mut(fb_ptr as *mut u8, VIRTGPU_LEN as usize) }; - Self { size, point, fb } - } -} - -impl OriginDimensions for Display { - fn size(&self) -> Size { - self.size - } -} - -impl DrawTarget for Display { - type Color = Rgb888; - - type Error = core::convert::Infallible; - - fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> - where - I: IntoIterator>, - { - pixels.into_iter().for_each(|px| { - let idx = ((self.point.y + px.0.y) * VIRTGPU_XRES as i32 + self.point.x + px.0.x) - as usize - * 4; - if idx + 2 >= self.fb.len() { - return; - } - self.fb[idx] = px.1.b(); - self.fb[idx + 1] = px.1.g(); - self.fb[idx + 2] = px.1.r(); - }); - framebuffer_flush(); - Ok(()) - } -} - pub struct DrawingBoard { disp: Display, latest_pos: Point, @@ -80,7 +22,7 @@ pub struct DrawingBoard { impl DrawingBoard { pub fn new() -> Self { Self { - disp: Display::new(Size::new(1280, 800), Point::new(0, 0)), + disp: Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES)), latest_pos: Point::new(INIT_X, INIT_Y), } } @@ -106,7 +48,6 @@ impl DrawingBoard { #[no_mangle] pub fn main() -> i32 { - // let fb_ptr = framebuffer() as *mut u8; let mut board = DrawingBoard::new(); let _ = board.disp.clear(Rgb888::BLACK).unwrap(); for i in 0..20 { diff --git a/user/src/bin/gui_simple.rs b/user/src/bin/gui_simple.rs index 83fb721d7843c087913a3bb430ad4b48d822736e..ccf5b89d09768dff52b5d426a0829e4ee1787eb1 100644 --- a/user/src/bin/gui_simple.rs +++ b/user/src/bin/gui_simple.rs @@ -1,27 +1,23 @@ #![no_std] #![no_main] -#[macro_use] extern crate user_lib; -use user_lib::{framebuffer, framebuffer_flush}; - -pub const VIRTGPU_XRES: usize = 1280; -pub const VIRTGPU_YRES: usize = 800; +use user_lib::{VIRTGPU_XRES, VIRTGPU_YRES, Display}; +use embedded_graphics::prelude::Size; #[no_mangle] pub fn main() -> i32 { - let fb_ptr =framebuffer() as *mut u8; - println!("Hello world from user mode program! 0x{:X} , len {}", fb_ptr as usize, VIRTGPU_XRES*VIRTGPU_YRES*4); - let fb= unsafe {core::slice::from_raw_parts_mut(fb_ptr as *mut u8, VIRTGPU_XRES*VIRTGPU_YRES*4 as usize)}; - for y in 0..800 { - for x in 0..1280 { - let idx = (y * 1280 + x) * 4; - fb[idx] = x as u8; - fb[idx + 1] = y as u8; - fb[idx + 2] = (x + y) as u8; + let mut disp = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES)); + disp.paint_on_framebuffer(|fb| { + for y in 0..VIRTGPU_YRES as usize { + for x in 0..VIRTGPU_XRES as usize { + let idx = (y * VIRTGPU_XRES as usize + x) * 4; + fb[idx] = x as u8; + fb[idx + 1] = y as u8; + fb[idx + 2] = (x + y) as u8; + } } - } - framebuffer_flush(); + }); 0 } diff --git a/user/src/bin/gui_snake.rs b/user/src/bin/gui_snake.rs index ce36b2e89b7eba180e1aadb4b25d56025842d60a..080c472546ddada2e7d6a073174e8c522a5b77dd 100644 --- a/user/src/bin/gui_snake.rs +++ b/user/src/bin/gui_snake.rs @@ -1,12 +1,11 @@ #![no_std] #![no_main] -#[macro_use] extern crate user_lib; extern crate alloc; use user_lib::console::getchar; -use user_lib::{framebuffer, framebuffer_flush, key_pressed, sleep}; +use user_lib::{Display, key_pressed, sleep, VIRTGPU_XRES, VIRTGPU_YRES}; use embedded_graphics::pixelcolor::*; use embedded_graphics::prelude::{Drawable, Point, RgbColor, Size}; @@ -16,58 +15,6 @@ use embedded_graphics::Pixel; use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions}; use oorandom; //random generator -pub const VIRTGPU_XRES: usize = 1280; -pub const VIRTGPU_YRES: usize = 800; -pub const VIRTGPU_LEN: usize = VIRTGPU_XRES * VIRTGPU_YRES * 4; - -pub struct Display { - pub size: Size, - pub point: Point, - pub fb: &'static mut [u8], -} - -impl Display { - pub fn new(size: Size, point: Point) -> Self { - let fb_ptr = framebuffer() as *mut u8; - println!( - "Hello world from user mode program! 0x{:X} , len {}", - fb_ptr as usize, VIRTGPU_LEN - ); - let fb = - unsafe { core::slice::from_raw_parts_mut(fb_ptr as *mut u8, VIRTGPU_LEN as usize) }; - Self { size, point, fb } - } -} - -impl OriginDimensions for Display { - fn size(&self) -> Size { - self.size - } -} - -impl DrawTarget for Display { - type Color = Rgb888; - type Error = core::convert::Infallible; - - fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> - where - I: IntoIterator>, - { - pixels.into_iter().for_each(|px| { - let idx = ((self.point.y + px.0.y) * VIRTGPU_XRES as i32 + self.point.x + px.0.x) - as usize - * 4; - if idx + 2 >= self.fb.len() { - return; - } - self.fb[idx] = px.1.b(); - self.fb[idx + 1] = px.1.g(); - self.fb[idx + 2] = px.1.r(); - }); - framebuffer_flush(); - Ok(()) - } -} struct Snake { parts: [Pixel; MAX_SIZE], len: usize, @@ -380,7 +327,7 @@ const LF: u8 = 0x0au8; const CR: u8 = 0x0du8; #[no_mangle] pub fn main() -> i32 { - let mut disp = Display::new(Size::new(1280, 800), Point::new(0, 0)); + let mut disp = Display::new(Size::new(VIRTGPU_XRES, VIRTGPU_YRES)); let mut game = SnakeGame::<20, Rgb888>::new(1280, 800, 20, 20, Rgb888::RED, Rgb888::YELLOW, 50); let _ = disp.clear(Rgb888::BLACK).unwrap(); loop { diff --git a/user/src/bin/inputdev_event.rs b/user/src/bin/inputdev_event.rs index 1e5b5a1021f7fbb2049c6b9cb8883744fde425e4..5b820d80086f9e4063b5de5fd73248839fef331f 100644 --- a/user/src/bin/inputdev_event.rs +++ b/user/src/bin/inputdev_event.rs @@ -1,7 +1,7 @@ #![no_std] #![no_main] -use user_lib::{event_get}; +use user_lib::{event_get, DecodeType, Key, KeyType}; #[macro_use] extern crate user_lib; @@ -9,13 +9,17 @@ extern crate user_lib; #[no_mangle] pub fn main() -> i32 { println!("Input device event test"); - let mut event=0; - for _ in 0..3 { - while event==0 { - event = event_get(); - } - println!("event: {:?}", event); + loop { + if let Some(event) = event_get() { + if let Some(decoder_type) = event.decode() { + println!("{:?}", decoder_type); + if let DecodeType::Key(key, keytype) = decoder_type { + if key == Key::Enter && keytype == KeyType::Press { + break; + } + } + } + } } - 0 } \ No newline at end of file diff --git a/user/src/file.rs b/user/src/file.rs new file mode 100644 index 0000000000000000000000000000000000000000..bf77667aae0a75885673c16506580bbf9fdacfd1 --- /dev/null +++ b/user/src/file.rs @@ -0,0 +1,30 @@ +use super::*; + +bitflags! { + pub struct OpenFlags: u32 { + const RDONLY = 0; + const WRONLY = 1 << 0; + const RDWR = 1 << 1; + const CREATE = 1 << 9; + const TRUNC = 1 << 10; + } +} + +pub fn dup(fd: usize) -> isize { + sys_dup(fd) +} +pub fn open(path: &str, flags: OpenFlags) -> isize { + sys_open(path, flags.bits) +} +pub fn close(fd: usize) -> isize { + sys_close(fd) +} +pub fn pipe(pipe_fd: &mut [usize]) -> isize { + sys_pipe(pipe_fd) +} +pub fn read(fd: usize, buf: &mut [u8]) -> isize { + sys_read(fd, buf) +} +pub fn write(fd: usize, buf: &[u8]) -> isize { + sys_write(fd, buf) +} \ No newline at end of file diff --git a/user/src/io.rs b/user/src/io.rs new file mode 100644 index 0000000000000000000000000000000000000000..baaa33823f9a9243f7d047a4abb7f44db876f528 --- /dev/null +++ b/user/src/io.rs @@ -0,0 +1,118 @@ +use super::*; +use embedded_graphics::prelude::{RgbColor, Size}; +use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions}; +use embedded_graphics::pixelcolor::Rgb888; +use virtio_input_decoder::Decoder; +pub use virtio_input_decoder::{DecodeType, Key, KeyType, Mouse}; + +pub const VIRTGPU_XRES: u32 = 1280; +pub const VIRTGPU_YRES: u32 = 800; +pub const VIRTGPU_LEN: usize = (VIRTGPU_XRES * VIRTGPU_YRES * 4) as usize; + +pub fn framebuffer() -> isize { + sys_framebuffer() +} +pub fn framebuffer_flush() -> isize { + sys_framebuffer_flush() +} + +pub struct Display { + pub size: Size, + pub fb: &'static mut [u8], +} + +impl Display { + pub fn new(size: Size) -> Self { + let fb_ptr = framebuffer() as *mut u8; + let fb = + unsafe { core::slice::from_raw_parts_mut(fb_ptr, VIRTGPU_LEN as usize) }; + Self { size, fb} + } + pub fn framebuffer(&mut self) -> &mut [u8] { + self.fb + } + pub fn paint_on_framebuffer(&mut self, p: impl FnOnce(&mut [u8]) -> ()) { + p(self.framebuffer()); + framebuffer_flush(); + } +} + +impl OriginDimensions for Display { + fn size(&self) -> Size { + self.size + } +} + +impl DrawTarget for Display { + type Color = Rgb888; + + type Error = core::convert::Infallible; + + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator>, + { + pixels.into_iter().for_each(|px| { + let idx = (px.0.y * VIRTGPU_XRES as i32 + px.0.x) + as usize + * 4; + if idx + 2 >= self.fb.len() { + return; + } + self.fb[idx] = px.1.b(); + self.fb[idx + 1] = px.1.g(); + self.fb[idx + 2] = px.1.r(); + }); + framebuffer_flush(); + Ok(()) + } +} + +pub fn event_get() -> Option { + let raw_value = sys_event_get(); + if raw_value == 0 { + None + } else { + Some((raw_value as u64).into()) + } +} + +pub fn key_pressed() -> bool { + if sys_key_pressed() == 1 { + true + } else { + false + } +} + +#[repr(C)] +pub struct InputEvent { + pub event_type: u16, + pub code: u16, + pub value: u32, +} + +impl From for InputEvent { + fn from(mut v: u64) -> Self { + let value = v as u32; + v >>= 32; + let code = v as u16; + v >>= 16; + let event_type = v as u16; + Self { + event_type, + code, + value, + } + } +} + +impl InputEvent { + pub fn decode(&self) -> Option { + Decoder::decode( + self.event_type as usize, + self.code as usize, + self.value as usize, + ).ok() + } +} \ No newline at end of file diff --git a/user/src/lib.rs b/user/src/lib.rs index 31ce9ba2c06dc699170ae97781693312f5396320..0d0db85fce444a6b6308a436e58b1a8127080d12 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -8,6 +8,10 @@ pub mod console; mod lang_items; mod syscall; +mod file; +mod task; +mod sync; +mod io; extern crate alloc; #[macro_use] @@ -16,6 +20,10 @@ extern crate bitflags; use alloc::vec::Vec; use buddy_system_allocator::LockedHeap; use syscall::*; +pub use file::*; +pub use task::*; +pub use sync::*; +pub use io::*; const USER_HEAP_SIZE: usize = 32768; @@ -59,164 +67,6 @@ fn main(_argc: usize, _argv: &[&str]) -> i32 { panic!("Cannot find main!"); } -bitflags! { - pub struct OpenFlags: u32 { - const RDONLY = 0; - const WRONLY = 1 << 0; - const RDWR = 1 << 1; - const CREATE = 1 << 9; - const TRUNC = 1 << 10; - } -} - -pub fn dup(fd: usize) -> isize { - sys_dup(fd) -} -pub fn open(path: &str, flags: OpenFlags) -> isize { - sys_open(path, flags.bits) -} -pub fn close(fd: usize) -> isize { - sys_close(fd) -} -pub fn pipe(pipe_fd: &mut [usize]) -> isize { - sys_pipe(pipe_fd) -} -pub fn read(fd: usize, buf: &mut [u8]) -> isize { - sys_read(fd, buf) -} -pub fn write(fd: usize, buf: &[u8]) -> isize { - sys_write(fd, buf) -} -pub fn exit(exit_code: i32) -> ! { - sys_exit(exit_code); -} -pub fn yield_() -> isize { - sys_yield() -} -pub fn get_time() -> isize { - sys_get_time() -} -pub fn getpid() -> isize { - sys_getpid() -} -pub fn fork() -> isize { - sys_fork() -} -pub fn exec(path: &str, args: &[*const u8]) -> isize { - sys_exec(path, args) -} -pub fn wait(exit_code: &mut i32) -> isize { - loop { - match sys_waitpid(-1, exit_code as *mut _) { - -2 => { - yield_(); - } - // -1 or a real pid - exit_pid => return exit_pid, - } - } -} - -pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { - loop { - match sys_waitpid(pid as isize, exit_code as *mut _) { - -2 => { - yield_(); - } - // -1 or a real pid - exit_pid => return exit_pid, - } - } -} - -pub fn waitpid_nb(pid: usize, exit_code: &mut i32) -> isize { - sys_waitpid(pid as isize, exit_code as *mut _) -} - -bitflags! { - pub struct SignalFlags: i32 { - const SIGINT = 1 << 2; - const SIGILL = 1 << 4; - const SIGABRT = 1 << 6; - const SIGFPE = 1 << 8; - const SIGSEGV = 1 << 11; - } -} - -pub fn kill(pid: usize, signal: i32) -> isize { - sys_kill(pid, signal) -} - -pub fn sleep(sleep_ms: usize) { - sys_sleep(sleep_ms); -} - -pub fn thread_create(entry: usize, arg: usize) -> isize { - sys_thread_create(entry, arg) -} -pub fn gettid() -> isize { - sys_gettid() -} -pub fn waittid(tid: usize) -> isize { - loop { - match sys_waittid(tid) { - -2 => { - yield_(); - } - exit_code => return exit_code, - } - } -} - -pub fn mutex_create() -> isize { - sys_mutex_create(false) -} -pub fn mutex_blocking_create() -> isize { - sys_mutex_create(true) -} -pub fn mutex_lock(mutex_id: usize) { - sys_mutex_lock(mutex_id); -} -pub fn mutex_unlock(mutex_id: usize) { - sys_mutex_unlock(mutex_id); -} -pub fn semaphore_create(res_count: usize) -> isize { - sys_semaphore_create(res_count) -} -pub fn semaphore_up(sem_id: usize) { - sys_semaphore_up(sem_id); -} -pub fn semaphore_down(sem_id: usize) { - sys_semaphore_down(sem_id); -} -pub fn condvar_create() -> isize { - sys_condvar_create(0) -} -pub fn condvar_signal(condvar_id: usize) { - sys_condvar_signal(condvar_id); -} -pub fn condvar_wait(condvar_id: usize, mutex_id: usize) { - sys_condvar_wait(condvar_id, mutex_id); -} -pub fn framebuffer() -> isize { - sys_framebuffer() -} -pub fn framebuffer_flush() -> isize { - sys_framebuffer_flush() -} - -pub fn event_get() -> isize { - sys_event_get() -} - -pub fn key_pressed() -> bool { - if sys_key_pressed() == 1 { - true - } else { - false - } -} - #[macro_export] macro_rules! vstore { ($var_ref: expr, $value: expr) => { diff --git a/user/src/sync.rs b/user/src/sync.rs new file mode 100644 index 0000000000000000000000000000000000000000..fbed4e315a61bbd5f78c8a66f22bd2206a36236a --- /dev/null +++ b/user/src/sync.rs @@ -0,0 +1,32 @@ +use super::*; + +pub fn mutex_create() -> isize { + sys_mutex_create(false) +} +pub fn mutex_blocking_create() -> isize { + sys_mutex_create(true) +} +pub fn mutex_lock(mutex_id: usize) { + sys_mutex_lock(mutex_id); +} +pub fn mutex_unlock(mutex_id: usize) { + sys_mutex_unlock(mutex_id); +} +pub fn semaphore_create(res_count: usize) -> isize { + sys_semaphore_create(res_count) +} +pub fn semaphore_up(sem_id: usize) { + sys_semaphore_up(sem_id); +} +pub fn semaphore_down(sem_id: usize) { + sys_semaphore_down(sem_id); +} +pub fn condvar_create() -> isize { + sys_condvar_create(0) +} +pub fn condvar_signal(condvar_id: usize) { + sys_condvar_signal(condvar_id); +} +pub fn condvar_wait(condvar_id: usize, mutex_id: usize) { + sys_condvar_wait(condvar_id, mutex_id); +} \ No newline at end of file diff --git a/user/src/task.rs b/user/src/task.rs new file mode 100644 index 0000000000000000000000000000000000000000..87d0ddaf2389b7d9064d01849a22996be21d26d1 --- /dev/null +++ b/user/src/task.rs @@ -0,0 +1,82 @@ +use super::*; + +pub fn exit(exit_code: i32) -> ! { + sys_exit(exit_code); +} +pub fn yield_() -> isize { + sys_yield() +} +pub fn get_time() -> isize { + sys_get_time() +} +pub fn getpid() -> isize { + sys_getpid() +} +pub fn fork() -> isize { + sys_fork() +} +pub fn exec(path: &str, args: &[*const u8]) -> isize { + sys_exec(path, args) +} +pub fn wait(exit_code: &mut i32) -> isize { + loop { + match sys_waitpid(-1, exit_code as *mut _) { + -2 => { + yield_(); + } + // -1 or a real pid + exit_pid => return exit_pid, + } + } +} + +pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize { + loop { + match sys_waitpid(pid as isize, exit_code as *mut _) { + -2 => { + yield_(); + } + // -1 or a real pid + exit_pid => return exit_pid, + } + } +} + +pub fn waitpid_nb(pid: usize, exit_code: &mut i32) -> isize { + sys_waitpid(pid as isize, exit_code as *mut _) +} + +bitflags! { + pub struct SignalFlags: i32 { + const SIGINT = 1 << 2; + const SIGILL = 1 << 4; + const SIGABRT = 1 << 6; + const SIGFPE = 1 << 8; + const SIGSEGV = 1 << 11; + } +} + +pub fn kill(pid: usize, signal: i32) -> isize { + sys_kill(pid, signal) +} + +pub fn sleep(sleep_ms: usize) { + sys_sleep(sleep_ms); +} + +pub fn thread_create(entry: usize, arg: usize) -> isize { + sys_thread_create(entry, arg) +} +pub fn gettid() -> isize { + sys_gettid() +} +pub fn waittid(tid: usize) -> isize { + loop { + match sys_waittid(tid) { + -2 => { + yield_(); + } + exit_code => return exit_code, + } + } +} \ No newline at end of file