diff options
| author | setje <none@none> | 2007-12-07 16:04:33 -0800 |
|---|---|---|
| committer | setje <none@none> | 2007-12-07 16:04:33 -0800 |
| commit | 986fd29a0dc13f7608ef7f508f6e700bd7bc2720 (patch) | |
| tree | 8612567367832542a32a2c8bbf3b9b7ef7639ab7 /usr/src/psm | |
| parent | f3b585ce799a83688c5532c430f6133f098431c2 (diff) | |
| download | illumos-joyent-986fd29a0dc13f7608ef7f508f6e700bd7bc2720.tar.gz | |
6521412 PSARC 2006/525: new boot sparc
6451467 bootadm update-archive does the wrong thing if interrupted
6477079 ability to pick up post bfu binaries from bfu PATH conflicts with sane scripting
--HG--
rename : usr/src/psm/stand/boot/sparc/common/boot.c => deleted_files/usr/src/psm/stand/boot/sparc/common/boot.c
rename : usr/src/psm/stand/boot/sparc/common/boot_services.c => deleted_files/usr/src/psm/stand/boot/sparc/common/boot_services.c
rename : usr/src/psm/stand/boot/sparc/common/hsfsconf.c => deleted_files/usr/src/psm/stand/boot/sparc/common/hsfsconf.c
rename : usr/src/psm/stand/boot/sparc/common/ufsconf.c => deleted_files/usr/src/psm/stand/boot/sparc/common/ufsconf.c
rename : usr/src/psm/stand/bootblks/Makefile.obp => deleted_files/usr/src/psm/stand/bootblks/Makefile.obp
rename : usr/src/psm/stand/bootblks/hsfs/common/Makefile.com => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com
rename : usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth
rename : usr/src/psm/stand/bootblks/hsfs/common/hsfs.c => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c
rename : usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h
rename : usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c
rename : usr/src/psm/stand/bootblks/hsfs/common/iob.h => deleted_files/usr/src/psm/stand/bootblks/hsfs/common/iob.h
rename : usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile => deleted_files/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile
rename : usr/src/psm/stand/bootblks/obp-c/Makefile.rules => deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.rules
rename : usr/src/psm/stand/bootblks/obp-c/Makefile.targ => deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.targ
rename : usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h
rename : usr/src/psm/stand/bootblks/obp-c/common/makevers.sh => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh
rename : usr/src/psm/stand/bootblks/obp-c/common/mkboot.c => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c
rename : usr/src/psm/stand/bootblks/obp-c/common/romp.h => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/romp.h
rename : usr/src/psm/stand/bootblks/obp-c/common/stub.c => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/stub.c
rename : usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c => deleted_files/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c
rename : usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile => deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile
rename : usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s => deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s
rename : usr/src/psm/stand/bootblks/ufs/common/Makefile.com => deleted_files/usr/src/psm/stand/bootblks/ufs/common/Makefile.com
rename : usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth => deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth
rename : usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth => deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth
rename : usr/src/psm/stand/bootblks/ufs/common/iob.h => deleted_files/usr/src/psm/stand/bootblks/ufs/common/iob.h
rename : usr/src/psm/stand/bootblks/ufs/common/ufs.c => deleted_files/usr/src/psm/stand/bootblks/ufs/common/ufs.c
rename : usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile => deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile
rename : usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile => deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile
rename : usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile => deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile
rename : usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile => deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile
rename : usr/src/uts/sparc/krtld/Makefile => deleted_files/usr/src/uts/sparc/krtld/Makefile
rename : usr/src/uts/sparc/krtld/kobj_alloc.c => deleted_files/usr/src/uts/sparc/krtld/kobj_alloc.c
rename : usr/src/uts/sparc/krtld/kobj_boot.c => deleted_files/usr/src/uts/sparc/krtld/kobj_boot.c
rename : usr/src/uts/sparc/krtld/kobj_crt.s => deleted_files/usr/src/uts/sparc/krtld/kobj_crt.s
rename : usr/src/cmd/boot/bootadm/filelist.ramdisk => usr/src/cmd/boot/filelist/i386/filelist.ramdisk
rename : usr/src/cmd/boot/bootadm/filelist.safe => usr/src/cmd/boot/filelist/i386/filelist.safe
Diffstat (limited to 'usr/src/psm')
83 files changed, 5269 insertions, 7388 deletions
diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_fio.c b/usr/src/psm/promif/ieee1275/sun4/prom_fio.c new file mode 100644 index 0000000000..3909b21170 --- /dev/null +++ b/usr/src/psm/promif/ieee1275/sun4/prom_fio.c @@ -0,0 +1,219 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/promif.h> +#include <sys/promimpl.h> + +int +prom_fopen(ihandle_t fsih, char *path) +{ + cell_t ci[10]; + size_t len; + +#ifdef PROM_32BIT_ADDRS + char *opath = NULL; + + if ((uintptr_t)path > (uint32_t)-1) { + opath = path; + len = prom_strlen(opath) + 1; /* include terminating NUL */ + path = promplat_alloc(len); + if (path == NULL) + return (0); + (void) prom_strcpy(path, opath); + } +#endif + len = prom_strlen(path); + + promif_preprom(); + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)3; /* #result cells */ + ci[3] = p1275_ptr2cell("open-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_uint2cell(len); /* Arg3: Len */ + ci[6] = p1275_ptr2cell(path); /* Arg4: Pathname */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (opath != NULL) + promplat_free(path, len + 1); +#endif + + if (ci[7] != 0) /* Catch result */ + return (-1); + + if (ci[8] == 0) /* Res1: failed */ + return (-1); + + return (p1275_cell2int(ci[9])); /* Res2: fd */ +} + + +int +prom_fseek(ihandle_t fsih, int fd, unsigned long long offset) +{ + cell_t ci[10]; + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)4; /* #argument cells */ + ci[2] = (cell_t)3; /* #result cells */ + ci[3] = p1275_ptr2cell("seek-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_int2cell(fd); /* Arg3: file desc */ + ci[6] = p1275_ull2cell_low(offset); /* Arg4: Offset */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + + if (ci[7] != 0) /* Catch result */ + return (-1); + + if (ci[8] == 0) /* Res1: failed */ + return (-1); + + return (p1275_cell2int(ci[9])); /* Res2: off */ +} + + +int +prom_fread(ihandle_t fsih, int fd, caddr_t buf, size_t len) +{ + cell_t ci[10]; +#ifdef PROM_32BIT_ADDRS + caddr_t obuf = NULL; + + if ((uintptr_t)buf > (uint32_t)-1) { + obuf = buf; + buf = promplat_alloc(len); + if (buf == NULL) + return (-1); + } +#endif + + promif_preprom(); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)5; /* #argument cells */ + ci[2] = (cell_t)2; /* #result cells */ + ci[3] = p1275_ptr2cell("read-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_int2cell(fd); /* Arg3: file desc */ + ci[6] = p1275_uint2cell(len); /* Arg4: buffer length */ + ci[7] = p1275_ptr2cell(buf); /* Arg5: buffer address */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + +#ifdef PROM_32BIT_ADDRS + if (obuf != NULL) { + promplat_bcopy(buf, obuf, len); + promplat_free(buf, len); + } +#endif + + if (ci[8] != 0) /* Catch result */ + return (-1); + + return (p1275_cell2int(ci[9])); /* Res2: actual length */ +} + +int +prom_fsize(ihandle_t fsih, int fd, size_t *size) +{ + cell_t ci[8]; + + promif_preprom(); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)2; /* #result cells */ + ci[3] = p1275_ptr2cell("size-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_int2cell(fd); /* Arg3: file desc */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + + if (ci[6] != 0) /* Catch result */ + return (-1); + + *size = p1275_cell2uint(ci[7]); /* Res2: size */ + return (0); +} + + +int +prom_compinfo(ihandle_t fsih, int fd, int *iscmp, size_t *fsize, size_t *bsize) +{ + cell_t ci[10]; + + promif_preprom(); + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)4; /* #result cells */ + ci[3] = p1275_ptr2cell("cinfo-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_int2cell(fd); /* Arg3: file desc */ + + (void) p1275_cif_handler(&ci); + + promif_postprom(); + + if (ci[6] != 0) /* Catch result */ + return (-1); + + *iscmp = p1275_cell2int(ci[7]); /* Res2: iscmp */ + *fsize = p1275_cell2uint(ci[8]); /* Res3: fsize */ + *bsize = p1275_cell2uint(ci[9]); /* Res4: bsize */ + return (0); +} + +void +prom_fclose(ihandle_t fsih, int fd) +{ + cell_t ci[7]; + + ci[0] = p1275_ptr2cell("call-method"); /* Service name */ + ci[1] = (cell_t)3; /* #argument cells */ + ci[2] = (cell_t)1; /* #result cells */ + ci[3] = p1275_ptr2cell("close-file"); /* Arg1: Method name */ + ci[4] = p1275_ihandle2cell(fsih); /* Arg2: fs ihandle */ + ci[5] = p1275_int2cell(fd); /* Arg3: file desc */ + + promif_preprom(); + (void) p1275_cif_handler(&ci); + promif_postprom(); + +} diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_init.c b/usr/src/psm/promif/ieee1275/sun4/prom_init.c index 66779087c9..8ca6d3742f 100644 --- a/usr/src/psm/promif/ieee1275/sun4/prom_init.c +++ b/usr/src/psm/promif/ieee1275/sun4/prom_init.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1994, 2001-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -107,12 +106,6 @@ prom_init(char *pgmname, void *p1275cookie) */ (void) prom_set_preprom(default_prepost_prom); (void) prom_set_postprom(default_prepost_prom); - - if (&plat_setprop_enter != NULL) { - prom_setprop_enter = &plat_setprop_enter; - prom_setprop_exit = &plat_setprop_exit; - ASSERT(prom_setprop_exit != NULL); - } } /* diff --git a/usr/src/psm/promif/ieee1275/sun4/prom_mem.c b/usr/src/psm/promif/ieee1275/sun4/prom_mem.c index 6983d1e09a..ada9a7fad2 100644 --- a/usr/src/psm/promif/ieee1275/sun4/prom_mem.c +++ b/usr/src/psm/promif/ieee1275/sun4/prom_mem.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1991-1994, by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -62,7 +61,7 @@ prom_memory_ihandle(void) * and a single size cell in the "memory" node. */ int -prom_allocate_phys(size_t size, u_int align, unsigned long long *physaddr) +prom_allocate_phys(size_t size, uint_t align, unsigned long long *physaddr) { cell_t ci[10]; int rv; @@ -72,7 +71,7 @@ prom_allocate_phys(size_t size, u_int align, unsigned long long *physaddr) return (-1); if (align == 0) - align = (u_int)1; + align = (uint_t)1; ci[0] = p1275_ptr2cell("call-method"); /* Service name */ ci[1] = (cell_t)4; /* #argument cells */ @@ -162,3 +161,43 @@ prom_free_phys(size_t size, unsigned long long physaddr) (void) p1275_cif_handler(&ci); promif_postprom(); } + +static pnode_t +prom_mem_phandle(void) +{ + static pnode_t pmem = 0; + + if (pmem == (pnode_t)0) { + ihandle_t ih; + + if ((ih = prom_memory_ihandle()) == (ihandle_t)-1) + prom_panic("Can't get memory ihandle"); + pmem = prom_getphandle(ih); + } + return (pmem); +} + + +int +prom_phys_installed_len(void) +{ + return (prom_getproplen(prom_mem_phandle(), "reg")); +} + +int +prom_phys_avail_len(void) +{ + return (prom_getproplen(prom_mem_phandle(), "available")); +} + +int +prom_phys_installed(caddr_t prop) +{ + return (prom_getprop(prom_mem_phandle(), "reg", prop)); +} + +int +prom_phys_avail(caddr_t prop) +{ + return (prom_getprop(prom_mem_phandle(), "available", prop)); +} diff --git a/usr/src/psm/promif/ieee1275/sun4u/Makefile.files b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files index 6808bc6499..40f83a581e 100644 --- a/usr/src/psm/promif/ieee1275/sun4u/Makefile.files +++ b/usr/src/psm/promif/ieee1275/sun4u/Makefile.files @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,15 +31,17 @@ # # -# Note that the kernel doesn't use/need prom_map.o and prom_alloc.o +# Note that the kernel doesn't use/need prom_map.o # # # PROM Platform-dependent routines # CORE_OBJS += \ + prom_alloc.o \ prom_cpuctl.o \ prom_efcode.o \ + prom_fio.o \ prom_getunum.o \ prom_heartbeat.o \ prom_idprom.o \ diff --git a/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c b/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c index c5556dc756..a9cfe6662e 100644 --- a/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c +++ b/usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1991-1994, by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -105,7 +104,7 @@ prom_unmap_phys(size_t size, caddr_t virt) * Allocate aligned or unaligned virtual address space, unmapped. */ caddr_t -prom_allocate_virt(u_int align, size_t size) +prom_allocate_virt(uint_t align, size_t size) { cell_t ci[9]; int rv; @@ -219,6 +218,34 @@ prom_unmap_virt(size_t size, caddr_t virt) promif_postprom(); } +static pnode_t +prom_mmu_phandle(void) +{ + static pnode_t pmmu = 0; + + if (pmmu == (pnode_t)0) { + ihandle_t ih; + + if ((ih = prom_mmu_ihandle()) == (ihandle_t)-1) + prom_panic("Can't get mmu ihandle"); + pmmu = prom_getphandle(ih); + } + return (pmmu); +} + + +int +prom_virt_avail_len(void) +{ + return (prom_getproplen(prom_mmu_phandle(), "available")); +} + +int +prom_virt_avail(caddr_t prop) +{ + return (prom_getprop(prom_mmu_phandle(), "available", prop)); +} + /* * Translate virtual address to physical address. * Returns 0: Success; Non-zero: failure. diff --git a/usr/src/psm/promif/ieee1275/sun4v/Makefile.files b/usr/src/psm/promif/ieee1275/sun4v/Makefile.files index 2914265a0c..0cb087efa2 100644 --- a/usr/src/psm/promif/ieee1275/sun4v/Makefile.files +++ b/usr/src/psm/promif/ieee1275/sun4v/Makefile.files @@ -19,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,15 +31,17 @@ # # -# Note that the kernel doesn't use/need prom_map.o and prom_alloc.o +# Note that the kernel doesn't use/need prom_map.o # # # PROM Platform-dependent routines # CORE_OBJS += \ + prom_alloc.o \ prom_cpuctl.o \ prom_efcode.o \ + prom_fio.o \ prom_getunum.o \ prom_idprom.o \ prom_heartbeat.o \ diff --git a/usr/src/psm/stand/boot/Makefile.boot b/usr/src/psm/stand/boot/Makefile.boot index b5d0f7c8ca..b57c66a046 100644 --- a/usr/src/psm/stand/boot/Makefile.boot +++ b/usr/src/psm/stand/boot/Makefile.boot @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -51,15 +50,9 @@ PSMPROMLIBDIR64 = $(PSMSTANDDIR)/lib/promif/$(MACH64) # XXX one day we should just be able to set PROG to 'cfsboot'.. # and everything will become a lot easier. # -# XXX note that we build but -don't- install the HSFS boot -# program - it's unused and untested, and until it is we -# shouldn't ship it! -# UNIBOOT = multiboot -UFSBOOT = ufsboot WANBOOT = wanboot NFSBOOT = inetboot -HSFSBOOT = hsfsboot # # Common install modes and owners @@ -73,10 +66,8 @@ GROUP = sys # Install locations # ROOT_PSM_UNIBOOT= $(ROOT_PSM_DIR)/$(UNIBOOT) -ROOT_PSM_UFSBOOT= $(ROOT_PSM_DIR)/$(UFSBOOT) ROOT_PSM_WANBOOT= $(ROOT_PSM_DIR)/$(WANBOOT) USR_PSM_NFSBOOT = $(USR_PSM_LIB_NFS_DIR)/$(NFSBOOT) -USR_PSM_HSFSBOOT= $(USR_PSM_LIB_HSFS_DIR)/$(HSFSBOOT) # # While things are pretty much 32-bit lint-clean, there are a ton of diff --git a/usr/src/psm/stand/boot/Makefile.targ b/usr/src/psm/stand/boot/Makefile.targ index 4d58601c91..fe366511e0 100644 --- a/usr/src/psm/stand/boot/Makefile.targ +++ b/usr/src/psm/stand/boot/Makefile.targ @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,15 +21,15 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/boot/Makefile.files # # Targets common to all versions # -install: all $(ROOT_PSM_UFSBOOT) $(USR_PSM_NFSBOOT) +install: all $(USR_PSM_NFSBOOT) # # Install rules diff --git a/usr/src/psm/stand/boot/common/readfile.c b/usr/src/psm/stand/boot/common/readfile.c index 846dadcdaa..daacc98d7a 100644 --- a/usr/src/psm/stand/boot/common/readfile.c +++ b/usr/src/psm/stand/boot/common/readfile.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -187,7 +186,7 @@ extern void sas_symtab(int start, int end); * repeat reads (forever) until size of request is satisfied * (Thus, you don't want to use this cases where short reads are ok) */ -static ssize_t +ssize_t xread(int fd, char *p, size_t nbytes) { size_t bytesread = 0; @@ -274,7 +273,7 @@ readfile(int fd, int print) printf("FATAL: 64-bit ELF executable " "not for AMD64\n (e_machine " "= %d).\n", elfhdr.e_machine); - return (FAIL); + return (FAIL); } /* @@ -395,7 +394,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) continue; if (verbosemode) { dprintf("allocating 0x%x bytes for note hdr\n", - phdr->p_filesz); + phdr->p_filesz); } if ((note_buf = kmem_alloc(phdr->p_filesz, 0)) == NULL) goto elferror; @@ -405,14 +404,14 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) goto elferror; if (verbosemode) { dprintf("reading 0x%x bytes into %p\n", - phdr->p_filesz, (void *)nhdr); + phdr->p_filesz, (void *)nhdr); } nhdr = (Elf32_Nhdr *)note_buf; if (xread(fd, (caddr_t)nhdr, phdr->p_filesz) != phdr->p_filesz) goto elferror; if (verbosemode) { dprintf("p_note namesz %x descsz %x type %x\n", - nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); + nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); } /* @@ -453,9 +452,9 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) dprintf("Doing header 0x%x\n", i); dprintf("phdr\n"); dprintf("\tp_offset = %x, p_vaddr = %x\n", - phdr->p_offset, phdr->p_vaddr); + phdr->p_offset, phdr->p_vaddr); dprintf("\tp_memsz = %x, p_filesz = %x\n", - phdr->p_memsz, phdr->p_filesz); + phdr->p_memsz, phdr->p_filesz); } if (phdr->p_type == PT_LOAD) { if (verbosemode) @@ -464,7 +463,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) goto elferror; if (phdr->p_flags == (PF_R | PF_W) && - phdr->p_vaddr == 0) { + phdr->p_vaddr == 0) { /* * It's a PT_LOAD segment that is RW but * not executable and has a vaddr @@ -494,7 +493,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) if (use_align && npagesize != 0) { off = loadaddr & (npagesize - 1); size = roundup(phdr->p_memsz + off, - npagesize); + npagesize); base = loadaddr - off; } else { npagesize = 0; @@ -558,7 +557,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) if (verbosemode) { dprintf("reading 0x%x bytes into 0x%x\n", - phdr->p_filesz, loadaddr); + phdr->p_filesz, loadaddr); } /* use uintptr_t to suppress the gcc warning */ if (xread(fd, (caddr_t)(uintptr_t)loadaddr, @@ -590,7 +589,7 @@ read_elf32(int fd, int print, Elf32_Ehdr *elfhdrp) } #ifdef MPSAS sas_symtab(phdr->p_vaddr, - phdr->p_vaddr + phdr->p_memsz); + phdr->p_vaddr + phdr->p_memsz); #endif } else if (phdr->p_type == PT_INTERP) { /* @@ -799,7 +798,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) continue; if (verbosemode) { dprintf("allocating 0x%llx bytes for note hdr\n", - (u_longlong_t)phdr->p_filesz); + (u_longlong_t)phdr->p_filesz); } if ((note_buf = kmem_alloc(phdr->p_filesz, 0)) == NULL) goto elf64error; @@ -810,14 +809,14 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) goto elf64error; if (verbosemode) { dprintf("reading 0x%llx bytes into 0x%p\n", - (u_longlong_t)phdr->p_filesz, (void *)nhdr); + (u_longlong_t)phdr->p_filesz, (void *)nhdr); } nhdr = (Elf64_Nhdr *)note_buf; if (xread(fd, (caddr_t)nhdr, phdr->p_filesz) != phdr->p_filesz) goto elf64error; if (verbosemode) { dprintf("p_note namesz %x descsz %x type %x\n", - nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); + nhdr->n_namesz, nhdr->n_descsz, nhdr->n_type); } /* @@ -858,13 +857,13 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) dprintf("Doing header 0x%x\n", i); dprintf("phdr\n"); dprintf("\tp_offset = %llx, p_vaddr = %llx\n", - (u_longlong_t)phdr->p_offset, - (u_longlong_t)phdr->p_vaddr); + (u_longlong_t)phdr->p_offset, + (u_longlong_t)phdr->p_vaddr); dprintf("\tp_memsz = %llx, p_filesz = %llx\n", - (u_longlong_t)phdr->p_memsz, - (u_longlong_t)phdr->p_filesz); + (u_longlong_t)phdr->p_memsz, + (u_longlong_t)phdr->p_filesz); dprintf("\tp_type = %x, p_flags = %x\n", - phdr->p_type, phdr->p_flags); + phdr->p_type, phdr->p_flags); } if (phdr->p_type == PT_LOAD) { if (verbosemode) @@ -874,7 +873,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) goto elf64error; if (phdr->p_flags == (PF_R | PF_W) && - phdr->p_vaddr == 0) { + phdr->p_vaddr == 0) { /* * It's a PT_LOAD segment that is RW but * not executable and has a vaddr @@ -912,7 +911,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) if (use_align && npagesize != 0) { off = loadaddr & (npagesize - 1); size = roundup(phdr->p_memsz + off, - npagesize); + npagesize); base = loadaddr - off; } else { npagesize = 0; @@ -951,8 +950,8 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) if (verbosemode) { dprintf("reading 0x%llx bytes into 0x%llx\n", - (u_longlong_t)phdr->p_filesz, - (u_longlong_t)loadaddr); + (u_longlong_t)phdr->p_filesz, + (u_longlong_t)loadaddr); } if (xread(fd, (caddr_t)(uintptr_t) loadaddr, phdr->p_filesz) != phdr->p_filesz) @@ -984,7 +983,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) #ifdef MPSAS sas_symtab(phdr->p_vaddr, - phdr->p_vaddr + phdr->p_memsz); + phdr->p_vaddr + phdr->p_memsz); #endif } else if (phdr->p_type == PT_INTERP) { /* @@ -1090,7 +1089,7 @@ read_elf64(int fd, int print, Elf64_Ehdr *elfhdrp) } bcopy((char *)auxv, (char *)(elfbootvecELF64->eb_un.eb_ptr), - size); + size); #endif /* BOOTAMD64 */ } else { kmem_free(allphdrs, phdrsize); @@ -1180,13 +1179,13 @@ iload32(char *rtld, Elf32_Phdr *thdr, Elf32_Phdr *dhdr, auxv32_t **avp) * to do relocation, skip it. */ if (!(sp->sh_flags & SHF_ALLOC) && - sp->sh_type != SHT_SYMTAB && - sp->sh_type != SHT_STRTAB && #ifdef i386 - sp->sh_type != SHT_REL) + sp->sh_type != SHT_REL && #else - sp->sh_type != SHT_RELA) + sp->sh_type != SHT_RELA && #endif + sp->sh_type != SHT_SYMTAB && + sp->sh_type != SHT_STRTAB) continue; /* * If the section is read-only, @@ -1392,10 +1391,9 @@ iload64(char *rtld, Elf64_Phdr *thdr, Elf64_Phdr *dhdr, auxv64_t **avp) */ if (lseek(fd, sp->sh_offset, 0) == -1 || xread(fd, (caddr_t)(uintptr_t)load, sp->sh_size) != - sp->sh_size) { - printf("boot: error reading section %d\n", - i); - goto error; + sp->sh_size) { + printf("boot: error reading section %d\n", i); + goto error; } } /* diff --git a/usr/src/psm/stand/boot/sparc/common/boot.c b/usr/src/psm/stand/boot/sparc/common/boot.c deleted file mode 100644 index acfbad580b..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/boot.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/salib.h> -#include <sys/stat.h> -#include <sys/promif.h> -#include <sys/bootvfs.h> -#include <sys/boot_redirect.h> -#include "boot_plat.h" - -/* - * This implementation of bootprog() is used by all bootloaders except wanboot. - */ - -#define SUCCESS 0 -#define FAILURE -1 - -/* - * bpath is the boot device path buffer. - * bargs is the boot arguments buffer. - */ -/*ARGSUSED*/ -int -bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) -{ - boolean_t once = B_FALSE; - - systype = set_fstype(v2path, bpath); - -loop: - /* - * Beware: the following code may be executed twice, with different - * bpath's if we discover a redirection file. - */ - - if (verbosemode) { - printf("device path '%s'\n", bpath); - if (strcmp(bpath, v2path) != 0) - printf("client path '%s'\n", v2path); - } - - if (mountroot(bpath) != SUCCESS) - prom_panic("Could not mount filesystem."); - - /* - * kernname (default-name) might have changed if mountroot() called - * boot_nfs_mountroot(), and it called set_default_filename(). - */ - if (!user_specified_filename) - (void) strcpy(filename, kernname); - - if (verbosemode) - printf("standalone = `%s', args = `%s'\n", filename, bargs); - - set_client_bootargs(filename, bargs); - - if (!once && - (strcmp(systype, "ufs") == 0 || strcmp(systype, "hsfs") == 0)) { - char redirect[OBP_MAXPATHLEN]; - - post_mountroot(filename, redirect); - - /* - * If we return at all, it's because we discovered - * a redirection file - the 'redirect' string now contains - * the name of the disk slice we should be looking at. - * - * Unmount the filesystem, tweak the boot path and retry - * the whole operation one more time. - */ - closeall(1); - once = B_TRUE; - redirect_boot_path(bpath, redirect); - if (verbosemode) - printf("%sboot: using '%s'\n", systype, bpath); - - goto loop; - /*NOTREACHED*/ - } - - return (0); -} diff --git a/usr/src/psm/stand/boot/sparc/common/boot_plat.c b/usr/src/psm/stand/boot/sparc/common/boot_plat.c index ff1f0fe23b..9a9423cf1b 100644 --- a/usr/src/psm/stand/boot/sparc/common/boot_plat.c +++ b/usr/src/psm/stand/boot/sparc/common/boot_plat.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -81,7 +80,6 @@ int client_isLP64 = 1; /* SPARC clients are always LP64 */ * filename is the name of the standalone we're going to execute. */ char filename[MAXPATHLEN]; -char *cmd_line_default_path; char * const defname = "kernel/sparcv9/unix"; @@ -236,24 +234,6 @@ boot_open(char *pathname, void *arg) return (open(pathname, O_RDONLY)); } -static int -boot_isdir(char *pathname) -{ - int fd, retval; - struct stat sbuf; - - dprintf("trying '%s'\n", pathname); - if ((fd = open(pathname, O_RDONLY)) == -1) - return (0); - retval = 1; - if (fstat(fd, &sbuf) == -1) - retval = 0; - else if ((sbuf.st_mode & S_IFMT) != S_IFDIR) - retval = 0; - (void) close(fd); - return (retval); -} - /* * Open the given filename, expanding to it's * platform-dependent location if necessary. @@ -266,8 +246,6 @@ int openfile(char *filename) { static char *fullpath; - static char *iarch; - static char *orig_impl_arch_name; static int once; int fd; @@ -282,78 +260,16 @@ openfile(char *filename) if (mfg_name == NULL) mfg_name = get_mfg_name(); - /* - * If impl_arch_name was specified on the command line - * via the -I <arch> argument, remember the original value. - */ - if (impl_arch_name) { - orig_impl_arch_name = (char *) - kmem_alloc(strlen(impl_arch_name) + 1, 0); - (void) strcpy(orig_impl_arch_name, impl_arch_name); - } - fullpath = (char *)kmem_alloc(MAXPATHLEN, 0); - iarch = (char *)kmem_alloc(MAXPATHLEN, 0); } - /* - * impl_arch_name is exported as boot property, and is - * set according to the following algorithm, depending - * on the contents of the filesystem. - * XXX: This shouldn't be a side effect of openfile(). - * - * impl_arch_name table: - * - * root name default name neither name - * boot args found found found - * - * relative path root name fail fail - * absolute path root name default name empty - * -I arch arch arch arch - * - */ - - /* - * If the caller -specifies- an absolute pathname, then we just try to - * open it. (Mostly for booting non-kernel standalones.) - * - * In case this absolute pathname is the kernel, make sure that - * impl_arch_name (exported as a boot property) is set to some - * valid string value. - */ if (*filename == '/') { - if (orig_impl_arch_name == NULL) { - if (find_platform_dir(boot_isdir, iarch, 1) != 0) - impl_arch_name = iarch; - else - impl_arch_name = ""; - } (void) strcpy(fullpath, filename); fd = boot_open(fullpath, NULL); return (fd); } - /* - * If the -I flag has been used, impl_arch_name will - * be specified .. otherwise we ask find_platform_dir() to - * look for the existance of a directory for this platform name. - * Preserve the given impl-arch-name, because the 'kernel file' - * may be elsewhere. (impl-arch-name could be 'SUNW,Ultra-1', - * but the kernel file itself might be in the 'sun4u' directory). - * - * When booting any file by relative pathname this code fails - * if the platform-name dir doesn't exist unless some - * -I <iarch> argument has been given on the command line. - */ - if (orig_impl_arch_name == NULL) { - if (find_platform_dir(boot_isdir, iarch, 0) != 0) - impl_arch_name = iarch; - else - return (-1); - } - - fd = open_platform_file(filename, boot_open, NULL, fullpath, - orig_impl_arch_name); + fd = open_platform_file(filename, boot_open, NULL, fullpath); if (fd == -1) return (-1); diff --git a/usr/src/psm/stand/boot/sparc/common/boot_plat.h b/usr/src/psm/stand/boot/sparc/common/boot_plat.h index 99066f70bb..e6dffbedc4 100644 --- a/usr/src/psm/stand/boot/sparc/common/boot_plat.h +++ b/usr/src/psm/stand/boot/sparc/common/boot_plat.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,7 +35,6 @@ extern "C" { /* boot_plat.c */ -extern char *cmd_line_default_path; extern int verbosemode; extern char filename[]; extern char *const defname; @@ -52,21 +50,11 @@ extern void set_client_bootargs(const char *, const char *); extern boolean_t is_netdev(char *devpath); -/* boot_1275entry.c */ -extern int boot1275_entry_asm(void *); -extern void boot_fail_gracefully_asm(void); - - -/* boot_services.c */ -extern int boot1275_entry(void *); - - /* bootops.c */ extern struct bootops bootops; extern void setup_bootops(void); extern void update_memlist(char *, char *, struct memlist **); -extern void boot_fail_gracefully(void); /* @@ -81,7 +69,6 @@ extern char *mfg_name; extern char *impl_arch_name; extern char *bootp_response; extern char *boot_message; -extern char *cmd_line_default_path; extern int cache_state; extern uint64_t memlistextent; extern char *netdev_path; diff --git a/usr/src/psm/stand/boot/sparc/common/boot_services.c b/usr/src/psm/stand/boot/sparc/common/boot_services.c deleted file mode 100644 index 16a7acaebe..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/boot_services.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Definitions of interfaces that provide services from the secondary - * boot program to its clients (primarily unix, krtld and their successors.) - * This interface replaces the bootops (BOP) implementation as the interface - * to be called by boot clients. The BOP macros are still used to make the - * integration easier. - * - * The bootops vector is vestigial. - * - * The kern_* routines used to implement many of the services here - * are in the usr/src/stand/lib/ modules. - * - */ - -#include <sys/types.h> -#include <sys/bootconf.h> -#include <sys/reboot.h> -#include <sys/param.h> -#include <sys/varargs.h> -#include <sys/obpdefs.h> -#include <sys/promif.h> -#include <sys/salib.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> - -extern void kern_killboot(void); -extern int bgetprop(struct bootops *, char *name, void *buf); -extern int bgetproplen(struct bootops *, char *name); -extern char *bnextprop(struct bootops *, char *prev); -extern caddr_t resalloc_virt(caddr_t virt, size_t size); - -static int boot1275_serviceavail(void *p); - -static struct boot_nm2svc *nm2svcp(char *name); - -/* - * Implementation of the "version" service. - * Return the compiled version number of this implementation of boot. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned version number - */ -static int boot_version = BO_VERSION; -static int -boot1275_getversion(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[3] = boot_int2cell(boot_version); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "open" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] filename string - * args[4] flags - * args[5] Res0: returned result - * - */ -static int -boot1275_open(void *p) -{ - int rc; - int flags; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - flags = boot_cell2int(args[4]); - rc = kern_open(name, flags); - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "read" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] client's buffer - * args[5] size of read request - * args[6] Res0: returned result - * - */ -static int -boot1275_read(void *p) -{ - int rc; - boot_cell_t *args = (boot_cell_t *)p; - - /* XXX use different routine to support larger I/O ? */ - int fd; - caddr_t buf; - size_t size; - - fd = boot_cell2int(args[3]); - buf = boot_cell2ptr(args[4]); - size = boot_cell2size(args[5]); - rc = kern_read(fd, buf, size); - args[6] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "seek" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] offset hi XXX just use one cell for offset? - * args[5] offset lo - * args[6] Res0: returned result - * - */ -static int -boot1275_seek(void *p) -{ - off_t rc; - int fd; - off_t hi, lo; - boot_cell_t *args = (boot_cell_t *)p; - - fd = boot_cell2int(args[3]); - hi = boot_cell2offt(args[4]); - lo = boot_cell2offt(args[5]); - rc = kern_lseek(fd, hi, lo); - args[6] = boot_offt2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "close" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] boot-opened file descriptor - * args[4] Res0: returned result - * - */ -static int -boot1275_close(void *p) -{ - int rc; - int fd; - boot_cell_t *args = (boot_cell_t *)p; - - fd = boot_cell2int(args[3]); - rc = kern_close(fd); - args[4] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "alloc" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual hint - * args[4] size to allocate - * args[5] alignment - * args[6] Res0: returned result - */ -static int -boot1275_alloc(void *p) -{ - caddr_t virthint, addr; - size_t size; - int align; - boot_cell_t *args = (boot_cell_t *)p; - - virthint = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - align = boot_cell2int(args[5]); - addr = kern_resalloc(virthint, size, align); - args[6] = boot_ptr2cell(addr); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "alloc_virt" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #arguments cells - * args[2] #result cells - * args[3] virtual address - * args[4] size to allocate - * args[5] Res0: returned result - */ -static int -boot1275_alloc_virt(void *p) -{ - caddr_t virt, addr; - size_t size; - boot_cell_t *args = (boot_cell_t *)p; - - virt = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - addr = resalloc_virt(virt, size); - args[5] = boot_ptr2cell(addr); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "free" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual addr - * args[4] size to free - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_free(void *p) -{ - caddr_t virtaddr; - size_t size; - boot_cell_t *args = (boot_cell_t *)p; - - virtaddr = boot_cell2ptr(args[3]); - size = boot_cell2size(args[4]); - kern_resfree(virtaddr, size); - args[5] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "map" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual address - * args[4] space of phys addr - * args[5] phys addr - * args[6] size - * args[7] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_map(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[6] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "unmap" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] virtual address - * args[4] size of chunk - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_unmap(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - args[5] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "quiesce" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_quiesce(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - - kern_killboot(); - args[3] = (boot_cell_t)0; - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "getproplen" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] property name string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_getproplen(void *p) -{ - int rc; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - - name = boot_cell2ptr(args[3]); - rc = bgetproplen((struct bootops *)0, name); - args[4] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "getprop" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] property name string - * args[4] buffer pointer to hold value of the property - * args[5] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_getprop(void *p) -{ - int rc; - char *name; - void *buf; - boot_cell_t *args = (boot_cell_t *)p; - - - name = boot_cell2ptr(args[3]); - buf = boot_cell2ptr(args[4]); - rc = bgetprop((struct bootops *)0, name, buf); - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "putsarg" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] string to print (with '%*' format) - * args[4] 64-bit thing to print - * - * The bootops interface can only pass one additional - * argument. Abusing the format string can cause failures - * in interesting ways that could be hard to debug when - * an argument is pulled off the stack or dereferenced, - * so if the format string indicates more than one argument, - * we note the problem rather print garbage or panic. - */ -/*ARGSUSED*/ -static int -boot1275_putsarg(void *p) -{ - const char *string; - boot_cell_t *args = (boot_cell_t *)p; - const char *fmt; - int ells = 0; - int arg_is_ptr = 0; - int nargs = 0; - uint64_t arg; - - - string = boot_cell2ptr(args[3]); - arg = boot_cell2uint64(args[4]); - - /* - * We need to do the minimum printf-like stuff here to figure - * out the size of argument, if present. - */ - for (fmt = string; *fmt; fmt++) { - if (*fmt != '%') - continue; - if (*(++fmt) == '%') - continue; - - nargs++; - while (*fmt >= '0' && *fmt <= '9') - fmt++; - for (ells = 0; *fmt == 'l'; fmt++) - ells++; - - switch (*fmt) { - case 's': - case 'p': - arg_is_ptr = 1; - break; - } - } - - if (nargs > 1) { - printf("boot1275_putsarg: unsupported format: \"%s\"\n", - string); - } else if (arg_is_ptr) { - printf(string, (void *)arg); - } else { - switch (ells) { - case 0: - printf(string, (uint_t)arg); - break; - case 1: - printf(string, (ulong_t)arg); - break; - default: - printf(string, arg); - break; - } - } - - return (BOOT_SVC_OK); -} -/* - * Implementation of the "puts" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] string to print - */ -/*ARGSUSED*/ -static int -boot1275_puts(void *p) -{ - char *string; - boot_cell_t *args = (boot_cell_t *)p; - - - string = boot_cell2ptr(args[3]); - printf("%s", string); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "nextprop" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] previous property name string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_nextprop(void *p) -{ - char *name, *np; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - np = bnextprop((struct bootops *)0, name); - args[4] = boot_ptr2cell(np); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "mount" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] pathname string - * args[4] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_mountroot(void *p) -{ - int rc; - char *name; - boot_cell_t *args = (boot_cell_t *)p; - - name = boot_cell2ptr(args[3]); - rc = kern_mountroot(name); - args[4] = boot_cell2int(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "unmount" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] Res0: returned result - */ -/*ARGSUSED*/ -static int -boot1275_unmountroot(void *p) -{ - int rc; - boot_cell_t *args = (boot_cell_t *)p; - - rc = kern_unmountroot(); - args[3] = boot_cell2int(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "fstat" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] fd - * args[4] client's stat structure - */ -int -boot1275_fstat(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - int fd = boot_cell2int(args[3]); - struct bootstat *st = boot_cell2ptr(args[4]); - int rc = kern_fstat(fd, st); - - args[5] = boot_int2cell(rc); - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "interpret" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells (1) - * args[2] #result cells (0) - * args[3] string to interpret - */ -int -boot1275_interpret(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - char *str = boot_cell2ptr(args[3]); - - prom_interpret(str, 0, 0, 0, 0, 0); - - return (BOOT_SVC_OK); -} - -/* - * Implementation of the "enter_mon" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells (0) - * args[2] #result cells (0) - */ -/*ARGSUSED*/ -int -boot1275_enter_mon(void *p) -{ - prom_enter_mon(); - - return (BOOT_SVC_OK); -} - -/* - * The lookup table akin to the old bootops vec - * for boot. Not part of the exported interface. - */ -static struct boot_nm2svc { - char *b_name; - int (*b_funcptr)(void *); - int b_svcversion; -} boot_nm2svc[] = { - { "version", boot1275_getversion, 1 }, - { "open", boot1275_open, 1 }, - { "read", boot1275_read, 1 }, - { "seek", boot1275_seek, 1 }, - { "close", boot1275_close, 1 }, - { "alloc", boot1275_alloc, 1 }, - { "alloc_virt", boot1275_alloc_virt, 1 }, - { "free", boot1275_free, 1 }, - { "map", boot1275_map, 1 }, - { "unmap", boot1275_unmap, 1 }, - { "quiesce", boot1275_quiesce, 1 }, - { "getproplen", boot1275_getproplen, 1 }, - { "getprop", boot1275_getprop, 1 }, - { "nextprop", boot1275_nextprop, 1 }, - { "mountroot", boot1275_mountroot, 1 }, - { "unmountroot", boot1275_unmountroot, 1 }, - { "serviceavail", boot1275_serviceavail, 1 }, - { "puts", boot1275_puts, 1 }, - { "putsarg", boot1275_putsarg, 1 }, - { "fstat", boot1275_fstat, 1 }, - { "interpret", boot1275_interpret, 1 }, - { "enter_mon", boot1275_enter_mon, 1 }, - { 0, 0, 0 } -}; - -static struct boot_nm2svc * -nm2svcp(char *name) -{ - struct boot_nm2svc *pnm2svc = &boot_nm2svc[0]; - - while (pnm2svc->b_name != 0) { - if (strcmp(pnm2svc->b_name, name)) - pnm2svc++; - else { - return (pnm2svc); - } - } - return (NULL); -} - -/* - * Implementation of the "serviceavail" boot service. - * - * Calling spec: - * args[0] Service name string - * args[1] #argument cells - * args[2] #result cells - * args[3] name string of service to be tested for - * args[4] Res0: returned version number or 0 - */ -/*ARGSUSED*/ -static int -boot1275_serviceavail(void *p) -{ - boot_cell_t *args = (boot_cell_t *)p; - char *name; - struct boot_nm2svc *pnm2svc; - int version = 0; /* 0 means service not avail */ - - name = boot_cell2ptr(args[3]); - pnm2svc = nm2svcp(name); - if (pnm2svc != 0) - version = pnm2svc->b_svcversion; - args[4] = boot_int2cell(version); - return (BOOT_SVC_OK); -} - -int -boot1275_entry(void *p) -{ - int rc = 0; - char *name; - int (*fp)(); - boot_cell_t *args = (boot_cell_t *)p; - struct boot_nm2svc *pnm2svc; - - name = boot_cell2ptr(args[0]); - pnm2svc = nm2svcp(name); - if (pnm2svc != NULL) { - fp = (int(*)())(pnm2svc->b_funcptr); - rc = (*fp)(args); - } else { - prom_printf("call to undefined service \"%s\"\n", name); - } - return (rc); -} diff --git a/usr/src/psm/stand/boot/sparc/common/bootflags.c b/usr/src/psm/stand/boot/sparc/common/bootflags.c index abb4573d24..f401f8ac57 100644 --- a/usr/src/psm/stand/boot/sparc/common/bootflags.c +++ b/usr/src/psm/stand/boot/sparc/common/bootflags.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,24 +37,19 @@ #include <util/getoptstr.h> #include "boot_plat.h" -static char impl_arch_buf[MAXNAMELEN]; static char default_path_buf[MAXPATHLEN]; char wanboot_arguments[OBP_MAXPATHLEN]; /* args following "-o" */ +char cmd_line_boot_archive[MAXPATHLEN]; + +boolean_t halt; + /* * Parse the boot arguments, adding the options found to the existing boothowto * value (if any) or other state. Then rewrite the buffer with arguments for * the standalone. * - * We assume that the buffer contains only the arguments (no preceeding - * filename or whitespace). We start interpreting flags, ignoring those used - * by the boot block (-H, -X, and -F filename) and acting on those intended - * for us (those documented in boot(1M) as well as some undocumented), and - * stop at unknown flags. Finally we reconstitute flags to be passed on to - * the standalone and the remaining arguments, excluding the first "--", to - * the beginning of the buffer, and return an integer representing our flags. - * * NOTE: boothowto may already have bits set when this function is called */ void @@ -67,8 +61,8 @@ bootflags(char *args, size_t argsz) char *np; size_t npres; int c; + char *cmd_line_default_path; - impl_arch_name = NULL; cmd_line_default_path = NULL; params.gos_opts = "HXF:VnI:D:advhko:"; @@ -77,11 +71,24 @@ bootflags(char *args, size_t argsz) while ((c = getoptstr(¶ms)) != -1) { switch (c) { /* - * Bootblock flags: ignore. + * Bootblock flags. */ case 'H': + halt = B_TRUE; + /*FALLTHRU*/ case 'X': + break; + case 'F': + if (params.gos_optarglen >= + sizeof (cmd_line_boot_archive)) { + printf("boot: -F argument too long. " + "Ignoring.\n"); + break; + } + (void) strncpy(cmd_line_boot_archive, + params.gos_optargp, params.gos_optarglen); + cmd_line_boot_archive[params.gos_optarglen] = '\0'; break; /* @@ -95,18 +102,6 @@ bootflags(char *args, size_t argsz) printf("Warning: boot will not enable cache\n"); break; - case 'I': - if (params.gos_optarglen >= sizeof (impl_arch_buf)) { - printf("boot: -I argument too long. " - "Ignoring.\n"); - break; - } - (void) strncpy(impl_arch_buf, params.gos_optargp, - params.gos_optarglen); - impl_arch_buf[params.gos_optarglen] = '\0'; - impl_arch_name = impl_arch_buf; - break; - case 'D': if (params.gos_optarglen >= sizeof (default_path_buf)) { printf("boot: -D argument too long. " @@ -160,8 +155,6 @@ bootflags(char *args, size_t argsz) */ switch (params.gos_last_opt) { case 'F': - /* -F is a bootblock flag, so ignore. */ - break; case 'I': case 'D': case 'o': @@ -271,4 +264,10 @@ done: */ if (cmd_line_default_path) set_default_filename(cmd_line_default_path); + + /* + * See if user wants to examine things + */ + if (halt == B_TRUE) + prom_enter_mon(); } diff --git a/usr/src/psm/stand/boot/sparc/common/bootops.c b/usr/src/psm/stand/boot/sparc/common/bootops.c index 662fcfaedc..10d7b87003 100644 --- a/usr/src/psm/stand/boot/sparc/common/bootops.c +++ b/usr/src/psm/stand/boot/sparc/common/bootops.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,12 @@ * CDDL HEADER END */ /* - * Copyright 1996-2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" -/* - * Implementation of the vestigial bootops vector for platforms using the - * 1275-like boot interfaces. - */ - #include <sys/types.h> #include <sys/bootconf.h> #include <sys/param.h> @@ -51,38 +45,20 @@ static const int debug = 0; extern void closeall(int); -/* - * This is the number for this version of bootops, which is vestigial. - * Standalones that require the old bootops will look in bootops.bsys_version, - * see this number is higher than they expect and fail gracefully. - * They can make this "peek" successfully even if they are ILP32 programs. - */ -int boot_version = BO_VERSION; - struct bootops bootops; +static void +boot_fail(void) +{ + prom_panic("bootops is gone, it should not be called"); +} + void setup_bootops(void) { - /* sanity-check bsys_printf - old kernels need to fail with a message */ -#if !defined(lint) - if (offsetof(struct bootops, bsys_printf) != 60) { - printf("boot: bsys_printf is at offset 0x%lx instead of 60\n" - "boot: this will likely make old kernels die without " - "printing a message.\n", - offsetof(struct bootops, bsys_printf)); - } - /* sanity-check bsys_1275_call - if it moves, kernels cannot boot */ - if (offsetof(struct bootops, bsys_1275_call) != 24) { - printf("boot: bsys_1275_call is at offset 0x%lx instead of 24\n" - "boot: this will likely break the kernel\n", - offsetof(struct bootops, bsys_1275_call)); - } -#endif - bootops.bsys_version = boot_version; - bootops.bsys_1275_call = (uint64_t)boot1275_entry; - /* so old kernels die with a message */ - bootops.bsys_printf = (uint32_t)boot_fail_gracefully; + bootops.bsys_version = BO_VERSION; + bootops.bsys_1275_call = (uint64_t)boot_fail; + bootops.bsys_printf = (uint32_t)boot_fail; if (!memlistpage) /* paranoia runs rampant */ prom_panic("\nMemlistpage not setup yet."); @@ -204,10 +180,3 @@ kern_killboot(void) prom_enter_mon(); #endif } - -void -boot_fail_gracefully(void) -{ - prom_panic( - "mismatched version of /boot interface: new boot, old kernel"); -} diff --git a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c b/usr/src/psm/stand/boot/sparc/common/hsfsconf.c deleted file mode 100644 index 2f71220391..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/param.h> -#include <sys/sysmacros.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> - -/* HSFS Support */ -extern struct boot_fs_ops boot_hsfs_ops; - -struct boot_fs_ops *boot_fsw[] = { - &boot_hsfs_ops, -}; - -int boot_nfsw = sizeof (boot_fsw) / sizeof (boot_fsw[0]); -static char *fstype = "hsfs"; - -/*ARGSUSED*/ -char * -set_fstype(char *v2path, char *bpath) -{ - set_default_fs(fstype); - return (fstype); -} diff --git a/usr/src/psm/stand/boot/sparc/common/inetboot.c b/usr/src/psm/stand/boot/sparc/common/inetboot.c new file mode 100644 index 0000000000..13a61bb30f --- /dev/null +++ b/usr/src/psm/stand/boot/sparc/common/inetboot.c @@ -0,0 +1,181 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +#include <sys/types.h> +#include <sys/param.h> +#include <sys/fcntl.h> +#include <sys/obpdefs.h> +#include <sys/reboot.h> +#include <sys/promif.h> +#include <sys/stat.h> +#include <sys/bootvfs.h> +#include <sys/platnames.h> +#include <sys/salib.h> +#include <sys/elf.h> +#include <sys/link.h> +#include <sys/auxv.h> +#include <sys/boot_policy.h> +#include <sys/boot_redirect.h> +#include <sys/bootconf.h> +#include <sys/boot.h> +#include "boot_plat.h" +#include "ramdisk.h" + +#define SUCCESS 0 +#define FAILURE -1 + +#ifdef DEBUG +extern int debug = 0; +#else +static const int debug = 0; +#endif + +#define dprintf if (debug) printf + +char *def_boot_archive = "boot_archive"; +char *def_miniroot = "miniroot"; +extern char cmd_line_boot_archive[]; + +extern int openfile(char *filename); + +static int +read_and_boot_ramdisk(int fd) +{ + struct stat st; + caddr_t virt; + size_t size; + extern ssize_t xread(int, char *, size_t); + + if ((fstat(fd, &st) != 0) || + ((virt = create_ramdisk(RD_ROOTFS, st.st_size, NULL)) == NULL)) + return (-1); + + dprintf("reading boot archive ...\n"); + if ((size = xread(fd, (char *)virt, st.st_size)) != st.st_size) { + (void) printf("Error reading boot archive, bytes read = %ld, " + "filesize = %ld\n", (long)size, (long)st.st_size); + destroy_ramdisk(RD_ROOTFS); + return (-1); + } + + boot_ramdisk(RD_ROOTFS); + /* NOT REACHED */ + return (0); /* to make cc happy */ +} + + +static void +post_mountroot_nfs(void) +{ + int fd; + char *fn; + char tmpname[MAXPATHLEN]; + + for (;;) { + fn = NULL; + if (boothowto & RB_ASKNAME) { + fn = (cmd_line_boot_archive[0] != '\0') ? + cmd_line_boot_archive : def_boot_archive; + printf("Enter filename [%s]: ", fn); + (void) cons_gets(tmpname, sizeof (tmpname)); + if (tmpname[0] != '\0') + fn = tmpname; + } + + if (boothowto & RB_HALT) { + printf("Boot halted.\n"); + prom_enter_mon(); + } + + if (fn != NULL) + fd = openfile(fn); + else if (cmd_line_boot_archive[0] != '\0') { + fn = cmd_line_boot_archive; + fd = openfile(fn); + } else { + fn = def_boot_archive; + if ((fd = openfile(fn)) == FAILURE) { + fn = def_miniroot; + fd = openfile(fn); + } + } + + if (fd == FAILURE) { + if (fn != def_miniroot) + printf("cannot open %s\n", fn); + else + printf("cannot open neither %s nor %s\n", + def_boot_archive, def_miniroot); + } else { + /* + * this function does not return if successful. + */ + (void) read_and_boot_ramdisk(fd); + + printf("boot failed\n"); + (void) close(fd); + } + boothowto |= RB_ASKNAME; + } +} + + +/* + * bpath is the boot device path buffer. + * bargs is the boot arguments buffer. + */ +/*ARGSUSED*/ +int +bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) +{ + systype = set_fstype(v2path, bpath); + + if (verbosemode) { + printf("device path '%s'\n", bpath); + if (strcmp(bpath, v2path) != 0) + printf("client path '%s'\n", v2path); + } + + if (mountroot(bpath) != SUCCESS) + prom_panic("Could not mount filesystem."); + + /* + * kernname (default-name) might have changed if mountroot() called + * boot_nfs_mountroot(), and it called set_default_filename(). + */ + if (!user_specified_filename) + (void) strcpy(filename, kernname); + + if (verbosemode) + printf("standalone = `%s', args = `%s'\n", filename, bargs); + + set_client_bootargs(filename, bargs); + + post_mountroot_nfs(); + + return (1); +} diff --git a/usr/src/psm/stand/boot/sparc/common/ramdisk.c b/usr/src/psm/stand/boot/sparc/common/ramdisk.c index bba9f4b5d2..ee0116f3d0 100644 --- a/usr/src/psm/stand/boot/sparc/common/ramdisk.c +++ b/usr/src/psm/stand/boot/sparc/common/ramdisk.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -34,534 +33,400 @@ /* EXPORT DELETE END */ #include "ramdisk.h" -/* - * This is a chunk of Forth delivered by the OBP group. When loaded - * into OBP it creates a ramdisk device node whose functionality is - * defined in FWARC 2002/299. - * - * Note the %s in the line following " new-device" - this is where we - * plug the name of the node in. - */ -static const char ramdisk_fth[] = - -"headerless " - -"\" /\" find-package 0= if" -" .\" Can't find /\" abort " -"then push-package " - -"new-device" -" \" %s\" device-name" -" \" block\" encode-string \" device_type\" property" -/* CSTYLED */ +#include <sys/param.h> +#include <sys/fcntl.h> +#include <sys/obpdefs.h> +#include <sys/reboot.h> +#include <sys/promif.h> +#include <sys/stat.h> +#include <sys/bootvfs.h> +#include <sys/platnames.h> +#include <sys/salib.h> +#include <sys/elf.h> +#include <sys/link.h> +#include <sys/auxv.h> +#include <sys/boot_policy.h> +#include <sys/boot_redirect.h> +#include <sys/bootconf.h> +#include <sys/boot.h> +#include "boot_plat.h" + + +static char ramdisk_preamble_fth[] = + +": find-abort ( name$ -- ) " +" .\" Can't find \" type abort " +"; " + +": get-package ( pkg$ -- ph ) " +" 2dup find-package 0= if " +" find-abort " +" then ( pkg$ ph ) " +" nip nip ( ph ) " +"; " + +"\" /openprom/client-services\" get-package constant cif-ph " + +"instance defer cif-open ( dev$ -- ihandle|0 ) " +"instance defer cif-close ( ihandle -- ) " + +": find-cif-method ( adr,len -- acf ) " +" 2dup cif-ph find-method 0= if ( adr,len ) " +" find-abort " +" then ( adr,len acf ) " +" nip nip ( acf ) " +"; " + +"\" open\" find-cif-method to cif-open " +"\" close\" find-cif-method to cif-close " + +"0 value dev-ih " + +"d# 100 buffer: open-cstr " + +": dev-open ( dev$ -- okay? ) " +/* copy to C string for open */ +" 0 over open-cstr + c! " +" open-cstr swap move " +" open-cstr cif-open dup if " +" dup to dev-ih " +" then " +"; " + +": dev-close ( -- ) " +" dev-ih cif-close " +" 0 to dev-ih " +"; " + +": open-abort ( file$ -- ) " +" .\" Can't open \" type abort " +"; " +; + +static char ramdisk_fth[] = + +"\" /\" get-package push-package " + +"new-device " +" \" %s\" device-name " +" " +" \" block\" device-type " " \" SUNW,ramdisk\" encode-string \" compatible\" property" -" hex" - -" headerless" - -" 0 value mmu-ihandle" -" 0 value mem-ihandle" - -" : get-memory-ihandles" /* ( -- ) */ -" \" /chosen\" find-package drop dup \" mmu\" rot" -" get-package-property if" -" .\" Can't find chosen mmu property\" cr abort" -" then" -" decode-int to mmu-ihandle 2drop" -" \" memory\" rot get-package-property if" -" .\" Can't find chosen memory property\" cr abort" -" then" -" decode-int to mem-ihandle 2drop" -" ;" - -" : get-page-size" /* ( -- page-size ) */ -" mmu-ihandle ihandle>phandle \" page-size\" rot get-package-property" -" if h# 2000 else decode-int nip nip then " -" ;" - -" : get-mode" /* ( -- rw-mode ) */ -" here \" translate\" mmu-ihandle $call-method if" -" nip nip" -" else" -" h# 27" -" then" -" ;" - -" : 64>32bit-phys" /* ( 64bit.lo 64bit.hi -- 32bit.lo 32bit.hi ) */ -" drop xlsplit" -" ;" - -" : 32>64bit-phys" /* ( 32bit.lo 32bit.hi -- 64bit.lo 64bit.hi ) */ -" lxjoin 0" -" ;" - -" : phy-claim" /* ( size align -- base.lo base.hi 0 | error ) */ -" \" claim\" mem-ihandle ['] $call-method catch if" -" drop 2drop 2drop -1" -" else" -" 64>32bit-phys 0" -" then" -" ;" - -" : phy-release" /* ( phys.lo phys.hi size -- ) */ -" >r 32>64bit-phys r> \" release\" mem-ihandle $call-method" -" ;" - -" : vir-claim" /* ( [ virt ] size align -- base ) */ -" \" claim\" mmu-ihandle $call-method" -" ;" - -" : vir-release" /* ( virt size -- ) */ -" \" release\" mmu-ihandle $call-method" -" ;" - -" : vir-map" /* ( phys-lo phys-hi virt size mode -- ) */ -" >r >r >r 32>64bit-phys r> r> r>" -" \" map\" mmu-ihandle $call-method" -" ;" - -" : vir-unmap" /* ( virt size -- ) */ -" \" unmap\" mmu-ihandle $call-method" -" ;" -" headers" - -/* \ This structure represents a physical "chunk" of ramdisk memory */ -" struct" -" /l field >res-pa.lo" /* \ lower 32bits of physical address */ -" /l field >res-pa.hi" /* \ upper 32bits of physical address */ -" /l field >res-len.lo" /* \ lower 32bits of chunk size */ -" /l field >res-len.hi" /* \ upper 32bits of chunk size */ -" constant /res-entry" - -" 4 value max-res-entries" /* \ Max # of non-contig phys chunks */ - -" max-res-entries /res-entry *" /* \ size of resource buffer */ -" ( value ) buffer: my-resources" /* \ resource buffer label */ -" 0 value num-res-entries" /* \ current # of chunks allocated */ -" h# 10 constant label-size" /* \ size of disk-label buffer */ -" label-size instance buffer: my-label" /* \ for disk-label argument string */ - -" get-memory-ihandles" /* \ So we can claim/map/free memory */ -" get-page-size value pagesize" /* \ get virt pagesize from vmem node */ -" get-mode value mode" /* \ get mode to map virt memory with */ - -" 0 instance value window-mapped?" /* \ just in case for pa's near 0 */ -" 0 instance value window-pa" /* \ physical base of virtual window */ -" 0 instance value window-base" /* \ virtual window base */ -" h# 10000 constant window-size" /* \ virtual window size */ - -" 0 instance value filepos" /* \ file position marker */ -" -1 value new-disk?" /* \ need to alloc new resources? */ - -" 0 instance value offset-low" /* \ Offset to start of partition */ -" 0 instance value offset-high" /* \ For partition relative seeks */ -" 0 instance value label-package" /* \ ihandle for disk-label package */ - -" external" /* \ Because device_type = block */ - -" 0 value size" /* \ size of disk */ -" 0 value #blocks" /* \ size of disk / decimal 512 */ - -" headerless" - -" : round-up" /* ( n -- n' ) */ -" 1- tuck + swap invert and" -" ;" - -" : init-label-package" /* ( adr len -- okay? ) */ -" 0 to offset-high 0 to offset-low" -" \" disk-label\" $open-package to label-package" -" label-package if" -" 0 0 \" offset\" label-package $call-method" -" to offset-high to offset-low" -" true" -" else" -" .\" Can't open disk label package\" cr false" -" then" -" ;" - -" : res-entry-len" /* ( n -- 64bit-len | 0 ) \ Get length of chunk n */ -" dup num-res-entries > if" -" drop 0" -" else" -" /res-entry * my-resources +" -" dup >res-len.lo l@ swap >res-len.hi l@" -" lxjoin" -" then" -" ;" - -" : res-entry-pa" /* ( n -- 64bit-pa | 0 ) \ Get phys address of chunk n */ -" dup num-res-entries > if" /* ( n ) */ -" drop 0" /* ( 0 ) */ -" else" /* ( n ) */ -" /res-entry * my-resources +" /* ( chunk-adr ) */ -" dup >res-pa.lo l@ swap >res-pa.hi l@" /* ( pa.lo pa.hi ) */ -" lxjoin" /* ( 64bit-pa ) */ -" then" /* ( 64bit-pa ) */ -" ;" - -" : claim-window" /* ( -- ) \ Claim mem for virt window */ -" window-size pagesize vir-claim to window-base" -" ;" - -" : release-window" /* ( -- ) \ Free virt window memory */ -" window-base window-size" -" 2dup vir-unmap" -" vir-release" -" ;" - -" : map-window" /* ( 64bit-pa -- ) \ Map a physical address to the v-window */ -" dup to window-pa" -" xlsplit window-base window-size mode vir-map" -" -1 to window-mapped?" -" ;" - -" : unmap-window" /* ( -- ) \ Unmap the virtual window */ -" window-base window-size vir-unmap" -" 0 to window-mapped?" -" ;" - -" : in-window?" /* ( pa -- in-window? ) */ -" window-mapped? if" -" window-pa dup window-size + 1- between" -" else" -" drop 0" -" then" -" ;" - -" : window-left" /* ( offset -- space-left-in-window ) */ -" window-size mod" -" window-size swap -" -" ;" - -" : release-resources" /* ( -- ) \ release previously claimed phys addrs */ -" num-res-entries 0 2dup = if" /* ( res-entries 0 ) */ -" 2drop exit" /* ( ) */ -" then" /* ( res-entries 0 ) */ -" do" /* ( ) */ -" i res-entry-pa xlsplit" /* ( pa.lo pa.hi ) */ -" i res-entry-len phy-release" /* ( ) */ -" loop" /* ( ) */ -" 0 to num-res-entries" /* ( ) */ -" my-resources max-res-entries /res-entry * erase" /* ( ) */ -" ;" - -" : fill-entry" /* ( pa.lo pa.hi size.lo size.hi -- ) \ fill chunk buf */ -" num-res-entries /res-entry * my-resources +" -" tuck >res-len.hi l!" -" tuck >res-len.lo l!" -" tuck >res-pa.hi l!" -" >res-pa.lo l!" -" num-res-entries 1+ to num-res-entries" -" ;" - -/* \ First attempt to claim the whole ramdisk contiguously. */ -/* \ If that doesn't work, try to claim it in smaller chunks */ - -" : attempt-claim" /* ( size -- error? ) */ -" size 0 begin" /* ( next totcl ) */ -" over pagesize phy-claim if" /* ( next totcl ) */ -" swap 2 / window-size" /* ( totcl next' ) */ -" round-up swap" /* ( next' totcl ) */ -" else" /* ( next totcl pa.lo,hi ) */ -" 2over drop xlsplit" /* ( next totcl pa.lo,hi len.lo,hi ) */ -" fill-entry" /* ( next totcl ) */ -" over +" /* ( next totcl ) */ -" then" /* ( next totcl ) */ -" 2dup size - 0>=" /* ( next totcl next comp? ) */ -" swap size max-res-entries /" /* ( next totcl comp? next smallest ) */ -" - 0< or" /* ( next totcl ) */ -" until" /* ( next totcl ) */ -" nip size - 0< if -1 else 0 then" -" ;" - -" : claim-resources" /* ( -- error? ) */ -" attempt-claim if release-resources -1 else 0 then" -" ;" - -/* \ Given a 0-relative disk offset compute the proper physical address */ -" : offset>pa" /* ( disk-offset -- 64bit-pa error? ) */ -" 0 num-res-entries 0 do" /* ( disk-offset 0 ) */ -" i res-entry-len +" /* ( disk-offset len' ) */ -" 2dup - 0< if" /* ( disk-offset len' ) */ -" - i res-entry-len +" /* ( offset-into-pa ) \ briefly -ve */ -" i res-entry-pa + 0" /* ( pa 0 ) */ -" unloop exit" /* ( pa 0 ) */ -" then" /* ( disk-offset len' ) */ -" loop" /* ( disk-offset len' ) */ -" drop -1" /* ( offset error ) */ -" ;" - -/* \ Map the virtual window to the physical-address corresponding to the */ -/* \ given 0-relative disk offset */ -" : get-window" /* ( offset -- va len error? ) */ -" dup offset>pa if" /* ( offset pa ) */ -" -1" /* ( offset pa -1 ) */ -" else" /* ( offset pa ) */ -" dup in-window? 0= if" /* ( offset pa ) */ -" unmap-window" /* ( offset pa ) */ -" over window-size mod - map-window" /* ( offset ) */ -" else" -" drop" -" then" -" window-base over window-size mod +" /* ( offset va ) */ -" swap window-left 0" /* ( va len 0 ) */ -" then" /* ( va len error? ) */ -" ;" - -" headers" - -/* \ Write len1 bytes from src into va. */ -" : partial-write" /* ( src len0 va len1 -- len' ) */ -" rot min dup >r move r>" -" ;" - -/* \ Read len1 bytes from src into va. */ -" : partial-read" /* ( src len0 va len1 -- len' ) */ -" rot min dup >r >r swap r> move r>" -" ;" - -" defer operation ' partial-write is operation" - -/* \ Write or Read len given the src address. The block-operation word */ -/* \ determines the physical address that corresponds to the current file */ -/* \ position, and maps/unmaps the 64K virtual window */ -" : block-operation" /* ( src len acf -- len' ) */ -" is operation" -" 0 -rot begin" /* ( 0 src len ) */ -" dup 0>" /* ( len' src len more? ) */ -" while" /* ( len' src len ) */ -" 2dup filepos" /* ( len' src len src len filepos ) */ -" get-window if" /* ( len' src len src len va len ) */ -" 2drop 2drop 2drop exit" /* ( len' ) */ -" then" /* ( len src len src len va len ) */ -" operation" /* ( len src len len' ) */ -" dup filepos + to filepos" /* ( len src len len' ) */ -" >r r@ - rot r@ + rot r> + rot" /* ( len' src' len' ) */ -" repeat" /* ( len' src' len' ) */ -" 2drop" /* ( len' ) */ -" ;" - -" : range-bad?" /* ( adr -- range-bad? ) */ -" 0 size between 0=" -" ;" - -" : space-left" /* ( -- space-left ) */ -" size filepos -" -" ;" - -" : hex-number" /* ( adr,len -- true | n false ) */ -" base @ >r hex $number r> base !" -" ;" - -" : parse-size" /* ( $nums -- 64bit-size | 0 ) \ poss ',' seperated ints */ -" ascii , left-parse-string" /* ( $num $num ) */ -" hex-number if 2drop 0 exit then" /* ( $num n ) */ -" over 0= if nip nip exit then" /* ( $num n ) */ -" -rot hex-number if drop 0 exit then" /* ( hi lo ) */ -" swap lxjoin" -" ;" - -" : set-size" /* ( adr len -- error? ) */ -" parse-size dup 0= if" /* ( size ) */ -" drop -1" /* ( -1 ) */ -" else" /* ( size ) */ -" window-size round-up" /* ( size' ) */ -" dup to size" /* ( size' ) */ -" d# 512 / to #blocks" /* ( ) */ -" \" nolabel\" my-label pack" /* \ first open cannot have a label */ -" drop 0" /* ( 0 ) */ -" then" /* ( error? ) */ -" ;" - -" : $=" /* (s adr1 len1 adr2 len2 -- same? ) */ -" rot tuck <> if 3drop false exit then" /* ( adr1 adr2 len1 ) */ -" comp 0=" /* ( same? ) */ -" ;" - -" : is-label?" /* ( adr len -- is-label? ) \ $= "nolabel" or <a-z> */ -" dup 1 = if" /* ( adr len ) */ -" drop c@ ascii a ascii z between" /* ( is-label? ) */ -" else" /* ( adr len ) */ -" \" nolabel\" $=" /* ( is-label? ) */ -" then" /* ( is-label? ) */ -" ;" - -" : set-label" /* ( adr len -- error? ) */ -" my-label label-size erase" -" dup 1+ label-size > if" -" 2drop -1" -" else" -" my-label pack drop 0" -" then" -" ;" - -" : process-args" /* ( arg$ -- error? ) */ -" ascii = left-parse-string" /* ( value$ key$ ) */ -" new-disk? if" /* ( value$ key$ ) */ -" 2dup \" size\" $= if" /* ( value$ key$ ) */ -" 2drop set-size exit" /* ( error? ) */ -" then" /* ( value$ key$ ) */ -" else" /* ( value$ key$ ) */ -" 2dup is-label? if" /* ( value$ key$ ) */ -" 2swap 2drop set-label exit" /* ( error? ) */ -" then" /* ( value$ key$ ) */ -" then" /* ( value$ key$ ) */ -" .\" Inappropriate argument \" type cr 2drop -1" /* ( -1 ) */ -" ;" - -/* \ Publish the physical chunks that make up the ramdisk in the */ -/* \ existing property */ -" : create-existing-prop" /* ( -- ) */ -" 0 0 encode-bytes" /* ( adr 0 ) */ -" num-res-entries 0 do" /* ( adr 0 ) */ -" i /res-entry * my-resources + >r" /* ( adr len ) */ -" r@ >res-pa.hi l@ encode-int encode+" /* ( adr len ) */ -" r@ >res-pa.lo l@ encode-int encode+" /* ( adr len ) */ -" r@ >res-len.hi l@ encode-int encode+" /* ( adr len ) */ -" r> >res-len.lo l@ encode-int encode+" /* ( adr len ) */ -" loop" /* ( adr len ) */ -" \" existing\" property" /* ( ) */ -" ;" - -" external" - -" : read" /* ( adr,len -- len' ) */ -" space-left" /* ( adr len space-left ) */ -" min ['] partial-read" /* ( adr len' read-acf ) */ -" block-operation" /* ( len' ) */ -" ;" - -" : write" /* ( adr,len -- len' ) */ -" space-left" /* ( adr len space-left ) */ -" min ['] partial-write" /* ( adr len' write-acf ) */ -" block-operation" /* ( len' ) */ -" ;" - -" : seek" /* ( offset other -- error? ) */ -" offset-high + swap offset-low + swap drop" /* \ "other" arg unused */ -" dup 0< if" /* ( offset ) */ -" size +" /* ( offset' ) */ -" then" /* ( offset' ) */ -" 0 + dup range-bad? if" /* ( offset' ) */ -" drop -1" /* ( -1 ) */ -" else" /* ( offset' ) */ -" to filepos false" /* ( 0 ) */ -" then" /* ( error? ) */ -" ;" - -" : load" /* ( addr -- size ) */ -" \" load\" label-package $call-method" -" ;" - -" : offset" /* ( rel -- abs ) \ needed for device_type = block */ -" offset-low +" -" ;" - -/* \ release resources, initialize data, remove existing property */ -/* \ Can be called with no instance data */ -" : destroy" /* ( -- ) */ -" \" existing\" delete-property" -" 0 to size" -" -1 to new-disk?" -" release-resources" -" ;" - -" : open" /* ( -- flag ) */ -" my-args process-args if" -" 0 exit" /* \ unrecognized arguments */ -" then" -" new-disk? if" -" claim-resources if 0 exit then" /* \ can't claim */ -" create-existing-prop" /* \ advertise resources */ -" 0 to new-disk?" /* \ no longer a new-disk */ -" then" -" claim-window" /* \ claim virtual window */ -" my-label count init-label-package 0= if 0 exit then" -" -1" -" ;" - -" : close" /* ( -- ) */ -" window-base if " -" release-window" -" then" +" 0 instance value current-offset " +" " +" 0 value ramdisk-base-va " +" 0 value ramdisk-size " +" 0 value alloc-size " +" " +" : set-props " +" ramdisk-size encode-int \" size\" property " +" ramdisk-base-va encode-int \" address\" property " +" alloc-size encode-int \" alloc-size\" property " +" ; " +" set-props " +" " +" : current-va ( -- adr ) ramdisk-base-va current-offset + ; " +" " +" external " +" " +" : open ( -- okay? ) " +/* " .\" ramdisk-open\" cr " */ +" true " +" ; " +" " +" : close ( -- ) " +" ; " +" " +" : seek ( off.low off.high -- error? ) " +/* " 2dup .\" ramdisk-seek: \" .x .x " */ +" drop dup ramdisk-size > if " +/* " .\" fail\" cr " */ +" drop true exit ( failed ) " +" then " +" to current-offset false ( succeeded ) " +/* " .\" OK\" cr " */ " ; " +" " +" : read ( addr len -- actual-len ) " +/* " 2dup .\" ramdisk-read: \" .x .x " */ +" dup current-offset + ( addr len new-off ) " +" dup ramdisk-size > if " +" ramdisk-size - - ( addr len' ) " +" ramdisk-size ( addr len new-off ) " +" then -rot ( new-off addr len ) " +" tuck current-va -rot move ( new-off len ) " +" swap to current-offset ( len ) " +/* " dup .x cr " */ +" ; " +" " +" : create ( alloc-sz base size -- ) " +" to ramdisk-size " +" to ramdisk-base-va " +" to alloc-size " +" set-props " +" ; " +" " "finish-device " +"pop-package " + +"\" /%s\" 2dup dev-open 0= if " +" open-abort " +"then 2drop " + +/* %x %x %x will be replaced by alloc-sz, base, size respectively */ +"h# %x h# %x h# %x ( alloc-sz base size ) " +"\" create\" dev-ih $call-method ( ) " +"dev-close " + +; + +char ramdisk_bootable[] = + +"\" /chosen\" get-package push-package " +" \" nfs\" encode-string \" fstype\" property " +" \" /%s\" encode-string \" bootarchive\" property " +"pop-package " + +" h# %x d# 512 + to load-base init-program " +; + +#define BOOT_ARCHIVE_ALLOC_SIZE (32 * 1024 * 1024) /* 32 MB */ +#define BOOTFS_VIRT ((caddr_t)0x50f00000) +#define ROOTFS_VIRT ((caddr_t)0x51000000) + +struct ramdisk_attr { + char *rd_name; + caddr_t rd_base; + size_t rd_size; +} ramdisk_attr[] = { + RD_BOOTFS, BOOTFS_VIRT, 0, + RD_ROOTFS, ROOTFS_VIRT, 0, + 0 +}; + +static struct ramdisk_attr * +ramdisk_lookup(char *ramdisk_name) +{ + int i; -"pop-package" + for (i = 0; ramdisk_attr[i].rd_name != 0; i++) { + if (strcmp(ramdisk_name, ramdisk_attr[i].rd_name) == 0) { + return (&ramdisk_attr[i]); + } + } + return (NULL); +} -; /* end of ramdisk_fth[] initialization */ +static void +ramdisk_free_mem(caddr_t addr, size_t size) +{ + caddr_t end_addr; + for (end_addr = addr + size; addr < end_addr; + addr += BOOT_ARCHIVE_ALLOC_SIZE) { + prom_free(addr, MIN(BOOT_ARCHIVE_ALLOC_SIZE, end_addr - addr)); + } +} /* - * Create an actual ramdisk instance. + * Allocate memory for ramdisk image. */ -static void -create_ramdisk_node(const char *ramdisk_name) +static caddr_t +ramdisk_alloc_mem(caddr_t addr, size_t size) +{ + caddr_t virt = addr; + caddr_t end_addr; + + for (end_addr = virt + size; virt < end_addr; + virt += BOOT_ARCHIVE_ALLOC_SIZE) { + if (prom_alloc(virt, + MIN(BOOT_ARCHIVE_ALLOC_SIZE, end_addr - virt), + 1) == NULL) { + ramdisk_free_mem(addr, virt - addr); + return (NULL); + } + } + return (addr); +} + +caddr_t +create_ramdisk(char *ramdisk_name, size_t size, char **devpath) { char *fth_buf; size_t buf_size; + struct ramdisk_attr *rdp; + char tdevpath[80]; + caddr_t virt; + static int need_preamble = 1; + + /* + * lookup ramdisk name. + */ + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); + + virt = rdp->rd_base; + + /* + * Allocate memory. + */ + size = roundup(size, PAGESIZE); + if (ramdisk_alloc_mem(virt, size) == NULL) + prom_panic("can't alloc ramdisk memory"); + + rdp->rd_size = size; - buf_size = sizeof (ramdisk_fth) + strlen(ramdisk_name); + if (need_preamble) { + prom_interpret(ramdisk_preamble_fth, 0, 0, 0, 0, 0); + need_preamble = 0; + } + + /* + * add some space to the size to accommodate a few words in the + * snprintf() below. + */ + buf_size = sizeof (ramdisk_fth) + 80; fth_buf = bkmem_alloc(buf_size); - if (fth_buf == NULL) { + if (fth_buf == NULL) prom_panic("unable to allocate Forth buffer for ramdisk"); - } - (void) snprintf(fth_buf, buf_size, ramdisk_fth, ramdisk_name); + (void) snprintf(fth_buf, buf_size, ramdisk_fth, + ramdisk_name, ramdisk_name, + BOOT_ARCHIVE_ALLOC_SIZE, virt, size); prom_interpret(fth_buf, 0, 0, 0, 0, 0); - bkmem_free(fth_buf, buf_size); + + if (devpath != NULL) { + (void) snprintf(tdevpath, sizeof (tdevpath), "/%s:nolabel", + ramdisk_name); + *devpath = strdup(tdevpath); + } + + return (virt); } -int -create_ramdisk(const char *ramdisk_name, size_t size, char **device_path) +void +destroy_ramdisk(char *ramdisk_name) { - static int first_time = 1; - char buf[OBP_MAXPATHLEN]; - ihandle_t ih; + struct ramdisk_attr *rdp; /* - * Ensure that size is a multiple of page size (rounded up). + * lookup ramdisk name. */ - size = ptob(btopr(size)); + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); -/* EXPORT DELETE START */ - bootlog("wanboot", BOOTLOG_VERBOSE, "Creating ramdisk, size=0x%lx", - size); -/* EXPORT DELETE END */ - - if (strcmp(ramdisk_name, RD_ROOTFS) == 0 || - strcmp(ramdisk_name, RD_BOOTFS) == 0) { + ramdisk_free_mem(rdp->rd_base, rdp->rd_size); + rdp->rd_size = 0; +} - if (first_time) { - first_time = 0; +/* + * change cwp! to drop in the 2nd word of (init-program) - really + * init-c-stack, but that word has no header. + * (you are not expected to undertsnad this) + */ +char obpfix[] = "' drop ' cwp! ' (init-program) >body ta1+ token@ (patch"; +char obpver[OBP_MAXPROPNAME]; +const char badver[] = "OBP 4.27."; - create_ramdisk_node(RD_ROOTFS); - create_ramdisk_node(RD_BOOTFS); - } - (void) snprintf(buf, sizeof (buf), "/%s:nolabel", ramdisk_name); - *device_path = strdup(buf); +void +boot_ramdisk(char *ramdisk_name) +{ + char *fth_buf; + size_t buf_size; + struct ramdisk_attr *rdp; + void do_sg_go(void); - if (*device_path != NULL) { - (void) snprintf(buf, sizeof (buf), "/%s:size=%x,%x", - ramdisk_name, - (uint32_t)(size >> 32), (uint32_t)size); + /* + * OBP revs 4.27.0 to 4.27.8 started using + * windowed regs for the forth kernel, but + * init-program still blindly 0'd %cwp, which + * causes predictably disaterous consequences + * when called with %cwp != 0. + * + * We detect and fix this here + */ + if (prom_version_name(obpver, OBP_MAXPROPNAME) != -1 && + strncmp(obpver, badver, sizeof (badver) - 1) == 0) { + char ch = obpver[sizeof (badver) - 1]; - if ((ih = prom_open(buf)) != 0) { - return (ih); - } + if (ch >= '0' && ch <= '8') { + prom_interpret(obpfix, 0, 0, 0, 0, 0); } } -/* EXPORT DELETE START */ - bootlog("wanboot", BOOTLOG_CRIT, "Cannot create ramdisk \"%s\"", - ramdisk_name); -/* EXPORT DELETE END */ - prom_panic("create_ramdisk: fatal error"); - /* NOTREACHED */ + /* close all open devices */ + closeall(1); + + /* + * lookup ramdisk name. + */ + if ((rdp = ramdisk_lookup(ramdisk_name)) == NULL) + prom_panic("invalid ramdisk name"); + + /* + * add some space to the size to accommodate a few words in the + * snprintf() below. + */ + buf_size = sizeof (ramdisk_bootable) + 80; + + fth_buf = bkmem_alloc(buf_size); + if (fth_buf == NULL) + prom_panic("unable to allocate Forth buffer for ramdisk"); + + (void) snprintf(fth_buf, buf_size, ramdisk_bootable, + ramdisk_name, rdp->rd_base); + + prom_interpret(fth_buf, 0, 0, 0, 0, 0); + + /* + * Ugh Serengeti proms don't execute C programs + * in init-program, and 'go' doesn't work when + * launching a second C program (inetboot itself + * was launched as the 1st C program). Nested fcode + * programs work, but that doesn't help the kernel. + */ + do_sg_go(); +} + +void +do_sg_go() +{ + pnode_t chosen = prom_chosennode(); + Elf64_Ehdr *ehdr; + Elf64_Addr entry; + uint32_t eadr; + extern int is_sg; + extern caddr_t sg_addr; + extern size_t sg_len; + + if (!is_sg) + prom_panic("do_sg_go"); + + /* + * The ramdisk bootblk left a pointer to the elf image + * in 'elfheader-address' Use it to find the kernel's + * entry point. + */ + if (prom_getprop(chosen, "elfheader-address", (caddr_t)&eadr) == -1) + prom_panic("no elf header property"); + ehdr = (Elf64_Ehdr *)(uintptr_t)eadr; + if (ehdr->e_machine != EM_SPARCV9) + prom_panic("bad ELF header"); + entry = ehdr->e_entry; + + /* + * free extra bootmem + */ + prom_free(sg_addr, sg_len); + + /* + * Use pre-newboot's exitto64() to launch the kernel + */ + exitto64((int (*)())entry, NULL); + prom_panic("exitto returned"); } diff --git a/usr/src/psm/stand/boot/sparc/common/ramdisk.h b/usr/src/psm/stand/boot/sparc/common/ramdisk.h index 77eb021a11..561b210f75 100644 --- a/usr/src/psm/stand/boot/sparc/common/ramdisk.h +++ b/usr/src/psm/stand/boot/sparc/common/ramdisk.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -39,9 +38,11 @@ extern "C" { * Ramdisk names */ #define RD_BOOTFS "ramdisk-bootfs" -#define RD_ROOTFS "ramdisk-rootfs" +#define RD_ROOTFS "ramdisk-root" -extern int create_ramdisk(const char *, size_t, char **); +extern caddr_t create_ramdisk(char *, size_t, char **); +extern void destroy_ramdisk(char *); +extern void boot_ramdisk(char *); #ifdef __cplusplus } diff --git a/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c b/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c index 707c7ff5c2..a68c6d0d47 100644 --- a/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c +++ b/usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -104,6 +103,15 @@ static caddr_t free_addr[N_FREELIST]; static caddr_t top_bootmem = MAPPEDMEM_MINTOP; static caddr_t top_resvmem, scratchresvp; +/* + * with newboot, boot goes away when it launches the client, + * so we can safely extend bootmem on sg, and give it back + * before we die. + */ +int is_sg; +caddr_t sg_addr; +size_t sg_len; + static int impl_name(char *buf, size_t bufsz) { @@ -212,8 +220,13 @@ resalloc_init(void) * but we don't have the ability to check for the firmware version here. */ if (strcmp(iarch, "SUNW,Sun-Fire") == 0 || - strcmp(iarch, "SUNW,Netra-T12") == 0) - return; + strcmp(iarch, "SUNW,Netra-T12") == 0) { + is_sg = 1; + sg_addr = MAPPEDMEM_MINTOP; + sg_len = MAPPEDMEM_FULLTOP - MAPPEDMEM_MINTOP; + if (prom_alloc(sg_addr, sg_len, 1) != sg_addr) + prom_panic("can't extend sg bootmem"); + } top_bootmem = MAPPEDMEM_FULLTOP; @@ -264,7 +277,7 @@ resalloc(enum RESOURCES type, size_t bytes, caddr_t virthint, int align) if (vaddr == (caddr_t)virthint) return (vaddr); printf("Alloc of 0x%lx bytes at 0x%p refused.\n", - bytes, (void *)virthint); + bytes, (void *)virthint); return ((caddr_t)0); /*NOTREACHED*/ diff --git a/usr/src/psm/stand/boot/sparc/common/ufsconf.c b/usr/src/psm/stand/boot/sparc/common/ufsconf.c deleted file mode 100644 index 5d0195e5f3..0000000000 --- a/usr/src/psm/stand/boot/sparc/common/ufsconf.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/param.h> -#include <sys/sysmacros.h> -#include <sys/obpdefs.h> -#include <sys/stat.h> -#include <sys/bootvfs.h> -#include <sys/bootdebug.h> -#include <sys/promif.h> -#include <sys/salib.h> -#include "boot_plat.h" - -/* - * filesystem switch table, UFS - */ -extern struct boot_fs_ops boot_ufs_ops; -struct boot_fs_ops *boot_fsw[] = { - &boot_ufs_ops, -}; - -int boot_nfsw = sizeof (boot_fsw) / sizeof (boot_fsw[0]); -int nfs_readsize = 0; - -static char *ufsname = "ufs"; - -/* ARGSUSED */ -char * -set_fstype(char *v2path, char *bpath) -{ - set_default_fs(ufsname); - return (ufsname); -} diff --git a/usr/src/psm/stand/boot/sparc/common/wanboot.c b/usr/src/psm/stand/boot/sparc/common/wanboot.c index 236746d9f6..2c8121f7a6 100644 --- a/usr/src/psm/stand/boot/sparc/common/wanboot.c +++ b/usr/src/psm/stand/boot/sparc/common/wanboot.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -77,7 +76,8 @@ /* * Experimentation has shown that an 8K download buffer is optimal */ -static char buffer[8192]; +#define HTTP_XFER_SIZE 8192 +static char buffer[HTTP_XFER_SIZE]; bc_handle_t bc_handle; @@ -428,7 +428,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) lenstr = http_get_header_value(handle, CONTENT_LENGTH); if (lenstr == NULL) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: error getting digest length", what); + "%s: error getting digest length", what); return (1); } digest_size = (size_t)strtol(lenstr, NULL, 10); @@ -439,8 +439,8 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) */ if (digest_size != HMAC_DIGEST_LEN) { bootlog("wanboot", BOOTLOG_CRIT, - "%s: error validating response - invalid digest size", - what); + "%s: error validating response - invalid digest size", + what); return (-1); } @@ -449,7 +449,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) */ if (read_bytes(handle, (char *)sdigest, digest_size) != 0) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: error reading digest", what); + "%s: error reading digest", what); return (1); } @@ -469,7 +469,7 @@ read_digest(const char *what, http_handle_t handle, unsigned char *sdigest) * 1 = HTTP download error */ static int -write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, +write_msg_to_ramdisk(const char *what, caddr_t addr, http_handle_t handle, size_t ramdisk_size, off_t *offset, SHA1_CTX *sha) { int len; @@ -497,13 +497,14 @@ write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, "Continuing read of %s file system (%ld kB)", what, ramdisk_size / 1024); } - for (ret = 0; ret == 0 && *offset < ramdisk_size; *offset += len) { + for (ret = 0; ret == 0 && *offset < ramdisk_size; + *offset += len, addr += len) { nleft = ramdisk_size - *offset; if (nleft > sizeof (buffer)) nleft = sizeof (buffer); - len = http_read_body(handle, buffer, nleft); + len = http_read_body(handle, addr, nleft); if (len <= 0) { print_errors("http_read_body", handle); /* @@ -517,13 +518,7 @@ write_msg_to_ramdisk(const char *what, int fd, http_handle_t handle, ret = 1; } if (sha != NULL) { - HMACUpdate(sha, (uchar_t *)buffer, (size_t)len); - } - if (prom_write(fd, buffer, (size_t)len, 0, 0) != (ssize_t)len) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: write to ramdisk failed", what); - ret = -1; - continue; + HMACUpdate(sha, (uchar_t *)addr, (size_t)len); } if (bootlog_progress == bootlog_message_interval) { bootlog("wanboot", BOOTLOG_PROGRESS, @@ -790,10 +785,10 @@ establish_http_connection(const char *what, http_handle_t *handlep, if ((offset == 0 && resp->code != 200) || (offset != 0 && resp->code != 206)) { bootlog("wanboot", BOOTLOG_ALERT, - "%s: Request returned code %d", what, resp->code); + "%s: Request returned code %d", what, resp->code); if (resp->statusmsg != NULL && resp->statusmsg[0] != '\0') bootlog("wanboot", BOOTLOG_ALERT, - "%s", resp->statusmsg); + "%s", resp->statusmsg); http_free_respinfo(resp); (void) http_srv_close(*handlep); return (1); @@ -929,7 +924,7 @@ get_miniinfo(const url_t *server_url, size_t *mini_size, } if ((ret = process_miniinfo(handle, mini_size, - sdigest)) > 0) { + sdigest)) > 0) { if (!wanboot_retry(++retry_cnt, retry_max)) { (void) http_srv_close(handle); break; @@ -985,10 +980,10 @@ process_miniroot(http_handle_t handle, hash_type_t htype, { static SHA1_CTX sha; static size_t miniroot_size; - static int fd = -1; + static caddr_t miniroot_vaddr = NULL; int ret; - if (fd == -1) { + if (miniroot_vaddr == NULL) { if (htype == HASH_HMAC_SHA1) { bootlog("wanboot", BOOTLOG_INFO, "%s: Authentication will use HMAC-SHA1", MINIROOT); @@ -997,23 +992,14 @@ process_miniroot(http_handle_t handle, hash_type_t htype, miniroot_size = length; - fd = create_ramdisk(RD_ROOTFS, miniroot_size, devpath); + miniroot_vaddr = create_ramdisk(RD_ROOTFS, miniroot_size, + devpath); } - if (prom_seek(fd, *offset) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", MINIROOT); - return (-1); - } + miniroot_vaddr += *offset; - if ((ret = write_msg_to_ramdisk(MINIROOT, fd, handle, miniroot_size, - offset, (htype == HASH_NONE) ? NULL : &sha)) != 0) { - if (ret < 0) { - /* - * Reentry not supported. - */ - (void) prom_close(fd); - } + if ((ret = write_msg_to_ramdisk(MINIROOT, miniroot_vaddr, handle, + miniroot_size, offset, (htype == HASH_NONE) ? NULL : &sha)) != 0) { return (ret); } @@ -1021,8 +1007,6 @@ process_miniroot(http_handle_t handle, hash_type_t htype, HMACFinal(&sha, g_hash_key, WANBOOT_HMAC_KEY_SIZE, cdigest); } - (void) prom_close(fd); - return (0); } @@ -1177,9 +1161,8 @@ encr_fini(encr_type_t etype, void *eh) } /* - * This routine is called by process_wanbootfs() to read the encrypted - * file system from ramdisk and decrypt it. This routine will rewrite - * the file system back to ramdisk in place. The method of decryption + * This routine is called by process_wanbootfs() to decrypt the encrypted + * file system from ramdisk in place. The method of decryption * (algorithm) will have already been determined by process_wanbootfs() * and the cbc_handle passed to this routine will already have been * initialized appropriately. @@ -1189,45 +1172,13 @@ encr_fini(encr_type_t etype, void *eh) * 0 = Success */ static int -decrypt_wanbootfs(int fd, cbc_handle_t *ch, uint8_t *iv, - size_t block_size, size_t wanbootfs_size) +decrypt_wanbootfs(caddr_t addr, cbc_handle_t *ch, uint8_t *iv, + size_t wanbootfs_size) { - size_t total; - size_t len; - size_t nleft; - size_t max_read_size; - - max_read_size = (sizeof (buffer) / block_size) * block_size; - for (total = 0; total < wanbootfs_size; total += len) { - if (prom_seek(fd, total) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - nleft = wanbootfs_size - total; - if (nleft > max_read_size) - nleft = max_read_size; - len = prom_read(fd, buffer, nleft, 0, 0); - if (len != nleft) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_read error", WANBOOTFS); - return (-1); - } - if (!cbc_decrypt(ch, (uint8_t *)buffer, len, iv)) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: cbc decrypt error", WANBOOTFS); - return (-1); - } - if (prom_seek(fd, total) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - if (prom_write(fd, buffer, len, 0, 0) != len) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_write error", WANBOOTFS); - return (-1); - } + if (!cbc_decrypt(ch, (uint8_t *)addr, wanbootfs_size, iv)) { + bootlog("wanboot", BOOTLOG_CRIT, + "%s: cbc decrypt error", WANBOOTFS); + return (-1); } return (0); } @@ -1279,7 +1230,7 @@ process_wanbootfs(http_handle_t handle, char **devpath, size_t wanbootfs_size; size_t block_size; off_t offset; - static int fd = -1; + static caddr_t bootfs_vaddr = NULL; int ret; switch (hash_type) { @@ -1371,25 +1322,16 @@ process_wanbootfs(http_handle_t handle, char **devpath, * the already existing ramdisk and seek back to the * beginning of the file. */ - if (fd == -1) { - fd = create_ramdisk(RD_BOOTFS, wanbootfs_size, devpath); + if (bootfs_vaddr == NULL) { + bootfs_vaddr = create_ramdisk(RD_BOOTFS, wanbootfs_size, + devpath); } offset = 0; - if (prom_seek(fd, offset) == -1) { - bootlog("wanboot", BOOTLOG_CRIT, - "%s: prom_seek error", WANBOOTFS); - return (-1); - } - if ((ret = write_msg_to_ramdisk(WANBOOTFS, fd, handle, wanbootfs_size, - &offset, (hash_type == HASH_NONE) ? NULL : &sha)) != 0) { - if (ret < 0) { - /* - * Reentry not supported. - */ - (void) prom_close(fd); - } + if ((ret = write_msg_to_ramdisk(WANBOOTFS, bootfs_vaddr, handle, + wanbootfs_size, &offset, (hash_type == HASH_NONE) ? NULL : &sha)) + != 0) { return (ret); } @@ -1401,18 +1343,14 @@ process_wanbootfs(http_handle_t handle, char **devpath, * If encrypted, then decrypt it. */ if (encr_type != ENCR_NONE) { - ret = decrypt_wanbootfs(fd, &ch, iv, block_size, - wanbootfs_size); + ret = decrypt_wanbootfs(bootfs_vaddr, &ch, iv, wanbootfs_size); if (ret != 0) { encr_fini(encr_type, eh); - (void) prom_close(fd); return (-1); } encr_fini(encr_type, eh); } - (void) prom_close(fd); - return (read_digest(WANBOOTFS, handle, sdigest)); } @@ -1472,7 +1410,7 @@ get_wanbootfs(const url_t *server_url) bzero(cdigest, sizeof (cdigest)); do { if ((ret = establish_http_connection(WANBOOTFS, &handle, - &req_url, 0)) < 0) { + &req_url, 0)) < 0) { break; } else if (ret > 0) { if (wanboot_retry(++retry_cnt, retry_max)) { @@ -1483,7 +1421,7 @@ get_wanbootfs(const url_t *server_url) } if ((ret = process_wanbootfs(handle, &devpath, - cdigest, sdigest)) > 0) { + cdigest, sdigest)) > 0) { if (!wanboot_retry(++retry_cnt, retry_max)) { (void) http_srv_close(handle); break; @@ -1498,7 +1436,7 @@ get_wanbootfs(const url_t *server_url) * Validate the computed digest against the one received. */ if (ret != 0 || - !verify_digests(WANBOOTFS, cdigest, sdigest)) { + !verify_digests(WANBOOTFS, cdigest, sdigest)) { bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1530,7 +1468,7 @@ get_wanbootfs(const url_t *server_url) */ if ((fd = open(WANBOOTFS_NONCE_FILE, O_RDONLY)) == -1) { bootlog("wanboot", BOOTLOG_CRIT, - "No nonce found in the wanboot file system"); + "No nonce found in the wanboot file system"); bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1540,7 +1478,7 @@ get_wanbootfs(const url_t *server_url) bcmp(nonce, buf, NONCELEN) != 0) { (void) close(fd); bootlog("wanboot", BOOTLOG_CRIT, - "Invalid nonce found in the wanboot file system"); + "Invalid nonce found in the wanboot file system"); bootlog("wanboot", BOOTLOG_CRIT, "The wanboot file system download aborted"); return (-1); @@ -1633,7 +1571,7 @@ init_netdev(char *bpath) * * - The wanboot miniroot is downloaded over http/https into the rootfs * ramdisk. The bootfs filesystem is unmounted, and the rootfs filesystem - * is mounted. + * is booted. */ /* EXPORT DELETE END */ /*ARGSUSED*/ @@ -1723,39 +1661,7 @@ bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) */ (void) unmountroot(); - /* - * Mount the miniroot. - */ - if (determine_fstype_and_mountroot(miniroot_path) != VFS_SUCCESS) { - bootlog("wanboot", BOOTLOG_CRIT, - "Could not mount miniroot filesystem"); - return (-1); - } - bootlog("wanboot", BOOTLOG_VERBOSE, "The miniroot has been mounted"); - - v2path = "/ramdisk-rootfs:a"; - bootlog("wanboot", BOOTLOG_VERBOSE, "device path '%s'", v2path); - - /* - * kernname (default-name) might have changed if mountroot() called - * boot_nfs_mountroot(), and it called set_default_filename(). - */ - if (! user_specified_filename) - (void) strcpy(filename, kernname); - - bootlog("wanboot", BOOTLOG_VERBOSE, - "standalone = `%s', args = `%s'", filename, bargs); - - set_client_bootargs(filename, bargs); - - /* - * We're done with the mac interface that was initialized by - * mac_init() inside init_netdev(). - */ - mac_fini(); - - bootconf_end(&bc_handle); - bootinfo_end(); + boot_ramdisk(RD_ROOTFS); /* EXPORT DELETE END */ return (0); diff --git a/usr/src/psm/stand/boot/sparcv9/Makefile.com b/usr/src/psm/stand/boot/sparcv9/Makefile.com index aac89a4000..2417ee62ed 100644 --- a/usr/src/psm/stand/boot/sparcv9/Makefile.com +++ b/usr/src/psm/stand/boot/sparcv9/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/boot/sparcv9/Makefile.com @@ -40,9 +39,9 @@ MACH_DIR = ../../sparc/common PLAT_DIR = . BOOT_DIR = $(SRC)/psm/stand/boot -BOOT_SRC = boot.c wanboot.c +BOOT_SRC = inetboot.c wanboot.c -CONF_SRC = ufsconf.c nfsconf.c hsfsconf.c wbfsconf.c wbcli.c +CONF_SRC = nfsconf.c wbfsconf.c wbcli.c TOP_CMN_C_SRC = getoptstr.c @@ -50,7 +49,7 @@ MISC_SRC = ramdisk.c CMN_C_SRC = heap_kmem.c readfile.c -MACH_C_SRC = boot_plat.c bootops.c bootprop.c boot_services.c bootflags.c +MACH_C_SRC = boot_plat.c bootops.c bootprop.c bootflags.c MACH_C_SRC += get.c BOOT_OBJS = $(BOOT_SRC:%.c=%.o) @@ -120,9 +119,6 @@ LIBPROM_LIBS += libprom.a # The following libraries are built in LIBSYS_DIR # LIBSYS_DIR += $(SYSLIBDIR) -LIBSYS_LIBS += libufs.a libhsfs.a libnfs.a libxdr.a \ - libsock.a libinet.a libtcp.a libtcpstubs.a libscrypt.a \ - libwanboot.a libsa.a libmd5.a libnvpair.a # # Used to convert ELF to an a.out and ensure alignment @@ -139,22 +135,13 @@ ELFCONV = ./$(STRIPALIGN) # Default value .PARALLEL: $(OBJS) $(CONF_OBJS) $(MISC_OBJS) $(SRT0_OBJ) $(BOOT_OBJS) .PARALLEL: $(L_OBJS) $(CONF_L_OBJS) $(MISC_L_OBJS) $(SRT0_L_OBJ) \ $(BOOT_L_OBJS) -.PARALLEL: $(UFSBOOT) $(HSFSBOOT) $(NFSBOOT) $(WANBOOT) +.PARALLEL: $(NFSBOOT) $(WANBOOT) -all: $(ELFCONV) $(UFSBOOT) $(HSFSBOOT) $(NFSBOOT) $(WANBOOT) +all: $(ELFCONV) $(NFSBOOT) $(WANBOOT) $(STRIPALIGN): $(CMN_DIR)/$$(@).c $(NATIVECC) -o $@ $(CMN_DIR)/$@.c -# 4.2 ufs filesystem booter -# -# Libraries used to build ufsboot -# -LIBUFS_LIBS = libufs.a libnames.a libsa.a libprom.a $(LIBPLAT_LIBS) -UFS_LIBS = $(LIBUFS_LIBS:lib%.a=-l%) -UFS_DIRS = $(LIBNAME_DIR:%=-L%) $(LIBSYS_DIR:%=-L%) -UFS_DIRS += $(LIBPLAT_DIR:%=-L%) $(LIBPROM_DIR:%=-L%) - # # Note that the presumption is that someone has already done a `make # install' from usr/src/stand/lib, such that all of the standalone @@ -167,39 +154,6 @@ L_LIBDEPS= $(LIBPROM_DIR)/llib-lprom.ln $(LIBPLAT_DEP_L) \ $(LIBNAME_DIR)/llib-lnames.ln # -# Loader flags used to build ufsboot -# -UFS_MAPFILE = $(MACH_DIR)/mapfile -UFS_LDFLAGS = -dn -M $(UFS_MAPFILE) -e _start $(UFS_DIRS) -UFS_L_LDFLAGS = $(UFS_DIRS) - -# -# Object files used to build ufsboot -# -UFS_SRT0 = $(SRT0_OBJ) -UFS_OBJS = $(OBJS) ufsconf.o boot.o -UFS_L_OBJS = $(UFS_SRT0:%.o=%.ln) $(UFS_OBJS:%.o=%.ln) - -# -# Build rules to build ufsboot -# - -$(UFSBOOT).elf: $(UFS_MAPFILE) $(UFS_SRT0) $(UFS_OBJS) $(LIBDEPS) - $(LD) $(UFS_LDFLAGS) -o $@ $(UFS_SRT0) $(UFS_OBJS) $(UFS_LIBS) - $(MCS) -d $@ - $(POST_PROCESS) - $(POST_PROCESS) - $(MCS) -c $@ - -$(UFSBOOT): $(UFSBOOT).elf - $(RM) $@; cp $@.elf $@ - $(STRIP) $@ - -$(UFSBOOT)_lint: $(L_LIBDEPS) $(UFS_L_OBJS) - @echo "" - @echo ufsboot lint: global crosschecks: - $(LINT.c) $(UFS_L_LDFLAGS) $(UFS_L_OBJS) $(UFS_LIBS) - # WANboot booter # # Libraries used to build wanboot @@ -259,44 +213,6 @@ $(WANBOOT)_lint: $(L_LIBDEPS) $(WAN_L_OBJS) # High-sierra filesystem booter. Probably doesn't work. -# -# Libraries used to build hsfsboot -# -LIBHSFS_LIBS = libhsfs.a libnames.a libsa.a libprom.a $(LIBPLAT_LIBS) -HSFS_LIBS = $(LIBHSFS_LIBS:lib%.a=-l%) -HSFS_DIRS = $(LIBNAME_DIR:%=-L%) $(LIBSYS_DIR:%=-L%) -HSFS_DIRS += $(LIBPLAT_DIR:%=-L%) $(LIBPROM_DIR:%=-L%) - -# -# Loader flags used to build hsfsboot -# -HSFS_MAPFILE = $(MACH_DIR)/mapfile -HSFS_LDFLAGS = -dn -M $(HSFS_MAPFILE) -e _start $(HSFS_DIRS) -HSFS_L_LDFLAGS = $(HSFS_DIRS) - -# -# Object files used to build hsfsboot -# -HSFS_SRT0 = $(SRT0_OBJ) -HSFS_OBJS = $(OBJS) hsfsconf.o boot.o -HSFS_L_OBJS = $(HSFS_SRT0:%.o=%.ln) $(HSFS_OBJS:%.o=%.ln) - -$(HSFSBOOT).elf: $(HSFS_MAPFILE) $(HSFS_SRT0) $(HSFS_OBJS) $(LIBDEPS) - $(LD) $(HSFS_LDFLAGS) -o $@ $(HSFS_SRT0) $(HSFS_OBJS) $(HSFS_LIBS) - $(MCS) -d $@ - $(POST_PROCESS) - $(POST_PROCESS) - $(MCS) -c $@ - -$(HSFSBOOT): $(HSFSBOOT).elf - $(RM) $(@); cp $@.elf $@ - $(STRIP) $@ - -$(HSFSBOOT)_lint: $(HSFS_L_OBJS) $(L_LIBDEPS) - @echo "" - @echo hsfsboot lint: global crosschecks: - $(LINT.c) $(HSFS_L_LDFLAGS) $(HSFS_L_OBJS) $(HSFS_LIBS) - # NFS booter # @@ -320,7 +236,7 @@ NFS_L_LDFLAGS = $(NFS_DIRS) # Object files used to build inetboot # NFS_SRT0 = $(SRT0_OBJ) -NFS_OBJS = $(OBJS) nfsconf.o boot.o +NFS_OBJS = $(OBJS) nfsconf.o inetboot.o ramdisk.o NFS_L_OBJS = $(NFS_SRT0:%.o=%.ln) $(NFS_OBJS:%.o=%.ln) $(NFSBOOT).elf: $(ELFCONV) $(NFS_MAPFILE) $(NFS_SRT0) $(NFS_OBJS) $(LIBDEPS) @@ -350,13 +266,13 @@ install: $(ROOT_PSM_WANBOOT) clean: $(RM) make.out lint.out $(RM) $(OBJS) $(CONF_OBJS) $(MISC_OBJS) $(BOOT_OBJS) $(SRT0_OBJ) - $(RM) $(NFSBOOT).elf $(UFSBOOT).elf $(HSFSBOOT).elf $(WANBOOT).elf + $(RM) $(NFSBOOT).elf $(WANBOOT).elf $(RM) $(L_OBJS) $(CONF_L_OBJS) $(MISC_L_OBJS) $(BOOT_L_OBJS) \ $(SRT0_L_OBJ) clobber: clean - $(RM) $(UFSBOOT) $(HSFSBOOT) $(NFSBOOT) $(WANBOOT) $(STRIPALIGN) + $(RM) $(NFSBOOT) $(WANBOOT) $(STRIPALIGN) -lint: $(UFSBOOT)_lint $(NFSBOOT)_lint $(WANBOOT)_lint +lint: $(NFSBOOT)_lint $(WANBOOT)_lint include $(BOOTSRCDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/Makefile b/usr/src/psm/stand/bootblks/Makefile index 81530b7c2b..b900dfb83d 100644 --- a/usr/src/psm/stand/bootblks/Makefile +++ b/usr/src/psm/stand/bootblks/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,14 +21,14 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/bootblks/Makefile # include ../../../Makefile.master -SUBDIRS = ufs hsfs +SUBDIRS = ufs hsfs zfs all install clean clobber lint: $(SUBDIRS) diff --git a/usr/src/psm/stand/bootblks/Makefile.1275 b/usr/src/psm/stand/bootblks/Makefile.1275 index 1066fef16c..63f4ebcff9 100644 --- a/usr/src/psm/stand/bootblks/Makefile.1275 +++ b/usr/src/psm/stand/bootblks/Makefile.1275 @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,8 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994, by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/bootblks/Makefile.1275 # @@ -31,23 +31,41 @@ # Sources and objects used to build the Forth-based bootblock # for all Sun OpenFirmware machines (IEEE Std. 1275) # -# Same names for both filesystems. +# Common pieces # -FORTH_SRC = boot_1275.fth -FORTH_FCODE = $(FORTH_SRC:%.fth=%.fcode) +BOOT_SRC = util.fth boot.fth +RD_SRC = rd.fth + +RD_FCODE = rd.fcode + +MKBB = mkbb +MKBB_SH = $(BASEDIR)/common/mkbb.sh + +%.fcode: $(BASEDIR)/common/%.fth + $(TOKENIZE) $< # # Targets # -$(PROG): $(FORTH_FCODE) +all: $(PROG) + +$(MKBB): $(MKBB_SH) + $(RM) $@ + cat $(MKBB_SH) > $@ + chmod +x $@ + +$(FS_BB): $(MKBB) $(FS_FCODE) $(RD_FCODE) + $(MKBB) $(FS_FCODE) $(RD_FCODE) $(FS_BB) + +$(PROG): $(FS_BB) @-$(RM) $@ - cp -p $(FORTH_FCODE) $@ + cp -p $(FS_BB) $@ clean: - -$(RM) $(FORTH_FCODE) + -$(RM) $(FS_FCODE) $(RD_FCODE) -clobber: clean - -$(RM) $(PROG) +clobber: clean + -$(RM) $(PROG) $(FS_BB) lint: FRC diff --git a/usr/src/psm/stand/bootblks/common/boot.fth b/usr/src/psm/stand/bootblks/common/boot.fth new file mode 100644 index 0000000000..997efb6b9f --- /dev/null +++ b/usr/src/psm/stand/bootblks/common/boot.fth @@ -0,0 +1,609 @@ +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ + +id: %Z%%M% %I% %E% SMI +purpose: boot block for OBP systems +copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved + + +headerless +d# 1024 dup * constant 1meg +d# 4 1meg * constant 4meg +d# 32 1meg * constant 32meg + +headers +" /" get-package constant root-ph + +0 value fs-ih +false value nested? +0 value file-sz + +/buf-len buffer: boot-dev +: boot-dev$ ( -- dev$ ) boot-dev cscount ; + +: loader-base ( -- base ) + nested? if + h# 5000.0000 + else + h# 5100.0000 + then +; + + +\ +\ methods we expect of fs reader packages +\ +headerless +: fs-open ( file$ -- fd true | false ) + " open-file" fs-ih $call-method +; + +: fs-close ( fd -- ) + " close-file" fs-ih $call-method +; + +: fs-size ( fd -- size ) + " size-file" fs-ih $call-method +; + +: fs-read ( adr len fd -- #read ) + " read-file" fs-ih $call-method +; + +: fs-getrd ( adr len -- ) + " get-rd" fs-ih $call-method +; + +: fs-bootprop ( -- propval propname true | false ) + " bootprop" fs-ih $call-method +; +headers + + +\ zfs bootblks with all headers exceeds 7.5k +\ 'bigbootblk' allows us to load the fs reader from elsewhere +[ifdef] bigbootblk + +: load-pkg ( -- ) + boot-dev$ 2dup dev-open ?dup 0= if ( dev$ ) + open-abort + then >r 2drop ( r: ih ) + /fs-fcode mem-alloc ( adr r: ih ) + dup /fs-fcode fs-offset r@ read-disk + dup 1 byte-load + /fs-fcode mem-free ( r: ih ) + r> dev-close +; + +[else] + +: load-pkg ( -- ) ; + +[then] + + +: get-bootdev ( -- ) + \ first try boot archive (nested boot from ramdisk) + \ then try boot device (direct boot from disk) + " bootarchive" chosen-ph get-package-property if + " bootpath" chosen-ph get-string-prop ( bootpath$ ) + else ( archiveprop$ ) + decode-string 2swap 2drop ( archivepath$ ) + true to nested? + then ( bootpath$ ) + boot-dev swap move ( ) +; + +: mount-root ( -- ) + boot-dev$ fs-pkg$ $open-package to fs-ih + fs-ih 0= if + ." Can't mount root" abort + then +; + +\ +\ cheap entertainment for those watching +\ boot progress +\ +headerless +create spin-data + ascii | c, ascii / c, ascii - c, ascii \ c, + +0 instance variable spindex + +: spinner ( -- ) + spindex @ 3 and spin-data + ( c-adr ) + c@ emit (cr + 1 spindex +! +; + +: spin-on ( -- ) ['] spinner d# 1000 alarm ; +: spin-off ( -- ) ['] spinner 0 alarm ; + +headers +\ allocate and return physical allocation size +: vmem-alloc-prop ( size virt -- alloc-size virt ) + 2dup ['] vmem-alloc catch if ( size virt ??? ??? ) + 2drop ( size virt ) + 2dup begin ( size virt len adr ) + over 32meg min >r ( size virt len adr r: alloc-sz ) + r@ over vmem-alloc ( size virt len adr adr r: alloc-sz ) + nip r@ + ( size virt len adr' r: alloc-sz ) + swap r> - ( size virt adr len' ) + swap over 0= ( size virt len adr done? ) + until ( size virt len adr ) + 2drop nip 32meg ( virt 32meg ) + else ( size virt virt ) + nip nip 0 ( virt 0 ) + then ( virt alloc-sz ) + swap +; + +\ read in file and return buffer +\ if base==0, vmem-alloc will allocate virt +: get-file ( base fd -- [ virt size ] failed? ) + dup >r fs-size ( base size r: fd ) + dup rot vmem-alloc-prop ( size alloc-sz virt r: fd ) + rot 2dup tuck r> ( alloc-sz virt size size virt size fd ) + spin-on fs-read spin-off ( alloc-sz virt size size size-rd ) + <> if ( alloc-sz virt size ) + 3drop true exit ( failed ) + then + false ( alloc-sz virt size succeeded ) +; + + +false value is-elf? +false value is-archive? + +: check-elf ( base -- is-elf? ) + l@ h# 7f454c46 ( \x7fELF ) = +; + +: check-fcode ( base -- is-fcode? ) + c@ dup h# f0 h# f3 between swap h# fd = or +; + +: >bootblk ( adr -- adr' ) d# 512 + ; + +\ figure out what we just loaded +: get-type ( adr -- ) + dup check-elf to is-elf? + + \ if not nested, check for boot archive (executable after label) + nested? invert if + >bootblk + dup check-fcode ( adr is-fcode? ) + over check-elf ( adr is-fcode? is-elf? ) + or to is-archive? + then + drop +; + + +\ +\ file name routines +\ + +\ boot file (-F name or boot archive) +false value fflag? +/buf-len buffer: boot-file +: boot-file$ ( -- file$ ) boot-file cscount ; + +\ kernel name (final name or unix) +false value kern? +/buf-len buffer: kern-file +: kern-file$ ( -- file$ ) kern-file cscount ; + +\ platform name +/buf-len buffer: plat-name +: plat-name$ ( -- plat$ ) plat-name cscount ; + +\ arch name +/buf-len buffer: arch-name +: arch-name$ ( -- arch$ ) arch-name cscount ; + +\ final name after /platform massaging +/buf-len buffer: targ-file +: targ-file$ ( -- file$ ) targ-file cscount ; + +: init-targ ( -- ) + targ-file /buf-len erase + " /platform/" targ-file swap move +; + +\ remove illegal file name chars (e.g., '/') +: munge-name ( name$ -- name$' ) + 2dup ( name$ name$ ) + begin dup while + over c@ ascii / = if + over ascii _ swap c! ( name$ name$' ) + then str++ + repeat 2drop ( name$ ) +; + +\ if the platform exists in the FS, use it +\ else use a default (e.g., sun4v) +: get-arch ( -- ) + " device_type" root-ph get-package-property if + \ some older sunfires don't have device_type set + false ( sun4u ) + else ( devtype-prop$ ) + decode-string 2swap 2drop ( devtype$ ) + " sun4v" $= ( sun4v? ) + then ( sun4v? ) + if " sun4v" else " sun4u" then ( arch$ ) + arch-name swap move + " name" root-ph get-string-prop ( name$ ) + munge-name ( name$' ) + init-targ 2dup targ-file$ $append + targ-file$ fs-open if ( name$ fd ) + fs-close ( name$ ) + else ( name$ ) + 2drop arch-name$ ( default$ ) + then ( name$ ) + plat-name swap move ( ) +; + +\ make <pre> <file> into /platform/<pre>/<file> +: $plat-prepend ( file$ pre$ -- file$' ) + init-targ + targ-file$ $append ( file$ ) + " /" targ-file$ $append + targ-file$ $append ( ) + targ-file$ ( new$ ) +; + +: get-boot ( -- file$ ) + fflag? if + boot-file$ + else + " boot_archive" + then +; + +: get-kern ( -- file$ ) + kern? if + kern-file$ + else + " kernel/sparcv9/unix" + then +; + +\ if we're nested, load the kernel, else load the bootarchive +: get-targ ( -- file$ ) + nested? if + get-kern + else + get-boot + then +; + + +: try-file ( file$ -- [ fd ] error? ) + diagnostic-mode? if + 2dup ." Loading: " type cr + then + fs-open invert ( fd false | true ) +; + +\ try "/platform/<plat-name>/<file>" e.g., SUNW,Sun-Blade-1000 +\ then "/platform/<arch-name>/<file>" e.g., sun4u +: open-path ( file$ - fd ) + over c@ ascii / <> if + 2dup plat-name$ $plat-prepend ( file$ file$' ) + try-file if ( file$ ) + 2dup arch-name$ $plat-prepend ( file$ file$' ) + try-file if ( file$ ) + open-abort + then ( file$ fd ) + then ( file$ fd ) + else ( file$ ) + \ copy to targ-file for 'whoami' prop + targ-file /buf-len erase + 2dup targ-file swap move + 2dup try-file if ( file$ ) + open-abort + then ( file$ fd ) + then ( file$ fd ) + -rot 2drop ( fd ) +; + + +\ ZFS support +\ -Z fsname opens specified filesystem in disk pool + +false value zflag? +/buf-len buffer: fs-name +: fs-name$ ( -- fs$ ) fs-name cscount ; + +[ifdef] zfs + +: open-zfs-fs ( fs$ -- ) + 2dup " open-fs" fs-ih $call-method 0= if + open-abort + then + 2drop ( ) +; + +[else] + +: open-zfs-fs ( fs$ -- ) + ." -Z not supported on non-zfs root" abort +; + +[then] + + +\ +\ arg parsing +\ + +headerless +: printable? ( n -- flag ) \ true if n is a printable ascii character + dup bl th 7f within swap th 80 th ff between or +; +: white-space? ( n -- flag ) \ true is n is non-printable? or a blank + dup printable? 0= swap bl = or +; + +: skip-blanks ( adr len -- adr' len' ) + begin dup while ( adr' len' ) + over c@ white-space? 0= if exit then + str++ + repeat +; + +: skip-non-blanks ( adr len -- adr' len' ) + begin dup while ( adr' len' ) + over c@ white-space? if exit then + str++ + repeat +; + +headers +\ left-parse-string w/ any white space as delimeter +: next-str ( adr len -- adr' len' s-adr s-len ) + 2dup skip-non-blanks ( s-adr len adr' len' ) + dup >r 2swap r> - ( adr' len' s-adr s-len ) +; + +: next-c ( adr len -- adr' len' c ) + over c@ >r str++ r> +; + +false value halt? + +: parse-bootargs ( -- ) + " bootargs" chosen-ph get-string-prop ( arg$ ) + + \ check for explicit kernel name + skip-blanks dup if + over c@ ascii - <> if + next-str ( arg$ kern$ ) + \ use default kernel if user specific a debugger + 2dup " kadb" $= >r ( arg$ kern$ r: kadb? ) + 2dup " kmdb" $= r> or ( arg$ kern$ debugger? ) + invert if ( arg$ kern$ ) + kern-file swap move ( arg$ ) + true to kern? + else 2drop then ( arg$ ) + then + then + + \ process args + begin + skip-blanks dup ( arg$ len ) + while + next-c ascii - = if + next-c case + ascii D of + \ for "boot kadb -D kernel.foo/unix" + skip-blanks next-str ( arg$ file$ ) + kern? invert if + ?dup if + kern-file swap move ( arg$ ) + true to kern? + else drop then ( arg$ ) + else 2drop then ( arg$ ) + endof + ascii F of + skip-blanks next-str ( arg$ file$ ) + ?dup if + boot-file swap move ( arg$ ) + true to fflag? + else drop then ( arg$ ) + endof + ascii H of + true to halt? + endof + ascii Z of + skip-blanks next-str ( arg$ fs-name$ ) + ?dup if + fs-name swap move ( arg$ ) + true to zflag? + else drop then ( arg$ ) + endof + endcase + then + repeat + 2drop ( ) +; + + +0 value rd-alloc-sz + +: "ramdisk" ( -- dev$ ) " /ramdisk-root" ; + +: setup-bootprops ( -- ) + chosen-ph push-package + + nested? invert if + fs-type$ encode-string " fstype" property + fs-ih encode-int " bootfs" property + fs-bootprop if property then + else + fs-type$ encode-string " archive-fstype" property + fs-ih encode-int " archfs" property + then + + is-archive? if + "ramdisk" encode-string " bootarchive" property + else + loader-base encode-int " elfheader-address" property + file-sz encode-int " elfheader-length" property + plat-name$ encode-string " impl-arch-name" property + targ-file$ encode-string " whoami" property + fs-pkg$ encode-string " fs-package" property + then + + pop-package +; + + +\ load ramdisk fcode and tell the driver where +\ we put the ramdisk data +: setup-ramdisk ( base size -- ) + /rd-fcode mem-alloc ( base size adr ) + dup /rd-fcode fs-getrd + + root-ph push-package + new-device + "ramdisk" str++ device-name + dup 1 byte-load + finish-device + pop-package + + /rd-fcode mem-free ( base size ) + + "ramdisk" dev-open dup 0= if + "ramdisk" open-abort + then >r ( base size r: ih ) + rd-alloc-sz ( base size alloc-sz r: ih ) + " create" r@ $call-method ( r: ih ) + r> dev-close ( ) +; + + +\ +\ ELF parsing +\ + +0 value elfhdr +0 value phdr + +: +elfhdr ( index -- value ) elfhdr swap ca+ ; +: e_machine ( -- n ) h# 12 +elfhdr w@ ; +: e_entry ( -- n ) h# 18 +elfhdr x@ ; +: e_phoff ( -- n ) h# 20 +elfhdr x@ ; +: e_phentsize ( -- n ) h# 36 +elfhdr w@ ; +: e_phnum ( -- n ) h# 38 +elfhdr w@ ; + +1 constant pt_load +: +phdr ( index -- value ) phdr swap ca+ ; +: p_type ( -- n ) h# 0 +phdr l@ ; +: p_vaddr ( -- n ) h# 10 +phdr x@ ; +: p_memsz ( -- n ) h# 28 +phdr x@ ; + +: get-phdr ( filebase index -- phdr ) + e_phentsize * e_phoff + + ( phdr ) +; + +\ alloc 4MB pages for kernel text/data +: vmem-alloc-4mb ( size virt -- base ) + swap 4meg roundup swap + 4meg (mem-alloc) +; + +\ OBP doesn't allocate memory for elf +\ programs, it assumes they'll fit +\ under the default 10MB limit +: fix-elf-mem ( base -- ) + dup to elfhdr + e_machine d# 43 <> if drop exit then \ 64b only + + e_phnum 0 ?do + dup i get-phdr to phdr + p_type pt_load = p_vaddr h# a0.0000 > and if + \ allocate 4MB segs for text & data + p_vaddr 4meg 1- and if + p_memsz p_vaddr vmem-alloc drop + else + p_memsz p_vaddr vmem-alloc-4mb drop + then + then + loop drop ( ) +; + + +: load-file ( -- virt ) + get-arch + get-targ open-path ( fd ) + loader-base over get-file if ( fd alloc-sz virt size ) + ." Boot load failed" abort + then + to file-sz ( fd alloc-sz virt ) + swap to rd-alloc-sz ( fd virt ) + swap fs-close ( virt ) +; + +: setup-props ( virt -- virt ) + dup get-type + setup-bootprops + is-archive? if + dup file-sz setup-ramdisk + then +; + +: exec-file ( virt -- ) + is-elf? if + dup fix-elf-mem + then + is-archive? if >bootblk then ( virt' ) + " to load-base init-program" evaluate +; + +: do-boot ( -- ) + parse-bootargs + halt? if + ." Halted with -H flag. " cr + exit + then + get-bootdev + load-pkg + mount-root + zflag? nested? invert and if + fs-name$ open-zfs-fs + then + load-file ( virt ) + setup-props + exec-file ( ) +; + +\ Tadpole proms don't initialize my-self +0 to my-self + +do-boot diff --git a/usr/src/psm/stand/bootblks/common/mkbb.sh b/usr/src/psm/stand/bootblks/common/mkbb.sh new file mode 100755 index 0000000000..d5d395d1fd --- /dev/null +++ b/usr/src/psm/stand/bootblks/common/mkbb.sh @@ -0,0 +1,85 @@ +#!/bin/ksh +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# + +#!/bin/sh + +# defaults +bblen=7680 +rdlen=256 +totlen=7680 + +while getopts b:r:e: a; do + case $a in + b) bblen=$OPTARG;; + r) rdlen=$OPTARG;; + e) extra=$OPTARG + totlen=15872;; + ?) printf "Usage: %s: [ -b bb_len ] [ -r rd_len ] boot_fcode ramdisk_fcode bootblk\n" $0 + exit -1;; + esac +done +shift $(($OPTIND - 1)) + +# +# check boot code and ramdisk code for size overflow +# +rdoff=$(($bblen - $rdlen)) + +bbsize=$(ls -l $1 | awk -e '{ print $5 }') +if [ $bbsize -gt $rdoff ]; then + printf "$1 must be smaller than $rdoff\n" + exit -1 +fi + +rdsize=$(ls -l $2 | awk -e '{ print $5 }') +if [ $rdsize -gt $rdlen ]; then + printf "$1 must be smaller than $rdlen\n" + exit -1 +fi + +# +# make the bootblk +# +mkfile -n $totlen $3 +chmod 644 $3 +dd if=$1 of=$3 conv=notrunc bs=1 +dd if=$2 of=$3 conv=notrunc bs=1 oseek=$rdoff + +# +# extended bootblk for zfs debug +# +if [ $totlen -gt $bblen ]; then + extsize=$(ls -l $extra | awk -e '{ print $5 }') + if [ $extsize -gt 8192 ]; then + printf "$1 must be smaller than 8k\n" + exit -1 + fi + dd if=$extra of=$3 conv=notrunc bs=1 oseek=$bblen +fi + +exit 0 diff --git a/usr/src/psm/stand/bootblks/common/rd.fth b/usr/src/psm/stand/bootblks/common/rd.fth new file mode 100644 index 0000000000..dee3a594e1 --- /dev/null +++ b/usr/src/psm/stand/bootblks/common/rd.fth @@ -0,0 +1,83 @@ +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ + +id: %Z%%M% %I% %E% SMI +purpose: simplified ramdisk driver +copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved + +headerless + +" block" device-type +" SUNW,ramdisk" encode-string " compatible" property + +0 instance value current-offset + +0 value ramdisk-base-va +0 value ramdisk-size +0 value alloc-size + +: set-props + ramdisk-size encode-int " size" property + ramdisk-base-va encode-int " address" property + alloc-size encode-int " alloc-size" property +; +set-props + +: current-va ( -- adr ) ramdisk-base-va current-offset + ; + +external + +: open ( -- okay? ) + true +; + +: close ( -- ) +; + +: seek ( off.low off.high -- error? ) + drop dup ramdisk-size > if + drop true exit ( failed ) + then + to current-offset false ( succeeded ) +; + +: read ( addr len -- actual-len ) + dup current-offset + ( addr len new-off ) + dup ramdisk-size > if + ramdisk-size - - ( addr len' ) + ramdisk-size ( addr len new-off ) + then -rot ( new-off addr len ) + tuck current-va -rot move ( new-off len ) + swap to current-offset ( len ) +; + +: create ( base size alloc-sz -- ) + to alloc-size + to ramdisk-size + to ramdisk-base-va + set-props +; + diff --git a/usr/src/psm/stand/bootblks/common/util.fth b/usr/src/psm/stand/bootblks/common/util.fth new file mode 100644 index 0000000000..d48904646c --- /dev/null +++ b/usr/src/psm/stand/bootblks/common/util.fth @@ -0,0 +1,219 @@ +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ + +id: %Z%%M% %I% %E% SMI +purpose: utility words +copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved + + +[ifdef] doheaders +headers +[else] +headerless +[then] + +d# 256 constant /buf-len + +\ +\ useful counting words +\ +: roundup ( x y -- x' ) 1- tuck + swap invert and ; + + +\ +\ various useful string manipulation words +\ + +: cstrlen ( cstr -- len ) + dup begin + dup c@ + while + char+ + repeat swap - +; + +: cscount ( cstr -- adr,len ) dup cstrlen ; + +\ Append str1 to the end of str2 +: $append ( adr,len1 adr,len2 -- ) + 2over 2over ca+ swap move ( adr,len1 adr,len2 ) + rot + ca+ 0 swap c! drop ( ) +; + +: $= ( str1$ str2$ -- same? ) + rot tuck <> if + 3drop false exit + then comp 0= +; + +\ advance str by 1 +: str++ ( adr len -- adr' len' ) + swap 1+ swap 1- +; + +: diag-cr? ( -- ) diagnostic-mode? if cr then ; + + +: find-abort ( name$ -- ) + ." Can't find " type abort +; + +: get-package ( pkg$ -- ph ) + 2dup find-package 0= if + find-abort + then ( pkg$ ph ) + nip nip ( ph ) +; + + +\ +\ CIF words for I/O and memory +\ +" /openprom/client-services" get-package constant cif-ph + +instance defer cif-open ( dev$ -- ihandle|0 ) +instance defer cif-close ( ihandle -- ) +instance defer cif-read ( len adr ihandle -- #read ) +instance defer cif-seek ( low high ihandle -- -1|0|1 ) +instance defer cif-release ( size virt -- ) + +: find-cif-method ( adr,len -- acf ) + 2dup cif-ph find-method 0= if ( adr,len ) + find-abort + then ( adr,len acf ) + nip nip ( acf ) +; + +" open" find-cif-method to cif-open +" close" find-cif-method to cif-close +" read" find-cif-method to cif-read +" seek" find-cif-method to cif-seek +" release" find-cif-method to cif-release + + +" /chosen" get-package constant chosen-ph + +: get-property ( name$ ph -- prop$ ) + >r 2dup r> get-package-property if ( name$ ) + find-abort + then ( name$ prop$ ) + 2swap 2drop ( prop$ ) +; + +: get-string-prop ( name$ ph -- val$ ) + get-property decode-string ( prop$' val$ ) + 2swap 2drop ( val$ ) +; + +: get-int-prop ( name$ ph -- n ) + get-property decode-int ( prop$' n ) + nip nip ( n ) +; + +\ +\ memory allocation +\ we bypass cif claim so we can do large page +\ allocations like promif can +\ + +" mmu" chosen-ph get-int-prop constant mmu-ih + +" memory" chosen-ph get-int-prop constant mem-ih + +: mmu-claim ( [ virt ] size align -- base ) + " claim" mmu-ih $call-method +; + +: mmu-map ( phys.lo phys.hi virt size -- ) + -1 " map" mmu-ih $call-method +; + +: mem-claim ( size align -- phys.lo phys.hi ) + " claim" mem-ih $call-method +; + +: (mem-alloc) ( size virt align -- virt ) + \ claim memory first since it may throw if fragmented + rot 2dup swap mem-claim ( virt align size phys.lo phys.hi ) + >r >r rot ?dup if ( align size virt r: phys.lo phys.hi ) + \ we picked virt - zero alignment + over 0 mmu-claim ( align size virt r: phys.lo phys.hi ) + else ( align size r: phys.lo phys.hi ) + \ OBP picks virt - pass alignment + 2dup swap mmu-claim ( align size virt r: phys.lo phys.hi ) + then ( align size virt r: phys.lo phys.hi ) + r> r> 2over swap mmu-map ( align size virt ) + nip nip ( virt ) +; + +: vmem-alloc ( size virt -- virt ) + swap h# 2000 roundup swap + 1 (mem-alloc) +; + +: mem-alloc ( size -- virt ) + h# 2000 roundup + 0 1 (mem-alloc) +; + +: mem-free ( virt size -- ) + h# 2000 roundup + swap cif-release ( ) +; + + + +\ put ramdisk fcode 256 bytes from end of bootblk +\ (currently 244 bytes in size) +d# 256 constant /rd-fcode +d# 8192 /rd-fcode - constant rd-offset + +: open-abort ( file$ -- ) + ." Can't open " type abort +; + +/buf-len buffer: open-cstr + +: dev-open ( dev$ -- ih | 0 ) + \ copy to C string for open + 0 over open-cstr + c! + open-cstr swap move + open-cstr cif-open +; + +: dev-close ( ih -- ) + cif-close +; + +: read-disk ( adr len off ih -- ) + dup >r 0 swap cif-seek if ( adr len r: ih ) + ." seek failed" abort + then + + tuck swap r> cif-read <> if ( ) + ." read failed" abort + then +; diff --git a/usr/src/psm/stand/bootblks/hsfs/Makefile b/usr/src/psm/stand/bootblks/hsfs/Makefile index cfae7b9a31..5bbc4326e0 100644 --- a/usr/src/psm/stand/bootblks/hsfs/Makefile +++ b/usr/src/psm/stand/bootblks/hsfs/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,8 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1989-1994, by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/bootblks/hsfs/Makefile # @@ -36,16 +36,10 @@ lint := TARGET= lint .KEEP_STATE: -all clean clobber lint : $(SUBDIRS) +all install clean clobber lint : $(SUBDIRS) $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) -# -# XXX There's no point in installing the hsfs stuff if we -# never use it (or test it!) -# -install: FRC - FRC: diff --git a/usr/src/psm/stand/bootblks/hsfs/Makefile.hsfs b/usr/src/psm/stand/bootblks/hsfs/Makefile.hsfs index 72ee6d8fd1..a5d61a916a 100644 --- a/usr/src/psm/stand/bootblks/hsfs/Makefile.hsfs +++ b/usr/src/psm/stand/bootblks/hsfs/Makefile.hsfs @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,14 +21,57 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994, by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/bootblks/hsfs/Makefile.hsfs # + include $(BASEDIR)/Makefile.com -include $(BASEDIR)/hsfs/common/Makefile.com # -# Where stuff gets installed +# Define FS dependent targets +# + +HSFS_DIR = $(BASEDIR)/hsfs/common + +FS_FCODE = boot-hsfs.fcode +FS_BB = hsfs.bb + +HSFSBOOT_FTH = $(HSFS_DIR)/boot-hsfs.fth +HSFS_FTH = $(HSFS_DIR)/hsfs.fth + +# +# This program is used to install the boot block +# +INSTALLBOOT = installboot + +# +# Where and how stuff gets installed # USR_PSM_BOOTBLOCK = $(USR_PSM_LIB_HSFS_DIR)/$(PROG) + +USR = $(ROOT)/usr +USR_SBIN = $(USR)/sbin +USR_SBIN_INSTALLBOOT = $(USR_SBIN)/$(INSTALLBOOT) + +# +# Overrides for installing installboot. +# +INS.file.555 = $(RM) $@; $(INS) -s -m 555 -f $(@D) $< +$(CH)INS.file.555 = $(INS) -s -m 555 -u $(OWNER) -g $(GROUP) -f $(@D) $< + +# +# dependencies +# +%.fcode: $(HSFS_DIR)/%.fth + $(TOKENIZE) $< + +$(FS_FCODE): $(UTIL_FTH) $(HSFS_FTH) $(BOOT_FTH) + $(TOKENIZE) $(HSFSBOOT_FTH) + +# +# install rules +# +$(USR_SBIN)/%: % $(USR_SBIN) + $(INS.file.555) diff --git a/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com b/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com deleted file mode 100644 index 26b9823359..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com +++ /dev/null @@ -1,56 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1994, by Sun Microsystems, Inc. -# All rights reserved. -# -# psm/stand/bootblks/hsfs/common/Makefile.com -# - -THISDIR = $(BASEDIR)/hsfs/common - -# -# Files that define the fs-reading capabilities of the C-based boot block -# -# uncomment following line if want to build big bootblk -# FS_C_SRCS = hsfs.c -# uncomment following line if want to build small bootblk -FS_C_SRCS = hsfs_small.c - -# -# Allow hsfs-specific files to find hsfs-specific include files -# -$(FS_C_SRCS:%.c=%.o) := CPPINCS += -I$(THISDIR) - -# -# Pattern-matching rules for source in this directory -# -%.o: $(THISDIR)/%.c - $(COMPILE.c) -o $@ $< - -%.ln: $(THISDIR)/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -%.fcode: $(THISDIR)/%.fth - $(TOKENIZE) $< diff --git a/usr/src/psm/stand/bootblks/hsfs/common/boot-hsfs.fth b/usr/src/psm/stand/bootblks/hsfs/common/boot-hsfs.fth new file mode 100644 index 0000000000..4328400421 --- /dev/null +++ b/usr/src/psm/stand/bootblks/hsfs/common/boot-hsfs.fth @@ -0,0 +1,44 @@ + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ + +id: %Z%%M% %I% %E% SMI +purpose: HSFS file system support package for NewBoot +copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved + +\ add headers +create doheaders + +: fs-pkg$ " hsfs-file-system" ; +: fs-type$ " hsfs" ; + +\ load common words +fload ../../../common/util.fth + +\ load fs reader +fload ../../common/hsfs.fth + +\ load booter +fload ../../../common/boot.fth diff --git a/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth b/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth deleted file mode 100644 index 3ab085f7ba..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth +++ /dev/null @@ -1,598 +0,0 @@ -\ ident "%Z%%M% %I% %E% SMI" -\ purpose: Rock Ridge Boot Block -\ copyright: Copyright 2005 Sun Microsystems, Inc. All rights reserved. -\ copyright: Use is subject to license terms. -\ copyright: -\ copyright: CDDL HEADER START -\ copyright: -\ copyright: The contents of this file are subject to the terms of the -\ copyright: Common Development and Distribution License, Version 1.0 only -\ copyright: (the "License"). You may not use this file except in compliance -\ copyright: with the License. -\ copyright: -\ copyright: You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -\ copyright: or http://www.opensolaris.org/os/licensing. -\ copyright: See the License for the specific language governing permissions -\ copyright: and limitations under the License. -\ copyright: -\ copyright: When distributing Covered Code, include this CDDL HEADER in each -\ copyright: file and include the License file at usr/src/OPENSOLARIS.LICENSE. -\ copyright: If applicable, add the following below this CDDL HEADER, with the -\ copyright: fields enclosed by brackets "[]" replaced with your own identifying -\ copyright: information: Portions Copyright [yyyy] [name of copyright owner] -\ copyright: -\ copyright: CDDL HEADER END -\ copyright: - -\ High Sierra, Rock Ridge (CD-ROM) file system reader and boot block -\ Original HSFS code from Mitch Bradley, RR extensions by Sam Cramer - -\ There's some code in there that would be a shame to throw out, -\ but which currently doesn't fit in the boot block. This code is commented -\ out, with #ifdef style comment lines. The "options" are: -\ HSFSNAMES -- look at hsfs names if you can't find Rock Ridge names -\ PROCESS_CE -- process continuation (CE) signatures; this is -\ potentially useful, but it looks like the RR disks -\ we're dealing with don't use them, and it is a bit -\ of work to implement continuations. -\ PATHLOOKUP -- handle pathnames, not just filenames which are in -\ the root directory - -\ FIXME need some way of returning exceptions cleanly -\ The culprit is the "abort" in read-blocks - -\ Fcode-version1 -decimal -headerless - -\ -\ Forth utility routines -\ -\ : $find 2dup type cr $find ; - -: boot-eval ( adr len -- ) - $find if - execute - else - type ." ?" cr exit - then -; - -\ " romvec" boot-eval constant romvec -variable boot-romvec - -: find-romvec - " romvec" $find if - execute - else - 2drop h# ffe8.0010 - then - boot-romvec ! -; - -find-romvec - -: roment ( offset -- adr ) boot-romvec @ + l@ ; - -" load-base" $find drop constant 'loadbase -\ " (is" $find drop constant '(is -\ " $=" $find drop constant '$= -" call" $find drop constant 'call - -: loadbase ( -- adr ) 'loadbase execute ; -\ : (is ( val acf -- ) '(is execute ; -\ : $= ( str1 str2 -- [ -1 | 0 | 1 ] ) '$= execute ; -: call ( ... addr -- ??? ) 'call execute ; -: loadbase! ( value -- ) 'loadbase " (is" boot-eval ; - - -\ defer open-disk ( -- ) -\ defer read-dev-bytes ( adr len byte# -- error? ) -\ defer close-disk ( -- ) - - -: devname ( -- cstr ) - h# 88 roment @ \ bootpath -; - -\ Debug V2 or later PROMs -\ : devname " /sbus/esp/sd@3,0:b" drop ; - - -\ Debug V0 PROMS -\ : devname " sd(0,0,0)" drop ; - -variable devid -: open-disk ( -- error? ) - devname - " op-open" - boot-eval dup if - dup devid ! - then - 0= ( invert sense of error flag ) -; - -: close-disk ( -- ) - devid @ " op-close" boot-eval drop -; - -: read-blks ( adr len -- error? ) - ( len adr devid -- #bytes_read ) - tuck swap devid @ " op-read" boot-eval <> -; - -: seek ( low high -- error? ) - ( low high devid -- ? ) - devid @ " op-seek" boot-eval 0< -; - -: read-dev-bytes ( adr len byte# -- error? ) - 0 seek ?dup if exit then - ( adr len ) read-blks -; - -\ : xl@ ( adr -- l ) la1+ unaligned-l@ ; \ For big-endian machines -\ unaligned-l@ is not define in OBP... -: xl@ ( adr -- l ) \ For big-endian machines - dup c@ swap ( c1 adr ) - 1+ dup c@ swap ( c0 c1 adr+1 ) - 1+ dup c@ swap ( c0 c1 c2 adr+2 ) - 1+ c@ ( c0 c1 c2 c3 ) - 8 << + 8 << + 8 << + -; - -\ : xl@ ( adr -- l ) unaligned-l@ ; \ For little-endian machines -: xw@ ( adr -- w ) dup c@ swap 1+ c@ 8 << + ; - -\ compare two strings for equality -: $= ( adr1 len1 adr2 len2 -- same? ) - rot over = if ( adr1 adr2 len2 ) - comp 0= - else - 2drop drop false - then -; - -0 value dir-buf \ buffer for current directory block -0 value sua-buf \ buffer for current sua block -0 value vol-desc \ volume descriptor - -2048 constant /sector - -16 constant vol-desc-sector# ( -- n ) - -\ logical block size (from volume descriptor) -: /block ( -- n ) vol-desc 128 + xw@ ; - -\ root directory entry (in volume descriptor) -: root-dirent ( -- adr ) vol-desc 156 + ; - -: release ( -- ) - dir-buf /block free-mem - sua-buf /block free-mem - vol-desc /sector free-mem - close-disk -; - -: read-abort ( adr len byte# -- error? ) -\ read-dev-bytes if release ." Disk read failed" abort then - 0 seek ?dup if exit then - read-blks drop \ Ignore error code !! -; - -: get-vol-desc ( -- ) - vol-desc /sector vol-desc-sector# /sector * read-abort -; - -\ **** Allocate memory for necessary data structures -: allocate-hsfs-buffers ( -- ) - /sector alloc-mem is vol-desc - get-vol-desc - /block alloc-mem is dir-buf - /block alloc-mem is sua-buf -; - -\ File handles - -\ #ifdef HSFSNAMES -\ \ Remove any version number ( ;nnn ) from the name. -\ : -version ( adr len -- adr len' ) -\ 2dup -\ bounds ?do ( adr len ) -\ \ If a ; is located, set len to the length before the ; -\ i c@ ascii ; = -\ if drop i over - leave then ( adr len' ) -\ loop -\ ; -\ #endif HSFSNAMES - -0 value file-desc \ points to current dir entry -0 value sua-desc \ points to current SUA entry - -: select-file ( adr -- ) is file-desc ; -: +fd ( n -- adr ) file-desc + ; -: file-extent ( -- n ) 2 +fd xl@ ; -: filesize ( -- n ) 10 +fd xl@ ; - -: hsfs-file-name ( -- adr len ) 33 +fd 32 +fd c@ ; -: dir? ( -- flag ) 25 +fd c@ h# 02 and 0<> ; -: dir-len ( -- len ) file-desc c@ ; - -\ Directories - -variable dir-block0 \ First block number in the directory file -variable dir-size \ Number of bytes in the directory file - -variable dir-block# \ Next block number in the directory file -variable dir-last-block# \ Last block number in the directory file -variable diroff \ Offset into the current directory block -variable totoff \ Total offset into the directory - -\ RR fields - -\ SUAs -variable sua-off \ Offset into the current sua entry -: select-sua ( adr -- ) is sua-desc ; -: +suad ( n -- adr ) sua-desc + ; - -\ return address of SUA, = addr of filename + len(filename) + 0/1 byte pad -: file-sua ( -- adr ) - hsfs-file-name dup ( addr len len ) - \ add in pad: 1 if len is even, 0 if odd - 2 mod 0= if 1 else 0 then + ( addr len' ) - + -; - -: suf-sig ( -- adr len ) sua-desc 2 ; \ signature bytes -: suf-len ( -- len ) 2 +suad c@ ; \ suf length - -\ #ifdef PROCESS_CE -\ \ location of continuation area, if parsed CE signature -\ variable ce-lbn -\ variable ce-offset -\ variable ce-len -\ -\ \ CE signature, continuation block -\ : suf-parse-ce-lbn ( -- loc ) 4 +suad xl@ ; \ location of cont -\ : suf-parse-ce-offset ( -- n ) 12 +suad xl@ ; \ offset of cont -\ : suf-parse-ce-len ( -- n ) 20 +suad xl@ ; \ len of cont -\ -\ : clear-cont-flags ( -- ) 0 ce-lbn ! 0 ce-len ! 0 ce-offset ! ; -\ -\ \ read the continuation area specified by CE signature -\ : read-cont ( -- ) sua-buf /block ce-lbn /sector * read-abort ; -\ #endif /* PROCESS_CE */ - -\ NM signature, alternate name -: suf-parse-nm ( -- addr len ) - 5 +suad - suf-len 5 - -; - -\ current suf is at or past end of the sua? -: end-sua ( -- end? ) - \ if (sua-off >= block size) then return (true); - \ if (sua-desc[0] == 0 || sua-desc[1] == 0) then return (true); - \ return (len(sua entry) == 0) - sua-off @ /block >= if true exit then - sua-desc c@ 0= if true exit then - 1 +suad c@ 0= if true exit then - suf-len 0= -; - -\ select the next system use field -: next-suf ( -- ) - \ sua-off += len(suf); sua-desc += len(suf); - suf-len dup sua-off +! +suad select-sua -; - -\ return the rock ridge file name associated with the current -\ dir-ent; returns 0 0 if can't find name. -\ ignores continuations -: rr-file-name ( -- adr len ) - \ select start of sua, record sua offset - file-sua select-sua - diroff @ sua-off ! - \ while (1) do - \ if (end of sua) { - \ break - \ } - \ if parse(sua) == 'NM' return suf-parse-nm; - \ next-suf; - \ done - begin - end-sua if 0 0 exit then - suf-sig - " NM" $= if suf-parse-nm exit then - next-suf - false - until -; - -\ #ifdef PROCESS_CE -\ \ Alternate verson of rr-file-name which chases continuations -\ \ -\ \ return the rock ridge file name associated with the current -\ \ dir-ent; returns 0 0 if can't find name. -\ \ chases continuations -\ : rr-file-name ( -- adr len ) -\ clear-cont-flags -\ \ select start of sua, record sua offset -\ file-sua select-sua -\ diroff @ sua-off ! -\ \ while (1) do -\ \ if (end of sua) { -\ \ if (ce-lbn) -\ \ read-continuation; -\ \ clear-continuation-info; -\ \ fiddle sua pointers; -\ \ else -\ \ break; -\ \ } -\ \ if parse(sua) == 'NM' return suf-parse-nm; -\ \ if parse(sua) == 'CE' -\ \ ce-lbn = suf-parse-ce-lbn(); -\ \ ce-len = suf-parse-ce-len(); -\ \ ce-offset = suf-parse-ce-offset(); -\ \ next-suf; -\ \ done -\ begin -\ end-sua if -\ ce-lbn @ if -\ read-cont -\ clear-cont-flags -\ sua-buf select-sua -\ 0 sua-off ! -\ end-sua if 0 0 exit then -\ else -\ 0 0 exit -\ then -\ then -\ suf-sig -\ 2dup " NM" $= if \ NM -\ 2drop suf-parse-nm exit -\ then -\ 2dup " CE" $= if \ CE -\ suf-parse-ce-lbn ce-lbn ! -\ suf-parse-ce-offset ce-offset ! -\ suf-parse-ce-len ce-len ! -\ \ XXX debug " had CE" type cr -\ then -\ 2drop -\ next-suf -\ false -\ until -\ ; -\ #endif /* PROCESS_CE */ - - -\ file name of dir entry -: file-name ( -- adr len ) - rr-file-name -\ #ifdef HSFSNAMES -\ \ if no rr name, use hsfs name minus version -\ dup 0= if 2drop hsfs-file-name -version then -\ #endif /* HSFSNAMES */ -; - -\ Read the next directory block, updating diroff and dir-block# -: get-dirblk ( -- ) - dir-buf /block dir-block# @ /block * read-abort - 0 diroff ! - 1 dir-block# +! -; - -\ **** Select the next directory entry -: next-file ( -- end? ) - \ diroff += len(dir entry); totoff += len(dir entry); - \ if (totoff >= dir-size) then return (true) - \ if (diroff = block size) then get-dirblk - \ if (len (next dir entry) == 0 && totoff < dir-size) then get-dirblk - \ file-desc = dir-buf + diroff - \ return (len(dir entry) == 0) - file-desc c@ dup diroff +! totoff +! - totoff @ dir-size @ >= if true exit then - diroff @ /block = if get-dirblk then - dir-buf diroff @ + c@ 0= - dir-block# @ dir-last-block# @ < - and if get-dirblk then - dir-buf diroff @ + select-file - file-desc c@ 0= -; - -\ **** Select the first file in the current directory -: reset-dir ( -- ) - dir-block0 @ dir-block# ! - get-dirblk - 0 totoff ! - dir-buf diroff @ + select-file - next-file drop next-file drop \ Skip the "parent" and "self" entries -; - -\ **** "cd" to the current file (read directory pointed to by dirent) -: set-dir ( -- ) - file-extent dir-block0 ! - filesize dir-size ! - filesize /block / dir-block0 @ + dir-last-block# ! - reset-dir -; - -\ **** Select the root directory -: froot ( -- ) root-dirent select-file set-dir ; - -: dir ( -- ) begin file-name type cr next-file until ; - - -\ search directory block for file name -: lookup ( adr len -- not-found? ) - \ #ifndef PATHLOOKUP - froot - \ #endif /* PATHLOOKUP */ - begin - 2dup file-name $= if 2drop false exit then - next-file - until - 2drop true -; - -\ #ifdef PATHLOOKUP -\ : /string ( adr len size -- adr+size len-size ) tuck - >r + r> ; -\ -\ \ Splits a string around a delimiter. If the delimiter is found, -\ \ two strings are returned under true, otherwise one string under false. -\ : $split ( adr len char -- remaining-adr,len [ initial-adr,len ] found? ) -\ 2 pick 2 pick bounds ?do -\ dup i c@ = if i nip -1 then -\ loop ( adr len adr' -1 | char ) -\ -1 = if ( adr len adr' ) -\ swap >r ( adr adr' ) ( r: len ) -\ 2dup swap - swap ( adr [adr'-adr] adr' ) ( r: len ) -\ 1+ r> ( adr [adr'-adr] adr'+1 len ) -\ 2 pick - 1- ( adr [adr'-adr] adr'+1 len-[adr'-adr-1] ) -\ 2swap true ( rem-adr,len initial-adr,len true ) -\ else -\ false -\ then -\ ; -\ -\ : path-lookup ( adr len -- not-found? ) -\ dup 0= if 2drop true exit then -\ over c@ ascii / = if 1 /string then -\ froot -\ begin -\ ascii / $split ( rem-adr,len [ adr,len ] delim-found? ) -\ while -\ lookup if ." Bad path" cr 2drop true exit then -\ dir? 0= if ." Bad path" cr 2drop true exit then -\ set-dir -\ repeat ( rem-adr,len ) -\ -\ \ Now we have found the directory containing the file -\ lookup if -\ ." File not found among: " cr -\ reset-dir dir -\ true -\ else -\ false \ File is already selected -\ then ( flag ) -\ ; -\ #endif /* PATHLOOKUP */ - -\ File reading -: read-file ( adr -- error? ) - filesize file-extent /block * read-dev-bytes ( error? ) -; - - -\ -\ ELF support -\ - -0 constant elfhdr -0 constant phdr - -: +w_elfhdr ( index -- value ) elfhdr swap ca+ w@ ; -: +l_elfhdr ( index -- value ) elfhdr swap ca+ l@ ; -: e_entry ( -- n ) 24 +l_elfhdr ; -: e_phoff ( -- n ) 28 +l_elfhdr ; -: e_phentsize ( -- n ) 42 +w_elfhdr ; -: e_phnum ( -- n ) 44 +w_elfhdr ; - -1 constant pt_load -: +phdr ( index -- value ) phdr swap la+ l@ ; -: p_type ( -- n ) 0 +phdr ; -: p_offset ( -- n ) 1 +phdr ; -: p_vaddr ( -- n ) 2 +phdr ; -: p_filesz ( -- n ) 4 +phdr ; -: p_memsz ( -- n ) 5 +phdr ; -\ : p_flags ( -- n ) 6 +phdr ; -\ : p_align ( -- n ) 7 +phdr ; - -: check-elf ( filebase -- is-elf? ) - l@ h# 7f454c46 ( \x7fELF ) = -; - -: get-phdr ( filebase index -- ) - e_phentsize * e_phoff + + - phdr e_phentsize move -; - -: load-elf ( filebase -- entry-point ) - dup is elfhdr - e_phentsize alloc-mem is phdr - e_phnum 0 ?do - dup i get-phdr - p_type pt_load = if - ( read it ) - dup p_offset + p_vaddr p_filesz move - p_memsz p_filesz > if - ( zero the bss ) - p_vaddr p_filesz + p_memsz p_filesz - 0 fill - then - then - loop drop - phdr e_phentsize free-mem - e_entry -; - -\ Installation - -: initialize ( -- ) - open-disk ?dup if exit then - allocate-hsfs-buffers -; - -hex -headers -( external ) - -: get-file ( load-adr name-adr name-len -- error? ) - initialize - \ #ifndef PATHLOOKUP - lookup if ." lookup failed" cr drop release true exit then - \ #else /* PATHLOOKUP */ - \ path-lookup if drop release true exit then - \ #endif /* PATHLOOKUP */ - dir? if - ." Requested file is a directory" cr drop release true exit - then - read-file ?dup if ." File read failed." cr exit then - filesize " file-size" boot-eval ! - release - false -; - -: reloc&go ( -- ) - loadbase - \ Is it ELF? - dup check-elf if ( base-adr ) - load-elf ( entry-point ) - loadbase! - " init-program" boot-eval - else ( base-adr ) -\ Let FORTH handle anything else - " adjust-header" boot-eval if - " init-program" boot-eval - then ( entry-point ) - loadbase! - then - 4000 loadbase! - " ?go" boot-eval -; - -\ -\ The boot stuff itself -\ -: do-boot - 4000 loadbase! - \ #ifndef PATHLOOKUP - loadbase " hsfsboot" get-file if - \ #else /* PATHLOOKUP */ - \ loadbase " /hsfsboot" get-file if - \ #endif /* PATHLOOKUP */ - ." Boot load failed." cr exit - then - reloc&go -; - -do-boot diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c b/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c deleted file mode 100644 index 2ff62f6c24..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c +++ /dev/null @@ -1,683 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1991, 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * The routines in this file are called only after the PROM - * version has been determined to be sunMON. - * - * Basic file system reading code for standalone I/O system. - * Simulates a primitive UNIX I/O system (read(), write(), open(), etc). - * Does not support writes. - */ - -#include <sys/param.h> -#include <sys/saio.h> -#include <sys/sysmacros.h> -#include <sys/vnode.h> -#include <sys/fs/ufs_fsdir.h> -#include <sys/fs/ufs_fs.h> -#include <sys/fs/ufs_inode.h> - -#include <sys/fs/hsfs_spec.h> -#include <sys/fs/hsfs_isospec.h> -#include <sys/fs/hsfs_node.h> -#include <sys/fs/hsfs_susp.h> -#include <sys/fs/hsfs_rrip.h> - -#include <iob.h> -#include "hsfs_sig.h" - -#define hdbtodb(n) ((ISO_SECTOR_SIZE / DEV_BSIZE) * (n)) - -#define NULL 0 - -#define TRUE 1 -#define FALSE 0 - -char *bootname = "/hsfsboot"; - -extern int (*printf_p)(); - -struct dirstuff { - int loc; - struct iob *io; -}; - -struct hs_direct { - struct direct hs_ufs_dir; - struct hs_direntry hs_dir; -}; - -/* These are the pools of buffers, iob's, etc. */ -struct iob iob[1]; - -/* This is the fd for the file(s) */ -static i_fd = 1; - -/* May not need this... */ -static uint_t root_ino = 0; - -/* - * Non-local prototypes - */ -extern int devread(struct saioreq *s); -extern int devopen(struct saioreq *s); -extern int devclose(struct saioreq *s); - -/* - * Local prototypes - */ -static struct hs_direct *readdir(struct dirstuff *); -static ino_t dlook(char *, struct iob *); -static ino_t find(char *, struct iob *); -static uint_t parse_dir(struct iob *, int, struct hs_direct *); -static uint_t parse_susp(char *, uint_t *, struct hs_direct *); -static int opendir(ino_t, struct iob *); -static int mountroot(void); - -extern int prom_type; /* Determined in main() */ -/* - * Exported functions - */ -extern int open(char *str, int flags); -extern int close(int fd); -extern int read(int fdesc, char *buf, int count); -extern int lseek(int fdesc, off_t addr); - -static int -opendir(ino_t inode, struct iob *io) -{ - struct hs_direct hsdep; - uint_t i; - int retval; - - /* Set up the saio request */ - io->i_offset = 0; - io->i_bn = hdbtodb(inode); - io->i_cc = ISO_SECTOR_SIZE; - - if ((retval = devread(&io->i_si)) != ISO_SECTOR_SIZE) - return (0); - - io->i_offset = 0; - io->i_bn = hdbtodb(inode); - - if (inode != root_ino) - return (0); - - if (parse_dir(io, 0, &hsdep) > 0) { - register struct inode *ip = &io->i_ino; - - bzero(io->i_ino, sizeof (struct inode)); - ip->i_size = hsdep.hs_dir.ext_size; - ip->i_smode = hsdep.hs_dir.mode; - ip->i_number = inode; - return (0); - } - return (1); -} - -static ino_t -find(char *path, struct iob *file) -{ - char *q; - char c; - ino_t n; - - if (path == NULL || *path == '\0') - return (0); - - if (opendir(root_ino, file)) - return (0); - - while (*path) { - while (*path == '/') - path++; - q = path; - while (*q != '/' && *q != '\0') - q++; - c = *q; - *q = '\0'; - - if ((n = dlook(path, file)) != 0) { - if (c == '\0') - break; - if (opendir(n, file)) - return (0); - *q = c; - path = q; - continue; - } else { - return (0); - } - } - return ((ino_t)n); -} - -static ino_t -dlook(char *s, struct iob *io) -{ - register struct hs_direct *hsdep; - register struct direct *udp; - register struct inode *ip; - struct dirstuff dirp; - register int len; - - ip = &io->i_ino; - if (s == NULL || *s == '\0') - return (0); - if ((ip->i_smode & IFMT) != IFDIR) { - return (0); - } - if (ip->i_size == 0) { - return (0); - } - len = strlen(s); - dirp.loc = 0; - dirp.io = io; - for (hsdep = readdir(&dirp); hsdep != NULL; hsdep = readdir(&dirp)) { - udp = &hsdep->hs_ufs_dir; - if (udp->d_namlen == 1 && - udp->d_name[0] == '.' && - udp->d_name[1] == '\0') - continue; - if (udp->d_namlen == 2 && - udp->d_name[0] == '.' && - udp->d_name[1] == '.' && - udp->d_name[2] == '\0') - continue; - if (udp->d_namlen == len && (strcmp(s, udp->d_name)) == 0) { - register struct inode *ip = &io->i_ino; - - io->i_offset = 0; - io->i_bn = hdbtodb(udp->d_ino); - - bzero(io->i_ino, sizeof (struct inode)); - ip->i_size = hsdep->hs_dir.ext_size; - ip->i_smode = hsdep->hs_dir.mode; - ip->i_number = udp->d_ino; - return (udp->d_ino); - } - } - return (0); -} - -/* - * get next entry in a directory. - */ -static struct hs_direct * -readdir(struct dirstuff *dirp) -{ - static struct hs_direct hsdep; - register struct direct *udp = &hsdep.hs_ufs_dir; - struct inode *ip; - struct iob *io; - daddr_t lbn, d; - int off; - - io = dirp->io; - ip = &io->i_ino; - for (;;) { - if (dirp->loc >= ip->i_size) { - return (NULL); - } - off = dirp->loc & ((1 << ISO_SECTOR_SHIFT) - 1); - if (off == 0) { - lbn = hdbtodb(dirp->loc >> ISO_SECTOR_SHIFT); - io->i_bn = lbn + hdbtodb(ip->i_number); - io->i_ma = io->i_buf; - io->i_cc = ISO_SECTOR_SIZE; - if (devread(&io->i_si) != io->i_cc) { - return (NULL); - } - } - dirp->loc += parse_dir(io, off, &hsdep); - if (udp->d_reclen == 0 && dirp->loc <= ip->i_size) { - dirp->loc = roundup(dirp->loc, ISO_SECTOR_SIZE); - continue; - } - return (&hsdep); - } -} - -static int -getblock(struct iob *io) -{ - register struct hs_volume *fsp; - register struct inode *ip = &io->i_ino; - register int off, size, diff; - register daddr_t lbn; -#ifdef SPIN_IND - static int pos; - static char ind[] = "|/-\\"; - static int blks_read; -#endif /* SPIN_IND */ - - diff = ip->i_size - io->i_offset; - if (diff <= 0) - return (-1); - - fsp = &io->ui_hsfs; - - /* which block (or frag) in the file do we read? */ - lbn = hdbtodb(io->i_offset >> ISO_SECTOR_SHIFT); - io->i_bn = lbn + hdbtodb(ip->i_number); - - off = io->i_offset & ((1 << ISO_SECTOR_SHIFT) - 1); - size = sizeof (io->i_buf); - io->i_ma = io->i_buf; - io->i_cc = size; - - if (devread(&io->i_si) != size) /* Trap errors */ - return (-1); - -#ifdef SPIN_IND - /* - * round and round she goes (though not on every block.. - * - Even SunMON proms take some time to actually print stuff) - */ - if ((blks_read++ & 0x3) == 0) - (*printf_p)("%c\b", ind[pos++ & 3]); -#endif /* SPIN_IND */ - - if (io->i_offset - off + size >= ip->i_size) - io->i_cc = diff + off; - io->i_cc -= off; - - io->i_ma = &io->i_buf[off]; - return (0); -} - -int -read(int fd, caddr_t buf, int count) -{ - register i, j; - register struct iob *io = &iob[fd]; - register struct inode *ip = &io->i_ino; - caddr_t n; - - n = buf; - - if (io->i_offset + count > ip->i_size) - count = ip->i_size - io->i_offset; - - if ((i = count) <= 0) - return (0); - - while (i > 0) { - if (io->i_cc <= 0) { - if (getblock(io) == -1) - return (0); - } - j = MIN(i, io->i_cc); - bcopy(io->i_ma, buf, (unsigned)j); - buf += j; - io->i_ma += j; - io->i_offset += j; - io->i_cc -= j; - i -= j; - } - return (buf - n); -} - -/* - * We use the token iob for reading the "super block". - */ -static int -mountroot() -{ - struct bootparam *bp; - struct hs_volume *fsp; - char *bufp; - int err; - int i; - - /* This really has to be done only once. */ - if (root_ino == 0) { - - bp = *(romp->sunmon.v_bootparam); - - fsp = &iob->ui_hsfs; - bufp = iob->i_buf; - - iob->i_boottab = bp->bp_boottab; - iob->i_ino.i_dev = 0; - iob->i_ctlr = bp->bp_ctlr; - iob->i_unit = bp->bp_unit; - iob->i_boff = bp->bp_part; - - /* make the prom open the device */ - if (err = devopen(&iob->i_si)) - return (-1); /* if devopen fails, open fails */ - - /* now opening file system; read the superblock. */ - iob->i_ma = iob->i_buf; - iob->i_cc = ISO_SECTOR_SIZE; - iob->i_bn = hdbtodb(ISO_VOLDESC_SEC); - iob->i_offset = 0; - if ((err = devread(&iob->i_si)) != ISO_SECTOR_SIZE) - return (-1); - - bufp = iob->i_buf; - fsp = &iob->ui_hsfs; - - /* Since RRIP is based on ISO9660, that's where we start */ - - if (ISO_DESC_TYPE(bufp) != ISO_VD_PVD) - return (-1); - if (strncmp(ISO_std_id(bufp), ISO_ID_STRING, ISO_ID_STRLEN) != 0) - return (-1); - if (ISO_STD_VER(bufp) != ISO_ID_VER) - return (-1); - - /* Now we fill in the volume descriptor */ - fsp->vol_size = ISO_VOL_SIZE(bufp); - fsp->lbn_size = ISO_BLK_SIZE(bufp); - fsp->lbn_shift = ISO_SECTOR_SHIFT; - fsp->lbn_secshift = ISO_SECTOR_SHIFT; - fsp->vol_set_size = (ushort_t)ISO_SET_SIZE(bufp); - fsp->vol_set_seq = (ushort_t)ISO_SET_SEQ(bufp); - - /* Make sure we have a valid logical block size */ - if (fsp->lbn_size & ~(1 << fsp->lbn_shift)) { - (*printf_p)("%d invalid logical block size\n", - fsp->lbn_size); - return (-1); - } - - /* Since an HSFS root could be located anywhere on the media! */ - root_ino = IDE_EXT_LBN(ISO_root_dir(bufp)); - } -} - -/* - * Open a file. For the bootblock, we assume one file can be opened - * on a ufs filesystem. The underlying device is the one we rode in on. - */ -int -open(char *str, int flags) -{ - register struct iob *ior; - register struct bootparam *bp; - register struct hs_volume *fsp; - register struct hs_direntry *dirp; - register char *bufp; - ino_t ino; - int err; - - /* Make sure we are set up */ - mountroot(); - - bp = *(romp->sunmon.v_bootparam); - - ior = iob; - fsp = &ior->ui_hsfs; - dirp = &fsp->root_dir; - bufp = ior->i_buf; - - ior->i_boottab = bp->bp_boottab; - ior->i_ino.i_dev = 0; - ior->i_ctlr = bp->bp_ctlr; - ior->i_unit = bp->bp_unit; - ior->i_boff = bp->bp_part; - - if ((ino = find(str, ior)) == 0) { - (*printf_p)("%s not found\n", str); - return (-1); - } - - ior->i_bn = hdbtodb(ino); - ior->i_offset = 0; - ior->i_cc = 0; - - return (0); -} - -int -close(int fd) -{ - struct iob *file = &iob[fd]; - - return (devclose(&file->i_si)); -} - -/* - * This version of seek() only performs absolute seeks (whence == 0). - */ -int -seek(int fd, off_t addr) -{ - struct iob *io = &iob[fd]; - - io->i_offset = addr; - io->i_bn = addr / DEV_BSIZE; - io->i_cc = 0; - return (0); -} - -/* - * Parse a directory entry. - * - */ -static uint_t -parse_dir( - struct iob *io, /* current dir block */ - int offset, /* offset into dir blk for dir entry */ - struct hs_direct *hsdep) /* return value: parsed entry */ -{ - char *bufp = (char *)(io->i_ma + offset); - struct hs_volume *fsp = &io->ui_hsfs; - struct direct *udp = &hsdep->hs_ufs_dir; /* ufs-style dir info */ - struct hs_direntry *hdp = &hsdep->hs_dir; /* hsfs-style dir info */ - int ce_buf[ISO_SECTOR_SIZE/sizeof (int)]; /* continuation area buffer */ - uint_t ce_lbn; - uint_t ce_len; - uint_t nmlen; - uint_t i; - uchar_t c; - int ret_code; - - /* a zero length dir entry terminates the dir block */ - if (!(udp->d_reclen = IDE_DIR_LEN(bufp))) - return (0); - - /* fill in some basic hsfs info */ - hdp->ext_lbn = IDE_EXT_LBN(bufp); - hdp->ext_size = IDE_EXT_SIZE(bufp); - hdp->xar_len = IDE_XAR_LEN(bufp); - hdp->intlf_sz = IDE_INTRLV_SIZE(bufp); - hdp->intlf_sk = IDE_INTRLV_SKIP(bufp); - hdp->sym_link = NULL; - - /* we use lbn of data extent as an inode # equivalent */ - udp->d_ino = hdp->ext_lbn; - - c = IDE_FLAGS(bufp); - if (IDE_REGULAR_FILE(c)) { - hdp->type = VREG; - hdp->mode = IFREG; - hdp->nlink = 1; - } else if (IDE_REGULAR_DIR(c)) { - hdp->type = VDIR; - hdp->mode = IFDIR; - hdp->nlink = 2; - } else { - (*printf_p)("pd(): file type=0x%x unknown.\n", c); - return (-1); - } - - /* - * Massage hsfs name, recognizing special entries for . and .. - * else lopping off version junk. - */ - - /* Some initial conditions */ - nmlen = IDE_NAME_LEN(bufp); - c = *IDE_NAME(bufp); - /* Special Case: Current Directory */ - if (nmlen == 1 && c == '\0') { - udp->d_name[0] = '.'; - udp->d_name[1] = '\0'; - udp->d_namlen = 1; - /* Special Case: Parent Directory */ - } else if (nmlen == 1 && c == '\001') { - udp->d_name[0] = '.'; - udp->d_name[1] = '.'; - udp->d_name[2] = '\0'; - udp->d_namlen = 2; - /* Other file name */ - } else { - udp->d_namlen = 0; - for (i = 0; i < nmlen; i++) { - c = *(IDE_name(bufp)+i); - if (c == ';') - break; - else if (c == ' ') - continue; - else - udp->d_name[udp->d_namlen++] = c; - } - udp->d_name[udp->d_namlen] = '\0'; - } - - /* System Use Fields */ - ce_len = IDE_SUA_LEN(bufp); - - if (ce_len > 0) { - /* there is an SUA for this dir entry; go parse it */ - ce_lbn = parse_susp((char *)IDE_sys_use_area(bufp), - &ce_len, hsdep); - - if (ce_lbn) { - /* - * store away current position in dir, - * as we will be using the iobuf to reading SUA. - */ - daddr_t save_bn = io->i_bn; - daddr_t save_offset = io->i_offset; - caddr_t save_ma = io->i_ma; - int save_cc = io->i_cc; - do { - io->i_cc = ISO_SECTOR_SIZE; - io->i_offset = 0; - io->i_bn = hdbtodb(ce_lbn); - io->i_ma = (char *)ce_buf; - ret_code = devread(&io->i_si); - if (ret_code != ISO_SECTOR_SIZE) { - ce_len = 0; - ce_lbn = 0; - break; - } - ce_lbn = parse_susp(io->i_ma, &ce_len, hsdep); - } while (ce_lbn); - io->i_bn = save_bn; - io->i_offset = save_offset; - io->i_ma = save_ma; - io->i_cc = save_cc; - } - } - return (udp->d_reclen); -} - -/* - * Parse the System Use Fields in this System Use Area. - * Return blk number of continuation/SUA, or 0 if no continuation/not a SUA. - */ -static uint_t -parse_susp(char *bufp, uint_t *len, struct hs_direct *hsdep) -{ - register struct direct *udp = &hsdep->hs_ufs_dir; /* ufs-style info */ - char *susp; - uint_t cur_off = 0; - uint_t blk_len = *len; - uint_t susp_len = 0; - uint_t ce_lbn = 0; - uint_t i; - - while (cur_off < blk_len) { - susp = (char *)(bufp + cur_off); - - /* - * A null entry, or an entry with zero length - * terminates the SUSP. - */ - if (susp[0] == '\0' || susp[1] == '\0' || - (susp_len = SUF_LEN(susp)) == 0) - break; - - /* - * Compare current entry to all known signatures. - */ - for (i = 0; i < hsfs_num_sig; i++) - if (strncmp(hsfs_sig_tab[i], susp, SUF_SIG_LEN) == 0) - break; - switch (i) { - case SUSP_SP_IX: - /* SP signature: field tells us where SUA is */ - if (CHECK_BYTES_OK(susp)) { - cur_off = SP_SUA_OFFSET(susp); - } - break; - case SUSP_CE_IX: - /* - * CE signature: continuation of SUSP. - * will want to return new lbn, len. - */ - ce_lbn = CE_BLK_LOC(susp); - *len = CE_CONT_LEN(susp); - cur_off += susp_len; - break; - case SUSP_ST_IX: - /* ST signature: terminates SUSP */ - return (ce_lbn); - case RRIP_RR_IX: - /* XXX do we want to break when we see a RR? */ - cur_off += susp_len; - break; - case RRIP_NM_IX: - /* NM signature: POSIX-style file name */ - if (!RRIP_NAME_FLAGS(susp)) { - udp->d_namlen = RRIP_NAME_LEN(susp); - bcopy((char *)RRIP_name(susp), - udp->d_name, udp->d_namlen); - udp->d_name[udp->d_namlen] = '\0'; - } - break; - - case HSFS_NUM_SIG: - /* couldn't find a legit susp, terminate loop */ - (*printf_p)("parse_susp(): Bad SUSP\n"); - cur_off = blk_len; - break; - - default: - cur_off += susp_len; - } - } - return (ce_lbn); -} diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs.fth b/usr/src/psm/stand/bootblks/hsfs/common/hsfs.fth new file mode 100644 index 0000000000..d5c3df8cb2 --- /dev/null +++ b/usr/src/psm/stand/bootblks/hsfs/common/hsfs.fth @@ -0,0 +1,636 @@ + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ + +id: %Z%%M% %I% %E% SMI +purpose: HSFS file system support package for NewBoot +copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved + +\ High Sierra, Rock Ridge (CD-ROM) file system reader and boot block + +headers +" /packages" get-package push-package + +new-device + fs-pkg$ device-name diag-cr? + + \ + \ HSFS variables + \ + 0 instance value dev-ih + 0 instance value vol-desc + 0 instance value dir-buf + 0 instance value sua-buf + 0 instance value ce-buf + + \ + \ HSFS volume descriptor routines + \ + + \ unaligned load of 2-byte item + : xw@ ( adr -- n ) + dup c@ swap char+ ( c0 adr+1 ) + c@ ( c0 c1 ) + bwjoin + ; + + \ unaligned store of 2-byte item + : xw! ( n adr -- ) + swap wbsplit swap 2 pick c! swap char+ c! + ; + + \ unaligned load of 4-byte item + : xl@ ( adr -- n ) + dup xw@ swap wa1+ ( w0 adr+2 ) + xw@ ( w0 w1 ) + wljoin + ; + \ unaligned store of 4-byte item + : xl! ( n adr -- ) + swap lwsplit swap 2 pick xw! swap wa1+ xw! + ; + + d# 2048 constant /sector + d# 16 constant vol-desc-sector# ( -- n ) + + : +vd ( index -- adr ) + vol-desc 0= if + ." invalid access of +vd" cr abort + then + vol-desc + + ; + + : root-dir ( -- n ) d# 156 +vd ; + : /block ( -- n ) d# 128 +vd xw@ ; + : byte>blkoff ( byte-off -- block-off ) /block mod ; + + : get-vol-desc ( -- ) + vol-desc /sector vol-desc-sector# /sector * dev-ih read-disk + ; + + : read-fs-blocks ( adr len fs-blk# -- ) /block * dev-ih read-disk ; + + \ + \ HSFS directory routines + \ + + \ Current directory variables. + instance variable cdir-blk \ Current directory device block ptr. + instance variable cdir-blk0 \ Current directory block0. + instance variable cdir-offset \ Current directory logical offset. + instance variable cdir-size \ Current directory logical size. + instance variable cdir-ptr \ Current directory entry pointer. + false instance value cdir-rescan \ Rescan current directory for symlink. + + \ Access of current directory entry. + : +dr ( n -- adr ) cdir-ptr @ + ; + + : dir-entrylen ( -- n ) d# 0 +dr c@ ; + : dir-block0 ( -- n ) d# 2 +dr xl@ ; + : dir-block0! ( n -- ) d# 2 +dr xl! ; + : dir-filesize ( -- n ) d# 10 +dr xl@ ; + : dir-filesize! ( n -- ) d# 10 +dr xl! ; + : dir-flags ( -- n ) d# 25 +dr c@ ; + : dir-flags! ( n -- ) d# 25 +dr c! ; + : dir-filenamelen ( -- n ) d# 32 +dr c@ ; + : dir-filename ( -- adr ) d# 33 +dr ; + + : dir-isdir? ( -- flag ) dir-flags h# 02 and 0<> ; + : dir-setdir ( -- ) h# 02 dir-flags! ; + : dir-file$ ( -- adr len ) dir-filename dir-filenamelen ; + : dir-sualen ( -- len ) dir-entrylen d# 33 - dir-filenamelen - ; + + false instance value symlink? + + : get-dirblk ( -- ) + dir-buf /block cdir-blk @ read-fs-blocks + 1 cdir-blk +! + ; + + : root-dir? ( -- flag ) root-dir cdir-ptr = ; + : froot ( -- ) root-dir cdir-ptr ! ; + + \ + \ SUAs - System Use Area in directory entry (Rock Ridge + \ Extensions to High Sierra/ISO 9660 Format). + \ Immediately follows directory entry name rounded up to + \ a half-word boundary. + \ + 0 instance value sua-ptr + 0 instance value sua-len + + : +suf ( n -- adr ) sua-ptr + ; + : suf-sig ( -- adr len ) sua-ptr 2 ; + : suf-len ( -- len ) 2 +suf c@ ; + : suf-dat ( -- data ) 5 +suf ; + : suf-ce-lbn ( -- lbn ) 4 +suf xl@ ; + : suf-ce-offset ( -- offset ) d# 12 +suf xl@ ; + : suf-ce-len ( -- len ) d# 20 +suf xl@ ; + + : init-sua ( -- ) + dir-file$ + /w roundup to sua-ptr + dir-sualen to sua-len + ; + + : next-suf ( -- ) + sua-len suf-len - to sua-len + suf-len +suf to sua-ptr + ; + + : end-sua ( -- end? ) + sua-len 4 < + ; + + : suf-nm$ ( -- adr len ) suf-dat suf-len 5 - ; + + \ Continuation suffix handling. When a 'CE' suffix is seen, + \ record the CE parameters (logical block#, offset and length + \ of continuation). We process the CE continuation only after + \ we've finished processing the current SUA area. + instance variable ce-lbn + instance variable ce-offset + instance variable ce-len + : suf-ce-set ( -- ) + suf-ce-lbn ce-lbn ! + suf-ce-offset ce-offset ! + suf-ce-len ce-len ! + ; + + : suf-ce-process ( -- error? ) + ce-lbn @ 0= if + true + else + sua-buf ce-len @ ce-lbn @ read-fs-blocks + sua-buf to sua-ptr + ce-len @ to sua-len + 0 ce-len ! 0 ce-lbn ! 0 ce-offset ! + false + then + ; + + /buf-len instance buffer: suf-sl-buf + false instance value symlink-need-sep + + \ Format of Rock Ridge symlinks needs to be munged to unix-style + \ name. Format is: <flag><nbytes>file-name<flag><nbytes>filename... + \ where \ <flag> is flag byte (0=filename, 2=current dir, 4=parent + \ dir, 8=root dir) and <nbytes> is one-byte byte count (zero for + \ !filename). + : suf-copy-to-symlinkbuf ( name$ -- ) + false to symlink-need-sep + suf-sl-buf -rot bounds do ( dst ) + symlink-need-sep if + ascii / over c! char+ + then + true to symlink-need-sep + i c@ dup 2 = if ( dst 2 ) + \ CURRENT (".") + drop ascii . over c! char+ 2 ( dst' inc ) + else dup 4 = if ( dst 4 ) + \ PARENT ("..") + drop " .." 2 pick swap move ( dst ) + wa1+ 2 ( dst' inc ) + else dup 8 = if ( dst 8 ) + \ ROOT ("/") + drop ascii / over c! char+ 2 ( dst' inc ) + false to symlink-need-sep + else dup 0<> if + ." unknown SL flag: " .x cr abort + else ( dst c ) + drop ( dst ) + i char+ dup c@ >r ( dst src+1 R:nbytes ) + char+ over r@ move ( dst R:nbytes ) + r@ + ( dst' R:nbytes ) + r> wa1+ ( dst' inc ) + then then then then + +loop ( dst ) + 0 swap c! + ; + + \ Saved 'NM' prefix buffer. + /buf-len instance buffer: suf-nm-buf + 0 instance value suf-nm-size + + \ Return the Rock Ridge file name associated with the current + \ dirent ('NM' suffix). Otherwise returns standard iso filename. + \ Marks whether returned filename is a symbolic link ('SL' suffix) + \ and also processes continuations ('CE' suffix). + : rr-file$ ( -- adr len ) + false to symlink? + 0 to suf-nm-size + + \ select start of sua, record sua offset + init-sua + begin + end-sua if + suf-ce-process if + suf-nm-size if + suf-nm-buf suf-nm-size + else + dir-file$ + then + exit + then + then + suf-sig ( sig-adr sig-len ) + 2dup " NM" $= if + suf-nm$ to suf-nm-size ( sig-adr sig-len suf-nm-adr ) + suf-nm-buf suf-nm-size move + then ( sig-adr sig-len ) + 2dup " SL" $= if + true to symlink? + suf-nm$ suf-copy-to-symlinkbuf + then + 2dup " CE" $= if + suf-ce-set + then ( sig-adr sig-len ) + 2drop next-suf ( ) + again + ; + + \ + \ HSFS high-level routines + \ + + \ Used for rescanning current directory for symbolic links. + + \ Initializes current directory settings from current directory + \ entry pointer or for rescan. If it's not a rescan, we have + \ access to the actual directory entry, so we can check whether + \ it's a directory or not here. + : init-dent ( -- error? ) + cdir-rescan if + false to cdir-rescan + cdir-blk0 @ cdir-blk ! + else + dir-isdir? 0= if + true exit + then + dir-block0 dup cdir-blk ! cdir-blk0 ! + dir-filesize cdir-size ! + then ( blk0 size ) + 0 cdir-offset ! + false + ; + + : get-dent ( -- error? ) + begin + \ Check for end of directory, return true if we're past the EOF. + cdir-offset @ cdir-size @ >= if + true exit + then + + \ If we're at a block boundary, get the next block. Otherwise + \ increment the directory pointer. + cdir-offset @ byte>blkoff 0= if + get-dirblk + dir-buf cdir-ptr ! + else + dir-entrylen cdir-ptr +! + then + + \ If dir-entrylen is not zero, increment the current directory + \ file offset. Otherwise, a dir-entrylen of zero indicates + \ the end of a dir block, so round up cdir-offset to fetch the + \ next one + dir-entrylen ?dup if + cdir-offset +! true + else + cdir-offset @ /block roundup cdir-offset ! + false + then + until false + ; + + \ directory stack + struct + /x field >dirs-size + /x field >dirs-block0 + constant /dirs-stack + + d# 10 constant #dirs-stack + #dirs-stack /dirs-stack * instance buffer: dirs-stack + instance variable dirs-stackp + + : dirs-init ( -- ) + dirs-stack dirs-stackp ! + ; + : dirs-push ( -- ) + dir-isdir? if + dirs-stackp @ + cdir-blk0 @ over >dirs-block0 ! + cdir-size @ over >dirs-size ! + /dirs-stack + dirs-stackp ! + then + ; + : dirs-pop ( -- ) + dirs-stackp @ dup dirs-stack = if + froot exit + then + /dirs-stack - + dup >dirs-block0 @ dir-block0! + dup >dirs-size @ dir-filesize! + dirs-stackp ! + dir-setdir + ; + + \ Look through current directory for file name 'file$'. + \ Will leave current directory entry (cdir-ptr) pointing + \ to matched entry on success. + : dirlook ( file$ -- error? ) + init-dent if + true exit + then + 2dup " .." $= if + 2drop dirs-pop false exit + then + 2dup " ." $= if + 2drop true to cdir-rescan false exit + then + + begin get-dent 0= while ( file$ ) + 2dup rr-file$ $= if ( file$ ) + 2drop dirs-push false exit ( succeeded ) + then ( file$ ) + repeat 2drop true ( failed ) + ; + + /buf-len instance buffer: symlink-buf + : symlink-buf$ ( -- path$ ) symlink-buf cscount ; + + : follow-symlink ( tail$ -- tail$' ) + + \ copy symlink value (plus null) to buf + suf-sl-buf cscount 1+ symlink-buf swap move + false to symlink? + + \ append to current path + ?dup if ( tail$ ) + " /" symlink-buf$ $append ( tail$ ) + symlink-buf$ $append ( ) + else drop then ( ) + symlink-buf$ ( path$ ) + over c@ ascii / = if ( path$ ) + froot str++ ( path$' ) + else + true to cdir-rescan + then ( path$ ) + ; + + : lookup ( path$ -- error? ) + dirs-init + over c@ ascii / = if + froot str++ ( path$' ) + then ( path$ ) + begin ( path$ ) + ascii / left-parse-string ( path$ file$ ) + dup while ( path$ file$ ) + dirlook if + 2drop true exit ( failed ) + then ( path$ ) + symlink? if + follow-symlink ( path$' ) + then ( path$ ) + repeat ( path$ file$ ) + 2drop 2drop false ( succeeded ) + ; + + + \ + \ HSFS installation routines + \ + + \ Allocate memory for necessary data structures. Need to + \ read volume desriptor sector in order to get /block value. + : initialize ( -- error? ) + /sector mem-alloc to vol-desc + get-vol-desc + /block mem-alloc to dir-buf + /block mem-alloc to sua-buf + /block mem-alloc to ce-buf + ; + + : release-buffers ( -- ) + ce-buf /block mem-free + sua-buf /block mem-free + dir-buf /block mem-free + vol-desc /sector mem-free + 0 to vol-desc + ; + + + \ HSFS file interface + struct + /x field >filesize + /x field >offset + /x field >block0 + constant /file-record + + d# 10 constant #opens + #opens /file-record * constant /file-records + + /file-records instance buffer: file-records + + -1 instance value current-fd + + : fd>record ( fd -- record ) /file-record * file-records + ; + + : set-fd ( fd -- error? ) + dup 0 #opens 1 - between 0= if + drop true exit + then + dup fd>record >block0 x@ 0= if + drop true exit + then + to current-fd false + ; + + : file-offset@ ( -- off ) + current-fd fd>record >offset x@ + ; + + : file-offset! ( off -- ) + current-fd fd>record >offset x! + ; + + : file-size@ ( -- size ) + current-fd fd>record >filesize x@ + ; + + : file-size! ( size -- ) + current-fd fd>record >filesize x! + ; + + : file-block0@ ( -- block0 ) + current-fd fd>record >block0 x@ + ; + + : file-block0! ( block0 -- ) + current-fd fd>record >block0 x! + ; + + : get-slot ( -- fd false | true ) + #opens 0 do + i fd>record >block0 x@ 0= if + i false unloop exit + then + loop true + ; + + : free-slot ( fd -- ) + set-fd 0= if + 0 file-offset! + 0 file-size! + 0 file-block0! + then + ; + + \ initializes the open structure with information from + \ the inode (on UFS) or directory entry (from HSFS). + : init-fd ( fd -- ) + to current-fd + dir-block0 file-block0! + dir-filesize file-size! + 0 file-offset! + ; + + external + + : open ( -- okay? ) + my-args dev-open dup 0= if ( 0 ) + exit ( failed ) + then to dev-ih + + initialize froot + file-records /file-records erase + true ( succeeded ) + ; + + : close ( -- ) + dev-ih dev-close + release-buffers + ; + + : open-file ( path$ -- fd true | false ) + get-slot if + 2drop false exit ( failed ) + then -rot ( fd path$ ) + + lookup if ( fd ) + drop false exit ( failed ) + then + + dup init-fd true ( fd success ) + ; + + : close-file ( fd -- ) + free-slot ( ) + ; + + : read-file ( adr len fd -- #read ) + + \ Check if fd is valid, if it is set current-fd. + set-fd if + 2drop 0 exit + then ( adr len ) + + \ Adjust len if less than len bytes remain. + file-size@ file-offset@ - min ( adr len' ) + + \ Check for invalid length read. + dup 0<= if 2drop 0 exit then + + \ Compute physical device byte offset. + tuck ( len adr len ) + file-block0@ /block * file-offset@ + ( len adr len off ) + dev-ih read-disk ( #read ) + ; + + : seek-file ( off fd -- error? ) + set-fd if ( off ) + drop false exit ( failed ) + then ( off ) + + dup file-size@ > if ( off ) + drop false exit ( failed ) + then ( off ) + dup file-offset! true ( off succeeded ) + ; + + : size-file ( fd -- size ) + set-fd if + 0 + else + file-size@ + then + ; + + \ we don't support compression (yet) + : cinfo-file ( fd -- bsize fsize comp? ) + set-fd if 0 0 0 else /block file-size@ 0 then + ; + + \ read ramdisk fcode at rd-offset + : get-rd ( adr len -- ) + rd-offset dev-ih read-disk + ; + + \ no additional props needed for hsfs + : bootprop ( -- ) false ; + + \ debug words + : chdir ( path$ -- ) + 2dup lookup if + type ." Not found" cr + else + dir-isdir? 0= if + type ." Not a directory" cr + else + type + ." blk0 " + cdir-blk0 @ .x + ." size " + cdir-size @ .x + cr + then + then + ; + + : dir ( -- ) + init-dent + begin get-dent 0= while + rr-file$ type + ." flags " dir-flags .x + ." blk0 " dir-block0 .x + ." size " dir-filesize .x + cr + repeat + true to cdir-rescan + ; + + +finish-device +pop-package + diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h b/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h deleted file mode 100644 index 2b18abe8e7..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h +++ /dev/null @@ -1,66 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright, 1991-1994, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef HANDLE_CONTINUATION -static char *hsfs_sig_tab[] = { - SUSP_SP, - SUSP_CE, - SUSP_PD, - SUSP_ST, - SUSP_ER, - RRIP_PX, - RRIP_PN, - RRIP_SL, - RRIP_CL, - RRIP_PL, - RRIP_RE, - RRIP_TF, - RRIP_RR, - RRIP_NM -}; - -static int hsfs_num_sig = sizeof (hsfs_sig_tab) / sizeof (hsfs_sig_tab[0]); -#endif /* HANDLE_CONTINUATION */ - -#define HSFS_NUM_SIG 14 - -#define SUSP_SP_IX 0 -#define SUSP_CE_IX 1 -#define SUSP_PD_IX 2 -#define SUSP_ST_IX 3 -#define SUSP_ER_IX 4 - -#define RRIP_PX_IX 5 -#define RRIP_PN_IX 6 -#define RRIP_SL_IX 7 -#define RRIP_CL_IX 8 -#define RRIP_PL_IX 9 -#define RRIP_RE_IX 10 -#define RRIP_RF_IX 11 -#define RRIP_RR_IX 12 -#define RRIP_NM_IX 13 diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c b/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c deleted file mode 100644 index b89892eafd..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c +++ /dev/null @@ -1,674 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1991-1994, Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* from "@(#)boot/ufssys.c 1.1 90/03/28 SMI" */ - -/* - * Basic file system reading code for standalone I/O system. - */ - -/* - * This code must be kept very small. If space allows, you can - * turn on the ability to handle continuations (and other signatures) - * by #defining HANDLE_CONTINUATION. - */ - -#include <sys/param.h> -#include <sys/vnode.h> -#include <sys/fs/ufs_fsdir.h> -#include <sys/fs/ufs_fs.h> -#include <sys/fs/ufs_inode.h> - -#include <sys/fs/hsfs_spec.h> -#include <sys/fs/hsfs_isospec.h> -#include <sys/fs/hsfs_node.h> -#include <sys/fs/hsfs_susp.h> -#include <sys/fs/hsfs_rrip.h> - -#include "iob.h" -#include "cbootblk.h" - -#include "hsfs_sig.h" - -#define NULL 0 - -#define TRUE 1 -#define FALSE 0 - -#define hdbtodb(n) ((ISO_SECTOR_SIZE / DEV_BSIZE) * (n)) - -#ifdef DEBUG -/* debugging printfs */ -#define DEBUG_PRINTF0(s) \ - fprintf(stderr, s) -#define DEBUG_PRINTF1(s, a1) \ - fprintf(stderr, s, (a1)) -#define DEBUG_PRINTF2(s, a1, a2) \ - fprintf(stderr, s, (a1), (a2)) -#define DEBUG_PRINTF3(s, a1, a2, a3) \ - fprintf(stderr, s, (a1), (a2), (a3)) -#define DEBUG_PRINTF4(s, a1, a2, a3, a4) \ - fprintf(stderr, s, (a1), (a2), (a3), (a4)) -#define DEBUG_PRINTF5(s, a1, a2, a3, a4, a5) \ - fprintf(stderr, s, (a1), (a2), (a3), (a4), (a5)) -#else -#define DEBUG_PRINTF0(s) -#define DEBUG_PRINTF1(s, a1) -#define DEBUG_PRINTF2(s, a1, a2) -#define DEBUG_PRINTF3(s, a1, a2, a3) -#define DEBUG_PRINTF4(s, a1, a2, a3, a4) -#define DEBUG_PRINTF5(s, a1, a2, a3, a4, a5) -#endif - -char fscompname[] = "hsfsboot"; - -static struct iob iob[1]; /* only one open file! */ - -static u_int dlook(char *, register struct iob *); -static int parse_dir(struct iob *, int, u_char *, u_int *, u_int *); -static u_int parse_susp(u_char *, u_int *, u_char *, u_int *, u_int *); -static int read_sector(struct iob *, u_int, char *, u_char); - -static int -read_sector(struct iob *io, u_int iso_secno, char *buf, u_char next) -{ -#ifdef DEBUG - static char *msg = "rs:[%c] o=%d b=%d c=%d n=%d\n"; -#endif - DEBUG_PRINTF5(msg, 'I', io->i_offset, io->i_bn, io->i_cc, next); - - io->i_cc = ISO_SECTOR_SIZE; - io->i_ma = buf; - - if (next == TRUE) { - io->i_bn += (ISO_SECTOR_SIZE / DEV_BSIZE); - } else { - io->i_offset = 0; - io->i_bn = hdbtodb(iso_secno); - } - - if (devbread(&io->i_si, io->i_ma, - io->i_bn, io->i_cc) != ISO_SECTOR_SIZE) { - DEBUG_PRINTF5(msg, '0', io->i_offset, - io->i_bn, io->i_cc, next); - return (0); - } - - DEBUG_PRINTF5(msg, '1', io->i_offset, io->i_bn, io->i_cc, next); - return (1); -} - -/* - * Look up a file, pathname component by pathname component. - * Return lbn of file if found, 0 otherwise. - */ -static u_int -find(char *path, struct iob *file) -{ - char *q; - char c; - u_int n; - - if (path == NULL || *path == '\0') - return (0); - - while (*path) { - while (*path == '/') - path++; - q = path; - while (*q != '/' && *q != '\0') - q++; - c = *q; - *q = '\0'; - - if ((n = dlook(path, file)) != 0) { - DEBUG_PRINTF1("fnd: n=%d\n", n); - if (c == '\0') - break; - if (!read_sector(file, n, file->i_buf, FALSE)) - return (0); - *q = c; - path = q; - continue; - } else { - return (0); - } - } - return (n); -} - -/* - * Look up the file in the directory. - * Return lbn of file extent on success, 0 on failure. - */ -static u_int -dlook(char *s, struct iob *io) -{ - struct hs_volume *fsp = &io->ui_hsfs; - struct hs_direntry *dirp = &fsp->root_dir; - int dirsz = dirp->ext_size; - u_char nameb[MAXPATHLEN]; - u_int nml; - u_int blkloc = 0; - u_int dirloc; - u_int reclen; - u_int len; - u_int altnm; - - if (s == NULL || *s == '\0') - return (0); - - if (dirp->type != VDIR) - return (0); - - len = strlen(s); - - while (blkloc < dirsz) { - dirloc = 0; - while (dirloc < ISO_SECTOR_SIZE) { - altnm = 0; - nml = sizeof (nameb); - reclen = parse_dir(io, dirloc, nameb, &nml, &altnm); - dirloc += reclen; - if (!reclen) - break; - if (altnm) { - if (len != nml || - strncmp(s, (char *)nameb, len) != 0) - continue; - } else { - if (strncmp(s, (char *)nameb, len) != 0) - continue; - } - DEBUG_PRINTF1("dl: ret lb=%d\n", dirp->ext_lbn); - return ((u_int) dirp->ext_lbn); - } - if (blkloc + ISO_SECTOR_SIZE < dirsz) { - if (!read_sector(io, 0, io->i_buf, TRUE)) - return (0); - } - blkloc += ISO_SECTOR_SIZE; - } - return (0); -} - -static int -getblock(register struct iob *io) -{ - u_int lbn; - int off, size, diff; - struct hs_volume *fsp = &io->ui_hsfs; - struct hs_direntry *dirp = &fsp->root_dir; - - diff = dirp->ext_size - io->i_offset; - if (diff <= 0) - return (-1); - lbn = hdbtodb(io->i_offset >> ISO_SECTOR_SHIFT); - io->i_bn = lbn + hdbtodb(dirp->ext_lbn); - off = io->i_offset % ISO_SECTOR_SIZE; - size = sizeof (io->i_buf); - io->i_cc = size; - io->i_ma = io->i_buf; - - if (devbread(&io->i_si, io->i_ma, - io->i_bn, io->i_cc) != io->i_cc) /* Trap errors */ - return (-1); - - if (io->i_offset - off + size >= dirp->ext_size) - io->i_cc = diff + off; - io->i_cc -= off; - - io->i_ma = &io->i_buf[off]; - return (0); -} - -int -readfile(int fd, char *buf, int count) -{ - int i, j; - struct iob *io = &iob[fd]; - struct iob *file = io; - struct hs_volume *fsp = &file->ui_hsfs; - struct hs_direntry *dirp = &fsp->root_dir; - - if (file->i_offset + count > dirp->ext_size) - count = dirp->ext_size - file->i_offset; - if ((i = count) <= 0) - return (0); - while (i > 0) { - if (file->i_cc <= 0) { - if (getblock(file) == -1) - return (0); - } - j = (i < file->i_cc) ? i : file->i_cc; - bcopy(file->i_ma, buf, (unsigned)j); - buf += j; - file->i_ma += j; - file->i_offset += j; - file->i_cc -= j; - i -= j; - } - return (count); -} - -/* - * Open a file. For the bootblock, we assume one file can be opened - * on a hsfs filesystem. The underlying device is the one we rode in on. - */ -int -openfile(char *device, char *pathname) -{ - struct iob *io = &iob[0]; /* only one open file! */ - register struct hs_volume *fsp; - register char *bufp; - u_int lbn; - - DEBUG_PRINTF0("open\n"); - - fsp = &io->ui_hsfs; - bufp = io->i_buf; - - if ((io->i_si = devopen(device)) == NULL) - return (-1); /* if devopen fails, open fails */ - /* - * Pseudo-mount a file system; read the superblock. - */ - if (!read_sector(io, ISO_VOLDESC_SEC, bufp, FALSE)) - goto failed; - - /* Make sure we start with a clean slate. */ - (void) bzero((char *)fsp, sizeof (io->ui_hsfs)); - - /* Since RRIP is based on ISO9660, that's where we start */ - - if (ISO_DESC_TYPE(bufp) != ISO_VD_PVD || - strncmp((char *)ISO_std_id(bufp), ISO_ID_STRING, - ISO_ID_STRLEN) != 0 || - ISO_STD_VER(bufp) != ISO_ID_VER) { - puts("bootblk: not an ISO9660 file system.\n"); - goto failed; - } - - /* Now we fill in the volume descriptor */ - fsp->vol_size = ISO_VOL_SIZE(bufp); - fsp->lbn_size = ISO_BLK_SIZE(bufp); - fsp->lbn_shift = ISO_SECTOR_SHIFT; - fsp->lbn_secshift = ISO_SECTOR_SHIFT; - fsp->vol_set_size = (u_short) ISO_SET_SIZE(bufp); - fsp->vol_set_seq = (u_short) ISO_SET_SEQ(bufp); - - /* Make sure we have a valid logical block size */ - if (fsp->lbn_size & ~(1 << fsp->lbn_shift)) { - DEBUG_PRINTF1("%d byte logical block size invalid.", - fsp->lbn_size); - goto failed; - } - - /* Read the ROOT directory */ - if (!read_sector(io, IDE_EXT_LBN(ISO_root_dir(bufp)), bufp, FALSE)) - goto failed; - - /* Extract the ROOT directory information from the directory block */ - (void) parse_dir(io, 0, NULL, (u_int *) 0, (u_int *) 0); - - if (!(lbn = find(pathname, io))) - goto failed; - - DEBUG_PRINTF1("lb=%d\n", lbn); - - io->i_bn = hdbtodb(lbn); - io->i_offset = 0; - io->i_cc = 0; - - return (0); /* only one open file! */ -failed: - (void) devclose(io->i_si); - return (-1); -} - -int -closefile(int fd) -{ - struct iob *io = &iob[fd]; - - return (devclose(io->i_si)); -} - -/* - * This version of seek() only performs absolute seeks (whence == 0). - */ -void -seekfile(int fd, off_t addr) -{ - struct iob *io = &iob[fd]; - - io->i_offset = addr; - io->i_bn = addr >> DEV_BSHIFT; - io->i_cc = 0; -} - -/* - * Return the next directory entry. - * Return 0 if no next entry, length of directory entry otherwise. - */ -static int -parse_dir( - struct iob *io, /* current dir block */ - int offset, /* dir entry offset into dir blk */ - u_char *namep, /* output: name found */ - u_int *namelen, /* output: length of name found */ - u_int *anm) /* output: found RR (altrnt) nm flg */ -{ - u_char *bufp = (u_char *)(io->i_buf + offset); - struct hs_direntry *dirp = &(io->ui_hsfs.root_dir); - static u_char ce_buf[ISO_SECTOR_SIZE]; - u_int ce_len; - static u_char nmbuf[MAXPATHLEN]; - u_int nmlen; - u_int altnm = 0; /* found RR name flag */ - u_char c; - u_int dir_len = IDE_DIR_LEN(bufp); - - DEBUG_PRINTF1("pd %d\n", dir_len); - - if (!dir_len) - /* zero length directory, done */ - return (0); - - dirp->ext_lbn = IDE_EXT_LBN(bufp); - dirp->ext_size = IDE_EXT_SIZE(bufp); - dirp->xar_len = IDE_XAR_LEN(bufp); - dirp->intlf_sz = IDE_INTRLV_SIZE(bufp); - dirp->intlf_sk = IDE_INTRLV_SKIP(bufp); - dirp->sym_link = NULL; - - c = IDE_FLAGS(bufp); - if (IDE_REGULAR_FILE(c)) { - dirp->type = VREG; - dirp->mode = IFREG; - dirp->nlink = 1; - } else if (IDE_REGULAR_DIR(c)) { - dirp->type = VDIR; - dirp->mode = IFDIR; - dirp->nlink = 2; - } else { - DEBUG_PRINTF1("pd: ftype=0x%x unknown.\n", c); - return (-1); - } - - /* - * Massage hsfs name, recognizing special entries for . and .. - * else lopping off version junk. - */ - - /* Some initial conditions */ - nmlen = IDE_NAME_LEN(bufp); - c = *IDE_NAME(bufp); - /* Special Case: Current Directory */ - if (nmlen == 1 && c == '\0') { - nmbuf[0] = '.'; - nmbuf[1] = '\0'; - nmlen = 1; - /* Special Case: Parent Directory */ - } else if (nmlen == 1 && c == '\001') { - nmbuf[0] = '.'; - nmbuf[1] = '.'; - nmbuf[2] = '\0'; - nmlen = 2; - /* Other file name */ - } else { - register int l = nmlen; - register int i; - - nmlen = 0; - for (i = 0; i < l; i++) { - c = *(IDE_name(bufp)+i); - if (c == ';') - break; - else if (c == ' ') - continue; - else - nmbuf[nmlen++] = c; - } - nmbuf[nmlen] = '\0'; - } - - DEBUG_PRINTF0("pd bf sua"); - -#ifdef HANDLE_CONTINUATION - /* System Use Fields */ - ce_len = IDE_SUA_LEN(bufp); - if (ce_len) { - /* there is an SUA for this dir entry; go parse it */ - u_int ce_lbn; - u_int nmbsz = sizeof (nmbuf); - - bcopy((char *)IDE_sys_use_area(bufp), (char *)ce_buf, ce_len); - ce_lbn = parse_susp(ce_buf, &ce_len, nmbuf, &nmbsz, &altnm); - - while (ce_lbn) { - /* - * Process continuation of SUA, - * saving current position in dir, - * as will be using iobuf to read SUA continuation. - */ - daddr_t save_bn = io->i_bn; - daddr_t save_offset = io->i_offset; - int save_cc = io->i_cc; - int rd_ok; - - rd_ok = read_sector(io, ce_lbn, (char *)ce_buf, FALSE); - - io->i_bn = save_bn; - io->i_offset = save_offset; - io->i_cc = save_cc; - - if (!rd_ok) - return (0); - - ce_lbn = parse_susp(ce_buf, &ce_len, nmbuf, &nmbsz, - &altnm); - } - if (altnm) - nmlen = nmbsz; - } -#else /* HANDLE_CONTINUATION */ - /* System Use Fields */ - ce_len = IDE_SUA_LEN(bufp); - if (ce_len) { - /* there is an SUA for this dir entry; go parse it */ - - u_int nmbsz = sizeof (nmbuf); - - bcopy((char *)IDE_sys_use_area(bufp), (char *)ce_buf, ce_len); - (void) parse_susp(ce_buf, &ce_len, nmbuf, &nmbsz, &altnm); - - if (altnm) - nmlen = nmbsz; - } -#endif /* HANDLE_CONTINUATION */ - - DEBUG_PRINTF0("pd af sua"); - - if (anm != NULL) - *anm = altnm; - - if (namep != NULL && namelen != NULL && *namelen) { - /* assert(namelen >= nmlen) */ - bcopy((char *)nmbuf, (char *)namep, nmlen); - *namelen = nmlen; - } - -#ifdef DEBUG - if (altnm) - nmbuf[nmlen] = '\0'; -#endif /* DEBUG */ - - DEBUG_PRINTF2("Nm(%d)=%s\n", nmlen, nmbuf); - DEBUG_PRINTF2(" lbn/len = %d/%d\n", dirp->ext_lbn, dirp->ext_size); - DEBUG_PRINTF0("pd end\n"); - - return (dir_len); -} - -#ifdef HANDLE_CONTINUATION -/* - * Parse the System Use Fields in the System Use Area. - * Return block number of continuation (if any), - * or 0 if no continuation. - */ -static u_int -parse_susp( - u_char *bufp, - u_int *len, - u_char *nmp, - u_int *nmlen, - u_int *altnm) /* found RR name */ -{ - u_char *susp; - u_int cur_off = 0; - u_int blk_len = *len; - u_int susp_len = 0; - u_int ce_lbn = 0; - u_int i; - - DEBUG_PRINTF1("ps: l=%d\n", *len); - - while (cur_off < blk_len) { - susp = (u_char *)(bufp + cur_off); - /* - * A null entry, or an entry with zero length - * terminates the SUSP. - */ - if (susp[0] == '\0' || susp[1] == '\0' || - (susp_len = SUF_LEN(susp)) == 0) - break; - - /* Compare current entry to all known signatures */ - for (i = 0; i < HSFS_NUM_SIG; i++) { - if (strncmp(hsfs_sig_tab[i], susp, SUF_SIG_LEN) == 0) { - DEBUG_PRINTF3("SUSP_%c%c %d\n", susp[0], - susp[1], susp_len); - break; - } - } - - switch (i) { - case SUSP_CE_IX: - /* - * CE signature: continuation of SUSP. - * will want to return new lbn, len. - */ - ce_lbn = CE_BLK_LOC(susp); - *len = CE_CONT_LEN(susp); - break; - case SUSP_ST_IX: - /* ST signature: terminates SUSP */ - return (ce_lbn); - case RRIP_RR_IX: - /* XXX do we want to break when we see a RR? */ - break; - case RRIP_NM_IX: - /* NM signature: POSIX-style file name */ - DEBUG_PRINTF0(" NM\n"); - if (!RRIP_NAME_FLAGS(susp)) { - /* copy out new name if requested */ - if (*nmlen) { - *nmlen = RRIP_NAME_LEN(susp); - /* assert(old(nmlen) >= new(nmlen)) */ - bcopy((char *)RRIP_name(susp), - (char *)nmp, *nmlen); - *altnm = 1; - } - } - break; - case HSFS_NUM_SIG: - /* couldn't find a legit susp, complain and continue */ - (*printf_p)("parse_susp(): Bad SUSP\n"); - break; - default: - break; - } - - cur_off += susp_len; - DEBUG_PRINTF1("ps: o=%d\n", cur_off); - } - return (ce_lbn); -} - -#else /* HANDLE_CONTINUATION */ -/* - * Parse the System Use Fields in the System Use Area. - * Return block number of continuation (if any), - * or 0 if no continuation. - */ -static u_int -parse_susp( - u_char *bufp, - u_int *len, - u_char *nmp, - u_int *nmlen, - u_int *altnm) /* found RR name */ -{ - u_char *susp; - u_int cur_off = 0; - u_int blk_len = *len; - u_int susp_len = 0; - - DEBUG_PRINTF1("ps: l=%d\n", *len); - - while (cur_off < blk_len) { - susp = (u_char *)(bufp + cur_off); - - /* - * A null entry, or an entry with zero length - * terminates the SUSP. - */ - if (susp[0] == '\0' || susp[1] == '\0' || - (susp_len = SUF_LEN(susp)) == 0) - break; - - /* Compare current entry to all known signatures */ - if ((susp[0] == 'N' && susp[1] == 'M') && - !RRIP_NAME_FLAGS(susp)) { - /* copy out new name if requested */ - if (*nmlen) { - *nmlen = RRIP_NAME_LEN(susp); - /* assert(old(nmlen) >= new(nmlen)) */ - bcopy((char *)RRIP_name(susp), (char *)nmp, - *nmlen); - *altnm = 1; - } - return (0); - } - cur_off += susp_len; - DEBUG_PRINTF1("ps: o=%d\n", cur_off); - } - return (0); -} -#endif /* HANDLE_CONTINUATION */ diff --git a/usr/src/psm/stand/bootblks/hsfs/common/iob.h b/usr/src/psm/stand/bootblks/hsfs/common/iob.h deleted file mode 100644 index 844f1152fb..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/common/iob.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1990-1994, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * This struct keeps track of an open file in the standalone I/O system. - * - * It includes an IOB for device addess, a buffer for reading directory blocks - * and a structure for volume. - */ -struct iob { - void *i_si; /* I/O handle for this file */ - struct { - off_t si_offset; /* byte offset */ - char *si_ma; /* memory address to r/w */ - int si_cc; /* character count to r/w */ - int si_bn; /* block number to r/w */ - } i_saio; - struct inode i_ino; /* Buffer for inode information */ - struct hs_volume ui_hsfs; /* Superblock for file system */ - char i_buf[MAXBSIZE]; /* Buffer for reading dirs */ -}; - -#define i_offset i_saio.si_offset -#define i_bn i_saio.si_bn -#define i_ma i_saio.si_ma -#define i_cc i_saio.si_cc diff --git a/usr/src/psm/stand/bootblks/hsfs/sparc/Makefile b/usr/src/psm/stand/bootblks/hsfs/sparc/Makefile index 00d81e23f9..804c2997f2 100644 --- a/usr/src/psm/stand/bootblks/hsfs/sparc/Makefile +++ b/usr/src/psm/stand/bootblks/hsfs/sparc/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 1994, 2001-2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/bootblks/hsfs/sparc/Makefile @@ -31,7 +30,7 @@ BASEDIR = ../.. include $(BASEDIR)/hsfs/Makefile.hsfs -SUBDIRS = unix +SUBDIRS = sun4u sun4v all := TARGET= all install := TARGET= install diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4u/Makefile index 5177d46a29..5103f063d8 100644 --- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile +++ b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4u/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,34 +21,23 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 1994, 2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# psm/stand/bootblks/ufs/sparc/sun4m/Makefile +# psm/stand/bootblks/hsfs/sparc/sun4u/Makefile # # # Platform specific Makefile for the boot block. # -# PLATFORM is the target for the binary installation. -# -# PROM_TYPE is the type of prom OBP, IEEE1275, etc... -# BASEDIR = ../../.. -PLATFORM = sun4m -PROM_TYPE = OBPDEP - -include $(BASEDIR)/ufs/Makefile.ufs -include $(BASEDIR)/obp-c/Makefile.rules +PLATFORM = sun4u -CPPINCS += -I$(SRC)/uts/common -CPPINCS += -I$(SRC)/uts/sun -CPPINCS += -I$(SRC)/uts/sparc +include $(BASEDIR)/hsfs/Makefile.hsfs +include $(BASEDIR)/Makefile.1275 .KEEP_STATE: -all: $(MKBOOT) $(PROG).elf - ./$(MKBOOT) $(PROG).elf $(PROG); chmod -x $(PROG) +all: $(PROG) -include $(BASEDIR)/obp-c/Makefile.targ include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4v/Makefile index 4665376d29..31a707e696 100644 --- a/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh +++ b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4v/Makefile @@ -1,11 +1,9 @@ -#!/bin/sh # # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,28 +19,25 @@ # CDDL HEADER END # # -# Copyright 1991-2000, 2003 Sun Microsystems, Inc. -# All rights reserved. +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" +# psm/stand/bootblks/hsfs/sparc/sun4u/Makefile +# + +# +# Platform specific Makefile for the boot block. +# +BASEDIR = ../../.. +PLATFORM = sun4v -ECHO=$1 -BOOTER=$2 -FILENAME=$3 +include $(BASEDIR)/hsfs/Makefile.hsfs +include $(BASEDIR)/Makefile.1275 -BANNER="${BOOTER} 1.0 #" +.KEEP_STATE: -test -f ${BOOTER}.version || echo 0 > ${BOOTER}.version -read OLDVERS < ${BOOTER}.version; export OLDVERS -VERS=`expr ${OLDVERS} + 1` -echo $VERS > ${BOOTER}.version +all: $(PROG) -( - SCCSSTRING="@(#)${FILENAME}\tDERIVED\t%E% SMI" - ${ECHO} "/*" ; \ - ${ECHO} " * This file is derived by makevers.sh" ; \ - ${ECHO} " */\n" ; \ - ${ECHO} "#pragma\tident\t\"${SCCSSTRING}\"\n" ; \ - ${ECHO} "char ident[] = \"@(#)${BANNER}${VERS} %G%\\\n\";" -) > ${FILENAME} +include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile b/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile deleted file mode 100644 index 8aa0b74787..0000000000 --- a/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1994, by Sun Microsystems, Inc. -# All rights reserved. -# -# psm/stand/bootblks/hsfs/sparc/unix/Makefile -# - -# -# Build the "Unix" version of the boot block. -# Useful solely for testing. DO NOT INSTALL IT! -# -BASEDIR = ../../.. -PLATFORM = unix -PLATFORM_INCS = ./ -PLATLINKS = - -include $(BASEDIR)/hsfs/Makefile.hsfs -include $(BASEDIR)/obp-c/Makefile.rules - -CPPINCS += -I$(SRC)/head -CPPINCS += -I$(SRC)/uts/common -CPPINCS += -I$(SRC)/uts/sun -CPPINCS += -I$(SRC)/uts/sparc -CPPINCS += -I$(PLATFORM_INCS) - -UNIX_OBJS = hsfs_small.o unix_devio.o - -$(UNIX_OBJS) := CFLAGS += -g - -.KEEP_STATE: - -all: $(PROG) - -$(PROG): $(UNIX_OBJS) - $(CC) $(CFLAGS) $(CPPFLAGS) -g -o $@ $(UNIX_OBJS) - -lint: FRC - -clean: - $(RM) $(UNIX_OBJS) - -clobber: clean - $(RM) $(PROG) - -install: FRC - -FRC: - diff --git a/usr/src/psm/stand/bootblks/obp-c/Makefile.rules b/usr/src/psm/stand/bootblks/obp-c/Makefile.rules deleted file mode 100644 index b320f564ac..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/Makefile.rules +++ /dev/null @@ -1,105 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# psm/stand/bootblks/obp-c/Makefile.rules -# - -OBPSRCDIR = $(BASEDIR)/obp-c -OBPCMNDIR = $(OBPSRCDIR)/common -OBPMACHDIR = $(OBPSRCDIR)/$(MACH)/common -OBPPLATDIR = $(OBPSRCDIR)/$(MACH)/$(PLATFORM) - -# -# Sources and objects used to build the C-based bootblock for -# deprecated OBP V0 and V2 platforms. -# -OBPDEP_C_SRCS = stub.c -OBPDEP_S_SRCS = -OBPDEP_SRCS = $(OBPDEP_C_SRCS) $(OBPDEP_S_SRCS) -OBPDEP_SRT = obp_srt0.o -OBPDEP_OBJS = $(OBPDEP_C_SRCS:%.c=%.o) $(OBPDEP_S_SRCS:%.s=%.o) bbvers.o -OBPDEP_L_OBJS = $(OBPDEP_SRT:%.o=%.ln) $(OBPDEP_OBJS:%.o=%.ln) -OBPDEP_LD_LIBS = - -# -# Rules used to build boot blocks. PROM_TYPE is defined in the platform -# specific Makefile in ../<fs>/<mach>/<platform>/Makefile and is set to one -# of OBP or IEEE1275. -# -BOOT_OBJS = $($(PROM_TYPE)_OBJS) -BOOT_SRT = $($(PROM_TYPE)_SRT) -BOOT_L_OBJS = $($(PROM_TYPE)_L_OBJS) -BOOT_LD_LIBS = $($(PROM_TYPE)_LD_LIBS) - -MAPFILE = $(OBPMACHDIR)/mapfile - -CPPINCS += -I$(OBPCMNDIR) -I$(PSMSYSHDRDIR) -CPPFLAGS += -D_BOOT -D_KERNEL -CPPFLAGS += $(CPPINCS) $(CCYFLAG)$(PSMSYSHDRDIR) -ASFLAGS += -D_BOOT -D_ASM -P $(CPPINCS) -LDFLAGS = -dn -e start -M $(MAPFILE) -LDLIBS = $(BOOT_LD_LIBS) - -# -# lint pass1 enforcement -# -CFLAGS += $(CCVERBOSE) - -MKBOOT = mkboot -MKVERS = makevers - -# -# Pattern matching rules to compile the source in this directory -# -%.o: $(OBPCMNDIR)/%.c - $(COMPILE.c) -o $@ $< - -%.o: $(OBPMACHDIR)/%.s - $(COMPILE.s) -o $@ $< - -%.o: $(OBPMACHDIR)/%.c - $(COMPILE.c) -o $@ $< - -%.o: $(OBPPLATDIR)/%.s - $(COMPILE.s) -o $@ $< - -%.ln: $(OBPCMNDIR)/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -%.ln: $(OBPMACHDIR)/%.s - @($(LHEAD) $(LINT.s) $< $(LTAIL)) - -%.ln: $(OBPMACHDIR)/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -%.ln: $(OBPPLATHDIR)/%.s - @($(LHEAD) $(LINT.s) $< $(LTAIL)) - -%: $(OBPCMNDIR)/%.sh - $(RM) $@ - cat $< > $@ - chmod +x $@ diff --git a/usr/src/psm/stand/bootblks/obp-c/Makefile.targ b/usr/src/psm/stand/bootblks/obp-c/Makefile.targ deleted file mode 100644 index 5644b688c1..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/Makefile.targ +++ /dev/null @@ -1,61 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# psm/stand/bootblks/obp-c/Makefile.targ -# - -# -# Targets for the C-only bootblock -# -.PARALLEL: $(BOOT_SRT) $(BOOT_OBJS) $(BOOT_L_OBJS) - -$(PROG).elf: $(BOOT_SRT) $(BOOT_OBJS) $(MAPFILE) - $(LD) $(LDFLAGS) -o $@ $(BOOT_SRT) $(BOOT_OBJS) $(LDLIBS) - -$(MKBOOT): $(OBPCMNDIR)/$$(@).c - $(NATIVECC) -o $@ $(OBPCMNDIR)/$@.c - -$(PROG): $(PROG).elf - -bbvers.c: $(MKVERS) - @-$(RM) $@ - ./$(MKVERS) ${ECHO} $(PROG) $@ - -clean: - -$(RM) $(BOOT_SRT) $(BOOT_OBJS) - -$(RM) $(BOOT_L_OBJS) - -$(RM) bbvers.c a.out core - -clobber: clean - -$(RM) $(PROG) $(PROG).elf bootblk.version - -$(RM) $(MKVERS) $(MKBOOT) - -lint: $(BOOT_L_OBJS) - @echo "\n$@: global crosschecks:" - $(LINT.2) $(BOOT_L_OBJS) $(LDLIBS) - -FRC: diff --git a/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h b/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h deleted file mode 100644 index 7a0565e88c..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1994, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#ifndef _CBOOTBLK_H -#define _CBOOTBLK_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -extern int openfile(char *, char *); -extern int closefile(int); -extern int readfile(int, char *, int); -extern void seekfile(int, off_t); - -extern void exit(void); -extern void puts(char *); -extern int utox(char *p, u_int n); - -extern void fw_init(void *); - -extern char *getbootdevice(char *); - -extern int devbread(void *, void *, int, int); -extern void *devopen(char *); -extern int devclose(void *); -extern void get_rootfs_start(char *device); -extern u_int fdisk2rootfs(u_int offset); - -extern void bcopy(const void *, void *, size_t); -extern void bzero(void *, size_t); -extern int strcmp(const char *, const char *); -extern int strncmp(const char *, const char *, size_t); -extern size_t strlen(const char *); -extern char *strcpy(char *, const char *); - -extern void main(void *); -extern void exitto(void *, void *); - -extern char ident[]; -extern char fscompname[]; -extern unsigned long read_elf_file(int, char *); -void sync_instruction_memory(caddr_t, u_int); - -#ifdef __cplusplus -} -#endif - -#endif /* _CBOOTBLK_H */ diff --git a/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c b/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c deleted file mode 100644 index 5f2f058723..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1992-1994, 2002-2003 Sun Microsystems, Inc. - * All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/exechdr.h> -#include <sys/elf.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <strings.h> - -#define BBSIZE (15 * 512) - -static Elf32_Ehdr elfhdr; -static Elf32_Phdr phdr, dphdr; -static char buf[4096]; - -int -main(int argc, char **argv) -{ - struct exec exec; - int ifd, ofd; - int count; - int text_written = 0; - int data_written = 0; - - if (argc < 3) { - (void) printf("usage: %s elf_file a.outfile\n", argv[0]); - exit(1); - } - if ((ifd = open(argv[1], O_RDONLY)) == -1) { - perror("open input"); - exit(1); - } - if (read(ifd, &elfhdr, sizeof (elfhdr)) < sizeof (elfhdr)) { - perror("read elfhdr"); - exit(1); - } - if ((ofd = open(argv[2], O_RDWR | O_TRUNC | O_CREAT, 0777)) == -1) { - perror("open aout"); - exit(1); - } - - if (elfhdr.e_ident[EI_MAG0] != ELFMAG0 || - elfhdr.e_ident[EI_MAG1] != ELFMAG1 || - elfhdr.e_ident[EI_MAG2] != ELFMAG2 || - elfhdr.e_ident[EI_MAG3] != ELFMAG3) { - perror("elfmagic"); - exit(1); - } - if (lseek(ifd, elfhdr.e_phoff, 0) == -1) { - perror("lseek"); - exit(1); - } - if (read(ifd, &phdr, sizeof (phdr)) < sizeof (phdr)) { - perror("read phdr"); - exit(1); - } - if (read(ifd, &dphdr, sizeof (dphdr)) < sizeof (dphdr)) { - perror("read dphdr"); - exit(1); - } - - /* - * Create an a.out header that will fool the PROM - */ - bzero(&exec, sizeof (exec)); - exec.a_toolversion = 1; -#ifdef sparc - exec.a_machtype = M_SPARC; -#else -#error "unknown machine type!" -#endif - exec.a_magic = OMAGIC; - exec.a_text = dphdr.p_vaddr - phdr.p_vaddr; - exec.a_data = dphdr.p_filesz; - exec.a_bss = dphdr.p_memsz - dphdr.p_filesz; - exec.a_entry = elfhdr.e_entry; - -#define text exec.a_text -#define data exec.a_data -#define bss exec.a_bss - - if (write(ofd, &exec, sizeof (exec)) != sizeof (exec)) { - perror("write exec"); - exit(1); - } - - /* - * Text section - */ - (void) printf("%d", text); - if (lseek(ifd, phdr.p_offset, 0) == -1) { - perror("lseek text"); - exit(1); - } - while (text_written < text && - (count = read(ifd, buf, sizeof (buf))) > 0) { - if (count > exec.a_text - text_written) - count = (exec.a_text - text_written); - if (write(ofd, buf, count) < count) { - perror("write text file"); - exit(1); - } - text_written += count; - } - /* Include a.out header in the accounting */ - text_written += sizeof (exec); - - /* - * Data section - */ - if (lseek(ifd, dphdr.p_offset, 0) == -1) { - perror("lseek data"); - exit(1); - } - (void) printf(" + %d (%d/0x%x)", data, text+data, text+data); - while (data_written < data && - (count = read(ifd, buf, sizeof (buf))) > 0) { - if (count > data - data_written) - count = (data - data_written); - if (write(ofd, buf, count) < count) { - perror("write data file"); - exit(1); - } - data_written += count; - } - (void) printf(" + %d (%d/0x%x)\n", bss, text+data+bss, text+data+bss); - (void) close(ofd); - (void) close(ifd); - - if (text_written + data_written > BBSIZE) { - (void) printf("*** WARNING! ***\n" - "Do not install this bootblock!\n"); - (void) printf("bootblock image is %d bytes too big.\n", - (text_written + data_written) - BBSIZE); - exit(1); - } - - (void) printf("bootblock %d%% full - %d bytes to spare.\n", - (text_written + data_written) * 100 / BBSIZE, - BBSIZE - (text_written + data_written)); - return (0); -} diff --git a/usr/src/psm/stand/bootblks/obp-c/common/romp.h b/usr/src/psm/stand/bootblks/obp-c/common/romp.h deleted file mode 100644 index 999564996d..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/common/romp.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#ifndef _SYS_ROMP_H -#define _SYS_ROMP_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#include <sys/types.h> -#include <sys/param.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Autoconfig operations - */ - -struct config_ops { -#ifdef _KERNEL - pnode_t (*devr_next)(/* pnode_t nodeid */); - pnode_t (*devr_child)(/* pnode_t nodeid */); -#else /* _KERNEL */ - int (*devr_next)(/* pnode_t nodeid */); - int (*devr_child)(/* pnode_t nodeid */); -#endif /* _KERNEL */ - int (*devr_getproplen)(/* pnode_t nodeid, char *name */); - int (*devr_getprop)(/* pnode_t nodeid, char *name, caddr_t buf */); - int (*devr_setprop)(/* pnode_t nodeid, char *name, caddr_t value, - uint_t size */); - caddr_t (*devr_nextprop)(/* pnode_t nodeid, char *previous */); -}; - -struct romvec_obp { - uint_t op_magic; /* magic mushroom */ - uint_t op_romvec_version; /* Version number of "romvec" */ - uint_t op_plugin_version; /* Plugin Architecture version */ - uint_t op_mon_id; /* version # of monitor firmware */ - - struct memlist **v_physmemory; /* total physical memory list */ - struct memlist **v_virtmemory; /* taken virtual memory list */ - struct memlist **v_availmemory; /* available physical memory */ - struct config_ops *op_config_ops; /* dev_info configuration access */ - - /* - * storage device access facilities - */ - char **v_bootcmd; /* expanded with PROM defaults */ - uint_t (*v_open)(/* char *name */); - uint_t (*v_close)(/* ihandle_t fileid */); - - /* - * block-oriented device access - */ - uint_t (*v_read_blocks)(); - uint_t (*v_write_blocks)(); - - /* - * network device access - */ - uint_t (*v_xmit_packet)(); - uint_t (*v_poll_packet)(); - - /* - * byte-oriented device access - */ - uint_t (*v_read_bytes)(); - uint_t (*v_write_bytes)(); - - /* - * 'File' access - i.e., Tapes for byte devices. - * TFTP for network devices - */ - uint_t (*v_seek)(); - - /* - * single character I/O - */ - uchar_t *v_insource; /* Current source of input */ - uchar_t *v_outsink; /* Currrent output sink */ - uchar_t (*v_getchar)(); /* Get a character from input */ - void (*v_putchar)(); /* Put a character to output sink. */ - int (*v_mayget)(); /* Maybe get a character, or "-1". */ - int (*v_mayput)(); /* Maybe put a character, or "-1". */ - - /* - * Frame buffer - */ - void (*v_fwritestr)(); /* write a string to framebuffer */ - - /* - * Miscellaneous Goodies - */ - void (*op_boot)(/* char *bootspec */); /* reboot machine */ - int (*v_printf)(); /* handles fmt string plus 5 args */ - void (*op_enter)(); /* Entry for keyboard abort. */ - int *op_milliseconds; /* Counts in milliseconds. */ - void (*op_exit)(); /* Exit from user program. */ - - /* - * Note: Different semantics for V0 versus other op_vector_cmd: - */ - void (**op_vector_cmd)(); /* Handler for the vector */ - void (*op_interpret)(/* char *string, ... */); - /* interpret forth string */ - - /* boot parameters and 'old' style device access */ - struct bootparam **v_bootparam; - - uint_t (*v_mac_address)(/* int fd, caddr_t buf */); - /* Copyout ether address */ - - /* - * new V2 openprom stuff - */ - - char **op2_bootpath; /* Full path name of boot device */ - char **op2_bootargs; /* Boot command line after dev spec */ - -#ifdef _KERNEL - ihandle_t *op2_stdin; /* Console input device */ - ihandle_t *op2_stdout; /* Console output device */ - - phandle_t (*op2_phandle)(/* ihandle_t */); - /* Convert ihandle to phandle */ -#else /* _KERNEL */ - int *op2_stdin; /* Console input device */ - int *op2_stdout; /* Console output device */ - - int (*op2_phandle)(/* ihandle_t */); - /* Convert ihandle to phandle */ -#endif /* _KERNEL */ - - caddr_t (*op2_alloc)(/* caddr_t virthint, uint_t size */); - /* Allocate physical memory */ - - void (*op2_free)(/* caddr_t virthint, uint_t size */); - /* Deallocate physical memory */ - - caddr_t (*op2_map)(/* caddr_t virthint, uint_t space, uint_t phys, - uint_t size */); /* Create device mapping */ - - void (*op2_unmap)(/* caddr_t virt, uint_t size */); - /* Destroy device mapping */ - -#ifdef _KERNEL - ihandle_t (*op2_open)(/* char *name */); -#else /* _KERNEL */ - int (*op2_open)(/* char *name */); -#endif /* _KERNEL */ - uint_t (*op2_close)(/* int ihandle */); - - int (*op2_read)(/* int ihandle, caddr_t buf, uint_t len */); - int (*op2_write)(/* int ihandle, caddr_t buf, uint_t len */); - int (*op2_seek)(/* int ihandle, uint_t offsh, uint_t offsl */); - - void (*op2_chain)(/* caddr_t virt, uint_t size, caddr_t entry, - caddr_t argaddr, uint_t arglen */); - - void (*op2_release)(/* caddr_t virt, uint_t size */); - - /* - * End V2 stuff - */ - - caddr_t (*op3_alloc)(/* caddr_t virthint, uint_t size, int align */); - /* Allocate mem and align */ - - int *v_reserved[14]; - - /* - * Sun4c specific romvec routines (From sys/sun4c/machine/romvec.h) - * Common to all PROM versions. - */ - - void (*op_setcxsegmap)(/* int ctx, caddr_t v, int pmgno */); - /* Set segment in any context. */ - - /* - * V3 MP only functions: It's a fatal error to call these from a UP. - */ - - int (*op3_startcpu)(/* pnode_t moduleid, dev_reg_t contextable, - int whichcontext, caddr_t pc */); - - int (*op3_stopcpu)(/* pnode_t */); - - int (*op3_idlecpu)(/* pnode_t */); - int (*op3_resumecpu)(/* pnode_t */); -}; - -union sunromvec { - struct romvec_obp obp; -}; - -extern union sunromvec *romp; - -#ifdef __cplusplus -} -#endif - -#endif /* _SYS_ROMP_H */ diff --git a/usr/src/psm/stand/bootblks/obp-c/common/stub.c b/usr/src/psm/stand/bootblks/obp-c/common/stub.c deleted file mode 100644 index 13b204597b..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/common/stub.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1999, 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Stub for deprecated OBP V0 and V2 systems (sun4c). - */ - -#include <sys/param.h> -#include <sys/promif.h> -#include "romp.h" - -/* - * XXX Should be 'static'; 'extern' definition in header files prevent this - */ -union sunromvec *romp; - -#define OBP_V0_ROMVEC_VERSION 0 -#define OBP_ROMVEC_VERSION (romp->obp.op_romvec_version) -#define OBP_V0_PRINTF (*romp->obp.v_printf) -#define OBP_V2_WRITE (*romp->obp.op2_write) -#define OBP_V2_STDOUT (*romp->obp.op2_stdout) -#define OBP_EXIT_TO_MON (*romp->obp.op_exit) - -static void -fw_init(void *ptr) -{ - romp = ptr; -} - -void -exit() -{ - OBP_EXIT_TO_MON(); -} - -static void -putchar(char c) -{ - while (OBP_V2_WRITE(OBP_V2_STDOUT, &c, 1) != 1) - ; -} - -static void -puts(char *msg) -{ - char c; - - if (OBP_ROMVEC_VERSION == OBP_V0_ROMVEC_VERSION) - OBP_V0_PRINTF(msg); - else { - /* prepend carriage return to linefeed */ - while ((c = *msg++) != '\0') { - if (c == '\n') - putchar('\r'); - putchar(c); - } - } -} - -void -main(void *ptr) -{ - fw_init(ptr); - puts("This hardware platform is not supported by this " - "release of Solaris.\n"); -} - -void -bzero(void *p, size_t n) -{ - char zeero = 0; - char *cp = p; - - while (n != 0) - *cp++ = zeero, n--; /* Avoid clr for 68000, still... */ -} diff --git a/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c b/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c deleted file mode 100644 index b1399b9ccd..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c +++ /dev/null @@ -1,124 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1991-1994, Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * Emulate the firmware on Unix - * Only useful for testing the boot block code. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <sys/param.h> - -int -devbread(void *handle, void *buf, int blkno, int size) -{ - int fd = (int)handle; - - if (lseek(fd, (off_t) blkno * DEV_BSIZE, SEEK_SET) == -1) - perror("lseek"), exit(1); - return (read(fd, buf, size)); -} - -void * -devopen(char *devname) -{ - int fd; - - if ((fd = open(devname, O_RDONLY)) == -1) { - perror(devname); - return (NULL); - } - return ((void *)fd); -} - -int -devclose(void *handle) -{ - int fd = (int)handle; - - return (close(fd)); -} - -#define SZBUF 511 /* or 513? */ - -static void -usage(void) -{ - char mess[] = "Usage:\ta.out raw-device pathname\n"; - - write(2, mess, strlen(mess) + 1); - exit(1); -} - -static void -openfail(void) -{ - char mess[] = "openfile failed\n"; - - write(2, mess, strlen(mess) + 1); - exit(2); -} - -extern int openfile(char *, char *); -extern int readfile(int, char *, size_t); -extern int closefile(int); - -int -main(int argc, char *argv[]) -{ - char buf[SZBUF]; - int fd, count; - - if (argc != 3) - usage(); - if ((fd = openfile(argv[1], argv[2])) == -1) - openfail(); - while ((count = readfile(fd, buf, SZBUF)) != 0) - write(1, buf, count); - (void) closefile(fd); - return (0); -} - -/* - * Sigh. These shouldn't be needed. - */ -void -bcopy(void *from, void *to, size_t howmany) -{ - (void) memcpy(to, from, howmany); -} - -void -bzero(void *addr, size_t howmany) -{ - (void) memset(addr, 0, howmany); -} diff --git a/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s b/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s deleted file mode 100644 index e2d36ca37a..0000000000 --- a/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s +++ /dev/null @@ -1,74 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1986-1994, by Sun Microsystems, Inc. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* - * simple standalone startup code - */ - -#include <sys/asm_linkage.h> - -#if defined(lint) - -#include "cbootblk.h" - -/*ARGSUSED*/ -void -start(void *romp) -{} - -#else /* lint */ - - ENTRY(start) - .global end - .global edata - .global main - ! - ! OBP gives us control right here .. - ! - ! On entry, %o0 contains the romp. - ! - sethi %hi(start), %o1 ! Top of stack - or %o1, %lo(start), %o1 - save %o1, -SA(MINFRAME), %sp - ! - ! zero the bss - ! - sethi %hi(edata), %o0 ! Beginning of bss - or %o0, %lo(edata), %o0 - sethi %hi(end), %o2 ! End of the whole wad - or %o2, %lo(end), %o2 - call bzero - sub %o2, %o0, %o1 ! end - edata = size of bss - call main - mov %i0, %o0 ! romvec pointer - call exit - mov 0, %o0 - ret ! ret to prom - restore - SET_SIZE(start) - -#endif /* lint */ diff --git a/usr/src/psm/stand/bootblks/ufs/Makefile.ufs b/usr/src/psm/stand/bootblks/ufs/Makefile.ufs index 31c97a8635..116496a618 100644 --- a/usr/src/psm/stand/bootblks/ufs/Makefile.ufs +++ b/usr/src/psm/stand/bootblks/ufs/Makefile.ufs @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,14 +21,25 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994, by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # psm/stand/bootblks/ufs/Makefile.ufs # include $(BASEDIR)/Makefile.com -include $(BASEDIR)/ufs/common/Makefile.com + +# +# Define FS dependent targets +# + +UFS_DIR = $(BASEDIR)/ufs/common + +FS_FCODE = boot-ufs.fcode +FS_BB = ufs.bb + +UFSBOOT_FTH = $(UFS_DIR)/boot-ufs.fth +UFS_FTH = $(UFS_DIR)/ufs.fth # # This program is used to install the boot block @@ -51,8 +61,15 @@ USR_SBIN_INSTALLBOOT = $(USR_SBIN)/$(INSTALLBOOT) INS.file.555 = $(RM) $@; $(INS) -s -m 555 -f $(@D) $< $(CH)INS.file.555 = $(INS) -s -m 555 -u $(OWNER) -g $(GROUP) -f $(@D) $< +%.fcode: $(UFS_DIR)/%.fth + $(TOKENIZE) $< + +$(FS_FCODE): $(UTIL_FTH) $(UFS_FTH) $(BOOT_FTH) + $(TOKENIZE) $(UFSBOOT_FTH) + # # install rules # $(USR_SBIN)/%: % $(USR_SBIN) $(INS.file.555) + diff --git a/usr/src/psm/stand/bootblks/ufs/common/Makefile.com b/usr/src/psm/stand/bootblks/ufs/common/Makefile.com deleted file mode 100644 index b759d5cf8f..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/common/Makefile.com +++ /dev/null @@ -1,55 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. -# -# psm/stand/bootblks/ufs/common/Makefile.com -# - -THISDIR = $(BASEDIR)/ufs/common - -# -# Files that define the fs-reading capabilities of the C-based boot block -# -FS_C_SRCS = ufs.c - -# -# Allow ufs-specific files to find ufs-specific include files -# -$(FS_C_SRCS:%.c=%.o) := CPPINCS += -I$(THISDIR) - -# -# Pattern-matching rules for source in this directory -# -%.o: $(THISDIR)/%.c - $(COMPILE.c) -o $@ $< - -%.ln: $(THISDIR)/%.c - @($(LHEAD) $(LINT.c) $< $(LTAIL)) - -%.fcode: $(THISDIR)/%.fth - sed 's/sun4u/$(PLATFORM)/g' $< >$(<F) - $(TOKENIZE) $(<F) - @$(RM) -f $(<F) diff --git a/usr/src/psm/stand/bootblks/ufs/common/boot-ufs.fth b/usr/src/psm/stand/bootblks/ufs/common/boot-ufs.fth new file mode 100644 index 0000000000..7deb242e70 --- /dev/null +++ b/usr/src/psm/stand/bootblks/ufs/common/boot-ufs.fth @@ -0,0 +1,45 @@ + + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ + + +id: %Z%%M% %I% %E% SMI +purpose: UFS bootblock for sun4u platforms +copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved + +\ add headers +create doheaders + +: fs-pkg$ " ufs-file-system" ; +: fs-type$ " ufs" ; + +\ load common words +fload ../../../common/util.fth + +\ load fs reader +fload ../../common/ufs.fth + +\ load booter +fload ../../../common/boot.fth diff --git a/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth b/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth deleted file mode 100644 index 8d0fe85209..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth +++ /dev/null @@ -1,898 +0,0 @@ -\ ident "%Z%%M% %I% %E% SMI" -\ Copyright 2005 Sun Microsystems, Inc. All rights reserved. -\ Use is subject to license terms. -\ -\ CDDL HEADER START -\ -\ The contents of this file are subject to the terms of the -\ Common Development and Distribution License, Version 1.0 only -\ (the "License"). You may not use this file except in compliance -\ with the License. -\ -\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -\ or http://www.opensolaris.org/os/licensing. -\ See the License for the specific language governing permissions -\ and limitations under the License. -\ -\ When distributing Covered Code, include this CDDL HEADER in each -\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. -\ If applicable, add the following below this CDDL HEADER, with the -\ fields enclosed by brackets "[]" replaced with your own identifying -\ information: Portions Copyright [yyyy] [name of copyright owner] -\ -\ CDDL HEADER END -\ -\ - - -id: @(#)ufs.fth 1.4 95/08/04 -purpose: UFS file system support package -copyright: Copyright 1995 Sun Microsystems, Inc. All Rights Reserved - -headers -" /packages" find-package 0= if - ." Can't find /packages" abort -then push-package -new-device - diagnostic-mode? if ." Loading " then - " ufs-file-system" device-name - diagnostic-mode? if - ." package 1.4 04 Aug 1995 13:02:54. " cr - then - - 0 0 " support" property - - : cstrlen ( cstr -- len ) - dup begin - dup c@ - while - char+ - repeat swap - - ; - - : cscount ( cstr -- adr,len ) dup cstrlen ; - - \ Append str1 to the end of str2 - : $append ( adr,len1 adr,len2 -- ) - 2over 2over ca+ swap cmove ( adr,len1 adr,len2 ) - rot + ca+ 0 swap c! drop ( ) - ; - - : $= ( str1$ str2$ -- same? ) - rot tuck <> if - 3drop false exit - then comp 0= - ; - - " /openprom/client-services" find-package 0= if - ." Can't find client-services" abort - then constant cif-phandle - - instance defer cif-claim ( align size virt -- base ) - instance defer cif-release ( size virt -- ) - - : find-cif-method ( adr,len -- acf ) - cif-phandle find-method drop - ; - - " claim" find-cif-method to cif-claim - " release" find-cif-method to cif-release - - : ufs-alloc-mem ( size -- virt ) 1 swap 0 cif-claim ; - : ufs-free-mem ( virt size -- ) swap cif-release ; - - \ - \ UFS low-level block routines - \ - - d# 512 constant ublock - d# 512 constant /super-block - d# 8 constant ndaddr - d# 16 constant super-block# ( -- n ) - - 0 instance value temp-block - 0 instance value indirect-block - 0 instance value indirect1-block - 0 instance value inode - 0 instance value super-block - - - \ Deblocker needs following - - \ read-blocks ( adr #blocks block# -- #blocks-read ) - \ write-blocks ( adr #blocks block# -- #blocks-written ) - - : quad@ ( adr -- l ) - \ For little-endian machines - \ l@ - \ For big-endian machines - la1+ l@ - ; - - : +sb ( index -- value ) super-block swap la+ l@ ; - : iblkno ( -- n ) d# 04 +sb ; - : cgoffset ( -- n ) d# 06 +sb ; - : cgmask ( -- n ) d# 07 +sb ; - : bsize ( -- n ) d# 12 +sb ; - : fragshift ( -- n ) d# 24 +sb ; - : fsbtodbc ( -- n ) d# 25 +sb ; - : inopb ( -- n ) d# 30 +sb ; - : ipg ( -- n ) d# 46 +sb ; - : fpg ( -- n ) d# 47 +sb ; - - : /frag ( -- fragsize ) bsize fragshift rshift ; - - - : read-ublocks ( adr len dev-block# -- error? ) - ublock * 0 " seek" $call-parent ?dup if exit then - ( adr len ) tuck " read" $call-parent <> - ; - : get-super-block ( -- error? ) - super-block /super-block super-block# read-ublocks - ; - - : cgstart ( cg -- block# ) - dup cgmask invert and cgoffset * swap fpg * + - ; - : cgimin ( cg -- block# ) cgstart iblkno + ; - - : blkstofrags ( #blocks -- #frags ) fragshift lshift ; - - : fsbtodb ( fs-blk# -- dev-blk# ) fsbtodbc lshift ; - - : read-fs-blocks ( adr len fs-blk# -- error? ) fsbtodb read-ublocks ; - - \ - \ UFS inode routines - \ - - h# 80 constant /inode - - instance variable blkptr - instance variable blklim - instance variable indirptr - instance variable indir1ptr - 0 instance value lblk# - - : itoo ( i# -- offset ) inopb mod ; - : itog ( i# -- group ) ipg / ; - : itod ( i# -- block# ) - dup itog cgimin swap ipg mod inopb / blkstofrags + - ; - - : +i ( n -- ) inode + ; - - : ftype ( -- n ) 0 +i w@ h# f000 and ; - : dir? ( -- flag ) ftype h# 4000 = ; - : symlink? ( -- flag ) ftype h# a000 = ; - : regular? ( -- flag ) ftype h# 8000 = ; - - : file-size ( -- n ) 8 +i quad@ ; - : direct0 ( -- adr ) d# 40 +i ; - : indirect0 ( -- adr ) d# 88 +i ; - \ : indirect1 ( -- adr ) d# 92 +i ; - - \ **** Select the indicated file for subsequent accesses - : rewind ( -- ) - direct0 blkptr ! indirect0 blklim ! indirect0 indirptr ! - 0 to lblk# - ; - - 0 instance value current-file - : select-file ( i# -- error? ) - dup to current-file - dup temp-block bsize rot itod - read-fs-blocks ?dup if exit then - itoo /inode * temp-block + inode /inode move - rewind - false - ; - - : l@++ ( ptr -- value ) dup @ l@ /l rot +! ; - - \ **** Locate the next block within the current file - : next-block# ( -- [ n ] error? ) - blkptr @ blklim @ = if - indirptr @ indirect0 = if - indirect-block bsize indirptr l@++ ( adr,len ) - read-fs-blocks if true exit then - indirect-block blkptr ! indirect-block bsize + blklim ! - - indirect1-block bsize indirptr l@++ ( adr,len ) - read-fs-blocks if true exit then - indirect1-block indir1ptr ! - else - indirect-block bsize indir1ptr l@++ ( adr,len ) - read-fs-blocks if true exit then - indirect-block blkptr ! indirect-block bsize + blklim ! - then - then - lblk# 1+ to lblk# - blkptr l@++ ( blk# ) ?dup 0= - ; - - : block#>fs-block# ( lblk# -- [ n ] error? ) - dup lblk# < if rewind then ( target-blk# ) - begin dup lblk# <> while ( target-blk# ) - next-block# if ( target-blk# ) - drop true exit - else ( target-blk# blk# ) - drop ( target-blk# ) - then ( target-blk# ) - repeat drop next-block# ( [ n ] error? ) - ; - - : read-one-block ( adr block# -- error? ) - block#>fs-block# ?dup if drop exit then - bsize swap read-fs-blocks - ; - - : get-dirblk ( -- error? ) - temp-block bsize next-block# 0= if - read-fs-blocks - else - 2drop true - then - ; - - \ - \ UFS directory routines - \ - - instance variable diroff - instance variable totoff - - 0 instance value current-dir - - \ **** Select the directory file - : init-dir ( i# -- error? ) - dup to current-dir - select-file ?dup if exit then - get-dirblk ?dup if exit then - 0 diroff ! 0 totoff ! - false - ; - - : root-dir? ( -- flag ) current-dir 2 = ; - - \ **** Return the address of the current directory entry - : dirent ( -- adr ) temp-block diroff @ + ; - - \ **** Select the next directory entry - : next-dirent ( -- end? ) - dirent la1+ w@ dup diroff +! totoff +! - totoff @ file-size >= if true exit then - diroff @ bsize = if - get-dirblk ?dup if exit then - diroff off - then - false - ; - - \ **** From directory, get handle of the file or subdir that it references - \ For Unix, file handle is the inode # - : file-handle ( -- i# ) dirent l@ ; - - \ **** From directory, get name of file - : file-name ( -- adr len ) dirent la1+ wa1+ dup wa1+ swap w@ ; - - \ **** Select the root directory - : froot ( -- error? ) 2 init-dir ; - - \ - \ UFS high-level routines - \ - \ After this point, the code should be independent of the disk format! - - : lookup ( adr len -- i# false | true ) - begin - 2dup file-name $= if ( adr,len ) - 2drop file-handle ( i# ) - dup select-file ?dup if ( i# true ) - nip ( true ) - else ( i# ) - false ( i# false ) - then exit - then ( adr,len ) - next-dirent ( adr,len end? ) - until 2drop true ( true ) - ; - - - h# 200 instance buffer: fpath-buf - - : follow-symlink ( tail$ -- tail$" ) - temp-block 0 read-one-block if 2drop exit then ( tail-$ ) - temp-block cscount ( tail-$ head-$' ) - fpath-buf 0 $append ( $tail-$ ) - ?dup if ( $tail-$ ) - " /" fpath-buf cscount $append ( $tail-$ ) - fpath-buf cscount $append ( ) - else drop then ( ) - fpath-buf cscount ( tail-$' ) - over c@ ascii / = if ( path$ ) - froot if 2drop true exit then ( \path$ ) - ascii / left-parse-string 2drop ( path$ ) - else ( path$ ) - current-dir init-dir if 2drop true exit then ( tail-$ ) - then - ; - - : ($chdir ( adr len -- error? ) \ Fail if path is file, not dir - ?dup 0= if drop true exit then - over c@ ascii / = if ( path$ ) - froot if 2drop true exit then ( \path$ ) - ascii / left-parse-string 2drop ( path$ ) - else ( path$ ) - current-dir init-dir drop ( path$ ) - then ( path$ ) - begin ( path-$ ) - ascii / left-parse-string ( tail-$ head-$ ) - dup - while ( tail-$ head-$ ) - lookup if 2drop true exit then ( tail-$ i# ) - symlink? if ( tail-$ i# ) - drop follow-symlink ( tail-$' ) - else ( tail-$ i# ) - dir? 0= if 2drop drop true exit then ( tail-$ i# ) - init-dir if 2drop true exit then ( tail$ ) - then ( tail$ ) - repeat ( tail-$ head-$ ) - 2drop 2drop false - ; - - : $chdir ( dirpath$ -- error? ) - current-dir >r ($chdir if ( ) ( r: prev-dir ) - r> init-dir drop true ( error ) - else ( ) ( r: prev-dir ) - r> drop false ( ok ) - then ( error? ) - ; - - : .dirname ( inode# -- ) - begin ( inode# ) - file-handle over = if ( inode# ) - ." /" ( inode# ) - file-name type true ( inode# done ) - else ( inode# ) - false ( inode# done? ) - then ( inode# done? ) - next-dirent or ( inode# done? ) - until drop ( ) - ; - - \ - \ UFS installation routines - \ - - \ **** Allocate memory for necessary data structures - : allocate-ufs-buffers ( -- error? ) - /super-block ufs-alloc-mem to super-block - get-super-block ?dup if - ." failed to read super block" cr - super-block /super-block ufs-free-mem true exit - then - bsize ufs-alloc-mem to temp-block - bsize ufs-alloc-mem to indirect-block - bsize ufs-alloc-mem to indirect1-block - /inode ufs-alloc-mem to inode - false - ; - - : release ( -- ) - inode /inode ufs-free-mem - indirect-block bsize ufs-free-mem - indirect1-block bsize ufs-free-mem - temp-block bsize ufs-free-mem - super-block /super-block ufs-free-mem - ; - - false instance value file-open? - - \ UFS file interface - - 0 instance value deblocker - : init-deblocker ( -- okay? ) - " " " deblocker" $open-package to deblocker - deblocker if - true - else - ." Can't open deblocker package" cr false - then - ; - - \ Splits a string into two halves after the last occurrence of - \ a delimiter character. - \ adra,lena is the string after the delimiter - \ adrb,lenb is the string before and including the delimiter - \ lena = 0 if there was no delimiter - - \ adra,lena is the string after the delimiter - \ adrb,lenb is the string before and including the delimiter - \ lena = 0 if there was no delimiter - - : right-parse-string ( adr len char -- adra lena adrb lenb ) - >r 2dup + 0 ( adrb lenb adra 0 ) - - \ Throughout the loop, we maintain both substrings. - \ Each time through, we add a character to the "after" - \ string and remove it from the "before". - \ The loop terminates when either the "before" string - \ is empty or the desired character is found - - begin 2 pick while ( adrb lenb adra lena ) - over 1- c@ r@ = if \ Found it ( adrb lenb adra lena ) - r> drop 2swap exit ( adrb lenb adra lena ) - then - 2swap 1- 2swap swap 1- swap 1+ ( adrb lenb adra lena ) - repeat ( adrb lenb adr1 len1 ) - - dup if ( adrb lenb adr1 len1 ) - 2swap dup if 1- then ( adr1 len1 adrb lenb' ) - else ( adrb lenb adr1 len1 ) - 2swap ( adr1 len1 adrb lenb ) - then ( adra lena adrb lenb ) - - \ Character not found. lena is 0. - r> drop - ; - - h# 200 instance buffer: fpath1-buf - - : file-lookup ( fname$ -- i# false | true ) - begin lookup 0= while ( i# ) - dup select-file if drop true exit then ( i# ) - symlink? if ( i# ) - drop 0 0 follow-symlink ( path$/file$ ) - fpath1-buf 0 $append fpath1-buf cscount ( path$/file$ ) - ascii / right-parse-string ( file$ path$ ) - ?dup if ( file$ path$ ) - $chdir if 2drop true exit then else drop - then ( file$ ) - else false exit then ( file$ ) - current-dir init-dir if 2drop true exit then ( file$ ) - repeat true ( true ) - ; - - : ufs-open ( adr len -- success? ) - file-lookup if ( ) - false ( fail ) - else ( i# ) - select-file if ( ) - false ( fail ) - else ( ) - init-deblocker ( success? ) - then ( success? ) - then ( success? ) - ; - - : (cwd) ( -- ) tokenizer[ reveal ]tokenizer - root-dir? 0= if - current-dir " .." $chdir drop - (cwd) dup .dirname init-dir drop - then - ; - - h# 100 instance buffer: ufs-args - - : get-my-args ( -- adr,len ) - my-args ?dup if ( arg$ ) - ufs-args pack count bounds ?do - i c@ ascii | = if ascii / i c! then - i c@ ascii \ = if ascii / i c! then - loop - else - drop 0 ufs-args c! - then ufs-args count - ; - : ufs-args$ ( -- arg$ ) ufs-args count ; - - 0 instance value file-offset - - external - : block-size ( -- #bytes/block ) bsize ; - : max-transfer ( -- #bytes/block ) block-size 4 * ; - - : dma-alloc ( size -- virt ) " dma-alloc" $call-parent ; - : dma-free ( virt size -- ) " dma-free" $call-parent ; - - : read-blocks ( adr block# #blocks -- #read ) - 0 -rot bounds ?do ( adr block-count ) - over i read-one-block ?leave ( adr count ) - 1+ swap bsize ca+ swap ( adr' count+1 ) - loop nip - ; - - \ UFS Write is not supported - : write-blocks ( adr #blocks block# -- #blocks-written ) 3drop 0 ; - - : open ( -- okay? ) - allocate-ufs-buffers if false exit then - - \ Select the root directory - froot drop - - get-my-args " <NoFile>" $= if true exit then - - ufs-args$ ascii / right-parse-string ( file$ path$ ) - $chdir if 2drop release false exit then ( file$ ) - - \ Filename ends in "/"; select the directory and exit with success - dup 0= if 2drop true exit then ( file$ ) - - ufs-open ?dup if exit then ( failed? ) - - release false - ; - - : close ( -- ) - deblocker ?dup if close-package then - release - ; - - : read ( addr len -- actual-len ) - " read" deblocker $call-method dup if ( #bytes-read ) - dup file-offset + file-size > if ( #bytes-read ) - drop file-size file-offset - ( #bytes-left ) - then ( #bytes-read ) - then ( #bytes-read ) - dup file-offset + to file-offset ( actual-len ) - ; - - \ UFS Write is not supported - : write ( addr len -- actual-len ) 2drop 0 ; - - : size ( -- d ) file-size 0 ; - - - : seek ( offset.low offset.high -- failed? ) - - \ Return error if offset.hi != 0 - dup 0<> if 2drop true exit then ( offset.lo offset.hi ) - - \ Return error if offset.lo > file-size - over file-size > if 2drop true exit then ( offset.lo offset.hi ) - - \ Looks like a reasonable offset - over to file-offset ( offset.lo offset.hi ) - - \ Finally give the deblocker chance to adjust - " seek" deblocker $call-method ( offset.lo offset.hi failed? ) - ; - : load ( adr -- size ) file-size read ; - - headers - : restore-file ( i# -- ) - ?dup if - select-file 0= if regular? if file-offset 0 seek drop then then - then - ; - external - : dir ( -- ) - current-file - current-dir init-dir drop - begin file-name type cr next-dirent until - restore-file - ; - : cwd ( -- ) - current-file - root-dir? if ." /" else (cwd) then - restore-file - ; - - headers - -finish-device -pop-package - -id: @(#)boot.fth 1.6 95/08/04 -purpose: UFS File System Boot Block -copyright: Copyright 1995 Sun Microsystems, Inc. All Rights Reserved - -headers -" /packages/disk-label" find-package 0= if - ." Can't find /packages/disk-label" abort -then dup push-package ( phandle ) - -\ Find the previous "open" definition. -defer prev-open ( -- ok? ) -' false to prev-open -" open" rot find-method if to prev-open then - -external -: open ( -- okay? ) - \ Arg string is <part>[,<filespec>] - \ Split off partition, and handle filename - my-args ascii , left-parse-string ( file$ part$ ) - 2drop ?dup if ( file$ ) - " ufs-file-system" find-package if ( file$ phandle ) - interpose ( ) - else ( file$ ) - 2drop ( ) - then ( ) - else ( file ) - drop ( ) - then prev-open ( okay? ) -; -headers - -pop-package - -headers -" /chosen" find-package 0= if false then ( phandle ) -constant chosen-phandle - -" /openprom/client-services" find-package 0= if false then ( phandle ) -constant cif-phandle - -defer cif-claim ( align size virt -- base ) -defer cif-release ( size virt -- ) -defer cif-open ( cstr -- ihandle|0 ) -defer cif-close ( ihandle -- ) -defer cif-read ( len adr ihandle -- #read ) -defer cif-seek ( low high ihandle -- -1|0|1 ) -defer cif-peer ( phandle -- phandle ) -defer cif-getprop ( len adr cstr phandle -- ) - -: find-cif-method ( adr,len -- acf ) - cif-phandle find-method drop -; - -" claim" find-cif-method to cif-claim -" release" find-cif-method to cif-release -" open" find-cif-method to cif-open -" close" find-cif-method to cif-close -" read" find-cif-method to cif-read -" seek" find-cif-method to cif-seek -" peer" find-cif-method to cif-peer -" getprop" find-cif-method to cif-getprop - - -d# 256 constant /devname-buf -/devname-buf buffer: devname -: clear-devname-buf ( -- ) - devname /devname-buf 0 fill -; - -: devname$ ( -- adr,len ) devname cscount ; - -: chosen-property ( name$ -- value$ false -or- true ) - chosen-phandle get-package-property if true - else - decode-string 2swap 2drop false - then -; -: get-devname ( -- ) - clear-devname-buf - " bootpath" chosen-property if ( ) - ." Can't find bootpath" abort ( ) - then devname$ $append ( ) -; - -get-devname \ Initialize the device name buffer - -: bootargs ( -- adr,len ) - " bootargs" chosen-property if - ." Can't find bootargs" abort - then -; - -: printable? ( n -- flag ) \ true if n is a printable ascii character - dup bl th 7f within swap th 80 th ff between or -; -: white-space? ( n -- flag ) \ true is n is non-printable? or a blank - dup printable? 0= swap bl = or -; - -: -leading ( adr len -- adr' len' ) - begin dup while ( adr' len' ) - over c@ white-space? 0= if exit then - swap 1+ swap 1- - repeat -; - -: -trailing (s adr len -- adr len' ) - dup 0 ?do 2dup + 1- c@ white-space? 0= ?leave 1- loop -; -: strip-blanks ( adr,len -- adr,len' ) -trailing -leading ; - -: (option?) ( char -- rem$ true -or- false ) - >r bootargs begin strip-blanks ?dup while ( $r ) - bl left-parse-string r@ -rot ( $r char $l ) - strip-blanks ?dup if ( $r char $l ) - over dup c@ ascii - = if ( $r char $l adr ) - 1+ c@ ascii - = if ( $r char $l ) - 2drop r> 2drop 2drop false exit - then ( $r char $l ) - bounds 0 -rot ?do ( $r char flag ) - over i c@ = or ( $r char flag ) - loop nip if r> drop true exit then - else ( $r char $l adr ) - 2drop 2drop ( $r ) - then ( $r ) - else ( $r char adr ) - 2drop ( $r ) - then ( $r ) - repeat r> 2drop false ( false ) -; -: option? ( char -- flag ) - (option?) if 2drop true else false then -; - -\ : don't-boot? ( -- flag ) ascii L option? ; -: halt? ( -- flag ) ascii H option? ; - -: alternate-booter? ( -- fname true -or- false ) - ascii F (option?) if ( adr,len ) - strip-blanks ( adr,len' ) - bl left-parse-string 2swap 2drop ?dup if ( fname$ ) - true exit - then drop ( ) - then false ( false ) -; - -d# 256 constant /booter-name -/booter-name buffer: booter-name -: booter-name$ ( -- adr,len ) booter-name cscount ; -: clear-booter-name ( -- ) booter-name /booter-name 0 fill ; -: $cat-booter-name ( adr,len -- ) booter-name$ $append ; - -d# 256 constant /root-name -/root-name buffer: root-name -: root-name$ ( -- adr,len ) root-name cscount ; -: clear-root-name ( -- ) root-name /root-name 0 fill ; - -: root$ ( -- adr,len ) - clear-root-name ( ) - /root-name root-name ( len,adr ) - " name" drop ( len,adr cstr ) - 0 cif-peer ( len,adr cstr root ) - cif-getprop drop ( ) - " /" root-name$ $append ( ) - root-name$ ( rootname$ ) -; - -: plat-booter$ ( -- adr,len ) - clear-booter-name ( ) - alternate-booter? 0= if ( ) - " ufsboot" ( filename$ ) - then ( filename$ ) - over c@ ascii / <> if ( filename$ ) - " /platform/" $cat-booter-name ( filename$ ) - root$ $cat-booter-name ( filename$ ) - then $cat-booter-name booter-name$ ( booter$ ) -; - -: def-dirname$ ( -- dir$ ) " /platform/sun4u/" ; - -: def-booter$ ( -- adr,len ) - clear-booter-name ( ) - alternate-booter? 0= if ( ) - " ufsboot" ( filename$ ) - then ( filename$ ) - over c@ ascii / <> if ( filename$ ) - def-dirname$ $cat-booter-name ( filename$ ) - then $cat-booter-name booter-name$ ( booter$ ) -; - -d# 256 constant /filename-buf -/filename-buf buffer: filename-buf -: filename-buf$ ( -- adr,len ) filename-buf cscount ; -: clear-filename-buf ( -- ) filename-buf /filename-buf 0 fill ; -: $cat-filename ( adr,len -- ) filename-buf$ $append ; - -h# 10.0000 constant 1meg - -: ufs-fopen ( adr,len -- ihandle|0 ) drop cif-open ; -: ufs-fread ( buf,len ihandle -- #read ) >r swap r> cif-read ; -: ufs-fclose ( ihandle -- ) cif-close ; - -: fname>devname$ ( fname$ -- dev$ ) - clear-filename-buf ( fname$ ) - devname$ tuck $cat-filename ( fname$ len ) - " ," $cat-filename ( fname$ len ) - >r $cat-filename r> ( len ) - filename-buf$ rot ?do ( bufadr ) - dup i ca+ c@ ascii / = if ( bufadr ) - ascii | over i ca+ c! ( bufadr ) - then ( bufadr ) - loop drop filename-buf$ ( dev$ ) -; - -: set-file-size ( ihandle -- ) - " size" rot $call-method ( size.lo size.hi ) - drop " to file-size" evaluate -; - -h# 6000 constant loader-base - -: get-file ( adr fname$ -- fail? ) - fname>devname$ ufs-fopen ?dup if ( adr ihandle ) - dup set-file-size ( adr ihandle ) - over to loader-base ( adr ihandle ) - >r begin ( adr ) - dup 1meg r@ ufs-fread ( adr #read ) - ?dup while ( adr #read ) - ca+ ( adr" ) - repeat drop r> ufs-fclose false ( ok ) - else ( adr ) - drop true ( failed ) - then ( failed? ) -; - -: get-redirect-info ( -- partition true -or- false ) - loader-base " /.SUNW-boot-redirect" get-file if ( ) - false ( false ) - else ( adr ) - loader-base c@ ( part ) - dup ascii 0 ascii 9 between if ( part ) - diagnostic-mode? if ( part ) - ." Redirected to slice: " dup emit cr - then ( part ) - ascii 0 - ascii a + true ( part' true ) - else ( part ) - drop false ( false ) - then ( part true | false ) - then ( part true | false ) -; - -: update-devname ( part -- ) - clear-devname-buf ( part ) - get-devname devname$ ( part adr,len ) - - ca+ 1- dup 1- c@ ascii : = if ( part adr:x ) - c! ( ) - else ( part adr:x ) - 2drop ( ) - then ( ) -; - -: real-devname ( -- ) - get-redirect-info if ( part ) - update-devname ( ) - then ( ) -; - -: allocate-memory ( size -- virtual ) 1 swap 0 cif-claim ; -: free-memory ( virt size -- ) swap cif-release ; - -: sign-on ( -- ) - diagnostic-mode? if - ." FCode UFS Reader %I% %E% %U%. " cr - then -; - -: check-elf ( vadr -- flag ) l@ h# 7f454c46 ( \x7fELF ) = ; - -: force? ( -- flag ) ascii X option? ; - -: execit ( -- ) - \ we rely on the prom to do the right thing with the executable, since - \ it understands ELF32 and ELF64 - loader-base dup check-elf force? or if - " to load-base init-program" evaluate - else - drop ." Not a valid ELF file" cr exit - then -; - -: do-boot ( -- ) - sign-on real-devname -\ don't-boot? if exit then - halt? if - ." Halted with -H flag. " cr - exit - then - loader-base plat-booter$ ( adr,len ) - diagnostic-mode? if ." Loading: " 2dup type cr then - get-file if - loader-base def-booter$ - diagnostic-mode? if ." Loading: " 2dup type cr then - get-file if - ." Boot load failed." cr exit - then - then - execit -; - -do-boot diff --git a/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth b/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth deleted file mode 100644 index 9714b61f56..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth +++ /dev/null @@ -1,463 +0,0 @@ -\ -\ CDDL HEADER START -\ -\ The contents of this file are subject to the terms of the -\ Common Development and Distribution License, Version 1.0 only -\ (the "License"). You may not use this file except in compliance -\ with the License. -\ -\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -\ or http://www.opensolaris.org/os/licensing. -\ See the License for the specific language governing permissions -\ and limitations under the License. -\ -\ When distributing Covered Code, include this CDDL HEADER in each -\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. -\ If applicable, add the following below this CDDL HEADER, with the -\ fields enclosed by brackets "[]" replaced with your own identifying -\ information: Portions Copyright [yyyy] [name of copyright owner] -\ -\ CDDL HEADER END -\ -\ Copyright 2000 Sun Microsystems, Inc. All rights reserved. -\ Use is subject to license terms. -\ -\ ident "%Z%%M% %I% %E% SMI" -\ -\ Unix 4.2 file system reader -\ - -\ When debugging, the sign on banner is on the stack -\ #ifdef DEBUG_BOOTBLK -\ type -\ #endif /* DEBUG_BOOTBLK */ - -decimal -headerless - -\ -\ Forth utility routines -\ -\ : $find 2dup type cr $find ; - -: boot-eval ( adr len -- ) - $find if - execute - else - type ." ?" cr exit - then -; - -\ " romvec" boot-eval constant romvec -variable boot-romvec - -: find-romvec - " romvec" $find if - execute - else - 2drop h# ffe8.0010 - then - boot-romvec ! -; - -find-romvec - -: roment ( offset -- adr ) boot-romvec @ + l@ ; - -" load-base" $find drop constant 'loadbase -\ " (is" $find drop constant '(is -\ " $=" $find drop constant '$= -" call" $find drop constant 'call - -: loadbase ( -- adr ) 'loadbase execute ; -\ : (is ( val acf -- ) '(is execute ; -\ : $= ( str1 str2 -- [ -1 | 0 | 1 ] ) '$= execute ; -: call ( ... addr -- ??? ) 'call execute ; -: loadbase! ( value -- ) 'loadbase " (is" boot-eval ; - -: devr_next ( nodeid -- next-nodeid ) h# 1c roment l@ call nip ; -: devr_getprop ( adr namecstr nodeid -- len|-1 ) h# 1c roment 3 la+ l@ call nip nip nip ; - -: boot-/string ( adr len size -- adr+size len-size ) tuck - >r + r> ; - -\ Splits a string around a delimiter. If the delimiter is found, -\ two strings are returned under true, otherwise one string under false. -: boot-$split ( adr len char -- remaining-adr len [ initial-adr len ] found? ) - 2 pick 2 pick bounds ?do - dup i c@ = if i nip -1 then - loop ( adr len adr' -1 | char ) - -1 = if ( adr len adr' ) - swap >r ( adr adr' ) ( r: len ) - 2dup swap - swap ( adr [adr'-adr] adr' ) ( r: len ) - 1+ r> ( adr [adr'-adr] adr'+1 len ) - 2 pick - 1- ( adr [adr'-adr] adr'+1 len-[adr'-adr-1] ) - 2swap true ( rem-adr,len initial-adr,len true ) - else - false - then -; - -\ -\ Device and driver section -\ - -512 constant ublock - -variable devid -variable nextblock \ holds seek target for V1 read-blocks - -: devname ( -- cstr ) - h# 88 roment @ \ bootpath -; - -\ Debug V2 or later PROMs -\ : devname " disk" drop ; - - -\ Debug V0 PROMS -\ : devname " sd(0,0,0)" drop ; - -: open-disk ( -- error? ) - devname - " op-open" - boot-eval dup if - dup devid ! - then - 0= ( invert sense of error flag ) -; - -: close-disk ( -- ) - devid @ " op-close" boot-eval drop -; - -: read-blks ( adr len -- error? ) - ( len adr devid -- #bytes_read ) - tuck swap devid @ " op-read" boot-eval <> -; - -: seek ( low high -- error? ) - ( low high devid -- ? ) - devid @ " op-seek" boot-eval 0< -; - -\ -\ UFS low-level block routines -\ - -512 constant /super-block -8 constant ndaddr -16 constant super-block# ( -- n ) - -0 constant temp-block -0 constant indirect-block -0 constant inode -0 constant super-block - -: quad@ ( adr -- l ) -\ For little-endian machines -\ l@ -\ For big-endian machines - la1+ l@ -; - -: +sb ( index -- value ) super-block swap la+ l@ ; -: iblkno ( -- n ) 4 +sb ; -: cgoffset ( -- n ) 6 +sb ; -: cgmask ( -- n ) 7 +sb ; -: bsize ( -- n ) 12 +sb ; -: fragshift ( -- n ) 24 +sb ; -: fsbtodbc ( -- n ) 25 +sb ; -: inopb ( -- n ) 30 +sb ; -: ipg ( -- n ) 46 +sb ; -: fpg ( -- n ) 47 +sb ; - -: read-ublocks ( adr len dev-block# -- error? ) - ublock * 0 seek ?dup if exit then - ( adr len ) read-blks -; - -: get-super-block ( -- error? ) - super-block /super-block super-block# read-ublocks -; - -: cgstart ( cg -- block# ) - dup cgmask not and cgoffset * swap fpg * + -; -: cgimin ( cg -- block# ) cgstart iblkno + ; - -: blkstofrags ( #blocks -- #frags ) fragshift << ; - -: fsbtodb ( fs-blk# -- dev-blk# ) fsbtodbc << ; - -: read-fs-blocks ( adr len fs-blk# -- error? ) fsbtodb read-ublocks ; - -\ -\ UFS inode routines -\ - -h# 80 constant /inode - -variable blkptr -variable blklim -variable indirptr - -: itoo ( n -- offset ) inopb mod ; -: itog ( n -- group ) ipg / ; -: itod ( n -- block# ) - dup itog cgimin swap ipg mod inopb / blkstofrags + -; - -: +i ( n -- ) inode + ; -: dir? ( -- flag ) 0 +i w@ h# 4000 and 0<> ; \ **** -: filesize ( -- n ) 8 +i quad@ ; \ **** -: direct0 ( -- adr ) 40 +i ; -: indirect0 ( -- adr ) 88 +i ; - -\ **** Select the indicated file for subsequent accesses -: select-file ( file-handle -- error? ) - dup temp-block bsize rot itod - read-fs-blocks ?dup if exit then - itoo /inode * temp-block + inode /inode move - direct0 blkptr ! indirect0 blklim ! indirect0 indirptr ! - false -; - -: l@++ ( ptr -- value ) dup @ l@ /l rot +! ; - -\ **** Locate the next block within the current file -: next-block# ( -- n ) - blkptr @ blklim @ = if - indirect-block bsize indirptr l@++ - read-fs-blocks drop ( XXX - what about the error? ) - indirect-block blkptr ! indirect-block bsize + blklim ! - then - blkptr l@++ ( blk# ) -; -: get-dirblk ( -- error? ) temp-block bsize next-block# read-fs-blocks ; - -\ -\ UFS directory routines -\ - -variable diroff -variable totoff -variable current-dir - -\ **** Select the directory file -: init-dir ( file-handle -- error? ) - dup current-dir ! - select-file ?dup if exit then - get-dirblk ?dup if exit then - 0 diroff ! 0 totoff ! - false -; - -\ **** Return the address of the current directory entry -: dirent ( -- adr ) temp-block diroff @ + ; - -\ **** Select the next directory entry -: next-dirent ( -- end? ) - dirent la1+ w@ dup diroff +! totoff +! - totoff @ filesize >= if true exit then - diroff @ bsize = if - get-dirblk ?dup if exit then - diroff off - then - false -; - -\ **** From directory, get handle of the file or subdir that it references -\ For Unix, file handle is the inode # -: file-handle ( -- file-handle ) dirent l@ ; - -\ **** From directory, get name of file -: file-name ( -- adr len ) dirent la1+ wa1+ dup wa1+ swap w@ ; - -\ **** Select the root directory -: froot ( -- error? ) 2 init-dir ; - -\ -\ UFS high-level routines -\ -\ After this point, the code should be independent of the disk format! - -: dir ( -- ) begin file-name type cr next-dirent until ; - -: lookup ( adr len -- not-found? ) - begin - 2dup file-name " $=" boot-eval if 2drop false exit then - next-dirent - until - 2drop true -; -: path-lookup ( adr len -- not-found? ) - dup 0= if 2drop true exit then - over c@ ascii / = if 1 boot-/string then - froot if 2drop true exit then - begin - ascii / boot-$split ( rem-adr len [ adr len ] delim-found? ) - while - lookup if 2drop true exit then - dir? 0= if 2drop true exit then - file-handle init-dir if 2drop true exit then - repeat ( rem-adr len ) - - \ Now we have found the directory containing the file - lookup ?dup if exit then - file-handle select-file -; - -\ -\ File reading, loading, etc. -\ ELF-specific routines go here. -\ - -: read-file ( adr -- error? ) - filesize begin ( adr remaining ) - dup 0> - while - over bsize next-block# - read-fs-blocks ?dup if exit then - ( adr remaining ) bsize boot-/string - repeat - 2drop false -; - -\ -\ ELF support -\ - -0 constant elfhdr -0 constant phdr - -: +w_elfhdr ( index -- value ) elfhdr swap ca+ w@ ; -: +l_elfhdr ( index -- value ) elfhdr swap ca+ l@ ; -: e_entry ( -- n ) 24 +l_elfhdr ; -: e_phoff ( -- n ) 28 +l_elfhdr ; -: e_phentsize ( -- n ) 42 +w_elfhdr ; -: e_phnum ( -- n ) 44 +w_elfhdr ; - -1 constant pt_load -: +phdr ( index -- value ) phdr swap la+ l@ ; -: p_type ( -- n ) 0 +phdr ; -: p_offset ( -- n ) 1 +phdr ; -: p_vaddr ( -- n ) 2 +phdr ; -: p_filesz ( -- n ) 4 +phdr ; -: p_memsz ( -- n ) 5 +phdr ; -: p_flags ( -- n ) 6 +phdr ; -: p_align ( -- n ) 7 +phdr ; - -: check-elf ( filebase -- is-elf? ) - l@ h# 7f454c46 ( \x7fELF ) = -; - -: get-phdr ( filebase index -- ) - e_phentsize * e_phoff + + - phdr e_phentsize move -; - -: load-elf ( filebase -- entry-point ) - dup is elfhdr - e_phentsize alloc-mem is phdr - e_phnum 0 ?do - dup i get-phdr - p_type pt_load = if - ( read it ) - dup p_offset + p_vaddr p_filesz move - p_memsz p_filesz > if - ( zero the bss ) - p_vaddr p_filesz + p_memsz p_filesz - 0 fill - then - then - loop drop - phdr e_phentsize free-mem - e_entry -; - -\ -\ UFS installation routines -\ - -\ **** Allocate memory for necessary data structures -: allocate-ufs-buffers ( -- error? ) - /super-block alloc-mem is super-block - get-super-block ?dup if - ." failed to read super block" cr - super-block /super-block free-mem close-disk exit - then - bsize alloc-mem is temp-block - bsize alloc-mem is indirect-block - /inode alloc-mem is inode - false -; - -: release ( -- ) - inode /inode free-mem - indirect-block bsize free-mem - temp-block bsize free-mem - super-block /super-block free-mem - close-disk -; - -: initialize ( -- error? ) - open-disk ?dup if exit then - allocate-ufs-buffers -; - -hex -headers -( external ) - -: get-file ( load-adr name-adr name-len -- error? ) - initialize ?dup if nip nip nip exit then ( ) - path-lookup ?dup if nip release exit then ( ) - dir? ?dup if ( load-adr error? ) - nip ." File is a directory." cr release exit - then ( load-adr ) - read-file ?dup if ." File read failed." cr exit then ( ) - \ Set FORTH file-size variable - filesize " file-size" boot-eval ! - release false ( ok ) -; - -: reloc&go ( -- ) - loadbase - \ Is it ELF? - dup check-elf if ( base-adr ) - load-elf ( entry-point ) - loadbase! - " init-program" boot-eval - else ( base-adr ) -\ Let FORTH handle anything else - " adjust-header" boot-eval if " init-program" boot-eval then ( entry-point ) - loadbase! - then - 4000 loadbase! - " ?go" boot-eval -; - -d# 128 buffer: boot-name - -: get-boot-name ( -- adr,len ) - boot-name d# 128 erase - " /platform/" boot-name swap dup >r cmove r> ( len0 ) - boot-name over + " name" drop ( len0 bufadr namestr ) - 0 devr_next devr_getprop ( len0 len ) - 1- + boot-name over + ( len1 adr ) - " /ufsboot" ( len1 adr adr,len ) - >r swap r@ cmove r> ( len1 len ) - + boot-name swap -; - -\ -\ The boot stuff itself -\ -: do-boot - 4000 loadbase! - loadbase get-boot-name get-file if - ." Boot load failed." cr exit - then - reloc&go -; - -do-boot diff --git a/usr/src/psm/stand/bootblks/ufs/common/iob.h b/usr/src/psm/stand/bootblks/ufs/common/iob.h deleted file mode 100644 index 7797839b4a..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/common/iob.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright (c) 1990-1994, by Sun Microsystems, Inc. - * All rights reserved. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" /* from SunOS 4.1 */ - -/* - * This stuff keeps track of an open file in the standalone I/O system. - * - * The definitions herein are *private* to ufs.c - * - * It includes an IOB for device addess, an inode, a buffer for reading - * indirect blocks and inodes, and a buffer for the superblock of the - * file system (if any). - * - * To make the boot block smaller, we're using a 'bnode' (for boot node) - * struct instead of an inode struct. This contains just the common - * data from the on-disk inode. - */ - -struct saioreq { - off_t si_offset; - char *si_ma; /* memory address to r/w */ - int si_cc; /* character count to r/w */ -}; - -struct bnode -{ - dev_t i_dev; /* from inode struct */ - struct icommon i_ic; /* disk inode struct */ -}; - - -struct iob { - void *i_si; /* I/O handle for this file */ - struct { - off_t si_offset; - char *si_ma; /* memory address to r/w */ - int si_cc; /* character count to r/w */ - } i_saio; /* I/O request block */ - struct bnode i_ino; /* Inode for this file */ - char i_buf[MAXBSIZE]; /* Buffer for reading inodes & dirs */ - union { - struct fs ui_fs; /* Superblock for file system */ - char dummy[SBSIZE]; - } i_un; -}; - -/* - * XXX: i_fs conflicts with a definition in ufs_inode.h... - */ -#define iob_fs i_un.ui_fs diff --git a/usr/src/psm/stand/bootblks/ufs/common/ufs.c b/usr/src/psm/stand/bootblks/ufs/common/ufs.c deleted file mode 100644 index 0d1f0f0540..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/common/ufs.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 1991-1994, 2002 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -#pragma ident "%Z%%M% %I% %E% SMI" - -/* from "@(#)boot/ufssys.c 1.1 90/03/28 SMI" */ - -/* - * Basic file system reading code for standalone I/O system. - */ - -#include <sys/param.h> -#include <sys/vnode.h> -#include <sys/fs/ufs_fsdir.h> -#include <sys/fs/ufs_fs.h> -#include <sys/fs/ufs_inode.h> - -#include "iob.h" -#include "cbootblk.h" - -/* - * private definitions of ufs macros from sys/fs/ufs_fs.h - * due to boot block size problems, these macros are coded - * to use the older narrow file offset type (31 bit). This - * saves a lot of code space. Since we will never encounter - * a large file here, it is safe to cast offset_t to off_t. - */ - -#define bb_fragroundup(fs, size) /* roundup(size, fs->fs_fsize) */ \ - ((off_t)((size) + (fs)->fs_fsize - 1) & (off_t)(fs)->fs_fmask) - -#define bb_blksize(fs, ip, lbn) \ - (((lbn) >= NDADDR || \ - (off_t)(ip)->i_size >= (off_t)((lbn) + 1) << (fs)->fs_bshift) \ - ? (fs)->fs_bsize \ - : (bb_fragroundup(fs, blkoff(fs, (off_t)(ip)->i_size)))) - -#define NULL 0 - -static struct direct *readdir(struct iob *, int *); -static ino_t dlook(char *, struct iob *); -static int getblock(struct iob *io); - -char fscompname[] = "ufsboot"; - -static struct iob iob[1]; /* only one open file! */ - -static int -openi(ino_t n, struct iob *io) -{ - struct dinode *dp; - struct fs *fs = &io->iob_fs; - - io->i_saio.si_offset = 0; - if (devbread(io->i_si, io->i_buf, - fsbtodb(fs, itod(fs, n)), fs->fs_bsize) != fs->fs_bsize) - return (0); - dp = (struct dinode *)io->i_buf; - io->i_ino.i_ic = dp[itoo(fs, n)].di_ic; - return (1); -} - -static ino_t -find(char *nm, struct iob *file) -{ - char *q; - char c; - ino_t n; - char pathbuf[MAXPATHLEN], *path; - char *link; - size_t linklen; - int fmt = IFDIR; - - if (nm == NULL || *nm == '\0') - return (0); - bcopy(nm, pathbuf, strlen(nm) + 1); -root: - path = pathbuf; - if (openi((ino_t)UFSROOTINO, file) == 0) - return (0); - while (*path) { - while (*path == '/') - path++; - q = path; - while (*q != '/' && *q != '\0') - q++; - c = *q; - *q = '\0'; - - if ((n = dlook(path, file)) != 0) { - - *q = c; - if (openi(n, file) == 0) - return (0); - switch (fmt = (file->i_ino.i_smode & IFMT)) { - case IFREG: - case IFDIR: - break; - - case IFLNK: - if (getblock(file) != 0) - return (0); - link = (char *)file->i_saio.si_ma; - linklen = strlen(link); - if (*link == '/') - path = pathbuf; - /* - * Copy unprocessed pathname up & prepend link - * (Yes, this bcopy handles overlapping args) - */ - bcopy(q, path + linklen, strlen(q) + 1); - bcopy(link, path, linklen); - path = pathbuf; - goto root; - /*NOTREACHED*/ - - default: - return (0); - } - if (c == '\0') - break; - path = q; - continue; - } else - return (0); - } - - return (fmt == IFREG ? n : 0); -} - -static daddr_t -sbmap(struct iob *io, daddr_t bn) -{ - struct bnode *ip; - int i, j, sh; - daddr_t nb, *bap; - - /* These are the pools of buffers, iob's, etc. */ - - static union { - char b[NIADDR+1][MAXBSIZE]; - daddr_t *dummy; /* force alignment */ - } b; - static daddr_t blknos[NIADDR+1]; - - ip = &io->i_ino; - - /* - * blocks 0..NDADDR are direct blocks - */ - if (bn < NDADDR) - return (ip->i_db[bn]); - - /* - * addresses NIADDR have single and double indirect blocks. - * the first step is to determine how many levels of indirection. - */ - sh = 1; - bn -= NDADDR; - for (j = NIADDR; j > 0; j--) { - sh *= NINDIR(&io->iob_fs); - if (bn < sh) - break; - bn -= sh; - } - if (j == 0) - return ((daddr_t)0); - - /* - * fetch the first indirect block address from the inode - */ - nb = ip->i_ib[NIADDR - j]; - if (nb == 0) - return ((daddr_t)0); - - /* - * fetch through the indirect blocks - */ - for (; j <= NIADDR; j++) { - if (blknos[j] != nb) { - if (devbread(io->i_si, b.b[j], - fsbtodb(&io->iob_fs, nb), - io->iob_fs.fs_bsize) != io->iob_fs.fs_bsize) - return ((daddr_t)0); - blknos[j] = nb; - } - bap = (daddr_t *)b.b[j]; - sh /= NINDIR(&io->iob_fs); - i = (bn / sh) % NINDIR(&io->iob_fs); - nb = bap[i]; - if (nb == 0) - return ((daddr_t)0); - } - return (nb); -} - -static ino_t -dlook(char *s, struct iob *io) -{ - struct direct *dp; - struct bnode *ip; - int len, loc = 0; - - ip = &io->i_ino; - if (s == NULL || *s == '\0') - return (0); - if ((ip->i_smode & IFMT) != IFDIR || ip->i_size == 0) - return (0); - len = strlen(s); - for (dp = readdir(io, &loc); dp != NULL; dp = readdir(io, &loc)) { - if (dp->d_ino == 0) - continue; - if (dp->d_namlen == len && strcmp(s, dp->d_name) == 0) - return (dp->d_ino); - } - return (0); -} - -/* - * get next entry in a directory. - */ -static struct direct * -readdir(struct iob *io, int *loc_p) -{ - struct direct *dp; - daddr_t lbn, d; - int off; - int loc = *loc_p; - int bsize; - - for (;;) { - if (loc >= io->i_ino.i_size) - return (NULL); - off = blkoff(&io->iob_fs, loc); - if (off == 0) { - lbn = lblkno(&io->iob_fs, loc); - if ((d = sbmap(io, lbn)) == 0) - return (NULL); - bsize = bb_blksize(&io->iob_fs, &io->i_ino, lbn); - if (devbread(io->i_si, io->i_buf, - fsbtodb(&io->iob_fs, d), bsize) != bsize) - return (NULL); - } - dp = (struct direct *)(io->i_buf + off); - *loc_p = (loc += dp->d_reclen); - if (dp->d_ino == 0) - continue; - return (dp); - } -} - -static int -getblock(struct iob *io) -{ - struct fs *fs; - int off, size, diff; - daddr_t lbn; - - diff = io->i_ino.i_size - io->i_saio.si_offset; - if (diff <= 0) - return (-1); - fs = &io->iob_fs; - lbn = lblkno(fs, io->i_saio.si_offset); - off = blkoff(fs, io->i_saio.si_offset); - size = bb_blksize(fs, &io->i_ino, lbn); - io->i_saio.si_cc = size; - if (devbread(io->i_si, io->i_buf, - fsbtodb(fs, sbmap(io, lbn)), size) != size) - return (-1); - if (io->i_saio.si_offset - off + size >= io->i_ino.i_size) - io->i_saio.si_cc = diff + off; - io->i_saio.si_cc -= off; - - io->i_saio.si_ma = &io->i_buf[off]; - return (0); -} - -int -readfile(int fd, char *buf, int count) -{ - struct iob *io = &iob[fd]; - int i, j; - - if (io->i_saio.si_offset + count > io->i_ino.i_size) - count = io->i_ino.i_size - io->i_saio.si_offset; - if ((i = count) <= 0) - return (0); - while (i > 0) { - if (io->i_saio.si_cc <= 0) { - if (getblock(io) == -1) - return (0); - } - j = (i < io->i_saio.si_cc) ? i : io->i_saio.si_cc; - bcopy(io->i_saio.si_ma, buf, (size_t)j); - buf += j; - io->i_saio.si_ma += j; - io->i_saio.si_offset += j; - io->i_saio.si_cc -= j; - i -= j; - } - return (count); -} - -/* - * Open a file. - */ -int -openfile(char *device, char *pathname) -{ - struct iob *io = &iob[0]; /* only one open file! */ - - io->i_ino.i_dev = 0; - if ((io->i_si = devopen(device)) == NULL) - return (-1); /* if devopen fails, open fails */ - - /* Pseudo-mount a file system; read the superblock. */ - - if (devbread(io->i_si, &io->iob_fs, SBLOCK, SBSIZE) != SBSIZE) - goto failed; - if (io->iob_fs.fs_magic != FS_MAGIC) { - puts("bootblk: not a UFS file system.\n"); - goto failed; - } - if (find(pathname, io) == 0) - goto failed; - io->i_saio.si_offset = io->i_saio.si_cc = 0; - - return (0); /* only one open file! */ -failed: - (void) devclose(io->i_si); - return (-1); -} - -int -closefile(int fd) -{ - struct iob *io = &iob[fd]; - - return (devclose(io->i_si)); -} - -/* - * This version of seek() only performs absolute seeks (whence == 0). - */ -void -seekfile(int fd, off_t addr) -{ - struct iob *io = &iob[fd]; - - io->i_saio.si_offset = addr; - io->i_saio.si_cc = 0; -} diff --git a/usr/src/psm/stand/bootblks/ufs/common/ufs.fth b/usr/src/psm/stand/bootblks/ufs/common/ufs.fth new file mode 100644 index 0000000000..25531ecd78 --- /dev/null +++ b/usr/src/psm/stand/bootblks/ufs/common/ufs.fth @@ -0,0 +1,584 @@ + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ + + +id: %Z%%M% %I% %E% SMI +purpose: UFS file system support package +copyright: Copyright 1995 Sun Microsystems, Inc. All Rights Reserved + +headers +" /packages" get-package push-package + +new-device + fs-pkg$ device-name diag-cr? + + \ + \ UFS low-level block routines + \ + + h# 2000 constant /max-bsize + d# 512 constant /disk-block + + 0 instance value dev-ih + 0 instance value temp-block + + : blk>byte ( block# -- byte# ) /disk-block * ; + + : read-disk-blocks ( adr len dev-block# -- ) + blk>byte dev-ih read-disk + ; + + + \ + \ UFS superblock routines + \ + + d# 512 constant /super-block + d# 16 constant super-block# + 0 instance value super-block + + : +sb ( index -- value ) super-block swap la+ l@ ; + : iblkno ( -- n ) d# 04 +sb ; + : cgoffset ( -- n ) d# 06 +sb ; + : cgmask ( -- n ) d# 07 +sb ; + : bsize ( -- n ) d# 12 +sb ; + : fragshift ( -- n ) d# 24 +sb ; + : fsbtodbc ( -- n ) d# 25 +sb ; + : inopb ( -- n ) d# 30 +sb ; + : ipg ( -- n ) d# 46 +sb ; + : fpg ( -- n ) d# 47 +sb ; + + : /frag ( -- fragsize ) bsize fragshift rshift ; + + : get-super-block ( -- ) + super-block /super-block super-block# read-disk-blocks + ; + + : cgstart ( cg -- block# ) + dup cgmask invert and cgoffset * swap fpg * + + ; + : cgimin ( cg -- block# ) cgstart iblkno + ; + : blkstofrags ( #blocks -- #frags ) fragshift lshift ; + : lblkno ( byte-off -- lblk# ) bsize / ; + : blkoff ( byte-off -- blk-off ) bsize mod ; + : fsbtodb ( fs-blk# -- dev-blk# ) fsbtodbc lshift ; + + : read-fs-blocks ( adr len fs-blk# -- ) fsbtodb read-disk-blocks ; + + + \ + \ UFS inode routines + \ + + h# 80 constant /inode + 0 instance value inode + 0 instance value iptr + + : itoo ( i# -- offset ) inopb mod ; + : itog ( i# -- group ) ipg / ; + : itod ( i# -- block# ) + dup itog cgimin swap ipg mod inopb / blkstofrags + + ; + + : +i ( n -- adr ) iptr + ; + + : ftype ( -- n ) 0 +i w@ h# f000 and ; + : dir? ( -- flag ) ftype h# 4000 = ; + : symlink? ( -- flag ) ftype h# a000 = ; + : regular? ( -- flag ) ftype h# 8000 = ; + + : file-size ( -- n ) 8 +i x@ ; + : direct0 ( -- adr ) d# 40 +i ; + : indirect0 ( -- adr ) d# 88 +i ; + : indirect1 ( -- adr ) d# 92 +i ; + : indirect2 ( -- adr ) d# 96 +i ; + : comp? ( -- flag ) d# 100 +i l@ 4 and 0<> ; + + 0 instance value current-file + : iget ( i# -- ) + dup temp-block bsize rot itod ( i# adr len blk# ) + read-fs-blocks + dup itoo /inode * temp-block + inode /inode move + inode to iptr + to current-file ( ) + ; + + : l@++ ( ptr -- value ) dup @ l@ /l rot +! ; + + d# 12 constant #direct + : #blk-addr/blk bsize /l / ; + : #sgl-addr #blk-addr/blk ; + : #dbl-addr #sgl-addr #blk-addr/blk * ; +\ : #tri-addr #dbl-addr #blk-addr/blk * ; + + : >1-idx ( blk# -- idx ) #blk-addr/blk mod ; + : >2-idx ( blk# -- idx ) #sgl-addr / >1-idx ; +\ : >3-idx ( blk# -- idx ) #dbl-addr / >1-idx ; + + \ + \ indirect block cache + \ we assume reads will mostly be sequential, and only + \ cache the current indirect block tree + \ + : get-indir ( fs-blk# var adr -- adr ) + -rot dup >r @ over = if ( adr fs-blk# r: var ) + r> 2drop exit ( adr ) + then ( adr fs-blk# r: var ) + 2dup bsize swap read-fs-blocks ( adr fs-blk# r: var ) + r> ! ( adr ) + ; + + 0 instance value indir0-adr + instance variable cur-indir0 + : get-indir0 ( fs-blk# -- adr ) + cur-indir0 indir0-adr get-indir + ; + + 0 instance value indir1-adr + instance variable cur-indir1 + : get-indir1 ( fs-blk# -- adr ) + cur-indir1 indir1-adr get-indir + ; + + \ + \ blkptr and blklim point to an array of blk#s, + \ whether in the inode direct block array or in + \ an indirect block + \ + instance variable blkptr + instance variable blklim + + : (bmap) ( lblk# -- ) + dup #direct < if ( lblk# ) + direct0 swap la+ blkptr ! ( ) + direct0 #direct la+ blklim ! + exit + then ( lblk# ) + + #direct - ( lblk#' ) + dup #sgl-addr < if + indirect0 l@ get-indir0 ( lblk# adr ) + tuck swap >1-idx la+ blkptr ! ( adr ) + #blk-addr/blk la+ blklim ! + exit + then ( lblk# ) + + #sgl-addr - ( lblk#' ) + dup #dbl-addr < if + indirect1 l@ get-indir0 ( lblk# adr ) + over >2-idx la+ l@ get-indir1 ( lblk# adr' ) + tuck swap >1-idx la+ blkptr ! ( adr ) + #blk-addr/blk la+ blklim ! ( ) + exit + then ( lblk# ) + +\ #dbl-addr - ( lblk#' ) +\ dup #tri-addr < if +\ indirect2 l@ get-indir0 ( lblk# adr ) +\ over >3-idx la+ l@ get-indir1 ( lblk# adr' ) +\ over >2-idx la+ l@ get-indir2 ( lblk# adr' ) +\ tuck swap >1-idx la+ blkptr ! ( adr ) +\ #blk-addr/blk la+ blklim ! ( ) +\ exit +\ then ( lblk# ) + ." file too large" cr drop true ( failed ) + ; + + 0 instance value cur-blk + : bmap ( lblk# -- fs-blk# ) + dup cur-blk <> blkptr @ blklim @ = or if ( lblk# ) + dup (bmap) ( lblk# ) + then ( lblk# ) + 1+ to cur-blk ( ) + blkptr l@++ ( fs-blk# ) + ; + + : read-one-block ( adr block# -- ) + bmap ?dup if + bsize swap read-fs-blocks + else + bsize erase + then + ; + + : read-partial-block ( adr len off block# -- ) + bmap ?dup if + fsbtodb blk>byte + ( adr len byte# ) + dev-ih read-disk + else + drop erase + then + ; + + \ + \ UFS directory routines + \ + + instance variable dir-blk + instance variable totoff + instance variable dirptr + 0 instance value dir-buf + + : get-dirblk ( -- ) + dir-buf bsize dir-blk @ bmap ( adr len fs-blk# ) + read-fs-blocks ( ) + 1 dir-blk +! + ; + + 2 constant rootino + + : +d ( n -- adr ) dirptr @ + ; + + : dir-ino ( -- adr ) 0 +d l@ ; + : reclen ( -- adr ) 4 +d w@ ; + : namelen ( -- adr ) 6 +d w@ ; + : dir-name ( -- adr ) 8 +d ; + : dir-name$ ( -- file$ ) dir-name namelen ; + + + \ + \ UFS high-level routines + \ + \ After this point, the code should be independent of the disk format! + + 0 instance value search-dir + : init-dent + 0 totoff ! 0 dir-blk ! + current-file to search-dir + ; + + : get-dent ( -- end-of-dir? ) + begin + totoff @ file-size >= if + true exit + then + totoff @ blkoff 0= if + get-dirblk + dir-buf dirptr ! + else + reclen dirptr +! + then + reclen totoff +! + dir-ino 0<> + until false + ; + + : dirlook ( file$ -- not-found? ) + init-dent + begin get-dent 0= while ( file$ ) + 2dup dir-name$ $= if ( file$ ) + dir-ino iget ( file$ ) + 2drop false exit ( found ) + then ( file$ ) + repeat 2drop true ( not-found ) + ; + + h# 200 constant /fpath-buf + /fpath-buf instance buffer: fpath-buf + : clr-fpath-buf ( -- ) fpath-buf /fpath-buf erase ; + : fpath-buf$ ( -- path$ ) fpath-buf cscount ; + + : follow-symlink ( tail$ -- tail$' ) + clr-fpath-buf ( tail$ ) + fpath-buf file-size 0 0 read-partial-block ( tail$ ) + ?dup if ( tail$ ) + " /" fpath-buf$ $append ( tail$ ) + fpath-buf$ $append ( ) + else drop then ( ) + fpath-buf$ ( path$ ) + over c@ ascii / = if ( path$ ) + str++ rootino ( path$' i# ) + else ( path$ ) + search-dir ( path$ i# ) + then ( path$ i# ) + iget ( path$ ) + ; + + : lookup ( path$ -- not-found? ) + over c@ ascii / = if + str++ rootino ( path$' i# ) + else + current-file ( path$ i# ) + then ( path$ i# ) + iget ( path$ ) + begin ( path$ ) + ascii / left-parse-string ( path$ file$ ) + dup while + dir? 0= if 2drop true exit then + dirlook if 2drop true exit then ( path$ ) + symlink? if + follow-symlink ( path$' ) + then ( path$ ) + repeat ( path$ file$ ) + 2drop 2drop false ( succeeded ) + ; + + : i#>name ( i# -- name$ ) + init-dent ( i# ) + begin get-dent 0= while ( i# ) + dup dir-ino = if ( i# ) + drop dir-name$ exit ( name$ ) + then ( i# ) + repeat drop " ???" ( name$ ) + ; + + + \ + \ UFS installation routines + \ + + /max-bsize 4 * + /super-block + + /inode + + constant alloc-size + + \ **** Allocate memory for necessary data structures + : allocate-buffers ( -- ) + alloc-size mem-alloc dup 0= if + ." no memory" abort + then ( adr ) + dup to temp-block /max-bsize + ( adr ) + dup to dir-buf /max-bsize + ( adr ) + dup to indir0-adr /max-bsize + ( adr ) + dup to indir1-adr /max-bsize + ( adr ) + dup to super-block /super-block + ( adr ) + to inode ( ) + ; + + : release-buffers ( -- ) + temp-block alloc-size mem-free + ; + + \ UFS file interface + + struct + /x field >busy + /x field >offset + /inode field >inode + constant /file-record + + d# 10 constant #opens + #opens /file-record * constant /file-records + + /file-records instance buffer: file-records + + -1 instance value current-fd + : fd>record ( fd -- record ) /file-record * file-records + ; + + + : file-offset@ ( -- off ) + current-fd fd>record >offset x@ + ; + + : file-offset! ( off -- ) + current-fd fd>record >offset x! + ; + + : get-slot ( -- fd false | true ) + #opens 0 do + i fd>record >busy x@ 0= if + i false unloop exit + then + loop true + ; + + : free-slot ( fd -- ) + 0 swap fd>record >busy x! + ; + + : init-fd ( fd -- ) + fd>record ( rec ) + dup >busy 1 swap x! + dup >inode inode swap /inode move + >offset 0 swap x! + ; + + : set-fd ( fd -- error? ) + dup fd>record dup >busy x@ 0= if ( fd rec ) + 2drop true exit ( failed ) + then + >inode to iptr ( fd ) + to current-fd false ( succeeded ) + ; + + + \ get current lblk# and offset within it + : file-blk+off ( -- off block# ) + file-offset@ dup blkoff swap lblkno + ; + + \ advance file io stack by n + : fio+ ( # adr len n -- #+n adr+n len-n ) + dup file-offset@ + file-offset! + dup >r - -rot ( len' # adr r: n ) + r@ + -rot ( adr' len' # r: n ) + r> + -rot ( #' adr' len' ) + ; + + : (cwd) ( i# -- ) tokenizer[ reveal ]tokenizer + dup rootino <> if + \ open parent, find current name + " .." lookup drop + i#>name ( name$ ) + \ recurse to print path components above + current-file (cwd) ( name$ ) + \ and print this component + type ( ) + else drop then ( ) + \ slash is both root name and separator + ." /" + ; + + external + + : open ( -- okay? ) + my-args dev-open dup 0= if ( 0 ) + exit ( failed ) + then to dev-ih + + allocate-buffers + get-super-block + file-records /file-records erase + true ( succeeded ) + ; + + : close ( -- ) + dev-ih dev-close + 0 to dev-ih + release-buffers + ; + + : open-file ( path$ -- fd true | false ) + get-slot if + 2drop false exit ( failed ) + then -rot ( fd path$ ) + + lookup if ( fd ) + drop false exit ( failed ) + then + + dup init-fd true ( fd succeeded ) + ; + + : close-file ( fd -- ) + free-slot ( ) + ; + + : size-file ( fd -- size ) + set-fd if 0 else file-size then + ; + + : seek-file ( off fd -- off true | false ) + set-fd if ( off ) + drop false exit ( failed ) + then ( off ) + + dup file-size > if ( off ) + drop false exit ( failed ) + then ( off ) + dup file-offset! true ( off succeeded ) + ; + + : read-file ( adr len fd -- #read ) + set-fd if ( adr len ) + 2drop 0 exit ( 0 ) + then ( adr len ) + + regular? 0= if 2drop 0 exit then + + \ adjust len if reading past eof + dup file-offset@ + file-size > if + dup file-offset@ + file-size - - + then + dup 0= if nip exit then + + 0 -rot ( #read adr len ) + + \ initial partial block + file-offset@ blkoff ?dup if ( #read adr len off ) + bsize swap - over min ( #read adr len len' ) + 3dup nip file-blk+off ( #read adr len len' adr len' off lblk# ) + read-partial-block ( #read adr len len ) + fio+ ( #read' adr' len' ) + then ( #read adr len ) + + dup lblkno 0 ?do ( #read adr len ) + over file-blk+off nip ( #read adr len adr lblk# ) + read-one-block ( #read adr len ) + bsize fio+ ( #read' adr' len' ) + loop ( #read adr len ) + + \ final partial block + dup if ( #read adr len ) + 2dup file-blk+off ( #read adr len adr len off lblk# ) + read-partial-block ( #read adr len ) + dup fio+ ( #read' adr' 0 ) + then 2drop ( #read ) + ; + + : cinfo-file ( fd -- bsize fsize comp? ) + set-fd if 0 0 0 else bsize file-size comp? then + ; + + \ read ramdisk fcode at rd-offset + : get-rd ( adr len -- ) + rd-offset dev-ih read-disk + ; + + \ no additional props needed for ufs + : bootprop ( -- ) false ; + + \ debug words + headers + + : chdir ( dir$ -- ) + current-file -rot ( i# dir$ ) + lookup if ( i# ) + to current-file ( ) + ." no such dir" cr exit + then ( i# ) + dir? 0= if ( i# ) + to current-file ( ) + ." not a dir" cr exit + then drop ( ) + ; + + : dir ( -- ) + current-file iget + init-dent + begin get-dent 0= while + dir-name$ type cr + repeat + ; + + : cwd ( -- ) + current-file ( i# ) + dup (cwd) cr ( i# ) + iget ( ) + ; + +finish-device +pop-package diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/Makefile b/usr/src/psm/stand/bootblks/ufs/sparc/Makefile index 69ec178a4e..9679b0362c 100644 --- a/usr/src/psm/stand/bootblks/ufs/sparc/Makefile +++ b/usr/src/psm/stand/bootblks/ufs/sparc/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/bootblks/ufs/sparc/Makefile @@ -30,9 +29,25 @@ BASEDIR = ../.. -include $(BASEDIR)/ufs/Makefile.ufs +include $(BASEDIR)/Makefile.com -SUBDIRS = unix sun4c sun4m sun4d sun4u sun4v +# +# This program is used to install the boot block +# +INSTALLBOOT = installboot + +USR = $(ROOT)/usr +USR_SBIN = $(USR)/sbin +USR_SBIN_INSTALLBOOT = $(USR_SBIN)/$(INSTALLBOOT) + +# +# Overrides for installing installboot. +# +INS.file.555 = $(RM) $@; $(INS) -s -m 555 -f $(@D) $< +$(CH)INS.file.555 = $(INS) -s -m 555 -u $(OWNER) -g $(GROUP) -f $(@D) $< + + +SUBDIRS = sun4u sun4v all := TARGET= all install := TARGET= install @@ -57,6 +72,12 @@ $(SUBDIRS): FRC FRC: # +# install rules +# +$(USR_SBIN)/%: % $(USR_SBIN) + $(INS.file.555) + +# # Pattern matching rules for source in this directory # %: %.sh diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile b/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile deleted file mode 100644 index e177bae10b..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1994, 1999, by Sun Microsystems, Inc. -# All rights reserved. -# -# psm/stand/bootblks/ufs/sparc/sun4c/Makefile -# - -# -# Platform specific Makefile for the boot block. -# -# PLATFORM is the target for the binary installation. -# -# PLATLINKS is a list of platforms which are to be linked to this binary -# at the file level. -# -# PROM_TYPE is the type of prom OBP, IEEE1275, etc... -# -BASEDIR = ../../.. -PLATFORM = sun4c -PLATLINKS = -PROM_TYPE = OBPDEP - -include $(BASEDIR)/ufs/Makefile.ufs -include $(BASEDIR)/obp-c/Makefile.rules - -CPPINCS += -I$(SRC)/uts/common -CPPINCS += -I$(SRC)/uts/sun -CPPINCS += -I$(SRC)/uts/sparc - -.KEEP_STATE: - -all: $(MKBOOT) $(PROG).elf - ./$(MKBOOT) $(PROG).elf $(PROG); chmod -x $(PROG) - -include $(BASEDIR)/obp-c/Makefile.targ -include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile b/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile deleted file mode 100644 index abb8f28aec..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile +++ /dev/null @@ -1,62 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1994, 2001 by Sun Microsystems, Inc. -# All rights reserved. -# -# psm/stand/bootblks/ufs/sparc/sun4d/Makefile -# - -# -# Platform specific Makefile for the boot block. -# -# PLATFORM is the target for the binary installation. -# -# PLATFORM_INCS is a list of directories to look in for platform specific -# header files to include -# -# PLATLINKS is a list of platforms which are to be linked to this binary -# at the file level. -# -# PROM_TYPE is the type of prom OBP, IEEE1275, etc... -# -BASEDIR = ../../.. -PLATFORM = sun4d -PLATLINKS = -PROM_TYPE = OBPDEP - -include $(BASEDIR)/ufs/Makefile.ufs -include $(BASEDIR)/obp-c/Makefile.rules - -CPPINCS += -I$(SRC)/uts/common -CPPINCS += -I$(SRC)/uts/sun -CPPINCS += -I$(SRC)/uts/sparc - -.KEEP_STATE: - -all: $(MKBOOT) $(PROG).elf - ./$(MKBOOT) $(PROG).elf $(PROG); chmod -x $(PROG) - -include $(BASEDIR)/obp-c/Makefile.targ -include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile b/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile deleted file mode 100644 index ae83da4aea..0000000000 --- a/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# -# CDDL HEADER START -# -# The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. -# -# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE -# or http://www.opensolaris.org/os/licensing. -# See the License for the specific language governing permissions -# and limitations under the License. -# -# When distributing Covered Code, include this CDDL HEADER in each -# file and include the License file at usr/src/OPENSOLARIS.LICENSE. -# If applicable, add the following below this CDDL HEADER, with the -# fields enclosed by brackets "[]" replaced with your own identifying -# information: Portions Copyright [yyyy] [name of copyright owner] -# -# CDDL HEADER END -# -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 1994, by Sun Microsystems, Inc. -# All rights reserved. -# -# psm/stand/bootblks/ufs/sparc/unix/Makefile -# - -# -# Build the "Unix" version of the boot block. -# Useful solely for testing. DO NOT INSTALL IT! -# - -BASEDIR = ../../.. -PLATFORM = unix -PLATFORM_INCS = ./ -PLATLINKS = - -include $(BASEDIR)/ufs/Makefile.ufs -include $(BASEDIR)/obp-c/Makefile.rules - -CPPINCS += -I$(SRC)/head -CPPINCS += -I$(SRC)/uts/common -CPPINCS += -I$(SRC)/uts/sun -CPPINCS += -I$(SRC)/uts/sparc -CPPINCS += -I$(PLATFORM_INCS) - -UNIX_OBJS = ufs.o unix_devio.o - -$(UNIX_OBJS) := CFLAGS += -g - -.KEEP_STATE: - -all: $(PROG) - -$(PROG): $(UNIX_OBJS) - $(CC) $(CFLAGS) $(CPPFLAGS) -g -o $@ $(UNIX_OBJS) - -lint: FRC - -clean: - $(RM) $(UNIX_OBJS) - -clobber: clean - $(RM) $(PROG) - -install: FRC - -FRC: - diff --git a/usr/src/psm/stand/bootblks/zfs/Makefile b/usr/src/psm/stand/bootblks/zfs/Makefile new file mode 100644 index 0000000000..3e71e02fc4 --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/Makefile @@ -0,0 +1,45 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# psm/stand/bootblks/zfs/Makefile +# +SUBDIRS = $(MACH) + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +all install clean clobber lint : $(SUBDIRS) + +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) + +FRC: + diff --git a/usr/src/psm/stand/bootblks/zfs/Makefile.zfs b/usr/src/psm/stand/bootblks/zfs/Makefile.zfs new file mode 100644 index 0000000000..e0f1e0b52b --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/Makefile.zfs @@ -0,0 +1,82 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +#ident "%Z%%M% %I% %E% SMI" +# +# psm/stand/bootblks/zfs/Makefile.zfs +# + +include $(BASEDIR)/Makefile.com + +# +# Define FS dependent targets +# + +ZFS_DIR = $(BASEDIR)/zfs/common + +ZFSBOOT_FTH = $(ZFS_DIR)/boot-zfs.fth +ZFS_FTH = $(ZFS_DIR)/zfs.fth + +FS_FCODE = boot-zfs.fcode +FS_BB = zfs.bb + +ZFSDBGBOOT_FTH = $(ZFS_DIR)/debug-zfs.fth +ZFSDBG_FTH = $(ZFS_DIR)/big-zfs.fth + +DBGBOOT_FCODE = debug-zfs.fcode +DBGFS_FCODE = big-zfs.fcode + +DBGFS_BB = debugzfs.bb +DBGPROG = debugbb + +DBG_CLEAN += $(DBGBOOT_FCODE) $(DBGFS_FCODE) +DBG_CLOBBER += $(DBGPROG) $(DBGFS_BB) + +# +# Where and how stuff gets installed +# +USR_PSM_BOOTBLOCK = $(USR_PSM_LIB_ZFS_DIR)/$(PROG) + +%.fcode: $(BASEDIR)/zfs/common/%.fth + $(TOKENIZE) $< + +# make doesn't know fload +$(FS_FCODE): $(UTIL_FTH) $(ZFS_FTH) $(BOOT_FTH) + $(TOKENIZE) $(ZFSBOOT_FTH) + + +$(DBGBOOT_FCODE): $(UTIL_FTH) $(BOOT_FTH) + $(TOKENIZE) $(ZFSDBGBOOT_FTH) + +$(DBGFS_FCODE): $(UTIL_FTH) $(ZFS_FTH) + $(TOKENIZE) $(ZFSDBG_FTH) + +$(DBGFS_BB): $(MKBB) $(DBGBOOT_FCODE) $(DBGFS_FCODE) $(RD_FCODE) + $(MKBB) -e $(DBGFS_FCODE) $(DBGBOOT_FCODE) $(RD_FCODE) $(DBGFS_BB) + +$(DBGPROG): $(DBGFS_BB) + @-$(RM) $@ + cp -p $(DBGFS_BB) $@ + +debug: $(DBGPROG) diff --git a/usr/src/psm/stand/bootblks/zfs/common/big-zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/big-zfs.fth new file mode 100644 index 0000000000..986dabf003 --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/common/big-zfs.fth @@ -0,0 +1,43 @@ + + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ + + +id: %Z%%M% %I% %E% SMI +purpose: ZFS debug fs reader +copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved + +\ add headers +create doheaders +create bigbootblk + +: fs-pkg$ " zfs-file-system" ; +: fs-type$ " zfs" ; + +\ load common words +fload ../../../common/util.fth + +\ load fs reader +fload ../../common/zfs.fth diff --git a/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth new file mode 100644 index 0000000000..69536d3c6a --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth @@ -0,0 +1,45 @@ + + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ + + +id: %Z%%M% %I% %E% SMI +purpose: ZFS bootblock +copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved + +\ for [ifdef] zfs +create zfs + +: fs-pkg$ " zfs-file-system" ; +: fs-type$ " zfs" ; + +\ load common words +fload ../../../common/util.fth + +\ load fs reader +fload ../../common/zfs.fth + +\ load booter +fload ../../../common/boot.fth diff --git a/usr/src/psm/stand/bootblks/zfs/common/debug-zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/debug-zfs.fth new file mode 100644 index 0000000000..296ea5a2a7 --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/common/debug-zfs.fth @@ -0,0 +1,48 @@ + + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ + + +id: %Z%%M% %I% %E% SMI +purpose: ZFS debug bootblock +copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved + +\ big bootblk +create doheaders +create bigbootblk +d# 8192 constant /fs-fcode +d# 8192 constant fs-offset + +\ for [ifdef] zfs +create zfs + +: fs-pkg$ " zfs-file-system" ; +: fs-type$ " zfs" ; + +\ load common words +fload ../../../common/util.fth + +\ load booter +fload ../../../common/boot.fth diff --git a/usr/src/psm/stand/bootblks/zfs/common/zfs.fth b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth new file mode 100644 index 0000000000..50784d8839 --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/common/zfs.fth @@ -0,0 +1,1221 @@ + +\ ident "%Z%%M% %I% %E% SMI" +\ Copyright 2007 Sun Microsystems, Inc. All rights reserved. +\ Use is subject to license terms. +\ +\ CDDL HEADER START +\ +\ The contents of this file are subject to the terms of the +\ Common Development and Distribution License (the "License"). +\ You may not use this file except in compliance with the License. +\ +\ You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +\ or http://www.opensolaris.org/os/licensing. +\ See the License for the specific language governing permissions +\ and limitations under the License. +\ +\ When distributing Covered Code, include this CDDL HEADER in each +\ file and include the License file at usr/src/OPENSOLARIS.LICENSE. +\ If applicable, add the following below this CDDL HEADER, with the +\ fields enclosed by brackets "[]" replaced with your own identifying +\ information: Portions Copyright [yyyy] [name of copyright owner] +\ +\ CDDL HEADER END +\ +\ + +[ifdef] doheaders +headers +[else] +headerless +[then] + + +id: %Z%%M% %I% %E% SMI +purpose: ZFS file system support package +copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved + +" /packages" get-package push-package + +new-device + fs-pkg$ device-name diag-cr? + + 0 instance value temp-space + + + \ 64b ops + \ fcode is still 32b on 64b sparc-v9, so + \ we need to override some arithmetic ops + \ stack ops and logical ops (dup, and, etc) are 64b + : xcmp ( x1 x2 -- -1|0|1 ) + xlsplit rot xlsplit ( x2.lo x2.hi x1.lo x1.hi ) + rot 2dup < if ( x2.lo x1.lo x1.hi x2.hi ) + 2drop 2drop -1 ( lt ) + else > if ( x2.lo x1.lo ) + 2drop 1 ( gt ) + else swap 2dup < if ( x1.lo x2.lo ) + 2drop -1 ( lt ) + else > if ( ) + 1 ( gt ) + else ( ) + 0 ( eq ) + then then then then ( -1|0|1 ) + ; + : x< ( x1 x2 -- <? ) xcmp -1 = ; + : x> ( x1 x2 -- >? ) xcmp 1 = ; +\ : x= ( x1 x2 -- =? ) xcmp 0= ; + : x<> ( x1 x2 -- <>? ) xcmp 0<> ; + : x0= ( x -- 0=? ) xlsplit 0= swap 0= and ; + + /buf-len instance buffer: numbuf + + : (xu.) ( u -- u$ ) + numbuf /buf-len + swap ( adr u ) + begin + d# 10 /mod swap ( adr u' rem ) + ascii 0 + ( adr u' c ) + rot 1- tuck c! ( u adr' ) + swap dup 0= ( adr u done? ) + until drop ( adr ) + dup numbuf - /buf-len swap - ( adr len ) + ; + + \ pool name + /buf-len instance buffer: bootprop-buf + : bootprop$ ( -- prop$ ) bootprop-buf cscount ; + + \ decompression + \ + \ uts/common/os/compress.c has a definitive theory of operation comment + \ on lzjb, but here's the reader's digest version: + \ + \ repeated phrases are replaced by referenced to the original + \ e.g., + \ y a d d a _ y a d d a _ y a d d a , _ b l a h _ b l a h _ b l a h + \ becomes + \ y a d d a _ 6 11 , _ b l a h 5 10 + \ where 6 11 means memmove(ptr, ptr - 6, 11) + \ + \ data is separated from metadata with embedded copymap entries + \ every 8 items e.g., + \ 0x40 y a d d a _ 6 11 , 0x20 _ b l a h 5 10 + \ the copymap has a set bit for copy refercences + \ and a clear bit for bytes to be copied directly + \ + \ the reference marks are encoded with match-bits and match-min + \ e.g., + \ byte[0] = ((mlen - MATCH_MIN) << (NBBY - MATCH_BITS) | (off >> NBBY) + \ byte[1] = (uint8_t)off + \ + + : pow2 ( n -- 2**n ) 1 swap lshift ; + + \ assume MATCH_BITS=6 and MATCH_MIN=3 + 6 constant mbits + 3 constant mmin + 8 mbits - constant mshift + d# 16 mbits - pow2 1- constant mmask + + : decode-src ( src -- mlen off ) + dup c@ swap 1+ c@ ( c[0] c[1] ) + over mshift rshift mmin + ( c[0] c[1] mlen ) + -rot swap bwjoin mmask and ( mlen off ) + ; + + \ equivalent of memmove(dst, dst - off, len) + \ src points to a copy reference to be decoded + : mcopy ( dend dst src -- dend dst' ) + decode-src ( dend dst mlen off ) + 2 pick swap - >r ( dent dst mlen r: cpy ) + begin + 1- dup 0>= ( dend dst mlen' any? r: cpy ) + 2over > and ( dend dst mlen !done? r : cpy ) + while ( dend dst mlen r: cpy ) + swap r> dup 1+ >r c@ ( dend mlen dst c r: cpy' ) + over c! 1+ swap ( dend dst' mlen r: cpy ) + repeat ( dend dst' mlen r: cpy ) + r> 2drop ( dend dst ) + ; + + + : lzjb ( src dst len -- ) + over + swap ( src dend dst ) + rot >r ( dend dst r: src ) + + \ setup mask so 1st while iteration fills map + 0 7 pow2 2swap ( map mask dend dst r: src ) + + begin 2dup > while + 2swap 1 lshift ( dend dst map mask' r: src ) + + dup 8 pow2 = if + \ fetch next copymap + 2drop ( dend dst r: src ) + r> dup 1+ >r c@ 1 ( dend dst map' mask' r: src' ) + then ( dend dst map mask r: src' ) + + \ if (map & mask) we hit a copy reference + \ else just copy 1 byte + 2swap 2over and if ( map mask dend dst r: src ) + r> dup 2+ >r ( map mask dend dst src r: src' ) + mcopy ( map mask dend dst' r: src ) + else + r> dup 1+ >r c@ ( map mask dend dst c r: src' ) + over c! 1+ ( map mask dend dst' r: src ) + then + repeat ( map mask dend dst r: src ) + 2drop 2drop r> drop ( ) + ; + + + \ + \ ZFS block (SPA) routines + \ + + 2 constant no-comp# + h# 2.0000 constant /max-bsize + d# 512 constant /disk-block + d# 128 constant /blkp + + : blk_offset ( bp -- n ) h# 8 + x@ -1 h# 8fff.ffff lxjoin and ; + : blk_gang ( bp -- n ) h# 8 + x@ xlsplit nip d# 31 rshift ; + : blk_comp ( bp -- n ) h# 33 + c@ ; + : blk_psize ( bp -- n ) h# 34 + w@ ; + : blk_lsize ( bp -- n ) h# 36 + w@ ; + : blk_birth ( bp -- n ) h# 50 + x@ ; + + 0 instance value dev-ih + 0 instance value blk-space + 0 instance value gang-space + + : foff>doff ( fs-off -- disk-off ) /disk-block * h# 40.0000 + ; + : fsz>dsz ( fs-size -- disk-size ) 1+ /disk-block * ; + + : bp-dsize ( bp -- dsize ) blk_psize fsz>dsz ; + : bp-lsize ( bp -- lsize ) blk_lsize fsz>dsz ; + + : (read-bp) ( adr len bp -- ) + blk_offset foff>doff dev-ih read-disk + ; + + : gang-read ( adr len bp -- ) + + \ read gang block + gang-space /disk-block rot ( adr len gb-adr gb-len bp ) + (read-bp) ( adr len ) + + \ read gang indirected blocks to blk-space + \ and copy requested len from there + blk-space gang-space ( adr len tmp-adr bp0 ) + dup /blkp 3 * + bounds do ( adr len tmp-adr ) + i blk_offset x0= ?leave + i bp-dsize ( adr len tmp-adr rd-len ) + 2dup i (read-bp) + + ( adr len tmp-adr' ) + /blkp +loop + drop ( adr len ) + blk-space -rot move ( ) + ; + + \ block read that check for holes, gangs, compression, etc + : read-bp ( adr len bp -- ) + \ sparse block? + dup blk_birth x0= if + drop erase exit ( ) + then + \ gang block? + dup blk_gang if + gang-read exit ( ) + then + \ compression? + dup blk_comp no-comp# <> if + blk-space over bp-dsize ( adr len bp b-adr rd-len ) + rot (read-bp) ( adr len ) + blk-space -rot lzjb exit ( ) + then + \ boring direct block + (read-bp) ( ) + ; + + \ + \ ZFS vdev routines + \ + + h# 1.c000 constant /nvpairs + h# 4000 constant nvpairs-off + + \ + \ xdr packed nvlist + \ + \ 12B header + \ array of xdr packed nvpairs + \ 4B encoded nvpair size + \ 4B decoded nvpair size + \ 4B name string size + \ name string + \ 4B data type + \ 4B # of data elements + \ data + \ 8B of 0 + \ + d# 12 constant /nvhead + + : >nvsize ( nv -- size ) l@ ; + : >nvname ( nv -- name$ ) + /l 2* + dup /l + swap l@ + ; + : >nvdata ( nv -- data ) + >nvname + /l roundup + ; + alias nvdata>$ >nvname + + : nv-lookup ( nv name$ -- nvdata false | true ) + rot /nvhead + ( name$ nvpair ) + begin dup >nvsize while + dup >r >nvname ( name$ nvname$ r: nvpair ) + 2over $= if ( name$ r: nvpair ) + 2drop r> >nvdata ( nvdata ) + false exit ( nvdata found ) + then ( name$ r: nvpair ) + r> dup >nvsize + ( name$ nvpair' ) + repeat + 3drop true ( not-found ) + ; + + : scan-vdev ( -- ) + temp-space /nvpairs nvpairs-off ( adr len off ) + dev-ih read-disk ( ) + temp-space " name" nv-lookup if + ." no name nvpair" abort + then nvdata>$ ( pool$ ) + bootprop-buf swap move ( ) + ; + + + \ + \ ZFS ueber-block routines + \ + + d# 1024 constant /uber-block + d# 128 constant #ub/label + #ub/label /uber-block * constant /ub-ring + h# 2.0000 constant ubring-off + + : ub_magic ( ub -- n ) x@ ; + : ub_txg ( ub -- n ) h# 10 + x@ ; + : ub_timestamp ( ub -- n ) h# 20 + x@ ; + : ub_rootbp ( ub -- p ) h# 28 + ; + + 0 instance value uber-block + + : ub-cmp ( ub1 ub2 -- best-ub ) + + \ ub1 wins if ub2 isn't valid + dup ub_magic h# 00bab10c x<> if + drop exit ( ub1 ) + then + + \ if ub1 is 0, ub2 wins by default + over 0= if nip exit then ( ub2 ) + + \ 2 valid ubs, compare transaction groups + over ub_txg over ub_txg ( ub1 ub2 txg1 txg2 ) + 2dup x< if + 2drop nip exit ( ub2 ) + then ( ub1 ub2 txg1 txg2 ) + x> if drop exit then ( ub1 ) + + \ same txg, check timestamps + over ub_timestamp over ub_timestamp x> if + nip ( ub2 ) + else + drop ( ub1 ) + then + ; + + \ find best uber-block in ring, and copy it to uber-block + : get-ub ( -- ) + temp-space /ub-ring ubring-off ( adr len off ) + dev-ih read-disk ( ) + 0 temp-space /ub-ring ( null-ub adr len ) + bounds do ( ub ) + i ub-cmp ( best-ub ) + /uber-block +loop + + \ make sure we found a valid ub + dup 0= if ." no ub found" abort then + + uber-block /uber-block move ( ) + ; + + + \ + \ ZFS dnode (DMU) routines + \ + + d# 512 constant /dnode + + : dn_indblkshift ( dn -- n ) h# 1 + c@ ; + : dn_nlevels ( dn -- n ) h# 2 + c@ ; + : dn_datablkszsec ( dn -- n ) h# 8 + w@ ; + : dn_blkptr ( dn -- p ) h# 40 + ; + : dn_bonus ( dn -- p ) h# c0 + ; + + 0 instance value dnode + + \ indirect cache + \ + \ ind-cache is a 1 block indirect block cache from dnode ic-dn + \ + \ ic-bp and ic-bplim point into the ic-dn's block ptr array, + \ either in dn_blkptr or in ind-cache ic-bp is the ic-blk#'th + \ block ptr, and ic-bplim is limit of the current bp array + \ + \ the assumption is that reads will be sequential, so we can + \ just increment ic-bp + \ + 0 instance value ind-cache + 0 instance value ic-dn + 0 instance value ic-blk# + 0 instance value ic-bp + 0 instance value ic-bplim + + : dn-bsize ( dn -- bsize ) dn_datablkszsec /disk-block * ; + : dn-indsize ( dn -- indsize ) dn_indblkshift pow2 ; + : dn-indmask ( dn -- mask ) dn-indsize 1- ; + + \ recursively climb the block tree from the leaf to the root + : blk@lvl>bp ( dn blk# lvl -- bp ) tokenizer[ reveal ]tokenizer + >r /blkp * over dn_nlevels ( dn bp-off #lvls r: lvl ) + + \ at top, just add dn_blkptr + r@ = if ( dn bp-off r: lvl ) + swap dn_blkptr + ( bp r: lvl ) + r> drop exit ( bp ) + then ( dn bp-off r: lvl ) + + \ shift bp-off down and find parent indir blk + 2dup over dn_indblkshift rshift ( dn bp-off dn blk# r: lvl ) + r> 1+ blk@lvl>bp ( dn bp-off bp ) + + \ read parent indir and index + rot tuck dn-indsize ( bp-off dn bp len ) + ind-cache swap rot read-bp ( bp-off dn ) + dn-indmask and ( bp-off' ) + ind-cache + ( bp ) + ; + + \ return end of current bp array + : bplim ( dn bp -- bp-lim ) + over dn_nlevels 1 = if + drop dn_blkptr ( bp0 ) + 3 /blkp * + ( bplim ) + else + 1+ swap dn-indsize ( bp+1 indsz ) + roundup ( bplim ) + then + ; + + \ return the lblk#'th block ptr from dnode + : lblk#>bp ( dn blk# -- bp ) + 2dup ( dn blk# dn blk# ) + ic-blk# <> swap ic-dn <> or ( dn blk# cache-miss? ) + ic-bp ic-bplim = ( dn blk# cache-miss? cache-empty? ) + or if ( dn blk# ) + 2dup 1 blk@lvl>bp ( dn blk# bp ) + dup to ic-bp ( dn blk# bp ) + swap to ic-blk# ( dn bp ) + 2dup bplim to ic-bplim ( dn bp ) + over to ic-dn + then 2drop ( ) + ic-blk# 1+ to ic-blk# + ic-bp dup /blkp + to ic-bp ( bp ) + ; + + + \ + \ ZFS attribute (ZAP) routines + \ + + 1 constant fzap# + 3 constant uzap# + + d# 64 constant /uzap + + d# 24 constant /lf-chunk + d# 21 constant /lf-arr + h# ffff constant chain-end# + + h# 100 constant /lf-buf + /lf-buf instance buffer: leaf-value + /lf-buf instance buffer: leaf-name + + : +le ( len off -- n ) + w@ ; + : le_next ( le -- n ) h# 2 +le ; + : le_name_chunk ( le -- n ) h# 4 +le ; + : le_name_length ( le -- n ) h# 6 +le ; + : le_value_chunk ( le -- n ) h# 8 +le ; + : le_value_length ( le -- n ) h# a +le ; + + : la_array ( la -- adr ) 1+ ; + : la_next ( la -- n ) h# 16 + w@ ; + + 0 instance value zap-space + + \ setup leaf hash bounds + : >leaf-hash ( dn lh -- hash-adr /hash ) + /lf-chunk 2* + ( dn hash-adr ) + \ size = (bsize / 32) * 2 + swap dn-bsize 4 rshift ( hash-adr /hash ) + ; + : >leaf-chunks ( lf -- ch0 ) >leaf-hash + ; + + \ convert chunk # to leaf chunk + : ch#>lc ( dn ch# -- lc ) + /lf-chunk * ( dn lc-off ) + swap zap-space >leaf-chunks ( lc-off ch0 ) + + ( lc ) + ; + + \ assemble chunk chain into single buffer + : get-chunk-data ( dn ch# adr -- ) + dup >r /lf-buf erase ( dn ch# r: adr ) + begin + 2dup ch#>lc nip ( dn la r: adr ) + dup la_array ( dn la la-arr r: adr ) + r@ /lf-arr move ( dn la r: adr ) + r> /lf-arr + >r ( dn la r: adr' ) + la_next dup chain-end# = ( dn la-ch# end? r: adr ) + until r> 3drop ( ) + ; + + \ get leaf entry's name + : entry-name$ ( dn le -- name$ ) + 2dup le_name_chunk ( dn le dn la-ch# ) + leaf-name get-chunk-data ( dn le ) + nip le_name_length ( len ) + leaf-name swap ( name$ ) + ; + + \ return entry value as int + : entry-int-val ( dn le -- n ) + le_value_chunk ( dn la-ch# ) + leaf-value get-chunk-data ( ) + leaf-value x@ ( n ) + ; + + +[ifdef] strlookup + \ get leaf entry's value as string + : entry-val$ ( dn le -- val$ ) + 2dup le_value_chunk ( dn le dn la-ch# ) + leaf-value get-chunk-data ( dn le ) + nip le_value_length ( len ) + leaf-value swap ( name$ ) + ; +[then] + + \ apply xt to entry + : entry-apply ( xt dn le -- xt dn false | ??? true ) + over >r ( xt dn le r: dn ) + rot dup >r execute if ( ??? r: xt dn ) + r> r> 2drop true ( ??? true ) + else ( ) + r> r> false ( xt dn false ) + then + ; + + \ apply xt to every entry in chain + : chain-apply ( xt dn ch# -- xt dn false | ??? true ) + begin + 2dup ch#>lc nip ( xt dn le ) + dup >r entry-apply if ( ??? r: le ) + r> drop true exit ( ??? found ) + then ( xt dn r: le ) + r> le_next ( xt dn ch# ) + dup chain-end# = ( xt dn ch# end? ) + until drop ( xt dn ) + false ( xt dn false ) + ; + + \ apply xt to every entry in leaf + : leaf-apply ( xt dn blk# -- xt dn false | ??? true ) + + \ read zap leaf into zap-space + 2dup lblk#>bp ( xt dn blk# bp ) + nip over dn-bsize zap-space ( xt dn bp len adr ) + swap rot read-bp ( xt dn ) + + \ call chunk-look for every valid chunk list + dup zap-space >leaf-hash ( xt dn hash-adr /hash ) + bounds do ( xt dn ) + i w@ dup chain-end# <> if ( xt dn ch# ) + chain-apply if ( ??? ) + unloop true exit ( ??? found ) + then ( xt dn ) + else drop then ( xt dn ) + /w +loop + false ( xt dn not-found ) + ; + + \ apply xt to every entry in fzap + : fzap-apply ( xt dn fz -- ??? not-found? ) + + \ blk# 1 is always the 1st leaf + >r 1 leaf-apply if ( ??? r: fz ) + r> drop false exit ( ??? found ) + then r> ( xt dn fz ) + + \ call leaf-apply on every non-duplicate hash entry + \ embedded hash is in 2nd half of fzap block + over dn-bsize tuck + ( xt dn bsize hash-eadr ) + swap 2dup 2/ - ( xt dn hash-eadr bsize hash-adr ) + nip do ( xt dn ) + i x@ dup 1 <> if ( xt dn blk# ) + leaf-apply if ( ??? ) + unloop true exit ( ??? found ) + then ( xt dn ) + else drop then ( xt dn ) + /x +loop + 2drop false ( not-found ) + ; + + : mze_value ( uz -- n ) x@ ; + : mze_name ( uz -- p ) h# e + ; + + : uzap-name$ ( uz -- name$ ) mze_name cscount ; + + \ apply xt to each entry in micro-zap + : uzap-apply ( xt uz len -- ??? not-found? ) + bounds do ( xt ) + i swap dup >r ( uz xt r: xt ) + execute if ( ??? r: xt ) + r> drop ( ??? ) + unloop true exit ( ??? found ) + then r> ( xt ) + /uzap +loop + drop false ( not-found ) + ; + + \ match by name + : fz-nmlook ( prop$ dn le -- prop$ false | prop$ dn le true ) + 2dup entry-name$ ( prop$ dn le name$ ) + 2rot 2swap ( dn le prop$ name$ ) + 2over $= if ( dn le prop$ ) + 2swap true ( prop$ dn le true ) + else ( dn le prop$ ) + 2swap 2drop false ( prop$ false ) + then ( prop$ false | prop$ dn le true ) + ; + + \ match by name + : uz-nmlook ( prop$ uz -- prop$ false | prop$ uz true ) + dup >r uzap-name$ ( prop$ name$ r: uz ) + 2over $= if ( prop$ r: uz ) + r> true ( prop$ uz true ) + else ( prop$ r: uz ) + r> drop false ( prop$ false ) + then ( prop$ false | prop$ uz true ) + ; + + : zap-type ( zp -- n ) h# 7 + c@ ; + : >uzap-ent ( adr -- ent ) h# 40 + ; + + \ read zap block into temp-space + : get-zap ( dn -- zp ) + dup 0 lblk#>bp ( dn bp ) + swap dn-bsize ( bp len ) + temp-space swap ( bp adr len ) + rot read-bp ( ) + temp-space ( zp ) + ; + + \ find prop in zap dnode + : zap-lookup ( dn prop$ -- [ n ] not-found? ) + rot dup get-zap ( prop$ dn zp ) + dup zap-type case + uzap# of + >uzap-ent swap dn-bsize ( prop$ uz len ) + ['] uz-nmlook -rot ( prop$ xt uz len ) + uzap-apply if ( prop$ uz ) + mze_value -rot 2drop ( n ) + false ( n found ) + else ( prop$ ) + 2drop true ( !found ) + then ( [ n ] not-found? ) + endof + fzap# of + ['] fz-nmlook -rot ( prop$ xt dn fz ) + fzap-apply if ( prop$ dn le ) + entry-int-val ( prop$ n ) + -rot 2drop false ( n found ) + else ( prop$ ) + 2drop true ( !found ) + then ( [ n ] not-found? ) + endof + 3drop 2drop true ( !found ) + endcase ( [ n ] not-found? ) + ; + +[ifdef] strlookup + : zap-lookup-str ( dn prop$ -- [ val$ ] not-found? ) + rot dup get-zap ( prop$ dn zp ) + dup zap-type fzap# <> if ( prop$ dn zp ) + 2drop 2drop true exit ( !found ) + then ( prop$ dn zp ) + ['] fz-nmlook -rot ( prop$ xt dn fz ) + fzap-apply if ( prop$ dn le ) + entry-val$ 2swap 2drop false ( val$ found ) + else ( prop$ ) + 2drop true ( !found ) + then ( [ val$ ] not-found? ) + ; +[then] + +[ifdef] bigbootblk + : fz-print ( dn le -- false ) + entry-name$ type cr false + ; + + : uz-print ( uz -- false ) + uzap-name$ type cr false + ; + + : zap-print ( dn -- ) + dup get-zap ( dn zp ) + dup zap-type case + uzap# of + >uzap-ent swap dn-bsize ( uz len ) + ['] uz-print -rot ( xt uz len ) + uzap-apply ( false ) + endof + fzap# of + ['] fz-print -rot ( xt dn fz ) + fzap-apply ( false ) + endof + 3drop false ( false ) + endcase ( false ) + drop ( ) + ; +[then] + + + \ + \ ZFS object set (DSL) routines + \ + + 1 constant pool-dir# + + : dd_head_dataset_obj ( dd -- n ) h# 8 + x@ ; + : dd_child_dir_zapobj ( dd -- n ) h# 20 + x@ ; + : ds_bp ( ds -- p ) h# 80 + ; + + 0 instance value mos-dn + 0 instance value obj-dir + 0 instance value root-dsl + 0 instance value root-dsl# + 0 instance value fs-dn + + \ dn-cache contains dc-dn's contents at dc-blk# + \ dc-dn will be either mos-dn or fs-dn + 0 instance value dn-cache + 0 instance value dc-dn + 0 instance value dc-blk# + + alias >dsl-dir dn_bonus + alias >dsl-ds dn_bonus + + : #dn/blk ( dn -- n ) dn-bsize /dnode / ; + + \ read block into dn-cache + : get-dnblk ( dn blk# -- ) + lblk#>bp dn-cache swap ( adr bp ) + dup bp-lsize swap read-bp ( ) + ; + + \ read obj# from objset dir dn into dnode + : get-dnode ( dn obj# -- ) + + \ check dn-cache + 2dup swap #dn/blk /mod ( dn obj# off# blk# ) + swap >r nip ( dn blk# r: off# ) + 2dup dc-blk# <> ( dn blk# dn !blk-hit? r: off# ) + swap dc-dn <> or if ( dn blk# r: off# ) + \ cache miss, fill from dir + 2dup get-dnblk + over to dc-dn + dup to dc-blk# + then ( dn blk# r: off# ) + + \ index and copy + 2drop r> /dnode * ( off ) + dn-cache + ( dn-adr ) + dnode /dnode move ( ) + ; + + \ read meta object set from uber-block + : get-mos ( -- ) + mos-dn /dnode ( adr len ) + uber-block ub_rootbp read-bp + ; + + : get-mos-dnode ( obj# -- ) + mos-dn swap get-dnode + ; + + \ get root dataset + : get-root-dsl ( -- ) + + \ read MOS + get-mos + + \ read object dir + pool-dir# get-mos-dnode + dnode obj-dir /dnode move + + \ read root dataset + obj-dir " root_dataset" zap-lookup if + ." no root_dataset" abort + then ( obj# ) + dup to root-dsl# + get-mos-dnode ( ) + dnode root-dsl /dnode move + ; + + \ look thru the dsl hierarchy for path + \ this looks almost exactly like a FS directory lookup + : dsl-lookup ( path$ -- [ ds-obj# ] not-found? ) + root-dsl >r ( path$ r: root-dn ) + begin + ascii / left-parse-string ( path$ file$ r: dn ) + dup while + + \ get child dir zap dnode + r> >dsl-dir dd_child_dir_zapobj ( path$ file$ obj# ) + get-mos-dnode ( path$ file$ ) + + \ search it + dnode -rot zap-lookup if ( path$ ) + \ not found + 2drop true exit ( not-found ) + then ( path$ obj# ) + get-mos-dnode ( path$ ) + dnode >r ( path$ r: dn ) + repeat ( path$ file$ r: dn) + 2drop 2drop r> drop ( ) + + \ found it, return dataset obj# + dnode >dsl-dir dd_head_dataset_obj ( ds-obj# ) + false ( ds-obj# found ) + ; + + \ get objset from dataset + : get-objset ( adr dn -- ) + >dsl-ds ds_bp /dnode swap read-bp + ; + + + \ + \ ZFS file-system (ZPL) routines + \ + + 1 constant master-node# + d# 264 constant /znode + d# 56 constant /zn-slink + + : zp_mode ( zn -- n ) h# 48 + x@ ; + : zp_size ( zn -- n ) h# 50 + x@ ; + : zp_parent ( zn -- n ) h# 58 + x@ ; + + 0 instance value bootfs-obj# + 0 instance value root-obj# + 0 instance value current-obj# + 0 instance value search-obj# + + alias >znode dn_bonus + + : fsize ( dn -- n ) >znode zp_size ; + : ftype ( dn -- n ) >znode zp_mode h# f000 and ; + : dir? ( dn -- flag ) ftype h# 4000 = ; + : regular? ( dn -- flag ) ftype h# 8000 = ; + : symlink? ( dn -- flag ) ftype h# a000 = ; + + \ read obj# from fs objset + : get-fs-dnode ( obj# -- ) + dup to current-obj# + fs-dn swap get-dnode ( ) + ; + + \ get root-obj# from dataset + : get-rootobj# ( ds-obj# -- fsroot-obj# ) + dup to bootfs-obj# + get-mos-dnode ( ) + fs-dn dnode get-objset + + \ get root obj# from master node + master-node# get-fs-dnode + dnode " ROOT" zap-lookup if + ." no ROOT" abort + then ( fsroot-obj# ) + ; + + : prop>rootobj# ( -- ) + obj-dir " pool_props" zap-lookup if + ." no pool_props" abort + then ( prop-obj# ) + get-mos-dnode ( ) + dnode " bootfs" zap-lookup if + ." no bootfs" abort + then ( ds-obj# ) + get-rootobj# ( fsroot-obj# ) + ; + + : fs>rootobj# ( fs$ -- root-obj# not-found? ) + + \ skip pool name + ascii / left-parse-string 2drop + + \ lookup fs in dsl + dsl-lookup if ( ) + true exit ( not-found ) + then ( ds-obj# ) + + get-rootobj# ( fsroot-obj# ) + false ( fsroot-obj# found ) + ; + + \ lookup file is current directory + : dirlook ( file$ dn -- not-found? ) + \ . and .. are magic + -rot 2dup " ." $= if ( dn file$ ) + 3drop false exit ( found ) + then + + 2dup " .." $= if + 2drop >znode zp_parent ( obj# ) + else ( dn file$ ) + \ search dir + current-obj# to search-obj# + zap-lookup if ( ) + true exit ( not-found ) + then ( obj# ) + then ( obj# ) + get-fs-dnode false ( found ) + ; + + /buf-len instance buffer: fpath-buf + : clr-fpath-buf ( -- ) fpath-buf /buf-len erase ; + + : fpath-buf$ ( -- path$ ) fpath-buf cscount ; + + \ copy symlink target to adr + : readlink ( dst dn -- ) + dup fsize tuck /zn-slink > if ( dst size dn ) + \ contents in 1st block + temp-space over dn-bsize ( dst size dn t-adr bsize ) + rot 0 lblk#>bp read-bp ( dst size ) + temp-space ( dst size src ) + else ( dst size dn ) + \ contents in dnode + >znode /znode + ( dst size src ) + then ( dst size src ) + -rot move ( ) + ; + + \ modify tail to account for symlink + : follow-symlink ( tail$ -- tail$' ) + clr-fpath-buf ( tail$ ) + fpath-buf dnode readlink + + \ append to current path + ?dup if ( tail$ ) + " /" fpath-buf$ $append ( tail$ ) + fpath-buf$ $append ( ) + else drop then ( ) + fpath-buf$ ( path$ ) + + \ get directory that starts changed path + over c@ ascii / = if ( path$ ) + str++ root-obj# ( path$' obj# ) + else ( path$ ) + search-obj# ( path$ obj# ) + then ( path$ obj# ) + get-fs-dnode ( path$ ) + ; + + \ open dnode at path + : lookup ( path$ -- not-found? ) + + \ get directory that starts path + over c@ ascii / = if + str++ root-obj# ( path$' obj# ) + else + current-obj# ( path$ obj# ) + then ( path$ obj# ) + get-fs-dnode ( path$ ) + + \ lookup each path component + begin ( path$ ) + ascii / left-parse-string ( path$ file$ ) + dup while + dnode dir? 0= if + 2drop true exit ( not-found ) + then ( path$ file$ ) + dnode dirlook if ( path$ ) + 2drop true exit ( not-found ) + then ( path$ ) + dnode symlink? if + follow-symlink ( path$' ) + then ( path$ ) + repeat ( path$ file$ ) + 2drop 2drop false ( found ) + ; + + \ + \ ZFS installation routines + \ + + \ ZFS file interface + struct + /x field >busy + /x field >offset + /dnode field >dnode + constant /file-record + + d# 10 constant #opens + #opens /file-record * constant /file-records + + /file-records instance buffer: file-records + + -1 instance value current-fd + + : fd>record ( fd -- rec ) /file-record * file-records + ; + : file-offset@ ( -- off ) current-fd fd>record >offset x@ ; + : file-offset! ( off -- ) current-fd fd>record >offset x! ; + : file-dnode ( -- dn ) current-fd fd>record >dnode ; + : file-size ( -- size ) file-dnode fsize ; + : file-bsize ( -- bsize ) file-dnode dn-bsize ; + + \ find free fd slot + : get-slot ( -- fd false | true ) + #opens 0 do + i fd>record >busy x@ 0= if + i false unloop exit + then + loop true + ; + + : free-slot ( fd -- ) + 0 swap fd>record >busy x! + ; + + \ init fd to offset 0 and copy dnode + : init-fd ( fd -- ) + fd>record ( rec ) + dup >busy 1 swap x! + dup >dnode dnode swap /dnode move + >offset 0 swap x! + ; + + \ make fd current + : set-fd ( fd -- error? ) + dup fd>record >busy x@ 0= if ( fd ) + drop true exit ( failed ) + then ( fd ) + to current-fd false ( succeeded ) + ; + + \ read next fs block + : file-bread ( adr -- ) + file-bsize ( adr len ) + file-offset@ over / ( adr len blk# ) + file-dnode swap lblk#>bp ( adr len bp ) + read-bp ( ) + ; + + \ advance file io stack by n + : fio+ ( # adr len n -- #+n adr+n len-n ) + dup file-offset@ + file-offset! + dup >r - -rot ( len' # adr r: n ) + r@ + -rot ( adr' len' # r: n ) + r> + -rot ( #' adr' len' ) + ; + + /max-bsize 5 * + /uber-block + + /dnode 5 * + + /disk-block + + constant alloc-size + + : allocate-buffers ( -- ) + alloc-size h# a0.0000 vmem-alloc dup 0= if + ." no memory" abort + then ( adr ) + dup to temp-space /max-bsize + ( adr ) + dup to dn-cache /max-bsize + ( adr ) + dup to blk-space /max-bsize + ( adr ) + dup to ind-cache /max-bsize + ( adr ) + dup to zap-space /max-bsize + ( adr ) + dup to uber-block /uber-block + ( adr ) + dup to mos-dn /dnode + ( adr ) + dup to obj-dir /dnode + ( adr ) + dup to root-dsl /dnode + ( adr ) + dup to fs-dn /dnode + ( adr ) + dup to dnode /dnode + ( adr ) + to gang-space ( ) + + \ zero instance buffers + file-records /file-records erase + bootprop-buf /buf-len erase + ; + + : release-buffers ( -- ) + temp-space alloc-size mem-free + ; + + external + + : open ( -- okay? ) + my-args dev-open dup 0= if + exit ( failed ) + then to dev-ih + + allocate-buffers + scan-vdev + get-ub + get-root-dsl + true + ; + + : open-fs ( fs$ -- okay? ) + fs>rootobj# if ( ) + false ( failed ) + else ( obj# ) + to root-obj# true ( succeeded ) + then ( okay? ) + ; + + : close ( -- ) + dev-ih dev-close + 0 to dev-ih + release-buffers + ; + + : open-file ( path$ -- fd true | false ) + + \ open default fs if no open-fs + root-obj# 0= if + prop>rootobj# to root-obj# + then + + get-slot if + 2drop false exit ( failed ) + then -rot ( fd path$ ) + + lookup if ( fd ) + drop false exit ( failed ) + then ( fd ) + + dup init-fd true ( fd succeeded ) + ; + + : close-file ( fd -- ) + free-slot ( ) + ; + + : size-file ( fd -- size ) + set-fd if 0 else file-size then + ; + + : seek-file ( off fd -- off true | false ) + set-fd if ( off ) + drop false exit ( failed ) + then ( off ) + + dup file-size > if ( off ) + drop false exit ( failed ) + then ( off ) + dup file-offset! true ( off succeeded ) + ; + + : read-file ( adr len fd -- #read ) + set-fd if ( adr len ) + 2drop 0 exit ( 0 ) + then ( adr len ) + + file-dnode regular? 0= if 2drop 0 exit then + + \ adjust len if reading past eof + dup file-offset@ + file-size > if + dup file-offset@ + file-size - - + then + dup 0= if nip exit then + + 0 -rot ( #read adr len ) + + \ initial partial block + file-offset@ file-bsize mod ?dup if ( #read adr len off ) + temp-space file-bread + 2dup file-bsize swap - min ( #read adr len off cpy-len ) + 2over drop -rot ( #read adr len adr off cpy-len ) + >r temp-space + swap ( #read adr len cpy-src adr r: cpy-len ) + r@ move r> fio+ ( #read' adr' len' ) + then ( #read adr len ) + + dup file-bsize / 0 ?do ( #read adr len ) + over file-bread + file-bsize fio+ ( #read' adr' len' ) + loop ( #read adr len ) + + \ final partial block + dup if ( #read adr len ) + temp-space file-bread + 2dup temp-space -rot move ( #read adr len ) + dup fio+ ( #read' adr' 0 ) + then 2drop ( #read ) + ; + + : cinfo-file ( fd -- bsize fsize comp? ) + set-fd if + 0 0 0 + else + file-bsize file-size ( bsize fsize ) + \ zfs does internal compression + 0 ( bsize fsize comp? ) + then + ; + + \ read ramdisk fcode at rd-offset + : get-rd ( adr len -- ) + rd-offset dev-ih read-disk + ; + + : bootprop + " /" bootprop$ $append + bootfs-obj# (xu.) bootprop$ $append + bootprop$ encode-string " zfs-bootfs" ( propval propname ) + true + ; + + +[ifdef] bigbootblk + : chdir ( dir$ -- ) + current-obj# -rot ( obj# dir$ ) + lookup if ( obj# ) + to current-obj# ( ) + ." no such dir" cr exit + then ( obj# ) + dnode dir? 0= if ( obj# ) + to current-obj# ( ) + ." not a dir" cr exit + then drop ( ) + ; + + : dir ( -- ) + current-obj# get-fs-dnode + dnode zap-print + ; +[then] + +finish-device +pop-package diff --git a/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile b/usr/src/psm/stand/bootblks/zfs/i386/Makefile index 5a96e9e689..a13453a764 100644 --- a/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile +++ b/usr/src/psm/stand/bootblks/zfs/i386/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -19,17 +18,26 @@ # # CDDL HEADER END # -# Copyright 1992 Sun Microsystems, Inc. All rights reserved. -# Use is subject to license terms. # #ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# psm/stand/bootblks/zfs/i386/Makefile +# +BASEDIR = ../.. + +include $(BASEDIR)/zfs/Makefile.zfs + +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint + +.KEEP_STATE: + +all install lint clean clobber: FRC -text = LOAD ?RX V0x4000; -text : $PROGBITS ?A!W; - -data = LOAD ?RWX A0x1; -data : $PROGBITS ?AW; -data : $NOBITS ?AW; - -note = NOTE; -note : $NOTE; +FRC: diff --git a/usr/src/psm/stand/bootblks/Makefile.obp b/usr/src/psm/stand/bootblks/zfs/sparc/Makefile index 4572164d4b..2a4c1e9b1f 100644 --- a/usr/src/psm/stand/bootblks/Makefile.obp +++ b/usr/src/psm/stand/bootblks/zfs/sparc/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,34 +21,28 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright (c) 1994, by Sun Microsystems, Inc. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # -# psm/stand/bootblks/Makefile.obp +# psm/stand/bootblks/zfs/sparc/Makefile # +BASEDIR = ../.. -# -# Sources and objects used to build the Forth-based bootblock -# for Sun OBP V2 and V3 machines (using the romvec client interface) -# -# Same names for both filesystem versions. -# -FORTH_SRC = boot_obp.fth -FORTH_FCODE = $(FORTH_SRC:%.fth=%.fcode) +include $(BASEDIR)/zfs/Makefile.zfs -# -# Targets -# -$(PROG): $(FORTH_FCODE) - @-$(RM) $@ - cp -p $(FORTH_FCODE) $@ +SUBDIRS = sun4u sun4v -clean: - -$(RM) $(FORTH_FCODE) +all := TARGET= all +install := TARGET= install +clean := TARGET= clean +clobber := TARGET= clobber +lint := TARGET= lint -clobber: clean - -$(RM) $(PROG) +.KEEP_STATE: -lint: FRC +all install lint clean clobber: $(SUBDIRS) -FRC: +$(SUBDIRS): FRC + @cd $@; pwd; $(MAKE) $(TARGET) +FRC: diff --git a/usr/src/psm/stand/bootblks/zfs/sparc/sun4u/Makefile b/usr/src/psm/stand/bootblks/zfs/sparc/sun4u/Makefile new file mode 100644 index 0000000000..50e47d1f52 --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/sparc/sun4u/Makefile @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# psm/stand/bootblks/zfs/sparc/sun4u/Makefile +# + +# +# Platform specific Makefile for the boot block. +# +BASEDIR = ../../.. +PLATFORM = sun4u + +include $(BASEDIR)/zfs/Makefile.zfs +include $(BASEDIR)/Makefile.1275 + +.KEEP_STATE: + +all: $(PROG) + +include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/bootblks/zfs/sparc/sun4v/Makefile b/usr/src/psm/stand/bootblks/zfs/sparc/sun4v/Makefile new file mode 100644 index 0000000000..7fff7f49de --- /dev/null +++ b/usr/src/psm/stand/bootblks/zfs/sparc/sun4v/Makefile @@ -0,0 +1,43 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +#ident "%Z%%M% %I% %E% SMI" +# +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# psm/stand/bootblks/zfs/sparc/sun4v/Makefile +# + +# +# Platform specific Makefile for the boot block. +# +BASEDIR = ../../.. +PLATFORM = sun4v + +include $(BASEDIR)/zfs/Makefile.zfs +include $(BASEDIR)/Makefile.1275 + +.KEEP_STATE: + +all: $(PROG) + +include $(BASEDIR)/Makefile.targ diff --git a/usr/src/psm/stand/cpr/common/support.c b/usr/src/psm/stand/cpr/common/support.c index 268fcd4445..dfafa98865 100644 --- a/usr/src/psm/stand/cpr/common/support.c +++ b/usr/src/psm/stand/cpr/common/support.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,11 +30,8 @@ #include <sys/pte.h> #include <sys/promimpl.h> #include <sys/prom_plat.h> +#include "cprboot.h" -extern int cpr_ufs_close(int); -extern int cpr_ufs_open(char *, char *); -extern int cpr_ufs_read(int, char *, int); -extern int cpr_read(int, char *, size_t); extern void prom_unmap(caddr_t, uint_t); extern int cpr_debug; @@ -51,7 +47,7 @@ cpr_read_cprinfo(int fd, char *file_path, char *fs_path) { struct cprconfig cf; - if (cpr_ufs_read(fd, (char *)&cf, sizeof (cf)) != sizeof (cf) || + if (cpr_fs_read(fd, (char *)&cf, sizeof (cf)) != sizeof (cf) || cf.cf_magic != CPR_CONFIG_MAGIC) return (-1); @@ -71,12 +67,11 @@ int cpr_locate_statefile(char *file_path, char *fs_path) { int fd; - char *boot_path = prom_bootpath(); int rc; - if ((fd = cpr_ufs_open(CPR_CONFIG, boot_path)) != -1) { + if ((fd = cpr_fs_open(CPR_CONFIG)) != -1) { rc = cpr_read_cprinfo(fd, file_path, fs_path); - (void) cpr_ufs_close(fd); + (void) cpr_fs_close(fd); } else rc = -1; @@ -95,7 +90,7 @@ cpr_locate_statefile(char *file_path, char *fs_path) int cpr_reset_properties(void) { - char *str, *boot_path, *default_path; + char *str, *default_path; int fd, len, rc, prop_errors; cprop_t *prop, *tail; cdef_t cdef; @@ -103,16 +98,15 @@ cpr_reset_properties(void) str = "cpr_reset_properties"; default_path = CPR_DEFAULT; - boot_path = prom_bootpath(); - if ((fd = cpr_ufs_open(default_path, boot_path)) == -1) { - prom_printf("%s: unable to open %s on %s\n", - str, default_path, boot_path); + if ((fd = cpr_fs_open(default_path)) == -1) { + prom_printf("%s: unable to open %s\n", + str, default_path); return (-1); } rc = 0; - len = cpr_ufs_read(fd, (char *)&cdef, sizeof (cdef)); + len = cpr_fs_read(fd, (char *)&cdef, sizeof (cdef)); if (len != sizeof (cdef)) { prom_printf("%s: error reading %s\n", str, default_path); rc = -1; @@ -121,7 +115,7 @@ cpr_reset_properties(void) rc = -1; } - (void) cpr_ufs_close(fd); + (void) cpr_fs_close(fd); if (rc) return (rc); diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c index 5881aa2fca..60ff9d8b96 100644 --- a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c +++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c @@ -84,7 +84,7 @@ static char cb_argbuf[CB_MAXPROP]; static char *cb_args[CB_MAXARGS]; static int reusable; -static char *specialstate; +char *specialstate; static int @@ -399,7 +399,10 @@ cb_read_statefile(void) cnt = 0; dtlb_index = cb_dents - 1; - (void) prom_seek(sfile.fd, specialstate ? CPR_SPEC_OFFSET : 0); + if (specialstate) + (void) prom_seek(sfile.fd, CPR_SPEC_OFFSET); + else + (void) cpr_fs_seek(sfile.fd, 0); CPR_DEBUG(CPR_DEBUG1, "%s: reading statefile... ", prog); for (resid = cdump.cdd_filesize; resid; resid -= len) { /* @@ -422,7 +425,7 @@ cb_read_statefile(void) cnt++; len = min(PROM_MAX_READ, resid); - nread = prom_read(sfile.fd, dst_virt, len, 0, 0); + nread = cpr_read(sfile.fd, dst_virt, len); if (nread != (ssize_t)len) { prom_printf("\n%s: prom read error, " "expect %ld, got %ld\n", str, len, nread); @@ -469,9 +472,11 @@ cb_read_statefile(void) */ static int (*first_worklist[])(void) = { cb_intro, + cb_mountroot, cb_startup, cb_get_props, cb_usb_setup, + cb_unmountroot, cb_open_sf, cb_read_statefile, cb_close_sf, diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h index 2102820146..4ceb64ba83 100644 --- a/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h +++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h @@ -225,11 +225,18 @@ extern pfn_t cpr_vatopfn(caddr_t); extern int prom_remap(size_t, caddr_t, physaddr_t); extern void install_remap(void); extern int cb_alloc(size_t, uint_t, caddr_t *, physaddr_t *); +extern int cb_mountroot(void); +extern int cb_unmountroot(void); extern int cb_get_props(void); extern void cb_mapin(caddr_t, pfn_t, uint_t, uint_t, uint_t); extern int cb_usb_setup(void); extern void cb_enter_mon(void); extern void cb_exit_to_mon(void); +extern int cpr_fs_close(int); +extern int cpr_fs_open(char *); +extern int cpr_fs_read(int, char *, int); +extern int cpr_fs_seek(int, offset_t); +extern int cpr_read(int, char *, size_t); /* * cb_srt0.s diff --git a/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c b/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c index d59258c8db..e739d31d46 100644 --- a/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c +++ b/usr/src/psm/stand/cpr/sparcv9/sun4u/util.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,11 +30,15 @@ #include "cprboot.h" +static ihandle_t cb_rih; +static pnode_t chosen; + +static int statefile_special; + static int reset_input = 0; static char kbd_input[] = "keyboard input"; static char null_input[] = "\" /nulldev\" input"; - /* * Ask prom to open a disk file given either the OBP device path, or the * device path representing the target drive/partition and the fs-relative @@ -44,113 +47,149 @@ static char null_input[] = "\" /nulldev\" input"; */ /* ARGSUSED */ int -cpr_statefile_open(char *path, char *fs) +cpr_statefile_open(char *path, char *fs_dev) { - char full_path[OBP_MAXPATHLEN]; - char *fp; + int plen, dlen; int handle; - int c; + char fs_pkg[OBP_MAXPATHLEN]; + char fs_name[OBP_MAXDRVNAME]; /* * instead of using specialstate, we use fs as the flag */ - if (*fs == '\0') { /* device open */ + if (*fs_dev == '\0') { /* device open */ + statefile_special = 1; handle = prom_open(path); /* IEEE1275 prom_open returns 0 on failure; we return -1 */ return (handle ? handle : -1); } /* - * IEEE 1275 prom needs "device-path,|file-path" where - * file-path can have embedded |'s. + * No cif for $open-package, so we have to use interpret */ - fp = full_path; - (void) prom_strcpy(fp, fs); - fp += prom_strlen(fp); - *fp++ = ','; - *fp++ = '|'; - - /* Skip a leading slash in file path -- we provided for it above. */ - if (*path == '/') - path++; - - /* Copy file path and convert separators. */ - while ((c = *path++) != '\0') - if (c == '/') - *fp++ = '|'; - else - *fp++ = c; - *fp = '\0'; - - handle = prom_open(full_path); - if (verbose) { - if (fp = prom_strrchr(full_path, '/')) - fp++; - else - fp = full_path; - prom_printf("cso: prom_open(\"%s\") = 0x%x\n", fp, handle); + if (prom_getprop(chosen, "fs-package", fs_pkg) == -1) { + prom_printf("Missing fs-package name\n"); + return (-1); + } + plen = prom_strlen(fs_pkg); + dlen = prom_strlen(fs_dev); + prom_interpret("$open-package swap l!", plen, (uintptr_t)fs_pkg, + dlen, (uintptr_t)fs_dev, (uintptr_t)&cb_rih); + if (cb_rih == OBP_BADNODE || cb_rih == 0) { + prom_printf("Can't open %s\n", fs_pkg); + return (-1); } /* - * IEEE1275 prom_open returns 0 on failure; we return -1 + * Prepend '/' if it's not there already */ - return (handle ? handle : -1); + if (*path != '/') { + (void) prom_sprintf(fs_name, "/%s", path); + return (cpr_fs_open(fs_name)); + } else + return (cpr_fs_open(path)); } - /* - * Ask prom to open a disk file given the device path representing - * the target drive/partition and the fs-relative path of the file. - * Handle file pathnames with or without leading '/'. if fs points - * to a null char, it indicates that we are opening a device. + * Mount root fs so we can read statefile, etc + * + * sets global + * cb_rih */ -/* ARGSUSED */ int -cpr_ufs_open(char *path, char *fs) +cb_mountroot() { - CB_VENTRY(cpr_ufs_open); - /* - * screen invalid state, then just use the other code rather than - * duplicating it - */ - if (*fs == '\0') { /* device open */ - prom_printf("cpr_ufs_open: NULL fs, path %s\n", path); + chosen = prom_chosennode(); + if (chosen == OBP_BADNODE) { + prom_printf("Missing chosen node\n"); return (ERR); } - return (cpr_statefile_open(path, fs)); + if (prom_getprop(chosen, "bootfs", (caddr_t)&cb_rih) == -1) { + prom_printf("Missing bootfs ihandle\n"); + return (ERR); + } + return (0); +} + +/* + * Unmount root + */ +int +cb_unmountroot() +{ + (void) prom_close(cb_rih); + cb_rih = OBP_BADNODE; + return (0); +} + +/* + * Ask prom to open a disk file. + */ +/* ARGSUSED */ +int +cpr_fs_open(char *path) +{ + + CB_VENTRY(cpr_fs_open); + + if (cb_rih == OBP_BADNODE) + return (-1); + return (prom_fopen(cb_rih, path)); } /* - * On sun4u there's no difference here, since prom groks ufs directly + * Direct read if using block special, + * otherwise use fs read */ int cpr_read(int fd, caddr_t buf, size_t len) { - return (prom_read(fd, buf, len, 0, 0)); + if (!statefile_special) + return (cpr_fs_read(fd, buf, len)); + else + return (prom_read(fd, buf, len, 0, 0)); } int -cpr_ufs_read(int fd, caddr_t buf, int len) +cpr_fs_read(int fd, caddr_t buf, int len) { - return (prom_read(fd, buf, len, 0, 0)); + if (cb_rih == OBP_BADNODE) + return (-1); + return (prom_fread(cb_rih, fd, buf, len)); } int -cpr_ufs_close(int fd) +cpr_fs_close(int fd) +{ + CB_VPRINTF(("cpr_fs_close 0x%x\n", fd)); + + if (cb_rih == OBP_BADNODE) + return (-1); + prom_fclose(cb_rih, fd); + return (0); +} + +int +cpr_fs_seek(int fd, offset_t off) { - CB_VPRINTF(("cpr_ufs_close 0x%x\n", fd)); - return (prom_close(fd)); + if (cb_rih == OBP_BADNODE) + return (-1); + return (prom_fseek(cb_rih, fd, off)); } int cpr_statefile_close(int fd) { - return (prom_close(fd)); + if (statefile_special) { + statefile_special = 0; + return (prom_close(fd)); + } else + return (cpr_fs_close(fd)); } diff --git a/usr/src/psm/stand/lib/boot/sparc/Makefile.com b/usr/src/psm/stand/lib/boot/sparc/Makefile.com index 495ca3d0ed..d7b224b644 100644 --- a/usr/src/psm/stand/lib/boot/sparc/Makefile.com +++ b/usr/src/psm/stand/lib/boot/sparc/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -64,7 +63,7 @@ CPPINCS += -I$(ROOT)/usr/include/$(ARCHVERS) CPPINCS += -I$(ROOT)/usr/platform/$(PLATFORM)/include CPPINCS += -I$(PSMSYSHDRDIR) CPPFLAGS = $(CPPINCS) $(CCYFLAG)$(PSMSYSHDRDIR) -CPPFLAGS += -D_KERNEL -D_BOOT +CPPFLAGS += -D_KERNEL -D_BOOT -D_MACHDEP ASFLAGS = -P -D__STDC__ -D_ASM $(CPPINCS) CFLAGS += $(CCVERBOSE) diff --git a/usr/src/psm/stand/lib/boot/sparcv9/Makefile.com b/usr/src/psm/stand/lib/boot/sparcv9/Makefile.com index f160c1405e..7f8dcdd49f 100644 --- a/usr/src/psm/stand/lib/boot/sparcv9/Makefile.com +++ b/usr/src/psm/stand/lib/boot/sparcv9/Makefile.com @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -22,7 +21,7 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/lib/boot/sparcv9/Makefile.com @@ -64,7 +63,7 @@ CPPINCS += -I$(ROOT)/usr/include/$(ARCHVERS) CPPINCS += -I$(ROOT)/usr/platform/$(PLATFORM)/include CPPINCS += -I$(PSMSYSHDRDIR) CPPFLAGS = $(CPPINCS) $(CCYFLAG)$(PSMSYSHDRDIR) -CPPFLAGS += -D_KERNEL +CPPFLAGS += -D_KERNEL -D_MACHDEP ASFLAGS = -P -D__STDC__ -D_ASM $(CPPINCS) CFLAGS += $(CCVERBOSE) diff --git a/usr/src/psm/stand/lib/names/sparc/common/uname-i.c b/usr/src/psm/stand/lib/names/sparc/common/uname-i.c index 6e7e9401f0..c91fdedb4b 100644 --- a/usr/src/psm/stand/lib/names/sparc/common/uname-i.c +++ b/usr/src/psm/stand/lib/names/sparc/common/uname-i.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -183,24 +182,13 @@ open_platform_file( char *filename, int (*openfn)(char *, void *), void *arg, - char *fullpath, - char *given_iarch) + char *fullpath) { char *ia; int fd; enum ia_state_mach state = STATE_NAME; /* - * First try the impl_arch_name hint. - * - * This is only here to support the -I flag to boot. - */ - if (given_iarch != NULL) { - make_platform_path(fullpath, given_iarch, filename); - return ((*openfn)(fullpath, arg)); - } - - /* * Hunt the filesystem for one that works .. */ while ((ia = get_impl_arch_name(&state, 1)) != NULL) { diff --git a/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4u/Makefile b/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4u/Makefile index 0d47a6ef89..2a4cb99393 100644 --- a/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4u/Makefile +++ b/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4u/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/boot/sparcv9/ieee1275/sun4u/Makefile @@ -54,6 +53,7 @@ PLAT_PFILES = \ PLAT_PSUN4FILES = \ prom_alloc.c \ prom_cpuctl.c \ + prom_fio.c \ prom_getunum.c \ prom_idprom.c \ prom_init.c \ @@ -61,7 +61,8 @@ PLAT_PSUN4FILES = \ prom_map.c \ prom_mem.c \ prom_retain.c \ - prom_sparc.c + prom_sparc.c \ + prom_vername.c KARCH = sun4u MMU = sfmmu diff --git a/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4v/Makefile b/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4v/Makefile index c02f97839c..e10d2c36c6 100644 --- a/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4v/Makefile +++ b/usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4v/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ # CDDL HEADER END # # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2007 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # psm/stand/boot/sparcv9/ieee1275/sun4v/Makefile @@ -59,7 +58,8 @@ PLAT_PSUN4FILES = \ prom_map.c \ prom_mem.c \ prom_retain.c \ - prom_sparc.c + prom_sparc.c \ + prom_vername.c KARCH = sun4v MMU = sfmmu diff --git a/usr/src/psm/stand/sys/platnames.h b/usr/src/psm/stand/sys/platnames.h index e63b357104..cf3152f2cb 100644 --- a/usr/src/psm/stand/sys/platnames.h +++ b/usr/src/psm/stand/sys/platnames.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1994-1999 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ #ifndef _SYS_PLATNAMES_H @@ -39,7 +38,7 @@ extern "C" { extern char *get_mfg_name(void); extern int find_platform_dir(int (*)(char *), char *, int); extern int open_platform_file(char *, - int (*)(char *, void *), void *, char *, char *); + int (*)(char *, void *), void *, char *); extern void mod_path_uname_m(char *, char *); #ifdef __cplusplus |
