diff --git a/sys/denali/CMakeLists.txt b/sys/denali/CMakeLists.txt index b798ac2..24602d1 100644 --- a/sys/denali/CMakeLists.txt +++ b/sys/denali/CMakeLists.txt @@ -8,10 +8,10 @@ add_executable(denali target_include_directories(denali - PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - "${CMAKE_CURRENT_SOURCE_DIR}/include") + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(denali + denali_yunq glacier mammoth yellowstone_yunq @@ -22,18 +22,20 @@ set_target_properties(denali PROPERTIES LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}" ) -add_library(denali_stub - client/denali_client.cpp +add_library(denali_yunq + lib/denali/denali.yunq.client.cpp + lib/denali/denali.yunq.server.cpp + lib/denali/denali.yunq.cpp ) -target_include_directories(denali_stub +target_include_directories(denali_yunq PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} - PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include") + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/lib") - target_link_libraries(denali_stub + target_link_libraries(denali_yunq mammoth) -set_target_properties(denali_stub PROPERTIES +set_target_properties(denali_yunq PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}" LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}" ) diff --git a/sys/denali/ahci/command.cpp b/sys/denali/ahci/command.cpp index c79a068..37dd63f 100644 --- a/sys/denali/ahci/command.cpp +++ b/sys/denali/ahci/command.cpp @@ -7,11 +7,8 @@ Command::~Command() {} DmaReadCommand::DmaReadCommand(uint64_t lba, uint64_t sector_cnt, - Mutex& callback_mutex, ResponseContext& response) - : response_(response), - lba_(lba), - sector_cnt_(sector_cnt), - callback_mutex_(callback_mutex) { + Mutex& callback_mutex) + : lba_(lba), sector_cnt_(sector_cnt), callback_mutex_(callback_mutex) { region_ = MappedMemoryRegion::ContiguousPhysical(sector_cnt * 512); } diff --git a/sys/denali/ahci/command.h b/sys/denali/ahci/command.h index 5464369..673321a 100644 --- a/sys/denali/ahci/command.h +++ b/sys/denali/ahci/command.h @@ -17,8 +17,7 @@ class Command { class DmaReadCommand : public Command { public: - DmaReadCommand(uint64_t lba, uint64_t sector_cnt, Mutex& callback_mutex_, - ResponseContext& reply_port); + DmaReadCommand(uint64_t lba, uint64_t sector_cnt, Mutex& callback_mutex); virtual ~DmaReadCommand() override; @@ -30,7 +29,6 @@ class DmaReadCommand : public Command { z_cap_t GetMemoryRegion() { return region_.cap(); } private: - ResponseContext& response_; uint64_t lba_; uint64_t sector_cnt_; Mutex& callback_mutex_; diff --git a/sys/denali/client/denali_client.cpp b/sys/denali/client/denali_client.cpp deleted file mode 100644 index 9d95f00..0000000 --- a/sys/denali/client/denali_client.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "denali/denali_client.h" - -#include - -#include "denali/denali.h" - -glcr::ErrorOr DenaliClient::ReadSectors( - uint64_t device_id, uint64_t lba, uint64_t num_sectors) { - DenaliReadRequest read{ - .device_id = device_id, - .lba = lba, - .size = num_sectors, - }; - auto pair_or = - endpoint_->CallEndpointGetCap( - read); - if (!pair_or) { - return pair_or.error(); - } - auto pair = pair_or.value(); - - DenaliReadResponse& resp = pair.first(); - z_cap_t& mem_cap = pair.second(); - - return MappedMemoryRegion::FromCapability(mem_cap); -} diff --git a/sys/denali/denali.cpp b/sys/denali/denali.cpp index ad19818..51f2189 100644 --- a/sys/denali/denali.cpp +++ b/sys/denali/denali.cpp @@ -25,14 +25,13 @@ uint64_t main(uint64_t init_port_cap) { ASSIGN_OR_RETURN(glcr::UniquePtr server, DenaliServer::Create(*driver)); - ASSIGN_OR_RETURN(glcr::UniquePtr client, - server->CreateClient()); + ASSIGN_OR_RETURN(DenaliClient client, server->CreateClient()); Thread server_thread = server->RunServer(); RegisterEndpointRequest req; req.set_endpoint_name("denali"); - req.set_endpoint_capability(client->GetCap()); + req.set_endpoint_capability(client.Capability()); check(stub.RegisterEndpoint(req, empty)); check(server_thread.Join()); diff --git a/sys/denali/denali_server.cpp b/sys/denali/denali_server.cpp index a4e9767..c3598cb 100644 --- a/sys/denali/denali_server.cpp +++ b/sys/denali/denali_server.cpp @@ -12,45 +12,22 @@ glcr::ErrorOr> DenaliServer::Create( return glcr::UniquePtr(new DenaliServer(cap, driver)); } -glcr::ErrorCode DenaliServer::HandleRequest(RequestContext& request, - ResponseContext& response) { - switch (request.request_id()) { - case DENALI_READ: { - DenaliReadRequest* req = 0; - glcr::ErrorCode err = request.As(&req); - if (err != glcr::OK) { - response.WriteError(err); - } - err = HandleRead(req, response); - if (err != glcr::OK) { - response.WriteError(err); - } - break; - } - default: - response.WriteError(glcr::UNIMPLEMENTED); - break; - } - return glcr::OK; -} - -glcr::ErrorCode DenaliServer::HandleRead(DenaliReadRequest* request, - ResponseContext& context) { - ASSIGN_OR_RETURN(AhciDevice * device, driver_.GetDevice(request->device_id)); +glcr::ErrorCode DenaliServer::HandleRead(const ReadRequest& req, + ReadResponse& resp) { + ASSIGN_OR_RETURN(AhciDevice * device, driver_.GetDevice(req.device_id())); ASSIGN_OR_RETURN(Mutex mutex, Mutex::Create()); RET_ERR(mutex.Lock()); - DmaReadCommand command(request->lba, request->size, mutex, context); + DmaReadCommand command(req.lba(), req.size(), mutex); device->IssueCommand(&command); // Wait for read operation to complete. RET_ERR(mutex.Lock()); RET_ERR(mutex.Release()); - DenaliReadResponse resp{ - .device_id = request->device_id, - .lba = request->lba, - .size = request->size, - }; - return context.WriteStructWithCap( - resp, command.GetMemoryRegion()); + + resp.set_device_id(req.device_id()); + resp.set_lba(req.lba()); + resp.set_size(req.size()); + resp.set_memory(command.GetMemoryRegion()); + return glcr::OK; } diff --git a/sys/denali/denali_server.h b/sys/denali/denali_server.h index 82c6a85..2dcfacd 100644 --- a/sys/denali/denali_server.h +++ b/sys/denali/denali_server.h @@ -4,15 +4,15 @@ #include #include "ahci/ahci_driver.h" -#include "denali/denali.h" +#include "lib/denali/denali.yunq.server.h" -class DenaliServer : public EndpointServer { +class DenaliServer : public DenaliServerBase { public: static glcr::ErrorOr> Create( AhciDriver& driver); - virtual glcr::ErrorCode HandleRequest(RequestContext& request, - ResponseContext& response) override; + glcr::ErrorCode HandleRead(const ReadRequest& req, + ReadResponse& resp) override; private: static const uint64_t kBuffSize = 1024; @@ -21,8 +21,5 @@ class DenaliServer : public EndpointServer { AhciDriver& driver_; DenaliServer(z_cap_t endpoint_cap, AhciDriver& driver) - : EndpointServer(endpoint_cap), driver_(driver) {} - - glcr::ErrorCode HandleRead(DenaliReadRequest* request, - ResponseContext& context); + : DenaliServerBase(endpoint_cap), driver_(driver) {} }; diff --git a/sys/denali/include/denali/denali.h b/sys/denali/include/denali/denali.h deleted file mode 100644 index 398e68c..0000000 --- a/sys/denali/include/denali/denali.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#define DENALI_INVALID 0 -#define DENALI_READ 100 - -struct DenaliReadRequest { - uint64_t request_type = DENALI_READ; - uint64_t device_id; - - uint64_t lba; - uint64_t size; -}; - -// Will also include a memory capability. -struct DenaliReadResponse { - uint64_t device_id; - uint64_t lba; - uint64_t size; -}; diff --git a/sys/denali/include/denali/denali_client.h b/sys/denali/include/denali/denali_client.h deleted file mode 100644 index 0b4386f..0000000 --- a/sys/denali/include/denali/denali_client.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -#include -#include -#include - -class DenaliClient { - public: - DenaliClient(glcr::UniquePtr endpoint) - : endpoint_(glcr::Move(endpoint)) {} - - glcr::ErrorOr ReadSectors(uint64_t device_id, - uint64_t lba, - uint64_t num_sectors); - - 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/denali/lib/denali/denali.yunq b/sys/denali/lib/denali/denali.yunq new file mode 100644 index 0000000..211c1c8 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq @@ -0,0 +1,16 @@ +interface Denali { + method Read(ReadRequest) -> (ReadResponse); +} + +message ReadRequest { + u64 device_id; + u64 lba; + u64 size; +} + +message ReadResponse { + u64 device_id; + u64 lba; + u64 size; + capability memory; +} diff --git a/sys/denali/lib/denali/denali.yunq.client.cpp b/sys/denali/lib/denali/denali.yunq.client.cpp new file mode 100644 index 0000000..bd6d833 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.client.cpp @@ -0,0 +1,41 @@ +// Generated file - DO NOT MODIFY +#include "denali.yunq.client.h" + +#include +#include +#include + + + + +glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& response) { + uint64_t buffer_size = kBufferSize; + uint64_t cap_size = kCapBufferSize; + + const uint32_t kSentinel = 0xBEEFDEAD; + buffer_.WriteAt(0, kSentinel); + buffer_.WriteAt(8, 0); + + cap_buffer_.Reset(); + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); + + z_cap_t reply_port_cap; + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_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/denali/lib/denali/denali.yunq.client.h b/sys/denali/lib/denali/denali.yunq.client.h new file mode 100644 index 0000000..599bc4a --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.client.h @@ -0,0 +1,28 @@ +// Generated file - DO NOT MODIFY +#pragma once + +#include +#include +#include +#include + +#include "denali.yunq.h" + +class DenaliClient { + public: + DenaliClient(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} + DenaliClient(const DenaliClient&) = delete; + DenaliClient(DenaliClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; + + z_cap_t Capability() { return endpoint_; } + + + [[nodiscard]] glcr::ErrorCode Read(const ReadRequest& request, ReadResponse& 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/denali/lib/denali/denali.yunq.cpp b/sys/denali/lib/denali/denali.yunq.cpp new file mode 100644 index 0000000..3bcb7d5 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.cpp @@ -0,0 +1,146 @@ +// Generated file -- DO NOT MODIFY. +#include "denali.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 ReadRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 0))); + // Parse lba. + set_lba(bytes.At(offset + header_size + (8 * 1))); + // Parse size. + set_size(bytes.At(offset + header_size + (8 * 2))); +} + +void ReadRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 0))); + // Parse lba. + set_lba(bytes.At(offset + header_size + (8 * 1))); + // Parse size. + set_size(bytes.At(offset + header_size + (8 * 2))); +} + +uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 3; + const uint32_t core_size = next_extension; + // Write device_id. + bytes.WriteAt(offset + header_size + (8 * 0), device_id()); + // Write lba. + bytes.WriteAt(offset + header_size + (8 * 1), lba()); + // Write size. + bytes.WriteAt(offset + header_size + (8 * 2), size()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t ReadRequest::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 device_id. + bytes.WriteAt(offset + header_size + (8 * 0), device_id()); + // Write lba. + bytes.WriteAt(offset + header_size + (8 * 1), lba()); + // Write size. + bytes.WriteAt(offset + header_size + (8 * 2), size()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} +void ReadResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 0))); + // Parse lba. + set_lba(bytes.At(offset + header_size + (8 * 1))); + // Parse size. + set_size(bytes.At(offset + header_size + (8 * 2))); + // Parse memory. + // FIXME: Implement in-buffer capabilities for inprocess serialization. + set_memory(0); +} + +void ReadResponse::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse device_id. + set_device_id(bytes.At(offset + header_size + (8 * 0))); + // Parse lba. + set_lba(bytes.At(offset + header_size + (8 * 1))); + // Parse size. + set_size(bytes.At(offset + header_size + (8 * 2))); + // Parse memory. + uint64_t memory_ptr = bytes.At(offset + header_size + (8 * 3)); + + set_memory(caps.At(memory_ptr)); +} + +uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 4; + const uint32_t core_size = next_extension; + // Write device_id. + bytes.WriteAt(offset + header_size + (8 * 0), device_id()); + // Write lba. + bytes.WriteAt(offset + header_size + (8 * 1), lba()); + // Write size. + bytes.WriteAt(offset + header_size + (8 * 2), size()); + // Write memory. + // FIXME: Implement inbuffer capabilities. + bytes.WriteAt(offset + header_size + (8 * 3), 0); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 4; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write device_id. + bytes.WriteAt(offset + header_size + (8 * 0), device_id()); + // Write lba. + bytes.WriteAt(offset + header_size + (8 * 1), lba()); + // Write size. + bytes.WriteAt(offset + header_size + (8 * 2), size()); + // Write memory. + caps.WriteAt(next_cap, memory()); + bytes.WriteAt(offset + header_size + (8 * 3), next_cap++); + + // 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/denali/lib/denali/denali.yunq.h b/sys/denali/lib/denali/denali.yunq.h new file mode 100644 index 0000000..7b3187c --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.h @@ -0,0 +1,58 @@ +// Generated file - DO NOT MODIFY +#pragma once + +#include +#include +#include +#include +class ReadRequest { + public: + ReadRequest() {} + // Delete copy and move until implemented. + ReadRequest(const ReadRequest&) = delete; + ReadRequest(ReadRequest&&) = 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; + uint64_t device_id() const { return device_id_; } + void set_device_id(const uint64_t& value) { device_id_ = value; } + uint64_t lba() const { return lba_; } + void set_lba(const uint64_t& value) { lba_ = value; } + uint64_t size() const { return size_; } + void set_size(const uint64_t& value) { size_ = value; } + + private: + uint64_t device_id_; + uint64_t lba_; + uint64_t size_; + +}; +class ReadResponse { + public: + ReadResponse() {} + // Delete copy and move until implemented. + ReadResponse(const ReadResponse&) = delete; + ReadResponse(ReadResponse&&) = 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; + uint64_t device_id() const { return device_id_; } + void set_device_id(const uint64_t& value) { device_id_ = value; } + uint64_t lba() const { return lba_; } + void set_lba(const uint64_t& value) { lba_ = value; } + uint64_t size() const { return size_; } + void set_size(const uint64_t& value) { size_ = value; } + z_cap_t memory() const { return memory_; } + void set_memory(const z_cap_t& value) { memory_ = value; } + + private: + uint64_t device_id_; + uint64_t lba_; + uint64_t size_; + z_cap_t memory_; + +}; \ No newline at end of file diff --git a/sys/denali/lib/denali/denali.yunq.server.cpp b/sys/denali/lib/denali/denali.yunq.server.cpp new file mode 100644 index 0000000..af1ed35 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.server.cpp @@ -0,0 +1,104 @@ +// Generated file -- DO NOT MODIFY. +#include "denali.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 DenaliServerBaseThreadBootstrap(void* server_base) { + ((DenaliServerBase*)server_base)->ServerThread(); +} + +glcr::ErrorOr DenaliServerBase::CreateClient() { + uint64_t client_cap; + // FIXME: Restrict permissions to send-only here. + RET_ERR(ZCapDuplicate(endpoint_, &client_cap)); + return DenaliClient(client_cap); +} + +Thread DenaliServerBase::RunServer() { + return Thread(DenaliServerBaseThreadBootstrap, this); +} + +void DenaliServerBase::ServerThread() { + glcr::ByteBuffer recv_buffer(0x1000); + glcr::CapBuffer recv_cap(0x10); + glcr::ByteBuffer resp_buffer(0x1000); + glcr::CapBuffer resp_cap(0x10); + z_cap_t reply_port_cap; + + while (true) { + uint64_t recv_cap_size = 0x10; + uint64_t recv_buf_size = 0x1000; + glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &recv_cap_size, recv_cap.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, recv_cap, 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 DenaliServerBase::HandleRequest(const glcr::ByteBuffer& request, + const glcr::CapBuffer& req_caps, + 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: { + ReadRequest yunq_request; + ReadResponse yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); + + RET_ERR(HandleRead(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/denali/lib/denali/denali.yunq.server.h b/sys/denali/lib/denali/denali.yunq.server.h new file mode 100644 index 0000000..7fd6723 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.server.h @@ -0,0 +1,37 @@ +// Generated File -- DO NOT MODIFY. +#pragma once + +#include +#include +#include + +#include "denali.yunq.h" +#include "denali.yunq.client.h" + + + +class DenaliServerBase { + public: + DenaliServerBase(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} + DenaliServerBase(const DenaliServerBase&) = delete; + DenaliServerBase(DenaliServerBase&&) = delete; + + glcr::ErrorOr CreateClient(); + + [[nodiscard]] Thread RunServer(); + + + [[nodiscard]] virtual glcr::ErrorCode HandleRead(const ReadRequest&, ReadResponse&) = 0; + + + private: + z_cap_t endpoint_; + + friend void DenaliServerBaseThreadBootstrap(void*); + void ServerThread(); + + [[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, const glcr::CapBuffer& req_caps, + glcr::ByteBuffer& response, uint64_t& resp_length, + glcr::CapBuffer& resp_caps); +}; + diff --git a/sys/denali/lib/denali/scoped_denali_client.h b/sys/denali/lib/denali/scoped_denali_client.h new file mode 100644 index 0000000..f122320 --- /dev/null +++ b/sys/denali/lib/denali/scoped_denali_client.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +#include "denali.yunq.client.h" + +class ScopedDenaliClient : protected DenaliClient { + public: + ScopedDenaliClient(z_cap_t endpoint_cap, uint64_t device_id, + uint64_t lba_offset) + : DenaliClient(endpoint_cap), + device_id_(device_id), + lba_offset_(lba_offset) {} + + glcr::ErrorOr ReadSectors(uint64_t lba, + uint64_t num_sectors) { + ReadRequest req; + req.set_device_id(device_id_); + req.set_lba(lba_offset_ + lba); + req.set_size(num_sectors); + + ReadResponse resp; + RET_ERR(DenaliClient::Read(req, resp)); + + return MappedMemoryRegion::FromCapability(resp.memory()); + } + + private: + uint64_t device_id_; + uint64_t lba_offset_; +}; diff --git a/sys/victoriafalls/CMakeLists.txt b/sys/victoriafalls/CMakeLists.txt index 380abef..e5e91e9 100644 --- a/sys/victoriafalls/CMakeLists.txt +++ b/sys/victoriafalls/CMakeLists.txt @@ -9,6 +9,7 @@ target_include_directories(victoriafalls "${CMAKE_CURRENT_SOURCE_DIR}/include") target_link_libraries(victoriafalls + denali_yunq glacier mammoth yellowstone_yunq diff --git a/sys/victoriafalls/fs/ext2/ext2_block_reader.h b/sys/victoriafalls/fs/ext2/ext2_block_reader.h index f149d8d..b2113cb 100644 --- a/sys/victoriafalls/fs/ext2/ext2_block_reader.h +++ b/sys/victoriafalls/fs/ext2/ext2_block_reader.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include diff --git a/sys/victoriafalls/fs/ext2/ext2_driver.h b/sys/victoriafalls/fs/ext2/ext2_driver.h index 77fe877..ee8fe7d 100644 --- a/sys/victoriafalls/fs/ext2/ext2_driver.h +++ b/sys/victoriafalls/fs/ext2/ext2_driver.h @@ -1,7 +1,8 @@ #pragma once -#include +#include #include +#include #include "fs/ext2/ext2.h" #include "fs/ext2/ext2_block_reader.h" diff --git a/sys/victoriafalls/victoriafalls.cpp b/sys/victoriafalls/victoriafalls.cpp index c071851..4bd7442 100644 --- a/sys/victoriafalls/victoriafalls.cpp +++ b/sys/victoriafalls/victoriafalls.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -14,9 +15,8 @@ uint64_t main(uint64_t init_cap) { 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()); + ScopedDenaliClient denali(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 06fbdfd..84124d6 100644 --- a/sys/yellowstone/CMakeLists.txt +++ b/sys/yellowstone/CMakeLists.txt @@ -9,9 +9,9 @@ target_include_directories(yellowstone PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(yellowstone + denali_yunq mammoth glacier - denali_stub yellowstone_yunq ) @@ -31,7 +31,6 @@ target_include_directories(yellowstone_yunq PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/lib") target_link_libraries(yellowstone_yunq - denali_stub mammoth ) diff --git a/sys/yellowstone/hw/gpt.cpp b/sys/yellowstone/hw/gpt.cpp index 3b98811..7266102 100644 --- a/sys/yellowstone/hw/gpt.cpp +++ b/sys/yellowstone/hw/gpt.cpp @@ -1,7 +1,9 @@ #include "hw/gpt.h" +#include #include #include +#include #include #include @@ -54,8 +56,14 @@ GptReader::GptReader(glcr::UniquePtr denali) : denali_(glcr::Move(denali)) {} glcr::ErrorCode GptReader::ParsePartitionTables() { - ASSIGN_OR_RETURN(MappedMemoryRegion lba_1_and_2, - denali_->ReadSectors(0, 0, 2)); + ReadRequest req; + req.set_device_id(0); + req.set_lba(0); + req.set_size(2); + ReadResponse resp; + RET_ERR(denali_->Read(req, resp)); + MappedMemoryRegion lba_1_and_2 = + MappedMemoryRegion::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); @@ -89,9 +97,12 @@ glcr::ErrorCode GptReader::ParsePartitionTables() { dbgln("partition_entry_size: %x", entry_size); dbgln("Num blocks: %x", num_blocks); - ASSIGN_OR_RETURN( - MappedMemoryRegion part_table, - denali_->ReadSectors(0, header->lba_partition_entries, num_blocks)); + req.set_device_id(0); + 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()); dbgln("Entries"); for (uint64_t i = 0; i < num_partitions; i++) { PartitionEntry* entry = reinterpret_cast( @@ -102,9 +113,10 @@ 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. + // 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 1a845ad..90cb279 100644 --- a/sys/yellowstone/hw/gpt.h +++ b/sys/yellowstone/hw/gpt.h @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include #include #include diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index 94db660..28e115e 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -1,6 +1,6 @@ #include "yellowstone_server.h" -#include +#include #include #include #include @@ -18,8 +18,8 @@ struct PartitionInfo { }; glcr::ErrorOr HandleDenaliRegistration(z_cap_t endpoint_cap) { - GptReader reader(glcr::UniquePtr( - new DenaliClient(EndpointClient::AdoptEndpoint(endpoint_cap)))); + GptReader reader( + glcr::UniquePtr(new DenaliClient(endpoint_cap))); RET_ERR(reader.ParsePartitionTables());