Diff markup
001 001
002 <<
003 002
004 003
005 004
006 005
007 006
008 007
009 008
010 009
011 010
012 011
013 012
014 013
015 014
016 015
017 016
018 017
019 #include <sos/list.h> 018 #include <sos/list.h>
020 #include <sos/macros.h> 019 #include <sos/macros.h>
021 #include <sos/assert.h> 020 #include <sos/assert.h>
022 #include <sos/klibc.h> 021 #include <sos/klibc.h>
023 022
024 #include "physmem.h" 023 #include "physmem.h"
025 024
026 025
027 struct physical_page_descr 026 struct physical_page_descr
028 { 027 {
029 028
030 sos_paddr_t paddr; 029 sos_paddr_t paddr;
031 030
032 031
033 !! 032
034 sos_count_t ref_cnt; 033 sos_count_t ref_cnt;
035 034
036 !! 035
037 <<
038 <<
039 <<
040 <<
041 <<
042 <<
043 <<
044 <<
045 sos_count_t occupation_cnt; <<
046 <<
047 <<
048 <<
049 struct sos_kmem_range *kernel_range; <<
050 <<
051 <<
052 struct physical_page_descr *prev, *next; 036 struct physical_page_descr *prev, *next;
053 }; 037 };
054 038
055 039
056 extern char __b_kernel, __e_kernel; 040 extern char __b_kernel, __e_kernel;
057 041
058 042
059 #define PAGE_DESCR_ARRAY_ADDR \ 043 #define PAGE_DESCR_ARRAY_ADDR \
060 SOS_PAGE_ALIGN_SUP((sos_paddr_t) (& __e_kern 044 SOS_PAGE_ALIGN_SUP((sos_paddr_t) (& __e_kernel))
061 static struct physical_page_descr * physical_p 045 static struct physical_page_descr * physical_page_descr_array;
062 046
063 047
064 static struct physical_page_descr *free_ppage; 048 static struct physical_page_descr *free_ppage;
065 049
066 !! 050
067 static struct physical_page_descr *nonfree_ppa !! 051 static struct physical_page_descr *used_ppage;
068 052
069 053
070 static sos_paddr_t physmem_base, physmem_top; 054 static sos_paddr_t physmem_base, physmem_top;
071 055
072 !! 056
073 static sos_count_t physmem_total_pages, physme !! 057 static sos_count_t physmem_total_pages, physmem_used_pages;
074 058
075 sos_ret_t sos_physmem_subsystem_setup(sos_size !! 059 sos_ret_t sos_physmem_setup(sos_size_t ram_size,
076 !! 060 sos_paddr_t *kernel_core_base,
077 !! 061 sos_paddr_t *kernel_core_top)
078 { 062 {
079 063
080 struct physical_page_descr *ppage_descr; 064 struct physical_page_descr *ppage_descr;
081 065
082 066
083 sos_paddr_t ppage_addr; 067 sos_paddr_t ppage_addr;
084 068
085 069
086 ram_size = SOS_PAGE_ALIGN_INF(ram_size); 070 ram_size = SOS_PAGE_ALIGN_INF(ram_size);
087 071
088 !! 072
089 free_ppage = nonfree_ppage = NULL; !! 073 free_ppage = used_ppage = NULL;
090 physmem_total_pages = physmem_nonfree_pages !! 074 physmem_total_pages = physmem_used_pages = 0;
091 075
092 076
093 077
094 *kernel_core_base = SOS_PAGE_ALIGN_INF((sos_ 078 *kernel_core_base = SOS_PAGE_ALIGN_INF((sos_paddr_t)(& __b_kernel));
095 *kernel_core_top 079 *kernel_core_top
096 = PAGE_DESCR_ARRAY_ADDR 080 = PAGE_DESCR_ARRAY_ADDR
097 + SOS_PAGE_ALIGN_SUP( (ram_size >> SOS_P 081 + SOS_PAGE_ALIGN_SUP( (ram_size >> SOS_PAGE_SHIFT)
098 * sizeof(struct ph 082 * sizeof(struct physical_page_descr));
099 if (*kernel_core_top > ram_size) 083 if (*kernel_core_top > ram_size)
100 return -SOS_ENOMEM; 084 return -SOS_ENOMEM;
101 085
102 086
103 087
104 physmem_base = SOS_PAGE_SIZE; 088 physmem_base = SOS_PAGE_SIZE;
105 physmem_top = ram_size; 089 physmem_top = ram_size;
106 090
107 091
108 physical_page_descr_array 092 physical_page_descr_array
109 = (struct physical_page_descr*)PAGE_DESCR_ 093 = (struct physical_page_descr*)PAGE_DESCR_ARRAY_ADDR;
110 094
111 095
112 for (ppage_addr = 0, 096 for (ppage_addr = 0,
113 ppage_descr = physical_page_descr_arr 097 ppage_descr = physical_page_descr_array ;
114 ppage_addr < physmem_top ; 098 ppage_addr < physmem_top ;
115 ppage_addr += SOS_PAGE_SIZE, 099 ppage_addr += SOS_PAGE_SIZE,
116 ppage_descr ++) 100 ppage_descr ++)
117 { 101 {
118 enum { PPAGE_MARK_RESERVED, PPAGE_MARK_F 102 enum { PPAGE_MARK_RESERVED, PPAGE_MARK_FREE,
119 PPAGE_MARK_KERNEL, PPAGE_MARK_HWM 103 PPAGE_MARK_KERNEL, PPAGE_MARK_HWMAP } todo;
120 104
121 memset(ppage_descr, 0x0, sizeof(struct p 105 memset(ppage_descr, 0x0, sizeof(struct physical_page_descr));
122 106
123 107
124 ppage_descr->paddr = ppage_addr; 108 ppage_descr->paddr = ppage_addr;
125 109
126 110
127 if (ppage_addr < physmem_base) 111 if (ppage_addr < physmem_base)
128 todo = PPAGE_MARK_RESERVED; 112 todo = PPAGE_MARK_RESERVED;
129 113
130 114
131 else if ((ppage_addr >= physmem_base) 115 else if ((ppage_addr >= physmem_base)
132 && (ppage_addr < BIOS_N_VIDEO_S 116 && (ppage_addr < BIOS_N_VIDEO_START))
133 todo = PPAGE_MARK_FREE; 117 todo = PPAGE_MARK_FREE;
134 118
135 119
136 else if ((ppage_addr >= BIOS_N_VIDEO_STA 120 else if ((ppage_addr >= BIOS_N_VIDEO_START)
137 && (ppage_addr < BIOS_N_VIDEO_E 121 && (ppage_addr < BIOS_N_VIDEO_END))
138 todo = PPAGE_MARK_HWMAP; 122 todo = PPAGE_MARK_HWMAP;
139 123
140 124
141 else if ((ppage_addr >= BIOS_N_VIDEO_END 125 else if ((ppage_addr >= BIOS_N_VIDEO_END)
142 && (ppage_addr < (sos_paddr_t) 126 && (ppage_addr < (sos_paddr_t) (& __b_kernel)))
143 todo = PPAGE_MARK_FREE; 127 todo = PPAGE_MARK_FREE;
144 128
145 129
146 else if ((ppage_addr >= *kernel_core_bas 130 else if ((ppage_addr >= *kernel_core_base)
147 && (ppage_addr < *kernel_core_ 131 && (ppage_addr < *kernel_core_top))
148 todo = PPAGE_MARK_KERNEL; 132 todo = PPAGE_MARK_KERNEL;
149 133
150 134
151 else 135 else
152 todo = PPAGE_MARK_FREE; 136 todo = PPAGE_MARK_FREE;
153 137
154 !! 138
155 physmem_total_pages ++; 139 physmem_total_pages ++;
156 switch (todo) 140 switch (todo)
157 { 141 {
158 case PPAGE_MARK_FREE: 142 case PPAGE_MARK_FREE:
159 ppage_descr->ref_cnt = 0; 143 ppage_descr->ref_cnt = 0;
160 list_add_head(free_ppage, ppage_desc 144 list_add_head(free_ppage, ppage_descr);
161 break; 145 break;
162 146
163 case PPAGE_MARK_KERNEL: 147 case PPAGE_MARK_KERNEL:
164 case PPAGE_MARK_HWMAP: 148 case PPAGE_MARK_HWMAP:
165 ppage_descr->ref_cnt = 1; 149 ppage_descr->ref_cnt = 1;
166 list_add_head(nonfree_ppage, ppage_d !! 150 list_add_head(used_ppage, ppage_descr);
167 physmem_nonfree_pages ++; !! 151 physmem_used_pages ++;
168 break; 152 break;
169 153
170 default: 154 default:
171 155
172 break; 156 break;
173 } 157 }
174 } 158 }
175 159
176 return SOS_OK; 160 return SOS_OK;
177 } 161 }
178 162
179 163
180 sos_paddr_t sos_physmem_ref_physpage_new(sos_b 164 sos_paddr_t sos_physmem_ref_physpage_new(sos_bool_t can_block)
181 { 165 {
182 struct physical_page_descr *ppage_descr; 166 struct physical_page_descr *ppage_descr;
183 167
184 if (! free_ppage) 168 if (! free_ppage)
185 return (sos_paddr_t)NULL; 169 return (sos_paddr_t)NULL;
186 170
187 171
188 ppage_descr = list_pop_head(free_ppage); 172 ppage_descr = list_pop_head(free_ppage);
189 173
190 !! 174
191 SOS_ASSERT_FATAL(ppage_descr->ref_cnt == 0); 175 SOS_ASSERT_FATAL(ppage_descr->ref_cnt == 0);
192 176
193 !! 177
194 ppage_descr->ref_cnt ++; 178 ppage_descr->ref_cnt ++;
195 179
196 !! 180
197 !! 181 list_add_tail(used_ppage, ppage_descr);
198 !! 182 physmem_used_pages ++;
199 SOS_ASSERT_FATAL(ppage_descr->occupation_cnt <<
200 SOS_ASSERT_FATAL(ppage_descr->kernel_range = <<
201 <<
202 <<
203 list_add_tail(nonfree_ppage, ppage_descr); <<
204 physmem_nonfree_pages ++; <<
205 183
206 return ppage_descr->paddr; 184 return ppage_descr->paddr;
207 } 185 }
208 186
209 187
210 188
211 189
212 190
213 191
214 192
215 193
216 inline static struct physical_page_descr * 194 inline static struct physical_page_descr *
217 get_page_descr_at_paddr(sos_paddr_t ppage_padd 195 get_page_descr_at_paddr(sos_paddr_t ppage_paddr)
218 { 196 {
219 197
220 if (ppage_paddr & SOS_PAGE_MASK) 198 if (ppage_paddr & SOS_PAGE_MASK)
221 return NULL; 199 return NULL;
222 200
223 201
224 if ((ppage_paddr < physmem_base) || (ppage_p 202 if ((ppage_paddr < physmem_base) || (ppage_paddr >= physmem_top))
225 return NULL; 203 return NULL;
226 204
227 return physical_page_descr_array + (ppage_pa 205 return physical_page_descr_array + (ppage_paddr >> SOS_PAGE_SHIFT);
228 } 206 }
229 207
230 208
231 sos_ret_t sos_physmem_ref_physpage_at(sos_padd 209 sos_ret_t sos_physmem_ref_physpage_at(sos_paddr_t ppage_paddr)
232 { 210 {
233 struct physical_page_descr *ppage_descr 211 struct physical_page_descr *ppage_descr
234 = get_page_descr_at_paddr(ppage_paddr); 212 = get_page_descr_at_paddr(ppage_paddr);
235 213
236 if (! ppage_descr) 214 if (! ppage_descr)
237 return -SOS_EINVAL; 215 return -SOS_EINVAL;
238 216
239 217
240 ppage_descr->ref_cnt ++; 218 ppage_descr->ref_cnt ++;
241 219
242 220
243 !! 221
244 if (ppage_descr->ref_cnt == 1) 222 if (ppage_descr->ref_cnt == 1)
245 { 223 {
246 <<
247 <<
248 <<
249 SOS_ASSERT_FATAL(ppage_descr->occupation <<
250 SOS_ASSERT_FATAL(ppage_descr->kernel_ran <<
251 <<
252 list_delete(free_ppage, ppage_descr); 224 list_delete(free_ppage, ppage_descr);
253 list_add_tail(nonfree_ppage, ppage_descr !! 225 list_add_tail(used_ppage, ppage_descr);
254 physmem_nonfree_pages ++; !! 226 physmem_used_pages ++;
255 227
256 228
257 return FALSE; 229 return FALSE;
258 } 230 }
259 !! 231
260 232
261 return TRUE; 233 return TRUE;
262 } 234 }
263 235
264 236
265 sos_ret_t 237 sos_ret_t
266 sos_physmem_unref_physpage(sos_paddr_t ppage_p 238 sos_physmem_unref_physpage(sos_paddr_t ppage_paddr)
267 { 239 {
268 240
269 241
270 sos_ret_t retval = FALSE; 242 sos_ret_t retval = FALSE;
271 243
272 struct physical_page_descr *ppage_descr 244 struct physical_page_descr *ppage_descr
273 = get_page_descr_at_paddr(ppage_paddr); 245 = get_page_descr_at_paddr(ppage_paddr);
274 246
275 if (! ppage_descr) 247 if (! ppage_descr)
276 return -SOS_EINVAL; 248 return -SOS_EINVAL;
277 249
278 !! 250
279 if (ppage_descr->ref_cnt <= 0) 251 if (ppage_descr->ref_cnt <= 0)
280 return -SOS_EINVAL; 252 return -SOS_EINVAL;
281 253
282 254
283 255
284 ppage_descr->ref_cnt--; 256 ppage_descr->ref_cnt--;
285 if (ppage_descr->ref_cnt == 0) !! 257 if (ppage_descr->ref_cnt <= 0)
286 { 258 {
287 !! 259
288 SOS_ASSERT_FATAL(ppage_descr->occupation !! 260 list_delete(used_ppage, ppage_descr);
289 !! 261 physmem_used_pages --;
290 <<
291 ppage_descr->kernel_range = NULL; <<
292 <<
293 <<
294 list_delete(nonfree_ppage, ppage_descr); <<
295 physmem_nonfree_pages --; <<
296 list_add_head(free_ppage, ppage_descr); 262 list_add_head(free_ppage, ppage_descr);
297 263
298 264
299 retval = TRUE; 265 retval = TRUE;
300 } 266 }
301 267
302 <<
303 return retval; 268 return retval;
304 } <<
305 <<
306 <<
307 sos_ret_t sos_physmem_get_physpage_refcount(so <<
308 { <<
309 struct physical_page_descr *ppage_descr <<
310 = get_page_descr_at_paddr(ppage_paddr); <<
311 <<
312 if (! ppage_descr) <<
313 return -SOS_EINVAL; <<
314 <<
315 return ppage_descr->ref_cnt; <<
316 } <<
317 <<
318 <<
319 sos_ret_t sos_physmem_inc_physpage_occupation( <<
320 { <<
321 struct physical_page_descr *ppage_descr <<
322 = get_page_descr_at_paddr(ppage_paddr); <<
323 <<
324 if (! ppage_descr) <<
325 return -SOS_EINVAL; <<
326 <<
327 <<
328 SOS_ASSERT_FATAL(ppage_descr->ref_cnt > 0); <<
329 <<
330 ppage_descr->occupation_cnt ++; <<
331 return (ppage_descr->occupation_cnt > 1); <<
332 } <<
333 <<
334 <<
335 sos_ret_t sos_physmem_dec_physpage_occupation( <<
336 { <<
337 struct physical_page_descr *ppage_descr <<
338 = get_page_descr_at_paddr(ppage_paddr); <<
339 <<
340 if (! ppage_descr) <<
341 return -SOS_EINVAL; <<
342 <<
343 <<
344 SOS_ASSERT_FATAL(ppage_descr->ref_cnt > 0); <<
345 SOS_ASSERT_FATAL(ppage_descr->occupation_cnt <<
346 <<
347 ppage_descr->occupation_cnt --; <<
348 return (ppage_descr->occupation_cnt == 0); <<
349 } <<
350 <<
351 <<
352 struct sos_kmem_range* sos_physmem_get_kmem_ra <<
353 { <<
354 struct physical_page_descr *ppage_descr <<
355 = get_page_descr_at_paddr(ppage_paddr); <<
356 <<
357 if (! ppage_descr) <<
358 return NULL; <<
359 <<
360 return ppage_descr->kernel_range; <<
361 } <<
362 <<
363 <<
364 sos_ret_t sos_physmem_set_kmem_range(sos_paddr <<
365 struct so <<
366 { <<
367 struct physical_page_descr *ppage_descr <<
368 = get_page_descr_at_paddr(ppage_paddr); <<
369 <<
370 if (! ppage_descr) <<
371 return -SOS_EINVAL; <<
372 <<
373 ppage_descr->kernel_range = range; <<
374 return SOS_OK; <<
375 } <<
376 <<
377 sos_ret_t sos_physmem_get_state(sos_c <<
378 sos_c <<
379 { <<
380 if (total_ppages) <<
381 *total_ppages = physmem_total_pages; <<
382 if (nonfree_ppages) <<
383 *nonfree_ppages = physmem_nonfree_pages; <<
384 return SOS_OK; <<
385 } 269 }