Index: head/sys/conf/files =================================================================== --- head/sys/conf/files (revision 310296) +++ head/sys/conf/files (revision 310297) @@ -1,4657 +1,4658 @@ # $FreeBSD$ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # acpi_quirks.h optional acpi \ dependency "$S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ compile-with "${AWK} -f $S/tools/acpi_quirks2h.awk $S/dev/acpica/acpi_quirks" \ no-obj no-implicit-rule before-depend \ clean "acpi_quirks.h" bhnd_nvram_map.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -h" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map.h" bhnd_nvram_map_data.h optional bhnd \ dependency "$S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/tools/nvram_map_gen.awk $S/dev/bhnd/nvram/nvram_map" \ compile-with "sh $S/dev/bhnd/tools/nvram_map_gen.sh $S/dev/bhnd/nvram/nvram_map -d" \ no-obj no-implicit-rule before-depend \ clean "bhnd_nvram_map_data.h" # # The 'fdt_dtb_file' target covers an actual DTB file name, which is derived # from the specified source (DTS) file: .dts -> .dtb # fdt_dtb_file optional fdt fdt_dtb_static \ compile-with "sh -c 'MACHINE=${MACHINE} $S/tools/fdt/make_dtb.sh $S ${FDT_DTS_FILE} ${.CURDIR}'" \ no-obj no-implicit-rule before-depend \ clean "${FDT_DTS_FILE:R}.dtb" fdt_static_dtb.h optional fdt fdt_dtb_static \ compile-with "sh -c 'MACHINE=${MACHINE} $S/tools/fdt/make_dtbh.sh ${FDT_DTS_FILE} ${.CURDIR}'" \ dependency "fdt_dtb_file" \ no-obj no-implicit-rule before-depend \ clean "fdt_static_dtb.h" feeder_eq_gen.h optional sound \ dependency "$S/tools/sound/feeder_eq_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_eq_mkfilter.awk -- ${FEEDER_EQ_PRESETS} > feeder_eq_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_eq_gen.h" feeder_rate_gen.h optional sound \ dependency "$S/tools/sound/feeder_rate_mkfilter.awk" \ compile-with "${AWK} -f $S/tools/sound/feeder_rate_mkfilter.awk -- ${FEEDER_RATE_PRESETS} > feeder_rate_gen.h" \ no-obj no-implicit-rule before-depend \ clean "feeder_rate_gen.h" snd_fxdiv_gen.h optional sound \ dependency "$S/tools/sound/snd_fxdiv_gen.awk" \ compile-with "${AWK} -f $S/tools/sound/snd_fxdiv_gen.awk -- > snd_fxdiv_gen.h" \ no-obj no-implicit-rule before-depend \ clean "snd_fxdiv_gen.h" miidevs.h optional miibus | mii \ dependency "$S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ compile-with "${AWK} -f $S/tools/miidevs2h.awk $S/dev/mii/miidevs" \ no-obj no-implicit-rule before-depend \ clean "miidevs.h" pccarddevs.h standard \ dependency "$S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \ compile-with "${AWK} -f $S/tools/pccarddevs2h.awk $S/dev/pccard/pccarddevs" \ no-obj no-implicit-rule before-depend \ clean "pccarddevs.h" kbdmuxmap.h optional kbdmux_dflt_keymap \ compile-with "kbdcontrol -P ${S:S/sys$/share/}/vt/keymaps -P ${S:S/sys$/share/}/syscons/keymaps -L ${KBDMUX_DFLT_KEYMAP} | sed -e 's/^static keymap_t.* = /static keymap_t key_map = /' -e 's/^static accentmap_t.* = /static accentmap_t accent_map = /' > kbdmuxmap.h" \ no-obj no-implicit-rule before-depend \ clean "kbdmuxmap.h" teken_state.h optional sc | vt \ dependency "$S/teken/gensequences $S/teken/sequences" \ compile-with "${AWK} -f $S/teken/gensequences $S/teken/sequences > teken_state.h" \ no-obj no-implicit-rule before-depend \ clean "teken_state.h" usbdevs.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -h" \ no-obj no-implicit-rule before-depend \ clean "usbdevs.h" usbdevs_data.h optional usb \ dependency "$S/tools/usbdevs2h.awk $S/dev/usb/usbdevs" \ compile-with "${AWK} -f $S/tools/usbdevs2h.awk $S/dev/usb/usbdevs -d" \ no-obj no-implicit-rule before-depend \ clean "usbdevs_data.h" cam/cam.c optional scbus cam/cam_compat.c optional scbus cam/cam_iosched.c optional scbus cam/cam_periph.c optional scbus cam/cam_queue.c optional scbus cam/cam_sim.c optional scbus cam/cam_xpt.c optional scbus cam/ata/ata_all.c optional scbus cam/ata/ata_xpt.c optional scbus cam/ata/ata_pmp.c optional scbus cam/nvme/nvme_all.c optional scbus nvme !nvd cam/nvme/nvme_da.c optional scbus nvme da !nvd cam/nvme/nvme_xpt.c optional scbus nvme !nvd cam/scsi/scsi_xpt.c optional scbus cam/scsi/scsi_all.c optional scbus cam/scsi/scsi_cd.c optional cd cam/scsi/scsi_ch.c optional ch cam/ata/ata_da.c optional ada | da cam/ctl/ctl.c optional ctl cam/ctl/ctl_backend.c optional ctl cam/ctl/ctl_backend_block.c optional ctl cam/ctl/ctl_backend_ramdisk.c optional ctl cam/ctl/ctl_cmd_table.c optional ctl cam/ctl/ctl_frontend.c optional ctl cam/ctl/ctl_frontend_cam_sim.c optional ctl cam/ctl/ctl_frontend_ioctl.c optional ctl cam/ctl/ctl_frontend_iscsi.c optional ctl cam/ctl/ctl_ha.c optional ctl cam/ctl/ctl_scsi_all.c optional ctl cam/ctl/ctl_tpc.c optional ctl cam/ctl/ctl_tpc_local.c optional ctl cam/ctl/ctl_error.c optional ctl cam/ctl/ctl_util.c optional ctl cam/ctl/scsi_ctl.c optional ctl cam/scsi/scsi_da.c optional da cam/scsi/scsi_low.c optional ct | ncv | nsp | stg cam/scsi/scsi_pass.c optional pass cam/scsi/scsi_pt.c optional pt cam/scsi/scsi_sa.c optional sa cam/scsi/scsi_enc.c optional ses cam/scsi/scsi_enc_ses.c optional ses cam/scsi/scsi_enc_safte.c optional ses cam/scsi/scsi_sg.c optional sg cam/scsi/scsi_targ_bh.c optional targbh cam/scsi/scsi_target.c optional targ cam/scsi/smp_all.c optional scbus # shared between zfs and dtrace cddl/compat/opensolaris/kern/opensolaris.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_cmn_err.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_kmem.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_misc.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_proc.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_sunddi.c optional zfs | dtrace compile-with "${CDDL_C}" cddl/compat/opensolaris/kern/opensolaris_taskq.c optional zfs | dtrace compile-with "${CDDL_C}" # zfs specific cddl/compat/opensolaris/kern/opensolaris_acl.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_dtrace.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_kobj.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_kstat.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_lookup.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_policy.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_string.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_sysevent.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_uio.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_vfs.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_vm.c optional zfs compile-with "${ZFS_C}" cddl/compat/opensolaris/kern/opensolaris_zone.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/acl/acl_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/avl/avl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_fnvpair.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/nvpair/opensolaris_nvpair_alloc_fixed.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/unicode/u8_textprep.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfeature_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_comutil.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_deleg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_fletcher.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_ioctl_compat.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_namecheck.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zfs_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zpool_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/common/zfs/zprop_common.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/gfs.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/vnode.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/blkptr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bplist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bpobj.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bptree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/bqueue.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dbuf.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/ddt.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/ddt_zap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_diff.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_object.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_objset.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_send.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_traverse.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_tx.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dmu_zfetch.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dnode.c optional zfs compile-with "${ZFS_C}" \ warning "kernel contains CDDL licensed ZFS filesystem" cddl/contrib/opensolaris/uts/common/fs/zfs/dnode_sync.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_bookmark.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dataset.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deadlist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_deleg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_destroy.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_dir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_prop.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_scan.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_userhold.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_synctask.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/gzip.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lz4.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/lzjb.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/metaslab.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/multilist.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/range_tree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/refcount.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/rrwlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/sa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/sha256.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/skein_zfs.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_config.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_errlog.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_history.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/spa_misc.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/space_map.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/space_reftree.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/trim_map.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/txg.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/uberblock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/unique.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_cache.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_file.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_label.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_mirror.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_missing.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_raidz.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_root.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_leaf.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zap_micro.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfeature.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_byteswap.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_debug.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_fuid.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_log.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_onexit.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_replay.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_rlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_sa.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_checksum.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_compress.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zio_inject.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zle.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zrlock.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/fs/zfs/zvol.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/callb.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/fm.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/list.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/os/nvpair_alloc_system.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/adler32.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/deflate.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inffast.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inflate.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/inftrees.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/trees.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zmod_subr.c optional zfs compile-with "${ZFS_C}" cddl/contrib/opensolaris/uts/common/zmod/zutil.c optional zfs compile-with "${ZFS_C}" # dtrace specific cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c optional dtrace compile-with "${DTRACE_C}" \ warning "kernel contains CDDL licensed DTRACE" cddl/dev/dtmalloc/dtmalloc.c optional dtmalloc | dtraceall compile-with "${CDDL_C}" cddl/dev/profile/profile.c optional dtrace_profile | dtraceall compile-with "${CDDL_C}" cddl/dev/sdt/sdt.c optional dtrace_sdt | dtraceall compile-with "${CDDL_C}" cddl/dev/fbt/fbt.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" cddl/dev/systrace/systrace.c optional dtrace_systrace | dtraceall compile-with "${CDDL_C}" cddl/dev/prototype.c optional dtrace_prototype | dtraceall compile-with "${CDDL_C}" fs/nfsclient/nfs_clkdtrace.c optional dtnfscl nfscl | dtraceall nfscl compile-with "${CDDL_C}" compat/cloudabi/cloudabi_clock.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_errno.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_fd.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_file.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_futex.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_mem.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_proc.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_random.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_sock.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_thread.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi/cloudabi_vdso.c optional compat_cloudabi32 | compat_cloudabi64 compat/cloudabi32/cloudabi32_fd.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_module.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_poll.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_sock.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_syscalls.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_sysent.c optional compat_cloudabi32 compat/cloudabi32/cloudabi32_thread.c optional compat_cloudabi32 compat/cloudabi64/cloudabi64_fd.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_module.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_poll.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_sock.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_syscalls.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_sysent.c optional compat_cloudabi64 compat/cloudabi64/cloudabi64_thread.c optional compat_cloudabi64 compat/freebsd32/freebsd32_capability.c optional compat_freebsd32 compat/freebsd32/freebsd32_ioctl.c optional compat_freebsd32 compat/freebsd32/freebsd32_misc.c optional compat_freebsd32 compat/freebsd32/freebsd32_syscalls.c optional compat_freebsd32 compat/freebsd32/freebsd32_sysent.c optional compat_freebsd32 contrib/ck/src/ck_array.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_centralized.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_combining.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_dissemination.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_mcs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_barrier_tournament.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_epoch.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hp.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_hs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_ht.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/ck/src/ck_rhs.c standard compile-with "${NORMAL_C} -I$S/contrib/ck/include" contrib/dev/acpica/common/ahids.c optional acpi acpi_debug contrib/dev/acpica/common/ahuuids.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbcmds.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbconvert.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbdisply.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbexec.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbhistry.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbinput.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbmethod.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbnames.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbobject.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbstats.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbtest.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbutils.c optional acpi acpi_debug contrib/dev/acpica/components/debugger/dbxface.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmbuffer.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmcstyle.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmdeferred.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmnames.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmopcode.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrc.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcl2.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmresrcs.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmutils.c optional acpi acpi_debug contrib/dev/acpica/components/disassembler/dmwalk.c optional acpi acpi_debug contrib/dev/acpica/components/dispatcher/dsargs.c optional acpi contrib/dev/acpica/components/dispatcher/dscontrol.c optional acpi contrib/dev/acpica/components/dispatcher/dsdebug.c optional acpi contrib/dev/acpica/components/dispatcher/dsfield.c optional acpi contrib/dev/acpica/components/dispatcher/dsinit.c optional acpi contrib/dev/acpica/components/dispatcher/dsmethod.c optional acpi contrib/dev/acpica/components/dispatcher/dsmthdat.c optional acpi contrib/dev/acpica/components/dispatcher/dsobject.c optional acpi contrib/dev/acpica/components/dispatcher/dsopcode.c optional acpi contrib/dev/acpica/components/dispatcher/dsutils.c optional acpi contrib/dev/acpica/components/dispatcher/dswexec.c optional acpi contrib/dev/acpica/components/dispatcher/dswload.c optional acpi contrib/dev/acpica/components/dispatcher/dswload2.c optional acpi contrib/dev/acpica/components/dispatcher/dswscope.c optional acpi contrib/dev/acpica/components/dispatcher/dswstate.c optional acpi contrib/dev/acpica/components/events/evevent.c optional acpi contrib/dev/acpica/components/events/evglock.c optional acpi contrib/dev/acpica/components/events/evgpe.c optional acpi contrib/dev/acpica/components/events/evgpeblk.c optional acpi contrib/dev/acpica/components/events/evgpeinit.c optional acpi contrib/dev/acpica/components/events/evgpeutil.c optional acpi contrib/dev/acpica/components/events/evhandler.c optional acpi contrib/dev/acpica/components/events/evmisc.c optional acpi contrib/dev/acpica/components/events/evregion.c optional acpi contrib/dev/acpica/components/events/evrgnini.c optional acpi contrib/dev/acpica/components/events/evsci.c optional acpi contrib/dev/acpica/components/events/evxface.c optional acpi contrib/dev/acpica/components/events/evxfevnt.c optional acpi contrib/dev/acpica/components/events/evxfgpe.c optional acpi contrib/dev/acpica/components/events/evxfregn.c optional acpi contrib/dev/acpica/components/executer/exconcat.c optional acpi contrib/dev/acpica/components/executer/exconfig.c optional acpi contrib/dev/acpica/components/executer/exconvrt.c optional acpi contrib/dev/acpica/components/executer/excreate.c optional acpi contrib/dev/acpica/components/executer/exdebug.c optional acpi contrib/dev/acpica/components/executer/exdump.c optional acpi contrib/dev/acpica/components/executer/exfield.c optional acpi contrib/dev/acpica/components/executer/exfldio.c optional acpi contrib/dev/acpica/components/executer/exmisc.c optional acpi contrib/dev/acpica/components/executer/exmutex.c optional acpi contrib/dev/acpica/components/executer/exnames.c optional acpi contrib/dev/acpica/components/executer/exoparg1.c optional acpi contrib/dev/acpica/components/executer/exoparg2.c optional acpi contrib/dev/acpica/components/executer/exoparg3.c optional acpi contrib/dev/acpica/components/executer/exoparg6.c optional acpi contrib/dev/acpica/components/executer/exprep.c optional acpi contrib/dev/acpica/components/executer/exregion.c optional acpi contrib/dev/acpica/components/executer/exresnte.c optional acpi contrib/dev/acpica/components/executer/exresolv.c optional acpi contrib/dev/acpica/components/executer/exresop.c optional acpi contrib/dev/acpica/components/executer/exstore.c optional acpi contrib/dev/acpica/components/executer/exstoren.c optional acpi contrib/dev/acpica/components/executer/exstorob.c optional acpi contrib/dev/acpica/components/executer/exsystem.c optional acpi contrib/dev/acpica/components/executer/extrace.c optional acpi contrib/dev/acpica/components/executer/exutils.c optional acpi contrib/dev/acpica/components/hardware/hwacpi.c optional acpi contrib/dev/acpica/components/hardware/hwesleep.c optional acpi contrib/dev/acpica/components/hardware/hwgpe.c optional acpi contrib/dev/acpica/components/hardware/hwpci.c optional acpi contrib/dev/acpica/components/hardware/hwregs.c optional acpi contrib/dev/acpica/components/hardware/hwsleep.c optional acpi contrib/dev/acpica/components/hardware/hwtimer.c optional acpi contrib/dev/acpica/components/hardware/hwvalid.c optional acpi contrib/dev/acpica/components/hardware/hwxface.c optional acpi contrib/dev/acpica/components/hardware/hwxfsleep.c optional acpi contrib/dev/acpica/components/namespace/nsaccess.c optional acpi contrib/dev/acpica/components/namespace/nsalloc.c optional acpi contrib/dev/acpica/components/namespace/nsarguments.c optional acpi contrib/dev/acpica/components/namespace/nsconvert.c optional acpi contrib/dev/acpica/components/namespace/nsdump.c optional acpi contrib/dev/acpica/components/namespace/nseval.c optional acpi contrib/dev/acpica/components/namespace/nsinit.c optional acpi contrib/dev/acpica/components/namespace/nsload.c optional acpi contrib/dev/acpica/components/namespace/nsnames.c optional acpi contrib/dev/acpica/components/namespace/nsobject.c optional acpi contrib/dev/acpica/components/namespace/nsparse.c optional acpi contrib/dev/acpica/components/namespace/nspredef.c optional acpi contrib/dev/acpica/components/namespace/nsprepkg.c optional acpi contrib/dev/acpica/components/namespace/nsrepair.c optional acpi contrib/dev/acpica/components/namespace/nsrepair2.c optional acpi contrib/dev/acpica/components/namespace/nssearch.c optional acpi contrib/dev/acpica/components/namespace/nsutils.c optional acpi contrib/dev/acpica/components/namespace/nswalk.c optional acpi contrib/dev/acpica/components/namespace/nsxfeval.c optional acpi contrib/dev/acpica/components/namespace/nsxfname.c optional acpi contrib/dev/acpica/components/namespace/nsxfobj.c optional acpi contrib/dev/acpica/components/parser/psargs.c optional acpi contrib/dev/acpica/components/parser/psloop.c optional acpi contrib/dev/acpica/components/parser/psobject.c optional acpi contrib/dev/acpica/components/parser/psopcode.c optional acpi contrib/dev/acpica/components/parser/psopinfo.c optional acpi contrib/dev/acpica/components/parser/psparse.c optional acpi contrib/dev/acpica/components/parser/psscope.c optional acpi contrib/dev/acpica/components/parser/pstree.c optional acpi contrib/dev/acpica/components/parser/psutils.c optional acpi contrib/dev/acpica/components/parser/pswalk.c optional acpi contrib/dev/acpica/components/parser/psxface.c optional acpi contrib/dev/acpica/components/resources/rsaddr.c optional acpi contrib/dev/acpica/components/resources/rscalc.c optional acpi contrib/dev/acpica/components/resources/rscreate.c optional acpi contrib/dev/acpica/components/resources/rsdump.c optional acpi acpi_debug contrib/dev/acpica/components/resources/rsdumpinfo.c optional acpi contrib/dev/acpica/components/resources/rsinfo.c optional acpi contrib/dev/acpica/components/resources/rsio.c optional acpi contrib/dev/acpica/components/resources/rsirq.c optional acpi contrib/dev/acpica/components/resources/rslist.c optional acpi contrib/dev/acpica/components/resources/rsmemory.c optional acpi contrib/dev/acpica/components/resources/rsmisc.c optional acpi contrib/dev/acpica/components/resources/rsserial.c optional acpi contrib/dev/acpica/components/resources/rsutils.c optional acpi contrib/dev/acpica/components/resources/rsxface.c optional acpi contrib/dev/acpica/components/tables/tbdata.c optional acpi contrib/dev/acpica/components/tables/tbfadt.c optional acpi contrib/dev/acpica/components/tables/tbfind.c optional acpi contrib/dev/acpica/components/tables/tbinstal.c optional acpi contrib/dev/acpica/components/tables/tbprint.c optional acpi contrib/dev/acpica/components/tables/tbutils.c optional acpi contrib/dev/acpica/components/tables/tbxface.c optional acpi contrib/dev/acpica/components/tables/tbxfload.c optional acpi contrib/dev/acpica/components/tables/tbxfroot.c optional acpi contrib/dev/acpica/components/utilities/utaddress.c optional acpi contrib/dev/acpica/components/utilities/utalloc.c optional acpi contrib/dev/acpica/components/utilities/utascii.c optional acpi contrib/dev/acpica/components/utilities/utbuffer.c optional acpi contrib/dev/acpica/components/utilities/utcache.c optional acpi contrib/dev/acpica/components/utilities/utcopy.c optional acpi contrib/dev/acpica/components/utilities/utdebug.c optional acpi contrib/dev/acpica/components/utilities/utdecode.c optional acpi contrib/dev/acpica/components/utilities/utdelete.c optional acpi contrib/dev/acpica/components/utilities/uterror.c optional acpi contrib/dev/acpica/components/utilities/uteval.c optional acpi contrib/dev/acpica/components/utilities/utexcep.c optional acpi contrib/dev/acpica/components/utilities/utglobal.c optional acpi contrib/dev/acpica/components/utilities/uthex.c optional acpi contrib/dev/acpica/components/utilities/utids.c optional acpi contrib/dev/acpica/components/utilities/utinit.c optional acpi contrib/dev/acpica/components/utilities/utlock.c optional acpi contrib/dev/acpica/components/utilities/utmath.c optional acpi contrib/dev/acpica/components/utilities/utmisc.c optional acpi contrib/dev/acpica/components/utilities/utmutex.c optional acpi contrib/dev/acpica/components/utilities/utnonansi.c optional acpi contrib/dev/acpica/components/utilities/utobject.c optional acpi contrib/dev/acpica/components/utilities/utosi.c optional acpi contrib/dev/acpica/components/utilities/utownerid.c optional acpi contrib/dev/acpica/components/utilities/utpredef.c optional acpi contrib/dev/acpica/components/utilities/utresrc.c optional acpi contrib/dev/acpica/components/utilities/utstate.c optional acpi contrib/dev/acpica/components/utilities/utstring.c optional acpi contrib/dev/acpica/components/utilities/utstrtoul64.c optional acpi contrib/dev/acpica/components/utilities/utuuid.c optional acpi acpi_debug contrib/dev/acpica/components/utilities/utxface.c optional acpi contrib/dev/acpica/components/utilities/utxferror.c optional acpi contrib/dev/acpica/components/utilities/utxfinit.c optional acpi #contrib/dev/acpica/components/utilities/utxfmutex.c optional acpi contrib/ipfilter/netinet/fil.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_auth.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_fil_freebsd.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_frag.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_log.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_nat.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_proxy.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_state.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_lookup.c optional ipfilter inet \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN} -Wno-unused -Wno-error -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_pool.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_htable.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_sync.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/mlfk_ipl.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_nat6.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_rules.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_scan.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/ip_dstlist.c optional ipfilter inet \ compile-with "${NORMAL_C} -Wno-unused -I$S/contrib/ipfilter" contrib/ipfilter/netinet/radix_ipf.c optional ipfilter inet \ compile-with "${NORMAL_C} -I$S/contrib/ipfilter" contrib/libfdt/fdt.c optional fdt contrib/libfdt/fdt_ro.c optional fdt contrib/libfdt/fdt_rw.c optional fdt contrib/libfdt/fdt_strerror.c optional fdt contrib/libfdt/fdt_sw.c optional fdt contrib/libfdt/fdt_wip.c optional fdt contrib/libnv/cnvlist.c standard contrib/libnv/dnvlist.c standard contrib/libnv/nvlist.c standard contrib/libnv/nvpair.c standard contrib/ngatm/netnatm/api/cc_conn.c optional ngatm_ccatm \ compile-with "${NORMAL_C_NOWERROR} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_data.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_dump.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_port.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_sig.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/cc_user.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/api/unisap.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/straddr.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/misc/unimsg_common.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/traffic.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_ie.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/msg/uni_msg.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/saal/saal_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_call.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_coord.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_party.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_print.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_reset.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_unimsgcpy.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" contrib/ngatm/netnatm/sig/sig_verify.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" crypto/blowfish/bf_ecb.c optional ipsec crypto/blowfish/bf_skey.c optional crypto | ipsec crypto/camellia/camellia.c optional crypto | ipsec crypto/camellia/camellia-api.c optional crypto | ipsec crypto/des/des_ecb.c optional crypto | ipsec | netsmb crypto/des/des_setkey.c optional crypto | ipsec | netsmb crypto/rc4/rc4.c optional netgraph_mppc_encryption | kgssapi crypto/rijndael/rijndael-alg-fst.c optional crypto | ekcd | geom_bde | \ ipsec | random !random_loadable | wlan_ccmp crypto/rijndael/rijndael-api-fst.c optional ekcd | geom_bde | random !random_loadable crypto/rijndael/rijndael-api.c optional crypto | ipsec | wlan_ccmp crypto/sha1.c optional carp | crypto | ipsec | \ netgraph_mppc_encryption | sctp crypto/sha2/sha256c.c optional crypto | ekcd | geom_bde | ipsec | random !random_loadable | \ sctp | zfs crypto/sha2/sha512c.c optional crypto | geom_bde | ipsec | zfs crypto/skein/skein.c optional crypto | zfs crypto/skein/skein_block.c optional crypto | zfs crypto/siphash/siphash.c optional inet | inet6 crypto/siphash/siphash_test.c optional inet | inet6 ddb/db_access.c optional ddb ddb/db_break.c optional ddb ddb/db_capture.c optional ddb ddb/db_command.c optional ddb ddb/db_examine.c optional ddb ddb/db_expr.c optional ddb ddb/db_input.c optional ddb ddb/db_lex.c optional ddb ddb/db_main.c optional ddb ddb/db_output.c optional ddb ddb/db_print.c optional ddb ddb/db_ps.c optional ddb ddb/db_run.c optional ddb ddb/db_script.c optional ddb ddb/db_sym.c optional ddb ddb/db_thread.c optional ddb ddb/db_textdump.c optional ddb ddb/db_variables.c optional ddb ddb/db_watch.c optional ddb ddb/db_write_cmd.c optional ddb dev/aac/aac.c optional aac dev/aac/aac_cam.c optional aacp aac dev/aac/aac_debug.c optional aac dev/aac/aac_disk.c optional aac dev/aac/aac_linux.c optional aac compat_linux dev/aac/aac_pci.c optional aac pci dev/aacraid/aacraid.c optional aacraid dev/aacraid/aacraid_cam.c optional aacraid scbus dev/aacraid/aacraid_debug.c optional aacraid dev/aacraid/aacraid_linux.c optional aacraid compat_linux dev/aacraid/aacraid_pci.c optional aacraid pci dev/acpi_support/acpi_wmi.c optional acpi_wmi acpi dev/acpi_support/acpi_asus.c optional acpi_asus acpi dev/acpi_support/acpi_asus_wmi.c optional acpi_asus_wmi acpi dev/acpi_support/acpi_fujitsu.c optional acpi_fujitsu acpi dev/acpi_support/acpi_hp.c optional acpi_hp acpi dev/acpi_support/acpi_ibm.c optional acpi_ibm acpi dev/acpi_support/acpi_panasonic.c optional acpi_panasonic acpi dev/acpi_support/acpi_sony.c optional acpi_sony acpi dev/acpi_support/acpi_toshiba.c optional acpi_toshiba acpi dev/acpi_support/atk0110.c optional aibs acpi dev/acpica/Osd/OsdDebug.c optional acpi dev/acpica/Osd/OsdHardware.c optional acpi dev/acpica/Osd/OsdInterrupt.c optional acpi dev/acpica/Osd/OsdMemory.c optional acpi dev/acpica/Osd/OsdSchedule.c optional acpi dev/acpica/Osd/OsdStream.c optional acpi dev/acpica/Osd/OsdSynch.c optional acpi dev/acpica/Osd/OsdTable.c optional acpi dev/acpica/acpi.c optional acpi dev/acpica/acpi_acad.c optional acpi dev/acpica/acpi_battery.c optional acpi dev/acpica/acpi_button.c optional acpi dev/acpica/acpi_cmbat.c optional acpi dev/acpica/acpi_cpu.c optional acpi dev/acpica/acpi_ec.c optional acpi dev/acpica/acpi_isab.c optional acpi isa dev/acpica/acpi_lid.c optional acpi dev/acpica/acpi_package.c optional acpi dev/acpica/acpi_pci.c optional acpi pci dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/acpica/acpi_pcib_acpi.c optional acpi pci dev/acpica/acpi_pcib_pci.c optional acpi pci dev/acpica/acpi_perf.c optional acpi dev/acpica/acpi_powerres.c optional acpi dev/acpica/acpi_quirk.c optional acpi dev/acpica/acpi_resource.c optional acpi dev/acpica/acpi_smbat.c optional acpi dev/acpica/acpi_thermal.c optional acpi dev/acpica/acpi_throttle.c optional acpi dev/acpica/acpi_video.c optional acpi_video acpi dev/acpica/acpi_dock.c optional acpi_dock acpi dev/adlink/adlink.c optional adlink dev/advansys/adv_eisa.c optional adv eisa dev/advansys/adv_pci.c optional adv pci dev/advansys/advansys.c optional adv dev/advansys/advlib.c optional adv dev/advansys/advmcode.c optional adv dev/advansys/adw_pci.c optional adw pci dev/advansys/adwcam.c optional adw dev/advansys/adwlib.c optional adw dev/advansys/adwmcode.c optional adw dev/ae/if_ae.c optional ae pci dev/age/if_age.c optional age pci dev/agp/agp.c optional agp pci dev/agp/agp_if.m optional agp pci dev/aha/aha.c optional aha dev/aha/aha_isa.c optional aha isa dev/aha/aha_mca.c optional aha mca dev/ahb/ahb.c optional ahb eisa dev/ahci/ahci.c optional ahci dev/ahci/ahciem.c optional ahci dev/ahci/ahci_pci.c optional ahci pci dev/aic/aic.c optional aic dev/aic/aic_pccard.c optional aic pccard dev/aic7xxx/ahc_eisa.c optional ahc eisa dev/aic7xxx/ahc_isa.c optional ahc isa dev/aic7xxx/ahc_pci.c optional ahc pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/ahd_pci.c optional ahd pci \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/aic7xxx/aic7770.c optional ahc dev/aic7xxx/aic79xx.c optional ahd pci dev/aic7xxx/aic79xx_osm.c optional ahd pci dev/aic7xxx/aic79xx_pci.c optional ahd pci dev/aic7xxx/aic79xx_reg_print.c optional ahd pci ahd_reg_pretty_print dev/aic7xxx/aic7xxx.c optional ahc dev/aic7xxx/aic7xxx_93cx6.c optional ahc dev/aic7xxx/aic7xxx_osm.c optional ahc dev/aic7xxx/aic7xxx_pci.c optional ahc pci dev/aic7xxx/aic7xxx_reg_print.c optional ahc ahc_reg_pretty_print dev/al_eth/al_eth.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/al_eth/al_init_eth_lm.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/al_eth/al_init_eth_kr.c optional al_eth fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_iofic.c optional al_iofic \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_25g.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_serdes_hssp.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_config.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_debug.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_iofic.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_hal_udma_main.c optional al_udma \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/al_serdes.c optional al_serdes \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_kr.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" contrib/alpine-hal/eth/al_hal_eth_main.c optional al_eth \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${PROF} ${.IMPSRC}" dev/alc/if_alc.c optional alc pci dev/ale/if_ale.c optional ale pci dev/alpm/alpm.c optional alpm pci dev/altera/avgen/altera_avgen.c optional altera_avgen dev/altera/avgen/altera_avgen_fdt.c optional altera_avgen fdt dev/altera/avgen/altera_avgen_nexus.c optional altera_avgen dev/altera/sdcard/altera_sdcard.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_disk.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_io.c optional altera_sdcard dev/altera/sdcard/altera_sdcard_fdt.c optional altera_sdcard fdt dev/altera/sdcard/altera_sdcard_nexus.c optional altera_sdcard dev/altera/pio/pio.c optional altera_pio dev/altera/pio/pio_if.m optional altera_pio dev/amdpm/amdpm.c optional amdpm pci | nfpm pci dev/amdsmb/amdsmb.c optional amdsmb pci dev/amr/amr.c optional amr dev/amr/amr_cam.c optional amrp amr dev/amr/amr_disk.c optional amr dev/amr/amr_linux.c optional amr compat_linux dev/amr/amr_pci.c optional amr pci dev/an/if_an.c optional an dev/an/if_an_isa.c optional an isa dev/an/if_an_pccard.c optional an pccard dev/an/if_an_pci.c optional an pci # dev/ata/ata_if.m optional ata | atacore dev/ata/ata-all.c optional ata | atacore dev/ata/ata-dma.c optional ata | atacore dev/ata/ata-lowlevel.c optional ata | atacore dev/ata/ata-sata.c optional ata | atacore dev/ata/ata-card.c optional ata pccard | atapccard dev/ata/ata-cbus.c optional ata pc98 | atapc98 dev/ata/ata-isa.c optional ata isa | ataisa dev/ata/ata-pci.c optional ata pci | atapci dev/ata/chipsets/ata-acard.c optional ata pci | ataacard dev/ata/chipsets/ata-acerlabs.c optional ata pci | ataacerlabs dev/ata/chipsets/ata-amd.c optional ata pci | ataamd dev/ata/chipsets/ata-ati.c optional ata pci | ataati dev/ata/chipsets/ata-cenatek.c optional ata pci | atacenatek dev/ata/chipsets/ata-cypress.c optional ata pci | atacypress dev/ata/chipsets/ata-cyrix.c optional ata pci | atacyrix dev/ata/chipsets/ata-highpoint.c optional ata pci | atahighpoint dev/ata/chipsets/ata-intel.c optional ata pci | ataintel dev/ata/chipsets/ata-ite.c optional ata pci | ataite dev/ata/chipsets/ata-jmicron.c optional ata pci | atajmicron dev/ata/chipsets/ata-marvell.c optional ata pci | atamarvell dev/ata/chipsets/ata-micron.c optional ata pci | atamicron dev/ata/chipsets/ata-national.c optional ata pci | atanational dev/ata/chipsets/ata-netcell.c optional ata pci | atanetcell dev/ata/chipsets/ata-nvidia.c optional ata pci | atanvidia dev/ata/chipsets/ata-promise.c optional ata pci | atapromise dev/ata/chipsets/ata-serverworks.c optional ata pci | ataserverworks dev/ata/chipsets/ata-siliconimage.c optional ata pci | atasiliconimage | ataati dev/ata/chipsets/ata-sis.c optional ata pci | atasis dev/ata/chipsets/ata-via.c optional ata pci | atavia # dev/ath/if_ath_pci.c optional ath_pci pci \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/if_ath_ahb.c optional ath_ahb \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/if_ath.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_alq.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_beacon.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_btcoex.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_btcoex_mci.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_debug.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_descdma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_keycache.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_ioctl.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_led.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_lna_div.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx_edma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tx_ht.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_tdma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_sysctl.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_rx.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_rx_edma.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/if_ath_spectral.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ah_osdep.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/ath/ath_hal/ah.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v1.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v3.c optional ath_hal | ath_ar5211 | ath_ar5212 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v14.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_v4k.c \ optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_eeprom_9287.c \ optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_hal/ah_regdomain.c optional ath \ compile-with "${NORMAL_C} ${NO_WSHIFT_COUNT_NEGATIVE} ${NO_WSHIFT_COUNT_OVERFLOW} -I$S/dev/ath" # ar5210 dev/ath/ath_hal/ar5210/ar5210_attach.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_beacon.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_interrupts.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_keycache.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_misc.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_phy.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_power.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_recv.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_reset.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5210/ar5210_xmit.c optional ath_hal | ath_ar5210 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5211 dev/ath/ath_hal/ar5211/ar5211_attach.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_beacon.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_interrupts.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_keycache.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_misc.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_phy.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_power.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_recv.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_reset.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5211/ar5211_xmit.c optional ath_hal | ath_ar5211 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5212 dev/ath/ath_hal/ar5212/ar5212_ani.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_attach.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_beacon.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_eeprom.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_gpio.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_interrupts.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_keycache.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_misc.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_phy.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_power.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_recv.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_reset.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_rfgain.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5212_xmit.c \ optional ath_hal | ath_ar5212 | ath_ar5416 | ath_ar9160 | ath_ar9280 | \ ath_ar9285 ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar5416 (depends on ar5212) dev/ath/ath_hal/ar5416/ar5416_ani.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_attach.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_beacon.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_btcoex.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_iq.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcgain.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_cal_adcdc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_eeprom.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_gpio.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_interrupts.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_keycache.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_misc.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_phy.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_power.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_radar.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_recv.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_reset.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_spectral.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar5416_xmit.c \ optional ath_hal | ath_ar5416 | ath_ar9160 | ath_ar9280 | ath_ar9285 | \ ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9130 (depends upon ar5416) - also requires AH_SUPPORT_AR9130 # # Since this is an embedded MAC SoC, there's no need to compile it into the # default HAL. dev/ath/ath_hal/ar9001/ar9130_attach.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_phy.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9001/ar9130_eeprom.c optional ath_ar9130 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9160 (depends on ar5416) dev/ath/ath_hal/ar9001/ar9160_attach.c optional ath_hal | ath_ar9160 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9280 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9280_attach.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280_olc.c optional ath_hal | ath_ar9280 | \ ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9285 (depends on ar5416 and ar9280) dev/ath/ath_hal/ar9002/ar9285_attach.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_btcoex.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_reset.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_cal.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_phy.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285_diversity.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9287 (depends on ar5416) dev/ath/ath_hal/ar9002/ar9287_attach.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_reset.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_cal.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287_olc.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ar9300 contrib/dev/ath/ath_hal/ar9300/ar9300_ani.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_attach.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_beacon.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WCONSTANT_CONVERSION}" contrib/dev/ath/ath_hal/ar9300/ar9300_freebsd.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_gpio.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_interrupts.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_keycache.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_mci.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_misc.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_paprd.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_phy.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_power.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radar.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_radio.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_recv_ds.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_reset.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal ${NO_WSOMETIMES_UNINITIALIZED} -Wno-unused-function" contrib/dev/ath/ath_hal/ar9300/ar9300_stub.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_stub_funcs.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_spectral.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_timer.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" contrib/dev/ath/ath_hal/ar9300/ar9300_xmit_ds.c optional ath_hal | ath_ar9300 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal -I$S/contrib/dev/ath/ath_hal" # rf backends dev/ath/ath_hal/ar5212/ar2316.c optional ath_rf2316 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2317.c optional ath_rf2317 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2413.c optional ath_hal | ath_rf2413 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar2425.c optional ath_hal | ath_rf2425 | ath_rf2417 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5111.c optional ath_hal | ath_rf5111 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5112.c optional ath_hal | ath_rf5112 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5212/ar5413.c optional ath_hal | ath_rf5413 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar5416/ar2133.c optional ath_hal | ath_ar5416 | \ ath_ar9130 | ath_ar9160 | ath_ar9280 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9280.c optional ath_hal | ath_ar9280 | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9285.c optional ath_hal | ath_ar9285 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" dev/ath/ath_hal/ar9002/ar9287.c optional ath_hal | ath_ar9287 \ compile-with "${NORMAL_C} -I$S/dev/ath -I$S/dev/ath/ath_hal" # ath rate control algorithms dev/ath/ath_rate/amrr/amrr.c optional ath_rate_amrr \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_rate/onoe/onoe.c optional ath_rate_onoe \ compile-with "${NORMAL_C} -I$S/dev/ath" dev/ath/ath_rate/sample/sample.c optional ath_rate_sample \ compile-with "${NORMAL_C} -I$S/dev/ath" # ath DFS modules dev/ath/ath_dfs/null/dfs_null.c optional ath \ compile-with "${NORMAL_C} -I$S/dev/ath" # dev/bce/if_bce.c optional bce dev/bfe/if_bfe.c optional bfe dev/bge/if_bge.c optional bge dev/bhnd/bhnd.c optional bhnd dev/bhnd/bhnd_erom.c optional bhnd dev/bhnd/bhnd_erom_if.m optional bhnd dev/bhnd/bhnd_nexus.c optional bhnd siba_nexus | \ bhnd bcma_nexus dev/bhnd/bhnd_subr.c optional bhnd dev/bhnd/bhnd_bus_if.m optional bhnd dev/bhnd/bhndb/bhnd_bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_bus_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_hwdata.c optional bhndb bhnd dev/bhnd/bhndb/bhndb_if.m optional bhndb bhnd dev/bhnd/bhndb/bhndb_pci.c optional bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_hwdata.c optional bhndb bhnd pci dev/bhnd/bhndb/bhndb_pci_sprom.c optional bhndb bhnd pci dev/bhnd/bhndb/bhndb_subr.c optional bhndb bhnd dev/bhnd/bcma/bcma.c optional bcma bhnd dev/bhnd/bcma/bcma_bhndb.c optional bcma bhnd bhndb dev/bhnd/bcma/bcma_erom.c optional bcma bhnd dev/bhnd/bcma/bcma_nexus.c optional bcma_nexus bcma bhnd dev/bhnd/bcma/bcma_subr.c optional bcma bhnd dev/bhnd/cores/chipc/bhnd_chipc_if.m optional bhnd dev/bhnd/cores/chipc/bhnd_sprom_chipc.c optional bhnd dev/bhnd/cores/chipc/bhnd_pmu_chipc.c optional bhnd dev/bhnd/cores/chipc/chipc.c optional bhnd dev/bhnd/cores/chipc/chipc_cfi.c optional bhnd cfi dev/bhnd/cores/chipc/chipc_slicer.c optional bhnd cfi | bhnd spibus dev/bhnd/cores/chipc/chipc_spi.c optional bhnd spibus dev/bhnd/cores/chipc/chipc_subr.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl.c optional bhnd dev/bhnd/cores/chipc/pwrctl/bhnd_pwrctl_subr.c optional bhnd dev/bhnd/cores/pci/bhnd_pci.c optional bhnd pci dev/bhnd/cores/pci/bhnd_pci_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pci/bhnd_pcib.c optional bhnd_pcib bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2.c optional bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2_hostb.c optional bhndb bhnd pci dev/bhnd/cores/pcie2/bhnd_pcie2b.c optional bhnd_pcie2b bhnd pci dev/bhnd/cores/pmu/bhnd_pmu.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_core.c optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_if.m optional bhnd dev/bhnd/cores/pmu/bhnd_pmu_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcm.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_btxt.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_sprom.c optional bhnd +dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_data_tlv.c optional bhnd dev/bhnd/nvram/bhnd_nvram_if.m optional bhnd dev/bhnd/nvram/bhnd_nvram_io.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iobuf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_ioptr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_iores.c optional bhnd dev/bhnd/nvram/bhnd_nvram_plist.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store.c optional bhnd dev/bhnd/nvram/bhnd_nvram_store_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_subr.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_fmts.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_prf.c optional bhnd dev/bhnd/nvram/bhnd_nvram_value_subr.c optional bhnd dev/bhnd/nvram/bhnd_sprom.c optional bhnd dev/bhnd/siba/siba.c optional siba bhnd dev/bhnd/siba/siba_bhndb.c optional siba bhnd bhndb dev/bhnd/siba/siba_erom.c optional siba bhnd dev/bhnd/siba/siba_nexus.c optional siba_nexus siba bhnd dev/bhnd/siba/siba_subr.c optional siba bhnd # dev/bktr/bktr_audio.c optional bktr pci dev/bktr/bktr_card.c optional bktr pci dev/bktr/bktr_core.c optional bktr pci dev/bktr/bktr_i2c.c optional bktr pci smbus dev/bktr/bktr_os.c optional bktr pci dev/bktr/bktr_tuner.c optional bktr pci dev/bktr/msp34xx.c optional bktr pci dev/bnxt/bnxt_hwrm.c optional bnxt iflib pci dev/bnxt/bnxt_sysctl.c optional bnxt iflib pci dev/bnxt/bnxt_txrx.c optional bnxt iflib pci dev/bnxt/if_bnxt.c optional bnxt iflib pci dev/buslogic/bt.c optional bt dev/buslogic/bt_eisa.c optional bt eisa dev/buslogic/bt_isa.c optional bt isa dev/buslogic/bt_mca.c optional bt mca dev/buslogic/bt_pci.c optional bt pci dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci # XXX Work around clang warnings, until maintainer approves fix. dev/bwn/if_bwn.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/bwn/if_bwn_pci.c optional bwn pci bhnd dev/bwn/if_bwn_phy_common.c optional bwn siba_bwn dev/bwn/if_bwn_phy_g.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED} ${NO_WCONSTANT_CONVERSION}" dev/bwn/if_bwn_phy_lp.c optional bwn siba_bwn \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/bwn/if_bwn_phy_n.c optional bwn siba_bwn dev/bwn/if_bwn_util.c optional bwn siba_bwn dev/bwn/bwn_mac.c optional bwn bhnd dev/cardbus/cardbus.c optional cardbus dev/cardbus/cardbus_cis.c optional cardbus dev/cardbus/cardbus_device.c optional cardbus dev/cas/if_cas.c optional cas dev/cfi/cfi_bus_fdt.c optional cfi fdt dev/cfi/cfi_bus_nexus.c optional cfi dev/cfi/cfi_core.c optional cfi dev/cfi/cfi_dev.c optional cfi dev/cfi/cfi_disk.c optional cfid dev/chromebook_platform/chromebook_platform.c optional chromebook_platform dev/ciss/ciss.c optional ciss dev/cm/smc90cx6.c optional cm dev/cmx/cmx.c optional cmx dev/cmx/cmx_pccard.c optional cmx pccard dev/cpufreq/ichss.c optional cpufreq pci dev/cs/if_cs.c optional cs dev/cs/if_cs_isa.c optional cs isa dev/cs/if_cs_pccard.c optional cs pccard dev/cxgb/cxgb_main.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_sge.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mc5.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc7323.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_vsc8211.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_ael1002.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_aq100x.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_mv88e1xxx.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_xgmac.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_t3_hw.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/common/cxgb_tn1010.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/sys/uipc_mvec.c optional cxgb pci \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgb/cxgb_t3fw.c optional cxgb cxgb_t3fw \ compile-with "${NORMAL_C} -I$S/dev/cxgb" dev/cxgbe/t4_if.m optional cxgbe pci dev/cxgbe/t4_iov.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_mp_ring.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_main.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_netmap.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_sge.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_l2t.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_tracer.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/t4_vf.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4_hw.c optional cxgbe pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" dev/cxgbe/common/t4vf_hw.c optional cxgbev pci \ compile-with "${NORMAL_C} -I$S/dev/cxgbe" t4fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t4fw_cfg.fw:t4fw_cfg t4fw_cfg_uwire.fw:t4fw_cfg_uwire t4fw.fw:t4fw -mt4fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t4fw_cfg.c" t4fw_cfg.fwo optional cxgbe \ dependency "t4fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg.fwo" t4fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg.fw" t4fw_cfg_uwire.fwo optional cxgbe \ dependency "t4fw_cfg_uwire.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw_cfg_uwire.fwo" t4fw_cfg_uwire.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw_cfg_uwire.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t4fw_cfg_uwire.fw" t4fw.fwo optional cxgbe \ dependency "t4fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t4fw.fwo" t4fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t4fw-1.16.22.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t4fw.fw" t5fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t5fw_cfg.fw:t5fw_cfg t5fw.fw:t5fw -mt5fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t5fw_cfg.c" t5fw_cfg.fwo optional cxgbe \ dependency "t5fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw_cfg.fwo" t5fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t5fw_cfg.fw" t5fw.fwo optional cxgbe \ dependency "t5fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t5fw.fwo" t5fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t5fw-1.16.22.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t5fw.fw" t6fw_cfg.c optional cxgbe \ compile-with "${AWK} -f $S/tools/fw_stub.awk t6fw_cfg.fw:t6fw_cfg t6fw.fw:t6fw -mt6fw_cfg -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "t6fw_cfg.c" t6fw_cfg.fwo optional cxgbe \ dependency "t6fw_cfg.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw_cfg.fwo" t6fw_cfg.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw_cfg.txt" \ compile-with "${CP} ${.ALLSRC} ${.TARGET}" \ no-obj no-implicit-rule \ clean "t6fw_cfg.fw" t6fw.fwo optional cxgbe \ dependency "t6fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "t6fw.fwo" t6fw.fw optional cxgbe \ dependency "$S/dev/cxgbe/firmware/t6fw-1.16.22.0.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "t6fw.fw" dev/cy/cy.c optional cy dev/cy/cy_isa.c optional cy isa dev/cy/cy_pci.c optional cy pci dev/cyapa/cyapa.c optional cyapa iicbus dev/dc/if_dc.c optional dc pci dev/dc/dcphy.c optional dc pci dev/dc/pnphy.c optional dc pci dev/dcons/dcons.c optional dcons dev/dcons/dcons_crom.c optional dcons_crom dev/dcons/dcons_os.c optional dcons dev/de/if_de.c optional de pci dev/dme/if_dme.c optional dme dev/dpt/dpt_eisa.c optional dpt eisa dev/dpt/dpt_pci.c optional dpt pci dev/dpt/dpt_scsi.c optional dpt dev/drm/ati_pcigart.c optional drm dev/drm/drm_agpsupport.c optional drm dev/drm/drm_auth.c optional drm dev/drm/drm_bufs.c optional drm dev/drm/drm_context.c optional drm dev/drm/drm_dma.c optional drm dev/drm/drm_drawable.c optional drm dev/drm/drm_drv.c optional drm dev/drm/drm_fops.c optional drm dev/drm/drm_hashtab.c optional drm dev/drm/drm_ioctl.c optional drm dev/drm/drm_irq.c optional drm dev/drm/drm_lock.c optional drm dev/drm/drm_memory.c optional drm dev/drm/drm_mm.c optional drm dev/drm/drm_pci.c optional drm dev/drm/drm_scatter.c optional drm dev/drm/drm_sman.c optional drm dev/drm/drm_sysctl.c optional drm dev/drm/drm_vm.c optional drm dev/drm/i915_dma.c optional i915drm dev/drm/i915_drv.c optional i915drm dev/drm/i915_irq.c optional i915drm dev/drm/i915_mem.c optional i915drm dev/drm/i915_suspend.c optional i915drm dev/drm/mach64_dma.c optional mach64drm dev/drm/mach64_drv.c optional mach64drm dev/drm/mach64_irq.c optional mach64drm dev/drm/mach64_state.c optional mach64drm dev/drm/mga_dma.c optional mgadrm dev/drm/mga_drv.c optional mgadrm dev/drm/mga_irq.c optional mgadrm dev/drm/mga_state.c optional mgadrm dev/drm/mga_warp.c optional mgadrm dev/drm/r128_cce.c optional r128drm \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/drm/r128_drv.c optional r128drm dev/drm/r128_irq.c optional r128drm dev/drm/r128_state.c optional r128drm dev/drm/r300_cmdbuf.c optional radeondrm dev/drm/r600_blit.c optional radeondrm dev/drm/r600_cp.c optional radeondrm \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/drm/radeon_cp.c optional radeondrm \ compile-with "${NORMAL_C} ${NO_WCONSTANT_CONVERSION}" dev/drm/radeon_cs.c optional radeondrm dev/drm/radeon_drv.c optional radeondrm dev/drm/radeon_irq.c optional radeondrm dev/drm/radeon_mem.c optional radeondrm dev/drm/radeon_state.c optional radeondrm dev/drm/savage_bci.c optional savagedrm dev/drm/savage_drv.c optional savagedrm dev/drm/savage_state.c optional savagedrm dev/drm/sis_drv.c optional sisdrm dev/drm/sis_ds.c optional sisdrm dev/drm/sis_mm.c optional sisdrm dev/drm/tdfx_drv.c optional tdfxdrm dev/drm/via_dma.c optional viadrm dev/drm/via_dmablit.c optional viadrm dev/drm/via_drv.c optional viadrm dev/drm/via_irq.c optional viadrm dev/drm/via_map.c optional viadrm dev/drm/via_mm.c optional viadrm dev/drm/via_verifier.c optional viadrm dev/drm/via_video.c optional viadrm dev/drm2/drm_agpsupport.c optional drm2 dev/drm2/drm_auth.c optional drm2 dev/drm2/drm_bufs.c optional drm2 dev/drm2/drm_buffer.c optional drm2 dev/drm2/drm_context.c optional drm2 dev/drm2/drm_crtc.c optional drm2 dev/drm2/drm_crtc_helper.c optional drm2 dev/drm2/drm_dma.c optional drm2 dev/drm2/drm_dp_helper.c optional drm2 dev/drm2/drm_dp_iic_helper.c optional drm2 dev/drm2/drm_drv.c optional drm2 dev/drm2/drm_edid.c optional drm2 dev/drm2/drm_fb_helper.c optional drm2 dev/drm2/drm_fops.c optional drm2 dev/drm2/drm_gem.c optional drm2 dev/drm2/drm_gem_names.c optional drm2 dev/drm2/drm_global.c optional drm2 dev/drm2/drm_hashtab.c optional drm2 dev/drm2/drm_ioctl.c optional drm2 dev/drm2/drm_irq.c optional drm2 dev/drm2/drm_linux_list_sort.c optional drm2 dev/drm2/drm_lock.c optional drm2 dev/drm2/drm_memory.c optional drm2 dev/drm2/drm_mm.c optional drm2 dev/drm2/drm_modes.c optional drm2 dev/drm2/drm_pci.c optional drm2 dev/drm2/drm_scatter.c optional drm2 dev/drm2/drm_stub.c optional drm2 dev/drm2/drm_sysctl.c optional drm2 dev/drm2/drm_vm.c optional drm2 dev/drm2/drm_os_freebsd.c optional drm2 dev/drm2/ttm/ttm_agp_backend.c optional drm2 dev/drm2/ttm/ttm_lock.c optional drm2 dev/drm2/ttm/ttm_object.c optional drm2 dev/drm2/ttm/ttm_tt.c optional drm2 dev/drm2/ttm/ttm_bo_util.c optional drm2 dev/drm2/ttm/ttm_bo.c optional drm2 dev/drm2/ttm/ttm_bo_manager.c optional drm2 dev/drm2/ttm/ttm_execbuf_util.c optional drm2 dev/drm2/ttm/ttm_memory.c optional drm2 dev/drm2/ttm/ttm_page_alloc.c optional drm2 dev/drm2/ttm/ttm_bo_vm.c optional drm2 dev/drm2/ati_pcigart.c optional drm2 agp pci dev/ed/if_ed.c optional ed dev/ed/if_ed_novell.c optional ed dev/ed/if_ed_rtl80x9.c optional ed dev/ed/if_ed_pccard.c optional ed pccard dev/ed/if_ed_pci.c optional ed pci dev/efidev/efidev.c optional efirt dev/eisa/eisa_if.m standard dev/eisa/eisaconf.c optional eisa dev/e1000/if_em.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/if_lem.c optional em \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/if_igb.c optional igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_80003es2lan.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82540.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82541.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82542.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82543.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82571.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_82575.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_ich8lan.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_i210.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_api.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mac.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_manage.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_nvm.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_phy.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_vf.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_mbx.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/e1000/e1000_osdep.c optional em | igb \ compile-with "${NORMAL_C} -I$S/dev/e1000" dev/et/if_et.c optional et dev/en/if_en_pci.c optional en pci dev/en/midway.c optional en dev/ep/if_ep.c optional ep dev/ep/if_ep_eisa.c optional ep eisa dev/ep/if_ep_isa.c optional ep isa dev/ep/if_ep_mca.c optional ep mca dev/ep/if_ep_pccard.c optional ep pccard dev/esp/esp_pci.c optional esp pci dev/esp/ncr53c9x.c optional esp dev/etherswitch/arswitch/arswitch.c optional arswitch dev/etherswitch/arswitch/arswitch_reg.c optional arswitch dev/etherswitch/arswitch/arswitch_phy.c optional arswitch dev/etherswitch/arswitch/arswitch_8216.c optional arswitch dev/etherswitch/arswitch/arswitch_8226.c optional arswitch dev/etherswitch/arswitch/arswitch_8316.c optional arswitch dev/etherswitch/arswitch/arswitch_8327.c optional arswitch dev/etherswitch/arswitch/arswitch_7240.c optional arswitch dev/etherswitch/arswitch/arswitch_9340.c optional arswitch dev/etherswitch/arswitch/arswitch_vlans.c optional arswitch dev/etherswitch/etherswitch.c optional etherswitch dev/etherswitch/etherswitch_if.m optional etherswitch dev/etherswitch/ip17x/ip17x.c optional ip17x dev/etherswitch/ip17x/ip175c.c optional ip17x dev/etherswitch/ip17x/ip175d.c optional ip17x dev/etherswitch/ip17x/ip17x_phy.c optional ip17x dev/etherswitch/ip17x/ip17x_vlans.c optional ip17x dev/etherswitch/miiproxy.c optional miiproxy dev/etherswitch/rtl8366/rtl8366rb.c optional rtl8366rb dev/etherswitch/ukswitch/ukswitch.c optional ukswitch dev/evdev/cdev.c optional evdev dev/evdev/evdev.c optional evdev dev/evdev/evdev_mt.c optional evdev dev/evdev/evdev_utils.c optional evdev dev/evdev/uinput.c optional evdev uinput dev/ex/if_ex.c optional ex dev/ex/if_ex_isa.c optional ex isa dev/ex/if_ex_pccard.c optional ex pccard dev/exca/exca.c optional cbb dev/extres/clk/clk.c optional ext_resources clk fdt dev/extres/clk/clkdev_if.m optional ext_resources clk fdt dev/extres/clk/clknode_if.m optional ext_resources clk fdt dev/extres/clk/clk_bus.c optional ext_resources clk fdt dev/extres/clk/clk_div.c optional ext_resources clk fdt dev/extres/clk/clk_fixed.c optional ext_resources clk fdt dev/extres/clk/clk_gate.c optional ext_resources clk fdt dev/extres/clk/clk_mux.c optional ext_resources clk fdt dev/extres/phy/phy.c optional ext_resources phy fdt dev/extres/phy/phy_if.m optional ext_resources phy fdt dev/extres/hwreset/hwreset.c optional ext_resources hwreset fdt dev/extres/hwreset/hwreset_if.m optional ext_resources hwreset fdt dev/extres/regulator/regdev_if.m optional ext_resources regulator fdt dev/extres/regulator/regnode_if.m optional ext_resources regulator fdt dev/extres/regulator/regulator.c optional ext_resources regulator fdt dev/extres/regulator/regulator_bus.c optional ext_resources regulator fdt dev/extres/regulator/regulator_fixed.c optional ext_resources regulator fdt dev/fatm/if_fatm.c optional fatm pci dev/fb/fbd.c optional fbd | vt dev/fb/fb_if.m standard dev/fb/splash.c optional sc splash dev/fdt/fdt_clock.c optional fdt fdt_clock dev/fdt/fdt_clock_if.m optional fdt fdt_clock dev/fdt/fdt_common.c optional fdt dev/fdt/fdt_pinctrl.c optional fdt fdt_pinctrl dev/fdt/fdt_pinctrl_if.m optional fdt fdt_pinctrl dev/fdt/fdt_slicer.c optional fdt cfi | fdt nand | fdt mx25l dev/fdt/fdt_static_dtb.S optional fdt fdt_dtb_static \ dependency "fdt_dtb_file" dev/fdt/simplebus.c optional fdt dev/fe/if_fe.c optional fe dev/fe/if_fe_pccard.c optional fe pccard dev/filemon/filemon.c optional filemon dev/firewire/firewire.c optional firewire dev/firewire/fwcrom.c optional firewire dev/firewire/fwdev.c optional firewire dev/firewire/fwdma.c optional firewire dev/firewire/fwmem.c optional firewire dev/firewire/fwohci.c optional firewire dev/firewire/fwohci_pci.c optional firewire pci dev/firewire/if_fwe.c optional fwe dev/firewire/if_fwip.c optional fwip dev/firewire/sbp.c optional sbp dev/firewire/sbp_targ.c optional sbp_targ dev/flash/at45d.c optional at45d dev/flash/mx25l.c optional mx25l dev/fxp/if_fxp.c optional fxp dev/fxp/inphy.c optional fxp dev/gem/if_gem.c optional gem dev/gem/if_gem_pci.c optional gem pci dev/gem/if_gem_sbus.c optional gem sbus dev/gpio/gpiobacklight.c optional gpiobacklight fdt dev/gpio/gpiokeys.c optional gpiokeys fdt dev/gpio/gpiokeys_codes.c optional gpiokeys fdt dev/gpio/gpiobus.c optional gpio \ dependency "gpiobus_if.h" dev/gpio/gpioc.c optional gpio \ dependency "gpio_if.h" dev/gpio/gpioiic.c optional gpioiic dev/gpio/gpioled.c optional gpioled !fdt dev/gpio/gpioled_fdt.c optional gpioled fdt dev/gpio/gpiopower.c optional gpiopower fdt dev/gpio/gpioregulator.c optional gpioregulator fdt ext_resources dev/gpio/gpiospi.c optional gpiospi dev/gpio/gpio_if.m optional gpio dev/gpio/gpiobus_if.m optional gpio dev/gpio/gpiopps.c optional gpiopps dev/gpio/ofw_gpiobus.c optional fdt gpio dev/hatm/if_hatm.c optional hatm pci dev/hatm/if_hatm_intr.c optional hatm pci dev/hatm/if_hatm_ioctl.c optional hatm pci dev/hatm/if_hatm_rx.c optional hatm pci dev/hatm/if_hatm_tx.c optional hatm pci dev/hifn/hifn7751.c optional hifn dev/hme/if_hme.c optional hme dev/hme/if_hme_pci.c optional hme pci dev/hme/if_hme_sbus.c optional hme sbus dev/hptiop/hptiop.c optional hptiop scbus dev/hwpmc/hwpmc_logging.c optional hwpmc dev/hwpmc/hwpmc_mod.c optional hwpmc dev/hwpmc/hwpmc_soft.c optional hwpmc dev/ichiic/ig4_iic.c optional ig4 iicbus dev/ichiic/ig4_pci.c optional ig4 pci iicbus dev/ichsmb/ichsmb.c optional ichsmb dev/ichsmb/ichsmb_pci.c optional ichsmb pci dev/ida/ida.c optional ida dev/ida/ida_disk.c optional ida dev/ida/ida_eisa.c optional ida eisa dev/ida/ida_pci.c optional ida pci dev/iicbus/ad7418.c optional ad7418 dev/iicbus/ds1307.c optional ds1307 dev/iicbus/ds133x.c optional ds133x dev/iicbus/ds1374.c optional ds1374 dev/iicbus/ds1672.c optional ds1672 dev/iicbus/ds3231.c optional ds3231 dev/iicbus/icee.c optional icee dev/iicbus/if_ic.c optional ic dev/iicbus/iic.c optional iic dev/iicbus/iicbb.c optional iicbb dev/iicbus/iicbb_if.m optional iicbb dev/iicbus/iicbus.c optional iicbus dev/iicbus/iicbus_if.m optional iicbus dev/iicbus/iiconf.c optional iicbus dev/iicbus/iicsmb.c optional iicsmb \ dependency "iicbus_if.h" dev/iicbus/iicoc.c optional iicoc dev/iicbus/lm75.c optional lm75 dev/iicbus/ofw_iicbus.c optional fdt iicbus dev/iicbus/pcf8563.c optional pcf8563 dev/iicbus/s35390a.c optional s35390a dev/iir/iir.c optional iir dev/iir/iir_ctrl.c optional iir dev/iir/iir_pci.c optional iir pci dev/intpm/intpm.c optional intpm pci # XXX Work around clang warning, until maintainer approves fix. dev/ips/ips.c optional ips \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/ips/ips_commands.c optional ips dev/ips/ips_disk.c optional ips dev/ips/ips_ioctl.c optional ips dev/ips/ips_pci.c optional ips pci dev/ipw/if_ipw.c optional ipw ipwbssfw.c optional ipwbssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_bss.fw:ipw_bss:130 -lintel_ipw -mipw_bss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwbssfw.c" ipw_bss.fwo optional ipwbssfw | ipwfw \ dependency "ipw_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_bss.fwo" ipw_bss.fw optional ipwbssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_bss.fw" ipwibssfw.c optional ipwibssfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_ibss.fw:ipw_ibss:130 -lintel_ipw -mipw_ibss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwibssfw.c" ipw_ibss.fwo optional ipwibssfw | ipwfw \ dependency "ipw_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_ibss.fwo" ipw_ibss.fw optional ipwibssfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-i.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_ibss.fw" ipwmonitorfw.c optional ipwmonitorfw | ipwfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk ipw_monitor.fw:ipw_monitor:130 -lintel_ipw -mipw_monitor -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "ipwmonitorfw.c" ipw_monitor.fwo optional ipwmonitorfw | ipwfw \ dependency "ipw_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ipw_monitor.fwo" ipw_monitor.fw optional ipwmonitorfw | ipwfw \ dependency "$S/contrib/dev/ipw/ipw2100-1.3-p.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "ipw_monitor.fw" dev/iscsi/icl.c optional iscsi | ctl dev/iscsi/icl_conn_if.m optional iscsi | ctl dev/iscsi/icl_soft.c optional iscsi | ctl dev/iscsi/icl_soft_proxy.c optional iscsi | ctl dev/iscsi/iscsi.c optional iscsi scbus dev/iscsi_initiator/iscsi.c optional iscsi_initiator scbus dev/iscsi_initiator/iscsi_subr.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_cam.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_soc.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_sm.c optional iscsi_initiator scbus dev/iscsi_initiator/isc_subr.c optional iscsi_initiator scbus dev/ismt/ismt.c optional ismt dev/isl/isl.c optional isl iicbus dev/isp/isp.c optional isp dev/isp/isp_freebsd.c optional isp dev/isp/isp_library.c optional isp dev/isp/isp_pci.c optional isp pci dev/isp/isp_sbus.c optional isp sbus dev/isp/isp_target.c optional isp dev/ispfw/ispfw.c optional ispfw dev/iwi/if_iwi.c optional iwi iwibssfw.c optional iwibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_bss.fw:iwi_bss:300 -lintel_iwi -miwi_bss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwibssfw.c" iwi_bss.fwo optional iwibssfw | iwifw \ dependency "iwi_bss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_bss.fwo" iwi_bss.fw optional iwibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-bss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_bss.fw" iwiibssfw.c optional iwiibssfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_ibss.fw:iwi_ibss:300 -lintel_iwi -miwi_ibss -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwiibssfw.c" iwi_ibss.fwo optional iwiibssfw | iwifw \ dependency "iwi_ibss.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_ibss.fwo" iwi_ibss.fw optional iwiibssfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-ibss.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_ibss.fw" iwimonitorfw.c optional iwimonitorfw | iwifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwi_monitor.fw:iwi_monitor:300 -lintel_iwi -miwi_monitor -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwimonitorfw.c" iwi_monitor.fwo optional iwimonitorfw | iwifw \ dependency "iwi_monitor.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwi_monitor.fwo" iwi_monitor.fw optional iwimonitorfw | iwifw \ dependency "$S/contrib/dev/iwi/ipw2200-sniffer.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwi_monitor.fw" dev/iwm/if_iwm.c optional iwm dev/iwm/if_iwm_binding.c optional iwm dev/iwm/if_iwm_led.c optional iwm dev/iwm/if_iwm_mac_ctxt.c optional iwm dev/iwm/if_iwm_pcie_trans.c optional iwm dev/iwm/if_iwm_phy_ctxt.c optional iwm dev/iwm/if_iwm_phy_db.c optional iwm dev/iwm/if_iwm_power.c optional iwm dev/iwm/if_iwm_scan.c optional iwm dev/iwm/if_iwm_time_event.c optional iwm dev/iwm/if_iwm_util.c optional iwm iwm3160fw.c optional iwm3160fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm3160.fw:iwm3160fw -miwm3160fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm3160fw.c" iwm3160fw.fwo optional iwm3160fw | iwmfw \ dependency "iwm3160.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm3160fw.fwo" iwm3160.fw optional iwm3160fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-3160-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm3160.fw" iwm7260fw.c optional iwm7260fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7260.fw:iwm7260fw -miwm7260fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm7260fw.c" iwm7260fw.fwo optional iwm7260fw | iwmfw \ dependency "iwm7260.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7260fw.fwo" iwm7260.fw optional iwm7260fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7260-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7260.fw" iwm7265fw.c optional iwm7265fw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm7265.fw:iwm7265fw -miwm7265fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm7265fw.c" iwm7265fw.fwo optional iwm7265fw | iwmfw \ dependency "iwm7265.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm7265fw.fwo" iwm7265.fw optional iwm7265fw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-7265-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm7265.fw" iwm8000Cfw.c optional iwm8000Cfw | iwmfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwm8000C.fw:iwm8000Cfw -miwm8000Cfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwm8000Cfw.c" iwm8000Cfw.fwo optional iwm8000Cfw | iwmfw \ dependency "iwm8000C.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwm8000Cfw.fwo" iwm8000C.fw optional iwm8000Cfw | iwmfw \ dependency "$S/contrib/dev/iwm/iwm-8000C-16.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwm8000C.fw" dev/iwn/if_iwn.c optional iwn iwn1000fw.c optional iwn1000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn1000.fw:iwn1000fw -miwn1000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn1000fw.c" iwn1000fw.fwo optional iwn1000fw | iwnfw \ dependency "iwn1000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn1000fw.fwo" iwn1000.fw optional iwn1000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-1000-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn1000.fw" iwn100fw.c optional iwn100fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn100.fw:iwn100fw -miwn100fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn100fw.c" iwn100fw.fwo optional iwn100fw | iwnfw \ dependency "iwn100.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn100fw.fwo" iwn100.fw optional iwn100fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-100-39.31.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn100.fw" iwn105fw.c optional iwn105fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn105.fw:iwn105fw -miwn105fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn105fw.c" iwn105fw.fwo optional iwn105fw | iwnfw \ dependency "iwn105.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn105fw.fwo" iwn105.fw optional iwn105fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-105-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn105.fw" iwn135fw.c optional iwn135fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn135.fw:iwn135fw -miwn135fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn135fw.c" iwn135fw.fwo optional iwn135fw | iwnfw \ dependency "iwn135.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn135fw.fwo" iwn135.fw optional iwn135fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-135-6-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn135.fw" iwn2000fw.c optional iwn2000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2000.fw:iwn2000fw -miwn2000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn2000fw.c" iwn2000fw.fwo optional iwn2000fw | iwnfw \ dependency "iwn2000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2000fw.fwo" iwn2000.fw optional iwn2000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-2000-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2000.fw" iwn2030fw.c optional iwn2030fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn2030.fw:iwn2030fw -miwn2030fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn2030fw.c" iwn2030fw.fwo optional iwn2030fw | iwnfw \ dependency "iwn2030.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn2030fw.fwo" iwn2030.fw optional iwn2030fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwnwifi-2030-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn2030.fw" iwn4965fw.c optional iwn4965fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn4965.fw:iwn4965fw -miwn4965fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn4965fw.c" iwn4965fw.fwo optional iwn4965fw | iwnfw \ dependency "iwn4965.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn4965fw.fwo" iwn4965.fw optional iwn4965fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-4965-228.61.2.24.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn4965.fw" iwn5000fw.c optional iwn5000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5000.fw:iwn5000fw -miwn5000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn5000fw.c" iwn5000fw.fwo optional iwn5000fw | iwnfw \ dependency "iwn5000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5000fw.fwo" iwn5000.fw optional iwn5000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5000-8.83.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5000.fw" iwn5150fw.c optional iwn5150fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn5150.fw:iwn5150fw -miwn5150fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn5150fw.c" iwn5150fw.fwo optional iwn5150fw | iwnfw \ dependency "iwn5150.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn5150fw.fwo" iwn5150.fw optional iwn5150fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-5150-8.24.2.2.fw.uu"\ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn5150.fw" iwn6000fw.c optional iwn6000fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000.fw:iwn6000fw -miwn6000fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000fw.c" iwn6000fw.fwo optional iwn6000fw | iwnfw \ dependency "iwn6000.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000fw.fwo" iwn6000.fw optional iwn6000fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000-9.221.4.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000.fw" iwn6000g2afw.c optional iwn6000g2afw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2a.fw:iwn6000g2afw -miwn6000g2afw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000g2afw.c" iwn6000g2afw.fwo optional iwn6000g2afw | iwnfw \ dependency "iwn6000g2a.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2afw.fwo" iwn6000g2a.fw optional iwn6000g2afw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2a-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2a.fw" iwn6000g2bfw.c optional iwn6000g2bfw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6000g2b.fw:iwn6000g2bfw -miwn6000g2bfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6000g2bfw.c" iwn6000g2bfw.fwo optional iwn6000g2bfw | iwnfw \ dependency "iwn6000g2b.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6000g2bfw.fwo" iwn6000g2b.fw optional iwn6000g2bfw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6000g2b-18.168.6.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6000g2b.fw" iwn6050fw.c optional iwn6050fw | iwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk iwn6050.fw:iwn6050fw -miwn6050fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "iwn6050fw.c" iwn6050fw.fwo optional iwn6050fw | iwnfw \ dependency "iwn6050.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "iwn6050fw.fwo" iwn6050.fw optional iwn6050fw | iwnfw \ dependency "$S/contrib/dev/iwn/iwlwifi-6050-41.28.5.1.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "iwn6050.fw" dev/ixgb/if_ixgb.c optional ixgb dev/ixgb/ixgb_ee.c optional ixgb dev/ixgb/ixgb_hw.c optional ixgb dev/ixgbe/if_ix.c optional ix inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/if_ixv.c optional ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe -DSMP" dev/ixgbe/ix_txrx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_osdep.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_phy.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_api.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_common.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_mbx.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_vf.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x540.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_x550.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82598.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/ixgbe/ixgbe_dcb_82599.c optional ix inet | ixv inet \ compile-with "${NORMAL_C} -I$S/dev/ixgbe" dev/jedec_ts/jedec_ts.c optional jedec_ts smbus dev/jme/if_jme.c optional jme pci dev/joy/joy.c optional joy dev/joy/joy_isa.c optional joy isa dev/kbd/kbd.c optional atkbd | pckbd | sc | ukbd | vt dev/kbdmux/kbdmux.c optional kbdmux dev/ksyms/ksyms.c optional ksyms dev/le/am7990.c optional le dev/le/am79900.c optional le dev/le/if_le_pci.c optional le pci dev/le/lance.c optional le dev/led/led.c standard dev/lge/if_lge.c optional lge dev/lmc/if_lmc.c optional lmc dev/malo/if_malo.c optional malo dev/malo/if_malohal.c optional malo dev/malo/if_malo_pci.c optional malo pci dev/mc146818/mc146818.c optional mc146818 dev/mca/mca_bus.c optional mca dev/md/md.c optional md dev/mdio/mdio_if.m optional miiproxy | mdio dev/mdio/mdio.c optional miiproxy | mdio dev/mem/memdev.c optional mem dev/mem/memutil.c optional mem dev/mfi/mfi.c optional mfi dev/mfi/mfi_debug.c optional mfi dev/mfi/mfi_pci.c optional mfi pci dev/mfi/mfi_disk.c optional mfi dev/mfi/mfi_syspd.c optional mfi dev/mfi/mfi_tbolt.c optional mfi dev/mfi/mfi_linux.c optional mfi compat_linux dev/mfi/mfi_cam.c optional mfip scbus dev/mii/acphy.c optional miibus | acphy dev/mii/amphy.c optional miibus | amphy dev/mii/atphy.c optional miibus | atphy dev/mii/axphy.c optional miibus | axphy dev/mii/bmtphy.c optional miibus | bmtphy dev/mii/brgphy.c optional miibus | brgphy dev/mii/ciphy.c optional miibus | ciphy dev/mii/e1000phy.c optional miibus | e1000phy dev/mii/gentbi.c optional miibus | gentbi dev/mii/icsphy.c optional miibus | icsphy dev/mii/ip1000phy.c optional miibus | ip1000phy dev/mii/jmphy.c optional miibus | jmphy dev/mii/lxtphy.c optional miibus | lxtphy dev/mii/micphy.c optional miibus fdt | micphy fdt dev/mii/mii.c optional miibus | mii dev/mii/mii_bitbang.c optional miibus | mii_bitbang dev/mii/mii_physubr.c optional miibus | mii dev/mii/miibus_if.m optional miibus | mii dev/mii/mlphy.c optional miibus | mlphy dev/mii/nsgphy.c optional miibus | nsgphy dev/mii/nsphy.c optional miibus | nsphy dev/mii/nsphyter.c optional miibus | nsphyter dev/mii/pnaphy.c optional miibus | pnaphy dev/mii/qsphy.c optional miibus | qsphy dev/mii/rdcphy.c optional miibus | rdcphy dev/mii/rgephy.c optional miibus | rgephy dev/mii/rlphy.c optional miibus | rlphy dev/mii/rlswitch.c optional rlswitch dev/mii/smcphy.c optional miibus | smcphy dev/mii/smscphy.c optional miibus | smscphy dev/mii/tdkphy.c optional miibus | tdkphy dev/mii/tlphy.c optional miibus | tlphy dev/mii/truephy.c optional miibus | truephy dev/mii/ukphy.c optional miibus | mii dev/mii/ukphy_subr.c optional miibus | mii dev/mii/xmphy.c optional miibus | xmphy dev/mk48txx/mk48txx.c optional mk48txx dev/mlx/mlx.c optional mlx dev/mlx/mlx_disk.c optional mlx dev/mlx/mlx_pci.c optional mlx pci dev/mly/mly.c optional mly dev/mmc/mmc.c optional mmc dev/mmc/mmcbr_if.m standard dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd dev/mn/if_mn.c optional mn pci dev/mpr/mpr.c optional mpr dev/mpr/mpr_config.c optional mpr # XXX Work around clang warning, until maintainer approves fix. dev/mpr/mpr_mapping.c optional mpr \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mpr/mpr_pci.c optional mpr pci dev/mpr/mpr_sas.c optional mpr \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mpr/mpr_sas_lsi.c optional mpr dev/mpr/mpr_table.c optional mpr dev/mpr/mpr_user.c optional mpr dev/mps/mps.c optional mps dev/mps/mps_config.c optional mps # XXX Work around clang warning, until maintainer approves fix. dev/mps/mps_mapping.c optional mps \ compile-with "${NORMAL_C} ${NO_WSOMETIMES_UNINITIALIZED}" dev/mps/mps_pci.c optional mps pci dev/mps/mps_sas.c optional mps \ compile-with "${NORMAL_C} ${NO_WUNNEEDED_INTERNAL_DECL}" dev/mps/mps_sas_lsi.c optional mps dev/mps/mps_table.c optional mps dev/mps/mps_user.c optional mps dev/mpt/mpt.c optional mpt dev/mpt/mpt_cam.c optional mpt dev/mpt/mpt_debug.c optional mpt dev/mpt/mpt_pci.c optional mpt pci dev/mpt/mpt_raid.c optional mpt dev/mpt/mpt_user.c optional mpt dev/mrsas/mrsas.c optional mrsas dev/mrsas/mrsas_cam.c optional mrsas dev/mrsas/mrsas_ioctl.c optional mrsas dev/mrsas/mrsas_fp.c optional mrsas dev/msk/if_msk.c optional msk dev/mvs/mvs.c optional mvs dev/mvs/mvs_if.m optional mvs dev/mvs/mvs_pci.c optional mvs pci dev/mwl/if_mwl.c optional mwl dev/mwl/if_mwl_pci.c optional mwl pci dev/mwl/mwlhal.c optional mwl mwlfw.c optional mwlfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk mw88W8363.fw:mw88W8363fw mwlboot.fw:mwlboot -mmwl -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "mwlfw.c" mw88W8363.fwo optional mwlfw \ dependency "mw88W8363.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mw88W8363.fwo" mw88W8363.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mw88W8363.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mw88W8363.fw" mwlboot.fwo optional mwlfw \ dependency "mwlboot.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "mwlboot.fwo" mwlboot.fw optional mwlfw \ dependency "$S/contrib/dev/mwl/mwlboot.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "mwlboot.fw" dev/mxge/if_mxge.c optional mxge pci dev/mxge/mxge_eth_z8e.c optional mxge pci dev/mxge/mxge_ethp_z8e.c optional mxge pci dev/mxge/mxge_rss_eth_z8e.c optional mxge pci dev/mxge/mxge_rss_ethp_z8e.c optional mxge pci dev/my/if_my.c optional my dev/nand/nand.c optional nand dev/nand/nand_bbt.c optional nand dev/nand/nand_cdev.c optional nand dev/nand/nand_generic.c optional nand dev/nand/nand_geom.c optional nand dev/nand/nand_id.c optional nand dev/nand/nandbus.c optional nand dev/nand/nandbus_if.m optional nand dev/nand/nand_if.m optional nand dev/nand/nandsim.c optional nandsim nand dev/nand/nandsim_chip.c optional nandsim nand dev/nand/nandsim_ctrl.c optional nandsim nand dev/nand/nandsim_log.c optional nandsim nand dev/nand/nandsim_swap.c optional nandsim nand dev/nand/nfc_if.m optional nand dev/ncr/ncr.c optional ncr pci dev/ncv/ncr53c500.c optional ncv dev/ncv/ncr53c500_pccard.c optional ncv pccard dev/netmap/if_ptnet.c optional netmap inet dev/netmap/netmap.c optional netmap dev/netmap/netmap_freebsd.c optional netmap dev/netmap/netmap_generic.c optional netmap dev/netmap/netmap_mbq.c optional netmap dev/netmap/netmap_mem2.c optional netmap dev/netmap/netmap_monitor.c optional netmap dev/netmap/netmap_offloadings.c optional netmap dev/netmap/netmap_pipe.c optional netmap dev/netmap/netmap_pt.c optional netmap dev/netmap/netmap_vale.c optional netmap # compile-with "${NORMAL_C} -Wconversion -Wextra" dev/nfsmb/nfsmb.c optional nfsmb pci dev/nge/if_nge.c optional nge dev/nxge/if_nxge.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-device.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-mm.c optional nxge dev/nxge/xgehal/xge-queue.c optional nxge dev/nxge/xgehal/xgehal-driver.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-ring.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-channel.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-fifo.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-stats.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nxge/xgehal/xgehal-config.c optional nxge dev/nxge/xgehal/xgehal-mgmt.c optional nxge \ compile-with "${NORMAL_C} ${NO_WSELF_ASSIGN}" dev/nmdm/nmdm.c optional nmdm dev/nsp/nsp.c optional nsp dev/nsp/nsp_pccard.c optional nsp pccard dev/null/null.c standard dev/oce/oce_hw.c optional oce pci dev/oce/oce_if.c optional oce pci dev/oce/oce_mbox.c optional oce pci dev/oce/oce_queue.c optional oce pci dev/oce/oce_sysctl.c optional oce pci dev/oce/oce_util.c optional oce pci dev/ofw/ofw_bus_if.m optional fdt dev/ofw/ofw_bus_subr.c optional fdt dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_fdt.c optional fdt dev/ofw/ofw_if.m optional fdt dev/ofw/ofw_subr.c optional fdt dev/ofw/ofwbus.c optional fdt dev/ofw/openfirm.c optional fdt dev/ofw/openfirmio.c optional fdt dev/ow/ow.c optional ow \ dependency "owll_if.h" \ dependency "own_if.h" dev/ow/owll_if.m optional ow dev/ow/own_if.m optional ow dev/ow/ow_temp.c optional ow_temp dev/ow/owc_gpiobus.c optional owc gpio dev/patm/if_patm.c optional patm pci dev/patm/if_patm_attach.c optional patm pci dev/patm/if_patm_intr.c optional patm pci dev/patm/if_patm_ioctl.c optional patm pci dev/patm/if_patm_rtables.c optional patm pci dev/patm/if_patm_rx.c optional patm pci dev/patm/if_patm_tx.c optional patm pci dev/pbio/pbio.c optional pbio isa dev/pccard/card_if.m standard dev/pccard/pccard.c optional pccard dev/pccard/pccard_cis.c optional pccard dev/pccard/pccard_cis_quirks.c optional pccard dev/pccard/pccard_device.c optional pccard dev/pccard/power_if.m standard dev/pccbb/pccbb.c optional cbb dev/pccbb/pccbb_isa.c optional cbb isa dev/pccbb/pccbb_pci.c optional cbb pci dev/pcf/pcf.c optional pcf dev/pci/eisa_pci.c optional pci eisa dev/pci/fixup_pci.c optional pci dev/pci/hostb_pci.c optional pci dev/pci/ignore_pci.c optional pci dev/pci/isa_pci.c optional pci isa dev/pci/pci.c optional pci dev/pci/pci_if.m standard dev/pci/pci_iov.c optional pci pci_iov dev/pci/pci_iov_if.m standard dev/pci/pci_iov_schema.c optional pci pci_iov dev/pci/pci_pci.c optional pci dev/pci/pci_subr.c optional pci dev/pci/pci_user.c optional pci dev/pci/pcib_if.m standard dev/pci/pcib_support.c standard dev/pci/vga_pci.c optional pci dev/pcn/if_pcn.c optional pcn pci dev/pdq/if_fea.c optional fea eisa dev/pdq/if_fpa.c optional fpa pci dev/pdq/pdq.c optional nowerror fea eisa | fpa pci dev/pdq/pdq_ifsubr.c optional nowerror fea eisa | fpa pci dev/pms/freebsd/driver/ini/src/agtiapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sadisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saframe.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sahw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sainit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampicmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sampirsp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saphy.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasata.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sasmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sassp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/satimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/sautil.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/saioctlcmd.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sallsdk/spc/mpidebug.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmsmp.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmdisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/discovery/dm/dmmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/sminit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsatcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smsathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/sat/src/smtimer.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdmisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdesgl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdport.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdint.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdioctl.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdhw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/ossacmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tddmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdsmcmnapi.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/common/tdtimers.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdio.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdcb.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itdinit.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sas/ini/itddisc.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/ossasat.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/pms/RefTisa/tisa/sassata/sata/host/sathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/ppbus/if_plip.c optional plip dev/ppbus/immio.c optional vpo dev/ppbus/lpbb.c optional lpbb dev/ppbus/lpt.c optional lpt dev/ppbus/pcfclock.c optional pcfclock dev/ppbus/ppb_1284.c optional ppbus dev/ppbus/ppb_base.c optional ppbus dev/ppbus/ppb_msq.c optional ppbus dev/ppbus/ppbconf.c optional ppbus dev/ppbus/ppbus_if.m optional ppbus dev/ppbus/ppi.c optional ppi dev/ppbus/pps.c optional pps dev/ppbus/vpo.c optional vpo dev/ppbus/vpoio.c optional vpo dev/ppc/ppc.c optional ppc dev/ppc/ppc_acpi.c optional ppc acpi dev/ppc/ppc_isa.c optional ppc isa dev/ppc/ppc_pci.c optional ppc pci dev/ppc/ppc_puc.c optional ppc puc dev/proto/proto_bus_isa.c optional proto acpi | proto isa dev/proto/proto_bus_pci.c optional proto pci dev/proto/proto_busdma.c optional proto dev/proto/proto_core.c optional proto dev/pst/pst-iop.c optional pst dev/pst/pst-pci.c optional pst pci dev/pst/pst-raid.c optional pst dev/pty/pty.c optional pty dev/puc/puc.c optional puc dev/puc/puc_cfg.c optional puc dev/puc/puc_pccard.c optional puc pccard dev/puc/puc_pci.c optional puc pci dev/puc/pucdata.c optional puc pci dev/quicc/quicc_core.c optional quicc dev/ral/rt2560.c optional ral dev/ral/rt2661.c optional ral dev/ral/rt2860.c optional ral dev/ral/if_ral_pci.c optional ral pci rt2561fw.c optional rt2561fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561.fw:rt2561fw -mrt2561 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2561fw.c" rt2561fw.fwo optional rt2561fw | ralfw \ dependency "rt2561.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561fw.fwo" rt2561.fw optional rt2561fw | ralfw \ dependency "$S/contrib/dev/ral/rt2561.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561.fw" rt2561sfw.c optional rt2561sfw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2561s.fw:rt2561sfw -mrt2561s -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2561sfw.c" rt2561sfw.fwo optional rt2561sfw | ralfw \ dependency "rt2561s.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2561sfw.fwo" rt2561s.fw optional rt2561sfw | ralfw \ dependency "$S/contrib/dev/ral/rt2561s.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2561s.fw" rt2661fw.c optional rt2661fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2661.fw:rt2661fw -mrt2661 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2661fw.c" rt2661fw.fwo optional rt2661fw | ralfw \ dependency "rt2661.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2661fw.fwo" rt2661.fw optional rt2661fw | ralfw \ dependency "$S/contrib/dev/ral/rt2661.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2661.fw" rt2860fw.c optional rt2860fw | ralfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rt2860.fw:rt2860fw -mrt2860 -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rt2860fw.c" rt2860fw.fwo optional rt2860fw | ralfw \ dependency "rt2860.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rt2860fw.fwo" rt2860.fw optional rt2860fw | ralfw \ dependency "$S/contrib/dev/ral/rt2860.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rt2860.fw" dev/random/random_infra.c optional random dev/random/random_harvestq.c optional random dev/random/randomdev.c optional random random_yarrow | \ random !random_yarrow !random_loadable dev/random/yarrow.c optional random random_yarrow dev/random/fortuna.c optional random !random_yarrow !random_loadable dev/random/hash.c optional random random_yarrow | \ random !random_yarrow !random_loadable dev/rc/rc.c optional rc dev/rccgpio/rccgpio.c optional rccgpio gpio dev/re/if_re.c optional re dev/rl/if_rl.c optional rl pci dev/rndtest/rndtest.c optional rndtest dev/rp/rp.c optional rp dev/rp/rp_isa.c optional rp isa dev/rp/rp_pci.c optional rp pci # dev/rtwn/if_rtwn.c optional rtwn dev/rtwn/if_rtwn_beacon.c optional rtwn dev/rtwn/if_rtwn_calib.c optional rtwn dev/rtwn/if_rtwn_cam.c optional rtwn dev/rtwn/if_rtwn_efuse.c optional rtwn dev/rtwn/if_rtwn_fw.c optional rtwn dev/rtwn/if_rtwn_rx.c optional rtwn dev/rtwn/if_rtwn_task.c optional rtwn dev/rtwn/if_rtwn_tx.c optional rtwn # dev/rtwn/pci/rtwn_pci_attach.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_reg.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_rx.c optional rtwn_pci pci dev/rtwn/pci/rtwn_pci_tx.c optional rtwn_pci pci # dev/rtwn/usb/rtwn_usb_attach.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_ep.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_reg.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_rx.c optional rtwn_usb dev/rtwn/usb/rtwn_usb_tx.c optional rtwn_usb # RTL8188E dev/rtwn/rtl8188e/r88e_beacon.c optional rtwn dev/rtwn/rtl8188e/r88e_calib.c optional rtwn dev/rtwn/rtl8188e/r88e_chan.c optional rtwn dev/rtwn/rtl8188e/r88e_fw.c optional rtwn dev/rtwn/rtl8188e/r88e_init.c optional rtwn dev/rtwn/rtl8188e/r88e_led.c optional rtwn dev/rtwn/rtl8188e/r88e_tx.c optional rtwn dev/rtwn/rtl8188e/r88e_rf.c optional rtwn dev/rtwn/rtl8188e/r88e_rom.c optional rtwn dev/rtwn/rtl8188e/r88e_rx.c optional rtwn dev/rtwn/rtl8188e/usb/r88eu_attach.c optional rtwn_usb dev/rtwn/rtl8188e/usb/r88eu_init.c optional rtwn_usb dev/rtwn/rtl8188e/usb/r88eu_rx.c optional rtwn_usb # RTL8192C dev/rtwn/rtl8192c/r92c_attach.c optional rtwn dev/rtwn/rtl8192c/r92c_beacon.c optional rtwn dev/rtwn/rtl8192c/r92c_calib.c optional rtwn dev/rtwn/rtl8192c/r92c_chan.c optional rtwn dev/rtwn/rtl8192c/r92c_fw.c optional rtwn dev/rtwn/rtl8192c/r92c_init.c optional rtwn dev/rtwn/rtl8192c/r92c_rf.c optional rtwn dev/rtwn/rtl8192c/r92c_rom.c optional rtwn dev/rtwn/rtl8192c/r92c_rx.c optional rtwn dev/rtwn/rtl8192c/r92c_tx.c optional rtwn dev/rtwn/rtl8192c/pci/r92ce_attach.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_calib.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_fw.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_init.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_led.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_rx.c optional rtwn_pci pci dev/rtwn/rtl8192c/pci/r92ce_tx.c optional rtwn_pci pci dev/rtwn/rtl8192c/usb/r92cu_attach.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_init.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_led.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_rx.c optional rtwn_usb dev/rtwn/rtl8192c/usb/r92cu_tx.c optional rtwn_usb # RTL8812A dev/rtwn/rtl8812a/r12a_beacon.c optional rtwn dev/rtwn/rtl8812a/r12a_calib.c optional rtwn dev/rtwn/rtl8812a/r12a_caps.c optional rtwn dev/rtwn/rtl8812a/r12a_chan.c optional rtwn dev/rtwn/rtl8812a/r12a_fw.c optional rtwn dev/rtwn/rtl8812a/r12a_init.c optional rtwn dev/rtwn/rtl8812a/r12a_led.c optional rtwn dev/rtwn/rtl8812a/r12a_rf.c optional rtwn dev/rtwn/rtl8812a/r12a_rom.c optional rtwn dev/rtwn/rtl8812a/r12a_rx.c optional rtwn dev/rtwn/rtl8812a/r12a_tx.c optional rtwn dev/rtwn/rtl8812a/usb/r12au_attach.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_init.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_rx.c optional rtwn_usb dev/rtwn/rtl8812a/usb/r12au_tx.c optional rtwn_usb # RTL8821A dev/rtwn/rtl8821a/r21a_beacon.c optional rtwn dev/rtwn/rtl8821a/r21a_calib.c optional rtwn dev/rtwn/rtl8821a/r21a_chan.c optional rtwn dev/rtwn/rtl8821a/r21a_fw.c optional rtwn dev/rtwn/rtl8821a/r21a_init.c optional rtwn dev/rtwn/rtl8821a/r21a_led.c optional rtwn dev/rtwn/rtl8821a/r21a_rom.c optional rtwn dev/rtwn/rtl8821a/r21a_rx.c optional rtwn dev/rtwn/rtl8821a/usb/r21au_attach.c optional rtwn_usb dev/rtwn/rtl8821a/usb/r21au_init.c optional rtwn_usb rtwn-rtl8188eufw.c optional rtwn-rtl8188eufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8188eufw.fw:rtwn-rtl8188eufw:111 -mrtwn-rtl8188eufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8188eufw.c" rtwn-rtl8188eufw.fwo optional rtwn-rtl8188eufw | rtwnfw \ dependency "rtwn-rtl8188eufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8188eufw.fwo" rtwn-rtl8188eufw.fw optional rtwn-rtl8188eufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8188eufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8188eufw.fw" rtwn-rtl8192cfwE.c optional rtwn-rtl8192cfwE | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE.fw:rtwn-rtl8192cfwE:111 -mrtwn-rtl8192cfwE -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE.c" rtwn-rtl8192cfwE.fwo optional rtwn-rtl8192cfwE | rtwnfw \ dependency "rtwn-rtl8192cfwE.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE.fwo" rtwn-rtl8192cfwE.fw optional rtwn-rtl8192cfwE | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE.fw" rtwn-rtl8192cfwE_B.c optional rtwn-rtl8192cfwE_B | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwE_B.fw:rtwn-rtl8192cfwE_B:111 -mrtwn-rtl8192cfwE_B -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwE_B.c" rtwn-rtl8192cfwE_B.fwo optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "rtwn-rtl8192cfwE_B.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fwo" rtwn-rtl8192cfwE_B.fw optional rtwn-rtl8192cfwE_B | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwE_B.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwE_B.fw" rtwn-rtl8192cfwT.c optional rtwn-rtl8192cfwT | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwT.fw:rtwn-rtl8192cfwT:111 -mrtwn-rtl8192cfwT -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwT.c" rtwn-rtl8192cfwT.fwo optional rtwn-rtl8192cfwT | rtwnfw \ dependency "rtwn-rtl8192cfwT.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwT.fwo" rtwn-rtl8192cfwT.fw optional rtwn-rtl8192cfwT | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwT.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwT.fw" rtwn-rtl8192cfwU.c optional rtwn-rtl8192cfwU | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8192cfwU.fw:rtwn-rtl8192cfwU:111 -mrtwn-rtl8192cfwU -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8192cfwU.c" rtwn-rtl8192cfwU.fwo optional rtwn-rtl8192cfwU | rtwnfw \ dependency "rtwn-rtl8192cfwU.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8192cfwU.fwo" rtwn-rtl8192cfwU.fw optional rtwn-rtl8192cfwU | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8192cfwU.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8192cfwU.fw" rtwn-rtl8812aufw.c optional rtwn-rtl8812aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8812aufw.fw:rtwn-rtl8812aufw:111 -mrtwn-rtl8812aufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8812aufw.c" rtwn-rtl8812aufw.fwo optional rtwn-rtl8812aufw | rtwnfw \ dependency "rtwn-rtl8812aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8812aufw.fwo" rtwn-rtl8812aufw.fw optional rtwn-rtl8812aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8812aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8812aufw.fw" rtwn-rtl8821aufw.c optional rtwn-rtl8821aufw | rtwnfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rtwn-rtl8821aufw.fw:rtwn-rtl8821aufw:111 -mrtwn-rtl8821aufw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rtwn-rtl8821aufw.c" rtwn-rtl8821aufw.fwo optional rtwn-rtl8821aufw | rtwnfw \ dependency "rtwn-rtl8821aufw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rtwn-rtl8821aufw.fwo" rtwn-rtl8821aufw.fw optional rtwn-rtl8821aufw | rtwnfw \ dependency "$S/contrib/dev/rtwn/rtwn-rtl8821aufw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rtwn-rtl8821aufw.fw" dev/safe/safe.c optional safe dev/scc/scc_if.m optional scc dev/scc/scc_bfe_ebus.c optional scc ebus dev/scc/scc_bfe_quicc.c optional scc quicc dev/scc/scc_bfe_sbus.c optional scc fhc | scc sbus dev/scc/scc_core.c optional scc dev/scc/scc_dev_quicc.c optional scc quicc dev/scc/scc_dev_sab82532.c optional scc dev/scc/scc_dev_z8530.c optional scc dev/sdhci/sdhci.c optional sdhci dev/sdhci/sdhci_if.m optional sdhci dev/sdhci/sdhci_pci.c optional sdhci pci dev/sf/if_sf.c optional sf pci dev/sge/if_sge.c optional sge pci dev/siba/siba_bwn.c optional siba_bwn pci dev/siba/siba_core.c optional siba_bwn pci dev/siis/siis.c optional siis pci dev/sis/if_sis.c optional sis pci dev/sk/if_sk.c optional sk pci dev/smbus/smb.c optional smb dev/smbus/smbconf.c optional smbus dev/smbus/smbus.c optional smbus dev/smbus/smbus_if.m optional smbus dev/smc/if_smc.c optional smc dev/smc/if_smc_fdt.c optional smc fdt dev/sn/if_sn.c optional sn dev/sn/if_sn_isa.c optional sn isa dev/sn/if_sn_pccard.c optional sn pccard dev/snp/snp.c optional snp dev/sound/clone.c optional sound dev/sound/unit.c optional sound dev/sound/isa/ad1816.c optional snd_ad1816 isa dev/sound/isa/ess.c optional snd_ess isa dev/sound/isa/gusc.c optional snd_gusc isa dev/sound/isa/mss.c optional snd_mss isa dev/sound/isa/sb16.c optional snd_sb16 isa dev/sound/isa/sb8.c optional snd_sb8 isa dev/sound/isa/sbc.c optional snd_sbc isa dev/sound/isa/sndbuf_dma.c optional sound isa dev/sound/pci/als4000.c optional snd_als4000 pci dev/sound/pci/atiixp.c optional snd_atiixp pci dev/sound/pci/cmi.c optional snd_cmi pci dev/sound/pci/cs4281.c optional snd_cs4281 pci dev/sound/pci/csa.c optional snd_csa pci dev/sound/pci/csapcm.c optional snd_csa pci dev/sound/pci/ds1.c optional snd_ds1 pci dev/sound/pci/emu10k1.c optional snd_emu10k1 pci dev/sound/pci/emu10kx.c optional snd_emu10kx pci dev/sound/pci/emu10kx-pcm.c optional snd_emu10kx pci dev/sound/pci/emu10kx-midi.c optional snd_emu10kx pci dev/sound/pci/envy24.c optional snd_envy24 pci dev/sound/pci/envy24ht.c optional snd_envy24ht pci dev/sound/pci/es137x.c optional snd_es137x pci dev/sound/pci/fm801.c optional snd_fm801 pci dev/sound/pci/ich.c optional snd_ich pci dev/sound/pci/maestro.c optional snd_maestro pci dev/sound/pci/maestro3.c optional snd_maestro3 pci dev/sound/pci/neomagic.c optional snd_neomagic pci dev/sound/pci/solo.c optional snd_solo pci dev/sound/pci/spicds.c optional snd_spicds pci dev/sound/pci/t4dwave.c optional snd_t4dwave pci dev/sound/pci/via8233.c optional snd_via8233 pci dev/sound/pci/via82c686.c optional snd_via82c686 pci dev/sound/pci/vibes.c optional snd_vibes pci dev/sound/pci/hda/hdaa.c optional snd_hda pci dev/sound/pci/hda/hdaa_patches.c optional snd_hda pci dev/sound/pci/hda/hdac.c optional snd_hda pci dev/sound/pci/hda/hdac_if.m optional snd_hda pci dev/sound/pci/hda/hdacc.c optional snd_hda pci dev/sound/pci/hdspe.c optional snd_hdspe pci dev/sound/pci/hdspe-pcm.c optional snd_hdspe pci dev/sound/pcm/ac97.c optional sound dev/sound/pcm/ac97_if.m optional sound dev/sound/pcm/ac97_patch.c optional sound dev/sound/pcm/buffer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/channel.c optional sound dev/sound/pcm/channel_if.m optional sound dev/sound/pcm/dsp.c optional sound dev/sound/pcm/feeder.c optional sound dev/sound/pcm/feeder_chain.c optional sound dev/sound/pcm/feeder_eq.c optional sound \ dependency "feeder_eq_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_if.m optional sound dev/sound/pcm/feeder_format.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_matrix.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_mixer.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_rate.c optional sound \ dependency "feeder_rate_gen.h" \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/feeder_volume.c optional sound \ dependency "snd_fxdiv_gen.h" dev/sound/pcm/mixer.c optional sound dev/sound/pcm/mixer_if.m optional sound dev/sound/pcm/sndstat.c optional sound dev/sound/pcm/sound.c optional sound dev/sound/pcm/vchan.c optional sound dev/sound/usb/uaudio.c optional snd_uaudio usb dev/sound/usb/uaudio_pcm.c optional snd_uaudio usb dev/sound/midi/midi.c optional sound dev/sound/midi/mpu401.c optional sound dev/sound/midi/mpu_if.m optional sound dev/sound/midi/mpufoi_if.m optional sound dev/sound/midi/sequencer.c optional sound dev/sound/midi/synth_if.m optional sound dev/spibus/ofw_spibus.c optional fdt spibus dev/spibus/spibus.c optional spibus \ dependency "spibus_if.h" dev/spibus/spigen.c optional spigen dev/spibus/spibus_if.m optional spibus dev/ste/if_ste.c optional ste pci dev/stg/tmc18c30.c optional stg dev/stg/tmc18c30_isa.c optional stg isa dev/stg/tmc18c30_pccard.c optional stg pccard dev/stg/tmc18c30_pci.c optional stg pci dev/stg/tmc18c30_subr.c optional stg dev/stge/if_stge.c optional stge dev/streams/streams.c optional streams dev/sym/sym_hipd.c optional sym \ dependency "$S/dev/sym/sym_{conf,defs}.h" dev/syscons/blank/blank_saver.c optional blank_saver dev/syscons/daemon/daemon_saver.c optional daemon_saver dev/syscons/dragon/dragon_saver.c optional dragon_saver dev/syscons/fade/fade_saver.c optional fade_saver dev/syscons/fire/fire_saver.c optional fire_saver dev/syscons/green/green_saver.c optional green_saver dev/syscons/logo/logo.c optional logo_saver dev/syscons/logo/logo_saver.c optional logo_saver dev/syscons/rain/rain_saver.c optional rain_saver dev/syscons/schistory.c optional sc dev/syscons/scmouse.c optional sc dev/syscons/scterm.c optional sc dev/syscons/scvidctl.c optional sc dev/syscons/snake/snake_saver.c optional snake_saver dev/syscons/star/star_saver.c optional star_saver dev/syscons/syscons.c optional sc dev/syscons/sysmouse.c optional sc dev/syscons/warp/warp_saver.c optional warp_saver dev/tdfx/tdfx_linux.c optional tdfx_linux tdfx compat_linux dev/tdfx/tdfx_pci.c optional tdfx pci dev/ti/if_ti.c optional ti pci dev/tl/if_tl.c optional tl pci dev/trm/trm.c optional trm dev/twa/tw_cl_init.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_intr.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_io.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_cl_misc.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_osl_cam.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twa/tw_osl_freebsd.c optional twa \ compile-with "${NORMAL_C} -I$S/dev/twa" dev/twe/twe.c optional twe dev/twe/twe_freebsd.c optional twe dev/tws/tws.c optional tws dev/tws/tws_cam.c optional tws dev/tws/tws_hdm.c optional tws dev/tws/tws_services.c optional tws dev/tws/tws_user.c optional tws dev/tx/if_tx.c optional tx dev/txp/if_txp.c optional txp dev/uart/uart_bus_acpi.c optional uart acpi dev/uart/uart_bus_ebus.c optional uart ebus dev/uart/uart_bus_fdt.c optional uart fdt dev/uart/uart_bus_isa.c optional uart isa dev/uart/uart_bus_pccard.c optional uart pccard dev/uart/uart_bus_pci.c optional uart pci dev/uart/uart_bus_puc.c optional uart puc dev/uart/uart_bus_scc.c optional uart scc dev/uart/uart_core.c optional uart dev/uart/uart_dbg.c optional uart gdb dev/uart/uart_dev_ns8250.c optional uart uart_ns8250 | uart uart_snps dev/uart/uart_dev_pl011.c optional uart pl011 dev/uart/uart_dev_quicc.c optional uart quicc dev/uart/uart_dev_sab82532.c optional uart uart_sab82532 dev/uart/uart_dev_sab82532.c optional uart scc dev/uart/uart_dev_snps.c optional uart uart_snps fdt dev/uart/uart_dev_z8530.c optional uart uart_z8530 dev/uart/uart_dev_z8530.c optional uart scc dev/uart/uart_if.m optional uart dev/uart/uart_subr.c optional uart dev/uart/uart_tty.c optional uart dev/ubsec/ubsec.c optional ubsec # # USB controller drivers # dev/usb/controller/at91dci.c optional at91dci dev/usb/controller/at91dci_atmelarm.c optional at91dci at91rm9200 dev/usb/controller/musb_otg.c optional musb dev/usb/controller/musb_otg_atmelarm.c optional musb at91rm9200 dev/usb/controller/dwc_otg.c optional dwcotg dev/usb/controller/dwc_otg_fdt.c optional dwcotg fdt dev/usb/controller/ehci.c optional ehci dev/usb/controller/ehci_pci.c optional ehci pci dev/usb/controller/ohci.c optional ohci dev/usb/controller/ohci_pci.c optional ohci pci dev/usb/controller/uhci.c optional uhci dev/usb/controller/uhci_pci.c optional uhci pci dev/usb/controller/xhci.c optional xhci dev/usb/controller/xhci_pci.c optional xhci pci dev/usb/controller/saf1761_otg.c optional saf1761otg dev/usb/controller/saf1761_otg_fdt.c optional saf1761otg fdt dev/usb/controller/uss820dci.c optional uss820dci dev/usb/controller/uss820dci_atmelarm.c optional uss820dci at91rm9200 dev/usb/controller/usb_controller.c optional usb # # USB storage drivers # dev/usb/storage/umass.c optional umass dev/usb/storage/urio.c optional urio dev/usb/storage/ustorage_fs.c optional usfs # # USB core # dev/usb/usb_busdma.c optional usb dev/usb/usb_core.c optional usb dev/usb/usb_debug.c optional usb dev/usb/usb_dev.c optional usb dev/usb/usb_device.c optional usb dev/usb/usb_dynamic.c optional usb dev/usb/usb_error.c optional usb dev/usb/usb_generic.c optional usb dev/usb/usb_handle_request.c optional usb dev/usb/usb_hid.c optional usb dev/usb/usb_hub.c optional usb dev/usb/usb_if.m optional usb dev/usb/usb_lookup.c optional usb dev/usb/usb_mbuf.c optional usb dev/usb/usb_msctest.c optional usb dev/usb/usb_parse.c optional usb dev/usb/usb_pf.c optional usb dev/usb/usb_process.c optional usb dev/usb/usb_request.c optional usb dev/usb/usb_transfer.c optional usb dev/usb/usb_util.c optional usb # # USB network drivers # dev/usb/net/if_aue.c optional aue dev/usb/net/if_axe.c optional axe dev/usb/net/if_axge.c optional axge dev/usb/net/if_cdce.c optional cdce dev/usb/net/if_cue.c optional cue dev/usb/net/if_ipheth.c optional ipheth dev/usb/net/if_kue.c optional kue dev/usb/net/if_mos.c optional mos dev/usb/net/if_rue.c optional rue dev/usb/net/if_smsc.c optional smsc dev/usb/net/if_udav.c optional udav dev/usb/net/if_ure.c optional ure dev/usb/net/if_usie.c optional usie dev/usb/net/if_urndis.c optional urndis dev/usb/net/ruephy.c optional rue dev/usb/net/usb_ethernet.c optional uether | aue | axe | axge | cdce | \ cue | ipheth | kue | mos | rue | \ smsc | udav | ure | urndis dev/usb/net/uhso.c optional uhso # # USB WLAN drivers # dev/usb/wlan/if_rsu.c optional rsu rsu-rtl8712fw.c optional rsu-rtl8712fw | rsufw \ compile-with "${AWK} -f $S/tools/fw_stub.awk rsu-rtl8712fw.fw:rsu-rtl8712fw:120 -mrsu-rtl8712fw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "rsu-rtl8712fw.c" rsu-rtl8712fw.fwo optional rsu-rtl8712fw | rsufw \ dependency "rsu-rtl8712fw.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "rsu-rtl8712fw.fwo" rsu-rtl8712fw.fw optional rsu-rtl8712.fw | rsufw \ dependency "$S/contrib/dev/rsu/rsu-rtl8712fw.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "rsu-rtl8712fw.fw" dev/usb/wlan/if_rum.c optional rum dev/usb/wlan/if_run.c optional run runfw.c optional runfw \ compile-with "${AWK} -f $S/tools/fw_stub.awk run.fw:runfw -mrunfw -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "runfw.c" runfw.fwo optional runfw \ dependency "run.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "runfw.fwo" run.fw optional runfw \ dependency "$S/contrib/dev/run/rt2870.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "run.fw" dev/usb/wlan/if_uath.c optional uath dev/usb/wlan/if_upgt.c optional upgt dev/usb/wlan/if_ural.c optional ural dev/usb/wlan/if_urtw.c optional urtw dev/usb/wlan/if_zyd.c optional zyd # # USB serial and parallel port drivers # dev/usb/serial/u3g.c optional u3g dev/usb/serial/uark.c optional uark dev/usb/serial/ubsa.c optional ubsa dev/usb/serial/ubser.c optional ubser dev/usb/serial/uchcom.c optional uchcom dev/usb/serial/ucycom.c optional ucycom dev/usb/serial/ufoma.c optional ufoma dev/usb/serial/uftdi.c optional uftdi dev/usb/serial/ugensa.c optional ugensa dev/usb/serial/uipaq.c optional uipaq dev/usb/serial/ulpt.c optional ulpt dev/usb/serial/umcs.c optional umcs dev/usb/serial/umct.c optional umct dev/usb/serial/umodem.c optional umodem dev/usb/serial/umoscom.c optional umoscom dev/usb/serial/uplcom.c optional uplcom dev/usb/serial/uslcom.c optional uslcom dev/usb/serial/uvisor.c optional uvisor dev/usb/serial/uvscom.c optional uvscom dev/usb/serial/usb_serial.c optional ucom | u3g | uark | ubsa | ubser | \ uchcom | ucycom | ufoma | uftdi | \ ugensa | uipaq | umcs | umct | \ umodem | umoscom | uplcom | usie | \ uslcom | uvisor | uvscom # # USB misc drivers # dev/usb/misc/ufm.c optional ufm dev/usb/misc/udbp.c optional udbp dev/usb/misc/ugold.c optional ugold dev/usb/misc/uled.c optional uled # # USB input drivers # dev/usb/input/atp.c optional atp dev/usb/input/uep.c optional uep dev/usb/input/uhid.c optional uhid dev/usb/input/ukbd.c optional ukbd dev/usb/input/ums.c optional ums dev/usb/input/wsp.c optional wsp # # USB quirks # dev/usb/quirk/usb_quirk.c optional usb # # USB templates # dev/usb/template/usb_template.c optional usb_template dev/usb/template/usb_template_audio.c optional usb_template dev/usb/template/usb_template_cdce.c optional usb_template dev/usb/template/usb_template_kbd.c optional usb_template dev/usb/template/usb_template_modem.c optional usb_template dev/usb/template/usb_template_mouse.c optional usb_template dev/usb/template/usb_template_msc.c optional usb_template dev/usb/template/usb_template_mtp.c optional usb_template dev/usb/template/usb_template_phone.c optional usb_template dev/usb/template/usb_template_serialnet.c optional usb_template dev/usb/template/usb_template_midi.c optional usb_template # # USB video drivers # dev/usb/video/udl.c optional udl # # USB END # dev/videomode/videomode.c optional videomode dev/videomode/edid.c optional videomode dev/videomode/pickmode.c optional videomode dev/videomode/vesagtf.c optional videomode dev/utopia/idtphy.c optional utopia dev/utopia/suni.c optional utopia dev/utopia/utopia.c optional utopia dev/vge/if_vge.c optional vge dev/viapm/viapm.c optional viapm pci dev/virtio/virtio.c optional virtio dev/virtio/virtqueue.c optional virtio dev/virtio/virtio_bus_if.m optional virtio dev/virtio/virtio_if.m optional virtio dev/virtio/pci/virtio_pci.c optional virtio_pci dev/virtio/mmio/virtio_mmio.c optional virtio_mmio fdt dev/virtio/mmio/virtio_mmio_if.m optional virtio_mmio fdt dev/virtio/network/if_vtnet.c optional vtnet dev/virtio/block/virtio_blk.c optional virtio_blk dev/virtio/balloon/virtio_balloon.c optional virtio_balloon dev/virtio/scsi/virtio_scsi.c optional virtio_scsi dev/virtio/random/virtio_random.c optional virtio_random dev/virtio/console/virtio_console.c optional virtio_console dev/vkbd/vkbd.c optional vkbd dev/vr/if_vr.c optional vr pci dev/vt/colors/vt_termcolors.c optional vt dev/vt/font/vt_font_default.c optional vt dev/vt/font/vt_mouse_cursor.c optional vt dev/vt/hw/efifb/efifb.c optional vt_efifb dev/vt/hw/fb/vt_fb.c optional vt dev/vt/hw/vga/vt_vga.c optional vt vt_vga dev/vt/logo/logo_freebsd.c optional vt splash dev/vt/logo/logo_beastie.c optional vt splash dev/vt/vt_buf.c optional vt dev/vt/vt_consolectl.c optional vt dev/vt/vt_core.c optional vt dev/vt/vt_cpulogos.c optional vt splash dev/vt/vt_font.c optional vt dev/vt/vt_sysmouse.c optional vt dev/vte/if_vte.c optional vte pci dev/vx/if_vx.c optional vx dev/vx/if_vx_eisa.c optional vx eisa dev/vx/if_vx_pci.c optional vx pci dev/vxge/vxge.c optional vxge dev/vxge/vxgehal/vxgehal-ifmsg.c optional vxge dev/vxge/vxgehal/vxgehal-mrpcim.c optional vxge dev/vxge/vxgehal/vxge-queue.c optional vxge dev/vxge/vxgehal/vxgehal-ring.c optional vxge dev/vxge/vxgehal/vxgehal-swapper.c optional vxge dev/vxge/vxgehal/vxgehal-mgmt.c optional vxge dev/vxge/vxgehal/vxgehal-srpcim.c optional vxge dev/vxge/vxgehal/vxgehal-config.c optional vxge dev/vxge/vxgehal/vxgehal-blockpool.c optional vxge dev/vxge/vxgehal/vxgehal-doorbells.c optional vxge dev/vxge/vxgehal/vxgehal-mgmtaux.c optional vxge dev/vxge/vxgehal/vxgehal-device.c optional vxge dev/vxge/vxgehal/vxgehal-mm.c optional vxge dev/vxge/vxgehal/vxgehal-driver.c optional vxge dev/vxge/vxgehal/vxgehal-virtualpath.c optional vxge dev/vxge/vxgehal/vxgehal-channel.c optional vxge dev/vxge/vxgehal/vxgehal-fifo.c optional vxge dev/watchdog/watchdog.c standard dev/wb/if_wb.c optional wb pci dev/wi/if_wi.c optional wi dev/wi/if_wi_pccard.c optional wi pccard dev/wi/if_wi_pci.c optional wi pci dev/wpi/if_wpi.c optional wpi pci wpifw.c optional wpifw \ compile-with "${AWK} -f $S/tools/fw_stub.awk wpi.fw:wpifw:153229 -mwpi -c${.TARGET}" \ no-implicit-rule before-depend local \ clean "wpifw.c" wpifw.fwo optional wpifw \ dependency "wpi.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "wpifw.fwo" wpi.fw optional wpifw \ dependency "$S/contrib/dev/wpi/iwlwifi-3945-15.32.2.9.fw.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "wpi.fw" dev/xe/if_xe.c optional xe dev/xe/if_xe_pccard.c optional xe pccard dev/xen/balloon/balloon.c optional xenhvm dev/xen/blkfront/blkfront.c optional xenhvm dev/xen/blkback/blkback.c optional xenhvm dev/xen/console/xen_console.c optional xenhvm dev/xen/control/control.c optional xenhvm dev/xen/grant_table/grant_table.c optional xenhvm dev/xen/netback/netback.c optional xenhvm dev/xen/netfront/netfront.c optional xenhvm dev/xen/xenpci/xenpci.c optional xenpci dev/xen/timer/timer.c optional xenhvm dev/xen/pvcpu/pvcpu.c optional xenhvm dev/xen/xenstore/xenstore.c optional xenhvm dev/xen/xenstore/xenstore_dev.c optional xenhvm dev/xen/xenstore/xenstored_dev.c optional xenhvm dev/xen/evtchn/evtchn_dev.c optional xenhvm dev/xen/privcmd/privcmd.c optional xenhvm dev/xen/gntdev/gntdev.c optional xenhvm dev/xen/debug/debug.c optional xenhvm dev/xl/if_xl.c optional xl pci dev/xl/xlphy.c optional xl pci fs/autofs/autofs.c optional autofs fs/autofs/autofs_vfsops.c optional autofs fs/autofs/autofs_vnops.c optional autofs fs/deadfs/dead_vnops.c standard fs/devfs/devfs_devs.c standard fs/devfs/devfs_dir.c standard fs/devfs/devfs_rule.c standard fs/devfs/devfs_vfsops.c standard fs/devfs/devfs_vnops.c standard fs/fdescfs/fdesc_vfsops.c optional fdescfs fs/fdescfs/fdesc_vnops.c optional fdescfs fs/fifofs/fifo_vnops.c standard fs/cuse/cuse.c optional cuse fs/fuse/fuse_device.c optional fuse fs/fuse/fuse_file.c optional fuse fs/fuse/fuse_internal.c optional fuse fs/fuse/fuse_io.c optional fuse fs/fuse/fuse_ipc.c optional fuse fs/fuse/fuse_main.c optional fuse fs/fuse/fuse_node.c optional fuse fs/fuse/fuse_vfsops.c optional fuse fs/fuse/fuse_vnops.c optional fuse fs/msdosfs/msdosfs_conv.c optional msdosfs fs/msdosfs/msdosfs_denode.c optional msdosfs fs/msdosfs/msdosfs_fat.c optional msdosfs fs/msdosfs/msdosfs_fileno.c optional msdosfs fs/msdosfs/msdosfs_iconv.c optional msdosfs_iconv fs/msdosfs/msdosfs_lookup.c optional msdosfs fs/msdosfs/msdosfs_vfsops.c optional msdosfs fs/msdosfs/msdosfs_vnops.c optional msdosfs fs/nandfs/bmap.c optional nandfs fs/nandfs/nandfs_alloc.c optional nandfs fs/nandfs/nandfs_bmap.c optional nandfs fs/nandfs/nandfs_buffer.c optional nandfs fs/nandfs/nandfs_cleaner.c optional nandfs fs/nandfs/nandfs_cpfile.c optional nandfs fs/nandfs/nandfs_dat.c optional nandfs fs/nandfs/nandfs_dir.c optional nandfs fs/nandfs/nandfs_ifile.c optional nandfs fs/nandfs/nandfs_segment.c optional nandfs fs/nandfs/nandfs_subr.c optional nandfs fs/nandfs/nandfs_sufile.c optional nandfs fs/nandfs/nandfs_vfsops.c optional nandfs fs/nandfs/nandfs_vnops.c optional nandfs fs/nfs/nfs_commonkrpc.c optional nfscl | nfsd fs/nfs/nfs_commonsubs.c optional nfscl | nfsd fs/nfs/nfs_commonport.c optional nfscl | nfsd fs/nfs/nfs_commonacl.c optional nfscl | nfsd fs/nfsclient/nfs_clcomsubs.c optional nfscl fs/nfsclient/nfs_clsubs.c optional nfscl fs/nfsclient/nfs_clstate.c optional nfscl fs/nfsclient/nfs_clkrpc.c optional nfscl fs/nfsclient/nfs_clrpcops.c optional nfscl fs/nfsclient/nfs_clvnops.c optional nfscl fs/nfsclient/nfs_clnode.c optional nfscl fs/nfsclient/nfs_clvfsops.c optional nfscl fs/nfsclient/nfs_clport.c optional nfscl fs/nfsclient/nfs_clbio.c optional nfscl fs/nfsclient/nfs_clnfsiod.c optional nfscl fs/nfsserver/nfs_fha_new.c optional nfsd inet fs/nfsserver/nfs_nfsdsocket.c optional nfsd inet fs/nfsserver/nfs_nfsdsubs.c optional nfsd inet fs/nfsserver/nfs_nfsdstate.c optional nfsd inet fs/nfsserver/nfs_nfsdkrpc.c optional nfsd inet fs/nfsserver/nfs_nfsdserv.c optional nfsd inet fs/nfsserver/nfs_nfsdport.c optional nfsd inet fs/nfsserver/nfs_nfsdcache.c optional nfsd inet fs/nullfs/null_subr.c optional nullfs fs/nullfs/null_vfsops.c optional nullfs fs/nullfs/null_vnops.c optional nullfs fs/procfs/procfs.c optional procfs fs/procfs/procfs_ctl.c optional procfs fs/procfs/procfs_dbregs.c optional procfs fs/procfs/procfs_fpregs.c optional procfs fs/procfs/procfs_ioctl.c optional procfs fs/procfs/procfs_map.c optional procfs fs/procfs/procfs_mem.c optional procfs fs/procfs/procfs_note.c optional procfs fs/procfs/procfs_osrel.c optional procfs fs/procfs/procfs_regs.c optional procfs fs/procfs/procfs_rlimit.c optional procfs fs/procfs/procfs_status.c optional procfs fs/procfs/procfs_type.c optional procfs fs/pseudofs/pseudofs.c optional pseudofs fs/pseudofs/pseudofs_fileno.c optional pseudofs fs/pseudofs/pseudofs_vncache.c optional pseudofs fs/pseudofs/pseudofs_vnops.c optional pseudofs fs/smbfs/smbfs_io.c optional smbfs fs/smbfs/smbfs_node.c optional smbfs fs/smbfs/smbfs_smb.c optional smbfs fs/smbfs/smbfs_subr.c optional smbfs fs/smbfs/smbfs_vfsops.c optional smbfs fs/smbfs/smbfs_vnops.c optional smbfs fs/udf/osta.c optional udf fs/udf/udf_iconv.c optional udf_iconv fs/udf/udf_vfsops.c optional udf fs/udf/udf_vnops.c optional udf fs/unionfs/union_subr.c optional unionfs fs/unionfs/union_vfsops.c optional unionfs fs/unionfs/union_vnops.c optional unionfs fs/tmpfs/tmpfs_vnops.c optional tmpfs fs/tmpfs/tmpfs_fifoops.c optional tmpfs fs/tmpfs/tmpfs_vfsops.c optional tmpfs fs/tmpfs/tmpfs_subr.c optional tmpfs gdb/gdb_cons.c optional gdb gdb/gdb_main.c optional gdb gdb/gdb_packet.c optional gdb geom/bde/g_bde.c optional geom_bde geom/bde/g_bde_crypt.c optional geom_bde geom/bde/g_bde_lock.c optional geom_bde geom/bde/g_bde_work.c optional geom_bde geom/cache/g_cache.c optional geom_cache geom/concat/g_concat.c optional geom_concat geom/eli/g_eli.c optional geom_eli geom/eli/g_eli_crypto.c optional geom_eli geom/eli/g_eli_ctl.c optional geom_eli geom/eli/g_eli_hmac.c optional geom_eli geom/eli/g_eli_integrity.c optional geom_eli geom/eli/g_eli_key.c optional geom_eli geom/eli/g_eli_key_cache.c optional geom_eli geom/eli/g_eli_privacy.c optional geom_eli geom/eli/pkcs5v2.c optional geom_eli geom/gate/g_gate.c optional geom_gate geom/geom_aes.c optional geom_aes geom/geom_bsd.c optional geom_bsd geom/geom_bsd_enc.c optional geom_bsd | geom_part_bsd geom/geom_ccd.c optional ccd | geom_ccd geom/geom_ctl.c standard geom/geom_dev.c standard geom/geom_disk.c standard geom/geom_dump.c standard geom/geom_event.c standard geom/geom_fox.c optional geom_fox geom/geom_flashmap.c optional fdt cfi | fdt nand | fdt mx25l geom/geom_io.c standard geom/geom_kern.c standard geom/geom_map.c optional geom_map geom/geom_mbr.c optional geom_mbr geom/geom_mbr_enc.c optional geom_mbr geom/geom_pc98.c optional geom_pc98 geom/geom_pc98_enc.c optional geom_pc98 geom/geom_redboot.c optional geom_redboot geom/geom_slice.c standard geom/geom_subr.c standard geom/geom_sunlabel.c optional geom_sunlabel geom/geom_sunlabel_enc.c optional geom_sunlabel geom/geom_vfs.c standard geom/geom_vol_ffs.c optional geom_vol geom/journal/g_journal.c optional geom_journal geom/journal/g_journal_ufs.c optional geom_journal geom/label/g_label.c optional geom_label | geom_label_gpt geom/label/g_label_ext2fs.c optional geom_label geom/label/g_label_iso9660.c optional geom_label geom/label/g_label_msdosfs.c optional geom_label geom/label/g_label_ntfs.c optional geom_label geom/label/g_label_reiserfs.c optional geom_label geom/label/g_label_ufs.c optional geom_label geom/label/g_label_gpt.c optional geom_label | geom_label_gpt geom/label/g_label_disk_ident.c optional geom_label geom/linux_lvm/g_linux_lvm.c optional geom_linux_lvm geom/mirror/g_mirror.c optional geom_mirror geom/mirror/g_mirror_ctl.c optional geom_mirror geom/mountver/g_mountver.c optional geom_mountver geom/multipath/g_multipath.c optional geom_multipath geom/nop/g_nop.c optional geom_nop geom/part/g_part.c standard geom/part/g_part_if.m standard geom/part/g_part_apm.c optional geom_part_apm geom/part/g_part_bsd.c optional geom_part_bsd geom/part/g_part_bsd64.c optional geom_part_bsd64 geom/part/g_part_ebr.c optional geom_part_ebr geom/part/g_part_gpt.c optional geom_part_gpt geom/part/g_part_ldm.c optional geom_part_ldm geom/part/g_part_mbr.c optional geom_part_mbr geom/part/g_part_pc98.c optional geom_part_pc98 geom/part/g_part_vtoc8.c optional geom_part_vtoc8 geom/raid/g_raid.c optional geom_raid geom/raid/g_raid_ctl.c optional geom_raid geom/raid/g_raid_md_if.m optional geom_raid geom/raid/g_raid_tr_if.m optional geom_raid geom/raid/md_ddf.c optional geom_raid geom/raid/md_intel.c optional geom_raid geom/raid/md_jmicron.c optional geom_raid geom/raid/md_nvidia.c optional geom_raid geom/raid/md_promise.c optional geom_raid geom/raid/md_sii.c optional geom_raid geom/raid/tr_concat.c optional geom_raid geom/raid/tr_raid0.c optional geom_raid geom/raid/tr_raid1.c optional geom_raid geom/raid/tr_raid1e.c optional geom_raid geom/raid/tr_raid5.c optional geom_raid geom/raid3/g_raid3.c optional geom_raid3 geom/raid3/g_raid3_ctl.c optional geom_raid3 geom/shsec/g_shsec.c optional geom_shsec geom/stripe/g_stripe.c optional geom_stripe contrib/xz-embedded/freebsd/xz_malloc.c \ optional xz_embedded | geom_uzip \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_crc32.c \ optional xz_embedded | geom_uzip \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_bcj.c \ optional xz_embedded | geom_uzip \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_lzma2.c \ optional xz_embedded | geom_uzip \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" contrib/xz-embedded/linux/lib/xz/xz_dec_stream.c \ optional xz_embedded | geom_uzip \ compile-with "${NORMAL_C} -I$S/contrib/xz-embedded/freebsd/ -I$S/contrib/xz-embedded/linux/lib/xz/ -I$S/contrib/xz-embedded/linux/include/linux/" geom/uzip/g_uzip.c optional geom_uzip geom/uzip/g_uzip_lzma.c optional geom_uzip geom/uzip/g_uzip_wrkthr.c optional geom_uzip geom/uzip/g_uzip_zlib.c optional geom_uzip geom/vinum/geom_vinum.c optional geom_vinum geom/vinum/geom_vinum_create.c optional geom_vinum geom/vinum/geom_vinum_drive.c optional geom_vinum geom/vinum/geom_vinum_plex.c optional geom_vinum geom/vinum/geom_vinum_volume.c optional geom_vinum geom/vinum/geom_vinum_subr.c optional geom_vinum geom/vinum/geom_vinum_raid5.c optional geom_vinum geom/vinum/geom_vinum_share.c optional geom_vinum geom/vinum/geom_vinum_list.c optional geom_vinum geom/vinum/geom_vinum_rm.c optional geom_vinum geom/vinum/geom_vinum_init.c optional geom_vinum geom/vinum/geom_vinum_state.c optional geom_vinum geom/vinum/geom_vinum_rename.c optional geom_vinum geom/vinum/geom_vinum_move.c optional geom_vinum geom/vinum/geom_vinum_events.c optional geom_vinum geom/virstor/binstream.c optional geom_virstor geom/virstor/g_virstor.c optional geom_virstor geom/virstor/g_virstor_md.c optional geom_virstor geom/zero/g_zero.c optional geom_zero fs/ext2fs/ext2_alloc.c optional ext2fs fs/ext2fs/ext2_balloc.c optional ext2fs fs/ext2fs/ext2_bmap.c optional ext2fs fs/ext2fs/ext2_extents.c optional ext2fs fs/ext2fs/ext2_inode.c optional ext2fs fs/ext2fs/ext2_inode_cnv.c optional ext2fs fs/ext2fs/ext2_hash.c optional ext2fs fs/ext2fs/ext2_htree.c optional ext2fs fs/ext2fs/ext2_lookup.c optional ext2fs fs/ext2fs/ext2_subr.c optional ext2fs fs/ext2fs/ext2_vfsops.c optional ext2fs fs/ext2fs/ext2_vnops.c optional ext2fs # isa/isa_if.m standard isa/isa_common.c optional isa isa/isahint.c optional isa isa/pnp.c optional isa isapnp isa/pnpparse.c optional isa isapnp fs/cd9660/cd9660_bmap.c optional cd9660 fs/cd9660/cd9660_lookup.c optional cd9660 fs/cd9660/cd9660_node.c optional cd9660 fs/cd9660/cd9660_rrip.c optional cd9660 fs/cd9660/cd9660_util.c optional cd9660 fs/cd9660/cd9660_vfsops.c optional cd9660 fs/cd9660/cd9660_vnops.c optional cd9660 fs/cd9660/cd9660_iconv.c optional cd9660_iconv kern/bus_if.m standard kern/clock_if.m standard kern/cpufreq_if.m standard kern/device_if.m standard kern/imgact_binmisc.c optional imagact_binmisc kern/imgact_elf.c standard kern/imgact_elf32.c optional compat_freebsd32 kern/imgact_shell.c standard kern/inflate.c optional gzip kern/init_main.c standard kern/init_sysent.c standard kern/ksched.c optional _kposix_priority_scheduling kern/kern_acct.c standard kern/kern_alq.c optional alq kern/kern_clock.c standard kern/kern_condvar.c standard kern/kern_conf.c standard kern/kern_cons.c standard kern/kern_cpu.c standard kern/kern_cpuset.c standard kern/kern_context.c standard kern/kern_descrip.c standard kern/kern_dtrace.c optional kdtrace_hooks kern/kern_dump.c standard kern/kern_environment.c standard kern/kern_et.c standard kern/kern_event.c standard kern/kern_exec.c standard kern/kern_exit.c standard kern/kern_fail.c standard kern/kern_ffclock.c standard kern/kern_fork.c standard kern/kern_gzio.c optional gzio kern/kern_hhook.c standard kern/kern_idle.c standard kern/kern_intr.c standard kern/kern_jail.c standard kern/kern_khelp.c standard kern/kern_kthread.c standard kern/kern_ktr.c optional ktr kern/kern_ktrace.c standard kern/kern_linker.c standard kern/kern_lock.c standard kern/kern_lockf.c standard kern/kern_lockstat.c optional kdtrace_hooks kern/kern_loginclass.c standard kern/kern_malloc.c standard kern/kern_mbuf.c standard kern/kern_mib.c standard kern/kern_module.c standard kern/kern_mtxpool.c standard kern/kern_mutex.c standard kern/kern_ntptime.c standard kern/kern_numa.c standard kern/kern_osd.c standard kern/kern_physio.c standard kern/kern_pmc.c standard kern/kern_poll.c optional device_polling kern/kern_priv.c standard kern/kern_proc.c standard kern/kern_procctl.c standard kern/kern_prot.c standard kern/kern_racct.c standard kern/kern_rangelock.c standard kern/kern_rctl.c standard kern/kern_resource.c standard kern/kern_rmlock.c standard kern/kern_rwlock.c standard kern/kern_sdt.c optional kdtrace_hooks kern/kern_sema.c standard kern/kern_sendfile.c standard kern/kern_sharedpage.c standard kern/kern_shutdown.c standard kern/kern_sig.c standard kern/kern_switch.c standard kern/kern_sx.c standard kern/kern_synch.c standard kern/kern_syscalls.c standard kern/kern_sysctl.c standard kern/kern_tc.c standard kern/kern_thr.c standard kern/kern_thread.c standard kern/kern_time.c standard kern/kern_timeout.c standard kern/kern_umtx.c standard kern/kern_uuid.c standard kern/kern_xxx.c standard kern/link_elf.c standard kern/linker_if.m standard kern/md4c.c optional netsmb kern/md5c.c standard kern/p1003_1b.c standard kern/posix4_mib.c standard kern/sched_4bsd.c optional sched_4bsd kern/sched_ule.c optional sched_ule kern/serdev_if.m standard kern/stack_protector.c standard \ compile-with "${NORMAL_C:N-fstack-protector*}" kern/subr_acl_nfs4.c optional ufs_acl | zfs kern/subr_acl_posix1e.c optional ufs_acl kern/subr_autoconf.c standard kern/subr_blist.c standard kern/subr_bus.c standard kern/subr_bus_dma.c standard kern/subr_bufring.c standard kern/subr_capability.c standard kern/subr_clock.c standard kern/subr_counter.c standard kern/subr_devstat.c standard kern/subr_disk.c standard kern/subr_eventhandler.c standard kern/subr_fattime.c standard kern/subr_firmware.c optional firmware kern/subr_gtaskqueue.c standard kern/subr_hash.c standard kern/subr_hints.c standard kern/subr_kdb.c standard kern/subr_kobj.c standard kern/subr_lock.c standard kern/subr_log.c standard kern/subr_mbpool.c optional libmbpool kern/subr_mchain.c optional libmchain kern/subr_module.c standard kern/subr_msgbuf.c standard kern/subr_param.c standard kern/subr_pcpu.c standard kern/subr_pctrie.c standard kern/subr_power.c standard kern/subr_prf.c standard kern/subr_prof.c standard kern/subr_rman.c standard kern/subr_rtc.c standard kern/subr_sbuf.c standard kern/subr_scanf.c standard kern/subr_sglist.c standard kern/subr_sleepqueue.c standard kern/subr_smp.c standard kern/subr_stack.c optional ddb | stack | ktr kern/subr_taskqueue.c standard kern/subr_terminal.c optional vt kern/subr_trap.c standard kern/subr_turnstile.c standard kern/subr_uio.c standard kern/subr_unit.c standard kern/subr_vmem.c standard kern/subr_witness.c optional witness kern/sys_capability.c standard kern/sys_generic.c standard kern/sys_pipe.c standard kern/sys_procdesc.c standard kern/sys_process.c standard kern/sys_socket.c standard kern/syscalls.c standard kern/sysv_ipc.c standard kern/sysv_msg.c optional sysvmsg kern/sysv_sem.c optional sysvsem kern/sysv_shm.c optional sysvshm kern/tty.c standard kern/tty_compat.c optional compat_43tty kern/tty_info.c standard kern/tty_inq.c standard kern/tty_outq.c standard kern/tty_pts.c standard kern/tty_tty.c standard kern/tty_ttydisc.c standard kern/uipc_accf.c standard kern/uipc_debug.c optional ddb kern/uipc_domain.c standard kern/uipc_mbuf.c standard kern/uipc_mbuf2.c standard kern/uipc_mbufhash.c standard kern/uipc_mqueue.c optional p1003_1b_mqueue kern/uipc_sem.c optional p1003_1b_semaphores kern/uipc_shm.c standard kern/uipc_sockbuf.c standard kern/uipc_socket.c standard kern/uipc_syscalls.c standard kern/uipc_usrreq.c standard kern/vfs_acl.c standard kern/vfs_aio.c standard kern/vfs_bio.c standard kern/vfs_cache.c standard kern/vfs_cluster.c standard kern/vfs_default.c standard kern/vfs_export.c standard kern/vfs_extattr.c standard kern/vfs_hash.c standard kern/vfs_init.c standard kern/vfs_lookup.c standard kern/vfs_mount.c standard kern/vfs_mountroot.c standard kern/vfs_subr.c standard kern/vfs_syscalls.c standard kern/vfs_vnops.c standard # # Kernel GSS-API # gssd.h optional kgssapi \ dependency "$S/kgssapi/gssd.x" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -hM $S/kgssapi/gssd.x | grep -v pthread.h > gssd.h" \ no-obj no-implicit-rule before-depend local \ clean "gssd.h" gssd_xdr.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -c $S/kgssapi/gssd.x -o gssd_xdr.c" \ no-implicit-rule before-depend local \ clean "gssd_xdr.c" gssd_clnt.c optional kgssapi \ dependency "$S/kgssapi/gssd.x gssd.h" \ compile-with "RPCGEN_CPP='${CPP}' rpcgen -lM $S/kgssapi/gssd.x | grep -v string.h > gssd_clnt.c" \ no-implicit-rule before-depend local \ clean "gssd_clnt.c" kgssapi/gss_accept_sec_context.c optional kgssapi kgssapi/gss_add_oid_set_member.c optional kgssapi kgssapi/gss_acquire_cred.c optional kgssapi kgssapi/gss_canonicalize_name.c optional kgssapi kgssapi/gss_create_empty_oid_set.c optional kgssapi kgssapi/gss_delete_sec_context.c optional kgssapi kgssapi/gss_display_status.c optional kgssapi kgssapi/gss_export_name.c optional kgssapi kgssapi/gss_get_mic.c optional kgssapi kgssapi/gss_init_sec_context.c optional kgssapi kgssapi/gss_impl.c optional kgssapi kgssapi/gss_import_name.c optional kgssapi kgssapi/gss_names.c optional kgssapi kgssapi/gss_pname_to_uid.c optional kgssapi kgssapi/gss_release_buffer.c optional kgssapi kgssapi/gss_release_cred.c optional kgssapi kgssapi/gss_release_name.c optional kgssapi kgssapi/gss_release_oid_set.c optional kgssapi kgssapi/gss_set_cred_option.c optional kgssapi kgssapi/gss_test_oid_set_member.c optional kgssapi kgssapi/gss_unwrap.c optional kgssapi kgssapi/gss_verify_mic.c optional kgssapi kgssapi/gss_wrap.c optional kgssapi kgssapi/gss_wrap_size_limit.c optional kgssapi kgssapi/gssd_prot.c optional kgssapi kgssapi/krb5/krb5_mech.c optional kgssapi kgssapi/krb5/kcrypto.c optional kgssapi kgssapi/krb5/kcrypto_aes.c optional kgssapi kgssapi/krb5/kcrypto_arcfour.c optional kgssapi kgssapi/krb5/kcrypto_des.c optional kgssapi kgssapi/krb5/kcrypto_des3.c optional kgssapi kgssapi/kgss_if.m optional kgssapi kgssapi/gsstest.c optional kgssapi_debug # These files in libkern/ are those needed by all architectures. Some # of the files in libkern/ are only needed on some architectures, e.g., # libkern/divdi3.c is needed by i386 but not alpha. Also, some of these # routines may be optimized for a particular platform. In either case, # the file should be moved to conf/files. from here. # libkern/arc4random.c standard libkern/asprintf.c standard libkern/bcd.c standard libkern/bsearch.c standard libkern/crc32.c standard libkern/explicit_bzero.c standard libkern/fnmatch.c standard libkern/iconv.c optional libiconv libkern/iconv_converter_if.m optional libiconv libkern/iconv_ucs.c optional libiconv libkern/iconv_xlat.c optional libiconv libkern/iconv_xlat16.c optional libiconv libkern/inet_aton.c standard libkern/inet_ntoa.c standard libkern/inet_ntop.c standard libkern/inet_pton.c standard libkern/jenkins_hash.c standard libkern/murmur3_32.c standard libkern/mcount.c optional profiling-routine libkern/memcchr.c standard libkern/memchr.c standard libkern/memcmp.c standard libkern/memmem.c optional gdb libkern/qsort.c standard libkern/qsort_r.c standard libkern/random.c standard libkern/scanc.c standard libkern/strcasecmp.c standard libkern/strcat.c standard libkern/strchr.c standard libkern/strcmp.c standard libkern/strcpy.c standard libkern/strcspn.c standard libkern/strdup.c standard libkern/strndup.c standard libkern/strlcat.c standard libkern/strlcpy.c standard libkern/strlen.c standard libkern/strncat.c standard libkern/strncmp.c standard libkern/strncpy.c standard libkern/strnlen.c standard libkern/strrchr.c standard libkern/strsep.c standard libkern/strspn.c standard libkern/strstr.c standard libkern/strtol.c standard libkern/strtoq.c standard libkern/strtoul.c standard libkern/strtouq.c standard libkern/strvalid.c standard libkern/timingsafe_bcmp.c standard libkern/zlib.c optional crypto | geom_uzip | ipsec | \ mxge | netgraph_deflate | \ ddb_ctf | gzio net/altq/altq_cbq.c optional altq net/altq/altq_cdnr.c optional altq net/altq/altq_codel.c optional altq net/altq/altq_hfsc.c optional altq net/altq/altq_fairq.c optional altq net/altq/altq_priq.c optional altq net/altq/altq_red.c optional altq net/altq/altq_rio.c optional altq net/altq/altq_rmclass.c optional altq net/altq/altq_subr.c optional altq net/bpf.c standard net/bpf_buffer.c optional bpf net/bpf_jitter.c optional bpf_jitter net/bpf_filter.c optional bpf | netgraph_bpf net/bpf_zerocopy.c optional bpf net/bridgestp.c optional bridge | if_bridge net/flowtable.c optional flowtable inet | flowtable inet6 net/ieee8023ad_lacp.c optional lagg net/if.c standard net/if_arcsubr.c optional arcnet net/if_atmsubr.c optional atm net/if_bridge.c optional bridge inet | if_bridge inet net/if_clone.c standard net/if_dead.c standard net/if_debug.c optional ddb net/if_disc.c optional disc net/if_edsc.c optional edsc net/if_enc.c optional enc inet | enc inet6 net/if_epair.c optional epair net/if_ethersubr.c optional ether net/if_fddisubr.c optional fddi net/if_fwsubr.c optional fwip net/if_gif.c optional gif inet | gif inet6 | \ netgraph_gif inet | netgraph_gif inet6 net/if_gre.c optional gre inet | gre inet6 net/if_iso88025subr.c optional token net/if_lagg.c optional lagg net/if_loop.c optional loop net/if_llatbl.c standard net/if_me.c optional me inet net/if_media.c standard net/if_mib.c standard net/if_spppfr.c optional sppp | netgraph_sppp net/if_spppsubr.c optional sppp | netgraph_sppp net/if_stf.c optional stf inet inet6 net/if_tun.c optional tun net/if_tap.c optional tap net/if_vlan.c optional vlan net/if_vxlan.c optional vxlan inet | vxlan inet6 net/ifdi_if.m optional ether pci net/iflib.c optional ether pci net/mp_ring.c optional ether net/mppcc.c optional netgraph_mppc_compression net/mppcd.c optional netgraph_mppc_compression net/netisr.c standard net/pfil.c optional ether | inet net/radix.c standard net/radix_mpath.c standard net/raw_cb.c standard net/raw_usrreq.c standard net/route.c standard net/rss_config.c optional inet rss | inet6 rss net/rtsock.c standard net/slcompress.c optional netgraph_vjc | sppp | \ netgraph_sppp net/toeplitz.c optional inet rss | inet6 rss net/vnet.c optional vimage net80211/ieee80211.c optional wlan net80211/ieee80211_acl.c optional wlan wlan_acl net80211/ieee80211_action.c optional wlan net80211/ieee80211_ageq.c optional wlan net80211/ieee80211_adhoc.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ageq.c optional wlan net80211/ieee80211_amrr.c optional wlan | wlan_amrr net80211/ieee80211_crypto.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp net80211/ieee80211_crypto_none.c optional wlan net80211/ieee80211_crypto_tkip.c optional wlan wlan_tkip net80211/ieee80211_crypto_wep.c optional wlan wlan_wep net80211/ieee80211_ddb.c optional wlan ddb net80211/ieee80211_dfs.c optional wlan net80211/ieee80211_freebsd.c optional wlan net80211/ieee80211_hostap.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_ht.c optional wlan net80211/ieee80211_hwmp.c optional wlan ieee80211_support_mesh net80211/ieee80211_input.c optional wlan net80211/ieee80211_ioctl.c optional wlan net80211/ieee80211_mesh.c optional wlan ieee80211_support_mesh \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_monitor.c optional wlan net80211/ieee80211_node.c optional wlan net80211/ieee80211_output.c optional wlan net80211/ieee80211_phy.c optional wlan net80211/ieee80211_power.c optional wlan net80211/ieee80211_proto.c optional wlan net80211/ieee80211_radiotap.c optional wlan net80211/ieee80211_ratectl.c optional wlan net80211/ieee80211_ratectl_none.c optional wlan net80211/ieee80211_regdomain.c optional wlan net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt net80211/ieee80211_scan.c optional wlan net80211/ieee80211_scan_sta.c optional wlan net80211/ieee80211_sta.c optional wlan \ compile-with "${NORMAL_C} -Wno-unused-function" net80211/ieee80211_superg.c optional wlan ieee80211_support_superg net80211/ieee80211_scan_sw.c optional wlan net80211/ieee80211_tdma.c optional wlan ieee80211_support_tdma net80211/ieee80211_wds.c optional wlan net80211/ieee80211_xauth.c optional wlan wlan_xauth net80211/ieee80211_alq.c optional wlan ieee80211_alq netgraph/atm/ccatm/ng_ccatm.c optional ngatm_ccatm \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/ng_atm.c optional ngatm_atm netgraph/atm/ngatmbase.c optional ngatm_atmbase \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscfu/ng_sscfu.c optional ngatm_sscfu \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/sscop/ng_sscop.c optional ngatm_sscop \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/atm/uni/ng_uni.c optional ngatm_uni \ compile-with "${NORMAL_C} -I$S/contrib/ngatm" netgraph/bluetooth/common/ng_bluetooth.c optional netgraph_bluetooth netgraph/bluetooth/drivers/bt3c/ng_bt3c_pccard.c optional netgraph_bluetooth_bt3c netgraph/bluetooth/drivers/h4/ng_h4.c optional netgraph_bluetooth_h4 netgraph/bluetooth/drivers/ubt/ng_ubt.c optional netgraph_bluetooth_ubt usb netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c optional netgraph_bluetooth_ubtbcmfw usb netgraph/bluetooth/hci/ng_hci_cmds.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_evnt.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_main.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_misc.c optional netgraph_bluetooth_hci netgraph/bluetooth/hci/ng_hci_ulpi.c optional netgraph_bluetooth_hci netgraph/bluetooth/l2cap/ng_l2cap_cmds.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_evnt.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_llpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_main.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_misc.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/l2cap/ng_l2cap_ulpi.c optional netgraph_bluetooth_l2cap netgraph/bluetooth/socket/ng_btsocket.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_hci_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_l2cap_raw.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_rfcomm.c optional netgraph_bluetooth_socket netgraph/bluetooth/socket/ng_btsocket_sco.c optional netgraph_bluetooth_socket netgraph/netflow/netflow.c optional netgraph_netflow netgraph/netflow/netflow_v9.c optional netgraph_netflow netgraph/netflow/ng_netflow.c optional netgraph_netflow netgraph/ng_UI.c optional netgraph_UI netgraph/ng_async.c optional netgraph_async netgraph/ng_atmllc.c optional netgraph_atmllc netgraph/ng_base.c optional netgraph netgraph/ng_bpf.c optional netgraph_bpf netgraph/ng_bridge.c optional netgraph_bridge netgraph/ng_car.c optional netgraph_car netgraph/ng_cisco.c optional netgraph_cisco netgraph/ng_deflate.c optional netgraph_deflate netgraph/ng_device.c optional netgraph_device netgraph/ng_echo.c optional netgraph_echo netgraph/ng_eiface.c optional netgraph_eiface netgraph/ng_ether.c optional netgraph_ether netgraph/ng_ether_echo.c optional netgraph_ether_echo netgraph/ng_frame_relay.c optional netgraph_frame_relay netgraph/ng_gif.c optional netgraph_gif inet6 | netgraph_gif inet netgraph/ng_gif_demux.c optional netgraph_gif_demux netgraph/ng_hole.c optional netgraph_hole netgraph/ng_iface.c optional netgraph_iface netgraph/ng_ip_input.c optional netgraph_ip_input netgraph/ng_ipfw.c optional netgraph_ipfw inet ipfirewall netgraph/ng_ksocket.c optional netgraph_ksocket netgraph/ng_l2tp.c optional netgraph_l2tp netgraph/ng_lmi.c optional netgraph_lmi netgraph/ng_mppc.c optional netgraph_mppc_compression | \ netgraph_mppc_encryption netgraph/ng_nat.c optional netgraph_nat inet libalias netgraph/ng_one2many.c optional netgraph_one2many netgraph/ng_parse.c optional netgraph netgraph/ng_patch.c optional netgraph_patch netgraph/ng_pipe.c optional netgraph_pipe netgraph/ng_ppp.c optional netgraph_ppp netgraph/ng_pppoe.c optional netgraph_pppoe netgraph/ng_pptpgre.c optional netgraph_pptpgre netgraph/ng_pred1.c optional netgraph_pred1 netgraph/ng_rfc1490.c optional netgraph_rfc1490 netgraph/ng_socket.c optional netgraph_socket netgraph/ng_split.c optional netgraph_split netgraph/ng_sppp.c optional netgraph_sppp netgraph/ng_tag.c optional netgraph_tag netgraph/ng_tcpmss.c optional netgraph_tcpmss netgraph/ng_tee.c optional netgraph_tee netgraph/ng_tty.c optional netgraph_tty netgraph/ng_vjc.c optional netgraph_vjc netgraph/ng_vlan.c optional netgraph_vlan netinet/accf_data.c optional accept_filter_data inet netinet/accf_dns.c optional accept_filter_dns inet netinet/accf_http.c optional accept_filter_http inet netinet/if_atm.c optional atm netinet/if_ether.c optional inet ether netinet/igmp.c optional inet netinet/in.c optional inet netinet/in_debug.c optional inet ddb netinet/in_kdtrace.c optional inet | inet6 netinet/ip_carp.c optional inet carp | inet6 carp netinet/in_fib.c optional inet netinet/in_gif.c optional gif inet | netgraph_gif inet netinet/ip_gre.c optional gre inet netinet/ip_id.c optional inet netinet/in_jail.c optional inet netinet/in_mcast.c optional inet netinet/in_pcb.c optional inet | inet6 netinet/in_pcbgroup.c optional inet pcbgroup | inet6 pcbgroup netinet/in_prot.c optional inet | inet6 netinet/in_proto.c optional inet | inet6 netinet/in_rmx.c optional inet netinet/in_rss.c optional inet rss netinet/ip_divert.c optional inet ipdivert ipfirewall netinet/ip_ecn.c optional inet | inet6 netinet/ip_encap.c optional inet | inet6 netinet/ip_fastfwd.c optional inet netinet/ip_icmp.c optional inet | inet6 netinet/ip_input.c optional inet netinet/ip_ipsec.c optional inet ipsec netinet/ip_mroute.c optional mrouting inet netinet/ip_options.c optional inet netinet/ip_output.c optional inet netinet/ip_reass.c optional inet netinet/raw_ip.c optional inet | inet6 netinet/cc/cc.c optional inet | inet6 netinet/cc/cc_newreno.c optional inet | inet6 netinet/sctp_asconf.c optional inet sctp | inet6 sctp netinet/sctp_auth.c optional inet sctp | inet6 sctp netinet/sctp_bsd_addr.c optional inet sctp | inet6 sctp netinet/sctp_cc_functions.c optional inet sctp | inet6 sctp netinet/sctp_crc32.c optional inet sctp | inet6 sctp netinet/sctp_indata.c optional inet sctp | inet6 sctp netinet/sctp_input.c optional inet sctp | inet6 sctp netinet/sctp_output.c optional inet sctp | inet6 sctp netinet/sctp_pcb.c optional inet sctp | inet6 sctp netinet/sctp_peeloff.c optional inet sctp | inet6 sctp netinet/sctp_ss_functions.c optional inet sctp | inet6 sctp netinet/sctp_syscalls.c optional inet sctp | inet6 sctp netinet/sctp_sysctl.c optional inet sctp | inet6 sctp netinet/sctp_timer.c optional inet sctp | inet6 sctp netinet/sctp_usrreq.c optional inet sctp | inet6 sctp netinet/sctputil.c optional inet sctp | inet6 sctp netinet/siftr.c optional inet siftr alq | inet6 siftr alq netinet/tcp_debug.c optional tcpdebug netinet/tcp_fastopen.c optional inet tcp_rfc7413 | inet6 tcp_rfc7413 netinet/tcp_hostcache.c optional inet | inet6 netinet/tcp_input.c optional inet | inet6 netinet/tcp_lro.c optional inet | inet6 netinet/tcp_output.c optional inet | inet6 netinet/tcp_offload.c optional tcp_offload inet | tcp_offload inet6 netinet/tcp_pcap.c optional inet tcppcap | inet6 tcppcap netinet/tcp_reass.c optional inet | inet6 netinet/tcp_sack.c optional inet | inet6 netinet/tcp_subr.c optional inet | inet6 netinet/tcp_syncache.c optional inet | inet6 netinet/tcp_timer.c optional inet | inet6 netinet/tcp_timewait.c optional inet | inet6 netinet/tcp_usrreq.c optional inet | inet6 netinet/udp_usrreq.c optional inet | inet6 netinet/libalias/alias.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_db.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_mod.c optional libalias | netgraph_nat netinet/libalias/alias_proxy.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_util.c optional libalias inet | netgraph_nat inet netinet/libalias/alias_sctp.c optional libalias inet | netgraph_nat inet netinet6/dest6.c optional inet6 netinet6/frag6.c optional inet6 netinet6/icmp6.c optional inet6 netinet6/in6.c optional inet6 netinet6/in6_cksum.c optional inet6 netinet6/in6_fib.c optional inet6 netinet6/in6_gif.c optional gif inet6 | netgraph_gif inet6 netinet6/in6_ifattach.c optional inet6 netinet6/in6_jail.c optional inet6 netinet6/in6_mcast.c optional inet6 netinet6/in6_pcb.c optional inet6 netinet6/in6_pcbgroup.c optional inet6 pcbgroup netinet6/in6_proto.c optional inet6 netinet6/in6_rmx.c optional inet6 netinet6/in6_rss.c optional inet6 rss netinet6/in6_src.c optional inet6 netinet6/ip6_fastfwd.c optional inet6 netinet6/ip6_forward.c optional inet6 netinet6/ip6_gre.c optional gre inet6 netinet6/ip6_id.c optional inet6 netinet6/ip6_input.c optional inet6 netinet6/ip6_mroute.c optional mrouting inet6 netinet6/ip6_output.c optional inet6 netinet6/ip6_ipsec.c optional inet6 ipsec netinet6/mld6.c optional inet6 netinet6/nd6.c optional inet6 netinet6/nd6_nbr.c optional inet6 netinet6/nd6_rtr.c optional inet6 netinet6/raw_ip6.c optional inet6 netinet6/route6.c optional inet6 netinet6/scope6.c optional inet6 netinet6/sctp6_usrreq.c optional inet6 sctp netinet6/udp6_usrreq.c optional inet6 netipsec/ipsec.c optional ipsec inet | ipsec inet6 netipsec/ipsec_input.c optional ipsec inet | ipsec inet6 netipsec/ipsec_mbuf.c optional ipsec inet | ipsec inet6 netipsec/ipsec_output.c optional ipsec inet | ipsec inet6 netipsec/key.c optional ipsec inet | ipsec inet6 netipsec/key_debug.c optional ipsec inet | ipsec inet6 netipsec/keysock.c optional ipsec inet | ipsec inet6 netipsec/xform_ah.c optional ipsec inet | ipsec inet6 netipsec/xform_esp.c optional ipsec inet | ipsec inet6 netipsec/xform_ipcomp.c optional ipsec inet | ipsec inet6 netipsec/xform_tcp.c optional ipsec inet tcp_signature | \ ipsec inet6 tcp_signature netnatm/natm.c optional natm netnatm/natm_pcb.c optional natm netnatm/natm_proto.c optional natm netpfil/ipfw/dn_aqm_codel.c optional inet dummynet netpfil/ipfw/dn_aqm_pie.c optional inet dummynet netpfil/ipfw/dn_heap.c optional inet dummynet netpfil/ipfw/dn_sched_fifo.c optional inet dummynet netpfil/ipfw/dn_sched_fq_codel.c optional inet dummynet netpfil/ipfw/dn_sched_fq_pie.c optional inet dummynet netpfil/ipfw/dn_sched_prio.c optional inet dummynet netpfil/ipfw/dn_sched_qfq.c optional inet dummynet netpfil/ipfw/dn_sched_rr.c optional inet dummynet netpfil/ipfw/dn_sched_wf2q.c optional inet dummynet netpfil/ipfw/ip_dummynet.c optional inet dummynet netpfil/ipfw/ip_dn_io.c optional inet dummynet netpfil/ipfw/ip_dn_glue.c optional inet dummynet netpfil/ipfw/ip_fw2.c optional inet ipfirewall netpfil/ipfw/ip_fw_bpf.c optional inet ipfirewall netpfil/ipfw/ip_fw_dynamic.c optional inet ipfirewall netpfil/ipfw/ip_fw_eaction.c optional inet ipfirewall netpfil/ipfw/ip_fw_log.c optional inet ipfirewall netpfil/ipfw/ip_fw_pfil.c optional inet ipfirewall netpfil/ipfw/ip_fw_sockopt.c optional inet ipfirewall netpfil/ipfw/ip_fw_table.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_algo.c optional inet ipfirewall netpfil/ipfw/ip_fw_table_value.c optional inet ipfirewall netpfil/ipfw/ip_fw_iface.c optional inet ipfirewall netpfil/ipfw/ip_fw_nat.c optional inet ipfirewall_nat netpfil/ipfw/nat64/ip_fw_nat64.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64lsn.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64lsn_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64stl.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64stl_control.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nat64/nat64_translate.c optional inet inet6 ipfirewall \ ipfirewall_nat64 netpfil/ipfw/nptv6/ip_fw_nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/ipfw/nptv6/nptv6.c optional inet inet6 ipfirewall \ ipfirewall_nptv6 netpfil/pf/if_pflog.c optional pflog pf inet netpfil/pf/if_pfsync.c optional pfsync pf inet netpfil/pf/pf.c optional pf inet netpfil/pf/pf_if.c optional pf inet netpfil/pf/pf_ioctl.c optional pf inet netpfil/pf/pf_lb.c optional pf inet netpfil/pf/pf_norm.c optional pf inet netpfil/pf/pf_osfp.c optional pf inet netpfil/pf/pf_ruleset.c optional pf inet netpfil/pf/pf_table.c optional pf inet netpfil/pf/in4_cksum.c optional pf inet netsmb/smb_conn.c optional netsmb netsmb/smb_crypt.c optional netsmb netsmb/smb_dev.c optional netsmb netsmb/smb_iod.c optional netsmb netsmb/smb_rq.c optional netsmb netsmb/smb_smb.c optional netsmb netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb nfs/bootp_subr.c optional bootp nfscl nfs/krpc_subr.c optional bootp nfscl nfs/nfs_diskless.c optional nfscl nfs_root nfs/nfs_fha.c optional nfsd nfs/nfs_lock.c optional nfscl | nfslockd | nfsd nfs/nfs_nfssvc.c optional nfscl | nfsd nlm/nlm_advlock.c optional nfslockd | nfsd nlm/nlm_prot_clnt.c optional nfslockd | nfsd nlm/nlm_prot_impl.c optional nfslockd | nfsd nlm/nlm_prot_server.c optional nfslockd | nfsd nlm/nlm_prot_svc.c optional nfslockd | nfsd nlm/nlm_prot_xdr.c optional nfslockd | nfsd nlm/sm_inter_xdr.c optional nfslockd | nfsd # Linux Kernel Programming Interface compat/linuxkpi/common/src/linux_kmod.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_compat.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_pci.c optional compat_linuxkpi pci \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_idr.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_radix.c optional compat_linuxkpi \ compile-with "${LINUXKPI_C}" compat/linuxkpi/common/src/linux_usb.c optional compat_linuxkpi usb \ compile-with "${LINUXKPI_C}" # OpenFabrics Enterprise Distribution (Infiniband) ofed/drivers/infiniband/core/addr.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/agent.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/cache.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" # XXX Mad.c must be ordered before cm.c for sysinit sets to occur in # the correct order. ofed/drivers/infiniband/core/mad.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/cm.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/ -Wno-unused-function" ofed/drivers/infiniband/core/cma.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/device.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/fmr_pool.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/iwcm.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/mad_rmpp.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/multicast.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/packer.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/peer_mem.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/sa_query.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/smi.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/sysfs.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/ucm.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/ucma.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/ud_header.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/umem.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/user_mad.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/uverbs_cmd.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/uverbs_main.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/uverbs_marshall.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/core/verbs.c optional ofed \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/core/" ofed/drivers/infiniband/ulp/ipoib/ipoib_cm.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_fs.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_ib.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_main.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_multicast.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/ipoib/ipoib_verbs.c optional ipoib \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" #ofed/drivers/infiniband/ulp/ipoib/ipoib_vlan.c optional ipoib \ # compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/ipoib/" ofed/drivers/infiniband/ulp/sdp/sdp_bcopy.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_main.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_rx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_cma.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" ofed/drivers/infiniband/ulp/sdp/sdp_tx.c optional sdp inet \ compile-with "${OFED_C} -I$S/ofed/drivers/infiniband/ulp/sdp/" dev/mlx4/mlx4_ib/mlx4_ib_alias_GUID.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mcg.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_sysfs.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cm.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_ah.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_cq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_doorbell.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mad.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_main.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_exp.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_mr.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_qp.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_srq.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_ib/mlx4_ib_wc.c optional mlx4ib pci ofed \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_alloc.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_catas.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cmd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_cq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_eq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_fw.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_icm.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_intf.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_main.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mcg.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_mr.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_pd.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_port.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_profile.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_qp.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_reset.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_sense.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_srq.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_resource_tracker.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_core/mlx4_sys_tune.c optional mlx4 pci \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_cq.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_main.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_netdev.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_port.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_resources.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_rx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx4/mlx4_en/mlx4_en_tx.c optional mlx4en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_alloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_cq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_eq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_flow_table.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_health.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mad.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_main.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mcg.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_mr.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pagealloc.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_pd.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_port.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_qp.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_srq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_transobj.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_uar.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_vport.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_wq.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_ethtool.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_main.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_tx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_flow_table.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_rx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" dev/mlx5/mlx5_en/mlx5_en_txrx.c optional mlx5en pci inet inet6 \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_allocator.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_av.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_catas.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_cmd.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_cq.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_eq.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_mad.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_main.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_mcg.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_memfree.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_mr.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_pd.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_profile.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_provider.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_qp.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_reset.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_srq.c optional mthca \ compile-with "${OFED_C}" ofed/drivers/infiniband/hw/mthca/mthca_uar.c optional mthca \ compile-with "${OFED_C}" # crypto support opencrypto/cast.c optional crypto | ipsec opencrypto/criov.c optional crypto | ipsec opencrypto/crypto.c optional crypto | ipsec opencrypto/cryptodev.c optional cryptodev opencrypto/cryptodev_if.m optional crypto | ipsec opencrypto/cryptosoft.c optional crypto | ipsec opencrypto/cryptodeflate.c optional crypto | ipsec opencrypto/gmac.c optional crypto | ipsec opencrypto/gfmult.c optional crypto | ipsec opencrypto/rmd160.c optional crypto | ipsec opencrypto/skipjack.c optional crypto | ipsec opencrypto/xform.c optional crypto | ipsec rpc/auth_none.c optional krpc | nfslockd | nfscl | nfsd rpc/auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/authunix_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_bck.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_rc.c optional krpc | nfslockd | nfscl | nfsd rpc/clnt_vc.c optional krpc | nfslockd | nfscl | nfsd rpc/getnetconfig.c optional krpc | nfslockd | nfscl | nfsd rpc/replay.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_callmsg.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/rpc_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_clnt.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcb_prot.c optional krpc | nfslockd | nfscl | nfsd rpc/svc.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_auth_unix.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_dg.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_generic.c optional krpc | nfslockd | nfscl | nfsd rpc/svc_vc.c optional krpc | nfslockd | nfscl | nfsd rpc/rpcsec_gss/rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_conf.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_misc.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/rpcsec_gss_prot.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi rpc/rpcsec_gss/svc_rpcsec_gss.c optional krpc kgssapi | nfslockd kgssapi | nfscl kgssapi | nfsd kgssapi security/audit/audit.c optional audit security/audit/audit_arg.c optional audit security/audit/audit_bsm.c optional audit security/audit/audit_bsm_klib.c optional audit security/audit/audit_pipe.c optional audit security/audit/audit_syscalls.c standard security/audit/audit_trigger.c optional audit security/audit/audit_worker.c optional audit security/audit/bsm_domain.c optional audit security/audit/bsm_errno.c optional audit security/audit/bsm_fcntl.c optional audit security/audit/bsm_socket_type.c optional audit security/audit/bsm_token.c optional audit security/mac/mac_audit.c optional mac audit security/mac/mac_cred.c optional mac security/mac/mac_framework.c optional mac security/mac/mac_inet.c optional mac inet | mac inet6 security/mac/mac_inet6.c optional mac inet6 security/mac/mac_label.c optional mac security/mac/mac_net.c optional mac security/mac/mac_pipe.c optional mac security/mac/mac_posix_sem.c optional mac security/mac/mac_posix_shm.c optional mac security/mac/mac_priv.c optional mac security/mac/mac_process.c optional mac security/mac/mac_socket.c optional mac security/mac/mac_syscalls.c standard security/mac/mac_system.c optional mac security/mac/mac_sysv_msg.c optional mac security/mac/mac_sysv_sem.c optional mac security/mac/mac_sysv_shm.c optional mac security/mac/mac_vfs.c optional mac security/mac_biba/mac_biba.c optional mac_biba security/mac_bsdextended/mac_bsdextended.c optional mac_bsdextended security/mac_bsdextended/ugidfw_system.c optional mac_bsdextended security/mac_bsdextended/ugidfw_vnode.c optional mac_bsdextended security/mac_ifoff/mac_ifoff.c optional mac_ifoff security/mac_lomac/mac_lomac.c optional mac_lomac security/mac_mls/mac_mls.c optional mac_mls security/mac_none/mac_none.c optional mac_none security/mac_partition/mac_partition.c optional mac_partition security/mac_portacl/mac_portacl.c optional mac_portacl security/mac_seeotheruids/mac_seeotheruids.c optional mac_seeotheruids security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test teken/teken.c optional sc | vt ufs/ffs/ffs_alloc.c optional ffs ufs/ffs/ffs_balloc.c optional ffs ufs/ffs/ffs_inode.c optional ffs ufs/ffs/ffs_snapshot.c optional ffs ufs/ffs/ffs_softdep.c optional ffs ufs/ffs/ffs_subr.c optional ffs ufs/ffs/ffs_tables.c optional ffs ufs/ffs/ffs_vfsops.c optional ffs ufs/ffs/ffs_vnops.c optional ffs ufs/ffs/ffs_rawread.c optional ffs directio ufs/ffs/ffs_suspend.c optional ffs ufs/ufs/ufs_acl.c optional ffs ufs/ufs/ufs_bmap.c optional ffs ufs/ufs/ufs_dirhash.c optional ffs ufs/ufs/ufs_extattr.c optional ffs ufs/ufs/ufs_gjournal.c optional ffs UFS_GJOURNAL ufs/ufs/ufs_inode.c optional ffs ufs/ufs/ufs_lookup.c optional ffs ufs/ufs/ufs_quota.c optional ffs ufs/ufs/ufs_vfsops.c optional ffs ufs/ufs/ufs_vnops.c optional ffs vm/default_pager.c standard vm/device_pager.c standard vm/phys_pager.c standard vm/redzone.c optional DEBUG_REDZONE vm/sg_pager.c standard vm/swap_pager.c standard vm/uma_core.c standard vm/uma_dbg.c standard vm/memguard.c optional DEBUG_MEMGUARD vm/vm_fault.c standard vm/vm_glue.c standard vm/vm_init.c standard vm/vm_kern.c standard vm/vm_map.c standard vm/vm_meter.c standard vm/vm_mmap.c standard vm/vm_object.c standard vm/vm_page.c standard vm/vm_pageout.c standard vm/vm_pager.c standard vm/vm_phys.c standard vm/vm_radix.c standard vm/vm_reserv.c standard vm/vm_domain.c standard vm/vm_unix.c standard vm/vnode_pager.c standard xen/features.c optional xenhvm xen/xenbus/xenbus_if.m optional xenhvm xen/xenbus/xenbus.c optional xenhvm xen/xenbus/xenbusb_if.m optional xenhvm xen/xenbus/xenbusb.c optional xenhvm xen/xenbus/xenbusb_front.c optional xenhvm xen/xenbus/xenbusb_back.c optional xenhvm xen/xenmem/xenmem_if.m optional xenhvm xdr/xdr.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_array.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_mbuf.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_mem.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_reference.c optional krpc | nfslockd | nfscl | nfsd xdr/xdr_sizeof.c optional krpc | nfslockd | nfscl | nfsd Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data.c (revision 310297) @@ -1,722 +1,725 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include #include #include #else /* !_KERNEL */ #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_io.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_data.h" /** * Return a human-readable description for the given NVRAM data class. * * @param cls The NVRAM class. */ const char * bhnd_nvram_data_class_desc(bhnd_nvram_data_class *cls) { return (cls->desc); } /** + * Return the class-level capability flags (@see BHND_NVRAM_DATA_CAP_*) for + * of @p cls. + * + * @param cls The NVRAM class. + */ +uint32_t +bhnd_nvram_data_class_caps(bhnd_nvram_data_class *cls) +{ + return (cls->caps); +} + +/** + * Serialize all NVRAM properties in @p plist using @p cls's NVRAM data + * format, writing the result to @p outp. + * + * @param cls The NVRAM data class to be used to perform + * serialization. + * @param props The raw property values to be serialized to + * @p outp, in serialization order. + * @param options Serialization options for @p cls, or NULL. + * @param[out] outp On success, the serialed NVRAM data will be + * written to this buffer. This argment may be + * NULL if the value is not desired. + * @param[in,out] olen The capacity of @p buf. On success, will be set + * to the actual length of the serialized data. + * + * @retval 0 success + * + * @retval ENOMEM If @p outp is non-NULL and a buffer of @p olen is too + * small to hold the serialized data. + * @retval EINVAL If a property value required by @p cls is not found in + * @p plist. + * @retval EFTYPE If a property value in @p plist cannot be represented + * as the data type required by @p cls. + * @retval ERANGE If a property value in @p plist would would overflow + * (or underflow) the data type required by @p cls. + * @retval non-zero If serialization otherwise fails, a regular unix error + * code will be returned. + */ +int +bhnd_nvram_data_serialize(bhnd_nvram_data_class *cls, + bhnd_nvram_plist *props, bhnd_nvram_plist *options, void *outp, + size_t *olen) +{ + return (cls->op_serialize(cls, props, options, outp, olen)); +} + +/** * Probe to see if this NVRAM data class class supports the data mapped by the * given I/O context, returning a BHND_NVRAM_DATA_PROBE probe result. * * @param cls The NVRAM class. * @param io An I/O context mapping the NVRAM data. * * @retval 0 if this is the only possible NVRAM data class for @p io. * @retval negative if the probe succeeds, a negative value should be returned; * the class returning the highest negative value should be selected to handle * NVRAM parsing. * @retval ENXIO If the NVRAM format is not handled by @p cls. * @retval positive if an error occurs during probing, a regular unix error * code should be returned. */ int bhnd_nvram_data_probe(bhnd_nvram_data_class *cls, struct bhnd_nvram_io *io) { return (cls->op_probe(io)); } /** * Probe to see if an NVRAM data class in @p classes supports parsing * of the data mapped by @p io, returning the parsed data in @p data. * * The caller is responsible for deallocating the returned instance via * bhnd_nvram_data_release(). * * @param[out] data On success, the parsed NVRAM data instance. * @param io An I/O context mapping the NVRAM data to be copied and parsed. * @param classes An array of NVRAM data classes to be probed, or NULL to * probe the default supported set. * @param num_classes The number of NVRAM data classes in @p classes. * * @retval 0 success * @retval ENXIO if no class is found capable of parsing @p io. * @retval non-zero if an error otherwise occurs during allocation, * initialization, or parsing of the NVRAM data, a regular unix error code * will be returned. */ int bhnd_nvram_data_probe_classes(struct bhnd_nvram_data **data, struct bhnd_nvram_io *io, bhnd_nvram_data_class *classes[], size_t num_classes) { bhnd_nvram_data_class *cls; int error, prio, result; cls = NULL; prio = 0; *data = NULL; /* If class array is NULL, default to our linker set */ if (classes == NULL) { classes = SET_BEGIN(bhnd_nvram_data_class_set); num_classes = SET_COUNT(bhnd_nvram_data_class_set); } /* Try to find the best data class capable of parsing io */ for (size_t i = 0; i < num_classes; i++) { bhnd_nvram_data_class *next_cls; next_cls = classes[i]; /* Try to probe */ result = bhnd_nvram_data_probe(next_cls, io); /* The parser did not match if an error was returned */ if (result > 0) continue; /* Lower priority than previous match; keep * searching */ if (cls != NULL && result <= prio) continue; /* Drop any previously parsed data */ if (*data != NULL) { bhnd_nvram_data_release(*data); *data = NULL; } /* If this is a 'maybe' match, attempt actual parsing to * verify that this does in fact match */ if (result <= BHND_NVRAM_DATA_PROBE_MAYBE) { /* If parsing fails, keep searching */ error = bhnd_nvram_data_new(next_cls, data, io); if (error) continue; } /* Record best new match */ prio = result; cls = next_cls; /* Terminate search immediately on * BHND_NVRAM_DATA_PROBE_SPECIFIC */ if (result == BHND_NVRAM_DATA_PROBE_SPECIFIC) break; } /* If no match, return error */ if (cls == NULL) return (ENXIO); /* If the NVRAM data was not parsed above, do so now */ if (*data == NULL) { if ((error = bhnd_nvram_data_new(cls, data, io))) return (error); } return (0); } /** * Allocate and initialize a new instance of data class @p cls, copying and * parsing NVRAM data from @p io. * * The caller is responsible for releasing the returned parser instance * reference via bhnd_nvram_data_release(). * * @param cls If non-NULL, the data class to be allocated. If NULL, * bhnd_nvram_data_probe_classes() will be used to determine the data format. * @param[out] nv On success, a pointer to the newly allocated NVRAM data instance. * @param io An I/O context mapping the NVRAM data to be copied and parsed. * * @retval 0 success * @retval non-zero if an error occurs during allocation or initialization, a * regular unix error code will be returned. */ int bhnd_nvram_data_new(bhnd_nvram_data_class *cls, struct bhnd_nvram_data **nv, struct bhnd_nvram_io *io) { struct bhnd_nvram_data *data; int error; /* If NULL, try to identify the appropriate class */ if (cls == NULL) return (bhnd_nvram_data_probe_classes(nv, io, NULL, 0)); /* Allocate new instance */ BHND_NV_ASSERT(sizeof(struct bhnd_nvram_data) <= cls->size, ("instance size %zu less than minimum %zu", cls->size, sizeof(struct bhnd_nvram_data))); data = bhnd_nv_calloc(1, cls->size); data->cls = cls; refcount_init(&data->refs, 1); /* Let the class handle initialization */ if ((error = cls->op_new(data, io))) { bhnd_nv_free(data); return (error); } *nv = data; return (0); } /** * Retain and return a reference to the given data instance. * * @param nv The reference to be retained. */ struct bhnd_nvram_data * bhnd_nvram_data_retain(struct bhnd_nvram_data *nv) { refcount_acquire(&nv->refs); return (nv); } /** * Release a reference to the given data instance. * * If this is the last reference, the data instance and its associated * resources will be freed. * * @param nv The reference to be released. */ void bhnd_nvram_data_release(struct bhnd_nvram_data *nv) { if (!refcount_release(&nv->refs)) return; /* Free any internal resources */ nv->cls->op_free(nv); /* Free the instance allocation */ bhnd_nv_free(nv); } /** * Return a pointer to @p nv's data class. * * @param nv The NVRAM data instance to be queried. */ bhnd_nvram_data_class * bhnd_nvram_data_get_class(struct bhnd_nvram_data *nv) { return (nv->cls); } /** * Return the number of variables in @p nv. * * @param nv The NVRAM data to be queried. */ size_t bhnd_nvram_data_count(struct bhnd_nvram_data *nv) { return (nv->cls->op_count(nv)); } /** * Return a borrowed reference to the serialization options for @p nv, * suitable for use with bhnd_nvram_data_serialize(), or NULL if none. * * @param nv The NVRAM data to be queried. */ bhnd_nvram_plist * bhnd_nvram_data_options(struct bhnd_nvram_data *nv) { return (nv->cls->op_options(nv)); -} - -/** - * Compute the size of the serialized form of @p nv. - * - * Serialization may be performed via bhnd_nvram_data_serialize(). - * - * @param nv The NVRAM data to be queried. - * @param[out] len On success, will be set to the computed size. - * - * @retval 0 success - * @retval non-zero if computing the serialized size otherwise fails, a - * regular unix error code will be returned. - */ -int -bhnd_nvram_data_size(struct bhnd_nvram_data *nv, size_t *len) -{ - return (nv->cls->op_size(nv, len)); -} - -/** - * Serialize the NVRAM data to @p buf, using the NVRAM data class' native - * format. - * - * The resulting serialization may be reparsed with @p nv's BHND NVRAM data - * class. - * - * @param nv The NVRAM data to be serialized. - * @param[out] buf On success, the serialed NVRAM data will be - * written to this buffer. This argment may be - * NULL if the value is not desired. - * @param[in,out] len The capacity of @p buf. On success, will be set - * to the actual length of the serialized data. - * - * @retval 0 success - * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too - * small to hold the serialized data. - * @retval non-zero If serialization otherwise fails, a regular unix error - * code will be returned. - */ -int -bhnd_nvram_data_serialize(struct bhnd_nvram_data *nv, - void *buf, size_t *len) -{ - return (nv->cls->op_serialize(nv, buf, len)); } /** * Return the capability flags (@see BHND_NVRAM_DATA_CAP_*) for @p nv. * * @param nv The NVRAM data to be queried. */ uint32_t bhnd_nvram_data_caps(struct bhnd_nvram_data *nv) { return (nv->cls->op_caps(nv)); } /** * Iterate over @p nv, returning the names of subsequent variables. * * @param nv The NVRAM data to be iterated. * @param[in,out] cookiep A pointer to a cookiep value previously returned * by bhnd_nvram_data_next(), or a NULL value to * begin iteration. * * @return Returns the next variable name, or NULL if there are no more * variables defined in @p nv. */ const char * bhnd_nvram_data_next(struct bhnd_nvram_data *nv, void **cookiep) { const char *name; #ifdef BHND_NV_INVARIANTS void *prev = *cookiep; #endif /* Fetch next */ if ((name = nv->cls->op_next(nv, cookiep)) == NULL) return (NULL); /* Enforce precedence ordering invariant between bhnd_nvram_data_next() * and bhnd_nvram_data_getvar_order() */ #ifdef BHND_NV_INVARIANTS if (prev != NULL && bhnd_nvram_data_getvar_order(nv, prev, *cookiep) > 0) { BHND_NV_PANIC("%s: returned out-of-order entry", __FUNCTION__); } #endif return (name); } /** * Search @p nv for a named variable, returning the variable's opaque reference * if found, or NULL if unavailable. * * The BHND_NVRAM_DATA_CAP_INDEXED capability flag will be returned by * bhnd_nvram_data_caps() if @p nv supports effecient name-based * lookups. * * @param nv The NVRAM data to search. * @param name The name to search for. * * @retval non-NULL If @p name is found, the opaque cookie value will be * returned. * @retval NULL If @p name is not found. */ void * bhnd_nvram_data_find(struct bhnd_nvram_data *nv, const char *name) { return (nv->cls->op_find(nv, name)); } /** * A generic implementation of bhnd_nvram_data_find(). * * This implementation will use bhnd_nvram_data_next() to perform a * simple O(n) case-insensitve search for @p name. */ void * bhnd_nvram_data_generic_find(struct bhnd_nvram_data *nv, const char *name) { const char *next; void *cookiep; cookiep = NULL; while ((next = bhnd_nvram_data_next(nv, &cookiep))) { if (strcmp(name, next) == 0) return (cookiep); } /* Not found */ return (NULL); } /** * Compare the declaration order of two NVRAM variables. * * Variable declaration order is used to determine the current order of * the variables in the source data, as well as to determine the precedence * of variable declarations in data sources that define duplicate names. * * The comparison order will match the order of variables returned via * bhnd_nvstore_path_data_next(). * * @param nv The NVRAM data. * @param cookiep1 An NVRAM variable cookie previously * returned via bhnd_nvram_data_next() or * bhnd_nvram_data_find(). * @param cookiep2 An NVRAM variable cookie previously * returned via bhnd_nvram_data_next() or * bhnd_nvram_data_find(). * * @retval <= -1 If @p cookiep1 has an earlier declaration order than * @p cookiep2. * @retval 0 If @p cookiep1 and @p cookiep2 are identical. * @retval >= 1 If @p cookiep has a later declaration order than * @p cookiep2. */ int bhnd_nvram_data_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { return (nv->cls->op_getvar_order(nv, cookiep1, cookiep2)); } /** * Read a variable and decode as @p type. * * @param nv The NVRAM data. * @param cookiep An NVRAM variable cookie previously returned * via bhnd_nvram_data_next() or * bhnd_nvram_data_find(). * @param[out] buf On success, the requested value will be written * to this buffer. This argment may be NULL if * the value is not desired. * @param[in,out] len The capacity of @p buf. On success, will be set * to the actual size of the requested value. * @param type The data type to be written to @p buf. * * @retval 0 success * @retval ENOMEM If @p buf is non-NULL and a buffer of @p len is too * small to hold the requested value. * @retval EFTYPE If the variable data cannot be coerced to @p type. * @retval ERANGE If value coercion would overflow @p type. */ int bhnd_nvram_data_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type) { return (nv->cls->op_getvar(nv, cookiep, buf, len, type)); } /* * Common bhnd_nvram_data_getvar_ptr() wrapper used by * bhnd_nvram_data_generic_rp_getvar() and * bhnd_nvram_data_generic_rp_copy_val(). * * If a variable definition for the requested variable is found via * bhnd_nvram_find_vardefn(), the definition will be used to populate fmt. */ static const void * bhnd_nvram_data_getvar_ptr_info(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type, const bhnd_nvram_val_fmt **fmt) { const struct bhnd_nvram_vardefn *vdefn; const char *name; const void *vptr; BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, ("instance does not advertise READ_PTR support")); /* Fetch pointer to variable data */ vptr = bhnd_nvram_data_getvar_ptr(nv, cookiep, len, type); if (vptr == NULL) return (NULL); /* Select a default value format implementation */ /* Fetch the reference variable name */ name = bhnd_nvram_data_getvar_name(nv, cookiep); /* Trim path prefix, if any; the Broadcom NVRAM format assumes a global * namespace for all variable definitions */ if (bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_DEVPATHS) name = bhnd_nvram_trim_path_name(name); /* Check the variable definition table for a matching entry; if * it exists, use it to populate the value format. */ vdefn = bhnd_nvram_find_vardefn(name); if (vdefn != NULL) { BHND_NV_ASSERT(vdefn->fmt != NULL, ("NULL format for %s", name)); *fmt = vdefn->fmt; } else if (*type == BHND_NVRAM_TYPE_STRING) { /* Default to Broadcom-specific string interpretation */ *fmt = &bhnd_nvram_val_bcm_string_fmt; } else { /* Fall back on native formatting */ *fmt = bhnd_nvram_val_default_fmt(*type); } return (vptr); } /** * A generic implementation of bhnd_nvram_data_getvar(). * * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch * a pointer to the variable data and perform data coercion on behalf * of the caller. * * If a variable definition for the requested variable is available via * bhnd_nvram_find_vardefn(), the definition will be used to provide a * formatting instance to bhnd_nvram_val_init(). */ int bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *outp, size_t *olen, bhnd_nvram_type otype) { bhnd_nvram_val val; const bhnd_nvram_val_fmt *fmt; const void *vptr; bhnd_nvram_type vtype; size_t vlen; int error; BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, ("instance does not advertise READ_PTR support")); /* Fetch variable data and value format*/ vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype, &fmt); if (vptr == NULL) return (EINVAL); /* Attempt value coercion */ error = bhnd_nvram_val_init(&val, fmt, vptr, vlen, vtype, BHND_NVRAM_VAL_BORROW_DATA); if (error) return (error); error = bhnd_nvram_val_encode(&val, outp, olen, otype); /* Clean up */ bhnd_nvram_val_release(&val); return (error); } /** * Return a caller-owned copy of an NVRAM entry's variable data. * * The caller is responsible for deallocating the returned value via * bhnd_nvram_val_release(). * * @param nv The NVRAM data. * @param cookiep An NVRAM variable cookie previously returned * via bhnd_nvram_data_next() or bhnd_nvram_data_find(). * @param[out] value On success, the caller-owned value instance. * * @retval 0 success * @retval ENOMEM If allocation fails. * @retval non-zero If initialization of the value otherwise fails, a * regular unix error code will be returned. */ int bhnd_nvram_data_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { return (nv->cls->op_copy_val(nv, cookiep, value)); } /** * A generic implementation of bhnd_nvram_data_copy_val(). * * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch * a pointer to the variable data and perform data coercion on behalf * of the caller. * * If a variable definition for the requested variable is available via * bhnd_nvram_find_vardefn(), the definition will be used to provide a * formatting instance to bhnd_nvram_val_init(). */ int bhnd_nvram_data_generic_rp_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { const bhnd_nvram_val_fmt *fmt; const void *vptr; bhnd_nvram_type vtype; size_t vlen; BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR, ("instance does not advertise READ_PTR support")); /* Fetch variable data and value format*/ vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype, &fmt); if (vptr == NULL) return (EINVAL); /* Allocate and return the new value instance */ return (bhnd_nvram_val_new(value, fmt, vptr, vlen, vtype, BHND_NVRAM_VAL_DYNAMIC)); } /** * If available and supported by the NVRAM data instance, return a reference * to the internal buffer containing an entry's variable data, * * Note that string values may not be NUL terminated. * * @param nv The NVRAM data. * @param cookiep An NVRAM variable cookie previously returned * via bhnd_nvram_data_next() or * bhnd_nvram_data_find(). * @param[out] len On success, will be set to the actual size of * the requested value. * @param[out] type The data type of the entry data. * * @retval non-NULL success * @retval NULL if direct data access is unsupported by @p nv, or * unavailable for @p cookiep. */ const void * bhnd_nvram_data_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { return (nv->cls->op_getvar_ptr(nv, cookiep, len, type)); } /** * Return the variable name associated with a given @p cookiep. * @param nv The NVRAM data to be iterated. * @param[in,out] cookiep A pointer to a cookiep value previously returned * via bhnd_nvram_data_next() or * bhnd_nvram_data_find(). * * @return Returns the variable's name. */ const char * bhnd_nvram_data_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { return (nv->cls->op_getvar_name(nv, cookiep)); } /** * Filter a request to set variable @p name with @p value. * * On success, the caller owns a reference to @p result, and must release * any held resources via bhnd_nvram_val_release(). * * @param nv The NVRAM data instance. * @param name The name of the variable to be set. * @param value The proposed value to be set. * @param[out] result On success, a caller-owned reference to the filtered * value to be set. * * @retval 0 success * @retval ENOENT if @p name is unrecognized by @p nv. * @retval EINVAL if @p name is read-only. * @retval EINVAL if @p value cannot be converted to the required value * type. */ int bhnd_nvram_data_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { return (nv->cls->op_filter_setvar(nv, name, value, result)); } /** * Filter a request to delete variable @p name. * * @param nv The NVRAM data instance. * @param name The name of the variable to be deleted. * * @retval 0 success * @retval ENOENT if @p name is unrecognized by @p nv. * @retval EINVAL if @p name is read-only. */ int bhnd_nvram_data_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { return (nv->cls->op_filter_unsetvar(nv, name)); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data.h (revision 310297) @@ -1,150 +1,149 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_DATA_H_ #define _BHND_NVRAM_BHND_NVRAM_DATA_H_ #ifdef _KERNEL #include #include #else /* !_KERNEL */ #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram.h" #include "bhnd_nvram_io.h" #include "bhnd_nvram_plist.h" #include "bhnd_nvram_value.h" /* NVRAM data class */ typedef struct bhnd_nvram_data_class bhnd_nvram_data_class; /* NVRAM data instance */ struct bhnd_nvram_data; /** Declare a bhnd_nvram_data_class with name @p _n */ #define BHND_NVRAM_DATA_CLASS_DECL(_n) \ extern struct bhnd_nvram_data_class bhnd_nvram_ ## _n ## _class BHND_NVRAM_DATA_CLASS_DECL(bcm); BHND_NVRAM_DATA_CLASS_DECL(bcmraw); BHND_NVRAM_DATA_CLASS_DECL(tlv); BHND_NVRAM_DATA_CLASS_DECL(btxt); BHND_NVRAM_DATA_CLASS_DECL(sprom); /** bhnd_nvram_data capabilities */ enum { /** Supports efficient lookup of variables by name */ BHND_NVRAM_DATA_CAP_INDEXED = (1<<0), /** Supports direct access to backing buffer */ BHND_NVRAM_DATA_CAP_READ_PTR = (1<<1), /** Supports device path prefixed variables */ BHND_NVRAM_DATA_CAP_DEVPATHS = (1<<2), }; /** * A standard set of probe priorities returned by bhnd_nvram_data_probe(). * * Priority is defined in ascending order, with 0 being the highest priority. * Return values greater than zero are interpreted as regular unix error codes. */ enum { BHND_NVRAM_DATA_PROBE_MAYBE = -40, /**< Possible match */ BHND_NVRAM_DATA_PROBE_DEFAULT = -20, /**< Definite match of a base OS-supplied data class */ BHND_NVRAM_DATA_PROBE_SPECIFIC = 0, /**< Terminate search and use this data class for parsing */ }; const char *bhnd_nvram_data_class_desc(bhnd_nvram_data_class *cls); +uint32_t bhnd_nvram_data_class_caps(bhnd_nvram_data_class *cls); +int bhnd_nvram_data_serialize(bhnd_nvram_data_class *cls, + bhnd_nvram_plist *props, bhnd_nvram_plist *options, + void *outp, size_t *olen); + int bhnd_nvram_data_probe(bhnd_nvram_data_class *cls, struct bhnd_nvram_io *io); int bhnd_nvram_data_probe_classes( struct bhnd_nvram_data **data, struct bhnd_nvram_io *io, bhnd_nvram_data_class *classes[], size_t num_classes); int bhnd_nvram_data_new(bhnd_nvram_data_class *cls, struct bhnd_nvram_data **nv, struct bhnd_nvram_io *io); struct bhnd_nvram_data *bhnd_nvram_data_retain(struct bhnd_nvram_data *nv); void bhnd_nvram_data_release(struct bhnd_nvram_data *nv); bhnd_nvram_data_class *bhnd_nvram_data_get_class(struct bhnd_nvram_data *nv); size_t bhnd_nvram_data_count(struct bhnd_nvram_data *nv); -int bhnd_nvram_data_size(struct bhnd_nvram_data *nv, - size_t *size); - -int bhnd_nvram_data_serialize(struct bhnd_nvram_data *nv, - void *buf, size_t *len); - bhnd_nvram_plist *bhnd_nvram_data_options(struct bhnd_nvram_data *nv); uint32_t bhnd_nvram_data_caps(struct bhnd_nvram_data *nv); const char *bhnd_nvram_data_next(struct bhnd_nvram_data *nv, void **cookiep); void *bhnd_nvram_data_find(struct bhnd_nvram_data *nv, const char *name); int bhnd_nvram_data_getvar_order( struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2); int bhnd_nvram_data_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type); const void *bhnd_nvram_data_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type); const char *bhnd_nvram_data_getvar_name(struct bhnd_nvram_data *nv, void *cookiep); int bhnd_nvram_data_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **val); int bhnd_nvram_data_filter_setvar( struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result); int bhnd_nvram_data_filter_unsetvar( struct bhnd_nvram_data *nv, const char *name); #endif /* _BHND_NVRAM_BHND_NVRAM_DATA_H_ */ Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcm.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcm.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcm.c (revision 310297) @@ -1,840 +1,904 @@ /*- * Copyright (c) 2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #include #include #ifdef _KERNEL #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_data_bcmreg.h" #include "bhnd_nvram_data_bcmvar.h" /* * Broadcom NVRAM data class. * * The Broadcom NVRAM NUL-delimited ASCII format is used by most * Broadcom SoCs. * * The NVRAM data is encoded as a standard header, followed by series of * NUL-terminated 'key=value' strings; the end of the stream is denoted * by a single extra NUL character. */ struct bhnd_nvram_bcm; static struct bhnd_nvram_bcm_hvar *bhnd_nvram_bcm_gethdrvar( struct bhnd_nvram_bcm *bcm, const char *name); static struct bhnd_nvram_bcm_hvar *bhnd_nvram_bcm_to_hdrvar( struct bhnd_nvram_bcm *bcm, void *cookiep); static size_t bhnd_nvram_bcm_hdrvar_index( struct bhnd_nvram_bcm *bcm, struct bhnd_nvram_bcm_hvar *hvar); /* * Set of BCM NVRAM header values that are required to be mirrored in the * NVRAM data itself. * * If they're not included in the parsed NVRAM data, we need to vend the * header-parsed values with their appropriate keys, and add them in any * updates to the NVRAM data. * * If they're modified in NVRAM, we need to sync the changes with the * the NVRAM header values. */ static const struct bhnd_nvram_bcm_hvar bhnd_nvram_bcm_hvars[] = { { .name = BCM_NVRAM_CFG0_SDRAM_INIT_VAR, .type = BHND_NVRAM_TYPE_UINT16, .len = sizeof(uint16_t), .nelem = 1, }, { .name = BCM_NVRAM_CFG1_SDRAM_CFG_VAR, .type = BHND_NVRAM_TYPE_UINT16, .len = sizeof(uint16_t), .nelem = 1, }, { .name = BCM_NVRAM_CFG1_SDRAM_REFRESH_VAR, .type = BHND_NVRAM_TYPE_UINT16, .len = sizeof(uint16_t), .nelem = 1, }, { .name = BCM_NVRAM_SDRAM_NCDL_VAR, .type = BHND_NVRAM_TYPE_UINT32, .len = sizeof(uint32_t), .nelem = 1, }, }; /** BCM NVRAM data class instance */ struct bhnd_nvram_bcm { struct bhnd_nvram_data nv; /**< common instance state */ struct bhnd_nvram_io *data; /**< backing buffer */ bhnd_nvram_plist *opts; /**< serialization options */ /** BCM header values */ struct bhnd_nvram_bcm_hvar hvars[nitems(bhnd_nvram_bcm_hvars)]; size_t count; /**< total variable count */ }; -BHND_NVRAM_DATA_CLASS_DEFN(bcm, "Broadcom", sizeof(struct bhnd_nvram_bcm)) +BHND_NVRAM_DATA_CLASS_DEFN(bcm, "Broadcom", BHND_NVRAM_DATA_CAP_DEVPATHS, + sizeof(struct bhnd_nvram_bcm)) static int bhnd_nvram_bcm_probe(struct bhnd_nvram_io *io) { struct bhnd_nvram_bcmhdr hdr; int error; if ((error = bhnd_nvram_io_read(io, 0x0, &hdr, sizeof(hdr)))) return (error); if (le32toh(hdr.magic) != BCM_NVRAM_MAGIC) return (ENXIO); return (BHND_NVRAM_DATA_PROBE_DEFAULT); } +static int +bhnd_nvram_bcm_serialize(bhnd_nvram_data_class *cls, bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, size_t *olen) +{ + struct bhnd_nvram_bcmhdr hdr; + bhnd_nvram_prop *prop; + size_t limit, nbytes; + uint32_t sdram_ncdl; + uint16_t sdram_init, sdram_cfg, sdram_refresh; + uint8_t bcm_ver, crc8; + int error; + + /* Determine output byte limit */ + if (outp != NULL) + limit = *olen; + else + limit = 0; + + /* Fetch required header variables */ +#define PROPS_GET_HDRVAR(_name, _dest, _type) do { \ + const char *name = BCM_NVRAM_ ## _name ## _VAR; \ + if (!bhnd_nvram_plist_contains(props, name)) { \ + BHND_NV_LOG("missing required property: %s\n", \ + name); \ + return (EFTYPE); \ + } \ + \ + error = bhnd_nvram_plist_get_encoded(props, name, \ + (_dest), sizeof(*(_dest)), \ + BHND_NVRAM_TYPE_ ##_type); \ + if (error) { \ + BHND_NV_LOG("error reading required header " \ + "%s property: %d\n", name, error); \ + return (EFTYPE); \ + } \ +} while (0) + + PROPS_GET_HDRVAR(SDRAM_NCDL, &sdram_ncdl, UINT32); + PROPS_GET_HDRVAR(CFG0_SDRAM_INIT, &sdram_init, UINT16); + PROPS_GET_HDRVAR(CFG1_SDRAM_CFG, &sdram_cfg, UINT16); + PROPS_GET_HDRVAR(CFG1_SDRAM_REFRESH, &sdram_refresh, UINT16); + +#undef PROPS_GET_HDRVAR + + /* Fetch BCM nvram version from options */ + if (options != NULL && + bhnd_nvram_plist_contains(options, BCM_NVRAM_ENCODE_OPT_VERSION)) + { + error = bhnd_nvram_plist_get_uint8(options, + BCM_NVRAM_ENCODE_OPT_VERSION, &bcm_ver); + if (error) { + BHND_NV_LOG("error reading %s uint8 option value: %d\n", + BCM_NVRAM_ENCODE_OPT_VERSION, error); + return (EINVAL); + } + } else { + bcm_ver = BCM_NVRAM_CFG0_VER_DEFAULT; + } + + /* Construct our header */ + hdr = (struct bhnd_nvram_bcmhdr) { + .magic = htole32(BCM_NVRAM_MAGIC), + .size = 0, + .cfg0 = 0, + .cfg1 = 0, + .sdram_ncdl = htole32(sdram_ncdl) + }; + + hdr.cfg0 = BCM_NVRAM_SET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_CRC, 0x0); + hdr.cfg0 = BCM_NVRAM_SET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_VER, bcm_ver); + hdr.cfg0 = BCM_NVRAM_SET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_SDRAM_INIT, + htole16(sdram_init)); + + hdr.cfg1 = BCM_NVRAM_SET_BITS(hdr.cfg1, BCM_NVRAM_CFG1_SDRAM_CFG, + htole16(sdram_cfg)); + hdr.cfg1 = BCM_NVRAM_SET_BITS(hdr.cfg1, BCM_NVRAM_CFG1_SDRAM_REFRESH, + htole16(sdram_refresh)); + + /* Write the header */ + nbytes = sizeof(hdr); + if (limit >= nbytes) + memcpy(outp, &hdr, sizeof(hdr)); + + /* Write all properties */ + prop = NULL; + while ((prop = bhnd_nvram_plist_next(props, prop)) != NULL) { + const char *name; + char *p; + size_t prop_limit; + size_t name_len, value_len; + + if (outp == NULL || limit < nbytes) { + p = NULL; + prop_limit = 0; + } else { + p = ((char *)outp) + nbytes; + prop_limit = limit - nbytes; + } + + /* Fetch and write name + '=' to output */ + name = bhnd_nvram_prop_name(prop); + name_len = strlen(name) + 1; + + if (prop_limit > name_len) { + memcpy(p, name, name_len - 1); + p[name_len - 1] = '='; + + prop_limit -= name_len; + p += name_len; + } else { + prop_limit = 0; + p = NULL; + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < name_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += name_len; + + /* Attempt to write NUL-terminated value to output */ + value_len = prop_limit; + error = bhnd_nvram_prop_encode(prop, p, &value_len, + BHND_NVRAM_TYPE_STRING); + + /* If encoding failed for any reason other than ENOMEM (which + * we'll detect and report after encoding all properties), + * return immediately */ + if (error && error != ENOMEM) { + BHND_NV_LOG("error serializing %s to required type " + "%s: %d\n", name, + bhnd_nvram_type_name(BHND_NVRAM_TYPE_STRING), + error); + return (error); + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < value_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += value_len; + } + + /* Write terminating '\0' */ + if (limit > nbytes) + *((char *)outp + nbytes) = '\0'; + + if (nbytes == SIZE_MAX) + return (EFTYPE); /* would overflow size_t */ + else + nbytes++; + + /* Update header length; this must fit within the header's 32-bit size + * field */ + if (nbytes <= UINT32_MAX) { + hdr.size = (uint32_t)nbytes; + } else { + BHND_NV_LOG("size %zu exceeds maximum supported size of %u " + "bytes\n", nbytes, UINT32_MAX); + return (EFTYPE); + } + + /* Provide required length */ + *olen = nbytes; + if (limit < *olen) { + if (outp == NULL) + return (0); + + return (ENOMEM); + } + + /* Calculate the CRC value */ + BHND_NV_ASSERT(nbytes >= BCM_NVRAM_CRC_SKIP, ("invalid output size")); + crc8 = bhnd_nvram_crc8((uint8_t *)outp + BCM_NVRAM_CRC_SKIP, + nbytes - BCM_NVRAM_CRC_SKIP, BHND_NVRAM_CRC8_INITIAL); + + /* Update CRC and write the finalized header */ + BHND_NV_ASSERT(nbytes >= sizeof(hdr), ("invalid output size")); + hdr.cfg0 = BCM_NVRAM_SET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_CRC, crc8); + memcpy(outp, &hdr, sizeof(hdr)); + + return (0); +} + /** * Initialize @p bcm with the provided NVRAM data mapped by @p src. * * @param bcm A newly allocated data instance. */ static int bhnd_nvram_bcm_init(struct bhnd_nvram_bcm *bcm, struct bhnd_nvram_io *src) { struct bhnd_nvram_bcmhdr hdr; uint8_t *p; void *ptr; size_t io_offset, io_size; uint8_t crc, valid, bcm_ver; int error; if ((error = bhnd_nvram_io_read(src, 0x0, &hdr, sizeof(hdr)))) return (error); if (le32toh(hdr.magic) != BCM_NVRAM_MAGIC) return (ENXIO); /* Fetch the actual NVRAM image size */ io_size = le32toh(hdr.size); if (io_size < sizeof(hdr)) { /* The header size must include the header itself */ BHND_NV_LOG("corrupt header size: %zu\n", io_size); return (EINVAL); } if (io_size > bhnd_nvram_io_getsize(src)) { BHND_NV_LOG("header size %zu exceeds input size %zu\n", io_size, bhnd_nvram_io_getsize(src)); return (EINVAL); } /* Allocate a buffer large enough to hold the NVRAM image, and * an extra EOF-signaling NUL (on the chance it's missing from the * source data) */ if (io_size == SIZE_MAX) return (ENOMEM); bcm->data = bhnd_nvram_iobuf_empty(io_size, io_size + 1); if (bcm->data == NULL) return (ENOMEM); /* Fetch a pointer into our backing buffer and copy in the * NVRAM image. */ error = bhnd_nvram_io_write_ptr(bcm->data, 0x0, &ptr, io_size, NULL); if (error) return (error); p = ptr; if ((error = bhnd_nvram_io_read(src, 0x0, p, io_size))) return (error); /* Verify the CRC */ valid = BCM_NVRAM_GET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_CRC); crc = bhnd_nvram_crc8(p + BCM_NVRAM_CRC_SKIP, io_size - BCM_NVRAM_CRC_SKIP, BHND_NVRAM_CRC8_INITIAL); if (crc != valid) { BHND_NV_LOG("warning: NVRAM CRC error (crc=%#hhx, " "expected=%hhx)\n", crc, valid); } /* Populate header variable definitions */ #define BCM_READ_HDR_VAR(_name, _dest, _swap) do { \ struct bhnd_nvram_bcm_hvar *data; \ data = bhnd_nvram_bcm_gethdrvar(bcm, _name ##_VAR); \ BHND_NV_ASSERT(data != NULL, \ ("no such header variable: " __STRING(_name))); \ \ \ data->value. _dest = _swap(BCM_NVRAM_GET_BITS( \ hdr. _name ## _FIELD, _name)); \ } while(0) BCM_READ_HDR_VAR(BCM_NVRAM_CFG0_SDRAM_INIT, u16, le16toh); BCM_READ_HDR_VAR(BCM_NVRAM_CFG1_SDRAM_CFG, u16, le16toh); BCM_READ_HDR_VAR(BCM_NVRAM_CFG1_SDRAM_REFRESH, u16, le16toh); BCM_READ_HDR_VAR(BCM_NVRAM_SDRAM_NCDL, u32, le32toh); _Static_assert(nitems(bcm->hvars) == 4, "missing initialization for" "NVRAM header variable(s)"); #undef BCM_READ_HDR_VAR /* Process the buffer */ bcm->count = 0; io_offset = sizeof(hdr); while (io_offset < io_size) { char *envp; const char *name, *value; size_t envp_len; size_t name_len, value_len; /* Parse the key=value string */ envp = (char *) (p + io_offset); envp_len = strnlen(envp, io_size - io_offset); error = bhnd_nvram_parse_env(envp, envp_len, '=', &name, &name_len, &value, &value_len); if (error) { BHND_NV_LOG("error parsing envp at offset %#zx: %d\n", io_offset, error); return (error); } /* Insert a '\0' character, replacing the '=' delimiter and * allowing us to vend references directly to the variable * name */ *(envp + name_len) = '\0'; /* Record any NVRAM variables that mirror our header variables. * This is a brute-force search -- for the amount of data we're * operating on, it shouldn't be an issue. */ for (size_t i = 0; i < nitems(bcm->hvars); i++) { struct bhnd_nvram_bcm_hvar *hvar; union bhnd_nvram_bcm_hvar_value hval; size_t hval_len; hvar = &bcm->hvars[i]; /* Already matched? */ if (hvar->envp != NULL) continue; /* Name matches? */ if ((strcmp(name, hvar->name)) != 0) continue; /* Save pointer to mirrored envp */ hvar->envp = envp; /* Check for stale value */ hval_len = sizeof(hval); error = bhnd_nvram_value_coerce(value, value_len, BHND_NVRAM_TYPE_STRING, &hval, &hval_len, hvar->type); if (error) { /* If parsing fails, we can likely only make * things worse by trying to synchronize the * variables */ BHND_NV_LOG("error parsing header variable " "'%s=%s': %d\n", name, value, error); } else if (hval_len != hvar->len) { hvar->stale = true; } else if (memcmp(&hval, &hvar->value, hval_len) != 0) { hvar->stale = true; } } /* Seek past the value's terminating '\0' */ io_offset += envp_len; if (io_offset == io_size) { BHND_NV_LOG("missing terminating NUL at offset %#zx\n", io_offset); return (EINVAL); } if (*(p + io_offset) != '\0') { BHND_NV_LOG("invalid terminator '%#hhx' at offset " "%#zx\n", *(p + io_offset), io_offset); return (EINVAL); } /* Update variable count */ bcm->count++; /* Seek to the next record */ if (++io_offset == io_size) { char ch; /* Hit EOF without finding a terminating NUL * byte; we need to grow our buffer and append * it */ io_size++; if ((error = bhnd_nvram_io_setsize(bcm->data, io_size))) return (error); /* Write NUL byte */ ch = '\0'; error = bhnd_nvram_io_write(bcm->data, io_size-1, &ch, sizeof(ch)); if (error) return (error); } /* Check for explicit EOF (encoded as a single empty NUL * terminated string) */ if (*(p + io_offset) == '\0') break; } /* Add non-mirrored header variables to total count variable */ for (size_t i = 0; i < nitems(bcm->hvars); i++) { if (bcm->hvars[i].envp == NULL) bcm->count++; } /* Populate serialization options from our header */ bcm_ver = BCM_NVRAM_GET_BITS(hdr.cfg0, BCM_NVRAM_CFG0_VER); error = bhnd_nvram_plist_append_bytes(bcm->opts, BCM_NVRAM_ENCODE_OPT_VERSION, &bcm_ver, sizeof(bcm_ver), BHND_NVRAM_TYPE_UINT8); if (error) return (error); return (0); } static int bhnd_nvram_bcm_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) { struct bhnd_nvram_bcm *bcm; int error; bcm = (struct bhnd_nvram_bcm *)nv; /* Populate default BCM mirrored header variable set */ _Static_assert(sizeof(bcm->hvars) == sizeof(bhnd_nvram_bcm_hvars), "hvar declarations must match bhnd_nvram_bcm_hvars template"); memcpy(bcm->hvars, bhnd_nvram_bcm_hvars, sizeof(bcm->hvars)); /* Allocate (empty) option list, to be populated by * bhnd_nvram_bcm_init() */ bcm->opts = bhnd_nvram_plist_new(); if (bcm->opts == NULL) return (ENOMEM); /* Parse the BCM input data and initialize our backing * data representation */ if ((error = bhnd_nvram_bcm_init(bcm, io))) { bhnd_nvram_bcm_free(nv); return (error); } return (0); } static void bhnd_nvram_bcm_free(struct bhnd_nvram_data *nv) { struct bhnd_nvram_bcm *bcm = (struct bhnd_nvram_bcm *)nv; if (bcm->data != NULL) bhnd_nvram_io_free(bcm->data); if (bcm->opts != NULL) bhnd_nvram_plist_release(bcm->opts); } size_t bhnd_nvram_bcm_count(struct bhnd_nvram_data *nv) { struct bhnd_nvram_bcm *bcm = (struct bhnd_nvram_bcm *)nv; return (bcm->count); } static bhnd_nvram_plist * bhnd_nvram_bcm_options(struct bhnd_nvram_data *nv) { struct bhnd_nvram_bcm *bcm = (struct bhnd_nvram_bcm *)nv; return (bcm->opts); -} - -static int -bhnd_nvram_bcm_size(struct bhnd_nvram_data *nv, size_t *size) -{ - return (bhnd_nvram_bcm_serialize(nv, NULL, size)); -} - -static int -bhnd_nvram_bcm_serialize(struct bhnd_nvram_data *nv, void *buf, size_t *len) -{ - struct bhnd_nvram_bcm *bcm; - struct bhnd_nvram_bcmhdr hdr; - void *cookiep; - const char *name; - size_t nbytes, limit; - uint8_t crc; - int error; - - bcm = (struct bhnd_nvram_bcm *)nv; - nbytes = 0; - - /* Save the output buffer limit */ - if (buf == NULL) - limit = 0; - else - limit = *len; - - /* Reserve space for the NVRAM header */ - nbytes += sizeof(struct bhnd_nvram_bcmhdr); - - /* Write all variables to the output buffer */ - cookiep = NULL; - while ((name = bhnd_nvram_data_next(nv, &cookiep))) { - uint8_t *outp; - size_t olen; - size_t name_len, val_len; - - if (limit > nbytes) { - outp = (uint8_t *)buf + nbytes; - olen = limit - nbytes; - } else { - outp = NULL; - olen = 0; - } - - /* Determine length of variable name */ - name_len = strlen(name) + 1; - - /* Write the variable name and '=' delimiter */ - if (olen >= name_len) { - /* Copy name */ - memcpy(outp, name, name_len - 1); - - /* Append '=' */ - *(outp + name_len - 1) = '='; - } - - /* Adjust byte counts */ - if (SIZE_MAX - name_len < nbytes) - return (ERANGE); - - nbytes += name_len; - - /* Reposition output */ - if (limit > nbytes) { - outp = (uint8_t *)buf + nbytes; - olen = limit - nbytes; - } else { - outp = NULL; - olen = 0; - } - - /* Coerce to NUL-terminated C string, writing to the output - * buffer (or just calculating the length if outp is NULL) */ - val_len = olen; - error = bhnd_nvram_data_getvar(nv, cookiep, outp, &val_len, - BHND_NVRAM_TYPE_STRING); - - if (error && error != ENOMEM) - return (error); - - /* Adjust byte counts */ - if (SIZE_MAX - val_len < nbytes) - return (ERANGE); - - nbytes += val_len; - } - - /* Write terminating NUL */ - if (nbytes < limit) - *((uint8_t *)buf + nbytes) = '\0'; - nbytes++; - - /* Provide actual size */ - *len = nbytes; - if (buf == NULL || nbytes > limit) { - if (buf != NULL) - return (ENOMEM); - - return (0); - } - - /* Fetch current NVRAM header */ - if ((error = bhnd_nvram_io_read(bcm->data, 0x0, &hdr, sizeof(hdr)))) - return (error); - - /* Update values covered by CRC and write to output buffer */ - hdr.size = htole32(*len); - memcpy(buf, &hdr, sizeof(hdr)); - - /* Calculate new CRC */ - crc = bhnd_nvram_crc8((uint8_t *)buf + BCM_NVRAM_CRC_SKIP, - *len - BCM_NVRAM_CRC_SKIP, BHND_NVRAM_CRC8_INITIAL); - - /* Update header with valid CRC */ - hdr.cfg0 &= ~BCM_NVRAM_CFG0_CRC_MASK; - hdr.cfg0 |= (crc << BCM_NVRAM_CFG0_CRC_SHIFT); - memcpy(buf, &hdr, sizeof(hdr)); - - return (0); } static uint32_t bhnd_nvram_bcm_caps(struct bhnd_nvram_data *nv) { return (BHND_NVRAM_DATA_CAP_READ_PTR|BHND_NVRAM_DATA_CAP_DEVPATHS); } static const char * bhnd_nvram_bcm_next(struct bhnd_nvram_data *nv, void **cookiep) { struct bhnd_nvram_bcm *bcm; struct bhnd_nvram_bcm_hvar *hvar, *hvar_next; const void *ptr; const char *envp, *basep; size_t io_size, io_offset; int error; bcm = (struct bhnd_nvram_bcm *)nv; io_offset = sizeof(struct bhnd_nvram_bcmhdr); io_size = bhnd_nvram_io_getsize(bcm->data) - io_offset; /* Map backing buffer */ error = bhnd_nvram_io_read_ptr(bcm->data, io_offset, &ptr, io_size, NULL); if (error) { BHND_NV_LOG("error mapping backing buffer: %d\n", error); return (NULL); } basep = ptr; /* If cookiep pointers into our header variable array, handle as header * variable iteration. */ hvar = bhnd_nvram_bcm_to_hdrvar(bcm, *cookiep); if (hvar != NULL) { size_t idx; /* Advance to next entry, if any */ idx = bhnd_nvram_bcm_hdrvar_index(bcm, hvar) + 1; /* Find the next header-defined variable that isn't defined in * the NVRAM data, start iteration there */ for (size_t i = idx; i < nitems(bcm->hvars); i++) { hvar_next = &bcm->hvars[i]; if (hvar_next->envp != NULL && !hvar_next->stale) continue; *cookiep = hvar_next; return (hvar_next->name); } /* No further header-defined variables; iteration * complete */ return (NULL); } /* Handle standard NVRAM data iteration */ if (*cookiep == NULL) { /* Start at the first NVRAM data record */ envp = basep; } else { /* Seek to next record */ envp = *cookiep; envp += strlen(envp) + 1; /* key + '\0' */ envp += strlen(envp) + 1; /* value + '\0' */ } /* * Skip entries that have an existing header variable entry that takes * precedence over the NVRAM data value. * * The header's value will be provided when performing header variable * iteration */ while ((size_t)(envp - basep) < io_size && *envp != '\0') { /* Locate corresponding header variable */ hvar = NULL; for (size_t i = 0; i < nitems(bcm->hvars); i++) { if (bcm->hvars[i].envp != envp) continue; hvar = &bcm->hvars[i]; break; } /* If no corresponding hvar entry, or the entry does not take * precedence over this NVRAM value, we can safely return this * value as-is. */ if (hvar == NULL || !hvar->stale) break; /* Seek to next record */ envp += strlen(envp) + 1; /* key + '\0' */ envp += strlen(envp) + 1; /* value + '\0' */ } /* On NVRAM data EOF, try switching to header variables */ if ((size_t)(envp - basep) == io_size || *envp == '\0') { /* Find first valid header variable */ for (size_t i = 0; i < nitems(bcm->hvars); i++) { if (bcm->hvars[i].envp != NULL) continue; *cookiep = &bcm->hvars[i]; return (bcm->hvars[i].name); } /* No header variables */ return (NULL); } *cookiep = __DECONST(void *, envp); return (envp); } static void * bhnd_nvram_bcm_find(struct bhnd_nvram_data *nv, const char *name) { return (bhnd_nvram_data_generic_find(nv, name)); } static int bhnd_nvram_bcm_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { struct bhnd_nvram_bcm *bcm; struct bhnd_nvram_bcm_hvar *hvar1, *hvar2; bcm = (struct bhnd_nvram_bcm *)nv; hvar1 = bhnd_nvram_bcm_to_hdrvar(bcm, cookiep1); hvar2 = bhnd_nvram_bcm_to_hdrvar(bcm, cookiep2); /* Header variables are always ordered below any variables defined * in the BCM data */ if (hvar1 != NULL && hvar2 == NULL) { return (1); /* hvar follows non-hvar */ } else if (hvar1 == NULL && hvar2 != NULL) { return (-1); /* non-hvar precedes hvar */ } /* Otherwise, both cookies are either hvars or non-hvars. We can * safely fall back on pointer order, which will provide a correct * ordering matching the behavior of bhnd_nvram_data_next() for * both cases */ if (cookiep1 < cookiep2) return (-1); if (cookiep1 > cookiep2) return (1); return (0); } static int bhnd_nvram_bcm_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type) { return (bhnd_nvram_data_generic_rp_getvar(nv, cookiep, buf, len, type)); } static int bhnd_nvram_bcm_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { return (bhnd_nvram_data_generic_rp_copy_val(nv, cookiep, value)); } static const void * bhnd_nvram_bcm_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { struct bhnd_nvram_bcm *bcm; struct bhnd_nvram_bcm_hvar *hvar; const char *envp; bcm = (struct bhnd_nvram_bcm *)nv; /* Handle header variables */ if ((hvar = bhnd_nvram_bcm_to_hdrvar(bcm, cookiep)) != NULL) { BHND_NV_ASSERT(bhnd_nvram_value_check_aligned(&hvar->value, hvar->len, hvar->type) == 0, ("value misaligned")); *type = hvar->type; *len = hvar->len; return (&hvar->value); } /* Cookie points to key\0value\0 -- get the value address */ BHND_NV_ASSERT(cookiep != NULL, ("NULL cookiep")); envp = cookiep; envp += strlen(envp) + 1; /* key + '\0' */ *len = strlen(envp) + 1; /* value + '\0' */ *type = BHND_NVRAM_TYPE_STRING; return (envp); } static const char * bhnd_nvram_bcm_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { struct bhnd_nvram_bcm *bcm; struct bhnd_nvram_bcm_hvar *hvar; bcm = (struct bhnd_nvram_bcm *)nv; /* Handle header variables */ if ((hvar = bhnd_nvram_bcm_to_hdrvar(bcm, cookiep)) != NULL) { return (hvar->name); } /* Cookie points to key\0value\0 */ return (cookiep); } static int bhnd_nvram_bcm_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { bhnd_nvram_val *str; int error; /* Name (trimmed of any path prefix) must be valid */ if (!bhnd_nvram_validate_name(bhnd_nvram_trim_path_name(name))) return (EINVAL); /* Value must be bcm-formatted string */ error = bhnd_nvram_val_convert_new(&str, &bhnd_nvram_val_bcm_string_fmt, value, BHND_NVRAM_VAL_DYNAMIC); if (error) return (error); /* Success. Transfer result ownership to the caller. */ *result = str; return (0); } static int bhnd_nvram_bcm_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { /* We permit deletion of any variable */ return (0); } /** * Return the internal BCM data reference for a header-defined variable * with @p name, or NULL if none exists. */ static struct bhnd_nvram_bcm_hvar * bhnd_nvram_bcm_gethdrvar(struct bhnd_nvram_bcm *bcm, const char *name) { for (size_t i = 0; i < nitems(bcm->hvars); i++) { if (strcmp(bcm->hvars[i].name, name) == 0) return (&bcm->hvars[i]); } /* Not found */ return (NULL); } /** * If @p cookiep references a header-defined variable, return the * internal BCM data reference. Otherwise, returns NULL. */ static struct bhnd_nvram_bcm_hvar * bhnd_nvram_bcm_to_hdrvar(struct bhnd_nvram_bcm *bcm, void *cookiep) { #ifdef BHND_NVRAM_INVARIANTS uintptr_t base, ptr; #endif /* If the cookie falls within the hvar array, it's a * header variable cookie */ if (nitems(bcm->hvars) == 0) return (NULL); if (cookiep < (void *)&bcm->hvars[0]) return (NULL); if (cookiep > (void *)&bcm->hvars[nitems(bcm->hvars)-1]) return (NULL); #ifdef BHND_NVRAM_INVARIANTS base = (uintptr_t)bcm->hvars; ptr = (uintptr_t)cookiep; BHND_NV_ASSERT((ptr - base) % sizeof(bcm->hvars[0]) == 0, ("misaligned hvar pointer %p/%p", cookiep, bcm->hvars)); #endif /* INVARIANTS */ return ((struct bhnd_nvram_bcm_hvar *)cookiep); } /** * Return the index of @p hdrvar within @p bcm's backing hvars array. */ static size_t bhnd_nvram_bcm_hdrvar_index(struct bhnd_nvram_bcm *bcm, struct bhnd_nvram_bcm_hvar *hdrvar) { BHND_NV_ASSERT(bhnd_nvram_bcm_to_hdrvar(bcm, (void *)hdrvar) != NULL, ("%p is not a valid hdrvar reference", hdrvar)); return (hdrvar - &bcm->hvars[0]); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmraw.c (revision 310297) @@ -1,447 +1,477 @@ /*- * Copyright (c) 2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" /* * Broadcom-RAW NVRAM data class. * * The Broadcom NVRAM NUL-delimited ASCII format is used by most * Broadcom SoCs. * * The NVRAM data is encoded as a stream of of NUL-terminated 'key=value' * strings; the end of the stream is denoted by a single extra NUL character. */ struct bhnd_nvram_bcmraw; /** BCM-RAW NVRAM data class instance */ struct bhnd_nvram_bcmraw { struct bhnd_nvram_data nv; /**< common instance state */ char *data; /**< backing buffer */ size_t size; /**< buffer size */ size_t count; /**< variable count */ }; BHND_NVRAM_DATA_CLASS_DEFN(bcmraw, "Broadcom (RAW)", - sizeof(struct bhnd_nvram_bcmraw)) + BHND_NVRAM_DATA_CAP_DEVPATHS, sizeof(struct bhnd_nvram_bcmraw)) static int bhnd_nvram_bcmraw_probe(struct bhnd_nvram_io *io) { char envp[16]; size_t envp_len; size_t io_size; int error; io_size = bhnd_nvram_io_getsize(io); /* * Fetch initial bytes */ envp_len = bhnd_nv_ummin(sizeof(envp), io_size); if ((error = bhnd_nvram_io_read(io, 0x0, envp, envp_len))) return (error); /* An empty BCM-RAW buffer should still contain a single terminating * NUL */ if (envp_len == 0) return (ENXIO); if (envp_len == 1) { if (envp[0] != '\0') return (ENXIO); return (BHND_NVRAM_DATA_PROBE_MAYBE); } /* Must contain only printable ASCII characters delimited * by NUL record delimiters */ for (size_t i = 0; i < envp_len; i++) { char c = envp[i]; /* If we hit a newline, this is probably BCM-TXT */ if (c == '\n') return (ENXIO); if (c == '\0' && !bhnd_nv_isprint(c)) continue; } /* A valid BCM-RAW buffer should contain a terminating NUL for * the last record, followed by a final empty record terminated by * NUL */ envp_len = 2; if (io_size < envp_len) return (ENXIO); if ((error = bhnd_nvram_io_read(io, io_size-envp_len, envp, envp_len))) return (error); if (envp[0] != '\0' || envp[1] != '\0') return (ENXIO); return (BHND_NVRAM_DATA_PROBE_MAYBE + 1); } +static int +bhnd_nvram_bcmraw_serialize(bhnd_nvram_data_class *cls, bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, size_t *olen) +{ + bhnd_nvram_prop *prop; + size_t limit, nbytes; + int error; + + /* Determine output byte limit */ + if (outp != NULL) + limit = *olen; + else + limit = 0; + + nbytes = 0; + + /* Write all properties */ + prop = NULL; + while ((prop = bhnd_nvram_plist_next(props, prop)) != NULL) { + const char *name; + char *p; + size_t prop_limit; + size_t name_len, value_len; + + if (outp == NULL || limit < nbytes) { + p = NULL; + prop_limit = 0; + } else { + p = ((char *)outp) + nbytes; + prop_limit = limit - nbytes; + } + + /* Fetch and write name + '=' to output */ + name = bhnd_nvram_prop_name(prop); + name_len = strlen(name) + 1; + + if (prop_limit > name_len) { + memcpy(p, name, name_len - 1); + p[name_len - 1] = '='; + + prop_limit -= name_len; + p += name_len; + } else { + prop_limit = 0; + p = NULL; + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < name_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += name_len; + + /* Attempt to write NUL-terminated value to output */ + value_len = prop_limit; + error = bhnd_nvram_prop_encode(prop, p, &value_len, + BHND_NVRAM_TYPE_STRING); + + /* If encoding failed for any reason other than ENOMEM (which + * we'll detect and report after encoding all properties), + * return immediately */ + if (error && error != ENOMEM) { + BHND_NV_LOG("error serializing %s to required type " + "%s: %d\n", name, + bhnd_nvram_type_name(BHND_NVRAM_TYPE_STRING), + error); + return (error); + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < value_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += value_len; + } + + /* Write terminating '\0' */ + if (limit > nbytes) + *((char *)outp + nbytes) = '\0'; + + if (nbytes == SIZE_MAX) + return (EFTYPE); /* would overflow size_t */ + else + nbytes++; + + /* Provide required length */ + *olen = nbytes; + if (limit < *olen) { + if (outp == NULL) + return (0); + + return (ENOMEM); + } + + return (0); +} + /** * Initialize @p bcm with the provided NVRAM data mapped by @p src. * * @param bcm A newly allocated data instance. */ static int bhnd_nvram_bcmraw_init(struct bhnd_nvram_bcmraw *bcm, struct bhnd_nvram_io *src) { size_t io_size; size_t capacity, offset; int error; /* Fetch the input image size */ io_size = bhnd_nvram_io_getsize(src); /* Allocate a buffer large enough to hold the NVRAM image, and * an extra EOF-signaling NUL (on the chance it's missing from the * source data) */ if (io_size == SIZE_MAX) return (ENOMEM); capacity = io_size + 1 /* room for extra NUL */; bcm->size = io_size; if ((bcm->data = bhnd_nv_malloc(capacity)) == NULL) return (ENOMEM); /* Copy in the NVRAM image */ if ((error = bhnd_nvram_io_read(src, 0x0, bcm->data, io_size))) return (error); /* Process the buffer */ bcm->count = 0; for (offset = 0; offset < bcm->size; offset++) { char *envp; const char *name, *value; size_t envp_len; size_t name_len, value_len; /* Parse the key=value string */ envp = (char *) (bcm->data + offset); envp_len = strnlen(envp, bcm->size - offset); error = bhnd_nvram_parse_env(envp, envp_len, '=', &name, &name_len, &value, &value_len); if (error) { BHND_NV_LOG("error parsing envp at offset %#zx: %d\n", offset, error); return (error); } /* Insert a '\0' character, replacing the '=' delimiter and * allowing us to vend references directly to the variable * name */ *(envp + name_len) = '\0'; /* Add to variable count */ bcm->count++; /* Seek past the value's terminating '\0' */ offset += envp_len; if (offset == io_size) { BHND_NV_LOG("missing terminating NUL at offset %#zx\n", offset); return (EINVAL); } /* If we hit EOF without finding a terminating NUL * byte, we need to append it */ if (++offset == bcm->size) { BHND_NV_ASSERT(offset < capacity, ("appending past end of buffer")); bcm->size++; *(bcm->data + offset) = '\0'; } /* Check for explicit EOF (encoded as a single empty NUL * terminated string) */ if (*(bcm->data + offset) == '\0') break; } /* Reclaim any unused space in he backing buffer */ if (offset < bcm->size) { bcm->data = bhnd_nv_reallocf(bcm->data, bcm->size); if (bcm->data == NULL) return (ENOMEM); } return (0); } static int bhnd_nvram_bcmraw_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) { struct bhnd_nvram_bcmraw *bcm; int error; bcm = (struct bhnd_nvram_bcmraw *)nv; /* Parse the BCM input data and initialize our backing * data representation */ if ((error = bhnd_nvram_bcmraw_init(bcm, io))) { bhnd_nvram_bcmraw_free(nv); return (error); } return (0); } static void bhnd_nvram_bcmraw_free(struct bhnd_nvram_data *nv) { struct bhnd_nvram_bcmraw *bcm = (struct bhnd_nvram_bcmraw *)nv; if (bcm->data != NULL) bhnd_nv_free(bcm->data); } -static size_t -bhnd_nvram_bcmraw_count(struct bhnd_nvram_data *nv) -{ - struct bhnd_nvram_bcmraw *bcm = (struct bhnd_nvram_bcmraw *)nv; - - return (bcm->count); -} - static bhnd_nvram_plist * bhnd_nvram_bcmraw_options(struct bhnd_nvram_data *nv) { return (NULL); } -static int -bhnd_nvram_bcmraw_size(struct bhnd_nvram_data *nv, size_t *size) +static size_t +bhnd_nvram_bcmraw_count(struct bhnd_nvram_data *nv) { - return (bhnd_nvram_bcmraw_serialize(nv, NULL, size)); -} + struct bhnd_nvram_bcmraw *bcm = (struct bhnd_nvram_bcmraw *)nv; -static int -bhnd_nvram_bcmraw_serialize(struct bhnd_nvram_data *nv, void *buf, size_t *len) -{ - struct bhnd_nvram_bcmraw *bcm; - char * const p = (char *)buf; - size_t limit; - size_t offset; - - bcm = (struct bhnd_nvram_bcmraw *)nv; - - /* Save the output buffer limit */ - if (buf == NULL) - limit = 0; - else - limit = *len; - - /* The serialized form will be exactly the length - * of our backing buffer representation */ - *len = bcm->size; - - /* Skip serialization if not requested, or report ENOMEM if - * buffer is too small */ - if (buf == NULL) { - return (0); - } else if (*len > limit) { - return (ENOMEM); - } - - /* Write all variables to the output buffer */ - memcpy(buf, bcm->data, *len); - - /* Rewrite all '\0' delimiters back to '=' */ - offset = 0; - while (offset < bcm->size) { - size_t name_len, value_len; - - name_len = strlen(p + offset); - - /* EOF? */ - if (name_len == 0) { - BHND_NV_ASSERT(*(p + offset) == '\0', - ("no NUL terminator")); - - offset++; - break; - } - - /* Rewrite 'name\0' to 'name=' */ - offset += name_len; - BHND_NV_ASSERT(*(p + offset) == '\0', ("incorrect offset")); - - *(p + offset) = '='; - offset++; - - value_len = strlen(p + offset); - offset += value_len + 1; - } - - return (0); + return (bcm->count); } static uint32_t bhnd_nvram_bcmraw_caps(struct bhnd_nvram_data *nv) { return (BHND_NVRAM_DATA_CAP_READ_PTR|BHND_NVRAM_DATA_CAP_DEVPATHS); } static const char * bhnd_nvram_bcmraw_next(struct bhnd_nvram_data *nv, void **cookiep) { struct bhnd_nvram_bcmraw *bcm; const char *envp; bcm = (struct bhnd_nvram_bcmraw *)nv; if (*cookiep == NULL) { /* Start at the first NVRAM data record */ envp = bcm->data; } else { /* Seek to next record */ envp = *cookiep; envp += strlen(envp) + 1; /* key + '\0' */ envp += strlen(envp) + 1; /* value + '\0' */ } /* EOF? */ if (*envp == '\0') return (NULL); *cookiep = (void *)(uintptr_t)envp; return (envp); } static void * bhnd_nvram_bcmraw_find(struct bhnd_nvram_data *nv, const char *name) { return (bhnd_nvram_data_generic_find(nv, name)); } static int bhnd_nvram_bcmraw_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { if (cookiep1 < cookiep2) return (-1); if (cookiep1 > cookiep2) return (1); return (0); } static int bhnd_nvram_bcmraw_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type) { return (bhnd_nvram_data_generic_rp_getvar(nv, cookiep, buf, len, type)); } static int bhnd_nvram_bcmraw_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { return (bhnd_nvram_data_generic_rp_copy_val(nv, cookiep, value)); } static const void * bhnd_nvram_bcmraw_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { const char *envp; /* Cookie points to key\0value\0 -- get the value address */ envp = cookiep; envp += strlen(envp) + 1; /* key + '\0' */ *len = strlen(envp) + 1; /* value + '\0' */ *type = BHND_NVRAM_TYPE_STRING; return (envp); } static const char * bhnd_nvram_bcmraw_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { /* Cookie points to key\0value\0 */ return (cookiep); } static int bhnd_nvram_bcmraw_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { bhnd_nvram_val *str; int error; /* Name (trimmed of any path prefix) must be valid */ if (!bhnd_nvram_validate_name(bhnd_nvram_trim_path_name(name))) return (EINVAL); /* Value must be bcm-formatted string */ error = bhnd_nvram_val_convert_new(&str, &bhnd_nvram_val_bcm_string_fmt, value, BHND_NVRAM_VAL_DYNAMIC); if (error) return (error); /* Success. Transfer result ownership to the caller. */ *result = str; return (0); } static int bhnd_nvram_bcmraw_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { /* We permit deletion of any variable */ return (0); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmreg.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmreg.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_bcmreg.h (revision 310297) @@ -1,73 +1,78 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_BCMREG_H_ #define _BHND_NVRAM_BHND_NVRAM_BCMREG_H_ -#define BCM_NVRAM_GET_BITS(_value, _field) \ +#define BCM_NVRAM_GET_BITS(_value, _field) \ ((_value & _field ## _MASK) >> _field ## _SHIFT) +#define BCM_NVRAM_SET_BITS(_value, _field, _bits) \ + ((_value & ~(_field ## _MASK)) | \ + (((_bits) << _field ## _SHIFT) & _field ## _MASK)) + /* BCM NVRAM header fields */ #define BCM_NVRAM_MAGIC 0x48534C46 /* 'FLSH' */ #define BCM_NVRAM_VERSION 1 #define BCM_NVRAM_CRC_SKIP 9 /* skip magic, size, and crc8 */ #define BCM_NVRAM_CFG0_CRC_MASK 0x000000FF #define BCM_NVRAM_CFG0_CRC_SHIFT 0 #define BCM_NVRAM_CFG0_VER_MASK 0x0000FF00 #define BCM_NVRAM_CFG0_VER_SHIFT 8 +#define BCM_NVRAM_CFG0_VER_DEFAULT 1 /* default version */ #define BCM_NVRAM_CFG0_SDRAM_INIT_FIELD cfg0 #define BCM_NVRAM_CFG0_SDRAM_INIT_MASK 0xFFFF0000 #define BCM_NVRAM_CFG0_SDRAM_INIT_SHIFT 16 #define BCM_NVRAM_CFG0_SDRAM_INIT_VAR "sdram_init" #define BCM_NVRAM_CFG0_SDRAM_INIT_FMT "0x%04x" #define BCM_NVRAM_CFG1_SDRAM_CFG_FIELD cfg1 #define BCM_NVRAM_CFG1_SDRAM_CFG_MASK 0x0000FFFF #define BCM_NVRAM_CFG1_SDRAM_CFG_SHIFT 0 #define BCM_NVRAM_CFG1_SDRAM_CFG_VAR "sdram_config" #define BCM_NVRAM_CFG1_SDRAM_CFG_FMT "0x%04x" #define BCM_NVRAM_CFG1_SDRAM_REFRESH_FIELD cfg1 #define BCM_NVRAM_CFG1_SDRAM_REFRESH_MASK 0xFFFF0000 #define BCM_NVRAM_CFG1_SDRAM_REFRESH_SHIFT 16 #define BCM_NVRAM_CFG1_SDRAM_REFRESH_VAR "sdram_refresh" #define BCM_NVRAM_CFG1_SDRAM_REFRESH_FMT "0x%04x" #define BCM_NVRAM_SDRAM_NCDL_FIELD sdram_ncdl #define BCM_NVRAM_SDRAM_NCDL_MASK UINT32_MAX #define BCM_NVRAM_SDRAM_NCDL_SHIFT 0 #define BCM_NVRAM_SDRAM_NCDL_VAR "sdram_ncdl" #define BCM_NVRAM_SDRAM_NCDL_FMT "0x%08x" #endif /* _BHND_NVRAM_BHND_NVRAM_BCMREG_H_ */ Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_btxt.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_btxt.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_btxt.c (revision 310297) @@ -1,697 +1,745 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_data_bcmreg.h" /* for BCM_NVRAM_MAGIC */ /** * Broadcom "Board Text" data class. * * This format is used to provide external NVRAM data for some * fullmac WiFi devices, and as an input format when programming * NVRAM/SPROM/OTP. */ struct bhnd_nvram_btxt { struct bhnd_nvram_data nv; /**< common instance state */ struct bhnd_nvram_io *data; /**< memory-backed board text data */ size_t count; /**< variable count */ }; BHND_NVRAM_DATA_CLASS_DEFN(btxt, "Broadcom Board Text", - sizeof(struct bhnd_nvram_btxt)) + BHND_NVRAM_DATA_CAP_DEVPATHS, sizeof(struct bhnd_nvram_btxt)) /** Minimal identification header */ union bhnd_nvram_btxt_ident { uint32_t bcm_magic; char btxt[8]; }; static void *bhnd_nvram_btxt_offset_to_cookiep(struct bhnd_nvram_btxt *btxt, size_t io_offset); static size_t bhnd_nvram_btxt_cookiep_to_offset(struct bhnd_nvram_btxt *btxt, void *cookiep); static int bhnd_nvram_btxt_entry_len(struct bhnd_nvram_io *io, size_t offset, size_t *line_len, size_t *env_len); static int bhnd_nvram_btxt_seek_next(struct bhnd_nvram_io *io, size_t *offset); static int bhnd_nvram_btxt_seek_eol(struct bhnd_nvram_io *io, size_t *offset); static int bhnd_nvram_btxt_probe(struct bhnd_nvram_io *io) { union bhnd_nvram_btxt_ident ident; char c; int error; /* Look at the initial header for something that looks like * an ASCII board text file */ if ((error = bhnd_nvram_io_read(io, 0x0, &ident, sizeof(ident)))) return (error); /* The BCM NVRAM format uses a 'FLSH' little endian magic value, which * shouldn't be interpreted as BTXT */ if (le32toh(ident.bcm_magic) == BCM_NVRAM_MAGIC) return (ENXIO); /* Don't match on non-ASCII/non-printable data */ for (size_t i = 0; i < nitems(ident.btxt); i++) { c = ident.btxt[i]; if (!bhnd_nv_isprint(c)) return (ENXIO); } /* The first character should either be a valid key char (alpha), * whitespace, or the start of a comment ('#') */ c = ident.btxt[0]; if (!bhnd_nv_isspace(c) && !bhnd_nv_isalpha(c) && c != '#') return (ENXIO); /* We assert a low priority, given that we've only scanned an * initial few bytes of the file. */ return (BHND_NVRAM_DATA_PROBE_MAYBE); } +static int +bhnd_nvram_btxt_serialize(bhnd_nvram_data_class *cls, bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, size_t *olen) +{ + bhnd_nvram_prop *prop; + size_t limit, nbytes; + int error; + + /* Determine output byte limit */ + if (outp != NULL) + limit = *olen; + else + limit = 0; + + nbytes = 0; + + /* Write all properties */ + prop = NULL; + while ((prop = bhnd_nvram_plist_next(props, prop)) != NULL) { + const char *name; + char *p; + size_t prop_limit; + size_t name_len, value_len; + + if (outp == NULL || limit < nbytes) { + p = NULL; + prop_limit = 0; + } else { + p = ((char *)outp) + nbytes; + prop_limit = limit - nbytes; + } + + /* Fetch and write 'name=' to output */ + name = bhnd_nvram_prop_name(prop); + name_len = strlen(name) + 1; + + if (prop_limit > name_len) { + memcpy(p, name, name_len - 1); + p[name_len - 1] = '='; + + prop_limit -= name_len; + p += name_len; + } else { + prop_limit = 0; + p = NULL; + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < name_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += name_len; + + /* Write NUL-terminated value to output, rewrite NUL as + * '\n' record delimiter */ + value_len = prop_limit; + error = bhnd_nvram_prop_encode(prop, p, &value_len, + BHND_NVRAM_TYPE_STRING); + if (p != NULL && error == 0) { + /* Replace trailing '\0' with newline */ + BHND_NV_ASSERT(value_len > 0, ("string length missing " + "minimum required trailing NUL")); + + *(p + (value_len - 1)) = '\n'; + } else if (error && error != ENOMEM) { + /* If encoding failed for any reason other than ENOMEM + * (which we'll detect and report after encoding all + * properties), return immediately */ + BHND_NV_LOG("error serializing %s to required type " + "%s: %d\n", name, + bhnd_nvram_type_name(BHND_NVRAM_TYPE_STRING), + error); + return (error); + } + + /* Advance byte count */ + if (SIZE_MAX - nbytes < value_len) + return (EFTYPE); /* would overflow size_t */ + + nbytes += value_len; + } + + /* Provide required length */ + *olen = nbytes; + if (limit < *olen) { + if (outp == NULL) + return (0); + + return (ENOMEM); + } + + return (0); +} + /** * Initialize @p btxt with the provided board text data mapped by @p src. * * @param btxt A newly allocated data instance. */ static int bhnd_nvram_btxt_init(struct bhnd_nvram_btxt *btxt, struct bhnd_nvram_io *src) { const void *ptr; const char *name, *value; size_t name_len, value_len; size_t line_len, env_len; size_t io_offset, io_size, str_size; int error; BHND_NV_ASSERT(btxt->data == NULL, ("btxt data already allocated")); if ((btxt->data = bhnd_nvram_iobuf_copy(src)) == NULL) return (ENOMEM); io_size = bhnd_nvram_io_getsize(btxt->data); io_offset = 0; /* Fetch a pointer mapping the entirity of the board text data */ error = bhnd_nvram_io_read_ptr(btxt->data, 0x0, &ptr, io_size, NULL); if (error) return (error); /* Determine the actual size, minus any terminating NUL. We * parse NUL-terminated C strings, but do not include NUL termination * in our internal or serialized representations */ str_size = strnlen(ptr, io_size); /* If the terminating NUL is not found at the end of the buffer, * this is BCM-RAW or other NUL-delimited NVRAM format. */ if (str_size < io_size && str_size + 1 < io_size) return (EINVAL); /* Adjust buffer size to account for NUL termination (if any) */ io_size = str_size; if ((error = bhnd_nvram_io_setsize(btxt->data, io_size))) return (error); /* Process the buffer */ btxt->count = 0; while (io_offset < io_size) { const void *envp; /* Seek to the next key=value entry */ if ((error = bhnd_nvram_btxt_seek_next(btxt->data, &io_offset))) return (error); /* Determine the entry and line length */ error = bhnd_nvram_btxt_entry_len(btxt->data, io_offset, &line_len, &env_len); if (error) return (error); /* EOF? */ if (env_len == 0) { BHND_NV_ASSERT(io_offset == io_size, ("zero-length record returned from " "bhnd_nvram_btxt_seek_next()")); break; } /* Fetch a pointer to the line start */ error = bhnd_nvram_io_read_ptr(btxt->data, io_offset, &envp, env_len, NULL); if (error) return (error); /* Parse the key=value string */ error = bhnd_nvram_parse_env(envp, env_len, '=', &name, &name_len, &value, &value_len); if (error) { return (error); } /* Insert a '\0' character, replacing the '=' delimiter and * allowing us to vend references directly to the variable * name */ error = bhnd_nvram_io_write(btxt->data, io_offset+name_len, &(char){'\0'}, 1); if (error) return (error); /* Add to variable count */ btxt->count++; /* Advance past EOL */ io_offset += line_len; } return (0); } static int bhnd_nvram_btxt_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) { struct bhnd_nvram_btxt *btxt; int error; /* Allocate and initialize the BTXT data instance */ btxt = (struct bhnd_nvram_btxt *)nv; /* Parse the BTXT input data and initialize our backing * data representation */ if ((error = bhnd_nvram_btxt_init(btxt, io))) { bhnd_nvram_btxt_free(nv); return (error); } return (0); } static void bhnd_nvram_btxt_free(struct bhnd_nvram_data *nv) { struct bhnd_nvram_btxt *btxt = (struct bhnd_nvram_btxt *)nv; if (btxt->data != NULL) bhnd_nvram_io_free(btxt->data); } size_t bhnd_nvram_btxt_count(struct bhnd_nvram_data *nv) { struct bhnd_nvram_btxt *btxt = (struct bhnd_nvram_btxt *)nv; return (btxt->count); } static bhnd_nvram_plist * bhnd_nvram_btxt_options(struct bhnd_nvram_data *nv) { return (NULL); -} - -static int -bhnd_nvram_btxt_size(struct bhnd_nvram_data *nv, size_t *size) -{ - struct bhnd_nvram_btxt *btxt = (struct bhnd_nvram_btxt *)nv; - - /* The serialized form will be identical in length - * to our backing buffer representation */ - *size = bhnd_nvram_io_getsize(btxt->data); - return (0); -} - -static int -bhnd_nvram_btxt_serialize(struct bhnd_nvram_data *nv, void *buf, size_t *len) -{ - struct bhnd_nvram_btxt *btxt; - size_t limit; - int error; - - btxt = (struct bhnd_nvram_btxt *)nv; - - limit = *len; - - /* Provide actual output size */ - if ((error = bhnd_nvram_data_size(nv, len))) - return (error); - - if (buf == NULL) { - return (0); - } else if (limit < *len) { - return (ENOMEM); - } - - /* Copy our internal representation to the output buffer */ - if ((error = bhnd_nvram_io_read(btxt->data, 0x0, buf, *len))) - return (error); - - /* Restore the original key=value format, rewriting all '\0' - * key\0value delimiters back to '=' */ - for (char *p = buf; (size_t)(p - (char *)buf) < *len; p++) { - if (*p == '\0') - *p = '='; - } - - return (0); } static uint32_t bhnd_nvram_btxt_caps(struct bhnd_nvram_data *nv) { return (BHND_NVRAM_DATA_CAP_READ_PTR|BHND_NVRAM_DATA_CAP_DEVPATHS); } static void * bhnd_nvram_btxt_find(struct bhnd_nvram_data *nv, const char *name) { return (bhnd_nvram_data_generic_find(nv, name)); } static const char * bhnd_nvram_btxt_next(struct bhnd_nvram_data *nv, void **cookiep) { struct bhnd_nvram_btxt *btxt; const void *nptr; size_t io_offset, io_size; int error; btxt = (struct bhnd_nvram_btxt *)nv; io_size = bhnd_nvram_io_getsize(btxt->data); if (*cookiep == NULL) { /* Start search at initial file offset */ io_offset = 0x0; } else { /* Start search after the current entry */ io_offset = bhnd_nvram_btxt_cookiep_to_offset(btxt, *cookiep); /* Scan past the current entry by finding the next newline */ error = bhnd_nvram_btxt_seek_eol(btxt->data, &io_offset); if (error) { BHND_NV_LOG("unexpected error in seek_eol(): %d\n", error); return (NULL); } } /* Already at EOF? */ if (io_offset == io_size) return (NULL); /* Seek to the first valid entry, or EOF */ if ((error = bhnd_nvram_btxt_seek_next(btxt->data, &io_offset))) { BHND_NV_LOG("unexpected error in seek_next(): %d\n", error); return (NULL); } /* Hit EOF? */ if (io_offset == io_size) return (NULL); /* Provide the new cookie for this offset */ *cookiep = bhnd_nvram_btxt_offset_to_cookiep(btxt, io_offset); /* Fetch the name pointer; it must be at least 1 byte long */ error = bhnd_nvram_io_read_ptr(btxt->data, io_offset, &nptr, 1, NULL); if (error) { BHND_NV_LOG("unexpected error in read_ptr(): %d\n", error); return (NULL); } /* Return the name pointer */ return (nptr); } static int bhnd_nvram_btxt_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { if (cookiep1 < cookiep2) return (-1); if (cookiep1 > cookiep2) return (1); return (0); } static int bhnd_nvram_btxt_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type) { return (bhnd_nvram_data_generic_rp_getvar(nv, cookiep, buf, len, type)); } static int bhnd_nvram_btxt_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { return (bhnd_nvram_data_generic_rp_copy_val(nv, cookiep, value)); } const void * bhnd_nvram_btxt_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { struct bhnd_nvram_btxt *btxt; const void *eptr; const char *vptr; size_t io_offset, io_size; size_t line_len, env_len; int error; btxt = (struct bhnd_nvram_btxt *)nv; io_size = bhnd_nvram_io_getsize(btxt->data); io_offset = bhnd_nvram_btxt_cookiep_to_offset(btxt, cookiep); /* At EOF? */ if (io_offset == io_size) return (NULL); /* Determine the entry length */ error = bhnd_nvram_btxt_entry_len(btxt->data, io_offset, &line_len, &env_len); if (error) { BHND_NV_LOG("unexpected error in entry_len(): %d\n", error); return (NULL); } /* Fetch the entry's value pointer and length */ error = bhnd_nvram_io_read_ptr(btxt->data, io_offset, &eptr, env_len, NULL); if (error) { BHND_NV_LOG("unexpected error in read_ptr(): %d\n", error); return (NULL); } error = bhnd_nvram_parse_env(eptr, env_len, '\0', NULL, NULL, &vptr, len); if (error) { BHND_NV_LOG("unexpected error in parse_env(): %d\n", error); return (NULL); } /* Type is always CSTR */ *type = BHND_NVRAM_TYPE_STRING; return (vptr); } static const char * bhnd_nvram_btxt_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { struct bhnd_nvram_btxt *btxt; const void *ptr; size_t io_offset, io_size; int error; btxt = (struct bhnd_nvram_btxt *)nv; io_size = bhnd_nvram_io_getsize(btxt->data); io_offset = bhnd_nvram_btxt_cookiep_to_offset(btxt, cookiep); /* At EOF? */ if (io_offset == io_size) BHND_NV_PANIC("invalid cookiep: %p", cookiep); /* Variable name is found directly at the given offset; trailing * NUL means we can assume that it's at least 1 byte long */ error = bhnd_nvram_io_read_ptr(btxt->data, io_offset, &ptr, 1, NULL); if (error) BHND_NV_PANIC("unexpected error in read_ptr(): %d\n", error); return (ptr); } /** * Return a cookiep for the given I/O offset. */ static void * bhnd_nvram_btxt_offset_to_cookiep(struct bhnd_nvram_btxt *btxt, size_t io_offset) { const void *ptr; int error; BHND_NV_ASSERT(io_offset < bhnd_nvram_io_getsize(btxt->data), ("io_offset %zu out-of-range", io_offset)); BHND_NV_ASSERT(io_offset < UINTPTR_MAX, ("io_offset %#zx exceeds UINTPTR_MAX", io_offset)); error = bhnd_nvram_io_read_ptr(btxt->data, 0x0, &ptr, io_offset, NULL); if (error) BHND_NV_PANIC("error mapping offset %zu: %d", io_offset, error); ptr = (const uint8_t *)ptr + io_offset; return (__DECONST(void *, ptr)); } /* Convert a cookiep back to an I/O offset */ static size_t bhnd_nvram_btxt_cookiep_to_offset(struct bhnd_nvram_btxt *btxt, void *cookiep) { const void *ptr; intptr_t offset; size_t io_size; int error; BHND_NV_ASSERT(cookiep != NULL, ("null cookiep")); io_size = bhnd_nvram_io_getsize(btxt->data); error = bhnd_nvram_io_read_ptr(btxt->data, 0x0, &ptr, io_size, NULL); if (error) BHND_NV_PANIC("error mapping offset %zu: %d", io_size, error); offset = (const uint8_t *)cookiep - (const uint8_t *)ptr; BHND_NV_ASSERT(offset >= 0, ("invalid cookiep")); BHND_NV_ASSERT((uintptr_t)offset < SIZE_MAX, ("cookiep > SIZE_MAX)")); BHND_NV_ASSERT((uintptr_t)offset <= io_size, ("cookiep > io_size)")); return ((size_t)offset); } /* Determine the entry length and env 'key=value' string length of the entry * at @p offset */ static int bhnd_nvram_btxt_entry_len(struct bhnd_nvram_io *io, size_t offset, size_t *line_len, size_t *env_len) { const uint8_t *baseptr, *p; const void *rbuf; size_t nbytes; int error; /* Fetch read buffer */ if ((error = bhnd_nvram_io_read_ptr(io, offset, &rbuf, 0, &nbytes))) return (error); /* Find record termination (EOL, or '#') */ p = rbuf; baseptr = rbuf; while ((size_t)(p - baseptr) < nbytes) { if (*p == '#' || *p == '\n' || *p == '\r') break; p++; } /* Got line length, now trim any trailing whitespace to determine * actual env length */ *line_len = p - baseptr; *env_len = *line_len; for (size_t i = 0; i < *line_len; i++) { char c = baseptr[*line_len - i - 1]; if (!bhnd_nv_isspace(c)) break; *env_len -= 1; } return (0); } /* Seek past the next line ending (\r, \r\n, or \n) */ static int bhnd_nvram_btxt_seek_eol(struct bhnd_nvram_io *io, size_t *offset) { const uint8_t *baseptr, *p; const void *rbuf; size_t nbytes; int error; /* Fetch read buffer */ if ((error = bhnd_nvram_io_read_ptr(io, *offset, &rbuf, 0, &nbytes))) return (error); baseptr = rbuf; p = rbuf; while ((size_t)(p - baseptr) < nbytes) { char c = *p; /* Advance to next char. The next position may be EOF, in which * case a read will be invalid */ p++; if (c == '\r') { /* CR, check for optional LF */ if ((size_t)(p - baseptr) < nbytes) { if (*p == '\n') p++; } break; } else if (c == '\n') { break; } } /* Hit newline or EOF */ *offset += (p - baseptr); return (0); } /* Seek to the next valid non-comment line (or EOF) */ static int bhnd_nvram_btxt_seek_next(struct bhnd_nvram_io *io, size_t *offset) { const uint8_t *baseptr, *p; const void *rbuf; size_t nbytes; int error; /* Fetch read buffer */ if ((error = bhnd_nvram_io_read_ptr(io, *offset, &rbuf, 0, &nbytes))) return (error); /* Skip leading whitespace and comments */ baseptr = rbuf; p = rbuf; while ((size_t)(p - baseptr) < nbytes) { char c = *p; /* Skip whitespace */ if (bhnd_nv_isspace(c)) { p++; continue; } /* Skip entire comment line */ if (c == '#') { size_t line_off = *offset + (p - baseptr); if ((error = bhnd_nvram_btxt_seek_eol(io, &line_off))) return (error); p = baseptr + (line_off - *offset); continue; } /* Non-whitespace, non-comment */ break; } *offset += (p - baseptr); return (0); } static int bhnd_nvram_btxt_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { bhnd_nvram_val *str; const char *inp; bhnd_nvram_type itype; size_t ilen; int error; /* Name (trimmed of any path prefix) must be valid */ if (!bhnd_nvram_validate_name(bhnd_nvram_trim_path_name(name))) return (EINVAL); /* Value must be bcm-formatted string */ error = bhnd_nvram_val_convert_new(&str, &bhnd_nvram_val_bcm_string_fmt, value, BHND_NVRAM_VAL_DYNAMIC); if (error) return (error); /* Value string must not contain our record delimiter character ('\n'), * or our comment character ('#') */ inp = bhnd_nvram_val_bytes(str, &ilen, &itype); BHND_NV_ASSERT(itype == BHND_NVRAM_TYPE_STRING, ("non-string value")); for (size_t i = 0; i < ilen; i++) { switch (inp[i]) { case '\n': case '#': BHND_NV_LOG("invalid character (%#hhx) in value\n", inp[i]); bhnd_nvram_val_release(str); return (EINVAL); } } /* Success. Transfer result ownership to the caller. */ *result = str; return (0); } static int bhnd_nvram_btxt_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { /* We permit deletion of any variable */ return (0); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom.c (revision 310297) @@ -1,2074 +1,1381 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #include #ifdef _KERNEL #include #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #include #include #endif /* _KERNEL */ -#include "bhnd_nvram_private.h" +#include "bhnd_nvram_map.h" +#include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_data_spromvar.h" /* * BHND SPROM NVRAM data class * * The SPROM data format is a fixed-layout, non-self-descriptive binary format, * used on Broadcom wireless and wired adapters, that provides a subset of the * variables defined by Broadcom SoC NVRAM formats. */ -BHND_NVRAM_DATA_CLASS_DEFN(sprom, "Broadcom SPROM", - sizeof(struct bhnd_nvram_sprom)) -static int sprom_sort_idx(const void *lhs, const void *rhs); +static const bhnd_sprom_layout *bhnd_nvram_sprom_get_layout(uint8_t sromrev); -static int sprom_opcode_state_init(struct sprom_opcode_state *state, - const struct bhnd_sprom_layout *layout); -static int sprom_opcode_state_reset(struct sprom_opcode_state *state); -static int sprom_opcode_state_seek(struct sprom_opcode_state *state, - struct sprom_opcode_idx *indexed); +static int bhnd_nvram_sprom_ident( + struct bhnd_nvram_io *io, + const bhnd_sprom_layout **ident, + struct bhnd_nvram_io **shadow); -static int sprom_opcode_next_var(struct sprom_opcode_state *state); -static int sprom_opcode_parse_var(struct sprom_opcode_state *state, - struct sprom_opcode_idx *indexed); - -static int sprom_opcode_next_binding(struct sprom_opcode_state *state); +static int bhnd_nvram_sprom_write_var( + bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry, + bhnd_nvram_val *value, + struct bhnd_nvram_io *io); -static int sprom_opcode_set_type(struct sprom_opcode_state *state, - bhnd_nvram_type type); +static int bhnd_nvram_sprom_write_offset( + const struct bhnd_nvram_vardefn *var, + struct bhnd_nvram_io *data, + bhnd_nvram_type type, size_t offset, + uint32_t mask, int8_t shift, + uint32_t value); -static int sprom_opcode_set_var(struct sprom_opcode_state *state, - size_t vid); -static int sprom_opcode_clear_var(struct sprom_opcode_state *state); -static int sprom_opcode_flush_bind(struct sprom_opcode_state *state); -static int sprom_opcode_read_opval32(struct sprom_opcode_state *state, - uint8_t type, uint32_t *opval); -static int sprom_opcode_apply_scale(struct sprom_opcode_state *state, - uint32_t *value); +static int bhnd_nvram_sprom_read_offset( + const struct bhnd_nvram_vardefn *var, + struct bhnd_nvram_io *data, + bhnd_nvram_type type, size_t offset, + uint32_t mask, int8_t shift, + uint32_t *value); -static int sprom_opcode_step(struct sprom_opcode_state *state, - uint8_t *opcode); +static bool bhnd_sprom_is_external_immutable( + const char *name); -#define SPROM_OP_BAD(_state, _fmt, ...) \ - BHND_NV_LOG("bad encoding at %td: " _fmt, \ - (_state)->input - (_state)->layout->bindings, ##__VA_ARGS__) +BHND_NVRAM_DATA_CLASS_DEFN(sprom, "Broadcom SPROM", + BHND_NVRAM_DATA_CAP_DEVPATHS, sizeof(struct bhnd_nvram_sprom)) -#define SPROM_COOKIE_TO_NVRAM(_cookie) \ - bhnd_nvram_get_vardefn(((struct sprom_opcode_idx *)_cookie)->vid) +#define SPROM_COOKIE_TO_VID(_cookie) \ + (((struct bhnd_sprom_opcode_idx_entry *)(_cookie))->vid) +#define SPROM_COOKIE_TO_NVRAM_VAR(_cookie) \ + bhnd_nvram_get_vardefn(SPROM_COOKIE_TO_VID(_cookie)) + /** * Read the magic value from @p io, and verify that it matches * the @p layout's expected magic value. * * If @p layout does not defined a magic value, @p magic is set to 0x0 * and success is returned. * * @param io An I/O context mapping the SPROM data to be identified. * @param layout The SPROM layout against which @p io should be verified. * @param[out] magic On success, the SPROM magic value. * * @retval 0 success * @retval non-zero If checking @p io otherwise fails, a regular unix * error code will be returned. */ static int bhnd_nvram_sprom_check_magic(struct bhnd_nvram_io *io, - const struct bhnd_sprom_layout *layout, uint16_t *magic) + const bhnd_sprom_layout *layout, uint16_t *magic) { int error; /* Skip if layout does not define a magic value */ if (layout->flags & SPROM_LAYOUT_MAGIC_NONE) return (0); /* Read the magic value */ error = bhnd_nvram_io_read(io, layout->magic_offset, magic, sizeof(*magic)); if (error) return (error); *magic = le16toh(*magic); /* If the signature does not match, skip to next layout */ if (*magic != layout->magic_value) return (ENXIO); return (0); } /** * Attempt to identify the format of the SPROM data mapped by @p io. * * The SPROM data format does not provide any identifying information at a * known offset, instead requiring that we iterate over the known SPROM image * sizes until we are able to compute a valid checksum (and, for later * revisions, validate a signature at a revision-specific offset). * * @param io An I/O context mapping the SPROM data to be identified. * @param[out] ident On success, the identified SPROM layout. * @param[out] shadow On success, a correctly sized iobuf instance mapping * a copy of the identified SPROM image. The caller is * responsible for deallocating this instance via * bhnd_nvram_io_free() * * @retval 0 success * @retval non-zero If identifying @p io otherwise fails, a regular unix * error code will be returned. */ static int bhnd_nvram_sprom_ident(struct bhnd_nvram_io *io, - const struct bhnd_sprom_layout **ident, struct bhnd_nvram_io **shadow) + const bhnd_sprom_layout **ident, struct bhnd_nvram_io **shadow) { struct bhnd_nvram_io *buf; uint8_t crc; size_t crc_errors; size_t sprom_sz_max; int error; /* Find the largest SPROM layout size */ sprom_sz_max = 0; for (size_t i = 0; i < bhnd_sprom_num_layouts; i++) { sprom_sz_max = bhnd_nv_ummax(sprom_sz_max, bhnd_sprom_layouts[i].size); } /* Allocate backing buffer and initialize CRC state */ buf = bhnd_nvram_iobuf_empty(0, sprom_sz_max); crc = BHND_NVRAM_CRC8_INITIAL; crc_errors = 0; /* We iterate the SPROM layouts smallest to largest, allowing us to * perform incremental checksum calculation */ for (size_t i = 0; i < bhnd_sprom_num_layouts; i++) { - const struct bhnd_sprom_layout *layout; - void *ptr; - size_t nbytes, nr; - uint16_t magic; - uint8_t srev; - bool crc_valid; - bool have_magic; + const bhnd_sprom_layout *layout; + void *ptr; + size_t nbytes, nr; + uint16_t magic; + uint8_t srev; + bool crc_valid; + bool have_magic; layout = &bhnd_sprom_layouts[i]; nbytes = bhnd_nvram_io_getsize(buf); if ((layout->flags & SPROM_LAYOUT_MAGIC_NONE)) { have_magic = false; } else { have_magic = true; } /* Layout instances must be ordered from smallest to largest by * the nvram_map compiler */ if (nbytes > layout->size) BHND_NV_PANIC("SPROM layout is defined out-of-order"); /* Calculate number of additional bytes to be read */ nr = layout->size - nbytes; /* Adjust the buffer size and fetch a write pointer */ if ((error = bhnd_nvram_io_setsize(buf, layout->size))) goto failed; error = bhnd_nvram_io_write_ptr(buf, nbytes, &ptr, nr, NULL); if (error) goto failed; /* Read image data and update CRC (errors are reported * after the signature check) */ if ((error = bhnd_nvram_io_read(io, nbytes, ptr, nr))) goto failed; crc = bhnd_nvram_crc8(ptr, nr, crc); crc_valid = (crc == BHND_NVRAM_CRC8_VALID); if (!crc_valid) crc_errors++; /* Fetch SPROM revision */ error = bhnd_nvram_io_read(buf, layout->srev_offset, &srev, sizeof(srev)); if (error) goto failed; /* Early sromrev 1 devices (specifically some BCM440x enet * cards) are reported to have been incorrectly programmed * with a revision of 0x10. */ if (layout->rev == 1 && srev == 0x10) srev = 0x1; /* Check revision against the layout definition */ if (srev != layout->rev) continue; /* Check the magic value, skipping to the next layout on * failure. */ error = bhnd_nvram_sprom_check_magic(buf, layout, &magic); if (error) { /* If the CRC is was valid, log the mismatch */ if (crc_valid || BHND_NV_VERBOSE) { BHND_NV_LOG("invalid sprom %hhu signature: " "0x%hx (expected 0x%hx)\n", srev, magic, layout->magic_value); error = ENXIO; goto failed; } continue; } /* Check for an earlier CRC error */ if (!crc_valid) { /* If the magic check succeeded, then we may just have * data corruption -- log the CRC error */ if (have_magic || BHND_NV_VERBOSE) { BHND_NV_LOG("sprom %hhu CRC error (crc=%#hhx, " "expected=%#x)\n", srev, crc, BHND_NVRAM_CRC8_VALID); } continue; } /* Identified */ *shadow = buf; *ident = layout; return (0); } /* No match -- set error and fallthrough */ error = ENXIO; if (crc_errors > 0 && BHND_NV_VERBOSE) { BHND_NV_LOG("sprom parsing failed with %zu CRC errors\n", crc_errors); } failed: bhnd_nvram_io_free(buf); return (error); } static int bhnd_nvram_sprom_probe(struct bhnd_nvram_io *io) { - const struct bhnd_sprom_layout *layout; - struct bhnd_nvram_io *shadow; - int error; + const bhnd_sprom_layout *layout; + struct bhnd_nvram_io *shadow; + int error; /* Try to parse the input */ if ((error = bhnd_nvram_sprom_ident(io, &layout, &shadow))) return (error); /* Clean up the shadow iobuf */ bhnd_nvram_io_free(shadow); return (BHND_NVRAM_DATA_PROBE_DEFAULT); } + +/** + * Return the SPROM layout definition for the given @p sromrev, or NULL if + * not found. + */ +static const bhnd_sprom_layout * +bhnd_nvram_sprom_get_layout(uint8_t sromrev) +{ + /* Find matching SPROM layout definition */ + for (size_t i = 0; i < bhnd_sprom_num_layouts; i++) { + if (bhnd_sprom_layouts[i].rev == sromrev) + return (&bhnd_sprom_layouts[i]); + } + + /* Not found */ + return (NULL); +} + +/** + * Serialize a SPROM variable. + * + * @param state The SPROM opcode state describing the layout of @p io. + * @param entry The variable's SPROM opcode index entry. + * @param value The value to encode to @p io as per @p entry. + * @param io I/O context to which @p value should be written, or NULL + * if no output should be produced. This may be used to validate + * values prior to write. + * + * @retval 0 success + * @retval EFTYPE If value coercion from @p value to the type required by + * @p entry is unsupported. + * @retval ERANGE If value coercion from @p value would overflow + * (or underflow) the type required by @p entry. + * @retval non-zero If serialization otherwise fails, a regular unix error + * code will be returned. + */ static int -bhnd_nvram_sprom_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) +bhnd_nvram_sprom_write_var(bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry, bhnd_nvram_val *value, + struct bhnd_nvram_io *io) { - struct bhnd_nvram_sprom *sp; - size_t num_vars; + const struct bhnd_nvram_vardefn *var; + uint32_t u32[BHND_SPROM_ARRAY_MAXLEN]; + bhnd_nvram_type itype, var_base_type; + size_t ipos, ilen, nelem; int error; - sp = (struct bhnd_nvram_sprom *)nv; + /* Fetch variable definition and the native element type */ + var = bhnd_nvram_get_vardefn(entry->vid); + BHND_NV_ASSERT(var != NULL, ("missing variable definition")); - /* Identify the SPROM input data */ - if ((error = bhnd_nvram_sprom_ident(io, &sp->layout, &sp->data))) - goto failed; + var_base_type = bhnd_nvram_base_type(var->type); - /* Initialize SPROM binding eval state */ - if ((error = sprom_opcode_state_init(&sp->state, sp->layout))) - goto failed; + /* Fetch the element count from the SPROM variable layout definition */ + if ((error = bhnd_sprom_opcode_parse_var(state, entry))) + return (error); - /* Allocate our opcode index */ - sp->num_idx = sp->layout->num_vars; - if ((sp->idx = bhnd_nv_calloc(sp->num_idx, sizeof(*sp->idx))) == NULL) - goto failed; + nelem = state->var.nelem; + BHND_NV_ASSERT(nelem <= var->nelem, ("SPROM nelem=%zu exceeds maximum " + "NVRAM nelem=%hhu", nelem, var->nelem)); - /* Parse out index entries from our stateful opcode stream */ - for (num_vars = 0; num_vars < sp->num_idx; num_vars++) { - size_t opcodes; + /* Promote the data to a common 32-bit representation */ + if (bhnd_nvram_is_signed_type(var_base_type)) + itype = BHND_NVRAM_TYPE_INT32_ARRAY; + else + itype = BHND_NVRAM_TYPE_UINT32_ARRAY; - /* Seek to next entry */ - if ((error = sprom_opcode_next_var(&sp->state))) { - SPROM_OP_BAD(&sp->state, - "error reading expected variable entry: %d\n", - error); - goto failed; + /* Calculate total size of the 32-bit promoted representation */ + if ((ilen = bhnd_nvram_value_size(NULL, 0, itype, nelem)) == 0) { + /* Variable-width types are unsupported */ + BHND_NV_LOG("invalid %s SPROM variable type %d\n", + var->name, var->type); + return (EFTYPE); + } + + /* The native representation must fit within our scratch array */ + if (ilen > sizeof(u32)) { + BHND_NV_LOG("error encoding '%s', SPROM_ARRAY_MAXLEN " + "incorrect\n", var->name); + return (EFTYPE); + } + + /* Initialize our common 32-bit value representation */ + if (bhnd_nvram_val_type(value) == BHND_NVRAM_TYPE_NULL) { + /* No value provided; can this variable be encoded as missing + * by setting all bits to one? */ + if (!(var->flags & BHND_NVRAM_VF_IGNALL1)) { + BHND_NV_LOG("missing required property: %s\n", + var->name); + return (EINVAL); } - /* We limit the SPROM index representations to the minimal - * type widths capable of covering all known layouts */ + /* Set all bits */ + memset(u32, 0xFF, ilen); + } else { + bhnd_nvram_val bcm_val; + const void *var_ptr; + bhnd_nvram_type var_type, raw_type; + size_t var_len, enc_nelem; - /* Save SPROM image offset */ - if (sp->state.offset > UINT16_MAX) { - SPROM_OP_BAD(&sp->state, - "cannot index large offset %u\n", sp->state.offset); + /* Try to coerce the value to the native variable format. */ + error = bhnd_nvram_val_convert_init(&bcm_val, var->fmt, value, + BHND_NVRAM_VAL_DYNAMIC|BHND_NVRAM_VAL_BORROW_DATA); + if (error) { + BHND_NV_LOG("error converting input type %s to %s " + "format\n", + bhnd_nvram_type_name(bhnd_nvram_val_type(value)), + bhnd_nvram_val_fmt_name(var->fmt)); + return (error); } - sp->idx[num_vars].offset = sp->state.offset; - /* Save current variable ID */ - if (sp->state.vid > UINT16_MAX) { - SPROM_OP_BAD(&sp->state, - "cannot index large vid %zu\n", sp->state.vid); + var_ptr = bhnd_nvram_val_bytes(&bcm_val, &var_len, &var_type); + + /* + * Promote to a common 32-bit representation. + * + * We must use the raw type to interpret the input data as its + * underlying integer representation -- otherwise, coercion + * would attempt to parse the input as its complex + * representation. + * + * For example, direct CHAR -> UINT32 coercion would attempt to + * parse the character as a decimal integer, rather than + * promoting the raw UTF8 byte value to a 32-bit value. + */ + raw_type = bhnd_nvram_raw_type(var_type); + error = bhnd_nvram_value_coerce(var_ptr, var_len, raw_type, + u32, &ilen, itype); + + /* Clean up temporary value representation */ + bhnd_nvram_val_release(&bcm_val); + + /* Report coercion failure */ + if (error) { + BHND_NV_LOG("error promoting %s to %s: %d\n", + bhnd_nvram_type_name(var_type), + bhnd_nvram_type_name(itype), error); + return (error); } - sp->idx[num_vars].vid = sp->state.vid; - /* Save opcode position */ - opcodes = (sp->state.input - sp->layout->bindings); - if (opcodes > UINT16_MAX) { - SPROM_OP_BAD(&sp->state, - "cannot index large opcode offset %zu\n", opcodes); + /* Encoded element count must match SPROM's definition */ + error = bhnd_nvram_value_nelem(u32, ilen, itype, &enc_nelem); + if (error) + return (error); + + if (enc_nelem != nelem) { + const char *type_name; + + type_name = bhnd_nvram_type_name(var_base_type); + BHND_NV_LOG("invalid %s property value '%s[%zu]': " + "required %s[%zu]", var->name, type_name, + enc_nelem, type_name, nelem); + return (EFTYPE); } - sp->idx[num_vars].opcodes = opcodes; } - /* Should have reached end of binding table; next read must return - * ENOENT */ - if ((error = sprom_opcode_next_var(&sp->state)) != ENOENT) { - BHND_NV_LOG("expected EOF parsing binding table: %d\n", error); - goto failed; + /* + * Seek to the start of the variable's SPROM layout definition and + * iterate over all bindings. + */ + if ((error = bhnd_sprom_opcode_seek(state, entry))) { + BHND_NV_LOG("variable seek failed: %d\n", error); + return (error); } + + ipos = 0; + while ((error = bhnd_sprom_opcode_next_binding(state)) == 0) { + bhnd_sprom_opcode_bind *binding; + bhnd_sprom_opcode_var *binding_var; + size_t offset; + uint32_t skip_out_bytes; - /* Sort index by variable ID, ascending */ - qsort(sp->idx, sp->num_idx, sizeof(sp->idx[0]), sprom_sort_idx); + BHND_NV_ASSERT( + state->var_state >= SPROM_OPCODE_VAR_STATE_OPEN, + ("invalid var state")); + BHND_NV_ASSERT(state->var.have_bind, ("invalid bind state")); + binding_var = &state->var; + binding = &state->var.bind; + + /* Calculate output skip bytes for this binding. + * + * Skip directions are defined in terms of decoding, and + * reversed when encoding. */ + skip_out_bytes = binding->skip_in; + error = bhnd_sprom_opcode_apply_scale(state, &skip_out_bytes); + if (error) + return (error); + + /* Bind */ + offset = state->offset; + for (size_t i = 0; i < binding->count; i++) { + if (ipos >= nelem) { + BHND_NV_LOG("input skip %u positioned %zu " + "beyond nelem %zu\n", binding->skip_out, + ipos, nelem); + return (EINVAL); + } + + /* Write next offset */ + if (io != NULL) { + error = bhnd_nvram_sprom_write_offset(var, io, + binding_var->base_type, + offset, + binding_var->mask, + binding_var->shift, + u32[ipos]); + if (error) + return (error); + } + + /* Adjust output position; this was already verified to + * not overflow/underflow during SPROM opcode + * evaluation */ + if (binding->skip_in_negative) { + offset -= skip_out_bytes; + } else { + offset += skip_out_bytes; + } + + /* Skip advancing input if additional bindings are + * required to fully encode intv */ + if (binding->skip_out == 0) + continue; + + /* Advance input position */ + if (SIZE_MAX - binding->skip_out < ipos) { + BHND_NV_LOG("output skip %u would overflow " + "%zu\n", binding->skip_out, ipos); + return (EINVAL); + } + + ipos += binding->skip_out; + } + } + + /* Did we iterate all bindings until hitting end of the variable + * definition? */ + BHND_NV_ASSERT(error != 0, ("loop terminated early")); + if (error != ENOENT) + return (error); + return (0); +} + +static int +bhnd_nvram_sprom_serialize(bhnd_nvram_data_class *cls, bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, size_t *olen) +{ + bhnd_sprom_opcode_state state; + struct bhnd_nvram_io *io; + bhnd_nvram_prop *prop; + bhnd_sprom_opcode_idx_entry *entry; + const bhnd_sprom_layout *layout; + size_t limit; + uint8_t crc; + uint8_t sromrev; + int error; + + limit = *olen; + layout = NULL; + io = NULL; + + /* Fetch sromrev property */ + if (!bhnd_nvram_plist_contains(props, BHND_NVAR_SROMREV)) { + BHND_NV_LOG("missing required property: %s\n", + BHND_NVAR_SROMREV); + return (EINVAL); + } + + error = bhnd_nvram_plist_get_uint8(props, BHND_NVAR_SROMREV, &sromrev); + if (error) { + BHND_NV_LOG("error reading sromrev property: %d\n", error); + return (EFTYPE); + } + + /* Find SPROM layout definition */ + if ((layout = bhnd_nvram_sprom_get_layout(sromrev)) == NULL) { + BHND_NV_LOG("unsupported sromrev: %hhu\n", sromrev); + return (EFTYPE); + } + + /* Provide required size to caller */ + *olen = layout->size; + if (outp == NULL) + return (0); + else if (limit < *olen) + return (ENOMEM); + + /* Initialize SPROM layout interpreter */ + if ((error = bhnd_sprom_opcode_init(&state, layout))) { + BHND_NV_LOG("error initializing opcode state: %d\n", error); + return (ENXIO); + } + + /* Check for unsupported properties */ + prop = NULL; + while ((prop = bhnd_nvram_plist_next(props, prop)) != NULL) { + const char *name; + + /* Fetch the corresponding SPROM layout index entry */ + name = bhnd_nvram_prop_name(prop); + entry = bhnd_sprom_opcode_index_find(&state, name); + if (entry == NULL) { + BHND_NV_LOG("property '%s' unsupported by sromrev " + "%hhu\n", name, layout->rev); + error = EINVAL; + goto finished; + } + } + + /* Zero-initialize output */ + memset(outp, 0, *olen); + + /* Allocate wrapping I/O context for output buffer */ + io = bhnd_nvram_ioptr_new(outp, *olen, *olen, BHND_NVRAM_IOPTR_RDWR); + if (io == NULL) { + error = ENOMEM; + goto finished; + } + + /* + * Serialize all SPROM variable data. + */ + entry = NULL; + while ((entry = bhnd_sprom_opcode_index_next(&state, entry)) != NULL) { + const struct bhnd_nvram_vardefn *var; + bhnd_nvram_val *val; + + var = bhnd_nvram_get_vardefn(entry->vid); + BHND_NV_ASSERT(var != NULL, ("missing variable definition")); + + /* Fetch prop; will be NULL if unavailable */ + prop = bhnd_nvram_plist_get_prop(props, var->name); + if (prop != NULL) { + val = bhnd_nvram_prop_val(prop); + } else { + val = BHND_NVRAM_VAL_NULL; + } + + /* Attempt to serialize the property value to the appropriate + * offset within the output buffer */ + error = bhnd_nvram_sprom_write_var(&state, entry, val, io); + if (error) { + BHND_NV_LOG("error serializing %s to required type " + "%s: %d\n", var->name, + bhnd_nvram_type_name(var->type), error); + + /* ENOMEM is reserved for signaling that the output + * buffer capacity is insufficient */ + if (error == ENOMEM) + error = EINVAL; + + goto finished; + } + } + + /* + * Write magic value, if any. + */ + if (!(layout->flags & SPROM_LAYOUT_MAGIC_NONE)) { + uint16_t magic; + + magic = htole16(layout->magic_value); + error = bhnd_nvram_io_write(io, layout->magic_offset, &magic, + sizeof(magic)); + if (error) { + BHND_NV_LOG("error writing magic value: %d\n", error); + goto finished; + } + } + + /* Calculate the CRC over all SPROM data, not including the CRC byte. */ + crc = ~bhnd_nvram_crc8(outp, layout->crc_offset, + BHND_NVRAM_CRC8_INITIAL); + + /* Write the checksum. */ + error = bhnd_nvram_io_write(io, layout->crc_offset, &crc, sizeof(crc)); + if (error) { + BHND_NV_LOG("error writing CRC value: %d\n", error); + goto finished; + } -failed: - if (sp->data != NULL) - bhnd_nvram_io_free(sp->data); + /* + * Success! + */ + error = 0; - if (sp->idx != NULL) - bhnd_nv_free(sp->idx); +finished: + bhnd_sprom_opcode_fini(&state); + + if (io != NULL) + bhnd_nvram_io_free(io); return (error); } -/* sort function for sprom_opcode_idx values */ static int -sprom_sort_idx(const void *lhs, const void *rhs) +bhnd_nvram_sprom_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) { - const struct sprom_opcode_idx *l, *r; + struct bhnd_nvram_sprom *sp; + int error; - l = lhs; - r = rhs; + sp = (struct bhnd_nvram_sprom *)nv; - if (l->vid < r->vid) - return (-1); - if (l->vid > r->vid) - return (1); + /* Identify the SPROM input data */ + if ((error = bhnd_nvram_sprom_ident(io, &sp->layout, &sp->data))) + goto failed; + + /* Initialize SPROM binding eval state */ + if ((error = bhnd_sprom_opcode_init(&sp->state, sp->layout))) + goto failed; + return (0); + +failed: + if (sp->data != NULL) + bhnd_nvram_io_free(sp->data); + + return (error); } static void bhnd_nvram_sprom_free(struct bhnd_nvram_data *nv) { struct bhnd_nvram_sprom *sp = (struct bhnd_nvram_sprom *)nv; - + + bhnd_sprom_opcode_fini(&sp->state); bhnd_nvram_io_free(sp->data); - bhnd_nv_free(sp->idx); } -static bhnd_nvram_plist * -bhnd_nvram_sprom_options(struct bhnd_nvram_data *nv) -{ - return (NULL); -} - size_t bhnd_nvram_sprom_count(struct bhnd_nvram_data *nv) { struct bhnd_nvram_sprom *sprom = (struct bhnd_nvram_sprom *)nv; return (sprom->layout->num_vars); } -static int -bhnd_nvram_sprom_size(struct bhnd_nvram_data *nv, size_t *size) +static bhnd_nvram_plist * +bhnd_nvram_sprom_options(struct bhnd_nvram_data *nv) { - struct bhnd_nvram_sprom *sprom = (struct bhnd_nvram_sprom *)nv; - - /* The serialized form will be identical in length - * to our backing buffer representation */ - *size = bhnd_nvram_io_getsize(sprom->data); - return (0); + return (NULL); } -static int -bhnd_nvram_sprom_serialize(struct bhnd_nvram_data *nv, void *buf, size_t *len) -{ - struct bhnd_nvram_sprom *sprom; - size_t limit, req_len; - int error; - - sprom = (struct bhnd_nvram_sprom *)nv; - limit = *len; - - /* Provide the required size */ - if ((error = bhnd_nvram_sprom_size(nv, &req_len))) - return (error); - - *len = req_len; - - if (buf == NULL) { - return (0); - } else if (*len > limit) { - return (ENOMEM); - } - - /* Write to the output buffer */ - return (bhnd_nvram_io_read(sprom->data, 0x0, buf, *len)); -} - static uint32_t bhnd_nvram_sprom_caps(struct bhnd_nvram_data *nv) { return (BHND_NVRAM_DATA_CAP_INDEXED); } static const char * bhnd_nvram_sprom_next(struct bhnd_nvram_data *nv, void **cookiep) { struct bhnd_nvram_sprom *sp; - struct sprom_opcode_idx *idx_entry; - size_t idx_next; + bhnd_sprom_opcode_idx_entry *entry; const struct bhnd_nvram_vardefn *var; sp = (struct bhnd_nvram_sprom *)nv; - /* Seek to appropriate starting point */ - if (*cookiep == NULL) { - /* Start search at first index entry */ - idx_next = 0; - } else { - /* Determine current index position */ - idx_entry = *cookiep; - idx_next = (size_t)(idx_entry - sp->idx); - BHND_NV_ASSERT(idx_next < sp->num_idx, - ("invalid index %zu; corrupt cookie?", idx_next)); + /* Find next index entry that is not disabled by virtue of IGNALL1 */ + entry = *cookiep; + while ((entry = bhnd_sprom_opcode_index_next(&sp->state, entry))) { + /* Update cookiep and fetch variable definition */ + *cookiep = entry; + var = SPROM_COOKIE_TO_NVRAM_VAR(*cookiep); - /* Advance to next entry */ - idx_next++; - - /* Check for EOF */ - if (idx_next == sp->num_idx) - return (NULL); - } - - /* Skip entries that are disabled by virtue of IGNALL1 */ - for (; idx_next < sp->num_idx; idx_next++) { - /* Fetch index entry and update cookiep */ - idx_entry = &sp->idx[idx_next]; - *cookiep = idx_entry; - - /* Fetch variable definition */ - var = bhnd_nvram_get_vardefn(idx_entry->vid); - /* We might need to parse the variable's value to determine * whether it should be treated as unset */ if (var->flags & BHND_NVRAM_VF_IGNALL1) { int error; size_t len; error = bhnd_nvram_sprom_getvar(nv, *cookiep, NULL, &len, var->type); if (error) { BHND_NV_ASSERT(error == ENOENT, ("unexpected " "error parsing variable: %d", error)); - continue; } } /* Found! */ return (var->name); } /* Reached end of index entries */ return (NULL); } -/* bsearch function used by bhnd_nvram_sprom_find() */ -static int -bhnd_nvram_sprom_find_vid_compare(const void *key, const void *rhs) -{ - const struct sprom_opcode_idx *r; - size_t l; - - l = *(const size_t *)key; - r = rhs; - - if (l < r->vid) - return (-1); - if (l > r->vid) - return (1); - return (0); -} - static void * bhnd_nvram_sprom_find(struct bhnd_nvram_data *nv, const char *name) { struct bhnd_nvram_sprom *sp; - const struct bhnd_nvram_vardefn *var; - size_t vid; + bhnd_sprom_opcode_idx_entry *entry; sp = (struct bhnd_nvram_sprom *)nv; - /* Determine the variable ID for the given name */ - if ((var = bhnd_nvram_find_vardefn(name)) == NULL) - return (NULL); + entry = bhnd_sprom_opcode_index_find(&sp->state, name); + return (entry); +} - vid = bhnd_nvram_get_vardefn_id(var); +/** + * Write @p value of @p type to the SPROM @p data at @p offset, applying + * @p mask and @p shift, and OR with the existing data. + * + * @param var The NVRAM variable definition. + * @param data The SPROM data to be modified. + * @param type The type to write at @p offset. + * @param offset The data offset to be written. + * @param mask The mask to be applied to @p value after shifting. + * @param shift The shift to be applied to @p value; if positive, a left + * shift will be applied, if negative, a right shift (this is the reverse of the + * decoding behavior) + * @param value The value to be written. The parsed value will be OR'd with the + * current contents of @p data at @p offset. + */ +static int +bhnd_nvram_sprom_write_offset(const struct bhnd_nvram_vardefn *var, + struct bhnd_nvram_io *data, bhnd_nvram_type type, size_t offset, + uint32_t mask, int8_t shift, uint32_t value) +{ + union bhnd_nvram_sprom_storage scratch; + int error; - /* Search our index for the variable ID */ - return (bsearch(&vid, sp->idx, sp->num_idx, sizeof(sp->idx[0]), - bhnd_nvram_sprom_find_vid_compare)); +#define NV_WRITE_INT(_widen, _repr, _swap) do { \ + /* Narrow the 32-bit representation */ \ + scratch._repr[1] = (_widen)value; \ + \ + /* Shift and mask the new value */ \ + if (shift > 0) \ + scratch._repr[1] <<= shift; \ + else if (shift < 0) \ + scratch._repr[1] >>= -shift; \ + scratch._repr[1] &= mask; \ + \ + /* Swap to output byte order */ \ + scratch._repr[1] = _swap(scratch._repr[1]); \ + \ + /* Fetch the current value */ \ + error = bhnd_nvram_io_read(data, offset, \ + &scratch._repr[0], sizeof(scratch._repr[0])); \ + if (error) { \ + BHND_NV_LOG("error reading %s SPROM offset " \ + "%#zx: %d\n", var->name, offset, error); \ + return (EFTYPE); \ + } \ + \ + /* Mask and set our new value's bits in the current \ + * value */ \ + if (shift >= 0) \ + scratch._repr[0] &= ~_swap(mask << shift); \ + else if (shift < 0) \ + scratch._repr[0] &= ~_swap(mask >> (-shift)); \ + scratch._repr[0] |= scratch._repr[1]; \ + \ + /* Perform write */ \ + error = bhnd_nvram_io_write(data, offset, \ + &scratch._repr[0], sizeof(scratch._repr[0])); \ + if (error) { \ + BHND_NV_LOG("error writing %s SPROM offset " \ + "%#zx: %d\n", var->name, offset, error); \ + return (EFTYPE); \ + } \ +} while(0) + + /* Apply mask/shift and widen to a common 32bit representation */ + switch (type) { + case BHND_NVRAM_TYPE_UINT8: + NV_WRITE_INT(uint32_t, u8, ); + break; + case BHND_NVRAM_TYPE_UINT16: + NV_WRITE_INT(uint32_t, u16, htole16); + break; + case BHND_NVRAM_TYPE_UINT32: + NV_WRITE_INT(uint32_t, u32, htole32); + break; + case BHND_NVRAM_TYPE_INT8: + NV_WRITE_INT(int32_t, i8, ); + break; + case BHND_NVRAM_TYPE_INT16: + NV_WRITE_INT(int32_t, i16, htole16); + break; + case BHND_NVRAM_TYPE_INT32: + NV_WRITE_INT(int32_t, i32, htole32); + break; + case BHND_NVRAM_TYPE_CHAR: + NV_WRITE_INT(uint32_t, u8, ); + break; + default: + BHND_NV_LOG("unhandled %s offset type: %d\n", var->name, type); + return (EFTYPE); + } +#undef NV_WRITE_INT + + return (0); } /** - * Read the value of @p type from the SPROM data at @p offset, apply @p mask + * Read the value of @p type from the SPROM @p data at @p offset, apply @p mask * and @p shift, and OR with the existing @p value. * - * @param sp The SPROM data instance. - * @param var The NVRAM variable definition + * @param var The NVRAM variable definition. + * @param data The SPROM data to be decoded. * @param type The type to read at @p offset * @param offset The data offset to be read. * @param mask The mask to be applied to the value read at @p offset. * @param shift The shift to be applied after masking; if positive, a right * shift will be applied, if negative, a left shift. * @param value The read destination; the parsed value will be OR'd with the * current contents of @p value. */ static int -bhnd_nvram_sprom_read_offset(struct bhnd_nvram_sprom *sp, - const struct bhnd_nvram_vardefn *var, bhnd_nvram_type type, - size_t offset, uint32_t mask, int8_t shift, - union bhnd_nvram_sprom_intv *value) +bhnd_nvram_sprom_read_offset(const struct bhnd_nvram_vardefn *var, + struct bhnd_nvram_io *data, bhnd_nvram_type type, size_t offset, + uint32_t mask, int8_t shift, uint32_t *value) { - size_t sp_width; - int error; - union { - uint8_t u8; - uint16_t u16; - uint32_t u32; - int8_t s8; - int16_t s16; - int32_t s32; - } sp_value; + union bhnd_nvram_sprom_storage scratch; + int error; - /* Determine type width */ - sp_width = bhnd_nvram_type_width(type); - if (sp_width == 0) { - /* Variable-width types are unsupported */ - BHND_NV_LOG("invalid %s SPROM offset type %d\n", var->name, - type); - return (EFTYPE); - } - - /* Perform read */ - error = bhnd_nvram_io_read(sp->data, offset, &sp_value, - sp_width); - if (error) { - BHND_NV_LOG("error reading %s SPROM offset %#zx: %d\n", - var->name, offset, error); - return (EFTYPE); - } - -#define NV_PARSE_INT(_type, _src, _dest, _swap) do { \ - /* Swap to host byte order */ \ - sp_value. _src = (_type) _swap(sp_value. _src); \ - \ - /* Mask and shift the value */ \ - sp_value. _src &= mask; \ +#define NV_PARSE_INT(_widen, _repr, _swap) do { \ + /* Perform read */ \ + error = bhnd_nvram_io_read(data, offset, \ + &scratch._repr[0], sizeof(scratch._repr[0])); \ + if (error) { \ + BHND_NV_LOG("error reading %s SPROM offset " \ + "%#zx: %d\n", var->name, offset, error); \ + return (EFTYPE); \ + } \ + \ + /* Swap to host byte order */ \ + scratch._repr[0] = _swap(scratch._repr[0]); \ + \ + /* Mask and shift the value */ \ + scratch._repr[0] &= mask; \ if (shift > 0) { \ - sp_value. _src >>= shift; \ - } else if (shift < 0) { \ - sp_value. _src <<= -shift; \ - } \ - \ - /* Emit output, widening to 32-bit representation */ \ - value-> _dest |= sp_value. _src; \ + scratch. _repr[0] >>= shift; \ + } else if (shift < 0) { \ + scratch. _repr[0] <<= -shift; \ + } \ + \ + /* Widen to 32-bit representation and OR with current \ + * value */ \ + (*value) |= (_widen)scratch._repr[0]; \ } while(0) /* Apply mask/shift and widen to a common 32bit representation */ switch (type) { case BHND_NVRAM_TYPE_UINT8: - NV_PARSE_INT(uint8_t, u8, u32, ); + NV_PARSE_INT(uint32_t, u8, ); break; case BHND_NVRAM_TYPE_UINT16: - NV_PARSE_INT(uint16_t, u16, u32, le16toh); + NV_PARSE_INT(uint32_t, u16, le16toh); break; case BHND_NVRAM_TYPE_UINT32: - NV_PARSE_INT(uint32_t, u32, u32, le32toh); + NV_PARSE_INT(uint32_t, u32, le32toh); break; case BHND_NVRAM_TYPE_INT8: - NV_PARSE_INT(int8_t, s8, s32, ); + NV_PARSE_INT(int32_t, i8, ); break; case BHND_NVRAM_TYPE_INT16: - NV_PARSE_INT(int16_t, s16, s32, le16toh); + NV_PARSE_INT(int32_t, i16, le16toh); break; case BHND_NVRAM_TYPE_INT32: - NV_PARSE_INT(int32_t, s32, s32, le32toh); + NV_PARSE_INT(int32_t, i32, le32toh); break; case BHND_NVRAM_TYPE_CHAR: - NV_PARSE_INT(uint8_t, u8, u32, ); + NV_PARSE_INT(uint32_t, u8, ); break; - - case BHND_NVRAM_TYPE_UINT64: - case BHND_NVRAM_TYPE_INT64: - case BHND_NVRAM_TYPE_STRING: - /* fallthrough (unused by SPROM) */ default: BHND_NV_LOG("unhandled %s offset type: %d\n", var->name, type); return (EFTYPE); } +#undef NV_PARSE_INT return (0); } /** * Common variable decoding; fetches and decodes variable to @p val, * using @p storage for actual data storage. * * The returned @p val instance will hold a borrowed reference to @p storage, * and must be copied via bhnd_nvram_val_copy() if it will be referenced beyond * the lifetime of @p storage. * * The caller is responsible for releasing any allocated value state * via bhnd_nvram_val_release(). */ static int bhnd_nvram_sprom_getvar_common(struct bhnd_nvram_data *nv, void *cookiep, union bhnd_nvram_sprom_storage *storage, bhnd_nvram_val *val) { struct bhnd_nvram_sprom *sp; - struct sprom_opcode_idx *entry; + bhnd_sprom_opcode_idx_entry *entry; const struct bhnd_nvram_vardefn *var; union bhnd_nvram_sprom_storage *inp; bhnd_nvram_type var_btype; - union bhnd_nvram_sprom_intv intv; + uint32_t intv; size_t ilen, ipos, iwidth; size_t nelem; bool all_bits_set; int error; sp = (struct bhnd_nvram_sprom *)nv; entry = cookiep; BHND_NV_ASSERT(cookiep != NULL, ("NULL variable cookiep")); /* Fetch canonical variable definition */ - var = SPROM_COOKIE_TO_NVRAM(cookiep); + var = SPROM_COOKIE_TO_NVRAM_VAR(cookiep); BHND_NV_ASSERT(var != NULL, ("invalid cookiep %p", cookiep)); /* * Fetch the array length from the SPROM variable definition. * * This generally be identical to the array length provided by the * canonical NVRAM variable definition, but some SPROM layouts may * define a smaller element count. */ - if ((error = sprom_opcode_parse_var(&sp->state, entry))) { + if ((error = bhnd_sprom_opcode_parse_var(&sp->state, entry))) { BHND_NV_LOG("variable evaluation failed: %d\n", error); return (error); } nelem = sp->state.var.nelem; if (nelem > var->nelem) { BHND_NV_LOG("SPROM array element count %zu cannot be " "represented by '%s' element count of %hhu\n", nelem, var->name, var->nelem); return (EFTYPE); } /* Fetch the var's base element type */ var_btype = bhnd_nvram_base_type(var->type); /* Calculate total byte length of the native encoding */ if ((iwidth = bhnd_nvram_value_size(NULL, 0, var_btype, 1)) == 0) { /* SPROM does not use (and we do not support) decoding of * variable-width data types */ BHND_NV_LOG("invalid SPROM data type: %d", var->type); return (EFTYPE); } ilen = nelem * iwidth; /* Decode into our caller's local storage */ inp = storage; if (ilen > sizeof(*storage)) { BHND_NV_LOG("error decoding '%s', SPROM_ARRAY_MAXLEN " "incorrect\n", var->name); return (EFTYPE); } /* Zero-initialize our decode buffer; any output elements skipped * during decode should default to zero. */ memset(inp, 0, ilen); /* * Decode the SPROM data, iteratively decoding up to nelem values. */ - if ((error = sprom_opcode_state_seek(&sp->state, entry))) { + if ((error = bhnd_sprom_opcode_seek(&sp->state, entry))) { BHND_NV_LOG("variable seek failed: %d\n", error); return (error); } ipos = 0; - intv.u32 = 0x0; + intv = 0x0; if (var->flags & BHND_NVRAM_VF_IGNALL1) all_bits_set = true; else all_bits_set = false; - while ((error = sprom_opcode_next_binding(&sp->state)) == 0) { - struct sprom_opcode_bind *binding; - struct sprom_opcode_var *binding_var; - bhnd_nvram_type intv_type; - size_t offset; - size_t nbyte; - uint32_t skip_in_bytes; - void *ptr; + while ((error = bhnd_sprom_opcode_next_binding(&sp->state)) == 0) { + bhnd_sprom_opcode_bind *binding; + bhnd_sprom_opcode_var *binding_var; + bhnd_nvram_type intv_type; + size_t offset; + size_t nbyte; + uint32_t skip_in_bytes; + void *ptr; BHND_NV_ASSERT( sp->state.var_state >= SPROM_OPCODE_VAR_STATE_OPEN, ("invalid var state")); BHND_NV_ASSERT(sp->state.var.have_bind, ("invalid bind state")); binding_var = &sp->state.var; binding = &sp->state.var.bind; if (ipos >= nelem) { BHND_NV_LOG("output skip %u positioned " "%zu beyond nelem %zu\n", binding->skip_out, ipos, nelem); return (EINVAL); } /* Calculate input skip bytes for this binding */ skip_in_bytes = binding->skip_in; - error = sprom_opcode_apply_scale(&sp->state, &skip_in_bytes); + error = bhnd_sprom_opcode_apply_scale(&sp->state, + &skip_in_bytes); if (error) return (error); /* Bind */ offset = sp->state.offset; for (size_t i = 0; i < binding->count; i++) { /* Read the offset value, OR'ing with the current * value of intv */ - error = bhnd_nvram_sprom_read_offset(sp, var, + error = bhnd_nvram_sprom_read_offset(var, sp->data, binding_var->base_type, offset, binding_var->mask, binding_var->shift, &intv); if (error) return (error); /* If IGNALL1, record whether value does not have * all bits set. */ if (var->flags & BHND_NVRAM_VF_IGNALL1 && all_bits_set) { uint32_t all1; all1 = binding_var->mask; if (binding_var->shift > 0) all1 >>= binding_var->shift; else if (binding_var->shift < 0) all1 <<= -binding_var->shift; - if ((intv.u32 & all1) != all1) + if ((intv & all1) != all1) all_bits_set = false; } /* Adjust input position; this was already verified to * not overflow/underflow during SPROM opcode * evaluation */ if (binding->skip_in_negative) { offset -= skip_in_bytes; } else { offset += skip_in_bytes; } /* Skip writing to inp if additional bindings are * required to fully populate intv */ if (binding->skip_out == 0) continue; /* We use bhnd_nvram_value_coerce() to perform * overflow-checked coercion from the widened * uint32/int32 intv value to the requested output * type */ if (bhnd_nvram_is_signed_type(var_btype)) intv_type = BHND_NVRAM_TYPE_INT32; else intv_type = BHND_NVRAM_TYPE_UINT32; /* Calculate address of the current element output * position */ ptr = (uint8_t *)inp + (iwidth * ipos); /* Perform coercion of the array element */ nbyte = iwidth; - error = bhnd_nvram_value_coerce(&intv.u32, - sizeof(intv.u32), intv_type, ptr, &nbyte, - var_btype); + error = bhnd_nvram_value_coerce(&intv, sizeof(intv), + intv_type, ptr, &nbyte, var_btype); if (error) return (error); /* Clear temporary state */ - intv.u32 = 0x0; + intv = 0x0; /* Advance output position */ if (SIZE_MAX - binding->skip_out < ipos) { BHND_NV_LOG("output skip %u would overflow " "%zu\n", binding->skip_out, ipos); return (EINVAL); } ipos += binding->skip_out; } } /* Did we iterate all bindings until hitting end of the variable * definition? */ BHND_NV_ASSERT(error != 0, ("loop terminated early")); if (error != ENOENT) { return (error); } /* If marked IGNALL1 and all bits are set, treat variable as * unavailable */ if ((var->flags & BHND_NVRAM_VF_IGNALL1) && all_bits_set) return (ENOENT); /* Provide value wrapper */ return (bhnd_nvram_val_init(val, var->fmt, inp, ilen, var->type, BHND_NVRAM_VAL_BORROW_DATA)); return (error); } static int bhnd_nvram_sprom_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { - struct sprom_opcode_idx_entry *e1, *e2; + struct bhnd_sprom_opcode_idx_entry *e1, *e2; e1 = cookiep1; e2 = cookiep2; /* Use the index entry order; this matches the order of variables * returned via bhnd_nvram_sprom_next() */ if (e1 < e2) return (-1); else if (e1 > e2) return (1); return (0); } static int bhnd_nvram_sprom_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type otype) { bhnd_nvram_val val; union bhnd_nvram_sprom_storage storage; int error; /* Decode variable to a new value instance */ error = bhnd_nvram_sprom_getvar_common(nv, cookiep, &storage, &val); if (error) return (error); /* Perform value coercion */ error = bhnd_nvram_val_encode(&val, buf, len, otype); /* Clean up */ bhnd_nvram_val_release(&val); return (error); } static int bhnd_nvram_sprom_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { bhnd_nvram_val val; union bhnd_nvram_sprom_storage storage; int error; /* Decode variable to a new value instance */ error = bhnd_nvram_sprom_getvar_common(nv, cookiep, &storage, &val); if (error) return (error); /* Attempt to copy to heap */ *value = bhnd_nvram_val_copy(&val); bhnd_nvram_val_release(&val); if (*value == NULL) return (ENOMEM); return (0); } static const void * bhnd_nvram_sprom_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { /* Unsupported */ return (NULL); } static const char * bhnd_nvram_sprom_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { const struct bhnd_nvram_vardefn *var; BHND_NV_ASSERT(cookiep != NULL, ("NULL variable cookiep")); - var = SPROM_COOKIE_TO_NVRAM(cookiep); + var = SPROM_COOKIE_TO_NVRAM_VAR(cookiep); BHND_NV_ASSERT(var != NULL, ("invalid cookiep %p", cookiep)); return (var->name); } static int bhnd_nvram_sprom_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { - // XXX TODO - return (ENXIO); -} - -static int -bhnd_nvram_sprom_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) -{ - // XXX TODO - return (ENXIO); -} - -/** - * Initialize SPROM opcode evaluation state. - * - * @param state The opcode state to be initialized. - * @param layout The SPROM layout to be parsed by this instance. - * - * - * @retval 0 success - * @retval non-zero If initialization fails, a regular unix error code will be - * returned. - */ -static int -sprom_opcode_state_init(struct sprom_opcode_state *state, - const struct bhnd_sprom_layout *layout) -{ - memset(state, 0, sizeof(*state)); - - state->layout = layout; - state->input = layout->bindings; - state->var_state = SPROM_OPCODE_VAR_STATE_NONE; - - bit_set(state->revs, layout->rev); - - return (0); -} - -/** - * Reset SPROM opcode evaluation state; future evaluation will be performed - * starting at the first opcode. - * - * @param state The opcode state to be reset. - * - * @retval 0 success - * @retval non-zero If reset fails, a regular unix error code will be returned. - */ -static int -sprom_opcode_state_reset(struct sprom_opcode_state *state) -{ - return (sprom_opcode_state_init(state, state->layout)); -} - -/** - * Reset SPROM opcode evaluation state and seek to the @p indexed position. - * - * @param state The opcode state to be reset. - * @param indexed The indexed location to which we'll seek the opcode state. - */ -static int -sprom_opcode_state_seek(struct sprom_opcode_state *state, - struct sprom_opcode_idx *indexed) -{ - int error; - - BHND_NV_ASSERT(indexed->opcodes < state->layout->bindings_size, - ("index entry references invalid opcode position")); - - /* Reset state */ - if ((error = sprom_opcode_state_reset(state))) - return (error); - - /* Seek to the indexed sprom opcode offset */ - state->input = state->layout->bindings + indexed->opcodes; - - /* Restore the indexed sprom data offset and VID */ - state->offset = indexed->offset; - - /* Restore the indexed sprom variable ID */ - if ((error = sprom_opcode_set_var(state, indexed->vid))) - return (error); - - return (0); -} - -/** - * Set the current revision range for @p state. This also resets - * variable state. - * - * @param state The opcode state to update - * @param start The first revision in the range. - * @param end The last revision in the range. - * - * @retval 0 success - * @retval non-zero If updating @p state fails, a regular unix error code will - * be returned. - */ -static inline int -sprom_opcode_set_revs(struct sprom_opcode_state *state, uint8_t start, - uint8_t end) -{ - int error; - - /* Validate the revision range */ - if (start > SPROM_OP_REV_MAX || - end > SPROM_OP_REV_MAX || - end < start) - { - SPROM_OP_BAD(state, "invalid revision range: %hhu-%hhu\n", - start, end); - return (EINVAL); - } - - /* Clear variable state */ - if ((error = sprom_opcode_clear_var(state))) - return (error); - - /* Reset revision mask */ - memset(state->revs, 0x0, sizeof(state->revs)); - bit_nset(state->revs, start, end); - - return (0); -} - -/** - * Set the current variable's value mask for @p state. - * - * @param state The opcode state to update - * @param mask The mask to be set - * - * @retval 0 success - * @retval non-zero If updating @p state fails, a regular unix error code will - * be returned. - */ -static inline int -sprom_opcode_set_mask(struct sprom_opcode_state *state, uint32_t mask) -{ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "no open variable definition\n"); - return (EINVAL); - } - - state->var.mask = mask; - return (0); -} - -/** - * Set the current variable's value shift for @p state. - * - * @param state The opcode state to update - * @param shift The shift to be set - * - * @retval 0 success - * @retval non-zero If updating @p state fails, a regular unix error code will - * be returned. - */ -static inline int -sprom_opcode_set_shift(struct sprom_opcode_state *state, int8_t shift) -{ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "no open variable definition\n"); - return (EINVAL); - } - - state->var.shift = shift; - return (0); -} - -/** - * Register a new BIND/BINDN operation with @p state. - * - * @param state The opcode state to update. - * @param count The number of elements to be bound. - * @param skip_in The number of input elements to skip after each bind. - * @param skip_in_negative If true, the input skip should be subtracted from - * the current offset after each bind. If false, the input skip should be - * added. - * @param skip_out The number of output elements to skip after each bind. - * - * @retval 0 success - * @retval EINVAL if a variable definition is not open. - * @retval EINVAL if @p skip_in and @p count would trigger an overflow or - * underflow when applied to the current input offset. - * @retval ERANGE if @p skip_in would overflow uint32_t when multiplied by - * @p count and the scale value. - * @retval ERANGE if @p skip_out would overflow uint32_t when multiplied by - * @p count and the scale value. - * @retval non-zero If updating @p state otherwise fails, a regular unix error - * code will be returned. - */ -static inline int -sprom_opcode_set_bind(struct sprom_opcode_state *state, uint8_t count, - uint8_t skip_in, bool skip_in_negative, uint8_t skip_out) -{ - uint32_t iskip_total; - uint32_t iskip_scaled; - int error; - - /* Must have an open variable */ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "no open variable definition\n"); - SPROM_OP_BAD(state, "BIND outside of variable definition\n"); - return (EINVAL); - } - - /* Cannot overwite an existing bind definition */ - if (state->var.have_bind) { - SPROM_OP_BAD(state, "BIND overwrites existing definition\n"); - return (EINVAL); - } - - /* Must have a count of at least 1 */ - if (count == 0) { - SPROM_OP_BAD(state, "BIND with zero count\n"); - return (EINVAL); - } - - /* Scale skip_in by the current type width */ - iskip_scaled = skip_in; - if ((error = sprom_opcode_apply_scale(state, &iskip_scaled))) - return (error); - - /* Calculate total input bytes skipped: iskip_scaled * count) */ - if (iskip_scaled > 0 && UINT32_MAX / iskip_scaled < count) { - SPROM_OP_BAD(state, "skip_in %hhu would overflow", skip_in); - return (EINVAL); - } - - iskip_total = iskip_scaled * count; - - /* Verify that the skip_in value won't under/overflow the current - * input offset. */ - if (skip_in_negative) { - if (iskip_total > state->offset) { - SPROM_OP_BAD(state, "skip_in %hhu would underflow " - "offset %u\n", skip_in, state->offset); - return (EINVAL); - } - } else { - if (UINT32_MAX - iskip_total < state->offset) { - SPROM_OP_BAD(state, "skip_in %hhu would overflow " - "offset %u\n", skip_in, state->offset); - return (EINVAL); - } - } - - /* Set the actual count and skip values */ - state->var.have_bind = true; - state->var.bind.count = count; - state->var.bind.skip_in = skip_in; - state->var.bind.skip_out = skip_out; - - state->var.bind.skip_in_negative = skip_in_negative; - - /* Update total bind count for the current variable */ - state->var.bind_total++; - - return (0); -} - - -/** - * Apply and clear the current opcode bind state, if any. - * - * @param state The opcode state to update. - * - * @retval 0 success - * @retval non-zero If updating @p state otherwise fails, a regular unix error - * code will be returned. - */ -static int -sprom_opcode_flush_bind(struct sprom_opcode_state *state) -{ - int error; - uint32_t skip; - - /* Nothing to do? */ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN || - !state->var.have_bind) - return (0); - - /* Apply SPROM offset adjustment */ - if (state->var.bind.count > 0) { - skip = state->var.bind.skip_in * state->var.bind.count; - if ((error = sprom_opcode_apply_scale(state, &skip))) - return (error); - - if (state->var.bind.skip_in_negative) { - state->offset -= skip; - } else { - state->offset += skip; - } - } - - /* Clear bind state */ - memset(&state->var.bind, 0, sizeof(state->var.bind)); - state->var.have_bind = false; - - return (0); -} - -/** - * Set the current type to @p type, and reset type-specific - * stream state. - * - * @param state The opcode state to update. - * @param type The new type. - * - * @retval 0 success - * @retval EINVAL if @p vid is not a valid variable ID. - */ -static int -sprom_opcode_set_type(struct sprom_opcode_state *state, bhnd_nvram_type type) -{ - bhnd_nvram_type base_type; - size_t width; - uint32_t mask; - - /* Must have an open variable definition */ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "type set outside variable definition\n"); - return (EINVAL); - } - - /* Fetch type width for use as our scale value */ - width = bhnd_nvram_type_width(type); - if (width == 0) { - SPROM_OP_BAD(state, "unsupported variable-width type: %d\n", - type); - return (EINVAL); - } else if (width > UINT32_MAX) { - SPROM_OP_BAD(state, "invalid type width %zu for type: %d\n", - width, type); - return (EINVAL); - } - - /* Determine default mask value for the element type */ - base_type = bhnd_nvram_base_type(type); - switch (base_type) { - case BHND_NVRAM_TYPE_UINT8: - case BHND_NVRAM_TYPE_INT8: - case BHND_NVRAM_TYPE_CHAR: - mask = UINT8_MAX; - break; - case BHND_NVRAM_TYPE_UINT16: - case BHND_NVRAM_TYPE_INT16: - mask = UINT16_MAX; - break; - case BHND_NVRAM_TYPE_UINT32: - case BHND_NVRAM_TYPE_INT32: - mask = UINT32_MAX; - break; - case BHND_NVRAM_TYPE_STRING: - /* fallthrough (unused by SPROM) */ - default: - SPROM_OP_BAD(state, "unsupported type: %d\n", type); - return (EINVAL); - } - - /* Update state */ - state->var.base_type = base_type; - state->var.mask = mask; - state->var.scale = (uint32_t)width; - - return (0); -} - -/** - * Clear current variable state, if any. - * - * @param state The opcode state to update. - */ -static int -sprom_opcode_clear_var(struct sprom_opcode_state *state) -{ - if (state->var_state == SPROM_OPCODE_VAR_STATE_NONE) - return (0); - - BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_DONE, - ("incomplete variable definition")); - BHND_NV_ASSERT(!state->var.have_bind, ("stale bind state")); - - memset(&state->var, 0, sizeof(state->var)); - state->var_state = SPROM_OPCODE_VAR_STATE_NONE; - - return (0); -} - -/** - * Set the current variable's array element count to @p nelem. - * - * @param state The opcode state to update. - * @param nelem The new array length. - * - * @retval 0 success - * @retval EINVAL if no open variable definition exists. - * @retval EINVAL if @p nelem is zero. - * @retval ENXIO if @p nelem is greater than one, and the current variable does - * not have an array type. - * @retval ENXIO if @p nelem exceeds the array length of the NVRAM variable - * definition. - */ -static int -sprom_opcode_set_nelem(struct sprom_opcode_state *state, uint8_t nelem) -{ + struct bhnd_nvram_sprom *sp; const struct bhnd_nvram_vardefn *var; - - /* Must have a defined variable */ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "array length set without open variable " - "state"); - return (EINVAL); - } - - /* Locate the actual variable definition */ - if ((var = bhnd_nvram_get_vardefn(state->vid)) == NULL) { - SPROM_OP_BAD(state, "unknown variable ID: %zu\n", state->vid); - return (EINVAL); - } - - /* Must be greater than zero */ - if (nelem == 0) { - SPROM_OP_BAD(state, "invalid nelem: %hhu\n", nelem); - return (EINVAL); - } - - /* If the variable is not an array-typed value, the array length - * must be 1 */ - if (!bhnd_nvram_is_array_type(var->type) && nelem != 1) { - SPROM_OP_BAD(state, "nelem %hhu on non-array %zu\n", nelem, - state->vid); - return (ENXIO); - } - - /* Cannot exceed the variable's defined array length */ - if (nelem > var->nelem) { - SPROM_OP_BAD(state, "nelem %hhu exceeds %zu length %hhu\n", - nelem, state->vid, var->nelem); - return (ENXIO); - } - - /* Valid length; update state */ - state->var.nelem = nelem; - - return (0); -} - -/** - * Set the current variable ID to @p vid, and reset variable-specific - * stream state. - * - * @param state The opcode state to update. - * @param vid The new variable ID. - * - * @retval 0 success - * @retval EINVAL if @p vid is not a valid variable ID. - */ -static int -sprom_opcode_set_var(struct sprom_opcode_state *state, size_t vid) -{ - const struct bhnd_nvram_vardefn *var; + bhnd_sprom_opcode_idx_entry *entry; + bhnd_nvram_val *spval; int error; - BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_NONE, - ("overwrite of open variable definition")); + sp = (struct bhnd_nvram_sprom *)nv; - /* Locate the variable definition */ - if ((var = bhnd_nvram_get_vardefn(vid)) == NULL) { - SPROM_OP_BAD(state, "unknown variable ID: %zu\n", vid); + /* Is this an externally immutable variable name? */ + if (bhnd_sprom_is_external_immutable(name)) return (EINVAL); - } - /* Update vid and var state */ - state->vid = vid; - state->var_state = SPROM_OPCODE_VAR_STATE_OPEN; + /* Variable must be defined in our SPROM layout */ + if ((entry = bhnd_sprom_opcode_index_find(&sp->state, name)) == NULL) + return (ENOENT); - /* Initialize default variable record values */ - memset(&state->var, 0x0, sizeof(state->var)); + var = bhnd_nvram_get_vardefn(entry->vid); + BHND_NV_ASSERT(var != NULL, ("missing variable definition")); - /* Set initial base type */ - if ((error = sprom_opcode_set_type(state, var->type))) + /* Value must be convertible to the native variable type */ + error = bhnd_nvram_val_convert_new(&spval, var->fmt, value, + BHND_NVRAM_VAL_DYNAMIC); + if (error) return (error); - /* Set default array length */ - if ((error = sprom_opcode_set_nelem(state, var->nelem))) + /* Value must be encodeable by our SPROM layout */ + error = bhnd_nvram_sprom_write_var(&sp->state, entry, spval, NULL); + if (error) { + bhnd_nvram_val_release(spval); return (error); + } + /* Success. Transfer our ownership of the converted value to the + * caller */ + *result = spval; return (0); } -/** - * Mark the currently open variable definition as complete. - * - * @param state The opcode state to update. - * - * @retval 0 success - * @retval EINVAL if no incomplete open variable definition exists. - */ static int -sprom_opcode_end_var(struct sprom_opcode_state *state) +bhnd_nvram_sprom_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "no open variable definition\n"); - return (EINVAL); - } + struct bhnd_nvram_sprom *sp; + const struct bhnd_nvram_vardefn *var; + bhnd_sprom_opcode_idx_entry *entry; - state->var_state = SPROM_OPCODE_VAR_STATE_DONE; - return (0); -} + sp = (struct bhnd_nvram_sprom *)nv; -/** - * Apply the current scale to @p value. - * - * @param state The SPROM opcode state. - * @param[in,out] value The value to scale - * - * @retval 0 success - * @retval EINVAL if no open variable definition exists. - * @retval EINVAL if applying the current scale would overflow. - */ -static int -sprom_opcode_apply_scale(struct sprom_opcode_state *state, uint32_t *value) -{ - /* Must have a defined variable (and thus, scale) */ - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { - SPROM_OP_BAD(state, "scaled value encoded without open " - "variable state"); + /* Is this an externally immutable variable name? */ + if (bhnd_sprom_is_external_immutable(name)) return (EINVAL); - } - /* Applying the scale value must not overflow */ - if (UINT32_MAX / state->var.scale < *value) { - SPROM_OP_BAD(state, "cannot represent %" PRIu32 " * %" PRIu32 - "\n", *value, state->var.scale); - return (EINVAL); - } + /* Variable must be defined in our SPROM layout */ + if ((entry = bhnd_sprom_opcode_index_find(&sp->state, name)) == NULL) + return (ENOENT); - *value = (*value) * state->var.scale; - return (0); -} + var = bhnd_nvram_get_vardefn(entry->vid); -/** - * Read a SPROM_OP_DATA_* value from @p opcodes. - * - * @param state The SPROM opcode state. - * @param type The SROM_OP_DATA_* type to be read. - * @param opval On success, the 32bit data representation. If @p type is signed, - * the value will be appropriately sign extended and may be directly cast to - * int32_t. - * - * @retval 0 success - * @retval non-zero If reading the value otherwise fails, a regular unix error - * code will be returned. - */ -static int -sprom_opcode_read_opval32(struct sprom_opcode_state *state, uint8_t type, - uint32_t *opval) -{ - const uint8_t *p; - int error; - - p = state->input; - switch (type) { - case SPROM_OP_DATA_I8: - /* Convert to signed value first, then sign extend */ - *opval = (int32_t)(int8_t)(*p); - p += 1; - break; - case SPROM_OP_DATA_U8: - *opval = *p; - p += 1; - break; - case SPROM_OP_DATA_U8_SCALED: - *opval = *p; - - if ((error = sprom_opcode_apply_scale(state, opval))) - return (error); - - p += 1; - break; - case SPROM_OP_DATA_U16: - *opval = le16dec(p); - p += 2; - break; - case SPROM_OP_DATA_U32: - *opval = le32dec(p); - p += 4; - break; - default: - SPROM_OP_BAD(state, "unsupported data type: %hhu\n", type); + /* Variable must be capable of representing a NULL/deleted value. + * + * Since SPROM's layout is fixed, this requires IGNALL -- if + * all bits are set, an IGNALL variable is treated as unset. */ + if (!(var->flags & BHND_NVRAM_VF_IGNALL1)) return (EINVAL); - } - /* Update read address */ - state->input = p; - return (0); } /** - * Return true if our layout revision is currently defined by the SPROM - * opcode state. + * Return true if @p name represents a special immutable variable name + * (e.g. sromrev) that cannot be updated in an SPROM existing image. * - * This may be used to test whether the current opcode stream state applies - * to the layout that we are actually parsing. - * - * A given opcode stream may cover multiple layout revisions, switching - * between them prior to defining a set of variables. + * @param name The name to check. */ -static inline bool -sprom_opcode_matches_layout_rev(struct sprom_opcode_state *state) +static bool +bhnd_sprom_is_external_immutable(const char *name) { - return (bit_test(state->revs, state->layout->rev)); -} + /* The layout revision is immutable and cannot be changed */ + if (strcmp(name, BHND_NVAR_SROMREV) == 0) + return (true); -/** - * When evaluating @p state and @p opcode, rewrite @p opcode and the current - * evaluation state, as required. - * - * If @p opcode is rewritten, it should be returned from - * sprom_opcode_step() instead of the opcode parsed from @p state's opcode - * stream. - * - * If @p opcode remains unmodified, then sprom_opcode_step() should proceed - * to standard evaluation. - */ -static int -sprom_opcode_rewrite_opcode(struct sprom_opcode_state *state, uint8_t *opcode) -{ - uint8_t op; - int error; - - op = SPROM_OPCODE_OP(*opcode); - switch (state->var_state) { - case SPROM_OPCODE_VAR_STATE_NONE: - /* No open variable definition */ - return (0); - - case SPROM_OPCODE_VAR_STATE_OPEN: - /* Open variable definition; check for implicit closure. */ - - /* - * If a variable definition contains no explicit bind - * instructions prior to closure, we must generate a DO_BIND - * instruction with count and skip values of 1. - */ - if (SPROM_OP_IS_VAR_END(op) && - state->var.bind_total == 0) - { - uint8_t count, skip_in, skip_out; - bool skip_in_negative; - - /* Create bind with skip_in/skip_out of 1, count of 1 */ - count = 1; - skip_in = 1; - skip_out = 1; - skip_in_negative = false; - - error = sprom_opcode_set_bind(state, count, skip_in, - skip_in_negative, skip_out); - if (error) - return (error); - - /* Return DO_BIND */ - *opcode = SPROM_OPCODE_DO_BIND | - (0 << SPROM_OP_BIND_SKIP_IN_SIGN) | - (1 << SPROM_OP_BIND_SKIP_IN_SHIFT) | - (1 << SPROM_OP_BIND_SKIP_OUT_SHIFT); - - return (0); - } - - /* - * If a variable is implicitly closed (e.g. by a new variable - * definition), we must generate a VAR_END instruction. - */ - if (SPROM_OP_IS_IMPLICIT_VAR_END(op)) { - /* Mark as complete */ - if ((error = sprom_opcode_end_var(state))) - return (error); - - /* Return VAR_END */ - *opcode = SPROM_OPCODE_VAR_END; - return (0); - } - break; - - - case SPROM_OPCODE_VAR_STATE_DONE: - /* Previously completed variable definition. Discard variable - * state */ - return (sprom_opcode_clear_var(state)); - } - - /* Nothing to do */ - return (0); -} - -/** - * Evaluate one opcode from @p state. - * - * @param state The opcode state to be evaluated. - * @param[out] opcode On success, the evaluated opcode - * - * @retval 0 success - * @retval ENOENT if EOF is reached - * @retval non-zero if evaluation otherwise fails, a regular unix error - * code will be returned. - */ -static int -sprom_opcode_step(struct sprom_opcode_state *state, uint8_t *opcode) -{ - int error; - - while (*state->input != SPROM_OPCODE_EOF) { - uint32_t val; - uint8_t op, rewrite, immd; - - /* Fetch opcode */ - *opcode = *state->input; - op = SPROM_OPCODE_OP(*opcode); - immd = SPROM_OPCODE_IMM(*opcode); - - /* Clear any existing bind state */ - if ((error = sprom_opcode_flush_bind(state))) - return (error); - - /* Insert local opcode based on current state? */ - rewrite = *opcode; - if ((error = sprom_opcode_rewrite_opcode(state, &rewrite))) - return (error); - - if (rewrite != *opcode) { - /* Provide rewritten opcode */ - *opcode = rewrite; - - /* We must keep evaluating until we hit a state - * applicable to the SPROM revision we're parsing */ - if (!sprom_opcode_matches_layout_rev(state)) - continue; - - return (0); - } - - /* Advance input */ - state->input++; - - switch (op) { - case SPROM_OPCODE_VAR_IMM: - if ((error = sprom_opcode_set_var(state, immd))) - return (error); - break; - - case SPROM_OPCODE_VAR_REL_IMM: - error = sprom_opcode_set_var(state, state->vid + immd); - if (error) - return (error); - break; - - case SPROM_OPCODE_VAR: - error = sprom_opcode_read_opval32(state, immd, &val); - if (error) - return (error); - - if ((error = sprom_opcode_set_var(state, val))) - return (error); - - break; - - case SPROM_OPCODE_VAR_END: - if ((error = sprom_opcode_end_var(state))) - return (error); - break; - - case SPROM_OPCODE_NELEM: - immd = *state->input; - if ((error = sprom_opcode_set_nelem(state, immd))) - return (error); - - state->input++; - break; - - case SPROM_OPCODE_DO_BIND: - case SPROM_OPCODE_DO_BINDN: { - uint8_t count, skip_in, skip_out; - bool skip_in_negative; - - /* Fetch skip arguments */ - skip_in = (immd & SPROM_OP_BIND_SKIP_IN_MASK) >> - SPROM_OP_BIND_SKIP_IN_SHIFT; - - skip_in_negative = - ((immd & SPROM_OP_BIND_SKIP_IN_SIGN) != 0); - - skip_out = (immd & SPROM_OP_BIND_SKIP_OUT_MASK) >> - SPROM_OP_BIND_SKIP_OUT_SHIFT; - - /* Fetch count argument (if any) */ - if (op == SPROM_OPCODE_DO_BINDN) { - /* Count is provided as trailing U8 */ - count = *state->input; - state->input++; - } else { - count = 1; - } - - /* Set BIND state */ - error = sprom_opcode_set_bind(state, count, skip_in, - skip_in_negative, skip_out); - if (error) - return (error); - - break; - } - case SPROM_OPCODE_DO_BINDN_IMM: { - uint8_t count, skip_in, skip_out; - bool skip_in_negative; - - /* Implicit skip_in/skip_out of 1, count encoded as immd - * value */ - count = immd; - skip_in = 1; - skip_out = 1; - skip_in_negative = false; - - error = sprom_opcode_set_bind(state, count, skip_in, - skip_in_negative, skip_out); - if (error) - return (error); - break; - } - - case SPROM_OPCODE_REV_IMM: - if ((error = sprom_opcode_set_revs(state, immd, immd))) - return (error); - break; - - case SPROM_OPCODE_REV_RANGE: { - uint8_t range; - uint8_t rstart, rend; - - /* Revision range is encoded in next byte, as - * { uint8_t start:4, uint8_t end:4 } */ - range = *state->input; - rstart = (range & SPROM_OP_REV_START_MASK) >> - SPROM_OP_REV_START_SHIFT; - rend = (range & SPROM_OP_REV_END_MASK) >> - SPROM_OP_REV_END_SHIFT; - - /* Update revision bitmask */ - error = sprom_opcode_set_revs(state, rstart, rend); - if (error) - return (error); - - /* Advance input */ - state->input++; - break; - } - case SPROM_OPCODE_MASK_IMM: - if ((error = sprom_opcode_set_mask(state, immd))) - return (error); - break; - - case SPROM_OPCODE_MASK: - error = sprom_opcode_read_opval32(state, immd, &val); - if (error) - return (error); - - if ((error = sprom_opcode_set_mask(state, val))) - return (error); - break; - - case SPROM_OPCODE_SHIFT_IMM: - if ((error = sprom_opcode_set_shift(state, immd * 2))) - return (error); - break; - - case SPROM_OPCODE_SHIFT: { - int8_t shift; - - if (immd == SPROM_OP_DATA_I8) { - shift = (int8_t)(*state->input); - } else if (immd == SPROM_OP_DATA_U8) { - val = *state->input; - if (val > INT8_MAX) { - SPROM_OP_BAD(state, "invalid shift " - "value: %#x\n", val); - } - - shift = val; - } else { - SPROM_OP_BAD(state, "unsupported shift data " - "type: %#hhx\n", immd); - return (EINVAL); - } - - if ((error = sprom_opcode_set_shift(state, shift))) - return (error); - - state->input++; - break; - } - case SPROM_OPCODE_OFFSET_REL_IMM: - /* Fetch unscaled relative offset */ - val = immd; - - /* Apply scale */ - if ((error = sprom_opcode_apply_scale(state, &val))) - return (error); - - /* Adding val must not overflow our offset */ - if (UINT32_MAX - state->offset < val) { - BHND_NV_LOG("offset out of range\n"); - return (EINVAL); - } - - /* Adjust offset */ - state->offset += val; - break; - case SPROM_OPCODE_OFFSET: - error = sprom_opcode_read_opval32(state, immd, &val); - if (error) - return (error); - - state->offset = val; - break; - - case SPROM_OPCODE_TYPE: - /* Type follows as U8 */ - immd = *state->input; - state->input++; - - /* fall through */ - case SPROM_OPCODE_TYPE_IMM: - switch (immd) { - case BHND_NVRAM_TYPE_UINT8: - case BHND_NVRAM_TYPE_UINT16: - case BHND_NVRAM_TYPE_UINT32: - case BHND_NVRAM_TYPE_UINT64: - case BHND_NVRAM_TYPE_INT8: - case BHND_NVRAM_TYPE_INT16: - case BHND_NVRAM_TYPE_INT32: - case BHND_NVRAM_TYPE_INT64: - case BHND_NVRAM_TYPE_CHAR: - case BHND_NVRAM_TYPE_STRING: - error = sprom_opcode_set_type(state, - (bhnd_nvram_type)immd); - if (error) - return (error); - break; - default: - BHND_NV_LOG("unrecognized type %#hhx\n", immd); - return (EINVAL); - } - break; - - default: - BHND_NV_LOG("unrecognized opcode %#hhx\n", *opcode); - return (EINVAL); - } - - /* We must keep evaluating until we hit a state applicable to - * the SPROM revision we're parsing */ - if (sprom_opcode_matches_layout_rev(state)) - return (0); - } - - /* End of opcode stream */ - return (ENOENT); -} - -/** - * Reset SPROM opcode evaluation state, seek to the @p indexed position, - * and perform complete evaluation of the variable's opcodes. - * - * @param state The opcode state to be to be evaluated. - * @param indexed The indexed variable location. - * - * @retval 0 success - * @retval non-zero If evaluation fails, a regular unix error code will be - * returned. - */ -static int -sprom_opcode_parse_var(struct sprom_opcode_state *state, - struct sprom_opcode_idx *indexed) -{ - uint8_t opcode; - int error; - - /* Seek to entry */ - if ((error = sprom_opcode_state_seek(state, indexed))) - return (error); - - /* Parse full variable definition */ - while ((error = sprom_opcode_step(state, &opcode)) == 0) { - /* Iterate until VAR_END */ - if (SPROM_OPCODE_OP(opcode) != SPROM_OPCODE_VAR_END) - continue; - - BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_DONE, - ("incomplete variable definition")); - - return (0); - } - - /* Error parsing definition */ - return (error); -} - -/** - * Evaluate @p state until the next variable definition is found. - * - * @param state The opcode state to be evaluated. - * - * @retval 0 success - * @retval ENOENT if no additional variable definitions are available. - * @retval non-zero if evaluation otherwise fails, a regular unix error - * code will be returned. - */ -static int -sprom_opcode_next_var(struct sprom_opcode_state *state) -{ - uint8_t opcode; - int error; - - /* Step until we hit a variable opcode */ - while ((error = sprom_opcode_step(state, &opcode)) == 0) { - switch (SPROM_OPCODE_OP(opcode)) { - case SPROM_OPCODE_VAR: - case SPROM_OPCODE_VAR_IMM: - case SPROM_OPCODE_VAR_REL_IMM: - BHND_NV_ASSERT( - state->var_state == SPROM_OPCODE_VAR_STATE_OPEN, - ("missing variable definition")); - - return (0); - default: - continue; - } - } - - /* Reached EOF, or evaluation failed */ - return (error); -} - -/** - * Evaluate @p state until the next binding for the current variable definition - * is found. - * - * @param state The opcode state to be evaluated. - * - * @retval 0 success - * @retval ENOENT if no additional binding opcodes are found prior to reaching - * a new variable definition, or the end of @p state's binding opcodes. - * @retval non-zero if evaluation otherwise fails, a regular unix error - * code will be returned. - */ -static int -sprom_opcode_next_binding(struct sprom_opcode_state *state) -{ - uint8_t opcode; - int error; - - if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) - return (EINVAL); - - /* Step until we hit a bind opcode, or a new variable */ - while ((error = sprom_opcode_step(state, &opcode)) == 0) { - switch (SPROM_OPCODE_OP(opcode)) { - case SPROM_OPCODE_DO_BIND: - case SPROM_OPCODE_DO_BINDN: - case SPROM_OPCODE_DO_BINDN_IMM: - /* Found next bind */ - BHND_NV_ASSERT( - state->var_state == SPROM_OPCODE_VAR_STATE_OPEN, - ("missing variable definition")); - BHND_NV_ASSERT(state->var.have_bind, ("missing bind")); - - return (0); - - case SPROM_OPCODE_VAR_END: - /* No further binding opcodes */ - BHND_NV_ASSERT( - state->var_state == SPROM_OPCODE_VAR_STATE_DONE, - ("variable definition still available")); - return (ENOENT); - } - } - - /* Not found, or evaluation failed */ - return (error); + return (false); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c (nonexistent) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c (revision 310297) @@ -0,0 +1,1366 @@ +/*- + * Copyright (c) 2015-2016 Landon Fuller + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include + +#ifdef _KERNEL +#include +#include +#else /* !_KERNEL */ +#include +#include +#include +#include +#endif /* _KERNEL */ + +#include "bhnd_nvram_private.h" +#include "bhnd_nvram_data_spromvar.h" + +static int bhnd_sprom_opcode_sort_idx(const void *lhs, const void *rhs); +static int bhnd_nvram_opcode_idx_vid_compare(const void *key, + const void *rhs); + +static int bhnd_sprom_opcode_reset(bhnd_sprom_opcode_state *state); +static int bhnd_sprom_opcode_next_var(bhnd_sprom_opcode_state *state); + +static int bhnd_sprom_opcode_set_type(bhnd_sprom_opcode_state *state, + bhnd_nvram_type type); + +static int bhnd_sprom_opcode_set_var(bhnd_sprom_opcode_state *state, + size_t vid); +static int bhnd_sprom_opcode_clear_var(bhnd_sprom_opcode_state *state); + +static int bhnd_sprom_opcode_flush_bind(bhnd_sprom_opcode_state *state); + +static int bhnd_sprom_opcode_read_opval32(bhnd_sprom_opcode_state *state, + uint8_t type, uint32_t *opval); + +static int bhnd_sprom_opcode_step(bhnd_sprom_opcode_state *state, + uint8_t *opcode); + +#define SPROM_OP_BAD(_state, _fmt, ...) \ + BHND_NV_LOG("bad encoding at %td: " _fmt, \ + (_state)->input - (_state)->layout->bindings, ##__VA_ARGS__) + +/** + * Initialize SPROM opcode evaluation state. + * + * @param state The opcode state to be initialized. + * @param layout The SPROM layout to be parsed by this instance. + * + * + * @retval 0 success + * @retval non-zero If initialization fails, a regular unix error code will be + * returned. + */ +int +bhnd_sprom_opcode_init(bhnd_sprom_opcode_state *state, + const struct bhnd_sprom_layout *layout) +{ + bhnd_sprom_opcode_idx_entry *idx; + size_t num_vars, num_idx; + int error; + + idx = NULL; + + state->layout = layout; + state->idx = NULL; + state->num_idx = 0; + + /* Initialize interpretation state */ + if ((error = bhnd_sprom_opcode_reset(state))) + return (error); + + /* Allocate and populate our opcode index */ + num_idx = state->layout->num_vars; + idx = bhnd_nv_calloc(num_idx, sizeof(*idx)); + if (idx == NULL) + return (ENOMEM); + + for (num_vars = 0; num_vars < num_idx; num_vars++) { + size_t opcodes; + + /* Seek to next entry */ + if ((error = bhnd_sprom_opcode_next_var(state))) { + SPROM_OP_BAD(state, "error reading expected variable " + "entry: %d\n", error); + bhnd_nv_free(idx); + return (error); + } + + /* We limit the SPROM index representations to the minimal + * type widths capable of covering all known layouts */ + + /* Save SPROM image offset */ + if (state->offset > UINT16_MAX) { + SPROM_OP_BAD(state, "cannot index large offset %u\n", + state->offset); + bhnd_nv_free(idx); + return (ENXIO); + } + idx[num_vars].offset = state->offset; + + /* Save current variable ID */ + if (state->vid > UINT16_MAX) { + SPROM_OP_BAD(state, "cannot index large vid %zu\n", + state->vid); + bhnd_nv_free(idx); + return (ENXIO); + } + idx[num_vars].vid = state->vid; + + /* Save opcode position */ + opcodes = (state->input - state->layout->bindings); + if (opcodes > UINT16_MAX) { + SPROM_OP_BAD(state, "cannot index large opcode offset " + "%zu\n", opcodes); + bhnd_nv_free(idx); + return (ENXIO); + } + idx[num_vars].opcodes = opcodes; + } + + /* Should have reached end of binding table; next read must return + * ENOENT */ + if ((error = bhnd_sprom_opcode_next_var(state)) != ENOENT) { + BHND_NV_LOG("expected EOF parsing binding table: %d\n", error); + bhnd_nv_free(idx); + return (ENXIO); + } + + /* Reset interpretation state */ + if ((error = bhnd_sprom_opcode_reset(state))) { + bhnd_nv_free(idx); + return (error); + } + + /* Make index available to opcode state evaluation */ + qsort(idx, num_idx, sizeof(idx[0]), bhnd_sprom_opcode_sort_idx); + + state->idx = idx; + state->num_idx = num_idx; + + return (0); +} + +/** + * Reset SPROM opcode evaluation state; future evaluation will be performed + * starting at the first opcode. + * + * @param state The opcode state to be reset. + * + * @retval 0 success + * @retval non-zero If reset fails, a regular unix error code will be returned. + */ +static int +bhnd_sprom_opcode_reset(bhnd_sprom_opcode_state *state) +{ + memset(&state->var, 0, sizeof(state->var)); + + state->input = state->layout->bindings; + state->offset = 0; + state->vid = 0; + state->var_state = SPROM_OPCODE_VAR_STATE_NONE; + bit_set(state->revs, state->layout->rev); + + return (0); +} + +/** + * Free any resources associated with @p state. + * + * @param state An opcode state previously successfully initialized with + * bhnd_sprom_opcode_init(). + */ +void +bhnd_sprom_opcode_fini(bhnd_sprom_opcode_state *state) +{ + bhnd_nv_free(state->idx); +} + + +/** + * Sort function used to prepare our index for querying; sorts + * bhnd_sprom_opcode_idx_entry values by variable ID, ascending. + */ +static int +bhnd_sprom_opcode_sort_idx(const void *lhs, const void *rhs) +{ + const bhnd_sprom_opcode_idx_entry *l, *r; + + l = lhs; + r = rhs; + + if (l->vid < r->vid) + return (-1); + if (l->vid > r->vid) + return (1); + return (0); +} + +/** + * Binary search comparison function used by bhnd_sprom_opcode_index_find(); + * searches bhnd_sprom_opcode_idx_entry values by variable ID, ascending. + */ +static int +bhnd_nvram_opcode_idx_vid_compare(const void *key, const void *rhs) +{ + const bhnd_sprom_opcode_idx_entry *entry; + size_t vid; + + vid = *(const size_t *)key; + entry = rhs; + + if (vid < entry->vid) + return (-1); + if (vid > entry->vid) + return (1); + + return (0); +} + +/** + * Locate an index entry for the variable with @p name, or NULL if not found. + * + * @param state The opcode state to be queried. + * @param name The name to search for. + * + * @retval non-NULL If @p name is found, its index entry value will be + * returned. + * @retval NULL If @p name is not found. + */ +bhnd_sprom_opcode_idx_entry * +bhnd_sprom_opcode_index_find(bhnd_sprom_opcode_state *state, const char *name) +{ + const struct bhnd_nvram_vardefn *var; + size_t vid; + + /* Determine the variable ID for the given name */ + if ((var = bhnd_nvram_find_vardefn(name)) == NULL) + return (NULL); + + vid = bhnd_nvram_get_vardefn_id(var); + + /* Search our index for the variable ID */ + return (bsearch(&vid, state->idx, state->num_idx, sizeof(state->idx[0]), + bhnd_nvram_opcode_idx_vid_compare)); +} + + +/** + * Iterate over all index entries in @p state. + * + * @param state The opcode state to be iterated. + * @param[in,out] prev An entry previously returned by + * bhnd_sprom_opcode_index_next(), or a NULL value + * to begin iteration. + * + * @return Returns the next index entry name, or NULL if all entries have + * been iterated. + */ +bhnd_sprom_opcode_idx_entry * +bhnd_sprom_opcode_index_next(bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *prev) +{ + size_t idxpos; + + /* Get next index position */ + if (prev == NULL) { + idxpos = 0; + } else { + /* Determine current position */ + idxpos = (size_t)(prev - state->idx); + BHND_NV_ASSERT(idxpos < state->num_idx, + ("invalid index %zu", idxpos)); + + /* Advance to next entry */ + idxpos++; + } + + /* Check for EOF */ + if (idxpos == state->num_idx) + return (NULL); + + return (&state->idx[idxpos]); +} + +/** + * Reset SPROM opcode evaluation state and seek to the @p entry's position. + * + * @param state The opcode state to be reset. + * @param entry The indexed entry to which we'll seek the opcode state. + */ +int +bhnd_sprom_opcode_seek(bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry) +{ + int error; + + BHND_NV_ASSERT(entry->opcodes < state->layout->bindings_size, + ("index entry references invalid opcode position")); + + /* Reset state */ + if ((error = bhnd_sprom_opcode_reset(state))) + return (error); + + /* Seek to the indexed sprom opcode offset */ + state->input = state->layout->bindings + entry->opcodes; + + /* Restore the indexed sprom data offset and VID */ + state->offset = entry->offset; + + /* Restore the indexed sprom variable ID */ + if ((error = bhnd_sprom_opcode_set_var(state, entry->vid))) + return (error); + + return (0); +} + +/** + * Set the current revision range for @p state. This also resets + * variable state. + * + * @param state The opcode state to update + * @param start The first revision in the range. + * @param end The last revision in the range. + * + * @retval 0 success + * @retval non-zero If updating @p state fails, a regular unix error code will + * be returned. + */ +static inline int +bhnd_sprom_opcode_set_revs(bhnd_sprom_opcode_state *state, uint8_t start, + uint8_t end) +{ + int error; + + /* Validate the revision range */ + if (start > SPROM_OP_REV_MAX || + end > SPROM_OP_REV_MAX || + end < start) + { + SPROM_OP_BAD(state, "invalid revision range: %hhu-%hhu\n", + start, end); + return (EINVAL); + } + + /* Clear variable state */ + if ((error = bhnd_sprom_opcode_clear_var(state))) + return (error); + + /* Reset revision mask */ + memset(state->revs, 0x0, sizeof(state->revs)); + bit_nset(state->revs, start, end); + + return (0); +} + +/** + * Set the current variable's value mask for @p state. + * + * @param state The opcode state to update + * @param mask The mask to be set + * + * @retval 0 success + * @retval non-zero If updating @p state fails, a regular unix error code will + * be returned. + */ +static inline int +bhnd_sprom_opcode_set_mask(bhnd_sprom_opcode_state *state, uint32_t mask) +{ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "no open variable definition\n"); + return (EINVAL); + } + + state->var.mask = mask; + return (0); +} + +/** + * Set the current variable's value shift for @p state. + * + * @param state The opcode state to update + * @param shift The shift to be set + * + * @retval 0 success + * @retval non-zero If updating @p state fails, a regular unix error code will + * be returned. + */ +static inline int +bhnd_sprom_opcode_set_shift(bhnd_sprom_opcode_state *state, int8_t shift) +{ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "no open variable definition\n"); + return (EINVAL); + } + + state->var.shift = shift; + return (0); +} + +/** + * Register a new BIND/BINDN operation with @p state. + * + * @param state The opcode state to update. + * @param count The number of elements to be bound. + * @param skip_in The number of input elements to skip after each bind. + * @param skip_in_negative If true, the input skip should be subtracted from + * the current offset after each bind. If false, the input skip should be + * added. + * @param skip_out The number of output elements to skip after each bind. + * + * @retval 0 success + * @retval EINVAL if a variable definition is not open. + * @retval EINVAL if @p skip_in and @p count would trigger an overflow or + * underflow when applied to the current input offset. + * @retval ERANGE if @p skip_in would overflow uint32_t when multiplied by + * @p count and the scale value. + * @retval ERANGE if @p skip_out would overflow uint32_t when multiplied by + * @p count and the scale value. + * @retval non-zero If updating @p state otherwise fails, a regular unix error + * code will be returned. + */ +static inline int +bhnd_sprom_opcode_set_bind(bhnd_sprom_opcode_state *state, uint8_t count, + uint8_t skip_in, bool skip_in_negative, uint8_t skip_out) +{ + uint32_t iskip_total; + uint32_t iskip_scaled; + int error; + + /* Must have an open variable */ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "no open variable definition\n"); + SPROM_OP_BAD(state, "BIND outside of variable definition\n"); + return (EINVAL); + } + + /* Cannot overwite an existing bind definition */ + if (state->var.have_bind) { + SPROM_OP_BAD(state, "BIND overwrites existing definition\n"); + return (EINVAL); + } + + /* Must have a count of at least 1 */ + if (count == 0) { + SPROM_OP_BAD(state, "BIND with zero count\n"); + return (EINVAL); + } + + /* Scale skip_in by the current type width */ + iskip_scaled = skip_in; + if ((error = bhnd_sprom_opcode_apply_scale(state, &iskip_scaled))) + return (error); + + /* Calculate total input bytes skipped: iskip_scaled * count) */ + if (iskip_scaled > 0 && UINT32_MAX / iskip_scaled < count) { + SPROM_OP_BAD(state, "skip_in %hhu would overflow", skip_in); + return (EINVAL); + } + + iskip_total = iskip_scaled * count; + + /* Verify that the skip_in value won't under/overflow the current + * input offset. */ + if (skip_in_negative) { + if (iskip_total > state->offset) { + SPROM_OP_BAD(state, "skip_in %hhu would underflow " + "offset %u\n", skip_in, state->offset); + return (EINVAL); + } + } else { + if (UINT32_MAX - iskip_total < state->offset) { + SPROM_OP_BAD(state, "skip_in %hhu would overflow " + "offset %u\n", skip_in, state->offset); + return (EINVAL); + } + } + + /* Set the actual count and skip values */ + state->var.have_bind = true; + state->var.bind.count = count; + state->var.bind.skip_in = skip_in; + state->var.bind.skip_out = skip_out; + + state->var.bind.skip_in_negative = skip_in_negative; + + /* Update total bind count for the current variable */ + state->var.bind_total++; + + return (0); +} + + +/** + * Apply and clear the current opcode bind state, if any. + * + * @param state The opcode state to update. + * + * @retval 0 success + * @retval non-zero If updating @p state otherwise fails, a regular unix error + * code will be returned. + */ +static int +bhnd_sprom_opcode_flush_bind(bhnd_sprom_opcode_state *state) +{ + int error; + uint32_t skip; + + /* Nothing to do? */ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN || + !state->var.have_bind) + return (0); + + /* Apply SPROM offset adjustment */ + if (state->var.bind.count > 0) { + skip = state->var.bind.skip_in * state->var.bind.count; + if ((error = bhnd_sprom_opcode_apply_scale(state, &skip))) + return (error); + + if (state->var.bind.skip_in_negative) { + state->offset -= skip; + } else { + state->offset += skip; + } + } + + /* Clear bind state */ + memset(&state->var.bind, 0, sizeof(state->var.bind)); + state->var.have_bind = false; + + return (0); +} + +/** + * Set the current type to @p type, and reset type-specific + * stream state. + * + * @param state The opcode state to update. + * @param type The new type. + * + * @retval 0 success + * @retval EINVAL if @p vid is not a valid variable ID. + */ +static int +bhnd_sprom_opcode_set_type(bhnd_sprom_opcode_state *state, bhnd_nvram_type type) +{ + bhnd_nvram_type base_type; + size_t width; + uint32_t mask; + + /* Must have an open variable definition */ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "type set outside variable definition\n"); + return (EINVAL); + } + + /* Fetch type width for use as our scale value */ + width = bhnd_nvram_type_width(type); + if (width == 0) { + SPROM_OP_BAD(state, "unsupported variable-width type: %d\n", + type); + return (EINVAL); + } else if (width > UINT32_MAX) { + SPROM_OP_BAD(state, "invalid type width %zu for type: %d\n", + width, type); + return (EINVAL); + } + + /* Determine default mask value for the element type */ + base_type = bhnd_nvram_base_type(type); + switch (base_type) { + case BHND_NVRAM_TYPE_UINT8: + case BHND_NVRAM_TYPE_INT8: + case BHND_NVRAM_TYPE_CHAR: + mask = UINT8_MAX; + break; + case BHND_NVRAM_TYPE_UINT16: + case BHND_NVRAM_TYPE_INT16: + mask = UINT16_MAX; + break; + case BHND_NVRAM_TYPE_UINT32: + case BHND_NVRAM_TYPE_INT32: + mask = UINT32_MAX; + break; + case BHND_NVRAM_TYPE_STRING: + /* fallthrough (unused by SPROM) */ + default: + SPROM_OP_BAD(state, "unsupported type: %d\n", type); + return (EINVAL); + } + + /* Update state */ + state->var.base_type = base_type; + state->var.mask = mask; + state->var.scale = (uint32_t)width; + + return (0); +} + +/** + * Clear current variable state, if any. + * + * @param state The opcode state to update. + */ +static int +bhnd_sprom_opcode_clear_var(bhnd_sprom_opcode_state *state) +{ + if (state->var_state == SPROM_OPCODE_VAR_STATE_NONE) + return (0); + + BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_DONE, + ("incomplete variable definition")); + BHND_NV_ASSERT(!state->var.have_bind, ("stale bind state")); + + memset(&state->var, 0, sizeof(state->var)); + state->var_state = SPROM_OPCODE_VAR_STATE_NONE; + + return (0); +} + +/** + * Set the current variable's array element count to @p nelem. + * + * @param state The opcode state to update. + * @param nelem The new array length. + * + * @retval 0 success + * @retval EINVAL if no open variable definition exists. + * @retval EINVAL if @p nelem is zero. + * @retval ENXIO if @p nelem is greater than one, and the current variable does + * not have an array type. + * @retval ENXIO if @p nelem exceeds the array length of the NVRAM variable + * definition. + */ +static int +bhnd_sprom_opcode_set_nelem(bhnd_sprom_opcode_state *state, uint8_t nelem) +{ + const struct bhnd_nvram_vardefn *var; + + /* Must have a defined variable */ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "array length set without open variable " + "state"); + return (EINVAL); + } + + /* Locate the actual variable definition */ + if ((var = bhnd_nvram_get_vardefn(state->vid)) == NULL) { + SPROM_OP_BAD(state, "unknown variable ID: %zu\n", state->vid); + return (EINVAL); + } + + /* Must be greater than zero */ + if (nelem == 0) { + SPROM_OP_BAD(state, "invalid nelem: %hhu\n", nelem); + return (EINVAL); + } + + /* If the variable is not an array-typed value, the array length + * must be 1 */ + if (!bhnd_nvram_is_array_type(var->type) && nelem != 1) { + SPROM_OP_BAD(state, "nelem %hhu on non-array %zu\n", nelem, + state->vid); + return (ENXIO); + } + + /* Cannot exceed the variable's defined array length */ + if (nelem > var->nelem) { + SPROM_OP_BAD(state, "nelem %hhu exceeds %zu length %hhu\n", + nelem, state->vid, var->nelem); + return (ENXIO); + } + + /* Valid length; update state */ + state->var.nelem = nelem; + + return (0); +} + +/** + * Set the current variable ID to @p vid, and reset variable-specific + * stream state. + * + * @param state The opcode state to update. + * @param vid The new variable ID. + * + * @retval 0 success + * @retval EINVAL if @p vid is not a valid variable ID. + */ +static int +bhnd_sprom_opcode_set_var(bhnd_sprom_opcode_state *state, size_t vid) +{ + const struct bhnd_nvram_vardefn *var; + int error; + + BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_NONE, + ("overwrite of open variable definition")); + + /* Locate the variable definition */ + if ((var = bhnd_nvram_get_vardefn(vid)) == NULL) { + SPROM_OP_BAD(state, "unknown variable ID: %zu\n", vid); + return (EINVAL); + } + + /* Update vid and var state */ + state->vid = vid; + state->var_state = SPROM_OPCODE_VAR_STATE_OPEN; + + /* Initialize default variable record values */ + memset(&state->var, 0x0, sizeof(state->var)); + + /* Set initial base type */ + if ((error = bhnd_sprom_opcode_set_type(state, var->type))) + return (error); + + /* Set default array length */ + if ((error = bhnd_sprom_opcode_set_nelem(state, var->nelem))) + return (error); + + return (0); +} + +/** + * Mark the currently open variable definition as complete. + * + * @param state The opcode state to update. + * + * @retval 0 success + * @retval EINVAL if no incomplete open variable definition exists. + */ +static int +bhnd_sprom_opcode_end_var(bhnd_sprom_opcode_state *state) +{ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "no open variable definition\n"); + return (EINVAL); + } + + state->var_state = SPROM_OPCODE_VAR_STATE_DONE; + return (0); +} + +/** + * Apply the current scale to @p value. + * + * @param state The SPROM opcode state. + * @param[in,out] value The value to scale + * + * @retval 0 success + * @retval EINVAL if no open variable definition exists. + * @retval EINVAL if applying the current scale would overflow. + */ +int +bhnd_sprom_opcode_apply_scale(bhnd_sprom_opcode_state *state, uint32_t *value) +{ + /* Must have a defined variable (and thus, scale) */ + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) { + SPROM_OP_BAD(state, "scaled value encoded without open " + "variable state"); + return (EINVAL); + } + + /* Applying the scale value must not overflow */ + if (UINT32_MAX / state->var.scale < *value) { + SPROM_OP_BAD(state, "cannot represent %" PRIu32 " * %" PRIu32 + "\n", *value, state->var.scale); + return (EINVAL); + } + + *value = (*value) * state->var.scale; + return (0); +} + +/** + * Read a SPROM_OP_DATA_* value from @p opcodes. + * + * @param state The SPROM opcode state. + * @param type The SROM_OP_DATA_* type to be read. + * @param opval On success, the 32bit data representation. If @p type is signed, + * the value will be appropriately sign extended and may be directly cast to + * int32_t. + * + * @retval 0 success + * @retval non-zero If reading the value otherwise fails, a regular unix error + * code will be returned. + */ +static int +bhnd_sprom_opcode_read_opval32(bhnd_sprom_opcode_state *state, uint8_t type, + uint32_t *opval) +{ + const uint8_t *p; + int error; + + p = state->input; + switch (type) { + case SPROM_OP_DATA_I8: + /* Convert to signed value first, then sign extend */ + *opval = (int32_t)(int8_t)(*p); + p += 1; + break; + case SPROM_OP_DATA_U8: + *opval = *p; + p += 1; + break; + case SPROM_OP_DATA_U8_SCALED: + *opval = *p; + + if ((error = bhnd_sprom_opcode_apply_scale(state, opval))) + return (error); + + p += 1; + break; + case SPROM_OP_DATA_U16: + *opval = le16dec(p); + p += 2; + break; + case SPROM_OP_DATA_U32: + *opval = le32dec(p); + p += 4; + break; + default: + SPROM_OP_BAD(state, "unsupported data type: %hhu\n", type); + return (EINVAL); + } + + /* Update read address */ + state->input = p; + + return (0); +} + +/** + * Return true if our layout revision is currently defined by the SPROM + * opcode state. + * + * This may be used to test whether the current opcode stream state applies + * to the layout that we are actually parsing. + * + * A given opcode stream may cover multiple layout revisions, switching + * between them prior to defining a set of variables. + */ +static inline bool +bhnd_sprom_opcode_matches_layout_rev(bhnd_sprom_opcode_state *state) +{ + return (bit_test(state->revs, state->layout->rev)); +} + +/** + * When evaluating @p state and @p opcode, rewrite @p opcode based on the + * current evaluation state. + * + * This allows the insertion of implicit opcodes into interpretation of the + * opcode stream. + * + * If @p opcode is rewritten, it should be returned from + * bhnd_sprom_opcode_step() instead of the opcode parsed from @p state's opcode + * stream. + * + * If @p opcode remains unmodified, then bhnd_sprom_opcode_step() should + * proceed to standard evaluation. + */ +static int +bhnd_sprom_opcode_rewrite_opcode(bhnd_sprom_opcode_state *state, + uint8_t *opcode) +{ + uint8_t op; + int error; + + op = SPROM_OPCODE_OP(*opcode); + switch (state->var_state) { + case SPROM_OPCODE_VAR_STATE_NONE: + /* No open variable definition */ + return (0); + + case SPROM_OPCODE_VAR_STATE_OPEN: + /* Open variable definition; check for implicit closure. */ + + /* + * If a variable definition contains no explicit bind + * instructions prior to closure, we must generate a DO_BIND + * instruction with count and skip values of 1. + */ + if (SPROM_OP_IS_VAR_END(op) && + state->var.bind_total == 0) + { + uint8_t count, skip_in, skip_out; + bool skip_in_negative; + + /* Create bind with skip_in/skip_out of 1, count of 1 */ + count = 1; + skip_in = 1; + skip_out = 1; + skip_in_negative = false; + + error = bhnd_sprom_opcode_set_bind(state, count, + skip_in, skip_in_negative, skip_out); + if (error) + return (error); + + /* Return DO_BIND */ + *opcode = SPROM_OPCODE_DO_BIND | + (0 << SPROM_OP_BIND_SKIP_IN_SIGN) | + (1 << SPROM_OP_BIND_SKIP_IN_SHIFT) | + (1 << SPROM_OP_BIND_SKIP_OUT_SHIFT); + + return (0); + } + + /* + * If a variable is implicitly closed (e.g. by a new variable + * definition), we must generate a VAR_END instruction. + */ + if (SPROM_OP_IS_IMPLICIT_VAR_END(op)) { + /* Mark as complete */ + if ((error = bhnd_sprom_opcode_end_var(state))) + return (error); + + /* Return VAR_END */ + *opcode = SPROM_OPCODE_VAR_END; + return (0); + } + break; + + + case SPROM_OPCODE_VAR_STATE_DONE: + /* Previously completed variable definition. Discard variable + * state */ + return (bhnd_sprom_opcode_clear_var(state)); + } + + /* Nothing to do */ + return (0); +} + +/** + * Evaluate one opcode from @p state. + * + * @param state The opcode state to be evaluated. + * @param[out] opcode On success, the evaluated opcode + * + * @retval 0 success + * @retval ENOENT if EOF is reached + * @retval non-zero if evaluation otherwise fails, a regular unix error + * code will be returned. + */ +static int +bhnd_sprom_opcode_step(bhnd_sprom_opcode_state *state, uint8_t *opcode) +{ + int error; + + while (*state->input != SPROM_OPCODE_EOF) { + uint32_t val; + uint8_t op, rewrite, immd; + + /* Fetch opcode */ + *opcode = *state->input; + op = SPROM_OPCODE_OP(*opcode); + immd = SPROM_OPCODE_IMM(*opcode); + + /* Clear any existing bind state */ + if ((error = bhnd_sprom_opcode_flush_bind(state))) + return (error); + + /* Insert local opcode based on current state? */ + rewrite = *opcode; + if ((error = bhnd_sprom_opcode_rewrite_opcode(state, &rewrite))) + return (error); + + if (rewrite != *opcode) { + /* Provide rewritten opcode */ + *opcode = rewrite; + + /* We must keep evaluating until we hit a state + * applicable to the SPROM revision we're parsing */ + if (!bhnd_sprom_opcode_matches_layout_rev(state)) + continue; + + return (0); + } + + /* Advance input */ + state->input++; + + switch (op) { + case SPROM_OPCODE_VAR_IMM: + if ((error = bhnd_sprom_opcode_set_var(state, immd))) + return (error); + break; + + case SPROM_OPCODE_VAR_REL_IMM: + error = bhnd_sprom_opcode_set_var(state, + state->vid + immd); + if (error) + return (error); + break; + + case SPROM_OPCODE_VAR: + error = bhnd_sprom_opcode_read_opval32(state, immd, + &val); + if (error) + return (error); + + if ((error = bhnd_sprom_opcode_set_var(state, val))) + return (error); + + break; + + case SPROM_OPCODE_VAR_END: + if ((error = bhnd_sprom_opcode_end_var(state))) + return (error); + break; + + case SPROM_OPCODE_NELEM: + immd = *state->input; + if ((error = bhnd_sprom_opcode_set_nelem(state, immd))) + return (error); + + state->input++; + break; + + case SPROM_OPCODE_DO_BIND: + case SPROM_OPCODE_DO_BINDN: { + uint8_t count, skip_in, skip_out; + bool skip_in_negative; + + /* Fetch skip arguments */ + skip_in = (immd & SPROM_OP_BIND_SKIP_IN_MASK) >> + SPROM_OP_BIND_SKIP_IN_SHIFT; + + skip_in_negative = + ((immd & SPROM_OP_BIND_SKIP_IN_SIGN) != 0); + + skip_out = (immd & SPROM_OP_BIND_SKIP_OUT_MASK) >> + SPROM_OP_BIND_SKIP_OUT_SHIFT; + + /* Fetch count argument (if any) */ + if (op == SPROM_OPCODE_DO_BINDN) { + /* Count is provided as trailing U8 */ + count = *state->input; + state->input++; + } else { + count = 1; + } + + /* Set BIND state */ + error = bhnd_sprom_opcode_set_bind(state, count, + skip_in, skip_in_negative, skip_out); + if (error) + return (error); + + break; + } + case SPROM_OPCODE_DO_BINDN_IMM: { + uint8_t count, skip_in, skip_out; + bool skip_in_negative; + + /* Implicit skip_in/skip_out of 1, count encoded as immd + * value */ + count = immd; + skip_in = 1; + skip_out = 1; + skip_in_negative = false; + + error = bhnd_sprom_opcode_set_bind(state, count, + skip_in, skip_in_negative, skip_out); + if (error) + return (error); + break; + } + + case SPROM_OPCODE_REV_IMM: + error = bhnd_sprom_opcode_set_revs(state, immd, immd); + if (error) + return (error); + break; + + case SPROM_OPCODE_REV_RANGE: { + uint8_t range; + uint8_t rstart, rend; + + /* Revision range is encoded in next byte, as + * { uint8_t start:4, uint8_t end:4 } */ + range = *state->input; + rstart = (range & SPROM_OP_REV_START_MASK) >> + SPROM_OP_REV_START_SHIFT; + rend = (range & SPROM_OP_REV_END_MASK) >> + SPROM_OP_REV_END_SHIFT; + + /* Update revision bitmask */ + error = bhnd_sprom_opcode_set_revs(state, rstart, rend); + if (error) + return (error); + + /* Advance input */ + state->input++; + break; + } + case SPROM_OPCODE_MASK_IMM: + if ((error = bhnd_sprom_opcode_set_mask(state, immd))) + return (error); + break; + + case SPROM_OPCODE_MASK: + error = bhnd_sprom_opcode_read_opval32(state, immd, + &val); + if (error) + return (error); + + if ((error = bhnd_sprom_opcode_set_mask(state, val))) + return (error); + break; + + case SPROM_OPCODE_SHIFT_IMM: + error = bhnd_sprom_opcode_set_shift(state, immd * 2); + if (error) + return (error); + break; + + case SPROM_OPCODE_SHIFT: { + int8_t shift; + + if (immd == SPROM_OP_DATA_I8) { + shift = (int8_t)(*state->input); + } else if (immd == SPROM_OP_DATA_U8) { + val = *state->input; + if (val > INT8_MAX) { + SPROM_OP_BAD(state, "invalid shift " + "value: %#x\n", val); + } + + shift = val; + } else { + SPROM_OP_BAD(state, "unsupported shift data " + "type: %#hhx\n", immd); + return (EINVAL); + } + + if ((error = bhnd_sprom_opcode_set_shift(state, shift))) + return (error); + + state->input++; + break; + } + case SPROM_OPCODE_OFFSET_REL_IMM: + /* Fetch unscaled relative offset */ + val = immd; + + /* Apply scale */ + error = bhnd_sprom_opcode_apply_scale(state, &val); + if (error) + return (error); + + /* Adding val must not overflow our offset */ + if (UINT32_MAX - state->offset < val) { + BHND_NV_LOG("offset out of range\n"); + return (EINVAL); + } + + /* Adjust offset */ + state->offset += val; + break; + case SPROM_OPCODE_OFFSET: + error = bhnd_sprom_opcode_read_opval32(state, immd, + &val); + if (error) + return (error); + + state->offset = val; + break; + + case SPROM_OPCODE_TYPE: + /* Type follows as U8 */ + immd = *state->input; + state->input++; + + /* fall through */ + case SPROM_OPCODE_TYPE_IMM: + switch (immd) { + case BHND_NVRAM_TYPE_UINT8: + case BHND_NVRAM_TYPE_UINT16: + case BHND_NVRAM_TYPE_UINT32: + case BHND_NVRAM_TYPE_UINT64: + case BHND_NVRAM_TYPE_INT8: + case BHND_NVRAM_TYPE_INT16: + case BHND_NVRAM_TYPE_INT32: + case BHND_NVRAM_TYPE_INT64: + case BHND_NVRAM_TYPE_CHAR: + case BHND_NVRAM_TYPE_STRING: + error = bhnd_sprom_opcode_set_type(state, + (bhnd_nvram_type)immd); + if (error) + return (error); + break; + default: + BHND_NV_LOG("unrecognized type %#hhx\n", immd); + return (EINVAL); + } + break; + + default: + BHND_NV_LOG("unrecognized opcode %#hhx\n", *opcode); + return (EINVAL); + } + + /* We must keep evaluating until we hit a state applicable to + * the SPROM revision we're parsing */ + if (bhnd_sprom_opcode_matches_layout_rev(state)) + return (0); + } + + /* End of opcode stream */ + return (ENOENT); +} + +/** + * Reset SPROM opcode evaluation state, seek to the @p entry's position, + * and perform complete evaluation of the variable's opcodes. + * + * @param state The opcode state to be to be evaluated. + * @param entry The indexed variable location. + * + * @retval 0 success + * @retval non-zero If evaluation fails, a regular unix error code will be + * returned. + */ +int +bhnd_sprom_opcode_parse_var(bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry) +{ + uint8_t opcode; + int error; + + /* Seek to entry */ + if ((error = bhnd_sprom_opcode_seek(state, entry))) + return (error); + + /* Parse full variable definition */ + while ((error = bhnd_sprom_opcode_step(state, &opcode)) == 0) { + /* Iterate until VAR_END */ + if (SPROM_OPCODE_OP(opcode) != SPROM_OPCODE_VAR_END) + continue; + + BHND_NV_ASSERT(state->var_state == SPROM_OPCODE_VAR_STATE_DONE, + ("incomplete variable definition")); + + return (0); + } + + /* Error parsing definition */ + return (error); +} + +/** + * Evaluate @p state until the next variable definition is found. + * + * @param state The opcode state to be evaluated. + * + * @retval 0 success + * @retval ENOENT if no additional variable definitions are available. + * @retval non-zero if evaluation otherwise fails, a regular unix error + * code will be returned. + */ +static int +bhnd_sprom_opcode_next_var(bhnd_sprom_opcode_state *state) +{ + uint8_t opcode; + int error; + + /* Step until we hit a variable opcode */ + while ((error = bhnd_sprom_opcode_step(state, &opcode)) == 0) { + switch (SPROM_OPCODE_OP(opcode)) { + case SPROM_OPCODE_VAR: + case SPROM_OPCODE_VAR_IMM: + case SPROM_OPCODE_VAR_REL_IMM: + BHND_NV_ASSERT( + state->var_state == SPROM_OPCODE_VAR_STATE_OPEN, + ("missing variable definition")); + + return (0); + default: + continue; + } + } + + /* Reached EOF, or evaluation failed */ + return (error); +} + +/** + * Evaluate @p state until the next binding for the current variable definition + * is found. + * + * @param state The opcode state to be evaluated. + * + * @retval 0 success + * @retval ENOENT if no additional binding opcodes are found prior to reaching + * a new variable definition, or the end of @p state's binding opcodes. + * @retval non-zero if evaluation otherwise fails, a regular unix error + * code will be returned. + */ +int +bhnd_sprom_opcode_next_binding(bhnd_sprom_opcode_state *state) +{ + uint8_t opcode; + int error; + + if (state->var_state != SPROM_OPCODE_VAR_STATE_OPEN) + return (EINVAL); + + /* Step until we hit a bind opcode, or a new variable */ + while ((error = bhnd_sprom_opcode_step(state, &opcode)) == 0) { + switch (SPROM_OPCODE_OP(opcode)) { + case SPROM_OPCODE_DO_BIND: + case SPROM_OPCODE_DO_BINDN: + case SPROM_OPCODE_DO_BINDN_IMM: + /* Found next bind */ + BHND_NV_ASSERT( + state->var_state == SPROM_OPCODE_VAR_STATE_OPEN, + ("missing variable definition")); + BHND_NV_ASSERT(state->var.have_bind, ("missing bind")); + + return (0); + + case SPROM_OPCODE_VAR_END: + /* No further binding opcodes */ + BHND_NV_ASSERT( + state->var_state == SPROM_OPCODE_VAR_STATE_DONE, + ("variable definition still available")); + return (ENOENT); + } + } + + /* Not found, or evaluation failed */ + return (error); +} Property changes on: head/sys/dev/bhnd/nvram/bhnd_nvram_data_sprom_subr.c ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_spromvar.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_spromvar.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_spromvar.h (revision 310297) @@ -1,150 +1,174 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ #define _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ #ifdef _KERNEL #include #else #include #endif #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_io.h" /** The maximum number of array elements encoded in a single SPROM variable */ -#define SPROM_ARRAY_MAXLEN 12 +#define BHND_SPROM_ARRAY_MAXLEN 12 +typedef struct bhnd_sprom_opcode_state bhnd_sprom_opcode_state; +typedef struct bhnd_sprom_opcode_bind bhnd_sprom_opcode_bind; +typedef struct bhnd_sprom_opcode_var bhnd_sprom_opcode_var; +typedef struct bhnd_sprom_opcode_idx_entry bhnd_sprom_opcode_idx_entry; + +int bhnd_sprom_opcode_init( + bhnd_sprom_opcode_state *state, + const bhnd_sprom_layout *layout); +void bhnd_sprom_opcode_fini( + bhnd_sprom_opcode_state *state); + +bhnd_sprom_opcode_idx_entry *bhnd_sprom_opcode_index_find( + bhnd_sprom_opcode_state *state, + const char *name); +bhnd_sprom_opcode_idx_entry *bhnd_sprom_opcode_index_next( + bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *prev); + +int bhnd_sprom_opcode_parse_var( + bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry); + +int bhnd_sprom_opcode_seek( + bhnd_sprom_opcode_state *state, + bhnd_sprom_opcode_idx_entry *entry); +int bhnd_sprom_opcode_next_binding( + bhnd_sprom_opcode_state *state); +int bhnd_sprom_opcode_apply_scale( + bhnd_sprom_opcode_state *state, + uint32_t *value); + /** * SPROM opcode per-bind evaluation state. */ -struct sprom_opcode_bind { +struct bhnd_sprom_opcode_bind { uint8_t count; uint32_t skip_in; /**< input element skips */ bool skip_in_negative; /**< skip_in should be subtracted */ uint32_t skip_out; /**< output element skip */ }; /** * SPROM opcode per-variable evaluation state. */ -struct sprom_opcode_var { - uint8_t nelem; /**< variable array length */ - uint32_t mask; /**< current bind input mask */ - int8_t shift; /**< current bind input shift */ - bhnd_nvram_type base_type; /**< current bind input type */ - uint32_t scale; /**< current scale to apply to scaled encodings */ - struct sprom_opcode_bind bind; /**< current bind state */ - bool have_bind; /**< if bind state is defined */ - size_t bind_total; /**< total count of bind operations performed */ +struct bhnd_sprom_opcode_var { + uint8_t nelem; /**< variable array length */ + uint32_t mask; /**< current bind input mask */ + int8_t shift; /**< current bind input shift */ + bhnd_nvram_type base_type; /**< current bind input type */ + uint32_t scale; /**< current scale to apply to scaled encodings */ + bhnd_sprom_opcode_bind bind; /**< current bind state */ + bool have_bind; /**< if bind state is defined */ + size_t bind_total; /**< total count of bind operations performed */ }; /** * SPROM opcode variable definition states. * * Ordered to support inequality comparisons * (e.g. >= SPROM_OPCODE_VAR_STATE_OPEN) */ typedef enum { SPROM_OPCODE_VAR_STATE_NONE = 1, /**< no variable entry available */ SPROM_OPCODE_VAR_STATE_OPEN = 2, /**< currently parsing a variable entry */ SPROM_OPCODE_VAR_STATE_DONE = 3 /**< full variable entry has been parsed */ -} sprom_opcode_var_state; +} bhnd_sprom_opcode_var_state; /** * SPROM opcode evaluation state */ -struct sprom_opcode_state { - const struct bhnd_sprom_layout *layout; /**< SPROM layout */ +struct bhnd_sprom_opcode_state { + const bhnd_sprom_layout *layout; /**< SPROM layout */ + bhnd_sprom_opcode_idx_entry *idx; /**< variable index (NULL during initialization) */ + size_t num_idx; /**< variable index entry count */ + /** Current SPROM revision range */ bitstr_t bit_decl(revs, SPROM_OP_REV_MAX); const uint8_t *input; /**< opcode input position */ /* State preserved across variable definitions */ uint32_t offset; /**< SPROM offset */ size_t vid; /**< Variable ID */ /* State reset after end of each variable definition */ - struct sprom_opcode_var var; /**< variable record (if any) */ - sprom_opcode_var_state var_state; /**< variable record state */ + bhnd_sprom_opcode_var var; /**< variable record (if any) */ + bhnd_sprom_opcode_var_state var_state; /**< variable record state */ }; /** * SPROM opcode variable index entry */ -struct sprom_opcode_idx { +struct bhnd_sprom_opcode_idx_entry { uint16_t vid; /**< SPROM variable ID */ uint16_t offset; /**< SPROM input offset */ uint16_t opcodes; /**< SPROM opcode offset */ }; /** * SPROM value storage. * * Sufficient for representing the native encoding of any defined SPROM * variable. */ union bhnd_nvram_sprom_storage { - uint8_t u8[SPROM_ARRAY_MAXLEN]; - uint16_t u16[SPROM_ARRAY_MAXLEN]; - uint32_t u32[SPROM_ARRAY_MAXLEN]; - int8_t i8[SPROM_ARRAY_MAXLEN]; - int16_t i16[SPROM_ARRAY_MAXLEN]; - int32_t i32[SPROM_ARRAY_MAXLEN]; - char ch[SPROM_ARRAY_MAXLEN]; + uint8_t u8[BHND_SPROM_ARRAY_MAXLEN]; + uint16_t u16[BHND_SPROM_ARRAY_MAXLEN]; + uint32_t u32[BHND_SPROM_ARRAY_MAXLEN]; + int8_t i8[BHND_SPROM_ARRAY_MAXLEN]; + int16_t i16[BHND_SPROM_ARRAY_MAXLEN]; + int32_t i32[BHND_SPROM_ARRAY_MAXLEN]; + char ch[BHND_SPROM_ARRAY_MAXLEN]; }; /** - * SPROM common integer value representation. - */ -union bhnd_nvram_sprom_intv { - uint32_t u32; - int32_t s32; -}; - -/** * SPROM data class instance state. */ struct bhnd_nvram_sprom { - struct bhnd_nvram_data nv; /**< common instance state */ - struct bhnd_nvram_io *data; /**< backing SPROM image */ - const struct bhnd_sprom_layout *layout; /**< layout definition */ - struct sprom_opcode_state state; /**< opcode eval state */ - struct sprom_opcode_idx *idx; /**< opcode index entries */ - size_t num_idx; /**< opcode index entry count */ + struct bhnd_nvram_data nv; /**< common instance state */ + struct bhnd_nvram_io *data; /**< backing SPROM image */ + const bhnd_sprom_layout *layout; /**< layout definition */ + bhnd_sprom_opcode_state state; /**< opcode eval state */ }; #endif /* _BHND_NVRAM_BHND_NVRAM_SPROMVAR_H_ */ Index: head/sys/dev/bhnd/nvram/bhnd_nvram_data_tlv.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_data_tlv.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_data_tlv.c (revision 310297) @@ -1,773 +1,813 @@ /*- * Copyright (c) 2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #ifdef _KERNEL #include #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_data_tlvreg.h" /* * CFE TLV NVRAM data class. * * The CFE-defined TLV NVRAM format is used on the WGT634U. */ struct bhnd_nvram_tlv { struct bhnd_nvram_data nv; /**< common instance state */ struct bhnd_nvram_io *data; /**< backing buffer */ size_t count; /**< variable count */ }; -BHND_NVRAM_DATA_CLASS_DEFN(tlv, "WGT634U", sizeof(struct bhnd_nvram_tlv)) +BHND_NVRAM_DATA_CLASS_DEFN(tlv, "WGT634U", BHND_NVRAM_DATA_CAP_DEVPATHS, + sizeof(struct bhnd_nvram_tlv)) /** Minimal TLV_ENV record header */ struct bhnd_nvram_tlv_env_hdr { uint8_t tag; uint8_t size; } __packed; /** Minimal TLV_ENV record */ struct bhnd_nvram_tlv_env { struct bhnd_nvram_tlv_env_hdr hdr; uint8_t flags; char envp[]; } __packed; /* Return the length in bytes of an TLV_ENV's envp data */ #define NVRAM_TLV_ENVP_DATA_LEN(_env) \ (((_env)->hdr.size < sizeof((_env)->flags)) ? 0 : \ ((_env)->hdr.size - sizeof((_env)->flags))) /* Maximum supported length of the envp data field, in bytes */ #define NVRAM_TLV_ENVP_DATA_MAX_LEN \ (UINT8_MAX - sizeof(uint8_t) /* flags */) static int bhnd_nvram_tlv_parse_size( struct bhnd_nvram_io *io, size_t *size); static int bhnd_nvram_tlv_next_record( struct bhnd_nvram_io *io, size_t *next, size_t *offset, uint8_t *tag); static struct bhnd_nvram_tlv_env *bhnd_nvram_tlv_next_env( struct bhnd_nvram_tlv *tlv, size_t *next, void **cookiep); static struct bhnd_nvram_tlv_env *bhnd_nvram_tlv_get_env( struct bhnd_nvram_tlv *tlv, void *cookiep); static void *bhnd_nvram_tlv_to_cookie( struct bhnd_nvram_tlv *tlv, size_t io_offset); static size_t bhnd_nvram_tlv_to_offset( struct bhnd_nvram_tlv *tlv, void *cookiep); static int bhnd_nvram_tlv_probe(struct bhnd_nvram_io *io) { struct bhnd_nvram_tlv_env ident; size_t nbytes; int error; nbytes = bhnd_nvram_io_getsize(io); /* Handle what might be an empty TLV image */ if (nbytes < sizeof(ident)) { uint8_t tag; /* Fetch just the first tag */ error = bhnd_nvram_io_read(io, 0x0, &tag, sizeof(tag)); if (error) return (error); /* This *could* be an empty TLV image, but all we're * testing for here is a single 0x0 byte followed by EOF */ if (tag == NVRAM_TLV_TYPE_END) return (BHND_NVRAM_DATA_PROBE_MAYBE); return (ENXIO); } /* Otherwise, look at the initial header for a valid TLV ENV tag, * plus one byte of the entry data */ error = bhnd_nvram_io_read(io, 0x0, &ident, sizeof(ident) + sizeof(ident.envp[0])); if (error) return (error); /* First entry should be a variable record (which we statically * assert as being defined to use a single byte size field) */ if (ident.hdr.tag != NVRAM_TLV_TYPE_ENV) return (ENXIO); _Static_assert(NVRAM_TLV_TYPE_ENV & NVRAM_TLV_TF_U8_LEN, "TYPE_ENV is not a U8-sized field"); /* The entry must be at least 3 characters ('x=\0') in length */ if (ident.hdr.size < 3) return (ENXIO); /* The first character should be a valid key char (alpha) */ if (!bhnd_nv_isalpha(ident.envp[0])) return (ENXIO); return (BHND_NVRAM_DATA_PROBE_DEFAULT); } +static int +bhnd_nvram_tlv_serialize(bhnd_nvram_data_class *cls, bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, size_t *olen) +{ + bhnd_nvram_prop *prop; + size_t limit, nbytes; + int error; + + /* Determine output byte limit */ + if (outp != NULL) + limit = *olen; + else + limit = 0; + + nbytes = 0; + + /* Write all properties */ + prop = NULL; + while ((prop = bhnd_nvram_plist_next(props, prop)) != NULL) { + struct bhnd_nvram_tlv_env env; + const char *name; + uint8_t *p; + size_t name_len, value_len; + size_t rec_size; + + env.hdr.tag = NVRAM_TLV_TYPE_ENV; + env.hdr.size = sizeof(env.flags); + env.flags = 0x0; + + /* Fetch name value and add to record length */ + name = bhnd_nvram_prop_name(prop); + name_len = strlen(name) + 1 /* '=' */; + + if (UINT8_MAX - env.hdr.size < name_len) { + BHND_NV_LOG("%s name exceeds maximum TLV record " + "length\n", name); + return (EFTYPE); /* would overflow TLV size */ + } + + env.hdr.size += name_len; + + /* Add string value to record length */ + error = bhnd_nvram_prop_encode(prop, NULL, &value_len, + BHND_NVRAM_TYPE_STRING); + if (error) { + BHND_NV_LOG("error serializing %s to required type " + "%s: %d\n", name, + bhnd_nvram_type_name(BHND_NVRAM_TYPE_STRING), + error); + return (error); + } + + if (UINT8_MAX - env.hdr.size < value_len) { + BHND_NV_LOG("%s value exceeds maximum TLV record " + "length\n", name); + return (EFTYPE); /* would overflow TLV size */ + } + + env.hdr.size += value_len; + + /* Calculate total record size */ + rec_size = sizeof(env.hdr) + env.hdr.size; + if (SIZE_MAX - nbytes < rec_size) + return (EFTYPE); /* would overflow size_t */ + + /* Calculate our output pointer */ + if (nbytes > limit || limit - nbytes < rec_size) { + /* buffer is full; cannot write */ + p = NULL; + } else { + p = (uint8_t *)outp + nbytes; + } + + /* Write to output */ + if (p != NULL) { + memcpy(p, &env, sizeof(env)); + p += sizeof(env); + + memcpy(p, name, name_len - 1); + p[name_len - 1] = '='; + p += name_len; + + error = bhnd_nvram_prop_encode(prop, p, &value_len, + BHND_NVRAM_TYPE_STRING); + if (error) { + BHND_NV_LOG("error serializing %s to required " + "type %s: %d\n", name, + bhnd_nvram_type_name( + BHND_NVRAM_TYPE_STRING), + error); + return (error); + } + } + + nbytes += rec_size; + } + + /* Write terminating END record */ + if (limit > nbytes) + *((uint8_t *)outp + nbytes) = NVRAM_TLV_TYPE_END; + + if (nbytes == SIZE_MAX) + return (EFTYPE); /* would overflow size_t */ + nbytes++; + + /* Provide required length */ + *olen = nbytes; + if (limit < *olen) { + if (outp == NULL) + return (0); + + return (ENOMEM); + } + + return (0); +} + /** * Initialize @p tlv with the provided NVRAM TLV data mapped by @p src. * * @param tlv A newly allocated data instance. */ static int bhnd_nvram_tlv_init(struct bhnd_nvram_tlv *tlv, struct bhnd_nvram_io *src) { struct bhnd_nvram_tlv_env *env; size_t size; size_t next; int error; BHND_NV_ASSERT(tlv->data == NULL, ("tlv data already initialized")); /* Determine the actual size of the TLV source data */ if ((error = bhnd_nvram_tlv_parse_size(src, &size))) return (error); /* Copy to our own internal buffer */ if ((tlv->data = bhnd_nvram_iobuf_copy_range(src, 0x0, size)) == NULL) return (ENOMEM); /* Initialize our backing buffer */ tlv->count = 0; next = 0; while ((env = bhnd_nvram_tlv_next_env(tlv, &next, NULL)) != NULL) { size_t env_len; size_t name_len; /* TLV_ENV data must not be empty */ env_len = NVRAM_TLV_ENVP_DATA_LEN(env); if (env_len == 0) { BHND_NV_LOG("cannot parse zero-length TLV_ENV record " "data\n"); return (EINVAL); } /* Parse the key=value string, and then replace the '=' * delimiter with '\0' to allow us to provide direct * name pointers from our backing buffer */ error = bhnd_nvram_parse_env(env->envp, env_len, '=', NULL, &name_len, NULL, NULL); if (error) { BHND_NV_LOG("error parsing TLV_ENV data: %d\n", error); return (error); } /* Replace '=' with '\0' */ *(env->envp + name_len) = '\0'; /* Add to variable count */ tlv->count++; }; return (0); } static int bhnd_nvram_tlv_new(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io) { struct bhnd_nvram_tlv *tlv; int error; /* Allocate and initialize the TLV data instance */ tlv = (struct bhnd_nvram_tlv *)nv; /* Parse the TLV input data and initialize our backing * data representation */ if ((error = bhnd_nvram_tlv_init(tlv, io))) { bhnd_nvram_tlv_free(nv); return (error); } return (0); } static void bhnd_nvram_tlv_free(struct bhnd_nvram_data *nv) { struct bhnd_nvram_tlv *tlv = (struct bhnd_nvram_tlv *)nv; if (tlv->data != NULL) bhnd_nvram_io_free(tlv->data); } size_t bhnd_nvram_tlv_count(struct bhnd_nvram_data *nv) { struct bhnd_nvram_tlv *tlv = (struct bhnd_nvram_tlv *)nv; return (tlv->count); } + static bhnd_nvram_plist * bhnd_nvram_tlv_options(struct bhnd_nvram_data *nv) { return (NULL); -} - -static int -bhnd_nvram_tlv_size(struct bhnd_nvram_data *nv, size_t *size) -{ - /* Let the serialization implementation calculate the length */ - return (bhnd_nvram_data_serialize(nv, NULL, size)); -} - -static int -bhnd_nvram_tlv_serialize(struct bhnd_nvram_data *nv, void *buf, size_t *len) -{ - struct bhnd_nvram_tlv *tlv; - size_t limit; - size_t next; - uint8_t tag; - int error; - - tlv = (struct bhnd_nvram_tlv *)nv; - - /* Save the buffer capacity */ - if (buf == NULL) - limit = 0; - else - limit = *len; - - /* Write all of our TLV records to the output buffer (or just - * calculate the buffer size that would be required) */ - next = 0; - do { - struct bhnd_nvram_tlv_env *env; - uint8_t *p; - size_t name_len; - size_t rec_offset, rec_size; - - /* Parse the TLV record */ - error = bhnd_nvram_tlv_next_record(tlv->data, &next, - &rec_offset, &tag); - if (error) - return (error); - - rec_size = next - rec_offset; - - /* Calculate our output pointer */ - if (rec_offset > limit || limit - rec_offset < rec_size) { - /* buffer is full; cannot write */ - p = NULL; - } else { - p = (uint8_t *)buf + rec_offset; - } - - /* If not writing, nothing further to do for this record */ - if (p == NULL) - continue; - - /* Copy to the output buffer */ - error = bhnd_nvram_io_read(tlv->data, rec_offset, p, rec_size); - if (error) - return (error); - - /* All further processing is TLV_ENV-specific */ - if (tag != NVRAM_TLV_TYPE_ENV) - continue; - - /* Restore the original key=value format, rewriting '\0' - * delimiter back to '=' */ - env = (struct bhnd_nvram_tlv_env *)p; - name_len = strlen(env->envp); /* skip variable name */ - *(env->envp + name_len) = '='; /* set '=' */ - } while (tag != NVRAM_TLV_TYPE_END); - - /* The 'next' offset should now point at EOF, and represents - * the total length of the serialized output. */ - *len = next; - - if (buf != NULL && limit < *len) - return (ENOMEM); - - return (0); } static uint32_t bhnd_nvram_tlv_caps(struct bhnd_nvram_data *nv) { return (BHND_NVRAM_DATA_CAP_READ_PTR|BHND_NVRAM_DATA_CAP_DEVPATHS); } static const char * bhnd_nvram_tlv_next(struct bhnd_nvram_data *nv, void **cookiep) { struct bhnd_nvram_tlv *tlv; struct bhnd_nvram_tlv_env *env; size_t io_offset; tlv = (struct bhnd_nvram_tlv *)nv; /* Find next readable TLV record */ if (*cookiep == NULL) { /* Start search at offset 0x0 */ io_offset = 0x0; env = bhnd_nvram_tlv_next_env(tlv, &io_offset, cookiep); } else { /* Seek past the previous env record */ io_offset = bhnd_nvram_tlv_to_offset(tlv, *cookiep); env = bhnd_nvram_tlv_next_env(tlv, &io_offset, NULL); if (env == NULL) BHND_NV_PANIC("invalid cookiep; record missing"); /* Advance to next env record, update the caller's cookiep */ env = bhnd_nvram_tlv_next_env(tlv, &io_offset, cookiep); } /* Check for EOF */ if (env == NULL) return (NULL); /* Return the NUL terminated name */ return (env->envp); } static void * bhnd_nvram_tlv_find(struct bhnd_nvram_data *nv, const char *name) { return (bhnd_nvram_data_generic_find(nv, name)); } static int bhnd_nvram_tlv_getvar_order(struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2) { if (cookiep1 < cookiep2) return (-1); if (cookiep1 > cookiep2) return (1); return (0); } static int bhnd_nvram_tlv_getvar(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type) { return (bhnd_nvram_data_generic_rp_getvar(nv, cookiep, buf, len, type)); } static int bhnd_nvram_tlv_copy_val(struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value) { return (bhnd_nvram_data_generic_rp_copy_val(nv, cookiep, value)); } static const void * bhnd_nvram_tlv_getvar_ptr(struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type) { struct bhnd_nvram_tlv *tlv; struct bhnd_nvram_tlv_env *env; const char *val; int error; tlv = (struct bhnd_nvram_tlv *)nv; /* Fetch pointer to the TLV_ENV record */ if ((env = bhnd_nvram_tlv_get_env(tlv, cookiep)) == NULL) BHND_NV_PANIC("invalid cookiep: %p", cookiep); /* Parse value pointer and length from key\0value data */ error = bhnd_nvram_parse_env(env->envp, NVRAM_TLV_ENVP_DATA_LEN(env), '\0', NULL, NULL, &val, len); if (error) BHND_NV_PANIC("unexpected error parsing '%s'", env->envp); /* Type is always CSTR */ *type = BHND_NVRAM_TYPE_STRING; return (val); } static const char * bhnd_nvram_tlv_getvar_name(struct bhnd_nvram_data *nv, void *cookiep) { struct bhnd_nvram_tlv *tlv; const struct bhnd_nvram_tlv_env *env; tlv = (struct bhnd_nvram_tlv *)nv; /* Fetch pointer to the TLV_ENV record */ if ((env = bhnd_nvram_tlv_get_env(tlv, cookiep)) == NULL) BHND_NV_PANIC("invalid cookiep: %p", cookiep); /* Return name pointer */ return (&env->envp[0]); } static int bhnd_nvram_tlv_filter_setvar(struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result) { bhnd_nvram_val *str; const char *inp; bhnd_nvram_type itype; size_t ilen; size_t name_len, tlv_nremain; int error; tlv_nremain = NVRAM_TLV_ENVP_DATA_MAX_LEN; /* Name (trimmed of any path prefix) must be valid */ if (!bhnd_nvram_validate_name(bhnd_nvram_trim_path_name(name))) return (EINVAL); /* 'name=' must fit within the maximum TLV_ENV record length */ name_len = strlen(name) + 1; /* '=' */ if (tlv_nremain < name_len) { BHND_NV_LOG("'%s=' exceeds maximum TLV_ENV record length\n", name); return (EINVAL); } tlv_nremain -= name_len; /* Convert value to a (bcm-formatted) string */ error = bhnd_nvram_val_convert_new(&str, &bhnd_nvram_val_bcm_string_fmt, value, BHND_NVRAM_VAL_DYNAMIC); if (error) return (error); /* The string value must fit within remaining TLV_ENV record length */ inp = bhnd_nvram_val_bytes(str, &ilen, &itype); if (tlv_nremain < ilen) { BHND_NV_LOG("'%.*s\\0' exceeds maximum TLV_ENV record length\n", BHND_NV_PRINT_WIDTH(ilen), inp); bhnd_nvram_val_release(str); return (EINVAL); } tlv_nremain -= name_len; /* Success. Transfer result ownership to the caller. */ *result = str; return (0); } static int bhnd_nvram_tlv_filter_unsetvar(struct bhnd_nvram_data *nv, const char *name) { /* We permit deletion of any variable */ return (0); } /** * Iterate over the records starting at @p next, returning the parsed * record's @p tag, @p size, and @p offset. * * @param io The I/O context to parse. * @param[in,out] next The next offset to be parsed, or 0x0 * to begin parsing. Upon successful * return, will be set to the offset of the * next record (or EOF, if * NVRAM_TLV_TYPE_END was parsed). * @param[out] offset The record's value offset. * @param[out] tag The record's tag. * * @retval 0 success * @retval EINVAL if parsing @p io as TLV fails. * @retval non-zero if reading @p io otherwise fails, a regular unix error * code will be returned. */ static int bhnd_nvram_tlv_next_record(struct bhnd_nvram_io *io, size_t *next, size_t *offset, uint8_t *tag) { size_t io_offset, io_size; uint16_t parsed_len; uint8_t len_hdr[2]; int error; io_offset = *next; io_size = bhnd_nvram_io_getsize(io); /* Save the record offset */ if (offset != NULL) *offset = io_offset; /* Fetch initial tag */ error = bhnd_nvram_io_read(io, io_offset, tag, sizeof(*tag)); if (error) return (error); io_offset++; /* EOF */ if (*tag == NVRAM_TLV_TYPE_END) { *next = io_offset; return (0); } /* Read length field */ if (*tag & NVRAM_TLV_TF_U8_LEN) { error = bhnd_nvram_io_read(io, io_offset, &len_hdr, sizeof(len_hdr[0])); if (error) { BHND_NV_LOG("error reading TLV record size: %d\n", error); return (error); } parsed_len = len_hdr[0]; io_offset++; } else { error = bhnd_nvram_io_read(io, io_offset, &len_hdr, sizeof(len_hdr)); if (error) { BHND_NV_LOG("error reading 16-bit TLV record " "size: %d\n", error); return (error); } parsed_len = (len_hdr[0] << 8) | len_hdr[1]; io_offset += 2; } /* Advance to next record */ if (parsed_len > io_size || io_size - parsed_len < io_offset) { /* Hit early EOF */ BHND_NV_LOG("TLV record length %hu truncated by input " "size of %zu\n", parsed_len, io_size); return (EINVAL); } *next = io_offset + parsed_len; /* Valid record found */ return (0); } /** * Parse the TLV data in @p io to determine the total size of the TLV * data mapped by @p io (which may be less than the size of @p io). */ static int bhnd_nvram_tlv_parse_size(struct bhnd_nvram_io *io, size_t *size) { size_t next; uint8_t tag; int error; /* We have to perform a minimal parse to determine the actual length */ next = 0x0; *size = 0x0; /* Iterate over the input until we hit END tag or the read fails */ do { error = bhnd_nvram_tlv_next_record(io, &next, NULL, &tag); if (error) return (error); } while (tag != NVRAM_TLV_TYPE_END); /* Offset should now point to EOF */ BHND_NV_ASSERT(next <= bhnd_nvram_io_getsize(io), ("parse returned invalid EOF offset")); *size = next; return (0); } /** * Iterate over the records in @p tlv, returning a pointer to the next * NVRAM_TLV_TYPE_ENV record, or NULL if EOF is reached. * * @param tlv The TLV instance. * @param[in,out] next The next offset to be parsed, or 0x0 * to begin parsing. Upon successful * return, will be set to the offset of the * next record. */ static struct bhnd_nvram_tlv_env * bhnd_nvram_tlv_next_env(struct bhnd_nvram_tlv *tlv, size_t *next, void **cookiep) { uint8_t tag; int error; /* Find the next TLV_ENV record, starting at @p next */ do { void *c; size_t offset; /* Fetch the next TLV record */ error = bhnd_nvram_tlv_next_record(tlv->data, next, &offset, &tag); if (error) { BHND_NV_LOG("unexpected error in next_record(): %d\n", error); return (NULL); } /* Only interested in ENV records */ if (tag != NVRAM_TLV_TYPE_ENV) continue; /* Map and return TLV_ENV record pointer */ c = bhnd_nvram_tlv_to_cookie(tlv, offset); /* Provide the cookiep value for the returned record */ if (cookiep != NULL) *cookiep = c; return (bhnd_nvram_tlv_get_env(tlv, c)); } while (tag != NVRAM_TLV_TYPE_END); /* No remaining ENV records */ return (NULL); } /** * Return a pointer to the TLV_ENV record for @p cookiep, or NULL * if none vailable. */ static struct bhnd_nvram_tlv_env * bhnd_nvram_tlv_get_env(struct bhnd_nvram_tlv *tlv, void *cookiep) { struct bhnd_nvram_tlv_env *env; void *ptr; size_t navail; size_t io_offset, io_size; int error; io_size = bhnd_nvram_io_getsize(tlv->data); io_offset = bhnd_nvram_tlv_to_offset(tlv, cookiep); /* At EOF? */ if (io_offset == io_size) return (NULL); /* Fetch non-const pointer to the record entry */ error = bhnd_nvram_io_write_ptr(tlv->data, io_offset, &ptr, sizeof(env->hdr), &navail); if (error) { /* Should never occur with a valid cookiep */ BHND_NV_LOG("error mapping record for cookiep: %d\n", error); return (NULL); } /* Validate the record pointer */ env = ptr; if (env->hdr.tag != NVRAM_TLV_TYPE_ENV) { /* Should never occur with a valid cookiep */ BHND_NV_LOG("non-ENV record mapped for %p\n", cookiep); return (NULL); } /* Is the required variable name data is mapped? */ if (navail < sizeof(struct bhnd_nvram_tlv_env_hdr) + env->hdr.size || env->hdr.size == sizeof(env->flags)) { /* Should never occur with a valid cookiep */ BHND_NV_LOG("TLV_ENV variable data not mapped for %p\n", cookiep); return (NULL); } return (env); } /** * Return a cookiep for the given I/O offset. */ static void * bhnd_nvram_tlv_to_cookie(struct bhnd_nvram_tlv *tlv, size_t io_offset) { const void *ptr; int error; BHND_NV_ASSERT(io_offset < bhnd_nvram_io_getsize(tlv->data), ("io_offset %zu out-of-range", io_offset)); BHND_NV_ASSERT(io_offset < UINTPTR_MAX, ("io_offset %#zx exceeds UINTPTR_MAX", io_offset)); error = bhnd_nvram_io_read_ptr(tlv->data, 0x0, &ptr, io_offset, NULL); if (error) BHND_NV_PANIC("error mapping offset %zu: %d", io_offset, error); ptr = (const uint8_t *)ptr + io_offset; return (__DECONST(void *, ptr)); } /* Convert a cookiep back to an I/O offset */ static size_t bhnd_nvram_tlv_to_offset(struct bhnd_nvram_tlv *tlv, void *cookiep) { const void *ptr; intptr_t offset; size_t io_size; int error; BHND_NV_ASSERT(cookiep != NULL, ("null cookiep")); io_size = bhnd_nvram_io_getsize(tlv->data); error = bhnd_nvram_io_read_ptr(tlv->data, 0x0, &ptr, io_size, NULL); if (error) BHND_NV_PANIC("error mapping offset %zu: %d", io_size, error); offset = (const uint8_t *)cookiep - (const uint8_t *)ptr; BHND_NV_ASSERT(offset >= 0, ("invalid cookiep")); BHND_NV_ASSERT((uintptr_t)offset < SIZE_MAX, ("cookiep > SIZE_MAX)")); BHND_NV_ASSERT((uintptr_t)offset <= io_size, ("cookiep > io_size)")); return ((size_t)offset); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_datavar.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_datavar.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_datavar.h (revision 310297) @@ -1,224 +1,222 @@ /*- * Copyright (c) 2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_DATAVAR_H_ #define _BHND_NVRAM_BHND_NVRAM_DATAVAR_H_ #include #include #include #include "bhnd_nvram_io.h" #include "bhnd_nvram_data.h" /** Registered NVRAM parser class instances. */ SET_DECLARE(bhnd_nvram_data_class_set, bhnd_nvram_data_class); void *bhnd_nvram_data_generic_find( struct bhnd_nvram_data *nv, const char *name); int bhnd_nvram_data_generic_rp_getvar( struct bhnd_nvram_data *nv, void *cookiep, void *outp, size_t *olen, bhnd_nvram_type otype); int bhnd_nvram_data_generic_rp_copy_val( struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **val); /** @see bhnd_nvram_data_probe() */ typedef int (bhnd_nvram_data_op_probe)(struct bhnd_nvram_io *io); +/** @see bhnd_nvram_data_serialize() */ +typedef int (bhnd_nvram_data_op_serialize)( + bhnd_nvram_data_class *cls, + bhnd_nvram_plist *props, + bhnd_nvram_plist *options, void *outp, + size_t *olen); + /** @see bhnd_nvram_data_new() */ typedef int (bhnd_nvram_data_op_new)(struct bhnd_nvram_data *nv, struct bhnd_nvram_io *io); /** Free all resources associated with @p nv. Called by * bhnd_nvram_data_release() when the reference count reaches zero. */ typedef void (bhnd_nvram_data_op_free)(struct bhnd_nvram_data *nv); /** @see bhnd_nvram_data_count() */ typedef size_t (bhnd_nvram_data_op_count)(struct bhnd_nvram_data *nv); -/** @see bhnd_nvram_data_size() */ -typedef int (bhnd_nvram_data_op_size)(struct bhnd_nvram_data *nv, - size_t *len); - -/** @see bhnd_nvram_data_serialize() */ -typedef int (bhnd_nvram_data_op_serialize)( - struct bhnd_nvram_data *nv, void *buf, - size_t *len); - /** @see bhnd_nvram_data_options() */ typedef bhnd_nvram_plist*(bhnd_nvram_data_op_options)( struct bhnd_nvram_data *nv); /** @see bhnd_nvram_data_caps() */ typedef uint32_t (bhnd_nvram_data_op_caps)(struct bhnd_nvram_data *nv); /** @see bhnd_nvram_data_next() */ typedef const char *(bhnd_nvram_data_op_next)(struct bhnd_nvram_data *nv, void **cookiep); /** @see bhnd_nvram_data_find() */ typedef void *(bhnd_nvram_data_op_find)(struct bhnd_nvram_data *nv, const char *name); /** @see bhnd_nvram_data_copy_val() */ typedef int (bhnd_nvram_data_op_copy_val)( struct bhnd_nvram_data *nv, void *cookiep, bhnd_nvram_val **value); /** @see bhnd_nvram_data_getvar_order() */ typedef int (bhnd_nvram_data_op_getvar_order)( struct bhnd_nvram_data *nv, void *cookiep1, void *cookiep2); /** @see bhnd_nvram_data_getvar_name() */ typedef const char *(bhnd_nvram_data_op_getvar_name)( struct bhnd_nvram_data *nv, void *cookiep); /** @see bhnd_nvram_data_getvar() */ typedef int (bhnd_nvram_data_op_getvar)(struct bhnd_nvram_data *nv, void *cookiep, void *buf, size_t *len, bhnd_nvram_type type); /** @see bhnd_nvram_data_getvar_ptr() */ typedef const void *(bhnd_nvram_data_op_getvar_ptr)( struct bhnd_nvram_data *nv, void *cookiep, size_t *len, bhnd_nvram_type *type); /** @see bhnd_nvram_data_filter_setvar() */ typedef int (bhnd_nvram_data_op_filter_setvar)( struct bhnd_nvram_data *nv, const char *name, bhnd_nvram_val *value, bhnd_nvram_val **result); /** @see bhnd_nvram_data_filter_unsetvar() */ typedef int (bhnd_nvram_data_op_filter_unsetvar)( struct bhnd_nvram_data *nv, const char *name); /** * NVRAM data class. */ struct bhnd_nvram_data_class { const char *desc; /**< description */ + uint32_t caps; /**< capabilities (BHND_NVRAM_DATA_CAP_*) */ size_t size; /**< instance size */ bhnd_nvram_data_op_probe *op_probe; + bhnd_nvram_data_op_serialize *op_serialize; bhnd_nvram_data_op_new *op_new; bhnd_nvram_data_op_free *op_free; bhnd_nvram_data_op_count *op_count; - bhnd_nvram_data_op_size *op_size; - bhnd_nvram_data_op_serialize *op_serialize; bhnd_nvram_data_op_options *op_options; bhnd_nvram_data_op_caps *op_caps; bhnd_nvram_data_op_next *op_next; bhnd_nvram_data_op_find *op_find; bhnd_nvram_data_op_copy_val *op_copy_val; bhnd_nvram_data_op_getvar_order *op_getvar_order; bhnd_nvram_data_op_getvar *op_getvar; bhnd_nvram_data_op_getvar_ptr *op_getvar_ptr; bhnd_nvram_data_op_getvar_name *op_getvar_name; bhnd_nvram_data_op_filter_setvar *op_filter_setvar; bhnd_nvram_data_op_filter_unsetvar *op_filter_unsetvar; }; /** * NVRAM data instance. */ struct bhnd_nvram_data { struct bhnd_nvram_data_class *cls; volatile u_int refs; }; /* * Helper macro for BHND_NVRAM_DATA_CLASS_DEFN(). * * Declares a bhnd_nvram_data_class method implementation with class name * _cname and method name _mname */ #define BHND_NVRAM_DATA_CLASS_DECL_METHOD(_cname, _mname) \ static bhnd_nvram_data_op_ ## _mname \ bhnd_nvram_ ## _cname ## _ ## _mname; \ /* * Helper macro for BHND_NVRAM_DATA_CLASS_DEFN(). * * Assign a bhnd_nvram_data_class method implementation with class name * @p _cname and method name @p _mname */ #define BHND_NVRAM_DATA_CLASS_ASSIGN_METHOD(_cname, _mname) \ .op_ ## _mname = bhnd_nvram_ ## _cname ## _ ## _mname, /* * Helper macro for BHND_NVRAM_DATA_CLASS_DEFN(). * * Iterate over all bhnd_nvram_data_class method names, calling * _macro with the class name _cname as the first argument, and * a bhnd_nvram_data_class method name as the second. */ #define BHND_NVRAM_DATA_CLASS_ITER_METHODS(_cname, _macro) \ _macro(_cname, probe) \ + _macro(_cname, serialize) \ _macro(_cname, new) \ _macro(_cname, free) \ _macro(_cname, count) \ - _macro(_cname, size) \ - _macro(_cname, serialize) \ _macro(_cname, options) \ _macro(_cname, caps) \ _macro(_cname, next) \ _macro(_cname, find) \ _macro(_cname, copy_val) \ _macro(_cname, getvar_order) \ _macro(_cname, getvar) \ _macro(_cname, getvar_ptr) \ _macro(_cname, getvar_name) \ _macro(_cname, filter_setvar) \ _macro(_cname, filter_unsetvar) /** * Define a bhnd_nvram_data_class with class name @p _n and description * @p _desc, and register with bhnd_nvram_data_class_set. */ -#define BHND_NVRAM_DATA_CLASS_DEFN(_cname, _desc, _size) \ +#define BHND_NVRAM_DATA_CLASS_DEFN(_cname, _desc, _caps, _size) \ BHND_NVRAM_DATA_CLASS_ITER_METHODS(_cname, \ BHND_NVRAM_DATA_CLASS_DECL_METHOD) \ \ struct bhnd_nvram_data_class bhnd_nvram_## _cname ## _class = { \ .desc = (_desc), \ + .caps = (_caps), \ .size = (_size), \ BHND_NVRAM_DATA_CLASS_ITER_METHODS(_cname, \ BHND_NVRAM_DATA_CLASS_ASSIGN_METHOD) \ }; \ \ DATA_SET(bhnd_nvram_data_class_set, \ bhnd_nvram_## _cname ## _class); #endif /* _BHND_NVRAM_BHND_NVRAM_DATAVAR_H_ */ Index: head/sys/dev/bhnd/nvram/bhnd_nvram_private.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_private.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_private.h (revision 310297) @@ -1,458 +1,459 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_ #define _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_ /* * Private BHND NVRAM definitions. */ #include #ifdef _KERNEL #include #include #else #include #include #include #include #endif #include "bhnd_nvram.h" #include "bhnd_nvram_value.h" /* * bhnd_nvram_crc8() lookup table. */ extern const uint8_t bhnd_nvram_crc8_tab[]; /* Forward declarations */ struct bhnd_nvram_vardefn; #ifdef _KERNEL MALLOC_DECLARE(M_BHND_NVRAM); #define bhnd_nv_isupper(c) isupper(c) #define bhnd_nv_islower(c) islower(c) #define bhnd_nv_isalpha(c) isalpha(c) #define bhnd_nv_isprint(c) isprint(c) #define bhnd_nv_isspace(c) isspace(c) #define bhnd_nv_isdigit(c) isdigit(c) #define bhnd_nv_isxdigit(c) isxdigit(c) #define bhnd_nv_toupper(c) toupper(c) #define bhnd_nv_malloc(size) malloc((size), M_BHND_NVRAM, M_NOWAIT) #define bhnd_nv_calloc(n, size) malloc((n) * (size), M_BHND_NVRAM, \ M_NOWAIT | M_ZERO) #define bhnd_nv_reallocf(buf, size) reallocf((buf), (size), M_BHND_NVRAM, \ M_NOWAIT) #define bhnd_nv_free(buf) free((buf), M_BHND_NVRAM) #define bhnd_nv_asprintf(buf, fmt, ...) asprintf((buf), M_BHND_NVRAM, \ fmt, ## __VA_ARGS__) /* We need our own strdup() implementation to pass required M_NOWAIT */ static inline char * bhnd_nv_strdup(const char *str) { char *dest; size_t len; len = strlen(str); dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT); memcpy(dest, str, len); dest[len] = '\0'; return (dest); } /* We need our own strndup() implementation to pass required M_NOWAIT */ static inline char * bhnd_nv_strndup(const char *str, size_t len) { char *dest; len = strnlen(str, len); dest = malloc(len + 1, M_BHND_NVRAM, M_NOWAIT); memcpy(dest, str, len); dest[len] = '\0'; return (dest); } #ifdef INVARIANTS #define BHND_NV_INVARIANTS #endif #define BHND_NV_ASSERT(expr, ...) KASSERT(expr, __VA_ARGS__) #define BHND_NV_VERBOSE (bootverbose) #define BHND_NV_PANIC(...) panic(__VA_ARGS__) #define BHND_NV_LOG(fmt, ...) \ printf("%s: " fmt, __FUNCTION__, ##__VA_ARGS__) #define bhnd_nv_ummax(a, b) ummax((a), (b)) #define bhnd_nv_ummin(a, b) ummin((a), (b)) #else /* !_KERNEL */ #include #include #include #include /* ASCII-specific ctype variants that work consistently regardless * of current locale */ #define bhnd_nv_isupper(c) ((c) >= 'A' && (c) <= 'Z') #define bhnd_nv_islower(c) ((c) >= 'a' && (c) <= 'z') #define bhnd_nv_isalpha(c) (bhnd_nv_isupper(c) || bhnd_nv_islower(c)) #define bhnd_nv_isprint(c) ((c) >= ' ' && (c) <= '~') #define bhnd_nv_isspace(c) ((c) == ' ' || ((c) >= '\t' && (c) <= '\r')) #define bhnd_nv_isdigit(c) isdigit(c) #define bhnd_nv_isxdigit(c) isxdigit(c) #define bhnd_nv_toupper(c) ((c) - \ (('a' - 'A') * ((c) >= 'a' && (c) <= 'z'))) #define bhnd_nv_malloc(size) malloc((size)) #define bhnd_nv_calloc(n, size) calloc((n), (size)) #define bhnd_nv_reallocf(buf, size) reallocf((buf), (size)) #define bhnd_nv_free(buf) free((buf)) #define bhnd_nv_strdup(str) strdup(str) #define bhnd_nv_strndup(str, len) strndup(str, len) #define bhnd_nv_asprintf(buf, fmt, ...) asprintf((buf), fmt, ## __VA_ARGS__) #ifndef NDEBUG #define BHND_NV_INVARIANTS #endif #ifdef BHND_NV_INVARIANTS #define BHND_NV_ASSERT(expr, msg) do { \ if (!(expr)) { \ fprintf(stderr, "Assertion failed: %s, function %s, " \ "file %s, line %u\n", __STRING(expr), __FUNCTION__, \ __FILE__, __LINE__); \ BHND_NV_PANIC msg; \ } \ } while(0) #else /* !BHND_NV_INVARIANTS */ #define BHND_NV_ASSERT(expr, msg) #endif /* BHND_NV_INVARIANTS */ #define BHND_NV_VERBOSE (0) #define BHND_NV_PANIC(fmt, ...) do { \ fprintf(stderr, "panic: " fmt "\n", ##__VA_ARGS__); \ abort(); \ } while(0) #define BHND_NV_LOG(fmt, ...) \ fprintf(stderr, "%s: " fmt, __FUNCTION__, ##__VA_ARGS__) static inline uintmax_t bhnd_nv_ummax(uintmax_t a, uintmax_t b) { return (a > b ? a : b); } static inline uintmax_t bhnd_nv_ummin(uintmax_t a, uintmax_t b) { return (a < b ? a : b); } #endif /* _KERNEL */ #ifdef BHND_NV_VERBOSE #define BHND_NV_DEBUG(...) BHND_NV_LOG(__VA_ARGS__) #else /* !BHND_NV_VERBOSE */ #define BHND_NV_DEBUG(...) #endif /* BHND_NV_VERBOSE */ /* Limit a size_t value to a suitable range for use as a printf string field * width */ #define BHND_NV_PRINT_WIDTH(_len) \ ((_len) > (INT_MAX) ? (INT_MAX) : (int)(_len)) int bhnd_nvram_value_coerce(const void *inp, size_t ilen, bhnd_nvram_type itype, void *outp, size_t *olen, bhnd_nvram_type otype); int bhnd_nvram_value_check_aligned(const void *inp, size_t ilen, bhnd_nvram_type itype); int bhnd_nvram_value_nelem(const void *inp, size_t ilen, bhnd_nvram_type itype, size_t *nelem); size_t bhnd_nvram_value_size(const void *inp, size_t ilen, bhnd_nvram_type itype, size_t nelem); int bhnd_nvram_value_printf(const char *fmt, const void *inp, size_t ilen, bhnd_nvram_type itype, char *outp, size_t *olen, ...); int bhnd_nvram_value_vprintf(const char *fmt, const void *inp, size_t ilen, bhnd_nvram_type itype, char *outp, size_t *olen, va_list ap); const void *bhnd_nvram_value_array_next(const void *inp, size_t ilen, bhnd_nvram_type itype, const void *prev, size_t *olen); const struct bhnd_nvram_vardefn *bhnd_nvram_find_vardefn(const char *varname); const struct bhnd_nvram_vardefn *bhnd_nvram_get_vardefn(size_t id); size_t bhnd_nvram_get_vardefn_id( const struct bhnd_nvram_vardefn *defn); int bhnd_nvram_parse_int(const char *s, size_t maxlen, u_int base, size_t *nbytes, void *outp, size_t *olen, bhnd_nvram_type otype); int bhnd_nvram_parse_env(const char *env, size_t env_len, char delim, const char **name, size_t *name_len, const char **value, size_t *value_len); size_t bhnd_nvram_parse_field(const char **inp, size_t ilen, char delim); size_t bhnd_nvram_trim_field(const char **inp, size_t ilen, char delim); const char *bhnd_nvram_trim_path_name(const char *name); bool bhnd_nvram_validate_name(const char *name); /** * Calculate CRC-8 over @p buf using the Broadcom SPROM/NVRAM CRC-8 * polynomial. * * @param buf input buffer * @param size buffer size * @param crc last computed crc, or BHND_NVRAM_CRC8_INITIAL */ static inline uint8_t bhnd_nvram_crc8(const void *buf, size_t size, uint8_t crc) { const uint8_t *p = (const uint8_t *)buf; while (size--) crc = bhnd_nvram_crc8_tab[(crc ^ *p++)]; return (crc); } #define BHND_NVRAM_CRC8_INITIAL 0xFF /**< Initial bhnd_nvram_crc8 value */ #define BHND_NVRAM_CRC8_VALID 0x9F /**< Valid CRC-8 checksum */ /** NVRAM variable flags */ enum { BHND_NVRAM_VF_MFGINT = 1<<0, /**< mfg-internal variable; should not be externally visible */ BHND_NVRAM_VF_IGNALL1 = 1<<1 /**< hide variable if its value has all bits set. */ }; /** * SPROM layout flags */ enum { /** * SPROM layout does not have magic identification value. * * This applies to SPROM revisions 1-3, where the actual * layout must be determined by looking for a matching sromrev * at the expected offset, and then verifying the CRC to ensure * that the match was not a false positive. */ SPROM_LAYOUT_MAGIC_NONE = (1<<0), }; /** NVRAM variable definition */ struct bhnd_nvram_vardefn { const char *name; /**< variable name */ const char *desc; /**< human readable description, or NULL */ const char *help; /**< human readable help text, or NULL */ bhnd_nvram_type type; /**< variable type */ uint8_t nelem; /**< element count, or 1 if not an array-typed variable */ - const bhnd_nvram_val_fmt *fmt; /**< value format, or NULL */ + const bhnd_nvram_val_fmt *fmt; /**< value format */ uint32_t flags; /**< flags (BHND_NVRAM_VF_*) */ }; /* * NVRAM variable definitions generated from nvram_map. */ extern const struct bhnd_nvram_vardefn bhnd_nvram_vardefns[]; extern const size_t bhnd_nvram_num_vardefns; /** * SPROM layout descriptor. */ -struct bhnd_sprom_layout { +typedef struct bhnd_sprom_layout { size_t size; /**< SPROM image size, in bytes */ uint8_t rev; /**< SPROM revision */ uint8_t flags; /**< layout flags (SPROM_LAYOUT_*) */ size_t srev_offset; /**< offset to SROM revision */ size_t magic_offset; /**< offset to magic value */ uint16_t magic_value; /**< expected magic value */ + size_t crc_offset; /**< offset to crc8 value */ const uint8_t *bindings; /**< SPROM binding opcode table */ size_t bindings_size; /**< SPROM binding opcode table size */ uint16_t num_vars; /**< total number of variables defined for this layout by the binding table */ -}; +} bhnd_sprom_layout; /* * SPROM layout descriptions generated from nvram_map. */ extern const struct bhnd_sprom_layout bhnd_sprom_layouts[]; extern const size_t bhnd_sprom_num_layouts; /* * SPROM binding opcodes. * * Most opcodes are provided with two variants: * * - Standard: The opcode's data directly follows the opcode. The data type * (SPROM_OPCODE_DATA_*) is encoded in the opcode immediate (IMM). * - Immediate: The opcode's data is encoded directly in the opcode immediate * (IMM). */ #define SPROM_OPC_MASK 0xF0 /**< operation mask */ #define SPROM_IMM_MASK 0x0F /**< immediate value mask */ #define SPROM_IMM_MAX SPROM_IMM_MASK #define SPROM_OP_DATA_U8 0x00 /**< data is u8 */ #define SPROM_OP_DATA_U8_SCALED 0x01 /**< data is u8; multiply by type width */ #define SPROM_OP_DATA_U16 0x02 /**< data is u16-le */ #define SPROM_OP_DATA_U32 0x03 /**< data is u32-le */ #define SPROM_OP_DATA_I8 0x04 /**< data is i8 */ #define SPROM_OPCODE_EXT 0x00 /**< extended opcodes defined in IMM */ #define SPROM_OPCODE_EOF 0x00 /**< marks end of opcode stream */ #define SPROM_OPCODE_NELEM 0x01 /**< variable array element count follows as U8 */ #define SPROM_OPCODE_VAR_END 0x02 /**< marks end of variable definition */ #define SPROM_OPCODE_TYPE 0x03 /**< input type follows as U8 (see BHND_NVRAM_TYPE_*) */ #define SPROM_OPCODE_VAR_IMM 0x10 /**< variable ID (imm) */ #define SPROM_OPCODE_VAR_REL_IMM 0x20 /**< relative variable ID (last ID + imm) */ #define SPROM_OPCODE_VAR 0x30 /**< variable ID */ #define SPROM_OPCODE_REV_IMM 0x40 /**< revision range (imm) */ #define SPROM_OPCODE_REV_RANGE 0x50 /**< revision range (8-bit range)*/ #define SPROM_OP_REV_RANGE_MAX 0x0F /**< maximum representable SROM revision */ #define SPROM_OP_REV_START_MASK 0xF0 #define SPROM_OP_REV_START_SHIFT 4 #define SPROM_OP_REV_END_MASK 0x0F #define SPROM_OP_REV_END_SHIFT 0 #define SPROM_OPCODE_MASK_IMM 0x60 /**< value mask (imm) */ #define SPROM_OPCODE_MASK 0x70 /**< value mask */ #define SPROM_OPCODE_SHIFT_IMM 0x80 /**< value shift (unsigned imm, multipled by 2) */ #define SPROM_OPCODE_SHIFT 0x90 /**< value shift */ #define SPROM_OPCODE_OFFSET_REL_IMM 0xA0 /**< relative input offset (last offset + (imm * type width)) */ #define SPROM_OPCODE_OFFSET 0xB0 /**< input offset */ #define SPROM_OPCODE_TYPE_IMM 0xC0 /**< input type (imm, see BHND_NVRAM_TYPE_*) */ #define SPROM_OPCODE_DO_BIND 0xD0 /**< bind current value, advance input/output offsets as per IMM */ #define SPROM_OP_BIND_SKIP_IN_MASK 0x03 /**< the number of input elements to advance after the bind */ #define SPROM_OP_BIND_SKIP_IN_SHIFT 0 #define SPROM_OP_BIND_SKIP_IN_SIGN (1<<2) /**< SKIP_IN sign bit */ #define SPROM_OP_BIND_SKIP_OUT_MASK 0x08 /**< the number of output elements to advance after the bind */ #define SPROM_OP_BIND_SKIP_OUT_SHIFT 3 #define SPROM_OPCODE_DO_BINDN_IMM 0xE0 /**< bind IMM times, advancing input/output offsets by one element each time */ #define SPROM_OPCODE_DO_BINDN 0xF0 /**< bind N times, advancing input/output offsets as per SPROM_OP_BIND_SKIP_IN/SPROM_OP_BIND_SKIP_OUT IMM values. The U8 element count follows. */ /** Evaluates to true if opcode is an extended opcode */ #define SPROM_OPCODE_IS_EXT(_opcode) \ (((_opcode) & SPROM_OPC_MASK) == SPROM_OPCODE_EXT) /** Return the opcode constant for a simple or extended opcode */ #define SPROM_OPCODE_OP(_opcode) \ (SPROM_OPCODE_IS_EXT(_opcode) ? (_opcode) : ((_opcode) & SPROM_OPC_MASK)) /** Return the opcode immediate for a simple opcode, or zero if this is * an extended opcode */ #define SPROM_OPCODE_IMM(_opcode) \ (SPROM_OPCODE_IS_EXT(_opcode) ? 0 : ((_opcode) & SPROM_IMM_MASK)) /** Evaluates to true if the given opcode produces an implicit * SPROM_OPCODE_VAR_END instruction for any open variable */ #define SPROM_OP_IS_IMPLICIT_VAR_END(_opcode) \ (((_opcode) == SPROM_OPCODE_VAR_IMM) || \ ((_opcode) == SPROM_OPCODE_VAR_REL_IMM) || \ ((_opcode) == SPROM_OPCODE_VAR) || \ ((_opcode) == SPROM_OPCODE_REV_IMM) || \ ((_opcode) == SPROM_OPCODE_REV_RANGE)) /** Evaluates to true if the given opcode is either an explicit * SPROM_OPCODE_VAR_END instruction, or is an opcode that produces an * implicit terminatation of any open variable */ #define SPROM_OP_IS_VAR_END(_opcode) \ (((_opcode) == SPROM_OPCODE_VAR_END) || \ SPROM_OP_IS_IMPLICIT_VAR_END(_opcode)) /** maximum representable immediate value */ #define SPROM_OP_IMM_MAX SPROM_IMM_MASK /** maximum representable SROM revision */ #define SPROM_OP_REV_MAX MAX(SPROM_OP_REV_RANGE_MAX, SPROM_IMM_MAX) #endif /* _BHND_NVRAM_BHND_NVRAM_PRIVATE_H_ */ Index: head/sys/dev/bhnd/nvram/bhnd_nvram_store.c =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_store.c (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_store.c (revision 310297) @@ -1,1184 +1,1268 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. */ #include __FBSDID("$FreeBSD$"); #include #include #include #ifdef _KERNEL #include #include #include #else /* !_KERNEL */ #include #include #include #include #include #include #include #include #endif /* _KERNEL */ #include "bhnd_nvram_private.h" #include "bhnd_nvram_datavar.h" #include "bhnd_nvram_storevar.h" /* * BHND NVRAM Store * * Manages in-memory and persistent representations of NVRAM data. */ static int bhnd_nvstore_parse_data( struct bhnd_nvram_store *sc); static int bhnd_nvstore_parse_path_entries( struct bhnd_nvram_store *sc); static int bhnd_nvram_store_export_child( struct bhnd_nvram_store *sc, bhnd_nvstore_path *top, bhnd_nvstore_path *child, bhnd_nvram_plist *plist, uint32_t flags); static int bhnd_nvstore_export_merge( struct bhnd_nvram_store *sc, bhnd_nvstore_path *path, bhnd_nvram_plist *merged, uint32_t flags); static int bhnd_nvstore_export_devpath_alias( struct bhnd_nvram_store *sc, bhnd_nvstore_path *path, const char *devpath, bhnd_nvram_plist *plist, u_long *alias_val); /** * Allocate and initialize a new NVRAM data store instance. * * The caller is responsible for deallocating the instance via * bhnd_nvram_store_free(). * * @param[out] store On success, a pointer to the newly allocated NVRAM data * instance. * @param data The NVRAM data to be managed by the returned NVRAM data store * instance. * * @retval 0 success * @retval non-zero if an error occurs during allocation or initialization, a * regular unix error code will be returned. */ int bhnd_nvram_store_new(struct bhnd_nvram_store **store, struct bhnd_nvram_data *data) { struct bhnd_nvram_store *sc; int error; /* Allocate new instance */ sc = bhnd_nv_calloc(1, sizeof(*sc)); if (sc == NULL) return (ENOMEM); BHND_NVSTORE_LOCK_INIT(sc); BHND_NVSTORE_LOCK(sc); /* Initialize path hash table */ sc->num_paths = 0; for (size_t i = 0; i < nitems(sc->paths); i++) LIST_INIT(&sc->paths[i]); /* Initialize alias hash table */ sc->num_aliases = 0; for (size_t i = 0; i < nitems(sc->aliases); i++) LIST_INIT(&sc->aliases[i]); /* Retain the NVRAM data */ sc->data = bhnd_nvram_data_retain(data); sc->data_caps = bhnd_nvram_data_caps(data); sc->data_opts = bhnd_nvram_data_options(data); if (sc->data_opts != NULL) { bhnd_nvram_plist_retain(sc->data_opts); } else { sc->data_opts = bhnd_nvram_plist_new(); if (sc->data_opts == NULL) { error = ENOMEM; goto cleanup; } } /* Register required root path */ error = bhnd_nvstore_register_path(sc, BHND_NVSTORE_ROOT_PATH, BHND_NVSTORE_ROOT_PATH_LEN); if (error) goto cleanup; sc->root_path = bhnd_nvstore_get_path(sc, BHND_NVSTORE_ROOT_PATH, BHND_NVSTORE_ROOT_PATH_LEN); BHND_NV_ASSERT(sc->root_path, ("missing root path")); /* Parse all variables vended by our backing NVRAM data instance, * generating all path entries, alias entries, and variable indexes */ if ((error = bhnd_nvstore_parse_data(sc))) goto cleanup; *store = sc; BHND_NVSTORE_UNLOCK(sc); return (0); cleanup: BHND_NVSTORE_UNLOCK(sc); bhnd_nvram_store_free(sc); return (error); } /** * Allocate and initialize a new NVRAM data store instance, parsing the * NVRAM data from @p io. * * The caller is responsible for deallocating the instance via * bhnd_nvram_store_free(). * * The NVRAM data mapped by @p io will be copied, and @p io may be safely * deallocated after bhnd_nvram_store_new() returns. * * @param[out] store On success, a pointer to the newly allocated NVRAM data * instance. * @param io An I/O context mapping the NVRAM data to be copied and parsed. * @param cls The NVRAM data class to be used when parsing @p io, or NULL * to perform runtime identification of the appropriate data class. * * @retval 0 success * @retval non-zero if an error occurs during allocation or initialization, a * regular unix error code will be returned. */ int bhnd_nvram_store_parse_new(struct bhnd_nvram_store **store, struct bhnd_nvram_io *io, bhnd_nvram_data_class *cls) { struct bhnd_nvram_data *data; int error; /* Try to parse the data */ if ((error = bhnd_nvram_data_new(cls, &data, io))) return (error); /* Try to create our new store instance */ error = bhnd_nvram_store_new(store, data); bhnd_nvram_data_release(data); return (error); } /** * Free an NVRAM store instance, releasing all associated resources. * * @param sc A store instance previously allocated via * bhnd_nvram_store_new(). */ void bhnd_nvram_store_free(struct bhnd_nvram_store *sc) { /* Clean up alias hash table */ for (size_t i = 0; i < nitems(sc->aliases); i++) { bhnd_nvstore_alias *alias, *anext; LIST_FOREACH_SAFE(alias, &sc->aliases[i], na_link, anext) bhnd_nv_free(alias); } /* Clean up path hash table */ for (size_t i = 0; i < nitems(sc->paths); i++) { bhnd_nvstore_path *path, *pnext; LIST_FOREACH_SAFE(path, &sc->paths[i], np_link, pnext) bhnd_nvstore_path_free(path); } if (sc->data != NULL) bhnd_nvram_data_release(sc->data); if (sc->data_opts != NULL) bhnd_nvram_plist_release(sc->data_opts); BHND_NVSTORE_LOCK_DESTROY(sc); bhnd_nv_free(sc); } /** * Parse all variables vended by our backing NVRAM data instance, * generating all path entries, alias entries, and variable indexes. * * @param sc The NVRAM store instance to be initialized with * paths, aliases, and data parsed from its backing * data. * * @retval 0 success * @retval non-zero if an error occurs during parsing, a regular unix error * code will be returned. */ static int bhnd_nvstore_parse_data(struct bhnd_nvram_store *sc) { const char *name; void *cookiep; int error; /* Parse and register all device paths and path aliases. This enables * resolution of _forward_ references to device paths aliases when * scanning variable entries below */ if ((error = bhnd_nvstore_parse_path_entries(sc))) return (error); /* Calculate the per-path variable counts, and report dangling alias * references as an error. */ cookiep = NULL; while ((name = bhnd_nvram_data_next(sc->data, &cookiep))) { bhnd_nvstore_path *path; bhnd_nvstore_name_info info; /* Parse the name info */ error = bhnd_nvstore_parse_name_info(name, BHND_NVSTORE_NAME_INTERNAL, sc->data_caps, &info); if (error) return (error); switch (info.type) { case BHND_NVSTORE_VAR: /* Fetch referenced path */ path = bhnd_nvstore_var_get_path(sc, &info); if (path == NULL) { BHND_NV_LOG("variable '%s' has dangling " "path reference\n", name); return (EFTYPE); } /* Increment path variable count */ if (path->num_vars == SIZE_MAX) { BHND_NV_LOG("more than SIZE_MAX variables in " "path %s\n", path->path_str); return (EFTYPE); } path->num_vars++; break; case BHND_NVSTORE_ALIAS_DECL: /* Skip -- path alias already parsed and recorded */ break; } } /* If the backing NVRAM data instance vends only a single root ("/") * path, we may be able to skip generating an index for the root * path */ if (sc->num_paths == 1) { bhnd_nvstore_path *path; /* If the backing instance provides its own name-based lookup * indexing, we can skip generating a duplicate here */ if (sc->data_caps & BHND_NVRAM_DATA_CAP_INDEXED) return (0); /* If the sole root path contains fewer variables than the * minimum indexing threshhold, we do not need to generate an * index */ path = bhnd_nvstore_get_root_path(sc); if (path->num_vars < BHND_NV_IDX_VAR_THRESHOLD) return (0); } /* Allocate per-path index instances */ for (size_t i = 0; i < nitems(sc->paths); i++) { bhnd_nvstore_path *path; LIST_FOREACH(path, &sc->paths[i], np_link) { path->index = bhnd_nvstore_index_new(path->num_vars); if (path->index == NULL) return (ENOMEM); } } /* Populate per-path indexes */ cookiep = NULL; while ((name = bhnd_nvram_data_next(sc->data, &cookiep))) { bhnd_nvstore_name_info info; bhnd_nvstore_path *path; /* Parse the name info */ error = bhnd_nvstore_parse_name_info(name, BHND_NVSTORE_NAME_INTERNAL, sc->data_caps, &info); if (error) return (error); switch (info.type) { case BHND_NVSTORE_VAR: /* Fetch referenced path */ path = bhnd_nvstore_var_get_path(sc, &info); BHND_NV_ASSERT(path != NULL, ("dangling path reference")); /* Append to index */ error = bhnd_nvstore_index_append(sc, path->index, cookiep); if (error) return (error); break; case BHND_NVSTORE_ALIAS_DECL: /* Skip */ break; } } /* Prepare indexes for querying */ for (size_t i = 0; i < nitems(sc->paths); i++) { bhnd_nvstore_path *path; LIST_FOREACH(path, &sc->paths[i], np_link) { error = bhnd_nvstore_index_prepare(sc, path->index); if (error) return (error); } } return (0); } /** * Parse and register path and path alias entries for all declarations found in * the NVRAM data backing @p nvram. * * @param sc The NVRAM store instance. * * @retval 0 success * @retval non-zero If parsing fails, a regular unix error code will be * returned. */ static int bhnd_nvstore_parse_path_entries(struct bhnd_nvram_store *sc) { const char *name; void *cookiep; int error; BHND_NVSTORE_LOCK_ASSERT(sc, MA_OWNED); /* Skip path registration if the data source does not support device * paths. */ if (!(sc->data_caps & BHND_NVRAM_DATA_CAP_DEVPATHS)) { BHND_NV_ASSERT(sc->root_path != NULL, ("missing root path")); return (0); } /* Otherwise, parse and register all paths and path aliases */ cookiep = NULL; while ((name = bhnd_nvram_data_next(sc->data, &cookiep))) { bhnd_nvstore_name_info info; /* Parse the name info */ error = bhnd_nvstore_parse_name_info(name, BHND_NVSTORE_NAME_INTERNAL, sc->data_caps, &info); if (error) return (error); /* Register the path */ error = bhnd_nvstore_var_register_path(sc, &info, cookiep); if (error) { BHND_NV_LOG("failed to register path for %s: %d\n", name, error); return (error); } } return (0); } /** * Merge exported per-path variables (uncommitted, committed, or both) into * the empty @p merged property list. * * @param sc The NVRAM store instance. * @param path The NVRAM path to be exported. * @param merged The property list to populate with the merged results. * @param flags Export flags. See BHND_NVSTORE_EXPORT_*. * * @retval 0 success * @retval ENOMEM If allocation fails. * @retval non-zero If merging the variables defined in @p path otherwise * fails, a regular unix error code will be returned. */ static int bhnd_nvstore_export_merge(struct bhnd_nvram_store *sc, bhnd_nvstore_path *path, bhnd_nvram_plist *merged, uint32_t flags) { void *cookiep, *idxp; int error; /* Populate merged list with all pending variables */ if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_UNCOMMITTED)) { bhnd_nvram_prop *prop; prop = NULL; while ((prop = bhnd_nvram_plist_next(path->pending, prop))) { /* Skip variables marked for deletion */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_DELETED)) { if (bhnd_nvram_prop_is_null(prop)) continue; } /* Append to merged list */ error = bhnd_nvram_plist_append(merged, prop); if (error) return (error); } } /* Skip merging committed variables? */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_COMMITTED)) return (0); /* Merge in the committed NVRAM variables */ idxp = NULL; while ((cookiep = bhnd_nvstore_path_data_next(sc, path, &idxp))) { const char *name; bhnd_nvram_val *val; /* Fetch the variable name */ name = bhnd_nvram_data_getvar_name(sc->data, cookiep); /* Trim device path prefix */ if (sc->data_caps & BHND_NVRAM_DATA_CAP_DEVPATHS) name = bhnd_nvram_trim_path_name(name); /* Skip if already defined in pending updates */ if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_UNCOMMITTED)) { if (bhnd_nvram_plist_contains(path->pending, name)) continue; } /* Skip if higher precedence value was already defined. This * may occur if the underlying data store contains duplicate * keys; iteration will always return the definition with * the highest precedence first */ if (bhnd_nvram_plist_contains(merged, name)) continue; /* Fetch the variable's value representation */ if ((error = bhnd_nvram_data_copy_val(sc->data, cookiep, &val))) return (error); /* Add to path variable list */ error = bhnd_nvram_plist_append_val(merged, name, val); bhnd_nvram_val_release(val); if (error) return (error); } return (0); } /** * Find a free alias value for @p path, and append the devpathXX alias * declaration to @p plist. * * @param sc The NVRAM store instance. * @param path The NVRAM path for which a devpath alias * variable should be produced. * @param devpath The devpathXX path value for @p path. * @param plist The property list to which @p path's devpath * variable will be appended. * @param[out] alias_val On success, will be set to the alias value * allocated for @p path. * * @retval 0 success * @retval ENOMEM If allocation fails. * @retval non-zero If merging the variables defined in @p path otherwise * fails, a regular unix error code will be returned. */ static int bhnd_nvstore_export_devpath_alias(struct bhnd_nvram_store *sc, bhnd_nvstore_path *path, const char *devpath, bhnd_nvram_plist *plist, u_long *alias_val) { bhnd_nvstore_alias *alias; char *pathvar; int error; *alias_val = 0; /* Prefer alias value already reserved for this path. */ alias = bhnd_nvstore_find_alias(sc, path->path_str); if (alias != NULL) { *alias_val = alias->alias; /* Allocate devpathXX variable name */ bhnd_nv_asprintf(&pathvar, "devpath%lu", *alias_val); if (pathvar == NULL) return (ENOMEM); /* Append alias variable to property list */ error = bhnd_nvram_plist_append_string(plist, pathvar, devpath); BHND_NV_ASSERT(error != EEXIST, ("reserved alias %lu:%s in use", * alias_val, path->path_str)); bhnd_nv_free(pathvar); return (error); } /* Find the next free devpathXX alias entry */ while (1) { /* Skip existing reserved alias values */ while (bhnd_nvstore_get_alias(sc, *alias_val) != NULL) { if (*alias_val == ULONG_MAX) return (ENOMEM); (*alias_val)++; } /* Allocate devpathXX variable name */ bhnd_nv_asprintf(&pathvar, "devpath%lu", *alias_val); if (pathvar == NULL) return (ENOMEM); /* If not in-use, we can terminate the search */ if (!bhnd_nvram_plist_contains(plist, pathvar)) break; /* Keep searching */ bhnd_nv_free(pathvar); if (*alias_val == ULONG_MAX) return (ENOMEM); (*alias_val)++; } /* Append alias variable to property list */ error = bhnd_nvram_plist_append_string(plist, pathvar, devpath); bhnd_nv_free(pathvar); return (error); } /** * Export a single @p child path's properties, appending the result to @p plist. * * @param sc The NVRAM store instance. * @param top The root NVRAM path being exported. * @param child The NVRAM path to be exported. * @param plist The property list to which @p child's exported * properties should be appended. * @param flags Export flags. See BHND_NVSTORE_EXPORT_*. * * @retval 0 success * @retval ENOMEM If allocation fails. * @retval non-zero If merging the variables defined in @p path otherwise * fails, a regular unix error code will be returned. */ static int bhnd_nvram_store_export_child(struct bhnd_nvram_store *sc, bhnd_nvstore_path *top, bhnd_nvstore_path *child, bhnd_nvram_plist *plist, uint32_t flags) { bhnd_nvram_plist *path_vars; bhnd_nvram_prop *prop; const char *relpath; char *prefix, *namebuf; size_t prefix_len, relpath_len; size_t namebuf_size, num_props; bool emit_compact_devpath; int error; BHND_NVSTORE_LOCK_ASSERT(sc, MA_OWNED); prefix = NULL; num_props = 0; path_vars = NULL; namebuf = NULL; /* Determine the path relative to the top-level path */ relpath = bhnd_nvstore_parse_relpath(top->path_str, child->path_str); if (relpath == NULL) { /* Skip -- not a child of the root path */ return (0); } relpath_len = strlen(relpath); /* Skip sub-path if export of children was not requested, */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_CHILDREN) && relpath_len > 0) return (0); /* Collect all variables to be included in the export */ if ((path_vars = bhnd_nvram_plist_new()) == NULL) return (ENOMEM); if ((error = bhnd_nvstore_export_merge(sc, child, path_vars, flags))) { bhnd_nvram_plist_release(path_vars); return (error); } /* Skip if no children are to be exported */ if (bhnd_nvram_plist_count(path_vars) == 0) { bhnd_nvram_plist_release(path_vars); return (0); } /* Determine appropriate device path encoding */ emit_compact_devpath = false; if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_COMPACT_DEVPATHS)) { /* Re-encode as compact (if non-empty path) */ if (relpath_len > 0) emit_compact_devpath = true; } else if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_EXPAND_DEVPATHS)) { /* Re-encode with fully expanded device path */ emit_compact_devpath = false; } else if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_PRESERVE_DEVPATHS)) { /* Preserve existing encoding of this path */ if (bhnd_nvstore_find_alias(sc, child->path_str) != NULL) emit_compact_devpath = true; } else { BHND_NV_LOG("invalid device path flag: %#" PRIx32, flags); error = EINVAL; goto finished; } /* Allocate variable device path prefix to use for all property names, * and if using compact encoding, emit the devpathXX= variable */ prefix = NULL; prefix_len = 0; if (emit_compact_devpath) { u_long alias_val; int len; /* Reserve an alias value and append the devpathXX= variable to * the property list */ error = bhnd_nvstore_export_devpath_alias(sc, child, relpath, plist, &alias_val); if (error) goto finished; /* Allocate variable name prefix */ len = bhnd_nv_asprintf(&prefix, "%lu:", alias_val); if (prefix == NULL) { error = ENOMEM; goto finished; } prefix_len = len; } else if (relpath_len > 0) { int len; /* Allocate the variable name prefix, appending '/' to the * relative path */ len = bhnd_nv_asprintf(&prefix, "%s/", relpath); if (prefix == NULL) { error = ENOMEM; goto finished; } prefix_len = len; } /* If prefixing of variable names is required, allocate a name * formatting buffer */ namebuf_size = 0; if (prefix != NULL) { size_t maxlen; /* Find the maximum name length */ maxlen = 0; prop = NULL; while ((prop = bhnd_nvram_plist_next(path_vars, prop))) { const char *name; name = bhnd_nvram_prop_name(prop); maxlen = bhnd_nv_ummax(strlen(name), maxlen); } /* Allocate name buffer (path-prefix + name + '\0') */ namebuf_size = prefix_len + maxlen + 1; namebuf = bhnd_nv_malloc(namebuf_size); if (namebuf == NULL) { error = ENOMEM; goto finished; } } /* Append all path variables to the export plist, prepending the * device-path prefix to the variable names, if required */ prop = NULL; while ((prop = bhnd_nvram_plist_next(path_vars, prop)) != NULL) { const char *name; /* Prepend device prefix to the variable name */ name = bhnd_nvram_prop_name(prop); if (prefix != NULL) { int len; /* * Write prefixed variable name to our name buffer. * * We precalcuate the size when scanning all names * above, so this should always succeed. */ len = snprintf(namebuf, namebuf_size, "%s%s", prefix, name); if (len < 0 || (size_t)len >= namebuf_size) BHND_NV_PANIC("invalid max_name_len"); name = namebuf; } /* Add property to export plist */ error = bhnd_nvram_plist_append_val(plist, name, bhnd_nvram_prop_val(prop)); if (error) goto finished; } /* Success */ error = 0; finished: if (prefix != NULL) bhnd_nv_free(prefix); if (namebuf != NULL) bhnd_nv_free(namebuf); if (path_vars != NULL) bhnd_nvram_plist_release(path_vars); return (error); } /** * Export a flat, ordered NVRAM property list representation of all NVRAM * properties at @p path. * * @param sc The NVRAM store instance. * @param path The NVRAM path to export, or NULL to select the root * path. * @param[out] cls On success, will be set to the backing data class * of @p sc. If the data class is are not desired, * a NULL pointer may be provided. * @param[out] props On success, will be set to a caller-owned property * list containing the exported properties. The caller is * responsible for releasing this value via * bhnd_nvram_plist_release(). * @param[out] options On success, will be set to a caller-owned property * list containing the current NVRAM serialization options * for @p sc. The caller is responsible for releasing this * value via bhnd_nvram_plist_release(). * @param flags Export flags. See BHND_NVSTORE_EXPORT_*. * * @retval 0 success * @retval EINVAL If @p flags is invalid. * @retval ENOENT The requested path was not found. * @retval ENOMEM If allocation fails. * @retval non-zero If export of @p path otherwise fails, a regular unix * error code will be returned. */ int bhnd_nvram_store_export(struct bhnd_nvram_store *sc, const char *path, bhnd_nvram_data_class **cls, bhnd_nvram_plist **props, bhnd_nvram_plist **options, uint32_t flags) { bhnd_nvram_plist *unordered; bhnd_nvstore_path *top; bhnd_nvram_prop *prop; const char *name; void *cookiep; size_t num_dpath_flags; int error; *props = NULL; unordered = NULL; num_dpath_flags = 0; if (options != NULL) *options = NULL; /* Default to exporting root path */ if (path == NULL) path = BHND_NVSTORE_ROOT_PATH; /* Default to exporting all properties */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_COMMITTED) && !BHND_NVSTORE_GET_FLAG(flags, EXPORT_UNCOMMITTED)) { flags |= BHND_NVSTORE_EXPORT_ALL_VARS; } /* Default to preserving the current device path encoding */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_COMPACT_DEVPATHS) && !BHND_NVSTORE_GET_FLAG(flags, EXPORT_EXPAND_DEVPATHS)) { flags |= BHND_NVSTORE_EXPORT_PRESERVE_DEVPATHS; } /* Exactly one device path encoding flag must be set */ if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_COMPACT_DEVPATHS)) num_dpath_flags++; if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_EXPAND_DEVPATHS)) num_dpath_flags++; if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_PRESERVE_DEVPATHS)) num_dpath_flags++; if (num_dpath_flags != 1) return (EINVAL); /* If EXPORT_DELETED is set, EXPORT_UNCOMMITTED must be set too */ if (BHND_NVSTORE_GET_FLAG(flags, EXPORT_DELETED) && !BHND_NVSTORE_GET_FLAG(flags, EXPORT_DELETED)) { return (EINVAL); } /* Lock internal state before querying paths/properties */ BHND_NVSTORE_LOCK(sc); /* Fetch referenced path */ top = bhnd_nvstore_get_path(sc, path, strlen(path)); if (top == NULL) { error = ENOENT; goto failed; } /* Allocate new, empty property list */ if ((unordered = bhnd_nvram_plist_new()) == NULL) { error = ENOMEM; goto failed; } /* Export the top-level path first */ error = bhnd_nvram_store_export_child(sc, top, top, unordered, flags); if (error) goto failed; /* Attempt to export any children of the root path */ for (size_t i = 0; i < nitems(sc->paths); i++) { bhnd_nvstore_path *child; LIST_FOREACH(child, &sc->paths[i], np_link) { /* Top-level path was already exported */ if (child == top) continue; error = bhnd_nvram_store_export_child(sc, top, child, unordered, flags); if (error) goto failed; } } /* If requested, provide the current class and serialization options */ if (cls != NULL) *cls = bhnd_nvram_data_get_class(sc->data); if (options != NULL) *options = bhnd_nvram_plist_retain(sc->data_opts); /* * If we're re-encoding device paths, don't bother preserving the * existing NVRAM variable order; our variable names will not match * the existing backing NVRAM data. */ if (!BHND_NVSTORE_GET_FLAG(flags, EXPORT_PRESERVE_DEVPATHS)) { *props = unordered; unordered = NULL; goto finished; } /* * Re-order the flattened output to match the existing NVRAM variable * ordering. * * We append all new variables at the end of the input; this should * reduce the delta that needs to be written (e.g. to flash) when * committing NVRAM updates, and should result in a serialization * identical to the input serialization if uncommitted updates are * excluded from the export. */ if ((*props = bhnd_nvram_plist_new()) == NULL) { error = ENOMEM; goto failed; } /* Using the backing NVRAM data ordering to order all variables * currently defined in the backing store */ cookiep = NULL; while ((name = bhnd_nvram_data_next(sc->data, &cookiep))) { prop = bhnd_nvram_plist_get_prop(unordered, name); if (prop == NULL) continue; /* Append to ordered result */ if ((error = bhnd_nvram_plist_append(*props, prop))) goto failed; /* Remove from unordered list */ bhnd_nvram_plist_remove(unordered, name); } /* Any remaining variables are new, and should be appended to the * end of the export list */ prop = NULL; while ((prop = bhnd_nvram_plist_next(unordered, prop)) != NULL) { if ((error = bhnd_nvram_plist_append(*props, prop))) goto failed; } /* Export complete */ finished: BHND_NVSTORE_UNLOCK(sc); if (unordered != NULL) bhnd_nvram_plist_release(unordered); return (0); failed: BHND_NVSTORE_UNLOCK(sc); if (unordered != NULL) bhnd_nvram_plist_release(unordered); if (options != NULL && *options != NULL) bhnd_nvram_plist_release(*options); if (*props != NULL) bhnd_nvram_plist_release(*props); return (error); } /** + * Encode all NVRAM properties at @p path, using the @p store's current NVRAM + * data format. + * + * @param sc The NVRAM store instance. + * @param path The NVRAM path to export, or NULL to select the root + * path. + * @param[out] data On success, will be set to the newly serialized value. + * The caller is responsible for freeing this value + * via bhnd_nvram_io_free(). + * @param flags Export flags. See BHND_NVSTORE_EXPORT_*. + * + * @retval 0 success + * @retval EINVAL If @p flags is invalid. + * @retval ENOENT The requested path was not found. + * @retval ENOMEM If allocation fails. + * @retval non-zero If serialization of @p path otherwise fails, a regular + * unix error code will be returned. + */ +int +bhnd_nvram_store_serialize(struct bhnd_nvram_store *sc, const char *path, + struct bhnd_nvram_io **data, uint32_t flags) +{ + bhnd_nvram_plist *props; + bhnd_nvram_plist *options; + bhnd_nvram_data_class *cls; + struct bhnd_nvram_io *io; + void *outp; + size_t olen; + int error; + + props = NULL; + options = NULL; + io = NULL; + + /* Perform requested export */ + error = bhnd_nvram_store_export(sc, path, &cls, &props, &options, + flags); + if (error) + return (error); + + /* Determine serialized size */ + error = bhnd_nvram_data_serialize(cls, props, options, NULL, &olen); + if (error) + goto failed; + + /* Allocate output buffer */ + if ((io = bhnd_nvram_iobuf_empty(olen, olen)) == NULL) { + error = ENOMEM; + goto failed; + } + + /* Fetch write pointer */ + if ((error = bhnd_nvram_io_write_ptr(io, 0, &outp, olen, NULL))) + goto failed; + + /* Perform serialization */ + error = bhnd_nvram_data_serialize(cls, props, options, outp, &olen); + if (error) + goto failed; + + if ((error = bhnd_nvram_io_setsize(io, olen))) + goto failed; + + /* Success */ + bhnd_nvram_plist_release(props); + bhnd_nvram_plist_release(options); + + *data = io; + return (0); + +failed: + if (props != NULL) + bhnd_nvram_plist_release(props); + + if (options != NULL) + bhnd_nvram_plist_release(options); + + if (io != NULL) + bhnd_nvram_io_free(io); + + return (error); +} + +/** * Read an NVRAM variable. * * @param sc The NVRAM parser state. * @param name The NVRAM variable name. * @param[out] outp On success, the requested value will be written * to this buffer. This argment may be NULL if * the value is not desired. * @param[in,out] olen The capacity of @p outp. On success, will be set * to the actual size of the requested value. * @param otype The requested data type to be written to * @p outp. * * @retval 0 success * @retval ENOENT The requested variable was not found. * @retval ENOMEM If @p outp is non-NULL and a buffer of @p olen is too * small to hold the requested value. * @retval non-zero If reading @p name otherwise fails, a regular unix * error code will be returned. */ int bhnd_nvram_store_getvar(struct bhnd_nvram_store *sc, const char *name, void *outp, size_t *olen, bhnd_nvram_type otype) { bhnd_nvstore_name_info info; bhnd_nvstore_path *path; bhnd_nvram_prop *prop; void *cookiep; int error; BHND_NVSTORE_LOCK(sc); /* Parse the variable name */ error = bhnd_nvstore_parse_name_info(name, BHND_NVSTORE_NAME_EXTERNAL, sc->data_caps, &info); if (error) goto finished; /* Fetch the variable's enclosing path entry */ if ((path = bhnd_nvstore_var_get_path(sc, &info)) == NULL) { error = ENOENT; goto finished; } /* Search uncommitted updates first */ prop = bhnd_nvstore_path_get_update(sc, path, info.name); if (prop != NULL) { if (bhnd_nvram_prop_is_null(prop)) { /* NULL denotes a pending deletion */ error = ENOENT; } else { error = bhnd_nvram_prop_encode(prop, outp, olen, otype); } goto finished; } /* Search the backing NVRAM data */ cookiep = bhnd_nvstore_path_data_lookup(sc, path, info.name); if (cookiep != NULL) { /* Found in backing store */ error = bhnd_nvram_data_getvar(sc->data, cookiep, outp, olen, otype); goto finished; } /* Not found */ error = ENOENT; finished: BHND_NVSTORE_UNLOCK(sc); return (error); } /** * Common bhnd_nvram_store_set*() and bhnd_nvram_store_unsetvar() * implementation. * * If @p value is NULL, the variable will be marked for deletion. */ static int bhnd_nvram_store_setval_common(struct bhnd_nvram_store *sc, const char *name, bhnd_nvram_val *value) { bhnd_nvstore_path *path; bhnd_nvstore_name_info info; int error; BHND_NVSTORE_LOCK_ASSERT(sc, MA_OWNED); /* Parse the variable name */ error = bhnd_nvstore_parse_name_info(name, BHND_NVSTORE_NAME_EXTERNAL, sc->data_caps, &info); if (error) return (error); /* Fetch the variable's enclosing path entry */ if ((path = bhnd_nvstore_var_get_path(sc, &info)) == NULL) return (error); /* Register the update entry */ return (bhnd_nvstore_path_register_update(sc, path, info.name, value)); } /** * Set an NVRAM variable. * * @param sc The NVRAM parser state. * @param name The NVRAM variable name. * @param value The new value. * * @retval 0 success * @retval ENOENT The requested variable @p name was not found. * @retval EINVAL If @p value is invalid. */ int bhnd_nvram_store_setval(struct bhnd_nvram_store *sc, const char *name, bhnd_nvram_val *value) { int error; BHND_NVSTORE_LOCK(sc); error = bhnd_nvram_store_setval_common(sc, name, value); BHND_NVSTORE_UNLOCK(sc); return (error); } /** * Set an NVRAM variable. * * @param sc The NVRAM parser state. * @param name The NVRAM variable name. * @param[out] inp The new value. * @param[in,out] ilen The size of @p inp. * @param itype The data type of @p inp. * * @retval 0 success * @retval ENOENT The requested variable @p name was not found. * @retval EINVAL If the new value is invalid. * @retval EINVAL If @p name is read-only. */ int bhnd_nvram_store_setvar(struct bhnd_nvram_store *sc, const char *name, const void *inp, size_t ilen, bhnd_nvram_type itype) { bhnd_nvram_val val; int error; error = bhnd_nvram_val_init(&val, NULL, inp, ilen, itype, BHND_NVRAM_VAL_FIXED|BHND_NVRAM_VAL_BORROW_DATA); if (error) { BHND_NV_LOG("error initializing value: %d\n", error); return (EINVAL); } BHND_NVSTORE_LOCK(sc); error = bhnd_nvram_store_setval_common(sc, name, &val); BHND_NVSTORE_UNLOCK(sc); bhnd_nvram_val_release(&val); return (error); } /** * Unset an NVRAM variable. * * @param sc The NVRAM parser state. * @param name The NVRAM variable name. * * @retval 0 success * @retval ENOENT The requested variable @p name was not found. * @retval EINVAL If @p name is read-only. */ int bhnd_nvram_store_unsetvar(struct bhnd_nvram_store *sc, const char *name) { int error; BHND_NVSTORE_LOCK(sc); error = bhnd_nvram_store_setval_common(sc, name, BHND_NVRAM_VAL_NULL); BHND_NVSTORE_UNLOCK(sc); return (error); } Index: head/sys/dev/bhnd/nvram/bhnd_nvram_store.h =================================================================== --- head/sys/dev/bhnd/nvram/bhnd_nvram_store.h (revision 310296) +++ head/sys/dev/bhnd/nvram/bhnd_nvram_store.h (revision 310297) @@ -1,89 +1,92 @@ /*- * Copyright (c) 2015-2016 Landon Fuller * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer, * without modification. * 2. Redistributions in binary form must reproduce at minimum a disclaimer * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any * redistribution must be conditioned upon including a substantially * similar Disclaimer requirement for further binary redistribution. * * NO WARRANTY * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGES. * * $FreeBSD$ */ #ifndef _BHND_NVRAM_BHND_NVRAM_STORE_H_ #define _BHND_NVRAM_BHND_NVRAM_STORE_H_ #ifdef _KERNEL #include #include #else /* !_KERNEL */ #include #include #include #endif #include #include "bhnd_nvram_data.h" #include "bhnd_nvram_io.h" struct bhnd_nvram_store; /** * NVRAM export flags. */ enum { BHND_NVSTORE_EXPORT_CHILDREN = (1<<0), /**< Include all subpaths */ BHND_NVSTORE_EXPORT_PRESERVE_DEVPATHS = (1<<1), /**< Preserve existing device path definitions (default) */ BHND_NVSTORE_EXPORT_COMPACT_DEVPATHS = (1<<2), /**< Re-encode all device paths using compact syntax */ BHND_NVSTORE_EXPORT_EXPAND_DEVPATHS = (1<<3), /**< Re-encode all device paths using non-compact syntax */ BHND_NVSTORE_EXPORT_ALL_VARS = (1<<6|1<<7), /**< Include all variables (default) */ BHND_NVSTORE_EXPORT_COMMITTED = (1<<6), /**< Include all committed changes */ BHND_NVSTORE_EXPORT_UNCOMMITTED = (1<<7), /**< Include all uncommitted changes (not including deletions) */ BHND_NVSTORE_EXPORT_DELETED = (1<<8), /**< Include all uncommitted deltions (as properties of type BHND_NVRAM_TYPE_NULL) */ }; int bhnd_nvram_store_new(struct bhnd_nvram_store **store, struct bhnd_nvram_data *data); int bhnd_nvram_store_parse_new(struct bhnd_nvram_store **store, struct bhnd_nvram_io *io, bhnd_nvram_data_class *cls); void bhnd_nvram_store_free(struct bhnd_nvram_store *store); int bhnd_nvram_store_export(struct bhnd_nvram_store *store, const char *path, bhnd_nvram_data_class **cls, bhnd_nvram_plist **props, bhnd_nvram_plist **options, uint32_t flags); +int bhnd_nvram_store_serialize(struct bhnd_nvram_store *store, + const char *path, struct bhnd_nvram_io **data, uint32_t flags); + int bhnd_nvram_store_getvar(struct bhnd_nvram_store *sc, const char *name, void *outp, size_t *olen, bhnd_nvram_type otype); int bhnd_nvram_store_setvar(struct bhnd_nvram_store *sc, const char *name, const void *inp, size_t ilen, bhnd_nvram_type itype); int bhnd_nvram_store_unsetvar(struct bhnd_nvram_store *sc, const char *name); int bhnd_nvram_store_setval(struct bhnd_nvram_store *sc, const char *name, bhnd_nvram_val *value); #endif /* _BHND_NVRAM_BHND_NVRAM_STORE_H_ */ Index: head/sys/dev/bhnd/tools/nvram_map_gen.awk =================================================================== --- head/sys/dev/bhnd/tools/nvram_map_gen.awk (revision 310296) +++ head/sys/dev/bhnd/tools/nvram_map_gen.awk (revision 310297) @@ -1,4200 +1,4222 @@ #!/usr/bin/awk -f #- # Copyright (c) 2015-2016 Landon Fuller # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer, # without modification. # 2. Redistributions in binary form must reproduce at minimum a disclaimer # similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any # redistribution must be conditioned upon including a substantially # similar Disclaimer requirement for further binary redistribution. # # NO WARRANTY # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL # THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, # OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER # IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF # THE POSSIBILITY OF SUCH DAMAGES. # # $FreeBSD$ BEGIN { main() } END { at_exit() } # # Print usage # function usage() { print "usage: bhnd_nvram_map.awk [-hd] [-o output file]" _EARLY_EXIT = 1 exit 1 } function main(_i) { RS="\n" OUTPUT_FILE = null # Probe awk implementation's hex digit handling if ("0xA" + 0 != 10) { AWK_REQ_HEX_PARSING=1 } # Seed rand() srand() # Output type OUT_T = null OUT_T_HEADER = "HEADER" OUT_T_DATA = "DATA" # Tab width to use when calculating output alignment TAB_WIDTH = 8 # Enable debug output DEBUG = 0 # Maximum revision REV_MAX = 256 # Parse arguments if (ARGC < 2) usage() for (_i = 1; _i < ARGC; _i++) { if (ARGV[_i] == "--debug") { DEBUG = 1 } else if (ARGV[_i] == "-d" && OUT_T == null) { OUT_T = OUT_T_DATA } else if (ARGV[_i] == "-h" && OUT_T == null) { OUT_T = OUT_T_HEADER } else if (ARGV[_i] == "-o") { _i++ if (_i >= ARGC) usage() OUTPUT_FILE = ARGV[_i] } else if (ARGV[_i] == "--") { _i++ break } else if (ARGV[_i] !~ /^-/) { FILENAME = ARGV[_i] } else { print "unknown option " ARGV[_i] usage() } } ARGC=2 if (OUT_T == null) { print("error: one of -d or -h required") usage() } if (FILENAME == null) { print("error: no input file specified") usage() } if (OUTPUT_FILE == "-") { OUTPUT_FILE = "/dev/stdout" } else if (OUTPUT_FILE == null) { OUTPUT_FILE_IDX = split(FILENAME, _g_output_path, "/") OUTPUT_FILE = _g_output_path[OUTPUT_FILE_IDX] if (OUTPUT_FILE !~ /^bhnd_/) OUTPUT_FILE = "bhnd_" OUTPUT_FILE if (OUT_T == OUT_T_HEADER) OUTPUT_FILE = OUTPUT_FILE ".h" else OUTPUT_FILE = OUTPUT_FILE "_data.h" } # Common Regexs UINT_REGEX = "^(0|[1-9][0-9]*)$" HEX_REGEX = "^(0x[A-Fa-f0-9]+)$" OFF_REGEX = "^(0|[1-9][0-9]*)|^(0x[A-Fa-f0-9]+)" REL_OFF_REGEX = "^\\+(0|[1-9][0-9]*)|^\\+(0x[A-Fa-f0-9]+)" ARRAY_REGEX = "\\[(0|[1-9][0-9]*)\\]" TYPES_REGEX = "^(((u|i)(8|16|32))|char)("ARRAY_REGEX")?$" IDENT_REGEX = "[A-Za-z_][A-Za-z0-9_]*" SVAR_IDENT_REGEX = "^<"IDENT_REGEX">{?$" # identifiers VAR_IDENT_REGEX = "^"IDENT_REGEX"{?$" # var identifiers VACCESS_REGEX = "^(private|internal)$" # Property array keys PROP_ID = "p_id" PROP_NAME = "p_name" # Prop path array keys PPATH_HEAD = "ppath_head" PPATH_TAIL = "ppath_tail" # Object array keys OBJ_IS_CLS = "o_is_cls" OBJ_SUPER = "o_super" OBJ_PROP = "o_prop" # Class array keys CLS_NAME = "cls_name" CLS_PROP = "cls_prop" # C SPROM binding opcodes/opcode flags SPROM_OPCODE_EOF = "SPROM_OPCODE_EOF" SPROM_OPCODE_NELEM = "SPROM_OPCODE_NELEM" SPROM_OPCODE_VAR_END = "SPROM_OPCODE_VAR_END" SPROM_OPCODE_VAR_IMM = "SPROM_OPCODE_VAR_IMM" SPROM_OPCODE_VAR_REL_IMM = "SPROM_OPCODE_VAR_REL_IMM" SPROM_OPCODE_VAR = "SPROM_OPCODE_VAR" SPROM_OPCODE_REV_IMM = "SPROM_OPCODE_REV_IMM" SPROM_OPCODE_REV_RANGE = "SPROM_OPCODE_REV_RANGE" SPROM_OP_REV_START_MASK = "SPROM_OP_REV_START_MASK" SPROM_OP_REV_START_SHIFT = "SPROM_OP_REV_START_SHIFT" SPROM_OP_REV_END_MASK = "SPROM_OP_REV_END_MASK" SPROM_OP_REV_END_SHIFT = "SPROM_OP_REV_END_SHIFT" SPROM_OPCODE_MASK_IMM = "SPROM_OPCODE_MASK_IMM" SPROM_OPCODE_MASK = "SPROM_OPCODE_MASK" SPROM_OPCODE_SHIFT_IMM = "SPROM_OPCODE_SHIFT_IMM" SPROM_OPCODE_SHIFT = "SPROM_OPCODE_SHIFT" SPROM_OPCODE_OFFSET_REL_IMM = "SPROM_OPCODE_OFFSET_REL_IMM" SPROM_OPCODE_OFFSET = "SPROM_OPCODE_OFFSET" SPROM_OPCODE_TYPE = "SPROM_OPCODE_TYPE" SPROM_OPCODE_TYPE_IMM = "SPROM_OPCODE_TYPE_IMM" SPROM_OPCODE_DO_BINDN_IMM = "SPROM_OPCODE_DO_BINDN_IMM" SPROM_OPCODE_DO_BIND = "SPROM_OPCODE_DO_BIND" SPROM_OPCODE_DO_BINDN = "SPROM_OPCODE_DO_BINDN" SPROM_OP_BIND_SKIP_IN_MASK = "SPROM_OP_BIND_SKIP_IN_MASK" SPROM_OP_BIND_SKIP_IN_SHIFT = "SPROM_OP_BIND_SKIP_IN_SHIFT" SPROM_OP_BIND_SKIP_IN_SIGN = "SPROM_OP_BIND_SKIP_IN_SIGN" SPROM_OP_BIND_SKIP_OUT_MASK = "SPROM_OP_BIND_SKIP_OUT_MASK" SPROM_OP_BIND_SKIP_OUT_SHIFT = "SPROM_OP_BIND_SKIP_OUT_SHIFT" SPROM_OP_DATA_U8 = "SPROM_OP_DATA_U8" SPROM_OP_DATA_U8_SCALED = "SPROM_OP_DATA_U8_SCALED" SPROM_OP_DATA_U16 = "SPROM_OP_DATA_U16" SPROM_OP_DATA_U32 = "SPROM_OP_DATA_U32" SPROM_OP_DATA_I8 = "SPROM_OP_DATA_I8" SPROM_OP_BIND_SKIP_IN_MAX = 3 # maximum SKIP_IN value SPROM_OP_BIND_SKIP_IN_MIN = -3 # minimum SKIP_IN value SPROM_OP_BIND_SKIP_OUT_MAX = 1 # maximum SKIP_OUT value SPROM_OP_BIND_SKIP_OUT_MIN = 0 # minimum SKIP_OUT value SPROM_OP_IMM_MAX = 15 # maximum immediate value SPROM_OP_REV_RANGE_MAX = 15 # maximum SROM rev range value # SPROM opcode encoding state SromOpStream = class_new("SromOpStream") class_add_prop(SromOpStream, p_layout, "layout") class_add_prop(SromOpStream, p_revisions, "revisions") class_add_prop(SromOpStream, p_vid, "vid") class_add_prop(SromOpStream, p_offset, "offset") class_add_prop(SromOpStream, p_type, "type") class_add_prop(SromOpStream, p_nelem, "nelem") class_add_prop(SromOpStream, p_mask, "mask") class_add_prop(SromOpStream, p_shift, "shift") class_add_prop(SromOpStream, p_bind_total, "bind_total") class_add_prop(SromOpStream, p_pending_bind, "pending_bind") # SROM pending bind operation SromOpBind = class_new("SromOpBind") class_add_prop(SromOpBind, p_segment, "segment") class_add_prop(SromOpBind, p_count, "count") class_add_prop(SromOpBind, p_offset, "offset") class_add_prop(SromOpBind, p_width, "width") class_add_prop(SromOpBind, p_skip_in, "skip_in") class_add_prop(SromOpBind, p_skip_out, "skip_out") class_add_prop(SromOpBind, p_buffer, "buffer") # Map class definition Map = class_new("Map") # Array class definition Array = class_new("Array") class_add_prop(Array, p_count, "count") # MacroType class definition # Used to define a set of known macro types that may be generated MacroType = class_new("MacroType") class_add_prop(MacroType, p_name, "name") class_add_prop(MacroType, p_const_suffix, "const_suffix") MTypeVarName = macro_type_new("name", "") # var name MTypeVarID = macro_type_new("id", "_ID") # var unique ID MTypeVarMaxLen = macro_type_new("len", "_MAXLEN") # var max array length # Preprocessor Constant MacroDefine = class_new("MacroDefine") class_add_prop(MacroDefine, p_name, "name") class_add_prop(MacroDefine, p_value, "value") # ParseState definition ParseState = class_new("ParseState") class_add_prop(ParseState, p_ctx, "ctx") class_add_prop(ParseState, p_is_block, "is_block") class_add_prop(ParseState, p_line, "line") # Value Formats Fmt = class_new("Fmt") class_add_prop(Fmt, p_name, "name") - class_add_prop(Fmt, p_symbol, "const") + class_add_prop(Fmt, p_symbol, "symbol") + class_add_prop(Fmt, p_array_fmt, "array_fmt") FmtHex = fmt_new("hex", "bhnd_nvram_val_bcm_hex_fmt") FmtDec = fmt_new("decimal", "bhnd_nvram_val_bcm_decimal_fmt") FmtMAC = fmt_new("macaddr", "bhnd_nvram_val_bcm_macaddr_fmt") FmtLEDDC = fmt_new("leddc", "bhnd_nvram_val_bcm_leddc_fmt") + FmtCharArray = fmt_new("char_array", "bhnd_nvram_val_char_array_fmt") + FmtChar = fmt_new("char", "bhnd_nvram_val_char_array_fmt", + FmtCharArray) FmtStr = fmt_new("string", "bhnd_nvram_val_bcm_string_fmt") + # User-specifiable value formats ValueFormats = map_new() map_set(ValueFormats, get(FmtHex, p_name), FmtHex) map_set(ValueFormats, get(FmtDec, p_name), FmtDec) map_set(ValueFormats, get(FmtMAC, p_name), FmtMAC) map_set(ValueFormats, get(FmtLEDDC, p_name), FmtLEDDC) map_set(ValueFormats, get(FmtStr, p_name), FmtStr) # Data Types Type = class_new("Type") class_add_prop(Type, p_name, "name") class_add_prop(Type, p_width, "width") class_add_prop(Type, p_signed, "signed") class_add_prop(Type, p_const, "const") class_add_prop(Type, p_const_val, "const_val") class_add_prop(Type, p_array_const, "array_const") class_add_prop(Type, p_array_const_val, "array_const_val") class_add_prop(Type, p_default_fmt, "default_fmt") class_add_prop(Type, p_mask, "mask") ArrayType = class_new("ArrayType", AST) class_add_prop(ArrayType, p_type, "type") class_add_prop(ArrayType, p_count, "count") UInt8Max = 255 UInt16Max = 65535 UInt32Max = 4294967295 Int8Min = -128 Int8Max = 127 Int16Min = -32768 Int16Max = 32767 Int32Min = -2147483648 Int32Max = 2147483648 CharMin = Int8Min CharMax = Int8Max UInt8 = type_new("u8", 1, 0, "BHND_NVRAM_TYPE_UINT8", "BHND_NVRAM_TYPE_UINT8_ARRAY", FmtHex, UInt8Max, 0, 16) UInt16 = type_new("u16", 2, 0, "BHND_NVRAM_TYPE_UINT16", "BHND_NVRAM_TYPE_UINT16_ARRAY", FmtHex, UInt16Max, 1, 17) UInt32 = type_new("u32", 4, 0, "BHND_NVRAM_TYPE_UINT32", "BHND_NVRAM_TYPE_UINT32_ARRAY", FmtHex, UInt32Max, 2, 18) Int8 = type_new("i8", 1, 1, "BHND_NVRAM_TYPE_INT8", "BHND_NVRAM_TYPE_INT8_ARRAY", FmtDec, UInt8Max, 4, 20) Int16 = type_new("i16", 2, 1, "BHND_NVRAM_TYPE_INT16", "BHND_NVRAM_TYPE_INT16_ARRAY", FmtDec, UInt16Max, 5, 21) Int32 = type_new("i32", 4, 1, "BHND_NVRAM_TYPE_INT32", "BHND_NVRAM_TYPE_INT32_ARRAY", FmtDec, UInt32Max, 6, 22) Char = type_new("char", 1, 1, "BHND_NVRAM_TYPE_CHAR", - "BHND_NVRAM_TYPE_CHAR_ARRAY", FmtStr, UInt8Max, 8, 24) + "BHND_NVRAM_TYPE_CHAR_ARRAY", FmtChar, UInt8Max, 8, 24) BaseTypes = map_new() map_set(BaseTypes, get(UInt8, p_name), UInt8) map_set(BaseTypes, get(UInt16, p_name), UInt16) map_set(BaseTypes, get(UInt32, p_name), UInt32) map_set(BaseTypes, get(Int8, p_name), Int8) map_set(BaseTypes, get(Int16, p_name), Int16) map_set(BaseTypes, get(Int32, p_name), Int32) map_set(BaseTypes, get(Char, p_name), Char) BaseTypesArray = map_to_array(BaseTypes) BaseTypesCount = array_size(BaseTypesArray) # Variable Flags VFlag = class_new("VFlag") class_add_prop(VFlag, p_name, "name") class_add_prop(VFlag, p_const, "const") VFlagPrivate = vflag_new("private", "BHND_NVRAM_VF_MFGINT") VFlagIgnoreAll1 = vflag_new("ignall1", "BHND_NVRAM_VF_IGNALL1") # Variable Access Type Constants VAccess = class_new("VAccess") VAccessPublic = obj_new(VAccess) # Public VAccessPrivate = obj_new(VAccess) # MFG Private VAccessInternal = obj_new(VAccess) # Implementation-Internal # # AST node classes # AST = class_new("AST") class_add_prop(AST, p_line, "line") SymbolContext = class_new("SymbolContext", AST) class_add_prop(SymbolContext, p_vars, "vars") # NVRAM root parser context NVRAM = class_new("NVRAM", SymbolContext) class_add_prop(NVRAM, p_var_groups, "var_groups") class_add_prop(NVRAM, p_srom_layouts, "srom_layouts") class_add_prop(NVRAM, p_srom_table, "srom_table") # Variable Group VarGroup = class_new("VarGroup", SymbolContext) class_add_prop(VarGroup, p_name, "name") # Revision Range RevRange = class_new("RevRange", AST) class_add_prop(RevRange, p_start, "start") class_add_prop(RevRange, p_end, "end") # String Constant StringConstant = class_new("StringConstant", AST) class_add_prop(StringConstant, p_value, "value") # string class_add_prop(StringConstant, p_continued, "continued") # bool # Variable Declaration Var = class_new("Var", AST) class_add_prop(Var, p_access, "access") # VAccess class_add_prop(Var, p_name, "name") # string class_add_prop(Var, p_desc, "desc") # StringConstant class_add_prop(Var, p_help, "help") # StringConstant class_add_prop(Var, p_type, "type") # AbstractType class_add_prop(Var, p_fmt, "fmt") # Fmt class_add_prop(Var, p_ignall1, "ignall1") # bool # ID is assigned once all variables are sorted class_add_prop(Var, p_vid, "vid") # int # Common interface inherited by parser contexts that support # registration of SROM variable entries SromContext = class_new("SromContext", AST) class_add_prop(SromContext, p_revisions, "revisions") # SROM Layout Node SromLayout = class_new("SromLayout", SromContext) class_add_prop(SromLayout, p_entries, "entries") # Array class_add_prop(SromLayout, p_revmap, "revmap") # Map<(string,int), SromEntry> class_add_prop(SromLayout, p_output_var_counts, # Map (rev->count) "output_var_counts") # SROM Layout Filter Node # Represents a filter over a parent SromLayout's revisions SromLayoutFilter = class_new("SromLayoutFilter", SromContext) class_add_prop(SromLayoutFilter, p_parent, "parent") # SROM variable entry SromEntry = class_new("SromEntry", AST) class_add_prop(SromEntry, p_var, "var") class_add_prop(SromEntry, p_revisions, "revisions") class_add_prop(SromEntry, p_base_offset, "base_offset") class_add_prop(SromEntry, p_type, "type") class_add_prop(SromEntry, p_offsets, "offsets") # SROM variable offset SromOffset = class_new("SromOffset", AST) class_add_prop(SromOffset, p_segments, "segments") # SROM variable offset segment SromSegment = class_new("SromSegment", AST) class_add_prop(SromSegment, p_offset, "offset") class_add_prop(SromSegment, p_type, "type") class_add_prop(SromSegment, p_mask, "mask") class_add_prop(SromSegment, p_shift, "shift") class_add_prop(SromSegment, p_value, "value") # Create the parse state stack _g_parse_stack_depth = 0 _g_parse_stack[0] = null # Push the root parse state parser_state_push(nvram_new(), 0) } function at_exit(_block_start, _state, _output_vars, _noutput_vars, _name, _var, _i) { # Skip completion handling if exiting from an error if (_EARLY_EXIT) exit 1 # Check for complete block closure if (!in_parser_context(NVRAM)) { _state = parser_state_get() _block_start = get(_state, p_line) errorx("missing '}' for block opened on line " _block_start "") } # Apply lexicographical sorting to our variable names. To support more # effecient table searching, we guarantee a stable sort order (using C # collation). # # This also has a side-effect of generating a unique monotonic ID # for all variables, which we will emit as a #define and can use as a # direct index into the C variable table _output_vars = array_new() for (_name in _g_var_names) { _var = _g_var_names[_name] # Don't include internal variables in the output if (var_is_internal(_var)) continue array_append(_output_vars, _var) } # Sort by variable name array_sort(_output_vars, prop_to_path(p_name)) # Set all variable ID properties to their newly assigned ID value _noutput_vars = array_size(_output_vars) for (_i = 0; _i < _noutput_vars; _i++) { _var = array_get(_output_vars, _i) set(_var, p_vid, _i) } # Truncate output file and write common header printf("") > OUTPUT_FILE emit("/*\n") emit(" * THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n") emit(" *\n") emit(" * generated from nvram map: " FILENAME "\n") emit(" */\n") emit("\n") # Emit all variable definitions if (OUT_T == OUT_T_DATA) { write_data(_output_vars) } else if (OUT_T == OUT_T_HEADER) { write_header(_output_vars) } printf("%u variable records written to %s\n", array_size(_output_vars), OUTPUT_FILE) >> "/dev/stderr" } # Write the public header (output type HEADER) function write_header(output_vars, _noutput_vars, _var, _tab_align, _macro, _macros, _num_macros, _i) { # Produce our array of #defines _num_macros = 0 _noutput_vars = array_size(output_vars) for (_i = 0; _i < _noutput_vars; _i++) { _var = array_get(output_vars, _i) # Variable name _macro = var_get_macro(_var, MTypeVarName, \ "\"" get(_var, p_name) "\"") _macros[_num_macros++] = _macro # Variable array length if (var_has_array_type(_var)) { _macro = var_get_macro(_var, MTypeVarMaxLen, var_get_array_len(_var)) _macros[_num_macros++] = _macro } } # Calculate value tab alignment position for our macros _tab_align = macros_get_tab_alignment(_macros, _num_macros) # Write the macros for (_i = 0; _i < _num_macros; _i++) write_macro_define(_macros[_i], _tab_align) } # Write the private data header (output type DATA) function write_data(output_vars, _noutput_vars, _var, _nvram, _layouts, _nlayouts, _layout, _revs, _rev, _rev_start, _rev_end, _base_type, _srom_table, _nsrom_table, _i, _j) { _nvram = parser_state_get_context(NVRAM) _layouts = get(_nvram, p_srom_layouts) _nlayouts = array_size(_layouts) _noutput_vars = array_size(output_vars) # Write all our private NVAR_ID defines write_data_defines(output_vars) # Write all layout binding opcodes, and build an array # mapping SROM revision to corresponding SROM layout _srom_table = array_new() for (_i = 0; _i < _nlayouts; _i++) { _layout = array_get(_layouts, _i) # Write binding opcode table to our output file write_srom_bindings(_layout) # Add entries to _srom_table for all covered revisions _revs = get(_layout, p_revisions) _rev_start = get(_revs, p_start) _rev_end = get(_revs, p_end) for (_j = _rev_start; _j <= _rev_end; _j++) array_append(_srom_table, _j) } # Sort in ascending order, by SROM revision array_sort(_srom_table) _nsrom_table = array_size(_srom_table) # Write the variable definitions emit("/* Variable definitions */\n") emit("const struct bhnd_nvram_vardefn " \ "bhnd_nvram_vardefns[] = {\n") output_depth++ for (_i = 0; _i < _noutput_vars; _i++) { write_data_nvram_vardefn(array_get(output_vars, _i)) } output_depth-- emit("};\n") emit("const size_t bhnd_nvram_num_vardefns = " _noutput_vars ";\n") # Write static asserts for raw type constant values that must be kept # synchronized with the code for (_i = 0; _i < BaseTypesCount; _i++) { _base_type = array_get(BaseTypesArray, _i) emit(sprintf("_Static_assert(%s == %u, \"%s\");\n", type_get_const(_base_type), type_get_const_val(_base_type), "type constant out of sync")) emit(sprintf("_Static_assert(%s == %u, \"%s\");\n", get(_base_type, p_array_const), get(_base_type, p_array_const_val), "array type constant out of sync")) } # Write all top-level bhnd_sprom_layout entries emit("/* SPROM layouts */\n") emit("const struct bhnd_sprom_layout bhnd_sprom_layouts[] = {\n") output_depth++ for (_i = 0; _i < _nsrom_table; _i++) { _rev = array_get(_srom_table, _i) _layout = nvram_get_srom_layout(_nvram, _rev) write_data_srom_layout(_layout, _rev) } output_depth-- emit("};\n") emit("const size_t bhnd_sprom_num_layouts = " _nsrom_table ";\n") } # Write a bhnd_nvram_vardef entry for the given variable function write_data_nvram_vardefn(v, _desc, _help, _type, _fmt) { obj_assert_class(v, Var) _desc = get(v, p_desc) _help = get(v, p_help) _type = get(v, p_type) _fmt = var_get_fmt(v) emit("{\n") output_depth++ emit(sprintf(".name = \"%s\",\n", get(v, p_name))) if (_desc != null) emit(sprintf(".desc = \"%s\",\n", get(_desc, p_value))) else emit(".desc = NULL,\n") if (_help != null) emit(sprintf(".help = \"%s\",\n", get(_help, p_value))) else emit(".help = NULL,\n") emit(".type = " type_get_const(_type) ",\n") emit(".nelem = " var_get_array_len(v) ",\n") emit(".fmt = &" get(_fmt, p_symbol) ",\n") emit(".flags = " gen_var_flags(v) ",\n") output_depth-- emit("},\n") } # Write a top-level bhnd_sprom_layout entry for the given revision # and layout definition function write_data_srom_layout(layout, revision, _flags, _size, - _sromcrc, _crc_seg, + _sromcrc, _crc_seg, _crc_off, _sromsig, _sig_seg, _sig_offset, _sig_value, _sromrev, _rev_seg, _rev_off, _num_vars) { _flags = array_new() # Calculate the size; it always follows the internal CRC variable _sromcrc = srom_layout_find_entry(layout, "", revision) if (_sromcrc == null) { errorx("missing '' entry for '"revision"' layout, " \ "cannot compute total size") } else { _crc_seg = srom_entry_get_single_segment(_sromcrc) - _size = get(_crc_seg, p_offset) + _crc_off = get(_crc_seg, p_offset) + _size = _crc_off _size += get(get(_crc_seg, p_type), p_width) } # Fetch signature definition _sromsig = srom_layout_find_entry(layout, "", revision) if (_sromsig == null) { array_append(_flags, "SPROM_LAYOUT_MAGIC_NONE") } else { _sig_seg = srom_entry_get_single_segment(_sromsig) _sig_offset = get(_sig_seg, p_offset) _sig_value = get(_sig_seg, p_value) if (_sig_value == "") errorc(get(_sromsig, p_line), "missing signature value") } # Fetch sromrev definition _sromrev = srom_layout_find_entry(layout, "sromrev", revision) if (_sromrev == null) { errorx("missing 'sromrev' entry for '"revision"' layout, " \ "cannot determine offset") } else { # Must be a u8 value if (!type_equal(get(_sromrev, p_type), UInt8)) { errorx("'sromrev' entry has non-u8 type '" \ type_to_string(get(_sromrev, p_type))) } _rev_seg = srom_entry_get_single_segment(_sromrev) _rev_off = get(_rev_seg, p_offset) } # Write layout entry emit("{\n") output_depth++ emit(".size = "_size",\n") emit(".rev = "revision",\n") if (array_size(_flags) > 0) { emit(".flags = " array_join(_flags, "|") ",\n") } else { emit(".flags = 0,\n") } emit(".srev_offset = " _rev_off ",\n") if (_sromsig != null) { emit(".magic_offset = " _sig_offset ",\n") emit(".magic_value = " _sig_value ",\n") } else { emit(".magic_offset = 0,\n") emit(".magic_value = 0,\n") } + emit(".crc_offset = " _crc_off ",\n") + emit(".bindings = " srom_layout_get_variable_name(layout) ",\n") emit(".bindings_size = nitems(" \ srom_layout_get_variable_name(layout) "),\n") emit(".num_vars = " srom_layout_num_output_vars(layout, revision) ",\n") obj_delete(_flags) output_depth-- emit("},\n"); } # Create a new opstream encoding state instance for the given layout function srom_ops_new(layout, _obj) { obj_assert_class(layout, SromLayout) _obj = obj_new(SromOpStream) set(_obj, p_layout, layout) set(_obj, p_revisions, get(layout, p_revisions)) set(_obj, p_vid, 0) set(_obj, p_offset, 0) set(_obj, p_type, null) set(_obj, p_mask, null) set(_obj, p_shift, null) return (_obj) } # Return the current type width, or throw an error if no type is currently # specified. function srom_ops_get_type_width(opstream, _type) { obj_assert_class(opstream, SromOpStream) _type = get(opstream, p_type) if (_type == null) errorx("no type value set") return (get(type_get_base(_type), p_width)) } # Write a string to the SROM opcode stream, either buffering the write, # or emitting it directly. function srom_ops_emit(opstream, string, _pending_bind, _buffer) { obj_assert_class(opstream, SromOpStream) # Buffered? if ((_pending_bind = get(opstream, p_pending_bind)) != null) { _buffer = get(_pending_bind, p_buffer) array_append(_buffer, string) return } # Emit directly emit(string) } # Emit a SROM opcode followed by up to four optional bytes function srom_ops_emit_opcode(opstream, opcode, arg0, arg1, arg2, arg3) { obj_assert_class(opstream, SromOpStream) srom_ops_emit(opstream, opcode",\n") if (arg0 != "") srom_ops_emit(opstream, arg0",\n") if (arg1 != "") srom_ops_emit(opstream, arg1",\n") if (arg2 != "") srom_ops_emit(opstream, arg2",\n") if (arg3 != "") srom_ops_emit(opstream, arg3",\n") } # Emit a SROM opcode and associated integer value, choosing the best # SROM_OP_DATA variant for encoding the value. # # opc: The standard opcode for non-IMM encoded data, or null if none # opc_imm: The IMM opcode, or null if none # value: The value to encode # svalue: Symbolic representation of value to include in output, or null function srom_ops_emit_int_opcode(opstream, opc, opc_imm, value, svalue, _width, _offset, _delta) { obj_assert_class(opstream, SromOpStream) # Fetch current type width _width = srom_ops_get_type_width(opstream) # Special cases: if (opc_imm == SPROM_OPCODE_SHIFT_IMM) { # SHIFT_IMM -- the imm value must be positive and divisible by # two (shift/2) to use the IMM form. if (value >= 0 && value % 2 == 0) { value = (value/2) opc = null } else { opc_imm = null } } else if (opc_imm == SPROM_OPCODE_OFFSET_REL_IMM) { # OFFSET_REL_IMM -- the imm value must be positive, divisible # by the type width, and relative to the last offset to use # the IMM form. # Assert that callers correctly flushed any pending bind before # attempting to set a relative offset if (get(opstream, p_pending_bind) != null) errorx("can't set relative offset with a pending bind") # Fetch current offset, calculate relative value and determine # whether we can issue an IMM opcode _offset = get(opstream, p_offset) _delta = value - _offset if (_delta >= 0 && _delta % _width == 0 && (_delta/_width) <= SPROM_OP_IMM_MAX) { srom_ops_emit(opstream, sprintf("/* %#x + %#x -> %#x */\n", _offset, _delta, value)) value = (_delta / _width) opc = null } else { opc_imm = null } } # If no symbolic representation provided, write the raw value if (svalue == null) svalue = value # Try to encode as IMM value? if (opc_imm != null && value >= 0 && value <= SPROM_OP_IMM_MAX) { srom_ops_emit_opcode(opstream, "("opc_imm"|"svalue")") return } # Can't encode as immediate; do we have a non-immediate form? if (opc == null) errorx("can't encode '" value "' as immediate, and no " \ "non-immediate form was provided") # Determine and emit minimal encoding # We let the C compiler perform the bit operations, rather than # trying to wrestle awk's floating point arithmetic if (value < 0) { # Only Int8 is used if (value < Int8Min) errorx("cannot int8 encode '" value "'") srom_ops_emit_opcode(opstream, "("opc"|"SPROM_OP_DATA_I8")", svalue) } else if (value <= UInt8Max) { srom_ops_emit_opcode(opstream, "("opc"|"SPROM_OP_DATA_U8")", svalue) } else if (value % _width == 0 && (value / _width) <= UInt8Max) { srom_ops_emit_opcode(opstream, "("opc"|"SPROM_OP_DATA_U8_SCALED")", svalue / _width) } else if (value <= UInt16Max) { srom_ops_emit_opcode(opstream, "("opc"|"SPROM_OP_DATA_U16")", "("svalue" & 0xFF)", "("svalue" >> 8)") } else if (value <= UInt32Max) { srom_ops_emit_opcode(opstream, "("opc"|"SPROM_OP_DATA_U32")", "("svalue" & 0xFF)", "(("svalue" >> 8) & 0xFF)", "(("svalue" >> 16) & 0xFF)", "(("svalue" >> 24) & 0xFF)") } else { errorx("can't encode '" value "' (too large)") } } # Emit initial OPCODE_VAR opcode and update opstream state function srom_ops_reset_var(opstream, var, _vid_prev, _vid, _vid_name, _type, _base_type) { obj_assert_class(opstream, SromOpStream) obj_assert_class(var, Var) # Flush any pending bind for the previous variable srom_ops_flush_bind(opstream, 1) # Fetch current state _vid_prev = get(opstream, p_vid) _vid = get(var, p_vid) _vid_name = var_get_macro_name(var, MTypeVarID) # Update state _type = get(var, p_type) set(opstream, p_vid, _vid) set(opstream, p_type, type_get_base(_type)) set(opstream, p_nelem, var_get_array_len(var)) set(opstream, p_mask, type_get_default_mask(_type)) set(opstream, p_shift, 0) set(opstream, p_bind_total, 0) # Always provide a human readable comment srom_ops_emit(opstream, sprintf("/* %s (%#x) */\n", get(var, p_name), get(opstream, p_offset))) # Prefer a single VAR_IMM byte if (_vid_prev == 0 || _vid <= SPROM_OP_IMM_MAX) { srom_ops_emit_int_opcode(opstream, null, SPROM_OPCODE_VAR_IMM, _vid, _vid_name) return } # Try encoding as a single VAR_REL_IMM byte if (_vid_prev <= _vid && (_vid - _vid_prev) <= SPROM_OP_IMM_MAX) { srom_ops_emit_int_opcode(opstream, null, SPROM_OPCODE_VAR_REL_IMM, _vid - _vid_prev, null) return } # Fall back on a multibyte encoding srom_ops_emit_int_opcode(opstream, SPROM_OPCODE_VAR, null, _vid, _vid_name) } # Emit OPCODE_REV/OPCODE_REV_RANGE (if necessary) for a new revision range function srom_ops_emit_revisions(opstream, revisions, _prev_revs, _start, _end) { obj_assert_class(opstream, SromOpStream) _prev_revs = get(opstream, p_revisions) if (revrange_equal(_prev_revs, revisions)) return; # Update stream state set(opstream, p_revisions, revisions) _start = get(revisions, p_start) _end = get(revisions, p_end) # Sanity-check range values if (_start < 0 || _end < 0) errorx("invalid range: " revrange_to_string(revisions)) # If range covers a single revision, and can be encoded within # SROM_OP_IMM_MAX, we can use the single byte encoding if (_start == _end && _start <= SPROM_OP_IMM_MAX) { srom_ops_emit_int_opcode(opstream, null, SPROM_OPCODE_REV_IMM, _start) return } # Otherwise, we need to use the two byte range encoding if (_start > SPROM_OP_REV_RANGE_MAX || _end > SPROM_OP_REV_RANGE_MAX) { errorx(sprintf("cannot encode range values %s (>= %u)", revrange_to_string(revisions), SPROM_OP_REV_RANGE_MAX)) } srom_ops_emit_opcode(opstream, SPROM_OPCODE_REV_RANGE, sprintf("(%u << %s) | (%u << %s)", _start, SPROM_OP_REV_START_SHIFT, _end, SPROM_OP_REV_END_SHIFT)) } # Emit OPCODE_OFFSET (if necessary) for a new offset function srom_ops_emit_offset(opstream, offset, _prev_offset, _rel_offset, _bind) { obj_assert_class(opstream, SromOpStream) # Flush any pending bind before adjusting the offset srom_ops_flush_bind(opstream, 0) # Fetch current offset _prev_offset = get(opstream, p_offset) if (_prev_offset == offset) return # Encode (possibly a relative, 1-byte form) of the offset opcode srom_ops_emit_int_opcode(opstream, SPROM_OPCODE_OFFSET, SPROM_OPCODE_OFFSET_REL_IMM, offset, null) # Update state set(opstream, p_offset, offset) } # Emit OPCODE_TYPE (if necessary) for a new type value; this also # resets the mask to the type default. function srom_ops_emit_type(opstream, type, _base_type, _prev_type, _prev_mask, _default_mask) { obj_assert_class(opstream, SromOpStream) if (!obj_is_instanceof(type, ArrayType)) obj_assert_class(type, Type) _default_mask = type_get_default_mask(type) _base_type = type_get_base(type) # If state already matches the requested type, nothing to be # done _prev_type = get(opstream, p_type) _prev_mask = get(opstream, p_mask) if (type_equal(_prev_type, _base_type) && _prev_mask == _default_mask) return # Update state set(opstream, p_type, _base_type) set(opstream, p_mask, _default_mask) # Emit opcode. if (type_get_const_val(_base_type) <= SPROM_OP_IMM_MAX) { # Single byte IMM encoding srom_ops_emit_opcode(opstream, SPROM_OPCODE_TYPE_IMM "|" type_get_const(_base_type)) } else { # Two byte encoding srom_ops_emit_opcode(opstream, SPROM_OPCODE_TYPE, type_get_const(_base_type)) } } # Emit OPCODE_MASK (if necessary) for a new mask value function srom_ops_emit_mask(opstream, mask, _prev_mask) { obj_assert_class(opstream, SromOpStream) _prev_mask = get(opstream, p_mask) if (_prev_mask == mask) return set(opstream, p_mask, mask) srom_ops_emit_int_opcode(opstream, SPROM_OPCODE_MASK, SPROM_OPCODE_MASK_IMM, mask, sprintf("0x%x", mask)) } # Emit OPCODE_SHIFT (if necessary) for a new shift value function srom_ops_emit_shift(opstream, shift, _prev_shift) { obj_assert_class(opstream, SromOpStream) _prev_shift = get(opstream, p_shift) if (_prev_shift == shift) return set(opstream, p_shift, shift) srom_ops_emit_int_opcode(opstream, SPROM_OPCODE_SHIFT, SPROM_OPCODE_SHIFT_IMM, shift, null) } # Return true if a valid BIND/BINDN encoding exists for the given SKIP_IN # value, false if the skip values exceed the limits of the bind opcode # family. function srom_ops_can_encode_skip_in(skip_in) { return (skip_in >= SPROM_OP_BIND_SKIP_IN_MIN && skip_in <= SPROM_OP_BIND_SKIP_IN_MAX) } # Return true if a valid BIND/BINDN encoding exists for the given SKIP_OUT # value, false if the skip values exceed the limits of the bind opcode # family. function srom_ops_can_encode_skip_out(skip_out) { return (skip_in >= SPROM_OP_BIND_SKIP_IN_MIN && skip_in <= SPROM_OP_BIND_SKIP_IN_MAX) } # Return true if a valid BIND/BINDN encoding exists for the given skip # values, false if the skip values exceed the limits of the bind opcode # family. function srom_ops_can_encode_skip(skip_in, skip_out) { return (srom_ops_can_encode_skip_in(skip_in) && srom_ops_can_encode_skip_out(skip_out)) } # Create a new SromOpBind instance for the given segment function srom_opbind_new(segment, skip_in, skip_out, _obj, _type, _width, _offset) { obj_assert_class(segment, SromSegment) # Verify that an encoding exists for the skip values if (!srom_ops_can_encode_skip_in(skip_in)) { errorx(sprintf("cannot encode SKIP_IN=%d; maximum supported " \ "range %d-%d", skip_in, SPROM_OP_BIND_SKIP_IN_MIN, SPROM_OP_BIND_SKIP_IN_MAX)) } if (!srom_ops_can_encode_skip_out(skip_out)) { errorx(sprintf("cannot encode SKIP_OUT=%d; maximum supported " \ "range %d-%d", skip_out, SPROM_OP_BIND_SKIP_OUT_MIN, SPROM_OP_BIND_SKIP_OUT_MAX)) } # Fetch basic segment info _offset = get(segment, p_offset) _type = srom_segment_get_base_type(segment) _width = get(_type, p_width) # Construct new instance _obj = obj_new(SromOpBind) set(_obj, p_segment, segment) set(_obj, p_count, 1) set(_obj, p_offset, _offset) set(_obj, p_width, _width) set(_obj, p_skip_in, skip_in) set(_obj, p_skip_out, skip_out) set(_obj, p_buffer, array_new()) return (_obj) } # Try to coalesce a BIND for the given segment with an existing bind request, # returning true on success, or false if the two segments cannot be coalesced # into the existing request function srom_opbind_append(bind, segment, skip_out, _bind_seg, _bind_off, _width, _count, _skip_in, _seg_offset, _delta) { obj_assert_class(bind, SromOpBind) obj_assert_class(segment, SromSegment) # Are the segments compatible? _bind_seg = get(bind, p_segment) if (!srom_segment_attributes_equal(_bind_seg, segment)) return (0) # Are the output skip values compatible? if (get(bind, p_skip_out) != skip_out) return (0) # Find bind offset/count/width/skip _bind_off = get(bind, p_offset) _count = get(bind, p_count) _skip_in = get(bind, p_skip_in) _width = get(bind, p_width) # Fetch new segment's offset _seg_offset = get(segment, p_offset) # If there's only one segment in the bind op, we ned to compute the # skip value to be used for all later segments (including the # segment we're attempting to append) # # If there's already multiple segments, we just need to verify that # the bind_offset + (count * width * skip_in) produces the new # segment's offset if (_count == 1) { # Determine the delta between the two segment offsets. This # must be a multiple of the type width to be encoded # as a BINDN entry _delta = _seg_offset - _bind_off if ((_delta % _width) != 0) return (0) # The skip byte count is calculated as (type width * skip) _skip_in = _delta / _width # Is the skip encodable? if (!srom_ops_can_encode_skip_in(_skip_in)) return (0) # Save required skip set(bind, p_skip_in, _skip_in) } else if (_count > 1) { # Get the final offset of the binding if we were to add # one additional segment _bind_off = _bind_off + (_width * _skip_in * (_count + 1)) # If it doesn't match our segment's offset, we can't # append this segment if (_bind_off != _seg_offset) return (0) } # Success! Increment the bind count in the existing bind set(bind, p_count, _count + 1) return (1) } # Return true if the given binding operation can be omitted from the output # if it would be immediately followed by a VAR, VAR_REL_IMM, or EOF opcode. # # The bind operatin must be configured with default count, skip_in, and # skip_out values of 1, and must contain no buffered post-BIND opcodes function srom_opbind_is_implicit_encodable(bind) { obj_assert_class(bind, SromOpBind) if (get(bind, p_count) != 1) return (0) if (get(bind, p_skip_in) != 1) return (0) if (get(bind, p_skip_out) != 1) return (0) if (array_size(get(bind, p_buffer)) != 0) return (0) return (1) } # Encode all segment settings for a single offset segment, followed by a bind # request. # # opstream: Opcode stream # segment: Segment to be written # continued: If this segment's value should be OR'd with the value of a # following segment function srom_ops_emit_segment(opstream, segment, continued, _value, _bind, _skip_in, _skip_out) { obj_assert_class(opstream, SromOpStream) obj_assert_class(segment, SromSegment) # Determine basic bind parameters _count = 1 _skip_in = 1 _skip_out = continued ? 0 : 1 # Try to coalesce with a pending binding if ((_bind = get(opstream, p_pending_bind)) != null) { if (srom_opbind_append(_bind, segment, _skip_out)) return } # Otherwise, flush any pending bind and enqueue our own srom_ops_flush_bind(opstream, 0) if (get(opstream, p_pending_bind)) errorx("bind not flushed!") # Encode type _value = get(segment, p_type) srom_ops_emit_type(opstream, _value) # Encode offset _value = get(segment, p_offset) srom_ops_emit_offset(opstream, _value) # Encode mask _value = get(segment, p_mask) srom_ops_emit_mask(opstream, _value) # Encode shift _value = get(segment, p_shift) srom_ops_emit_shift(opstream, _value) # Enqueue binding with opstream _bind = srom_opbind_new(segment, _skip_in, _skip_out) set(opstream, p_pending_bind, _bind) } # (private) Adjust the stream's input offset by applying the given bind # operation's skip_in * width * count. function _srom_ops_apply_bind_offset(opstream, bind, _count, _offset, _width, _skip_in, _opstream_offset) { obj_assert_class(opstream, SromOpStream) obj_assert_class(bind, SromOpBind) _opstream_offset = get(opstream, p_offset) _offset = get(bind, p_offset) if (_opstream_offset != _offset) errorx("stream/bind offset state mismatch") _count = get(bind, p_count) _width = get(bind, p_width) _skip_in = get(bind, p_skip_in) set(opstream, p_offset, _opstream_offset + ((_width * _skip_in) * _count)) } # (private) Write a bind instance and all buffered opcodes function _srom_ops_emit_bind(opstream, bind, _count, _skip_in, _skip_out, _off_start, _width, _si_signbit, _written, _nbuffer, _buffer) { obj_assert_class(opstream, SromOpStream) obj_assert_class(bind, SromOpBind) # Assert that any pending bind state has already been cleared if (get(opstream, p_pending_bind) != null) errorx("cannot flush bind with an existing pending_bind active") # Fetch (and assert valid) our skip values _skip_in = get(bind, p_skip_in) _skip_out = get(bind, p_skip_out) if (!srom_ops_can_encode_skip(_skip_in, _skip_out)) errorx("invalid skip values in buffered bind") # Determine SKIP_IN sign bit _si_signbit = "0" if (_skip_in < 0) _si_signbit = SPROM_OP_BIND_SKIP_IN_SIGN # Emit BIND/BINDN opcodes until the full count is encoded _count = get(bind, p_count) while (_count > 0) { if (_count > 1 && _count <= SPROM_OP_IMM_MAX && _skip_in == 1 && _skip_out == 1) { # The one-byte BINDN form requires encoding the count # as a IMM, and has an implicit in/out skip of 1. srom_ops_emit_opcode(opstream, "("SPROM_OPCODE_DO_BINDN_IMM"|"_count")") _count -= _count } else if (_count > 1) { # The two byte BINDN form can encode skip values and a # larger U8 count _written = min(_count, UInt8Max) srom_ops_emit_opcode(opstream, sprintf("(%s|%s|(%u<<%s)|(%u<<%s))", SPROM_OPCODE_DO_BINDN, _si_signbit, abs(_skip_in), SPROM_OP_BIND_SKIP_IN_SHIFT, _skip_out, SPROM_OP_BIND_SKIP_OUT_SHIFT), _written) _count -= _written } else { # The 1-byte BIND form can encode the same SKIP values # as the 2-byte BINDN, with a implicit count of 1 srom_ops_emit_opcode(opstream, sprintf("(%s|%s|(%u<<%s)|(%u<<%s))", SPROM_OPCODE_DO_BIND, _si_signbit, abs(_skip_in), SPROM_OP_BIND_SKIP_IN_SHIFT, _skip_out, SPROM_OP_BIND_SKIP_OUT_SHIFT)) _count-- } } # Update the stream's input offset _srom_ops_apply_bind_offset(opstream, bind) # Write any buffered post-BIND opcodes _buffer = get(bind, p_buffer) _nbuffer = array_size(_buffer) for (_i = 0; _i < _nbuffer; _i++) srom_ops_emit(opstream, array_get(_buffer, _i)) } # Flush any buffered binding function srom_ops_flush_bind(opstream, allow_implicit, _bind, _bind_total) { obj_assert_class(opstream, SromOpStream) # If no pending bind, nothing to flush if ((_bind = get(opstream, p_pending_bind)) == null) return # Check the per-variable bind count to determine whether # we can encode an implicit bind. # # If there have been any explicit bind statements, implicit binding # cannot be used. _bind_total = get(opstream, p_bind_total) if (allow_implicit && _bind_total > 0) { # Disable implicit encoding; explicit bind statements have # been issued for this variable previously. allow_implicit = 0 } # Increment bind count set(opstream, p_bind_total, _bind_total + 1) # Clear the property value set(opstream, p_pending_bind, null) # If a pending bind operation can be encoded as an implicit bind, # emit a descriptive comment and update the stream state. # # Otherwise, emit the full set of bind opcode(s) _base_off = get(opstream, p_offset) if (allow_implicit && srom_opbind_is_implicit_encodable(_bind)) { # Update stream's input offset _srom_ops_apply_bind_offset(opstream, _bind) } else { _srom_ops_emit_bind(opstream, _bind) } # Provide bind information as a comment srom_ops_emit(opstream, sprintf("/* bind (%s @ %#x -> %#x) */\n", type_to_string(get(opstream, p_type)), _base_off, get(opstream, p_offset))) # Clean up obj_delete(_bind) } # Write OPCODE_EOF after flushing any buffered writes function srom_ops_emit_eof(opstream) { obj_assert_class(opstream, SromOpStream) # Flush any buffered writes srom_ops_flush_bind(opstream, 1) # Emit an explicit VAR_END opcode for the last entry srom_ops_emit_opcode(opstream, SPROM_OPCODE_VAR_END) # Emit EOF srom_ops_emit_opcode(opstream, SPROM_OPCODE_EOF) } # Write the SROM offset segment bindings to the opstream function write_srom_offset_bindings(opstream, offsets, _noffsets, _offset, _segs, _nsegs, _segment, _cont, _i, _j) { _noffsets = array_size(offsets) for (_i = 0; _i < _noffsets; _i++) { # Encode each segment in this offset _offset = array_get(offsets, _i) _segs = get(_offset, p_segments) _nsegs = array_size(_segs) for (_j = 0; _j < _nsegs; _j++) { _segment = array_get(_segs, _j) _cont = 0 # Should this value be OR'd with the next segment? if (_j+1 < _nsegs) _cont = 1 # Encode segment srom_ops_emit_segment(opstream, _segment, _cont) } } } # Write the SROM entry stream for a SROM entry to the output file function write_srom_entry_bindings(entry, opstream, _var, _vid, _var_type, _entry_type, _offsets, _noffsets) { _var = get(entry, p_var) _vid = get(_var, p_vid) # Encode revision switch. This resets variable state, so must # occur before any variable definitions to which it applies srom_ops_emit_revisions(opstream, get(entry, p_revisions)) # Encode variable ID srom_ops_reset_var(opstream, _var, _vid) output_depth++ # Write entry-specific array length (SROM layouts may define array # mappings with fewer elements than in the variable definition) if (srom_entry_has_array_type(entry)) { _var_type = get(_var, p_type) _entry_type = get(entry, p_type) # If the array length differs from the variable default, # write an OPCODE_EXT_NELEM entry if (type_get_nelem(_var_type) != type_get_nelem(_entry_type)) { srom_ops_emit_opcode(opstream, SPROM_OPCODE_NELEM, srom_entry_get_array_len(entry)) } } # Write offset segment bindings _offsets = get(entry, p_offsets) write_srom_offset_bindings(opstream, _offsets) output_depth-- } # Write a SROM layout binding opcode table to the output file function write_srom_bindings(layout, _varname, _var, _all_entries, _nall_entries, _entries, _nentries, _entry, _opstream, _i) { _varname = srom_layout_get_variable_name(layout) _all_entries = get(layout, p_entries) _opstream = srom_ops_new(layout) # # Collect all entries to be included in the output, and then # sort by their variable's assigned ID (ascending). # # The variable IDs were previously assigned in lexigraphical sort # order; since the variable *offsets* tend to match this order, this # works out well for our compact encoding, allowing us to make use of # compact relative encoding of both variable IDs and variable offsets. # _entries = array_new() _nall_entries = array_size(_all_entries) for (_i = 0; _i < _nall_entries; _i++) { _entry = array_get(_all_entries, _i) _var = get(_entry, p_var) # Skip internal variables if (var_is_internal(_var)) continue # Sanity check variable ID assignment if (get(_var, p_vid) == "") errorx("missing variable ID for " obj_to_string(_var)) array_append(_entries, _entry) } # Sort entries by variable ID, ascending array_sort(_entries, prop_path_create(p_var, p_vid)) # Emit all entry binding opcodes emit("static const uint8_t " _varname "[] = {\n") output_depth++ _nentries = array_size(_entries) for (_i = 0; _i < _nentries; _i++) { _entry = array_get(_entries, _i) write_srom_entry_bindings(_entry, _opstream) } # Flush and write EOF srom_ops_emit_eof(_opstream) output_depth-- emit("};\n") obj_delete(_opstream) obj_delete(_entries) } # Write the BHND_NVAR__ID #defines to the output file function write_data_defines(output_vars, _noutput_vars, _tab_align, _var, _macro, _macros, _num_macros, _i) { # Produce our array of #defines _num_macros = 0 _noutput_vars = array_size(output_vars) for (_i = 0; _i < _noutput_vars; _i++) { _var = array_get(output_vars, _i) # Variable ID _macro = var_get_macro(_var, MTypeVarID, get(_var, p_vid)) _macros[_num_macros++] = _macro } # Calculate value tab alignment position for our macros _tab_align = macros_get_tab_alignment(_macros, _num_macros) # Write the #defines emit("/* ID constants provide an index into the variable array */\n") for (_i = 0; _i < _num_macros; _i++) write_macro_define(_macros[_i], _tab_align) emit("\n\n"); } # Calculate the common tab alignment to be used with a set of prefix strings # with the given maximum length function tab_alignment(max_len, _tab_align) { _tab_align = max_len _tab_align += (TAB_WIDTH - (_tab_align % TAB_WIDTH)) % TAB_WIDTH _tab_align /= TAB_WIDTH return (_tab_align) } # Generate and return a tab string that can be appended to a string of # `strlen` to pad the column out to `align_to` # # Note: If the string from which strlen was derived contains tabs, the result # is undefined function tab_str(strlen, align_to, _lead, _pad, _result, _i) { _lead = strlen _lead -= (_lead % TAB_WIDTH); _lead /= TAB_WIDTH; # Determine required padding to reach the desired alignment if (align_to >= _lead) _pad = align_to - _lead; else _pad = 1; for (_i = 0; _i < _pad; _i++) _result = _result "\t" return (_result) } # Write a MacroDefine constant, padding the constant out to `align_to` function write_macro_define(macro, align_to, _tabstr, _i) { # Determine required padding to reach the desired alignment _tabstr = tab_str(length(get(macro, p_name)), align_to) emit("#define\t" get(macro, p_name) _tabstr get(macro, p_value) "\n") } # Calculate the tab alignment to be used with a given integer-indexed array # of Macro instances. function macros_get_tab_alignment(macros, macros_len, _macro, _max_len, _i) { _max_len = 0 for (_i = 0; _i < macros_len; _i++) { _macro = macros[_i] _max_len = max(_max_len, length(get(_macro, p_name))) } return (tab_alignment(_max_len)) } # Variable group block $1 == "group" && in_parser_context(NVRAM) { parse_variable_group() } # Variable definition (($1 ~ VACCESS_REGEX && $2 ~ TYPES_REGEX) || $1 ~ TYPES_REGEX) && in_parser_context(SymbolContext) \ { parse_variable_defn() } # Variable "fmt" parameter $1 == "fmt" && in_parser_context(Var) { parse_variable_param($1) next } # Variable "all1" parameter $1 == "all1" && in_parser_context(Var) { parse_variable_param($1) next } # Variable desc/help parameters ($1 == "desc" || $1 == "help") && in_parser_context(Var) { parse_variable_param($1) next } # SROM layout block $1 == "srom" && in_parser_context(NVRAM) { parse_srom_layout() } # SROM layout revision filter block $1 == "srom" && in_parser_context(SromLayout) { parse_srom_layout_filter() } # SROM layout variable entry $1 ~ "("OFF_REGEX"):$" && \ (in_parser_context(SromLayout) || in_parser_context(SromLayoutFilter)) \ { parse_srom_variable_entry() } # SROM entry segment $1 ~ "("REL_OFF_REGEX"|"OFF_REGEX")[:,|]?" && in_parser_context(SromEntry) { parse_srom_entry_segments() } # Skip comments and blank lines /^[ \t]*#/ || /^$/ { next } # Close blocks /}/ && !in_parser_context(NVRAM) { while (!in_parser_context(NVRAM) && $0 ~ "}") { parser_state_close_block(); } next } # Report unbalanced '}' /}/ && in_parser_context(NVRAM) { error("extra '}'") } # Invalid variable type $1 && in_parser_context(SymbolContext) { error("unknown type '" $1 "'") } # Generic parse failure { error("unrecognized statement") } # Create a class instance with the given name function class_new(name, superclass, _class) { if (_class != null) errorx("class_get() must be called with one or two arguments") # Look for an existing class instance if (name in _g_class_names) errorx("redefining class: " name) # Create and register the class object _class = obj_new(superclass) _g_class_names[name] = _class _g_obj[_class,OBJ_IS_CLS] = 1 _g_obj[_class,CLS_NAME] = name return (_class) } # Return the class instance with the given name function class_get(name) { if (name in _g_class_names) return (_g_class_names[name]) errorx("no such class " name) } # Return the name of cls function class_get_name(cls) { if (cls == null) { warnx("class_get_name() called with null class") return "" } if (!obj_is_class(cls)) errorx(cls " is not a class object") return (_g_obj[cls,CLS_NAME]) } # Return true if the given property property ID is defined on class function class_has_prop_id(class, prop_id, _super) { if (_super != null) errorx("class_has_prop_id() must be called with two arguments") if (class == null) return (0) + if (prop_id == null) + return (0) + # Check class<->prop cache if ((class, prop_id) in _g_class_prop_cache) return (1) # Otherwise, slow path if (!obj_is_class(class)) errorx(class " is not a class object") if (_super != null) errorx("class_has_prop_id() must be called with two arguments") for (_super = class; _super != null; _super = obj_get_class(_super)) { if (!((_super,CLS_PROP,prop_id) in _g_obj)) continue # Found; add to class<->prop cache _g_class_prop_cache[class,prop_id] = 1 return (1) } return (0) } # Return true if the given property prop is defined on class function class_has_property(class, prop) { if (!(PROP_ID in prop)) return (0) return (class_has_prop_id(class, prop[PROP_ID])) } # Define a `prop` on `class` with the given `name` string function class_add_prop(class, prop, name, _prop_id) { if (_prop_id != null) errorx("class_add_prop() must be called with three arguments") # Check for duplicate property definition if (class_has_property(class, prop)) errorx("property " prop[PROP_NAME] " already defined on " \ class_get_name(class)) # Init property IDs if (_g_prop_ids == null) _g_prop_ids = 1 # Get (or create) new property entry if (name in _g_prop_names) { _prop_id = _g_prop_names[name] } else { _prop_id = _g_prop_ids++ _g_prop_names[name] = _prop_id _g_props[_prop_id] = name prop[PROP_NAME] = name prop[PROP_ID] = _prop_id } # Add to class definition _g_obj[class,CLS_PROP,prop[PROP_ID]] = name return (name) } # Return the property ID for a given class-defined property function class_get_prop_id(class, prop) { if (class == null) errorx("class_get_prop_id() on null class") if (!class_has_property(class, prop)) { errorx("requested undefined property '" prop[PROP_NAME] "on " \ class_get_name(class)) } return (prop[PROP_ID]) } # Return the property ID for a given class-defined property name function class_get_named_prop_id(class, name, _prop_id) { if (class == null) errorx("class_get_prop_id() on null class") if (!(name in _g_prop_names)) errorx("requested undefined property '" name "'") _prop_id = _g_prop_names[name] if (!class_has_prop_id(class, _prop_id)) { errorx("requested undefined property '" _g_props[_prop_id] \ "' on " class_get_name(class)) } return (_prop_id) } # Create a new instance of the given class function obj_new(class, _obj) { if (_obj != null) errorx("obj_new() must be called with one argument") if (_g_obj_ids == null) _g_obj_ids = 1 # Assign ID and set superclass _obj = _g_obj_ids++ _g_obj[_obj,OBJ_SUPER] = class return (_obj) } # obj_delete() support for Map instances function _obj_delete_map(obj, _prefix, _key) { obj_assert_class(obj, Map) _prefix = "^" obj SUBSEP for (_key in _g_maps) { if (!match(_key, _prefix) && _key != obj) continue delete _g_maps[_key] } } # obj_delete() support for Array instances function _obj_delete_array(obj, _size, _i) { obj_assert_class(obj, Array) _size = array_size(obj) for (_i = 0; _i < _size; _i++) delete _g_arrays[obj,OBJ_PROP,_i] } # Destroy all metadata associated with the given object function obj_delete(obj, _prop_id, _prop_name, _prefix, _key, _size, _i) { if (obj_is_class(obj)) errorx("cannot delete class objects") # Handle classes that use external global array storage # for effeciency if (obj_is_instanceof(obj, Map)) { _obj_delete_map(obj) } else if (obj_is_instanceof(obj, Array)) { _obj_delete_array(obj) } # Delete all object properties for (_prop_name in _g_prop_names) { if (!obj_has_prop_id(obj, _prop_id)) continue _prop_id = _g_prop_names[_prop_name] delete _g_obj[obj,OBJ_PROP,_prop_id] delete _g_obj_nr[obj,OBJ_PROP,_prop_id] } # Delete instance state delete _g_obj[obj,OBJ_IS_CLS] delete _g_obj[obj,OBJ_SUPER] } # Print an object's unique ID, class, and properties to # stdout function obj_dump(obj, _pname, _prop_id, _prop_val) { print(class_get_name(obj_get_class(obj)) "<" obj ">:") # Dump all properties for (_pname in _g_prop_names) { _prop_id = _g_prop_names[_pname] if (!obj_has_prop_id(obj, _prop_id)) continue _prop_val = prop_get(obj, _prop_id) printf("\t%s: %s\n", _pname, _prop_val) } } # Return true if obj is a class object function obj_is_class(obj) { return (_g_obj[obj,OBJ_IS_CLS] == 1) } # Return the class of obj, if any. function obj_get_class(obj) { if (obj == null) errorx("obj_get_class() on null object") return (_g_obj[obj,OBJ_SUPER]) } # Return true if obj is an instance of the given class function obj_is_instanceof(obj, class, _super) { if (_super != null) errorx("obj_is_instanceof() must be called with two arguments") if (!obj_is_class(class)) errorx(class " is not a class object") if (obj == null) { errorx("obj_is_instanceof() called with null obj (class " \ class_get_name(class) ")") } for (_super = obj_get_class(obj); _super != null; _super = obj_get_class(_super)) { if (_super == class) return (1) } return (0) } # Default object shallow equality implementation. Returns true if the two # objects share a common superclass and have identity equality across all defined # properties. function obj_trivially_equal(lhs, rhs, _class, _pname, _prop_id) { # Simple case if (lhs == rhs) return (1) # Must share a common superclass _class = obj_get_class(lhs) if (_class != obj_get_class(rhs)) return (0) # Compare all properties _prop_count = 0 for (_pname in _g_prop_names) { _prop_id = _g_prop_names[_pname] if (!class_has_prop_id(_class, _prop_id)) continue if (prop_get(lhs, _prop_id) != prop_get(rhs, _prop_id)) return (0) } # All properties are trivially equal return (1) } # Return a debug string representation of an object's unique ID, class, and # properties function obj_to_string(obj, _pname, _prop_id, _prop_val, _prop_count, _result) { _result = class_get_name(obj_get_class(obj)) "<" obj ">: { " # Fetch all properties _prop_count = 0 for (_pname in _g_prop_names) { _prop_id = _g_prop_names[_pname] if (!obj_has_prop_id(obj, _prop_id)) continue if (_prop_count >= 0) _result = _result ", " _result = _result sprintf("\t%s: %s\n", _pname, _prop_val) _prop_count++ } return (_result " }") } # Assert that obj is an instance of the given class function obj_assert_class(obj, class) { if (!obj_is_instanceof(obj, class)) { errorx(class_get_name(obj_get_class(obj)) "<" obj "> is not " \ "an instance of " class_get_name(class)) } } # Return true if the given property prop is defined by the object's superclass function obj_has_property(obj, prop, _class) { if (obj == null) errorx("obj_has_property() on null object") _class = obj_get_class(obj) return (class_has_property(_class, prop)) } # Return true if the given property ID is defined by the object's superclass function obj_has_prop_id(obj, prop_id, _class) { if (obj == null) errorx("obj_has_prop_id() on null object") _class = obj_get_class(obj) return (class_has_prop_id(_class, prop_id)) } # Return the line (NR) at which a given property ID was set on the object # Will throw an error if the property has not been set on obj function obj_get_prop_id_nr(obj, prop_id) { if (obj == null) errorx("obj_get_prop_id_nr() on null object") if (!obj_has_prop_id(obj, prop_id)) { errorx("requested undefined property '" _g_props[prop_id] \ "' (" prop_id ") on " obj_to_string(obj)) } # Fetch NR if ((obj,OBJ_PROP,prop_id) in _g_obj_nr) return (_g_obj_nr[obj,OBJ_PROP,prop_id]) errorx("property '" _g_props[prop_id] "' (" prop_id ") not " \ "previously set on " obj_to_string(obj)) } # Return the line (NR) at which a given property was set on the object # Will throw an error if the property has not been set on obj function obj_get_prop_nr(obj, prop) { return (obj_get_prop_id_nr(obj, prop[PROP_ID])) } # Return an abstract property ID for a given property function obj_get_prop_id(obj, prop) { if (obj == null) errorx("obj_get_prop_id() on null object") return (class_get_prop_id(obj_get_class(obj), prop)) } # Return the property ID for a given property name function obj_get_named_prop_id(obj, name) { if (obj == null) errorx("obj_get_named_prop_id() on null object") return (class_get_named_prop_id(obj_get_class(obj), name)) } # Set a property on obj function set(obj, prop, value, _class) { return (prop_set(obj, prop[PROP_ID], value)) } # Get a property value defined on obj function get(obj, prop, _class) { return (prop_get(obj, prop[PROP_ID])) } # Set a property on obj, using a property ID returned by obj_get_prop_id() or # class_get_prop_id() function prop_set(obj, prop_id, value, _class) { if (obj == null) { errorx("setting property '" _g_props[prop_id] \ "' on null object") } _class = obj_get_class(obj) if (_class == null) errorx(obj " has no superclass") if (!class_has_prop_id(_class, prop_id)) { errorx("requested undefined property '" _g_props[prop_id] \ "' (" prop_id ") on " class_get_name(_class)) } # Track the line on which the property was set _g_obj_nr[obj,OBJ_PROP,prop_id] = NR _g_obj[obj,OBJ_PROP,prop_id] = value } # Convert a property ID to a property path. function prop_id_to_path(prop_id) { if (!(prop_id in _g_props)) errorx("'" prop_id "' is not a property ID") # Convert to path string representation return (""prop_id) } # Convert a property to a property path. function prop_to_path(prop) { if (!(PROP_ID in prop)) errorx("prop_to_path() called with non-property head") return (prop_id_to_path(prop[PROP_ID])) } # Create a property path from head and tail properties # Additional properties may be appended via prop_path_append() or # prop_path_append_id() function prop_path_create(head, tail) { if (!(PROP_ID in head)) errorx("prop_path() called with non-property head") if (!(PROP_ID in tail)) errorx("prop_path() called with non-property tail") return (head[PROP_ID] SUBSEP tail[PROP_ID]) } # Append a property to the given property path function prop_path_append(path, tail) { if (!(PROP_ID in tail)) errorx("prop_path_append() called with non-property tail") return (prop_path_append_id(path, tail[PROP_ID])) } # Append a property ID to the given property path function prop_path_append_id(path, tail_id) { if (!(tail_id in _g_props)) errorx("'" tail_id "' is not a property ID") return (path SUBSEP tail_id) } # Fetch a value from obj using a property path previously returned by # prop_path_create(), prop_to_path(), etc. function prop_get_path(obj, prop_path, _class, _prop_ids, _nprop_ids, _next, _prop_head, _prop_len, _prop_tail) { if (obj == null) { errorx("requested property path '" \ gsub(SUBSEP, ".", prop_path) "' on null object") } # Try the cache first _class = obj_get_class(obj) if ((_class,prop_path,PPATH_HEAD) in _g_ppath_cache) { _prop_head = _g_ppath_cache[_class,prop_path,PPATH_HEAD] _next = prop_get(obj, _prop_head) if ((_class,prop_path,PPATH_TAIL) in _g_ppath_cache) { _prop_tail = _g_ppath_cache[_class,prop_path,PPATH_TAIL] return (prop_get_path(_next, _prop_tail)) } return (_next) } # Parse the head/tail of the property path and add to cache _nprop_ids = split(prop_path, _prop_ids, SUBSEP) if (_nprop_ids == 0) errorx("empty property path") _prop_head = _prop_ids[1] _g_ppath_cache[_class,prop_path,PPATH_HEAD] = _prop_head if (_nprop_ids > 1) { _prop_len = length(_prop_head) _prop_tail = substr(prop_path, _prop_len+2) # Add to cache _g_ppath_cache[_class,prop_path,PPATH_TAIL] = _prop_tail } # Recursively call out implementation, this time fetching from # cache return (prop_get_path(obj, prop_path)) } # Fetch a value property value from obj, using a property ID returned by # obj_get_prop_id() or class_get_prop_id() function prop_get(obj, prop_id, _class) { if (obj == null) { errorx("requested property '" _g_props[prop_id] \ "' on null object") } _class = obj_get_class(obj) if (_class == null) errorx(obj " has no superclass") if (!class_has_prop_id(_class, prop_id)) { errorx("requested undefined property '" _g_props[prop_id] \ "' (" prop_id ") on " class_get_name(_class)) } return (_g_obj[obj,OBJ_PROP,prop_id]) } # Create a new MacroType instance function macro_type_new(name, const_suffix, _obj) { _obj = obj_new(MacroType) set(_obj, p_name, name) set(_obj, p_const_suffix, const_suffix) return (_obj) } # Create a new MacroDefine instance function macro_new(name, value, _obj) { _obj = obj_new(MacroDefine) set(_obj, p_name, name) set(_obj, p_value, value) return (_obj) } # Create an empty array; this uses _g_arrays to store integer # keys/values under the object's property prefix. function array_new(_obj) { _obj = obj_new(Array) set(_obj, p_count, 0) return (_obj) } # Return the number of elements in the array function array_size(array) { obj_assert_class(array, Array) return (get(array, p_count)) } # Return true if the array is empty function array_empty(array) { return (array_size(array) == 0) } # Append a value to the array function array_append(array, value, _i) { obj_assert_class(array, Array) _i = get(array, p_count) _g_arrays[array,OBJ_PROP,_i] = value set(array, p_count, _i+1) } # Set an array value # An error will be thrown if the idx is outside array bounds function array_set(array, idx, value) { obj_assert_class(array, Array) if (!((array,OBJ_PROP,idx) in _g_arrays)) errorx(idx " out of range of array " obj_to_string(array)) _g_arrays[array,OBJ_PROP,idx] = value } # Return value at the given index from the array # An error will be thrown if 'idx' is outside the array bounds function array_get(array, idx) { obj_assert_class(array, Array) if (!((array,OBJ_PROP,idx) in _g_arrays)) errorx(idx " out of range of array " obj_to_string(array)) return (_g_arrays[array,OBJ_PROP,idx]) } # # Sort an array, using standard awk comparison operators over its values. # # If `prop_path` is non-NULL, the corresponding property path (or property ID) # will be fetched from each array element and used as the sorting value. # function array_sort(array, prop_path, _size) { obj_assert_class(array, Array) _size = array_size(array) if (_size <= 1) return _qsort(array, prop_path, 0, _size-1) } function _qsort_get_key(array, idx, prop_path, _v) { _v = array_get(array, idx) if (prop_path == null) return (_v) return (prop_get_path(_v, prop_path)) } function _qsort(array, prop_path, first, last, _qpivot, _qpivot_val, _qleft, _qleft_val, _qright, _qright_val) { if (first >= last) return # select pivot element _qpivot = int(first + int((last-first+1) * rand())) _qleft = first _qright = last _qpivot_val = _qsort_get_key(array, _qpivot, prop_path) # partition while (_qleft <= _qright) { while (_qsort_get_key(array, _qleft, prop_path) < _qpivot_val) _qleft++ while (_qsort_get_key(array, _qright, prop_path) > _qpivot_val) _qright-- # swap if (_qleft <= _qright) { _qleft_val = array_get(array, _qleft) _qright_val = array_get(array, _qright) array_set(array, _qleft, _qright_val) array_set(array, _qright, _qleft_val) _qleft++ _qright-- } } # sort the partitions _qsort(array, prop_path, first, _qright) _qsort(array, prop_path, _qleft, last) } # # Join all array values with the given separator # # If `prop_path` is non-NULL, the corresponding property path (or property ID) # will be fetched from each array value and included in the result, rather than # immediate array value # function array_join(array, sep, prop_path, _i, _size, _value, _result) { obj_assert_class(array, Array) _result = "" _size = array_size(array) for (_i = 0; _i < _size; _i++) { # Fetch the value (and optionally, a target property) _value = array_get(array, _i) if (prop_path != null) _value = prop_get_path(_value, prop_path) if (_i+1 < _size) _result = _result _value sep else _result = _result _value } return (_result) } # Return the first value in the array, or null if empty function array_first(array) { obj_assert_class(array, Array) if (array_size(array) == 0) return (null) else return (array_get(array, 0)) } # Return the last value in the array, or null if empty function array_tail(list, _size) { obj_assert_class(array, Array) _size = array_size(array) if (_size == 0) return (null) else return (array_get(array, _size-1)) } # Create an empty hash table; this uses the _g_maps array to store arbitrary # keys/values under the object's property prefix. function map_new(_obj) { _obj = obj_new(Map) return (_obj) } # Add `key` with `value` to `map` function map_set(map, key, value) { obj_assert_class(map, Map) _g_maps[map,OBJ_PROP,key] = value } # Remove `key` from the map function map_remove(map, key) { obj_assert_class(map, Map) delete _g_maps[map,OBJ_PROP,key] } # Return true if `key` is found in `map`, false otherwise function map_contains(map, key) { obj_assert_class(map, Map) return ((map,OBJ_PROP,key) in _g_maps) } # Fetch the value of `key` from the map. Will throw an error if the # key does not exist function map_get(map, key) { obj_assert_class(map, Map) return _g_maps[map,OBJ_PROP,key] } # Create and return a new list containing all defined values in `map` function map_to_array(map, _key, _prefix, _values) { obj_assert_class(map, Map) _values = array_new() _prefix = "^" map SUBSEP OBJ_PROP SUBSEP for (_key in _g_maps) { if (!match(_key, _prefix)) continue array_append(_values, _g_maps[_key]) } return (_values) } # Create a new Type instance function type_new(name, width, signed, constant, array_constant, fmt, mask, constant_value, array_constant_value, _obj) { obj_assert_class(fmt, Fmt) _obj = obj_new(Type) set(_obj, p_name, name) set(_obj, p_width, width) set(_obj, p_signed, signed) set(_obj, p_const, constant) set(_obj, p_const_val, constant_value) set(_obj, p_array_const, array_constant) set(_obj, p_array_const_val, array_constant_value) set(_obj, p_default_fmt, fmt) set(_obj, p_mask, mask) return (_obj) } # Return true if two types are equal function type_equal(lhs, rhs) { # Simple case if (lhs == rhs) return (1) # Must share a common class if (obj_get_class(lhs) != obj_get_class(rhs)) return (0) # Handle ArrayType equality if (obj_is_instanceof(lhs, ArrayType)) { # Size must be equal if (get(lhs, p_count) != get(rhs, p_count)) return (0) # The base types must be equal return (type_equal(type_get_base(lhs), type_get_base(rhs))) } # Handle Type equality -- we just check for trivial identity # equality of all members obj_assert_class(lhs, Type) return (obj_trivially_equal(lhs, rhs)) } # Return the type's default value mask. If the type is an array type, # the default mask of the base type will be returned. function type_get_default_mask(type) { if (obj_is_instanceof(type, ArrayType)) return (type_get_default_mask(type_get_base(type))) obj_assert_class(type, Type) return (get(type, p_mask)) } # Return the type's C constant representation function type_get_const(type) { if (obj_is_instanceof(type, ArrayType)) return (get(type_get_base(type), p_array_const)) obj_assert_class(type, Type) return (get(type, p_const)) } # Return the type's C constant integer value function type_get_const_val(type) { if (obj_is_instanceof(type, ArrayType)) return (get(type_get_base(type), p_array_const_val)) obj_assert_class(type, Type) return (get(type, p_const_val)) } # Return an array type's element count, or 1 if the type is not # an array type function type_get_nelem(type) { if (obj_is_instanceof(type, ArrayType)) return (get(type, p_count)) obj_assert_class(type, Type) return (1) } # Return the base type for a given type instance. function type_get_base(type) { if (obj_is_instanceof(type, ArrayType)) return (type_get_base(get(type, p_type))) obj_assert_class(type, Type) return (type) } # Return the default fmt for a given type instance -function type_get_default_fmt(type, _base) { +function type_get_default_fmt(type, _base, _fmt, _array_fmt) { _base = type_get_base(type) - return (get(_base, p_default_fmt)) + _fmt = get(_base, p_default_fmt) + + if (obj_is_instanceof(type, ArrayType)) { + _array_fmt = get(_fmt, p_array_fmt) + if (_array_fmt != null) + _fmt = _array_fmt + } + + return (_fmt) } # Return a string representation of the given type function type_to_string(type, _base_type) { if (obj_is_instanceof(type, ArrayType)) { _base_type = type_get_base(type) return (type_to_string(_base_type) "[" get(type, p_count) "]") } return get(type, p_name) } # Return true if type `rhs` is can be coerced to type `lhs` without data # loss function type_can_represent(lhs, rhs) { # Must be of the same class (Type or ArrayType) if (obj_get_class(lhs) != obj_get_class(rhs)) return (0) if (obj_is_instanceof(lhs, ArrayType)) { # The base types must have a representable relationship if (!type_can_represent(type_get_base(lhs), type_get_base(rhs))) return (0) # The lhs type must be able to represent -at least- as # many elements as the RHS type if (get(lhs, p_count) < get(rhs, p_count)) return (0) return (1) } # A signed type could represent the full range of a smaller unsigned # type, but we don't bother; the two should agree when used in a SROM # layout. Instead simply assert that both are signed or unsigned. if (get(lhs, p_signed) != get(rhs, p_signed)) return (0) # The `rhs` type must be equal or smaller in width to the `lhs` type if (get(lhs, p_width) < get(rhs, p_width)) return (0) return (1) } # Create a new ArrayType instance function array_type_new(type, count, _obj) { _obj = obj_new(ArrayType) set(_obj, p_type, type) set(_obj, p_count, count) return (_obj) } # # Parse a type string to either the Type, ArrayType, or null if # the type is not recognized. # function parse_type_string(str, _base, _count) { if (match(str, ARRAY_REGEX"$") > 0) { # Extract count and base type _count = substr(str, RSTART+1, RLENGTH-2) sub(ARRAY_REGEX"$", "", str) # Look for base type if ((_base = type_named(str)) == null) return (null) return (array_type_new(_base, int(_count))) } else { return (type_named(str)) } } # # Parse a variable name in the form of 'name' or 'name[len]', returning # either the provided base_type if no array specifiers are found, or # the fully parsed ArrayType. # function parse_array_type_specifier(str, base_type, _count) { if (match(str, ARRAY_REGEX"$") > 0) { # Extract count _count = substr(str, RSTART+1, RLENGTH-2) return (array_type_new(base_type, int(_count))) } else { return (base_type) } } # Return the type constant for `name`, if any function type_named(name, _n, _type) { if (name == null) errorx("called type_named() with null name") if (map_contains(BaseTypes, name)) return (map_get(BaseTypes, name)) return (null) } # Create a new Fmt instance -function fmt_new(name, symbol, _obj) { +function fmt_new(name, symbol, array_fmt, _obj) { _obj = obj_new(Fmt) set(_obj, p_name, name) set(_obj, p_symbol, symbol) + + if (array_fmt != null) + set(_obj, p_array_fmt, array_fmt) return (_obj) } # Return the Fmt constant for `name`, if any function fmt_named(name, _n, _fmt) { if (map_contains(ValueFormats, name)) return (map_get(ValueFormats, name)) return (null) } # Create a new VFlag instance function vflag_new(name, constant, _obj) { _obj = obj_new(VFlag) set(_obj, p_name, name) set(_obj, p_const, constant) return (_obj) } # Create a new StringConstant AST node function stringconstant_new(value, continued, _obj) { _obj = obj_new(StringConstant) set(_obj, p_value, value) set(_obj, p_continued, continued) set(_obj, p_line, NR) return (_obj) } # Create an empty StringConstant AST node to which additional lines # may be appended function stringconstant_empty(_obj) { return (stringconstant_new("", 1)) } # Parse an input string and return a new string constant # instance function stringconstant_parse_line(line, _obj) { _obj = stringconstant_empty() stringconstant_append_line(_obj, line) return (_obj) } # Parse and apend an additional line to this string constant function stringconstant_append_line(str, line, _cont, _strbuf, _regex, _eol) { obj_assert_class(str, StringConstant) # Must be marked for continuation if (!get(str, p_continued)) { errorx("can't append to non-continuation string '" \ get(str, p_value) "'") } _strbuf = get(str, p_value) # If start of string, look for (and remove) initial double quote if (_strbuf == null) { _regex = "^[ \t]*\"" if (!sub(_regex, "", line)) { error("expected quoted string") } } # Look for a terminating double quote _regex = "([^\"\\\\]*(\\\\.[^\"\\\\]*)*)\"" _eol = match(line, _regex) if (_eol > 0) { # Drop everything following the terminating quote line = substr(line, 1, RLENGTH-1) _cont = 0 } else { # No terminating quote found, continues on next line _cont = 1 } # Trim leading and trailing whitespace sub(/(^[ \t]+|[ \t]+$)/, "", line) # Append to existing buffer if ((_strbuf = get(str, p_value)) == NULL) set(str, p_value, line) else set(str, p_value, _strbuf " " line) # Update line continuation setting set(str, p_continued, _cont) } # Create a new RevRange instance function revrange_new(start, end, _obj) { _obj = obj_new(RevRange) set(_obj, p_start, start) set(_obj, p_end, end) set(_obj, p_line, NR) return (_obj) } # Return true if the two revision ranges are equal function revrange_equal(lhs, rhs) { if (get(lhs, p_start) != get(rhs, p_start)) return (0) if (get(lhs, p_end) != get(rhs, p_end)) return (0) return (1) } # Return true if the requested rev is covered by revrange, false otherwise function revrange_contains(range, rev) { obj_assert_class(range, RevRange) if (rev < get(range, p_start)) return (0) else if (rev > get(range, p_end)) { return (0) } else { return (1) } } # # Return a string representation of the given revision range # function revrange_to_string(revs, _start, _end) { obj_assert_class(revs, RevRange) _start = get(revs, p_start) _end = get(revs, p_end) if (_start == 0) return ("<= " _end) else if (_end == REV_MAX) return (">= " _start) else return (_start "-" _end) } # Create a new VarGroup instance function var_group_new(name, _obj) { _obj = obj_new(VarGroup) set(_obj, p_name, name) set(_obj, p_vars, array_new()) set(_obj, p_line, NR) return (_obj) } # Create a new NVRAM instance function nvram_new(_obj, _vars, _v) { _obj = obj_new(NVRAM) _vars = array_new() set(_obj, p_vars, _vars) set(_obj, p_var_groups, array_new()) set(_obj, p_srom_layouts, array_new()) set(_obj, p_srom_table, map_new()) # # Register our implicit variable definitions # # SROM signature offset _v = var_new(VAccessInternal, "", UInt16) array_append(_vars, _v) _g_var_names[get(_v, p_name)] = _v # SROM CRC8 offset _v = var_new(VAccessInternal, "", UInt8) array_append(_vars, _v) _g_var_names[get(_v, p_name)] = _v return (_obj) } # Register a new SROM layout instance # An error will be thrown if the layout overlaps any revisions covered # by an existing instance. function nvram_add_srom_layout(nvram, layout, _table, _revs, _start, _end, _i) { obj_assert_class(nvram, NVRAM) obj_assert_class(layout, SromLayout) # revision:layout hash table _table = get(nvram, p_srom_table) # register the layout's revisions _revs = get(layout, p_revisions) _start = get(_revs, p_start) _end = get(_revs, p_end) for (_i = _start; _i <= _end; _i++) { if (map_contains(_table, _i)) { error("SROM layout redeclares layout for revision '" \ _i "' (originally declared on line " \ get(map_get(_table, _i), p_line) ")") } map_set(_table, _i, layout) } # append to srom_layouts array_append(get(nvram, p_srom_layouts), layout) } # Return the first SROM layout registered for a given SROM revision, # or null if no matching layout is found function nvram_get_srom_layout(nvram, revision, _layouts, _nlayouts, _layout, _i) { obj_assert_class(nvram, NVRAM) _layouts = get(nvram, p_srom_layouts) _nlayouts = array_size(_layouts) for (_i = 0; _i < _nlayouts; _i++) { _layout = array_get(_layouts, _i) if (srom_layout_has_rev(_layout, revision)) return (_layout) } # Not found return (null) } # Create a new Var instance function var_new(access, name, type, _obj) { obj_assert_class(access, VAccess) # Validate the variable identifier # # The access modifier dictates the permitted identifier format. # VAccessInternal: # VAccess(Public|Private): ident if (access != VAccessInternal && name ~ SVAR_IDENT_REGEX) { error("invalid identifier '"name"'; did you mean to " \ "mark this variable as internal?") } else if (access == VAccessInternal) { if (name !~ SVAR_IDENT_REGEX) error("invalid identifier '"name"' for internal " \ "variable; did you mean '<" name ">'?") } else if (name !~ VAR_IDENT_REGEX) { error("invalid identifier '"name"'") } _obj = obj_new(Var) set(_obj, p_access, access) set(_obj, p_name, name) set(_obj, p_type, type) set(_obj, p_line, NR) return (_obj) } # Return true if var is internal-only, and should not be included # in any output (e.g. has an access specifier of VAccessInternal). function var_is_internal(var) { return (get(var, p_access) == VAccessInternal) } # Return true if `var` has an array type function var_has_array_type(var, _vtype) { obj_assert_class(var, Var) _vtype = get(var, p_type) return (obj_is_instanceof(_vtype, ArrayType)) } # Return the number of array elements defined by this variable's type, # or 1 if the variable does not have an array type. function var_get_array_len(var) { obj_assert_class(var, Var) return (type_get_nelem(get(var, p_type))) } # Return the fmt for var. If not explicitly set on var, will return then # return of calling type_get_default_fmt() with the variable's type function var_get_fmt(var, _fmt) { obj_assert_class(var, Var) # If defined on var, return it if ((_fmt = get(var, p_fmt)) != null) return (_fmt) # Fall back on the type's default return (type_get_default_fmt(get(var, p_type))) } # Return a new MacroDefine instance for the given variable, macro type, # and value function var_get_macro(var, macro_type, value, _macro) { obj_assert_class(var, Var) obj_assert_class(macro_type, MacroType) return (macro_new(var_get_macro_name(var, macro_type), value)) } # Return the preprocessor constant name to be used with `var` for the given # macro_type function var_get_macro_name(var, macro_type, _var_name, _suffix) { obj_assert_class(var, Var) obj_assert_class(macro_type, MacroType) _var_name = get(var, p_name) _suffix = get(macro_type, p_const_suffix) return("BHND_NVAR_" toupper(_var_name) _suffix) } # Create a new SromLayout instance function srom_layout_new(rev_desc, _obj) { _obj = obj_new(SromLayout) set(_obj, p_revisions, rev_desc) set(_obj, p_entries, array_new()) set(_obj, p_revmap, map_new()) set(_obj, p_output_var_counts, map_new()) set(_obj, p_line, NR) return (_obj) } # Register a new entry with the srom layout function srom_layout_add_entry(layout, entry, _revmap, _name, _rev_start, _rev_end, _var, _prev_entry, _count, _i) { obj_assert_class(layout, SromLayout) obj_assert_class(entry, SromEntry) _layout_revmap = get(layout, p_revmap) _layout_var_count = get(layout, p_output_var_counts) _var = get(entry, p_var) _name = get(_var, p_name) # Add to revision array array_append(get(layout, p_entries), entry) # Add to the revision map tables _rev_start = get(get(entry, p_revisions), p_start) _rev_end = get(get(entry, p_revisions), p_end) for (_i = _rev_start; _i <= _rev_end; _i++) { # Check for existing entry _prev_entry = srom_layout_find_entry(layout, _name, _i) if (_prev_entry != null) { error("redefinition of variable '" _name "' for SROM " \ "revision " _i " (previously defined on line " \ get(_prev_entry, p_line) ")") } # Add to the (varname,revision) map map_set(_layout_revmap, (_name SUBSEP _i), entry) # If an output variable, set or increment the output variable # count if (!srom_entry_should_output(entry, _i)) continue if (!map_contains(_layout_var_count, _i)) { map_set(_layout_var_count, _i, 1) } else { _count = map_get(_layout_var_count, _i) map_set(_layout_var_count, _i, _count + 1) } } } # Return the variable name to be used when emitting C declarations # for this SROM layout # # The name is gauranteed to be unique across SROM layouts with non-overlapping # revision ranges function srom_layout_get_variable_name(layout, _revs) { obj_assert_class(layout, SromLayout) _revs = get(layout, p_revisions) return ("bhnd_sprom_layout_r" get(_revs, p_start) \ "_r" get(_revs, p_end)) } # Return true if the given SROM revision is defined by the layout, false # otherwise function srom_layout_has_rev(layout, rev) { obj_assert_class(layout, SromLayout) return (revrange_contains(get(layout, p_revisions), rev)) } # Return the total number of output variables (variables to be included # in the SROM layout bindings) for the given SROM revision function srom_layout_num_output_vars(layout, rev, _counts) { obj_assert_class(layout, SromLayout) _counts = get(layout, p_output_var_counts) if (!map_contains(_counts, rev)) return (0) return (map_get(_counts, rev)) } # Return the SromEntry defined for the given variable name and SROM revision, # or null if none function srom_layout_find_entry(layout, vname, revision, _key, _srom_revmap) { obj_assert_class(layout, SromLayout) _srom_revmap = get(layout, p_revmap) # SromEntry are mapped by name,revision composite keys _key = vname SUBSEP revision if (!map_contains(_srom_revmap, _key)) return (null) return (map_get(_srom_revmap, _key)) } # Create a new SromLayoutFilter instance, checking that `revs` # falls within the parent's revision range function srom_layout_filter_new(parent, revs, _obj, _start, _end, _parent_revs) { obj_assert_class(parent, SromLayout) obj_assert_class(revs, RevRange) # Fetch our parent's revision range, confirm that we're # a strict subset _start = get(revs, p_start) _end = get(revs, p_end) _parent_revs = get(parent, p_revisions) if (!revrange_contains(_parent_revs, _start)) error("'" _start "' is outside of parent range") if (!revrange_contains(_parent_revs, _end)) error("'" _end "' is outside of parent range") if (revrange_equal(revs, _parent_revs)) { error("srom range '" revrange_to_string(revs) "' is " \ "identical to parent range of '" \ revrange_to_string(_parent_revs) "'") } # Construct and return new filter instance _obj = obj_new(SromLayoutFilter) set(_obj, p_parent, parent) set(_obj, p_revisions, revs) set(_obj, p_line, NR) return (_obj) } # # Create a new SromEntry instance # # var: The variable referenced by this entry # revisions: The SROM revisions to which this entry applies # base_offset: The SROM entry offset; any relative segment offsets will be # calculated relative to the base offset # type: The SROM's value type; this may be a subtype of the variable # type, and defines the data (width, sign, etc) to be read from # SROM. # function srom_entry_new(var, revisions, base_offset, type, _obj) { obj_assert_class(var, Var) if (revisions != null) obj_assert_class(revisions, RevRange) _obj = obj_new(SromEntry) set(_obj, p_var, var) set(_obj, p_revisions, revisions) set(_obj, p_base_offset, base_offset) set(_obj, p_type, type) set(_obj, p_offsets, array_new()) set(_obj, p_line, NR) return (_obj) } # Return true if the SromEntry has an array type function srom_entry_has_array_type(entry) { obj_assert_class(entry, SromEntry) return (obj_is_instanceof(get(entry, p_type), ArrayType)) } # Return the number of array elements defined by this SromEntry's type, # or 1 if the entry does not have an array type. function srom_entry_get_array_len(entry, _type) { obj_assert_class(entry, SromEntry) return (type_get_nelem(get(entry, p_type))) } # # Return true if the given entry should be included in the output bindings # generated for the given revision, false otherwise. # function srom_entry_should_output(entry, rev, _var, _revs) { obj_assert_class(entry, SromEntry) _var = get(entry, p_var) _revs = get(entry, p_revisions) # Exclude internal variables if (var_is_internal(_var)) return (0) # Exclude inapplicable entry revisions if (!revrange_contains(_revs, rev)) return (0) return (1) } # # Return the single, non-shifted, non-masked offset/segment for the given # SromEntry, or throw an error if the entry contains multiple offsets/segments. # # This is used to fetch special-cased variable definitions that are required # to present a single simple offset. # function srom_entry_get_single_segment(entry, _offsets, _segments, _seg, _base_type, _default_mask) { obj_assert_class(entry, SromEntry) # Fetch the single offset's segment list _offsets = get(entry, p_offsets) if (array_size(_offsets) != 1) errorc(get(entry, p_line), "unsupported offset count") _segments = get(array_first(_offsets), p_segments) if (array_size(_segments) != 1) errorc(get(entry, p_line), "unsupported segment count") # Fetch the single segment _seg = array_first(_segments) _base_type = srom_segment_get_base_type(_seg) _default_mask = get(_base_type, p_mask) # Must not be shifted/masked if (get(_seg, p_shift) != 0) errorc(obj_get_prop_nr(_seg, p_mask), "shift unsupported") if (get(_seg, p_mask) != _default_mask) errorc(obj_get_prop_nr(_seg, p_mask), "mask unsupported") return (_seg) } # Create a new SromOffset instance function srom_offset_new(_obj) { _obj = obj_new(SromOffset) set(_obj, p_segments, array_new()) set(_obj, p_line, NR) return (_obj) } # Return the number of SromSegment instances defined by this offset. function srom_offset_segment_count(offset) { obj_assert_class(offset, SromOffset) return (array_size(get(offset, p_segments))) } # Return the idx'th segment. Will throw an error if idx falls outside # the number of available segments. function srom_offset_get_segment(offset, idx, _segments, _seg) { obj_assert_class(offset, SromOffset) return (array_get(get(offset, p_segments), idx)) } # Create a new SromSegment instance function srom_segment_new(offset, type, mask, shift, value, _obj) { _obj = obj_new(SromSegment) set(_obj, p_offset, offset) set(_obj, p_type, type) set(_obj, p_mask, mask) set(_obj, p_shift, shift) set(_obj, p_value, value) set(_obj, p_line, NR) return (_obj) } # Return true if the segment has an array type function srom_segment_has_array_type(seg, _type) { _type = srom_segment_get_type(seg) return (obj_is_instanceof(_type, ArrayType)) } # Return the array count of the segment, or 1 if the segment does not have # an array type function srom_segment_get_array_len(seg, _type) { if (!srom_segment_has_array_type(seg)) return (1) _type = srom_segment_get_type(seg) return (get(_type, p_count)) } # Return the type of the segment function srom_segment_get_type(seg) { obj_assert_class(seg, SromSegment) return (get(seg, p_type)) } # Return the base type of the segment function srom_segment_get_base_type(seg) { return (type_get_base(srom_segment_get_type(seg))) } # Return true if the two segments have identical types and attributes (i.e. # differing only by offset) function srom_segment_attributes_equal(lhs, rhs) { obj_assert_class(lhs, SromSegment) obj_assert_class(rhs, SromSegment) # type if (!type_equal(get(lhs, p_type), get(rhs, p_type))) return (0) # mask if (get(lhs, p_mask) != get(rhs, p_mask)) return (0) # shift if (get(lhs, p_shift) != get(rhs, p_shift)) return (0) # value if (get(lhs, p_value) != get(rhs, p_value)) return (0) return (1) } # Return a human-readable representation of a Segment instance function segment_to_string(seg, _str, _t, _m, _s, _attrs, _attr_str) { _attrs = array_new() # include type (if specified) if ((_t = get(seg, p_type)) != null) _str = (type_to_string(_t) " ") # include offset _str = (_str sprintf("0x%X", get(seg, p_offset))) # append list of attributes if ((_m = get(seg, p_mask)) != null) array_append(_attrs, ("&" _m)) if ((_s = get(seg, p_shift)) != null) { if (_s > 0) _s = ">>" _s else _s = "<<" _s array_append(_attrs, _s) } _attr_str = array_join(_attrs, ", ") obj_delete(_attrs) if (_attr_str == "") return (_str) else return (_str " (" _attr_str ")") } # return the flag definition for variable `v` function gen_var_flags(v, _type, _flags, _flag, _str) { _num_flags = 0; _type = get(v, p_type) _flags = array_new() # VF_PRIVATE if (get(v, p_access) == VAccessPrivate) array_append(_flags, VFlagPrivate) # VF_IGNALL1 if (get(v, p_ignall1)) array_append(_flags, VFlagIgnoreAll1) # If empty, return empty flag value if (array_size(_flags) == 0) { obj_delete(_flags) return ("0") } # Join all flag constants with | _str = array_join(_flags, "|", class_get_prop_id(VFlag, p_const)) # Clean up obj_delete(_flags) return (_str) } # # Return the absolute value # function abs(i) { return (i < 0 ? -i : i) } # # Return the minimum of two values # function min(lhs, rhs) { return (lhs < rhs ? lhs : rhs) } # # Return the maximum of two values # function max(lhs, rhs) { return (lhs > rhs ? lhs : rhs) } # # Parse a hex string # function parse_hex_string(str, _hex_pstate, _out, _p, _count) { if (!AWK_REQ_HEX_PARSING) return (str + 0) # Populate hex parsing lookup table on-demand if (!("F" in _g_hex_table)) { for (_p = 0; _p < 16; _p++) { _g_hex_table[sprintf("%X", _p)] = _p _g_hex_table[sprintf("%x", _p)] = _p } } # Split input into an array _count = split(toupper(str), _hex_pstate, "") _p = 1 # Skip leading '0x' if (_count >= 2 && _hex_pstate[1] == "0") { if (_hex_pstate[2] == "x" || _hex_pstate[2] == "X") _p += 2 } # Parse the hex_digits _out = 0 for (; _p <= _count; _p++) _out = (_out * 16) + _g_hex_table[_hex_pstate[_p]] return (_out) } # # Return the integer representation of an unsigned decimal, hexadecimal, or # octal string # function parse_uint_string(str) { if (str ~ UINT_REGEX) return (int(str)) else if (str ~ HEX_REGEX) return (parse_hex_string(str)) else error("invalid integer value: '" str "'") } # # Parse an offset string, stripping any leading '+' or trailing ':' or ',' # characters # # +0x0: # 0x0, # ... # function parse_uint_offset(str) { # Drop any leading '+' sub(/^\+/, "", str) # Drop any trailing ':', ',', or '|' sub("[,|:]$", "", str) # Parse the cleaned up string return (parse_uint_string(str)) } # # Print msg to output file, without indentation # function emit_ni(msg) { printf("%s", msg) >> OUTPUT_FILE } # # Print msg to output file, indented for the current `output_depth` # function emit(msg, _ind) { for (_ind = 0; _ind < output_depth; _ind++) emit_ni("\t") emit_ni(msg) } # # Print a warning to stderr # function warn(msg) { print "warning:", msg, "at", FILENAME, "line", NR > "/dev/stderr" } # # Print an warning message without including the source line information # function warnx(msg) { print "warning:", msg > "/dev/stderr" } # # Print a compiler error to stderr with a caller supplied # line number # function errorc(line, msg) { errorx(msg " at " FILENAME " line " line) } # # Print a compiler error to stderr # function error(msg) { errorx(msg " at " FILENAME " line " NR ":\n\t" $0) } # # Print an error message without including the source line information # function errorx(msg) { print "error:", msg > "/dev/stderr" _EARLY_EXIT=1 exit 1 } # # Print a debug output message # function debug(msg, _i) { if (!DEBUG) return for (_i = 1; _i < _g_parse_stack_depth; _i++) printf("\t") > "/dev/stderr" print msg > "/dev/stderr" } # # Advance to the next non-comment input record # function next_line(_result) { do { _result = getline } while (_result > 0 && $0 ~ /^[ \t]*#.*/) # skip comment lines return (_result) } # # Advance to the next input record and verify that it matches @p regex # function getline_matching(regex, _result) { _result = next_line() if (_result <= 0) return (_result) if ($0 ~ regex) return (1) return (-1) } # # Shift the current fields left by `n`. # # If all fields are consumed and the optional do_getline argument is true, # read the next line. # function shiftf(n, do_getline, _i) { if (n > NF) error("shift past end of line") if (n == NF) { # If shifting the entire line, just reset the line value $0 = "" } else { for (_i = 1; _i <= NF-n; _i++) { $(_i) = $(_i+n) } NF = NF - n } if (NF == 0 && do_getline) next_line() } # Push a new parser state. function parser_state_push(ctx, is_block, _state) { _state = obj_new(ParseState) set(_state, p_ctx, ctx) set(_state, p_is_block, is_block) set(_state, p_line, NR) _g_parse_stack_depth++ _g_parse_stack[_g_parse_stack_depth] = _state } # Fetch the current parser state function parser_state_get() { if (_g_parse_stack_depth == 0) errorx("parser_state_get() called with empty parse stack") return (_g_parse_stack[_g_parse_stack_depth]) } # Pop the current parser state function parser_state_pop(_block_state, _closes_block) { if (_g_parse_stack_depth == 0) errorx("parser_state_pop() called with empty parse stack") _closes_block = get(parser_state_get(), p_is_block) delete _g_parse_stack[_g_parse_stack_depth] _g_parse_stack_depth-- if (_closes_block) debug("}") } # Fetch the current context object associated with this parser state # The object will be asserted as being an instance of the given class. function parser_state_get_context(class, _ctx_obj) { _ctx_obj = get(parser_state_get(), p_ctx) obj_assert_class(_ctx_obj, class) return (_ctx_obj) } # Walk the parser state stack until a context object of the given class # is found. If the top of the stack is reached without finding a context object # of the requested type, an error will be thrown. function parser_state_find_context(class, _state, _ctx, _i) { if (class == null) errorx("parser_state_find_context() called with null class") # Find the first context instance inheriting from `class` for (_i = 0; _i < _g_parse_stack_depth; _i++) { _state = _g_parse_stack[_g_parse_stack_depth - _i] _ctx = get(_state, p_ctx) # Check for match if (obj_is_instanceof(_ctx, class)) return (_ctx) } # Not found errorx("no context instance of type '" class_get_name(class) "' " \ "found in parse stack") } # # Find opening brace and push a new parser state for a brace-delimited block. # function parser_state_open_block(ctx) { if ($0 ~ "{" || getline_matching("^[ \t]*{") > 0) { parser_state_push(ctx, 1) sub("^[^{]*{", "", $0) return } error("found '"$1 "' instead of expected '{'") } # # Find closing brace and pop parser states until the first # brace-delimited block is discarded. # function parser_state_close_block(_next_state, _found_block) { if ($0 !~ "}") error("internal error - no closing brace") # pop states until we exit the first enclosing block do { _next_state = parser_state_get() _found_block = get(_next_state, p_is_block) parser_state_pop() } while (!_found_block) # strip everything prior to the block closure sub("^[^}]*}", "", $0) } # Evaluates to true if the current parser state is defined with a context of # the given class function in_parser_context(class, _ctx) { if (class == null) errorx("called in_parser_context() with null class") _ctx = get(parser_state_get(), p_ctx) return (obj_is_instanceof(_ctx, class)) } # # Parse and return a revision range from the current line. # # 4 # 4-10 # revisions 4-10, inclusive # > 4 # < 4 # >= 4 # <= 4 # function parse_revrange(_start, _end, _robj) { _start = 0 _end = 0 if ($2 ~ "[0-9]*-[0-9*]") { split($2, _g_rev_range, "[ \t]*-[ \t]*") _start = int(_g_rev_range[1]) _end = int(_g_rev_range[2]) } else if ($2 ~ "(>|>=|<|<=)" && $3 ~ "[1-9][0-9]*") { if ($2 == ">") { _start = int($3)+1 _end = REV_MAX } else if ($2 == ">=") { _start = int($3) _end = REV_MAX } else if ($2 == "<" && int($3) > 0) { _start = 0 _end = int($3)-1 } else if ($2 == "<=") { _start = 0 _end = int($3)-1 } else { error("invalid revision descriptor") } } else if ($2 ~ "[1-9][0-9]*") { _start = int($2) _end = int($2) } else { error("invalid revision descriptor") } return (revrange_new(_start, _end)) } # # Parse a variable group block starting at the current line # # group "Group Name" { # u8 var_name[10] { # ... # } # ... # } # function parse_variable_group(_ctx, _groups, _group, _group_name) { _ctx = parser_state_get_context(NVRAM) # Seek to the start of the name string shiftf(1) # Parse the first line _group_name = stringconstant_parse_line($0) # Incrementally parse line continuations while (get(_group_name, p_continued)) { getline stringconstant_append_line(_group_name, $0) } debug("group \"" get(_group_name, p_value) "\" {") # Register the new variable group _groups = get(_ctx, p_var_groups) _group = var_group_new(_group_name) array_append(_groups, _group) # Push our variable group block parser_state_open_block(_group) } # # Parse a variable definition block starting at the current line # # u8 var_name[10] { # all1 ignore # desc ... # } # function parse_variable_defn(_ctx, _vaccess, _type, _name, _fmt, _var, _var_list) { _ctx = parser_state_get_context(SymbolContext) # Check for access modifier if ($1 == "private") { _vaccess = VAccessPrivate shiftf(1) } else if ($1 == "internal") { _vaccess = VAccessInternal shiftf(1) } else { _vaccess = VAccessPublic } # Find the base type if ((_type = type_named($1)) == null) error("unknown type '" $1 "'") # Parse (and trim) any array specifier from the variable name _name = $2 _type = parse_array_type_specifier(_name, _type) sub(ARRAY_REGEX"$", "", _name) # Look for an existing variable definition if (_name in _g_var_names) { error("variable identifier '" _name "' previously defined at " \ "line " get(_g_var_names[_name], p_line)) } # Construct new variable instance _var = var_new(_vaccess, _name, _type) debug((_private ? "private " : "") type_to_string(_type) " " _name " {") # Register in global name table _g_var_names[_name] = _var # Add to our parent context _var_list = get(_ctx, p_vars) array_append(_var_list, _var) # Push our variable definition block parser_state_open_block(_var) } # # Return a string containing the human-readable list of valid Fmt names # function fmt_get_human_readable_list(_result, _fmts, _fmt, _nfmts, _i) { # Build up a string listing the valid formats _fmts = map_to_array(ValueFormats) _result = "" _nfmts = array_size(_fmts) for (_i = 0; _i < _nfmts; _i++) { _fmt = array_get(_fmts, _i) if (_i+1 == _nfmts) _result = _result "or " _result = _name_str \ "'" get(_fmt, p_name) "'" if (_i+1 < _nfmts) _result = _result ", " } obj_delete(_fmts) return (_result) } # # Parse a variable parameter from the current line # # fmt (decimal|hex|macaddr|...) # all1 ignore # desc "quoted string" # help "quoted string" # function parse_variable_param(param_name, _var, _vprops, _prop_id, _pval) { _var = parser_state_get_context(Var) if (param_name == "fmt") { debug($1 " " $2) # Check for an existing definition if ((_pval = get(_var, p_fmt)) != null) { error("fmt previously specified on line " \ obj_get_prop_nr(_var, p_fmt)) } # Validate arguments if (NF != 2) { error("'" $1 "' requires a single parameter value of " \ fmt_get_human_readable_list()) } if ((_pval = fmt_named($2)) == null) { error("'" $1 "' value '" $2 "' unrecognized. Must be " \ "one of " fmt_get_human_readable_list()) } # Set fmt reference set(_var, p_fmt, _pval) } else if (param_name == "all1") { debug($1 " " $2) # Check for an existing definition if ((_pval = get(_var, p_ignall1)) != null) { error("all1 previously specified on line " \ obj_get_prop_nr(_var, p_ignall1)) } # Check argument if (NF != 2) error("'" $1 "'requires a single 'ignore' argument") else if ($2 != "ignore") error("unknown "$1" value '"$2"', expected 'ignore'") # Set variable property set(_var, p_ignall1, 1) } else if (param_name == "desc" || param_name == "help") { # Fetch an indirect property reference for either the 'desc' # or 'help' property _prop_id = obj_get_named_prop_id(_var, param_name) # Check for an existing definition if ((_pval = prop_get(_var, _prop_id)) != null) { error(get(_var, p_name) " '" $1 "' redefined " \ "(previously defined on line " \ obj_get_prop_id_nr(_var, _prop_id) ")") } # Seek to the start of the desc/help string shiftf(1) # Parse the first line _pval = stringconstant_parse_line($0) # Incrementally parse line continuations while (get(_pval, p_continued)) { getline stringconstant_append_line(_pval, $0) } debug(param_name " \"" get(_pval, p_value) "\"") # Add to the var object prop_set(_var, _prop_id, _pval) } else { error("unknown variable property type: '" param_name "'") } } # # Parse a top-level SROM layout block starting at the current line # # srom 4-7 { # 0x000: ... # } # function parse_srom_layout(_nvram, _srom_layouts, _revs, _layout) { _nvram = parser_state_get_context(NVRAM) _srom_layouts = get(_nvram, p_srom_layouts) # Parse revision descriptor and register SROM # instance _revs = parse_revrange() _layout = srom_layout_new(_revs) nvram_add_srom_layout(_nvram, _layout) debug("srom " revrange_to_string(_revs) " {") # Push new SROM parser state parser_state_open_block(_layout) } # # Parse a nested srom range filter block starting at the current line # srom 4-7 { # # Filter block # srom 5 { # 0x000: ... # } # } # function parse_srom_layout_filter(_parent, _revs, _filter) { _parent = parser_state_get_context(SromLayout) # Parse revision descriptor _revs = parse_revrange() # Construct the filter (which also validates the revision range) _filter = srom_layout_filter_new(_parent, _revs) debug("srom " revrange_to_string(_revs) " {") # Push new SROM parser state parser_state_open_block(_filter) } # # Parse a SROM offset segment's attribute list from the current line # # # (&0xF0, >>4, =0x5340) # () # # Attribute designators: # &0xF Mask value with 0xF # <<4 Shift left 4 bits # >>4 Shift right 4 bits # =0x53 The parsed value must be equal to this constant value # # May be followed by a | indicating that this segment should be OR'd with the # segment that follows, or a terminating , indicating that a new offset's # list of segments may follow. # function parse_srom_segment_attributes(offset, type, _attrs, _num_attr, _attr, _mask, _shift, _value, _i) { # seek to offset (attributes...) or end of the offset expr (|,) sub("^[^,(|){}]+", "", $0) # defaults _mask = type_get_default_mask(type) _shift = 0 # parse attributes if ($1 ~ "^\\(") { # extract attribute list if (match($0, /\([^|\(\)]*\)/) <= 0) error("expected attribute list") _attrs = substr($0, RSTART+1, RLENGTH-2) # drop attribute list from the input line $0 = substr($0, RSTART+RLENGTH, length($0) - RSTART+RLENGTH) # parse attributes _num_attr = split(_attrs, _g_attrs, ",[ \t]*") for (_i = 1; _i <= _num_attr; _i++) { _attr = _g_attrs[_i] if (sub("^&[ \t]*", "", _attr) > 0) { _mask = parse_uint_string(_attr) } else if (sub("^<<[ \t]*", "", _attr) > 0) { _shift = - parse_uint_string(_attr) } else if (sub("^>>[ \t]*", "", _attr) > 0) { _shift = parse_uint_string(_attr) } else if (sub("^=[ \t]*", "", _attr) > 0) { _value = _attr } else { error("unknown attribute '" _attr "'") } } } return (srom_segment_new(offset, type, _mask, _shift, _value)) } # # Parse a SROM offset's segment declaration from the current line # # +0x0: u8 (&0xF0, >>4) # read 8 bits at +0x0 (relative to srom entry # # offset, apply 0xF0 mask, shift >> 4 # 0x10: u8 (&0xF0, >>4) # identical to above, but perform the read at # # absolute offset 0x10 # # +0x0: u8 # no attributes # 0x10: u8 # # +0x0 # simplified forms denoted by lack of ':'; the # 0x0 # type is inherited from the parent SromEntry # # function parse_srom_segment(base_offset, base_type, _simple, _type, _type_str, _offset, _attrs, _num_attr, _attr, _mask, _shift, _off_desc) { # Fetch the offset value _offset = $1 # Offset string must be one of: # simplified entry: # Provides only the offset, with the type inherited # from the original variable definition # standard entry: : # Provides the offset, followed by a type # # We differentiate the two by looking for (and simultaneously removing) # the trailing ':' if (!sub(/:$/, "", _offset)) _simple = 1 # The offset may either be absolute (e.g. 0x180) or relative (e.g. # +0x01). # # If we find a relative offset definition, we must trim the leading '+' # and then add the base offset if (sub(/^\+/, "", _offset)) { _offset = base_offset + parse_uint_offset(_offset) } else { _offset = parse_uint_offset(_offset) } # If simplified form, use the base type of the SROM entry. Otherwise, # we need to parse the type. if (_simple) { _type = base_type } else { _type_str = $2 sub(/,$/, "", _type_str) # trim trailing ',', if any if ((_type = parse_type_string(_type_str)) == null) error("unknown type '" _type_str "'") } # Parse the trailing (... attributes ...), if any return (parse_srom_segment_attributes(_offset, _type)) } # # Parse a SROM variable entry from the current line # : ... # function parse_srom_variable_entry(_srom, _srom_revs, _rev_start, _rev_end, _srom_entries, _srom_revmap, _prev_entry, _ctx, _base_offset, _name, _stype, _var, _entry, _offset, _seg, _i) { # Fetch our parent context _ctx = parser_state_get_context(SromContext) _srom_revs = get(_ctx, p_revisions) _rev_start = get(_srom_revs, p_start) _rev_end = get(_srom_revs, p_end) # Locate our enclosing layout _srom = parser_state_find_context(SromLayout) _srom_entries = get(_srom, p_entries) _srom_revmap = get(_srom, p_revmap) # Verify argument count if (NF < 3) { error("unrecognized srom entry syntax; must specify at " \ "least \": \"") } # Parse the base offset _base_offset = parse_uint_offset($1) # Parse the base type if ((_stype = type_named($2)) == null) error("unknown type '" $2 "'") # Parse (and trim) any array specifier from the variable name _name = $3 _stype = parse_array_type_specifier(_name, _stype) sub(ARRAY_REGEX"$", "", _name) # Locate the variable definition if (!(_name in _g_var_names)) error("no definition found for variable '" _name "'") _var = _g_var_names[_name] # The SROM entry type must be a subtype of the variable's declared # type if (!type_can_represent(get(_var, p_type), _stype)) { error("'" type_to_string(_stype) "' SROM value cannot be " \ "coerced to '" type_to_string(get(_var, p_type)) " " _name \ "' variable") } # Create and register our new offset entry _entry = srom_entry_new(_var, _srom_revs, _base_offset, _stype) srom_layout_add_entry(_srom, _entry) # Seek to either the block start ('{'), or the attributes to be # used for a single offset/segment entry at `offset` shiftf(3) # Using the block syntax? */ if ($1 == "{") { debug(sprintf("0x%03x: %s %s {", _base_offset, type_to_string(_stype), _name)) parser_state_open_block(_entry) } else { # Otherwise, we're using the simplified syntax -- create and # register our implicit SromOffset _offset = srom_offset_new() array_append(get(_entry, p_offsets), _offset) # Parse and register simplified segment syntax _seg = parse_srom_segment_attributes(_base_offset, _stype) array_append(get(_offset, p_segments), _seg) debug(sprintf("0x%03x: %s %s { %s }", _base_offset, type_to_string(_stype), _name, segment_to_string(_seg))) } } # # Parse all SromSegment entry segments readable starting at the current line # # [,|]? # : [,|]? # : ()[,|]? # function parse_srom_entry_segments(_entry, _base_off, _base_type, _offs, _offset, _segs, _seg, _more_seg, _more_vals) { _entry = parser_state_get_context(SromEntry) _base_off = get(_entry, p_base_offset) _offs = get(_entry, p_offsets) _base_type = get(_entry, p_type) _base_type = type_get_base(_base_type) # Parse all offsets do { # Create a SromOffset _offset = srom_offset_new() _segs = get(_offset, p_segments) array_append(_offs, _offset) # Parse all segments do { _seg = parse_srom_segment(_base_off, _base_type) array_append(_segs, _seg) # Do more segments follow? _more_seg = ($1 == "|") if (_more_seg) shiftf(1, 1) if (_more_seg) debug(segment_to_string(_seg) " |") else debug(segment_to_string(_seg)) } while (_more_seg) # Do more offsets follow? _more_vals = ($1 == ",") if (_more_vals) shiftf(1, 1) } while (_more_vals) } Index: head/sys/modules/bhnd/Makefile =================================================================== --- head/sys/modules/bhnd/Makefile (revision 310296) +++ head/sys/modules/bhnd/Makefile (revision 310297) @@ -1,63 +1,64 @@ # $FreeBSD$ .PATH: ${.CURDIR}/../../dev/bhnd .PATH: ${.CURDIR}/../../dev/bhnd/cores/chipc .PATH: ${.CURDIR}/../../dev/bhnd/cores/chipc/pwrctl .PATH: ${.CURDIR}/../../dev/bhnd/cores/pmu .PATH: ${.CURDIR}/../../dev/bhnd/nvram KMOD= bhnd SRCS= bhnd.c bhnd_subr.c SRCS+= bhnd_bus_if.c bhnd_bus_if.h SRCS+= bhnd_erom.c SRCS+= bhnd_erom_if.c bhnd_erom_if.h # ChipCommon SRCS+= chipc.c chipc_subr.c SRCS+= bhnd_sprom_chipc.c \ bhnd_pmu_chipc.c \ bhnd_pwrctl.c bhnd_pwrctl_subr.c SRCS+= bhnd_chipc_if.c bhnd_chipc_if.h # PMU SRCS+= bhnd_pmu.c \ bhnd_pmu_core.c \ bhnd_pmu_subr.c SRCS+= bhnd_pmu_if.c bhnd_pmu_if.h # NVRAM/SPROM SRCS+= bhnd_nvram_data.c \ bhnd_nvram_data_bcm.c \ bhnd_nvram_data_bcmraw.c \ bhnd_nvram_data_btxt.c \ bhnd_nvram_data_sprom.c \ + bhnd_nvram_data_sprom_subr.c \ bhnd_nvram_data_tlv.c \ bhnd_nvram_io.c \ bhnd_nvram_iobuf.c \ bhnd_nvram_ioptr.c \ bhnd_nvram_iores.c \ bhnd_nvram_plist.c \ bhnd_nvram_store.c \ bhnd_nvram_store_subr.c \ bhnd_nvram_subr.c \ bhnd_nvram_value.c \ bhnd_nvram_value_fmts.c \ bhnd_nvram_value_prf.c \ bhnd_nvram_value_subr.c \ bhnd_sprom.c SRCS+= bhnd_nvram_map.h bhnd_nvram_map_data.h SRCS+= bhnd_nvram_if.c bhnd_nvram_if.h SRCS+= device_if.h bus_if.h SUBDIR= bcma \ bcma_bhndb \ bhndb \ bhndb_pci \ cores \ siba \ siba_bhndb .include .include