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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *   Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *   Copyright 2007 rPath, Inc. - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *   Copyright 2009 Intel Corporation; author H. Peter Anvin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Main module for the real-mode kernel code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/build_bug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "boot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "string.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) struct boot_params boot_params __attribute__((aligned(16)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) char *HEAP = _end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) char *heap_end = _end;		/* Default end of heap = no heap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * Copy the header into the boot parameter block.  Since this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * screws up the old-style command line protocol, adjust by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * filling in the new-style command line pointer instead.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static void copy_boot_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct old_cmdline {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 		u16 cl_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 		u16 cl_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	const struct old_cmdline * const oldcmd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 		(const struct old_cmdline *)OLD_CL_ADDRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	BUILD_BUG_ON(sizeof(boot_params) != 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	if (!boot_params.hdr.cmd_line_ptr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	    oldcmd->cl_magic == OLD_CL_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		/* Old-style command line protocol. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		u16 cmdline_seg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		/* Figure out if the command line falls in the region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		   of memory that an old kernel would have copied up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		   to 0x90000... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		if (oldcmd->cl_offset < boot_params.hdr.setup_move_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 			cmdline_seg = ds();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 			cmdline_seg = 0x9000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		boot_params.hdr.cmd_line_ptr =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 			(cmdline_seg << 4) + oldcmd->cl_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60)  * Query the keyboard lock status as given by the BIOS, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61)  * set the keyboard repeat rate to maximum.  Unclear why the latter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * is done here; this might be possible to kill off as stale code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static void keyboard_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	ireg.ah = 0x02;		/* Get keyboard status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	intcall(0x16, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	boot_params.kbd_status = oreg.al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	ireg.ax = 0x0305;	/* Set keyboard repeat rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	intcall(0x16, &ireg, NULL);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * Get Intel SpeedStep (IST) information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static void query_ist(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	/* Some older BIOSes apparently crash on this call, so filter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	   it from machines too old to have SpeedStep at all. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	if (cpu.level < 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	ireg.ax  = 0xe980;	 /* IST Support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	ireg.edx = 0x47534943;	 /* Request value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	intcall(0x15, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	boot_params.ist_info.signature  = oreg.eax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	boot_params.ist_info.command    = oreg.ebx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	boot_params.ist_info.event      = oreg.ecx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	boot_params.ist_info.perf_level = oreg.edx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * Tell the BIOS what CPU mode we intend to run in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static void set_bios_mode(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	struct biosregs ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	ireg.ax = 0xec00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ireg.bx = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	intcall(0x15, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) #endif
^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) static void init_heap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	char *stack_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	if (boot_params.hdr.loadflags & CAN_USE_HEAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 		asm("leal %P1(%%esp),%0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		    : "=r" (stack_end) : "i" (-STACK_SIZE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 		heap_end = (char *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			((size_t)boot_params.hdr.heap_end_ptr + 0x200);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		if (heap_end > stack_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			heap_end = stack_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		/* Boot protocol 2.00 only, no heap available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		puts("WARNING: Ancient bootloader, some functionality "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		     "may be limited!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) void main(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	/* First, copy the boot header into the "zeropage" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	copy_boot_params();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 	/* Initialize the early-boot console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	console_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	if (cmdline_find_option_bool("debug"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 		puts("early console in setup code\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	/* End of heap check */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	init_heap();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	/* Make sure we have all the proper CPU support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	if (validate_cpu()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 		puts("Unable to boot - please use a kernel appropriate "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 		     "for your CPU.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		die();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	/* Tell the BIOS what CPU mode we intend to run in. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	set_bios_mode();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	/* Detect memory layout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	detect_memory();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	/* Set keyboard repeat rate (why?) and query the lock flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	keyboard_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	/* Query Intel SpeedStep (IST) information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	query_ist();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	/* Query APM information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	query_apm_bios();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	/* Query EDD information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	query_edd();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	/* Set the video mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	set_video();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	/* Do the last things and invoke protected mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	go_to_protected_mode();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) }