; Copyright 2009 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.<Machine> GET Hdr:ImageSize.<ImageSize> GET Hdr:MEMM.ARM600 GET Hdr:Proc GET Hdr:OSEntries GET Hdr:HALEntries GET hdr.omap3530 GET hdr.StaticWS GET hdr.SDRC GET hdr.Interrupts GET hdr.Timers GET hdr.GPIO GET hdr.Copro15ops GET hdr.UART GET hdr.PRCM GET hdr.GPMC ; This version assumes a RISC OS image starting 64K after us. ; FIQ-based debugger - prints out the PC when the beagleboard 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} AREA |Asm$$Code|, CODE, READONLY, PIC EXPORT rom_checkedout_ok IMPORT HAL_Base IMPORT DebugHALPrint IMPORT DebugHALPrintReg ; IMPORT generate_POR_flags IMPORT RTC_Init ; 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 MACRO CallOS $entry, $tailcall ASSERT $entry <= HighestOSEntry [ "$tailcall"="" MOV lr, pc | [ "$tailcall"<>"tailcall" ! 0, "Unrecognised parameter to CallOS" ] ] LDR pc, OSentries + 4*$entry MEND rom_checkedout_ok ; On entry, v8 -> OS entry table, sb -> board config ; Register the attached RAM LDR v1, =SDRC_Regs MOV a1, #0 MOV sp, #0 ; Check CS0 LDR a3, [v1, #SDRC_MCFG_0] LDR a2, =&3FF00<<13 ANDS a3, a2, a3, LSL #13 ; Get CS0 RAM size BEQ no_cs0 LDR a2, =CS0_SDRAM ADD a3, a3, a2 LDR a4, =&FFFFFFFF ADD sp, a2, #4096 ; HAL spec says that (for software reset compliance only?) stack should be 4K into first block STR a1, [sp, #-4]! MOV a1, #0 CallOSM OS_AddRAM no_cs0 ; Check CS1 LDR a3, [v1, #SDRC_MCFG_1] LDR a2, =&3FF00<<13 ANDS a3, a2, a3, LSL #13 BEQ no_cs1 LDR a2, =CS0_SDRAM LDR a4, [v1, #SDRC_CS_CFG] AND v2, a4, #7 ; Offset in 128MB units ADD a2, a2, v2, LSL #20+7 AND v2, a4, #&300 ; Offset in 32MB units ADD a2, a2, v2, LSL #20+5-8 ADD a3, a3, a2 LDR a4, =&FFFFFFFF CMP sp, #0 ADDEQ sp, a2, #4096 ; If no CS0 set up stack in CS1 STR a1, [sp, #-4]! MOV a1, #0 CallOSM OS_AddRAM no_cs1 DebugChar v1,v2,71 MOV a4, a1 MOV a1, #OSStartFlag_RAMCleared ADRL a2, HAL_Base + 64*1024 ; a2 -> RISC OS image ADR a3, HALdescriptor CallOSM OS_Start HALdescriptor DATA DCD HALFlag_NCNBWorkspace DCD HAL_Base - HALdescriptor DCD 64*1024 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 [ :LNOT: HALDoesVideo IMPORT VideoDevice_Init ] IMPORT Audio_Init IMPORT GPMC_Init IMPORT NIC_Init IMPORT NIC_GPMC_Config_IGEP IMPORT NIC_GPMC_Config_DevKit IMPORT NIC_SMSC IMPORT NIC_DM9000 IMPORT GPIO_Init EXPORT Board_InitDevices_None EXPORT Board_InitDevices_IGEP EXPORT Board_InitDevices_DevKit 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_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_VideoFlybackDevice IMPORT HAL_Video_SetMode IMPORT HAL_Video_WritePaletteEntry IMPORT HAL_Video_WritePaletteEntries IMPORT HAL_Video_ReadPaletteEntry IMPORT HAL_Video_SetInterlace IMPORT HAL_Video_SetBlank IMPORT HAL_Video_SetPowerSave IMPORT HAL_Video_UpdatePointer IMPORT HAL_Video_SetDAG IMPORT HAL_Video_VetMode IMPORT HAL_Video_PixelFormats IMPORT HAL_Video_Features IMPORT HAL_Video_BufferAlignment IMPORT HAL_Video_OutputFormat IMPORT HAL_Video_IICOp ; 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_DebugRX IMPORT HAL_DebugTX IMPORT HAL_ATAControllerInfo IMPORT HAL_KbdScanSetup IMPORT HAL_KbdScan IMPORT HAL_KbdScanFinish IMPORT HAL_KbdScanInterrupt IMPORT HAL_USBControllerInfo IMPORT HAL_USBPortPower IMPORT HAL_USBPortStatus IMPORT HAL_USBPortIRQ 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 NullEntry ; HAL_NVMemorySize NullEntry ; HAL_NVMemoryPageSize NullEntry ; HAL_NVMemoryProtectedSize NullEntry ; HAL_NVMemoryProtection NullEntry ; HAL_NVMemoryIICAddress NullEntry ; HAL_NVMemoryRead NullEntry ; HAL_NVMemoryWrite HALEntry HAL_IICBuses HALEntry HAL_IICType NullEntry ; HAL_IICSetLines NullEntry ; HAL_IICReadLines HALEntry HAL_IICDevice HALEntry HAL_IICTransfer HALEntry HAL_IICMonitorTransfer HALEntry HAL_VideoFlybackDevice HALEntry HAL_Video_SetMode HALEntry HAL_Video_WritePaletteEntry HALEntry HAL_Video_WritePaletteEntries HALEntry HAL_Video_ReadPaletteEntry HALEntry HAL_Video_SetInterlace HALEntry HAL_Video_SetBlank HALEntry HAL_Video_SetPowerSave HALEntry HAL_Video_UpdatePointer HALEntry HAL_Video_SetDAG HALEntry HAL_Video_VetMode HALEntry HAL_Video_PixelFormats HALEntry HAL_Video_Features HALEntry HAL_Video_BufferAlignment HALEntry HAL_Video_OutputFormat 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 NullEntry ;HALEntry HAL_MonitorLeadID NullEntry ;HALEntry HAL_Video_Render HALEntry HAL_USBPortPower HALEntry HAL_USBPortStatus HALEntry HAL_USBPortIRQ HALEntry HAL_Video_IICOp HAL_Entries * (.-HAL_EntryTable)/4 ;-------------------------------------------------------------------------------------- HAL_Init Entry "v1" 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_Control MOV a3, #L3_Size CallOS OS_MapInIO STR a1, L3_Log MOV a1, #0 LDR a2, =L4_Core MOV a3, #L4_Core_Size CallOS OS_MapInIO STR a1, L4_Core_Log ADD a2, a1, #L4_Wakeup-L4_Core STR a2, L4_Wakeup_Log ; L4_PowerMan, L4_32KTIMER, L4_GPIO1 ADD a3, a2, #L4_PowerMan-L4_Wakeup STR a3, L4_PowerMan_Log ADD a3, a2, #L4_32KTIMER-L4_Wakeup STR a3, L4_32KTIMER_Log ADD a3, a2, #L4_GPIO1-L4_Wakeup STR a3, L4_GPIO1_Log ; Interrupt controller ADD a3, a1, #MPU_INTC-L4_Core STR a3, MPU_INTC_Log ; Clockman ADD a3, a1, #L4_ClockMan-L4_Core STR a3, L4_ClockMan_Log ; Display ADD a3, a1, #L4_Display-L4_Core STR a3, L4_Display_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_Per MOV a3, #L4_Per_Size CallOS OS_MapInIO STR a1, L4_Per_Log ; Timers ADD a2, a1, #TIMER_BASE-L4_Per STR a2, Timers_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 ; 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 ; This gets mapped in last so debugging is easier (don't have to worry about logical addresses being offset by funny amounts) 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+4*2 10 BL phys2log SUBS a1, a1, #4 BGE %BT10 MOV a1, #BoardConfig_HALI2C BL phys2log STR a2, I2C1Block+I2C_HW MOV a1, #BoardConfig_HALI2C+4 BL phys2log STR a2, I2C2Block+I2C_HW MOV a1, #BoardConfig_HALI2C+8 BL phys2log STR a2, I2C3Block+I2C_HW [ Debug DebugTX "HAL_Init" ] BL PRCM_SetClocks ; Calls Timer_init & starts GPTIMER2 BL GPIO_Init ; Make sure all GPIO IRQs are disabled before we potentially start enabling them BL Video_init ; Uses GPTIMER2 BL USB_Init ; Uses GPTIMER2 BL I2C_Init ; Uses GPTIMER2 BL Timer_Init ; Re-inits timers BL Interrupt_Init BL GPMC_Init LDRB v1, [sb, #BoardConfig_NumUART] 10 SUBS v1, v1, #1 MOVGE a1, v1 ADRGE lr, %BT10 BGE HAL_UARTStartUp 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 SUB a2, a3, #L3_Control CMP a2, #L3_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_Core LDR a3, L4_Core_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 MCR p15, 0, a1, c7, c5, 1 ; invalidate ICache entry (to PoC) MCR p15, 0, a1, c7, c10, 4 ; Drain write buffer ; 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 B HAL_FIQEnable ; tail-optimised, repeating the HAL device init would be a bad thing! 10 ] Entry ; Common HAL devices BL RTC_Init BL SDMA_Init [ :LNOT: HALDoesVideo BL VideoDevice_Init ] BL Audio_Init ; Board-specific HAL devices LDR pc, [sb, #BoardConfig_InitDevices] Board_InitDevices_None EXIT Board_InitDevices_IGEP ; SMSC NIC on GPMC CS 5, GPIO IRQ 176 MOV a1, #5 ADRL a2, NIC_GPMC_Config_IGEP MOV a3, #176 ADRL a4, NIC_SMSC MOV v1, #256 ; 256 bytes is all we need... although OS_MapInIO will only map in a minimum of 1MB! BL NIC_Init EXIT Board_InitDevices_DevKit ; DM9000 on GPMC 6, GPIO IRQ 25 MOV a1, #6 ADRL a2, NIC_GPMC_Config_DevKit MOV a3, #25 ADRL a4, NIC_DM9000 MOV v1, #256 BL NIC_Init EXIT HAL_ControllerAddress MOV a1, #0 MOV pc, lr HAL_HardwareInfo LDR ip, =&FFFFFF00 STR ip, [a1] MOV ip, #0 STR ip, [a2] LDR ip, =&00FFFF00 STR ip, [a3] MOV pc, lr HAL_PlatformInfo MOV ip, #2_10000 ; no podules,no PCI cards,no multi CPU,no soft off (for now!),and soft ROM 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 LDR a3, L4_Wakeup_Log ADD a3, a3, #(L4_DIE_ID-L4_Wakeup) :AND: &FF00 ADD a3, a3, #(L4_DIE_ID-L4_Wakeup) :AND: &00FF LDMIA a3, {a1-a2} ; Return the lower 8 bytes of the ID. According to the HAL spec there should also be a CRC, as calculated in kernel.s.PMF.osinit 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, #0 MOVEQ a1, #1:SHL:(32-ByteShift) MOVEQ pc, lr Push "a2,v1,v2,lr" MOV v1, a1 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 MOV a1, #&70000000 ; Physical RAM from &70000000 and up? LDR lr, =&FFFFE000-1 Pull "a2" STR lr, [a2] 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 &70000000, NotPresent :OR: NotAvailable ; SDRC-SMS/SDRAM DCD &FFFFE000, NotPresent :OR: NotAvailable ; SDRC-SMS/SDRAM DCD 0 HAL_Reset ; At the moment we only support resets, not power off ; For a reset, we just poke PRM_RSTCTRL.RST_GS LDR a1, L4_PowerMan_Log ADD a1, a1, #Global_Reg_PRM MOV a2, #2 STR a2, [a1, #PRM_RSTCTRL] 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, #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, #THRE BEQ %BT10 MOV r12, #13 STRB r12, [r8, #UART_THR] 10 LDRB r12, [r8, #UART_LSR] TST r12, #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 MOV r8, #0 MCR ARM_config_cp, 0, r8, C7, C10, 4 ; Now return SUBS pc, lr, #4 hextab DCB "0123456789abcdef" ] END