qemu/hw/arm/smmu-internal.h
<<
>>
Prefs
   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
  81static inline int level_shift(int level, int granule_sz)
  82{
  83    return granule_sz + (3 - level) * (granule_sz - 3);
  84}
  85
  86static 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
  91static inline
  92uint64_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#define SMMU_IOTLB_ASID(key) ((key).asid)
 100
 101typedef struct SMMUIOTLBPageInvInfo {
 102    int asid;
 103    uint64_t iova;
 104    uint64_t mask;
 105} SMMUIOTLBPageInvInfo;
 106
 107typedef struct SMMUSIDRange {
 108    uint32_t start;
 109    uint32_t end;
 110} SMMUSIDRange;
 111
 112#endif
 113