main.rs 2.73 KB
Newer Older
1 2 3 4
#![feature(asm)]

#[macro_use]
extern crate bitflags;
Jeremy Soller's avatar
Jeremy Soller committed
5
extern crate dma;
6
extern crate io;
7
extern crate spin;
8 9
extern crate syscall;

Jeremy Soller's avatar
Jeremy Soller committed
10
use std::{env, thread, usize};
11 12
use std::fs::File;
use std::io::{Read, Write};
13
use std::os::unix::io::{AsRawFd, FromRawFd};
Jeremy Soller's avatar
Jeremy Soller committed
14
use syscall::{EVENT_READ, MAP_WRITE, Event, Packet, Scheme};
15

16
use scheme::DiskScheme;
17 18

pub mod ahci;
19
pub mod scheme;
20 21 22 23 24 25 26 27 28 29 30 31

fn main() {
    let mut args = env::args().skip(1);

    let bar_str = args.next().expect("ahcid: no address provided");
    let bar = usize::from_str_radix(&bar_str, 16).expect("ahcid: failed to parse address");

    let irq_str = args.next().expect("ahcid: no irq provided");
    let irq = irq_str.parse::<u8>().expect("ahcid: failed to parse irq");

    thread::spawn(move || {
        unsafe {
Jeremy Soller's avatar
Jeremy Soller committed
32
            syscall::iopl(3).expect("ahcid: failed to get I/O permission");
33 34 35
            asm!("cli" :::: "intel", "volatile");
        }

Jeremy Soller's avatar
Jeremy Soller committed
36
        let address = unsafe { syscall::physmap(bar, 4096, MAP_WRITE).expect("ahcid: failed to map address") };
Jeremy Soller's avatar
Jeremy Soller committed
37
        {
38 39
            let socket_fd = syscall::open(":disk", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("ahcid: failed to create disk scheme");
            let mut socket = unsafe { File::from_raw_fd(socket_fd) };
Jeremy Soller's avatar
Jeremy Soller committed
40 41 42 43 44 45 46 47
            syscall::fevent(socket_fd, EVENT_READ).expect("ahcid: failed to fevent disk scheme");

            let mut irq_file = File::open(&format!("irq:{}", irq)).expect("ahcid: failed to open irq file");
            let irq_fd = irq_file.as_raw_fd();
            syscall::fevent(irq_fd, EVENT_READ).expect("ahcid: failed to fevent irq file");

            let mut event_file = File::open("event:").expect("ahcid: failed to open event file");

48
            let scheme = DiskScheme::new(ahci::disks(address, irq));
Jeremy Soller's avatar
Jeremy Soller committed
49
            loop {
Jeremy Soller's avatar
Jeremy Soller committed
50 51 52 53 54 55 56 57 58 59
                let mut event = Event::default();
                event_file.read(&mut event).expect("ahcid: failed to read event file");
                if event.id == socket_fd {
                    let mut packet = Packet::default();
                    socket.read(&mut packet).expect("ahcid: failed to read disk scheme");
                    scheme.handle(&mut packet);
                    socket.write(&mut packet).expect("ahcid: failed to write disk scheme");
                } else if event.id == irq_fd {
                    let mut irq = [0; 8];
                    if irq_file.read(&mut irq).expect("ahcid: failed to read irq file") >= irq.len() {
60 61
                        //TODO : Test for IRQ
                        //irq_file.write(&irq).expect("ahcid: failed to write irq file");
Jeremy Soller's avatar
Jeremy Soller committed
62 63 64 65
                    }
                } else {
                    println!("Unknown event {}", event.id);
                }
Jeremy Soller's avatar
Jeremy Soller committed
66
            }
67
        }
Jeremy Soller's avatar
Jeremy Soller committed
68
        unsafe { let _ = syscall::physunmap(address); }
69 70
    });
}