/** @file Copyright (c) 2018, Linaro, Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ /* * This file contains the assembler code to instantiate a set of stage 2 * translation tables that make the ECAM space of the Synopsys DesignWare * PCIe root complexes appear sane to the OS. * - ECAM 'shadows' caused by non TLP filtering root ports are eliminated * - MMIO region are mapped with device attributes that supersede write combine * attributes that the OS may attempt to use, and which is not supported by * the SoC. */ #define TT_S2_CONT_SHIFT 52 #define TT_S2_AF (0x1 << 10) #define TT_S2_SH_NON_SHAREABLE (0x0 << 8) #define TT_S2_AP_RO (0x1 << 6) #define TT_S2_AP_RW (0x3 << 6) #define TT_S2_MEMATTR_DEVICE_nGRE (0x2 << 2) #define TT_S2_MEMATTR_DEVICE_nGnRE (0x1 << 2) #define TT_S2_MEMATTR_MEMORY_WB (0xf << 2) #define TT_S2_TABLE (0x3 << 0) #define TT_S2_L3_PAGE (0x1 << 1) #define TT_S2_VALID (0x1 << 0) #ifdef __aarch64__ #define QWORD(x) .quad (x) #else #define QWORD(x) .long (x), 0 #endif .altmacro .macro for, start, count, do, arg2, arg3, arg4 .if \count == 1 \do \start, \arg2, \arg3, \arg4 .elseif \count > 1 for \start, %(\count / 2), \do, \arg2, \arg3, \arg4 for %(\start + \count / 2), %((\count + 1) / 2), \do, \arg2, \arg3, \arg4 .endif .endm .macro s2_dev_entry, base, shift=30, offset=0, cont=0 .quad ((\base << \shift) + \offset) | TT_S2_AF | TT_S2_AP_RW | \ TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_DEVICE_nGRE | \ TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT) .endm .macro s2_mem_entry, base, shift=30, offset=0, cont=0 .quad ((\base << \shift) + \offset) | TT_S2_AF | TT_S2_AP_RW | \ TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_MEMORY_WB | \ TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT) .endm .macro s2_l3_entry, base, offset=0, cont=0 .quad ((\base << 12) + \offset) | TT_S2_AF | TT_S2_AP_RW | \ TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_MEMORY_WB | \ TT_S2_L3_PAGE | TT_S2_VALID | (\cont << TT_S2_CONT_SHIFT) .endm .macro smmu_l3_entry, base, offset=0, ignore=0 .quad ((\base << 12) + \offset) | TT_S2_AF | TT_S2_AP_RO | \ TT_S2_SH_NON_SHAREABLE | TT_S2_MEMATTR_DEVICE_nGnRE | \ TT_S2_L3_PAGE | TT_S2_VALID .endm .section ".rodata", "a", %progbits /* level 1 */ s2_mem_entry 0 /* 0x0000_0000 - 0x3fff_ffff */ QWORD (1f + TT_S2_TABLE) /* 0x4000_0000 - 0x7fff_ffff */ for 2, 246, s2_mem_entry /* 0x8000_0000 - 0x3d_ffff_ffff */ for 248, 8, s2_dev_entry /* PCIe MMIO64 */ for 256, 768, s2_mem_entry /* 0x40_0000_0000 - 0xff_ffff_ffff */ /* level 2 */ 1:for 0, 256, s2_mem_entry, 21, 0x40000000, 1 QWORD (2f + TT_S2_TABLE) /* 0x6000_0000 -> RC #0 bus 0 */ for 1, 15, s2_mem_entry, 21, 0x60000000 for 0, 48, s2_mem_entry, 21, 0x62000000, 1 for 0, 64, s2_dev_entry, 21, 0x68000000, 1 /* PCIe MMIO32 */ QWORD (3f + TT_S2_TABLE) /* 0x7000_0000 -> RC #1 bus 0 */ for 1, 15, s2_mem_entry, 21, 0x70000000 for 0, 48, s2_mem_entry, 21, 0x72000000, 1 for 0, 64, s2_dev_entry, 21, 0x78000000, 1 /* PCIe MMIO32 */ /* level 3 */ 2:for 0, 8, s2_l3_entry, 0x60000000 for 0, 8, s2_l3_entry, 0x60010000 /* hide device #1 */ for 0, 496, s2_l3_entry, 0x60010000, 1 3:for 0, 8, s2_l3_entry, 0x70000000 for 0, 8, s2_l3_entry, 0x70010000 /* hide device #1 */ for 0, 496, s2_l3_entry, 0x70010000, 1 /* level 3 for north SMMU */ .org 0x6000 for 0, 8, smmu_l3_entry, 0xc00060000000 for 0, 8, smmu_l3_entry, 0xc00060010000 /* hide device #1 */ for 0, 496, smmu_l3_entry, 0xc00060010000 for 0, 8, smmu_l3_entry, 0x800070000000 for 0, 8, smmu_l3_entry, 0x800070010000 /* hide device #1 */ for 0, 496, smmu_l3_entry, 0x800070010000