arch/m68k/sun3/mmu_emu.c

Source file repositories/reference/linux-study-clean/arch/m68k/sun3/mmu_emu.c

File Facts

System
Linux kernel
Corpus path
arch/m68k/sun3/mmu_emu.c
Extension
.c
Size
11915 bytes
Lines
428
Domain
Architecture Layer
Bucket
arch/m68k
Inferred role
Architecture Layer: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

if(!pmeg_alloc[i]) {
#ifdef DEBUG_MMU_EMU
			pr_info("freed:");
			print_pte_vaddr (seg);
#endif
			sun3_put_segmap(seg, SUN3_INVALID_PMEG);
		}
	}

	j = 0;
	for (num=0, seg=0x0F800000; seg<0x10000000; seg+=16*PAGE_SIZE) {
		if (sun3_get_segmap (seg) != SUN3_INVALID_PMEG) {
#ifdef DEBUG_PROM_MAPS
			for(i = 0; i < 16; i++) {
				pr_info("mapped:");
				print_pte_vaddr (seg + (i*PAGE_SIZE));
				break;
			}
#endif
			// the lowest mapping here is the end of our
			// vmalloc region
			if (!m68k_vmalloc_end)
				m68k_vmalloc_end = seg;

			// mark the segmap alloc'd, and reserve any
			// of the first 0xbff pages the hardware is
			// already using...  does any sun3 support > 24mb?
			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)
		sun3_put_segmap(seg, SUN3_INVALID_PMEG);

	set_fc(3);
	for(seg = 0; seg < 0x10000000; seg += SUN3_PMEG_SIZE) {
		i = sun3_get_segmap(seg);
		for(j = 1; j < CONTEXTS_NUM; j++)
			(*(romvec->pv_setctxt))(j, (void *)seg, i);
	}
	set_fc(USER_DATA);
}

/* erase the mappings for a dead context.  Uses the pg_dir for hints
   as the pmeg tables proved somewhat unreliable, and unmapping all of
   TASK_SIZE was much slower and no more stable. */
/* todo: find a better way to keep track of the pmegs used by a
   context for when they're cleared */
void clear_context(unsigned long context)
{
	unsigned char oldctx;
	unsigned long i;

	if (context) {
		if (!ctx_alloc[context])
			panic("%s: context not allocated\n", __func__);

		ctx_alloc[context]->context = SUN3_INVALID_CONTEXT;
		ctx_alloc[context] = (struct mm_struct *)0;
		ctx_avail++;
	}

	oldctx = sun3_get_context();

	sun3_put_context(context);

	for (i = 0; i < SUN3_INVALID_PMEG; i++) {
		if ((pmeg_ctx[i] == context) && (pmeg_alloc[i] == 1)) {
			sun3_put_segmap(pmeg_vaddr[i], SUN3_INVALID_PMEG);
			pmeg_ctx[i] = 0;
			pmeg_alloc[i] = 0;
			pmeg_vaddr[i] = 0;
		}
	}

	sun3_put_context(oldctx);
}

/* gets an empty context.  if full, kills the next context listed to
   die first */
/* This context invalidation scheme is, well, totally arbitrary, I'm
   sure it could be much more intelligent...  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)

Annotation

Implementation Notes