debug: Use flags for resume instead of program buffer. Untested.
This commit is contained in:
		
				
					committed by
					
						 Andrew Waterman
						Andrew Waterman
					
				
			
			
				
	
			
			
			
						parent
						
							d361e9e343
						
					
				
				
					commit
					22c6f728c3
				
			| @@ -10,7 +10,9 @@ | ||||
|  | ||||
| // Region of memory where each hart has 1 | ||||
| // byte to read. | ||||
| #define OK_GO 0x400 | ||||
| #define FLAGS 0x400 | ||||
| #define FLAG_GO     0 | ||||
| #define FLAG_RESUME 1 | ||||
|  | ||||
|         .option norvc | ||||
|         .global entry | ||||
| @@ -18,7 +20,7 @@ | ||||
|  | ||||
|         // Entry location on ebreak, Halt, or Breakpoint | ||||
|         // It is the same for all harts. They branch when  | ||||
|         // their specific OK_GO bit is set. | ||||
|         // their GO or RESUME bit is set. | ||||
|  | ||||
| entry: | ||||
|        jal zero, _entry | ||||
| @@ -36,12 +38,17 @@ _entry: | ||||
|         // 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 not be halted anymore. | ||||
|         // us to do, or whether we should resume. | ||||
| entry_loop: | ||||
|         csrr s0, CSR_MHARTID | ||||
|         sw   s0, HALTED(zero) | ||||
|         lb   s0, OK_GO(s0) // 1 byte flag per hart. Only one hart advances here. | ||||
|         bne  zero, s0, going | ||||
|         lbu  s0, FLAGS(s0) // 1 byte flag per hart. Only one hart advances here. | ||||
|         andi s0, s0, (1 << FLAG_GO) | ||||
|         bnez s0, going | ||||
|         csrr s0, CSR_MHARTID | ||||
|         lbu  s0, FLAGS(s0) // multiple harts can resume  here | ||||
|         andi s0, s0, (1 << FLAG_RESUME) | ||||
|         bnez s0, resume | ||||
|         jal  zero, entry_loop | ||||
|  | ||||
| _exception: | ||||
| @@ -50,16 +57,14 @@ _exception: | ||||
|  | ||||
| going: | ||||
|         csrr s0, CSR_DSCRATCH          // Restore s0 here | ||||
|         sw zero, GOING(zero)           // When debug module sees this write, the OK_GO flag is reset. | ||||
|         sw zero, GOING(zero)           // When debug module sees this write, the GO flag is reset. | ||||
|         jalr zero, zero, %lo(whereto)          // 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. | ||||
|  | ||||
| _resume: | ||||
|         csrw CSR_DSCRATCH, s0   // Save s0 to allow signaling MHARTID | ||||
|         csrr s0, CSR_MHARTID | ||||
|         sw   s0, RESUMING(zero) // Let the Debug Module know you're not halted anymore. | ||||
|         sw   s0, RESUMING(zero) // When Debug Module sees this write, the RESUME flag is reset. | ||||
|         csrr s0, CSR_DSCRATCH   // Restore s0 | ||||
|         dret | ||||
|  | ||||
|   | ||||
| @@ -52,7 +52,7 @@ object DsbRegAddrs{ | ||||
|   def RESUMING     = 0x108 | ||||
|   def EXCEPTION    = 0x10C | ||||
|  | ||||
|   def GO           = 0x400 | ||||
|   def FLAGS        = 0x400 | ||||
|  | ||||
|   def ROMBASE      = 0x800 | ||||
|   def RESUME       = 0x804 | ||||
| @@ -479,6 +479,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|     //-------------------------------------------------------------- | ||||
|  | ||||
|     val haltedBitRegs  = RegInit(Vec.fill(nComponents){false.B}) | ||||
|     val resumeReqRegs  = RegInit(Vec.fill(nComponents){false.B}) | ||||
|  | ||||
|     // --- regmapper outputs | ||||
|  | ||||
| @@ -537,6 +538,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|       DMSTATUSRdData.anyrunning := true.B | ||||
|     } | ||||
|  | ||||
|     DMSTATUSRdData.allresumeack := ~resumeReqRegs(selectedHartReg) | ||||
|     DMSTATUSRdData.anyresumeack := ~resumeReqRegs(selectedHartReg) | ||||
|  | ||||
|     //TODO | ||||
|     DMSTATUSRdData.cfgstrvalid := false.B | ||||
|  | ||||
| @@ -685,7 +689,9 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|     for (component <- 0 until nComponents) { | ||||
|       when (~io.dmactive) { | ||||
|         haltedBitRegs(component) := false.B | ||||
|         resumeReqRegs(component) := false.B | ||||
|       }.otherwise { | ||||
|         // Hart Halt Notification Logic | ||||
|         when (hartHaltedWrEn) { | ||||
|           when (cfg.hartIdToHartSel(hartHaltedId) === component.U) { | ||||
|             haltedBitRegs(component) := true.B | ||||
| @@ -695,6 +701,19 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|             haltedBitRegs(component) := false.B | ||||
|           } | ||||
|         } | ||||
|  | ||||
|         // Hart Resume Req Logic | ||||
|         // If you request a hart to resume at the same moment | ||||
|         // it actually does resume, then the request wins. | ||||
|         // So don't try to write resumereq more than once | ||||
|         when (hartResumingWrEn) { | ||||
|           when (cfg.hartIdToHartSel(hartResumingId) === component.U) { | ||||
|             resumeReqRegs(component) := false.B | ||||
|           } | ||||
|         } | ||||
|         when(io.innerCtrl.fire() && io.innerCtrl.bits.resumereq) { | ||||
|           resumeReqRegs(io.innerCtrl.bits.hartsel) := true.B | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|  | ||||
| @@ -723,7 +742,6 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|     //-------------------------------------------------------------- | ||||
|  | ||||
|     val goProgramBuffer = Wire(init = false.B) | ||||
|     val goResume        = Wire(init = false.B) | ||||
|     val goAbstract      = Wire(init = false.B) | ||||
|  | ||||
|     val whereToReg = Reg(UInt(32.W)) | ||||
| @@ -736,17 +754,11 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|     jalAbstract.setImm(ABSTRACT - WHERETO) | ||||
|     jalProgBuf.rd := 0.U | ||||
|  | ||||
|     val jalResume  = Wire(init = (new GeneratedUJ()).fromBits(rocket.Instructions.JAL.value.U)) | ||||
|     jalResume.setImm(RESUME - WHERETO) | ||||
|     jalResume.rd := 0.U | ||||
|  | ||||
|     when (~io.dmactive) { | ||||
|       whereToReg := 0.U | ||||
|     }.otherwise{ | ||||
|       when (goProgramBuffer) { | ||||
|         whereToReg := jalProgBuf.asUInt() | ||||
|       }.elsewhen (goResume) { | ||||
|         whereToReg := jalResume.asUInt() | ||||
|       }.elsewhen (goAbstract) { | ||||
|         whereToReg := jalAbstract.asUInt() | ||||
|       } | ||||
| @@ -757,7 +769,7 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|     when (~io.dmactive){ | ||||
|       goReg := false.B | ||||
|     }.otherwise { | ||||
|       when (goProgramBuffer | goResume | goAbstract) { | ||||
|       when (goProgramBuffer | goAbstract) { | ||||
|         goReg := true.B | ||||
|       }.elsewhen (hartGoingWrEn){ | ||||
|         assert(hartGoingId === 0.U, "Unexpected 'GOING' hart.")//Chisel3 #540 %x, expected %x", hartGoingId, 0.U) | ||||
| @@ -765,10 +777,20 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     val goBytes = Wire(init = Vec.fill(1024){0.U(8.W)}) | ||||
|     class flagBundle extends Bundle { | ||||
|       val reserved = UInt(6.W) | ||||
|       val resume = Bool() | ||||
|       val go = Bool() | ||||
|     } | ||||
|  | ||||
|     val flags = Wire(init = Vec.fill(1024){new flagBundle().fromBits(0.U)}) | ||||
|     assert ((cfg.hartSelToHartId(selectedHartReg) < 1024.U), | ||||
|       "HartSel to HartId Mapping is illegal for this Debug Implementation, because HartID must be < 1024 for it to work."); | ||||
|     goBytes(cfg.hartSelToHartId(selectedHartReg)) := Cat(0.U(7.W), goReg) | ||||
|     flags(cfg.hartSelToHartId(selectedHartReg)).go := goReg | ||||
|     for (component <- 0 until nComponents) { | ||||
|       val componentSel = Wire(component.U) | ||||
|       flags(cfg.hartSelToHartId(componentSel)).resume := resumeReqRegs(component) | ||||
|     } | ||||
|  | ||||
|     //---------------------------- | ||||
|     // Abstract Command Decoding & Generation | ||||
| @@ -870,10 +892,10 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|  | ||||
|       // These sections are read-only. | ||||
|       ROMBASE     -> DebugRomContents().map(x => RegField.r(8, (x & 0xFF).U(8.W))), | ||||
|       GO          -> goBytes.map(x => RegField.r(8, x)), | ||||
|       FLAGS       -> flags.map{x => RegField.r(8, x.asUInt())}, | ||||
|       WHERETO     -> Seq(RegField.r(32, whereToReg)), | ||||
|       ABSTRACT    -> abstractGeneratedMem.map(x => RegField.r(32, x)) | ||||
|      ) | ||||
|       ) | ||||
|  | ||||
|     // Override System Bus accesses with dmactive reset. | ||||
|     when (~io.dmactive){ | ||||
| @@ -940,9 +962,8 @@ class TLDebugModuleInner(device: Device, getNComponents: () => Int)(implicit p: | ||||
|  | ||||
|       when (wrAccessRegisterCommand || regAccessRegisterCommand) { | ||||
|         ctrlStateNxt := CtrlState(CheckGenerate) | ||||
|       }.elsewhen(io.innerCtrl.fire() && io.innerCtrl.bits.resumereq) { | ||||
|         goResume := true.B | ||||
|       } | ||||
|  | ||||
|     }.elsewhen (ctrlStateReg === CtrlState(CheckGenerate)){ | ||||
|  | ||||
|       // We use this state to ensure that the COMMAND has been | ||||
|   | ||||
| @@ -5,13 +5,14 @@ package uncore.devices | ||||
| object DebugRomContents { | ||||
|  | ||||
|   def apply() : Array[Byte] = { Array ( | ||||
|   0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0x80, 0x03, 0x6f, 0x00, 0x00, 0x02, | ||||
|   0x6f, 0x00, 0xc0, 0x00, 0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0x40, 0x03, | ||||
|   0x0f, 0x00, 0xf0, 0x0f, 0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, | ||||
|   0x23, 0x20, 0x80, 0x10, 0x03, 0x04, 0x04, 0x40, 0x63, 0x18, 0x80, 0x00, | ||||
|   0x6f, 0xf0, 0x1f, 0xff, 0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, | ||||
|   0x73, 0x24, 0x20, 0x7b, 0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, | ||||
|   0x73, 0x10, 0x24, 0x7b, 0x73, 0x24, 0x40, 0xf1, 0x23, 0x24, 0x80, 0x10, | ||||
|   0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b | ||||
|   0x23, 0x20, 0x80, 0x10, 0x03, 0x44, 0x04, 0x40, 0x13, 0x74, 0x14, 0x00, | ||||
|   0x63, 0x10, 0x04, 0x02, 0x73, 0x24, 0x40, 0xf1, 0x03, 0x44, 0x04, 0x40, | ||||
|   0x13, 0x74, 0x24, 0x00, 0xe3, 0x18, 0x04, 0xfc, 0x6f, 0xf0, 0xdf, 0xfd, | ||||
|   0x23, 0x26, 0x00, 0x10, 0x73, 0x00, 0x10, 0x00, 0x73, 0x24, 0x20, 0x7b, | ||||
|   0x23, 0x22, 0x00, 0x10, 0x67, 0x00, 0x00, 0x30, 0x73, 0x24, 0x40, 0xf1, | ||||
|   0x23, 0x24, 0x80, 0x10, 0x73, 0x24, 0x20, 0x7b, 0x73, 0x00, 0x20, 0x7b | ||||
|   ).map(_.toByte) } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user