Run cargo fmt

Signed-off-by: Harry Chen <i@harrychen.xyz>
master
Harry Chen 6 years ago
parent 9b5f7b8078
commit 75ba0859cf

@ -9,23 +9,20 @@ fn main() {
println!("cargo:rerun-if-env-changed=BOARD"); println!("cargo:rerun-if-env-changed=BOARD");
println!("cargo:rerun-if-env-changed=SFSIMG"); println!("cargo:rerun-if-env-changed=SFSIMG");
let arch: String = std::env::var("ARCH").unwrap(); let arch: String = std::env::var("ARCH").unwrap();
let board: String = std::env::var("BOARD").unwrap(); let board: String = std::env::var("BOARD").unwrap();
match arch.as_str() { match arch.as_str() {
"x86_64" => { "x86_64" => {
gen_vector_asm().unwrap(); gen_vector_asm().unwrap();
} }
"riscv32" => { "riscv32" => {}
} "riscv64" => {}
"riscv64" => { "mipsel" => {
} gen_dtb_asm(&arch, &board).unwrap();
"mipsel" => { }
gen_dtb_asm(&arch, &board).unwrap(); "aarch64" => {}
} _ => panic!("Unknown arch {}", arch),
"aarch64" => { }
}
_ => panic!("Unknown arch {}", arch),
}
} }
fn gen_vector_asm() -> Result<()> { fn gen_vector_asm() -> Result<()> {
@ -52,7 +49,6 @@ fn gen_vector_asm() -> Result<()> {
Ok(()) Ok(())
} }
fn gen_dtb_asm(arch: &String, _board: &String) -> Result<()> { fn gen_dtb_asm(arch: &String, _board: &String) -> Result<()> {
let dtb = std::env::var("DTB").unwrap(); let dtb = std::env::var("DTB").unwrap();
@ -60,20 +56,24 @@ fn gen_dtb_asm(arch: &String, _board: &String) -> Result<()> {
panic!("DTB `{}` not found", dtb) panic!("DTB `{}` not found", dtb)
} }
let mut f = File::create(format!("src/arch/{}/boot/dtb.gen.s", arch)).unwrap(); let mut f = File::create(format!("src/arch/{}/boot/dtb.gen.s", arch)).unwrap();
println!("cargo:rerun-if-changed={}", dtb); println!("cargo:rerun-if-changed={}", dtb);
println!("cargo:rerun-if-env-changed=DTB"); println!("cargo:rerun-if-env-changed=DTB");
writeln!(f, "# generated by build.rs - do not edit")?; writeln!(f, "# generated by build.rs - do not edit")?;
write!(f, r#" write!(
f,
r#"
.section .dtb,"a" .section .dtb,"a"
.align 12 .align 12
.global _dtb_start, _dtb_end .global _dtb_start, _dtb_end
_dtb_start: _dtb_start:
.incbin "{}" .incbin "{}"
_dtb_end: _dtb_end:
"#, dtb)?; "#,
dtb
)?;
Ok(()) Ok(())
} }

@ -1,9 +1,8 @@
//! Raspberry PI 3 Model B/B+ //! Raspberry PI 3 Model B/B+
use alloc::string::String;
use bcm2837::atags::Atags; use bcm2837::atags::Atags;
use once::*; use once::*;
use alloc::string::String;
#[path = "../../../../drivers/gpu/fb.rs"] #[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb; pub mod fb;
@ -48,13 +47,12 @@ pub fn probe_memory() -> Option<(usize, usize)> {
} }
pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult { pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult {
let (width, height) = if width == 0 || height == 0 { let (width, height) = if width == 0 || height == 0 {
mailbox::framebuffer_get_physical_size()? mailbox::framebuffer_get_physical_size()?
} else { } else {
(width, height) (width, height)
}; };
let depth = if depth == 0 { let depth = if depth == 0 {
mailbox::framebuffer_get_depth()? mailbox::framebuffer_get_depth()?
} else { } else {
@ -85,4 +83,4 @@ pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult {
} }
Ok((info, fb::ColorConfig::BGRA8888, vaddr)) Ok((info, fb::ColorConfig::BGRA8888, vaddr))
} }

@ -1,17 +1,17 @@
use once::*; use crate::drivers::bus::pci;
use alloc::string::String; use alloc::string::String;
use mips::registers::cp0; use mips::registers::cp0;
use crate::drivers::bus::pci; use once::*;
#[path = "../../../../drivers/console/mod.rs"]
pub mod console;
pub mod consts;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/serial/ti_16c550c.rs"] #[path = "../../../../drivers/serial/ti_16c550c.rs"]
pub mod serial; pub mod serial;
#[path = "../../../../drivers/gpu/qemu_stdvga.rs"] #[path = "../../../../drivers/gpu/qemu_stdvga.rs"]
pub mod vga; pub mod vga;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/console/mod.rs"]
pub mod console;
pub mod consts;
use fb::FramebufferInfo; use fb::FramebufferInfo;
@ -51,4 +51,4 @@ pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferR
screen_size: 800 * 600, screen_size: 800 * 600,
}; };
Ok((fb_info, fb::ColorConfig::VgaPalette, 0xb0000000)) Ok((fb_info, fb::ColorConfig::VgaPalette, 0xb0000000))
} }

@ -1,13 +1,13 @@
use once::*;
use alloc::string::String; use alloc::string::String;
use once::*;
#[path = "../../../../drivers/serial/16550_reg.rs"]
pub mod serial;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/console/mod.rs"] #[path = "../../../../drivers/console/mod.rs"]
pub mod console; pub mod console;
pub mod consts; pub mod consts;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/serial/16550_reg.rs"]
pub mod serial;
/// Initialize serial port first /// Initialize serial port first
pub fn init_serial_early() { pub fn init_serial_early() {
@ -24,4 +24,4 @@ pub fn init_driver() {
pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult { pub fn probe_fb_info(_width: u32, _height: u32, _depth: u32) -> fb::FramebufferResult {
Err(String::from("Framebuffer not usable on mipssim board")) Err(String::from("Framebuffer not usable on mipssim board"))
} }

@ -1,13 +1,13 @@
use once::*;
use alloc::string::String; use alloc::string::String;
use once::*;
#[path = "../../../../drivers/serial/simple_uart.rs"]
pub mod serial;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/console/mod.rs"] #[path = "../../../../drivers/console/mod.rs"]
pub mod console; pub mod console;
pub mod consts; pub mod consts;
#[path = "../../../../drivers/gpu/fb.rs"]
pub mod fb;
#[path = "../../../../drivers/serial/simple_uart.rs"]
pub mod serial;
use fb::FramebufferInfo; use fb::FramebufferInfo;
use fb::FramebufferResult; use fb::FramebufferResult;
@ -39,4 +39,4 @@ pub fn probe_fb_info(width: u32, height: u32, depth: u32) -> FramebufferResult {
screen_size: 800 * 600, screen_size: 800 * 600,
}; };
Ok((fb_info, fb::ColorConfig::RGB332, 0xa2000000)) Ok((fb_info, fb::ColorConfig::RGB332, 0xa2000000))
} }

@ -3,6 +3,6 @@
//! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic) //! [atomic](http://llvm.org/docs/Atomics.html#libcalls-atomic)
#[no_mangle] #[no_mangle]
pub extern fn abort() { pub extern "C" fn abort() {
panic!("abort"); panic!("abort");
} }

@ -1,6 +1,5 @@
/// Platform specific constants /// Platform specific constants
/// ///
pub use super::board::consts::*; pub use super::board::consts::*;
pub const KERNEL_OFFSET: usize = 0x80100000; pub const KERNEL_OFFSET: usize = 0x80100000;

@ -59,7 +59,7 @@ impl TrapFrame {
/// ///
/// The new thread starts at function `entry` with an usize argument `arg`. /// The new thread starts at function `entry` with an usize argument `arg`.
/// The stack pointer will be set to `sp`. /// The stack pointer will be set to `sp`.
fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, sp: usize) -> Self { fn new_kernel_thread(entry: extern "C" fn(usize) -> !, arg: usize, sp: usize) -> Self {
use core::mem::zeroed; use core::mem::zeroed;
let mut tf: Self = unsafe { zeroed() }; let mut tf: Self = unsafe { zeroed() };
tf.a0 = arg; tf.a0 = arg;
@ -89,7 +89,7 @@ impl TrapFrame {
} }
} }
use core::fmt::{Debug, Formatter, Error}; use core::fmt::{Debug, Error, Formatter};
impl Debug for TrapFrame { impl Debug for TrapFrame {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> { fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
f.debug_struct("TrapFrame") f.debug_struct("TrapFrame")
@ -136,7 +136,11 @@ struct ContextData {
impl ContextData { impl ContextData {
fn new(satp: usize) -> Self { fn new(satp: usize) -> Self {
ContextData { ra: trap_return as usize, satp, ..ContextData::default() } ContextData {
ra: trap_return as usize,
satp,
..ContextData::default()
}
} }
} }
@ -175,13 +179,22 @@ impl Context {
/// The new thread starts at function `entry` with an usize argument `arg`. /// The new thread starts at function `entry` with an usize argument `arg`.
/// The stack pointer will be set to `kstack_top`. /// The stack pointer will be set to `kstack_top`.
/// The SATP register will be set to `satp`. /// The SATP register will be set to `satp`.
pub unsafe fn new_kernel_thread(entry: extern fn(usize) -> !, arg: usize, kstack_top: usize, satp: usize) -> Self { pub unsafe fn new_kernel_thread(
info!("New kernel thread @ {:x}, stack = {:x}", entry as usize, kstack_top); entry: extern "C" fn(usize) -> !,
arg: usize,
kstack_top: usize,
satp: usize,
) -> Self {
info!(
"New kernel thread @ {:x}, stack = {:x}",
entry as usize, kstack_top
);
InitStack { InitStack {
context: ContextData::new(satp), context: ContextData::new(satp),
tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top), tf: TrapFrame::new_kernel_thread(entry, arg, kstack_top),
}.push_at(kstack_top) }
.push_at(kstack_top)
} }
/// Constructs Context for a new user thread. /// Constructs Context for a new user thread.
@ -189,13 +202,23 @@ impl Context {
/// The new thread starts at `entry_addr`. /// The new thread starts at `entry_addr`.
/// The stack pointer of user and kernel mode will be set to `ustack_top`, `kstack_top`. /// The stack pointer of user and kernel mode will be set to `ustack_top`, `kstack_top`.
/// The SATP register will be set to `satp`. /// The SATP register will be set to `satp`.
pub unsafe fn new_user_thread(entry_addr: usize, ustack_top: usize, kstack_top: usize, _is32: bool, satp: usize) -> Self { pub unsafe fn new_user_thread(
info!("New user thread @ {:x}, stack = {:x}", entry_addr, kstack_top); entry_addr: usize,
ustack_top: usize,
kstack_top: usize,
_is32: bool,
satp: usize,
) -> Self {
info!(
"New user thread @ {:x}, stack = {:x}",
entry_addr, kstack_top
);
InitStack { InitStack {
context: ContextData::new(satp), context: ContextData::new(satp),
tf: TrapFrame::new_user_thread(entry_addr, ustack_top), tf: TrapFrame::new_user_thread(entry_addr, ustack_top),
}.push_at(kstack_top) }
.push_at(kstack_top)
} }
/// Fork a user process and get the new Context. /// Fork a user process and get the new Context.
@ -212,7 +235,8 @@ impl Context {
tf.v0 = 0; tf.v0 = 0;
tf tf
}, },
}.push_at(kstack_top) }
.push_at(kstack_top)
} }
/// Fork a user thread and get the new Context. /// Fork a user thread and get the new Context.
@ -222,17 +246,24 @@ impl Context {
/// The new user stack will be set to `ustack_top`. /// The new user stack will be set to `ustack_top`.
/// The new thread pointer will be set to `tls`. /// The new thread pointer will be set to `tls`.
/// All the other registers are same as the original. /// All the other registers are same as the original.
pub unsafe fn new_clone(tf: &TrapFrame, ustack_top: usize, kstack_top: usize, satp: usize, tls: usize) -> Self { pub unsafe fn new_clone(
tf: &TrapFrame,
ustack_top: usize,
kstack_top: usize,
satp: usize,
tls: usize,
) -> Self {
InitStack { InitStack {
context: ContextData::new(satp), context: ContextData::new(satp),
tf: { tf: {
let mut tf = tf.clone(); let mut tf = tf.clone();
tf.sp = ustack_top; // sp tf.sp = ustack_top; // sp
tf.v1 = tls; tf.v1 = tls;
tf.v0 = 0; // return value tf.v0 = 0; // return value
tf tf
}, },
}.push_at(kstack_top) }
.push_at(kstack_top)
} }
/// Used for getting the init TrapFrame of a new user context in `sys_exec`. /// Used for getting the init TrapFrame of a new user context in `sys_exec`.

@ -1,6 +1,6 @@
use mips::registers::cp0;
use crate::consts::MAX_CPU_NUM; use crate::consts::MAX_CPU_NUM;
use core::ptr::{read_volatile, write_volatile}; use core::ptr::{read_volatile, write_volatile};
use mips::registers::cp0;
static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM]; static mut STARTED: [bool; MAX_CPU_NUM] = [false; MAX_CPU_NUM];

@ -3,8 +3,8 @@
use super::board; use super::board;
use once::*; use once::*;
pub use self::board::serial;
pub use self::board::fb; pub use self::board::fb;
pub use self::board::serial;
#[path = "../../../drivers/console/mod.rs"] #[path = "../../../drivers/console/mod.rs"]
pub mod console; pub mod console;

@ -1,19 +1,21 @@
use mips::interrupts;
use mips::tlb;
use mips::registers::cp0;
use crate::drivers::DRIVERS;
use mips::paging::{PageTable as MIPSPageTable, PageTableEntry, PageTableFlags as EF, TwoLevelPageTable};
use mips::addr::*;
pub use self::context::*; pub use self::context::*;
use crate::arch::paging::get_root_page_table_ptr; use crate::arch::paging::get_root_page_table_ptr;
use crate::drivers::DRIVERS;
use log::*; use log::*;
use mips::addr::*;
use mips::interrupts;
use mips::paging::{
PageTable as MIPSPageTable, PageTableEntry, PageTableFlags as EF, TwoLevelPageTable,
};
use mips::registers::cp0;
use mips::tlb;
#[path = "context.rs"] #[path = "context.rs"]
mod context; mod context;
/// Initialize interrupt /// Initialize interrupt
pub fn init() { pub fn init() {
extern { extern "C" {
fn trap_entry(); fn trap_entry();
} }
unsafe { unsafe {
@ -59,8 +61,8 @@ pub unsafe fn restore(flags: usize) {
/// ///
/// This function is called from `trap.asm`. /// This function is called from `trap.asm`.
#[no_mangle] #[no_mangle]
pub extern fn rust_trap(tf: &mut TrapFrame) { pub extern "C" fn rust_trap(tf: &mut TrapFrame) {
use cp0::cause::{Exception as E}; use cp0::cause::Exception as E;
trace!("Exception @ CPU{}: {:?} ", 0, tf.cause.cause()); trace!("Exception @ CPU{}: {:?} ", 0, tf.cause.cause());
match tf.cause.cause() { match tf.cause.cause() {
E::Interrupt => interrupt_dispatcher(tf), E::Interrupt => interrupt_dispatcher(tf),
@ -93,7 +95,7 @@ fn external() {
let handlers = [try_process_serial, try_process_drivers]; let handlers = [try_process_serial, try_process_drivers];
for handler in handlers.iter() { for handler in handlers.iter() {
if handler() == true { if handler() == true {
break break;
} }
} }
} }
@ -105,7 +107,7 @@ fn try_process_serial() -> bool {
crate::trap::serial(ch); crate::trap::serial(ch);
true true
} }
None => false None => false,
} }
} }
@ -113,10 +115,10 @@ fn try_process_drivers() -> bool {
// TODO // TODO
for driver in DRIVERS.read().iter() { for driver in DRIVERS.read().iter() {
if driver.try_handle_interrupt(None) == true { if driver.try_handle_interrupt(None) == true {
return true return true;
} }
} }
return false return false;
} }
fn ipi() { fn ipi() {
@ -131,7 +133,7 @@ fn timer() {
} }
fn syscall(tf: &mut TrapFrame) { fn syscall(tf: &mut TrapFrame) {
tf.epc += 4; // Must before syscall, because of fork. tf.epc += 4; // Must before syscall, because of fork.
let arguments = [tf.a0, tf.a1, tf.a2, tf.a3, tf.t0, tf.t1]; let arguments = [tf.a0, tf.a1, tf.a2, tf.a3, tf.t0, tf.t1];
trace!("MIPS syscall {} invoked with {:?}", tf.v0, arguments); trace!("MIPS syscall {} invoked with {:?}", tf.v0, arguments);
@ -153,17 +155,17 @@ fn page_fault(tf: &mut TrapFrame) {
trace!("\nEXCEPTION: Page Fault @ {:#x}", addr); trace!("\nEXCEPTION: Page Fault @ {:#x}", addr);
let virt_addr = VirtAddr::new(addr); let virt_addr = VirtAddr::new(addr);
let root_table = unsafe { let root_table = unsafe { &mut *(get_root_page_table_ptr() as *mut MIPSPageTable) };
&mut *(get_root_page_table_ptr() as *mut MIPSPageTable)
};
let tlb_result = root_table.lookup(addr); let tlb_result = root_table.lookup(addr);
match tlb_result { match tlb_result {
Ok(tlb_entry) => { Ok(tlb_entry) => {
trace!("PhysAddr = {:x}/{:x}", trace!(
tlb_entry.entry_lo0.get_pfn() << 12, "PhysAddr = {:x}/{:x}",
tlb_entry.entry_lo1.get_pfn() << 12); tlb_entry.entry_lo0.get_pfn() << 12,
tlb_entry.entry_lo1.get_pfn() << 12
);
tlb::write_tlb_random(tlb_entry) tlb::write_tlb_random(tlb_entry)
}, }
Err(()) => { Err(()) => {
if !crate::memory::handle_page_fault(addr) { if !crate::memory::handle_page_fault(addr) {
crate::trap::error(tf); crate::trap::error(tf);

@ -1,9 +1,9 @@
use crate::arch::paging::*;
use crate::consts::{KERNEL_OFFSET, MEMORY_END, MEMORY_OFFSET};
use crate::memory::{init_heap, Linear, MemoryAttr, MemorySet, FRAME_ALLOCATOR};
use core::mem; use core::mem;
use rcore_memory::PAGE_SIZE;
use log::*; use log::*;
use crate::memory::{FRAME_ALLOCATOR, init_heap, MemoryAttr, MemorySet, Linear}; use rcore_memory::PAGE_SIZE;
use crate::consts::{MEMORY_OFFSET, MEMORY_END, KERNEL_OFFSET};
use crate::arch::paging::*;
/// Initialize the memory management module /// Initialize the memory management module
pub fn init() { pub fn init() {
@ -29,7 +29,10 @@ fn init_frame_allocator() {
use core::ops::Range; use core::ops::Range;
let mut ba = FRAME_ALLOCATOR.lock(); let mut ba = FRAME_ALLOCATOR.lock();
let range = to_range((end as usize) - KERNEL_OFFSET + MEMORY_OFFSET + PAGE_SIZE, MEMORY_END); let range = to_range(
(end as usize) - KERNEL_OFFSET + MEMORY_OFFSET + PAGE_SIZE,
MEMORY_END,
);
ba.insert(range); ba.insert(range);
info!("frame allocator: init end"); info!("frame allocator: init end");
@ -58,7 +61,7 @@ pub unsafe fn clear_bss() {
// Symbols provided by linker script // Symbols provided by linker script
#[allow(dead_code)] #[allow(dead_code)]
extern { extern "C" {
fn stext(); fn stext();
fn etext(); fn etext();
fn sdata(); fn sdata();

@ -1,14 +1,14 @@
pub mod io;
pub mod interrupt;
pub mod timer;
pub mod paging;
pub mod memory;
pub mod compiler_rt; pub mod compiler_rt;
pub mod consts; pub mod consts;
pub mod cpu; pub mod cpu;
pub mod syscall;
pub mod rand;
pub mod driver; pub mod driver;
pub mod interrupt;
pub mod io;
pub mod memory;
pub mod paging;
pub mod rand;
pub mod syscall;
pub mod timer;
use log::*; use log::*;
use mips::registers::cp0; use mips::registers::cp0;
@ -25,15 +25,13 @@ pub mod board;
#[path = "board/mipssim/mod.rs"] #[path = "board/mipssim/mod.rs"]
pub mod board; pub mod board;
extern "C" { extern "C" {
fn _dtb_start(); fn _dtb_start();
fn _dtb_end(); fn _dtb_end();
} }
#[no_mangle] #[no_mangle]
pub extern fn rust_main() -> ! { pub extern "C" fn rust_main() -> ! {
// unsafe { cpu::set_cpu_id(hartid); } // unsafe { cpu::set_cpu_id(hartid); }
let ebase = cp0::ebase::read_u32(); let ebase = cp0::ebase::read_u32();
@ -48,7 +46,9 @@ pub extern fn rust_main() -> ! {
loop {} loop {}
} }
unsafe { memory::clear_bss(); } unsafe {
memory::clear_bss();
}
board::init_serial_early(); board::init_serial_early();
crate::logging::init(); crate::logging::init();

@ -1,11 +1,13 @@
// Depends on kernel // Depends on kernel
use crate::memory::{active_table, alloc_frame, dealloc_frame}; use crate::memory::{active_table, alloc_frame, dealloc_frame};
use log::*;
use mips::addr::*; use mips::addr::*;
use mips::tlb::*;
use mips::paging::{Mapper, PageTable as MIPSPageTable, PageTableEntry, PageTableFlags as EF, TwoLevelPageTable};
use mips::paging::{FrameAllocator, FrameDeallocator}; use mips::paging::{FrameAllocator, FrameDeallocator};
use mips::paging::{
Mapper, PageTable as MIPSPageTable, PageTableEntry, PageTableFlags as EF, TwoLevelPageTable,
};
use mips::tlb::*;
use rcore_memory::paging::*; use rcore_memory::paging::*;
use log::*;
pub struct ActivePageTable(TwoLevelPageTable<'static>, PageEntry); pub struct ActivePageTable(TwoLevelPageTable<'static>, PageEntry);
@ -14,7 +16,6 @@ pub struct ActivePageTable(TwoLevelPageTable<'static>, PageEntry);
pub struct PageEntry(&'static mut PageTableEntry, Page); pub struct PageEntry(&'static mut PageTableEntry, Page);
impl PageTable for ActivePageTable { impl PageTable for ActivePageTable {
fn map(&mut self, addr: usize, target: usize) -> &mut Entry { fn map(&mut self, addr: usize, target: usize) -> &mut Entry {
// map the 4K `page` to the 4K `frame` with `flags` // map the 4K `page` to the 4K `frame` with `flags`
let flags = EF::VALID | EF::WRITABLE | EF::CACHEABLE; let flags = EF::VALID | EF::WRITABLE | EF::CACHEABLE;
@ -22,7 +23,10 @@ impl PageTable for ActivePageTable {
let frame = Frame::of_addr(PhysAddr::new(target)); let frame = Frame::of_addr(PhysAddr::new(target));
// map the page to the frame using FrameAllocatorForRiscv // map the page to the frame using FrameAllocatorForRiscv
// we may need frame allocator to alloc frame for new page table(first/second) // we may need frame allocator to alloc frame for new page table(first/second)
self.0.map_to(page, frame, flags, &mut FrameAllocatorForRiscv).unwrap().flush(); self.0
.map_to(page, frame, flags, &mut FrameAllocatorForRiscv)
.unwrap()
.flush();
self.get_entry(addr).expect("fail to get entry") self.get_entry(addr).expect("fail to get entry")
} }
@ -49,7 +53,7 @@ extern "C" {
fn _root_page_table_ptr(); fn _root_page_table_ptr();
} }
pub fn set_root_page_table_ptr(ptr : usize) { pub fn set_root_page_table_ptr(ptr: usize) {
unsafe { unsafe {
clear_all_tlb(); clear_all_tlb();
*(_root_page_table_ptr as *mut usize) = ptr; *(_root_page_table_ptr as *mut usize) = ptr;
@ -57,18 +61,13 @@ pub fn set_root_page_table_ptr(ptr : usize) {
} }
pub fn get_root_page_table_ptr() -> usize { pub fn get_root_page_table_ptr() -> usize {
unsafe { unsafe { *(_root_page_table_ptr as *mut usize) }
*(_root_page_table_ptr as *mut usize)
}
} }
pub fn root_page_table_buffer() -> &'static mut MIPSPageTable { pub fn root_page_table_buffer() -> &'static mut MIPSPageTable {
unsafe { unsafe { &mut *(_root_page_table_ptr as *mut MIPSPageTable) }
&mut *(_root_page_table_ptr as *mut MIPSPageTable)
}
} }
impl PageTableExt for ActivePageTable {} impl PageTableExt for ActivePageTable {}
/// The virtual address of root page table /// The virtual address of root page table
@ -77,7 +76,7 @@ impl ActivePageTable {
pub unsafe fn new() -> Self { pub unsafe fn new() -> Self {
ActivePageTable( ActivePageTable(
TwoLevelPageTable::new(root_page_table_buffer()), TwoLevelPageTable::new(root_page_table_buffer()),
::core::mem::uninitialized() ::core::mem::uninitialized(),
) )
} }
} }
@ -85,34 +84,68 @@ impl ActivePageTable {
/// implementation for the Entry trait in /crate/memory/src/paging/mod.rs /// implementation for the Entry trait in /crate/memory/src/paging/mod.rs
impl Entry for PageEntry { impl Entry for PageEntry {
fn update(&mut self) { fn update(&mut self) {
unsafe { clear_all_tlb(); } unsafe {
} clear_all_tlb();
fn accessed(&self) -> bool { self.0.flags().contains(EF::ACCESSED) } }
fn dirty(&self) -> bool { self.0.flags().contains(EF::DIRTY) } }
fn writable(&self) -> bool { self.0.flags().contains(EF::WRITABLE) } fn accessed(&self) -> bool {
fn present(&self) -> bool { self.0.flags().contains(EF::VALID) } self.0.flags().contains(EF::ACCESSED)
fn clear_accessed(&mut self) { self.0.flags_mut().remove(EF::ACCESSED); } }
fn clear_dirty(&mut self) { self.0.flags_mut().remove(EF::DIRTY); } fn dirty(&self) -> bool {
fn set_writable(&mut self, value: bool) { self.0.flags_mut().set(EF::WRITABLE, value); } self.0.flags().contains(EF::DIRTY)
fn set_present(&mut self, value: bool) { self.0.flags_mut().set(EF::VALID, value); } }
fn target(&self) -> usize { self.0.addr().as_usize() } fn writable(&self) -> bool {
self.0.flags().contains(EF::WRITABLE)
}
fn present(&self) -> bool {
self.0.flags().contains(EF::VALID)
}
fn clear_accessed(&mut self) {
self.0.flags_mut().remove(EF::ACCESSED);
}
fn clear_dirty(&mut self) {
self.0.flags_mut().remove(EF::DIRTY);
}
fn set_writable(&mut self, value: bool) {
self.0.flags_mut().set(EF::WRITABLE, value);
}
fn set_present(&mut self, value: bool) {
self.0.flags_mut().set(EF::VALID, value);
}
fn target(&self) -> usize {
self.0.addr().as_usize()
}
fn set_target(&mut self, target: usize) { fn set_target(&mut self, target: usize) {
let flags = self.0.flags(); let flags = self.0.flags();
let frame = Frame::of_addr(PhysAddr::new(target)); let frame = Frame::of_addr(PhysAddr::new(target));
self.0.set(frame, flags); self.0.set(frame, flags);
} }
fn writable_shared(&self) -> bool { false } fn writable_shared(&self) -> bool {
fn readonly_shared(&self) -> bool { false } false
fn set_shared(&mut self, writable: bool) { } }
fn clear_shared(&mut self) { } fn readonly_shared(&self) -> bool {
fn swapped(&self) -> bool { self.0.flags().contains(EF::RESERVED1) } false
fn set_swapped(&mut self, value: bool) { self.0.flags_mut().set(EF::RESERVED1, value); } }
fn user(&self) -> bool { true } fn set_shared(&mut self, writable: bool) {}
fn set_user(&mut self, value: bool) { } fn clear_shared(&mut self) {}
fn execute(&self) -> bool { true } fn swapped(&self) -> bool {
fn set_execute(&mut self, value: bool) { } self.0.flags().contains(EF::RESERVED1)
fn mmio(&self) -> u8 { 0 } }
fn set_mmio(&mut self, _value: u8) { } fn set_swapped(&mut self, value: bool) {
self.0.flags_mut().set(EF::RESERVED1, value);
}
fn user(&self) -> bool {
true
}
fn set_user(&mut self, value: bool) {}
fn execute(&self) -> bool {
true
}
fn set_execute(&mut self, value: bool) {}
fn mmio(&self) -> u8 {
0
}
fn set_mmio(&mut self, _value: u8) {}
} }
#[derive(Debug)] #[derive(Debug)]
@ -127,15 +160,15 @@ impl InactivePageTable for InactivePageTable0 {
let target = alloc_frame().expect("failed to allocate frame"); let target = alloc_frame().expect("failed to allocate frame");
let frame = Frame::of_addr(PhysAddr::new(target)); let frame = Frame::of_addr(PhysAddr::new(target));
let table = unsafe { let table = unsafe { &mut *(target as *mut MIPSPageTable) };
&mut *(target as *mut MIPSPageTable)
};
table.zero(); table.zero();
InactivePageTable0 { root_frame: frame } InactivePageTable0 { root_frame: frame }
} }
fn map_kernel(&mut self) { /* nothing to do */ } fn map_kernel(&mut self) {
/* nothing to do */
}
fn token(&self) -> usize { fn token(&self) -> usize {
self.root_frame.to_kernel_unmapped().as_usize() self.root_frame.to_kernel_unmapped().as_usize()
@ -150,26 +183,30 @@ impl InactivePageTable for InactivePageTable0 {
} }
fn flush_tlb() { fn flush_tlb() {
unsafe { clear_all_tlb(); } unsafe {
clear_all_tlb();
}
} }
fn edit<T>(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T { fn edit<T>(&mut self, f: impl FnOnce(&mut Self::Active) -> T) -> T {
let pt: *mut MIPSPageTable = unsafe { let pt: *mut MIPSPageTable = unsafe { self.token() as *mut MIPSPageTable };
self.token() as *mut MIPSPageTable
};
unsafe { clear_all_tlb(); } unsafe {
clear_all_tlb();
}
let mut active = unsafe { let mut active = unsafe {
ActivePageTable( ActivePageTable(
TwoLevelPageTable::new(&mut *pt), TwoLevelPageTable::new(&mut *pt),
::core::mem::uninitialized() ::core::mem::uninitialized(),
) )
}; };
let ret = f(&mut active); let ret = f(&mut active);
unsafe { clear_all_tlb(); } unsafe {
clear_all_tlb();
}
ret ret
} }
} }

@ -1,3 +1,3 @@
pub fn rand() -> u64 { pub fn rand() -> u64 {
return 0; return 0;
} }

@ -1,5 +1,5 @@
use mips::registers::cp0;
use log::*; use log::*;
use mips::registers::cp0;
pub fn read_epoch() -> u64 { pub fn read_epoch() -> u64 {
// TODO: support RTC // TODO: support RTC
@ -9,7 +9,7 @@ pub fn read_epoch() -> u64 {
/// Enable timer interrupt /// Enable timer interrupt
pub fn init() { pub fn init() {
// Enable supervisor timer interrupt // Enable supervisor timer interrupt
cp0::status::enable_hard_int5(); // IP(7), timer interrupt cp0::status::enable_hard_int5(); // IP(7), timer interrupt
cp0::count::write_u32(0); cp0::count::write_u32(0);
set_next(); set_next();
info!("timer: init end"); info!("timer: init end");

@ -39,8 +39,7 @@ pub fn lr() -> usize {
unsafe { unsafe {
asm!("mov $0, x30" : "=r"(ptr)); asm!("mov $0, x30" : "=r"(ptr));
} }
#[cfg(any(target_arch = "riscv32", #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
target_arch = "riscv64"))]
unsafe { unsafe {
asm!("mv $0, ra" : "=r"(ptr)); asm!("mv $0, ra" : "=r"(ptr));
} }
@ -57,7 +56,6 @@ pub fn lr() -> usize {
ptr ptr
} }
// Print the backtrace starting from the caller // Print the backtrace starting from the caller
pub fn backtrace() { pub fn backtrace() {
unsafe { unsafe {
@ -88,7 +86,7 @@ pub fn backtrace() {
current_pc - size_of::<usize>(), current_pc - size_of::<usize>(),
current_fp current_fp
); );
}, }
_ => { _ => {
println!( println!(
"#{:02} PC: {:#018X} FP: {:#018X}", "#{:02} PC: {:#018X} FP: {:#018X}",
@ -125,7 +123,12 @@ pub fn backtrace() {
code_ptr = code_ptr.offset(-1); code_ptr = code_ptr.offset(-1);
} }
let sp_offset = (*code_ptr << 16) >> 16; let sp_offset = (*code_ptr << 16) >> 16;
trace!("Found addiu sp @ {:08X}({:08x}) with sp offset {}", code_ptr as usize, *code_ptr, sp_offset); trace!(
"Found addiu sp @ {:08X}({:08x}) with sp offset {}",
code_ptr as usize,
*code_ptr,
sp_offset
);
// get the return address offset of last function // get the return address offset of last function
let mut last_fun_found = false; let mut last_fun_found = false;
@ -139,7 +142,12 @@ pub fn backtrace() {
if last_fun_found { if last_fun_found {
// unwind stack // unwind stack
let ra_offset = (*code_ptr << 16) >> 16; let ra_offset = (*code_ptr << 16) >> 16;
trace!("Found sw ra @ {:08X}({:08x}) with ra offset {}", code_ptr as usize, *code_ptr, ra_offset); trace!(
"Found sw ra @ {:08X}({:08x}) with ra offset {}",
code_ptr as usize,
*code_ptr,
ra_offset
);
current_pc = *(((current_fp as isize) + ra_offset) as *const usize); current_pc = *(((current_fp as isize) + ra_offset) as *const usize);
current_fp = ((current_fp as isize) - sp_offset) as usize; current_fp = ((current_fp as isize) - sp_offset) as usize;
trace!("New PC {:08X} FP {:08X}", current_pc, current_fp); trace!("New PC {:08X} FP {:08X}", current_pc, current_fp);

@ -30,7 +30,6 @@ use x86_64::instructions::port::Port;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
impl PortOps for PortOpsImpl { impl PortOps for PortOpsImpl {
unsafe fn read8(&self, port: u16) -> u8 { unsafe fn read8(&self, port: u16) -> u8 {
Port::new(port).read() Port::new(port).read()
} }
@ -51,7 +50,6 @@ impl PortOps for PortOpsImpl {
} }
} }
#[cfg(target_arch = "mips")] #[cfg(target_arch = "mips")]
use crate::util::{read, write}; use crate::util::{read, write};
#[cfg(feature = "board_malta")] #[cfg(feature = "board_malta")]
@ -59,7 +57,6 @@ const PCI_BASE: usize = 0xbbe00000;
#[cfg(target_arch = "mips")] #[cfg(target_arch = "mips")]
impl PortOps for PortOpsImpl { impl PortOps for PortOpsImpl {
unsafe fn read8(&self, port: u16) -> u8 { unsafe fn read8(&self, port: u16) -> u8 {
read(PCI_BASE + port as usize) read(PCI_BASE + port as usize)
} }

@ -43,12 +43,20 @@ impl FramebufferColor for RgbColor {
#[inline] #[inline]
fn pack32(&self, config: ColorConfig) -> u32 { fn pack32(&self, config: ColorConfig) -> u32 {
match config { match config {
ColorConfig::RGB332 => (((self.0 >> 5) << 5) | ((self.1 >> 5) << 2) | (self.2 >> 6)) as u32, ColorConfig::RGB332 => {
ColorConfig::RGB565 => (((self.0 as u16 & 0xF8) << 8) | ((self.1 as u16 & 0xFC) << 3) | (self.2 as u16 >> 3)) as u32, (((self.0 >> 5) << 5) | ((self.1 >> 5) << 2) | (self.2 >> 6)) as u32
}
ColorConfig::RGB565 => {
(((self.0 as u16 & 0xF8) << 8)
| ((self.1 as u16 & 0xFC) << 3)
| (self.2 as u16 >> 3)) as u32
}
// FIXME: qemu and low version RPi use RGBA order for 24/32-bit color depth, // FIXME: qemu and low version RPi use RGBA order for 24/32-bit color depth,
// but RPi3 B+ uses BGRA order for 24/32-bit color depth. // but RPi3 B+ uses BGRA order for 24/32-bit color depth.
ColorConfig::BGRA8888 => ((self.0 as u32) << 16) | ((self.1 as u32) << 8) | (self.2 as u32), ColorConfig::BGRA8888 => {
_ => unimplemented!() ((self.0 as u32) << 16) | ((self.1 as u32) << 8) | (self.2 as u32)
}
_ => unimplemented!(),
} }
} }
} }

@ -10,7 +10,7 @@ use spin::Mutex;
use crate::util::escape_parser::{CharacterAttribute, EscapeParser}; use crate::util::escape_parser::{CharacterAttribute, EscapeParser};
use super::fb::{ColorDepth::*, ColorConfig, FramebufferInfo, FRAME_BUFFER}; use super::fb::{ColorConfig, ColorDepth::*, FramebufferInfo, FRAME_BUFFER};
use self::color::FramebufferColor; use self::color::FramebufferColor;
use self::fonts::{Font, Font8x16}; use self::fonts::{Font, Font8x16};
@ -64,7 +64,7 @@ impl<F: Font> ConsoleBuffer<F> {
if let Some(fb) = FRAME_BUFFER.lock().as_mut() { if let Some(fb) = FRAME_BUFFER.lock().as_mut() {
let (mut foreground, mut background) = ( let (mut foreground, mut background) = (
ch.attr.foreground.pack32(fb.color_config), ch.attr.foreground.pack32(fb.color_config),
ch.attr.background.pack32(fb.color_config) ch.attr.background.pack32(fb.color_config),
); );
if ch.attr.reverse { if ch.attr.reverse {
core::mem::swap(&mut foreground, &mut background); core::mem::swap(&mut foreground, &mut background);

@ -152,12 +152,9 @@ impl Framebuffer {
color_depth, color_depth,
fb_info: info, fb_info: info,
}) })
}, }
Err(e) => { Err(e) => Err(e)?,
Err(e)?
},
} }
} }
#[inline] #[inline]

@ -5,22 +5,22 @@ use crate::util::{read, write};
const VGA_MMIO_OFFSET: usize = 0x400 - 0x3C0; const VGA_MMIO_OFFSET: usize = 0x400 - 0x3C0;
const VBE_MMIO_OFFSET: usize = 0x500; const VBE_MMIO_OFFSET: usize = 0x500;
const VGA_AR_ADDR : u16 = 0x3C0; const VGA_AR_ADDR: u16 = 0x3C0;
const VBE_DISPI_INDEX_XRES : u16 = 0x1; const VBE_DISPI_INDEX_XRES: u16 = 0x1;
const VBE_DISPI_INDEX_YRES : u16 = 0x2; const VBE_DISPI_INDEX_YRES: u16 = 0x2;
const VBE_DISPI_INDEX_BPP : u16 = 0x3; const VBE_DISPI_INDEX_BPP: u16 = 0x3;
const VBE_DISPI_INDEX_ENABLE : u16 = 0x4; const VBE_DISPI_INDEX_ENABLE: u16 = 0x4;
const VBE_DISPI_INDEX_BANK : u16 = 0x5; const VBE_DISPI_INDEX_BANK: u16 = 0x5;
const VBE_DISPI_INDEX_VIRT_WIDTH : u16 = 0x6; const VBE_DISPI_INDEX_VIRT_WIDTH: u16 = 0x6;
const VBE_DISPI_INDEX_VIRT_HEIGHT : u16 = 0x7; const VBE_DISPI_INDEX_VIRT_HEIGHT: u16 = 0x7;
const VBE_DISPI_INDEX_X_OFFSET : u16 = 0x8; const VBE_DISPI_INDEX_X_OFFSET: u16 = 0x8;
const VBE_DISPI_INDEX_Y_OFFSET : u16 = 0x9; const VBE_DISPI_INDEX_Y_OFFSET: u16 = 0x9;
const VBE_DISPI_INDEX_VIDEO_MEMORY_64K : u16 = 0xa; const VBE_DISPI_INDEX_VIDEO_MEMORY_64K: u16 = 0xa;
const VGA_AR_PAS : u8 = 0x20; const VGA_AR_PAS: u8 = 0x20;
const VBE_DISPI_ENABLED : u16 = 0x01; const VBE_DISPI_ENABLED: u16 = 0x01;
const VBE_DISPI_8BIT_DAC : u16 = 0x20; const VBE_DISPI_8BIT_DAC: u16 = 0x20;
const VBE_DISPI_LFB_ENABLED : u16 = 0x40; const VBE_DISPI_LFB_ENABLED: u16 = 0x40;
const PCI_COMMAND: u8 = 0x04; const PCI_COMMAND: u8 = 0x04;
const PCI_COMMAND_IO: u32 = 0x1; const PCI_COMMAND_IO: u32 = 0x1;
@ -29,72 +29,102 @@ const PCI_COMMAND_MASTER: u32 = 0x4;
const PCI_COMMAND_SPECIAL: u32 = 0x8; const PCI_COMMAND_SPECIAL: u32 = 0x8;
const PCI_COMMAND_SERR: u32 = 0x100; const PCI_COMMAND_SERR: u32 = 0x100;
fn pci_read_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8) -> u32 { fn pci_read_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8) -> u32 {
// write config address // write config address
let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32); let address = (1 << 31)
| ((bus as u32) << 16)
| ((slot as u32) << 11)
| ((func as u32) << 8)
| (offset as u32);
write(pci_base + 0xcf8, address); write(pci_base + 0xcf8, address);
// do the actual work // do the actual work
let value = read(pci_base + 0xcfc); let value = read(pci_base + 0xcfc);
debug!("Read {:08x} from PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}", value, bus, slot, func, offset); debug!(
"Read {:08x} from PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}",
value, bus, slot, func, offset
);
value value
} }
fn pci_write_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8, value: u32) { fn pci_write_config(pci_base: usize, bus: u8, slot: u8, func: u8, offset: u8, value: u32) {
// write config address // write config address
let address = (1 << 31) | ((bus as u32) << 16) | ((slot as u32) << 11) | ((func as u32) << 8) | (offset as u32); let address = (1 << 31)
debug!("Write {:08x} to PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}", value, bus, slot, func, offset); | ((bus as u32) << 16)
| ((slot as u32) << 11)
| ((func as u32) << 8)
| (offset as u32);
debug!(
"Write {:08x} to PCI address: {:02x}:{:02x}.{:02x} @ 0x{:02x}",
value, bus, slot, func, offset
);
write(pci_base + 0xcf8, address); write(pci_base + 0xcf8, address);
// do the actual work // do the actual work
write(pci_base + 0xcfc, value) write(pci_base + 0xcfc, value)
} }
pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) { pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) {
debug!(
debug!("PCI Controller Base: {:08x}", pci_read_config(pci_base, 0x00, 0x00, 0x00, 0x20)); "PCI Controller Base: {:08x}",
pci_read_config(pci_base, 0x00, 0x00, 0x00, 0x20)
);
let controller = pci_read_config(pci_base, 0x00, 0x00, 0x00, PCI_COMMAND); let controller = pci_read_config(pci_base, 0x00, 0x00, 0x00, PCI_COMMAND);
pci_write_config(pci_base, 0x00, 0x00, 0x00, PCI_COMMAND, controller | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR); pci_write_config(
pci_base,
0x00,
0x00,
0x00,
PCI_COMMAND,
controller | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR,
);
let pci_vendor = pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x0); let pci_vendor = pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x0);
debug!("VGA PCI Device ID: {:08x}", pci_vendor); debug!("VGA PCI Device ID: {:08x}", pci_vendor);
// enable port and MMIO for vga card // enable port and MMIO for vga card
pci_write_config(pci_base, 0x00, 0x12, 0x00, PCI_COMMAND, pci_read_config(pci_base, 0x00, 0x12, 0x00, PCI_COMMAND) | PCI_COMMAND_MEMORY); pci_write_config(
pci_base,
0x00,
0x12,
0x00,
PCI_COMMAND,
pci_read_config(pci_base, 0x00, 0x12, 0x00, PCI_COMMAND) | PCI_COMMAND_MEMORY,
);
// bar 0 // bar 0
pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x10, 0x10000000); pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x10, 0x10000000);
debug!("VGA PCI BAR 0: {:08x}", pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x10)); debug!(
"VGA PCI BAR 0: {:08x}",
pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x10)
);
// bar 2 // bar 2
pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x18, 0x12050000); pci_write_config(pci_base, 0x00, 0x12, 0x00, 0x18, 0x12050000);
debug!("VGA PCI BAR 2: {:08x}", pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x18)); debug!(
"VGA PCI BAR 2: {:08x}",
pci_read_config(pci_base, 0x00, 0x12, 0x00, 0x18)
);
// vga operations // vga operations
let vga_write_io = |offset: u16, value: u8| { let vga_write_io = |offset: u16, value: u8| {
write(vga_base + VGA_MMIO_OFFSET + (offset as usize), value); write(vga_base + VGA_MMIO_OFFSET + (offset as usize), value);
}; };
let vga_read_io = |offset: u16| -> u8 { let vga_read_io = |offset: u16| -> u8 { read(vga_base + VGA_MMIO_OFFSET + (offset as usize)) };
read(vga_base + VGA_MMIO_OFFSET + (offset as usize))
};
let vga_write_vbe = |offset: u16, value: u16| { let vga_write_vbe = |offset: u16, value: u16| {
write(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2, value); write(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2, value);
}; };
let vga_read_vbe = |offset: u16| -> u16 { let vga_read_vbe =
read(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2) |offset: u16| -> u16 { read(vga_base + VBE_MMIO_OFFSET + (offset as usize) * 2) };
};
debug!("VGA Endianess: {:x}", read::<u32>(vga_base + 0x604)); debug!("VGA Endianess: {:x}", read::<u32>(vga_base + 0x604));
// unblank vga output // unblank vga output
vga_write_io(VGA_AR_ADDR, VGA_AR_PAS); vga_write_io(VGA_AR_ADDR, VGA_AR_PAS);
debug!("VGA AR: {}", vga_read_io(VGA_AR_ADDR)); debug!("VGA AR: {}", vga_read_io(VGA_AR_ADDR));
vga_write_vbe(VBE_DISPI_INDEX_ENABLE, 0); vga_write_vbe(VBE_DISPI_INDEX_ENABLE, 0);
// set resolution and color depth // set resolution and color depth
vga_write_vbe(VBE_DISPI_INDEX_XRES, x_res); vga_write_vbe(VBE_DISPI_INDEX_XRES, x_res);
vga_write_vbe(VBE_DISPI_INDEX_YRES, y_res); vga_write_vbe(VBE_DISPI_INDEX_YRES, y_res);
@ -104,13 +134,20 @@ pub fn init(pci_base: usize, vga_base: usize, x_res: u16, y_res: u16) {
vga_write_vbe(VBE_DISPI_INDEX_X_OFFSET, 0); vga_write_vbe(VBE_DISPI_INDEX_X_OFFSET, 0);
vga_write_vbe(VBE_DISPI_INDEX_Y_OFFSET, 0); vga_write_vbe(VBE_DISPI_INDEX_Y_OFFSET, 0);
vga_write_vbe(VBE_DISPI_INDEX_BPP, 8); vga_write_vbe(VBE_DISPI_INDEX_BPP, 8);
debug!("VGA Resolution: {}*{}@{}bit", vga_read_vbe(VBE_DISPI_INDEX_XRES), vga_read_vbe(VBE_DISPI_INDEX_YRES), vga_read_vbe(VBE_DISPI_INDEX_BPP)); debug!(
"VGA Resolution: {}*{}@{}bit",
vga_read_vbe(VBE_DISPI_INDEX_XRES),
vga_read_vbe(VBE_DISPI_INDEX_YRES),
vga_read_vbe(VBE_DISPI_INDEX_BPP)
);
// enable vbe // enable vbe
let vbe_enable = vga_read_vbe(VBE_DISPI_INDEX_ENABLE); let vbe_enable = vga_read_vbe(VBE_DISPI_INDEX_ENABLE);
vga_write_vbe(VBE_DISPI_INDEX_ENABLE, vbe_enable | VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED | VBE_DISPI_8BIT_DAC); vga_write_vbe(
VBE_DISPI_INDEX_ENABLE,
vbe_enable | VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED | VBE_DISPI_8BIT_DAC,
);
debug!("VBE Status: {:04x}", vga_read_vbe(VBE_DISPI_INDEX_ENABLE)); debug!("VBE Status: {:04x}", vga_read_vbe(VBE_DISPI_INDEX_ENABLE));
info!("QEMU STDVGA driver initialized @ {:x}", vga_base); info!("QEMU STDVGA driver initialized @ {:x}", vga_base);
} }

@ -2,19 +2,17 @@
#![allow(dead_code)] #![allow(dead_code)]
use core::fmt::{Write, Result, Arguments};
use crate::util::{read, write}; use crate::util::{read, write};
use core::fmt::{Arguments, Result, Write};
use spin::Mutex; use spin::Mutex;
pub struct SerialPort { pub struct SerialPort {
base: usize base: usize,
} }
impl SerialPort { impl SerialPort {
fn new() -> SerialPort { fn new() -> SerialPort {
SerialPort { SerialPort { base: 0 }
base: 0
}
} }
pub fn init(&mut self, base: usize) { pub fn init(&mut self, base: usize) {
@ -49,7 +47,7 @@ impl SerialPort {
} }
let c = read::<u8>(self.base + COM_RX); let c = read::<u8>(self.base + COM_RX);
match c { match c {
255 => '\0', // null 255 => '\0', // null
c => c as char, c => c as char,
} }
} }
@ -65,7 +63,6 @@ impl SerialPort {
pub fn putfmt(&mut self, fmt: Arguments) { pub fn putfmt(&mut self, fmt: Arguments) {
self.write_fmt(fmt).unwrap(); self.write_fmt(fmt).unwrap();
} }
} }
impl Write for SerialPort { impl Write for SerialPort {
@ -83,27 +80,25 @@ impl Write for SerialPort {
} }
} }
const COM_RX: usize = 0; // In: Receive buffer (DLAB=0)
const COM_RX :usize = 0; // In: Receive buffer (DLAB=0) const COM_TX: usize = 0; // Out: Transmit buffer (DLAB=0)
const COM_TX :usize = 0; // Out: Transmit buffer (DLAB=0) const COM_DLL: usize = 0; // Out: Divisor Latch Low (DLAB=1)
const COM_DLL :usize = 0; // Out: Divisor Latch Low (DLAB=1) const COM_DLM: usize = 1; // Out: Divisor Latch High (DLAB=1)
const COM_DLM :usize = 1; // Out: Divisor Latch High (DLAB=1) const COM_IER: usize = 1; // Out: Interrupt Enable Register
const COM_IER :usize = 1; // Out: Interrupt Enable Register const COM_IER_RDI: u8 = 0x01; // Enable receiver data interrupt
const COM_IER_RDI :u8 = 0x01; // Enable receiver data interrupt const COM_IIR: usize = 2; // In: Interrupt ID Register
const COM_IIR :usize = 2; // In: Interrupt ID Register const COM_FCR: usize = 2; // Out: FIFO Control Register
const COM_FCR :usize = 2; // Out: FIFO Control Register const COM_LCR: usize = 3; // Out: Line Control Register
const COM_LCR :usize = 3; // Out: Line Control Register const COM_LCR_DLAB: u8 = 0x80; // Divisor latch access bit
const COM_LCR_DLAB :u8 = 0x80; // Divisor latch access bit const COM_LCR_WLEN8: u8 = 0x03; // Wordlength: 8 bits
const COM_LCR_WLEN8 :u8 = 0x03; // Wordlength: 8 bits const COM_MCR: usize = 4; // Out: Modem Control Register
const COM_MCR :usize = 4; // Out: Modem Control Register const COM_MCR_RTS: u8 = 0x02; // RTS complement
const COM_MCR_RTS :u8 = 0x02; // RTS complement const COM_MCR_DTR: u8 = 0x01; // DTR complement
const COM_MCR_DTR :u8 = 0x01; // DTR complement const COM_MCR_OUT2: u8 = 0x08; // Out2 complement
const COM_MCR_OUT2 :u8 = 0x08; // Out2 complement const COM_LSR: usize = 5; // In: Line Status Register
const COM_LSR :usize = 5; // In: Line Status Register const COM_LSR_DATA: u8 = 0x01; // Data available
const COM_LSR_DATA :u8 = 0x01; // Data available const COM_LSR_TXRDY: u8 = 0x20; // Transmit buffer avail
const COM_LSR_TXRDY :u8 = 0x20; // Transmit buffer avail const COM_LSR_TSRE: u8 = 0x40; // Transmitter off
const COM_LSR_TSRE :u8 = 0x40; // Transmitter off
lazy_static! { lazy_static! {
pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new()); pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new());

@ -1,11 +1,11 @@
//! naive serial adapter driver for thinpad //! naive serial adapter driver for thinpad
use core::fmt::{Write, Result, Arguments};
use crate::util::{read, write}; use crate::util::{read, write};
use core::fmt::{Arguments, Result, Write};
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct SerialPort { pub struct SerialPort {
base: usize base: usize,
} }
const UART_STATUS: usize = 0x0; const UART_STATUS: usize = 0x0;
@ -15,7 +15,6 @@ const UART_STATUS_CTS: u8 = 0x1; // clear to send signal
const UART_STATUS_DR: u8 = 0x2; // data ready signal const UART_STATUS_DR: u8 = 0x2; // data ready signal
impl SerialPort { impl SerialPort {
pub fn init(&mut self, base: usize) { pub fn init(&mut self, base: usize) {
self.base = base; self.base = base;
} }
@ -34,7 +33,7 @@ impl SerialPort {
} }
let c = read::<u8>(self.base + UART_DATA); let c = read::<u8>(self.base + UART_DATA);
match c { match c {
255 => '\0', // null 255 => '\0', // null
c => c as char, c => c as char,
} }
} }
@ -73,9 +72,7 @@ impl Write for SerialPort {
} }
} }
pub static SERIAL_PORT: SerialPort = SerialPort { pub static SERIAL_PORT: SerialPort = SerialPort { base: 0 };
base: 0
};
pub fn init(base: usize) { pub fn init(base: usize) {
SERIAL_PORT.lock().init(base); SERIAL_PORT.lock().init(base);

@ -2,19 +2,17 @@
#![allow(dead_code)] #![allow(dead_code)]
use core::fmt::{Write, Result, Arguments};
use spin::Mutex;
use crate::util::{read, write}; use crate::util::{read, write};
use core::fmt::{Arguments, Result, Write};
use spin::Mutex;
pub struct SerialPort { pub struct SerialPort {
base: usize base: usize,
} }
impl SerialPort { impl SerialPort {
fn new() -> SerialPort { fn new() -> SerialPort {
SerialPort { SerialPort { base: 0 }
base: 0
}
} }
pub fn init(&mut self, base: usize) { pub fn init(&mut self, base: usize) {
@ -49,7 +47,7 @@ impl SerialPort {
} }
let c = read::<u8>(self.base + COM_RX); let c = read::<u8>(self.base + COM_RX);
match c { match c {
255 => '\0', // null 255 => '\0', // null
c => c as char, c => c as char,
} }
} }
@ -65,7 +63,6 @@ impl SerialPort {
pub fn putfmt(&mut self, fmt: Arguments) { pub fn putfmt(&mut self, fmt: Arguments) {
self.write_fmt(fmt).unwrap(); self.write_fmt(fmt).unwrap();
} }
} }
impl Write for SerialPort { impl Write for SerialPort {
@ -83,12 +80,11 @@ impl Write for SerialPort {
} }
} }
const COM_RX :usize = 0x00; // In: Receive buffer (DLAB=0) const COM_RX: usize = 0x00; // In: Receive buffer (DLAB=0)
const COM_TX :usize = 0x00; // Out: Transmit buffer (DLAB=0) const COM_TX: usize = 0x00; // Out: Transmit buffer (DLAB=0)
const COM_INT_EN :usize = 0x08; // In: Interrupt enable const COM_INT_EN: usize = 0x08; // In: Interrupt enable
const COM_INT_ID :usize = 0x10; // Out: Interrupt identification const COM_INT_ID: usize = 0x10; // Out: Interrupt identification
const COM_LSR :usize = 0x28; // In: Line status register const COM_LSR: usize = 0x28; // In: Line status register
lazy_static! { lazy_static! {
pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new()); pub static ref SERIAL_PORT: Mutex<SerialPort> = Mutex::new(SerialPort::new());

@ -19,11 +19,13 @@ pub unsafe fn write_cstr(ptr: *mut u8, s: &str) {
#[inline(always)] #[inline(always)]
pub fn write<T>(addr: usize, content: T) { pub fn write<T>(addr: usize, content: T) {
let cell = (addr) as *mut T; let cell = (addr) as *mut T;
unsafe { write_volatile(cell, content); } unsafe {
write_volatile(cell, content);
}
} }
#[inline(always)] #[inline(always)]
pub fn read<T>(addr: usize) -> T { pub fn read<T>(addr: usize) -> T {
let cell = (addr) as *const T; let cell = (addr) as *const T;
unsafe { read_volatile(cell) } unsafe { read_volatile(cell) }
} }

Loading…
Cancel
Save