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)  * Memory detection code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "boot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define SMAP	0x534d4150	/* ASCII "SMAP" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) static void detect_memory_e820(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 	struct boot_e820_entry *desc = boot_params.e820_table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	static struct boot_e820_entry buf; /* static so it is zeroed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	ireg.ax  = 0xe820;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	ireg.cx  = sizeof(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	ireg.edx = SMAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	ireg.di  = (size_t)&buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	 * Note: at least one BIOS is known which assumes that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	 * buffer pointed to by one e820 call is the same one as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	 * the previous call, and only changes modified fields.  Therefore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	 * we use a temporary buffer and copy the results entry by entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	 * This routine deliberately does not try to account for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	 * ACPI 3+ extended attributes.  This is because there are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	 * BIOSes in the field which report zero for the valid bit for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	 * all ranges, and we don't currently make any use of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	 * other attribute bits.  Revisit this if we see the extended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	 * attribute bits deployed in a meaningful way in the future.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		intcall(0x15, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		ireg.ebx = oreg.ebx; /* for next iteration... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		/* BIOSes which terminate the chain with CF = 1 as opposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		   to %ebx = 0 don't always report the SMAP signature on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		   the final, failing, probe. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		if (oreg.eflags & X86_EFLAGS_CF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		/* Some BIOSes stop returning SMAP in the middle of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		   the search loop.  We don't know exactly how the BIOS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		   screwed up the map at that point, we might have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		   partial map, the full map, or complete garbage, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		   just return failure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		if (oreg.eax != SMAP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 			count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 			break;
^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) 		*desc++ = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	} while (ireg.ebx && count < ARRAY_SIZE(boot_params.e820_table));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	boot_params.e820_entries = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) static void detect_memory_e801(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	ireg.ax = 0xe801;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	intcall(0x15, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	if (oreg.eflags & X86_EFLAGS_CF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	/* Do we really need to do this? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	if (oreg.cx || oreg.dx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		oreg.ax = oreg.cx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		oreg.bx = oreg.dx;
^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) 	if (oreg.ax > 15*1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		return;	/* Bogus! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	} else if (oreg.ax == 15*1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		boot_params.alt_mem_k = (oreg.bx << 6) + oreg.ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		 * This ignores memory above 16MB if we have a memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 		 * hole there.  If someone actually finds a machine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		 * with a memory hole at 16MB and no support for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		 * 0E820h they should probably generate a fake e820
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		 * map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		boot_params.alt_mem_k = oreg.ax;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static void detect_memory_88(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	ireg.ah = 0x88;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	intcall(0x15, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	boot_params.screen_info.ext_mem_k = oreg.ax;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void detect_memory(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	detect_memory_e820();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	detect_memory_e801();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	detect_memory_88();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }