Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / os / bootprom / allocph.fth
CommitLineData
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 ============================================
42id: @(#)allocph.fth 2.32 06/02/16 19:19:49
43purpose:
44copyright: Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved
45copyright: Copyright 1994 FirmWorks All Rights Reserved
46copyright: 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 ;
70defer clear-mem ( phys space size -- ) ' 3drop is clear-mem
71defer initial-memory ( -- phys.lo phys.hi len ) ' no-phys-memory to initial-memory
72
73root-device
74new-device
75
76" memory" device-name
77
78list: physavail 0 physavail !
79
80headerless
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
96headers
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
108also forth definitions variable memory-clean? previous definitions
109
110[ifdef] PreCleanedMemory
111 memory-clean? on
112[else]
113 memory-clean? off
114[then]
115
116headerless
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
203headers
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
238finish-device
239device-end
240
241stand-init: Opening the physical memory package
242 " /memory" open-dev memory-node !
243;