pci, ide stuff

This commit is contained in:
Jack Halford 2019-02-02 18:46:41 +01:00
parent c9ad4e9e58
commit 3d167f26d5
10 changed files with 115 additions and 73 deletions

View file

@ -9,7 +9,8 @@ qemu:
-enable-kvm\ -enable-kvm\
-curses\ -curses\
-gdb tcp::$(QEMU_GDB_PORT)\ -gdb tcp::$(QEMU_GDB_PORT)\
-monitor unix:${QEMU_SOCKET},server,nowait -monitor unix:${QEMU_SOCKET},server,nowait\
-drive file=disk,if=ide,index=1
qemu-gdb: qemu-gdb:
gdb\ gdb\

View file

@ -128,33 +128,27 @@ impl Iterator for ACPISDTIter {
/// Initalized the ACPI module /// Initalized the ACPI module
pub fn init() -> Result<(), &'static str> { pub fn init() -> Result<(), &'static str> {
if unsafe{ACPI.valid} { if unsafe{ACPI.valid} { return Ok(()); }
return Ok(());
}
unsafe { ACPI.init() } unsafe { ACPI.init() }
} }
/// Load the ACPI module, addr given is a ptr to RSDP /// Load the ACPI module, addr given is a ptr to RSDP
pub fn load(rsdp_addr: u32) -> Result<(), &'static str> { pub fn load(rsdp_addr: u32) -> Result<(), &'static str> {
if unsafe{ACPI.valid} { if unsafe{!ACPI.valid} { return Ok(()); }
return Ok(());
}
unsafe { ACPI.load(rsdp_addr) } unsafe { ACPI.load(rsdp_addr) }
} }
/// Proceed to ACPI shutdown /// Proceed to ACPI shutdown
/// This function doesn't work with Virtual Box yet /// This function doesn't work with Virtual Box yet
pub fn shutdown() { pub fn shutdown() {
if unsafe{ACPI.valid} { return } if unsafe{!ACPI.valid} { return; }
dsdt::shutdown(fadt::get_controlblock().unwrap()); dsdt::shutdown(fadt::get_controlblock().unwrap()).unwrap();
} }
/// Proceed to ACPI reboot /// Proceed to ACPI reboot
/// This function need ACPI in v2 /// This function need ACPI in v2
pub fn reboot() { pub fn reboot() {
if unsafe {!ACPI.valid} { if unsafe {!ACPI.valid} { println!("ACPI not initialized"); }
println!("ACPI not initialized");
}
if unsafe { ACPI.v2 } { if unsafe { ACPI.v2 } {
fadt::reboot().unwrap() fadt::reboot().unwrap()
} else { } else {
@ -166,8 +160,8 @@ pub fn reboot() {
pub fn info() { pub fn info() {
if unsafe { !ACPI.valid } { println!("ACPI not initialized"); return } if unsafe { !ACPI.valid } { println!("ACPI not initialized"); return }
match fadt::is_enable() { match fadt::is_enable() {
Ok(True) => println!("ACPI is disabled"), Ok(true) => println!("ACPI is disabled"),
Ok(False) => println!("ACPI is disabled"), Ok(false) => println!("ACPI is disabled"),
Err(msg) => println!("error while checking ACPI") Err(msg) => println!("error while checking ACPI: {}", msg)
} }
} }

View file

@ -1,6 +1,3 @@
extern crate core;
// extern crate multiboot2;
use vga::*; use vga::*;
use alloc::collections::BTreeMap; use alloc::collections::BTreeMap;
@ -29,7 +26,6 @@ lazy_static! {
commands.insert("stack", ::memory::print_stack as fn()); commands.insert("stack", ::memory::print_stack as fn());
commands.insert("page_fault", ::memory::page_fault as fn()); commands.insert("page_fault", ::memory::page_fault as fn());
commands.insert("overflow", ::memory::overflow as fn()); commands.insert("overflow", ::memory::overflow as fn());
commands.insert("overflow", ::memory::overflow as fn());
//pci //pci
commands.insert("lspci", ::pci::lspci as fn()); commands.insert("lspci", ::pci::lspci as fn());
@ -39,7 +35,7 @@ lazy_static! {
fn help() { fn help() {
println!("The following commands are available:"); println!("The following commands are available:");
for (key, val) in COMMANDS.iter() { for (key, _val) in COMMANDS.iter() {
println!("{}", key); println!("{}", key);
} }
} }

View file

@ -1,5 +1,3 @@
extern crate core;
use console; use console;
use x86::devices::io::{Io, Pio}; use x86::devices::io::{Io, Pio};

View file

@ -15,6 +15,7 @@
// x86 specific // x86 specific
#![feature(abi_x86_interrupt)] #![feature(abi_x86_interrupt)]
// extern crate core;
extern crate alloc; extern crate alloc;
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
@ -39,11 +40,12 @@ pub mod memory;
pub mod arch; pub mod arch;
pub use arch::x86::consts::*; pub use arch::x86::consts::*;
pub mod scheduling; pub mod scheduling;
#[allow(dead_code)]
pub mod time; pub mod time;
pub mod pci; pub mod pci;
/// kernel entry point. arch module is responsible for /// kernel entry point.
/// calling this once the core has loaded /// ::arch is responsible for calling this once the core has loaded.
pub fn kmain() -> ! { pub fn kmain() -> ! {
// memory init after heap is available // memory init after heap is available
// memory::init_noncore(); // memory::init_noncore();
@ -51,9 +53,11 @@ pub fn kmain() -> ! {
// unsafe VGA // unsafe VGA
unsafe { console::CONSOLE.init(); } unsafe { console::CONSOLE.init(); }
if let Ok(slot) = pci::get_ide1() { if let Some(ide) = pci::get_first(0x1, 0x1) {
println!("found IDE at slot {}", slot); println!("found IDE at slot {}", ide.slot);
pci::ide::init(ide);
} }
// scheduler WIP // scheduler WIP
// scheduling::schedule(); // scheduling::schedule();
unreachable!(); unreachable!();

4
kernel-rs/src/pci/ide.rs Normal file
View file

@ -0,0 +1,4 @@
use super::*;
pub fn init(drive: Pci) {
}

View file

@ -1,58 +1,105 @@
// https://wiki.osdev.org/PCI // https://wiki.osdev.org/PCI
use x86::devices::io::{Pio, Io}; use x86::devices::io::{Pio, Io};
use alloc::vec::*;
pub mod ide;
pub static mut PCI_CONFIG_ADDRESS: Pio<u32> = Pio::new(0xCF8); pub static mut PCI_CONFIG_ADDRESS: Pio<u32> = Pio::new(0xCF8);
pub static mut PCI_CONFIG_DATA: Pio<u32> = Pio::new(0xCFC); pub static mut PCI_CONFIG_DATA: Pio<u32> = Pio::new(0xCFC);
pub fn get_ide1() -> Result<u32, ()> { pub struct Pci {
let bus = 0; pub bus: u32,
pub slot: u32,
for slot in 0..31 { pub func: u32,
let vendor = pci_config_read_word(bus, slot, 0, 0); pub device: u16,
if vendor == 0xffff { pub vendor: u16,
continue; pub class: u8,
} pub subclass: u8,
let class = pci_config_read_byte(bus, slot, 0, 11); pub header_type: u8,
let subclass = pci_config_read_byte(bus, slot, 0, 10);
if class == 0x01 && subclass == 0x01 {
return Ok(slot);
}
}
Err(())
} }
pub fn lspci() { pub fn lspci() {
for pci in self::get_all() {
println!("{}", pci);
}
}
pub fn get_all() -> Vec<Pci> {
let bus = 0; let bus = 0;
let mut slot = 0;
let mut pcis: Vec<Pci> = Vec::new();
for slot in 0..31 { while let Some(pci)= pci_get(bus, slot, 0) {
let vendor = pci_config_read_word(bus, slot, 0, 0); if pci.header_type & 0x80 != 0 {
if vendor == 0xffff { let mut func = 0;
continue; while let Some(pci)= pci_get(bus, slot, func) {
}
let header_type = pci_config_read_byte(bus, slot, 0, 14) ;
if header_type & 0x80 != 0 {
// device has multiple functions // device has multiple functions
for function in 0..0x7 { pcis.push(pci);
let vendor = pci_config_read_word(bus, slot, function, 0); func += 1;
if vendor != 0xffff { if func == 7 {break;}
pci_display(bus, slot, function);
} }
} }
} else { pcis.push(pci);
pci_display(bus, slot, 0); slot += 1;
if slot == 32 {break;}
} }
pcis
}
pub fn get_first(class: u8, subclass: u8) -> Option<Pci> {
let bus = 0;
let mut slot = 0;
while let Some(pci)= pci_get(bus, slot, 0) {
if pci.class == class && pci.subclass == subclass {
return Some(pci);
}
if pci.header_type & 0x80 != 0 {
let mut func = 0;
while let Some(pci)= pci_get(bus, slot, func) {
// device has multiple functions
if pci.class == class && pci.subclass == subclass {
return Some(pci);
}
func += 1;
if func == 7 {break;}
}
}
slot += 1;
if slot == 32 {break;}
}
None
}
pub fn pci_get(bus: u32, slot: u32, func: u32) -> Option<Pci> {
let vendor = pci_config_read_word(bus, slot, func, 0);
if vendor == 0xffff { return None }
let pci = Pci {bus, slot, func, vendor,
device: pci_config_read_word(bus, slot, func, 2),
subclass: pci_config_read_byte(bus, slot, func, 10),
class: pci_config_read_byte(bus, slot, func, 11),
header_type: pci_config_read_byte(bus, slot, func, 14),
};
Some(pci)
}
use core::fmt;
impl fmt::Display for Pci {
fn fmt(&self, f: &mut core::fmt::Formatter) -> fmt::Result {
write!(f, "{}:{}.{} {:#x},{:#x} {:#x} {:#x}",
self.bus, self.slot, self.func,
self.class, self.subclass,
self.vendor, self.device);
Ok(())
} }
} }
pub fn pci_display(bus: u32, slot: u32, function: u32) { // pub fn pci_display(bus: u32, slot: u32, function: u32) {
let vendor = pci_config_read_word(bus, slot, function, 0); // let vendor = pci_config_read_word(bus, slot, function, 0);
let device = pci_config_read_word(bus, slot, function, 2); // let device = pci_config_read_word(bus, slot, function, 2);
let class = pci_config_read_byte(bus, slot, function, 11); // println!("{}:{}.{} {:#x},{:#x}: {:#x} {:#x}",
let subclass = pci_config_read_byte(bus, slot, function, 10); // bus, slot, function, class, subclass, vendor, device);
println!("{}:{}.{} {:#x},{:#x}: {:#x} {:#x}", // }
bus, slot, function, class, subclass, vendor, device);
}
pub fn pci_access(bus: u32, slot: u32, func: u32, offset: u32) { pub fn pci_access(bus: u32, slot: u32, func: u32, offset: u32) {
let address = (bus as u32) << 16 let address = (bus as u32) << 16

View file

@ -3,7 +3,7 @@
//! way the scheduling algorithms don't have to worry about //! way the scheduling algorithms don't have to worry about
//! managing these //! managing these
//! //!
//! inspired from https://wiki.osdev.org/Blocking_Process //! https://wiki.osdev.org/Blocking_Process
use alloc::collections::vec_deque::VecDeque; use alloc::collections::vec_deque::VecDeque;
use super::*; use super::*;

View file

@ -17,6 +17,6 @@ pub fn realtime() -> (u32, u32) {
} }
pub fn uptime() { pub fn uptime() {
let mut offset = self::OFFSET.lock(); let offset = self::OFFSET.lock();
println!("{}s", offset.0 + offset.1 / 1_000_000); println!("{}s", offset.0 + offset.1 / 1_000_000);
} }

View file

@ -67,8 +67,6 @@ pub fn print(args: fmt::Arguments) {
} }
} }
extern crate core;
const BUFFER_ROWS: usize = 25; const BUFFER_ROWS: usize = 25;
const BUFFER_COLS: usize = 80 * 2; const BUFFER_COLS: usize = 80 * 2;
@ -153,7 +151,7 @@ impl Writer {
// trait needed by formatting macros // trait needed by formatting macros
use core::fmt; use core::fmt;
impl fmt::Write for Writer { impl fmt::Write for Writer {
fn write_str(&mut self, s: &str) -> ::core::fmt::Result { fn write_str(&mut self, s: &str) -> fmt::Result {
for byte in s.bytes() { for byte in s.bytes() {
self.write_byte(byte) self.write_byte(byte)
} }