diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /arch/alpha/lib/callback_init.c | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'arch/alpha/lib/callback_init.c')
-rw-r--r-- | arch/alpha/lib/callback_init.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/arch/alpha/lib/callback_init.c b/arch/alpha/lib/callback_init.c new file mode 100644 index 000000000..fe643ccfc --- /dev/null +++ b/arch/alpha/lib/callback_init.c @@ -0,0 +1,79 @@ +#include <linux/init.h> +#include <linux/sched.h> + +#include <asm/page.h> +#include <asm/hwrpb.h> +#include <asm/console.h> +#include <asm/pgtable.h> + +#include "../kernel/proto.h" + +extern struct hwrpb_struct *hwrpb; + +/* This is the SRM version. Maybe there will be a DBM version. */ + +int callback_init_done = 0; + +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; + unsigned long two_pte_pages; + + if (!alpha_using_srm) { + switch_to_system_map(); + return kernel_end; + } + + /* Allocate some memory for the pages. */ + two_pte_pages = ((unsigned long)kernel_end + ~PAGE_MASK) & PAGE_MASK; + kernel_end = (void *)(two_pte_pages + 2*PAGE_SIZE); + memset((void *)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 4MB. + */ + 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; +} + |