Example #1
0
void
as_destroy(struct addrspace *as)
{
	pt_destroy(as->as_pgtbl);
#if OPT_ASID
    tlb_flush_asid(as->as_id);
#endif
	kfree(as);
}
Example #2
0
// NIY: think about real int safe
static void 
alloc_asid(ADDRESS *adp) {
	static int	asid_rotor = 1;
	int 		asid, i;
	ADDRESS		*oldadp;

	/*
	 * Be very, very careful in here. We can be allocating an asid for
	 * somebody and have an interrupt go off. If the interrupt has a
	 * handler routine, we will re-enterantly execute this code to set up
	 * the address space for the routine.
	 */

	/*
	 * Do a quick scan through the asid_map and see 
	 * if there are any unallocated entries. The
	 * reason why we do this is because it is cheaper 
	 * to do this one scan than to steal an asid,
	 * do a MemPageFlushAsid, and also possibly incur
	 * tlb refills for the poor guy we stole from.
	 * If there are no unallocated asids, then go 
	 * back to where we were in the asid_map.
	 */
	// asid 0 is reserved for system address space
	for(i = 1; i <= VM_ASID_BOUNDARY; ++i) {
		if(asid_map[i] == NULL) {
			asid_map[i] = adp;
			adp->cpu.asid = i;
#ifdef	VARIANT_smp
			/*
			 * Indicate ASID needs purging on all cpus
			 */
			atomic_set(&adp->cpu.asid_flush, LEGAL_CPU_BITMASK);
#endif
			return; 
		}
	}
	/* have to steal one */
	asid = asid_rotor;
	if(++asid_rotor > VM_ASID_BOUNDARY) {
		asid_rotor = 1;
	}
	adp->cpu.asid = asid;
#ifdef	VARIANT_smp
	/*
	 * Indicate ASID needs purging on all cpus
	 */
	atomic_set(&adp->cpu.asid_flush, LEGAL_CPU_BITMASK);
#endif
	oldadp = asid_map[asid];
	asid_map[asid] = adp;
	if(oldadp != NULL) {
		/* 
		 * Mark his asid as invalid so
		 * that when we switch to him he'll
		 * pick up another one.
		 */
		oldadp->cpu.asid = ~0;
#ifdef	VARIANT_smp
		/*
		 * We will flush the asid in vmm_aspace
		 */
#else
		tlb_flush_asid(asid);
#endif
	}
}