@@ -102,20 +102,21 @@ template <typename WORD_TYPE> struct clic : public memory_elem {
102102 clic_cfg_reg = 0x30 ;
103103 clic_mact_lvl = clic_mprev_lvl = (1 << (cfg.clic_int_ctl_bits )) - 1 ;
104104 clic_uact_lvl = clic_uprev_lvl = (1 << (cfg.clic_int_ctl_bits )) - 1 ;
105- hart_if.csr_rd_cb [arch::mtvt] = MK_CSR_RD_CB (read_xtvt); // 0x307
105+ hart_if.csr_rd_cb [arch::mcause] = MK_CSR_RD_CB (read_cause);
106+ hart_if.csr_wr_cb [arch::mcause] = MK_CSR_WR_CB (write_cause);
107+ hart_if.csr_rd_cb [arch::mtvec] = MK_CSR_RD_CB (read_xtvec);
108+ hart_if.csr_wr_cb [arch::mtvec] = MK_CSR_WR_CB (write_xtvec);
109+ hart_if.csr_rd_cb [arch::mtvt] = MK_CSR_RD_CB (read_xtvt);
106110 hart_if.csr_wr_cb [arch::mtvt] = MK_CSR_WR_CB (write_xtvt);
107- // hart_if.csr_rd_cb[mxnti] = MK_CSR_RD_CB(read_plain(a,r);};
108- // hart_if.csr_wr_cb[mxnti] = MK_CSR_WR_CB(write_plain(a,r);};
109111 hart_if.csr_rd_cb [arch::mintstatus] = MK_CSR_RD_CB (read_intstatus);
110112 hart_if.csr_wr_cb [arch::mintstatus] = MK_CSR_WR_CB (write_null);
111- // hart_if.csr_rd_cb[mscratchcsw] = MK_CSR_RD_CB(read_plain(a,r);};
112- // hart_if.csr_wr_cb[mscratchcsw] = MK_CSR_WR_CB(write_plain(a,r);};
113- // hart_if.csr_rd_cb[mscratchcswl] = MK_CSR_RD_CB(read_plain(a,r);};
114- // hart_if.csr_wr_cb[mscratchcswl] = MK_CSR_WR_CB(write_plain(a,r);};
115113 hart_if.csr_rd_cb [arch::mintthresh] = MK_CSR_RD_CB (read_intthresh);
116114 hart_if.csr_wr_cb [arch::mintthresh] = MK_CSR_WR_CB (write_intthresh);
117115 if (cfg.nmode ) {
118- hart_if.csr_rd_cb [arch::utvt] = MK_CSR_RD_CB (read_xtvt); // 0x007
116+ hart_if.csr_rd_cb [arch::ucause] = MK_CSR_RD_CB (read_cause);
117+ hart_if.csr_wr_cb [arch::ucause] = MK_CSR_WR_CB (write_cause);
118+ hart_if.csr_rd_cb [arch::utvec] = MK_CSR_RD_CB (read_xtvec);
119+ hart_if.csr_rd_cb [arch::utvt] = MK_CSR_RD_CB (read_xtvt);
119120 hart_if.csr_wr_cb [arch::utvt] = MK_CSR_WR_CB (write_xtvt);
120121 hart_if.csr_rd_cb [arch::uintstatus] = MK_CSR_RD_CB (read_intstatus);
121122 hart_if.csr_wr_cb [arch::uintstatus] = MK_CSR_WR_CB (write_null);
@@ -139,13 +140,15 @@ template <typename WORD_TYPE> struct clic : public memory_elem {
139140
140141private:
141142 iss::status read_mem (addr_t const & addr, unsigned length, uint8_t * data) {
142- if (addr.space == 0 && addr.val >= cfg.clic_base && (addr.val + length) < (cfg.clic_base + 0x8000 ))
143+ auto end_addr = addr.val - 1 + length;
144+ if (addr.space == 0 && addr.val <=end_addr && addr.val >= cfg.clic_base && end_addr <= (cfg.clic_base + 0x7fff ))
143145 return read_clic (addr.val , length, data);
144146 return down_stream_mem.rd_mem (addr, length, data);
145147 }
146148
147149 iss::status write_mem (addr_t const & addr, unsigned length, uint8_t const * data) {
148- if (addr.space == 0 && addr.val >= cfg.clic_base && (addr.val + length) < (cfg.clic_base + 0x8000 ))
150+ auto end_addr = addr.val - 1 + length;
151+ if (addr.space == 0 && addr.val <=end_addr && addr.val >= cfg.clic_base && end_addr <= (cfg.clic_base + 0x7fff ))
149152 return write_clic (addr.val , length, data);
150153 return down_stream_mem.wr_mem (addr, length, data);
151154 }
@@ -184,6 +187,50 @@ template <typename WORD_TYPE> struct clic : public memory_elem {
184187 return iss::Ok;
185188 }
186189
190+ iss::status read_xtvec (unsigned addr, reg_t & val) {
191+ val = hart_if.get_csr (addr);
192+ return iss::Ok;
193+ }
194+
195+ iss::status write_xtvec (unsigned addr, reg_t val) {
196+ hart_if.set_csr (addr, val);
197+ if ((val & 0x3 ) != 0x3 ) {
198+ clic_mprev_lvl = 0xff >>cfg.clic_int_ctl_bits ;
199+ clic_uprev_lvl = 0xff >>cfg.clic_int_ctl_bits ;
200+ }
201+ return iss::Ok;
202+ }
203+
204+ iss::status read_cause (unsigned addr, reg_t & val) {
205+ val = hart_if.get_csr (addr) & ((1UL << (WORD_LEN - 1 )) | (hart_if.max_irq - 1 ));
206+ auto xtvec = hart_if.get_csr (arch::mtvec);
207+ if ((xtvec& 0x3 ) == 0x3 ) {
208+ if (addr == arch::mcause) { // mcause access
209+ val |= hart_if.state .mstatus .MPP <<28 | hart_if.state .mstatus .MPIE <<27 |clic_mprev_lvl<<16 ;
210+ } else if (addr ==arch::ucause) {
211+ val |= hart_if.state .mstatus .UPIE <<27 | clic_uprev_lvl<<16 ;
212+ }
213+ }
214+ return iss::Ok;
215+ }
216+
217+ iss::status write_cause (unsigned addr, reg_t val) {
218+ auto mask = ((1UL << (WORD_LEN - 1 )) | (hart_if.max_irq - 1 ));
219+ hart_if.set_csr (addr,(val & mask) | (hart_if.get_csr (addr) & ~mask));
220+ auto xtvec = hart_if.get_csr (arch::mtvec);
221+ if ((xtvec & 0x3 ) == 0x3 ) {
222+ if (addr == arch::mcause){ // mcause access
223+ hart_if.state .mstatus .MPIE = (val>>27 )&1 ;
224+ clic_mprev_lvl = ((val >> 16 ) & 0xff ) | 0xff >>cfg.clic_int_ctl_bits ;
225+ hart_if.state .mstatus .MPP = (val <<28 )&0x3 ;
226+ } else if (addr ==arch::ucause) {
227+ hart_if.state .mstatus .UPIE = (val>>27 )&1 ;
228+ clic_uprev_lvl = ((val >> 16 ) & 0xff ) | 0xff >>cfg.clic_int_ctl_bits ;
229+ }
230+ }
231+ return iss::Ok;
232+ }
233+
187234protected:
188235 arch::priv_if<WORD_TYPE> hart_if;
189236 memory_if down_stream_mem;
@@ -202,8 +249,8 @@ template <typename WORD_TYPE> struct clic : public memory_elem {
202249 std::vector<clic_int_reg_t > clic_int_reg;
203250 uint8_t clic_mprev_lvl{0 }, clic_uprev_lvl{0 };
204251 uint8_t clic_mact_lvl{0 }, clic_uact_lvl{0 };
205- std::array<reg_t , 4 > clic_intthresh;
206- std::array<reg_t , 4 > clic_xtvt;
252+ std::array<reg_t , 4 > clic_intthresh{ 0 } ;
253+ std::array<reg_t , 4 > clic_xtvt{ 0 } ;
207254};
208255
209256template <typename WORD_TYPE> iss::status clic<WORD_TYPE>::read_clic(uint64_t addr, unsigned length, uint8_t * const data) {
0 commit comments