2 * linux/arch/alpha/mm/init.c
4 * Copyright (C) 1995 Linus Torvalds
7 /* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea@suse.de> */
9 #include <linux/config.h>
10 #include <linux/signal.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #include <linux/types.h>
16 #include <linux/ptrace.h>
17 #include <linux/mman.h>
19 #include <linux/swap.h>
20 #include <linux/init.h>
21 #include <linux/bootmem.h> /* max_low_pfn */
22 #include <linux/vmalloc.h>
24 #include <asm/system.h>
25 #include <asm/uaccess.h>
26 #include <asm/pgtable.h>
27 #include <asm/pgalloc.h>
28 #include <asm/hwrpb.h>
30 #include <asm/mmu_context.h>
31 #include <asm/console.h>
34 DEFINE_PER_CPU(struct mmu_gather
, mmu_gathers
);
36 extern void die_if_kernel(char *,struct pt_regs
*,long);
38 static struct pcb_struct original_pcb
;
41 pgd_alloc(struct mm_struct
*mm
)
45 ret
= (pgd_t
*)__get_free_page(GFP_KERNEL
);
46 init
= pgd_offset(&init_mm
, 0UL);
49 #ifdef CONFIG_ALPHA_LARGE_VMALLOC
50 memcpy (ret
+ USER_PTRS_PER_PGD
, init
+ USER_PTRS_PER_PGD
,
51 (PTRS_PER_PGD
- USER_PTRS_PER_PGD
- 1)*sizeof(pgd_t
));
53 pgd_val(ret
[PTRS_PER_PGD
-2]) = pgd_val(init
[PTRS_PER_PGD
-2]);
56 /* The last PGD entry is the VPTB self-map. */
57 pgd_val(ret
[PTRS_PER_PGD
-1])
58 = pte_val(mk_pte(virt_to_page(ret
), PAGE_KERNEL
));
64 pte_alloc_one_kernel(struct mm_struct
*mm
, unsigned long address
)
66 pte_t
*pte
= (pte_t
*)__get_free_page(GFP_KERNEL
|__GFP_REPEAT
);
74 * BAD_PAGE is the page that is used for page faults when linux
75 * is out-of-memory. Older versions of linux just did a
76 * do_exit(), but using this instead means there is less risk
77 * for a process dying in kernel mode, possibly leaving an inode
80 * BAD_PAGETABLE is the accompanying page-table: it is initialized
81 * to point to BAD_PAGE entries.
83 * ZERO_PAGE is a special page that is used for zero-initialized
89 memset((void *) EMPTY_PGT
, 0, PAGE_SIZE
);
90 return (pmd_t
*) EMPTY_PGT
;
96 memset((void *) EMPTY_PGE
, 0, PAGE_SIZE
);
97 return pte_mkdirty(mk_pte(virt_to_page(EMPTY_PGE
), PAGE_SHARED
));
100 #ifndef CONFIG_DISCONTIGMEM
104 long i
,free
= 0,total
= 0,reserved
= 0;
105 long shared
= 0, cached
= 0;
107 printk("\nMem-info:\n");
109 printk("Free swap: %6ldkB\n", nr_swap_pages
<<(PAGE_SHIFT
-10));
113 if (PageReserved(mem_map
+i
))
115 else if (PageSwapCache(mem_map
+i
))
117 else if (!page_count(mem_map
+i
))
120 shared
+= page_count(mem_map
+ i
) - 1;
122 printk("%ld pages of RAM\n",total
);
123 printk("%ld free pages\n",free
);
124 printk("%ld reserved pages\n",reserved
);
125 printk("%ld pages shared\n",shared
);
126 printk("%ld pages swap cached\n",cached
);
130 static inline unsigned long
131 load_PCB(struct pcb_struct
*pcb
)
133 register unsigned long sp
__asm__("$30");
135 return __reload_thread(pcb
);
138 /* Set up initial PCB, VPTB, and other such nicities. */
141 switch_to_system_map(void)
143 unsigned long newptbr
;
144 unsigned long original_pcb_ptr
;
146 /* Initialize the kernel's page tables. Linux puts the vptb in
147 the last slot of the L1 page table. */
148 memset(swapper_pg_dir
, 0, PAGE_SIZE
);
149 newptbr
= ((unsigned long) swapper_pg_dir
- PAGE_OFFSET
) >> PAGE_SHIFT
;
150 pgd_val(swapper_pg_dir
[1023]) =
151 (newptbr
<< 32) | pgprot_val(PAGE_KERNEL
);
153 /* Set the vptb. This is often done by the bootloader, but
154 shouldn't be required. */
155 if (hwrpb
->vptb
!= 0xfffffffe00000000UL
) {
156 wrvptptr(0xfffffffe00000000UL
);
157 hwrpb
->vptb
= 0xfffffffe00000000UL
;
158 hwrpb_update_checksum(hwrpb
);
161 /* Also set up the real kernel PCB while we're at it. */
162 init_thread_info
.pcb
.ptbr
= newptbr
;
163 init_thread_info
.pcb
.flags
= 1; /* set FEN, clear everything else */
164 original_pcb_ptr
= load_PCB(&init_thread_info
.pcb
);
167 /* Save off the contents of the original PCB so that we can
168 restore the original console's page tables for a clean reboot.
170 Note that the PCB is supposed to be a physical address, but
171 since KSEG values also happen to work, folks get confused.
174 if (original_pcb_ptr
< PAGE_OFFSET
) {
175 original_pcb_ptr
= (unsigned long)
176 phys_to_virt(original_pcb_ptr
);
178 original_pcb
= *(struct pcb_struct
*) original_pcb_ptr
;
181 int callback_init_done
;
184 callback_init(void * kernel_end
)
186 struct crb_struct
* crb
;
191 /* Starting at the HWRPB, locate the CRB. */
192 crb
= (struct crb_struct
*)((char *)hwrpb
+ hwrpb
->crb_offset
);
194 if (alpha_using_srm
) {
195 /* Tell the console whither it is to be remapped. */
196 if (srm_fixup(VMALLOC_START
, (unsigned long)hwrpb
))
197 __halt(); /* "We're boned." --Bender */
199 /* Edit the procedure descriptors for DISPATCH and FIXUP. */
200 crb
->dispatch_va
= (struct procdesc_struct
*)
201 (VMALLOC_START
+ (unsigned long)crb
->dispatch_va
203 crb
->fixup_va
= (struct procdesc_struct
*)
204 (VMALLOC_START
+ (unsigned long)crb
->fixup_va
208 switch_to_system_map();
210 /* Allocate one PGD and one PMD. In the case of SRM, we'll need
211 these to actually remap the console. There is an assumption
212 here that only one of each is needed, and this allows for 8MB.
213 On systems with larger consoles, additional pages will be
214 allocated as needed during the mapping process.
216 In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC,
217 we need to allocate the PGD we use for vmalloc before we start
218 forking other tasks. */
221 (((unsigned long)kernel_end
+ ~PAGE_MASK
) & PAGE_MASK
);
222 kernel_end
= two_pages
+ 2*PAGE_SIZE
;
223 memset(two_pages
, 0, 2*PAGE_SIZE
);
225 pgd
= pgd_offset_k(VMALLOC_START
);
226 pgd_set(pgd
, (pmd_t
*)two_pages
);
227 pmd
= pmd_offset(pgd
, VMALLOC_START
);
228 pmd_set(pmd
, (pte_t
*)(two_pages
+ PAGE_SIZE
));
230 if (alpha_using_srm
) {
231 static struct vm_struct console_remap_vm
;
232 unsigned long vaddr
= VMALLOC_START
;
235 /* Set up the third level PTEs and update the virtual
236 addresses of the CRB entries. */
237 for (i
= 0; i
< crb
->map_entries
; ++i
) {
238 unsigned long pfn
= crb
->map
[i
].pa
>> PAGE_SHIFT
;
239 crb
->map
[i
].va
= vaddr
;
240 for (j
= 0; j
< crb
->map
[i
].count
; ++j
) {
241 /* Newer console's (especially on larger
242 systems) may require more pages of
243 PTEs. Grab additional pages as needed. */
244 if (pmd
!= pmd_offset(pgd
, vaddr
)) {
245 memset(kernel_end
, 0, PAGE_SIZE
);
246 pmd
= pmd_offset(pgd
, vaddr
);
247 pmd_set(pmd
, (pte_t
*)kernel_end
);
248 kernel_end
+= PAGE_SIZE
;
250 set_pte(pte_offset_kernel(pmd
, vaddr
),
251 pfn_pte(pfn
, PAGE_KERNEL
));
257 /* Let vmalloc know that we've allocated some space. */
258 console_remap_vm
.flags
= VM_ALLOC
;
259 console_remap_vm
.addr
= (void *) VMALLOC_START
;
260 console_remap_vm
.size
= vaddr
- VMALLOC_START
;
261 vmlist
= &console_remap_vm
;
264 callback_init_done
= 1;
269 #ifndef CONFIG_DISCONTIGMEM
271 * paging_init() sets up the memory map.
276 unsigned long zones_size
[MAX_NR_ZONES
] = {0, 0, 0};
277 unsigned long dma_pfn
, high_pfn
;
279 dma_pfn
= virt_to_phys((char *)MAX_DMA_ADDRESS
) >> PAGE_SHIFT
;
280 high_pfn
= max_pfn
= max_low_pfn
;
282 if (dma_pfn
>= high_pfn
)
283 zones_size
[ZONE_DMA
] = high_pfn
;
285 zones_size
[ZONE_DMA
] = dma_pfn
;
286 zones_size
[ZONE_NORMAL
] = high_pfn
- dma_pfn
;
289 /* Initialize mem_map[]. */
290 free_area_init(zones_size
);
292 /* Initialize the kernel's ZERO_PGE. */
293 memset((void *)ZERO_PGE
, 0, PAGE_SIZE
);
295 #endif /* CONFIG_DISCONTIGMEM */
297 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
299 srm_paging_stop (void)
301 /* Move the vptb back to where the SRM console expects it. */
302 swapper_pg_dir
[1] = swapper_pg_dir
[1023];
304 wrvptptr(0x200000000UL
);
305 hwrpb
->vptb
= 0x200000000UL
;
306 hwrpb_update_checksum(hwrpb
);
308 /* Reload the page tables that the console had in use. */
309 load_PCB(&original_pcb
);
314 #ifndef CONFIG_DISCONTIGMEM
316 printk_memory_info(void)
318 unsigned long codesize
, reservedpages
, datasize
, initsize
, tmp
;
319 extern int page_is_ram(unsigned long) __init
;
320 extern char _text
, _etext
, _data
, _edata
;
321 extern char __init_begin
, __init_end
;
323 /* printk all informations */
325 for (tmp
= 0; tmp
< max_low_pfn
; tmp
++)
327 * Only count reserved RAM pages
329 if (page_is_ram(tmp
) && PageReserved(mem_map
+tmp
))
332 codesize
= (unsigned long) &_etext
- (unsigned long) &_text
;
333 datasize
= (unsigned long) &_edata
- (unsigned long) &_data
;
334 initsize
= (unsigned long) &__init_end
- (unsigned long) &__init_begin
;
336 printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk init)\n",
337 (unsigned long) nr_free_pages() << (PAGE_SHIFT
-10),
338 max_mapnr
<< (PAGE_SHIFT
-10),
340 reservedpages
<< (PAGE_SHIFT
-10),
348 max_mapnr
= num_physpages
= max_low_pfn
;
349 totalram_pages
+= free_all_bootmem();
350 high_memory
= (void *) __va(max_low_pfn
* PAGE_SIZE
);
352 printk_memory_info();
354 #endif /* CONFIG_DISCONTIGMEM */
357 free_reserved_mem(void *start
, void *end
)
359 void *__start
= start
;
360 for (; __start
< end
; __start
+= PAGE_SIZE
) {
361 ClearPageReserved(virt_to_page(__start
));
362 set_page_count(virt_to_page(__start
), 1);
363 free_page((long)__start
);
371 extern char __init_begin
, __init_end
;
373 free_reserved_mem(&__init_begin
, &__init_end
);
374 printk ("Freeing unused kernel memory: %ldk freed\n",
375 (&__init_end
- &__init_begin
) >> 10);
378 #ifdef CONFIG_BLK_DEV_INITRD
380 free_initrd_mem(unsigned long start
, unsigned long end
)
382 free_reserved_mem((void *)start
, (void *)end
);
383 printk ("Freeing initrd memory: %ldk freed\n", (end
- start
) >> 10);