diff --git a/lib/libc/src/malloc.cpp b/lib/libc/src/malloc.cpp index 4747aaf..c8dff91 100644 --- a/lib/libc/src/malloc.cpp +++ b/lib/libc/src/malloc.cpp @@ -6,7 +6,7 @@ namespace { class NaiveAllocator { public: - constexpr static uint64_t kSize = 0x4000; + constexpr static uint64_t kSize = 0x10000; NaiveAllocator() {} bool is_init() { return next_addr_ != 0; } void Init() { @@ -23,6 +23,7 @@ class NaiveAllocator { uint64_t addr = next_addr_; next_addr_ += size; if (next_addr_ >= max_addr_) { + ZProcessExit(0xBEEF); return 0; } return reinterpret_cast(addr); diff --git a/lib/mammoth/include/mammoth/process.h b/lib/mammoth/include/mammoth/process.h index 4317c76..e46047e 100644 --- a/lib/mammoth/include/mammoth/process.h +++ b/lib/mammoth/include/mammoth/process.h @@ -5,5 +5,5 @@ #include "mammoth/endpoint_client.h" -glcr::ErrorCode SpawnProcessFromElfRegion( - uint64_t program, glcr::UniquePtr client); +glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program, + z_cap_t yellowstone_client); diff --git a/lib/mammoth/src/process.cpp b/lib/mammoth/src/process.cpp index d4dbcad..9d59828 100644 --- a/lib/mammoth/src/process.cpp +++ b/lib/mammoth/src/process.cpp @@ -96,8 +96,8 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) { } // namespace -glcr::ErrorCode SpawnProcessFromElfRegion( - uint64_t program, glcr::UniquePtr client) { +glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program, + z_cap_t yellowstone_client) { uint64_t proc_cap; uint64_t as_cap; uint64_t foreign_port_id; @@ -125,7 +125,7 @@ glcr::ErrorCode SpawnProcessFromElfRegion( RET_ERR(pclient.WriteMessage(Z_INIT_SELF_PROC, proc_cap)); RET_ERR(pclient.WriteMessage(Z_INIT_SELF_VMAS, as_cap)); - RET_ERR(pclient.WriteMessage(Z_INIT_ENDPOINT, client->GetCap())); + RET_ERR(pclient.WriteMessage(Z_INIT_ENDPOINT, yellowstone_client)); #if MAM_PROC_DEBUG dbgln("Thread start"); diff --git a/sys/denali/CMakeLists.txt b/sys/denali/CMakeLists.txt index 2ca3dfe..b798ac2 100644 --- a/sys/denali/CMakeLists.txt +++ b/sys/denali/CMakeLists.txt @@ -14,7 +14,7 @@ target_include_directories(denali target_link_libraries(denali glacier mammoth - yellowstone_stub + yellowstone_yunq ) set_target_properties(denali PROPERTIES diff --git a/sys/denali/denali.cpp b/sys/denali/denali.cpp index a7ba4e7..d4aa72c 100644 --- a/sys/denali/denali.cpp +++ b/sys/denali/denali.cpp @@ -5,7 +5,7 @@ #include #include #include -#include +#include #include "ahci/ahci_driver.h" #include "denali_server.h" @@ -15,8 +15,12 @@ uint64_t main(uint64_t init_port_cap) { glcr::UniquePtr yellowstone = EndpointClient::AdoptEndpoint(gInitEndpointCap); - YellowstoneStub stub(gInitEndpointCap); - ASSIGN_OR_RETURN(MappedMemoryRegion ahci_region, stub.GetAhciConfig()); + YellowstoneClient stub(gInitEndpointCap); + Empty empty; + AhciInfo ahci; + RET_ERR(stub.GetAhciInfo(empty, ahci)); + MappedMemoryRegion ahci_region = + MappedMemoryRegion::FromCapability(ahci.ahci_region()); ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(ahci_region)); ASSIGN_OR_RETURN(glcr::UniquePtr server, @@ -24,7 +28,14 @@ uint64_t main(uint64_t init_port_cap) { ASSIGN_OR_RETURN(glcr::UniquePtr client, server->CreateClient()); - check(stub.Register("denali", *client)); + + RegisterInfo reg; + Empty empty2; + check(stub.GetRegister(empty2, reg)); + + PortClient register_port = PortClient::AdoptPort(reg.register_port()); + + check(register_port.WriteString("denali", client->GetCap())); Thread server_thread = server->RunServer(); diff --git a/sys/victoriafalls/CMakeLists.txt b/sys/victoriafalls/CMakeLists.txt index b848b39..380abef 100644 --- a/sys/victoriafalls/CMakeLists.txt +++ b/sys/victoriafalls/CMakeLists.txt @@ -11,7 +11,7 @@ target_include_directories(victoriafalls target_link_libraries(victoriafalls glacier mammoth - yellowstone_stub + yellowstone_yunq ) set_target_properties(victoriafalls PROPERTIES diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp index a128bbb..cab63d8 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.cpp @@ -1,5 +1,7 @@ #include "fs/ext2/ext2_block_reader.h" +#include "mammoth/debug.h" + glcr::ErrorOr> Ext2BlockReader::Init( ScopedDenaliClient&& denali) { // Read 1024 bytes from 1024 offset. diff --git a/sys/victoriafalls/victoriafalls.cpp b/sys/victoriafalls/victoriafalls.cpp index 3b0a293..c071851 100644 --- a/sys/victoriafalls/victoriafalls.cpp +++ b/sys/victoriafalls/victoriafalls.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include "fs/ext2/ext2_driver.h" @@ -9,8 +9,14 @@ uint64_t main(uint64_t init_cap) { dbgln("VFs Started"); - YellowstoneStub yellowstone(gInitEndpointCap); - ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali()); + YellowstoneClient yellowstone(gInitEndpointCap); + Empty empty; + DenaliInfo denali_info; + RET_ERR(yellowstone.GetDenali(empty, denali_info)); + dbgln("LBA (recv): %u", denali_info.lba_offset()); + ScopedDenaliClient denali( + EndpointClient::AdoptEndpoint(denali_info.denali_endpoint()), + denali_info.device_id(), denali_info.lba_offset()); ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali))); ASSIGN_OR_RETURN(Inode * root, ext2.GetInode(2)); diff --git a/sys/yellowstone/CMakeLists.txt b/sys/yellowstone/CMakeLists.txt index 94031ff..7a3d6ff 100644 --- a/sys/yellowstone/CMakeLists.txt +++ b/sys/yellowstone/CMakeLists.txt @@ -12,6 +12,7 @@ target_link_libraries(yellowstone mammoth glacier denali_stub + yellowstone_yunq ) set_target_properties(yellowstone PROPERTIES @@ -20,20 +21,22 @@ set_target_properties(yellowstone PROPERTIES ) -add_library(yellowstone_stub - stub/yellowstone_stub.cpp +add_library(yellowstone_yunq + include/yellowstone/yellowstone.yunq.cpp + include/yellowstone/yellowstone.yunq.client.cpp + include/yellowstone/yellowstone.yunq.server.cpp ) -target_include_directories(yellowstone_stub +target_include_directories(yellowstone_yunq PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") -target_link_libraries(yellowstone_stub +target_link_libraries(yellowstone_yunq denali_stub mammoth ) -set_target_properties(yellowstone_stub PROPERTIES +set_target_properties(yellowstone_yunq PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}" LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}" ) diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq b/sys/yellowstone/include/yellowstone/yellowstone.yunq new file mode 100644 index 0000000..530c3f1 --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq @@ -0,0 +1,24 @@ +interface Yellowstone { + method GetRegister(Empty) -> (RegisterInfo); + method GetAhciInfo(Empty) -> (AhciInfo); + method GetDenali(Empty) -> (DenaliInfo); +} + +message Empty { + +} + +message RegisterInfo { + capability register_port; +} + +message AhciInfo { + capability ahci_region; + u64 region_length; +} + +message DenaliInfo { + capability denali_endpoint; + u64 device_id; + u64 lba_offset; +} diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp new file mode 100644 index 0000000..2026c48 --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.cpp @@ -0,0 +1,105 @@ +// Generated file - DO NOT MODIFY +#include "yellowstone.yunq.client.h" + +#include +#include +#include + + + + +glcr::ErrorCode YellowstoneClient::GetRegister(const Empty& request, RegisterInfo& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; + + const uint32_t kSentinel = 0xBEEFDEAD; + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, 0); + + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); + + z_cap_t reply_port_cap; + // FIXME: We need to be able to send capabilities via endpoint call. + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap)); + + // FIXME: Add a way to zero out the first buffer. + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); + + if (buffer_.At(0) != kSentinel) { + return glcr::INVALID_RESPONSE; + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + response.ParseFromBytes(buffer_, 16, cap_buffer_); + + return glcr::OK; +} + + + +glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; + + const uint32_t kSentinel = 0xBEEFDEAD; + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, 1); + + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); + + z_cap_t reply_port_cap; + // FIXME: We need to be able to send capabilities via endpoint call. + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap)); + + // FIXME: Add a way to zero out the first buffer. + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); + + if (buffer_.At(0) != kSentinel) { + return glcr::INVALID_RESPONSE; + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + response.ParseFromBytes(buffer_, 16, cap_buffer_); + + return glcr::OK; +} + + + +glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; + + const uint32_t kSentinel = 0xBEEFDEAD; + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, 2); + + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); + + z_cap_t reply_port_cap; + // FIXME: We need to be able to send capabilities via endpoint call. + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap)); + + // FIXME: Add a way to zero out the first buffer. + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); + + if (buffer_.At(0) != kSentinel) { + return glcr::INVALID_RESPONSE; + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + response.ParseFromBytes(buffer_, 16, cap_buffer_); + + return glcr::OK; +} + + diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h new file mode 100644 index 0000000..225b351 --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.client.h @@ -0,0 +1,32 @@ +// Generated file - DO NOT MODIFY +#pragma once + +#include +#include +#include +#include + +#include "yellowstone.yunq.h" + +class YellowstoneClient { + public: + YellowstoneClient(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {} + YellowstoneClient(const YellowstoneClient&) = delete; + YellowstoneClient(YellowstoneClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; + + z_cap_t Capability() { return endpoint_; } + + + [[nodiscard]] glcr::ErrorCode GetRegister(const Empty& request, RegisterInfo& response); + + [[nodiscard]] glcr::ErrorCode GetAhciInfo(const Empty& request, AhciInfo& response); + + [[nodiscard]] glcr::ErrorCode GetDenali(const Empty& request, DenaliInfo& response); + + private: + z_cap_t endpoint_; + uint64_t kBufferSize = 0x1000; + glcr::ByteBuffer buffer_{kBufferSize}; + uint64_t kCapBufferSize = 0x10; + glcr::CapBuffer cap_buffer_{kCapBufferSize}; +}; diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp new file mode 100644 index 0000000..41dacd1 --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.cpp @@ -0,0 +1,204 @@ +// Generated file -- DO NOT MODIFY. +#include "yellowstone.yunq.h" + +namespace { + +const uint64_t header_size = 24; // 4x uint32, 1x uint64 + +struct ExtPointer { + uint32_t offset; + uint32_t length; +}; + +void CheckHeader(const glcr::ByteBuffer& bytes) { + // TODO: Check ident. + // TODO: Parse core size. + // TODO: Parse extension size. + // TODO: Check CRC32 + // TODO: Parse options. +} + +void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, uint32_t extension_size) { + bytes.WriteAt(offset + 0, 0xDEADBEEF); // TODO: Chose a more unique ident sequence. + bytes.WriteAt(offset + 4, core_size); + bytes.WriteAt(offset + 8, extension_size); + bytes.WriteAt(offset + 12, 0); // TODO: Calculate CRC32. + bytes.WriteAt(offset + 16, 0); // TODO: Add options. +} + +} // namespace +void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); +} + +void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); +} + +uint64_t Empty::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 0; + const uint32_t core_size = next_extension; + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t Empty::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 0; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} +void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse register_port. + // FIXME: Implement in-buffer capabilities for inprocess serialization. + set_register_port(0); +} + +void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse register_port. + uint64_t register_port_ptr = bytes.At(offset + header_size + (8 * 0)); + + set_register_port(caps.At(register_port_ptr)); +} + +uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 1; + const uint32_t core_size = next_extension; + // Write register_port. + // FIXME: Implement inbuffer capabilities. + bytes.WriteAt(offset + header_size + (8 * 0), 0); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 1; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write register_port. + caps.WriteAt(next_cap, register_port()); + bytes.WriteAt(offset + header_size + (8 * 0), next_cap++); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} +void AhciInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse ahci_region. + // FIXME: Implement in-buffer capabilities for inprocess serialization. + set_ahci_region(0); + // Parse region_length. + set_region_length(bytes.At(offset + header_size + (8 * 1))); +} + +void AhciInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse ahci_region. + uint64_t ahci_region_ptr = bytes.At(offset + header_size + (8 * 0)); + + set_ahci_region(caps.At(ahci_region_ptr)); + // Parse region_length. + set_region_length(bytes.At(offset + header_size + (8 * 1))); +} + +uint64_t AhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 2; + const uint32_t core_size = next_extension; + // Write ahci_region. + // FIXME: Implement inbuffer capabilities. + bytes.WriteAt(offset + header_size + (8 * 0), 0); + // Write region_length. + bytes.WriteAt(offset + header_size + (8 * 1), region_length()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t AhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 2; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write ahci_region. + caps.WriteAt(next_cap, ahci_region()); + bytes.WriteAt(offset + header_size + (8 * 0), next_cap++); + // Write region_length. + bytes.WriteAt(offset + header_size + (8 * 1), region_length()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} +void DenaliInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse denali_endpoint. + // FIXME: Implement in-buffer capabilities for inprocess serialization. + set_denali_endpoint(0); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 1))); + // Parse lba_offset. + set_lba_offset(bytes.At(offset + header_size + (8 * 2))); +} + +void DenaliInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse denali_endpoint. + uint64_t denali_endpoint_ptr = bytes.At(offset + header_size + (8 * 0)); + + set_denali_endpoint(caps.At(denali_endpoint_ptr)); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 1))); + // Parse lba_offset. + set_lba_offset(bytes.At(offset + header_size + (8 * 2))); +} + +uint64_t DenaliInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 3; + const uint32_t core_size = next_extension; + // Write denali_endpoint. + // FIXME: Implement inbuffer capabilities. + bytes.WriteAt(offset + header_size + (8 * 0), 0); + // Write device_id. + bytes.WriteAt(offset + header_size + (8 * 1), device_id()); + // Write lba_offset. + bytes.WriteAt(offset + header_size + (8 * 2), lba_offset()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t DenaliInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 3; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write denali_endpoint. + caps.WriteAt(next_cap, denali_endpoint()); + bytes.WriteAt(offset + header_size + (8 * 0), next_cap++); + // Write device_id. + bytes.WriteAt(offset + header_size + (8 * 1), device_id()); + // Write lba_offset. + bytes.WriteAt(offset + header_size + (8 * 2), lba_offset()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} \ No newline at end of file diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.h new file mode 100644 index 0000000..b66b35f --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.h @@ -0,0 +1,85 @@ +// Generated file - DO NOT MODIFY +#pragma once + +#include +#include +#include +#include +class Empty { + public: + Empty() {} + // Delete copy and move until implemented. + Empty(const Empty&) = delete; + Empty(Empty&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + + private: + +}; +class RegisterInfo { + public: + RegisterInfo() {} + // Delete copy and move until implemented. + RegisterInfo(const RegisterInfo&) = delete; + RegisterInfo(RegisterInfo&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + z_cap_t register_port() const { return register_port_; } + void set_register_port(const z_cap_t& value) { register_port_ = value; } + + private: + z_cap_t register_port_; + +}; +class AhciInfo { + public: + AhciInfo() {} + // Delete copy and move until implemented. + AhciInfo(const AhciInfo&) = delete; + AhciInfo(AhciInfo&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + z_cap_t ahci_region() const { return ahci_region_; } + void set_ahci_region(const z_cap_t& value) { ahci_region_ = value; } + uint64_t region_length() const { return region_length_; } + void set_region_length(const uint64_t& value) { region_length_ = value; } + + private: + z_cap_t ahci_region_; + uint64_t region_length_; + +}; +class DenaliInfo { + public: + DenaliInfo() {} + // Delete copy and move until implemented. + DenaliInfo(const DenaliInfo&) = delete; + DenaliInfo(DenaliInfo&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + z_cap_t denali_endpoint() const { return denali_endpoint_; } + void set_denali_endpoint(const z_cap_t& value) { denali_endpoint_ = value; } + uint64_t device_id() const { return device_id_; } + void set_device_id(const uint64_t& value) { device_id_ = value; } + uint64_t lba_offset() const { return lba_offset_; } + void set_lba_offset(const uint64_t& value) { lba_offset_ = value; } + + private: + z_cap_t denali_endpoint_; + uint64_t device_id_; + uint64_t lba_offset_; + +}; \ No newline at end of file diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp new file mode 100644 index 0000000..1dd74fc --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.cpp @@ -0,0 +1,124 @@ +// Generated file -- DO NOT MODIFY. +#include "yellowstone.yunq.server.h" + +#include +#include + +namespace { + +const uint32_t kSentinel = 0xBEEFDEAD; +const uint32_t kHeaderSize = 0x10; + +void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) { + buffer.WriteAt(0, kSentinel); + buffer.WriteAt(4, kHeaderSize); + buffer.WriteAt(8, err); +} + +void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) { + buffer.WriteAt(0, kSentinel); + buffer.WriteAt(4, kHeaderSize + message_length); + buffer.WriteAt(8, glcr::OK); +} + +} // namespace + + + +void YellowstoneServerBaseThreadBootstrap(void* server_base) { + ((YellowstoneServerBase*)server_base)->ServerThread(); +} + +glcr::ErrorOr YellowstoneServerBase::CreateClient() { + uint64_t client_cap; + // FIXME: Restrict permissions to send-only here. + RET_ERR(ZCapDuplicate(endpoint_, &client_cap)); + return YellowstoneClient(client_cap); +} + +Thread YellowstoneServerBase::RunServer() { + return Thread(YellowstoneServerBaseThreadBootstrap, this); +} + +void YellowstoneServerBase::ServerThread() { + glcr::ByteBuffer recv_buffer(0x1000); + glcr::ByteBuffer resp_buffer(0x1000); + uint64_t resp_cap_size = 0x10; + glcr::CapBuffer resp_cap(resp_cap_size); + z_cap_t reply_port_cap; + + while (true) { + uint64_t recv_buf_size = 0x1000; + glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &reply_port_cap); + if (recv_err != glcr::OK) { + dbgln("Error in receive: %x", recv_err); + continue; + } + + uint64_t resp_length = 0; + + glcr::ErrorCode reply_err = glcr::OK; + glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap); + if (err != glcr::OK) { + WriteError(resp_buffer, err); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr); + } else { + WriteHeader(resp_buffer, resp_length); + reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr()); + } + if (reply_err != glcr::OK) { + dbgln("Error in reply: %x", recv_err); + } + } + +} + +glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& request, + glcr::ByteBuffer& response, uint64_t& resp_length, + glcr::CapBuffer& resp_caps) { + if (request.At(0) != kSentinel) { + return glcr::INVALID_ARGUMENT; + } + + uint64_t method_select = request.At(8); + + switch(method_select) { + case 0: { + Empty yunq_request; + RegisterInfo yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize); + + RET_ERR(HandleGetRegister(yunq_request, yunq_response)); + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + break; + } + case 1: { + Empty yunq_request; + AhciInfo yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize); + + RET_ERR(HandleGetAhciInfo(yunq_request, yunq_response)); + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + break; + } + case 2: { + Empty yunq_request; + DenaliInfo yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize); + + RET_ERR(HandleGetDenali(yunq_request, yunq_response)); + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + break; + } + default: { + return glcr::UNIMPLEMENTED; + } + } + return glcr::OK; +} diff --git a/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h new file mode 100644 index 0000000..03d8989 --- /dev/null +++ b/sys/yellowstone/include/yellowstone/yellowstone.yunq.server.h @@ -0,0 +1,41 @@ +// Generated File -- DO NOT MODIFY. +#pragma once + +#include +#include +#include + +#include "yellowstone.yunq.h" +#include "yellowstone.yunq.client.h" + + + +class YellowstoneServerBase { + public: + YellowstoneServerBase(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {} + YellowstoneServerBase(const YellowstoneServerBase&) = delete; + YellowstoneServerBase(YellowstoneServerBase&&) = delete; + + glcr::ErrorOr CreateClient(); + + [[nodiscard]] Thread RunServer(); + + + [[nodiscard]] virtual glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) = 0; + + [[nodiscard]] virtual glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) = 0; + + [[nodiscard]] virtual glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) = 0; + + + private: + z_cap_t endpoint_; + + friend void YellowstoneServerBaseThreadBootstrap(void*); + void ServerThread(); + + [[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, + uint64_t& resp_length, + glcr::CapBuffer& resp_caps); +}; + diff --git a/sys/yellowstone/stub/yellowstone_stub.cpp b/sys/yellowstone/stub/yellowstone_stub.cpp deleted file mode 100644 index 27b5ae7..0000000 --- a/sys/yellowstone/stub/yellowstone_stub.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "include/yellowstone_stub.h" - -#include - -#include "include/yellowstone.h" - -YellowstoneStub::YellowstoneStub(z_cap_t yellowstone_cap) - : yellowstone_stub_(EndpointClient::AdoptEndpoint(yellowstone_cap)) {} - -glcr::ErrorOr YellowstoneStub::GetAhciConfig() { - YellowstoneGetReq req{ - .type = kYellowstoneGetAhci, - }; - ASSIGN_OR_RETURN( - auto resp_cap_pair, - (yellowstone_stub_->CallEndpointGetCap(req))); - return MappedMemoryRegion::FromCapability(resp_cap_pair.second()); -} - -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()) { - YellowstoneGetReq req{ - .type = kYellowstoneGetRegistration, - }; - ASSIGN_OR_RETURN( - auto resp_cap, - (yellowstone_stub_->CallEndpointGetCap< - YellowstoneGetReq, YellowstoneGetRegistrationResp>(req))); - register_port_ = PortClient::AdoptPort(resp_cap.second()); - } - - return register_port_.WriteString(name, client.GetCap()); -} diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index 6db5faf..e367359 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -18,9 +18,8 @@ uint64_t main(uint64_t port_cap) { uint64_t vaddr; check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr)); - ASSIGN_OR_RETURN(glcr::UniquePtr client, - server->CreateClient()); - check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client))); + ASSIGN_OR_RETURN(YellowstoneClient client, server->CreateClient()); + check(SpawnProcessFromElfRegion(vaddr, client.Capability())); check(server_thread.Join()); check(registration_thread.Join()); diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index 78f4d8c..133c38e 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -43,54 +43,36 @@ glcr::ErrorOr> YellowstoneServer::Create() { } YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, PortServer port) - : EndpointServer(endpoint_cap), register_port_(port) {} + : YellowstoneServerBase(endpoint_cap), register_port_(port) {} Thread YellowstoneServer::RunRegistration() { return Thread(RegistrationThreadBootstrap, this); } -glcr::ErrorCode YellowstoneServer::HandleRequest(RequestContext& request, - ResponseContext& response) { - switch (request.request_id()) { - case kYellowstoneGetAhci: { - dbgln("Yellowstone::GetAHCI"); - YellowstoneGetAhciResp resp{ - .type = kYellowstoneGetAhci, - .ahci_length = kPcieConfigurationSize, - }; - z_cap_t vmmo_cap = pci_reader_.GetAhciVmmo(); - RET_ERR( - response.WriteStructWithCap(resp, vmmo_cap)); - break; - } - case kYellowstoneGetRegistration: { - dbgln("Yellowstone::GetRegistration"); - auto client_or = register_port_.CreateClient(); - if (!client_or.ok()) { - check(client_or.error()); - } - YellowstoneGetRegistrationResp resp; - uint64_t reg_cap = client_or.value().cap(); - RET_ERR(response.WriteStructWithCap(resp, reg_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_, - }; - RET_ERR(response.WriteStructWithCap(resp, new_denali)); - break; - } - default: - dbgln("Unknown request type: %x", request.request_id()); - return glcr::UNIMPLEMENTED; - break; +glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, + AhciInfo& info) { + info.set_ahci_region(pci_reader_.GetAhciVmmo()); + info.set_region_length(kPcieConfigurationSize); + return glcr::OK; +} + +glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&, + DenaliInfo& info) { + z_cap_t new_denali; + check(ZCapDuplicate(denali_cap_, &new_denali)); + info.set_denali_endpoint(new_denali); + info.set_device_id(device_id_); + info.set_lba_offset(lba_offset_); + return glcr::OK; +} +glcr::ErrorCode YellowstoneServer::HandleGetRegister(const Empty&, + RegisterInfo& info) { + auto client_or = register_port_.CreateClient(); + if (!client_or.ok()) { + dbgln("Error creating register client: %u", client_or.error()); + return glcr::INTERNAL; } + info.set_register_port(client_or.value().cap()); return glcr::OK; } @@ -118,7 +100,7 @@ void YellowstoneServer::RegistrationThread() { if (!client_or.ok()) { check(client_or.error()); } - check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client_or.value()))); + check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability())); continue; } diff --git a/sys/yellowstone/yellowstone_server.h b/sys/yellowstone/yellowstone_server.h index bd643dc..afe0113 100644 --- a/sys/yellowstone/yellowstone_server.h +++ b/sys/yellowstone/yellowstone_server.h @@ -7,8 +7,9 @@ #include #include "hw/pcie.h" +#include "include/yellowstone/yellowstone.yunq.server.h" -class YellowstoneServer : public EndpointServer { +class YellowstoneServer : public YellowstoneServerBase { public: static glcr::ErrorOr> Create(); @@ -16,8 +17,9 @@ class YellowstoneServer : public EndpointServer { void RegistrationThread(); - virtual glcr::ErrorCode HandleRequest(RequestContext& request, - ResponseContext& response) override; + glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) override; + glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) override; + glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) override; private: // FIXME: Separate this to its own service. diff --git a/zion/interrupt/interrupt.cpp b/zion/interrupt/interrupt.cpp index 6226330..b00e69a 100644 --- a/zion/interrupt/interrupt.cpp +++ b/zion/interrupt/interrupt.cpp @@ -69,7 +69,10 @@ struct InterruptFrame { }; extern "C" void isr_divide_by_zero(); -extern "C" void interrupt_divide_by_zero(void* frame) { panic("DIV0"); } +extern "C" void interrupt_divide_by_zero(InterruptFrame* frame) { + dbgln("RIP: %m", frame->rip); + panic("DIV0"); +} extern "C" void isr_protection_fault(); extern "C" void interrupt_protection_fault(InterruptFrame* frame) { diff --git a/zion/memory/physical_memory.cpp b/zion/memory/physical_memory.cpp index 52e850b..e2d6d42 100644 --- a/zion/memory/physical_memory.cpp +++ b/zion/memory/physical_memory.cpp @@ -88,6 +88,8 @@ class PhysicalMemoryManager { MemBlock* block = front_; while (block != nullptr && block->num_pages < num_pages) { + dbgln("Skipping block of size %u seeking %u", block->num_pages, + num_pages); block = block->next; }