blob: 1888d7c784685e19905bfadce5c8f6f3e661de53 [file] [log] [blame]
// Copyright 2021 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 "src/devices/bus/testing/fake-pdev/fake-pdev.h"
#include <lib/fake-bti/bti.h>
#include <lib/fake-resource/resource.h>
namespace fake_pdev {
fake_ddk::FragmentEntry FakePDev::fragment() const {
return fake_ddk::FragmentEntry{
.name = "fuchsia.hardware.platform.device.PDev",
.protocols = {fake_ddk::ProtocolEntry{ZX_PROTOCOL_PDEV,
*reinterpret_cast<const fake_ddk::Protocol*>(proto())}},
};
}
zx::unowned_interrupt FakePDev::CreateVirtualInterrupt(uint32_t idx) {
fbl::AutoLock al(&lock_);
zx::interrupt irq;
auto status = zx::interrupt::create(zx::resource(), 0, ZX_INTERRUPT_VIRTUAL, &irq);
ZX_ASSERT(status == ZX_OK);
zx::unowned_interrupt ret(irq);
irqs_[0] = std::move(irq);
return ret;
}
zx_status_t FakePDev::PDevGetMmio(uint32_t index, pdev_mmio_t* out_mmio) {
fbl::AutoLock al(&lock_);
auto mmio = mmios_.find(index);
if (mmio == mmios_.end()) {
return ZX_ERR_OUT_OF_RANGE;
}
zx::vmo dup;
mmio->second.vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &dup);
out_mmio->vmo = dup.release();
out_mmio->offset = mmio->second.offset;
out_mmio->size = mmio->second.size;
return ZX_OK;
}
zx_status_t FakePDev::PDevGetBti(uint32_t index, zx::bti* out_bti) {
fbl::AutoLock al(&lock_);
auto bti = btis_.find(index);
if (bti == btis_.end()) {
if (use_fake_bti_) {
return fake_bti_create(out_bti->reset_and_get_address());
}
return ZX_ERR_OUT_OF_RANGE;
}
bti->second.duplicate(ZX_RIGHT_SAME_RIGHTS, out_bti);
return ZX_OK;
}
zx_status_t FakePDev::PDevGetSmc(uint32_t index, zx::resource* out_resource) {
fbl::AutoLock al(&lock_);
auto smc = smcs_.find(index);
if (smc == smcs_.end()) {
if (use_fake_smc_) {
return fake_root_resource_create(out_resource->reset_and_get_address());
}
return ZX_ERR_OUT_OF_RANGE;
}
smc->second.duplicate(ZX_RIGHT_SAME_RIGHTS, out_resource);
return ZX_OK;
}
zx_status_t FakePDev::PDevGetInterrupt(uint32_t index, uint32_t flags, zx::interrupt* out_irq) {
fbl::AutoLock al(&lock_);
auto irq = irqs_.find(index);
if (irq == irqs_.end()) {
return ZX_ERR_OUT_OF_RANGE;
}
irq->second.duplicate(ZX_RIGHT_SAME_RIGHTS, out_irq);
return ZX_OK;
}
zx_status_t FakePDev::PDevGetDeviceInfo(pdev_device_info_t* out_info) {
fbl::AutoLock al(&lock_);
if (device_info_) {
*out_info = *device_info_;
return ZX_OK;
}
return ZX_ERR_NOT_SUPPORTED;
}
zx_status_t FakePDev::PDevGetBoardInfo(pdev_board_info_t* out_info) {
fbl::AutoLock al(&lock_);
if (board_info_) {
*out_info = *board_info_;
return ZX_OK;
}
return ZX_ERR_NOT_SUPPORTED;
}
} // namespace fake_pdev