2023-06-22 02:19:16 -07:00
|
|
|
#include "yellowstone_server.h"
|
|
|
|
|
|
|
|
#include <denali/denali.h>
|
|
|
|
#include <glacier/string/string.h>
|
|
|
|
#include <mammoth/debug.h>
|
2023-07-05 16:03:20 -07:00
|
|
|
#include <mammoth/init.h>
|
|
|
|
#include <mammoth/process.h>
|
2023-06-22 02:19:16 -07:00
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "hw/gpt.h"
|
2023-08-01 17:46:26 -07:00
|
|
|
#include "hw/pcie.h"
|
2023-06-22 02:19:16 -07:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2023-07-05 16:03:20 -07:00
|
|
|
struct PartitionInfo {
|
|
|
|
uint64_t device_id;
|
|
|
|
uint64_t partition_lba;
|
|
|
|
};
|
|
|
|
|
|
|
|
glcr::ErrorOr<PartitionInfo> HandleDenaliRegistration(z_cap_t endpoint_cap) {
|
2023-06-26 11:54:36 -07:00
|
|
|
GptReader reader(glcr::UniquePtr<DenaliClient>(
|
|
|
|
new DenaliClient(EndpointClient::AdoptEndpoint(endpoint_cap))));
|
2023-06-22 02:19:16 -07:00
|
|
|
|
2023-07-05 16:03:20 -07:00
|
|
|
RET_ERR(reader.ParsePartitionTables());
|
|
|
|
|
|
|
|
return PartitionInfo{.device_id = 0,
|
|
|
|
.partition_lba = reader.GetPrimaryPartitionLba()};
|
2023-06-22 02:19:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2023-06-26 11:38:17 -07:00
|
|
|
glcr::ErrorOr<glcr::UniquePtr<YellowstoneServer>> YellowstoneServer::Create() {
|
2023-10-25 19:08:00 -07:00
|
|
|
z_cap_t endpoint_cap;
|
|
|
|
RET_ERR(ZEndpointCreate(&endpoint_cap));
|
|
|
|
|
|
|
|
ASSIGN_OR_RETURN(Mutex mut, Mutex::Create());
|
|
|
|
RET_ERR(mut.Lock());
|
|
|
|
|
|
|
|
return glcr::UniquePtr<YellowstoneServer>(
|
|
|
|
new YellowstoneServer(endpoint_cap, glcr::Move(mut)));
|
2023-06-22 02:19:16 -07:00
|
|
|
}
|
|
|
|
|
2023-10-25 19:08:00 -07:00
|
|
|
YellowstoneServer::YellowstoneServer(z_cap_t endpoint_cap, Mutex&& mutex)
|
|
|
|
: YellowstoneServerBase(endpoint_cap),
|
|
|
|
has_denali_mutex_(glcr::Move(mutex)) {}
|
2023-06-22 02:19:16 -07:00
|
|
|
|
2023-10-24 18:24:26 -07:00
|
|
|
glcr::ErrorCode YellowstoneServer::HandleGetAhciInfo(const Empty&,
|
|
|
|
AhciInfo& info) {
|
|
|
|
info.set_ahci_region(pci_reader_.GetAhciVmmo());
|
|
|
|
info.set_region_length(kPcieConfigurationSize);
|
|
|
|
return glcr::OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
glcr::ErrorCode YellowstoneServer::HandleGetDenali(const Empty&,
|
|
|
|
DenaliInfo& info) {
|
|
|
|
z_cap_t new_denali;
|
|
|
|
check(ZCapDuplicate(denali_cap_, &new_denali));
|
|
|
|
info.set_denali_endpoint(new_denali);
|
|
|
|
info.set_device_id(device_id_);
|
|
|
|
info.set_lba_offset(lba_offset_);
|
|
|
|
return glcr::OK;
|
|
|
|
}
|
2023-07-05 16:03:20 -07:00
|
|
|
|
2023-10-24 23:42:34 -07:00
|
|
|
glcr::ErrorCode YellowstoneServer::HandleRegisterEndpoint(
|
|
|
|
const RegisterEndpointRequest& req, Empty&) {
|
|
|
|
dbgln("Registering.");
|
|
|
|
if (req.endpoint_name() == "denali") {
|
2023-10-24 23:43:57 -07:00
|
|
|
// FIXME: Rather than blocking and calling the denali service
|
|
|
|
// immediately we should signal the main thread that it can continue init.
|
2023-10-24 23:42:34 -07:00
|
|
|
denali_cap_ = req.endpoint_capability();
|
|
|
|
auto part_info_or = HandleDenaliRegistration(denali_cap_);
|
|
|
|
if (!part_info_or.ok()) {
|
|
|
|
check(part_info_or.error());
|
2023-06-22 02:19:16 -07:00
|
|
|
}
|
2023-10-24 23:42:34 -07:00
|
|
|
device_id_ = part_info_or.value().device_id;
|
|
|
|
lba_offset_ = part_info_or.value().partition_lba;
|
|
|
|
|
2023-10-25 19:08:00 -07:00
|
|
|
check(has_denali_mutex_.Release());
|
2023-10-24 23:42:34 -07:00
|
|
|
} else if (req.endpoint_name() == "victoriafalls") {
|
|
|
|
victoria_falls_cap_ = req.endpoint_capability();
|
|
|
|
} else {
|
|
|
|
dbgln("[WARN] Got endpoint cap type: %s", req.endpoint_name().cstr());
|
2023-06-22 02:19:16 -07:00
|
|
|
}
|
2023-10-24 23:42:34 -07:00
|
|
|
return glcr::OK;
|
2023-06-22 02:19:16 -07:00
|
|
|
}
|
2023-10-25 19:08:00 -07:00
|
|
|
|
|
|
|
glcr::ErrorCode YellowstoneServer::WaitDenaliRegistered() {
|
|
|
|
RET_ERR(has_denali_mutex_.Lock());
|
|
|
|
return has_denali_mutex_.Release();
|
|
|
|
}
|