aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArve Hjønnevåg <arve@android.com>2016-06-08 20:41:37 -0700
committerArve Hjønnevåg <arve@android.com>2017-09-19 16:01:17 -0700
commitdb32add4f851447f6f2806f6943f8c45965c4425 (patch)
tree3754fb54a50997fc0013d14813484b61ac011388
parent21a97dff5b75c2c110b2793bc40d1c7018527776 (diff)
downloadcommon-db32add4f851447f6f2806f6943f8c45965c4425.tar.gz
[kernel][vm] Add support for mapping a page array
Change-Id: I12fed431a6281eb33f68335cb3f97c27d02c9237
-rw-r--r--include/kernel/vm.h10
-rw-r--r--kernel/vm/vmm.c27
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;