Compare commits
3 Commits
75219763da
...
d2fb4a68ca
Author | SHA1 | Date | |
---|---|---|---|
d2fb4a68ca | |||
523130a69e | |||
6a41c4fc4e |
37
moon/Cargo.lock
generated
37
moon/Cargo.lock
generated
@ -8,6 +8,18 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bit_field"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@ -23,8 +35,15 @@ name = "moon"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"spin",
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97477e48b4cf8603ad5f7aaf897467cf42ab4218a38ef76fb14c2d6773a6d6a8"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.1.0"
|
||||
@ -39,3 +58,21 @@ checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "volatile"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3ca98349dda8a60ae74e04fd90c7fb4d6a4fbe01e6d3be095478aa0b76f6c0c"
|
||||
|
||||
[[package]]
|
||||
name = "x86_64"
|
||||
version = "0.14.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "100555a863c0092238c2e0e814c1096c1e5cf066a309c696a87e907b5f8c5d69"
|
||||
dependencies = [
|
||||
"bit_field",
|
||||
"bitflags",
|
||||
"rustversion",
|
||||
"volatile",
|
||||
]
|
||||
|
@ -16,4 +16,5 @@ strip = "debuginfo"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
spin = "0.9.4"
|
||||
spin = "0.9.4"
|
||||
x86_64 = "0.14.10"
|
2
moon/src/arch/interrupts.rs
Normal file
2
moon/src/arch/interrupts.rs
Normal file
@ -0,0 +1,2 @@
|
||||
#![cfg(target_arch = "x86_64")]
|
||||
pub use super::x86_64::interrupts::*;
|
@ -1,5 +1,6 @@
|
||||
pub mod cpu;
|
||||
pub mod io;
|
||||
pub mod interrupts;
|
||||
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
mod x86_64;
|
34
moon/src/arch/x86_64/interrupts.rs
Normal file
34
moon/src/arch/x86_64/interrupts.rs
Normal file
@ -0,0 +1,34 @@
|
||||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame, PageFaultErrorCode};
|
||||
use crate::try_println;
|
||||
use core::arch::asm;
|
||||
|
||||
static mut IDT: InterruptDescriptorTable = InterruptDescriptorTable::new();
|
||||
|
||||
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame)
|
||||
{
|
||||
try_println!("Breakpoint!\n{:#?}", stack_frame);
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn page_fault_handler(stack_frame: InterruptStackFrame, faulting_address: PageFaultErrorCode)
|
||||
{
|
||||
try_println!("Page fault at {:#?}\n{:#?}", faulting_address, stack_frame);
|
||||
}
|
||||
|
||||
pub fn load()
|
||||
{
|
||||
unsafe {
|
||||
IDT.breakpoint.set_handler_fn(breakpoint_handler);
|
||||
IDT.page_fault.set_handler_fn(page_fault_handler);
|
||||
IDT.load();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn enable()
|
||||
{
|
||||
unsafe { asm!("sti"); }
|
||||
}
|
||||
|
||||
pub fn disable()
|
||||
{
|
||||
unsafe { asm!("cli"); }
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
#![cfg(target_arch = "x86_64")]
|
||||
pub mod cpu;
|
||||
pub mod io;
|
||||
pub mod io;
|
||||
pub mod interrupts;
|
@ -4,13 +4,13 @@ use crate::util::get_bootboot;
|
||||
use crate::arch::cpu;
|
||||
|
||||
pub fn halt_other_cores() -> () {
|
||||
let boot: BOOTBOOT = get_bootboot();
|
||||
let boot: &BOOTBOOT = get_bootboot();
|
||||
if cpu::get_processor_id() != boot.bspid as u32 {
|
||||
cpu::halt();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn check_magic() -> () {
|
||||
let boot: BOOTBOOT = get_bootboot();
|
||||
let boot: &BOOTBOOT = get_bootboot();
|
||||
assert_eq!(boot.magic, BOOTBOOT_MAGIC[..4]);
|
||||
}
|
@ -1,19 +1,48 @@
|
||||
use crate::arch::io::SERIAL;
|
||||
use core::fmt;
|
||||
|
||||
/// Locks the serial port and writes formatted output.
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => ($crate::log::_print(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Tries to lock the serial port and writes formatted output.
|
||||
/// Should be used in interrupt handlers, as it does not block but silently fails.
|
||||
/// (If we are blocked waiting for interrupted code to unlock a lock, that's an instant deadlock unless we are on SMP and another CPU schedules that code)
|
||||
#[macro_export]
|
||||
macro_rules! try_print {
|
||||
($($arg:tt)*) => ($crate::log::_try_print(format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Locks the serial port and writes formatted output with a trailing newline.
|
||||
#[macro_export]
|
||||
macro_rules! println {
|
||||
() => ($crate::print!("\n"));
|
||||
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Tries to lock the serial port and writes formatted output with a trailing newline.
|
||||
/// Should be used in interrupt handlers, as it does not block but silently fails.
|
||||
/// (If we are blocked waiting for interrupted code to unlock a lock, that's an instant deadlock unless we are on SMP and another CPU schedules that code)
|
||||
#[macro_export]
|
||||
macro_rules! try_println {
|
||||
() => ($crate::try_print!("\n"));
|
||||
($($arg:tt)*) => ($crate::try_print!("{}\n", format_args!($($arg)*)));
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
SERIAL.lock().write_fmt(args).unwrap();
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn _try_print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
let serial = SERIAL.try_lock();
|
||||
if serial.is_some()
|
||||
{
|
||||
serial.unwrap().write_fmt(args).unwrap();
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
#![no_main]
|
||||
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(abi_x86_interrupt)]
|
||||
|
||||
mod video;
|
||||
mod bootboot;
|
||||
@ -12,18 +13,31 @@ mod arch;
|
||||
mod log;
|
||||
|
||||
use arch::cpu;
|
||||
use arch::interrupts;
|
||||
|
||||
use x86_64::instructions::interrupts::int3;
|
||||
|
||||
use video::Color;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn _start() -> ! {
|
||||
|
||||
interrupts::disable();
|
||||
|
||||
init::halt_other_cores();
|
||||
init::check_magic();
|
||||
|
||||
interrupts::load();
|
||||
|
||||
video::clear(Color::White);
|
||||
|
||||
println!("Hello, world!");
|
||||
|
||||
interrupts::enable();
|
||||
|
||||
int3();
|
||||
|
||||
println!("Still here!");
|
||||
|
||||
cpu::halt();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::bootboot::{BOOTBOOT, BOOTBOOT_INFO};
|
||||
|
||||
pub fn get_bootboot() -> BOOTBOOT {
|
||||
return unsafe { *(BOOTBOOT_INFO as *const BOOTBOOT) }
|
||||
pub fn get_bootboot() -> &'static BOOTBOOT {
|
||||
return unsafe { & *(BOOTBOOT_INFO as *const BOOTBOOT) }
|
||||
}
|
@ -39,7 +39,7 @@ impl Color {
|
||||
bswap(self as u32)
|
||||
}
|
||||
|
||||
fn to_layout(self, layout: u32) -> u32 {
|
||||
fn to_data_layout(self, layout: u32) -> u32 {
|
||||
match layout {
|
||||
FB_ARGB => self.to_argb(),
|
||||
FB_BGRA => self.to_bgra(),
|
||||
@ -49,24 +49,25 @@ impl Color {
|
||||
}
|
||||
|
||||
pub fn put_pixel(x: u32, y: u32, color: Color) -> () {
|
||||
let boot: BOOTBOOT = get_bootboot();
|
||||
let boot: &BOOTBOOT = get_bootboot();
|
||||
let ptr: u64 = FB + (boot.fb_scanline * y) as u64 + (x * 4) as u64;
|
||||
unsafe { *(ptr as *mut u32) = color.to_layout(boot.fb_type as u32) };
|
||||
unsafe { *(ptr as *mut u32) = color.to_data_layout(boot.fb_type as u32) };
|
||||
}
|
||||
|
||||
pub fn draw_rect(x: u32, y: u32, width: u32, height: u32, color: Color) -> () {
|
||||
let boot: BOOTBOOT = get_bootboot();
|
||||
let boot: &BOOTBOOT = get_bootboot();
|
||||
let col: u32 = color.to_data_layout(boot.fb_type as u32);
|
||||
for i in y..(y + height)
|
||||
{
|
||||
let addr: u64 = FB + (boot.fb_scanline * i) as u64 + (x * 4) as u64;
|
||||
for ptr in (addr..(addr + (width*4) as u64)).step_by(4)
|
||||
{
|
||||
unsafe { *(ptr as *mut u32) = color.to_layout(boot.fb_type as u32) };
|
||||
unsafe { *(ptr as *mut u32) = col };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(color: Color) -> () {
|
||||
let boot: BOOTBOOT = get_bootboot();
|
||||
let boot: &BOOTBOOT = get_bootboot();
|
||||
draw_rect(0, 0, boot.fb_width, boot.fb_height, color)
|
||||
}
|
Loading…
Reference in New Issue
Block a user