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