blob: 9baa0c8fe043ed39b148ac2a75993276b7fcc505 [file] [log] [blame]
// Copyright 2016 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.
#ifndef REGISTER_IO_H
#define REGISTER_IO_H
#include <lib/magma/platform/platform_mmio.h>
#include <lib/magma/util/macros.h>
#include <memory>
namespace magma {
// RegisterIo wraps mmio access.
class RegisterIo {
public:
RegisterIo(std::unique_ptr<magma::PlatformMmio> mmio);
void Write32(uint32_t val, uint32_t offset) {
mmio_->Write32(val, offset);
if (hook_)
hook_->Write32(val, offset);
}
uint32_t Read32(uint32_t offset) {
uint32_t val = mmio_->Read32(offset);
if (hook_)
hook_->Read32(val, offset);
return val;
}
uint64_t Read64(uint32_t offset) {
if (offset & 0x7) {
uint64_t value = Read32(offset + 4);
value = (value << 32) | Read32(offset);
return value;
}
uint64_t val = mmio_->Read64(offset);
if (hook_)
hook_->Read64(val, offset);
return val;
}
// For hwreg::RegisterBase::WriteTo.
template <typename T>
void Write(T val, uint32_t offset) {
if constexpr (sizeof(T) == sizeof(uint32_t)) {
this->Write32(val, offset);
} else {
static_assert(always_false<T>);
}
}
// For hwreg::RegisterBase::ReadFrom.
template <typename T>
T Read(uint32_t offset) {
if constexpr (sizeof(T) == sizeof(uint32_t)) {
return this->Read32(offset);
} else if constexpr (sizeof(T) == sizeof(uint64_t)) {
return this->Read64(offset);
} else {
static_assert(always_false<T>);
}
}
magma::PlatformMmio* mmio() { return mmio_.get(); }
class Hook {
public:
virtual ~Hook() = 0;
virtual void Write32(uint32_t val, uint32_t offset) = 0;
virtual void Read32(uint32_t val, uint32_t offset) = 0;
virtual void Read64(uint64_t val, uint32_t offset) = 0;
};
void InstallHook(std::unique_ptr<Hook> hook) {
MAGMA_DASSERT(!hook_);
hook_ = std::move(hook);
}
Hook* hook() { return hook_.get(); }
private:
std::unique_ptr<magma::PlatformMmio> mmio_;
std::unique_ptr<Hook> hook_;
template <typename T>
static constexpr std::false_type always_false{};
};
} // namespace magma
#endif // REGISTER_IO_H