patch-2.4.0-test10 linux/arch/alpha/mm/init.c
Next file: linux/arch/arm/config.in
Previous file: linux/arch/alpha/mm/fault.c
Back to the patch index
Back to the overall index
- Lines: 143
- Date:
Mon Oct 16 15:38:41 2000
- Orig file:
v2.4.0-test9/linux/arch/alpha/mm/init.c
- Orig date:
Mon Aug 7 21:02:27 2000
diff -u --recursive --new-file v2.4.0-test9/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c
@@ -19,6 +19,7 @@
#include <linux/swap.h>
#include <linux/init.h>
#include <linux/bootmem.h> /* max_low_pfn */
+#include <linux/vmalloc.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
@@ -30,6 +31,7 @@
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/mmu_context.h>
+#include <asm/console.h>
static unsigned long totalram_pages;
@@ -55,6 +57,29 @@
pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
}
+pgd_t *
+get_pgd_slow(void)
+{
+ pgd_t *ret, *init;
+
+ ret = (pgd_t *)__get_free_page(GFP_KERNEL);
+ init = pgd_offset(&init_mm, 0UL);
+ if (ret) {
+ clear_page(ret);
+#ifdef CONFIG_ALPHA_LARGE_VMALLOC
+ memcpy (ret + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD - 1)*sizeof(pgd_t));
+#else
+ pgd_val(ret[PTRS_PER_PGD-2]) = pgd_val(init[PTRS_PER_PGD-2]);
+#endif
+
+ /* The last PGD entry is the VPTB self-map. */
+ pgd_val(ret[PTRS_PER_PGD-1])
+ = pte_val(mk_pte(virt_to_page(ret), PAGE_KERNEL));
+ }
+ return ret;
+}
+
pmd_t *
get_pmd_slow(pgd_t *pgd, unsigned long offset)
{
@@ -182,8 +207,9 @@
return __reload_thread(pcb);
}
-/* switch_to_system_map() sets up some necessary page tables. */
-void
+/* Set up initial PCB, VPTB, and other such nicities. */
+
+static inline void
switch_to_system_map(void)
{
unsigned long newptbr;
@@ -224,6 +250,84 @@
}
original_pcb = *(struct thread_struct *) original_pcb_ptr;
}
+
+int callback_init_done;
+
+void * __init
+callback_init(void * kernel_end)
+{
+ struct crb_struct * crb;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ void *two_pages;
+
+ /* Starting at the HWRPB, locate the CRB. */
+ crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset);
+
+ if (alpha_using_srm) {
+ /* Tell the console whither it is to be remapped. */
+ if (srm_fixup(VMALLOC_START, (unsigned long)hwrpb))
+ __halt(); /* "We're boned." --Bender */
+
+ /* Edit the procedure descriptors for DISPATCH and FIXUP. */
+ crb->dispatch_va = (struct procdesc_struct *)
+ (VMALLOC_START + (unsigned long)crb->dispatch_va
+ - crb->map[0].va);
+ crb->fixup_va = (struct procdesc_struct *)
+ (VMALLOC_START + (unsigned long)crb->fixup_va
+ - crb->map[0].va);
+ }
+
+ switch_to_system_map();
+
+ /* Allocate one PGD and one PMD. In the case of SRM, we'll need
+ these to actually remap the console. There is an assumption
+ here that only one of each is needed, and this allows for 8MB.
+ Currently (late 1999), big consoles are still under 4MB.
+
+ In the case of not SRM, but not CONFIG_ALPHA_LARGE_VMALLOC,
+ we need to allocate the PGD we use for vmalloc before we start
+ forking other tasks. */
+
+ two_pages = (void *)
+ (((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK);
+ kernel_end = two_pages + 2*PAGE_SIZE;
+ memset(two_pages, 0, 2*PAGE_SIZE);
+
+ pgd = pgd_offset_k(VMALLOC_START);
+ pgd_set(pgd, (pmd_t *)two_pages);
+ pmd = pmd_offset(pgd, VMALLOC_START);
+ pmd_set(pmd, (pte_t *)(two_pages + PAGE_SIZE));
+
+ if (alpha_using_srm) {
+ static struct vm_struct console_remap_vm;
+ unsigned long vaddr = VMALLOC_START;
+ long i, j;
+
+ /* Set up the third level PTEs and update the virtual
+ addresses of the CRB entries. */
+ for (i = 0; i < crb->map_entries; ++i) {
+ unsigned long paddr = crb->map[i].pa;
+ crb->map[i].va = vaddr;
+ for (j = 0; j < crb->map[i].count; ++j) {
+ set_pte(pte_offset(pmd, vaddr),
+ mk_pte_phys(paddr, PAGE_KERNEL));
+ paddr += PAGE_SIZE;
+ vaddr += PAGE_SIZE;
+ }
+ }
+
+ /* Let vmalloc know that we've allocated some space. */
+ console_remap_vm.flags = VM_ALLOC;
+ console_remap_vm.addr = VMALLOC_START;
+ console_remap_vm.size = vaddr - VMALLOC_START;
+ vmlist = &console_remap_vm;
+ }
+
+ callback_init_done = 1;
+ return kernel_end;
+}
+
/*
* paging_init() sets up the memory map.
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)