FreeBSD/sys/i386/i386/pmap.c
/*
 * Map a set of physical memory pages into the kernel virtual
 * address space. Return a pointer to where it is mapped. This
 * routine is intended to be used for mapping device memory,
 * NOT real memory.
 */
Map a set of physical memory pages into the kernel virtual
address space. Return a pointer to where it is mapped. This
routine is intended to be used for mapping device memory,
NOT real memory.
Map a set of physical memory pages into the kernel virtual address space . Return a pointer to where it is mapped . This routine is intended to be used for mapping device memory NOT real memory .
void *
pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
{
	struct pmap_preinit_mapping *ppim;
	vm_offset_t va, offset;
	vm_size_t tmpsize;
	int i;
	offset = pa & PAGE_MASK;
	size = round_page(offset + size);
	pa = pa & PG_FRAME;
	if (pa < KERNLOAD && pa + size <= KERNLOAD)
		va = KERNBASE + pa;
	else if (!pmap_initialized) {
		va = 0;
		for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) {
			ppim = pmap_preinit_mapping + i;
			if (ppim->va == 0) {
				ppim->pa = pa;
				ppim->sz = size;
				ppim->mode = mode;
				ppim->va = virtual_avail;
				virtual_avail += size;
				va = ppim->va;
				break;
			}
		}
		if (va == 0)
			panic("%s: too many preinit mappings", __func__);
	} else {
		for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) {
			ppim = pmap_preinit_mapping + i;
			if (ppim->pa == pa && ppim->sz == size &&
			    ppim->mode == mode)
				return ((void *)(ppim->va + offset));
		}
		va = kva_alloc(size);
		if (va == 0)
			panic("%s: Couldn't allocate KVA", __func__);
	}
	for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE)
		pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode);
	pmap_invalidate_range(kernel_pmap, va, va + tmpsize);
	pmap_invalidate_cache_range(va, va + size, FALSE);
	return ((void *)(va + offset));
}
void * pmap_mapdev_attr ( vm_paddr_t pa , vm_size_t size , int mode ) { struct pmap_preinit_mapping * ppim ; vm_offset_t va , offset ; vm_size_t tmpsize ; int i ; offset = pa & PAGE_MASK ; size = round_page ( offset + size ) ; pa = pa & PG_FRAME ; if ( pa < KERNLOAD && pa + size <= KERNLOAD ) va = KERNBASE + pa ; else if ( ! pmap_initialized ) { va = 0 ; for ( i = 0 ; i < PMAP_PREINIT_MAPPING_COUNT ; i ++ ) { ppim = pmap_preinit_mapping + i ; if ( ppim -> va == 0 ) { ppim -> pa = pa ; ppim -> sz = size ; ppim -> mode = mode ; ppim -> va = virtual_avail ; virtual_avail += size ; va = ppim -> va ; break ; } } if ( va == 0 ) panic ( " " , __func__ ) ; } else { for ( i = 0 ; i < PMAP_PREINIT_MAPPING_COUNT ; i ++ ) { ppim = pmap_preinit_mapping + i ; if ( ppim -> pa == pa && ppim -> sz == size && ppim -> mode == mode ) return ( ( void * ) ( ppim -> va + offset ) ) ; } va = kva_alloc ( size ) ; if ( va == 0 ) panic ( " " , __func__ ) ; } for ( tmpsize = 0 ; tmpsize < size ; tmpsize += PAGE_SIZE ) pmap_kenter_attr ( va + tmpsize , pa + tmpsize , mode ) ; pmap_invalidate_range ( kernel_pmap , va , va + tmpsize ) ; pmap_invalidate_cache_range ( va , va + size , FALSE ) ; return ( ( void * ) ( va + offset ) ) ; }
Map a set of physical memory pages into the kernel virtual
 address space.
Map a set of physical memory pages into the kernel virtual address space .
/*
		 * If we have a preinit mapping, re-use it.
		 */