forked from Minki/linux
irqchip/gic-v3-its: Add missing changes to support 52bit physical address
The current ITS driver works fine as long as normal memory and GICR regions are located within the lower 48bit (>=0 && <2^48) physical address space. Some of the registers GICR_PEND/PROP, GICR_VPEND/VPROP and GITS_CBASER are handled properly but not all when configuring the hardware with 52bit physical address. This patch does the following changes to support 52bit PA. -Handle 52bit PA in GITS_BASERn. -Fix ITT_addr width to 52bits, bits[51:8]. -Fix RDbase width to 52bits, bits[51:16]. -Fix VPT_addr width to 52bits, bits[51:16]. Definition of the GITS_BASERn register when ITS PageSize is 64KB: -Bits[47:16] of the register provide bits[47:16] of the table PA. -Bits[15:12] of the register provide bits[51:48] of the table PA. -Bits[15:00] of the base physical address are 0. Signed-off-by: Shanker Donthineni <shankerd@codeaurora.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
This commit is contained in:
parent
32bd44dc19
commit
30ae9610d2
@ -312,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
|
||||
|
||||
static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8);
|
||||
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
|
||||
}
|
||||
|
||||
static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
||||
@ -322,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
|
||||
|
||||
static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_collection(struct its_cmd_block *cmd, u16 col)
|
||||
@ -362,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
|
||||
|
||||
static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
|
||||
{
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16);
|
||||
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
|
||||
}
|
||||
|
||||
static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size)
|
||||
@ -1482,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
|
||||
u64 val = its_read_baser(its, baser);
|
||||
u64 esz = GITS_BASER_ENTRY_SIZE(val);
|
||||
u64 type = GITS_BASER_TYPE(val);
|
||||
u64 baser_phys, tmp;
|
||||
u32 alloc_pages;
|
||||
void *base;
|
||||
u64 tmp;
|
||||
|
||||
retry_alloc_baser:
|
||||
alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
|
||||
@ -1500,8 +1500,24 @@ retry_alloc_baser:
|
||||
if (!base)
|
||||
return -ENOMEM;
|
||||
|
||||
baser_phys = virt_to_phys(base);
|
||||
|
||||
/* Check if the physical address of the memory is above 48bits */
|
||||
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
|
||||
|
||||
/* 52bit PA is supported only when PageSize=64K */
|
||||
if (psz != SZ_64K) {
|
||||
pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
|
||||
free_pages((unsigned long)base, order);
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
/* Convert 52bit PA to 48bit field */
|
||||
baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
|
||||
}
|
||||
|
||||
retry_baser:
|
||||
val = (virt_to_phys(base) |
|
||||
val = (baser_phys |
|
||||
(type << GITS_BASER_TYPE_SHIFT) |
|
||||
((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
|
||||
((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) |
|
||||
|
@ -372,6 +372,8 @@
|
||||
#define GITS_BASER_ENTRY_SIZE_SHIFT (48)
|
||||
#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
|
||||
#define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48)
|
||||
#define GITS_BASER_PHYS_52_to_48(phys) \
|
||||
(((phys) & GENMASK_ULL(47, 16)) | (((phys) >> 48) & 0xf) << 12)
|
||||
#define GITS_BASER_SHAREABILITY_SHIFT (10)
|
||||
#define GITS_BASER_InnerShareable \
|
||||
GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
|
||||
|
Loading…
Reference in New Issue
Block a user