Compare commits
1 Commits
riscv
...
feat/conso
| Author | SHA1 | Date |
|---|---|---|
|
|
94e6d016ac |
|
|
@ -182,3 +182,25 @@ void consoleinit(void) {
|
||||||
devsw[CONSOLE].read = consoleread;
|
devsw[CONSOLE].read = consoleread;
|
||||||
devsw[CONSOLE].write = consolewrite;
|
devsw[CONSOLE].write = consolewrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// int consoleread(int, uint64, int);
|
||||||
|
// int consolewrite(int, uint64, int);
|
||||||
|
|
||||||
|
// struct {
|
||||||
|
// struct spinlock lock;
|
||||||
|
|
||||||
|
// // input
|
||||||
|
// #define INPUT_BUF_SIZE 128
|
||||||
|
// char buf[INPUT_BUF_SIZE];
|
||||||
|
// uint r; // Read index
|
||||||
|
// uint w; // Write index
|
||||||
|
// uint e; // Edit index
|
||||||
|
// } cons;
|
||||||
|
|
||||||
|
// // Call from consoleinit
|
||||||
|
// void connect_console_syscalls() {
|
||||||
|
// // connect read and write system calls
|
||||||
|
// // to consoleread and consolewrite.
|
||||||
|
// devsw[CONSOLE].read = consoleread;
|
||||||
|
// devsw[CONSOLE].write = consolewrite;
|
||||||
|
// }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,198 @@
|
||||||
|
use core::ptr::{addr_of, addr_of_mut, null, null_mut};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
spinlock::{initlock, SpinLock},
|
||||||
|
uart::{uartinit, uartputc},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Console input and output, to the uart.
|
||||||
|
// Reads are line at a time.
|
||||||
|
// Implements special input characters:
|
||||||
|
// newline -- end of line
|
||||||
|
// control-h -- backspace
|
||||||
|
// control-u -- kill line
|
||||||
|
// control-d -- end of file
|
||||||
|
// control-p -- print process list
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
// proc.c
|
||||||
|
fn either_copyout(user_dst: i32, dst: u64, src: *mut (), len: u64) -> i32;
|
||||||
|
fn either_copyin(dst: *mut (), user_src: i32, src: u64, len: u64) -> i32;
|
||||||
|
fn killed(proc: *const ()) -> bool;
|
||||||
|
fn myproc() -> *const ();
|
||||||
|
fn sleep(chan: *const u64, lock: *mut SpinLock);
|
||||||
|
fn procdump();
|
||||||
|
|
||||||
|
// spinlock.c
|
||||||
|
fn acquire(lock: *mut SpinLock);
|
||||||
|
fn release(lock: *mut SpinLock);
|
||||||
|
|
||||||
|
// console.c
|
||||||
|
fn connect_console_syscalls();
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn control_modified(c: i32) -> i32 {
|
||||||
|
c - b'@' as i32
|
||||||
|
}
|
||||||
|
|
||||||
|
const BACKSPACE: i32 = 0x100;
|
||||||
|
const INPUT_BUF_SIZE: usize = 128;
|
||||||
|
const CODE_BACKSPACE: i32 = control_modified(b'H' as i32);
|
||||||
|
const CODE_KILL_LINE: i32 = control_modified(b'U' as i32);
|
||||||
|
const CODE_END_OF_FILE: i32 = control_modified(b'D' as i32);
|
||||||
|
const CODE_PRINT_PROCESSES: i32 = control_modified(b'P' as i32);
|
||||||
|
|
||||||
|
// #[repr(C)]
|
||||||
|
// struct Console {
|
||||||
|
// lock: SpinLock,
|
||||||
|
// /// Input
|
||||||
|
// buf: [u8; INPUT_BUF_SIZE],
|
||||||
|
// /// Read index
|
||||||
|
// r: u64,
|
||||||
|
// /// Write index
|
||||||
|
// w: u64,
|
||||||
|
// /// Edit index
|
||||||
|
// e: u64,
|
||||||
|
// }
|
||||||
|
|
||||||
|
// static mut CONSOLE: Console = Console {
|
||||||
|
// lock: SpinLock {
|
||||||
|
// locked: 0,
|
||||||
|
// cpu: null_mut(),
|
||||||
|
// name: null(),
|
||||||
|
// },
|
||||||
|
// buf: [0; INPUT_BUF_SIZE],
|
||||||
|
// r: 0,
|
||||||
|
// w: 0,
|
||||||
|
// e: 0,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// /// send one character to the uart.
|
||||||
|
// /// called by printf(), and to echo input characters,
|
||||||
|
// /// but not from write().
|
||||||
|
// #[no_mangle]
|
||||||
|
// pub extern "C" fn consputc(c: i32) {
|
||||||
|
// if c == BACKSPACE {
|
||||||
|
// // if the user typed backspace, overwrite with a space.
|
||||||
|
// uartputc(8);
|
||||||
|
// uartputc(b' ');
|
||||||
|
// uartputc(8);
|
||||||
|
// } else {
|
||||||
|
// uartputc(c.try_into().unwrap_or(b'?'));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// user write()s to the console go here.
|
||||||
|
// #[no_mangle]
|
||||||
|
// pub extern "C" fn consolewrite(user_src: i32, src: u64, n: i32) -> i32 {
|
||||||
|
// for i in 0..n {
|
||||||
|
// let mut c: u8 = 0;
|
||||||
|
// unsafe {
|
||||||
|
// if either_copyin(addr_of_mut!(c) as *mut (), user_src, src, 1) == -1 {
|
||||||
|
// return i;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// uartputc(c);
|
||||||
|
// }
|
||||||
|
// 0
|
||||||
|
// }
|
||||||
|
|
||||||
|
// /// user read()s from the console go here.
|
||||||
|
// /// copy (up to) a whole input line to dst.
|
||||||
|
// /// user_dist indicates whether dst is a user
|
||||||
|
// /// or kernel address.
|
||||||
|
// #[no_mangle]
|
||||||
|
// pub unsafe extern "C" fn consoleread(user_dst: i32, dst: u64, n: i32) -> i32 {
|
||||||
|
// let mut c: i32;
|
||||||
|
// let mut cbuf: u8;
|
||||||
|
|
||||||
|
// let target = n;
|
||||||
|
// acquire(addr_of_mut!(CONSOLE.lock));
|
||||||
|
|
||||||
|
// let mut dst = dst;
|
||||||
|
// let mut n = n;
|
||||||
|
|
||||||
|
// while n > 0 {
|
||||||
|
// // wait until interrupt handler has put some
|
||||||
|
// // input into cons.buffer.
|
||||||
|
// while CONSOLE.r == CONSOLE.w {
|
||||||
|
// if killed(myproc()) {
|
||||||
|
// release(addr_of_mut!(CONSOLE.lock));
|
||||||
|
// return -1;
|
||||||
|
// }
|
||||||
|
// // sleep(&cons.r, &cons.lock);
|
||||||
|
// sleep(addr_of!(CONSOLE.r), addr_of_mut!(CONSOLE.lock));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// c = CONSOLE.buf[CONSOLE.r as usize % INPUT_BUF_SIZE] as i32;
|
||||||
|
// CONSOLE.r += 1;
|
||||||
|
|
||||||
|
// if c == CODE_END_OF_FILE {
|
||||||
|
// // end-of-file
|
||||||
|
// if n < target {
|
||||||
|
// // Save ^D for next time, to make sure
|
||||||
|
// // caller gets a 0-byte result.
|
||||||
|
// CONSOLE.r -= 1;
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // copy the input byte to the user-space buffer.
|
||||||
|
// cbuf = c as u8;
|
||||||
|
// if either_copyout(user_dst, dst, addr_of_mut!(cbuf) as *mut (), 1) == -1 {
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// dst += 1;
|
||||||
|
// n -= 1;
|
||||||
|
|
||||||
|
// if c == b'\n' as i32 {
|
||||||
|
// // a whole line has arrived, return to
|
||||||
|
// // the user-level read().
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// release(addr_of_mut!(CONSOLE.lock));
|
||||||
|
|
||||||
|
// target - n
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub unsafe fn consoleintr(c: i32) {
|
||||||
|
// acquire(addr_of_mut!(CONSOLE.lock));
|
||||||
|
|
||||||
|
// match c {
|
||||||
|
// CODE_PRINT_PROCESSES => {
|
||||||
|
// procdump();
|
||||||
|
// }
|
||||||
|
// CODE_KILL_LINE => {
|
||||||
|
// while CONSOLE.e != CONSOLE.w
|
||||||
|
// && CONSOLE.buf[(CONSOLE.e as usize - 1) % INPUT_BUF_SIZE] != b'\n'
|
||||||
|
// {
|
||||||
|
// CONSOLE.e -= 1;
|
||||||
|
// consputc(BACKSPACE)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// CODE_BACKSPACE | 0x7f => {
|
||||||
|
// if CONSOLE.e != CONSOLE.w {
|
||||||
|
// CONSOLE.e -= 1;
|
||||||
|
// consputc(BACKSPACE)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// c => {
|
||||||
|
// if c != 0 && ((CONSOLE.e - CONSOLE.r) as usize) < INPUT_BUF_SIZE {
|
||||||
|
// let c = if c == b'\r' as i32 { b'\n' as i32 } else { c };
|
||||||
|
// consputc(c);
|
||||||
|
// CONSOLE.buf[CONSOLE.e as usize % INPUT_BUF_SIZE] = c.try_into().unwrap();
|
||||||
|
// CONSOLE.e += 1;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// release(addr_of_mut!(CONSOLE.lock));
|
||||||
|
// }
|
||||||
|
|
||||||
|
// pub unsafe fn consoleinit() {
|
||||||
|
// initlock(addr_of_mut!(CONSOLE.lock), c"cons".as_ptr());
|
||||||
|
// uartinit();
|
||||||
|
// connect_console_syscalls();
|
||||||
|
// }
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
use crate::riscv;
|
use crate::{
|
||||||
|
// console::consoleinit,
|
||||||
|
riscv,
|
||||||
|
};
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn cpuid() -> u64;
|
fn cpuid() -> u64;
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
use core::ffi::CStr;
|
use core::ffi::CStr;
|
||||||
|
|
||||||
|
pub mod console;
|
||||||
pub mod kmain;
|
pub mod kmain;
|
||||||
pub mod memlayout;
|
pub mod memlayout;
|
||||||
pub mod param;
|
pub mod param;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Saved registers for kernel context switches.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct Context {
|
||||||
|
pub ra: u64,
|
||||||
|
pub sp: u64,
|
||||||
|
|
||||||
|
// Callee-saved
|
||||||
|
pub s0: u64,
|
||||||
|
pub s1: u64,
|
||||||
|
pub s2: u64,
|
||||||
|
pub s3: u64,
|
||||||
|
pub s4: u64,
|
||||||
|
pub s5: u64,
|
||||||
|
pub s6: u64,
|
||||||
|
pub s7: u64,
|
||||||
|
pub s8: u64,
|
||||||
|
pub s9: u64,
|
||||||
|
pub s10: u64,
|
||||||
|
pub s11: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Per-CPU state.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct CpuState {
|
||||||
|
pub proc: *mut (), // The process running on this cpu, or null.
|
||||||
|
pub context: Context, // swtch() here to enter scheduler().
|
||||||
|
pub noff: i32, // Depth of push_off() nesting.
|
||||||
|
pub intena: i32, // Were interrupts enabled before push_off()?
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
|
// console::consoleintr,
|
||||||
memlayout::UART0,
|
memlayout::UART0,
|
||||||
spinlock::{initlock, SpinLock},
|
spinlock::{initlock, SpinLock},
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue