lilzz
Posts: 411
Joined: Sat Nov 30, 2013 5:27 pm

The following defines and linux codes

Mon Nov 17, 2014 5:21 pm

Code: Select all

#define A (1)
#define B (2)
#define C(32)
what does that means? It's not a dimension of the array.

Code: Select all

 PageSize = sysconf(_SC_PAGESIZE);
    PageMask = (~(PageSize-1));

    addr_start = IO_BASE & PageMask;
    addr_offset = IO_BASE & ~PageMask;
So the sysconf function finds out the system's page size. But what's a page mask is?

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 26660
Joined: Sat Jul 30, 2011 7:41 pm

Re: The following defines and linux codes

Mon Nov 17, 2014 7:03 pm

Not sure what the third define is - have you copied it correctly? But the other two simple define A to be (1) and B to be (2) - remember the preprocessor is a direct text substitution.

The second question ,sysconf returns a long int, that's probably a 64 bit value but it depends on the build IRC. _SC_PAGESIZE inquire about the virtual memory page size of the machine.

So lets say it's 4K (4096, or 001000000000000 in binary). Pagemask is then set to the inverse of 4096 -1, which would be ~(11111111111), or 1111111111111111111111111111100000000000 (I may have got the number of 1 wrong, but its all of them)

Now that is then applied to various other values. Try working the numbers out to see what happens.

Always a good idea when trying to work out code - try it with some numbers, and see what happens.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Contrary to popular belief, humorous signatures are allowed.
I've been saying "Mucho" to my Spanish friend a lot more lately. It means a lot to him.

lilzz
Posts: 411
Joined: Sat Nov 30, 2013 5:27 pm

Re: The following defines and linux codes

Tue Nov 18, 2014 6:53 pm

jamesh wrote:Not sure what the third define is - have you copied it correctly? But the other two simple define A to be (1) and B to be (2) - remember the preprocessor is a direct text substitution.

The second question ,sysconf returns a long int, that's probably a 64 bit value but it depends on the build IRC. _SC_PAGESIZE inquire about the virtual memory page size of the machine.

So lets say it's 4K (4096, or 001000000000000 in binary). Pagemask is then set to the inverse of 4096 -1, which would be ~(11111111111), or 1111111111111111111111111111100000000000 (I may have got the number of 1 wrong, but its all of them)

Now that is then applied to various other values. Try working the numbers out to see what happens.

Always a good idea when trying to work out code - try it with some numbers, and see what happens.

thanks but I fail to see how page mask is related to address_start and ~pagemask relates to address offset.

User avatar
Paeryn
Posts: 2966
Joined: Wed Nov 23, 2011 1:10 am
Location: Sheffield, England

Re: The following defines and linux codes

Wed Nov 19, 2014 12:10 am

lilzz wrote:
jamesh wrote:Not sure what the third define is - have you copied it correctly? But the other two simple define A to be (1) and B to be (2) - remember the preprocessor is a direct text substitution.

The second question ,sysconf returns a long int, that's probably a 64 bit value but it depends on the build IRC. _SC_PAGESIZE inquire about the virtual memory page size of the machine.

So lets say it's 4K (4096, or 001000000000000 in binary). Pagemask is then set to the inverse of 4096 -1, which would be ~(11111111111), or 1111111111111111111111111111100000000000 (I may have got the number of 1 wrong, but its all of them)

Now that is then applied to various other values. Try working the numbers out to see what happens.

Always a good idea when trying to work out code - try it with some numbers, and see what happens.

thanks but I fail to see how page mask is related to address_start and ~pagemask relates to address offset.
Taking James' example of a 4K pagesize, address_start will hold an address that is aligned to 4K (upper 20 bits of IO_BASE with the lowest 12 bits set to zero), and address_offset will hold the value that you need to add to address_start (lowest 12 bits of IO_BASE with the upper 20 bits set to zero) such that address_start + address_offset = IO_BASE.
So, if IO_BASE = 8, address_start would be 0 and address_offset would be 8.
If IO_BASE = 4100, address_start would be 4096 and address_offset would be 4.
pagemask is just a convenient quick way of masking off the required parts of the value without having to do expensive calculations - it only works when pagesize is a power of 2, but things are designed so that it will be.
She who travels light — forgot something.

Return to “C/C++”