diff --git a/sys/yellowstone/CMakeLists.txt b/sys/yellowstone/CMakeLists.txt index 9e0b3ae..83a3d24 100644 --- a/sys/yellowstone/CMakeLists.txt +++ b/sys/yellowstone/CMakeLists.txt @@ -1,4 +1,5 @@ add_executable(yellowstone + hw/gpt.cpp hw/pcie.cpp yellowstone.cpp ) diff --git a/sys/yellowstone/hw/gpt.cpp b/sys/yellowstone/hw/gpt.cpp new file mode 100644 index 0000000..6664183 --- /dev/null +++ b/sys/yellowstone/hw/gpt.cpp @@ -0,0 +1,109 @@ +#include "hw/gpt.h" + +#include +#include +#include + +struct MbrPartition { + uint8_t boot_indicator; + uint8_t starting_chs[3]; + uint8_t os_type; + uint8_t ending_chs[3]; + uint32_t starting_lba; + uint32_t ending_lba; +} __attribute__((packed)); + +z_err_t CheckMbrIsGpt(uint64_t mem_cap) { + uint64_t vaddr; + RET_ERR(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr)); + uint16_t* mbr_sig = reinterpret_cast(vaddr + 0x1FE); + if (*mbr_sig != 0xAA55) { + return Z_ERR_INVALID; + } + + MbrPartition* first_partition = + reinterpret_cast(vaddr + 0x1BE); + if (first_partition->boot_indicator != 0) { + dbgln("Boot indicator set: %u", first_partition->boot_indicator); + return Z_ERR_INVALID; + } + if (first_partition->os_type != 0xEE) { + dbgln("Incorrect OS type: %x", first_partition->os_type); + } + dbgln("LBAs: (%x, %x)", first_partition->starting_lba, + first_partition->ending_lba); + return Z_OK; +} + +const uint64_t kGptPartitionSignature = 0x54524150'20494645; +struct ParititionHeader { + uint64_t signature; + uint32_t revision; + uint32_t header_size; + uint32_t crc_32; + uint32_t reserved; + uint64_t lba_self; + uint64_t lba_mirror; + uint64_t lba_min; + uint64_t lba_max; + uint64_t guid_low; + uint64_t guid_high; + uint64_t lba_partition_entries; + uint32_t num_partitions; + uint32_t parition_entry_size; + uint32_t partition_entry_crc32; +} __attribute__((packed)); + +z_err_t ReadPartitionHeader(uint64_t mem_cap) { + uint64_t vaddr; + RET_ERR(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr)); + ParititionHeader* header = reinterpret_cast(vaddr); + + dbgln("signature %lx", header->signature); + + dbgln("lba_partition_entries %lx", header->lba_partition_entries); + dbgln("num_partitions: %x", header->num_partitions); + dbgln("partition_entry_size: %x", header->parition_entry_size); + dbgln("Num blocks: %x", + (header->num_partitions * header->parition_entry_size) / 512); + + dbgln("LBA: (%x, %x)", header->lba_min, header->lba_max); + + return Z_OK; +} + +struct PartitionEntry { + uint64_t type_guid_low; + uint64_t type_guid_high; + uint64_t part_guid_low; + uint64_t part_guid_high; + uint64_t lba_start; + uint64_t lba_end; + uint64_t attributes; + char partition_name[72]; +} __attribute__((packed)); + +z_err_t ReadPartitionEntries(uint64_t mem_cap) { + uint64_t vaddr; + RET_ERR(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr)); + ParititionHeader* header = reinterpret_cast(vaddr); + + // FIXME: Dont hard code these. + uint64_t num_parts = 0x28; + uint64_t entry_size = 0x80; + + dbgln("Entries"); + for (uint64_t i = 0; i < num_parts; i++) { + PartitionEntry* entry = + reinterpret_cast(vaddr + (i * entry_size)); + if (entry->type_guid_low != 0 || entry->type_guid_high != 0) { + dbgln("Entry %u", i); + dbgln("T Guid: %lx-%lx", entry->type_guid_high, entry->type_guid_low); + 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); + } + } + + return Z_OK; +} diff --git a/sys/yellowstone/hw/gpt.h b/sys/yellowstone/hw/gpt.h new file mode 100644 index 0000000..ac2cc31 --- /dev/null +++ b/sys/yellowstone/hw/gpt.h @@ -0,0 +1,10 @@ +#pragma once + +#include +#include + +z_err_t CheckMbrIsGpt(uint64_t mem_cap); + +z_err_t ReadPartitionHeader(uint64_t mem_cap); + +z_err_t ReadPartitionEntries(uint64_t mem_cap); diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index 954321e..e1d8d85 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -5,12 +5,15 @@ #include #include +#include "hw/gpt.h" #include "hw/pcie.h" uint64_t main(uint64_t port_cap) { dbgln("Yellowstone Initializing."); check(ParseInitPort(port_cap)); + DumpPciEDevices(); + uint64_t vaddr; check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr)); @@ -22,21 +25,29 @@ uint64_t main(uint64_t port_cap) { .lba = 0, .size = 1, }; - check(ZChannelSend(local.cap(), sizeof(DenaliRead), - reinterpret_cast(&read), 0, nullptr)); - + check(local.WriteStruct(&read)); DenaliReadResponse resp; - uint64_t mem_cap, bytes, caps; + uint64_t mem_cap; + check(local.ReadStructAndCap(&resp, &mem_cap)); + check(CheckMbrIsGpt(mem_cap)); - check(ZChannelRecv(local.cap(), sizeof(resp), - reinterpret_cast(&resp), 1, &mem_cap, &bytes, - &caps)); + DenaliRead read_lba1{ + .device_id = 0, + .lba = 1, + .size = 1, + }; + check(local.WriteStruct(&read_lba1)); + check(local.ReadStructAndCap(&resp, &mem_cap)); + check(ReadPartitionHeader(mem_cap)); - check(ZAddressSpaceMap(gSelfVmasCap, 0, mem_cap, &vaddr)); - uint32_t* mbr = reinterpret_cast(vaddr + 0x1FE); - dbgln("MBR: %x", *mbr); - - DumpPciEDevices(); + DenaliRead read_parts{ + .device_id = 0, + .lba = 2, + .size = 10, // FIXME: Dont hardcode this. + }; + check(local.WriteStruct(&read_parts)); + check(local.ReadStructAndCap(&resp, &mem_cap)); + check(ReadPartitionEntries(mem_cap)); dbgln("Yellowstone Finished Successfully."); return 0;