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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *  C interface for trapping into the standard LinuxSH BIOS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *  Copyright (C) 2000 Greg Banks, Mitch Davis
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *  Copyright (C) 1999, 2000  Niibe Yutaka
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *  Copyright (C) 2002  M. R. Brown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *  Copyright (C) 2004 - 2010  Paul Mundt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <asm/sh_bios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define BIOS_CALL_CONSOLE_WRITE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define BIOS_CALL_ETH_NODE_ADDR		10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #define BIOS_CALL_SHUTDOWN		11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #define BIOS_CALL_GDB_DETACH		0xff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) void *gdb_vbr_vector = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) static inline long sh_bios_call(long func, long arg0, long arg1, long arg2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 				    long arg3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	register long r0 __asm__("r0") = func;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	register long r4 __asm__("r4") = arg0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	register long r5 __asm__("r5") = arg1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	register long r6 __asm__("r6") = arg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	register long r7 __asm__("r7") = arg3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (!gdb_vbr_vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	__asm__ __volatile__("trapa	#0x3f":"=z"(r0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 			     :"0"(r0), "r"(r4), "r"(r5), "r"(r6), "r"(r7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 			     :"memory");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	return r0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) void sh_bios_console_write(const char *buf, unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	sh_bios_call(BIOS_CALL_CONSOLE_WRITE, (long)buf, (long)len, 0, 0);
^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) void sh_bios_gdb_detach(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	sh_bios_call(BIOS_CALL_GDB_DETACH, 0, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) EXPORT_SYMBOL_GPL(sh_bios_gdb_detach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) void sh_bios_get_node_addr(unsigned char *node_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	sh_bios_call(BIOS_CALL_ETH_NODE_ADDR, 0, (long)node_addr, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) EXPORT_SYMBOL_GPL(sh_bios_get_node_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) void sh_bios_shutdown(unsigned int how)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	sh_bios_call(BIOS_CALL_SHUTDOWN, how, 0, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  * Read the old value of the VBR register to initialise the vector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * through which debug and BIOS traps are delegated by the Linux trap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) void sh_bios_vbr_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	unsigned long vbr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (unlikely(gdb_vbr_vector))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	__asm__ __volatile__ ("stc vbr, %0" : "=r" (vbr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (vbr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		gdb_vbr_vector = (void *)(vbr + 0x100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		printk(KERN_NOTICE "Setting GDB trap vector to %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		       gdb_vbr_vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		printk(KERN_NOTICE "SH-BIOS not detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)  * sh_bios_vbr_reload - Re-load the system VBR from the BIOS vector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90)  * This can be used by save/restore code to reinitialize the system VBR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91)  * from the fixed BIOS VBR. A no-op if no BIOS VBR is known.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) void sh_bios_vbr_reload(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	if (gdb_vbr_vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		__asm__ __volatile__ (
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			"ldc %0, vbr"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 			: "r" (((unsigned long) gdb_vbr_vector) - 0x100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 			: "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #ifdef CONFIG_EARLY_PRINTK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  *	Print a string through the BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static void sh_console_write(struct console *co, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 				 unsigned count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	sh_bios_console_write(s, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  *	Setup initial baud/bits/parity. We do two things here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  *	- construct a cflag setting for the first rs_open()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  *	- initialize the serial port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *	Return non-zero if we didn't find a serial port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static int __init sh_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	int	cflag = CREAD | HUPCL | CLOCAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	 *	Now construct a cflag setting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	 *	TODO: this is a totally bogus cflag, as we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	 *	no idea what serial settings the BIOS is using, or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	 *	even if its using the serial port at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	cflag |= B115200 | CS8 | /*no parity*/0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	co->cflag = cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static struct console bios_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	.name		= "bios",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	.write		= sh_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	.setup		= sh_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	.flags		= CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	.index		= -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int __init setup_early_printk(char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	int keep_early = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	if (!buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	if (strstr(buf, "keep"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		keep_early = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	if (!strncmp(buf, "bios", 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		early_console = &bios_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	if (likely(early_console)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		if (keep_early)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			early_console->flags &= ~CON_BOOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			early_console->flags |= CON_BOOT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		register_console(early_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) early_param("earlyprintk", setup_early_printk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif