Unexpected behaviour in cpu module

classic Classic list List threaded Threaded
6 messages Options
Brian Thorne Brian Thorne
Reply | Threaded
Open this post in threaded view
|

Unexpected behaviour in cpu module

Hi all,

I came across some strange behaviour when writing to the first 8 bits of a 32 bit register from elua with cpu.w8. The lua code seems to write copies of the 8 bits to all other writeable bits in the targeted 32bit register; if the register has RO bits they are unaffected. I have seen this on two different boards (LM3S and an STM32F1). Is this expected and desired behaviour? If so could we make this clearer in the documentation?

Using cpu.w8 with hardware bitbanding from the micro's datasheet or using cpu.w32 were the two methods I found to successfully write to just the byte referenced.

Cheers,

Brian

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
BogdanM BogdanM
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behaviour in cpu module

Hi,

On Tue, Dec 6, 2011 at 11:21 PM, Brian Thorne <[hidden email]> wrote:
Hi all,

I came across some strange behaviour when writing to the first 8 bits of a 32 bit register from elua with cpu.w8. The lua code seems to write copies of the 8 bits to all other writeable bits in the targeted 32bit register; if the register has RO bits they are unaffected. I have seen this on two different boards (LM3S and an STM32F1). Is this expected and desired behaviour? If so could we make this clearer in the documentation?

Using cpu.w8 with hardware bitbanding from the micro's datasheet or using cpu.w32 were the two methods I found to successfully write to just the byte referenced.

The code for cpu.w8 looks OK to me. I believe that some CPU registers are simply not byte addressable. Try cpu.w8 on a memory location (for example a fixed RAM address); if it works as expected, the problem is definitely in the hardware.

Best,
Bogdan
 

Cheers,

Brian

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev



_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Brian Thorne Brian Thorne
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behaviour in cpu module

Thanks for the reply Bogdan,

So cpu.w8 works as expected for SRAM addresses but not for peripheral registers.

Looking at the code in cpu.c the implementation appears to be entirely platform independent, and reading the memory model documentation for the LM3S it doesn't specify any behaviour like this. Does it not seem odd that two different chips would have the same hardware problem?

Cheers,

On 7 December 2011 10:33, Bogdan Marinescu <[hidden email]> wrote:
Hi,

On Tue, Dec 6, 2011 at 11:21 PM, Brian Thorne <[hidden email]> wrote:
Hi all,

I came across some strange behaviour when writing to the first 8 bits of a 32 bit register from elua with cpu.w8. The lua code seems to write copies of the 8 bits to all other writeable bits in the targeted 32bit register; if the register has RO bits they are unaffected. I have seen this on two different boards (LM3S and an STM32F1). Is this expected and desired behaviour? If so could we make this clearer in the documentation?

Using cpu.w8 with hardware bitbanding from the micro's datasheet or using cpu.w32 were the two methods I found to successfully write to just the byte referenced.

The code for cpu.w8 looks OK to me. I believe that some CPU registers are simply not byte addressable. Try cpu.w8 on a memory location (for example a fixed RAM address); if it works as expected, the problem is definitely in the hardware.

Best,
Bogdan
 

Cheers,

Brian

 

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
jbsnyder jbsnyder
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behaviour in cpu module

In reply to this post by BogdanM
Both of the platforms you mention are ARM and Cortex-M3, so it's
perhaps not hugely surprising that they would exhibit similar
behavior.  Now as far as what is going on, the code for the function
that's being used (cpu_w8), generates the following code in gcc:
00018362 <cpu_w8>:
18362:       b538            push    {r3, r4, r5, lr}
18364:       2102            movs    r1, #2
18366:       4604            mov     r4, r0
18368:       f7f8 ffdf       bl      1132a <luaL_checkinteger>
1836c:       2101            movs    r1, #1
1836e:       4605            mov     r5, r0
18370:       4620            mov     r0, r4
18372:       f7f8 ffda       bl      1132a <luaL_checkinteger>
18376:       4620            mov     r0, r4
18378:       2101            movs    r1, #1
1837a:       f7f8 ffa9       bl      112d0 <luaL_checknumber>
1837e:       f00c fffb       bl      25378 <__aeabi_d2uiz>
18382:       7005            strb    r5, [r0, #0]
18384:       2000            movs    r0, #0
18386:       bd38            pop     {r3, r4, r5, pc}

I believe the strb near the end is probably what's important, where it
copies the value from r5 into an address in r0 with a zero offset.

According to this page (http://www.heyrick.co.uk/assembler/str.html):
A byte store (STRB) repeats the bottom 8 bits of the source register
four times across the data bus. The external memory system should
activate the appropriate byte subsystem to store the data.

I can't find exactly that same description in in the Cortex-M3
reference manuals, which seem to suggest that at least for memory
writes it should zero extend up to 32-bits, but I have found
references for other ARM parts that describe this same replication
behavior:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0087e/ch11s09s03.html

As far as a conclusion to this, I'm not sure what might be best if we
were to consider modifying the behavior of the module.  We could
certainly consider doing reading, masking and then writing registers,
but there are some registers that might be write-only.  Certainly it
would seem to be prudent to use 32-bit writes with registers of the
same size on ARM.


On Tue, Dec 6, 2011 at 3:33 PM, Bogdan Marinescu
<[hidden email]> wrote:

> Hi,
>
> On Tue, Dec 6, 2011 at 11:21 PM, Brian Thorne <[hidden email]> wrote:
>>
>> Hi all,
>>
>> I came across some strange behaviour when writing to the first 8 bits of a
>> 32 bit register from elua with cpu.w8. The lua code seems to write copies of
>> the 8 bits to all other writeable bits in the targeted 32bit register; if
>> the register has RO bits they are unaffected. I have seen this on two
>> different boards (LM3S and an STM32F1). Is this expected and desired
>> behaviour? If so could we make this clearer in the documentation?
>>
>> Using cpu.w8 with hardware bitbanding from the micro's datasheet or using
>> cpu.w32 were the two methods I found to successfully write to just the byte
>> referenced.
>
>
> The code for cpu.w8 looks OK to me. I believe that some CPU registers are
> simply not byte addressable. Try cpu.w8 on a memory location (for example a
> fixed RAM address); if it works as expected, the problem is definitely in
> the hardware.

Should there, perhaps, be some sort of option or command that would

>
> Best,
> Bogdan
>
>>
>>
>> Cheers,
>>
>> Brian
>>
>> _______________________________________________
>> eLua-dev mailing list
>> [hidden email]
>> https://lists.berlios.de/mailman/listinfo/elua-dev
>>
>
>
> _______________________________________________
> eLua-dev mailing list
> [hidden email]
> https://lists.berlios.de/mailman/listinfo/elua-dev
>
_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Ned Konz-2 Ned Konz-2
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behaviour in cpu module

In the STM32F reference manual RM0008, in section 2.1 under "AHB/APB
bridges" it says:
> When a 16- or 8-bit access is performed on an APB register, the access
> is transformed into
> a 32-bit access: the bridge duplicates the 16- or 8-bit data to feed
> the 32-bit vector.

And at least on the STM32F1xxx parts, you have to go through the AHB/APB
bridges to get to any of the peripheral registers.

It may be that you can safely use the strb instruction on core registers
that don't have to go through these bridges.

Generally, you want to access registers using the same width as the
register itself (though some registers may be documented as allowing
16-bit access).

On 12/06/2011 07:44 PM, James Snyder wrote:

> Both of the platforms you mention are ARM and Cortex-M3, so it's
> perhaps not hugely surprising that they would exhibit similar
> behavior.  Now as far as what is going on, the code for the function
> that's being used (cpu_w8), generates the following code in gcc:
> 00018362<cpu_w8>:
> 18362:       b538            push    {r3, r4, r5, lr}
> 18364:       2102            movs    r1, #2
> 18366:       4604            mov     r4, r0
> 18368:       f7f8 ffdf       bl      1132a<luaL_checkinteger>
> 1836c:       2101            movs    r1, #1
> 1836e:       4605            mov     r5, r0
> 18370:       4620            mov     r0, r4
> 18372:       f7f8 ffda       bl      1132a<luaL_checkinteger>
> 18376:       4620            mov     r0, r4
> 18378:       2101            movs    r1, #1
> 1837a:       f7f8 ffa9       bl      112d0<luaL_checknumber>
> 1837e:       f00c fffb       bl      25378<__aeabi_d2uiz>
> 18382:       7005            strb    r5, [r0, #0]
> 18384:       2000            movs    r0, #0
> 18386:       bd38            pop     {r3, r4, r5, pc}
>
> I believe the strb near the end is probably what's important, where it
> copies the value from r5 into an address in r0 with a zero offset.
>
> According to this page (http://www.heyrick.co.uk/assembler/str.html):
> A byte store (STRB) repeats the bottom 8 bits of the source register
> four times across the data bus. The external memory system should
> activate the appropriate byte subsystem to store the data.
>
> I can't find exactly that same description in in the Cortex-M3
> reference manuals, which seem to suggest that at least for memory
> writes it should zero extend up to 32-bits, but I have found
> references for other ARM parts that describe this same replication
> behavior:
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0087e/ch11s09s03.html
>
> As far as a conclusion to this, I'm not sure what might be best if we
> were to consider modifying the behavior of the module.  We could
> certainly consider doing reading, masking and then writing registers,
> but there are some registers that might be write-only.  Certainly it
> would seem to be prudent to use 32-bit writes with registers of the
> same size on ARM.
>
>
> On Tue, Dec 6, 2011 at 3:33 PM, Bogdan Marinescu
> <[hidden email]>  wrote:
>> Hi,
>>
>> On Tue, Dec 6, 2011 at 11:21 PM, Brian Thorne<[hidden email]>  wrote:
>>> Hi all,
>>>
>>> I came across some strange behaviour when writing to the first 8 bits of a
>>> 32 bit register from elua with cpu.w8. The lua code seems to write copies of
>>> the 8 bits to all other writeable bits in the targeted 32bit register; if
>>> the register has RO bits they are unaffected. I have seen this on two
>>> different boards (LM3S and an STM32F1). Is this expected and desired
>>> behaviour? If so could we make this clearer in the documentation?
>>>
>>> Using cpu.w8 with hardware bitbanding from the micro's datasheet or using
>>> cpu.w32 were the two methods I found to successfully write to just the byte
>>> referenced.
>>
>> The code for cpu.w8 looks OK to me. I believe that some CPU registers are
>> simply not byte addressable. Try cpu.w8 on a memory location (for example a
>> fixed RAM address); if it works as expected, the problem is definitely in
>> the hardware.
> Should there, perhaps, be some sort of option or command that would
>
>> Best,
>> Bogdan
>>
>>>
>>> Cheers,
>>>
>>> Brian
>>>
>>> _______________________________________________
>>> eLua-dev mailing list
>>> [hidden email]
>>> https://lists.berlios.de/mailman/listinfo/elua-dev
>>>
>>
>> _______________________________________________
>> eLua-dev mailing list
>> [hidden email]
>> https://lists.berlios.de/mailman/listinfo/elua-dev
>>
> _______________________________________________
> eLua-dev mailing list
> [hidden email]
> https://lists.berlios.de/mailman/listinfo/elua-dev

--
Ned Konz
Product Creation | Studio
425 Westlake Av. N
Seattle, WA 98109
PH 206-297-7200
http://productcreationstudio.com

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev
Brian Thorne Brian Thorne
Reply | Threaded
Open this post in threaded view
|

Re: Unexpected behaviour in cpu module

Thank you very much for looking into this. I also couldn't find any reference of this behaviour in the ARM Cortex-M3 official documentation of the instruction set. No matter, I will just make sure to use 32bit instructions to access the 32bit registers.
Cheers,
Brian

On 8 December 2011 07:52, Ned Konz <[hidden email]> wrote:
In the STM32F reference manual RM0008, in section 2.1 under "AHB/APB bridges" it says:
When a 16- or 8-bit access is performed on an APB register, the access is transformed into
a 32-bit access: the bridge duplicates the 16- or 8-bit data to feed the 32-bit vector.

And at least on the STM32F1xxx parts, you have to go through the AHB/APB bridges to get to any of the peripheral registers.

It may be that you can safely use the strb instruction on core registers that don't have to go through these bridges.

Generally, you want to access registers using the same width as the register itself (though some registers may be documented as allowing 16-bit access).


On 12/06/2011 07:44 PM, James Snyder wrote:
Both of the platforms you mention are ARM and Cortex-M3, so it's
perhaps not hugely surprising that they would exhibit similar
behavior.  Now as far as what is going on, the code for the function
that's being used (cpu_w8), generates the following code in gcc:
00018362<cpu_w8>:
18362:       b538            push    {r3, r4, r5, lr}
18364:       2102            movs    r1, #2
18366:       4604            mov     r4, r0
18368:       f7f8 ffdf       bl      1132a<luaL_checkinteger>
1836c:       2101            movs    r1, #1
1836e:       4605            mov     r5, r0
18370:       4620            mov     r0, r4
18372:       f7f8 ffda       bl      1132a<luaL_checkinteger>
18376:       4620            mov     r0, r4
18378:       2101            movs    r1, #1
1837a:       f7f8 ffa9       bl      112d0<luaL_checknumber>
1837e:       f00c fffb       bl      25378<__aeabi_d2uiz>
18382:       7005            strb    r5, [r0, #0]
18384:       2000            movs    r0, #0
18386:       bd38            pop     {r3, r4, r5, pc}

I believe the strb near the end is probably what's important, where it
copies the value from r5 into an address in r0 with a zero offset.

According to this page (http://www.heyrick.co.uk/assembler/str.html):
A byte store (STRB) repeats the bottom 8 bits of the source register
four times across the data bus. The external memory system should
activate the appropriate byte subsystem to store the data.

I can't find exactly that same description in in the Cortex-M3
reference manuals, which seem to suggest that at least for memory
writes it should zero extend up to 32-bits, but I have found
references for other ARM parts that describe this same replication
behavior:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0087e/ch11s09s03.html

As far as a conclusion to this, I'm not sure what might be best if we
were to consider modifying the behavior of the module.  We could
certainly consider doing reading, masking and then writing registers,
but there are some registers that might be write-only.  Certainly it
would seem to be prudent to use 32-bit writes with registers of the
same size on ARM.


On Tue, Dec 6, 2011 at 3:33 PM, Bogdan Marinescu
<[hidden email]>  wrote:
Hi,

On Tue, Dec 6, 2011 at 11:21 PM, Brian Thorne<[hidden email]>  wrote:
Hi all,

I came across some strange behaviour when writing to the first 8 bits of a
32 bit register from elua with cpu.w8. The lua code seems to write copies of
the 8 bits to all other writeable bits in the targeted 32bit register; if
the register has RO bits they are unaffected. I have seen this on two
different boards (LM3S and an STM32F1). Is this expected and desired
behaviour? If so could we make this clearer in the documentation?

Using cpu.w8 with hardware bitbanding from the micro's datasheet or using
cpu.w32 were the two methods I found to successfully write to just the byte
referenced.

The code for cpu.w8 looks OK to me. I believe that some CPU registers are
simply not byte addressable. Try cpu.w8 on a memory location (for example a
fixed RAM address); if it works as expected, the problem is definitely in
the hardware.
Should there, perhaps, be some sort of option or command that would

Best,
Bogdan


Cheers,

Brian

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev

_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev

--
Ned Konz
Product Creation | Studio
425 Westlake Av. N
Seattle, WA 98109
PH <a href="tel:206-297-7200" value="+12062977200" target="_blank">206-297-7200
http://productcreationstudio.com


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev


_______________________________________________
eLua-dev mailing list
[hidden email]
https://lists.berlios.de/mailman/listinfo/elua-dev