Commit | Line | Data |
---|---|---|
920dae64 AT |
1 | \ ========== Copyright Header Begin ========================================== |
2 | \ | |
3 | \ Hypervisor Software File: allocator.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: @(#)allocator.fth 1.2 98/03/24 | |
43 | purpose: | |
44 | copyright: Copyright 1998 Sun Microsystems, Inc. All Rights Reserved | |
45 | ||
46 | \ XXX This is a crude brute-force allocation scheme that won't work for | |
47 | \ many cases, but probably will work for most of the situations we will | |
48 | \ face in practise -- a prototype version that gets lots of memory once, | |
49 | \ releases it once, and while the host adaptor is active, parcels out bits | |
50 | \ and pieces on request. | |
51 | ||
52 | -1 value dma-base \ Must be global | |
53 | -1 value dev-dma-base \ Ditto | |
54 | ||
55 | h# 10.0000 constant #grab | |
56 | ||
57 | : get-mem ( -- ) | |
58 | #grab dma-alloc to dma-base | |
59 | dma-base #grab false dma-map-in to dev-dma-base | |
60 | ; | |
61 | ||
62 | : give-mem ( -- ) | |
63 | dma-base dev-dma-base #grab dma-map-out | |
64 | -1 to dev-dma-base | |
65 | dma-base #grab dma-free | |
66 | -1 to dma-base | |
67 | ; | |
68 | ||
69 | : sync-mem ( -- ) | |
70 | dma-base dev-dma-base #grab dma-sync | |
71 | ; | |
72 | ||
73 | : virt>offset ( virt -- offset ) dma-base - ; | |
74 | : dev>offset ( dev -- offset ) dev-dma-base - ; | |
75 | ||
76 | : offset>virt ( offset -- virt ) dma-base + ; | |
77 | : offset>dev ( offset -- dev ) dev-dma-base + ; | |
78 | ||
79 | : virt>dev ( virt -- dev ) virt>offset offset>dev ; | |
80 | ||
81 | : dev>virt ( dev -- virt ) dev>offset offset>virt ; | |
82 | ||
83 | \ XXX alignment restrictions. first fit. keep list in sorted order. key | |
84 | \ on virt address. keep actual requested amount and allocated amount for | |
85 | \ now. do in 1k byte chunks for now. this gives 1000 entries for 1000 | |
86 | \ pieces to get to 1 meg grabbed in the first place. | |
87 | \ most alignment can actually be done to 32 bytes. | |
88 | ||
89 | \ The allocation table has one entry for each chunk of the dma space. | |
90 | \ So, 1k entries * 1kbytes/entry = 1meg. The entry is marked if that | |
91 | \ chunk is allocated. It is unmarked if that chunk is available. This | |
92 | \ gives coalescing chunks for free. | |
93 | ||
94 | \ The memory must be like dma-alloc and dma-free -- the requester must free | |
95 | \ exactly what it asked for. | |
96 | ||
97 | struct | |
98 | /n field >marker \ non-zero if allocated | |
99 | \ /n field >asked | |
100 | \ /n field >given | |
101 | /n field >caller-addr \ in case this is a copy buffer | |
102 | constant /entry | |
103 | ||
104 | h# 400 constant /slot \ #bytes for each table slot | |
105 | ||
106 | #grab /slot / constant #mem-entries | |
107 | ||
108 | #mem-entries /entry * buffer: mem-table | |
109 | ||
110 | \ In case the table representation changes, use these: | |
111 | : mark ( tbl-addr #slots -- ) | |
112 | 0 do | |
113 | true | |
114 | over i /entry * + ! | |
115 | loop | |
116 | drop | |
117 | ; | |
118 | ||
119 | : unmark ( tbl-addr #slots -- ) | |
120 | /entry * erase | |
121 | ; | |
122 | ||
123 | : slot>tbl-addr ( slot# -- table-addr ) /entry * mem-table + ; | |
124 | ||
125 | : marked? ( slot# -- marker ) slot>tbl-addr >marker @ ; | |
126 | ||
127 | : virt>slot ( virt -- slot# ) virt>offset /slot / ; | |
128 | ||
129 | : slot>virt ( slot# -- virt ) /slot * dma-base + ; | |
130 | ||
131 | : #slots ( #bytes -- #slots-taken ) \ number of slots for this many bytes | |
132 | /slot /mod | |
133 | swap if 1+ then | |
134 | ; | |
135 | ||
136 | \ slot#1 is the start slot. slot#2 is the first slot that is unmarked. | |
137 | \ There had better be one, or this will fail. slot#2 could = slot#1 | |
138 | \ could use left-parse-string | |
139 | : find-next-open ( slot#1 -- slot#2 ) | |
140 | dup #mem-entries swap - 0 do | |
141 | dup i + marked? 0= if | |
142 | i leave | |
143 | then | |
144 | loop | |
145 | + | |
146 | ; | |
147 | ||
148 | \ could fill a region of memory w. 0's and do successive compares | |
149 | \ XXX again, there had better be a chunk that works somewhere in the table | |
150 | \ or crash will occur. | |
151 | : enough-slots? ( slot# #slots-needed -- yes? ) | |
152 | true -rot | |
153 | 0 do | |
154 | dup i + marked? if nip false swap leave then | |
155 | loop | |
156 | drop | |
157 | ; | |
158 | ||
159 | \ XXX this is dumb. brute force. slows down in a region of not enough slots. | |
160 | : find-start-slot ( #slots -- slot# ) \ slot# is start of region | |
161 | >r 0 begin ( test-slot ) ( R: #slots ) | |
162 | dup r@ enough-slots? 0= | |
163 | while ( bad-slot# ) ( R: #slots ) | |
164 | 1+ find-next-open | |
165 | repeat | |
166 | r> drop | |
167 | ; | |
168 | ||
169 | \ find the first non-zero. count number of succeeding zeros. are there enough? | |
170 | \ if so, done. if not, go to the next non-zero and start over. | |
171 | \ XXX there better be enough room left or the whole thing will crash. | |
172 | \ XXX assume it never fails: | |
173 | : get-chunk ( #bytes -- virt ) \ acquire dma memory | |
174 | dup | |
175 | #slots dup | |
176 | find-start-slot ( #bytes #slots slot# ) | |
177 | tuck | |
178 | slot>tbl-addr swap mark | |
179 | slot>virt ( #bytes virt ) | |
180 | tuck swap erase | |
181 | ; | |
182 | ||
183 | : give-chunk ( virt #bytes -- ) \ return dma memory | |
184 | #slots swap | |
185 | virt>slot slot>tbl-addr swap | |
186 | unmark | |
187 | ; | |
188 | ||
189 | : new-mem-table ( -- ) | |
190 | mem-table #mem-entries /entry * erase | |
191 | ; |