Subject: RE: pgd_offset

From: "Chagas, Jason" <[email-masked]>
Date: Fri, 20 Aug 1999 08:03:33 -0700

Kong,

That's right, 'pgd' is a pointer to the translation table (TB) and 'address'
contains the virtual address being mapped. Shifting the virtual address
[right] by 18 (the most significant 11 bits - 31-20) yield the address of
first-level descriptor in the translation table with the first two least
significant bits (1-0) set to zero. Oddly enough, the function below is
shifts by 20. I just wondering if anyone could explain it to me...

Jason

		-----Original Message-----
		From:	Kong Gang Feng [mailto:[email-masked]]
<mailto:[mailto:[email-masked]]> 
		Sent:	Wednesday, August 18, 1999 6:51 AM
		To:	Chagas, Jason; [email-masked]'
		Subject:	Re: pgd_offset

		Hi,

		I think the entry of 'pgd' is in word (4bytes) instead of
byte. 
		So PGDIR_SHIFT=18+2=20.

		Kong G.F.
		At 08:52 PM 8/19/99 -0700, Chagas, Jason wrote:
		>Need help understanding some code...
		>
		>The 'pgd_offset' function defined in
		>"./include/asm-arm/proc-armv/pgtable.h" is supposed to
calculate the offset
		>into the Translation Table with PGDIR_SHIFT defined as "20"
in
		>./include/asm-arm/proc-armv/pgtable.h" (see attached code
snippet). It is my
		>understanding the entry into the TB is calculated by
shifting the address
		>right by "18" instead. It is a mystery to me how Linux
kernel still works.
		>Am I missing something?
		>
		>Thanks,
		>
		>Jason
		>
		>--------------
		>/* to find an entry in a page-table-directory */
		>extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm,
unsigned long
		>address)
		>{
		>	return mm->pgd + (address >> PGDIR_SHIFT);
		>}
		>
		>unsubscribe: body of `unsubscribe linux-arm' to
[email-masked] <mailto:[email-masked]> 
		unsubscribe: body of `unsubscribe linux-arm' to
[email-masked] <mailto:[email-masked]> 

unsubscribe: body of `unsubscribe linux-arm' to [email-masked]

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Sat, 21 Aug 1999 11:11:43 +0100 (BST)

> shifts by 20. I just wondering if anyone could explain it to me...

It is correct.  sizeof(mm->pgd) = 4, so adding an integer to the pointer
actually does the equivalent of (int)(mm->pgd) + 4*(integer), which will
give you your 18 ( (a >> 20) * 4 == (a >> 18) with bottom two bits cleared)
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |
unsubscribe: body of `unsubscribe linux-arm' to [email-masked]