From fd81a66c8b20b63aea6b12f1854251f4c6444c15 Mon Sep 17 00:00:00 2001
From: Robert Sprowson <rsprowson@gitlab.riscosopen.org>
Date: Sun, 1 Mar 2020 11:23:02 +0000
Subject: [PATCH] Add aligned RMA claim subreason

OS_Module
=> R0=24
   R3=size in bytes
   R4=alignment in bytes (must be a power of 2)
<= R2=base of request
   or error
Tested with a handful of valid and invalid alignments, and with one grossly larger than the free RMA to trigger an RMA extend to occur.

Version 6.35. Tagged as 'Kernel-6_35'
---
 Resources/UK/Messages |  1 +
 VersionASM            |  8 +++---
 VersionNum            | 14 +++++-----
 hdr/ModHand           |  3 ++
 s/ModHand             | 64 +++++++++++++++++++++++++++++++++++++------
 5 files changed, 71 insertions(+), 19 deletions(-)

diff --git a/Resources/UK/Messages b/Resources/UK/Messages
index ed09075..fc6146d 100644
--- a/Resources/UK/Messages
+++ b/Resources/UK/Messages
@@ -79,6 +79,7 @@ BadRMHeaderField:Illegal header field in module
 RMNot32bit:Module '%0' is not 32-bit compatible
 IncarnationNotFound:Incarnation not found
 RMNotFoundInROM:Module is not in ROM
+RMAlignment:Bad alignment request
 NumbTooBig:Number too big
 BadBase:Base not recognised
 BadClaimNum:Bad vector number
diff --git a/VersionASM b/VersionASM
index 63194de..9f99a48 100644
--- a/VersionASM
+++ b/VersionASM
@@ -9,12 +9,12 @@
                         GBLS    Module_ApplicationDate
                         GBLS    Module_HelpVersion
                         GBLS    Module_ComponentName
-Module_MajorVersion     SETS    "6.34"
-Module_Version          SETA    634
+Module_MajorVersion     SETS    "6.35"
+Module_Version          SETA    635
 Module_MinorVersion     SETS    ""
 Module_Date             SETS    "02 Mar 2020"
 Module_ApplicationDate  SETS    "02-Mar-20"
 Module_ComponentName    SETS    "Kernel"
-Module_FullVersion      SETS    "6.34"
-Module_HelpVersion      SETS    "6.34 (02 Mar 2020)"
+Module_FullVersion      SETS    "6.35"
+Module_HelpVersion      SETS    "6.35 (02 Mar 2020)"
                         END
diff --git a/VersionNum b/VersionNum
index 4e79423..7317692 100644
--- a/VersionNum
+++ b/VersionNum
@@ -1,14 +1,14 @@
-/* (6.34)
+/* (6.35)
  *
  * This file is automatically maintained by srccommit, do not edit manually.
  *
  */
-#define Module_MajorVersion_CMHG        6.34
+#define Module_MajorVersion_CMHG        6.35
 #define Module_MinorVersion_CMHG        
 #define Module_Date_CMHG                02 Mar 2020
 
-#define Module_MajorVersion             "6.34"
-#define Module_Version                  634
+#define Module_MajorVersion             "6.35"
+#define Module_Version                  635
 #define Module_MinorVersion             ""
 #define Module_Date                     "02 Mar 2020"
 
@@ -16,6 +16,6 @@
 
 #define Module_ComponentName            "Kernel"
 
-#define Module_FullVersion              "6.34"
-#define Module_HelpVersion              "6.34 (02 Mar 2020)"
-#define Module_LibraryVersionInfo       "6:34"
+#define Module_FullVersion              "6.35"
+#define Module_HelpVersion              "6.35 (02 Mar 2020)"
+#define Module_LibraryVersionInfo       "6:35"
diff --git a/hdr/ModHand b/hdr/ModHand
index 96066ae..43e1795 100644
--- a/hdr/ModHand
+++ b/hdr/ModHand
@@ -63,6 +63,9 @@ ModHandReason_LookupName                   * 18
 ModHandReason_EnumerateROM_Modules         * 19
 ModHandReason_EnumerateROM_ModulesWithInfo * 20
 ModHandReason_FindEndOfROM_ModuleChain     * 21
+ModHandReason_EnumerateROM_ModulesWithPWP  * 22
+ModHandReason_UnplugInsert                 * 23
+ModHandReason_ClaimAligned                 * 24
 
 ; Real module offsets
 
diff --git a/s/ModHand b/s/ModHand
index ced9b2a..e108425 100644
--- a/s/ModHand
+++ b/s/ModHand
@@ -769,7 +769,12 @@ ModuleHandler ROUT
      ModuleDispatchEntry EnumerateROM_Modules
      ModuleDispatchEntry EnumerateROM_ModulesWithInfo
      ModuleDispatchEntry FindEndOfROM_ModuleChain
+     ModuleDispatchEntry EnumerateROM_ModulesWithPWP
+     ModuleDispatchEntry UnplugInsert
+     ModuleDispatchEntry ClaimAligned
 
+Module_EnumerateROM_ModulesWithPWP
+Module_UnplugInsert
 NaffSWI                                     ; Set V and return
         ADR     R0, ErrorBlock_BadModuleReason
       [ International
@@ -940,6 +945,32 @@ Module_Claim  ROUT
          Pull   "R0, R1, lr"
          B       SLVK_TestV
 
+;*************************************************************
+
+Module_ClaimAligned  ROUT
+         Push   "R0, R1, R4, lr"
+         MOVS    R2, R4                                 ; caller's requested alignment
+         BEQ     %FT10
+         SUB     LR, R2, #1
+         TST     R2, LR
+         BNE     %FT10
+         MOV     R4, #0                                 ; any boundary
+         BL      RMAClaim_ChunkAligned
+         B       %FT20
+10
+         ADR     R0, ErrorBlock_RMAlignment             ; powers of two only please
+       [ International
+         BL      TranslateError
+       |
+         SETV
+       ]
+20
+         STRVS   R0, [stack]
+         Pull   "R0, R1, R4, lr"
+         B       SLVK_TestV
+
+         MakeErrorBlock RMAlignment
+
 ;*************************************************************
 ; Garbage collect the RMA. We know there's always one module,
 ; and some RMA space.
@@ -3286,8 +3317,19 @@ Module_CopyError ROUT
        Pull     "R0, R2, R5, R6, PC"
 
 ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-;  Claim chunk from RMA : increase RMA if can,
-;  force size to multiple of 32 -4 to keep alignment OK
+;  Claim chunk from RMA & increase RMA if can
+
+RMAClaim_ChunkAligned ROUT
+         MOV     R0, #HeapReason_GetAligned
+         Push   "R0, R3, lr"
+
+         CMP     R2, #32                     ; alignment is at least 32, and a power of 2
+         MOVCC   R2, #32
+         ADD     R3, R3, #15                 ; round size up to be 32*n + bonus 16 such that this claim
+         BIC     R3, R3, #31                 ; ends at n%32=16 and therefore the next claim starts at n%32=20
+         ADD     R3, R3, #16
+
+         B       IntoRMAHeapOp
 
 RMAClaim_Chunk   ROUT
          MOV     R0, #HeapReason_Get
@@ -3305,19 +3347,26 @@ DoRMAHeapOpWithExtension
          Push   "R0, R3, lr"
 
 IntoRMAHeapOp
+         Push   "R2"                         ; might need alignment again
          MOV     R1, #RMAAddress
          SWI     XOS_Heap
+         ADDVC   SP, SP, #4
          Pull   "R0, R3, PC", VC
 
          LDR     r14, [r0]                   ; look at error number
          TEQ     r14, #ErrorNumber_HeapFail_Alloc
-         STRNE   r0, [stack]
-         Pull   "r0, r3, PC", NE            ; can only retry if ran out of room
+         ADDNE   SP, SP, #4*2
+         Pull   "R3, PC", NE                 ; can only retry if ran out of room
 
-         Push    r3                         ; in case extension
+         Pull   "R2"                         ; recover alignment
+         Push   "R3"                         ; in case extension
          LDR     r1, [stack, #4]
          CMP     r1, #HeapReason_ExtendBlock
-         BNE     notRMAextendblock
+         BEQ     %FT10
+         CMP     r1, #HeapReason_GetAligned
+         ADDEQ   r3, r3, r2                  ; worst case size + alignment
+         B       %FT20
+10
          Push   "r5, r6"
          LDR     r1, [r2, #-4]               ; pick up block size
          ADD     r5, r1, r2                  ; block end +4
@@ -3331,8 +3380,7 @@ IntoRMAHeapOp
 
   ; note that this doesn't cope well with a block at the end preceded by a
   ; free block, but tough.
-
-notRMAextendblock
+20
          MOV     r1, #RMAAddress
          LDR     R0, [R1, #:INDEX: hpdbase]
          LDR     R1, [R1, #:INDEX: hpdend]
-- 
GitLab