L4Re Operating System Framework
Interface and Usage Documentation
Loading...
Searching...
No Matches
io_regblock.h
1/*
2 * Copyright (C) 2012 Technische Universität Dresden.
3 * Author(s): Adam Lackorzynski <adam@os.inf.tu-dresden.de>
4 *
5 * License: see LICENSE.spdx (in this directory or the directories above)
6 */
7#pragma once
8
9namespace L4
10{
11 class Io_register_block
12 {
13 public:
17 virtual unsigned char read8(unsigned long reg) const = 0;
18
22 virtual unsigned short read16(unsigned long reg) const = 0;
23
27 virtual unsigned int read32(unsigned long reg) const = 0;
28
29 /*
30 * \brief Read register with an 8 byte access.
31 */
32 //virtual unsigned long long read64(unsigned long reg) const = 0;
33
37 virtual void write8(unsigned long reg, unsigned char value) const = 0;
38
42 virtual void write16(unsigned long reg, unsigned short value) const = 0;
43
47 virtual void write32(unsigned long reg, unsigned int value) const = 0;
48
49 /*
50 * \brief Write register with an 8 byte access.
51 */
52 //virtual void write64(unsigned long reg, unsigned long long value) const = 0;
53
57 virtual unsigned long addr(unsigned long reg) const = 0;
58
64 virtual void delay() const = 0;
65
66 virtual ~Io_register_block() = 0;
67
75 template< typename R >
76 R read(unsigned long reg) const
77 {
78 static_assert(sizeof(R) == 1 || sizeof(R) == 2 || sizeof(R) == 4,
79 "Invalid size");
80
81 switch (sizeof(R))
82 {
83 case 1: return read8(reg);
84 case 2: return read16(reg);
85 case 4: return read32(reg);
86 };
87 }
88
96 template< typename R >
97 void write(unsigned long reg, R value) const
98 {
99 static_assert(sizeof(R) == 1 || sizeof(R) == 2 || sizeof(R) == 4,
100 "Invalid size");
101
102 switch (sizeof(R))
103 {
104 case 1: write8(reg, value); return;
105 case 2: write16(reg, value); return;
106 case 4: write32(reg, value); return;
107 };
108 }
109
120 template< typename R >
121 R modify(unsigned long reg, R clear_bits, R set_bits) const
122 {
123 R r = (read<R>(reg) & ~clear_bits) | set_bits;
124 write(reg, r);
125 return r;
126 }
127
134 template< typename R >
135 R set(unsigned long reg, R set_bits) const
136 {
137 return modify<R>(reg, 0, set_bits);
138 }
139
146 template< typename R >
147 R clear(unsigned long reg, R clear_bits) const
148 {
149 return modify<R>(reg, clear_bits, 0);
150 }
151
152 };
153
154 inline Io_register_block::~Io_register_block() {}
155
156
157 class Io_register_block_mmio : public Io_register_block
158 {
159 private:
160 template< typename R >
161 R _read(unsigned long reg) const
162 { return *reinterpret_cast<volatile R *>(_base + (reg << _shift)); }
163
164 template< typename R >
165 void _write(unsigned long reg, R val) const
166 { *reinterpret_cast<volatile R *>(_base + (reg << _shift)) = val; }
167
168 public:
169 Io_register_block_mmio(unsigned long base, unsigned char shift = 0)
170 : _base(base), _shift(shift)
171 {}
172
173 unsigned long addr(unsigned long reg) const override
174 { return _base + (reg << _shift); }
175
176 unsigned char read8(unsigned long reg) const override
177 { return _read<unsigned char>(reg); }
178 unsigned short read16(unsigned long reg) const override
179 { return _read<unsigned short>(reg); }
180 unsigned int read32(unsigned long reg) const override
181 { return _read<unsigned int>(reg); }
182
183 void write8(unsigned long reg, unsigned char val) const override
184 { _write(reg, val); }
185 void write16(unsigned long reg, unsigned short val) const override
186 { _write(reg, val); }
187 void write32(unsigned long reg, unsigned int val) const override
188 { _write(reg, val); }
189
190 void delay() const override
191 {}
192
193 void set_base(unsigned long base) { _base = base; }
194 void set_shift(unsigned char shift) { _shift = shift; }
195
196 unsigned long get_base() const { return _base; }
197
198 private:
199 unsigned long _base;
200 unsigned char _shift;
201 };
202
203 template<typename ACCESS_TYPE>
204 class Io_register_block_mmio_fixed_width : public Io_register_block
205 {
206 private:
207 template< typename R >
208 R _read(unsigned long reg) const
209 { return *reinterpret_cast<volatile ACCESS_TYPE *>(_base + (reg << _shift)); }
210
211 template< typename R >
212 void _write(unsigned long reg, R val) const
213 { *reinterpret_cast<volatile ACCESS_TYPE *>(_base + (reg << _shift)) = val; }
214
215 public:
216 Io_register_block_mmio_fixed_width(unsigned long base, unsigned char shift = 0)
217 : _base(base), _shift(shift)
218 {}
219
220 unsigned long addr(unsigned long reg) const
221 { return _base + (reg << _shift); }
222
223 unsigned char read8(unsigned long reg) const override
224 { return _read<unsigned char>(reg); }
225 unsigned short read16(unsigned long reg) const override
226 { return _read<unsigned short>(reg); }
227 unsigned int read32(unsigned long reg) const override
228 { return _read<unsigned int>(reg); }
229
230 void write8(unsigned long reg, unsigned char val) const override
231 { _write(reg, val); }
232 void write16(unsigned long reg, unsigned short val) const override
233 { _write(reg, val); }
234 void write32(unsigned long reg, unsigned int val) const override
235 { _write(reg, val); }
236
237 void delay() const override
238 {}
239
240 private:
241 unsigned long _base;
242 unsigned char _shift;
243 };
244}
L4 low-level kernel interface.