[PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common

Pierrick Bouvier posted 30 patches 1 week, 5 days ago
There is a newer version of this series
[PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common
Posted by Pierrick Bouvier 1 week, 5 days ago
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
 hw/arm/armv7m.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 98a69846119..c367c2dcb99 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -139,8 +139,9 @@ static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
     if (attrs.secure) {
         /* S accesses to the alias act like NS accesses to the real region */
         attrs.secure = 0;
+        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
         return memory_region_dispatch_write(mr, addr, value,
-                                            size_memop(size) | MO_TE, attrs);
+                                            size_memop(size) | end, attrs);
     } else {
         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
         if (attrs.user) {
@@ -159,8 +160,9 @@ static MemTxResult v7m_sysreg_ns_read(void *opaque, hwaddr addr,
     if (attrs.secure) {
         /* S accesses to the alias act like NS accesses to the real region */
         attrs.secure = 0;
+        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
         return memory_region_dispatch_read(mr, addr, data,
-                                           size_memop(size) | MO_TE, attrs);
+                                           size_memop(size) | end, attrs);
     } else {
         /* NS attrs are RAZ/WI for privileged, and BusFault for user */
         if (attrs.user) {
@@ -186,8 +188,9 @@ static MemTxResult v7m_systick_write(void *opaque, hwaddr addr,
 
     /* Direct the access to the correct systick */
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
+    MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
     return memory_region_dispatch_write(mr, addr, value,
-                                        size_memop(size) | MO_TE, attrs);
+                                        size_memop(size) | end, attrs);
 }
 
 static MemTxResult v7m_systick_read(void *opaque, hwaddr addr,
@@ -199,7 +202,8 @@ static MemTxResult v7m_systick_read(void *opaque, hwaddr addr,
 
     /* Direct the access to the correct systick */
     mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->systick[attrs.secure]), 0);
-    return memory_region_dispatch_read(mr, addr, data, size_memop(size) | MO_TE,
+    MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
+    return memory_region_dispatch_read(mr, addr, data, size_memop(size) | end,
                                        attrs);
 }
 
-- 
2.39.5
Re: [PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common
Posted by Richard Henderson 1 week, 2 days ago
On 3/20/25 15:29, Pierrick Bouvier wrote:
> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
> ---
>   hw/arm/armv7m.c | 12 ++++++++----
>   1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
> index 98a69846119..c367c2dcb99 100644
> --- a/hw/arm/armv7m.c
> +++ b/hw/arm/armv7m.c
> @@ -139,8 +139,9 @@ static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
>       if (attrs.secure) {
>           /* S accesses to the alias act like NS accesses to the real region */
>           attrs.secure = 0;
> +        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
>           return memory_region_dispatch_write(mr, addr, value,
> -                                            size_memop(size) | MO_TE, attrs);
> +                                            size_memop(size) | end, attrs);

target_words_bigendian() is always false for arm system mode.
Just s/TE/LE/.


r~
Re: [PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common
Posted by Pierrick Bouvier 1 week, 1 day ago
On 3/23/25 12:48, Richard Henderson wrote:
> On 3/20/25 15:29, Pierrick Bouvier wrote:
>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>> ---
>>    hw/arm/armv7m.c | 12 ++++++++----
>>    1 file changed, 8 insertions(+), 4 deletions(-)
>>
>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>> index 98a69846119..c367c2dcb99 100644
>> --- a/hw/arm/armv7m.c
>> +++ b/hw/arm/armv7m.c
>> @@ -139,8 +139,9 @@ static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
>>        if (attrs.secure) {
>>            /* S accesses to the alias act like NS accesses to the real region */
>>            attrs.secure = 0;
>> +        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
>>            return memory_region_dispatch_write(mr, addr, value,
>> -                                            size_memop(size) | MO_TE, attrs);
>> +                                            size_memop(size) | end, attrs);
> 
> target_words_bigendian() is always false for arm system mode.
> Just s/TE/LE/.
> 

Good point.

By the way, what's the QEMU rationale behind having Arm big endian user 
binaries, and not provide it for softmmu binaries?
If those systems are so rare, why would people need a user mode emulation?

Thanks,
Pierrick

> 
> r~
Re: [PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common
Posted by Richard Henderson 1 week, 1 day ago
On 3/24/25 14:31, Pierrick Bouvier wrote:
> On 3/23/25 12:48, Richard Henderson wrote:
>> On 3/20/25 15:29, Pierrick Bouvier wrote:
>>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>>> ---
>>>    hw/arm/armv7m.c | 12 ++++++++----
>>>    1 file changed, 8 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>>> index 98a69846119..c367c2dcb99 100644
>>> --- a/hw/arm/armv7m.c
>>> +++ b/hw/arm/armv7m.c
>>> @@ -139,8 +139,9 @@ static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
>>>        if (attrs.secure) {
>>>            /* S accesses to the alias act like NS accesses to the real region */
>>>            attrs.secure = 0;
>>> +        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
>>>            return memory_region_dispatch_write(mr, addr, value,
>>> -                                            size_memop(size) | MO_TE, attrs);
>>> +                                            size_memop(size) | end, attrs);
>>
>> target_words_bigendian() is always false for arm system mode.
>> Just s/TE/LE/.
>>
> 
> Good point.
> 
> By the way, what's the QEMU rationale behind having Arm big endian user binaries, and not 
> provide it for softmmu binaries?

For system mode, endianness is set via a combination of CPSR.E, SCTLR.B and SCTLR.EE, 
details depending on armv4, armv6, armv7+.

It is IMPLEMENTATION DEFINED how the cpu initiailizes at reset.  In olden times, via a 
board-level pin (sometimes switched, sometimes soldered).  We model the board-level pin 
via the "cfgend" cpu property.

In any case, for system mode we expect the guest to do the same thing it would need to do 
on real hardware.  For user mode, we can't do that, as we're also emulating the OS layer, 
which needs to know the endianness to expect from the guest binaries.

> If those systems are so rare, why would people need a user mode emulation?

IMO armbe-linux-user is extinct.

Debian never had big-endian support at all.  If there was some other distro which had it, 
I don't recall which.  Otherwise you'd need to bootstrap the entire toolchain, which to me 
seems rather beside the point.


r~

Re: [PATCH v2 26/30] hw/arm/armv7m: prepare compilation unit to be common
Posted by Pierrick Bouvier 1 week, 1 day ago
On 3/24/25 18:22, Richard Henderson wrote:
> On 3/24/25 14:31, Pierrick Bouvier wrote:
>> On 3/23/25 12:48, Richard Henderson wrote:
>>> On 3/20/25 15:29, Pierrick Bouvier wrote:
>>>> Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
>>>> ---
>>>>     hw/arm/armv7m.c | 12 ++++++++----
>>>>     1 file changed, 8 insertions(+), 4 deletions(-)
>>>>
>>>> diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
>>>> index 98a69846119..c367c2dcb99 100644
>>>> --- a/hw/arm/armv7m.c
>>>> +++ b/hw/arm/armv7m.c
>>>> @@ -139,8 +139,9 @@ static MemTxResult v7m_sysreg_ns_write(void *opaque, hwaddr addr,
>>>>         if (attrs.secure) {
>>>>             /* S accesses to the alias act like NS accesses to the real region */
>>>>             attrs.secure = 0;
>>>> +        MemOp end = target_words_bigendian() ? MO_BE : MO_LE;
>>>>             return memory_region_dispatch_write(mr, addr, value,
>>>> -                                            size_memop(size) | MO_TE, attrs);
>>>> +                                            size_memop(size) | end, attrs);
>>>
>>> target_words_bigendian() is always false for arm system mode.
>>> Just s/TE/LE/.
>>>
>>
>> Good point.
>>
>> By the way, what's the QEMU rationale behind having Arm big endian user binaries, and not
>> provide it for softmmu binaries?
> 
> For system mode, endianness is set via a combination of CPSR.E, SCTLR.B and SCTLR.EE,
> details depending on armv4, armv6, armv7+.
> 
> It is IMPLEMENTATION DEFINED how the cpu initiailizes at reset.  In olden times, via a
> board-level pin (sometimes switched, sometimes soldered).  We model the board-level pin
> via the "cfgend" cpu property.
> 
> In any case, for system mode we expect the guest to do the same thing it would need to do
> on real hardware.  For user mode, we can't do that, as we're also emulating the OS layer,
> which needs to know the endianness to expect from the guest binaries.
> 

Oh yes, totally makes sense. Thanks.

>> If those systems are so rare, why would people need a user mode emulation?
> 
> IMO armbe-linux-user is extinct.
> 
> Debian never had big-endian support at all.  If there was some other distro which had it,
> I don't recall which.  Otherwise you'd need to bootstrap the entire toolchain, which to me
> seems rather beside the point.
> 
> 
> r~