blob: 0f2e502ef0b9ad3dca75c93a00475e31e0133adc [file] [log] [blame] [edit]
// Copyright 2024 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_LIB_USERABI_USERBOOT_FIDL_H_
#define ZIRCON_KERNEL_LIB_USERABI_USERBOOT_FIDL_H_
#include <lib/fidl/txn_header.h>
#include <lib/zx/channel.h>
#include <lib/zx/result.h>
#include <lib/zx/vmo.h>
#include <zircon/fidl.h>
#include <span>
// TODO(https://fxbug.dev/42072759): Replace copy & pasted FIDL C bindings with new C++ bindings
// when that's allowed.
constexpr std::string_view kUserbootProtocolName = "fuchsia.boot.Userboot";
constexpr std::string_view kSvcStashProtocolName = "fuchsia.boot.SvcStash";
struct fuchsia_boot_SvcStashStoreRequestMessage {
FIDL_ALIGNDECL
fidl_message_header_t hdr;
zx_handle_t svc_endpoint;
};
constexpr uint64_t fuchsia_boot_SvcStashStoreOrdinal = 0xC2648E356CA2870;
inline zx::result<> SvcStashStore(const zx::channel& svc_stash_client_endpoint,
zx::channel svc_server_endpoint) {
zx_handle_t h = svc_server_endpoint.release();
fuchsia_boot_SvcStashStoreRequestMessage request = {};
fidl_init_txn_header(&request.hdr, 0, fuchsia_boot_SvcStashStoreOrdinal, 0);
request.svc_endpoint = FIDL_HANDLE_PRESENT;
return zx::make_result(svc_stash_client_endpoint.write(0, &request, sizeof(request), &h, 1));
}
struct fuchsia_boot_UserbootPushRequestMessage {
FIDL_ALIGNDECL
fidl_message_header_t hdr;
zx_handle_t stash_svc_endpoint;
};
constexpr uint64_t fuchsia_boot_UserbootPushStashSvcOrdinal = 0x506ECF7DB01ADEAC;
inline zx::result<> UserbootPostStashSvc(const zx::channel& userboot_client_endpoint,
zx::channel svc_stash_server_endpoint) {
zx_handle_t h = svc_stash_server_endpoint.release();
fuchsia_boot_UserbootPushRequestMessage request = {};
fidl_init_txn_header(&request.hdr, 0, fuchsia_boot_UserbootPushStashSvcOrdinal, 0);
request.stash_svc_endpoint = FIDL_HANDLE_PRESENT;
return zx::make_result(userboot_client_endpoint.write(0, &request, sizeof(request), &h, 1));
}
struct BootfsFileVmo {
uint32_t offset;
zx::vmo contents;
};
struct fuchsia_boot_BootfsFileVmo {
FIDL_ALIGNDECL
uint32_t offset;
zx_handle_t contents;
};
struct fuchsia_boot_PostBootfsFilesRequestMessage {
FIDL_ALIGNDECL
fidl_message_header_t hdr;
fidl_vector_t vector;
};
constexpr uint64_t fuchsia_boot_UserbootPostBootfsFilesOrdinal = 2985117035928536724l;
inline zx::result<> UserbootPostBootfsEntries(const zx::channel& userboot_client_endpoint,
std::span<BootfsFileVmo> entries) {
if (entries.empty()) {
return zx::ok();
}
std::array<uint8_t,
FIDL_ALIGN(sizeof(fuchsia_boot_PostBootfsFilesRequestMessage)) +
FIDL_ALIGN(sizeof(fuchsia_boot_BootfsFileVmo) * ZX_CHANNEL_MAX_MSG_HANDLES)>
buffer;
std::array<zx_handle_t, ZX_CHANNEL_MAX_MSG_HANDLES> handles;
auto* request = reinterpret_cast<fuchsia_boot_PostBootfsFilesRequestMessage*>(buffer.data());
fidl_init_txn_header(&request->hdr, 0, fuchsia_boot_UserbootPostBootfsFilesOrdinal, 0);
// Aligned main object and secondary object.
// | request | payload |
// | hdr | vector_t | vector data |
auto* raw_entries_ptr = buffer.data() + sizeof(fuchsia_boot_PostBootfsFilesRequestMessage);
auto* typed_entries = reinterpret_cast<fuchsia_boot_BootfsFileVmo*>(raw_entries_ptr);
for (size_t i = 0; i < entries.size(); ++i) {
typed_entries[i].contents = FIDL_HANDLE_PRESENT;
typed_entries[i].offset = entries[i].offset;
handles[i] = entries[i].contents.release();
}
size_t num_bytes = FIDL_ALIGN(reinterpret_cast<uintptr_t>(typed_entries + entries.size())) -
reinterpret_cast<uintptr_t>(buffer.data());
request->vector.count = entries.size();
// Turn this into a flat offset from message start.
request->vector.data = reinterpret_cast<void*>(FIDL_ALLOC_PRESENT);
return zx::make_result(
userboot_client_endpoint.write(0, buffer.data(), static_cast<uint32_t>(num_bytes),
handles.data(), static_cast<uint32_t>(entries.size())));
}
#endif // ZIRCON_KERNEL_LIB_USERABI_USERBOOT_FIDL_H_