| 5869 | } |
| 5870 | |
| 5871 | void * |
| 5872 | pmap_mapbios(vm_paddr_t pa, vm_size_t size) |
| 5873 | { |
| 5874 | struct pmap_preinit_mapping *ppim; |
| 5875 | vm_offset_t va, offset; |
| 5876 | pd_entry_t *pde; |
| 5877 | pt_entry_t *l2; |
| 5878 | int i, lvl, l2_blocks, free_l2_count, start_idx; |
| 5879 | |
| 5880 | if (!vm_initialized) { |
| 5881 | /* |
| 5882 | * No L3 ptables so map entire L2 blocks where start VA is: |
| 5883 | * preinit_map_va + start_idx * L2_SIZE |
| 5884 | * There may be duplicate mappings (multiple VA -> same PA) but |
| 5885 | * ARM64 dcache is always PIPT so that's acceptable. |
| 5886 | */ |
| 5887 | if (size == 0) |
| 5888 | return (NULL); |
| 5889 | |
| 5890 | /* Calculate how many L2 blocks are needed for the mapping */ |
| 5891 | l2_blocks = (roundup2(pa + size, L2_SIZE) - |
| 5892 | rounddown2(pa, L2_SIZE)) >> L2_SHIFT; |
| 5893 | |
| 5894 | offset = pa & L2_OFFSET; |
| 5895 | |
| 5896 | if (preinit_map_va == 0) |
| 5897 | return (NULL); |
| 5898 | |
| 5899 | /* Map 2MiB L2 blocks from reserved VA space */ |
| 5900 | |
| 5901 | free_l2_count = 0; |
| 5902 | start_idx = -1; |
| 5903 | /* Find enough free contiguous VA space */ |
| 5904 | for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { |
| 5905 | ppim = pmap_preinit_mapping + i; |
| 5906 | if (free_l2_count > 0 && ppim->pa != 0) { |
| 5907 | /* Not enough space here */ |
| 5908 | free_l2_count = 0; |
| 5909 | start_idx = -1; |
| 5910 | continue; |
| 5911 | } |
| 5912 | |
| 5913 | if (ppim->pa == 0) { |
| 5914 | /* Free L2 block */ |
| 5915 | if (start_idx == -1) |
| 5916 | start_idx = i; |
| 5917 | free_l2_count++; |
| 5918 | if (free_l2_count == l2_blocks) |
| 5919 | break; |
| 5920 | } |
| 5921 | } |
| 5922 | if (free_l2_count != l2_blocks) |
| 5923 | panic("%s: too many preinit mappings", __func__); |
| 5924 | |
| 5925 | va = preinit_map_va + (start_idx * L2_SIZE); |
| 5926 | for (i = start_idx; i < start_idx + l2_blocks; i++) { |
| 5927 | /* Mark entries as allocated */ |
| 5928 | ppim = pmap_preinit_mapping + i; |
no test coverage detected