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