Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) typedef unsigned int instr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #define MAJOR_OP	0xfc000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #define LDA_OP		0x20000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #define STQ_OP		0xb4000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #define BR_OP		0xc0000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define STK_ALLOC_1	0x23de8000 /* lda $30,-X($30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define STK_ALLOC_1M	0xffff8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #define STK_ALLOC_2	0x43c0153e /* subq $30,X,$30 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define STK_ALLOC_2M	0xffe01fff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define MEM_REG		0x03e00000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define MEM_BASE	0x001f0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define MEM_OFF		0x0000ffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define MEM_OFF_SIGN	0x00008000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define	BASE_SP		0x001e0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #define STK_ALLOC_MATCH(INSTR)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)   (((INSTR) & STK_ALLOC_1M) == STK_ALLOC_1	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)    || ((INSTR) & STK_ALLOC_2M) == STK_ALLOC_2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define STK_PUSH_MATCH(INSTR) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)   (((INSTR) & (MAJOR_OP | MEM_BASE | MEM_OFF_SIGN)) == (STQ_OP | BASE_SP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define MEM_OP_OFFSET(INSTR) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)   (((long)((INSTR) & MEM_OFF) << 48) >> 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define MEM_OP_REG(INSTR) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)   (((INSTR) & MEM_REG) >> 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) /* Branches, jumps, PAL calls, and illegal opcodes end a basic block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #define BB_END(INSTR)						\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34)   (((instr)(INSTR) >= BR_OP) | ((instr)(INSTR) < LDA_OP) |	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35)    ((((instr)(INSTR) ^ 0x60000000) < 0x20000000) &		\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36)     (((instr)(INSTR) & 0x0c000000) != 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #define IS_KERNEL_TEXT(PC) ((unsigned long)(PC) > START_ADDR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static char reg_name[][4] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	"v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ", "t7 ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	"s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "a0 ", "a1 ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	"a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ", "t10", "t11", "ra ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	"pv ", "at ", "gp ", "sp ", "0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) static instr *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) display_stored_regs(instr * pro_pc, unsigned char * sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	instr * ret_pc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	int reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	unsigned long value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	printk("Prologue [<%p>], Frame %p:\n", pro_pc, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	while (!BB_END(*pro_pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		if (STK_PUSH_MATCH(*pro_pc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 			reg = (*pro_pc & MEM_REG) >> 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 			value = *(unsigned long *)(sp + (*pro_pc & MEM_OFF));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 			if (reg == 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 				ret_pc = (instr *)value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			printk("\t\t%s / 0x%016lx\n", reg_name[reg], value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	return ret_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) static instr *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) seek_prologue(instr * pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	while (!STK_ALLOC_MATCH(*pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		--pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	while (!BB_END(*(pc - 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		--pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	return pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) static long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) stack_increment(instr * prologue_pc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	while (!STK_ALLOC_MATCH(*prologue_pc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		++prologue_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* Count the bytes allocated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if ((*prologue_pc & STK_ALLOC_1M) == STK_ALLOC_1M)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		return -(((long)(*prologue_pc) << 48) >> 48);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		return (*prologue_pc >> 13) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) stacktrace(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	instr * ret_pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	instr * prologue = (instr *)stacktrace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	register unsigned char * sp __asm__ ("$30");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	printk("\tstack trace:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		ret_pc = display_stored_regs(prologue, sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		sp += stack_increment(prologue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		prologue = seek_prologue(ret_pc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	} while (IS_KERNEL_TEXT(ret_pc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }