summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deleted_files/usr/src/psm/stand/boot/sparc/common/boot.c (renamed from usr/src/psm/stand/boot/sparc/common/boot.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/sparc/common/boot_services.c (renamed from usr/src/psm/stand/boot/sparc/common/boot_services.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/sparc/common/hsfsconf.c (renamed from usr/src/psm/stand/boot/sparc/common/hsfsconf.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/boot/sparc/common/ufsconf.c (renamed from usr/src/psm/stand/boot/sparc/common/ufsconf.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/Makefile.obp (renamed from usr/src/psm/stand/bootblks/Makefile.obp)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com (renamed from usr/src/psm/stand/bootblks/hsfs/common/Makefile.com)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth (renamed from usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c (renamed from usr/src/psm/stand/bootblks/hsfs/common/hsfs.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h (renamed from usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c (renamed from usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/common/iob.h (renamed from usr/src/psm/stand/bootblks/hsfs/common/iob.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile (renamed from usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.rules (renamed from usr/src/psm/stand/bootblks/obp-c/Makefile.rules)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.targ (renamed from usr/src/psm/stand/bootblks/obp-c/Makefile.targ)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h (renamed from usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh (renamed from usr/src/psm/stand/bootblks/obp-c/common/makevers.sh)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c (renamed from usr/src/psm/stand/bootblks/obp-c/common/mkboot.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/romp.h (renamed from usr/src/psm/stand/bootblks/obp-c/common/romp.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/stub.c (renamed from usr/src/psm/stand/bootblks/obp-c/common/stub.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c (renamed from usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile (renamed from usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s (renamed from usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/common/Makefile.com (renamed from usr/src/psm/stand/bootblks/ufs/common/Makefile.com)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth (renamed from usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth (renamed from usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/common/iob.h (renamed from usr/src/psm/stand/bootblks/ufs/common/iob.h)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/common/ufs.c (renamed from usr/src/psm/stand/bootblks/ufs/common/ufs.c)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile (renamed from usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile (renamed from usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile (renamed from usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile)0
-rw-r--r--deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile (renamed from usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile)0
-rw-r--r--deleted_files/usr/src/uts/sparc/krtld/Makefile (renamed from usr/src/uts/sparc/krtld/Makefile)0
-rw-r--r--deleted_files/usr/src/uts/sparc/krtld/kobj_alloc.c (renamed from usr/src/uts/sparc/krtld/kobj_alloc.c)0
-rw-r--r--deleted_files/usr/src/uts/sparc/krtld/kobj_boot.c (renamed from usr/src/uts/sparc/krtld/kobj_boot.c)0
-rw-r--r--deleted_files/usr/src/uts/sparc/krtld/kobj_crt.s (renamed from usr/src/uts/sparc/krtld/kobj_crt.s)0
-rw-r--r--usr/src/Makefile.psm1
-rw-r--r--usr/src/Makefile.psm.targ6
-rw-r--r--usr/src/Targetdirs6
-rw-r--r--usr/src/cmd/boot/Makefile13
-rw-r--r--usr/src/cmd/boot/Makefile.com21
-rw-r--r--usr/src/cmd/boot/Makefile.targ15
-rw-r--r--usr/src/cmd/boot/bootadm/Makefile13
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.c367
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm.h3
-rw-r--r--usr/src/cmd/boot/bootadm/bootadm_upgrade.c6
-rw-r--r--usr/src/cmd/boot/filelist/Makefile46
-rw-r--r--usr/src/cmd/boot/filelist/Makefile.com39
-rw-r--r--usr/src/cmd/boot/filelist/Makefile.targ32
-rw-r--r--usr/src/cmd/boot/filelist/i386/Makefile36
-rw-r--r--usr/src/cmd/boot/filelist/i386/filelist.ramdisk (renamed from usr/src/cmd/boot/bootadm/filelist.ramdisk)29
-rw-r--r--usr/src/cmd/boot/filelist/i386/filelist.safe (renamed from usr/src/cmd/boot/bootadm/filelist.safe)0
-rw-r--r--usr/src/cmd/boot/filelist/sparc/Makefile36
-rw-r--r--usr/src/cmd/boot/filelist/sparc/filelist.ramdisk75
-rw-r--r--usr/src/cmd/boot/filelist/sparc/filelist.safe14
-rw-r--r--usr/src/cmd/boot/fiocompress/Makefile64
-rw-r--r--usr/src/cmd/boot/fiocompress/fiocompress.c316
-rw-r--r--usr/src/cmd/boot/fiocompress/message.h67
-rw-r--r--usr/src/cmd/boot/installgrub/Makefile13
-rw-r--r--usr/src/cmd/boot/mbr/Makefile17
-rw-r--r--usr/src/cmd/boot/scripts/Makefile.com33
-rw-r--r--usr/src/cmd/boot/scripts/Makefile.i38611
-rw-r--r--usr/src/cmd/boot/scripts/Makefile.sparc12
-rw-r--r--usr/src/cmd/boot/scripts/boot-archive-update.ksh21
-rw-r--r--usr/src/cmd/boot/scripts/create_ramdisk.ksh117
-rw-r--r--usr/src/cmd/boot/scripts/extract_boot_filelist.ksh92
-rw-r--r--usr/src/cmd/boot/scripts/root_archive.ksh384
-rw-r--r--usr/src/cmd/boot/symdef/Makefile10
-rw-r--r--usr/src/cmd/sgs/libld/Makefile.com1
-rw-r--r--usr/src/cmd/sgs/librtld/Makefile.com5
-rw-r--r--usr/src/cmd/sgs/rtld/Makefile.com1
-rw-r--r--usr/src/cmd/svc/milestone/README.share19
-rw-r--r--usr/src/cmd/svc/milestone/boot-archive20
-rw-r--r--usr/src/pkgdefs/SUNWcakr.i/prototype_com3
-rw-r--r--usr/src/pkgdefs/SUNWcakr.u/prototype_com1
-rw-r--r--usr/src/pkgdefs/SUNWcakr.v/prototype_com3
-rw-r--r--usr/src/pkgdefs/SUNWckr/prototype_sparc2
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_com9
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_i3863
-rw-r--r--usr/src/pkgdefs/SUNWcsr/prototype_sparc1
-rw-r--r--usr/src/pkgdefs/SUNWcsu/prototype_sparc1
-rw-r--r--usr/src/pkgdefs/SUNWhea/prototype_com1
-rw-r--r--usr/src/pkgdefs/SUNWkvm.c/prototype_com14
-rw-r--r--usr/src/pkgdefs/SUNWkvm.d/prototype_com14
-rw-r--r--usr/src/pkgdefs/SUNWkvm.m/prototype_com12
-rw-r--r--usr/src/pkgdefs/SUNWkvm.u/prototype_com4
-rw-r--r--usr/src/pkgdefs/SUNWkvm.v/prototype_com4
-rw-r--r--usr/src/psm/promif/ieee1275/sun4/prom_fio.c219
-rw-r--r--usr/src/psm/promif/ieee1275/sun4/prom_init.c13
-rw-r--r--usr/src/psm/promif/ieee1275/sun4/prom_mem.c53
-rw-r--r--usr/src/psm/promif/ieee1275/sun4u/Makefile.files6
-rw-r--r--usr/src/psm/promif/ieee1275/sun4u/prom_mmu.c39
-rw-r--r--usr/src/psm/promif/ieee1275/sun4v/Makefile.files6
-rw-r--r--usr/src/psm/stand/boot/Makefile.boot15
-rw-r--r--usr/src/psm/stand/boot/Makefile.targ11
-rw-r--r--usr/src/psm/stand/boot/common/readfile.c72
-rw-r--r--usr/src/psm/stand/boot/sparc/common/boot_plat.c92
-rw-r--r--usr/src/psm/stand/boot/sparc/common/boot_plat.h19
-rw-r--r--usr/src/psm/stand/boot/sparc/common/bootflags.c57
-rw-r--r--usr/src/psm/stand/boot/sparc/common/bootops.c55
-rw-r--r--usr/src/psm/stand/boot/sparc/common/inetboot.c181
-rw-r--r--usr/src/psm/stand/boot/sparc/common/ramdisk.c861
-rw-r--r--usr/src/psm/stand/boot/sparc/common/ramdisk.h13
-rw-r--r--usr/src/psm/stand/boot/sparc/common/sun4x_standalloc.c27
-rw-r--r--usr/src/psm/stand/boot/sparc/common/wanboot.c188
-rw-r--r--usr/src/psm/stand/boot/sparcv9/Makefile.com108
-rw-r--r--usr/src/psm/stand/bootblks/Makefile11
-rw-r--r--usr/src/psm/stand/bootblks/Makefile.127542
-rw-r--r--usr/src/psm/stand/bootblks/common/boot.fth609
-rwxr-xr-xusr/src/psm/stand/bootblks/common/mkbb.sh85
-rw-r--r--usr/src/psm/stand/bootblks/common/rd.fth83
-rw-r--r--usr/src/psm/stand/bootblks/common/util.fth219
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/Makefile16
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/Makefile.hsfs54
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/common/boot-hsfs.fth44
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/common/hsfs.fth636
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/sparc/Makefile9
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/sparc/sun4u/Makefile43
-rw-r--r--usr/src/psm/stand/bootblks/hsfs/sparc/sun4v/Makefile43
-rw-r--r--usr/src/psm/stand/bootblks/ufs/Makefile.ufs29
-rw-r--r--usr/src/psm/stand/bootblks/ufs/common/boot-ufs.fth45
-rw-r--r--usr/src/psm/stand/bootblks/ufs/common/ufs.fth584
-rw-r--r--usr/src/psm/stand/bootblks/ufs/sparc/Makefile33
-rw-r--r--usr/src/psm/stand/bootblks/zfs/Makefile45
-rw-r--r--usr/src/psm/stand/bootblks/zfs/Makefile.zfs82
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/big-zfs.fth43
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/boot-zfs.fth45
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/debug-zfs.fth48
-rw-r--r--usr/src/psm/stand/bootblks/zfs/common/zfs.fth1221
-rw-r--r--usr/src/psm/stand/bootblks/zfs/i386/Makefile43
-rw-r--r--usr/src/psm/stand/bootblks/zfs/sparc/Makefile48
-rw-r--r--usr/src/psm/stand/bootblks/zfs/sparc/sun4u/Makefile43
-rw-r--r--usr/src/psm/stand/bootblks/zfs/sparc/sun4v/Makefile43
-rw-r--r--usr/src/psm/stand/cpr/common/support.c32
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.c11
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/cprboot.h7
-rw-r--r--usr/src/psm/stand/cpr/sparcv9/sun4u/util.c163
-rw-r--r--usr/src/psm/stand/lib/boot/sparc/Makefile.com9
-rw-r--r--usr/src/psm/stand/lib/boot/sparcv9/Makefile.com9
-rw-r--r--usr/src/psm/stand/lib/names/sparc/common/uname-i.c20
-rw-r--r--usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4u/Makefile11
-rw-r--r--usr/src/psm/stand/lib/promif/sparcv9/ieee1275/sun4v/Makefile10
-rw-r--r--usr/src/psm/stand/sys/platnames.h11
-rw-r--r--usr/src/stand/lib/fs/hsfs/hsfsops.c225
-rw-r--r--usr/src/stand/lib/fs/nfs/nfsops.c24
-rw-r--r--usr/src/stand/lib/fs/ufs/ufsops.c22
-rw-r--r--usr/src/stand/lib/sa/stddef.h9
-rw-r--r--usr/src/tools/findunref/exception_list7
-rw-r--r--usr/src/tools/scripts/Install.sh4
-rw-r--r--usr/src/tools/scripts/bfu.sh69
-rw-r--r--usr/src/tools/scripts/mkbfu.sh9
-rw-r--r--usr/src/uts/common/Makefile.files20
-rw-r--r--usr/src/uts/common/Makefile.rules23
-rw-r--r--usr/src/uts/common/fs/dcfs/dc_vnops.c1110
-rw-r--r--usr/src/uts/common/fs/nfs/nfs_dlinet.c35
-rw-r--r--usr/src/uts/common/fs/ufs/ufs_filio.c21
-rw-r--r--usr/src/uts/common/fs/ufs/ufs_vnops.c61
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c16
-rw-r--r--usr/src/uts/common/inet/ip/ip_if.c6
-rw-r--r--usr/src/uts/common/io/ramdisk.c78
-rw-r--r--usr/src/uts/common/io/strplumb.c51
-rw-r--r--usr/src/uts/common/krtld/kobj.c498
-rw-r--r--usr/src/uts/common/krtld/kobj_bootflags.c41
-rw-r--r--usr/src/uts/common/krtld/kobj_kdi.c2
-rw-r--r--usr/src/uts/common/krtld/kobj_subr.c167
-rw-r--r--usr/src/uts/common/os/autoconf.c2
-rw-r--r--usr/src/uts/common/os/instance.c16
-rw-r--r--usr/src/uts/common/os/modsysfile.c2
-rw-r--r--usr/src/uts/common/os/space.c27
-rw-r--r--usr/src/uts/common/os/swapgeneric.c60
-rw-r--r--usr/src/uts/common/os/vfs_conf.c1
-rw-r--r--usr/src/uts/common/sys/Makefile1
-rw-r--r--usr/src/uts/common/sys/bootstat.h19
-rw-r--r--usr/src/uts/common/sys/filio.h12
-rw-r--r--usr/src/uts/common/sys/fs/decomp.h78
-rw-r--r--usr/src/uts/common/sys/fs/ufs_filio.h8
-rw-r--r--usr/src/uts/common/sys/fs/ufs_inode.h2
-rw-r--r--usr/src/uts/common/sys/isa_defs.h5
-rw-r--r--usr/src/uts/common/sys/kobj.h14
-rw-r--r--usr/src/uts/common/sys/kobj_impl.h40
-rw-r--r--usr/src/uts/common/sys/ramdisk.h14
-rw-r--r--usr/src/uts/common/sys/systm.h4
-rw-r--r--usr/src/uts/common/syscall/systeminfo.c54
-rw-r--r--usr/src/uts/i86pc/os/ddi_impl.c3
-rw-r--r--usr/src/uts/i86pc/os/fakebop.c20
-rw-r--r--usr/src/uts/i86pc/os/mlsetup.c37
-rw-r--r--usr/src/uts/intel/Makefile.rules6
-rw-r--r--usr/src/uts/intel/amd64/krtld/kobj_boot.c2
-rw-r--r--usr/src/uts/intel/ia32/krtld/kobj_boot.c2
-rw-r--r--usr/src/uts/intel/ia32/ml/modstubs.s9
-rw-r--r--usr/src/uts/intel/sys/bootconf.h18
-rw-r--r--usr/src/uts/sparc/Makefile.files5
-rw-r--r--usr/src/uts/sparc/Makefile.rules19
-rw-r--r--usr/src/uts/sparc/Makefile.sparc.shared3
-rw-r--r--usr/src/uts/sparc/dcfs/Makefile88
-rw-r--r--usr/src/uts/sparc/krtld/doreloc.c6
-rw-r--r--usr/src/uts/sparc/krtld/kobj_convrelstr.c4
-rw-r--r--usr/src/uts/sparc/krtld/kobj_reloc.c2
-rw-r--r--usr/src/uts/sparc/ml/modstubs.s9
-rw-r--r--usr/src/uts/sparc/os/archdep.c9
-rw-r--r--usr/src/uts/sparc/os/bootops.c907
-rw-r--r--usr/src/uts/sun/sys/bootconf.h99
-rw-r--r--usr/src/uts/sun/sys/obpdefs.h2
-rw-r--r--usr/src/uts/sun/sys/promif.h12
-rw-r--r--usr/src/uts/sun4/conf/Mapfile13
-rw-r--r--usr/src/uts/sun4/os/forthdebug.c16
-rw-r--r--usr/src/uts/sun4/os/memlist.c585
-rw-r--r--usr/src/uts/sun4/os/memnode.c10
-rw-r--r--usr/src/uts/sun4/os/mlsetup.c250
-rw-r--r--usr/src/uts/sun4/os/mp_startup.c21
-rw-r--r--usr/src/uts/sun4/os/startup.c1338
-rw-r--r--usr/src/uts/sun4/sys/memlist_plat.h39
-rw-r--r--usr/src/uts/sun4/sys/memnode.h3
-rw-r--r--usr/src/uts/sun4/sys/platform_module.h5
-rw-r--r--usr/src/uts/sun4/vm/sfmmu.c212
-rw-r--r--usr/src/uts/sun4/vm/vm_dep.c170
-rw-r--r--usr/src/uts/sun4u/boston/os/boston.c23
-rw-r--r--usr/src/uts/sun4u/cherrystone/os/cherrystone.c18
-rw-r--r--usr/src/uts/sun4u/chicago/os/chicago.c25
-rw-r--r--usr/src/uts/sun4u/cpu/us3_cheetah.c52
-rw-r--r--usr/src/uts/sun4u/daktari/os/daktari.c16
-rw-r--r--usr/src/uts/sun4u/enchilada/os/enchilada.c25
-rw-r--r--usr/src/uts/sun4u/lw8/os/lw8_platmod.c35
-rw-r--r--usr/src/uts/sun4u/ml/mach_locore.s21
-rw-r--r--usr/src/uts/sun4u/opl/os/opl.c8
-rw-r--r--usr/src/uts/sun4u/opl/unix/Makefile30
-rw-r--r--usr/src/uts/sun4u/schumacher/os/schumacher.c25
-rw-r--r--usr/src/uts/sun4u/seattle/os/seattle.c24
-rw-r--r--usr/src/uts/sun4u/serengeti/os/serengeti.c32
-rw-r--r--usr/src/uts/sun4u/serengeti/unix/Makefile28
-rw-r--r--usr/src/uts/sun4u/starcat/os/starcat.c8
-rw-r--r--usr/src/uts/sun4u/starcat/unix/Makefile28
-rw-r--r--usr/src/uts/sun4u/starfire/unix/Makefile28
-rw-r--r--usr/src/uts/sun4u/sys/machparam.h20
-rw-r--r--usr/src/uts/sun4u/sys/machsystm.h16
-rw-r--r--usr/src/uts/sun4u/sys/prom_plat.h10
-rw-r--r--usr/src/uts/sun4u/sys/traptrace.h15
-rw-r--r--usr/src/uts/sun4u/unix/Makefile32
-rw-r--r--usr/src/uts/sun4v/Makefile.files1
-rw-r--r--usr/src/uts/sun4v/ml/mach_locore.s20
-rw-r--r--usr/src/uts/sun4v/os/mpo.c8
-rw-r--r--usr/src/uts/sun4v/sys/machparam.h20
-rw-r--r--usr/src/uts/sun4v/sys/machsystm.h16
-rw-r--r--usr/src/uts/sun4v/sys/prom_plat.h10
-rw-r--r--usr/src/uts/sun4v/sys/traptrace.h21
-rw-r--r--usr/src/uts/sun4v/unix/Makefile29
-rw-r--r--usr/src/uts/sun4v/vm/mach_vm_dep.c5
246 files changed, 11400 insertions, 4627 deletions
diff --git a/usr/src/psm/stand/boot/sparc/common/boot.c b/deleted_files/usr/src/psm/stand/boot/sparc/common/boot.c
index acfbad580b..acfbad580b 100644
--- a/usr/src/psm/stand/boot/sparc/common/boot.c
+++ b/deleted_files/usr/src/psm/stand/boot/sparc/common/boot.c
diff --git a/usr/src/psm/stand/boot/sparc/common/boot_services.c b/deleted_files/usr/src/psm/stand/boot/sparc/common/boot_services.c
index 16a7acaebe..16a7acaebe 100644
--- a/usr/src/psm/stand/boot/sparc/common/boot_services.c
+++ b/deleted_files/usr/src/psm/stand/boot/sparc/common/boot_services.c
diff --git a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c b/deleted_files/usr/src/psm/stand/boot/sparc/common/hsfsconf.c
index 2f71220391..2f71220391 100644
--- a/usr/src/psm/stand/boot/sparc/common/hsfsconf.c
+++ b/deleted_files/usr/src/psm/stand/boot/sparc/common/hsfsconf.c
diff --git a/usr/src/psm/stand/boot/sparc/common/ufsconf.c b/deleted_files/usr/src/psm/stand/boot/sparc/common/ufsconf.c
index 5d0195e5f3..5d0195e5f3 100644
--- a/usr/src/psm/stand/boot/sparc/common/ufsconf.c
+++ b/deleted_files/usr/src/psm/stand/boot/sparc/common/ufsconf.c
diff --git a/usr/src/psm/stand/bootblks/Makefile.obp b/deleted_files/usr/src/psm/stand/bootblks/Makefile.obp
index 4572164d4b..4572164d4b 100644
--- a/usr/src/psm/stand/bootblks/Makefile.obp
+++ b/deleted_files/usr/src/psm/stand/bootblks/Makefile.obp
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com
index 26b9823359..26b9823359 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/Makefile.com
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth
index 3ab085f7ba..3ab085f7ba 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/boot_obp.fth
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c
index 2ff62f6c24..2ff62f6c24 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs.c
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h
index 2b18abe8e7..2b18abe8e7 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_sig.h
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c
index b89892eafd..b89892eafd 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/hsfs_small.c
diff --git a/usr/src/psm/stand/bootblks/hsfs/common/iob.h b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/iob.h
index 844f1152fb..844f1152fb 100644
--- a/usr/src/psm/stand/bootblks/hsfs/common/iob.h
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/common/iob.h
diff --git a/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile b/deleted_files/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile
index 8aa0b74787..8aa0b74787 100644
--- a/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile
+++ b/deleted_files/usr/src/psm/stand/bootblks/hsfs/sparc/unix/Makefile
diff --git a/usr/src/psm/stand/bootblks/obp-c/Makefile.rules b/deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.rules
index b320f564ac..b320f564ac 100644
--- a/usr/src/psm/stand/bootblks/obp-c/Makefile.rules
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.rules
diff --git a/usr/src/psm/stand/bootblks/obp-c/Makefile.targ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.targ
index 5644b688c1..5644b688c1 100644
--- a/usr/src/psm/stand/bootblks/obp-c/Makefile.targ
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/Makefile.targ
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h
index 7a0565e88c..7a0565e88c 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/cbootblk.h
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh
index 4665376d29..4665376d29 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/makevers.sh
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c
index 5f2f058723..5f2f058723 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/mkboot.c
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/romp.h b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/romp.h
index 999564996d..999564996d 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/romp.h
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/romp.h
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/stub.c b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/stub.c
index 13b204597b..13b204597b 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/stub.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/stub.c
diff --git a/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c
index b1399b9ccd..b1399b9ccd 100644
--- a/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/common/unix_devio.c
diff --git a/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile b/deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile
index 5a96e9e689..5a96e9e689 100644
--- a/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/mapfile
diff --git a/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s b/deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s
index e2d36ca37a..e2d36ca37a 100644
--- a/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s
+++ b/deleted_files/usr/src/psm/stand/bootblks/obp-c/sparc/common/obp_srt0.s
diff --git a/usr/src/psm/stand/bootblks/ufs/common/Makefile.com b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/Makefile.com
index b759d5cf8f..b759d5cf8f 100644
--- a/usr/src/psm/stand/bootblks/ufs/common/Makefile.com
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/Makefile.com
diff --git a/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth
index 8d0fe85209..8d0fe85209 100644
--- a/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_1275.fth
diff --git a/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth
index 9714b61f56..9714b61f56 100644
--- a/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/boot_obp.fth
diff --git a/usr/src/psm/stand/bootblks/ufs/common/iob.h b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/iob.h
index 7797839b4a..7797839b4a 100644
--- a/usr/src/psm/stand/bootblks/ufs/common/iob.h
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/iob.h
diff --git a/usr/src/psm/stand/bootblks/ufs/common/ufs.c b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/ufs.c
index 0d1f0f0540..0d1f0f0540 100644
--- a/usr/src/psm/stand/bootblks/ufs/common/ufs.c
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/common/ufs.c
diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile
index e177bae10b..e177bae10b 100644
--- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4c/Makefile
diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile
index abb8f28aec..abb8f28aec 100644
--- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4d/Makefile
diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile
index 5177d46a29..5177d46a29 100644
--- a/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/sun4m/Makefile
diff --git a/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile
index ae83da4aea..ae83da4aea 100644
--- a/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile
+++ b/deleted_files/usr/src/psm/stand/bootblks/ufs/sparc/unix/Makefile
diff --git a/usr/src/uts/sparc/krtld/Makefile b/deleted_files/usr/src/uts/sparc/krtld/Makefile
index e6e2e44b90..e6e2e44b90 100644
--- a/usr/src/uts/sparc/krtld/Makefile
+++ b/deleted_files/usr/src/uts/sparc/krtld/Makefile
diff --git a/usr/src/uts/sparc/krtld/kobj_alloc.c b/deleted_files/usr/src/uts/sparc/krtld/kobj_alloc.c
index ab179e267f..ab179e267f 100644
--- a/usr/src/uts/sparc/krtld/kobj_alloc.c
+++ b/deleted_files/usr/src/uts/sparc/krtld/kobj_alloc.c
diff --git a/usr/src/uts/sparc/krtld/kobj_boot.c b/deleted_files/usr/src/uts/sparc/krtld/kobj_boot.c
index 014e198efd..014e198efd 100644
--- a/usr/src/uts/sparc/krtld/kobj_boot.c
+++ b/deleted_files/usr/src/uts/sparc/krtld/kobj_boot.c
diff --git a/usr/src/uts/sparc/krtld/kobj_crt.s b/deleted_files/usr/src/uts/sparc/krtld/kobj_crt.s
index f1accdb3e2..f1accdb3e2 100644
--- a/usr/src/uts/sparc/krtld/kobj_crt.s
+++ b/deleted_files/usr/src/uts/sparc/krtld/kobj_crt.s
diff --git a/usr/src/Makefile.psm b/usr/src/Makefile.psm
index 4ade958609..79f451df40 100644
--- a/usr/src/Makefile.psm
+++ b/usr/src/Makefile.psm
@@ -139,6 +139,7 @@ USR_PSM_LIB_FS_DIR = $(USR_PSM_LIB_DIR)/fs
USR_PSM_LIB_UFS_DIR = $(USR_PSM_LIB_FS_DIR)/ufs
USR_PSM_LIB_NFS_DIR = $(USR_PSM_LIB_FS_DIR)/nfs
USR_PSM_LIB_HSFS_DIR = $(USR_PSM_LIB_FS_DIR)/hsfs
+USR_PSM_LIB_ZFS_DIR = $(USR_PSM_LIB_FS_DIR)/zfs
USR_PSM_DRV_DIR_32 = $(USR_PSM_MOD_DIR)/drv
USR_PSM_EXEC_DIR_32 = $(USR_PSM_MOD_DIR)/exec
diff --git a/usr/src/Makefile.psm.targ b/usr/src/Makefile.psm.targ
index 4570a118dc..5c23e3ca43 100644
--- a/usr/src/Makefile.psm.targ
+++ b/usr/src/Makefile.psm.targ
@@ -133,7 +133,8 @@ $(USR_PSM_LIB_FS_DIR): $(USR_PSM_LIB_DIR) $(LINKED_LIB_FS_DIRS)
$(USR_PSM_LIB_UFS_DIR) \
$(USR_PSM_LIB_NFS_DIR) \
-$(USR_PSM_LIB_HSFS_DIR): $(USR_PSM_LIB_FS_DIR)
+$(USR_PSM_LIB_HSFS_DIR) \
+$(USR_PSM_LIB_ZFS_DIR): $(USR_PSM_LIB_FS_DIR)
-$(INS.dir.root.bin)
$(USR_PSM_MOD_DIR): $(USR_PSM_DIR)
@@ -173,6 +174,9 @@ $(USR_PSM_LIB_NFS_DIR)/%: % $(USR_PSM_LIB_NFS_DIR)
$(USR_PSM_LIB_HSFS_DIR)/%: % $(USR_PSM_LIB_HSFS_DIR)
$(INS.file)
+$(USR_PSM_LIB_ZFS_DIR)/%: % $(USR_PSM_LIB_ZFS_DIR)
+ $(INS.file)
+
$(USR_PSM_MOD_DIR)/%: % $(USR_PSM_MOD_DIR)
$(INS.file)
diff --git a/usr/src/Targetdirs b/usr/src/Targetdirs
index a281b3ba1a..8ae894cab2 100644
--- a/usr/src/Targetdirs
+++ b/usr/src/Targetdirs
@@ -48,18 +48,18 @@ $(BUILD64) SYMLINKS += $(SYM.ROOT.BIN64) $(SYM.ROOT.SFW64)
TARGETDIRS += $(SYMLINKS)
i386_ROOT.SYS= \
- /boot \
/boot/acpi \
/boot/acpi/tables \
/boot/grub \
/boot/grub/bin \
- /boot/solaris \
- /boot/solaris/bin \
/platform/i86pc
sparc_ROOT.SYS=
ROOT.SYS= \
+ /boot \
+ /boot/solaris \
+ /boot/solaris/bin \
$($(MACH)_ROOT.SYS) \
/dev \
/dev/dsk \
diff --git a/usr/src/cmd/boot/Makefile b/usr/src/cmd/boot/Makefile
index 51b1ebf3d8..31945e80f1 100644
--- a/usr/src/cmd/boot/Makefile
+++ b/usr/src/cmd/boot/Makefile
@@ -25,11 +25,12 @@
#ident "%Z%%M% %I% %E% SMI"
#
-include ../Makefile.cmd
+include $(SRC)/cmd/Makefile.cmd
.PARALLEL:
COMMON_SUBDIRS= \
+ filelist \
scripts \
bootadm
@@ -38,7 +39,8 @@ i386_SUBDIRS= \
mbr \
symdef
-sparc_SUBDIRS=
+sparc_SUBDIRS= \
+ fiocompress
COMMON_LINTSUBDIRS= \
bootadm
@@ -47,7 +49,8 @@ i386_LINTSUBDIRS= \
installgrub \
symdef
-sparc_LINTSUBDIRS=
+sparc_LINTSUBDIRS= \
+ fiocompress
COMMON_MSGSUBDIRS= \
bootadm
@@ -55,7 +58,9 @@ COMMON_MSGSUBDIRS= \
i386_MSGSUBDIRS= \
installgrub
-sparc_MSGSUBDIRS=
+sparc_MSGSUBDIRS= \
+ fiocompress
+
all:= TARGET= all
install:= TARGET= install
diff --git a/usr/src/cmd/boot/Makefile.com b/usr/src/cmd/boot/Makefile.com
index 885a829995..c0a9a0e880 100644
--- a/usr/src/cmd/boot/Makefile.com
+++ b/usr/src/cmd/boot/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,13 +19,13 @@
# 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"
#
-include ../../Makefile.cmd
+include $(SRC)/cmd/Makefile.cmd
CFLAGS += $(CCVERBOSE)
@@ -34,8 +33,18 @@ ROOTBOOT= $(ROOT)/boot
ROOTBOOTSOLARIS= $(ROOTBOOT)/solaris
ROOTBOOTSOLARISBIN= $(ROOTBOOTSOLARIS)/bin
-ROOTBOOTSOLARISBINPROG= $(PROG:%=$(ROOTBOOTSOLARISBIN)/%)
+ROOTBOOTSOLARISBINPROG= $(BOOTPROG:%=$(ROOTBOOTSOLARISBIN)/%)
$(ROOTBOOTSOLARISBINPROG) := OWNER= root
$(ROOTBOOTSOLARISBINPROG) := GROUP= bin
$(ROOTBOOTSOLARISBINPROG) := FILEMODE= 0555
+
+ROOTBOOTSOLARISDATA= $(DATA:%=$(ROOTBOOTSOLARIS)/%)
+
+$(ROOTBOOTSOLARISDATA) := OWNER= root
+$(ROOTBOOTSOLARISDATA) := GROUP= sys
+$(ROOTBOOTSOLARISDATA) := FILEMODE= 0644
+
+ROOTUSRSBINLINKS= $(SBINLINKS:%=$(ROOTUSRSBIN)/%)
+
+ROOTBOOTSOLARISBINLINKS= $(SBINLINKS:%=$(ROOTBOOTSOLARISBIN)/%)
diff --git a/usr/src/cmd/boot/Makefile.targ b/usr/src/cmd/boot/Makefile.targ
index ee78f8af05..f802db2730 100644
--- a/usr/src/cmd/boot/Makefile.targ
+++ b/usr/src/cmd/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.
@@ -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"
@@ -42,4 +41,10 @@ $(ROOTBOOTSOLARIS)/%: %
$(ROOTBOOTSOLARISBIN)/%: %
$(INS.file)
-include ../../Makefile.targ
+$(ROOTUSRSBINLINKS):
+ -$(RM) $@; $(SYMLINK) ../../sbin/$(@F) $@
+
+$(ROOTBOOTSOLARISBINLINKS):
+ $(RM) $@; $(SYMLINK) ../../sbin/$(@F) $@
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/boot/bootadm/Makefile b/usr/src/cmd/boot/bootadm/Makefile
index c077811679..c8ab308730 100644
--- a/usr/src/cmd/boot/bootadm/Makefile
+++ b/usr/src/cmd/boot/bootadm/Makefile
@@ -27,8 +27,6 @@
PROG= bootadm
-i386_DATA= filelist.ramdisk filelist.safe
-
SBINLINKS= $(PROG)
OBJS= bootadm.o bootadm_upgrade.o
@@ -36,12 +34,6 @@ SRCS = $(OBJS:.o=.c)
include ../Makefile.com
-ROOTBOOTSOLARISDATA= $($(MACH)_DATA:%=$(ROOTBOOTSOLARIS)/%)
-ROOTUSRSBINLINKS= $(SBINLINKS:%=$(ROOTUSRSBIN)/%)
-
-$(ROOTBOOTSOLARISDATA) := OWNER = root
-$(ROOTBOOTSOLARISDATA) := GROUP = sys
-$(ROOTBOOTSOLARISDATA) := FILEMODE = 0644
.KEEP_STATE:
@@ -59,10 +51,7 @@ $(PROG): $(OBJS) bootadm.h
$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
$(POST_PROCESS)
-$(ROOTUSRSBINLINKS):
- -$(RM) $@; $(SYMLINK) ../../sbin/$(@F) $@
-
-install: all $(ROOTSBINPROG) $(ROOTBOOTSOLARISDATA) .WAIT $(ROOTUSRSBINLINKS)
+install: all $(ROOTSBINPROG) .WAIT $(ROOTUSRSBINLINKS)
clean:
-$(RM) $(OBJS)
diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c
index 2ebc4e1b1e..ce2e154314 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.c
+++ b/usr/src/cmd/boot/bootadm/bootadm.c
@@ -54,7 +54,8 @@
#include <sys/systeminfo.h>
#include <sys/dktp/fdisk.h>
#include <sys/param.h>
-#if defined(__i386)
+
+#if !defined(_OPB)
#include <sys/ucode.h>
#endif
@@ -108,8 +109,9 @@ typedef struct {
#define BAM_LOCK_FILE "/var/run/bootadm.lock"
#define LOCK_FILE_PERMS (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
-#define CREATE_RAMDISK "/boot/solaris/bin/create_ramdisk"
-#define CREATE_DISKMAP "/boot/solaris/bin/create_diskmap"
+#define CREATE_RAMDISK "boot/solaris/bin/create_ramdisk"
+#define CREATE_DISKMAP "boot/solaris/bin/create_diskmap"
+#define EXTRACT_BOOT_FILELIST "boot/solaris/bin/extract_boot_filelist"
#define GRUBDISK_MAP "/var/run/solaris_grubdisk.map"
#define GRUB_slice "/etc/lu/GRUB_slice"
@@ -201,56 +203,51 @@ static char rootbuf[PATH_MAX] = "/";
static int bam_update_all;
/* function prototypes */
-static void parse_args_internal(int argc, char *argv[]);
-static void parse_args(int argc, char *argv[]);
-static error_t bam_menu(char *subcmd, char *opt, int argc, char *argv[]);
-static error_t bam_archive(char *subcmd, char *opt);
+static void parse_args_internal(int, char *[]);
+static void parse_args(int, char *argv[]);
+static error_t bam_menu(char *, char *, int, char *[]);
+static error_t bam_archive(char *, char *);
-static void bam_print(char *format, ...);
-static void bam_exit(int excode);
+static void bam_print(char *, ...);
+static void bam_exit(int);
static void bam_lock(void);
static void bam_unlock(void);
-static int exec_cmd(char *cmdline, char *output, int64_t osize);
-static error_t read_globals(menu_t *mp, char *menu_path,
- char *globalcmd, int quiet);
-
-static menu_t *menu_read(char *menu_path);
-static error_t menu_write(char *root, menu_t *mp);
-static void linelist_free(line_t *start);
-static void menu_free(menu_t *mp);
-static void line_free(line_t *lp);
-static void filelist_free(filelist_t *flistp);
-static error_t list2file(char *root, char *tmp,
- char *final, line_t *start);
-static error_t list_entry(menu_t *mp, char *menu_path, char *opt);
-static error_t delete_all_entries(menu_t *mp, char *menu_path, char *opt);
-static error_t update_entry(menu_t *mp, char *root, char *opt);
-static error_t update_temp(menu_t *mp, char *root, char *opt);
-
-static error_t update_archive(char *root, char *opt);
-static error_t list_archive(char *root, char *opt);
-static error_t update_all(char *root, char *opt);
-static error_t read_list(char *root, filelist_t *flistp);
-static error_t set_global(menu_t *mp, char *globalcmd, int val);
-static error_t set_option(menu_t *mp, char *globalcmd, char *opt);
-static error_t set_kernel(menu_t *mp, menu_cmd_t optnum, char *path,
- char *buf, size_t bufsize);
-static char *expand_path(const char *partial_path);
-
-static long s_strtol(char *str);
-static int s_fputs(char *str, FILE *fp);
-
-static char *s_strdup(char *str);
+static int exec_cmd(char *, filelist_t *);
+static error_t read_globals(menu_t *, char *, char *, int);
+
+static menu_t *menu_read(char *);
+static error_t menu_write(char *, menu_t *);
+static void linelist_free(line_t *);
+static void menu_free(menu_t *);
+static void line_free(line_t *);
+static void filelist_free(filelist_t *);
+static error_t list2file(char *, char *, char *, line_t *);
+static error_t list_entry(menu_t *, char *, char *);
+static error_t delete_all_entries(menu_t *, char *, char *);
+static error_t update_entry(menu_t *, char *, char *);
+static error_t update_temp(menu_t *, char *, char *);
+
+static error_t update_archive(char *, char *);
+static error_t list_archive(char *, char *);
+static error_t update_all(char *, char *);
+static error_t read_list(char *, filelist_t *);
+static error_t set_global(menu_t *, char *, int);
+static error_t set_option(menu_t *, char *, char *);
+static error_t set_kernel(menu_t *, menu_cmd_t, char *, char *, size_t);
+static char *expand_path(const char *);
+
+static long s_strtol(char *);
+static int s_fputs(char *, FILE *);
+
+static char *s_strdup(char *);
static int is_readonly(char *);
static int is_amd64(void);
+static int is_sun4u(void);
+static int is_sun4v(void);
static void append_to_flist(filelist_t *, char *);
-#if defined(__sparc)
-static void sparc_abort(void);
-#endif
-
-#if defined(__i386)
+#if !defined(_OPB)
static void ucode_install();
#endif
@@ -298,7 +295,7 @@ usage(void)
(void) fprintf(stderr, "\t%s update-archive [-vn] [-R altroot]\n",
prog);
(void) fprintf(stderr, "\t%s list-archive [-R altroot]\n", prog);
-#ifndef __sparc
+#if !defined(_OPB)
/* x86 only */
(void) fprintf(stderr, "\t%s set-menu [-R altroot] key=value\n", prog);
(void) fprintf(stderr, "\t%s list-menu [-R altroot]\n", prog);
@@ -327,21 +324,6 @@ main(int argc, char *argv[])
parse_args(argc, argv);
-#if defined(__sparc)
- /*
- * There are only two valid invocations of bootadm
- * on SPARC:
- *
- * - SPARC diskless server creating boot_archive for i386 clients
- * - archive creation call during reboot of a SPARC system
- *
- * The latter should be a NOP
- */
- if (bam_cmd != BAM_ARCHIVE) {
- sparc_abort();
- }
-#endif
-
switch (bam_cmd) {
case BAM_MENU:
ret = bam_menu(bam_subcmd, bam_opt, bam_argc, bam_argv);
@@ -361,17 +343,6 @@ main(int argc, char *argv[])
return (0);
}
-#if defined(__sparc)
-
-static void
-sparc_abort(void)
-{
- bam_error(NOT_ON_SPARC);
- bam_exit(1);
-}
-
-#endif
-
/*
* Equivalence of public and internal commands:
* update-archive -- -a update
@@ -738,7 +709,7 @@ mount_grub_slice(int *mnted, char **physlice, char **logslice, char **fs_type)
(void) snprintf(cmd, sizeof (cmd), "/sbin/mount -F %s %s %s",
fstype, dev, mntpt);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(MOUNT_FAILED, dev, fstype);
if (rmdir(mntpt) != 0) {
bam_error(RMDIR_FAILED, mntpt, strerror(errno));
@@ -791,7 +762,7 @@ umount_grub_slice(
if (mnted) {
(void) snprintf(cmd, sizeof (cmd), "/sbin/umount %s",
mntpt);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(UMOUNT_FAILED, mntpt);
}
if (rmdir(mntpt) != 0) {
@@ -853,7 +824,7 @@ use_stubboot(void)
*/
(void) snprintf(cmd, sizeof (cmd), "/sbin/mount %s",
STUBBOOT);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(MOUNT_MNTPT_FAILED, STUBBOOT);
return (NULL);
}
@@ -908,6 +879,16 @@ bam_menu(char *subcmd, char *opt, int largc, char *largv[])
struct stat sb;
int mnted; /* set if we did a mount */
error_t (*f)(menu_t *mp, char *menu_path, char *opt);
+ char *rootpath;
+
+ /*
+ * Menu sub-command only applies to GRUB (i.e. x86)
+ */
+ rootpath = (bam_alt_root) ? bam_root : "/";
+ if (!is_grub((const char *)rootpath)) {
+ bam_error(NOT_ON_SPARC);
+ return (BAM_ERROR);
+ }
/*
* Check arguments
@@ -1033,16 +1014,6 @@ bam_archive(
return (BAM_ERROR);
}
-#if defined(__sparc)
- /*
- * A NOP if called on SPARC during reboot
- */
- if (strcmp(subcmd, "update_all") == 0)
- return (BAM_SUCCESS);
- else if (strcmp(subcmd, "update") != 0)
- sparc_abort();
-#endif
-
ret = dboot_or_multiboot(rootbuf);
if (ret != BAM_SUCCESS)
return (ret);
@@ -1060,7 +1031,7 @@ bam_archive(
if (strcmp(subcmd, "update_all") == 0)
bam_update_all = 1;
-#if defined(__i386)
+#if !defined(_OPB)
ucode_install(bam_root);
#endif
@@ -1496,24 +1467,34 @@ check_flags_and_files(char *root)
/*
* If archive is missing, create archive
*/
- (void) snprintf(path, sizeof (path), "%s%s", root,
- DIRECT_BOOT_ARCHIVE_32);
+
+ if (is_sun4u())
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ SUN4U__ARCHIVE);
+ else if (is_sun4v())
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ SUN4V__ARCHIVE);
+ else {
+ if (bam_direct == BAM_DIRECT_DBOOT) {
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_64);
+ if (stat(path, &sb) != 0) {
+ if (bam_verbose && !bam_check)
+ bam_print(UPDATE_ARCH_MISS, path);
+ walk_arg.need_update = 1;
+ return;
+ }
+ }
+ (void) snprintf(path, sizeof (path), "%s%s", root,
+ DIRECT_BOOT_ARCHIVE_32);
+ }
+
if (stat(path, &sb) != 0) {
if (bam_verbose && !bam_check)
bam_print(UPDATE_ARCH_MISS, path);
walk_arg.need_update = 1;
return;
}
- if (bam_direct == BAM_DIRECT_DBOOT) {
- (void) snprintf(path, sizeof (path), "%s%s", root,
- DIRECT_BOOT_ARCHIVE_64);
- if (stat(path, &sb) != 0) {
- if (bam_verbose && !bam_check)
- bam_print(UPDATE_ARCH_MISS, path);
- walk_arg.need_update = 1;
- return;
- }
- }
}
static error_t
@@ -1547,17 +1528,55 @@ read_one_list(char *root, filelist_t *flistp, char *filelist)
static error_t
read_list(char *root, filelist_t *flistp)
{
- int rval;
+ char path[PATH_MAX];
+ char cmd[PATH_MAX];
+ struct stat sb;
+ int n, rval;
flistp->head = flistp->tail = NULL;
/*
- * Read current lists of files - only the first is mandatory
+ * build and check path to extract_boot_filelist.ksh
*/
- rval = read_one_list(root, flistp, BOOT_FILE_LIST);
- if (rval != BAM_SUCCESS)
- return (rval);
- (void) read_one_list(root, flistp, ETC_FILE_LIST);
+ n = snprintf(path, sizeof (path), "%s%s", root, EXTRACT_BOOT_FILELIST);
+ if (n >= sizeof (path)) {
+ bam_error(NO_FLIST);
+ return (BAM_ERROR);
+ }
+
+ /*
+ * If extract_boot_filelist is present, exec it, otherwise read
+ * the filelists directly, for compatibility with older images.
+ */
+ if (stat(path, &sb) == 0) {
+ /*
+ * build arguments to exec extract_boot_filelist.ksh
+ */
+ if (strlen(root) > 1) {
+ n = snprintf(cmd, sizeof (cmd), "%s -R %s /%s /%s",
+ path, root, BOOT_FILE_LIST, ETC_FILE_LIST);
+ } else {
+ n = snprintf(cmd, sizeof (cmd), "%s /%s /%s",
+ path, BOOT_FILE_LIST, ETC_FILE_LIST);
+ }
+ if (n >= sizeof (cmd)) {
+ bam_error(NO_FLIST);
+ return (BAM_ERROR);
+ }
+ if (exec_cmd(cmd, flistp) != 0) {
+ if (bam_debug)
+ bam_error(FLIST_FAIL, path, strerror(errno));
+ return (BAM_ERROR);
+ }
+ } else {
+ /*
+ * Read current lists of files - only the first is mandatory
+ */
+ rval = read_one_list(root, flistp, BOOT_FILE_LIST);
+ if (rval != BAM_SUCCESS)
+ return (rval);
+ (void) read_one_list(root, flistp, ETC_FILE_LIST);
+ }
if (flistp->head == NULL) {
bam_error(NO_FLIST);
@@ -1678,9 +1697,14 @@ walk_list(char *root, filelist_t *flistp)
line_t *lp;
for (lp = flistp->head; lp; lp = lp->next) {
+ /*
+ * Don't follow symlinks. A symlink must refer to
+ * a file that would appear in the archive through
+ * a direct reference. This matches the archive
+ * construction behavior.
+ */
(void) snprintf(path, sizeof (path), "%s%s", root, lp->line);
- /* XXX shouldn't we use FTW_MOUNT ? */
- if (nftw(path, cmpstat, 20, 0) == -1) {
+ if (nftw(path, cmpstat, 20, FTW_PHYS) == -1) {
/*
* Some files may not exist.
* For example: etc/rtc_config on a x86 diskless system
@@ -1849,15 +1873,6 @@ update_required(char *root)
return (0);
}
- /*
- * At this point we need an update - so save new stat data
- * However, if only checking (-n), don't save new stat data.
- */
- if (!bam_check)
- savenew(root);
-
- clear_walk_args();
-
return (1);
}
@@ -1871,7 +1886,7 @@ create_ramdisk(char *root)
/*
* Setup command args for create_ramdisk.ksh
*/
- (void) snprintf(path, sizeof (path), "%s%s", root, CREATE_RAMDISK);
+ (void) snprintf(path, sizeof (path), "%s/%s", root, CREATE_RAMDISK);
if (stat(path, &sb) != 0) {
bam_error(ARCH_EXEC_MISS, path, strerror(errno));
return (BAM_ERROR);
@@ -1887,7 +1902,7 @@ create_ramdisk(char *root)
} else
(void) snprintf(cmdline, len, "%s", path);
- if (exec_cmd(cmdline, NULL, 0) != 0) {
+ if (exec_cmd(cmdline, NULL) != 0) {
bam_error(ARCHIVE_FAIL, cmdline);
free(cmdline);
return (BAM_ERROR);
@@ -1895,22 +1910,10 @@ create_ramdisk(char *root)
free(cmdline);
/*
- * Verify that the archive has been created
+ * The existence of the expected archives used to be
+ * verified here. This check is done in create_ramdisk as
+ * it needs to be in sync with the altroot operated upon.
*/
- (void) snprintf(path, sizeof (path), "%s%s", root,
- DIRECT_BOOT_ARCHIVE_32);
- if (stat(path, &sb) != 0) {
- bam_error(ARCHIVE_NOT_CREATED, path);
- return (BAM_ERROR);
- }
- if (bam_direct == BAM_DIRECT_DBOOT) {
- (void) snprintf(path, sizeof (path), "%s%s", root,
- DIRECT_BOOT_ARCHIVE_64);
- if (stat(path, &sb) != 0) {
- bam_error(ARCHIVE_NOT_CREATED, path);
- return (BAM_ERROR);
- }
- }
return (BAM_SUCCESS);
}
@@ -1986,27 +1989,39 @@ is_ramdisk(char *root)
}
static int
-is_newboot(char *root)
+is_boot_archive(char *root)
{
char path[PATH_MAX];
struct stat sb;
/*
- * We can't boot without MULTI_BOOT
+ * We can't create an archive without the create_ramdisk script
*/
- (void) snprintf(path, sizeof (path), "%s%s", root, MULTI_BOOT);
+ (void) snprintf(path, sizeof (path), "%s/%s", root, CREATE_RAMDISK);
if (stat(path, &sb) == -1) {
if (bam_verbose)
bam_print(FILE_MISS, path);
return (0);
}
+ return (1);
+}
+
+/*
+ * Need to call this for anything that operates on the GRUB menu
+ */
+int
+is_grub(const char *root)
+{
+ char path[PATH_MAX];
+ struct stat sb;
+
/*
- * We can't generate archive without GRUB_DIR
+ * GRUB_DIR is required to modify the menu
*/
(void) snprintf(path, sizeof (path), "%s%s", root, GRUB_DIR);
if (stat(path, &sb) == -1) {
- if (bam_verbose)
+ if (bam_debug)
bam_print(DIR_MISS, path);
return (0);
}
@@ -2045,10 +2060,9 @@ update_archive(char *root, char *opt)
assert(opt == NULL);
/*
- * root must belong to a GRUB boot OS,
- * don't care on sparc except for diskless clients
+ * root must belong to a boot archive based OS,
*/
- if (!is_newboot(root)) {
+ if (!is_boot_archive(root)) {
/*
* Emit message only if not in context of update_all.
* If in update_all, emit only if verbose flag is set.
@@ -2103,6 +2117,14 @@ update_archive(char *root, char *opt)
/* create the ramdisk */
ret = create_ramdisk(root);
}
+
+ /* if the archive is updated, save the new stat data */
+ if (ret == 0 && walk_arg.new_nvlp != NULL) {
+ savenew(root);
+ }
+
+ clear_walk_args();
+
return (ret);
}
@@ -2120,7 +2142,7 @@ update_fdisk(void)
GRUB_fdisk, GRUB_fdisk_target);
bam_print(UPDATING_FDISK);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(FDISK_UPDATE_FAILED);
}
@@ -2178,7 +2200,7 @@ restore_grub_slice(void)
(void) snprintf(cmd, sizeof (cmd), "%s %s %s %s",
INSTALLGRUB, STAGE1, STAGE2, physlice);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(RESTORE_GRUB_FAILED);
umount_grub_slice(mnted, mntpt, physlice, NULL, NULL);
return;
@@ -2194,7 +2216,7 @@ restore_grub_slice(void)
(void) snprintf(cmd, sizeof (cmd), "/bin/cp %s %s",
GRUB_backup_menu, menupath);
- if (exec_cmd(cmd, NULL, 0) != 0) {
+ if (exec_cmd(cmd, NULL) != 0) {
bam_error(RESTORE_MENU_FAILED, menupath);
umount_grub_slice(mnted, mntpt, physlice, NULL, NULL);
return;
@@ -2211,6 +2233,7 @@ update_all(char *root, char *opt)
struct stat sb;
FILE *fp;
char multibt[PATH_MAX];
+ char creatram[PATH_MAX];
error_t ret = BAM_SUCCESS;
int ret1, ret2;
@@ -2239,7 +2262,7 @@ update_all(char *root, char *opt)
}
(void) snprintf(multibt, sizeof (multibt),
"/sbin/mount -F lofs -o nosub / %s", LOFS_PATCH_MNT);
- if (exec_cmd(multibt, NULL, 0) != 0) {
+ if (exec_cmd(multibt, NULL) != 0) {
bam_error(MOUNT_FAILED, LOFS_PATCH_MNT, "lofs");
ret = BAM_ERROR;
}
@@ -2255,7 +2278,7 @@ update_all(char *root, char *opt)
*/
(void) snprintf(multibt, sizeof (multibt),
"/sbin/umount %s", LOFS_PATCH_MNT);
- if (exec_cmd(multibt, NULL, 0) != 0) {
+ if (exec_cmd(multibt, NULL) != 0) {
bam_error(UMOUNT_FAILED, LOFS_PATCH_MNT);
ret = BAM_ERROR;
}
@@ -2292,10 +2315,10 @@ update_all(char *root, char *opt)
if (strcmp(mnt.mnt_mountp, "/") == 0)
continue;
- (void) snprintf(multibt, sizeof (multibt), "%s%s",
- mnt.mnt_mountp, MULTI_BOOT);
+ (void) snprintf(creatram, sizeof (creatram), "%s/%s",
+ mnt.mnt_mountp, CREATE_RAMDISK);
- if (stat(multibt, &sb) == -1)
+ if (stat(creatram, &sb) == -1)
continue;
/*
@@ -3019,7 +3042,7 @@ open_diskmap(char *root)
fp = fopen(GRUBDISK_MAP, "r");
if (fp == NULL) {
(void) snprintf(cmd, sizeof (cmd),
- "%s%s > /dev/null", root, CREATE_DISKMAP);
+ "%s/%s > /dev/null", root, CREATE_DISKMAP);
(void) system(cmd);
fp = fopen(GRUBDISK_MAP, "r");
}
@@ -4341,12 +4364,11 @@ menu_free(menu_t *mp)
* Any other value indicates an error
*/
static int
-exec_cmd(char *cmdline, char *output, int64_t osize)
+exec_cmd(char *cmdline, filelist_t *flistp)
{
char buf[BUFSIZ];
int ret;
FILE *ptr;
- size_t len;
sigset_t set;
void (*disp)(int);
@@ -4407,14 +4429,12 @@ exec_cmd(char *cmdline, char *output, int64_t osize)
* we can safely reap the exit status of the command
* from the value returned by pclose()
*/
- while (fgets(buf, sizeof (buf), ptr) != NULL) {
- /* if (bam_verbose) XXX */
- bam_print(PRINT_NO_NEWLINE, buf);
- if (output && osize > 0) {
- (void) snprintf(output, osize, "%s", buf);
- len = strlen(buf);
- output += len;
- osize -= len;
+ while (s_fgets(buf, sizeof (buf), ptr) != NULL) {
+ if (flistp == NULL) {
+ /* s_fgets strips newlines, so insert them at the end */
+ bam_print(PRINT, buf);
+ } else {
+ append_to_flist(flistp, buf);
}
}
@@ -4551,6 +4571,33 @@ is_amd64(void)
return (amd64);
}
+static int
+is_sun4u(void)
+{
+ static int sun4u = 0;
+ char mbuf[257]; /* from sysinfo(2) manpage */
+
+ if (sysinfo(SI_MACHINE, mbuf, sizeof (mbuf)) > 0 &&
+ strncmp(mbuf, "sun4u", strlen("sun4u")) == 0)
+ sun4u = 1;
+
+ return (sun4u);
+}
+
+static int
+is_sun4v(void)
+{
+ static int sun4v = 0;
+ char mbuf[257]; /* from sysinfo(2) manpage */
+
+ if (sysinfo(SI_MACHINE, mbuf, sizeof (mbuf)) > 0 &&
+ strncmp(mbuf, "sun4v", strlen("sun4v")) == 0)
+ sun4v = 1;
+
+ return (sun4v);
+}
+
+
static void
append_to_flist(filelist_t *flistp, char *s)
{
@@ -4565,7 +4612,7 @@ append_to_flist(filelist_t *flistp, char *s)
flistp->tail = lp;
}
-#if defined(__i386)
+#if !defined(_OPB)
UCODE_VENDORS;
diff --git a/usr/src/cmd/boot/bootadm/bootadm.h b/usr/src/cmd/boot/bootadm/bootadm.h
index 45d99e91ab..3dc4d6d201 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.h
+++ b/usr/src/cmd/boot/bootadm/bootadm.h
@@ -150,6 +150,7 @@ extern char *get_special(char *);
extern char *os_to_grubdisk(char *, int);
extern void update_line(line_t *);
extern int add_boot_entry(menu_t *, char *, char *, char *, char *, char *);
+extern int is_grub(const char *);
#define BAM_MAXLINE 8192
@@ -187,6 +188,8 @@ extern int add_boot_entry(menu_t *, char *, char *, char *, char *, char *);
#define DIRECT_BOOT_FAILSAFE_LINE DIRECT_BOOT_FAILSAFE_KERNEL " -s"
/* Boot archives */
+#define SUN4U__ARCHIVE "/platform/sun4u/boot_archive"
+#define SUN4V__ARCHIVE "/platform/sun4v/boot_archive"
#define DIRECT_BOOT_ARCHIVE "/platform/i86pc/$ISADIR/boot_archive"
#define DIRECT_BOOT_ARCHIVE_32 "/platform/i86pc/boot_archive"
#define DIRECT_BOOT_ARCHIVE_64 "/platform/i86pc/amd64/boot_archive"
diff --git a/usr/src/cmd/boot/bootadm/bootadm_upgrade.c b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c
index 7235caf22a..9614cd2c7a 100644
--- a/usr/src/cmd/boot/bootadm/bootadm_upgrade.c
+++ b/usr/src/cmd/boot/bootadm/bootadm_upgrade.c
@@ -56,6 +56,12 @@ dboot_or_multiboot(const char *root)
multiboot_header_t *mbh;
struct stat sb;
+ if (!is_grub(root)) {
+ /* there is no non dboot sparc new-boot */
+ bam_direct = BAM_DIRECT_DBOOT;
+ return (BAM_SUCCESS);
+ }
+
(void) snprintf(fname, PATH_MAX, "%s/%s", root,
"platform/i86pc/kernel/unix");
fd = open(fname, O_RDONLY);
diff --git a/usr/src/cmd/boot/filelist/Makefile b/usr/src/cmd/boot/filelist/Makefile
new file mode 100644
index 0000000000..5b195ceace
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/Makefile
@@ -0,0 +1,46 @@
+#
+# 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"
+#
+
+SUBDIRS = $(MACH)
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+_msg := TARGET= _msg
+lint := TARGET= lint
+
+.KEEP_STATE:
+
+install: $(SUBDIRS)
+
+all clobber clean lint _msg:
+
+FRC:
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
diff --git a/usr/src/cmd/boot/filelist/Makefile.com b/usr/src/cmd/boot/filelist/Makefile.com
new file mode 100644
index 0000000000..b7d0f1f6aa
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/Makefile.com
@@ -0,0 +1,39 @@
+#
+# 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"
+#
+
+#
+# Common prologue for /boot/solaris filelist generation
+#
+
+#
+# filelists
+#
+DATA= \
+ filelist.ramdisk \
+ filelist.safe
+
+include $(SRC)/cmd/boot/Makefile.com
diff --git a/usr/src/cmd/boot/filelist/Makefile.targ b/usr/src/cmd/boot/filelist/Makefile.targ
new file mode 100644
index 0000000000..1b44feebed
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/Makefile.targ
@@ -0,0 +1,32 @@
+#
+# 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"
+#
+
+#
+# Common epilogue for /boot/solaris filelist generation
+#
+
+include $(SRC)/cmd/boot/Makefile.targ
diff --git a/usr/src/cmd/boot/filelist/i386/Makefile b/usr/src/cmd/boot/filelist/i386/Makefile
new file mode 100644
index 0000000000..e9bf8c5c80
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/i386/Makefile
@@ -0,0 +1,36 @@
+#
+# 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"
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all:
+
+install: $(ROOTBOOTSOLARISDATA)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/boot/bootadm/filelist.ramdisk b/usr/src/cmd/boot/filelist/i386/filelist.ramdisk
index 83f0df6a16..4029f595dc 100644
--- a/usr/src/cmd/boot/bootadm/filelist.ramdisk
+++ b/usr/src/cmd/boot/filelist/i386/filelist.ramdisk
@@ -1,23 +1,22 @@
-etc/rtc_config
-etc/system
-etc/name_to_major
-etc/driver_aliases
-etc/name_to_sysnum
+boot/acpi/tables
+boot/solaris/bootenv.rc
+boot/solaris/devicedb/master
+etc/cluster/nodeid
etc/dacf.conf
-etc/driver_classes
-etc/path_to_inst
-etc/mach
etc/devices/devid_cache
-etc/devices/retire_store
-etc/devices/mdi_scsi_vhci_cache
etc/devices/mdi_ib_cache
-etc/cluster/nodeid
+etc/devices/mdi_scsi_vhci_cache
+etc/devices/retire_store
+etc/driver_aliases
+etc/driver_classes
+etc/mach
+etc/name_to_major
+etc/name_to_sysnum
+etc/path_to_inst
+etc/rtc_config
+etc/system
kernel
-platform/i86pc/biosint
platform/i86pc/kernel
platform/i86xpv/kernel
platform/i86pc/ucode/GenuineIntel
platform/i86pc/ucode/AuthenticAMD
-boot/solaris/bootenv.rc
-boot/solaris/devicedb/master
-boot/acpi/tables
diff --git a/usr/src/cmd/boot/bootadm/filelist.safe b/usr/src/cmd/boot/filelist/i386/filelist.safe
index 7f09ac0da9..7f09ac0da9 100644
--- a/usr/src/cmd/boot/bootadm/filelist.safe
+++ b/usr/src/cmd/boot/filelist/i386/filelist.safe
diff --git a/usr/src/cmd/boot/filelist/sparc/Makefile b/usr/src/cmd/boot/filelist/sparc/Makefile
new file mode 100644
index 0000000000..e9bf8c5c80
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/sparc/Makefile
@@ -0,0 +1,36 @@
+#
+# 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"
+#
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+all:
+
+install: $(ROOTBOOTSOLARISDATA)
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/boot/filelist/sparc/filelist.ramdisk b/usr/src/cmd/boot/filelist/sparc/filelist.ramdisk
new file mode 100644
index 0000000000..aa02810afc
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/sparc/filelist.ramdisk
@@ -0,0 +1,75 @@
+etc/cluster/nodeid
+etc/dacf.conf
+etc/mach
+kernel
+platform/SUNW,A70/kernel
+platform/SUNW,Netra-210
+platform/SUNW,Netra-210/kernel
+platform/SUNW,Netra-240
+platform/SUNW,Netra-240/kernel
+platform/SUNW,Netra-440
+platform/SUNW,Netra-440/kernel
+platform/SUNW,Netra-CP2300/kernel
+platform/SUNW,Netra-CP3010/kernel
+platform/SUNW,Netra-CP3060
+platform/SUNW,Netra-CP3060/kernel
+platform/SUNW,Netra-CP3260
+platform/SUNW,Netra-T12/kernel
+platform/SUNW,Netra-T2000
+platform/SUNW,Netra-T4/kernel
+platform/SUNW,Netra-T5220
+platform/SUNW,SPARC-Enterprise-T1000
+platform/SUNW,SPARC-Enterprise-T2000
+platform/SUNW,SPARC-Enterprise-T5120
+platform/SUNW,SPARC-Enterprise-T5220
+platform/SUNW,SPARC-Enterprise/kernel
+platform/SUNW,Serverblade1/kernel
+platform/SUNW,Sun-Blade-100/kernel
+platform/SUNW,Sun-Blade-1000/kernel
+platform/SUNW,Sun-Blade-1500/kernel
+platform/SUNW,Sun-Blade-2500/kernel
+platform/SUNW,Sun-Blade-T6300
+platform/SUNW,Sun-Blade-T6320
+platform/SUNW,Sun-Fire-15000/kernel
+platform/SUNW,Sun-Fire-280R/kernel
+platform/SUNW,Sun-Fire-480R/kernel
+platform/SUNW,Sun-Fire-880/kernel
+platform/SUNW,Sun-Fire-T1000
+platform/SUNW,Sun-Fire-T200
+platform/SUNW,Sun-Fire-T200/kernel
+platform/SUNW,Sun-Fire-V210
+platform/SUNW,Sun-Fire-V210/kernel
+platform/SUNW,Sun-Fire-V215/kernel
+platform/SUNW,Sun-Fire-V240/kernel
+platform/SUNW,Sun-Fire-V245
+platform/SUNW,Sun-Fire-V245/kernel
+platform/SUNW,Sun-Fire-V250/kernel
+platform/SUNW,Sun-Fire-V440/kernel
+platform/SUNW,Sun-Fire-V445/kernel
+platform/SUNW,Sun-Fire-V490
+platform/SUNW,Sun-Fire-V490/kernel
+platform/SUNW,Sun-Fire-V890
+platform/SUNW,Sun-Fire-V890/kernel
+platform/SUNW,Sun-Fire/kernel
+platform/SUNW,T5140
+platform/SUNW,T5240
+platform/SUNW,T5440
+platform/SUNW,USBRDT-5240
+platform/SUNW,Ultra-2
+platform/SUNW,Ultra-250/kernel
+platform/SUNW,Ultra-30
+platform/SUNW,Ultra-4/kernel
+platform/SUNW,Ultra-5_10/kernel
+platform/SUNW,Ultra-60
+platform/SUNW,Ultra-80/kernel
+platform/SUNW,Ultra-Enterprise-10000/kernel
+platform/SUNW,Ultra-Enterprise/kernel
+platform/SUNW,UltraAX-i2/kernel
+platform/SUNW,UltraSPARC-IIe-NetraCT-40/kernel
+platform/SUNW,UltraSPARC-IIe-NetraCT-60/kernel
+platform/SUNW,UltraSPARC-IIi-Netract/kernel
+platform/TAD,SPARCLE/kernel
+platform/sun4u-opl
+platform/sun4u-us3/kernel
+platform/sun4u/kernel
+platform/sun4v/kernel
diff --git a/usr/src/cmd/boot/filelist/sparc/filelist.safe b/usr/src/cmd/boot/filelist/sparc/filelist.safe
new file mode 100644
index 0000000000..e648976739
--- /dev/null
+++ b/usr/src/cmd/boot/filelist/sparc/filelist.safe
@@ -0,0 +1,14 @@
+etc/cluster/nodeid
+etc/dacf.conf
+etc/devices/devid_cache
+etc/devices/mdi_ib_cache
+etc/devices/mdi_scsi_vhci_cache
+etc/driver_aliases
+etc/driver_classes
+etc/mach
+etc/name_to_major
+etc/name_to_sysnum
+etc/path_to_inst
+etc/rtc_config
+etc/system
+etc/zfs/zpool.cache
diff --git a/usr/src/cmd/boot/fiocompress/Makefile b/usr/src/cmd/boot/fiocompress/Makefile
new file mode 100644
index 0000000000..1595b14bec
--- /dev/null
+++ b/usr/src/cmd/boot/fiocompress/Makefile
@@ -0,0 +1,64 @@
+#
+# 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"
+#
+
+PROG= fiocompress
+
+SBINLINKS= $(PROG)
+
+OBJS= fiocompress.o
+SRCS = $(OBJS:.o=.c)
+
+include ../Makefile.com
+
+.KEEP_STATE:
+
+LDLIBS += -lz
+
+CFLAGS += -I../../../uts/common
+LINTFLAGS += -I../../../uts/common
+
+# definitions for lint
+# until libz is compiled against ON header files (uid/gid)
+LINTFLAGS += -erroff=E_INCONS_ARG_DECL2
+LINTFLAGS += -erroff=E_INCONS_VAL_TYPE_DECL2
+
+all: $(PROG)
+
+$(PROG): $(OBJS)
+ $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+ $(POST_PROCESS)
+
+install: all $(ROOTSBINPROG) .WAIT $(ROOTUSRSBINLINKS)
+
+clean:
+ -$(RM) $(OBJS)
+
+_msg:
+
+lint: lint_SRCS
+
+include ../Makefile.targ
diff --git a/usr/src/cmd/boot/fiocompress/fiocompress.c b/usr/src/cmd/boot/fiocompress/fiocompress.c
new file mode 100644
index 0000000000..cef348b158
--- /dev/null
+++ b/usr/src/cmd/boot/fiocompress/fiocompress.c
@@ -0,0 +1,316 @@
+/*
+ * 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"
+
+/*
+ * fiocompress - a utility to compress files with a filesystem.
+ * Used to build compressed boot archives to reduce memory
+ * requirements for booting.
+ */
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <utility.h>
+#include <zlib.h>
+
+#include <sys/filio.h>
+#include <sys/fs/decomp.h>
+
+#include "message.h"
+
+static void setup_infile(char *);
+static void setup_outfile(char *);
+static void do_comp(size_t);
+static void do_decomp(void);
+
+static caddr_t srcaddr;
+static size_t srclen;
+
+static int dstfd;
+
+static char *srcfile;
+static char *dstfile;
+
+
+int
+main(int argc, char **argv)
+{
+ int compress = 0;
+ int decompress = 0;
+ int doioc = 0;
+ size_t blksize = 8192;
+ char c;
+
+ while ((c = getopt(argc, argv, "mcdb:")) != -1) {
+ switch (c) {
+ case 'm':
+ doioc++;
+ break;
+ case 'c':
+ if (decompress) {
+ (void) fprintf(stderr, OPT_DC_EXCL);
+ exit(-1);
+ }
+ compress = 1;
+ break;
+ case 'd':
+ if (compress) {
+ (void) fprintf(stderr, OPT_DC_EXCL);
+ exit(-1);
+ }
+ decompress = 1;
+ break;
+ case 'b':
+ blksize = atoi(optarg);
+ if (blksize == 0 || (blksize & (blksize-1))) {
+ (void) fprintf(stderr, INVALID_BLKSZ);
+ exit(-1);
+ }
+ break;
+ case '?':
+ (void) fprintf(stderr, UNKNOWN_OPTION, optopt);
+ exit(-1);
+ }
+ }
+ if (argc - optind != 2) {
+ (void) fprintf(stderr, MISS_FILES);
+ exit(-1);
+ }
+
+ setup_infile(argv[optind]);
+ setup_outfile(argv[optind + 1]);
+
+ if (decompress)
+ do_decomp();
+ else {
+ do_comp(blksize);
+ if (doioc) {
+ if (ioctl(dstfd, _FIO_COMPRESSED, 0) == -1) {
+ (void) fprintf(stderr, FIO_COMP_FAIL,
+ dstfile, strerror(errno));
+ exit(-1);
+ }
+ }
+ }
+ return (0);
+}
+
+static void
+setup_infile(char *file)
+{
+ int fd;
+ void *addr;
+ struct stat stbuf;
+
+ srcfile = file;
+
+ fd = open(srcfile, O_RDONLY, 0);
+ if (fd == -1) {
+ (void) fprintf(stderr, CANT_OPEN,
+ srcfile, strerror(errno));
+ exit(-1);
+ }
+
+ if (fstat(fd, &stbuf) == -1) {
+ (void) fprintf(stderr, STAT_FAIL,
+ srcfile, strerror(errno));
+ exit(-1);
+ }
+ srclen = stbuf.st_size;
+
+ addr = mmap(0, srclen, PROT_READ, MAP_SHARED, fd, 0);
+ if (addr == MAP_FAILED) {
+ (void) fprintf(stderr, MMAP_FAIL, srcfile, strerror(errno));
+ exit(-1);
+ }
+ srcaddr = addr;
+}
+
+static void
+setup_outfile(char *file)
+{
+ int fd;
+
+ dstfile = file;
+
+ fd = open(dstfile, O_WRONLY | O_CREAT | O_TRUNC,
+ S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+ if (fd == -1) {
+ (void) fprintf(stderr, OPEN_FAIL, dstfile, strerror(errno));
+ exit(-1);
+ }
+ dstfd = fd;
+}
+
+static void
+do_comp(size_t blksize)
+{
+ struct comphdr *hdr;
+ off_t offset;
+ size_t blks, dstlen, hlen;
+ void *dstbuf;
+ int i;
+
+ blks = ((srclen - 1) / blksize) + 1;
+ hlen = offset = sizeof (struct comphdr) + blks * sizeof (uint64_t);
+ hdr = malloc(hlen);
+ if (hdr == NULL) {
+ (void) fprintf(stderr, HDR_ALLOC, hlen);
+ exit(-1);
+ }
+
+ hdr->ch_magic = CH_MAGIC;
+ hdr->ch_version = CH_VERSION;
+ hdr->ch_algorithm = CH_ALG_ZLIB;
+ hdr->ch_fsize = srclen;
+ hdr->ch_blksize = blksize;
+
+ dstlen = ZMAXBUF(blksize);
+ dstbuf = malloc(dstlen);
+ if (dstbuf == NULL) {
+ (void) fprintf(stderr, BUF_ALLOC, dstlen);
+ exit(-1);
+ }
+
+ if (lseek(dstfd, offset, SEEK_SET) == (off_t)-1) {
+ (void) fprintf(stderr, SEEK_ERR,
+ offset, dstfile, strerror(errno));
+ exit(-1);
+ }
+
+ for (i = 0; i < blks; i++) {
+ ulong_t slen, dlen;
+ int ret;
+
+ hdr->ch_blkmap[i] = offset;
+ slen = MIN(srclen, blksize);
+ dlen = dstlen;
+ ret = compress2(dstbuf, &dlen, (Bytef *)srcaddr, slen, 9);
+ if (ret != Z_OK) {
+ (void) fprintf(stderr, COMP_ERR, srcfile, ret);
+ exit(-1);
+ }
+
+ if (write(dstfd, dstbuf, dlen) != dlen) {
+ (void) fprintf(stderr, WRITE_ERR,
+ dlen, dstfile, strerror(errno));
+ exit(-1);
+ }
+
+ offset += dlen;
+ srclen -= slen;
+ srcaddr += slen;
+ }
+
+ if (lseek(dstfd, 0, SEEK_SET) == (off_t)-1) {
+ (void) fprintf(stderr, SEEK_ERR,
+ 0, dstfile, strerror(errno));
+ exit(-1);
+ }
+
+ if (write(dstfd, hdr, hlen) != hlen) {
+ (void) fprintf(stderr, WRITE_ERR,
+ hlen, dstfile, strerror(errno));
+ exit(-1);
+ }
+}
+
+static void
+do_decomp()
+{
+ struct comphdr *hdr;
+ size_t blks, blksize;
+ void *dstbuf;
+ int i;
+ ulong_t slen, dlen;
+ int ret;
+
+ hdr = (struct comphdr *)(void *)srcaddr;
+ if (hdr->ch_magic != CH_MAGIC) {
+ (void) fprintf(stderr, BAD_MAGIC,
+ srcfile, (uint64_t)hdr->ch_magic, CH_MAGIC);
+ exit(-1);
+ }
+ if (hdr->ch_version != CH_VERSION) {
+ (void) fprintf(stderr, BAD_VERS,
+ srcfile, (uint64_t)hdr->ch_version, CH_VERSION);
+ exit(-1);
+ }
+ if (hdr->ch_algorithm != CH_ALG_ZLIB) {
+ (void) fprintf(stderr, BAD_ALG,
+ srcfile, (uint64_t)hdr->ch_algorithm, CH_ALG_ZLIB);
+ exit(-1);
+ }
+
+ blksize = hdr->ch_blksize;
+ dstbuf = malloc(blksize);
+ if (dstbuf == NULL) {
+ (void) fprintf(stderr, HDR_ALLOC, blksize);
+ exit(-1);
+ }
+
+ blks = (hdr->ch_fsize - 1) / blksize;
+ srcaddr += hdr->ch_blkmap[0];
+ for (i = 0; i < blks; i++) {
+ dlen = blksize;
+ slen = hdr->ch_blkmap[i + 1] - hdr->ch_blkmap[i];
+ ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen);
+ if (ret != Z_OK) {
+ (void) fprintf(stderr, DECOMP_ERR, srcfile, ret);
+ exit(-1);
+ }
+
+ if (dlen != blksize) {
+ (void) fprintf(stderr, CORRUPT, srcfile);
+ exit(-1);
+ }
+ if (write(dstfd, dstbuf, dlen) != dlen) {
+ (void) fprintf(stderr, WRITE_ERR,
+ dlen, dstfile, strerror(errno));
+ exit(-1);
+ }
+ srcaddr += slen;
+ }
+
+ dlen = blksize;
+ slen = hdr->ch_fsize - hdr->ch_blkmap[i];
+ if ((ret = uncompress(dstbuf, &dlen, (Bytef *)srcaddr, slen)) != Z_OK) {
+ (void) fprintf(stderr, DECOMP_ERR, dstfile, ret);
+ exit(-1);
+ }
+
+ if (write(dstfd, dstbuf, dlen) != dlen) {
+ (void) fprintf(stderr, WRITE_ERR,
+ dlen, dstfile, strerror(errno));
+ exit(-1);
+ }
+}
diff --git a/usr/src/cmd/boot/fiocompress/message.h b/usr/src/cmd/boot/fiocompress/message.h
new file mode 100644
index 0000000000..c92407bebd
--- /dev/null
+++ b/usr/src/cmd/boot/fiocompress/message.h
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+
+#ifndef _MESSAGE_H
+#define _MESSAGE_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <libintl.h>
+
+#define OPT_DC_EXCL gettext("fiocompress: -c and -d are exclusive\n")
+#define INVALID_BLKSZ gettext("fiocompress: invalid block size\n")
+#define UNKNOWN_OPTION gettext("fiocompress: unknown option -%c\n")
+#define MISS_FILES gettext("fiocompress: input and output files\
+ must be specified\n")
+#define FIO_COMP_FAIL gettext("fiocompress: FIO_COMPRESSED on %s failed\
+ - %s\n")
+#define CANT_OPEN gettext("fiocompress: cannot open %s - %s\n")
+#define STAT_FAIL gettext("fiocompress: stat of %s failed - %s\n")
+#define MMAP_FAIL gettext("fiocompress: mmapping on %s failed - %s\n")
+#define OPEN_FAIL gettext("fiocompress: open of %s failed - %s\n")
+#define HDR_ALLOC gettext("fiocompress: failed to allocate %d bytes\
+ for header\n")
+#define BUF_ALLOC gettext("fiocompress: failed to allocate %d bytes\
+ for buffer\n")
+#define SEEK_ERR gettext("fiocompress: seek to %ld on %s failed - %s\n")
+#define COMP_ERR gettext("fiocompress: %s - compression error %d\n")
+#define WRITE_ERR gettext("fiocompress: write of %ld bytes on %s failed\
+ - %s\n")
+#define BAD_MAGIC gettext("fiocompress: %s - bad magic (0x%llx/0x%x)\n")
+#define BAD_VERS gettext("fiocompress: %s - bad version (0x%llx/0x%x)\n")
+#define BAD_ALG gettext("fiocompress: %s - bad algorithm\
+ (0x%llx/0x%x)\n")
+#define DECOMP_ERR gettext("fiocompress: %s - decompression error %d\n")
+#define CORRUPT gettext("fiocompress: %s - corrupt file\n")
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MESSAGE_H */
diff --git a/usr/src/cmd/boot/installgrub/Makefile b/usr/src/cmd/boot/installgrub/Makefile
index f59050c1e7..b53a6d1f74 100644
--- a/usr/src/cmd/boot/installgrub/Makefile
+++ b/usr/src/cmd/boot/installgrub/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,8 +18,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"
@@ -36,8 +34,6 @@ SBINLINKS= $(PROG)
include ../Makefile.com
-ROOTUSRSBINLINKS= $(SBINLINKS:%=$(ROOTUSRSBIN)/%)
-
CPPFLAGS += -I$(SRC)/uts/i86pc -I$(SRC)/uts/intel -I$(SRC)/uts/common
LINTFLAGS += \
@@ -59,9 +55,6 @@ $(PROG): $(OBJS)
pcfs.o: $(PCFS_SRC)
$(COMPILE.c) -o $@ $(PCFS_SRC)
-$(ROOTUSRSBINLINKS):
- -$(RM) $@; $(SYMLINK) ../../sbin/$(@F) $@
-
install: all $(ROOTSBINPROG) .WAIT $(ROOTUSRSBINLINKS)
clean:
diff --git a/usr/src/cmd/boot/mbr/Makefile b/usr/src/cmd/boot/mbr/Makefile
index 5d80e2f517..510257daac 100644
--- a/usr/src/cmd/boot/mbr/Makefile
+++ b/usr/src/cmd/boot/mbr/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,24 +19,28 @@
# 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"
#
-PROG= mbr
+BOOTPROG= mbr
+
+OBJS= $(BOOTPROG).o
+SRCS = $(OBJS:.o=.c)
include ../Makefile.com
.KEEP_STATE:
-all: $(PROG)
+all: $(BOOTPROG)
install: all $(ROOTBOOTSOLARISBINPROG)
clean:
+ -$(RM) $(OBJS)
-lint: lint_PROG
+lint: lint_SRCS
include ../Makefile.targ
diff --git a/usr/src/cmd/boot/scripts/Makefile.com b/usr/src/cmd/boot/scripts/Makefile.com
index b8fe31bc54..59ddadf0a0 100644
--- a/usr/src/cmd/boot/scripts/Makefile.com
+++ b/usr/src/cmd/boot/scripts/Makefile.com
@@ -30,36 +30,41 @@
MANIFEST= boot-archive-update.xml
SVCMETHOD= boot-archive-update
-PROG= create_ramdisk create_diskmap update_grub
-METHODPROG= boot-archive-update
-SBINPROG= root_archive
+sparc_BOOTPROG=
-SBINLINKS= $(SBINPROG)
+i386_BOOTPROG= \
+ create_diskmap \
+ update_grub
-include ../Makefile.com
+COMMON_BOOTPROG= \
+ create_ramdisk \
+ extract_boot_filelist
-ROOTSBINPROG= $(SBINPROG:%=$(ROOTUSRSBIN)/%)
+
+BOOTPROG= $(COMMON_BOOTPROG) $($(MACH)_BOOTPROG)
+METHODPROG= boot-archive-update
+PROG= root_archive
+
+include ../Makefile.com
ROOTMANIFESTDIR= $(ROOTSVCSYSTEM)
$(ROOTMANIFEST) := FILEMODE= 444
-ROOTBOOTSOLARISBINLINKS= $(SBINLINKS:%=$(ROOTBOOTSOLARISBIN)/%)
+ROOTBOOTSOLARISUSRSBINLINKS= $(PROG:%=$(ROOTBOOTSOLARISBIN)/%)
.KEEP_STATE:
-all: $(PROG) $(METHODPROG) $(SBINPROG)
-
-$(ROOTBOOTSOLARISBINLINKS):
- -$(RM) $@; $(SYMLINK) ../../../usr/sbin/$(@F) $@
+all: $(BOOTPROG) $(METHODPROG) $(PROG)
check: $(CHKMANIFEST)
clean:
- $(RM) $(PROG) $(METHODPROG) $(SBINPROG)
+ $(RM) $(BOOTPROG) $(METHODPROG) $(PROG)
- _msg:
+lint _msg:
-lint:
+$(ROOTBOOTSOLARISUSRSBINLINKS):
+ $(RM) $@; $(SYMLINK) ../../../usr/sbin/$(@F) $@
# Default rule for building ksh scripts.
.ksh:
diff --git a/usr/src/cmd/boot/scripts/Makefile.i386 b/usr/src/cmd/boot/scripts/Makefile.i386
index 25f0533800..7fac1f59fd 100644
--- a/usr/src/cmd/boot/scripts/Makefile.i386
+++ b/usr/src/cmd/boot/scripts/Makefile.i386
@@ -18,8 +18,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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,5 +28,9 @@ include Makefile.com
.KEEP_STATE:
-install: all $(ROOTBOOTSOLARISBINPROG) $(ROOTMANIFEST) $(ROOTSVCMETHOD) \
- $(ROOTSBINPROG) .WAIT $(ROOTBOOTSOLARISBINLINKS)
+install: all \
+ $(ROOTBOOTSOLARISBINPROG) \
+ $(ROOTMANIFEST) \
+ $(ROOTSVCMETHOD) \
+ $(ROOTUSRSBINPROG) .WAIT \
+ $(ROOTBOOTSOLARISUSRSBINLINKS)
diff --git a/usr/src/cmd/boot/scripts/Makefile.sparc b/usr/src/cmd/boot/scripts/Makefile.sparc
index e70274cd36..8816f19096 100644
--- a/usr/src/cmd/boot/scripts/Makefile.sparc
+++ b/usr/src/cmd/boot/scripts/Makefile.sparc
@@ -18,8 +18,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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -29,4 +28,11 @@ include Makefile.com
.KEEP_STATE:
-install: all $(ROOTSBINPROG) .WAIT
+install: all \
+ $(ROOTBOOTSOLARISBINPROG) \
+ $(ROOTMANIFEST) \
+ $(ROOTSVCMETHOD) \
+ $(ROOTUSRSBINPROG)
+
+# .WAIT \
+# $(ROOTBOOTSOLARISUSRSBINLINKS)
diff --git a/usr/src/cmd/boot/scripts/boot-archive-update.ksh b/usr/src/cmd/boot/scripts/boot-archive-update.ksh
index 57746dcb83..4db6b72478 100644
--- a/usr/src/cmd/boot/scripts/boot-archive-update.ksh
+++ b/usr/src/cmd/boot/scripts/boot-archive-update.ksh
@@ -20,7 +20,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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -32,17 +32,14 @@ UPDATEFILE=/etc/svc/volatile/boot_archive_needs_update
smf_is_globalzone || exit $SMF_EXIT_OK
-# no boot-archive on sparc...yet
-#
-if [ `uname -p` = "sparc" ]; then
- exit $SMF_EXIT_OK
-fi
-
-# get rid of transient reboot entry in GRUB menu
-if [ -f /stubboot/boot/grub/menu.lst ]; then
- /sbin/bootadm -m update_temp -R /stubboot
-else
- /sbin/bootadm -m update_temp
+# on x86 get rid of transient reboot entry in the GRUB menu
+#
+if [ `uname -p` = "i386" ]; then
+ if [ -f /stubboot/boot/grub/menu.lst ]; then
+ /sbin/bootadm -m update_temp -R /stubboot
+ else
+ /sbin/bootadm -m update_temp
+ fi
fi
if [ -f $UPDATEFILE ] || [ -f /reconfigure ]; then
diff --git a/usr/src/cmd/boot/scripts/create_ramdisk.ksh b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
index f983ccc094..1c3d2b2d62 100644
--- a/usr/src/cmd/boot/scripts/create_ramdisk.ksh
+++ b/usr/src/cmd/boot/scripts/create_ramdisk.ksh
@@ -27,16 +27,34 @@
format=ufs
ALT_ROOT=
+ALTROOT_ARG=
compress=yes
SPLIT=unknown
ERROR=0
dirsize32=0
dirsize64=0
-BOOT_ARCHIVE=platform/i86pc/boot_archive
-BOOT_ARCHIVE_64=platform/i86pc/amd64/boot_archive
+PLAT=`uname -m`
+if [ $PLAT = i86pc ] ; then
+ ARCH64=amd64
+else
+ ARCH64=sparcv9
+fi
+BOOT_ARCHIVE=platform/$PLAT/boot_archive
+BOOT_ARCHIVE_64=platform/$PLAT/$ARCH64/boot_archive
+
+#
+# set path, but inherit /tmp/bfubin if owned by
+# same uid executing this process, which must be root.
+#
+if [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
+ [ -O /tmp/bfubin ] ; then
+ export PATH=/tmp/bfubin:/usr/sbin:/usr/bin:/sbin
+else
+ export PATH=/usr/sbin:/usr/bin:/sbin
+fi
-export PATH=$PATH:/usr/sbin:/usr/bin:/sbin
+EXTRACT_FILELIST="/boot/solaris/bin/extract_boot_filelist"
#
# Parse options
@@ -48,6 +66,8 @@ do
ALT_ROOT="$1"
if [ "$ALT_ROOT" != "/" ]; then
echo "Creating ram disk for $ALT_ROOT"
+ ALTROOT_ARG="-R $ALT_ROOT"
+ EXTRACT_FILELIST="${ALT_ROOT}${EXTRACT_FILELIST}"
fi
;;
-n|--nocompress) compress=no
@@ -79,19 +99,24 @@ if [ $# -eq 1 ]; then
echo "Creating ram disk for $ALT_ROOT"
fi
-rundir=`dirname $0`
-if [ ! -x "$rundir"/symdef ]; then
- # Shouldn't happen
- echo "Warning: $rundir/symdef not present."
- echo "Creating single archive at $ALT_ROOT/platform/i86pc/boot_archive"
- SPLIT=no
- compress=no
-elif "$rundir"/symdef "$ALT_ROOT"/platform/i86pc/kernel/unix \
- dboot_image 2>/dev/null; then
- SPLIT=yes
-else
- SPLIT=no
- compress=no
+if [ $PLAT = i86pc ] ; then
+ rundir=`dirname $0`
+ if [ ! -x "$rundir"/symdef ]; then
+ # Shouldn't happen
+ echo "Warning: $rundir/symdef not present."
+ echo "Creating single archive at $ALT_ROOT/$BOOT_ARCHIVE"
+ SPLIT=no
+ compress=no
+ elif "$rundir"/symdef "$ALT_ROOT"/platform/i86pc/kernel/unix \
+ dboot_image 2>/dev/null; then
+ SPLIT=yes
+ else
+ SPLIT=no
+ compress=no
+ fi
+else # must be sparc
+ SPLIT=no # there's only 64-bit (sparcv9), so don't split
+ compress=no
fi
[ -x /usr/bin/gzip ] || compress=no
@@ -119,15 +144,19 @@ function getsize
# next multiple of 1024. This mimics the behavior of ufs especially
# with directories. This results in a total size that's slightly
# bigger than if du was called on a ufs directory.
- size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" | nawk '
- {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
+ size32=$(cat "$list32" | xargs -I {} ls -lLd "{}" 2> /dev/null |
+ nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
END {print int(t * 1.10 / 1024)}')
(( size32 += dirsize32 ))
- size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" | nawk '
- {t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
+ size64=$(cat "$list64" | xargs -I {} ls -lLd "{}" 2> /dev/null |
+ nawk '{t += ($5 % 1024) ? (int($5 / 1024) + 1) * 1024 : $5}
END {print int(t * 1.10 / 1024)}')
(( size64 += dirsize64 ))
(( total_size = size32 + size64 ))
+
+ if [ $compress = yes ] ; then
+ total_size=`echo $total_size | nawk '{print int($1 / 2)}'`
+ fi
}
#
@@ -161,6 +190,18 @@ function copy_files
print "$path"
fi
done <"$list" | cpio -pdum "$rdmnt" 2>/dev/null
+
+ if [ `uname -p` = sparc ] ; then
+ # copy links
+ find $filelist -type l -print 2>/dev/null |\
+ cpio -pdum "$rdmnt" 2>/dev/null
+ if [ $compress = yes ] ; then
+ # always copy unix uncompressed
+ find $filelist -name unix -type f -print 2>/dev/null |\
+ cpio -pdum "$rdmnt" 2>/dev/null
+ fi
+ fi
+
}
#
@@ -202,6 +243,12 @@ function create_ufs
umount "$rdmnt"
rmdir "$rdmnt"
+ if [ `uname -p` = sparc ] ; then
+ rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
+ bb="$ALT_ROOT/usr/platform/`uname -i`/lib/fs/ufs/bootblk"
+ installboot "$bb" $rlofidev
+ fi
+
#
# Check if gzip exists in /usr/bin, so we only try to run gzip
# on systems that have gzip. Then run gzip out of the patch to
@@ -211,7 +258,8 @@ function create_ufs
# compressed, and the final compression will accomplish very
# little. To save time, we skip the gzip in this case.
#
- if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then
+ if [ `uname -p` = i386 ] && [ $compress = no ] && \
+ [ -x /usr/bin/gzip ] ; then
gzip -c "$rdfile" > "${archive}-new"
else
cat "$rdfile" > "${archive}-new"
@@ -250,6 +298,11 @@ function create_isofs
files=
isocmd="mkisofs -quiet -graft-points -dlrDJN -relaxed-filenames"
+ if [ `uname -p` = sparc ] ; then
+ bb="$ALT_ROOT/usr/platform/`uname -i`/lib/fs/hsfs/bootblk"
+ isocmd="$isocmd -G \"$bb\""
+ fi
+
copy_files "$list"
isocmd="$isocmd \"$rdmnt\""
rm -f "$errlog"
@@ -263,13 +316,22 @@ function create_isofs
# compressed, and the final compression will accomplish very
# little. To save time, we skip the gzip in this case.
#
- if [ $compress = no ] && [ -x /usr/bin/gzip ] ; then
+ if [ `uname -p` = i386 ] &&[ $compress = no ] && [ -x /usr/bin/gzip ]
+ then
ksh -c "$isocmd" 2> "$errlog" | \
gzip > "${archive}-new"
else
ksh -c "$isocmd" 2> "$errlog" > "${archive}-new"
fi
+ if [ `uname -p` = sparc ] ; then
+ bb="$ALT_ROOT/usr/platform/`uname -i`/lib/fs/hsfs/bootblk"
+ lofidev=`lofiadm -a "${archive}-new"`
+ rlofidev=`echo "$lofidev" | sed -e "s/dev\/lofi/dev\/rlofi/"`
+ installboot "$bb" "$rlofidev"
+ lofiadm -d "$lofidev"
+ fi
+
if [ -s "$errlog" ]; then
grep Error: "$errlog" >/dev/null 2>&1
if [ $? -eq 0 ]; then
@@ -286,7 +348,7 @@ function create_archive
archive=$2
lofidev=$3
- echo "updating $archive...this may take a minute"
+ echo "updating $archive"
if [ "$format" = "ufs" ]; then
create_ufs "$which" "$archive" "$lofidev"
@@ -297,8 +359,7 @@ function create_archive
# sanity check the archive before moving it into place
#
ARCHIVE_SIZE=`ls -l "${archive}-new" | nawk '{ print $5 }'`
- if [ $compress = yes ]
- then
+ if [ $compress = yes ] || [ `uname -p` = sparc ] ; then
#
# 'file' will report "English text" for uncompressed
# boot_archives. Checking for that doesn't seem stable,
@@ -345,8 +406,8 @@ then
print -u2 "Can't find filelist.ramdisk"
exit 1
fi
-filelist=$(cat "$ALT_ROOT/boot/solaris/filelist.ramdisk" \
- "$ALT_ROOT/etc/boot/solaris/filelist.ramdisk" 2>/dev/null | sort -u)
+filelist=$($EXTRACT_FILELIST $ALTROOT_ARG /boot/solaris/filelist.ramdisk \
+ /etc/boot/solaris/filelist.ramdisk 2>/dev/null | sort -u)
#
# We use /tmp/ for scratch space now. This may be changed later if there
@@ -363,6 +424,8 @@ trap 'cleanup' EXIT
list32="$rddir/filelist.32"
list64="$rddir/filelist.64"
+touch $list32 $list64
+
#
# This loop creates the 32-bit and 64-bit lists of files. The 32-bit list
# is written to stdout, which is redirected at the end of the loop. The
diff --git a/usr/src/cmd/boot/scripts/extract_boot_filelist.ksh b/usr/src/cmd/boot/scripts/extract_boot_filelist.ksh
new file mode 100644
index 0000000000..a41d9bcf70
--- /dev/null
+++ b/usr/src/cmd/boot/scripts/extract_boot_filelist.ksh
@@ -0,0 +1,92 @@
+#!/bin/ksh -p
+#
+# 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"
+
+#
+# set path, but inherit /tmp/bfubin if it is sane
+#
+if [ "`echo $PATH | cut -f 1 -d :`" = /tmp/bfubin ] && \
+ [ -O /tmp/bfubin ] ; then
+ export PATH=/tmp/bfubin:/usr/sbin:/usr/bin:/sbin
+else
+ export PATH=/usr/sbin:/usr/bin:/sbin
+fi
+
+usage() {
+ echo "Usage: ${0##*/}: [-R \<root\>] <filelist> ..."
+ exit 2
+}
+
+altroot=""
+filelists=
+while getopts R FLAG
+do
+ case $FLAG in
+ R) shift
+ if [ "$1" != "/" ]; then
+ altroot="$1"
+ fi
+ ;;
+ *) usage
+ ;;
+ esac
+ shift
+done
+
+if [ $# -eq 0 ]; then
+ usage
+fi
+
+filelists=$*
+
+filtering=no
+if [ "$altroot" == "" ]; then
+ case `uname -m` in
+ i86pc)
+ filtering=no
+ ;;
+ sun4u)
+ filtering=yes
+ exclude_pattern="sun4v"
+ ;;
+ sun4v)
+ filtering=yes
+ exclude_pattern="sun4u"
+ ;;
+ esac
+fi
+
+for list in $filelists
+do
+ if [ -f $altroot/$list ]; then
+ if [ $filtering = yes ]; then
+ cat $altroot/$list | grep -v $exclude_pattern
+ else
+ cat $altroot/$list
+ fi
+ fi
+done
+
+exit 0
diff --git a/usr/src/cmd/boot/scripts/root_archive.ksh b/usr/src/cmd/boot/scripts/root_archive.ksh
index 8eacfd5484..215a2ae849 100644
--- a/usr/src/cmd/boot/scripts/root_archive.ksh
+++ b/usr/src/cmd/boot/scripts/root_archive.ksh
@@ -20,7 +20,7 @@
# CDDL HEADER END
#
-# Copyright 2007 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"
@@ -41,10 +41,10 @@
# Solaris media and all the things that don't go into the ramdisk image
# are (un)cpio'd as well
#
-# This utility is also used to pack parts (in essence the window system,
-# usr/dt and usr/openwin) of the non ramdisk SPARC
-# miniroot. (un)packmedia will recognize that they are being run a SPARC
-# miniroot and do the appropriate work.
+# This utility is also used to pack parts (in essence the window system,
+# usr/dt and usr/openwin) of the non ramdisk SPARC
+# miniroot. (un)packmedia will recognize that they are being run a SPARC
+# miniroot and do the appropriate work.
#
usage()
@@ -63,7 +63,10 @@ cleanup()
fi
lofiadm -d "$TMR" 2>/dev/null
- rm -f "$TMR" "$TMR.gz"
+ if [ "$REALTHING" != true ] ; then
+ rm -f "$TMR"
+ fi
+ rm -f "$TMR.gz"
}
archive_Gnome()
@@ -74,12 +77,7 @@ archive_Gnome()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- mkdir -p "$CPIO_DIR"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# Create the gnome archive
@@ -98,11 +96,13 @@ archive_Gnome()
HOME="./tmp/root"
export HOME
umask 0022
- GCONF_CONFIG_SOURCE="xml:merged:"$MINIROOT"/.tmp_proto/root/etc/gconf/gconf.xml.defaults"
+ mumble=.tmp_proto/root/etc/gconf/gconf.xml.defaults
+ GCONF_CONFIG_SOURCE="xml:merged:$MINIROOT/$mumble"
export GCONF_CONFIG_SOURCE
SCHEMADIR="$MINIROOT/.tmp_proto/root/etc/gconf/schemas"
export SCHEMADIR
- /usr/bin/gconftool-2 --makefile-install-rule $SCHEMADIR/*.schemas >/dev/null 2>&1
+ /usr/bin/gconftool-2 --makefile-install-rule \
+ $SCHEMADIR/*.schemas >/dev/null 2>&1
echo '
xml:readwrite:/tmp/root/.gconf
xml:readonly:/etc/gconf/gconf.xml.defaults
@@ -124,7 +124,7 @@ archive_Gnome()
if [ ! -f /tmp/gnome_share.$$ ] ; then
echo "/tmp/gnome_share.$$ file list not found."
- return
+ return
fi
# usr/lib gnome stuff
@@ -191,7 +191,7 @@ archive_Gnome()
if [ ! -f /tmp/gnome_bin.$$ ] ; then
echo "/tmp/gnome_bin.$$ file list not found."
- return
+ return
fi
# Cat all the files together and create the gnome archive
@@ -221,13 +221,13 @@ archive_Gnome()
cpio -ocmPuB < /tmp/gnome.$$ 2>/dev/null | bzip2 > \
"$CPIO_DIR/gnome.cpio.bz2"
- # Remove files from miniroot that are in archive.
+ # Remove files from miniroot that are in archive.
# Create symlinks for files in archive
rm -rf `cat /tmp/gnome_share.$$`
for i in `cat /tmp/gnome_share.$$`
- do
+ do
ln -s /tmp/root/$i $i 2>/dev/null
done
@@ -239,19 +239,19 @@ archive_Gnome()
rm -rf `cat /tmp/gnome_libdir.$$`
for i in `cat /tmp/gnome_libdir.$$`
- do
+ do
ln -s /tmp/root/$i $i 2>/dev/null
done
rm -rf `cat /tmp/gnome_sfw.$$`
for i in `cat /tmp/gnome_sfw.$$`
- do
+ do
ln -s /tmp/root/$i $i 2>/dev/null
done
rm -rf `cat /tmp/gnome_bin.$$`
for i in `cat /tmp/gnome_bin.$$`
- do
+ do
ln -s /tmp/root/$i $i 2>/dev/null
done
rm -f /tmp/gnome_share.$$
@@ -269,12 +269,7 @@ archive_JavaGUI()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- mkdir -p "$CPIO_DIR"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# Archive the java wizard components that are only used in the
# non developer express path.
@@ -287,14 +282,15 @@ archive_JavaGUI()
if [ ! -f /tmp/java_ui.$$ ] ; then
echo "/tmp/java_ui.$$ file list not found."
- return
+ return
fi
cpio -ocmPuB < /tmp/java_ui.$$ 2>/dev/null | bzip2 > \
"$CPIO_DIR/javaui.cpio.bz2"
rm -rf `cat /tmp/java_ui.$$`
- ln -s /tmp/root/usr/lib/install/data/wizards usr/lib/install/data/wizards 2>/dev/null
+ ln -s /tmp/root/usr/lib/install/data/wizards \
+ usr/lib/install/data/wizards 2>/dev/null
rm -f /tmp/java_ui.$$
@@ -309,12 +305,7 @@ archive_Misc()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- mkdir -p "$CPIO_DIR"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# Archive misc stuff that is needed by non devex installer
#
@@ -324,7 +315,7 @@ archive_Misc()
find usr/lib/lp -print > /tmp/lp.$$ 2>/dev/null
if [ ! -f /tmp/lp.$$ ] ; then
echo "/tmp/lp.$$ file list not found."
- return
+ return
fi
cpio -ocmPuB < /tmp/lp.$$ 2>/dev/null | bzip2 > \
@@ -346,12 +337,7 @@ archive_Perl()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- mkdir -p "$CPIO_DIR"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# Archive perl, it is only needed by gnome gui.
#
@@ -362,7 +348,7 @@ archive_Perl()
if [ ! -f /tmp/perl.$$ ] ; then
echo "/tmp/perl.$$ file list not found."
- return
+ return
fi
cpio -ocmPuB < /tmp/perl.$$ 2>/dev/null | bzip2 > \
"$CPIO_DIR/perl.cpio.bz2"
@@ -381,12 +367,7 @@ archive_X()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- mkdir -p "$CPIO_DIR"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# create the graphics and non-graphics X archive
#
@@ -409,6 +390,24 @@ archive_X()
)
}
+archive_lu()
+{
+ MEDIA="$1"
+ MINIROOT="$2"
+
+ RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
+ RELEASE=`basename "$RELEASE"`
+
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
+
+ (
+ cd "$MINIROOT"
+ find usr/lib/install usr/snadm usr/sbin | \
+ cpio -ocmPuB 2> /dev/null | bzip2 > "$CPIO_DIR"/lu.cpio.bz2
+ ls platform > "$CPIO_DIR/lu.platforms"
+ )
+}
+
packmedia()
{
MEDIA="$1"
@@ -418,11 +417,56 @@ packmedia()
RELEASE=`basename "$RELEASE"`
mkdir -p "$MEDIA/$RELEASE/Tools/Boot"
- mkdir -p "$MEDIA/boot/amd64"
- mkdir -p "$MEDIA/boot/platform/i86pc/kernel"
- mkdir -p "$MEDIA/boot/platform/i86pc/kernel/amd64"
- mkdir -p "$MEDIA/boot/platform/i86xpv/kernel"
- mkdir -p "$MEDIA/boot/platform/i86xpv/kernel/amd64"
+
+ if [ -d "$MINIROOT/platform/i86pc" ] ; then
+ mkdir -p "$MEDIA/boot/amd64"
+ mkdir -p "$MEDIA/boot/platform/i86pc/kernel"
+ mkdir -p "$MEDIA/boot/platform/i86pc/kernel/amd64"
+ mkdir -p "$MEDIA/boot/platform/i86xpv/kernel"
+ mkdir -p "$MEDIA/boot/platform/i86xpv/kernel/amd64"
+ cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
+ cp "$MINIROOT/platform/i86pc/kernel/unix" \
+ "$MEDIA/boot/platform/i86pc/kernel/unix"
+ cp "$MINIROOT/platform/i86pc/kernel/amd64/unix" \
+ "$MEDIA/boot/platform/i86pc/kernel/amd64/unix"
+ cp "$MINIROOT/platform/i86xpv/kernel/unix" \
+ "$MEDIA/boot/platform/i86xpv/kernel/unix"
+ cp "$MINIROOT/platform/i86xpv/kernel/amd64/unix" \
+ "$MEDIA/boot/platform/i86xpv/kernel/amd64/unix"
+ (
+ cd "$MEDIA/$RELEASE/Tools/Boot"
+ ln -sf ../../../boot/x86.miniroot
+ ln -sf ../../../boot/multiboot
+ ln -sf ../../../boot/platform/i86pc/kernel/unix
+ ln -sf ../../../boot/platform/i86pc/kernel/amd64/unix
+ ln -sf ../../../boot/platform/i86xpv/kernel/unix
+ ln -sf ../../../boot/platform/i86xpv/kernel/amd64/unix
+ ln -sf ../../../boot/grub/pxegrub
+ )
+ fi
+
+ if [ -d "$MINIROOT/platform/sun4u" ] ; then
+ mkdir -p "$MEDIA/boot"
+ dd if="$MINIROOT/usr/platform/sun4u/lib/fs/hsfs/bootblk" \
+ of="$MEDIA/boot/hsfs.bootblock" \
+ bs=1b oseek=1 count=15 conv=sync 2> /dev/null
+ fi
+
+ for arch in sun4u sun4v ; do
+ if [ -d "$MINIROOT/platform/$arch" ] ; then
+ archdir="$MEDIA/$RELEASE/Tools/Boot/platform/$arch"
+ mkdir -p $archdir
+ ln -sf ../../../../../boot/sparc.miniroot \
+ "$archdir/boot_archive"
+ cp "$MINIROOT/usr/platform/$arch/lib/fs/nfs/inetboot" \
+ "$archdir"
+ cp "$MINIROOT/platform/$arch/wanboot" \
+ "$archdir"
+ mkdir -p "$MEDIA/platform/$arch"
+ ln -sf ../../boot/sparc.miniroot \
+ "$MEDIA/platform/$arch/boot_archive"
+ fi
+ done
# archive package databases to conserve memory
#
@@ -432,49 +476,37 @@ packmedia()
cpio -ocmPuB 2> /dev/null | bzip2 > \
"$MEDIA/$RELEASE/Tools/Boot/pkg_db.cpio.bz2"
)
-
rm -rf "$MINIROOT/tmp/root/var/sadm/install"
rm -rf "$MINIROOT/tmp/root/var/sadm/pkg"
+ if [ -d "$MINIROOT/kernel/drv/sparcv9" ] ; then
+ archive_lu "$MEDIA" "$MINIROOT"
+ elif [ "$STRIP_AMD64" != false ] ; then
+ # clear out 64 bit support to conserve memory
+ #
+ find "$MINIROOT" -name amd64 -type directory | xargs rm -rf
+ fi
+
archive_X "$MEDIA" "$MINIROOT"
# Take out the gnome and java parts of the installer from
# the miniroot. These are not required to boot the system
# and start the installers.
-
- archive_Gnome "$MEDIA" "$MINIROOT"
- archive_JavaGUI "$MEDIA" "$MINIROOT"
- archive_Perl "$MEDIA" "$MINIROOT"
- archive_Misc "$MEDIA" "$MINIROOT"
-
- cp "$MINIROOT/platform/i86pc/multiboot" "$MEDIA/boot"
- cp "$MINIROOT/platform/i86pc/kernel/unix" \
- "$MEDIA/boot/platform/i86pc/kernel/unix"
- cp "$MINIROOT/platform/i86pc/kernel/amd64/unix" \
- "$MEDIA/boot/platform/i86pc/kernel/amd64/unix"
- cp "$MINIROOT/platform/i86xpv/kernel/unix" \
- "$MEDIA/boot/platform/i86xpv/kernel/unix"
- cp "$MINIROOT/platform/i86xpv/kernel/amd64/unix" \
- "$MEDIA/boot/platform/i86xpv/kernel/amd64/unix"
+
+ if [ -d "$MINIROOT/platform/i86pc" ] ; then
+ archive_Gnome "$MEDIA" "$MINIROOT"
+ archive_JavaGUI "$MEDIA" "$MINIROOT"
+ archive_Misc "$MEDIA" "$MINIROOT"
+ archive_Perl "$MEDIA" "$MINIROOT"
+ fi
# copy the install menu to menu.lst so we have a menu
# on the install media
#
- if [ -f "${MINIROOT}/boot/grub/install_menu" ] ; then
- cp ${MINIROOT}/boot/grub/install_menu \
- ${MEDIA}/boot/grub/menu.lst
+ if [ -f "$MINIROOT/boot/grub/install_menu" ] ; then
+ cp $MINIROOT/boot/grub/install_menu \
+ $MEDIA/boot/grub/menu.lst
fi
-
- (
- cd "$MEDIA/$RELEASE/Tools/Boot"
- ln -sf ../../../boot/x86.miniroot
- ln -sf ../../../boot/platform/i86pc/kernel/unix
- ln -sf ../../../boot/platform/i86pc/kernel/amd64/unix
- ln -sf ../../../boot/platform/i86xpv/kernel/unix
- ln -sf ../../../boot/platform/i86xpv/kernel/amd64/unix
- ln -sf ../../../boot/multiboot
- ln -sf ../../../boot/grub/pxegrub
- )
}
unarchive_X()
@@ -485,11 +517,7 @@ unarchive_X()
RELEASE=`/bin/ls -d "$MEDIA/Solaris_"*`
RELEASE=`basename "$RELEASE"`
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- CPIO_DIR="$MEDIA/$RELEASE/Tools/miniroot_extra"
- else
- CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
- fi
+ CPIO_DIR="$MEDIA/$RELEASE/Tools/Boot"
# unpack X
#
@@ -527,7 +555,7 @@ unpackmedia()
# Gnome list saved off from packmedia
for i in `cat .tmp_proto/gnome_saved`
- do
+ do
rm -rf $i
done
@@ -561,7 +589,12 @@ unpack()
exit 1
fi
- gzcat "$MR" > $TMR
+ if [ `basename $MR` = x86.miniroot ] ; then
+ gzcat "$MR" > $TMR
+ else
+ REALTHING=true ; export REALTHING
+ TMR="$MR"
+ fi
LOFIDEV=`/usr/sbin/lofiadm -a $TMR`
if [ $? != 0 ] ; then
@@ -583,9 +616,64 @@ unpack()
printf "invalid root archive\n"
fi
+
rmdir $MNT
lofiadm -d $TMR ; LOFIDEV=
- rm $TMR
+ if [ "$REALTHING" != true ] ; then
+ rm $TMR
+ fi
+}
+
+compress()
+{
+ SRC=$1
+ DST=$2
+
+ (
+ cd $SRC
+ filelist=`find .`
+
+ for file in $filelist ; do
+
+ file=`echo $file | sed s#^./##`
+
+ # copy all files over to preserve hard links
+ #
+ echo $file | cpio -pdum $DST 2> /dev/null
+
+ if [ -f $file ] && [ -s $file ] && [ ! -h $file ] ; then
+ fiocompress -mc $file $DST/$file &
+ fi
+
+ done
+
+ # now re-copy a couple of uncompressed files
+ #
+
+ find kernel platform -name unix | cpio -pdum $DST 2> /dev/null
+ find kernel platform -name genunix | cpio -pdum $DST \
+ 2> /dev/null
+ find kernel platform -name platmod | cpio -pdum $DST \
+ 2> /dev/null
+ find `find kernel platform -name cpu` | cpio -pdum $DST \
+ 2> /dev/null
+ find `find kernel platform -name kmdb\*` | cpio -pdum $DST \
+ 2> /dev/null
+ find kernel/misc/sparcv9/ctf kernel/fs/sparcv9/dcfs \
+ etc/system etc/name_to_major etc/path_to_inst \
+ etc/name_to_sysnum | cpio -pdum $DST 2> /dev/null
+ )
+}
+
+root_is_ramdisk()
+{
+ grep -v "set root_is_ramdisk=" "$UNPACKED_ROOT"/etc/system | \
+ grep -v "set ramdisk_size=" > /tmp/system.$$
+ cat /tmp/system.$$ > "$UNPACKED_ROOT"/etc/system
+ rm /tmp/system.$$
+
+ echo set root_is_ramdisk=1 >> "$UNPACKED_ROOT"/etc/system
+ echo set ramdisk_size=$1 >> "$UNPACKED_ROOT"/etc/system
}
pack()
@@ -595,10 +683,17 @@ pack()
exit 1
fi
+ # always compress on sparc if fiocompress exists
+ #
+ if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] && \
+ [ -x /usr/sbin/fiocompress ] ; then
+ COMPRESS=true
+ fi
+
# Estimate image size and add %10 overhead for ufs stuff.
# Note, we can't use du here in case $UNPACKED_ROOT is on a filesystem,
# e.g. zfs, in which the disk usage is less than the sum of the file
- # sizes. The nawk code
+ # sizes. The nawk code
#
# {t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
#
@@ -606,9 +701,16 @@ pack()
# next multiple of 1024. This mimics the behavior of ufs especially
# with directories. This results in a total size that's slightly
# bigger than if du was called on a ufs directory.
+ #
+ # if the operation in turn is compressing the files the amount
+ # of typical shrinkage is used to come up with a useful archive
+ # size
size=$(find "$UNPACKED_ROOT" -ls | nawk '
{t += ($7 % 1024) ? (int($7 / 1024) + 1) * 1024 : $7}
END {print int(t * 1.10 / 1024)}')
+ if [ "$COMPRESS" = true ] ; then
+ size=`echo $size | nawk '{s = $1} END {print int(s * .53)}'`
+ fi
/usr/sbin/mkfile ${size}k "$TMR"
@@ -619,23 +721,45 @@ pack()
fi
RLOFIDEV=`echo $LOFIDEV | sed s/lofi/rlofi/`
- newfs $RLOFIDEV < /dev/null 2> /dev/null
+ newfs $RLOFIDEV < /dev/null 2> /dev/null
mkdir -p $MNT
- mount -o nologging $LOFIDEV $MNT
+ mount -o nologging $LOFIDEV $MNT
rmdir $MNT/lost+found
+
+ if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
+ root_is_ramdisk $size
+ fi
+
(
cd "$UNPACKED_ROOT"
- find . -print | cpio -pdum $MNT 2> /dev/null
+ if [ "$COMPRESS" = true ] ; then
+ compress . $MNT
+ else
+ find . -print | cpio -pdum $MNT 2> /dev/null
+ fi
)
lockfs -f $MNT
umount $MNT
rmdir $MNT
+
+ if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
+ "$UNPACKED_ROOT/usr/sbin/installboot" \
+ "$UNPACKED_ROOT/usr/platform/sun4u/lib/fs/ufs/bootblk" \
+ $RLOFIDEV
+ fi
+
lofiadm -d $LOFIDEV
LOFIDEV=
rm -f "$TMR.gz"
- gzip -f "$TMR"
- mv "$TMR.gz" "$MR"
+
+ if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
+ mv "$TMR" "$MR"
+ else
+ gzip -f "$TMR"
+ mv "$TMR.gz" "$MR"
+ fi
+
chmod a+r "$MR"
}
@@ -644,13 +768,18 @@ pack()
EXTRA_SPACE=0
STRIP_AMD64=
+COMPRESS=
+
+PATH=/usr/sbin:/usr/bin:/opt/sfw/bin ; export PATH
-while getopts s:6 opt ; do
+while getopts s:6c opt ; do
case $opt in
s) EXTRA_SPACE="$OPTARG"
;;
6) STRIP_AMD64=false
;;
+ c) COMPRESS=true
+ ;;
*) usage
exit 1
;;
@@ -677,45 +806,36 @@ if [ "`dirname $UNPACKED_ROOT`" = . ] ; then
UNPACKED_ROOT="$BASE/$UNPACKED_ROOT"
fi
+
+MEDIA="$MR"
+
trap cleanup EXIT
case $1 in
packmedia)
- MEDIA="$MR"
- MR="$MEDIA/boot/x86.miniroot"
-
if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- archive_X "$MEDIA" "$UNPACKED_ROOT"
+ ARCHIVE=sparc.miniroot
else
- packmedia "$MEDIA" "$UNPACKED_ROOT"
-
- # create the 64-bit miniroot
- # if the -6 option was passed, don't strip
- # the 64-bit modules from the 32-bit miniroot
- MR="$MEDIA/boot/amd64/x86.miniroot"
- pack
-
- if [ "$STRIP_AMD64" = false ] ; then
- ln $MR $MEDIA/boot/x86.miniroot
- else
- # create the 32-bit miniroot
- MR="$MEDIA/boot/x86.miniroot"
- find "$UNPACKED_ROOT" -name amd64 \
- -type directory | xargs rm -rf
- pack
- fi
- fi ;;
+ ARCHIVE=x86.miniroot
+ fi
+ MR="$MR/boot/$ARCHIVE"
+ packmedia "$MEDIA" "$UNPACKED_ROOT"
+ pack
+ ;;
unpackmedia)
- MEDIA="$MR"
- MR="$MR/boot/x86.miniroot"
-
- if [ -d "$UNPACKED_ROOT/kernel/drv/sparcv9" ] ; then
- unarchive_X "$MEDIA" "$UNPACKED_ROOT"
+ if [ -f "$MEDIA/boot/sparc.miniroot" ] ; then
+ ARCHIVE=sparc.miniroot
else
- unpack
- unpackmedia "$MEDIA" "$UNPACKED_ROOT"
- fi ;;
- pack) pack ;;
- unpack) unpack ;;
- *) usage ;;
+ ARCHIVE=x86.miniroot
+ fi
+ MR="$MR/boot/$ARCHIVE"
+ unpack
+ unpackmedia "$MEDIA" "$UNPACKED_ROOT"
+ ;;
+ pack) pack
+ ;;
+ unpack) unpack
+ ;;
+ *) usage
+ ;;
esac
diff --git a/usr/src/cmd/boot/symdef/Makefile b/usr/src/cmd/boot/symdef/Makefile
index dba76dea89..9e551fccae 100644
--- a/usr/src/cmd/boot/symdef/Makefile
+++ b/usr/src/cmd/boot/symdef/Makefile
@@ -25,9 +25,9 @@
# ident "%Z%%M% %I% %E% SMI"
#
-PROG= symdef
+BOOTPROG= symdef
-OBJS= symdef.o
+OBJS= $(BOOTPROG).o
SRCS = $(OBJS:.o=.c)
include ../Makefile.com
@@ -40,11 +40,7 @@ LDLIBS += -lelf
# behavior, which causes us to take SIGSEGV on such a write.
CFLAGS += $(XSTRCONST)
-all: $(PROG)
-
-$(PROG): $(OBJS)
- $(LINK.c) -o $@ $(OBJS) $(LDLIBS)
- $(POST_PROCESS)
+all: $(BOOTPROG)
install: all $(ROOTBOOTSOLARISBINPROG)
diff --git a/usr/src/cmd/sgs/libld/Makefile.com b/usr/src/cmd/sgs/libld/Makefile.com
index e9914c6d9a..8f7df55423 100644
--- a/usr/src/cmd/sgs/libld/Makefile.com
+++ b/usr/src/cmd/sgs/libld/Makefile.com
@@ -74,6 +74,7 @@ package := DLLIB = $(VAR_PKG_DL_LIB)
CPPFLAGS += -DUSE_LIBLD_MALLOC -I$(SRCBASE)/lib/libc/inc \
-I$(SRCBASE)/uts/common/krtld -I$(ELFCAP) \
+ -I$(SRCBASE)/uts/sparc \
$(VAR_LIBLD_CPPFLAGS) -DDO_RELOC_LIBLD
LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(LDDBGLIBDIR) $(LDDBG_LIB) \
$(ELFLIBDIR) -lelf $(DLLIB) -lc
diff --git a/usr/src/cmd/sgs/librtld/Makefile.com b/usr/src/cmd/sgs/librtld/Makefile.com
index 7b0763aeb4..c5d862ff8b 100644
--- a/usr/src/cmd/sgs/librtld/Makefile.com
+++ b/usr/src/cmd/sgs/librtld/Makefile.com
@@ -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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -41,7 +41,8 @@ include $(SRC)/cmd/sgs/Makefile.com
SRCDIR = ../common
CPPFLAGS += -I../../rtld/common -I$(SRCBASE)/lib/libc/inc \
- -I$(SRCBASE)/uts/common/krtld -I$(SRC)/common/sgsrtcid
+ -I$(SRCBASE)/uts/common/krtld -I$(SRC)/common/sgsrtcid \
+ -I$(SRCBASE)/uts/sparc
DYNFLAGS += $(VERSREF) $(ZLAZYLOAD) '-R$$ORIGIN'
LDLIBS += $(CONVLIBDIR) $(CONV_LIB) $(ELFLIBDIR) -lelf -lc
diff --git a/usr/src/cmd/sgs/rtld/Makefile.com b/usr/src/cmd/sgs/rtld/Makefile.com
index bb12a510c4..c14ee7fe0b 100644
--- a/usr/src/cmd/sgs/rtld/Makefile.com
+++ b/usr/src/cmd/sgs/rtld/Makefile.com
@@ -76,6 +76,7 @@ CPPFEATUREMACROS= $(VAR_RTLD_CPPFEATUREMACROS)
CPPFLAGS += -I$(SRCBASE)/lib/libc/inc \
-I$(SRCBASE)/uts/common/krtld \
+ -I$(SRCBASE)/uts/$(PLAT) \
-I$(SRCBASE)/uts/$(PLAT)/krtld \
-I$(SRC)/common/sgsrtcid \
$(CPPFEATUREMACROS)
diff --git a/usr/src/cmd/svc/milestone/README.share b/usr/src/cmd/svc/milestone/README.share
index 4751b3cefc..4cb23168da 100644
--- a/usr/src/cmd/svc/milestone/README.share
+++ b/usr/src/cmd/svc/milestone/README.share
@@ -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"
@@ -63,11 +62,13 @@ potentially require interpreters other than sh(1) or ksh(1).
1. Boot archive failure
-Boot archive may become out of sync with the root filesystem in
-a reboot following an abnormal system shutdown. The recommended
-action is to reboot immediately, choose "Solaris failsafe" when
-the boot menu is displayed. Type 'i' to get an interactive recovery
-shell and follow instructions to update the boot archive.
+The boot archive may become out of sync with the root filesystem in a
+reboot following an abnormal system shutdown. The recommended action is
+to reboot immediately to rebuild the archive and correct the inconsistency.
+To accomplish this, on a GRUB-based platform, choose "Solaris failsafe"
+when the boot menu is displayed. Type 'i' to get an interactive recovery
+shell and follow instructions to update the boot archive. On an OBP-
+based platform, type 'boot -F failsafe' and follow the instructions.
If the list of stale files are not yet loaded by the kernel
or are compatible, you may continue booting by clearing the
diff --git a/usr/src/cmd/svc/milestone/boot-archive b/usr/src/cmd/svc/milestone/boot-archive
index 76ab9f1398..94a2006d23 100644
--- a/usr/src/cmd/svc/milestone/boot-archive
+++ b/usr/src/cmd/svc/milestone/boot-archive
@@ -20,7 +20,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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -32,13 +32,6 @@ ERRORFILE=/etc/svc/volatile/boot_archive_error
FILELIST=/etc/svc/volatile/boot_archive_filelist
UPDATEFILE=/etc/svc/volatile/boot_archive_needs_update
-#
-# no boot-archive on sparc...yet
-#
-if [ `uname -p` = "sparc" ]; then
- exit $SMF_EXIT_OK
-fi
-
smf_is_globalzone || exit $SMF_EXIT_OK
#
@@ -69,10 +62,13 @@ cecho ""
/sbin/bootadm update-archive -vn | grep -v "cannot find" > /dev/msglog
cecho ""
-cecho "The recommended action is to reboot and select the \"Solaris failsafe\""
-cecho "option from the boot menu. Then follow the prompts to update the"
-cecho "boot archive. To continue booting at your own risk, you may clear the"
-cecho "service by running: \"svcadm clear system/boot-archive\""
+cecho "The recommended action is to reboot to the failsafe archive to correct"
+cecho "the above inconsistency. To accomplish this, on a GRUB-based platform,"
+cecho "reboot and select the \"Solaris failsafe\" option from the boot menu."
+cecho "On an OBP-based platform, reboot then type \"boot -F failsafe\". Then"
+cecho "follow the prompts to update the boot archive. Alternately, to continue"
+cecho "booting at your own risk, you may clear the service by running:"
+cecho "\"svcadm clear system/boot-archive\""
cecho ""
exit $SMF_EXIT_ERR_FATAL
diff --git a/usr/src/pkgdefs/SUNWcakr.i/prototype_com b/usr/src/pkgdefs/SUNWcakr.i/prototype_com
index 10f820f3dd..4ccf723226 100644
--- a/usr/src/pkgdefs/SUNWcakr.i/prototype_com
+++ b/usr/src/pkgdefs/SUNWcakr.i/prototype_com
@@ -48,13 +48,10 @@ d none boot 755 root sys
d none boot/solaris 755 root sys
d none boot/solaris/bin 0755 root sys
f none boot/solaris/bin/create_diskmap 0555 root sys
-f none boot/solaris/bin/create_ramdisk 0555 root sys
f none boot/solaris/bin/mbr 0555 root sys
s none boot/solaris/bin/root_archive=../../../usr/sbin/root_archive
f none boot/solaris/bin/symdef 0555 root sys
f none boot/solaris/bin/update_grub 0555 root sys
-f none boot/solaris/filelist.ramdisk 0644 root sys
-f none boot/solaris/filelist.safe 0644 root sys
d none platform 755 root sys
d none platform/i86pc 755 root sys
d none platform/i86pc/amd64 755 root sys
diff --git a/usr/src/pkgdefs/SUNWcakr.u/prototype_com b/usr/src/pkgdefs/SUNWcakr.u/prototype_com
index 7573a522ea..97d5cb6f9d 100644
--- a/usr/src/pkgdefs/SUNWcakr.u/prototype_com
+++ b/usr/src/pkgdefs/SUNWcakr.u/prototype_com
@@ -519,5 +519,4 @@ f none platform/sun4u/kernel/tod/sparcv9/todsg 755 root sys
f none platform/sun4u/kernel/tod/sparcv9/todstarcat 755 root sys
f none platform/sun4u/kernel/tod/sparcv9/todstarfire 755 root sys
s none platform/sun4u/kernel/unix=sparcv9/unix
-f none platform/sun4u/ufsboot 644 root sys
f none platform/sun4u/wanboot 644 root sys
diff --git a/usr/src/pkgdefs/SUNWcakr.v/prototype_com b/usr/src/pkgdefs/SUNWcakr.v/prototype_com
index b42caed3d2..d5236b47f4 100644
--- a/usr/src/pkgdefs/SUNWcakr.v/prototype_com
+++ b/usr/src/pkgdefs/SUNWcakr.v/prototype_com
@@ -92,5 +92,6 @@ d none platform/sun4v/kernel/sys 755 root sys
d none platform/sun4v/kernel/sys/sparcv9 755 root sys
s none platform/sun4v/kernel/unix=sparcv9/unix
#
-f none platform/sun4v/ufsboot 644 root sys
+
+
f none platform/sun4v/wanboot 644 root sys
diff --git a/usr/src/pkgdefs/SUNWckr/prototype_sparc b/usr/src/pkgdefs/SUNWckr/prototype_sparc
index 9b0a5c702e..18b28c5aac 100644
--- a/usr/src/pkgdefs/SUNWckr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWckr/prototype_sparc
@@ -145,6 +145,7 @@ d none kernel/fs/sparcv9 755 root sys
f none kernel/fs/sparcv9/autofs 755 root sys
f none kernel/fs/sparcv9/cachefs 755 root sys
f none kernel/fs/sparcv9/ctfs 755 root sys
+f none kernel/fs/sparcv9/dcfs 755 root sys
f none kernel/fs/sparcv9/devfs 755 root sys
f none kernel/fs/sparcv9/dev 755 root sys
f none kernel/fs/sparcv9/fifofs 755 root sys
@@ -189,7 +190,6 @@ f none kernel/misc/sparcv9/idmap 755 root sys
f none kernel/misc/sparcv9/ipc 755 root sys
f none kernel/misc/sparcv9/kbtrans 755 root sys
f none kernel/misc/sparcv9/kcf 755 root sys
-f none kernel/misc/sparcv9/krtld 755 root sys
f none kernel/misc/sparcv9/mac 755 root sys
l none kernel/misc/sparcv9/md5=../../../kernel/crypto/sparcv9/md5
f none kernel/misc/sparcv9/neti 755 root sys
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_com b/usr/src/pkgdefs/SUNWcsr/prototype_com
index cceeea6d89..fd364d5816 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_com
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_com
@@ -90,6 +90,13 @@ i i.kmfconfbase
# SUNWcsr
#
s none bin=./usr/bin
+d none boot 755 root sys
+d none boot/solaris 755 root sys
+d none boot/solaris/bin 0755 root sys
+f none boot/solaris/bin/create_ramdisk 0555 root sys
+f none boot/solaris/bin/extract_boot_filelist 0555 root sys
+f none boot/solaris/filelist.ramdisk 0644 root sys
+f none boot/solaris/filelist.safe 0644 root sys
d none dev 755 root sys
d none etc 755 root sys
e renamenew etc/.login 644 root sys
@@ -346,6 +353,7 @@ f none lib/svc/bin/svc.startd 0555 root sys
d none lib/svc/capture 0755 root bin
d none lib/svc/method 0755 root bin
f none lib/svc/method/boot-archive 0555 root bin
+f none lib/svc/method/boot-archive-update 0555 root bin
f none lib/svc/method/console-login 0555 root bin
f none lib/svc/method/devices-local 0555 root bin
f none lib/svc/method/fs-local 0555 root bin
@@ -515,6 +523,7 @@ d none var/svc/manifest/platform 755 root sys
d none var/svc/manifest/site 755 root sys
d none var/svc/manifest/system 755 root sys
f manifest var/svc/manifest/system/boot-archive.xml 0444 root sys
+f none var/svc/manifest/system/boot-archive-update.xml 0444 root sys
d none var/svc/manifest/system/device 755 root sys
f manifest var/svc/manifest/system/device/devices-local.xml 0444 root sys
f manifest var/svc/manifest/system/device/mpxio-upgrade.xml 0444 root sys
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_i386 b/usr/src/pkgdefs/SUNWcsr/prototype_i386
index 2cb46da075..e89fc5a4c7 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_i386
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_i386
@@ -46,9 +46,8 @@
#
# SUNWcsr
#
-f none lib/svc/method/boot-archive-update 0555 root bin
+f none boot/solaris/bin/create_diskmap 0555 root sys
f none sbin/biosdev 555 root bin
f none sbin/installgrub 0555 root sys
d none var/ld/amd64 755 root bin
s none var/ld/64=amd64
-f none var/svc/manifest/system/boot-archive-update.xml 0444 root sys
diff --git a/usr/src/pkgdefs/SUNWcsr/prototype_sparc b/usr/src/pkgdefs/SUNWcsr/prototype_sparc
index 9ceff74138..3c5e918767 100644
--- a/usr/src/pkgdefs/SUNWcsr/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcsr/prototype_sparc
@@ -46,6 +46,7 @@
#
# SUNWcsr
#
+f none sbin/fiocompress 555 root bin
d none var/ld/sparcv9 755 root bin
s none var/ld/64=sparcv9
d none var/svc/manifest/platform/sun4u 755 root sys
diff --git a/usr/src/pkgdefs/SUNWcsu/prototype_sparc b/usr/src/pkgdefs/SUNWcsu/prototype_sparc
index f0f6830bc1..06773e1625 100644
--- a/usr/src/pkgdefs/SUNWcsu/prototype_sparc
+++ b/usr/src/pkgdefs/SUNWcsu/prototype_sparc
@@ -105,6 +105,7 @@ s none usr/lib/sparcv9/ld.so.1=../../../lib/sparcv9/ld.so.1
f none usr/lib/sparcv9/libshare.so.1 755 root bin
d none usr/lib/fs/nfs 755 root sys
d none usr/lib/fs/nfs/sparcv9 755 root sys
+s none usr/sbin/fiocompress=../../sbin/fiocompress
l none usr/sbin/prtdiag=../../usr/lib/platexec
d none usr/sbin/sparcv9 755 root bin
f none usr/sbin/sparcv9/add_drv 555 root sys
diff --git a/usr/src/pkgdefs/SUNWhea/prototype_com b/usr/src/pkgdefs/SUNWhea/prototype_com
index 81c0ddb2ae..2e9983f80a 100644
--- a/usr/src/pkgdefs/SUNWhea/prototype_com
+++ b/usr/src/pkgdefs/SUNWhea/prototype_com
@@ -837,6 +837,7 @@ f none usr/include/sys/fs/cachefs_fscache.h 644 root bin
f none usr/include/sys/fs/cachefs_log.h 644 root bin
f none usr/include/sys/fs/cachefs_dlog.h 644 root bin
f none usr/include/sys/fs/cachefs_ioctl.h 644 root bin
+f none usr/include/sys/fs/decomp.h 644 root bin
f none usr/include/sys/fs/dv_node.h 644 root bin
f none usr/include/sys/fs/sdev_node.h 644 root bin
f none usr/include/sys/fs/sdev_impl.h 644 root bin
diff --git a/usr/src/pkgdefs/SUNWkvm.c/prototype_com b/usr/src/pkgdefs/SUNWkvm.c/prototype_com
index 959e58a29d..962918c0f5 100644
--- a/usr/src/pkgdefs/SUNWkvm.c/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.c/prototype_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,8 +19,8 @@
# CDDL HEADER END
#
#
-# Copyright (c) 1990-1998 by 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"
#
@@ -45,8 +44,3 @@ i copyright
#
d none usr 755 root sys
d none usr/platform 755 root sys
-d none usr/platform/sun4c 755 root sys
-d none usr/platform/sun4c/lib 755 root bin
-d none usr/platform/sun4c/lib/fs 755 root bin
-d none usr/platform/sun4c/lib/fs/ufs 755 root bin
-f none usr/platform/sun4c/lib/fs/ufs/bootblk 444 root sys
diff --git a/usr/src/pkgdefs/SUNWkvm.d/prototype_com b/usr/src/pkgdefs/SUNWkvm.d/prototype_com
index 8a53aa2983..528472c700 100644
--- a/usr/src/pkgdefs/SUNWkvm.d/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.d/prototype_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,8 +19,8 @@
# CDDL HEADER END
#
#
-# Copyright (c) 1990-1998, 2001 by 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"
#
@@ -45,8 +44,3 @@ i copyright
#
d none usr 755 root sys
d none usr/platform 755 root sys
-d none usr/platform/sun4d 755 root sys
-d none usr/platform/sun4d/lib 755 root bin
-d none usr/platform/sun4d/lib/fs 755 root bin
-d none usr/platform/sun4d/lib/fs/ufs 755 root bin
-f none usr/platform/sun4d/lib/fs/ufs/bootblk 444 root sys
diff --git a/usr/src/pkgdefs/SUNWkvm.m/prototype_com b/usr/src/pkgdefs/SUNWkvm.m/prototype_com
index 2f6c702131..b245dc8d48 100644
--- a/usr/src/pkgdefs/SUNWkvm.m/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.m/prototype_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 1990-1999, 2002 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"
@@ -45,8 +44,3 @@ i copyright
#
d none usr 755 root sys
d none usr/platform 755 root sys
-d none usr/platform/sun4m 755 root sys
-d none usr/platform/sun4m/lib 755 root bin
-d none usr/platform/sun4m/lib/fs 755 root bin
-d none usr/platform/sun4m/lib/fs/ufs 755 root bin
-f none usr/platform/sun4m/lib/fs/ufs/bootblk 444 root sys
diff --git a/usr/src/pkgdefs/SUNWkvm.u/prototype_com b/usr/src/pkgdefs/SUNWkvm.u/prototype_com
index 0e316a23bb..104225aefb 100644
--- a/usr/src/pkgdefs/SUNWkvm.u/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.u/prototype_com
@@ -287,6 +287,10 @@ s none usr/platform/TAD,SPARCLE/lib/fs=../../sun4u/lib/fs
#
d none usr/platform/sun4u/lib/fs/ufs 755 root bin
f none usr/platform/sun4u/lib/fs/ufs/bootblk 444 root sys
+d none usr/platform/sun4u/lib/fs/hsfs 755 root bin
+f none usr/platform/sun4u/lib/fs/hsfs/bootblk 444 root sys
+d none usr/platform/sun4u/lib/fs/zfs 755 root bin
+f none usr/platform/sun4u/lib/fs/zfs/bootblk 444 root sys
d none usr/platform/sun4u/lib/fs/nfs 755 root bin
f none usr/platform/sun4u/lib/fs/nfs/inetboot 644 root sys
#
diff --git a/usr/src/pkgdefs/SUNWkvm.v/prototype_com b/usr/src/pkgdefs/SUNWkvm.v/prototype_com
index 0d388e4eff..720506b5b0 100644
--- a/usr/src/pkgdefs/SUNWkvm.v/prototype_com
+++ b/usr/src/pkgdefs/SUNWkvm.v/prototype_com
@@ -72,5 +72,9 @@ d none usr/platform/sun4v/lib/fs 755 root bin
#
d none usr/platform/sun4v/lib/fs/ufs 755 root bin
f none usr/platform/sun4v/lib/fs/ufs/bootblk 444 root sys
+d none usr/platform/sun4v/lib/fs/hsfs 755 root bin
+f none usr/platform/sun4v/lib/fs/hsfs/bootblk 444 root sys
+d none usr/platform/sun4v/lib/fs/zfs 755 root bin
+f none usr/platform/sun4v/lib/fs/zfs/bootblk 444 root sys
d none usr/platform/sun4v/lib/fs/nfs 755 root bin
f none usr/platform/sun4v/lib/fs/nfs/inetboot 644 root sys
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_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/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(&params)) != -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/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/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/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/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/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/hsfs/sparc/sun4u/Makefile b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4u/Makefile
new file mode 100644
index 0000000000..5103f063d8
--- /dev/null
+++ b/usr/src/psm/stand/bootblks/hsfs/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/hsfs/sparc/sun4u/Makefile
+#
+
+#
+# Platform specific Makefile for the boot block.
+#
+BASEDIR = ../../..
+PLATFORM = sun4u
+
+include $(BASEDIR)/hsfs/Makefile.hsfs
+include $(BASEDIR)/Makefile.1275
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+include $(BASEDIR)/Makefile.targ
diff --git a/usr/src/psm/stand/bootblks/hsfs/sparc/sun4v/Makefile b/usr/src/psm/stand/bootblks/hsfs/sparc/sun4v/Makefile
new file mode 100644
index 0000000000..31a707e696
--- /dev/null
+++ b/usr/src/psm/stand/bootblks/hsfs/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/hsfs/sparc/sun4u/Makefile
+#
+
+#
+# Platform specific Makefile for the boot block.
+#
+BASEDIR = ../../..
+PLATFORM = sun4v
+
+include $(BASEDIR)/hsfs/Makefile.hsfs
+include $(BASEDIR)/Makefile.1275
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+include $(BASEDIR)/Makefile.targ
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/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/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/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/zfs/i386/Makefile b/usr/src/psm/stand/bootblks/zfs/i386/Makefile
new file mode 100644
index 0000000000..a13453a764
--- /dev/null
+++ b/usr/src/psm/stand/bootblks/zfs/i386/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/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
+
+FRC:
diff --git a/usr/src/psm/stand/bootblks/zfs/sparc/Makefile b/usr/src/psm/stand/bootblks/zfs/sparc/Makefile
new file mode 100644
index 0000000000..2a4c1e9b1f
--- /dev/null
+++ b/usr/src/psm/stand/bootblks/zfs/sparc/Makefile
@@ -0,0 +1,48 @@
+#
+# 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/Makefile
+#
+BASEDIR = ../..
+
+include $(BASEDIR)/zfs/Makefile.zfs
+
+SUBDIRS = sun4u sun4v
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+
+.KEEP_STATE:
+
+all install lint clean clobber: $(SUBDIRS)
+
+$(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
diff --git a/usr/src/stand/lib/fs/hsfs/hsfsops.c b/usr/src/stand/lib/fs/hsfs/hsfsops.c
index c8a98b4780..0c515740f5 100644
--- a/usr/src/stand/lib/fs/hsfs/hsfsops.c
+++ b/usr/src/stand/lib/fs/hsfs/hsfsops.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-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -146,7 +145,7 @@ opendir(fileid_t *filep, ino_t inode)
filep->fi_blocknum = hdbtodb(inode);
if (inode != root_ino)
- return (0);
+ return (0);
if ((int)(parse_dir(filep, 0, &hsdep)) > 0) {
hs_seti(filep, &hsdep, inode);
@@ -168,7 +167,7 @@ find(fileid_t *filep, char *path)
}
if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf("find(): path=<%s>\n", path);
+ printf("find(): path=<%s>\n", path);
/* Read the ROOT directory */
if (opendir(filep, inode = root_ino)) {
@@ -464,7 +463,7 @@ boot_hsfs_mountroot(char *str)
char *bufp;
if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf("mountroot()\n");
+ printf("mountroot()\n");
/*
* If already mounted, just return success.
@@ -595,7 +594,7 @@ boot_hsfs_open(char *filename, int flags)
inode = find(filep, filename);
if (inode == (ino_t)0) {
if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf("open(%s) ENOENT\n", filename);
+ printf("open(%s) ENOENT\n", filename);
(void) boot_hsfs_close(filep->fi_filedes);
return (-1);
}
@@ -604,7 +603,7 @@ boot_hsfs_open(char *filename, int flags)
filep->fi_offset = filep->fi_count = 0;
if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf("open(%s) fd=%d\n", filename, filep->fi_filedes);
+ printf("open(%s) fd=%d\n", filename, filep->fi_filedes);
return (filep->fi_filedes);
}
@@ -679,7 +678,7 @@ boot_hsfs_close(int fd)
fileid_t *filep;
if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf("close(%d)\n", fd);
+ printf("close(%d)\n", fd);
if (filep = find_fp(fd)) {
/* Clear the ranks */
@@ -702,6 +701,7 @@ boot_hsfs_close(int fd)
}
}
+/* closeall is now idempotent */
/*ARGSUSED*/
static void
boot_hsfs_closeall(int flag)
@@ -709,11 +709,18 @@ boot_hsfs_closeall(int flag)
fileid_t *filep = head;
extern int verbosemode;
+ if (devp == NULL) {
+ if (head)
+ prom_panic("boot_hsfs_closeall: head != NULL.\n");
+ return;
+ }
+
while ((filep = filep->fi_forw) != head)
if (filep->fi_taken)
if (boot_hsfs_close(filep->fi_filedes))
prom_panic("Filesystem may be inconsistent.\n");
+
release_cache(devp->di_dcookie);
(void) prom_close(devp->di_dcookie);
devp->di_taken = 0;
@@ -722,6 +729,8 @@ boot_hsfs_closeall(int flag)
bkmem_free((char *)devp, sizeof (devid_t));
bkmem_free((char *)head, sizeof (fileid_t));
root_ino = 0;
+ devp = NULL;
+ head = NULL;
}
static uint_t
@@ -796,52 +805,53 @@ parse_dir(fileid_t *filep, int offset, struct hs_direct *hsdep)
ce_len = IDE_SUA_LEN(bufp);
ce_lbn = 0;
if ((int)(ce_len) > 0) {
- ce_lbn = parse_susp((char *)IDE_sys_use_area(bufp), &ce_len, hsdep);
- while (ce_lbn) {
- daddr_t save_blocknum = filep->fi_blocknum;
- daddr_t save_offset = filep->fi_offset;
- caddr_t save_memp = filep->fi_memp;
- uint_t save_count = filep->fi_count;
+ ce_lbn = parse_susp((char *)IDE_sys_use_area(bufp),
+ &ce_len, hsdep);
+ while (ce_lbn) {
+ daddr_t save_blocknum = filep->fi_blocknum;
+ daddr_t save_offset = filep->fi_offset;
+ caddr_t save_memp = filep->fi_memp;
+ uint_t save_count = filep->fi_count;
#ifdef noisy
- print_io_req(filep, "parse_dir(): [I]");
+ print_io_req(filep, "parse_dir(): [I]");
#endif /* noisy */
- filep->fi_blocknum = hdbtodb(ce_lbn);
- filep->fi_offset = 0;
- filep->fi_count = ISO_SECTOR_SIZE;
+ filep->fi_blocknum = hdbtodb(ce_lbn);
+ filep->fi_offset = 0;
+ filep->fi_count = ISO_SECTOR_SIZE;
#ifdef noisy
- print_io_req(filep, "parse_dir(): [0]");
+ print_io_req(filep, "parse_dir(): [0]");
#endif /* noisy */
- if ((filep->fi_memp = get_bcache(filep)) == 0)
- ret_code = set_bcache(filep);
+ if ((filep->fi_memp = get_bcache(filep)) == 0)
+ ret_code = set_bcache(filep);
#ifdef noisy
- print_io_req(filep, "parse_dir(): [1]");
+ print_io_req(filep, "parse_dir(): [1]");
#endif /* noisy */
- if (ret_code) {
- filep->fi_blocknum = save_blocknum;
- filep->fi_offset = save_offset;
- filep->fi_memp = save_memp;
- filep->fi_count = save_count;
- printf("parse_dir(): set_bcache() failed (%d)\n",
- ret_code);
- break;
- }
- ce_lbn = parse_susp(filep->fi_memp, &ce_len, hsdep);
-
- filep->fi_blocknum = save_blocknum;
- filep->fi_offset = save_offset;
- filep->fi_memp = save_memp;
- filep->fi_count = save_count;
+ if (ret_code) {
+ filep->fi_blocknum = save_blocknum;
+ filep->fi_offset = save_offset;
+ filep->fi_memp = save_memp;
+ filep->fi_count = save_count;
+ printf("parse_dir(): "
+ "set_bcache() failed (%d)\n", ret_code);
+ break;
+ }
+ ce_lbn = parse_susp(filep->fi_memp, &ce_len, hsdep);
+
+ filep->fi_blocknum = save_blocknum;
+ filep->fi_offset = save_offset;
+ filep->fi_memp = save_memp;
+ filep->fi_count = save_count;
#ifdef noisy
- print_io_req(filep, "parse_dir(): [2]");
+ print_io_req(filep, "parse_dir(): [2]");
#endif /* noisy */
- }
+ }
}
return (udp->d_reclen);
@@ -859,75 +869,84 @@ parse_susp(char *bufp, uint_t *ce_len, struct hs_direct *hsdep)
uint_t i;
while (cur_off < blk_len) {
- susp = (uchar_t *)(bufp + cur_off);
- if (susp[0] == '\0' || susp[1] == '\0')
- break;
- susp_len = SUF_LEN(susp);
- if (susp_len == 0)
- break;
- for (i = 0; i < hsfs_num_sig; i++) {
- if (strncmp(hsfs_sig_tab[i], (char *)susp, SUF_SIG_LEN) == 0) {
+ susp = (uchar_t *)(bufp + cur_off);
+ if (susp[0] == '\0' || susp[1] == '\0')
+ break;
+ susp_len = SUF_LEN(susp);
+ if (susp_len == 0)
+ break;
+ for (i = 0; i < hsfs_num_sig; i++) {
+ if (strncmp(hsfs_sig_tab[i],
+ (char *)susp, SUF_SIG_LEN) == 0) {
#ifdef noisy
- if ((boothowto & RB_DEBUG) && (boothowto & RB_VERBOSE))
- printf(" SUSP_%c%c %d\n", susp[0], susp[1], susp_len);
+ if ((boothowto & RB_DEBUG) &&
+ (boothowto & RB_VERBOSE))
+ printf(" SUSP_%c%c %d\n",
+ susp[0], susp[1], susp_len);
#endif /* noisy */
- switch (i) {
- case SUSP_SP_IX:
- if (CHECK_BYTES_OK(susp)) {
- sua_offset = SP_SUA_OFFSET(susp);
+ switch (i) {
+ case SUSP_SP_IX:
+ if (CHECK_BYTES_OK(susp)) {
+ sua_offset =
+ SP_SUA_OFFSET(susp);
#ifdef lint
- /* Like the man said, this may not be needed */
- i = (int)sua_offset;
+ /* this may not be needed */
+ i = (int)sua_offset;
#endif /* lint */
- }
- break;
+ }
+ break;
- case SUSP_CE_IX:
- ce_lbn = CE_BLK_LOC(susp);
- *ce_len = CE_CONT_LEN(susp);
+ case SUSP_CE_IX:
+ ce_lbn = CE_BLK_LOC(susp);
+ *ce_len = CE_CONT_LEN(susp);
#ifdef noisy
- if ((boothowto & RB_DEBUG) &&
- (boothowto & RB_VERBOSE))
- printf("parse_susp(): "
- "CE: ce_lbn = %d ce_len=%d\n",
- ce_lbn, *ce_len);
+ if ((boothowto & RB_DEBUG) &&
+ (boothowto & RB_VERBOSE))
+ printf("parse_susp(): "
+ "CE: ce_lbn = %d "
+ "ce_len=%d\n",
+ ce_lbn, *ce_len);
#endif /* noisy */
- break;
+ break;
- case SUSP_ST_IX:
- printf("parse_susp(): ST: returning %d\n", ce_lbn);
- return (ce_lbn);
+ case SUSP_ST_IX:
+ printf("parse_susp(): ST: returning "
+ "%d\n", ce_lbn);
+ return (ce_lbn);
- case RRIP_SL_IX:
+ case RRIP_SL_IX:
#ifdef noisy
- if ((boothowto & RB_DEBUG) &&
- (boothowto & RB_VERBOSE))
- printf("parse_susp(): ******* SL *******\n");
+ if ((boothowto & RB_DEBUG) &&
+ (boothowto & RB_VERBOSE))
+ printf("parse_susp(): "
+ "******* SL *******\n");
#endif /* noisy */
- break;
-
- case RRIP_RR_IX:
- break;
-
- case RRIP_NM_IX:
- if (!RRIP_NAME_FLAGS(susp)) {
- udp->d_namlen = RRIP_NAME_LEN(susp);
- bcopy((char *)RRIP_name(susp),
- (char *)udp->d_name,
- udp->d_namlen);
- udp->d_name[udp->d_namlen] = '\0';
- }
- break;
- }
- cur_off += susp_len;
- break;
+ break;
+
+ case RRIP_RR_IX:
+ break;
+
+ case RRIP_NM_IX:
+ if (!RRIP_NAME_FLAGS(susp)) {
+ udp->d_namlen =
+ RRIP_NAME_LEN(susp);
+ bcopy((char *)RRIP_name(susp),
+ (char *)udp->d_name,
+ udp->d_namlen);
+ udp->d_name
+ [udp->d_namlen] = '\0';
+ }
+ break;
+ }
+ cur_off += susp_len;
+ break;
+ }
+ }
+ if (i > hsfs_num_sig) {
+ printf("parse_susp(): Bad SUSP\n");
+ cur_off = blk_len;
+ break;
}
- }
- if (i > hsfs_num_sig) {
- printf("parse_susp(): Bad SUSP\n");
- cur_off = blk_len;
- break;
- }
}
return (ce_lbn);
}
@@ -962,11 +981,11 @@ static void
print_io_req(fileid_t *filep, char *str)
{
printf("%s o=%d b=%d c=%d m=%x\n",
- str,
- filep->fi_offset,
- filep->fi_blocknum,
- filep->fi_count,
- (uint_t)filep->fi_memp);
+ str,
+ filep->fi_offset,
+ filep->fi_blocknum,
+ filep->fi_count,
+ (uint_t)filep->fi_memp);
}
#endif /* noisy */
diff --git a/usr/src/stand/lib/fs/nfs/nfsops.c b/usr/src/stand/lib/fs/nfs/nfsops.c
index 2adf856fc0..3da57391ab 100644
--- a/usr/src/stand/lib/fs/nfs/nfsops.c
+++ b/usr/src/stand/lib/fs/nfs/nfsops.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.
*
* Simple nfs ops - open, close, read, and lseek.
@@ -104,6 +103,11 @@ boot_nfs_closeall(int flag)
printf("boot_nfs_closeall(%x)\n", flag);
#endif
+ if (nfs_files->file.version == 0 &&
+ nfs_files->desc == 0 &&
+ nfs_files->next == NULL)
+ return;
+
/* delete any dynamically allocated entries */
while ((filep = nfs_files->next) != NULL) {
nfs_files->next = filep->next;
@@ -211,7 +215,7 @@ boot_nfs_open(char *path, int flags)
#ifdef NFS_OPS_DEBUG
if ((boothowto & DBFLAGS) == DBFLAGS)
printf("boot_nfs_open(): '%s' successful, fd = 0x%x\n",
- path, filep->desc);
+ path, filep->desc);
#endif
return (filep->desc);
}
@@ -283,7 +287,7 @@ boot_nfs_read(int fd, char *buf, size_t size)
break;
default:
printf("boot_nfs_read: NFS Version %d not supported\n",
- filep->file.version);
+ filep->file.version);
count = -1;
break;
}
@@ -382,8 +386,8 @@ boot_nfs_fstat(int fd, struct bootstat *stp)
return (-1);
bzero((char *)&va, sizeof (va));
- va.va_mask = AT_TYPE | AT_SIZE | AT_MODE | AT_NODEID | \
- AT_ATIME | AT_CTIME | AT_MTIME;
+ va.va_mask = AT_TYPE | AT_SIZE | AT_MODE | AT_NODEID |
+ AT_ATIME | AT_CTIME | AT_MTIME;
switch (filep->file.version) {
case NFS_VERSION:
@@ -397,7 +401,7 @@ boot_nfs_fstat(int fd, struct bootstat *stp)
break;
default:
printf("boot_nfs_fstat: NFS Version %d not supported\n",
- filep->file.version);
+ filep->file.version);
status = -1;
break;
}
@@ -455,7 +459,7 @@ boot_nfs_getdents(int fd, struct dirent *dep, unsigned size)
break;
default:
printf("boot_nfs_getdents: NFS Version %d not supported\n",
- filep->file.version);
+ filep->file.version);
status = -1;
}
diff --git a/usr/src/stand/lib/fs/ufs/ufsops.c b/usr/src/stand/lib/fs/ufs/ufsops.c
index 8e3cab1f03..8a53f92627 100644
--- a/usr/src/stand/lib/fs/ufs/ufsops.c
+++ b/usr/src/stand/lib/fs/ufs/ufsops.c
@@ -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.
*/
@@ -125,7 +125,7 @@ openi(fileid_t *filep, ino_t inode)
/* Nope, not there so lets read it off the disk. */
filep->fi_offset = 0;
filep->fi_blocknum = fsbtodb(&devp->un_fs.di_fs,
- itod(&devp->un_fs.di_fs, inode));
+ itod(&devp->un_fs.di_fs, inode));
/* never more than 1 disk block */
filep->fi_count = devp->un_fs.di_fs.fs_bsize;
@@ -147,7 +147,7 @@ openi(fileid_t *filep, ino_t inode)
dp[itoo(&devp->un_fs.di_fs, inode)].di_un.di_icom;
filep->fi_inode->i_number = inode;
if (set_ricache(devp->di_dcookie, inode, (void *)filep->fi_inode,
- sizeof (struct inode)))
+ sizeof (struct inode)))
filep->fi_inode->i_flag = FI_NOCACHE;
return (0);
}
@@ -210,8 +210,8 @@ find(fileid_t *filep, char *path)
filep->fi_inode->i_db[0]);
filep->fi_count = DEV_BSIZE;
/* check the block cache */
- if ((filep->fi_memp = get_bcache(filep))
- == NULL) {
+ if ((filep->fi_memp =
+ get_bcache(filep)) == NULL) {
if (set_bcache(filep))
return ((ino_t)0);
lufs_merge_deltas(filep);
@@ -385,7 +385,7 @@ dlook(fileid_t *filep, char *path)
continue;
if (set_rdcache(devp->di_dcookie, dp->d_name, ip->i_number,
- dp->d_ino)) {
+ dp->d_ino)) {
ip->i_flag &= ~FI_CACHED;
ip->i_flag |= FI_PARTIAL_CACHE;
#ifdef DEBUG
@@ -825,17 +825,25 @@ boot_ufs_close(int fd)
}
}
+/* closeall is now idempotent */
/*ARGSUSED*/
static void
boot_ufs_closeall(int flag)
{
fileid_t *filep = head;
+ if (ufs_devp == NULL) {
+ if (head)
+ prom_panic("boot_ufs_closeall: head != NULL.\n");
+ return;
+ }
+
while ((filep = filep->fi_forw) != head)
if (filep->fi_taken)
if (boot_ufs_close(filep->fi_filedes))
prom_panic("Filesystem may be inconsistent.\n");
+
release_cache(ufs_devp->di_dcookie);
(void) prom_close(ufs_devp->di_dcookie);
ufs_devp->di_taken = 0;
@@ -896,7 +904,7 @@ boot_ufs_getdents(int fd, struct dirent *dep, unsigned size)
}
}
- if ((fp->fi_inode->i_smode & IFMT) == IFDIR) {
+ if ((fp->fi_inode->i_smode & IFMT) == IFDIR) {
/*
* If target file is a directory, go ahead
* and read it. This consists of making
diff --git a/usr/src/stand/lib/sa/stddef.h b/usr/src/stand/lib/sa/stddef.h
index c9709aa373..82a497f4d1 100644
--- a/usr/src/stand/lib/sa/stddef.h
+++ b/usr/src/stand/lib/sa/stddef.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.
*/
@@ -42,7 +41,9 @@ extern "C" {
#define NULL 0
#endif
+#ifndef offsetof
#define offsetof(s, m) (size_t)(&(((s *)0)->m))
+#endif
#ifdef __cplusplus
}
diff --git a/usr/src/tools/findunref/exception_list b/usr/src/tools/findunref/exception_list
index e0ab7dd900..070af00ac3 100644
--- a/usr/src/tools/findunref/exception_list
+++ b/usr/src/tools/findunref/exception_list
@@ -262,13 +262,6 @@
./src/lib/libresolv2/include/err.h
#
-# Ignore ufs unix version of the boot block, useful for testing.
-#
-./src/psm/stand/bootblks/ufs/common/iob.h
-./src/psm/stand/bootblks/ufs/common/ufs.c
-./src/psm/stand/bootblks/obp-c/common/cbootblk.h
-
-#
# Ignore mont_mulf.c. It is used as a starting point for some hand optimized
# assembly files. We keep it around for future reference.
#
diff --git a/usr/src/tools/scripts/Install.sh b/usr/src/tools/scripts/Install.sh
index f491412c46..b9ed32064b 100644
--- a/usr/src/tools/scripts/Install.sh
+++ b/usr/src/tools/scripts/Install.sh
@@ -489,9 +489,9 @@ copy_kernel() {
done
#
- # on x86, add the glommed kernel name to the root archive
+ # Add the glommed kernel name to the root archive
#
- if [[ $MACH = "i386" && $GLOM == "yes" ]];
+ if [[ $GLOM == "yes" ]];
then
filelist="$INSTALL_FILES/etc/boot/solaris/filelist.ramdisk"
mkdir -p `dirname $filelist`
diff --git a/usr/src/tools/scripts/bfu.sh b/usr/src/tools/scripts/bfu.sh
index 26fb0ad277..560e06d722 100644
--- a/usr/src/tools/scripts/bfu.sh
+++ b/usr/src/tools/scripts/bfu.sh
@@ -339,9 +339,7 @@ superfluous_nonglobal_zone_files="
platform/sun4u/lib/sparcv9/libwrsmconf.so
platform/sun4u/lib/sparcv9/libwrsmconf.so.1
platform/sun4u/sbin
- platform/sun4u/ufsboot
platform/sun4u/wanboot
- platform/sun4v/ufsboot
platform/sun4v/wanboot
sbin/metadb
sbin/metadevadm
@@ -2358,6 +2356,15 @@ if $ZCAT $cpiodir/generic.root$ZFIX | cpio -it 2>/dev/null | \
new_dladm=yes
fi
+#
+# Check whether the build is boot-archive or ufsboot sparc
+# boot based on the existence of a generic.boot archive
+#
+newboot_sparc=no
+if [ $target_isa = sparc -a -f $cpiodir/generic.boot$ZFIX ]; then
+ newboot_sparc=yes
+fi
+
time_ref=/tmp/bfu.time_ref.$$
rm -f $time_ref
touch $time_ref || fail "$time_ref: Unable to create time reference."
@@ -4712,7 +4719,8 @@ get_rootdev_list()
elif [[ $metadev = /dev/md/rdsk/* ]]; then
metavol=`echo "$metadev" | sed -e "s#/dev/md/rdsk/##"`
rootdevlist=`metastat -p $metavol |\
- grep -v "^$metavol[ ]" | nawk '{print $4}'`
+ grep -v "^$metavol[ ]" |\
+ nawk '{print $4}' | sed -e "s#/dev/rdsk/##"`
fi
for rootdev in $rootdevlist
do
@@ -5093,6 +5101,39 @@ EOF
chmod +x $rootprefix/bfu.conflicts/lib/svc/method/boot-archive
}
+#
+# Install failsafe archive on a sparc machine if not present.
+# Use a well-known server for the archive if we need it.
+#
+install_sparc_failsafe()
+{
+ # check if failsafe already installed
+ if [ -f $rootprefix/platform/$karch/failsafe ]; then
+ return
+ fi
+ if [ -z "$FAILSAFE_SERVER" ]; then
+ FAILSAFE_SERVER="netinstall.sfbay"
+ fi
+ if [ -z "$FAILSAFE_IMAGE" ]; then
+ FAILSAFE_IMAGE="export/nv/s/latest"
+ fi
+ fs_wos_image="/net/${FAILSAFE_SERVER}/${FAILSAFE_IMAGE}"
+ fs_archive="${fs_wos_image}/boot/sparc.miniroot"
+ if [ ! -d $fs_wos_image ] || [ ! -f $fs_archive ]; then
+ # XXX Remove this fallback to a known good archive once real
+ # XXX images with boot archives become available.
+ fs_wos_image="/net/netinstall.sfbay/export/setje/nbs-latest"
+ fs_archive="${fs_wos_image}/boot/sparc.miniroot"
+ fi
+ if [ ! -d $fs_wos_image ] || [ ! -f $fs_archive ]; then
+ echo "no failsafe archive, but can't find one to install"
+ return
+ fi
+
+ echo "Installing failsafe archive from $fs_wos_image"
+ cp $fs_archive $rootprefix/platform/$karch/failsafe
+}
+
disable_boot_service()
{
svccfg -s system/boot-archive setprop start/exec = true
@@ -7017,6 +7058,14 @@ mondo_loop() {
print "Installing boot block on $rootslice."
cd $usr/platform/$karch/lib/fs/ufs
installboot ./bootblk $rootslice
+ elif [[ "$rootslice" = /dev/md/rdsk/* ]]; then
+ print "Detected SVM root."
+ cd $usr/platform/$karch/lib/fs/ufs
+ get_rootdev_list | while read physlice
+ do
+ print "Installing bootblk on $physlice."
+ installboot ./bootblk $physlice
+ done
fi
;;
i386)
@@ -7044,6 +7093,8 @@ mondo_loop() {
extract_archives root generic $archlist
if [ $target_isa = i386 ]; then
extract_boot_archives boot $archlist
+ elif [ $newboot_sparc = yes ]; then
+ extract_boot_archives boot generic
fi
else
export PATH=/tmp/bfubin
@@ -7064,6 +7115,8 @@ mondo_loop() {
# .root archives.
#
extract_boot_archives boot $rootarchs
+ elif [ $newboot_sparc = yes ]; then
+ extract_boot_archives boot generic
fi
else
dir_is_inherited usr ||
@@ -7344,6 +7397,16 @@ mondo_loop() {
check_boot_env
fi
+ #
+ # update boot archives for new boot sparc
+ #
+ if [ $newboot_sparc = yes ] && \
+ [[ $rootslice = /dev/rdsk/* ||
+ $rootslice = /dev/md/rdsk/* ]]; then
+ build_boot_archive
+ install_sparc_failsafe
+ fi
+
# Check for damage due to CR 6379341. This was actually fixed
# back in snv_24, but users BFUing from an S10 build up to
# Nevada can still encounter it.
diff --git a/usr/src/tools/scripts/mkbfu.sh b/usr/src/tools/scripts/mkbfu.sh
index 963eb4b246..c5980fd645 100644
--- a/usr/src/tools/scripts/mkbfu.sh
+++ b/usr/src/tools/scripts/mkbfu.sh
@@ -197,8 +197,13 @@ do
done
if [ -d boot ]; then
- ( find boot -depth -print | create_archive $CLASS boot ) \
- 2>$CPIODIR/${CLASS}.boot.err &
+ if [ "$CLASS" = "i86pc" ]; then
+ ARCHIVECLASS="$CLASS"
+ else
+ ARCHIVECLASS="generic"
+ fi
+ ( find boot -depth -print | create_archive $ARCHIVECLASS boot ) \
+ 2>$CPIODIR/$ARCHIVECLASS.boot.err &
bgcheck
fi
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files
index 52ba4b0bf2..1dec324b2f 100644
--- a/usr/src/uts/common/Makefile.files
+++ b/usr/src/uts/common/Makefile.files
@@ -214,6 +214,7 @@ GENUNIX_OBJS += \
nvpair.o \
nvpair_alloc_system.o \
nvpair_alloc_fixed.o \
+ octet.o \
open.o \
p_online.o \
pathconf.o \
@@ -836,6 +837,8 @@ CACHEFS_OBJS += cachefs_cnode.o cachefs_cod.o \
cachefs_subr.o cachefs_vfsops.o \
cachefs_vnops.o
+DCFS_OBJS += dc_vnops.o
+
DEVFS_OBJS += devfs_subr.o devfs_vfsops.o devfs_vnops.o
DEV_OBJS += sdev_subr.o sdev_vfsops.o sdev_vnops.o \
@@ -1372,23 +1375,12 @@ DES_OBJS += des_crypt.o des_cbc_crypt.o des_impl.o des_ks.o des_soft.o
DLBOOT_OBJS += bootparam_xdr.o nfs_dlinet.o scan.o
-sparc_KRTLD_OBJS = \
- kobj_subr.o
-
-i386_KRTLD_OBJS =
-
-COMMON_KRTLD_OBJS = \
- kobj_bootflags.o \
- getoptstr.o \
- kobj.o \
- kobj_kdi.o \
- kobj_lm.o
-
-KRTLD_OBJS += $(COMMON_KRTLD_OBJS) $($(MACH)_KRTLD_OBJS)
+KRTLD_OBJS += kobj_bootflags.o getoptstr.o \
+ kobj.o kobj_kdi.o kobj_lm.o kobj_subr.o
MOD_OBJS += modctl.o modsubr.o modsysfile.o modconf.o modhash.o
-STRPLUMB_OBJS += strplumb.o octet.o
+STRPLUMB_OBJS += strplumb.o
CPR_OBJS += cpr_driver.o cpr_dump.o \
cpr_main.o cpr_misc.o cpr_mod.o cpr_stat.o \
diff --git a/usr/src/uts/common/Makefile.rules b/usr/src/uts/common/Makefile.rules
index 5f47d597de..d33fcc7bc0 100644
--- a/usr/src/uts/common/Makefile.rules
+++ b/usr/src/uts/common/Makefile.rules
@@ -178,6 +178,10 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/cachefs/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+$(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/dcfs/%.c
+ $(COMPILE.c) -o $@ $<
+ $(CTFCONVERT_O)
+
$(OBJS_DIR)/%.o: $(UTSBASE)/common/fs/devfs/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -907,6 +911,22 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/common/ktli/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+#
+# krtld must refer to its own bzero/bcopy until the kernel is fully linked
+#
+$(OBJS_DIR)/bootrd.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/doreloc.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_boot.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_bootflags.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_convrelstr.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_isa.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_kdi.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_lm.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_reloc.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_stubs.o := CPPFLAGS += -DKOBJ_OVERRIDES
+$(OBJS_DIR)/kobj_subr.o := CPPFLAGS += -DKOBJ_OVERRIDES
+
$(OBJS_DIR)/%.o: $(UTSBASE)/common/krtld/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
@@ -1142,6 +1162,9 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/ctfs/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/doorfs/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/dcfs/%.c
+ @($(LHEAD) $(LINT.c) $< $(LTAIL))
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/common/fs/devfs/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
diff --git a/usr/src/uts/common/fs/dcfs/dc_vnops.c b/usr/src/uts/common/fs/dcfs/dc_vnops.c
new file mode 100644
index 0000000000..8b2f2875fb
--- /dev/null
+++ b/usr/src/uts/common/fs/dcfs/dc_vnops.c
@@ -0,0 +1,1110 @@
+
+/*
+ * 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.
+ */
+
+/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+/*
+ * University Copyright- Copyright (c) 1982, 1986, 1988
+ * The Regents of the University of California
+ * All Rights Reserved
+ *
+ * University Acknowledgment- Portions of this document are derived from
+ * software developed by the University of California, Berkeley, and its
+ * contributors.
+ */
+
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/types.h>
+#include <sys/thread.h>
+#include <sys/t_lock.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bitmap.h>
+#include <sys/buf.h>
+#include <sys/cmn_err.h>
+#include <sys/conf.h>
+#include <sys/ddi.h>
+#include <sys/debug.h>
+#include <sys/errno.h>
+#include <sys/time.h>
+#include <sys/fcntl.h>
+#include <sys/flock.h>
+#include <sys/file.h>
+#include <sys/kmem.h>
+#include <sys/mman.h>
+#include <sys/vmsystm.h>
+#include <sys/open.h>
+#include <sys/swap.h>
+#include <sys/sysmacros.h>
+#include <sys/uio.h>
+#include <sys/vfs.h>
+#include <sys/vfs_opreg.h>
+#include <sys/vnode.h>
+#include <sys/stat.h>
+#include <sys/poll.h>
+#include <sys/zmod.h>
+#include <sys/fs/decomp.h>
+
+#include <vm/hat.h>
+#include <vm/as.h>
+#include <vm/page.h>
+#include <vm/pvn.h>
+#include <vm/seg_vn.h>
+#include <vm/seg_kmem.h>
+#include <vm/seg_map.h>
+
+#include <fs/fs_subr.h>
+
+/*
+ * dcfs - A filesystem for automatic decompressing of fiocompressed files
+ *
+ * This filesystem is a layered filesystem that sits on top of a normal
+ * persistent filesystem and provides automatic decompression of files
+ * that have been previously compressed and stored on the host file system.
+ * This is a pseudo filesystem in that it does not persist data, rather it
+ * intercepts file lookup requests on the host filesystem and provides
+ * transparent decompression of those files. Currently the only supported
+ * host filesystem is ufs.
+ *
+ * A file is compressed via a userland utility (currently cmd/boot/fiocompress)
+ * and marked by fiocompress as a compressed file via a flag in the on-disk
+ * inode (set via a ufs ioctl() - see `ufs_vnops.c`ufs_ioctl()`_FIO_COMPRESSED
+ * ufs_lookup checks for this flag and if set, passes control to decompvp
+ * a function defined in this (dcfs) filesystem. decomvp uncompresses the file
+ * and returns a dcfs vnode to the VFS layer.
+ *
+ * dcfs is layered on top of ufs and passes requests involving persistence
+ * to the underlying ufs filesystem. The compressed files currently cannot be
+ * written to.
+ */
+
+
+/*
+ * Define data structures within this file.
+ */
+#define DCSHFT 5
+#define DCTABLESIZE 16
+
+#if ((DCTABLESIZE & (DCTABLESIZE - 1)) == 0)
+#define DCHASH(vp) (((uintptr_t)(vp) >> DCSHFT) & (DCTABLESIZE - 1))
+#else
+#define DCHASH(vp) (((uintptr_t)(vp) >> DCSHFT) % DTABLESIZEC)
+#endif
+
+#define DCLRUSIZE 16
+
+#define DCCACHESIZE 4
+
+#define rounddown(x, y) ((x) & ~((y) - 1))
+
+struct dcnode *dctable[DCTABLESIZE];
+
+struct dcnode *dclru;
+static int dclru_len;
+
+kmutex_t dctable_lock;
+
+dev_t dcdev;
+struct vfs dc_vfs;
+
+struct kmem_cache *dcnode_cache;
+struct kmem_cache *dcbuf_cache[DCCACHESIZE];
+
+kmutex_t dccache_lock;
+
+static int dcinit(int, char *);
+
+static struct dcnode *dcnode_alloc(void);
+static void dcnode_free(struct dcnode *);
+static void dcnode_recycle(struct dcnode *);
+
+static void dcinsert(struct dcnode *);
+static void dcdelete(struct dcnode *);
+static struct dcnode *dcfind(struct vnode *);
+static void dclru_add(struct dcnode *);
+static void dclru_sub(struct dcnode *);
+
+
+/*
+ * This is the loadable module wrapper.
+ */
+#include <sys/modctl.h>
+
+struct vfsops *dc_vfsops;
+
+static vfsdef_t vfw = {
+ VFSDEF_VERSION,
+ "dcfs",
+ dcinit,
+ 0,
+ NULL
+};
+
+/*
+ * Module linkage information for the kernel.
+ */
+extern struct mod_ops mod_fsops;
+
+static struct modlfs modlfs = {
+ &mod_fsops, "compressed filesystem", &vfw
+};
+
+static struct modlinkage modlinkage = {
+ MODREV_1, (void *)&modlfs, NULL
+};
+
+int
+_init()
+{
+ return (mod_install(&modlinkage));
+}
+
+int
+_info(struct modinfo *modinfop)
+{
+ return (mod_info(&modlinkage, modinfop));
+}
+
+
+static int dc_open(struct vnode **, int, struct cred *, caller_context_t *);
+static int dc_close(struct vnode *, int, int, offset_t,
+ struct cred *, caller_context_t *);
+static int dc_read(struct vnode *, struct uio *, int, struct cred *,
+ struct caller_context *);
+static int dc_getattr(struct vnode *, struct vattr *, int,
+ struct cred *, caller_context_t *);
+static int dc_setattr(struct vnode *, struct vattr *, int, struct cred *,
+ struct caller_context *);
+static int dc_access(struct vnode *, int, int,
+ struct cred *, caller_context_t *);
+static int dc_fsync(struct vnode *, int, struct cred *, caller_context_t *);
+static void dc_inactive(struct vnode *, struct cred *, caller_context_t *);
+static int dc_fid(struct vnode *, struct fid *, caller_context_t *);
+static int dc_seek(struct vnode *, offset_t, offset_t *, caller_context_t *);
+static int dc_frlock(struct vnode *, int, struct flock64 *, int, offset_t,
+ struct flk_callback *, struct cred *, caller_context_t *);
+static int dc_getpage(struct vnode *, offset_t, size_t, uint_t *,
+ struct page **, size_t, struct seg *, caddr_t, enum seg_rw,
+ struct cred *, caller_context_t *);
+static int dc_putpage(struct vnode *, offset_t, size_t, int,
+ struct cred *, caller_context_t *);
+static int dc_map(struct vnode *, offset_t, struct as *, caddr_t *, size_t,
+ uchar_t, uchar_t, uint_t, struct cred *, caller_context_t *);
+static int dc_addmap(struct vnode *, offset_t, struct as *, caddr_t, size_t,
+ uchar_t, uchar_t, uint_t, struct cred *, caller_context_t *);
+static int dc_delmap(struct vnode *, offset_t, struct as *, caddr_t, size_t,
+ uint_t, uint_t, uint_t, struct cred *, caller_context_t *);
+
+struct vnodeops *dc_vnodeops;
+
+const fs_operation_def_t dc_vnodeops_template[] = {
+ VOPNAME_OPEN, { .vop_open = dc_open },
+ VOPNAME_CLOSE, { .vop_close = dc_close },
+ VOPNAME_READ, { .vop_read = dc_read },
+ VOPNAME_GETATTR, { .vop_getattr = dc_getattr },
+ VOPNAME_SETATTR, { .vop_setattr = dc_setattr },
+ VOPNAME_ACCESS, { .vop_access = dc_access },
+ VOPNAME_FSYNC, { .vop_fsync = dc_fsync },
+ VOPNAME_INACTIVE, { .vop_inactive = dc_inactive },
+ VOPNAME_FID, { .vop_fid = dc_fid },
+ VOPNAME_SEEK, { .vop_seek = dc_seek },
+ VOPNAME_FRLOCK, { .vop_frlock = dc_frlock },
+ VOPNAME_GETPAGE, { .vop_getpage = dc_getpage },
+ VOPNAME_PUTPAGE, { .vop_putpage = dc_putpage },
+ VOPNAME_MAP, { .vop_map = dc_map },
+ VOPNAME_ADDMAP, { .vop_addmap = dc_addmap },
+ VOPNAME_DELMAP, { .vop_delmap = dc_delmap },
+ NULL, NULL
+};
+
+/*ARGSUSED*/
+static int
+dc_open(struct vnode **vpp, int flag, struct cred *cr, caller_context_t *ctp)
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dc_close(struct vnode *vp, int flag, int count, offset_t off,
+ struct cred *cr, caller_context_t *ctp)
+{
+ (void) cleanlocks(vp, ttoproc(curthread)->p_pid, 0);
+ cleanshares(vp, ttoproc(curthread)->p_pid);
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dc_read(struct vnode *vp, struct uio *uiop, int ioflag, struct cred *cr,
+ struct caller_context *ct)
+{
+ struct dcnode *dp = VTODC(vp);
+ size_t rdsize = MAX(MAXBSIZE, dp->dc_hdr->ch_blksize);
+ size_t fsize = dp->dc_hdr->ch_fsize;
+ int error;
+
+ /*
+ * Loop through file with segmap, decompression will occur
+ * in dc_getapage
+ */
+ do {
+ caddr_t base;
+ size_t n;
+ offset_t mapon;
+
+ /*
+ * read to end of block or file
+ */
+ mapon = uiop->uio_loffset & (rdsize - 1);
+ n = MIN(rdsize - mapon, uiop->uio_resid);
+ n = MIN(n, fsize - uiop->uio_loffset);
+ if (n == 0)
+ return (0); /* at EOF */
+
+ base = segmap_getmapflt(segkmap, vp, uiop->uio_loffset, n, 1,
+ S_READ);
+ error = uiomove(base + mapon, n, UIO_READ, uiop);
+ if (!error) {
+ uint_t flags;
+
+ if (n + mapon == rdsize || uiop->uio_loffset == fsize)
+ flags = SM_DONTNEED;
+ else
+ flags = 0;
+ error = segmap_release(segkmap, base, flags);
+ } else
+ (void) segmap_release(segkmap, base, 0);
+ } while (!error && uiop->uio_resid);
+
+ return (error);
+}
+
+static int
+dc_getattr(struct vnode *vp, struct vattr *vap, int flags,
+ cred_t *cred, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct vnode *subvp = dp->dc_subvp;
+ int error;
+
+ error = VOP_GETATTR(subvp, vap, flags, cred, ctp);
+
+ /* substitute uncompressed size */
+ vap->va_size = dp->dc_hdr->ch_fsize;
+ return (error);
+}
+
+static int
+dc_setattr(struct vnode *vp, struct vattr *vap, int flags, cred_t *cred,
+ caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct vnode *subvp = dp->dc_subvp;
+
+ return (VOP_SETATTR(subvp, vap, flags, cred, ctp));
+}
+
+static int
+dc_access(struct vnode *vp, int mode, int flags,
+ cred_t *cred, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct vnode *subvp = dp->dc_subvp;
+
+ return (VOP_ACCESS(subvp, mode, flags, cred, ctp));
+}
+
+/*ARGSUSED*/
+static int
+dc_fsync(vnode_t *vp, int syncflag, cred_t *cred, caller_context_t *ctp)
+{
+ return (0);
+}
+
+/*ARGSUSED*/
+static void
+dc_inactive(struct vnode *vp, cred_t *cr, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+
+ mutex_enter(&dctable_lock);
+ mutex_enter(&vp->v_lock);
+ ASSERT(vp->v_count >= 1);
+ if (--vp->v_count != 0) {
+ /*
+ * Somebody accessed the dcnode before we got a chance to
+ * remove it. They will remove it when they do a vn_rele.
+ */
+ mutex_exit(&vp->v_lock);
+ mutex_exit(&dctable_lock);
+ return;
+ }
+ mutex_exit(&vp->v_lock);
+
+ dcnode_free(dp);
+
+ mutex_exit(&dctable_lock);
+}
+
+static int
+dc_fid(struct vnode *vp, struct fid *fidp, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct vnode *subvp = dp->dc_subvp;
+
+ return (VOP_FID(subvp, fidp, ctp));
+}
+
+static int
+dc_seek(struct vnode *vp, offset_t oof, offset_t *noffp, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct vnode *subvp = dp->dc_subvp;
+
+ return (VOP_SEEK(subvp, oof, noffp, ctp));
+}
+
+static int
+dc_frlock(struct vnode *vp, int cmd, struct flock64 *bfp, int flag,
+ offset_t offset, struct flk_callback *flk_cbp,
+ cred_t *cr, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+
+ /*
+ * If file is being mapped, disallow frlock.
+ */
+ if (dp->dc_mapcnt > 0)
+ return (EAGAIN);
+
+ return (fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr, ctp));
+}
+
+/*ARGSUSED*/
+static int
+dc_getblock_miss(struct vnode *vp, offset_t off, size_t len, struct page **ppp,
+ struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct comphdr *hdr = dp->dc_hdr;
+ struct page *pp;
+ struct buf *bp;
+ caddr_t saddr;
+ off_t cblkno;
+ size_t rdoff, rdsize, dsize;
+ long xlen;
+ int error, zerr;
+
+ ASSERT(len == hdr->ch_blksize);
+ /*
+ * Get destination pages and make them addressable
+ */
+ pp = page_create_va(vp, off, len, PG_WAIT, seg, addr);
+ bp = pageio_setup(pp, len, vp, B_READ);
+ bp_mapin(bp);
+
+ /*
+ * read compressed data from subordinate vnode
+ */
+ saddr = kmem_cache_alloc(dp->dc_bufcache, KM_SLEEP);
+ cblkno = off / len;
+ rdoff = hdr->ch_blkmap[cblkno];
+ rdsize = hdr->ch_blkmap[cblkno + 1] - rdoff;
+ error = vn_rdwr(UIO_READ, dp->dc_subvp, saddr, rdsize, rdoff,
+ UIO_SYSSPACE, 0, 0, cr, NULL);
+ if (error)
+ goto cleanup;
+
+ /*
+ * Uncompress
+ */
+ dsize = len;
+ zerr = z_uncompress(bp->b_un.b_addr, &dsize, saddr, dp->dc_zmax);
+ if (zerr != Z_OK) {
+ error = EIO;
+ goto cleanup;
+ }
+
+ /*
+ * Handle EOF
+ */
+ xlen = hdr->ch_fsize - off;
+ if (xlen < len) {
+ bzero(bp->b_un.b_addr + xlen, len - xlen);
+ if (dsize != xlen)
+ error = EIO;
+ } else if (dsize != len)
+ error = EIO;
+
+ /*
+ * Clean up
+ */
+cleanup:
+ kmem_cache_free(dp->dc_bufcache, saddr);
+ pageio_done(bp);
+ *ppp = pp;
+ return (error);
+}
+
+static int
+dc_getblock(struct vnode *vp, offset_t off, size_t len, struct page **ppp,
+ struct seg *seg, caddr_t addr, enum seg_rw rw, struct cred *cr)
+{
+ struct page *pp, *plist = NULL;
+ offset_t pgoff;
+ int rdblk;
+
+ /*
+ * pvn_read_kluster() doesn't quite do what we want, since it
+ * thinks sub block reads are ok. Here we always decompress
+ * a full block.
+ */
+
+ /*
+ * Check page cache
+ */
+ rdblk = 0;
+ for (pgoff = off; pgoff < off + len; pgoff += PAGESIZE) {
+ pp = page_lookup(vp, pgoff, SE_EXCL);
+ if (pp == NULL) {
+ rdblk = 1;
+ break;
+ }
+ page_io_lock(pp);
+ page_add(&plist, pp);
+ plist = plist->p_next;
+ }
+ if (!rdblk) {
+ *ppp = plist;
+ return (0); /* all pages in cache */
+ }
+
+ /*
+ * Undo any locks so getblock_miss has an open field
+ */
+ if (plist != NULL)
+ pvn_io_done(plist);
+
+ return (dc_getblock_miss(vp, off, len, ppp, seg, addr, rw, cr));
+}
+
+/*ARGSUSED10*/
+static int
+dc_getpage(struct vnode *vp, offset_t off, size_t len, uint_t *protp,
+ struct page *pl[], size_t plsz, struct seg *seg, caddr_t addr,
+ enum seg_rw rw, struct cred *cr, caller_context_t *ctp)
+{
+ struct dcnode *dp = VTODC(vp);
+ struct comphdr *hdr = dp->dc_hdr;
+ struct page *pp, *plist = NULL;
+ caddr_t vp_baddr;
+ offset_t vp_boff, vp_bend;
+ size_t bsize = hdr->ch_blksize;
+ int nblks, error;
+
+ /* does not support write */
+ if (rw == S_WRITE) {
+ panic("write attempt on compressed file");
+ /*NOTREACHED*/
+ }
+
+ if (protp)
+ *protp = PROT_ALL;
+ /*
+ * We don't support asynchronous operation at the moment, so
+ * just pretend we did it. If the pages are ever actually
+ * needed, they'll get brought in then.
+ */
+ if (pl == NULL)
+ return (0);
+
+ /*
+ * Calc block start and end offsets
+ */
+ vp_boff = rounddown(off, bsize);
+ vp_bend = roundup(off + len, bsize);
+ vp_baddr = (caddr_t)rounddown((uintptr_t)addr, bsize);
+
+ nblks = (vp_bend - vp_boff) / bsize;
+ while (nblks--) {
+ error = dc_getblock(vp, vp_boff, bsize, &pp, seg, vp_baddr,
+ rw, cr);
+ page_list_concat(&plist, &pp);
+ vp_boff += bsize;
+ vp_baddr += bsize;
+ }
+ if (!error)
+ pvn_plist_init(plist, pl, plsz, off, len, rw);
+ else
+ pvn_read_done(plist, B_ERROR);
+ return (error);
+}
+
+/*
+ * This function should never be called. We need to have it to pass
+ * it as an argument to other functions.
+ */
+/*ARGSUSED*/
+static int
+dc_putapage(struct vnode *vp, struct page *pp, u_offset_t *offp, size_t *lenp,
+ int flags, struct cred *cr)
+{
+ /* should never happen */
+ cmn_err(CE_PANIC, "dcfs: dc_putapage: dirty page");
+ /*NOTREACHED*/
+ return (0);
+}
+
+
+/*
+ * The only flags we support are B_INVAL, B_FREE and B_DONTNEED.
+ * B_INVAL is set by:
+ *
+ * 1) the MC_SYNC command of memcntl(2) to support the MS_INVALIDATE flag.
+ * 2) the MC_ADVISE command of memcntl(2) with the MADV_DONTNEED advice
+ * which translates to an MC_SYNC with the MS_INVALIDATE flag.
+ *
+ * The B_FREE (as well as the B_DONTNEED) flag is set when the
+ * MADV_SEQUENTIAL advice has been used. VOP_PUTPAGE is invoked
+ * from SEGVN to release pages behind a pagefault.
+ */
+/*ARGSUSED5*/
+static int
+dc_putpage(struct vnode *vp, offset_t off, size_t len, int flags,
+ struct cred *cr, caller_context_t *ctp)
+{
+ int error = 0;
+
+ if (vp->v_count == 0) {
+ panic("dcfs_putpage: bad v_count");
+ /*NOTREACHED*/
+ }
+
+ if (vp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ if (!vn_has_cached_data(vp)) /* no pages mapped */
+ return (0);
+
+ if (len == 0) /* from 'off' to EOF */
+ error = pvn_vplist_dirty(vp, off, dc_putapage, flags, cr);
+ else {
+ offset_t io_off;
+ se_t se = (flags & (B_INVAL | B_FREE)) ? SE_EXCL : SE_SHARED;
+
+ for (io_off = off; io_off < off + len; io_off += PAGESIZE) {
+ page_t *pp;
+
+ /*
+ * We insist on getting the page only if we are
+ * about to invalidate, free or write it and
+ * the B_ASYNC flag is not set.
+ */
+ if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0))
+ pp = page_lookup(vp, io_off, se);
+ else
+ pp = page_lookup_nowait(vp, io_off, se);
+
+ if (pp == NULL)
+ continue;
+ /*
+ * Normally pvn_getdirty() should return 0, which
+ * impies that it has done the job for us.
+ * The shouldn't-happen scenario is when it returns 1.
+ * This means that the page has been modified and
+ * needs to be put back.
+ * Since we can't write to a dcfs compressed file,
+ * we fake a failed I/O and force pvn_write_done()
+ * to destroy the page.
+ */
+ if (pvn_getdirty(pp, flags) == 1) {
+ cmn_err(CE_NOTE, "dc_putpage: dirty page");
+ pvn_write_done(pp, flags |
+ B_ERROR | B_WRITE | B_INVAL | B_FORCE);
+ }
+ }
+ }
+ return (error);
+}
+
+static int
+dc_map(struct vnode *vp, offset_t off, struct as *as, caddr_t *addrp,
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
+ struct cred *cred, caller_context_t *ctp)
+{
+ struct vattr vattr;
+ struct segvn_crargs vn_a;
+ int error;
+
+ if (vp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ if (off < (offset_t)0 || (offset_t)(off + len) < (offset_t)0)
+ return (ENXIO);
+
+ /*
+ * If file is being locked, disallow mapping.
+ */
+ if (error = VOP_GETATTR(VTODC(vp)->dc_subvp, &vattr, 0, cred, ctp))
+ return (error);
+ if (vn_has_mandatory_locks(vp, vattr.va_mode))
+ return (EAGAIN);
+
+ as_rangelock(as);
+
+ if ((flags & MAP_FIXED) == 0) {
+ map_addr(addrp, len, off, 1, flags);
+ if (*addrp == NULL) {
+ as_rangeunlock(as);
+ return (ENOMEM);
+ }
+ } else {
+ /*
+ * User specified address - blow away any previous mappings
+ */
+ (void) as_unmap(as, *addrp, len);
+ }
+
+ vn_a.vp = vp;
+ vn_a.offset = off;
+ vn_a.type = flags & MAP_TYPE;
+ vn_a.prot = prot;
+ vn_a.maxprot = maxprot;
+ vn_a.flags = flags & ~MAP_TYPE;
+ vn_a.cred = cred;
+ vn_a.amp = NULL;
+ vn_a.szc = 0;
+ vn_a.lgrp_mem_policy_flags = 0;
+
+ error = as_map(as, *addrp, len, segvn_create, &vn_a);
+ as_rangeunlock(as);
+ return (error);
+}
+
+/*ARGSUSED*/
+static int
+dc_addmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
+ size_t len, uchar_t prot, uchar_t maxprot, uint_t flags,
+ struct cred *cr, caller_context_t *ctp)
+{
+ struct dcnode *dp;
+
+ if (vp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ dp = VTODC(vp);
+ mutex_enter(&dp->dc_lock);
+ dp->dc_mapcnt += btopr(len);
+ mutex_exit(&dp->dc_lock);
+ return (0);
+}
+
+/*ARGSUSED*/
+static int
+dc_delmap(struct vnode *vp, offset_t off, struct as *as, caddr_t addr,
+ size_t len, uint_t prot, uint_t maxprot, uint_t flags,
+ struct cred *cr, caller_context_t *ctp)
+{
+ struct dcnode *dp;
+
+ if (vp->v_flag & VNOMAP)
+ return (ENOSYS);
+
+ dp = VTODC(vp);
+ mutex_enter(&dp->dc_lock);
+ dp->dc_mapcnt -= btopr(len);
+ ASSERT(dp->dc_mapcnt >= 0);
+ mutex_exit(&dp->dc_lock);
+ return (0);
+}
+
+/*
+ * Constructor/destructor routines for dcnodes
+ */
+/*ARGSUSED1*/
+static int
+dcnode_constructor(void *buf, void *cdrarg, int kmflags)
+{
+ struct dcnode *dp = buf;
+ struct vnode *vp;
+
+ ASSERT(!(kmflags & KM_NOSLEEP));
+
+ vp = vn_alloc(KM_SLEEP);
+ vp->v_data = (caddr_t)dp;
+ vp->v_type = VREG;
+ vp->v_flag = VNOSWAP;
+ vp->v_vfsp = &dc_vfs;
+ vn_setops(vp, dc_vnodeops);
+ vn_exists(vp);
+
+ dp->dc_vp = vp;
+ mutex_init(&dp->dc_lock, NULL, MUTEX_DEFAULT, NULL);
+ dp->dc_mapcnt = 0;
+ dp->dc_lrunext = dp->dc_lruprev = NULL;
+ return (0);
+}
+
+/*ARGSUSED*/
+static void
+dcnode_destructor(void *buf, void *cdrarg)
+{
+ struct dcnode *dp = buf;
+ struct vnode *vp = DCTOV(dp);
+
+ mutex_destroy(&dp->dc_lock);
+
+ VERIFY(dp->dc_hdr == NULL);
+ VERIFY(dp->dc_subvp == NULL);
+ vn_invalid(vp);
+ vn_free(vp);
+}
+
+static struct dcnode *
+dcnode_alloc(void)
+{
+ struct dcnode *dp;
+
+ /*
+ * If the free list is above DCLRUSIZE
+ * re-use one from it
+ */
+ mutex_enter(&dctable_lock);
+ if (dclru_len < DCLRUSIZE) {
+ mutex_exit(&dctable_lock);
+ dp = kmem_cache_alloc(dcnode_cache, KM_SLEEP);
+ } else {
+ ASSERT(dclru != NULL);
+ dp = dclru;
+ dclru_sub(dp);
+ dcdelete(dp);
+ mutex_exit(&dctable_lock);
+ dcnode_recycle(dp);
+ }
+ return (dp);
+}
+
+static void
+dcnode_free(struct dcnode *dp)
+{
+ struct vnode *vp = DCTOV(dp);
+
+ ASSERT(MUTEX_HELD(&dctable_lock));
+
+ /*
+ * If no cached pages, no need to put it on lru
+ */
+ if (!vn_has_cached_data(vp)) {
+ dcdelete(dp);
+ dcnode_recycle(dp);
+ kmem_cache_free(dcnode_cache, dp);
+ return;
+ }
+
+ /*
+ * Add to lru, if it's over the limit, free from head
+ */
+ dclru_add(dp);
+ if (dclru_len > DCLRUSIZE) {
+ dp = dclru;
+ dclru_sub(dp);
+ dcdelete(dp);
+ dcnode_recycle(dp);
+ kmem_cache_free(dcnode_cache, dp);
+ }
+}
+
+static void
+dcnode_recycle(struct dcnode *dp)
+{
+ struct vnode *vp;
+
+ vp = DCTOV(dp);
+
+ VN_RELE(dp->dc_subvp);
+ dp->dc_subvp = NULL;
+ (void) pvn_vplist_dirty(vp, 0, dc_putapage, B_INVAL, NULL);
+ kmem_free(dp->dc_hdr, dp->dc_hdrsize);
+ dp->dc_hdr = NULL;
+ dp->dc_hdrsize = dp->dc_zmax = 0;
+ dp->dc_bufcache = NULL;
+ dp->dc_mapcnt = 0;
+ vn_reinit(vp);
+ vp->v_type = VREG;
+ vp->v_flag = VNOSWAP;
+ vp->v_vfsp = &dc_vfs;
+}
+
+static int
+dcinit(int fstype, char *name)
+{
+ static const fs_operation_def_t dc_vfsops_template[] = {
+ NULL, NULL
+ };
+ int error;
+ major_t dev;
+
+ error = vfs_setfsops(fstype, dc_vfsops_template, &dc_vfsops);
+ if (error) {
+ cmn_err(CE_WARN, "dcinit: bad vfs ops template");
+ return (error);
+ }
+ VFS_INIT(&dc_vfs, dc_vfsops, NULL);
+ dc_vfs.vfs_flag = VFS_RDONLY;
+ dc_vfs.vfs_fstype = fstype;
+ if ((dev = getudev()) == (major_t)-1)
+ dev = 0;
+ dcdev = makedevice(dev, 0);
+ dc_vfs.vfs_dev = dcdev;
+
+ error = vn_make_ops(name, dc_vnodeops_template, &dc_vnodeops);
+ if (error != 0) {
+ (void) vfs_freevfsops_by_type(fstype);
+ cmn_err(CE_WARN, "dcinit: bad vnode ops template");
+ return (error);
+ }
+
+ mutex_init(&dctable_lock, NULL, MUTEX_DEFAULT, NULL);
+ mutex_init(&dccache_lock, NULL, MUTEX_DEFAULT, NULL);
+ dcnode_cache = kmem_cache_create("dcnode_cache", sizeof (struct dcnode),
+ 0, dcnode_constructor, dcnode_destructor, NULL, NULL, NULL, 0);
+
+ return (0);
+}
+
+/*
+ * Return shadow vnode with the given vp as its subordinate
+ */
+struct vnode *
+decompvp(struct vnode *vp, cred_t *cred, caller_context_t *ctp)
+{
+ struct dcnode *dp, *ndp;
+ struct comphdr thdr, *hdr;
+ struct kmem_cache **cpp;
+ struct vattr vattr;
+ size_t hdrsize, bsize;
+ int error;
+
+ /*
+ * See if we have an existing shadow
+ * If none, we have to manufacture one
+ */
+ mutex_enter(&dctable_lock);
+ dp = dcfind(vp);
+ mutex_exit(&dctable_lock);
+ if (dp != NULL)
+ return (DCTOV(dp));
+
+ /*
+ * Make sure it's a valid compressed file
+ */
+ hdr = &thdr;
+ error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, sizeof (struct comphdr), 0,
+ UIO_SYSSPACE, 0, 0, cred, NULL);
+ if (error || hdr->ch_magic != CH_MAGIC ||
+ hdr->ch_version != CH_VERSION || hdr->ch_algorithm != CH_ALG_ZLIB ||
+ hdr->ch_fsize == 0 || hdr->ch_blksize < PAGESIZE ||
+ hdr->ch_blksize > ptob(DCCACHESIZE) ||
+ (hdr->ch_blksize & (hdr->ch_blksize - 1)) != 0)
+ return (NULL);
+
+ /* get underlying file size */
+ if (VOP_GETATTR(vp, &vattr, 0, cred, ctp) != 0)
+ return (NULL);
+
+ /*
+ * Re-read entire header
+ */
+ hdrsize = hdr->ch_blkmap[0] + sizeof (uint64_t);
+ hdr = kmem_alloc(hdrsize, KM_SLEEP);
+ error = vn_rdwr(UIO_READ, vp, (caddr_t)hdr, hdrsize, 0, UIO_SYSSPACE,
+ 0, 0, cred, NULL);
+ if (error) {
+ kmem_free(hdr, hdrsize);
+ return (NULL);
+ }
+
+ /*
+ * add extra blkmap entry to make dc_getblock()'s
+ * life easier
+ */
+ bsize = hdr->ch_blksize;
+ hdr->ch_blkmap[((hdr->ch_fsize-1) / bsize) + 1] = vattr.va_size;
+
+ ndp = dcnode_alloc();
+ ndp->dc_subvp = vp;
+ VN_HOLD(vp);
+ ndp->dc_hdr = hdr;
+ ndp->dc_hdrsize = hdrsize;
+
+ /*
+ * Allocate kmem cache if none there already
+ */
+ ndp->dc_zmax = ZMAXBUF(bsize);
+ cpp = &dcbuf_cache[btop(bsize)];
+ mutex_enter(&dccache_lock);
+ if (*cpp == NULL)
+ *cpp = kmem_cache_create("dcbuf_cache", ndp->dc_zmax, 0, NULL,
+ NULL, NULL, NULL, NULL, 0);
+ mutex_exit(&dccache_lock);
+ ndp->dc_bufcache = *cpp;
+
+ /*
+ * Recheck table in case someone else created shadow
+ * while we were blocked above.
+ */
+ mutex_enter(&dctable_lock);
+ dp = dcfind(vp);
+ if (dp != NULL) {
+ mutex_exit(&dctable_lock);
+ dcnode_recycle(ndp);
+ kmem_cache_free(dcnode_cache, ndp);
+ return (DCTOV(dp));
+ }
+ dcinsert(ndp);
+ mutex_exit(&dctable_lock);
+
+ return (DCTOV(ndp));
+}
+
+
+/*
+ * dcnode lookup table
+ * These routines maintain a table of dcnodes hashed by their
+ * subordinate vnode so that they can be found if they already
+ * exist in the vnode cache
+ */
+
+/*
+ * Put a dcnode in the table.
+ */
+static void
+dcinsert(struct dcnode *newdp)
+{
+ int idx = DCHASH(newdp->dc_subvp);
+
+ ASSERT(MUTEX_HELD(&dctable_lock));
+ newdp->dc_hash = dctable[idx];
+ dctable[idx] = newdp;
+}
+
+/*
+ * Remove a dcnode from the hash table.
+ */
+void
+dcdelete(struct dcnode *deldp)
+{
+ int idx = DCHASH(deldp->dc_subvp);
+ struct dcnode *dp, *prevdp;
+
+ ASSERT(MUTEX_HELD(&dctable_lock));
+ dp = dctable[idx];
+ if (dp == deldp)
+ dctable[idx] = dp->dc_hash;
+ else {
+ for (prevdp = dp, dp = dp->dc_hash; dp != NULL;
+ prevdp = dp, dp = dp->dc_hash) {
+ if (dp == deldp) {
+ prevdp->dc_hash = dp->dc_hash;
+ break;
+ }
+ }
+ }
+ ASSERT(dp != NULL);
+}
+
+/*
+ * Find a shadow vnode in the dctable hash list.
+ */
+static struct dcnode *
+dcfind(struct vnode *vp)
+{
+ struct dcnode *dp;
+
+ ASSERT(MUTEX_HELD(&dctable_lock));
+ for (dp = dctable[DCHASH(vp)]; dp != NULL; dp = dp->dc_hash)
+ if (dp->dc_subvp == vp) {
+ VN_HOLD(DCTOV(dp));
+ if (dp->dc_lrunext)
+ dclru_sub(dp);
+ return (dp);
+ }
+ return (NULL);
+}
+
+#ifdef DEBUG
+static int
+dclru_count(void)
+{
+ struct dcnode *dp;
+ int i = 0;
+
+ if (dclru == NULL)
+ return (0);
+ for (dp = dclru; dp->dc_lrunext != dclru; dp = dp->dc_lrunext)
+ i++;
+ return (i + 1);
+}
+#endif
+
+static void
+dclru_add(struct dcnode *dp)
+{
+ /*
+ * Add to dclru as double-link chain
+ */
+ ASSERT(MUTEX_HELD(&dctable_lock));
+ if (dclru == NULL) {
+ dclru = dp;
+ dp->dc_lruprev = dp->dc_lrunext = dp;
+ } else {
+ struct dcnode *last = dclru->dc_lruprev;
+
+ dclru->dc_lruprev = dp;
+ last->dc_lrunext = dp;
+ dp->dc_lruprev = last;
+ dp->dc_lrunext = dclru;
+ }
+ dclru_len++;
+ ASSERT(dclru_len == dclru_count());
+}
+
+static void
+dclru_sub(struct dcnode *dp)
+{
+ ASSERT(MUTEX_HELD(&dctable_lock));
+ dp->dc_lrunext->dc_lruprev = dp->dc_lruprev;
+ dp->dc_lruprev->dc_lrunext = dp->dc_lrunext;
+ if (dp == dclru)
+ dclru = dp->dc_lrunext == dp ? NULL : dp->dc_lrunext;
+ dp->dc_lrunext = dp->dc_lruprev = NULL;
+ dclru_len--;
+ ASSERT(dclru_len == dclru_count());
+}
diff --git a/usr/src/uts/common/fs/nfs/nfs_dlinet.c b/usr/src/uts/common/fs/nfs/nfs_dlinet.c
index 253312588e..632a5b29a7 100644
--- a/usr/src/uts/common/fs/nfs/nfs_dlinet.c
+++ b/usr/src/uts/common/fs/nfs/nfs_dlinet.c
@@ -951,7 +951,7 @@ getfile(char *fileid,
}
/*
- * If the boot property "bootp-response" exists, then inetboot performed a
+ * If the boot property "bootp-response" exists, then OBP performed a
* successful DHCP lease acquisition for us and left the resultant ACK packet
* encoded at that location.
*
@@ -968,8 +968,6 @@ dhcpinit(void)
DHCP_OPT *doptp;
TIUSER *tiptr;
struct sockaddr_in *sin;
- int true_dhcacklen;
- char *ackp;
static int once_only = 0;
if (once_only == 1) {
@@ -981,45 +979,24 @@ dhcpinit(void)
return (-1);
}
- ackp = (char *)(dhcack + IFNAMSIZ);
- true_dhcacklen = strlen(ackp);
-
- /*
- * Since we expect the "bootp-response" property to have
- * been encoded via octet_to_hexascii(), its length should
- * always be even.
- */
- ASSERT((true_dhcacklen % 2) == 0);
-
if (dldebug) {
printf("dhcp: dhcack %p, len %d\n", (void *)dhcack,
- true_dhcacklen + IFNAMSIZ);
+ dhcacklen);
}
pl = kmem_alloc(sizeof (PKT_LIST), KM_SLEEP);
- pl->len = true_dhcacklen / 2;
+ pl->len = dhcacklen;
pl->pkt = kmem_alloc(pl->len, KM_SLEEP);
+ bcopy(dhcack, pl->pkt, dhcacklen);
/*
- * Store our interface name in the reserved block at the
- * head of our packet. For x86, ifname is not initialized
+ * For x86, ifname is not initialized
* in the netinstall case and dhcack interface name is
* set in strplumb(). So we only copy the name if ifname
* is set properly.
*/
if (ifname[0])
- (void) strncpy(dhcack, ifname, IFNAMSIZ - 1);
-
- /* skip over the interface name section */
- if (hexascii_to_octet(ackp, true_dhcacklen, (uchar_t *)pl->pkt,
- &(pl->len)) != 0) {
- cmn_err(CE_WARN,
- "dhcp: boot dhcp cache is corrupted.");
- kmem_free(pl->pkt, pl->len);
- kmem_free(pl, sizeof (PKT_LIST));
- pl = NULL;
- return (-1);
- }
+ (void) strlcpy(dhcifname, ifname, sizeof (dhcifname));
/* remember the server_ip in dhcack */
bcopy((uchar_t *)pl->pkt + 20, dhcp_server_ip, 4);
diff --git a/usr/src/uts/common/fs/ufs/ufs_filio.c b/usr/src/uts/common/fs/ufs/ufs_filio.c
index 04a68104ff..c02fd89748 100644
--- a/usr/src/uts/common/fs/ufs/ufs_filio.c
+++ b/usr/src/uts/common/fs/ufs/ufs_filio.c
@@ -693,3 +693,24 @@ ufs_fio_holey(vnode_t *vp, int cmd, offset_t *off)
*off = noff;
return (error);
}
+
+int
+ufs_mark_compressed(struct vnode *vp)
+{
+ struct inode *ip = VTOI(vp);
+ struct ufsvfs *ufsvfsp = ip->i_ufsvfs;
+
+ if (vp->v_type != VREG)
+ return (EINVAL);
+
+ rw_enter(&ip->i_contents, RW_WRITER);
+ ip->i_cflags |= ICOMPRESS;
+ TRANS_INODE(ufsvfsp, ip);
+ ip->i_flag |= (ICHG|ISEQ);
+ ip->i_seq++;
+ if (!TRANS_ISTRANS(ufsvfsp))
+ ufs_iupdat(ip, I_ASYNC);
+ rw_exit(&ip->i_contents);
+
+ return (0);
+}
diff --git a/usr/src/uts/common/fs/ufs/ufs_vnops.c b/usr/src/uts/common/fs/ufs/ufs_vnops.c
index 1274789e2d..5f4136afa3 100644
--- a/usr/src/uts/common/fs/ufs/ufs_vnops.c
+++ b/usr/src/uts/common/fs/ufs/ufs_vnops.c
@@ -98,6 +98,8 @@
#include <fs/fs_subr.h>
+#include <sys/fs/decomp.h>
+
static struct instats ins;
static int ufs_getpage_ra(struct vnode *, u_offset_t, struct seg *, caddr_t);
@@ -177,7 +179,6 @@ static int ufs_getsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
caller_context_t *);
static int ufs_setsecattr(struct vnode *, vsecattr_t *, int, struct cred *,
caller_context_t *);
-
extern int as_map_locked(struct as *, caddr_t, size_t, int ((*)()), void *);
/*
@@ -860,7 +861,7 @@ wrip(struct inode *ip, struct uio *uio, int ioflag, struct cred *cr)
*/
if ((type == IFSHAD) ||
(rw_owner(&ufsvfsp->vfs_dqrwlock) == curthread)) {
- do_dqrwlock = 0;
+ do_dqrwlock = 0;
} else {
do_dqrwlock = 1;
}
@@ -1508,7 +1509,7 @@ out:
*/
if (ioflag & FRSYNC) {
if (TRANS_ISTRANS(ufsvfsp) && ((ip->i_mode & IFMT) == IFDIR)) {
- doupdate = 0;
+ doupdate = 0;
}
if (doupdate) {
if ((ioflag & FSYNC) ||
@@ -1929,11 +1930,53 @@ ufs_ioctl(
return (EFAULT);
return (0);
+ case _FIO_COMPRESSED:
+ {
+ /*
+ * This is a project private ufs ioctl() to mark
+ * the inode as that belonging to a compressed
+ * file. This is used to mark individual
+ * files in a miniroot archive for SPARC boot.
+ * The files compressed in this manner are
+ * automatically decompressed by the dcfs filesystem
+ * (via an interception in ufs_lookup - see decompvp())
+ * which is layered on top of ufs on a system running
+ * the new archive booted SPARC system. See
+ * uts/common/fs/dcfs for details.
+ * This ioctl only marks the file as compressed - the
+ * actual compression is done by fiocompress (a
+ * userland utility) which invokes this ioctl().
+ */
+ struct inode *ip = VTOI(vp);
+
+ error = ufs_lockfs_begin(ufsvfsp, &ulp,
+ ULOCKFS_SETATTR_MASK);
+ if (error)
+ return (error);
+
+ if (ulp) {
+ TRANS_BEGIN_ASYNC(ufsvfsp, TOP_IUPDAT,
+ TOP_IUPDAT_SIZE(ip));
+ }
+
+ error = ufs_mark_compressed(vp);
+
+ if (ulp) {
+ TRANS_END_ASYNC(ufsvfsp, TOP_IUPDAT,
+ TOP_IUPDAT_SIZE(ip));
+ ufs_lockfs_end(ulp);
+ }
+
+ return (error);
+
+ }
+
default:
return (ENOTTY);
}
}
+
/* ARGSUSED */
static int
ufs_getattr(struct vnode *vp, struct vattr *vap, int flags,
@@ -2812,6 +2855,18 @@ fastpath:
error = ENOSYS;
else
*vpp = newvp;
+ } else if (ip->i_cflags & ICOMPRESS) {
+ struct vnode *newvp;
+
+ /*
+ * Compressed file, substitute dcfs vnode
+ */
+ newvp = decompvp(*vpp, cr, ct);
+ VN_RELE(*vpp);
+ if (newvp == NULL)
+ error = ENOSYS;
+ else
+ *vpp = newvp;
}
}
if (ulp) {
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index 4440d7b13b..d55dee5ae3 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -859,6 +859,9 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
znode_t *zp = NULL;
vnode_t *vp = NULL;
char *zfs_bootpath;
+#if defined(_OBP)
+ int proplen;
+#endif
ASSERT(vfsp);
@@ -870,6 +873,18 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
if (zfsrootdone++)
return (EBUSY);
+#if defined(_OBP)
+ proplen = BOP_GETPROPLEN(bootops, "zfs-bootfs");
+ if (proplen == 0)
+ return (EIO);
+ zfs_bootpath = kmem_zalloc(proplen, KM_SLEEP);
+ if (BOP_GETPROP(bootops, "zfs-bootfs", zfs_bootpath) == -1) {
+ kmem_free(zfs_bootpath, proplen);
+ return (EIO);
+ }
+ error = parse_bootpath(zfs_bootpath, rootfs.bo_name);
+ kmem_free(zfs_bootpath, proplen);
+#else
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
DDI_PROP_DONTPASS, "zfs-bootfs", &zfs_bootpath) !=
DDI_SUCCESS)
@@ -877,6 +892,7 @@ zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
error = parse_bootpath(zfs_bootpath, rootfs.bo_name);
ddi_prop_free(zfs_bootpath);
+#endif
if (error)
return (error);
diff --git a/usr/src/uts/common/inet/ip/ip_if.c b/usr/src/uts/common/inet/ip/ip_if.c
index dba1cf5e00..eb52e897e9 100644
--- a/usr/src/uts/common/inet/ip/ip_if.c
+++ b/usr/src/uts/common/inet/ip/ip_if.c
@@ -19971,11 +19971,11 @@ ill_dl_up(ill_t *ill, ipif_t *ipif, mblk_t *mp, queue_t *q)
* and miniroot network configuration is driven from userland
* these things still need to be set. This situation can be detected
* by comparing the interface being configured here to the one
- * dhcack was set to reference by the boot loader. Once sysid is
+ * dhcifname was set to reference by the boot loader. Once sysid is
* converted to use dhcp_ipc_getinfo() this call can go away.
*/
- if ((ipif->ipif_flags & IPIF_DHCPRUNNING) && (dhcack != NULL) &&
- (strcmp(ill->ill_name, dhcack) == 0) &&
+ if ((ipif->ipif_flags & IPIF_DHCPRUNNING) &&
+ (strcmp(ill->ill_name, dhcifname) == 0) &&
(strlen(srpc_domain) == 0)) {
if (dhcpinit() != 0)
cmn_err(CE_WARN, "no cached dhcp response");
diff --git a/usr/src/uts/common/io/ramdisk.c b/usr/src/uts/common/io/ramdisk.c
index 66ea7fa77a..36ad87c369 100644
--- a/usr/src/uts/common/io/ramdisk.c
+++ b/usr/src/uts/common/io/ramdisk.c
@@ -391,6 +391,7 @@ rd_phys_free(page_t **ppa, pgcnt_t npages)
static void
rd_unmap_window(rd_devstate_t *rsp)
{
+ ASSERT(rsp->rd_window_obp == 0);
if (rsp->rd_window_base != RD_WINDOW_NOT_MAPPED) {
hat_unload(kas.a_hat, rsp->rd_window_virt, rsp->rd_window_size,
HAT_UNLOAD_UNLOCK);
@@ -574,7 +575,7 @@ rd_dealloc_resources(rd_devstate_t *rsp)
char namebuf[RD_NAME_LEN + 5];
dev_t fulldev;
- if (rsp->rd_window_virt != NULL) {
+ if (rsp->rd_window_obp == 0 && rsp->rd_window_virt != NULL) {
if (rsp->rd_window_base != RD_WINDOW_NOT_MAPPED) {
rd_unmap_window(rsp);
}
@@ -624,7 +625,7 @@ rd_dealloc_resources(rd_devstate_t *rsp)
* to a ramdisk.
*/
static rd_devstate_t *
-rd_alloc_resources(char *name, size_t size, dev_info_t *dip)
+rd_alloc_resources(char *name, uint_t addr, size_t size, dev_info_t *dip)
{
minor_t minor;
rd_devstate_t *rsp;
@@ -648,12 +649,20 @@ rd_alloc_resources(char *name, size_t size, dev_info_t *dip)
* Allocate virtual window onto ramdisk.
*/
mutex_init(&rsp->rd_device_lock, NULL, MUTEX_DRIVER, NULL);
- rsp->rd_window_base = RD_WINDOW_NOT_MAPPED;
- rsp->rd_window_size = PAGESIZE;
- rsp->rd_window_virt = vmem_alloc(heap_arena,
- rsp->rd_window_size, VM_SLEEP);
- if (rsp->rd_window_virt == NULL) {
- goto create_failed;
+ if (addr == 0) {
+ rsp->rd_window_obp = 0;
+ rsp->rd_window_base = RD_WINDOW_NOT_MAPPED;
+ rsp->rd_window_size = PAGESIZE;
+ rsp->rd_window_virt = vmem_alloc(heap_arena,
+ rsp->rd_window_size, VM_SLEEP);
+ if (rsp->rd_window_virt == NULL) {
+ goto create_failed;
+ }
+ } else {
+ rsp->rd_window_obp = 1;
+ rsp->rd_window_base = 0;
+ rsp->rd_window_size = size;
+ rsp->rd_window_virt = (caddr_t)((ulong_t)addr);
}
/*
@@ -779,7 +788,7 @@ rd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
{
char *name;
rd_existing_t *ep = NULL;
- uint_t nep, i;
+ uint_t obpaddr = 0, nep, i;
size_t size = 0;
rd_devstate_t *rsp;
@@ -825,32 +834,39 @@ rd_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
* property; get and check it.
*/
if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, RD_EXISTING_PROP_NAME,
- (uchar_t **)&ep, &nep) != DDI_SUCCESS) {
- cmn_err(CE_CONT,
- "%s: " RD_EXISTING_PROP_NAME
- " property missing\n", name);
- goto attach_failed;
- }
- if (nep == 0 || (nep % sizeof (*ep)) != 0) {
- cmn_err(CE_CONT,
- "%s: " RD_EXISTING_PROP_NAME
- " illegal size\n", name);
+ DDI_PROP_DONTPASS, OBP_EXISTING_PROP_NAME,
+ (uchar_t **)&ep, &nep) == DDI_SUCCESS) {
+
+ if (nep == 0 || (nep % sizeof (*ep)) != 0) {
+ cmn_err(CE_CONT,
+ "%s: " OBP_EXISTING_PROP_NAME
+ " illegal size\n", name);
+ goto attach_failed;
+ }
+ nep /= sizeof (*ep);
+
+ /*
+ * Calculate the size of the ramdisk.
+ */
+ for (i = 0; i < nep; ++i) {
+ size += ep[i].size;
+ }
+ } else if ((obpaddr = ddi_prop_get_int(DDI_DEV_T_ANY,
+ dip, DDI_PROP_DONTPASS, OBP_ADDRESS_PROP_NAME,
+ 0)) != 0) {
+
+ size = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
+ DDI_PROP_DONTPASS, OBP_SIZE_PROP_NAME, 0);
+ } else {
+ cmn_err(CE_CONT, "%s: missing OBP properties\n",
+ name);
goto attach_failed;
}
- nep /= sizeof (*ep);
-
- /*
- * Calculate the size of the ramdisk.
- */
- for (i = 0; i < nep; ++i) {
- size += ep[i].size;
- }
/*
* Allocate driver resources for the ramdisk.
*/
- if ((rsp = rd_alloc_resources(name, size,
+ if ((rsp = rd_alloc_resources(name, obpaddr, size,
dip)) == NULL) {
goto attach_failed;
}
@@ -1164,7 +1180,7 @@ rd_create_disk(dev_t dev, struct rd_ioctl *urip, int mode, int *rvalp)
return (EEXIST);
}
- rsp = rd_alloc_resources(kri.ri_name, size, rd_dip);
+ rsp = rd_alloc_resources(kri.ri_name, 0, size, rd_dip);
if (rsp == NULL) {
mutex_exit(&rd_lock);
return (EAGAIN);
@@ -1337,7 +1353,7 @@ extern struct mod_ops mod_driverops;
static struct modldrv modldrv = {
&mod_driverops,
- "ramdisk driver v%I%",
+ "ramdisk driver",
&rd_ops
};
diff --git a/usr/src/uts/common/io/strplumb.c b/usr/src/uts/common/io/strplumb.c
index 8243f9263f..80f4850622 100644
--- a/usr/src/uts/common/io/strplumb.c
+++ b/usr/src/uts/common/io/strplumb.c
@@ -96,7 +96,7 @@ int strplumbdebug = 0;
/*
* Module linkage information for the kernel.
*/
-#define STRPLUMB_IDENT "STREAMS Plumbing Module v%I%"
+#define STRPLUMB_IDENT "STREAMS Plumbing Module"
static struct modlmisc modlmisc = {
&mod_miscops,
@@ -339,10 +339,22 @@ resolve_boot_path(void)
dev_info_t *dip;
const char *driver;
int instance;
+#ifdef _OBP
+ char stripped_path[OBP_MAXPATHLEN];
+#endif
+#ifdef _OBP
+ /*
+ * OBP passes options e.g, "net:dhcp"
+ * remove them here
+ */
+ if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0) {
+ prom_strip_options(rootfs.bo_name, stripped_path);
+ devpath = stripped_path;
+ }
+#else
if (strncmp(rootfs.bo_fstype, "nfs", 3) == 0)
devpath = rootfs.bo_name;
-#ifndef __sparc
else
devpath = strplumb_get_netdev_path();
#endif
@@ -614,7 +626,7 @@ done:
/* multiboot: diskless boot interface discovery */
-#ifndef __sparc
+#ifndef _OBP
static uchar_t boot_macaddr[16];
static int boot_maclen;
@@ -625,15 +637,15 @@ int dl_bind(ldi_handle_t lh, uint_t sap, uint_t max_conn,
uint_t service, uint_t conn_mgmt);
int dl_phys_addr(ldi_handle_t lh, struct ether_addr *eaddr);
-#endif /* !__sparc */
+#endif /* !_OBP */
char *
strplumb_get_netdev_path(void)
{
-#ifndef __sparc
+#ifndef _OBP
char *macstr, *devpath = NULL;
uchar_t *bootp;
- uint_t bootp_len, len;
+ uint_t bootp_len;
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
DDI_PROP_DONTPASS, BP_BOOT_MAC, &macstr) == DDI_SUCCESS) {
@@ -658,14 +670,12 @@ strplumb_get_netdev_path(void)
*/
boot_maclen = *(bootp + 2);
ASSERT(boot_maclen <= 16);
- (void) bcopy(bootp + 28, boot_macaddr, boot_maclen);
-
- /* encode to ascii string to match what sparc OBP exports */
- dhcack = kmem_zalloc(bootp_len * 2 + IFNAMSIZ + 2, KM_SLEEP);
- len = bootp_len * 2 + 2;
- (void) octet_to_hexascii(bootp, bootp_len, dhcack + IFNAMSIZ,
- &len);
- ASSERT(len < bootp_len * 2 + 2);
+ bcopy(bootp + 28, boot_macaddr, boot_maclen);
+
+ dhcack = kmem_alloc(bootp_len, KM_SLEEP);
+ bcopy(bootp, dhcack, bootp_len);
+ dhcacklen = bootp_len;
+
ddi_prop_free(bootp);
} else
return (NULL);
@@ -675,10 +685,10 @@ strplumb_get_netdev_path(void)
#else
return (NULL);
-#endif /* !__sparc */
+#endif /* !_OBP */
}
-#ifndef __sparc
+#ifndef _OBP
/*
* Get boot path from the boot_mac address
@@ -726,10 +736,11 @@ matchmac(dev_info_t *dip, void *arg)
*devpathp = kmem_alloc(MAXPATHLEN, KM_SLEEP);
(void) ddi_pathname(dip, *devpathp);
- /* fill in the name portion of dhcack */
- if (dhcack)
- (void) snprintf(dhcack, IFNAMSIZ, "%s%d",
+ /* fill in dhcifname */
+ if (dhcack) {
+ (void) snprintf(dhcifname, IFNAMSIZ, "%s%d",
ddi_driver_name(dip), i_ddi_devi_get_ppa(dip));
+ }
return (DDI_WALK_TERMINATE);
}
@@ -812,7 +823,7 @@ getmacaddr(dev_info_t *dip, int *maclenp)
return (macaddr);
}
-#endif /* !__sparc */
+#endif /* !_OBP */
int
dl_attach(ldi_handle_t lh, int unit)
diff --git a/usr/src/uts/common/krtld/kobj.c b/usr/src/uts/common/krtld/kobj.c
index deffd012bd..64a3648741 100644
--- a/usr/src/uts/common/krtld/kobj.c
+++ b/usr/src/uts/common/krtld/kobj.c
@@ -61,16 +61,18 @@
#include <sys/varargs.h>
#include <sys/kstat.h>
#include <sys/kobj_impl.h>
+#include <sys/fs/decomp.h>
#include <sys/callb.h>
#include <sys/cmn_err.h>
#include <sys/tnf_probe.h>
+#include <sys/zmod.h>
-#include <reloc.h>
-#include <kobj_kdi.h>
+#include <krtld/reloc.h>
+#include <krtld/kobj_kdi.h>
#include <sys/sha1.h>
#include <sys/crypto/elfsign.h>
-#if !defined(__sparc)
+#if !defined(_OBP)
#include <sys/bootvfs.h>
#endif
@@ -80,7 +82,10 @@
#define DOSYM_UNDEF -1 /* undefined symbol */
#define DOSYM_UNSAFE -2 /* MT-unsafe driver symbol */
+#if !defined(_OBP)
static void synthetic_bootaux(char *, val_t *);
+#endif
+
static struct module *load_exec(val_t *, char *);
static void load_linker(val_t *);
static struct modctl *add_primary(const char *filename, int);
@@ -104,19 +109,20 @@ static void attr_val(val_t *);
static char *find_libmacro(char *);
static char *expand_libmacro(char *, char *, char *);
static int read_bootflags(void);
+static int kobj_comp_setup(struct _buf *, struct compinfo *);
+static int kobj_uncomp_blk(struct _buf *, caddr_t, uint_t);
+static int kobj_read_blks(struct _buf *, caddr_t, uint_t, uint_t);
static int kobj_boot_open(char *, int);
static int kobj_boot_close(int);
static int kobj_boot_seek(int, off_t, off_t);
static int kobj_boot_read(int, caddr_t, size_t);
static int kobj_boot_fstat(int, struct bootstat *);
+static int kobj_boot_compinfo(int, struct compinfo *);
static Sym *lookup_one(struct module *, const char *);
static void sym_insert(struct module *, char *, symid_t);
static Sym *sym_lookup(struct module *, Sym *);
-/*PRINTFLIKE2*/
-static void kprintf(void *, const char *, ...) __KPRINTFLIKE(2);
-
static struct kobjopen_tctl *kobjopen_alloc(char *filename);
static void kobjopen_free(struct kobjopen_tctl *ltp);
static void kobjopen_thread(struct kobjopen_tctl *ltp);
@@ -125,13 +131,22 @@ extern int kcopy(const void *, void *, size_t);
extern int elf_mach_ok(Ehdr *);
extern int alloc_gottable(struct module *, caddr_t *, caddr_t *);
-static void tnf_unsplice_probes(unsigned int, struct modctl *);
+#if !defined(_OBP)
+extern int kobj_boot_mountroot(void);
+#endif
+
+static void tnf_unsplice_probes(uint_t, struct modctl *);
+extern tnf_probe_control_t *__tnf_probe_list_head;
+extern tnf_tag_data_t *__tnf_tag_list_head;
extern int modrootloaded;
extern int swaploaded;
extern int bop_io_quiesced;
extern int last_module_id;
+extern char stubs_base[];
+extern char stubs_end[];
+
#ifdef KOBJ_DEBUG
/*
* Values that can be or'd in to kobj_debug and their effects:
@@ -198,10 +213,6 @@ struct lib_macro_info {
char *boot_cpu_compatible_list; /* make $CPU available */
-#ifdef MPSAS
-void sas_prisyms(struct modctl_list *);
-void sas_syms(struct module *);
-#endif
char *kobj_module_path; /* module search path */
vmem_t *text_arena; /* module text arena */
@@ -256,17 +267,6 @@ int tnf_changed_probe_list = 0;
*/
const char *sdt_prefix = "__dtrace_probe_";
-#if defined(__sparc)
-/*
- * Some PROMs return SUNW,UltraSPARC when they actually have
- * SUNW,UltraSPARC-II cpus. SInce we're now filtering out all
- * SUNW,UltraSPARC systems during the boot phase, we can safely
- * point the auxv CPU value at SUNW,UltraSPARC-II. This is what
- * we point it at.
- */
-const char *ultra_2 = "SUNW,UltraSPARC-II";
-#endif
-
/*
* Beginning and end of the kernel's dynamic text/data segments.
*/
@@ -275,14 +275,21 @@ static caddr_t _etext;
static caddr_t _data;
/*
- * XXX Hmm. The sparc linker fails to define this symbol.
+ * The sparc linker doesn't create a memory location
+ * for a variable named _edata, so _edata can only be
+ * referred to, not modified. krtld needs a static
+ * variable to modify it - within krtld, of course -
+ * outside of krtld, e_data is used in all kernels.
*/
-#if !defined(__sparc)
-extern
+#if defined(__sparc)
+static caddr_t _edata;
+#else
+extern caddr_t _edata;
#endif
-caddr_t _edata;
-static Addr dynseg = 0; /* load address of "dynamic" segment */
+Addr dynseg = 0; /* load address of "dynamic" segment */
+size_t dynsize; /* "dynamic" segment size */
+
int standalone = 1; /* an unwholey kernel? */
int use_iflush; /* iflush after relocations */
@@ -297,6 +304,17 @@ int use_iflush; /* iflush after relocations */
*/
void (*_kobj_printf)(void *, const char *, ...); /* printf routine */
+/*
+ * Standalone function pointers for use within krtld.
+ * Many platforms implement optimized platmod versions of
+ * utilities such as bcopy and any such are not yet available
+ * until the kernel is more completely stitched together.
+ * See kobj_impl.h
+ */
+void (*kobj_bcopy)(const void *, void *, size_t);
+void (*kobj_bzero)(void *, size_t);
+size_t (*kobj_strlcat)(char *, const char *, size_t);
+
static kobj_stat_t kobj_stat;
#define MINALIGN 8 /* at least a double-word */
@@ -359,39 +377,9 @@ kobj_init(
dbvec = dvec;
ops = bootvec;
-#if defined(__i386) || defined(__amd64)
- _kobj_printf = (void (*)(void *, const char *, ...))ops->bsys_printf;
-#else
- _kobj_printf = (void (*)(void *, const char *, ...))bop_putsarg;
-#endif
- KOBJ_MARK("Entered kobj_init()");
-
-#if defined(__sparc)
- /* XXXQ should suppress this test on sun4v */
- if (bootaux[BA_CPU].ba_ptr) {
- if (strcmp("SUNW,UltraSPARC", bootaux[BA_CPU].ba_ptr) == 0) {
- bootaux[BA_CPU].ba_ptr = (void *) ultra_2;
- }
- }
-#endif
+ kobj_setup_standalone_vectors();
- /*
- * Check bootops version.
- */
- if (BOP_GETVERSION(ops) != BO_VERSION) {
- _kobj_printf(ops, "Warning: Using boot version %d, ",
- BOP_GETVERSION(ops));
- _kobj_printf(ops, "expected %d\n", BO_VERSION);
- }
-#ifdef KOBJ_DEBUG
- else if (kobj_debug & D_DEBUG) {
- /*
- * Say -something- so we know we got this far ..
- */
- _kobj_printf(ops, "krtld: Using boot version %d.\n",
- BOP_GETVERSION(ops));
- }
-#endif
+ KOBJ_MARK("Entered kobj_init()");
(void) BOP_GETPROP(ops, "whoami", filename);
@@ -410,10 +398,21 @@ kobj_init(
goto fail;
}
-#ifndef __sparc
+#if defined(_OBP)
+ /*
+ * OBP allows us to read both the ramdisk and
+ * the underlying root fs when root is a disk.
+ * This can lower incidences of unbootable systems
+ * when the archive is out-of-date with the /etc
+ * state files.
+ */
+ if (BOP_MOUNTROOT() != BOOT_SVC_OK) {
+ _kobj_printf(ops, "can't mount boot fs\n");
+ goto fail;
+ }
+#else
{
/* on x86, we always boot with a ramdisk */
- extern int kobj_boot_mountroot(void);
(void) kobj_boot_mountroot();
/*
@@ -422,11 +421,10 @@ kobj_init(
*/
boot_prop_finish();
}
-#endif
#if !defined(_UNIX_KRTLD)
/*
- * If 'unix' is linked together with 'krtld' into one executable,
+ * 'unix' is linked together with 'krtld' into one executable and
* the early boot code does -not- hand us any of the dynamic metadata
* about the executable. In particular, it does not read in, map or
* otherwise look at the program headers. We fake all that up now.
@@ -434,10 +432,15 @@ kobj_init(
* We do this early as DTrace static probes and tnf probes both call
* undefined references. We have to process those relocations before
* calling any of them.
+ *
+ * OBP tells kobj_start() where the ELF image is in memory, so it
+ * synthesized bootaux before kobj_init() was called
*/
if (bootaux[BA_PHDR].ba_ptr == NULL)
synthetic_bootaux(filename, bootaux);
-#endif
+
+#endif /* !_UNIX_KRTLD */
+#endif /* _OBP */
/*
* Save the interesting attribute-values
@@ -476,15 +479,6 @@ kobj_init(
entry = bootaux[BA_ENTRY].ba_val;
-#ifdef __sparc
- /*
- * On sparcv9, boot scratch memory is running out.
- * Free the temporary allocations here to allow boot
- * to continue.
- */
- kobj_tmp_free();
-#endif
-
/*
* Get the boot flags
*/
@@ -503,9 +497,6 @@ kobj_init(
/*
* Post setup.
*/
-#ifdef MPSAS
- sas_prisyms(kobj_lm_lookup(KOBJ_LM_PRIMARY));
-#endif
s_text = _text;
e_text = _etext;
s_data = _data;
@@ -534,17 +525,28 @@ kobj_init(
standalone = 0;
-#ifdef __sparc
+#ifdef KOBJ_DEBUG
+ if (kobj_debug & D_DEBUG)
+ _kobj_printf(ops,
+ "krtld: really transferring control to: 0x%p\n", entry);
+#endif
+
+ /* restore printf/bcopy/bzero vectors before returning */
+ kobj_restore_vectors();
+
+#if defined(_DBOOT)
/*
- * On sparcv9, boot scratch memory is running out.
- * Free the temporary allocations here to allow boot
- * to continue.
+ * krtld was called from a dboot ELF section, the embedded
+ * dboot code contains the real entry via bootaux
*/
- kobj_tmp_free();
+ exitto((caddr_t)entry);
+#else
+ /*
+ * krtld was directly called from startup
+ */
+ return;
#endif
- _kobj_printf = kprintf;
- exitto((caddr_t)entry);
fail:
_kobj_printf(ops, "krtld: error during initial load/link phase\n");
@@ -563,9 +565,10 @@ fail:
#endif
}
-#if !defined(_UNIX_KRTLD)
+#if !defined(_UNIX_KRTLD) && !defined(_OBP)
/*
- * Synthesize additional metadata that describes the executable.
+ * Synthesize additional metadata that describes the executable if
+ * krtld's caller didn't do it.
*
* (When the dynamic executable has an interpreter, the boot program
* does all this for us. Where we don't have an interpreter, (or a
@@ -627,7 +630,7 @@ synthetic_bootaux(char *filename, val_t *bootaux)
}
KOBJ_MARK("synthetic_bootaux() done");
}
-#endif
+#endif /* !_UNIX_KRTLD && !_OBP */
/*
* Set up any global information derived
@@ -652,14 +655,22 @@ attr_val(val_t *bootaux)
for (i = 0; i < phnum; i++) {
phdr = (Phdr *)(bootaux[BA_PHDR].ba_val + i * phsize);
- if (phdr->p_type != PT_LOAD)
+ if (phdr->p_type != PT_LOAD) {
continue;
+ }
/*
* Bounds of the various segments.
*/
if (!(phdr->p_flags & PF_X)) {
-#if defined(_UNIX_KRTLD)
+#if defined(_RELSEG)
+ /*
+ * sparc kernel puts the dynamic info
+ * into a separate segment, which is
+ * free'd in bop_fini()
+ */
+ ASSERT(phdr->p_vaddr != 0);
dynseg = phdr->p_vaddr;
+ dynsize = phdr->p_memsz;
#else
ASSERT(phdr->p_vaddr == 0);
#endif
@@ -699,11 +710,7 @@ load_exec(val_t *bootaux, char *filename)
Sym *sp;
int i, lsize, osize, nsize, allocsize;
char *libname, *tmp;
-
- /*
- * Set the module search path.
- */
- kobj_module_path = getmodpath(filename);
+ char path[MAXPATHLEN];
#ifdef KOBJ_DEBUG
if (kobj_debug & D_DEBUG)
@@ -745,17 +752,14 @@ load_exec(val_t *bootaux, char *filename)
dyn->d_tag != DT_NULL; dyn++) {
switch (dyn->d_tag) {
case DT_SYMTAB:
- dyn->d_un.d_ptr += dynseg;
mp->symspace = mp->symtbl = (char *)dyn->d_un.d_ptr;
mp->symhdr->sh_addr = dyn->d_un.d_ptr;
break;
case DT_HASH:
- dyn->d_un.d_ptr += dynseg;
mp->nsyms = *((uint_t *)dyn->d_un.d_ptr + 1);
mp->hashsize = *(uint_t *)dyn->d_un.d_ptr;
break;
case DT_STRTAB:
- dyn->d_un.d_ptr += dynseg;
mp->strings = (char *)dyn->d_un.d_ptr;
mp->strhdr->sh_addr = dyn->d_un.d_ptr;
break;
@@ -785,7 +789,7 @@ load_exec(val_t *bootaux, char *filename)
libname = mp->strings + dyn->d_un.d_val;
if (strchr(libname, '$') != NULL) {
if ((_lib = expand_libmacro(libname,
- filename, filename)) != NULL)
+ path, path)) != NULL)
libname = _lib;
else
_kobj_printf(ops, "krtld: "
@@ -863,7 +867,7 @@ load_exec(val_t *bootaux, char *filename)
if (sp->st_name == 0 || sp->st_shndx == SHN_UNDEF)
continue;
-#ifdef __sparc
+#if defined(__sparc)
/*
* Register symbols are ignored in the kernel
*/
@@ -1063,67 +1067,21 @@ kobj_notify(int type, struct modctl *modp)
}
/*
- * Ask boot for the module path.
+ * Create the module path.
*/
-/*ARGSUSED*/
static char *
getmodpath(const char *filename)
{
- char *path;
- int len;
-
-#if defined(_UNIX_KRTLD)
- /*
- * The boot program provides the module name when it detects
- * that the executable has an interpreter, thus we can ask
- * it directly in this case.
- */
- if ((len = BOP_GETPROPLEN(ops, MODPATH_PROPNAME)) == -1)
- return (MOD_DEFPATH);
-
- path = kobj_zalloc(len, KM_WAIT);
-
- (void) BOP_GETPROP(ops, MODPATH_PROPNAME, path);
-
- return (*path ? path : MOD_DEFPATH);
-
-#else
+ char *path = kobj_zalloc(MAXPATHLEN, KM_WAIT);
/*
- * Construct the directory path from the filename.
+ * Platform code gets first crack, then add
+ * the default components
*/
-
- char *p;
- const char isastr[] = "/amd64";
- size_t isalen = strlen(isastr);
-
- if ((p = strrchr(filename, '/')) == NULL)
- return (MOD_DEFPATH);
-
- while (p > filename && *(p - 1) == '/')
- p--; /* remove trailing '/' characters */
- if (p == filename)
- p++; /* so "/" -is- the modpath in this case */
-
- /*
- * Remove optional isa-dependent directory name - the module
- * subsystem will put this back again (!)
- */
- len = p - filename;
- if (len > isalen &&
- strncmp(&filename[len - isalen], isastr, isalen) == 0)
- p -= isalen;
-
- /*
- * "/platform/mumblefrotz" + " " + MOD_DEFPATH
- */
- len += (p - filename) + 1 + strlen(MOD_DEFPATH) + 1;
-
- path = kobj_zalloc(len, KM_WAIT);
- (void) strncpy(path, filename, p - filename);
- (void) strcat(path, " ");
+ mach_modpath(path, filename);
+ if (*path != '\0')
+ (void) strcat(path, " ");
return (strcat(path, MOD_DEFPATH));
-#endif
}
static struct modctl *
@@ -1230,13 +1188,11 @@ bind_primary(val_t *bootaux, int lmid)
break;
case DT_RELA:
shtype = SHT_RELA;
- rela = (char *)(dyn->d_un.d_ptr +
- dynseg);
+ rela = (char *)dyn->d_un.d_ptr;
break;
case DT_REL:
shtype = SHT_REL;
- rela = (char *)(dyn->d_un.d_ptr +
- dynseg);
+ rela = (char *)dyn->d_un.d_ptr;
break;
}
}
@@ -2105,9 +2061,6 @@ kobj_load_module(struct modctl *modp, int use_path)
/* sync_instruction_memory */
kobj_sync_instruction_memory(mp->text, mp->text_size);
-#ifdef MPSAS
- sas_syms(mp);
-#endif
kobj_export_module(mp);
kobj_notify(KOBJ_NOTIFY_MODLOADED, modp);
}
@@ -2312,9 +2265,9 @@ get_progbits(struct module *mp, struct _buf *file)
uint_t shn;
int err = -1;
- tp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT);
- dp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT);
- sdp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT);
+ tp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT|KM_TMP);
+ dp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT|KM_TMP);
+ sdp = kobj_zalloc(sizeof (struct proginfo), KM_WAIT|KM_TMP);
/*
* loop through sections to find out how much space we need
* for text, data, (also bss that is already assigned)
@@ -2513,7 +2466,6 @@ get_syms(struct module *mp, struct _buf *file)
Sym *sp, *ksp;
char *symname;
int dosymtab = 0;
- extern char stubs_base[], stubs_end[];
/*
* Find the interesting sections.
@@ -2534,6 +2486,8 @@ get_syms(struct module *mp, struct _buf *file)
*/
if (shp->sh_addr)
continue;
+
+ /* KM_TMP since kobj_free'd in do_relocations */
shp->sh_addr = (Addr)
kobj_alloc(shp->sh_size, KM_WAIT|KM_TMP);
@@ -3028,7 +2982,7 @@ do_symbols(struct module *mp, Elf64_Addr bss_base)
name = mp->strings + sp->st_name;
if (sp->st_shndx != SHN_UNDEF && sp->st_shndx != SHN_COMMON)
continue;
-#ifdef __sparc
+#if defined(__sparc)
/*
* Register symbols are ignored in the kernel
*/
@@ -3127,7 +3081,7 @@ do_symbols(struct module *mp, Elf64_Addr bss_base)
uint_t
kobj_hash_name(const char *p)
{
- unsigned int g;
+ uint_t g;
uint_t hval;
hval = 0;
@@ -3661,7 +3615,7 @@ kobjopen_free(struct kobjopen_tctl *ltp)
}
int
-kobj_read(intptr_t descr, char *buf, unsigned size, unsigned offset)
+kobj_read(intptr_t descr, char *buf, uint_t size, uint_t offset)
{
int stat;
ssize_t resid;
@@ -3755,6 +3709,7 @@ struct _buf *
kobj_open_file(char *name)
{
struct _buf *file;
+ struct compinfo cbuf;
intptr_t fd;
if ((fd = kobj_open(name)) == -1) {
@@ -3764,25 +3719,80 @@ kobj_open_file(char *name)
file = kobj_zalloc(sizeof (struct _buf), KM_WAIT|KM_TMP);
file->_fd = fd;
file->_name = kobj_alloc(strlen(name)+1, KM_WAIT|KM_TMP);
- file->_base = kobj_zalloc(MAXBSIZE, KM_WAIT|KM_TMP);
file->_cnt = file->_size = file->_off = 0;
file->_ln = 1;
file->_ptr = file->_base;
(void) strcpy(file->_name, name);
+
+ /*
+ * Before root is mounted, we must check
+ * for a compressed file and do our own
+ * buffering.
+ */
+ if (_modrootloaded) {
+ file->_base = kobj_zalloc(MAXBSIZE, KM_WAIT);
+ file->_bsize = MAXBSIZE;
+ } else {
+ if (kobj_boot_compinfo(fd, &cbuf) != 0) {
+ kobj_close_file(file);
+ return ((struct _buf *)-1);
+ }
+ file->_iscmp = cbuf.iscmp;
+ if (file->_iscmp) {
+ if (kobj_comp_setup(file, &cbuf) != 0) {
+ kobj_close_file(file);
+ return ((struct _buf *)-1);
+ }
+ } else {
+ file->_base = kobj_zalloc(cbuf.blksize, KM_WAIT|KM_TMP);
+ file->_bsize = cbuf.blksize;
+ }
+ }
return (file);
}
+static int
+kobj_comp_setup(struct _buf *file, struct compinfo *cip)
+{
+ struct comphdr *hdr;
+
+ /*
+ * read the compressed image into memory,
+ * so we can deompress from there
+ */
+ file->_dsize = cip->fsize;
+ file->_dbuf = kobj_alloc(cip->fsize, KM_WAIT|KM_TMP);
+ if (kobj_read(file->_fd, file->_dbuf, cip->fsize, 0) != cip->fsize) {
+ kobj_free(file->_dbuf, cip->fsize);
+ return (-1);
+ }
+
+ hdr = kobj_comphdr(file);
+ if (hdr->ch_magic != CH_MAGIC || hdr->ch_version != CH_VERSION ||
+ hdr->ch_algorithm != CH_ALG_ZLIB || hdr->ch_fsize == 0 ||
+ (hdr->ch_blksize & (hdr->ch_blksize - 1)) != 0) {
+ kobj_free(file->_dbuf, cip->fsize);
+ return (-1);
+ }
+ file->_base = kobj_alloc(hdr->ch_blksize, KM_WAIT|KM_TMP);
+ file->_bsize = hdr->ch_blksize;
+ return (0);
+}
+
void
kobj_close_file(struct _buf *file)
{
kobj_close(file->_fd);
- kobj_free(file->_base, MAXBSIZE);
+ if (file->_base != NULL)
+ kobj_free(file->_base, file->_bsize);
+ if (file->_dbuf != NULL)
+ kobj_free(file->_dbuf, file->_dsize);
kobj_free(file->_name, strlen(file->_name)+1);
kobj_free(file, sizeof (struct _buf));
}
int
-kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
+kobj_read_file(struct _buf *file, char *buf, uint_t size, uint_t off)
{
int b_size, c_size;
int b_off; /* Offset into buffer for start of bcopy */
@@ -3796,7 +3806,7 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
}
while (size) {
- page_addr = F_PAGE(off);
+ page_addr = F_PAGE(file, off);
b_size = file->_size;
/*
* If we have the filesystem page the caller's referring to
@@ -3804,7 +3814,7 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
* satisfy as much of the request from the buffer as we can.
*/
if (page_addr == file->_off && b_size > 0) {
- b_off = B_OFFSET(off);
+ b_off = B_OFFSET(file, off);
c_size = b_size - b_off;
/*
* If there's nothing to copy, we're at EOF.
@@ -3835,15 +3845,15 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
* read directly into the caller's buffer.
*/
if (page_addr == off &&
- (c_size = F_PAGE(size)) && buf) {
- c_size = kobj_read(file->_fd, buf, c_size,
+ (c_size = F_BLKS(file, size)) && buf) {
+ c_size = kobj_read_blks(file, buf, c_size,
page_addr);
if (c_size < 0) {
count = -1;
break;
}
count += c_size;
- if (c_size != F_PAGE(size))
+ if (c_size != F_BLKS(file, size))
break;
size -= c_size;
off += c_size;
@@ -3854,8 +3864,8 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
*/
} else {
file->_off = page_addr;
- c_size = kobj_read(file->_fd, file->_base,
- MAXBSIZE, page_addr);
+ c_size = kobj_read_blks(file, file->_base,
+ file->_bsize, page_addr);
file->_ptr = file->_base;
file->_cnt = c_size;
file->_size = c_size;
@@ -3877,10 +3887,56 @@ kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
return (count);
}
+static int
+kobj_read_blks(struct _buf *file, char *buf, uint_t size, uint_t off)
+{
+ int ret;
+
+ ASSERT(B_OFFSET(file, size) == 0 && B_OFFSET(file, off) == 0);
+ if (file->_iscmp) {
+ uint_t blks;
+ int nret;
+
+ ret = 0;
+ for (blks = size / file->_bsize; blks != 0; blks--) {
+ nret = kobj_uncomp_blk(file, buf, off);
+ if (nret == -1)
+ return (-1);
+ buf += nret;
+ off += nret;
+ ret += nret;
+ if (nret < file->_bsize)
+ break;
+ }
+ } else
+ ret = kobj_read(file->_fd, buf, size, off);
+ return (ret);
+}
+
+static int
+kobj_uncomp_blk(struct _buf *file, char *buf, uint_t off)
+{
+ struct comphdr *hdr = kobj_comphdr(file);
+ ulong_t dlen, slen;
+ caddr_t src;
+ int i;
+
+ dlen = file->_bsize;
+ i = off / file->_bsize;
+ src = file->_dbuf + hdr->ch_blkmap[i];
+ if (i == hdr->ch_fsize / file->_bsize)
+ slen = hdr->ch_fsize - hdr->ch_blkmap[i];
+ else
+ slen = hdr->ch_blkmap[i + 1] - hdr->ch_blkmap[i];
+ if (z_uncompress(buf, &dlen, src, slen) != Z_OK)
+ return (-1);
+ return (dlen);
+}
+
int
kobj_filbuf(struct _buf *f)
{
- if (kobj_read_file(f, NULL, MAXBSIZE, f->_off + f->_size) > 0)
+ if (kobj_read_file(f, NULL, f->_bsize, f->_off + f->_size) > 0)
return (kobj_getc(f));
return (-1);
}
@@ -3919,23 +3975,10 @@ kobj_alloc(size_t size, int flag)
* permanently using the dynamic data segment.
*/
if (standalone) {
-#ifdef __sparc
- if (flag & KM_TMP) {
- return (kobj_tmp_alloc(size));
- } else if (flag & KM_SCRATCH) {
- void *buf = kobj_bs_alloc(size);
-
- if (buf != NULL)
- return (buf);
-#ifdef KOBJ_DEBUG
- if (kobj_debug & D_DEBUG) {
- _kobj_printf(ops, "krtld: failed scratch alloc "
- "of %lu bytes -- falling back\n", size);
- }
-#endif
- }
-
-#else /* x86 */
+#if defined(_OBP)
+ if (flag & (KM_TMP | KM_SCRATCH))
+ return (bop_temp_alloc(size, MINALIGN));
+#else
if (flag & (KM_TMP | KM_SCRATCH))
return (BOP_ALLOC(ops, 0, size, MINALIGN));
#endif
@@ -4068,6 +4111,19 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
return (EIO);
*size = bst.st_size;
} else {
+
+#if defined(_OBP)
+ struct bootstat bsb;
+
+ if (file->_iscmp) {
+ struct comphdr *hdr = kobj_comphdr(file);
+
+ *size = hdr->ch_fsize;
+ } else if (kobj_boot_fstat(file->_fd, &bsb) != 0)
+ return (EIO);
+ else
+ *size = bsb.st_size;
+#else
char *buf;
int count;
uint64_t offset = 0;
@@ -4084,6 +4140,7 @@ kobj_get_filesize(struct _buf *file, uint64_t *size)
kmem_free(buf, MAXBSIZE);
*size = offset;
+#endif
}
return (0);
@@ -4103,17 +4160,6 @@ basename(char *s)
return (q ? q + 1 : s);
}
-/*ARGSUSED*/
-static void
-kprintf(void *op, const char *fmt, ...)
-{
- va_list adx;
-
- va_start(adx, fmt);
- vprintf(fmt, adx);
- va_end(adx);
-}
-
void
kobj_stat_get(kobj_stat_t *kp)
{
@@ -4327,10 +4373,8 @@ tnf_add_notifyunload(kobj_notify_f *fp)
/* ARGSUSED */
static void
-tnf_unsplice_probes(unsigned int what, struct modctl *mod)
+tnf_unsplice_probes(uint_t what, struct modctl *mod)
{
- extern tnf_probe_control_t *__tnf_probe_list_head;
- extern tnf_tag_data_t *__tnf_tag_list_head;
tnf_probe_control_t **p;
tnf_tag_data_t **q;
struct module *mp = mod->mod_mp;
@@ -4397,7 +4441,9 @@ tnf_splice_probes(int boot_load, tnf_probe_control_t *plist,
return (result);
}
-#if defined(__x86)
+char *kobj_file_buf;
+int kobj_file_bufsize;
+
/*
* This code is for the purpose of manually recording which files
* needs to go into the boot archive on any given system.
@@ -4408,15 +4454,10 @@ tnf_splice_probes(int boot_load, tnf_probe_control_t *plist,
static void
kobj_record_file(char *filename)
{
- extern char *kobj_file_buf;
- extern int kobj_file_bufsize;
static char *buf;
static int size = 0;
int n;
- if (standalone) /* kernel symbol not available */
- return;
-
if (kobj_file_bufsize == 0) /* don't bother */
return;
@@ -4431,12 +4472,11 @@ kobj_record_file(char *filename)
size -= n;
buf += n;
}
-#endif /* __x86 */
static int
kobj_boot_fstat(int fd, struct bootstat *stp)
{
-#if defined(__sparc)
+#if defined(_OBP)
if (!standalone && _ioquiesced)
return (-1);
return (BOP_FSTAT(ops, fd, stp));
@@ -4445,14 +4485,11 @@ kobj_boot_fstat(int fd, struct bootstat *stp)
#endif
}
-/*
- * XXX these wrappers should go away when sparc is converted
- * boot from ramdisk
- */
static int
kobj_boot_open(char *filename, int flags)
{
-#if defined(__sparc)
+#if defined(_OBP)
+
/*
* If io via bootops is quiesced, it means boot is no longer
* available to us. We make it look as if we can't open the
@@ -4461,7 +4498,8 @@ kobj_boot_open(char *filename, int flags)
if (!standalone && _ioquiesced)
return (-1);
- return (BOP_OPEN(ops, filename, flags));
+ kobj_record_file(filename);
+ return (BOP_OPEN(filename, flags));
#else /* x86 */
kobj_record_file(filename);
return (BRD_OPEN(bfs_ops, filename, flags));
@@ -4471,11 +4509,11 @@ kobj_boot_open(char *filename, int flags)
static int
kobj_boot_close(int fd)
{
-#if defined(__sparc)
+#if defined(_OBP)
if (!standalone && _ioquiesced)
return (-1);
- return (BOP_CLOSE(ops, fd));
+ return (BOP_CLOSE(fd));
#else /* x86 */
return (BRD_CLOSE(bfs_ops, fd));
#endif
@@ -4485,8 +4523,8 @@ kobj_boot_close(int fd)
static int
kobj_boot_seek(int fd, off_t hi, off_t lo)
{
-#if defined(__sparc)
- return (BOP_SEEK(ops, fd, hi, lo));
+#if defined(_OBP)
+ return (BOP_SEEK(fd, lo) == -1 ? -1 : 0);
#else
return (BRD_SEEK(bfs_ops, fd, lo, SEEK_SET));
#endif
@@ -4495,9 +4533,15 @@ kobj_boot_seek(int fd, off_t hi, off_t lo)
static int
kobj_boot_read(int fd, caddr_t buf, size_t size)
{
-#if defined(__sparc)
- return (BOP_READ(ops, fd, buf, size));
+#if defined(_OBP)
+ return (BOP_READ(fd, buf, size));
#else
return (BRD_READ(bfs_ops, fd, buf, size));
#endif
}
+
+static int
+kobj_boot_compinfo(int fd, struct compinfo *cb)
+{
+ return (boot_compinfo(fd, cb));
+}
diff --git a/usr/src/uts/common/krtld/kobj_bootflags.c b/usr/src/uts/common/krtld/kobj_bootflags.c
index 68cc7a41b4..681f80e362 100644
--- a/usr/src/uts/common/krtld/kobj_bootflags.c
+++ b/usr/src/uts/common/krtld/kobj_bootflags.c
@@ -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.
*/
@@ -51,25 +51,37 @@ bootflags(struct bootops *ops)
int c;
char scratch[BOOTARGS_MAX];
- if (BOP_GETPROP(ops, "boot-args", kern_bootargs) != 0) {
+ if (BOP_GETPROP(ops, "bootargs", kern_bootargs) == -1) {
boothowto |= RB_ASKNAME;
return;
}
cp = kern_bootargs;
-#if !defined(__i386) && !defined(__amd64)
+#if defined(_OBP)
/*
* x86: The boot scripts (i.e., /etc/bootrc) don't prepend the kernel
* name to the boot arguments. (And beware making it do so: if the
* run-kernel command returns, it will loop, and you will end up with
* multiple copies of the kernel name.)
*/
- SKIP_WORD(cp); /* Skip the kernel's filename. */
+ if (cp[0] != '-') {
+ /* if user booted kadb or kmdb, load kmdb */
+ if (cp[0] == 'k' && (cp[1] == 'a' || cp[1] == 'm') &&
+ cp[2] == 'd' && cp[3] == 'b' &&
+ (cp[4] == ' ' || cp[4] == ' ' || cp[4] == 0))
+ boothowto |= RB_KMDB;
+ SKIP_WORD(cp); /* Skip the kernel's filename. */
+ }
#endif
SKIP_SPC(cp);
+#if defined(_OBP)
+ /* skip bootblk args */
+ params.gos_opts = "abcdDF:gGHhi:km:o:O:rsvVwx";
+#else
params.gos_opts = "abcdgGhi:km:O:rsvwx";
+#endif
params.gos_strp = cp;
getoptstr_init(&params);
while ((c = getoptstr(&params)) != -1) {
@@ -87,6 +99,11 @@ bootflags(struct bootops *ops)
case 'd':
boothowto |= RB_DEBUGENTER;
break;
+#if defined(_OBP)
+ case 'D':
+ case 'F':
+ break;
+#endif
case 'g':
boothowto |= RB_FORTHDEBUG;
break;
@@ -96,6 +113,10 @@ bootflags(struct bootops *ops)
case 'h':
boothowto |= RB_HALT;
break;
+#if defined(_OBP)
+ case 'H':
+ break;
+#endif
case 'i':
if (params.gos_optarglen + 1 > sizeof (initname)) {
_kobj_printf(ops, "krtld: initname too long. "
@@ -122,9 +143,15 @@ bootflags(struct bootops *ops)
params.gos_optarglen);
scratch[params.gos_optarglen] = '\0';
(void) strlcat(initargs, "-m ", sizeof (initargs));
- (void) strlcat(initargs, scratch, sizeof (initargs));
+ (void) strlcat(initargs, scratch,
+ sizeof (initargs));
(void) strlcat(initargs, " ", sizeof (initargs));
break;
+#if defined(_OBP)
+ /* Ignore argument meant for wanboot standalone */
+ case 'o':
+ break;
+#endif
case 'O': {
char **str = &kobj_kmdb_argv[num_O_opt];
@@ -169,6 +196,10 @@ bootflags(struct bootops *ops)
boothowto |= RB_VERBOSE;
(void) strlcat(initargs, "-v ", sizeof (initargs));
break;
+#if defined(_OBP)
+ case 'V':
+ break;
+#endif
case 'w':
boothowto |= RB_WRITABLE;
break;
diff --git a/usr/src/uts/common/krtld/kobj_kdi.c b/usr/src/uts/common/krtld/kobj_kdi.c
index c094e30d06..f843158535 100644
--- a/usr/src/uts/common/krtld/kobj_kdi.c
+++ b/usr/src/uts/common/krtld/kobj_kdi.c
@@ -76,7 +76,7 @@
#include <sys/reboot.h>
#include <sys/kdi_impl.h>
-#include <kobj_kdi.h>
+#include <krtld/kobj_kdi.h>
#define KOBJ_KDI_MOD_IDLE 0
#define KOBJ_KDI_MOD_CHANGING 1
diff --git a/usr/src/uts/common/krtld/kobj_subr.c b/usr/src/uts/common/krtld/kobj_subr.c
index a949922fe0..761c8b69f6 100644
--- a/usr/src/uts/common/krtld/kobj_subr.c
+++ b/usr/src/uts/common/krtld/kobj_subr.c
@@ -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.
*/
@@ -29,93 +29,61 @@
#include <sys/param.h>
#include <sys/systm.h>
-/*
- * Standalone copies of some basic routines. Note that these routines
- * are transformed via Makefile -D flags into krtld_* routines. So,
- * this version of strcmp() will become krtld_strcmp() when built.
- *
- * This dubious practice is so that krtld can have its own private
- * versions of these routines suitable for use during early boot,
- * when kernel-based routines might not work. Make sure to use 'nm'
- * on your krtld to make sure it is calling the appropriate routines.
- */
-
-int
-strcmp(const char *s1, const char *s2)
-{
- if (s1 == s2)
- return (0);
- while (*s1 == *s2++)
- if (*s1++ == '\0')
- return (0);
- return (*s1 - s2[-1]);
-}
+#include <sys/bootconf.h>
+#include <sys/kobj_impl.h>
+#include <sys/cmn_err.h>
/*
- * Compare strings (at most n bytes): return *s1-*s2 for the last
- * characters in s1 and s2 which were compared.
+ * Standalone utility functions for use within krtld.
+ * Many platforms implement optimized platmod versions of
+ * utilities such as bcopy and any such are not yet available
+ * until the kernel is more completely stitched together.
+ * These standalones are referenced through vectors
+ * kobj_bzero, etc. Throughout krtld, the usual utility
+ * is redefined to reference through the corresponding
+ * vector so that krtld may simply refer to bzero etc.
+ * as usual. See kobj_impl.h.
*/
-int
-strncmp(const char *s1, const char *s2, size_t n)
-{
- if (s1 == s2)
- return (0);
- n++;
- while (--n != 0 && *s1 == *s2++)
- if (*s1++ == '\0')
- return (0);
- return ((n == 0) ? 0 : *s1 - *--s2);
-}
-size_t
-strlen(const char *s)
+/*ARGSUSED*/
+static void
+kprintf(void *op, const char *fmt, ...)
{
- const char *s0 = s + 1;
+ va_list adx;
- while (*s++ != '\0')
- ;
- return (s - s0);
+ va_start(adx, fmt);
+ vprintf(fmt, adx);
+ va_end(adx);
}
-char *
-strcpy(char *s1, const char *s2)
+static void
+stand_bzero(void *p_arg, size_t count)
{
- char *os1 = s1;
+ char zero = 0;
+ caddr_t p = p_arg;
- while (*s1++ = *s2++)
- ;
- return (os1);
+ while (count != 0)
+ *p++ = zero, count--;
}
-char *
-strncpy(char *s1, const char *s2, size_t n)
+static void
+stand_bcopy(const void *src_arg, void *dest_arg, size_t count)
{
- char *os1 = s1;
-
- n++;
- while ((--n != 0) && ((*s1++ = *s2++) != '\0'))
- ;
- if (n != 0)
- while (--n != 0)
- *s1++ = '\0';
- return (os1);
-}
+ caddr_t src = (caddr_t)src_arg;
+ caddr_t dest = dest_arg;
-char *
-strcat(char *s1, const char *s2)
-{
- char *os1 = s1;
-
- while (*s1++)
- ;
- --s1;
- while (*s1++ = *s2++)
- ;
- return (os1);
+ if (src < dest && (src + count) > dest) {
+ /* overlap copy */
+ while (--count != -1)
+ *(dest + count) = *(src + count);
+ } else {
+ while (--count != -1)
+ *dest++ = *src++;
+ }
}
-size_t
-strlcat(char *dst, const char *src, size_t dstsize)
+static size_t
+stand_strlcat(char *dst, const char *src, size_t dstsize)
{
char *df = dst;
size_t left = dstsize;
@@ -135,39 +103,36 @@ strlcat(char *dst, const char *src, size_t dstsize)
return (l1 + l2);
}
-char *
-strchr(const char *sp, int c)
-{
-
- do {
- if (*sp == (char)c)
- return ((char *)sp);
- } while (*sp++);
- return (NULL);
-}
-
+/*
+ * Set up the krtld standalone utilty vectors
+ */
void
-bzero(void *p_arg, size_t count)
+kobj_setup_standalone_vectors()
{
- char zero = 0;
- caddr_t p = p_arg;
-
- while (count != 0)
- *p++ = zero, count--; /* Avoid clr for 68000, still... */
+ _kobj_printf = (void (*)(void *, const char *, ...))bop_printf;
+ kobj_bcopy = stand_bcopy;
+ kobj_bzero = stand_bzero;
+ kobj_strlcat = stand_strlcat;
}
+/*
+ * Restore the kprintf/bcopy/bzero kobj vectors.
+ * We need to undefine the override macros to
+ * accomplish this.
+ *
+ * Do NOT add new code after the point or at least
+ * certainly not code using bcopy or bzero which would
+ * need to be vectored to the krtld equivalents.
+ */
+#undef bcopy
+#undef bzero
+#undef strlcat
+
void
-bcopy(const void *src_arg, void *dest_arg, size_t count)
+kobj_restore_vectors()
{
- caddr_t src = (caddr_t)src_arg;
- caddr_t dest = dest_arg;
-
- if (src < dest && (src + count) > dest) {
- /* overlap copy */
- while (--count != -1)
- *(dest + count) = *(src + count);
- } else {
- while (--count != -1)
- *dest++ = *src++;
- }
+ _kobj_printf = kprintf;
+ kobj_bcopy = bcopy;
+ kobj_bzero = bzero;
+ kobj_strlcat = strlcat;
}
diff --git a/usr/src/uts/common/os/autoconf.c b/usr/src/uts/common/os/autoconf.c
index 2adffdd7b0..0bd34a64a9 100644
--- a/usr/src/uts/common/os/autoconf.c
+++ b/usr/src/uts/common/os/autoconf.c
@@ -48,6 +48,7 @@
#include <sys/sysevent_impl.h>
#include <sys/sunldi_impl.h>
#include <sys/disp.h>
+#include <sys/bootconf.h>
#include <sys/fm/util.h>
extern dev_info_t *top_devinfo;
@@ -126,7 +127,6 @@ impl_create_root_class(void)
major_t major;
size_t size;
char *cp;
- extern struct bootops *bootops;
/*
* The name for the root nexus is exactly as the manufacturer
diff --git a/usr/src/uts/common/os/instance.c b/usr/src/uts/common/os/instance.c
index 08537f3372..7134d93c56 100644
--- a/usr/src/uts/common/os/instance.c
+++ b/usr/src/uts/common/os/instance.c
@@ -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.
*/
@@ -195,7 +195,7 @@ e_ddi_instance_init(void)
case PTI_REBUILD:
cmn_err(CE_CONT,
- "?Using default device instance data\n");
+ "?Using default device instance data\n");
break;
}
@@ -245,14 +245,14 @@ in_preassign_instance()
static int
in_get_infile(char *filename)
{
- intptr_t file;
+ struct _buf *file;
int return_val;
char buf[PTI_MAGIC_STR_LEN];
/*
* Try to open the file.
*/
- if ((file = kobj_open(filename)) == -1) {
+ if ((file = kobj_open_file(filename)) == (struct _buf *)-1) {
return (PTI_NOT_FOUND);
}
return_val = PTI_FOUND;
@@ -263,7 +263,7 @@ in_get_infile(char *filename)
* in the file, then assume file is correct and no magic string
* and move on.
*/
- switch (kobj_read(file, buf, PTI_MAGIC_STR_LEN, 0)) {
+ switch (kobj_read_file(file, buf, PTI_MAGIC_STR_LEN, 0)) {
case PTI_MAGIC_STR_LEN:
/*
@@ -285,7 +285,7 @@ in_get_infile(char *filename)
break;
}
- kobj_close(file);
+ kobj_close_file(file);
return (return_val);
}
@@ -1360,13 +1360,13 @@ i_log_devfs_instance_mod(void)
return;
ev = sysevent_alloc(EC_DEVFS, ESC_DEVFS_INSTANCE_MOD, EP_DDI,
- SE_NOSLEEP);
+ SE_NOSLEEP);
if (ev == NULL) {
return;
}
if (log_sysevent(ev, SE_NOSLEEP, &eid) != 0) {
cmn_err(CE_WARN, "i_log_devfs_instance_mod: failed to post "
- "event");
+ "event");
} else {
sent_one = 1;
}
diff --git a/usr/src/uts/common/os/modsysfile.c b/usr/src/uts/common/os/modsysfile.c
index 07076f02dd..5ba026e22e 100644
--- a/usr/src/uts/common/os/modsysfile.c
+++ b/usr/src/uts/common/os/modsysfile.c
@@ -64,7 +64,7 @@ static char class_file[] = CLASSFILE;
static char dafile[] = DAFILE;
static char dacffile[] = DACFFILE;
-char *systemfile = "etc/system"; /* name of ascii system file */
+char *systemfile = "/etc/system"; /* name of ascii system file */
static struct sysparam *sysparam_hd; /* head of parameters list */
static struct sysparam *sysparam_tl; /* tail of parameters list */
diff --git a/usr/src/uts/common/os/space.c b/usr/src/uts/common/os/space.c
index d21630cb22..08384fab47 100644
--- a/usr/src/uts/common/os/space.c
+++ b/usr/src/uts/common/os/space.c
@@ -106,15 +106,12 @@ struct var v;
*/
struct vnode *rootvp; /* vnode of the root device */
dev_t rootdev; /* dev_t of the root device */
-int root_is_svm; /* root is a mirrored device flag */
-
-int netboot;
-int obpdebug;
-char *dhcack; /* Used to cache ascii form of DHCPACK handed up by boot */
-char *netdev_path; /* Used to cache the netdev_path handed up by boot */
+boolean_t root_is_svm; /* root is a mirrored device flag */
+boolean_t root_is_ramdisk; /* root is ramdisk */
+uint32_t ramdisk_size; /* (KB) currently set only for sparc netboots */
/*
- * Data from arp.c that must be resident.
+ * dhcp
*/
#include <sys/socket.h>
#include <sys/errno.h>
@@ -123,6 +120,17 @@ char *netdev_path; /* Used to cache the netdev_path handed up by boot */
#include <sys/stropts.h>
#include <sys/dlpi.h>
#include <net/if.h>
+
+int netboot;
+int obpdebug;
+char *dhcack; /* dhcp response packet */
+int dhcacklen;
+char *netdev_path; /* Used to cache the netdev_path handed up by boot */
+char dhcifname[IFNAMSIZ];
+
+/*
+ * Data from arp.c that must be resident.
+ */
#include <net/if_arp.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
@@ -130,6 +138,7 @@ char *netdev_path; /* Used to cache the netdev_path handed up by boot */
ether_addr_t etherbroadcastaddr = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
/*
* Data from timod that must be resident
*/
@@ -260,7 +269,7 @@ static void
store_fetch_initspace()
{
space_hash = mod_hash_create_strhash(space_hash_name,
- space_hash_nchains, mod_hash_null_valdtor);
+ space_hash_nchains, mod_hash_null_valdtor);
ASSERT(space_hash);
}
@@ -288,7 +297,7 @@ space_store(char *key, uintptr_t ptr)
bcopy(key, s, l);
rval = mod_hash_insert(space_hash,
- (mod_hash_key_t)s, (mod_hash_val_t)ptr);
+ (mod_hash_key_t)s, (mod_hash_val_t)ptr);
switch (rval) {
case 0:
diff --git a/usr/src/uts/common/os/swapgeneric.c b/usr/src/uts/common/os/swapgeneric.c
index 23fe002d2f..33ce90b489 100644
--- a/usr/src/uts/common/os/swapgeneric.c
+++ b/usr/src/uts/common/os/swapgeneric.c
@@ -91,7 +91,7 @@ static boolean_t netboot_over_ib(char *bootpath);
* Module linkage information for the kernel.
*/
static struct modlmisc modlmisc = {
- &mod_miscops, "root and swap configuration %I%"
+ &mod_miscops, "root and swap configuration"
};
static struct modlinkage modlinkage = {
@@ -308,7 +308,7 @@ loadrootmodules(void)
char *name;
int err;
/* ONC_PLUS EXTRACT END */
- int i, proplen, dhcacklen;
+ int i, proplen;
extern char *impl_module_list[];
extern char *platform_module_list[];
@@ -415,23 +415,19 @@ loop:
* ("bootp-response" boot property exists). If so, then before
* bootops disappears we need to save the value of this property
* such that the userland dhcpagent can adopt the DHCP management
- * of our primary network interface. We leave room at the beginning of
- * saved property to cache the interface name we used to boot the
- * client. This context is necessary for the user land dhcpagent
- * to do its job properly on a multi-homed system.
+ * of our primary network interface.
*/
proplen = BOP_GETPROPLEN(bootops, "bootp-response");
if (proplen > 0) {
- dhcacklen = proplen + IFNAMSIZ;
- dhcack = kmem_zalloc(dhcacklen, KM_SLEEP);
- if (BOP_GETPROP(bootops, "bootp-response",
- (uchar_t *)&dhcack[IFNAMSIZ]) == -1) {
+ dhcack = kmem_zalloc(proplen, KM_SLEEP);
+ if (BOP_GETPROP(bootops, "bootp-response", dhcack) == -1) {
cmn_err(CE_WARN, "BOP_GETPROP of "
"\"bootp-response\" failed\n");
kmem_free(dhcack, dhcacklen);
dhcack = NULL;
goto out;
}
+ dhcacklen = proplen;
/*
* Fetch the "netdev-path" boot property (if it exists), and
@@ -522,6 +518,36 @@ out:
}
/* ONC_PLUS EXTRACT END */
+static int
+get_bootpath_prop(char *bootpath)
+{
+ if (root_is_ramdisk) {
+ if (BOP_GETPROP(bootops, "bootarchive", bootpath) == -1)
+ return (-1);
+ (void) strlcat(bootpath, ":a", BO_MAXOBJNAME);
+ } else {
+ /*
+ * Look for the 1275 compliant name 'bootpath' first,
+ * but make certain it has a non-NULL value as well.
+ */
+ if ((BOP_GETPROP(bootops, "bootpath", bootpath) == -1) ||
+ strlen(bootpath) == 0) {
+ if (BOP_GETPROP(bootops,
+ "boot-path", bootpath) == -1)
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+static int
+get_fstype_prop(char *fstype)
+{
+ char *prop = (root_is_ramdisk) ? "archive-fstype" : "fstype";
+
+ return (BOP_GETPROP(bootops, prop, fstype));
+}
+
/*
* Get the name of the root or swap filesystem type, and return
* the corresponding entry in the vfs switch.
@@ -558,7 +584,7 @@ getfstype(char *askfor, char *fsname, size_t fsnamelen)
int root = 0;
if (strcmp(askfor, "root") == 0) {
- (void) BOP_GETPROP(bootops, "fstype", defaultfs);
+ (void) get_fstype_prop(defaultfs);
root++;
} else {
(void) strcpy(defaultfs, "swapfs");
@@ -628,16 +654,8 @@ getphysdev(char *askfor, char *name, size_t namelen)
* ease-of-use ..
*/
if (strcmp(askfor, "root") == 0) {
- /*
- * Look for the 1275 compliant name 'bootpath' first,
- * but make certain it has a non-NULL value as well.
- */
- if ((BOP_GETPROP(bootops, "bootpath", defaultpath) == -1) ||
- strlen(defaultpath) == 0) {
- if (BOP_GETPROP(bootops,
- "boot-path", defaultpath) == -1)
- boothowto |= RB_ASKNAME | RB_VERBOSE;
- }
+ if (get_bootpath_prop(defaultpath) == -1)
+ boothowto |= RB_ASKNAME | RB_VERBOSE;
} else {
(void) strcpy(defaultpath, rootfs.bo_name);
defaultpath[strlen(defaultpath) - 1] = 'b';
diff --git a/usr/src/uts/common/os/vfs_conf.c b/usr/src/uts/common/os/vfs_conf.c
index fec5cc998f..b15c834fbe 100644
--- a/usr/src/uts/common/os/vfs_conf.c
+++ b/usr/src/uts/common/os/vfs_conf.c
@@ -80,6 +80,7 @@ struct vfssw vfssw[] = {
{ "ctfs" }, /* CONTRACTFS */
{ "objfs" }, /* OBJFS */
{ "sharefs" }, /* SHAREFS */
+ { "dcfs" }, /* DCFS */
{ "" }, /* reserved for loadable fs */
{ "" },
{ "" },
diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile
index adf32df9d7..c46d01b321 100644
--- a/usr/src/uts/common/sys/Makefile
+++ b/usr/src/uts/common/sys/Makefile
@@ -731,6 +731,7 @@ FSHDRS= \
cachefs_fscache.h \
cachefs_ioctl.h \
cachefs_log.h \
+ decomp.h \
dv_node.h \
sdev_impl.h \
sdev_node.h \
diff --git a/usr/src/uts/common/sys/bootstat.h b/usr/src/uts/common/sys/bootstat.h
index b972d1419e..437f74d1c0 100644
--- a/usr/src/uts/common/sys/bootstat.h
+++ b/usr/src/uts/common/sys/bootstat.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 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -65,6 +64,18 @@ struct bootstat {
char st_fstype[_ST_FSTYPSZ];
};
+/*
+ * Special struct for compressed files.
+ * Only used by kobj to decompress files before
+ * root is mounted. Afterwards, dcfs will take
+ * over decompression.
+ */
+struct compinfo {
+ int iscmp;
+ size_t fsize;
+ size_t blksize;
+};
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/filio.h b/usr/src/uts/common/sys/filio.h
index 8d13c2e483..cbd98af97e 100644
--- a/usr/src/uts/common/sys/filio.h
+++ b/usr/src/uts/common/sys/filio.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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -133,6 +132,11 @@ extern "C" {
#define _FIO_SEEK_DATA _IO('f', 97) /* SEEK_DATA */
#define _FIO_SEEK_HOLE _IO('f', 98) /* SEEK_HOLE */
+/*
+ * boot archive compression
+ */
+#define _FIO_COMPRESSED _IO('f', 99) /* mark file as compressed */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/fs/decomp.h b/usr/src/uts/common/sys/fs/decomp.h
new file mode 100644
index 0000000000..035a5ab6c8
--- /dev/null
+++ b/usr/src/uts/common/sys/fs/decomp.h
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#ifndef _SYS_DECOMP_H
+#define _SYS_DECOMP_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CH_MAGIC 0x5a636d70 /* Zcmp */
+
+#define CH_VERSION 1
+
+#define CH_ALG_ZLIB 1
+
+struct comphdr {
+ uint64_t ch_magic;
+ uint64_t ch_version;
+ uint64_t ch_algorithm;
+ uint64_t ch_fsize;
+ uint64_t ch_blksize;
+ uint64_t ch_blkmap[1];
+};
+
+#define ZMAXBUF(n) ((n) + ((n) / 1000) + 12)
+
+#ifdef _KERNEL
+
+struct dcnode {
+ struct vnode *dc_vp;
+ struct vnode *dc_subvp;
+ struct kmem_cache *dc_bufcache;
+ kmutex_t dc_lock;
+ struct dcnode *dc_hash;
+ struct dcnode *dc_lrunext;
+ struct dcnode *dc_lruprev;
+ struct comphdr *dc_hdr;
+ size_t dc_hdrsize;
+ size_t dc_zmax;
+ int dc_mapcnt;
+};
+
+#define VTODC(vp) ((struct dcnode *)(vp)->v_data)
+#define DCTOV(dp) ((dp)->dc_vp)
+
+struct vnode *decompvp(struct vnode *, struct cred *, caller_context_t *);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _SYS_DECOMP_H */
diff --git a/usr/src/uts/common/sys/fs/ufs_filio.h b/usr/src/uts/common/sys/fs/ufs_filio.h
index d97d765dd8..052be12ef4 100644
--- a/usr/src/uts/common/sys/fs/ufs_filio.h
+++ b/usr/src/uts/common/sys/fs/ufs_filio.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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -103,6 +102,7 @@ extern int ufs_fiologenable(vnode_t *, fiolog_t *, cred_t *, int);
extern int ufs_fiologdisable(vnode_t *, fiolog_t *, cred_t *, int);
extern int ufs_fioislog(vnode_t *, uint32_t *, cred_t *, int);
extern int ufs_fio_holey(vnode_t *, int, offset_t *);
+extern int ufs_mark_compressed(struct vnode *vp);
#endif /* defined(_KERNEL) && defined(__STDC__) */
diff --git a/usr/src/uts/common/sys/fs/ufs_inode.h b/usr/src/uts/common/sys/fs/ufs_inode.h
index effc5aa9f6..ec0ecdc766 100644
--- a/usr/src/uts/common/sys/fs/ufs_inode.h
+++ b/usr/src/uts/common/sys/fs/ufs_inode.h
@@ -369,6 +369,8 @@ struct dinode {
/* cflags */
#define IXATTR 0x0001 /* extended attribute */
#define IFALLOCATE 0x0002 /* fallocate'd file */
+#define ICOMPRESS 0x0004 /* compressed for dcfs - see */
+ /* `ufs_ioctl()`_FIO_COMPRESSED */
/* modes */
#define IFMT 0170000 /* type of file */
diff --git a/usr/src/uts/common/sys/isa_defs.h b/usr/src/uts/common/sys/isa_defs.h
index 08fcbd02e5..005c0f6eef 100644
--- a/usr/src/uts/common/sys/isa_defs.h
+++ b/usr/src/uts/common/sys/isa_defs.h
@@ -206,6 +206,9 @@
* This indicates that the implementation uses a dynamically
* linked unix + krtld to form the core kernel image at boot
* time, or (in the absence of this symbol) a prelinked kernel image.
+ *
+ * _OBP
+ * This indicates the firmware interface is OBP.
*/
#ifdef __cplusplus
@@ -402,7 +405,7 @@ extern "C" {
#define _DMA_USES_VIRTADDR
#define _NO_FDISK_PRESENT
#define _HAVE_TEM_FIRMWARE
-#define _UNIX_KRTLD
+#define _OBP
/*
* The following set of definitions characterize the implementation of
diff --git a/usr/src/uts/common/sys/kobj.h b/usr/src/uts/common/sys/kobj.h
index 6c8fde02b4..8537430ed0 100644
--- a/usr/src/uts/common/sys/kobj.h
+++ b/usr/src/uts/common/sys/kobj.h
@@ -122,10 +122,14 @@ struct _buf {
char *_ptr;
char *_base;
char *_name;
+ char *_dbuf;
int _size;
int _cnt;
int _off;
int _ln;
+ int _bsize;
+ int _iscmp;
+ int _dsize;
};
@@ -144,9 +148,15 @@ typedef struct {
#define kobj_newline(p) ((p)->_ln++)
#define kobj_getc(p) (--(p)->_cnt >= 0 ? ((int)*(p)->_ptr++):kobj_filbuf(p))
#define kobj_ungetc(p) (++(p)->_cnt > (p)->_size ? -1 : ((int)*(--(p)->_ptr)))
+#define kobj_comphdr(p) ((struct comphdr *)(p)->_dbuf)
-#define B_OFFSET(f_offset) (f_offset & (MAXBSIZE-1)) /* Offset into buffer */
-#define F_PAGE(f_offset) (f_offset & ~(MAXBSIZE-1)) /* Start of page */
+/* Offset into buffer */
+#define B_OFFSET(file, off) (off % (file)->_bsize)
+
+/* Start of page */
+#define F_PAGE(file, off) (off - B_OFFSET(file, off))
+
+#define F_BLKS(file, size) ((size / (file)->_bsize) * (file)->_bsize)
#if defined(_KERNEL)
diff --git a/usr/src/uts/common/sys/kobj_impl.h b/usr/src/uts/common/sys/kobj_impl.h
index 363cf5a5ca..1dd7da9ee7 100644
--- a/usr/src/uts/common/sys/kobj_impl.h
+++ b/usr/src/uts/common/sys/kobj_impl.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 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -136,8 +135,20 @@ extern int kobj_debug; /* different than moddebug */
#define KM_WAIT 0x0 /* wait for it */
#define KM_NOWAIT 0x1 /* return immediately */
-#define KM_TMP 0x1000 /* freed before kobj_init return */
-#define KM_SCRATCH 0x2000 /* not freed until boot unmap */
+#define KM_TMP 0x1000 /* freed before kobj_init returns */
+#define KM_SCRATCH 0x2000 /* not freed until kobj_sync */
+
+#ifdef KOBJ_OVERRIDES
+/*
+ * Until the kernel is fully linked, all code running in the
+ * context of krtld/kobj using bcopy or bzero must be directed
+ * to the kobj equivalents. All (ok, most) references to bcopy
+ * or bzero are thus so vectored.
+ */
+#define bcopy(s, d, n) kobj_bcopy((s), (d), (n))
+#define bzero(p, n) kobj_bzero((p), (n))
+#define strlcat(s, d, n) kobj_strlcat((s), (d), (n))
+#endif
extern kdi_t kobj_kdi;
@@ -155,7 +166,6 @@ extern int kobj_notify_add(kobj_notify_list_t *);
extern int kobj_notify_remove(kobj_notify_list_t *);
extern int do_relocations(struct module *);
extern int do_relocate(struct module *, char *, Word, int, int, Addr);
-extern void (*_kobj_printf)(void *, const char *fmt, ...);
extern struct bootops *ops;
extern void exitto(caddr_t);
extern void kobj_sync_instruction_memory(caddr_t, size_t);
@@ -170,15 +180,15 @@ extern Sym *kobj_lookup_kernel(const char *);
extern struct modctl *kobj_boot_mod_lookup(const char *);
extern void kobj_export_module(struct module *);
extern int kobj_load_primary_module(struct modctl *);
+extern int boot_compinfo(int, struct compinfo *);
+extern void mach_modpath(char *, const char *);
-#ifdef __sparc
-extern void *kobj_bs_alloc(size_t);
-
-extern void *kobj_tmp_alloc(size_t);
-extern void kobj_tmp_free(void);
-#else
-extern void kobj_boot_unmountroot(void);
-#endif
+extern void kobj_setup_standalone_vectors(void);
+extern void kobj_restore_vectors(void);
+extern void (*_kobj_printf)(void *, const char *fmt, ...);
+extern void (*kobj_bcopy)(const void *, void *, size_t);
+extern void (*kobj_bzero)(void *, size_t);
+extern size_t (*kobj_strlcat)(char *, const char *, size_t);
#define KOBJ_LM_PRIMARY 0x0
#define KOBJ_LM_DEBUGGER 0x1
diff --git a/usr/src/uts/common/sys/ramdisk.h b/usr/src/uts/common/sys/ramdisk.h
index a33e2d1cb1..a750336d37 100644
--- a/usr/src/uts/common/sys/ramdisk.h
+++ b/usr/src/uts/common/sys/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 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -164,7 +163,11 @@ struct rd_ioctl {
* ranges; these are described by the 'existing' property, whose value
* is a (corresponding) number of {phys,size} pairs.
*/
-#define RD_EXISTING_PROP_NAME "existing"
+#define OBP_EXISTING_PROP_NAME "existing"
+#define OBP_ADDRESS_PROP_NAME "address"
+#define OBP_SIZE_PROP_NAME "size"
+
+#define RD_EXISTING_PROP_NAME "existing" /* for x86 */
typedef struct {
uint64_t phys; /* Phys addr of range */
@@ -199,6 +202,7 @@ typedef struct rd_devstate {
* giving the offset within the ramdisk of the window, its size,
* and its virtual address (in the kernel heap).
*/
+ uint_t rd_window_obp; /* using OBP's vaddr */
offset_t rd_window_base;
uint64_t rd_window_size;
caddr_t rd_window_virt;
diff --git a/usr/src/uts/common/sys/systm.h b/usr/src/uts/common/sys/systm.h
index b34d7ed304..df834a88ec 100644
--- a/usr/src/uts/common/sys/systm.h
+++ b/usr/src/uts/common/sys/systm.h
@@ -90,7 +90,9 @@ extern pgcnt_t freemem; /* Current free memory. */
extern dev_t rootdev; /* device of the root */
extern struct vnode *rootvp; /* vnode of root device */
-extern int root_is_svm; /* root is a mirrored device flag */
+extern boolean_t root_is_svm; /* root is a mirrored device flag */
+extern boolean_t root_is_ramdisk; /* root is boot_archive ramdisk */
+extern uint32_t ramdisk_size; /* (KB) set only for sparc netboots */
extern char *volatile panicstr; /* panic string pointer */
extern va_list panicargs; /* panic arguments */
diff --git a/usr/src/uts/common/syscall/systeminfo.c b/usr/src/uts/common/syscall/systeminfo.c
index dd3dade3c5..5094294188 100644
--- a/usr/src/uts/common/syscall/systeminfo.c
+++ b/usr/src/uts/common/syscall/systeminfo.c
@@ -47,6 +47,7 @@
#include <sys/promif.h>
#include <sys/zone.h>
#include <sys/model.h>
+#include <netinet/inetutil.h>
static void get_netif_name(char *, char *);
@@ -91,7 +92,7 @@ systeminfo(int command, char *buf, long count)
break;
case SI_ARCHITECTURE_NATIVE:
kstr = get_udatamodel() == DATAMODEL_NATIVE ?
- architecture : architecture_32;
+ architecture : architecture_32;
break;
#else
case SI_ARCHITECTURE_K:
@@ -141,6 +142,7 @@ systeminfo(int command, char *buf, long count)
case SI_DHCP_CACHE:
{
char *tmp;
+ unsigned int tlen, octlen;
if (dhcack == NULL) {
tmp = "";
@@ -157,37 +159,53 @@ systeminfo(int command, char *buf, long count)
}
/*
* If the interface name has not yet been resolved
- * (first IFNAMSIZ bytes of dhcack[]) and a valid
- * netdev_path[] was stashed by loadrootmodules in
- * swapgeneric.c, or established above, resolve
- * the interface name now.
+ * and a validnetdev_path[] was stashed by
+ * loadrootmodules in swapgeneric.c, or established
+ * above, resolve the interface name now.
*/
- if (dhcack[0] == '\0' &&
+ if (dhcifname[0] == '\0' &&
netdev_path != NULL && netdev_path[0] != '\0') {
- get_netif_name(netdev_path, dhcack);
+ get_netif_name(netdev_path, dhcifname);
}
- tmp = dhcack;
- strcnt = IFNAMSIZ + strlen(&tmp[IFNAMSIZ]);
+ /*
+ * Form reply:
+ * IFNAMESIZ array of dhcp i/f
+ * hexascii representation of dhcp reply
+ */
+ octlen = dhcacklen * 2 + 1;
+ tlen = octlen + IFNAMSIZ;
+ tmp = kmem_alloc(tlen, KM_SLEEP);
+ (void) strncpy(tmp, dhcifname, IFNAMSIZ);
+ if (octet_to_hexascii(dhcack, dhcacklen,
+ &tmp[IFNAMSIZ], &octlen) != 0) {
+ kmem_free(tmp, tlen);
+ error = EINVAL;
+ break;
+ } else {
+ strcnt = IFNAMSIZ + octlen;
+ }
}
if (count > 0) {
if (count <= strcnt) {
getcnt = count - 1;
- if (subyte((buf + getcnt), 0) < 0) {
- error = EFAULT;
- break;
- }
+ if (subyte((buf + getcnt), 0) < 0)
+ goto fail;
} else {
getcnt = strcnt + 1;
}
- if (copyout(tmp, buf, getcnt)) {
- error = EFAULT;
- break;
- }
+ if (copyout(tmp, buf, getcnt))
+ goto fail;
}
-
+ if (strcnt != 0)
+ kmem_free(tmp, tlen);
return (strcnt + 1);
+fail:
+ if (strcnt != 0)
+ kmem_free(tmp, tlen);
+ error = EFAULT;
+ break;
}
case SI_SET_HOSTNAME:
diff --git a/usr/src/uts/i86pc/os/ddi_impl.c b/usr/src/uts/i86pc/os/ddi_impl.c
index 1ddc6aa0f7..e001a30f78 100644
--- a/usr/src/uts/i86pc/os/ddi_impl.c
+++ b/usr/src/uts/i86pc/os/ddi_impl.c
@@ -86,7 +86,6 @@ struct pci_bus_resource *pci_bus_res;
size_t dma_max_copybuf_size = 0x101000; /* 1M + 4K */
-extern int root_is_svm;
uint64_t ramdisk_start, ramdisk_end;
/*
@@ -2557,7 +2556,7 @@ getrootdev(void)
/*
* Precedence given to rootdev if set in /etc/system
*/
- if (root_is_svm) {
+ if (root_is_svm == B_TRUE) {
return (ddi_pathname_to_dev_t(svm_bootpath));
}
diff --git a/usr/src/uts/i86pc/os/fakebop.c b/usr/src/uts/i86pc/os/fakebop.c
index dc4de9eb30..622097c84e 100644
--- a/usr/src/uts/i86pc/os/fakebop.c
+++ b/usr/src/uts/i86pc/os/fakebop.c
@@ -383,7 +383,7 @@ bsetpropsi(char *name, int value)
*/
/*ARGSUSED*/
int
-do_bsys_getproplen(bootops_t *bop, char *name)
+do_bsys_getproplen(bootops_t *bop, const char *name)
{
bootprop_t *b;
@@ -400,7 +400,7 @@ do_bsys_getproplen(bootops_t *bop, char *name)
*/
/*ARGSUSED*/
int
-do_bsys_getprop(bootops_t *bop, char *name, void *value)
+do_bsys_getprop(bootops_t *bop, const char *name, void *value)
{
bootprop_t *b;
@@ -698,7 +698,7 @@ done:
/*PRINTFLIKE2*/
/*ARGSUSED*/
void
-bop_printf(bootops_t *bop, char *fmt, ...)
+bop_printf(bootops_t *bop, const char *fmt, ...)
{
va_list ap;
@@ -717,7 +717,7 @@ bop_printf(bootops_t *bop, char *fmt, ...)
*/
/*PRINTFLIKE1*/
void
-bop_panic(char *fmt, ...)
+bop_panic(const char *fmt, ...)
{
va_list ap;
@@ -1216,8 +1216,11 @@ build_boot_properties(void)
/*
* set boot-args property
+ * 1275 name is bootargs, so set
+ * that too
*/
bsetprops("boot-args", boot_args);
+ bsetprops("bootargs", boot_args);
#ifndef __xpv
/*
@@ -2029,3 +2032,12 @@ usbser_init(size_t size)
&p, sizeof (p));
return (p);
}
+
+/*ARGSUSED*/
+int
+boot_compinfo(int fd, struct compinfo *cbp)
+{
+ cbp->iscmp = 0;
+ cbp->blksize = MAXBSIZE;
+ return (0);
+}
diff --git a/usr/src/uts/i86pc/os/mlsetup.c b/usr/src/uts/i86pc/os/mlsetup.c
index 2c23519515..3f5705bbc6 100644
--- a/usr/src/uts/i86pc/os/mlsetup.c
+++ b/usr/src/uts/i86pc/os/mlsetup.c
@@ -347,3 +347,40 @@ mlsetup(struct regs *rp)
if (workaround_errata(CPU) != 0)
panic("critical workaround(s) missing for boot cpu");
}
+
+
+void
+mach_modpath(char *path, const char *filename)
+{
+ /*
+ * Construct the directory path from the filename.
+ */
+
+ int len;
+ char *p;
+ const char isastr[] = "/amd64";
+ size_t isalen = strlen(isastr);
+
+ if ((p = strrchr(filename, '/')) == NULL)
+ return;
+
+ while (p > filename && *(p - 1) == '/')
+ p--; /* remove trailing '/' characters */
+ if (p == filename)
+ p++; /* so "/" -is- the modpath in this case */
+
+ /*
+ * Remove optional isa-dependent directory name - the module
+ * subsystem will put this back again (!)
+ */
+ len = p - filename;
+ if (len > isalen &&
+ strncmp(&filename[len - isalen], isastr, isalen) == 0)
+ p -= isalen;
+
+ /*
+ * "/platform/mumblefrotz" + " " + MOD_DEFPATH
+ */
+ len += (p - filename) + 1 + strlen(MOD_DEFPATH) + 1;
+ (void) strncpy(path, filename, p - filename);
+}
diff --git a/usr/src/uts/intel/Makefile.rules b/usr/src/uts/intel/Makefile.rules
index 105e2873bd..c1b13870f5 100644
--- a/usr/src/uts/intel/Makefile.rules
+++ b/usr/src/uts/intel/Makefile.rules
@@ -258,6 +258,11 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.c
$(COMPILE.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
$(CTFCONVERT_O)
+#
+# _DBOOT indicates that krtld is called from a dboot ELF section
+#
+$(OBJS_DIR)/kobj.o := CPPFLAGS += -D_DBOOT
+
$(OBJS_DIR)/%.o: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.s
$(COMPILE.s) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) -o $@ $<
$(CTFCONVERT_O)
@@ -432,3 +437,4 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/intel/$(SUBARCH_DIR)/krtld/%.s
$(LINTS_DIR)/%.ln: $(SRC)/common/util/$(SUBARCH_DIR)/%.c
@($(LHEAD) $(LINT.c) $(KRTLD_INC_PATH) $(KRTLD_CPPFLAGS) $< $(LTAIL))
+$(OBJS_DIR)/kobj.ln := CPPFLAGS += -D_DBOOT
diff --git a/usr/src/uts/intel/amd64/krtld/kobj_boot.c b/usr/src/uts/intel/amd64/krtld/kobj_boot.c
index bdd6779d01..b63486fd69 100644
--- a/usr/src/uts/intel/amd64/krtld/kobj_boot.c
+++ b/usr/src/uts/intel/amd64/krtld/kobj_boot.c
@@ -35,8 +35,8 @@
#include <sys/auxv.h>
#include <sys/kobj.h>
#include <sys/bootsvcs.h>
-#include <sys/kobj_impl.h>
#include <vm/kboot_mmu.h>
+#include <sys/kobj_impl.h>
/*
* the kernel's entry point (from locore.s)
diff --git a/usr/src/uts/intel/ia32/krtld/kobj_boot.c b/usr/src/uts/intel/ia32/krtld/kobj_boot.c
index a65721d82c..83fceab7d0 100644
--- a/usr/src/uts/intel/ia32/krtld/kobj_boot.c
+++ b/usr/src/uts/intel/ia32/krtld/kobj_boot.c
@@ -35,8 +35,8 @@
#include <sys/auxv.h>
#include <sys/kobj.h>
#include <sys/bootsvcs.h>
-#include <sys/kobj_impl.h>
#include <vm/kboot_mmu.h>
+#include <sys/kobj_impl.h>
/*
* the kernel's entry point (from locore.s)
diff --git a/usr/src/uts/intel/ia32/ml/modstubs.s b/usr/src/uts/intel/ia32/ml/modstubs.s
index d6f06c6e1f..7cee20312e 100644
--- a/usr/src/uts/intel/ia32/ml/modstubs.s
+++ b/usr/src/uts/intel/ia32/ml/modstubs.s
@@ -739,6 +739,15 @@ fcnname/**/_info: \
#endif
/*
+ * Stubs for dcfs
+ */
+#ifndef DCFS_MODULE
+ MODULE(dcfs,fs);
+ STUB(dcfs, decompvp, 0);
+ END_MODULE(dcfs);
+#endif
+
+/*
* Stubs for namefs
*/
#ifndef NAMEFS_MODULE
diff --git a/usr/src/uts/intel/sys/bootconf.h b/usr/src/uts/intel/sys/bootconf.h
index 4da7f8c3cb..89b38435cd 100644
--- a/usr/src/uts/intel/sys/bootconf.h
+++ b/usr/src/uts/intel/sys/bootconf.h
@@ -35,9 +35,10 @@
#include <sys/types.h>
#include <sys/bootregs.h> /* for struct bop_regs */
#include <sys/bootstat.h>
-#include <sys/dirent.h> /* for struct dirent */
+#include <sys/dirent.h> /* for struct dirent */
#include <sys/memlist.h>
#include <sys/obpdefs.h>
+#include <net/if.h> /* for IFNAMSIZ */
#ifdef __cplusplus
extern "C" {
@@ -108,12 +109,12 @@ typedef struct bootops {
/*
* to find the size of the buffer to allocate
*/
- int (*bsys_getproplen)(struct bootops *, char *name);
+ int (*bsys_getproplen)(struct bootops *, const char *);
/*
* get the value associated with this name
*/
- int (*bsys_getprop)(struct bootops *, char *name, void *value);
+ int (*bsys_getprop)(struct bootops *, const char *, void *);
/*
* get the name of the next property in succession
@@ -124,7 +125,7 @@ typedef struct bootops {
/*
* print formatted output
*/
- void (*bsys_printf)(struct bootops *, char *, ...);
+ void (*bsys_printf)(struct bootops *, const char *, ...);
/*
* Do a real mode interrupt
@@ -222,15 +223,16 @@ extern char *kobj_module_path;
extern char *default_path;
extern char *dhcack;
extern int dhcacklen;
+extern char dhcifname[IFNAMSIZ];
extern char *netdev_path;
extern void bop_no_more_mem(void);
/*PRINTFLIKE2*/
-extern void bop_printf(struct bootops *, char *, ...)
+extern void bop_printf(struct bootops *, const char *, ...)
__KPRINTFLIKE(2);
/*PRINTFLIKE1*/
-extern void bop_panic(char *, ...)
+extern void bop_panic(const char *, ...)
__KPRINTFLIKE(1);
extern void boot_prop_finish(void);
@@ -240,8 +242,8 @@ extern void boot_prop_finish(void);
*/
extern paddr_t do_bop_phys_alloc(uint64_t, uint64_t);
-extern int do_bsys_getproplen(bootops_t *, char *);
-extern int do_bsys_getprop(bootops_t *, char *, void *);
+extern int do_bsys_getproplen(bootops_t *, const char *);
+extern int do_bsys_getprop(bootops_t *, const char *, void *);
#endif /* _KERNEL && !_BOOT */
diff --git a/usr/src/uts/sparc/Makefile.files b/usr/src/uts/sparc/Makefile.files
index 7d4c036a18..fccd7341e3 100644
--- a/usr/src/uts/sparc/Makefile.files
+++ b/usr/src/uts/sparc/Makefile.files
@@ -79,13 +79,9 @@ CORE_OBJS += prmachdep.o
#
# misc modules
#
-KRTLD_BOOT_OBJS += kobj_boot.o
KRTLD_OBJS += \
- bootops.o \
doreloc.o \
- kobj_alloc.o \
kobj_convrelstr.o \
- kobj_crt.o \
kobj_isa.o \
kobj_reloc.o
@@ -110,6 +106,7 @@ SDT_OBJS += sdt.o
#
LINT_DEFS += -Dsparc
INC_PATH += -I$(UTSBASE)/sparc
+INC_PATH += -I$(UTSBASE)/sparc/krtld
#
# Since assym.h is a derived file, the dependency must be explicit for
diff --git a/usr/src/uts/sparc/Makefile.rules b/usr/src/uts/sparc/Makefile.rules
index b693acfa37..b7978200ad 100644
--- a/usr/src/uts/sparc/Makefile.rules
+++ b/usr/src/uts/sparc/Makefile.rules
@@ -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 1991-2003 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"
@@ -63,6 +62,14 @@ $(OBJS_DIR)/%.o: $(UTSBASE)/sparc/krtld/%.c
$(COMPILE.c) -o $@ $<
$(CTFCONVERT_O)
+#
+# _RELSEG indicates that the dynamic syms are put in a separate ELF
+# section so they can be freed later.
+#
+$(OBJS_DIR)/kobj_bootflags.o := CPPFLAGS += -I$(SRC)/common
+$(OBJS_DIR)/kobj.o := CPPFLAGS += -DMODDIR_SUFFIX=\"sparcv9\"
+$(OBJS_DIR)/kobj.o := CPPFLAGS += -D_RELSEG
+
$(OBJS_DIR)/%.o: $(UTSBASE)/sparc/krtld/%.s
$(COMPILE.s) -o $@ $<
@@ -98,6 +105,10 @@ $(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/fs/proc/%.c
$(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/krtld/%.c
@($(LHEAD) $(LINT.c) $< $(LTAIL))
+$(OBJS_DIR)/kobj_bootflags.ln := CPPFLAGS += -I$(SRC)/common
+$(OBJS_DIR)/kobj.ln := CPPFLAGS += -DMODDIR_SUFFIX=\"sparcv9\"
+$(OBJS_DIR)/kobj.ln := CPPFLAGS += -D_RELSEG
+
$(LINTS_DIR)/%.ln: $(UTSBASE)/sparc/krtld/%.s
@($(LHEAD) $(LINT.s) $< $(LTAIL))
diff --git a/usr/src/uts/sparc/Makefile.sparc.shared b/usr/src/uts/sparc/Makefile.sparc.shared
index 2db72ddc3f..58d69a0d61 100644
--- a/usr/src/uts/sparc/Makefile.sparc.shared
+++ b/usr/src/uts/sparc/Makefile.sparc.shared
@@ -340,7 +340,7 @@ SCHED_KMODS += RT TS RT_DPTBL TS_DPTBL IA FSS FX FX_DPTBL
#
FS_KMODS += dev devfs fdfs fifofs hsfs lofs namefs nfs pcfs tmpfs zfs
FS_KMODS += specfs udfs ufs autofs cachefs procfs sockfs mntfs
-FS_KMODS += ctfs objfs sharefs
+FS_KMODS += ctfs objfs sharefs dcfs
#
# Streams Modules (/kernel/strmod):
@@ -368,7 +368,6 @@ SYS_KMODS += doorfs pset acctctl portfs
MISC_KMODS += amsrc2 audiosup diaudio mixer
MISC_KMODS += consconfig gld ipc nfs_dlboot nfssrv scsi
MISC_KMODS += strplumb swapgeneric tlimod
-MISC_KMODS += krtld
MISC_KMODS += rpcsec rpcsec_gss kgssapi kmech_dummy
MISC_KMODS += kmech_krb5
MISC_KMODS += fssnap_if
diff --git a/usr/src/uts/sparc/dcfs/Makefile b/usr/src/uts/sparc/dcfs/Makefile
new file mode 100644
index 0000000000..ca4be87faf
--- /dev/null
+++ b/usr/src/uts/sparc/dcfs/Makefile
@@ -0,0 +1,88 @@
+#
+# 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
+#
+#
+# uts/sparc/dcfs/Makefile
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+# This makefile drives the production of the dcfs file system
+# kernel module.
+#
+# sparc architecture dependent
+#
+
+#
+# Path to the base of the uts directory tree (usually /usr/src/uts).
+#
+UTSBASE = ../..
+
+#
+# Define the module and object file sets.
+#
+MODULE = dcfs
+OBJECTS = $(DCFS_OBJS:%=$(OBJS_DIR)/%)
+LINTS = $(DCFS_OBJS:%.o=$(LINTS_DIR)/%.ln)
+ROOTMODULE = $(ROOT_FS_DIR)/$(MODULE)
+
+#
+# Include common rules.
+#
+include $(UTSBASE)/sparc/Makefile.sparc
+
+#
+# Define targets
+#
+ALL_TARGET = $(BINARY)
+LINT_TARGET = $(MODULE).lint
+INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
+
+#
+# Overrides.
+#
+CFLAGS += $(CCVERBOSE)
+
+#
+# Default build targets.
+#
+.KEEP_STATE:
+
+def: $(DEF_DEPS)
+
+all: $(ALL_DEPS)
+
+clean: $(CLEAN_DEPS)
+
+clobber: $(CLOBBER_DEPS)
+
+lint: $(LINT_DEPS)
+
+modlintlib: $(MODLINTLIB_DEPS)
+
+clean.lint: $(CLEAN_LINT_DEPS)
+
+install: $(INSTALL_DEPS)
+
+#
+# Include common targets.
+#
+include $(UTSBASE)/sparc/Makefile.targ
diff --git a/usr/src/uts/sparc/krtld/doreloc.c b/usr/src/uts/sparc/krtld/doreloc.c
index ff9864ae84..b044fbac43 100644
--- a/usr/src/uts/sparc/krtld/doreloc.c
+++ b/usr/src/uts/sparc/krtld/doreloc.c
@@ -28,7 +28,7 @@
#if defined(_KERNEL)
#include <sys/types.h>
-#include "reloc.h"
+#include "krtld/reloc.h"
#else
#include <stdio.h>
#include "sgs.h"
@@ -450,7 +450,7 @@ do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym,
*/
if (re_flags & FLG_RE_WDISP16) {
uvalue = ((basevalue & 0x300000) >> 6) |
- (basevalue & 0x3fff);
+ (basevalue & 0x3fff);
basevalue &= ~0x303fff;
} else {
uvalue = sigbit_mask & basevalue;
@@ -533,7 +533,7 @@ do_reloc_rtld(uchar_t rtype, uchar_t *off, Xword *value, const char *sym,
*/
if (re_flags & FLG_RE_WDISP16)
uvalue = ((uvalue & 0xc000) << 6) |
- (uvalue & 0x3fff);
+ (uvalue & 0x3fff);
else
uvalue &= sigbit_mask;
/*
diff --git a/usr/src/uts/sparc/krtld/kobj_convrelstr.c b/usr/src/uts/sparc/krtld/kobj_convrelstr.c
index 93f02bb716..8bac7172b3 100644
--- a/usr/src/uts/sparc/krtld/kobj_convrelstr.c
+++ b/usr/src/uts/sparc/krtld/kobj_convrelstr.c
@@ -20,13 +20,13 @@
*/
/*
- * 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"
#include <sys/types.h>
-#include "reloc.h"
+#include "krtld/reloc.h"
static const char *rels[R_SPARC_NUM] = {
"R_SPARC_NONE", "R_SPARC_8",
diff --git a/usr/src/uts/sparc/krtld/kobj_reloc.c b/usr/src/uts/sparc/krtld/kobj_reloc.c
index eda18f35a1..05e207810a 100644
--- a/usr/src/uts/sparc/krtld/kobj_reloc.c
+++ b/usr/src/uts/sparc/krtld/kobj_reloc.c
@@ -44,7 +44,7 @@
#include <sys/tnf_probe.h>
#include <sys/sdt.h>
-#include "reloc.h"
+#include "krtld/reloc.h"
/*
diff --git a/usr/src/uts/sparc/ml/modstubs.s b/usr/src/uts/sparc/ml/modstubs.s
index 5424c4cce7..db9f9d954f 100644
--- a/usr/src/uts/sparc/ml/modstubs.s
+++ b/usr/src/uts/sparc/ml/modstubs.s
@@ -627,6 +627,15 @@ stubs_base:
#endif
/*
+ * Stubs for dcfs
+ */
+#ifndef DCFS_MODULE
+ MODULE(dcfs,fs);
+ STUB(dcfs, decompvp, 0);
+ END_MODULE(dcfs);
+#endif
+
+/*
* Stubs for namefs
*/
#ifndef NAMEFS_MODULE
diff --git a/usr/src/uts/sparc/os/archdep.c b/usr/src/uts/sparc/os/archdep.c
index ceeee3ef44..a1964308ed 100644
--- a/usr/src/uts/sparc/os/archdep.c
+++ b/usr/src/uts/sparc/os/archdep.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.
*/
@@ -386,7 +385,7 @@ exec_set_sp(size_t stksize)
void *
boot_virt_alloc(void *addr, size_t size)
{
- return (BOP_ALLOC_VIRT(bootops, (caddr_t)addr, size));
+ return (BOP_ALLOC_VIRT((caddr_t)addr, size));
}
diff --git a/usr/src/uts/sparc/os/bootops.c b/usr/src/uts/sparc/os/bootops.c
index f01c0f8f65..b0231cae13 100644
--- a/usr/src/uts/sparc/os/bootops.c
+++ b/usr/src/uts/sparc/os/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,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.
*/
@@ -35,670 +34,518 @@
*/
#include <sys/types.h>
+#include <sys/systm.h>
#include <sys/reboot.h>
#include <sys/param.h>
#include <sys/varargs.h>
#include <sys/obpdefs.h>
-#include <sys/promif.h>
+#include <sys/promimpl.h>
+#include <sys/prom_plat.h>
#include <sys/bootconf.h>
#include <sys/bootstat.h>
+#include <sys/kobj_impl.h>
-/*
- * Implementation of the "version" boot service.
- * Return the compiled version number of this implementation.
- *
- * Note: An individual service can be tested for and versioned with
- * bop_serviceavail();
- *
- * Calling spec:
- * args[0] Service name string
- * args[1] #argument cells
- * args[2] #result cells
- * args[3] Res0: returned version number
- */
-uint_t
-bop_getversion(struct bootops *bop)
+struct bootops *bootops;
+struct bootops kbootops;
+
+pnode_t chosennode;
+
+#define FAKE_ROOT (pnode_t)1
+
+struct fakeprop {
+ char *bootname;
+ pnode_t promnode;
+ char *promname;
+} fakeprops[] = {
+ { "mfg-name", FAKE_ROOT, "name" },
+ { NULL, 0, NULL }
+};
+
+static void
+fakelook_init(void)
{
- return (bop->bsys_version);
+ struct fakeprop *fpp = fakeprops;
+
+ while (fpp->bootname != NULL) {
+ switch (fpp->promnode) {
+ case FAKE_ROOT:
+ fpp->promnode = prom_rootnode();
+ break;
+ }
+ fpp++;
+ }
+}
+
+static struct fakeprop *
+fakelook(const char *prop)
+{
+ struct fakeprop *fpp = fakeprops;
+
+ while (fpp->bootname != NULL) {
+ if (strcmp(prop, fpp->bootname) == 0)
+ return (fpp);
+ fpp++;
+ }
+ return (NULL);
}
+ihandle_t bfs_ih = OBP_BADNODE;
+ihandle_t afs_ih = OBP_BADNODE;
+
+void
+bop_init(void)
+{
+ chosennode = prom_chosennode();
+
+ fakelook_init();
+
+ /* fake bootops - it needs to point to non-NULL */
+ bootops = &kbootops;
+}
+
+#define MAXPROMFD 16
+
+static ihandle_t prom_ihs[MAXPROMFD];
+int filter_etc = 1;
/*
* 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
- *
*/
+/*ARGSUSED*/
int
-bop_open(struct bootops *bop, char *name, int flags)
+bop_open(const char *name, int flags)
+{
+ int fd = -1, layered;
+ ihandle_t ih;
+
+ /*
+ * Only look underneath archive for /etc files
+ */
+ layered = filter_etc ?
+ strncmp(name, "/etc", sizeof ("/etc") - 1) == 0 : 1;
+
+ if (afs_ih != OBP_BADNODE) {
+ ih = afs_ih;
+ fd = prom_fopen(ih, (char *)name);
+ if (fd == -1 && !layered)
+ return (BOOT_SVC_FAIL);
+ }
+ if (fd == -1 && bfs_ih != OBP_BADNODE) {
+ ih = bfs_ih;
+ fd = prom_fopen(ih, (char *)name);
+ }
+ if (fd == -1)
+ return (BOOT_SVC_FAIL);
+ ASSERT(fd < MAXPROMFD);
+ ASSERT(prom_ihs[fd] == 0);
+ prom_ihs[fd] = ih;
+ return (fd);
+}
+
+static void
+spinner(void)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("open");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(name);
- args[4] = boot_int2cell(flags);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[5]));
+ static int pos;
+ static char ind[] = "|/-\\"; /* that's entertainment? */
+ static int blks_read;
+
+ if ((blks_read++ & 0x3) == 0)
+ prom_printf("%c\b", ind[pos++ & 3]);
}
/*
* 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
- *
*/
int
-bop_read(struct bootops *bop, int fd, caddr_t buf, size_t size)
+bop_read(int fd, caddr_t buf, size_t size)
{
- boot_cell_t args[7];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("read");
- args[1] = 3;
- args[2] = 1;
-
- args[3] = boot_int2cell(fd);
- args[4] = boot_ptr2cell(buf);
- args[5] = boot_uint2cell(size);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[6]));
+ ASSERT(prom_ihs[fd] != 0);
+ spinner();
+ return (prom_fread(prom_ihs[fd], fd, buf, size));
}
/*
* 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
*/
int
-bop_seek(struct bootops *bop, int fd, off_t hi, off_t lo)
+bop_seek(int fd, off_t off)
{
- boot_cell_t args[7];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("seek");
- args[1] = 3;
- args[2] = 1;
-
- args[3] = boot_int2cell(fd);
- args[4] = boot_offt2cell(hi);
- args[5] = boot_offt2cell(lo);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[6]));
+ ASSERT(prom_ihs[fd] != 0);
+ return (prom_fseek(prom_ihs[fd], fd, off));
}
/*
* 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
*/
int
-bop_close(struct bootops *bop, int fd)
+bop_close(int fd)
{
- boot_cell_t args[5];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("close");
- args[1] = 1;
- args[2] = 1;
-
- args[3] = boot_int2cell(fd);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[4]));
+ ASSERT(prom_ihs[fd] != 0);
+ prom_fclose(prom_ihs[fd], fd);
+ prom_ihs[fd] = 0;
+ return (0);
}
/*
- * Implementation of the "alloc" boot service.
+ * Simple temp memory allocator
*
- * 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
+ * >PAGESIZE allocations are gotten directly from prom at bighand
+ * smaller ones are satisfied from littlehand, which does a
+ * 1 page bighand allocation when it runs out of memory
*/
-caddr_t
-bop_alloc(struct bootops *bop, caddr_t virthint, size_t size, int align)
-{
- boot_cell_t args[7];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("alloc");
- args[1] = 3;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(virthint);
- args[4] = boot_size2cell(size);
- args[5] = boot_int2cell(align);
- (void) (bsys_1275_call)(args);
- return ((caddr_t)(uintptr_t)boot_ptr2cell((uintptr_t)args[6]));
-}
+static caddr_t bighand = (caddr_t)BOOTTMPBASE;
+static caddr_t littlehand = (caddr_t)BOOTTMPBASE;
+
+#define NTMPALLOC 128
+
+static caddr_t temp_base[NTMPALLOC];
+static size_t temp_size[NTMPALLOC];
+static int temp_indx;
+
+#if defined(C_OBP)
+void cobp_free_mem(caddr_t, size_t);
+#endif /* C_OBP */
+
/*
- * Implementation of the "alloc_virt" boot service
- *
- * Calling spec:
- * args[0] Service name string
- * args[1] #argument cells
- * args[2] #result cells
- * args[3] virtual address
- * args[4] size to allocate
- * args[5] Resi: returned result
+ * temporary memory storage until bop_tmp_freeall is called
+ * (after the kernel heap is initialized)
*/
caddr_t
-bop_alloc_virt(struct bootops *bop, caddr_t virt, size_t size)
+bop_temp_alloc(size_t size, int align)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("alloc_virt");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(virt);
- args[4] = boot_size2cell(size);
- (void) (bsys_1275_call)(args);
- return ((caddr_t)(uintptr_t)boot_ptr2cell((uintptr_t)args[5]));
+ caddr_t ret;
+
+ /*
+ * OBP allocs 10MB to boot, which is where virthint = 0
+ * memory was allocated from. Without boot, we allocate
+ * from BOOTTMPBASE and free when we're ready to take
+ * the machine from OBP
+ */
+ if (size < PAGESIZE) {
+ size_t left =
+ ALIGN(littlehand, PAGESIZE) - (uintptr_t)littlehand;
+
+ size = roundup(size, MAX(align, 8));
+ if (size <= left) {
+ ret = littlehand;
+ littlehand += size;
+ return (ret);
+ }
+ littlehand = bighand + size;
+ }
+ size = roundup(size, PAGESIZE);
+ ret = prom_alloc(bighand, size, align);
+ if (ret == NULL)
+ prom_panic("boot temp overflow");
+ bighand += size;
+
+ /* log it for bop_fini() */
+ temp_base[temp_indx] = ret;
+ temp_size[temp_indx] = size;
+ if (++temp_indx == NTMPALLOC)
+ prom_panic("out of bop temp space");
+
+ return (ret);
}
-/*
- * Implementation of the "free" 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 free
- * args[5] Res0: returned result
- */
-/*ARGSUSED*/
void
-bop_free(struct bootops *bop, caddr_t virt, size_t size)
+bop_temp_freeall(void)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("free");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(virt);
- args[4] = boot_size2cell(size);
- (void) (bsys_1275_call)(args);
+ int i;
+
+ /*
+ * We have to call prom_free() with the same args
+ * as we used in prom_alloc()
+ */
+ for (i = 0; i < NTMPALLOC; i++) {
+ if (temp_base[i] == NULL)
+ break;
+#if !defined(C_OBP)
+ prom_free(temp_base[i], temp_size[i]);
+#else /* !C_OBP */
+ cobp_free_mem(temp_base[i], temp_size[i]);
+#endif /* !C_OBP */
+ }
}
+
/*
- * 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
+ * Implementation of the "alloc" boot service.
*/
-/*ARGSUSED*/
caddr_t
-bop_map(struct bootops *bop, caddr_t virt, int space,
- caddr_t phys, size_t size)
+bop_alloc(caddr_t virthint, size_t size, int align)
{
- boot_cell_t args[8];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("map");
- args[1] = 3;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(virt);
- args[4] = boot_int2cell(space);
- args[5] = boot_ptr2cell(phys);
- args[6] = boot_size2cell(size);
- (void) (bsys_1275_call)(args);
- return ((caddr_t)boot_cell2ptr(args[7]));
+ if (virthint == NULL)
+ return (bop_temp_alloc(size, align));
+ return (prom_alloc(virthint, size, align));
}
/*
- * 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
+ * Implementation of the "alloc_virt" boot service
*/
-/*ARGSUSED*/
-void
-bop_unmap(struct bootops *bop, caddr_t virt, size_t size)
+caddr_t
+bop_alloc_virt(caddr_t virt, size_t size)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("unmap");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(virt);
- args[4] = boot_size2cell(size);
- (void) (bsys_1275_call)(args);
+ return (prom_claim_virt(size, virt));
}
/*
- * 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
+ * Implementation of the "free" boot service.
*/
/*ARGSUSED*/
void
-bop_quiesce_io(struct bootops *bop)
+bop_free(caddr_t virt, size_t size)
{
- boot_cell_t args[4];
- int (*bsys_1275_call)(void *);
+ prom_free(virt, size);
+}
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("quiesce");
- args[1] = 0;
- args[2] = 1;
- (void) (bsys_1275_call)(args);
-}
/*
* 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*/
int
-bop_getproplen(struct bootops *bop, char *name)
+bop_getproplen(const char *name)
{
- boot_cell_t args[7];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("getproplen");
- args[1] = 1;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(name);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[4]));
+ struct fakeprop *fpp;
+ pnode_t node;
+ char *prop;
+
+ fpp = fakelook(name);
+ if (fpp != NULL) {
+ node = fpp->promnode;
+ prop = fpp->promname;
+ } else {
+ node = chosennode;
+ prop = (char *)name;
+ }
+ return (prom_getproplen(node, prop));
}
/*
* 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*/
int
-bop_getprop(struct bootops *bop, char *name, void *value)
+bop_getprop(const char *name, void *value)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("getprop");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(name);
- args[4] = boot_ptr2cell(value);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[5]));
+ struct fakeprop *fpp;
+ pnode_t node;
+ char *prop;
+
+ fpp = fakelook(name);
+ if (fpp != NULL) {
+ node = fpp->promnode;
+ prop = fpp->promname;
+ } else {
+ node = chosennode;
+ prop = (char *)name;
+ }
+ return (prom_getprop(node, prop, value));
}
/*
- * 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
+ * Implementation of the "print" boot service.
*/
/*ARGSUSED*/
-char *
-bop_nextprop(struct bootops *bop, char *prevprop)
+void
+bop_printf(void *ops, const char *fmt, ...)
{
- boot_cell_t args[5];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("nextprop");
- args[1] = 1;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(prevprop);
- (void) (bsys_1275_call)(args);
- return ((char *)boot_cell2ptr(args[4]));
+ va_list adx;
+
+ va_start(adx, fmt);
+ prom_vprintf(fmt, adx);
+ va_end(adx);
}
/*
- * 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
+ * Special routine for kmdb
*/
-/*ARGSUSED*/
void
-bop_puts(struct bootops *bop, char *string)
+bop_putsarg(const char *fmt, char *arg)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
- void (*bsys_printf)(struct bootops *, char *, ...);
-
- /* so new kernel, old boot can print a message before dying */
- if (!BOOTOPS_ARE_1275(bop)) {
- /* use uintptr_t to suppress the gcc warning */
- bsys_printf = (void (*)(struct bootops *, char *, ...))
- (uintptr_t)bop->bsys_printf;
- (*bsys_printf)(bop, string);
- return;
- }
-
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("puts");
- args[1] = 1;
- args[2] = 0;
-
- args[3] = boot_ptr2cell(string);
- (void) (bsys_1275_call)(args);
-
+ prom_printf(fmt, arg);
}
/*
- * 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
+ * panic for krtld only
*/
-/*ARGSUSED*/
void
-bop_putsarg(struct bootops *bop, const char *string, ...)
+bop_panic(const char *s)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
- void (*bsys_printf)(struct bootops *, char *, ...);
- va_list ap;
- const char *fmt = string;
- int ells = 0;
- uint64_t arg;
-
- /*
- * We need to do the minimum printf-like stuff here to figure
- * out the size of argument, if present.
- */
- while (*fmt) {
- if (*fmt++ != '%')
- continue;
- if (*fmt == '%') {
- fmt++;
- continue;
- }
-
- while (*fmt >= '0' && *fmt <= '9')
- fmt++;
- for (ells = 0; *fmt == 'l'; fmt++)
- ells++;
- va_start(ap, string);
- switch (*fmt) {
- case 's':
- /* use uintptr_t to suppress the gcc warning */
- arg = (uint64_t)(uintptr_t)va_arg(ap, char *);
- break;
- case 'p':
- arg = (uint64_t)(uintptr_t)va_arg(ap, void *);
- break;
- case 'd':
- case 'D':
- case 'x':
- case 'X':
- case 'u':
- case 'U':
- case 'o':
- case 'O':
- if (ells == 0)
- arg = (uint64_t)va_arg(ap, uint_t);
- else if (ells == 1)
- arg = (uint64_t)va_arg(ap, ulong_t);
- else
- arg = (uint64_t)va_arg(ap, uint64_t);
- break;
- default:
- arg = (uint64_t)va_arg(ap, uint_t);
- break;
- }
- va_end(ap);
- break;
- }
-
- /* so new kernel, old boot can print a message before dying */
- if (!BOOTOPS_ARE_1275(bop)) {
- /* use uintptr_t to suppress the gcc warning */
- bsys_printf = (void (*)(struct bootops *, char *, ...))
- (uintptr_t)bop->bsys_printf;
- (*bsys_printf)(bop, (char *)string, arg);
- return;
- }
-
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("putsarg");
- args[1] = 2;
- args[2] = 0;
- args[3] = boot_ptr2cell(string);
- args[4] = boot_uint642cell(arg);
-
- (void) (bsys_1275_call)(args);
+ prom_panic((char *)s);
}
/*
* 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*/
int
-bop_mountroot(struct bootops *bop, char *path)
+bop_mountroot(void)
{
- boot_cell_t args[5];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("mountroot");
- args[1] = 2;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(path);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[4]));
+ (void) prom_getprop(chosennode, "bootfs", (caddr_t)&bfs_ih);
+ (void) prom_getprop(chosennode, "archfs", (caddr_t)&afs_ih);
+ return ((bfs_ih == -1 && afs_ih == -1) ? BOOT_SVC_FAIL : BOOT_SVC_OK);
}
/*
* Implementation of the "unmountroot" boot service.
- *
- * Calling spec:
- * args[0] Service name string
- * args[1] #argument cells
- * args[2] #result cells
- * args[3] Res0: returned result
*/
/*ARGSUSED*/
int
-bop_unmountroot(struct bootops *bop)
+bop_unmountroot(void)
{
- boot_cell_t args[4];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("unmountroot");
- args[1] = 0;
- args[2] = 1;
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[3]));
+ if (bfs_ih != OBP_BADNODE) {
+ (void) prom_close(bfs_ih);
+ bfs_ih = OBP_BADNODE;
+ }
+ if (afs_ih != OBP_BADNODE) {
+ (void) prom_close(afs_ih);
+ afs_ih = OBP_BADNODE;
+ }
+ return (BOOT_SVC_OK);
}
/*
- * 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
+ * Implementation of the "fstat" boot service.
*/
-/*ARGSUSED*/
int
-bop_serviceavail(struct bootops *bop, char *name)
+bop_fstat(int fd, struct bootstat *st)
{
- /* use uintptr_t to suppress the gcc warning */
- boot_cell_t args[5];
- int (*bsys_1275_call)(void *) =
- (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
-
- args[0] = boot_ptr2cell("serviceavail");
- args[1] = 1;
- args[2] = 1;
-
- args[3] = boot_ptr2cell(name);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[4]));
+ ASSERT(prom_ihs[fd] != 0);
+ return (prom_fsize(prom_ihs[fd], fd, (size_t *)&st->st_size));
}
+int
+boot_compinfo(int fd, struct compinfo *cb)
+{
+ ASSERT(prom_ihs[fd] != 0);
+ return (prom_compinfo(prom_ihs[fd], fd,
+ &cb->iscmp, &cb->fsize, &cb->blksize));
+}
+
+void
+bop_free_archive(void)
+{
+ char archive[OBP_MAXPATHLEN];
+ pnode_t arph;
+ uint32_t arbase, arsize, alloc_size;
+
+ /*
+ * If the ramdisk will eventually be root, or we weren't
+ * booted via the archive, then nothing to do here
+ */
+ if (root_is_ramdisk == B_TRUE ||
+ prom_getprop(chosennode, "bootarchive", archive) == -1)
+ return;
+ arph = prom_finddevice(archive);
+ if (arph == -1 ||
+ prom_getprop(arph, OBP_ALLOCSIZE, (caddr_t)&alloc_size) == -1 ||
+ prom_getprop(arph, OBP_SIZE, (caddr_t)&arsize) == -1 ||
+ prom_getprop(arph, OBP_ADDRESS, (caddr_t)&arbase) == -1)
+ prom_panic("can't free boot archive");
+
+#if !defined(C_OBP)
+ if (alloc_size == 0)
+ prom_free((caddr_t)(uintptr_t)arbase, arsize);
+ else {
+ uint32_t arend = arbase + arsize;
+
+ while (arbase < arend) {
+ prom_free((caddr_t)(uintptr_t)arbase,
+ MIN(alloc_size, arend - arbase));
+ arbase += alloc_size;
+ }
+ }
+#else /* !C_OBP */
+ cobp_free_mem((caddr_t)(uintptr_t)arbase, arsize);
+#endif /* !C_OBP */
+}
+
+#if defined(C_OBP)
/*
- * 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
+ * Blech. The C proms have a bug when freeing areas that cross
+ * page sizes, so we have to break up the free into sections
+ * bounded by the various pagesizes.
*/
-int
-bop_fstat(struct bootops *bop, int fd, struct bootstat *st)
+void
+cobp_free_mem(caddr_t base, size_t size)
{
- boot_cell_t args[6];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("fstat");
- args[1] = 2;
- args[2] = 1;
- args[3] = boot_int2cell(fd);
- args[4] = boot_ptr2cell(st);
- (void) (bsys_1275_call)(args);
- return (boot_cell2int(args[5]));
+ int i;
+ size_t len, pgsz;
+
+ /*
+ * Large pages only used when size > 512k
+ */
+ if (size < MMU_PAGESIZE512K ||
+ ((uintptr_t)base & MMU_PAGEOFFSET512K) != 0) {
+ prom_free(base, size);
+ return;
+ }
+ for (i = 3; i >= 0; i--) {
+ pgsz = page_get_pagesize(i);
+ if (size < pgsz)
+ continue;
+ len = size & ~(pgsz - 1);
+ prom_free(base, len);
+ base += len;
+ size -= len;
+ }
}
+#endif /* C_OBP */
+
/*
* Implementation of the "enter_mon" boot service.
- *
- * Calling spec:
- * args[0] Service name string
- * args[1] #argument cells (0)
- * args[2] #result cells (0)
*/
void
-bop_enter_mon(struct bootops *bop)
+bop_enter_mon(void)
+{
+ prom_enter_mon();
+}
+
+/*
+ * free elf info allocated by booter
+ */
+void
+bop_free_elf(void)
+{
+ uint32_t eadr;
+ uint32_t esize;
+ extern Addr dynseg;
+ extern size_t dynsize;
+
+ if (bop_getprop("elfheader-address", (caddr_t)&eadr) == -1 ||
+ bop_getprop("elfheader-length", (caddr_t)&esize) == -1)
+ prom_panic("missing elfheader");
+ prom_free((caddr_t)(uintptr_t)eadr, roundup(esize, PAGESIZE));
+
+ prom_free((caddr_t)(uintptr_t)dynseg, roundup(dynsize, PAGESIZE));
+}
+
+
+/* Simple message to indicate that the bootops pointer has been zeroed */
+#ifdef DEBUG
+int bootops_gone_on = 0;
+#define BOOTOPS_GONE() \
+ if (bootops_gone_on) \
+ prom_printf("The bootops vec is zeroed now!\n");
+#else
+#define BOOTOPS_GONE()
+#endif /* DEBUG */
+
+void
+bop_fini(void)
{
- boot_cell_t args[4];
- int (*bsys_1275_call)(void *);
-
- /* use uintptr_t to suppress the gcc warning */
- bsys_1275_call = (int (*)(void *))(uintptr_t)bop->bsys_1275_call;
- args[0] = boot_ptr2cell("enter_mon");
- args[1] = 0;
- args[2] = 0;
- (void) (bsys_1275_call)(args);
+ bop_free_archive();
+ (void) bop_unmountroot();
+ bop_free_elf();
+ bop_temp_freeall();
+
+ bootops = (struct bootops *)NULL;
+ BOOTOPS_GONE();
}
diff --git a/usr/src/uts/sun/sys/bootconf.h b/usr/src/uts/sun/sys/bootconf.h
index beaa49a17c..814b84ef61 100644
--- a/usr/src/uts/sun/sys/bootconf.h
+++ b/usr/src/uts/sun/sys/bootconf.h
@@ -33,8 +33,11 @@
*/
#include <sys/types.h>
+#include <sys/varargs.h>
+#include <sys/sysmacros.h>
#include <sys/memlist.h>
#include <sys/bootstat.h>
+#include <net/if.h> /* for IFNAMSIZ */
#ifdef __cplusplus
extern "C" {
@@ -72,26 +75,12 @@ typedef struct bootops {
uint_t bsys_version;
/*
- * pointer to our parents bootops
- */
- struct bootops *bsys_super;
-
- /*
- * the area containing boot's memlists (non-LP64 boot)
- */
- struct bsys_mem *boot_mem;
-
-#ifndef _LP64
- uint32_t bsys_pad2[2]; /* pointers above get larger */
-#endif
- /*
* The entry point to jump to for boot services.
* Pass this routine the array of boot_cell_t's describing the
* service requested.
*/
uint64_t bsys_1275_call;
- uint32_t bsys_pad1[7];
/*
* print formatted output - PRINTFLIKE1
* here (and maintained) so old kernels can fail with
@@ -101,51 +90,43 @@ typedef struct bootops {
uint32_t bsys_printf;
} bootops_t;
-extern uint_t bop_getversion(struct bootops *bootops);
-extern int bop_open(struct bootops *bop, char *s, int flags);
-extern int bop_read(struct bootops *bop, int fd, caddr_t buf, size_t size);
-extern int bop_seek(struct bootops *bop, int fd, off_t hi, off_t lo);
-extern int bop_close(struct bootops *bop, int fd);
-extern caddr_t bop_alloc(struct bootops *bop, caddr_t virthint, size_t size,
- int align);
-extern caddr_t bop_alloc_virt(struct bootops *bop, caddr_t virt, size_t size);
-extern void bop_free(struct bootops *bop, caddr_t virt, size_t size);
-extern caddr_t bop_map(struct bootops *bop, caddr_t virt, int space,
- caddr_t phys, size_t size);
-extern void bop_unmap(struct bootops *bop, caddr_t virt, size_t size);
-extern void bop_quiesce_io(struct bootops *bop);
-extern int bop_getproplen(struct bootops *bop, char *name);
-extern int bop_getprop(struct bootops *bop, char *name, void *value);
-extern char *bop_nextprop(struct bootops *bop, char *prevprop);
-extern int bop_mountroot(struct bootops *bop, char *path);
-extern int bop_unmountroot(struct bootops *bop);
-extern void bop_puts(struct bootops *, char *);
-extern void bop_putsarg(struct bootops *, const char *, ...);
-extern int bop_fstat(struct bootops *, int fd, struct bootstat *);
-extern void bop_enter_mon(struct bootops *bop);
-
-#define BOP_GETVERSION(bop) bop_getversion(bop)
-#define BOP_OPEN(bop, s, flags) bop_open(bop, s, flags)
-#define BOP_READ(bop, fd, buf, size) bop_read(bop, fd, buf, size)
-#define BOP_SEEK(bop, fd, hi, lo) bop_seek(bop, fd, hi, lo)
-#define BOP_CLOSE(bop, fd) bop_close(bop, fd)
+extern void bop_init(void);
+extern int bop_open(const char *s, int flags);
+extern int bop_read(int fd, caddr_t buf, size_t size);
+extern int bop_seek(int fd, off_t off);
+extern int bop_close(int fd);
+extern caddr_t bop_alloc(caddr_t virthint, size_t size, int align);
+extern caddr_t bop_alloc_virt(caddr_t virt, size_t size);
+extern caddr_t bop_temp_alloc(size_t size, int align);
+extern void bop_free(caddr_t virt, size_t size);
+extern int bop_getproplen(const char *name);
+extern int bop_getprop(const char *name, void *value);
+extern int bop_mountroot(void);
+extern int bop_unmountroot(void);
+extern int bop_fstat(int fd, struct bootstat *st);
+extern void bop_enter_mon(void);
+extern void bop_fini(void);
+
+extern void bop_printf(void *ops, const char *fmt, ...);
+extern void bop_putsarg(const char *fmt, char *arg);
+extern void bop_panic(const char *s);
+
+#define BOP_OPEN(s, flags) bop_open(s, flags)
+#define BOP_READ(fd, buf, size) bop_read(fd, buf, size)
+#define BOP_SEEK(fd, off) bop_seek(fd, off)
+#define BOP_CLOSE(fd) bop_close(fd)
#define BOP_ALLOC(bop, virthint, size, align) \
- bop_alloc(bop, virthint, size, align)
-#define BOP_ALLOC_VIRT(bop, virt, size) bop_alloc_virt(bop, virt, size)
-#define BOP_FREE(bop, virt, size) bop_free(bop, virt, size)
-#define BOP_MAP(bop, virt, space, phys, size) \
- bop_map(bop, virt, space, phys, size)
-#define BOP_UNMAP(bop, virt, size) bop_unmap(bop, virt, size)
-#define BOP_QUIESCE_IO(bop) bop_quiesce_io(bop)
-#define BOP_GETPROPLEN(bop, name) bop_getproplen(bop, name)
-#define BOP_GETPROP(bop, name, buf) bop_getprop(bop, name, buf)
-#define BOP_NEXTPROP(bop, prev) bop_nextprop(bop, prev)
-#define BOP_MOUNTROOT(bop, path) bop_mountroot(bop, path)
-#define BOP_UNMOUNTROOT(bop) bop_unmountroot(bop)
-#define BOP_PUTS(bop, msg) bop_puts(bop, msg)
-#define BOP_PUTSARG(bop, msg, arg) bop_putsarg(bop, msg, arg)
-#define BOP_FSTAT(bop, fd, st) bop_fstat(bop, fd, st)
-#define BOP_ENTER_MON(bop) bop_enter_mon(bop)
+ bop_alloc(virthint, size, align)
+#define BOP_ALLOC_VIRT(virt, size) bop_alloc_virt(virt, size)
+#define BOP_FREE(bop, virt, size) bop_free(virt, size)
+#define BOP_GETPROPLEN(bop, name) bop_getproplen(name)
+#define BOP_GETPROP(bop, name, buf) bop_getprop(name, buf)
+#define BOP_MOUNTROOT() bop_mountroot()
+#define BOP_UNMOUNTROOT() bop_unmountroot()
+#define BOP_FSTAT(bop, fd, st) bop_fstat(fd, st)
+
+/* special routine for kmdb only */
+#define BOP_PUTSARG(bop, fmt, arg) bop_putsarg(fmt, arg)
/*
* macros and declarations needed by clients of boot to
@@ -243,6 +224,8 @@ extern char kern_bootargs[];
extern char *kobj_module_path;
extern char *default_path;
extern char *dhcack;
+extern int dhcacklen;
+extern char dhcifname[IFNAMSIZ];
extern char *netdev_path;
extern char *strplumb_get_netdev_path(void);
diff --git a/usr/src/uts/sun/sys/obpdefs.h b/usr/src/uts/sun/sys/obpdefs.h
index d209af3d90..2a9fb15989 100644
--- a/usr/src/uts/sun/sys/obpdefs.h
+++ b/usr/src/uts/sun/sys/obpdefs.h
@@ -74,6 +74,8 @@ typedef phandle_t pnode_t;
#define OBP_IPI "ipi3"
#define OBP_CPU "cpu"
#define OBP_ADDRESS "address"
+#define OBP_SIZE "size"
+#define OBP_ALLOCSIZE "alloc-size"
/*
* OBP status values defines
diff --git a/usr/src/uts/sun/sys/promif.h b/usr/src/uts/sun/sys/promif.h
index a31fa87f05..bd761e6fa0 100644
--- a/usr/src/uts/sun/sys/promif.h
+++ b/usr/src/uts/sun/sys/promif.h
@@ -312,6 +312,18 @@ extern pnode_t prom_findnode_bydevtype(pnode_t id, char *devtype);
prom_enter_mon(); \
}
+/*
+ * file IO
+ */
+extern int prom_fopen(ihandle_t, char *);
+extern int prom_fseek(ihandle_t, int, unsigned long long);
+extern int prom_fread(ihandle_t, int, caddr_t, size_t);
+extern int prom_fsize(ihandle_t, int, size_t *);
+extern int prom_compinfo(ihandle_t, int, int *,
+ size_t *, size_t *);
+extern void prom_fclose(ihandle_t, int);
+
+
#endif /* _KERNEL || _KMDB */
#ifdef _KERNEL
diff --git a/usr/src/uts/sun4/conf/Mapfile b/usr/src/uts/sun4/conf/Mapfile
index 1ed243344f..9a0dd0b984 100644
--- a/usr/src/uts/sun4/conf/Mapfile
+++ b/usr/src/uts/sun4/conf/Mapfile
@@ -1,13 +1,12 @@
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# 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, 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.
@@ -42,7 +41,11 @@ data | .data;
data : $PROGBITS ?AW;
data : $NOBITS ?AW;
-reloc = LOAD ?RW V0x0;
+#
+# put reloc seg in space between text and data
+# it will be freed by the kernel after use
+#
+reloc = LOAD ?RW V0x01402000;
reloc : $DYNSYM;
reloc : $HASH;
reloc : .dynstr;
diff --git a/usr/src/uts/sun4/os/forthdebug.c b/usr/src/uts/sun4/os/forthdebug.c
index c2f9ab9f1e..244905d96e 100644
--- a/usr/src/uts/sun4/os/forthdebug.c
+++ b/usr/src/uts/sun4/os/forthdebug.c
@@ -96,7 +96,7 @@ forthdebug_init(void)
char *fth_buf, *buf_p;
ulong_t modsym;
int i, sz;
- struct bootstat bstat;
+ uint64_t fsz;
struct _buf *file;
if (!forthdebug_supported) {
@@ -113,20 +113,20 @@ forthdebug_init(void)
return;
}
- i = BOP_FSTAT(bootops, file->_fd, &bstat);
- if (i || !bstat.st_size) {
+ i = kobj_get_filesize(file, &fsz);
+ if (i || !fsz) {
cmn_err(CE_CONT, "Can't stat %s stat=%x sz=%llx\n",
- FDEBUGFILE, i, (long long)bstat.st_size);
+ FDEBUGFILE, i, (long long)fsz);
goto err_stat;
}
- fth_buf = (char *)kobj_zalloc(bstat.st_size + 1, KM_SLEEP);
- sz = kobj_read_file(file, fth_buf, bstat.st_size, 0); /* entire file */
+ fth_buf = (char *)kobj_zalloc(fsz + 1, KM_SLEEP);
+ sz = kobj_read_file(file, fth_buf, fsz, 0); /* entire file */
if (sz < 0) {
cmn_err(CE_CONT, "Error(%d) reading %s\n", sz, FDEBUGFILE);
goto done;
}
- ASSERT(bstat.st_size == sz);
+ ASSERT(fsz == sz);
fth_buf[sz] = 0;
/* resolve all essential symbols in basic_sym[] */
@@ -176,7 +176,7 @@ forthdebug_init(void)
debug_enter("Defer breakpoint enabled. Add breakpoints, then");
}
done:
- kobj_free(fth_buf, bstat.st_size + 1);
+ kobj_free(fth_buf, fsz + 1);
err_stat:
kobj_close_file(file);
diff --git a/usr/src/uts/sun4/os/memlist.c b/usr/src/uts/sun4/os/memlist.c
index 9fbac7d65b..cbef1ec58d 100644
--- a/usr/src/uts/sun4/os/memlist.c
+++ b/usr/src/uts/sun4/os/memlist.c
@@ -86,6 +86,7 @@
#include <sys/memlist_plat.h>
#include <sys/systeminfo.h>
#include <sys/promif.h>
+#include <sys/prom_plat.h>
u_longlong_t spec_hole_start = 0x80000000000ull;
u_longlong_t spec_hole_end = 0xfffff80000000000ull;
@@ -102,29 +103,9 @@ num_phys_pages()
return (npages);
}
-/*
- * Count the number of available pages and the number of
- * chunks in the list of available memory.
- */
-void
-size_physavail(
- u_longlong_t *physavail,
- size_t nelems,
- pgcnt_t *npages,
- int *memblocks)
-{
- size_t i;
-
- *npages = 0;
- *memblocks = 0;
- for (i = 0; i < nelems; i += 2) {
- *npages += (pgcnt_t)(physavail[i+1] >> PAGESHIFT);
- (*memblocks)++;
- }
-}
pgcnt_t
-size_virtalloc(u_longlong_t *avail, size_t nelems)
+size_virtalloc(prom_memlist_t *avail, size_t nelems)
{
u_longlong_t start, end;
@@ -132,10 +113,10 @@ size_virtalloc(u_longlong_t *avail, size_t nelems)
uint_t hole_allocated = 0;
uint_t i;
- for (i = 0; i < (nelems - 2); i += 2) {
+ for (i = 0; i < nelems - 1; i++) {
- start = avail[i] + avail[i + 1];
- end = avail[i + 2];
+ start = avail[i].addr + avail[i].size;
+ end = avail[i + 1].addr;
/*
* Notes:
@@ -195,182 +176,197 @@ get_max_phys_size(
}
-/*
- * Copy boot's physavail list deducting memory at "start"
- * for "size" bytes.
- */
-int
-copy_physavail(
- u_longlong_t *src,
- size_t nelems,
- struct memlist **dstp,
- uint_t start,
- uint_t size)
-{
- struct memlist *dst, *prev;
- uint_t end1;
- int deducted = 0;
- size_t i;
- dst = *dstp;
- prev = dst;
- end1 = start + size;
-
- for (i = 0; i < nelems; i += 2) {
- uint64_t addr, lsize, end2;
-
- addr = src[i];
- lsize = src[i+1];
- end2 = addr + lsize;
-
- if ((size != 0) && start >= addr && end1 <= end2) {
- /* deducted range in this chunk */
- deducted = 1;
- if (start == addr) {
- /* abuts start of chunk */
- if (end1 == end2)
- /* is equal to the chunk */
- continue;
- dst->address = end1;
- dst->size = lsize - size;
- } else if (end1 == end2) {
- /* abuts end of chunk */
- dst->address = addr;
- dst->size = lsize - size;
- } else {
- /* in the middle of the chunk */
- dst->address = addr;
- dst->size = start - addr;
- dst->next = 0;
- if (prev == dst) {
- dst->prev = 0;
- dst++;
- } else {
- dst->prev = prev;
- prev->next = dst;
- dst++;
- prev++;
- }
- dst->address = end1;
- dst->size = end2 - end1;
- }
- dst->next = 0;
- if (prev == dst) {
- dst->prev = 0;
- dst++;
- } else {
- dst->prev = prev;
- prev->next = dst;
- dst++;
- prev++;
- }
- } else {
- dst->address = src[i];
- dst->size = src[i+1];
- dst->next = 0;
- if (prev == dst) {
- dst->prev = 0;
- dst++;
- } else {
- dst->prev = prev;
- prev->next = dst;
- dst++;
- prev++;
- }
- }
- }
+struct vnode prom_ppages;
- *dstp = dst;
- return (deducted);
-}
+static void
+more_pages(uint64_t base, uint64_t len)
+{
+ void kphysm_add();
-struct vnode prom_ppages;
+ kphysm_add(base, len, 1);
+}
-/*
- * Find the pages allocated by the prom by diffing the original
- * phys_avail list and the current list. In the difference, the
- * pages not locked belong to the PROM. (The kernel has already locked
- * and removed all the pages it has allocated from the freelist, this
- * routine removes the remaining "free" pages that really belong to the
- * PROM and hashs them in on the 'prom_pages' vnode.)
- */
-void
-fix_prom_pages(struct memlist *orig, struct memlist *new)
+static void
+less_pages(uint64_t base, uint64_t len)
{
- struct memlist *list, *nlist;
+ uint64_t pa, end = base + len;
extern int kcage_on;
- nlist = new;
- for (list = orig; list; list = list->next) {
- uint64_t pa, end;
+ for (pa = base; pa < end; pa += PAGESIZE) {
pfn_t pfnum;
page_t *pp;
- if (list->address == nlist->address &&
- list->size == nlist->size) {
- nlist = nlist->next ? nlist->next : nlist;
+ pfnum = (pfn_t)(pa >> PAGESHIFT);
+ if ((pp = page_numtopp_nolock(pfnum)) == NULL)
+ cmn_err(CE_PANIC, "missing pfnum %lx", pfnum);
+
+ /*
+ * must break up any large pages that may have
+ * constituent pages being utilized for
+ * prom_alloc()'s. page_reclaim() can't handle
+ * large pages.
+ */
+ if (pp->p_szc != 0)
+ page_boot_demote(pp);
+
+ if (!PAGE_LOCKED(pp) && pp->p_lckcnt == 0) {
+ /*
+ * Ahhh yes, a prom page,
+ * suck it off the freelist,
+ * lock it, and hashin on prom_pages vp.
+ */
+ if (page_trylock(pp, SE_EXCL) == 0)
+ cmn_err(CE_PANIC, "prom page locked");
+
+ (void) page_reclaim(pp, NULL);
+ /*
+ * vnode offsets on the prom_ppages vnode
+ * are page numbers (gack) for >32 bit
+ * physical memory machines.
+ */
+ (void) page_hashin(pp, &prom_ppages,
+ (offset_t)pfnum, NULL);
+
+ if (kcage_on) {
+ ASSERT(pp->p_szc == 0);
+ PP_SETNORELOC(pp);
+ }
+ (void) page_pp_lock(pp, 0, 1);
+ }
+ }
+}
+
+void
+diff_memlists(struct memlist *proto, struct memlist *diff, void (*func)())
+{
+ uint64_t p_base, p_end, d_base, d_end;
+
+ while (proto != NULL) {
+ /*
+ * find diff item which may overlap with proto item
+ * if none, apply func to all of proto item
+ */
+ while (diff != NULL &&
+ proto->address >= diff->address + diff->size)
+ diff = diff->next;
+ if (diff == NULL) {
+ (*func)(proto->address, proto->size);
+ proto = proto->next;
+ continue;
+ }
+ if (proto->address == diff->address &&
+ proto->size == diff->size) {
+ proto = proto->next;
+ diff = diff->next;
continue;
}
+ p_base = proto->address;
+ p_end = p_base + proto->size;
+ d_base = diff->address;
+ d_end = d_base + diff->size;
/*
- * Loop through the old list looking to
- * see if each page is still in the new one.
- * If a page is not in the new list then we
- * check to see if it locked permanently.
- * If so, the kernel allocated and owns it.
- * If not, then the prom must own it. We
- * remove any pages found to owned by the prom
- * from the freelist.
+ * here p_base < d_end
+ * there are 5 cases
*/
- end = list->address + list->size;
- for (pa = list->address; pa < end; pa += PAGESIZE) {
- if (address_in_memlist(new, pa, PAGESIZE))
- continue;
+ /*
+ * d_end
+ * d_base
+ * p_end
+ * p_base
+ *
+ * apply func to all of proto item
+ */
+ if (p_end <= d_base) {
+ (*func)(p_base, proto->size);
+ proto = proto->next;
+ continue;
+ }
- pfnum = (pfn_t)(pa >> PAGESHIFT);
- if ((pp = page_numtopp_nolock(pfnum)) == NULL)
- cmn_err(CE_PANIC, "missing pfnum %lx", pfnum);
+ /*
+ * ...
+ * d_base
+ * p_base
+ *
+ * normalize by applying func from p_base to d_base
+ */
+ if (p_base < d_base)
+ (*func)(p_base, d_base - p_base);
+ if (p_end <= d_end) {
/*
- * must break up any large pages that may have
- * constituent pages being utilized for
- * BOP_ALLOC()'s. page_reclaim() can't handle
- * large pages.
+ * d_end
+ * p_end
+ * d_base
+ * p_base
+ *
+ * -or-
+ *
+ * d_end
+ * p_end
+ * p_base
+ * d_base
+ *
+ * any non-overlapping ranges applied above,
+ * so just continue
*/
- if (pp->p_szc != 0)
- page_boot_demote(pp);
-
- if (!PAGE_LOCKED(pp) && pp->p_lckcnt == 0) {
- /*
- * Ahhh yes, a prom page,
- * suck it off the freelist,
- * lock it, and hashin on prom_pages vp.
- */
- if (page_trylock(pp, SE_EXCL) == 0)
- cmn_err(CE_PANIC, "prom page locked");
-
- (void) page_reclaim(pp, NULL);
- /*
- * XXX vnode offsets on the prom_ppages vnode
- * are page numbers (gack) for >32 bit
- * physical memory machines.
- */
- (void) page_hashin(pp, &prom_ppages,
- (offset_t)pfnum, NULL);
-
- if (kcage_on) {
- ASSERT(pp->p_szc == 0);
- PP_SETNORELOC(pp);
- }
- (void) page_pp_lock(pp, 0, 1);
- page_downgrade(pp);
- }
+ proto = proto->next;
+ continue;
+ }
+
+ /*
+ * p_end
+ * d_end
+ * d_base
+ * p_base
+ *
+ * -or-
+ *
+ * p_end
+ * d_end
+ * p_base
+ * d_base
+ *
+ * Find overlapping d_base..d_end ranges, and apply func
+ * where no overlap occurs. Stop when d_base is above
+ * p_end
+ */
+ for (p_base = d_end, diff = diff->next; diff != NULL;
+ p_base = d_end, diff = diff->next) {
+ d_base = diff->address;
+ d_end = d_base + diff->size;
+ if (p_end <= d_base) {
+ (*func)(p_base, p_end - p_base);
+ break;
+ } else
+ (*func)(p_base, d_base - p_base);
}
- nlist = nlist->next ? nlist->next : nlist;
+ if (diff == NULL)
+ (*func)(p_base, p_end - p_base);
+ proto = proto->next;
}
}
+void
+sync_memlists(struct memlist *orig, struct memlist *new)
+{
+
+ /*
+ * Find pages allocated via prom by looking for
+ * pages on orig, but no on new.
+ */
+ diff_memlists(orig, new, less_pages);
+
+ /*
+ * Find pages free'd via prom by looking for
+ * pages on new, but not on orig.
+ */
+ diff_memlists(new, orig, more_pages);
+}
+
+
/*
* Find the page number of the highest installed physical
* page and the number of pages installed (one cannot be
@@ -379,7 +375,7 @@ fix_prom_pages(struct memlist *orig, struct memlist *new)
*/
void
installed_top_size_memlist_array(
- u_longlong_t *list, /* base of array */
+ prom_memlist_t *list, /* base of array */
size_t nelems, /* number of elements */
pfn_t *topp, /* return ptr for top value */
pgcnt_t *sumpagesp) /* return prt for sum of installed pages */
@@ -389,11 +385,11 @@ installed_top_size_memlist_array(
pfn_t highp; /* high page in a chunk */
size_t i;
- for (i = 0; i < nelems; i += 2) {
- highp = (list[i] + list[i+1] - 1) >> PAGESHIFT;
+ for (i = 0; i < nelems; list++, i++) {
+ highp = (list->addr + list->size - 1) >> PAGESHIFT;
if (top < highp)
top = highp;
- sumpages += (list[i+1] >> PAGESHIFT);
+ sumpages += (list->size >> PAGESHIFT);
}
*topp = top;
@@ -406,7 +402,7 @@ installed_top_size_memlist_array(
*/
void
copy_memlist(
- u_longlong_t *src,
+ prom_memlist_t *src,
size_t nelems,
struct memlist **dstp)
{
@@ -416,9 +412,9 @@ copy_memlist(
dst = *dstp;
prev = dst;
- for (i = 0; i < nelems; i += 2) {
- dst->address = src[i];
- dst->size = src[i+1];
+ for (i = 0; i < nelems; src++, i++) {
+ dst->address = src->addr;
+ dst->size = src->size;
dst->next = 0;
if (prev == dst) {
dst->prev = 0;
@@ -434,93 +430,176 @@ copy_memlist(
*dstp = dst;
}
+
static struct bootmem_props {
- char *name;
- u_longlong_t *ptr;
+ prom_memlist_t *ptr;
size_t nelems; /* actual number of elements */
- size_t bufsize; /* length of allocated buffer */
-} bootmem_props[] = {
- { "phys-installed", NULL, 0, 0 },
- { "phys-avail", NULL, 0, 0 },
- { "virt-avail", NULL, 0, 0 },
- { NULL, NULL, 0, 0 }
-};
+ size_t maxsize; /* max buffer */
+} bootmem_props[3];
#define PHYSINSTALLED 0
#define PHYSAVAIL 1
#define VIRTAVAIL 2
-void
-copy_boot_memlists(u_longlong_t **physinstalled, size_t *physinstalled_len,
- u_longlong_t **physavail, size_t *physavail_len,
- u_longlong_t **virtavail, size_t *virtavail_len)
+/*
+ * Comapct contiguous memory list elements
+ */
+static void
+compact_promlist(struct bootmem_props *bpp)
{
- int align = BO_ALIGN_L3;
- size_t len;
- struct bootmem_props *tmp = bootmem_props;
-
-tryagain:
- for (tmp = bootmem_props; tmp->name != NULL; tmp++) {
- len = BOP_GETPROPLEN(bootops, tmp->name);
- if (len == 0) {
- panic("cannot get length of \"%s\" property",
- tmp->name);
- }
- tmp->nelems = len / sizeof (u_longlong_t);
- len = roundup(len, PAGESIZE);
- if (len <= tmp->bufsize)
- continue;
- /* need to allocate more */
- if (tmp->ptr) {
- BOP_FREE(bootops, (caddr_t)tmp->ptr, tmp->bufsize);
- tmp->ptr = NULL;
- tmp->bufsize = 0;
+ int i = 0, j;
+ struct prom_memlist *pmp = bpp->ptr;
+
+ for (;;) {
+ if (pmp[i].addr + pmp[i].size == pmp[i+1].addr) {
+ pmp[i].size += pmp[i+1].size;
+ bpp->nelems--;
+ for (j = i + 1; j < bpp->nelems; j++)
+ pmp[j] = pmp[j+1];
+ pmp[j].addr = 0;
+ } else
+ i++;
+ if (i == bpp->nelems)
+ break;
+ }
+}
+
+/*
+ * Sort prom memory lists into ascending order
+ */
+static void
+sort_promlist(struct bootmem_props *bpp)
+{
+ int i, j, min;
+ struct prom_memlist *pmp = bpp->ptr;
+ struct prom_memlist temp;
+
+ for (i = 0; i < bpp->nelems; i++) {
+ min = i;
+
+ for (j = i+1; j < bpp->nelems; j++) {
+ if (pmp[j].addr < pmp[min].addr)
+ min = j;
}
- tmp->bufsize = len;
- tmp->ptr = (void *)BOP_ALLOC(bootops, 0, tmp->bufsize, align);
- if (tmp->ptr == NULL)
- panic("cannot allocate %lu bytes for \"%s\" property",
- tmp->bufsize, tmp->name);
+ if (i != min) {
+ /* Swap pmp[i] and pmp[min] */
+ temp = pmp[min];
+ pmp[min] = pmp[i];
+ pmp[i] = temp;
+ }
}
+}
+
+static int max_bootlist_sz;
+
+void
+init_boot_memlists(void)
+{
+ size_t size, len;
+ char *start;
+ struct bootmem_props *tmp;
+
/*
- * take the most current snapshot we can by calling mem-update
+ * These lists can get fragmented as the prom allocates
+ * memory, so generously round up.
*/
- if (BOP_GETPROPLEN(bootops, "memory-update") == 0)
- (void) BOP_GETPROP(bootops, "memory-update", NULL);
-
- /* did the sizes change? */
- for (tmp = bootmem_props; tmp->name != NULL; tmp++) {
- len = BOP_GETPROPLEN(bootops, tmp->name);
- tmp->nelems = len / sizeof (u_longlong_t);
- len = roundup(len, PAGESIZE);
- if (len > tmp->bufsize) {
- /* ick. Free them all and try again */
- for (tmp = bootmem_props; tmp->name != NULL; tmp++) {
- BOP_FREE(bootops, (caddr_t)tmp->ptr,
- tmp->bufsize);
- tmp->ptr = NULL;
- tmp->bufsize = 0;
- }
- goto tryagain;
- }
+ size = prom_phys_installed_len() + prom_phys_avail_len() +
+ prom_virt_avail_len();
+ size *= 4;
+ size = roundup(size, PAGESIZE);
+ start = prom_alloc(0, size, BO_NO_ALIGN);
+
+ /*
+ * Get physinstalled
+ */
+ tmp = &bootmem_props[PHYSINSTALLED];
+ len = prom_phys_installed_len();
+ if (len == 0)
+ panic("no \"reg\" in /memory");
+ tmp->nelems = len / sizeof (struct prom_memlist);
+ tmp->maxsize = len;
+ tmp->ptr = (prom_memlist_t *)start;
+ start += len;
+ size -= len;
+ (void) prom_phys_installed((caddr_t)tmp->ptr);
+ sort_promlist(tmp);
+ compact_promlist(tmp);
+
+ /*
+ * Start out giving each half of available space
+ */
+ max_bootlist_sz = size;
+ len = size / 2;
+ tmp = &bootmem_props[PHYSAVAIL];
+ tmp->maxsize = len;
+ tmp->ptr = (prom_memlist_t *)start;
+ start += len;
+
+ tmp = &bootmem_props[VIRTAVAIL];
+ tmp->maxsize = len;
+ tmp->ptr = (prom_memlist_t *)start;
+}
+
+
+void
+copy_boot_memlists(
+ prom_memlist_t **physinstalled, size_t *physinstalled_len,
+ prom_memlist_t **physavail, size_t *physavail_len,
+ prom_memlist_t **virtavail, size_t *virtavail_len)
+{
+ size_t plen, vlen, move = 0;
+ struct bootmem_props *il, *pl, *vl;
+
+ plen = prom_phys_avail_len();
+ if (plen == 0)
+ panic("no \"available\" in /memory");
+ vlen = prom_virt_avail_len();
+ if (vlen == 0)
+ panic("no \"available\" in /virtual-memory");
+ if (plen + vlen > max_bootlist_sz)
+ panic("ran out of prom_memlist space");
+
+ pl = &bootmem_props[PHYSAVAIL];
+ vl = &bootmem_props[VIRTAVAIL];
+
+ /*
+ * re-adjust ptrs if needed
+ */
+ if (plen > pl->maxsize) {
+ /* move virt avail up */
+ move = plen - pl->maxsize;
+ pl->maxsize = plen;
+ vl->ptr += move / sizeof (struct prom_memlist);
+ vl->maxsize -= move;
+ } else if (vlen > vl->maxsize) {
+ /* move virt avail down */
+ move = vlen - vl->maxsize;
+ vl->maxsize = vlen;
+ vl->ptr -= move / sizeof (struct prom_memlist);
+ pl->maxsize -= move;
}
+ pl->nelems = plen / sizeof (struct prom_memlist);
+ vl->nelems = vlen / sizeof (struct prom_memlist);
+
/* now we can retrieve the properties */
- for (tmp = bootmem_props; tmp->name != NULL; tmp++) {
- if (BOP_GETPROP(bootops, tmp->name, tmp->ptr) == -1) {
- panic("cannot retrieve \"%s\" property",
- tmp->name);
- }
- }
- *physinstalled = bootmem_props[PHYSINSTALLED].ptr;
- *physinstalled_len = bootmem_props[PHYSINSTALLED].nelems;
+ (void) prom_phys_avail((caddr_t)pl->ptr);
+ (void) prom_virt_avail((caddr_t)vl->ptr);
+
+ /* .. and sort them */
+ sort_promlist(pl);
+ sort_promlist(vl);
+
+ il = &bootmem_props[PHYSINSTALLED];
+ *physinstalled = il->ptr;
+ *physinstalled_len = il->nelems;
- *physavail = bootmem_props[PHYSAVAIL].ptr;
- *physavail_len = bootmem_props[PHYSAVAIL].nelems;
+ *physavail = pl->ptr;
+ *physavail_len = pl->nelems;
- *virtavail = bootmem_props[VIRTAVAIL].ptr;
- *virtavail_len = bootmem_props[VIRTAVAIL].nelems;
+ *virtavail = vl->ptr;
+ *virtavail_len = vl->nelems;
}
diff --git a/usr/src/uts/sun4/os/memnode.c b/usr/src/uts/sun4/os/memnode.c
index cb21287ebd..b9d0fa3d56 100644
--- a/usr/src/uts/sun4/os/memnode.c
+++ b/usr/src/uts/sun4/os/memnode.c
@@ -185,7 +185,7 @@ mem_node_post_del_slice(pfn_t start, pfn_t end, int cancelled)
}
void
-startup_build_mem_nodes(u_longlong_t *list, size_t nelems)
+startup_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
size_t elem;
pfn_t basepfn;
@@ -200,13 +200,11 @@ startup_build_mem_nodes(u_longlong_t *list, size_t nelems)
/*
* Boot install lists are arranged <addr, len>, ...
*/
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
+ for (elem = 0; elem < nelems; list++, elem++) {
+ basepfn = btop(list->addr);
+ npgs = btop(list->size);
mem_node_add_slice(basepfn, basepfn + npgs - 1);
}
- mem_node_physalign = 0;
- mem_node_pfn_shift = 0;
}
}
diff --git a/usr/src/uts/sun4/os/mlsetup.c b/usr/src/uts/sun4/os/mlsetup.c
index af8ab0ac17..6cefe6cc99 100644
--- a/usr/src/uts/sun4/os/mlsetup.c
+++ b/usr/src/uts/sun4/os/mlsetup.c
@@ -33,6 +33,8 @@
#include <sys/autoconf.h>
#include <sys/promif.h>
#include <sys/prom_plat.h>
+#include <sys/promimpl.h>
+#include <sys/platform_module.h>
#include <sys/clock.h>
#include <sys/pte.h>
#include <sys/scb.h>
@@ -66,6 +68,10 @@
#include <sys/sunddi.h>
#include <sys/lgrp.h>
#include <sys/traptrace.h>
+
+#include <sys/kobj_impl.h>
+#include <sys/kdi_machimpl.h>
+
/*
* External Routines:
*/
@@ -115,7 +121,7 @@ static void kern_splx_postprom(void);
*/
void
-mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
+mlsetup(struct regs *rp, kfpu_t *fp)
{
struct machpcb *mpcb;
@@ -128,6 +134,10 @@ mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
TRAP_TRACE_CTL *ctlp;
#endif /* TRAPTRACE */
+ /* drop into kmdb on boot -d */
+ if (boothowto & RB_DEBUGENTER)
+ kmdb_enter();
+
/*
* initialize cpu_self
*/
@@ -205,10 +215,8 @@ mlsetup(struct regs *rp, void *cif, kfpu_t *fp)
cpu_vm_data_init(CPU);
- prom_init("kernel", cif);
(void) prom_set_preprom(kern_splr_preprom);
(void) prom_set_postprom(kern_splx_postprom);
-
PRM_INFO("mlsetup: now ok to call prom_printf");
mpcb->mpcb_pa = va_to_pa(t0.t_stk);
@@ -298,3 +306,239 @@ kern_splx_postprom(void)
{
splx(saved_spl);
}
+
+
+/*
+ * WARNING
+ * The code fom here to the end of mlsetup.c runs before krtld has
+ * knitted unix and genunix together. It can call routines in unix,
+ * but calls into genunix will fail spectacularly. More specifically,
+ * calls to prom_*, bop_* and str* will work, everything else is
+ * caveat emptor.
+ *
+ * Also note that while #ifdef sun4u is generally a bad idea, they
+ * exist here to concentrate the dangerous code into a single file.
+ */
+
+static char *
+getcpulist(void)
+{
+ pnode_t node;
+ /* big enough for OBP_NAME and for a reasonably sized OBP_COMPATIBLE. */
+ static char cpubuf[5 * OBP_MAXDRVNAME];
+ int nlen, clen, i;
+#ifdef sun4u
+ char dname[OBP_MAXDRVNAME];
+#endif
+
+ node = prom_findnode_bydevtype(prom_rootnode(), OBP_CPU);
+ if (node != OBP_NONODE && node != OBP_BADNODE) {
+ if ((nlen = prom_getproplen(node, OBP_NAME)) <= 0 ||
+ nlen > sizeof (cpubuf) ||
+ prom_getprop(node, OBP_NAME, cpubuf) <= 0)
+ prom_panic("no name in cpu node");
+
+ /* nlen includes the terminating null character */
+#ifdef sun4v
+ if ((clen = prom_getproplen(node, OBP_COMPATIBLE)) > 0) {
+#else /* sun4u */
+ /*
+ * For the CMT case, need check the parent "core"
+ * node for the compatible property.
+ */
+ if ((clen = prom_getproplen(node, OBP_COMPATIBLE)) > 0 ||
+ ((node = prom_parentnode(node)) != OBP_NONODE &&
+ node != OBP_BADNODE &&
+ (clen = prom_getproplen(node, OBP_COMPATIBLE)) > 0 &&
+ prom_getprop(node, OBP_DEVICETYPE, dname) > 0 &&
+ strcmp(dname, "core") == 0)) {
+#endif
+ if ((clen + nlen) > sizeof (cpubuf))
+ prom_panic("cpu node \"compatible\" too long");
+ /* read in compatible, leaving space for ':' */
+ if (prom_getprop(node, OBP_COMPATIBLE,
+ &cpubuf[nlen]) != clen)
+ prom_panic("cpu node \"compatible\" error");
+ clen += nlen; /* total length */
+ /* convert all null characters to ':' */
+ clen--; /* except the final one... */
+ for (i = 0; i < clen; i++)
+ if (cpubuf[i] == '\0')
+ cpubuf[i] = ':';
+ }
+#ifdef sun4u
+ /*
+ * Some PROMs return SUNW,UltraSPARC when they actually have
+ * SUNW,UltraSPARC-II cpus. SInce we're now filtering out all
+ * SUNW,UltraSPARC systems during the boot phase, we can safely
+ * point the auxv CPU value at SUNW,UltraSPARC-II.
+ */
+ if (strcmp("SUNW,UltraSPARC", cpubuf) == 0)
+ (void) strcpy(cpubuf, "SUNW,UltraSPARC-II");
+#endif
+ return (cpubuf);
+ } else
+ return (NULL);
+}
+
+/*
+ * called immediately from _start to stich the
+ * primary modules together
+ */
+void
+kobj_start(void *cif)
+{
+ Ehdr *ehdr;
+ Phdr *phdr;
+ uint32_t eadr, padr;
+ val_t bootaux[BA_NUM];
+ int i;
+
+ prom_init("kernel", cif);
+ bop_init();
+#ifdef DEBUG
+ if (bop_getproplen("stop-me") != -1)
+ prom_enter_mon();
+#endif
+
+ if (bop_getprop("elfheader-address", (caddr_t)&eadr) == -1)
+ prom_panic("no ELF image");
+ ehdr = (Ehdr *)(uintptr_t)eadr;
+ for (i = 0; i < BA_NUM; i++)
+ bootaux[i].ba_val = NULL;
+ bootaux[BA_PHNUM].ba_val = ehdr->e_phnum;
+ bootaux[BA_PHENT].ba_val = ehdr->e_phentsize;
+ bootaux[BA_LDNAME].ba_ptr = NULL;
+
+ padr = eadr + ehdr->e_phoff;
+ bootaux[BA_PHDR].ba_ptr = (void *)(uintptr_t)padr;
+ for (i = 0; i < ehdr->e_phnum; i++) {
+ phdr = (Phdr *)((uintptr_t)padr + i * ehdr->e_phentsize);
+ if (phdr->p_type == PT_DYNAMIC) {
+ bootaux[BA_DYNAMIC].ba_ptr = (void *)phdr->p_vaddr;
+ break;
+ }
+ }
+
+ bootaux[BA_LPAGESZ].ba_val = MMU_PAGESIZE4M;
+ bootaux[BA_PAGESZ].ba_val = MMU_PAGESIZE;
+ bootaux[BA_IFLUSH].ba_val = 1;
+ bootaux[BA_CPU].ba_ptr = getcpulist();
+ bootaux[BA_MMU].ba_ptr = NULL;
+
+ kobj_init(cif, NULL, bootops, bootaux);
+
+ /* kernel stitched together; we can now test #pragma's */
+ if (&plat_setprop_enter != NULL) {
+ prom_setprop_enter = &plat_setprop_enter;
+ prom_setprop_exit = &plat_setprop_exit;
+ ASSERT(prom_setprop_exit != NULL);
+ }
+
+}
+
+/*
+ * Create modpath from kernel name.
+ * If we booted:
+ * /platform/`uname -i`/kernel/sparcv9/unix
+ * or
+ * /platform/`uname -m`/kernel/sparcv9/unix
+ *
+ * then make the modpath:
+ * /platform/`uname -i`/kernel /platform/`uname -m`/kernel
+ *
+ * otherwise, make the modpath the dir the kernel was
+ * loaded from, minus any sparcv9 extension
+ *
+ * note the sparcv9 dir is optional since a unix -> sparcv9/unix
+ * symlink is available as a shortcut.
+ */
+void
+mach_modpath(char *path, const char *fname)
+{
+ char *p;
+ int len, compat;
+ const char prefix[] = "/platform/";
+ char platname[MAXPATHLEN];
+#ifdef sun4u
+ char defname[] = "sun4u";
+#else
+ char defname[] = "sun4v";
+#endif
+ const char suffix[] = "/kernel";
+ const char isastr[] = "/sparcv9";
+
+ /*
+ * check for /platform
+ */
+ p = (char *)fname;
+ if (strncmp(p, prefix, sizeof (prefix) - 1) != 0)
+ goto nopath;
+ p += sizeof (prefix) - 1;
+
+ /*
+ * check for the default name or the platform name.
+ * also see if we used the 'compatible' name
+ * (platname == default)
+ */
+ (void) bop_getprop("impl-arch-name", platname);
+ compat = strcmp(platname, defname) == 0;
+ len = strlen(platname);
+ if (strncmp(p, platname, len) == 0)
+ p += len;
+ else if (strncmp(p, defname, sizeof (defname) - 1) == 0)
+ p += sizeof (defname) - 1;
+ else
+ goto nopath;
+
+ /*
+ * check for /kernel/sparcv9 or just /kernel
+ */
+ if (strncmp(p, suffix, sizeof (suffix) - 1) != 0)
+ goto nopath;
+ p += sizeof (suffix) - 1;
+ if (strncmp(p, isastr, sizeof (isastr) - 1) == 0)
+ p += sizeof (isastr) - 1;
+
+ /*
+ * check we're at the last component
+ */
+ if (p != strrchr(fname, '/'))
+ goto nopath;
+
+ /*
+ * everything is kosher; setup modpath
+ */
+ (void) strcpy(path, "/platform/");
+ (void) strcat(path, platname);
+ (void) strcat(path, "/kernel ");
+ if (!compat) {
+ (void) strcat(path, "/platform/");
+ (void) strcat(path, defname);
+ (void) strcat(path, "/kernel ");
+ }
+ return;
+
+nopath:
+ /*
+ * Construct the directory path from the filename.
+ */
+ if ((p = strrchr(fname, '/')) == NULL)
+ return;
+
+ while (p > fname && *(p - 1) == '/')
+ p--; /* remove trailing '/' characters */
+ if (p == fname)
+ p++; /* so "/" -is- the modpath in this case */
+
+ /*
+ * Remove optional isa-dependent directory name - the module
+ * subsystem will put this back again (!)
+ */
+ len = p - fname;
+ if (len > sizeof (isastr) - 1 &&
+ strncmp(&fname[len - (sizeof (isastr) - 1)], isastr,
+ sizeof (isastr) - 1) == 0)
+ p -= sizeof (isastr) - 1;
+ (void) strncpy(path, fname, p - fname);
+}
diff --git a/usr/src/uts/sun4/os/mp_startup.c b/usr/src/uts/sun4/os/mp_startup.c
index 843e57f3d2..7d9eac0e18 100644
--- a/usr/src/uts/sun4/os/mp_startup.c
+++ b/usr/src/uts/sun4/os/mp_startup.c
@@ -56,7 +56,7 @@ uint64_t cpu_pa[NCPU]; /* pointers to all CPUs in PA */
cpu_core_t cpu_core[NCPU]; /* cpu_core structures */
#ifdef TRAPTRACE
-caddr_t ttrace_buf; /* bop alloced traptrace for all cpus except 0 */
+caddr_t ttrace_buf; /* kmem64 traptrace for all cpus except 0 */
#endif /* TRAPTRACE */
/* bit mask of cpus ready for x-calls, protected by cpu_lock */
@@ -83,26 +83,15 @@ static void slave_startup(void);
/*
* This function sets traptrace buffers for all cpus
* other than boot cpu.
- * Note that the memory at base will be allocated later.
*/
-caddr_t
-trap_trace_alloc(caddr_t base)
+size_t
+calc_traptrace_sz(void)
{
- caddr_t vaddr;
- extern int max_ncpus;
-
- if (max_ncpus == 1) {
- return (base);
- }
-
- vaddr = (caddr_t)base;
-
- ttrace_buf = vaddr;
- PRM_DEBUG(ttrace_buf);
- return (vaddr + (TRAP_TSIZE * (max_ncpus - 1)));
+ return (TRAP_TSIZE * (max_ncpus - 1));
}
#endif /* TRAPTRACE */
+
/*
* common slave cpu initialization code
*/
diff --git a/usr/src/uts/sun4/os/startup.c b/usr/src/uts/sun4/os/startup.c
index f69b831007..2974299c1b 100644
--- a/usr/src/uts/sun4/os/startup.c
+++ b/usr/src/uts/sun4/os/startup.c
@@ -128,7 +128,6 @@ char *cache_mode = NULL;
int use_mix = 1;
int prom_debug = 0;
-struct bootops *bootops = 0; /* passed in from boot in %o2 */
caddr_t boot_tba; /* %tba at boot - used by kmdb */
uint_t tba_taken_over = 0;
@@ -149,10 +148,6 @@ caddr_t econtig32; /* end of first blk of contiguous kernel */
caddr_t ncbase; /* beginning of non-cached segment */
caddr_t ncend; /* end of non-cached segment */
-caddr_t sdata; /* beginning of data segment */
-
-caddr_t extra_etva; /* beginning of unused nucleus text */
-pgcnt_t extra_etpg; /* number of pages of unused nucleus text */
size_t ndata_remain_sz; /* bytes from end of data to 4MB boundary */
caddr_t nalloc_base; /* beginning of nucleus allocation */
@@ -161,8 +156,8 @@ caddr_t valloc_base; /* beginning of kvalloc segment */
caddr_t kmem64_base; /* base of kernel mem segment in 64-bit space */
caddr_t kmem64_end; /* end of kernel mem segment in 64-bit space */
+size_t kmem64_sz; /* bytes in kernel mem segment, 64-bit space */
caddr_t kmem64_aligned_end; /* end of large page, overmaps 64-bit space */
-int kmem64_alignsize; /* page size for mem segment in 64-bit space */
int kmem64_szc; /* page size code */
uint64_t kmem64_pabase = (uint64_t)-1; /* physical address of kmem64_base */
@@ -170,6 +165,7 @@ uintptr_t shm_alignment; /* VAC address consistency modulus */
struct memlist *phys_install; /* Total installed physical memory */
struct memlist *phys_avail; /* Available (unreserved) physical memory */
struct memlist *virt_avail; /* Available (unmapped?) virtual memory */
+struct memlist *nopp_list; /* pages with no backing page structs */
struct memlist ndata; /* memlist of nucleus allocatable memory */
int memexp_flag; /* memory expansion card flag */
uint64_t ecache_flushaddr; /* physical address used for flushing E$ */
@@ -193,7 +189,7 @@ struct seg kmapseg; /* Segment used for generic kernel mappings */
struct seg kpmseg; /* Segment used for physical mapping */
struct seg kdebugseg; /* Segment used for the kernel debugger */
-uintptr_t kpm_pp_base; /* Base of system kpm_page array */
+void *kpm_pp_base; /* Base of system kpm_page array */
size_t kpm_pp_sz; /* Size of system kpm_page array */
pgcnt_t kpm_npages; /* How many kpm pages are managed */
@@ -221,8 +217,8 @@ const size_t kdi_segdebugsize = SEGDEBUGSIZE;
*/
struct seg kmem64;
-struct memseg *memseg_base;
-size_t memseg_sz; /* Used to translate a va to page */
+struct memseg *memseg_free;
+
struct vnode unused_pages_vp;
/*
@@ -239,11 +235,13 @@ size_t mpo_heap32_bufsz = 0;
/*
* Static Routines:
*/
-static void memlist_add(uint64_t, uint64_t, struct memlist **,
- struct memlist **);
-static void kphysm_init(page_t *, struct memseg *, pgcnt_t, uintptr_t,
- pgcnt_t);
+static int ndata_alloc_memseg(struct memlist *, size_t);
+static void memlist_new(uint64_t, uint64_t, struct memlist **);
+static void memlist_add(uint64_t, uint64_t,
+ struct memlist **, struct memlist **);
+static void kphysm_init(void);
static void kvm_init(void);
+static void install_kmem64_tte(void);
static void startup_init(void);
static void startup_memlist(void);
@@ -270,9 +268,6 @@ uint_t hblk1_min = H1MIN;
int iam_positron(void);
#pragma weak iam_positron
static void do_prom_version_check(void);
-static void kpm_init(void);
-static void kpm_npages_setup(int);
-static void kpm_memseg_init(void);
/*
* After receiving a thermal interrupt, this is the number of seconds
@@ -339,51 +334,8 @@ printmemseg(struct memseg *memseg)
#define MPRINTF3(str, a, b, c)
#endif /* DEBUGGING_MEM */
-/* Simple message to indicate that the bootops pointer has been zeroed */
-#ifdef DEBUG
-static int bootops_gone_on = 0;
-#define BOOTOPS_GONE() \
- if (bootops_gone_on) \
- prom_printf("The bootops vec is zeroed now!\n");
-#else
-#define BOOTOPS_GONE()
-#endif /* DEBUG */
/*
- * Monitor pages may not be where this says they are.
- * and the debugger may not be there either.
- *
- * Note that 'pages' here are *physical* pages, which are 8k on sun4u.
- *
- * Physical memory layout
- * (not necessarily contiguous)
- * (THIS IS SOMEWHAT WRONG)
- * /-----------------------\
- * | monitor pages |
- * availmem -|-----------------------|
- * | |
- * | page pool |
- * | |
- * |-----------------------|
- * | configured tables |
- * | buffers |
- * firstaddr -|-----------------------|
- * | hat data structures |
- * |-----------------------|
- * | kernel data, bss |
- * |-----------------------|
- * | interrupt stack |
- * |-----------------------|
- * | kernel text (RO) |
- * |-----------------------|
- * | trap table (4k) |
- * |-----------------------|
- * page 1 | panicbuf |
- * |-----------------------|
- * page 0 | reclaimed |
- * |_______________________|
- *
- *
*
* Kernel's Virtual Memory Layout.
* /-----------------------\
@@ -425,6 +377,11 @@ static int bootops_gone_on = 0;
* 0x000007FF.00000000 -|-----------------------|- hole_start -----
* : : ^
* : : |
+ * |-----------------------| |
+ * | | |
+ * | ecache flush area | |
+ * | (twice largest e$) | |
+ * | | |
* 0x00000XXX.XXX00000 -|-----------------------|- kmem64_ |
* | overmapped area | alignend_end |
* | (kmem64_alignsize | |
@@ -493,9 +450,12 @@ static int bootops_gone_on = 0;
* | |
* | segkmem32 segment | (SYSLIMIT32 - SYSBASE32 =
* | | ~64MB)
- * 0x00000000.78002000 -|-----------------------|
+ * 0x00000000.70002000 -|-----------------------|
* | panicbuf |
- * 0x00000000.78000000 -|-----------------------|- SYSBASE32
+ * 0x00000000.70000000 -|-----------------------|- SYSBASE32
+ * | boot-time |
+ * | temporary space |
+ * 0x00000000.4C000000 -|-----------------------|- BOOTTMPBASE
* : :
* : :
* | |
@@ -557,7 +517,7 @@ static int bootops_gone_on = 0;
* | user data |
* -|-----------------------|-
* | user text |
- * 0x00000000.00100000 -|-----------------------|-
+ * 0x00000000.01000000 -|-----------------------|-
* | invalid |
* 0x00000000.00000000 _|_______________________|
*/
@@ -698,8 +658,6 @@ startup_init(void)
*/
char bp[sizeof (sync_str) + 16 * 20];
- (void) check_boot_version(BOP_GETVERSION(bootops));
-
/*
* Initialize ptl1 stack for the 1st CPU.
*/
@@ -736,12 +694,111 @@ startup_init(void)
add_vx_handler("sync", 1, (void (*)(cell_t *))sync_handler);
}
-static u_longlong_t *boot_physinstalled, *boot_physavail, *boot_virtavail;
+
+size_t
+calc_pp_sz(pgcnt_t npages)
+{
+
+ return (npages * sizeof (struct page));
+}
+
+size_t
+calc_kpmpp_sz(pgcnt_t npages)
+{
+
+ kpm_pgshft = (kpm_smallpages == 0) ? MMU_PAGESHIFT4M : MMU_PAGESHIFT;
+ kpm_pgsz = 1ull << kpm_pgshft;
+ kpm_pgoff = kpm_pgsz - 1;
+ kpmp2pshft = kpm_pgshft - PAGESHIFT;
+ kpmpnpgs = 1 << kpmp2pshft;
+
+ if (kpm_smallpages == 0) {
+ /*
+ * Avoid fragmentation problems in kphysm_init()
+ * by allocating for all of physical memory
+ */
+ kpm_npages = ptokpmpr(physinstalled);
+ return (kpm_npages * sizeof (kpm_page_t));
+ } else {
+ kpm_npages = npages;
+ return (kpm_npages * sizeof (kpm_spage_t));
+ }
+}
+
+size_t
+calc_pagehash_sz(pgcnt_t npages)
+{
+
+ /*
+ * The page structure hash table size is a power of 2
+ * such that the average hash chain length is PAGE_HASHAVELEN.
+ */
+ page_hashsz = npages / PAGE_HASHAVELEN;
+ page_hashsz = 1 << highbit(page_hashsz);
+ return (page_hashsz * sizeof (struct page *));
+}
+
+void
+alloc_kmem64(caddr_t base, caddr_t end)
+{
+ int i;
+ caddr_t aligned_end = NULL;
+
+ /*
+ * Make one large memory alloc after figuring out the 64-bit size. This
+ * will enable use of the largest page size appropriate for the system
+ * architecture.
+ */
+ ASSERT(mmu_exported_pagesize_mask & (1 << TTE8K));
+ ASSERT(IS_P2ALIGNED(base, TTEBYTES(max_bootlp_tteszc)));
+ for (i = max_bootlp_tteszc; i >= TTE8K; i--) {
+ size_t alloc_size, alignsize;
+#if !defined(C_OBP)
+ unsigned long long pa;
+#endif /* !C_OBP */
+
+ if ((mmu_exported_pagesize_mask & (1 << i)) == 0)
+ continue;
+ alignsize = TTEBYTES(i);
+ kmem64_szc = i;
+
+ /* limit page size for small memory */
+ if (mmu_btop(alignsize) > (npages >> 2))
+ continue;
+
+ aligned_end = (caddr_t)roundup((uintptr_t)end, alignsize);
+ alloc_size = aligned_end - base;
+#if !defined(C_OBP)
+ if (prom_allocate_phys(alloc_size, alignsize, &pa) == 0) {
+ if (prom_claim_virt(alloc_size, base) != (caddr_t)-1) {
+ kmem64_pabase = pa;
+ kmem64_aligned_end = aligned_end;
+ install_kmem64_tte();
+ break;
+ } else {
+ prom_free_phys(alloc_size, pa);
+ }
+ }
+#else /* !C_OBP */
+ if (prom_alloc(base, alloc_size, alignsize) == base) {
+ kmem64_pabase = va_to_pa(kmem64_base);
+ kmem64_aligned_end = aligned_end;
+ break;
+ }
+#endif /* !C_OBP */
+ if (i == TTE8K) {
+ prom_panic("kmem64 allocation failure");
+ }
+ }
+ ASSERT(aligned_end != NULL);
+}
+
+static prom_memlist_t *boot_physinstalled, *boot_physavail, *boot_virtavail;
static size_t boot_physinstalled_len, boot_physavail_len, boot_virtavail_len;
-#define IVSIZE ((MAXIVNUM * sizeof (intr_vec_t *)) + \
- (MAX_RSVD_IV * sizeof (intr_vec_t)) + \
- (MAX_RSVD_IVX * sizeof (intr_vecx_t)))
+#define IVSIZE roundup(((MAXIVNUM * sizeof (intr_vec_t *)) + \
+ (MAX_RSVD_IV * sizeof (intr_vec_t)) + \
+ (MAX_RSVD_IVX * sizeof (intr_vecx_t))), PAGESIZE)
#if !defined(C_OBP)
/*
@@ -782,18 +839,18 @@ static size_t boot_physinstalled_len, boot_physavail_len, boot_virtavail_len;
* }
*/
char kmem64_obp_str[] =
- "h# %lx constant kmem64_base "
- "h# %lx constant kmem64_end "
- "h# %lx constant kmem64_pagemask "
- "h# %lx constant kmem64_template "
+ "h# %lx constant kmem64-base "
+ "h# %lx constant kmem64-end "
+ "h# %lx constant kmem64-pagemask "
+ "h# %lx constant kmem64-template "
": kmem64-tte ( addr cnum -- false | tte-data true ) "
" if ( addr ) "
" drop false exit then ( false ) "
- " dup kmem64_base kmem64_end within if ( addr ) "
- " kmem64_pagemask and ( addr' ) "
- " kmem64_base - ( addr' ) "
- " kmem64_template + ( tte ) "
+ " dup kmem64-base kmem64-end within if ( addr ) "
+ " kmem64-pagemask and ( addr' ) "
+ " kmem64-base - ( addr' ) "
+ " kmem64-template + ( tte ) "
" true ( tte true ) "
" else ( addr ) "
" pgmap@ ( tte ) "
@@ -804,7 +861,7 @@ char kmem64_obp_str[] =
"' kmem64-tte is va>tte-data "
;
-void
+static void
install_kmem64_tte()
{
char b[sizeof (kmem64_obp_str) + (4 * 16)];
@@ -843,24 +900,19 @@ pgcnt_t tune_npages = (pgcnt_t)
#pragma weak page_set_colorequiv_arr_cpu
extern void page_set_colorequiv_arr_cpu(void);
+extern void page_set_colorequiv_arr(void);
+
static void
startup_memlist(void)
{
- size_t alloc_sz;
- size_t ctrs_sz;
+ size_t hmehash_sz, pagelist_sz, tt_sz;
+ size_t psetable_sz;
caddr_t alloc_base;
- caddr_t ctrs_base, ctrs_end;
caddr_t memspace;
- caddr_t va;
- int memblocks = 0;
struct memlist *cur;
size_t syslimit = (size_t)SYSLIMIT;
size_t sysbase = (size_t)SYSBASE;
- int alloc_alignsize = ecache_alignsize;
- int i;
- extern void page_coloring_init(void);
- extern void page_set_colorequiv_arr(void);
/*
* Initialize enough of the system to allow kmem_alloc to work by
@@ -896,12 +948,11 @@ startup_memlist(void)
* handling operations. We align nalloc_base to a l2 cache
* linesize because this is the line size the hardware uses to
* maintain cache coherency.
- * 256K is carved out for module data.
+ * 512K is carved out for module data.
*/
- nalloc_base = (caddr_t)roundup((uintptr_t)e_data, MMU_PAGESIZE);
- moddata = nalloc_base;
- e_moddata = nalloc_base + MODDATA;
+ moddata = (caddr_t)roundup((uintptr_t)e_data, MMU_PAGESIZE);
+ e_moddata = moddata + MODDATA;
nalloc_base = e_moddata;
nalloc_end = (caddr_t)roundup((uintptr_t)nalloc_base, MMU_PAGESIZE4M);
@@ -910,12 +961,12 @@ startup_memlist(void)
/*
* Calculate the start of the data segment.
*/
- sdata = (caddr_t)((uintptr_t)e_data & MMU_PAGEMASK4M);
+ if (((uintptr_t)e_moddata & MMU_PAGEMASK4M) != (uintptr_t)s_data)
+ prom_panic("nucleus data overflow");
PRM_DEBUG(moddata);
PRM_DEBUG(nalloc_base);
PRM_DEBUG(nalloc_end);
- PRM_DEBUG(sdata);
/*
* Remember any slop after e_text so we can give it to the modules.
@@ -929,9 +980,11 @@ startup_memlist(void)
PRM_DEBUG(modtext);
PRM_DEBUG(modtext_sz);
+ init_boot_memlists();
copy_boot_memlists(&boot_physinstalled, &boot_physinstalled_len,
&boot_physavail, &boot_physavail_len,
&boot_virtavail, &boot_virtavail_len);
+
/*
* Remember what the physically available highest page is
* so that dumpsys works properly, and find out how much
@@ -946,106 +999,39 @@ startup_memlist(void)
startup_build_mem_nodes(boot_physinstalled, boot_physinstalled_len);
/*
- * Get the list of physically available memory to size
- * the number of page structures needed.
- */
- size_physavail(boot_physavail, boot_physavail_len, &npages, &memblocks);
- /*
- * This first snap shot of npages can represent the pages used
- * by OBP's text and data approximately. This is used in the
- * the calculation of the kernel size
- */
- obp_pages = physinstalled - npages;
-
-
- /*
- * On small-memory systems (<MODTEXT_SM_SIZE MB, currently 256MB), the
- * in-nucleus module text is capped to MODTEXT_SM_CAP bytes (currently
- * 2MB) and any excess pages are put on physavail. The assumption is
- * that small-memory systems will need more pages more than they'll
- * need efficiently-mapped module texts.
- */
- if ((physinstalled < mmu_btop(MODTEXT_SM_SIZE << 20)) &&
- modtext_sz > MODTEXT_SM_CAP) {
- extra_etpg = mmu_btop(modtext_sz - MODTEXT_SM_CAP);
- modtext_sz = MODTEXT_SM_CAP;
- extra_etva = modtext + modtext_sz;
- }
-
- PRM_DEBUG(extra_etpg);
- PRM_DEBUG(modtext_sz);
- PRM_DEBUG(extra_etva);
-
- /*
- * Account for any pages after e_text and e_data.
- */
- npages += extra_etpg;
- npages += mmu_btopr(nalloc_end - nalloc_base);
- PRM_DEBUG(npages);
-
- /*
* npages is the maximum of available physical memory possible.
* (ie. it will never be more than this)
+ *
+ * When we boot from a ramdisk, the ramdisk memory isn't free, so
+ * using phys_avail will underestimate what will end up being freed.
+ * A better initial guess is just total memory minus the kernel text
*/
+ npages = physinstalled - btop(MMU_PAGESIZE4M);
/*
- * initialize the nucleus memory allocator.
+ * First allocate things that can go in the nucleus data page
+ * (fault status, TSBs, dmv, CPUs)
*/
ndata_alloc_init(&ndata, (uintptr_t)nalloc_base, (uintptr_t)nalloc_end);
- /*
- * Allocate mmu fault status area from the nucleus data area.
- */
if ((&ndata_alloc_mmfsa != NULL) && (ndata_alloc_mmfsa(&ndata) != 0))
cmn_err(CE_PANIC, "no more nucleus memory after mfsa alloc");
- /*
- * Allocate kernel TSBs from the nucleus data area.
- */
if (ndata_alloc_tsbs(&ndata, npages) != 0)
cmn_err(CE_PANIC, "no more nucleus memory after tsbs alloc");
- /*
- * Allocate dmv dispatch table from the nucleus data area.
- */
if (ndata_alloc_dmv(&ndata) != 0)
cmn_err(CE_PANIC, "no more nucleus memory after dmv alloc");
-
- page_coloring_init();
-
- /*
- * Allocate page_freelists bin headers for memnode 0 from the
- * nucleus data area.
- */
- if (ndata_alloc_page_freelists(&ndata, 0) != 0)
+ if (ndata_alloc_page_mutexs(&ndata) != 0)
cmn_err(CE_PANIC,
"no more nucleus memory after page free lists alloc");
- if (kpm_enable) {
- kpm_init();
- /*
- * kpm page space -- Update kpm_npages and make the
- * same assumption about fragmenting as it is done
- * for memseg_sz.
- */
- kpm_npages_setup(memblocks + 4);
- }
-
- /*
- * Allocate hat related structs from the nucleus data area.
- */
- if (ndata_alloc_hat(&ndata, npages, kpm_npages) != 0)
+ if (ndata_alloc_hat(&ndata, npages) != 0)
cmn_err(CE_PANIC, "no more nucleus memory after hat alloc");
- /*
- * We want to do the BOP_ALLOCs before the real allocation of page
- * structs in order to not have to allocate page structs for this
- * memory. We need to calculate a virtual address because we want
- * the page structs to come before other allocations in virtual address
- * space. This is so some (if not all) of page structs can actually
- * live in the nucleus.
- */
+ if (ndata_alloc_memseg(&ndata, boot_physavail_len) != 0)
+ cmn_err(CE_PANIC, "no more nucleus memory after memseg alloc");
/*
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING
@@ -1059,6 +1045,8 @@ startup_memlist(void)
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING
*/
alloc_base = (caddr_t)roundup((uintptr_t)nalloc_end, MMU_PAGESIZE);
+ PRM_DEBUG(alloc_base);
+
alloc_base = sfmmu_ktsb_alloc(alloc_base);
alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
PRM_DEBUG(alloc_base);
@@ -1068,11 +1056,15 @@ startup_memlist(void)
* memory gets deducted from the PROM's physical memory list.
*/
alloc_base = iommu_tsb_init(alloc_base);
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- ecache_alignsize);
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
PRM_DEBUG(alloc_base);
/*
+ * Allow for an early allocation of physically contiguous memory.
+ */
+ alloc_base = contig_mem_prealloc(alloc_base, npages);
+
+ /*
* Platforms like Starcat and OPL need special structures assigned in
* 32-bit virtual address space because their probing routines execute
* FCode, and FCode can't handle 64-bit virtual addresses...
@@ -1090,189 +1082,117 @@ startup_memlist(void)
*/
econtig32 = alloc_base;
PRM_DEBUG(econtig32);
-
if (econtig32 > (caddr_t)KERNEL_LIMIT32)
cmn_err(CE_PANIC, "econtig32 too big");
- /*
- * To avoid memory allocation collisions in the 32-bit virtual address
- * space, make allocations from this point forward in 64-bit virtual
- * address space starting at syslimit and working up.
- *
- * All this is needed because on large memory systems, the default
- * Solaris allocations will collide with SYSBASE32, which is hard
- * coded to be at the virtual address 0x78000000. Therefore, on 64-bit
- * kernels, move the allocations to a location in the 64-bit virtual
- * address space space, allowing those structures to grow without
- * worry.
- *
- * On current CPUs we'll run out of physical memory address bits before
- * we need to worry about the allocations running into anything else in
- * VM or the virtual address holes on US-I and II, as there's currently
- * about 1 TB of addressable space before the US-I/II VA hole.
- */
- kmem64_base = (caddr_t)syslimit;
- PRM_DEBUG(kmem64_base);
+ pp_sz = calc_pp_sz(npages);
+ PRM_DEBUG(pp_sz);
+ if (kpm_enable) {
+ kpm_pp_sz = calc_kpmpp_sz(npages);
+ PRM_DEBUG(kpm_pp_sz);
+ }
- /*
- * Allocate addresses, but not physical memory. None of these locations
- * can be touched until physical memory is allocated below.
- */
- alloc_base = kmem64_base;
+ hmehash_sz = calc_hmehash_sz(npages);
+ PRM_DEBUG(hmehash_sz);
- /*
- * If KHME and/or UHME hash buckets won't fit in the nucleus, allocate
- * them here.
- */
- if (khme_hash == NULL || uhme_hash == NULL) {
- /*
- * alloc_hme_buckets() will align alloc_base properly before
- * assigning the hash buckets, so we don't need to do it
- * before the call...
- */
- alloc_base = alloc_hme_buckets(alloc_base, alloc_alignsize);
+ pagehash_sz = calc_pagehash_sz(npages);
+ PRM_DEBUG(pagehash_sz);
- PRM_DEBUG(alloc_base);
- PRM_DEBUG(khme_hash);
- PRM_DEBUG(uhme_hash);
- }
+ pagelist_sz = calc_free_pagelist_sz();
+ PRM_DEBUG(pagelist_sz);
+
+#ifdef TRAPTRACE
+ tt_sz = calc_traptrace_sz();
+ PRM_DEBUG(tt_sz);
+#else
+ tt_sz = 0;
+#endif /* TRAPTRACE */
/*
- * Allow for an early allocation of physically contiguous memory.
+ * Place the array that protects pp->p_selock in the kmem64 wad.
*/
- alloc_base = contig_mem_prealloc(alloc_base, npages);
+ pse_shift = size_pse_array(physmem, max_ncpus);
+ PRM_DEBUG(pse_shift);
+ pse_table_size = 1 << pse_shift;
+ PRM_DEBUG(pse_table_size);
+ psetable_sz = roundup(
+ pse_table_size * sizeof (pad_mutex_t), ecache_alignsize);
+ PRM_DEBUG(psetable_sz);
/*
- * Allocate the remaining page freelists. NUMA systems can
- * have lots of page freelists, one per node, which quickly
- * outgrow the amount of nucleus memory available.
+ * Now allocate the whole wad
*/
- if (max_mem_nodes > 1) {
- int mnode;
-
- for (mnode = 1; mnode < max_mem_nodes; mnode++) {
- alloc_base = alloc_page_freelists(mnode, alloc_base,
- ecache_alignsize);
- }
- PRM_DEBUG(alloc_base);
- }
-
- if (!mml_table) {
- size_t mmltable_sz;
-
- /*
- * We need to allocate the mml_table here because there
- * was not enough space within the nucleus.
- */
- mmltable_sz = sizeof (kmutex_t) * mml_table_sz;
- alloc_sz = roundup(mmltable_sz, alloc_alignsize);
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- alloc_alignsize);
- mml_table = (kmutex_t *)alloc_base;
- alloc_base += alloc_sz;
- PRM_DEBUG(mml_table);
- PRM_DEBUG(alloc_base);
- }
-
- if (kpm_enable && !(kpmp_table || kpmp_stable)) {
- size_t kpmptable_sz;
- caddr_t table;
-
- /*
- * We need to allocate either kpmp_table or kpmp_stable here
- * because there was not enough space within the nucleus.
- */
- kpmptable_sz = (kpm_smallpages == 0) ?
- sizeof (kpm_hlk_t) * kpmp_table_sz :
- sizeof (kpm_shlk_t) * kpmp_stable_sz;
-
- alloc_sz = roundup(kpmptable_sz, alloc_alignsize);
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- alloc_alignsize);
+ kmem64_sz = pp_sz + kpm_pp_sz + hmehash_sz + pagehash_sz +
+ pagelist_sz + tt_sz + psetable_sz;
+ kmem64_sz = roundup(kmem64_sz, PAGESIZE);
+ kmem64_base = (caddr_t)syslimit;
+ kmem64_end = kmem64_base + kmem64_sz;
+ alloc_kmem64(kmem64_base, kmem64_end);
+ if (kmem64_aligned_end > (hole_start ? hole_start : kpm_vbase))
+ cmn_err(CE_PANIC, "not enough kmem64 space");
+ PRM_DEBUG(kmem64_base);
+ PRM_DEBUG(kmem64_end);
+ PRM_DEBUG(kmem64_aligned_end);
- table = alloc_base;
+ /*
+ * ... and divy it up
+ */
+ alloc_base = kmem64_base;
+ npages -= kmem64_sz / (PAGESIZE + sizeof (struct page));
+ pp_base = (page_t *)alloc_base;
+ pp_sz = npages * sizeof (struct page);
+ alloc_base += pp_sz;
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(pp_base);
+ PRM_DEBUG(npages);
+ if (kpm_enable) {
+ kpm_pp_base = alloc_base;
if (kpm_smallpages == 0) {
- kpmp_table = (kpm_hlk_t *)table;
- PRM_DEBUG(kpmp_table);
+ /* kpm_npages based on physinstalled, don't reset */
+ kpm_pp_sz = kpm_npages * sizeof (kpm_page_t);
} else {
- kpmp_stable = (kpm_shlk_t *)table;
- PRM_DEBUG(kpmp_stable);
+ kpm_npages = ptokpmpr(npages);
+ kpm_pp_sz = kpm_npages * sizeof (kpm_spage_t);
}
-
- alloc_base += alloc_sz;
- PRM_DEBUG(alloc_base);
- }
-
- if (&ecache_init_scrub_flush_area) {
- /*
- * Pass alloc_base directly, as the routine itself is
- * responsible for any special alignment requirements...
- */
- alloc_base = ecache_init_scrub_flush_area(alloc_base);
- PRM_DEBUG(alloc_base);
+ alloc_base += kpm_pp_sz;
+ alloc_base =
+ (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(kpm_pp_base);
}
- /*
- * Take the most current snapshot we can by calling mem-update.
- */
- copy_boot_memlists(&boot_physinstalled, &boot_physinstalled_len,
- &boot_physavail, &boot_physavail_len,
- &boot_virtavail, &boot_virtavail_len);
-
- /*
- * Reset npages and memblocks based on boot_physavail list.
- */
- size_physavail(boot_physavail, boot_physavail_len, &npages, &memblocks);
- PRM_DEBUG(npages);
-
- /*
- * Account for extra memory after e_text.
- */
- npages += extra_etpg;
+ alloc_base = alloc_hmehash(alloc_base);
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(alloc_base);
- /*
- * Calculate the largest free memory chunk in the nucleus data area.
- * We need to figure out if page structs can fit in there or not.
- * We also make sure enough page structs get created for any physical
- * memory we might be returning to the system.
- */
- ndata_remain_sz = ndata_maxsize(&ndata);
- PRM_DEBUG(ndata_remain_sz);
+ page_hash = (page_t **)alloc_base;
+ alloc_base += pagehash_sz;
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(page_hash);
- pp_sz = sizeof (struct page) * npages;
+ alloc_base = alloc_page_freelists(alloc_base);
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(alloc_base);
- /*
- * Here's a nice bit of code based on somewhat recursive logic:
- *
- * If the page array would fit within the nucleus, we want to
- * add npages to cover any extra memory we may be returning back
- * to the system.
- *
- * HOWEVER, the page array is sized by calculating the size of
- * (struct page * npages), as are the pagehash table, ctrs and
- * memseg_list, so the very act of performing the calculation below may
- * in fact make the array large enough that it no longer fits in the
- * nucleus, meaning there would now be a much larger area of the
- * nucleus free that should really be added to npages, which would
- * make the page array that much larger, and so on.
- *
- * This also ignores the memory possibly used in the nucleus for the
- * the page hash, ctrs and memseg list and the fact that whether they
- * fit there or not varies with the npages calculation below, but we
- * don't even factor them into the equation at this point; perhaps we
- * should or perhaps we should just take the approach that the few
- * extra pages we could add via this calculation REALLY aren't worth
- * the hassle...
- */
- if (ndata_remain_sz > pp_sz) {
- size_t spare = ndata_spare(&ndata, pp_sz, ecache_alignsize);
+#ifdef TRAPTRACE
+ ttrace_buf = alloc_base;
+ alloc_base += tt_sz;
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(alloc_base);
+#endif /* TRAPTRACE */
- npages += mmu_btop(spare);
+ pse_mutex = (pad_mutex_t *)alloc_base;
+ alloc_base += psetable_sz;
+ alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, ecache_alignsize);
+ PRM_DEBUG(alloc_base);
- pp_sz = npages * sizeof (struct page);
+ /* adjust kmem64_end to what we really allocated */
+ kmem64_end = (caddr_t)roundup((uintptr_t)alloc_base, PAGESIZE);
+ kmem64_sz = kmem64_end - kmem64_base;
- pp_base = ndata_alloc(&ndata, pp_sz, ecache_alignsize);
+ if (&ecache_init_scrub_flush_area) {
+ alloc_base = ecache_init_scrub_flush_area(kmem64_aligned_end);
+ ASSERT(alloc_base <= (hole_start ? hole_start : kpm_vbase));
}
/*
@@ -1284,283 +1204,52 @@ startup_memlist(void)
physmem = npages;
/*
- * If pp_base is NULL that means the routines above have determined
- * the page array will not fit in the nucleus; we'll have to
- * BOP_ALLOC() ourselves some space for them.
- */
- if (pp_base == NULL) {
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- alloc_alignsize);
- alloc_sz = roundup(pp_sz, alloc_alignsize);
-
- pp_base = (struct page *)alloc_base;
-
- alloc_base += alloc_sz;
- }
-
- /*
- * The page structure hash table size is a power of 2
- * such that the average hash chain length is PAGE_HASHAVELEN.
- */
- page_hashsz = npages / PAGE_HASHAVELEN;
- page_hashsz = 1 << highbit((ulong_t)page_hashsz);
- pagehash_sz = sizeof (struct page *) * page_hashsz;
-
- /*
- * We want to TRY to fit the page structure hash table,
- * the page size free list counters, the memseg list and
- * and the kpm page space in the nucleus if possible.
+ * root_is_ramdisk is set via /etc/system when the ramdisk miniroot
+ * is mounted as root. This memory is held down by OBP and unlike
+ * the stub boot_archive is never released.
*
- * alloc_sz counts how much memory needs to be allocated by
- * BOP_ALLOC().
- */
- page_hash = ndata_alloc(&ndata, pagehash_sz, ecache_alignsize);
-
- alloc_sz = (page_hash == NULL ? pagehash_sz : 0);
-
- /*
- * Size up per page size free list counters.
- */
- ctrs_sz = page_ctrs_sz();
- ctrs_base = ndata_alloc(&ndata, ctrs_sz, ecache_alignsize);
-
- if (ctrs_base == NULL)
- alloc_sz = roundup(alloc_sz, ecache_alignsize) + ctrs_sz;
-
- /*
- * The memseg list is for the chunks of physical memory that
- * will be managed by the vm system. The number calculated is
- * a guess as boot may fragment it more when memory allocations
- * are made before kphysm_init(). Currently, there are two
- * allocations before then, so we assume each causes fragmen-
- * tation, and add a couple more for good measure.
- */
- memseg_sz = sizeof (struct memseg) * (memblocks + 4);
- memseg_base = ndata_alloc(&ndata, memseg_sz, ecache_alignsize);
-
- if (memseg_base == NULL)
- alloc_sz = roundup(alloc_sz, ecache_alignsize) + memseg_sz;
-
-
- if (kpm_enable) {
- /*
- * kpm page space -- Update kpm_npages and make the
- * same assumption about fragmenting as it is done
- * for memseg_sz above.
- */
- kpm_npages_setup(memblocks + 4);
- kpm_pp_sz = (kpm_smallpages == 0) ?
- kpm_npages * sizeof (kpm_page_t):
- kpm_npages * sizeof (kpm_spage_t);
-
- kpm_pp_base = (uintptr_t)ndata_alloc(&ndata, kpm_pp_sz,
- ecache_alignsize);
-
- if (kpm_pp_base == NULL)
- alloc_sz = roundup(alloc_sz, ecache_alignsize) +
- kpm_pp_sz;
- }
-
- /*
- * Allocate the array that protects pp->p_selock.
- */
- pse_shift = size_pse_array(physmem, max_ncpus);
- pse_table_size = 1 << pse_shift;
- pse_mutex = ndata_alloc(&ndata, pse_table_size * sizeof (pad_mutex_t),
- ecache_alignsize);
- if (pse_mutex == NULL)
- alloc_sz = roundup(alloc_sz, ecache_alignsize) +
- pse_table_size * sizeof (pad_mutex_t);
-
- if (alloc_sz > 0) {
- uintptr_t bop_base;
-
- /*
- * We need extra memory allocated through BOP_ALLOC.
- */
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base,
- alloc_alignsize);
-
- alloc_sz = roundup(alloc_sz, alloc_alignsize);
-
- bop_base = (uintptr_t)alloc_base;
-
- alloc_base += alloc_sz;
-
- if (page_hash == NULL) {
- page_hash = (struct page **)bop_base;
- bop_base = roundup(bop_base + pagehash_sz,
- ecache_alignsize);
- }
-
- if (ctrs_base == NULL) {
- ctrs_base = (caddr_t)bop_base;
- bop_base = roundup(bop_base + ctrs_sz,
- ecache_alignsize);
- }
-
- if (memseg_base == NULL) {
- memseg_base = (struct memseg *)bop_base;
- bop_base = roundup(bop_base + memseg_sz,
- ecache_alignsize);
- }
-
- if (kpm_enable && kpm_pp_base == NULL) {
- kpm_pp_base = (uintptr_t)bop_base;
- bop_base = roundup(bop_base + kpm_pp_sz,
- ecache_alignsize);
- }
-
- if (pse_mutex == NULL) {
- pse_mutex = (pad_mutex_t *)bop_base;
- bop_base = roundup(bop_base +
- pse_table_size * sizeof (pad_mutex_t),
- ecache_alignsize);
- }
-
- ASSERT(bop_base <= (uintptr_t)alloc_base);
- }
-
- PRM_DEBUG(page_hash);
- PRM_DEBUG(memseg_base);
- PRM_DEBUG(kpm_pp_base);
- PRM_DEBUG(kpm_pp_sz);
- PRM_DEBUG(pp_base);
- PRM_DEBUG(pp_sz);
- PRM_DEBUG(alloc_base);
-
-#ifdef TRAPTRACE
- alloc_base = trap_trace_alloc(alloc_base);
- PRM_DEBUG(alloc_base);
-#endif /* TRAPTRACE */
-
- /*
- * In theory it's possible that kmem64 chunk is 0 sized
- * (on very small machines). Check for that.
- */
- if (alloc_base == kmem64_base) {
- kmem64_base = NULL;
- kmem64_end = NULL;
- kmem64_aligned_end = NULL;
- goto kmem64_alloced;
- }
-
- /*
- * Allocate kmem64 memory.
- * Round up to end of large page and overmap.
- * kmem64_end..kmem64_aligned_end is added to memory list for reuse
- */
- kmem64_end = (caddr_t)roundup((uintptr_t)alloc_base,
- MMU_PAGESIZE);
-
- /*
- * Make one large memory alloc after figuring out the 64-bit size. This
- * will enable use of the largest page size appropriate for the system
- * architecture.
- */
- ASSERT(mmu_exported_pagesize_mask & (1 << TTE8K));
- ASSERT(IS_P2ALIGNED(kmem64_base, TTEBYTES(max_bootlp_tteszc)));
- for (i = max_bootlp_tteszc; i >= TTE8K; i--) {
- size_t asize;
-#if !defined(C_OBP)
- unsigned long long pa;
-#endif /* !C_OBP */
-
- if ((mmu_exported_pagesize_mask & (1 << i)) == 0)
- continue;
- kmem64_alignsize = TTEBYTES(i);
- kmem64_szc = i;
-
- /* limit page size for small memory */
- if (mmu_btop(kmem64_alignsize) > (npages >> 2))
- continue;
-
- kmem64_aligned_end = (caddr_t)roundup((uintptr_t)kmem64_end,
- kmem64_alignsize);
- asize = kmem64_aligned_end - kmem64_base;
-#if !defined(C_OBP)
- if (prom_allocate_phys(asize, kmem64_alignsize, &pa) == 0) {
- if (prom_claim_virt(asize, kmem64_base) !=
- (caddr_t)-1) {
- kmem64_pabase = pa;
- install_kmem64_tte();
- break;
- } else {
- prom_free_phys(asize, pa);
- }
- }
-#else /* !C_OBP */
- if ((caddr_t)BOP_ALLOC(bootops, kmem64_base, asize,
- kmem64_alignsize) == kmem64_base) {
- kmem64_pabase = va_to_pa(kmem64_base);
- break;
- }
-#endif /* !C_OBP */
- if (i == TTE8K) {
- prom_panic("kmem64 allocation failure");
- }
- }
-
- PRM_DEBUG(kmem64_base);
- PRM_DEBUG(kmem64_end);
- PRM_DEBUG(kmem64_aligned_end);
- PRM_DEBUG(kmem64_alignsize);
-
- /*
- * Now set pa using saved va from above.
+ * In order to get things sized correctly on lower memory
+ * machines (where the memory used by the ramdisk represents
+ * a significant portion of memory), physmem is adjusted.
+ *
+ * This is done by subtracting the ramdisk_size which is set
+ * to the size of the ramdisk (in Kb) in /etc/system at the
+ * time the miniroot archive is constructed.
*/
- if (&ecache_init_scrub_flush_area) {
- (void) ecache_init_scrub_flush_area(NULL);
- }
-
-kmem64_alloced:
+ if (root_is_ramdisk == B_TRUE)
+ physmem -= (ramdisk_size * 1024) / PAGESIZE;
- /*
- * Initialize per page size free list counters.
- */
- ctrs_end = page_ctrs_alloc(ctrs_base);
- ASSERT(ctrs_base + ctrs_sz >= ctrs_end);
+ if (kpm_enable && (ndata_alloc_kpm(&ndata, kpm_npages) != 0))
+ cmn_err(CE_PANIC, "no more nucleus memory after kpm alloc");
/*
- * Allocate space for the interrupt vector table and also for the
- * reserved interrupt vector data structures.
+ * Allocate space for the interrupt vector table.
*/
- memspace = (caddr_t)BOP_ALLOC(bootops, (caddr_t)intr_vec_table,
- IVSIZE, MMU_PAGESIZE);
+ memspace = prom_alloc((caddr_t)intr_vec_table, IVSIZE, MMU_PAGESIZE);
if (memspace != (caddr_t)intr_vec_table)
prom_panic("interrupt vector table allocation failure");
/*
- * The memory lists from boot are allocated from the heap arena
- * so that later they can be freed and/or reallocated.
- */
- if (BOP_GETPROP(bootops, "extent", &memlist_sz) == -1)
- prom_panic("could not retrieve property \"extent\"");
-
- /*
* Between now and when we finish copying in the memory lists,
* allocations happen so the space gets fragmented and the
- * lists longer. Leave enough space for lists twice as long
- * as what boot says it has now; roundup to a pagesize.
- * Also add space for the final phys-avail copy in the fixup
- * routine.
- */
- va = (caddr_t)(sysbase + PAGESIZE + PANICBUFSIZE +
- roundup(IVSIZE, MMU_PAGESIZE));
- memlist_sz *= 4;
- memlist_sz = roundup(memlist_sz, MMU_PAGESIZE);
- memspace = (caddr_t)BOP_ALLOC(bootops, va, memlist_sz, BO_NO_ALIGN);
+ * lists longer. Leave enough space for lists twice as
+ * long as we have now; then roundup to a pagesize.
+ */
+ memlist_sz = sizeof (struct memlist) * (prom_phys_installed_len() +
+ prom_phys_avail_len() + prom_virt_avail_len());
+ memlist_sz *= 2;
+ memlist_sz = roundup(memlist_sz, PAGESIZE);
+ memspace = ndata_alloc(&ndata, memlist_sz, ecache_alignsize);
if (memspace == NULL)
- halt("Boot allocation failed.");
+ cmn_err(CE_PANIC, "no more nucleus memory after memlist alloc");
memlist = (struct memlist *)memspace;
memlist_end = (char *)memspace + memlist_sz;
-
PRM_DEBUG(memlist);
PRM_DEBUG(memlist_end);
+
PRM_DEBUG(sysbase);
PRM_DEBUG(syslimit);
-
kernelheap_init((void *)sysbase, (void *)syslimit,
(caddr_t)sysbase + PAGESIZE, NULL, NULL);
@@ -1572,7 +1261,7 @@ kmem64_alloced:
&boot_virtavail, &boot_virtavail_len);
/*
- * Remove the space used by BOP_ALLOC from the kernel heap
+ * Remove the space used by prom_alloc from the kernel heap
* plus the area actually used by the OBP (if any)
* ignoring virtual addresses in virt_avail, above syslimit.
*/
@@ -1597,30 +1286,7 @@ kmem64_alloced:
}
phys_avail = memlist;
- (void) copy_physavail(boot_physavail, boot_physavail_len,
- &memlist, 0, 0);
-
- /*
- * Add any unused kmem64 memory from overmapped page
- * (Note: va_to_pa does not work for kmem64_end)
- */
- if (kmem64_end < kmem64_aligned_end) {
- uint64_t overlap_size = kmem64_aligned_end - kmem64_end;
- uint64_t overlap_pa = kmem64_pabase +
- (kmem64_end - kmem64_base);
-
- PRM_DEBUG(overlap_pa);
- PRM_DEBUG(overlap_size);
- memlist_add(overlap_pa, overlap_size, &memlist, &phys_avail);
- }
-
- /*
- * Add any extra memory after e_text to the phys_avail list, as long
- * as there's at least a page to add.
- */
- if (extra_etpg)
- memlist_add(va_to_pa(extra_etva), mmu_ptob(extra_etpg),
- &memlist, &phys_avail);
+ copy_memlist(boot_physavail, boot_physavail_len, &memlist);
/*
* Add any extra memory at the end of the ndata region if there's at
@@ -1632,25 +1298,34 @@ kmem64_alloced:
nalloc_base = nalloc_end;
ndata_remain_sz = nalloc_end - nalloc_base;
- if (ndata_remain_sz >= MMU_PAGESIZE)
- memlist_add(va_to_pa(nalloc_base),
- (uint64_t)ndata_remain_sz, &memlist, &phys_avail);
+ /*
+ * Copy physinstalled list into kernel space.
+ */
+ phys_install = memlist;
+ copy_memlist(boot_physinstalled, boot_physinstalled_len, &memlist);
- PRM_DEBUG(memlist);
- PRM_DEBUG(memlist_sz);
- PRM_DEBUG(memspace);
+ /*
+ * Create list of physical addrs we don't need pp's for:
+ * kernel text 4M page
+ * kernel data 4M page - ndata_remain_sz
+ * kmem64 pages
+ *
+ * NB if adding any pages here, make sure no kpm page
+ * overlaps can occur (see ASSERTs in kphysm_memsegs)
+ */
+ nopp_list = memlist;
+ memlist_new(va_to_pa(s_text), MMU_PAGESIZE4M, &memlist);
+ memlist_add(va_to_pa(s_data), MMU_PAGESIZE4M - ndata_remain_sz,
+ &memlist, &nopp_list);
+ memlist_add(kmem64_pabase, kmem64_sz, &memlist, &nopp_list);
if ((caddr_t)memlist > (memspace + memlist_sz))
prom_panic("memlist overflow");
- PRM_DEBUG(pp_base);
- PRM_DEBUG(memseg_base);
- PRM_DEBUG(npages);
-
/*
* Initialize the page structures from the memory lists.
*/
- kphysm_init(pp_base, memseg_base, npages, kpm_pp_base, kpm_npages);
+ kphysm_init();
availrmem_initial = availrmem = freemem;
PRM_DEBUG(availrmem);
@@ -1703,26 +1378,12 @@ kmem64_alloced:
static void
startup_modules(void)
{
- int proplen, nhblk1, nhblk8;
+ int nhblk1, nhblk8;
size_t nhblksz;
pgcnt_t pages_per_hblk;
size_t hme8blk_sz, hme1blk_sz;
/*
- * Log any optional messages from the boot program
- */
- proplen = (size_t)BOP_GETPROPLEN(bootops, "boot-message");
- if (proplen > 0) {
- char *msg;
- size_t len = (size_t)proplen;
-
- msg = kmem_zalloc(len, KM_SLEEP);
- (void) BOP_GETPROP(bootops, "boot-message", msg);
- cmn_err(CE_CONT, "?%s\n", msg);
- kmem_free(msg, len);
- }
-
- /*
* Let the platforms have a chance to change default
* values before reading system file.
*/
@@ -1903,7 +1564,6 @@ startup_modules(void)
static void
startup_bop_gone(void)
{
- extern int bop_io_quiesced;
/*
* Destroy the MD initialized at startup
@@ -1913,19 +1573,13 @@ startup_bop_gone(void)
mach_descrip_startup_fini();
/*
- * Call back into boot and release boots resources.
+ * We're done with prom allocations.
*/
- BOP_QUIESCE_IO(bootops);
- bop_io_quiesced = 1;
+ bop_fini();
copy_boot_memlists(&boot_physinstalled, &boot_physinstalled_len,
&boot_physavail, &boot_physavail_len,
&boot_virtavail, &boot_virtavail_len);
- /*
- * Copy physinstalled list into kernel space.
- */
- phys_install = memlist;
- copy_memlist(boot_physinstalled, boot_physinstalled_len, &memlist);
/*
* setup physically contiguous area twice as large as the ecache.
@@ -1947,9 +1601,6 @@ startup_bop_gone(void)
virt_avail = memlist;
copy_memlist(boot_virtavail, boot_virtavail_len, &memlist);
- /*
- * Last chance to ask our booter questions ..
- */
}
@@ -1979,8 +1630,7 @@ startup_fixup_physavail(void)
* from the original list we copied earlier.
*/
cur = memlist;
- (void) copy_physavail(boot_physavail, boot_physavail_len,
- &memlist, 0, 0);
+ copy_memlist(boot_physavail, boot_physavail_len, &memlist);
/*
* Add any unused kmem64 memory from overmapped page
@@ -1988,17 +1638,13 @@ startup_fixup_physavail(void)
*/
if (kmem64_overmap_size) {
memlist_add(kmem64_pabase + (kmem64_end - kmem64_base),
- kmem64_overmap_size,
- &memlist, &cur);
+ kmem64_overmap_size, &memlist, &cur);
}
/*
- * Add any extra memory after e_text we added to the phys_avail list
+ * Add any extra memory after e_data we added to the phys_avail list
* back to the old list.
*/
- if (extra_etpg)
- memlist_add(va_to_pa(extra_etva), mmu_ptob(extra_etpg),
- &memlist, &cur);
if (ndata_remain_sz >= MMU_PAGESIZE)
memlist_add(va_to_pa(nalloc_base),
(uint64_t)ndata_remain_sz, &memlist, &cur);
@@ -2016,19 +1662,12 @@ startup_fixup_physavail(void)
* the prom has allocated for it's own book-keeping, and remove
* them from the freelist too. sigh.
*/
- fix_prom_pages(phys_avail, cur);
+ sync_memlists(phys_avail, cur);
ASSERT(phys_avail != NULL);
memlist_free_list(phys_avail);
phys_avail = cur;
- /*
- * We're done with boot. Just after this point in time, boot
- * gets unmapped, so we can no longer rely on its services.
- * Zero the bootops to indicate this fact.
- */
- bootops = (struct bootops *)NULL;
- BOOTOPS_GONE();
}
static void
@@ -2088,13 +1727,6 @@ startup_vm(void)
kvm_init();
/*
- * XXX4U: previously, we initialized and turned on
- * the caches at this point. But of course we have
- * nothing to do, as the prom has already done this
- * for us -- main memory must be E$able at all times.
- */
-
- /*
* If the following is true, someone has patched
* phsymem to be less than the number of pages that
* the system actually has. Remove pages until system
@@ -2595,6 +2227,17 @@ init_ptl1_thread(void)
#endif /* PTL1_PANIC_DEBUG */
+static void
+memlist_new(uint64_t start, uint64_t len, struct memlist **memlistp)
+{
+ struct memlist *new;
+
+ new = *memlistp;
+ new->address = start;
+ new->size = len;
+ *memlistp = new + 1;
+}
+
/*
* Add to a memory list.
* start = start of new memory segment
@@ -2606,16 +2249,41 @@ static void
memlist_add(uint64_t start, uint64_t len, struct memlist **memlistp,
struct memlist **curmemlistp)
{
- struct memlist *new;
-
- new = *memlistp;
- new->address = start;
- new->size = len;
- *memlistp = new + 1;
+ struct memlist *new = *memlistp;
+ memlist_new(start, len, memlistp);
memlist_insert(new, curmemlistp);
}
+static int
+ndata_alloc_memseg(struct memlist *ndata, size_t avail)
+{
+ int nseg;
+ size_t memseg_sz;
+ struct memseg *msp;
+
+ /*
+ * The memseg list is for the chunks of physical memory that
+ * will be managed by the vm system. The number calculated is
+ * a guess as boot may fragment it more when memory allocations
+ * are made before kphysm_init().
+ */
+ memseg_sz = (avail + 10) * sizeof (struct memseg);
+ memseg_sz = roundup(memseg_sz, PAGESIZE);
+ nseg = memseg_sz / sizeof (struct memseg);
+ msp = ndata_alloc(ndata, memseg_sz, ecache_alignsize);
+ if (msp == NULL)
+ return (1);
+ PRM_DEBUG(memseg_free);
+
+ while (nseg--) {
+ msp->next = memseg_free;
+ memseg_free = msp;
+ msp++;
+ }
+ return (0);
+}
+
/*
* In the case of architectures that support dynamic addition of
* memory at run-time there are two cases where memsegs need to
@@ -2687,132 +2355,207 @@ add_physmem_cb(page_t *pp, pfn_t pnum)
}
/*
- * kphysm_init() tackles the problem of initializing physical memory.
- * The old startup made some assumptions about the kernel living in
- * physically contiguous space which is no longer valid.
+ * Find memseg with given pfn
+ */
+static struct memseg *
+memseg_find(pfn_t base, pfn_t *next)
+{
+ struct memseg *seg;
+
+ if (next != NULL)
+ *next = LONG_MAX;
+ for (seg = memsegs; seg != NULL; seg = seg->next) {
+ if (base >= seg->pages_base && base < seg->pages_end)
+ return (seg);
+ if (next != NULL && seg->pages_base > base &&
+ seg->pages_base < *next)
+ *next = seg->pages_base;
+ }
+ return (NULL);
+}
+
+extern struct vnode prom_ppages;
+
+/*
+ * Put page allocated by OBP on prom_ppages
*/
static void
-kphysm_init(page_t *pp, struct memseg *memsegp, pgcnt_t npages,
- uintptr_t kpm_pp, pgcnt_t kpm_npages)
+kphysm_erase(uint64_t addr, uint64_t len)
{
- struct memlist *pmem;
- struct memseg *msp;
- pfn_t base;
- pgcnt_t num;
- pfn_t lastseg_pages_end = 0;
- pgcnt_t nelem_used = 0;
+ struct page *pp;
+ struct memseg *seg;
+ pfn_t base = btop(addr), next;
+ pgcnt_t num = btop(len);
- ASSERT(page_hash != NULL && page_hashsz != 0);
+ while (num != 0) {
+ pgcnt_t off, left;
- msp = memsegp;
- for (pmem = phys_avail; pmem && npages; pmem = pmem->next) {
+ seg = memseg_find(base, &next);
+ if (seg == NULL) {
+ if (next == LONG_MAX)
+ break;
+ left = MIN(next - base, num);
+ base += left, num -= left;
+ continue;
+ }
+ off = base - seg->pages_base;
+ pp = seg->pages + off;
+ left = num - MIN(num, (seg->pages_end - seg->pages_base) - off);
+ while (num != left) {
+ /*
+ * init it, lock it, and hashin on prom_pages vp.
+ *
+ * XXX vnode offsets on the prom_ppages vnode
+ * are page numbers (gack) for >32 bit
+ * physical memory machines.
+ */
+ add_physmem_cb(pp, base);
+ if (page_trylock(pp, SE_EXCL) == 0)
+ cmn_err(CE_PANIC, "prom page locked");
+ (void) page_hashin(pp, &prom_ppages,
+ (offset_t)base, NULL);
+ (void) page_pp_lock(pp, 0, 1);
+ pp++, base++, num--;
+ }
+ }
+}
+
+static page_t *ppnext;
+static pgcnt_t ppleft;
+
+static void *kpm_ppnext;
+static pgcnt_t kpm_ppleft;
+
+/*
+ * Create a memseg
+ */
+static void
+kphysm_memseg(uint64_t addr, uint64_t len)
+{
+ pfn_t base = btop(addr);
+ pgcnt_t num = btop(len);
+ struct memseg *seg;
+ seg = memseg_free;
+ memseg_free = seg->next;
+ ASSERT(seg != NULL);
+
+ seg->pages = ppnext;
+ seg->epages = ppnext + num;
+ seg->pages_base = base;
+ seg->pages_end = base + num;
+ ppnext += num;
+ ppleft -= num;
+
+ if (kpm_enable) {
+ pgcnt_t kpnum = ptokpmpr(num);
+
+ if (kpnum > kpm_ppleft)
+ panic("kphysm_memseg: kpm_pp overflow");
+ seg->pagespa = va_to_pa(seg->pages);
+ seg->epagespa = va_to_pa(seg->epages);
+ seg->kpm_pbase = kpmptop(ptokpmp(base));
+ seg->kpm_nkpmpgs = kpnum;
/*
- * Build the memsegs entry
+ * In the kpm_smallpage case, the kpm array
+ * is 1-1 wrt the page array
*/
- num = btop(pmem->size);
- if (num > npages)
- num = npages;
- npages -= num;
- base = btop(pmem->address);
-
- msp->pages = pp;
- msp->epages = pp + num;
- msp->pages_base = base;
- msp->pages_end = base + num;
-
- if (kpm_enable) {
- pfn_t pbase_a;
- pfn_t pend_a;
- pfn_t prev_pend_a;
- pgcnt_t nelem;
-
- msp->pagespa = va_to_pa(pp);
- msp->epagespa = va_to_pa(pp + num);
- pbase_a = kpmptop(ptokpmp(base));
- pend_a = kpmptop(ptokpmp(base + num - 1)) + kpmpnpgs;
- nelem = ptokpmp(pend_a - pbase_a);
- msp->kpm_nkpmpgs = nelem;
- msp->kpm_pbase = pbase_a;
- if (lastseg_pages_end) {
- /*
- * Assume phys_avail is in ascending order
- * of physical addresses.
- */
- ASSERT(base + num > lastseg_pages_end);
- prev_pend_a = kpmptop(
- ptokpmp(lastseg_pages_end - 1)) + kpmpnpgs;
-
- if (prev_pend_a > pbase_a) {
- /*
- * Overlap, more than one memseg may
- * point to the same kpm_page range.
- */
- if (kpm_smallpages == 0) {
- msp->kpm_pages =
- (kpm_page_t *)kpm_pp - 1;
- kpm_pp = (uintptr_t)
- ((kpm_page_t *)kpm_pp
- + nelem - 1);
- } else {
- msp->kpm_spages =
- (kpm_spage_t *)kpm_pp - 1;
- kpm_pp = (uintptr_t)
- ((kpm_spage_t *)kpm_pp
- + nelem - 1);
- }
- nelem_used += nelem - 1;
-
- } else {
- if (kpm_smallpages == 0) {
- msp->kpm_pages =
- (kpm_page_t *)kpm_pp;
- kpm_pp = (uintptr_t)
- ((kpm_page_t *)kpm_pp
- + nelem);
- } else {
- msp->kpm_spages =
- (kpm_spage_t *)kpm_pp;
- kpm_pp = (uintptr_t)
- ((kpm_spage_t *)
- kpm_pp + nelem);
- }
- nelem_used += nelem;
- }
+ if (kpm_smallpages) {
+ kpm_spage_t *kpm_pp = kpm_ppnext;
- } else {
- if (kpm_smallpages == 0) {
- msp->kpm_pages = (kpm_page_t *)kpm_pp;
- kpm_pp = (uintptr_t)
- ((kpm_page_t *)kpm_pp + nelem);
- } else {
- msp->kpm_spages = (kpm_spage_t *)kpm_pp;
- kpm_pp = (uintptr_t)
- ((kpm_spage_t *)kpm_pp + nelem);
- }
- nelem_used = nelem;
- }
+ kpm_ppnext = kpm_pp + kpnum;
+ seg->kpm_spages = kpm_pp;
+ seg->kpm_pagespa = va_to_pa(seg->kpm_spages);
+ } else {
+ kpm_page_t *kpm_pp = kpm_ppnext;
+
+ kpm_ppnext = kpm_pp + kpnum;
+ seg->kpm_pages = kpm_pp;
+ seg->kpm_pagespa = va_to_pa(seg->kpm_pages);
+ /* ASSERT no kpm overlaps */
+ ASSERT(
+ memseg_find(base - pmodkpmp(base), NULL) == NULL);
+ ASSERT(memseg_find(
+ roundup(base + num, kpmpnpgs) - 1, NULL) == NULL);
+ }
+ kpm_ppleft -= num;
+ }
- if (nelem_used > kpm_npages)
- panic("kphysm_init: kpm_pp overflow\n");
+ memseg_list_add(seg);
+}
- msp->kpm_pagespa = va_to_pa(msp->kpm_pages);
- lastseg_pages_end = msp->pages_end;
- }
+/*
+ * Add range to free list
+ */
+void
+kphysm_add(uint64_t addr, uint64_t len, int reclaim)
+{
+ struct page *pp;
+ struct memseg *seg;
+ pfn_t base = btop(addr);
+ pgcnt_t num = btop(len);
- memseg_list_add(msp);
+ seg = memseg_find(base, NULL);
+ ASSERT(seg != NULL);
+ pp = seg->pages + (base - seg->pages_base);
+
+ if (reclaim) {
+ struct page *rpp = pp;
+ struct page *lpp = pp + num;
/*
- * add_physmem() initializes the PSM part of the page
- * struct by calling the PSM back with add_physmem_cb().
- * In addition it coalesces pages into larger pages as
- * it initializes them.
+ * page should be locked on prom_ppages
+ * unhash and unlock it
*/
- add_physmem(pp, num, base);
- pp += num;
- msp++;
+ while (rpp < lpp) {
+ ASSERT(PAGE_EXCL(rpp) && rpp->p_vnode == &prom_ppages);
+ page_pp_unlock(rpp, 0, 1);
+ page_hashout(rpp, NULL);
+ page_unlock(rpp);
+ rpp++;
+ }
}
+ /*
+ * add_physmem() initializes the PSM part of the page
+ * struct by calling the PSM back with add_physmem_cb().
+ * In addition it coalesces pages into larger pages as
+ * it initializes them.
+ */
+ add_physmem(pp, num, base);
+}
+
+/*
+ * kphysm_init() tackles the problem of initializing physical memory.
+ */
+static void
+kphysm_init(void)
+{
+ struct memlist *pmem;
+
+ ASSERT(page_hash != NULL && page_hashsz != 0);
+
+ ppnext = pp_base;
+ ppleft = npages;
+ kpm_ppnext = kpm_pp_base;
+ kpm_ppleft = kpm_npages;
+
+ /*
+ * installed pages not on nopp_memlist go in memseg list
+ */
+ diff_memlists(phys_install, nopp_list, kphysm_memseg);
+
+ /*
+ * Free the avail list
+ */
+ for (pmem = phys_avail; pmem != NULL; pmem = pmem->next)
+ kphysm_add(pmem->address, pmem->size, 0);
+
+ /*
+ * Erase pages that aren't available
+ */
+ diff_memlists(phys_install, phys_avail, kphysm_erase);
+
build_pfn_hash();
}
@@ -3201,25 +2944,6 @@ do_prom_version_check(void)
cmn_err(CE_WARN, drev, " on one or more CPU boards", buf);
}
-static void
-kpm_init()
-{
- kpm_pgshft = (kpm_smallpages == 0) ? MMU_PAGESHIFT4M : MMU_PAGESHIFT;
- kpm_pgsz = 1ull << kpm_pgshft;
- kpm_pgoff = kpm_pgsz - 1;
- kpmp2pshft = kpm_pgshft - PAGESHIFT;
- kpmpnpgs = 1 << kpmp2pshft;
- ASSERT(((uintptr_t)kpm_vbase & (kpm_pgsz - 1)) == 0);
-}
-
-void
-kpm_npages_setup(int memblocks)
-{
- /*
- * npages can be scattered in a maximum of 'memblocks'
- */
- kpm_npages = ptokpmpr(npages) + memblocks;
-}
/*
* Must be defined in platform dependent code.
diff --git a/usr/src/uts/sun4/sys/memlist_plat.h b/usr/src/uts/sun4/sys/memlist_plat.h
index 7bf901ce6c..6f98bcb28a 100644
--- a/usr/src/uts/sun4/sys/memlist_plat.h
+++ b/usr/src/uts/sun4/sys/memlist_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 1991-2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -40,23 +39,35 @@
extern "C" {
#endif
+/*
+ * The prom hands us an array of these
+ * as available and installed props
+ */
+typedef struct prom_memlist {
+ u_longlong_t addr;
+ u_longlong_t size;
+} prom_memlist_t;
+
extern int check_boot_version(int);
-extern int check_memexp(struct memlist *, uint_t);
-extern void copy_memlist(u_longlong_t *, size_t, struct memlist **);
-extern int copy_physavail(u_longlong_t *, size_t, struct memlist **,
- uint_t, uint_t);
-extern void size_physavail(u_longlong_t *physavail, size_t size,
+extern void copy_memlist(prom_memlist_t *, size_t, struct memlist **);
+extern void size_physavail(prom_memlist_t *physavail, size_t size,
pgcnt_t *npages, int *memblocks);
-extern pgcnt_t size_virtalloc(u_longlong_t *avail, size_t size);
-extern void installed_top_size_memlist_array(u_longlong_t *, size_t, pfn_t *,
+extern pgcnt_t size_virtalloc(prom_memlist_t *avail, size_t size);
+extern void installed_top_size_memlist_array(prom_memlist_t *, size_t, pfn_t *,
pgcnt_t *);
extern void installed_top_size(struct memlist *, pfn_t *, pgcnt_t *);
extern void fix_prom_pages(struct memlist *, struct memlist *);
-extern void copy_boot_memlists(u_longlong_t **physinstalled,
- size_t *physinstalled_len, u_longlong_t **physavail, size_t *physavail_len,
- u_longlong_t **virtavail, size_t *virtavail_len);
+extern void init_boot_memlists(void);
+extern void copy_boot_memlists(
+ prom_memlist_t **physinstalled, size_t *physinstalled_len,
+ prom_memlist_t **physavail, size_t *physavail_len,
+ prom_memlist_t **virtavail, size_t *virtavail_len);
extern void phys_install_has_changed(void);
+extern void diff_memlists(struct memlist *, struct memlist *,
+ void (*)(uint64_t, uint64_t));
+extern void sync_memlists(struct memlist *, struct memlist *);
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/sun4/sys/memnode.h b/usr/src/uts/sun4/sys/memnode.h
index 745d03002f..e3bba09096 100644
--- a/usr/src/uts/sun4/sys/memnode.h
+++ b/usr/src/uts/sun4/sys/memnode.h
@@ -35,6 +35,7 @@ extern "C" {
#ifdef _KERNEL
#include <sys/lgrp.h>
+#include <sys/memlist_plat.h>
/*
* This file defines the mappings between physical addresses and memory
@@ -103,7 +104,7 @@ struct mem_node_conf {
struct memlist;
-extern void startup_build_mem_nodes(u_longlong_t *, size_t);
+extern void startup_build_mem_nodes(prom_memlist_t *, size_t);
extern void mem_node_add_slice(pfn_t, pfn_t);
extern void mem_node_pre_del_slice(pfn_t, pfn_t);
extern void mem_node_post_del_slice(pfn_t, pfn_t, int);
diff --git a/usr/src/uts/sun4/sys/platform_module.h b/usr/src/uts/sun4/sys/platform_module.h
index 8f96b014c7..1475816e52 100644
--- a/usr/src/uts/sun4/sys/platform_module.h
+++ b/usr/src/uts/sun4/sys/platform_module.h
@@ -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.
*/
@@ -30,6 +30,7 @@
#include <sys/async.h>
#include <sys/sunddi.h>
+#include <sys/memlist_plat.h>
#ifdef __cplusplus
extern "C" {
@@ -59,7 +60,7 @@ extern void load_platform_modules(void);
extern int plat_cpu_poweron(struct cpu *cp); /* power on CPU */
extern int plat_cpu_poweroff(struct cpu *cp); /* power off CPU */
extern void plat_freelist_process(int mnode);
-extern void plat_build_mem_nodes(u_longlong_t *, size_t);
+extern void plat_build_mem_nodes(prom_memlist_t *, size_t);
extern void plat_slice_add(pfn_t, pfn_t);
extern void plat_slice_del(pfn_t, pfn_t);
extern int plat_lpkmem_is_supported(void);
diff --git a/usr/src/uts/sun4/vm/sfmmu.c b/usr/src/uts/sun4/vm/sfmmu.c
index 78247431a3..8581f17d4d 100644
--- a/usr/src/uts/sun4/vm/sfmmu.c
+++ b/usr/src/uts/sun4/vm/sfmmu.c
@@ -514,37 +514,6 @@ ndata_maxsize(struct memlist *ndata)
return (chunksize);
}
-/*
- * This is a special function to figure out if the memory chunk needed
- * for the page structs can fit in the nucleus or not. If it fits the
- * function calculates and returns the possible remaining ndata size
- * in the last element if the size needed for page structs would be
- * allocated from the nucleus.
- */
-size_t
-ndata_spare(struct memlist *ndata, size_t wanted, size_t alignment)
-{
- struct memlist *frlist;
- uintptr_t base;
- uintptr_t end;
-
- for (frlist = ndata; frlist != NULL; frlist = frlist->next) {
- base = roundup(frlist->address, alignment);
- end = roundup(base + wanted, ecache_alignsize);
-
- if (end <= frlist->address + frlist->size) {
- if (frlist->next == NULL)
- return (frlist->address + frlist->size - end);
-
- while (frlist->next != NULL)
- frlist = frlist->next;
-
- return (frlist->size);
- }
- }
-
- return (0);
-}
/*
* Allocate the last properly aligned memory chunk.
@@ -876,27 +845,11 @@ ndata_alloc_tsbs(struct memlist *ndata, pgcnt_t npages)
return (0);
}
-/*
- * Allocate hat structs from the nucleus data memory.
- */
-int
-ndata_alloc_hat(struct memlist *ndata, pgcnt_t npages, pgcnt_t kpm_npages)
+size_t
+calc_hmehash_sz(pgcnt_t npages)
{
- size_t mml_alloc_sz;
- size_t cb_alloc_sz;
- int max_nucuhme_buckets = MAX_NUCUHME_BUCKETS;
- int max_nuckhme_buckets = MAX_NUCKHME_BUCKETS;
ulong_t hme_buckets;
- if (enable_bigktsb) {
- ASSERT((max_nucuhme_buckets + max_nuckhme_buckets) *
- sizeof (struct hmehash_bucket) <=
- TSB_BYTES(TSB_1M_SZCODE));
-
- max_nucuhme_buckets *= 2;
- max_nuckhme_buckets *= 2;
- }
-
/*
* The number of buckets in the hme hash tables
* is a power of 2 such that the average hash chain length is
@@ -925,27 +878,36 @@ ndata_alloc_hat(struct memlist *ndata, pgcnt_t npages, pgcnt_t kpm_npages)
khmehash_num = 1 << highbit(khmehash_num - 1);
khmehash_num = MAX(khmehash_num, MIN_KHME_BUCKETS);
- if ((khmehash_num > max_nuckhme_buckets) ||
- (uhmehash_num > max_nucuhme_buckets)) {
- khme_hash = NULL;
- uhme_hash = NULL;
- } else {
- size_t hmehash_sz = (uhmehash_num + khmehash_num) *
- sizeof (struct hmehash_bucket);
+ return ((uhmehash_num + khmehash_num) * sizeof (struct hmehash_bucket));
+}
- if ((khme_hash = ndata_alloc(ndata, hmehash_sz,
- ecache_alignsize)) != NULL)
- uhme_hash = &khme_hash[khmehash_num];
- else
- uhme_hash = NULL;
+caddr_t
+alloc_hmehash(caddr_t alloc_base)
+{
+ size_t khmehash_sz, uhmehash_sz;
- PRM_DEBUG(hmehash_sz);
- }
+ khme_hash = (struct hmehash_bucket *)alloc_base;
+ khmehash_sz = khmehash_num * sizeof (struct hmehash_bucket);
+ alloc_base += khmehash_sz;
+
+ uhme_hash = (struct hmehash_bucket *)alloc_base;
+ uhmehash_sz = uhmehash_num * sizeof (struct hmehash_bucket);
+ alloc_base += uhmehash_sz;
PRM_DEBUG(khme_hash);
- PRM_DEBUG(khmehash_num);
PRM_DEBUG(uhme_hash);
- PRM_DEBUG(uhmehash_num);
+
+ return (alloc_base);
+}
+
+/*
+ * Allocate hat structs from the nucleus data memory.
+ */
+int
+ndata_alloc_hat(struct memlist *ndata, pgcnt_t npages)
+{
+ size_t mml_alloc_sz;
+ size_t cb_alloc_sz;
/*
* For the page mapping list mutex array we allocate one mutex
@@ -954,13 +916,6 @@ ndata_alloc_hat(struct memlist *ndata, pgcnt_t npages, pgcnt_t kpm_npages)
* is rounded up (ie. 1 << highbit(npages * 1.5 / 128))
*
* mml_shift is roughly log2(mml_table_sz) + 3 for MLIST_HASH
- *
- * It is not required that this be allocated from the nucleus,
- * but it is desirable. So we first allocate from the nucleus
- * everything that must be there. Having done so, if mml_table
- * will fit within what remains of the nucleus then it will be
- * allocated here. If not, set mml_table to NULL, which will cause
- * startup_memlist() to BOP_ALLOC() space for it after our return...
*/
mml_table_sz = 1 << highbit((npages * 3) / 256);
if (mml_table_sz < 64)
@@ -975,92 +930,73 @@ ndata_alloc_hat(struct memlist *ndata, pgcnt_t npages, pgcnt_t kpm_npages)
mml_alloc_sz = mml_table_sz * sizeof (kmutex_t);
mml_table = ndata_alloc(ndata, mml_alloc_sz, ecache_alignsize);
-
+ if (mml_table == NULL)
+ return (-1);
PRM_DEBUG(mml_table);
cb_alloc_sz = sfmmu_max_cb_id * sizeof (struct sfmmu_callback);
PRM_DEBUG(cb_alloc_sz);
sfmmu_cb_table = ndata_alloc(ndata, cb_alloc_sz, ecache_alignsize);
+ if (sfmmu_cb_table == NULL)
+ return (-1);
PRM_DEBUG(sfmmu_cb_table);
+ return (0);
+}
+
+int
+ndata_alloc_kpm(struct memlist *ndata, pgcnt_t kpm_npages)
+{
+ size_t kpmp_alloc_sz;
+
/*
* For the kpm_page mutex array we allocate one mutex every 16
* kpm pages (64MB). In smallpage mode we allocate one mutex
* every 8K pages. The minimum is set to 64 entries and the
* maximum to 8K entries.
- *
- * It is not required that this be allocated from the nucleus,
- * but it is desirable. So we first allocate from the nucleus
- * everything that must be there. Having done so, if kpmp_table
- * or kpmp_stable will fit within what remains of the nucleus
- * then it will be allocated here. If not, startup_memlist()
- * will use BOP_ALLOC() space for it after our return...
*/
- if (kpm_enable) {
- size_t kpmp_alloc_sz;
-
- if (kpm_smallpages == 0) {
- kpmp_shift = highbit(sizeof (kpm_page_t)) - 1;
- kpmp_table_sz = 1 << highbit(kpm_npages / 16);
- kpmp_table_sz = (kpmp_table_sz < 64) ? 64 :
- ((kpmp_table_sz > 8192) ? 8192 : kpmp_table_sz);
- kpmp_alloc_sz = kpmp_table_sz * sizeof (kpm_hlk_t);
-
- kpmp_table = ndata_alloc(ndata, kpmp_alloc_sz,
- ecache_alignsize);
+ if (kpm_smallpages == 0) {
+ kpmp_shift = highbit(sizeof (kpm_page_t)) - 1;
+ kpmp_table_sz = 1 << highbit(kpm_npages / 16);
+ kpmp_table_sz = (kpmp_table_sz < 64) ? 64 :
+ ((kpmp_table_sz > 8192) ? 8192 : kpmp_table_sz);
+ kpmp_alloc_sz = kpmp_table_sz * sizeof (kpm_hlk_t);
+
+ kpmp_table = ndata_alloc(ndata, kpmp_alloc_sz,
+ ecache_alignsize);
+ if (kpmp_table == NULL)
+ return (-1);
- PRM_DEBUG(kpmp_table);
- PRM_DEBUG(kpmp_table_sz);
+ PRM_DEBUG(kpmp_table);
+ PRM_DEBUG(kpmp_table_sz);
- kpmp_stable_sz = 0;
- kpmp_stable = NULL;
- } else {
- ASSERT(kpm_pgsz == PAGESIZE);
- kpmp_shift = highbit(sizeof (kpm_shlk_t)) + 1;
- kpmp_stable_sz = 1 << highbit(kpm_npages / 8192);
- kpmp_stable_sz = (kpmp_stable_sz < 64) ? 64 :
- ((kpmp_stable_sz > 8192) ? 8192 : kpmp_stable_sz);
- kpmp_alloc_sz = kpmp_stable_sz * sizeof (kpm_shlk_t);
-
- kpmp_stable = ndata_alloc(ndata, kpmp_alloc_sz,
- ecache_alignsize);
+ kpmp_stable_sz = 0;
+ kpmp_stable = NULL;
+ } else {
+ ASSERT(kpm_pgsz == PAGESIZE);
+ kpmp_shift = highbit(sizeof (kpm_shlk_t)) + 1;
+ kpmp_stable_sz = 1 << highbit(kpm_npages / 8192);
+ kpmp_stable_sz = (kpmp_stable_sz < 64) ? 64 :
+ ((kpmp_stable_sz > 8192) ? 8192 : kpmp_stable_sz);
+ kpmp_alloc_sz = kpmp_stable_sz * sizeof (kpm_shlk_t);
+
+ kpmp_stable = ndata_alloc(ndata, kpmp_alloc_sz,
+ ecache_alignsize);
+ if (kpmp_stable == NULL)
+ return (-1);
- PRM_DEBUG(kpmp_stable);
- PRM_DEBUG(kpmp_stable_sz);
+ PRM_DEBUG(kpmp_stable);
+ PRM_DEBUG(kpmp_stable_sz);
- kpmp_table_sz = 0;
- kpmp_table = NULL;
- }
- PRM_DEBUG(kpmp_shift);
+ kpmp_table_sz = 0;
+ kpmp_table = NULL;
}
+ PRM_DEBUG(kpmp_shift);
return (0);
}
/*
- * Allocate virtual addresses at base with given alignment.
- * Note that there is no physical memory behind the address yet.
- */
-caddr_t
-alloc_hme_buckets(caddr_t base, int alignsize)
-{
- size_t hmehash_sz = (uhmehash_num + khmehash_num) *
- sizeof (struct hmehash_bucket);
-
- ASSERT(khme_hash == NULL);
- ASSERT(uhme_hash == NULL);
-
- base = (caddr_t)roundup((uintptr_t)base, alignsize);
- hmehash_sz = roundup(hmehash_sz, alignsize);
-
- khme_hash = (struct hmehash_bucket *)base;
- uhme_hash = (struct hmehash_bucket *)((caddr_t)khme_hash +
- khmehash_num * sizeof (struct hmehash_bucket));
- base += hmehash_sz;
- return (base);
-}
-
-/*
* This function bop allocs kernel TSBs.
*/
caddr_t
@@ -1070,8 +1006,7 @@ sfmmu_ktsb_alloc(caddr_t tsbbase)
if (enable_bigktsb) {
ktsb_base = (caddr_t)roundup((uintptr_t)tsbbase, ktsb_sz);
- vaddr = (caddr_t)BOP_ALLOC(bootops, ktsb_base, ktsb_sz,
- ktsb_sz);
+ vaddr = prom_alloc(ktsb_base, ktsb_sz, ktsb_sz);
if (vaddr != ktsb_base)
cmn_err(CE_PANIC, "sfmmu_ktsb_alloc: can't alloc"
" 8K bigktsb");
@@ -1275,7 +1210,8 @@ sfmmu_tsb_segkmem_alloc(vmem_t *vmp, size_t size, int vmflag)
* to do this the hard way.
*/
for (lgrpid = 0; lgrpid < NLGRPS_MAX &&
- vmp != kmem_tsb_default_arena[lgrpid]; lgrpid++);
+ vmp != kmem_tsb_default_arena[lgrpid]; lgrpid++)
+ ;
if (lgrpid == NLGRPS_MAX)
lgrpid = LGRP_NONE;
}
diff --git a/usr/src/uts/sun4/vm/vm_dep.c b/usr/src/uts/sun4/vm/vm_dep.c
index 763b3dc737..4b80603a8f 100644
--- a/usr/src/uts/sun4/vm/vm_dep.c
+++ b/usr/src/uts/sun4/vm/vm_dep.c
@@ -242,7 +242,7 @@ map_addr(caddr_t *addrp, size_t len, offset_t off, int vacalign, uint_t flags)
{
struct proc *p = curproc;
caddr_t userlimit = flags & _MAP_LOW32 ?
- (caddr_t)USERLIMIT32 : p->p_as->a_userlimit;
+ (caddr_t)USERLIMIT32 : p->p_as->a_userlimit;
map_addr_proc(addrp, len, off, vacalign, userlimit, p, flags);
}
@@ -665,27 +665,33 @@ map_pgszcvec(caddr_t addr, size_t size, uintptr_t off, int flags, int type,
int memcntl)
{
if (flags & MAP_TEXT) {
- return (map_szcvec(addr, size, off, disable_auto_text_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_text_large_pages,
max_utext_lpsize, shm_lpg_min_physmem));
} else if (flags & MAP_INITDATA) {
- return (map_szcvec(addr, size, off, disable_auto_data_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_data_large_pages,
max_uidata_lpsize, privm_lpg_min_physmem));
} else if (type == MAPPGSZC_SHM) {
- return (map_szcvec(addr, size, off, disable_auto_data_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_data_large_pages,
max_shm_lpsize, shm_lpg_min_physmem));
} else if (type == MAPPGSZC_HEAP) {
- return (map_szcvec(addr, size, off, disable_auto_data_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_data_large_pages,
max_uheap_lpsize, privm_lpg_min_physmem));
} else if (type == MAPPGSZC_STACK) {
- return (map_szcvec(addr, size, off, disable_auto_data_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_data_large_pages,
max_ustack_lpsize, privm_lpg_min_physmem));
} else {
- return (map_szcvec(addr, size, off, disable_auto_data_large_pages,
+ return (map_szcvec(addr, size, off,
+ disable_auto_data_large_pages,
max_privmap_lpsize, privm_lpg_min_physmem));
}
}
@@ -734,119 +740,111 @@ page_t ***page_cachelists[MAX_MEM_TYPES];
kmutex_t *fpc_mutex[NPC_MUTEX];
kmutex_t *cpc_mutex[NPC_MUTEX];
-caddr_t
-alloc_page_freelists(int mnode, caddr_t alloc_base, int alloc_align)
+/*
+ * Calculate space needed for page freelists and counters
+ */
+size_t
+calc_free_pagelist_sz(void)
{
- int mtype;
- uint_t szc;
+ int szc;
+ size_t alloc_sz, cache_sz, free_sz;
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, alloc_align);
+ /*
+ * one cachelist per color, node, and type
+ */
+ cache_sz = (page_get_pagecolors(0) * sizeof (page_t *)) +
+ sizeof (page_t **);
+ cache_sz *= max_mem_nodes * MAX_MEM_TYPES;
+
+ /*
+ * one freelist per size, color, node, and type
+ */
+ free_sz = sizeof (page_t **);
+ for (szc = 0; szc < mmu_page_sizes; szc++)
+ free_sz += sizeof (page_t *) * page_get_pagecolors(szc);
+ free_sz *= max_mem_nodes * MAX_MEM_TYPES;
+
+ alloc_sz = cache_sz + free_sz + page_ctrs_sz();
+ return (alloc_sz);
+}
+
+caddr_t
+alloc_page_freelists(caddr_t alloc_base)
+{
+ int mnode, mtype;
+ int szc, clrs;
/*
* We only support small pages in the cachelist.
*/
for (mtype = 0; mtype < MAX_MEM_TYPES; mtype++) {
- page_cachelists[mtype][mnode] = (page_t **)alloc_base;
- alloc_base += (sizeof (page_t *) * page_get_pagecolors(0));
- /*
- * Allocate freelists bins for all
- * supported page sizes.
- */
- for (szc = 0; szc < mmu_page_sizes; szc++) {
- page_freelists[szc][mtype][mnode] =
- (page_t **)alloc_base;
- alloc_base += ((sizeof (page_t *) *
- page_get_pagecolors(szc)));
+ page_cachelists[mtype] = (page_t ***)alloc_base;
+ alloc_base += (max_mem_nodes * sizeof (page_t **));
+ for (mnode = 0; mnode < max_mem_nodes; mnode++) {
+ page_cachelists[mtype][mnode] = (page_t **)alloc_base;
+ alloc_base +=
+ (page_get_pagecolors(0) * sizeof (page_t *));
}
}
- alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, alloc_align);
+ /*
+ * Allocate freelists bins for all
+ * supported page sizes.
+ */
+ for (szc = 0; szc < mmu_page_sizes; szc++) {
+ clrs = page_get_pagecolors(szc);
+ for (mtype = 0; mtype < MAX_MEM_TYPES; mtype++) {
+ page_freelists[szc][mtype] = (page_t ***)alloc_base;
+ alloc_base += (max_mem_nodes * sizeof (page_t **));
+ for (mnode = 0; mnode < max_mem_nodes; mnode++) {
+ page_freelists[szc][mtype][mnode] =
+ (page_t **)alloc_base;
+ alloc_base += (clrs * (sizeof (page_t *)));
+ }
+ }
+ }
+ alloc_base = page_ctrs_alloc(alloc_base);
return (alloc_base);
}
/*
- * Allocate page_freelists bin headers for a memnode from the
- * nucleus data area. This is the first time that mmu_page_sizes is
- * used during sun4u bootup, so check mmu_page_sizes initialization.
+ * Allocate page_freelists locks for a memnode from the nucleus data
+ * area. This is the first time that mmu_page_sizes is used during
+ * bootup, so check mmu_page_sizes initialization.
*/
int
-ndata_alloc_page_freelists(struct memlist *ndata, int mnode)
+ndata_alloc_page_mutexs(struct memlist *ndata)
{
size_t alloc_sz;
caddr_t alloc_base;
- caddr_t end;
- int mtype;
- uint_t szc;
- int32_t allp = 0;
+ int i;
+ void page_coloring_init();
+ page_coloring_init();
if (&mmu_init_mmu_page_sizes) {
- if (!mmu_init_mmu_page_sizes(allp)) {
+ if (!mmu_init_mmu_page_sizes(0)) {
cmn_err(CE_PANIC, "mmu_page_sizes %d not initialized",
mmu_page_sizes);
}
}
ASSERT(mmu_page_sizes >= DEFAULT_MMU_PAGE_SIZES);
- /* first time called - allocate max_mem_nodes dimension */
- if (mnode == 0) {
- int i;
-
- /* page_cachelists */
- alloc_sz = MAX_MEM_TYPES * max_mem_nodes *
- sizeof (page_t **);
-
- /* page_freelists */
- alloc_sz += MAX_MEM_TYPES * mmu_page_sizes * max_mem_nodes *
- sizeof (page_t **);
-
- /* fpc_mutex and cpc_mutex */
- alloc_sz += 2 * NPC_MUTEX * max_mem_nodes * sizeof (kmutex_t);
-
- alloc_base = ndata_alloc(ndata, alloc_sz, ecache_alignsize);
- if (alloc_base == NULL)
- return (-1);
-
- ASSERT(((uintptr_t)alloc_base & (ecache_alignsize - 1)) == 0);
-
- for (mtype = 0; mtype < MAX_MEM_TYPES; mtype++) {
- page_cachelists[mtype] = (page_t ***)alloc_base;
- alloc_base += (max_mem_nodes * sizeof (page_t **));
- for (szc = 0; szc < mmu_page_sizes; szc++) {
- page_freelists[szc][mtype] =
- (page_t ***)alloc_base;
- alloc_base += (max_mem_nodes *
- sizeof (page_t **));
- }
- }
- for (i = 0; i < NPC_MUTEX; i++) {
- fpc_mutex[i] = (kmutex_t *)alloc_base;
- alloc_base += (sizeof (kmutex_t) * max_mem_nodes);
- cpc_mutex[i] = (kmutex_t *)alloc_base;
- alloc_base += (sizeof (kmutex_t) * max_mem_nodes);
- }
- alloc_sz = 0;
- }
-
- /*
- * Calculate the size needed by alloc_page_freelists().
- */
- for (mtype = 0; mtype < MAX_MEM_TYPES; mtype++) {
- alloc_sz += sizeof (page_t *) * page_get_pagecolors(0);
-
- for (szc = 0; szc < mmu_page_sizes; szc++)
- alloc_sz += sizeof (page_t *) *
- page_get_pagecolors(szc);
- }
+ /* fpc_mutex and cpc_mutex */
+ alloc_sz = 2 * NPC_MUTEX * max_mem_nodes * sizeof (kmutex_t);
alloc_base = ndata_alloc(ndata, alloc_sz, ecache_alignsize);
if (alloc_base == NULL)
return (-1);
- end = alloc_page_freelists(mnode, alloc_base, ecache_alignsize);
- ASSERT((uintptr_t)end == roundup((uintptr_t)alloc_base + alloc_sz,
- ecache_alignsize));
+ ASSERT(((uintptr_t)alloc_base & (ecache_alignsize - 1)) == 0);
+ for (i = 0; i < NPC_MUTEX; i++) {
+ fpc_mutex[i] = (kmutex_t *)alloc_base;
+ alloc_base += (sizeof (kmutex_t) * max_mem_nodes);
+ cpc_mutex[i] = (kmutex_t *)alloc_base;
+ alloc_base += (sizeof (kmutex_t) * max_mem_nodes);
+ }
return (0);
}
diff --git a/usr/src/uts/sun4u/boston/os/boston.c b/usr/src/uts/sun4u/boston/os/boston.c
index f30ba9510f..39713603a2 100644
--- a/usr/src/uts/sun4u/boston/os/boston.c
+++ b/usr/src/uts/sun4u/boston/os/boston.c
@@ -191,7 +191,7 @@ load_platform_drivers(void)
* updates to ALOM.
*/
rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
- modgetsymvalue("rmc_comm_request_nowait", 0);
+ modgetsymvalue("rmc_comm_request_nowait", 0);
}
/*
@@ -313,7 +313,7 @@ plat_nodename_set(void)
* find the symbol for the mailbox routine
*/
rmc_req_res = (int (*)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t))
- modgetsymvalue("rmc_comm_request_response", 0);
+ modgetsymvalue("rmc_comm_request_response", 0);
if (rmc_req_res == NULL) {
return;
@@ -385,7 +385,7 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
* find the symbol for the mailbox routine
*/
rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
- modgetsymvalue("rmc_comm_request_nowait", 0);
+ modgetsymvalue("rmc_comm_request_nowait", 0);
if (rmc_req_now == NULL) {
return;
}
@@ -563,23 +563,6 @@ plat_fill_mc(pnode_t nodeid)
plat_assign_lgrphand_to_mem_node((lgrp_handle_t)portid, portid);
}
-/* ARGSUSED */
-void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
/*
* Common locking enter code
diff --git a/usr/src/uts/sun4u/cherrystone/os/cherrystone.c b/usr/src/uts/sun4u/cherrystone/os/cherrystone.c
index 0db042c464..cca3d056a8 100644
--- a/usr/src/uts/sun4u/cherrystone/os/cherrystone.c
+++ b/usr/src/uts/sun4u/cherrystone/os/cherrystone.c
@@ -144,7 +144,7 @@ load_platform_drivers(void)
for (drv = boot_time_drivers; *drv; drv++) {
if (i_ddi_attach_hw_nodes(*drv) != DDI_SUCCESS)
cmn_err(CE_WARN, "Failed to install \"%s\" driver.",
- *drv);
+ *drv);
}
/*
@@ -156,7 +156,7 @@ load_platform_drivers(void)
/* Gain access into the ssc050_get_port function */
cherry_ssc050_get_port_bit = (int (*) (dev_info_t *, int, int,
- uint8_t *, int)) modgetsymvalue("ssc050_get_port_bit", 0);
+ uint8_t *, int)) modgetsymvalue("ssc050_get_port_bit", 0);
if (cherry_ssc050_get_port_bit == NULL) {
cmn_err(CE_WARN, "cannot find ssc050_get_port_bit");
return;
@@ -199,7 +199,7 @@ cherry_dev_search(dev_info_t *dip, void *arg)
return (DDI_WALK_CONTINUE);
err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "reg", &dev_regs, &len);
+ DDI_PROP_DONTPASS, "reg", &dev_regs, &len);
if (err != DDI_PROP_SUCCESS) {
return (DDI_WALK_CONTINUE);
}
@@ -228,10 +228,10 @@ keyswitch_poll(void *arg)
int err;
err = cherry_ssc050_get_port_bit(dip, port, bit,
- &port_byte, I2C_NOSLEEP);
+ &port_byte, I2C_NOSLEEP);
if (err != 0) {
cmn_err(CE_WARN, "keyswitch polling disabled: "
- "errno=%d while reading ssc050", err);
+ "errno=%d while reading ssc050", err);
return;
}
@@ -244,7 +244,7 @@ cherry_abort_seq_handler(char *msg)
{
if (key_locked_bit == 0)
cmn_err(CE_CONT, "KEY in LOCKED position, "
- "ignoring debug enter sequence");
+ "ignoring debug enter sequence");
else {
debug_enter(msg);
}
@@ -277,7 +277,7 @@ plat_discover_slice(pfn_t pfn, pfn_t *first, pfn_t *last)
for (bd = 0; bd < CHERRYSTONE_SBD_SLOTS; bd++) {
for (cpu = 0; cpu < CHERRYSTONE_CPUS_PER_BOARD; cpu++) {
for (bank = 0; bank < CHERRYSTONE_BANKS_PER_MC;
- bank++) {
+ bank++) {
uint64_t *slice = slice_table[bd][cpu][bank];
uint64_t base = btop(slice[SLICE_PA]);
uint64_t len = btop(slice[SLICE_SPAN]);
@@ -437,7 +437,7 @@ plat_fill_mc(pnode_t nodeid)
*/
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
int slice;
pfn_t basepfn;
@@ -549,7 +549,7 @@ plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
{
if (flt_in_memory && (p2get_mem_unum != NULL))
return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8),
- buf, buflen, lenp));
+ buf, buflen, lenp));
else
return (ENOTSUP);
}
diff --git a/usr/src/uts/sun4u/chicago/os/chicago.c b/usr/src/uts/sun4u/chicago/os/chicago.c
index 152f08f249..f1cfc84bfe 100644
--- a/usr/src/uts/sun4u/chicago/os/chicago.c
+++ b/usr/src/uts/sun4u/chicago/os/chicago.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.
*/
@@ -320,24 +319,6 @@ plat_fill_mc(pnode_t nodeid)
plat_assign_lgrphand_to_mem_node((lgrp_handle_t)portid, portid);
}
-/* ARGSUSED */
-void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
-
/*
* Common locking enter code
*/
diff --git a/usr/src/uts/sun4u/cpu/us3_cheetah.c b/usr/src/uts/sun4u/cpu/us3_cheetah.c
index ce160b43c4..44fefd1ecf 100644
--- a/usr/src/uts/sun4u/cpu/us3_cheetah.c
+++ b/usr/src/uts/sun4u/cpu/us3_cheetah.c
@@ -667,36 +667,52 @@ uint64_t ecache_tl1_flushaddr = (uint64_t)-1; /* physaddr for E$ flushing */
/*
* Allocate and initialize the exclusive displacement flush area.
- * Called twice. The first time allocates virtual address. The second
- * call looks up the physical address.
*/
caddr_t
ecache_init_scrub_flush_area(caddr_t alloc_base)
{
- static caddr_t ecache_tl1_virtaddr;
+ unsigned size = 2 * CH_ECACHE_8M_SIZE;
+ caddr_t tmp_alloc_base = alloc_base;
+ caddr_t flush_alloc_base =
+ (caddr_t)roundup((uintptr_t)alloc_base, size);
+ caddr_t ecache_tl1_virtaddr;
- if (alloc_base != NULL) {
- /*
- * Need to allocate an exclusive flush area that is twice the
- * largest supported E$ size, physically contiguous, and
- * aligned on twice the largest E$ size boundary.
- */
- unsigned size = 2 * CH_ECACHE_8M_SIZE;
- caddr_t va = (caddr_t)roundup((uintptr_t)alloc_base, size);
+ /*
+ * Allocate the physical memory for the exclusive flush area
+ *
+ * Need to allocate an exclusive flush area that is twice the
+ * largest supported E$ size, physically contiguous, and
+ * aligned on twice the largest E$ size boundary.
+ *
+ * Memory allocated via prom_alloc is included in the "cage"
+ * from the DR perspective and due to this, its physical
+ * address will never change and the memory will not be
+ * removed.
+ *
+ * prom_alloc takes 3 arguments: bootops, virtual address hint,
+ * size of the area to allocate, and alignment of the area to
+ * allocate. It returns zero if the allocation fails, or the
+ * virtual address for a successful allocation. Memory prom_alloc'd
+ * is physically contiguous.
+ */
+ if ((ecache_tl1_virtaddr =
+ prom_alloc(flush_alloc_base, size, size)) != NULL) {
- ecache_tl1_virtaddr = va;
- alloc_base = va + size;
+ tmp_alloc_base =
+ (caddr_t)roundup((uintptr_t)(ecache_tl1_virtaddr + size),
+ ecache_alignsize);
- } else {
/*
- * Get the physical address of the exclusive flush area.
+ * get the physical address of the exclusive flush area
*/
- ASSERT(ecache_tl1_virtaddr != NULL);
ecache_tl1_flushaddr = va_to_pa(ecache_tl1_virtaddr);
- ASSERT(ecache_tl1_flushaddr != ((uint64_t)-1));
+
+ } else {
+ ecache_tl1_virtaddr = (caddr_t)-1;
+ cmn_err(CE_NOTE, "!ecache_init_scrub_flush_area failed\n");
}
- return (alloc_base);
+ return (tmp_alloc_base);
}
/*
diff --git a/usr/src/uts/sun4u/daktari/os/daktari.c b/usr/src/uts/sun4u/daktari/os/daktari.c
index f441ba787e..c6e3287636 100644
--- a/usr/src/uts/sun4u/daktari/os/daktari.c
+++ b/usr/src/uts/sun4u/daktari/os/daktari.c
@@ -153,7 +153,7 @@ load_platform_drivers(void)
/* Gain access into the ssc050_get_port function */
daktari_ssc050_get_port_bit = (int (*) (dev_info_t *, int, int,
- uint8_t *, int)) modgetsymvalue("ssc050_get_port_bit", 0);
+ uint8_t *, int)) modgetsymvalue("ssc050_get_port_bit", 0);
if (daktari_ssc050_get_port_bit == NULL) {
cmn_err(CE_WARN, "cannot find ssc050_get_port_bit");
return;
@@ -181,14 +181,14 @@ daktari_dev_search(dev_info_t *dip, void *arg)
int err;
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
- "compatible", &compatible) != DDI_PROP_SUCCESS)
+ "compatible", &compatible) != DDI_PROP_SUCCESS)
return (DDI_WALK_CONTINUE);
if (strcmp(compatible, "i2c-ssc050") == 0) {
ddi_prop_free(compatible);
err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
- DDI_PROP_DONTPASS, "reg", &dev_regs, &len);
+ DDI_PROP_DONTPASS, "reg", &dev_regs, &len);
if (err != DDI_PROP_SUCCESS) {
return (DDI_WALK_CONTINUE);
}
@@ -220,10 +220,10 @@ keyswitch_poll(void *arg)
int err;
err = daktari_ssc050_get_port_bit(dip, port, bit,
- &port_byte, I2C_NOSLEEP);
+ &port_byte, I2C_NOSLEEP);
if (err != 0) {
cmn_err(CE_WARN, "keyswitch polling disabled: "
- "errno=%d while reading ssc050", err);
+ "errno=%d while reading ssc050", err);
return;
}
@@ -236,7 +236,7 @@ daktari_abort_seq_handler(char *msg)
{
if (key_locked_bit == 0)
cmn_err(CE_CONT, "KEY in LOCKED position, "
- "ignoring debug enter sequence");
+ "ignoring debug enter sequence");
else {
debug_enter(msg);
}
@@ -430,7 +430,7 @@ plat_fill_mc(pnode_t nodeid)
*/
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
int slice;
pfn_t basepfn;
@@ -540,7 +540,7 @@ plat_get_mem_unum(int synd_code, uint64_t flt_addr, int flt_bus_id,
{
if (flt_in_memory && (p2get_mem_unum != NULL))
return (p2get_mem_unum(synd_code, P2ALIGN(flt_addr, 8),
- buf, buflen, lenp));
+ buf, buflen, lenp));
else
return (ENOTSUP);
}
diff --git a/usr/src/uts/sun4u/enchilada/os/enchilada.c b/usr/src/uts/sun4u/enchilada/os/enchilada.c
index 7415e77807..786228ee42 100644
--- a/usr/src/uts/sun4u/enchilada/os/enchilada.c
+++ b/usr/src/uts/sun4u/enchilada/os/enchilada.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.
*/
@@ -367,21 +366,3 @@ plat_fill_mc(pnode_t nodeid)
if (portid < max_mem_nodes)
plat_assign_lgrphand_to_mem_node(portid, portid);
}
-
-/* ARGSUSED */
-void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
diff --git a/usr/src/uts/sun4u/lw8/os/lw8_platmod.c b/usr/src/uts/sun4u/lw8/os/lw8_platmod.c
index aeb275346a..70442879c1 100644
--- a/usr/src/uts/sun4u/lw8/os/lw8_platmod.c
+++ b/usr/src/uts/sun4u/lw8/os/lw8_platmod.c
@@ -412,7 +412,7 @@ plat_fill_mc(pnode_t nodeid)
*/
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
int slice;
pfn_t basepfn;
@@ -657,8 +657,7 @@ find_chosen_dip(void)
dip = e_ddi_hold_devi_by_path(master_sbbc, 0);
if ((dip == NULL) || (ddi_get_nodeid(dip) != tunnel)) {
cmn_err(CE_PANIC,
- "e_ddi_hold_devi_by_path(%x) failed for SBBC\n",
- tunnel);
+ "e_ddi_hold_devi_by_path(%x) failed for SBBC\n", tunnel);
}
/* make sure devi_ref is ZERO */
@@ -824,7 +823,7 @@ plat_nodename_set(void)
*/
if (sg_mbox == NULL)
sg_mbox = (int (*)(sbbc_msg_t *, sbbc_msg_t *, time_t))
- modgetsymvalue("sbbc_mbox_request_response", 0);
+ modgetsymvalue("sbbc_mbox_request_response", 0);
if (sg_mbox == NULL) {
cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox not found\n");
@@ -867,7 +866,7 @@ plat_nodename_set(void)
cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox retval %d\n", rv);
} else if (resp.msg_status != 0) {
cmn_err(CE_NOTE, "!plat_nodename_set: msg_status %d\n",
- resp.msg_status);
+ resp.msg_status);
} else {
DCMNERR(CE_NOTE, "!plat_nodename_set was successful\n");
@@ -1130,10 +1129,10 @@ plat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
}
msgp = (sbbc_ecc_mbox_t *)kmem_zalloc(sizeof (sbbc_ecc_mbox_t),
- sleep_flag);
+ sleep_flag);
if (msgp == NULL) {
cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
- "unable to allocate sbbc_ecc_mbox");
+ "unable to allocate sbbc_ecc_mbox");
return (ENOMEM);
}
@@ -1150,7 +1149,7 @@ plat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
if (msgp->ecc_req.msg_buf == NULL) {
cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
- "unable to allocate request msg_buf");
+ "unable to allocate request msg_buf");
kmem_free((void *)msgp, sizeof (sbbc_ecc_mbox_t));
return (ENOMEM);
}
@@ -1274,11 +1273,11 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
" could not check current domain signature\n");
} else {
(void) (*iosram_read_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_DOMAINSIG_OFFSET,
- (char *)&current_sgn, sizeof (current_sgn));
+ SG_SGNBLK_DOMAINSIG_OFFSET,
+ (char *)&current_sgn, sizeof (current_sgn));
if (current_sgn.state_t.state == SIGST_EXIT)
signature = CPU_SIG_BLD(sig, state,
- SIGSUBST_PANIC_REBOOT);
+ SIGSUBST_PANIC_REBOOT);
}
}
@@ -1287,17 +1286,17 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
*/
if (cpuid >= 0) {
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_CPUSIG_OFFSET(cpuid), (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_CPUSIG_OFFSET(cpuid), (char *)&signature,
+ sizeof (signature));
} else {
for (i = 0; i < NCPU; i++) {
if (cpu[i] == NULL || !(cpu[i]->cpu_flags &
- (CPU_EXISTS|CPU_QUIESCED))) {
+ (CPU_EXISTS|CPU_QUIESCED))) {
continue;
}
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_CPUSIG_OFFSET(i), (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_CPUSIG_OFFSET(i), (char *)&signature,
+ sizeof (signature));
}
}
@@ -1306,8 +1305,8 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
}
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_DOMAINSIG_OFFSET, (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_DOMAINSIG_OFFSET, (char *)&signature,
+ sizeof (signature));
}
void
diff --git a/usr/src/uts/sun4u/ml/mach_locore.s b/usr/src/uts/sun4u/ml/mach_locore.s
index 75aefc3bc7..9393dd2f7a 100644
--- a/usr/src/uts/sun4u/ml/mach_locore.s
+++ b/usr/src/uts/sun4u/ml/mach_locore.s
@@ -232,18 +232,22 @@ afsrbuf:
! Stash away our arguments in memory.
!
sethi %hi(_local_p1275cis), %g1
- stn %o0, [%g1 + %lo(_local_p1275cis)]
- sethi %hi(bootops), %g1
- stn %o1, [%g1 + %lo(bootops)]
+ stn %o4, [%g1 + %lo(_local_p1275cis)]
!
! Initialize CPU state registers
!
wrpr %g0, PSTATE_KERN, %pstate
wr %g0, %g0, %fprs
- CLEARTICKNPT ! allow user rdtick
!
+ ! call krtld to link the world together
+ !
+ call kobj_start
+ mov %o4, %o0
+
+ CLEARTICKNPT ! allow user rdtick
+ !
! Get maxwin from %ver
!
rdpr %ver, %g1
@@ -297,8 +301,8 @@ afsrbuf:
set t0stacktop, %g1 ! setup kernel stack pointer
sub %g1, SA(KFPUSIZE+GSR_SIZE), %g2
and %g2, 0x3f, %g3
- sub %g2, %g3, %o2
- sub %o2, SA(MPCBSIZE) + STACK_BIAS, %sp
+ sub %g2, %g3, %o1
+ sub %o1, SA(MPCBSIZE) + STACK_BIAS, %sp
!
! Initialize global thread register.
@@ -326,10 +330,7 @@ afsrbuf:
!
! Call mlsetup with address of prototype user registers.
- ! and p1275cis pointers.
-
- sethi %hi(_local_p1275cis), %o1
- ldn [%o1 + %lo(_local_p1275cis)], %o1
+ !
call mlsetup
add %sp, REGOFF + STACK_BIAS, %o0
diff --git a/usr/src/uts/sun4u/opl/os/opl.c b/usr/src/uts/sun4u/opl/os/opl.c
index b4c3e94c51..f2d3162a93 100644
--- a/usr/src/uts/sun4u/opl/os/opl.c
+++ b/usr/src/uts/sun4u/opl/os/opl.c
@@ -457,7 +457,7 @@ plat_pfn_to_mem_node(pfn_t pfn)
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
size_t elem;
pfn_t basepfn;
@@ -475,9 +475,9 @@ plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
* Boot install lists are arranged <addr, len>, <addr, len>, ...
*/
ssize = (1ull << OPL_MC_MEMBOARD_SHIFT);
- for (elem = 0; elem < nelems; elem += 2) {
- low = (uint64_t)list[elem];
- high = low+(uint64_t)(list[elem+1]);
+ for (elem = 0; elem < nelems; list++, elem++) {
+ low = list->addr;
+ high = low + list->size;
while (low < high) {
boundary = roundup(low+1, ssize);
boundary = MIN(high, boundary);
diff --git a/usr/src/uts/sun4u/opl/unix/Makefile b/usr/src/uts/sun4u/opl/unix/Makefile
index 0be4aed67f..b8b938ca51 100644
--- a/usr/src/uts/sun4u/opl/unix/Makefile
+++ b/usr/src/uts/sun4u/opl/unix/Makefile
@@ -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.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -48,13 +48,14 @@ LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_OPL_KERN_DIR)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
GENUNIX = genunix
@@ -99,8 +100,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -133,19 +135,23 @@ install: $(INSTALL_DEPS)
symcheck: $(SYM_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
-symcheck.targ: $(UNIX_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
+symcheck.targ: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4u/schumacher/os/schumacher.c b/usr/src/uts/sun4u/schumacher/os/schumacher.c
index c8463c4226..abc5dec3c7 100644
--- a/usr/src/uts/sun4u/schumacher/os/schumacher.c
+++ b/usr/src/uts/sun4u/schumacher/os/schumacher.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.
*/
@@ -350,21 +349,3 @@ plat_fill_mc(pnode_t nodeid)
if (portid < max_mem_nodes)
plat_assign_lgrphand_to_mem_node(portid, portid);
}
-
-/* ARGSUSED */
-void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
diff --git a/usr/src/uts/sun4u/seattle/os/seattle.c b/usr/src/uts/sun4u/seattle/os/seattle.c
index ee74bbe5df..c165e2eeac 100644
--- a/usr/src/uts/sun4u/seattle/os/seattle.c
+++ b/usr/src/uts/sun4u/seattle/os/seattle.c
@@ -194,7 +194,7 @@ load_platform_drivers(void)
* updates to ALOM.
*/
rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
- modgetsymvalue("rmc_comm_request_nowait", 0);
+ modgetsymvalue("rmc_comm_request_nowait", 0);
}
/*
@@ -315,7 +315,7 @@ plat_nodename_set(void)
* find the symbol for the mailbox routine
*/
rmc_req_res = (int (*)(rmc_comm_msg_t *, rmc_comm_msg_t *, time_t))
- modgetsymvalue("rmc_comm_request_response", 0);
+ modgetsymvalue("rmc_comm_request_response", 0);
if (rmc_req_res == NULL) {
return;
@@ -387,7 +387,7 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
* find the symbol for the mailbox routine
*/
rmc_req_now = (int (*)(rmc_comm_msg_t *, uint8_t))
- modgetsymvalue("rmc_comm_request_nowait", 0);
+ modgetsymvalue("rmc_comm_request_nowait", 0);
if (rmc_req_now == NULL) {
return;
}
@@ -565,24 +565,6 @@ plat_fill_mc(pnode_t nodeid)
plat_assign_lgrphand_to_mem_node((lgrp_handle_t)portid, portid);
}
-/* ARGSUSED */
-void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
-{
- size_t elem;
- pfn_t basepfn;
- pgcnt_t npgs;
-
- /*
- * Boot install lists are arranged <addr, len>, <addr, len>, ...
- */
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
- mem_node_add_slice(basepfn, basepfn + npgs - 1);
- }
-}
-
/*
* Common locking enter code
*/
diff --git a/usr/src/uts/sun4u/serengeti/os/serengeti.c b/usr/src/uts/sun4u/serengeti/os/serengeti.c
index ce9e95e669..847384abee 100644
--- a/usr/src/uts/sun4u/serengeti/os/serengeti.c
+++ b/usr/src/uts/sun4u/serengeti/os/serengeti.c
@@ -405,7 +405,7 @@ plat_fill_mc(pnode_t nodeid)
*/
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
int slice;
pfn_t basepfn;
@@ -813,7 +813,7 @@ plat_nodename_set(void)
* find the symbol for the mailbox routine
*/
sg_mbox = (int (*)(sbbc_msg_t *, sbbc_msg_t *, time_t))
- modgetsymvalue("sbbc_mbox_request_response", 0);
+ modgetsymvalue("sbbc_mbox_request_response", 0);
if (sg_mbox == NULL) {
cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox not found\n");
@@ -856,7 +856,7 @@ plat_nodename_set(void)
cmn_err(CE_NOTE, "!plat_nodename_set: sg_mbox retval %d\n", rv);
} else if (resp.msg_status != 0) {
cmn_err(CE_NOTE, "!plat_nodename_set: msg_status %d\n",
- resp.msg_status);
+ resp.msg_status);
} else {
DCMNERR(CE_NOTE, "!plat_nodename_set was successful\n");
@@ -1116,10 +1116,10 @@ plat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
}
msgp = (sbbc_ecc_mbox_t *)kmem_zalloc(sizeof (sbbc_ecc_mbox_t),
- sleep_flag);
+ sleep_flag);
if (msgp == NULL) {
cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
- "unable to allocate sbbc_ecc_mbox");
+ "unable to allocate sbbc_ecc_mbox");
return (ENOMEM);
}
@@ -1136,7 +1136,7 @@ plat_send_ecc_mailbox_msg(plat_ecc_message_type_t msg_type, void *datap)
if (msgp->ecc_req.msg_buf == NULL) {
cmn_err(CE_NOTE, "!plat_send_ecc_mailbox_msg: "
- "unable to allocate request msg_buf");
+ "unable to allocate request msg_buf");
kmem_free((void *)msgp, sizeof (sbbc_ecc_mbox_t));
return (ENOMEM);
}
@@ -1258,11 +1258,11 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
" could not check current domain signature\n");
} else {
(void) (*iosram_read_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_DOMAINSIG_OFFSET,
- (char *)&current_sgn, sizeof (current_sgn));
+ SG_SGNBLK_DOMAINSIG_OFFSET,
+ (char *)&current_sgn, sizeof (current_sgn));
if (current_sgn.state_t.state == SIGST_EXIT)
signature = CPU_SIG_BLD(sig, state,
- SIGSUBST_PANIC_REBOOT);
+ SIGSUBST_PANIC_REBOOT);
}
}
@@ -1271,17 +1271,17 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
*/
if (cpuid >= 0) {
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_CPUSIG_OFFSET(cpuid), (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_CPUSIG_OFFSET(cpuid), (char *)&signature,
+ sizeof (signature));
} else {
for (i = 0; i < NCPU; i++) {
if (cpu[i] == NULL || !(cpu[i]->cpu_flags &
- (CPU_EXISTS|CPU_QUIESCED))) {
+ (CPU_EXISTS|CPU_QUIESCED))) {
continue;
}
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_CPUSIG_OFFSET(i), (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_CPUSIG_OFFSET(i), (char *)&signature,
+ sizeof (signature));
}
}
@@ -1290,8 +1290,8 @@ cpu_sgn_update(ushort_t sig, uchar_t state, uchar_t sub_state, int cpuid)
}
(void) (*iosram_write_ptr)(SBBC_SIGBLCK_KEY,
- SG_SGNBLK_DOMAINSIG_OFFSET, (char *)&signature,
- sizeof (signature));
+ SG_SGNBLK_DOMAINSIG_OFFSET, (char *)&signature,
+ sizeof (signature));
}
void
diff --git a/usr/src/uts/sun4u/serengeti/unix/Makefile b/usr/src/uts/sun4u/serengeti/unix/Makefile
index e909cd31e1..5e01356937 100644
--- a/usr/src/uts/sun4u/serengeti/unix/Makefile
+++ b/usr/src/uts/sun4u/serengeti/unix/Makefile
@@ -49,13 +49,14 @@ LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_SERENGETI_KERN_DIR)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
GENUNIX = genunix
@@ -100,8 +101,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -134,19 +136,23 @@ install: $(INSTALL_DEPS)
symcheck: $(SYM_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
-symcheck.targ: $(UNIX_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
+symcheck.targ: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M $(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4u/starcat/os/starcat.c b/usr/src/uts/sun4u/starcat/os/starcat.c
index 4cde2078c8..c00976dfc9 100644
--- a/usr/src/uts/sun4u/starcat/os/starcat.c
+++ b/usr/src/uts/sun4u/starcat/os/starcat.c
@@ -313,7 +313,7 @@ plat_pfn_to_mem_node(pfn_t pfn)
/* ARGSUSED */
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
size_t elem;
pfn_t basepfn;
@@ -330,9 +330,9 @@ plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
/*
* Boot install lists are arranged <addr, len>, <addr, len>, ...
*/
- for (elem = 0; elem < nelems; elem += 2) {
- basepfn = btop(list[elem]);
- npgs = btop(list[elem+1]);
+ for (elem = 0; elem < nelems; list++, elem++) {
+ basepfn = btop(list->addr);
+ npgs = btop(list->size);
mem_node_add_slice(basepfn, basepfn + npgs - 1);
}
}
diff --git a/usr/src/uts/sun4u/starcat/unix/Makefile b/usr/src/uts/sun4u/starcat/unix/Makefile
index 9d1c3b50f5..0920829465 100644
--- a/usr/src/uts/sun4u/starcat/unix/Makefile
+++ b/usr/src/uts/sun4u/starcat/unix/Makefile
@@ -49,13 +49,14 @@ LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_STARCAT_KERN_DIR)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
GENUNIX = genunix
@@ -100,8 +101,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -134,19 +136,23 @@ install: $(INSTALL_DEPS)
symcheck: $(SYM_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
-symcheck.targ: $(UNIX_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
+symcheck.targ: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS) $(DTRACESTUBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4u/starfire/unix/Makefile b/usr/src/uts/sun4u/starfire/unix/Makefile
index 889cfa5b4d..e856bc1f2f 100644
--- a/usr/src/uts/sun4u/starfire/unix/Makefile
+++ b/usr/src/uts/sun4u/starfire/unix/Makefile
@@ -49,14 +49,15 @@ LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_STARFIRE_KERN_DIR)/$(UNIX)
UNIX32_LINK = $(ROOT_STARFIRE_KERN_DIR_32)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
GENUNIX = genunix
@@ -93,8 +94,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -125,22 +127,26 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
$(UNIX32_LINK): $(ROOT_PSM_KERN_DIR_32) $(UNIX_BIN)
-$(RM) $@; ln -s $(SUBDIR64)/$(UNIX) $@
-symcheck: $(UNIX_O) $(MODSTUBS_O) $(LIBS)
+symcheck: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4u/sys/machparam.h b/usr/src/uts/sun4u/sys/machparam.h
index 394079a247..c53632a5eb 100644
--- a/usr/src/uts/sun4u/sys/machparam.h
+++ b/usr/src/uts/sun4u/sys/machparam.h
@@ -201,6 +201,14 @@ extern "C" {
#define SYSLIMIT32 ADDRESS_C(0x80000000)
/*
+ * BOOTTMPBASE is the base of a space that can be reclaimed
+ * after the kernel takes over the machine. It contains the
+ * boot archive and memory allocated by krtld before kmem_alloc
+ * is brought online.
+ */
+#define BOOTTMPBASE ADDRESS_C(0x4C000000)
+
+/*
* MEMSCRUBBASE is the base virtual address for the memory scrubber
* to read large pages. It MUST be 4MB page aligned.
*/
@@ -242,15 +250,7 @@ extern "C" {
/*
* Allocate space for kernel modules on nucleus pages
*/
-#define MODDATA 1024 * 256
-
-/*
- * On systems with <MODTEXT_SM_SIZE MB available physical memory,
- * cap the in-nucleus module text to MODTEXT_SM_CAP bytes. The
- * cap must be a multiple of the base page size. Also see startup.c.
- */
-#define MODTEXT_SM_CAP (0x200000) /* bytes */
-#define MODTEXT_SM_SIZE (256) /* MB */
+#define MODDATA 1024 * 512
/*
* The heap has a region allocated from it specifically for module text that
@@ -292,7 +292,7 @@ extern "C" {
* reflect the fact that it's actually the limit for 32-bit kernel virtual
* addresses.
*/
-#define KERNEL_LIMIT32 (SYSBASE32)
+#define KERNEL_LIMIT32 BOOTTMPBASE
#define PFN_TO_BUSTYPE(pfn) (((pfn) >> 19) & 0x1FF)
#define IO_BUSTYPE(pfn) ((PFN_TO_BUSTYPE(pfn) & 0x100) >> 8)
diff --git a/usr/src/uts/sun4u/sys/machsystm.h b/usr/src/uts/sun4u/sys/machsystm.h
index 28d3f1a137..76e96a56d6 100644
--- a/usr/src/uts/sun4u/sys/machsystm.h
+++ b/usr/src/uts/sun4u/sys/machsystm.h
@@ -276,9 +276,19 @@ extern uint_t vac_colors_mask;
extern int ndata_alloc_page_freelists(struct memlist *, int);
extern int ndata_alloc_dmv(struct memlist *);
extern int ndata_alloc_tsbs(struct memlist *, pgcnt_t);
-extern int ndata_alloc_hat(struct memlist *, pgcnt_t, pgcnt_t);
-extern caddr_t alloc_page_freelists(int, caddr_t, int);
-extern caddr_t alloc_hme_buckets(caddr_t, int);
+extern int ndata_alloc_hat(struct memlist *, pgcnt_t);
+extern int ndata_alloc_kpm(struct memlist *, pgcnt_t);
+extern int ndata_alloc_page_mutexs(struct memlist *ndata);
+
+extern size_t calc_pp_sz(pgcnt_t);
+extern size_t calc_kpmpp_sz(pgcnt_t);
+extern size_t calc_hmehash_sz(pgcnt_t);
+extern size_t calc_pagehash_sz(pgcnt_t);
+extern size_t calc_free_pagelist_sz(void);
+
+extern caddr_t alloc_hmehash(caddr_t);
+extern caddr_t alloc_page_freelists(caddr_t);
+
extern size_t page_ctrs_sz(void);
extern caddr_t page_ctrs_alloc(caddr_t);
extern void page_freelist_coalesce_all(int);
diff --git a/usr/src/uts/sun4u/sys/prom_plat.h b/usr/src/uts/sun4u/sys/prom_plat.h
index 646da1c7cc..66ea55b2c1 100644
--- a/usr/src/uts/sun4u/sys/prom_plat.h
+++ b/usr/src/uts/sun4u/sys/prom_plat.h
@@ -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.
*/
@@ -150,6 +150,14 @@ extern int prom_map_phys(int mode, size_t size, caddr_t virt,
extern void prom_unmap_phys(size_t size, caddr_t virt);
extern void prom_unmap_virt(size_t size, caddr_t virt);
+extern int prom_phys_installed_len(void);
+extern int prom_phys_avail_len(void);
+extern int prom_virt_avail_len(void);
+
+extern int prom_phys_installed(caddr_t);
+extern int prom_phys_avail(caddr_t);
+extern int prom_virt_avail(caddr_t);
+
/*
* prom_retain allocates or returns retained physical memory
* identified by the arguments of name string "id", "size" and "align".
diff --git a/usr/src/uts/sun4u/sys/traptrace.h b/usr/src/uts/sun4u/sys/traptrace.h
index b0c36d6ac6..24a6104b9e 100644
--- a/usr/src/uts/sun4u/sys/traptrace.h
+++ b/usr/src/uts/sun4u/sys/traptrace.h
@@ -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.
*/
@@ -53,7 +53,7 @@ extern "C" {
* the TRAP_ENT_TT field
*/
-#define TRAP_TPGS (2 * PAGESIZE) /* default size is two pages */
+#define TRAP_TSIZE (2 * PAGESIZE) /* default size is two pages */
#ifndef _ASM
@@ -71,13 +71,6 @@ struct trap_trace_record {
uintptr_t tt_f4;
};
-#define TRAP_TSIZE ((TRAP_TPGS / sizeof (struct trap_trace_record)) * \
- sizeof (struct trap_trace_record))
-
-#else
-
-#define TRAP_TSIZE ((TRAP_TPGS / TRAP_ENT_SIZE) * TRAP_ENT_SIZE)
-
#endif
#define HTRAP_TSIZE 0
@@ -111,9 +104,9 @@ extern TRAP_TRACE_CTL trap_trace_ctl[]; /* allocated in locore.s */
extern int trap_trace_bufsize; /* default buffer size */
extern char trap_tr0[]; /* prealloc buf for boot cpu */
extern int trap_freeze; /* freeze the trap trace */
-extern caddr_t ttrace_buf; /* buffer bop alloced */
+extern caddr_t ttrace_buf; /* kmem64 buffer */
extern int ttrace_index; /* index used */
-extern caddr_t trap_trace_alloc(caddr_t);
+extern size_t calc_traptrace_sz(void);
extern void mach_htraptrace_setup(int);
extern void mach_htraptrace_configure(int);
extern void mach_htraptrace_cleanup(int);
diff --git a/usr/src/uts/sun4u/unix/Makefile b/usr/src/uts/sun4u/unix/Makefile
index 90535da2de..d41a0a9f07 100644
--- a/usr/src/uts/sun4u/unix/Makefile
+++ b/usr/src/uts/sun4u/unix/Makefile
@@ -27,7 +27,7 @@
#
#
-# This makefile drives the production of /unix (and unix.o).
+# This makefile drives the production of unix (and unix.o).
#
# sun4u implementation architecture dependent
#
@@ -46,16 +46,19 @@ OBJECTS = $(SPECIAL_OBJS:%=$(OBJS_DIR)/%) \
$(MACH_NOT_YET_KMODS:%=$(OBJS_DIR)/%)
LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(CORE_OBJS:%.o=$(LINTS_DIR)/%.ln) \
+ $(KRTLD_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_PSM_KERN_DIR)/$(UNIX)
UNIX32_LINK = $(ROOT_PSM_KERN_DIR_32)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
+#UNIX_GLOM = $(OBJS_DIR)/unix.glom
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
@@ -93,8 +96,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -138,22 +142,26 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
$(UNIX32_LINK): $(ROOT_PSM_KERN_DIR_32) $(UNIX_BIN)
-$(RM) $@; ln -s $(SUBDIR64)/$(UNIX) $@
-symcheck: $(UNIX_O) $(MODSTUBS_O) $(LIBS)
+symcheck: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4v/Makefile.files b/usr/src/uts/sun4v/Makefile.files
index aac90ceb1b..9cc13305af 100644
--- a/usr/src/uts/sun4v/Makefile.files
+++ b/usr/src/uts/sun4v/Makefile.files
@@ -34,7 +34,6 @@
# object lists
#
CORE_OBJS += bootops.o
-CORE_OBJS += prom_alloc.o
CORE_OBJS += cmp.o
CORE_OBJS += cpc_hwreg.o
CORE_OBJS += cpc_subr.o
diff --git a/usr/src/uts/sun4v/ml/mach_locore.s b/usr/src/uts/sun4v/ml/mach_locore.s
index fdd6b28992..8e391ed480 100644
--- a/usr/src/uts/sun4v/ml/mach_locore.s
+++ b/usr/src/uts/sun4v/ml/mach_locore.s
@@ -242,16 +242,19 @@ afsrbuf:
! Stash away our arguments in memory.
!
sethi %hi(_local_p1275cis), %g1
- stn %o0, [%g1 + %lo(_local_p1275cis)]
- sethi %hi(bootops), %g1
- stn %o1, [%g1 + %lo(bootops)]
+ stn %o4, [%g1 + %lo(_local_p1275cis)]
!
! Initialize CPU state registers
!
wrpr %g0, PSTATE_KERN, %pstate
wr %g0, %g0, %fprs
- CLEARTICKNPT ! allow user rdtick
+
+ !
+ ! call krtld to link the world together
+ !
+ call kobj_start
+ mov %o4, %o0
! Write 0x1f (MAX_REG_WINDOWS) to %cwp and read back to get
! the actual implemented nwin - 1 value
@@ -308,8 +311,8 @@ afsrbuf:
set t0stacktop, %g1 ! setup kernel stack pointer
sub %g1, SA(KFPUSIZE+GSR_SIZE), %g2
and %g2, 0x3f, %g3
- sub %g2, %g3, %o2
- sub %o2, SA(MPCBSIZE) + STACK_BIAS, %sp
+ sub %g2, %g3, %o1
+ sub %o1, SA(MPCBSIZE) + STACK_BIAS, %sp
!
! Initialize global thread register.
@@ -337,10 +340,7 @@ afsrbuf:
!
! Call mlsetup with address of prototype user registers.
- ! and p1275cis pointers.
-
- sethi %hi(_local_p1275cis), %o1
- ldn [%o1 + %lo(_local_p1275cis)], %o1
+ !
call mlsetup
add %sp, REGOFF + STACK_BIAS, %o0
diff --git a/usr/src/uts/sun4v/os/mpo.c b/usr/src/uts/sun4v/os/mpo.c
index d1bae0a815..cf4a4836b1 100644
--- a/usr/src/uts/sun4v/os/mpo.c
+++ b/usr/src/uts/sun4v/os/mpo.c
@@ -874,7 +874,7 @@ mpo_plat_assign_lgrphand_to_mem_node(lgrp_handle_t plathand, int mnode)
*/
void
-plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
+plat_build_mem_nodes(prom_memlist_t *list, size_t nelems)
{
lgrp_handle_t lgrphand, lgrp_start;
int i, mnode, elem;
@@ -888,9 +888,9 @@ plat_build_mem_nodes(u_longlong_t *list, size_t nelems)
/* Check for non-MPO sun4v platforms */
if (n_locality_groups <= 1) {
mpo_plat_assign_lgrphand_to_mem_node(LGRP_DEFAULT_HANDLE, 0);
- for (elem = 0; elem < nelems; elem += 2) {
- base = list[elem];
- len = list[elem+1];
+ for (elem = 0; elem < nelems; list++, elem++) {
+ base = list->addr;
+ len = list->size;
mpo_mem_node_add_slice(btop(base),
btop(base + len - 1));
diff --git a/usr/src/uts/sun4v/sys/machparam.h b/usr/src/uts/sun4v/sys/machparam.h
index ffa3fec5da..b6ca2491a3 100644
--- a/usr/src/uts/sun4v/sys/machparam.h
+++ b/usr/src/uts/sun4v/sys/machparam.h
@@ -184,6 +184,14 @@ extern "C" {
#define SYSLIMIT32 ADDRESS_C(0x80000000)
/*
+ * BOOTTMPBASE is the base of a space that can be reclaimed
+ * after the kernel takes over the machine. It contains the
+ * boot archive and memory allocated by krtld before kmem_alloc
+ * is brought online.
+ */
+#define BOOTTMPBASE ADDRESS_C(0x4C000000)
+
+/*
* MEMSCRUBBASE is the base virtual address for the memory scrubber
* to read large pages. It MUST be 4MB page aligned.
*/
@@ -225,15 +233,7 @@ extern "C" {
/*
* Allocate space for kernel modules on nucleus pages
*/
-#define MODDATA 1024 * 256
-
-/*
- * On systems with <MODTEXT_SM_SIZE MB available physical memory,
- * cap the in-nucleus module text to MODTEXT_SM_CAP bytes. The
- * cap must be a multiple of the base page size. Also see startup.c.
- */
-#define MODTEXT_SM_CAP (0x200000) /* bytes */
-#define MODTEXT_SM_SIZE (256) /* MB */
+#define MODDATA 1024 * 512
/*
* The heap has a region allocated from it specifically for module text that
@@ -283,7 +283,7 @@ extern "C" {
* reflect the fact that it's actually the limit for 32-bit kernel virtual
* addresses.
*/
-#define KERNEL_LIMIT32 (SYSBASE32)
+#define KERNEL_LIMIT32 BOOTTMPBASE
/*
* Defines used for the ptl1_panic parameter, which is passed to the
diff --git a/usr/src/uts/sun4v/sys/machsystm.h b/usr/src/uts/sun4v/sys/machsystm.h
index 84ef8b740f..b9df6e3f45 100644
--- a/usr/src/uts/sun4v/sys/machsystm.h
+++ b/usr/src/uts/sun4v/sys/machsystm.h
@@ -277,9 +277,19 @@ extern int ndata_alloc_mmfsa(struct memlist *);
extern int ndata_alloc_page_freelists(struct memlist *, int);
extern int ndata_alloc_dmv(struct memlist *);
extern int ndata_alloc_tsbs(struct memlist *, pgcnt_t);
-extern int ndata_alloc_hat(struct memlist *, pgcnt_t, pgcnt_t);
-extern caddr_t alloc_page_freelists(int, caddr_t, int);
-extern caddr_t alloc_hme_buckets(caddr_t, int);
+extern int ndata_alloc_hat(struct memlist *, pgcnt_t);
+extern int ndata_alloc_kpm(struct memlist *, pgcnt_t);
+extern int ndata_alloc_page_mutexs(struct memlist *ndata);
+
+extern size_t calc_pp_sz(pgcnt_t);
+extern size_t calc_kpmpp_sz(pgcnt_t);
+extern size_t calc_hmehash_sz(pgcnt_t);
+extern size_t calc_pagehash_sz(pgcnt_t);
+extern size_t calc_free_pagelist_sz(void);
+
+extern caddr_t alloc_hmehash(caddr_t);
+extern caddr_t alloc_page_freelists(caddr_t);
+
extern size_t page_ctrs_sz(void);
extern caddr_t page_ctrs_alloc(caddr_t);
extern void page_freelist_coalesce_all(int);
diff --git a/usr/src/uts/sun4v/sys/prom_plat.h b/usr/src/uts/sun4v/sys/prom_plat.h
index 6e7ffb247b..7316a5c211 100644
--- a/usr/src/uts/sun4v/sys/prom_plat.h
+++ b/usr/src/uts/sun4v/sys/prom_plat.h
@@ -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.
*/
@@ -150,6 +150,14 @@ extern int prom_map_phys(int mode, size_t size, caddr_t virt,
extern void prom_unmap_phys(size_t size, caddr_t virt);
extern void prom_unmap_virt(size_t size, caddr_t virt);
+extern int prom_phys_installed_len(void);
+extern int prom_phys_avail_len(void);
+extern int prom_virt_avail_len(void);
+
+extern int prom_phys_installed(caddr_t);
+extern int prom_phys_avail(caddr_t);
+extern int prom_virt_avail(caddr_t);
+
/*
* prom_retain allocates or returns retained physical memory
* identified by the arguments of name string "id", "size" and "align".
diff --git a/usr/src/uts/sun4v/sys/traptrace.h b/usr/src/uts/sun4v/sys/traptrace.h
index 90343b8767..08f5dea459 100644
--- a/usr/src/uts/sun4v/sys/traptrace.h
+++ b/usr/src/uts/sun4v/sys/traptrace.h
@@ -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.
*/
@@ -58,7 +58,7 @@ extern "C" {
* the TRAP_ENT_TT field
*/
-#define TRAP_TBUF (2 * PAGESIZE) /* default size is two pages */
+#define TRAP_TSIZE (2 * PAGESIZE) /* default size is two pages */
#ifndef _ASM
@@ -113,19 +113,10 @@ struct trap_trace_record {
uintptr_t tt_f4;
};
-#define TRAP_TSIZE ((TRAP_TBUF / sizeof (struct trap_trace_record)) * \
- sizeof (struct trap_trace_record))
-
-/* Rounding not needed, done for consistency */
-#define HTRAP_TSIZE ((TRAP_TBUF / sizeof (struct htrap_trace_record)) * \
- sizeof (struct htrap_trace_record))
-
-#else
+#endif
-#define TRAP_TSIZE ((TRAP_TBUF / TRAP_ENT_SIZE) * TRAP_ENT_SIZE)
-#define HTRAP_TSIZE ((TRAP_TBUF / HTRAP_ENT_SIZE) * HTRAP_ENT_SIZE)
+#define HTRAP_TSIZE TRAP_TSIZE
-#endif
/*
* Trap tracing buffer header.
@@ -159,9 +150,9 @@ extern TRAP_TRACE_CTL trap_trace_ctl[]; /* allocated in locore.s */
extern int trap_trace_bufsize; /* default buffer size */
extern char trap_tr0[]; /* prealloc buf for boot cpu */
extern int trap_freeze; /* freeze the trap trace */
-extern caddr_t ttrace_buf; /* buffer bop alloced */
+extern caddr_t ttrace_buf; /* kmem64 buffer */
extern int ttrace_index; /* index used */
-extern caddr_t trap_trace_alloc(caddr_t);
+extern size_t calc_traptrace_sz(void);
extern int htrap_trace_bufsize; /* default hv buffer size */
extern int mach_htraptrace_enable;
diff --git a/usr/src/uts/sun4v/unix/Makefile b/usr/src/uts/sun4v/unix/Makefile
index cc2f63dd7e..411bd5ef04 100644
--- a/usr/src/uts/sun4v/unix/Makefile
+++ b/usr/src/uts/sun4v/unix/Makefile
@@ -46,17 +46,19 @@ OBJECTS = $(SPECIAL_OBJS:%=$(OBJS_DIR)/%) \
$(MACH_NOT_YET_KMODS:%=$(OBJS_DIR)/%)
LINTS = $(SPECIAL_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(CORE_OBJS:%.o=$(LINTS_DIR)/%.ln) \
+ $(KRTLD_OBJS:%.o=$(LINTS_DIR)/%.ln) \
$(MACH_NOT_YET_KMODS:%.o=$(LINTS_DIR)/%.ln) \
$(LINTS_DIR)/vers.ln \
$(LINTS_DIR)/modstubs.ln
+
+KRTLD_MAPFILE = $(UTSBASE)/sparc/krtld/mapfile
+KRTLD_OBJECTS = $(KRTLD_OBJS:%=$(OBJS_DIR)/%)
+KRTLD_O = $(OBJS_DIR)/krtld.o
+
ROOTMODULE = $(ROOT_PSM_KERN_DIR)/$(UNIX)
UNIX32_LINK = $(ROOT_PSM_KERN_DIR_32)/$(UNIX)
UNIX_BIN = $(OBJS_DIR)/$(UNIX)
-KRTLD_32 = misc/krtld
-KRTLD_64 = misc/$(SUBDIR64)/krtld
-KRTLD = $(KRTLD_$(CLASS))
-
LIBS = $(GENLIB) $(PLATLIB) $(CPULIB)
GENUNIX = genunix
@@ -93,8 +95,9 @@ UNIX_DIR = .
#
# Overrides
#
-CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(OBJS_DIR)/vers.c \
- $(OBJS_DIR)/vers.o $(CPU_OBJ) $(CPULIB) \
+CLEANFILES += $(UNIX_O) $(MODSTUBS_O) $(KRTLD_O) $(KRTLD_OBJECTS) \
+ $(OBJS_DIR)/vers.c $(OBJS_DIR)/vers.o \
+ $(CPU_OBJ) $(CPULIB) \
$(DTRACESTUBS_O) $(DTRACESTUBS)
CLOBBERFILES = $(CLEANFILES) $(UNIX_BIN)
@@ -138,22 +141,26 @@ clean.lint: $(CLEAN_LINT_DEPS)
install: $(INSTALL_DEPS)
-$(UNIX_BIN): $(UNIX_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) $(DTRACESTUBS)
- $(LD) -dy -b -o $@ -e _start -I $(KRTLD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+$(UNIX_BIN): $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(MAPFILE) $(LIBS) \
+ $(DTRACESTUBS)
+ $(LD) -dy -b -o $@ -e _start -M $(MAPFILE) \
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(CTFMERGE_UNIQUIFY_AGAINST_GENUNIX)
$(POST_PROCESS)
$(UNIX32_LINK): $(ROOT_PSM_KERN_DIR_32) $(UNIX_BIN)
-$(RM) $@; ln -s $(SUBDIR64)/$(UNIX) $@
-symcheck: $(UNIX_O) $(MODSTUBS_O) $(LIBS)
+symcheck: $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBS)
$(LD) -dy -b -o $(SYM_MOD) -M $(MAPFILE) \
- $(UNIX_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
+ $(UNIX_O) $(KRTLD_O) $(MODSTUBS_O) $(LIBOPTS) $(DTRACESTUBS)
$(UNIX_O): $(OBJECTS) $(OBJS_DIR)/vers.o
$(LD) -r -o $@ $(OBJECTS) $(OBJS_DIR)/vers.o
+$(KRTLD_O): $(KRTLD_OBJECTS)
+ $(LD) -r -o $@ -M$(KRTLD_MAPFILE) $(KRTLD_OBJECTS)
+
#
# Special rules for generating assym.h for inclusion in assembly files.
#
diff --git a/usr/src/uts/sun4v/vm/mach_vm_dep.c b/usr/src/uts/sun4v/vm/mach_vm_dep.c
index b46a1f3f09..09aea923e0 100644
--- a/usr/src/uts/sun4v/vm/mach_vm_dep.c
+++ b/usr/src/uts/sun4v/vm/mach_vm_dep.c
@@ -53,6 +53,7 @@
#include <vm/seg_kmem.h>
#include <sys/stack.h>
#include <sys/atomic.h>
+#include <sys/promif.h>
uint_t page_colors = 0;
uint_t page_colors_mask = 0;
@@ -730,6 +731,10 @@ contig_mem_prealloc(caddr_t alloc_base, pgcnt_t npages)
MMU_PAGESIZE4M);
alloc_base = (caddr_t)roundup((uintptr_t)alloc_base, MMU_PAGESIZE4M);
+ if (prom_alloc(alloc_base, contig_mem_prealloc_size,
+ MMU_PAGESIZE4M) != alloc_base)
+ prom_panic("can't allocate contig mem");
+
contig_mem_prealloc_buf = alloc_base;
alloc_base += contig_mem_prealloc_size;