URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_arm_plugin/] [cpu_arm7_func.cpp] - Rev 5
Compare with Previous | Blame | View Log
/* * Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <api_core.h> #include "cpu_arm7_func.h" namespace debugger { CpuCortex_Functional::CpuCortex_Functional(const char *name) : CpuGeneric(name), portRegs_(this, "regs", 0x8000, Reg_Total), portSavedRegs_(this, "savedregs", 0, Reg_Total) { registerInterface(static_cast<ICpuArm *>(this)); registerAttribute("VectorTable", &vectorTable_); p_psr_ = reinterpret_cast<ProgramStatusRegsiterType *>( &portRegs_.getp()[Reg_cpsr]); } CpuCortex_Functional::~CpuCortex_Functional() { } void CpuCortex_Functional::postinitService() { // Supported instruction sets: for (int i = 0; i < INSTR_HASH_TABLE_SIZE; i++) { listInstr_[i].make_list(0); } addArm7tmdiIsa(); // Power-on reset(false); CpuGeneric::postinitService(); } unsigned CpuCortex_Functional::addSupportedInstruction( ArmInstruction *instr) { AttributeType tmp(instr); listInstr_[instr->hash()].add_to_list(&tmp); return 0; } void CpuCortex_Functional::handleTrap() { if (interrupt_pending_ == 0) { return; } npc_.setValue(0 + 4*0); interrupt_pending_ = 0; } void CpuCortex_Functional::reset(bool active) { CpuGeneric::reset(active); portRegs_.reset(); estate_ = CORE_Halted; } GenericInstruction *CpuCortex_Functional::decodeInstruction(Reg64Type *cache) { ArmInstruction *instr = NULL; int hash_idx = hash32(cacheline_[0].buf32[0]); for (unsigned i = 0; i < listInstr_[hash_idx].size(); i++) { instr = static_cast<ArmInstruction *>( listInstr_[hash_idx][i].to_iface()); if (instr->parse(cacheline_[0].buf32)) { break; } instr = NULL; } portRegs_.getp()[Reg_pc].val = getPC(); return instr; } void CpuCortex_Functional::generateIllegalOpcode() { //raiseSignal(EXCEPTION_InstrIllegal); RISCV_error("Illegal instruction at 0x%08" RV_PRI64 "x", getPC()); } void CpuCortex_Functional::trackContextStart() { if (reg_trace_file == 0) { return; } /** Save previous reg values to find modification after exec() */ uint64_t *dst = portSavedRegs_.getpR64(); uint64_t *src = portRegs_.getpR64(); memcpy(dst, src, Reg_Total*sizeof(uint64_t)); } void CpuCortex_Functional::trackContextEnd() { if (reg_trace_file == 0) { return; } int sz; char tstr[1024]; const char *pinstrname = "unknown"; if (instr_) { pinstrname = instr_->name(); } sz = RISCV_sprintf(tstr, sizeof(tstr),"%8I64d [%08x]: %8s ", step_cnt_, pc_.getValue().buf32[0], pinstrname); bool reg_changed = false; uint64_t *prev = portSavedRegs_.getpR64(); uint64_t *cur = portRegs_.getpR64(); for (int i = 0; i < Reg_Total; i++) { if (prev[i] != cur[i]) { reg_changed = true; sz += RISCV_sprintf(&tstr[sz], sizeof(tstr) - sz, "%3s <= %016I64x ", IREGS_NAMES[i], cur[i]); } } if (instr_ && !reg_changed) { sz += RISCV_sprintf(&tstr[sz], sizeof(tstr) - sz, "-", NULL); } (*reg_trace_file) << tstr << "\n"; reg_trace_file->flush(); } void CpuCortex_Functional::raiseSignal(int idx) { RISCV_error("Raise unsupported signal %d", idx); } void CpuCortex_Functional::lowerSignal(int idx) { interrupt_pending_ &= ~(1 << idx); RISCV_error("Lower unsupported signal %d", idx); } } // namespace debugger