Merge branch 'alx'
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "alxd"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "0.7"
|
||||
netutils = { git = "https://github.com/redox-os/netutils.git" }
|
||||
redox_event = { git = "https://github.com/redox-os/event.git" }
|
||||
redox_syscall = "0.1"
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,138 @@
|
||||
#![allow(unused_parens)]
|
||||
#![feature(asm)]
|
||||
#![feature(concat_idents)]
|
||||
|
||||
extern crate event;
|
||||
extern crate netutils;
|
||||
extern crate syscall;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::env;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, Write, Result};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
use std::sync::Arc;
|
||||
|
||||
use event::EventQueue;
|
||||
use syscall::{Packet, SchemeMut, MAP_WRITE};
|
||||
use syscall::error::EWOULDBLOCK;
|
||||
|
||||
pub mod device;
|
||||
|
||||
fn main() {
|
||||
let mut args = env::args().skip(1);
|
||||
|
||||
let mut name = args.next().expect("alxd: no name provided");
|
||||
name.push_str("_alx");
|
||||
|
||||
let bar_str = args.next().expect("alxd: no address provided");
|
||||
let bar = usize::from_str_radix(&bar_str, 16).expect("alxd: failed to parse address");
|
||||
|
||||
let irq_str = args.next().expect("alxd: no irq provided");
|
||||
let irq = irq_str.parse::<u8>().expect("alxd: failed to parse irq");
|
||||
|
||||
print!("{}", format!(" + ALX {} on: {:X}, IRQ: {}\n", name, bar, irq));
|
||||
|
||||
// Daemonize
|
||||
if unsafe { syscall::clone(0).unwrap() } == 0
|
||||
{
|
||||
let socket_fd = syscall::open(":network", syscall::O_RDWR | syscall::O_CREAT | syscall::O_NONBLOCK).expect("alxd: failed to create network scheme");
|
||||
let socket = Arc::new(RefCell::new(unsafe { File::from_raw_fd(socket_fd) }));
|
||||
|
||||
let address = unsafe { syscall::physmap(bar, 128*1024, MAP_WRITE).expect("alxd: failed to map address") };
|
||||
{
|
||||
let device = Arc::new(RefCell::new(unsafe { device::Alx::new(address).expect("alxd: failed to allocate device") }));
|
||||
|
||||
let mut event_queue = EventQueue::<usize>::new().expect("alxd: failed to create event queue");
|
||||
|
||||
let todo = Arc::new(RefCell::new(Vec::<Packet>::new()));
|
||||
|
||||
let device_irq = device.clone();
|
||||
let socket_irq = socket.clone();
|
||||
let todo_irq = todo.clone();
|
||||
let mut irq_file = File::open(format!("irq:{}", irq)).expect("alxd: failed to open IRQ file");
|
||||
event_queue.add(irq_file.as_raw_fd(), move |_count: usize| -> Result<Option<usize>> {
|
||||
let mut irq = [0; 8];
|
||||
irq_file.read(&mut irq)?;
|
||||
if unsafe { device_irq.borrow_mut().intr_legacy() } {
|
||||
irq_file.write(&mut irq)?;
|
||||
|
||||
let mut todo = todo_irq.borrow_mut();
|
||||
let mut i = 0;
|
||||
while i < todo.len() {
|
||||
let a = todo[i].a;
|
||||
device_irq.borrow_mut().handle(&mut todo[i]);
|
||||
if todo[i].a == (-EWOULDBLOCK) as usize {
|
||||
todo[i].a = a;
|
||||
i += 1;
|
||||
} else {
|
||||
socket_irq.borrow_mut().write(&mut todo[i])?;
|
||||
todo.remove(i);
|
||||
}
|
||||
}
|
||||
|
||||
let next_read = device_irq.borrow().next_read();
|
||||
if next_read > 0 {
|
||||
return Ok(Some(next_read));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
}).expect("alxd: failed to catch events on IRQ file");
|
||||
|
||||
let socket_packet = socket.clone();
|
||||
event_queue.add(socket_fd, move |_count: usize| -> Result<Option<usize>> {
|
||||
loop {
|
||||
let mut packet = Packet::default();
|
||||
if socket_packet.borrow_mut().read(&mut packet)? == 0 {
|
||||
break;
|
||||
}
|
||||
|
||||
let a = packet.a;
|
||||
device.borrow_mut().handle(&mut packet);
|
||||
if packet.a == (-EWOULDBLOCK) as usize {
|
||||
packet.a = a;
|
||||
todo.borrow_mut().push(packet);
|
||||
} else {
|
||||
socket_packet.borrow_mut().write(&mut packet)?;
|
||||
}
|
||||
}
|
||||
|
||||
let next_read = device.borrow().next_read();
|
||||
if next_read > 0 {
|
||||
return Ok(Some(next_read));
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}).expect("alxd: failed to catch events on IRQ file");
|
||||
|
||||
for event_count in event_queue.trigger_all(0).expect("alxd: failed to trigger events") {
|
||||
socket.borrow_mut().write(&Packet {
|
||||
id: 0,
|
||||
pid: 0,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
a: syscall::number::SYS_FEVENT,
|
||||
b: 0,
|
||||
c: syscall::flag::EVENT_READ,
|
||||
d: event_count
|
||||
}).expect("alxd: failed to write event");
|
||||
}
|
||||
|
||||
loop {
|
||||
let event_count = event_queue.run().expect("alxd: failed to handle events");
|
||||
|
||||
socket.borrow_mut().write(&Packet {
|
||||
id: 0,
|
||||
pid: 0,
|
||||
uid: 0,
|
||||
gid: 0,
|
||||
a: syscall::number::SYS_FEVENT,
|
||||
b: 0,
|
||||
c: syscall::flag::EVENT_READ,
|
||||
d: event_count
|
||||
}).expect("alxd: failed to write event");
|
||||
}
|
||||
}
|
||||
unsafe { let _ = syscall::physunmap(address); }
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -25,6 +25,6 @@ fn main() {
|
||||
unsafe { iopl(3).unwrap() };
|
||||
|
||||
let mut bga = Bga::new();
|
||||
print!("{}", format!(" - BGA {}x{}", bga.width(), bga.height()));
|
||||
print!("{}", format!(" - BGA {}x{}\n", bga.width(), bga.height()));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -108,10 +108,11 @@ fn main() {
|
||||
}
|
||||
|
||||
if let Some(ref args) = driver.command {
|
||||
// Enable bus mastering
|
||||
// Enable bus mastering, memory space, and I/O space
|
||||
unsafe {
|
||||
let cmd = pci.read(bus.num, dev.num, func.num, 0x04);
|
||||
pci.write(bus.num, dev.num, func.num, 0x04, cmd | 4);
|
||||
println!("PCI CMD: {:>02X}", cmd);
|
||||
pci.write(bus.num, dev.num, func.num, 0x04, cmd | 7);
|
||||
}
|
||||
|
||||
let mut args = args.iter();
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
use syscall::io::{Io, Pio};
|
||||
|
||||
const BGA_INDEX_XRES: u16 = 1;
|
||||
const BGA_INDEX_YRES: u16 = 2;
|
||||
const BGA_INDEX_BPP: u16 = 3;
|
||||
const BGA_INDEX_ENABLE: u16 = 4;
|
||||
|
||||
pub struct Bga {
|
||||
index: Pio<u16>,
|
||||
data: Pio<u16>,
|
||||
}
|
||||
|
||||
impl Bga {
|
||||
pub fn new() -> Bga {
|
||||
Bga {
|
||||
index: Pio::new(0x1CE),
|
||||
data: Pio::new(0x1CF),
|
||||
}
|
||||
}
|
||||
|
||||
fn read(&mut self, index: u16) -> u16 {
|
||||
self.index.write(index);
|
||||
self.data.read()
|
||||
}
|
||||
|
||||
fn write(&mut self, index: u16, data: u16) {
|
||||
self.index.write(index);
|
||||
self.data.write(data);
|
||||
}
|
||||
|
||||
pub fn width(&mut self) -> u16 {
|
||||
self.read(BGA_INDEX_XRES)
|
||||
}
|
||||
|
||||
pub fn height(&mut self) -> u16 {
|
||||
self.read(BGA_INDEX_YRES)
|
||||
}
|
||||
|
||||
pub fn set_size(&mut self, width: u16, height: u16) {
|
||||
self.write(BGA_INDEX_ENABLE, 0);
|
||||
self.write(BGA_INDEX_XRES, width);
|
||||
self.write(BGA_INDEX_YRES, height);
|
||||
self.write(BGA_INDEX_BPP, 32);
|
||||
self.write(BGA_INDEX_ENABLE, 0x41);
|
||||
}
|
||||
}
|
||||
+21
-3
@@ -13,6 +13,10 @@ use syscall::flag::MAP_WRITE;
|
||||
use syscall::io::{Dma, Io, Mmio, Pio};
|
||||
use syscall::iopl;
|
||||
|
||||
use bga::Bga;
|
||||
|
||||
mod bga;
|
||||
|
||||
const VBOX_REQUEST_HEADER_VERSION: u32 = 0x10001;
|
||||
const VBOX_VMMDEV_VERSION: u32 = 0x00010003;
|
||||
|
||||
@@ -234,6 +238,7 @@ fn main() {
|
||||
|
||||
let mut event_queue = EventQueue::<()>::new().expect("vboxd: failed to create event queue");
|
||||
|
||||
let mut bga = Bga::new();
|
||||
let get_mouse = VboxGetMouse::new().expect("vboxd: failed to map GetMouse");
|
||||
let display_change = VboxDisplayChange::new().expect("vboxd: failed to map DisplayChange");
|
||||
let ack_events = VboxAckEvents::new().expect("vboxd: failed to map AckEvents");
|
||||
@@ -247,14 +252,27 @@ fn main() {
|
||||
|
||||
if host_events & VBOX_EVENT_DISPLAY == VBOX_EVENT_DISPLAY {
|
||||
port.write(display_change.physical() as u32);
|
||||
println!("Display {}, {}", display_change.xres.read(), display_change.yres.read());
|
||||
if let Some(ref mut display) = display_opt {
|
||||
let new_width = display_change.xres.read();
|
||||
let new_height = display_change.yres.read();
|
||||
if width != new_width || height != new_height {
|
||||
width = new_width;
|
||||
height = new_height;
|
||||
println!("Display {}, {}", width, height);
|
||||
bga.set_size(width as u16, height as u16);
|
||||
let _ = display.write(&orbclient::ResizeEvent {
|
||||
width: width,
|
||||
height: height,
|
||||
}.to_event());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if host_events & VBOX_EVENT_MOUSE == VBOX_EVENT_MOUSE {
|
||||
port.write(get_mouse.physical() as u32);
|
||||
let x = get_mouse.x.read() * width / 0x10000;
|
||||
let y = get_mouse.y.read() * height / 0x10000;
|
||||
if let Some(ref mut display) = display_opt {
|
||||
let x = get_mouse.x.read() * width / 0x10000;
|
||||
let y = get_mouse.y.read() * height / 0x10000;
|
||||
let _ = display.write(&orbclient::MouseEvent {
|
||||
x: x as i32,
|
||||
y: y as i32,
|
||||
|
||||
+62
-13
@@ -4,7 +4,7 @@ extern crate rusttype;
|
||||
use alloc::heap;
|
||||
use std::{cmp, slice};
|
||||
|
||||
use primitive::{fast_set32, fast_set64, fast_copy, fast_copy64};
|
||||
use primitive::{fast_set32, fast_set64, fast_copy};
|
||||
|
||||
#[cfg(feature="rusttype")]
|
||||
use self::rusttype::{Font, FontCollection, Scale, point};
|
||||
@@ -68,12 +68,57 @@ impl Display {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: usize, height: usize) {
|
||||
if width != self.width || height != self.height {
|
||||
println!("Resize display to {}, {}", width, height);
|
||||
|
||||
let size = width * height;
|
||||
let offscreen = unsafe { heap::allocate(size * 4, 4096) };
|
||||
|
||||
{
|
||||
let mut old_ptr = self.offscreen.as_ptr();
|
||||
let mut new_ptr = offscreen as *mut u32;
|
||||
|
||||
for _y in 0..cmp::min(height, self.height) {
|
||||
unsafe {
|
||||
fast_copy(new_ptr as *mut u8, old_ptr as *const u8, cmp::min(width, self.width) * 4);
|
||||
if width > self.width {
|
||||
fast_set32(new_ptr.offset(self.width as isize), 0, width - self.width);
|
||||
}
|
||||
old_ptr = old_ptr.offset(self.width as isize);
|
||||
new_ptr = new_ptr.offset(width as isize);
|
||||
}
|
||||
}
|
||||
|
||||
if height > self.height {
|
||||
for _y in self.height..height {
|
||||
unsafe {
|
||||
fast_set32(new_ptr, 0, width);
|
||||
new_ptr = new_ptr.offset(width as isize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.width = width;
|
||||
self.height = height;
|
||||
|
||||
let onscreen = self.onscreen.as_mut_ptr();
|
||||
self.onscreen = unsafe { slice::from_raw_parts_mut(onscreen, size) };
|
||||
|
||||
unsafe { heap::deallocate(self.offscreen.as_mut_ptr() as *mut u8, self.offscreen.len() * 4, 4096) };
|
||||
self.offscreen = unsafe { slice::from_raw_parts_mut(offscreen as *mut u32, size) };
|
||||
} else {
|
||||
println!("Display is already {}, {}", width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a rectangle
|
||||
pub fn rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: u32) {
|
||||
let start_y = cmp::min(self.height - 1, y);
|
||||
let start_y = cmp::min(self.height, y);
|
||||
let end_y = cmp::min(self.height, y + h);
|
||||
|
||||
let start_x = cmp::min(self.width - 1, x);
|
||||
let start_x = cmp::min(self.width, x);
|
||||
let len = cmp::min(self.width, x + w) - start_x;
|
||||
|
||||
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||
@@ -95,10 +140,10 @@ impl Display {
|
||||
|
||||
/// Invert a rectangle
|
||||
pub fn invert(&mut self, x: usize, y: usize, w: usize, h: usize) {
|
||||
let start_y = cmp::min(self.height - 1, y);
|
||||
let start_y = cmp::min(self.height, y);
|
||||
let end_y = cmp::min(self.height, y + h);
|
||||
|
||||
let start_x = cmp::min(self.width - 1, x);
|
||||
let start_x = cmp::min(self.width, x);
|
||||
let len = cmp::min(self.width, x + w) - start_x;
|
||||
|
||||
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||
@@ -201,27 +246,25 @@ impl Display {
|
||||
|
||||
/// Scroll display
|
||||
pub fn scroll(&mut self, rows: usize, color: u32) {
|
||||
let data = (color as u64) << 32 | color as u64;
|
||||
|
||||
let width = self.width/2;
|
||||
let width = self.width;
|
||||
let height = self.height;
|
||||
if rows > 0 && rows < height {
|
||||
let off1 = rows * width;
|
||||
let off2 = height * width - off1;
|
||||
unsafe {
|
||||
let data_ptr = self.offscreen.as_mut_ptr() as *mut u64;
|
||||
fast_copy64(data_ptr, data_ptr.offset(off1 as isize), off2);
|
||||
fast_set64(data_ptr.offset(off2 as isize), data, off1);
|
||||
let data_ptr = self.offscreen.as_mut_ptr() as *mut u32;
|
||||
fast_copy(data_ptr as *mut u8, data_ptr.offset(off1 as isize) as *const u8, off2 as usize * 4);
|
||||
fast_set32(data_ptr.offset(off2 as isize), color, off1 as usize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Copy from offscreen to onscreen
|
||||
pub fn sync(&mut self, x: usize, y: usize, w: usize, h: usize) {
|
||||
let start_y = cmp::min(self.height - 1, y);
|
||||
let start_y = cmp::min(self.height, y);
|
||||
let end_y = cmp::min(self.height, y + h);
|
||||
|
||||
let start_x = cmp::min(self.width - 1, x);
|
||||
let start_x = cmp::min(self.width, x);
|
||||
let len = (cmp::min(self.width, x + w) - start_x) * 4;
|
||||
|
||||
let mut offscreen_ptr = self.offscreen.as_mut_ptr() as usize;
|
||||
@@ -244,3 +287,9 @@ impl Display {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Display {
|
||||
fn drop(&mut self) {
|
||||
unsafe { heap::deallocate(self.offscreen.as_mut_ptr() as *mut u8, self.offscreen.len() * 4, 4096) };
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -55,8 +55,9 @@ fn main() {
|
||||
let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
|
||||
|
||||
let size = width * height;
|
||||
|
||||
let onscreen = unsafe { physmap(physbaseptr, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
|
||||
//TODO: Remap on resize
|
||||
let largest_size = 8 * 1024 * 1024;
|
||||
let onscreen = unsafe { physmap(physbaseptr, largest_size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
|
||||
unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };
|
||||
|
||||
let mut scheme = DisplayScheme::new(width, height, onscreen, &spec);
|
||||
|
||||
+18
-9
@@ -142,21 +142,30 @@ impl SchemeMut for DisplayScheme {
|
||||
let events = unsafe { slice::from_raw_parts(buf.as_ptr() as *const Event, buf.len()/mem::size_of::<Event>()) };
|
||||
|
||||
for event in events.iter() {
|
||||
let new_active_opt = if let EventOption::Key(key_event) = event.to_option() {
|
||||
match key_event.scancode {
|
||||
let mut new_active_opt = None;
|
||||
match event.to_option() {
|
||||
EventOption::Key(key_event) => match key_event.scancode {
|
||||
f @ 0x3B ... 0x44 => { // F1 through F10
|
||||
Some((f - 0x3A) as usize)
|
||||
new_active_opt = Some((f - 0x3A) as usize);
|
||||
},
|
||||
0x57 => { // F11
|
||||
Some(11)
|
||||
new_active_opt = Some(11);
|
||||
},
|
||||
0x58 => { // F12
|
||||
Some(12)
|
||||
new_active_opt = Some(12);
|
||||
},
|
||||
_ => None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
_ => ()
|
||||
},
|
||||
EventOption::Resize(resize_event) => {
|
||||
println!("Resizing to {}, {}", resize_event.width, resize_event.height);
|
||||
for (screen_id, screen) in self.screens.iter_mut() {
|
||||
screen.resize(resize_event.width as usize, resize_event.height as usize);
|
||||
if *screen_id == self.active {
|
||||
screen.redraw();
|
||||
}
|
||||
}
|
||||
},
|
||||
_ => ()
|
||||
};
|
||||
|
||||
if let Some(new_active) = new_active_opt {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::collections::VecDeque;
|
||||
use std::{cmp, mem, slice};
|
||||
|
||||
use orbclient::Event;
|
||||
use orbclient::{Event, ResizeEvent};
|
||||
use syscall::error::*;
|
||||
use syscall::flag::{SEEK_SET, SEEK_CUR, SEEK_END};
|
||||
|
||||
@@ -36,6 +36,15 @@ impl Screen for GraphicScreen {
|
||||
self.display.height
|
||||
}
|
||||
|
||||
fn resize(&mut self, width: usize, height: usize) {
|
||||
//TODO: Fix issue with mapped screens
|
||||
self.display.resize(width, height);
|
||||
self.input.push_back(ResizeEvent {
|
||||
width: width as u32,
|
||||
height: height as u32,
|
||||
}.to_event());
|
||||
}
|
||||
|
||||
fn event(&mut self, flags: usize) -> Result<usize> {
|
||||
self.requested = flags;
|
||||
Ok(0)
|
||||
|
||||
@@ -12,6 +12,8 @@ pub trait Screen {
|
||||
|
||||
fn height(&self) -> usize;
|
||||
|
||||
fn resize(&mut self, width: usize, height: usize);
|
||||
|
||||
fn event(&mut self, flags: usize) -> Result<usize>;
|
||||
|
||||
fn map(&self, offset: usize, size: usize) -> Result<usize>;
|
||||
|
||||
@@ -43,6 +43,12 @@ impl Screen for TextScreen {
|
||||
self.console.h
|
||||
}
|
||||
|
||||
fn resize(&mut self, width: usize, height: usize) {
|
||||
self.display.resize(width, height);
|
||||
self.console.w = width / 8;
|
||||
self.console.h = height / 16;
|
||||
}
|
||||
|
||||
fn event(&mut self, flags: usize) -> Result<usize> {
|
||||
self.requested = flags;
|
||||
Ok(0)
|
||||
|
||||
Reference in New Issue
Block a user