CC drivers/iommu/msm_iommu-v1.o
In file included from include/linux/io.h:22:0,
from drivers/iommu/msm_iommu-v1.c:18:
drivers/iommu/msm_iommu-v1.c: In function '__program_context':
arch/arm/mach-msm/include/mach/iommu_hw-v1.h:61:31: warning:
result of '16777215 << 14' requires 39 bits to represent,
but 'int' only has 32 bits [-Wshift-overflow=]
error, forbidden warning: iommu_hw-v1.h:61
以前曾经问过这个问题。 Android kernel compile error gcc6 linaro 6唯一的答案是用
编译 # Ensure C builds don't fail on warnings
export CFLAGS="-Wno-error"
export CXXFLAGS="-Wno-error"
这对我来说没有意义,为什么隐藏错误?我们应该修复它们。这是我到目前为止所发现的。
static void __program_context(struct msm_iommu_drvdata *iommu_drvdata,
struct msm_iommu_ctx_drvdata *ctx_drvdata,
struct msm_iommu_priv *priv, bool is_secure,
bool program_m2v)
{
unsigned int prrr, nmrr;
phys_addr_t pn;
void __iomem *base = iommu_drvdata->base;
unsigned int ctx = ctx_drvdata->num;
phys_addr_t pgtable = __pa(priv->pt.fl_table);
__reset_context(base, ctx);
pn = pgtable >> CB_TTBR0_ADDR_SHIFT;
SET_TTBCR(base, ctx, 0);
SET_CB_TTBR0_ADDR(base, ctx, pn);
/* Enable context fault interrupt */
SET_CB_SCTLR_CFIE(base, ctx, 1);
/* Redirect all cacheable requests to L2 slave port. */
SET_CB_ACTLR_BPRCISH(base, ctx, 1);
SET_CB_ACTLR_BPRCOSH(base, ctx, 1);
SET_CB_ACTLR_BPRCNSH(base, ctx, 1);
/* Turn on TEX Remap */
SET_CB_SCTLR_TRE(base, ctx, 1);
/* Enable private ASID namespace */
SET_CB_SCTLR_ASIDPNE(base, ctx, 1);
/* Set TEX remap attributes */
RCP15_PRRR(prrr);
RCP15_NMRR(nmrr);
SET_PRRR(base, ctx, prrr);
SET_NMRR(base, ctx, nmrr);
/* Configure page tables as inner-cacheable and shareable to reduce
* the TLB miss penalty.
*/
if (priv->pt.redirect) {
SET_CB_TTBR0_S(base, ctx, 1);
SET_CB_TTBR0_NOS(base, ctx, 1);
SET_CB_TTBR0_IRGN1(base, ctx, 0); /* WB, WA */
SET_CB_TTBR0_IRGN0(base, ctx, 1);
SET_CB_TTBR0_RGN(base, ctx, 1); /* WB, WA */
}
if (!is_secure) {
if (program_m2v)
program_all_m2v_tables(iommu_drvdata);
SET_CBAR_N(base, ctx, 0);
/* Stage 1 Context with Stage 2 bypass */
SET_CBAR_TYPE(base, ctx, 1);
/* Route page faults to the non-secure interrupt */
SET_CBAR_IRPTNDX(base, ctx, 1);
/* Set VMID to non-secure HLOS */
SET_CBAR_VMID(base, ctx, 3);
/* Bypass is treated as inner-shareable */
SET_CBAR_BPSHCFG(base, ctx, 2);
/* Do not downgrade memory attributes */
SET_CBAR_MEMATTR(base, ctx, 0x0A);
}
msm_iommu_assign_ASID(iommu_drvdata, ctx_drvdata, priv);
/* Enable the MMU */
SET_CB_SCTLR_M(base, ctx, 1);
mb();
}
#define SET_FIELD(addr, mask, shift, v) \
do { \
int t = readl_relaxed(addr); \
writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
(mask)) << (shift)), addr); \
} while (0)
我能说的问题是来自arch / arm / include / asm / io.h的函数writel_relaxed
#define writel_relaxed(v,c) ((void)__raw_writel((__force u32) \
cpu_to_le32(v),c))
答案 0 :(得分:0)
简单的解决方案 - 使用更大的宽度变量。使用unsigned long long代替int。
编辑:如果在常量而不是变量上调用宏,则将常量显式转换为(unsigned long long)。我不确定C标准是否有很长的后缀。
答案 1 :(得分:0)
错误来自SET_FIELD
的宏扩展。 {常量} 16777215
用作mask
值:
#define SET_FIELD(addr, mask, shift, v) \
do { \
int t = readl_relaxed(addr); \
writel_relaxed((t & ~((mask) << (shift))) + (((v) & \
(mask)) << (shift)), addr); \
} while (0)
常量可能需要转换为unsigned int
,或者甚至更宽泛的类型(如果这是64位ARM)。但是,仅从源和警告中不清楚这个宏SET_FIELD
的调用位置。
或,可能会将上方宏中的mask
转换为(unsigned int)
。