예제 #1
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.GPR:
            self.error("Unexpected StateElement type %s" %
                       aStateElem.getStateElementType())

        # This implementation loads the memory block pointer GPR out of order,
        # so that it can be used to process all subsequent StateElements.
        if not self._mMemBlockAddrLoaded:
            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(self.mMemBlockPtrIndex,
                                self.mMemBlockStartAddr)
            self._mMemBlockAddrLoaded = True

        gpr_index = aStateElem.getRegisterIndex()
        if gpr_index in self.mGprIndices:
            if self.getGlobalState("AppRegisterWidth") == 32:
                instr = "LW##RISCV"
            else:
                instr = "LD##RISCV"
            self.genInstruction(
                instr,
                {
                    "rd": gpr_index,
                    "rs1": self.mMemBlockPtrIndex,
                    "simm12": (gpr_index * 8),
                    "NoRestriction": 1,
                },
            )
        elif gpr_index != self.mMemBlockPtrIndex:
            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(gpr_index, aStateElem.getValues()[0])

        return True
예제 #2
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.GPR:
            self.error('Unexpected StateElement type %s' %
                       aStateElem.getStateElementType())

        # This implementation loads the memory block pointer GPR out of order, so that it can be
        # used to process all subsequent StateElements.
        if not self._mMemBlockAddrLoaded:
            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(self.mMemBlockPtrIndex,
                                self.mMemBlockStartAddr)
            self._mMemBlockAddrLoaded = True

        gpr_index = aStateElem.getRegisterIndex()
        if gpr_index in self.mGprIndices:
            self.genInstruction(
                'LD##RISCV', {
                    'rd': gpr_index,
                    'rs1': self.mMemBlockPtrIndex,
                    'simm12': (gpr_index * 8),
                    'NoRestriction': 1
                })
        elif gpr_index != self.mMemBlockPtrIndex:
            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(gpr_index, aStateElem.getValues()[0])

        return True
예제 #3
0
    def _testExclusiveStoreLoad(self, aTargetAddr):
        src_reg_index = self.getRandomGPR(exclude="0")
        self.reserveRegister("x%d" % src_reg_index)

        if self.getGlobalState("AppRegisterWidth") == 64:
            load_gpr64_seq = LoadGPR64(self.genThread)
            test_val = RandomUtils.random64()
            load_gpr64_seq.load(src_reg_index, test_val)
            instr = "SD##RISCV"
        else:
            load_gpr32_seq = LoadGPR64(self.genThread)
            test_val = RandomUtils.random32()
            load_gpr32_seq.load(src_reg_index, test_val)
            instr = "SW##RISCV"
        self.genInstruction(
            instr, {"rs2": src_reg_index, "LSTarget": aTargetAddr}
        )

        self.unreserveRegister("x%d" % src_reg_index)

        if self.getGlobalState("AppRegisterWidth") == 32:
            instr_map = RV32_G_map - BranchJump_map
        else:
            instr_map = RV_G_map - BranchJump_map

        for _ in range(RandomUtils.random32(5, 10)):
            instr = instr_map.pick(self.genThread)
            self.genInstruction(instr)

        if self.getGlobalState("AppRegisterWidth") == 32:
            instr = "LW##RISCV"
        else:
            instr = "LD##RISCV"
        instr_id = self.genInstruction(instr, {"LSTarget": aTargetAddr})

        instr_record = self.queryInstructionRecord(instr_id)
        dest_reg_index = instr_record["Dests"]["rd"]
        if dest_reg_index != 0:
            dest_reg_name = "x%d" % dest_reg_index
            (dest_reg_val, valid) = self.readRegister(dest_reg_name)
            self._assertValidRegisterValue(dest_reg_name, valid)

            gen_mode = self.getPEstate("GenMode")
            no_iss = gen_mode & 0x1
            if (no_iss != 1) and (dest_reg_val != test_val):
                self.error(
                    "Unexpected destination register value; Expected=0x%x, "
                    "Actual=0x%x" % (test_val, dest_reg_val)
                )
예제 #4
0
    def processStateElements(self, aStateElems):
        if aStateElems[0].getStateElementType() != EStateElementType.VmContext:
            self.error(
                'This StateTransitionHandler can only process StateElements of type %s'
                % EStateElementType.VmContext)

        (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

        # Consolidate StateElements by register, so we only need to set each register once
        reg_fields = self._groupStateElementFieldsByRegister(aStateElems)

        load_gpr64_seq = LoadGPR64(self.genThread)
        for (reg_name, (reg_field_names,
                        reg_field_values)) in reg_fields.items():
            # Ensure the register is initialized before attempting to read it
            self.randomInitializeRegister(reg_name)
            (reg_val, _) = self.readRegister(reg_name)

            for (i, reg_field_name) in enumerate(reg_field_names):
                reg_val = combineRegisterValueWithFieldValue(
                    self, reg_name, reg_val, reg_field_name,
                    reg_field_values[i])

            load_gpr64_seq.load(reg_val_gpr_index, reg_val)
            self.genInstruction(
                'CSRRW#register#RISCV', {
                    'rd': 0,
                    'rs1': reg_val_gpr_index,
                    'csr': self.getRegisterIndex(reg_name)
                })
            self.updateVm()

        self._mHelperGprSet.releaseHelperGprs()
예제 #5
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType(
        ) != EStateElementType.SystemRegister:
            return False

        (reg_val_gpr_index,
         scratch_gpr_index) = self._mHelperGprSet.acquireHelperGprs(
             2, aValidate=False)

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0])
        if aStateElem.getName() == 'vtype':
            self._processVtypeStateElement(reg_val_gpr_index)
        elif aStateElem.getName() == 'vl':
            self._processVlStateElement(aStateElem, reg_val_gpr_index,
                                        scratch_gpr_index)
        else:
            self.genInstruction(
                'CSRRW#register#RISCV', {
                    'rd': 0,
                    'rs1': reg_val_gpr_index,
                    'csr': aStateElem.getRegisterIndex()
                })

        self._mHelperGprSet.releaseHelperGprs()

        return True
예제 #6
0
    def processStateElements(self, aStateElems):
        if aStateElems[0].getStateElementType() != EStateElementType.Memory:
            self.error(
                'This StateTransitionHandler can only process StateElements of type %s'
                % EStateElementType.Memory)

        (base_reg_index,
         mem_val_reg_index) = self._mHelperGprSet.acquireHelperGprs(2)

        load_gpr64_seq = LoadGPR64(self.genThread)
        offset_limit = 2**11
        base_addr = -offset_limit
        for state_elem in aStateElems:
            load_gpr64_seq.load(mem_val_reg_index, state_elem.getValues()[0])

            # This is a minor optimization for the likely case in which the starting addresses of
            # consecutive State Elements are close together. Instead of loading the base register
            # from scratch, we can offset from its current value.
            offset = state_elem.getStartAddress() - base_addr
            if (offset < -offset_limit) or (offset >= offset_limit):
                base_addr = state_elem.getStartAddress()
                load_gpr64_seq.load(base_reg_index, base_addr)
                offset = 0

            self.genInstruction(
                'SD##RISCV', {
                    'rs1': base_reg_index,
                    'rs2': mem_val_reg_index,
                    'simm12': offset,
                    'NoRestriction': 1
                })

        self._mHelperGprSet.releaseHelperGprs()
예제 #7
0
def _verify_memory_state(aSequence, aExpectedMemStateData):
    load_gpr64_seq = LoadGPR64(aSequence.genThread)
    (base_reg_index, mem_val_reg_index) = aSequence.getRandomGPRs(2,
                                                                  exclude="0")
    for (mem_start_addr, expected_mem_val) in aExpectedMemStateData:
        load_gpr64_seq.load(base_reg_index, mem_start_addr)
        if aSequence.getGlobalState("AppRegisterWidth") == 32:
            aSequence.genInstruction(
                "LW##RISCV",
                {
                    "rd": mem_val_reg_index,
                    "rs1": base_reg_index,
                    "simm12": 0,
                    "NoRestriction": 1,
                },
            )
        else:
            aSequence.genInstruction(
                "LD##RISCV",
                {
                    "rd": mem_val_reg_index,
                    "rs1": base_reg_index,
                    "simm12": 0,
                    "NoRestriction": 1,
                },
            )
        mem_val_reg_name = "x%d" % mem_val_reg_index
        (mem_val, valid) = aSequence.readRegister(mem_val_reg_name)
        assert_valid_register_value(aSequence, mem_val_reg_name, valid)
        if mem_val != expected_mem_val:
            aSequence.error(
                "Value at address 0x%x does not match the specified State. "
                "Expected=0x%x, Actual=0x%x" %
                (mem_start_addr, expected_mem_val, mem_val))
예제 #8
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.PC:
            return False

        target_addr = aStateElem.getValues()[0]

        # Try using a PC-relative branch first to limit the number of generated instructions; fall
        # back to a register branch if that fails.
        (branch_offset, is_valid,
         num_hw) = self.getBranchOffset(self.getPEstate('PC'), target_addr, 20,
                                        1)
        if is_valid:
            self.genInstruction('JAL##RISCV', {
                'rd': 0,
                'simm20': branch_offset,
                'NoRestriction': 1
            })
        else:
            (branch_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

            load_gpr = LoadGPR64(self.genThread)
            load_gpr.load(branch_gpr_index, target_addr)
            self.genInstruction('JALR##RISCV', {
                'rd': 0,
                'rs1': branch_gpr_index,
                'simm12': 0,
                'NoRestriction': 1
            })

            self._mHelperGprSet.releaseHelperGprs()

        return True
예제 #9
0
    def generate(self, **kargs):
        # Disable floating point, so the StateTransition can enable it
        sys_reg_name = "misa"
        (sys_reg_val, valid) = self.readRegister(sys_reg_name)
        state_transition_test_utils.assert_valid_register_value(
            self, sys_reg_name, valid)

        load_gpr64_seq = LoadGPR64(self.genThread)
        rand_gpr_index = self.getRandomGPR(exclude="0")
        load_gpr64_seq.load(rand_gpr_index, 0x0000028)
        self.genInstruction(
            "CSRRC#register#RISCV",
            {
                "rd": 0,
                "rs1": rand_gpr_index,
                "csr": self.getRegisterIndex(sys_reg_name),
            },
        )

        state = self._createState()
        StateTransition.transitionToState(state,
                                          EStateTransitionOrderMode.ByPriority)

        state_transition_test_utils.verify_state(self,
                                                 self._mExpectedStateData)
예제 #10
0
    def processStateElements(self, aStateElems):
        if aStateElems[0].getStateElementType() != EStateElementType.Memory:
            self.error("This StateTransitionHandler can only process "
                       "StateElements of type %s" % EStateElementType.Memory)

        (
            base_reg_index,
            mem_val_reg_index,
        ) = self._mHelperGprSet.acquireHelperGprs(2)

        load_gpr64_seq = LoadGPR64(self.genThread)
        offset_limit = 2**11
        base_addr = -offset_limit
        for state_elem in aStateElems:
            load_gpr64_seq.load(mem_val_reg_index, state_elem.getValues()[0])

            # This is a minor optimization for the likely case in which the
            # starting addresses of consecutive State Elements are close
            # together. Instead of loading the base register from scratch, we
            # can offset from its current value.
            offset = state_elem.getStartAddress() - base_addr
            if (offset < -offset_limit) or (offset >= offset_limit):
                base_addr = state_elem.getStartAddress()
                load_gpr64_seq.load(base_reg_index, base_addr)
                offset = 0

            self._genStoreInstruction(base_reg_index, mem_val_reg_index,
                                      offset)

        self._mHelperGprSet.releaseHelperGprs()
예제 #11
0
    def _switchPrivilegeLevel(self, aParams):
        except_request_results = self.exceptionRequest('SystemCall', aParams)

        ret_code = except_request_results['RetCode']
        if ret_code != 0:
            return ret_code

        self._assignRegisters(except_request_results['DataBlockAddrRegIndex'],
                              except_request_results['ActionCodeRegIndex'])

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(self._mDataBlockAddrRegIndex,
                            except_request_results['DataBlockAddr'])

        self._genPrivilegeLevelSwitchInstructions(
            except_request_results['InstrSeqCode'],
            except_request_results['PrivilegeLevel'],
            except_request_results['TargetAddr'],
            except_request_results['IntermediateRetAddr'])

        self._unassignRegisters()

        self.genSequence('UpdatePeState',
                         {'RecordId': except_request_results['RecordId']})
        self.updateVm()

        return ret_code
예제 #12
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType(
        ) != EStateElementType.FloatingPointRegister:
            return False

        (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0])

        (mem_block_ptr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)
        self.initializeMemoryBlock(mem_block_ptr_index, [aStateElem])
        fp_load_instr = "FLW##RISCV" if aStateElem.getName().startswith(
            "S") else "FLD##RISCV"
        self.genInstruction(
            fp_load_instr,
            {
                "rd": aStateElem.getRegisterIndex(),
                "rs1": mem_block_ptr_index,
                "simm12": 0,
                "NoRestriction": 1,
            },
        )

        self._mHelperGprSet.releaseHelperGprs()

        return True
예제 #13
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.VmContext:
            return False

        (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

        # Ensure the register is initialized before attempting to read it
        self.randomInitializeRegister(aStateElem.getRegisterName())
        (reg_val, _) = self.readRegister(aStateElem.getRegisterName())

        reg_val = combine_register_value_with_field_value(
            self,
            aStateElem.getRegisterName(),
            reg_val,
            aStateElem.getRegisterFieldName(),
            aStateElem.getValues()[0],
        )

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(reg_val_gpr_index, reg_val)
        self.genInstruction(
            "CSRRW#register#RISCV",
            {
                "rd": 0,
                "rs1": reg_val_gpr_index,
                "csr": self.getRegisterIndex(aStateElem.getRegisterName()),
            },
        )
        self.updateVm()

        self._mHelperGprSet.releaseHelperGprs()

        return True
예제 #14
0
    def processStateElements(self, aStateElems):
        if aStateElems[0].getStateElementType(
        ) != EStateElementType.SystemRegister:
            self.error("This StateTransitionHandler can only process "
                       "StateElements of type %s" %
                       EStateElementType.SystemRegister)

        (
            mem_block_ptr_index,
            reg_val_gpr_index,
            scratch_gpr_index,
        ) = self._mHelperGprSet.acquireHelperGprs(3)
        self.initializeMemoryBlock(mem_block_ptr_index, aStateElems)
        (mem_block_ptr_val, _) = self.readRegister("x%d" % mem_block_ptr_index)

        load_gpr64_seq = LoadGPR64(self.genThread)
        offset_limit = 2**11
        offset = 0
        for state_elem in aStateElems:
            # This is a minor optimization that offsets from the memory block
            # pointer when possible rather than adjusting its value
            if offset >= offset_limit:
                mem_block_ptr_val += offset
                load_gpr64_seq.load(mem_block_ptr_index, mem_block_ptr_val)
                offset = 0

            self._genLoadInstruction(reg_val_gpr_index, mem_block_ptr_index,
                                     offset)
            self._processSystemRegisterStateElement(state_elem,
                                                    reg_val_gpr_index,
                                                    scratch_gpr_index)

            offset += 8

        self._mHelperGprSet.releaseHelperGprs()
예제 #15
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.VmContext:
            return False

        (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

        # Ensure the register is initialized before attempting to read it
        self.randomInitializeRegister(aStateElem.getRegisterName())
        (reg_val, _) = self.readRegister(aStateElem.getRegisterName())

        reg_val = combineRegisterValueWithFieldValue(
            self, aStateElem.getRegisterName(), reg_val,
            aStateElem.getRegisterFieldName(),
            aStateElem.getValues()[0])

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(reg_val_gpr_index, reg_val)
        self.genInstruction(
            'CSRRW#register#RISCV', {
                'rd': 0,
                'rs1': reg_val_gpr_index,
                'csr': self.getRegisterIndex(aStateElem.getRegisterName())
            })
        self.updateVm()

        self._mHelperGprSet.releaseHelperGprs()

        return True
예제 #16
0
    def _switchPrivilegeLevel(self, aParams):
        except_request_results = self.exceptionRequest("SystemCall", aParams)

        ret_code = except_request_results["RetCode"]
        if ret_code != 0:
            return ret_code

        self._assignRegisters(
            except_request_results["DataBlockAddrRegIndex"],
            except_request_results["ActionCodeRegIndex"],
        )

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(
            self._mDataBlockAddrRegIndex,
            except_request_results["DataBlockAddr"],
        )

        self._genPrivilegeLevelSwitchInstructions(
            except_request_results["InstrSeqCode"],
            except_request_results["PrivilegeLevel"],
            except_request_results["TargetAddr"],
            except_request_results["IntermediateRetAddr"],
        )

        self._unassignRegisters()

        self.genSequence("UpdatePeState", {"RecordId": except_request_results["RecordId"]})
        self.updateVm()

        return ret_code
예제 #17
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType() != EStateElementType.GPR:
            return False

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(aStateElem.getRegisterIndex(),
                            aStateElem.getValues()[0])
        return True
예제 #18
0
    def releaseHelperGprs(self):
        load_gpr64_seq = LoadGPR64(self._mStateTransHandler.genThread)
        for (i, non_arbitrary_gpr_index) in enumerate(
                self._mNonArbitraryGprIndices):
            load_gpr64_seq.load(non_arbitrary_gpr_index,
                                self._mNonArbitraryGprOrigValues[i])

        self._mNonArbitraryGprOrigValues = []
        self._mNonArbitraryGprIndices = []
        self._mArbitraryGprIndices = []
예제 #19
0
    def _generateInstructionParameters(self):
        instr_params = {}

        load_gpr64_seq = LoadGPR64(self.genThread)
        (avl_reg_index, vtype_reg_index) = self.getRandomGPRs(2, exclude='0')
        load_gpr64_seq.load(avl_reg_index, self.mAvl)
        instr_params['rs1'] = avl_reg_index
        load_gpr64_seq.load(vtype_reg_index, self.mVtype)
        instr_params['rs2'] = vtype_reg_index

        return instr_params
예제 #20
0
    def _generateInstructionParameters(self):
        instr_params = {}

        load_gpr64_seq = LoadGPR64(self.genThread)
        avl_reg_index = self.getRandomGPR(exclude='0')
        load_gpr64_seq.load(avl_reg_index, self.mAvl)
        instr_params['rs1'] = avl_reg_index
        avl_reg_index = self.getRandomGPR(exclude='0')
        instr_params['zimm10'] = self.mVtype

        return instr_params
예제 #21
0
    def _initializeStackPointer(self, aLoadStackPointer):
        self.initializeRegister(self._mSpName, self._mStackTop)

        if aLoadStackPointer:
            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(self._mSpIndex, self._mStackTop)

        # Reserve the stack register to prevent its corruption by randomly-generated instructions
        self.reserveRegister(self._mSpName, 'ReadWrite')

        Log.debug('DEBUG [ExceptionHandlerStackRISCV::_initializeStackPointer] STACK REG: %s (index: %d), value: 0x%x\n' % (self._mSpName, self._mSpIndex, self._mStackTop))
def _verifyMemoryState(aSequence, aExpectedMemStateData):
    load_gpr64_seq = LoadGPR64(aSequence.genThread)
    (base_reg_index, mem_val_reg_index) = aSequence.getRandomGPRs(2, exclude='0')
    for (mem_start_addr, expected_mem_val) in aExpectedMemStateData:
        load_gpr64_seq.load(base_reg_index, mem_start_addr)
        aSequence.genInstruction('LD##RISCV', {'rd': mem_val_reg_index, 'rs1': base_reg_index, 'simm12': 0, 'NoRestriction': 1})

        mem_val_reg_name = 'x%d' % mem_val_reg_index
        (mem_val, valid) = aSequence.readRegister(mem_val_reg_name)
        assertValidRegisterValue(aSequence, mem_val_reg_name, valid)
        if mem_val != expected_mem_val:
            aSequence.error('Value at address 0x%x does not match the specified State. Expected=0x%x, Actual=0x%x' % (mem_start_addr, expected_mem_val, mem_val))
예제 #23
0
    def _configureExceptionDelegation(self, aExceptCodes):
        # Spike appears to only allow exception codes 0, 3, 8, 12, 13 and 15 to be delegated. The
        # logic below harmlessly ignores this constraint for simplicity and in case Spike's
        # implementation changes in the future. There does not appear to be any provisions in the
        # RISCV Privileged Architecture Specification that mandate such a restrictive delegation
        # scheme.
        medeleg_val = 0
        for except_code in aExceptCodes:
            medeleg_val |= (RandomUtils.random32(0, 1) << except_code)

        load_gpr64_seq = LoadGPR64(self.genThread)
        medeleg_val_reg_index = self.getRandomGPR(exclude='0')
        load_gpr64_seq.load(medeleg_val_reg_index, medeleg_val)
예제 #24
0
    def _loadRandomizedGprValue(self, aGprIndex):
        gpr_val = 0
        if RandomUtils.random32(0, 1) == 0:
            gpr_name = 'x%d' % aGprIndex
            self.randomInitializeRegister(gpr_name)
            (gpr_val, valid) = self.readRegister(gpr_name)
            exception_handlers_test_utils.assertValidGprValue(
                self, aGprIndex, valid)
        else:
            load_gpr64_seq = LoadGPR64(self.genThread)
            gpr_val = RandomUtils.random64()
            load_gpr64_seq.load(aGprIndex, gpr_val)

        return gpr_val
예제 #25
0
    def generate(self, **kargs):
        self.randomInitializeRegister('D0')
        for reg_index in range(1, 32):
            self.randomInitializeRegister('D%d' % reg_index)
            self.initializeRegister('x%d' % reg_index,
                                    RandomUtils.random64(0x0, 0x7FFFFFFFFFFF))

        instructions = ('LD##RISCV', 'SD##RISCV')
        for _ in range(RandomUtils.random32(100, 200)):
            self.genInstruction(self.choice(instructions), {'NoPreamble': 1})

        load_gpr64_seq = LoadGPR64(self.genThread)
        for reg_index in range(1, 32):
            load_gpr64_seq.load(
                reg_index,
                RandomUtils.random64(0x800000000000, 0x7FFFFFFFFFFFFFFF))
예제 #26
0
    def _loadRandomizedGprValue(self, aGprIndex):
        gpr_val = 0
        if RandomUtils.random32(0, 1) == 0:
            gpr_name = "x%d" % aGprIndex
            self.randomInitializeRegister(gpr_name)
            (gpr_val, valid) = self.readRegister(gpr_name)
            exception_handlers_test_utils.assert_valid_gpr_value(
                self, aGprIndex, valid)
        else:
            load_gpr64_seq = LoadGPR64(self.genThread)
            gpr_val = (RandomUtils.random32()
                       if self.getGlobalState("AppRegisterWidth") == 32 else
                       RandomUtils.random64())
            load_gpr64_seq.load(aGprIndex, gpr_val)

        return gpr_val
예제 #27
0
    def initializeMemoryBlock(self, aMemBlockPtrIndex, aStateElems):
        mem_block_size = 0
        alignment = 0
        for state_elem in aStateElems:
            byte_count = len(state_elem.getValues()) * 8
            mem_block_size += byte_count

            # Align the memory block to the largest StateElement size
            if byte_count > alignment:
                alignment = byte_count

        mem_block_start_addr = self.genVA(Size=mem_block_size, Align=alignment, Type='D')
        self._initializeMemoryWithStateElementValues(mem_block_start_addr, aStateElems)

        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(aMemBlockPtrIndex, mem_block_start_addr)
예제 #28
0
    def processStateElements(self, aStateElems):
        if aStateElems[0].getStateElementType(
        ) != EStateElementType.SystemRegister:
            self.error(
                'This StateTransitionHandler can only process StateElements of type %s'
                % EStateElementType.SystemRegister)

        (mem_block_ptr_index, reg_val_gpr_index,
         scratch_gpr_index) = self._mHelperGprSet.acquireHelperGprs(3)
        self.initializeMemoryBlock(mem_block_ptr_index, aStateElems)
        (mem_block_ptr_val, _) = self.readRegister('x%d' % mem_block_ptr_index)

        load_gpr64_seq = LoadGPR64(self.genThread)
        offset_limit = 2**11
        offset = 0
        for state_elem in aStateElems:
            # This is a minor optimization that offsets from the memory block pointer when possible
            # rather than adjusting its value
            if offset >= offset_limit:
                mem_block_ptr_val += offset
                load_gpr64_seq.load(mem_block_ptr_index, mem_block_ptr_val)
                offset = 0

            self.genInstruction(
                'LD##RISCV', {
                    'rd': reg_val_gpr_index,
                    'rs1': mem_block_ptr_index,
                    'simm12': offset,
                    'NoRestriction': 1
                })
            if state_elem.getName() == 'vtype':
                self._processVtypeStateElement(reg_val_gpr_index)
            elif state_elem.getName() == 'vl':
                self._processVlStateElement(state_elem, reg_val_gpr_index,
                                            scratch_gpr_index)
            else:
                self.genInstruction(
                    'CSRRW#register#RISCV', {
                        'rd': 0,
                        'rs1': reg_val_gpr_index,
                        'csr': state_elem.getRegisterIndex()
                    })

            offset += 8

        self._mHelperGprSet.releaseHelperGprs()
예제 #29
0
    def generate(self, **kwargs):
        with ThreadSplitterContextManager(self):
            pc = PcConfig.get_base_boot_pc()
            (skip_boot, skip_boot_valid) = self.getOption("SkipBootCode")
            if skip_boot_valid and skip_boot == 1:
                pc = PcConfig.get_base_initial_pc()

            (
                boot_pc_reg_index,
                thread_id_reg_index,
                pc_offset_reg_index,
            ) = self.getRandomGPRs(3, exclude="0")
            assembly_helper = AssemblyHelperRISCV(self)
            assembly_helper.genReadSystemRegister(
                thread_id_reg_index, "mhartid"
            )  # Get the thread ID

            load_gpr64_seq = LoadGPR64(self.genThread)
            load_gpr64_seq.load(
                pc_offset_reg_index, PcConfig.get_boot_pc_offset()
            )
            self.genInstruction(
                "MUL##RISCV",
                {
                    "rd": pc_offset_reg_index,
                    "rs1": thread_id_reg_index,
                    "rs2": pc_offset_reg_index,
                },
            )  # Multiply the base PC offset by the thread ID

            load_gpr64_seq.load(boot_pc_reg_index, PcConfig.get_base_boot_pc())
            assembly_helper.genAddRegister(
                boot_pc_reg_index, pc_offset_reg_index
            )  # Add the thread PC offset to the base initial PC

            self.genInstruction(
                "JALR##RISCV",
                {
                    "rd": 0,
                    "rs1": boot_pc_reg_index,
                    "simm12": 0,
                    "NoBnt": 1,
                    "NoRestriction": 1,
                },
            )  # Branch to calculated address
예제 #30
0
    def processStateElement(self, aStateElem):
        if aStateElem.getStateElementType(
        ) != EStateElementType.FloatingPointRegister:
            return False

        (reg_val_gpr_index, ) = self._mHelperGprSet.acquireHelperGprs(1)

        # TODO(Noah): Handle Q regisers when the Q extension is supported.
        load_gpr64_seq = LoadGPR64(self.genThread)
        load_gpr64_seq.load(reg_val_gpr_index, aStateElem.getValues()[0])
        self.genInstruction('FMV.D.X##RISCV', {
            'rd': aStateElem.getRegisterIndex(),
            'rs1': reg_val_gpr_index
        })

        self._mHelperGprSet.releaseHelperGprs()

        return True