#include <linux/ptrace.h>
#include <linux/delay.h>
#include <linux/bootmem.h>
+#include <linux/bitops.h>
+#include <linux/module.h>
#include <asm/setup.h>
#include <asm/traps.h>
#include <asm/pgtable.h>
#include <asm/sun3mmu.h>
#include <asm/segment.h>
-#include <asm/bitops.h>
#include <asm/oplib.h>
#include <asm/mmu_context.h>
#include <asm/dvma.h>
*/
unsigned long vmalloc_end;
+EXPORT_SYMBOL(vmalloc_end);
+
unsigned long pmeg_vaddr[PMEGS_NUM];
unsigned char pmeg_alloc[PMEGS_NUM];
unsigned char pmeg_ctx[PMEGS_NUM];
{
unsigned long seg, num;
int i,j;
-
+
memset(rom_pages, 0, sizeof(rom_pages));
memset(pmeg_vaddr, 0, sizeof(pmeg_vaddr));
memset(pmeg_alloc, 0, sizeof(pmeg_alloc));
memset(pmeg_ctx, 0, sizeof(pmeg_ctx));
-
+
/* pmeg align the end of bootmem, adding another pmeg,
* later bootmem allocations will likely need it */
bootmem_end = (bootmem_end + (2 * SUN3_PMEG_SIZE)) & ~SUN3_PMEG_MASK;
/* liberate all existing mappings in the rest of kernel space */
for(seg = bootmem_end; seg < 0x0f800000; seg += SUN3_PMEG_SIZE) {
i = sun3_get_segmap(seg);
-
+
if(!pmeg_alloc[i]) {
#ifdef DEBUG_MMU_EMU
printk("freed: ");
pmeg_alloc[sun3_get_segmap(seg)] = 2;
}
}
-
+
dvma_init();
-
-
+
+
/* blank everything below the kernel, and we've got the base
mapping to start all the contexts off with... */
- for(seg = 0; seg < PAGE_OFFSET; seg += SUN3_PMEG_SIZE)
+ for(seg = 0; seg < PAGE_OFFSET; seg += SUN3_PMEG_SIZE)
sun3_put_segmap(seg, SUN3_INVALID_PMEG);
set_fs(MAKE_MM_SEG(3));
(*(romvec->pv_setctxt))(j, (void *)seg, i);
}
set_fs(KERNEL_DS);
-
+
}
/* erase the mappings for a dead context. Uses the pg_dir for hints
{
unsigned char oldctx;
unsigned long i;
-
+
if(context) {
- if(!ctx_alloc[context])
+ if(!ctx_alloc[context])
panic("clear_context: context not allocated\n");
ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
pmeg_vaddr[i] = 0;
}
}
-
+
sun3_put_context(oldctx);
}
sure it could be much more intellegent... but it gets the job done
for now without much overhead in making it's decision. */
/* todo: come up with optimized scheme for flushing contexts */
-unsigned long get_free_context(struct mm_struct *mm)
+unsigned long get_free_context(struct mm_struct *mm)
{
unsigned long new = 1;
static unsigned char next_to_die = 1;
break;
}
// check to make sure one was really free...
- if(new == CONTEXTS_NUM)
+ if(new == CONTEXTS_NUM)
panic("get_free_context: failed to find free context");
}
if(vaddr >= PAGE_OFFSET) {
/* map kernel pmegs into all contexts */
unsigned char i;
-
+
for(i = 0; i < CONTEXTS_NUM; i++) {
sun3_put_context(i);
sun3_put_segmap (vaddr, curr_pmeg);
sun3_put_context(context);
pmeg_alloc[curr_pmeg] = 2;
pmeg_ctx[curr_pmeg] = 0;
-
+
}
else {
pmeg_alloc[curr_pmeg] = 1;
pmeg_vaddr[curr_pmeg] = vaddr;
/* Set hardware mapping and clear the old PTE entries. */
- for (i=0; i<SUN3_PMEG_SIZE; i+=SUN3_PTE_SIZE)
+ for (i=0; i<SUN3_PMEG_SIZE; i+=SUN3_PTE_SIZE)
sun3_put_pte (vaddr + i, SUN3_PAGE_SYSTEM);
/* Consider a different one next time. */
context = 0;
} else {
context = current->mm->context;
- if(kernel_fault)
+ if(kernel_fault)
crp = swapper_pg_dir;
else
crp = current->mm->pgd;
pte = (pte_t *) __va ((unsigned long)(pte + offset));
/* Make sure this is a valid page */
- if (!(pte_val (*pte) & SUN3_PAGE_VALID))
+ if (!(pte_val (*pte) & SUN3_PAGE_VALID))
return 0;
/* Make sure there's a pmeg allocated for the page */
- if (sun3_get_segmap (vaddr&~SUN3_PMEG_MASK) == SUN3_INVALID_PMEG)
+ if (sun3_get_segmap (vaddr&~SUN3_PMEG_MASK) == SUN3_INVALID_PMEG)
mmu_emu_map_pmeg (context, vaddr);
/* Write the pte value to hardware MMU */
if (pte_val (*pte) & SUN3_PAGE_WRITEABLE)
pte_val (*pte) |= (SUN3_PAGE_ACCESSED
| SUN3_PAGE_MODIFIED);
- else
+ else
return 0; /* Write-protect error. */
} else
pte_val (*pte) |= SUN3_PAGE_ACCESSED;