Commit 59b57900 authored by Jeremy Soller's avatar Jeremy Soller

Merge branch 'alx'

parents 21991855 0b94ce28
[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"
This diff is collapsed.
This diff is collapsed.
#![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); }
}
}
......@@ -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()));
}
}
......@@ -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();
......
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);
}
}
\ No newline at end of file
......@@ -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,
......
......@@ -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) };
}
}
......@@ -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);
......
......@@ -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 {
......
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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment