[Yellowstone] Add method to get XHCI configuration space.
This commit is contained in:
parent
27c39d05e8
commit
3bacfea183
|
@ -4,7 +4,7 @@
|
|||
#include <mammoth/util/init.h>
|
||||
#include <zcall.h>
|
||||
|
||||
#define PCI_DEBUG 0
|
||||
#define PCI_DEBUG 1
|
||||
|
||||
namespace {
|
||||
|
||||
|
@ -32,6 +32,13 @@ z_cap_t PciReader::GetAhciVmmo() {
|
|||
return new_cap;
|
||||
}
|
||||
|
||||
z_cap_t PciReader::GetXhciVmmo() {
|
||||
uint64_t new_cap;
|
||||
check(ZMemoryObjectDuplicate(gBootPciVmmoCap, xhci_device_offset_,
|
||||
kPcieConfigurationSize, &new_cap));
|
||||
return new_cap;
|
||||
}
|
||||
|
||||
void PciReader::FunctionDump(uint64_t base, uint64_t bus, uint64_t dev,
|
||||
uint64_t fun) {
|
||||
PciDeviceHeader* hdr = PciHeader(base, bus, dev, fun);
|
||||
|
@ -55,6 +62,14 @@ void PciReader::FunctionDump(uint64_t base, uint64_t bus, uint64_t dev,
|
|||
#endif
|
||||
achi_device_offset_ = reinterpret_cast<uint64_t>(hdr) - base;
|
||||
}
|
||||
|
||||
if (hdr->class_code == 0xC && hdr->subclass == 0x3) {
|
||||
if (hdr->prog_interface == 0x30) {
|
||||
xhci_device_offset_ = reinterpret_cast<uint64_t>(hdr) - base;
|
||||
} else {
|
||||
dbgln("WARN: Non-XHCI USB Controller found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PciReader::DeviceDump(uint64_t base, uint64_t bus, uint64_t dev) {
|
||||
|
|
|
@ -28,11 +28,13 @@ class PciReader {
|
|||
PciReader();
|
||||
|
||||
z_cap_t GetAhciVmmo();
|
||||
z_cap_t GetXhciVmmo();
|
||||
|
||||
private:
|
||||
PciDeviceHeader* header_;
|
||||
|
||||
uint64_t achi_device_offset_ = 0;
|
||||
uint64_t xhci_device_offset_ = 0;
|
||||
|
||||
void PciDump(uint64_t vaddr);
|
||||
void BusDump(uint64_t base, uint64_t bus);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -34,6 +34,10 @@ class YellowstoneClient {
|
|||
|
||||
|
||||
|
||||
[[nodiscard]] glcr::Status GetXhciInfo(XhciInfo& response);
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] glcr::Status GetFramebufferInfo(FramebufferInfo& response);
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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: {
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -41,6 +41,10 @@ class YellowstoneServerBase {
|
|||
|
||||
|
||||
|
||||
[[nodiscard]] virtual glcr::Status HandleGetXhciInfo(XhciInfo&) = 0;
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] virtual glcr::Status HandleGetFramebufferInfo(FramebufferInfo&) = 0;
|
||||
|
||||
|
||||
|
|
|
@ -52,6 +52,12 @@ glcr::Status YellowstoneServer::HandleGetAhciInfo(AhciInfo& info) {
|
|||
return glcr::Status::Ok();
|
||||
}
|
||||
|
||||
glcr::Status YellowstoneServer::HandleGetXhciInfo(XhciInfo& info) {
|
||||
info.set_xhci_region(pci_reader_.GetXhciVmmo());
|
||||
info.set_region_length(kPcieConfigurationSize);
|
||||
return glcr::Status::Ok();
|
||||
}
|
||||
|
||||
glcr::Status YellowstoneServer::HandleGetFramebufferInfo(
|
||||
FramebufferInfo& info) {
|
||||
// FIXME: Don't do this for each request.
|
||||
|
|
|
@ -17,6 +17,7 @@ class YellowstoneServer : public YellowstoneServerBase {
|
|||
static glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> Create();
|
||||
|
||||
glcr::Status HandleGetAhciInfo(AhciInfo&) override;
|
||||
glcr::Status HandleGetXhciInfo(XhciInfo&) override;
|
||||
glcr::Status HandleGetFramebufferInfo(FramebufferInfo&) override;
|
||||
glcr::Status HandleGetDenali(DenaliInfo&) override;
|
||||
glcr::Status HandleRegisterEndpoint(const RegisterEndpointRequest&) override;
|
||||
|
|
Loading…
Reference in New Issue