Compare commits
2 Commits
71e3521b87
...
2b27af5814
Author | SHA1 | Date |
---|---|---|
Drew Galbraith | 2b27af5814 | |
Drew Galbraith | 9c9fd167cd |
|
@ -14,6 +14,9 @@ class ByteBuffer {
|
||||||
|
|
||||||
~ByteBuffer() { delete[] buffer_; }
|
~ByteBuffer() { delete[] buffer_; }
|
||||||
|
|
||||||
|
uint8_t* RawPtr() { return buffer_; }
|
||||||
|
const uint8_t* RawPtr() const { return buffer_; }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void WriteAt(uint64_t offset, const T& object) {
|
void WriteAt(uint64_t offset, const T& object) {
|
||||||
// FIXME: Add bounds check here.
|
// FIXME: Add bounds check here.
|
||||||
|
|
|
@ -13,12 +13,23 @@ class CapBuffer {
|
||||||
|
|
||||||
~CapBuffer() { delete[] buffer_; }
|
~CapBuffer() { delete[] buffer_; }
|
||||||
|
|
||||||
|
uint64_t* RawPtr() { return buffer_; }
|
||||||
|
|
||||||
|
uint64_t UsedSlots() { return used_slots_; }
|
||||||
|
|
||||||
uint64_t At(uint64_t offset) const { return buffer_[offset]; }
|
uint64_t At(uint64_t offset) const { return buffer_[offset]; }
|
||||||
|
|
||||||
void WriteAt(uint64_t offset, uint64_t cap) { buffer_[offset] = cap; }
|
void WriteAt(uint64_t offset, uint64_t cap) {
|
||||||
|
buffer_[offset] = cap;
|
||||||
|
// This is fairly hacky considering we pass out the raw ptr.
|
||||||
|
if (used_slots_ < (offset + 1)) {
|
||||||
|
used_slots_ = offset + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t* buffer_;
|
uint64_t* buffer_;
|
||||||
|
uint64_t used_slots_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace glcr
|
} // namespace glcr
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
namespace {
|
namespace {
|
||||||
class NaiveAllocator {
|
class NaiveAllocator {
|
||||||
public:
|
public:
|
||||||
constexpr static uint64_t kSize = 0x4000;
|
constexpr static uint64_t kSize = 0x10000;
|
||||||
NaiveAllocator() {}
|
NaiveAllocator() {}
|
||||||
bool is_init() { return next_addr_ != 0; }
|
bool is_init() { return next_addr_ != 0; }
|
||||||
void Init() {
|
void Init() {
|
||||||
|
@ -23,6 +23,7 @@ class NaiveAllocator {
|
||||||
uint64_t addr = next_addr_;
|
uint64_t addr = next_addr_;
|
||||||
next_addr_ += size;
|
next_addr_ += size;
|
||||||
if (next_addr_ >= max_addr_) {
|
if (next_addr_ >= max_addr_) {
|
||||||
|
ZProcessExit(0xBEEF);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return reinterpret_cast<void*>(addr);
|
return reinterpret_cast<void*>(addr);
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
|
|
||||||
#include "mammoth/endpoint_client.h"
|
#include "mammoth/endpoint_client.h"
|
||||||
|
|
||||||
glcr::ErrorCode SpawnProcessFromElfRegion(
|
glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program,
|
||||||
uint64_t program, glcr::UniquePtr<EndpointClient> client);
|
z_cap_t yellowstone_client);
|
||||||
|
|
|
@ -96,8 +96,8 @@ uint64_t LoadElfProgram(uint64_t base, uint64_t as_cap) {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
glcr::ErrorCode SpawnProcessFromElfRegion(
|
glcr::ErrorCode SpawnProcessFromElfRegion(uint64_t program,
|
||||||
uint64_t program, glcr::UniquePtr<EndpointClient> client) {
|
z_cap_t yellowstone_client) {
|
||||||
uint64_t proc_cap;
|
uint64_t proc_cap;
|
||||||
uint64_t as_cap;
|
uint64_t as_cap;
|
||||||
uint64_t foreign_port_id;
|
uint64_t foreign_port_id;
|
||||||
|
@ -125,7 +125,7 @@ glcr::ErrorCode SpawnProcessFromElfRegion(
|
||||||
|
|
||||||
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_PROC, proc_cap));
|
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_PROC, proc_cap));
|
||||||
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_VMAS, as_cap));
|
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_SELF_VMAS, as_cap));
|
||||||
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_ENDPOINT, client->GetCap()));
|
RET_ERR(pclient.WriteMessage<uint64_t>(Z_INIT_ENDPOINT, yellowstone_client));
|
||||||
|
|
||||||
#if MAM_PROC_DEBUG
|
#if MAM_PROC_DEBUG
|
||||||
dbgln("Thread start");
|
dbgln("Thread start");
|
||||||
|
|
|
@ -14,7 +14,7 @@ target_include_directories(denali
|
||||||
target_link_libraries(denali
|
target_link_libraries(denali
|
||||||
glacier
|
glacier
|
||||||
mammoth
|
mammoth
|
||||||
yellowstone_stub
|
yellowstone_yunq
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(denali PROPERTIES
|
set_target_properties(denali PROPERTIES
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <mammoth/port_client.h>
|
#include <mammoth/port_client.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <yellowstone.h>
|
#include <yellowstone.h>
|
||||||
#include <yellowstone_stub.h>
|
#include <yellowstone/yellowstone.yunq.client.h>
|
||||||
|
|
||||||
#include "ahci/ahci_driver.h"
|
#include "ahci/ahci_driver.h"
|
||||||
#include "denali_server.h"
|
#include "denali_server.h"
|
||||||
|
@ -15,8 +15,12 @@ uint64_t main(uint64_t init_port_cap) {
|
||||||
glcr::UniquePtr<EndpointClient> yellowstone =
|
glcr::UniquePtr<EndpointClient> yellowstone =
|
||||||
EndpointClient::AdoptEndpoint(gInitEndpointCap);
|
EndpointClient::AdoptEndpoint(gInitEndpointCap);
|
||||||
|
|
||||||
YellowstoneStub stub(gInitEndpointCap);
|
YellowstoneClient stub(gInitEndpointCap);
|
||||||
ASSIGN_OR_RETURN(MappedMemoryRegion ahci_region, stub.GetAhciConfig());
|
Empty empty;
|
||||||
|
AhciInfo ahci;
|
||||||
|
RET_ERR(stub.GetAhciInfo(empty, ahci));
|
||||||
|
MappedMemoryRegion ahci_region =
|
||||||
|
MappedMemoryRegion::FromCapability(ahci.ahci_region());
|
||||||
ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(ahci_region));
|
ASSIGN_OR_RETURN(auto driver, AhciDriver::Init(ahci_region));
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(glcr::UniquePtr<DenaliServer> server,
|
ASSIGN_OR_RETURN(glcr::UniquePtr<DenaliServer> server,
|
||||||
|
@ -24,7 +28,14 @@ uint64_t main(uint64_t init_port_cap) {
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> client,
|
ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> client,
|
||||||
server->CreateClient());
|
server->CreateClient());
|
||||||
check(stub.Register("denali", *client));
|
|
||||||
|
RegisterInfo reg;
|
||||||
|
Empty empty2;
|
||||||
|
check(stub.GetRegister(empty2, reg));
|
||||||
|
|
||||||
|
PortClient register_port = PortClient::AdoptPort(reg.register_port());
|
||||||
|
|
||||||
|
check(register_port.WriteString("denali", client->GetCap()));
|
||||||
|
|
||||||
Thread server_thread = server->RunServer();
|
Thread server_thread = server->RunServer();
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ target_include_directories(victoriafalls
|
||||||
target_link_libraries(victoriafalls
|
target_link_libraries(victoriafalls
|
||||||
glacier
|
glacier
|
||||||
mammoth
|
mammoth
|
||||||
yellowstone_stub
|
yellowstone_yunq
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(victoriafalls PROPERTIES
|
set_target_properties(victoriafalls PROPERTIES
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#include "fs/ext2/ext2_block_reader.h"
|
#include "fs/ext2/ext2_block_reader.h"
|
||||||
|
|
||||||
|
#include "mammoth/debug.h"
|
||||||
|
|
||||||
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
|
glcr::ErrorOr<glcr::SharedPtr<Ext2BlockReader>> Ext2BlockReader::Init(
|
||||||
ScopedDenaliClient&& denali) {
|
ScopedDenaliClient&& denali) {
|
||||||
// Read 1024 bytes from 1024 offset.
|
// Read 1024 bytes from 1024 offset.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include <mammoth/debug.h>
|
#include <mammoth/debug.h>
|
||||||
#include <mammoth/init.h>
|
#include <mammoth/init.h>
|
||||||
#include <yellowstone_stub.h>
|
#include <yellowstone/yellowstone.yunq.client.h>
|
||||||
|
|
||||||
#include "fs/ext2/ext2_driver.h"
|
#include "fs/ext2/ext2_driver.h"
|
||||||
|
|
||||||
|
@ -9,8 +9,14 @@ uint64_t main(uint64_t init_cap) {
|
||||||
|
|
||||||
dbgln("VFs Started");
|
dbgln("VFs Started");
|
||||||
|
|
||||||
YellowstoneStub yellowstone(gInitEndpointCap);
|
YellowstoneClient yellowstone(gInitEndpointCap);
|
||||||
ASSIGN_OR_RETURN(ScopedDenaliClient denali, yellowstone.GetDenali());
|
Empty empty;
|
||||||
|
DenaliInfo denali_info;
|
||||||
|
RET_ERR(yellowstone.GetDenali(empty, denali_info));
|
||||||
|
dbgln("LBA (recv): %u", denali_info.lba_offset());
|
||||||
|
ScopedDenaliClient denali(
|
||||||
|
EndpointClient::AdoptEndpoint(denali_info.denali_endpoint()),
|
||||||
|
denali_info.device_id(), denali_info.lba_offset());
|
||||||
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
|
ASSIGN_OR_RETURN(Ext2Driver ext2, Ext2Driver::Init(glcr::Move(denali)));
|
||||||
|
|
||||||
ASSIGN_OR_RETURN(Inode * root, ext2.GetInode(2));
|
ASSIGN_OR_RETURN(Inode * root, ext2.GetInode(2));
|
||||||
|
|
|
@ -12,6 +12,7 @@ target_link_libraries(yellowstone
|
||||||
mammoth
|
mammoth
|
||||||
glacier
|
glacier
|
||||||
denali_stub
|
denali_stub
|
||||||
|
yellowstone_yunq
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(yellowstone PROPERTIES
|
set_target_properties(yellowstone PROPERTIES
|
||||||
|
@ -20,20 +21,22 @@ set_target_properties(yellowstone PROPERTIES
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
add_library(yellowstone_stub
|
add_library(yellowstone_yunq
|
||||||
stub/yellowstone_stub.cpp
|
include/yellowstone/yellowstone.yunq.cpp
|
||||||
|
include/yellowstone/yellowstone.yunq.client.cpp
|
||||||
|
include/yellowstone/yellowstone.yunq.server.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(yellowstone_stub
|
target_include_directories(yellowstone_yunq
|
||||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
||||||
|
|
||||||
target_link_libraries(yellowstone_stub
|
target_link_libraries(yellowstone_yunq
|
||||||
denali_stub
|
denali_stub
|
||||||
mammoth
|
mammoth
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(yellowstone_stub PROPERTIES
|
set_target_properties(yellowstone_yunq PROPERTIES
|
||||||
COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}"
|
COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BASE_COMPILE_FLAGS}"
|
||||||
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}"
|
LINK_FLAGS "${CMAKE_EXE_LINK_FLAGS} ${BASE_LINK_FLAGS}"
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
interface Yellowstone {
|
||||||
|
method GetRegister(Empty) -> (RegisterInfo);
|
||||||
|
method GetAhciInfo(Empty) -> (AhciInfo);
|
||||||
|
method GetDenali(Empty) -> (DenaliInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
message Empty {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
message RegisterInfo {
|
||||||
|
capability register_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
message AhciInfo {
|
||||||
|
capability ahci_region;
|
||||||
|
u64 region_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
message DenaliInfo {
|
||||||
|
capability denali_endpoint;
|
||||||
|
u64 device_id;
|
||||||
|
u64 lba_offset;
|
||||||
|
}
|
|
@ -0,0 +1,105 @@
|
||||||
|
// Generated file - DO NOT MODIFY
|
||||||
|
#include "yellowstone.yunq.client.h"
|
||||||
|
|
||||||
|
#include <glacier/buffer/byte_buffer.h>
|
||||||
|
#include <glacier/buffer/cap_buffer.h>
|
||||||
|
#include <zcall.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glcr::ErrorCode YellowstoneClient::GetRegister(const Empty& request, RegisterInfo& response) {
|
||||||
|
uint64_t buffer_size = kBufferSize;
|
||||||
|
uint64_t cap_size = kCapBufferSize;
|
||||||
|
|
||||||
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
|
buffer_.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer_.WriteAt<uint64_t>(8, 0);
|
||||||
|
|
||||||
|
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
|
||||||
|
buffer_.WriteAt<uint32_t>(4, 16 + length);
|
||||||
|
|
||||||
|
z_cap_t reply_port_cap;
|
||||||
|
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||||
|
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap));
|
||||||
|
|
||||||
|
// FIXME: Add a way to zero out the first buffer.
|
||||||
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
|
||||||
|
|
||||||
|
if (buffer_.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Response Code.
|
||||||
|
RET_ERR(buffer_.At<uint64_t>(8));
|
||||||
|
|
||||||
|
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& response) {
|
||||||
|
uint64_t buffer_size = kBufferSize;
|
||||||
|
uint64_t cap_size = kCapBufferSize;
|
||||||
|
|
||||||
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
|
buffer_.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer_.WriteAt<uint64_t>(8, 1);
|
||||||
|
|
||||||
|
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
|
||||||
|
buffer_.WriteAt<uint32_t>(4, 16 + length);
|
||||||
|
|
||||||
|
z_cap_t reply_port_cap;
|
||||||
|
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||||
|
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap));
|
||||||
|
|
||||||
|
// FIXME: Add a way to zero out the first buffer.
|
||||||
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
|
||||||
|
|
||||||
|
if (buffer_.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Response Code.
|
||||||
|
RET_ERR(buffer_.At<uint64_t>(8));
|
||||||
|
|
||||||
|
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& response) {
|
||||||
|
uint64_t buffer_size = kBufferSize;
|
||||||
|
uint64_t cap_size = kCapBufferSize;
|
||||||
|
|
||||||
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
|
buffer_.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer_.WriteAt<uint64_t>(8, 2);
|
||||||
|
|
||||||
|
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
|
||||||
|
buffer_.WriteAt<uint32_t>(4, 16 + length);
|
||||||
|
|
||||||
|
z_cap_t reply_port_cap;
|
||||||
|
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||||
|
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap));
|
||||||
|
|
||||||
|
// FIXME: Add a way to zero out the first buffer.
|
||||||
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
|
||||||
|
|
||||||
|
if (buffer_.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_RESPONSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check Response Code.
|
||||||
|
RET_ERR(buffer_.At<uint64_t>(8));
|
||||||
|
|
||||||
|
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||||
|
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Generated file - DO NOT MODIFY
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/buffer/byte_buffer.h>
|
||||||
|
#include <glacier/buffer/cap_buffer.h>
|
||||||
|
#include <glacier/status/error.h>
|
||||||
|
#include <ztypes.h>
|
||||||
|
|
||||||
|
#include "yellowstone.yunq.h"
|
||||||
|
|
||||||
|
class YellowstoneClient {
|
||||||
|
public:
|
||||||
|
YellowstoneClient(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {}
|
||||||
|
YellowstoneClient(const YellowstoneClient&) = delete;
|
||||||
|
YellowstoneClient(YellowstoneClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
|
||||||
|
|
||||||
|
z_cap_t Capability() { return endpoint_; }
|
||||||
|
|
||||||
|
|
||||||
|
[[nodiscard]] glcr::ErrorCode GetRegister(const Empty& request, RegisterInfo& response);
|
||||||
|
|
||||||
|
[[nodiscard]] glcr::ErrorCode GetAhciInfo(const Empty& request, AhciInfo& response);
|
||||||
|
|
||||||
|
[[nodiscard]] glcr::ErrorCode GetDenali(const Empty& request, DenaliInfo& response);
|
||||||
|
|
||||||
|
private:
|
||||||
|
z_cap_t endpoint_;
|
||||||
|
uint64_t kBufferSize = 0x1000;
|
||||||
|
glcr::ByteBuffer buffer_{kBufferSize};
|
||||||
|
uint64_t kCapBufferSize = 0x10;
|
||||||
|
glcr::CapBuffer cap_buffer_{kCapBufferSize};
|
||||||
|
};
|
|
@ -0,0 +1,204 @@
|
||||||
|
// Generated file -- DO NOT MODIFY.
|
||||||
|
#include "yellowstone.yunq.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const uint64_t header_size = 24; // 4x uint32, 1x uint64
|
||||||
|
|
||||||
|
struct ExtPointer {
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t length;
|
||||||
|
};
|
||||||
|
|
||||||
|
void CheckHeader(const glcr::ByteBuffer& bytes) {
|
||||||
|
// TODO: Check ident.
|
||||||
|
// TODO: Parse core size.
|
||||||
|
// TODO: Parse extension size.
|
||||||
|
// TODO: Check CRC32
|
||||||
|
// TODO: Parse options.
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, uint32_t extension_size) {
|
||||||
|
bytes.WriteAt<uint32_t>(offset + 0, 0xDEADBEEF); // TODO: Chose a more unique ident sequence.
|
||||||
|
bytes.WriteAt<uint32_t>(offset + 4, core_size);
|
||||||
|
bytes.WriteAt<uint32_t>(offset + 8, extension_size);
|
||||||
|
bytes.WriteAt<uint32_t>(offset + 12, 0); // TODO: Calculate CRC32.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + 16, 0); // TODO: Add options.
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Empty::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Empty::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 0;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t Empty::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 0;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
uint64_t next_cap = 0;
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse register_port.
|
||||||
|
// FIXME: Implement in-buffer capabilities for inprocess serialization.
|
||||||
|
set_register_port(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse register_port.
|
||||||
|
uint64_t register_port_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 0));
|
||||||
|
|
||||||
|
set_register_port(caps.At(register_port_ptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 1;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
// Write register_port.
|
||||||
|
// FIXME: Implement inbuffer capabilities.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), 0);
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RegisterInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 1;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
uint64_t next_cap = 0;
|
||||||
|
// Write register_port.
|
||||||
|
caps.WriteAt(next_cap, register_port());
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), next_cap++);
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
void AhciInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse ahci_region.
|
||||||
|
// FIXME: Implement in-buffer capabilities for inprocess serialization.
|
||||||
|
set_ahci_region(0);
|
||||||
|
// Parse region_length.
|
||||||
|
set_region_length(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AhciInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse ahci_region.
|
||||||
|
uint64_t ahci_region_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 0));
|
||||||
|
|
||||||
|
set_ahci_region(caps.At(ahci_region_ptr));
|
||||||
|
// Parse region_length.
|
||||||
|
set_region_length(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t AhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 2;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
// Write ahci_region.
|
||||||
|
// FIXME: Implement inbuffer capabilities.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), 0);
|
||||||
|
// Write region_length.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), region_length());
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t AhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 2;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
uint64_t next_cap = 0;
|
||||||
|
// Write ahci_region.
|
||||||
|
caps.WriteAt(next_cap, ahci_region());
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), next_cap++);
|
||||||
|
// Write region_length.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), region_length());
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
void DenaliInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse denali_endpoint.
|
||||||
|
// FIXME: Implement in-buffer capabilities for inprocess serialization.
|
||||||
|
set_denali_endpoint(0);
|
||||||
|
// Parse device_id.
|
||||||
|
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||||
|
// Parse lba_offset.
|
||||||
|
set_lba_offset(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DenaliInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||||
|
CheckHeader(bytes);
|
||||||
|
// Parse denali_endpoint.
|
||||||
|
uint64_t denali_endpoint_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 0));
|
||||||
|
|
||||||
|
set_denali_endpoint(caps.At(denali_endpoint_ptr));
|
||||||
|
// Parse device_id.
|
||||||
|
set_device_id(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||||
|
// Parse lba_offset.
|
||||||
|
set_lba_offset(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DenaliInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 3;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
// Write denali_endpoint.
|
||||||
|
// FIXME: Implement inbuffer capabilities.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), 0);
|
||||||
|
// Write device_id.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), device_id());
|
||||||
|
// Write lba_offset.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), lba_offset());
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t DenaliInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
|
uint32_t next_extension = header_size + 8 * 3;
|
||||||
|
const uint32_t core_size = next_extension;
|
||||||
|
uint64_t next_cap = 0;
|
||||||
|
// Write denali_endpoint.
|
||||||
|
caps.WriteAt(next_cap, denali_endpoint());
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 0), next_cap++);
|
||||||
|
// Write device_id.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), device_id());
|
||||||
|
// Write lba_offset.
|
||||||
|
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), lba_offset());
|
||||||
|
|
||||||
|
// The next extension pointer is the length of the message.
|
||||||
|
WriteHeader(bytes, offset, core_size, next_extension);
|
||||||
|
|
||||||
|
return next_extension;
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Generated file - DO NOT MODIFY
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/buffer/byte_buffer.h>
|
||||||
|
#include <glacier/buffer/cap_buffer.h>
|
||||||
|
#include <glacier/string/string.h>
|
||||||
|
#include <ztypes.h>
|
||||||
|
class Empty {
|
||||||
|
public:
|
||||||
|
Empty() {}
|
||||||
|
// Delete copy and move until implemented.
|
||||||
|
Empty(const Empty&) = delete;
|
||||||
|
Empty(Empty&&) = delete;
|
||||||
|
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
class RegisterInfo {
|
||||||
|
public:
|
||||||
|
RegisterInfo() {}
|
||||||
|
// Delete copy and move until implemented.
|
||||||
|
RegisterInfo(const RegisterInfo&) = delete;
|
||||||
|
RegisterInfo(RegisterInfo&&) = delete;
|
||||||
|
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
|
z_cap_t register_port() const { return register_port_; }
|
||||||
|
void set_register_port(const z_cap_t& value) { register_port_ = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
z_cap_t register_port_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class AhciInfo {
|
||||||
|
public:
|
||||||
|
AhciInfo() {}
|
||||||
|
// Delete copy and move until implemented.
|
||||||
|
AhciInfo(const AhciInfo&) = delete;
|
||||||
|
AhciInfo(AhciInfo&&) = delete;
|
||||||
|
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
|
z_cap_t ahci_region() const { return ahci_region_; }
|
||||||
|
void set_ahci_region(const z_cap_t& value) { ahci_region_ = value; }
|
||||||
|
uint64_t region_length() const { return region_length_; }
|
||||||
|
void set_region_length(const uint64_t& value) { region_length_ = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
z_cap_t ahci_region_;
|
||||||
|
uint64_t region_length_;
|
||||||
|
|
||||||
|
};
|
||||||
|
class DenaliInfo {
|
||||||
|
public:
|
||||||
|
DenaliInfo() {}
|
||||||
|
// Delete copy and move until implemented.
|
||||||
|
DenaliInfo(const DenaliInfo&) = delete;
|
||||||
|
DenaliInfo(DenaliInfo&&) = delete;
|
||||||
|
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
|
z_cap_t denali_endpoint() const { return denali_endpoint_; }
|
||||||
|
void set_denali_endpoint(const z_cap_t& value) { denali_endpoint_ = value; }
|
||||||
|
uint64_t device_id() const { return device_id_; }
|
||||||
|
void set_device_id(const uint64_t& value) { device_id_ = value; }
|
||||||
|
uint64_t lba_offset() const { return lba_offset_; }
|
||||||
|
void set_lba_offset(const uint64_t& value) { lba_offset_ = value; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
z_cap_t denali_endpoint_;
|
||||||
|
uint64_t device_id_;
|
||||||
|
uint64_t lba_offset_;
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,124 @@
|
||||||
|
// Generated file -- DO NOT MODIFY.
|
||||||
|
#include "yellowstone.yunq.server.h"
|
||||||
|
|
||||||
|
#include <mammoth/debug.h>
|
||||||
|
#include <zcall.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
|
const uint32_t kHeaderSize = 0x10;
|
||||||
|
|
||||||
|
void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) {
|
||||||
|
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer.WriteAt<uint32_t>(4, kHeaderSize);
|
||||||
|
buffer.WriteAt<uint64_t>(8, err);
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) {
|
||||||
|
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer.WriteAt<uint32_t>(4, kHeaderSize + message_length);
|
||||||
|
buffer.WriteAt<uint64_t>(8, glcr::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void YellowstoneServerBaseThreadBootstrap(void* server_base) {
|
||||||
|
((YellowstoneServerBase*)server_base)->ServerThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorOr<YellowstoneClient> YellowstoneServerBase::CreateClient() {
|
||||||
|
uint64_t client_cap;
|
||||||
|
// FIXME: Restrict permissions to send-only here.
|
||||||
|
RET_ERR(ZCapDuplicate(endpoint_, &client_cap));
|
||||||
|
return YellowstoneClient(client_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread YellowstoneServerBase::RunServer() {
|
||||||
|
return Thread(YellowstoneServerBaseThreadBootstrap, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void YellowstoneServerBase::ServerThread() {
|
||||||
|
glcr::ByteBuffer recv_buffer(0x1000);
|
||||||
|
glcr::ByteBuffer resp_buffer(0x1000);
|
||||||
|
uint64_t resp_cap_size = 0x10;
|
||||||
|
glcr::CapBuffer resp_cap(resp_cap_size);
|
||||||
|
z_cap_t reply_port_cap;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint64_t recv_buf_size = 0x1000;
|
||||||
|
glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &reply_port_cap);
|
||||||
|
if (recv_err != glcr::OK) {
|
||||||
|
dbgln("Error in receive: %x", recv_err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t resp_length = 0;
|
||||||
|
|
||||||
|
glcr::ErrorCode reply_err = glcr::OK;
|
||||||
|
glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap);
|
||||||
|
if (err != glcr::OK) {
|
||||||
|
WriteError(resp_buffer, err);
|
||||||
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr);
|
||||||
|
} else {
|
||||||
|
WriteHeader(resp_buffer, resp_length);
|
||||||
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr());
|
||||||
|
}
|
||||||
|
if (reply_err != glcr::OK) {
|
||||||
|
dbgln("Error in reply: %x", recv_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& request,
|
||||||
|
glcr::ByteBuffer& response, uint64_t& resp_length,
|
||||||
|
glcr::CapBuffer& resp_caps) {
|
||||||
|
if (request.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t method_select = request.At<uint64_t>(8);
|
||||||
|
|
||||||
|
switch(method_select) {
|
||||||
|
case 0: {
|
||||||
|
Empty yunq_request;
|
||||||
|
RegisterInfo yunq_response;
|
||||||
|
|
||||||
|
yunq_request.ParseFromBytes(request, kHeaderSize);
|
||||||
|
|
||||||
|
RET_ERR(HandleGetRegister(yunq_request, yunq_response));
|
||||||
|
|
||||||
|
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
Empty yunq_request;
|
||||||
|
AhciInfo yunq_response;
|
||||||
|
|
||||||
|
yunq_request.ParseFromBytes(request, kHeaderSize);
|
||||||
|
|
||||||
|
RET_ERR(HandleGetAhciInfo(yunq_request, yunq_response));
|
||||||
|
|
||||||
|
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
Empty yunq_request;
|
||||||
|
DenaliInfo yunq_response;
|
||||||
|
|
||||||
|
yunq_request.ParseFromBytes(request, kHeaderSize);
|
||||||
|
|
||||||
|
RET_ERR(HandleGetDenali(yunq_request, yunq_response));
|
||||||
|
|
||||||
|
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return glcr::UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Generated File -- DO NOT MODIFY.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/status/error_or.h>
|
||||||
|
#include <mammoth/thread.h>
|
||||||
|
#include <ztypes.h>
|
||||||
|
|
||||||
|
#include "yellowstone.yunq.h"
|
||||||
|
#include "yellowstone.yunq.client.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class YellowstoneServerBase {
|
||||||
|
public:
|
||||||
|
YellowstoneServerBase(z_cap_t Yellowstone_cap) : endpoint_(Yellowstone_cap) {}
|
||||||
|
YellowstoneServerBase(const YellowstoneServerBase&) = delete;
|
||||||
|
YellowstoneServerBase(YellowstoneServerBase&&) = delete;
|
||||||
|
|
||||||
|
glcr::ErrorOr<YellowstoneClient> CreateClient();
|
||||||
|
|
||||||
|
[[nodiscard]] Thread RunServer();
|
||||||
|
|
||||||
|
|
||||||
|
[[nodiscard]] virtual glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) = 0;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
z_cap_t endpoint_;
|
||||||
|
|
||||||
|
friend void YellowstoneServerBaseThreadBootstrap(void*);
|
||||||
|
void ServerThread();
|
||||||
|
|
||||||
|
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
||||||
|
uint64_t& resp_length,
|
||||||
|
glcr::CapBuffer& resp_caps);
|
||||||
|
};
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
#include "include/yellowstone_stub.h"
|
|
||||||
|
|
||||||
#include <denali/denali_client.h>
|
|
||||||
|
|
||||||
#include "include/yellowstone.h"
|
|
||||||
|
|
||||||
YellowstoneStub::YellowstoneStub(z_cap_t yellowstone_cap)
|
|
||||||
: yellowstone_stub_(EndpointClient::AdoptEndpoint(yellowstone_cap)) {}
|
|
||||||
|
|
||||||
glcr::ErrorOr<MappedMemoryRegion> YellowstoneStub::GetAhciConfig() {
|
|
||||||
YellowstoneGetReq req{
|
|
||||||
.type = kYellowstoneGetAhci,
|
|
||||||
};
|
|
||||||
ASSIGN_OR_RETURN(
|
|
||||||
auto resp_cap_pair,
|
|
||||||
(yellowstone_stub_->CallEndpointGetCap<YellowstoneGetReq,
|
|
||||||
YellowstoneGetAhciResp>(req)));
|
|
||||||
return MappedMemoryRegion::FromCapability(resp_cap_pair.second());
|
|
||||||
}
|
|
||||||
|
|
||||||
glcr::ErrorOr<ScopedDenaliClient> YellowstoneStub::GetDenali() {
|
|
||||||
YellowstoneGetReq req{
|
|
||||||
.type = kYellowstoneGetDenali,
|
|
||||||
};
|
|
||||||
ASSIGN_OR_RETURN(
|
|
||||||
auto resp_and_cap,
|
|
||||||
(yellowstone_stub_->CallEndpointGetCap<YellowstoneGetReq,
|
|
||||||
YellowstoneGetDenaliResp>(req)));
|
|
||||||
return ScopedDenaliClient(
|
|
||||||
EndpointClient::AdoptEndpoint(resp_and_cap.second()), 0,
|
|
||||||
resp_and_cap.first().lba_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
glcr::ErrorCode YellowstoneStub::Register(glcr::String name,
|
|
||||||
const EndpointClient& client) {
|
|
||||||
if (register_port_.empty()) {
|
|
||||||
YellowstoneGetReq req{
|
|
||||||
.type = kYellowstoneGetRegistration,
|
|
||||||
};
|
|
||||||
ASSIGN_OR_RETURN(
|
|
||||||
auto resp_cap,
|
|
||||||
(yellowstone_stub_->CallEndpointGetCap<
|
|
||||||
YellowstoneGetReq, YellowstoneGetRegistrationResp>(req)));
|
|
||||||
register_port_ = PortClient::AdoptPort(resp_cap.second());
|
|
||||||
}
|
|
||||||
|
|
||||||
return register_port_.WriteString(name, client.GetCap());
|
|
||||||
}
|
|
|
@ -18,9 +18,8 @@ uint64_t main(uint64_t port_cap) {
|
||||||
|
|
||||||
uint64_t vaddr;
|
uint64_t vaddr;
|
||||||
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr));
|
check(ZAddressSpaceMap(gSelfVmasCap, 0, gBootDenaliVmmoCap, &vaddr));
|
||||||
ASSIGN_OR_RETURN(glcr::UniquePtr<EndpointClient> client,
|
ASSIGN_OR_RETURN(YellowstoneClient client, server->CreateClient());
|
||||||
server->CreateClient());
|
check(SpawnProcessFromElfRegion(vaddr, client.Capability()));
|
||||||
check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client)));
|
|
||||||
|
|
||||||
check(server_thread.Join());
|
check(server_thread.Join());
|
||||||
check(registration_thread.Join());
|
check(registration_thread.Join());
|
||||||
|
|
|
@ -43,54 +43,36 @@ glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> YellowstoneServer::Create() {
|
||||||
}
|
}
|
||||||
|
|
||||||
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, PortServer port)
|
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, PortServer port)
|
||||||
: EndpointServer(endpoint_cap), register_port_(port) {}
|
: YellowstoneServerBase(endpoint_cap), register_port_(port) {}
|
||||||
|
|
||||||
Thread YellowstoneServer::RunRegistration() {
|
Thread YellowstoneServer::RunRegistration() {
|
||||||
return Thread(RegistrationThreadBootstrap, this);
|
return Thread(RegistrationThreadBootstrap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode YellowstoneServer::HandleRequest(RequestContext& request,
|
glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&,
|
||||||
ResponseContext& response) {
|
AhciInfo& info) {
|
||||||
switch (request.request_id()) {
|
info.set_ahci_region(pci_reader_.GetAhciVmmo());
|
||||||
case kYellowstoneGetAhci: {
|
info.set_region_length(kPcieConfigurationSize);
|
||||||
dbgln("Yellowstone::GetAHCI");
|
return glcr::OK;
|
||||||
YellowstoneGetAhciResp resp{
|
}
|
||||||
.type = kYellowstoneGetAhci,
|
|
||||||
.ahci_length = kPcieConfigurationSize,
|
glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&,
|
||||||
};
|
DenaliInfo& info) {
|
||||||
z_cap_t vmmo_cap = pci_reader_.GetAhciVmmo();
|
z_cap_t new_denali;
|
||||||
RET_ERR(
|
check(ZCapDuplicate(denali_cap_, &new_denali));
|
||||||
response.WriteStructWithCap<YellowstoneGetAhciResp>(resp, vmmo_cap));
|
info.set_denali_endpoint(new_denali);
|
||||||
break;
|
info.set_device_id(device_id_);
|
||||||
}
|
info.set_lba_offset(lba_offset_);
|
||||||
case kYellowstoneGetRegistration: {
|
return glcr::OK;
|
||||||
dbgln("Yellowstone::GetRegistration");
|
}
|
||||||
auto client_or = register_port_.CreateClient();
|
glcr::ErrorCode YellowstoneServer::HandleGetRegister(const Empty&,
|
||||||
if (!client_or.ok()) {
|
RegisterInfo& info) {
|
||||||
check(client_or.error());
|
auto client_or = register_port_.CreateClient();
|
||||||
}
|
if (!client_or.ok()) {
|
||||||
YellowstoneGetRegistrationResp resp;
|
dbgln("Error creating register client: %u", client_or.error());
|
||||||
uint64_t reg_cap = client_or.value().cap();
|
return glcr::INTERNAL;
|
||||||
RET_ERR(response.WriteStructWithCap(resp, reg_cap));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case kYellowstoneGetDenali: {
|
|
||||||
dbgln("Yellowstone::GetDenali");
|
|
||||||
z_cap_t new_denali;
|
|
||||||
check(ZCapDuplicate(denali_cap_, &new_denali));
|
|
||||||
YellowstoneGetDenaliResp resp{
|
|
||||||
.type = kYellowstoneGetDenali,
|
|
||||||
.device_id = device_id_,
|
|
||||||
.lba_offset = lba_offset_,
|
|
||||||
};
|
|
||||||
RET_ERR(response.WriteStructWithCap(resp, new_denali));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
dbgln("Unknown request type: %x", request.request_id());
|
|
||||||
return glcr::UNIMPLEMENTED;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
info.set_register_port(client_or.value().cap());
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,7 +100,7 @@ void YellowstoneServer::RegistrationThread() {
|
||||||
if (!client_or.ok()) {
|
if (!client_or.ok()) {
|
||||||
check(client_or.error());
|
check(client_or.error());
|
||||||
}
|
}
|
||||||
check(SpawnProcessFromElfRegion(vaddr, glcr::Move(client_or.value())));
|
check(SpawnProcessFromElfRegion(vaddr, client_or.value().Capability()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
#include <mammoth/thread.h>
|
#include <mammoth/thread.h>
|
||||||
|
|
||||||
#include "hw/pcie.h"
|
#include "hw/pcie.h"
|
||||||
|
#include "include/yellowstone/yellowstone.yunq.server.h"
|
||||||
|
|
||||||
class YellowstoneServer : public EndpointServer {
|
class YellowstoneServer : public YellowstoneServerBase {
|
||||||
public:
|
public:
|
||||||
static glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> Create();
|
static glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> Create();
|
||||||
|
|
||||||
|
@ -16,8 +17,9 @@ class YellowstoneServer : public EndpointServer {
|
||||||
|
|
||||||
void RegistrationThread();
|
void RegistrationThread();
|
||||||
|
|
||||||
virtual glcr::ErrorCode HandleRequest(RequestContext& request,
|
glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) override;
|
||||||
ResponseContext& response) override;
|
glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) override;
|
||||||
|
glcr::ErrorCode HandleGetRegister(const Empty&, RegisterInfo&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// FIXME: Separate this to its own service.
|
// FIXME: Separate this to its own service.
|
||||||
|
|
|
@ -3,41 +3,37 @@
|
||||||
|
|
||||||
#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 <zcall.h>
|
||||||
|
|
||||||
{% for interface in interfaces %}
|
{% for interface in interfaces %}
|
||||||
{% for method in interface.methods %}
|
{% for method in interface.methods %}
|
||||||
|
|
||||||
glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response) {
|
glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request, {{method.response}}& response) {
|
||||||
uint64_t buffer_size = 0x1000;
|
uint64_t buffer_size = kBufferSize;
|
||||||
// FIXME: Maybe raise this limit.
|
uint64_t cap_size = kCapBufferSize;
|
||||||
uint64_t cap_size = 100;
|
|
||||||
glcr::ByteBuffer buffer(buffer_size);
|
|
||||||
glcr::CapBuffer caps(cap_size);
|
|
||||||
|
|
||||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
buffer_.WriteAt<uint32_t>(0, kSentinel);
|
||||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
buffer_.WriteAt<uint64_t>(8, {{loop.index0}});
|
||||||
|
|
||||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
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;
|
||||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap));
|
||||||
|
|
||||||
// FIXME: Add a way to zero out the first buffer.
|
// FIXME: Add a way to zero out the first buffer.
|
||||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
|
||||||
glcr::CapBuffer recv_caps(cap_size);
|
|
||||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
|
||||||
|
|
||||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
if (buffer_.At<uint32_t>(0) != kSentinel) {
|
||||||
return glcr::INVALID_RESPONSE;
|
return glcr::INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Response Code.
|
// Check Response Code.
|
||||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
RET_ERR(buffer_.At<uint64_t>(8));
|
||||||
|
|
||||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||||
|
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// Generated file - DO NOT MODIFY
|
// Generated file - DO NOT MODIFY
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/buffer/byte_buffer.h>
|
||||||
|
#include <glacier/buffer/cap_buffer.h>
|
||||||
|
#include <glacier/status/error.h>
|
||||||
#include <ztypes.h>
|
#include <ztypes.h>
|
||||||
|
|
||||||
#include "{{file}}.h"
|
#include "{{file}}.h"
|
||||||
|
@ -10,12 +13,19 @@ 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&&) = delete;
|
{{interface.name}}Client({{interface.name}}Client&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
|
||||||
|
|
||||||
|
z_cap_t Capability() { return endpoint_; }
|
||||||
|
|
||||||
{% for method in interface.methods %}
|
{% for method in interface.methods %}
|
||||||
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response);
|
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response);
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
private:
|
private:
|
||||||
z_cap_t endpoint_;
|
z_cap_t endpoint_;
|
||||||
|
uint64_t kBufferSize = 0x1000;
|
||||||
|
glcr::ByteBuffer buffer_{kBufferSize};
|
||||||
|
uint64_t kCapBufferSize = 0x10;
|
||||||
|
glcr::CapBuffer cap_buffer_{kCapBufferSize};
|
||||||
};
|
};
|
||||||
|
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
|
@ -3,41 +3,37 @@
|
||||||
|
|
||||||
#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 <zcall.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
glcr::ErrorCode open(const OpenFileRequest& request, File& response) {
|
glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response) {
|
||||||
uint64_t buffer_size = 0x1000;
|
uint64_t buffer_size = kBufferSize;
|
||||||
// FIXME: Maybe raise this limit.
|
uint64_t cap_size = kCapBufferSize;
|
||||||
uint64_t cap_size = 100;
|
|
||||||
glcr::ByteBuffer buffer(buffer_size);
|
|
||||||
glcr::CapBuffer caps(cap_size);
|
|
||||||
|
|
||||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
buffer_.WriteAt<uint32_t>(0, kSentinel);
|
||||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
buffer_.WriteAt<uint64_t>(8, 0);
|
||||||
|
|
||||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
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;
|
||||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), &reply_port_cap));
|
||||||
|
|
||||||
// FIXME: Add a way to zero out the first buffer.
|
// FIXME: Add a way to zero out the first buffer.
|
||||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
|
||||||
glcr::CapBuffer recv_caps(cap_size);
|
|
||||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
|
||||||
|
|
||||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
if (buffer_.At<uint32_t>(0) != kSentinel) {
|
||||||
return glcr::INVALID_RESPONSE;
|
return glcr::INVALID_RESPONSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check Response Code.
|
// Check Response Code.
|
||||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
RET_ERR(buffer_.At<uint64_t>(8));
|
||||||
|
|
||||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||||
|
|
||||||
return glcr::OK;
|
return glcr::OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
// Generated file - DO NOT MODIFY
|
// Generated file - DO NOT MODIFY
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/buffer/byte_buffer.h>
|
||||||
|
#include <glacier/buffer/cap_buffer.h>
|
||||||
|
#include <glacier/status/error.h>
|
||||||
#include <ztypes.h>
|
#include <ztypes.h>
|
||||||
|
|
||||||
#include "example.yunq.h"
|
#include "example.yunq.h"
|
||||||
|
@ -9,10 +12,17 @@ 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&&) = delete;
|
VFSClient(VFSClient&& other) : endpoint_(other.endpoint_) {other.endpoint_ = 0;};
|
||||||
|
|
||||||
|
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_;
|
||||||
|
uint64_t kBufferSize = 0x1000;
|
||||||
|
glcr::ByteBuffer buffer_{kBufferSize};
|
||||||
|
uint64_t kCapBufferSize = 0x10;
|
||||||
|
glcr::CapBuffer cap_buffer_{kCapBufferSize};
|
||||||
};
|
};
|
||||||
|
|
|
@ -47,7 +47,7 @@ void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t off
|
||||||
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
uint32_t next_extension = header_size + 8 * 2;
|
uint32_t next_extension = header_size + 8 * 2;
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
// Write path.
|
// Write path.
|
||||||
|
@ -70,7 +70,7 @@ uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t off
|
||||||
return next_extension;
|
return next_extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) {
|
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
uint32_t next_extension = header_size + 8 * 2;
|
uint32_t next_extension = header_size + 8 * 2;
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
uint64_t next_cap = 0;
|
uint64_t next_cap = 0;
|
||||||
|
@ -120,7 +120,7 @@ void File::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const
|
||||||
set_mem_cap(caps.At(mem_cap_ptr));
|
set_mem_cap(caps.At(mem_cap_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
uint32_t next_extension = header_size + 8 * 3;
|
uint32_t next_extension = header_size + 8 * 3;
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
// Write path.
|
// Write path.
|
||||||
|
@ -146,7 +146,7 @@ uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||||
return next_extension;
|
return next_extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) {
|
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
uint32_t next_extension = header_size + 8 * 3;
|
uint32_t next_extension = header_size + 8 * 3;
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
uint64_t next_cap = 0;
|
uint64_t next_cap = 0;
|
||||||
|
|
|
@ -14,11 +14,11 @@ class OpenFileRequest {
|
||||||
|
|
||||||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
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);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
glcr::String path() { return path_; }
|
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 options() { return options_; }
|
uint64_t options() const { return options_; }
|
||||||
void set_options(const uint64_t& value) { options_ = value; }
|
void set_options(const uint64_t& value) { options_ = value; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -35,13 +35,13 @@ class File {
|
||||||
|
|
||||||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
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);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
glcr::String path() { return path_; }
|
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() { return attrs_; }
|
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() { return mem_cap_; }
|
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:
|
||||||
|
|
|
@ -1,45 +1,102 @@
|
||||||
// Generated file - DO NOT MODIFY
|
// Generated file -- DO NOT MODIFY.
|
||||||
#include "example.yunq.client.h"
|
#include "example.yunq.server.h"
|
||||||
|
|
||||||
#include <glacier/buffer/byte_buffer.h>
|
#include <mammoth/debug.h>
|
||||||
#include <glacier/buffer/cap_buffer.h>
|
#include <zcall.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||||
|
const uint32_t kHeaderSize = 0x10;
|
||||||
|
|
||||||
|
void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) {
|
||||||
glcr::ErrorCode open(const OpenFileRequest& request, File& response) {
|
|
||||||
uint64_t buffer_size = 0x1000;
|
|
||||||
// FIXME: Maybe raise this limit.
|
|
||||||
uint64_t cap_size = 100;
|
|
||||||
glcr::ByteBuffer buffer(buffer_size);
|
|
||||||
glcr::CapBuffer caps(cap_size);
|
|
||||||
|
|
||||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
|
||||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
buffer.WriteAt<uint32_t>(4, kHeaderSize);
|
||||||
|
buffer.WriteAt<uint64_t>(8, err);
|
||||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
|
||||||
buffer.WriteAt<uint32_t>(4, 16 + length);
|
|
||||||
|
|
||||||
z_cap_t reply_port_cap;
|
|
||||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
|
||||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
|
||||||
|
|
||||||
// FIXME: Add a way to zero out the first buffer.
|
|
||||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
|
||||||
glcr::CapBuffer recv_caps(cap_size);
|
|
||||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
|
||||||
|
|
||||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
|
||||||
return glcr::INVALID_RESPONSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check Response Code.
|
|
||||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
|
||||||
|
|
||||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
|
||||||
|
|
||||||
return glcr::OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) {
|
||||||
|
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||||
|
buffer.WriteAt<uint32_t>(4, kHeaderSize + message_length);
|
||||||
|
buffer.WriteAt<uint64_t>(8, glcr::OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void VFSServerBaseThreadBootstrap(void* server_base) {
|
||||||
|
((VFSServerBase*)server_base)->ServerThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorOr<VFSClient> VFSServerBase::CreateClient() {
|
||||||
|
uint64_t client_cap;
|
||||||
|
// FIXME: Restrict permissions to send-only here.
|
||||||
|
RET_ERR(ZCapDuplicate(endpoint_, &client_cap));
|
||||||
|
return VFSClient(client_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread VFSServerBase::RunServer() {
|
||||||
|
return Thread(VFSServerBaseThreadBootstrap, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VFSServerBase::ServerThread() {
|
||||||
|
glcr::ByteBuffer recv_buffer(0x1000);
|
||||||
|
glcr::ByteBuffer resp_buffer(0x1000);
|
||||||
|
uint64_t resp_cap_size = 0x10;
|
||||||
|
glcr::CapBuffer resp_cap(resp_cap_size);
|
||||||
|
z_cap_t reply_port_cap;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
uint64_t recv_buf_size = 0x1000;
|
||||||
|
glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &reply_port_cap);
|
||||||
|
if (recv_err != glcr::OK) {
|
||||||
|
dbgln("Error in receive: %x", recv_err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t resp_length = 0;
|
||||||
|
|
||||||
|
glcr::ErrorCode reply_err = glcr::OK;
|
||||||
|
glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap);
|
||||||
|
if (err != glcr::OK) {
|
||||||
|
WriteError(resp_buffer, err);
|
||||||
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr);
|
||||||
|
} else {
|
||||||
|
WriteHeader(resp_buffer, resp_length);
|
||||||
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr());
|
||||||
|
}
|
||||||
|
if (reply_err != glcr::OK) {
|
||||||
|
dbgln("Error in reply: %x", recv_err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
|
||||||
|
glcr::ByteBuffer& response, uint64_t& resp_length,
|
||||||
|
glcr::CapBuffer& resp_caps) {
|
||||||
|
if (request.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t method_select = request.At<uint64_t>(8);
|
||||||
|
|
||||||
|
switch(method_select) {
|
||||||
|
case 0: {
|
||||||
|
OpenFileRequest yunq_request;
|
||||||
|
File yunq_response;
|
||||||
|
|
||||||
|
yunq_request.ParseFromBytes(request, kHeaderSize);
|
||||||
|
|
||||||
|
RET_ERR(Handleopen(yunq_request, yunq_response));
|
||||||
|
|
||||||
|
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return glcr::UNIMPLEMENTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return glcr::OK;
|
||||||
|
}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
// Generated File -- DO NOT MODIFY.
|
// Generated File -- DO NOT MODIFY.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/status/error_or.h>
|
||||||
#include <mammoth/thread.h>
|
#include <mammoth/thread.h>
|
||||||
#include <ztypes.h>
|
#include <ztypes.h>
|
||||||
|
|
||||||
#include "example.yunq.h"
|
#include "example.yunq.h"
|
||||||
|
#include "example.yunq.client.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class VFSServerBase {
|
class VFSServerBase {
|
||||||
public:
|
public:
|
||||||
VFSServerBase(z_cap_t 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;
|
||||||
|
|
||||||
|
glcr::ErrorOr<VFSClient> CreateClient();
|
||||||
|
|
||||||
[[nodiscard]] Thread RunServer();
|
[[nodiscard]] Thread RunServer();
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,6 +31,7 @@ class VFSServerBase {
|
||||||
void ServerThread();
|
void ServerThread();
|
||||||
|
|
||||||
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
||||||
|
uint64_t& resp_length,
|
||||||
glcr::CapBuffer& resp_caps);
|
glcr::CapBuffer& resp_caps);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -74,7 +74,7 @@ void {{message.name}}::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t of
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
|
||||||
uint32_t next_extension = header_size + 8 * {{ message.fields | length }};
|
uint32_t next_extension = header_size + 8 * {{ message.fields | length }};
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@ uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t of
|
||||||
return next_extension;
|
return next_extension;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) {
|
uint64_t {{message.name}}::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
|
||||||
uint32_t next_extension = header_size + 8 * {{ message.fields | length}};
|
uint32_t next_extension = header_size + 8 * {{ message.fields | length}};
|
||||||
const uint32_t core_size = next_extension;
|
const uint32_t core_size = next_extension;
|
||||||
uint64_t next_cap = 0;
|
uint64_t next_cap = 0;
|
||||||
|
|
|
@ -17,11 +17,11 @@ class {{message.name}} {
|
||||||
|
|
||||||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset);
|
||||||
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);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&);
|
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||||
|
|
||||||
{%- for field in message.fields %}
|
{%- for field in message.fields %}
|
||||||
{{field.cpp_type()}} {{field.name}}() { return {{field.name}}_; }
|
{{field.cpp_type()}} {{field.name}}() const { return {{field.name}}_; }
|
||||||
void set_{{field.name}}(const {{field.cpp_type()}}& value) { {{field.name}}_ = value; }
|
void set_{{field.name}}(const {{field.cpp_type()}}& value) { {{field.name}}_ = value; }
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,21 @@ void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) {
|
||||||
|
|
||||||
{% for interface in interfaces %}
|
{% for interface in interfaces %}
|
||||||
void {{interface.name}}ServerBaseThreadBootstrap(void* server_base) {
|
void {{interface.name}}ServerBaseThreadBootstrap(void* server_base) {
|
||||||
({{interface.name}}ServerBase*)(server_base)->ServerThread();
|
(({{interface.name}}ServerBase*)server_base)->ServerThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread {{interface.name}}::RunServer() {
|
glcr::ErrorOr<{{interface.name}}Client> {{interface.name}}ServerBase::CreateClient() {
|
||||||
|
uint64_t client_cap;
|
||||||
|
// FIXME: Restrict permissions to send-only here.
|
||||||
|
RET_ERR(ZCapDuplicate(endpoint_, &client_cap));
|
||||||
|
return {{interface.name}}Client(client_cap);
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread {{interface.name}}ServerBase::RunServer() {
|
||||||
return Thread({{interface.name}}ServerBaseThreadBootstrap, this);
|
return Thread({{interface.name}}ServerBaseThreadBootstrap, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void {{interface.name}}::ServerThread() {
|
void {{interface.name}}ServerBase::ServerThread() {
|
||||||
glcr::ByteBuffer recv_buffer(0x1000);
|
glcr::ByteBuffer recv_buffer(0x1000);
|
||||||
glcr::ByteBuffer resp_buffer(0x1000);
|
glcr::ByteBuffer resp_buffer(0x1000);
|
||||||
uint64_t resp_cap_size = 0x10;
|
uint64_t resp_cap_size = 0x10;
|
||||||
|
@ -50,37 +57,42 @@ void {{interface.name}}::ServerThread() {
|
||||||
|
|
||||||
uint64_t resp_length = 0;
|
uint64_t resp_length = 0;
|
||||||
|
|
||||||
glcr::ErrorCode err = HandlRequest(recv_buffer, resp_buffer, resp_length, resp_cap);
|
glcr::ErrorCode reply_err = glcr::OK;
|
||||||
|
glcr::ErrorCode err = HandleRequest(recv_buffer, resp_buffer, resp_length, resp_cap);
|
||||||
if (err != glcr::OK) {
|
if (err != glcr::OK) {
|
||||||
WriteError(resp_buffer, err);
|
WriteError(resp_buffer, err);
|
||||||
ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr);
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr);
|
||||||
} else {
|
} else {
|
||||||
WriteHeader(resp_buffer, resp_length);
|
WriteHeader(resp_buffer, resp_length);
|
||||||
ZReplyPortSend(reply_port_cap, resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr());
|
reply_err = ZReplyPortSend(reply_port_cap, kHeaderSize + resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr());
|
||||||
|
}
|
||||||
|
if (reply_err != glcr::OK) {
|
||||||
|
dbgln("Error in reply: %x", recv_err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glcr::ErrorCode {{interface.name}}::HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, uint64_t& resp_length
|
glcr::ErrorCode {{interface.name}}ServerBase::HandleRequest(const glcr::ByteBuffer& request,
|
||||||
glcr::CapBuffer& resp_caps) {
|
glcr::ByteBuffer& response, uint64_t& resp_length,
|
||||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
glcr::CapBuffer& resp_caps) {
|
||||||
return glcr::INVALID_INPUT;
|
if (request.At<uint32_t>(0) != kSentinel) {
|
||||||
|
return glcr::INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t method_select = recv_buffer.At<uint64_t>(8);
|
uint64_t method_select = request.At<uint64_t>(8);
|
||||||
|
|
||||||
switch(method_select) {
|
switch(method_select) {
|
||||||
{%- for method in interface.methods %}
|
{%- for method in interface.methods %}
|
||||||
case {{loop.index0}}: {
|
case {{loop.index0}}: {
|
||||||
{{method.request}} request;
|
{{method.request}} yunq_request;
|
||||||
{{method.response}} response;
|
{{method.response}} yunq_response;
|
||||||
|
|
||||||
request.ParseFromBytes(recv_buffer, kHeaderSize);
|
yunq_request.ParseFromBytes(request, kHeaderSize);
|
||||||
|
|
||||||
RET_ERR(Handle{{method.name}}(request, response));
|
RET_ERR(Handle{{method.name}}(yunq_request, yunq_response));
|
||||||
|
|
||||||
resp_length = response.SerializeToBytes(resp_buffer, kHeaderSize, resp_cap);
|
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
|
|
|
@ -1,19 +1,23 @@
|
||||||
// Generated File -- DO NOT MODIFY.
|
// Generated File -- DO NOT MODIFY.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <glacier/status/error_or.h>
|
||||||
#include <mammoth/thread.h>
|
#include <mammoth/thread.h>
|
||||||
#include <ztypes.h>
|
#include <ztypes.h>
|
||||||
|
|
||||||
#include "{{file}}.h"
|
#include "{{file}}.h"
|
||||||
|
#include "{{file}}.client.h"
|
||||||
|
|
||||||
{% for interface in interfaces %}
|
{% for interface in interfaces %}
|
||||||
|
|
||||||
class {{interface.name}}ServerBase {
|
class {{interface.name}}ServerBase {
|
||||||
public:
|
public:
|
||||||
{{interface.name}}ServerBase(z_cap_t {{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;
|
||||||
|
|
||||||
|
glcr::ErrorOr<{{interface.name}}Client> CreateClient();
|
||||||
|
|
||||||
[[nodiscard]] Thread RunServer();
|
[[nodiscard]] Thread RunServer();
|
||||||
|
|
||||||
{% for method in interface.methods %}
|
{% for method in interface.methods %}
|
||||||
|
@ -27,6 +31,7 @@ class {{interface.name}}ServerBase {
|
||||||
void ServerThread();
|
void ServerThread();
|
||||||
|
|
||||||
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
||||||
|
uint64_t& resp_length,
|
||||||
glcr::CapBuffer& resp_caps);
|
glcr::CapBuffer& resp_caps);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ def main():
|
||||||
|
|
||||||
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 = client_impl_tmpl.render(file=filename, interfaces=interfaces)
|
server_impl = server_impl_tmpl.render(file=filename, interfaces=interfaces)
|
||||||
f.write(server_impl)
|
f.write(server_impl)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -69,7 +69,10 @@ struct InterruptFrame {
|
||||||
};
|
};
|
||||||
|
|
||||||
extern "C" void isr_divide_by_zero();
|
extern "C" void isr_divide_by_zero();
|
||||||
extern "C" void interrupt_divide_by_zero(void* frame) { panic("DIV0"); }
|
extern "C" void interrupt_divide_by_zero(InterruptFrame* frame) {
|
||||||
|
dbgln("RIP: %m", frame->rip);
|
||||||
|
panic("DIV0");
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" void isr_protection_fault();
|
extern "C" void isr_protection_fault();
|
||||||
extern "C" void interrupt_protection_fault(InterruptFrame* frame) {
|
extern "C" void interrupt_protection_fault(InterruptFrame* frame) {
|
||||||
|
|
|
@ -88,6 +88,8 @@ class PhysicalMemoryManager {
|
||||||
|
|
||||||
MemBlock* block = front_;
|
MemBlock* block = front_;
|
||||||
while (block != nullptr && block->num_pages < num_pages) {
|
while (block != nullptr && block->num_pages < num_pages) {
|
||||||
|
dbgln("Skipping block of size %u seeking %u", block->num_pages,
|
||||||
|
num_pages);
|
||||||
block = block->next;
|
block = block->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue