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-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *  Chen Liqin <liqin.chen@sunplusct.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Lennox Wu <lennox.wu@sunplusct.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Copyright (C) 2012 Regents of the University of California
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright (C) 2017 SiFive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/sched/task_stack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/tick.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <asm/unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <asm/csr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <asm/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <asm/switch_to.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) register unsigned long gp_in_global __asm__("gp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #ifdef CONFIG_STACKPROTECTOR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/stackprotector.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) unsigned long __stack_chk_guard __read_mostly;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) EXPORT_SYMBOL(__stack_chk_guard);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) extern asmlinkage void ret_from_fork(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) extern asmlinkage void ret_from_kernel_thread(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) void arch_cpu_idle(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	wait_for_interrupt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	raw_local_irq_enable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) void show_regs(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	show_regs_print_info(KERN_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	pr_cont("epc: " REG_FMT " ra : " REG_FMT " sp : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		regs->epc, regs->ra, regs->sp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	pr_cont(" gp : " REG_FMT " tp : " REG_FMT " t0 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		regs->gp, regs->tp, regs->t0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	pr_cont(" t1 : " REG_FMT " t2 : " REG_FMT " s0 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		regs->t1, regs->t2, regs->s0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	pr_cont(" s1 : " REG_FMT " a0 : " REG_FMT " a1 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		regs->s1, regs->a0, regs->a1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	pr_cont(" a2 : " REG_FMT " a3 : " REG_FMT " a4 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		regs->a2, regs->a3, regs->a4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	pr_cont(" a5 : " REG_FMT " a6 : " REG_FMT " a7 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		regs->a5, regs->a6, regs->a7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	pr_cont(" s2 : " REG_FMT " s3 : " REG_FMT " s4 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		regs->s2, regs->s3, regs->s4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	pr_cont(" s5 : " REG_FMT " s6 : " REG_FMT " s7 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		regs->s5, regs->s6, regs->s7);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	pr_cont(" s8 : " REG_FMT " s9 : " REG_FMT " s10: " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 		regs->s8, regs->s9, regs->s10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	pr_cont(" s11: " REG_FMT " t3 : " REG_FMT " t4 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 		regs->s11, regs->t3, regs->t4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	pr_cont(" t5 : " REG_FMT " t6 : " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		regs->t5, regs->t6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	pr_cont("status: " REG_FMT " badaddr: " REG_FMT " cause: " REG_FMT "\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		regs->status, regs->badaddr, regs->cause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) void start_thread(struct pt_regs *regs, unsigned long pc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	unsigned long sp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	regs->status = SR_PIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	if (has_fpu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		regs->status |= SR_FS_INITIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		 * Restore the initial value to the FP register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		 * before starting the user program.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		fstate_restore(current, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	regs->epc = pc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	regs->sp = sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) void flush_thread(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) #ifdef CONFIG_FPU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	 * Reset FPU state and context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	 *	frm: round to nearest, ties to even (IEEE default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	 *	fflags: accrued exceptions cleared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	fstate_off(current, task_pt_regs(current));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	fstate_save(src, task_pt_regs(src));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	*dst = *src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) int copy_thread(unsigned long clone_flags, unsigned long usp, unsigned long arg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		struct task_struct *p, unsigned long tls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	struct pt_regs *childregs = task_pt_regs(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	/* p->thread holds context to be restored by __switch_to() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	if (unlikely(p->flags & PF_KTHREAD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		/* Kernel thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		memset(childregs, 0, sizeof(struct pt_regs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		childregs->gp = gp_in_global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		/* Supervisor/Machine, irqs on: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		childregs->status = SR_PP | SR_PIE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		p->thread.ra = (unsigned long)ret_from_kernel_thread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		p->thread.s[0] = usp; /* fn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		p->thread.s[1] = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		*childregs = *(current_pt_regs());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		if (usp) /* User fork */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			childregs->sp = usp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		if (clone_flags & CLONE_SETTLS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 			childregs->tp = tls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		childregs->a0 = 0; /* Return value of fork() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 		p->thread.ra = (unsigned long)ret_from_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	p->thread.sp = (unsigned long)childregs; /* kernel sp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }