Subject: advice required for 2.3.26

From: Nicolas Pitre <[email-masked]>
Date: Sun, 14 Nov 1999 19:09:15 -0500 (EST)

I'm working on the SA1100 support in 2.3.26 and I'm somewhat comfused by
the new memory management framework.

First, what is the definition and relation between those macros:

	PAGE_OFFSET
	PHYS_OFFSET
	__pa()
	__va()
	virt_to_phys()
	phys_to_virt()

>From what I understood, PAGE_OFFSET is the virtual start address for all
the ram the kernel can see, and PHYS_OFFSET is the physical address of the
first ram page.  On the SA1100, both of these are then equal to
0xC0000000.

In arch/arm/kernel/setup.c, there are multiple calls to
reserve_bootmem()/free_bootmem() wich an address argument which seems to
be a physical address relative to the physical start of the ram.  The
__pa() macro apparently convert a virtual address into that relative
physical address.  The problem is that __pa() is defined like this in
include/asm-arm/page.h:

#define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET +
	PHYS_OFFSET)

although the definition from include/asm-i386/page.h is:

#define __pa(x)                 ((unsigned long)(x) - PAGE_OFFSET)

Since PHYS_OFFSET on the SA1100 isn't 0 like it is for EBSA285, this lead
to inconsistency when the following call is made from setup.c:

        reserve_bootmem(0, PAGE_SIZE);
        reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void*));

Also, if __pa() is really relative to the start of physical ram, the call:

  bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end));
  bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn,
  	PHYS_OFFSET );

implies that phys_to_virt() is also assuming relative physical addresses
since init_bootmem() uses phys_to_virt() on the argument passed as
bootmem_end.  The i386 architecture defines phys_to_virt(x) as __va(x),
wich isn't the case for ARM...  Some code in
include/asm-arm/proc-armv/pgtable.h using __virt_to_phys() implies that
this macro must return an absolute physical address, not a relative one.

The problems on the SA1100 occur because the physical ram address is
0xc0000000, not 0 like for the EBSA285 on which relative and absolute
physical addresses start at 0.

So... Any enlightment on how to sort out all this on the SA1100 would be
greatly appreciated.  I'm about to try some ideas, but an "official"
statement might help.

Nicolas

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

---

From: Russell King - ARM Linux Admin <[email-masked]>
Date: Wed, 17 Nov 1999 11:00:30 +0000 (GMT)

> First, what is the definition and relation between those macros:

The start address of kernel virtual RAM.

> 	PHYS_OFFSET

The physical start address of RAM.

> 	__pa()

Fast conversion to a physical address from a virtual address

> 	__va()

Fast conversion from a virtual address to a physical address

> 	virt_to_phys()

(Slower) conversion ala __pa()

> 	phys_to_virt()

(Slower) conversion ala __va()

> reserve_bootmem()/free_bootmem() which an address argument which seems to
> be a physical address relative to the physical start of the ram.

The whole bootmem stuff is a mess on the ARM at the moment.  It's probably
best to stick with .24 for the moment (except for EBSA285/NetWinder which
are the only two I have been testing this stuff on so far).

Currently, there are a couple of "more important" problems which need
sorting before this one gets cleaned up.  To this end, I will not be
releasing a 2.3.28 tree (my build trees are too messed up with various
"other" patches to make this worth while), hopefully the required changes
to the generic code will be in Linus' 2.3.29 to allow an ARM release.
   _____
  |_____| ------------------------------------------------- ---+---+-
  |   |        Russell King       [email-masked]      --- ---
  | | | |  http://www.arm.linux.org.uk/~rmk/armlinux.html    /  /  |
  | +-+-+                                                     --- -+-
  /   |               THE developer of ARM Linux              |+| /|\
 /  | | |                                                     ---  |
    +-+-+ -------------------------------------------------  /\\\  |