; 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.shrinkp


;shrink slot by taking pages (from AppSpace); add them to FreePool


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

shrinkpages     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

        ADD     R10,R2,#AMBNode_DANode

        LDR     LR,AMBMappedInNode
        CMP     LR,R2
        BNE     %FT10

        ; Map out pages
        Push    "R5,R12"
        SUB     R5,R5,R1
        MOV     R7,#0
        BL      AMB_SetMemMapEntries_MapOut_Lazy
        Pull    "R5,R12"

10
        ; Release pages from PMP
        Push    "R2"
        SUB     SP,SP,#64*12            ;Temp page list
        MOV     R7,#-1                  ; Release page from PMP
15
        MOV     R3,#0
        MOV     LR,#0
        MOV     R2,SP
20
        SUB     R5,R5,#1
        STMIA   R2!,{R5,R7,LR}          ;Fill page list with decreasing PMP page indices, so last page added by growpages is first to be removed by shrinkpages (keeps free pool in optimal order for DMA)
        ADD     R3,R3,#1
        CMP     R5,R1
        CMPNE   R3,#64
        BNE     %BT20
        Push    "R10,R12"
        ADD     R2,SP,#8
        BL      DynArea_PMP_PhysOp_WithNode
        Pull    "R10,R12"
        ; Release shouldn't fail, so ignore any errors
        CMP     R5,R1
        BNE     %BT15
        ADD     SP,SP,#64*12
        Pull    "R2"

        ; Shrink max size of PMP
        Push    "R2,R12"
        LDR     R1,[R10,#DANode_PMPMaxSize]
        LDR     R2,[R10,#DANode_PMPSize]
        SUB     R2,R2,R1
        BL      DynArea_PMP_Resize_WithNode
        Pull    "R2,R12"

        ; Update AplWorkSize, MemLimit if this is the current AMBNode
        LDR     R5,AMBMappedInNode
        CMP     R5,R2
        BNE     %FT90
        LDR     R5,[R2,#AMBNode_DANode+DANode_PMPSize]
        MOV     R2,#ApplicationStart
        ADD     R5,R2,R5,LSL #Log2PageSize
        LDR     R2,=ZeroPage
        STR     R5,[R2,#AplWorkSize]
        STR     R5,[R2,#MemLimit]

90
        CLRV
        EXIT


    END