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