This source file includes following definitions.
- __bad_pagetable
- __bad_page
- show_mem
- paging_init
- mem_init
- si_meminfo
1
2
3
4
5
6
7 #include <linux/config.h>
8 #include <linux/signal.h>
9 #include <linux/sched.h>
10 #include <linux/head.h>
11 #include <linux/kernel.h>
12 #include <linux/errno.h>
13 #include <linux/string.h>
14 #include <linux/types.h>
15 #include <linux/ptrace.h>
16 #include <linux/mman.h>
17 #include <linux/mm.h>
18 #include <linux/smp.h>
19
20 #include <asm/system.h>
21 #include <asm/segment.h>
22 #include <asm/pgtable.h>
23
24
25
26
27 #ifdef __SMP__
28 #undef USE_PENTIUM_MM
29 #endif
30
31 extern void scsi_mem_init(unsigned long);
32 extern void die_if_kernel(char *,struct pt_regs *,long);
33 extern void show_net_buffers(void);
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 pte_t * __bad_pagetable(void)
49 {
50 extern char empty_bad_page_table[PAGE_SIZE];
51
52 __asm__ __volatile__("cld ; rep ; stosl":
53 :"a" (pte_val(BAD_PAGE)),
54 "D" ((long) empty_bad_page_table),
55 "c" (PAGE_SIZE/4)
56 :"di","cx");
57 return (pte_t *) empty_bad_page_table;
58 }
59
60 pte_t __bad_page(void)
61 {
62 extern char empty_bad_page[PAGE_SIZE];
63
64 __asm__ __volatile__("cld ; rep ; stosl":
65 :"a" (0),
66 "D" ((long) empty_bad_page),
67 "c" (PAGE_SIZE/4)
68 :"di","cx");
69 return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
70 }
71
72 void show_mem(void)
73 {
74 int i,free = 0,total = 0,reserved = 0;
75 int shared = 0;
76
77 printk("Mem-info:\n");
78 show_free_areas();
79 printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
80 i = high_memory >> PAGE_SHIFT;
81 while (i-- > 0) {
82 total++;
83 if (mem_map[i].reserved)
84 reserved++;
85 else if (!mem_map[i].count)
86 free++;
87 else
88 shared += mem_map[i].count-1;
89 }
90 printk("%d pages of RAM\n",total);
91 printk("%d free pages\n",free);
92 printk("%d reserved pages\n",reserved);
93 printk("%d pages shared\n",shared);
94 show_buffers();
95 #ifdef CONFIG_NET
96 show_net_buffers();
97 #endif
98 }
99
100 extern unsigned long free_area_init(unsigned long, unsigned long);
101
102
103
104
105
106
107
108
109 unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
110 {
111 pgd_t * pg_dir;
112 pte_t * pg_table;
113 unsigned long tmp;
114 unsigned long address;
115
116
117
118
119
120
121
122
123 #if 0
124 memset((void *) 0, 0, PAGE_SIZE);
125 #endif
126 #ifdef __SMP__
127 smp_scan_config(0x0,0x400);
128
129
130
131
132 smp_scan_config(639*0x400,0x400);
133 smp_scan_config(0xF0000,0x10000);
134
135
136
137
138
139
140
141 #endif
142 #ifdef TEST_VERIFY_AREA
143 wp_works_ok = 0;
144 #endif
145 start_mem = PAGE_ALIGN(start_mem);
146 address = 0;
147 pg_dir = swapper_pg_dir;
148 while (address < end_mem) {
149 #ifdef USE_PENTIUM_MM
150 if (address <= end_mem + 4*1024*1024 &&
151 (x86_capability & 8)) {
152 #ifdef GAS_KNOWS_CR4
153 __asm__("movl %%cr4,%%eax\n\t"
154 "orl $16,%%eax\n\t"
155 "movl %%eax,%%cr4"
156 : : :"ax");
157 #else
158 __asm__(".byte 0x0f,0x20,0xe0\n\t"
159 "orl $16,%%eax\n\t"
160 ".byte 0x0f,0x22,0xe0"
161 : : :"ax");
162 #endif
163 wp_works_ok = 1;
164 pgd_val(pg_dir[0]) = _PAGE_TABLE | _PAGE_4M | address;
165 pgd_val(pg_dir[768]) = _PAGE_TABLE | _PAGE_4M | address;
166 pg_dir++;
167 address += 4*1024*1024;
168 continue;
169 }
170 #endif
171
172 pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768]));
173 if (!pg_table) {
174 pg_table = (pte_t *) start_mem;
175 start_mem += PAGE_SIZE;
176 }
177
178
179 pgd_val(pg_dir[0]) = _PAGE_TABLE | (unsigned long) pg_table;
180 pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table;
181 pg_dir++;
182 for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) {
183 if (address < end_mem)
184 set_pte(pg_table, mk_pte(address, PAGE_SHARED));
185 else
186 pte_clear(pg_table);
187 address += PAGE_SIZE;
188 }
189 }
190 invalidate();
191 return free_area_init(start_mem, end_mem);
192 }
193
194 void mem_init(unsigned long start_mem, unsigned long end_mem)
195 {
196 unsigned long start_low_mem = PAGE_SIZE;
197 int codepages = 0;
198 int reservedpages = 0;
199 int datapages = 0;
200 unsigned long tmp;
201 extern int _etext;
202
203 end_mem &= PAGE_MASK;
204 high_memory = end_mem;
205
206
207 memset(empty_zero_page, 0, PAGE_SIZE);
208
209
210 start_low_mem = PAGE_ALIGN(start_low_mem);
211
212 #ifdef __SMP__
213
214
215
216 start_low_mem += PAGE_SIZE;
217 start_low_mem = smp_alloc_memory(start_low_mem);
218 #endif
219 start_mem = PAGE_ALIGN(start_mem);
220
221
222
223
224
225
226 while (start_low_mem < 0x9f000) {
227 mem_map[MAP_NR(start_low_mem)].reserved = 0;
228 start_low_mem += PAGE_SIZE;
229 }
230
231 while (start_mem < high_memory) {
232 mem_map[MAP_NR(start_mem)].reserved = 0;
233 start_mem += PAGE_SIZE;
234 }
235 #ifdef CONFIG_SCSI
236 scsi_mem_init(high_memory);
237 #endif
238 for (tmp = 0 ; tmp < high_memory ; tmp += PAGE_SIZE) {
239 if (mem_map[MAP_NR(tmp)].reserved) {
240 if (tmp >= 0xA0000 && tmp < 0x100000)
241 reservedpages++;
242 else if (tmp < (unsigned long) &_etext)
243 codepages++;
244 else
245 datapages++;
246 continue;
247 }
248 mem_map[MAP_NR(tmp)].count = 1;
249 free_page(tmp);
250 }
251 tmp = nr_free_pages << PAGE_SHIFT;
252 printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
253 tmp >> 10,
254 high_memory >> 10,
255 codepages << (PAGE_SHIFT-10),
256 reservedpages << (PAGE_SHIFT-10),
257 datapages << (PAGE_SHIFT-10));
258
259 if (wp_works_ok < 0) {
260 pg0[0] = pte_val(mk_pte(0, PAGE_READONLY));
261 invalidate();
262 __asm__ __volatile__("movb 0,%%al ; movb %%al,0": : :"ax", "memory");
263 pg0[0] = 0;
264 invalidate();
265 if (wp_works_ok < 0)
266 wp_works_ok = 0;
267 }
268 return;
269 }
270
271 void si_meminfo(struct sysinfo *val)
272 {
273 int i;
274
275 i = high_memory >> PAGE_SHIFT;
276 val->totalram = 0;
277 val->sharedram = 0;
278 val->freeram = nr_free_pages << PAGE_SHIFT;
279 val->bufferram = buffermem;
280 while (i-- > 0) {
281 if (mem_map[i].reserved)
282 continue;
283 val->totalram++;
284 if (!mem_map[i].count)
285 continue;
286 val->sharedram += mem_map[i].count-1;
287 }
288 val->totalram <<= PAGE_SHIFT;
289 val->sharedram <<= PAGE_SHIFT;
290 return;
291 }