Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-08 Thread Scott Wood
On Wed, Jan 08, 2014 at 10:42:35AM +0800, Kevin Hao wrote:
 On Tue, Jan 07, 2014 at 05:46:04PM -0600, Scott Wood wrote:
  Oh.  I think it'd be more readable to do offset = start -
  memstart_addr and add offset instead of subtracting it.
 
 Yes, I agree. The reason that I use offset = memstart_addr - start is that
 it seems memstart_addr is always greater than start when we are booting
 a kdump kernel with a kernel option like crashkernel=64M@80M. :-)
 
  
  Also, offset should be phys_addr_t -- even if you don't expect to
  support offsets greater than 4G on 32-bit, it's semantically the right
  type to use.  Plus, int would break if this code were ever used with
  64-bit.
 
 I thought about using phy_addr_t for the offset originally but gave it up
 for the following reasons:
   * It will not be greater than 4G.
   * We have to use the ugly #ifdef CONFIG_PHYS_64BIT in restore_to_as0().
   * Need more registers for arguments for restore_to_as0().
 
 Of course you can change it to phys_addr_t if you prefer.

Here's the diff I made when applying (also changed the subf in patch 9 to
add)

diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
b/arch/powerpc/kernel/head_fsl_booke.S
index 71e08df..b1f7edc 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -1251,7 +1251,7 @@ _GLOBAL(switch_to_as1)
  * Restore to the address space 0 and also invalidate the tlb entry created
  * by switch_to_as1.
  * r3 - the tlb entry which should be invalidated
- * r4 - __pa(PAGE_OFFSET in AS0) - __pa(PAGE_OFFSET in AS1)
+ * r4 - __pa(PAGE_OFFSET in AS1) - __pa(PAGE_OFFSET in AS0)
  * r5 - device tree virtual address. If r4 is 0, r5 is ignored.
 */
 _GLOBAL(restore_to_as0)
@@ -1266,8 +1266,8 @@ _GLOBAL(restore_to_as0)
 * so we need calculate the right jump and device tree address based
 * on the offset passed by r4.
 */
-   subfr9,r4,r9
-   subfr5,r4,r5
+   add r9,r9,r4
+   add r5,r5,r4
 
 2: mfmsr   r7
li  r8,(MSR_IS | MSR_DS)
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index ce0c7d7..95deb9fd 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -291,7 +291,8 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t 
start)
 * and do a second relocation.
 */
if (start != memstart_addr) {
-   int n, offset = memstart_addr - start;
+   int n;
+   long offset = start - memstart_addr;
 
is_second_reloc = 1;
n = switch_to_as1();
@@ -299,7 +300,7 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t 
start)
if (memstart_addr  start)
map_mem_in_cams(0x400, CONFIG_LOWMEM_CAM_NUM);
else
-   map_mem_in_cams_addr(start, PAGE_OFFSET - offset,
+   map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
0x400, CONFIG_LOWMEM_CAM_NUM);
restore_to_as0(n, offset, __va(dt_ptr));
/* We should never reach here */

-Scott
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-08 Thread Kevin Hao
On Wed, Jan 08, 2014 at 06:02:19PM -0600, Scott Wood wrote:
 On Wed, Jan 08, 2014 at 10:42:35AM +0800, Kevin Hao wrote:
  On Tue, Jan 07, 2014 at 05:46:04PM -0600, Scott Wood wrote:
   Oh.  I think it'd be more readable to do offset = start -
   memstart_addr and add offset instead of subtracting it.
  
  Yes, I agree. The reason that I use offset = memstart_addr - start is that
  it seems memstart_addr is always greater than start when we are booting
  a kdump kernel with a kernel option like crashkernel=64M@80M. :-)
  
   
   Also, offset should be phys_addr_t -- even if you don't expect to
   support offsets greater than 4G on 32-bit, it's semantically the right
   type to use.  Plus, int would break if this code were ever used with
   64-bit.
  
  I thought about using phy_addr_t for the offset originally but gave it up
  for the following reasons:
* It will not be greater than 4G.
* We have to use the ugly #ifdef CONFIG_PHYS_64BIT in restore_to_as0().
* Need more registers for arguments for restore_to_as0().
  
  Of course you can change it to phys_addr_t if you prefer.
 
 Here's the diff I made when applying (also changed the subf in patch 9 to
 add)

Looks fine to me. I also done a boot test and it works pretty well.
Thanks Scott.

Kevin


pgpjE_4e6_kV2.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-07 Thread Scott Wood
On Sat, 2014-01-04 at 14:34 +0800, Kevin Hao wrote:
 On Fri, Jan 03, 2014 at 06:49:09PM -0600, Scott Wood wrote:
  On Fri, 2013-12-20 at 15:43 +0800, Kevin Hao wrote:
   On Wed, Dec 18, 2013 at 05:48:25PM -0600, Scott Wood wrote:
On Wed, Aug 07, 2013 at 09:18:31AM +0800, Kevin Hao wrote:
 This is based on the codes in the head_44x.S. The difference is that
 the init tlb size we used is 64M. With this patch we can only load the
 kernel at address between memstart_addr ~ memstart_addr + 64M. We will
 fix this restriction in the following patches.

Which following patch fixes the restriction?  With all seven patches
applied, I was still only successful booting within 64M of 
memstart_addr.
   
   There is bug in this patch series when booting above the 64M. It seems
   that I missed to test this previously. Sorry for that. With the following
   change I can boot the kernel at 0x500.
  
  I tried v4 and it still doesn't work for me over 64M (without increasing
  the start of memory).  I pulled the following out of the log buffer when
  booting at 0x500 (after cleaning up the binary goo -- is that
  something new?):
  
  Unable to handle kernel paging request for data at address 0xbffe4008
 
 Actually there still have one limitation that we have to make sure
 that the kernel and dtb are in the 64M memory mapped by the init tlb entry.
 I booted the kernel successfully by using the following u-boot commands:
   setenv fdt_high 0x
   dhcp 600 128.224.162.196:/vlm-boards/p5020/uImage
   tftp 6f0 128.224.162.196:/vlm-boards/p5020/p5020ds.dtb
   bootm 600 - 6f0 
   
   

OK, that was it -- I hadn't set fdt_high and thus U-Boot was relocating
the fdt under 64M.

We should probably be using ioremap_prot() (or some other mechanism) to
create a special mapping, rather than assuming the fdt is covered by the
initial TLB entry.  That doesn't need to happen as part of this
patchset, of course, as it's not a new limitation.

  I'm having a hard time following the logic here.  What is PAGE_OFFSET -
  offset supposed to be?  Why would we map anything belowe PAGE_OFFSET?
 
 No, we don't map the address below PAGE_OFFSET.
 memstart_addr is the physical start address of RAM.
 start is the kernel running physical address aligned with 64M.
 
 offset = memstart_addr - start
 
 So if memstart_addr  start, the offset is negative. The PAGE_OFFSET - offset
 is the virtual start address we should use for the init 64M map. It's above
 the PAGE_OFFSET instead of below.

Oh.  I think it'd be more readable to do offset = start -
memstart_addr and add offset instead of subtracting it.

Also, offset should be phys_addr_t -- even if you don't expect to
support offsets greater than 4G on 32-bit, it's semantically the right
type to use.  Plus, int would break if this code were ever used with
64-bit.

If you're OK with these changes, I can fix it while applying.

-Scott


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-07 Thread Kevin Hao
On Tue, Jan 07, 2014 at 05:46:04PM -0600, Scott Wood wrote:
 On Sat, 2014-01-04 at 14:34 +0800, Kevin Hao wrote:
  Actually there still have one limitation that we have to make sure
  that the kernel and dtb are in the 64M memory mapped by the init tlb entry.
  I booted the kernel successfully by using the following u-boot commands:
setenv fdt_high 0x
dhcp 600 128.224.162.196:/vlm-boards/p5020/uImage
tftp 6f0 128.224.162.196:/vlm-boards/p5020/p5020ds.dtb
bootm 600 - 6f0   
  

 
 OK, that was it -- I hadn't set fdt_high and thus U-Boot was relocating
 the fdt under 64M.
 
 We should probably be using ioremap_prot() (or some other mechanism) to

It is too early to use ioremap_prot() for this case.

 create a special mapping, rather than assuming the fdt is covered by the
 initial TLB entry.  That doesn't need to happen as part of this
 patchset, of course, as it's not a new limitation.

In order to fix this limitation we would have to create a separate map for
the dtb if it is not covered by the init 64M tlb. I would like to give it
a try if I can get some time.

 
   I'm having a hard time following the logic here.  What is PAGE_OFFSET -
   offset supposed to be?  Why would we map anything belowe PAGE_OFFSET?
  
  No, we don't map the address below PAGE_OFFSET.
  memstart_addr is the physical start address of RAM.
  start is the kernel running physical address aligned with 64M.
  
  offset = memstart_addr - start
  
  So if memstart_addr  start, the offset is negative. The PAGE_OFFSET - 
  offset
  is the virtual start address we should use for the init 64M map. It's above
  the PAGE_OFFSET instead of below.
 
 Oh.  I think it'd be more readable to do offset = start -
 memstart_addr and add offset instead of subtracting it.

Yes, I agree. The reason that I use offset = memstart_addr - start is that
it seems memstart_addr is always greater than start when we are booting
a kdump kernel with a kernel option like crashkernel=64M@80M. :-)

 
 Also, offset should be phys_addr_t -- even if you don't expect to
 support offsets greater than 4G on 32-bit, it's semantically the right
 type to use.  Plus, int would break if this code were ever used with
 64-bit.

I thought about using phy_addr_t for the offset originally but gave it up
for the following reasons:
  * It will not be greater than 4G.
  * We have to use the ugly #ifdef CONFIG_PHYS_64BIT in restore_to_as0().
  * Need more registers for arguments for restore_to_as0().

Of course you can change it to phys_addr_t if you prefer.

Thanks,
Kevin
 
 If you're OK with these changes, I can fix it while applying.
 
 -Scott
 
 


pgpv7dsFDc2nR.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-03 Thread Scott Wood
On Fri, 2013-12-20 at 15:43 +0800, Kevin Hao wrote:
 On Wed, Dec 18, 2013 at 05:48:25PM -0600, Scott Wood wrote:
  On Wed, Aug 07, 2013 at 09:18:31AM +0800, Kevin Hao wrote:
   This is based on the codes in the head_44x.S. The difference is that
   the init tlb size we used is 64M. With this patch we can only load the
   kernel at address between memstart_addr ~ memstart_addr + 64M. We will
   fix this restriction in the following patches.
  
  Which following patch fixes the restriction?  With all seven patches
  applied, I was still only successful booting within 64M of memstart_addr.
 
 There is bug in this patch series when booting above the 64M. It seems
 that I missed to test this previously. Sorry for that. With the following
 change I can boot the kernel at 0x500.

I tried v4 and it still doesn't work for me over 64M (without increasing
the start of memory).  I pulled the following out of the log buffer when
booting at 0x500 (after cleaning up the binary goo -- is that
something new?):

Unable to handle kernel paging request for data at address 0xbffe4008
Faulting instruction address: 0xc16ee934
Oops: Kernel access of bad area, sig: 11 [#1]
SMP NR_CPUS=8
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 3.13.0-rc1-00065-g422752a #12
task: c18f2340 ti: c192c000 task.ti: c192c000
NIP: c16ee934 LR: c16d1860 CTR: c100e96c
REGS: c192dee0 TRAP: 0300   Not tainted  (3.13.0-rc1-00065-g422752a)
MSR: 00021002 CE,ME  CR: 42044022  XER: 2000
DEAR: bffe4008 ESR:  
GPR00: c16d1860 c192df90 c18f2340 c16eec58   0500  
GPR08:  bffe4000  bc00  0570ad40  7ffb0aec 
GPR16:   7fe4dd70  7fe4ddb0  c192c000 0007 
GPR24:  c194 c16eec58   03fe4000  c18f
NIP [c16ee934] of_scan_flat_dt+0x28/0x148
LR [c16d1860] early_get_first_memblock_info+0x38/0x84
Call Trace:
[c192dfc0] [c16d1860] early_get_first_memblock_info+0x38/0x84
[c192dfd0] [c16d4888] relocate_init+0x98/0x160
[c192dff0] [c100045c] set_ivor+0x144/0x190
Instruction dump:
7c0803a6 4e800020 9421ffd0 7c0802a6 bee1000c 3f20c194 8139a45c 7c7a1b78
90010034 7c9b2378 3b80 3ae7 83e90008 3b00fff8 7fe9fa14 4808
---[ end trace 41ed10ed80b8d831 ]---
Kernel panic - not syncing: Attempted to kill the idle task!


 diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
 index 048d716ae706..ce0c7d7db6c3 100644
 --- a/arch/powerpc/mm/fsl_booke_mmu.c
 +++ b/arch/powerpc/mm/fsl_booke_mmu.c
 @@ -171,11 +171,10 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned 
 long virt,
   return 1UL  camsize;
  }
  
 -unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
 +static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long 
 virt,
 + unsigned long ram, int max_cam_idx)
  {
   int i;
 - unsigned long virt = PAGE_OFFSET;
 - phys_addr_t phys = memstart_addr;
   unsigned long amount_mapped = 0;
  
   /* Calculate CAM values */
 @@ -195,6 +194,14 @@ unsigned long map_mem_in_cams(unsigned long ram, int 
 max_cam_idx)
   return amount_mapped;
  }
  
 +unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
 +{
 + unsigned long virt = PAGE_OFFSET;
 + phys_addr_t phys = memstart_addr;
 +
 + return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
 +}
 +
  #ifdef CONFIG_PPC32
  
  #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL)  (CONFIG_LOWMEM_CAM_NUM = 
 NUM_TLBCAMS)
 @@ -289,7 +296,11 @@ notrace void __init relocate_init(u64 dt_ptr, 
 phys_addr_t start)
   is_second_reloc = 1;
   n = switch_to_as1();
   /* map a 64M area for the second relocation */
 - map_mem_in_cams(0x400UL, CONFIG_LOWMEM_CAM_NUM);
 + if (memstart_addr  start)
 + map_mem_in_cams(0x400, CONFIG_LOWMEM_CAM_NUM);
 + else
 + map_mem_in_cams_addr(start, PAGE_OFFSET - offset,
 + 0x400, CONFIG_LOWMEM_CAM_NUM);
   restore_to_as0(n, offset, __va(dt_ptr));
   /* We should never reach here */
   panic(Relocation error);
 

I'm having a hard time following the logic here.  What is PAGE_OFFSET -
offset supposed to be?  Why would we map anything belowe PAGE_OFFSET?

-Scott


___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2014-01-03 Thread Kevin Hao
On Fri, Jan 03, 2014 at 06:49:09PM -0600, Scott Wood wrote:
 On Fri, 2013-12-20 at 15:43 +0800, Kevin Hao wrote:
  On Wed, Dec 18, 2013 at 05:48:25PM -0600, Scott Wood wrote:
   On Wed, Aug 07, 2013 at 09:18:31AM +0800, Kevin Hao wrote:
This is based on the codes in the head_44x.S. The difference is that
the init tlb size we used is 64M. With this patch we can only load the
kernel at address between memstart_addr ~ memstart_addr + 64M. We will
fix this restriction in the following patches.
   
   Which following patch fixes the restriction?  With all seven patches
   applied, I was still only successful booting within 64M of memstart_addr.
  
  There is bug in this patch series when booting above the 64M. It seems
  that I missed to test this previously. Sorry for that. With the following
  change I can boot the kernel at 0x500.
 
 I tried v4 and it still doesn't work for me over 64M (without increasing
 the start of memory).  I pulled the following out of the log buffer when
 booting at 0x500 (after cleaning up the binary goo -- is that
 something new?):
 
 Unable to handle kernel paging request for data at address 0xbffe4008

Actually there still have one limitation that we have to make sure
that the kernel and dtb are in the 64M memory mapped by the init tlb entry.
I booted the kernel successfully by using the following u-boot commands:
  setenv fdt_high 0x
  dhcp 600 128.224.162.196:/vlm-boards/p5020/uImage
  tftp 6f0 128.224.162.196:/vlm-boards/p5020/p5020ds.dtb
  bootm 600 - 6f0   

  

 Faulting instruction address: 0xc16ee934
 Oops: Kernel access of bad area, sig: 11 [#1]
 SMP NR_CPUS=8
 Modules linked in:
 CPU: 0 PID: 0 Comm: swapper Not tainted 3.13.0-rc1-00065-g422752a #12
 task: c18f2340 ti: c192c000 task.ti: c192c000
 NIP: c16ee934 LR: c16d1860 CTR: c100e96c
 REGS: c192dee0 TRAP: 0300   Not tainted  (3.13.0-rc1-00065-g422752a)
 MSR: 00021002 CE,ME  CR: 42044022  XER: 2000
 DEAR: bffe4008 ESR:  
 GPR00: c16d1860 c192df90 c18f2340 c16eec58   0500 
  
 GPR08:  bffe4000  bc00  0570ad40  
 7ffb0aec 
 GPR16:   7fe4dd70  7fe4ddb0  c192c000 
 0007 
 GPR24:  c194 c16eec58   03fe4000  c18f
 NIP [c16ee934] of_scan_flat_dt+0x28/0x148
 LR [c16d1860] early_get_first_memblock_info+0x38/0x84
 Call Trace:
 [c192dfc0] [c16d1860] early_get_first_memblock_info+0x38/0x84
 [c192dfd0] [c16d4888] relocate_init+0x98/0x160
 [c192dff0] [c100045c] set_ivor+0x144/0x190
 Instruction dump:
 7c0803a6 4e800020 9421ffd0 7c0802a6 bee1000c 3f20c194 8139a45c 7c7a1b78
 90010034 7c9b2378 3b80 3ae7 83e90008 3b00fff8 7fe9fa14 4808
 ---[ end trace 41ed10ed80b8d831 ]---
 Kernel panic - not syncing: Attempted to kill the idle task!
 
 
  diff --git a/arch/powerpc/mm/fsl_booke_mmu.c 
  b/arch/powerpc/mm/fsl_booke_mmu.c
  index 048d716ae706..ce0c7d7db6c3 100644
  --- a/arch/powerpc/mm/fsl_booke_mmu.c
  +++ b/arch/powerpc/mm/fsl_booke_mmu.c
  @@ -171,11 +171,10 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned 
  long virt,
  return 1UL  camsize;
   }
   
  -unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
  +static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long 
  virt,
  +   unsigned long ram, int max_cam_idx)
   {
  int i;
  -   unsigned long virt = PAGE_OFFSET;
  -   phys_addr_t phys = memstart_addr;
  unsigned long amount_mapped = 0;
   
  /* Calculate CAM values */
  @@ -195,6 +194,14 @@ unsigned long map_mem_in_cams(unsigned long ram, int 
  max_cam_idx)
  return amount_mapped;
   }
   
  +unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
  +{
  +   unsigned long virt = PAGE_OFFSET;
  +   phys_addr_t phys = memstart_addr;
  +
  +   return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
  +}
  +
   #ifdef CONFIG_PPC32
   
   #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL)  (CONFIG_LOWMEM_CAM_NUM = 
  NUM_TLBCAMS)
  @@ -289,7 +296,11 @@ notrace void __init relocate_init(u64 dt_ptr, 
  phys_addr_t start)
  is_second_reloc = 1;
  n = switch_to_as1();
  /* map a 64M area for the second relocation */
  -   map_mem_in_cams(0x400UL, CONFIG_LOWMEM_CAM_NUM);
  +   if (memstart_addr  start)
  +   map_mem_in_cams(0x400, CONFIG_LOWMEM_CAM_NUM);
  +   else
  +   map_mem_in_cams_addr(start, PAGE_OFFSET - offset,
  +   0x400, CONFIG_LOWMEM_CAM_NUM);
  restore_to_as0(n, offset, __va(dt_ptr));
  /* We should never reach here */
  panic(Relocation error);
  
 
 I'm having a hard time following the logic here.  What is PAGE_OFFSET -
 

Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2013-12-19 Thread Kevin Hao
On Wed, Dec 18, 2013 at 05:48:25PM -0600, Scott Wood wrote:
 On Wed, Aug 07, 2013 at 09:18:31AM +0800, Kevin Hao wrote:
  This is based on the codes in the head_44x.S. The difference is that
  the init tlb size we used is 64M. With this patch we can only load the
  kernel at address between memstart_addr ~ memstart_addr + 64M. We will
  fix this restriction in the following patches.
 
 Which following patch fixes the restriction?  With all seven patches
 applied, I was still only successful booting within 64M of memstart_addr.

There is bug in this patch series when booting above the 64M. It seems
that I missed to test this previously. Sorry for that. With the following
change I can boot the kernel at 0x500.

diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 048d716ae706..ce0c7d7db6c3 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -171,11 +171,10 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned 
long virt,
return 1UL  camsize;
 }
 
-unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
+static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
+   unsigned long ram, int max_cam_idx)
 {
int i;
-   unsigned long virt = PAGE_OFFSET;
-   phys_addr_t phys = memstart_addr;
unsigned long amount_mapped = 0;
 
/* Calculate CAM values */
@@ -195,6 +194,14 @@ unsigned long map_mem_in_cams(unsigned long ram, int 
max_cam_idx)
return amount_mapped;
 }
 
+unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
+{
+   unsigned long virt = PAGE_OFFSET;
+   phys_addr_t phys = memstart_addr;
+
+   return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
+}
+
 #ifdef CONFIG_PPC32
 
 #if defined(CONFIG_LOWMEM_CAM_NUM_BOOL)  (CONFIG_LOWMEM_CAM_NUM = 
NUM_TLBCAMS)
@@ -289,7 +296,11 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t 
start)
is_second_reloc = 1;
n = switch_to_as1();
/* map a 64M area for the second relocation */
-   map_mem_in_cams(0x400UL, CONFIG_LOWMEM_CAM_NUM);
+   if (memstart_addr  start)
+   map_mem_in_cams(0x400, CONFIG_LOWMEM_CAM_NUM);
+   else
+   map_mem_in_cams_addr(start, PAGE_OFFSET - offset,
+   0x400, CONFIG_LOWMEM_CAM_NUM);
restore_to_as0(n, offset, __va(dt_ptr));
/* We should never reach here */
panic(Relocation error);

I will do more test and then create a new spin to merge this change and rebase
on the latest kernel. Thanks for the review.

Kevin
 
 -Scott


pgpoT22rj1Ydf.pgp
Description: PGP signature
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

Re: [v3, 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2013-12-18 Thread Scott Wood
On Wed, Aug 07, 2013 at 09:18:31AM +0800, Kevin Hao wrote:
 This is based on the codes in the head_44x.S. The difference is that
 the init tlb size we used is 64M. With this patch we can only load the
 kernel at address between memstart_addr ~ memstart_addr + 64M. We will
 fix this restriction in the following patches.

Which following patch fixes the restriction?  With all seven patches
applied, I was still only successful booting within 64M of memstart_addr.

-Scott
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev


[PATCH v3 3/7] powerpc: enable the relocatable support for the fsl booke 32bit kernel

2013-08-06 Thread Kevin Hao
This is based on the codes in the head_44x.S. The difference is that
the init tlb size we used is 64M. With this patch we can only load the
kernel at address between memstart_addr ~ memstart_addr + 64M. We will
fix this restriction in the following patches.

Signed-off-by: Kevin Hao haoke...@gmail.com
---
v3:
  * Use the 64M align.
  * typo fix.

v2: Move the code to set kernstart_addr and virt_phys_offset to a c function.
So we can expand it easily later.

 arch/powerpc/Kconfig  |  2 +-
 arch/powerpc/kernel/fsl_booke_entry_mapping.S |  2 ++
 arch/powerpc/kernel/head_fsl_booke.S  | 37 +++
 arch/powerpc/mm/fsl_booke_mmu.c   | 28 
 4 files changed, 68 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 3bf72cd..57dc8f9 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -859,7 +859,7 @@ config DYNAMIC_MEMSTART
 
 config RELOCATABLE
bool Build a relocatable kernel
-   depends on ADVANCED_OPTIONS  FLATMEM  44x
+   depends on ADVANCED_OPTIONS  FLATMEM  (44x || FSL_BOOKE)
select NONSTATIC_KERNEL
help
  This builds a kernel image that is capable of running at the
diff --git a/arch/powerpc/kernel/fsl_booke_entry_mapping.S 
b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
index a92c79b..f22e7e4 100644
--- a/arch/powerpc/kernel/fsl_booke_entry_mapping.S
+++ b/arch/powerpc/kernel/fsl_booke_entry_mapping.S
@@ -176,6 +176,8 @@ skpinv: addir6,r6,1 /* 
Increment */
 /* 7. Jump to KERNELBASE mapping */
lis r6,(KERNELBASE  ~0xfff)@h
ori r6,r6,(KERNELBASE  ~0xfff)@l
+   rlwinm  r7,r25,0,0x03ff
+   add r6,r7,r6
 
 #elif defined(ENTRY_MAPPING_KEXEC_SETUP)
 /*
diff --git a/arch/powerpc/kernel/head_fsl_booke.S 
b/arch/powerpc/kernel/head_fsl_booke.S
index 377bd81..f6ec9a3 100644
--- a/arch/powerpc/kernel/head_fsl_booke.S
+++ b/arch/powerpc/kernel/head_fsl_booke.S
@@ -73,6 +73,33 @@ _ENTRY(_start);
li  r24,0   /* CPU number */
li  r23,0   /* phys kernel start (high) */
 
+#ifdef CONFIG_RELOCATABLE
+   bl  0f  /* Get our runtime address */
+0: mflrr3  /* Make it accessible */
+   addis   r3,r3,(_stext - 0b)@ha
+   addir3,r3,(_stext - 0b)@l   /* Get our current runtime base */
+
+   /* Translate _stext address to physical, save in r23/r25 */
+   bl  get_phys_addr
+   mr  r23,r3
+   mr  r25,r4
+
+   /*
+* We have the runtime (virutal) address of our base.
+* We calculate our shift of offset from a 64M page.
+* We could map the 64M page we belong to at PAGE_OFFSET and
+* get going from there.
+*/
+   lis r4,KERNELBASE@h
+   ori r4,r4,KERNELBASE@l
+   rlwinm  r6,r25,0,0x3ff  /* r6 = PHYS_START % 64M */
+   rlwinm  r5,r4,0,0x3ff   /* r5 = KERNELBASE % 64M */
+   subfr3,r5,r6/* r3 = r6 - r5 */
+   add r3,r4,r3/* Required Virtual Address */
+
+   bl  relocate
+#endif
+
 /* We try to not make any assumptions about how the boot loader
  * setup or used the TLBs.  We invalidate all mappings from the
  * boot loader and load a single entry in TLB1[0] to map the
@@ -182,6 +209,16 @@ _ENTRY(__early_start)
 
bl  early_init
 
+#ifdef CONFIG_RELOCATABLE
+#ifdef CONFIG_PHYS_64BIT
+   mr  r3,r23
+   mr  r4,r25
+#else
+   mr  r3,r25
+#endif
+   bl  relocate_init
+#endif
+
 #ifdef CONFIG_DYNAMIC_MEMSTART
lis r3,kernstart_addr@ha
la  r3,kernstart_addr@l(r3)
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 07ba45b..ce4a116 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -241,4 +241,32 @@ void setup_initial_memory_limit(phys_addr_t 
first_memblock_base,
/* 64M mapped initially according to head_fsl_booke.S */
memblock_set_current_limit(min_t(u64, limit, 0x0400));
 }
+
+#ifdef CONFIG_RELOCATABLE
+notrace void __init relocate_init(phys_addr_t start)
+{
+   unsigned long base = KERNELBASE;
+
+   /*
+* Relocatable kernel support based on processing of dynamic
+* relocation entries.
+* Compute the virt_phys_offset :
+* virt_phys_offset = stext.run - kernstart_addr
+*
+* stext.run = (KERNELBASE  ~0x3ff) + (kernstart_addr  0x3ff)
+* When we relocate, we have :
+*
+*  (kernstart_addr  0x3ff) = (stext.run  0x3ff)
+*
+* hence:
+*  virt_phys_offset = (KERNELBASE  ~0x3ff) -
+*  (kernstart_addr  ~0x3ff)
+*
+*/
+   kernstart_addr = start;
+   start