]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * ARM SMMU support - Internal API | |
3 | * | |
4 | * Copyright (c) 2017 Red Hat, Inc. | |
5 | * Copyright (C) 2014-2016 Broadcom Corporation | |
6 | * Written by Prem Mallappa, Eric Auger | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify | |
9 | * it under the terms of the GNU General Public License version 2 as | |
10 | * published by the Free Software Foundation. | |
11 | * | |
12 | * This program is distributed in the hope that it will be useful, | |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * General Public License for more details. | |
16 | * | |
17 | * You should have received a copy of the GNU General Public License along | |
18 | * with this program; if not, see <http://www.gnu.org/licenses/>. | |
19 | */ | |
20 | ||
21 | #ifndef HW_ARM_SMMU_INTERNAL_H | |
22 | #define HW_ARM_SMMU_INTERNAL_H | |
23 | ||
24 | #define TBI0(tbi) ((tbi) & 0x1) | |
25 | #define TBI1(tbi) ((tbi) & 0x2 >> 1) | |
26 | ||
27 | /* PTE Manipulation */ | |
28 | ||
29 | #define ARM_LPAE_PTE_TYPE_SHIFT 0 | |
30 | #define ARM_LPAE_PTE_TYPE_MASK 0x3 | |
31 | ||
32 | #define ARM_LPAE_PTE_TYPE_BLOCK 1 | |
33 | #define ARM_LPAE_PTE_TYPE_TABLE 3 | |
34 | ||
35 | #define ARM_LPAE_L3_PTE_TYPE_RESERVED 1 | |
36 | #define ARM_LPAE_L3_PTE_TYPE_PAGE 3 | |
37 | ||
38 | #define ARM_LPAE_PTE_VALID (1 << 0) | |
39 | ||
40 | #define PTE_ADDRESS(pte, shift) \ | |
41 | (extract64(pte, shift, 47 - shift + 1) << shift) | |
42 | ||
43 | #define is_invalid_pte(pte) (!(pte & ARM_LPAE_PTE_VALID)) | |
44 | ||
45 | #define is_reserved_pte(pte, level) \ | |
46 | ((level == 3) && \ | |
47 | ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_RESERVED)) | |
48 | ||
49 | #define is_block_pte(pte, level) \ | |
50 | ((level < 3) && \ | |
51 | ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_BLOCK)) | |
52 | ||
53 | #define is_table_pte(pte, level) \ | |
54 | ((level < 3) && \ | |
55 | ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_PTE_TYPE_TABLE)) | |
56 | ||
57 | #define is_page_pte(pte, level) \ | |
58 | ((level == 3) && \ | |
59 | ((pte & ARM_LPAE_PTE_TYPE_MASK) == ARM_LPAE_L3_PTE_TYPE_PAGE)) | |
60 | ||
61 | /* access permissions */ | |
62 | ||
63 | #define PTE_AP(pte) \ | |
64 | (extract64(pte, 6, 2)) | |
65 | ||
66 | #define PTE_APTABLE(pte) \ | |
67 | (extract64(pte, 61, 2)) | |
68 | ||
69 | /* | |
70 | * TODO: At the moment all transactions are considered as privileged (EL1) | |
71 | * as IOMMU translation callback does not pass user/priv attributes. | |
72 | */ | |
73 | #define is_permission_fault(ap, perm) \ | |
74 | (((perm) & IOMMU_WO) && ((ap) & 0x2)) | |
75 | ||
76 | #define PTE_AP_TO_PERM(ap) \ | |
77 | (IOMMU_ACCESS_FLAG(true, !((ap) & 0x2))) | |
78 | ||
79 | /* Level Indexing */ | |
80 | ||
81 | static inline int level_shift(int level, int granule_sz) | |
82 | { | |
83 | return granule_sz + (3 - level) * (granule_sz - 3); | |
84 | } | |
85 | ||
86 | static inline uint64_t level_page_mask(int level, int granule_sz) | |
87 | { | |
88 | return ~(MAKE_64BIT_MASK(0, level_shift(level, granule_sz))); | |
89 | } | |
90 | ||
91 | static inline | |
92 | uint64_t iova_level_offset(uint64_t iova, int inputsize, | |
93 | int level, int gsz) | |
94 | { | |
95 | return ((iova & MAKE_64BIT_MASK(0, inputsize)) >> level_shift(level, gsz)) & | |
96 | MAKE_64BIT_MASK(0, gsz - 3); | |
97 | } | |
98 | ||
99 | #endif |