1*c2e8ce64Stsutsui /* $NetBSD: devopen.c,v 1.5 2011/12/25 06:09:09 tsutsui Exp $ */
204faabf0Stsutsui
304faabf0Stsutsui /*-
404faabf0Stsutsui * Copyright (c) 2004 The NetBSD Foundation, Inc.
504faabf0Stsutsui * All rights reserved.
604faabf0Stsutsui *
704faabf0Stsutsui * This code is derived from software contributed to The NetBSD Foundation
804faabf0Stsutsui * by UCHIYAMA Yasushi.
904faabf0Stsutsui *
1004faabf0Stsutsui * Redistribution and use in source and binary forms, with or without
1104faabf0Stsutsui * modification, are permitted provided that the following conditions
1204faabf0Stsutsui * are met:
1304faabf0Stsutsui * 1. Redistributions of source code must retain the above copyright
1404faabf0Stsutsui * notice, this list of conditions and the following disclaimer.
1504faabf0Stsutsui * 2. Redistributions in binary form must reproduce the above copyright
1604faabf0Stsutsui * notice, this list of conditions and the following disclaimer in the
1704faabf0Stsutsui * documentation and/or other materials provided with the distribution.
1804faabf0Stsutsui *
1904faabf0Stsutsui * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2004faabf0Stsutsui * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2104faabf0Stsutsui * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2204faabf0Stsutsui * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2304faabf0Stsutsui * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2404faabf0Stsutsui * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2504faabf0Stsutsui * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2604faabf0Stsutsui * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2704faabf0Stsutsui * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2804faabf0Stsutsui * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2904faabf0Stsutsui * POSSIBILITY OF SUCH DAMAGE.
3004faabf0Stsutsui */
3104faabf0Stsutsui
3204faabf0Stsutsui #include <lib/libsa/stand.h>
3304faabf0Stsutsui #include <lib/libkern/libkern.h>
3404faabf0Stsutsui
3504faabf0Stsutsui #include <netinet/in.h>
3604faabf0Stsutsui #include <lib/libsa/dev_net.h>
3704faabf0Stsutsui #include <lib/libsa/ufs.h>
3804faabf0Stsutsui #include <lib/libsa/nfs.h>
39d1b230abStsutsui #include <lib/libsa/dev_net.h>
4004faabf0Stsutsui #include <machine/sbd.h>
4104faabf0Stsutsui
4204faabf0Stsutsui #include "local.h"
4304faabf0Stsutsui
4404faabf0Stsutsui extern uint8_t kernel_binary[];
4504faabf0Stsutsui extern int kernel_binary_size;
4604faabf0Stsutsui
4704faabf0Stsutsui extern struct fs_ops datafs_ops;
4804faabf0Stsutsui extern struct fs_ops bfs_ops;
49*c2e8ce64Stsutsui struct fs_ops ufs_ops = FS_OPS(ufs);
50*c2e8ce64Stsutsui struct fs_ops nfs_ops = FS_OPS(nfs);
5104faabf0Stsutsui
5204faabf0Stsutsui extern struct devsw netdevsw;
5304faabf0Stsutsui extern struct devsw dkdevsw;
5404faabf0Stsutsui char fname[16];
5504faabf0Stsutsui
5604faabf0Stsutsui /* Referenced by libsa/open.c */
5704faabf0Stsutsui struct fs_ops file_system[1];
5804faabf0Stsutsui int nfsys = 1;
5904faabf0Stsutsui struct devsw devsw[1];
6004faabf0Stsutsui int ndevs = 1;
6104faabf0Stsutsui
6204faabf0Stsutsui int
devopen(struct open_file * f,const char * request,char ** file)6304faabf0Stsutsui devopen(struct open_file *f, const char *request, char **file)
6404faabf0Stsutsui {
6504faabf0Stsutsui char *p, *filename;
6604faabf0Stsutsui int disk, partition;
6704faabf0Stsutsui void *addr;
6804faabf0Stsutsui size_t size;
6904faabf0Stsutsui
7004faabf0Stsutsui strcpy(fname, request);
7104faabf0Stsutsui
7204faabf0Stsutsui filename = 0;
7304faabf0Stsutsui for (p = fname; *p; p++) {
7404faabf0Stsutsui if (*p == ':') {
7504faabf0Stsutsui filename = p + 1;
7604faabf0Stsutsui *p = '\0';
7704faabf0Stsutsui break;
7804faabf0Stsutsui }
7904faabf0Stsutsui }
8004faabf0Stsutsui
8104faabf0Stsutsui if (filename == 0) { /* not a loader's request. probably ufs_ls() */
8204faabf0Stsutsui printf("request=%s\n", request);
8304faabf0Stsutsui f->f_dev = &dkdevsw;
8404faabf0Stsutsui file_system[0] = ufs_ops;
8504faabf0Stsutsui devsw[0] = dkdevsw;
8604faabf0Stsutsui *file = "/";
8704faabf0Stsutsui return 0;
8804faabf0Stsutsui }
8904faabf0Stsutsui
9004faabf0Stsutsui /* Data section */
9104faabf0Stsutsui if (strcmp(fname, "mem") == 0) {
9204faabf0Stsutsui data_attach(kernel_binary, kernel_binary_size);
9304faabf0Stsutsui *file = "noname";
9404faabf0Stsutsui f->f_flags |= F_NODEV;
9504faabf0Stsutsui file_system[0] = datafs_ops;
9604faabf0Stsutsui printf("data(compiled):noname\n");
9704faabf0Stsutsui return 0;
9804faabf0Stsutsui }
9904faabf0Stsutsui
10004faabf0Stsutsui /* NFS boot */
10104faabf0Stsutsui if (strcmp(fname, "nfs") == 0) {
10204faabf0Stsutsui if (!DEVICE_CAPABILITY.network_enabled) {
10304faabf0Stsutsui printf("Network disabled.\n");
10404faabf0Stsutsui return -1;
10504faabf0Stsutsui }
10616ed6645Sthorpej try_bootp = true;
10704faabf0Stsutsui file_system[0] = nfs_ops;
10804faabf0Stsutsui f->f_dev = &netdevsw;
10904faabf0Stsutsui if (*filename == '\0') {
11004faabf0Stsutsui printf("set kernel filename. ex.) nfs:netbsd\n");
11104faabf0Stsutsui return 1;
11204faabf0Stsutsui }
11304faabf0Stsutsui *--filename = '/';
11404faabf0Stsutsui *file = filename;
11504faabf0Stsutsui printf("nfs:/%s\n", filename);
11604faabf0Stsutsui net_open(f);
11704faabf0Stsutsui return 0;
11804faabf0Stsutsui }
11904faabf0Stsutsui
12004faabf0Stsutsui /* FD boot */
12104faabf0Stsutsui if (strcmp(fname, "fd") == 0) {
12204faabf0Stsutsui printf("floppy(boot):/%s (ustarfs)\n", filename);
12304faabf0Stsutsui f->f_dev = &dkdevsw;
12404faabf0Stsutsui file_system[0] = datafs_ops;
12504faabf0Stsutsui devsw[0] = dkdevsw;
12604faabf0Stsutsui device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1);
12704faabf0Stsutsui if (!ustarfs_load(filename, &addr, &size))
12804faabf0Stsutsui return -1;
12904faabf0Stsutsui data_attach(addr, size);
13004faabf0Stsutsui *file = filename;
13104faabf0Stsutsui return 0;
13204faabf0Stsutsui }
13304faabf0Stsutsui
13404faabf0Stsutsui /* Disk boot */
13504faabf0Stsutsui if (strncmp(fname, "sd", 2) == 0) {
13604faabf0Stsutsui enum fstype fs;
13704faabf0Stsutsui if (!DEVICE_CAPABILITY.disk_enabled) {
13804faabf0Stsutsui printf("Disk disabled.\n");
13904faabf0Stsutsui return -1;
14004faabf0Stsutsui }
14104faabf0Stsutsui
14204faabf0Stsutsui disk = fname[2] - '0';
14304faabf0Stsutsui partition = fname[3] - 'a';
14404faabf0Stsutsui if (disk < 0 || disk > 9 || partition < 0 || partition > 15) {
14504faabf0Stsutsui fs = FSTYPE_USTARFS;
14604faabf0Stsutsui printf("disk(boot):%s ", filename);
14704faabf0Stsutsui device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1);
14804faabf0Stsutsui } else {
14904faabf0Stsutsui fs = fstype(partition);
15004faabf0Stsutsui printf("disk(%d,%d):/%s ",
15104faabf0Stsutsui disk, partition, filename);
15204faabf0Stsutsui device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition);
15304faabf0Stsutsui }
15404faabf0Stsutsui
15504faabf0Stsutsui switch (fs) {
15604faabf0Stsutsui case FSTYPE_UFS:
15704faabf0Stsutsui printf(" (ufs)\n");
15804faabf0Stsutsui f->f_dev = &dkdevsw;
15904faabf0Stsutsui file_system[0] = ufs_ops;
16004faabf0Stsutsui devsw[0] = dkdevsw;
16104faabf0Stsutsui break;
16204faabf0Stsutsui case FSTYPE_BFS:
16304faabf0Stsutsui printf(" (bfs)\n");
16404faabf0Stsutsui f->f_flags |= F_NODEV;
16504faabf0Stsutsui file_system[0] = bfs_ops;
16604faabf0Stsutsui break;
16704faabf0Stsutsui case FSTYPE_USTARFS:
16804faabf0Stsutsui printf(" (ustarfs)\n");
16904faabf0Stsutsui f->f_dev = &dkdevsw;
17004faabf0Stsutsui file_system[0] = datafs_ops;
17104faabf0Stsutsui devsw[0] = dkdevsw;
17204faabf0Stsutsui if (!ustarfs_load(filename, &addr, &size))
17304faabf0Stsutsui return -1;
17404faabf0Stsutsui data_attach(addr, size);
17504faabf0Stsutsui break;
17604faabf0Stsutsui }
17704faabf0Stsutsui *file = filename;
17804faabf0Stsutsui return 0;
17904faabf0Stsutsui }
18004faabf0Stsutsui
18104faabf0Stsutsui printf("%s invalid.\n", fname);
18204faabf0Stsutsui
18304faabf0Stsutsui return -1;
18404faabf0Stsutsui }
185