diff --git a/scripts/debug_rom/Makefile b/scripts/debug_rom/Makefile index 01f1ed5906c..5348c57ad39 100644 --- a/scripts/debug_rom/Makefile +++ b/scripts/debug_rom/Makefile @@ -5,27 +5,28 @@ CC = $(RISCV)/bin/riscv64-unknown-elf-gcc OBJCOPY = $(RISCV)/bin/riscv64-unknown-elf-objcopy -COMPILE = $(CC) -nostdlib -nostartfiles -I$(RISCV)/include/ -Tlink.ld +COMPILE = $(CC) -nostdlib -nostartfiles -I$(RISCV)/riscv64-unknown-elf/include/ -Tlink.ld -ELFS = debug_rom -DEPS = debug_rom.S link.ld +ELFS = debug_rom debug_rom_nonzero -all: $(patsubst %,%.h,$(ELFS)) +all: $(ELFS) -publish: debug_rom.scala - mv $< ../../src/main/scala/devices/debug/DebugRomContents.scala +publish: DebugRomContents.scala DebugRomNonzeroContents.scala + mv $^ ../../src/main/scala/devices/debug %.scala: %.raw - xxd -i $^ | sed -e "s/^unsigned char debug_rom_raw\[\] = {/\/\/ This file was auto-generated by 'make publish' in debug\/ directory.\n\npackage freechips.rocketchip.devices.debug\n\nobject DebugRomContents {\n\n def apply() : Array[Byte] = { Array (/" \ + xxd -i $^ | sed -e "s/^unsigned char DebugRom.*/\/\/ This file was auto-generated by 'make publish' in debug\/ directory.\n\npackage freechips.rocketchip.devices.debug\n\nobject $(basename $<) {\n\n def apply() : Array[Byte] = { Array (/" \ -e "s/};/ ).map(_.toByte) }\n\n}/" \ - -e "s/^unsigned int debug_rom_raw_len.*//" > $@ + -e "s/^unsigned int DebugRom.*//" > $@ +DebugRomContents.raw: debug_rom + $(OBJCOPY) -O binary --only-section .text $^ $@ -%.raw: % +DebugRomNonzeroContents.raw: debug_rom_nonzero $(OBJCOPY) -O binary --only-section .text $^ $@ -debug_rom: $(DEPS) +%: %.S $(COMPILE) -o $@ $^ clean: - rm -f $(ELFS) debug_rom*.raw debug_rom*.h + rm -f $(ELFS) DebugRom*.raw diff --git a/scripts/debug_rom/debug_rom.S b/scripts/debug_rom/debug_rom.S index 72da1e8edfb..00af9f095f9 100755 --- a/scripts/debug_rom/debug_rom.S +++ b/scripts/debug_rom/debug_rom.S @@ -1,6 +1,6 @@ // See LICENSE.SiFive for license details. -#include "spike/encoding.h" +#include "riscv-pk/encoding.h" // These are implementation-specific addresses in the Debug Module #define HALTED 0x100 diff --git a/scripts/debug_rom/debug_rom_nonzero.S b/scripts/debug_rom/debug_rom_nonzero.S new file mode 100644 index 00000000000..f78b8434695 --- /dev/null +++ b/scripts/debug_rom/debug_rom_nonzero.S @@ -0,0 +1,89 @@ +// See LICENSE.SiFive for license details. + +#include "riscv-pk/encoding.h" + +#ifndef CSR_DSCRATCH1 +#define CSR_DSCRATCH1 (CSR_DSCRATCH + 1) +#endif + +// These are implementation-specific addresses in the Debug Module, relative to entry +#define HALTED -0x700 // 0x100 +#define GOING -0x6FC // 0x104 +#define RESUMING -0x6F8 // 0x108 +#define EXCEPTION -0x6F4 // 0x10C + +// Region of memory where each hart has 1 byte to read. +#define FLAGS -0x400 // 0x400 +#define FLAG_GO 0 +#define FLAG_RESUME 1 + + .option norvc + .global entry + .global exception + + // Entry location on ebreak, Halt, or Breakpoint + // It is the same for all harts. They branch when + // their GO or RESUME bit is set. + +// 0x800 +entry: + csrw CSR_DSCRATCH1, s1 // s1=s1, ds1=s1: Save s1 to use as base pointer + j _entry + +// 0x808 +exception: + csrrw s1, CSR_DSCRATCH1, s1 // s1=base, ds1=s1 + sw zero, EXCEPTION(s1) // Let debug module know you got an exception. + +_entry: + // This fence is required because the execution may have written something + // into the Abstract Data or Program Buffer registers. + fence + csrw CSR_DSCRATCH, s0 // Save s0 to allow signaling MHARTID + la s1, entry // s1 = base (0x800 into debug region) + + // We continue to let the hart know that we are halted in order that + // a DM which was reset is still made aware that a hart is halted. + // We keep checking both whether there is something the debugger wants + // us to do, or whether we should resume. +entry_loop: + csrr s0, CSR_MHARTID + sw s0, HALTED(s1) + add s0, s0, s1 // s0=base + hartid + lbu s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. + andi s0, s0, (1 << FLAG_GO) | (1 << FLAG_RESUME) + beqz s0, entry_loop // Loop until either GO or RESUME is set. + + andi s0, s0, (1 << FLAG_GO) + beqz s0, _resume // If GO is clear at this point, RESUME must be set. + + csrr s0, CSR_DSCRATCH // Restore s0 here + +//TODO: 0x48 is a hack for (icache-entry) constant + jalr zero, 0x48(s1) // Rocket-Chip has a specific hack which is that jalr in + // Debug Mode will flush the I-Cache. We need that so that the + // remainder of the variable instructions will be what Debug Module + // intends. +icache: + sw zero, GOING(s1) // When debug module sees this write, the GO flag is reset. + csrrw s1, CSR_DSCRATCH1, s1 // s1=s1, ds1=base + j whereto + +_resume: + csrr s0, CSR_MHARTID + sw s0, RESUMING(s1) // When Debug Module sees this write, the RESUME flag is reset. + csrr s0, CSR_DSCRATCH // Restore s0 + csrr s1, CSR_DSCRATCH1 // Restore s1 + dret + + // END OF ACTUAL "ROM" CONTENTS. BELOW IS JUST FOR LINKER SCRIPT. + +.section .whereto +whereto: + nop + // Variable "ROM" This is : jal x0 abstract, jal x0 program_buffer, + // or jal x0 resume, as desired. + // Debug Module state machine tracks what is 'desired'. + // We don't need/want to use jalr here because all of the + // Variable ROM contents are set by + // Debug Module before setting the OK_GO byte. diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index 3c4bdff3a91..8e71bbaa031 100755 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -9,7 +9,7 @@ import chisel3.util._ import freechips.rocketchip.config._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.regmapper._ -import freechips.rocketchip.rocket.Instructions +import freechips.rocketchip.rocket.{CSRs, Instructions} import freechips.rocketchip.tile.MaxHartIdBits import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError} @@ -54,8 +54,8 @@ object DsbRegAddrs{ def IMPEBREAK(cfg: DebugModuleParams) = { DATA - 4 } // We want abstract to be immediately before PROGBUF - // because we auto-generate 2 instructions. - def ABSTRACT(cfg:DebugModuleParams) = PROGBUF(cfg) - 8 + // because we auto-generate 2 (or 5) instructions. + def ABSTRACT(cfg:DebugModuleParams) = PROGBUF(cfg) - (cfg.nAbstractInstructions * 4) def FLAGS = 0x400 def ROMBASE = 0x800 @@ -101,6 +101,7 @@ object DebugAbstractCommandType extends scala.Enumeration { **/ case class DebugModuleParams ( + baseAddress : BigInt = BigInt(0), nDMIAddrSize : Int = 7, nProgramBufferWords: Int = 16, nAbstractDataWords : Int = 4, @@ -130,7 +131,12 @@ case class DebugModuleParams ( // TODO: Check that quick access requirements are met. } - def address = AddressSet(0, 0xFFF) // This is required for correct functionality; it's not configurable. + def address = AddressSet(baseAddress, 0xFFF) + def atzero = (baseAddress == 0) + def nAbstractInstructions = if (atzero) 2 else 5 + def debugEntry: BigInt = baseAddress + 0x800 + def debugException: BigInt = baseAddress + 0x808 + def nDscratch: Int = if (atzero) 1 else 2 } object DefaultDebugModuleParams { @@ -363,9 +369,12 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod } //----HARTINFO + // DATA registers are mapped to memory. The dataaddr field of HARTINFO has only + // 12 bits and assumes the DM base is 0. If not at 0, then HARTINFO reads as 0 + // (implying nonexistence according to the Debug Spec). val HARTINFORdData = WireInit(0.U.asTypeOf(new HARTINFOFields())) - when (dmAuthenticated) { + if (cfg.atzero) when (dmAuthenticated) { HARTINFORdData.dataaccess := true.B HARTINFORdData.datasize := cfg.nAbstractDataWords.U HARTINFORdData.dataaddr := DsbRegAddrs.DATA.U @@ -510,11 +519,11 @@ class TLDebugModuleOuter(device: Device)(implicit p: Parameters) extends LazyMod )) val hartinfoRegFields = RegFieldGroup("dmi_hartinfo", Some("hart information"), Seq( - RegField.r(12, HARTINFORdData.dataaddr, RegFieldDesc("dataaddr", "data address", reset=Some(DsbRegAddrs.DATA))), - RegField.r(4, HARTINFORdData.datasize, RegFieldDesc("datasize", "number of DATA registers", reset=Some(cfg.nAbstractDataWords))), - RegField.r(1, HARTINFORdData.dataaccess, RegFieldDesc("dataaccess", "data access type", reset=Some(1))), + RegField.r(12, HARTINFORdData.dataaddr, RegFieldDesc("dataaddr", "data address", reset=Some(if (cfg.atzero) DsbRegAddrs.DATA else 0))), + RegField.r(4, HARTINFORdData.datasize, RegFieldDesc("datasize", "number of DATA registers", reset=Some(if (cfg.atzero) cfg.nAbstractDataWords else 0))), + RegField.r(1, HARTINFORdData.dataaccess, RegFieldDesc("dataaccess", "data access type", reset=Some(if (cfg.atzero) 1 else 0))), RegField(3), - RegField.r(4, HARTINFORdData.nscratch, RegFieldDesc("nscratch", "number of scratch registers", reset=Some(cfg.nScratch))) + RegField.r(4, HARTINFORdData.nscratch, RegFieldDesc("nscratch", "number of scratch registers", reset=Some(if (cfg.atzero) cfg.nScratch else 0))) )) //-------------------------------------------------------------- @@ -1429,6 +1438,14 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I val opcode = UInt(7.W) } + class GeneratedCSR extends Bundle { + val imm = UInt(12.W) + val rs1 = UInt(5.W) + val funct3 = UInt(3.W) + val rd = UInt(5.W) + val opcode = UInt(7.W) + } + class GeneratedUJ extends Bundle { val imm3 = UInt(1.W) val imm0 = UInt(10.W) @@ -1451,41 +1468,87 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I } } - val abstractGeneratedMem = Reg(Vec(2, (UInt(32.W)))) - val abstractGeneratedI = Wire(new GeneratedI()) - val abstractGeneratedS = Wire(new GeneratedS()) - val nop = Wire(new GeneratedI()) + require((cfg.atzero && cfg.nAbstractInstructions == 2) || (!cfg.atzero && cfg.nAbstractInstructions == 5), + "Mismatch between DebugModuleParams atzero and nAbstractInstructions") + val abstractGeneratedMem = Reg(Vec(cfg.nAbstractInstructions, (UInt(32.W)))) + + def abstractGeneratedI(cfg: DebugModuleParams): UInt = { + val inst = Wire(new GeneratedI()) + val offset = if (cfg.atzero) DATA else (DATA-0x800) & 0xFFF + val base = if (cfg.atzero) 0.U else Mux(accessRegisterCommandReg.regno(0), 8.U, 9.U) + inst.opcode := (Instructions.LW.value.U.asTypeOf(new GeneratedI())).opcode + inst.rd := (accessRegisterCommandReg.regno & 0x1F.U) + inst.funct3 := accessRegisterCommandReg.size + inst.rs1 := base + inst.imm := offset.U + inst.asUInt + } - abstractGeneratedI.opcode := (Instructions.LW.value.U.asTypeOf(new GeneratedI())).opcode - abstractGeneratedI.rd := (accessRegisterCommandReg.regno & 0x1F.U) - abstractGeneratedI.funct3 := accessRegisterCommandReg.size - abstractGeneratedI.rs1 := 0.U - abstractGeneratedI.imm := DATA.U + def abstractGeneratedS(cfg: DebugModuleParams): UInt = { + val inst = Wire(new GeneratedS()) + val offset = if (cfg.atzero) DATA else (DATA-0x800) & 0xFFF + val base = if (cfg.atzero) 0.U else Mux(accessRegisterCommandReg.regno(0), 8.U, 9.U) + inst.opcode := (Instructions.SW.value.U.asTypeOf(new GeneratedS())).opcode + inst.immlo := (offset & 0x1F).U + inst.funct3 := accessRegisterCommandReg.size + inst.rs1 := base + inst.rs2 := (accessRegisterCommandReg.regno & 0x1F.U) + inst.immhi := (offset >> 5).U + inst.asUInt + } - abstractGeneratedS.opcode := (Instructions.SW.value.U.asTypeOf(new GeneratedS())).opcode - abstractGeneratedS.immlo := (DATA & 0x1F).U - abstractGeneratedS.funct3 := accessRegisterCommandReg.size - abstractGeneratedS.rs1 := 0.U - abstractGeneratedS.rs2 := (accessRegisterCommandReg.regno & 0x1F.U) - abstractGeneratedS.immhi := (DATA >> 5).U + def abstractGeneratedCSR: UInt = { + val inst = Wire(new GeneratedCSR()) + val base = Mux(accessRegisterCommandReg.regno(0), 8.U, 9.U) // use s0 as base for odd regs, s1 as base for even regs + inst := (Instructions.CSRRW.value.U.asTypeOf(new GeneratedCSR())) + inst.imm := CSRs.dscratch1.U + inst.rs1 := base + inst.rd := base + inst.asUInt + } + val nop = Wire(new GeneratedI()) nop := Instructions.ADDI.value.U.asTypeOf(new GeneratedI()) nop.rd := 0.U nop.rs1 := 0.U nop.imm := 0.U + val isa = Wire(new GeneratedI()) + isa := Instructions.ADDIW.value.U.asTypeOf(new GeneratedI()) + isa.rd := 0.U + isa.rs1 := 0.U + isa.imm := 0.U + + when (goAbstract) { - abstractGeneratedMem(0) := Mux(accessRegisterCommandReg.transfer, - Mux(accessRegisterCommandReg.write, - // To write a register, we need to do LW. - abstractGeneratedI.asUInt(), - // To read a register, we need to do SW. - abstractGeneratedS.asUInt()), - nop.asUInt() - ) - abstractGeneratedMem(1) := Mux(accessRegisterCommandReg.postexec, - nop.asUInt(), - Instructions.EBREAK.value.U) + if (cfg.nAbstractInstructions == 2) { + // ABSTRACT(0): Transfer: LW or SW, else NOP + // ABSTRACT(1): Postexec: NOP else EBREAK + abstractGeneratedMem(0) := Mux(accessRegisterCommandReg.transfer, + Mux(accessRegisterCommandReg.write, abstractGeneratedI(cfg), abstractGeneratedS(cfg)), + nop.asUInt() + ) + abstractGeneratedMem(1) := Mux(accessRegisterCommandReg.postexec, + nop.asUInt(), + Instructions.EBREAK.value.U) + } else { + // Entry: All regs in GPRs, dscratch1=offset 0x800 in DM + // ABSTRACT(0): CheckISA: ADDW or NOP (exception here if size=3 and not RV64) + // ABSTRACT(1): CSRRW s1,dscratch1,s1 or CSRRW s0,dscratch1,s0 + // ABSTRACT(2): Transfer: LW, SW, LD, SD else NOP + // ABSTRACT(3): CSRRW s1,dscratch1,s1 or CSRRW s0,dscratch1,s0 + // ABSTRACT(4): Postexec: NOP else EBREAK + abstractGeneratedMem(0) := Mux(accessRegisterCommandReg.transfer && accessRegisterCommandReg.size =/= 2.U, isa.asUInt(), nop.asUInt()) + abstractGeneratedMem(1) := abstractGeneratedCSR + abstractGeneratedMem(2) := Mux(accessRegisterCommandReg.transfer, + Mux(accessRegisterCommandReg.write, abstractGeneratedI(cfg), abstractGeneratedS(cfg)), + nop.asUInt() + ) + abstractGeneratedMem(3) := abstractGeneratedCSR + abstractGeneratedMem(4) := Mux(accessRegisterCommandReg.postexec, + nop.asUInt(), + Instructions.EBREAK.value.U) + } } //-------------------------------------------------------------- @@ -1528,7 +1591,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I flags.zipWithIndex.map{case(x, i) => RegField.r(8, x.asUInt(), RegFieldDesc(s"debug_flags_$i", "", volatile=true))} }), ROMBASE -> RegFieldGroup("debug_rom", Some("Debug ROM"), - DebugRomContents().zipWithIndex.map{case (x, i) => RegField.r(8, (x & 0xFF).U(8.W), RegFieldDesc(s"debug_rom_$i", "", reset=Some(x)))}) + (if (cfg.atzero) DebugRomContents() else DebugRomNonzeroContents()).zipWithIndex.map{case (x, i) => + RegField.r(8, (x & 0xFF).U(8.W), RegFieldDesc(s"debug_rom_$i", "", reset=Some(x)))}) ) // Override System Bus accesses with dmactive reset. @@ -1579,13 +1643,14 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int, beatBytes: I val commandWrIsAccessRegister = (COMMANDWrData.cmdtype === DebugAbstractCommandType.AccessRegister.id.U) val commandRegIsAccessRegister = (COMMANDReg.cmdtype === DebugAbstractCommandType.AccessRegister.id.U) - val commandWrIsUnsupported = COMMANDWrEn && !commandWrIsAccessRegister; + val commandWrIsUnsupported = COMMANDWrEn && !commandWrIsAccessRegister val commandRegIsUnsupported = WireInit(true.B) val commandRegBadHaltResume = WireInit(false.B) // We only support abstract commands for GPRs and any custom registers, if specified. - val accessRegIsGPR = (accessRegisterCommandReg.regno >= 0x1000.U && accessRegisterCommandReg.regno <= 0x101F.U) + val accessRegIsLegalSize = (accessRegisterCommandReg.size === 2.U) || (accessRegisterCommandReg.size === 3.U) + val accessRegIsGPR = (accessRegisterCommandReg.regno >= 0x1000.U && accessRegisterCommandReg.regno <= 0x101F.U) && accessRegIsLegalSize val accessRegIsCustom = if (needCustom) { val (custom, customP) = customNode.in.head customP.addrs.foldLeft(false.B){ diff --git a/src/main/scala/devices/debug/DebugRomNonzeroContents.scala b/src/main/scala/devices/debug/DebugRomNonzeroContents.scala new file mode 100644 index 00000000000..65be23ca1cc --- /dev/null +++ b/src/main/scala/devices/debug/DebugRomNonzeroContents.scala @@ -0,0 +1,20 @@ +// This file was auto-generated by 'make publish' in debug/ directory. + +package freechips.rocketchip.devices.debug + +object DebugRomNonzeroContents { + + def apply() : Array[Byte] = { Array ( + 0x73, 0x90, 0x34, 0x7b, 0x6f, 0x00, 0xc0, 0x00, 0xf3, 0x94, 0x34, 0x7b, + 0x23, 0xa6, 0x04, 0x90, 0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, + 0x97, 0x04, 0x00, 0x00, 0x93, 0x84, 0x84, 0xfe, 0x73, 0x24, 0x40, 0xf1, + 0x23, 0xa0, 0x84, 0x90, 0x33, 0x04, 0x94, 0x00, 0x03, 0x44, 0x04, 0xc0, + 0x13, 0x74, 0x34, 0x00, 0xe3, 0x06, 0x04, 0xfe, 0x13, 0x74, 0x14, 0x00, + 0x63, 0x0c, 0x04, 0x00, 0x73, 0x24, 0x20, 0x7b, 0x67, 0x80, 0x84, 0x04, + 0x23, 0xa2, 0x04, 0x90, 0xf3, 0x94, 0x34, 0x7b, 0x6f, 0xf0, 0x1f, 0xab, + 0x73, 0x24, 0x40, 0xf1, 0x23, 0xa4, 0x84, 0x90, 0x73, 0x24, 0x20, 0x7b, + 0xf3, 0x24, 0x30, 0x7b, 0x73, 0x00, 0x20, 0x7b + ).map(_.toByte) } + +} + diff --git a/src/main/scala/diplomaticobjectmodel/logicaltree/LogicalTrees.scala b/src/main/scala/diplomaticobjectmodel/logicaltree/LogicalTrees.scala index a430d3564b0..e3533819d5c 100644 --- a/src/main/scala/diplomaticobjectmodel/logicaltree/LogicalTrees.scala +++ b/src/main/scala/diplomaticobjectmodel/logicaltree/LogicalTrees.scala @@ -113,7 +113,7 @@ class DebugLogicalTreeNode( hartSeltoHartIDMapping = Nil, // HartSel goes from 0->N but HartID is not contiguious or increasing authenticationType = (if (cfg.hasAuthentication) PASSTHRU else NONE), nHartsellenBits = p(MaxHartIdBits), // Number of actually implemented bits of Hartsel - hasHartInfo = true, + hasHartInfo = cfg.atzero, hasAbstractauto = true, cfgStrPtrValid = false, nHaltSummaryRegisters = 2, diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 55a6062b5f4..bcfc50c3911 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -7,6 +7,7 @@ import Chisel._ import Chisel.ImplicitConversions._ import chisel3.withClock import freechips.rocketchip.config.Parameters +import freechips.rocketchip.devices.debug.DebugModuleKey import freechips.rocketchip.tile._ import freechips.rocketchip.util._ import freechips.rocketchip.util.property._ @@ -363,6 +364,7 @@ class CSRFile( val reg_debug = Reg(init=Bool(false)) val reg_dpc = Reg(UInt(width = vaddrBitsExtended)) val reg_dscratch = Reg(UInt(width = xLen)) + val reg_dscratch1 = (p(DebugModuleKey).map(_.nDscratch).getOrElse(1) > 1).option(Reg(UInt(width = xLen))) val reg_singleStepped = Reg(Bool()) val reg_mcontext = (coreParams.mcontextWidth > 0).option(RegInit(0.U(coreParams.mcontextWidth.W))) @@ -485,7 +487,8 @@ class CSRFile( val debug_csrs = if (!usingDebug) LinkedHashMap() else LinkedHashMap[Int,Bits]( CSRs.dcsr -> reg_dcsr.asUInt, CSRs.dpc -> readEPC(reg_dpc).sextTo(xLen), - CSRs.dscratch -> reg_dscratch.asUInt) + CSRs.dscratch -> reg_dscratch.asUInt) ++ + reg_dscratch1.map(r => CSRs.dscratch1 -> r) val context_csrs = LinkedHashMap[Int,Bits]() ++ reg_mcontext.map(r => CSRs.mcontext -> r) ++ @@ -654,7 +657,9 @@ class CSRFile( val causeIsDebugTrigger = !cause(xLen-1) && cause_lsbs === CSR.debugTriggerCause val causeIsDebugBreak = !cause(xLen-1) && insn_break && Cat(reg_dcsr.ebreakm, reg_dcsr.ebreakh, reg_dcsr.ebreaks, reg_dcsr.ebreaku)(reg_mstatus.prv) val trapToDebug = Bool(usingDebug) && (reg_singleStepped || causeIsDebugInt || causeIsDebugTrigger || causeIsDebugBreak || reg_debug) - val debugTVec = Mux(reg_debug, Mux(insn_break, UInt(0x800), UInt(0x808)), UInt(0x800)) + val debugEntry = p(DebugModuleKey).map(_.debugEntry).getOrElse(BigInt(0x800)) + val debugException = p(DebugModuleKey).map(_.debugException).getOrElse(BigInt(0x808)) + val debugTVec = Mux(reg_debug, Mux(insn_break, debugEntry.U, debugException.U), debugEntry.U) val delegate = Bool(usingSupervisor) && reg_mstatus.prv <= PRV.S && Mux(cause(xLen-1), read_mideleg(cause_lsbs), read_medeleg(cause_lsbs)) def mtvecBaseAlign = 2 def mtvecInterruptAlign = { @@ -905,6 +910,9 @@ class CSRFile( } when (decoded_addr(CSRs.dpc)) { reg_dpc := formEPC(wdata) } when (decoded_addr(CSRs.dscratch)) { reg_dscratch := wdata } + reg_dscratch1.foreach { r => + when (decoded_addr(CSRs.dscratch1)) { r := wdata } + } } if (usingSupervisor) { when (decoded_addr(CSRs.sstatus)) { diff --git a/src/main/scala/rocket/Instructions.scala b/src/main/scala/rocket/Instructions.scala index 2792dab9009..9c0beda2c95 100644 --- a/src/main/scala/rocket/Instructions.scala +++ b/src/main/scala/rocket/Instructions.scala @@ -917,6 +917,7 @@ object CSRs { val dcsr = 0x7b0 val dpc = 0x7b1 val dscratch = 0x7b2 + val dscratch1 = 0x7b3 val mcycle = 0xb00 val minstret = 0xb02 val mhpmcounter3 = 0xb03 @@ -1176,6 +1177,7 @@ object CSRs { res += dcsr res += dpc res += dscratch + res += dscratch1 res += mcycle res += minstret res += mhpmcounter3