1
0
mirror of https://github.com/sgmarz/osblog.git synced 2024-11-23 18:06:20 +04:00

Ran rustfmt

This commit is contained in:
Stephen Marz 2019-10-27 16:03:37 -04:00
parent 0b2506e8e5
commit 6f333bd8f0
6 changed files with 133 additions and 96 deletions

View File

@ -10,35 +10,36 @@ use core::ptr::null_mut;
pub enum SatpMode {
Off = 0,
Sv39 = 8,
Sv48 = 9
Sv48 = 9,
}
#[repr(C)]
#[derive(Clone,Copy)]
#[derive(Clone, Copy)]
pub struct KernelTrapFrame {
pub regs: [usize; 32], // 0 - 255
pub fregs: [usize; 32], // 256 - 511
pub satp: usize, // 512 - 519
pub trap_stack: *mut u8, // 520
pub hartid: usize, // 528
pub regs: [usize; 32], // 0 - 255
pub fregs: [usize; 32], // 256 - 511
pub satp: usize, // 512 - 519
pub trap_stack: *mut u8, // 520
pub hartid: usize, // 528
}
impl KernelTrapFrame {
pub const fn zero() -> Self {
KernelTrapFrame {
regs: [0; 32],
fregs: [0; 32],
satp: 0,
trap_stack: null_mut(),
hartid: 0
}
KernelTrapFrame { regs: [0; 32],
fregs: [0; 32],
satp: 0,
trap_stack: null_mut(),
hartid: 0, }
}
}
pub static mut KERNEL_TRAP_FRAME: [KernelTrapFrame; 8] = [KernelTrapFrame::zero(); 8];
pub static mut KERNEL_TRAP_FRAME: [KernelTrapFrame; 8] =
[KernelTrapFrame::zero(); 8];
pub const fn build_satp(mode: SatpMode, asid: usize, addr: usize) -> usize {
(mode as usize) << 60 | (asid & 0xffff) << 44 | (addr >> 12) & 0xff_ffff_ffff
(mode as usize) << 60
| (asid & 0xffff) << 44
| (addr >> 12) & 0xff_ffff_ffff
}
pub fn mhartid_read() -> usize {
@ -135,7 +136,6 @@ pub fn sepc_read() -> usize {
}
}
pub fn satp_write(val: usize) {
unsafe {
asm!("csrw satp, $0" :: "r"(val));

View File

@ -58,7 +58,6 @@ static mut KMEM_HEAD: *mut AllocList = null_mut();
static mut KMEM_ALLOC: usize = 0;
static mut KMEM_PAGE_TABLE: *mut Table = null_mut();
// These functions are safe helpers around an unsafe
// operation.
pub fn get_head() -> *mut u8 {

View File

@ -254,29 +254,33 @@ extern "C" fn kinit() {
// back and forth between the kernel's table and user
// applicatons' tables.
cpu::mscratch_write(
(&mut cpu::KERNEL_TRAP_FRAME[0]
as *mut cpu::KernelTrapFrame)
as usize,
(&mut cpu::KERNEL_TRAP_FRAME[0]
as *mut cpu::KernelTrapFrame)
as usize,
);
cpu::sscratch_write(cpu::mscratch_read());
cpu::KERNEL_TRAP_FRAME[0].satp = satp_value;
// Move the stack pointer to the very bottom. The stack is actually in a
// non-mapped page. The stack is decrement-before push and increment after
// pop. Therefore, the stack will be allocated (decremented)
// before it is stored.
cpu::KERNEL_TRAP_FRAME[0].trap_stack = page::zalloc(1).add(page::PAGE_SIZE);
// Move the stack pointer to the very bottom. The stack is
// actually in a non-mapped page. The stack is decrement-before
// push and increment after pop. Therefore, the stack will be
// allocated (decremented) before it is stored.
cpu::KERNEL_TRAP_FRAME[0].trap_stack =
page::zalloc(1).add(page::PAGE_SIZE);
id_map_range(
&mut root,
cpu::KERNEL_TRAP_FRAME[0].trap_stack.sub(page::PAGE_SIZE) as usize,
cpu::KERNEL_TRAP_FRAME[0].trap_stack as usize,
page::EntryBits::ReadWrite.val(),
&mut root,
cpu::KERNEL_TRAP_FRAME[0].trap_stack
.sub(page::PAGE_SIZE,)
as usize,
cpu::KERNEL_TRAP_FRAME[0].trap_stack as usize,
page::EntryBits::ReadWrite.val(),
);
// The trap frame itself is stored in the mscratch register.
id_map_range(
&mut root,
cpu::mscratch_read(),
cpu::mscratch_read() + core::mem::size_of::<cpu::KernelTrapFrame>(),
page::EntryBits::ReadWrite.val(),
&mut root,
cpu::mscratch_read(),
cpu::mscratch_read()
+ core::mem::size_of::<cpu::KernelTrapFrame,>(),
page::EntryBits::ReadWrite.val(),
);
page::print_page_allocations();
let p = cpu::KERNEL_TRAP_FRAME[0].trap_stack as usize - 1;
@ -302,16 +306,17 @@ extern "C" fn kinit_hart(hartid: usize) {
// back and forth between the kernel's table and user
// applicatons' tables.
cpu::mscratch_write(
(&mut cpu::KERNEL_TRAP_FRAME[hartid]
as *mut cpu::KernelTrapFrame)
as usize,
(&mut cpu::KERNEL_TRAP_FRAME[hartid]
as *mut cpu::KernelTrapFrame)
as usize,
);
// Copy the same mscratch over to the supervisor version of the same
// register.
// Copy the same mscratch over to the supervisor version of the
// same register.
cpu::sscratch_write(cpu::mscratch_read());
cpu::KERNEL_TRAP_FRAME[hartid].hartid = hartid;
// We can't do the following until zalloc() is locked, but we don't have locks, yet :(
// cpu::KERNEL_TRAP_FRAME[hartid].satp = cpu::KERNEL_TRAP_FRAME[0].satp;
// We can't do the following until zalloc() is locked, but we
// don't have locks, yet :( cpu::KERNEL_TRAP_FRAME[hartid].satp
// = cpu::KERNEL_TRAP_FRAME[0].satp;
// cpu::KERNEL_TRAP_FRAME[hartid].trap_stack = page::zalloc(1);
}
}

View File

@ -398,7 +398,12 @@ impl Table {
/// The bits MUST include one or more of the following:
/// Read, Write, Execute
/// The valid bit automatically gets added.
pub fn map(root: &mut Table, vaddr: usize, paddr: usize, bits: i64, level: usize) {
pub fn map(root: &mut Table,
vaddr: usize,
paddr: usize,
bits: i64,
level: usize)
{
// Make sure that Read, Write, or Execute have been provided
// otherwise, we'll leak memory and always create a page fault.
assert!(bits & 0xe != 0);
@ -462,9 +467,9 @@ pub fn map(root: &mut Table, vaddr: usize, paddr: usize, bits: i64, level: usize
EntryBits::Valid.val() | // Valid bit
EntryBits::Dirty.val() | // Some machines require this to =1
EntryBits::Access.val() // Just like dirty, some machines require this
;
// Set the entry. V should be set to the correct pointer by the loop
// above.
;
// Set the entry. V should be set to the correct pointer by the loop
// above.
v.set_entry(entry);
}
@ -482,7 +487,8 @@ pub fn unmap(root: &mut Table) {
// This is a valid entry, so drill down and free.
let memaddr_lv1 = (entry_lv2.get_entry() & !0x3ff) << 2;
let table_lv1 = unsafe {
// Make table_lv1 a mutable reference instead of a pointer.
// Make table_lv1 a mutable reference instead of
// a pointer.
(memaddr_lv1 as *mut Table).as_mut().unwrap()
};
for lv1 in 0..Table::len() {

View File

@ -3,34 +3,51 @@
// Stephen Marz
// 10 October 2019
use crate::cpu::KernelTrapFrame;
#[no_mangle]
extern "C"
fn s_trap(epc: usize, tval: usize, cause: usize, hart: usize, stat: usize, frame: &mut KernelTrapFrame) -> usize {
extern "C" fn s_trap(epc: usize,
tval: usize,
cause: usize,
hart: usize,
stat: usize,
frame: &mut KernelTrapFrame)
-> usize
{
println!("STRAP (cause: {} @ 0x{:x}) [cpu: {}]", cause, epc, hart);
epc + 4
epc + 4
}
#[no_mangle]
extern "C"
fn m_trap(epc: usize, tval: usize, cause: usize, hart: usize, stat: usize, frame: &mut KernelTrapFrame) -> usize {
// println!("MTRAP ({}) (cause: 0x{:x} @ 0x{:x}) [0x{:x}]", hart, cause, epc, stat);
// println!("Stack = {:p}", &frame.trap_stack);
// Only machine timers should come here. Everything else should be brought to supervisor
// mode (s_trap).
extern "C" fn m_trap(epc: usize,
tval: usize,
cause: usize,
hart: usize,
stat: usize,
frame: &mut KernelTrapFrame)
-> usize
{
// println!("MTRAP ({}) (cause: 0x{:x} @ 0x{:x}) [0x{:x}]", hart, cause,
// epc, stat); println!("Stack = {:p}", &frame.trap_stack);
// Only machine timers should come here. Everything else should be
// brought to supervisor mode (s_trap).
if cause == 0x8000_0000_0000_0007 {
unsafe {
let addr = 0x0200_4000 + hart * 8;
let mtimecmp = addr as *mut u64;
let mtime = 0x0200_bff8 as *const u64;
mtimecmp.write_volatile(mtime.read_volatile() + 10_000_000);
mtimecmp.write_volatile(
mtime.read_volatile()
+ 10_000_000,
);
asm!("csrw sip, $0" ::"r"(2));
}
epc
}
else {
panic!("Non-timer machine interrupt: 0x{:x} on hart {}", cause, hart)
panic!(
"Non-timer machine interrupt: 0x{:x} on hart {}",
cause, hart
)
}
}
}

View File

@ -1,9 +1,8 @@
// uart.rs
// UART routines and driver
use core::convert::TryInto;
use core::fmt::Write;
use core::fmt::Error;
use core::{convert::TryInto,
fmt::{Error, Write}};
pub struct Uart {
base_address: usize,
@ -20,9 +19,7 @@ impl Write for Uart {
impl Uart {
pub fn new(base_address: usize) -> Self {
Uart {
base_address
}
Uart { base_address }
}
pub fn init(&mut self) {
@ -32,28 +29,32 @@ impl Uart {
// are bits 0 and 1 of the line control register (LCR)
// which is at base_address + 3
// We can easily write the value 3 here or 0b11, but I'm
// extending it so that it is clear we're setting two individual
// fields
// extending it so that it is clear we're setting two
// individual fields
// Word 0 Word 1
// ~~~~~~ ~~~~~~
let lcr: u8 = (1 << 0) | (1 << 1);
let lcr: u8 = (1 << 0) | (1 << 1);
ptr.add(3).write_volatile(lcr);
// Now, enable the FIFO, which is bit index 0 of the FIFO
// control register (FCR at offset 2).
// Again, we can just write 1 here, but when we use left shift,
// it's easier to see that we're trying to write bit index #0.
// Now, enable the FIFO, which is bit index 0 of the
// FIFO control register (FCR at offset 2).
// Again, we can just write 1 here, but when we use left
// shift, it's easier to see that we're trying to write
// bit index #0.
ptr.add(2).write_volatile(1 << 0);
// Enable receiver buffer interrupts, which is at bit index
// 0 of the interrupt enable register (IER at offset 1).
// Enable receiver buffer interrupts, which is at bit
// index 0 of the interrupt enable register (IER at
// offset 1).
ptr.add(1).write_volatile(1 << 0);
// If we cared about the divisor, the code below would set the divisor
// from a global clock rate of 22.729 MHz (22,729,000 cycles per second)
// to a signaling rate of 2400 (BAUD). We usually have much faster signalling
// rates nowadays, but this demonstrates what the divisor actually does.
// The formula given in the NS16500A specification for calculating the divisor
// If we cared about the divisor, the code below would
// set the divisor from a global clock rate of 22.729
// MHz (22,729,000 cycles per second) to a signaling
// rate of 2400 (BAUD). We usually have much faster
// signalling rates nowadays, but this demonstrates what
// the divisor actually does. The formula given in the
// NS16500A specification for calculating the divisor
// is:
// divisor = ceil( (clock_hz) / (baud_sps x 16) )
// So, we substitute our values and get:
@ -61,30 +62,39 @@ impl Uart {
// divisor = ceil( 22_729_000 / 38_400 )
// divisor = ceil( 591.901 ) = 592
// The divisor register is two bytes (16 bits), so we need to split the value
// 592 into two bytes. Typically, we would calculate this based on measuring
// the clock rate, but again, for our purposes [qemu], this doesn't really do
// anything.
// The divisor register is two bytes (16 bits), so we
// need to split the value 592 into two bytes.
// Typically, we would calculate this based on measuring
// the clock rate, but again, for our purposes [qemu],
// this doesn't really do anything.
let divisor: u16 = 592;
let divisor_least: u8 = (divisor & 0xff).try_into().unwrap();
let divisor_most: u8 = (divisor >> 8).try_into().unwrap();
let divisor_least: u8 =
(divisor & 0xff).try_into().unwrap();
let divisor_most: u8 =
(divisor >> 8).try_into().unwrap();
// Notice that the divisor register DLL (divisor latch least) and DLM (divisor latch most)
// have the same base address as the receiver/transmitter and the interrupt enable register.
// To change what the base address points to, we open the "divisor latch" by writing 1 into
// the Divisor Latch Access Bit (DLAB), which is bit index 7 of the Line Control Register (LCR)
// which is at base_address + 3.
// Notice that the divisor register DLL (divisor latch
// least) and DLM (divisor latch most) have the same
// base address as the receiver/transmitter and the
// interrupt enable register. To change what the base
// address points to, we open the "divisor latch" by
// writing 1 into the Divisor Latch Access Bit (DLAB),
// which is bit index 7 of the Line Control Register
// (LCR) which is at base_address + 3.
ptr.add(3).write_volatile(lcr | 1 << 7);
// Now, base addresses 0 and 1 point to DLL and DLM, respectively.
// Put the lower 8 bits of the divisor into DLL
// Now, base addresses 0 and 1 point to DLL and DLM,
// respectively. Put the lower 8 bits of the divisor
// into DLL
ptr.add(0).write_volatile(divisor_least);
ptr.add(1).write_volatile(divisor_most);
// Now that we've written the divisor, we never have to touch this again. In hardware, this
// will divide the global clock (22.729 MHz) into one suitable for 2,400 signals per second.
// So, to once again get access to the RBR/THR/IER registers, we need to close the DLAB bit
// by clearing it to 0.
// Now that we've written the divisor, we never have to
// touch this again. In hardware, this will divide the
// global clock (22.729 MHz) into one suitable for 2,400
// signals per second. So, to once again get access to
// the RBR/THR/IER registers, we need to close the DLAB
// bit by clearing it to 0.
ptr.add(3).write_volatile(lcr);
}
}