I haven't seen any Cortex A8 activity on the list, lately, so I wonder if anyone has come across these issues.

See attached script:

I tried implementing the functions described in the Cortex A8 TRM. I was trying to see if I could read CPU ARM registers.

The code seems to mostly work.

Except for weird Cortex A8 things that don't seem to be documented, at least I cant find them.

1. If I set bit 1 to 1, on a write to the DSCR the core restarts ??
2. If I write an instruction to the ITR, the "Execute Instruction Enable" and "Halting debug-mode" bits in the DSCR randomly clear? 3. Even though DTRXfull in DSCR is set after writing the instruction to ITR (as expected), reading the DTRTX returns invalid data (it seems to be the data of the last write to ANY other debug register), BUT the DTRXfull flag in the DSCR is cleared, indicating the register was actually read?

Anyone have any ideas? Anyone managed to read an ARM register through this interface?

I am obviously missing something important, but a days worth of hacking and re-reading the cortex a8 TRM has bought me no closer.

I am testing this on a small assembly stub which alternately flashes the leds on a beagle in a loop, its loaded by the ROM boot loader in the OMAP3 over USB. That way when I read registers, I should be able to verify the contents against my code, based on the state of the leds.

Strontium




proc omap3_WriteDebugRegister { reg_num val } {
  # write the value val to the debug register reg_num at address reg_num << 2
  puts [format "Write- %4d : %#010x" $reg_num $val  ]
  omap3.cpu mww [expr "0x54011000 + $reg_num * 4"] $val 4
}

proc omap3_ReadDebugRegister { reg_num } {
  # read the value of the debug register reg_num at address reg_num << 2
  omap3.cpu mem2array junk dataval 32 [expr "0x54011000 + $reg_num * 4"] 1
  set val [format "%#010x" $dataval(0)]
  puts [format "Read - %4d : %#010x" $reg_num $val  ]
  return $val
}

proc omap3_ReadModifyWriteDebugRegister { reg_num and_mask or_mask } {
  # reads a register, modifies it, writes it back, re-reads and returns the new register state
  set val [omap3_ReadDebugRegister $reg_num]
  set val [expr "$val & $and_mask"]
  set val [expr "$val | $or_mask"]
  omap3_WriteDebugRegister $reg_num $val
  omap3_ReadDebugRegister 34
}

proc omap3_TestWaitDebugRegister {reg_num and_mask wait_bits} {
  set val [omap3_ReadDebugRegister $reg_num]
  set val [expr "$val & $and_mask"]
  while { $val == $wait_bits } {
    set val [omap3_ReadDebugRegister $reg_num]
    set val [expr "$val & $and_mask"]
  }
}

proc omap3_ExecuteARMInstruction { instr } {
  # Step 0. Ensure we can execute instructions.
  # Note, setting bit 1 of DSCR restarts the core, so make sure its clear.
  omap3_ReadModifyWriteDebugRegister 34 0xFFFFDFFD 0x00002000

  # Step 1. Poll DSCR until InstrCompl is set to 1.
  puts "Step 1. Poll DSCR until InstrCompl is set to 1."
  omap3_TestWaitDebugRegister 34 (1<<24) 0

  # Step 2. Write the opcode to the ITR.
  puts "Step 2. Write the opcode to the ITR."
  puts [format "  : %#010x" $instr  ]

  omap3_ReadDebugRegister 34
  omap3_WriteDebugRegister 33 $instr
  omap3_ReadDebugRegister 34
  omap3_ReadModifyWriteDebugRegister 34 0xFFFF9FFD 0x00006000

  # Step 3. Poll DSCR until InstrCompl is set to 1.
  puts "Step 3. Poll DSCR until InstrCompl is set to 1."
  omap3_TestWaitDebugRegister 34 (1<<24) 0
}

proc omap3_ReadDCC { } {
  # Step 1. Poll DSCR until DTRRXfull is set to 1.
  puts "Step 1. Poll DSCR until DTRRXfull is set to 1."
  omap3_TestWaitDebugRegister 34 (1<<29) 0

  # Step 2. Read the value from DTRRX.
  puts "Step 2. Read the value from DTRRX."
  omap3_ReadDebugRegister 35
  omap3_ReadDebugRegister 32
}

proc omap3_WriteDCC { dtr_val } {
  # Step 1. Poll DSCR until DTRTXfull is cleared to 0.
  omap3_TestWaitDebugRegister 34 (1<<30) (1<<30)

  # Step 2. Write the value to DTRTX.
  omap3_WriteDebugRegister 32 $dtr_val
}

proc omap3_ReadARMRegister { Rd } {
  # Step 1. Execute instruction MCR p14, 0, Rd, c0, c5, 0 through the ITR.
  omap3_ExecuteARMInstruction [expr "0xEE000E15 + ($Rd<<12)"]
  # Step 2. Read the register value through DTRTX.
  omap3_ReadDCC
}

proc omap3_WriteARMRegister { Rd reg_val } {
  # Step 1. Write the register value to DTRRX.
  omap3_WriteDCC $reg_val
  # Step 2. Execute instruction MRC p14, 0, Rd, c0, c5, 0 to the ITR.
  omap3_ExecuteARMInstruction [expr "0xEE100E15 + ($Rd<<12)"]
}

proc omap3_ReadPC { } {
  # Step 1. Save R0
  set saved_r0 [ omap3_ReadARMRegister 0 ]
  # Step 2. Execute the instruction MOV r0, pc through the ITR.
  omap3_ExecuteARMInstruction 0xE1A0000F
  # Step 3. Read the value of r0 that now contains the PC.
  set pc [ omap3_ReadRegister 0 ]
  # Step 4. Restore the value of R0.
  omap3_WriteARMRegister 0 $saved_r0

  return $pc
}

proc omap3_ReadCPSR { } {
  # Step 1. Save R0.
  set saved_r0 [ omap3_ReadARMRegister 0 ]
  # Step 2. Execute instruction MRS r0, CPSR through the ITR.
  omap3_ExecuteARMInstruction 0xE10F0000
  # Step 3. Read the value of r0 that now contains the CPSR
  set cpsr_val [ omap3_ReadARMRegister 0 ]
  # Step 4. Restore the value of R0.
  omap3_WriteARMRegister 0 $saved_r0
  return $cpsr_val;
}

proc omap3_WriteCPSR { cpsr_val } {
  # Step 1. Save R0.
  set saved_r0 [ omap3_ReadRegister 0 ]
  # Step 2. Write the new CPSR value to r0.
  WriteRegister 0 $cpsr_val
  # Step 3. Execute instruction MSR r0, CPSR through the ITR.
  omap3_ExecuteARMInstruction 0xE12FF000
  # Step 4. Execute a PrefetchFlush instruction through the ITR.
  omap3_ExecuteARMInstruction 0xEE070F95
  # Step 5. Restore the value of r0.
  omap3_WriteARMRegister 0 $saved_r0
}

proc omap3_dbginit { } {
     version
     jtag tapenable omap3.cpu
     target create omap3.cpu cortex_a8 -endian little -chain-position omap3.cpu
     targets

     # The DBGEM signal on the Cortex-A8 is driven by setting bit 0xD401D030 in the DAP-APB address space
     # OMAP35x Applications Processor - spruf98b - 25.6.4
     omap3.cpu mdw 0x5401d030
     omap3.cpu mww 0x5401d030 0x00002000 4
     omap3.cpu mdw 0x5401d030

     # write unlock key to "Lock Access Register" - 12.5.8 Cortex A8 TRM
     omap3_WriteDebugRegister 1004 0xC5ACCE55

     # Read PRSR "Device Power Down and Reset Status Register" twice to clear sticky bits - 12.4.21 Cortex A8 TRM
     omap3_ReadDebugRegister 197
     omap3_ReadDebugRegister 197

}


proc omap3_dump_registers { } {
  puts "ARM STATE:"
  puts [format "  R0 : %#010x" [omap3_ReadARMRegister 0]  ]
  puts [format "  R1 : %#010x" [omap3_ReadARMRegister 1]  ]
  puts [format "  R2 : %#010x" [omap3_ReadARMRegister 2]  ]
  puts [format "  R3 : %#010x" [omap3_ReadARMRegister 3]  ]
  puts [format "  R4 : %#010x" [omap3_ReadARMRegister 4]  ]
  puts [format "  R5 : %#010x" [omap3_ReadARMRegister 5]  ]
  puts [format "  R6 : %#010x" [omap3_ReadARMRegister 6]  ]
  puts [format "  R7 : %#010x" [omap3_ReadARMRegister 7]  ]
  puts [format "  R8 : %#010x" [omap3_ReadARMRegister 8]  ]
  puts [format "  R9 : %#010x" [omap3_ReadARMRegister 9]  ]
  puts [format " R10 : %#010x" [omap3_ReadARMRegister 10]  ]
  puts [format " R11 : %#010x" [omap3_ReadARMRegister 11]  ]
  puts [format " R12 : %#010x" [omap3_ReadARMRegister 12]  ]
  puts [format " R13 : %#010x" [omap3_ReadARMRegister 13]  ]
  puts [format " R14 : %#010x" [omap3_ReadARMRegister 14]  ]
  puts [format " R15 : %#010x" [omap3_ReadARMRegister 15]  ]
# Dont worry about these until R0-R15 can be read OK.
#  puts [format " CPSR: %#010x" [omap3_ReadCPSR] ]
#  puts [format " PC  : %#010x" [omap3_ReadPC] ]
}

proc omap3_halt { } {
  # Set Halting debug-mode in DSCR - 12-22 Cortex A8 R3P0 TRM
  # Note, setting bit 1 of DSCR restarts the core, so make sure its clear.
  omap3_ReadModifyWriteDebugRegister 34 0xFFFFBFFD 0x00004000

  # Set Halt Request in DRCR - 12.4.2 Cortex A8 R3P0 TRM
  omap3_WriteDebugRegister 36 0x9

  # Poll DSCR until Core Halted is 1.
  omap3_TestWaitDebugRegister 34 1 0

  set dscr [omap3_ReadDebugRegister 34]
  omap3_dump_registers
}

proc omap3_restart { } {
  # Set Restart Request in DRCR - 12.4.2 Cortex A8 R3P0 TRM
  omap3_WriteDebugRegister 36 0xA
}

proc omap3_step { } {
}
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to