xref: /netbsd-src/sys/arch/i386/stand/boot/devopen.c (revision 9d087602a97dc9d942320415a928fde78c18bc43)
1*9d087602Smanu /*	$NetBSD: devopen.c,v 1.10 2019/12/10 02:02:47 manu Exp $	 */
2c53f251eSjunyoung 
3c53f251eSjunyoung /*-
4c53f251eSjunyoung  * Copyright (c) 2005 The NetBSD Foundation, Inc.
5c53f251eSjunyoung  * All rights reserved.
6c53f251eSjunyoung  *
7c53f251eSjunyoung  * This code is derived from software contributed to The NetBSD Foundation
8c53f251eSjunyoung  * by Bang Jun-Young.
9c53f251eSjunyoung  *
10c53f251eSjunyoung  * Redistribution and use in source and binary forms, with or without
11c53f251eSjunyoung  * modification, are permitted provided that the following conditions
12c53f251eSjunyoung  * are met:
13c53f251eSjunyoung  * 1. Redistributions of source code must retain the above copyright
14c53f251eSjunyoung  *    notice, this list of conditions and the following disclaimer.
15c53f251eSjunyoung  * 2. Redistributions in binary form must reproduce the above copyright
16c53f251eSjunyoung  *    notice, this list of conditions and the following disclaimer in the
17c53f251eSjunyoung  *    documentation and/or other materials provided with the distribution.
18c53f251eSjunyoung  *
19c53f251eSjunyoung  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20c53f251eSjunyoung  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21c53f251eSjunyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22c53f251eSjunyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23c53f251eSjunyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24c53f251eSjunyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25c53f251eSjunyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26c53f251eSjunyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27c53f251eSjunyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28c53f251eSjunyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29c53f251eSjunyoung  * POSSIBILITY OF SUCH DAMAGE.
30c53f251eSjunyoung  */
3160c3e62aSdsl 
3260c3e62aSdsl /*
3360c3e62aSdsl  * Copyright (c) 1996, 1997
3460c3e62aSdsl  *	Matthias Drochner.  All rights reserved.
3560c3e62aSdsl  *
3660c3e62aSdsl  * Redistribution and use in source and binary forms, with or without
3760c3e62aSdsl  * modification, are permitted provided that the following conditions
3860c3e62aSdsl  * are met:
3960c3e62aSdsl  * 1. Redistributions of source code must retain the above copyright
4060c3e62aSdsl  *    notice, this list of conditions and the following disclaimer.
4160c3e62aSdsl  * 2. Redistributions in binary form must reproduce the above copyright
4260c3e62aSdsl  *    notice, this list of conditions and the following disclaimer in the
4360c3e62aSdsl  *    documentation and/or other materials provided with the distribution.
4460c3e62aSdsl  *
4560c3e62aSdsl  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
4660c3e62aSdsl  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
4760c3e62aSdsl  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4860c3e62aSdsl  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
4960c3e62aSdsl  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
5060c3e62aSdsl  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
5160c3e62aSdsl  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
5260c3e62aSdsl  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
5360c3e62aSdsl  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
5460c3e62aSdsl  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5560c3e62aSdsl  */
5660c3e62aSdsl 
5760c3e62aSdsl 
5860c3e62aSdsl #include <sys/types.h>
5960c3e62aSdsl 
6060c3e62aSdsl #include <lib/libsa/stand.h>
6160c3e62aSdsl #include <lib/libkern/libkern.h>
6260c3e62aSdsl 
6360c3e62aSdsl #include <libi386.h>
6460c3e62aSdsl #include <biosdisk.h>
6560c3e62aSdsl #include "devopen.h"
6660c3e62aSdsl #ifdef _STANDALONE
6760c3e62aSdsl #include <bootinfo.h>
6860c3e62aSdsl #endif
6960c3e62aSdsl #ifdef SUPPORT_PS2
7060c3e62aSdsl #include <biosmca.h>
7160c3e62aSdsl #endif
7260c3e62aSdsl 
73c53f251eSjunyoung static int dev2bios(char *, int, int *);
7460c3e62aSdsl 
75d659374dSjunyoung static int
dev2bios(char * devname,int unit,int * biosdev)76c53f251eSjunyoung dev2bios(char *devname, int unit, int *biosdev)
7760c3e62aSdsl {
78c53f251eSjunyoung 
7960c3e62aSdsl 	if (strcmp(devname, "hd") == 0)
8060c3e62aSdsl 		*biosdev = 0x80 + unit;
8160c3e62aSdsl 	else if (strcmp(devname, "fd") == 0)
8260c3e62aSdsl 		*biosdev = 0x00 + unit;
83c53f251eSjunyoung 	else if (strcmp(devname, "cd") == 0)
84c53f251eSjunyoung 		*biosdev = boot_biosdev;
8560c3e62aSdsl 	else
86d659374dSjunyoung 		return ENXIO;
8760c3e62aSdsl 
88d659374dSjunyoung 	return 0;
8960c3e62aSdsl }
9060c3e62aSdsl 
91c53f251eSjunyoung void
bios2dev(int biosdev,daddr_t sector,char ** devname,int * unit,int * partition,const char ** part_name)9292f692b3Smanu bios2dev(int biosdev, daddr_t sector, char **devname, int *unit,
9392f692b3Smanu 	 int *partition, const char **part_name)
9460c3e62aSdsl {
95c53f251eSjunyoung 
96c53f251eSjunyoung 	/* set default */
97c53f251eSjunyoung 	*unit = biosdev & 0x7f;
98c53f251eSjunyoung 
99c53f251eSjunyoung 	if (biosdev & 0x80) {
100c53f251eSjunyoung 		/*
101c53f251eSjunyoung 		 * There seems to be no standard way of numbering BIOS
102c53f251eSjunyoung 		 * CD-ROM drives. The following method is a little tricky
103c53f251eSjunyoung 		 * but works nicely.
104c53f251eSjunyoung 		 */
105c53f251eSjunyoung 		if (biosdev >= 0x80 + get_harddrives()) {
106c53f251eSjunyoung 			*devname = "cd";
107c53f251eSjunyoung 			*unit = 0;		/* override default */
108c53f251eSjunyoung 		} else
10960c3e62aSdsl 			*devname = "hd";
110c53f251eSjunyoung 	} else
11160c3e62aSdsl 		*devname = "fd";
11260c3e62aSdsl 
11392f692b3Smanu 	(void)biosdisk_findpartition(biosdev, sector, partition, part_name);
11460c3e62aSdsl }
11560c3e62aSdsl 
11660c3e62aSdsl #ifdef _STANDALONE
11760c3e62aSdsl struct btinfo_bootpath bibp;
118bfc57323Sad extern bool kernel_loaded;
11960c3e62aSdsl #endif
12060c3e62aSdsl 
12160c3e62aSdsl /*
12260c3e62aSdsl  * Open the BIOS disk device
12360c3e62aSdsl  */
12460c3e62aSdsl int
devopen(struct open_file * f,const char * fname,char ** file)125d659374dSjunyoung devopen(struct open_file *f, const char *fname, char **file)
12660c3e62aSdsl {
12760c3e62aSdsl 	char *fsname, *devname;
128c53f251eSjunyoung 	int unit, partition;
12960c3e62aSdsl 	int biosdev;
13060c3e62aSdsl 	int error;
13160c3e62aSdsl 
13292f692b3Smanu 	error = parsebootfile(fname, &fsname, &devname,
13392f692b3Smanu 			      &unit, &partition, (const char **) file);
13492f692b3Smanu 	if (error)
135d659374dSjunyoung 		return error;
13660c3e62aSdsl 
137d659374dSjunyoung 	f->f_dev = &devsw[0];		/* must be biosdisk */
13860c3e62aSdsl 
13960c3e62aSdsl #ifdef _STANDALONE
140bfc57323Sad 	if (!kernel_loaded) {
14160c3e62aSdsl 		strncpy(bibp.bootpath, *file, sizeof(bibp.bootpath));
14260c3e62aSdsl 		BI_ADD(&bibp, BTINFO_BOOTPATH, sizeof(bibp));
143bfc57323Sad 	}
14460c3e62aSdsl #endif
14560c3e62aSdsl 
14692f692b3Smanu #ifndef NO_GPT
14792f692b3Smanu 	/* Search by GPT label name */
14892f692b3Smanu 	if (strstr(devname, "NAME=") == devname) {
14992f692b3Smanu 		f->f_dev = &devsw[0];		/* must be biosdisk */
15092f692b3Smanu 
15192f692b3Smanu 		return biosdisk_open_name(f, devname);
15292f692b3Smanu 	}
15392f692b3Smanu #endif
15492f692b3Smanu #ifndef NO_RAIDFRAME
15592f692b3Smanu 	/* Search by raidframe name */
15692f692b3Smanu 	if (strstr(devname, "raid") == devname) {
15792f692b3Smanu 		f->f_dev = &devsw[0];		/* must be biosdisk */
15892f692b3Smanu 
159*9d087602Smanu 		return biosdisk_open_name(f, fname);
16092f692b3Smanu 	}
16192f692b3Smanu #endif
16292f692b3Smanu 
16392f692b3Smanu 	error = dev2bios(devname, unit, &biosdev);
16492f692b3Smanu 	if (error)
16592f692b3Smanu 		return error;
16692f692b3Smanu 
167c53f251eSjunyoung 	return biosdisk_open(f, biosdev, partition);
16860c3e62aSdsl }
169