blob: de8b995dbf05eb642fc968cb0f58a5a92776e32b [file] [log] [blame]
Sheetal Tigadoli58a9eca2019-12-18 20:05:09 +05301/*
2 * Copyright (c) 2017 - 2020, Broadcom
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch_helpers.h>
8#include <common/debug.h>
9#include <drivers/delay_timer.h>
10#include <lib/mmio.h>
11
12#include <iommu.h>
13#include <platform_def.h>
14
15#define SMMU_BASE 0x64000000
16#define ARM_SMMU_MAX_NUM_CNTXT_BANK 64
17#define SMMU_CTX_BANK_IDX_SECURE_CRMU 63
18#define ARM_SMMU_NUM_SECURE_MASTER 1
19#define ARM_SMMU_NSNUMCBO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
20 ARM_SMMU_NUM_SECURE_MASTER)
21#define ARM_SMMU_NSNUMSMRGO (ARM_SMMU_MAX_NUM_CNTXT_BANK - \
22 ARM_SMMU_NUM_SECURE_MASTER)
23/* Reserved Banks. */
24#define SMMU_CTX_BANK_IDX (SMMU_CTX_BANK_IDX_SECURE_CRMU - \
25 ARM_SMMU_NUM_SECURE_MASTER)
26#define NUM_OF_SMRS 1
27
28#define STG1_WITH_STG2_BYPASS 1
29#define ARM_LPAE_PGTBL_PHYS_CRMU 0x880000000
30#define ARM_LPAE_PGTBL_PHYS 0x880200000
31#define ARM_LPAE_PGTBL_PTE_CNT 512
32#define ARM_LPAE_PTE_L1_BLOCK_SIZE 0x40000000
33#define ARM_LPAE_PTE_L1_ADDR_MASK 0x0000FFFFC0000000UL
34#define ARM_LPAE_PTE_TABLE 0x2UL
35#define ARM_LPAE_PTE_VALID 0x1UL
36#define ARM_LPAE_PTE_ATTRINDX 2
37#define ARM_LPAE_PTE_NS 5
38#define ARM_LPAE_PTE_AP 6
39#define ARM_LPAE_PTE_AP_EL1_RW 0x0
40#define ARM_LPAE_PTE_AP_EL0_RW 0x1
41#define ARM_LPAE_PTE_SH 8
42#define ARM_LPAE_PTE_SH_NON 0x0
43#define ARM_LPAE_PTE_SH_OUTER 0x2
44#define ARM_LPAE_PTE_SH_INNER 0x3
45#define ARM_LPAE_PTE_AF 10
46#define ARM_SMMU_RES_SIZE 0x80000
47
48#define ARM_LPAE_PTE_NSTABLE 0x8000000000000000UL
49#define ARM_LPAE_PTE_L1_INDEX_SHIFT 30
50#define ARM_LPAE_PTE_L1_INDEX_MASK 0x1ff
51#define ARM_LPAE_PTE_L0_INDEX_SHIFT 39
52#define ARM_LPAE_PTE_L0_INDEX_MASK 0x1ff
53#define ARM_LPAE_PTE_TABLE_MASK ~(0xfffUL)
54/* Configuration registers */
55#define ARM_SMMU_GR0_sCR0 0x0
56#define sCR0_CLIENTPD (1 << 0)
57#define sCR0_GFRE (1 << 1)
58#define sCR0_GFIE (1 << 2)
59#define sCR0_GCFGFRE (1 << 4)
60#define sCR0_GCFGFIE (1 << 5)
61#define sCR0_USFCFG (1 << 10)
62#define sCR0_VMIDPNE (1 << 11)
63#define sCR0_PTM (1 << 12)
64#define sCR0_FB (1 << 13)
65#define sCR0_VMID16EN (1 << 31)
66#define sCR0_BSU_SHIFT 14
67#define sCR0_BSU_MASK 0x3
68#define ARM_SMMU_SMMU_SCR1 0x4
69#define SCR1_NSNUMCBO_MASK 0xFF
70#define SCR1_NSNUMCBO_SHIFT 0x0
71#define SCR1_NSNUMSMRGO_MASK 0xFF00
72#define SCR1_NSNUMSMRGO_SHIFT 0x8
73
74/* Identification registers */
75#define ARM_SMMU_GR0_ID0 0x20
76#define ARM_SMMU_GR0_ID1 0x24
77#define ARM_SMMU_GR0_ID2 0x28
78#define ARM_SMMU_GR0_ID3 0x2c
79#define ARM_SMMU_GR0_ID4 0x30
80#define ARM_SMMU_GR0_ID5 0x34
81#define ARM_SMMU_GR0_ID6 0x38
82#define ARM_SMMU_GR0_ID7 0x3c
83#define ARM_SMMU_GR0_sGFSR 0x48
84#define ARM_SMMU_GR0_sGFSYNR0 0x50
85#define ARM_SMMU_GR0_sGFSYNR1 0x54
86#define ARM_SMMU_GR0_sGFSYNR2 0x58
87
88#define ID1_PAGESIZE (1U << 31)
89#define ID1_NUMPAGENDXB_SHIFT 28
90#define ID1_NUMPAGENDXB_MASK 7
91#define ID1_NUMS2CB_SHIFT 16
92#define ID1_NUMS2CB_MASK 0xff
93#define ID1_NUMCB_SHIFT 0
94#define ID1_NUMCB_MASK 0xff
95
96/* SMMU global address space */
97#define ARM_SMMU_GR0(smmu) ((smmu)->base)
98#define ARM_SMMU_GR1(smmu) ((smmu)->base + (1 << (smmu)->pgshift))
99
100/* Stream mapping registers */
101#define ARM_SMMU_GR0_SMR(n) (0x800 + (n << 2))
102#define SMR_VALID (1U << 31)
103#define SMR_MASK_SHIFT 16
104#define SMR_ID_SHIFT 0
105
106#define ARM_SMMU_GR0_S2CR(n) (0xc00 + (n << 2))
107#define S2CR_CBNDX_SHIFT 0
108#define S2CR_CBNDX_MASK 0xff
109#define S2CR_TYPE_SHIFT 16
110#define S2CR_TYPE_MASK 0x3
111
112#define ARM_SMMU_GR1_CBA2R(n) (0x800 + (n << 2))
113#define CBA2R_RW64_32BIT (0 << 0)
114#define CBA2R_RW64_64BIT (1 << 0)
115#define CBA2R_VMID_SHIFT 16
116#define CBA2R_VMID_MASK 0xffff
117
118#define ARM_SMMU_GR1_CBAR(n) (0x0 + (n << 2))
119#define CBAR_VMID_SHIFT 0
120#define CBAR_VMID_MASK 0xff
121#define CBAR_S1_BPSHCFG_SHIFT 8
122#define CBAR_S1_BPSHCFG_MASK 3
123#define CBAR_S1_BPSHCFG_NSH 3
124#define CBAR_S1_MEMATTR_SHIFT 12
125#define CBAR_S1_MEMATTR_MASK 0xf
126#define CBAR_S1_MEMATTR_WB 0xf
127#define CBAR_TYPE_SHIFT 16
128#define CBAR_TYPE_MASK 0x3
129#define CBAR_TYPE_S2_TRANS (0 << CBAR_TYPE_SHIFT)
130#define CBAR_TYPE_S1_TRANS_S2_BYPASS (1 << CBAR_TYPE_SHIFT)
131#define CBAR_TYPE_S1_TRANS_S2_FAULT (2 << CBAR_TYPE_SHIFT)
132#define CBAR_TYPE_S1_TRANS_S2_TRANS (3 << CBAR_TYPE_SHIFT)
133#define CBAR_IRPTNDX_SHIFT 24
134#define CBAR_IRPTNDX_MASK 0xff
135
136/* Translation context bank */
137#define ARM_SMMU_CB_BASE(smmu) ((smmu)->base + ((smmu)->size >> 1))
138#define ARM_SMMU_CB(smmu, n) ((n) * (1 << (smmu)->pgshift))
139
140#define ARM_SMMU_CB_SCTLR 0x0
141#define ARM_SMMU_CB_ACTLR 0x4
142#define ARM_SMMU_CB_RESUME 0x8
143#define ARM_SMMU_CB_TTBCR2 0x10
144#define ARM_SMMU_CB_TTBR0 0x20
145#define ARM_SMMU_CB_TTBR1 0x28
146#define ARM_SMMU_CB_TTBCR 0x30
147#define ARM_SMMU_CB_CONTEXTIDR 0x34
148#define ARM_SMMU_CB_S1_MAIR0 0x38
149#define ARM_SMMU_CB_S1_MAIR1 0x3c
150#define ARM_SMMU_CB_PAR 0x50
151#define ARM_SMMU_CB_FSR 0x58
152#define ARM_SMMU_CB_FAR 0x60
153#define ARM_SMMU_CB_FSYNR0 0x68
154#define ARM_SMMU_CB_S1_TLBIVA 0x600
155#define ARM_SMMU_CB_S1_TLBIASID 0x610
156#define ARM_SMMU_CB_S1_TLBIVAL 0x620
157#define ARM_SMMU_CB_S2_TLBIIPAS2 0x630
158#define ARM_SMMU_CB_S2_TLBIIPAS2L 0x638
159#define ARM_SMMU_CB_ATS1PR 0x800
160#define ARM_SMMU_CB_ATSR 0x8f0
161
162#define SCTLR_S1_ASIDPNE (1 << 12)
163#define SCTLR_CFCFG (1 << 7)
164#define SCTLR_CFIE (1 << 6)
165#define SCTLR_CFRE (1 << 5)
166#define SCTLR_E (1 << 4)
167#define SCTLR_AFE (1 << 2)
168#define SCTLR_TRE (1 << 1)
169#define SCTLR_M (1 << 0)
170
171/* ARM LPAE configuration. */
172/**************************************************************/
173/* Register bits */
174#define ARM_32_LPAE_TCR_EAE (1 << 31)
175#define ARM_64_LPAE_S2_TCR_RES1 (1 << 31)
176
177#define ARM_LPAE_TCR_EPD1 (1 << 23)
178
179#define ARM_LPAE_TCR_TG0_4K (0 << 14)
180#define ARM_LPAE_TCR_TG0_64K (1 << 14)
181#define ARM_LPAE_TCR_TG0_16K (2 << 14)
182
183#define ARM_LPAE_TCR_SH0_SHIFT 12
184#define ARM_LPAE_TCR_SH0_MASK 0x3
185#define ARM_LPAE_TCR_SH_NS 0
186#define ARM_LPAE_TCR_SH_OS 2
187#define ARM_LPAE_TCR_SH_IS 3
188
189#define ARM_LPAE_TCR_ORGN0_SHIFT 10
190#define ARM_LPAE_TCR_IRGN0_SHIFT 8
191#define ARM_LPAE_TCR_RGN_MASK 0x3
192#define ARM_LPAE_TCR_RGN_NC 0
193#define ARM_LPAE_TCR_RGN_WBWA 1
194#define ARM_LPAE_TCR_RGN_WT 2
195#define ARM_LPAE_TCR_RGN_WB 3
196
197#define ARM_LPAE_TCR_SL0_SHIFT 6
198#define ARM_LPAE_TCR_SL0_MASK 0x3
199
200#define ARM_LPAE_TCR_T0SZ_SHIFT 0
201#define ARM_LPAE_TCR_SZ_MASK 0xf
202
203#define ARM_LPAE_TCR_PS_SHIFT 16
204#define ARM_LPAE_TCR_PS_MASK 0x7
205
206#define ARM_LPAE_TCR_IPS_SHIFT 32
207#define ARM_LPAE_TCR_IPS_MASK 0x7
208
209#define ARM_LPAE_TCR_PS_32_BIT 0x0ULL
210#define ARM_LPAE_TCR_PS_36_BIT 0x1ULL
211#define ARM_LPAE_TCR_PS_40_BIT 0x2ULL
212#define ARM_LPAE_TCR_PS_42_BIT 0x3ULL
213#define ARM_LPAE_TCR_PS_44_BIT 0x4ULL
214#define ARM_LPAE_TCR_PS_48_BIT 0x5ULL
215
216#define ARM_LPAE_MAIR_ATTR_SHIFT(n) ((n) << 3)
217#define ARM_LPAE_MAIR_ATTR_MASK 0xff
218#define ARM_LPAE_MAIR_ATTR_DEVICE 0x04
219#define ARM_LPAE_MAIR_ATTR_NC 0x44
220#define ARM_LPAE_MAIR_ATTR_WBRWA 0xff
221#define ARM_LPAE_MAIR_ATTR_IDX_NC 0
222#define ARM_LPAE_MAIR_ATTR_IDX_CACHE 1
223#define ARM_LPAE_MAIR_ATTR_IDX_DEV 2
224
225#define TTBRn_ASID_SHIFT 48
226#define TTBCR2_SEP_SHIFT 15
227#define TTBCR2_SEP_UPSTREAM (0x7 << TTBCR2_SEP_SHIFT)
228#define TTBCR2_AS (1 << 4)
229#define TTBCR_T0SZ(ia_bits) (64 - (ia_bits))
230
231#define S2CR_PRIVCFG_SHIFT 24
232#define S2CR_PRIVCFG_MASK 0x3
233
234/**************************************************************/
235
236uint16_t paxc_stream_ids[] = { 0x2000 };
237
238uint16_t paxc_stream_ids_mask[] = { 0x1fff };
239uint16_t crmu_stream_ids[] = { CRMU_STREAM_ID };
240uint16_t crmu_stream_ids_mask[] = { 0x0 };
241
242enum arm_smmu_s2cr_type {
243 S2CR_TYPE_TRANS,
244 S2CR_TYPE_BYPASS,
245 S2CR_TYPE_FAULT,
246};
247
248enum arm_smmu_s2cr_privcfg {
249 S2CR_PRIVCFG_DEFAULT,
250 S2CR_PRIVCFG_DIPAN,
251 S2CR_PRIVCFG_UNPRIV,
252 S2CR_PRIVCFG_PRIV,
253};
254
255struct arm_smmu_smr {
256 uint16_t mask;
257 uint16_t id;
258 uint32_t valid;
259};
260
261struct arm_smmu_s2cr {
262 int count;
263 enum arm_smmu_s2cr_type type;
264 enum arm_smmu_s2cr_privcfg privcfg;
265 uint8_t cbndx;
266};
267
268struct arm_smmu_cfg {
269 uint8_t cbndx;
270 uint8_t irptndx;
271 uint32_t cbar;
272};
273
274struct arm_smmu_device {
275 uint8_t *base;
276 uint32_t streams;
277 unsigned long size;
278 unsigned long pgshift;
279 unsigned long va_size;
280 unsigned long ipa_size;
281 unsigned long pa_size;
282 struct arm_smmu_smr smr[NUM_OF_SMRS];
283 struct arm_smmu_s2cr s2cr[NUM_OF_SMRS];
284 struct arm_smmu_cfg cfg[NUM_OF_SMRS];
285 uint16_t *stream_ids;
286 uint16_t *stream_ids_mask;
287};
288
289void arm_smmu_enable_secure_client_port(void)
290{
291 uintptr_t smmu_base = SMMU_BASE;
292
293 mmio_clrbits_32(smmu_base, sCR0_CLIENTPD);
294}
295
296void arm_smmu_reserve_secure_cntxt(void)
297{
298 uintptr_t smmu_base = SMMU_BASE;
299
300 mmio_clrsetbits_32(smmu_base + ARM_SMMU_SMMU_SCR1,
301 (SCR1_NSNUMSMRGO_MASK | SCR1_NSNUMCBO_MASK),
302 ((ARM_SMMU_NSNUMCBO << SCR1_NSNUMCBO_SHIFT) |
303 (ARM_SMMU_NSNUMSMRGO << SCR1_NSNUMSMRGO_SHIFT)));
304}
305
306static void arm_smmu_smr_cfg(struct arm_smmu_device *smmu, uint32_t index)
307{
308 uint32_t idx = smmu->cfg[index].cbndx;
309 struct arm_smmu_smr *smr = &smmu->smr[index];
310 uint32_t reg = smr->id << SMR_ID_SHIFT | smr->mask << SMR_MASK_SHIFT;
311
312 if (smr->valid)
313 reg |= SMR_VALID;
314
315 mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
316 ARM_SMMU_GR0_SMR(idx)), reg);
317}
318
319static void arm_smmu_s2cr_cfg(struct arm_smmu_device *smmu, uint32_t index)
320{
321 uint32_t idx = smmu->cfg[index].cbndx;
322 struct arm_smmu_s2cr *s2cr = &smmu->s2cr[index];
323
324 uint32_t reg = (s2cr->type & S2CR_TYPE_MASK) << S2CR_TYPE_SHIFT |
325 (s2cr->cbndx & S2CR_CBNDX_MASK) << S2CR_CBNDX_SHIFT |
326 (s2cr->privcfg & S2CR_PRIVCFG_MASK) << S2CR_PRIVCFG_SHIFT;
327
328 mmio_write_32((uintptr_t) (ARM_SMMU_GR0(smmu) +
329 ARM_SMMU_GR0_S2CR(idx)), reg);
330}
331
332static void smmu_set_pgtbl(struct arm_smmu_device *smmu,
333 enum iommu_domain dom,
334 uint64_t *pg_table_base)
335{
336 int i, l0_index, l1_index;
337 uint64_t addr, *pte, *l0_base, *l1_base;
338 uint64_t addr_space_limit;
339
340 if (dom == PCIE_PAXC) {
341 addr_space_limit = 0xffffffffff;
342 } else if (dom == DOMAIN_CRMU) {
343 addr_space_limit = 0xffffffff;
344 } else {
345 ERROR("dom is not supported\n");
346 return;
347 }
348
349 l0_base = pg_table_base;
350 /* clear L0 descriptors. */
351 for (i = 0; i < ARM_LPAE_PGTBL_PTE_CNT; i++)
352 l0_base[i] = 0x0;
353
354 addr = 0x0;
355 while (addr < addr_space_limit) {
356 /* find L0 pte */
357 l0_index = ((addr >> ARM_LPAE_PTE_L0_INDEX_SHIFT) &
358 ARM_LPAE_PTE_L0_INDEX_MASK);
359 l1_base = l0_base + ((l0_index + 1) * ARM_LPAE_PGTBL_PTE_CNT);
360
361 /* setup L0 pte if required */
362 pte = l0_base + l0_index;
363 if (*pte == 0x0) {
364 *pte |= ((uint64_t)l1_base & ARM_LPAE_PTE_TABLE_MASK);
365 if (dom == PCIE_PAXC)
366 *pte |= ARM_LPAE_PTE_NSTABLE;
367 *pte |= ARM_LPAE_PTE_TABLE;
368 *pte |= ARM_LPAE_PTE_VALID;
369 }
370
371 /* find L1 pte */
372 l1_index = ((addr >> ARM_LPAE_PTE_L1_INDEX_SHIFT) &
373 ARM_LPAE_PTE_L1_INDEX_MASK);
374 pte = l1_base + l1_index;
375
376 /* setup L1 pte */
377 *pte = 0x0;
378 *pte |= (addr & ARM_LPAE_PTE_L1_ADDR_MASK);
379 if (addr < 0x80000000) {
380 *pte |= (ARM_LPAE_MAIR_ATTR_IDX_DEV <<
381 ARM_LPAE_PTE_ATTRINDX);
382 if (dom == PCIE_PAXC)
383 *pte |= (1 << ARM_LPAE_PTE_NS);
384 } else {
385 *pte |= (ARM_LPAE_MAIR_ATTR_IDX_CACHE <<
386 ARM_LPAE_PTE_ATTRINDX);
387 *pte |= (1 << ARM_LPAE_PTE_NS);
388 }
389 *pte |= (ARM_LPAE_PTE_AP_EL0_RW << ARM_LPAE_PTE_AP);
390 *pte |= (ARM_LPAE_PTE_SH_INNER << ARM_LPAE_PTE_SH);
391 *pte |= (1 << ARM_LPAE_PTE_AF);
392 *pte |= ARM_LPAE_PTE_VALID;
393
394 addr += ARM_LPAE_PTE_L1_BLOCK_SIZE;
395 }
396}
397
398void arm_smmu_create_identity_map(enum iommu_domain dom)
399{
400 struct arm_smmu_device iommu;
401 struct arm_smmu_device *smmu = &iommu;
402 uint32_t reg, reg2;
403 unsigned long long reg64;
404 uint32_t idx;
405 uint16_t asid;
406 unsigned int context_bank_index;
407 unsigned long long pg_table_base;
408
409 smmu->base = (uint8_t *) SMMU_BASE;
410 reg = mmio_read_32((uintptr_t) (ARM_SMMU_GR0(smmu) + ARM_SMMU_GR0_ID1));
411 smmu->pgshift = (reg & ID1_PAGESIZE) ? 16 : 12;
412 smmu->size = ARM_SMMU_RES_SIZE;
413 smmu->stream_ids = NULL;
414
415 switch (dom) {
416 case PCIE_PAXC:
417 smmu->stream_ids = &paxc_stream_ids[0];
418 smmu->stream_ids_mask = &paxc_stream_ids_mask[0];
419 smmu->streams = ARRAY_SIZE(paxc_stream_ids);
420 context_bank_index = SMMU_CTX_BANK_IDX;
421 pg_table_base = ARM_LPAE_PGTBL_PHYS;
422 break;
423 case DOMAIN_CRMU:
424 smmu->stream_ids = &crmu_stream_ids[0];
425 smmu->stream_ids_mask = &crmu_stream_ids_mask[0];
426 smmu->streams = ARRAY_SIZE(crmu_stream_ids);
427 context_bank_index = SMMU_CTX_BANK_IDX_SECURE_CRMU;
428 pg_table_base = ARM_LPAE_PGTBL_PHYS_CRMU;
429 break;
430 default:
431 ERROR("domain not supported\n");
432 return;
433 }
434
435 if (smmu->streams > NUM_OF_SMRS) {
436 INFO("can not support more than %d sids\n", NUM_OF_SMRS);
437 return;
438 }
439
440 /* set up iommu dev. */
441 for (idx = 0; idx < smmu->streams; idx++) {
442 /* S2CR. */
443 smmu->s2cr[idx].type = S2CR_TYPE_TRANS;
444 smmu->s2cr[idx].privcfg = S2CR_PRIVCFG_DEFAULT;
445 smmu->s2cr[idx].cbndx = context_bank_index;
446 smmu->cfg[idx].cbndx = context_bank_index;
447 smmu->cfg[idx].cbar = STG1_WITH_STG2_BYPASS << CBAR_TYPE_SHIFT;
448 arm_smmu_s2cr_cfg(smmu, idx);
449
450 /* SMR. */
451 smmu->smr[idx].mask = smmu->stream_ids_mask[idx];
452 smmu->smr[idx].id = smmu->stream_ids[idx];
453 smmu->smr[idx].valid = 1;
454 arm_smmu_smr_cfg(smmu, idx);
455
456 /* CBA2R. 64-bit Translation */
457 mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
458 ARM_SMMU_GR1_CBA2R(smmu->cfg[idx].cbndx)),
459 0x1);
460 /* CBAR.*/
461 reg = smmu->cfg[idx].cbar;
462 reg |= (CBAR_S1_BPSHCFG_NSH << CBAR_S1_BPSHCFG_SHIFT) |
463 (CBAR_S1_MEMATTR_WB << CBAR_S1_MEMATTR_SHIFT);
464
465 mmio_write_32((uintptr_t) (ARM_SMMU_GR1(smmu) +
466 ARM_SMMU_GR1_CBAR(smmu->cfg[idx].cbndx)),
467 reg);
468
469 /* TTBCR. */
470 reg64 = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
471 (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
472 (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
473 reg64 |= ARM_LPAE_TCR_TG0_4K;
474 reg64 |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT);
475 /* ias 40 bits.*/
476 reg64 |= TTBCR_T0SZ(40) << ARM_LPAE_TCR_T0SZ_SHIFT;
477 /* Disable speculative walks through TTBR1 */
478 reg64 |= ARM_LPAE_TCR_EPD1;
479 reg = (uint32_t) reg64;
480 reg2 = (uint32_t) (reg64 >> 32);
481 reg2 |= TTBCR2_SEP_UPSTREAM;
482 reg2 |= TTBCR2_AS;
483
484 mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
485 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
486 ARM_SMMU_CB_TTBCR2), reg2);
487
488 mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
489 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
490 ARM_SMMU_CB_TTBCR), reg);
491
492 /* TTBR0. */
493 asid = smmu->cfg[idx].cbndx;
494 reg64 = pg_table_base;
495 reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
496
497 mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
498 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
499 ARM_SMMU_CB_TTBR0), reg64);
500 /* TTBR1. */
501 reg64 = 0;
502 reg64 |= (unsigned long long) asid << TTBRn_ASID_SHIFT;
503
504 mmio_write_64((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
505 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
506 ARM_SMMU_CB_TTBR1), reg64);
507 /* MAIR. */
508 reg = (ARM_LPAE_MAIR_ATTR_NC
509 << ARM_LPAE_MAIR_ATTR_SHIFT
510 (ARM_LPAE_MAIR_ATTR_IDX_NC)) |
511 (ARM_LPAE_MAIR_ATTR_WBRWA <<
512 ARM_LPAE_MAIR_ATTR_SHIFT
513 (ARM_LPAE_MAIR_ATTR_IDX_CACHE)) |
514 (ARM_LPAE_MAIR_ATTR_DEVICE <<
515 ARM_LPAE_MAIR_ATTR_SHIFT
516 (ARM_LPAE_MAIR_ATTR_IDX_DEV));
517
518 mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
519 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
520 ARM_SMMU_CB_S1_MAIR0), reg);
521
522 /* MAIR1. */
523 reg = 0;
524 mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
525 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
526 ARM_SMMU_CB_S1_MAIR1), reg);
527 /* SCTLR. */
528 reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M;
529 /* stage 1.*/
530 reg |= SCTLR_S1_ASIDPNE;
531 mmio_write_32((uintptr_t) (ARM_SMMU_CB_BASE(smmu) +
532 ARM_SMMU_CB(smmu, smmu->cfg[idx].cbndx) +
533 ARM_SMMU_CB_SCTLR), reg);
534 }
535 smmu_set_pgtbl(smmu, dom, (uint64_t *)pg_table_base);
536}