8 Replies Latest reply on Jul 4, 2016 1:55 PM by Intel Corporation

    How to access register address in C (Intel Galileo)

    fellipe_leandroBR

      Hello;
      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:

       

      gpio.png

       

       

       

       

       

       

       

       

      This tables show a model for compose the address:

      general_adress.png

      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

        • 1. Re: How to access register address in C (Intel Galileo)
          Intel Corporation
          This message was posted on behalf of Intel Corporation

          Hi,

          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.

          Regards,
          Carlos

          • 2. Re: How to access register address in C (Intel Galileo)
            fellipe_leandroBR

            Hi, Carlos!

            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.

            • 3. Re: How to access register address in C (Intel Galileo)
              fellipe_leandroBR

              UPDATE

              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.

               

               

               

              #include <stdio.h>

              #include<inttypes.h>

              #include<sys/io.h>

              #include<errno.h>

              #include<string.h>

              int main(){

                int perm;

                unsigned int volatile BarContent;

                uint32_t GpioDirOff;

                uint32_t GpioDirAdd;

                perm=iopl(3);//privilege for access

                if(perm==-1){

                  printf("%s",strerror(errno));

                }

                uint32_funcNumber=2<<8,devNumber=21<<11,busNumber=0<<16;

                uint8_t offset=0x10;

                unsigned int Bar= (uint32_t)((busNumber)|(devNumber)|(funcNumber)|(offset&0xFC)|((uint32_t)0x80000000)); //composing BAR address

                outl(Bar,0xCF8); //writing

                BarContent=inl(0xCFC);//reading content

               

                //------Setando BAR no  registrador PCI CONFIG_ADDRES e lendo seu conteúdo por meio do registrador PCI CONFIG_DATA-----//

               

                GpioDirOff=0x14;

                GpioDirAdd=(uint32_t)((BarContent&0xFFFFFFF0)+GpioDirOff);

               

               

              }

              • 4. Re: How to access register address in C (Intel Galileo)
                Intel Corporation
                This message was posted on behalf of Intel Corporation

                Hi,

                Let me gather more information about this and to run some tests. I will contact you back when I get some results.

                Regards,
                Charlie
                 

                • 5. Re: How to access register address in C (Intel Galileo)
                  fellipe_leandroBR

                  Hi Charles!
                  Any progress?
                  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.

                  • 6. Re: How to access register address in C (Intel Galileo)
                    Intel Corporation
                    This message was posted on behalf of Intel Corporation

                    Hi,

                    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

                    Regards,
                    Charlie

                    • 7. Re: How to access register address in C (Intel Galileo)
                      fellipe_leandroBR

                      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?

                      • 8. Re: How to access register address in C (Intel Galileo)
                        Intel Corporation
                        This message was posted on behalf of Intel Corporation

                        Hi,

                        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.

                        Regards,
                        Charlie