2022-05-15 15:13:58

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 00/13] OpenIRSC misc cleanups for 5.19

This is a collection of misc cleanups I have accumulated when working on some
recent OpenRISC projects.

The patch themes:
- Sparse warning cleanups
- Removal of dead code
- Emergency debug fixups in head.S
- Support for gcc machine instruction flags
- defconfig updates for litex

I have tested these patches when verifying the glibc port by running the glibc
test suite.

Stafford Horne (13):
openrisc: Add gcc machine instruction flag configuration
openrisc: Cleanup emergency print handling
openrisc: Add support for liteuart emergency printing
openrisc: Add syscall details to emergency syscall debugging
openrisc: Pretty print show_registers memory dumps
openrisc: Update litex defconfig to support glibc userland
openrisc/traps: Declare file scope symbols as static
openrisc/traps: Remove die_if_kernel function
openrisc/traps: Declare unhandled_exception for asmlinkage
openrisc/time: Fix symbol scope warnings
openrisc/delay: Add include to fix symbol not declared warning
openrisc/fault: Fix symbol scope warnings
openrisc: Remove unused IMMU tlb workardound

arch/openrisc/Kconfig | 53 ++++
arch/openrisc/Makefile | 17 +
arch/openrisc/configs/or1klitex_defconfig | 33 ++
arch/openrisc/kernel/entry.S | 20 +-
arch/openrisc/kernel/head.S | 368 ++++++----------------
arch/openrisc/kernel/time.c | 3 +-
arch/openrisc/kernel/traps.c | 63 ++--
arch/openrisc/lib/delay.c | 1 +
arch/openrisc/mm/fault.c | 4 +-
9 files changed, 255 insertions(+), 307 deletions(-)

--
2.31.1



2022-05-15 15:56:57

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 01/13] openrisc: Add gcc machine instruction flag configuration

OpenRISC GCC supports flags to enable the backend to output instructions
if they are supported by a target processor. This patch adds
configuration flags to enable configuring these flags to tune the kernel
for a particular CPU configuration.

In the future we could also enable all of these flags by default and
provide instruction emulation in the kernel to make these choices easier
for users but this is what we provide for now.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/Kconfig | 53 ++++++++++++++++++++++++++++++++++++++++++
arch/openrisc/Makefile | 17 ++++++++++++++
2 files changed, 70 insertions(+)

diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 0d68adf6e02b..ea7eac20911a 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -114,6 +114,59 @@ config OPENRISC_HAVE_INST_DIV
default y
help
Select this if your implementation has a hardware divide instruction
+
+config OPENRISC_HAVE_INST_CMOV
+ bool "Have instruction l.cmov for conditional move"
+ default y
+ help
+ This config enables gcc to generate l.cmov instructions when compiling
+ the kernel which in general will improve performance and reduce the
+ binary size.
+
+ Select this if your implementation has support for the Class II
+ l.cmov conistional move instruction.
+
+ Say N if you are unsure.
+
+config OPENRISC_HAVE_INST_ROR
+ bool "Have instruction l.ror for rotate right"
+ default y
+ help
+ This config enables gcc to generate l.ror instructions when compiling
+ the kernel which in general will improve performance and reduce the
+ binary size.
+
+ Select this if your implementation has support for the Class II
+ l.ror rotate right instruction.
+
+ Say N if you are unsure.
+
+config OPENRISC_HAVE_INST_RORI
+ bool "Have instruction l.rori for rotate right with immediate"
+ default y
+ help
+ This config enables gcc to generate l.rori instructions when compiling
+ the kernel which in general will improve performance and reduce the
+ binary size.
+
+ Select this if your implementation has support for the Class II
+ l.rori rotate right with immediate instruction.
+
+ Say N if you are unsure.
+
+config OPENRISC_HAVE_INST_SEXT
+ bool "Have instructions l.ext* for sign extension"
+ default y
+ help
+ This config enables gcc to generate l.ext* instructions when compiling
+ the kernel which in general will improve performance and reduce the
+ binary size.
+
+ Select this if your implementation has support for the Class II
+ l.exths, l.extbs, l.exthz and l.extbz size extend instructions.
+
+ Say N if you are unsure.
+
endmenu

config NR_CPUS
diff --git a/arch/openrisc/Makefile b/arch/openrisc/Makefile
index 760b734fb822..b446510173cd 100644
--- a/arch/openrisc/Makefile
+++ b/arch/openrisc/Makefile
@@ -21,6 +21,7 @@ OBJCOPYFLAGS := -O binary -R .note -R .comment -S
LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)

KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__
+KBUILD_CFLAGS += -msfimm -mshftimm

all: vmlinux.bin

@@ -38,6 +39,22 @@ else
KBUILD_CFLAGS += $(call cc-option,-msoft-div)
endif

+ifeq ($(CONFIG_OPENRISC_HAVE_INST_CMOV),y)
+ KBUILD_CFLAGS += $(call cc-option,-mcmov)
+endif
+
+ifeq ($(CONFIG_OPENRISC_HAVE_INST_ROR),y)
+ KBUILD_CFLAGS += $(call cc-option,-mror)
+endif
+
+ifeq ($(CONFIG_OPENRISC_HAVE_INST_RORI),y)
+ KBUILD_CFLAGS += $(call cc-option,-mrori)
+endif
+
+ifeq ($(CONFIG_OPENRISC_HAVE_INST_SEXT),y)
+ KBUILD_CFLAGS += $(call cc-option,-msext)
+endif
+
head-y := arch/openrisc/kernel/head.o

libs-y += $(LIBGCC)
--
2.31.1


2022-05-15 15:59:38

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 02/13] openrisc: Cleanup emergency print handling

The emergency print support only works for 8250 compatible serial ports.
Now that OpenRISC platforms may be configured with different serial port
hardware we don't want emergency print to try to print to non-existent
hardware which will cause lockups.

This patch contains several fixes to get emergency print working again:

- Update symbol loading to not assume the location of symbols
- Split the putc print operation out to its own function to allow
for different future implementations.
- Update _emergency_print_nr and _emergency_print to use the putc
function.
- Guard serial 8250 specific sequences by CONFIG_SERIAL_8250
- Update string line feed from lf,cr to cr,lf.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/head.S | 148 +++++++++++++++++++++---------------
1 file changed, 85 insertions(+), 63 deletions(-)

diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
index 15f1b38dfe03..b1f3a65c271c 100644
--- a/arch/openrisc/kernel/head.S
+++ b/arch/openrisc/kernel/head.S
@@ -297,19 +297,23 @@
/* temporary store r3, r9 into r1, r10 */ ;\
l.addi r1,r3,0x0 ;\
l.addi r10,r9,0x0 ;\
- /* the string referenced by r3 must be low enough */ ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_unhandled_exception) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_unhandled_exception) ;\
+ l.nop ;\
l.mfspr r3,r0,SPR_NPC ;\
l.jal _emergency_print_nr ;\
- l.andi r3,r3,0x1f00 ;\
- /* the string referenced by r3 must be low enough */ ;\
+ l.andi r3,r3,0x1f00 ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_epc_prefix) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_epc_prefix) ;\
+ l.nop ;\
l.jal _emergency_print_nr ;\
- l.mfspr r3,r0,SPR_EPCR_BASE ;\
+ l.mfspr r3,r0,SPR_EPCR_BASE ;\
+ LOAD_SYMBOL_2_GPR(r9,_string_nl) ;\
+ tophys (r3,r9) ;\
l.jal _emergency_print ;\
- l.ori r3,r0,lo(_string_nl) ;\
+ l.nop ;\
/* end of printing */ ;\
l.addi r3,r1,0x0 ;\
l.addi r9,r10,0x0 ;\
@@ -1530,65 +1534,99 @@ trampoline_out:
l.jr r9
l.nop

-
/*
- * DSCR: prints a string referenced by r3.
+ * DESC: Prints ASCII character stored in r7
*
- * PRMS: r3 - address of the first character of null
- * terminated string to be printed
+ * PRMS: r7 - a 32-bit value with an ASCII character in the first byte
+ * position.
*
- * PREQ: UART at UART_BASE_ADD has to be initialized
+ * PREQ: The UART at UART_BASE_ADD has to be initialized
*
- * POST: caller should be aware that r3, r9 are changed
+ * POST: internally used but restores:
+ * r4 - to store UART_BASE_ADD
+ * r5 - for loading OFF_TXFULL / THRE,TEMT
+ * r6 - for storing bitmask (SERIAL_8250)
*/
-ENTRY(_emergency_print)
+ENTRY(_emergency_putc)
EMERGENCY_PRINT_STORE_GPR4
EMERGENCY_PRINT_STORE_GPR5
EMERGENCY_PRINT_STORE_GPR6
- EMERGENCY_PRINT_STORE_GPR7
-2:
- l.lbz r7,0(r3)
- l.sfeq r7,r0
- l.bf 9f
- l.nop

-// putc:
l.movhi r4,hi(UART_BASE_ADD)
+ l.ori r4,r4,lo(UART_BASE_ADD)

+#elif defined(CONFIG_SERIAL_8250)
+ /* Check UART LSR THRE (hold) bit */
l.addi r6,r0,0x20
1: l.lbz r5,5(r4)
l.andi r5,r5,0x20
l.sfeq r5,r6
l.bnf 1b
- l.nop
+ l.nop

+ /* Write character */
l.sb 0(r4),r7

+ /* Check UART LSR THRE|TEMT (hold, empty) bits */
l.addi r6,r0,0x60
1: l.lbz r5,5(r4)
l.andi r5,r5,0x60
l.sfeq r5,r6
l.bnf 1b
- l.nop
+ l.nop
+#endif
+ EMERGENCY_PRINT_LOAD_GPR6
+ EMERGENCY_PRINT_LOAD_GPR5
+ EMERGENCY_PRINT_LOAD_GPR4
+ l.jr r9
+ l.nop
+
+/*
+ * DSCR: prints a string referenced by r3.
+ *
+ * PRMS: r3 - address of the first character of null
+ * terminated string to be printed
+ *
+ * PREQ: UART at UART_BASE_ADD has to be initialized
+ *
+ * POST: caller should be aware that r3, r9 are changed
+ */
+ENTRY(_emergency_print)
+ EMERGENCY_PRINT_STORE_GPR7
+ EMERGENCY_PRINT_STORE_GPR9
+
+ /* Load character to r7, check for null terminator */
+2: l.lbz r7,0(r3)
+ l.sfeqi r7,0x0
+ l.bf 9f
+ l.nop
+
+ l.jal _emergency_putc
+ l.nop

/* next character */
l.j 2b
- l.addi r3,r3,0x1
+ l.addi r3,r3,0x1

9:
+ EMERGENCY_PRINT_LOAD_GPR9
EMERGENCY_PRINT_LOAD_GPR7
- EMERGENCY_PRINT_LOAD_GPR6
- EMERGENCY_PRINT_LOAD_GPR5
- EMERGENCY_PRINT_LOAD_GPR4
l.jr r9
- l.nop
+ l.nop

+/*
+ * DSCR: prints a number in r3 in hex.
+ *
+ * PRMS: r3 - a 32-bit unsigned integer
+ *
+ * PREQ: UART at UART_BASE_ADD has to be initialized
+ *
+ * POST: caller should be aware that r3, r9 are changed
+ */
ENTRY(_emergency_print_nr)
- EMERGENCY_PRINT_STORE_GPR4
- EMERGENCY_PRINT_STORE_GPR5
- EMERGENCY_PRINT_STORE_GPR6
EMERGENCY_PRINT_STORE_GPR7
EMERGENCY_PRINT_STORE_GPR8
+ EMERGENCY_PRINT_STORE_GPR9

l.addi r8,r0,32 // shift register

@@ -1600,58 +1638,39 @@ ENTRY(_emergency_print_nr)
/* don't skip the last zero if number == 0x0 */
l.sfeqi r8,0x4
l.bf 2f
- l.nop
+ l.nop

l.sfeq r7,r0
l.bf 1b
- l.nop
+ l.nop

2:
l.srl r7,r3,r8

l.andi r7,r7,0xf
l.sflts r8,r0
- l.bf 9f
+ l.bf 9f

+ /* Numbers greater than 9 translate to a-f */
l.sfgtui r7,0x9
l.bnf 8f
- l.nop
+ l.nop
l.addi r7,r7,0x27

-8:
- l.addi r7,r7,0x30
-// putc:
- l.movhi r4,hi(UART_BASE_ADD)
-
- l.addi r6,r0,0x20
-1: l.lbz r5,5(r4)
- l.andi r5,r5,0x20
- l.sfeq r5,r6
- l.bnf 1b
- l.nop
-
- l.sb 0(r4),r7
-
- l.addi r6,r0,0x60
-1: l.lbz r5,5(r4)
- l.andi r5,r5,0x60
- l.sfeq r5,r6
- l.bnf 1b
- l.nop
+ /* Convert to ascii and output character */
+8: l.jal _emergency_putc
+ l.addi r7,r7,0x30

/* next character */
l.j 2b
l.addi r8,r8,-0x4

9:
+ EMERGENCY_PRINT_LOAD_GPR9
EMERGENCY_PRINT_LOAD_GPR8
EMERGENCY_PRINT_LOAD_GPR7
- EMERGENCY_PRINT_LOAD_GPR6
- EMERGENCY_PRINT_LOAD_GPR5
- EMERGENCY_PRINT_LOAD_GPR4
l.jr r9
- l.nop
-
+ l.nop

/*
* This should be used for debugging only.
@@ -1676,7 +1695,9 @@ ENTRY(_emergency_print_nr)

ENTRY(_early_uart_init)
l.movhi r3,hi(UART_BASE_ADD)
+ l.ori r3,r3,lo(UART_BASE_ADD)

+#if defined(CONFIG_SERIAL_8250)
l.addi r4,r0,0x7
l.sb 0x2(r3),r4

@@ -1694,9 +1715,10 @@ ENTRY(_early_uart_init)
l.addi r4,r0,((UART_DIVISOR) & 0x000000ff)
l.sb UART_DLL(r3),r4
l.sb 0x3(r3),r5
+#endif

l.jr r9
- l.nop
+ l.nop

.align 0x1000
.global _secondary_evbar
@@ -1711,13 +1733,13 @@ _secondary_evbar:

.section .rodata
_string_unhandled_exception:
- .string "\n\rRunarunaround: Unhandled exception 0x\0"
+ .string "\r\nRunarunaround: Unhandled exception 0x\0"

_string_epc_prefix:
.string ": EPC=0x\0"

_string_nl:
- .string "\n\r\0"
+ .string "\r\n\0"


/* ========================================[ page aligned structures ]=== */
--
2.31.1


2022-05-15 17:39:24

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 07/13] openrisc/traps: Declare file scope symbols as static

Sparse was reporting the following warnings:

arch/openrisc/kernel/traps.c:37:5: warning: symbol 'kstack_depth_to_print' was not declared. Should it be static?
arch/openrisc/kernel/traps.c:39:22: warning: symbol 'lwa_addr' was not declared. Should it be static?
arch/openrisc/kernel/traps.c:41:6: warning: symbol 'print_trace' was not declared. Should it be static?

The function print_trace and local variables kstack_depth_to_print and
lwa_addr are not used outside of this file. This patch marks them as
static.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/traps.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index f2478bba77b9..9e0937eb31ca 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -34,11 +34,11 @@
#include <asm/unwinder.h>
#include <asm/sections.h>

-int kstack_depth_to_print = 0x180;
+static int kstack_depth_to_print = 0x180;
int lwa_flag;
-unsigned long __user *lwa_addr;
+static unsigned long __user *lwa_addr;

-void print_trace(void *data, unsigned long addr, int reliable)
+static void print_trace(void *data, unsigned long addr, int reliable)
{
const char *loglvl = data;

--
2.31.1


2022-05-15 17:41:30

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 09/13] openrisc/traps: Declare unhandled_exception for asmlinkage

Noticed this when workin on warnings. As unhandled_exception is used in
entry.S we should attribute it with asmlinkage.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/traps.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 99cd2e6f8873..fd9a0f2b66c4 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -235,7 +235,7 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
make_task_dead(SIGSEGV);
}

-void unhandled_exception(struct pt_regs *regs, int ea, int vector)
+asmlinkage void unhandled_exception(struct pt_regs *regs, int ea, int vector)
{
printk("Unable to handle exception at EA =0x%x, vector 0x%x",
ea, vector);
--
2.31.1


2022-05-15 19:53:25

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 04/13] openrisc: Add syscall details to emergency syscall debugging

When bringing linux on the or1k Marocchino we ran into issues starting
init. This patch adds the syscall number and return address to
assist tracing syscalls even before strace is able to be used.

By default this is all disabled but a developer could adjust the ifdef
to enable debugging.

Cc: Andrey Bacherov <[email protected]>
Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/entry.S | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S
index 3ca1b1f490b9..54a87bba35ca 100644
--- a/arch/openrisc/kernel/entry.S
+++ b/arch/openrisc/kernel/entry.S
@@ -601,7 +601,7 @@ UNHANDLED_EXCEPTION(_vector_0xb00,0xb00)
*/

_string_syscall_return:
- .string "syscall return %ld \n\r\0"
+ .string "syscall r9:0x%08x -> syscall(%ld) return %ld\0"
.align 4

ENTRY(_sys_call_handler)
@@ -679,15 +679,25 @@ _syscall_return:
_syscall_debug:
l.movhi r3,hi(_string_syscall_return)
l.ori r3,r3,lo(_string_syscall_return)
- l.ori r27,r0,1
+ l.ori r27,r0,2
l.sw -4(r1),r27
l.sw -8(r1),r11
- l.addi r1,r1,-8
+ l.lwz r29,PT_ORIG_GPR11(r1)
+ l.sw -12(r1),r29
+ l.lwz r29,PT_GPR9(r1)
+ l.sw -16(r1),r29
l.movhi r27,hi(_printk)
l.ori r27,r27,lo(_printk)
l.jalr r27
- l.nop
- l.addi r1,r1,8
+ l.addi r1,r1,-16
+ l.addi r1,r1,16
+#endif
+#if 0
+_syscall_show_regs:
+ l.movhi r27,hi(show_registers)
+ l.ori r27,r27,lo(show_registers)
+ l.jalr r27
+ l.or r3,r1,r1
#endif

_syscall_check_trace_leave:
--
2.31.1


2022-05-15 20:06:18

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 03/13] openrisc: Add support for liteuart emergency printing

This patch adds support for sending emergency print output, such as
unhandled exception details, to a liteuart serial device. This is the
default device available on litex platforms.

If a developer want to use this they should update UART_BASE_ADD
to the address of liteuart.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/head.S | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
index b1f3a65c271c..21db50563f97 100644
--- a/arch/openrisc/kernel/head.S
+++ b/arch/openrisc/kernel/head.S
@@ -1555,6 +1555,17 @@ ENTRY(_emergency_putc)
l.movhi r4,hi(UART_BASE_ADD)
l.ori r4,r4,lo(UART_BASE_ADD)

+#if defined(CONFIG_SERIAL_LITEUART)
+ /* Check OFF_TXFULL status */
+1: l.lwz r5,4(r4)
+ l.andi r5,r5,0xff
+ l.sfnei r5,0
+ l.bf 1b
+ l.nop
+
+ /* Write character */
+ l.andi r7,r7,0xff
+ l.sw 0(r4),r7
#elif defined(CONFIG_SERIAL_8250)
/* Check UART LSR THRE (hold) bit */
l.addi r6,r0,0x20
--
2.31.1


2022-05-15 20:47:20

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 11/13] openrisc/delay: Add include to fix symbol not declared warning

Add asm/timex.h include for read_current_timer prototype.

Sparse reporting the following warning:

arch/openrisc/lib/delay.c:23:5: warning: symbol 'read_current_timer' was not declared. Should it be static?

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/lib/delay.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/openrisc/lib/delay.c b/arch/openrisc/lib/delay.c
index 036ae57180ef..5e89e4131304 100644
--- a/arch/openrisc/lib/delay.c
+++ b/arch/openrisc/lib/delay.c
@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/init.h>
+#include <linux/timex.h>
#include <asm/param.h>
#include <asm/delay.h>
#include <asm/timex.h>
--
2.31.1


2022-05-16 01:13:00

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 13/13] openrisc: Remove unused IMMU tlb workardound

This looks to be some historical code that was used to convert TLB
misses on branches from l.bf, l.jal, l.j etc all to a trampoline
using l.jr (jump register). I don't see this being used and I don't
know the history of it so remove it.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/head.S | 209 ------------------------------------
1 file changed, 209 deletions(-)

diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
index 21db50563f97..9b59d0ca665c 100644
--- a/arch/openrisc/kernel/head.S
+++ b/arch/openrisc/kernel/head.S
@@ -1325,215 +1325,6 @@ i_pte_not_present:

/* =================================================[ debugging aids ]=== */

- .align 64
-_immu_trampoline:
- .space 64
-_immu_trampoline_top:
-
-#define TRAMP_SLOT_0 (0x0)
-#define TRAMP_SLOT_1 (0x4)
-#define TRAMP_SLOT_2 (0x8)
-#define TRAMP_SLOT_3 (0xc)
-#define TRAMP_SLOT_4 (0x10)
-#define TRAMP_SLOT_5 (0x14)
-#define TRAMP_FRAME_SIZE (0x18)
-
-ENTRY(_immu_trampoline_workaround)
- // r2 EEA
- // r6 is physical EEA
- tophys(r6,r2)
-
- LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
- tophys (r3,r5) // r3 is trampoline (physical)
-
- LOAD_SYMBOL_2_GPR(r4,0x15000000)
- l.sw TRAMP_SLOT_0(r3),r4
- l.sw TRAMP_SLOT_1(r3),r4
- l.sw TRAMP_SLOT_4(r3),r4
- l.sw TRAMP_SLOT_5(r3),r4
-
- // EPC = EEA - 0x4
- l.lwz r4,0x0(r6) // load op @ EEA + 0x0 (fc address)
- l.sw TRAMP_SLOT_3(r3),r4 // store it to _immu_trampoline_data
- l.lwz r4,-0x4(r6) // load op @ EEA - 0x4 (f8 address)
- l.sw TRAMP_SLOT_2(r3),r4 // store it to _immu_trampoline_data
-
- l.srli r5,r4,26 // check opcode for write access
- l.sfeqi r5,0 // l.j
- l.bf 0f
- l.sfeqi r5,0x11 // l.jr
- l.bf 1f
- l.sfeqi r5,1 // l.jal
- l.bf 2f
- l.sfeqi r5,0x12 // l.jalr
- l.bf 3f
- l.sfeqi r5,3 // l.bnf
- l.bf 4f
- l.sfeqi r5,4 // l.bf
- l.bf 5f
-99:
- l.nop
- l.j 99b // should never happen
- l.nop 1
-
- // r2 is EEA
- // r3 is trampoline address (physical)
- // r4 is instruction
- // r6 is physical(EEA)
- //
- // r5
-
-2: // l.jal
-
- /* 19 20 aa aa l.movhi r9,0xaaaa
- * a9 29 bb bb l.ori r9,0xbbbb
- *
- * where 0xaaaabbbb is EEA + 0x4 shifted right 2
- */
-
- l.addi r6,r2,0x4 // this is 0xaaaabbbb
-
- // l.movhi r9,0xaaaa
- l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9
- l.sh (TRAMP_SLOT_0+0x0)(r3),r5
- l.srli r5,r6,16
- l.sh (TRAMP_SLOT_0+0x2)(r3),r5
-
- // l.ori r9,0xbbbb
- l.ori r5,r0,0xa929 // 0xa929 == l.ori r9
- l.sh (TRAMP_SLOT_1+0x0)(r3),r5
- l.andi r5,r6,0xffff
- l.sh (TRAMP_SLOT_1+0x2)(r3),r5
-
- /* falthrough, need to set up new jump offset */
-
-
-0: // l.j
- l.slli r6,r4,6 // original offset shifted left 6 - 2
-// l.srli r6,r6,6 // original offset shifted right 2
-
- l.slli r4,r2,4 // old jump position: EEA shifted left 4
-// l.srli r4,r4,6 // old jump position: shifted right 2
-
- l.addi r5,r3,0xc // new jump position (physical)
- l.slli r5,r5,4 // new jump position: shifted left 4
-
- // calculate new jump offset
- // new_off = old_off + (old_jump - new_jump)
-
- l.sub r5,r4,r5 // old_jump - new_jump
- l.add r5,r6,r5 // orig_off + (old_jump - new_jump)
- l.srli r5,r5,6 // new offset shifted right 2
-
- // r5 is new jump offset
- // l.j has opcode 0x0...
- l.sw TRAMP_SLOT_2(r3),r5 // write it back
-
- l.j trampoline_out
- l.nop
-
-/* ----------------------------- */
-
-3: // l.jalr
-
- /* 19 20 aa aa l.movhi r9,0xaaaa
- * a9 29 bb bb l.ori r9,0xbbbb
- *
- * where 0xaaaabbbb is EEA + 0x4 shifted right 2
- */
-
- l.addi r6,r2,0x4 // this is 0xaaaabbbb
-
- // l.movhi r9,0xaaaa
- l.ori r5,r0,0x1920 // 0x1920 == l.movhi r9
- l.sh (TRAMP_SLOT_0+0x0)(r3),r5
- l.srli r5,r6,16
- l.sh (TRAMP_SLOT_0+0x2)(r3),r5
-
- // l.ori r9,0xbbbb
- l.ori r5,r0,0xa929 // 0xa929 == l.ori r9
- l.sh (TRAMP_SLOT_1+0x0)(r3),r5
- l.andi r5,r6,0xffff
- l.sh (TRAMP_SLOT_1+0x2)(r3),r5
-
- l.lhz r5,(TRAMP_SLOT_2+0x0)(r3) // load hi part of jump instruction
- l.andi r5,r5,0x3ff // clear out opcode part
- l.ori r5,r5,0x4400 // opcode changed from l.jalr -> l.jr
- l.sh (TRAMP_SLOT_2+0x0)(r3),r5 // write it back
-
- /* falthrough */
-
-1: // l.jr
- l.j trampoline_out
- l.nop
-
-/* ----------------------------- */
-
-4: // l.bnf
-5: // l.bf
- l.slli r6,r4,6 // original offset shifted left 6 - 2
-// l.srli r6,r6,6 // original offset shifted right 2
-
- l.slli r4,r2,4 // old jump position: EEA shifted left 4
-// l.srli r4,r4,6 // old jump position: shifted right 2
-
- l.addi r5,r3,0xc // new jump position (physical)
- l.slli r5,r5,4 // new jump position: shifted left 4
-
- // calculate new jump offset
- // new_off = old_off + (old_jump - new_jump)
-
- l.add r6,r6,r4 // (orig_off + old_jump)
- l.sub r6,r6,r5 // (orig_off + old_jump) - new_jump
- l.srli r6,r6,6 // new offset shifted right 2
-
- // r6 is new jump offset
- l.lwz r4,(TRAMP_SLOT_2+0x0)(r3) // load jump instruction
- l.srli r4,r4,16
- l.andi r4,r4,0xfc00 // get opcode part
- l.slli r4,r4,16
- l.or r6,r4,r6 // l.b(n)f new offset
- l.sw TRAMP_SLOT_2(r3),r6 // write it back
-
- /* we need to add l.j to EEA + 0x8 */
- tophys (r4,r2) // may not be needed (due to shifts down_
- l.addi r4,r4,(0x8 - 0x8) // jump target = r2 + 0x8 (compensate for 0x8)
- // jump position = r5 + 0x8 (0x8 compensated)
- l.sub r4,r4,r5 // jump offset = target - new_position + 0x8
-
- l.slli r4,r4,4 // the amount of info in imediate of jump
- l.srli r4,r4,6 // jump instruction with offset
- l.sw TRAMP_SLOT_4(r3),r4 // write it to 4th slot
-
- /* fallthrough */
-
-trampoline_out:
- // set up new EPC to point to our trampoline code
- LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
- l.mtspr r0,r5,SPR_EPCR_BASE
-
- // immu_trampoline is (4x) CACHE_LINE aligned
- // and only 6 instructions long,
- // so we need to invalidate only 2 lines
-
- /* Establish cache block size
- If BS=0, 16;
- If BS=1, 32;
- r14 contain block size
- */
- l.mfspr r21,r0,SPR_ICCFGR
- l.andi r21,r21,SPR_ICCFGR_CBS
- l.srli r21,r21,7
- l.ori r23,r0,16
- l.sll r14,r23,r21
-
- l.mtspr r0,r5,SPR_ICBIR
- l.add r5,r5,r14
- l.mtspr r0,r5,SPR_ICBIR
-
- l.jr r9
- l.nop
-
/*
* DESC: Prints ASCII character stored in r7
*
--
2.31.1


2022-05-16 04:26:43

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 05/13] openrisc: Pretty print show_registers memory dumps

Currently show registers, print memory dumps character by character and
there is no address information, so its a bit difficult to use. For
example before a stack dump looks as follows.

[ 13.650000] Stack:
[ 13.650000] Call trace
[ 13.690000] [<(ptrval)>] ? put_timespec64+0x44/0x60
[ 13.690000] [<(ptrval)>] ? _data_page_fault_handler+0x104/0x10c
[ 13.700000]
[ 13.700000] Code:
[ 13.700000] 13
[ 13.700000] ff
[ 13.700000] ff
[ 13.700000] f9
[ 13.710000] 84
[ 13.710000] 82
[ 13.710000] ff
[ 13.710000] bc
[ 13.710000] 07
[ 13.710000] fd
[ 13.720000] 4e
[ 13.720000] 67
[ 13.720000] 84
[ 13.720000] 62
[ 13.720000] ff
...

This change updates this to print the address and data a word at time.

[ 0.830000] Stack:
[ 0.830000] Call trace:
[ 0.830000] [<(ptrval)>] load_elf_binary+0x744/0xf5c
[ 0.830000] [<(ptrval)>] ? __kernel_read+0x144/0x184
[ 0.830000] [<(ptrval)>] bprm_execve+0x27c/0x3e4
[ 0.830000] [<(ptrval)>] kernel_execve+0x16c/0x1a0
[ 0.830000] [<(ptrval)>] run_init_process+0xa0/0xec
[ 0.830000] [<(ptrval)>] ? kernel_init+0x0/0x14c
[ 0.830000] [<(ptrval)>] kernel_init+0x7c/0x14c
[ 0.830000] [<(ptrval)>] ? calculate_sigpending+0x30/0x40
[ 0.830000] [<(ptrval)>] ret_from_fork+0x1c/0x84
[ 0.830000]
[ 0.830000] c1033dbc: c1033dec
[ 0.830000] c1033dc0: c015258c
[ 0.830000] c1033dc4: c129da00
[ 0.830000] c1033dc8: 00000002
[ 0.830000] c1033dcc: 00000000
[ 0.830000] c1033dd0: c129da00
[ 0.830000] c1033dd4: 00000000
[ 0.830000] c1033dd8: 00000000
[ 0.830000] (c1033ddc:) 00001e04
[ 0.830000] c1033de0: 001501fc
[ 0.830000] c1033de4: c1033e68
[ 0.830000] c1033de8: c0152e60
[ 0.830000] c1033dec: c129da5c
[ 0.830000] c1033df0: c0674a20
[ 0.830000] c1033df4: c1033e50
[ 0.830000] c1033df8: c00e3d6c
[ 0.830000] c1033dfc: c129da5c
[ 0.830000] c1033e00: 00000003
[ 0.830000] c1033e04: 00150000
[ 0.830000] c1033e08: 00002034
[ 0.830000] c1033e0c: 001501fc
[ 0.830000] c1033e10: 00000000
[ 0.830000] c1033e14: 00150000
[ 0.830000] c1033e18: 0014ebbc
[ 0.830000] c1033e1c: 00002000
[ 0.830000] c1033e20: 00000003
[ 0.830000] c1033e24: c12a07e0
[ 0.830000] c1033e28: 00000000
[ 0.830000] c1033e2c: 00000000
[ 0.830000] c1033e30: 00000000
[ 0.830000] c1033e34: 40040000
[ 0.830000] c1033e38: 00000000
[ 0.830000]
[ 0.830000] Code:
[ 0.830000] c00047a4: 9c21fff8
[ 0.830000] c00047a8: d4012000
[ 0.830000] c00047ac: d4011804
[ 0.830000] c00047b0: e4040000
[ 0.830000] c00047b4: 10000005
[ 0.830000] c00047b8: 9c84ffff
[ 0.830000] (c00047bc:) d8030000
[ 0.830000] c00047c0: 03fffffc
[ 0.830000] c00047c4: 9c630001
[ 0.830000] c00047c8: 9d640001
[ 0.830000] c00047cc: 84810000
[ 0.830000] c00047d0: 84610004

Now we are also printing a bit of the stack as well as the code. The
stack is output to help with debugging. There may be concern about
exposing sensitive information on the stack, but we are already dumping
all register content which would have similar sensitive information. So
I am going ahead as this proves useful in investigation.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/traps.c | 46 ++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 13 deletions(-)

diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 0446a3c34372..f2478bba77b9 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -46,6 +46,14 @@ void print_trace(void *data, unsigned long addr, int reliable)
(void *) addr);
}

+static void print_data(unsigned long base_addr, unsigned long word, int i)
+{
+ if (i == 0)
+ printk("(%08lx:)\t%08lx", base_addr + (i * 4), word);
+ else
+ printk(" %08lx:\t%08lx", base_addr + (i * 4), word);
+}
+
/* displays a short stack trace */
void show_stack(struct task_struct *task, unsigned long *esp, const char *loglvl)
{
@@ -99,22 +107,36 @@ void show_registers(struct pt_regs *regs)
printk("\nStack: ");
show_stack(NULL, (unsigned long *)esp, KERN_EMERG);

+ if (esp < PAGE_OFFSET)
+ goto bad_stack;
+
+ printk("\n");
+ for (i = -8; i < 24; i += 1) {
+ unsigned long word;
+
+ if (__get_user(word, &((unsigned long *)esp)[i])) {
+bad_stack:
+ printk(" Bad Stack value.");
+ break;
+ }
+
+ print_data(esp, word, i);
+ }
+
printk("\nCode: ");
if (regs->pc < PAGE_OFFSET)
goto bad;

- for (i = -24; i < 24; i++) {
- unsigned char c;
- if (__get_user(c, &((unsigned char *)regs->pc)[i])) {
+ for (i = -6; i < 6; i += 1) {
+ unsigned long word;
+
+ if (__get_user(word, &((unsigned long *)regs->pc)[i])) {
bad:
printk(" Bad PC value.");
break;
}

- if (i == 0)
- printk("(%02x) ", c);
- else
- printk("%02x ", c);
+ print_data(regs->pc, word, i);
}
}
printk("\n");
@@ -185,13 +207,11 @@ void nommu_dump_state(struct pt_regs *regs,
printk("\nCode: ");

for (i = -24; i < 24; i++) {
- unsigned char c;
- c = ((unsigned char *)(__pa(regs->pc)))[i];
+ unsigned long word;
+
+ word = ((unsigned long *)(__pa(regs->pc)))[i];

- if (i == 0)
- printk("(%02x) ", c);
- else
- printk("%02x ", c);
+ print_data(regs->pc, word, i);
}
printk("\n");
}
--
2.31.1


2022-05-16 05:42:32

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 12/13] openrisc/fault: Fix symbol scope warnings

Sparse reported the following warning:

arch/openrisc/mm/fault.c:27:15: warning: symbol 'pte_misses' was not declared. Should it be static?
arch/openrisc/mm/fault.c:28:15: warning: symbol 'pte_errors' was not declared. Should it be static?
arch/openrisc/mm/fault.c:33:16: warning: symbol 'current_pgd' was not declared. Should it be static?

This patch fixes these by:
- Remove unused pte_misses and pte_errors counters which are no longer
used.
- Add asm/mmu_context.h include to provide the current_pgd declaration.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/mm/fault.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/arch/openrisc/mm/fault.c b/arch/openrisc/mm/fault.c
index 80bb66ad42f6..516cba14dec9 100644
--- a/arch/openrisc/mm/fault.c
+++ b/arch/openrisc/mm/fault.c
@@ -18,15 +18,13 @@
#include <linux/perf_event.h>

#include <linux/uaccess.h>
+#include <asm/mmu_context.h>
#include <asm/siginfo.h>
#include <asm/signal.h>

#define NUM_TLB_ENTRIES 64
#define TLB_OFFSET(add) (((add) >> PAGE_SHIFT) & (NUM_TLB_ENTRIES-1))

-unsigned long pte_misses; /* updated by do_page_fault() */
-unsigned long pte_errors; /* updated by do_page_fault() */
-
/* __PHX__ :: - check the vmalloc_fault in do_page_fault()
* - also look into include/asm/mmu_context.h
*/
--
2.31.1


2022-05-16 12:01:32

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 08/13] openrisc/traps: Remove die_if_kernel function

This was noticed when I saw this warning:

arch/openrisc/kernel/traps.c:234:6: warning: no previous prototype for 'die_if_kernel' [-Wmissing-prototypes]
234 | void die_if_kernel(const char *str, struct pt_regs *regs, long err)
| ^~~~~~~~~~~~~

The die_if_kernel function is not used in the OpenRISC port so remove
it.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/kernel/traps.c | 9 ---------
1 file changed, 9 deletions(-)

diff --git a/arch/openrisc/kernel/traps.c b/arch/openrisc/kernel/traps.c
index 9e0937eb31ca..99cd2e6f8873 100644
--- a/arch/openrisc/kernel/traps.c
+++ b/arch/openrisc/kernel/traps.c
@@ -235,15 +235,6 @@ void __noreturn die(const char *str, struct pt_regs *regs, long err)
make_task_dead(SIGSEGV);
}

-/* This is normally the 'Oops' routine */
-void die_if_kernel(const char *str, struct pt_regs *regs, long err)
-{
- if (user_mode(regs))
- return;
-
- die(str, regs, err);
-}
-
void unhandled_exception(struct pt_regs *regs, int ea, int vector)
{
printk("Unable to handle exception at EA =0x%x, vector 0x%x",
--
2.31.1


2022-05-16 12:50:04

by Stafford Horne

[permalink] [raw]
Subject: [PATCH 06/13] openrisc: Update litex defconfig to support glibc userland

I have been using a litex SoC for glibc verification. Update the
default litex config to support required userspace API's needed for the
full glibc testsuite to pass.

This includes enabling the litex mmc driver and filesystems used
in a typical litex environment.

Signed-off-by: Stafford Horne <[email protected]>
---
arch/openrisc/configs/or1klitex_defconfig | 33 +++++++++++++++++++++++
1 file changed, 33 insertions(+)

diff --git a/arch/openrisc/configs/or1klitex_defconfig b/arch/openrisc/configs/or1klitex_defconfig
index d695879a4d26..4c0138340bd9 100644
--- a/arch/openrisc/configs/or1klitex_defconfig
+++ b/arch/openrisc/configs/or1klitex_defconfig
@@ -1,22 +1,55 @@
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_CGROUPS=y
+CONFIG_NAMESPACES=y
+CONFIG_USER_NS=y
CONFIG_BLK_DEV_INITRD=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SGETMASK_SYSCALL=y
CONFIG_EMBEDDED=y
CONFIG_OPENRISC_BUILTIN_DTB="or1klitex"
+# CONFIG_OPENRISC_HAVE_INST_RORI is not set
CONFIG_HZ_100=y
+CONFIG_OPENRISC_HAVE_SHADOW_GPRS=y
CONFIG_NET=y
CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=y
CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=y
CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_INET_UDP_DIAG=y
+CONFIG_INET_RAW_DIAG=y
+# CONFIG_WIRELESS is not set
+# CONFIG_ETHTOOL_NETLINK is not set
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
CONFIG_OF_OVERLAY=y
CONFIG_NETDEVICES=y
CONFIG_LITEX_LITEETH=y
+# CONFIG_WLAN is not set
CONFIG_SERIAL_LITEUART=y
CONFIG_SERIAL_LITEUART_CONSOLE=y
CONFIG_TTY_PRINTK=y
+# CONFIG_GPIO_CDEV is not set
+CONFIG_MMC=y
+CONFIG_MMC_LITEX=y
+# CONFIG_VHOST_MENU is not set
+# CONFIG_IOMMU_SUPPORT is not set
CONFIG_LITEX_SOC_CONTROLLER=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_EXFAT_FS=y
CONFIG_TMPFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_LSM="lockdown,yama,loadpin,safesetid,integrity,bpf"
CONFIG_PRINTK_TIME=y
CONFIG_PANIC_ON_OOPS=y
CONFIG_SOFTLOCKUP_DETECTOR=y
--
2.31.1


2022-05-16 13:44:14

by Samuel Holland

[permalink] [raw]
Subject: Re: [PATCH 02/13] openrisc: Cleanup emergency print handling

Hi Stafford,

On 5/15/22 7:41 AM, Stafford Horne wrote:
> The emergency print support only works for 8250 compatible serial ports.
> Now that OpenRISC platforms may be configured with different serial port
> hardware we don't want emergency print to try to print to non-existent
> hardware which will cause lockups.
>
> This patch contains several fixes to get emergency print working again:
>
> - Update symbol loading to not assume the location of symbols
> - Split the putc print operation out to its own function to allow
> for different future implementations.
> - Update _emergency_print_nr and _emergency_print to use the putc
> function.
> - Guard serial 8250 specific sequences by CONFIG_SERIAL_8250
> - Update string line feed from lf,cr to cr,lf.
>
> Signed-off-by: Stafford Horne <[email protected]>
> ---
> arch/openrisc/kernel/head.S | 148 +++++++++++++++++++++---------------
> 1 file changed, 85 insertions(+), 63 deletions(-)
>
> diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
> index 15f1b38dfe03..b1f3a65c271c 100644
> --- a/arch/openrisc/kernel/head.S
> +++ b/arch/openrisc/kernel/head.S
> @@ -297,19 +297,23 @@
> /* temporary store r3, r9 into r1, r10 */ ;\
> l.addi r1,r3,0x0 ;\
> l.addi r10,r9,0x0 ;\
> - /* the string referenced by r3 must be low enough */ ;\
> + LOAD_SYMBOL_2_GPR(r9,_string_unhandled_exception) ;\
> + tophys (r3,r9) ;\
> l.jal _emergency_print ;\
> - l.ori r3,r0,lo(_string_unhandled_exception) ;\
> + l.nop ;\
> l.mfspr r3,r0,SPR_NPC ;\
> l.jal _emergency_print_nr ;\
> - l.andi r3,r3,0x1f00 ;\
> - /* the string referenced by r3 must be low enough */ ;\
> + l.andi r3,r3,0x1f00 ;\
> + LOAD_SYMBOL_2_GPR(r9,_string_epc_prefix) ;\
> + tophys (r3,r9) ;\
> l.jal _emergency_print ;\
> - l.ori r3,r0,lo(_string_epc_prefix) ;\
> + l.nop ;\
> l.jal _emergency_print_nr ;\
> - l.mfspr r3,r0,SPR_EPCR_BASE ;\
> + l.mfspr r3,r0,SPR_EPCR_BASE ;\
> + LOAD_SYMBOL_2_GPR(r9,_string_nl) ;\
> + tophys (r3,r9) ;\
> l.jal _emergency_print ;\
> - l.ori r3,r0,lo(_string_nl) ;\
> + l.nop ;\
> /* end of printing */ ;\
> l.addi r3,r1,0x0 ;\
> l.addi r9,r10,0x0 ;\
> @@ -1530,65 +1534,99 @@ trampoline_out:
> l.jr r9
> l.nop
>
> -
> /*
> - * DSCR: prints a string referenced by r3.
> + * DESC: Prints ASCII character stored in r7
> *
> - * PRMS: r3 - address of the first character of null
> - * terminated string to be printed
> + * PRMS: r7 - a 32-bit value with an ASCII character in the first byte
> + * position.
> *
> - * PREQ: UART at UART_BASE_ADD has to be initialized
> + * PREQ: The UART at UART_BASE_ADD has to be initialized
> *
> - * POST: caller should be aware that r3, r9 are changed
> + * POST: internally used but restores:
> + * r4 - to store UART_BASE_ADD
> + * r5 - for loading OFF_TXFULL / THRE,TEMT
> + * r6 - for storing bitmask (SERIAL_8250)
> */
> -ENTRY(_emergency_print)
> +ENTRY(_emergency_putc)
> EMERGENCY_PRINT_STORE_GPR4
> EMERGENCY_PRINT_STORE_GPR5
> EMERGENCY_PRINT_STORE_GPR6
> - EMERGENCY_PRINT_STORE_GPR7
> -2:
> - l.lbz r7,0(r3)
> - l.sfeq r7,r0
> - l.bf 9f
> - l.nop
>
> -// putc:
> l.movhi r4,hi(UART_BASE_ADD)
> + l.ori r4,r4,lo(UART_BASE_ADD)
>
> +#elif defined(CONFIG_SERIAL_8250)

This needs to use #if in this patch (and #elif in the next patch).

Regards,
Samuel

> + /* Check UART LSR THRE (hold) bit */
> l.addi r6,r0,0x20
> 1: l.lbz r5,5(r4)
> l.andi r5,r5,0x20
> l.sfeq r5,r6
> l.bnf 1b
> - l.nop
> + l.nop
>
> + /* Write character */
> l.sb 0(r4),r7
>
> + /* Check UART LSR THRE|TEMT (hold, empty) bits */
> l.addi r6,r0,0x60
> 1: l.lbz r5,5(r4)
> l.andi r5,r5,0x60
> l.sfeq r5,r6
> l.bnf 1b
> - l.nop
> + l.nop
> +#endif
> + EMERGENCY_PRINT_LOAD_GPR6
> + EMERGENCY_PRINT_LOAD_GPR5
> + EMERGENCY_PRINT_LOAD_GPR4
> + l.jr r9
> + l.nop
> +
> +/*
> + * DSCR: prints a string referenced by r3.
> + *
> + * PRMS: r3 - address of the first character of null
> + * terminated string to be printed
> + *
> + * PREQ: UART at UART_BASE_ADD has to be initialized
> + *
> + * POST: caller should be aware that r3, r9 are changed
> + */
> +ENTRY(_emergency_print)
> + EMERGENCY_PRINT_STORE_GPR7
> + EMERGENCY_PRINT_STORE_GPR9
> +
> + /* Load character to r7, check for null terminator */
> +2: l.lbz r7,0(r3)
> + l.sfeqi r7,0x0
> + l.bf 9f
> + l.nop
> +
> + l.jal _emergency_putc
> + l.nop
>
> /* next character */
> l.j 2b
> - l.addi r3,r3,0x1
> + l.addi r3,r3,0x1
>
> 9:
> + EMERGENCY_PRINT_LOAD_GPR9
> EMERGENCY_PRINT_LOAD_GPR7
> - EMERGENCY_PRINT_LOAD_GPR6
> - EMERGENCY_PRINT_LOAD_GPR5
> - EMERGENCY_PRINT_LOAD_GPR4
> l.jr r9
> - l.nop
> + l.nop
>
> +/*
> + * DSCR: prints a number in r3 in hex.
> + *
> + * PRMS: r3 - a 32-bit unsigned integer
> + *
> + * PREQ: UART at UART_BASE_ADD has to be initialized
> + *
> + * POST: caller should be aware that r3, r9 are changed
> + */
> ENTRY(_emergency_print_nr)
> - EMERGENCY_PRINT_STORE_GPR4
> - EMERGENCY_PRINT_STORE_GPR5
> - EMERGENCY_PRINT_STORE_GPR6
> EMERGENCY_PRINT_STORE_GPR7
> EMERGENCY_PRINT_STORE_GPR8
> + EMERGENCY_PRINT_STORE_GPR9
>
> l.addi r8,r0,32 // shift register
>
> @@ -1600,58 +1638,39 @@ ENTRY(_emergency_print_nr)
> /* don't skip the last zero if number == 0x0 */
> l.sfeqi r8,0x4
> l.bf 2f
> - l.nop
> + l.nop
>
> l.sfeq r7,r0
> l.bf 1b
> - l.nop
> + l.nop
>
> 2:
> l.srl r7,r3,r8
>
> l.andi r7,r7,0xf
> l.sflts r8,r0
> - l.bf 9f
> + l.bf 9f
>
> + /* Numbers greater than 9 translate to a-f */
> l.sfgtui r7,0x9
> l.bnf 8f
> - l.nop
> + l.nop
> l.addi r7,r7,0x27
>
> -8:
> - l.addi r7,r7,0x30
> -// putc:
> - l.movhi r4,hi(UART_BASE_ADD)
> -
> - l.addi r6,r0,0x20
> -1: l.lbz r5,5(r4)
> - l.andi r5,r5,0x20
> - l.sfeq r5,r6
> - l.bnf 1b
> - l.nop
> -
> - l.sb 0(r4),r7
> -
> - l.addi r6,r0,0x60
> -1: l.lbz r5,5(r4)
> - l.andi r5,r5,0x60
> - l.sfeq r5,r6
> - l.bnf 1b
> - l.nop
> + /* Convert to ascii and output character */
> +8: l.jal _emergency_putc
> + l.addi r7,r7,0x30
>
> /* next character */
> l.j 2b
> l.addi r8,r8,-0x4
>
> 9:
> + EMERGENCY_PRINT_LOAD_GPR9
> EMERGENCY_PRINT_LOAD_GPR8
> EMERGENCY_PRINT_LOAD_GPR7
> - EMERGENCY_PRINT_LOAD_GPR6
> - EMERGENCY_PRINT_LOAD_GPR5
> - EMERGENCY_PRINT_LOAD_GPR4
> l.jr r9
> - l.nop
> -
> + l.nop
>
> /*
> * This should be used for debugging only.
> @@ -1676,7 +1695,9 @@ ENTRY(_emergency_print_nr)
>
> ENTRY(_early_uart_init)
> l.movhi r3,hi(UART_BASE_ADD)
> + l.ori r3,r3,lo(UART_BASE_ADD)
>
> +#if defined(CONFIG_SERIAL_8250)
> l.addi r4,r0,0x7
> l.sb 0x2(r3),r4
>
> @@ -1694,9 +1715,10 @@ ENTRY(_early_uart_init)
> l.addi r4,r0,((UART_DIVISOR) & 0x000000ff)
> l.sb UART_DLL(r3),r4
> l.sb 0x3(r3),r5
> +#endif
>
> l.jr r9
> - l.nop
> + l.nop
>
> .align 0x1000
> .global _secondary_evbar
> @@ -1711,13 +1733,13 @@ _secondary_evbar:
>
> .section .rodata
> _string_unhandled_exception:
> - .string "\n\rRunarunaround: Unhandled exception 0x\0"
> + .string "\r\nRunarunaround: Unhandled exception 0x\0"
>
> _string_epc_prefix:
> .string ": EPC=0x\0"
>
> _string_nl:
> - .string "\n\r\0"
> + .string "\r\n\0"
>
>
> /* ========================================[ page aligned structures ]=== */
>


2022-05-16 13:50:16

by Stafford Horne

[permalink] [raw]
Subject: Re: [PATCH 02/13] openrisc: Cleanup emergency print handling

On Sun, May 15, 2022 at 11:03:47AM -0500, Samuel Holland wrote:
> Hi Stafford,
>
> On 5/15/22 7:41 AM, Stafford Horne wrote:
> > The emergency print support only works for 8250 compatible serial ports.
> > Now that OpenRISC platforms may be configured with different serial port
> > hardware we don't want emergency print to try to print to non-existent
> > hardware which will cause lockups.
> >
> > This patch contains several fixes to get emergency print working again:
> >
> > - Update symbol loading to not assume the location of symbols
> > - Split the putc print operation out to its own function to allow
> > for different future implementations.
> > - Update _emergency_print_nr and _emergency_print to use the putc
> > function.
> > - Guard serial 8250 specific sequences by CONFIG_SERIAL_8250
> > - Update string line feed from lf,cr to cr,lf.
> >
> > Signed-off-by: Stafford Horne <[email protected]>
> > ---
> > arch/openrisc/kernel/head.S | 148 +++++++++++++++++++++---------------
> > 1 file changed, 85 insertions(+), 63 deletions(-)
> >
> > diff --git a/arch/openrisc/kernel/head.S b/arch/openrisc/kernel/head.S
> > index 15f1b38dfe03..b1f3a65c271c 100644
> > --- a/arch/openrisc/kernel/head.S
> > +++ b/arch/openrisc/kernel/head.S
> > @@ -297,19 +297,23 @@
> > /* temporary store r3, r9 into r1, r10 */ ;\
> > l.addi r1,r3,0x0 ;\
> > l.addi r10,r9,0x0 ;\
> > - /* the string referenced by r3 must be low enough */ ;\
> > + LOAD_SYMBOL_2_GPR(r9,_string_unhandled_exception) ;\
> > + tophys (r3,r9) ;\
> > l.jal _emergency_print ;\
> > - l.ori r3,r0,lo(_string_unhandled_exception) ;\
> > + l.nop ;\
> > l.mfspr r3,r0,SPR_NPC ;\
> > l.jal _emergency_print_nr ;\
> > - l.andi r3,r3,0x1f00 ;\
> > - /* the string referenced by r3 must be low enough */ ;\
> > + l.andi r3,r3,0x1f00 ;\
> > + LOAD_SYMBOL_2_GPR(r9,_string_epc_prefix) ;\
> > + tophys (r3,r9) ;\
> > l.jal _emergency_print ;\
> > - l.ori r3,r0,lo(_string_epc_prefix) ;\
> > + l.nop ;\
> > l.jal _emergency_print_nr ;\
> > - l.mfspr r3,r0,SPR_EPCR_BASE ;\
> > + l.mfspr r3,r0,SPR_EPCR_BASE ;\
> > + LOAD_SYMBOL_2_GPR(r9,_string_nl) ;\
> > + tophys (r3,r9) ;\
> > l.jal _emergency_print ;\
> > - l.ori r3,r0,lo(_string_nl) ;\
> > + l.nop ;\
> > /* end of printing */ ;\
> > l.addi r3,r1,0x0 ;\
> > l.addi r9,r10,0x0 ;\
> > @@ -1530,65 +1534,99 @@ trampoline_out:
> > l.jr r9
> > l.nop
> >
> > -
> > /*
> > - * DSCR: prints a string referenced by r3.
> > + * DESC: Prints ASCII character stored in r7
> > *
> > - * PRMS: r3 - address of the first character of null
> > - * terminated string to be printed
> > + * PRMS: r7 - a 32-bit value with an ASCII character in the first byte
> > + * position.
> > *
> > - * PREQ: UART at UART_BASE_ADD has to be initialized
> > + * PREQ: The UART at UART_BASE_ADD has to be initialized
> > *
> > - * POST: caller should be aware that r3, r9 are changed
> > + * POST: internally used but restores:
> > + * r4 - to store UART_BASE_ADD
> > + * r5 - for loading OFF_TXFULL / THRE,TEMT
> > + * r6 - for storing bitmask (SERIAL_8250)
> > */
> > -ENTRY(_emergency_print)
> > +ENTRY(_emergency_putc)
> > EMERGENCY_PRINT_STORE_GPR4
> > EMERGENCY_PRINT_STORE_GPR5
> > EMERGENCY_PRINT_STORE_GPR6
> > - EMERGENCY_PRINT_STORE_GPR7
> > -2:
> > - l.lbz r7,0(r3)
> > - l.sfeq r7,r0
> > - l.bf 9f
> > - l.nop
> >
> > -// putc:
> > l.movhi r4,hi(UART_BASE_ADD)
> > + l.ori r4,r4,lo(UART_BASE_ADD)
> >
> > +#elif defined(CONFIG_SERIAL_8250)
>
> This needs to use #if in this patch (and #elif in the next patch).

Thnak you. right, I split these patches up at the last moment
and I messed up these ifdefs. They work together but not separated.

I will fix this, do some testing and send a v2 tomorrow.

Patches posted here:

https://github.com/stffrdhrn/linux/commits/or1k-5.19-cleanups

-Stafford

> > + /* Check UART LSR THRE (hold) bit */
> > l.addi r6,r0,0x20
> > 1: l.lbz r5,5(r4)
> > l.andi r5,r5,0x20
> > l.sfeq r5,r6
> > l.bnf 1b
> > - l.nop
> > + l.nop
> >
> > + /* Write character */
> > l.sb 0(r4),r7
> >
> > + /* Check UART LSR THRE|TEMT (hold, empty) bits */
> > l.addi r6,r0,0x60
> > 1: l.lbz r5,5(r4)
> > l.andi r5,r5,0x60
> > l.sfeq r5,r6
> > l.bnf 1b
> > - l.nop
> > + l.nop
> > +#endif
> > + EMERGENCY_PRINT_LOAD_GPR6
> > + EMERGENCY_PRINT_LOAD_GPR5
> > + EMERGENCY_PRINT_LOAD_GPR4
> > + l.jr r9
> > + l.nop
> > +
> > +/*
> > + * DSCR: prints a string referenced by r3.
> > + *
> > + * PRMS: r3 - address of the first character of null
> > + * terminated string to be printed
> > + *
> > + * PREQ: UART at UART_BASE_ADD has to be initialized
> > + *
> > + * POST: caller should be aware that r3, r9 are changed
> > + */
> > +ENTRY(_emergency_print)
> > + EMERGENCY_PRINT_STORE_GPR7
> > + EMERGENCY_PRINT_STORE_GPR9
> > +
> > + /* Load character to r7, check for null terminator */
> > +2: l.lbz r7,0(r3)
> > + l.sfeqi r7,0x0
> > + l.bf 9f
> > + l.nop
> > +
> > + l.jal _emergency_putc
> > + l.nop
> >
> > /* next character */
> > l.j 2b
> > - l.addi r3,r3,0x1
> > + l.addi r3,r3,0x1
> >
> > 9:
> > + EMERGENCY_PRINT_LOAD_GPR9
> > EMERGENCY_PRINT_LOAD_GPR7
> > - EMERGENCY_PRINT_LOAD_GPR6
> > - EMERGENCY_PRINT_LOAD_GPR5
> > - EMERGENCY_PRINT_LOAD_GPR4
> > l.jr r9
> > - l.nop
> > + l.nop
> >
> > +/*
> > + * DSCR: prints a number in r3 in hex.
> > + *
> > + * PRMS: r3 - a 32-bit unsigned integer
> > + *
> > + * PREQ: UART at UART_BASE_ADD has to be initialized
> > + *
> > + * POST: caller should be aware that r3, r9 are changed
> > + */
> > ENTRY(_emergency_print_nr)
> > - EMERGENCY_PRINT_STORE_GPR4
> > - EMERGENCY_PRINT_STORE_GPR5
> > - EMERGENCY_PRINT_STORE_GPR6
> > EMERGENCY_PRINT_STORE_GPR7
> > EMERGENCY_PRINT_STORE_GPR8
> > + EMERGENCY_PRINT_STORE_GPR9
> >
> > l.addi r8,r0,32 // shift register
> >
> > @@ -1600,58 +1638,39 @@ ENTRY(_emergency_print_nr)
> > /* don't skip the last zero if number == 0x0 */
> > l.sfeqi r8,0x4
> > l.bf 2f
> > - l.nop
> > + l.nop
> >
> > l.sfeq r7,r0
> > l.bf 1b
> > - l.nop
> > + l.nop
> >
> > 2:
> > l.srl r7,r3,r8
> >
> > l.andi r7,r7,0xf
> > l.sflts r8,r0
> > - l.bf 9f
> > + l.bf 9f
> >
> > + /* Numbers greater than 9 translate to a-f */
> > l.sfgtui r7,0x9
> > l.bnf 8f
> > - l.nop
> > + l.nop
> > l.addi r7,r7,0x27
> >
> > -8:
> > - l.addi r7,r7,0x30
> > -// putc:
> > - l.movhi r4,hi(UART_BASE_ADD)
> > -
> > - l.addi r6,r0,0x20
> > -1: l.lbz r5,5(r4)
> > - l.andi r5,r5,0x20
> > - l.sfeq r5,r6
> > - l.bnf 1b
> > - l.nop
> > -
> > - l.sb 0(r4),r7
> > -
> > - l.addi r6,r0,0x60
> > -1: l.lbz r5,5(r4)
> > - l.andi r5,r5,0x60
> > - l.sfeq r5,r6
> > - l.bnf 1b
> > - l.nop
> > + /* Convert to ascii and output character */
> > +8: l.jal _emergency_putc
> > + l.addi r7,r7,0x30
> >
> > /* next character */
> > l.j 2b
> > l.addi r8,r8,-0x4
> >
> > 9:
> > + EMERGENCY_PRINT_LOAD_GPR9
> > EMERGENCY_PRINT_LOAD_GPR8
> > EMERGENCY_PRINT_LOAD_GPR7
> > - EMERGENCY_PRINT_LOAD_GPR6
> > - EMERGENCY_PRINT_LOAD_GPR5
> > - EMERGENCY_PRINT_LOAD_GPR4
> > l.jr r9
> > - l.nop
> > -
> > + l.nop
> >
> > /*
> > * This should be used for debugging only.
> > @@ -1676,7 +1695,9 @@ ENTRY(_emergency_print_nr)
> >
> > ENTRY(_early_uart_init)
> > l.movhi r3,hi(UART_BASE_ADD)
> > + l.ori r3,r3,lo(UART_BASE_ADD)
> >
> > +#if defined(CONFIG_SERIAL_8250)
> > l.addi r4,r0,0x7
> > l.sb 0x2(r3),r4
> >
> > @@ -1694,9 +1715,10 @@ ENTRY(_early_uart_init)
> > l.addi r4,r0,((UART_DIVISOR) & 0x000000ff)
> > l.sb UART_DLL(r3),r4
> > l.sb 0x3(r3),r5
> > +#endif
> >
> > l.jr r9
> > - l.nop
> > + l.nop
> >
> > .align 0x1000
> > .global _secondary_evbar
> > @@ -1711,13 +1733,13 @@ _secondary_evbar:
> >
> > .section .rodata
> > _string_unhandled_exception:
> > - .string "\n\rRunarunaround: Unhandled exception 0x\0"
> > + .string "\r\nRunarunaround: Unhandled exception 0x\0"
> >
> > _string_epc_prefix:
> > .string ": EPC=0x\0"
> >
> > _string_nl:
> > - .string "\n\r\0"
> > + .string "\r\n\0"
> >
> >
> > /* ========================================[ page aligned structures ]=== */
> >
>