Hello,
With these patches and a hack such as the following I am able to build and debug into ppc64 OpenBIOS:
diff --git a/kernel/internal.c b/kernel/internal.c index 91ab440..d1fd850 100644 --- a/kernel/internal.c +++ b/kernel/internal.c @@ -50,7 +50,11 @@ char xtname[MAXNFALEN]; /* instead of pointing to an explicit 0 variable we * point behind the pointer. */ +#ifdef __powerpc64__ +static ucell t[] = { DOCOL, 0, 0, 0 }; +#else static ucell t[] = { DOCOL, 0, (ucell)(t+3), 0 }; +#endif static ucell *trampoline = t; #endif
This hack does not matter yet as we don't return from setup_mmu() anyway.
I have some more fixes related to exception preamble and epilogue cooking but that needs some more thought for a sane interim solution.
Regards, Andreas
Andreas Färber (4): ppc: Use vector-local version of exception_return ppc64: Don't disable SF bit ppc: Introduce load() macro for ppc64 ppc: Avoid vector overlap on ppc64
arch/ppc/qemu/start.S | 76 +++++++++++++++++++++++++++++++------------------ 1 files changed, 48 insertions(+), 28 deletions(-)
On ppc64 the high 32 address bits are clear, so ba's sign extension cannot be used to branch to the ROM version of exception_return. Use a relative branch to the relocated version instead.
This fixes relocation linker errors for ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 27168ad..3ee59d7 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -206,7 +206,7 @@ VECTOR( 0x300, "DSI" ): addi r3,r3,LO(dsi_exception) mtctr r3 bctrl - ba exception_return + b exception_return
VECTOR( 0x400, "ISI" ): EXCEPTION_PREAMBLE @@ -214,7 +214,7 @@ VECTOR( 0x400, "ISI" ): addi r3,r3,LO(isi_exception) mtctr r3 bctrl - ba exception_return + b exception_return
ILLEGAL_VECTOR( 0x500 ) ILLEGAL_VECTOR( 0x600 )
Don't clear the MSR for the pure ppc64 version since it would disable Sixty Four bit mode as well.
The MMU is supposed to be disabled by default.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 3ee59d7..443d668 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -268,10 +268,13 @@ GLOBL(__vectors_end): /************************************************************************/
GLOBL(_entry): + +#ifndef __powerpc64__ /* clear MSR, disable MMU */
li r0,0 mtmsr r0 +#endif
/* copy exception vectors */
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 51 +++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..0be69d9 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -176,6 +176,24 @@ #undef stl #undef ll
+ +#ifdef __powerpc64__ + +#define load(D, x) \ + lis (D), (x)@highest ; \ + ori (D), (D), (x)@higher ; \ + sldi (D), (D), 32 ; \ + oris (D), (D), (x)@h ; \ + ori (D), (D), (x)@l + +#else + +#define load(D, x) \ + lis (D), HA(x) ; \ + addi (D), (D), LO(x) + +#endif + /************************************************************************/ /* vectors */ /************************************************************************/ @@ -202,16 +220,14 @@ ILLEGAL_VECTOR( 0x200 )
VECTOR( 0x300, "DSI" ): EXCEPTION_PREAMBLE - lis r3,HA(dsi_exception) - addi r3,r3,LO(dsi_exception) + load(r3, dsi_exception) mtctr r3 bctrl b exception_return
VECTOR( 0x400, "ISI" ): EXCEPTION_PREAMBLE - lis r3,HA(isi_exception) - addi r3,r3,LO(isi_exception) + load(r3, isi_exception) mtctr r3 bctrl b exception_return @@ -247,16 +263,14 @@ ILLEGAL_VECTOR( 0x1700 )
VECTOR( 0x2000, "DSI_64" ): EXCEPTION_PREAMBLE_64 - lis r3,HA(dsi_exception) - addi r3,r3,LO(dsi_exception) + load(r3, dsi_exception) mtctr r3 bctrl EXCEPTION_EPILOGUE_64
VECTOR( 0x2200, "ISI_64" ): EXCEPTION_PREAMBLE_64 - lis r3,HA(isi_exception) - addi r3,r3,LO(isi_exception) + load(r3, isi_exception) mtctr r3 bctrl EXCEPTION_EPILOGUE_64 @@ -278,8 +292,7 @@ GLOBL(_entry):
/* copy exception vectors */
- lis r3,HA(__vectors) - addi r3,r3,LO(__vectors) + load(r3, __vectors) li r4,0 li r5,__vectors_end - __vectors + 16 rlwinm r5,r5,0,0,28 @@ -378,22 +391,19 @@ GLOBL(call_elf): stwu r1,-16(r1) stw r0,20(r1) mtlr r5 - lis r8,HA(saved_stack) - addi r8,r8,LO(saved_stack) // save our stack pointer + load(r8, saved_stack) // save our stack pointer stw r1,0(r8) mfsdr1 r1 addi r1, r1, -32768 /* - 32 KiB exception stack */ addis r1, r1, -1 /* - 64 KiB stack */ - lis r5,HA(of_client_callback) - addi r5,r5,LO(of_client_callback) // r5 = callback + load(r5, of_client_callback) // r5 = callback li r6,0 // r6 = address of client program arguments (unused) li r7,0 // r7 = length of client program arguments (unused) li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR mtmsr r0 blrl
- lis r8,HA(saved_stack) - addi r8,r8,LO(saved_stack) // restore stack pointer + load(r8, saved_stack) // restore stack pointer mr r1,r8 lwz r0,20(r1) mtlr r0 @@ -418,8 +428,7 @@ GLOBL(of_client_callback):
/* restore OF stack */
- lis r4,HA(saved_stack) - addi r4,r4,LO(saved_stack) + load(r4, saved_stack) lwz r4,0(r4)
stwu r4,-SAVE_SPACE(r4) @@ -564,12 +573,10 @@ GLOBL(flush_icache_range): #define FW_CFG_RAM_SIZE 0x03
compute_ramsize: - lis r9,HA(CFG_ADDR) - ori r9,r9,LO(CFG_ADDR) + load(r9, CFG_ADDR) li r0,FW_CFG_RAM_SIZE sth r0,0(r9) - lis r9,HA(CFG_ADDR + 2) - ori r9,r9,LO(CFG_ADDR + 2) + load(r9, CFG_ADDR + 2) lbz r1,0(r9) lbz r0,0(r9) slwi r0,r0,8
Due to the 64-bit immediate load sequence, the ISI and DSI vectors are two instructions too long for the respective segment exceptions.
Move the code to the start of the relocated vector region and do a relative branch there.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 0be69d9..b81e108 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -204,6 +204,18 @@ GLOBL(__vectors): 1: nop // b 1b
+call_dsi_exception: + load(r3, dsi_exception) + mtctr r3 + bctrl + b exception_return + +call_isi_exception: + load(r3, isi_exception) + mtctr r3 + bctrl + b exception_return + exception_return: EXCEPTION_EPILOGUE
@@ -220,17 +232,15 @@ ILLEGAL_VECTOR( 0x200 )
VECTOR( 0x300, "DSI" ): EXCEPTION_PREAMBLE - load(r3, dsi_exception) - mtctr r3 - bctrl - b exception_return + b call_dsi_exception + +ILLEGAL_VECTOR( 0x380 )
VECTOR( 0x400, "ISI" ): EXCEPTION_PREAMBLE - load(r3, isi_exception) - mtctr r3 - bctrl - b exception_return + b call_isi_exception + +ILLEGAL_VECTOR( 0x480 )
ILLEGAL_VECTOR( 0x500 ) ILLEGAL_VECTOR( 0x600 )
On 01.11.2010, at 16:56, Andreas Färber wrote:
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
arch/ppc/qemu/start.S | 51 +++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..0be69d9 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -176,6 +176,24 @@ #undef stl #undef ll
+#ifdef __powerpc64__
+#define load(D, x) \
- lis (D), (x)@highest ; \
- ori (D), (D), (x)@higher ; \
- sldi (D), (D), 32 ; \
- oris (D), (D), (x)@h ; \
- ori (D), (D), (x)@l
+#else
+#define load(D, x) \
- lis (D), HA(x) ; \
- addi (D), (D), LO(x)
I would recommend to take the LOAD_REG_IMMEDIATE macro from Linux :). That makes the code more readable for someone who knows his way around the Linux code.
Alex
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
v2: * Rename from load() to LOAD_REG_IMMEDIATE() to match Linux. Suggested by Alex. * Move to ppc/asmdefs.h for future use elsewhere.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 33 +++++++++++---------------------- include/arch/ppc/asmdefs.h | 13 +++++++++++++ 2 files changed, 24 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..b86cd66 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -202,16 +202,14 @@ ILLEGAL_VECTOR( 0x200 )
VECTOR( 0x300, "DSI" ): EXCEPTION_PREAMBLE - lis r3,HA(dsi_exception) - addi r3,r3,LO(dsi_exception) + LOAD_REG_IMMEDIATE(r3, dsi_exception) mtctr r3 bctrl b exception_return
VECTOR( 0x400, "ISI" ): EXCEPTION_PREAMBLE - lis r3,HA(isi_exception) - addi r3,r3,LO(isi_exception) + LOAD_REG_IMMEDIATE(r3, isi_exception) mtctr r3 bctrl b exception_return @@ -247,16 +245,14 @@ ILLEGAL_VECTOR( 0x1700 )
VECTOR( 0x2000, "DSI_64" ): EXCEPTION_PREAMBLE_64 - lis r3,HA(dsi_exception) - addi r3,r3,LO(dsi_exception) + LOAD_REG_IMMEDIATE(r3, dsi_exception) mtctr r3 bctrl EXCEPTION_EPILOGUE_64
VECTOR( 0x2200, "ISI_64" ): EXCEPTION_PREAMBLE_64 - lis r3,HA(isi_exception) - addi r3,r3,LO(isi_exception) + LOAD_REG_IMMEDIATE(r3, isi_exception) mtctr r3 bctrl EXCEPTION_EPILOGUE_64 @@ -278,8 +274,7 @@ GLOBL(_entry):
/* copy exception vectors */
- lis r3,HA(__vectors) - addi r3,r3,LO(__vectors) + LOAD_REG_IMMEDIATE(r3, __vectors) li r4,0 li r5,__vectors_end - __vectors + 16 rlwinm r5,r5,0,0,28 @@ -378,22 +373,19 @@ GLOBL(call_elf): stwu r1,-16(r1) stw r0,20(r1) mtlr r5 - lis r8,HA(saved_stack) - addi r8,r8,LO(saved_stack) // save our stack pointer + LOAD_REG_IMMEDIATE(r8, saved_stack) // save our stack pointer stw r1,0(r8) mfsdr1 r1 addi r1, r1, -32768 /* - 32 KiB exception stack */ addis r1, r1, -1 /* - 64 KiB stack */ - lis r5,HA(of_client_callback) - addi r5,r5,LO(of_client_callback) // r5 = callback + LOAD_REG_IMMEDIATE(r5, of_client_callback) // r5 = callback li r6,0 // r6 = address of client program arguments (unused) li r7,0 // r7 = length of client program arguments (unused) li r0,MSR_FP | MSR_ME | MSR_DR | MSR_IR mtmsr r0 blrl
- lis r8,HA(saved_stack) - addi r8,r8,LO(saved_stack) // restore stack pointer + LOAD_REG_IMMEDIATE(r8, saved_stack) // restore stack pointer mr r1,r8 lwz r0,20(r1) mtlr r0 @@ -418,8 +410,7 @@ GLOBL(of_client_callback):
/* restore OF stack */
- lis r4,HA(saved_stack) - addi r4,r4,LO(saved_stack) + LOAD_REG_IMMEDIATE(r4, saved_stack) lwz r4,0(r4)
stwu r4,-SAVE_SPACE(r4) @@ -564,12 +555,10 @@ GLOBL(flush_icache_range): #define FW_CFG_RAM_SIZE 0x03
compute_ramsize: - lis r9,HA(CFG_ADDR) - ori r9,r9,LO(CFG_ADDR) + LOAD_REG_IMMEDIATE(r9, CFG_ADDR) li r0,FW_CFG_RAM_SIZE sth r0,0(r9) - lis r9,HA(CFG_ADDR + 2) - ori r9,r9,LO(CFG_ADDR + 2) + LOAD_REG_IMMEDIATE(r9, CFG_ADDR + 2) lbz r1,0(r9) lbz r0,0(r9) slwi r0,r0,8 diff --git a/include/arch/ppc/asmdefs.h b/include/arch/ppc/asmdefs.h index ca3ebcd..9da4124 100644 --- a/include/arch/ppc/asmdefs.h +++ b/include/arch/ppc/asmdefs.h @@ -75,6 +75,19 @@ /* MISC */ /************************************************************************/
+#ifdef __powerpc64__ +#define LOAD_REG_IMMEDIATE(D, x) \ + lis (D), (x)@highest ; \ + ori (D), (D), (x)@higher ; \ + sldi (D), (D), 32 ; \ + oris (D), (D), (x)@h ; \ + ori (D), (D), (x)@l +#else +#define LOAD_REG_IMMEDIATE(D, x) \ + lis (D), HA(x) ; \ + addi (D), (D), LO(x) +#endif + #ifndef __darwin__ #define GLOBL( name ) .globl name ; name #define EXTERN( name ) name
Due to the 64-bit immediate load sequence, the ISI and DSI vectors are two instructions too long for the respective segment exceptions.
Move the code to the start of the relocated vector region and do a relative branch there.
v2: * load() -> LOAD_REG_IMMEDIATE()
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de --- arch/ppc/qemu/start.S | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index b86cd66..4db6462 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -186,6 +186,18 @@ GLOBL(__vectors): 1: nop // b 1b
+call_dsi_exception: + LOAD_REG_IMMEDIATE(r3, dsi_exception) + mtctr r3 + bctrl + b exception_return + +call_isi_exception: + LOAD_REG_IMMEDIATE(r3, isi_exception) + mtctr r3 + bctrl + b exception_return + exception_return: EXCEPTION_EPILOGUE
@@ -202,17 +214,15 @@ ILLEGAL_VECTOR( 0x200 )
VECTOR( 0x300, "DSI" ): EXCEPTION_PREAMBLE - LOAD_REG_IMMEDIATE(r3, dsi_exception) - mtctr r3 - bctrl - b exception_return + b call_dsi_exception + +ILLEGAL_VECTOR( 0x380 )
VECTOR( 0x400, "ISI" ): EXCEPTION_PREAMBLE - LOAD_REG_IMMEDIATE(r3, isi_exception) - mtctr r3 - bctrl - b exception_return + b call_isi_exception + +ILLEGAL_VECTOR( 0x480 )
ILLEGAL_VECTOR( 0x500 ) ILLEGAL_VECTOR( 0x600 )
Am 01.11.2010 um 22:10 schrieb Alexander Graf:
On 01.11.2010, at 16:56, Andreas Färber wrote:
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
arch/ppc/qemu/start.S | 51 ++++++++++++++++++++++++++ +--------------------- 1 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..0be69d9 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -176,6 +176,24 @@ #undef stl #undef ll
+#ifdef __powerpc64__
+#define load(D, x) \
- lis (D), (x)@highest ; \
- ori (D), (D), (x)@higher ; \
- sldi (D), (D), 32 ; \
- oris (D), (D), (x)@h ; \
- ori (D), (D), (x)@l
+#else
+#define load(D, x) \
- lis (D), HA(x) ; \
- addi (D), (D), LO(x)
I would recommend to take the LOAD_REG_IMMEDIATE macro from Linux :). That makes the code more readable for someone who knows his way around the Linux code.
Done. This series is now also available from http://repo.or.cz/w/openbios/afaerber.git ppc64-queue.
Andreas
On 01.11.2010, at 18:09, Andreas Färber wrote:
Am 01.11.2010 um 22:10 schrieb Alexander Graf:
On 01.11.2010, at 16:56, Andreas Färber wrote:
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
arch/ppc/qemu/start.S | 51 +++++++++++++++++++++++++++--------------------- 1 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..0be69d9 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -176,6 +176,24 @@ #undef stl #undef ll
+#ifdef __powerpc64__
+#define load(D, x) \
- lis (D), (x)@highest ; \
- ori (D), (D), (x)@higher ; \
- sldi (D), (D), 32 ; \
- oris (D), (D), (x)@h ; \
- ori (D), (D), (x)@l
+#else
+#define load(D, x) \
- lis (D), HA(x) ; \
- addi (D), (D), LO(x)
I would recommend to take the LOAD_REG_IMMEDIATE macro from Linux :). That makes the code more readable for someone who knows his way around the Linux code.
Done. This series is now also available from http://repo.or.cz/w/openbios/afaerber.git ppc64-queue.
v2 of the series:
Acked-by: Alexander Graf agraf@suse.de
Alex
Am 01.11.2010 um 23:17 schrieb Alexander Graf:
On 01.11.2010, at 18:09, Andreas Färber wrote:
Am 01.11.2010 um 22:10 schrieb Alexander Graf:
On 01.11.2010, at 16:56, Andreas Färber wrote:
When loading the fw_cfg address with just lis, addi sequence, we get the high address bits as 0xffffffff on ppc64.
Use the full double word immediate load sequence on ppc64.
Cc: Alexander Graf agraf@suse.de Signed-off-by: Andreas Färber andreas.faerber@web.de
arch/ppc/qemu/start.S | 51 ++++++++++++++++++++++++++ +--------------------- 1 files changed, 29 insertions(+), 22 deletions(-)
diff --git a/arch/ppc/qemu/start.S b/arch/ppc/qemu/start.S index 443d668..0be69d9 100644 --- a/arch/ppc/qemu/start.S +++ b/arch/ppc/qemu/start.S @@ -176,6 +176,24 @@ #undef stl #undef ll
+#ifdef __powerpc64__
+#define load(D, x) \
- lis (D), (x)@highest ; \
- ori (D), (D), (x)@higher ; \
- sldi (D), (D), 32 ; \
- oris (D), (D), (x)@h ; \
- ori (D), (D), (x)@l
+#else
+#define load(D, x) \
- lis (D), HA(x) ; \
- addi (D), (D), LO(x)
I would recommend to take the LOAD_REG_IMMEDIATE macro from Linux :). That makes the code more readable for someone who knows his way around the Linux code.
Done. This series is now also available from http://repo.or.cz/w/openbios/afaerber.git ppc64-queue.
v2 of the series:
Acked-by: Alexander Graf agraf@suse.de
Thanks, applied as r942-r945.
Andreas