diff --git a/sys/denali/include/denali/denali_client.h b/sys/denali/include/denali/denali_client.h index 9622861..0b4386f 100644 --- a/sys/denali/include/denali/denali_client.h +++ b/sys/denali/include/denali/denali_client.h @@ -16,3 +16,22 @@ class DenaliClient { private: glcr::UniquePtr endpoint_; }; + +class ScopedDenaliClient : protected DenaliClient { + public: + ScopedDenaliClient(glcr::UniquePtr endpoint, + uint64_t device_id, uint64_t lba_offset) + : DenaliClient(glcr::Move(endpoint)), + device_id_(device_id), + lba_offset_(lba_offset) {} + + glcr::ErrorOr ReadSectors(uint64_t lba, + uint64_t num_sectors) { + return DenaliClient::ReadSectors(device_id_, lba_offset_ + lba, + num_sectors); + } + + private: + uint64_t device_id_; + uint64_t lba_offset_; +}; diff --git a/sys/yellowstone/CMakeLists.txt b/sys/yellowstone/CMakeLists.txt index ac35d6c..94031ff 100644 --- a/sys/yellowstone/CMakeLists.txt +++ b/sys/yellowstone/CMakeLists.txt @@ -29,6 +29,7 @@ target_include_directories(yellowstone_stub PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") target_link_libraries(yellowstone_stub + denali_stub mammoth ) diff --git a/sys/yellowstone/hw/gpt.cpp b/sys/yellowstone/hw/gpt.cpp index b94e511..3b98811 100644 --- a/sys/yellowstone/hw/gpt.cpp +++ b/sys/yellowstone/hw/gpt.cpp @@ -9,6 +9,9 @@ const uint64_t kSectorSize = 512; const uint64_t kGptPartitionSignature = 0x54524150'20494645; +const uint64_t kLfsDataLow = 0x477284830fc63daf; +const uint64_t kLfsDataHigh = 0xe47d47d8693d798e; + struct MbrPartition { uint8_t boot_indicator; uint8_t starting_chs[3]; @@ -99,6 +102,13 @@ glcr::ErrorCode GptReader::ParsePartitionTables() { dbgln("P Guid: %lx-%lx", entry->part_guid_high, entry->part_guid_low); dbgln("LBA: %lx, %lx", entry->lba_start, entry->lba_end); dbgln("Attrs: %lx", entry->attributes); + // For now we hardcode these values to the type that is created in our + // setup script. + // FIXME: Set up our own root partition type guid at some point. + if (entry->type_guid_low == kLfsDataLow && + entry->type_guid_high == kLfsDataHigh) { + primary_partition_lba_ = entry->lba_start; + } } } diff --git a/sys/yellowstone/hw/gpt.h b/sys/yellowstone/hw/gpt.h index 94d98fa..1a845ad 100644 --- a/sys/yellowstone/hw/gpt.h +++ b/sys/yellowstone/hw/gpt.h @@ -10,6 +10,9 @@ class GptReader { glcr::ErrorCode ParsePartitionTables(); + uint64_t GetPrimaryPartitionLba() { return primary_partition_lba_; } + private: glcr::UniquePtr denali_; + uint64_t primary_partition_lba_; }; diff --git a/sys/yellowstone/include/yellowstone.h b/sys/yellowstone/include/yellowstone.h index 6954ab5..5ea6c62 100644 --- a/sys/yellowstone/include/yellowstone.h +++ b/sys/yellowstone/include/yellowstone.h @@ -4,6 +4,7 @@ const uint64_t kYellowstoneGetRegistration = 0x01; const uint64_t kYellowstoneGetAhci = 0x02; +const uint64_t kYellowstoneGetDenali = 0x03; struct YellowstoneGetReq { uint64_t type; @@ -14,3 +15,10 @@ struct YellowstoneGetAhciResp { uint64_t type; uint64_t ahci_phys_offset; }; + +// Has a denali cap attached. +struct YellowstoneGetDenaliResp { + uint64_t type; + uint64_t device_id; + uint64_t lba_offset; +}; diff --git a/sys/yellowstone/include/yellowstone_stub.h b/sys/yellowstone/include/yellowstone_stub.h index 9199bc0..71e4ff4 100644 --- a/sys/yellowstone/include/yellowstone_stub.h +++ b/sys/yellowstone/include/yellowstone_stub.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include #include @@ -10,6 +11,7 @@ class YellowstoneStub { explicit YellowstoneStub(z_cap_t yellowstone_cap); glcr::ErrorOr GetAhciConfig(); + glcr::ErrorOr GetDenali(); [[nodiscard]] glcr::ErrorCode Register(glcr::String name, const EndpointClient& client); diff --git a/sys/yellowstone/stub/yellowstone_stub.cpp b/sys/yellowstone/stub/yellowstone_stub.cpp index 993b73b..9cec8c5 100644 --- a/sys/yellowstone/stub/yellowstone_stub.cpp +++ b/sys/yellowstone/stub/yellowstone_stub.cpp @@ -1,5 +1,7 @@ #include "include/yellowstone_stub.h" +#include + #include "include/yellowstone.h" namespace { @@ -22,6 +24,19 @@ glcr::ErrorOr YellowstoneStub::GetAhciConfig() { return MappedMemoryRegion::DirectPhysical(resp.ahci_phys_offset, kPciSize); } +glcr::ErrorOr YellowstoneStub::GetDenali() { + YellowstoneGetReq req{ + .type = kYellowstoneGetDenali, + }; + ASSIGN_OR_RETURN( + auto resp_and_cap, + (yellowstone_stub_->CallEndpointGetCap(req))); + return ScopedDenaliClient( + EndpointClient::AdoptEndpoint(resp_and_cap.second()), 0, + resp_and_cap.first().lba_offset); +} + glcr::ErrorCode YellowstoneStub::Register(glcr::String name, const EndpointClient& client) { if (register_port_.empty()) { diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index ec81d97..6d3a3fe 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -22,10 +22,6 @@ uint64_t main(uint64_t port_cap) { server->GetServerClient()); check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client))); - check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootVictoriaFallsVmmoCap, &vaddr)); - ASSIGN_OR_RETURN(client, server->GetServerClient()); - check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client))); - check(server_thread.Join()); check(registration_thread.Join()); dbgln("Yellowstone Finished Successfully."); diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index 28bb8c8..fec3d46 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include "hw/gpt.h" @@ -20,11 +22,19 @@ void RegistrationThreadBootstrap(void* yellowstone) { static_cast(yellowstone)->RegistrationThread(); } -glcr::ErrorCode HandleDenaliRegistration(z_cap_t endpoint_cap) { +struct PartitionInfo { + uint64_t device_id; + uint64_t partition_lba; +}; + +glcr::ErrorOr HandleDenaliRegistration(z_cap_t endpoint_cap) { GptReader reader(glcr::UniquePtr( new DenaliClient(EndpointClient::AdoptEndpoint(endpoint_cap)))); - return reader.ParsePartitionTables(); + RET_ERR(reader.ParsePartitionTables()); + + return PartitionInfo{.device_id = 0, + .partition_lba = reader.GetPrimaryPartitionLba()}; } } // namespace @@ -77,6 +87,18 @@ void YellowstoneServer::ServerThread() { check(ZReplyPortSend(reply_port_cap, sizeof(resp), &resp, 1, ®_cap)); break; } + case kYellowstoneGetDenali: { + dbgln("Yellowstone::GetDenali"); + z_cap_t new_denali; + check(ZCapDuplicate(denali_cap_, &new_denali)); + YellowstoneGetDenaliResp resp{ + .type = kYellowstoneGetDenali, + .device_id = device_id_, + .lba_offset = lba_offset_, + }; + check(ZReplyPortSend(reply_port_cap, sizeof(resp), &resp, 1, + &new_denali)); + } default: dbgln("Unknown request type: %x", req->type); break; @@ -94,7 +116,21 @@ void YellowstoneServer::RegistrationThread() { glcr::String name(registration_buffer_); if (name == "denali") { denali_cap_ = endpoint_cap; - check(HandleDenaliRegistration(denali_cap_)); + auto part_info_or = HandleDenaliRegistration(denali_cap_); + if (!part_info_or.ok()) { + check(part_info_or.error()); + } + 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 = GetServerClient(); + if (!client_or.ok()) { + check(client_or.error()); + } + check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client_or.value()))); continue; } diff --git a/sys/yellowstone/yellowstone_server.h b/sys/yellowstone/yellowstone_server.h index dae944c..609f238 100644 --- a/sys/yellowstone/yellowstone_server.h +++ b/sys/yellowstone/yellowstone_server.h @@ -30,6 +30,8 @@ class YellowstoneServer { // TODO: Store these in a data structure. z_cap_t denali_cap_ = 0; + uint64_t device_id_ = 0; + uint64_t lba_offset_ = 0; z_cap_t victoria_falls_cap_ = 0; PciReader pci_reader_;