fs: simple kernel log buffer
This commit is contained in:
parent
dbbddaa4f5
commit
0dc2cfa159
55
src/debug.rs
55
src/debug.rs
@ -2,14 +2,30 @@
|
||||
use core::fmt::{self, Arguments};
|
||||
|
||||
use abi::error::Error;
|
||||
use kernel_util::util::StaticVector;
|
||||
use alloc::sync::Arc;
|
||||
use futures_util::Future;
|
||||
use kernel_util::util::{OneTimeInit, StaticVector};
|
||||
|
||||
use crate::{sync::IrqSafeSpinlock, task::process::Process};
|
||||
use crate::{
|
||||
sync::IrqSafeSpinlock,
|
||||
task::{process::Process, runtime::QueueWaker},
|
||||
util::ring::RingBuffer,
|
||||
};
|
||||
|
||||
const MAX_DEBUG_SINKS: usize = 4;
|
||||
const RING_LOGGER_CAPACITY: usize = 65536;
|
||||
|
||||
struct SimpleLogger;
|
||||
|
||||
struct RingLoggerInner {
|
||||
data: RingBuffer<u8, RING_LOGGER_CAPACITY>,
|
||||
}
|
||||
|
||||
pub struct RingLoggerSink {
|
||||
inner: IrqSafeSpinlock<RingLoggerInner>,
|
||||
waker: QueueWaker,
|
||||
}
|
||||
|
||||
/// Defines the severity of the message
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub enum LogLevel {
|
||||
@ -151,11 +167,44 @@ impl fmt::Write for DebugSinkWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
impl RingLoggerSink {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
inner: IrqSafeSpinlock::new(RingLoggerInner {
|
||||
data: RingBuffer::new(0),
|
||||
}),
|
||||
waker: QueueWaker::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read(&self, pos: usize, buffer: &mut [u8]) -> usize {
|
||||
unsafe { self.inner.lock().data.read_all_static(pos, buffer) }
|
||||
}
|
||||
|
||||
fn write_fmt(&self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
use fmt::Write;
|
||||
self.inner.lock().write_fmt(args)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Write for RingLoggerInner {
|
||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||
for ch in s.bytes() {
|
||||
unsafe {
|
||||
self.data.write_unchecked(ch);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
static LOGGER: SimpleLogger = SimpleLogger;
|
||||
|
||||
static DEBUG_SINKS: IrqSafeSpinlock<StaticVector<DebugSinkWrapper, MAX_DEBUG_SINKS>> =
|
||||
IrqSafeSpinlock::new(StaticVector::new());
|
||||
|
||||
pub static RING_LOGGER_SINK: RingLoggerSink = RingLoggerSink::new();
|
||||
|
||||
/// Prints a hex-dump of a slice, appending a virtual address offset to the output
|
||||
pub fn hex_dump(level: LogLevel, addr_offset: usize, data: &[u8]) {
|
||||
for (i, b) in data.iter().enumerate() {
|
||||
@ -208,6 +257,8 @@ pub fn init() {
|
||||
pub fn debug_internal(args: Arguments, level: LogLevel) {
|
||||
use fmt::Write;
|
||||
|
||||
RING_LOGGER_SINK.write_fmt(args).ok();
|
||||
|
||||
for sink in DEBUG_SINKS.lock().iter_mut() {
|
||||
if level < sink.level {
|
||||
continue;
|
||||
|
@ -192,7 +192,7 @@ impl Device for Pl011 {
|
||||
|
||||
self.inner.init(IrqSafeSpinlock::new(inner));
|
||||
|
||||
debug::add_sink(self, LogLevel::Debug);
|
||||
// debug::add_sink(self, LogLevel::Debug);
|
||||
devfs::add_char_device(self, CharDeviceType::TtySerial)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -12,7 +12,7 @@ use git_version::git_version;
|
||||
use kernel_util::util::OneTimeInit;
|
||||
use vfs::{Vnode, VnodeImpl, VnodeKind, VnodeRef, DIR_POSITION_FROM_CACHE};
|
||||
|
||||
use crate::util;
|
||||
use crate::{debug, util};
|
||||
|
||||
trait GetterFn<T: ToString> = Fn() -> Result<T, Error>;
|
||||
trait ReaderFn = Fn(u64, &mut [u8]) -> Result<usize, Error>;
|
||||
@ -169,8 +169,7 @@ pub fn root() -> &'static VnodeRef {
|
||||
}
|
||||
|
||||
fn read_kernel_log(pos: u64, buffer: &mut [u8]) -> Result<usize, Error> {
|
||||
// TODO actual kernel log buffer
|
||||
todo!()
|
||||
Ok(debug::RING_LOGGER_SINK.read(pos as usize, buffer))
|
||||
}
|
||||
|
||||
pub fn init() {
|
||||
|
@ -9,24 +9,36 @@ use futures_util::Future;
|
||||
|
||||
use crate::{sync::IrqSafeSpinlock, task::runtime::QueueWaker};
|
||||
|
||||
struct Inner<T, const N: usize> {
|
||||
pub struct RingBuffer<T, const N: usize> {
|
||||
rd: usize,
|
||||
wr: usize,
|
||||
data: [T; N],
|
||||
}
|
||||
|
||||
pub struct AsyncRing<T, const N: usize> {
|
||||
inner: Arc<IrqSafeSpinlock<Inner<T, N>>>,
|
||||
inner: Arc<IrqSafeSpinlock<RingBuffer<T, N>>>,
|
||||
read_waker: Arc<QueueWaker>,
|
||||
}
|
||||
|
||||
impl<T: Copy, const N: usize> Inner<T, N> {
|
||||
impl<T: Copy, const N: usize> RingBuffer<T, N> {
|
||||
pub const fn new(value: T) -> Self {
|
||||
Self {
|
||||
rd: 0,
|
||||
wr: 0,
|
||||
data: [value; N],
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
const fn is_readable(&self) -> bool {
|
||||
if self.rd <= self.wr {
|
||||
(self.wr - self.rd) > 0
|
||||
self.is_readable_at(self.rd)
|
||||
}
|
||||
|
||||
const fn is_readable_at(&self, at: usize) -> bool {
|
||||
if at <= self.wr {
|
||||
(self.wr - at) > 0
|
||||
} else {
|
||||
(self.wr + (N - self.rd)) > 0
|
||||
(self.wr + (N - at)) > 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,8 +49,19 @@ impl<T: Copy, const N: usize> Inner<T, N> {
|
||||
res
|
||||
}
|
||||
|
||||
pub unsafe fn read_all_static(&mut self, pos: usize, buffer: &mut [T]) -> usize {
|
||||
let mut pos = (self.rd + pos) % N;
|
||||
let mut off = 0;
|
||||
while off < buffer.len() && self.is_readable_at(pos) {
|
||||
buffer[off] = self.data[pos];
|
||||
pos += 1;
|
||||
off += 1;
|
||||
}
|
||||
off
|
||||
}
|
||||
|
||||
#[inline]
|
||||
unsafe fn write_unchecked(&mut self, ch: T) {
|
||||
pub unsafe fn write_unchecked(&mut self, ch: T) {
|
||||
self.data[self.wr] = ch;
|
||||
self.wr = (self.wr + 1) % N;
|
||||
}
|
||||
@ -47,11 +70,7 @@ impl<T: Copy, const N: usize> Inner<T, N> {
|
||||
impl<T: Copy, const N: usize> AsyncRing<T, N> {
|
||||
pub fn new(value: T) -> Self {
|
||||
Self {
|
||||
inner: Arc::new(IrqSafeSpinlock::new(Inner {
|
||||
rd: 0,
|
||||
wr: 0,
|
||||
data: [value; N],
|
||||
})),
|
||||
inner: Arc::new(IrqSafeSpinlock::new(RingBuffer::new(value))),
|
||||
read_waker: Arc::new(QueueWaker::new()),
|
||||
}
|
||||
}
|
||||
@ -69,7 +88,7 @@ impl<T: Copy, const N: usize> AsyncRing<T, N> {
|
||||
|
||||
pub fn read(&self) -> impl Future<Output = T> {
|
||||
struct ReadFuture<T: Copy, const N: usize> {
|
||||
inner: Arc<IrqSafeSpinlock<Inner<T, N>>>,
|
||||
inner: Arc<IrqSafeSpinlock<RingBuffer<T, N>>>,
|
||||
read_waker: Arc<QueueWaker>,
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user