Commit d58d5839 authored by Jeffrey Lee's avatar Jeffrey Lee

Fix compatibility with latest firmware

Detail:
  Firmware as of 28th July will allow the GPU to make use of the top 16MB of RAM in 1GB machines. This overlaps the ARM's IO space, essentially making that area of memory inaccessible to us.
  This causes problems because we rely on a couple of buffers which are located in VC memory (virtual GPIO buffer & FT5406 touchscreen buffer)
  At some point extra mailbox messages were added to allow the ARM to dictate the location of these buffers; so make use of those messages wherever possible.
  File changes:
  s/Messaging - Remove VirtGPIOBuf and TouchBuf related tags from the initialisation tag sequence. Add new GetVCBuffer function that can be called post-MMU init to deal with getting/setting the buffer addresses.
  s/Top - Use GetVCBuffer to initialise VirtGPIOBuf
  s/Touch - Use GetVCBuffer to get touchscreen buffer
  hdr/StaticWS - Remove TouchBuf from workspace, no longer needed
Admin:
  Tested on Raspberry Pi 3 with firmware from March 2016 (Set commands not supported), 21st July 2017 (set commands supported, but upper 16MB not used), 28th July 2017 (set commands supported and necessary)


Version 0.71. Tagged as 'BCM2835-0_71'
parent 49c74f92
/* (0.70)
/* (0.71)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.70
#define Module_MajorVersion_CMHG 0.71
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 14 May 2017
#define Module_Date_CMHG 31 Jul 2017
#define Module_MajorVersion "0.70"
#define Module_Version 70
#define Module_MajorVersion "0.71"
#define Module_Version 71
#define Module_MinorVersion ""
#define Module_Date "14 May 2017"
#define Module_Date "31 Jul 2017"
#define Module_ApplicationDate "14-May-17"
#define Module_ApplicationDate "31-Jul-17"
#define Module_ComponentName "BCM2835"
#define Module_ComponentPath "mixed/RiscOS/Sources/HAL/BCM2835"
#define Module_FullVersion "0.70"
#define Module_HelpVersion "0.70 (14 May 2017)"
#define Module_LibraryVersionInfo "0:70"
#define Module_FullVersion "0.71"
#define Module_HelpVersion "0.71 (31 Jul 2017)"
#define Module_LibraryVersionInfo "0:71"
......@@ -122,7 +122,6 @@ VC_Size # 4
Board_Model # 4
Board_Revision # 4
ARM_DMAChannels # 4
TouchBuf # 4
VirtGPIOBuf # 4
SafetyCatch # 4 ; Only valid on Compute Module 3
......
......@@ -37,8 +37,10 @@
GET Hdr:FSNumbers
GET Hdr:NewErrors
GET Hdr:BCMSupport
$GetMEMM
GET hdr.BCM2835
GET hdr.StaticWS
GET hdr.CastleMacros
IMPORT workspace
......@@ -50,6 +52,7 @@
IMPORT memcpy
EXPORT HAL_SendHostMessage
EXPORT HAL_QueryPlatform
EXPORT GetVCBuffer
EXPORT BCMMBox_InitDevices
; Send a message packet to the host and await the reply
......@@ -138,10 +141,6 @@ HAL_QueryPlatform ROUT
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
......@@ -219,6 +218,146 @@ gbit ;
]
LDMFD R13!, {r0-r6, pc}
; In:
; a1 = GET tag to fetch buffer for
; a2 = buffer size
; a3 = corresponding SET tag
; Out:
; a1 = buffer logical address, 0 if not present
; a2-a4, ip corrupt
;
; Query the VC for a data buffer. Historically the VC has dictated the locations
; of these buffers, but at some point the ability was added for the ARM to
; dictate the address to the GPU. With recent firmware versions, use of this
; feature is now mandatory, as on systems with 1GB of RAM the firmware will now
; attempt to make use of the upper 16MB of RAM (which overlaps the ARM's IO
; space, making it inaccessible to the ARM)
;
; Annoyingly, the main tags we're interested in don't follow the usual pattern
; of adding &8000 in order to convert a GET request to a SET, so we require both
; the GET and SET values to be explicitly specified.
GetVCBuffer ROUT
[ HALDebug
STR lr, [sp, #-4]!
BL %FT01
BL HAL_DebugHexTX4
BL HAL_DebugTXStrInline
DCB "log",10,0
ALIGN
LDR pc, [sp], #4
01
]
STMFD sp!, {a1-a2, lr}
[ HALDebug
BL HAL_DebugHexTX4
BL HAL_DebugTXStrInline
DCB "GetVCBuffer",10,0
ALIGN
]
MOV a1, a3 ; Start off with the SET request
; Reserve space for the buffer in NCNB workspace
LDR ip, NCNBPhysAddr
LDR a4, NCNBAddr
MOV a3, a2
MOV lr, #0
10
SUBS a3, a3, #4
STRGE lr, [a4, a3] ; Ensure buffer memory is zeroed, just in case ARM/VC is confused by any previous content (like a tag buffer from a previous call to GetVCBuffer). E.g. recent firmware versions will allow you to get/set the FT5406 touchscreen buffer, even if the touchscreen isn't connected.
BGT %BT10
ADD a3, ip, a2
ADD a4, a4, a2
; Now construct a message tag block after it
ADD a3, a3, #15 ; Align for mailbox use
ADD a4, a4, #15
BIC a3, a3, #15
BIC a4, a4, #15
STR a1, [a4, #8] ; Tag
MOV a1, #7*4
MOV a2, #0
STMIA a4!, {a1, a2} ; Total length, out flags
MOV a1, #4
MOV a2, #4
MOV lr, #ARM2VC_Tag_End
STMIB a4, {a1, a2, ip, lr} ; Tag length, in length, in data, terminator
MOV a2, a3
MOV a1, #MB_Chan_ARM2VC
BL HAL_SendHostMessage
[ HALDebug
LDR a1, [a4, #-8]
BL HAL_DebugHexTX4
LDR a1, [a4, #-4]
BL HAL_DebugHexTX4
LDR a1, [a4, #0]
BL HAL_DebugHexTX4
LDR a1, [a4, #4]
BL HAL_DebugHexTX4
LDR a1, [a4, #8]
BL HAL_DebugHexTX4
LDR a1, [a4, #12]
BL HAL_DebugHexTX4
LDR a1, [a4, #16]
BL HAL_DebugHexTX4
BL HAL_DebugTXStrInline
DCB "set",10,0
ALIGN
]
; On success, firmware should overwrite the address with zero
LDR a1, [a4, #12]
CMP a1, #0
BNE %FT50
; Buffer set success; update NCNB claim and return the claimed addr
LDMIA sp!, {a1-a2, lr}
LDR a1, NCNBAddr
LDR ip, NCNBPhysAddr
ADD a3, a1, a2
ADD ip, ip, a2
STR a3, NCNBAddr
STR ip, NCNBPhysAddr
MOV pc, lr
50
; Buffer set failure. Try getting the address instead.
MOV a1, #7*4
MOV a2, #0
STMDB a4, {a1, a2} ; Total length, out flags
LDR a1, [sp]
MOV a2, #4
MOV ip, #0
MOV lr, #0
STMIA a4, {a1, a2, ip, lr} ; Tag, tag length, in length, in data
; n.b. assuming terminator word still in place!
MOV a2, a3
MOV a1, #MB_Chan_ARM2VC
BL HAL_SendHostMessage
[ HALDebug
LDR a1, [a4, #-8]
BL HAL_DebugHexTX4
LDR a1, [a4, #-4]
BL HAL_DebugHexTX4
LDR a1, [a4, #0]
BL HAL_DebugHexTX4
LDR a1, [a4, #4]
BL HAL_DebugHexTX4
LDR a1, [a4, #8]
BL HAL_DebugHexTX4
LDR a1, [a4, #12]
BL HAL_DebugHexTX4
LDR a1, [a4, #16]
BL HAL_DebugHexTX4
BL HAL_DebugTXStrInline
DCB "get",10,0
ALIGN
]
; On success, firmware should write non-zero address
LDR a1, [a4, #12]
BICS a1, a1, #&c0000000 ; Convert to ARM phys addr
LDMIA sp!, {a2-a3, lr} ; Junk stacked a1-a2, but also loads a2 into correct reg for OS_MapInIO
MOVEQ pc, lr
; Buffer exists, map it in
MOV a2, a1
MOV a1, #1:SHL:L1_TEXShift ; VMSA Normal, non-cacheable
CallOS OS_MapInIO, tailcall
; Series of VC side query tags.
;
tagb DCD tagslen
......@@ -266,20 +405,12 @@ dmachans DCD 0
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
......
......@@ -40,7 +40,6 @@
GET Hdr:FSNumbers
GET Hdr:NewErrors
GET Hdr:BCMSupport
$GetMEMM
GET Hdr:HALEntries
......@@ -146,6 +145,7 @@
IMPORT HAL_SendHostMessage
IMPORT HAL_QueryPlatform
IMPORT GetVCBuffer
EXPORT HAL_Base
IMPORT memcpy
......@@ -697,11 +697,7 @@ HAL_Init
ADRL a4, workspace ; where they are post ROM relocation
LDR a1, [a4, #:INDEX:FB_CacheMode]
LDR a2, [a4, #:INDEX:TouchBuf]
LDR a3, [a4, #:INDEX:VirtGPIOBuf]
STR a1, FB_CacheMode ; GPU cache mode
STR a2, TouchBuf
STR a3, VirtGPIOBuf
LDR a3, [a4, #:INDEX:VC_Size]
LDR a2, [a4, #:INDEX:VC_Base]
......@@ -726,6 +722,9 @@ HAL_Init
BL HAL_DebugHexTX4
LDR a1, VC_Size
BL HAL_DebugHexTX4
BL HAL_DebugTXStrInline
DCB "VC memory",10,0
ALIGN
]
; Get the physical address of NCNB workspace
......@@ -738,16 +737,13 @@ HAL_Init
ORR a1, a1, a3
STR a1, NCNBPhysAddr
; Map in virtual GPIO buffer if present
LDR a2, VirtGPIOBuf
BICS a2, a2, #&C0000000
STREQ a2, VirtGPIOBuf
BEQ %FT10
MOV a1, #1:SHL:L1_TEXShift ; VMSA Normal, non-cacheable
MOV a3, #4096
CallOS OS_MapInIO
; Try and initialise virtual GPIO buffer
LDR a1, =ARM2VC_Tag_GetVirtGPIOBuf
MOV a2, #4096 ; should only need a word, but request a whole page for safety (avoid getting caught out if they make the buffer bigger in future)
LDR a3, =ARM2VC_Tag_SetVirtGPIOBuf
BL GetVCBuffer
STR a1, VirtGPIOBuf
10
BL CMOS_Init
BL Interrupt_Init ; initialise our interrupts
BL Timer_Init
......
......@@ -31,7 +31,10 @@
GET Hdr:ListOpts
GET Hdr:Macros
GET Hdr:Proc
$GetMEMM
GET Hdr:System
GET Hdr:FSNumbers
GET Hdr:NewErrors
GET Hdr:BCMSupport
GET hdr.BCM2835
GET hdr.StaticWS
GET hdr.CastleMacros
......@@ -39,6 +42,7 @@
EXPORT Touch_InitDevices
IMPORT memcpy
IMPORT GetVCBuffer
MACRO
$class HALDeviceField $field, $value
......@@ -88,24 +92,19 @@ Touch_Description
; Initialise our HAL devices
Touch_InitDevices ROUT
Entry "v1"
LDR v1, TouchBuf
CMP v1, #0
; Try and initialise the register softcopy buffer
LDR a1, =ARM2VC_Tag_FBGetTouchBuf
MOV a2, #256
LDR a3, =ARM2VC_Tag_FBSetTouchBuf
BL GetVCBuffer
MOVS v1, a1
EXIT EQ
ADRL a1, TouchDevice
ADR a2, Touch_Dev
MOV a3, #HALDeviceSize
BL memcpy
; Guess whether we've been given an ARM or GPU physical address
LDR a1, FB_CacheMode
CMP v1, a1
SUBHS v1, v1, a1
; Map in the memory (assumed to be RAM, not actual hardware regs)
MOV a1, #1:SHL:L1_TEXShift ; VMSA Normal, non-cacheable
MOV a2, v1
MOV a3, #256
CallOS OS_MapInIO
ADRL a2, TouchDevice
STR a1, [a2, #HALDevice_Address]
STR v1, [a2, #HALDevice_Address]
; Register the device
MOV a1, #0
CallOS OS_AddDevice
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment