; Copyright 1996 Acorn Computers 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.
;
; > s.growp


;grow slot by taking pages from FreePool; add them to AppSpace


; entry:
;     R1 =  new number of pages for slot (more than current value)
;     R2 -> AMB node
;
; exit: -

growpages ROUT
        Entry   "R0-R7,R10-R11"

        MOV     R6,R1                      ;save entry R1
        LDR     R5,[R2,#AMBNode_DANode+DANode_PMPSize]
        CMP     R5,R6
        EXIT    EQ                         ;done if no. of pages unchanged

      [ AMB_Debug
        DebugReg r1, "growpages to "
        DebugReg r5, "from "
      ]

        ; Grow PMP to right size
        ADD     R10,R2,#AMBNode_DANode
        Push    "R1-R2,R10,R12"
        LDR     R1,[R2,#AMBNode_DANode+DANode_PMPMaxSize]
        SUB     R2,R6,R1
        BL      DynArea_PMP_Resize_WithNode
        Pull    "R1-R2,R10,R12"
        ; Check new size is correct
        LDR     R1,[R2,#AMBNode_DANode+DANode_PMPMaxSize]
      [ AMB_Debug
        DebugReg r1, "Resize result "
      ]
        CMP     R1,R6
        BNE     %FT90                      ;give up if PMP resize failed

        ; Now add pages to the PMP for the new region
        Push    "R5"
        SUB     SP,SP,#64*12               ;Temp page list
        MOV     R7,#-2                     ;-2 = kernel picks physical page
05
        MOV     R3,#0
        LDR     LR,[R10,#DANode_Flags]
        MOV     R2,SP
10
        STMIA   R2!,{R5,R7,LR}             ;Fill page list with increasing PMP page indices, to ensure no gaps in PMP if we hit an error
        ADD     R5,R5,#1
        ADD     R3,R3,#1
        CMP     R5,R6
        CMPNE   R3,#64
        BNE     %BT10
        MOV     R2,SP
        Push    "R10,R12"
        BL      DynArea_PMP_PhysOp_WithNode
        Pull    "R10,R12"
        CMP     R3,#0
        BNE     %FT20 ; Stop if failed to allocate something
        CMP     R5,R6
        BNE     %BT05
20
        ADD     SP,SP,#64*12
        Pull    "R5"

        ; Map in the new pages (if any)
        Push    "R1,R5"
        MOV     R1,R5
        LDR     R5,[R10,#DANode_PMPSize]
        SUBS    R5,R5,R1
        MOV     R7,#0
        BLNE    AMB_SetMemMapEntries_MapIn_Lazy
        Pull    "R1,R5"

        ; Update AplWorkSize, MemLimit
        LDR     R5,[R10,#DANode_PMPSize]
      [ AMB_Debug
        DebugReg r5, "PhysOp result "
      ]
        MOV     R2,#ApplicationStart
        ADD     R5,R2,R5,LSL #Log2PageSize
        LDR     R2,=ZeroPage
        STR     R5,[R2,#AplWorkSize]
        STR     R5,[R2,#MemLimit]

90
        CLRV
        EXIT

    END