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