Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: allocph.fth | |
4 | \ | |
5 | \ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. | |
6 | \ | |
7 | \ - Do no alter or remove copyright notices | |
8 | \ | |
9 | \ - Redistribution and use of this software in source and binary forms, with | |
10 | \ or without modification, are permitted provided that the following | |
11 | \ conditions are met: | |
12 | \ | |
13 | \ - Redistribution of source code must retain the above copyright notice, | |
14 | \ this list of conditions and the following disclaimer. | |
15 | \ | |
16 | \ - Redistribution in binary form must reproduce the above copyright notice, | |
17 | \ this list of conditions and the following disclaimer in the | |
18 | \ documentation and/or other materials provided with the distribution. | |
19 | \ | |
20 | \ Neither the name of Sun Microsystems, Inc. or the names of contributors | |
21 | \ may be used to endorse or promote products derived from this software | |
22 | \ without specific prior written permission. | |
23 | \ | |
24 | \ This software is provided "AS IS," without a warranty of any kind. | |
25 | \ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, | |
26 | \ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A | |
27 | \ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN | |
28 | \ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR | |
29 | \ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR | |
30 | \ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN | |
31 | \ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR | |
32 | \ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE | |
33 | \ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, | |
34 | \ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF | |
35 | \ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. | |
36 | \ | |
37 | \ You acknowledge that this software is not designed, licensed or | |
38 | \ intended for use in the design, construction, operation or maintenance of | |
39 | \ any nuclear facility. | |
40 | \ | |
41 | \ ========== Copyright Header End ============================================ | |
42 | id: @(#)allocph.fth 2.32 06/02/16 19:19:49 | |
43 | purpose: | |
44 | copyright: Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved | |
45 | copyright: Copyright 1994 FirmWorks All Rights Reserved | |
46 | copyright: Use is subject to license terms. | |
47 | ||
48 | \ Allocator for physical memory. | |
49 | ||
50 | \ Methods: | |
51 | ||
52 | \ claim ( [ phys.lo phys.hi ] alignment size -- base.lo base.hi ) | |
53 | \ If "alignment" is non-zero, allocates at least "size" bytes of | |
54 | \ physical memory aligned on the indicated boundary, returning | |
55 | \ its address "base.lo base.hi". This implementation rounds | |
56 | \ "alignment" up to a multiple of the page size. | |
57 | \ | |
58 | \ If "alignment" is zero, removes the range of physical memory | |
59 | \ denoted by phys.lo, phys.hi, and size from the list of available | |
60 | \ physical memory, returning "base.lo base.hi" equal to "phys.lo phys.hi" | |
61 | \ | |
62 | \ release ( phys.lo phys.hi size -- ) | |
63 | \ Frees the physical memory range denoted by phys.lo, phys.hi, and size. | |
64 | ||
65 | \ clear-mem is a deferred word so that a system-dependent implementation, | |
66 | \ perhaps using bzero hardware, can be installed in the system-dependent | |
67 | \ part of the load sequence. | |
68 | ||
69 | : no-phys-memory ( -- phys.lo phys.hi len ) 0 0 0 ; | |
70 | defer clear-mem ( phys space size -- ) ' 3drop is clear-mem | |
71 | defer initial-memory ( -- phys.lo phys.hi len ) ' no-phys-memory to initial-memory | |
72 | ||
73 | root-device | |
74 | new-device | |
75 | ||
76 | " memory" device-name | |
77 | ||
78 | list: physavail 0 physavail ! | |
79 | ||
80 | headerless | |
81 | : bytes>pages ( bytes -- #pages ) pageshift rshift ; | |
82 | : pages>bytes ( #pages -- bytes ) pageshift lshift ; | |
83 | ||
84 | : pages>phys-adr,len ( page# #pages -- phys.lo phys.hi size ) | |
85 | pages>bytes >r ( page# ) ( r: size ) | |
86 | dup pages>bytes ( page# p.lo ) ( r: size ) | |
87 | swap bits/cell pageshift - rshift ( p.lo p.hi ) ( r: size ) | |
88 | r> ( phys.lo phys.hi size ) | |
89 | ; | |
90 | : phys-adr,len>pages ( phys.lo phys.hi size -- page# #pages ) | |
91 | bytes>pages >r ( phys.lo phys.hi ) ( r: #pages ) | |
92 | bits/cell pageshift - lshift ( phys.lo page#.hi ) ( r: #pages ) | |
93 | swap bytes>pages or r> ( page# #pages ) | |
94 | ; | |
95 | ||
96 | headers | |
97 | : first-phys-avail ( -- phys.lo phys.hi size ) | |
98 | physavail last-node ( node ) | |
99 | node-range pages>phys-adr,len ( phys.lo phys.hi size ) | |
100 | ; | |
101 | ||
102 | ||
103 | \ Variable to indicate when all physical memory is clean. | |
104 | \ Gets turned on after the scrubbing operation is complete. | |
105 | \ Platforms that know that their memory is pre-cleaned can | |
106 | \ cause this to be turned on by defining the compile-time | |
107 | \ switch PreCleanedMemory | |
108 | also forth definitions variable memory-clean? previous definitions | |
109 | ||
110 | [ifdef] PreCleanedMemory | |
111 | memory-clean? on | |
112 | [else] | |
113 | memory-clean? off | |
114 | [then] | |
115 | ||
116 | headerless | |
117 | ||
118 | : accum-size ( total node -- total' false ) >size @ + false ; | |
119 | : total-size ( list -- size-lo size-hi ) | |
120 | 0 swap ['] accum-size find-node 2drop | |
121 | 1 pages>phys-adr,len drop | |
122 | ; | |
123 | ||
124 | : allocate-aligned-physical ( alignment size -- phys-adr space ) | |
125 | \ Minumum granularity of memory chunks is 1 page | |
126 | swap mmu-pagesize round-up bytes>pages | |
127 | swap mmu-pagesize round-up bytes>pages ( aln+ size+ ) | |
128 | tuck physavail ( size alignment size list ) | |
129 | allocate-memrange ( size [ adr ] error? ) | |
130 | abort" Insufficient physical memory" ( size adr ) | |
131 | swap pages>phys-adr,len ( phys.lo phys.hi bytes ) | |
132 | ||
133 | \ Don't re-clear memory after it's been scrubbed, | |
134 | \ or if it's been pre-cleaned. | |
135 | memory-clean? @ 0= if | |
136 | 3dup clear-mem ( phys.lo phys.hi bytes ) | |
137 | then | |
138 | ||
139 | drop | |
140 | ; | |
141 | ||
142 | \ variable allow-reclaim true allow-reclaim ! | |
143 | : claim-physical ( adr space size -- ) | |
144 | ['] 2drop is ?splice | |
145 | swap >r ( adr size ) ( r: space ) | |
146 | >page-boundaries ( adr' size' ) | |
147 | r> swap phys-adr,len>pages ( page# #pages ) | |
148 | ||
149 | \ Look first in the monitor's piece list | |
150 | physavail ['] contained? find-node ( page#,#pages prev next|0 ) | |
151 | is next-node is prev-node ( page#,#pages ) | |
152 | ||
153 | next-node 0= abort" physical address already used" ( page#,#pages ) | |
154 | ||
155 | \ There are 4 cases to consider in removing the requested physical | |
156 | \ address range from the list: | |
157 | \ (1) The requested range exactly matches the list node range | |
158 | \ (2) The requested range is at the beginning of the list node range | |
159 | \ (3) The requested range is at the end of the list node range | |
160 | \ (4) The requested range is in the middle of the list node range | |
161 | ||
162 | \ Remember the range of the node to be deleted | |
163 | next-node node-range ( page#,#pages node-a,l ) | |
164 | ||
165 | \ Remove the node from the list | |
166 | prev-node delete-after memrange free-node ( page#,#pages node-a,l ) | |
167 | ||
168 | \ Give back any left-over portion at the beginning | |
169 | over 4 pick over - dup if ( page#,#pages node-a,l begin-a,l ) | |
170 | physavail free-memrange | |
171 | else | |
172 | 2drop | |
173 | then ( page#,#pages node-a,l ) | |
174 | ||
175 | \ Give back any left-over portion at the end | |
176 | 2swap + -rot + over - ( end-a,l ) | |
177 | ?dup if physavail free-memrange else drop then ( ) | |
178 | ; | |
179 | ||
180 | \ Adjust the alignment and size of a given range of memory to match | |
181 | \ the granularity of what will actually be freed-up. | |
182 | : range>page-boundaries ( phys.lo phys.hi size -- phys.lo' phys.hi size' ) | |
183 | swap >r ( phys.lo bytes ) ( R: phys.hi ) | |
184 | >page-boundaries ( phys.lo' bytes' ) ( R: phys.hi ) | |
185 | r> swap ( phys.lo' phys.hi bytes' ) | |
186 | ; | |
187 | ||
188 | \ Free-up the given range of physical memory. | |
189 | \ It's expected to be all adjusted and aligned... | |
190 | : free-phys-range ( phys.lo' phys.hi size' -- ) | |
191 | phys-adr,len>pages ( page# #pages ) | |
192 | ['] 2drop is ?splice | |
193 | physavail free-memrange ( ) | |
194 | ; | |
195 | ||
196 | \ Initialize the "available" list. Formerly, this was accomplished | |
197 | \ by using the release function, but now that memory-clearing has | |
198 | \ been introduced there, this function needs to be distinct. | |
199 | : init-phys-mem ( phys.lo phys.hi size -- ) | |
200 | range>page-boundaries free-phys-range | |
201 | ; | |
202 | ||
203 | headers | |
204 | : claim ( [ phys.lo phys.hi ] size align -- base.lo base.hi ) | |
205 | ?dup if ( size align ) | |
206 | \ Alignment should be next power of two | |
207 | swap allocate-aligned-physical ( base.lo base.hi ) | |
208 | else ( phys.lo phys.hi size ) | |
209 | 3dup claim-physical drop ( base.lo base.hi ) | |
210 | then ( base.lo base.hi ) | |
211 | ; | |
212 | ||
213 | : release ( phys.lo phys.hi size -- ) | |
214 | range>page-boundaries ( phys.lo' phys.hi size' ) | |
215 | ||
216 | \ We need to clear the memory when we release it in case we disable | |
217 | \ clearing at allocation time in the future. Therefore, before we | |
218 | \ set the 'memory-clean?' variable, we will be clearing the memory | |
219 | \ during both the 'claim' and 'release' client interface calls. | |
220 | 3dup clear-mem ( phys.lo phys.hi bytes ) | |
221 | ||
222 | free-phys-range ( ) | |
223 | ; | |
224 | : close ( -- ) ; | |
225 | : open ( -- ok? ) | |
226 | physavail @ if true exit then | |
227 | initial-memory dup if ( p.lo p.hi size ) | |
228 | init-phys-mem | |
229 | else | |
230 | 3drop | |
231 | then | |
232 | true | |
233 | ; | |
234 | ||
235 | \ Leave it up to the MMU driver | |
236 | -1 constant mode | |
237 | ||
238 | finish-device | |
239 | device-end | |
240 | ||
241 | stand-init: Opening the physical memory package | |
242 | " /memory" open-dev memory-node ! | |
243 | ; |