Compare commits

...

11 Commits

63 changed files with 783 additions and 274 deletions

View File

@ -3,6 +3,7 @@
#include <glacier/string/str_split.h> #include <glacier/string/str_split.h>
#include <victoriafalls/victoriafalls.yunq.client.h> #include <victoriafalls/victoriafalls.yunq.client.h>
#include <yellowstone/yellowstone.yunq.client.h> #include <yellowstone/yellowstone.yunq.client.h>
#include <zcall.h>
#include <zglobal.h> #include <zglobal.h>
#include "util/debug.h" #include "util/debug.h"
@ -10,11 +11,19 @@
namespace mmth { namespace mmth {
namespace { namespace {
using yellowstone::Endpoint;
using yellowstone::GetEndpointRequest;
using yellowstone::YellowstoneClient;
VFSClient* gVfsClient = nullptr; VFSClient* gVfsClient = nullptr;
void GetVfsClientIfNeeded() { void GetVfsClientIfNeeded() {
if (gVfsClient == nullptr) { if (gVfsClient == nullptr) {
YellowstoneClient client(gInitEndpointCap); // TODO: Add an unowned client so we don't have to duplicate this cap every
// time.
uint64_t dup_cap;
check(ZCapDuplicate(gInitEndpointCap, kZionPerm_All, &dup_cap));
YellowstoneClient client(dup_cap);
GetEndpointRequest yreq; GetEndpointRequest yreq;
yreq.set_endpoint_name("victoriafalls"); yreq.set_endpoint_name("victoriafalls");

View File

@ -9,6 +9,10 @@
namespace mmth { namespace mmth {
namespace { namespace {
using yellowstone::Endpoint;
using yellowstone::GetEndpointRequest;
using yellowstone::YellowstoneClient;
void KeyboardListenerEntry(void* keyboard_base) { void KeyboardListenerEntry(void* keyboard_base) {
reinterpret_cast<KeyboardListenerBase*>(keyboard_base)->ListenLoop(); reinterpret_cast<KeyboardListenerBase*>(keyboard_base)->ListenLoop();
} }
@ -24,7 +28,9 @@ KeyboardListenerBase::KeyboardListenerBase() {
} }
void KeyboardListenerBase::Register() { void KeyboardListenerBase::Register() {
YellowstoneClient client(gInitEndpointCap); uint64_t dup_cap;
check(ZCapDuplicate(gInitEndpointCap, kZionPerm_All, &dup_cap));
YellowstoneClient client(dup_cap);
GetEndpointRequest req; GetEndpointRequest req;
req.set_endpoint_name("voyageurs"); req.set_endpoint_name("voyageurs");
@ -40,8 +46,7 @@ void KeyboardListenerBase::Register() {
crash("Failed to create client", client_or.error()); crash("Failed to create client", client_or.error());
} }
listn.set_port_capability(client_or.value().cap()); listn.set_port_capability(client_or.value().cap());
None n; check(vclient.RegisterKeyboardListener(listn));
check(vclient.RegisterKeyboardListener(listn, n));
} }
Thread KeyboardListenerBase::Listen() { Thread KeyboardListenerBase::Listen() {

View File

@ -7,13 +7,16 @@
#include "ahci/ahci_driver.h" #include "ahci/ahci_driver.h"
#include "denali_server.h" #include "denali_server.h"
using yellowstone::AhciInfo;
using yellowstone::RegisterEndpointRequest;
using yellowstone::YellowstoneClient;
uint64_t main(uint64_t init_port_cap) { uint64_t main(uint64_t init_port_cap) {
check(ParseInitPort(init_port_cap)); check(ParseInitPort(init_port_cap));
YellowstoneClient stub(gInitEndpointCap); YellowstoneClient stub(gInitEndpointCap);
Empty empty;
AhciInfo ahci; AhciInfo ahci;
RET_ERR(stub.GetAhciInfo(empty, ahci)); RET_ERR(stub.GetAhciInfo(ahci));
mmth::OwnedMemoryRegion ahci_region = mmth::OwnedMemoryRegion ahci_region =
mmth::OwnedMemoryRegion::FromCapability(ahci.ahci_region()); mmth::OwnedMemoryRegion::FromCapability(ahci.ahci_region());
ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(glcr::Move(ahci_region))); ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(glcr::Move(ahci_region)));
@ -21,14 +24,13 @@ uint64_t main(uint64_t init_port_cap) {
ASSIGN_OR_RETURN(glcr::UniquePtr<DenaliServer> server, ASSIGN_OR_RETURN(glcr::UniquePtr<DenaliServer> server,
DenaliServer::Create(*driver)); DenaliServer::Create(*driver));
ASSIGN_OR_RETURN(DenaliClient client, server->CreateClient());
Thread server_thread = server->RunServer(); Thread server_thread = server->RunServer();
RegisterEndpointRequest req; RegisterEndpointRequest req;
req.set_endpoint_name("denali"); req.set_endpoint_name("denali");
req.set_endpoint_capability(client.Capability()); ASSIGN_OR_RETURN(z_cap_t client_cap, server->CreateClientCap());
check(stub.RegisterEndpoint(req, empty)); req.set_endpoint_capability(client_cap);
check(stub.RegisterEndpoint(req));
check(server_thread.Join()); check(server_thread.Join());
return 0; return 0;

View File

@ -3,12 +3,23 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
DenaliClient::~DenaliClient() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& response) { glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +28,10 @@ glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& res
buffer_.WriteAt<uint64_t>(8, 0); buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,14 +47,18 @@ glcr::ErrorCode DenaliClient::Read(const ReadRequest& request, ReadResponse& res
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode DenaliClient::ReadMany(const ReadManyRequest& request, ReadResponse& response) { glcr::ErrorCode DenaliClient::ReadMany(const ReadManyRequest& request, ReadResponse& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -49,7 +67,10 @@ glcr::ErrorCode DenaliClient::ReadMany(const ReadManyRequest& request, ReadRespo
buffer_.WriteAt<uint64_t>(8, 1); buffer_.WriteAt<uint64_t>(8, 1);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -65,9 +86,13 @@ glcr::ErrorCode DenaliClient::ReadMany(const ReadManyRequest& request, ReadRespo
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }

View File

@ -8,18 +8,24 @@
#include "denali.yunq.h" #include "denali.yunq.h"
class DenaliClient { class DenaliClient {
public: public:
DenaliClient(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} DenaliClient(z_cap_t Denali_cap) : endpoint_(Denali_cap) {}
DenaliClient(const DenaliClient&) = delete; DenaliClient(const DenaliClient&) = delete;
DenaliClient(DenaliClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; DenaliClient(DenaliClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~DenaliClient();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
[[nodiscard]] glcr::ErrorCode Read(const ReadRequest& request, ReadResponse& response); [[nodiscard]] glcr::ErrorCode Read(const ReadRequest& request, ReadResponse& response);
[[nodiscard]] glcr::ErrorCode ReadMany(const ReadManyRequest& request, ReadResponse& response); [[nodiscard]] glcr::ErrorCode ReadMany(const ReadManyRequest& request, ReadResponse& response);
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -28,3 +34,4 @@ class DenaliClient {
uint64_t kCapBufferSize = 0x10; uint64_t kCapBufferSize = 0x10;
glcr::CapBuffer cap_buffer_{kCapBufferSize}; glcr::CapBuffer cap_buffer_{kCapBufferSize};
}; };

View File

@ -1,6 +1,7 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "denali.yunq.h" #include "denali.yunq.h"
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -248,4 +249,5 @@ uint64_t ReadResponse::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset
WriteHeader(bytes, offset, core_size, next_extension); WriteHeader(bytes, offset, core_size, next_extension);
return next_extension; return next_extension;
} }

View File

@ -6,6 +6,8 @@
#include <glacier/container/vector.h> #include <glacier/container/vector.h>
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
class ReadRequest { class ReadRequest {
public: public:
ReadRequest() {} ReadRequest() {}
@ -83,4 +85,5 @@ class ReadResponse {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };

View File

@ -4,6 +4,7 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +30,18 @@ void DenaliServerBaseThreadBootstrap(void* server_base) {
((DenaliServerBase*)server_base)->ServerThread(); ((DenaliServerBase*)server_base)->ServerThread();
} }
DenaliServerBase::~DenaliServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> DenaliServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<DenaliClient> DenaliServerBase::CreateClient() { glcr::ErrorOr<DenaliClient> DenaliServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -87,25 +100,43 @@ glcr::ErrorCode DenaliServerBase::HandleRequest(const glcr::ByteBuffer& request,
switch(method_select) { switch(method_select) {
case 0: { case 0: {
ReadRequest yunq_request; ReadRequest yunq_request;
ReadResponse yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
ReadResponse yunq_response;
RET_ERR(HandleRead(yunq_request, yunq_response)); RET_ERR(HandleRead(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
case 1: { case 1: {
ReadManyRequest yunq_request; ReadManyRequest yunq_request;
ReadResponse yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
ReadResponse yunq_response;
RET_ERR(HandleReadMany(yunq_request, yunq_response)); RET_ERR(HandleReadMany(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
default: { default: {
@ -114,3 +145,5 @@ glcr::ErrorCode DenaliServerBase::HandleRequest(const glcr::ByteBuffer& request,
} }
return glcr::OK; return glcr::OK;
} }

View File

@ -10,22 +10,30 @@
class DenaliServerBase { class DenaliServerBase {
public: public:
DenaliServerBase(z_cap_t Denali_cap) : endpoint_(Denali_cap) {} DenaliServerBase(z_cap_t Denali_cap) : endpoint_(Denali_cap) {}
DenaliServerBase(const DenaliServerBase&) = delete; DenaliServerBase(const DenaliServerBase&) = delete;
DenaliServerBase(DenaliServerBase&&) = delete; DenaliServerBase(DenaliServerBase&&) = delete;
virtual ~DenaliServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<DenaliClient> CreateClient(); glcr::ErrorOr<DenaliClient> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
[[nodiscard]] virtual glcr::ErrorCode HandleRead(const ReadRequest&, ReadResponse&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleRead(const ReadRequest&, ReadResponse&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleReadMany(const ReadManyRequest&, ReadResponse&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleReadMany(const ReadManyRequest&, ReadResponse&) = 0;
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -37,3 +45,5 @@ class DenaliServerBase {
glcr::CapBuffer& resp_caps); glcr::CapBuffer& resp_caps);
}; };

View File

@ -1,6 +1,6 @@
#include "framebuffer/framebuffer.h" #include "framebuffer/framebuffer.h"
Framebuffer::Framebuffer(const FramebufferInfo& info) Framebuffer::Framebuffer(const yellowstone::FramebufferInfo& info)
: fb_info_(info), cursor_pos_(0) { : fb_info_(info), cursor_pos_(0) {
uint64_t buff_size_bytes = fb_info_.height() * fb_info_.pitch(); uint64_t buff_size_bytes = fb_info_.height() * fb_info_.pitch();
fb_memory_ = mmth::OwnedMemoryRegion::DirectPhysical(fb_info_.address_phys(), fb_memory_ = mmth::OwnedMemoryRegion::DirectPhysical(fb_info_.address_phys(),

View File

@ -5,7 +5,7 @@
class Framebuffer { class Framebuffer {
public: public:
Framebuffer(const FramebufferInfo& info); Framebuffer(const yellowstone::FramebufferInfo& info);
void DrawPixel(uint32_t row, uint32_t col, uint32_t pixel); void DrawPixel(uint32_t row, uint32_t col, uint32_t pixel);
@ -17,7 +17,7 @@ class Framebuffer {
private: private:
// FIXME: Implement Yunq copy or move so we // FIXME: Implement Yunq copy or move so we
// don't have to store a reference here. // don't have to store a reference here.
const FramebufferInfo& fb_info_; const yellowstone::FramebufferInfo& fb_info_;
mmth::OwnedMemoryRegion fb_memory_; mmth::OwnedMemoryRegion fb_memory_;
uint32_t* fb_; uint32_t* fb_;

View File

@ -9,6 +9,9 @@
#include "framebuffer/psf.h" #include "framebuffer/psf.h"
#include "terminal.h" #include "terminal.h"
using yellowstone::FramebufferInfo;
using yellowstone::YellowstoneClient;
uint64_t main(uint64_t init_port) { uint64_t main(uint64_t init_port) {
ParseInitPort(init_port); ParseInitPort(init_port);
@ -18,7 +21,7 @@ uint64_t main(uint64_t init_port) {
YellowstoneClient client(gInitEndpointCap); YellowstoneClient client(gInitEndpointCap);
FramebufferInfo framebuffer; FramebufferInfo framebuffer;
RET_ERR(client.GetFramebufferInfo({}, framebuffer)); RET_ERR(client.GetFramebufferInfo(framebuffer));
dbgln("FB addr {x}, bpp {}, width {} , height {}, pitch {}", dbgln("FB addr {x}, bpp {}, width {} , height {}, pitch {}",
framebuffer.address_phys(), framebuffer.bpp(), framebuffer.width(), framebuffer.address_phys(), framebuffer.bpp(), framebuffer.width(),
framebuffer.height(), framebuffer.pitch()); framebuffer.height(), framebuffer.pitch());

View File

@ -3,7 +3,7 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init( glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
const DenaliInfo& denali_info) { const yellowstone::DenaliInfo& denali_info) {
// Read 1024 bytes from 1024 offset. // Read 1024 bytes from 1024 offset.
// FIXME: Don't assume 512 byte sectors somehow. // FIXME: Don't assume 512 byte sectors somehow.
DenaliClient client(denali_info.denali_endpoint()); DenaliClient client(denali_info.denali_endpoint());

View File

@ -16,7 +16,7 @@
class Ext2BlockReader { class Ext2BlockReader {
public: public:
static glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Init( static glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Init(
const DenaliInfo& denali_info); const yellowstone::DenaliInfo& denali_info);
// TODO: Consider creating a new class wrapper with these computations. // TODO: Consider creating a new class wrapper with these computations.
Superblock* GetSuperblock(); Superblock* GetSuperblock();

View File

@ -3,7 +3,8 @@
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(const DenaliInfo& denali_info) { glcr::ErrorOr<Ext2Driver> Ext2Driver::Init(
const yellowstone::DenaliInfo& denali_info) {
ASSIGN_OR_RETURN(glcr::SharedPtr<Ext2BlockReader> reader, ASSIGN_OR_RETURN(glcr::SharedPtr<Ext2BlockReader> reader,
Ext2BlockReader::Init(glcr::Move(denali_info))); Ext2BlockReader::Init(glcr::Move(denali_info)));

View File

@ -10,7 +10,8 @@
class Ext2Driver { class Ext2Driver {
public: public:
static glcr::ErrorOr<Ext2Driver> Init(const DenaliInfo& denali_info); static glcr::ErrorOr<Ext2Driver> Init(
const yellowstone::DenaliInfo& denali_info);
glcr::ErrorCode ProbePartition(); glcr::ErrorCode ProbePartition();

View File

@ -3,12 +3,23 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
VFSClient::~VFSClient() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorCode VFSClient::OpenFile(const OpenFileRequest& request, OpenFileResponse& response) { glcr::ErrorCode VFSClient::OpenFile(const OpenFileRequest& request, OpenFileResponse& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +28,10 @@ glcr::ErrorCode VFSClient::OpenFile(const OpenFileRequest& request, OpenFileResp
buffer_.WriteAt<uint64_t>(8, 0); buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,14 +47,18 @@ glcr::ErrorCode VFSClient::OpenFile(const OpenFileRequest& request, OpenFileResp
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode VFSClient::GetDirectory(const GetDirectoryRequest& request, Directory& response) { glcr::ErrorCode VFSClient::GetDirectory(const GetDirectoryRequest& request, Directory& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -49,7 +67,10 @@ glcr::ErrorCode VFSClient::GetDirectory(const GetDirectoryRequest& request, Dire
buffer_.WriteAt<uint64_t>(8, 1); buffer_.WriteAt<uint64_t>(8, 1);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -65,9 +86,13 @@ glcr::ErrorCode VFSClient::GetDirectory(const GetDirectoryRequest& request, Dire
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }

View File

@ -8,18 +8,24 @@
#include "victoriafalls.yunq.h" #include "victoriafalls.yunq.h"
class VFSClient { class VFSClient {
public: public:
VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {}
VFSClient(const VFSClient&) = delete; VFSClient(const VFSClient&) = delete;
VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~VFSClient();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
[[nodiscard]] glcr::ErrorCode OpenFile(const OpenFileRequest& request, OpenFileResponse& response); [[nodiscard]] glcr::ErrorCode OpenFile(const OpenFileRequest& request, OpenFileResponse& response);
[[nodiscard]] glcr::ErrorCode GetDirectory(const GetDirectoryRequest& request, Directory& response); [[nodiscard]] glcr::ErrorCode GetDirectory(const GetDirectoryRequest& request, Directory& response);
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -28,3 +34,4 @@ class VFSClient {
uint64_t kCapBufferSize = 0x10; uint64_t kCapBufferSize = 0x10;
glcr::CapBuffer cap_buffer_{kCapBufferSize}; glcr::CapBuffer cap_buffer_{kCapBufferSize};
}; };

View File

@ -1,6 +1,7 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "victoriafalls.yunq.h" #include "victoriafalls.yunq.h"
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -283,4 +284,5 @@ uint64_t Directory::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, g
WriteHeader(bytes, offset, core_size, next_extension); WriteHeader(bytes, offset, core_size, next_extension);
return next_extension; return next_extension;
} }

View File

@ -6,6 +6,8 @@
#include <glacier/container/vector.h> #include <glacier/container/vector.h>
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
class OpenFileRequest { class OpenFileRequest {
public: public:
OpenFileRequest() {} OpenFileRequest() {}
@ -91,4 +93,5 @@ class Directory {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };

View File

@ -4,6 +4,7 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +30,18 @@ void VFSServerBaseThreadBootstrap(void* server_base) {
((VFSServerBase*)server_base)->ServerThread(); ((VFSServerBase*)server_base)->ServerThread();
} }
VFSServerBase::~VFSServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> VFSServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<VFSClient> VFSServerBase::CreateClient() { glcr::ErrorOr<VFSClient> VFSServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -87,25 +100,43 @@ glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
switch(method_select) { switch(method_select) {
case 0: { case 0: {
OpenFileRequest yunq_request; OpenFileRequest yunq_request;
OpenFileResponse yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
OpenFileResponse yunq_response;
RET_ERR(HandleOpenFile(yunq_request, yunq_response)); RET_ERR(HandleOpenFile(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
case 1: { case 1: {
GetDirectoryRequest yunq_request; GetDirectoryRequest yunq_request;
Directory yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
Directory yunq_response;
RET_ERR(HandleGetDirectory(yunq_request, yunq_response)); RET_ERR(HandleGetDirectory(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
default: { default: {
@ -114,3 +145,5 @@ glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
} }
return glcr::OK; return glcr::OK;
} }

View File

@ -10,22 +10,30 @@
class VFSServerBase { class VFSServerBase {
public: public:
VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {}
VFSServerBase(const VFSServerBase&) = delete; VFSServerBase(const VFSServerBase&) = delete;
VFSServerBase(VFSServerBase&&) = delete; VFSServerBase(VFSServerBase&&) = delete;
virtual ~VFSServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<VFSClient> CreateClient(); glcr::ErrorOr<VFSClient> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
[[nodiscard]] virtual glcr::ErrorCode HandleOpenFile(const OpenFileRequest&, OpenFileResponse&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleOpenFile(const OpenFileRequest&, OpenFileResponse&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetDirectory(const GetDirectoryRequest&, Directory&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleGetDirectory(const GetDirectoryRequest&, Directory&) = 0;
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -37,3 +45,5 @@ class VFSServerBase {
glcr::CapBuffer& resp_caps); glcr::CapBuffer& resp_caps);
}; };

View File

@ -5,15 +5,18 @@
#include "fs/ext2/ext2_driver.h" #include "fs/ext2/ext2_driver.h"
#include "victoriafalls_server.h" #include "victoriafalls_server.h"
using yellowstone::DenaliInfo;
using yellowstone::RegisterEndpointRequest;
using yellowstone::YellowstoneClient;
uint64_t main(uint64_t init_cap) { uint64_t main(uint64_t init_cap) {
ParseInitPort(init_cap); ParseInitPort(init_cap);
dbgln("VFs Started"); dbgln("VFs Started");
YellowstoneClient yellowstone(gInitEndpointCap); YellowstoneClient yellowstone(gInitEndpointCap);
Empty empty;
DenaliInfo denali_info; DenaliInfo denali_info;
RET_ERR(yellowstone.GetDenali(empty, denali_info)); RET_ERR(yellowstone.GetDenali(denali_info));
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(denali_info)); ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(denali_info));
ASSIGN_OR_RETURN(auto server, VFSServer::Create(ext2)); ASSIGN_OR_RETURN(auto server, VFSServer::Create(ext2));
@ -22,9 +25,9 @@ uint64_t main(uint64_t init_cap) {
RegisterEndpointRequest req; RegisterEndpointRequest req;
req.set_endpoint_name("victoriafalls"); req.set_endpoint_name("victoriafalls");
ASSIGN_OR_RETURN(auto client, server->CreateClient()); ASSIGN_OR_RETURN(auto client_cap, server->CreateClientCap());
req.set_endpoint_capability(client.Capability()); req.set_endpoint_capability(client_cap);
check(yellowstone.RegisterEndpoint(req, empty)); check(yellowstone.RegisterEndpoint(req));
RET_ERR(server_thread.Join()); RET_ERR(server_thread.Join());

View File

@ -1,12 +1,8 @@
interface Voyageurs { interface Voyageurs {
method RegisterKeyboardListener(KeyboardListener) -> (None); method RegisterKeyboardListener(KeyboardListener) -> ();
} }
message KeyboardListener { message KeyboardListener {
capability port_capability; capability port_capability;
} }
message None {
}

View File

@ -3,12 +3,23 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
glcr::ErrorCode VoyageursClient::RegisterKeyboardListener(const KeyboardListener& request, None& response) { VoyageursClient::~VoyageursClient() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorCode VoyageursClient::RegisterKeyboardListener(const KeyboardListener& request) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +28,10 @@ glcr::ErrorCode VoyageursClient::RegisterKeyboardListener(const KeyboardListener
buffer_.WriteAt<uint64_t>(8, 0); buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,9 +47,11 @@ glcr::ErrorCode VoyageursClient::RegisterKeyboardListener(const KeyboardListener
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }

View File

@ -8,16 +8,20 @@
#include "voyageurs.yunq.h" #include "voyageurs.yunq.h"
class VoyageursClient { class VoyageursClient {
public: public:
VoyageursClient(z_cap_t Voyageurs_cap) : endpoint_(Voyageurs_cap) {} VoyageursClient(z_cap_t Voyageurs_cap) : endpoint_(Voyageurs_cap) {}
VoyageursClient(const VoyageursClient&) = delete; VoyageursClient(const VoyageursClient&) = delete;
VoyageursClient(VoyageursClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; VoyageursClient(VoyageursClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~VoyageursClient();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
[[nodiscard]] glcr::ErrorCode RegisterKeyboardListener(const KeyboardListener& request, None& response);
[[nodiscard]] glcr::ErrorCode RegisterKeyboardListener(const KeyboardListener& request);
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -26,3 +30,4 @@ class VoyageursClient {
uint64_t kCapBufferSize = 0x10; uint64_t kCapBufferSize = 0x10;
glcr::CapBuffer cap_buffer_{kCapBufferSize}; glcr::CapBuffer cap_buffer_{kCapBufferSize};
}; };

View File

@ -1,6 +1,7 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "voyageurs.yunq.h" #include "voyageurs.yunq.h"
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -75,36 +76,4 @@ uint64_t KeyboardListener::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t of
return next_extension; return next_extension;
} }
void None::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
ParseFromBytesInternal(bytes, offset);
}
void None::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
}
void None::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
CheckHeader(bytes);
}
uint64_t None::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 None::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;
}

View File

@ -6,6 +6,8 @@
#include <glacier/container/vector.h> #include <glacier/container/vector.h>
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
class KeyboardListener { class KeyboardListener {
public: public:
KeyboardListener() {} KeyboardListener() {}
@ -26,20 +28,4 @@ class KeyboardListener {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };
class None {
public:
None() {}
// Delete copy and move until implemented.
None(const None&) = delete;
None(None&&) = 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:
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};

View File

@ -4,6 +4,7 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +30,18 @@ void VoyageursServerBaseThreadBootstrap(void* server_base) {
((VoyageursServerBase*)server_base)->ServerThread(); ((VoyageursServerBase*)server_base)->ServerThread();
} }
VoyageursServerBase::~VoyageursServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> VoyageursServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<VoyageursClient> VoyageursServerBase::CreateClient() { glcr::ErrorOr<VoyageursClient> VoyageursServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -87,14 +100,21 @@ glcr::ErrorCode VoyageursServerBase::HandleRequest(const glcr::ByteBuffer& reque
switch(method_select) { switch(method_select) {
case 0: { case 0: {
KeyboardListener yunq_request; KeyboardListener yunq_request;
None yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleRegisterKeyboardListener(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
RET_ERR(HandleRegisterKeyboardListener(yunq_request));
resp_length = 0;
break; break;
} }
default: { default: {
@ -103,3 +123,5 @@ glcr::ErrorCode VoyageursServerBase::HandleRequest(const glcr::ByteBuffer& reque
} }
return glcr::OK; return glcr::OK;
} }

View File

@ -10,18 +10,24 @@
class VoyageursServerBase { class VoyageursServerBase {
public: public:
VoyageursServerBase(z_cap_t Voyageurs_cap) : endpoint_(Voyageurs_cap) {} VoyageursServerBase(z_cap_t Voyageurs_cap) : endpoint_(Voyageurs_cap) {}
VoyageursServerBase(const VoyageursServerBase&) = delete; VoyageursServerBase(const VoyageursServerBase&) = delete;
VoyageursServerBase(VoyageursServerBase&&) = delete; VoyageursServerBase(VoyageursServerBase&&) = delete;
virtual ~VoyageursServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<VoyageursClient> CreateClient(); glcr::ErrorOr<VoyageursClient> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
[[nodiscard]] virtual glcr::ErrorCode HandleRegisterKeyboardListener(const KeyboardListener&, None&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleRegisterKeyboardListener(const KeyboardListener&) = 0;
private: private:
@ -35,3 +41,5 @@ class VoyageursServerBase {
glcr::CapBuffer& resp_caps); glcr::CapBuffer& resp_caps);
}; };

View File

@ -6,6 +6,9 @@
#include "keyboard/keyboard_driver.h" #include "keyboard/keyboard_driver.h"
#include "voyageurs_server.h" #include "voyageurs_server.h"
using yellowstone::RegisterEndpointRequest;
using yellowstone::YellowstoneClient;
uint64_t main(uint64_t init_port) { uint64_t main(uint64_t init_port) {
ParseInitPort(init_port); ParseInitPort(init_port);
@ -25,10 +28,9 @@ uint64_t main(uint64_t init_port) {
RegisterEndpointRequest req; RegisterEndpointRequest req;
req.set_endpoint_name("voyageurs"); req.set_endpoint_name("voyageurs");
ASSIGN_OR_RETURN(VoyageursClient client, server->CreateClient()); ASSIGN_OR_RETURN(z_cap_t client_cap, server->CreateClientCap());
req.set_endpoint_capability(client.Capability()); req.set_endpoint_capability(client_cap);
Empty empty; check(yellowstone.RegisterEndpoint(req));
check(yellowstone.RegisterEndpoint(req, empty));
check(server_thread.Join()); check(server_thread.Join());
check(keyboard_thread.Join()); check(keyboard_thread.Join());

View File

@ -9,7 +9,7 @@ glcr::ErrorOr<glcr::UniquePtr<VoyageursServer>> VoyageursServer::Create(
} }
glcr::ErrorCode VoyageursServer::HandleRegisterKeyboardListener( glcr::ErrorCode VoyageursServer::HandleRegisterKeyboardListener(
const KeyboardListener& listener, None&) { const KeyboardListener& listener) {
keyboard_driver_.RegisterListener(listener.port_capability()); keyboard_driver_.RegisterListener(listener.port_capability());
return glcr::OK; return glcr::OK;
} }

View File

@ -12,7 +12,7 @@ class VoyageursServer : public VoyageursServerBase {
KeyboardDriver& keyboard_driver); KeyboardDriver& keyboard_driver);
virtual glcr::ErrorCode HandleRegisterKeyboardListener( virtual glcr::ErrorCode HandleRegisterKeyboardListener(
const KeyboardListener& listener, None&) override; const KeyboardListener& listener) override;
private: private:
KeyboardDriver& keyboard_driver_; KeyboardDriver& keyboard_driver_;

View File

@ -1,9 +1,11 @@
package yellowstone;
interface Yellowstone { interface Yellowstone {
method RegisterEndpoint(RegisterEndpointRequest) -> (Empty); method RegisterEndpoint(RegisterEndpointRequest) -> ();
method GetEndpoint(GetEndpointRequest) -> (Endpoint); method GetEndpoint(GetEndpointRequest) -> (Endpoint);
method GetAhciInfo(Empty) -> (AhciInfo); method GetAhciInfo() -> (AhciInfo);
method GetFramebufferInfo(Empty) -> (FramebufferInfo); method GetFramebufferInfo() -> (FramebufferInfo);
method GetDenali(Empty) -> (DenaliInfo); method GetDenali() -> (DenaliInfo);
} }
message RegisterEndpointRequest { message RegisterEndpointRequest {
@ -11,10 +13,6 @@ message RegisterEndpointRequest {
capability endpoint_capability; capability endpoint_capability;
} }
message Empty {
}
message GetEndpointRequest { message GetEndpointRequest {
string endpoint_name; string endpoint_name;
} }

View File

@ -3,12 +3,25 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace yellowstone {
glcr::ErrorCode YellowstoneClient::RegisterEndpoint(const RegisterEndpointRequest& request, Empty& response) {
YellowstoneClient::~YellowstoneClient() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorCode YellowstoneClient::RegisterEndpoint(const RegisterEndpointRequest& request) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +30,10 @@ glcr::ErrorCode YellowstoneClient::RegisterEndpoint(const RegisterEndpointReques
buffer_.WriteAt<uint64_t>(8, 0); buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,14 +49,16 @@ glcr::ErrorCode YellowstoneClient::RegisterEndpoint(const RegisterEndpointReques
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneClient::GetEndpoint(const GetEndpointRequest& request, Endpoint& response) { glcr::ErrorCode YellowstoneClient::GetEndpoint(const GetEndpointRequest& request, Endpoint& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -49,7 +67,10 @@ glcr::ErrorCode YellowstoneClient::GetEndpoint(const GetEndpointRequest& request
buffer_.WriteAt<uint64_t>(8, 1); buffer_.WriteAt<uint64_t>(8, 1);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -65,14 +86,18 @@ glcr::ErrorCode YellowstoneClient::GetEndpoint(const GetEndpointRequest& request
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& response) {
glcr::ErrorCode YellowstoneClient::GetAhciInfo(AhciInfo& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -81,7 +106,10 @@ glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& r
buffer_.WriteAt<uint64_t>(8, 2); buffer_.WriteAt<uint64_t>(8, 2);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
uint64_t length = 0;
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -97,14 +125,18 @@ glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& r
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneClient::GetFramebufferInfo(const Empty& request, FramebufferInfo& response) {
glcr::ErrorCode YellowstoneClient::GetFramebufferInfo(FramebufferInfo& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -113,7 +145,10 @@ glcr::ErrorCode YellowstoneClient::GetFramebufferInfo(const Empty& request, Fram
buffer_.WriteAt<uint64_t>(8, 3); buffer_.WriteAt<uint64_t>(8, 3);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
uint64_t length = 0;
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -129,14 +164,18 @@ glcr::ErrorCode YellowstoneClient::GetFramebufferInfo(const Empty& request, Fram
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& response) {
glcr::ErrorCode YellowstoneClient::GetDenali(DenaliInfo& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -145,7 +184,10 @@ glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& r
buffer_.WriteAt<uint64_t>(8, 4); buffer_.WriteAt<uint64_t>(8, 4);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
uint64_t length = 0;
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -161,9 +203,15 @@ glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& r
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
} // namepace yellowstone

View File

@ -8,24 +8,38 @@
#include "yellowstone.yunq.h" #include "yellowstone.yunq.h"
namespace yellowstone {
class YellowstoneClient { class YellowstoneClient {
public: public:
YellowstoneClient(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {} YellowstoneClient(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {}
YellowstoneClient(const YellowstoneClient&) = delete; YellowstoneClient(const YellowstoneClient&) = delete;
YellowstoneClient(YellowstoneClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; YellowstoneClient(YellowstoneClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~YellowstoneClient();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
[[nodiscard]] glcr::ErrorCode RegisterEndpoint(const RegisterEndpointRequest& request, Empty& response);
[[nodiscard]] glcr::ErrorCode RegisterEndpoint(const RegisterEndpointRequest& request);
[[nodiscard]] glcr::ErrorCode GetEndpoint(const GetEndpointRequest& request, Endpoint& response); [[nodiscard]] glcr::ErrorCode GetEndpoint(const GetEndpointRequest& request, Endpoint& response);
[[nodiscard]] glcr::ErrorCode GetAhciInfo(const Empty& request, AhciInfo& response);
[[nodiscard]] glcr::ErrorCode GetAhciInfo(AhciInfo& response);
[[nodiscard]] glcr::ErrorCode GetFramebufferInfo(const Empty& request, FramebufferInfo& response);
[[nodiscard]] glcr::ErrorCode GetFramebufferInfo(FramebufferInfo& response);
[[nodiscard]] glcr::ErrorCode GetDenali(const Empty& request, DenaliInfo& response);
[[nodiscard]] glcr::ErrorCode GetDenali(DenaliInfo& response);
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -34,3 +48,6 @@ class YellowstoneClient {
uint64_t kCapBufferSize = 0x10; uint64_t kCapBufferSize = 0x10;
glcr::CapBuffer cap_buffer_{kCapBufferSize}; glcr::CapBuffer cap_buffer_{kCapBufferSize};
}; };
} // namepace yellowstone

View File

@ -1,6 +1,9 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "yellowstone.yunq.h" #include "yellowstone.yunq.h"
namespace yellowstone {
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -101,39 +104,6 @@ uint64_t RegisterEndpointRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint
return next_extension; return next_extension;
} }
void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
ParseFromBytesInternal(bytes, offset);
}
void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
ParseFromBytesInternal(bytes, offset);
}
void Empty::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint64_t offset) {
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 GetEndpointRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { void GetEndpointRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
ParseFromBytesInternal(bytes, offset); ParseFromBytesInternal(bytes, offset);
} }
@ -459,4 +429,7 @@ uint64_t DenaliInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset,
WriteHeader(bytes, offset, core_size, next_extension); WriteHeader(bytes, offset, core_size, next_extension);
return next_extension; return next_extension;
} }
} // namepace yellowstone

View File

@ -6,6 +6,10 @@
#include <glacier/container/vector.h> #include <glacier/container/vector.h>
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
namespace yellowstone {
class RegisterEndpointRequest { class RegisterEndpointRequest {
public: public:
RegisterEndpointRequest() {} RegisterEndpointRequest() {}
@ -29,23 +33,6 @@ class RegisterEndpointRequest {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };
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:
// Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
};
class GetEndpointRequest { class GetEndpointRequest {
public: public:
GetEndpointRequest() {} GetEndpointRequest() {}
@ -187,4 +174,7 @@ class DenaliInfo {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };
} // namepace yellowstone

View File

@ -4,6 +4,9 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace yellowstone {
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +32,18 @@ void YellowstoneServerBaseThreadBootstrap(void* server_base) {
((YellowstoneServerBase*)server_base)->ServerThread(); ((YellowstoneServerBase*)server_base)->ServerThread();
} }
YellowstoneServerBase::~YellowstoneServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> YellowstoneServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<YellowstoneClient> YellowstoneServerBase::CreateClient() { glcr::ErrorOr<YellowstoneClient> YellowstoneServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -87,58 +102,92 @@ glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& req
switch(method_select) { switch(method_select) {
case 0: { case 0: {
RegisterEndpointRequest yunq_request; RegisterEndpointRequest yunq_request;
Empty yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleRegisterEndpoint(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
RET_ERR(HandleRegisterEndpoint(yunq_request));
resp_length = 0;
break; break;
} }
case 1: { case 1: {
GetEndpointRequest yunq_request; GetEndpointRequest yunq_request;
Endpoint yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
Endpoint yunq_response;
RET_ERR(HandleGetEndpoint(yunq_request, yunq_response)); RET_ERR(HandleGetEndpoint(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
case 2: { case 2: {
Empty yunq_request;
AhciInfo yunq_response; AhciInfo yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleGetAhciInfo(yunq_response));
RET_ERR(HandleGetAhciInfo(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
case 3: { case 3: {
Empty yunq_request;
FramebufferInfo yunq_response; FramebufferInfo yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleGetFramebufferInfo(yunq_response));
RET_ERR(HandleGetFramebufferInfo(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
case 4: { case 4: {
Empty yunq_request;
DenaliInfo yunq_response; DenaliInfo yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
RET_ERR(HandleGetDenali(yunq_response));
RET_ERR(HandleGetDenali(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
default: { default: {
@ -147,3 +196,7 @@ glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& req
} }
return glcr::OK; return glcr::OK;
} }
} // namepace yellowstone

View File

@ -9,27 +9,43 @@
#include "yellowstone.yunq.client.h" #include "yellowstone.yunq.client.h"
namespace yellowstone {
class YellowstoneServerBase { class YellowstoneServerBase {
public: public:
YellowstoneServerBase(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {} YellowstoneServerBase(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {}
YellowstoneServerBase(const YellowstoneServerBase&) = delete; YellowstoneServerBase(const YellowstoneServerBase&) = delete;
YellowstoneServerBase(YellowstoneServerBase&&) = delete; YellowstoneServerBase(YellowstoneServerBase&&) = delete;
virtual ~YellowstoneServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<YellowstoneClient> CreateClient(); glcr::ErrorOr<YellowstoneClient> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
[[nodiscard]] virtual glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, Empty&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetEndpoint(const GetEndpointRequest&, Endpoint&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleGetEndpoint(const GetEndpointRequest&, Endpoint&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetFramebufferInfo(const Empty&, FramebufferInfo&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) = 0; [[nodiscard]] virtual glcr::ErrorCode HandleGetAhciInfo(AhciInfo&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetFramebufferInfo(FramebufferInfo&) = 0;
[[nodiscard]] virtual glcr::ErrorCode HandleGetDenali(DenaliInfo&) = 0;
private: private:
@ -43,3 +59,7 @@ class YellowstoneServerBase {
glcr::CapBuffer& resp_caps); glcr::CapBuffer& resp_caps);
}; };
} // namepace yellowstone

View File

@ -22,16 +22,16 @@ uint64_t main(uint64_t port_cap) {
check(ParseInitPort(port_cap)); check(ParseInitPort(port_cap));
dbgln("Yellowstone Initializing."); dbgln("Yellowstone Initializing.");
ASSIGN_OR_RETURN(auto server, YellowstoneServer::Create()); ASSIGN_OR_RETURN(auto server, yellowstone::YellowstoneServer::Create());
Thread server_thread = server->RunServer(); Thread server_thread = server->RunServer();
ASSIGN_OR_RETURN(YellowstoneClient client1, server->CreateClient()); ASSIGN_OR_RETURN(uint64_t client_cap, server->CreateClientCap());
check(SpawnProcess(gBootDenaliVmmoCap, client1.Capability())); check(SpawnProcess(gBootDenaliVmmoCap, client_cap));
server->WaitDenaliRegistered(); server->WaitDenaliRegistered();
ASSIGN_OR_RETURN(YellowstoneClient client2, server->CreateClient()); ASSIGN_OR_RETURN(client_cap, server->CreateClientCap());
check(SpawnProcess(gBootVictoriaFallsVmmoCap, client2.Capability())); check(SpawnProcess(gBootVictoriaFallsVmmoCap, client_cap));
server->WaitVictoriaFallsRegistered(); server->WaitVictoriaFallsRegistered();
@ -47,9 +47,9 @@ uint64_t main(uint64_t port_cap) {
mmth::File binary = mmth::File binary =
mmth::File::Open(glcr::StrFormat("/bin/{}", files[i])); mmth::File::Open(glcr::StrFormat("/bin/{}", files[i]));
ASSIGN_OR_RETURN(YellowstoneClient client3, server->CreateClient()); ASSIGN_OR_RETURN(client_cap, server->CreateClientCap());
check(mmth::SpawnProcessFromElfRegion((uint64_t)binary.raw_ptr(), check(mmth::SpawnProcessFromElfRegion((uint64_t)binary.raw_ptr(),
client3.Capability())); client_cap));
} }
} }

View File

@ -11,6 +11,7 @@
#include "hw/gpt.h" #include "hw/gpt.h"
#include "hw/pcie.h" #include "hw/pcie.h"
namespace yellowstone {
namespace { namespace {
struct PartitionInfo { struct PartitionInfo {
@ -41,15 +42,14 @@ glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> YellowstoneServer::Create() {
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap) YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap)
: YellowstoneServerBase(endpoint_cap) {} : YellowstoneServerBase(endpoint_cap) {}
glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(AhciInfo& info) {
AhciInfo& info) {
info.set_ahci_region(pci_reader_.GetAhciVmmo()); info.set_ahci_region(pci_reader_.GetAhciVmmo());
info.set_region_length(kPcieConfigurationSize); info.set_region_length(kPcieConfigurationSize);
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneServer::HandleGetFramebufferInfo( glcr::ErrorCode YellowstoneServer::HandleGetFramebufferInfo(
const Empty&, FramebufferInfo& info) { FramebufferInfo& info) {
// FIXME: Don't do this for each request. // FIXME: Don't do this for each request.
mmth::OwnedMemoryRegion region = mmth::OwnedMemoryRegion region =
mmth::OwnedMemoryRegion::FromCapability(gBootFramebufferVmmoCap); mmth::OwnedMemoryRegion::FromCapability(gBootFramebufferVmmoCap);
@ -71,8 +71,7 @@ glcr::ErrorCode YellowstoneServer::HandleGetFramebufferInfo(
return glcr::OK; return glcr::OK;
} }
glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&, glcr::ErrorCode YellowstoneServer::HandleGetDenali(DenaliInfo& info) {
DenaliInfo& info) {
if (!endpoint_map_.Contains("denali")) { if (!endpoint_map_.Contains("denali")) {
return glcr::NOT_FOUND; return glcr::NOT_FOUND;
} }
@ -85,11 +84,13 @@ glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&,
} }
glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint( glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint(
const RegisterEndpointRequest& req, Empty&) { const RegisterEndpointRequest& req) {
dbgln("Registering {}.", req.endpoint_name().view()); dbgln("Registering {}.", req.endpoint_name().view());
check(endpoint_map_.Insert(req.endpoint_name(), req.endpoint_capability())); check(endpoint_map_.Insert(req.endpoint_name(), req.endpoint_capability()));
if (req.endpoint_name() == "denali") { if (req.endpoint_name() == "denali") {
auto part_info_or = HandleDenaliRegistration(req.endpoint_capability()); z_cap_t dup_cap;
check(ZCapDuplicate(req.endpoint_capability(), kZionPerm_All, &dup_cap));
auto part_info_or = HandleDenaliRegistration(dup_cap);
if (!part_info_or.ok()) { if (!part_info_or.ok()) {
check(part_info_or.error()); check(part_info_or.error());
} }
@ -125,3 +126,5 @@ void YellowstoneServer::WaitDenaliRegistered() { has_denali_semaphore_.Wait(); }
void YellowstoneServer::WaitVictoriaFallsRegistered() { void YellowstoneServer::WaitVictoriaFallsRegistered() {
has_victoriafalls_semaphore_.Wait(); has_victoriafalls_semaphore_.Wait();
} }
} // namespace yellowstone

View File

@ -10,16 +10,17 @@
#include "hw/pcie.h" #include "hw/pcie.h"
#include "lib/yellowstone/yellowstone.yunq.server.h" #include "lib/yellowstone/yellowstone.yunq.server.h"
namespace yellowstone {
class YellowstoneServer : public YellowstoneServerBase { class YellowstoneServer : public YellowstoneServerBase {
public: public:
static glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> Create(); static glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> Create();
glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) override; glcr::ErrorCode HandleGetAhciInfo(AhciInfo&) override;
glcr::ErrorCode HandleGetFramebufferInfo(const Empty&, glcr::ErrorCode HandleGetFramebufferInfo(FramebufferInfo&) override;
FramebufferInfo&) override; glcr::ErrorCode HandleGetDenali(DenaliInfo&) override;
glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) override; glcr::ErrorCode HandleRegisterEndpoint(
glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, const RegisterEndpointRequest&) override;
Empty&) override;
glcr::ErrorCode HandleGetEndpoint(const GetEndpointRequest&, glcr::ErrorCode HandleGetEndpoint(const GetEndpointRequest&,
Endpoint&) override; Endpoint&) override;
@ -40,3 +41,5 @@ class YellowstoneServer : public YellowstoneServerBase {
YellowstoneServer(z_cap_t endpoint_cap); YellowstoneServer(z_cap_t endpoint_cap);
}; };
} // namespace yellowstone

View File

@ -3,12 +3,29 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
{% for interface in interfaces %} {% for interface in interfaces %}
{{interface.name}}Client::~{{interface.name}}Client() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
{% for method in interface.methods %} {% for method in interface.methods %}
{% if method.request == None %}
glcr::ErrorCode {{interface.name}}Client::{{method.name}}({{method.response}}& response) {
{% elif method.response == None %}
glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request) {
{% else %}
glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request, {{method.response}}& response) { glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request, {{method.response}}& response) {
{% endif %}
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +34,12 @@ glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request
buffer_.WriteAt<uint64_t>(8, {{loop.index0}}); buffer_.WriteAt<uint64_t>(8, {{loop.index0}});
cap_buffer_.Reset(); cap_buffer_.Reset();
{% if method.request == None %}
uint64_t length = 0;
{% else %}
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
{% endif %}
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,10 +55,16 @@ glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
{% if method.response != None %}
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
{% endif %}
return glcr::OK; return glcr::OK;
} }
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -8,17 +8,27 @@
#include "{{file}}.h" #include "{{file}}.h"
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
{% for interface in interfaces -%} {% for interface in interfaces -%}
class {{interface.name}}Client { class {{interface.name}}Client {
public: public:
{{interface.name}}Client(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {} {{interface.name}}Client(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {}
{{interface.name}}Client(const {{interface.name}}Client&) = delete; {{interface.name}}Client(const {{interface.name}}Client&) = delete;
{{interface.name}}Client({{interface.name}}Client&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; {{interface.name}}Client({{interface.name}}Client&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~{{interface.name}}Client();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
{% for method in interface.methods %} {% for method in interface.methods %}
{% if method.request == None %}
[[nodiscard]] glcr::ErrorCode {{method.name}}({{method.response}}& response);
{% elif method.response == None %}
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request);
{% else %}
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response); [[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response);
{% endif %}
{% endfor %} {% endfor %}
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -30,3 +40,6 @@ class {{interface.name}}Client {
{%- endfor %} {%- endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -1,3 +1,5 @@
package srv.file;
interface VFS { interface VFS {
method open (OpenFileRequest) -> (File); method open (OpenFileRequest) -> (File);
} }

View File

@ -3,12 +3,25 @@
#include <glacier/buffer/byte_buffer.h> #include <glacier/buffer/byte_buffer.h>
#include <glacier/buffer/cap_buffer.h> #include <glacier/buffer/cap_buffer.h>
#include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace srv::file {
VFSClient::~VFSClient() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response) { glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response) {
uint64_t buffer_size = kBufferSize; uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize; uint64_t cap_size = kCapBufferSize;
@ -17,7 +30,10 @@ glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response)
buffer_.WriteAt<uint64_t>(8, 0); buffer_.WriteAt<uint64_t>(8, 0);
cap_buffer_.Reset(); cap_buffer_.Reset();
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
buffer_.WriteAt<uint32_t>(4, 16 + length); buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap; z_cap_t reply_port_cap;
@ -33,9 +49,15 @@ glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response)
// Check Response Code. // Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8)); RET_ERR(buffer_.At<uint64_t>(8));
response.ParseFromBytes(buffer_, 16, cap_buffer_); response.ParseFromBytes(buffer_, 16, cap_buffer_);
return glcr::OK; return glcr::OK;
} }
} // namepace srv::file

View File

@ -8,16 +8,22 @@
#include "example.yunq.h" #include "example.yunq.h"
namespace srv::file {
class VFSClient { class VFSClient {
public: public:
VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {}
VFSClient(const VFSClient&) = delete; VFSClient(const VFSClient&) = delete;
VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;}; VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
~VFSClient();
z_cap_t Capability() { return endpoint_; } z_cap_t Capability() { return endpoint_; }
[[nodiscard]] glcr::ErrorCode open(const OpenFileRequest& request, File& response); [[nodiscard]] glcr::ErrorCode open(const OpenFileRequest& request, File& response);
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -26,3 +32,6 @@ class VFSClient {
uint64_t kCapBufferSize = 0x10; uint64_t kCapBufferSize = 0x10;
glcr::CapBuffer cap_buffer_{kCapBufferSize}; glcr::CapBuffer cap_buffer_{kCapBufferSize};
}; };
} // namepace srv::file

View File

@ -1,6 +1,9 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "example.yunq.h" #include "example.yunq.h"
namespace srv::file {
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -44,9 +47,9 @@ void OpenFileRequest::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint
// Parse options. // Parse options.
auto options_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 1)); auto options_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 1));
options_.Resize(options_pointer.length); options_.Resize(options_pointer.length / sizeof(uint64_t));
for (uint64_t i = offset + options_pointer.offset; for (uint64_t i = offset + options_pointer.offset;
i < offset + options_pointer.offset + (sizeof(uint64_t) * options_pointer.length); i < offset + options_pointer.offset + options_pointer.length;
i += sizeof(uint64_t)) { i += sizeof(uint64_t)) {
options_.PushBack(bytes.At<uint64_t>(i)); options_.PushBack(bytes.At<uint64_t>(i));
} }
@ -201,4 +204,7 @@ uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::
WriteHeader(bytes, offset, core_size, next_extension); WriteHeader(bytes, offset, core_size, next_extension);
return next_extension; return next_extension;
} }
} // namepace srv::file

View File

@ -6,6 +6,10 @@
#include <glacier/container/vector.h> #include <glacier/container/vector.h>
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
namespace srv::file {
class OpenFileRequest { class OpenFileRequest {
public: public:
OpenFileRequest() {} OpenFileRequest() {}
@ -17,7 +21,7 @@ class OpenFileRequest {
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); 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) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
glcr::String path() const { return path_; } const glcr::String& path() const { return path_; }
void set_path(const glcr::String& value) { path_ = value; } void set_path(const glcr::String& value) { path_ = value; }
const glcr::Vector<uint64_t>& options() const { return options_; } const glcr::Vector<uint64_t>& options() const { return options_; }
void add_options(const uint64_t& value) { options_.PushBack(value); } void add_options(const uint64_t& value) { options_.PushBack(value); }
@ -40,11 +44,11 @@ class File {
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); 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) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
glcr::String path() const { return path_; } const glcr::String& path() const { return path_; }
void set_path(const glcr::String& value) { path_ = value; } void set_path(const glcr::String& value) { path_ = value; }
uint64_t attrs() const { return attrs_; } const uint64_t& attrs() const { return attrs_; }
void set_attrs(const uint64_t& value) { attrs_ = value; } void set_attrs(const uint64_t& value) { attrs_ = value; }
z_cap_t mem_cap() const { return mem_cap_; } const z_cap_t& mem_cap() const { return mem_cap_; }
void set_mem_cap(const z_cap_t& value) { mem_cap_ = value; } void set_mem_cap(const z_cap_t& value) { mem_cap_ = value; }
private: private:
@ -54,4 +58,7 @@ class File {
// Parses everything except for caps. // Parses everything except for caps.
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };
} // namepace srv::file

View File

@ -1,9 +1,12 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "example.yunq.server.h" #include "example.yunq.server.h"
#include <mammoth/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
namespace srv::file {
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +32,18 @@ void VFSServerBaseThreadBootstrap(void* server_base) {
((VFSServerBase*)server_base)->ServerThread(); ((VFSServerBase*)server_base)->ServerThread();
} }
VFSServerBase::~VFSServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> VFSServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<VFSClient> VFSServerBase::CreateClient() { glcr::ErrorOr<VFSClient> VFSServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -87,14 +102,23 @@ glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
switch(method_select) { switch(method_select) {
case 0: { case 0: {
OpenFileRequest yunq_request; OpenFileRequest yunq_request;
File yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
File yunq_response;
RET_ERR(Handleopen(yunq_request, yunq_response)); RET_ERR(Handleopen(yunq_request, yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break; break;
} }
default: { default: {
@ -103,3 +127,7 @@ glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
} }
return glcr::OK; return glcr::OK;
} }
} // namepace srv::file

View File

@ -2,28 +2,36 @@
#pragma once #pragma once
#include <glacier/status/error_or.h> #include <glacier/status/error_or.h>
#include <mammoth/thread.h> #include <mammoth/proc/thread.h>
#include <ztypes.h> #include <ztypes.h>
#include "example.yunq.h" #include "example.yunq.h"
#include "example.yunq.client.h" #include "example.yunq.client.h"
namespace srv::file {
class VFSServerBase { class VFSServerBase {
public: public:
VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {} VFSServerBase(z_cap_t VFS_cap) : endpoint_(VFS_cap) {}
VFSServerBase(const VFSServerBase&) = delete; VFSServerBase(const VFSServerBase&) = delete;
VFSServerBase(VFSServerBase&&) = delete; VFSServerBase(VFSServerBase&&) = delete;
virtual ~VFSServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<VFSClient> CreateClient(); glcr::ErrorOr<VFSClient> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
[[nodiscard]] virtual glcr::ErrorCode Handleopen(const OpenFileRequest&, File&) = 0; [[nodiscard]] virtual glcr::ErrorCode Handleopen(const OpenFileRequest&, File&) = 0;
private: private:
z_cap_t endpoint_; z_cap_t endpoint_;
@ -35,3 +43,7 @@ class VFSServerBase {
glcr::CapBuffer& resp_caps); glcr::CapBuffer& resp_caps);
}; };
} // namepace srv::file

View File

@ -1,6 +1,9 @@
// Generated file -- DO NOT MODIFY. // Generated file -- DO NOT MODIFY.
#include "{{file}}.h" #include "{{file}}.h"
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
namespace { namespace {
const uint64_t header_size = 24; // 4x uint32, 1x uint64 const uint64_t header_size = 24; // 4x uint32, 1x uint64
@ -188,3 +191,7 @@ uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t of
return next_extension; return next_extension;
} }
{%- endfor %} {%- endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -7,6 +7,9 @@
#include <glacier/string/string.h> #include <glacier/string/string.h>
#include <ztypes.h> #include <ztypes.h>
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
{%- for message in messages %} {%- for message in messages %}
class {{message.name}} { class {{message.name}} {
@ -44,3 +47,7 @@ class {{message.name}} {
void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset); void ParseFromBytesInternal(const glcr::ByteBuffer&, uint64_t offset);
}; };
{%- endfor %} {%- endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -16,6 +16,7 @@ class LexemeType(Enum):
RIGHT_PAREN = 6 RIGHT_PAREN = 6
ARROW = 7 ARROW = 7
SEMICOLON = 8 SEMICOLON = 8
DOT = 9
class Lexeme(): class Lexeme():
@ -55,6 +56,8 @@ def lexer(program: str):
tokens.append(Lexeme(LexemeType.RIGHT_PAREN)) tokens.append(Lexeme(LexemeType.RIGHT_PAREN))
elif curr == ';': elif curr == ';':
tokens.append(Lexeme(LexemeType.SEMICOLON)) tokens.append(Lexeme(LexemeType.SEMICOLON))
elif curr == '.':
tokens.append(Lexeme(LexemeType.DOT))
elif curr == '-': elif curr == '-':
current += 1 current += 1
if program[current] == '>': if program[current] == '>':
@ -77,6 +80,12 @@ def lexer(program: str):
return tokens return tokens
class Package():
def __init__(self, names: list[str]):
self.names = names
def cpp_namespace(self):
return "::".join(self.names)
class Method(): class Method():
def __init__(self, name: str, request: str, response: str): def __init__(self, name: str, request: str, response: str):
@ -174,11 +183,25 @@ class Parser():
token = self.consume() token = self.consume()
if token.type != LexemeType.NAME: if token.type != LexemeType.NAME:
sys.exit("Unexpected token: %s", token) sys.exit("Unexpected token: %s", token)
if token.value == "package":
# TODO: Enforce that package decl comes before all messages and interface.
return self.package()
if token.value == "message": if token.value == "message":
return self.message() return self.message()
elif token.value == "interface": elif token.value == "interface":
return self.interface() return self.interface()
sys.exit("Unexpected identifier '%s', expected message or interface" % token.value) sys.exit("Unexpected identifier '%s', expected package, message, interface" % token.value)
def package(self):
names = [self.consume_identifier()]
while self.peektype() == LexemeType.DOT:
self.consume_check(LexemeType.DOT)
names += [self.consume_identifier()]
self.consume_check(LexemeType.SEMICOLON)
return Package(names)
def interface(self): def interface(self):
# "interface" consumed by decl. # "interface" consumed by decl.
@ -211,13 +234,20 @@ class Parser():
self.consume_check(LexemeType.LEFT_PAREN) self.consume_check(LexemeType.LEFT_PAREN)
request = self.consume_identifier() request = None
# FIXME: Fix error handling here (and for response). We want to show
# "expected rparen or identifier" if type is wrong rather than just
# "expected rparen".
if self.peektype() == LexemeType.NAME:
request = self.consume_identifier()
self.consume_check(LexemeType.RIGHT_PAREN) self.consume_check(LexemeType.RIGHT_PAREN)
self.consume_check(LexemeType.ARROW) self.consume_check(LexemeType.ARROW)
self.consume_check(LexemeType.LEFT_PAREN) self.consume_check(LexemeType.LEFT_PAREN)
response = self.consume_identifier() response = None
if self.peektype() == LexemeType.NAME:
response = self.consume_identifier()
self.consume_check(LexemeType.RIGHT_PAREN) self.consume_check(LexemeType.RIGHT_PAREN)
self.consume_check(LexemeType.SEMICOLON) self.consume_check(LexemeType.SEMICOLON)
@ -266,21 +296,29 @@ class Parser():
return Field(field_type, name, repeated) return Field(field_type, name, repeated)
def type_check(decls: list[Decl]): def type_check(decls: list[Decl]):
if sum(1 for decl in decls if type(decl) is Package) > 1:
sys.exit("Cannot have more than one package declaration")
for decl in decls: for decl in decls:
if type(decl) is Interface: if type(decl) is Interface:
for method in decl.methods: for method in decl.methods:
if method.request not in name_dict.keys(): if method.request is None and method.response is None:
sys.exit("Request type '%s' for '%s.%s' does not exist" % (method.request, decl.name, method.name)) sys.exit("Method '%s.%s' cannot have empty request and response" % (decl.name, method.name))
if type(name_dict[method.request]) is not Message: if method.request is not None:
sys.exit("Request type '%s' for '%s.%s' should be a message" % (method.request, decl.name, method.name)) if method.request not in name_dict.keys():
if method.response not in name_dict.keys(): sys.exit("Request type '%s' for '%s.%s' does not exist" % (method.request, decl.name, method.name))
sys.exit("Response type '%s' for '%s.%s' does not exist" % (method.response, decl.name, method.name)) if type(name_dict[method.request]) is not Message:
if type(name_dict[method.response]) is not Message: sys.exit("Request type '%s' for '%s.%s' should be a message" % (method.request, decl.name, method.name))
sys.exit("Response type '%s' for '%s.%s' should be a message" % (method.response, decl.name, method.name)) if method.response is not None:
if method.response not in name_dict.keys():
sys.exit("Response type '%s' for '%s.%s' does not exist" % (method.response, decl.name, method.name))
if type(name_dict[method.response]) is not Message:
sys.exit("Response type '%s' for '%s.%s' should be a message" % (method.response, decl.name, method.name))
def print_ast(decls: list[Decl]): def print_ast(decls: list[Decl]):
for decl in decls: for decl in decls:
if type(decl) is Interface: if type(decl) is Package:
print("%s (Package)" % decl.cpp_namespace())
elif type(decl) is Interface:
print("%s (Interface)" % decl.name) print("%s (Interface)" % decl.name)
for method in decl.methods: for method in decl.methods:
print("\t%s (%s -> %s)" % (method.name, method.request, method.response)) print("\t%s (%s -> %s)" % (method.name, method.request, method.response))

View File

@ -4,6 +4,9 @@
#include <mammoth/util/debug.h> #include <mammoth/util/debug.h>
#include <zcall.h> #include <zcall.h>
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
namespace { namespace {
const uint32_t kSentinel = 0xBEEFDEAD; const uint32_t kSentinel = 0xBEEFDEAD;
@ -29,6 +32,18 @@ void {{interface.name}}ServerBaseThreadBootstrap(void* server_base) {
(({{interface.name}}ServerBase*)server_base)->ServerThread(); (({{interface.name}}ServerBase*)server_base)->ServerThread();
} }
{{interface.name}}ServerBase::~{{interface.name}}ServerBase() {
if (endpoint_ != 0) {
check(ZCapRelease(endpoint_));
}
}
glcr::ErrorOr<z_cap_t> {{interface.name}}ServerBase::CreateClientCap() {
uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
return client_cap;
}
glcr::ErrorOr<{{interface.name}}Client> {{interface.name}}ServerBase::CreateClient() { glcr::ErrorOr<{{interface.name}}Client> {{interface.name}}ServerBase::CreateClient() {
uint64_t client_cap; uint64_t client_cap;
RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap)); RET_ERR(ZCapDuplicate(endpoint_, ~(kZionPerm_Read), &client_cap));
@ -88,14 +103,29 @@ glcr::ErrorCode {{interface.name}}ServerBase::HandleRequest(const glcr::ByteBuff
switch(method_select) { switch(method_select) {
{%- for method in interface.methods %} {%- for method in interface.methods %}
case {{loop.index0}}: { case {{loop.index0}}: {
{% if method.request != None %}
{{method.request}} yunq_request; {{method.request}} yunq_request;
{{method.response}} yunq_response;
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
{% endif %}
{% if method.response != None %}
{{method.response}} yunq_response;
{% endif %}
{% if method.request == None %}
RET_ERR(Handle{{method.name}}(yunq_response));
{% elif method.response == None %}
RET_ERR(Handle{{method.name}}(yunq_request));
{% else %}
RET_ERR(Handle{{method.name}}(yunq_request, yunq_response)); RET_ERR(Handle{{method.name}}(yunq_request, yunq_response));
{% endif %}
{% if method.response != None %}
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
{% else %}
resp_length = 0;
{% endif %}
break; break;
} }
{%- endfor %} {%- endfor %}
@ -106,3 +136,7 @@ glcr::ErrorCode {{interface.name}}ServerBase::HandleRequest(const glcr::ByteBuff
return glcr::OK; return glcr::OK;
} }
{% endfor %} {% endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -8,6 +8,10 @@
#include "{{file}}.h" #include "{{file}}.h"
#include "{{file}}.client.h" #include "{{file}}.client.h"
{% if package != None %}
namespace {{package.cpp_namespace()}} {
{% endif %}
{% for interface in interfaces %} {% for interface in interfaces %}
class {{interface.name}}ServerBase { class {{interface.name}}ServerBase {
@ -15,13 +19,21 @@ class {{interface.name}}ServerBase {
{{interface.name}}ServerBase(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {} {{interface.name}}ServerBase(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {}
{{interface.name}}ServerBase(const {{interface.name}}ServerBase&) = delete; {{interface.name}}ServerBase(const {{interface.name}}ServerBase&) = delete;
{{interface.name}}ServerBase({{interface.name}}ServerBase&&) = delete; {{interface.name}}ServerBase({{interface.name}}ServerBase&&) = delete;
virtual ~{{interface.name}}ServerBase();
glcr::ErrorOr<z_cap_t> CreateClientCap();
glcr::ErrorOr<{{interface.name}}Client> CreateClient(); glcr::ErrorOr<{{interface.name}}Client> CreateClient();
[[nodiscard]] Thread RunServer(); [[nodiscard]] Thread RunServer();
{% for method in interface.methods %} {% for method in interface.methods %}
{% if method.request == None %}
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}({{method.response}}&) = 0;
{% elif method.response == None %}
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&) = 0;
{% else %}
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&, {{method.response}}&) = 0; [[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&, {{method.response}}&) = 0;
{% endif %}
{% endfor %} {% endfor %}
private: private:
@ -36,3 +48,7 @@ class {{interface.name}}ServerBase {
}; };
{% endfor %} {% endfor %}
{% if package != None %}
} // namepace {{package.cpp_namespace()}}
{% endif %}

View File

@ -21,42 +21,48 @@ def main():
parser = Parser(lexemes) parser = Parser(lexemes)
ast = parser.parse() ast = parser.parse()
print_ast(ast)
type_check(ast) type_check(ast)
messages = [m for m in ast if type(m) is Message] messages = [m for m in ast if type(m) is Message]
interfaces = [i for i in ast if type(i) is Interface] interfaces = [i for i in ast if type(i) is Interface]
# We know there is only one package decl from the type_check.
packages = [p for p in ast if type(p) is Package]
package = None
if len(packages) == 1:
package = packages[0]
jinja_env = Environment(loader=FileSystemLoader(pathlib.Path(__file__).parent.resolve())) jinja_env = Environment(loader=FileSystemLoader(pathlib.Path(__file__).parent.resolve()))
message_header_tmpl = jinja_env.get_template("message.h.jinja") message_header_tmpl = jinja_env.get_template("message.h.jinja")
with open(filename + '.h', mode='w') as f: with open(filename + '.h', mode='w') as f:
message_header = message_header_tmpl.render(messages=messages) message_header = message_header_tmpl.render(messages=messages, package=package)
f.write(message_header) f.write(message_header)
message_impl_tmpl = jinja_env.get_template("message.cpp.jinja") message_impl_tmpl = jinja_env.get_template("message.cpp.jinja")
message_impl_tmpl.globals['Type'] = Type message_impl_tmpl.globals['Type'] = Type
with open(filename + '.cpp', mode='w') as f: with open(filename + '.cpp', mode='w') as f:
message_impl = message_impl_tmpl.render(file=filebase, messages=messages) message_impl = message_impl_tmpl.render(file=filebase, messages=messages, package=package)
f.write(message_impl) f.write(message_impl)
client_header_tmpl = jinja_env.get_template("client.h.jinja") client_header_tmpl = jinja_env.get_template("client.h.jinja")
with open(filename + '.client.h', mode='w') as f: with open(filename + '.client.h', mode='w') as f:
client_header = client_header_tmpl.render(file=filebase, interfaces=interfaces) client_header = client_header_tmpl.render(file=filebase, interfaces=interfaces, package=package)
f.write(client_header) f.write(client_header)
client_impl_tmpl = jinja_env.get_template("client.cpp.jinja") client_impl_tmpl = jinja_env.get_template("client.cpp.jinja")
with open(filename + '.client.cpp', mode='w') as f: with open(filename + '.client.cpp', mode='w') as f:
client_impl = client_impl_tmpl.render(file=filebase, interfaces=interfaces) client_impl = client_impl_tmpl.render(file=filebase, interfaces=interfaces, package=package)
f.write(client_impl) f.write(client_impl)
server_header_tmpl = jinja_env.get_template("server.h.jinja") server_header_tmpl = jinja_env.get_template("server.h.jinja")
with open(filename + '.server.h', mode='w') as f: with open(filename + '.server.h', mode='w') as f:
server_header = server_header_tmpl.render(file=filebase, interfaces=interfaces) server_header = server_header_tmpl.render(file=filebase, interfaces=interfaces, package=package)
f.write(server_header) f.write(server_header)
server_impl_tmpl = jinja_env.get_template("server.cpp.jinja") server_impl_tmpl = jinja_env.get_template("server.cpp.jinja")
with open(filename + '.server.cpp', mode='w') as f: with open(filename + '.server.cpp', mode='w') as f:
server_impl = server_impl_tmpl.render(file=filebase, interfaces=interfaces) server_impl = server_impl_tmpl.render(file=filebase, interfaces=interfaces, package=package)
f.write(server_impl) f.write(server_impl)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -69,7 +69,7 @@ target_link_libraries(zion
# -mno-red-zone -- Don't put data below the stack pointer (clobbered by interrupts). # -mno-red-zone -- Don't put data below the stack pointer (clobbered by interrupts).
# -mcmodel=kernel -- Assume the kernel code is running in the higher half. # -mcmodel=kernel -- Assume the kernel code is running in the higher half.
# -mgeneral-regs-only -- Prevent GCC from using a whole host of nonsense registers (that we have to enable). # -mgeneral-regs-only -- Prevent GCC from using a whole host of nonsense registers (that we have to enable).
set(_Z_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -fno-use-cxa-atexit -nostdlib -mabi=sysv -mno-red-zone -mcmodel=kernel -mgeneral-regs-only") set(_Z_COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -c -ffreestanding -fno-rtti -fno-exceptions -fno-use-cxa-atexit -nostdlib -mabi=sysv -mno-red-zone -mcmodel=kernel -mgeneral-regs-only -Wall -Werror")
set(_Z_LINK_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld") set(_Z_LINK_SCRIPT "${CMAKE_CURRENT_SOURCE_DIR}/linker.ld")

View File

@ -96,6 +96,7 @@ bool checksum(uint8_t* addr, uint8_t num_bytes) {
return check_cnt == 0; return check_cnt == 0;
} }
#if K_ACPI_DEBUG
void dbgsz(const char* c, uint8_t cnt) { void dbgsz(const char* c, uint8_t cnt) {
char cl[cnt + 1]; char cl[cnt + 1];
@ -105,6 +106,7 @@ void dbgsz(const char* c, uint8_t cnt) {
cl[cnt] = '\0'; cl[cnt] = '\0';
dbgln(cl); dbgln(cl);
} }
#endif
uint8_t* SdtDataStart(SdtHeader* sdt) { uint8_t* SdtDataStart(SdtHeader* sdt) {
return reinterpret_cast<uint8_t*>(sdt) + sizeof(SdtHeader); return reinterpret_cast<uint8_t*>(sdt) + sizeof(SdtHeader);
@ -157,8 +159,8 @@ void ParseMadt(SdtHeader* rsdt) {
while (reinterpret_cast<uint64_t>(entry) < max_addr) { while (reinterpret_cast<uint64_t>(entry) < max_addr) {
switch (entry->type) { switch (entry->type) {
case 0: { case 0: {
MadtLocalApic* local = reinterpret_cast<MadtLocalApic*>(entry);
#if K_ACPI_DEBUG #if K_ACPI_DEBUG
MadtLocalApic* local = reinterpret_cast<MadtLocalApic*>(entry);
dbgln("Local APIC (Proc id, id, flags): {x}, {x}, {x}", dbgln("Local APIC (Proc id, id, flags): {x}, {x}, {x}",
local->processor_id, local->apic_id, +local->flags); local->processor_id, local->apic_id, +local->flags);
#endif #endif
@ -177,9 +179,9 @@ void ParseMadt(SdtHeader* rsdt) {
break; break;
} }
case 2: { case 2: {
#if K_ACPI_DEBUG
MadtIoApicInterruptSource* src = MadtIoApicInterruptSource* src =
reinterpret_cast<MadtIoApicInterruptSource*>(entry); reinterpret_cast<MadtIoApicInterruptSource*>(entry);
#if K_ACPI_DEBUG
dbgln("IO Source (Bus, IRQ, GSI, flags): {x}, {x}, {x}, {x}", dbgln("IO Source (Bus, IRQ, GSI, flags): {x}, {x}, {x}, {x}",
src->bus_source, src->irq_source, +src->global_system_interrupt, src->bus_source, src->irq_source, +src->global_system_interrupt,
+src->flags); +src->flags);
@ -187,9 +189,9 @@ void ParseMadt(SdtHeader* rsdt) {
break; break;
} }
case 4: { case 4: {
#if K_ACPI_DEBUG
MadtLocalApicNonMaskable* lnmi = MadtLocalApicNonMaskable* lnmi =
reinterpret_cast<MadtLocalApicNonMaskable*>(entry); reinterpret_cast<MadtLocalApicNonMaskable*>(entry);
#if K_ACPI_DEBUG
dbgln("Local NMI (proc id, flags, lint#): {x}, {x}, {x}", dbgln("Local NMI (proc id, flags, lint#): {x}, {x}, {x}",
lnmi->apic_processor_id, +lnmi->flags, lnmi->lint_num); lnmi->apic_processor_id, +lnmi->flags, lnmi->lint_num);
#endif #endif

View File

@ -41,7 +41,6 @@ static TaskStateSegment gTaskStateSegment;
extern "C" void ReloadSegments(); extern "C" void ReloadSegments();
uint64_t CreateSegment(uint64_t access, uint64_t flags) { uint64_t CreateSegment(uint64_t access, uint64_t flags) {
uint64_t base = 0;
access &= 0xFF; access &= 0xFF;
flags &= 0xF0; flags &= 0xF0;
flags |= 0xF; // For the highest 4 bits of the limit. flags |= 0xF; // For the highest 4 bits of the limit.

View File

@ -15,12 +15,6 @@ void dbgputchar(char c) {
outb(COM1, c); outb(COM1, c);
} }
void dbgcstr(const char* str) {
for (; *str != '\0'; str++) {
dbgputchar(*str);
}
}
void dbg(const glcr::StringView& str) { void dbg(const glcr::StringView& str) {
for (uint64_t i = 0; i < str.size(); i++) { for (uint64_t i = 0; i < str.size(); i++) {
dbgputchar(str[i]); dbgputchar(str[i]);

View File

@ -84,20 +84,6 @@ uint64_t LoadElfProgram(Process& dest_proc, uint64_t base, uint64_t offset) {
return header->entry; return header->entry;
} }
bool streq(const char* a, const char* b) {
while (true) {
if (*a == '\0' && *b == '\0') return true;
if (*a == '\0' || *b == '\0') {
return false;
}
if (*a != *b) {
return false;
}
a++;
b++;
}
}
void DumpModules() { void DumpModules() {
#if K_INIT_DEBUG #if K_INIT_DEBUG
const limine_module_response& resp = boot::GetModules(); const limine_module_response& resp = boot::GetModules();
@ -188,7 +174,7 @@ void LoadInitProgram() {
} }
// Start process. // Start process.
const limine_file& init_prog = GetInitProgram("/sys/yellowstone"); limine_file init_prog = GetInitProgram("/sys/yellowstone");
uint64_t entry = LoadElfProgram( uint64_t entry = LoadElfProgram(
*proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size); *proc, reinterpret_cast<uint64_t>(init_prog.address), init_prog.size);
proc->CreateThread()->Start(entry, port_cap, 0); proc->CreateThread()->Start(entry, port_cap, 0);