blob: a38a7defafaa4cb03b749e15c4071262c6765c0f [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fbl/ref_ptr.h>
#include <fbl/unique_fd.h>
#include <fbl/unique_ptr.h>
#include <fuchsia/sysinfo/c/fidl.h>
#include <lib/fidl-utils/bind.h>
#include <lib/fzl/vmo-mapper.h>
#include <ramdevice-client/ramdisk.h>
#include <ramdevice-client/ramnand.h>
#include <zxtest/zxtest.h>
constexpr uint64_t kBlockSize = 0x1000;
constexpr uint64_t kBlockCount = 0x100;
constexpr uint32_t kOobSize = 8;
constexpr uint32_t kPageSize = 1024;
constexpr uint32_t kPagesPerBlock = 16;
constexpr uint32_t kSkipBlockSize = kPageSize * kPagesPerBlock;
constexpr uint32_t kNumBlocks = 20;
extern fbl::Vector<fbl::String> test_block_devices;
bool FilterRealBlockDevices(const fbl::unique_fd& fd);
class BlockDevice {
public:
static void Create(const uint8_t* guid, fbl::unique_ptr<BlockDevice>* device);
~BlockDevice() {
ramdisk_destroy(client_);
}
// Does not transfer ownership of the file descriptor.
int fd() { return ramdisk_get_block_fd(client_); }
private:
BlockDevice(ramdisk_client_t* client)
: client_(client) {}
ramdisk_client_t* client_;
};
class SkipBlockDevice {
public:
static void Create(const fuchsia_hardware_nand_RamNandInfo& nand_info,
fbl::unique_ptr<SkipBlockDevice>* device);
fbl::unique_fd devfs_root() { return fbl::unique_fd(dup(ctl_->devfs_root().get())); }
fzl::VmoMapper& mapper() { return mapper_; }
~SkipBlockDevice() = default;
private:
SkipBlockDevice(fbl::RefPtr<ramdevice_client::RamNandCtl> ctl,
ramdevice_client::RamNand ram_nand, fzl::VmoMapper mapper)
: ctl_(std::move(ctl)), ram_nand_(std::move(ram_nand)), mapper_(std::move(mapper)) {}
fbl::RefPtr<ramdevice_client::RamNandCtl> ctl_;
ramdevice_client::RamNand ram_nand_;
fzl::VmoMapper mapper_;
};
class FakeSysinfo {
public:
FakeSysinfo(async_dispatcher_t* dispatcher) {
zx::channel remote;
ASSERT_OK(zx::channel::create(0, &remote, &svc_chan_));
fidl_bind(dispatcher, remote.release(),
reinterpret_cast<fidl_dispatch_t*>(fuchsia_sysinfo_Device_dispatch),
this, &ops_);
}
zx_status_t GetRootJob(fidl_txn_t* txn) {
return fuchsia_sysinfo_DeviceGetRootJob_reply(txn, ZX_ERR_NOT_SUPPORTED, ZX_HANDLE_INVALID);
}
zx_status_t GetRootResource(fidl_txn_t* txn) {
return fuchsia_sysinfo_DeviceGetRootResource_reply(txn, ZX_ERR_NOT_SUPPORTED,
ZX_HANDLE_INVALID);
}
zx_status_t GetHypervisorResource(fidl_txn_t* txn) {
return fuchsia_sysinfo_DeviceGetHypervisorResource_reply(txn, ZX_ERR_NOT_SUPPORTED,
ZX_HANDLE_INVALID);
}
zx_status_t GetBoardName(fidl_txn_t* txn) {
char board[32] = {};
strcpy(board, "vim2");
return fuchsia_sysinfo_DeviceGetBoardName_reply(txn, ZX_OK, board, 32);
}
zx_status_t GetInterruptControllerInfo(fidl_txn_t* txn) {
return fuchsia_sysinfo_DeviceGetInterruptControllerInfo_reply(txn, ZX_ERR_NOT_SUPPORTED,
nullptr);
}
zx::channel& svc_chan() { return svc_chan_; }
private:
using Binder = fidl::Binder<FakeSysinfo>;
zx::channel svc_chan_;
static constexpr fuchsia_sysinfo_Device_ops_t ops_ = {
.GetRootJob = Binder::BindMember<&FakeSysinfo::GetRootJob>,
.GetRootResource = Binder::BindMember<&FakeSysinfo::GetRootResource>,
.GetHypervisorResource = Binder::BindMember<&FakeSysinfo::GetHypervisorResource>,
.GetBoardName = Binder::BindMember<&FakeSysinfo::GetBoardName>,
.GetInterruptControllerInfo = Binder::BindMember<&FakeSysinfo::GetInterruptControllerInfo>,
};
};