Compare commits
	
		
			1 Commits
		
	
	
		
			bfa8166223
			...
			fd98ad95f6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| fd98ad95f6 | 
| @@ -7,7 +7,7 @@ Core TGC_D provides RV32I, Zicsr, Zifencei, RV32M, RV32IC { | |||||||
|         XLEN=32; |         XLEN=32; | ||||||
|         // definitions for the architecture wrapper |         // definitions for the architecture wrapper | ||||||
|         //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA |         //                    XL    ZYXWVUTSRQPONMLKJIHGFEDCBA | ||||||
|         unsigned MISA_VAL = 0b01000000000000000001000100000100; |         unsigned MISA_VAL = 0b01000000000100000011000100000100; | ||||||
|         unsigned MARCHID_VAL = 0x80000004; |         unsigned MARCHID_VAL = 0x80000004; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -554,42 +554,36 @@ template <typename BASE, features_e FEAT> bool riscv_hart_mu_p<BASE, FEAT>::pmp_ | |||||||
|     constexpr auto PMP_TOR =0x1U; |     constexpr auto PMP_TOR =0x1U; | ||||||
|     constexpr auto PMP_NA4 =0x2U; |     constexpr auto PMP_NA4 =0x2U; | ||||||
|     constexpr auto PMP_NAPOT =0x3U; |     constexpr auto PMP_NAPOT =0x3U; | ||||||
|     reg_t base = 0; |     constexpr auto pmp_num_regs = 16; | ||||||
|  |     reg_t tor_base = 0; | ||||||
|     auto any_active = false; |     auto any_active = false; | ||||||
|     for (size_t i = 0; i < 16; i++) { |     auto lower_addr = addr >>2; | ||||||
|         reg_t tor = csr[pmpaddr0+i] << PMP_SHIFT; |     auto upper_addr = (addr+len-1)>>2; | ||||||
|  |     for (size_t i = 0; i < pmp_num_regs; i++) { | ||||||
|         uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4); |         uint8_t cfg = csr[pmpcfg0+(i/4)]>>(i%4); | ||||||
|  |         uint8_t cfg_next = i==(pmp_num_regs-1)? 0 : csr[pmpcfg0+((i+1)/4)]>>((i+1)%4); | ||||||
|  |         auto pmpaddr = csr[pmpaddr0+i]; | ||||||
|         if (cfg & PMP_A) { |         if (cfg & PMP_A) { | ||||||
|             any_active=true; |             any_active=true; | ||||||
|             auto pmp_a = (cfg & PMP_A) >> 3; |             auto is_tor = bit_sub<3, 2>(cfg) == PMP_TOR; | ||||||
|             auto is_tor = pmp_a == PMP_TOR; |             auto is_napot = bit_sub<4, 1>(cfg) && bit_sub<3, 2>(cfg_next)!= PMP_TOR; | ||||||
|             auto is_na4 = pmp_a == PMP_NA4; |             if(is_napot) { | ||||||
|  |                 reg_t mask = bit_sub<3, 1>(cfg)?~( pmpaddr & ~(pmpaddr + 1)): 0x3fffffff; | ||||||
|             reg_t mask = (csr[pmpaddr0+i] << 1) | (!is_na4); |                 auto mpmpaddr = pmpaddr & mask; | ||||||
|             mask = ~(mask & ~(mask + 1)) << PMP_SHIFT; |                 if((lower_addr&mask) == mpmpaddr && (upper_addr&mask)==mpmpaddr) | ||||||
|  |                     return  (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || | ||||||
|             // Check each 4-byte sector of the access |                             (type == access_type::READ && (cfg & PMP_R)) || | ||||||
|             auto any_match = false; |                             (type == access_type::WRITE && (cfg & PMP_W)) || | ||||||
|             auto all_match = true; |                             (type == access_type::FETCH && (cfg & PMP_X)); | ||||||
|             for (reg_t offset = 0; offset < len; offset += 1 << PMP_SHIFT) { |             } else if(is_tor) { | ||||||
|                 reg_t cur_addr = addr + offset; |                 if(lower_addr>=tor_base && upper_addr<=pmpaddr) | ||||||
|                 auto napot_match = ((cur_addr ^ tor) & mask) == 0; |                     return  (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || | ||||||
|                 auto tor_match = base <= cur_addr && cur_addr < tor; |                             (type == access_type::READ && (cfg & PMP_R)) || | ||||||
|                 auto match = is_tor ? tor_match : napot_match; |                             (type == access_type::WRITE && (cfg & PMP_W)) || | ||||||
|                 any_match |= match; |                             (type == access_type::FETCH && (cfg & PMP_X)); | ||||||
|                 all_match &= match; |  | ||||||
|             } |  | ||||||
|             if (any_match) { |  | ||||||
|                 // If the PMP matches only a strict subset of the access, fail it |  | ||||||
|                 if (!all_match) |  | ||||||
|                     return false; |  | ||||||
|                 return  (this->reg.PRIV == PRIV_M && !(cfg & PMP_L)) || |  | ||||||
|                         (type == access_type::READ && (cfg & PMP_R)) || |  | ||||||
|                         (type == access_type::WRITE && (cfg & PMP_W)) || |  | ||||||
|                         (type == access_type::FETCH && (cfg & PMP_X)); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         base = tor; |         tor_base = pmpaddr; | ||||||
|     } |     } | ||||||
|     return !any_active || this->reg.PRIV == PRIV_M; |     return !any_active || this->reg.PRIV == PRIV_M; | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user