; Copyright 2011 Castle Technology Ltd ; ; 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. ; GET Hdr:ListOpts GET Hdr:Macros GET Hdr:System GET Hdr:Machine. GET Hdr:HALSize. GET Hdr:MEMM.VMSAv6 GET Hdr:Proc GET Hdr:OSEntries GET Hdr:HALEntries GET hdr.omap4430 GET hdr.StaticWS GET hdr.SDRC GET hdr.Interrupts GET hdr.Timers GET hdr.GPIO GET hdr.UART GET hdr.PRCM GET hdr.GPMC ; This version assumes a RISC OS image starting OSROM_HALSize after us. ; FIQs are not available on Cortex-A9 (outside the secure world) ; FIQ-based debugger - prints out the PC when the beagleboard/touchbook USER button is pressed ; The code installs itself when HAL_InitDevices is called with R0=123. ; e.g. SYS "OS_Hardware",123,,,,,,,,0,100 GBLL FIQDebug FIQDebug SETL {FALSE} GBLL MoreDebug MoreDebug SETL Debug :LAND: {FALSE} GBLL UseSR44x UseSR44x SETL {TRUE} AREA |Asm$$Code|, CODE, READONLY, PIC EXPORT rom_checkedout_ok IMPORT HAL_Base IMPORT DebugHALPrint IMPORT DebugHALPrintReg IMPORT DebugHALPrintByte IMPORT RTC_Init IMPORT DebugCallstack IMPORT SR44x_Init IMPORT SR44x_Exit IMPORT PowerCtrl_Init IMPORT PowerCtrl_SwitchOff ; v8 is used as pointer to RISC OS entry table throughout pre-MMU stage. MACRO CallOSM $entry, $reg LDR ip, [v8, #$entry*4] MOV lr, pc ADD pc, v8, ip MEND rom_checkedout_ok ; On entry, v8 -> OS entry table, sb -> board config ; Register the attached RAM LDR v1, =DMM_Base MOV sp, #0 ; Check all DMM_LISA_MAP_i registers (starting with highest priority) LDR a1, =DMM_LISA_MAP_3 LDR a4, =DMM_LISA_MAP_i_SDRC_ADDRSPC 05 LDR a2, =DMM_LISA_MAP_i_SDRC_MAP LDR a3, [v1, a1] ANDS a2, a3, a2 ; MAP_x used ? BEQ %FT10 AND a2, a3, a4 ; check ADDRSPC CMP a2, #DMM_LISA_MAP_i_SDRC_ADDRSPC_SDRAM BEQ %FT15 10 ; Next DMM_LISA_MAP_x CMP a1, #DMM_LISA_MAP_0 SUBHI a1, a1, #4 BHI %BT05 ; This should not happen: no RAM found B . 15 ; Check DMM_LISA_MAP_x LDR a2, =DMM_LISA_MAP_i_SYS_SIZE AND a2, a3, a2 MOV a2, a2, LSR #DMM_LISA_MAP_i_SYS_SIZE_SHIFT LDR a4, =(16 * 1024 * 1024) ; 16 MiB smallest size MOV a4, a4, LSL a2 ; final size AND a2, a3, #DMM_LISA_MAP_i_SYS_ADDR ; Check for overflow of address range ADDS a3, a4, a2 LDRCS a3, =((4096 - 16) << 20) ; round down to next 16 MiB boundary LDR a4, =&FFFFFFFF ADD sp, a2, #4096 ; HAL spec says that (for software reset compliance only?) stack should be 4K into first block MOV a1, #0 STR a1, [sp, #-4]! CallOSM OS_AddRAM DebugChar a3,a2,71 ; Check for reset cause: test PRM_RSTST.GLOBAL_COLD_RST LDR a3, =L4_PowerMan ADD a3, a3, #DEVICE_PRM LDR a2, [a3, #PRM_RSTST] STR a2, [a3, #PRM_RSTST] ; clear old status TST a2, #1 ; GLOBAL_COLD_RST MOV a4, a1 MOVNE a1, #(OSStartFlag_RAMCleared :OR: OSStartFlag_POR) MOVEQ a1, #OSStartFlag_RAMCleared ADRL a2, HAL_Base + OSROM_HALSize ; a2 -> RISC OS image ADR a3, HALdescriptor CallOSM OS_Start HALdescriptor DATA DCD HALFlag_NCNBWorkspace DCD HAL_Base - HALdescriptor DCD OSROM_HALSize DCD HAL_EntryTable - HALdescriptor DCD HAL_Entries DCD HAL_WsSize MACRO HALEntry $name ASSERT (. - HAL_EntryTable) / 4 = EntryNo_$name DCD $name - HAL_EntryTable MEND MACRO NullEntry DCD HAL_Null - HAL_EntryTable MEND IMPORT Video_Init IMPORT Interrupt_Init IMPORT Timer_Init IMPORT PRCM_SetClocks IMPORT USB_Init IMPORT I2C_Init IMPORT SDMA_Init IMPORT VideoDevice_Init IMPORT Audio_Init IMPORT GPMC_Init IMPORT GPIO_Init IMPORT GPIOx_SetAsOutput IMPORT GPIO_InitDevice IMPORT SDIO_InitDevices IMPORT NVMemory_Init IMPORT NVMemory_InitDevice EXPORT Board_InitDevices_None EXPORT Board_InitDevices_Panda IMPORT HAL_IRQEnable IMPORT HAL_IRQDisable IMPORT HAL_IRQClear IMPORT HAL_IRQSource IMPORT HAL_IRQStatus IMPORT HAL_FIQEnable IMPORT HAL_FIQDisable IMPORT HAL_FIQDisableAll IMPORT HAL_FIQClear IMPORT HAL_FIQSource IMPORT HAL_FIQStatus IMPORT HAL_IRQMax IMPORT HAL_Timers IMPORT HAL_TimerDevice IMPORT HAL_TimerGranularity IMPORT HAL_TimerMaxPeriod IMPORT HAL_TimerSetPeriod IMPORT HAL_TimerPeriod IMPORT HAL_TimerReadCountdown IMPORT HAL_CounterRate IMPORT HAL_CounterPeriod IMPORT HAL_CounterRead IMPORT HAL_CounterDelay IMPORT HAL_IICBuses IMPORT HAL_IICType IMPORT HAL_IICDevice IMPORT HAL_IICTransfer IMPORT HAL_IICMonitorTransfer IMPORT HAL_NVMemoryType IMPORT HAL_NVMemorySize IMPORT HAL_NVMemoryPageSize IMPORT HAL_NVMemoryProtectedSize IMPORT HAL_NVMemoryProtection IMPORT HAL_NVMemoryRead IMPORT HAL_NVMemoryWrite IMPORT HAL_VideoIICOp ; Implemented in s.I2C IMPORT HAL_UARTPorts IMPORT HAL_UARTStartUp IMPORT HAL_UARTShutdown IMPORT HAL_UARTFeatures IMPORT HAL_UARTReceiveByte IMPORT HAL_UARTTransmitByte IMPORT HAL_UARTLineStatus IMPORT HAL_UARTInterruptEnable IMPORT HAL_UARTRate IMPORT HAL_UARTFormat IMPORT HAL_UARTFIFOSize IMPORT HAL_UARTFIFOClear IMPORT HAL_UARTFIFOEnable IMPORT HAL_UARTFIFOThreshold IMPORT HAL_UARTInterruptID IMPORT HAL_UARTBreak IMPORT HAL_UARTModemControl IMPORT HAL_UARTModemStatus IMPORT HAL_UARTDevice IMPORT HAL_UARTDefault IMPORT HAL_DebugRX IMPORT HAL_DebugTX IMPORT HAL_ATAControllerInfo IMPORT HAL_KbdScanSetup IMPORT HAL_KbdScan IMPORT HAL_KbdScanFinish IMPORT HAL_KbdScanInterrupt IMPORT HAL_USBControllerInfo HAL_EntryTable DATA HALEntry HAL_Init HALEntry HAL_IRQEnable HALEntry HAL_IRQDisable HALEntry HAL_IRQClear HALEntry HAL_IRQSource HALEntry HAL_IRQStatus HALEntry HAL_FIQEnable HALEntry HAL_FIQDisable HALEntry HAL_FIQDisableAll HALEntry HAL_FIQClear HALEntry HAL_FIQSource HALEntry HAL_FIQStatus HALEntry HAL_Timers HALEntry HAL_TimerDevice HALEntry HAL_TimerGranularity HALEntry HAL_TimerMaxPeriod HALEntry HAL_TimerSetPeriod HALEntry HAL_TimerPeriod HALEntry HAL_TimerReadCountdown HALEntry HAL_CounterRate HALEntry HAL_CounterPeriod HALEntry HAL_CounterRead HALEntry HAL_CounterDelay HALEntry HAL_NVMemoryType HALEntry HAL_NVMemorySize HALEntry HAL_NVMemoryPageSize HALEntry HAL_NVMemoryProtectedSize HALEntry HAL_NVMemoryProtection NullEntry ; HAL_NVMemoryIICAddress HALEntry HAL_NVMemoryRead HALEntry HAL_NVMemoryWrite HALEntry HAL_IICBuses HALEntry HAL_IICType NullEntry ; HAL_IICSetLines NullEntry ; HAL_IICReadLines HALEntry HAL_IICDevice HALEntry HAL_IICTransfer HALEntry HAL_IICMonitorTransfer NullEntry ; HALEntry HAL_VideoFlybackDevice NullEntry ; HALEntry HAL_VideoSetMode NullEntry ; HALEntry HAL_VideoWritePaletteEntry NullEntry ; HALEntry HAL_VideoWritePaletteEntries NullEntry ; HALEntry HAL_VideoReadPaletteEntry NullEntry ; HALEntry HAL_VideoSetInterlace NullEntry ; HALEntry HAL_VideoSetBlank NullEntry ; HALEntry HAL_VideoSetPowerSave NullEntry ; HALEntry HAL_VideoUpdatePointer NullEntry ; HALEntry HAL_VideoSetDAG NullEntry ; HALEntry HAL_VideoVetMode NullEntry ; HALEntry HAL_VideoPixelFormats NullEntry ; HALEntry HAL_VideoFeatures NullEntry ; HALEntry HAL_VideoBufferAlignment NullEntry ; HALEntry HAL_VideoOutputFormat NullEntry ; HALEntry HAL_MatrixColumns NullEntry ; HALEntry HAL_MatrixScan NullEntry ; HALEntry HAL_TouchscreenType NullEntry ; HALEntry HAL_TouchscreenRead NullEntry ; HALEntry HAL_TouchscreenMode NullEntry ; HALEntry HAL_TouchscreenMeasure HALEntry HAL_MachineID HALEntry HAL_ControllerAddress HALEntry HAL_HardwareInfo HALEntry HAL_SuperIOInfo HALEntry HAL_PlatformInfo NullEntry ; HALEntry HAL_CleanerSpace HALEntry HAL_UARTPorts HALEntry HAL_UARTStartUp HALEntry HAL_UARTShutdown HALEntry HAL_UARTFeatures HALEntry HAL_UARTReceiveByte HALEntry HAL_UARTTransmitByte HALEntry HAL_UARTLineStatus HALEntry HAL_UARTInterruptEnable HALEntry HAL_UARTRate HALEntry HAL_UARTFormat HALEntry HAL_UARTFIFOSize HALEntry HAL_UARTFIFOClear HALEntry HAL_UARTFIFOEnable HALEntry HAL_UARTFIFOThreshold HALEntry HAL_UARTInterruptID HALEntry HAL_UARTBreak HALEntry HAL_UARTModemControl HALEntry HAL_UARTModemStatus HALEntry HAL_UARTDevice HALEntry HAL_Reset HALEntry HAL_DebugRX HALEntry HAL_DebugTX NullEntry ; HAL_PCIFeatures NullEntry ; HAL_PCIReadConfigByte NullEntry ; HAL_PCIReadConfigHalfword NullEntry ; HAL_PCIReadConfigWord NullEntry ; HAL_PCIWriteConfigByte NullEntry ; HAL_PCIWriteConfigHalfword NullEntry ; HAL_PCIWriteConfigWord NullEntry ; HAL_PCISpecialCycle NullEntry ; HAL_PCISlotTable NullEntry ; HAL_PCIAddresses HALEntry HAL_ATAControllerInfo NullEntry ; HAL_ATASetModes NullEntry ; HAL_ATACableID HALEntry HAL_InitDevices HALEntry HAL_KbdScanSetup HALEntry HAL_KbdScan HALEntry HAL_KbdScanFinish HALEntry HAL_KbdScanInterrupt HALEntry HAL_PhysInfo HALEntry HAL_USBControllerInfo HALEntry HAL_IRQMax NullEntry ; HAL_VideoRender NullEntry ; HAL_USBPortPower NullEntry ; HAL_USBPortStatus NullEntry ; HAL_USBPortDevice HALEntry HAL_VideoIICOp NullEntry ; HAL_TimerIRQClear NullEntry ; HAL_TimerIRQStatus HALEntry HAL_ExtMachineID NullEntry ; HAL_VideoFramestoreAddress HALEntry HAL_UARTDefault HAL_Entries * (. - HAL_EntryTable) / 4 ;-------------------------------------------------------------------------------------- HAL_Init Entry "v1-v3" STR a2, NCNBWorkspace STR a2, NCNBAllocNext BL SetUpOSEntries ; Map in the main IO ranges (L3, L4) and then store the offsets to the components ; we're interested in MOV a1, #0 LDR a2, =L3_ABE MOV a3, #L3_ABE_Size CallOS OS_MapInIO STR a1, L3_Log MOV a1, #0 LDR a2, =L4_ABE MOV a3, #L4_ABE_Size CallOS OS_MapInIO STR a1, L4_ABE_Log ; Timers ADD a2, a1, #(TIMER_BASE - L4_ABE) STR a2, Timers_Log MOV a1, #0 LDR a2, =L4_Core MOV a3, #L4_Core_Size CallOS OS_MapInIO STR a1, L4_Core_Log ; ClockMan + ClockMan2 ADD a3, a1, #(L4_ClockMan - L4_Core) STR a3, L4_ClockMan_Log ADD a3, a1, #(L4_ClockMan2 - L4_Core) STR a3, L4_ClockMan2_Log ; USB ADD a3, a1, #(L4_USBTLL - L4_Core) STR a3, L4_USBTLL_Log ADD a3, a1, #(L4_USB_Host - L4_Core) STR a3, L4_USB_Host_Log ADD a3, a1, #(L4_USB_OTG - L4_Core) STR a3, L4_USB_OTG_Log ; DMA ADD a3, a1, #(L4_sDMA - L4_Core) STR a3, L4_sDMA_Log MOV a1, #0 LDR a2, =L4_Wakeup MOV a3, #L4_Wakeup_Size CallOS OS_MapInIO STR a1, L4_Wakeup_Log ; L4_PowerMan, L4_32KTIMER, L4_GPIO1 ADD a3, a1, #(L4_PowerMan - L4_Wakeup) STR a3, L4_PowerMan_Log ADD a3, a1, #(L4_32KTIMER - L4_Wakeup) STR a3, L4_32KTIMER_Log ADD a3, a1, #(L4_GPIO1 - L4_Wakeup) STR a3, L4_GPIO1_Log MOV a1, #0 LDR a2, =L4_Per MOV a3, #L4_Per_Size CallOS OS_MapInIO STR a1, L4_Per_Log ; this address range is only for backward compatibility ! ; TI recommends using the DSS address range ; ; Display ; ADD a3, a1, #(L4_Display - L4_Per) ; STR a3, L4_Display_Log ; GPIO2-6 ADD a2, a1, #(L4_GPIO2 - L4_Per) STR a2, L4_GPIO2_Log ADD a2, a1, #(L4_GPIO3 - L4_Per) STR a2, L4_GPIO3_Log ADD a2, a1, #(L4_GPIO4 - L4_Per) STR a2, L4_GPIO4_Log ADD a2, a1, #(L4_GPIO5 - L4_Per) STR a2, L4_GPIO5_Log ADD a2, a1, #(L4_GPIO6 - L4_Per) STR a2, L4_GPIO6_Log ; Display subsystem (DSS) MOV a1, #0 LDR a2, =DSS_Base MOV a3, #(32 * 1024) CallOS OS_MapInIO STR a1, L4_Display_Log ; Interrupt controller MOV a1, #0 LDR a2, =MPU_INTC MOV a3, #MPU_INTC_SIZE CallOS OS_MapInIO STR a1, MPU_INTC_Log ; GPMC MOV a1, #0 LDR a2, =GPMC_Regs MOV a3, #4096 ; only a small register file CallOS OS_MapInIO STR a1, GPMC_Regs_Log ; Recover board config from SRAM MOV a1, #0 LDR a2, =IntSRAM_Base MOV a3, #IntSRAM_Size CallOS OS_MapInIO STR a1, IntSRAM_Log MOV a2, #BoardConfig_Size 10 SUBS a2, a2, #4 LDR a3, [a1, a2] STR a3, [sb, a2] BGT %BT10 ; Now do phys -> log conversion on all the addresses contained within ; RISC OS doesn't currently provide a phys->log conversion function, so we do it ; manually based around the regions that were mapped in above ASSERT BoardConfig_DebugUART = 0 ASSERT BoardConfig_DebugUART+4 = BoardConfig_HALUART MOV a1, #(BoardConfig_HALUART + ?BoardConfig_HALUART-4) 10 BL phys2log SUBS a1, a1, #4 BGE %BT10 ; handle supported I2C interfaces (at most MaxI2CControllers) LDRB v1, [sb, #BoardConfig_NumI2C] CMP v1, #MaxI2CControllers MOVGT v1, #MaxI2CControllers ADR v2, (I2C_Table + I2C_HW) MOV a1, #BoardConfig_HALI2C 10 BL phys2log STR a2, [v2], #I2CBlockSize ADD a1, a1, #4 SUBS v1, v1, #1 BGT %BT10 [ Debug DebugTX "HAL_Init" DebugTime a1, "@ " ] BL PRCM_SetClocks ; Calls Timer_init & starts GPTIMER5 BL I2C_Init ; Uses GPTIMER5 ; Make sure all GPIO IRQs are disabled before we potentially start enabling them BL GPIO_Init [ MoreDebug DebugTX "Video_Init" ] ; MoreDebug BL Video_Init [ MoreDebug DebugTX "USB_Init" ] ; MoreDebug BL USB_Init [ MoreDebug DebugTX "NVMemory_Init" ] ; MoreDebug BL NVMemory_Init [ MoreDebug DebugTX "Timer_Init" ] ; MoreDebug BL Timer_Init ; Re-inits timers [ MoreDebug DebugTX "Interrupt_Init" ] ; MoreDebug BL Interrupt_Init [ MoreDebug DebugTX "GPMC_Init" ] ; MoreDebug BL GPMC_Init LDRB v1, [sb, #BoardConfig_NumUART] 10 SUBS v1, v1, #1 [ Debug BLT %FT20 ; Don't reset the debug UART LDR a3, [sb, #BoardConfig_DebugUART] ADD a2, sb, v1, LSL #2 LDR a2, [a2, #BoardConfig_HALUART] CMP a3, a2 BEQ %BT10 MOV a1, v1 ADR lr, %BT10 B HAL_UARTStartUp | MOVGE a1, v1 ADRGE lr, %BT10 BGE HAL_UARTStartUp ] 20 ; Mark HAL as initialised STR pc, HALInitialised ; Any nonzero value will do DebugTime a1, "HAL initialised @ " EXIT ; Dodgy phys->log conversion using the mapped in IO ranges ; In/out: a1 = offset into sb of address to get/put ; Out: a2 = log addr ; Corrupts a3 phys2log LDR a3, [sb, a1] CMP a3, #0 ; Null pointers are valid; ignore them MOVEQ a2, #0 MOVEQ pc, lr LDR a2, =L3_ABE SUB a2, a3, a2 CMP a2, #L3_ABE_Size LDRLO a3, L3_Log BLO %FT10 SUB a2, a3, #L4_Per CMP a2, #L4_Per_Size LDRLO a3, L4_Per_Log BLO %FT10 SUB a2, a3, #L4_ABE CMP a2, #L4_ABE_Size LDRLO a3, L4_ABE_Log BLO %FT10 SUB a2, a3, #L4_Core CMP a2, #L4_Core_Size LDRLO a3, L4_Core_Log SUBHI a2, a2, #(L4_Wakeup - L4_Core) LDRHI a3, L4_Wakeup_Log 10 ADD a2, a2, a3 STR a2, [sb, a1] MOV pc, lr ; Initialise and relocate the entry table. SetUpOSEntries ROUT STR a1, OSheader LDR a2, [a1, #OSHdr_NumEntries] CMP a2, #(HighestOSEntry + 1) MOVHI a2, #(HighestOSEntry + 1) ADR a3, OSentries LDR a4, [a1, #OSHdr_Entries] ADD a4, a4, a1 05 SUBS a2, a2, #1 LDR ip, [a4, a2, LSL #2] ADD ip, ip, a4 STR ip, [a3, a2, LSL #2] BNE %BT05 ; Fall through HAL_Null MOV pc, lr HAL_InitDevices [ FIQDebug CMP a1, #123 BNE %FT10 LDR a1, =&E51FF004 ADR a2, FIQRoutine MOV a4, #&1C STMIA a4,{a1-a2,sb} ; Sync cache MOV a1, #0 MCR p15, 0, a1, c7, c11, 1 ; Clean DCache by VA to PoU DSB SY ; wait for clean to complete MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry (to PoC) MCR p15, 0, a1, c7, c5, 6 ; invalidate entire BTC DSB SY ; wait for cache invalidation to complete ISB SY ; wait for BTC invalidation to complete? ; Now reconfigure the USER button (GPIO 7) to fire an FIQ LDR a1, L4_GPIO1_Log LDR a2, [a1, #GPIO_OE] ORR a2, a2, #1:SHL:7 ; Configure as input STR a2, [a1, #GPIO_OE] MOV a2, #0 STR a2, [a1, #GPIO_LEVELDETECT0] STR a2, [a1, #GPIO_LEVELDETECT1] STR a2, [a1, #GPIO_FALLINGDETECT] MOV a2, #1:SHL:7 STR a2, [a1, #GPIO_RISINGDETECT] ; Enable IRQ on rising edge STR a2, [a1, #GPIO_IRQENABLE1] ; Set MPU as interrupt target MOV a1, #29 ; GPIO1 IRQ ; tail-optimised, repeating the HAL device init would be a bad thing! B HAL_FIQEnable 10 ] Entry "v1-v3" DebugTime a1, "HAL_InitDevices @ " ; Common HAL devices [ UseSR44x BL SR44x_Init ] BL NVMemory_InitDevice BL RTC_Init BL SDMA_Init BL VideoDevice_Init BL Audio_Init BL PowerCtrl_Init ; Board-specific HAL devices LDR pc, [sb, #BoardConfig_InitDevices] Board_InitDevices_None EXIT Board_InitDevices_Panda ; SD needs boardtype and revision to configure the devices correctly ; for OMAP4 we just differentiate between ES (4460) and non-ES (4430) LDR a2, L4_Core_Log LDR a1, =(L4_CONTROL_IDCODE - L4_Core) LDR a2, [a2, a1] LDR v2, =HAWKEYE_OMAP4460_ES10 UBFX a2, a2, #12, #16 CMP v2, a2 MOV a1, #GPIOType_OMAP4_Panda MOVNE a2, #GPIORevision_Panda MOVEQ a2, #GPIORevision_PandaES Push "a1-a2" BL GPIO_InitDevice ; SD needs the same parameters to configure the device correctly Pull "a1-a2" BL SDIO_InitDevices DebugTime a1, "Done @ " EXIT HAL_ControllerAddress MOV a1, #0 MOV pc, lr HAL_HardwareInfo LDR ip, =&FFFFFF00 STR ip, [a1] MOV ip, #0 STR ip, [a2] STR ip, [a3] MOV pc, lr HAL_PlatformInfo LDRB ip, [sb, #BoardConfig_BoardFlags] STR ip, [a2] MOV ip, #2_11111 ; mask of valid bits STR ip, [a3] MOV pc, lr HAL_SuperIOInfo MOV ip, #0 STR ip, [a1] STR ip, [a2] MOV pc, lr HAL_MachineID MOV a1, #0 MOV a2, #0 MOV pc, lr HAL_ExtMachineID MOVS ip, a1 MOV a1, #16 MOVEQ pc, lr ; OMAP44xx: L4_CONTROL_IDCODE lies in between L4_DIE_ID0 and L4_DIE_ID1 LDR a2, L4_Core_Log ADD a2, a2, #(L4_DIE_ID0 - L4_Core) LDR a3, [a2], #8 ; skip L4_CONTROL_IDCODE LDR a4, [a2], #4 STMIA ip!, {a3-a4} LDMIA a2, {a3-a4} STMIA ip, {a3-a4} MOV pc, lr ; Shifts to determine number of bytes/words to allocate in table. NibbleShift * 12 ; 1<<12 = 4K ARM page size ByteShift * NibbleShift + 1 WordShift * ByteShift + 2 ; Bit patterns for different types of memory. NotPresent * &00000000 DRAM_Pattern * &11111111 VRAM_Pattern * &22222222 ROM_Pattern * &33333333 IO_Pattern * &44444444 NotAvailable * &88888888 IMPORT memset HAL_PhysInfo TEQ a1, #PhysInfo_GetTableSize MOVEQ a1, #1:SHL:(32-ByteShift) STREQ a1, [a2] MVNEQ a1, #0 ; Supported MOVEQ pc, lr TEQ a1, #PhysInfo_HardROM MOVEQ a1, #0 ; No hard ROM, since the NAND flash isn't yet supported MOVEQ a2, #0 STMEQIA a3, {a1-a2} MVNEQ a1, #0 ; Supported MOVEQ pc, lr TEQ a1, #PhysInfo_WriteTable MOVNE a1, #0 MOVNE pc, lr ; Do the PhysInfo_WriteTable table output Push "v1-v2,lr" MOV a1, #&80000000 ; Physical RAM from &80000000 and up? LDR lr, =&FFFFE000-1 STMIA a3, {a1,lr} MOV v1, a2 ADR v2, HAL_PhysTable 10 LDMIA v2, {a1, a2, lr} SUB a3, lr, a1 ADD a1, v1, a1, LSR #ByteShift MOV a3, a3, LSR #ByteShift BL memset LDR a1, [v2, #8]! TEQ a1, #0 BNE %BT10 MVN a1, #0 ; Supported Pull "v1,v2,pc" ; HAL_PhysInfo uses memset to fill the table, so all regions ; must be byte-aligned (ie double-page-aligned addresses). HAL_PhysTable DCD &00000000, NotPresent :OR: NotAvailable ; GPMC DCD &40000000, IO_Pattern :OR: NotAvailable ; All I/O registers DCD &80000000, NotPresent :OR: NotAvailable ; SDRC-SMS/SDRAM DCD &FFFFE000, NotPresent :OR: NotAvailable ; SDRC-SMS/SDRAM DCD 0 HAL_Reset ; Reset or power off? CMP a1, #0 BNE %FT10 ; If there is a power control unit connected we can do a power off command BL PowerCtrl_SwitchOff 10 [ UseSR44x BL SR44x_Exit ] ; Reset, or power off not supported ; For a reset, we just poke PRM_RSTCTRL.RST_GLOBAL_WARM_software LDR a3, L4_PowerMan_Log ADD a3, a3, #DEVICE_PRM MOV a2, #1 STR a2, [a3, #PRM_RSTCTRL] DebugTX "HAL_Reset failed!" B . ; Just in case LTORG EXPORT vtophys vtophys CallOS OS_LogToPhys, tailcall EXPORT mapinio mapinio CallOS OS_MapInIO, tailcall [ FIQDebug FIQRoutine ; Dump PC value to the serial port MOV r8, #&24 LDR sb, [r8] LDR r8, [sb, #BoardConfig_DebugUART] ADR r9, hextab MOV r10, #8 MOV r11, lr ; Preserve return address 10 LDRB r12, [r8, #UART_LSR] TST r12, #UART_LSR_THRE BEQ %BT10 LDRB r12, [r9, r11, LSR #28] STRB r12, [r8, #UART_THR] MOV r11, r11, LSL #4 SUBS r10, r10, #1 BNE %BT10 10 LDRB r12, [r8, #UART_LSR] TST r12, #UART_LSR_THRE BEQ %BT10 MOV r12, #13 STRB r12, [r8, #UART_THR] 10 LDRB r12, [r8, #UART_LSR] TST r12, #UART_LSR_THRE BEQ %BT10 MOV r12, #10 STRB r12, [r8, #UART_THR] ; Clear interrupt MOV r8, #&24 LDR sb, [r8] LDR r8, L4_GPIO1_Log LDR r10, [r8, #GPIO_IRQSTATUS1] STR r10, [r8, #GPIO_IRQSTATUS1] LDR r8, MPU_INTC_Log MOV r10, #2 STR r10, [r8, #INTCPS_CONTROL] ; Data synchronisation barrier to make sure INTC gets the message DSB SY [ {FALSE} ; Code to call DebugCallstack on any button press ; Switch back to original mode MRS r8, CPSR MRS r9, SPSR BIC r8, r8, #&1F AND r9, r9, #&1F ORR r8, r8, r9 MSR CPSR_c, r8 ; Dump the callstack & other regs Push "sb" ; preserve original sb so it can be dumped MOV sb, #&24 LDR sb, [sb] B DebugCallstack ] ; Now return SUBS pc, lr, #4 hextab DCB "0123456789abcdef" ] END