Loading...
/* * arch/alpha/lib/callback_init.c */ #include <asm/page.h> #include <asm/hwrpb.h> #include <asm/console.h> #include <asm/pgtable.h> #include <asm/init.h> #include "../kernel/proto.h" int callback_init_done = 0; /* This is the SRM version. Maybe there will be a DBM version. */ void * __init callback_init(void * kernel_end) { int i, j; unsigned long vaddr = CONSOLE_REMAP_START; struct crb_struct * crb; pgd_t * pgd = pgd_offset_k(vaddr); pmd_t * pmd; void * two_pte_pages; /* Always page align the end of the kernel. */ kernel_end = (void *) (((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK); if (!alpha_using_srm) { switch_to_system_map(); return kernel_end; } /* Allocate some memory for the pages. */ two_pte_pages = kernel_end; kernel_end = two_pte_pages + 2*PAGE_SIZE; memset(two_pte_pages, 0, 2*PAGE_SIZE); /* Starting at the HWRPB, locate the CRB. */ crb = (struct crb_struct *)((char *)hwrpb + hwrpb->crb_offset); /* Tell the console whither the console is to be remapped. */ if (srm_fixup(vaddr, (unsigned long)hwrpb)) __halt(); /* "We're boned." --Bender */ /* Edit the procedure descriptors for DISPATCH and FIXUP. */ crb->dispatch_va = (struct procdesc_struct *) (vaddr + (unsigned long)crb->dispatch_va - crb->map[0].va); crb->fixup_va = (struct procdesc_struct *) (vaddr + (unsigned long)crb->fixup_va - crb->map[0].va); switch_to_system_map(); /* * Set up the first and second level PTEs for console callbacks. * 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 3MB. */ pgd_set(pgd, (pmd_t *)two_pte_pages); pmd = pmd_offset(pgd, vaddr); pmd_set(pmd, (pte_t *)(two_pte_pages + PAGE_SIZE)); /* * 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; } } callback_init_done = 1; return kernel_end; } |