[Denali] Move denali server to yunq.

This commit is contained in:
Drew Galbraith 2023-10-25 20:28:28 -07:00
parent acfaf26391
commit 3e4fdfee84
25 changed files with 526 additions and 163 deletions

View File

@ -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}"
)

View File

@ -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);
}

View File

@ -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_;

View File

@ -1,26 +0,0 @@
#include "denali/denali_client.h"
#include <mammoth/debug.h>
#include "denali/denali.h"
glcr::ErrorOr<MappedMemoryRegion> 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<DenaliReadRequest, DenaliReadResponse>(
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);
}

View File

@ -25,14 +25,13 @@ uint64_t main(uint64_t init_port_cap) {
ASSIGN_OR_RETURN(glcr::UniquePtr<DenaliServer> server,
DenaliServer::Create(*driver));
ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> 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());

View File

@ -12,45 +12,22 @@ glcr::ErrorOr<glcr::UniquePtr<DenaliServer>> DenaliServer::Create(
return glcr::UniquePtr<DenaliServer>(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<DenaliReadRequest>(&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<DenaliReadResponse>(
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;
}

View File

@ -4,15 +4,15 @@
#include <mammoth/endpoint_server.h>
#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<glcr::UniquePtr<DenaliServer>> 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) {}
};

View File

@ -1,21 +0,0 @@
#pragma once
#include <stdint.h>
#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;
};

View File

@ -1,37 +0,0 @@
#pragma once
#include <glacier/status/error_or.h>
#include <mammoth/endpoint_client.h>
#include <mammoth/memory_region.h>
class DenaliClient {
public:
DenaliClient(glcr::UniquePtr<EndpointClient> endpoint)
: endpoint_(glcr::Move(endpoint)) {}
glcr::ErrorOr<MappedMemoryRegion> ReadSectors(uint64_t device_id,
uint64_t lba,
uint64_t num_sectors);
private:
glcr::UniquePtr<EndpointClient> endpoint_;
};
class ScopedDenaliClient : protected DenaliClient {
public:
ScopedDenaliClient(glcr::UniquePtr<EndpointClient> endpoint,
uint64_t device_id, uint64_t lba_offset)
: DenaliClient(glcr::Move(endpoint)),
device_id_(device_id),
lba_offset_(lba_offset) {}
glcr::ErrorOr<MappedMemoryRegion> 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_;
};

View File

@ -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;
}

View File

@ -0,0 +1,41 @@
// Generated file - DO NOT MODIFY
#include "denali.yunq.client.h"
#include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h>
#include <zcall.h>
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<uint32_t>(0, kSentinel);
buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(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<uint32_t>(0) != kSentinel) {
return glcr::INVALID_RESPONSE;
}
// Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK;
}

View File

@ -0,0 +1,28 @@
// Generated file - DO NOT MODIFY
#pragma once
#include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h>
#include <glacier/status/error.h>
#include <ztypes.h>
#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};
};

View File

@ -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<uint32_t>(offset + 0, 0xDEADBEEF); // TODO: Chose a more unique ident sequence.
bytes.WriteAt<uint32_t>(offset + 4, core_size);
bytes.WriteAt<uint32_t>(offset + 8, extension_size);
bytes.WriteAt<uint32_t>(offset + 12, 0); // TODO: Calculate CRC32.
bytes.WriteAt<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0)));
// Parse lba.
set_lba(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
// Parse size.
set_size(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
// Parse memory.
uint64_t memory_ptr = bytes.At<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), size());
// Write memory.
// FIXME: Implement inbuffer capabilities.
bytes.WriteAt<uint64_t>(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<uint64_t>(offset + header_size + (8 * 0), device_id());
// Write lba.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), lba());
// Write size.
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), size());
// Write memory.
caps.WriteAt(next_cap, memory());
bytes.WriteAt<uint64_t>(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;
}

View File

@ -0,0 +1,58 @@
// Generated file - DO NOT MODIFY
#pragma once
#include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h>
#include <glacier/string/string.h>
#include <ztypes.h>
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_;
};

View File

@ -0,0 +1,104 @@
// Generated file -- DO NOT MODIFY.
#include "denali.yunq.server.h"
#include <mammoth/debug.h>
#include <zcall.h>
namespace {
const uint32_t kSentinel = 0xBEEFDEAD;
const uint32_t kHeaderSize = 0x10;
void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) {
buffer.WriteAt<uint32_t>(0, kSentinel);
buffer.WriteAt<uint32_t>(4, kHeaderSize);
buffer.WriteAt<uint64_t>(8, err);
}
void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) {
buffer.WriteAt<uint32_t>(0, kSentinel);
buffer.WriteAt<uint32_t>(4, kHeaderSize + message_length);
buffer.WriteAt<uint64_t>(8, glcr::OK);
}
} // namespace
void DenaliServerBaseThreadBootstrap(void* server_base) {
((DenaliServerBase*)server_base)->ServerThread();
}
glcr::ErrorOr<DenaliClient> 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<uint32_t>(0) != kSentinel) {
return glcr::INVALID_ARGUMENT;
}
uint64_t method_select = request.At<uint64_t>(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;
}

View File

@ -0,0 +1,37 @@
// Generated File -- DO NOT MODIFY.
#pragma once
#include <glacier/status/error_or.h>
#include <mammoth/thread.h>
#include <ztypes.h>
#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<DenaliClient> 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);
};

View File

@ -0,0 +1,32 @@
#pragma once
#include <glacier/status/error_or.h>
#include <mammoth/memory_region.h>
#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<MappedMemoryRegion> 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_;
};

View File

@ -9,6 +9,7 @@ target_include_directories(victoriafalls
"${CMAKE_CURRENT_SOURCE_DIR}/include")
target_link_libraries(victoriafalls
denali_yunq
glacier
mammoth
yellowstone_yunq

View File

@ -1,6 +1,6 @@
#pragma once
#include <denali/denali_client.h>
#include <denali/scoped_denali_client.h>
#include <glacier/memory/shared_ptr.h>
#include <glacier/status/error_or.h>
#include <mammoth/memory_region.h>

View File

@ -1,7 +1,8 @@
#pragma once
#include <denali/denali_client.h>
#include <denali/scoped_denali_client.h>
#include <glacier/memory/move.h>
#include <glacier/memory/unique_ptr.h>
#include "fs/ext2/ext2.h"
#include "fs/ext2/ext2_block_reader.h"

View File

@ -1,3 +1,4 @@
#include <denali/scoped_denali_client.h>
#include <mammoth/debug.h>
#include <mammoth/init.h>
#include <yellowstone/yellowstone.yunq.client.h>
@ -14,8 +15,7 @@ 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()),
ScopedDenaliClient denali(denali_info.denali_endpoint(),
denali_info.device_id(), denali_info.lba_offset());
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));

View File

@ -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
)

View File

@ -1,7 +1,9 @@
#include "hw/gpt.h"
#include <glacier/memory/move.h>
#include <glacier/status/error.h>
#include <mammoth/debug.h>
#include <mammoth/memory_region.h>
#include <zcall.h>
#include <zglobal.h>
@ -54,8 +56,14 @@ GptReader::GptReader(glcr::UniquePtr<DenaliClient> 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<uint16_t*>(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<PartitionEntry*>(
@ -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;

View File

@ -1,6 +1,8 @@
#pragma once
#include <denali/denali_client.h>
#include <denali/denali.yunq.client.h>
#include <glacier/memory/unique_ptr.h>
#include <glacier/status/error.h>
#include <stdint.h>
#include <ztypes.h>

View File

@ -1,6 +1,6 @@
#include "yellowstone_server.h"
#include <denali/denali.h>
#include <denali/denali.yunq.client.h>
#include <glacier/string/string.h>
#include <mammoth/debug.h>
#include <mammoth/init.h>
@ -18,8 +18,8 @@ struct PartitionInfo {
};
glcr::ErrorOr<PartitionInfo> HandleDenaliRegistration(z_cap_t endpoint_cap) {
GptReader reader(glcr::UniquePtr<DenaliClient>(
new DenaliClient(EndpointClient::AdoptEndpoint(endpoint_cap))));
GptReader reader(
glcr::UniquePtr<DenaliClient>(new DenaliClient(endpoint_cap)));
RET_ERR(reader.ParsePartitionTables());