diff --git a/lib/glacier/container/binary_tree.h b/lib/glacier/container/binary_tree.h index b6beaa9..e3dfb08 100644 --- a/lib/glacier/container/binary_tree.h +++ b/lib/glacier/container/binary_tree.h @@ -7,6 +7,7 @@ #include "glacier/memory/ref_ptr.h" #include "glacier/memory/reference.h" #include "glacier/memory/unique_ptr.h" +#include "glacier/string/str_format.h" namespace glcr { @@ -26,6 +27,8 @@ class BinaryTree { Optional> Find(K key); + void DebugTreeIntoStr(StringBuilder& builder) const; + private: // TODO: Consider adding a sharedptr type to // avoid making this "RefCounted". @@ -45,6 +48,9 @@ class BinaryTree { // If this node exists, return it. Otherwise, this // will be the parent of where this node would be inserted. RefPtr FindOrInsertionParent(K key); + + static void DebugNodeIntoString(StringBuilder& builder, uint64_t indent_level, + const RefPtr& node); }; template @@ -102,6 +108,9 @@ void BinaryTree::Delete(K key) { node->parent->left = new_child; } } + if (new_child) { + new_child->parent = node->parent; + } } template @@ -211,4 +220,36 @@ BinaryTree::FindOrInsertionParent(K key) { } } +template +void StrFormatValue(StringBuilder& builder, const BinaryTree& value, + StringView opts) { + value.DebugTreeIntoStr(builder); +} + +template +void BinaryTree::DebugTreeIntoStr(StringBuilder& builder) const { + DebugNodeIntoString(builder, 0, root_); +} + +template +void BinaryTree::DebugNodeIntoString(StringBuilder& builder, + uint64_t indent_level, + const RefPtr& node) { + if (node.empty()) { + return; + } + for (uint64_t i = 0; i < indent_level; i++) { + builder.PushBack('\t'); + } + StrFormatValue(builder, node->value, ""); + builder.PushBack('\n'); + if (node->left) { + builder.PushBack('L'); + DebugNodeIntoString(builder, indent_level + 1, node->left); + } + if (node->right) { + builder.PushBack('R'); + DebugNodeIntoString(builder, indent_level + 1, node->right); + } +} } // namespace glcr diff --git a/lib/glacier/memory/ref_counted.h b/lib/glacier/memory/ref_counted.h index a141de4..4ac3653 100644 --- a/lib/glacier/memory/ref_counted.h +++ b/lib/glacier/memory/ref_counted.h @@ -11,10 +11,12 @@ class RefCounted { virtual ~RefCounted() {} // FIXME: Rethink error handling in these cases now that we can't panic the // kernel. - void Adopt() { ref_count_ = 1; } + void AdoptPtr() { ref_count_ = 1; } - void Acquire() { ref_count_++; } - bool Release() { return (--ref_count_) == 0; } + void AcquirePtr() { ref_count_++; } + bool ReleasePtr() { return (--ref_count_) == 0; } + + uint64_t ref_count() { return ref_count_; } private: // FIXME: This should be an atomic type. diff --git a/lib/glacier/memory/ref_ptr.h b/lib/glacier/memory/ref_ptr.h index 2ed2ceb..c4dbdb2 100644 --- a/lib/glacier/memory/ref_ptr.h +++ b/lib/glacier/memory/ref_ptr.h @@ -18,16 +18,16 @@ class RefPtr { RefPtr(decltype(nullptr)) : ptr_(nullptr) {} RefPtr(const RefPtr& other) : ptr_(other.ptr_) { if (ptr_) { - ptr_->Acquire(); + ptr_->AcquirePtr(); } } RefPtr& operator=(const RefPtr& other) { T* old = ptr_; ptr_ = other.ptr_; if (ptr_) { - ptr_->Acquire(); + ptr_->AcquirePtr(); } - if (old && old->Release()) { + if (old && old->ReleasePtr()) { delete old; } @@ -46,7 +46,15 @@ class RefPtr { enum DontAdoptTag { DontAdopt, }; - RefPtr(T* ptr, DontAdoptTag) : ptr_(ptr) { ptr->Acquire(); } + RefPtr(T* ptr, DontAdoptTag) : ptr_(ptr) { ptr->AcquirePtr(); } + + ~RefPtr() { + if (ptr_) { + if (ptr_->ReleasePtr()) { + delete ptr_; + } + } + } T* get() const { return ptr_; }; T& operator*() const { return *ptr_; } @@ -65,7 +73,7 @@ class RefPtr { T* ptr_; friend RefPtr AdoptPtr(T* ptr); - RefPtr(T* ptr) : ptr_(ptr) { ptr->Adopt(); } + RefPtr(T* ptr) : ptr_(ptr) { ptr->AdoptPtr(); } }; template diff --git a/lib/glacier/string/str_format.cpp b/lib/glacier/string/str_format.cpp index afdff66..d06fbf8 100644 --- a/lib/glacier/string/str_format.cpp +++ b/lib/glacier/string/str_format.cpp @@ -20,27 +20,32 @@ void StrFormatNumber(StringBuilder& builder, uint64_t value, uint64_t base) { } // namespace template <> -void StrFormatValue(StringBuilder& builder, uint8_t value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const uint8_t& value, + StringView opts) { StrFormatValue(builder, static_cast(value), opts); } template <> -void StrFormatValue(StringBuilder& builder, uint16_t value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const uint16_t& value, + StringView opts) { StrFormatValue(builder, static_cast(value), opts); } template <> -void StrFormatValue(StringBuilder& builder, int32_t value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const int32_t& value, + StringView opts) { StrFormatValue(builder, static_cast(value), opts); } template <> -void StrFormatValue(StringBuilder& builder, uint32_t value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const uint32_t& value, + StringView opts) { StrFormatValue(builder, static_cast(value), opts); } template <> -void StrFormatValue(StringBuilder& builder, uint64_t value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const uint64_t& value, + StringView opts) { if (opts.find('x') != opts.npos) { builder.PushBack("0x"); StrFormatNumber(builder, value, 16); @@ -50,23 +55,26 @@ void StrFormatValue(StringBuilder& builder, uint64_t value, StringView opts) { } template <> -void StrFormatValue(StringBuilder& builder, ErrorCode value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const ErrorCode& value, + StringView opts) { StrFormatValue(builder, static_cast(value), opts); } template <> -void StrFormatValue(StringBuilder& builder, char value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const char& value, + StringView opts) { builder.PushBack(value); } template <> -void StrFormatValue(StringBuilder& builder, const char* value, +void StrFormatValue(StringBuilder& builder, char const* const& value, StringView opts) { - StrFormatValue(builder, StringView(value), opts); + StrFormatInternal(builder, StringView(value)); } template <> -void StrFormatValue(StringBuilder& builder, StringView value, StringView opts) { +void StrFormatValue(StringBuilder& builder, const StringView& value, + StringView opts) { StrFormatInternal(builder, value); } diff --git a/lib/glacier/string/str_format.h b/lib/glacier/string/str_format.h index 3f13ec4..1d0c907 100644 --- a/lib/glacier/string/str_format.h +++ b/lib/glacier/string/str_format.h @@ -7,41 +7,51 @@ namespace glcr { +// FIXME: We need some meta-programming here to allow pass-by-value for pointers +// and primitives. template -void StrFormatValue(StringBuilder& builder, T value, StringView opts); +void StrFormatValue(StringBuilder& builder, const T& value, StringView opts); template <> -void StrFormatValue(StringBuilder& builder, uint8_t value, StringView opts); +void StrFormatValue(StringBuilder& builder, const uint8_t& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, uint16_t value, StringView opts); +void StrFormatValue(StringBuilder& builder, const uint16_t& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, int32_t value, StringView opts); +void StrFormatValue(StringBuilder& builder, const int32_t& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, uint32_t value, StringView opts); +void StrFormatValue(StringBuilder& builder, const uint32_t& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, uint64_t value, StringView opts); +void StrFormatValue(StringBuilder& builder, const uint64_t& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, ErrorCode value, StringView opts); +void StrFormatValue(StringBuilder& builder, const ErrorCode& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, char value, StringView opts); +void StrFormatValue(StringBuilder& builder, const char& value, StringView opts); template <> -void StrFormatValue(StringBuilder& builder, const char* value, StringView opts); +void StrFormatValue(StringBuilder& builder, char const* const& value, + StringView opts); template <> -void StrFormatValue(StringBuilder& builder, StringView value, StringView opts); +void StrFormatValue(StringBuilder& builder, const StringView& value, + StringView opts); void StrFormatInternal(StringBuilder& builder, StringView format); template -void StrFormatInternal(StringBuilder& builder, StringView format, T value, - Args... args) { +void StrFormatInternal(StringBuilder& builder, StringView format, + const T& value, Args&&... args) { uint64_t posl = format.find('{'); uint64_t posr = format.find('}', posl); if (posl == format.npos || posr == format.npos) { @@ -56,7 +66,7 @@ void StrFormatInternal(StringBuilder& builder, StringView format, T value, } template -String StrFormat(StringView format, Args... args) { +String StrFormat(StringView format, Args&&... args) { VariableStringBuilder builder; StrFormatInternal(builder, format, args...); return builder.ToString(); @@ -64,7 +74,7 @@ String StrFormat(StringView format, Args... args) { template void StrFormatIntoBuffer(StringBuilder& builder, StringView format, - Args... args) { + Args&&... args) { StrFormatInternal(builder, format, args...); } diff --git a/lib/mammoth/include/mammoth/memory_region.h b/lib/mammoth/include/mammoth/memory_region.h index 6728f55..de87d6e 100644 --- a/lib/mammoth/include/mammoth/memory_region.h +++ b/lib/mammoth/include/mammoth/memory_region.h @@ -9,7 +9,6 @@ class MappedMemoryRegion { static MappedMemoryRegion DirectPhysical(uint64_t phys_addr, uint64_t size); static MappedMemoryRegion ContiguousPhysical(uint64_t size); static MappedMemoryRegion Default(uint64_t size); - static MappedMemoryRegion FromCapability(z_cap_t vmmo_cap); MappedMemoryRegion() {} // TODO: Disallow copy before doing any cleanup here. diff --git a/lib/mammoth/src/memory_region.cpp b/lib/mammoth/src/memory_region.cpp index 23e7db4..e070b03 100644 --- a/lib/mammoth/src/memory_region.cpp +++ b/lib/mammoth/src/memory_region.cpp @@ -36,14 +36,6 @@ MappedMemoryRegion MappedMemoryRegion::Default(uint64_t size) { return MappedMemoryRegion(vmmo_cap, 0, vaddr, size); } -MappedMemoryRegion MappedMemoryRegion::FromCapability(z_cap_t vmmo_cap) { - uint64_t vaddr; - check(ZAddressSpaceMap(gSelfVmasCap, 0, vmmo_cap, &vaddr)); - - // FIXME: get the size here. - return MappedMemoryRegion(vmmo_cap, 0, vaddr, 0); -} - OwnedMemoryRegion::OwnedMemoryRegion(OwnedMemoryRegion&& other) : OwnedMemoryRegion(other.vmmo_cap_, other.vaddr_, other.size_) { other.vmmo_cap_ = 0; diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp index d96e6ec..bb85086 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp @@ -13,12 +13,12 @@ glcr::ErrorOr> Ext2BlockReader::Init( req.set_size(2); ReadResponse resp; RET_ERR(client.Read(req, resp)); - MappedMemoryRegion superblock = - MappedMemoryRegion::FromCapability(resp.memory()); + OwnedMemoryRegion superblock = + OwnedMemoryRegion::FromCapability(resp.memory()); return glcr::SharedPtr( new Ext2BlockReader(glcr::Move(client), denali_info.device_id(), - denali_info.lba_offset(), superblock)); + denali_info.lba_offset(), glcr::Move(superblock))); } Superblock* Ext2BlockReader::GetSuperblock() { @@ -59,11 +59,11 @@ uint64_t Ext2BlockReader::InodeTableBlockSize() { return (InodeSize() * GetSuperblock()->inodes_per_group) / BlockSize(); } -glcr::ErrorOr Ext2BlockReader::ReadBlock( +glcr::ErrorOr Ext2BlockReader::ReadBlock( uint64_t block_number) { return ReadBlocks(block_number, 1); } -glcr::ErrorOr Ext2BlockReader::ReadBlocks( +glcr::ErrorOr Ext2BlockReader::ReadBlocks( uint64_t block_number, uint64_t num_blocks) { ReadRequest req; req.set_device_id(device_id_); @@ -71,10 +71,10 @@ glcr::ErrorOr Ext2BlockReader::ReadBlocks( req.set_size(num_blocks * SectorsPerBlock()); ReadResponse resp; RET_ERR(denali_.Read(req, resp)); - return MappedMemoryRegion::FromCapability(resp.memory()); + return OwnedMemoryRegion::FromCapability(resp.memory()); } -glcr::ErrorOr Ext2BlockReader::ReadBlocks( +glcr::ErrorOr Ext2BlockReader::ReadBlocks( const glcr::Vector& block_list) { ReadManyRequest req; req.set_device_id(device_id_); @@ -88,13 +88,13 @@ glcr::ErrorOr Ext2BlockReader::ReadBlocks( } ReadResponse resp; RET_ERR(denali_.ReadMany(req, resp)); - return MappedMemoryRegion::FromCapability(resp.memory()); + return OwnedMemoryRegion::FromCapability(resp.memory()); } Ext2BlockReader::Ext2BlockReader(DenaliClient&& denali, uint64_t device_id, uint64_t lba_offset, - MappedMemoryRegion super_block) + OwnedMemoryRegion&& super_block) : denali_(glcr::Move(denali)), device_id_(device_id), lba_offset_(lba_offset), - super_block_region_(super_block) {} + super_block_region_(glcr::Move(super_block)) {} diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.h b/sys/victoriafalls/fs/ext2/ext2_block_reader.h index e1c4968..d30914a 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.h +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.h @@ -29,21 +29,21 @@ class Ext2BlockReader { // because the last table will likely be smaller. uint64_t InodeTableBlockSize(); - glcr::ErrorOr ReadBlock(uint64_t block_number); - glcr::ErrorOr ReadBlocks(uint64_t block_number, - uint64_t num_blocks); + glcr::ErrorOr ReadBlock(uint64_t block_number); + glcr::ErrorOr ReadBlocks(uint64_t block_number, + uint64_t num_blocks); - glcr::ErrorOr ReadBlocks( + glcr::ErrorOr ReadBlocks( const glcr::Vector& block_list); private: DenaliClient denali_; uint64_t device_id_; uint64_t lba_offset_; - MappedMemoryRegion super_block_region_; + OwnedMemoryRegion super_block_region_; Ext2BlockReader(DenaliClient&& denali, uint64_t device_id, - uint64_t lba_offset, MappedMemoryRegion super_block); + uint64_t lba_offset, OwnedMemoryRegion&& super_block); uint64_t SectorsPerBlock(); }; diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.cpp b/sys/victoriafalls/fs/ext2/ext2_driver.cpp index 077e3a2..05e4091 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_driver.cpp @@ -8,11 +8,10 @@ glcr::ErrorOr Ext2Driver::Init(const DenaliInfo& denali_info) { Ext2BlockReader::Init(glcr::Move(denali_info))); ASSIGN_OR_RETURN( - MappedMemoryRegion bgdt, + OwnedMemoryRegion bgdt, reader->ReadBlocks(reader->BgdtBlockNum(), reader->BgdtBlockSize())); - BlockGroupDescriptor* bgds = - reinterpret_cast(bgdt.vaddr()); - glcr::UniquePtr inode_table(new InodeTable(reader, bgds)); + glcr::UniquePtr inode_table( + new InodeTable(reader, glcr::Move(bgdt))); return Ext2Driver(reader, glcr::Move(inode_table)); } @@ -64,7 +63,7 @@ glcr::ErrorOr> Ext2Driver::ReadDirectory( glcr::Vector directory; for (uint64_t i = 0; i < real_block_cnt; i++) { dbgln("Getting block {x}", inode->block[i]); - ASSIGN_OR_RETURN(MappedMemoryRegion block, + ASSIGN_OR_RETURN(OwnedMemoryRegion block, ext2_reader_->ReadBlock(inode->block[i])); uint64_t addr = block.vaddr(); while (addr < block.vaddr() + ext2_reader_->BlockSize()) { @@ -87,7 +86,7 @@ glcr::ErrorOr> Ext2Driver::ReadDirectory( return directory; } -glcr::ErrorOr Ext2Driver::ReadFile(uint64_t inode_number) { +glcr::ErrorOr Ext2Driver::ReadFile(uint64_t inode_number) { ASSIGN_OR_RETURN(Inode * inode, inode_table_->GetInode(inode_number)); if (!(inode->mode & 0x8000)) { @@ -109,7 +108,7 @@ glcr::ErrorOr Ext2Driver::ReadFile(uint64_t inode_number) { return glcr::UNIMPLEMENTED; } - MappedMemoryRegion indirect_block; + OwnedMemoryRegion indirect_block; if (inode->block[12]) { ASSIGN_OR_RETURN(indirect_block, ext2_reader_->ReadBlock(inode->block[12])); } diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h index d41d29f..7be3b29 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ b/sys/victoriafalls/fs/ext2/ext2_driver.h @@ -18,7 +18,7 @@ class Ext2Driver { glcr::ErrorOr> ReadDirectory(uint32_t inode_number); - glcr::ErrorOr ReadFile(uint64_t inode_number); + glcr::ErrorOr ReadFile(uint64_t inode_number); private: glcr::SharedPtr ext2_reader_; diff --git a/sys/victoriafalls/fs/ext2/inode_table.cpp b/sys/victoriafalls/fs/ext2/inode_table.cpp index e729d7e..cfb5a15 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.cpp +++ b/sys/victoriafalls/fs/ext2/inode_table.cpp @@ -3,8 +3,10 @@ #include InodeTable::InodeTable(const glcr::SharedPtr& reader, - BlockGroupDescriptor* bgdt) - : ext2_reader_(reader), bgdt_(bgdt) { + OwnedMemoryRegion&& bgdt_region) + : ext2_reader_(reader), + bgdt_region_(glcr::Move(bgdt_region)), + bgdt_(reinterpret_cast(bgdt_region_.vaddr())) { inode_tables_.Resize(ext2_reader_->NumberOfBlockGroups()); } diff --git a/sys/victoriafalls/fs/ext2/inode_table.h b/sys/victoriafalls/fs/ext2/inode_table.h index f72350f..401a3b3 100644 --- a/sys/victoriafalls/fs/ext2/inode_table.h +++ b/sys/victoriafalls/fs/ext2/inode_table.h @@ -8,15 +8,16 @@ class InodeTable { public: InodeTable(const glcr::SharedPtr& driver, - BlockGroupDescriptor* bgdt); + OwnedMemoryRegion&& bgdt_region); glcr::ErrorOr GetInode(uint32_t inode_num); private: glcr::SharedPtr ext2_reader_; + OwnedMemoryRegion bgdt_region_; BlockGroupDescriptor* bgdt_; - glcr::Vector inode_tables_; + glcr::Vector inode_tables_; glcr::ErrorOr GetRootOfInodeTable(uint64_t block_group_num); }; diff --git a/sys/victoriafalls/victoriafalls_server.cpp b/sys/victoriafalls/victoriafalls_server.cpp index 815e0bd..788998c 100644 --- a/sys/victoriafalls/victoriafalls_server.cpp +++ b/sys/victoriafalls/victoriafalls_server.cpp @@ -38,7 +38,7 @@ glcr::ErrorCode VFSServer::HandleOpenFile(const OpenFileRequest& request, } uint64_t inode_num; - MappedMemoryRegion region; + OwnedMemoryRegion region; for (uint64_t j = 0; j < files.size(); j++) { if (path_tokens.at(path_tokens.size() - 1) == glcr::StringView(files.at(j).name, files.at(j).name_len)) { @@ -53,7 +53,12 @@ glcr::ErrorCode VFSServer::HandleOpenFile(const OpenFileRequest& request, } response.set_path(request.path()); - response.set_memory(region.cap()); + // FIXME: There isn't really a reason we need to map the file into memory then + // duplicate the cap. In the future just get the cap from the read then pass + // it to the caller directly. + uint64_t mem_cap; + uint64_t cap = ZCapDuplicate(region.cap(), kZionPerm_All, &mem_cap); + response.set_memory(mem_cap); // TODO: Consider folding this up into the actual read call. ASSIGN_OR_RETURN(Inode * inode, driver_.GetInode(inode_num)); // FIXME: This technically only sets the lower 32 bits. diff --git a/sys/yellowstone/hw/gpt.cpp b/sys/yellowstone/hw/gpt.cpp index 06e10d9..2ce326b 100644 --- a/sys/yellowstone/hw/gpt.cpp +++ b/sys/yellowstone/hw/gpt.cpp @@ -64,8 +64,8 @@ glcr::ErrorCode GptReader::ParsePartitionTables() { req.set_size(2); ReadResponse resp; RET_ERR(denali_->Read(req, resp)); - MappedMemoryRegion lba_1_and_2 = - MappedMemoryRegion::FromCapability(resp.memory()); + OwnedMemoryRegion lba_1_and_2 = + OwnedMemoryRegion::FromCapability(resp.memory()); uint16_t* mbr_sig = reinterpret_cast(lba_1_and_2.vaddr() + 0x1FE); if (*mbr_sig != 0xAA55) { dbgln("Invalid MBR Sig: {x}", *mbr_sig); @@ -106,8 +106,8 @@ glcr::ErrorCode GptReader::ParsePartitionTables() { req.set_lba(header->lba_partition_entries); req.set_size(num_blocks); RET_ERR(denali_->Read(req, resp)); - MappedMemoryRegion part_table = - MappedMemoryRegion::FromCapability(resp.memory()); + OwnedMemoryRegion part_table = + OwnedMemoryRegion::FromCapability(resp.memory()); for (uint64_t i = 0; i < num_partitions; i++) { PartitionEntry* entry = reinterpret_cast( part_table.vaddr() + (i * entry_size)); diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index 68131f9..dc6de12 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -43,8 +43,8 @@ uint64_t main(uint64_t port_cap) { OpenFileResponse response; check(vfs_client->OpenFile(request, response)); - MappedMemoryRegion filemem = - MappedMemoryRegion::FromCapability(response.memory()); + OwnedMemoryRegion filemem = + OwnedMemoryRegion::FromCapability(response.memory()); glcr::String file(reinterpret_cast(filemem.vaddr()), response.size()); diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index 978e4fd..509f45f 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -60,8 +60,8 @@ glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, glcr::ErrorCode YellowstoneServer::HandleGetFramebufferInfo( const Empty&, FramebufferInfo& info) { // FIXME: Don't do this for each request. - MappedMemoryRegion region = - MappedMemoryRegion::FromCapability(gBootFramebufferVmmoCap); + OwnedMemoryRegion region = + OwnedMemoryRegion::FromCapability(gBootFramebufferVmmoCap); ZFramebufferInfo* fb = reinterpret_cast(region.vaddr()); info.set_address_phys(fb->address_phys); diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index 4a23b55..1e30851 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -64,7 +64,7 @@ target_link_libraries(zion # -mno-red-zone -- Don't put data below the stack pointer (clobbered by interrupts). # -mcmodel=kernel -- Assume the kernel code is running in the higher half. # -mgeneral-regs-only -- Prevent GCC from using a whole host of nonsense registers (that we have to enable). -set(_Z_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -nostdlib -mabi=sysv -mno-red-zone -mcmodel=kernel -mgeneral-regs-only") +set(_Z_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -fno-use-cxa-atexit -nostdlib -mabi=sysv -mno-red-zone -mcmodel=kernel -mgeneral-regs-only") set(_Z_LINK_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") diff --git a/zion/debug/debug.h b/zion/debug/debug.h index ed07d9a..63b0d0e 100644 --- a/zion/debug/debug.h +++ b/zion/debug/debug.h @@ -9,7 +9,7 @@ void dbgln(const glcr::StringView& str); template -void dbgln(const char* str, Args... args) { +void dbgln(const char* str, Args&&... args) { char buffer[256]; glcr::FixedStringBuilder builder(buffer, 256); glcr::StrFormatIntoBuffer(builder, str, args...); @@ -17,12 +17,12 @@ void dbgln(const char* str, Args... args) { } template -void dbgln_large(const char* str, Args... args) { +void dbgln_large(const char* str, Args&&... args) { dbgln(glcr::StrFormat(str, args...)); } template -void panic(const char* str, Args... args) { +void panic(const char* str, Args&&... args) { dbgln(str, args...); dbgln("PANIC"); asm volatile("cli; hlt;"); @@ -34,6 +34,6 @@ void panic(const char* str, Args... args) { panic(str); \ } \ } -#define UNREACHABLE \ - panic("Unreachable {}, {}", __FILE__, __LINE__); \ +#define UNREACHABLE \ + panic("Unreachable {}, {}", glcr::StringView(__FILE__), __LINE__); \ __builtin_unreachable(); diff --git a/zion/lib/memory_mapping_tree.cpp b/zion/lib/memory_mapping_tree.cpp index 72e711f..ead2ff6 100644 --- a/zion/lib/memory_mapping_tree.cpp +++ b/zion/lib/memory_mapping_tree.cpp @@ -1,7 +1,17 @@ #include "lib/memory_mapping_tree.h" +#include + #include "debug/debug.h" +template <> +void glcr::StrFormatValue(glcr::StringBuilder& builder, + const MemoryMappingTree::MemoryMapping& value, + glcr::StringView opts) { + builder.PushBack( + glcr::StrFormat("Range {x}-{x}", value.vaddr_base, value.vaddr_limit)); +} + glcr::ErrorCode MemoryMappingTree::AddInMemoryObject( uint64_t vaddr, const glcr::RefPtr& object) { // TODO: This implementation is inefficient as it traverses the tree a lot, we @@ -45,6 +55,9 @@ glcr::ErrorCode MemoryMappingTree::FreeMemoryRange(uint64_t vaddr_base, auto find_or = mapping_tree_.Find(vaddr_base); if (find_or) { + dbgln("Mem addr {x} refcnt {}", + (uint64_t)find_or.value().get().mem_object.get(), + find_or.value().get().mem_object->ref_count()); mapping_tree_.Delete(vaddr_base); } while (true) { diff --git a/zion/lib/memory_mapping_tree.h b/zion/lib/memory_mapping_tree.h index 7fb876d..7dafecc 100644 --- a/zion/lib/memory_mapping_tree.h +++ b/zion/lib/memory_mapping_tree.h @@ -21,13 +21,13 @@ class MemoryMappingTree { glcr::ErrorOr GetPhysicalPageAtVaddr(uint64_t vaddr); - private: struct MemoryMapping { uint64_t vaddr_base; uint64_t vaddr_limit; glcr::RefPtr mem_object; }; + private: // TODO: Consider adding a red-black tree implementation here. // As is this tree functions about as well as a linked list // because mappings are likely to be added in near-perfect ascedning order. diff --git a/zion/memory/kernel_heap.cpp b/zion/memory/kernel_heap.cpp index 14a4a37..6ad518a 100644 --- a/zion/memory/kernel_heap.cpp +++ b/zion/memory/kernel_heap.cpp @@ -164,3 +164,8 @@ void operator delete[](void* addr) { SlabFree(addr); } } +void operator delete[](void* addr, uint64_t size) { + if (IsSlab(addr)) { + SlabFree(addr); + } +} diff --git a/zion/object/memory_object.cpp b/zion/object/memory_object.cpp index 469d237..62d6520 100644 --- a/zion/object/memory_object.cpp +++ b/zion/object/memory_object.cpp @@ -20,6 +20,8 @@ MemoryObject::MemoryObject(uint64_t size) : size_(size) { } } +MemoryObject::~MemoryObject() { dbgln("Memory Object Freed"); } + uint64_t MemoryObject::PhysicalPageAtOffset(uint64_t offset) { if (offset > size_) { panic("Invalid offset"); diff --git a/zion/object/memory_object.h b/zion/object/memory_object.h index 027563e..e7bdcdc 100644 --- a/zion/object/memory_object.h +++ b/zion/object/memory_object.h @@ -27,7 +27,8 @@ class MemoryObject : public KernelObject { kZionPerm_Transmit; } - MemoryObject(uint64_t size); + explicit MemoryObject(uint64_t size); + ~MemoryObject(); uint64_t size() { return size_; } uint64_t num_pages() { return size_ / 0x1000; }