From 8741c6c1caf2fcb19fb19fe75de54bfa80652a73 Mon Sep 17 00:00:00 2001 From: dodge-this Date: Sat, 4 Sep 2010 06:27:42 +0000 Subject: [PATCH] AT91x40 series of ARM7 microcontrollers supported. still no flash capability yet. working on it. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@720 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- client/GoodFETARM7.py | 20 -- client/GoodFETAT91X40.py | 420 ++++++++++++++++++++++++++++++++++ client/gplay-at91x40.py | 35 +++ firmware/apps/jtag/jtagarm7.c | 8 +- 4 files changed, 459 insertions(+), 24 deletions(-) create mode 100644 client/GoodFETAT91X40.py create mode 100755 client/gplay-at91x40.py diff --git a/client/GoodFETARM7.py b/client/GoodFETARM7.py index 81a8aef..dbf015c 100644 --- a/client/GoodFETARM7.py +++ b/client/GoodFETARM7.py @@ -576,26 +576,6 @@ class GoodFETARM(GoodFET): 0x02 : "force dbgrq", 0x01 : "force dbgack" } - def ARMgetChipID(self): - chipid = self.ARMreadMem(SF_CHIP_ID,1) - return chipid[0] - def ARMwriteFirmware(self, firmware): - self.halt() - chipid = self.ARMgetChipID() - # FIXME: initialize PLL or EBI - self.ARMmassErase(chipid) - self.ARMset_regCPSR(PM_svc) # set supervisor mode - # FIXME: download the "flash identifier" program into target RAM - self.ARMsetPC(PROGGYBASE) - self.release() - # get manufacturer crap through DCC (really?? screw this...) - self.halt() - if (self.ARMget_regCPSR() & PM_svc != PM_svc): - raise Exception("No longer in Supervisor mode after firmware upload") - # FIXME: download the downloader program into target RAM - self.ARMsetPC(PROGGYBASE) - self.release() - # FIXME: use DCC to upload the new firmware def ARMresettarget(self, delay=10): return self.writecmd(0x13,RESETTARGET,2, [ delay&0xff, (delay>>8)&0xff ] ) def ARMchain0(self, address, bits=0x819684c054, data=0): diff --git a/client/GoodFETAT91X40.py b/client/GoodFETAT91X40.py new file mode 100644 index 0000000..04a99e1 --- /dev/null +++ b/client/GoodFETAT91X40.py @@ -0,0 +1,420 @@ +from GoodFETARM7 import * +""" +This is the ARM7 series of microcontrollers from Atmel, including: +* AT91M40800 +* AT91R40807 +* AT91M40807 +* AT91R40008 + +""" +##### FLASH UPLOADER CODE +EBI_BASE = 0xFFE00000 +EBI_OFF_CSR0 = 0x0 +EBI_OFF_CSR1 = 0x4 +EBI_OFF_CSR2 = 0x8 +EBI_OFF_CSR3 = 0xc +EBI_OFF_CSR4 = 0x10 +EBI_OFF_CSR5 = 0x14 +EBI_OFF_CSR6 = 0x18 +EBI_OFF_CSR7 = 0x1c +EBI_CSR0_MASK = 0xFFFF0000 +EBI_OFF_RCR = 0x20 +EBI_OFF_MCR = 0x24 + +EBI_CSR0 = EBI_BASE + EBI_OFF_CSR0 +EBI_CSR1 = EBI_BASE + EBI_OFF_CSR1 +EBI_CSR2 = EBI_BASE + EBI_OFF_CSR2 +EBI_CSR3 = EBI_BASE + EBI_OFF_CSR3 +EBI_CSR4 = EBI_BASE + EBI_OFF_CSR4 +EBI_CSR5 = EBI_BASE + EBI_OFF_CSR5 +EBI_CSR6 = EBI_BASE + EBI_OFF_CSR6 +EBI_CSR7 = EBI_BASE + EBI_OFF_CSR7 +EBI_MCR = EBI_BASE + EBI_OFF_MCR + +REMAP_CMD = 0x00000001 +MEM_CTRL_VAL = 0x00000006 + + +SF_CHIP_ID = 0xFFF00000 # AT91R40 series, not sure on others +SF_CIDR_MASK = 0x0FFFFF00 + +PS_BASE = 0xFFFF4000 +PS_CR = PS_BASE +PS_PCER = PS_BASE + 0x4 +PS_PCDR = PS_BASE + 0x8 +PS_PCSR = PS_BASE + 0xC +PS_US0 = 1<<2 +PS_US1 = 1<<3 +PS_TC0 = 1<<4 +PS_TC1 = 1<<5 +PS_TC2 = 1<<6 +PS_PIO = 1<<8 + +AIC_INT_SOURCES = ( + ("FIQ","Fast Interrupt"), + ("SWIRQ","Software Interrupt"), + ("US0IRQ","USART Channel 0 Interrupt"), + ("US1IRQ","USART Channel 1 Interrupt"), + ("TC0IRQ","Timer Channel 0 Interrupt"), + ("TC1IRQ","Timer Channel 1 Interrupt"), + ("TC2IRQ","Timer Channel 2 Interrupt"), + ("WDIRQ", "Watchdog Interrupt"), + ("PIOIRQ","Parallel I/O Controller Interrupt"), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + ("IRQ0","External Interrupt 0"), + ("IRQ1","External Interrupt 0"), + ("IRQ0","External Interrupt 0"), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + (None,None), + ) + +def aic_smr_decode(smr): + output = ["Interrupt Priority: %s"%(smr&7), + "Interrupt Source Type: %s"%("Low Level Sensitive","Negative Edge Triggered","High Level Sensitive","Positive Edge Triggered")[(smr>>5)], + ] + return "\n".join(output) + +AIC_BASE = 0xFFFFF000 +AIC_SMR = [(AIC_BASE+(x*4), "Source Mode Register %d"%x) for x in xrange(32)] +AIC_SVR = [(AIC_BASE+0x80+(x*4), "Source Vector Register %d"%x) for x in xrange(32)] +AIC_IVR = AIC_BASE + 0x100 +AIC_FVR = AIC_BASE + 0x104 +AIC_ISR = AIC_BASE + 0x108 +AIC_IPR = AIC_BASE + 0x10c +AIC_IMR = AIC_BASE + 0x110 +AIC_CISR = AIC_BASE + 0x114 +AIC_IECR = AIC_BASE + 0x120 +AIC_IDCR = AIC_BASE + 0x124 +AIC_ICCR = AIC_BASE + 0x128 +AIC_ISCR = AIC_BASE + 0x12c +AIC_EOICR = AIC_BASE + 0x130 +AIC_SPU = AIC_BASE + 0x134 + + +PIO_BASE = 0xFFFF0000 +PIO_PER = PIO_BASE + 0x0 +PIO_PDR = PIO_BASE + 0x4 +PIO_PSR = PIO_BASE + 0x8 +PIO_OER = PIO_BASE + 0x10 +PIO_ODR = PIO_BASE + 0x14 +PIO_OSR = PIO_BASE + 0x18 +PIO_SODR = PIO_BASE + 0x30 +PIO_CODR = PIO_BASE + 0x34 +PIO_ODSR = PIO_BASE + 0x38 +PIO_CDSR = PIO_BASE + 0x3c +PIO_IER = PIO_BASE + 0x40 +PIO_IDR = PIO_BASE + 0x44 +PIO_IMR = PIO_BASE + 0x48 +PIO_ISR = PIO_BASE + 0x4c + +WD_BASE = 0xFFFF8000 +WD_OMR = WD_BASE + 0x0 +WD_CMR = WD_BASE + 0x4 +WD_CR = WD_BASE + 0x8 +WD_SR = WD_BASE + 0xc + +SF_BASE = 0xFFF00000 +SF_CIDR = SF_BASE + 0x0 +SF_EXID = SF_BASE + 0x4 +SF_RSR = SF_BASE + 0x8 +SF_MMR = SF_BASE + 0xC +SF_PMR = SF_BASE + 0x18 + +#* Flash +FLASH_BASE_ADDR = 0x1000000 +WAIT = 300000 +FLASH_CODE_MASK = 0x000000FF + +#*Flash AT49 codes +ATMEL_MANUFACTURED = 0x001F +FLASH_AT49BV_UNKNOW = 0xFFFF +FLASH_AT49BV8011 = 0x00CB +FLASH_AT49BV8011T = 0x004A +FLASH_AT49BV16x4 = 0x00C0 +FLASH_AT49BV16x4T = 0x00C2 + +#*Flash AT29 codes +FLASH_AT29LV1024 = 0X26 +FLASH_AT29C020 = 0XDA + +#* Flash Program information +FLASH_PRG_SIZE = 0x800 #* 2Kbytes +FLASH_PRG_DEST = 0x20 #* Address on the target +START_PRG = 0x20 + +#* Parameter for Flash_XV_Send_Data functions +ERASE = 1 +PROGRAM =0 + +MIRROR = 1 +NO_MIRROR = 0 + +ERASE_DATA = 0 + +#* Load program parameters +NB_REG = 13 +SIZE_DATA = 4 + +#* Flash LV Send Data parameters +SIZE_256_BYTES = 0x100 +PACKET_SIZE =64 + +NB_PRG = 3 + +#* Periph +EBI = 0 +PLL = 1 + +#* Targets +EB40 = 0x04080700 +EB40A = 0x04000800 +EB42 = 0x04280000 +EB55 = 0x05580000 +EB63 = 0x06320000 +EBMASK = 0x0fffff00 + +NB_TARGET_SUPPORTED = 6 + +#* Flash type +FLASH_LV = 0 +FLASH_BV = 1 + +#* Flash Program Address +FLASH_LV_PRG = 0x01018000 +FLASH_BV_PRG = 0x0101A000 + +EBI_READ = 4 +EBI_WRITE = 2 + +ebi_memory_map_items = { + EBI_OFF_CSR0:("Chip Select Register 0", "EBI_CSR0", EBI_READ|EBI_WRITE,0x0000203e), + EBI_OFF_CSR1:("Chip Select Register 1", "EBI_CSR1", EBI_READ|EBI_WRITE,0x10000000), + EBI_OFF_CSR2:("Chip Select Register 2", "EBI_CSR2", EBI_READ|EBI_WRITE,0x20000000), + EBI_OFF_CSR3:("Chip Select Register 3", "EBI_CSR3", EBI_READ|EBI_WRITE,0x30000000), + EBI_OFF_CSR4:("Chip Select Register 4", "EBI_CSR4", EBI_READ|EBI_WRITE,0x40000000), + EBI_OFF_CSR5:("Chip Select Register 5", "EBI_CSR5", EBI_READ|EBI_WRITE,0x50000000), + EBI_OFF_CSR6:("Chip Select Register 6", "EBI_CSR6", EBI_READ|EBI_WRITE,0x60000000), + EBI_OFF_CSR7:("Chip Select Register 7", "EBI_CSR7", EBI_READ|EBI_WRITE,0x70000000), + EBI_OFF_MCR: ("Memory Control Register","EBI_MCR", EBI_READ|EBI_WRITE,0), + } + +def ebi_csr_decode(reg): + addr = reg>>20 + csen = (reg>>13)&1 + bat = (reg>>12)&1 + tdf = (reg>>9)&7 + pages =(reg>>7)&3 + wse = (reg>>5)&1 + nws = (reg>>2)&7 + dbw = (reg&3) + output = ["Base Address: %s"%hex(addr), + "Chip Select: %s"%("False","True")[csen], + "Byte Access Type: %s"%("Byte-Write","Byte-Access")[bat], + "Data Float Output Time: %d cycles added"%tdf, + "Page Size: %d MB"%(1,4,16,64)[pages], + "Wait State: %s"%("disabled","enabled")[wse], + "Wait States: %d"%nws, + "Data Bus Size: %d bits"%dbw, + ] + return "\n".join(output) + +mcr_ale = { + 0: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"), + 1: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"), + 2: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"), + 3: ("A20,A21,A22,A23", 16, "None", "EBI_ALE_16M"), + 4: ("A20,A21,A22", 8, "CS4", "EBI_ALE_8M"), + 5: ("A20,A21", 4, "CS4,CS5", "EBI_ALE_4M"), + 6: ("A20", 2, "CS4,CS5,CS6", "EBI_ALE_2M"), + 7: ("None", 1, "CS4,CS5,CS6,CS7", "EBI_ALE_1M"), + } + +def mcr_decode(mcr): + validAddrBits,maxAddrSpace,validCS,codeLabel = mcr_decode[mcr&7] + drp = mcr>>4 + output = ["Valid Address Bits: %s"%validAddrBits, + "Maximum Address Space: %xMB"%maxAddrSpace, + "Valid Chip Select: %s"%validCS, + "Code Label: %s"%codeLabel, + ("Standard Read Protocol for all external memory devices enabled (EBI_DRP_STANDARD)","Early Read Protocol for all external memory devices enabled (EBI_DRP_EARLY)")[drp] + ] + return "\n".join(output) + +def wd_omr_decode(omr): + return "\n".join(["External Signal: %s"%("disabled","enabled")[(omr>>3)&1], + "External Signal: %s"%("disabled","enabled")[(omr>>3)&1], + "Interrupt: %s"%("disabled","enabled")[(omr>>2)&1], + "Reset: %s"%("disabled","enabled")[(omr>>1)&1], + "Watch Dog: %s"%("disabled","enabled")[(omr)&1], + ]) +def wd_cmr_decode(cmr): + return "MCK/%d"%(8,32,128,1024)[(cmr>>2)&0xf] + + + + + +class GoodFETAT91X40(GoodFETARM): + def getChipSelectReg(self, chipnum): + addr = EBI_BASE + (chipnum*4) + reg, = self.ARMreadMem(addr,1) + return reg + def getChipSelectRegstr(self, chipnum): + return ebi_csr_decode(self.getChipSelectReg(chipnum)) + + def getEBIMemoryMap(self): + keys = ebi_memory_map_items.keys() + keys.sort() + output = [ "EBI Memory Map"] + for x in xrange(8): + desc,name,rw,default = ebi_memory_map_items[x*4] + output.append("\nMAP: %s (%s) - default: %x\n%s"%(name,desc,default,self.getChipSelectRegstr(x))) + return "\n".join(output) + def getMemoryControlRegister(self): + mcr = self.ARMreadMem(EBI_MCR) + return mcr + def getMemoryControlRegisterstr(self): + return mcr_decode(self.getMemoryControlRegister()) + + def getInterruptSourceModeReg(self, regnum): + regval = self.ARMreadMem(AIC_SMR[regnum][0]) + return retval + def getInterruptSourceModeRegstr(self, regnum): + return aic_smr_decode(self.getInterruptSourceModeReg(regnum)) + def setInterruptSourceModeReg(self, regnum, val): + self.ARMwriteMem(AIC_SMR[regnum][0], val) + + def getInterruptSourceVectorReg(self, regnum): + regval = self.ARMreadMem(AIC_SVR[regnum][0]) + return retval + def setInterruptSourceModeReg(self, regnum, val): + self.ARMwriteMem(AIC_SVR[regnum][0], val) + + def getIRQVectorReg(self): + return self.ARMreadMem(AIC_IVR) + def getFIQVectorReg(self): + return self.ARMreadMem(AIC_FVR) + + def getInterruptStatusReg(self): + return self.ARMreadMem(AIC_ISR) + def getInterruptPendingReg(self): + return self.ARMreadMem(AIC_FSR) + def getInterruptMaskReg(self): + return self.ARMreadMem(AIC_IMR) + def getCoreInterruptStatusReg(self): + return self.ARMreadMem(AIC_CISR) + def enableInterrupt(self, interrupt): + self.ARMwriteMem(AIC_IECR, 1<>sys.stderr,"Connecting to goodfet..." + client.serInit() + # + #Connect to target + print >>sys.stderr,"Setting up JTAG ARM on goodfet..." + client.setup() + print >>sys.stderr,"Starting JTAG ARM on goodfet..." + client.start() + print "STARTUP: "+repr(client.data) + # + +def print_registers(): + return [ hex(client.ARMget_register(x)) for x in range(15) ] + + +init() +print "Don't forget to 'client.stop()' if you want to exit cleanly" + + +def printResults(): + for y in range(len(results)): + x=results[y] + print "%.2x=%s"%(y,repr(["%x"%t for t in x])) + diff --git a/firmware/apps/jtag/jtagarm7.c b/firmware/apps/jtag/jtagarm7.c index f674510..cd9bf63 100644 --- a/firmware/apps/jtag/jtagarm7.c +++ b/firmware/apps/jtag/jtagarm7.c @@ -154,7 +154,7 @@ void jtagarm7_set_reg_prim(unsigned long instr, unsigned long reg, unsigned long jtagarm7tdmi_nop( 0); // push nop into pipeline - execute jtagarm7tdmi_instr_primitive(val, 0); // push 32-bit word on data bus if (reg == ARM_REG_PC){ - debugstr("setting pc..."); + //debugstr("setting pc..."); jtagarm7tdmi_nop( 0); // push nop into pipeline - refill jtagarm7tdmi_nop( 0); // push nop into pipeline - refill } @@ -167,10 +167,10 @@ void jtagarm7_thumb_swap_reg(unsigned char dir, unsigned long reg){ jtagarm7tdmi_nop( 0); if (dir){ jtagarm7tdmi_instr_primitive((unsigned long)(THUMB_INSTR_MOV_LoHi | (reg) | (reg<<16)), 0); - debughex32((unsigned long)(THUMB_INSTR_MOV_LoHi | (reg) | (reg<<16))); + //debughex32((unsigned long)(THUMB_INSTR_MOV_LoHi | (reg) | (reg<<16))); } else { jtagarm7tdmi_instr_primitive((unsigned long)(THUMB_INSTR_MOV_HiLo | (reg<<3) | (reg<<19)), 0); - debughex32((unsigned long)(THUMB_INSTR_MOV_HiLo | (reg<<3) | (reg<<19))); + //debughex32((unsigned long)(THUMB_INSTR_MOV_HiLo | (reg<<3) | (reg<<19))); } jtagarm7tdmi_nop( 0); jtagarm7tdmi_nop( 0); @@ -182,7 +182,7 @@ unsigned long jtagarm7tdmi_get_register(unsigned long reg) { current_dbgstate = eice_read(EICE_DBGSTATUS); if (current_dbgstate & JTAG_ARM7TDMI_DBG_TBIT){ if (reg > 7){ - debugstr("debug: jtagarm7tdmi_get_register: thumb reg > 15"); + //debugstr("debug: jtagarm7tdmi_get_register: thumb reg > 15"); reg = reg & 7; r0 = jtagarm7_get_reg_prim( THUMB_READ_REG); // save reg0 jtagarm7_thumb_swap_reg(THUMB_SWAP_HiLo, reg); // clobber reg0 with hi reg -- 2.20.1