frutbunn
Member
BradN posted on Oct 22 2006 at 09:42 AM said:Mr.Jabberwocky posted on Oct 18 2006 at 07:29 AM said:Can anyone explain to me what is going on in this kind of reference -> memregs32[0x808>>2] ?
Presumably is does not convert to memregs32[0x202] or it would be written that way. The only thing I can think is that it is referring to the top 16 bits of ( memregs32 + 0x808 ). Is that correct ?
I am giving up on setting the clock speed - it has caused me enough grief and delay.
I think it's referring to a register number 0x808 according to the documentation, but due to how the logic is connected to the address bus, it probably requires shifting the relative address right by 2 bits. memregs32[] is just a reference to the memory mapped registers, and the index gets added to it.
Just to totally confuse you, ponder this bit of C trivia... array[index] and index[array] are identical functionally.
Simple example:
Code:
// Pointers to Magic-Eyes hardware registers:
volatile unsigned short *hardware_regs16;
volatile unsigned int *hardware_regs32;
// Map it:
int devmem_fd;
/* Allow access to MMSP2 hardware registers:
*/
if ( (devmem_fd=open("/dev/mem", O_RDWR)) == 0 ) {
fprintf(stderr, "Could not open /dev/mem,"
" are you sure you're root?\n");
return 1;
}
if ( (hardware_regs32=mmap(0, 0x10000, 3, 1, devmem_fd, 0xC0000000))
== MAP_FAILED ) {
fprintf(stderr, "Call to mmap failed, are you sure"
" you're root?\n");
return 1;
}
hardware_regs16 = (unsigned short*) hardware_regs32;
// Write to hardware registers (set to 8 bit color depth):
hardware_regs16[0x28DA>>1] = 0x02AB; // 8bbp
hardware_regs16[0x290C>>1] = 320; // width;
Most of the Magic-Eyes hardware registers are 16 bit, so if we map a C pointer to the base of the hardware registers at 0xC0000000 (using mmap), we want to easily say which register we want to set. The easiest way is to index that pointer is to use the [n] notation.
So, to set the hardware register 0xC0000002AB, I've mapped hardware_regs32 and hardware_regs16 to point to 0xC00000000 in memory. If I add a displacement to hardware_regs16, then I can assume that hardware_regs16 points to the real address of 0xC0000000, and my index (in the []) points to the offset from that base. So, it's indexed from 0, so adding an offset of 0x02AB will offset 0xC0000000 by 0x02AB bytes!
But! No it won't, because an unsigned short is a 16 bit data type, so it will index from 0xC000000 by TWICE that amount! Remember in C an index is an offset multipled by the size of the variable data type. So char mystring[10] is &mystring+10, but unsigned short myint[10] is actually &myint+(10*2), as the unsigned short is two bytes long.
So we need to divide our pointers offset by the number of bytes the data type uses. So for hardware_regs16 we divide by 2 (or use a logical shift of 1), for hardware_regs32 we divide by four (or use a logical shift of 2). So that's what the >>2 is for!
Hope this helps, I'm not that good at explaining things!
Last edited by a moderator: