From 0125023e4d3a6aa37b39d42c4b5d2c8bf1ec4ce4 Mon Sep 17 00:00:00 2001
From: Ben Avison <bavison@gitlab.riscosopen.org>
Date: Thu, 10 May 2012 03:10:02 +0000
Subject: [PATCH] Support for Raspberry Pi / BCM2835

Detail:
  Falls into two main areas: graphics support and ARM11 core support.
  A work in progress - in many cases the code changes need to be replaced
  with an alternative mechanism which will permit the kernel to still function
  on other platforms. Adrian marked these with "!!!" comments - I have added
  ! directives as well so that they don't get forgotten about.
Admin:
  Changes received from Adrian Lees. This revision represents the code largely
  as delivered, and is placed on its own branch (forked off from the version
  from which he worked). It is intended for reference. It doesn't build against
  current headers - this is likely to require a merge with the other changes
  to the kernel since that time.

Version 5.35, 4.79.2.98.2.52.2.1. Tagged as 'Kernel-5_35-4_79_2_98_2_52_2_1'
---
 Docs/RPiNotes    | 36 +++++++++++++++++++++++++++++++
 VersionASM       | 10 ++++-----
 VersionNum       | 14 ++++++------
 hdr/Options      |  4 ++--
 s/ARMops         | 16 ++++++++++++++
 s/HAL            |  6 ++++++
 s/Kernel         |  4 ++++
 s/NewIRQs        | 11 ++++++++++
 s/NewReset       |  7 +++++-
 s/PMF/key        | 17 +++++++++++++++
 s/vdu/vducursoft | 22 ++++++++++++++++++-
 s/vdu/vdudriver  | 44 ++++++++++++++++++++++++++++++++++---
 s/vdu/vdupointer | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
 s/vdu/vduswis    |  6 ++++++
 14 files changed, 234 insertions(+), 19 deletions(-)
 create mode 100644 Docs/RPiNotes

diff --git a/Docs/RPiNotes b/Docs/RPiNotes
new file mode 100644
index 00000000..1d7b7420
--- /dev/null
+++ b/Docs/RPiNotes
@@ -0,0 +1,36 @@
+Things remaining to be tidied:
+
+ - The starting in a non-numbered video mode; in s.vdu. Code deliberately
+   bodged (and flagged with !!!) to force starting in 1920x1080x32bpp.
+   I guess any HAL_VideoFeatures call that returns inability to handle a
+   <= 8bpp mode might be a way to activate it? Then I guess the HAL needs to
+   suggest a suitable default resolution.
+
+   Alternatively, with later start.elf images perhaps we will be able to run
+   in lower resolutions when booting.
+
+ - There's code surrounding ARM_Analyse and particularly EvaluateCache
+   where it didn't determine the correct cachetype and cachelinelen
+   for this ARM. I've not tidied this properly yet; it should be obvious
+   what's required.
+
+      ARM ID reg &410FB767
+      MRC 15,1,R0,C0,C0,1
+        cache info = &1D152152
+        ARMv6 format...ok
+
+   I'm not sure who's best-placed to sort this cleanly; my knowledge of
+   ARMs from that era is not extensive...I'd have to study the ARM ARM
+   to ascertain the 'correct' way to determine cache properties.
+
+ - The code in vdudriver that reads the framestore properties requires
+   a GraphicsV claimant if an external framestore is required. I can
+   knock up a simple asm module to do this, or we can switch to an
+   internal framestore if that can be made to work. I like the latter
+   idea because it gives us 'hardware scrolling' and possibly the
+   screen cacheing (SA), both of which would benefit us with the
+   currently unaccelerated display.
+
+ - the centisecond timer interrupt currently needs to
+   be a 'pretend Vsync' handler too at the moment. I'm unsure how you'd
+   like to go about having this workaround used for R-Pi only
diff --git a/VersionASM b/VersionASM
index 3db775c4..2ca768e7 100644
--- a/VersionASM
+++ b/VersionASM
@@ -13,11 +13,11 @@
                         GBLS    Module_ComponentPath
 Module_MajorVersion     SETS    "5.35"
 Module_Version          SETA    535
-Module_MinorVersion     SETS    "4.79.2.98.2.52"
-Module_Date             SETS    "15 Sep 2011"
-Module_ApplicationDate  SETS    "15-Sep-11"
+Module_MinorVersion     SETS    "4.79.2.98.2.52.2.1"
+Module_Date             SETS    "10 May 2012"
+Module_ApplicationDate  SETS    "10-May-12"
 Module_ComponentName    SETS    "Kernel"
 Module_ComponentPath    SETS    "castle/RiscOS/Sources/Kernel"
-Module_FullVersion      SETS    "5.35 (4.79.2.98.2.52)"
-Module_HelpVersion      SETS    "5.35 (15 Sep 2011) 4.79.2.98.2.52"
+Module_FullVersion      SETS    "5.35 (4.79.2.98.2.52.2.1)"
+Module_HelpVersion      SETS    "5.35 (10 May 2012) 4.79.2.98.2.52.2.1"
                         END
diff --git a/VersionNum b/VersionNum
index ae7167e2..5da73938 100644
--- a/VersionNum
+++ b/VersionNum
@@ -5,19 +5,19 @@
  *
  */
 #define Module_MajorVersion_CMHG        5.35
-#define Module_MinorVersion_CMHG        4.79.2.98.2.52
-#define Module_Date_CMHG                15 Sep 2011
+#define Module_MinorVersion_CMHG        4.79.2.98.2.52.2.1
+#define Module_Date_CMHG                10 May 2012
 
 #define Module_MajorVersion             "5.35"
 #define Module_Version                  535
-#define Module_MinorVersion             "4.79.2.98.2.52"
-#define Module_Date                     "15 Sep 2011"
+#define Module_MinorVersion             "4.79.2.98.2.52.2.1"
+#define Module_Date                     "10 May 2012"
 
-#define Module_ApplicationDate          "15-Sep-11"
+#define Module_ApplicationDate          "10-May-12"
 
 #define Module_ComponentName            "Kernel"
 #define Module_ComponentPath            "castle/RiscOS/Sources/Kernel"
 
-#define Module_FullVersion              "5.35 (4.79.2.98.2.52)"
-#define Module_HelpVersion              "5.35 (15 Sep 2011) 4.79.2.98.2.52"
+#define Module_FullVersion              "5.35 (4.79.2.98.2.52.2.1)"
+#define Module_HelpVersion              "5.35 (10 May 2012) 4.79.2.98.2.52.2.1"
 #define Module_LibraryVersionInfo       "5:35"
diff --git a/hdr/Options b/hdr/Options
index 8f4fe276..12eadb14 100644
--- a/hdr/Options
+++ b/hdr/Options
@@ -302,13 +302,13 @@ RMTidyDoesNowt  SETL    {TRUE}                  ; should really be "machine has
 RogerEXEY       SETL    {FALSE}                 ; Marketing don't like it!
 
                 GBLL    DebugROMInit
-DebugROMInit    SETL    {TRUE}
+DebugROMInit    SETL    {FALSE}
 
                 GBLL    DebugROMPostInit ; Displays when the PostInit service call is sent to each ROM module (currently works on vanilla service call handling only)
 DebugROMPostInit SETL    (:LNOT: ChocolateService) :LAND: {FALSE}
 
                 GBLL    DebugROMErrors
-DebugROMErrors  SETL    {TRUE}
+DebugROMErrors  SETL    {FALSE}
 
                 GBLL    DebugTerminal           ; default WRCH and RDCH through HAL
 DebugTerminal   SETL    {FALSE}
diff --git a/s/ARMops b/s/ARMops
index 0665d386..b49c97ed 100644
--- a/s/ARMops
+++ b/s/ARMops
@@ -221,6 +221,12 @@ FindARMloop
         ; others ...
 
 WeirdARMPanic
+        ! 0, "FIXME: temporary code"
+;!!!
+  MOV ip,#&C0
+  STR a1,[ip,#&40]
+  STMIA ip,{a1-ip}
+
         B       WeirdARMPanic                   ; stiff :)
 
 Analyse_ARMv3
@@ -566,6 +572,10 @@ Analyse_WB_CR7_Lx
         CMP     a3, #14 ; Stop after level 7 (even though an 8th level might exist on some CPUs?)
         ADD     a2, a2, #4
         BLT     %BT10
+        ! 0, "FIXME: temporary code"
+;!!!
+  MOV a4,#32
+  MOV v2,#32
         STRB    a4, [v6, #ICache_LineLen] ; Store log2(line size)-2
         STRB    v2, [v6, #DCache_LineLen] ; log2(line size)-2
 
@@ -839,6 +849,12 @@ ARM_Analyse_Fancy
         MOV     a1, v2, LSR #CT_Dsize_pos
         ADD     a2, v6, #DCache_Info
         BL      EvaluateCache
+
+;EvaluateCache isn't doing our job for us....assuming these flags are true! ;)
+        ! 0, "FIXME: temporary code"
+;!!!
+   ORR   v5, v5, #CPUFlag_SynchroniseCodeAreas+CPUFlag_SplitCache
+
         B       %FT27
 
 25
diff --git a/s/HAL b/s/HAL
index 2a882db8..e8a6ef02 100644
--- a/s/HAL
+++ b/s/HAL
@@ -832,6 +832,12 @@ MMUon_nol1ptoverlap
         MOV     v3, #0                                  ; "MMU is on" signal
 
         BL      ARM_Analyse
+        ! 0, "FIXME: temporary code"
+;!!! STILL DON'T KNOW WHY THE BODGE IN ARM_ANALYSE ITSELF DOESN'T WORK!
+  MOV a1,#0
+  MOV a2,#32
+  STRB a2,[a1,#DCache_LineLen]
+  STRB a2,[a1,#ICache_LineLen]
 
         ChangedProcVecs a1
 
diff --git a/s/Kernel b/s/Kernel
index 6dcf59c0..d393d91f 100644
--- a/s/Kernel
+++ b/s/Kernel
@@ -42,9 +42,13 @@
         MACRO
         DebugTX $str
     [ DebugHALTX
+        ! 0, "FIXME: temporary code"
+;!!!
+  STR lr,[sp,#-4]!
         BL      DebugHALPrint
         =       "$str", 0
         ALIGN
+  LDR lr,[sp],#4
     ]
         MEND
   |
diff --git a/s/NewIRQs b/s/NewIRQs
index dc22cfff..13e9b728 100644
--- a/s/NewIRQs
+++ b/s/NewIRQs
@@ -1455,6 +1455,17 @@ TickOne ROUT
         STRB    R0, [R3, #IOCIRQCLRA]   ; clear timer 0 interrupt
  ]
 
+
+        ! 0, "FIXME: temporary code"
+;!!! HAPPY HACK
+        STMFD   sp!,{r0-r12}
+        ADR     r0,ret_from_vs
+        Push    r0
+        B       VsyncIRQ_ExtEntry
+ret_from_vs
+        LDMFD   sp!,{r0-r12}
+;!!! HAPPY HACK
+
         LDR     R1, =ZeroPage
         LDR     R0, [R1, #MetroGnome]
         ADD     R0, R0, #1
diff --git a/s/NewReset b/s/NewReset
index f6cc34f1..fbc934c8 100644
--- a/s/NewReset
+++ b/s/NewReset
@@ -1562,6 +1562,7 @@ WallopDuffOnes
         MOV     r1, #AP_UndStackSoftCam
         BL      AddCamEntries
  ]
+        DebugTX "InitDynamicAreas"
 
 ; let's boogie with the CMOS for a bit
 ; read info and move as much memory as we can
@@ -1709,6 +1710,7 @@ WallopDuffOnes
         STR     R1, [R0, #AplWorkSize]
         STR     R1, [R0, #MemLimit]
 
+        DebugTX "InitVectors"
         BL      InitVectors               ; ready for OsByte to read mode
 
         LDR     R1, =ZeroPage+ModuleSWI_HashTab
@@ -1773,6 +1775,7 @@ ResetPart1Done                          ; R0 is reset type
  ]
         Push    "R0, R1"                ; save until after MOSInit
 
+        DebugTX "InitIRQ1"
         BL      InitialiseIRQ1Vtable
 
         LDR     R3, =ZeroPage
@@ -1823,6 +1826,7 @@ ResetPart1Done                          ; R0 is reset type
         MOV     R4, #0
         STMIA   R2!, {R3,R4}
         STMIA   R2!, {R3,R4}
+        DebugTX "IMB_Full"
 
    ;we need to do an IMB type thing for modifying code in vector area,
    ;and for copying irq handler code
@@ -1911,7 +1915,8 @@ ResetPart1Done                          ; R0 is reset type
         STR     R0, [R1, #DeviceTable]
       ]
         CallHAL HAL_InitDevices         ; get HAL to register any devices it has
-        BL      LookForHALRTC ; Check if an RTC was just added. This is currently the only place where HAL RTCs are checked for; if we wanted to check anywhere else (e.g. after ROM module initialisation) then we'd have to listen for Service_Hardware so we can cope with device removal
+        ! 0, "FIXME: we're going to need this back at some point"
+;        BL      LookForHALRTC ; Check if an RTC was just added. This is currently the only place where HAL RTCs are checked for; if we wanted to check anywhere else (e.g. after ROM module initialisation) then we'd have to listen for Service_Hardware so we can cope with device removal
  |
         BL      L1L2PTenhancements      ; little tricks on cacheability etc for performance
  ]
diff --git a/s/PMF/key b/s/PMF/key
index 3ddbd79b..9cadedc5 100644
--- a/s/PMF/key
+++ b/s/PMF/key
@@ -1090,6 +1090,23 @@ RedirectBadExit                         ; got an error from BGET
 ; in:   R1 = input buffer id (0 => keyboard, 1 => RS423)
 
 RDCHG   ROUT
+
+  [ {FALSE}
+  STMFD sp!,{R1-R12,R14}
+  MOV a1, #0
+  AddressHAL a1
+  SUB sp,sp,#4
+  MOV a2,sp
+  CallHAL HAL_UARTReceiveByte
+  LDR a2,[sp],#4
+  TST a2,#1
+  BNE %FT00
+  SEC
+  LDMFD sp!,{R1-R12,PC}
+00
+  CLC
+  LDMFD sp!,{R1-R12,PC}
+  ]
         Push    R14
 
 ; insert check here for ECONET interception of RDCH
diff --git a/s/vdu/vducursoft b/s/vdu/vducursoft
index e25dc363..0625d50d 100644
--- a/s/vdu/vducursoft
+++ b/s/vdu/vducursoft
@@ -100,6 +100,12 @@ PreWrchCursor
                                                 ; state in top bit
         STR     R0, [WsPtr, #CursorStack]
 
+        MOV     R2,R14
+        LDR     R14, [WsPtr, #HALVideoFeatures]
+        TST     R14, #2
+        BLEQ    RemovePointer
+        MOV     R14,R2
+
  [ No26bitCode
         MSR     CPSR_c, R3                      ; restore old I bit
         MOVCS   PC, R14                         ; already off, so exit
@@ -271,7 +277,21 @@ Cursor32loop
 ; out:  R6 = new CursorFlags, R5,R7 preserved, all others undefined
 ;
 
-PostWrchCursor
+PostWrchCursor ROUT
+
+        MOV     R6,R14
+        LDR     R14,[WsPtr, #HALVideoFeatures]
+        TST     R14,#2
+        BNE     %FT10
+
+        MRS     R4,CPSR
+        ORR     R3,R4,#I32_bit
+        MSR CPSR_c,R3
+        BL      RestorePointer
+        MSR CPSR_c,R4
+10
+        MOV     R14,R6
+
         LDR     R6, [WsPtr, #CursorFlags]
         LDR     R0, [WsPtr, #CursorStack]
         MOVS    R0, R0, LSL #1
diff --git a/s/vdu/vdudriver b/s/vdu/vdudriver
index 109dee58..df77b43d 100644
--- a/s/vdu/vdudriver
+++ b/s/vdu/vdudriver
@@ -362,7 +362,12 @@ InitialiseMode Entry
         MOV     r0, #1                  ; no need to check for soft reset,
         SWI     XOS_ReadSysInfo         ; always use configured value
  ]
-        MOV     r1, r0
+        ! 0, "FIXME: temporary code"
+;!!!
+   ADR r1,mode_defn
+
+;        MOV     r1, r0
+
         MOV     r0, #ScreenModeReason_SelectMode
         SWI     XOS_ScreenMode
         EXIT    VC
@@ -374,6 +379,14 @@ InitialiseMode Entry
         SWIVC   XOS_WriteI+0            ; and if we can't get mode 0, we're really fooked!!!
         EXIT
 
+        ! 0, "FIXME: temporary code"
+mode_defn DCD 1
+        DCD 1920
+        DCD 1080
+        DCD 5
+        DCD -1
+        DCD -1
+
 ;
 ;------------------------------------------------------------------------------
 ;
@@ -729,6 +742,10 @@ VduBadExit                              ; jumped to if an error in VDU code
 ModeChangeSub ROUT
         Push    lr
 
+        ! 0, "FIXME: temporary code"
+; !!!
+  ADRL R2,mode_defn
+
         ;If its a common mode number (0..49) consider a possible mode number
         ;substitution, if hardware does not support given bits per pixel.
         ;We are vaguely assuming h/w supports at least 8 bpp, otherwise we may
@@ -794,6 +811,7 @@ mchsub_3
 
         TEQ     R0, R1                  ; if substitute mode
         MOVNE   R2, #0                  ; then don't use shadow
+  DebugTX "FindOKMode reached"
 
         CMP     r1, #&100
         BICCC   r10, r1, #&80
@@ -801,6 +819,7 @@ mchsub_3
         MOV     R11, R10
         BL      PushModeInfo
         BVS     %FT07                   ; [probably duff mode selector]
+  DebugTX "PushModeInfo done"
 
         LDR     R11, [R13, #wkScreenSize] ; get screen size for this mode
         LDR     R9, [WsPtr, #TotalScreenSize] ; maximum allowed amount
@@ -828,7 +847,9 @@ mchsub_3
       [ International
         BL      TranslateError
       ]
+  DebugTX "Can't grow framestore"
 07
+  DebugTX "Mode fail"
         SETV                            ; indicate error
         Pull    PC
 
@@ -911,10 +932,20 @@ TV_Mode_string
 
  [ UseGraphicsV
         Push    "r0-r4"
+        ! 0, "FIXME: temporary code"
+;!!!
+  [ {FALSE}
         MOV     r4, #GraphicsV_FramestoreAddress
         BL      CallGraphicsV
         TEQ     r4, #0
         BNE     %FT581
+  |
+  ;hardcoded values for R-Pi alpha. external framestore requires a GraphicsV client,
+  ;  but still debating the merits of external vs internal
+  MOV r0,#&2000000
+  MOV r1,#&0800000
+  MOV r4,#0
+  ]
         MOV     r1, r1, LSR #20                 ; round size down to 1MB
         MOV     r2, r1, LSL #20
         ADD     r0, r0, #1:SHL:20               ; round addr up to 1MB
@@ -1199,8 +1230,13 @@ PushModeInfo ROUT
         BL      ReadMonitorType
 PushModeInfoCommon
         MOV     r2, r10                 ; r2 = original mode
-        BL      OfferModeExtension
-        BEQ     %FT30                   ; [service claimed]
+        ! 0, "FIXME: temporary code"
+;!!!
+;        BL      OfferModeExtension
+;        BEQ     %FT30                   ; [service claimed]
+  MOV r3,#0
+  MOV r4,#0
+  B %FT30
 
         CMP     r2, #&100               ; service not claimed - check if mode selector
         MOVCC   r10, r11                ; unrecognised mode number, so use substitute
@@ -1399,9 +1435,11 @@ GenerateModeSelectorVars Entry "r0,r1,r3-r8,r10-r12"
         TST     r2, #1                          ; is it a new format sprite mode word?
         BNE     %FT50                           ; [yes, so skip]
         MOV     r0, r2
+;  DebugTX "ValModeSel"
         BL      ValidateModeSelector
         BVS     %FT95                           ; invalid - return error
         LDMIB   r2, {r4-r6}                     ; r4 = xres; r5 = yres; r6 = pixdepth
+;  DebugTX "Passed"
 
         STR     r6, [r9, #wkLog2BPC]            ; log2bpc = log2bpp = pixdepth
         STR     r6, [r9, #wkLog2BPP]
diff --git a/s/vdu/vdupointer b/s/vdu/vdupointer
index cfd76902..6a49b5f8 100644
--- a/s/vdu/vdupointer
+++ b/s/vdu/vdupointer
@@ -604,4 +604,60 @@ FlushMouse ROUT
 
         LTORG
 
+; *****************************************************************************
+;
+;       RemovePointer - Remove soft mouse pointer from screen
+;
+
+RemovePointer ROUT
+        STMFD   R13!,{R0-R6,R14}
+        LDRB    R3, [WsPtr, #PointerShapeNumber]
+        TST     R3, #&7F
+        MOVNE   R0, #0
+        MOVNE   R4, #GraphicsV_UpdatePointer
+        BLNE    CallGraphicsV
+        LDMFD   R13!,{R0-R6,PC}
+
+; *****************************************************************************
+;
+;       RestorePointer - Restore soft mouse pointer to previous state
+;
+
+RestorePointer ROUT
+        STMFD   R13!,{R0-R6,R14}
+        LDRB    R6, [WsPtr, #PointerShapeNumber]
+        ANDS    R6, R6, #&7F
+        BEQ     %FT10
+
+        ADD     R3, WsPtr, #PointerShapes-4
+        LDR     R3, [R3, R6, LSL #2]         ; R3 -> current shape block (R6 = shape 1..4)
+
+        MOV     R0, #1                       ; R0 = flags, set pointer on (bit 0 = 1)
+
+        LDR     R1, [WsPtr, #PointerShapeLA] ; last shape buffer given to HAL
+        LDR     R4, [R3, #PointerBuffLA]     ; shape buffer we're about to give
+        TEQ     R1, R4                       ; same as last time?
+        STRNE   R4, [WsPtr, #PointerShapeLA] ; update
+        ORRNE   R0, R0, #2                   ; flag new shape (bit 1 = 1)
+
+        LDR     R1, [WsPtr, #PointerX]
+        LDR     R4, [WsPtr, #PointerXEigFactor]
+        MOV     R1, R1, ASR R4                     ; R1 = pointer x, pixels
+        LDRB    R4, [R3, #PointerActiveX]
+        SUB     R1, R1, R4                         ; R1 = pointer x, adjusted for active point
+
+        LDR     R2, [WsPtr, #PointerY]
+        LDR     R4, [WsPtr, #DisplayYEigFactor]
+        LDR     R5, [WsPtr, #DisplayYWindLimit]    ; R5 = display height -1
+        SUB     R2, R5, R2, ASR R4                 ; R2 = pointer y, pixels, inverted
+        LDRB    R4, [R3, #PointerActiveY]
+        SUB     R2, R2, R4                         ; R2 = pointer y, adjusted for active point
+
+        ; and it's up to the HAL to handle clipping according to h/w capabilities
+
+        MOV     R4, #GraphicsV_UpdatePointer
+        BL      CallGraphicsV
+10
+        LDMFD   R13!,{R0-R6,PC}
+
         END
diff --git a/s/vdu/vduswis b/s/vdu/vduswis
index 37575ad7..8917f410 100644
--- a/s/vdu/vduswis
+++ b/s/vdu/vduswis
@@ -698,6 +698,7 @@ NSM_yshftfactor
 ;
 
 SWICheckModeValid ROUT
+  DebugTX "CheckModeValid"
         VDWS    WsPtr
         Push    "r1,r9,lr"
         BL      FindOKMode              ; out: r1 = substitute mode
@@ -772,6 +773,11 @@ SWICheckModeValid ROUT
 ;
 
 FindOKMode ROUT
+        ! 0, "FIXME: temporary code"
+;!!!
+  ADDS R1,R0,#0
+  MOV pc,lr
+
         Push    "r0,r2-r4,r10,r11,lr"
         BL      ReadMonitorType
         CMP     r0, #&100               ; if it's a mode number
-- 
GitLab