Added RV32F extension, fixed RV32M bugs
This commit is contained in:
		| @@ -48,6 +48,7 @@ | ||||
| #include <util/sparse_array.h> | ||||
| #include <util/bit_field.h> | ||||
| #include <array> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace iss { | ||||
| namespace arch { | ||||
| @@ -537,6 +538,8 @@ private: | ||||
|     iss::status write_ip(unsigned addr, reg_t val); | ||||
|     iss::status read_satp(unsigned addr, reg_t &val); | ||||
|     iss::status write_satp(unsigned addr, reg_t val); | ||||
|     iss::status read_fcsr(unsigned addr, reg_t& val); | ||||
|     iss::status write_fcsr(unsigned addr, reg_t val); | ||||
| protected: | ||||
|     void check_interrupt(); | ||||
| }; | ||||
| @@ -579,6 +582,13 @@ riscv_hart_msu_vp<BASE>::riscv_hart_msu_vp() | ||||
|     csr_wr_cb[uie] = &riscv_hart_msu_vp<BASE>::write_ie; | ||||
|     csr_rd_cb[satp] = &riscv_hart_msu_vp<BASE>::read_satp; | ||||
|     csr_wr_cb[satp] = &riscv_hart_msu_vp<BASE>::write_satp; | ||||
|     csr_rd_cb[fcsr] = &riscv_hart_msu_vp<BASE>::read_fcsr; | ||||
|     csr_wr_cb[fcsr] = &riscv_hart_msu_vp<BASE>::write_fcsr; | ||||
|     csr_rd_cb[fflags] = &riscv_hart_msu_vp<BASE>::read_fcsr; | ||||
|     csr_wr_cb[fflags] = &riscv_hart_msu_vp<BASE>::write_fcsr; | ||||
|     csr_rd_cb[frm] = &riscv_hart_msu_vp<BASE>::read_fcsr; | ||||
|     csr_wr_cb[frm] = &riscv_hart_msu_vp<BASE>::write_fcsr; | ||||
|  | ||||
| } | ||||
|  | ||||
| template <typename BASE> std::pair<uint64_t,bool> riscv_hart_msu_vp<BASE>::load_file(std::string name, int type) { | ||||
| @@ -940,6 +950,39 @@ template <typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_satp(unsigne | ||||
|     update_vm_info(); | ||||
|     return iss::Ok; | ||||
| } | ||||
| template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::read_fcsr(unsigned addr, reg_t& val) { | ||||
|     switch(addr){ | ||||
|     case 1: //fflags, 4:0 | ||||
|         val = bit_sub<0, 5>(this->get_fcsr()); | ||||
|         break; | ||||
|     case 2: // frm, 7:5 | ||||
|         val = bit_sub<5, 3>(this->get_fcsr()); | ||||
|        break; | ||||
|     case 3: // fcsr | ||||
|         val=this->get_fcsr(); | ||||
|         break; | ||||
|     default: | ||||
|         return iss::Err; | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template<typename BASE> iss::status riscv_hart_msu_vp<BASE>::write_fcsr(unsigned addr, reg_t val) { | ||||
|     switch(addr){ | ||||
|     case 1: //fflags, 4:0 | ||||
|         this->set_fcsr( (this->get_fcsr() & 0xffffffe0) | (val&0x1f)); | ||||
|         break; | ||||
|     case 2: // frm, 7:5 | ||||
|         this->set_fcsr( (this->get_fcsr() & 0xffffff1f) | ((val&0x7)<<5)); | ||||
|        break; | ||||
|     case 3: // fcsr | ||||
|         this->set_fcsr(val&0xff); | ||||
|         break; | ||||
|     default: | ||||
|         return iss::Err; | ||||
|     } | ||||
|     return iss::Ok; | ||||
| } | ||||
|  | ||||
| template <typename BASE> | ||||
| iss::status riscv_hart_msu_vp<BASE>::read_mem(phys_addr_t paddr, unsigned length, uint8_t *const data) { | ||||
| @@ -1299,4 +1342,5 @@ template <typename BASE> void riscv_hart_msu_vp<BASE>::wait_until(uint64_t flags | ||||
| } | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif /* _RISCV_CORE_H_ */ | ||||
|   | ||||
							
								
								
									
										278
									
								
								riscv/incl/iss/arch/rv32gc.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										278
									
								
								riscv/incl/iss/arch/rv32gc.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,278 @@ | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
| // Copyright (C) 2017, MINRES Technologies GmbH | ||||
| // All rights reserved. | ||||
| //  | ||||
| // Redistribution and use in source and binary forms, with or without | ||||
| // modification, are permitted provided that the following conditions are met: | ||||
| //  | ||||
| // 1. Redistributions of source code must retain the above copyright notice, | ||||
| //    this list of conditions and the following disclaimer. | ||||
| //  | ||||
| // 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
| //    this list of conditions and the following disclaimer in the documentation | ||||
| //    and/or other materials provided with the distribution. | ||||
| //  | ||||
| // 3. Neither the name of the copyright holder nor the names of its contributors | ||||
| //    may be used to endorse or promote products derived from this software | ||||
| //    without specific prior written permission. | ||||
| //  | ||||
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
| // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||
| // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
| // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
| // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
| // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
| // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
| // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| // POSSIBILITY OF SUCH DAMAGE. | ||||
| //  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| #ifndef _RV32GC_H_ | ||||
| #define _RV32GC_H_ | ||||
|  | ||||
| #include <iss/arch_if.h> | ||||
| #include <iss/vm_if.h> | ||||
| #include <iss/arch/traits.h> | ||||
| #include <array> | ||||
|  | ||||
| namespace iss { | ||||
| namespace arch { | ||||
|  | ||||
| struct rv32gc; | ||||
|  | ||||
| template<> | ||||
| struct traits<rv32gc> { | ||||
|  | ||||
| 	constexpr static char const* const core_type = "RV32GC"; | ||||
|      | ||||
|     enum constants {XLEN=32, FLEN=32, XLEN2=64, XLEN_BIT_MASK=31, PCLEN=32, fence=0, fencei=1, fencevmal=2, fencevmau=3, MISA_VAL=1075056897, PGSIZE=4096, PGMASK=4095, FFLAG_MASK=31}; | ||||
|  | ||||
|     enum reg_e { | ||||
|         X0, | ||||
|         X1, | ||||
|         X2, | ||||
|         X3, | ||||
|         X4, | ||||
|         X5, | ||||
|         X6, | ||||
|         X7, | ||||
|         X8, | ||||
|         X9, | ||||
|         X10, | ||||
|         X11, | ||||
|         X12, | ||||
|         X13, | ||||
|         X14, | ||||
|         X15, | ||||
|         X16, | ||||
|         X17, | ||||
|         X18, | ||||
|         X19, | ||||
|         X20, | ||||
|         X21, | ||||
|         X22, | ||||
|         X23, | ||||
|         X24, | ||||
|         X25, | ||||
|         X26, | ||||
|         X27, | ||||
|         X28, | ||||
|         X29, | ||||
|         X30, | ||||
|         X31, | ||||
|         PC, | ||||
|         F0, | ||||
|         F1, | ||||
|         F2, | ||||
|         F3, | ||||
|         F4, | ||||
|         F5, | ||||
|         F6, | ||||
|         F7, | ||||
|         F8, | ||||
|         F9, | ||||
|         F10, | ||||
|         F11, | ||||
|         F12, | ||||
|         F13, | ||||
|         F14, | ||||
|         F15, | ||||
|         F16, | ||||
|         F17, | ||||
|         F18, | ||||
|         F19, | ||||
|         F20, | ||||
|         F21, | ||||
|         F22, | ||||
|         F23, | ||||
|         F24, | ||||
|         F25, | ||||
|         F26, | ||||
|         F27, | ||||
|         F28, | ||||
|         F29, | ||||
|         F30, | ||||
|         F31, | ||||
|         FCSR, | ||||
|         NUM_REGS, | ||||
|         NEXT_PC=NUM_REGS, | ||||
|         TRAP_STATE, | ||||
|         PENDING_TRAP, | ||||
|         MACHINE_STATE, | ||||
|         ICOUNT | ||||
|     }; | ||||
|  | ||||
|     using reg_t = uint32_t; | ||||
|  | ||||
|     using addr_t = uint32_t; | ||||
|  | ||||
|     using code_word_t = uint32_t; //TODO: check removal | ||||
|  | ||||
|     using virt_addr_t = iss::typed_addr_t<iss::address_type::VIRTUAL>; | ||||
|  | ||||
|     using phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>; | ||||
|  | ||||
|     constexpr static unsigned reg_bit_width(unsigned r) { | ||||
|         constexpr std::array<const uint32_t, 71> RV32GC_reg_size{{32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,64}}; | ||||
|         return RV32GC_reg_size[r]; | ||||
|     } | ||||
|  | ||||
|     constexpr static unsigned reg_byte_offset(unsigned r) { | ||||
|     	constexpr std::array<const uint32_t, 72> RV32GC_reg_byte_offset{{0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,288}}; | ||||
|         return RV32GC_reg_byte_offset[r]; | ||||
|     } | ||||
|  | ||||
|     static const uint64_t addr_mask = (reg_t(1) << (XLEN - 1)) | ((reg_t(1) << (XLEN - 1)) - 1); | ||||
|  | ||||
|     enum sreg_flag_e {FLAGS}; | ||||
|  | ||||
|     enum mem_type_e {MEM, CSR, FENCE, RES}; | ||||
|  | ||||
| 	constexpr static bool has_fp_regs = true; | ||||
|      | ||||
| }; | ||||
|  | ||||
| struct rv32gc: public arch_if { | ||||
|  | ||||
|     using virt_addr_t = typename traits<rv32gc>::virt_addr_t; | ||||
|     using phys_addr_t = typename traits<rv32gc>::phys_addr_t; | ||||
|     using reg_t =  typename traits<rv32gc>::reg_t; | ||||
|     using addr_t = typename traits<rv32gc>::addr_t; | ||||
|  | ||||
|     rv32gc(); | ||||
|     ~rv32gc(); | ||||
|  | ||||
|     void reset(uint64_t address=0) override; | ||||
|  | ||||
|     uint8_t* get_regs_base_ptr() override; | ||||
|     /// deprecated | ||||
|     void get_reg(short idx, std::vector<uint8_t>& value) override {} | ||||
|     void set_reg(short idx, const std::vector<uint8_t>& value) override {} | ||||
|     /// deprecated | ||||
|     bool get_flag(int flag) override {return false;} | ||||
|     void set_flag(int, bool value) override {}; | ||||
|     /// deprecated | ||||
|     void update_flags(operations op, uint64_t opr1, uint64_t opr2) override {}; | ||||
|  | ||||
|     uint64_t get_icount() { return reg.icount;} | ||||
|  | ||||
|     inline phys_addr_t v2p(const iss::addr_t& addr){ | ||||
|         if(addr.space != traits<rv32gc>::MEM || | ||||
|                 addr.type == iss::address_type::PHYSICAL || | ||||
|                 addr_mode[static_cast<uint16_t>(addr.access)&0x3]==address_type::PHYSICAL){ | ||||
|             return phys_addr_t(addr.access, addr.space, addr.val&traits<rv32gc>::addr_mask); | ||||
|         } else | ||||
|             return virt2phys(addr); | ||||
|     } | ||||
|  | ||||
|     virtual phys_addr_t virt2phys(const iss::addr_t& addr); | ||||
|  | ||||
|     virtual iss::sync_type needed_sync() const { return iss::NO_SYNC; } | ||||
|  | ||||
| protected: | ||||
|     struct RV32GC_regs { | ||||
|         uint32_t X0 = 0; | ||||
|         uint32_t X1 = 0; | ||||
|         uint32_t X2 = 0; | ||||
|         uint32_t X3 = 0; | ||||
|         uint32_t X4 = 0; | ||||
|         uint32_t X5 = 0; | ||||
|         uint32_t X6 = 0; | ||||
|         uint32_t X7 = 0; | ||||
|         uint32_t X8 = 0; | ||||
|         uint32_t X9 = 0; | ||||
|         uint32_t X10 = 0; | ||||
|         uint32_t X11 = 0; | ||||
|         uint32_t X12 = 0; | ||||
|         uint32_t X13 = 0; | ||||
|         uint32_t X14 = 0; | ||||
|         uint32_t X15 = 0; | ||||
|         uint32_t X16 = 0; | ||||
|         uint32_t X17 = 0; | ||||
|         uint32_t X18 = 0; | ||||
|         uint32_t X19 = 0; | ||||
|         uint32_t X20 = 0; | ||||
|         uint32_t X21 = 0; | ||||
|         uint32_t X22 = 0; | ||||
|         uint32_t X23 = 0; | ||||
|         uint32_t X24 = 0; | ||||
|         uint32_t X25 = 0; | ||||
|         uint32_t X26 = 0; | ||||
|         uint32_t X27 = 0; | ||||
|         uint32_t X28 = 0; | ||||
|         uint32_t X29 = 0; | ||||
|         uint32_t X30 = 0; | ||||
|         uint32_t X31 = 0; | ||||
|         uint32_t PC = 0; | ||||
|         uint32_t F0 = 0; | ||||
|         uint32_t F1 = 0; | ||||
|         uint32_t F2 = 0; | ||||
|         uint32_t F3 = 0; | ||||
|         uint32_t F4 = 0; | ||||
|         uint32_t F5 = 0; | ||||
|         uint32_t F6 = 0; | ||||
|         uint32_t F7 = 0; | ||||
|         uint32_t F8 = 0; | ||||
|         uint32_t F9 = 0; | ||||
|         uint32_t F10 = 0; | ||||
|         uint32_t F11 = 0; | ||||
|         uint32_t F12 = 0; | ||||
|         uint32_t F13 = 0; | ||||
|         uint32_t F14 = 0; | ||||
|         uint32_t F15 = 0; | ||||
|         uint32_t F16 = 0; | ||||
|         uint32_t F17 = 0; | ||||
|         uint32_t F18 = 0; | ||||
|         uint32_t F19 = 0; | ||||
|         uint32_t F20 = 0; | ||||
|         uint32_t F21 = 0; | ||||
|         uint32_t F22 = 0; | ||||
|         uint32_t F23 = 0; | ||||
|         uint32_t F24 = 0; | ||||
|         uint32_t F25 = 0; | ||||
|         uint32_t F26 = 0; | ||||
|         uint32_t F27 = 0; | ||||
|         uint32_t F28 = 0; | ||||
|         uint32_t F29 = 0; | ||||
|         uint32_t F30 = 0; | ||||
|         uint32_t F31 = 0; | ||||
|         uint32_t FCSR = 0; | ||||
|         uint32_t NEXT_PC = 0; | ||||
|         uint32_t trap_state = 0, pending_trap = 0, machine_state = 0; | ||||
|         uint64_t icount = 0; | ||||
|     } reg; | ||||
|  | ||||
|     std::array<address_type, 4> addr_mode; | ||||
|      | ||||
|  | ||||
| 	uint32_t get_fcsr(){return reg.FCSR;} | ||||
| 	void set_fcsr(uint32_t val){reg.FCSR = val;}		 | ||||
|  | ||||
| }; | ||||
|  | ||||
| } | ||||
| }             | ||||
| #endif /* _RV32GC_H_ */ | ||||
| @@ -118,6 +118,8 @@ struct traits<rv32imac> { | ||||
|  | ||||
|     enum mem_type_e {MEM, CSR, FENCE, RES}; | ||||
|  | ||||
| 	constexpr static bool has_fp_regs = false; | ||||
|      | ||||
| }; | ||||
|  | ||||
| struct rv32imac: public arch_if { | ||||
| @@ -198,6 +200,10 @@ protected: | ||||
|     } reg; | ||||
|  | ||||
|     std::array<address_type, 4> addr_mode; | ||||
|      | ||||
|  | ||||
| 	uint32_t get_fcsr(){return 0;} | ||||
| 	void set_fcsr(uint32_t val){} | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -118,6 +118,8 @@ struct traits<rv64ia> { | ||||
|  | ||||
|     enum mem_type_e {MEM, CSR, FENCE, RES}; | ||||
|  | ||||
| 	constexpr static bool has_fp_regs = false; | ||||
|      | ||||
| }; | ||||
|  | ||||
| struct rv64ia: public arch_if { | ||||
| @@ -198,6 +200,10 @@ protected: | ||||
|     } reg; | ||||
|  | ||||
|     std::array<address_type, 4> addr_mode; | ||||
|      | ||||
|  | ||||
| 	uint32_t get_fcsr(){return 0;} | ||||
| 	void set_fcsr(uint32_t val){} | ||||
|  | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user