L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
io_regblock.h
1/*
2 * (c) 2012 Adam Lackorzynski <adam@os.inf.tu-dresden.de>
3 * economic rights: Technische Universität Dresden (Germany)
4 *
5 * This file is part of TUD:OS and distributed under the terms of the
6 * GNU General Public License 2.
7 * Please see the COPYING-GPL-2 file for details.
8 */
9#pragma once
10
11#ifndef __GXX_EXPERIMENTAL_CXX0X__
12#ifndef static_assert
13#define static_assert(x, y) \
14 do { (void)sizeof(char[-(!(x))]); } while (0)
15#endif
16#endif
17
18namespace L4
19{
20 class Io_register_block
21 {
22 public:
26 virtual unsigned char read8(unsigned long reg) const = 0;
27
31 virtual unsigned short read16(unsigned long reg) const = 0;
32
36 virtual unsigned int read32(unsigned long reg) const = 0;
37
38 /*
39 * \brief Read register with an 8 byte access.
40 */
41 //virtual unsigned long long read64(unsigned long reg) const = 0;
42
46 virtual void write8(unsigned long reg, unsigned char value) const = 0;
47
51 virtual void write16(unsigned long reg, unsigned short value) const = 0;
52
56 virtual void write32(unsigned long reg, unsigned int value) const = 0;
57
58 /*
59 * \brief Write register with an 8 byte access.
60 */
61 //virtual void write64(unsigned long reg, unsigned long long value) const = 0;
62
66 virtual unsigned long addr(unsigned long reg) const = 0;
67
73 virtual void delay() const = 0;
74
75 virtual ~Io_register_block() = 0;
76
84 template< typename R >
85 R read(unsigned long reg) const
86 {
87 switch (sizeof(R))
88 {
89 case 1: return read8(reg);
90 case 2: return read16(reg);
91 case 4: return read32(reg);
92 default: static_assert(sizeof(R) == 1 || sizeof(R) == 2 || sizeof(R) == 4,
93 "Invalid size");
94 };
95 }
96
104 template< typename R >
105 void write(unsigned long reg, R value) const
106 {
107 switch (sizeof(R))
108 {
109 case 1: write8(reg, value); return;
110 case 2: write16(reg, value); return;
111 case 4: write32(reg, value); return;
112 default: static_assert(sizeof(R) == 1 || sizeof(R) == 2 || sizeof(R) == 4,
113 "Invalid size");
114 };
115 }
116
127 template< typename R >
128 R modify(unsigned long reg, R clear_bits, R set_bits) const
129 {
130 R r = (read<R>(reg) & ~clear_bits) | set_bits;
131 write(reg, r);
132 return r;
133 }
134
141 template< typename R >
142 R set(unsigned long reg, R set_bits) const
143 {
144 return modify<R>(reg, 0, set_bits);
145 }
146
153 template< typename R >
154 R clear(unsigned long reg, R clear_bits) const
155 {
156 return modify<R>(reg, clear_bits, 0);
157 }
158
159 };
160
161 inline Io_register_block::~Io_register_block() {}
162
163
164 class Io_register_block_mmio : public Io_register_block
165 {
166 private:
167 template< typename R >
168 R _read(unsigned long reg) const
169 { return *reinterpret_cast<volatile R *>(_base + (reg << _shift)); }
170
171 template< typename R >
172 void _write(unsigned long reg, R val) const
173 { *reinterpret_cast<volatile R *>(_base + (reg << _shift)) = val; }
174
175 public:
176 Io_register_block_mmio(unsigned long base, unsigned char shift = 0)
177 : _base(base), _shift(shift)
178 {}
179
180 unsigned long addr(unsigned long reg) const override
181 { return _base + (reg << _shift); }
182
183 unsigned char read8(unsigned long reg) const override
184 { return _read<unsigned char>(reg); }
185 unsigned short read16(unsigned long reg) const override
186 { return _read<unsigned short>(reg); }
187 unsigned int read32(unsigned long reg) const override
188 { return _read<unsigned int>(reg); }
189
190 void write8(unsigned long reg, unsigned char val) const override
191 { _write(reg, val); }
192 void write16(unsigned long reg, unsigned short val) const override
193 { _write(reg, val); }
194 void write32(unsigned long reg, unsigned int val) const override
195 { _write(reg, val); }
196
197 void delay() const override
198 {}
199
200 private:
201 unsigned long _base;
202 unsigned char _shift;
203 };
204
205 template<typename ACCESS_TYPE>
206 class Io_register_block_mmio_fixed_width : public Io_register_block
207 {
208 private:
209 template< typename R >
210 R _read(unsigned long reg) const
211 { return *reinterpret_cast<volatile ACCESS_TYPE *>(_base + (reg << _shift)); }
212
213 template< typename R >
214 void _write(unsigned long reg, R val) const
215 { *reinterpret_cast<volatile ACCESS_TYPE *>(_base + (reg << _shift)) = val; }
216
217 public:
218 Io_register_block_mmio_fixed_width(unsigned long base, unsigned char shift = 0)
219 : _base(base), _shift(shift)
220 {}
221
222 unsigned long addr(unsigned long reg) const
223 { return _base + (reg << _shift); }
224
225 unsigned char read8(unsigned long reg) const override
226 { return _read<unsigned char>(reg); }
227 unsigned short read16(unsigned long reg) const override
228 { return _read<unsigned short>(reg); }
229 unsigned int read32(unsigned long reg) const override
230 { return _read<unsigned int>(reg); }
231
232 void write8(unsigned long reg, unsigned char val) const override
233 { _write(reg, val); }
234 void write16(unsigned long reg, unsigned short val) const override
235 { _write(reg, val); }
236 void write32(unsigned long reg, unsigned int val) const override
237 { _write(reg, val); }
238
239 void delay() const override
240 {}
241
242 private:
243 unsigned long _base;
244 unsigned char _shift;
245 };
246}
L4 low-level kernel interface.
Definition io_regblock.h:19