Move boot device detection code from i386 and amd64 ports to x86_autoconf.c.
Rename i386_alldisks and x86_64_alldisks to x86_alldisks, adjust other references to compensate.
This commit is contained in:
parent
f3458f94d0
commit
42b8fac3b8
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.9 2004/10/15 06:18:48 thorpej Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.10 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@ -41,27 +41,21 @@
|
||||
* device tables and the memory controller monitoring. Available
|
||||
* devices are determined (from possibilities mentioned in ioconf.c),
|
||||
* and the drivers are initialized.
|
||||
*
|
||||
* Lots of this is now in x86/x86/x86_autoconf.c
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.9 2004/10/15 06:18:48 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.10 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/dkio.h>
|
||||
|
||||
#include <machine/pte.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#include "ioapic.h"
|
||||
#include "lapic.h"
|
||||
@ -74,13 +68,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.9 2004/10/15 06:18:48 thorpej Exp $")
|
||||
#include <machine/i82489var.h>
|
||||
#endif
|
||||
|
||||
static int match_harddisk __P((struct device *, struct btinfo_bootdisk *));
|
||||
static void matchbiosdisks __P((void));
|
||||
static void findroot __P((void));
|
||||
|
||||
extern struct disklist *x86_64_alldisks;
|
||||
extern int x86_64_ndisks;
|
||||
|
||||
#include "bios32.h"
|
||||
#if NBIOS32 > 0
|
||||
#include <machine/bios32.h>
|
||||
@ -123,370 +110,3 @@ cpu_configure()
|
||||
spl0();
|
||||
lcr8(0);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_rootconf()
|
||||
{
|
||||
findroot();
|
||||
matchbiosdisks();
|
||||
|
||||
printf("boot device: %s\n",
|
||||
booted_device ? booted_device->dv_xname : "<unknown>");
|
||||
|
||||
setroot(booted_device, booted_partition);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX ugly bit of code. But, this is the only safe time that the
|
||||
* match between BIOS disks and native disks can be done.
|
||||
*/
|
||||
static void
|
||||
matchbiosdisks()
|
||||
{
|
||||
struct btinfo_biosgeom *big;
|
||||
struct bi_biosgeom_entry *be;
|
||||
struct device *dv;
|
||||
int i, ck, error, m, n, bmajor;
|
||||
struct vnode *tv;
|
||||
char mbr[DEV_BSIZE];
|
||||
|
||||
big = lookup_bootinfo(BTINFO_BIOSGEOM);
|
||||
|
||||
if (big == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* First, count all native disks
|
||||
*/
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next)
|
||||
if (dv->dv_class == DV_DISK &&
|
||||
(!strcmp(dv->dv_cfdata->cf_name, "sd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "wd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "ld")))
|
||||
x86_64_ndisks++;
|
||||
|
||||
if (x86_64_ndisks == 0)
|
||||
return;
|
||||
|
||||
/* XXX M_TEMP is wrong */
|
||||
x86_64_alldisks = malloc(sizeof (struct disklist) + (x86_64_ndisks - 1) *
|
||||
sizeof (struct nativedisk_info),
|
||||
M_TEMP, M_NOWAIT);
|
||||
if (x86_64_alldisks == NULL)
|
||||
return;
|
||||
|
||||
x86_64_alldisks->dl_nnativedisks = x86_64_ndisks;
|
||||
x86_64_alldisks->dl_nbiosdisks = big->num;
|
||||
for (i = 0; i < big->num; i++) {
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
|
||||
x86_64_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX code duplication from findroot()
|
||||
*/
|
||||
n = -1;
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: trying to match (%s) %s\n",
|
||||
dv->dv_xname, dv->dv_cfdata->cf_name);
|
||||
#endif
|
||||
if (!strcmp(dv->dv_cfdata->cf_name, "sd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "wd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "ld")) {
|
||||
n++;
|
||||
sprintf(x86_64_alldisks->dl_nativedisks[n].ni_devname,
|
||||
"%s%d", dv->dv_cfdata->cf_name,
|
||||
dv->dv_unit);
|
||||
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return;
|
||||
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART),
|
||||
&tv))
|
||||
panic("matchbiosdisks: can't alloc vnode");
|
||||
|
||||
error = VOP_OPEN(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
vput(tv);
|
||||
continue;
|
||||
}
|
||||
error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
|
||||
UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
|
||||
VOP_CLOSE(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: %s: MBR read failure\n",
|
||||
dv->dv_xname);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ck = i = 0; i < DEV_BSIZE; i++)
|
||||
ck += mbr[i];
|
||||
for (m = i = 0; i < big->num; i++) {
|
||||
be = &big->disk[i];
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("match %s with %d\n", dv->dv_xname, i);
|
||||
printf("dev ck %x bios ck %x\n", ck, be->cksum);
|
||||
#endif
|
||||
if (be->flags & BI_GEOM_INVALID)
|
||||
continue;
|
||||
if (be->cksum == ck &&
|
||||
!memcmp(&mbr[MBR_PART_OFFSET], be->dosparts,
|
||||
MBR_PART_COUNT *
|
||||
sizeof (struct mbr_partition))) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matched bios disk %x with %s\n",
|
||||
be->dev, be->devname);
|
||||
#endif
|
||||
x86_64_alldisks->dl_nativedisks[n].
|
||||
ni_biosmatches[m++] = i;
|
||||
}
|
||||
}
|
||||
x86_64_alldisks->dl_nativedisks[n].ni_nmatches = m;
|
||||
vput(tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* helper function for "findroot()":
|
||||
* return nonzero if disk device matches bootinfo
|
||||
*/
|
||||
static int
|
||||
match_harddisk(dv, bid)
|
||||
struct device *dv;
|
||||
struct btinfo_bootdisk *bid;
|
||||
{
|
||||
struct vnode *tmpvn;
|
||||
int bmajor, error;
|
||||
struct disklabel label;
|
||||
int found = 0;
|
||||
|
||||
/*
|
||||
* A disklabel is required here. The
|
||||
* bootblocks don't refuse to boot from
|
||||
* a disk without a label, but this is
|
||||
* normally not wanted.
|
||||
*/
|
||||
if (bid->labelsector == -1)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* lookup major number for disk block device
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return(0); /* XXX panic() ??? */
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open
|
||||
* it, and read the disklabel for comparison.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART), &tmpvn))
|
||||
panic("findroot can't alloc vnode");
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing
|
||||
* device, partition or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("findroot: can't open dev %s%c (%d)\n",
|
||||
dv->dv_xname, 'a' + bid->partition, error);
|
||||
vput(tmpvn);
|
||||
return(0);
|
||||
}
|
||||
error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
/*
|
||||
* XXX can't happen - open() would
|
||||
* have errored out (or faked up one)
|
||||
*/
|
||||
printf("can't get label for dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
goto closeout;
|
||||
}
|
||||
|
||||
/* compare with our data */
|
||||
if (label.d_type == bid->label.type &&
|
||||
label.d_checksum == bid->label.checksum &&
|
||||
!strncmp(label.d_packname, bid->label.packname, 16))
|
||||
found = 1;
|
||||
|
||||
closeout:
|
||||
VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
|
||||
vput(tmpvn);
|
||||
return(found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to find the device from which we were booted.
|
||||
* If we can do so, and not instructed not to do so,
|
||||
* change rootdev to correspond to the load device.
|
||||
*/
|
||||
void
|
||||
findroot(void)
|
||||
{
|
||||
struct btinfo_bootdisk *bid;
|
||||
struct device *dv;
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
|
||||
if (lookup_bootinfo(BTINFO_NETIF)) {
|
||||
/*
|
||||
* We got netboot interface information, but
|
||||
* "device_register()" couldn't match it to a configured
|
||||
* device. Bootdisk information cannot be present at the
|
||||
* same time, so give up.
|
||||
*/
|
||||
printf("findroot: netboot interface not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bid = lookup_bootinfo(BTINFO_BOOTDISK);
|
||||
if (bid) {
|
||||
/*
|
||||
* Scan all disk devices for ones that match the passed data.
|
||||
* Don't break if one is found, to get possible multiple
|
||||
* matches - for problem tracking. Use the first match anyway
|
||||
* because lower device numbers are more likely to be the
|
||||
* boot device.
|
||||
*/
|
||||
for (dv = alldevs.tqh_first; dv != NULL;
|
||||
dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
|
||||
if (!strcmp(dv->dv_cfdata->cf_name, "fd")) {
|
||||
/*
|
||||
* Assume the configured unit number matches
|
||||
* the BIOS device number. (This is the old
|
||||
* behaviour.) Needs some ideas how to handle
|
||||
* BIOS's "swap floppy drive" options.
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) ||
|
||||
dv->dv_unit != bid->biosdev)
|
||||
continue;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (!strcmp(dv->dv_cfdata->cf_name, "sd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "wd") ||
|
||||
!strcmp(dv->dv_cfdata->cf_name, "ld")) {
|
||||
/*
|
||||
* Don't trust BIOS device numbers, try
|
||||
* to match the information passed by the
|
||||
* bootloader instead.
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) == 0 ||
|
||||
!match_harddisk(dv, bid))
|
||||
continue;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* no "fd", "wd", "sd", "ld" */
|
||||
continue;
|
||||
|
||||
found:
|
||||
if (booted_device) {
|
||||
printf("warning: double match for boot "
|
||||
"device (%s, %s)\n", booted_device->dv_xname,
|
||||
dv->dv_xname);
|
||||
continue;
|
||||
}
|
||||
booted_device = dv;
|
||||
booted_partition = bid->partition;
|
||||
}
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#if NPCI > 0
|
||||
#include <dev/pci/pcivar.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
device_register(dev, aux)
|
||||
struct device *dev;
|
||||
void *aux;
|
||||
{
|
||||
/*
|
||||
* Handle network interfaces here, the attachment information is
|
||||
* not available driver independantly later.
|
||||
* For disks, there is nothing useful available at attach time.
|
||||
*/
|
||||
if (dev->dv_class == DV_IFNET) {
|
||||
struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
|
||||
if (bin == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We don't check the driver name against the device name
|
||||
* passed by the boot ROM. The ROM should stay usable
|
||||
* if the driver gets obsoleted.
|
||||
* The physical attachment information (checked below)
|
||||
* must be sufficient to identify the device.
|
||||
*/
|
||||
|
||||
if (bin->bus == BI_BUS_ISA &&
|
||||
!strcmp(dev->dv_parent->dv_cfdata->cf_name,
|
||||
"isa")) {
|
||||
struct isa_attach_args *iaa = aux;
|
||||
|
||||
/* compare IO base address */
|
||||
/* XXXJRT what about multiple I/O addrs? */
|
||||
if (iaa->ia_nio > 0 &&
|
||||
bin->addr.iobase == iaa->ia_io[0].ir_addr)
|
||||
goto found;
|
||||
}
|
||||
#if NPCI > 0
|
||||
if (bin->bus == BI_BUS_PCI &&
|
||||
!strcmp(dev->dv_parent->dv_cfdata->cf_name,
|
||||
"pci")) {
|
||||
struct pci_attach_args *paa = aux;
|
||||
int b, d, f;
|
||||
|
||||
/*
|
||||
* Calculate BIOS representation of:
|
||||
*
|
||||
* <bus,device,function>
|
||||
*
|
||||
* and compare.
|
||||
*/
|
||||
pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
|
||||
if (bin->addr.tag == ((b << 8) | (d << 3) | f))
|
||||
goto found;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
|
||||
found:
|
||||
if (booted_device) {
|
||||
/* XXX should be a "panic()" */
|
||||
printf("warning: double match for boot device (%s, %s)\n",
|
||||
booted_device->dv_xname, dev->dv_xname);
|
||||
return;
|
||||
}
|
||||
booted_device = dev;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.30 2004/08/05 13:31:38 cube Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.31 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
||||
@ -72,7 +72,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.30 2004/08/05 13:31:38 cube Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.31 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_user_ldt.h"
|
||||
#include "opt_ddb.h"
|
||||
@ -167,8 +167,8 @@ char bootinfo[BOOTINFO_MAXSIZE];
|
||||
struct cpu_info cpu_info_primary;
|
||||
struct cpu_info *cpu_info_list;
|
||||
|
||||
struct bi_devmatch *x86_64_alldisks = NULL;
|
||||
int x86_64_ndisks = 0;
|
||||
extern struct bi_devmatch *x86_alldisks;
|
||||
extern int x86_ndisks;
|
||||
|
||||
#ifdef CPURESET_DELAY
|
||||
int cpureset_delay = CPURESET_DELAY;
|
||||
@ -377,13 +377,13 @@ sysctl_machdep_diskinfo(SYSCTLFN_ARGS)
|
||||
{
|
||||
struct sysctlnode node;
|
||||
|
||||
if (x86_64_alldisks == NULL)
|
||||
if (x86_alldisks == NULL)
|
||||
return (ENOENT);
|
||||
|
||||
node = *rnode;
|
||||
node.sysctl_data = x86_64_alldisks;
|
||||
node.sysctl_data = x86_alldisks;
|
||||
node.sysctl_size = sizeof(struct disklist) +
|
||||
(x86_64_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
(x86_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.79 2004/10/15 06:18:47 thorpej Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.80 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
@ -41,10 +41,12 @@
|
||||
* device tables and the memory controller monitoring. Available
|
||||
* devices are determined (from possibilities mentioned in ioconf.c),
|
||||
* and the drivers are initialized.
|
||||
*
|
||||
* Lots of this is now in x86/x86/x86_autoconf.c
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.79 2004/10/15 06:18:47 thorpej Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.80 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_compat_oldboot.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
@ -52,16 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.79 2004/10/15 06:18:47 thorpej Exp $"
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/conf.h>
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
#include <sys/reboot.h>
|
||||
#endif
|
||||
#include <sys/device.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/user.h>
|
||||
|
||||
@ -69,7 +61,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.79 2004/10/15 06:18:47 thorpej Exp $"
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/gdt.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#include "ioapic.h"
|
||||
#include "lapic.h"
|
||||
@ -82,14 +73,6 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.79 2004/10/15 06:18:47 thorpej Exp $"
|
||||
#include <machine/i82489var.h>
|
||||
#endif
|
||||
|
||||
static int match_harddisk(struct device *, struct btinfo_bootdisk *);
|
||||
static void matchbiosdisks(void);
|
||||
static void findroot(void);
|
||||
static int is_valid_disk(struct device *);
|
||||
|
||||
extern struct disklist *i386_alldisks;
|
||||
extern int i386_ndisks;
|
||||
|
||||
#include "bios32.h"
|
||||
#if NBIOS32 > 0
|
||||
#include <machine/bios32.h>
|
||||
@ -107,9 +90,6 @@ extern int i386_ndisks;
|
||||
#include <machine/kvm86.h>
|
||||
#endif
|
||||
|
||||
struct device *booted_device;
|
||||
int booted_partition;
|
||||
|
||||
/*
|
||||
* Determine i/o configuration for a machine.
|
||||
*/
|
||||
@ -155,413 +135,3 @@ cpu_configure(void)
|
||||
lapic_tpr = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
cpu_rootconf(void)
|
||||
{
|
||||
findroot();
|
||||
matchbiosdisks();
|
||||
|
||||
printf("boot device: %s\n",
|
||||
booted_device ? booted_device->dv_xname : "<unknown>");
|
||||
|
||||
setroot(booted_device, booted_partition);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX ugly bit of code. But, this is the only safe time that the
|
||||
* match between BIOS disks and native disks can be done.
|
||||
*/
|
||||
static void
|
||||
matchbiosdisks(void)
|
||||
{
|
||||
struct btinfo_biosgeom *big;
|
||||
struct bi_biosgeom_entry *be;
|
||||
struct device *dv;
|
||||
int i, ck, error, m, n;
|
||||
struct vnode *tv;
|
||||
char mbr[DEV_BSIZE];
|
||||
int dklist_size;
|
||||
int bmajor;
|
||||
int numbig;
|
||||
|
||||
big = lookup_bootinfo(BTINFO_BIOSGEOM);
|
||||
|
||||
numbig = big ? big->num : 0;
|
||||
|
||||
/*
|
||||
* First, count all native disks
|
||||
*/
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next)
|
||||
if (is_valid_disk(dv))
|
||||
i386_ndisks++;
|
||||
|
||||
dklist_size = sizeof (struct disklist) + (i386_ndisks - 1) *
|
||||
sizeof (struct nativedisk_info);
|
||||
|
||||
/* XXX M_TEMP is wrong */
|
||||
i386_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
|
||||
if (i386_alldisks == NULL)
|
||||
return;
|
||||
|
||||
i386_alldisks->dl_nnativedisks = i386_ndisks;
|
||||
i386_alldisks->dl_nbiosdisks = numbig;
|
||||
for (i = 0; i < numbig; i++) {
|
||||
i386_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
|
||||
i386_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
|
||||
i386_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
|
||||
i386_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
|
||||
i386_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
|
||||
i386_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
|
||||
#ifdef GEOM_DEBUG
|
||||
#ifdef NOTYET
|
||||
printf("disk %x: flags %x, interface %x, device %llx\n",
|
||||
big->disk[i].dev, big->disk[i].flags,
|
||||
big->disk[i].interface_path, big->disk[i].device_path);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX code duplication from findroot()
|
||||
*/
|
||||
n = -1;
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: trying to match (%s) %s\n",
|
||||
dv->dv_xname, dv->dv_cfdata->cf_name);
|
||||
#endif
|
||||
if (is_valid_disk(dv)) {
|
||||
n++;
|
||||
snprintf(i386_alldisks->dl_nativedisks[n].ni_devname,
|
||||
sizeof(i386_alldisks->dl_nativedisks[n].ni_devname),
|
||||
"%s%d", dv->dv_cfdata->cf_name,
|
||||
dv->dv_unit);
|
||||
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return;
|
||||
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART),
|
||||
&tv))
|
||||
panic("matchbiosdisks: can't alloc vnode");
|
||||
|
||||
error = VOP_OPEN(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
vput(tv);
|
||||
continue;
|
||||
}
|
||||
error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
|
||||
UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
|
||||
VOP_CLOSE(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: %s: MBR read failure\n",
|
||||
dv->dv_xname);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ck = i = 0; i < DEV_BSIZE; i++)
|
||||
ck += mbr[i];
|
||||
for (m = i = 0; i < numbig; i++) {
|
||||
be = &big->disk[i];
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("match %s with %d ", dv->dv_xname, i);
|
||||
printf("dev ck %x bios ck %x\n", ck, be->cksum);
|
||||
#endif
|
||||
if (be->flags & BI_GEOM_INVALID)
|
||||
continue;
|
||||
if (be->cksum == ck &&
|
||||
!memcmp(&mbr[MBR_PART_OFFSET], be->dosparts,
|
||||
MBR_PART_COUNT *
|
||||
sizeof (struct mbr_partition))) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matched bios disk %x with %s\n",
|
||||
be->dev, dv->dv_xname);
|
||||
#endif
|
||||
i386_alldisks->dl_nativedisks[n].
|
||||
ni_biosmatches[m++] = i;
|
||||
}
|
||||
}
|
||||
i386_alldisks->dl_nativedisks[n].ni_nmatches = m;
|
||||
vput(tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
u_long bootdev = 0; /* should be dev_t, but not until 32 bits */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* helper function for "findroot()":
|
||||
* return nonzero if disk device matches bootinfo
|
||||
*/
|
||||
static int
|
||||
match_harddisk(struct device *dv, struct btinfo_bootdisk *bid)
|
||||
{
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
struct disklabel label;
|
||||
int found = 0;
|
||||
int bmajor;
|
||||
|
||||
/*
|
||||
* A disklabel is required here. The
|
||||
* bootblocks don't refuse to boot from
|
||||
* a disk without a label, but this is
|
||||
* normally not wanted.
|
||||
*/
|
||||
if (bid->labelsector == -1)
|
||||
return(0);
|
||||
|
||||
/*
|
||||
* lookup major number for disk block device
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return(0); /* XXX panic() ??? */
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open
|
||||
* it, and read the disklabel for comparison.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART), &tmpvn))
|
||||
panic("findroot can't alloc vnode");
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing
|
||||
* device, partition or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("findroot: can't open dev %s%c (%d)\n",
|
||||
dv->dv_xname, 'a' + bid->partition, error);
|
||||
vput(tmpvn);
|
||||
return(0);
|
||||
}
|
||||
error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
/*
|
||||
* XXX can't happen - open() would
|
||||
* have errored out (or faked up one)
|
||||
*/
|
||||
printf("can't get label for dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
goto closeout;
|
||||
}
|
||||
|
||||
/* compare with our data */
|
||||
if (label.d_type == bid->label.type &&
|
||||
label.d_checksum == bid->label.checksum &&
|
||||
!strncmp(label.d_packname, bid->label.packname, 16))
|
||||
found = 1;
|
||||
|
||||
closeout:
|
||||
VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
|
||||
vput(tmpvn);
|
||||
return(found);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to find the device from which we were booted.
|
||||
* If we can do so, and not instructed not to do so,
|
||||
* change rootdev to correspond to the load device.
|
||||
*/
|
||||
void
|
||||
findroot(void)
|
||||
{
|
||||
struct btinfo_bootdisk *bid;
|
||||
struct device *dv;
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
int i, majdev, unit, part;
|
||||
char buf[32];
|
||||
#endif
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
|
||||
if (lookup_bootinfo(BTINFO_NETIF)) {
|
||||
/*
|
||||
* We got netboot interface information, but
|
||||
* "device_register()" couldn't match it to a configured
|
||||
* device. Bootdisk information cannot be present at the
|
||||
* same time, so give up.
|
||||
*/
|
||||
printf("findroot: netboot interface not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bid = lookup_bootinfo(BTINFO_BOOTDISK);
|
||||
if (bid) {
|
||||
/*
|
||||
* Scan all disk devices for ones that match the passed data.
|
||||
* Don't break if one is found, to get possible multiple
|
||||
* matches - for problem tracking. Use the first match anyway
|
||||
* because lower device numbers are more likely to be the
|
||||
* boot device.
|
||||
*/
|
||||
for (dv = alldevs.tqh_first; dv != NULL;
|
||||
dv = dv->dv_list.tqe_next) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
|
||||
if (!strcmp(dv->dv_cfdata->cf_name, "fd")) {
|
||||
/*
|
||||
* Assume the configured unit number matches
|
||||
* the BIOS device number. (This is the old
|
||||
* behaviour.) Needs some ideas how to handle
|
||||
* BIOS's "swap floppy drive" options.
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) ||
|
||||
dv->dv_unit != bid->biosdev)
|
||||
continue;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (is_valid_disk(dv)) {
|
||||
/*
|
||||
* Don't trust BIOS device numbers, try
|
||||
* to match the information passed by the
|
||||
* bootloader instead.
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) == 0 ||
|
||||
!match_harddisk(dv, bid))
|
||||
continue;
|
||||
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* no "fd", "wd", "sd", "ld", "ed" */
|
||||
continue;
|
||||
|
||||
found:
|
||||
if (booted_device) {
|
||||
printf("warning: double match for boot "
|
||||
"device (%s, %s)\n",
|
||||
booted_device->dv_xname, dv->dv_xname);
|
||||
continue;
|
||||
}
|
||||
booted_device = dv;
|
||||
booted_partition = bid->partition;
|
||||
}
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
#if 0
|
||||
printf("howto %x bootdev %x ", boothowto, bootdev);
|
||||
#endif
|
||||
|
||||
if ((bootdev & B_MAGICMASK) != (u_long)B_DEVMAGIC)
|
||||
return;
|
||||
|
||||
majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
|
||||
name = devsw_blk2name(majdev);
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
|
||||
unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%d", name, unit);
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next) {
|
||||
if (strcmp(buf, dv->dv_xname) == 0) {
|
||||
booted_device = dv;
|
||||
booted_partition = part;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#if NPCI > 0
|
||||
#include <dev/pci/pcivar.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
device_register(struct device *dev, void *aux)
|
||||
{
|
||||
/*
|
||||
* Handle network interfaces here, the attachment information is
|
||||
* not available driver independantly later.
|
||||
* For disks, there is nothing useful available at attach time.
|
||||
*/
|
||||
if (dev->dv_class == DV_IFNET) {
|
||||
struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
|
||||
if (bin == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We don't check the driver name against the device name
|
||||
* passed by the boot ROM. The ROM should stay usable
|
||||
* if the driver gets obsoleted.
|
||||
* The physical attachment information (checked below)
|
||||
* must be sufficient to identify the device.
|
||||
*/
|
||||
|
||||
if (bin->bus == BI_BUS_ISA &&
|
||||
!strcmp(dev->dv_parent->dv_cfdata->cf_name, "isa")) {
|
||||
struct isa_attach_args *iaa = aux;
|
||||
|
||||
/* compare IO base address */
|
||||
/* XXXJRT what about multiple I/O addrs? */
|
||||
if (iaa->ia_nio > 0 &&
|
||||
bin->addr.iobase == iaa->ia_io[0].ir_addr)
|
||||
goto found;
|
||||
}
|
||||
#if NPCI > 0
|
||||
if (bin->bus == BI_BUS_PCI &&
|
||||
!strcmp(dev->dv_parent->dv_cfdata->cf_name, "pci")) {
|
||||
struct pci_attach_args *paa = aux;
|
||||
int b, d, f;
|
||||
|
||||
/*
|
||||
* Calculate BIOS representation of:
|
||||
*
|
||||
* <bus,device,function>
|
||||
*
|
||||
* and compare.
|
||||
*/
|
||||
pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
|
||||
if (bin->addr.tag == ((b << 8) | (d << 3) | f))
|
||||
goto found;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
|
||||
found:
|
||||
if (booted_device) {
|
||||
/* XXX should be a "panic()" */
|
||||
printf("warning: double match for boot device (%s, %s)\n",
|
||||
booted_device->dv_xname, dev->dv_xname);
|
||||
return;
|
||||
}
|
||||
booted_device = dev;
|
||||
}
|
||||
|
||||
static int
|
||||
is_valid_disk(struct device *dv)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (dv->dv_class != DV_DISK)
|
||||
return (0);
|
||||
|
||||
name = dv->dv_cfdata->cf_name;
|
||||
|
||||
return (strcmp(name, "sd") == 0 || strcmp(name, "wd") == 0 ||
|
||||
strcmp(name, "ld") == 0 || strcmp(name, "ed") == 0);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.558 2004/08/26 10:12:33 junyoung Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.559 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1996, 1997, 1998, 2000 The NetBSD Foundation, Inc.
|
||||
@ -72,7 +72,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.558 2004/08/26 10:12:33 junyoung Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.559 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
@ -205,8 +205,8 @@ char machine_arch[] = "i386"; /* machine == machine_arch */
|
||||
|
||||
char bootinfo[BOOTINFO_MAXSIZE];
|
||||
|
||||
struct bi_devmatch *i386_alldisks = NULL;
|
||||
int i386_ndisks = 0;
|
||||
extern struct bi_devmatch *x86_alldisks;
|
||||
extern int x86_ndisks;
|
||||
|
||||
#ifdef CPURESET_DELAY
|
||||
int cpureset_delay = CPURESET_DELAY;
|
||||
@ -470,11 +470,11 @@ sysctl_machdep_diskinfo(SYSCTLFN_ARGS)
|
||||
struct sysctlnode node;
|
||||
|
||||
node = *rnode;
|
||||
if (!i386_alldisks)
|
||||
if (x86_alldisks == NULL)
|
||||
return(EOPNOTSUPP);
|
||||
node.sysctl_data = i386_alldisks;
|
||||
node.sysctl_data = x86_alldisks;
|
||||
node.sysctl_size = sizeof(struct disklist) +
|
||||
(i386_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
(x86_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.x86,v 1.11 2004/08/30 15:05:19 drochner Exp $
|
||||
# $NetBSD: files.x86,v 1.12 2004/10/20 04:20:05 thorpej Exp $
|
||||
|
||||
# options for MP configuration through the MP spec
|
||||
defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI
|
||||
@ -20,6 +20,7 @@ file arch/x86/x86/ipi.c multiprocessor
|
||||
file arch/x86/x86/lock_machdep.c lockdebug
|
||||
file arch/x86/x86/mtrr_i686.c mtrr
|
||||
file arch/x86/x86/softintr.c
|
||||
file arch/x86/x86/x86_autoconf.c
|
||||
|
||||
define lapic
|
||||
file arch/x86/x86/lapic.c lapic needs-flag
|
||||
|
476
sys/arch/x86/x86/x86_autoconf.c
Normal file
476
sys/arch/x86/x86/x86_autoconf.c
Normal file
@ -0,0 +1,476 @@
|
||||
/* $NetBSD: x86_autoconf.c,v 1.1 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* William Jolitz.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)autoconf.c 7.1 (Berkeley) 5/9/91
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/conf.h>
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
#include <sys/reboot.h>
|
||||
#endif
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/dkio.h>
|
||||
#include <sys/proc.h>
|
||||
|
||||
#include <machine/bootinfo.h>
|
||||
|
||||
#include "pci.h"
|
||||
|
||||
#include <dev/isa/isavar.h>
|
||||
#if NPCI > 0
|
||||
#include <dev/pci/pcivar.h>
|
||||
#endif
|
||||
|
||||
struct device *booted_device;
|
||||
int booted_partition;
|
||||
|
||||
struct disklist *x86_alldisks;
|
||||
int x86_ndisks;
|
||||
|
||||
static int
|
||||
is_valid_disk(struct device *dv)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (dv->dv_class != DV_DISK)
|
||||
return (0);
|
||||
|
||||
name = dv->dv_cfdata->cf_name;
|
||||
|
||||
return (strcmp(name, "sd") == 0 || strcmp(name, "wd") == 0 ||
|
||||
strcmp(name, "ld") == 0 || strcmp(name, "ed") == 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Ugly bit of code. But, this is the only safe time that the
|
||||
* match between BIOS disks and native disks can be done.
|
||||
*/
|
||||
static void
|
||||
matchbiosdisks(void)
|
||||
{
|
||||
struct btinfo_biosgeom *big;
|
||||
struct bi_biosgeom_entry *be;
|
||||
struct device *dv;
|
||||
int i, ck, error, m, n;
|
||||
struct vnode *tv;
|
||||
char mbr[DEV_BSIZE];
|
||||
int dklist_size;
|
||||
int bmajor, numbig;
|
||||
|
||||
big = lookup_bootinfo(BTINFO_BIOSGEOM);
|
||||
|
||||
numbig = big ? big->num : 0;
|
||||
|
||||
/* First, count all native disks. */
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list)) {
|
||||
if (is_valid_disk(dv))
|
||||
x86_ndisks++;
|
||||
}
|
||||
|
||||
dklist_size = sizeof(struct disklist) + (x86_ndisks - 1) *
|
||||
sizeof(struct nativedisk_info);
|
||||
|
||||
/* XXX M_TEMP is wrong */
|
||||
x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT | M_ZERO);
|
||||
if (x86_alldisks == NULL)
|
||||
return;
|
||||
|
||||
x86_alldisks->dl_nnativedisks = x86_ndisks;
|
||||
x86_alldisks->dl_nbiosdisks = numbig;
|
||||
for (i = 0; i < numbig; i++) {
|
||||
x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
|
||||
x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
|
||||
x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
|
||||
x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
|
||||
x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
|
||||
x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
|
||||
#ifdef GEOM_DEBUG
|
||||
#ifdef notyet
|
||||
printf("disk %x: flags %x, interface %x, device %llx\n",
|
||||
big->disk[i].dev, big->disk[i].flags,
|
||||
big->disk[i].interface_path, big->disk[i].device_path);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX Code duplication from findroot(). */
|
||||
n = -1;
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list)) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: trying to match (%s) %s\n",
|
||||
dv->dv_xname, dv->dv_cfdata->cf_name);
|
||||
#endif
|
||||
if (is_valid_disk(dv)) {
|
||||
n++;
|
||||
/* XXXJRT why not just dv_xname?? */
|
||||
snprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
|
||||
sizeof(x86_alldisks->dl_nativedisks[n].ni_devname),
|
||||
"%s%d", dv->dv_cfdata->cf_name, dv->dv_unit);
|
||||
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return;
|
||||
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART),
|
||||
&tv))
|
||||
panic("matchbiosdisks: can't alloc vnode");
|
||||
|
||||
error = VOP_OPEN(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
vput(tv);
|
||||
continue;
|
||||
}
|
||||
error = vn_rdwr(UIO_READ, tv, mbr, DEV_BSIZE, 0,
|
||||
UIO_SYSSPACE, 0, NOCRED, NULL, NULL);
|
||||
VOP_CLOSE(tv, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matchbiosdisks: %s: MBR read failure\n",
|
||||
dv->dv_xname);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
|
||||
for (ck = i = 0; i < DEV_BSIZE; i++)
|
||||
ck += mbr[i];
|
||||
for (m = i = 0; i < numbig; i++) {
|
||||
be = &big->disk[i];
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("match %s with %d "
|
||||
"dev ck %x bios ck %x\n", dv->dv_xname, i,
|
||||
ck, be->cksum);
|
||||
#endif
|
||||
if (be->flags & BI_GEOM_INVALID)
|
||||
continue;
|
||||
if (be->cksum == ck &&
|
||||
memcmp(&mbr[MBR_PART_OFFSET], be->dosparts,
|
||||
MBR_PART_COUNT *
|
||||
sizeof(struct mbr_partition)) == 0) {
|
||||
#ifdef GEOM_DEBUG
|
||||
printf("matched BIOS disk %x with %s\n",
|
||||
be->dev, dv->dv_xname);
|
||||
#endif
|
||||
x86_alldisks->dl_nativedisks[n].
|
||||
ni_biosmatches[m++] = i;
|
||||
}
|
||||
}
|
||||
x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
|
||||
vput(tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function for findroot():
|
||||
* Return non-zero if disk device matches bootinfo.
|
||||
*/
|
||||
static int
|
||||
match_bootdisk(struct device *dv, struct btinfo_bootdisk *bid)
|
||||
{
|
||||
struct vnode *tmpvn;
|
||||
int error;
|
||||
struct disklabel label;
|
||||
int found = 0;
|
||||
int bmajor;
|
||||
|
||||
/*
|
||||
* A disklabel is required here. The boot loader doesn't refuse
|
||||
* to boot from a disk without a label, but this is normally not
|
||||
* wanted.
|
||||
*/
|
||||
if (bid->labelsector == -1)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Lookup major number for disk block device.
|
||||
*/
|
||||
bmajor = devsw_name2blk(dv->dv_xname, NULL, 0);
|
||||
if (bmajor == -1)
|
||||
return (0); /* XXX panic ??? */
|
||||
|
||||
/*
|
||||
* Fake a temporary vnode for the disk, open it, and read
|
||||
* the disklabel for comparison.
|
||||
*/
|
||||
if (bdevvp(MAKEDISKDEV(bmajor, dv->dv_unit, RAW_PART), &tmpvn))
|
||||
panic("findroot: can't alloc vnode");
|
||||
error = VOP_OPEN(tmpvn, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
#ifndef DEBUG
|
||||
/*
|
||||
* Ignore errors caused by missing device, partition,
|
||||
* or medium.
|
||||
*/
|
||||
if (error != ENXIO && error != ENODEV)
|
||||
#endif
|
||||
printf("findroot: can't open dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
vput(tmpvn);
|
||||
return (0);
|
||||
}
|
||||
error = VOP_IOCTL(tmpvn, DIOCGDINFO, &label, FREAD, NOCRED, 0);
|
||||
if (error) {
|
||||
/*
|
||||
* XXX Can't happen -- open() would have errored out
|
||||
* or faked one up.
|
||||
*/
|
||||
printf("findroot: can't get labe for dev %s (%d)\n",
|
||||
dv->dv_xname, error);
|
||||
goto closeout;
|
||||
}
|
||||
|
||||
/* Compare with our data. */
|
||||
if (label.d_type == bid->label.type &&
|
||||
label.d_checksum == bid->label.checksum &&
|
||||
strncmp(label.d_packname, bid->label.packname, 16) == 0)
|
||||
found = 1;
|
||||
|
||||
closeout:
|
||||
VOP_CLOSE(tmpvn, FREAD, NOCRED, 0);
|
||||
vput(tmpvn);
|
||||
return (found);
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
/* Old style bootdev never existed on amd64. */
|
||||
#undef COMPAT_OLDBOOT
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
uint32_t bootdev = 0;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Attempt to find the device from which we were booted. If we can do so,
|
||||
* and not instructed not to do so, change rootdev to correspond to the
|
||||
* load device.
|
||||
*/
|
||||
static void
|
||||
findroot(void)
|
||||
{
|
||||
struct btinfo_bootdisk *bid;
|
||||
struct device *dv;
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
const char *name;
|
||||
int majdev, unit, part;
|
||||
char buf[32];
|
||||
#endif
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
|
||||
if (lookup_bootinfo(BTINFO_NETIF) != NULL) {
|
||||
/*
|
||||
* We got netboot interface information, but device_register()
|
||||
* failed to match it to a configured device. Boot disk
|
||||
* information cannot be present at the same time, so give
|
||||
* up.
|
||||
*/
|
||||
printf("findroot: netboot interface not found.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
bid = lookup_bootinfo(BTINFO_BOOTDISK);
|
||||
if (bid) {
|
||||
/*
|
||||
* Scan all disk devices for ones that match the passed data.
|
||||
* Don't break if one is found, to get possible multiple
|
||||
* matches - for problem tracking. Use the first match anyway
|
||||
* because lower device numbers are more likely to be the
|
||||
* boot device.
|
||||
*/
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list)) {
|
||||
if (dv->dv_class != DV_DISK)
|
||||
continue;
|
||||
|
||||
if (strcmp(dv->dv_cfdata->cf_name, "fd") == 0) {
|
||||
/*
|
||||
* Assume the configured unit number matches
|
||||
* the BIOS device number. (This is the old
|
||||
* behavior.) Needs some ideas how to handle
|
||||
* the BIOS's "swap floppy drive" options.
|
||||
*
|
||||
* XXXJRT This use of the unit number is
|
||||
* totally bogus!
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) != 0 ||
|
||||
dv->dv_unit != bid->biosdev)
|
||||
continue;
|
||||
goto found;
|
||||
}
|
||||
|
||||
if (is_valid_disk(dv)) {
|
||||
/*
|
||||
* Don't trust BIOS device numbers, try
|
||||
* to match the information passed by the
|
||||
* boot loader instead.
|
||||
*/
|
||||
if ((bid->biosdev & 0x80) == 0 ||
|
||||
match_bootdisk(dv, bid) == 0)
|
||||
continue;
|
||||
goto found;
|
||||
}
|
||||
|
||||
continue;
|
||||
found:
|
||||
if (booted_device) {
|
||||
printf("WARNING: double match for boot "
|
||||
"device (%s, %s)\n",
|
||||
booted_device->dv_xname, dv->dv_xname);
|
||||
continue;
|
||||
}
|
||||
booted_device = dv;
|
||||
booted_partition = bid->partition;
|
||||
}
|
||||
|
||||
if (booted_device)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef COMPAT_OLDBOOT
|
||||
#if 0
|
||||
printf("findroot: howto %x bootdev %x\n", boothowto, bootdev);
|
||||
#endif
|
||||
|
||||
if ((bootdev & B_MAGICMASK) != B_DEVMAGIC)
|
||||
return;
|
||||
|
||||
majdev = (bootdev >> B_TYPESHIFT) & B_TYPEMASK;
|
||||
name = devsw_blk2name(majdev);
|
||||
if (name == NULL)
|
||||
return;
|
||||
|
||||
part = (bootdev >> B_PARTITIONSHIFT) & B_PARTITIONMASK;
|
||||
unit = (bootdev >> B_UNITSHIFT) & B_UNITMASK;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s%d", name, unit);
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv != NULL;
|
||||
dv = TAILQ_NEXT(dv, dv_list)) {
|
||||
if (strcmp(buf, dv->dv_xname) == 0) {
|
||||
booted_device = dv;
|
||||
booted_partition = part;
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif /* COMPAT_OLDBOOT */
|
||||
}
|
||||
|
||||
void
|
||||
cpu_rootconf(void)
|
||||
{
|
||||
|
||||
findroot();
|
||||
matchbiosdisks();
|
||||
|
||||
printf("boot device: %s\n",
|
||||
booted_device ? booted_device->dv_xname : "<unknown>");
|
||||
|
||||
setroot(booted_device, booted_partition);
|
||||
}
|
||||
|
||||
void
|
||||
device_register(struct device *dev, void *aux)
|
||||
{
|
||||
|
||||
/*
|
||||
* Handle network interfaces here, the attachment information is
|
||||
* not available driver-independently later.
|
||||
*
|
||||
* For disks, there is nothing useful available at attach time.
|
||||
*/
|
||||
if (dev->dv_class == DV_IFNET) {
|
||||
struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
|
||||
if (bin == NULL)
|
||||
return;
|
||||
|
||||
/*
|
||||
* We don't check the driver name against the device name
|
||||
* passed by the boot ROM. The ROM should stay usable if
|
||||
* the driver becomes obsolete. The physical attachment
|
||||
* information (checked below) must be sufficient to
|
||||
* idenfity the device.
|
||||
*/
|
||||
if (bin->bus == BI_BUS_ISA &&
|
||||
strcmp(dev->dv_parent->dv_cfdata->cf_name, "isa") == 0) {
|
||||
struct isa_attach_args *iaa = aux;
|
||||
|
||||
/* Compare IO base address */
|
||||
/* XXXJRT What about multiple IO addrs? */
|
||||
if (iaa->ia_nio > 0 &&
|
||||
bin->addr.iobase == iaa->ia_io[0].ir_addr)
|
||||
goto found;
|
||||
}
|
||||
#if NPCI > 0
|
||||
if (bin->bus == BI_BUS_PCI &&
|
||||
strcmp(dev->dv_parent->dv_cfdata->cf_name, "pci") == 0) {
|
||||
struct pci_attach_args *paa = aux;
|
||||
int b, d, f;
|
||||
|
||||
/*
|
||||
* Calculate BIOS representation of:
|
||||
*
|
||||
* <bus,device,function>
|
||||
*
|
||||
* and compare.
|
||||
*/
|
||||
pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
|
||||
if (bin->addr.tag == ((b << 8) | (d << 3) | f))
|
||||
goto found;
|
||||
}
|
||||
#endif /* NPCI > 0 */
|
||||
}
|
||||
return;
|
||||
|
||||
found:
|
||||
if (booted_device) {
|
||||
/* XXX should be a panic() */
|
||||
printf("WARNING: double match for boot device (%s, %s)\n",
|
||||
booted_device->dv_xname, dev->dv_xname);
|
||||
return;
|
||||
}
|
||||
booted_device = dev;
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: autoconf.c,v 1.6 2004/09/17 14:11:23 skrll Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.7 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
/* NetBSD: autoconf.c,v 1.75 2003/12/30 12:33:22 pk Exp */
|
||||
|
||||
/*-
|
||||
@ -45,7 +45,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.6 2004/09/17 14:11:23 skrll Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.7 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_compat_oldboot.h"
|
||||
#include "opt_multiprocessor.h"
|
||||
@ -101,8 +101,8 @@ static void matchbiosdisks(void);
|
||||
static void findroot(void);
|
||||
static int is_valid_disk(struct device *);
|
||||
|
||||
extern struct disklist *i386_alldisks;
|
||||
extern int i386_ndisks;
|
||||
struct disklist *x86_alldisks;
|
||||
int x86_ndisks;
|
||||
|
||||
#include "bios32.h"
|
||||
#if NBIOS32 > 0
|
||||
@ -210,30 +210,30 @@ matchbiosdisks(void)
|
||||
*/
|
||||
for (dv = alldevs.tqh_first; dv != NULL; dv = dv->dv_list.tqe_next)
|
||||
if (is_valid_disk(dv))
|
||||
i386_ndisks++;
|
||||
x86_ndisks++;
|
||||
|
||||
if (i386_ndisks == 0)
|
||||
if (x86_ndisks == 0)
|
||||
return;
|
||||
|
||||
dklist_size = sizeof (struct disklist) + (i386_ndisks - 1) *
|
||||
dklist_size = sizeof (struct disklist) + (x86_ndisks - 1) *
|
||||
sizeof (struct nativedisk_info);
|
||||
|
||||
/* XXX M_TEMP is wrong */
|
||||
i386_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT);
|
||||
if (i386_alldisks == NULL)
|
||||
x86_alldisks = malloc(dklist_size, M_TEMP, M_NOWAIT);
|
||||
if (x86_alldisks == NULL)
|
||||
return;
|
||||
|
||||
memset(i386_alldisks, 0, dklist_size);
|
||||
memset(x86_alldisks, 0, dklist_size);
|
||||
|
||||
i386_alldisks->dl_nnativedisks = i386_ndisks;
|
||||
i386_alldisks->dl_nbiosdisks = big->num;
|
||||
x86_alldisks->dl_nnativedisks = x86_ndisks;
|
||||
x86_alldisks->dl_nbiosdisks = big->num;
|
||||
for (i = 0; i < big->num; i++) {
|
||||
i386_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
|
||||
i386_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
|
||||
i386_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
|
||||
i386_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
|
||||
i386_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
|
||||
i386_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
|
||||
x86_alldisks->dl_biosdisks[i].bi_dev = big->disk[i].dev;
|
||||
x86_alldisks->dl_biosdisks[i].bi_sec = big->disk[i].sec;
|
||||
x86_alldisks->dl_biosdisks[i].bi_head = big->disk[i].head;
|
||||
x86_alldisks->dl_biosdisks[i].bi_cyl = big->disk[i].cyl;
|
||||
x86_alldisks->dl_biosdisks[i].bi_lbasecs = big->disk[i].totsec;
|
||||
x86_alldisks->dl_biosdisks[i].bi_flags = big->disk[i].flags;
|
||||
#ifdef GEOM_DEBUG
|
||||
#ifdef NOTYET
|
||||
printf("disk %x: flags %x, interface %x, device %llx\n",
|
||||
@ -256,7 +256,7 @@ matchbiosdisks(void)
|
||||
#endif
|
||||
if (is_valid_disk(dv)) {
|
||||
n++;
|
||||
sprintf(i386_alldisks->dl_nativedisks[n].ni_devname,
|
||||
sprintf(x86_alldisks->dl_nativedisks[n].ni_devname,
|
||||
"%s%d", dv->dv_cfdata->cf_name,
|
||||
dv->dv_unit);
|
||||
|
||||
@ -302,11 +302,11 @@ matchbiosdisks(void)
|
||||
printf("matched bios disk %x with %s\n",
|
||||
be->dev, dv->dv_xname);
|
||||
#endif
|
||||
i386_alldisks->dl_nativedisks[n].
|
||||
x86_alldisks->dl_nativedisks[n].
|
||||
ni_biosmatches[m++] = i;
|
||||
}
|
||||
}
|
||||
i386_alldisks->dl_nativedisks[n].ni_nmatches = m;
|
||||
x86_alldisks->dl_nativedisks[n].ni_nmatches = m;
|
||||
vput(tv);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: machdep.c,v 1.8 2004/05/07 13:48:32 cl Exp $ */
|
||||
/* $NetBSD: machdep.c,v 1.9 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
/* NetBSD: machdep.c,v 1.552 2004/03/24 15:34:49 atatat Exp */
|
||||
|
||||
/*-
|
||||
@ -73,7 +73,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.8 2004/05/07 13:48:32 cl Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.9 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#include "opt_beep.h"
|
||||
#include "opt_compat_ibcs2.h"
|
||||
@ -233,8 +233,8 @@ char machine_arch[] = "i386"; /* machine == machine_arch */
|
||||
|
||||
char bootinfo[BOOTINFO_MAXSIZE];
|
||||
|
||||
struct bi_devmatch *i386_alldisks = NULL;
|
||||
int i386_ndisks = 0;
|
||||
extern struct bi_devmatch *x86_alldisks;
|
||||
extern int x86_ndisks;
|
||||
|
||||
#ifdef CPURESET_DELAY
|
||||
int cpureset_delay = CPURESET_DELAY;
|
||||
@ -544,9 +544,9 @@ sysctl_machdep_diskinfo(SYSCTLFN_ARGS)
|
||||
struct sysctlnode node;
|
||||
|
||||
node = *rnode;
|
||||
node.sysctl_data = i386_alldisks;
|
||||
node.sysctl_data = x86_alldisks;
|
||||
node.sysctl_size = sizeof(struct disklist) +
|
||||
(i386_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
(x86_ndisks - 1) * sizeof(struct nativedisk_info);
|
||||
return (sysctl_lookup(SYSCTLFN_CALL(&node)));
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: linux_machdep.c,v 1.102 2004/01/28 10:48:55 yamt Exp $ */
|
||||
/* $NetBSD: linux_machdep.c,v 1.103 2004/10/20 04:20:05 thorpej Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1995, 2000 The NetBSD Foundation, Inc.
|
||||
@ -37,7 +37,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.102 2004/01/28 10:48:55 yamt Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: linux_machdep.c,v 1.103 2004/10/20 04:20:05 thorpej Exp $");
|
||||
|
||||
#if defined(_KERNEL_OPT)
|
||||
#include "opt_vm86.h"
|
||||
@ -120,7 +120,7 @@ int linux_write_ldt __P((struct lwp *, struct linux_sys_modify_ldt_args *,
|
||||
#endif
|
||||
|
||||
static struct biosdisk_info *fd2biosinfo __P((struct proc *, struct file *));
|
||||
extern struct disklist *i386_alldisks;
|
||||
extern struct disklist *x86_alldisks;
|
||||
static void linux_save_ucontext __P((struct lwp *, struct trapframe *,
|
||||
const sigset_t *, struct sigaltstack *, struct linux_ucontext *));
|
||||
static void linux_save_sigcontext __P((struct lwp *, struct trapframe *,
|
||||
@ -841,7 +841,7 @@ fd2biosinfo(p, fp)
|
||||
char diskname[16];
|
||||
int i;
|
||||
struct nativedisk_info *nip;
|
||||
struct disklist *dl = i386_alldisks;
|
||||
struct disklist *dl = x86_alldisks;
|
||||
|
||||
if (fp->f_type != DTYPE_VNODE)
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user