4040#include < memory>
4141#include < util/ities.h>
4242#include < vector>
43+ #include " iss/arch/riscv_hart_common.h"
4344
4445namespace iss {
45- namespace arch {
46+ namespace mem {
4647namespace cache {
4748
4849enum class state { INVALID, VALID };
@@ -74,17 +75,23 @@ struct wt_policy {
7475} // namespace cache
7576
7677// write thru, allocate on read, direct mapped or set-associative with round-robin replacement policy
77- template <typename BASE > class wt_cache : public BASE {
78+ template <typename PLAT > class wt_cache : public PLAT {
7879public:
79- using base_class = BASE ;
80- using this_class = wt_cache<BASE >;
81- using reg_t = typename BASE ::reg_t ;
82- using mem_read_f = typename BASE ::mem_read_f;
83- using mem_write_f = typename BASE ::mem_write_f;
84- using phys_addr_t = typename BASE ::phys_addr_t ;
85-
86- wt_cache (feature_config cfg = feature_config{} );
80+ using base_class = PLAT ;
81+ using this_class = wt_cache<PLAT >;
82+ using reg_t = typename PLAT ::reg_t ;
83+ using mem_read_f = typename PLAT ::mem_read_f;
84+ using mem_write_f = typename PLAT ::mem_write_f;
85+ using phys_addr_t = typename PLAT ::phys_addr_t ;
86+
87+ wt_cache (arch::priv_if< reg_t > hart_if );
8788 virtual ~wt_cache () = default ;
89+ memory_if get_mem_if () override {
90+ return memory_if{.rd_mem {util::delegate<rd_mem_func_sig>::from<this_class, &this_class::read_cache>(this )},
91+ .wr_mem {util::delegate<wr_mem_func_sig>::from<this_class, &this_class::write_cache>(this )}};
92+ }
93+
94+ void set_next (memory_if mem) override { down_stream_mem = mem; }
8895
8996 unsigned size{4096 };
9097 unsigned line_sz{64 };
@@ -93,28 +100,26 @@ template <typename BASE> class wt_cache : public BASE {
93100 uint64_t io_addr_mask{0xf0000000 };
94101
95102protected:
96- iss::status read_cache (phys_addr_t addr, unsigned , uint8_t * const );
97- iss::status write_cache (phys_addr_t addr, unsigned , uint8_t const * const );
98- std::function<mem_read_f> cache_mem_rd_delegate ;
99- std::function<mem_write_f> cache_mem_wr_delegate ;
103+ iss::status read_cache (addr_t addr, unsigned , uint8_t * const );
104+ iss::status write_cache (addr_t addr, unsigned , uint8_t const * const );
105+ arch::priv_if< reg_t > hart_if ;
106+ memory_if down_stream_mem ;
100107 std::unique_ptr<cache::cache> dcache_ptr;
101108 std::unique_ptr<cache::cache> icache_ptr;
102109 size_t get_way_select () { return 0 ; }
103110};
104111
105- template <typename BASE >
106- inline wt_cache<BASE >::wt_cache(feature_config cfg )
107- : BASE(cfg )
112+ template <typename PLAT >
113+ inline wt_cache<PLAT >::wt_cache(arch::priv_if< reg_t > hart_if )
114+ : hart_if(hart_if )
108115, io_address{cfg.io_address }
109116, io_addr_mask{cfg.io_addr_mask } {
110117 auto cb = base_class::replace_mem_access (
111118 [this ](phys_addr_t a, unsigned l, uint8_t * const d) -> iss::status { return read_cache (a, l, d); },
112119 [this ](phys_addr_t a, unsigned l, uint8_t const * const d) -> iss::status { return write_cache (a, l, d); });
113- cache_mem_rd_delegate = cb.first ;
114- cache_mem_wr_delegate = cb.second ;
115120}
116121
117- template <typename BASE > iss::status iss::arch:: wt_cache<BASE >::read_cache(phys_addr_t a, unsigned l, uint8_t * const d) {
122+ template <typename PLAT > iss::status wt_cache<PLAT >::read_cache(addr_t a, unsigned l, uint8_t * const d) {
118123 if (!icache_ptr) {
119124 icache_ptr.reset (new cache::cache (size, line_sz, ways));
120125 dcache_ptr.reset (new cache::cache (size, line_sz, ways));
@@ -142,13 +147,13 @@ template <typename BASE> iss::status iss::arch::wt_cache<BASE>::read_cache(phys_
142147 d[i] = cl.data [start_addr + i];
143148 return iss::Ok;
144149 } else
145- return cache_mem_rd_delegate (a, l, d );
150+ return down_stream_mem. rd_mem (addr, length, data );
146151}
147152
148- template <typename BASE > iss::status iss::arch:: wt_cache<BASE >::write_cache(phys_addr_t a, unsigned l, const uint8_t * const d) {
153+ template <typename PLAT > iss::status wt_cache<PLAT >::write_cache(addr_t a, unsigned l, const uint8_t * const d) {
149154 if (!dcache_ptr)
150155 dcache_ptr.reset (new cache::cache (size, line_sz, ways));
151- auto res = cache_mem_wr_delegate (a, l, d );
156+ auto res = down_stream_mem. wr_mem (addr, length, data );
152157 if (res == iss::Ok && ((a.val & io_addr_mask) != io_address)) {
153158 auto set_addr = (a.val & (size - 1 )) >> util::ilog2 (line_sz * ways);
154159 auto tag_addr = a.val >> util::ilog2 (line_sz);
0 commit comments