This commit is contained in:
Jeremy Soller 2016-10-23 09:13:20 -06:00
commit 9836b3cb56
18 changed files with 238 additions and 226 deletions

View file

@ -246,7 +246,9 @@ $(BUILD)/initfs.rs: \
initfs/bin/init \ initfs/bin/init \
initfs/bin/ahcid \ initfs/bin/ahcid \
initfs/bin/pcid \ initfs/bin/pcid \
initfs/bin/ps2d \
initfs/bin/redoxfs \ initfs/bin/redoxfs \
initfs/bin/vesad \
initfs/etc/** initfs/etc/**
echo 'use collections::BTreeMap;' > $@ echo 'use collections::BTreeMap;' > $@
echo 'pub fn gen() -> BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> {' >> $@ echo 'pub fn gen() -> BTreeMap<&'"'"'static [u8], (&'"'"'static [u8], bool)> {' >> $@
@ -321,9 +323,7 @@ filesystem/bin/%: schemes/%/Cargo.toml schemes/%/src/** $(BUILD)/libstd.rlib
drivers: \ drivers: \
filesystem/bin/e1000d \ filesystem/bin/e1000d \
filesystem/bin/ps2d \ filesystem/bin/rtl8168d
filesystem/bin/rtl8168d \
filesystem/bin/vesad
coreutils: \ coreutils: \
filesystem/bin/basename \ filesystem/bin/basename \

View file

@ -18,7 +18,7 @@ const HBA_PORT_CMD_CR: u32 = 1 << 15;
const HBA_PORT_CMD_FR: u32 = 1 << 14; const HBA_PORT_CMD_FR: u32 = 1 << 14;
const HBA_PORT_CMD_FRE: u32 = 1 << 4; const HBA_PORT_CMD_FRE: u32 = 1 << 4;
const HBA_PORT_CMD_ST: u32 = 1; const HBA_PORT_CMD_ST: u32 = 1;
const HBA_PORT_IS_TFES: u32 = 1 << 30; const HBA_PORT_IS_ERR: u32 = 1 << 30 | 1 << 29 | 1 << 28 | 1 << 27;
const HBA_SSTS_PRESENT: u32 = 0x3; const HBA_SSTS_PRESENT: u32 = 0x3;
const HBA_SIG_ATA: u32 = 0x00000101; const HBA_SIG_ATA: u32 = 0x00000101;
const HBA_SIG_ATAPI: u32 = 0xEB140101; const HBA_SIG_ATAPI: u32 = 0xEB140101;
@ -41,12 +41,12 @@ pub enum HbaPortType {
#[repr(packed)] #[repr(packed)]
pub struct HbaPort { pub struct HbaPort {
pub clb: Mmio<u64>, // 0x00, command list base address, 1K-byte aligned pub clb: [Mmio<u32>; 2], // 0x00, command list base address, 1K-byte aligned
pub fb: Mmio<u64>, // 0x08, FIS base address, 256-byte aligned pub fb: [Mmio<u32>; 2], // 0x08, FIS base address, 256-byte aligned
pub is: Mmio<u32>, // 0x10, interrupt status pub is: Mmio<u32>, // 0x10, interrupt status
pub ie: Mmio<u32>, // 0x14, interrupt enable pub ie: Mmio<u32>, // 0x14, interrupt enable
pub cmd: Mmio<u32>, // 0x18, command and status pub cmd: Mmio<u32>, // 0x18, command and status
pub rsv0: Mmio<u32>, // 0x1C, Reserved pub _rsv0: Mmio<u32>, // 0x1C, Reserved
pub tfd: Mmio<u32>, // 0x20, task file data pub tfd: Mmio<u32>, // 0x20, task file data
pub sig: Mmio<u32>, // 0x24, signature pub sig: Mmio<u32>, // 0x24, signature
pub ssts: Mmio<u32>, // 0x28, SATA status (SCR0:SStatus) pub ssts: Mmio<u32>, // 0x28, SATA status (SCR0:SStatus)
@ -56,7 +56,7 @@ pub struct HbaPort {
pub ci: Mmio<u32>, // 0x38, command issue pub ci: Mmio<u32>, // 0x38, command issue
pub sntf: Mmio<u32>, // 0x3C, SATA notification (SCR4:SNotification) pub sntf: Mmio<u32>, // 0x3C, SATA notification (SCR4:SNotification)
pub fbs: Mmio<u32>, // 0x40, FIS-based switch control pub fbs: Mmio<u32>, // 0x40, FIS-based switch control
pub rsv1: [Mmio<u32>; 11], // 0x44 ~ 0x6F, Reserved pub _rsv1: [Mmio<u32>; 11], // 0x44 ~ 0x6F, Reserved
pub vendor: [Mmio<u32>; 4], // 0x70 ~ 0x7F, vendor specific pub vendor: [Mmio<u32>; 4], // 0x70 ~ 0x7F, vendor specific
} }
@ -76,21 +76,54 @@ impl HbaPort {
} }
} }
pub fn start(&mut self) {
while self.cmd.readf(HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE | HBA_PORT_CMD_ST, true);
}
pub fn stop(&mut self) {
self.cmd.writef(HBA_PORT_CMD_ST, false);
while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE, false);
}
pub fn slot(&self) -> Option<u32> {
let slots = self.sact.read() | self.ci.read();
for i in 0..32 {
if slots & 1 << i == 0 {
return Some(i);
}
}
None
}
pub fn init(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32], fb: &mut Dma<[u8; 256]>) { pub fn init(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32], fb: &mut Dma<[u8; 256]>) {
self.stop(); self.stop();
self.clb.write(clb.physical() as u64);
self.fb.write(fb.physical() as u64);
let is = self.is.read();
self.is.write(is);
for i in 0..32 { for i in 0..32 {
let cmdheader = &mut clb[i]; let cmdheader = &mut clb[i];
cmdheader.ctba.write(ctbas[i].physical() as u64); cmdheader.ctba.write(ctbas[i].physical() as u64);
cmdheader.prdtl.write(0); cmdheader.prdtl.write(0);
} }
self.start(); self.clb[0].write(clb.physical() as u32);
self.clb[1].write((clb.physical() >> 32) as u32);
self.fb[0].write(fb.physical() as u32);
self.fb[1].write((fb.physical() >> 32) as u32);
let is = self.is.read();
self.is.write(is);
self.ie.write(0);
let serr = self.serr.read();
self.serr.write(serr);
print!("{}", format!(" - AHCI init {:X}\n", self.cmd.read()));
} }
pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32]) -> Option<u64> { pub unsafe fn identify(&mut self, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32]) -> Option<u64> {
@ -129,14 +162,16 @@ impl HbaPort {
self.ci.writef(1 << slot, true); self.ci.writef(1 << slot, true);
while self.ci.readf(1 << slot) { self.start();
if self.is.readf(HBA_PORT_IS_TFES) {
return None; while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 {
}
pause(); pause();
} }
if self.is.readf(HBA_PORT_IS_TFES) { self.stop();
if self.is.read() & HBA_PORT_IS_ERR != 0 {
print!("{}", format!("ERROR IS {:X} TFD {:X} SERR {:X}\n", self.is.read(), self.tfd.read(), self.serr.read()));
return None; return None;
} }
@ -191,8 +226,8 @@ impl HbaPort {
48 48
}; };
println!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB", print!("{}", format!(" + Serial: {} Firmware: {} Model: {} {}-bit LBA Size: {} MB\n",
serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048); serial.trim(), firmware.trim(), model.trim(), lba_bits, sectors / 2048));
Some(sectors * 512) Some(sectors * 512)
} else { } else {
@ -200,43 +235,20 @@ impl HbaPort {
} }
} }
pub fn start(&mut self) {
while self.cmd.readf(HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE, true);
self.cmd.writef(HBA_PORT_CMD_ST, true);
}
pub fn stop(&mut self) {
self.cmd.writef(HBA_PORT_CMD_ST, false);
while self.cmd.readf(HBA_PORT_CMD_FR | HBA_PORT_CMD_CR) {
pause();
}
self.cmd.writef(HBA_PORT_CMD_FRE, false);
}
pub fn slot(&self) -> Option<u32> {
let slots = self.sact.read() | self.ci.read();
for i in 0..32 {
if slots & 1 << i == 0 {
return Some(i);
}
}
None
}
pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result<usize> { pub fn ata_dma(&mut self, block: u64, sectors: usize, write: bool, clb: &mut Dma<[HbaCmdHeader; 32]>, ctbas: &mut [Dma<HbaCmdTable>; 32], buf: &mut Dma<[u8; 256 * 512]>) -> Result<usize> {
//println!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}", (self as *mut HbaPort) as usize, block, sectors, write); if write {
print!("{}", format!("AHCI {:X} DMA BLOCK: {:X} SECTORS: {} WRITE: {}\n", (self as *mut HbaPort) as usize, block, sectors, write));
}
assert!(sectors > 0 && sectors < 256); assert!(sectors > 0 && sectors < 256);
self.is.write(u32::MAX); self.is.write(u32::MAX);
if let Some(slot) = self.slot() { if let Some(slot) = self.slot() {
if write {
print!("{}", format!("SLOT {}\n", slot));
}
let cmdheader = &mut clb[slot as usize]; let cmdheader = &mut clb[slot as usize];
cmdheader.cfl.write(((size_of::<FisRegH2D>() / size_of::<u32>()) as u8)); cmdheader.cfl.write(((size_of::<FisRegH2D>() / size_of::<u32>()) as u8));
@ -278,28 +290,43 @@ impl HbaPort {
cmdfis.counth.write((sectors >> 8) as u8); cmdfis.counth.write((sectors >> 8) as u8);
} }
if write {
print!("WAIT ATA_DEV_BUSY | ATA_DEV_DRQ\n");
}
while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) { while self.tfd.readf((ATA_DEV_BUSY | ATA_DEV_DRQ) as u32) {
pause(); pause();
} }
if write {
print!("{}", format!("WRITE CI {:X} in {:X}\n", 1 << slot, self.ci.read()));
}
self.ci.writef(1 << slot, true); self.ci.writef(1 << slot, true);
while self.ci.readf(1 << slot) { self.start();
if self.is.readf(HBA_PORT_IS_TFES) {
println!("IS_TFES set in CI loop TFS {:X} SERR {:X}", self.tfd.read(), self.serr.read()); if write {
return Err(Error::new(EIO)); print!("{}", format!("WAIT CI {:X} in {:X}\n", 1 << slot, self.ci.read()));
} }
while (self.ci.readf(1 << slot) || self.tfd.readf(0x80)) && self.is.read() & HBA_PORT_IS_ERR == 0 {
pause(); pause();
if write {
print!("{}", format!("WAIT CI {:X} TFD {:X} IS {:X} CMD {:X} SERR {:X}\n", self.ci.read(), self.tfd.read(), self.is.read(), self.cmd.read(), self.serr.read()));
}
} }
if self.is.readf(HBA_PORT_IS_TFES) { self.stop();
println!("IS_TFES set after CI loop TFS {:X} SERR {:X}", self.tfd.read(), self.serr.read());
if self.is.read() & HBA_PORT_IS_ERR != 0 {
print!("{}", format!("ERROR IS {:X} TFD {:X} SERR {:X}\n", self.is.read(), self.tfd.read(), self.serr.read()));
return Err(Error::new(EIO)); return Err(Error::new(EIO));
} }
if write {
print!("{}", format!("SUCCESS {}\n", sectors));
}
Ok(sectors * 512) Ok(sectors * 512)
} else { } else {
println!("No Command Slots"); print!("No Command Slots\n");
Err(Error::new(EIO)) Err(Error::new(EIO))
} }
} }
@ -318,24 +345,31 @@ pub struct HbaMem {
pub em_ctl: Mmio<u32>, // 0x20, Enclosure management control pub em_ctl: Mmio<u32>, // 0x20, Enclosure management control
pub cap2: Mmio<u32>, // 0x24, Host capabilities extended pub cap2: Mmio<u32>, // 0x24, Host capabilities extended
pub bohc: Mmio<u32>, // 0x28, BIOS/OS handoff control and status pub bohc: Mmio<u32>, // 0x28, BIOS/OS handoff control and status
pub rsv: [Mmio<u8>; 116], // 0x2C - 0x9F, Reserved pub _rsv: [Mmio<u8>; 116], // 0x2C - 0x9F, Reserved
pub vendor: [Mmio<u8>; 96], // 0xA0 - 0xFF, Vendor specific registers pub vendor: [Mmio<u8>; 96], // 0xA0 - 0xFF, Vendor specific registers
pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers pub ports: [HbaPort; 32], // 0x100 - 0x10FF, Port control registers
} }
impl HbaMem { impl HbaMem {
pub fn reset(&mut self) { pub fn init(&mut self) {
/*
self.ghc.writef(1, true); self.ghc.writef(1, true);
while self.ghc.readf(1) { while self.ghc.readf(1) {
pause(); pause();
} }
*/
self.ghc.write(1 << 31 | 1 << 1);
print!("{}", format!(" - AHCI CAP {:X} GHC {:X} IS {:X} PI {:X} VS {:X} CAP2 {:X} BOHC {:X}",
self.cap.read(), self.ghc.read(), self.is.read(), self.pi.read(),
self.vs.read(), self.cap2.read(), self.bohc.read()));
} }
} }
#[repr(packed)] #[repr(packed)]
pub struct HbaPrdtEntry { pub struct HbaPrdtEntry {
dba: Mmio<u64>, // Data base address dba: Mmio<u64>, // Data base address
rsv0: Mmio<u32>, // Reserved _rsv0: Mmio<u32>, // Reserved
dbc: Mmio<u32>, // Byte count, 4M max, interrupt = 1 dbc: Mmio<u32>, // Byte count, 4M max, interrupt = 1
} }
@ -348,7 +382,7 @@ pub struct HbaCmdTable {
acmd: [Mmio<u8>; 16], // ATAPI command, 12 or 16 bytes acmd: [Mmio<u8>; 16], // ATAPI command, 12 or 16 bytes
// 0x50 // 0x50
rsv: [Mmio<u8>; 48], // Reserved _rsv: [Mmio<u8>; 48], // Reserved
// 0x80 // 0x80
prdt_entry: [HbaPrdtEntry; 65536], // Physical region descriptor table entries, 0 ~ 65535 prdt_entry: [HbaPrdtEntry; 65536], // Physical region descriptor table entries, 0 ~ 65535
@ -369,5 +403,5 @@ pub struct HbaCmdHeader {
ctba: Mmio<u64>, // Command table descriptor base address ctba: Mmio<u64>, // Command table descriptor base address
// DW4 - 7 // DW4 - 7
rsv1: [Mmio<u32>; 4], // Reserved _rsv1: [Mmio<u32>; 4], // Reserved
} }

View file

@ -7,22 +7,21 @@ pub mod disk;
pub mod fis; pub mod fis;
pub mod hba; pub mod hba;
pub fn disks(base: usize, irq: u8) -> Vec<Disk> { pub fn disks(base: usize) -> Vec<Disk> {
println!(" + AHCI on: {:X} IRQ: {}", base as usize, irq); unsafe { &mut *(base as *mut HbaMem) }.init();
let pi = unsafe { &mut *(base as *mut HbaMem) }.pi.read(); let pi = unsafe { &mut *(base as *mut HbaMem) }.pi.read();
let ret: Vec<Disk> = (0..32) let ret: Vec<Disk> = (0..32)
.filter(|&i| pi & 1 << i as i32 == 1 << i as i32) .filter(|&i| pi & 1 << i as i32 == 1 << i as i32)
.filter_map(|i| { .filter_map(|i| {
let port = &mut unsafe { &mut *(base as *mut HbaMem) }.ports[i]; let port = &mut unsafe { &mut *(base as *mut HbaMem) }.ports[i];
let port_type = port.probe(); let port_type = port.probe();
println!("{}: {:?}", i, port_type); print!("{}", format!("{}: {:?}\n", i, port_type));
match port_type { match port_type {
HbaPortType::SATA => { HbaPortType::SATA => {
match Disk::new(i, port) { match Disk::new(i, port) {
Ok(disk) => Some(disk), Ok(disk) => Some(disk),
Err(err) => { Err(err) => {
println!("{}: {}", i, err); print!("{}", format!("{}: {}\n", i, err));
None None
} }
} }

View file

@ -27,6 +27,8 @@ fn main() {
let irq_str = args.next().expect("ahcid: no irq provided"); let irq_str = args.next().expect("ahcid: no irq provided");
let irq = irq_str.parse::<u8>().expect("ahcid: failed to parse irq"); let irq = irq_str.parse::<u8>().expect("ahcid: failed to parse irq");
print!("{}", format!(" + AHCI on: {:X} IRQ: {}\n", bar, irq));
thread::spawn(move || { thread::spawn(move || {
unsafe { unsafe {
syscall::iopl(3).expect("ahcid: failed to get I/O permission"); syscall::iopl(3).expect("ahcid: failed to get I/O permission");
@ -45,7 +47,7 @@ fn main() {
let mut event_file = File::open("event:").expect("ahcid: failed to open event file"); let mut event_file = File::open("event:").expect("ahcid: failed to open event file");
let scheme = DiskScheme::new(ahci::disks(address, irq)); let scheme = DiskScheme::new(ahci::disks(address));
loop { loop {
let mut event = Event::default(); let mut event = Event::default();
event_file.read(&mut event).expect("ahcid: failed to read event file"); event_file.read(&mut event).expect("ahcid: failed to read event file");

View file

@ -7,5 +7,5 @@ bitflags = "*"
dma = { path = "../../crates/dma/" } dma = { path = "../../crates/dma/" }
event = { path = "../../crates/event/" } event = { path = "../../crates/event/" }
io = { path = "../../crates/io/" } io = { path = "../../crates/io/" }
spin = "*" netutils = { path = "../../programs/netutils/" }
syscall = { path = "../../syscall/" } syscall = { path = "../../syscall/" }

View file

@ -1,6 +1,7 @@
use std::{cmp, mem, ptr, slice}; use std::{cmp, mem, ptr, slice};
use dma::Dma; use dma::Dma;
use netutils::setcfg;
use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; use syscall::error::{Error, EACCES, EWOULDBLOCK, Result};
use syscall::scheme::Scheme; use syscall::scheme::Scheme;
@ -92,7 +93,6 @@ const TD_DD: u8 = 1;
pub struct Intel8254x { pub struct Intel8254x {
base: usize, base: usize,
irq: u8,
receive_buffer: [Dma<[u8; 16384]>; 16], receive_buffer: [Dma<[u8; 16384]>; 16],
receive_ring: Dma<[Rd; 16]>, receive_ring: Dma<[Rd; 16]>,
transmit_buffer: [Dma<[u8; 16384]>; 16], transmit_buffer: [Dma<[u8; 16384]>; 16],
@ -200,10 +200,9 @@ impl Scheme for Intel8254x {
} }
impl Intel8254x { impl Intel8254x {
pub unsafe fn new(base: usize, irq: u8) -> Result<Self> { pub unsafe fn new(base: usize) -> Result<Self> {
let mut module = Intel8254x { let mut module = Intel8254x {
base: base, base: base,
irq: irq,
receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
@ -244,8 +243,6 @@ impl Intel8254x {
} }
pub unsafe fn init(&mut self) { pub unsafe fn init(&mut self) {
println!(" + Intel 8254x on: {:X}, IRQ: {}", self.base, self.irq);
// Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal // Enable auto negotiate, link, clear reset, do not Invert Loss-Of Signal
self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true); self.flag(CTRL, CTRL_ASDE | CTRL_SLU, true);
self.flag(CTRL, CTRL_LRST, false); self.flag(CTRL, CTRL_LRST, false);
@ -271,7 +268,8 @@ impl Intel8254x {
(mac_low >> 24) as u8, (mac_low >> 24) as u8,
mac_high as u8, mac_high as u8,
(mac_high >> 8) as u8]; (mac_high >> 8) as u8];
println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
let _ = setcfg("mac", &format!("{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
// //
// MTA => 0; // MTA => 0;

View file

@ -2,6 +2,7 @@
extern crate dma; extern crate dma;
extern crate event; extern crate event;
extern crate netutils;
extern crate syscall; extern crate syscall;
use std::cell::RefCell; use std::cell::RefCell;
@ -26,6 +27,8 @@ fn main() {
let irq_str = args.next().expect("e1000d: no irq provided"); let irq_str = args.next().expect("e1000d: no irq provided");
let irq = irq_str.parse::<u8>().expect("e1000d: failed to parse irq"); let irq = irq_str.parse::<u8>().expect("e1000d: failed to parse irq");
print!("{}", format!(" + E1000 on: {:X}, IRQ: {}\n", bar, irq));
thread::spawn(move || { thread::spawn(move || {
unsafe { unsafe {
syscall::iopl(3).expect("e1000d: failed to get I/O permission"); syscall::iopl(3).expect("e1000d: failed to get I/O permission");
@ -37,7 +40,7 @@ fn main() {
let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") }; let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("e1000d: failed to map address") };
{ {
let device = Arc::new(unsafe { device::Intel8254x::new(address, irq).expect("e1000d: failed to allocate device") }); let device = Arc::new(unsafe { device::Intel8254x::new(address).expect("e1000d: failed to allocate device") });
let mut event_queue = EventQueue::<usize>::new().expect("e1000d: failed to create event queue"); let mut event_queue = EventQueue::<usize>::new().expect("e1000d: failed to create event queue");

View file

@ -8,7 +8,6 @@ use std::env;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
use std::process::Command; use std::process::Command;
use std::thread;
use syscall::iopl; use syscall::iopl;
use config::Config; use config::Config;
@ -18,7 +17,6 @@ mod config;
mod pci; mod pci;
fn main() { fn main() {
thread::spawn(|| {
let mut config = Config::default(); let mut config = Config::default();
let mut args = env::args().skip(1); let mut args = env::args().skip(1);
@ -33,43 +31,44 @@ fn main() {
unsafe { iopl(3).unwrap() }; unsafe { iopl(3).unwrap() };
println!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV"); print!("PCI BS/DV/FN VEND:DEVI CL.SC.IN.RV\n");
let pci = Pci::new(); let pci = Pci::new();
for bus in pci.buses() { for bus in pci.buses() {
for dev in bus.devs() { for dev in bus.devs() {
for func in dev.funcs() { for func in dev.funcs() {
if let Some(header) = func.header() { if let Some(header) = func.header() {
print!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X}", let pci_class = PciClass::from(header.class);
let mut string = format!("PCI {:>02X}/{:>02X}/{:>02X} {:>04X}:{:>04X} {:>02X}.{:>02X}.{:>02X}.{:>02X} {:?}",
bus.num, dev.num, func.num, bus.num, dev.num, func.num,
header.vendor_id, header.device_id, header.vendor_id, header.device_id,
header.class, header.subclass, header.interface, header.revision); header.class, header.subclass, header.interface, header.revision,
pci_class);
let pci_class = PciClass::from(header.class);
print!(" {:?}", pci_class);
match pci_class { match pci_class {
PciClass::Storage => match header.subclass { PciClass::Storage => match header.subclass {
0x01 => { 0x01 => {
print!(" IDE"); string.push_str(" IDE");
}, },
0x06 => { 0x06 => {
print!(" SATA"); string.push_str(" SATA");
}, },
_ => () _ => ()
}, },
PciClass::SerialBus => match header.subclass { PciClass::SerialBus => match header.subclass {
0x03 => match header.interface { 0x03 => match header.interface {
0x00 => { 0x00 => {
print!(" UHCI"); string.push_str(" UHCI");
}, },
0x10 => { 0x10 => {
print!(" OHCI"); string.push_str(" OHCI");
}, },
0x20 => { 0x20 => {
print!(" EHCI"); string.push_str(" EHCI");
}, },
0x30 => { 0x30 => {
print!(" XHCI"); string.push_str(" XHCI");
}, },
_ => () _ => ()
}, },
@ -81,12 +80,14 @@ fn main() {
for i in 0..header.bars.len() { for i in 0..header.bars.len() {
match PciBar::from(header.bars[i]) { match PciBar::from(header.bars[i]) {
PciBar::None => (), PciBar::None => (),
PciBar::Memory(address) => print!(" {}={:>08X}", i, address), PciBar::Memory(address) => string.push_str(&format!(" {}={:>08X}", i, address)),
PciBar::Port(address) => print!(" {}={:>04X}", i, address) PciBar::Port(address) => string.push_str(&format!(" {}={:>04X}", i, address))
} }
} }
print!("\n"); string.push('\n');
print!("{}", string);
for driver in config.drivers.iter() { for driver in config.drivers.iter() {
if let Some(class) = driver.class { if let Some(class) = driver.class {
@ -150,5 +151,4 @@ fn main() {
} }
} }
} }
});
} }

View file

@ -7,5 +7,5 @@ bitflags = "*"
dma = { path = "../../crates/dma/" } dma = { path = "../../crates/dma/" }
event = { path = "../../crates/event/" } event = { path = "../../crates/event/" }
io = { path = "../../crates/io/" } io = { path = "../../crates/io/" }
spin = "*" netutils = { path = "../../programs/netutils/" }
syscall = { path = "../../syscall/" } syscall = { path = "../../syscall/" }

View file

@ -2,6 +2,7 @@ use std::mem;
use dma::Dma; use dma::Dma;
use io::{Mmio, Io, ReadOnly}; use io::{Mmio, Io, ReadOnly};
use netutils::setcfg;
use syscall::error::{Error, EACCES, EWOULDBLOCK, Result}; use syscall::error::{Error, EACCES, EWOULDBLOCK, Result};
use syscall::scheme::SchemeMut; use syscall::scheme::SchemeMut;
@ -65,7 +66,6 @@ struct Td {
pub struct Rtl8168 { pub struct Rtl8168 {
regs: &'static mut Regs, regs: &'static mut Regs,
irq: u8,
receive_buffer: [Dma<[u8; 0x1FF8]>; 16], receive_buffer: [Dma<[u8; 0x1FF8]>; 16],
receive_ring: Dma<[Rd; 16]>, receive_ring: Dma<[Rd; 16]>,
transmit_buffer: [Dma<[u8; 7552]>; 16], transmit_buffer: [Dma<[u8; 7552]>; 16],
@ -88,13 +88,10 @@ impl SchemeMut for Rtl8168 {
} }
fn read(&mut self, _id: usize, buf: &mut [u8]) -> Result<usize> { fn read(&mut self, _id: usize, buf: &mut [u8]) -> Result<usize> {
println!("Try Receive {}", buf.len());
for (rd_i, rd) in self.receive_ring.iter_mut().enumerate() { for (rd_i, rd) in self.receive_ring.iter_mut().enumerate() {
if ! rd.ctrl.readf(OWN) { if ! rd.ctrl.readf(OWN) {
let rd_len = rd.ctrl.read() & 0x3FFF; let rd_len = rd.ctrl.read() & 0x3FFF;
println!("Receive {}: {}", rd_i, rd_len);
let data = &self.receive_buffer[rd_i as usize]; let data = &self.receive_buffer[rd_i as usize];
let mut i = 0; let mut i = 0;
@ -114,11 +111,9 @@ impl SchemeMut for Rtl8168 {
} }
fn write(&mut self, _id: usize, buf: &[u8]) -> Result<usize> { fn write(&mut self, _id: usize, buf: &[u8]) -> Result<usize> {
println!("Try Transmit {}", buf.len());
loop { loop {
for (td_i, td) in self.transmit_ring.iter_mut().enumerate() { for (td_i, td) in self.transmit_ring.iter_mut().enumerate() {
if ! td.ctrl.readf(OWN) { if ! td.ctrl.readf(OWN) {
println!("Transmit {}: Setup {}", td_i, buf.len());
let mut data = &mut self.transmit_buffer[td_i as usize]; let mut data = &mut self.transmit_buffer[td_i as usize];
@ -128,21 +123,15 @@ impl SchemeMut for Rtl8168 {
i += 1; i += 1;
} }
println!("Transmit {}: Before: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read());
let eor = td.ctrl.read() & EOR; let eor = td.ctrl.read() & EOR;
td.ctrl.write(OWN | eor | FS | LS | i as u32); td.ctrl.write(OWN | eor | FS | LS | i as u32);
self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet self.regs.tppoll.writef(1 << 6, true); //Notify of normal priority packet
println!("Transmit {}: During: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read());
while self.regs.tppoll.readf(1 << 6) { while self.regs.tppoll.readf(1 << 6) {
unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); } unsafe { asm!("pause" : : : "memory" : "intel", "volatile"); }
} }
println!("Transmit {}: After: Control {:X}: Buffer {:X} TPPoll: {:X} ISR: {:X}", td_i, td.ctrl.read(), td.buffer.read(), self.regs.tppoll.read(), self.regs.isr.read());
return Ok(i); return Ok(i);
} }
} }
@ -165,7 +154,7 @@ impl SchemeMut for Rtl8168 {
} }
impl Rtl8168 { impl Rtl8168 {
pub unsafe fn new(base: usize, irq: u8) -> Result<Self> { pub unsafe fn new(base: usize) -> Result<Self> {
assert_eq!(mem::size_of::<Regs>(), 256); assert_eq!(mem::size_of::<Regs>(), 256);
let regs = &mut *(base as *mut Regs); let regs = &mut *(base as *mut Regs);
@ -181,7 +170,6 @@ impl Rtl8168 {
let mut module = Rtl8168 { let mut module = Rtl8168 {
regs: regs, regs: regs,
irq: irq,
receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, receive_buffer: [Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?, Dma::zeroed()?,
@ -210,8 +198,6 @@ impl Rtl8168 {
} }
pub unsafe fn init(&mut self) { pub unsafe fn init(&mut self) {
println!(" + RTL8168 on: {:X}, IRQ: {}", self.regs as *mut Regs as usize, self.irq);
let mac_low = self.regs.mac[0].read(); let mac_low = self.regs.mac[0].read();
let mac_high = self.regs.mac[1].read(); let mac_high = self.regs.mac[1].read();
let mac = [mac_low as u8, let mac = [mac_low as u8,
@ -220,7 +206,8 @@ impl Rtl8168 {
(mac_low >> 24) as u8, (mac_low >> 24) as u8,
mac_high as u8, mac_high as u8,
(mac_high >> 8) as u8]; (mac_high >> 8) as u8];
println!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); print!("{}", format!(" - MAC: {:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}:{:>02X}\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
let _ = setcfg("mac", &format!("{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}.{:>02X}", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]));
// Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value // Reset - this will disable tx and rx, reinitialize FIFOs, and set the system buffer pointer to the initial value
self.regs.cmd.writef(1 << 4, true); self.regs.cmd.writef(1 << 4, true);
@ -292,18 +279,5 @@ impl Rtl8168 {
// Lock config // Lock config
self.regs.cmd_9346.write(0); self.regs.cmd_9346.write(0);
println!(" - Ready CMD {:X} ISR {:X} IMR {:X} PHYS {:X} RMS {:X} MTPS {:X} RCR {:X} TCR {:X} RDSAR {:X} TNPDS {:X} THPDS {:X}",
self.regs.cmd.read(),
self.regs.isr.read(),
self.regs.imr.read(),
self.regs.phys_sts.read(),
self.regs.rms.read(),
self.regs.mtps.read(),
self.regs.rcr.read(),
self.regs.tcr.read(),
self.regs.rdsar[0].read(),
self.regs.tnpds[0].read(),
self.regs.thpds[0].read());
} }
} }

View file

@ -3,6 +3,7 @@
extern crate dma; extern crate dma;
extern crate event; extern crate event;
extern crate io; extern crate io;
extern crate netutils;
extern crate syscall; extern crate syscall;
use std::cell::RefCell; use std::cell::RefCell;
@ -27,6 +28,8 @@ fn main() {
let irq_str = args.next().expect("rtl8168d: no irq provided"); let irq_str = args.next().expect("rtl8168d: no irq provided");
let irq = irq_str.parse::<u8>().expect("rtl8168d: failed to parse irq"); let irq = irq_str.parse::<u8>().expect("rtl8168d: failed to parse irq");
print!("{}", format!(" + RTL8168 on: {:X}, IRQ: {}\n", bar, irq));
thread::spawn(move || { thread::spawn(move || {
unsafe { unsafe {
syscall::iopl(3).expect("rtl8168d: failed to get I/O permission"); syscall::iopl(3).expect("rtl8168d: failed to get I/O permission");
@ -40,7 +43,7 @@ fn main() {
let address = unsafe { syscall::physmap(bar, 256, MAP_WRITE).expect("rtl8168d: failed to map address") }; let address = unsafe { syscall::physmap(bar, 256, MAP_WRITE).expect("rtl8168d: failed to map address") };
{ {
let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address, irq).expect("rtl8168d: failed to allocate device") })); let device = Arc::new(RefCell::new(unsafe { device::Rtl8168::new(address).expect("rtl8168d: failed to allocate device") }));
let mut event_queue = EventQueue::<usize>::new().expect("rtl8168d: failed to create event queue"); let mut event_queue = EventQueue::<usize>::new().expect("rtl8168d: failed to create event queue");
@ -55,8 +58,6 @@ fn main() {
let isr = unsafe { device_irq.borrow_mut().irq() }; let isr = unsafe { device_irq.borrow_mut().irq() };
if isr != 0 { if isr != 0 {
println!("RTL8168 ISR {:X}", isr);
irq_file.write(&mut irq)?; irq_file.write(&mut irq)?;
let mut todo = todo_irq.borrow_mut(); let mut todo = todo_irq.borrow_mut();

View file

@ -1,12 +1,10 @@
vesad T T T G
stdio display:1
ps2d
initfs:bin/pcid /etc/pcid.toml initfs:bin/pcid /etc/pcid.toml
ethernetd ethernetd
#arpd #arpd
ipd ipd
tcpd tcpd
udpd udpd
dhcpd -b
getty display:2 getty display:2
getty display:3 getty display:3
#orbital display:4 #orbital display:4

View file

@ -1 +1 @@
10.85.85.1 0.0.0.0

View file

@ -1 +1 @@
10.85.85.2 0.0.0.0

View file

@ -1 +1 @@
10.85.85.1 0.0.0.0

View file

@ -1 +1 @@
255.255.255.0 0.0.0.0

View file

@ -1 +1 @@
08.9E.01.DD.45.AF 00.00.00.00.00.00

View file

@ -1,3 +1,6 @@
initfs:bin/vesad T T T G
stdio display:1
initfs:bin/ps2d
initfs:bin/pcid initfs:etc/pcid.toml initfs:bin/pcid initfs:etc/pcid.toml
initfs:bin/redoxfs disk:0 initfs:bin/redoxfs disk:0
cd file: cd file: