1 // Copyright 2018 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6
7 #include <dev/address_provider/ecam_region.h>
8 #include <dev/pci_common.h>
9 #include <vm/vm_aspace.h>
10
~MappedEcamRegion()11 MappedEcamRegion::~MappedEcamRegion() {
12 if (vaddr_ != nullptr) {
13 VmAspace::kernel_aspace()->FreeRegion(reinterpret_cast<vaddr_t>(vaddr_));
14 }
15 }
16
MapEcam()17 zx_status_t MappedEcamRegion::MapEcam() {
18 DEBUG_ASSERT(ecam_.bus_start <= ecam_.bus_end);
19
20 // TODO(gkalsi): These asserts are helpful but they don't apply for the DWC
21 // since the ECAM is broken up and mapped in different places.
22 // We should find a way to enforce these only for MMIO ECAMs
23 // DEBUG_ASSERT((ecam_.size % PCIE_ECAM_BYTE_PER_BUS) == 0);
24 // DEBUG_ASSERT((ecam_.size / PCIE_ECAM_BYTE_PER_BUS) ==
25 // (static_cast<size_t>(ecam_.bus_end) - ecam_.bus_start + 1u));
26
27 if (vaddr_ != nullptr) {
28 return ZX_ERR_BAD_STATE;
29 }
30
31 char name_buf[32];
32 snprintf(name_buf, sizeof(name_buf), "pcie_cfg_%02x_%02x",
33 ecam_.bus_start, ecam_.bus_end);
34
35 return VmAspace::kernel_aspace()->AllocPhysical(
36 name_buf,
37 ecam_.size,
38 &vaddr_,
39 PAGE_SIZE_SHIFT,
40 ecam_.phys_base,
41 0 /* vmm flags */,
42 ARCH_MMU_FLAG_UNCACHED_DEVICE |
43 ARCH_MMU_FLAG_PERM_READ |
44 ARCH_MMU_FLAG_PERM_WRITE);
45 }
46