forked from LowLevelDevs/FoundryOS
Bump edition to now stable 2024 edition (shiny!).
This commit is contained in:
+35
-29
@@ -3,7 +3,7 @@ use spin::{Lazy, Mutex};
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
pub use super::framebuffer::screensize_px;
|
||||
use super::framebuffer::{Color, FRAMEBUFFER_WRITER};
|
||||
use super::framebuffer::{Colour, FRAMEBUFFER_WRITER};
|
||||
|
||||
mod font;
|
||||
use font::FONT;
|
||||
@@ -28,32 +28,39 @@ pub struct Writer {
|
||||
/// 8 pixels wide.
|
||||
text_col: u32,
|
||||
|
||||
fg_color: Color,
|
||||
bg_color: Color,
|
||||
fg_color: Colour,
|
||||
bg_color: Colour,
|
||||
|
||||
offset1: usize,
|
||||
offset2: usize,
|
||||
}
|
||||
|
||||
impl Default for Writer {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Writer {
|
||||
pub fn new() -> Self {
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
Self {
|
||||
screen_width: writer.width() as u32 / 8,
|
||||
screen_height: writer.height() as u32 / 16,
|
||||
FRAMEBUFFER_WRITER.lock().as_mut().map_or_else(
|
||||
|| {
|
||||
panic!("Framebuffer writer not initialized.");
|
||||
},
|
||||
|writer| Self {
|
||||
screen_width: writer.width() / 8,
|
||||
screen_height: writer.height() / 16,
|
||||
text_line: 0,
|
||||
text_col: 0,
|
||||
fg_color: Color::White,
|
||||
bg_color: Color::Black,
|
||||
fg_color: Colour::White,
|
||||
bg_color: Colour::Black,
|
||||
offset1: 16,
|
||||
offset2: 0,
|
||||
}
|
||||
} else {
|
||||
panic!("Framebuffer writer not initialized");
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn write_char(&mut self, c: u16) {
|
||||
pub fn write_glyph(&mut self, c: u16) {
|
||||
if c as u8 == b'\n' {
|
||||
self.newline();
|
||||
return;
|
||||
@@ -63,8 +70,7 @@ impl Writer {
|
||||
let data: &[u8] = &FONT[c as usize * 16..(c as usize + 1) * 16];
|
||||
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
for row in 0..16 {
|
||||
let line: u8 = data[row];
|
||||
for (row, line) in data.iter().enumerate().take(16) {
|
||||
for col in 0..8 {
|
||||
let pixel_x: u32 = self.text_col * FONT_WIDTH + col;
|
||||
let pixel_y: u32 = self.text_line * FONT_HEIGHT + row as u32;
|
||||
@@ -88,20 +94,20 @@ impl Writer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_offset(&mut self, offset1: usize, offset2: usize) {
|
||||
pub const fn set_offset(&mut self, offset1: usize, offset2: usize) {
|
||||
self.offset1 = offset1;
|
||||
self.offset2 = offset2;
|
||||
}
|
||||
|
||||
pub fn dimensions(&self) -> (u32, u32) {
|
||||
pub const fn dimensions(&self) -> (u32, u32) {
|
||||
(self.screen_width, self.screen_height)
|
||||
}
|
||||
|
||||
pub fn next_char(&mut self) {
|
||||
pub const fn next_char(&mut self) {
|
||||
self.text_col += 1;
|
||||
}
|
||||
|
||||
pub fn newline(&mut self) {
|
||||
pub const fn newline(&mut self) {
|
||||
self.text_col = 0;
|
||||
|
||||
if self.text_line + 1 >= self.screen_height {
|
||||
@@ -113,18 +119,18 @@ impl Writer {
|
||||
|
||||
pub fn write_string(&mut self, s: &str) {
|
||||
for c in s.chars() {
|
||||
self.write_char(c as u16);
|
||||
self.write_glyph(c as u16);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_colour(&mut self, fg: Color, bg: Color) {
|
||||
pub const fn set_colour(&mut self, fg: Colour, bg: Colour) {
|
||||
self.fg_color = fg;
|
||||
self.bg_color = bg;
|
||||
}
|
||||
|
||||
pub fn reset_colour(&mut self) {
|
||||
self.fg_color = Color::White;
|
||||
self.bg_color = Color::Black;
|
||||
pub const fn reset_colour(&mut self) {
|
||||
self.fg_color = Colour::White;
|
||||
self.bg_color = Colour::Black;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +141,7 @@ impl core::fmt::Write for Writer {
|
||||
}
|
||||
}
|
||||
|
||||
fn write(args: fmt::Arguments, fg: Color, bg: Color) {
|
||||
fn write(args: fmt::Arguments, fg: Colour, bg: Colour) {
|
||||
use core::fmt::Write;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
@@ -148,19 +154,19 @@ fn write(args: fmt::Arguments, fg: Color, bg: Color) {
|
||||
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::White, Color::Black);
|
||||
write(args, Colour::White, Colour::Black);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn _print_err(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::Red, Color::Black);
|
||||
write(args, Colour::Red, Colour::Black);
|
||||
})
|
||||
}
|
||||
|
||||
pub fn _print_log(args: fmt::Arguments) {
|
||||
x86_64::instructions::interrupts::without_interrupts(|| {
|
||||
write(args, Color::Yellow, Color::Black);
|
||||
write(args, Colour::Yellow, Colour::Black);
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+54
-38
@@ -1,52 +1,69 @@
|
||||
use limine::request::FramebufferRequest;
|
||||
|
||||
#[used]
|
||||
#[link_section = ".requests"]
|
||||
#[unsafe(link_section = ".requests")]
|
||||
static FRAMEBUFFER_REQUEST: FramebufferRequest = FramebufferRequest::new();
|
||||
|
||||
mod colour;
|
||||
|
||||
pub use colour::Color;
|
||||
pub use colour::Colour;
|
||||
use core::panic;
|
||||
|
||||
use limine::framebuffer::Framebuffer;
|
||||
use spin::{Lazy, Mutex};
|
||||
|
||||
// use crate::{colour::Color, FRAMEBUFFER_REQUEST};
|
||||
|
||||
pub static FRAMEBUFFER_WRITER: Lazy<Mutex<Option<FramebufferWriter>>> = Lazy::new(|| {
|
||||
Mutex::new(
|
||||
if let Some(framebuffer_response) = FRAMEBUFFER_REQUEST.get_response() {
|
||||
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||
Some(FramebufferWriter::new(framebuffer))
|
||||
} else {
|
||||
Mutex::new(FRAMEBUFFER_REQUEST.get_response().map_or_else(
|
||||
|| {
|
||||
panic!("Framebuffer request failed");
|
||||
},
|
||||
)
|
||||
|framebuffer_response| {
|
||||
let framebuffer = framebuffer_response.framebuffers().next().unwrap();
|
||||
Some(FramebufferWriter::new(framebuffer))
|
||||
},
|
||||
))
|
||||
});
|
||||
|
||||
pub struct FramebufferWriter<'a> {
|
||||
framebuffer: Framebuffer<'a>,
|
||||
/// The updated writer stores necessary fields from the [Framebuffer].
|
||||
/// This ensures that the contained types are Send, as Framebuffer was
|
||||
/// not marked as Send.
|
||||
///
|
||||
/// It also avoids the requirement for lifetimes.
|
||||
///
|
||||
/// Note this does not implement Writer as these functions only handle drawing pixels.
|
||||
pub struct FramebufferWriter {
|
||||
pitch: u64,
|
||||
bpp: u16,
|
||||
addr: *mut u8,
|
||||
width: u64,
|
||||
height: u64,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for FramebufferWriter<'a> {}
|
||||
unsafe impl<'a> Sync for FramebufferWriter<'a> {}
|
||||
impl<'a> FramebufferWriter<'a> {
|
||||
pub fn new(framebuffer: Framebuffer<'a>) -> Self {
|
||||
Self { framebuffer }
|
||||
}
|
||||
unsafe impl Send for FramebufferWriter {}
|
||||
unsafe impl Sync for FramebufferWriter {}
|
||||
|
||||
pub fn write_pixel(&self, x: usize, y: usize, color: Color) {
|
||||
let pitch = self.framebuffer.pitch() as usize;
|
||||
let bpp = (self.framebuffer.bpp() / 8) as usize;
|
||||
let pixel_offset = y * pitch + x * bpp;
|
||||
|
||||
unsafe {
|
||||
*(self.framebuffer.addr().add(pixel_offset) as *mut u32) = color.into();
|
||||
impl FramebufferWriter {
|
||||
pub fn new(framebuffer: Framebuffer) -> Self {
|
||||
Self {
|
||||
pitch: framebuffer.pitch(),
|
||||
bpp: framebuffer.bpp(),
|
||||
addr: framebuffer.addr(),
|
||||
width: framebuffer.width(),
|
||||
height: framebuffer.height(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_frame(&self, buffer: &[Color; 1280 * 800]) {
|
||||
pub fn write_pixel(&self, x: usize, y: usize, color: Colour) {
|
||||
let pitch = self.pitch as usize;
|
||||
let bpp = (self.bpp / 8) as usize;
|
||||
let pixel_offset = y * pitch + x * bpp;
|
||||
|
||||
unsafe {
|
||||
*(self.addr.add(pixel_offset) as *mut u32) = color.into();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_frame(&self, buffer: &[Colour; 1280 * 800]) {
|
||||
for (y, row) in buffer.chunks(1280).enumerate() {
|
||||
for (x, pixel) in row.iter().enumerate() {
|
||||
self.write_pixel(x, y, *pixel);
|
||||
@@ -54,30 +71,29 @@ impl<'a> FramebufferWriter<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn width(&self) -> u32 {
|
||||
self.framebuffer.width() as u32
|
||||
pub const fn width(&self) -> u32 {
|
||||
self.width as u32
|
||||
}
|
||||
|
||||
pub fn height(&self) -> u32 {
|
||||
self.framebuffer.height() as u32
|
||||
pub const fn height(&self) -> u32 {
|
||||
self.height as u32
|
||||
}
|
||||
|
||||
pub fn clear(&self) {
|
||||
let width = self.framebuffer.width() as usize;
|
||||
let height = self.framebuffer.height() as usize;
|
||||
let width = self.width as usize;
|
||||
let height = self.height as usize;
|
||||
|
||||
for y in 0..height {
|
||||
for x in 0..width {
|
||||
self.write_pixel(x, y, Color::Black);
|
||||
self.write_pixel(x, y, Colour::Black);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn screensize_px() -> (u32, u32) {
|
||||
if let Some(writer) = FRAMEBUFFER_WRITER.lock().as_mut() {
|
||||
(writer.width(), writer.height())
|
||||
} else {
|
||||
(0, 0)
|
||||
}
|
||||
FRAMEBUFFER_WRITER
|
||||
.lock()
|
||||
.as_mut()
|
||||
.map_or_else(|| (0, 0), |writer| (writer.width(), writer.height()))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#[repr(u32)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
|
||||
pub enum Color {
|
||||
pub enum Colour {
|
||||
ARGB(u8, u8, u8, u8),
|
||||
RGB(u8, u8, u8),
|
||||
HexARGB(u32),
|
||||
@@ -14,40 +14,40 @@ pub enum Color {
|
||||
White = 0xFFFFFFFF,
|
||||
}
|
||||
|
||||
impl Into<u32> for Color {
|
||||
fn into(self) -> u32 {
|
||||
match self {
|
||||
Color::ARGB(a, r, g, b) => {
|
||||
impl From<Colour> for u32 {
|
||||
fn from(val: Colour) -> Self {
|
||||
match val {
|
||||
Colour::ARGB(a, r, g, b) => {
|
||||
(a as u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32)
|
||||
}
|
||||
Color::RGB(r, g, b) => (0u32) << 24 | (r as u32) << 16 | (g as u32) << 8 | (b as u32),
|
||||
Color::HexARGB(hex) => hex,
|
||||
Color::Black => 0xFF000000,
|
||||
Color::Blue => 0xFF0000FF,
|
||||
Color::Green => 0xFF00FF00,
|
||||
Color::Cyan => 0xFF00FFFF,
|
||||
Color::Red => 0xFFFF0000,
|
||||
Color::Magenta => 0xFFFF00FF,
|
||||
Color::Yellow => 0xFFFFFF00,
|
||||
Color::White => 0xFFFFFFFF,
|
||||
Colour::RGB(r, g, b) => ((r as u32) << 16) | (g as u32) << 8 | (b as u32),
|
||||
Colour::HexARGB(hex) => hex,
|
||||
Colour::Black => 0xFF000000,
|
||||
Colour::Blue => 0xFF0000FF,
|
||||
Colour::Green => 0xFF00FF00,
|
||||
Colour::Cyan => 0xFF00FFFF,
|
||||
Colour::Red => 0xFFFF0000,
|
||||
Colour::Magenta => 0xFFFF00FF,
|
||||
Colour::Yellow => 0xFFFFFF00,
|
||||
Colour::White => 0xFFFFFFFF,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Color {
|
||||
impl core::fmt::Display for Colour {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
match self {
|
||||
Color::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
|
||||
Color::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
|
||||
Color::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
|
||||
Color::Black => write!(f, "Black"),
|
||||
Color::Blue => write!(f, "Blue"),
|
||||
Color::Green => write!(f, "Green"),
|
||||
Color::Cyan => write!(f, "Cyan"),
|
||||
Color::Red => write!(f, "Red"),
|
||||
Color::Magenta => write!(f, "Magenta"),
|
||||
Color::Yellow => write!(f, "Yellow"),
|
||||
Color::White => write!(f, "White"),
|
||||
Colour::ARGB(r, g, b, a) => write!(f, "RGBA(#{:x}{:x}{:x}{:x})", r, g, b, a),
|
||||
Colour::RGB(r, g, b) => write!(f, "RGB(#{:x}{:x}{:x})", r, g, b),
|
||||
Colour::HexARGB(hex) => write!(f, "Hex(#{:x})", hex),
|
||||
Colour::Black => write!(f, "Black"),
|
||||
Colour::Blue => write!(f, "Blue"),
|
||||
Colour::Green => write!(f, "Green"),
|
||||
Colour::Cyan => write!(f, "Cyan"),
|
||||
Colour::Red => write!(f, "Red"),
|
||||
Colour::Magenta => write!(f, "Magenta"),
|
||||
Colour::Yellow => write!(f, "Yellow"),
|
||||
Colour::White => write!(f, "White"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+24
-17
@@ -5,9 +5,9 @@ use core::{
|
||||
task::{Context, Poll},
|
||||
};
|
||||
|
||||
use super::{print, println};
|
||||
use crate::prelude::*;
|
||||
use crossbeam::queue::ArrayQueue;
|
||||
use futures_util::{task::AtomicWaker, Stream};
|
||||
use futures_util::{Stream, task::AtomicWaker};
|
||||
use spin::Once;
|
||||
|
||||
static KBD_QUEUE: Once<ArrayQueue<u8>> = Once::new();
|
||||
@@ -15,7 +15,7 @@ static WAKER: AtomicWaker = AtomicWaker::new();
|
||||
|
||||
pub fn add_scancode(scancode: u8) {
|
||||
if let Some(queue) = KBD_QUEUE.get() {
|
||||
if let Err(_) = queue.push(scancode) {
|
||||
if queue.push(scancode).is_err() {
|
||||
println!("WARNING: scancode queue full; dropping keyboard input");
|
||||
} else {
|
||||
println!("waking waker");
|
||||
@@ -33,7 +33,14 @@ pub struct ScanCodeStream {
|
||||
impl ScanCodeStream {
|
||||
pub fn new() -> Self {
|
||||
KBD_QUEUE.call_once(|| ArrayQueue::new(5));
|
||||
ScanCodeStream { _private: () }
|
||||
|
||||
Self { _private: () }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ScanCodeStream {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,30 +49,30 @@ impl Stream for ScanCodeStream {
|
||||
|
||||
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
|
||||
let queue = KBD_QUEUE.get().expect("scancode queue not initialized");
|
||||
print!("polling or smth");
|
||||
serial_println!("This is called once.");
|
||||
WAKER.register(cx.waker());
|
||||
|
||||
// fast path
|
||||
if let Some(scancode) = queue.pop() {
|
||||
return Poll::Ready(Some(scancode));
|
||||
}
|
||||
|
||||
WAKER.register(&cx.waker());
|
||||
match queue.pop() {
|
||||
Some(scancode) => {
|
||||
print!("scancode found");
|
||||
queue.pop().map_or_else(
|
||||
|| {
|
||||
print!("Returning");
|
||||
Poll::Pending
|
||||
},
|
||||
|scancode| {
|
||||
print!("Scancode found");
|
||||
WAKER.take();
|
||||
Poll::Ready(Some(scancode))
|
||||
}
|
||||
None => {
|
||||
print!("returning");
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
use futures_util::stream::StreamExt;
|
||||
use pc_keyboard::{layouts, DecodedKey, HandleControl, Keyboard, ScancodeSet1};
|
||||
use pc_keyboard::{DecodedKey, HandleControl, Keyboard, ScancodeSet1, layouts};
|
||||
|
||||
pub async fn print_keypresses() {
|
||||
let mut scancodes = ScanCodeStream::new();
|
||||
@@ -75,7 +82,7 @@ pub async fn print_keypresses() {
|
||||
HandleControl::Ignore,
|
||||
);
|
||||
|
||||
println!("OK!!!");
|
||||
serial_println!("Printing keypresses.");
|
||||
|
||||
while let Some(scancode) = scancodes.next().await {
|
||||
if let Ok(Some(key_event)) = keyboard.add_byte(scancode) {
|
||||
|
||||
+18
-14
@@ -3,23 +3,27 @@
|
||||
use core::arch::asm;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn inb(port: u16) -> u8 {
|
||||
pub fn inb(port: u16) -> u8 {
|
||||
let value: u8;
|
||||
asm!(
|
||||
"in al, dx",
|
||||
out("al") value,
|
||||
in("dx") port,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
unsafe {
|
||||
asm!(
|
||||
"in al, dx",
|
||||
out("al") value,
|
||||
in("dx") port,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
value
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn outb(port: u16, value: u8) {
|
||||
asm!(
|
||||
"out dx, al",
|
||||
in("dx") port,
|
||||
in("al") value,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
pub fn outb(port: u16, value: u8) {
|
||||
unsafe {
|
||||
asm!(
|
||||
"out dx, al",
|
||||
in("dx") port,
|
||||
in("al") value,
|
||||
options(nomem, nostack, preserves_flags)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+18
-22
@@ -45,14 +45,14 @@ pub fn serial_read() -> &'static str {
|
||||
|
||||
let i = BUFFER_LEN.load(Ordering::SeqCst);
|
||||
|
||||
return unsafe {
|
||||
unsafe {
|
||||
if i != 0 {
|
||||
core::str::from_utf8(&BUFFER[..i - 1]).unwrap()
|
||||
} else {
|
||||
serial_println!("empty string");
|
||||
""
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static PORT: u16 = 0x3f8;
|
||||
@@ -83,15 +83,13 @@ impl Writer {
|
||||
pub fn write_byte(&self, data: u8) {
|
||||
unsafe {
|
||||
while !self.write_success() {}
|
||||
outb(PORT + 0, data);
|
||||
outb(PORT, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn init() -> Result<(), &'static str> {
|
||||
if let Err(e) = test() {
|
||||
return Err(e);
|
||||
}
|
||||
test()?;
|
||||
|
||||
if READER.lock().is_none() {
|
||||
*READER.lock() = Some(Reader);
|
||||
@@ -105,24 +103,22 @@ pub fn init() -> Result<(), &'static str> {
|
||||
}
|
||||
|
||||
pub fn test() -> Result<(), &'static str> {
|
||||
unsafe {
|
||||
outb(PORT + 1, 0x00); // Disable all interrupts
|
||||
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||
outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||
outb(PORT + 1, 0x00); // (hi byte)
|
||||
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold
|
||||
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||
outb(PORT + 1, 0x00); // Disable all interrupts
|
||||
outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
|
||||
outb(PORT, 0x03); // Set divisor to 3 (lo byte) 38400 baud
|
||||
outb(PORT + 1, 0x00); // (hi byte)
|
||||
outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
|
||||
outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-bytethreshold
|
||||
outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
|
||||
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
|
||||
outb(PORT, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
|
||||
|
||||
if inb(PORT + 0) != 0xAE {
|
||||
return Err("serial test failed");
|
||||
}
|
||||
|
||||
outb(PORT + 4, 0x0F);
|
||||
if inb(PORT) != 0xAE {
|
||||
return Err("serial test failed");
|
||||
}
|
||||
|
||||
outb(PORT + 4, 0x0F);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -153,7 +149,7 @@ impl Reader {
|
||||
pub fn read(&self) -> u8 {
|
||||
unsafe {
|
||||
while !self.read_ready() {}
|
||||
return inb(PORT + 0);
|
||||
inb(PORT)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,5 +1,6 @@
|
||||
#![no_std]
|
||||
|
||||
#![warn(tail_expr_drop_order)]
|
||||
#![warn(clippy::correctness, clippy::perf, clippy::nursery)]
|
||||
// alloc
|
||||
// io : serial, framebuffer, ascii(?), keyboard
|
||||
// ?????
|
||||
@@ -11,5 +12,5 @@ pub mod scheduling;
|
||||
|
||||
/// Re-exports most of the IO macros.
|
||||
pub mod prelude {
|
||||
pub use crate::{print_log, println, println_log, serial_print, serial_println};
|
||||
pub use crate::{print, print_log, println, println_log, serial_print, serial_println};
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@ pub struct Task {
|
||||
}
|
||||
|
||||
impl Task {
|
||||
pub fn new(future: impl Future<Output = ()> + 'static) -> Task {
|
||||
Task {
|
||||
pub fn new(future: impl Future<Output = ()> + 'static) -> Self {
|
||||
Self {
|
||||
id: TaskId::new(),
|
||||
future: Box::pin(future),
|
||||
}
|
||||
@@ -32,9 +32,15 @@ pub struct Executor {
|
||||
waker_cache: BTreeMap<TaskId, Waker>,
|
||||
}
|
||||
|
||||
impl Default for Executor {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl Executor {
|
||||
pub fn new() -> Self {
|
||||
Executor {
|
||||
Self {
|
||||
tasks: BTreeMap::new(),
|
||||
task_queue: Arc::new(ArrayQueue::new(100)),
|
||||
waker_cache: BTreeMap::new(),
|
||||
@@ -63,7 +69,7 @@ impl Executor {
|
||||
};
|
||||
let waker = waker_cache
|
||||
.entry(task_id)
|
||||
.or_insert_with(|| TaskWaker::new(task_id, task_queue.clone()));
|
||||
.or_insert_with(|| TaskWaker::waker(task_id, task_queue.clone()));
|
||||
let mut context = Context::from_waker(waker);
|
||||
match task.poll(&mut context) {
|
||||
Poll::Ready(()) => {
|
||||
@@ -98,8 +104,8 @@ struct TaskWaker {
|
||||
}
|
||||
|
||||
impl TaskWaker {
|
||||
fn new(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
|
||||
Waker::from(Arc::new(TaskWaker {
|
||||
fn waker(task_id: TaskId, task_queue: Arc<ArrayQueue<TaskId>>) -> Waker {
|
||||
Waker::from(Arc::new(Self {
|
||||
task_id,
|
||||
task_queue,
|
||||
}))
|
||||
@@ -128,6 +134,6 @@ struct TaskId(u64);
|
||||
impl TaskId {
|
||||
fn new() -> Self {
|
||||
static NEXT: AtomicU64 = AtomicU64::new(0);
|
||||
TaskId(NEXT.fetch_add(1, Ordering::Relaxed))
|
||||
Self(NEXT.fetch_add(1, Ordering::Relaxed))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user