Skip to content

Commit 4d52c3a

Browse files
committed
mem_space: Implement {io,main}_mem_space
1 parent 0ae2427 commit 4d52c3a

File tree

5 files changed

+91
-10
lines changed

5 files changed

+91
-10
lines changed

include/arch/aarch64/mem_space.hpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,34 @@ namespace _detail {
168168
};
169169
}
170170

171+
template<typename B>
172+
struct io_mem_ops {
173+
static B load(const B *p) {
174+
auto v = _detail::mem_ops<B>::load_relaxed(p);
175+
asm volatile("dmb oshld" ::: "memory");
176+
return v;
177+
}
178+
179+
static void store(B *p, B v) {
180+
asm volatile("dmb osh" ::: "memory");
181+
_detail::mem_ops<B>::store_relaxed(p, v);
182+
}
183+
};
184+
185+
template<typename B>
186+
struct main_mem_ops {
187+
static B load(const B *p) {
188+
auto v = _detail::mem_ops<B>::load_relaxed(p);
189+
asm volatile("dmb ishld" ::: "memory");
190+
return v;
191+
}
192+
193+
static void store(B *p, B v) {
194+
asm volatile("dmb ish" ::: "memory");
195+
_detail::mem_ops<B>::store_relaxed(p, v);
196+
}
197+
};
198+
171199
using _detail::mem_ops;
172200

173201
} // namespace arch

include/arch/arm/mem_space.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,14 @@ namespace _detail {
123123
};
124124
}
125125

126+
// TODO: This is not correct.
127+
template<typename B>
128+
using io_mem_ops = mem_ops<B>;
129+
130+
// TODO: This is not correct.
131+
template<typename B>
132+
using main_mem_ops = mem_ops<B>;
133+
126134
using _detail::mem_ops;
127135

128136
} // namespace arch

include/arch/mem_space.hpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,52 +14,59 @@
1414

1515
namespace arch {
1616

17-
struct mem_space {
18-
constexpr mem_space()
17+
namespace _details {
18+
19+
template<template<typename> typename Ops>
20+
struct base_mem_space {
21+
constexpr base_mem_space()
1922
: _base(0) { }
2023

21-
constexpr mem_space(uintptr_t base)
24+
constexpr base_mem_space(uintptr_t base)
2225
: _base(base) { }
2326

24-
mem_space(void *base)
27+
base_mem_space(void *base)
2528
: _base(reinterpret_cast<uintptr_t>(base)) { }
2629

27-
mem_space subspace(ptrdiff_t offset) const {
28-
return mem_space(reinterpret_cast<void *>(_base + offset));
30+
base_mem_space subspace(ptrdiff_t offset) const {
31+
return base_mem_space(reinterpret_cast<void *>(_base + offset));
2932
}
3033

3134
template<typename RT>
3235
void store(RT r, typename RT::rep_type value) const {
3336
auto p = reinterpret_cast<typename RT::bits_type *>(_base + r.offset());
3437
auto v = static_cast<typename RT::bits_type>(value);
35-
mem_ops<typename RT::bits_type>::store(p, v);
38+
Ops<typename RT::bits_type>::store(p, v);
3639
}
3740

3841
template<typename RT>
3942
typename RT::rep_type load(RT r) const {
4043
auto p = reinterpret_cast<const typename RT::bits_type *>(_base + r.offset());
41-
auto b = mem_ops<typename RT::bits_type>::load(p);
44+
auto b = Ops<typename RT::bits_type>::load(p);
4245
return static_cast<typename RT::rep_type>(b);
4346
}
4447

4548
template<typename RT>
4649
void store_relaxed(RT r, typename RT::rep_type value) const {
4750
auto p = reinterpret_cast<typename RT::bits_type *>(_base + r.offset());
4851
auto v = static_cast<typename RT::bits_type>(value);
49-
mem_ops<typename RT::bits_type>::store_relaxed(p, v);
52+
Ops<typename RT::bits_type>::store_relaxed(p, v);
5053
}
5154

5255
template<typename RT>
5356
typename RT::rep_type load_relaxed(RT r) const {
5457
auto p = reinterpret_cast<const typename RT::bits_type *>(_base + r.offset());
55-
auto b = mem_ops<typename RT::bits_type>::load_relaxed(p);
58+
auto b = Ops<typename RT::bits_type>::load_relaxed(p);
5659
return static_cast<typename RT::rep_type>(b);
5760
}
5861

5962
private:
6063
uintptr_t _base;
6164
};
6265

66+
} // namespace _details
67+
68+
using mem_space = _details::base_mem_space<mem_ops>;
69+
6370
static constexpr mem_space global_mem{};
6471

6572
} // namespace arch

include/arch/riscv64/mem_space.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,36 @@ namespace _detail {
9191
};
9292
}
9393

94+
template<typename B>
95+
struct io_mem_ops {
96+
static B load(const B *p) {
97+
asm volatile("fence r, i" ::: "memory");
98+
auto v = _detail::mem_ops<B>::load_relaxed(p);
99+
asm volatile("fence i, rw" ::: "memory");
100+
return v;
101+
}
102+
103+
static void store(B *p, B v) {
104+
asm volatile("fence rw, o" ::: "memory");
105+
_detail::mem_ops<B>::store_relaxed(p, v);
106+
asm volatile("fence o, w" ::: "memory");
107+
}
108+
};
109+
110+
template<typename B>
111+
struct main_mem_ops {
112+
static B load(const B *p) {
113+
auto v = _detail::mem_ops<B>::load_relaxed(p);
114+
asm volatile("fence r, rw" ::: "memory");
115+
return v;
116+
}
117+
118+
static void store(B *p, B v) {
119+
asm volatile("fence rw, w" ::: "memory");
120+
_detail::mem_ops<B>::store_relaxed(p, v);
121+
}
122+
};
123+
94124
using _detail::mem_ops;
95125

96126
} // namespace arch

include/arch/x86/mem_space.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ namespace _detail {
9393
};
9494
}
9595

96+
// x86 has TSO which is strong enough to not require barriers anywhere.
97+
98+
template<typename B>
99+
using io_mem_ops = _detail::mem_ops<B>;
100+
101+
template<typename B>
102+
using main_mem_ops = _detail::mem_ops<B>;
103+
96104
using _detail::mem_ops;
97105

98106
} // namespace arch

0 commit comments

Comments
 (0)