1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #pragma once
6 
7 #include <hwreg/internal.h>
8 
9 #include <stdint.h>
10 
11 namespace hwreg {
12 
13 // Wrap MMIO for easier testing of device drivers
14 
15 class RegisterIo {
16 public:
RegisterIo(volatile void * mmio)17     RegisterIo(volatile void* mmio) : mmio_(reinterpret_cast<uintptr_t>(mmio)) {
18     }
19 
20     // Write |val| to the |sizeof(IntType)| byte field located |offset| bytes from
21     // |base()|.
Write(uint32_t offset,IntType val)22     template <class IntType> void Write(uint32_t offset, IntType val) {
23         static_assert(internal::IsSupportedInt<IntType>::value,
24                       "unsupported register access width");
25         auto ptr = reinterpret_cast<volatile IntType*>(mmio_ + offset);
26         *ptr = val;
27     }
28 
29     // Read the value of the |sizeof(IntType)| byte field located |offset| bytes from
30     // |base()|.
Read(uint32_t offset)31     template <class IntType> IntType Read(uint32_t offset) {
32         static_assert(internal::IsSupportedInt<IntType>::value,
33                       "unsupported register access width");
34         auto ptr = reinterpret_cast<volatile IntType*>(mmio_ + offset);
35         return *ptr;
36     }
37 
base()38     uintptr_t base() const { return mmio_; }
39 
40 private:
41     const uintptr_t mmio_;
42 };
43 
44 } // namespace hwreg
45