- Make better use of the global chosen, memory and mmu handles instead

of obtaining them over and over again and pretending we could do
  anything useful without them (for chosen this includes adding a
  declaration and initializing it in OF_init()).
- In OF_init() if obtaining the memory or mmu handle fails just call
  OF_exit() instead of panic() as the loader hasn't initialized the
  console at these early stages yet and trying to print out something
  causes a hang. With OF_exit() one at least has a change to get back
  to the OFW boot monitor and debug the problem.
- Fix OF_call_method() on 64-bit machines (this is a merge of
  sys/dev/ofw/openfirm.c rev 1.6).
- Replace OF_alloc_phys(), OF_claim_virt(), OF_map_phys() and
  OF_release_phys() in the MI part of the loader with wrappers around
  OF_call_method() in the sparc64. Beside the fact that they duplicate
  OF_call_method() the formers should never have been in the MI part
  of the loader as contrary to the OFW spec they use two-cell physical
  addresses.
- Remove unused functions which are also MD dupes of OF_call_method().
- In sys/boot/sparc64/loader/main.c add __func__ to panic strings as
  different functions use otherwise identical panic strings and make
  some of the panic strings a tad more user-friendly instead of just
  mentioning the name of the function that returned an unexpected
  result.
This commit is contained in:
Marius Strobl 2007-06-17 00:17:15 +00:00
parent 4d69a9d061
commit aa785996fd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=170854
8 changed files with 96 additions and 333 deletions

View File

@ -41,7 +41,6 @@ extern char bootprog_rev[];
extern char bootprog_date[];
extern char bootprog_maker[];
phandle_t chosen;
u_int32_t acells;
static char bootargs[128];
@ -64,24 +63,22 @@ init_heap(void)
uint64_t
memsize(void)
{
ihandle_t meminstance;
phandle_t memory;
phandle_t memoryp;
struct ofw_reg reg[4];
struct ofw_reg2 reg2[8];
int i;
u_int64_t sz, memsz;
OF_getprop(chosen, "memory", &meminstance, sizeof(meminstance));
memory = OF_instance_to_package(meminstance);
memoryp = OF_instance_to_package(memory);
if (acells == 1) {
sz = OF_getprop(memory, "reg", &reg, sizeof(reg));
sz = OF_getprop(memoryp, "reg", &reg, sizeof(reg));
sz /= sizeof(struct ofw_reg);
for (i = 0, memsz = 0; i < sz; i++)
memsz += reg[i].size;
} else if (acells == 2) {
sz = OF_getprop(memory, "reg", &reg2, sizeof(reg2));
sz = OF_getprop(memoryp, "reg", &reg2, sizeof(reg2));
sz /= sizeof(struct ofw_reg2);
for (i = 0, memsz = 0; i < sz; i++)
@ -107,7 +104,6 @@ main(int (*openfirm)(void *))
OF_init(openfirm);
root = OF_finddevice("/");
chosen = OF_finddevice("/chosen");
acells = 1;
OF_getprop(root, "#address-cells", &acells, sizeof(acells));

View File

@ -5,7 +5,7 @@ INTERNALLIB=
SRCS= devicename.c elf_freebsd.c ofw_console.c ofw_copy.c ofw_disk.c \
ofw_memory.c ofw_module.c ofw_net.c ofw_reboot.c \
ofw_time.c openfirm.c openfirm_mmu.c
ofw_time.c openfirm.c
CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/

View File

@ -34,8 +34,6 @@ __FBSDID("$FreeBSD$");
#include "bootstrap.h"
#include "openfirm.h"
int console;
static void ofw_cons_probe(struct console *cp);
static int ofw_cons_init(int);
void ofw_cons_putchar(int);
@ -59,10 +57,7 @@ struct console ofwconsole = {
static void
ofw_cons_probe(struct console *cp)
{
phandle_t chosen;
if ((chosen = OF_finddevice("/chosen")) == -1)
OF_exit();
OF_getprop(chosen, "stdin", &stdin, sizeof(stdin));
OF_getprop(chosen, "stdout", &stdout, sizeof(stdout));
cp->c_flags |= C_PRESENTIN|C_PRESENTOUT;

View File

@ -179,12 +179,11 @@ extern char *strchr();
static void
ofwn_init(struct iodesc *desc, void *machdep_hint)
{
phandle_t chosen, netdev;
phandle_t netdev;
char path[64];
char *ch;
int pathlen;
chosen = OF_finddevice("/chosen");
pathlen = OF_getprop(chosen, "bootpath", path, 64);
if ((ch = index(path, ':')) != NULL)
*ch = '\0';

View File

@ -66,6 +66,7 @@ __FBSDID("$FreeBSD$");
int (*openfirmware)(void *);
phandle_t chosen;
ihandle_t mmu;
ihandle_t memory;
@ -74,30 +75,15 @@ ihandle_t memory;
void
OF_init(int (*openfirm)(void *))
{
phandle_t chosen;
openfirmware = openfirm;
chosen = OF_finddevice("/chosen");
OF_getprop(chosen, "memory", &memory, sizeof(memory));
if (memory == 0)
panic("failed to get memory ihandle");
OF_getprop(chosen, "mmu", &mmu, sizeof(mmu));
if (mmu == 0)
panic("failed to get mmu ihandle");
}
phandle_t
OF_chosennode(void)
{
static phandle_t chosen;
if (chosen)
return (chosen);
if ((chosen = OF_finddevice("/chosen")) == -1)
OF_exit();
return (chosen);
if (OF_getprop(chosen, "memory", &memory, sizeof(memory)) == -1)
OF_exit();
if (OF_getprop(chosen, "mmu", &mmu, sizeof(mmu)) == -1)
OF_exit();
}
/*
@ -461,7 +447,8 @@ OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...)
2,
1,
};
int *ip, n;
cell_t *cp;
int n;
if (nargs > 6)
return (-1);
@ -470,15 +457,15 @@ OF_call_method(char *method, ihandle_t instance, int nargs, int nreturns, ...)
args.method = (cell_t)method;
args.instance = instance;
va_start(ap, nreturns);
for (ip = (int *)(args.args_n_results + (n = nargs)); --n >= 0;)
*--ip = va_arg(ap, int);
for (cp = (cell_t *)(args.args_n_results + (n = nargs)); --n >= 0;)
*--cp = va_arg(ap, cell_t);
if (openfirmware(&args) == -1)
return (-1);
if (args.args_n_results[nargs])
return (args.args_n_results[nargs]);
for (ip = (int *)(args.args_n_results + nargs + (n = args.nreturns));
for (cp = (cell_t *)(args.args_n_results + nargs + (n = args.nreturns));
--n > 0;)
*va_arg(ap, int *) = *--ip;
*va_arg(ap, cell_t *) = *--cp;
va_end(ap);
return (0);
}
@ -648,67 +635,6 @@ OF_claim(void *virt, u_int size, u_int align)
return ((void *)args.baseaddr);
}
/* Allocate an area of physical memory */
vm_offset_t
OF_claim_virt(vm_offset_t virt, size_t size, int align)
{
static struct {
cell_t name;
cell_t nargs;
cell_t nret;
cell_t method;
cell_t ihandle;
cell_t align;
cell_t size;
cell_t virt;
cell_t status;
cell_t ret;
} args = {
(cell_t)"call-method",
5,
2,
(cell_t)"claim",
};
args.ihandle = mmu;
args.align = align;
args.size = size;
args.virt = (cell_t)virt;
if (openfirmware(&args) == -1)
return (-1);
return (args.ret);
}
/* Allocate an area of physical memory */
void *
OF_alloc_phys(size_t size, int align)
{
static struct {
cell_t name;
cell_t nargs;
cell_t nret;
cell_t method;
cell_t ihandle;
cell_t align;
cell_t size;
cell_t status;
cell_t phys_hi;
cell_t phys_low;
} args = {
(cell_t)"call-method",
4,
3,
(cell_t)"claim",
};
args.ihandle = memory;
args.size = size;
args.align = align;
if (openfirmware(&args) == -1)
return ((void *)-1);
return ((void *)(args.phys_hi << 32 | args.phys_low));
}
/* Release an area of memory. */
void
OF_release(void *virt, u_int size)
@ -729,33 +655,6 @@ OF_release(void *virt, u_int size)
openfirmware(&args);
}
/* Release an area of physical memory. */
void
OF_release_phys(vm_offset_t phys, u_int size)
{
static struct {
cell_t name;
cell_t nargs;
cell_t nret;
cell_t method;
cell_t ihandle;
cell_t size;
cell_t phys_hi;
cell_t phys_lo;
} args = {
(cell_t)"call-method",
5,
0,
(cell_t)"release",
};
args.ihandle = memory;
args.phys_hi = phys >> 32;
args.phys_lo = phys;
args.size = size;
openfirmware(&args);
}
/*
* Control transfer functions
*/

View File

@ -106,10 +106,7 @@ int OF_seek(ihandle_t, u_quad_t);
/* Memory functions */
void *OF_claim(void *, u_int, u_int);
vm_offset_t OF_claim_virt(vm_offset_t, size_t, int);
void *OF_alloc_phys(size_t, int);
void OF_release(void *, u_int);
void OF_release_phys(vm_offset_t, u_int);
/* Control transfer functions */
void OF_boot(char *);
@ -117,13 +114,7 @@ void OF_enter(void);
void OF_exit(void) __attribute__((noreturn));
void OF_chain(void *, u_int, void (*)(), void *, u_int);
#if 0
/* User interface functions */
/* OF_interpret */
void *OF_set_callback(void *);
void OF_set_symbol_lookup(void *, void *);
#endif
/* Time function */
int OF_milliseconds(void);
#endif /* _OPENFIRM_H_ */

View File

@ -1,143 +0,0 @@
/*
* Copyright (c) 2006 Kip Macy
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 TOOLS GMBH 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.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <stand.h>
#include "openfirm.h"
static ihandle_t
OF_mmu_ihandle(void)
{
static ihandle_t immu;
if (immu != (ihandle_t)0)
return (immu);
if (OF_getproplen(OF_chosennode(), "mmu") != sizeof (ihandle_t))
return (immu = (ihandle_t)-1);
(void) OF_getprop(OF_chosennode(), "mmu", (caddr_t)(&immu), sizeof immu);
return (immu);
}
int
OF_translate_virt(vm_offset_t va, int *valid, vm_paddr_t *physaddr, int *mode)
{
int rv;
static struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
cell_t method;
cell_t immu;
cell_t va;
cell_t result;
cell_t valid;
cell_t mode;
cell_t phys_hi;
cell_t phys_lo;
} args = {
(cell_t)"call-method",
3,
5,
(cell_t)"translate",
};
args.immu = (cell_t) OF_mmu_ihandle();
args.result = 0;
args.valid = 0;
args.mode = 0;
rv = openfirmware(&args);
if (rv == -1)
return (-1);
if (args.result != 0)
return (-1);
*valid = args.valid;
*mode = args.mode;
*physaddr = (vm_paddr_t)(args.phys_hi << 32 | args.phys_lo);
return (0);
}
vm_paddr_t
OF_vtophys(vm_offset_t va)
{
int mode, valid, error;
vm_paddr_t physaddr;
error = OF_translate_virt(va, &valid, &physaddr, &mode);
if (error == 0 && valid == -1)
return physaddr;
return (0);
}
int
OF_map_phys(int mode, size_t size, vm_offset_t va, uint64_t pa)
{
int rv;
static struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
cell_t method;
cell_t immu;
cell_t mode;
cell_t size;
cell_t va;
cell_t pa_hi;
cell_t pa_lo;
cell_t result;
} args = {
(cell_t)"call-method",
7,
1,
(cell_t)"map",
};
args.immu = (cell_t)OF_mmu_ihandle();
args.mode = (cell_t)mode;
args.size = (cell_t)size;
args.va = (cell_t)va;
args.pa_hi = (cell_t)(pa >> 32);
args.pa_lo = (cell_t)((uint32_t)pa);
rv = openfirmware(&args);
if (rv == -1)
return (-1);
if (args.result != 0)
return (-1);
return (0);
}

View File

@ -65,6 +65,10 @@ static int sparc64_autoload(void);
static ssize_t sparc64_readin(const int, vm_offset_t, const size_t);
static ssize_t sparc64_copyin(const void *, vm_offset_t, size_t);
static void sparc64_maphint(vm_offset_t, size_t);
static vm_offset_t claim_virt(vm_offset_t, size_t, int);
static vm_offset_t alloc_phys(size_t, int);
static int map_phys(int, size_t, vm_offset_t, vm_offset_t);
static void release_phys(vm_offset_t, u_int);
static int __elfN(exec)(struct preloaded_file *);
static int mmu_mapin_sun4u(vm_offset_t, vm_size_t);
static int mmu_mapin_sun4v(vm_offset_t, vm_size_t);
@ -96,7 +100,7 @@ static int is_sun4v = 0;
static vm_offset_t curkva = 0;
static vm_offset_t heapva;
phandle_t pmemh; /* OFW memory handle */
static phandle_t root;
/*
* Machine dependent structures that the machine independent
@ -245,7 +249,7 @@ sparc64_maphint(vm_offset_t va, size_t len)
vm_paddr_t pa;
vm_offset_t mva;
size_t size;
int i, ret, free_excess = 0;
int i, free_excess = 0;
if (!is_sun4v)
return;
@ -256,36 +260,73 @@ sparc64_maphint(vm_offset_t va, size_t len)
/* round up to nearest 4MB page */
size = (len + PAGE_MASK_4M) & ~PAGE_MASK_4M;
#if 0
pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_256M, PAGE_SIZE_256M);
pa = alloc_phys(PAGE_SIZE_256M, PAGE_SIZE_256M);
if (pa != -1)
free_excess = 1;
else
#endif
pa = (vm_offset_t)OF_alloc_phys(size, PAGE_SIZE_256M);
pa = alloc_phys(size, PAGE_SIZE_256M);
if (pa == -1)
pa = (vm_offset_t)OF_alloc_phys(size, PAGE_SIZE_4M);
pa = alloc_phys(size, PAGE_SIZE_4M);
if (pa == -1)
panic("out of memory");
panic("%s: out of memory", __func__);
for (i = 0; i < size; i += PAGE_SIZE_4M) {
mva = (vm_offset_t)OF_claim_virt(va + i, PAGE_SIZE_4M, 0);
mva = claim_virt(va + i, PAGE_SIZE_4M, 0);
if (mva != (va + i))
panic("can't claim virtual page "
panic("%s: can't claim virtual page "
"(wanted %#lx, got %#lx)",
va, mva);
__func__, va, mva);
tlb_store[mva >> 22].te_pa = pa + i;
if ((ret = OF_map_phys(-1, PAGE_SIZE_4M, mva, pa + i)) != 0)
printf("OF_map_phys failed: %d\n", ret);
if (map_phys(-1, PAGE_SIZE_4M, mva, pa + i) != 0)
printf("%s: can't map physical page\n", __func__);
}
if (free_excess)
OF_release_phys((vm_offset_t)pa, PAGE_SIZE_256M);
release_phys(pa, PAGE_SIZE_256M);
}
/*
* other MD functions
*/
static vm_offset_t
claim_virt(vm_offset_t virt, size_t size, int align)
{
vm_offset_t mva;
if (OF_call_method("claim", mmu, 3, 1, virt, size, align, &mva) == -1)
return ((vm_offset_t)-1);
return (mva);
}
static vm_offset_t
alloc_phys(size_t size, int align)
{
cell_t phys_hi, phys_low;
if (OF_call_method("claim", memory, 2, 2, size, align, &phys_low,
&phys_hi) == -1)
return ((vm_offset_t)-1);
return ((vm_offset_t)phys_hi << 32 | phys_low);
}
static int
map_phys(int mode, size_t size, vm_offset_t virt, vm_offset_t phys)
{
return (OF_call_method("map", mmu, 5, 0, (uint32_t)phys,
(uint32_t)(phys >> 32), virt, size, mode));
}
static void
release_phys(vm_offset_t phys, u_int size)
{
(void)OF_call_method("release", memory, 3, 0, (uint32_t)phys,
(uint32_t)(phys >> 32), size);
}
static int
__elfN(exec)(struct preloaded_file *fp)
{
@ -314,7 +355,7 @@ __elfN(exec)(struct preloaded_file *fp)
((kernel_entry_t *)entry)(mdp, 0, 0, 0, openfirmware);
panic("exec returned");
panic("%s: exec returned", __func__);
}
static int
@ -334,16 +375,14 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len)
itlb_va_to_pa(va) == (vm_offset_t)-1) {
/* Allocate a physical page, claim the virtual area */
if (pa == (vm_offset_t)-1) {
pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_4M,
PAGE_SIZE_4M);
pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M);
if (pa == (vm_offset_t)-1)
panic("out of memory");
mva = (vm_offset_t)OF_claim_virt(va,
PAGE_SIZE_4M, 0);
panic("%s: out of memory", __func__);
mva = claim_virt(va, PAGE_SIZE_4M, 0);
if (mva != va)
panic("can't claim virtual page "
panic("%s: can't claim virtual page "
"(wanted %#lx, got %#lx)",
va, mva);
__func__, va, mva);
/* The mappings may have changed, be paranoid. */
continue;
}
@ -371,7 +410,7 @@ mmu_mapin_sun4u(vm_offset_t va, vm_size_t len)
va += PAGE_SIZE_4M;
}
if (pa != (vm_offset_t)-1)
OF_release_phys(pa, PAGE_SIZE_4M);
release_phys(pa, PAGE_SIZE_4M);
return (0);
}
@ -379,8 +418,6 @@ static int
mmu_mapin_sun4v(vm_offset_t va, vm_size_t len)
{
vm_offset_t pa, mva;
u_long data;
int ret;
if (va + len > curkva)
curkva = va + len;
@ -390,43 +427,37 @@ mmu_mapin_sun4v(vm_offset_t va, vm_size_t len)
va &= ~PAGE_MASK_4M;
while (len) {
if ((va >> 22) > SUN4V_TLB_SLOT_MAX)
panic("trying to map more than 4GB");
panic("%s: trying to map more than 4GB", __func__);
if (tlb_store[va >> 22].te_pa == -1) {
/* Allocate a physical page, claim the virtual area */
if (pa == (vm_offset_t)-1) {
pa = (vm_offset_t)OF_alloc_phys(PAGE_SIZE_4M,
PAGE_SIZE_4M);
pa = alloc_phys(PAGE_SIZE_4M, PAGE_SIZE_4M);
if (pa == (vm_offset_t)-1)
panic("out of memory");
mva = (vm_offset_t)OF_claim_virt(va,
PAGE_SIZE_4M, 0);
panic("%s: out of memory", __func__);
mva = claim_virt(va, PAGE_SIZE_4M, 0);
if (mva != va)
panic("can't claim virtual page "
panic("%s: can't claim virtual page "
"(wanted %#lx, got %#lx)",
va, mva);
__func__, va, mva);
}
tlb_store[va >> 22].te_pa = pa;
if ((ret = OF_map_phys(-1, PAGE_SIZE_4M, va, pa)) != 0)
printf("OF_map_phys failed: %d\n", ret);
if (map_phys(-1, PAGE_SIZE_4M, va, pa) == -1)
printf("%s: can't map physical page\n",
__func__);
pa = (vm_offset_t)-1;
}
len -= len > PAGE_SIZE_4M ? PAGE_SIZE_4M : len;
va += PAGE_SIZE_4M;
}
if (pa != (vm_offset_t)-1)
OF_release_phys(pa, PAGE_SIZE_4M);
release_phys(pa, PAGE_SIZE_4M);
return (0);
}
static vm_offset_t
init_heap(void)
{
if ((pmemh = OF_finddevice("/memory")) == (phandle_t)-1)
OF_exit();
if (OF_getprop(pmemh, "available", memslices, sizeof(memslices)) <= 0)
OF_exit();
/* There is no need for continuous physical heap memory. */
heapva = (vm_offset_t)OF_claim((void *)HEAPVA, HEAPSZ, 32);
@ -437,23 +468,20 @@ static void
tlb_init_sun4u(void)
{
phandle_t child;
phandle_t root;
char buf[128];
u_int bootcpu;
u_int cpu;
bootcpu = UPA_CR_GET_MID(ldxa(0, ASI_UPA_CONFIG_REG));
if ((root = OF_peer(0)) == -1)
panic("%s: OF_peer", __func__);
for (child = OF_child(root); child != 0; child = OF_peer(child)) {
if (child == -1)
panic("%s: OF_child", __func__);
panic("%s: can't get child phandle", __func__);
if (OF_getprop(child, "device_type", buf, sizeof(buf)) > 0 &&
strcmp(buf, "cpu") == 0) {
if (OF_getprop(child, "upa-portid", &cpu,
sizeof(cpu)) == -1 && OF_getprop(child, "portid",
&cpu, sizeof(cpu)) == -1)
panic("%s: OF_getprop", __func__);
panic("%s: can't get portid", __func__);
if (cpu == bootcpu)
break;
}
@ -464,11 +492,11 @@ tlb_init_sun4u(void)
sizeof(dtlb_slot_max)) == -1 ||
OF_getprop(child, "#itlb-entries", &itlb_slot_max,
sizeof(itlb_slot_max)) == -1)
panic("%s: OF_getprop", __func__);
panic("%s: can't get TLB slot max.", __func__);
dtlb_store = malloc(dtlb_slot_max * sizeof(*dtlb_store));
itlb_store = malloc(itlb_slot_max * sizeof(*itlb_store));
if (dtlb_store == NULL || itlb_store == NULL)
panic("%s: malloc", __func__);
panic("%s: can't allocate TLB store", __func__);
}
static void
@ -485,8 +513,6 @@ main(int (*openfirm)(void *))
char bootpath[64];
char compatible[32];
struct devsw **dp;
phandle_t rooth;
phandle_t chosenh;
/*
* Tell the Open Firmware functions where they find the ofw gate.
@ -508,8 +534,9 @@ main(int (*openfirm)(void *))
*/
cons_probe();
rooth = OF_peer(0);
OF_getprop(rooth, "compatible", compatible, sizeof(compatible));
if ((root = OF_peer(0)) == -1)
panic("%s: can't get root phandle", __func__);
OF_getprop(root, "compatible", compatible, sizeof(compatible));
if (!strcmp(compatible, "sun4v")) {
printf("\nBooting with sun4v support.\n");
mmu_ops = &mmu_ops_sun4v;
@ -532,8 +559,7 @@ main(int (*openfirm)(void *))
/*
* Set up the current device.
*/
chosenh = OF_finddevice("/chosen");
OF_getprop(chosenh, "bootpath", bootpath, sizeof(bootpath));
OF_getprop(chosen, "bootpath", bootpath, sizeof(bootpath));
/*
* Sun compatible bootable CD-ROMs have a disk label placed