[Yellowstone] Allow teton/voyageurs to fully spawn.
This commit is contained in:
parent
bbb44be96e
commit
d58cbed0df
|
@ -3,11 +3,11 @@
|
||||||
|
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::{string::ToString, vec::Vec};
|
||||||
use mammoth::{
|
use mammoth::{
|
||||||
cap::Capability,
|
cap::Capability,
|
||||||
define_entry, elf,
|
define_entry, elf,
|
||||||
init::BOOT_PCI_VMMO,
|
init::{BOOT_FRAMEBUFFER_INFO_VMMO, BOOT_PCI_VMMO},
|
||||||
mem::MemoryRegion,
|
mem::MemoryRegion,
|
||||||
zion::{z_cap_t, z_err_t, ZError},
|
zion::{z_cap_t, z_err_t, ZError},
|
||||||
};
|
};
|
||||||
|
@ -20,9 +20,17 @@ mod server;
|
||||||
|
|
||||||
define_entry!();
|
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> {
|
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))?;
|
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(())
|
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 {
|
extern "C" fn main() -> z_err_t {
|
||||||
let pci_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_PCI_VMMO }))
|
let pci_region = MemoryRegion::from_cap(Capability::take(unsafe { BOOT_PCI_VMMO }))
|
||||||
.expect("Failed to create PCI region");
|
.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(
|
let context = alloc::rc::Rc::new(
|
||||||
server::YellowstoneServerContext::new(pci_region)
|
server::YellowstoneServerContext::new(pci_region, fb_region)
|
||||||
.expect("Failed to create yellowstone context"),
|
.expect("Failed to create yellowstone context"),
|
||||||
);
|
);
|
||||||
let handler = server::YellowstoneServerImpl::new(context.clone());
|
let handler = server::YellowstoneServerImpl::new(context.clone());
|
||||||
|
@ -47,7 +57,7 @@ extern "C" fn main() -> z_err_t {
|
||||||
)
|
)
|
||||||
.expect("Failed to spawn denali");
|
.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.");
|
mammoth::debug!("Denali registered.");
|
||||||
|
|
||||||
spawn_from_vmmo(
|
spawn_from_vmmo(
|
||||||
|
@ -56,7 +66,7 @@ extern "C" fn main() -> z_err_t {
|
||||||
)
|
)
|
||||||
.expect("Failed to spawn victoriafalls");
|
.expect("Failed to spawn victoriafalls");
|
||||||
|
|
||||||
context.wait_victoria_falls().unwrap();
|
context.wait("victoriafalls").unwrap();
|
||||||
mammoth::debug!("VFS Registered");
|
mammoth::debug!("VFS Registered");
|
||||||
|
|
||||||
let file = victoriafalls::file::File::open("/init.txt").unwrap();
|
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);
|
mammoth::debug!("Init files: {:?}", init_files);
|
||||||
|
|
||||||
for bin_name in 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");
|
server_thread.join().expect("Failed to join thread");
|
||||||
|
|
|
@ -18,6 +18,15 @@ impl PciReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_xhci_region(&self) -> Result<Capability, ZError> {
|
||||||
|
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<Capability> {
|
fn probe_pci(&self, pred: DevPredicate) -> Option<Capability> {
|
||||||
let base_header = self.pci_header(0, 0, 0);
|
let base_header = self.pci_header(0, 0, 0);
|
||||||
if (base_header.header_type & 0x80) == 0 {
|
if (base_header.header_type & 0x80) == 0 {
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use core::cell::RefCell;
|
||||||
|
|
||||||
use alloc::rc::Rc;
|
use alloc::rc::Rc;
|
||||||
use alloc::{collections::BTreeMap, string::String};
|
use alloc::{collections::BTreeMap, string::String};
|
||||||
use mammoth::{cap::Capability, mem::MemoryRegion, zion::ZError};
|
use mammoth::{cap::Capability, mem::MemoryRegion, zion::ZError};
|
||||||
|
@ -10,65 +12,90 @@ use yellowstone_yunq::{
|
||||||
use crate::pci::PciReader;
|
use crate::pci::PciReader;
|
||||||
|
|
||||||
pub struct YellowstoneServerContext {
|
pub struct YellowstoneServerContext {
|
||||||
denali_semaphore: mammoth::sync::Semaphore,
|
registration_semaphore: mammoth::sync::Semaphore,
|
||||||
victoria_falls_semaphore: mammoth::sync::Semaphore,
|
|
||||||
pci_reader: PciReader,
|
pci_reader: PciReader,
|
||||||
|
framebuffer_info_region: MemoryRegion,
|
||||||
|
service_map: RefCell<BTreeMap<String, Capability>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YellowstoneServerContext {
|
impl YellowstoneServerContext {
|
||||||
pub fn new(pci_region: MemoryRegion) -> Result<Self, ZError> {
|
fn framebuffer_info(&self) -> yellowstone_yunq::FramebufferInfo {
|
||||||
|
let fb_info: &mammoth::zion::ZFramebufferInfo = unsafe {
|
||||||
|
self.framebuffer_info_region
|
||||||
|
.slice::<u8>()
|
||||||
|
.as_ptr()
|
||||||
|
.cast::<mammoth::zion::ZFramebufferInfo>()
|
||||||
|
.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<Self, ZError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
denali_semaphore: mammoth::sync::Semaphore::new()?,
|
registration_semaphore: mammoth::sync::Semaphore::new()?,
|
||||||
victoria_falls_semaphore: mammoth::sync::Semaphore::new()?,
|
|
||||||
pci_reader: PciReader::new(pci_region),
|
pci_reader: PciReader::new(pci_region),
|
||||||
|
framebuffer_info_region: fb_region,
|
||||||
|
service_map: BTreeMap::new().into(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn wait_denali(&self) -> Result<(), ZError> {
|
pub fn wait(&self, service: &str) -> Result<(), ZError> {
|
||||||
self.denali_semaphore.wait()
|
loop {
|
||||||
}
|
match self.service_map.borrow().get(service) {
|
||||||
|
Some(_) => return Ok(()),
|
||||||
pub fn wait_victoria_falls(&self) -> Result<(), ZError> {
|
None => {}
|
||||||
self.victoria_falls_semaphore.wait()
|
}
|
||||||
|
self.registration_semaphore.wait().unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct YellowstoneServerImpl {
|
pub struct YellowstoneServerImpl {
|
||||||
context: Rc<YellowstoneServerContext>,
|
context: Rc<YellowstoneServerContext>,
|
||||||
service_map: BTreeMap<String, Capability>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YellowstoneServerImpl {
|
impl YellowstoneServerImpl {
|
||||||
pub fn new(context: Rc<YellowstoneServerContext>) -> Self {
|
pub fn new(context: Rc<YellowstoneServerContext>) -> Self {
|
||||||
Self {
|
Self { context }
|
||||||
context,
|
|
||||||
service_map: BTreeMap::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl YellowstoneServerHandler for YellowstoneServerImpl {
|
impl YellowstoneServerHandler for YellowstoneServerImpl {
|
||||||
fn register_endpoint(&mut self, req: RegisterEndpointRequest) -> Result<(), ZError> {
|
fn register_endpoint(&mut self, req: RegisterEndpointRequest) -> Result<(), ZError> {
|
||||||
let signal_denali = req.endpoint_name == "denali";
|
if req.endpoint_name == "victoriafalls" {
|
||||||
let signal_vfs = req.endpoint_name == "victoriafalls";
|
victoriafalls::set_client(VFSClient::new(
|
||||||
|
Capability::take_copy(req.endpoint_capability).unwrap(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
let raw_cap = req.endpoint_capability;
|
self.context
|
||||||
|
.service_map
|
||||||
self.service_map
|
.borrow_mut()
|
||||||
.insert(req.endpoint_name, Capability::take(req.endpoint_capability));
|
.insert(req.endpoint_name, Capability::take(req.endpoint_capability));
|
||||||
|
|
||||||
if signal_denali {
|
self.context.registration_semaphore.signal()?;
|
||||||
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()));
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_endpoint(&mut self, req: GetEndpointRequest) -> Result<Endpoint, ZError> {
|
fn get_endpoint(&mut self, req: GetEndpointRequest) -> Result<Endpoint, ZError> {
|
||||||
match self.service_map.get(&req.endpoint_name) {
|
match self.context.service_map.borrow().get(&req.endpoint_name) {
|
||||||
Some(cap) => Ok(Endpoint {
|
Some(cap) => Ok(Endpoint {
|
||||||
endpoint: cap.duplicate(Capability::PERMS_ALL)?.release(),
|
endpoint: cap.duplicate(Capability::PERMS_ALL)?.release(),
|
||||||
}),
|
}),
|
||||||
|
@ -84,15 +111,18 @@ impl YellowstoneServerHandler for YellowstoneServerImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_xhci_info(&mut self) -> Result<XhciInfo, ZError> {
|
fn get_xhci_info(&mut self) -> Result<XhciInfo, ZError> {
|
||||||
todo!()
|
Ok(XhciInfo {
|
||||||
|
xhci_region: self.context.pci_reader.get_xhci_region()?.release(),
|
||||||
|
region_length: 0x1000,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_framebuffer_info(&mut self) -> Result<FramebufferInfo, ZError> {
|
fn get_framebuffer_info(&mut self) -> Result<FramebufferInfo, ZError> {
|
||||||
todo!()
|
Ok(self.context.framebuffer_info())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_denali(&mut self) -> Result<DenaliInfo, ZError> {
|
fn get_denali(&mut self) -> Result<DenaliInfo, ZError> {
|
||||||
match self.service_map.get("denali") {
|
match self.context.service_map.borrow().get("denali") {
|
||||||
Some(ep_cap) => crate::gpt::read_gpt(denali::DenaliClient::new(
|
Some(ep_cap) => crate::gpt::read_gpt(denali::DenaliClient::new(
|
||||||
ep_cap.duplicate(Capability::PERMS_ALL).unwrap(),
|
ep_cap.duplicate(Capability::PERMS_ALL).unwrap(),
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in New Issue