2016-09-21 05:52:45 +02:00
|
|
|
#![feature(alloc)]
|
|
|
|
#![feature(asm)]
|
|
|
|
#![feature(heap_api)]
|
|
|
|
|
|
|
|
extern crate alloc;
|
Orbital (#16)
* Port previous ethernet scheme
* Add ipd
* Fix initfs rebuilds, use QEMU user networking addresses in ipd
* Add tcp/udp, netutils, dns, and network config
* Add fsync to network driver
* Add dns, router, subnet by default
* Fix e1000 driver. Make ethernet and IP non-blocking to avoid deadlocks
* Add orbital server, WIP
* Add futex
* Add orbutils and orbital
* Update libstd, orbutils, and orbital
Move ANSI key encoding to vesad
* Add orbital assets
* Update orbital
* Update to add login manager
* Add blocking primitives, block for most things except waitpid, update orbital
* Wait in waitpid and IRQ, improvements for other waits
* Fevent in root scheme
* WIP: Switch to using fevent
* Reorganize
* Event based e1000d driver
* Superuser-only access to some network schemes, display, and disk
* Superuser root and irq schemes
* Fix orbital
2016-10-14 01:21:42 +02:00
|
|
|
extern crate orbclient;
|
2016-09-21 05:52:45 +02:00
|
|
|
extern crate syscall;
|
|
|
|
|
2016-10-15 04:12:21 +02:00
|
|
|
use std::{env, mem, thread};
|
2016-09-21 05:52:45 +02:00
|
|
|
use std::fs::File;
|
2016-09-21 20:18:48 +02:00
|
|
|
use std::io::{Read, Write};
|
2016-10-15 04:12:21 +02:00
|
|
|
use syscall::{physmap, physunmap, Packet, Scheme, EVENT_READ, MAP_WRITE, MAP_WRITE_COMBINE};
|
2016-09-21 05:52:45 +02:00
|
|
|
|
|
|
|
use mode_info::VBEModeInfo;
|
2016-09-22 16:43:22 +02:00
|
|
|
use primitive::fast_set64;
|
2016-10-08 04:18:05 +02:00
|
|
|
use scheme::DisplayScheme;
|
2016-09-21 05:52:45 +02:00
|
|
|
|
|
|
|
pub mod display;
|
|
|
|
pub mod mode_info;
|
|
|
|
pub mod primitive;
|
2016-10-08 04:18:05 +02:00
|
|
|
pub mod scheme;
|
|
|
|
pub mod screen;
|
2016-09-21 20:18:48 +02:00
|
|
|
|
2016-09-21 05:52:45 +02:00
|
|
|
fn main() {
|
2016-10-15 02:22:57 +02:00
|
|
|
let mut spec = Vec::new();
|
|
|
|
|
|
|
|
for arg in env::args().skip(1) {
|
|
|
|
if arg == "T" {
|
|
|
|
spec.push(false);
|
|
|
|
} else if arg == "G" {
|
|
|
|
spec.push(true);
|
|
|
|
} else {
|
|
|
|
println!("vesad: unknown screen type: {}", arg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-21 05:52:45 +02:00
|
|
|
let width;
|
|
|
|
let height;
|
|
|
|
let physbaseptr;
|
|
|
|
|
|
|
|
{
|
|
|
|
let mode_info = unsafe { &*(physmap(0x5200, 4096, 0).expect("vesad: failed to map VBE info") as *const VBEModeInfo) };
|
|
|
|
|
|
|
|
width = mode_info.xresolution as usize;
|
|
|
|
height = mode_info.yresolution as usize;
|
|
|
|
physbaseptr = mode_info.physbaseptr as usize;
|
|
|
|
|
|
|
|
unsafe { let _ = physunmap(mode_info as *const _ as usize); }
|
|
|
|
}
|
|
|
|
|
|
|
|
if physbaseptr > 0 {
|
|
|
|
thread::spawn(move || {
|
2016-09-21 05:56:40 +02:00
|
|
|
let mut socket = File::create(":display").expect("vesad: failed to create display scheme");
|
2016-09-21 20:18:48 +02:00
|
|
|
|
2016-09-21 05:52:45 +02:00
|
|
|
let size = width * height;
|
|
|
|
|
2016-10-08 04:18:05 +02:00
|
|
|
let onscreen = unsafe { physmap(physbaseptr, size * 4, MAP_WRITE | MAP_WRITE_COMBINE).expect("vesad: failed to map VBE LFB") };
|
2016-09-21 05:52:45 +02:00
|
|
|
unsafe { fast_set64(onscreen as *mut u64, 0, size/2) };
|
|
|
|
|
2016-10-15 02:22:57 +02:00
|
|
|
let scheme = DisplayScheme::new(width, height, onscreen, &spec);
|
2016-09-21 05:52:45 +02:00
|
|
|
|
2016-10-08 04:18:05 +02:00
|
|
|
let mut blocked = Vec::new();
|
2016-09-21 20:18:48 +02:00
|
|
|
loop {
|
|
|
|
let mut packet = Packet::default();
|
2016-09-22 16:43:22 +02:00
|
|
|
socket.read(&mut packet).expect("vesad: failed to read display scheme");
|
2016-09-21 20:18:48 +02:00
|
|
|
//println!("vesad: {:?}", packet);
|
2016-09-24 01:54:39 +02:00
|
|
|
|
|
|
|
// If it is a read packet, and there is no data, block it. Otherwise, handle packet
|
2016-10-08 04:18:05 +02:00
|
|
|
if packet.a == syscall::number::SYS_READ && packet.d > 0 && scheme.will_block(packet.b) {
|
|
|
|
blocked.push(packet);
|
2016-09-22 18:10:27 +02:00
|
|
|
} else {
|
|
|
|
scheme.handle(&mut packet);
|
|
|
|
socket.write(&packet).expect("vesad: failed to write display scheme");
|
|
|
|
}
|
2016-09-24 01:54:39 +02:00
|
|
|
|
|
|
|
// If there are blocked readers, and data is available, handle them
|
2016-10-08 04:18:05 +02:00
|
|
|
{
|
|
|
|
let mut i = 0;
|
|
|
|
while i < blocked.len() {
|
|
|
|
if ! scheme.will_block(blocked[i].b) {
|
|
|
|
let mut packet = blocked.remove(i);
|
|
|
|
scheme.handle(&mut packet);
|
|
|
|
socket.write(&packet).expect("vesad: failed to write display scheme");
|
|
|
|
} else {
|
|
|
|
i += 1;
|
|
|
|
}
|
2016-09-22 18:10:27 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-24 01:54:39 +02:00
|
|
|
|
2016-10-15 04:12:21 +02:00
|
|
|
for (screen_id, screen) in scheme.screens.borrow().iter() {
|
|
|
|
if ! screen.will_block() {
|
|
|
|
let event_packet = Packet {
|
|
|
|
id: 0,
|
|
|
|
pid: 0,
|
|
|
|
uid: 0,
|
|
|
|
gid: 0,
|
|
|
|
a: syscall::number::SYS_FEVENT,
|
|
|
|
b: *screen_id,
|
|
|
|
c: EVENT_READ,
|
2016-10-15 06:06:20 +02:00
|
|
|
d: mem::size_of::<orbclient::Event>()
|
2016-10-15 04:12:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
socket.write(&event_packet).expect("vesad: failed to write display event");
|
|
|
|
}
|
2016-09-24 01:54:39 +02:00
|
|
|
}
|
2016-09-21 20:18:48 +02:00
|
|
|
}
|
2016-09-21 05:52:45 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|