Re: [Openocd-development] MIPS target, big endian host

2011-08-09 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 1:50 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Yes, if BE target shifts out an 32 bit value from address 0, it will
 begin with bit0:7, that is byte address 0x03 at targets memory.

 And host will do the same. When it shifts out 32-bit value , it will
 put contents of it's address 0x3 to output buffer[0] and send this
 first.
 I am talking about BE host, off course.

 LE host will put contents of it's 0x0 address to buffer[0] and send
 this out first.

 Yes, that's the way buf_get_u32 and buf_set_u32 works.

OK,
I think that things are clear now, and as I see it patching all the
functions in PrAcc as you suggested seem to be realistic fix...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-08-09 Thread Drasko DRASKOVIC
BTW,
Stefan and all others,
thank you very much for this long discussion and for the effort on
explaining things. I think it was very useful.

BR,
Drasko

On Tue, Aug 9, 2011 at 11:20 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 1:50 PM, Mahr, Stefan stefan.m...@sphairon.com 
 wrote:
 Yes, if BE target shifts out an 32 bit value from address 0, it will
 begin with bit0:7, that is byte address 0x03 at targets memory.

 And host will do the same. When it shifts out 32-bit value , it will
 put contents of it's address 0x3 to output buffer[0] and send this
 first.
 I am talking about BE host, off course.

 LE host will put contents of it's 0x0 address to buffer[0] and send
 this out first.

 Yes, that's the way buf_get_u32 and buf_set_u32 works.

 OK,
 I think that things are clear now, and as I see it patching all the
 functions in PrAcc as you suggested seem to be realistic fix...

 BR,
 Drasko

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Mahr, Stefan
 buf_get_u32:
                return (((uint32_t)buffer[3])  24) |
                        (((uint32_t)buffer[2])  16) |
                        (((uint32_t)buffer[1])  8) |
                        (((uint32_t)buffer[0])  0);


 I do not get this function at all... What I see is that it is presumed
 that host executing this code must be in the same endianess as the
 target who filled this buffer. Otherwise bytes get flipped.
 
 Here is an experiment :
 Let's imagine that target is BE. Then it will put word 0x12345678 read
 from the it's (target's) mem like this :
 buffer[0] = 0x12
 buffer [1] = 0x34
 buffer[2] = 0x56
 buffer[3] = 0x78

Let's forget target endianness for a moment. If you buffer is filled like above,
LE host will do following:

result =  (uint32_t)buffer[0]  0; //  result = 0x0012  or in memory 
0x12 0x00 0x00 0x00
result |= (uint32_t)buffer[1]  8; //  result = 0x3412  or in memory 
0x12 0x34 0x00 0x00
result |= (uint32_t)buffer[2]  16;//  result = 0x00563412  or in memory 
0x12 0x34 0x56 0x00
result |= (uint32_t)buffer[3]  24;//  result = 0x78563412  or in memory 
0x12 0x34 0x56 0x78

BE host will do:

result =  (uint32_t)buffer[0]  0; //  result = 0x0012  or in memory 
0x00 0x00 0x00 0x12
result |= (uint32_t)buffer[1]  8; //  result = 0x3412  or in memory 
0x00 0x00 0x34 0x12
result |= (uint32_t)buffer[2]  16;//  result = 0x00563412  or in memory 
0x00 0x56 0x34 0x12
result |= (uint32_t)buffer[3]  24;//  result = 0x78563412  or in memory 
0x78 0x56 0x34 0x12

As you see result is always the same, but order in memory differs depending on 
host endianness.
This is what I mean when I say it's ensured the result is in host endianness.

If you would simply cast the buffer, result would be swapped:
LE host:  result = (uint32_t)buffer[0];// result = 0x78563412  (memory 0x12 
0x34 0x56 0x78)
BE host:  result = (uint32_t)buffer[0];// result = 0x12345678  (memory 0x12 
0x34 0x56 0x78)


 What is funny however, is that I have BE target and LE host, and MIPS
 code seems to be working fine... Which would say that EJTAG somehow
 speaks LE with my host. Crazy thing.

 Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to 
 bits 23:16, and byte 3 refers to bits
 31:24, independent of endianess.

 My guess is, if you read out a 32bit value, target endianness doesn't matter.
 This is the only sane solution I can think of. It would say that EJTAG
 is a bi-endian machine that can read both BE and LE if we feed it
 fixed instr. size.

No, there is no bi-endian machine.

The sentence Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 
refers to bits 23:16, and byte 3
refers to bits 31:24, independent of endianess. says for me that EJTAG is 
always LE, no matter of target
endianness setting.


___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Øyvind Harboe
On Mon, Jul 11, 2011 at 12:17 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 7:31 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 Now a sequence of 8 bit words happens to be identical to
 little endian representation
 In what way ? 8 bits is 8 bits - one byte, bits 7:0. I do not see BE
 or LE representation here...

Consider a series of words in memory where the width is greater than 8.

Clearly a BE series has a different representation than a LE version.

For a series of words that are 8 bits long, then the BE series and
LE series are identical.

Further, if you have 32 bits stored in a series of bytes in memory,
then the memory layout is identical to the memory layout of
little endian layout.


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 12:31 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 On Mon, Jul 11, 2011 at 12:17 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 7:31 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 Now a sequence of 8 bit words happens to be identical to
 little endian representation
 In what way ? 8 bits is 8 bits - one byte, bits 7:0. I do not see BE
 or LE representation here...

 Consider a series of words in memory where the width is greater than 8.

 Clearly a BE series has a different representation than a LE version.

 For a series of words that are 8 bits long, then the BE series and
 LE series are identical.

 Further, if you have 32 bits stored in a series of bytes in memory,
 then the memory layout is identical to the memory layout of
 little endian layout.

Sorry Øyvind,
I did not get at first that you meant on this - a byte array in the
mem. Yes, I agree, it has LE order when memory is observed (which is
one of the main arguments of the LE camp why LE is natural).

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 11:53 AM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 I think there is a fundamental misunderstanding about JTAG
 and OpenOCD.

 Let me try to clarify:

 JTAG clocks in and out bits, not bytes, so the concept of
 big/small-endian does not enter the picture at the JTAG level.

Sat that we have 0x12345678 at addr 0x0 on LE host.
You will shift out byte 0x78 first, shifting out from LSB upwards.
I.e. You will be starting with shifting out addr 0x0 on the host.
Now, if the host is BE, you will again be shifting LSB first, but this
time that means that you will be starting withs shifting out addr 0x3
(on the host) first.

Am I correct so far ?


At what addr will EJTAG on the other side write this byte ? At addr
0x0, or addr 0x03 - this is the main question.

If it is LE, Byte0, as they say in manual, will be put to 0x0, and if
it is BE MIPS, it will be put always to 0x3.

So, the first 8 bits that MIPS EJTAG shifts in, which will be noted
Byte0 in their terminology and represent bits 7:0, will be put to
either addr 0x0 or 0x3 - depending on endianess of the MIPS target.

That would say to me that MIPS EJTAG is actually doing following :
1) Takes the value of Byte0, in this case 0x78
2) Cast it to uint32_t, getting 0x0078
3) Stores the word in memory - and if it is BE MIPS, 0x78 byte will
end-up on addr 0x3.

This way, EJTAG is endianess-agnostic - it really do not care about
your host endianess, as long as you are are sending it LSB fist. It
will arrange then to store the Byte0 at appropriate address once it
gathers bits 7:0.

This is what I think.

Now, when EJTAG is sending back data to the host, it will also send
LSB first, i.e. it's Byte0. But in the case of BE, this Byte0 lives on
the address 0x3, so it will start with sending addr 0x3.

When receives data as a byte array, host can not give any conclusions
about target endianess. It just know that it gets LSB first, and we
have to use buf_get_u32() to make some meaning on the host of a byte
array value that came.

This way target endianess is completely unimportant to the OpenOCD,
and we can not even know it by observing bytes that come we will
always see LSB coming first.

Does this all makes sense for you ?


BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Mahr, Stefan

Sorry, little mistake:

wrong:
 LE host:  result = (uint32_t)buffer[0];    // result = 0x78563412  (memory 
 0x12 0x34 0x56 0x78)
 BE host:  result = (uint32_t)buffer[0];    // result = 0x12345678  (memory 
 0x12 0x34 0x56 0x78)

corrected:
LE host:  result = *(uint32_t*)buffer[0];// result = 0x78563412  (memory 
0x12 0x34 0x56 0x78)
BE host:  result = *(uint32_t*)buffer[0];// result = 0x12345678  (memory 
0x12 0x34 0x56 0x78)

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Øyvind Harboe
On Mon, Jul 11, 2011 at 12:45 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 11:53 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 I think there is a fundamental misunderstanding about JTAG
 and OpenOCD.

 Let me try to clarify:

 JTAG clocks in and out bits, not bytes, so the concept of
 big/small-endian does not enter the picture at the JTAG level.

 Sat that we have 0x12345678 at addr 0x0 on LE host.
 You will shift out byte 0x78 first, shifting out from LSB upwards.

You're on the wrong track here. Shifting out happens with *bits*.

So the situation is:

- you have a host word. 8, 16, 32 or 64 bit wide.
- that word must be copied over to an array of bytes to be shifted out.
At this point any memory of host representation is gone.
- the jtag layer now shifts out the bits, starting with bit 0 in byte 0.
- the target receives the bits in order completely oblivious to how you
put them on the wire.



-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 12:52 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 On Mon, Jul 11, 2011 at 12:45 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 11:53 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 I think there is a fundamental misunderstanding about JTAG
 and OpenOCD.

 Let me try to clarify:

 JTAG clocks in and out bits, not bytes, so the concept of
 big/small-endian does not enter the picture at the JTAG level.

 Sat that we have 0x12345678 at addr 0x0 on LE host.
 You will shift out byte 0x78 first, shifting out from LSB upwards.

 You're on the wrong track here. Shifting out happens with *bits*.
When I said LSB I meant Least Significant *Bit*, not *Byte*.


 So the situation is:

 - you have a host word. 8, 16, 32 or 64 bit wide.
 - that word must be copied over to an array of bytes to be shifted out.
 At this point any memory of host representation is gone.
 - the jtag layer now shifts out the bits, starting with bit 0 in byte 0.
What is byte 0 for you ?

I'd say, on a BE host it lives at addr 0x3. On LE host it lives at addr 0x0.

When you start shifting out LSB (bit) from the BE host, will you start
shifting out contents of address 0x3, or the address 0x0 ? In my
opinion, it will be content of the addr 0x3 that will be shifted out
first (as it holds bits 0:7 for on the BE host).

 - the target receives the bits in order completely oblivious to how you
 put them on the wire.

Yes - it receives LSB (bit) first.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Øyvind Harboe
On Mon, Jul 11, 2011 at 1:10 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 12:52 PM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 On Mon, Jul 11, 2011 at 12:45 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 11:53 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 I think there is a fundamental misunderstanding about JTAG
 and OpenOCD.

 Let me try to clarify:

 JTAG clocks in and out bits, not bytes, so the concept of
 big/small-endian does not enter the picture at the JTAG level.

 Sat that we have 0x12345678 at addr 0x0 on LE host.
 You will shift out byte 0x78 first, shifting out from LSB upwards.

 You're on the wrong track here. Shifting out happens with *bits*.
 When I said LSB I meant Least Significant *Bit*, not *Byte*.


 So the situation is:

 - you have a host word. 8, 16, 32 or 64 bit wide.
 - that word must be copied over to an array of bytes to be shifted out.
 At this point any memory of host representation is gone.
 - the jtag layer now shifts out the bits, starting with bit 0 in byte 0.
 What is byte 0 for you ?

An array of bytes as an unambiguous representation in memory and
C programming model. When I say byte 0 of an array of bytes, there is
no question about what that is.

OpenOCD shifts out an array of bytes LSB first.



-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Mahr, Stefan
Øyvind Harboe wrote:
 Really OpenOCD could have stored the bits as a series of
 words larger than bytes in the host representation to be more
 efficient.

This would probably be a source of much more confusion :-)

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 1:30 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 On Mon, Jul 11, 2011 at 1:10 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 12:52 PM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 On Mon, Jul 11, 2011 at 12:45 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Mon, Jul 11, 2011 at 11:53 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 I think there is a fundamental misunderstanding about JTAG
 and OpenOCD.

 Let me try to clarify:

 JTAG clocks in and out bits, not bytes, so the concept of
 big/small-endian does not enter the picture at the JTAG level.

 Sat that we have 0x12345678 at addr 0x0 on LE host.
 You will shift out byte 0x78 first, shifting out from LSB upwards.

 You're on the wrong track here. Shifting out happens with *bits*.
 When I said LSB I meant Least Significant *Bit*, not *Byte*.


 So the situation is:

 - you have a host word. 8, 16, 32 or 64 bit wide.
 - that word must be copied over to an array of bytes to be shifted out.
 At this point any memory of host representation is gone.
 - the jtag layer now shifts out the bits, starting with bit 0 in byte 0.
 What is byte 0 for you ?

 An array of bytes as an unambiguous representation in memory and
 C programming model. When I say byte 0 of an array of bytes, there is
 no question about what that is.

This is not arguable. What I am asking you here is how do you create
this array of bytes you want to shift out ?

I'd say - on BE host, when you want to shift out word you put addr 0x3
to be shifted out first, and then in the end addr 0x0, because LSB of
your value lives on addr 0x3.

Here is how you prepare your shift-out buffer of 8-bit long elements :
buffer[0] = (contents_of_the_host_addr 0x3);
buffer[1] = (contents_of_the_host_addr 0x2);
buffer[2] = (contents_of_the_host_addr 0x1);
buffer[3] = (contents_of_the_host_addr 0x0);

And then you shift out buffer[0] first, then buffer[1], etc.

Which would in the end say - when you want to shift 32-bit word from
the BE host, it will be contents addr 0x3 that will be going out on
the wire first, this is all I am trying to say.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Mahr, Stefan
 When you start shifting out LSB (bit) from the BE host, will you start
 shifting out contents of address 0x3, or the address 0x0 ? In my
 opinion, it will be content of the addr 0x3 that will be shifted out
 first (as it holds bits 0:7 for on the BE host).

Yes, if BE target shifts out an 32 bit value from address 0, it will
begin with bit0:7, that is byte address 0x03 at targets memory.
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 1:41 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 When you start shifting out LSB (bit) from the BE host, will you start
 shifting out contents of address 0x3, or the address 0x0 ? In my
 opinion, it will be content of the addr 0x3 that will be shifted out
 first (as it holds bits 0:7 for on the BE host).

 Yes, if BE target shifts out an 32 bit value from address 0, it will
 begin with bit0:7, that is byte address 0x03 at targets memory.

And host will do the same. When it shifts out 32-bit value , it will
put contents of it's address 0x3 to output buffer[0] and send this
first.
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Drasko DRASKOVIC
On Mon, Jul 11, 2011 at 1:43 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 Yes, if BE target shifts out an 32 bit value from address 0, it will
 begin with bit0:7, that is byte address 0x03 at targets memory.

 And host will do the same. When it shifts out 32-bit value , it will
 put contents of it's address 0x3 to output buffer[0] and send this
 first.
I am talking about BE host, off course.

LE host will put contents of it's 0x0 address to buffer[0] and send
this out first.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-11 Thread Mahr, Stefan
 Yes, if BE target shifts out an 32 bit value from address 0, it will
 begin with bit0:7, that is byte address 0x03 at targets memory.

 And host will do the same. When it shifts out 32-bit value , it will
 put contents of it's address 0x3 to output buffer[0] and send this
 first.
 I am talking about BE host, off course.

 LE host will put contents of it's 0x0 address to buffer[0] and send
 this out first.

Yes, that's the way buf_get_u32 and buf_set_u32 works.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-10 Thread Drasko DRASKOVIC
On Sat, Jul 9, 2011 at 10:44 AM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 How do they convert then, when they do not know from which endianes to
 convert from ?

 Conversion is done from byte array of jtag chain.
 How ?

 buf_get_u32 does conversion from uint8* array

 example:
 mips_ejtag_get_impcode (mips_ejtag.c)

  field.in_value is filled by jtag_add_dr_scan with 4 times uint8.
  buf_get_u32 converts byte array to host endian uint32

 How ? It does not convert anything. It just takes the data and puts it
 into array, in the order that it comes.

 No, you do *arithmetical* operations on host, so it is ensured that result is 
 always in host endianness.

 buf_get_u32:
                return (((uint32_t)buffer[3])  24) |
                        (((uint32_t)buffer[2])  16) |
                        (((uint32_t)buffer[1])  8) |
                        (((uint32_t)buffer[0])  0);


I do not get this function at all... What I see is that it is presumed
that host executing this code must be in the same endianess as the
target who filled this buffer. Otherwise bytes get flipped.

Here is an experiment :
Let's imagine that target is BE. Then it will put word 0x12345678 read
from the it's (target's) mem like this :
buffer[0] = 0x12
buffer [1] = 0x34
buffer[2] = 0x56
buffer[3] = 0x78

Because BE keeps MSB on lower addr.

On the LE host, function buf_get_u32() will shift 0x78 to addr 0x3,
0x56 to addr 0x2, etc and you will get :
 | 78 | 56 | 34  | 12 | --- value (hex)
 |  3  |  2  |  1  | 0   | --- addr

i.e, you will have 0x78453412 as a return on a LE host, which is, ay
you see, flipped value.
It is because you kept MSB part put by the target in beuffer[0] on
your host's addr 0x0, i.e. you did not shift it you addr 0x3.
On LE arch MSB is kept on higher addresses.

Similar will happen if you have LE target and BE host.

That's why I do not think that this function was ever meant to do any
conversion to host's endianess, as you say. What I thing is that it is
a function that *must* be used locally on the host, and *only* on the
data filled by the host, because then we are guaranteed that the
person who fills the buffer[] is the same who reads it, i.e. endianess
is same for the reader and for the writer.

Do you agree with me on this, or am I missing something ?


What is funny however, is that I have BE target and LE host, and MIPS
code seems to be working fine... Which would say that EJTAG somehow
speaks LE with my host. Crazy thing.



 The endianness of MIPS EJTAG tap seems to have always the same endianness,
 no matter of MIPS CPU memory endianness.
 What makes you think so ?

 Because openocd works in all combinations of BE and LE host and target. (If 
 you
 revert commit 2482244b0788c007dd789c21a4416379c229ea5c.) So yes, it's just 
 a guess.

 Which might mean that all commands are sent to EJTAG in appropriate
 target format in which CPU expects them (be it BE or LE, depends in
 which mode it runs).

 I can't find code that swaps target endianness in mips32_pracc.c or 
 mips_ejtag.c


 Could this be the explanation:

 http://downloads.buffalo.nas-central.org/LS2_MIPSel/DevelopmentTools/JTAG/MD00047-2B-EJTAG-SPC-03.10.pdf
 Page 97:
 Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to 
 bits 23:16, and byte 3 refers to bits
 31:24, independent of endianess.

 This is _always_ the case in _all_ architectures. But, as you see,
 this Byte0 is put to lower addresses for LE and to higher for BE. This
 is always the case.

 Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to bits 
 23:16, and byte 3 refers to bits
 31:24, independent of endianess.

 My guess is, if you read out a 32bit value, target endianness doesn't matter.

This is the only sane solution I can think of. It would say that EJTAG
is a bi-endian machine that can read both BE and LE if we feed it
fixed instr. size.

Do you know some examples of architectures (bi-endian) like this ? How
can it exactly guess the endianess of the program and adopt itself
appropriately ?

 If a 8bit value is read out, you get byte0 for address 0 in LE mode and byte3 
 at address 0 in BE mode.

OK, but this does not change anything for any architecture in the
world, as I said - this chapter is just the MIPS terminology, theirs
notation, nothing significant there, IMHO.

As I said, for value 0x12345678, on BE byte0 is bits 7..0 = 0x78.
Reading addr 0x0 you will get MSB on BE, as it stores MSB on lower
addr, so you will get 0x12, which is in MIPS (or any other notation)
byte3 of the 4-byte value, as it holds MSB, i.e. bits 31..28.

As I said, I do not see nothing special there, but it might be that I
am missing something you want to point out.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-10 Thread Øyvind Harboe
  buf_get_u32:
                 return (((uint32_t)buffer[3])  24) |
                         (((uint32_t)buffer[2])  16) |
                         (((uint32_t)buffer[1])  8) |
                         (((uint32_t)buffer[0])  0);
 

 I do not get this function at all... What I see is that it is presumed
 that host executing this code must be in the same endianess as the
 target who filled this buffer. Otherwise bytes get flipped.

I'm jumping into this discussion with something I hope will
be useful.

The JTAG functions use a sequence of 8 bit words to
represent the data that is being clocked in-out. It could have
been a sequence of, say, 32 or 64 bit words.

Now a sequence of 8 bit words happens to be identical to
little endian representation, which is a source of much confusion, I'd say.



--
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-09 Thread Mahr, Stefan
 How do they convert then, when they do not know from which endianes to
 convert from ?

 Conversion is done from byte array of jtag chain.
 How ?

 buf_get_u32 does conversion from uint8* array

 example:
 mips_ejtag_get_impcode (mips_ejtag.c)

  field.in_value is filled by jtag_add_dr_scan with 4 times uint8.
  buf_get_u32 converts byte array to host endian uint32

 How ? It does not convert anything. It just takes the data and puts it
 into array, in the order that it comes.

No, you do *arithmetical* operations on host, so it is ensured that result is 
always in host endianness.

buf_get_u32:
return (((uint32_t)buffer[3])  24) |
(((uint32_t)buffer[2])  16) |
(((uint32_t)buffer[1])  8) |
(((uint32_t)buffer[0])  0);



 The endianness of MIPS EJTAG tap seems to have always the same endianness,
 no matter of MIPS CPU memory endianness.
 What makes you think so ?

 Because openocd works in all combinations of BE and LE host and target. (If 
 you
 revert commit 2482244b0788c007dd789c21a4416379c229ea5c.) So yes, it's just a 
 guess.

 Which might mean that all commands are sent to EJTAG in appropriate
 target format in which CPU expects them (be it BE or LE, depends in
 which mode it runs).

I can't find code that swaps target endianness in mips32_pracc.c or mips_ejtag.c


 Could this be the explanation:

 http://downloads.buffalo.nas-central.org/LS2_MIPSel/DevelopmentTools/JTAG/MD00047-2B-EJTAG-SPC-03.10.pdf
 Page 97:
 Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to bits 
 23:16, and byte 3 refers to bits
 31:24, independent of endianess.

 This is _always_ the case in _all_ architectures. But, as you see,
 this Byte0 is put to lower addresses for LE and to higher for BE. This
 is always the case.

Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to bits 
23:16, and byte 3 refers to bits
31:24, independent of endianess.

My guess is, if you read out a 32bit value, target endianness doesn't matter. 
If a 8bit value is read out, you get byte0 for address 0 in LE mode and byte3 
at address 0 in BE mode.


BR,
Stefan

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
On Fri, Jul 8, 2011 at 11:43 AM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Thu, Jul 7, 2011 at 11:58 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 Note that this problem has cropped up many places over the OpenOCD
 code. I'd like to get rid of it once and for all

 I absolutely intend to fix it for MIPS, but I'd like a good long term 
 solution.

 With jtag queue callbacks, a user data pointer to the callback is cast to
 a void pointer, then cast back to e.g. uint32_t *. Casting to/from void *
 does not yield a warning(should not anyway, right?),
 Why shouldn't it ? I mean, you can have unaligned acces by casting
 void* to unaligned addr to uint32* and then reference, right ?

Such warnings would be hopelessly noisy. A callback generally
takes a pointer to *something* and then inside the callback you cast
back the pointer to whatever you *know* you passed in.

Of course C++ the whole casting business is much more advanced than
i C.

 From my point of view casting uint8_t* to uint32* is dangerous as
 casting void* to uint32_t*. Isee no difference, as void* can point to
 unaligned addr.

There is no difference in danger, but what the compiler is telling
you is that if you do need to have a generic pointer, then use void *,
not uint8_t *.

-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 11:47 AM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 On Fri, Jul 8, 2011 at 11:43 AM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Thu, Jul 7, 2011 at 11:58 AM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 Note that this problem has cropped up many places over the OpenOCD
 code. I'd like to get rid of it once and for all

 I absolutely intend to fix it for MIPS, but I'd like a good long term 
 solution.

 With jtag queue callbacks, a user data pointer to the callback is cast to
 a void pointer, then cast back to e.g. uint32_t *. Casting to/from void *
 does not yield a warning(should not anyway, right?),
 Why shouldn't it ? I mean, you can have unaligned acces by casting
 void* to unaligned addr to uint32* and then reference, right ?

 Such warnings would be hopelessly noisy. A callback generally
 takes a pointer to *something* and then inside the callback you cast
 back the pointer to whatever you *know* you passed in.

 Of course C++ the whole casting business is much more advanced than
 i C.

 From my point of view casting uint8_t* to uint32* is dangerous as
 casting void* to uint32_t*. Isee no difference, as void* can point to
 unaligned addr.

 There is no difference in danger, but what the compiler is telling
 you is that if you do need to have a generic pointer, then use void *,
 not uint8_t *.

OK, I am starting to get this... Thanks  Øyvind.

But looking from to the code, I see no explicit casting uint8_t* to
uint32_t in mips_pracc code. Where did you exactly run into compiler
warning ?

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Thu, Jul 7, 2011 at 11:52 AM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 011/7/7 Mahr, Stefan stefan.m...@sphairon.com:
 Øyvind Harboe wrote:
 It is not obvious at all from the context that there is an alignment
 guarantee.

 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?

 Why?

 http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd;a=blob;f=src/target/mips32_pracc.c;h=af60d321638652aad0a52a573add2aceacbfb7d9;hb=HEAD#l310


 = this is strange, why cast to uint8_t ?

 return mips32_pracc_read_mem16(ejtag_info, addr, count, (uint8_t*)buf);

There is no particular need to cast this into uint8_t* and this can be
kept as a void*. Would that suppress the warnings ?

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
 There is no particular need to cast this into uint8_t* and this can be
 kept as a void*. Would that suppress the warnings ?

It does look like this code is using uint8_t * in lieu of void *...

I think it would suppress the warnings, yes.


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
On Fri, Jul 8, 2011 at 12:31 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Fri, Jul 8, 2011 at 12:14 PM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 There is no particular need to cast this into uint8_t* and this can be
 kept as a void*. Would that suppress the warnings ?

 It does look like this code is using uint8_t * in lieu of void *...

 Why ? It is just an address of 1-byte placeholder to which you would
 like to copy byte read from the memory.

It's not about what you do, it is about telling the compiler as much
as possible about the types so that it can check for problems.

I don't know the code too well to comment about which types
should be used. Especially with big/small endian...


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 12:14 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 There is no particular need to cast this into uint8_t* and this can be
 kept as a void*. Would that suppress the warnings ?

 It does look like this code is using uint8_t * in lieu of void *...

Why ? It is just an address of 1-byte placeholder to which you would
like to copy byte read from the memory.

All you have to do late is to copy values read into each memeber of
uint32_t array to each corresponding member of uint8_t array.
This loop :
for (i = 0; i  count; i++)
{
buf[i] = param_out[i];
}
I see no problem of alignment there, as actually uint32_t will be
casted to uint8_t, which should be OK (while the other way around is
dangerous).



But even that can be avoided, as

retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
ARRAY_SIZE(param_in), param_in, count, param_out, 1);

will get you values in param_out[] array. This array is an array of
uint32_t values, I do not know for which reason...

Actually, copy from RAM address to our buffer is done in this loop :

/* loop */
MIPS32_BEQ(0,10,8), 
/* beq 0, $10, end */
MIPS32_NOP,

MIPS32_LBU(8,0,9),  
/* lw $8,0($9), Load t4 with the byte @mem[t1] */
MIPS32_SW(8,0,11),  
/* sw $8,0($11) */

MIPS32_ADDI(10,10,NEG16(1)),
/* $10-- */
MIPS32_ADDI(9,9,1), 
/* $9 += 1 */
MIPS32_ADDI(11,11,4),   
/* $11 += 4 */
MIPS32_B(NEG16(8)), 
/* b loop */

/* end */

Where $11 holds the adress of our buffer member (dst addr). Because we
said that our destination buffer is consisted of uint32_t, this
address is incremented by 4 in every pass:
MIPS32_ADDI(11,11,4),   
/* $11 += 4 */

I think that using uint8_t array and using $11 += 1 in the loop should
do the same thing...
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 12:10 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 OK, I am starting to get this... Thanks  Øyvind.

 But looking from to the code, I see no explicit casting uint8_t* to
 uint32_t in mips_pracc code. Where did you exactly run into compiler
 warning ?

 git revert 2482244b0788c007dd789c2

I reverted this commit :

commit e442054bf9acf70cb2b9b2ac297cba2b15df5642
Author: Drasko DRASKOVIC drasko.drasko...@gmail.com
Date:   Fri Jul 8 12:32:42 2011 +0200

Revert mips4k: fix big-endian hosts and host alignment problems

This reverts commit 2482244b0788c007dd789c21a4416379c229ea5c.

I still can not reproduce a problem - it buidls just fine. No warnings
whatsoever.

gcc version 4.3.2 (Debian 4.3.2-1.1)

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 12:35 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 On Fri, Jul 8, 2011 at 12:31 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:
 On Fri, Jul 8, 2011 at 12:14 PM, Øyvind Harboe oyvind.har...@zylin.com 
 wrote:
 There is no particular need to cast this into uint8_t* and this can be
 kept as a void*. Would that suppress the warnings ?

 It does look like this code is using uint8_t * in lieu of void *...

 Why ? It is just an address of 1-byte placeholder to which you would
 like to copy byte read from the memory.

 It's not about what you do, it is about telling the compiler as much
 as possible about the types so that it can check for problems.

 I don't know the code too well to comment about which types
 should be used. Especially with big/small endian...

I know this code, and I can change it. I just do not see any casting
to unaligned access by visual inspection, and I can not reproduce the
problem. So I do not know where to start changing - everything looks
OK to me here.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
 I still can not reproduce a problem - it buidls just fine. No warnings
 whatsoever.


libtool: compile:  nios2-linux-gnu-gcc -std=gnu99 -DHAVE_CONFIG_H -I.
-I/home/oyvind/workspace/zy1000/build/../openocd/src/target -I../..
-I/home/oyvind/workspace/zy1000/build/../openocd/src -I../../src
-DPKGDATADIR=\/opt/zy1000/share/openocd\
-DPKGLIBDIR=\/opt/zy1000/lib/openocd\ -O3 -g
-I/home/oyvind/nios2-linux/uClinux-dist/staging/usr/include
-I/opt/zy1000/include -Wall -Wstrict-prototypes -Wformat-security
-Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast
-Wcast-align -Wredundant-decls -Werror -MT mips_m4k.lo -MD -MP -MF
.deps/mips_m4k.Tpo -c
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c
-o mips_m4k.o
cc1: warnings being treated as errors
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
In function 'mips_m4k_read_memory':
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:880:
warning: cast increases required alignment of target type
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:884:
warning: cast increases required alignment of target type
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
In function 'mips_m4k_write_memory':
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:933:
warning: cast increases required alignment of target type
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:937:
warning: cast increases required alignment of target type
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
In function 'mips_m4k_bulk_write_memory':
/home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:1077:
warning: cast increases required alignment of target type




-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
What puzzles me is that there is no warning on x86, even if I the
-Wcast-align option
is there


-Wcast-align
Warn whenever a pointer is cast such that the required alignment
of the target is increased. For example, warn if a char * is cast to
an int * on machines where integers can only be accessed at two- or
four-byte boundaries.



-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 12:42 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 I still can not reproduce a problem - it buidls just fine. No warnings
 whatsoever.


 libtool: compile:  nios2-linux-gnu-gcc -std=gnu99 -DHAVE_CONFIG_H -I.
 -I/home/oyvind/workspace/zy1000/build/../openocd/src/target -I../..
 -I/home/oyvind/workspace/zy1000/build/../openocd/src -I../../src
 -DPKGDATADIR=\/opt/zy1000/share/openocd\
 -DPKGLIBDIR=\/opt/zy1000/lib/openocd\ -O3 -g
 -I/home/oyvind/nios2-linux/uClinux-dist/staging/usr/include
 -I/opt/zy1000/include -Wall -Wstrict-prototypes -Wformat-security
 -Wshadow -Wextra -Wno-unused-parameter -Wbad-function-cast
 -Wcast-align -Wredundant-decls -Werror -MT mips_m4k.lo -MD -MP -MF
 .deps/mips_m4k.Tpo -c
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c
 -o mips_m4k.o
 cc1: warnings being treated as errors
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
 In function 'mips_m4k_read_memory':
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:880:
 warning: cast increases required alignment of target type
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:884:
 warning: cast increases required alignment of target type
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
 In function 'mips_m4k_write_memory':
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:933:
 warning: cast increases required alignment of target type
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:937:
 warning: cast increases required alignment of target type
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:
 In function 'mips_m4k_bulk_write_memory':
 /home/oyvind/workspace/zy1000/build/../openocd/src/target/mips_m4k.c:1077:
 warning: cast increases required alignment of target type

OK, I was looking at mips32_pracc.c, but actually it is this in mips_m4k.c :

for(i = 0; i  (count*size); i += size)
{
switch(size)
{
case 4:
t32 = *(uint32_t*)buffer[i];
target_buffer_set_u32(target,buffer[i], t32);
break;
case 2:
t16 = *(uint16_t*)buffer[i];
target_buffer_set_u16(target,buffer[i], t16);
break;
}
}

that casts void* buf to uint32_t*.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 12:52 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 What puzzles me is that there is no warning on x86, even if I the
 -Wcast-align option
 is there

This kind of explains why I never saw it...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Wed, Jul 6, 2011 at 2:42 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 mips32_pracc_read_mem and mips32_pracc_write_mem return values 
 (buffer[i]) are already in host endianness, so le_to_h_u32 fails on big 
 endian hosts. I already mentioned this in previous discussions.

Hi Stefan,
are you sure about this ?

It seems to me that buffer[i] is directly filled by target, and I see
no reason that it is in the host endianess...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Øyvind Harboe
 that casts void* buf to uint32_t*.

Actually buffer is uint8_t *. The definition of target-type-read_memory is
bad in that it uses uint8_t * instead of void *. Which is kinda the
root of this mess.

-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 1:13 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 that casts void* buf to uint32_t*.

 Actually buffer is uint8_t *. The definition of target-type-read_memory is
 bad in that it uses uint8_t * instead of void *. Which is kinda the
 root of this mess.

Well, this propagate through all the targets...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
I am just wandering, would :
t32 = *(uint32_t*)((void *)buffer[i]);
quite the compiler ;)

BR,
Drasko

On Fri, Jul 8, 2011 at 1:14 PM, Drasko DRASKOVIC
drasko.drasko...@gmail.com wrote:
 On Fri, Jul 8, 2011 at 1:13 PM, Øyvind Harboe oyvind.har...@zylin.com wrote:
 that casts void* buf to uint32_t*.

 Actually buffer is uint8_t *. The definition of target-type-read_memory is
 bad in that it uses uint8_t * instead of void *. Which is kinda the
 root of this mess.

 Well, this propagate through all the targets...

 BR,
 Drasko

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 12:52 PM, Øyvind Harboe oyvind.har...@zylin.comwrote:

 What puzzles me is that there is no warning on x86, even if I the
 -Wcast-align option
 is there

 
 -Wcast-align
Warn whenever a pointer is cast such that the required alignment
 of the target is increased. For example, warn if a char * is cast to
 an int * on machines where integers can only be accessed at two- or
 four-byte boundaries.
 


on machines where integers can only be accessed at two- or four-byte
boundaries

x86 is not such a machine, it supports unaligned access. Which is why it's
good to do a cross-compile to another arch regularly to catch these
problems. It would be good if there was an option to emit these warnings
regardless. Maybe there is.

I looked briefly at the memory read functions in mips32_dmaacc.c and
mips32_pracc.c and it looks like the type usage is a bit confused. The
difference between the *_read_mem{32,16,8} functions should only be what
kind of access is made *on the target*. Host data buffer type should be
identical, preferrably void*, with no alignment requirement, and count
should be in number of bytes.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 1:17 PM, Drasko DRASKOVIC drasko.drasko...@gmail.com
 wrote:

 I am just wandering, would :
 t32 = *(uint32_t*)((void *)buffer[i]);
 quite the compiler ;)


Yes probably, but it would still crash on an architecture that doesn't
support unaligned accesses.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 1:20 PM, Andreas Fritiofson
andreas.fritiof...@gmail.com wrote:


 On Fri, Jul 8, 2011 at 1:17 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:

 I am just wandering, would :
 t32 = *(uint32_t*)((void *)buffer[i]);
 quite the compiler ;)

 Yes probably, but it would still crash on an architecture that doesn't
 support unaligned accesses.

Yes,
if there is a reason for crash. I am not sure that it is the case
here... I am trying to investigate...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 1:19 PM, Andreas Fritiofson
andreas.fritiof...@gmail.com wrote:
 I looked briefly at the memory read functions in mips32_dmaacc.c and
 mips32_pracc.c and it looks like the type usage is a bit confused. The
 difference between the *_read_mem{32,16,8} functions should only be what
 kind of access is made *on the target*.
How do we determine that ?

I thought that it is kept in the size parameter, and
mips32_pracc_read_mem is doing exactly this :

int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t
addr, int size, int count, void *buf)
{
switch (size)
{
case 1:
return mips32_pracc_read_mem8(ejtag_info, addr, count, 
(uint8_t*)buf);
case 2:
return mips32_pracc_read_mem16(ejtag_info, addr, count, 
(uint16_t*)buf);
case 4:
if (count == 1)
return mips32_pracc_read_u32(ejtag_info, addr, 
(uint32_t*)buf);
else
return mips32_pracc_read_mem32(ejtag_info, 
addr, count, (uint32_t*)buf);
}

return ERROR_OK;
}

 Host data buffer type should be
 identical, preferrably void*, with no alignment requirement, and count
 should be in number of bytes.

Problem is not in the mips32_pracc.c, thought, but when you come back
to mips_m4k_read_memory(), in which buf is uint8_t*.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 are you sure about this ?
 
 It seems to me that buffer[i] is directly filled by target, and I see
 no reason that it is in the host endianess...

Hi Drasko,

Yes I'm sure. I tested it on my big endian host platform.

I do not understand the code completely, but I think it's caused by the mips 
ejtag functions.

Example:
- mips_ejtag_drscan_32 uses uint32 for data
- buf_set_u32 and buf_get_u32 make sure that data is in host endianness

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 1:38 PM, Mahr, Stefan stefan.m...@sphairon.comwrote:

  are you sure about this ?
 
  It seems to me that buffer[i] is directly filled by target, and I see
  no reason that it is in the host endianess...

 Hi Drasko,

 Yes I'm sure. I tested it on my big endian host platform.

 I do not understand the code completely, but I think it's caused by the
 mips ejtag functions.

 Example:
 - mips_ejtag_drscan_32 uses uint32 for data
 - buf_set_u32 and buf_get_u32 make sure that data is in host endianness


Where are those functions defined and how do they know what the target
endianness is?

It sounds a little strange to do the swapping at this low level.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 Problem is not in the mips32_pracc.c, thought, but when you come back
 to mips_m4k_read_memory(), in which buf is uint8_t*.

That's why the solution could be to add swapping to _mem16, _mem32 etc. and
alway return  uint8*.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 Where are those functions defined and how do they know what the target 
 endianness is?

They doesn't know the target endianness, but host endianness.


 It sounds a little strange to do the swapping at this low level.

You need swapping when reading and comparing debug registers or send code to 
MIPS CPU.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 2:05 PM, Mahr, Stefan stefan.m...@sphairon.comwrote:

  Where are those functions defined and how do they know what the target
 endianness is?

 They doesn't know the target endianness, but host endianness.


  It sounds a little strange to do the swapping at this low level.

 You need swapping when reading and comparing debug registers or send code
 to MIPS CPU.


But there are other times when swapping is not the right thing to do, such
as reading/writing arbitrary memory blocks, right? So I'd say the swapping
belongs to the higher levels that know if the data is to be interpreted or
not. Otherwise we'll just be swapping back and forth needlessly.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 2:05 PM, Mahr, Stefan stefan.m...@sphairon.comwrote:

  Where are those functions defined and how do they know what the target
 endianness is?

 They doesn't know the target endianness, but host endianness.


You can't convert between target and host endianness if you don't know both.

I'm getting confused about all this endianness. Main thing we need to do is
to define and be consistent with where we have target and host endianess and
look over the data types we use. This is probably not restricted to the MIPS
code but probably goes up into the target interface. I have to think it
through and right now I have a bunch of kids running around my legs so it'll
have to wait. :)

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Andreas Fritiofson
On Fri, Jul 8, 2011 at 1:26 PM, Drasko DRASKOVIC drasko.drasko...@gmail.com
 wrote:

 On Fri, Jul 8, 2011 at 1:19 PM, Andreas Fritiofson
 andreas.fritiof...@gmail.com wrote:
  I looked briefly at the memory read functions in mips32_dmaacc.c and
  mips32_pracc.c and it looks like the type usage is a bit confused. The
  difference between the *_read_mem{32,16,8} functions should only be what
  kind of access is made *on the target*.
 How do we determine that ?

 I thought that it is kept in the size parameter, and
 mips32_pracc_read_mem is doing exactly this :

 int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t
 addr, int size, int count, void *buf)
 {
switch (size)
{
case 1:
return mips32_pracc_read_mem8(ejtag_info, addr,
 count, (uint8_t*)buf);
case 2:
return mips32_pracc_read_mem16(ejtag_info, addr,
 count, (uint16_t*)buf);
case 4:
if (count == 1)
return mips32_pracc_read_u32(ejtag_info,
 addr, (uint32_t*)buf);
else
return mips32_pracc_read_mem32(ejtag_info,
 addr, count, (uint32_t*)buf);
}

return ERROR_OK;
 }

  Host data buffer type should be
  identical, preferrably void*, with no alignment requirement, and count
  should be in number of bytes.

 Problem is not in the mips32_pracc.c, thought, but when you come back
 to mips_m4k_read_memory(), in which buf is uint8_t*.


But already here buf is cast to uint{8,16,32}_t* (from void* so no warning
but equally risky) which shouldn't be needed because all read_mem* functions
could accept a void* buffer and write the data to arbitrary alignment. Main
point is that the alignment requirement (buffer data type) on the host
should not be coupled to the access size used on the target. And also the
data returned in the host buffer should be identical, regardless of which
target access size is chosen (this requirement probably gives the answer to
whether endian swapping should be done here or not). Does this make sense?
Of course you may not be able to do an access with size 2 or 4 to an
unaligned *target address* but that has nothing to do with host buffer
alignment.

If the memory functions only handle byte addressed generic memory blocks,
there are no endian issues (here). They pop up first when higher level code
tries to interpret the memory contents as multi-byte entities (instructions,
addresses, ...) in which case that code must be aware of the target
endianness. Again, I may be confused here.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 1:38 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 are you sure about this ?

 It seems to me that buffer[i] is directly filled by target, and I see
 no reason that it is in the host endianess...

 Hi Drasko,

 Yes I'm sure. I tested it on my big endian host platform.

 I do not understand the code completely, but I think it's caused by the mips 
 ejtag functions.

 Example:
 - mips_ejtag_drscan_32 uses uint32 for data
Ok, I see no problem there...

 - buf_set_u32 and buf_get_u32 make sure that data is in host endianness
Why ? Don't we want the data to be in target endianess ?

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 1:54 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Problem is not in the mips32_pracc.c, thought, but when you come back
 to mips_m4k_read_memory(), in which buf is uint8_t*.

 That's why the solution could be to add swapping to _mem16, _mem32 etc. and
 alway return  uint8*.

I agree with you, but we should look for the best solution. We can
always fall back to this brute force if we do not find anything
better.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 2:05 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Where are those functions defined and how do they know what the target 
 endianness is?

 They doesn't know the target endianness, but host endianness.


 It sounds a little strange to do the swapping at this low level.

 You need swapping when reading and comparing debug registers or send code to 
 MIPS CPU.

Can you give the example of some of these comparisons in the source
code ? You are referring to some comparisons in mips32_pracc.c ?

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 3:08 PM, Andreas Fritiofson
andreas.fritiof...@gmail.com wrote:


 On Fri, Jul 8, 2011 at 1:26 PM, Drasko DRASKOVIC
 drasko.drasko...@gmail.com wrote:

 On Fri, Jul 8, 2011 at 1:19 PM, Andreas Fritiofson
 andreas.fritiof...@gmail.com wrote:
  I looked briefly at the memory read functions in mips32_dmaacc.c and
  mips32_pracc.c and it looks like the type usage is a bit confused. The
  difference between the *_read_mem{32,16,8} functions should only be what
  kind of access is made *on the target*.
 How do we determine that ?

 I thought that it is kept in the size parameter, and
 mips32_pracc_read_mem is doing exactly this :

 int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t
 addr, int size, int count, void *buf)
 {
        switch (size)
        {
                case 1:
                        return mips32_pracc_read_mem8(ejtag_info, addr,
 count, (uint8_t*)buf);
                case 2:
                        return mips32_pracc_read_mem16(ejtag_info, addr,
 count, (uint16_t*)buf);
                case 4:
                        if (count == 1)
                                return mips32_pracc_read_u32(ejtag_info,
 addr, (uint32_t*)buf);
                        else
                                return mips32_pracc_read_mem32(ejtag_info,
 addr, count, (uint32_t*)buf);
        }

        return ERROR_OK;
 }

  Host data buffer type should be
  identical, preferrably void*, with no alignment requirement, and count
  should be in number of bytes.

 Problem is not in the mips32_pracc.c, thought, but when you come back
 to mips_m4k_read_memory(), in which buf is uint8_t*.

 But already here buf is cast to uint{8,16,32}_t* (from void* so no warning
 but equally risky) which shouldn't be needed because all read_mem* functions
 could accept a void* buffer and write the data to arbitrary alignment. Main
 point is that the alignment requirement (buffer data type) on the host
 should not be coupled to the access size used on the target.

I do not know all the OpenOCD internals, but I guess that size
represent data access size you are mentioning.
like, if count is 5 and size is 4 that would mean  I want 5  ints.

If my presumption is true, then I agree with you, and looking at the
PrAcc code that we can safely use void for these buffer pointers.
They are just addresses where read data will be put.

However, data will be read (accessed) in the size - if it is 4 we
will use MIPS32_LW which loads word from memory, and if it is 2, we
will use MIPS32_LHU - load halfword unsigned.

So, from this point everything seems to be OK, except from this
unnecessary casting void* to uintX_t*.

Problem is however in  mips_m4k_read_memory(), where you have explicit
casting t32 = *(uint32_t*)buffer[i];

 And also the
 data returned in the host buffer should be identical, regardless of which
 target access size is chosen (this requirement probably gives the answer to
 whether endian swapping should be done here or not). Does this make sense?
Yes, and it is (IMHO).

 Of course you may not be able to do an access with size 2 or 4 to an
 unaligned *target address* but that has nothing to do with host buffer
 alignment.

 If the memory functions only handle byte addressed generic memory blocks,
 there are no endian issues (here). They pop up first when higher level code
 tries to interpret the memory contents as multi-byte entities (instructions,
 addresses, ...) in which case that code must be aware of the target
 endianness. Again, I may be confused here.

I've got lost here...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 - buf_set_u32 and buf_get_u32 make sure that data is in host endianness
 Why ? Don't we want the data to be in target endianess ?

 You need swapping when reading and comparing debug registers or send code to 
 MIPS CPU.
 Can you give the example of some of these comparisons in the source
 code ? You are referring to some comparisons in mips32_pracc.c ?

example:

mips_m4k.c: mips_m4k_poll

  mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
  retval = mips_ejtag_drscan_32(ejtag_info, ejtag_ctrl);
  ...
  if (ejtag_ctrl  EJTAG_CTRL_ROCC)
  {...

ejtag_ctrl is host endian uint32. If mips_ejtag_drscan_32 would be in
target endianness you need to swap here or write and use a new function
that does swapping.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 4:10 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 - buf_set_u32 and buf_get_u32 make sure that data is in host endianness
 Why ? Don't we want the data to be in target endianess ?

 You need swapping when reading and comparing debug registers or send code 
 to MIPS CPU.
 Can you give the example of some of these comparisons in the source
 code ? You are referring to some comparisons in mips32_pracc.c ?

 example:

 mips_m4k.c: mips_m4k_poll

  mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
  retval = mips_ejtag_drscan_32(ejtag_info, ejtag_ctrl);
  ...
  if (ejtag_ctrl  EJTAG_CTRL_ROCC)
  {...

 ejtag_ctrl is host endian uint32. If mips_ejtag_drscan_32 would be in
 target endianness you need to swap here or write and use a new function
 that does swapping.

I agreee. Code like this is present on even lower level, im mips32_pracc.c, like
while (1)
{
retval = mips_ejtag_drscan_32(ejtag_info, ejtag_ctrl);
if (retval != ERROR_OK)
return retval;

if (ejtag_ctrl  EJTAG_CTRL_PRACC)
break;

if ( (timeout = timeval_ms()-then)  1000 )
{
LOG_DEBUG(DEBUGMODULE: No memory access in progress!);
return ERROR_JTAG_DEVICE_ERROR;
}
}


It has to be that way - so code must be in the host endianess right
after drscan.

Is this swap to host endianess done by buf_get_u32() in
mips_ejtag_drscan_32() after the queue has been executed ?

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 Is this swap to host endianess done by buf_get_u32() in
 mips_ejtag_drscan_32() after the queue has been executed ?

Yes, buf_get_u32() and buf_set_u32() make sure uint32 is in host endianness.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 2:05 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Where are those functions defined and how do they know what the target 
 endianness is?

 They doesn't know the target endianness, but host endianness.

How do they convert then, when they do not know from which endianes to
convert from ?

/**
 * Sets @c num bits in @c _buffer, starting at the @c first bit,
 * using the bits in @c value.  This routine fast-paths writes
 * of little-endian, byte-aligned, 32-bit words.
 * @param _buffer The buffer whose bits will be set.
 * @param first The bit offset in @c _buffer to start writing (0-31).
 * @param num The number of bits from @c value to copy (1-32).
 * @param value Up to 32 bits that will be copied to _buffer.
 */
static inline void buf_set_u32(void *_buffer,
unsigned first, unsigned num, uint32_t value)

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 4:23 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Is this swap to host endianess done by buf_get_u32() in
 mips_ejtag_drscan_32() after the queue has been executed ?

 Yes, buf_get_u32() and buf_set_u32() make sure uint32 is in host endianness.

OK, we are slowely nailing it... Just let me see how the hell these
functions do the conversion target/host endianess

Do you have any idea ?


BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 How do they convert then, when they do not know from which endianes to
 convert from ?

Conversion is done from byte array of jtag chain. The endianness of MIPS EJTAG 
tap seems to have always the same endianness, no matter of MIPS CPU memory 
endianness.


___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 4:30 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 How do they convert then, when they do not know from which endianes to
 convert from ?

 Conversion is done from byte array of jtag chain.
How ?

 The endianness of MIPS EJTAG tap seems to have always the same endianness, no 
 matter of MIPS CPU memory endianness.
What makes you think so ?
EJTAG specification, Document Number: MD00047 describes bit in Debug
Control Register

ENM (bit 29 of DCR)
Endianess in which the processor is running in kernel and
Debug Mode.

If your CPU runs in the BE, you'll have to feed it with BE code.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Mahr, Stefan
 How do they convert then, when they do not know from which endianes to
 convert from ?

 Conversion is done from byte array of jtag chain.
 How ?

buf_get_u32 does conversion from uint8* array

example:
mips_ejtag_get_impcode (mips_ejtag.c)

  field.in_value is filled by jtag_add_dr_scan with 4 times uint8.
  buf_get_u32 converts byte array to host endian uint32


 The endianness of MIPS EJTAG tap seems to have always the same endianness,
 no matter of MIPS CPU memory endianness.
 What makes you think so ?

Because openocd works in all combinations of BE and LE host and target. (If you
revert commit 2482244b0788c007dd789c21a4416379c229ea5c.) So yes, it's just a 
guess.


Could this be the explanation:

http://downloads.buffalo.nas-central.org/LS2_MIPSel/DevelopmentTools/JTAG/MD00047-2B-EJTAG-SPC-03.10.pdf
Page 97:
Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to bits 
23:16, and byte 3 refers to bits
31:24, independent of endianess.

Please also see Chapter 6.3.3, 6.3.6, 6.4.1, etc. TAPs are alway LSB first, so 
endianness doesn't matter here.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-08 Thread Drasko DRASKOVIC
On Fri, Jul 8, 2011 at 6:30 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 How do they convert then, when they do not know from which endianes to
 convert from ?

 Conversion is done from byte array of jtag chain.
 How ?

 buf_get_u32 does conversion from uint8* array

 example:
 mips_ejtag_get_impcode (mips_ejtag.c)

  field.in_value is filled by jtag_add_dr_scan with 4 times uint8.
  buf_get_u32 converts byte array to host endian uint32

How ? It does not convert anything. It just takes the data and puts it
into array, in the order that it comes.




 The endianness of MIPS EJTAG tap seems to have always the same endianness,
 no matter of MIPS CPU memory endianness.
 What makes you think so ?

 Because openocd works in all combinations of BE and LE host and target. (If 
 you
 revert commit 2482244b0788c007dd789c21a4416379c229ea5c.) So yes, it's just a 
 guess.

Which might mean that all commands are sent to EJTAG in appropriate
target format in which CPU expects them (be it BE or LE, depends in
which mode it runs).


 Could this be the explanation:

 http://downloads.buffalo.nas-central.org/LS2_MIPSel/DevelopmentTools/JTAG/MD00047-2B-EJTAG-SPC-03.10.pdf
 Page 97:
 Byte 0 refers to bits 7:0, byte 1 refers to bits 15:8, byte 2 refers to bits 
 23:16, and byte 3 refers to bits
 31:24, independent of endianess.

This is _always_ the case in _all_ architectures. But, as you see,
this Byte0 is put to lower addresses for LE and to higher for BE. This
is always the case.


 Please also see Chapter 6.3.3, 6.3.6, 6.4.1, etc. TAPs are alway LSB first, 
 so endianness doesn't matter here.
This is always the case, for all JTAG TAPS.

No, there must be something else...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Mahr, Stefan
Øyvind Harboe wrote:
 It is not obvious at all from the context that there is an alignment
 guarantee.

If alignment is not guaranteed, casting from uint32 to void would cause 
problems too, wouldn't it?
http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd;a=blob;f=src/target/mips32_pracc.c;h=af60d321638652aad0a52a573add2aceacbfb7d9;hb=HEAD#l310


 The version below yields decent code across architectures after
 Stefan showed that the mileage varies greatly with intrinsic memcpy().

The resulting code is even worse.


Andreas Fritiofson wrote:
 The question is who makes the guarantee that the function is only ever called 
 with uint32-aligned
 generic pointers. If it just happens to be so that all *current* callers pass 
 a uint32 pointer cast
 to void pointer, it would be a terribly bad idea to suddenly assume that. If 
 it is guaranteed by
 design/contract, why is a void pointer used at all? Just use a pointer to 
 uint32 then.

Please see mips32_pracc_read_mem (link above). This function returns void 
pointer because it is
used for uint8, uint16 or uint32, depending on size parameter.

If reading uint32 or uint16 from target memory, this function returns value in 
host endianness.
While this is useful for normal EJTAG handling, it's bad for dumping target 
memory. For dumping
we need target endianness.


BR,
Stefan

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Øyvind Harboe
011/7/7 Mahr, Stefan stefan.m...@sphairon.com:
 Øyvind Harboe wrote:
 It is not obvious at all from the context that there is an alignment
 guarantee.

 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?

Why?

 http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd;a=blob;f=src/target/mips32_pracc.c;h=af60d321638652aad0a52a573add2aceacbfb7d9;hb=HEAD#l310


= this is strange, why cast to uint8_t ?

return mips32_pracc_read_mem16(ejtag_info, addr, count, (uint8_t*)buf);




-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Øyvind Harboe
Note that this problem has cropped up many places over the OpenOCD
code. I'd like to get rid of it once and for all

I absolutely intend to fix it for MIPS, but I'd like a good long term solution.

With jtag queue callbacks, a user data pointer to the callback is cast to
a void pointer, then cast back to e.g. uint32_t *. Casting to/from void *
does not yield a warning(should not anyway, right?), but casting from
uint8_t * to uint32_t * is dubious because the code does not clearly
state it's assumptions.


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Mahr, Stefan
 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?
 Why?

Sorry for confusion. I meant the casting within mips32_pracc_read_mem. This 
is also a cast from void* to uint32_t*. If there will be an alignment error, it 
will occur here too.

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Mahr, Stefan
 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?
 Why?

 Sorry for confusion. I meant the casting within mips32_pracc_read_mem. This
 is also a cast from void* to uint32_t*. If there will be an alignment error, 
 it will
 occur here too.

 That's correct. There is no way to know from the code context, is there?

 No documentation either.

Probably the best way would be to remove endianness swapping from 
mips_m4k_read_memory
and put it to mips32_pracc/dma_read_mem32/16. Same for write.

pro: mips32_pracc_read_mem32, ... will return a byte array in target 
endianness, so no cast necessary.
con: Add swapping to at least 10 seperate functions


BR,
Stefan

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Øyvind Harboe
On Thu, Jul 7, 2011 at 10:41 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?
 Why?

 Sorry for confusion. I meant the casting within mips32_pracc_read_mem. 
 This
 is also a cast from void* to uint32_t*. If there will be an alignment 
 error, it will
 occur here too.

 That's correct. There is no way to know from the code context, is there?

 No documentation either.

 Probably the best way would be to remove endianness swapping from 
 mips_m4k_read_memory
 and put it to mips32_pracc/dma_read_mem32/16. Same for write.

 pro: mips32_pracc_read_mem32, ... will return a byte array in target 
 endianness, so no cast necessary.
 con: Add swapping to at least 10 seperate functions

I clearly do not know the code well enough and I have no facilities to
test such a thing I trust you here though.


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Mahr, Stefan
 Probably the best way would be to remove endianness swapping from 
 mips_m4k_read_memory
 and put it to mips32_pracc/dma_read_mem32/16. Same for write.

 pro: mips32_pracc_read_mem32, ... will return a byte array in target 
 endianness, so no cast necessary.
 con: Add swapping to at least 10 seperate functions

 I clearly do not know the code well enough and I have no facilities to
 test such a thing I trust you here though.

There is no problem to get it work, but I'm not sure if this is really the best 
way. I try to prepare a patch within the next days, so you and others can 
comment.

BR,
Stefan

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Øyvind Harboe
 There is no problem to get it work, but I'm not sure if this is
 really the best way. I try to prepare a patch within the next
 days, so you and others can comment.

I have particular reason to be especially grateful for your efforts here... ;-)

Thanks!


-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Drasko DRASKOVIC
On Wed, Jul 6, 2011 at 6:35 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 Did you see this by testing or by inspection?

 Both :)


 Do we even have the right macros  here?

 It would be something like unaligned uint32_t access macros, which will have 
 to
 exist in host endian versions.

 mips32_pracc_read_mem casts uint32 to void, so we need to cast it back to 
 uint32

Where exactly ? I can see that void* is casted in uint32*, but not vice versa...

I can see also that in mips_m4k_read_memory() uint8_t* is casted to void*.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Drasko DRASKOVIC
On Thu, Jul 7, 2011 at 12:59 AM, Andreas Fritiofson
andreas.fritiof...@gmail.com wrote:
 No, casting a pointer-to-any-type to a pointer-to-void and back will never
 cause alignment issues. The question is who makes the guarantee that the
 function is only ever called with uint32-aligned generic pointers. If it
 just happens to be so that all *current* callers pass a uint32 pointer cast
 to void pointer, it would be a terribly bad idea to suddenly assume that. If
 it is guaranteed by design/contract, why is a void pointer used at all? Just
 use a pointer to uint32 then.

 I have no experience with the MIPS code or arch at all, but if it was up to
 me I'd prefer if a *_read_mem function didn't interpret the data and thus it
 should deal with void pointers.

I see no other way... Actually, any data you want to write must be
transfered to 32-bit value put to the register... Acutually, it is
transformed in 32-bit parameter, put onto the miniprogram EJTAG stack,
and then copied in the miniprogram (a small Monitor ROM, if you want,
written dynamically via dongle) to register. This register is the
written to RAM.

Now, there must be a way to put 8-bit values to EJTAG stack and then
just put this 8 bits into the reg in a miniprogram, but that would
demand quite a bit of changes of assembly bytecode miniprograms, IMHO.

I don't know at this point, I'll have to study MIPS code more throughly.

 It would by design be totally free from all
 endian issues and conversions. Moreover, a function accepting a
 pointer-to-void should be prepared to handle any kind of alignment thrown at
 it (unless explicitly stated). That excludes direct casts to uint32_t*.

 That's why GCC is complaining. Sometimes...


 It should never complain when casting a generic pointer to another pointer,
 right? You shouldn't even need an explicit cast IIRC.

Where param_in is uint32_t*, and buf is uint8_t* ?
Is is maybe because of code like this :
for (i = 0; i  count; i++)
{
param_in[i + 2] = buf[i];
}


Dunno... I never seen the warnings so far...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Drasko DRASKOVIC
On Thu, Jul 7, 2011 at 11:04 PM, Michael Schwingen
rincew...@discworld.dascon.de wrote:
 Am 07/07/2011 10:41 PM, schrieb Mahr, Stefan:
 Probably the best way would be to remove endianness swapping from 
 mips_m4k_read_memory
 and put it to mips32_pracc/dma_read_mem32/16. Same for write.

 pro: mips32_pracc_read_mem32, ... will return a byte array in target 
 endianness, so no cast necessary.
 con: Add swapping to at least 10 seperate functions
 Not sure about this.

 Without having a look at the code, I would expect a function with
 read_mem32 in the name to return a 32-bit value, not a byte array, and I
 would expect to get a 32-bit value without a cast.

Which cast exacly are you mentioning, and in which function ?
static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info,
uint32_t addr, int count, uint32_t *buf) does not do any casting and
returns 32-bit value.


 Especially if this is used in 10 places, this looks like there *is* a
 need for a function that returns swapped 32-bit values, only the
 function uses the wrong data types.

I have seen some things that can be avoided in mips32_pracc code. Can
you point me exactly to the places, I can not seem to get the
particular problem...

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-07 Thread Drasko DRASKOVIC
On Thu, Jul 7, 2011 at 10:41 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 If alignment is not guaranteed, casting from uint32 to void would cause 
 problems too, wouldn't it?
 Why?

 Sorry for confusion. I meant the casting within mips32_pracc_read_mem. 
 This
 is also a cast from void* to uint32_t*. If there will be an alignment 
 error, it will
 occur here too.

 That's correct. There is no way to know from the code context, is there?

 No documentation either.

 Probably the best way would be to remove endianness swapping from 
 mips_m4k_read_memory
 and put it to mips32_pracc/dma_read_mem32/16. Same for write.

 pro: mips32_pracc_read_mem32, ... will return a byte array in target 
 endianness, so no cast necessary.
 con: Add swapping to at least 10 seperate functions

I am not keen to have code repetition in MIPS32 PrAcc code, which is
already bloated and very difficult to maintain...

I think we should well understand what is happening here before
resolving the problem in the most elegant manner.

BR,
Drasko
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] MIPS target, big endian host

2011-07-06 Thread Mahr, Stefan
Hi Øyvind,

Did you see problems with host endianness or why did you commit this patch:
http://openocd.git.sourceforge.net/git/gitweb.cgi?p=openocd/openocd;a=commit;h=2482244b0788c007dd789c21a4416379c229ea5c

This patch brokes endianness on big endian host.

mips32_pracc_read_mem and mips32_pracc_write_mem return values (buffer[i]) 
are already in host endianness, so le_to_h_u32 fails on big endian hosts. I 
already mentioned this in previous discussions.

Best regards
Stefan

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Øyvind Harboe
 mips32_pracc_read_mem and mips32_pracc_write_mem return
 values (buffer[i]) are already in host endianness, so le_to_h_u32 fails on 
 big endian hosts. I already
 mentioned this in previous discussions.

Ouch. Did you see this by testing or by inspection?

The problem is that I mis-interpreted a warning from the compiler. The
compiler warned me
that I shouldn't cast a uint8_t * to a uint32_t * as this increases alignment.

Do we even have the right macros  here?

It would be something like unaligned uint32_t access macros, which will have to
exist in host endian versions.




-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Mahr, Stefan
 Did you see this by testing or by inspection?

Both :)


 Do we even have the right macros  here?
 
 It would be something like unaligned uint32_t access macros, which will have 
 to
 exist in host endian versions.

mips32_pracc_read_mem casts uint32 to void, so we need to cast it back to 
uint32. I found no suitable macro in actual sources.



-Ursprüngliche Nachricht-
Von: Øyvind Harboe [mailto:oyvind.har...@zylin.com] 
Gesendet: Mittwoch, 6. Juli 2011 15:02
An: Mahr, Stefan
Cc: openocd-development@lists.berlios.de
Betreff: Re: MIPS target, big endian host

 mips32_pracc_read_mem and mips32_pracc_write_mem return
 values (buffer[i]) are already in host endianness, so le_to_h_u32 fails on 
 big endian hosts. I already
 mentioned this in previous discussions.

Ouch. Did you see this by testing or by inspection?

The problem is that I mis-interpreted a warning from the compiler. The
compiler warned me
that I shouldn't cast a uint8_t * to a uint32_t * as this increases alignment.

Do we even have the right macros  here?

It would be something like unaligned uint32_t access macros, which will have to
exist in host endian versions.




-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Øyvind Harboe
On Wed, Jul 6, 2011 at 6:35 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:

  Did you see this by testing or by inspection?

 Both :)


  Do we even have the right macros  here?
 
  It would be something like unaligned uint32_t access macros, which will 
  have to
  exist in host endian versions.

 mips32_pracc_read_mem casts uint32 to void, so we need to cast it
 back to uint32. I found no suitable macro in actual sources.

Hmm then I think we ought to define one to get this put to
bed once and for all...


--
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Øyvind Harboe
 mips32_pracc_read_mem casts uint32 to void, so we need to cast it
 back to uint32. I found no suitable macro in actual sources.

 Hmm then I think we ought to define one to get this put to
 bed once and for all...

static inline uint32_t uint32_read_unaligned(const void *data)
{
uint32_t t;
 // Let's trust the compiler to do something very clever here.
memcpy(t, data, sizeof(t));
return t;
}

?

-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Mahr, Stefan
 mips32_pracc_read_mem casts uint32 to void, so we need to cast it
 back to uint32. I found no suitable macro in actual sources.

 Hmm then I think we ought to define one to get this put to
 bed once and for all...
  
 static inline uint32_t uint32_read_unaligned(const void *data)
 {
 uint32_t t;
  // Let's trust the compiler to do something very clever here.
 memcpy(t, data, sizeof(t));
 return t;
 }

Do we really need a memcpy? Could we ever run into an alignment issue when 
simply cast void *back* to uint32 ? If not, I would prefer the simplifed 
solution.

static inline uint32_t h_to_h_u32(const void *data)
{
  return (uint32_t)*data;
}

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Øyvind Harboe
On Wed, Jul 6, 2011 at 11:28 PM, Mahr, Stefan stefan.m...@sphairon.com wrote:
 mips32_pracc_read_mem casts uint32 to void, so we need to cast it
 back to uint32. I found no suitable macro in actual sources.

 Hmm then I think we ought to define one to get this put to
 bed once and for all...

 static inline uint32_t uint32_read_unaligned(const void *data)
 {
 uint32_t t;
  // Let's trust the compiler to do something very clever here.
 memcpy(t, data, sizeof(t));
 return t;
 }

 Do we really need a memcpy?

Trust the compiler:

oyvind@fierce:~$ cat test.c
#include string.h
#include stdint.h

uint32_t uint32_read_unaligned(const void *data)
{
uint32_t t;
 // Let's trust the compiler to do something very clever here.
memcpy(t, data, sizeof(t));
 return t;
}
oyvind@fierce:~$ gcc -O3 -S test.c
oyvind@fierce:~$ cat test.s
.file   test.c
.text
.p2align 4,,15
.globl uint32_read_unaligned
.type   uint32_read_unaligned, @function
uint32_read_unaligned:
.LFB22:
.cfi_startproc
movl(%rdi), %eax
ret
.cfi_endproc
.LFE22:
.size   uint32_read_unaligned, .-uint32_read_unaligned
.ident  GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2
.section.note.GNU-stack,,@progbits


 Could we ever run into an alignment
 issue when simply cast void *back* to uint32 ? If not, I would prefer
 the simplifed solution.

The below does not work in all cases. It will break on architectures that
do not support unaligned access.

That's why GCC is complaining. Sometimes...



-- 
Øyvind Harboe - Can Zylin Consulting help on your project?
US toll free 1-866-980-3434 / International +47 51 87 40 27
http://www.zylin.com/
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Mahr, Stefan
 Trust the compiler

NO !

:-)


$ gcc -O3 -S test.c 
$ cat test.s
.file   test.c
.text
.p2align 4,,15
.globl uint32_read_unaligned
.type   uint32_read_unaligned, @function
uint32_read_unaligned:
pushl   %ebp
movl%esp, %ebp
subl$16, %esp
movl8(%ebp), %eax
movl(%eax), %eax
leave
ret
.size   uint32_read_unaligned, .-uint32_read_unaligned
.ident  GCC: (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
.section.note.GNU-stack,,@progbits

-
$ mips-linux-gcc -O3 -S test.c
$ cat test.s
.file   1 test.c
.section .mdebug.abi32
.previous
.abicalls
.text
.align  2
.globl  uint32_read_unaligned
.entuint32_read_unaligned
.type   uint32_read_unaligned, @function
uint32_read_unaligned:
.frame  $sp,24,$31  # vars= 8, regs= 1/0, args= 0, extra= 8
.mask   0x1000,-8
.fmask  0x,0
.setnoreorder
.cpload $25
.setreorder
subu$sp,$sp,24
.cprestore 0
lwl $2,0($4)
lwr $2,3($4)
swl $2,8($sp)
swr $2,11($sp)
lw  $2,8($sp)
sw  $28,16($sp)
.setnoreorder
.setnomacro
j   $31
addu$sp,$sp,24
.setmacro
.setreorder

.enduint32_read_unaligned
.ident  GCC: (GNU) 3.3.6


-
$ mips-linux-gnu-gcc -O3 -S test.c
$ cat test.s
.file   1 test.c
.section .mdebug.abi32
.previous
.gnu_attribute 4, 1
.abicalls
.option pic0
.text
.align  2
.globl  uint32_read_unaligned
.entuint32_read_unaligned
.type   uint32_read_unaligned, @function
uint32_read_unaligned:
.setnomips16
.frame  $sp,8,$31   # vars= 8, regs= 0/0, args= 0, gp= 0
.mask   0x,0
.fmask  0x,0
.setnoreorder
.setnomacro

lwl $2,0($4)
addiu   $sp,$sp,-8
addiu   $sp,$sp,8
j   $31
lwr $2,3($4)

.setmacro
.setreorder
.enduint32_read_unaligned
.ident  GCC: (Sourcery G++ Lite 4.3-154) 4.3.3


-
$ arm-none-eabi-gcc -O3 -S test.c
$ cat test.s
.cpu arm7tdmi
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.file   test.c
.text
.align  2
.global uint32_read_unaligned
.type   uint32_read_unaligned, %function
uint32_read_unaligned:
@ Function supports interworking.
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 0, uses_anonymous_args = 0
str lr, [sp, #-4]!
sub sp, sp, #12
mov r1, r0
mov r2, #4
add r0, sp, #4
bl  memcpy
ldr r0, [sp, #4]
add sp, sp, #12
ldr lr, [sp], #4
bx  lr
.size   uint32_read_unaligned, .-uint32_read_unaligned
.ident  GCC: (GNU) 4.5.1

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] MIPS target, big endian host

2011-07-06 Thread Andreas Fritiofson
On Wed, Jul 6, 2011 at 11:35 PM, Øyvind Harboe oyvind.har...@zylin.comwrote:

 On Wed, Jul 6, 2011 at 11:28 PM, Mahr, Stefan stefan.m...@sphairon.com
 wrote:
  mips32_pracc_read_mem casts uint32 to void, so we need to cast it
  back to uint32. I found no suitable macro in actual sources.
 
  Hmm then I think we ought to define one to get this put to
  bed once and for all...
 
  static inline uint32_t uint32_read_unaligned(const void *data)
  {
  uint32_t t;
   // Let's trust the compiler to do something very clever here.
  memcpy(t, data, sizeof(t));
  return t;
  }
 
  Do we really need a memcpy?

 Trust the compiler:

 oyvind@fierce:~$ cat test.c
 #include string.h
 #include stdint.h

 uint32_t uint32_read_unaligned(const void *data)
 {
 uint32_t t;
  // Let's trust the compiler to do something very clever here.
 memcpy(t, data, sizeof(t));
  return t;
 }
 oyvind@fierce:~$ gcc -O3 -S test.c


And with the default optimization level (O2, isn't it)?


  Could we ever run into an alignment
  issue when simply cast void *back* to uint32 ? If not, I would prefer
  the simplifed solution.

 The below does not work in all cases. It will break on architectures that
 do not support unaligned access.


No, casting a pointer-to-any-type to a pointer-to-void and back will never
cause alignment issues. The question is who makes the guarantee that the
function is only ever called with uint32-aligned generic pointers. If it
just happens to be so that all *current* callers pass a uint32 pointer cast
to void pointer, it would be a terribly bad idea to suddenly assume that. If
it is guaranteed by design/contract, why is a void pointer used at all? Just
use a pointer to uint32 then.

I have no experience with the MIPS code or arch at all, but if it was up to
me I'd prefer if a *_read_mem function didn't interpret the data and thus it
should deal with void pointers. It would by design be totally free from all
endian issues and conversions. Moreover, a function accepting a
pointer-to-void should be prepared to handle any kind of alignment thrown at
it (unless explicitly stated). That excludes direct casts to uint32_t*.


 That's why GCC is complaining. Sometimes...


It should never complain when casting a generic pointer to another pointer,
right? You shouldn't even need an explicit cast IIRC.

/Andreas
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development