From d58cbed0df84a695dacfe51fb346d00db221d51a Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sun, 18 Aug 2024 12:27:16 -0700 Subject: [PATCH] [Yellowstone] Allow teton/voyageurs to fully spawn. --- rust/sys/yellowstone/src/main.rs | 31 +++++++--- rust/sys/yellowstone/src/pci.rs | 9 +++ rust/sys/yellowstone/src/server.rs | 94 ++++++++++++++++++++---------- 3 files changed, 95 insertions(+), 39 deletions(-) diff --git a/rust/sys/yellowstone/src/main.rs b/rust/sys/yellowstone/src/main.rs index 46a6c49..18e386f 100644 --- a/rust/sys/yellowstone/src/main.rs +++ b/rust/sys/yellowstone/src/main.rs @@ -3,11 +3,11 @@ extern crate alloc; -use alloc::vec::Vec; +use alloc::{string::ToString, vec::Vec}; use mammoth::{ cap::Capability, define_entry, elf, - init::BOOT_PCI_VMMO, + init::{BOOT_FRAMEBUFFER_INFO_VMMO, BOOT_PCI_VMMO}, mem::MemoryRegion, zion::{z_cap_t, z_err_t, ZError}, }; @@ -20,9 +20,17 @@ mod server; define_entry!(); +fn spawn_from_mem_region( + mem_region: &mammoth::mem::MemoryRegion, + server_cap: Capability, +) -> Result<(), ZError> { + elf::spawn_process_from_elf_and_init(mem_region.slice(), server_cap)?; + Ok(()) +} + fn spawn_from_vmmo(vmmo_cap: z_cap_t, server_cap: Capability) -> Result<(), ZError> { let region = mammoth::mem::MemoryRegion::from_cap(Capability::take(vmmo_cap))?; - elf::spawn_process_from_elf_and_init(region.slice(), server_cap)?; + spawn_from_mem_region(®ion, server_cap)?; Ok(()) } @@ -30,8 +38,10 @@ fn spawn_from_vmmo(vmmo_cap: z_cap_t, server_cap: Capability) -> Result<(), ZErr extern "C" fn main() -> z_err_t { let pci_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_PCI_VMMO })) .expect("Failed to create PCI region"); + let fb_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_FRAMEBUFFER_INFO_VMMO })) + .expect("Failed to create Framebuffer region"); let context = alloc::rc::Rc::new( - server::YellowstoneServerContext::new(pci_region) + server::YellowstoneServerContext::new(pci_region, fb_region) .expect("Failed to create yellowstone context"), ); let handler = server::YellowstoneServerImpl::new(context.clone()); @@ -47,7 +57,7 @@ extern "C" fn main() -> z_err_t { ) .expect("Failed to spawn denali"); - context.wait_denali().expect("Failed to wait for denali"); + context.wait("denali").expect("Failed to wait for denali"); mammoth::debug!("Denali registered."); spawn_from_vmmo( @@ -56,7 +66,7 @@ extern "C" fn main() -> z_err_t { ) .expect("Failed to spawn victoriafalls"); - context.wait_victoria_falls().unwrap(); + context.wait("victoriafalls").unwrap(); mammoth::debug!("VFS Registered"); let file = victoriafalls::file::File::open("/init.txt").unwrap(); @@ -70,7 +80,14 @@ extern "C" fn main() -> z_err_t { mammoth::debug!("Init files: {:?}", init_files); for bin_name in init_files { - let path = "/bin/" + bin_name; + // FIXME implement dependencies. + if bin_name == "teton" { + context.wait("voyageurs").unwrap(); + } + let path = "/bin/".to_string() + bin_name; + + let bin_file = victoriafalls::file::File::open(&path).unwrap(); + spawn_from_mem_region(bin_file.memory(), server.create_client_cap().unwrap()).unwrap(); } server_thread.join().expect("Failed to join thread"); diff --git a/rust/sys/yellowstone/src/pci.rs b/rust/sys/yellowstone/src/pci.rs index b7b4116..e421f74 100644 --- a/rust/sys/yellowstone/src/pci.rs +++ b/rust/sys/yellowstone/src/pci.rs @@ -18,6 +18,15 @@ impl PciReader { } } + pub fn get_xhci_region(&self) -> Result { + match self.probe_pci(|class, subclass, prog_interface| { + class == 0xC && subclass == 0x3 && prog_interface == 0x30 + }) { + Some(m) => Ok(m), + None => Err(ZError::NOT_FOUND), + } + } + fn probe_pci(&self, pred: DevPredicate) -> Option { let base_header = self.pci_header(0, 0, 0); if (base_header.header_type & 0x80) == 0 { diff --git a/rust/sys/yellowstone/src/server.rs b/rust/sys/yellowstone/src/server.rs index ef33146..5a8ce9c 100644 --- a/rust/sys/yellowstone/src/server.rs +++ b/rust/sys/yellowstone/src/server.rs @@ -1,3 +1,5 @@ +use core::cell::RefCell; + use alloc::rc::Rc; use alloc::{collections::BTreeMap, string::String}; use mammoth::{cap::Capability, mem::MemoryRegion, zion::ZError}; @@ -10,65 +12,90 @@ use yellowstone_yunq::{ use crate::pci::PciReader; pub struct YellowstoneServerContext { - denali_semaphore: mammoth::sync::Semaphore, - victoria_falls_semaphore: mammoth::sync::Semaphore, + registration_semaphore: mammoth::sync::Semaphore, pci_reader: PciReader, + framebuffer_info_region: MemoryRegion, + service_map: RefCell>, } impl YellowstoneServerContext { - pub fn new(pci_region: MemoryRegion) -> Result { + fn framebuffer_info(&self) -> yellowstone_yunq::FramebufferInfo { + let fb_info: &mammoth::zion::ZFramebufferInfo = unsafe { + self.framebuffer_info_region + .slice::() + .as_ptr() + .cast::() + .as_ref() + .unwrap() + }; + + yellowstone_yunq::FramebufferInfo { + address_phys: fb_info.address_phys, + width: fb_info.width, + height: fb_info.height, + pitch: fb_info.pitch, + bpp: fb_info.bpp as u64, + memory_model: fb_info.memory_model as u64, + red_mask_size: fb_info.red_mask_size as u64, + red_mask_shift: fb_info.red_mask_shift as u64, + blue_mask_size: fb_info.blue_mask_size as u64, + blue_mask_shift: fb_info.blue_mask_shift as u64, + green_mask_size: fb_info.green_mask_size as u64, + green_mask_shift: fb_info.green_mask_shift as u64, + } + } +} + +impl YellowstoneServerContext { + pub fn new(pci_region: MemoryRegion, fb_region: MemoryRegion) -> Result { Ok(Self { - denali_semaphore: mammoth::sync::Semaphore::new()?, - victoria_falls_semaphore: mammoth::sync::Semaphore::new()?, + registration_semaphore: mammoth::sync::Semaphore::new()?, pci_reader: PciReader::new(pci_region), + framebuffer_info_region: fb_region, + service_map: BTreeMap::new().into(), }) } - pub fn wait_denali(&self) -> Result<(), ZError> { - self.denali_semaphore.wait() - } - - pub fn wait_victoria_falls(&self) -> Result<(), ZError> { - self.victoria_falls_semaphore.wait() + pub fn wait(&self, service: &str) -> Result<(), ZError> { + loop { + match self.service_map.borrow().get(service) { + Some(_) => return Ok(()), + None => {} + } + self.registration_semaphore.wait().unwrap(); + } } } pub struct YellowstoneServerImpl { context: Rc, - service_map: BTreeMap, } impl YellowstoneServerImpl { pub fn new(context: Rc) -> Self { - Self { - context, - service_map: BTreeMap::new(), - } + Self { context } } } impl YellowstoneServerHandler for YellowstoneServerImpl { fn register_endpoint(&mut self, req: RegisterEndpointRequest) -> Result<(), ZError> { - let signal_denali = req.endpoint_name == "denali"; - let signal_vfs = req.endpoint_name == "victoriafalls"; + if req.endpoint_name == "victoriafalls" { + victoriafalls::set_client(VFSClient::new( + Capability::take_copy(req.endpoint_capability).unwrap(), + )); + } - let raw_cap = req.endpoint_capability; - - self.service_map + self.context + .service_map + .borrow_mut() .insert(req.endpoint_name, Capability::take(req.endpoint_capability)); - if signal_denali { - self.context.denali_semaphore.signal()?; - } - if signal_vfs { - self.context.victoria_falls_semaphore.signal()?; - victoriafalls::set_client(VFSClient::new(Capability::take_copy(raw_cap).unwrap())); - } + self.context.registration_semaphore.signal()?; Ok(()) } fn get_endpoint(&mut self, req: GetEndpointRequest) -> Result { - match self.service_map.get(&req.endpoint_name) { + match self.context.service_map.borrow().get(&req.endpoint_name) { Some(cap) => Ok(Endpoint { endpoint: cap.duplicate(Capability::PERMS_ALL)?.release(), }), @@ -84,15 +111,18 @@ impl YellowstoneServerHandler for YellowstoneServerImpl { } fn get_xhci_info(&mut self) -> Result { - todo!() + Ok(XhciInfo { + xhci_region: self.context.pci_reader.get_xhci_region()?.release(), + region_length: 0x1000, + }) } fn get_framebuffer_info(&mut self) -> Result { - todo!() + Ok(self.context.framebuffer_info()) } fn get_denali(&mut self) -> Result { - match self.service_map.get("denali") { + match self.context.service_map.borrow().get("denali") { Some(ep_cap) => crate::gpt::read_gpt(denali::DenaliClient::new( ep_cap.duplicate(Capability::PERMS_ALL).unwrap(), ))