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..09e6f6a --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.client.cpp @@ -0,0 +1,100 @@ +// Generated file - DO NOT MODIFY +#include "denali.yunq.client.h" + +#include +#include +#include +#include + + + + +DenaliClient::~DenaliClient() { + if (endpoint_ != 0) { + check(ZCapRelease(endpoint_)); + } +} + + + + +glcr::Status 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::InvalidResponse("Got an invalid response from server."); + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + + yunq::MessageView resp_view(buffer_, 16); + RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); + + + return glcr::OK; +} + + + + +glcr::Status DenaliClient::ReadMany(const ReadManyRequest& 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, 1); + + 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::InvalidResponse("Got an invalid response from server."); + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + + yunq::MessageView resp_view(buffer_, 16); + RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_)); + + + return glcr::OK; +} + + + + diff --git a/sys/denali/lib/denali/denali.yunq.cpp b/sys/denali/lib/denali/denali.yunq.cpp new file mode 100644 index 0000000..de259cc --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.cpp @@ -0,0 +1,186 @@ +// Generated file -- DO NOT MODIFY. +#include "denali.yunq.h" + +#include +#include + + +namespace { + +const uint64_t header_size = 24; // 4x uint32, 1x uint64 + +struct ExtPointer { + uint32_t offset; + uint32_t length; +}; + +} // namespace +glcr::Status DiskBlock::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status DiskBlock::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status DiskBlock::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse lba. + ASSIGN_OR_RETURN(lba_, message.ReadField(0)); + // Parse size. + ASSIGN_OR_RETURN(size_, message.ReadField(1)); + + return glcr::Status::Ok(); +} + +uint64_t DiskBlock::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 2); + return SerializeInternal(serializer); +} + +uint64_t DiskBlock::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 2, caps); + return SerializeInternal(serializer); +} + +uint64_t DiskBlock::SerializeInternal(yunq::Serializer& serializer) const { + // Write lba. + serializer.WriteField(0, lba_); + // Write size. + serializer.WriteField(1, size_); + + serializer.WriteHeader(); + + return serializer.size(); +} +glcr::Status ReadRequest::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status ReadRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status ReadRequest::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse device_id. + ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); + // Parse block. + message.ReadMessage(1, block_); + + return glcr::Status::Ok(); +} + +uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 2); + return SerializeInternal(serializer); +} + +uint64_t ReadRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 2, caps); + return SerializeInternal(serializer); +} + +uint64_t ReadRequest::SerializeInternal(yunq::Serializer& serializer) const { + // Write device_id. + serializer.WriteField(0, device_id_); + // Write block. + serializer.WriteMessage(1, block_); + + serializer.WriteHeader(); + + return serializer.size(); +} +glcr::Status ReadManyRequest::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status ReadManyRequest::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + return glcr::Status::Ok(); +} + +glcr::Status ReadManyRequest::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse device_id. + ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); + // Parse blocks. + message.ReadRepeatedMessage(1, blocks_); + + + return glcr::Status::Ok(); +} + +uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 2); + return SerializeInternal(serializer); +} + +uint64_t ReadManyRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 2, caps); + return SerializeInternal(serializer); +} + +uint64_t ReadManyRequest::SerializeInternal(yunq::Serializer& serializer) const { + // Write device_id. + serializer.WriteField(0, device_id_); + // Write blocks. + serializer.WriteRepeatedMessage(1, blocks_); + + serializer.WriteHeader(); + + return serializer.size(); +} +glcr::Status ReadResponse::ParseFromBytes(const yunq::MessageView& message) { + RETURN_ERROR(ParseFromBytesInternal(message)); + // Parse memory. + ASSIGN_OR_RETURN(memory_, message.ReadCapability(2)); + return glcr::Status::Ok(); +} + +glcr::Status ReadResponse::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) { + RETURN_ERROR(ParseFromBytesInternal(message)); + // Parse memory. + ASSIGN_OR_RETURN(memory_, message.ReadCapability(2, caps)); + return glcr::Status::Ok(); +} + +glcr::Status ReadResponse::ParseFromBytesInternal(const yunq::MessageView& message) { + RETURN_ERROR(message.CheckHeader()); + // Parse device_id. + ASSIGN_OR_RETURN(device_id_, message.ReadField(0)); + // Parse size. + ASSIGN_OR_RETURN(size_, message.ReadField(1)); + // Parse memory. + + return glcr::Status::Ok(); +} + +uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + yunq::Serializer serializer(bytes, offset, 3); + return SerializeInternal(serializer); +} + +uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + yunq::Serializer serializer(bytes, offset, 3, caps); + return SerializeInternal(serializer); +} + +uint64_t ReadResponse::SerializeInternal(yunq::Serializer& serializer) const { + // Write device_id. + serializer.WriteField(0, device_id_); + // Write size. + serializer.WriteField(1, size_); + // Write memory. + serializer.WriteCapability(2, memory_); + + serializer.WriteHeader(); + + return serializer.size(); +} + 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..4fe21f5 --- /dev/null +++ b/sys/denali/lib/denali/denali.yunq.server.cpp @@ -0,0 +1,152 @@ +// 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(); +} + +DenaliServerBase::~DenaliServerBase() { + if (endpoint_ != 0) { + check(ZCapRelease(endpoint_)); + } +} + +glcr::ErrorOr DenaliServerBase::CreateClientCap() { + uint64_t client_cap; + RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); + return client_cap; +} + +glcr::ErrorOr DenaliServerBase::CreateClient() { + uint64_t client_cap; + RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &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; + recv_cap.Reset(); + glcr::ErrorCode recv_err = static_cast(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; + resp_cap.Reset(); + glcr::Status err = HandleRequest(recv_buffer, recv_cap, resp_buffer, resp_length, resp_cap); + if (!err) { + WriteError(resp_buffer, err.code()); + dbgln("Responding Error {}", err.message()); + reply_err = static_cast(ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr)); + } else { + WriteHeader(resp_buffer, resp_length); + reply_err = static_cast(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}", reply_err); + } + } + +} + +glcr::Status 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::InvalidArgument("Request Not Valid"); + } + + uint64_t method_select = request.At(8); + + switch(method_select) { + case 0: { + + + ReadRequest yunq_request; + yunq::MessageView request_view(request, kHeaderSize); + RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); + + + + ReadResponse yunq_response; + + + + RETURN_ERROR(HandleRead(yunq_request, yunq_response)); + + + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + + break; + } + case 1: { + + + ReadManyRequest yunq_request; + yunq::MessageView request_view(request, kHeaderSize); + RETURN_ERROR(yunq_request.ParseFromBytes(request_view, req_caps)); + + + + ReadResponse yunq_response; + + + + RETURN_ERROR(HandleReadMany(yunq_request, yunq_response)); + + + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + + break; + } + default: { + return glcr::Unimplemented("Method unimplemented by server."); + } + } + return glcr::Status::Ok(); +} + + diff --git a/zion/CMakeLists.txt b/zion/CMakeLists.txt index e42ee29..598a3de 100644 --- a/zion/CMakeLists.txt +++ b/zion/CMakeLists.txt @@ -99,3 +99,10 @@ add_library(zion_stub STATIC target_include_directories(zion_stub PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(zion_stub + PROPERTIES + COMPILE_FLAGS "${BASE_COMPILE_FLAGS} -nostdlib -c" + LINK_FLAGS "${BASE_LINK_FLAGS} -nostartfiles -static -lgcc" + ) +