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)  * Get EDD BIOS disk information
^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) #include <linux/edd.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) #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Read the MBR (first sector) from a specific device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) static int read_mbr(u8 devno, void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 	ireg.ax = 0x0201;		/* Legacy Read, one sector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	ireg.cx = 0x0001;		/* Sector 0-0-1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	ireg.dl = devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	ireg.bx = (size_t)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	intcall(0x13, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	return -(oreg.eflags & X86_EFLAGS_CF); /* 0 or -1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static u32 read_mbr_sig(u8 devno, struct edd_info *ei, u32 *mbrsig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	int sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	char *mbrbuf_ptr, *mbrbuf_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	u32 buf_base, mbr_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	extern char _end[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	u16 mbr_magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	sector_size = ei->params.bytes_per_sector;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	if (!sector_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		sector_size = 512; /* Best available guess */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	/* Produce a naturally aligned buffer on the heap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	buf_base = (ds() << 4) + (u32)&_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	mbr_base = (buf_base+sector_size-1) & ~(sector_size-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	mbrbuf_ptr = _end + (mbr_base-buf_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 	mbrbuf_end = mbrbuf_ptr + sector_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	/* Make sure we actually have space on the heap... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	if (!(boot_params.hdr.loadflags & CAN_USE_HEAP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (mbrbuf_end > (char *)(size_t)boot_params.hdr.heap_end_ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	memset(mbrbuf_ptr, 0, sector_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (read_mbr(devno, mbrbuf_ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	*mbrsig = *(u32 *)&mbrbuf_ptr[EDD_MBR_SIG_OFFSET];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	mbr_magic = *(u16 *)&mbrbuf_ptr[510];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	/* check for valid MBR magic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return mbr_magic == 0xAA55 ? 0 : -1;
^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) static int get_edd_info(u8 devno, struct edd_info *ei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	memset(ei, 0, sizeof(*ei));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	/* Check Extensions Present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	ireg.ah = 0x41;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	ireg.bx = EDDMAGIC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	ireg.dl = devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	intcall(0x13, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (oreg.eflags & X86_EFLAGS_CF)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return -1;	/* No extended information */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	if (oreg.bx != EDDMAGIC2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	ei->device  = devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	ei->version = oreg.ah;		 /* EDD version number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	ei->interface_support = oreg.cx; /* EDD functionality subsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	/* Extended Get Device Parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	ei->params.length = sizeof(ei->params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	ireg.ah = 0x48;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	ireg.si = (size_t)&ei->params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	intcall(0x13, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	/* Get legacy CHS parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	/* Ralf Brown recommends setting ES:DI to 0:0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	ireg.ah = 0x08;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	ireg.es = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	intcall(0x13, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (!(oreg.eflags & X86_EFLAGS_CF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		ei->legacy_max_cylinder = oreg.ch + ((oreg.cl & 0xc0) << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		ei->legacy_max_head = oreg.dh;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		ei->legacy_sectors_per_track = oreg.cl & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) void query_edd(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	char eddarg[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	int do_mbr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #ifdef CONFIG_EDD_OFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	int do_edd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	int do_edd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	int be_quiet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int devno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct edd_info ei, *edp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	u32 *mbrptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (cmdline_find_option("edd", eddarg, sizeof(eddarg)) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		if (!strcmp(eddarg, "skipmbr") || !strcmp(eddarg, "skip")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 			do_edd = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			do_mbr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 		else if (!strcmp(eddarg, "off"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			do_edd = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		else if (!strcmp(eddarg, "on"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 			do_edd = 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) 	be_quiet = cmdline_find_option_bool("quiet");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 	edp    = boot_params.eddbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	mbrptr = boot_params.edd_mbr_sig_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	if (!do_edd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	/* Bugs in OnBoard or AddOnCards Bios may hang the EDD probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	 * so give a hint if this happens.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	if (!be_quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		printf("Probing EDD (edd=off to disable)... ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 	for (devno = 0x80; devno < 0x80+EDD_MBR_SIG_MAX; devno++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		 * Scan the BIOS-supported hard disks and query EDD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		 * information...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		if (!get_edd_info(devno, &ei)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		    && boot_params.eddbuf_entries < EDDMAXNR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 			memcpy(edp, &ei, sizeof(ei));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 			edp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			boot_params.eddbuf_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		if (do_mbr && !read_mbr_sig(devno, &ei, mbrptr++))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 			boot_params.edd_mbr_sig_buf_entries = devno-0x80+1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	if (!be_quiet)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		printf("ok\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) #endif