target/riscv: Simplify counter predicate function
All the hpmcounters and the fixed counters (CY, IR, TM) can be represented as a unified counter. Thus, the predicate function doesn't need handle each case separately. Simplify the predicate function so that we just handle things differently between RV32/RV64 and S/HS mode. Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Atish Patra <atishp@rivosinc.com> Message-Id: <20220824221701.41932-3-atishp@rivosinc.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
		
							parent
							
								
									1466448345
								
							
						
					
					
						commit
						ade445ef85
					
				| @ -75,6 +75,7 @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||||
|     CPUState *cs = env_cpu(env); | ||||
|     RISCVCPU *cpu = RISCV_CPU(cs); | ||||
|     int ctr_index; | ||||
|     target_ulong ctr_mask; | ||||
|     int base_csrno = CSR_CYCLE; | ||||
|     bool rv32 = riscv_cpu_mxl(env) == MXL_RV32 ? true : false; | ||||
| 
 | ||||
| @ -83,122 +84,29 @@ static RISCVException ctr(CPURISCVState *env, int csrno) | ||||
|         base_csrno += 0x80; | ||||
|     } | ||||
|     ctr_index = csrno - base_csrno; | ||||
|     ctr_mask = BIT(ctr_index); | ||||
| 
 | ||||
|     if ((csrno >= CSR_CYCLE && csrno <= CSR_INSTRET) || | ||||
|         (csrno >= CSR_CYCLEH && csrno <= CSR_INSTRETH)) { | ||||
|         goto skip_ext_pmu_check; | ||||
|     } | ||||
| 
 | ||||
|     if ((!cpu->cfg.pmu_num || !(cpu->pmu_avail_ctrs & BIT(ctr_index)))) { | ||||
|     if (!(cpu->pmu_avail_ctrs & ctr_mask)) { | ||||
|         /* No counter is enabled in PMU or the counter is out of range */ | ||||
|         return RISCV_EXCP_ILLEGAL_INST; | ||||
|     } | ||||
| 
 | ||||
| skip_ext_pmu_check: | ||||
| 
 | ||||
|     if (env->priv == PRV_S) { | ||||
|         switch (csrno) { | ||||
|         case CSR_CYCLE: | ||||
|             if (!get_field(env->mcounteren, COUNTEREN_CY)) { | ||||
|                 return RISCV_EXCP_ILLEGAL_INST; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_TIME: | ||||
|             if (!get_field(env->mcounteren, COUNTEREN_TM)) { | ||||
|                 return RISCV_EXCP_ILLEGAL_INST; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_INSTRET: | ||||
|             if (!get_field(env->mcounteren, COUNTEREN_IR)) { | ||||
|                 return RISCV_EXCP_ILLEGAL_INST; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||||
|             if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||||
|                 return RISCV_EXCP_ILLEGAL_INST; | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         if (rv32) { | ||||
|             switch (csrno) { | ||||
|             case CSR_CYCLEH: | ||||
|                 if (!get_field(env->mcounteren, COUNTEREN_CY)) { | ||||
|                     return RISCV_EXCP_ILLEGAL_INST; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_TIMEH: | ||||
|                 if (!get_field(env->mcounteren, COUNTEREN_TM)) { | ||||
|                     return RISCV_EXCP_ILLEGAL_INST; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_INSTRETH: | ||||
|                 if (!get_field(env->mcounteren, COUNTEREN_IR)) { | ||||
|                     return RISCV_EXCP_ILLEGAL_INST; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||||
|                 if (!get_field(env->mcounteren, 1 << ctr_index)) { | ||||
|                     return RISCV_EXCP_ILLEGAL_INST; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|     if (((env->priv == PRV_S) && (!get_field(env->mcounteren, ctr_mask))) || | ||||
|         ((env->priv == PRV_U) && (!get_field(env->scounteren, ctr_mask)))) { | ||||
|         return RISCV_EXCP_ILLEGAL_INST; | ||||
|     } | ||||
| 
 | ||||
|     if (riscv_cpu_virt_enabled(env)) { | ||||
|         switch (csrno) { | ||||
|         case CSR_CYCLE: | ||||
|             if (!get_field(env->hcounteren, COUNTEREN_CY) && | ||||
|                 get_field(env->mcounteren, COUNTEREN_CY)) { | ||||
|                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_TIME: | ||||
|             if (!get_field(env->hcounteren, COUNTEREN_TM) && | ||||
|                 get_field(env->mcounteren, COUNTEREN_TM)) { | ||||
|                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_INSTRET: | ||||
|             if (!get_field(env->hcounteren, COUNTEREN_IR) && | ||||
|                 get_field(env->mcounteren, COUNTEREN_IR)) { | ||||
|                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|             } | ||||
|             break; | ||||
|         case CSR_HPMCOUNTER3...CSR_HPMCOUNTER31: | ||||
|             if (!get_field(env->hcounteren, 1 << ctr_index) && | ||||
|                  get_field(env->mcounteren, 1 << ctr_index)) { | ||||
|                 return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
|         if (rv32) { | ||||
|             switch (csrno) { | ||||
|             case CSR_CYCLEH: | ||||
|                 if (!get_field(env->hcounteren, COUNTEREN_CY) && | ||||
|                     get_field(env->mcounteren, COUNTEREN_CY)) { | ||||
|                     return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_TIMEH: | ||||
|                 if (!get_field(env->hcounteren, COUNTEREN_TM) && | ||||
|                     get_field(env->mcounteren, COUNTEREN_TM)) { | ||||
|                     return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_INSTRETH: | ||||
|                 if (!get_field(env->hcounteren, COUNTEREN_IR) && | ||||
|                     get_field(env->mcounteren, COUNTEREN_IR)) { | ||||
|                     return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|                 } | ||||
|                 break; | ||||
|             case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H: | ||||
|                 if (!get_field(env->hcounteren, 1 << ctr_index) && | ||||
|                      get_field(env->mcounteren, 1 << ctr_index)) { | ||||
|                     return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|                 } | ||||
|                 break; | ||||
|             } | ||||
|         if (!get_field(env->hcounteren, ctr_mask) && | ||||
|             get_field(env->mcounteren, ctr_mask)) { | ||||
|             return RISCV_EXCP_VIRT_INSTRUCTION_FAULT; | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Atish Patra
						Atish Patra