Boot 26.9 KB
Newer Older
Ben Avison's avatar
Ben Avison committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
; Copyright 2011 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.
;

Robert Sprowson's avatar
Robert Sprowson committed
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
        GET     Hdr:ListOpts
        GET     Hdr:Macros
        GET     Hdr:System
        GET     Hdr:Machine.<Machine>
        GET     Hdr:HALSize.<HALSize>

        GET     Hdr:MEMM.VMSAv6

        GET     Hdr:Proc
        GET     Hdr:OSEntries
        GET     Hdr:HALEntries

        GET     hdr.omap4430
        GET     hdr.StaticWS
        GET     hdr.SDRC
        GET     hdr.Interrupts
        GET     hdr.Timers
        GET     hdr.GPIO
        GET     hdr.UART
        GET     hdr.PRCM
        GET     hdr.GPMC
Ben Avison's avatar
Ben Avison committed
37 38 39

; This version assumes a RISC OS image starting OSROM_HALSize after us.

Robert Sprowson's avatar
Robert Sprowson committed
40
; FIQs are not available on Cortex-A9 (outside the secure world)
Ben Avison's avatar
Ben Avison committed
41 42 43
; FIQ-based debugger - prints out the PC when the beagleboard/touchbook USER button is pressed
; The code installs itself when HAL_InitDevices is called with R0=123.
; e.g. SYS "OS_Hardware",123,,,,,,,,0,100
Robert Sprowson's avatar
Robert Sprowson committed
44 45
                GBLL    FIQDebug
FIQDebug        SETL    {FALSE}
Robert Sprowson's avatar
Robert Sprowson committed
46

Robert Sprowson's avatar
Robert Sprowson committed
47 48
                GBLL    MoreDebug
MoreDebug       SETL    Debug :LAND: {FALSE}
Ben Avison's avatar
Ben Avison committed
49

Robert Sprowson's avatar
Robert Sprowson committed
50 51 52
                GBLL    UseSR44x
UseSR44x        SETL    {TRUE}

Robert Sprowson's avatar
Robert Sprowson committed
53
        AREA    |Asm$$Code|, CODE, READONLY, PIC
Ben Avison's avatar
Ben Avison committed
54

Robert Sprowson's avatar
Robert Sprowson committed
55
        EXPORT  rom_checkedout_ok
Ben Avison's avatar
Ben Avison committed
56

Robert Sprowson's avatar
Robert Sprowson committed
57 58 59 60 61 62
        IMPORT  HAL_Base
        IMPORT  DebugHALPrint
        IMPORT  DebugHALPrintReg
        IMPORT  DebugHALPrintByte
        IMPORT  RTC_Init
        IMPORT  DebugCallstack
Robert Sprowson's avatar
Robert Sprowson committed
63 64
        IMPORT  SR44x_Init
        IMPORT  SR44x_Exit
65 66
        IMPORT  PowerCtrl_Init
        IMPORT  PowerCtrl_SwitchOff
Ben Avison's avatar
Ben Avison committed
67 68

; v8 is used as pointer to RISC OS entry table throughout pre-MMU stage.
Robert Sprowson's avatar
Robert Sprowson committed
69 70 71 72 73 74 75
        MACRO
        CallOSM $entry, $reg
        LDR     ip, [v8, #$entry*4]
        MOV     lr, pc
        ADD     pc, v8, ip
        MEND

Ben Avison's avatar
Ben Avison committed
76
rom_checkedout_ok
Robert Sprowson's avatar
Robert Sprowson committed
77 78 79 80 81
        ; On entry, v8 -> OS entry table, sb -> board config
        ; Register the attached RAM

        LDR     v1, =DMM_Base
        MOV     sp, #0
Robert Sprowson's avatar
Robert Sprowson committed
82 83 84 85
        ; Check all DMM_LISA_MAP_i registers (starting with highest priority)
        LDR     a1, =DMM_LISA_MAP_3
        LDR     a4, =DMM_LISA_MAP_i_SDRC_ADDRSPC
05
Robert Sprowson's avatar
Robert Sprowson committed
86
        LDR     a2, =DMM_LISA_MAP_i_SDRC_MAP
Robert Sprowson's avatar
Robert Sprowson committed
87
        LDR     a3, [v1, a1]
Robert Sprowson's avatar
Robert Sprowson committed
88
        ANDS    a2, a3, a2      ; MAP_x used ?
Robert Sprowson's avatar
Robert Sprowson committed
89 90 91 92 93 94 95 96 97 98 99 100 101 102
        BEQ     %FT10
        AND     a2, a3, a4      ; check ADDRSPC
        CMP     a2, #DMM_LISA_MAP_i_SDRC_ADDRSPC_SDRAM
        BEQ     %FT15
10
        ; Next DMM_LISA_MAP_x
        CMP     a1, #DMM_LISA_MAP_0
        SUBHI   a1, a1, #4
        BHI     %BT05

        ; This should not happen: no RAM found
        B       .
15
        ; Check DMM_LISA_MAP_x
Robert Sprowson's avatar
Robert Sprowson committed
103 104 105 106 107 108
        LDR     a2, =DMM_LISA_MAP_i_SYS_SIZE
        AND     a2, a3, a2
        MOV     a2, a2, LSR #DMM_LISA_MAP_i_SYS_SIZE_SHIFT
        LDR     a4, =(16 * 1024 * 1024) ; 16 MiB smallest size
        MOV     a4, a4, LSL a2          ; final size
        AND     a2, a3, #DMM_LISA_MAP_i_SYS_ADDR
109 110 111
        ; Check for overflow of address range
        ADDS    a3, a4, a2
        LDRCS   a3, =((4096 - 16) << 20)        ; round down to next 16 MiB boundary
Robert Sprowson's avatar
Robert Sprowson committed
112 113 114 115 116
        LDR     a4, =&FFFFFFFF
        ADD     sp, a2, #4096 ; HAL spec says that (for software reset compliance only?) stack should be 4K into first block
        MOV     a1, #0
        STR     a1, [sp, #-4]!
        CallOSM OS_AddRAM
Robert Sprowson's avatar
Robert Sprowson committed
117
        DebugChar a3,a2,71
Robert Sprowson's avatar
Robert Sprowson committed
118

Robert Sprowson's avatar
Robert Sprowson committed
119
        ; Check for reset cause: test PRM_RSTST.GLOBAL_COLD_RST
Robert Sprowson's avatar
Robert Sprowson committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
        LDR     a3, =L4_PowerMan
        ADD     a3, a3, #DEVICE_PRM
        LDR     a2, [a3, #PRM_RSTST]
        STR     a2, [a3, #PRM_RSTST]    ; clear old status
        TST     a2, #1                  ; GLOBAL_COLD_RST
        MOV     a4, a1
        MOVNE   a1, #(OSStartFlag_RAMCleared :OR: OSStartFlag_POR)
        MOVEQ   a1, #OSStartFlag_RAMCleared
        ADRL    a2, HAL_Base + OSROM_HALSize    ; a2 -> RISC OS image
        ADR     a3, HALdescriptor
        CallOSM OS_Start


HALdescriptor   DATA
        DCD     HALFlag_NCNBWorkspace
        DCD     HAL_Base - HALdescriptor
        DCD     OSROM_HALSize
        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

153
        IMPORT  Video_Init
Robert Sprowson's avatar
Robert Sprowson committed
154 155 156 157 158 159 160 161 162 163 164
        IMPORT  Interrupt_Init
        IMPORT  Timer_Init
        IMPORT  PRCM_SetClocks
        IMPORT  USB_Init
        IMPORT  I2C_Init
        IMPORT  SDMA_Init
        IMPORT  VideoDevice_Init
        IMPORT  Audio_Init
        IMPORT  GPMC_Init
        IMPORT  GPIO_Init
        IMPORT  GPIOx_SetAsOutput
Robert Sprowson's avatar
Robert Sprowson committed
165
        IMPORT  GPIO_InitDevice
Ben Avison's avatar
Ben Avison committed
166
        IMPORT  SDIO_InitDevices
Robert Sprowson's avatar
Robert Sprowson committed
167
        IMPORT  NVMemory_Init
168
        IMPORT  NVMemory_InitDevice
Robert Sprowson's avatar
Robert Sprowson committed
169 170

        EXPORT  Board_InitDevices_None
Ben Avison's avatar
Ben Avison committed
171
        EXPORT  Board_InitDevices_Panda
Robert Sprowson's avatar
Robert Sprowson committed
172 173 174 175 176 177 178 179 180 181 182 183

        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
Jeffrey Lee's avatar
Jeffrey Lee committed
184
        IMPORT  HAL_IRQMax
Robert Sprowson's avatar
Robert Sprowson committed
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212

        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_NVMemorySize
        IMPORT  HAL_NVMemoryPageSize
        IMPORT  HAL_NVMemoryProtectedSize
        IMPORT  HAL_NVMemoryProtection
        IMPORT  HAL_NVMemoryRead
        IMPORT  HAL_NVMemoryWrite

213
        IMPORT  HAL_VideoIICOp ; Implemented in s.I2C
Robert Sprowson's avatar
Robert Sprowson committed
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233

        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
Ben Avison's avatar
Ben Avison committed
234
        IMPORT  HAL_UARTDefault
Robert Sprowson's avatar
Robert Sprowson committed
235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292

        IMPORT  HAL_DebugRX
        IMPORT  HAL_DebugTX

        IMPORT  HAL_ATAControllerInfo

        IMPORT  HAL_KbdScanSetup
        IMPORT  HAL_KbdScan
        IMPORT  HAL_KbdScanFinish
        IMPORT  HAL_KbdScanInterrupt

        IMPORT  HAL_USBControllerInfo

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
        HALEntry HAL_NVMemorySize
        HALEntry HAL_NVMemoryPageSize
        HALEntry HAL_NVMemoryProtectedSize
        HALEntry HAL_NVMemoryProtection
        NullEntry ; HAL_NVMemoryIICAddress
        HALEntry HAL_NVMemoryRead
        HALEntry HAL_NVMemoryWrite

        HALEntry HAL_IICBuses
        HALEntry HAL_IICType
        NullEntry ; HAL_IICSetLines
        NullEntry ; HAL_IICReadLines
        HALEntry HAL_IICDevice
        HALEntry HAL_IICTransfer
        HALEntry HAL_IICMonitorTransfer

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307
        NullEntry ; HALEntry HAL_VideoFlybackDevice
        NullEntry ; HALEntry HAL_VideoSetMode
        NullEntry ; HALEntry HAL_VideoWritePaletteEntry
        NullEntry ; HALEntry HAL_VideoWritePaletteEntries
        NullEntry ; HALEntry HAL_VideoReadPaletteEntry
        NullEntry ; HALEntry HAL_VideoSetInterlace
        NullEntry ; HALEntry HAL_VideoSetBlank
        NullEntry ; HALEntry HAL_VideoSetPowerSave
        NullEntry ; HALEntry HAL_VideoUpdatePointer
        NullEntry ; HALEntry HAL_VideoSetDAG
        NullEntry ; HALEntry HAL_VideoVetMode
        NullEntry ; HALEntry HAL_VideoPixelFormats
        NullEntry ; HALEntry HAL_VideoFeatures
        NullEntry ; HALEntry HAL_VideoBufferAlignment
        NullEntry ; HALEntry HAL_VideoOutputFormat
Robert Sprowson's avatar
Robert Sprowson committed
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375

        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

Jeffrey Lee's avatar
Jeffrey Lee committed
376
        HALEntry HAL_IRQMax
Robert Sprowson's avatar
Robert Sprowson committed
377

378
        NullEntry ; HAL_VideoRender
Robert Sprowson's avatar
Robert Sprowson committed
379

380 381 382
        NullEntry ; HAL_USBPortPower
        NullEntry ; HAL_USBPortStatus
        NullEntry ; HAL_USBPortDevice
Robert Sprowson's avatar
Robert Sprowson committed
383

384
        HALEntry HAL_VideoIICOp
Robert Sprowson's avatar
Robert Sprowson committed
385 386 387 388 389 390

        NullEntry ; HAL_TimerIRQClear
        NullEntry ; HAL_TimerIRQStatus

        HALEntry HAL_ExtMachineID

391
        NullEntry ; HAL_VideoFramestoreAddress
Ben Avison's avatar
Ben Avison committed
392 393 394

        HALEntry HAL_UARTDefault

Robert Sprowson's avatar
Robert Sprowson committed
395
HAL_Entries     *       (. - HAL_EntryTable) / 4
Ben Avison's avatar
Ben Avison committed
396 397 398 399 400 401


;--------------------------------------------------------------------------------------


HAL_Init
Robert Sprowson's avatar
Robert Sprowson committed
402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
        Entry   "v1-v3"

        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_ABE
        MOV     a3, #L3_ABE_Size
        CallOS  OS_MapInIO
        STR     a1, L3_Log

        MOV     a1, #0
        LDR     a2, =L4_ABE
        MOV     a3, #L4_ABE_Size
        CallOS  OS_MapInIO
        STR     a1, L4_ABE_Log

        ; Timers
        ADD     a2, a1, #(TIMER_BASE - L4_ABE)
        STR     a2, Timers_Log

        MOV     a1, #0
        LDR     a2, =L4_Core
        MOV     a3, #L4_Core_Size
        CallOS  OS_MapInIO
        STR     a1, L4_Core_Log

        ; ClockMan + ClockMan2
        ADD     a3, a1, #(L4_ClockMan - L4_Core)
        STR     a3, L4_ClockMan_Log
        ADD     a3, a1, #(L4_ClockMan2 - L4_Core)
        STR     a3, L4_ClockMan2_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_Wakeup
        MOV     a3, #L4_Wakeup_Size
        CallOS  OS_MapInIO
        STR     a1, L4_Wakeup_Log

        ; L4_PowerMan, L4_32KTIMER, L4_GPIO1
        ADD     a3, a1, #(L4_PowerMan - L4_Wakeup)
        STR     a3, L4_PowerMan_Log
        ADD     a3, a1, #(L4_32KTIMER - L4_Wakeup)
        STR     a3, L4_32KTIMER_Log
        ADD     a3, a1, #(L4_GPIO1 - L4_Wakeup)
        STR     a3, L4_GPIO1_Log

        MOV     a1, #0
        LDR     a2, =L4_Per
        MOV     a3, #L4_Per_Size
        CallOS  OS_MapInIO
        STR     a1, L4_Per_Log
Ben Avison's avatar
Ben Avison committed
470 471 472

; this address range is only for backward compatibility !
; TI recommends using the DSS address range
Robert Sprowson's avatar
Robert Sprowson committed
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
;       ; Display
;       ADD     a3, a1, #(L4_Display - L4_Per)
;       STR     a3, L4_Display_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

        ; Display subsystem (DSS)
        MOV     a1, #0
        LDR     a2, =DSS_Base
        MOV     a3, #(32 * 1024)
        CallOS  OS_MapInIO
        STR     a1, L4_Display_Log

        ; Interrupt controller
        MOV     a1, #0
        LDR     a2, =MPU_INTC
        MOV     a3, #MPU_INTC_SIZE
        CallOS  OS_MapInIO
        STR     a1, MPU_INTC_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
        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 + ?BoardConfig_HALUART-4)
10      BL      phys2log
        SUBS    a1, a1, #4
        BGE     %BT10
530 531 532 533 534 535

        ; handle supported I2C interfaces (at most MaxI2CControllers)
        LDRB    v1, [sb, #BoardConfig_NumI2C]
        CMP     v1, #MaxI2CControllers
        MOVGT   v1, #MaxI2CControllers
        ADR     v2, (I2C_Table + I2C_HW)
Robert Sprowson's avatar
Robert Sprowson committed
536
        MOV     a1, #BoardConfig_HALI2C
537
10
Robert Sprowson's avatar
Robert Sprowson committed
538
        BL      phys2log
539 540 541 542
        STR     a2, [v2], #I2CBlockSize
        ADD     a1, a1, #4
        SUBS    v1, v1, #1
        BGT     %BT10
Ben Avison's avatar
Ben Avison committed
543 544

 [ Debug
Robert Sprowson's avatar
Robert Sprowson committed
545 546
        DebugTX "HAL_Init"
        DebugTime a1, "@ "
Ben Avison's avatar
Ben Avison committed
547 548
 ]

Robert Sprowson's avatar
Robert Sprowson committed
549
        BL      PRCM_SetClocks  ; Calls Timer_init & starts GPTIMER5
Ben Avison's avatar
Ben Avison committed
550

Robert Sprowson's avatar
Robert Sprowson committed
551
        BL      I2C_Init        ; Uses GPTIMER5
Ben Avison's avatar
Ben Avison committed
552

Robert Sprowson's avatar
Robert Sprowson committed
553 554
        ; Make sure all GPIO IRQs are disabled before we potentially start enabling them
        BL      GPIO_Init
Ben Avison's avatar
Ben Avison committed
555

Robert Sprowson's avatar
Robert Sprowson committed
556
 [ MoreDebug
557
        DebugTX "Video_Init"
Robert Sprowson's avatar
Robert Sprowson committed
558
 ] ; MoreDebug
559
        BL      Video_Init
Ben Avison's avatar
Ben Avison committed
560

Robert Sprowson's avatar
Robert Sprowson committed
561
 [ MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
562
        DebugTX "USB_Init"
Robert Sprowson's avatar
Robert Sprowson committed
563
 ] ; MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
564
        BL      USB_Init
Ben Avison's avatar
Ben Avison committed
565

566 567 568 569 570
 [ MoreDebug
        DebugTX "NVMemory_Init"
 ] ; MoreDebug
        BL      NVMemory_Init

Robert Sprowson's avatar
Robert Sprowson committed
571
 [ MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
572
        DebugTX "Timer_Init"
Robert Sprowson's avatar
Robert Sprowson committed
573
 ] ; MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
574
        BL      Timer_Init      ; Re-inits timers
Ben Avison's avatar
Ben Avison committed
575

Robert Sprowson's avatar
Robert Sprowson committed
576
 [ MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
577
        DebugTX "Interrupt_Init"
Robert Sprowson's avatar
Robert Sprowson committed
578
 ] ; MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
579
        BL      Interrupt_Init
Ben Avison's avatar
Ben Avison committed
580

Robert Sprowson's avatar
Robert Sprowson committed
581
 [ MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
582
        DebugTX "GPMC_Init"
Robert Sprowson's avatar
Robert Sprowson committed
583
 ] ; MoreDebug
Robert Sprowson's avatar
Robert Sprowson committed
584
        BL      GPMC_Init
Ben Avison's avatar
Ben Avison committed
585

Robert Sprowson's avatar
Robert Sprowson committed
586 587
        LDRB    v1, [sb, #BoardConfig_NumUART]
10      SUBS    v1, v1, #1
Robert Sprowson's avatar
Robert Sprowson committed
588
 [ Debug
Robert Sprowson's avatar
Robert Sprowson committed
589 590 591 592 593 594 595 596 597 598
        BLT     %FT20
        ; Don't reset the debug UART
        LDR     a3, [sb, #BoardConfig_DebugUART]
        ADD     a2, sb, v1, LSL #2
        LDR     a2, [a2, #BoardConfig_HALUART]
        CMP     a3, a2
        BEQ     %BT10
        MOV     a1, v1
        ADR     lr, %BT10
        B       HAL_UARTStartUp
Robert Sprowson's avatar
Robert Sprowson committed
599
 |
Robert Sprowson's avatar
Robert Sprowson committed
600 601 602
        MOVGE   a1, v1
        ADRGE   lr, %BT10
        BGE     HAL_UARTStartUp
Robert Sprowson's avatar
Robert Sprowson committed
603 604
 ]
20
Ben Avison's avatar
Ben Avison committed
605

Robert Sprowson's avatar
Robert Sprowson committed
606 607
        ; Mark HAL as initialised
        STR     pc, HALInitialised ; Any nonzero value will do
Ben Avison's avatar
Ben Avison committed
608

Robert Sprowson's avatar
Robert Sprowson committed
609
        DebugTime a1, "HAL initialised @ "
Robert Sprowson's avatar
Robert Sprowson committed
610

Robert Sprowson's avatar
Robert Sprowson committed
611
        EXIT
Ben Avison's avatar
Ben Avison committed
612 613 614 615 616 617

; 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
Robert Sprowson's avatar
Robert Sprowson committed
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
        LDR     a3, [sb, a1]
        CMP     a3, #0 ; Null pointers are valid; ignore them
        MOVEQ   a2, #0
        MOVEQ   pc, lr
        LDR     a2, =L3_ABE
        SUB     a2, a3, a2
        CMP     a2, #L3_ABE_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_ABE
        CMP     a2, #L4_ABE_Size
        LDRLO   a3, L4_ABE_Log
        BLO     %FT10

        SUB     a2, a3, #L4_Core
        CMP     a2, #L4_Core_Size
        LDRLO   a3, L4_Core_Log
        SUBHI   a2, a2, #(L4_Wakeup - L4_Core)
        LDRHI   a3, L4_Wakeup_Log
Ben Avison's avatar
Ben Avison committed
643
10
Robert Sprowson's avatar
Robert Sprowson committed
644 645 646
        ADD     a2, a2, a3
        STR     a2, [sb, a1]
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
647 648

; Initialise and relocate the entry table.
Robert Sprowson's avatar
Robert Sprowson committed
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
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
Ben Avison's avatar
Ben Avison committed
665 666

HAL_Null
Robert Sprowson's avatar
Robert Sprowson committed
667
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
668 669 670

HAL_InitDevices
 [ FIQDebug
Robert Sprowson's avatar
Robert Sprowson committed
671 672 673 674 675 676 677 678 679
        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
Robert Sprowson's avatar
Robert Sprowson committed
680
        DSB     SY ; wait for clean to complete
Robert Sprowson's avatar
Robert Sprowson committed
681 682
        MCR     p15, 0, a1, c7, c5, 1 ; invalidate ICache entry (to PoC)
        MCR     p15, 0, a1, c7, c5, 6 ; invalidate entire BTC
Robert Sprowson's avatar
Robert Sprowson committed
683 684
        DSB     SY ; wait for cache invalidation to complete
        ISB     SY ; wait for BTC invalidation to complete?
Robert Sprowson's avatar
Robert Sprowson committed
685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
        ; 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
        ; tail-optimised, repeating the HAL device init would be a bad thing!
        B       HAL_FIQEnable
Ben Avison's avatar
Ben Avison committed
700 701
10
 ]
Robert Sprowson's avatar
Robert Sprowson committed
702 703 704
        Entry   "v1-v3"
        DebugTime a1, "HAL_InitDevices @ "
        ; Common HAL devices
Robert Sprowson's avatar
Robert Sprowson committed
705 706 707
 [ UseSR44x
        BL      SR44x_Init
 ]
708
        BL      NVMemory_InitDevice
Robert Sprowson's avatar
Robert Sprowson committed
709 710 711 712
        BL      RTC_Init
        BL      SDMA_Init
        BL      VideoDevice_Init
        BL      Audio_Init
713
        BL      PowerCtrl_Init
Robert Sprowson's avatar
Robert Sprowson committed
714 715
        ; Board-specific HAL devices
        LDR     pc, [sb, #BoardConfig_InitDevices]
Ben Avison's avatar
Ben Avison committed
716
Board_InitDevices_None
Ben Avison's avatar
Ben Avison committed
717 718 719 720 721 722 723
        EXIT


Board_InitDevices_Panda
        ; SD needs boardtype and revision to configure the devices correctly
        ; for OMAP4 we just differentiate between ES (4460) and non-ES (4430)
        LDR     a2, L4_Core_Log
Robert Sprowson's avatar
Robert Sprowson committed
724 725
        LDR     a1, =(L4_CONTROL_IDCODE - L4_Core)
        LDR     a2, [a2, a1]
Ben Avison's avatar
Ben Avison committed
726
        LDR     v2, =HAWKEYE_OMAP4460_ES10
Robert Sprowson's avatar
Robert Sprowson committed
727 728
        UBFX    a2, a2, #12, #16
        CMP     v2, a2
Ben Avison's avatar
Ben Avison committed
729 730 731
        MOV     a1, #GPIOType_OMAP4_Panda
        MOVNE   a2, #GPIORevision_Panda
        MOVEQ   a2, #GPIORevision_PandaES
Robert Sprowson's avatar
Robert Sprowson committed
732 733 734 735
        Push    "a1-a2"
        BL      GPIO_InitDevice
        ; SD needs the same parameters to configure the device correctly
        Pull    "a1-a2"
Ben Avison's avatar
Ben Avison committed
736
        BL      SDIO_InitDevices
Robert Sprowson's avatar
Robert Sprowson committed
737 738
        DebugTime a1, "Done @ "
        EXIT
Ben Avison's avatar
Ben Avison committed
739 740 741


HAL_ControllerAddress
Robert Sprowson's avatar
Robert Sprowson committed
742 743
        MOV     a1, #0
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
744 745

HAL_HardwareInfo
Robert Sprowson's avatar
Robert Sprowson committed
746 747 748 749 750 751
        LDR     ip, =&FFFFFF00
        STR     ip, [a1]
        MOV     ip, #0
        STR     ip, [a2]
        STR     ip, [a3]
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
752 753

HAL_PlatformInfo
754
        LDRB    ip, [sb, #BoardConfig_BoardFlags]
Robert Sprowson's avatar
Robert Sprowson committed
755 756 757 758
        STR     ip, [a2]
        MOV     ip, #2_11111    ; mask of valid bits
        STR     ip, [a3]
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
759 760

HAL_SuperIOInfo
Robert Sprowson's avatar
Robert Sprowson committed
761 762 763 764
        MOV     ip, #0
        STR     ip, [a1]
        STR     ip, [a2]
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
765 766

HAL_MachineID
Robert Sprowson's avatar
Robert Sprowson committed
767 768 769
        MOV     a1, #0
        MOV     a2, #0
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
770 771

HAL_ExtMachineID
Robert Sprowson's avatar
Robert Sprowson committed
772 773 774
        MOVS    ip, a1
        MOV     a1, #16
        MOVEQ   pc, lr
Ben Avison's avatar
Ben Avison committed
775

Robert Sprowson's avatar
Robert Sprowson committed
776
; OMAP44xx: L4_CONTROL_IDCODE lies in between L4_DIE_ID0 and L4_DIE_ID1
Robert Sprowson's avatar
Robert Sprowson committed
777 778 779 780 781 782 783 784
        LDR     a2, L4_Core_Log
        ADD     a2, a2, #(L4_DIE_ID0 - L4_Core)
        LDR     a3, [a2], #8    ; skip L4_CONTROL_IDCODE
        LDR     a4, [a2], #4
        STMIA   ip!, {a3-a4}
        LDMIA   a2, {a3-a4}
        STMIA   ip, {a3-a4}
        MOV     pc, lr
Ben Avison's avatar
Ben Avison committed
785 786

; Shifts to determine number of bytes/words to allocate in table.
Robert Sprowson's avatar
Robert Sprowson committed
787 788 789
NibbleShift     *       12 ; 1<<12 = 4K ARM page size
ByteShift       *       NibbleShift + 1
WordShift       *       ByteShift + 2
Ben Avison's avatar
Ben Avison committed
790 791

; Bit patterns for different types of memory.
Robert Sprowson's avatar
Robert Sprowson committed
792 793 794 795 796 797
NotPresent      *       &00000000
DRAM_Pattern    *       &11111111
VRAM_Pattern    *       &22222222
ROM_Pattern     *       &33333333
IO_Pattern      *       &44444444
NotAvailable    *       &88888888
Ben Avison's avatar
Ben Avison committed
798

Robert Sprowson's avatar
Robert Sprowson committed
799
        IMPORT  memset
Ben Avison's avatar
Ben Avison committed
800 801

HAL_PhysInfo
802
        TEQ     a1, #PhysInfo_GetTableSize
Robert Sprowson's avatar
Robert Sprowson committed
803
        MOVEQ   a1, #1:SHL:(32-ByteShift)
804
        STREQ   a1, [a2]
Robert Sprowson's avatar
Robert Sprowson committed
805
        MVNEQ   a1, #0          ; Supported
Robert Sprowson's avatar
Robert Sprowson committed
806 807
        MOVEQ   pc, lr

808
        TEQ     a1, #PhysInfo_HardROM
Robert Sprowson's avatar
Robert Sprowson committed
809
        MOVEQ   a1, #0          ; No hard ROM, since the NAND flash isn't yet supported
810 811
        MOVEQ   a2, #0
        STMEQIA a3, {a1-a2}
Robert Sprowson's avatar
Robert Sprowson committed
812
        MVNEQ   a1, #0          ; Supported
813 814 815 816 817 818 819 820
        MOVEQ   pc, lr

        TEQ     a1, #PhysInfo_WriteTable
        MOVNE   a1, #0
        MOVNE   pc, lr

        ; Do the PhysInfo_WriteTable table output
        Push    "v1-v2,lr"
Robert Sprowson's avatar
Robert Sprowson committed
821
        MOV     a1, #&80000000  ; Physical RAM from &80000000 and up?
822 823 824 825
        LDR     lr, =&FFFFE000-1
        STMIA   a3, {a1,lr}
        MOV     v1, a2

Robert Sprowson's avatar
Robert Sprowson committed
826 827 828 829 830 831 832 833 834
        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
835

Robert Sprowson's avatar
Robert Sprowson committed
836
        MVN     a1, #0          ; Supported
Robert Sprowson's avatar
Robert Sprowson committed
837
        Pull    "v1,v2,pc"
Ben Avison's avatar
Ben Avison committed
838 839 840 841

; HAL_PhysInfo uses memset to fill the table, so all regions
; must be byte-aligned (ie double-page-aligned addresses).
HAL_PhysTable
Robert Sprowson's avatar
Robert Sprowson committed
842 843 844 845 846
        DCD     &00000000, NotPresent  :OR: NotAvailable ; GPMC
        DCD     &40000000, IO_Pattern  :OR: NotAvailable ; All I/O registers
        DCD     &80000000, NotPresent  :OR: NotAvailable ; SDRC-SMS/SDRAM
        DCD     &FFFFE000, NotPresent  :OR: NotAvailable ; SDRC-SMS/SDRAM
        DCD     0
Ben Avison's avatar
Ben Avison committed
847 848

HAL_Reset
849 850
        ; Reset or power off?
        CMP     a1, #0
Robert Sprowson's avatar
Robert Sprowson committed
851
        BNE     %FT10
852

853 854 855
        ; If there is a power control unit connected we can do a power off command
        BL      PowerCtrl_SwitchOff

Ben Avison's avatar
Ben Avison committed
856
10
857 858 859
 [ UseSR44x
        BL      SR44x_Exit
 ]
860
        ; Reset, or power off not supported
Robert Sprowson's avatar
Robert Sprowson committed
861 862 863 864 865 866
        ; For a reset, we just poke PRM_RSTCTRL.RST_GLOBAL_WARM_software
        LDR     a3, L4_PowerMan_Log
        ADD     a3, a3, #DEVICE_PRM
        MOV     a2, #1
        STR     a2, [a3, #PRM_RSTCTRL]
        DebugTX "HAL_Reset failed!"
Robert Sprowson's avatar
Robert Sprowson committed
867
        B       .       ; Just in case
Robert Sprowson's avatar
Robert Sprowson committed
868 869 870 871

        LTORG

        EXPORT  vtophys
Ben Avison's avatar
Ben Avison committed
872
vtophys
Robert Sprowson's avatar
Robert Sprowson committed
873
        CallOS  OS_LogToPhys, tailcall
Ben Avison's avatar
Ben Avison committed
874

Robert Sprowson's avatar
Robert Sprowson committed
875
        EXPORT  mapinio
Ben Avison's avatar
Ben Avison committed
876
mapinio
Robert Sprowson's avatar
Robert Sprowson committed
877
        CallOS  OS_MapInIO, tailcall
Ben Avison's avatar
Ben Avison committed
878 879 880

 [ FIQDebug
FIQRoutine
Robert Sprowson's avatar
Robert Sprowson committed
881 882 883 884 885 886 887
        ; 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
Ben Avison's avatar
Ben Avison committed
888
10
Robert Sprowson's avatar
Robert Sprowson committed
889 890 891 892 893 894 895 896
        LDRB    r12, [r8, #UART_LSR]
        TST     r12, #UART_LSR_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
Ben Avison's avatar
Ben Avison committed
897
10
Robert Sprowson's avatar
Robert Sprowson committed
898 899 900 901 902
        LDRB    r12, [r8, #UART_LSR]
        TST     r12, #UART_LSR_THRE
        BEQ     %BT10
        MOV     r12, #13
        STRB    r12, [r8, #UART_THR]
Ben Avison's avatar
Ben Avison committed
903
10
Robert Sprowson's avatar
Robert Sprowson committed
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
        LDRB    r12, [r8, #UART_LSR]
        TST     r12, #UART_LSR_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
Robert Sprowson's avatar
Robert Sprowson committed
919
        DSB     SY
Ben Avison's avatar
Ben Avison committed
920
   [ {FALSE} ; Code to call DebugCallstack on any button press
Robert Sprowson's avatar
Robert Sprowson committed
921 922 923 924 925 926 927 928 929 930 931 932
        ; Switch back to original mode
        MRS     r8, CPSR
        MRS     r9, SPSR
        BIC     r8, r8, #&1F
        AND     r9, r9, #&1F
        ORR     r8, r8, r9
        MSR     CPSR_c, r8
        ; Dump the callstack & other regs
        Push    "sb" ; preserve original sb so it can be dumped
        MOV     sb, #&24
        LDR     sb, [sb]
        B       DebugCallstack
Ben Avison's avatar
Ben Avison committed
933
   ]
Robert Sprowson's avatar
Robert Sprowson committed
934 935
        ; Now return
        SUBS    pc, lr, #4
Ben Avison's avatar
Ben Avison committed
936

Robert Sprowson's avatar
Robert Sprowson committed
937
hextab  DCB "0123456789abcdef"
Ben Avison's avatar
Ben Avison committed
938 939
 ]

Robert Sprowson's avatar
Robert Sprowson committed
940
        END