blob: 434f505a8caee7aa8ca5cb0b98aa98bf0bf7cb7b [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include "iommu_page.h"
#include <vm/pmm.h>
#include <vm/vm_aspace.h>
namespace intel_iommu {
IommuPage::IommuPage(vm_page_t* page, uintptr_t virt) : page_(page), virt_(virt) {}
IommuPage::~IommuPage() {
if (page_) {
VmAspace::kernel_aspace()->FreeRegion(reinterpret_cast<vaddr_t>(virt_));
pmm_free_page(page_);
}
}
zx_status_t IommuPage::AllocatePage(IommuPage* out) {
vm_page_t* page;
zx_status_t status = pmm_alloc_page(0, &page);
if (status != ZX_OK) {
return status;
}
page->set_state(vm_page_state::IOMMU);
void* vaddr;
auto kernel_aspace = VmAspace::kernel_aspace();
status = kernel_aspace->AllocPhysical("iommu_ctx_tbl", PAGE_SIZE, &vaddr, PAGE_SIZE_SHIFT,
page->paddr(), 0,
ARCH_MMU_FLAG_PERM_READ | ARCH_MMU_FLAG_PERM_WRITE);
if (status != ZX_OK) {
pmm_free_page(page);
return status;
}
arch_zero_page(vaddr);
*out = IommuPage(page, reinterpret_cast<uintptr_t>(vaddr));
return ZX_OK;
}
} // namespace intel_iommu