Pull OpenRISC updates from Stafford Horne:

 - A few sparse warning fixups and other cleanups I noticed when working
   on a recent TLB bug found on a new OpenRISC core bring up.

 - A few fixup's from me and Jason A Donenfeld to help shutdown OpenRISC
   platforms when running CI tests

* tag 'for-linus' of https://github.com/openrisc/linux:
  openrisc: Allow power off handler overriding
  openrisc: Remove unused IMMU tlb workardound
  openrisc/fault: Fix symbol scope warnings
  openrisc/delay: Add include to fix symbol not declared warning
  openrisc/time: Fix symbol scope warnings
  openrisc/traps: Declare unhandled_exception for asmlinkage
  openrisc/traps: Remove die_if_kernel function
  openrisc/traps: Declare file scope symbols as static
  openrisc: Update litex defconfig to support glibc userland
  openrisc: Pretty print show_registers memory dumps
  openrisc: Add syscall details to emergency syscall debugging
  openrisc: Add support for liteuart emergency printing
  openrisc: Cleanup emergency print handling
  openrisc: Add gcc machine instruction flag configuration
  openrisc: define nop command for simulator reboot
  openrisc: remove bogus nops and shutdowns
  openrisc: fix typos in comments
This commit is contained in:
Linus Torvalds
2022-05-26 17:27:49 -07:00
11 changed files with 275 additions and 318 deletions

View File

@@ -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 ;\
@@ -1330,215 +1334,63 @@ i_pte_not_present:
/* =================================================[ debugging aids ]=== */
.align 64
_immu_trampoline:
.space 64
_immu_trampoline_top:
/*
* DESC: Prints ASCII character stored in r7
*
* PRMS: r7 - a 32-bit value with an ASCII character in the first byte
* position.
*
* PREQ: The UART at UART_BASE_ADD has to be initialized
*
* 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_putc)
EMERGENCY_PRINT_STORE_GPR4
EMERGENCY_PRINT_STORE_GPR5
EMERGENCY_PRINT_STORE_GPR6
#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)
l.movhi r4,hi(UART_BASE_ADD)
l.ori r4,r4,lo(UART_BASE_ADD)
ENTRY(_immu_trampoline_workaround)
// r2 EEA
// r6 is physical EEA
tophys(r6,r2)
#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
LOAD_SYMBOL_2_GPR(r5,_immu_trampoline)
tophys (r3,r5) // r3 is trampoline (physical)
/* 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
1: l.lbz r5,5(r4)
l.andi r5,r5,0x20
l.sfeq r5,r6
l.bnf 1b
l.nop
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
/* 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
#endif
EMERGENCY_PRINT_LOAD_GPR6
EMERGENCY_PRINT_LOAD_GPR5
EMERGENCY_PRINT_LOAD_GPR4
l.jr r9
l.nop
l.nop
/*
* DSCR: prints a string referenced by r3.
@@ -1551,53 +1403,41 @@ trampoline_out:
* POST: caller should be aware that r3, r9 are changed
*/
ENTRY(_emergency_print)
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
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.nop
// 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
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
@@ -1609,58 +1449,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.
@@ -1685,7 +1506,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
@@ -1703,9 +1526,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
@@ -1720,13 +1544,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 ]=== */