; ; Copyright (c) 2012, RISC OS Open Ltd ; Copyright (c) 2012, Adrian Lees ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without ; modification, are permitted provided that the following conditions are met: ; * Redistributions of source code must retain the above copyright ; notice, this list of conditions and the following disclaimer. ; * Redistributions in binary form must reproduce the above copyright ; notice, this list of conditions and the following disclaimer in the ; documentation and/or other materials provided with the distribution. ; * Neither the name of RISC OS Open Ltd nor the names of its contributors ; may be used to endorse or promote products derived from this software ; without specific prior written permission. ; ; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" ; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE ; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR ; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS ; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN ; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ; POSSIBILITY OF SUCH DAMAGE. ; ; With many thanks to Broadcom Europe Ltd for releasing the source code to ; its Linux drivers, thus making this port possible. ; [ :LNOT :DEF: BCM2835_Hdr GBLL BCM2835_Hdr GBLL HALDebug HALDebug SETL {TRUE} GBLL ExtFramestore ExtFramestore SETL {TRUE} GBLL SCR32 SCR32 SETL {TRUE} ; Debugging in the serial port (HAL_DebugTX, HAL_DebugRX) GBLL Debug Debug SETL {TRUE} ; RPi ARM11 registers ; 4Gbytes of address space. ; 00000000-0000001F reserved for exception vectors ; FFFFE000-FFFFFFFF allocated to control registers ; Bus memory map, for direct DMA access to devices ; 7e000000-7effffff I/O peripherals for DMA access ; c0000000-???????? SDRAM physical for DMA ; Our physical memory map: ; 00000000-???????? SDRAM upper bound set at boot ; 20000000-20ffffff IO_Base for peripherals ; 3fffffff top of physical memory space ; Address window 0 is set to 4K and points to a single page of HAL workspace for the messaging ; unit. ;ROM_Base * &00000000 IO_Base * &20000000 IO_Size * &01000000 RAM_Base * &00000000 ; try off bottom Boot_RAM_Base * &00000000 DMA_RAM_Base * &C0000000 ; base physical address of ram for DMA purposes GPU_UnCached * &c0000000 ; GPU mempry mapping uncached GPU_L2Conly * &80000000 ; GPU L2 Cached (only) GPU_L2CnonAl * &40000000 ; GPU L2 cached non allocating coherent GPU_L1L2Cac * &00000000 ; both L1 and L2 cached GPU side GPU_CacheMask * &c0000000 ; ; Timer details ; TIMER_RATE * 1000000 ; 1MHz MACRO $label ReadTMR0 $r,$cond $label MRC$cond p6, 0, $r, c0, c1 MEND MACRO $label ReadTMR1 $r,$cond $label MRC$cond p6, 0, $r, c1, c1 MEND MACRO $label ReadTCR0 $r,$cond $label MRC$cond p6, 0, $r, c2, c1 MEND MACRO $label ReadTCR1 $r,$cond $label MRC$cond p6, 0, $r, c3, c1 MEND MACRO $label ReadTRR0 $r,$cond $label MRC$cond p6, 0, $r, c4, c1 MEND MACRO $label ReadTRR1 $r,$cond $label MRC$cond p6, 0, $r, c5, c1 MEND MACRO $label ReadTISR $r,$cond $label MRC$cond p6, 0, $r, c6, c1 MEND MACRO $label ReadWDTCR $r,$cond $label MRC$cond p6, 0, $r, c7, c1 MEND MACRO $label WriteTMR0 $r,$cond $label MCR$cond p6, 0, $r, c0, c1 MEND MACRO $label WriteTMR1 $r,$cond $label MCR$cond p6, 0, $r, c1, c1 MEND MACRO $label WriteTCR0 $r,$cond $label MCR$cond p6, 0, $r, c2, c1 MEND MACRO $label WriteTCR1 $r,$cond $label MCR$cond p6, 0, $r, c3, c1 MEND MACRO $label WriteTRR0 $r,$cond $label MCR$cond p6, 0, $r, c4, c1 MEND MACRO $label WriteTRR1 $r,$cond $label MCR$cond p6, 0, $r, c5, c1 MEND MACRO $label WriteTISR $r,$cond $label MCR$cond p6, 0, $r, c6, c1 MEND MACRO $label WriteWDTCR $r,$cond $label MCR$cond p6, 0, $r, c7, c1 MEND GBLA NumTimers NumTimers SETA 0 MACRO DeclareTimer $phys TimerPhysFromLog$NumTimers * $phys NumTimers SETA NumTimers + 1 MEND ; List of physical timers (excluding those already used by VideoCore) ; in the order we use them for logical timers DeclareTimer 1 DeclareTimer 3 ; An assembly-time variable for looping over all logical timers, since ; the available timers might vary with version of start.elf GBLA Timer ; ; Mailbox ; ; There are two mailboxes; we write to mailbox 1 and read from mailbox 0 ; MB_Base * &0000b800 ; offset from IO space start MB_ChRd * &80 ; normal read - offset from MB_Base MB_ChWr * &a0 ; normal write MB_ChRWTop * &8c ; 4 word read or write MB_Pol * &90 ; NonPOP read MB_Snd * &94 ; sender read (bottom 2 bits) MB_Sta * &98 ; status read MB_Cnf * &9c ; config r/w ; ; mailbox register bits ; ; MB_Sta MB_Sta_Full * &80000000 ; mailbox full MB_Sta_Empty * &40000000 ; mailbox empty MB_Sta_Level * &000000ff ; mailbox content count ; MB_Cnf MB_Cnf_HDIrqEn * &00000001 ; mailbox has-data irq enable MB_Cnf_HSIrqEn * &00000002 ; mailbox has-space irq enable MB_Cnf_OpIrqEn * &00000004 ; mailbox Opp irq en MB_Cnf_MBClr * &00000008 ; write 1 then 0 to clear mailbox MB_Cnf_HDIrq * &00000010 ; mailbox has-data irq pending MB_Cnf_HSIrq * &00000020 ; mailbox has-space irq pending MB_Cnf_OpIrq * &00000040 ; mailbox Opp irq pending ; these flags are reset on any write to this register MB_Cnf_ErNone * &00000100 ; none read error MB_Cnf_ErWFull * &00000200 ; Write to full mailbox MB_Cnf_ErREmty * &00000400 ; read from empty mailbox ; ; mailbox channel numbers MB_Chan_Pwr * 0 ; Power channel MB_Chan_FB * 1 ; Frame Buffer channel MB_Chan_VUart * 2 ; Virtual UART channel MB_Chan_VCHIQ * 3 ; VCHIQ channel MB_Chan_LEDS * 4 ; LEDS channel MB_Chan_Btn * 5 ; Buttons channel MB_Chan_TSc * 6 ; TouchScreen channel MB_Chan_ARM2VC * 8 ; ARM -> VC property channel MB_Chan_VC2ARM * 9 ; VC -> ARM property channel ; far end replies on the same channel when command done.. e.g. ; command c0000001 gets 00000001 (ie channel1) reply ; Power channel bits MB_Pwr_SDCard * 0 MB_Pwr_UART * 1 MB_Pwr_MiniUART * 2 MB_Pwr_USB * 3 MB_Pwr_I2C0 * 4 MB_Pwr_I2C1_MASK * 5 MB_Pwr_I2C2_MASK * 6 MB_Pwr_SPI_MASK * 7 MB_Pwr_CCP2TX_MASK * 8 ; ARM2VC tags ; see https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface ; Note - this interface isn't implemented in the GPU firmware yet! ARM2VC_Tag_End * &00000000 ; End of tag list ARM2VC_Tag_GetFirmwareVersion * &00000001 ; return 4 byte firmware version ARM2VC_Tag_GetBoardModel * &00010001 ; return 4 byte model ARM2VC_Tag_GetBoardRevision * &00010002 ; return 4 byte revision ARM2VC_Tag_GetBoardMAC * &00010003 ; return 6 byte MAC ARM2VC_Tag_GetBoardSerial * &00010004 ; return 8 byte serial ARM2VC_Tag_GetARMMemory * &00010005 ; return ARM mem base + size ARM2VC_Tag_GetVCMemory * &00010006 ; return VC mem base + size ARM2VC_Tag_GetClocks * &00010007 ; return clock tree ARM2VC_Tag_GetConfig * &00050001 ; get kernel boot args string ARM2VC_Tag_GetDMAChannels * &00060001 ; get mask of DMA channels usable by ARM ARM2VC_Tag_GetPowerState * &00020001 ; get power state of specified MB_Pwr_ device ARM2VC_Tag_GetPowerTiming * &00020002 ; get microsecond delay required after power on for indicated device ARM2VC_Tag_SetPowerState * &00028001 ; set power state of device ARM2VC_Tag_GetClockState * &00030001 ; get power state of clock ARM2VC_Tag_SetClockState * &00038001 ; set power state of clock ARM2VC_Tag_GetClockRate * &00030002 ; get rate of clock ARM2VC_Tag_SetClockRate * &00038002 ; set rate of clock ARM2VC_Tag_FBAlloc * &00040001 ; alloc framebuffer at given alignment ARM2VC_Tag_FBRelease * &00048001 ; release framebuffer ARM2VC_Tag_FBBlank * &00040002 ; blank screen ARM2VC_Tag_FBGetPhysDimension * &00040003 ; get physical display width/height ARM2VC_Tag_FBTestPhysDimension * &00044003 ; test physical display w/h ARM2VC_Tag_FBSetPhysDimension * &00048003 ; set physical display w/h ARM2VC_Tag_FBGetVirtDimension * &00040004 ; get virtual display w/h ARM2VC_Tag_FBTestVirtDimension * &00044004 ; test virtual display w/h ARM2VC_Tag_FBSetVirtDimension * &00048004 ; set virtual display w/h ARM2VC_Tag_FBGetDepth * &00040005 ; get display BPP ARM2VC_Tag_FBTestDepth * &00044005 ; test display BPP ARM2VC_Tag_FBSetDepth * &00048005 ; set display BPP ARM2VC_Tag_FBGetPixelOrder * &00040006 ; get RGB/BGR order ARM2VC_Tag_FBTestPixelOrder * &00044006 ; test RGB/BGR order ARM2VC_Tag_FBSetPixelOrder * &00048006 ; set RGB/BGR order ARM2VC_Tag_FBGetAlphaMode * &00040007 ; get alpha mode ARM2VC_Tag_FBTestAlphaMode * &00044007 ; test alpha mode ARM2VC_Tag_FBSetAlphaMode * &00048007 ; set alpha mode ARM2VC_Tag_FBGetPitch * &00040008 ; get row pitch ARM2VC_Tag_FBGetVirtOffset * &00040009 ; get X/Y offset of virtual display ARM2VC_Tag_FBTestVirtOffset * &00044009 ; test X/Y offset ARM2VC_Tag_FBSetVirtOffset * &00048009 ; set X/Y offset ARM2VC_Tag_FBGetOverscan * &0004000a ; get overscan values ARM2VC_Tag_FBTestOverscan * &0004400a ; test overscan values ARM2VC_Tag_FBSetOverscan * &0004800a ; set overscan values ARM2VC_Tag_FBGetPalette * &0004000b ; get full palette table ARM2VC_Tag_FBTestPalette * &0004400b ; test ranged update of table ARM2VC_Tag_FBSetPalette * &0004800b ; do ranged update of table ; mem barrier operation; ensures all explicit mem operations completed before ; instruction exits. ; (value 4 is all instructions, value 5 is just mem instructions) ; zeroes $r MACRO $label DataSyncBarrier $r, $cond $label MOV$cond $r, #0 [ {UAL} MCR$cond p15, #0, $r, c7, c10, #4 | MCR$cond p15, 0, $r, c7, c10,4 ] MEND MACRO $label DoMemBarrier $r, $cond $label MOV$cond $r, #0 [ {UAL} MCR$cond p15, #0, $r, c7, c10, #5 | MCR$cond p15, 0, $r, c7, c10,5 ] MEND MACRO $label FlushDataCache $r, $cond $label MOV$cond $r, #0 [ {UAL} MCR$cond p15, #0, $r, c7, c6, #0 | MCR$cond p15, 0, $r, c7, c6,0 ] MEND MACRO $label FlushDataCacheRange $startaddr,$endaddr,$cond $label BIC$cond $startaddr, $startaddr, #&1f BIC$cond $endaddr, $endaddr, #&1f [ {UAL} MCRR$cond p15, #0, $endaddr, $startaddr, c14 | MCRR$cond p15, 0, $endaddr, $startaddr, c14 ] MEND ; GPIO register set GPIO_Base * &00200000 ; base offset of GPIO regs GPFSel0 * &0 ; function sel 0 GPFSel1 * &4 ; function sel 1 GPFSel2 * &8 ; function sel 2 GPFSel3 * &c ; function sel 3 GPFSel4 * &10 ; function sel 4 GPFSel5 * &14 ; function sel 5 GPSet0 * &1c ; GPIO Set 0 GPSet1 * &20 ; GPIO Set 1 GPClr0 * &28 ; GPIO Clear 0 GPClr1 * &2c ; GPIO Clear 1 GPLev0 * &34 ; GPIO Level 0 GPLev1 * &38 ; GPIO Level 1 GPPEDS0 * &40 ; GPOI Pin Event Detect Status 0 GPPEDS1 * &44 ; GPOI Pin Event Detect Status 1 GPREDE0 * &4c ; GPIO rising edge detect enable 0 GPREDE1 * &50 ; GPIO rising edge detect enable 1 GPFEDE0 * &58 ; GPIO falling edge detect enable 0 GPFEDE1 * &5c ; GPIO falling edge detect enable 1 GPHIDE0 * &64 ; GPIO High detect enable 0 GPHIDE1 * &68 ; GPIO High detect enable 1 GPLODE0 * &70 ; GPIO Low detect enable 0 GPLODE1 * &74 ; GPIO Low detect enable 1 GPAREDE0 * &7c ; GPIO Async rising edge detect enable 0 GPAREDE1 * &80 ; GPIO Async rising edge detect enable 1 GPAFEDE0 * &88 ; GPIO Async falling edge detect enable 0 GPAFEDE1 * &8c ; GPIO Async falling edge detect enable 1 GPPUPDEN * &94 ; GPIO PullUp PullDown Enable GPPUDCK0 * &98 ; GPIO PullUp PullDown Clock 0 GPPUDCK1 * &9c ; GPIO PullUp PullDown Clock 1 ; Auxio peripherals ; MiniUart uses TXD1 and RXD1 ; txd1 is GPIO14 alt 5 (010) ; rxd1 is GPIO15 alt 5 ; rts1 is GPIO17 alt 5 AUXIO_Base * &00215000 ; base of auxio regs AUXIRQ * &0 ; IRQ status AUXEnables * &4 ; AUX enables AUXMUIO * &40 ; MiniUart IO data AUXMUIER * &44 ; MU int enable AUXMUIIR * &48 ; MU int identify AUXMULCR * &4c ; MU Line Control AUXMUMCR * &50 ; MU Modem Control AUXMULSR * &54 ; MU Line Status AUXMUMSR * &58 ; MU Control Status AUXMUSCRATCH * &5c ; MU Scratch reg AUXMUCNTL * &60 ; MU extra control AUXMUSTAT * &64 ; MU extra status AUXMUBAUD * &68 ; MU Baud rate ; etc ; UART TXD0 RXD0 ; txd0 is GPIO14 alt 0 (100) ; rxd0 is GPIO15 alt 0 UART_Base * &00201000 ; base of uart regs UART1_offset * &00004000 ; offset to base of uart1 regs ; mini uart (above) UARTDR * &0 ; data reg UARTRSRECR * &4 ; UARTFLAG * &18 ; UARTIBRD * &24 ; int baud reg UARTFBRD * &28 ; fract baud reg UARTLCRH * &2c ; Line Control UARTCR * &30 ; Control Reg UARTIFLS * &34 ; Int FIFO Level UARTIMSC * &38 ; Int Mask set clear UARTRIS * &3c ; raw int status UARTMIS * &40 ; masked int status UARTICR * &44 ; irq clr UARTDMACR * &40 ; DMA Control UARTITCR * &80 ; test control UARTITIP * &84 ; integr test ip UARTITOP * &88 ; integ test op UARTTDR * &8c ; test data reg ; GPU System Timer Timer_Base * &00003000 ; base of system timer regs ST_CS * &00 ; control/status ST_CLO * &04 ; counter low ST_CHI * &08 ; counter high ST_C0 * &0C ; compare 0 ST_C1 * &10 ; compare 1 ST_C2 * &14 ; compare 2 ST_C3 * &18 ; compare 3 ; ARM Timer ARM_Timer_Base * &0000b400 ; base of ARM timer regs ; DMA registers DMA_Base * &00007000 DMA_CH_Count * 13 ; Allegedly 16 channels, but can only get IRQs from 13 of them? ; PM_Base * &00100000 ; power management PM_Rstc * &1c ; reset control reg PM_Rsts * &20 ; reset status reg (?) PM_Wdog * &24 ; watchdog control reg ; register bits PM_Wdog_Reset * &00 ; watchdog reset PM_Password * &5a000000 PM_Wdog_TimeSet * &000fffff PM_Rst_WCfgClr * &ffffffcf PM_Rst_WCfgSet * &00000030 PM_Rst_WCfg_FullRst * &00000020 PM_Rst_Reset * &00000102 ; ; USB_Base * &00980000 ; USB ISP_Base * &00a00000 ; ISP ; ; Interrupt handling ; IRQ_Base * &0000B200 IRQ_PENDB * &00 ; read: pending basic interrupts (devices 64-95) IRQ_PEND1 * &04 ; read: pending interrupts 1 (GPU IRQs 0-31, devices 0-31) IRQ_PEND2 * &08 ; read: pending interrupts 2 (GPU IRQs 32-63, devices 32-63) IRQ_FIQCTL * &0C ; FIQ control register IRQ_EN1 * &10 ; read: enabled interrupts 1; write: bits to OR into enabled interrupts 1 IRQ_EN2 * &14 ; read: enabled interrupts 2; write: bits to OR into enabled interrupts 2 IRQ_ENB * &18 ; read: enabled basic interrupts; write: bits to OR into enabled basic interrupts IRQ_DIS1 * &1C ; read: enabled interrupts 1; write: bits to BIC from enabled interrupts 1 IRQ_DIS2 * &20 ; read: enabled interrupts 2; write: bits to BIC from enabled interrupts 2 IRQ_DISB * &24 ; read: enabled basic interrupts; write: bits to BIC from enabled basic interrupts ; Raspberry Pi interrupt sources. ; Because the pending and enable registers are listed in different orders, there are 2 logical ways to map these onto ; device numbers. However, matching the order of the enable registers has the following advantages: ; * the same device numbers can be used in the FIQ control register without modification ; * the GPU timer interrupts end up with the lowest priority - desirable since we run our counter from them ; devices in register 1 - start at 0 iDev_GPU_Timer0 * 0 ; not on list in datasheet iDev_GPU_Timer1 * 1 ; not on list in datasheet iDev_GPU_Timer2 * 2 ; not on list in datasheet iDev_GPU_Timer3 * 3 ; not on list in datasheet iDev_GPU_Codec0 * 4 ; not on list in datasheet iDev_GPU_Codec1 * 5 ; not on list in datasheet iDev_GPU_Codec2 * 6 ; not on list in datasheet iDev_GPU_VCJPEG * 7 ; not on list in datasheet iDev_GPU_ISP * 8 ; not on list in datasheet iDev_GPU_VCUSB * 9 ; not on list in datasheet iDev_GPU_VC3D * 10 ; not on list in datasheet iDev_GPU_Transp * 11 ; not on list in datasheet iDev_GPU_MCSync0 * 12 ; not on list in datasheet iDev_GPU_MCSync1 * 13 ; not on list in datasheet iDev_GPU_MCSync2 * 14 ; not on list in datasheet iDev_GPU_MCSync3 * 15 ; not on list in datasheet iDev_GPU_DMA0 * 16 ; not on list in datasheet iDev_GPU_DMA1 * 17 ; not on list in datasheet iDev_GPU_VCDMA2 * 18 ; not on list in datasheet iDev_GPU_VCDMA3 * 19 ; not on list in datasheet iDev_GPU_DMA4 * 20 ; not on list in datasheet iDev_GPU_DMA5 * 21 ; not on list in datasheet iDev_GPU_DMA6 * 22 ; not on list in datasheet iDev_GPU_DMA7 * 23 ; not on list in datasheet iDev_GPU_DMA8 * 24 ; not on list in datasheet iDev_GPU_DMA9 * 25 ; not on list in datasheet iDev_GPU_DMA10 * 26 ; not on list in datasheet iDev_GPU_DMA11 * 27 ; not on list in datasheet iDev_GPU_DMA12 * 28 ; not on list in datasheet iDev_GPU_AuxInt * 29 iDev_GPU_ARM * 30 ; not on list in datasheet iDev_GPU_VPUDMA * 31 ; not on list in datasheet ; devices in register 2 - start at 32 iDev_GPU_HostPort * 32 ; not on list in datasheet iDev_GPU_VidScale * 33 ; not on list in datasheet iDev_GPU_CCP2TX * 34 ; not on list in datasheet iDev_GPU_SDC * 35 ; not on list in datasheet iDev_GPU_DSI0 * 36 ; not on list in datasheet iDev_GPU_AVE * 37 ; not on list in datasheet iDev_GPU_Cam0 * 38 ; not on list in datasheet iDev_GPU_Cam1 * 39 ; not on list in datasheet iDev_GPU_HDMI0 * 40 ; not on list in datasheet iDev_GPU_HDMI1 * 41 ; not on list in datasheet iDev_GPU_PixVal1 * 42 ; not on list in datasheet iDev_GPU_I2CSPISlv * 43 iDev_GPU_DSI1 * 44 ; not on list in datasheet iDev_GPU_PWA0 * 45 iDev_GPU_PWA1 * 46 iDev_GPU_CPR * 47 ; not on list in datasheet iDev_GPU_SMI * 48 iDev_GPU_GPIO0 * 49 iDev_GPU_GPIO1 * 50 iDev_GPU_GPIO2 * 51 iDev_GPU_GPIO3 * 52 iDev_GPU_I2C * 53 iDev_GPU_SPI * 54 iDev_GPU_PCM * 55 iDev_GPU_SDIO * 56 ; not on list in datasheet iDev_GPU_Uart * 57 iDev_GPU_SlimBus * 58 ; not on list in datasheet iDev_GPU_Vec * 59 ; not on list in datasheet iDev_GPU_CPG * 60 ; not on list in datasheet iDev_GPU_RNG * 61 ; not on list in datasheet iDev_GPU_VCSDIO * 62 ; not on list in datasheet iDev_GPU_AVSPMON * 63 ; not on list in datasheet iDev_ARM_Timer * 64+0 iDev_ARM_Mbx * 64+1 iDev_ARM_DBell0 * 64+2 iDev_ARM_DBell1 * 64+3 iDev_ARM_GPU0Hlt * 64+4 iDev_ARM_GPU1Hlt * 64+5 iDev_ARM_IllegAcs1 * 64+6 iDev_ARM_IllegAcs0 * 64+7 ; Notice that bits 8-31 of the pending basic interrupts cannot be masked. This causes the RISC OS kernel problems, ; because the default action for an unhandled interrupt is to mask it, and if masking doesn't work, we end up with an ; infinite loop. You *could* map these device numbers back to bits in the disable interrupts 1/2 registers, but it's ; not a simple mapping and the same bits appear in the pending interrupts 1/2 registers as well, so they're arguably ; not much use. Is the saving of one or two reads of the pending interrupt registers worth the complexity? I don't know. ; It's also worth noting that these device numbers are not valid for use as FIQs. So for now, I recommend you don't use ; these devices - use the equivalents in the GPU interrupt registers instead. iDev_ARM_MiscGPU1 * 64+8 ; OR of GPU IRQs 0-31 excluding those listed below iDev_ARM_MiscGPU2 * 64+9 ; OR of GPU IRQs 32-63 excluding those listed below iDev_ARM_VCJPEG * 64+10 ; copy of GPU IRQ 7 iDev_ARM_VCUSB * 64+11 ; copy of GPU IRQ 9 iDev_ARM_VC3D * 64+12 ; copy of GPU IRQ 10 iDev_ARM_VCDMA2 * 64+13 ; copy of GPU IRQ 18 iDev_ARM_VCDMA3 * 64+14 ; copy of GPU IRQ 19 iDev_ARM_I2C * 64+15 ; copy of GPU IRQ 53 iDev_ARM_SPI * 64+16 ; copy of GPU IRQ 54 iDev_ARM_PCM * 64+17 ; copy of GPU IRQ 55 iDev_ARM_SDIO * 64+18 ; copy of GPU IRQ 56 iDev_ARM_Uart * 64+19 ; copy of GPU IRQ 57 iDev_ARM_VCSDIO * 64+20 ; copy of GPU IRQ 62 MACRO $label ReadINTCTL $r,$cond $label MRC$cond p6, 0, $r, c0, c0 MEND MACRO $label ReadINTSTR $r,$cond $label MRC$cond p6, 0, $r, c4, c0 MEND MACRO $label ReadIINTSRC $r,$cond $label MRC$cond p6, 0, $r, c8, c0 MEND MACRO $label ReadFINTSRC $r,$cond $label MRC$cond p6, 0, $r, c9, c0 MEND MACRO $label WriteINTCTL $r,$cond $label MCR$cond p6, 0, $r, c0, c0 MEND MACRO $label WriteINTSTR $r,$cond $label MCR$cond p6, 0, $r, c4, c0 MEND MACRO $label WriteIINTSRC $r,$cond $label MCR$cond p6, 0, $r, c8, c0 MEND MACRO $label WriteFINTSRC $r,$cond $label MCR$cond p6, 0, $r, c9, c0 MEND ] END