From adfffdd3c3bc1a07c57afe22763495543f498356 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Wed, 25 Oct 2023 19:08:00 -0700 Subject: [PATCH] [Yellowstone] Use mutex to wait for denali to spawn VFS. Kind of a hacky way to pass a signal between threads but works as a POC for thread synchronization. --- sys/yellowstone/yellowstone.cpp | 17 +++++++++++---- sys/yellowstone/yellowstone_server.cpp | 29 +++++++++++++++----------- sys/yellowstone/yellowstone_server.h | 7 ++++++- 3 files changed, 36 insertions(+), 17 deletions(-) diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index 5a2f34e..4b35ef2 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -8,6 +8,12 @@ #include "hw/pcie.h" #include "yellowstone_server.h" +glcr::ErrorCode SpawnProcess(z_cap_t vmmo_cap, z_cap_t yellowstone_cap) { + uint64_t vaddr; + RET_ERR(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr)); + return SpawnProcessFromElfRegion(vaddr, yellowstone_cap); +} + uint64_t main(uint64_t port_cap) { dbgln("Yellowstone Initializing."); check(ParseInitPort(port_cap)); @@ -15,10 +21,13 @@ uint64_t main(uint64_t port_cap) { ASSIGN_OR_RETURN(auto server, YellowstoneServer::Create()); Thread server_thread = server->RunServer(); - uint64_t vaddr; - check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr)); - ASSIGN_OR_RETURN(YellowstoneClient client, server->CreateClient()); - check(SpawnProcessFromElfRegion(vaddr, client.Capability())); + ASSIGN_OR_RETURN(YellowstoneClient client1, server->CreateClient()); + check(SpawnProcess(gBootDenaliVmmoCap, client1.Capability())); + + check(server->WaitDenaliRegistered()); + + ASSIGN_OR_RETURN(YellowstoneClient client2, server->CreateClient()); + check(SpawnProcess(gBootVictoriaFallsVmmoCap, client2.Capability())); check(server_thread.Join()); dbgln("Yellowstone Finished Successfully."); diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index aa37405..94db660 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -30,13 +30,19 @@ glcr::ErrorOr HandleDenaliRegistration(z_cap_t endpoint_cap) { } // namespace glcr::ErrorOr> YellowstoneServer::Create() { - z_cap_t cap; - RET_ERR(ZEndpointCreate(&cap)); - return glcr::UniquePtr(new YellowstoneServer(cap)); + z_cap_t endpoint_cap; + RET_ERR(ZEndpointCreate(&endpoint_cap)); + + ASSIGN_OR_RETURN(Mutex mut, Mutex::Create()); + RET_ERR(mut.Lock()); + + return glcr::UniquePtr( + new YellowstoneServer(endpoint_cap, glcr::Move(mut))); } -YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap) - : YellowstoneServerBase(endpoint_cap) {} +YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, Mutex&& mutex) + : YellowstoneServerBase(endpoint_cap), + has_denali_mutex_(glcr::Move(mutex)) {} glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, AhciInfo& info) { @@ -69,13 +75,7 @@ glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint( device_id_ = part_info_or.value().device_id; lba_offset_ = part_info_or.value().partition_lba; - uint64_t vaddr; - check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr)); - auto client_or = CreateClient(); - if (!client_or.ok()) { - check(client_or.error()); - } - check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability())); + check(has_denali_mutex_.Release()); } else if (req.endpoint_name() == "victoriafalls") { victoria_falls_cap_ = req.endpoint_capability(); } else { @@ -83,3 +83,8 @@ glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint( } return glcr::OK; } + +glcr::ErrorCode YellowstoneServer::WaitDenaliRegistered() { + RET_ERR(has_denali_mutex_.Lock()); + return has_denali_mutex_.Release(); +} diff --git a/sys/yellowstone/yellowstone_server.h b/sys/yellowstone/yellowstone_server.h index c037f76..6708de3 100644 --- a/sys/yellowstone/yellowstone_server.h +++ b/sys/yellowstone/yellowstone_server.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -18,6 +19,8 @@ class YellowstoneServer : public YellowstoneServerBase { glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, Empty&) override; + glcr::ErrorCode WaitDenaliRegistered(); + private: // TODO: Store these in a data structure. z_cap_t denali_cap_ = 0; @@ -27,5 +30,7 @@ class YellowstoneServer : public YellowstoneServerBase { PciReader pci_reader_; - YellowstoneServer(z_cap_t endpoint_cap); + Mutex has_denali_mutex_; + + YellowstoneServer(z_cap_t endpoint_cap, Mutex&& mutex); };