Zth (libzth)
regs.h
Go to the documentation of this file.
1 #ifndef ZTH_REGS_H
2 #define ZTH_REGS_H
3 /*
4  * Zth (libzth), a cooperative userspace multitasking library.
5  * Copyright (C) 2019-2022 Jochem Rutgers
6  *
7  * This Source Code Form is subject to the terms of the Mozilla Public
8  * License, v. 2.0. If a copy of the MPL was not distributed with this
9  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
10  */
11 
12 #ifdef __cplusplus
13 # include <libzth/macros.h>
14 # include <libzth/util.h>
15 
21 namespace zth {
22 
32 template <typename T, uintptr_t Addr, typename Fields>
33 struct Register {
34  typedef T type;
35 
36  Register() noexcept
37  {
38  static_assert(sizeof(Fields) == sizeof(type), "");
39  read();
40  }
41 
42  constexpr explicit Register(type v) noexcept
43  : value(v)
44  {}
45 
46  union {
48  Fields field;
49  };
50 
51  static type volatile* r() noexcept
52  {
53  return (type volatile*)Addr;
54  }
55 
56  type read() const noexcept
57  {
58  return *r();
59  }
60 
61  type read() noexcept
62  {
63  return value = *r();
64  }
65 
66  void write() const noexcept
67  {
68  *r() = value;
69  }
70 
71  void write(type v) const noexcept
72  {
73  *r() = v;
74  }
75 
76  void write(type v) noexcept
77  {
78  *r() = value = v;
79  }
80 
81  operator type() const noexcept
82  {
83  return value;
84  }
85 };
86 
87 # if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
88 // In case of little-endian, gcc puts the last field at the highest bits.
89 // This is counter intuitive for registers. Reverse them.
90 # define ZTH_REG_BITFIELDS(...) REVERSE(__VA_ARGS__)
91 # else
92 # define ZTH_REG_BITFIELDS(...) __VA_ARGS__
93 # endif
94 
118 # define ZTH_REG_DEFINE(T, name, addr, fields...) \
119  struct name##__type { \
120  T ZTH_REG_BITFIELDS(fields); \
121  } __attribute__((packed)); \
122  struct name : public zth::Register<T, addr, name##__type> { \
123  typedef zth::Register<T, addr, name##__type> base; \
124  using typename base::type; \
125  name() noexcept \
126  : base() \
127  {} \
128  constexpr explicit name(type v) noexcept \
129  : base(v) \
130  {} \
131  };
132 
133 } // namespace zth
134 #endif // __cplusplus
135 #endif // ZTH_REGS_H
Definition: allocator.h:23
Helper class to read/write (bitfields in) hardware registers.
Definition: regs.h:33
constexpr Register(type v) noexcept
Definition: regs.h:42
type read() noexcept
Definition: regs.h:61
static type volatile * r() noexcept
Definition: regs.h:51
void write(type v) noexcept
Definition: regs.h:76
Fields field
Definition: regs.h:48
type read() const noexcept
Definition: regs.h:56
Register() noexcept
Definition: regs.h:36
void write(type v) const noexcept
Definition: regs.h:71
void write() const noexcept
Definition: regs.h:66
type value
Definition: regs.h:47