[Yellowstone] Add method to get XHCI configuration space.

This commit is contained in:
Drew Galbraith 2024-02-06 20:49:43 -08:00
parent 27c39d05e8
commit 3bacfea183
11 changed files with 172 additions and 4 deletions

View file

@ -4,6 +4,7 @@ interface Yellowstone {
method RegisterEndpoint(RegisterEndpointRequest) -> ();
method GetEndpoint(GetEndpointRequest) -> (Endpoint);
method GetAhciInfo() -> (AhciInfo);
method GetXhciInfo() -> (XhciInfo);
method GetFramebufferInfo() -> (FramebufferInfo);
method GetDenali() -> (DenaliInfo);
}
@ -26,6 +27,11 @@ message AhciInfo {
u64 region_length;
}
message XhciInfo {
capability xhci_region;
u64 region_length;
}
message FramebufferInfo {
u64 address_phys;
u64 width;

View file

@ -137,7 +137,7 @@ glcr::Status YellowstoneClient::GetAhciInfo(AhciInfo& response) {
glcr::Status YellowstoneClient::GetFramebufferInfo(FramebufferInfo& response) {
glcr::Status YellowstoneClient::GetXhciInfo(XhciInfo& response) {
uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize;
@ -177,7 +177,7 @@ glcr::Status YellowstoneClient::GetFramebufferInfo(FramebufferInfo& response) {
glcr::Status YellowstoneClient::GetDenali(DenaliInfo& response) {
glcr::Status YellowstoneClient::GetFramebufferInfo(FramebufferInfo& response) {
uint64_t buffer_size = kBufferSize;
uint64_t cap_size = kCapBufferSize;
@ -217,5 +217,45 @@ glcr::Status YellowstoneClient::GetDenali(DenaliInfo& response) {
glcr::Status YellowstoneClient::GetDenali(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, 5);
cap_buffer_.Reset();
uint64_t length = 0;
buffer_.WriteAt<uint32_t>(4, 16 + length);
z_cap_t reply_port_cap;
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer_.RawPtr(), cap_buffer_.UsedSlots(), cap_buffer_.RawPtr(), &reply_port_cap));
// FIXME: Add a way to zero out the first buffer.
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, buffer_.RawPtr(), &cap_size, cap_buffer_.RawPtr()));
if (buffer_.At<uint32_t>(0) != kSentinel) {
return glcr::InvalidResponse("Got an invalid response from server.");
}
// Check Response Code.
RET_ERR(buffer_.At<uint64_t>(8));
yunq::MessageView resp_view(buffer_, 16);
RETURN_ERROR(response.ParseFromBytes(resp_view, cap_buffer_));
return glcr::OK;
}
} // namepace yellowstone

View file

@ -34,6 +34,10 @@ class YellowstoneClient {
[[nodiscard]] glcr::Status GetXhciInfo(XhciInfo& response);
[[nodiscard]] glcr::Status GetFramebufferInfo(FramebufferInfo& response);

View file

@ -178,6 +178,49 @@ uint64_t AhciInfo::SerializeInternal(yunq::Serializer& serializer) const {
return serializer.size();
}
glcr::Status XhciInfo::ParseFromBytes(const yunq::MessageView& message) {
RETURN_ERROR(ParseFromBytesInternal(message));
// Parse xhci_region.
ASSIGN_OR_RETURN(xhci_region_, message.ReadCapability(0));
return glcr::Status::Ok();
}
glcr::Status XhciInfo::ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer& caps) {
RETURN_ERROR(ParseFromBytesInternal(message));
// Parse xhci_region.
ASSIGN_OR_RETURN(xhci_region_, message.ReadCapability(0, caps));
return glcr::Status::Ok();
}
glcr::Status XhciInfo::ParseFromBytesInternal(const yunq::MessageView& message) {
RETURN_ERROR(message.CheckHeader());
// Parse xhci_region.
// Parse region_length.
ASSIGN_OR_RETURN(region_length_, message.ReadField<uint64_t>(1));
return glcr::Status::Ok();
}
uint64_t XhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) const {
yunq::Serializer serializer(bytes, offset, 2);
return SerializeInternal(serializer);
}
uint64_t XhciInfo::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) const {
yunq::Serializer serializer(bytes, offset, 2, caps);
return SerializeInternal(serializer);
}
uint64_t XhciInfo::SerializeInternal(yunq::Serializer& serializer) const {
// Write xhci_region.
serializer.WriteCapability(0, xhci_region_);
// Write region_length.
serializer.WriteField<uint64_t>(1, region_length_);
serializer.WriteHeader();
return serializer.size();
}
glcr::Status FramebufferInfo::ParseFromBytes(const yunq::MessageView& message) {
RETURN_ERROR(ParseFromBytesInternal(message));
return glcr::Status::Ok();

View file

@ -123,6 +123,36 @@ class AhciInfo {
uint64_t SerializeInternal(yunq::Serializer& serializer) const;
};
class XhciInfo {
public:
XhciInfo() {}
// Delete copy and move until implemented.
XhciInfo(const XhciInfo&) = delete;
XhciInfo(XhciInfo&&) = default;
XhciInfo& operator=(XhciInfo&&) = default;
[[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message);
[[nodiscard]] glcr::Status ParseFromBytes(const yunq::MessageView& message, const glcr::CapBuffer&);
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
const z_cap_t& xhci_region() const { return xhci_region_; }
z_cap_t& mutable_xhci_region() { return xhci_region_; }
void set_xhci_region(const z_cap_t& value) { xhci_region_ = value; }
const uint64_t& region_length() const { return region_length_; }
uint64_t& mutable_region_length() { return region_length_; }
void set_region_length(const uint64_t& value) { region_length_ = value; }
private:
z_cap_t xhci_region_;
uint64_t region_length_;
// Parses everything except for caps.
glcr::Status ParseFromBytesInternal(const yunq::MessageView& message);
uint64_t SerializeInternal(yunq::Serializer& serializer) const;
};
class FramebufferInfo {
public:
FramebufferInfo() {}

View file

@ -164,6 +164,23 @@ glcr::Status YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& reques
XhciInfo yunq_response;
RETURN_ERROR(HandleGetXhciInfo(yunq_response));
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
break;
}
case 4: {
FramebufferInfo yunq_response;
@ -176,7 +193,7 @@ glcr::Status YellowstoneServerBase::HandleRequest(const glcr::ByteBuffer& reques
break;
}
case 4: {
case 5: {

View file

@ -41,6 +41,10 @@ class YellowstoneServerBase {
[[nodiscard]] virtual glcr::Status HandleGetXhciInfo(XhciInfo&) = 0;
[[nodiscard]] virtual glcr::Status HandleGetFramebufferInfo(FramebufferInfo&) = 0;