forked from Minki/linux
OpenRISC updates for 5.19
Fixups and enhancements for OpenRISC: - 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 -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE2cRzVK74bBA6Je/xw7McLV5mJ+QFAmKP+24ACgkQw7McLV5m J+Q59w//eiFQv/L//IPZ//fDhDKYILs0JYnJGmAY2IBFpI/m/KkSWOeo32L5qyXe IlvbxyrM3RVzDQVS/q1DG7vz9HuEI52asuefPEUeCmDSEcZH6g8ZzRHOrYqqDcM6 nKBoi2CIv9BpfkOdoewgUdaMoijhIWsT5QSZpLjkfPZvc2E78tlHvWiaZffZAJiR XliE16XeuuKN6/vu5MNK2qExwsO9ayAiylv1K6bfN/0KkJEysY2FscRifHCbwscs bGi367C7XfHE8Tks31SyUDqNlD760FjjL+ygAMG63v20mswhQggwEb/dApjzHj1l MwrRBOG6CGYHE+AATsQLrd4N+fM9NNMfIARhtnbQYQlicAQpwGWNIPbpe1WOnBcw KfXaiJwUcntf3bfBLyfZVvWs0ZYMgfUD8NGX4nDtTomywdxSUlTPefj2KP7UKiaV NRwCOgZaT5iRzuJT832wCIRU75CjbFLvZ3JgMVwZtAlmGKTUopAikxvHTKRDDybn O9ghq1b34hJf0BmnPTWF0pELTu2z3Vpt8qrUdNtfy3ICNiMDJV0e3aUH1gFJ1LtA ++bh98wErqaxVsNzQXS7PUwiB2xmUB8YGMfJoQIN/spysJ3mAlOjVPxFKLVXHopi aHatlCvIV/Lc4ygt7no8PHtjvt8JckwCRpG0BLnrw09TokAQkp0= =JxMd -----END PGP SIGNATURE----- Merge tag 'for-linus' of https://github.com/openrisc/linux 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:
commit
7f50d4dfe8
@ -113,6 +113,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 n
|
||||
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 n
|
||||
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 n
|
||||
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 n
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -1,22 +1,54 @@
|
||||
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_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
|
||||
|
@ -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:
|
||||
|
@ -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 ]=== */
|
||||
|
@ -52,6 +52,8 @@ void machine_restart(char *cmd)
|
||||
{
|
||||
do_kernel_restart(cmd);
|
||||
|
||||
__asm__("l.nop 13");
|
||||
|
||||
/* Give a grace period for failure to restart of 1s */
|
||||
mdelay(1000);
|
||||
|
||||
@ -60,6 +62,16 @@ void machine_restart(char *cmd)
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is used if pm_power_off has not been set by a power management
|
||||
* driver, in this case we can assume we are on a simulator. On
|
||||
* OpenRISC simulators l.nop 1 will trigger the simulator exit.
|
||||
*/
|
||||
static void default_power_off(void)
|
||||
{
|
||||
__asm__("l.nop 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* Similar to machine_power_off, but don't shut off power. Add code
|
||||
* here to freeze the system for e.g. post-mortem debug purpose when
|
||||
@ -75,7 +87,10 @@ void machine_halt(void)
|
||||
void machine_power_off(void)
|
||||
{
|
||||
printk(KERN_INFO "*** MACHINE POWER OFF ***\n");
|
||||
__asm__("l.nop 1");
|
||||
if (pm_power_off != NULL)
|
||||
pm_power_off();
|
||||
else
|
||||
default_power_off();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -89,7 +104,7 @@ void arch_cpu_idle(void)
|
||||
mtspr(SPR_PMR, mfspr(SPR_PMR) | SPR_PMR_DME);
|
||||
}
|
||||
|
||||
void (*pm_power_off) (void) = machine_power_off;
|
||||
void (*pm_power_off)(void) = NULL;
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
|
||||
/*
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <linux/of_clk.h>
|
||||
|
||||
#include <asm/cpuinfo.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
/* Test the timer ticks to count, used in sync routine */
|
||||
inline void openrisc_timer_set(unsigned long count)
|
||||
@ -61,7 +62,7 @@ static int openrisc_timer_set_next_event(unsigned long delta,
|
||||
* timers) we cannot enable the PERIODIC feature. The tick timer can run using
|
||||
* one-shot events, so no problem.
|
||||
*/
|
||||
DEFINE_PER_CPU(struct clock_event_device, clockevent_openrisc_timer);
|
||||
static DEFINE_PER_CPU(struct clock_event_device, clockevent_openrisc_timer);
|
||||
|
||||
void openrisc_clockevent_init(void)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
if (i == 0)
|
||||
printk("(%02x) ", c);
|
||||
else
|
||||
printk("%02x ", c);
|
||||
word = ((unsigned long *)(__pa(regs->pc)))[i];
|
||||
|
||||
print_data(regs->pc, word, i);
|
||||
}
|
||||
printk("\n");
|
||||
}
|
||||
@ -215,16 +235,7 @@ 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)
|
||||
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);
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
*/
|
||||
@ -223,8 +221,6 @@ no_context:
|
||||
{
|
||||
const struct exception_table_entry *entry;
|
||||
|
||||
__asm__ __volatile__("l.nop 42");
|
||||
|
||||
if ((entry = search_exception_tables(regs->pc)) != NULL) {
|
||||
/* Adjust the instruction pointer in the stackframe */
|
||||
regs->pc = entry->fixup;
|
||||
@ -252,9 +248,6 @@ no_context:
|
||||
*/
|
||||
|
||||
out_of_memory:
|
||||
__asm__ __volatile__("l.nop 42");
|
||||
__asm__ __volatile__("l.nop 1");
|
||||
|
||||
mmap_read_unlock(mm);
|
||||
if (!user_mode(regs))
|
||||
goto no_context;
|
||||
|
@ -128,7 +128,7 @@ void local_flush_tlb_mm(struct mm_struct *mm)
|
||||
|
||||
/* Was seeing bugs with the mm struct passed to us. Scrapped most of
|
||||
this function. */
|
||||
/* Several architctures do this */
|
||||
/* Several architectures do this */
|
||||
local_flush_tlb_all();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user