blob: de8b995dbf05eb642fc968cb0f58a5a92776e32b [file] [log] [blame]
/*
* Copyright (c) 2017 - 2020, Broadcom
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <arch_helpers.h>
#include <common/debug.h>
#include <drivers/delay_timer.h>
#include <lib/mmio.h>
#include <iommu.h>
#include <platform_def.h>
#define SMMU_BASE 0x64000000
#define ARM_SMMU_MAX_NUM_CNTXT_BANK 64
#define SMMU_CTX_BANK_IDX_SECURE_CRMU 63
#define ARM_SMMU_NUM_SECURE_MASTER 1
#define ARM_SMMU_NSNUMCBO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
ARM_SMMU_NUM_SECURE_MASTER)
#define ARM_SMMU_NSNUMSMRGO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
ARM_SMMU_NUM_SECURE_MASTER)
/* Reserved Banks. */
#define SMMU_CTX_BANK_IDX (SMMU_CTX_BANK_IDX_SECURE_CRMU - \
ARM_SMMU_NUM_SECURE_MASTER)
#define NUM_OF_SMRS 1
#define STG1_WITH_STG2_BYPASS 1
#define ARM_LPAE_PGTBL_PHYS_CRMU 0x880000000
#define ARM_LPAE_PGTBL_PHYS 0x880200000
#define ARM_LPAE_PGTBL_PTE_CNT 512
#define ARM_LPAE_PTE_L1_BLOCK_SIZE 0x40000000
#define ARM_LPAE_PTE_L1_ADDR_MASK 0x0000FFFFC0000000UL
#define ARM_LPAE_PTE_TABLE 0x2UL
#define ARM_LPAE_PTE_VALID 0x1UL
#define ARM_LPAE_PTE_ATTRINDX 2
#define ARM_LPAE_PTE_NS 5
#define ARM_LPAE_PTE_AP 6
#define ARM_LPAE_PTE_AP_EL1_RW 0x0
#define ARM_LPAE_PTE_AP_EL0_RW 0x1
#define ARM_LPAE_PTE_SH 8
#define ARM_LPAE_PTE_SH_NON 0x0
#define ARM_LPAE_PTE_SH_OUTER 0x2
#define ARM_LPAE_PTE_SH_INNER 0x3
#define ARM_LPAE_PTE_AF 10
#define ARM_SMMU_RES_SIZE 0x80000
#define ARM_LPAE_PTE_NSTABLE 0x8000000000000000UL
#define ARM_LPAE_PTE_L1_INDEX_SHIFT 30
#define ARM_LPAE_PTE_L1_INDEX_MASK 0x1ff
#define ARM_LPAE_PTE_L0_INDEX_SHIFT 39
#define ARM_LPAE_PTE_L0_INDEX_MASK 0x1ff
#define ARM_LPAE_PTE_TABLE_MASK ~(0xfffUL)
/* Configuration registers */
#define ARM_SMMU_GR0_sCR0 0x0
#define sCR0_CLIENTPD (1 << 0)
#define sCR0_GFRE (1 << 1)
#define sCR0_GFIE (1 << 2)
#define sCR0_GCFGFRE (1 << 4)
#define sCR0_GCFGFIE (1 << 5)
#define sCR0_USFCFG (1 << 10)
#define sCR0_VMIDPNE (1 << 11)
#define sCR0_PTM (1 << 12)
#define sCR0_FB (1 << 13)
#define sCR0_VMID16EN (1 << 31)
#define sCR0_BSU_SHIFT 14
#define sCR0_BSU_MASK 0x3
#define ARM_SMMU_SMMU_SCR1 0x4
#define SCR1_NSNUMCBO_MASK 0xFF
#define SCR1_NSNUMCBO_SHIFT 0x0
#define SCR1_NSNUMSMRGO_MASK 0xFF00
#define SCR1_NSNUMSMRGO_SHIFT 0x8
/* Identification registers */
#define ARM_SMMU_GR0_ID0 0x20
#define ARM_SMMU_GR0_ID1 0x24
#define ARM_SMMU_GR0_ID2 0x28
#define ARM_SMMU_GR0_ID3 0x2c
#define ARM_SMMU_GR0_ID4 0x30
#define ARM_SMMU_GR0_ID5 0x34
#define ARM_SMMU_GR0_ID6 0x38
#define ARM_SMMU_GR0_ID7 0x3c
#define ARM_SMMU_GR0_sGFSR 0x48
#define ARM_SMMU_GR0_sGFSYNR0 0x50
#define ARM_SMMU_GR0_sGFSYNR1 0x54
#define ARM_SMMU_GR0_sGFSYNR2 0x58
#define ID1_PAGESIZE (1U << 31)
#define ID1_NUMPAGENDXB_SHIFT 28
#define ID1_NUMPAGENDXB_MASK 7
#define ID1_NUMS2CB_SHIFT 16
#define ID1_NUMS2CB_MASK 0xff
#define ID1_NUMCB_SHIFT 0
#define ID1_NUMCB_MASK 0xff
/* SMMU global address space */
#define ARM_SMMU_GR0(smmu) ((smmu)->base)
#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
/* Stream mapping registers */
#define ARM_SMMU_GR0_SMR(n) (0x800 + (n << 2))
#define SMR_VALID (1U << 31)
#define SMR_MASK_SHIFT 16
#define SMR_ID_SHIFT 0
#define ARM_SMMU_GR0_S2CR(n) (0xc00 + (n << 2))
#define S2CR_CBNDX_SHIFT 0
#define S2CR_CBNDX_MASK 0xff
#define S2CR_TYPE_SHIFT 16
#define S2CR_TYPE_MASK 0x3
#define ARM_SMMU_GR1_CBA2R(n) (0x800 + (n << 2))
#define CBA2R_RW64_32BIT (0 << 0)
#define CBA2R_RW64_64BIT (1 << 0)
#define CBA2R_VMID_SHIFT 16
#define CBA2R_VMID_MASK 0xffff
#define ARM_SMMU_GR1_CBAR(n) (0x0 + (n << 2))
#define CBAR_VMID_SHIFT 0
#define CBAR_VMID_MASK 0xff
#define CBAR_S1_BPSHCFG_SHIFT 8
#define CBAR_S1_BPSHCFG_MASK 3
#define CBAR_S1_BPSHCFG_NSH 3
#define CBAR_S1_MEMATTR_SHIFT 12
#define CBAR_S1_MEMATTR_MASK 0xf
#define CBAR_S1_MEMATTR_WB 0xf
#define CBAR_TYPE_SHIFT 16
#define CBAR_TYPE_MASK 0x3
#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT)
#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT)
#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT)
#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT)
#define CBAR_IRPTNDX_SHIFT 24
#define CBAR_IRPTNDX_MASK 0xff
/* Translation context bank */
#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift))
#define ARM_SMMU_CB_SCTLR 0x0
#define ARM_SMMU_CB_ACTLR 0x4
#define ARM_SMMU_CB_RESUME 0x8
#define ARM_SMMU_CB_TTBCR2 0x10
#define ARM_SMMU_CB_TTBR0 0x20
#define ARM_SMMU_CB_TTBR1 0x28
#define ARM_SMMU_CB_TTBCR 0x30
#define ARM_SMMU_CB_CONTEXTIDR 0x34
#define ARM_SMMU_CB_S1_MAIR0 0x38
#define ARM_SMMU_CB_S1_MAIR1 0x3c
#define ARM_SMMU_CB_PAR 0x50
#define ARM_SMMU_CB_FSR 0x58
#define ARM_SMMU_CB_FAR 0x60
#define ARM_SMMU_CB_FSYNR0 0x68
#define ARM_SMMU_CB_S1_TLBIVA 0x600
#define ARM_SMMU_CB_S1_TLBIASID 0x610
#define ARM_SMMU_CB_S1_TLBIVAL 0x620
#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630
#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638
#define ARM_SMMU_CB_ATS1PR 0x800
#define ARM_SMMU_CB_ATSR 0x8f0
#define SCTLR_S1_ASIDPNE (1 << 12)
#define SCTLR_CFCFG (1 << 7)
#define SCTLR_CFIE (1 << 6)
#define SCTLR_CFRE (1 << 5)
#define SCTLR_E (1 << 4)
#define SCTLR_AFE (1 << 2)
#define SCTLR_TRE (1 << 1)
#define SCTLR_M (1 << 0)
/* ARM LPAE configuration. */
/**************************************************************/
/* Register bits */
#define ARM_32_LPAE_TCR_EAE (1 << 31)
#define ARM_64_LPAE_S2_TCR_RES1 (1 << 31)
#define ARM_LPAE_TCR_EPD1 (1 << 23)
#define ARM_LPAE_TCR_TG0_4K (0 << 14)
#define ARM_LPAE_TCR_TG0_64K (1 << 14)
#define ARM_LPAE_TCR_TG0_16K (2 << 14)
#define ARM_LPAE_TCR_SH0_SHIFT 12
#define ARM_LPAE_TCR_SH0_MASK 0x3
#define ARM_LPAE_TCR_SH_NS 0
#define ARM_LPAE_TCR_SH_OS 2
#define ARM_LPAE_TCR_SH_IS 3
#define ARM_LPAE_TCR_ORGN0_SHIFT 10
#define ARM_LPAE_TCR_IRGN0_SHIFT 8
#define ARM_LPAE_TCR_RGN_MASK 0x3
#define ARM_LPAE_TCR_RGN_NC 0
#define ARM_LPAE_TCR_RGN_WBWA 1
#define ARM_LPAE_TCR_RGN_WT 2
#define ARM_LPAE_TCR_RGN_WB 3
#define ARM_LPAE_TCR_SL0_SHIFT 6
#define ARM_LPAE_TCR_SL0_MASK 0x3
#define ARM_LPAE_TCR_T0SZ_SHIFT 0
#define ARM_LPAE_TCR_SZ_MASK 0xf
#define ARM_LPAE_TCR_PS_SHIFT 16
#define ARM_LPAE_TCR_PS_MASK 0x7
#define ARM_LPAE_TCR_IPS_SHIFT 32
#define ARM_LPAE_TCR_IPS_MASK 0x7
#define ARM_LPAE_TCR_PS_32_BIT 0x0ULL
#define ARM_LPAE_TCR_PS_36_BIT 0x1ULL
#define ARM_LPAE_TCR_PS_40_BIT 0x2ULL
#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL
#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL
#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL
#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3)
#define ARM_LPAE_MAIR_ATTR_MASK 0xff
#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04
#define ARM_LPAE_MAIR_ATTR_NC 0x44
#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff
#define ARM_LPAE_MAIR_ATTR_IDX_NC 0
#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1
#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2
#define TTBRn_ASID_SHIFT 48
#define TTBCR2_SEP_SHIFT 15
#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)
#define TTBCR2_AS (1 << 4)
#define TTBCR_T0SZ(ia_bits) (64 - (ia_bits))
#define S2CR_PRIVCFG_SHIFT 24
#define S2CR_PRIVCFG_MASK 0x3
/**************************************************************/
uint16_t paxc_stream_ids[] = { 0x2000 };
uint16_t paxc_stream_ids_mask[] = { 0x1fff };
uint16_t crmu_stream_ids[] = { CRMU_STREAM_ID };
uint16_t crmu_stream_ids_mask[] = { 0x0 };
enum arm_smmu_s2cr_type {
S2CR_TYPE_TRANS,
S2CR_TYPE_BYPASS,
S2CR_TYPE_FAULT,
};
enum arm_smmu_s2cr_privcfg {
S2CR_PRIVCFG_DEFAULT,
S2CR_PRIVCFG_DIPAN,
S2CR_PRIVCFG_UNPRIV,
S2CR_PRIVCFG_PRIV,
};
struct arm_smmu_smr {
uint16_t mask;
uint16_t id;
uint32_t valid;
};
struct arm_smmu_s2cr {
int count;
enum arm_smmu_s2cr_type type;
enum arm_smmu_s2cr_privcfg privcfg;
uint8_t cbndx;
};
struct arm_smmu_cfg {
uint8_t cbndx;
uint8_t irptndx;
uint32_t cbar;
};
struct arm_smmu_device {
uint8_t *base;
uint32_t streams;
unsigned long size;
unsigned long pgshift;
unsigned long va_size;
unsigned long ipa_size;
unsigned long pa_size;
struct arm_smmu_smr smr[NUM_OF_SMRS];
struct arm_smmu_s2cr s2cr[NUM_OF_SMRS];
struct arm_smmu_cfg cfg[NUM_OF_SMRS];
uint16_t *stream_ids;
uint16_t *stream_ids_mask;
};
void arm_smmu_enable_secure_client_port(void)
{
uintptr_t smmu_base = SMMU_BASE;
mmio_clrbits_32(smmu_base, sCR0_CLIENTPD);
}
void arm_smmu_reserve_secure_cntxt(void)
{
uintptr_t smmu_base = SMMU_BASE;
mmio_clrsetbits_32(smmu_base + ARM_SMMU_SMMU_SCR1,
(SCR1_NSNUMSMRGO_MASK | SCR1_NSNUMCBO_MASK),
((ARM_SMMU_NSNUMCBO << SCR1_NSNUMCBO_SHIFT) |
(ARM_SMMU_NSNUMSMRGO << SCR1_NSNUMSMRGO_SHIFT)));
}
static void arm_smmu_smr_cfg(struct arm_smmu_device *smmu, uint32_t index)
{
uint32_t idx = smmu->cfg[index].cbndx;
struct arm_smmu_smr *smr = &smmu->smr[index];
uint32_t reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
if (smr->valid)
reg |= SMR_VALID;
mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
ARM_SMMU_GR0_SMR(idx)), reg);
}
static void arm_smmu_s2cr_cfg(struct arm_smmu_device *smmu, uint32_t index)
{
uint32_t idx = smmu->cfg[index].cbndx;
struct arm_smmu_s2cr *s2cr = &smmu->s2cr[index];
uint32_t reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
(s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
(s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
ARM_SMMU_GR0_S2CR(idx)), reg);
}
static void smmu_set_pgtbl(struct arm_smmu_device *smmu,
enum iommu_domain dom,
uint64_t *pg_table_base)
{
int i, l0_index, l1_index;
uint64_t addr, *pte, *l0_base, *l1_base;
uint64_t addr_space_limit;
if (dom == PCIE_PAXC) {
addr_space_limit = 0xffffffffff;
} else if (dom == DOMAIN_CRMU) {
addr_space_limit = 0xffffffff;
} else {
ERROR("dom is not supported\n");
return;
}
l0_base = pg_table_base;
/* clear L0 descriptors. */
for (i = 0; i < ARM_LPAE_PGTBL_PTE_CNT; i++)
l0_base[i] = 0x0;
addr = 0x0;
while (addr < addr_space_limit) {
/* find L0 pte */
l0_index = ((addr >> ARM_LPAE_PTE_L0_INDEX_SHIFT) &
ARM_LPAE_PTE_L0_INDEX_MASK);
l1_base = l0_base + ((l0_index + 1) * ARM_LPAE_PGTBL_PTE_CNT);
/* setup L0 pte if required */
pte = l0_base + l0_index;
if (*pte == 0x0) {
*pte |= ((uint64_t)l1_base & ARM_LPAE_PTE_TABLE_MASK);
if (dom == PCIE_PAXC)
*pte |= ARM_LPAE_PTE_NSTABLE;
*pte |= ARM_LPAE_PTE_TABLE;
*pte |= ARM_LPAE_PTE_VALID;
}
/* find L1 pte */
l1_index = ((addr >> ARM_LPAE_PTE_L1_INDEX_SHIFT) &
ARM_LPAE_PTE_L1_INDEX_MASK);
pte = l1_base + l1_index;
/* setup L1 pte */
*pte = 0x0;
*pte |= (addr & ARM_LPAE_PTE_L1_ADDR_MASK);
if (addr < 0x80000000) {
*pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV <<
ARM_LPAE_PTE_ATTRINDX);
if (dom == PCIE_PAXC)
*pte |= (1 << ARM_LPAE_PTE_NS);
} else {
*pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<
ARM_LPAE_PTE_ATTRINDX);
*pte |= (1 << ARM_LPAE_PTE_NS);
}
*pte |= (ARM_LPAE_PTE_AP_EL0_RW << ARM_LPAE_PTE_AP);
*pte |= (ARM_LPAE_PTE_SH_INNER << ARM_LPAE_PTE_SH);
*pte |= (1 << ARM_LPAE_PTE_AF);
*pte |= ARM_LPAE_PTE_VALID;
addr += ARM_LPAE_PTE_L1_BLOCK_SIZE;
}
}
void arm_smmu_create_identity_map(enum iommu_domain dom)
{
struct arm_smmu_device iommu;
struct arm_smmu_device *smmu = &iommu;
uint32_t reg, reg2;
unsigned long long reg64;
uint32_t idx;
uint16_t asid;
unsigned int context_bank_index;
unsigned long long pg_table_base;
smmu->base = (uint8_t *) SMMU_BASE;
reg = mmio_read_32((uintptr_t) (ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_ID1));
smmu->pgshift = (reg & ID1_PAGESIZE) ? 16 : 12;
smmu->size = ARM_SMMU_RES_SIZE;
smmu->stream_ids = NULL;
switch (dom) {
case PCIE_PAXC:
smmu->stream_ids = &paxc_stream_ids[0];
smmu->stream_ids_mask = &paxc_stream_ids_mask[0];
smmu->streams = ARRAY_SIZE(paxc_stream_ids);
context_bank_index = SMMU_CTX_BANK_IDX;
pg_table_base = ARM_LPAE_PGTBL_PHYS;
break;
case DOMAIN_CRMU:
smmu->stream_ids = &crmu_stream_ids[0];
smmu->stream_ids_mask = &crmu_stream_ids_mask[0];
smmu->streams = ARRAY_SIZE(crmu_stream_ids);
context_bank_index = SMMU_CTX_BANK_IDX_SECURE_CRMU;
pg_table_base = ARM_LPAE_PGTBL_PHYS_CRMU;
break;
default:
ERROR("domain not supported\n");
return;
}
if (smmu->streams > NUM_OF_SMRS) {
INFO("can not support more than %d sids\n", NUM_OF_SMRS);
return;
}
/* set up iommu dev. */
for (idx = 0; idx < smmu->streams; idx++) {
/* S2CR. */
smmu->s2cr[idx].type = S2CR_TYPE_TRANS;
smmu->s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT;
smmu->s2cr[idx].cbndx = context_bank_index;
smmu->cfg[idx].cbndx = context_bank_index;
smmu->cfg[idx].cbar = STG1_WITH_STG2_BYPASS << CBAR_TYPE_SHIFT;
arm_smmu_s2cr_cfg(smmu, idx);
/* SMR. */
smmu->smr[idx].mask = smmu->stream_ids_mask[idx];
smmu->smr[idx].id = smmu->stream_ids[idx];
smmu->smr[idx].valid = 1;
arm_smmu_smr_cfg(smmu, idx);
/* CBA2R. 64-bit Translation */
mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
ARM_SMMU_GR1_CBA2R(smmu->cfg[idx].cbndx)),
0x1);
/* CBAR.*/
reg = smmu->cfg[idx].cbar;
reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
(CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
ARM_SMMU_GR1_CBAR(smmu->cfg[idx].cbndx)),
reg);
/* TTBCR. */
reg64 = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
(ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
reg64 |= ARM_LPAE_TCR_TG0_4K;
reg64 |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT);
/* ias 40 bits.*/
reg64 |= TTBCR_T0SZ(40) << ARM_LPAE_TCR_T0SZ_SHIFT;
/* Disable speculative walks through TTBR1 */
reg64 |= ARM_LPAE_TCR_EPD1;
reg = (uint32_t) reg64;
reg2 = (uint32_t) (reg64 >> 32);
reg2 |= TTBCR2_SEP_UPSTREAM;
reg2 |= TTBCR2_AS;
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_TTBCR2), reg2);
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_TTBCR), reg);
/* TTBR0. */
asid = smmu->cfg[idx].cbndx;
reg64 = pg_table_base;
reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_TTBR0), reg64);
/* TTBR1. */
reg64 = 0;
reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_TTBR1), reg64);
/* MAIR. */
reg = (ARM_LPAE_MAIR_ATTR_NC
<< ARM_LPAE_MAIR_ATTR_SHIFT
(ARM_LPAE_MAIR_ATTR_IDX_NC)) |
(ARM_LPAE_MAIR_ATTR_WBRWA <<
ARM_LPAE_MAIR_ATTR_SHIFT
(ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
(ARM_LPAE_MAIR_ATTR_DEVICE <<
ARM_LPAE_MAIR_ATTR_SHIFT
(ARM_LPAE_MAIR_ATTR_IDX_DEV));
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_S1_MAIR0), reg);
/* MAIR1. */
reg = 0;
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_S1_MAIR1), reg);
/* SCTLR. */
reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M;
/* stage 1.*/
reg |= SCTLR_S1_ASIDPNE;
mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
ARM_SMMU_CB_SCTLR), reg);
}
smmu_set_pgtbl(smmu, dom, (uint64_t *)pg_table_base);
}