diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq b/sys/yellowstone/lib/yellowstone/yellowstone.yunq index 9c2b134..0022629 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq @@ -1,6 +1,7 @@ interface Yellowstone { method RegisterEndpoint(RegisterEndpointRequest) -> (Empty); method GetAhciInfo(Empty) -> (AhciInfo); + method GetFramebufferInfo(Empty) -> (FramebufferInfo); method GetDenali(Empty) -> (DenaliInfo); } @@ -18,6 +19,23 @@ message AhciInfo { u64 region_length; } +message FramebufferInfo { + u64 address_phys; + u64 width; + u64 height; + u64 pitch; + // TODO: Add u16 & u8 to the yunq language so + // the following can be appropriate widths. + u64 bpp; + u64 memory_model; + u64 red_mask_size; + u64 red_mask_shift; + u64 green_mask_size; + u64 green_mask_shift; + u64 blue_mask_size; + u64 blue_mask_shift; +} + message DenaliInfo { capability denali_endpoint; u64 device_id; diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.cpp b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.cpp index fa0ec17..d1d2f69 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.cpp +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.cpp @@ -72,7 +72,7 @@ glcr::ErrorCode YellowstoneClient::GetAhciInfo(const Empty& request, AhciInfo& r -glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& response) { +glcr::ErrorCode YellowstoneClient::GetFramebufferInfo(const Empty& request, FramebufferInfo& response) { uint64_t buffer_size = kBufferSize; uint64_t cap_size = kCapBufferSize; @@ -103,3 +103,35 @@ glcr::ErrorCode YellowstoneClient::GetDenali(const Empty& request, DenaliInfo& r } + +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(0, kSentinel); + buffer_.WriteAt(8, 3); + + cap_buffer_.Reset(); + uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_); + buffer_.WriteAt(4, 16 + length); + + z_cap_t reply_port_cap; + RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap)); + + // FIXME: Add a way to zero out the first buffer. + RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr())); + + if (buffer_.At(0) != kSentinel) { + return glcr::INVALID_RESPONSE; + } + + // Check Response Code. + RET_ERR(buffer_.At(8)); + + response.ParseFromBytes(buffer_, 16, cap_buffer_); + + return glcr::OK; +} + + diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.h b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.h index 56ca541..9b3c035 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.h +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.client.h @@ -21,6 +21,8 @@ class YellowstoneClient { [[nodiscard]] glcr::ErrorCode GetAhciInfo(const Empty& request, AhciInfo& response); + [[nodiscard]] glcr::ErrorCode GetFramebufferInfo(const Empty& request, FramebufferInfo& response); + [[nodiscard]] glcr::ErrorCode GetDenali(const Empty& request, DenaliInfo& response); private: diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.cpp b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.cpp index c2e8e26..c80cbb5 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.cpp +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.cpp @@ -175,6 +175,130 @@ uint64_t AhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, gl return next_extension; } +void FramebufferInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) { + CheckHeader(bytes); + // Parse address_phys. + set_address_phys(bytes.At(offset + header_size + (8 * 0))); + // Parse width. + set_width(bytes.At(offset + header_size + (8 * 1))); + // Parse height. + set_height(bytes.At(offset + header_size + (8 * 2))); + // Parse pitch. + set_pitch(bytes.At(offset + header_size + (8 * 3))); + // Parse bpp. + set_bpp(bytes.At(offset + header_size + (8 * 4))); + // Parse memory_model. + set_memory_model(bytes.At(offset + header_size + (8 * 5))); + // Parse red_mask_size. + set_red_mask_size(bytes.At(offset + header_size + (8 * 6))); + // Parse red_mask_shift. + set_red_mask_shift(bytes.At(offset + header_size + (8 * 7))); + // Parse green_mask_size. + set_green_mask_size(bytes.At(offset + header_size + (8 * 8))); + // Parse green_mask_shift. + set_green_mask_shift(bytes.At(offset + header_size + (8 * 9))); + // Parse blue_mask_size. + set_blue_mask_size(bytes.At(offset + header_size + (8 * 10))); + // Parse blue_mask_shift. + set_blue_mask_shift(bytes.At(offset + header_size + (8 * 11))); +} + +void FramebufferInfo::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) { + CheckHeader(bytes); + // Parse address_phys. + set_address_phys(bytes.At(offset + header_size + (8 * 0))); + // Parse width. + set_width(bytes.At(offset + header_size + (8 * 1))); + // Parse height. + set_height(bytes.At(offset + header_size + (8 * 2))); + // Parse pitch. + set_pitch(bytes.At(offset + header_size + (8 * 3))); + // Parse bpp. + set_bpp(bytes.At(offset + header_size + (8 * 4))); + // Parse memory_model. + set_memory_model(bytes.At(offset + header_size + (8 * 5))); + // Parse red_mask_size. + set_red_mask_size(bytes.At(offset + header_size + (8 * 6))); + // Parse red_mask_shift. + set_red_mask_shift(bytes.At(offset + header_size + (8 * 7))); + // Parse green_mask_size. + set_green_mask_size(bytes.At(offset + header_size + (8 * 8))); + // Parse green_mask_shift. + set_green_mask_shift(bytes.At(offset + header_size + (8 * 9))); + // Parse blue_mask_size. + set_blue_mask_size(bytes.At(offset + header_size + (8 * 10))); + // Parse blue_mask_shift. + set_blue_mask_shift(bytes.At(offset + header_size + (8 * 11))); +} + +uint64_t FramebufferInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const { + uint32_t next_extension = header_size + 8 * 12; + const uint32_t core_size = next_extension; + // Write address_phys. + bytes.WriteAt(offset + header_size + (8 * 0), address_phys()); + // Write width. + bytes.WriteAt(offset + header_size + (8 * 1), width()); + // Write height. + bytes.WriteAt(offset + header_size + (8 * 2), height()); + // Write pitch. + bytes.WriteAt(offset + header_size + (8 * 3), pitch()); + // Write bpp. + bytes.WriteAt(offset + header_size + (8 * 4), bpp()); + // Write memory_model. + bytes.WriteAt(offset + header_size + (8 * 5), memory_model()); + // Write red_mask_size. + bytes.WriteAt(offset + header_size + (8 * 6), red_mask_size()); + // Write red_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 7), red_mask_shift()); + // Write green_mask_size. + bytes.WriteAt(offset + header_size + (8 * 8), green_mask_size()); + // Write green_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 9), green_mask_shift()); + // Write blue_mask_size. + bytes.WriteAt(offset + header_size + (8 * 10), blue_mask_size()); + // Write blue_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 11), blue_mask_shift()); + + // The next extension pointer is the length of the message. + WriteHeader(bytes, offset, core_size, next_extension); + + return next_extension; +} + +uint64_t FramebufferInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const { + uint32_t next_extension = header_size + 8 * 12; + const uint32_t core_size = next_extension; + uint64_t next_cap = 0; + // Write address_phys. + bytes.WriteAt(offset + header_size + (8 * 0), address_phys()); + // Write width. + bytes.WriteAt(offset + header_size + (8 * 1), width()); + // Write height. + bytes.WriteAt(offset + header_size + (8 * 2), height()); + // Write pitch. + bytes.WriteAt(offset + header_size + (8 * 3), pitch()); + // Write bpp. + bytes.WriteAt(offset + header_size + (8 * 4), bpp()); + // Write memory_model. + bytes.WriteAt(offset + header_size + (8 * 5), memory_model()); + // Write red_mask_size. + bytes.WriteAt(offset + header_size + (8 * 6), red_mask_size()); + // Write red_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 7), red_mask_shift()); + // Write green_mask_size. + bytes.WriteAt(offset + header_size + (8 * 8), green_mask_size()); + // Write green_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 9), green_mask_shift()); + // Write blue_mask_size. + bytes.WriteAt(offset + header_size + (8 * 10), blue_mask_size()); + // Write blue_mask_shift. + bytes.WriteAt(offset + header_size + (8 * 11), blue_mask_shift()); + + // 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. diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.h b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.h index ffea85e..102bd77 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.h +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.h @@ -61,6 +61,57 @@ class AhciInfo { z_cap_t ahci_region_; uint64_t region_length_; +}; +class FramebufferInfo { + public: + FramebufferInfo() {} + // Delete copy and move until implemented. + FramebufferInfo(const FramebufferInfo&) = delete; + FramebufferInfo(FramebufferInfo&&) = delete; + + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset); + void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&); + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const; + uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const; + uint64_t address_phys() const { return address_phys_; } + void set_address_phys(const uint64_t& value) { address_phys_ = value; } + uint64_t width() const { return width_; } + void set_width(const uint64_t& value) { width_ = value; } + uint64_t height() const { return height_; } + void set_height(const uint64_t& value) { height_ = value; } + uint64_t pitch() const { return pitch_; } + void set_pitch(const uint64_t& value) { pitch_ = value; } + uint64_t bpp() const { return bpp_; } + void set_bpp(const uint64_t& value) { bpp_ = value; } + uint64_t memory_model() const { return memory_model_; } + void set_memory_model(const uint64_t& value) { memory_model_ = value; } + uint64_t red_mask_size() const { return red_mask_size_; } + void set_red_mask_size(const uint64_t& value) { red_mask_size_ = value; } + uint64_t red_mask_shift() const { return red_mask_shift_; } + void set_red_mask_shift(const uint64_t& value) { red_mask_shift_ = value; } + uint64_t green_mask_size() const { return green_mask_size_; } + void set_green_mask_size(const uint64_t& value) { green_mask_size_ = value; } + uint64_t green_mask_shift() const { return green_mask_shift_; } + void set_green_mask_shift(const uint64_t& value) { green_mask_shift_ = value; } + uint64_t blue_mask_size() const { return blue_mask_size_; } + void set_blue_mask_size(const uint64_t& value) { blue_mask_size_ = value; } + uint64_t blue_mask_shift() const { return blue_mask_shift_; } + void set_blue_mask_shift(const uint64_t& value) { blue_mask_shift_ = value; } + + private: + uint64_t address_phys_; + uint64_t width_; + uint64_t height_; + uint64_t pitch_; + uint64_t bpp_; + uint64_t memory_model_; + uint64_t red_mask_size_; + uint64_t red_mask_shift_; + uint64_t green_mask_size_; + uint64_t green_mask_shift_; + uint64_t blue_mask_size_; + uint64_t blue_mask_shift_; + }; class DenaliInfo { public: diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.cpp b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.cpp index 3f9bda7..199eaf1 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.cpp +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.cpp @@ -109,6 +109,17 @@ glcr::ErrorCode YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& req break; } case 2: { + Empty yunq_request; + FramebufferInfo yunq_response; + + yunq_request.ParseFromBytes(request, kHeaderSize, req_caps); + + RET_ERR(HandleGetFramebufferInfo(yunq_request, yunq_response)); + + resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps); + break; + } + case 3: { Empty yunq_request; DenaliInfo yunq_response; diff --git a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.h b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.h index 13c3da3..41e7901 100644 --- a/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.h +++ b/sys/yellowstone/lib/yellowstone/yellowstone.yunq.server.h @@ -25,6 +25,8 @@ class YellowstoneServerBase { [[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; diff --git a/sys/yellowstone/yellowstone.cpp b/sys/yellowstone/yellowstone.cpp index 92ce448..815e2f9 100644 --- a/sys/yellowstone/yellowstone.cpp +++ b/sys/yellowstone/yellowstone.cpp @@ -49,13 +49,6 @@ uint64_t main(uint64_t port_cap) { dbgln("Test: '{}'", file.cstr()); - MappedMemoryRegion region = - MappedMemoryRegion::FromCapability(gBootFramebufferVmmoCap); - - ZFramebufferInfo* fb = reinterpret_cast(region.vaddr()); - - dbgln("FB Addr: {x}", fb->address_phys); - check(server_thread.Join()); dbgln("Yellowstone Finished Successfully."); return 0; diff --git a/sys/yellowstone/yellowstone_server.cpp b/sys/yellowstone/yellowstone_server.cpp index f1be0ce..b343192 100644 --- a/sys/yellowstone/yellowstone_server.cpp +++ b/sys/yellowstone/yellowstone_server.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,29 @@ glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&, return glcr::OK; } +glcr::ErrorCode YellowstoneServer::HandleGetFramebufferInfo( + const Empty&, FramebufferInfo& info) { + // FIXME: Don't do this for each request. + MappedMemoryRegion region = + MappedMemoryRegion::FromCapability(gBootFramebufferVmmoCap); + ZFramebufferInfo* fb = reinterpret_cast(region.vaddr()); + + info.set_address_phys(fb->address_phys); + info.set_width(fb->width); + info.set_height(fb->height); + info.set_pitch(fb->pitch); + info.set_bpp(fb->bpp); + info.set_memory_model(fb->memory_model); + info.set_red_mask_size(fb->red_mask_size); + info.set_red_mask_shift(fb->red_mask_shift); + info.set_green_mask_size(fb->green_mask_size); + info.set_green_mask_shift(fb->green_mask_shift); + info.set_blue_mask_size(fb->blue_mask_size); + info.set_blue_mask_shift(fb->blue_mask_shift); + + return glcr::OK; +} + glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&, DenaliInfo& info) { z_cap_t new_denali; diff --git a/sys/yellowstone/yellowstone_server.h b/sys/yellowstone/yellowstone_server.h index 95734a7..3606441 100644 --- a/sys/yellowstone/yellowstone_server.h +++ b/sys/yellowstone/yellowstone_server.h @@ -17,6 +17,8 @@ class YellowstoneServer : public YellowstoneServerBase { static glcr::ErrorOr> Create(); glcr::ErrorCode HandleGetAhciInfo(const Empty&, AhciInfo&) override; + glcr::ErrorCode HandleGetFramebufferInfo(const Empty&, + FramebufferInfo&) override; glcr::ErrorCode HandleGetDenali(const Empty&, DenaliInfo&) override; glcr::ErrorCode HandleRegisterEndpoint(const RegisterEndpointRequest&, Empty&) override;