1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
; 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.growshrink
; heap block can move when resized, so make sure pointers fixed-up
; change number of pages in slot (grow/shrink)
; entry:
; R0 = 2 (reason code 2)
; R1 = new number of pages required
; R2 = handle
;
; exit:
; R1 = new number of pages actually achieved
; R3 = old number of pages
growshrink
Push "R0,R2,R4,R5,LR"
; Debug AMB,"growshrink ",r0,r1,r2
MOV R5,#AbsMaxAppSize
SUB R5,R5,#ApplicationStart
MOV R5,R5,LSR #Log2PageSize ;R5 = absolute max app pages
CMP R1,R5
MOVGT R1,R5
[ ValidateAMBHandles
;validate handle
LDR R0,AMBNhandles
CMP R2,R0
BGT badsghandle
CMP R2,#1
BLT badsghandle
]
LDR R0,AMBNodeHandles ; R0 -> handles array
LDR R2,[R0,R2,LSL #2] ; R2 -> node
[ ValidateAMBHandles
;check we have a proper id for node
LDR R3,=AMBMagicNodeID
LDR LR,[R2,#AMBNode_id]
CMP LR,R3
BNE badsghandle
]
LDR R3,[R2,#AMBNode_Npages]
CMP R1,R3
Pull "R0,R2,R4,R5,LR",EQ ; done if no change
BEQ SLVK
MOV R5,R3 ; R5 := old no. pages
BLT gs_shrink
;grow
BL grwshr_node ; grow node itself first
BVS gs_done ; failed node grow is not error - means grow by 0
BL growpages ; grow the slot (MMU mapping)
STRVS R0,[SP]
Pull "R0,R2,R4,R5,LR",VS
BVS SLVK_SetV
B gs_done
gs_shrink
BL shrinkpages ; shrink the slot (MMU mapping) first
BLVC grwshr_node ; shrink node itself
STRVS R0,[SP]
Pull "R0,R2,R4,R5,LR",VS
BVS SLVK_SetV
gs_done
MOV R3,R5 ;old no. of pages
CMP R2,#0 ;also clears V
MOVEQ R1,#0
LDRNE R1,[R2,#AMBNode_Npages]
CMP R2,#0 ;0 for freed node
STREQ R2,[SP,#4] ;poke freed handle to saved R2
Pull "R0,R2,R4,R5,LR"
B SLVK
;handle grow/shrink of node itself
;entry:
; R1 = new no. of pages
; R2 -> node
; R5 = old no. of pages
;exit:
; R2 -> node (may be moved)
grwshr_node
Push "R0,R3,R4,LR"
CMP R1,#0
BEQ grwshrn_free ;shrunk to nothing
MOV R3,#(AMBNode_pages - AMBNode_id) ;new size excluding page list
ADD R3,R3,R1,LSL #2 ;new size
MOV R4,R2 ;so we can check for moved block
BL AMB_BlockResize
MOVVS R2,R4 ;in case block ptr not preserved on error
BVS grwshrn_done
;fix-up links if block has moved
CMP R4,R2
BEQ grwshrn_done
LDR R3,[R2,#AMBNode_prev]
STR R2,[R3,#AMBNode_next] ;fix prev_next
LDR R3,[R2,#AMBNode_next]
STR R2,[R3,#AMBNode_prev] ;fix next_prev
LDR R3,AMBMappedInNode
CMP R3,R4
STREQ R2,AMBMappedInNode ;fix MappedInNode if it matches
LDR R3,[R2,#AMBNode_handle]
LDR R4,AMBNodeHandles
STR R2,[R4,R3,LSL #2] ;fix node address in handle array
grwshrn_done
STRVS R0,[SP]
Pull "R0,R3,R4,PC"
grwshrn_free
LDR R0,AMBNodeHandles
LDR R4,[R2,#AMBNode_handle]
;put handle on free list
LDR R3,[R0] ;current first free handle
STR R3,[R0,R4,LSL #2] ;attach
STR R4,[R0] ;new first free handle
;remove node from list
LDR R0,[R2,#AMBNode_prev] ; R0 -> prev_node
LDR R3,[R2,#AMBNode_next] ; R3 -> next_node
STR R3,[R0,#AMBNode_next] ; prev_next := next_node
STR R0,[R3,#AMBNode_prev] ; next_prev := prev_node
LDR R0,AMBNtasks
SUB R0,R0,#1
STR R0,AMBNtasks
;if this is the mapped-in node, then nothing is now mapped in
LDR R0,AMBMappedInNode
CMP R0,R2
MOVEQ R0,#0
STREQ R0,AMBMappedInNode
BL AMB_BlockFree
MOVVC R2,#0
B grwshrn_done
LTORG
[ ValidateAMBHandles
badsghandle
Pull "R0,R2,R4,R5,LR"
B badhandle
]
END