Compare commits
	
		
			1 Commits
		
	
	
		
			a943dd3bdf
			...
			39b2788b7e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 39b2788b7e | 
| @@ -221,6 +221,7 @@ struct vm_info { | ||||
|  | ||||
| struct feature_config { | ||||
|     uint64_t clic_base{0xc0000000}; | ||||
|     unsigned clic_int_ctl_bits{4}; | ||||
|     unsigned clic_num_irq{16}; | ||||
|     unsigned clic_num_trigger{0}; | ||||
|     uint64_t tcm_base{0x10000000}; | ||||
|   | ||||
| @@ -289,6 +289,8 @@ protected: | ||||
|         uint32_t raw; | ||||
|     }; | ||||
|     std::vector<clic_int_reg_t> clic_int_reg; | ||||
|     uint8_t clic_mprev_lvl{0}; | ||||
|     uint8_t clic_mact_lvl{0}; | ||||
|  | ||||
|     std::vector<uint8_t> tcm; | ||||
|  | ||||
| @@ -430,6 +432,8 @@ riscv_hart_m_p<BASE, FEAT>::riscv_hart_m_p(feature_config cfg) | ||||
|         clic_int_reg.resize(cfg.clic_num_irq,  clic_int_reg_t{.raw=0}); | ||||
|         clic_cfg_reg=0x20; | ||||
|         clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq; | ||||
|         clic_mact_lvl = clic_mprev_lvl = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         csr[mintthresh] = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         insert_mem_range(cfg.clic_base, 0x5000UL, | ||||
|                 [this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);}, | ||||
|                 [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);}); | ||||
| @@ -869,18 +873,26 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT> | ||||
| template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::read_cause(unsigned addr, reg_t &val) { | ||||
|     auto res = csr[addr]; | ||||
|     if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) { | ||||
|         res |= state.mstatus.MPIE<<27; | ||||
|         res |= state.mstatus.MPP<<28; | ||||
|     } | ||||
|     val=res; | ||||
|         val = csr[addr] & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16)); | ||||
|         val |= clic_mprev_lvl<<16; | ||||
|         val |= state.mstatus.MPIE<<27; | ||||
|         val |= state.mstatus.MPP<<28; | ||||
|     } else | ||||
|         val = csr[addr] & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1)); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) { | ||||
|     csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1)); | ||||
|     if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) { | ||||
|         auto mask = ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16)); | ||||
|         csr[addr] = (val & mask) | (csr[addr] & ~mask); | ||||
|         clic_mprev_lvl = ((val>>16)&0xff) | (1<<(8-cfg. clic_int_ctl_bits)) - 1; | ||||
|         state.mstatus.MPIE=(val>>27)&0x1; | ||||
|         state.mstatus.MPP=(val>>28)&0x3; | ||||
|     } else { | ||||
|         auto mask = ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1)); | ||||
|         csr[addr] = (val & mask) | (csr[addr] & ~mask); | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
| @@ -955,7 +967,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_m_p<BASE, FEAT> | ||||
|  | ||||
| template<typename BASE, features_e FEAT> | ||||
| iss::status riscv_hart_m_p<BASE, FEAT>::write_intthresh(unsigned addr, reg_t val) { | ||||
|     csr[addr]= val &0xff; | ||||
|     csr[addr]= (val &0xff) | (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| @@ -1107,6 +1119,7 @@ template <typename BASE, features_e FEAT> inline void riscv_hart_m_p<BASE, FEAT> | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT> void riscv_hart_m_p<BASE, FEAT>::check_interrupt() { | ||||
|     //TODO: Implement CLIC functionality | ||||
|     //auto ideleg = csr[mideleg]; | ||||
|     // Multiple simultaneous interrupts and traps at the same privilege level are | ||||
|     // handled in the following decreasing priority order: | ||||
|   | ||||
| @@ -304,6 +304,8 @@ protected: | ||||
|         uint32_t raw; | ||||
|     }; | ||||
|     std::vector<clic_int_reg_t> clic_int_reg; | ||||
|     uint8_t clic_mprev_lvl{0}, clic_uprev_lvl{0}; | ||||
|     uint8_t clic_mact_lvl{0}, clic_uact_lvl{0}; | ||||
|  | ||||
|     std::vector<uint8_t> tcm; | ||||
|  | ||||
| @@ -486,6 +488,10 @@ riscv_hart_mu_p<BASE, FEAT>::riscv_hart_mu_p(feature_config cfg) | ||||
|         clic_int_reg.resize(cfg.clic_num_irq,  clic_int_reg_t{.raw=0}); | ||||
|         clic_cfg_reg=0x30; | ||||
|         clic_info_reg = (/*CLICINTCTLBITS*/ 4U<<21) + cfg.clic_num_irq; | ||||
|         clic_mact_lvl = clic_mprev_lvl = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         clic_uact_lvl = clic_uprev_lvl = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         csr[mintthresh] = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         csr[uintthresh] = (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|         insert_mem_range(cfg.clic_base, 0x5000UL, | ||||
|                 [this](phys_addr_t addr, unsigned length, uint8_t * const data) { return read_clic(addr.val, length, data);}, | ||||
|                 [this](phys_addr_t addr, unsigned length, uint8_t const * const data) {return write_clic(addr.val, length, data);}); | ||||
| @@ -1026,36 +1032,44 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::read_cause(unsigned addr, reg_t &val) { | ||||
|     auto res = csr[addr]; | ||||
|     if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) { | ||||
|         val = csr[addr] & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16)); | ||||
|         auto mode = (addr >> 8) & 0x3; | ||||
|         switch(mode) { | ||||
|         case 0: | ||||
|             res |= state.mstatus.UPIE<<27; | ||||
|             val |= clic_uprev_lvl<<16; | ||||
|             val |= state.mstatus.UPIE<<27; | ||||
|             break; | ||||
|         default: | ||||
|             res |= state.mstatus.MPIE<<27; | ||||
|             res |= state.mstatus.MPP<<28; | ||||
|             val |= clic_mprev_lvl<<16; | ||||
|             val |= state.mstatus.MPIE<<27; | ||||
|             val |= state.mstatus.MPP<<28; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|     val=res; | ||||
|     } else | ||||
|         val = csr[addr] & ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1)); | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT>::write_cause(unsigned addr, reg_t val) { | ||||
|     csr[addr] = val & ((1UL<<(traits<BASE>::XLEN-1))|(mcause_max_irq-1)); | ||||
|     if((FEAT & features_e::FEAT_CLIC) && (csr[mtvec]&0x3)==3) { | ||||
|         auto mask = ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1) | (0xfUL<<16)); | ||||
|         csr[addr] = (val & mask) | (csr[addr] & ~mask); | ||||
|         auto mode = (addr >> 8) & 0x3; | ||||
|         switch(mode) { | ||||
|         case 0: | ||||
|             clic_uprev_lvl = ((val>>16)&0xff) | (1<<(8-cfg. clic_int_ctl_bits)) - 1; | ||||
|             state.mstatus.UPIE=(val>>27)&0x1; | ||||
|             break; | ||||
|         default: | ||||
|             clic_mprev_lvl = ((val>>16)&0xff) | (1<<(8-cfg. clic_int_ctl_bits)) - 1; | ||||
|             state.mstatus.MPIE=(val>>27)&0x1; | ||||
|             state.mstatus.MPP=(val>>28)&0x3; | ||||
|             break; | ||||
|         } | ||||
|     } else { | ||||
|         auto mask = ((1UL<<(traits<BASE>::XLEN-1)) | (mcause_max_irq-1)); | ||||
|         csr[addr] = (val & mask) | (csr[addr] & ~mask); | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
| @@ -1146,7 +1160,7 @@ template <typename BASE, features_e FEAT> iss::status riscv_hart_mu_p<BASE, FEAT | ||||
|  | ||||
| template<typename BASE, features_e FEAT> | ||||
| iss::status riscv_hart_mu_p<BASE, FEAT>::write_intthresh(unsigned addr, reg_t val) { | ||||
|     csr[addr]= val &0xff; | ||||
|     csr[addr]= (val &0xff) | (1<<(cfg.clic_int_ctl_bits)) - 1; | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| @@ -1298,6 +1312,7 @@ template <typename BASE, features_e FEAT> inline void riscv_hart_mu_p<BASE, FEAT | ||||
| } | ||||
|  | ||||
| template <typename BASE, features_e FEAT> void riscv_hart_mu_p<BASE, FEAT>::check_interrupt() { | ||||
|     //TODO: Implement CLIC functionality | ||||
|     auto ideleg = csr[mideleg]; | ||||
|     // Multiple simultaneous interrupts and traps at the same privilege level are | ||||
|     // handled in the following decreasing priority order: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user