Commit 71e5f9c7 authored by John Ballance's avatar John Ballance
Browse files

Update of HAL to incorporate separate development of HAL by J Ballance

  Will now compile against initial developemnt start.elf, and against the
  start.elf in general release at this date. (compile switch UseALBlob in
  hdr.BCM2835). Extended header defs, Updated IRQ stuff, HAL_FramebufferAddress
  Reworked Timers, + a number of other bits. Still work in progress.
Detail:
  (list files and functions that have changed)
Admin:
  Compiled and working - as far as it goes -. Will enable use with the current
  start.elf, and is (subject to any minor changes introduced) ready for use with the
  version due for release shortly which will provide the correct transparency operation,
  and a better aligned frame buffer

Version 0.02. Tagged as 'BCM2835-0_02'
parent 1c532eb0
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "0.01"
Module_Version SETA 1
Module_MajorVersion SETS "0.02"
Module_Version SETA 2
Module_MinorVersion SETS ""
Module_Date SETS "10 May 2012"
Module_ApplicationDate SETS "10-May-12"
Module_Date SETS "20 May 2012"
Module_ApplicationDate SETS "20-May-12"
Module_ComponentName SETS "BCM2835"
Module_ComponentPath SETS "mixed/RiscOS/Sources/HAL/BCM2835"
Module_FullVersion SETS "0.01"
Module_HelpVersion SETS "0.01 (10 May 2012)"
Module_FullVersion SETS "0.02"
Module_HelpVersion SETS "0.02 (20 May 2012)"
END
/* (0.01)
/* (0.02)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 0.01
#define Module_MajorVersion_CMHG 0.02
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 10 May 2012
#define Module_Date_CMHG 20 May 2012
#define Module_MajorVersion "0.01"
#define Module_Version 1
#define Module_MajorVersion "0.02"
#define Module_Version 2
#define Module_MinorVersion ""
#define Module_Date "10 May 2012"
#define Module_Date "20 May 2012"
#define Module_ApplicationDate "10-May-12"
#define Module_ApplicationDate "20-May-12"
#define Module_ComponentName "BCM2835"
#define Module_ComponentPath "mixed/RiscOS/Sources/HAL/BCM2835"
#define Module_FullVersion "0.01"
#define Module_HelpVersion "0.01 (10 May 2012)"
#define Module_LibraryVersionInfo "0:1"
#define Module_FullVersion "0.02"
#define Module_HelpVersion "0.02 (20 May 2012)"
#define Module_LibraryVersionInfo "0:2"
......@@ -30,7 +30,7 @@
; its Linux drivers, thus making this port possible.
;
; on the prototype (UseALBlob==TRUE)
; VideoCore sets up the following address windows for use by the ARM core:
; - &08000000 -> &7E000000 : 4MB window granting access to peripherals
; - &08800000 -> &7E800000 : 4MB window granting access to USB peripheral
......@@ -44,22 +44,292 @@ HALDebug SETL {TRUE}
GBLL ExtFramestore
ExtFramestore SETL {TRUE}
; Peripheral address space
PERI_BASE * &08000000
;PERI2_BASE * &08800000
; set TRUE if using the start.elf originally used for development. FALSE otherwise
GBLL UseALBlob
UseALBlob SETL {FALSE}
GBLL SCR32
SCR32 SETL {TRUE}
; Debugging in the serial port (HAL_DebugTX, HAL_DebugRX)
GBLL Debug
Debug SETL {TRUE}
; Delay macro for really short delays
; RPi ARM11 registers
; Offsets from peripheral base address
ST_BASE * &3000 ;System Timer 0
DMA_BASE * &7000 ;DMA controller
PM_BASE * &100000 ;Power management
UART0_BASE * &201000 ;UART 0
UART1_BASE * &215000 ;UART 1
INTC_BASE * &B200 ;Interrupt controller
USB_BASE * &980000 ;USB controller
ISP_BASE * &A00000 ;ISP
; 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
[ UseALBlob
IO_Base * &08000000
IO_Size * &00c00000
|
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
[ UseALBlob
; FB_MemBase is the point at which riscos is 'capped'
; valid megabyte boundaries at &1e00000, &1f00000 and &2000000
; FB_Address is the start address of the frame buffer. Valid addresses
; (ideally) anywhere between &1e00000 and &2000000
; FB_Length is max framebuffer length. &800000 is just more than
; required for a 1920*1080 32bpp screen
; conclusions .. at the moment the wimp system/desktop appears to need megabyte ; base alignment
FB_MemBase * &01e00000 ; top address of our memory
FB_Address * &01e00000;&01f90000;&01f83ea0;
FB_Length * &007f8000;&00800000;
ASSERT FB_MemBase <= FB_Address
|
]
;
; 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
;
; 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
; far end replies on the same channel when command done.. e.g.
; command c0000001 gets 00000001 (ie channel1) reply
; mem barrier operation; ensures all explicit mem operations completed before
; instruction exits.
; (value 4 is all insructions, value 5 is just mem instructions)
; zeroes $r
MACRO
$label DataSyncBarrier $r
$label MOV $r, #0
MCR p15, 0, $r, c7, c10,4
MEND
MACRO
$label DoMemBarrier $r
$label MOV $r, #0
MCR p15, 0, $r, c7, c10,5
MEND
MACRO
$label FlushDataCache $r
$label MOV $r, #0
MCR p15, 0, $r, c7, c6,0
MEND
MACRO
$label FlushDataCacheRange $startaddr,$endaddr
$label BIC $startaddr, $startaddr, #&1f
BIC $endaddr, $endaddr, #&1f
MCRR 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
; Timer
Timer_Base * &00003000 ; base of system timer regs
ARM_Timer_Base * &0000b400 ; base of ARM timer regs
; DMA registers
DMA_Base * &00007000 ;
DMA0_CS * 0
DMA0_CONBLK_AD * 4
......@@ -78,6 +348,92 @@ DMAcb_pad0 # 4
DMAcb_pad1 # 4
sizeof_DMAcb * @
]
;
PM_Base * &00100000 ; power management
USB_Base * &00980000 ; USB
ISP_Base * &00a00000 ; ISP
;
; Interrupt handling
;
IRQ_Base * &0000B200
; Raspberry Pi interrupt sources.. there are several, with
; odd placing. all convcentrated int 3 32bit registers.
; The bottom 5 bits are the bit within the register, the next 2 the register
; there are a total of 21 interrupts in the main IRQ register
; and 64 possible ones in the GPU registers
; Not all are identified...
; so..
iDev_ARM_Timer * 0
iDev_ARM_Mbx * 1
iDev_ARM_DBell0 * 2
iDev_ARM_DBell1 * 3
iDev_ARM_GPU0Hlt * 4
iDev_ARM_GPU1Hlt * 5
iDev_ARM_IllegAcs1 * 6
iDev_ARM_IllegAcs0 * 7
iDev_IRQ_Pend1 * 8
iDev_IRQ_Pend2 * 9
iDev_GPU_IRQ7 * 10
iDev_GPU_IRQ9 * 11
iDev_GPU_IRQ10 * 12
iDev_GPU_IRQ18 * 13
iDev_GPU_IRQ19 * 14
iDev_GPU_IRQ53 * 15
iDev_GPU_IRQ54 * 16
iDev_GPU_IRQ55 * 17
iDev_GPU_IRQ56 * 18
iDev_GPU_IRQ57 * 19
iDev_GPU_IRQ62 * 20
; devices in register 1 - start at 32
iDev_GPU_AuxInt * 32+29
; devices in register 2 - start at 64
iDev_GPU_i2cslv * 32+43
iDev_GPU_pwa0 * 32+45
iDev_GPU_pwa1 * 32+46
iDev_GPU_smi * 32+48
iDev_GPU_ioi0 * 32+49
iDev_GPU_ioi1 * 32+50
iDev_GPU_ioi2 * 32+51
iDev_GPU_ioi3 * 32+52
iDev_GPU_i2c * 32+53
iDev_GPU_spi * 32+54
iDev_GPU_pcm * 32+55
iDev_GPU_Uart * 32+57
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
......@@ -33,20 +33,35 @@
GET Hdr:OSEntries
GET hdr.BCM2835
GBLL SCR32
SCR32 SETL {TRUE}
sb RN 9
^ 0,sb
PeriBase # 4
;Peri2Base # 4
IRQ_Base_Address # 4
ARM_Counter_IO_Address # 4
ARM_Timer_IO_Address # 4
UARTFCRSoftCopy # 4
DMAcb # sizeof_DMAcb
FB_Base # 4
FB_Size # 4
; align to 16 byte boundary
# (((:INDEX:@)+15):AND::NOT:15)-(:INDEX:@)
mbram # 0 ; structure needed for frame buffer descriptor
mbxres # 4
mbyres # 4
mbxvres # 4
mbyvres # 4
mbpitch # 4
mbbpp # 4
mbxoff # 4
myyoff # 4
mbbase # 4
mbscrsz # 4
ScreenBase # 4
FTextPixel # 4
BTextPixel # 4
......
......@@ -30,6 +30,8 @@
; its Linux drivers, thus making this port possible.
;
; not used any longer .. JB 20/2/12
UART011_DR * 0
UART011_RSR * 4
UART011_ECR * 4
......
......@@ -34,9 +34,12 @@
IMPORT HAL_UARTLineStatus
IMPORT HAL_UARTTransmitByte
IMPORT HAL_UARTReceiveByte
EXPORT HAL_DebugTX
EXPORT HAL_DebugRX
; in a1 = char
HAL_DebugTX STMFD sp!,{a1,lr}
busy MOV a1, #0
BL HAL_UARTLineStatus
......@@ -46,4 +49,15 @@ busy MOV a1, #0
MOV a1, #0
B HAL_UARTTransmitByte
; out a1 = char if there or -1
HAL_DebugRX stmfd sp!, {a2,lr}
mov a2, sp
sub sp,sp,#4
bl HAL_UARTReceiveByte
add sp,sp,#4
ldr a2, [sp]
tst a2, #1
mvneq a1, #0 ; -1 exit if no character
ldmfd sp!, {a2,pc}
END
......@@ -45,7 +45,7 @@
IMPORT output_text
IMPORT output_text_at
]
EXPORT Interrupt_Init
EXPORT HAL_IRQEnable
EXPORT HAL_IRQDisable
EXPORT HAL_IRQClear
......@@ -58,6 +58,7 @@
EXPORT HAL_FIQSource
EXPORT HAL_FIQStatus
EXPORT Timer_Init
EXPORT HAL_Timers
EXPORT HAL_TimerDevice
EXPORT HAL_TimerGranularity
......@@ -85,8 +86,6 @@
EXPORT HAL_NVMemoryRead
EXPORT HAL_NVMemoryWrite
EXPORT HAL_DebugRX
EXPORT HAL_ATAControllerInfo
EXPORT HAL_KbdScanSetup
......@@ -110,66 +109,100 @@
]
MEND
INTERRUPT_TIMER * 3
INTERRUPT_FLYBACK * -1
; interrupt pending registers are
; basic & 0ffset 0, pending 1 @ +4 and pending 2 @ +8
; set amd clear are pending 1 @ +0 and pending 2 @ +4 and basic @ +8
; device numbering is optimised for handling irqs
Interrupt_Init
LDR R0,PeriBase
ADD R0,R0,#IRQ_Base
STR R0,IRQ_Base_Address
MOV pc, lr
HAL_IRQEnable
CMN a1,#1
MOVEQ pc,lr
LDR ip, PeriBase
ADD ip, ip, #INTC_BASE
ADD ip, ip, #&10
MOV a2, #1
MOV a4, a1, LSR #5
AND a3, a1, #31
MOV a2, a2, LSL a3
STR a2, [ip, a4, LSL #2]
MOV a1, #0 ; how do we get the previous state without using a cache?
MOV pc, lr
LDR R12,IRQ_Base_Address
ADD R12,R12,#&10 ; IRQ_Enables1
MOV R1,#1
MOV R3,R0,LSR #5 ; shift to get relevant register
SUBS R3,R3,#1
MOVMI r3,#2 ; reorder which register
AND R2,R0,#&1F ; get bit in register
MOV R1,R1,LSL R2
DataSyncBarrier r2 ; resync before writing peripheral
LDR R2,[R12,R3,LSL #2]
ORR R0, R2, R1
STR R0,[R12,R3,LSL #2] ; set the bit
DataSyncBarrier r0 ; resync after reading peripheral
MOV PC,R14
HAL_IRQDisable
CMN a1,#1
MOVEQ pc,lr
LDR ip, PeriBase
ADD ip, ip, #INTC_BASE
ADD ip, ip, #&1C
MOV a2, #1
MOV a4, a1, LSR #5
AND a3, a1, #31
MOV a2, a2, LSL a3
STR a2, [ip, a4, LSL #2]
MOV a1, #1 ;!!! previous state
MOV pc,lr
LDR R12,IRQ_Base_Address
ADD R12,R12,#&1C ; IRQ_Disables1
MOV R1,#1
MOV R3,R0,LSR #5
SUBS R3,R3,#1
MOVMI r3,#2 ; reorder which register
DataSyncBarrier r2 ; resync before writing peripheral
AND R2,R0,#&1F ;
MOV R1,R1,LSL R2