From 9a4d002832c836c3202050cb90b76ffbc2e613c2 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 19 Dec 2019 12:17:07 +0800 Subject: [PATCH] irq commit: this large commit gets interrupts working Signed-off-by: Sean Cross --- Cargo.toml | 2 +- build.rs | 19 ++ src/irq.rs | 83 +++++ src/lib.rs | 12 + src/main.rs | 57 +++- src/syscalls.rs | 291 ++++++++++++++++++ .../Cargo.toml | 8 +- .../README.md | 0 {xous-riscv-rt => xous-kernel-riscv-rt}/asm.S | 0 .../assemble.ps1 | 0 .../assemble.sh | 0 .../bin/riscv32i-unknown-none-elf.a | Bin .../bin/riscv32imac-unknown-none-elf.a | Bin .../bin/riscv32imc-unknown-none-elf.a | Bin .../bin/riscv64gc-unknown-none-elf.a | Bin .../bin/riscv64imac-unknown-none-elf.a | Bin .../build.rs | 0 .../link.x | 0 .../macros/Cargo.toml | 2 +- .../macros/src/lib.rs | 4 +- .../src/lib.rs | 8 +- xous-riscv/asm.S | 7 + xous-riscv/bin/riscv32i-unknown-none-elf.a | Bin 70954 -> 73492 bytes xous-riscv/bin/riscv32imac-unknown-none-elf.a | Bin 69970 -> 72468 bytes xous-riscv/bin/riscv32imc-unknown-none-elf.a | Bin 69970 -> 72468 bytes xous-riscv/bin/riscv64gc-unknown-none-elf.a | Bin 76768 -> 80062 bytes xous-riscv/bin/riscv64imac-unknown-none-elf.a | Bin 76768 -> 80062 bytes xous-riscv/src/register/mod.rs | 7 + xous-riscv/src/register/vdci.rs | 4 + xous-riscv/src/register/vmim.rs | 4 + xous-riscv/src/register/vmip.rs | 4 + xous-riscv/src/register/vsim.rs | 4 + xous-riscv/src/register/vsip.rs | 4 + 33 files changed, 505 insertions(+), 15 deletions(-) create mode 100644 build.rs create mode 100644 src/irq.rs create mode 100644 src/lib.rs create mode 100644 src/syscalls.rs rename {xous-riscv-rt => xous-kernel-riscv-rt}/Cargo.toml (65%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/README.md (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/asm.S (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/assemble.ps1 (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/assemble.sh (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/bin/riscv32i-unknown-none-elf.a (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/bin/riscv32imac-unknown-none-elf.a (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/bin/riscv32imc-unknown-none-elf.a (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/bin/riscv64gc-unknown-none-elf.a (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/bin/riscv64imac-unknown-none-elf.a (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/build.rs (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/link.x (100%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/macros/Cargo.toml (90%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/macros/src/lib.rs (94%) rename {xous-riscv-rt => xous-kernel-riscv-rt}/src/lib.rs (95%) create mode 100644 xous-riscv/src/register/vdci.rs create mode 100644 xous-riscv/src/register/vmim.rs create mode 100644 xous-riscv/src/register/vmip.rs create mode 100644 xous-riscv/src/register/vsim.rs create mode 100644 xous-riscv/src/register/vsip.rs diff --git a/Cargo.toml b/Cargo.toml index 06b7379..2b4e30d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ description = "Core kernel for Xous, including task switching and memory managem [dependencies] xous-riscv = { path = "xous-riscv" } -xous-riscv-rt = { path = "xous-riscv-rt" } +xous-kernel-riscv-rt = { path = "xous-kernel-riscv-rt" } [profile.release] codegen-units = 1 # 1 better optimizations diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..84e26f1 --- /dev/null +++ b/build.rs @@ -0,0 +1,19 @@ +// NOTE: Adapted from cortex-m/build.rs +use std::env; +use std::fs; +use std::io::Write; +use std::path::PathBuf; + +fn main() { + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + + // Put the linker script somewhere the linker can find it + fs::File::create(out_dir.join("memory.x")) + .unwrap() + .write_all(include_bytes!("memory.x")) + .unwrap(); + println!("cargo:rustc-link-search={}", out_dir.display()); + + println!("cargo:rerun-if-changed=build.rs"); + println!("cargo:rerun-if-changed=memory.x"); +} diff --git a/src/irq.rs b/src/irq.rs new file mode 100644 index 0000000..83d00eb --- /dev/null +++ b/src/irq.rs @@ -0,0 +1,83 @@ +use crate::syscalls; +use xous_riscv::register::{mstatus, vmim}; + +// Shamelessly taken from +// https://stackoverflow.com/questions/36258417/using-a-macro-to-initialize-a-big-array-of-non-copy-elements +// Allows us to fill an array with a predefined value. +macro_rules! filled_array { + (@accum (0, $($_es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@as_expr [$($body)*])}; + (@accum (1, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)*))}; + (@accum (2, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (0, $($es),*) -> ($($body)* $($es,)* $($es,)*))}; + (@accum (3, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (2, $($es),*) -> ($($body)* $($es,)*))}; + (@accum (4, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (2, $($es,)* $($es),*) -> ($($body)*))}; + (@accum (5, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)*))}; + (@accum (6, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)*))}; + (@accum (7, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (4, $($es),*) -> ($($body)* $($es,)* $($es,)* $($es,)*))}; + (@accum (8, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (4, $($es,)* $($es),*) -> ($($body)*))}; + (@accum (16, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (8, $($es,)* $($es),*) -> ($($body)*))}; + (@accum (32, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (16, $($es,)* $($es),*) -> ($($body)*))}; + (@accum (64, $($es:expr),*) -> ($($body:tt)*)) + => {filled_array!(@accum (32, $($es,)* $($es),*) -> ($($body)*))}; + + (@as_expr $e:expr) => {$e}; + + [$e:expr; $n:tt] => { filled_array!(@accum ($n, $e) -> ()) }; +} + +static mut IRQ_HANDLERS: [Option; 32] = filled_array![None; 32]; + +pub fn handle(irqs_pending: usize) { + // Unsafe is required here because we're accessing a static + // mutable value, and it could be modified from various threads. + // However, this is fine because this is run from an IRQ context + // with interrupts disabled. + // NOTE: This will become an issue when running with multiple cores, + // so this should be protected by a mutex. + unsafe { + for irq_no in 0..IRQ_HANDLERS.len() { + if irqs_pending & (1 << irq_no) != 0 { + if let Some(f) = IRQ_HANDLERS[irq_no] { + // Call the IRQ handler + f(irq_no); + } else { + // If there is no handler, mask this interrupt + // to prevent an IRQ storm. This is considered + // an error. + vmim::write(vmim::read() | (1 << irq_no)); + } + } + } + } +} + +pub fn sys_interrupt_claim(irq: usize, f: fn(usize)) -> Result<(), syscalls::XousError> { + // Unsafe is required since we're accessing a static mut array. + // However, we disable interrupts to prevent contention on this array. + unsafe { + mstatus::clear_mie(); + let result = if irq > IRQ_HANDLERS.len() { + Err(syscalls::XousError::InterruptNotFound) + } else if IRQ_HANDLERS[irq].is_some() { + Err(syscalls::XousError::InterruptInUse) + } else { + IRQ_HANDLERS[irq] = Some(f); + // Note that the vexriscv "IRQ Mask" register is inverse-logic -- + // that is, setting a bit in the "mask" register unmasks (i.e. enables) it. + vmim::write(vmim::read() | (1 << irq)); + Ok(()) + }; + mstatus::set_mie(); + result + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..8732447 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,12 @@ +#![no_std] + +extern crate xous_riscv; + +use core::panic::PanicInfo; +#[panic_handler] +fn handle_panic(_arg: &PanicInfo) -> ! { + loop {} +} + +// Allow consumers of this library to make syscalls +pub mod syscalls; diff --git a/src/main.rs b/src/main.rs index 43098f8..e92c089 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,17 +2,68 @@ #![no_main] extern crate xous_riscv; +mod syscalls; +mod irq; + +pub use irq::sys_interrupt_claim; use core::panic::PanicInfo; +use xous_kernel_riscv_rt::xous_kernel_entry; +use xous_riscv::register::{mcause, mstatus, mie, vmim, vmip}; + + #[panic_handler] -fn handle_panic(arg: &PanicInfo) -> ! { +fn handle_panic(_arg: &PanicInfo) -> ! { loop {} } -use xous_riscv_rt::entry; -#[entry] +fn print_str(uart: *mut usize, s: &str) { + for c in s.bytes() { + unsafe { uart.write_volatile(c as usize) }; + } +} + +#[xous_kernel_entry] fn xous_main() -> ! { + unsafe { + vmim::write(0); // Disable all machine interrupts + mie::set_msoft(); + mie::set_mtimer(); + mie::set_mext(); + mstatus::set_mie(); // Enable CPU interrupts + } + sys_interrupt_claim(2, |_| { + let uart_ptr = 0xE000_1800 as *mut usize; + print_str(uart_ptr, "hello, world!\r\n"); + // Acknowledge the IRQ + unsafe { + uart_ptr.add(0).read_volatile(); + + // Acknowledge the event + uart_ptr.add(4).write_volatile(3); + }; + }) + .unwrap(); + + // Enable interrupts + let uart_ptr = 0xE000_1800 as *mut usize; + unsafe { uart_ptr.add(4).write_volatile(3) }; + unsafe { uart_ptr.add(5).write_volatile(3) }; + print_str(uart_ptr, "greetings!\r\n"); + loop { unsafe { xous_riscv::asm::wfi() }; } } + +#[no_mangle] +pub fn trap_handler() { + let mc = mcause::read(); + let irqs_pending = vmip::read(); + + if mc.is_exception() {} + + if irqs_pending != 0 { + irq::handle(irqs_pending); + } +} diff --git a/src/syscalls.rs b/src/syscalls.rs new file mode 100644 index 0000000..687ba56 --- /dev/null +++ b/src/syscalls.rs @@ -0,0 +1,291 @@ +use core::num::NonZeroUsize; + +#[allow(dead_code)] pub type MemoryAddress = NonZeroUsize; +#[allow(dead_code)] pub type MemorySize = NonZeroUsize; +#[allow(dead_code)] pub type StackPointer = usize; +#[allow(dead_code)] pub type MessageId = usize; + +#[allow(dead_code)] pub type XousPid = u8; +#[allow(dead_code)] pub type XousMessageSender = usize; +#[allow(dead_code)] pub type XousConnection = usize; + +/// Server ID +#[allow(dead_code)] pub type XousSid = usize; + +/// Equivalent to a RISC-V Hart ID +#[allow(dead_code)] pub type XousCpuId = usize; + +#[allow(dead_code)] +#[derive(Debug)] +pub enum XousError { + BadAlignment, + BadAddress, + OutOfMemory, + InterruptNotFound, + InterruptInUse, + InvalidString, + ServerExists, + ServerNotFound, + ProcessNotFound, + ProcessNotChild, + ProcessTerminated, + Timeout, +} + +#[allow(dead_code)] +pub struct XousContext { + stack: StackPointer, + pid: XousPid, +} + +#[allow(dead_code)] +pub struct XousMemoryMessage { + id: MessageId, + in_buf: Option, + in_buf_size: Option, + out_buf: Option, + out_buf_size: Option, +} + +#[allow(dead_code)] +pub struct XousScalarMessage { + id: MessageId, + arg1: usize, + arg2: usize, + arg3: usize, + arg4: usize, +} + +#[allow(dead_code)] +pub enum XousMessage { + Memory(XousMemoryMessage), + Scalar(XousScalarMessage), +} + +#[allow(dead_code)] +pub struct XousMessageReceived { + sender: XousMessageSender, + message: XousMessage, +} + +extern "Rust" { + /// Allocates kernel structures for a new process, and returns the new PID. + /// This removes `page_count` page tables from the calling process at `origin_address` + /// and places them at `target_address`. + /// + /// If the process was created successfully, then the new PID is returned to + /// the calling process. The child is not automatically scheduled for running. + /// + /// # Errors + /// + /// * **BadAlignment**: `origin_address` or `target_address` were not page-aligned, + /// or `address_size` was not a multiple of the page address size. + /// * **OutOfMemory**: The kernel couldn't allocate memory for the new process. + #[allow(dead_code)] + pub fn sys_process_spawn( + origin_address: MemoryAddress, + target_address: MemoryAddress, + address_size: MemorySize, + ) -> Result; + + /// Pauses execution of the current thread and returns execution to the parent + /// process. This function may return at any time in the future, including immediately. + #[allow(dead_code)] + pub fn sys_process_yield(); + + /// Interrupts the current process and returns control to the parent process. + /// + /// # Errors + /// + /// * **ProcessNotFound**: The provided PID doesn't exist, or is not running on the given CPU. + #[allow(dead_code)] + pub fn sysi_process_suspend(pid: XousPid, cpu_id: XousCpuId) -> Result<(), XousError>; + + /// Claims an interrupt and unmasks it immediately. The provided function will + /// be called from within an interrupt context, but using the ordinary privilege level of + /// the process. + /// + /// # Errors + /// + /// * **InterruptNotFound**: The specified interrupt isn't valid on this system + /// * **InterruptInUse**: The specified interrupt has already been claimed + #[allow(dead_code)] + pub fn sys_interrupt_claim(irq: usize, f: fn(usize)) -> Result<(), XousError>; + + /// Returns the interrupt back to the operating system and masks it again. + /// This function is implicitly called when a process exits. + /// + /// # Errors + /// + /// * **InterruptNotFound**: The specified interrupt doesn't exist, or isn't assigned + /// to this process. + #[allow(dead_code)] + pub fn sys_interrupt_free(irq: usize) -> Result<(), XousError>; + + /// Resumes a process using the given stack pointer. A parent could use + /// this function to implement multi-threading inside a child process, or + /// to create a task switcher. + /// + /// To resume a process exactly where it left off, set `stack_pointer` to `None`. + /// This would be done in a very simple system that has no threads. + /// + /// By default, at most three context switches can be made before the quantum + /// expires. To enable more, pass `additional_contexts`. + /// + /// If no more contexts are available when one is required, then the child + /// automatically relinquishes its quantum. + /// + /// # Returns + /// + /// When this function returns, it provides a list of the processes and + /// stack pointers that are ready to be run. Three can fit as return values, + /// and additional context switches will be supplied in the slice of context + /// switches, if one is provided. + /// + /// # Examples + /// + /// If a process called `yield()`, or if its quantum expired normally, then + /// a single context is returned: The target thread, and its stack pointer. + /// + /// If the child process called `client_send()` and ended up blocking due to + /// the server not being ready, then this would return no context switches. + /// This thread or process should not be scheduled to run. + /// + /// If the child called `client_send()` and the server was ready, then the + /// server process would be run immediately. If the child process' quantum + /// expired while the server was running, then this function would return + /// a single context containing the PID of the server, and the stack pointer. + /// + /// If the child called `client_send()` and the server was ready, then the + /// server process would be run immediately. If the server then finishes, + /// execution flow is returned to the child process. If the quantum then + /// expires, this would return two contexts: the server's PID and its stack + /// pointer when it called `client_reply()`, and the child's PID with its + /// current stack pointer. + /// + /// If the server in turn called another server, and both servers ended up + /// returning to the child before the quantum expired, then there would be + /// three contexts on the stack. + /// + /// # Errors + /// + /// * **ProcessNotFound**: The requested process does not exist + /// * **ProcessNotChild**: The given process was not a child process, and + /// therefore couldn't be resumed. + /// * **ProcessTerminated**: The process has crashed. + #[allow(dead_code)] + pub fn sys_process_resume( + process_id: XousPid, + stack_pointer: Option, + additional_contexts: &Option<&[XousContext]>, + ) -> Result< + ( + Option, + Option, + Option, + ), + XousError, + >; + + /// Causes a process to terminate immediately. + /// + /// It is recommended that this function only be called on processes that + /// have cleaned up after themselves, e.g. shut down any servers and + /// flushed any file descriptors. + /// + /// # Errors + /// + /// * **ProcessNotFound**: The requested process does not exist + /// * **ProcessNotChild**: The requested process is not our child process + #[allow(dead_code)] + pub fn sys_process_terminate(process_id: XousPid) -> Result<(), XousError>; + + /// Allocates pages of memory, equal to a total of `size + /// bytes. If a physical address is specified, then this + /// can be used to allocate regions such as memory-mapped I/O. + /// If a virtual address is specified, then the returned + /// pages are located at that address. Otherwise, they + /// are located at an unspecified offset. + /// + /// # Errors + /// + /// * **BadAlignment**: Either the physical or virtual addresses aren't page-aligned, or the size isn't a multiple of the page width. + /// * **OutOfMemory**: A contiguous chunk of memory couldn't be found, or the system's memory size has been exceeded. + #[allow(dead_code)] + pub fn sys_memory_allocate( + phys: Option, + virt: Option, + size: MemorySize, + ) -> Result; + + /// Equivalent to the Unix `sbrk` call. Adjusts the + /// heap size to be equal to the specified value. Heap + /// sizes start out at 0 bytes in new processes. + /// + /// # Errors + /// + /// * **OutOfMemory**: The region couldn't be extended. + #[allow(dead_code)] + pub fn sys_heap_resize(size: MemorySize) -> Result<(), XousError>; + + ///! Message Passing Functions + + /// Create a new server with the given name. This enables other processes to + /// connect to this server to send messages. Only one server name may exist + /// on a system at a time. + /// + /// # Errors + /// + /// * **ServerExists**: A server has already registered with that name + /// * **InvalidString**: The name was not a valid UTF-8 string + #[allow(dead_code)] + pub fn sys_server_create(server_name: usize) -> Result; + + /// Suspend the current process until a message is received. This thread will + /// block until a message is received. + /// + /// # Errors + /// + #[allow(dead_code)] + pub fn sys_server_receive(server_id: XousSid) -> Result; + + /// Reply to a message received. The thread will be unblocked, and will be + /// scheduled to run sometime in the future. + /// + /// If the message that we're responding to is a Memory message, then it should be + /// passed back directly to the destination without modification -- the actual contents + /// will be passed in the `out` address pointed to by the structure. + /// + /// # Errors + /// + /// * **ProcessTerminated**: The process we're replying to doesn't exist any more. + /// * **BadAddress**: The message didn't pass back all the memory it should have. + #[allow(dead_code)] + pub fn sys_server_reply( + destination: XousMessageSender, + message: XousMessage, + ) -> Result<(), XousError>; + + /// Look up a server name and connect to it. + /// + /// # Errors + /// + /// * **ServerNotFound**: No server is registered with that name. + #[allow(dead_code)] + pub fn sys_client_connect(server_name: usize) -> Result; + + /// Send a message to a server. This thread will block until the message is responded to. + /// If the message type is `Memory`, then the memory addresses pointed to will be + /// unavailable to this process until this function returns. + /// + /// # Errors + /// + /// * **ServerNotFound**: The server does not exist so the connection is now invalid + /// * **BadAddress**: The client tried to pass a Memory message using an address it doesn't own + /// * **Timeout**: The timeout limit has been reached + #[allow(dead_code)] + pub fn sys_client_send( + server: XousConnection, + message: XousMessage, + ) -> Result; +} diff --git a/xous-riscv-rt/Cargo.toml b/xous-kernel-riscv-rt/Cargo.toml similarity index 65% rename from xous-riscv-rt/Cargo.toml rename to xous-kernel-riscv-rt/Cargo.toml index f7f808e..fc53327 100644 --- a/xous-riscv-rt/Cargo.toml +++ b/xous-kernel-riscv-rt/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "xous-riscv-rt" +name = "xous-kernel-riscv-rt" version = "0.6.1" repository = "https://github.com/xous/xous-riscv-rt" authors = ["Sean Cross ", "The RISC-V Team "] @@ -10,9 +10,9 @@ license = "ISC" [dependencies] r0 = "0.2.2" -xous-riscv = { path = "../xous-riscv", version = "0.5.1" } -riscv-rt-macros = { path = "macros", version = "0.1.6" } +xous-riscv = { path = "../xous-riscv" } +xous-kernel-riscv-rt-macros = { path = "macros" } [dev-dependencies] -xous-riscv = { path = "../xous-riscv", version = "0.5.1" } +xous-riscv = { path = "../xous-riscv" } panic-halt = "0.2.0" diff --git a/xous-riscv-rt/README.md b/xous-kernel-riscv-rt/README.md similarity index 100% rename from xous-riscv-rt/README.md rename to xous-kernel-riscv-rt/README.md diff --git a/xous-riscv-rt/asm.S b/xous-kernel-riscv-rt/asm.S similarity index 100% rename from xous-riscv-rt/asm.S rename to xous-kernel-riscv-rt/asm.S diff --git a/xous-riscv-rt/assemble.ps1 b/xous-kernel-riscv-rt/assemble.ps1 similarity index 100% rename from xous-riscv-rt/assemble.ps1 rename to xous-kernel-riscv-rt/assemble.ps1 diff --git a/xous-riscv-rt/assemble.sh b/xous-kernel-riscv-rt/assemble.sh similarity index 100% rename from xous-riscv-rt/assemble.sh rename to xous-kernel-riscv-rt/assemble.sh diff --git a/xous-riscv-rt/bin/riscv32i-unknown-none-elf.a b/xous-kernel-riscv-rt/bin/riscv32i-unknown-none-elf.a similarity index 100% rename from xous-riscv-rt/bin/riscv32i-unknown-none-elf.a rename to xous-kernel-riscv-rt/bin/riscv32i-unknown-none-elf.a diff --git a/xous-riscv-rt/bin/riscv32imac-unknown-none-elf.a b/xous-kernel-riscv-rt/bin/riscv32imac-unknown-none-elf.a similarity index 100% rename from xous-riscv-rt/bin/riscv32imac-unknown-none-elf.a rename to xous-kernel-riscv-rt/bin/riscv32imac-unknown-none-elf.a diff --git a/xous-riscv-rt/bin/riscv32imc-unknown-none-elf.a b/xous-kernel-riscv-rt/bin/riscv32imc-unknown-none-elf.a similarity index 100% rename from xous-riscv-rt/bin/riscv32imc-unknown-none-elf.a rename to xous-kernel-riscv-rt/bin/riscv32imc-unknown-none-elf.a diff --git a/xous-riscv-rt/bin/riscv64gc-unknown-none-elf.a b/xous-kernel-riscv-rt/bin/riscv64gc-unknown-none-elf.a similarity index 100% rename from xous-riscv-rt/bin/riscv64gc-unknown-none-elf.a rename to xous-kernel-riscv-rt/bin/riscv64gc-unknown-none-elf.a diff --git a/xous-riscv-rt/bin/riscv64imac-unknown-none-elf.a b/xous-kernel-riscv-rt/bin/riscv64imac-unknown-none-elf.a similarity index 100% rename from xous-riscv-rt/bin/riscv64imac-unknown-none-elf.a rename to xous-kernel-riscv-rt/bin/riscv64imac-unknown-none-elf.a diff --git a/xous-riscv-rt/build.rs b/xous-kernel-riscv-rt/build.rs similarity index 100% rename from xous-riscv-rt/build.rs rename to xous-kernel-riscv-rt/build.rs diff --git a/xous-riscv-rt/link.x b/xous-kernel-riscv-rt/link.x similarity index 100% rename from xous-riscv-rt/link.x rename to xous-kernel-riscv-rt/link.x diff --git a/xous-riscv-rt/macros/Cargo.toml b/xous-kernel-riscv-rt/macros/Cargo.toml similarity index 90% rename from xous-riscv-rt/macros/Cargo.toml rename to xous-kernel-riscv-rt/macros/Cargo.toml index 31de3cb..cb92a0a 100644 --- a/xous-riscv-rt/macros/Cargo.toml +++ b/xous-kernel-riscv-rt/macros/Cargo.toml @@ -8,7 +8,7 @@ description = "Attributes re-exported in `riscv-rt`" documentation = "https://docs.rs/riscv-rt" keywords = ["riscv", "runtime", "startup"] license = "MIT OR Apache-2.0" -name = "riscv-rt-macros" +name = "xous-kernel-riscv-rt-macros" repository = "https://github.com/rust-embedded/riscv-rt" version = "0.1.6" diff --git a/xous-riscv-rt/macros/src/lib.rs b/xous-kernel-riscv-rt/macros/src/lib.rs similarity index 94% rename from xous-riscv-rt/macros/src/lib.rs rename to xous-kernel-riscv-rt/macros/src/lib.rs index 8efe092..84dfb81 100644 --- a/xous-riscv-rt/macros/src/lib.rs +++ b/xous-kernel-riscv-rt/macros/src/lib.rs @@ -53,7 +53,7 @@ use proc_macro::TokenStream; /// } /// ``` #[proc_macro_attribute] -pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { +pub fn xous_kernel_entry(args: TokenStream, input: TokenStream) -> TokenStream { let f = parse_macro_input!(input as ItemFn); // check the function signature @@ -94,7 +94,7 @@ pub fn entry(args: TokenStream, input: TokenStream) -> TokenStream { let stmts = f.block.stmts; quote!( - #[export_name = "xous_main"] + #[export_name = "xous_kernel_main"] #(#attrs)* pub #unsafety fn #hash() -> ! { #(#stmts)* diff --git a/xous-riscv-rt/src/lib.rs b/xous-kernel-riscv-rt/src/lib.rs similarity index 95% rename from xous-riscv-rt/src/lib.rs rename to xous-kernel-riscv-rt/src/lib.rs index 5624697..bc41b5c 100644 --- a/xous-riscv-rt/src/lib.rs +++ b/xous-kernel-riscv-rt/src/lib.rs @@ -254,10 +254,10 @@ #![deny(warnings)] extern crate xous_riscv; -extern crate riscv_rt_macros as macros; +extern crate xous_kernel_riscv_rt_macros as macros; extern crate r0; -pub use macros::{entry, pre_init}; +pub use macros::{xous_kernel_entry, pre_init}; use xous_riscv::register::mstatus; @@ -288,7 +288,7 @@ extern "C" { pub unsafe extern "C" fn start_rust() -> ! { extern "Rust" { // This symbol will be provided by the kernel - fn xous_main() -> !; + fn xous_kernel_main() -> !; // This symbol will be provided by the user via `#[pre_init]` fn __pre_init(); @@ -303,7 +303,7 @@ pub unsafe extern "C" fn start_rust() -> ! { r0::init_data(&mut _sdata, &mut _edata, &_sidata); } - xous_main(); + xous_kernel_main(); } diff --git a/xous-riscv/asm.S b/xous-riscv/asm.S index e861189..e42d90c 100644 --- a/xous-riscv/asm.S +++ b/xous-riscv/asm.S @@ -315,3 +315,10 @@ RW(0x7A3, tdata3) // Third Debug/Trace trigger data register RW(0x7B0, dcsr) // Debug control and status register RW(0x7B1, dpc) // Debug PC RW(0x7B2, dscratch) // Debug scratch register + +// VexRiscv custom registers +RW(0xBC0, vmim) // Machine IRQ Mask +RW(0xFC0, vmip) // Machine IRQ Pending +RW(0x9C0, vsim) // Supervisor IRQ Mask +RW(0xDC0, vsip) // Supervisor IRQ Pending +RW(0xCC0, vdci) // DCache Info diff --git a/xous-riscv/bin/riscv32i-unknown-none-elf.a b/xous-riscv/bin/riscv32i-unknown-none-elf.a index 72d93bc2de9797b69936552fe9e17f17f8589670..516d9295be665459fd912218eb07b5d690167e4a 100644 GIT binary patch delta 4851 zcmeH~O=uHA6vy9AvT3c=#8MDSrQ2$(l{Tg|Nn7Zlen1aOQSeYfh_MM8+R&PfwL;7G z>MamO1W!E(7Ci+oA|6C?>Os&;p?LCEkJ8Vyb#`ZGcju8k1R_1O1Ie5J+uwU{GCO&j zEG>CoeDUU6wf^4NU^J#EVMQO#cSY$94}=E{|NRC4;sdxiSL2sf>x5P2(`x>Ss#}0o z`z@_%0a}gkXH~^%?W6mDum|wy{#ScqYs(*f{|~kS9rpfz=YMQ}F;IWLU5m%FsYEh9 zlSyYF9)Frm=Tcm#sT`k$kCMJwEv8frL3z(gHqV{CdYSZ{kXzCLE_0${fkFj4_g}Y*t9`dHLo+P$jpWfdj{wNmQ8?JMP@cEFBkg;^KJC8VGj>%NVWp-z$VgLNN*#( zgLE0`U8MIk(XUG zZ%D&}-jr?#dP^D;^tO}~^p5mc&}C^((7T%STyX43F9p3XEeaaQ2SH2Zlb{JH3ED$` z2--`23Hq8$)&z%-YzVrJcsrasR8RbZru%xRyG=-amdPa^K(XoddUs*vU8837+fXhw zn+pkDm%FUq%NZ}VeVBW!_C0MuR!`=Pkx0{fxef7lYv(pI>D`zI8kw99s{z{# zPh_XI64@@AD4}}f?QCGoN8Y&K#Mn{b%ME?{U|`oS>iwV48n1l9X%Vf?B>ax^+Gw r7bq9F0?$8I^H8wGAZE zyn3qph%^V(Q$I*aazH(m`&CRg24h#(p%*@Ob6wC~aO-v?l)KV8&F^2&ROu(cD z!!O34jGNzRP2k@wW8EXa`9-vXJR<|xlFcde{_9M>aK>sg&siToL1qSq0*F=yh9mq8 z3{sO5&k0YTBgZJf_W;P9V8_7lgOP#ZJLB|Sa*R@J1%3<+>Wb5E$uTNPOwVUv5YUBb J2DVP1OaQ}l`r-fp diff --git a/xous-riscv/bin/riscv32imac-unknown-none-elf.a b/xous-riscv/bin/riscv32imac-unknown-none-elf.a index 799dc790cbf2c88c53613b1e0eea1fdb517f54ae..ca631c06a46980c0bd6c64ce679a3528331ac91a 100644 GIT binary patch delta 4808 zcmeH~Jxmlq6vyAr-SMrQh8SWP(#86pjWn!qTpt0in!+*a44k?u%0_dh8CAO!$Tvw6PEd?(B?pPBbN%54E={a@PH76%%y1UjP~ZLN!A zjrA4HZviv_Xr~uI16(8*NcLUh`%=>g!Pl4bMlisv&TWL-5FBtnvwDEp2)7}4!~M+a z0cIoIhTu2%Gph%fjc^-+@7&L<9$+@YY;OZyNIIE))UjAi-we+1!8Ti|96s1VdKc+E zr1z0NK>85rBNI7}kp?1HLnl7akS0j`koF@TK>Bt8augz6gmf{|B_z8ss8^fyHO@kV zu%)#rdRyyJ^p194(YxA^qW82>Mel3R6n&u0D*DjWUMY?vZAsC`+KQrqd{neXz9^cI zHAVZ#PeuF5x}xs{$fn{bAlr&AB>r0W4i%AdMbmvf(+wqTyqL(uhar1&X{*`HBxW*U z(fC+v4ci`9gB32>W`#rcPAAN1xdM`jQZlz}zhO~dW^y3WS)JT=Cf0aGa-PZUkiFJn zL?S1(Oq4QlCI^z49G8`ewPjJ?&g6E13QUEb$4$X2yu*I5-zy0yxt|4y2gKKvR=Vcjdn0IRqA!oy;vD?xF{`g18F7iPw|Z>Q4x~DnR=v1h$8I^H8wGAZE zyn3qph%^V(Q$I*aazH(m`&CRg24h#(p%*@Ob6ih9R%?u`Q)KV9@Fay{+U|?V{ z0b&LQ4TfKgKN&Z_(OSj5na_Nd{N@+o3i6B$U`sZq%=)i0`N9dS%{(W4`~;a97z)68 zfW$p+pi?F%o)VruM~YE^kAsJSVS*h4!w;ar-x;Uxl46u%o8iU4psqOmmK39s#Qtms N1_51|W{CYD9srRf`l$c_ diff --git a/xous-riscv/bin/riscv32imc-unknown-none-elf.a b/xous-riscv/bin/riscv32imc-unknown-none-elf.a index 799dc790cbf2c88c53613b1e0eea1fdb517f54ae..ca631c06a46980c0bd6c64ce679a3528331ac91a 100644 GIT binary patch delta 4808 zcmeH~Jxmlq6vyAr-SMrQh8SWP(#86pjWn!qTpt0in!+*a44k?u%0_dh8CAO!$Tvw6PEd?(B?pPBbN%54E={a@PH76%%y1UjP~ZLN!A zjrA4HZviv_Xr~uI16(8*NcLUh`%=>g!Pl4bMlisv&TWL-5FBtnvwDEp2)7}4!~M+a z0cIoIhTu2%Gph%fjc^-+@7&L<9$+@YY;OZyNIIE))UjAi-we+1!8Ti|96s1VdKc+E zr1z0NK>85rBNI7}kp?1HLnl7akS0j`koF@TK>Bt8augz6gmf{|B_z8ss8^fyHO@kV zu%)#rdRyyJ^p194(YxA^qW82>Mel3R6n&u0D*DjWUMY?vZAsC`+KQrqd{neXz9^cI zHAVZ#PeuF5x}xs{$fn{bAlr&AB>r0W4i%AdMbmvf(+wqTyqL(uhar1&X{*`HBxW*U z(fC+v4ci`9gB32>W`#rcPAAN1xdM`jQZlz}zhO~dW^y3WS)JT=Cf0aGa-PZUkiFJn zL?S1(Oq4QlCI^z49G8`ewPjJ?&g6E13QUEb$4$X2yu*I5-zy0yxt|4y2gKKvR=Vcjdn0IRqA!oy;vD?xF{`g18F7iPw|Z>Q4x~DnR=v1h$8I^H8wGAZE zyn3qph%^V(Q$I*aazH(m`&CRg24h#(p%*@Ob6ih9R%?u`Q)KV9@Fay{+U|?V{ z0b&LQ4TfKgKN&Z_(OSj5na_Nd{N@+o3i6B$U`sZq%=)i0`N9dS%{(W4`~;a97z)68 zfW$p+pi?F%o)VruM~YE^kAsJSVS*h4!w;ar-x;Uxl46u%o8iU4psqOmmK39s#Qtms N1_51|W{CYD9srRf`l$c_ diff --git a/xous-riscv/bin/riscv64gc-unknown-none-elf.a b/xous-riscv/bin/riscv64gc-unknown-none-elf.a index 223145178ee1e17a73e093141c4109061b808241..702db08cc69c531d29f622aee38c6bd4b965a41d 100644 GIT binary patch delta 4262 zcmeH~O=uHA6vt<6Vl@a>Tdl1Hm)f+E+PDSVTCvbx#Dj{8y_%+N4nb=}Hdd>a)gt1t zFhZ#KQAHF*uy*bDN1FPDB3iw8P_!tBSJ8urqBC!HX4foxhy*;?g}(gX@6G(*B%8dX zbFW-epItpgT1{njZB>mdD>A*TQI>0!+KqtaCJ#bV0-?1}GW@4y+AvK&E#uE9y#r{O ze@W9ifR^F=nO1Ysd;b3a+c)6+{ZIEDo7wgApZ|Y5fU5uQ>~{pdSiI6*qiou! z;L+j@`QNS}xFizmLDi#2(nI}MvEX148LS z-4$w3s3D<-g&GlRRH!kb#)X;?YEq~vp%Ow(3zZaV29%4O`JR5MvA`GaTPnG<9CVw$ z(tlhRRwI;y`fdCs@H;j>2z6wN>&kySWBh7oTP)a&^gX>pUM&_n67%y}NT;peAeNcSk(j(3h;eFeGp8_LB#a`$ zTTEm>?=PIpMSR$r-i8yM#oQd6tU!!ka}75#t%XrUOLa0A2`3XVCpxKlf5XX&#AxSh z3?o=WW;+?}!B{LBZax$Xsd!altKO72wLgB`u_u$RRQfW4R*(c@WxwkI7C0QbU zfONrjR{YAcJ&-NVE+zjyl2746yzE^ro_Opn;J`94sN4tZ3)ef8TbW%QFXP?Bjx;aa z#Yu`^#1kKLNo7v$Iz0I3tYh^!?dDkRW=HLH=zPY5zyB;-#H;v)andPHQcil7**$kC zpJV0s4&^>p{_0S^#>&}c#%)OHeT$V>Ig|%T`DNK6Qq4jrg7EG+@@+}3b+{q92KP6* x;w9x$-il8iX1i@Kdwf9d`2F~fa;e;-1Q$a4mI*TTMiz#~hDHhs1_~g6Oe!c?n44LEg%uLG7#J8=GcYK%P#M=#+dvY{ ztEak;NOM3v^@Efo2h>wJK1s41X!mIR4{QP)jek;8EOph7^!%Sn-QdJgnr=34o*->n zkzZP@Ta;OxT&9<=53JV=P0h`)Rey#C24-ev3JPZC7Uo8i|10Z@C(L0014ba}0A@Kb zY-ZfF*;R#+Yx6$64H}#MA~`fRn>A0A-n?i2e$~k@j)gHZFi21Se?ok7*zug~>4(f2 zMK~RRwI~Q^PL@9{KmDIMql9PyRH!2WBDE1{#fItH7L3|lKcXN)6Qw6BoR(u0oNjNy PD9+Vc1`)lW3K9hX3!hz` diff --git a/xous-riscv/bin/riscv64imac-unknown-none-elf.a b/xous-riscv/bin/riscv64imac-unknown-none-elf.a index 223145178ee1e17a73e093141c4109061b808241..702db08cc69c531d29f622aee38c6bd4b965a41d 100644 GIT binary patch delta 4262 zcmeH~O=uHA6vt<6Vl@a>Tdl1Hm)f+E+PDSVTCvbx#Dj{8y_%+N4nb=}Hdd>a)gt1t zFhZ#KQAHF*uy*bDN1FPDB3iw8P_!tBSJ8urqBC!HX4foxhy*;?g}(gX@6G(*B%8dX zbFW-epItpgT1{njZB>mdD>A*TQI>0!+KqtaCJ#bV0-?1}GW@4y+AvK&E#uE9y#r{O ze@W9ifR^F=nO1Ysd;b3a+c)6+{ZIEDo7wgApZ|Y5fU5uQ>~{pdSiI6*qiou! z;L+j@`QNS}xFizmLDi#2(nI}MvEX148LS z-4$w3s3D<-g&GlRRH!kb#)X;?YEq~vp%Ow(3zZaV29%4O`JR5MvA`GaTPnG<9CVw$ z(tlhRRwI;y`fdCs@H;j>2z6wN>&kySWBh7oTP)a&^gX>pUM&_n67%y}NT;peAeNcSk(j(3h;eFeGp8_LB#a`$ zTTEm>?=PIpMSR$r-i8yM#oQd6tU!!ka}75#t%XrUOLa0A2`3XVCpxKlf5XX&#AxSh z3?o=WW;+?}!B{LBZax$Xsd!altKO72wLgB`u_u$RRQfW4R*(c@WxwkI7C0QbU zfONrjR{YAcJ&-NVE+zjyl2746yzE^ro_Opn;J`94sN4tZ3)ef8TbW%QFXP?Bjx;aa z#Yu`^#1kKLNo7v$Iz0I3tYh^!?dDkRW=HLH=zPY5zyB;-#H;v)andPHQcil7**$kC zpJV0s4&^>p{_0S^#>&}c#%)OHeT$V>Ig|%T`DNK6Qq4jrg7EG+@@+}3b+{q92KP6* x;w9x$-il8iX1i@Kdwf9d`2F~fa;e;-1Q$a4mI*TTMiz#~hDHhs1_~g6Oe!c?n44LEg%uLG7#J8=GcYK%P#M=#+dvY{ ztEak;NOM3v^@Efo2h>wJK1s41X!mIR4{QP)jek;8EOph7^!%Sn-QdJgnr=34o*->n zkzZP@Ta;OxT&9<=53JV=P0h`)Rey#C24-ev3JPZC7Uo8i|10Z@C(L0014ba}0A@Kb zY-ZfF*;R#+Yx6$64H}#MA~`fRn>A0A-n?i2e$~k@j)gHZFi21Se?ok7*zug~>4(f2 zMK~RRwI~Q^PL@9{KmDIMql9PyRH!2WBDE1{#fItH7L3|lKcXN)6Qw6BoR(u0oNjNy PD9+Vc1`)lW3K9hX3!hz` diff --git a/xous-riscv/src/register/mod.rs b/xous-riscv/src/register/mod.rs index 1660e41..c1a75bf 100644 --- a/xous-riscv/src/register/mod.rs +++ b/xous-riscv/src/register/mod.rs @@ -107,3 +107,10 @@ pub use self::mhpmeventx::*; // TODO: Debug Mode Registers + +// VexRiscv registers +pub mod vmim; +pub mod vmip; +pub mod vsim; +pub mod vsip; +pub mod vdci; diff --git a/xous-riscv/src/register/vdci.rs b/xous-riscv/src/register/vdci.rs new file mode 100644 index 0000000..26bf062 --- /dev/null +++ b/xous-riscv/src/register/vdci.rs @@ -0,0 +1,4 @@ +//! uscratch register + +read_csr_as_usize!(0xCC0, __read_vdci); +write_csr_as_usize!(0xCC0, __write_vdci); diff --git a/xous-riscv/src/register/vmim.rs b/xous-riscv/src/register/vmim.rs new file mode 100644 index 0000000..8e160e9 --- /dev/null +++ b/xous-riscv/src/register/vmim.rs @@ -0,0 +1,4 @@ +//! uscratch register + +read_csr_as_usize!(0xBC0, __read_vmim); +write_csr_as_usize!(0xBC0, __write_vmim); diff --git a/xous-riscv/src/register/vmip.rs b/xous-riscv/src/register/vmip.rs new file mode 100644 index 0000000..345081d --- /dev/null +++ b/xous-riscv/src/register/vmip.rs @@ -0,0 +1,4 @@ +//! uscratch register + +read_csr_as_usize!(0xFC0, __read_vmip); +write_csr_as_usize!(0xFC0, __write_vmip); diff --git a/xous-riscv/src/register/vsim.rs b/xous-riscv/src/register/vsim.rs new file mode 100644 index 0000000..a2f341a --- /dev/null +++ b/xous-riscv/src/register/vsim.rs @@ -0,0 +1,4 @@ +//! uscratch register + +read_csr_as_usize!(0x9C0, __read_vsim); +write_csr_as_usize!(0x9C0, __write_vsim); diff --git a/xous-riscv/src/register/vsip.rs b/xous-riscv/src/register/vsip.rs new file mode 100644 index 0000000..16eafc0 --- /dev/null +++ b/xous-riscv/src/register/vsip.rs @@ -0,0 +1,4 @@ +//! uscratch register + +read_csr_as_usize!(0xDC0, __read_vsip); +write_csr_as_usize!(0xDC0, __write_vsip);