On Mon, Jul 11, 2011 at 11:10 AM, Mahr, Stefan <stefan.m...@sphairon.com> wrote:
>>> 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 = 0x00000012  or in memory 
> 0x12 0x00 0x00 0x00
> result |= (uint32_t)buffer[1] << 8;     //  result = 0x00003412  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 = 0x00000012  or in memory 
> 0x00 0x00 0x00 0x12
> result |= (uint32_t)buffer[1] << 8;     //  result = 0x00003412  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 endiannes.

Yes, exactly. I see now what I did not take care of - it's the
(uint32_t) case of the buffer[0].
In this case, for BE host it will be written in memory like this 0x00
0x00 0x00 0x12, and not like this :
0x12 0x00 0x00 0x00, which would be without cast (i.e. if it stayed
uint8_t), right ?

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

My concern is how the target will fill this buffer when it sends
information to the host ?
I.e, looking at the memory you represented above, does it say byte[0]
= [addr0x0] (which is 0x78 in BE, and 0x12 in LE), or it says byte[0]
= (uint_8)((uint32_t)[addr0x0]) (which should be 0x12 regardless of
endianess) ?


>> 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.

But it says that Byte0 is on address 0x0 in the case of LE and addr
0x3 in the case of BE...

If it was always LE, then bits 7..0 would always be on addr 0x0, right
? This thing with addresses confusing to me.

One more question - if the EJTAG is always LE, how does it understands
bytecode programs you are feeding it from BE host ?
I mean, you are sending byte-by-byte... It must use then some
algorithm similar to buf_get_u32() to write these bytecode programs in
it's EJTAG memory.
Since all instructions are 32-bit long that might work fine in
whatever endianess you wrote your program into the buffer that you are
sending to the target...

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

Reply via email to