diff mbox series

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

Message ID 20250320223002.2915728-27-pierrick.bouvier@linaro.org
State New
Headers show
Series single-binary: start make hw/arm/ common | expand

Commit Message

Pierrick Bouvier March 20, 2025, 10:29 p.m. UTC
Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
---
 hw/arm/armv7m.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

Comments

Richard Henderson March 23, 2025, 7:48 p.m. UTC | #1
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~
Pierrick Bouvier March 24, 2025, 9:31 p.m. UTC | #2
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~
Richard Henderson March 25, 2025, 1:22 a.m. UTC | #3
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~
Pierrick Bouvier March 25, 2025, 1:48 a.m. UTC | #4
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~
diff mbox series

Patch

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);
 }