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