diff options
author | Arve Hjønnevåg <arve@android.com> | 2016-06-08 20:41:37 -0700 |
---|---|---|
committer | Arve Hjønnevåg <arve@android.com> | 2017-09-19 16:01:17 -0700 |
commit | db32add4f851447f6f2806f6943f8c45965c4425 (patch) | |
tree | 3754fb54a50997fc0013d14813484b61ac011388 | |
parent | 21a97dff5b75c2c110b2793bc40d1c7018527776 (diff) | |
download | common-db32add4f851447f6f2806f6943f8c45965c4425.tar.gz |
[kernel][vm] Add support for mapping a page array
Change-Id: I12fed431a6281eb33f68335cb3f97c27d02c9237
-rw-r--r-- | include/kernel/vm.h | 10 | ||||
-rw-r--r-- | kernel/vm/vmm.c | 27 |
2 files changed, 28 insertions, 9 deletions
diff --git a/include/kernel/vm.h b/include/kernel/vm.h index 9925d1e9..b590b050 100644 --- a/include/kernel/vm.h +++ b/include/kernel/vm.h @@ -240,9 +240,17 @@ __NONNULL((1)); /* allocate a region of virtual space that maps a physical piece of address space. the physical pages that back this are not allocated from the pmm. */ -status_t vmm_alloc_physical(vmm_aspace_t *aspace, const char *name, size_t size, void **ptr, uint8_t align_log2, paddr_t paddr, uint vmm_flags, uint arch_mmu_flags) +status_t vmm_alloc_physical_etc(vmm_aspace_t *aspace, const char *name, size_t size, void **ptr, uint8_t align_log2, paddr_t *paddr, uint paddr_count, uint vmm_flags, uint arch_mmu_flags) __NONNULL((1)); +/* allocate a region of virtual space that maps a physical piece of address space. + the physical pages that back this are not allocated from the pmm. */ +static inline status_t vmm_alloc_physical(vmm_aspace_t *aspace, const char *name, size_t size, void **ptr, uint8_t align_log2, paddr_t paddr, uint vmm_flags, uint arch_mmu_flags) +{ + return vmm_alloc_physical_etc(aspace, name, size, ptr, align_log2, + &paddr, 1, vmm_flags, arch_mmu_flags); +} __NONNULL((1)) + /* allocate a region of memory backed by newly allocated contiguous physical memory */ status_t vmm_alloc_contiguous(vmm_aspace_t *aspace, const char *name, size_t size, void **ptr, uint8_t align_log2, uint vmm_flags, uint arch_mmu_flags) __NONNULL((1)); diff --git a/kernel/vm/vmm.c b/kernel/vm/vmm.c index 24f9b143..22a925af 100644 --- a/kernel/vm/vmm.c +++ b/kernel/vm/vmm.c @@ -349,16 +349,21 @@ status_t vmm_reserve_space(vmm_aspace_t *aspace, const char *name, size_t size, return r ? NO_ERROR : ERR_NO_MEMORY; } -status_t vmm_alloc_physical(vmm_aspace_t *aspace, const char *name, size_t size, - void **ptr, uint8_t align_log2, paddr_t paddr, uint vmm_flags, uint arch_mmu_flags) +status_t vmm_alloc_physical_etc(vmm_aspace_t *aspace, const char *name, size_t size, + void **ptr, uint8_t align_log2, paddr_t *paddr, uint paddr_count, + uint vmm_flags, uint arch_mmu_flags) { status_t ret; + uint i; + size_t page_size; - LTRACEF("aspace %p name '%s' size 0x%zx ptr %p paddr 0x%lx vmm_flags 0x%x arch_mmu_flags 0x%x\n", - aspace, name, size, ptr ? *ptr : 0, paddr, vmm_flags, arch_mmu_flags); + LTRACEF("aspace %p name '%s' size 0x%zx ptr %p paddr 0x%lx... vmm_flags 0x%x arch_mmu_flags 0x%x\n", + aspace, name, size, ptr ? *ptr : 0, paddr[0], vmm_flags, arch_mmu_flags); DEBUG_ASSERT(aspace); - DEBUG_ASSERT(IS_PAGE_ALIGNED(paddr)); + for (i = 0; i < paddr_count; i++) { + DEBUG_ASSERT(IS_PAGE_ALIGNED(paddr[i])); + } DEBUG_ASSERT(IS_PAGE_ALIGNED(size)); if (!name) @@ -368,7 +373,10 @@ status_t vmm_alloc_physical(vmm_aspace_t *aspace, const char *name, size_t size, return ERR_INVALID_ARGS; if (size == 0) return NO_ERROR; - if (!IS_PAGE_ALIGNED(paddr) || !IS_PAGE_ALIGNED(size)) + if (!paddr_count) + return ERR_INVALID_ARGS; + page_size = size / paddr_count; + if (!IS_PAGE_ALIGNED(paddr[0]) || !IS_PAGE_ALIGNED(page_size)) return ERR_INVALID_ARGS; vaddr_t vaddr = 0; @@ -397,8 +405,11 @@ status_t vmm_alloc_physical(vmm_aspace_t *aspace, const char *name, size_t size, *ptr = (void *)r->base; /* map all of the pages */ - int err = arch_mmu_map(&aspace->arch_aspace, r->base, paddr, size / PAGE_SIZE, arch_mmu_flags); - LTRACEF("arch_mmu_map returns %d\n", err); + for (i = 0; i < paddr_count; i++) { + int err = arch_mmu_map(&aspace->arch_aspace, r->base + i * page_size, + paddr[i], page_size / PAGE_SIZE, arch_mmu_flags); + LTRACEF("arch_mmu_map returns %d\n", err); + } ret = NO_ERROR; |