; ; Copyright (c) 2012, RISC OS Open Ltd ; Copyright (c) 2012, John Ballance ; 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. ; ; AREA |ARM$$code|, CODE, READONLY, PIC GET Hdr:ListOpts GET Hdr:Macros GET Hdr:Proc GET Hdr:System GET Hdr:FSNumbers GET Hdr:NewErrors GET Hdr:BCMSupport GET hdr.BCM2835 GET hdr.StaticWS IMPORT workspace [ HALDebug IMPORT HAL_DebugTX IMPORT HAL_DebugHexTX4 IMPORT HAL_DebugTXStrInline ] IMPORT memcpy EXPORT HAL_SendHostMessage EXPORT HAL_QueryPlatform EXPORT BCMMBox_InitDevices ; Send a message packet to the host and await the reply ; on entry, r0 = message channel to use and/or wholemessage ; r1 -> message tag buffer, 16 byte aligned. or 0 ; ; on exit, r0 = mailbox response word ; HAL_SendHostMessage ROUT STMFD r13!, {r1-r3, lr} DoMemBarrier r3 FlushDataCache ; corrupts r2,r3,lr LDR r3, PeriBase ADD r3, r3, #MB_Base ; check we can send a message 001 LDR r2,[r3, #MB_Sta] TST r2, #MB_Sta_Full BNE %BT001 ; write channel full ; send message TEQ r1, #0 BICNE r1, r1, #&c0000000 ; LDRNE r2, FB_CacheMode ; ORRNE r1, r1, r2 ORR r2, r0, r1 AND r1, r0, #&f ; isolate channel number STR r2,[r3, #MB_ChWr] ; await response and check it is ours 002 LDR r0,[r3, #MB_Sta] TST r0, #MB_Sta_Empty BNE %BT002 ; still empty LDR r0,[r3,#MB_ChRd] AND r2, r0, #&f CMP r2, r1 ; check its is our channel BNE %BT002 ; not our reply DoMemBarrier r3 LDMFD r13!, {r1-r3, pc} ; returning composite response in r0 ; Interrogate the platform and set up basic machine ; Sets up L2 cache addressing mode ; ARM_Memory_MB (in Megabytes) ; Frame buffer base address for 32bit fb ; Board_MAC address ; Board_Serial ; Board model & revision ; Available DMA channels ; HAL_QueryPlatform ROUT STMFD R13!, {r0-r6, lr} [ HALDebug BL HAL_DebugTXStrInline DCB "QueryPlatform",10,0 ALIGN ] MRC p15, 0, r4, c0, c0, 0 ; read Main ID Register AND r4, r4, #&FF00 CMP r4, #&C000 ; xxxxB76x for ARM1176, xxxxC07x for Cortex-A7 MOVCC r4, #GPU_L2CnonAl ; Pi 1 has L2 cache enabled MOVCS r4, #GPU_UnCached ; Pi 2 has L2 cache disabled STR r4, FB_CacheMode ; remember base of bus addresses (i.e. memory accessed by GPU and GPU peripherals like DMA and USB) ADRL r0, tagbuffer ADR r1, tagb MOV r2, #tagslen BL memcpy ; copy to workspace buffer MOV r1, r0 MOV r0, #MB_Chan_ARM2VC BL HAL_SendHostMessage ; ask the questions ADRL r5, tagbuffer ; now read the answers ADD r0,r5,#VCbs-tagb ; VC address and size LDMIA r0, {r1, r2} STR r1, VC_Base STR r2, VC_Size ADD r0,r5,#ARMbs-tagb ; ARM address and size LDMIA r0, {r1, r2} STR r1, ARM_Base STR r2, ARM_Size LDR r0, [r5, #boardmodel-tagb] LDR r1, [r5, #boardrev-tagb] LDR r2, [r5, #dmachans-tagb] STR r0, Board_Model STR r1, Board_Revision ; If no channels are reported as available, use channel 4 ; (Matches default channel mask from Linux) CMP r2, #0 MOVEQ r2, #1<<4 STR r2, ARM_DMAChannels LDR r0, [r5, #virtgpio-tagb] LDR r1, [r5, #touchbuf-tagb] STR r0, VirtGPIOBuf STR r1, TouchBuf ; Copy out and construct machine ID from MAC address ADRL a3, tagbuffer ADD a3, a3,#:INDEX:MAClo-:INDEX:tagb LDR lr, [a3, #-4] ; check if message completed TST lr, #&80000000 ; NE if successful MOVEQ a1, #0 MOVEQ a2, #0 LDMNEIA a3, {a1, a2} AND a3, a1, #&ff000000 MOV a3, a3, LSR #24 ORR a2, a3, a2, LSL #8 MOV a1, a1, LSL #8 ORR a1, a1, #&81 ; make it look like a Dallas unique id BIC a2, a2, #&ff000000 MOV a3, #0 ; compute a Dallas unique id CRC MOV a4, #7 ; number of bytes to do gbyte ; AND v2, a1, #&ff ; get next byte. shift reg round 8 byte AND v3, a2, #&ff ; shift reg round 8 byte MOV v1, v2, lsl #24 MOV v3, v3, lsl #24 ORR a1, v3, a1,lsr #8 ; shift reg round 8 byte ORR a2, v1, a2,lsr #8 ; shift reg round 8 byte EOR a3, a3, v2 ; MOV v1, #8 ; number of bits to do gbit ; MOVS a3, a3, LSR #1 ; shift bit out into carry EORCS a3, a3, #&8C ; feedback carry into other bits SUBS v1, v1, #1 ; one less bit to do BNE gbit ; loop until done whole byte SUBS a4, a4, #1 ; one less byte to do BNE gbyte ; loop until done all 7 bytes AND v2, a1, #&ff ; get next byte. shift reg round 8 byte AND v3, a2, #&ff ; shift reg round 8 byte MOV v1, v2, lsl #24 MOV v3, v3, lsl #24 ORR a1, v3, a1,lsr #8 ; shift reg round 8 byte ORR a2, v1, a2,lsr #8 ; shift reg round 8 byte ORR a2, a2, a3, lsl #24 ; insert crc into hi byte ADRL lr,MachineID STMIA lr, {a1, a2} [ HALDebug BL HAL_DebugTXStrInline DCB "QueryPlatform done",10,0 ALIGN ] LDMFD R13!, {r0-r6, pc} ; Series of VC side query tags. ; tagb DCD tagslen DCD 0 DCD ARM2VC_Tag_GetBoardMAC DCD 8 DCD 0 MAClo DCD 0 MAChi DCD 0 DCD ARM2VC_Tag_GetBoardSerial DCD 8 DCD 0 SNlo DCD 0 SNhi DCD 0 DCD ARM2VC_Tag_GetARMMemory DCD 8 DCD 0 ARMbs DCD 0 ARMsz DCD 0 DCD ARM2VC_Tag_GetVCMemory DCD 8 DCD 0 VCbs DCD 0 VCsz DCD 0 DCD ARM2VC_Tag_GetBoardModel DCD 4 DCD 0 boardmodel DCD 0 DCD ARM2VC_Tag_GetBoardRevision DCD 4 DCD 0 boardrev DCD 0 DCD ARM2VC_Tag_GetDMAChannels DCD 4 DCD 0 dmachans DCD 0 DCD ARM2VC_Tag_FBBlank DCD 4 DCD 4 DCD 1 ; Start with the screen blanked (avoids firmware displaying an RGB square) DCD ARM2VC_Tag_FBGetTouchBuf DCD 4 DCD 0 touchbuf DCD 0 DCD ARM2VC_Tag_SetClockRate DCD 12 DCD 12 DCD 2 DCD 3000000 ; Reset PL011 UART clock to default (Pi 3 has this set to 48MHz for BT, but currently we want to use it for plain serial) DCD 0 DCD ARM2VC_Tag_GetVirtGPIOBuf DCD 4 DCD 0 virtgpio DCD 0 DCD ARM2VC_Tag_End tagslen * . - tagb ASSERT tagslen <= ?tagbuffer MACRO $class HALDeviceField $field, $value LCLS myvalue [ "$value" = "" myvalue SETS "$field" | myvalue SETS "$value" ] ASSERT . - %A0 = HALDevice_$class$field [ ?HALDevice_$class$field = 2 DCW $myvalue ELIF ?HALDevice_$class$field = 4 DCD $myvalue | % ?HALDevice_$class$field ] MEND ; Template for mailbox device BCMMBox_Dev 0 HALDeviceField Type, HALDeviceType_Comms + HALDeviceComms_InterProc HALDeviceField ID, HALDeviceID_InterProc_BCMMBox HALDeviceField Location, HALDeviceBus_Sys + HALDeviceSysBus_AHB ; Guess HALDeviceField Version, 0 HALDeviceField Description, BCMMBox_Description HALDeviceField Address, 0 HALDeviceField Reserved1, 0 HALDeviceField Activate, BCMMBox_Activate HALDeviceField Deactivate, BCMMBox_Deactivate HALDeviceField Reset, BCMMBox_Reset HALDeviceField Sleep, BCMMBox_Sleep HALDeviceField Device, iDev_ARM_Mbx HALDeviceField TestIRQ, 0 HALDeviceField ClearIRQ, 0 HALDeviceField Reserved2, 0 ASSERT . - %A0 = HALDeviceSize BCMMBox_Description = "BCM283x VideoCore mailboxes", 0 ALIGN ; Initialise our HAL devices BCMMBox_InitDevices ROUT Entry ADRL a1, MBoxDevice ADR a2, BCMMBox_Dev MOV a3, #HALDeviceSize BL memcpy ADRL a2, MBoxDevice LDR a1, PeriBase ADD a1, a1, #MB_Base STR a1, [a2, #HALDevice_Address] MOV a1, #0 MOV lr, pc LDR pc, OSentries+4*OS_AddDevice EXIT BCMMBox_Activate MOV a1, #1 BCMMBox_Deactivate BCMMBox_Reset MOV pc, lr BCMMBox_Sleep MOV a1, #0 MOV pc, lr END