refactor: apply newtypes throughout userspace API and display types
Every syscall stub now uses proper types from types/ — CapSlot,
EntryPoint, StackPointer, VirtualAddress, PageCount, ProcessId,
PermissionSet, Ticks. The compiler prevents swapping entry/stack,
passing a ProcessId where a CapSlot is expected, or using an
address as a page count.
New display types in types/display.rs:
- Color(u32) with rgb() constructor
- ScreenCoord(u16) for x/y positions
- Dimension(u16) for width/height
Updated throughout:
- userspace/syscall.rs: all params typed, returns Option instead
of sentinel usize::MAX
- server-framework: endpoint param is CapSlot
- port-framebuffer: trait uses Color, ScreenCoord, Dimension
- hw-virtio: DmaAddrs uses PhysicalAddress/VirtualAddress,
GPU commands use Dimension
- All servers, drivers, bins, apps updated for new signatures
- permission-manager: process field uses ProcessId
- PermissionSet: added bits() accessor
89 tests pass, full QEMU boot verified.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
use server_framework::{Decode, Encode};
|
||||
use types::display::{Color, Dimension, ScreenCoord};
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DisplayRequest {
|
||||
DrawRect { x: u16, y: u16, w: u16, h: u16, color: u32 },
|
||||
Clear { color: u32 },
|
||||
DrawRect { x: ScreenCoord, y: ScreenCoord, w: Dimension, h: Dimension, color: Color },
|
||||
Clear { color: Color },
|
||||
Flush,
|
||||
GetDimensions,
|
||||
}
|
||||
@@ -11,7 +12,7 @@ pub enum DisplayRequest {
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum DisplayResponse {
|
||||
Ok,
|
||||
Dimensions { width: u16, height: u16 },
|
||||
Dimensions { width: Dimension, height: Dimension },
|
||||
Error,
|
||||
}
|
||||
|
||||
@@ -19,11 +20,11 @@ impl Encode for DisplayRequest {
|
||||
fn encode(&self) -> [usize; 4] {
|
||||
match self {
|
||||
DisplayRequest::DrawRect { x, y, w, h, color } => {
|
||||
let xy = (*x as usize) | ((*y as usize) << 16);
|
||||
let wh = (*w as usize) | ((*h as usize) << 16);
|
||||
[0, xy, wh, *color as usize]
|
||||
let xy = (x.raw() as usize) | ((y.raw() as usize) << 16);
|
||||
let wh = (w.raw() as usize) | ((h.raw() as usize) << 16);
|
||||
[0, xy, wh, color.raw() as usize]
|
||||
}
|
||||
DisplayRequest::Clear { color } => [1, *color as usize, 0, 0],
|
||||
DisplayRequest::Clear { color } => [1, color.raw() as usize, 0, 0],
|
||||
DisplayRequest::Flush => [2, 0, 0, 0],
|
||||
DisplayRequest::GetDimensions => [3, 0, 0, 0],
|
||||
}
|
||||
@@ -34,14 +35,14 @@ impl Decode for DisplayRequest {
|
||||
fn decode(words: [usize; 4]) -> Option<Self> {
|
||||
match words[0] {
|
||||
0 => {
|
||||
let x = (words[1] & 0xFFFF) as u16;
|
||||
let y = ((words[1] >> 16) & 0xFFFF) as u16;
|
||||
let w = (words[2] & 0xFFFF) as u16;
|
||||
let h = ((words[2] >> 16) & 0xFFFF) as u16;
|
||||
let color = words[3] as u32;
|
||||
let x = ScreenCoord::new((words[1] & 0xFFFF) as u16);
|
||||
let y = ScreenCoord::new(((words[1] >> 16) & 0xFFFF) as u16);
|
||||
let w = Dimension::new((words[2] & 0xFFFF) as u16);
|
||||
let h = Dimension::new(((words[2] >> 16) & 0xFFFF) as u16);
|
||||
let color = Color::from_raw(words[3] as u32);
|
||||
Some(DisplayRequest::DrawRect { x, y, w, h, color })
|
||||
}
|
||||
1 => Some(DisplayRequest::Clear { color: words[1] as u32 }),
|
||||
1 => Some(DisplayRequest::Clear { color: Color::from_raw(words[1] as u32) }),
|
||||
2 => Some(DisplayRequest::Flush),
|
||||
3 => Some(DisplayRequest::GetDimensions),
|
||||
_ => None,
|
||||
@@ -54,7 +55,7 @@ impl Encode for DisplayResponse {
|
||||
match self {
|
||||
DisplayResponse::Ok => [0, 0, 0, 0],
|
||||
DisplayResponse::Dimensions { width, height } => {
|
||||
[1, *width as usize, *height as usize, 0]
|
||||
[1, width.raw() as usize, height.raw() as usize, 0]
|
||||
}
|
||||
DisplayResponse::Error => [2, 0, 0, 0],
|
||||
}
|
||||
@@ -66,8 +67,8 @@ impl Decode for DisplayResponse {
|
||||
match words[0] {
|
||||
0 => Some(DisplayResponse::Ok),
|
||||
1 => Some(DisplayResponse::Dimensions {
|
||||
width: words[1] as u16,
|
||||
height: words[2] as u16,
|
||||
width: Dimension::new(words[1] as u16),
|
||||
height: Dimension::new(words[2] as u16),
|
||||
}),
|
||||
2 => Some(DisplayResponse::Error),
|
||||
_ => None,
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
use crate::protocol::{DisplayRequest, DisplayResponse};
|
||||
use server_framework::{Decode, Encode};
|
||||
use types::display::{Color, Dimension, ScreenCoord};
|
||||
|
||||
#[test]
|
||||
fn draw_rect_roundtrip() {
|
||||
let req = DisplayRequest::DrawRect {
|
||||
x: 10,
|
||||
y: 20,
|
||||
w: 100,
|
||||
h: 50,
|
||||
color: 0xFF0000,
|
||||
x: ScreenCoord::new(10),
|
||||
y: ScreenCoord::new(20),
|
||||
w: Dimension::new(100),
|
||||
h: Dimension::new(50),
|
||||
color: Color::from_raw(0xFF0000),
|
||||
};
|
||||
let words = req.encode();
|
||||
let decoded = DisplayRequest::decode(words).unwrap();
|
||||
@@ -17,7 +18,7 @@ fn draw_rect_roundtrip() {
|
||||
|
||||
#[test]
|
||||
fn clear_roundtrip() {
|
||||
let req = DisplayRequest::Clear { color: 0x00FF00 };
|
||||
let req = DisplayRequest::Clear { color: Color::from_raw(0x00FF00) };
|
||||
let words = req.encode();
|
||||
let decoded = DisplayRequest::decode(words).unwrap();
|
||||
assert_eq!(decoded, req);
|
||||
@@ -40,8 +41,8 @@ fn get_dimensions_roundtrip() {
|
||||
#[test]
|
||||
fn dimensions_response_roundtrip() {
|
||||
let resp = DisplayResponse::Dimensions {
|
||||
width: 320,
|
||||
height: 240,
|
||||
width: Dimension::new(320),
|
||||
height: Dimension::new(240),
|
||||
};
|
||||
let words = resp.encode();
|
||||
let decoded = DisplayResponse::decode(words).unwrap();
|
||||
|
||||
@@ -2,20 +2,21 @@ use driver_framebuffer_mock::MockFramebuffer;
|
||||
use crate::protocol::{DisplayRequest, DisplayResponse};
|
||||
use crate::server::DisplayServer;
|
||||
use server_framework::Server;
|
||||
use types::display::{Color, Dimension, ScreenCoord};
|
||||
|
||||
fn test_server() -> DisplayServer<MockFramebuffer> {
|
||||
DisplayServer::new(MockFramebuffer::new(320, 240))
|
||||
DisplayServer::new(MockFramebuffer::new(Dimension::new(320), Dimension::new(240)))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn draw_rect_writes_pixels() {
|
||||
let mut server = test_server();
|
||||
let resp = server.handle(DisplayRequest::DrawRect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 4,
|
||||
h: 3,
|
||||
color: 0xFF,
|
||||
x: ScreenCoord::new(0),
|
||||
y: ScreenCoord::new(0),
|
||||
w: Dimension::new(4),
|
||||
h: Dimension::new(3),
|
||||
color: Color::from_raw(0xFF),
|
||||
});
|
||||
assert_eq!(resp, DisplayResponse::Ok);
|
||||
assert_eq!(server.framebuffer().pixel_count(), 12);
|
||||
@@ -25,13 +26,13 @@ fn draw_rect_writes_pixels() {
|
||||
fn clear_resets_pixels() {
|
||||
let mut server = test_server();
|
||||
server.handle(DisplayRequest::DrawRect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 10,
|
||||
h: 10,
|
||||
color: 0xFF,
|
||||
x: ScreenCoord::new(0),
|
||||
y: ScreenCoord::new(0),
|
||||
w: Dimension::new(10),
|
||||
h: Dimension::new(10),
|
||||
color: Color::from_raw(0xFF),
|
||||
});
|
||||
server.handle(DisplayRequest::Clear { color: 0 });
|
||||
server.handle(DisplayRequest::Clear { color: Color::from_raw(0) });
|
||||
assert_eq!(server.framebuffer().pixel_count(), 0);
|
||||
}
|
||||
|
||||
@@ -50,8 +51,8 @@ fn get_dimensions_returns_size() {
|
||||
assert_eq!(
|
||||
resp,
|
||||
DisplayResponse::Dimensions {
|
||||
width: 320,
|
||||
height: 240
|
||||
width: Dimension::new(320),
|
||||
height: Dimension::new(240),
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -60,16 +61,16 @@ fn get_dimensions_returns_size() {
|
||||
fn draw_rect_correct_pixel_positions() {
|
||||
let mut server = test_server();
|
||||
server.handle(DisplayRequest::DrawRect {
|
||||
x: 5,
|
||||
y: 10,
|
||||
w: 2,
|
||||
h: 2,
|
||||
color: 0xAB,
|
||||
x: ScreenCoord::new(5),
|
||||
y: ScreenCoord::new(10),
|
||||
w: Dimension::new(2),
|
||||
h: Dimension::new(2),
|
||||
color: Color::from_raw(0xAB),
|
||||
});
|
||||
let fb = server.framebuffer();
|
||||
assert_eq!(fb.pixel_count(), 4);
|
||||
assert_eq!(fb.pixel_at(0), (5, 10, 0xAB));
|
||||
assert_eq!(fb.pixel_at(1), (6, 10, 0xAB));
|
||||
assert_eq!(fb.pixel_at(2), (5, 11, 0xAB));
|
||||
assert_eq!(fb.pixel_at(3), (6, 11, 0xAB));
|
||||
assert_eq!(fb.pixel_at(0), (ScreenCoord::new(5), ScreenCoord::new(10), Color::from_raw(0xAB)));
|
||||
assert_eq!(fb.pixel_at(1), (ScreenCoord::new(6), ScreenCoord::new(10), Color::from_raw(0xAB)));
|
||||
assert_eq!(fb.pixel_at(2), (ScreenCoord::new(5), ScreenCoord::new(11), Color::from_raw(0xAB)));
|
||||
assert_eq!(fb.pixel_at(3), (ScreenCoord::new(6), ScreenCoord::new(11), Color::from_raw(0xAB)));
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ pub fn run() -> ! {
|
||||
let device = adapters::mock::MockInputDevice::new();
|
||||
|
||||
let mut srv = server::InputServer::new(device);
|
||||
server_framework::serve(&mut srv, 0);
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
server_framework::serve(&mut srv, ep);
|
||||
loop { userspace::syscall::yield_now(); }
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ mod tests;
|
||||
|
||||
pub fn run() -> ! {
|
||||
let mut srv = server::LogServer::new();
|
||||
server_framework::serve(&mut srv, 0);
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
server_framework::serve(&mut srv, ep);
|
||||
loop { userspace::syscall::yield_now(); }
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ mod tests;
|
||||
|
||||
pub fn run() -> ! {
|
||||
let mut srv = server::PermissionManager::new();
|
||||
server_framework::serve(&mut srv, 0);
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
server_framework::serve(&mut srv, ep);
|
||||
loop { userspace::syscall::yield_now(); }
|
||||
}
|
||||
|
||||
@@ -46,10 +46,10 @@ impl CapabilityKind {
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
pub enum PermissionRequest {
|
||||
RequestCapability { process: u16, kind: CapabilityKind },
|
||||
RevokeCapability { process: u16, kind: CapabilityKind },
|
||||
CheckCapability { process: u16, kind: CapabilityKind },
|
||||
ListGranted { process: u16 },
|
||||
RequestCapability { process: types::id::ProcessId, kind: CapabilityKind },
|
||||
RevokeCapability { process: types::id::ProcessId, kind: CapabilityKind },
|
||||
CheckCapability { process: types::id::ProcessId, kind: CapabilityKind },
|
||||
ListGranted { process: types::id::ProcessId },
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq)]
|
||||
@@ -66,16 +66,16 @@ impl Encode for PermissionRequest {
|
||||
fn encode(&self) -> [usize; 4] {
|
||||
match self {
|
||||
PermissionRequest::RequestCapability { process, kind } => {
|
||||
[0, *process as usize, kind.index(), 0]
|
||||
[0, process.raw() as usize, kind.index(), 0]
|
||||
}
|
||||
PermissionRequest::RevokeCapability { process, kind } => {
|
||||
[1, *process as usize, kind.index(), 0]
|
||||
[1, process.raw() as usize, kind.index(), 0]
|
||||
}
|
||||
PermissionRequest::CheckCapability { process, kind } => {
|
||||
[2, *process as usize, kind.index(), 0]
|
||||
[2, process.raw() as usize, kind.index(), 0]
|
||||
}
|
||||
PermissionRequest::ListGranted { process } => {
|
||||
[3, *process as usize, 0, 0]
|
||||
[3, process.raw() as usize, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,19 +85,19 @@ impl Decode for PermissionRequest {
|
||||
fn decode(words: [usize; 4]) -> Option<Self> {
|
||||
match words[0] {
|
||||
0 => Some(PermissionRequest::RequestCapability {
|
||||
process: words[1] as u16,
|
||||
process: types::id::ProcessId::from_raw(words[1] as u16),
|
||||
kind: CapabilityKind::from_index(words[2])?,
|
||||
}),
|
||||
1 => Some(PermissionRequest::RevokeCapability {
|
||||
process: words[1] as u16,
|
||||
process: types::id::ProcessId::from_raw(words[1] as u16),
|
||||
kind: CapabilityKind::from_index(words[2])?,
|
||||
}),
|
||||
2 => Some(PermissionRequest::CheckCapability {
|
||||
process: words[1] as u16,
|
||||
process: types::id::ProcessId::from_raw(words[1] as u16),
|
||||
kind: CapabilityKind::from_index(words[2])?,
|
||||
}),
|
||||
3 => Some(PermissionRequest::ListGranted {
|
||||
process: words[1] as u16,
|
||||
process: types::id::ProcessId::from_raw(words[1] as u16),
|
||||
}),
|
||||
_ => None,
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use server_framework::Server;
|
||||
use types::id::ProcessId;
|
||||
|
||||
use crate::protocol::{CapabilityKind, PermissionRequest, PermissionResponse};
|
||||
|
||||
@@ -16,8 +17,8 @@ impl PermissionManager {
|
||||
}
|
||||
}
|
||||
|
||||
fn granted_bits(&self, process: u16) -> u16 {
|
||||
let idx = process as usize;
|
||||
fn granted_bits(&self, process: ProcessId) -> u16 {
|
||||
let idx = process.raw() as usize;
|
||||
if idx >= MAX_PROCESSES {
|
||||
return 0;
|
||||
}
|
||||
@@ -38,7 +39,7 @@ impl Server for PermissionManager {
|
||||
fn handle(&mut self, request: PermissionRequest) -> PermissionResponse {
|
||||
match request {
|
||||
PermissionRequest::RequestCapability { process, kind } => {
|
||||
let idx = process as usize;
|
||||
let idx = process.raw() as usize;
|
||||
if idx >= MAX_PROCESSES {
|
||||
return PermissionResponse::Denied;
|
||||
}
|
||||
@@ -46,7 +47,7 @@ impl Server for PermissionManager {
|
||||
PermissionResponse::Granted
|
||||
}
|
||||
PermissionRequest::RevokeCapability { process, kind } => {
|
||||
let idx = process as usize;
|
||||
let idx = process.raw() as usize;
|
||||
if idx >= MAX_PROCESSES {
|
||||
return PermissionResponse::Denied;
|
||||
}
|
||||
@@ -54,7 +55,7 @@ impl Server for PermissionManager {
|
||||
PermissionResponse::Revoked
|
||||
}
|
||||
PermissionRequest::CheckCapability { process, kind } => {
|
||||
let idx = process as usize;
|
||||
let idx = process.raw() as usize;
|
||||
if idx >= MAX_PROCESSES {
|
||||
return PermissionResponse::HasCapability(false);
|
||||
}
|
||||
|
||||
@@ -1,27 +1,30 @@
|
||||
use crate::protocol::*;
|
||||
use server_framework::{Decode, Encode};
|
||||
use types::id::ProcessId;
|
||||
|
||||
fn pid(v: u16) -> ProcessId { ProcessId::from_raw(v) }
|
||||
|
||||
#[test]
|
||||
fn request_capability_roundtrip() {
|
||||
let req = PermissionRequest::RequestCapability { process: 5, kind: CapabilityKind::Camera };
|
||||
let req = PermissionRequest::RequestCapability { process: pid(5), kind: CapabilityKind::Camera };
|
||||
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn revoke_capability_roundtrip() {
|
||||
let req = PermissionRequest::RevokeCapability { process: 3, kind: CapabilityKind::Network };
|
||||
let req = PermissionRequest::RevokeCapability { process: pid(3), kind: CapabilityKind::Network };
|
||||
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_capability_roundtrip() {
|
||||
let req = PermissionRequest::CheckCapability { process: 1, kind: CapabilityKind::Storage };
|
||||
let req = PermissionRequest::CheckCapability { process: pid(1), kind: CapabilityKind::Storage };
|
||||
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_granted_roundtrip() {
|
||||
let req = PermissionRequest::ListGranted { process: 7 };
|
||||
let req = PermissionRequest::ListGranted { process: pid(7) };
|
||||
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
|
||||
}
|
||||
|
||||
@@ -33,7 +36,7 @@ fn all_kinds_roundtrip() {
|
||||
CapabilityKind::Network, CapabilityKind::Gps, CapabilityKind::Bluetooth,
|
||||
];
|
||||
for kind in kinds {
|
||||
let req = PermissionRequest::RequestCapability { process: 0, kind };
|
||||
let req = PermissionRequest::RequestCapability { process: pid(0), kind };
|
||||
assert_eq!(PermissionRequest::decode(req.encode()), Some(req));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
use crate::protocol::*;
|
||||
use crate::server::PermissionManager;
|
||||
use server_framework::Server;
|
||||
use types::id::ProcessId;
|
||||
|
||||
fn pid(v: u16) -> ProcessId { ProcessId::from_raw(v) }
|
||||
|
||||
#[test]
|
||||
fn new_manager_has_no_grants() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
let resp = mgr.handle(PermissionRequest::CheckCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Camera,
|
||||
});
|
||||
assert_eq!(resp, PermissionResponse::HasCapability(false));
|
||||
@@ -16,11 +19,11 @@ fn new_manager_has_no_grants() {
|
||||
fn grant_then_check() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 1,
|
||||
process: pid(1),
|
||||
kind: CapabilityKind::Network,
|
||||
});
|
||||
let resp = mgr.handle(PermissionRequest::CheckCapability {
|
||||
process: 1,
|
||||
process: pid(1),
|
||||
kind: CapabilityKind::Network,
|
||||
});
|
||||
assert_eq!(resp, PermissionResponse::HasCapability(true));
|
||||
@@ -30,11 +33,11 @@ fn grant_then_check() {
|
||||
fn grant_does_not_affect_other_process() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 1,
|
||||
process: pid(1),
|
||||
kind: CapabilityKind::Camera,
|
||||
});
|
||||
let resp = mgr.handle(PermissionRequest::CheckCapability {
|
||||
process: 2,
|
||||
process: pid(2),
|
||||
kind: CapabilityKind::Camera,
|
||||
});
|
||||
assert_eq!(resp, PermissionResponse::HasCapability(false));
|
||||
@@ -44,15 +47,15 @@ fn grant_does_not_affect_other_process() {
|
||||
fn revoke_removes_grant() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Storage,
|
||||
});
|
||||
mgr.handle(PermissionRequest::RevokeCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Storage,
|
||||
});
|
||||
let resp = mgr.handle(PermissionRequest::CheckCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Storage,
|
||||
});
|
||||
assert_eq!(resp, PermissionResponse::HasCapability(false));
|
||||
@@ -62,15 +65,14 @@ fn revoke_removes_grant() {
|
||||
fn list_granted_returns_bitfield() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Display,
|
||||
});
|
||||
mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 0,
|
||||
process: pid(0),
|
||||
kind: CapabilityKind::Network,
|
||||
});
|
||||
let resp = mgr.handle(PermissionRequest::ListGranted { process: 0 });
|
||||
// Display=bit 0, Network=bit 6 → 0b1000001 = 65
|
||||
let resp = mgr.handle(PermissionRequest::ListGranted { process: pid(0) });
|
||||
assert_eq!(resp, PermissionResponse::GrantedList(0b1000001));
|
||||
}
|
||||
|
||||
@@ -78,7 +80,7 @@ fn list_granted_returns_bitfield() {
|
||||
fn out_of_range_process_denied() {
|
||||
let mut mgr = PermissionManager::new();
|
||||
let resp = mgr.handle(PermissionRequest::RequestCapability {
|
||||
process: 999,
|
||||
process: pid(999),
|
||||
kind: CapabilityKind::Camera,
|
||||
});
|
||||
assert_eq!(resp, PermissionResponse::Denied);
|
||||
|
||||
@@ -8,8 +8,10 @@ pub mod server;
|
||||
mod tests;
|
||||
|
||||
pub fn run() -> ! {
|
||||
let mut srv = server::SessionServer::new(0, 0, 0);
|
||||
let create_cap = types::bounded::CapSlot::new(0).unwrap();
|
||||
let mut srv = server::SessionServer::new(create_cap);
|
||||
srv.register_app("snake", "/apps/snake.elf");
|
||||
server_framework::serve(&mut srv, 0);
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
server_framework::serve(&mut srv, ep);
|
||||
loop { userspace::syscall::yield_now(); }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
use server_framework::Server;
|
||||
use types::bounded::CapSlot;
|
||||
use types::id::ProcessId;
|
||||
|
||||
use crate::protocol::{AppId, SessionRequest, SessionResponse};
|
||||
|
||||
@@ -14,7 +16,7 @@ pub struct AppEntry {
|
||||
#[derive(Clone, Copy)]
|
||||
struct RunningApp {
|
||||
app: AppId,
|
||||
pid: u16,
|
||||
pid: ProcessId,
|
||||
}
|
||||
|
||||
pub struct SessionServer {
|
||||
@@ -22,21 +24,17 @@ pub struct SessionServer {
|
||||
app_count: usize,
|
||||
running: [Option<RunningApp>; MAX_APPS],
|
||||
active: Option<AppId>,
|
||||
create_cap: usize,
|
||||
display_cap: usize,
|
||||
input_cap: usize,
|
||||
create_cap: CapSlot,
|
||||
}
|
||||
|
||||
impl SessionServer {
|
||||
pub fn new(create_cap: usize, display_cap: usize, input_cap: usize) -> Self {
|
||||
pub fn new(create_cap: CapSlot) -> Self {
|
||||
Self {
|
||||
apps: [const { None }; MAX_APPS],
|
||||
app_count: 0,
|
||||
running: [const { None }; MAX_APPS],
|
||||
active: None,
|
||||
create_cap,
|
||||
display_cap,
|
||||
input_cap,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,9 +72,13 @@ impl SessionServer {
|
||||
None => return SessionResponse::NotFound,
|
||||
};
|
||||
|
||||
let pid = userspace::syscall::create_process(self.create_cap);
|
||||
let process_cap = match userspace::syscall::create_process(self.create_cap) {
|
||||
Some(cap) => cap,
|
||||
None => return SessionResponse::Error,
|
||||
};
|
||||
|
||||
self.running[idx] = Some(RunningApp { app, pid: pid as u16 });
|
||||
let pid = ProcessId::from_raw(process_cap.value() as u16);
|
||||
self.running[idx] = Some(RunningApp { app, pid });
|
||||
self.active = Some(app);
|
||||
|
||||
SessionResponse::Launched { app }
|
||||
@@ -85,8 +87,7 @@ impl SessionServer {
|
||||
fn kill_app(&mut self, app: AppId) -> SessionResponse {
|
||||
let idx = app.raw() as usize;
|
||||
match self.running[idx].take() {
|
||||
Some(running) => {
|
||||
let _ = running.pid;
|
||||
Some(_running) => {
|
||||
if self.active == Some(app) {
|
||||
self.active = None;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,8 @@ use crate::server::SessionServer;
|
||||
use server_framework::Server;
|
||||
|
||||
fn test_server() -> SessionServer {
|
||||
let mut s = SessionServer::new(0, 0, 0);
|
||||
let cap = types::bounded::CapSlot::new(0).unwrap();
|
||||
let mut s = SessionServer::new(cap);
|
||||
s.register_app("snake", "/apps/snake.elf");
|
||||
s.register_app("clock", "/apps/clock.elf");
|
||||
s
|
||||
|
||||
@@ -38,7 +38,7 @@ pub fn run() -> ! {
|
||||
let mut fat16 = fat16.unwrap();
|
||||
debug_print(b"storage: FAT16 mounted\n");
|
||||
|
||||
let ep: usize = 0;
|
||||
let ep = types::bounded::CapSlot::new(0).unwrap();
|
||||
|
||||
loop {
|
||||
let (w0, w1, _w2, _w3) = syscall::receive(ep);
|
||||
|
||||
Reference in New Issue
Block a user