FreeBSD/sys/arm/arm/pmap-v4.c
/*
 * pmap_map_chunk:
 *
 *	Map a chunk of memory using the most efficient mappings
 *	possible (section. large page, small page) into the
 *	provided L1 and L2 tables at the specified virtual address.
 */
Map a chunk of memory using the most efficient mappings
possible (section. large page, small page) into the
provided L1 and L2 tables at the specified virtual address.
Map a chunk of memory using the most efficient mappings possible ( section . large page small page ) into the provided L1 and L2 tables at the specified virtual address .
vm_size_t
pmap_map_chunk(vm_offset_t l1pt, vm_offset_t va, vm_offset_t pa,
    vm_size_t size, int prot, int cache)
{
	pd_entry_t *pde = (pd_entry_t *) l1pt;
	pt_entry_t *pte, f1, f2s, f2l;
	vm_size_t resid;
	int i;
	resid = roundup2(size, PAGE_SIZE);
	if (l1pt == 0)
		panic("pmap_map_chunk: no L1 table provided");
#ifdef VERBOSE_INIT_ARM
	printf("pmap_map_chunk: pa=0x%x va=0x%x size=0x%x resid=0x%x "
	    "prot=0x%x cache=%d\n", pa, va, size, resid, prot, cache);
#endif
	switch (cache) {
	case PTE_NOCACHE:
	default:
		f1 = 0;
		f2l = 0;
		f2s = 0;
		break;
	case PTE_CACHE:
		f1 = pte_l1_s_cache_mode;
		f2l = pte_l2_l_cache_mode;
		f2s = pte_l2_s_cache_mode;
		break;
	case PTE_PAGETABLE:
		f1 = pte_l1_s_cache_mode_pt;
		f2l = pte_l2_l_cache_mode_pt;
		f2s = pte_l2_s_cache_mode_pt;
		break;
	}
	size = resid;
	while (resid > 0) {
		if (L1_S_MAPPABLE_P(va, pa, resid)) {
#ifdef VERBOSE_INIT_ARM
			printf("S");
#endif
			pde[va >> L1_S_SHIFT] = L1_S_PROTO | pa |
			    L1_S_PROT(PTE_KERNEL, prot) | f1 |
			    L1_S_DOM(PMAP_DOMAIN_KERNEL);
			PTE_SYNC(&pde[va >> L1_S_SHIFT]);
			va += L1_S_SIZE;
			pa += L1_S_SIZE;
			resid -= L1_S_SIZE;
			continue;
		}
		if ((pde[va >> L1_S_SHIFT] & L1_TYPE_MASK) != L1_TYPE_C)
			panic("pmap_map_chunk: no L2 table for VA 0x%08x", va);
		pte = (pt_entry_t *) kernel_pt_lookup(
		    pde[L1_IDX(va)] & L1_C_ADDR_MASK);
		if (pte == NULL)
			panic("pmap_map_chunk: can't find L2 table for VA"
			    "0x%08x", va);
		if (L2_L_MAPPABLE_P(va, pa, resid)) {
#ifdef VERBOSE_INIT_ARM
			printf("L");
#endif
			for (i = 0; i < 16; i++) {
				pte[l2pte_index(va) + i] =
				    L2_L_PROTO | pa |
				    L2_L_PROT(PTE_KERNEL, prot) | f2l;
				PTE_SYNC(&pte[l2pte_index(va) + i]);
			}
			va += L2_L_SIZE;
			pa += L2_L_SIZE;
			resid -= L2_L_SIZE;
			continue;
		}
#ifdef VERBOSE_INIT_ARM
		printf("P");
#endif
		pte[l2pte_index(va)] =
		    L2_S_PROTO | pa | L2_S_PROT(PTE_KERNEL, prot) | f2s;
		PTE_SYNC(&pte[l2pte_index(va)]);
		va += PAGE_SIZE;
		pa += PAGE_SIZE;
		resid -= PAGE_SIZE;
	}
#ifdef VERBOSE_INIT_ARM
	printf("\n");
#endif
	return (size);
}
vm_size_t pmap_map_chunk ( vm_offset_t l1pt , vm_offset_t va , vm_offset_t pa , vm_size_t size , int prot , int cache ) { pd_entry_t * pde = ( pd_entry_t * ) l1pt ; pt_entry_t * pte , f1 , f2s , f2l ; vm_size_t resid ; int i ; resid = roundup2 ( size , PAGE_SIZE ) ; if ( l1pt == 0 ) panic ( " " ) ; #ifdef VERBOSE_INIT_ARM printf ( " " " \n " , pa , va , size , resid , prot , cache ) ; #endif switch ( cache ) { case PTE_NOCACHE : default : f1 = 0 ; f2l = 0 ; f2s = 0 ; break ; case PTE_CACHE : f1 = pte_l1_s_cache_mode ; f2l = pte_l2_l_cache_mode ; f2s = pte_l2_s_cache_mode ; break ; case PTE_PAGETABLE : f1 = pte_l1_s_cache_mode_pt ; f2l = pte_l2_l_cache_mode_pt ; f2s = pte_l2_s_cache_mode_pt ; break ; } size = resid ; while ( resid > 0 ) { if ( L1_S_MAPPABLE_P ( va , pa , resid ) ) { #ifdef VERBOSE_INIT_ARM printf ( " " ) ; #endif pde [ va >> L1_S_SHIFT ] = L1_S_PROTO | pa | L1_S_PROT ( PTE_KERNEL , prot ) | f1 | L1_S_DOM ( PMAP_DOMAIN_KERNEL ) ; PTE_SYNC ( & pde [ va >> L1_S_SHIFT ] ) ; va += L1_S_SIZE ; pa += L1_S_SIZE ; resid -= L1_S_SIZE ; continue ; } if ( ( pde [ va >> L1_S_SHIFT ] & L1_TYPE_MASK ) != L1_TYPE_C ) panic ( " " , va ) ; pte = ( pt_entry_t * ) kernel_pt_lookup ( pde [ L1_IDX ( va ) ] & L1_C_ADDR_MASK ) ; if ( pte == NULL ) panic ( " " " " , va ) ; if ( L2_L_MAPPABLE_P ( va , pa , resid ) ) { #ifdef VERBOSE_INIT_ARM printf ( " " ) ; #endif for ( i = 0 ; i < 16 ; i ++ ) { pte [ l2pte_index ( va ) + i ] = L2_L_PROTO | pa | L2_L_PROT ( PTE_KERNEL , prot ) | f2l ; PTE_SYNC ( & pte [ l2pte_index ( va ) + i ] ) ; } va += L2_L_SIZE ; pa += L2_L_SIZE ; resid -= L2_L_SIZE ; continue ; } #ifdef VERBOSE_INIT_ARM printf ( " " ) ; #endif pte [ l2pte_index ( va ) ] = L2_S_PROTO | pa | L2_S_PROT ( PTE_KERNEL , prot ) | f2s ; PTE_SYNC ( & pte [ l2pte_index ( va ) ] ) ; va += PAGE_SIZE ; pa += PAGE_SIZE ; resid -= PAGE_SIZE ; } #ifdef VERBOSE_INIT_ARM printf ( " \n " ) ; #endif return ( size ) ; }
pmap_map_chunk:
      Map a chunk of memory using the most efficient mappings
      possible (section.
pmap_map_chunk : Map a chunk of memory using the most efficient mappings possible ( section .
/* See if we can use a section mapping. */ /*
		 * Ok, we're going to use an L2 table.  Make sure
		 * one is actually in the corresponding L1 slot
		 * for the current VA.
		 */ /* See if we can use a L2 large page mapping. */ /* Use a small page mapping. */