I'm starting to programming in a low-level approach on Intel Quark (Intel Galileo Gen2). My question in how I write in C code a register address.
For example, I want to access this register:
This tables show a model for compose the address:
Following this model, I set this macro:
"# define GPIO_SWPORTA_DDR 0b11010100010101010001000000000000", but gcc gives segmentation fault when I define a pointer for that address.
I'm using debian image on Galileo
Have you tried by just writing to the register to the default address? With this I mean, defining the register and writing directly to the GPIO_SWPORTA_DIR with the 32bit instruction, as you know the 31:8 is reserved and you have to use the 7:0.
Please let me know the outcome of doing these variations in your code.
I want to access directly this register, but my problem is:
What is its address? The data-sheet shows "offset=[BAR1]+4h", and I think that the register address is this: [BAR1]+4h. However, I don't know the BAR1 value.
The address of GPIO_SWPORTA_DIR is really sum value or I'm thinking wrong?
Until now, i could access and read the PCI registers (including BAR1) because they follow the access scheme of the table 47 above.
Using the following code, I can get two (undesirable) results: if I define a pointer to GpioDirAdd and execute a command for read its content, I still get segmentation fault. If I use inl function (i don't know if it's is right) I get the result 0xffffffff, that's probably not the content of the register.
OBS: in the following code, I'm not really (trying to) access the GPIO_SWPORTA_DDR, but a i2c register that have by default a value different of zero, and than would indicates that i am accessing a real register.
unsigned int volatile BarContent;
perm=iopl(3);//privilege for access
unsigned int Bar= (uint32_t)((busNumber)|(devNumber)|(funcNumber)|(offset&0xFC)|((uint32_t)0x80000000)); //composing BAR address
//------Setando BAR no registrador PCI CONFIG_ADDRES e lendo seu conteúdo por meio do registrador PCI CONFIG_DATA-----//
After some research, I think that for access the adress, I have to use the "# define..." structure in the begin of script to acess, or, in a way to more difficult approach, change the linker script for define de memory regions that a I have do access.
The BAR1 address can be get by reading the offset 0x14, with this offset the address will be present.
For accessing the GPIO_SWPORTA_DDR, you need to:
1. Read the BAR1 address from the PCI device BUS 0 , device 21 function 02 offset 0x14.
2. Add 0x4 to the BAR1 address we got from the step 1.
3. Do the operation you need on the GPIO_SWPORTA_DDR
Hi Charles! Thank you for the answer.
I'm stuck on the third point. As GPIO_SWPORTA_DDR is a Memory Mapped I/O Register, for access it, it's not too simple as to access the BAR (doing out/in assembly commands). If I try to simply define a pointer to the address location of GPIO_SWPORTA_DDR, I get segmentation fault.
After some lectures about memory map on x86 processors, I've found that I have to make a call to the mman() for mapping the region that a want to access. Apparently I could allocate the range of address that is necessary, but I'm getting strange values from the register,because they don't match with the default values exposed on the datasheet.
Do you think that this mmap() approach is the right one or not?
Do you have updates using mmap? Are you still having the same behavior?
I will investigate for another way to access the register and will let you know.