diff mbox

[2/3] hw/arm/virt: Put GIC register banks on 64K boundaries

Message ID 1398362083-17737-3-git-send-email-peter.maydell@linaro.org
State New
Headers show

Commit Message

Peter Maydell April 24, 2014, 5:54 p.m. UTC
For an AArch64 CPU which supports 64K pages, having the GIC
register banks at 4K offsets is potentially awkward. Move
them out to being at 64K offsets. (This is harmless for
AArch32 CPUs and for AArch64 CPUs with 4K pages, so it is simpler
to use the same offsets everywhere than to try to use 64K offsets
only for AArch64 host CPUs.)

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 hw/arm/virt.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

Rob Herring April 25, 2014, 1:28 p.m. UTC | #1
On Thu, Apr 24, 2014 at 12:54 PM, Peter Maydell
<peter.maydell@linaro.org> wrote:
> For an AArch64 CPU which supports 64K pages, having the GIC
> register banks at 4K offsets is potentially awkward. Move
> them out to being at 64K offsets. (This is harmless for
> AArch32 CPUs and for AArch64 CPUs with 4K pages, so it is simpler
> to use the same offsets everywhere than to try to use 64K offsets
> only for AArch64 host CPUs.)
>
> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
> ---
>  hw/arm/virt.c | 6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index ecff256..9c4d337 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -96,10 +96,10 @@ typedef struct VirtBoardInfo {
>  static const MemMapEntry a15memmap[] = {
>      /* Space up to 0x8000000 is reserved for a boot ROM */
>      [VIRT_FLASH] = { 0, 0x8000000 },
> -    [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
> +    [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 },
>      /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
> -    [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
> -    [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
> +    [VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
> +    [VIRT_GIC_CPU] = { 0x8010000, 0x10000 },

This is not quite what you would have if people follow the SBSA
address swizzling on a GIC-400. The problem is the GICC_DIR register
at 0x1000 offset. IIRC, this register would show up at 0x8020000 in
this case. That means the CPU registers should be at 0x801f000. The
registers banks get aliased in every 4KB with the 64KB region.

That being said, perhaps we don't want to follow actual h/w that closely.

It sure is nice there are no hacks in the server space.

Rob
Peter Maydell April 25, 2014, 1:39 p.m. UTC | #2
On 25 April 2014 14:28, Rob Herring <rob.herring@linaro.org> wrote:
> On Thu, Apr 24, 2014 at 12:54 PM, Peter Maydell
> <peter.maydell@linaro.org> wrote:
>> For an AArch64 CPU which supports 64K pages, having the GIC
>> register banks at 4K offsets is potentially awkward. Move
>> them out to being at 64K offsets. (This is harmless for
>> AArch32 CPUs and for AArch64 CPUs with 4K pages, so it is simpler
>> to use the same offsets everywhere than to try to use 64K offsets
>> only for AArch64 host CPUs.)
>>
>> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
>> ---
>>  hw/arm/virt.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
>> index ecff256..9c4d337 100644
>> --- a/hw/arm/virt.c
>> +++ b/hw/arm/virt.c
>> @@ -96,10 +96,10 @@ typedef struct VirtBoardInfo {
>>  static const MemMapEntry a15memmap[] = {
>>      /* Space up to 0x8000000 is reserved for a boot ROM */
>>      [VIRT_FLASH] = { 0, 0x8000000 },
>> -    [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
>> +    [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 },
>>      /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
>> -    [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
>> -    [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
>> +    [VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
>> +    [VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
>
> This is not quite what you would have if people follow the SBSA
> address swizzling on a GIC-400. The problem is the GICC_DIR register
> at 0x1000 offset. IIRC, this register would show up at 0x8020000 in
> this case. That means the CPU registers should be at 0x801f000. The
> registers banks get aliased in every 4KB with the 64KB region.

Yes. Unfortunately if you want to use the in-kernel GIC
(which you pretty much have to for KVM) then you can't
emulate every-4K-aliasing on a 64K-pages host unless the
host h/w happens to do the 4K swizzling trick.

Also AIUI (without some patches maz has) it's not currently
possible to put the KVM GICC at a non-page-boundary.

> That being said, perhaps we don't want to follow actual
> h/w that closely.

I had a look at some of the dts files in the kernel and
for instance the APM boards define the GICV as being on
a 64K page boundary. So I figured putting GICC on a 64K
boundary was probably the least worst compromise.

(Eventually we might have to have full kvmtool style
"the memory map and available devices in the VM are
dependent on what the host has" flexibility, at least
for machines like 'virt' where we do device tree
generation.)

> It sure is nice there are no hacks in the server space.

Sure is.

thanks
-- PMM
diff mbox

Patch

diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ecff256..9c4d337 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -96,10 +96,10 @@  typedef struct VirtBoardInfo {
 static const MemMapEntry a15memmap[] = {
     /* Space up to 0x8000000 is reserved for a boot ROM */
     [VIRT_FLASH] = { 0, 0x8000000 },
-    [VIRT_CPUPERIPHS] = { 0x8000000, 0x8000 },
+    [VIRT_CPUPERIPHS] = { 0x8000000, 0x20000 },
     /* GIC distributor and CPU interfaces sit inside the CPU peripheral space */
-    [VIRT_GIC_DIST] = { 0x8001000, 0x1000 },
-    [VIRT_GIC_CPU] = { 0x8002000, 0x1000 },
+    [VIRT_GIC_DIST] = { 0x8000000, 0x10000 },
+    [VIRT_GIC_CPU] = { 0x8010000, 0x10000 },
     [VIRT_UART] = { 0x9000000, 0x1000 },
     [VIRT_MMIO] = { 0xa000000, 0x200 },
     /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */