diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 256b67975092..26b9c8ae2215 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -1,603 +1,607 @@ # $FreeBSD$ ## ## Kernel ## kern/msi_if.m optional intrng kern/pic_if.m optional intrng kern/subr_devmap.c standard kern/subr_intr.c optional intrng kern/subr_physmem.c standard libkern/memcmp.c standard \ compile-with "${NORMAL_C:N-fsanitize*}" libkern/memset.c standard \ compile-with "${NORMAL_C:N-fsanitize*}" libkern/strlen.c standard libkern/arm64/crc32c_armv8.S standard arm/arm/generic_timer.c standard arm/arm/gic.c standard arm/arm/gic_acpi.c optional acpi arm/arm/gic_fdt.c optional fdt arm/arm/gic_if.m standard arm/arm/pmu.c standard arm/arm/pmu_acpi.c optional acpi arm/arm/pmu_fdt.c optional fdt arm64/acpica/acpi_iort.c optional acpi arm64/acpica/acpi_machdep.c optional acpi arm64/acpica/OsdEnvironment.c optional acpi arm64/acpica/acpi_wakeup.c optional acpi arm64/acpica/pci_cfgreg.c optional acpi pci arm64/arm64/autoconf.c standard arm64/arm64/bus_machdep.c standard arm64/arm64/bus_space_asm.S standard arm64/arm64/busdma_bounce.c standard arm64/arm64/busdma_machdep.c standard arm64/arm64/clock.c standard arm64/arm64/copyinout.S standard arm64/arm64/cpu_errata.c standard arm64/arm64/cpufunc_asm.S standard arm64/arm64/db_disasm.c optional ddb arm64/arm64/db_interface.c optional ddb arm64/arm64/db_trace.c optional ddb arm64/arm64/debug_monitor.c standard arm64/arm64/disassem.c optional ddb arm64/arm64/dump_machdep.c standard arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/elf_machdep.c standard arm64/arm64/exception.S standard arm64/arm64/exec_machdep.c standard arm64/arm64/freebsd32_machdep.c optional compat_freebsd32 arm64/arm64/gdb_machdep.c optional gdb arm64/arm64/gicv3_its.c optional intrng fdt arm64/arm64/gic_v3.c standard arm64/arm64/gic_v3_acpi.c optional acpi arm64/arm64/gic_v3_fdt.c optional fdt arm64/arm64/identcpu.c standard arm64/arm64/locore.S standard no-obj arm64/arm64/machdep.c standard arm64/arm64/machdep_boot.c standard arm64/arm64/mem.c standard arm64/arm64/memcpy.S standard arm64/arm64/memmove.S standard arm64/arm64/minidump_machdep.c standard arm64/arm64/mp_machdep.c optional smp arm64/arm64/nexus.c standard arm64/arm64/ofw_machdep.c optional fdt arm64/arm64/ptrauth.c standard \ compile-with "${NORMAL_C:N-mbranch-protection*}" arm64/arm64/pmap.c standard arm64/arm64/ptrace_machdep.c standard arm64/arm64/sigtramp.S standard arm64/arm64/stack_machdep.c optional ddb | stack arm64/arm64/support_ifunc.c standard arm64/arm64/support.S standard arm64/arm64/swtch.S standard arm64/arm64/sys_machdep.c standard arm64/arm64/trap.c standard arm64/arm64/uio_machdep.c standard arm64/arm64/uma_machdep.c standard arm64/arm64/undefined.c standard arm64/arm64/unwind.c optional ddb | kdtrace_hooks | stack arm64/arm64/vfp.c standard arm64/arm64/vm_machdep.c standard arm64/coresight/coresight.c standard arm64/coresight/coresight_acpi.c optional acpi arm64/coresight/coresight_fdt.c optional fdt arm64/coresight/coresight_if.m standard arm64/coresight/coresight_cmd.c standard arm64/coresight/coresight_cpu_debug.c standard arm64/coresight/coresight_etm4x.c standard arm64/coresight/coresight_etm4x_acpi.c optional acpi arm64/coresight/coresight_etm4x_fdt.c optional fdt arm64/coresight/coresight_funnel.c standard arm64/coresight/coresight_funnel_acpi.c optional acpi arm64/coresight/coresight_funnel_fdt.c optional fdt arm64/coresight/coresight_replicator.c standard arm64/coresight/coresight_replicator_acpi.c optional acpi arm64/coresight/coresight_replicator_fdt.c optional fdt arm64/coresight/coresight_tmc.c standard arm64/coresight/coresight_tmc_acpi.c optional acpi arm64/coresight/coresight_tmc_fdt.c optional fdt arm64/iommu/iommu.c optional iommu arm64/iommu/iommu_if.m optional iommu arm64/iommu/iommu_pmap.c optional iommu arm64/iommu/smmu.c optional iommu arm64/iommu/smmu_acpi.c optional iommu acpi arm64/iommu/smmu_fdt.c optional iommu fdt arm64/iommu/smmu_quirks.c optional iommu dev/iommu/busdma_iommu.c optional iommu dev/iommu/iommu_gas.c optional iommu crypto/armv8/armv8_crypto.c optional armv8crypto armv8_crypto_wrap.o optional armv8crypto \ dependency "$S/crypto/armv8/armv8_crypto_wrap.c" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "armv8_crypto_wrap.o" aesv8-armx.o optional armv8crypto | ossl \ dependency "$S/crypto/openssl/aarch64/aesv8-armx.S" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "aesv8-armx.o" ghashv8-armx.o optional armv8crypto \ dependency "$S/crypto/openssl/aarch64/ghashv8-armx.S" \ compile-with "${CC} -c ${CFLAGS:C/^-O2$/-O3/:N-nostdinc:N-mgeneral-regs-only} -I$S/crypto/armv8/ ${WERROR} ${NO_WCAST_QUAL} -march=armv8-a+crypto ${.IMPSRC}" \ no-implicit-rule \ clean "ghashv8-armx.o" crypto/des/des_enc.c optional netsmb crypto/openssl/ossl_aarch64.c optional ossl crypto/openssl/aarch64/chacha-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/poly1305-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha1-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha256-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/sha512-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" crypto/openssl/aarch64/vpaes-armv8.S optional ossl \ compile-with "${CC} -c ${CFLAGS:N-mgeneral-regs-only} ${WERROR} ${.IMPSRC}" dev/acpica/acpi_bus_if.m optional acpi dev/acpica/acpi_if.m optional acpi dev/acpica/acpi_pci_link.c optional acpi pci dev/acpica/acpi_pcib.c optional acpi pci dev/acpica/acpi_pxm.c optional acpi dev/ahci/ahci_generic.c optional ahci cddl/dev/dtrace/aarch64/dtrace_asm.S optional dtrace compile-with "${DTRACE_S}" cddl/dev/dtrace/aarch64/dtrace_subr.c optional dtrace compile-with "${DTRACE_C}" cddl/dev/fbt/aarch64/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}" contrib/openzfs/module/icp/asm-aarch64/blake3/b3_aarch64_sse2.S optional zfs compile-with "${ZFS_S:N-mgeneral-regs-only}" contrib/openzfs/module/icp/asm-aarch64/blake3/b3_aarch64_sse41.S optional zfs compile-with "${ZFS_S:N-mgeneral-regs-only}" ## ## ASoC support ## dev/sound/fdt/audio_dai_if.m optional sound fdt dev/sound/fdt/audio_soc.c optional sound fdt dev/sound/fdt/dummy_codec.c optional sound fdt dev/sound/fdt/simple_amplifier.c optional sound fdt ## ## Device drivers ## dev/axgbe/if_axgbe.c optional axa dev/axgbe/xgbe-desc.c optional axa dev/axgbe/xgbe-dev.c optional axa dev/axgbe/xgbe-drv.c optional axa dev/axgbe/xgbe-mdio.c optional axa dev/axgbe/xgbe-sysctl.c optional axa dev/axgbe/xgbe-txrx.c optional axa dev/axgbe/xgbe_osdep.c optional axa dev/axgbe/xgbe-phy-v1.c optional axa dev/cpufreq/cpufreq_dt.c optional cpufreq fdt dev/dwc/if_dwc.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 | fdt dwc_socfpga soc_intel_stratix10 dev/dwc/if_dwc_if.m optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 | fdt dwc_socfpga soc_intel_stratix10 dev/enetc/enetc_mdio.c optional enetc soc_nxp_ls dev/enetc/if_enetc.c optional enetc iflib pci fdt soc_nxp_ls dev/etherswitch/felix/felix.c optional enetc etherswitch fdt felix pci soc_nxp_ls dev/gpio/pl061.c optional pl061 gpio dev/gpio/pl061_acpi.c optional pl061 gpio acpi dev/gpio/pl061_fdt.c optional pl061 gpio fdt dev/gpio/qoriq_gpio.c optional SOC_NXP_LS gpio fdt dev/hwpmc/hwpmc_arm64.c optional hwpmc dev/hwpmc/hwpmc_arm64_md.c optional hwpmc +dev/hwpmc/hwpmc_cmn600.c optional hwpmc +arm64/arm64/cmn600.c optional hwpmc +dev/hwpmc/hwpmc_dmc620.c optional hwpmc +dev/hwpmc/pmu_dmc620.c optional hwpmc dev/ice/if_ice_iflib.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_lib.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_osdep.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_resmgr.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_strings.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_iflib_recovery_txrx.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_iflib_txrx.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_common.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_controlq.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_dcb.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_flex_pipe.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_flow.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_nvm.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_sched.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_switch.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_vlan_mode.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_fw_logging.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_fwlog.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/ice_rdma.c optional ice pci \ compile-with "${NORMAL_C} -I$S/dev/ice" dev/ice/irdma_if.m optional ice pci \ compile-with "${NORMAL_M} -I$S/dev/ice" dev/ice/irdma_di_if.m optional ice pci \ compile-with "${NORMAL_M} -I$S/dev/ice" ice_ddp.c optional ice_ddp \ compile-with "${AWK} -f $S/tools/fw_stub.awk ice_ddp.fw:ice_ddp:0x01031b00 -mice_ddp -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "ice_ddp.c" ice_ddp.fwo optional ice_ddp \ dependency "ice_ddp.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "ice_ddp.fwo" ice_ddp.fw optional ice_ddp \ dependency "$S/contrib/dev/ice/ice-1.3.27.0.pkg" \ compile-with "${CP} $S/contrib/dev/ice/ice-1.3.27.0.pkg ice_ddp.fw" \ no-obj no-implicit-rule \ clean "ice_ddp.fw" dev/iicbus/sy8106a.c optional sy8106a fdt dev/iicbus/twsi/mv_twsi.c optional twsi fdt dev/iicbus/twsi/a10_twsi.c optional twsi fdt dev/iicbus/twsi/twsi.c optional twsi fdt dev/ipmi/ipmi.c optional ipmi dev/ipmi/ipmi_acpi.c optional ipmi acpi dev/ipmi/ipmi_kcs.c optional ipmi dev/ipmi/ipmi_smic.c optional ipmi dev/mbox/mbox_if.m optional soc_brcm_bcm2837 dev/mmc/host/dwmmc.c optional dwmmc fdt dev/mmc/host/dwmmc_altera.c optional dwmmc dwmmc_altera fdt dev/mmc/host/dwmmc_hisi.c optional dwmmc dwmmc_hisi fdt dev/mmc/host/dwmmc_rockchip.c optional dwmmc rk_dwmmc fdt dev/neta/if_mvneta_fdt.c optional neta fdt dev/neta/if_mvneta.c optional neta mdio mii dev/ofw/ofw_cpu.c optional fdt dev/ofw/ofw_pci.c optional fdt pci dev/ofw/ofw_pcib.c optional fdt pci dev/pci/controller/pci_n1sdp.c optional pci_n1sdp acpi dev/pci/pci_host_generic.c optional pci dev/pci/pci_host_generic_acpi.c optional pci acpi dev/pci/pci_host_generic_fdt.c optional pci fdt dev/pci/pci_dw_mv.c optional pci fdt dev/pci/pci_dw.c optional pci fdt dev/pci/pci_dw_if.m optional pci fdt dev/psci/psci.c standard dev/psci/smccc_arm64.S standard dev/psci/smccc.c standard dev/safexcel/safexcel.c optional safexcel fdt dev/sdhci/sdhci_xenon.c optional sdhci_xenon sdhci dev/sdhci/sdhci_xenon_acpi.c optional sdhci_xenon sdhci acpi dev/sdhci/sdhci_xenon_fdt.c optional sdhci_xenon sdhci fdt dev/uart/uart_cpu_arm64.c optional uart dev/uart/uart_dev_mu.c optional uart uart_mu dev/uart/uart_dev_pl011.c optional uart pl011 dev/usb/controller/dwc_otg_hisi.c optional dwcotg fdt soc_hisi_hi6220 dev/usb/controller/dwc3.c optional fdt dwc3 dev/usb/controller/ehci_mv.c optional ehci_mv fdt dev/usb/controller/generic_ehci.c optional ehci dev/usb/controller/generic_ehci_acpi.c optional ehci acpi dev/usb/controller/generic_ehci_fdt.c optional ehci fdt dev/usb/controller/generic_ohci.c optional ohci fdt dev/usb/controller/generic_usb_if.m optional ohci fdt dev/usb/controller/musb_otg_allwinner.c optional musb fdt soc_allwinner_a64 dev/usb/controller/usb_nop_xceiv.c optional fdt dev/usb/controller/generic_xhci.c optional xhci dev/usb/controller/generic_xhci_acpi.c optional xhci acpi dev/usb/controller/generic_xhci_fdt.c optional xhci fdt dev/vnic/mrml_bridge.c optional vnic fdt dev/vnic/nic_main.c optional vnic pci dev/vnic/nicvf_main.c optional vnic pci pci_iov dev/vnic/nicvf_queues.c optional vnic pci pci_iov dev/vnic/thunder_bgx_fdt.c optional soc_cavm_thunderx pci vnic fdt dev/vnic/thunder_bgx.c optional soc_cavm_thunderx pci vnic pci dev/vnic/thunder_mdio_fdt.c optional soc_cavm_thunderx pci vnic fdt dev/vnic/thunder_mdio.c optional soc_cavm_thunderx pci vnic dev/vnic/lmac_if.m optional inet | inet6 | vnic ## ## SoC Support ## # Allwinner common files arm/allwinner/a10_timer.c optional a10_timer fdt arm/allwinner/a10_codec.c optional sound a10_codec arm/allwinner/a31_dmac.c optional a31_dmac arm/allwinner/a33_codec.c optional fdt sound a33_codec arm/allwinner/a64/sun50i_a64_acodec.c optional fdt sound a64_codec arm/allwinner/sunxi_dma_if.m optional a31_dmac arm/allwinner/aw_cir.c optional evdev aw_cir fdt arm/allwinner/aw_dwc3.c optional aw_dwc3 fdt arm/allwinner/aw_gpio.c optional gpio aw_gpio fdt arm/allwinner/aw_i2s.c optional fdt sound aw_i2s arm/allwinner/aw_mmc.c optional mmc aw_mmc fdt | mmccam aw_mmc fdt arm/allwinner/aw_nmi.c optional aw_nmi fdt \ compile-with "${NORMAL_C} -I$S/contrib/device-tree/include" arm/allwinner/aw_pwm.c optional aw_pwm fdt arm/allwinner/aw_r_intc.c optional aw_r_intc fdt arm/allwinner/aw_rsb.c optional aw_rsb fdt arm/allwinner/aw_rtc.c optional aw_rtc fdt arm/allwinner/aw_sid.c optional aw_sid nvmem fdt arm/allwinner/aw_spi.c optional aw_spi fdt arm/allwinner/aw_syscon.c optional aw_syscon syscon fdt arm/allwinner/aw_thermal.c optional aw_thermal nvmem fdt arm/allwinner/aw_usbphy.c optional ehci aw_usbphy fdt arm/allwinner/aw_usb3phy.c optional xhci aw_usbphy fdt arm/allwinner/aw_wdog.c optional aw_wdog fdt arm/allwinner/axp81x.c optional axp81x fdt arm/allwinner/if_awg.c optional awg syscon aw_sid nvmem fdt # Allwinner clock driver arm/allwinner/clkng/aw_ccung.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_frac.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_m.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_mipi.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nkmp.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_nmm.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_np.c optional aw_ccu fdt arm/allwinner/clkng/aw_clk_prediv_mux.c optional aw_ccu fdt arm/allwinner/clkng/ccu_a64.c optional soc_allwinner_a64 aw_ccu fdt arm/allwinner/clkng/ccu_h3.c optional soc_allwinner_h5 aw_ccu fdt arm/allwinner/clkng/ccu_h6.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_h6_r.c optional soc_allwinner_h6 aw_ccu fdt arm/allwinner/clkng/ccu_sun8i_r.c optional aw_ccu fdt arm/allwinner/clkng/ccu_de2.c optional aw_ccu fdt # Allwinner padconf files arm/allwinner/a64/a64_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/a64/a64_r_padconf.c optional soc_allwinner_a64 fdt arm/allwinner/h3/h3_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h3/h3_r_padconf.c optional soc_allwinner_h5 fdt arm/allwinner/h6/h6_padconf.c optional soc_allwinner_h6 fdt arm/allwinner/h6/h6_r_padconf.c optional soc_allwinner_h6 fdt # Altera/Intel dev/altera/dwc/if_dwc_socfpga.c optional fdt dwc_socfpga arm64/intel/firmware.c optional soc_intel_stratix10 arm64/intel/stratix10-soc-fpga-mgr.c optional soc_intel_stratix10 arm64/intel/stratix10-svc.c optional soc_intel_stratix10 # Annapurna arm/annapurna/alpine/alpine_ccu.c optional al_ccu fdt arm/annapurna/alpine/alpine_nb_service.c optional al_nb_service fdt arm/annapurna/alpine/alpine_pci.c optional al_pci fdt arm/annapurna/alpine/alpine_pci_msix.c optional al_pci fdt arm/annapurna/alpine/alpine_serdes.c optional al_serdes fdt \ no-depend \ compile-with "${CC} -c -o ${.TARGET} ${CFLAGS} -I$S/contrib/alpine-hal -I$S/contrib/alpine-hal/eth ${.IMPSRC}" # Broadcom arm64/broadcom/brcmmdio/mdio_mux_iproc.c optional soc_brcm_ns2 fdt arm64/broadcom/brcmmdio/mdio_nexus_iproc.c optional soc_brcm_ns2 fdt arm64/broadcom/brcmmdio/mdio_ns2_pcie_phy.c optional soc_brcm_ns2 fdt pci arm64/broadcom/genet/if_genet.c optional SOC_BRCM_BCM2838 fdt genet arm/broadcom/bcm2835/bcm2835_audio.c optional sound vchiq fdt \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" arm/broadcom/bcm2835/bcm2835_bsc.c optional bcm2835_bsc fdt arm/broadcom/bcm2835/bcm2835_clkman.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_cpufreq.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_dma.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_fbd.c optional vt soc_brcm_bcm2837 fdt | vt soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_firmware.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_ft5406.c optional evdev bcm2835_ft5406 fdt arm/broadcom/bcm2835/bcm2835_gpio.c optional gpio soc_brcm_bcm2837 fdt | gpio soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_intr.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_mbox.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_rng.c optional !random_loadable soc_brcm_bcm2837 fdt | !random_loadable soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_sdhci.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_sdhost.c optional sdhci soc_brcm_bcm2837 fdt | sdhci soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_spi.c optional bcm2835_spi fdt arm/broadcom/bcm2835/bcm2835_vcbus.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_vcio.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2835_wdog.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm2836.c optional soc_brcm_bcm2837 fdt | soc_brcm_bcm2838 fdt arm/broadcom/bcm2835/bcm283x_dwc_fdt.c optional dwcotg fdt soc_brcm_bcm2837 | dwcotg fdt soc_brcm_bcm2838 arm/broadcom/bcm2835/bcm2838_pci.c optional soc_brcm_bcm2838 fdt pci arm/broadcom/bcm2835/bcm2838_xhci.c optional soc_brcm_bcm2838 fdt pci xhci arm/broadcom/bcm2835/raspberrypi_gpio.c optional soc_brcm_bcm2837 gpio | soc_brcm_bcm2838 gpio contrib/vchiq/interface/compat/vchi_bsd.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_2835_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_arm.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -Wno-unused -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_connected.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_core.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kern_lib.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_kmod.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_shim.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" contrib/vchiq/interface/vchiq_arm/vchiq_util.c optional vchiq soc_brcm_bcm2837 \ compile-with "${NORMAL_C} -DUSE_VCHIQ_ARM -D__VCCOREVER__=0x04000000 -I$S/contrib/vchiq" # Cavium arm64/cavium/thunder_pcie_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_pem.c optional soc_cavm_thunderx pci arm64/cavium/thunder_pcie_pem_fdt.c optional soc_cavm_thunderx pci fdt arm64/cavium/thunder_pcie_common.c optional soc_cavm_thunderx pci # i.MX8 Clock support arm64/freescale/imx/imx8mq_ccm.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_gate.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_mux.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_composite.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_sscg_pll.c optional fdt soc_freescale_imx8 arm64/freescale/imx/clk/imx_clk_frac_pll.c optional fdt soc_freescale_imx8 # iMX drivers arm/freescale/imx/imx_gpio.c optional gpio soc_freescale_imx8 arm/freescale/imx/imx_i2c.c optional fsliic arm/freescale/imx/imx_machdep.c optional fdt soc_freescale_imx8 arm64/freescale/imx/imx7gpc.c optional fdt soc_freescale_imx8 dev/ffec/if_ffec.c optional ffec # Marvell arm/mv/a37x0_gpio.c optional a37x0_gpio gpio fdt arm/mv/a37x0_iic.c optional a37x0_iic iicbus fdt arm/mv/a37x0_spi.c optional a37x0_spi spibus fdt arm/mv/clk/a37x0_tbg.c optional a37x0_tbg clk fdt syscon arm/mv/clk/a37x0_xtal.c optional a37x0_xtal clk fdt syscon arm/mv/armada38x/armada38x_rtc.c optional mv_rtc fdt arm/mv/gpio.c optional mv_gpio fdt arm/mv/mvebu_gpio.c optional mv_gpio fdt arm/mv/mvebu_pinctrl.c optional mvebu_pinctrl fdt arm/mv/mv_ap806_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_ap806_gicp.c optional mv_ap806_gicp fdt arm/mv/mv_ap806_sei.c optional mv_ap806_sei fdt arm/mv/mv_cp110_clock.c optional SOC_MARVELL_8K fdt arm/mv/mv_cp110_icu.c optional mv_cp110_icu fdt arm/mv/mv_cp110_icu_bus.c optional mv_cp110_icu fdt arm/mv/mv_thermal.c optional SOC_MARVELL_8K mv_thermal fdt arm/mv/clk/a37x0_tbg_pll.c optional a37x0_tbg clk fdt syscon arm/mv/clk/a37x0_periph_clk_driver.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon arm/mv/clk/a37x0_nb_periph_clk_driver.c optional a37x0_nb_periph clk fdt syscon arm/mv/clk/a37x0_sb_periph_clk_driver.c optional a37x0_sb_periph clk fdt syscon arm/mv/clk/periph.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon arm/mv/clk/periph_clk_d.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon arm/mv/clk/periph_clk_fixed.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon arm/mv/clk/periph_clk_gate.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon arm/mv/clk/periph_clk_mux_gate.c optional a37x0_nb_periph a37x0_sb_periph clk fdt syscon # NVidia arm/nvidia/tegra_abpmisc.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_ahci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_efuse.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_ehci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_gpio.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_i2c.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_lic.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_mc.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_pcie.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_sdhci.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_soctherm_if.m optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_soctherm.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_uart.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_usbphy.c optional fdt soc_nvidia_tegra210 arm/nvidia/tegra_xhci.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_gpio.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_regulators.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/max77620_rtc.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_car.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_per.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_pll.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_clk_super.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_coretemp.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_cpufreq.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_pinmux.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_pmc.c optional fdt soc_nvidia_tegra210 arm64/nvidia/tegra210/tegra210_xusbpadctl.c optional fdt soc_nvidia_tegra210 # Nvidia firmware for Tegra tegra210_xusb_fw.c optional tegra210_xusb_fw \ dependency "$S/conf/files.arm64" \ compile-with "${AWK} -f $S/tools/fw_stub.awk tegra210_xusb.fw:tegra210_xusb_fw -mtegra210_xusb_fw -c${.TARGET}" \ no-ctfconvert no-implicit-rule before-depend local \ clean "tegra210_xusb_fw.c" tegra210_xusb.fwo optional tegra210_xusb_fw \ dependency "tegra210_xusb.fw" \ compile-with "${NORMAL_FWO}" \ no-implicit-rule \ clean "tegra210_xusb.fwo" tegra210_xusb.fw optional tegra210_xusb_fw \ dependency "$S/contrib/dev/nvidia/tegra210_xusb.bin.uu" \ compile-with "${NORMAL_FW}" \ no-obj no-implicit-rule \ clean "tegra210_xusb.fw" # NXP arm/freescale/vybrid/vf_i2c.c optional vf_i2c iicbus SOC_NXP_LS arm64/qoriq/qoriq_dw_pci.c optional pci fdt SOC_NXP_LS arm64/qoriq/qoriq_gpio_pic.c optional gpio fdt SOC_NXP_LS arm64/qoriq/qoriq_therm.c optional pci fdt SOC_NXP_LS arm64/qoriq/qoriq_therm_if.m optional pci fdt SOC_NXP_LS arm64/qoriq/clk/ls1028a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/ls1028a_flexspi_clk.c optional clk SOC_NXP_LS arm64/qoriq/clk/ls1046a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/lx2160a_clkgen.c optional clk SOC_NXP_LS arm64/qoriq/clk/qoriq_clk_pll.c optional clk SOC_NXP_LS arm64/qoriq/clk/qoriq_clkgen.c optional clk SOC_NXP_LS dev/ahci/ahci_fsl_fdt.c optional SOC_NXP_LS ahci fdt dev/flash/flexspi/flex_spi.c optional clk flex_spi SOC_NXP_LS fdt # Qualcomm arm64/qualcomm/qcom_gcc.c optional qcom_gcc fdt # RockChip Drivers arm64/rockchip/rk3328_codec.c optional fdt rk3328codec soc_rockchip_rk3328 arm64/rockchip/rk3399_emmcphy.c optional fdt rk_emmcphy soc_rockchip_rk3399 arm64/rockchip/rk_dwc3.c optional fdt rk_dwc3 soc_rockchip_rk3399 arm64/rockchip/rk_i2c.c optional fdt rk_i2c soc_rockchip_rk3328 | fdt rk_i2c soc_rockchip_rk3399 arm64/rockchip/rk_i2s.c optional fdt sound soc_rockchip_rk3328 | fdt sound soc_rockchip_rk3399 dev/iicbus/pmic/rockchip/rk8xx.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 dev/iicbus/pmic/rockchip/rk805.c optional fdt rk805 soc_rockchip_rk3328 dev/iicbus/pmic/rockchip/rk808.c optional fdt rk805 soc_rockchip_rk3399 dev/iicbus/pmic/rockchip/rk8xx_clocks.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 dev/iicbus/pmic/rockchip/rk8xx_regulators.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 dev/iicbus/pmic/rockchip/rk8xx_rtc.c optional fdt rk805 soc_rockchip_rk3328 | fdt rk805 soc_rockchip_rk3399 arm64/rockchip/rk_grf.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/rk_pinctrl.c optional fdt rk_pinctrl soc_rockchip_rk3328 | fdt rk_pinctrl soc_rockchip_rk3399 arm64/rockchip/rk_gpio.c optional fdt rk_gpio soc_rockchip_rk3328 | fdt rk_gpio soc_rockchip_rk3399 arm64/rockchip/rk_iodomain.c optional fdt rk_iodomain arm64/rockchip/rk_spi.c optional fdt rk_spi arm64/rockchip/rk_usb2phy.c optional fdt rk_usb2phy soc_rockchip_rk3328 | soc_rockchip_rk3399 arm64/rockchip/rk_typec_phy.c optional fdt rk_typec_phy soc_rockchip_rk3399 arm64/rockchip/if_dwc_rk.c optional fdt dwc_rk soc_rockchip_rk3328 | fdt dwc_rk soc_rockchip_rk3399 arm64/rockchip/rk_tsadc_if.m optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_tsadc.c optional fdt soc_rockchip_rk3399 arm64/rockchip/rk_pwm.c optional fdt rk_pwm arm64/rockchip/rk_pcie.c optional fdt pci soc_rockchip_rk3399 arm64/rockchip/rk_pcie_phy.c optional fdt pci soc_rockchip_rk3399 # RockChip Clock support arm64/rockchip/clk/rk_cru.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_armclk.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_composite.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_fract.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_gate.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_mux.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk_clk_pll.c optional fdt soc_rockchip_rk3328 | fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3328_cru.c optional fdt soc_rockchip_rk3328 arm64/rockchip/clk/rk3399_cru.c optional fdt soc_rockchip_rk3399 arm64/rockchip/clk/rk3399_pmucru.c optional fdt soc_rockchip_rk3399 # Xilinx arm/xilinx/uart_dev_cdnc.c optional uart soc_xilinx_zynq diff --git a/sys/dev/hwpmc/hwpmc_cmn600.c b/sys/dev/hwpmc/hwpmc_cmn600.c index b33dd2693b25..2e6ea41abff8 100644 --- a/sys/dev/hwpmc/hwpmc_cmn600.c +++ b/sys/dev/hwpmc/hwpmc_cmn600.c @@ -1,830 +1,826 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2003-2008 Joseph Koshy * Copyright (c) 2007 The FreeBSD Foundation * Copyright (c) 2021 ARM Ltd * * Portions of this software were developed by A. Joseph Koshy under * sponsorship from the FreeBSD Foundation and Google, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* Arm CoreLink CMN-600 Coherent Mesh Network PMU Driver */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #include struct cmn600_descr { struct pmc_descr pd_descr; /* "base class" */ void *pd_rw_arg; /* Argument to use with read/write */ struct pmc *pd_pmc; struct pmc_hw *pd_phw; uint32_t pd_nodeid; int32_t pd_node_type; int pd_local_counter; }; static struct cmn600_descr **cmn600_pmcdesc; static struct cmn600_pmc cmn600_pmcs[CMN600_UNIT_MAX]; static int cmn600_units = 0; static inline struct cmn600_descr * cmn600desc(int ri) { return (cmn600_pmcdesc[ri]); } static inline int class_ri2unit(int ri) { return (ri / CMN600_COUNTERS_N); } #define EVENCNTR(x) (((x) >> POR_DT_PMEVCNT_EVENCNT_SHIFT) << \ POR_DTM_PMEVCNT_CNTR_WIDTH) #define ODDCNTR(x) (((x) >> POR_DT_PMEVCNT_ODDCNT_SHIFT) << \ POR_DTM_PMEVCNT_CNTR_WIDTH) static uint64_t cmn600_pmu_readcntr(void *arg, u_int nodeid, u_int xpcntr, u_int dtccntr, u_int width) { uint64_t dtcval, xpval; KASSERT(xpcntr < 4, ("[cmn600,%d] XP counter number %d is too big." " Max: 3", __LINE__, xpcntr)); KASSERT(dtccntr < 8, ("[cmn600,%d] Global counter number %d is too" " big. Max: 7", __LINE__, dtccntr)); dtcval = pmu_cmn600_rd8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMEVCNT(dtccntr >> 1)); if (width == 4) { dtcval = (dtccntr & 1) ? ODDCNTR(dtcval) : EVENCNTR(dtcval); dtcval &= 0xffffffff0000UL; } else dtcval <<= POR_DTM_PMEVCNT_CNTR_WIDTH; xpval = pmu_cmn600_rd8(arg, nodeid, NODE_TYPE_XP, POR_DTM_PMEVCNT); xpval >>= xpcntr * POR_DTM_PMEVCNT_CNTR_WIDTH; xpval &= 0xffffUL; return (dtcval | xpval); } static void cmn600_pmu_writecntr(void *arg, u_int nodeid, u_int xpcntr, u_int dtccntr, u_int width, uint64_t val) { int shift; KASSERT(xpcntr < 4, ("[cmn600,%d] XP counter number %d is too big." " Max: 3", __LINE__, xpcntr)); KASSERT(dtccntr < 8, ("[cmn600,%d] Global counter number %d is too" " big. Max: 7", __LINE__, dtccntr)); if (width == 4) { shift = (dtccntr & 1) ? POR_DT_PMEVCNT_ODDCNT_SHIFT : POR_DT_PMEVCNT_EVENCNT_SHIFT; pmu_cmn600_md8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMEVCNT(dtccntr >> 1), 0xffffffffUL << shift, ((val >> POR_DTM_PMEVCNT_CNTR_WIDTH) & 0xffffffff) << shift); } else pmu_cmn600_wr8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMEVCNT(dtccntr & ~0x1), val >> POR_DTM_PMEVCNT_CNTR_WIDTH); shift = xpcntr * POR_DTM_PMEVCNT_CNTR_WIDTH; val &= 0xffffUL; pmu_cmn600_md8(arg, nodeid, NODE_TYPE_XP, POR_DTM_PMEVCNT, 0xffffUL << shift, val << shift); } #undef EVENCNTR #undef ODDCNTR /* * read a pmc register */ static int cmn600_read_pmc(int cpu, int ri, pmc_value_t *v) { int counter, local_counter, nodeid; struct cmn600_descr *desc; struct pmc *pm; void *arg; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); counter = ri % CMN600_COUNTERS_N; desc = cmn600desc(ri); pm = desc->pd_phw->phw_pmc; arg = desc->pd_rw_arg; nodeid = pm->pm_md.pm_cmn600.pm_cmn600_nodeid; local_counter = pm->pm_md.pm_cmn600.pm_cmn600_local_counter; KASSERT(pm != NULL, ("[cmn600,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, cpu, ri)); *v = cmn600_pmu_readcntr(arg, nodeid, local_counter, counter, 4); PMCDBG3(MDP, REA, 2, "%s id=%d -> %jd", __func__, ri, *v); return (0); } /* * Write a pmc register. */ static int cmn600_write_pmc(int cpu, int ri, pmc_value_t v) { int counter, local_counter, nodeid; struct cmn600_descr *desc; struct pmc *pm; void *arg; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); counter = ri % CMN600_COUNTERS_N; desc = cmn600desc(ri); pm = desc->pd_phw->phw_pmc; arg = desc->pd_rw_arg; nodeid = pm->pm_md.pm_cmn600.pm_cmn600_nodeid; local_counter = pm->pm_md.pm_cmn600.pm_cmn600_local_counter; KASSERT(pm != NULL, ("[cmn600,%d] PMC not owned (cpu%d,pmc%d)", __LINE__, cpu, ri)); PMCDBG4(MDP, WRI, 1, "%s cpu=%d ri=%d v=%jx", __func__, cpu, ri, v); cmn600_pmu_writecntr(arg, nodeid, local_counter, counter, 4, v); return (0); } /* * configure hardware pmc according to the configuration recorded in * pmc 'pm'. */ static int cmn600_config_pmc(int cpu, int ri, struct pmc *pm) { struct pmc_hw *phw; PMCDBG4(MDP, CFG, 1, "%s cpu=%d ri=%d pm=%p", __func__, cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); phw = cmn600desc(ri)->pd_phw; KASSERT(pm == NULL || phw->phw_pmc == NULL, ("[cmn600,%d] pm=%p phw->pm=%p hwpmc not unconfigured", __LINE__, pm, phw->phw_pmc)); phw->phw_pmc = pm; return (0); } /* * Retrieve a configured PMC pointer from hardware state. */ static int cmn600_get_config(int cpu, int ri, struct pmc **ppm) { *ppm = cmn600desc(ri)->pd_phw->phw_pmc; return (0); } #define CASE_DN_VER_EVT(n, id) case PMC_EV_CMN600_PMU_ ## n: { *event = id; \ return (0); } static int cmn600_map_ev2event(int ev, int rev, int *node_type, uint8_t *event) { if (ev < PMC_EV_CMN600_PMU_dn_rxreq_dvmop || ev > PMC_EV_CMN600_PMU_rni_rdb_ord) return (EINVAL); if (ev <= PMC_EV_CMN600_PMU_dn_rxreq_trk_full) { *node_type = NODE_TYPE_DVM; if (rev < 0x200) { switch (ev) { CASE_DN_VER_EVT(dn_rxreq_dvmop, 1); CASE_DN_VER_EVT(dn_rxreq_dvmsync, 2); CASE_DN_VER_EVT(dn_rxreq_dvmop_vmid_filtered, 3); CASE_DN_VER_EVT(dn_rxreq_retried, 4); CASE_DN_VER_EVT(dn_rxreq_trk_occupancy, 5); } } else { switch (ev) { CASE_DN_VER_EVT(dn_rxreq_tlbi_dvmop, 0x01); CASE_DN_VER_EVT(dn_rxreq_bpi_dvmop, 0x02); CASE_DN_VER_EVT(dn_rxreq_pici_dvmop, 0x03); CASE_DN_VER_EVT(dn_rxreq_vivi_dvmop, 0x04); CASE_DN_VER_EVT(dn_rxreq_dvmsync, 0x05); CASE_DN_VER_EVT(dn_rxreq_dvmop_vmid_filtered, 0x06); CASE_DN_VER_EVT(dn_rxreq_dvmop_other_filtered, 0x07); CASE_DN_VER_EVT(dn_rxreq_retried, 0x08); CASE_DN_VER_EVT(dn_rxreq_snp_sent, 0x09); CASE_DN_VER_EVT(dn_rxreq_snp_stalled, 0x0a); CASE_DN_VER_EVT(dn_rxreq_trk_full, 0x0b); CASE_DN_VER_EVT(dn_rxreq_trk_occupancy, 0x0c); } } return (EINVAL); } else if (ev <= PMC_EV_CMN600_PMU_hnf_snp_fwded) { *node_type = NODE_TYPE_HN_F; *event = ev - PMC_EV_CMN600_PMU_hnf_cache_miss; return (0); } else if (ev <= PMC_EV_CMN600_PMU_hni_pcie_serialization) { *node_type = NODE_TYPE_HN_I; *event = ev - PMC_EV_CMN600_PMU_hni_rrt_rd_occ_cnt_ovfl; return (0); } else if (ev <= PMC_EV_CMN600_PMU_xp_partial_dat_flit) { *node_type = NODE_TYPE_XP; *event = ev - PMC_EV_CMN600_PMU_xp_txflit_valid; return (0); } else if (ev <= PMC_EV_CMN600_PMU_sbsx_txrsp_stall) { *node_type = NODE_TYPE_SBSX; *event = ev - PMC_EV_CMN600_PMU_sbsx_rd_req; return (0); } else if (ev <= PMC_EV_CMN600_PMU_rnd_rdb_ord) { *node_type = NODE_TYPE_RN_D; *event = ev - PMC_EV_CMN600_PMU_rnd_s0_rdata_beats; return (0); } else if (ev <= PMC_EV_CMN600_PMU_rni_rdb_ord) { *node_type = NODE_TYPE_RN_I; *event = ev - PMC_EV_CMN600_PMU_rni_s0_rdata_beats; return (0); } else if (ev <= PMC_EV_CMN600_PMU_cxha_snphaz_occ) { *node_type = NODE_TYPE_CXHA; *event = ev - PMC_EV_CMN600_PMU_cxha_rddatbyp; return (0); } else if (ev <= PMC_EV_CMN600_PMU_cxra_ext_dat_stall) { *node_type = NODE_TYPE_CXRA; *event = ev - PMC_EV_CMN600_PMU_cxra_req_trk_occ; return (0); } else if (ev <= PMC_EV_CMN600_PMU_cxla_avg_latency_form_tx_tlp) { *node_type = NODE_TYPE_CXLA; *event = ev - PMC_EV_CMN600_PMU_cxla_rx_tlp_link0; return (0); } return (EINVAL); } /* * Check if a given allocation is feasible. */ static int cmn600_allocate_pmc(int cpu, int ri, struct pmc *pm, const struct pmc_op_pmcallocate *a) { struct cmn600_descr *desc; const struct pmc_descr *pd; uint64_t caps __unused; int local_counter, node_type; enum pmc_event pe; void *arg; uint8_t e; int err; (void) cpu; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); desc = cmn600desc(ri); arg = desc->pd_rw_arg; pd = &desc->pd_descr; if (cmn600_pmcs[class_ri2unit(ri)].domain != pcpu_find(cpu)->pc_domain) return (EINVAL); /* check class match */ if (pd->pd_class != a->pm_class) return (EINVAL); caps = pm->pm_caps; PMCDBG3(MDP, ALL, 1, "%s ri=%d caps=0x%x", __func__, ri, caps); pe = a->pm_ev; err = cmn600_map_ev2event(pe, pmu_cmn600_rev(arg), &node_type, &e); if (err != 0) return (err); err = pmu_cmn600_alloc_localpmc(arg, a->pm_md.pm_cmn600.pma_cmn600_nodeid, node_type, &local_counter); if (err != 0) return (err); pm->pm_md.pm_cmn600.pm_cmn600_config = a->pm_md.pm_cmn600.pma_cmn600_config; pm->pm_md.pm_cmn600.pm_cmn600_occupancy = a->pm_md.pm_cmn600.pma_cmn600_occupancy; desc->pd_nodeid = pm->pm_md.pm_cmn600.pm_cmn600_nodeid = a->pm_md.pm_cmn600.pma_cmn600_nodeid; desc->pd_node_type = pm->pm_md.pm_cmn600.pm_cmn600_node_type = node_type; pm->pm_md.pm_cmn600.pm_cmn600_event = e; desc->pd_local_counter = pm->pm_md.pm_cmn600.pm_cmn600_local_counter = local_counter; - PMCDBG3(MDP, ALL, 2, "%s ri=%d -> control=0x%x", __func__, ri, control); - return (0); } /* Release machine dependent state associated with a PMC. */ static int cmn600_release_pmc(int cpu, int ri, struct pmc *pmc) { struct cmn600_descr *desc; struct pmc_hw *phw; - struct pmc *pm; + struct pmc *pm __diagused; int err; (void) pmc; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); desc = cmn600desc(ri); phw = desc->pd_phw; pm = phw->phw_pmc; err = pmu_cmn600_free_localpmc(desc->pd_rw_arg, desc->pd_nodeid, desc->pd_node_type, desc->pd_local_counter); if (err != 0) return (err); KASSERT(pm == NULL, ("[cmn600,%d] PHW pmc %p non-NULL", __LINE__, pm)); return (0); } static inline uint64_t cmn600_encode_source(int node_type, int counter, int port, int sub) { /* Calculate pmevcnt0_input_sel based on list in Table 3-794. */ if (node_type == NODE_TYPE_XP) return (0x4 | counter); return (((port + 1) << 4) | (sub << 2) | counter); } /* * start a PMC. */ static int cmn600_start_pmc(int cpu, int ri) { int counter, local_counter, node_type, shift; uint64_t config, occupancy, source, xp_pmucfg; struct cmn600_descr *desc; struct pmc_hw *phw; struct pmc *pm; uint8_t event, port, sub; uint16_t nodeid; void *arg; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); counter = ri % CMN600_COUNTERS_N; desc = cmn600desc(ri); phw = desc->pd_phw; pm = phw->phw_pmc; arg = desc->pd_rw_arg; KASSERT(pm != NULL, ("[cmn600,%d] starting cpu%d,pmc%d with null pmc record", __LINE__, cpu, ri)); PMCDBG3(MDP, STA, 1, "%s cpu=%d ri=%d", __func__, cpu, ri); config = pm->pm_md.pm_cmn600.pm_cmn600_config; occupancy = pm->pm_md.pm_cmn600.pm_cmn600_occupancy; node_type = pm->pm_md.pm_cmn600.pm_cmn600_node_type; event = pm->pm_md.pm_cmn600.pm_cmn600_event; nodeid = pm->pm_md.pm_cmn600.pm_cmn600_nodeid; local_counter = pm->pm_md.pm_cmn600.pm_cmn600_local_counter; port = (nodeid >> 2) & 1; sub = nodeid & 3; switch (node_type) { case NODE_TYPE_DVM: case NODE_TYPE_HN_F: case NODE_TYPE_CXHA: case NODE_TYPE_CXRA: pmu_cmn600_md8(arg, nodeid, node_type, CMN600_COMMON_PMU_EVENT_SEL, CMN600_COMMON_PMU_EVENT_SEL_OCC_MASK, occupancy << CMN600_COMMON_PMU_EVENT_SEL_OCC_SHIFT); break; case NODE_TYPE_XP: /* Set PC and Interface.*/ event |= config; } /* * 5.5.1 Set up PMU counters * 1. Ensure that the NIDEN input is asserted. HW side. */ /* 2. Select event of target node for one of four outputs. */ pmu_cmn600_md8(arg, nodeid, node_type, CMN600_COMMON_PMU_EVENT_SEL, 0xff << (local_counter * 8), event << (local_counter * 8)); xp_pmucfg = pmu_cmn600_rd8(arg, nodeid, NODE_TYPE_XP, POR_DTM_PMU_CONFIG); /* * 3. configure XP to connect one of four target node outputs to local * counter. */ source = cmn600_encode_source(node_type, local_counter, port, sub); shift = (local_counter * POR_DTM_PMU_CONFIG_VCNT_INPUT_SEL_WIDTH) + POR_DTM_PMU_CONFIG_VCNT_INPUT_SEL_SHIFT; xp_pmucfg &= ~(0xffUL << shift); xp_pmucfg |= source << shift; /* 4. Pair with global counters A, B, C, ..., H. */ shift = (local_counter * 4) + 16; xp_pmucfg &= ~(0xfUL << shift); xp_pmucfg |= counter << shift; /* Enable pairing.*/ xp_pmucfg |= 1 << (local_counter + 4); /* 5. Combine local counters 0 with 1, 2 with 3 or all four. */ xp_pmucfg &= ~0xeUL; /* 6. Enable XP's PMU function. */ xp_pmucfg |= POR_DTM_PMU_CONFIG_PMU_EN; pmu_cmn600_wr8(arg, nodeid, NODE_TYPE_XP, POR_DTM_PMU_CONFIG, xp_pmucfg); if (node_type == NODE_TYPE_CXLA) pmu_cmn600_set8(arg, nodeid, NODE_TYPE_CXLA, POR_CXG_RA_CFG_CTL, EN_CXLA_PMUCMD_PROP); /* 7. Enable DTM. */ pmu_cmn600_set8(arg, nodeid, NODE_TYPE_XP, POR_DTM_CONTROL, POR_DTM_CONTROL_DTM_ENABLE); /* 8. Reset grouping of global counters. Use 32 bits. */ pmu_cmn600_clr8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMCR, POR_DT_PMCR_CNTCFG_MASK); /* 9. Enable DTC. */ pmu_cmn600_set8(arg, nodeid, NODE_TYPE_DTC, POR_DT_DTC_CTL, POR_DT_DTC_CTL_DT_EN); /* 10. Enable Overflow Interrupt. */ pmu_cmn600_set8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMCR, POR_DT_PMCR_OVFL_INTR_EN); /* 11. Run PMC. */ pmu_cmn600_set8(arg, nodeid, NODE_TYPE_DTC, POR_DT_PMCR, POR_DT_PMCR_PMU_EN); - PMCDBG2(MDP, STA, 2, "%s control=0x%x", __func__, control); - return (0); } /* * Stop a PMC. */ static int cmn600_stop_pmc(int cpu, int ri) { struct cmn600_descr *desc; struct pmc_hw *phw; struct pmc *pm; int local_counter; uint64_t val; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); desc = cmn600desc(ri); phw = desc->pd_phw; pm = phw->phw_pmc; KASSERT(pm != NULL, ("[cmn600,%d] cpu%d,pmc%d no PMC to stop", __LINE__, cpu, ri)); PMCDBG2(MDP, STO, 1, "%s ri=%d", __func__, ri); /* Disable pairing. */ local_counter = pm->pm_md.pm_cmn600.pm_cmn600_local_counter; pmu_cmn600_clr8(desc->pd_rw_arg, pm->pm_md.pm_cmn600.pm_cmn600_nodeid, NODE_TYPE_XP, POR_DTM_PMU_CONFIG, (1 << (local_counter + 4))); /* Shutdown XP's DTM function if no paired counters. */ val = pmu_cmn600_rd8(desc->pd_rw_arg, pm->pm_md.pm_cmn600.pm_cmn600_nodeid, NODE_TYPE_XP, POR_DTM_PMU_CONFIG); if ((val & 0xf0) == 0) pmu_cmn600_clr8(desc->pd_rw_arg, pm->pm_md.pm_cmn600.pm_cmn600_nodeid, NODE_TYPE_XP, POR_DTM_PMU_CONFIG, POR_DTM_CONTROL_DTM_ENABLE); return (0); } /* * describe a PMC */ static int cmn600_describe(int cpu, int ri, struct pmc_info *pi, struct pmc **ppmc) { struct pmc_hw *phw; size_t copied; int error; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] illegal CPU %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[cmn600,%d] row-index %d out of range", __LINE__, ri)); phw = cmn600desc(ri)->pd_phw; if ((error = copystr(cmn600desc(ri)->pd_descr.pd_name, pi->pm_name, PMC_NAME_MAX, &copied)) != 0) return (error); pi->pm_class = cmn600desc(ri)->pd_descr.pd_class; if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { pi->pm_enabled = TRUE; *ppmc = phw->phw_pmc; } else { pi->pm_enabled = FALSE; *ppmc = NULL; } return (0); } /* * processor dependent initialization. */ static int cmn600_pcpu_init(struct pmc_mdep *md, int cpu) { int first_ri, n, npmc; struct pmc_hw *phw; struct pmc_cpu *pc; int mdep_class; mdep_class = PMC_MDEP_CLASS_INDEX_CMN600; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] insane cpu number %d", __LINE__, cpu)); PMCDBG1(MDP, INI, 1, "cmn600-init cpu=%d", cpu); /* * Set the content of the hardware descriptors to a known * state and initialize pointers in the MI per-cpu descriptor. */ pc = pmc_pcpu[cpu]; first_ri = md->pmd_classdep[mdep_class].pcd_ri; npmc = md->pmd_classdep[mdep_class].pcd_num; for (n = 0; n < npmc; n++, phw++) { phw = cmn600desc(n)->pd_phw; phw->phw_state = PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(n); /* Set enabled only if unit present. */ if (cmn600_pmcs[class_ri2unit(n)].arg != NULL) phw->phw_state |= PMC_PHW_FLAG_IS_ENABLED; phw->phw_pmc = NULL; pc->pc_hwpmcs[n + first_ri] = phw; } return (0); } /* * processor dependent cleanup prior to the KLD * being unloaded */ static int cmn600_pcpu_fini(struct pmc_mdep *md, int cpu) { return (0); } static int cmn600_pmu_intr(struct trapframe *tf, int unit, int i) { - struct pmc_cpu *pc; + struct pmc_cpu *pc __diagused; struct pmc_hw *phw; struct pmc *pm; int error, cpu, ri; ri = i + unit * CMN600_COUNTERS_N; cpu = curcpu; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[cmn600,%d] CPU %d out of range", __LINE__, cpu)); pc = pmc_pcpu[cpu]; KASSERT(pc != NULL, ("pc != NULL")); phw = cmn600desc(ri)->pd_phw; KASSERT(phw != NULL, ("phw != NULL")); pm = phw->phw_pmc; if (pm == NULL) return (0); if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { /* Always CPU0. */ pm->pm_pcpu_state[0].pps_overflowcnt += 1; return (0); } if (pm->pm_state != PMC_STATE_RUNNING) return (0); error = pmc_process_interrupt(PMC_HR, pm, tf); if (error) cmn600_stop_pmc(cpu, ri); /* Reload sampling count */ cmn600_write_pmc(cpu, ri, pm->pm_sc.pm_reloadcount); return (0); } /* * Initialize ourselves. */ static int cmn600_init_pmc_units() { int i; if (cmn600_units > 0) { /* Already initialized. */ return (0); } cmn600_units = cmn600_pmc_nunits(); if (cmn600_units == 0) return (ENOENT); for (i = 0; i < cmn600_units; i++) { if (cmn600_pmc_getunit(i, &cmn600_pmcs[i].arg, &cmn600_pmcs[i].domain) != 0) cmn600_pmcs[i].arg = NULL; } return (0); } int pmc_cmn600_nclasses() { if (cmn600_pmc_nunits() > 0) return (1); return (0); } int pmc_cmn600_initialize(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc, unit; cmn600_init_pmc_units(); KASSERT(md != NULL, ("[cmn600,%d] md is NULL", __LINE__)); KASSERT(cmn600_units < CMN600_UNIT_MAX, ("[cmn600,%d] cmn600_units too big", __LINE__)); PMCDBG0(MDP,INI,1, "cmn600-initialize"); npmc = CMN600_COUNTERS_N * cmn600_units; pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_CMN600]; pcd->pcd_caps = PMC_CAP_SYSTEM | PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_QUALIFIER | PMC_CAP_INTERRUPT | PMC_CAP_DOMWIDE; pcd->pcd_class = PMC_CLASS_CMN600_PMU; pcd->pcd_num = npmc; pcd->pcd_ri = md->pmd_npmc; pcd->pcd_width = 48; pcd->pcd_allocate_pmc = cmn600_allocate_pmc; pcd->pcd_config_pmc = cmn600_config_pmc; pcd->pcd_describe = cmn600_describe; pcd->pcd_get_config = cmn600_get_config; pcd->pcd_get_msr = NULL; pcd->pcd_pcpu_fini = cmn600_pcpu_fini; pcd->pcd_pcpu_init = cmn600_pcpu_init; pcd->pcd_read_pmc = cmn600_read_pmc; pcd->pcd_release_pmc = cmn600_release_pmc; pcd->pcd_start_pmc = cmn600_start_pmc; pcd->pcd_stop_pmc = cmn600_stop_pmc; pcd->pcd_write_pmc = cmn600_write_pmc; md->pmd_npmc += npmc; cmn600_pmcdesc = malloc(sizeof(struct cmn600_descr *) * npmc * CMN600_PMU_DEFAULT_UNITS_N, M_PMC, M_WAITOK|M_ZERO); for (i = 0; i < npmc; i++) { cmn600_pmcdesc[i] = malloc(sizeof(struct cmn600_descr), M_PMC, M_WAITOK|M_ZERO); unit = i / CMN600_COUNTERS_N; KASSERT(unit >= 0, ("unit >= 0")); KASSERT(cmn600_pmcs[unit].arg != NULL, ("arg != NULL")); cmn600_pmcdesc[i]->pd_rw_arg = cmn600_pmcs[unit].arg; cmn600_pmcdesc[i]->pd_descr.pd_class = PMC_CLASS_CMN600_PMU; cmn600_pmcdesc[i]->pd_descr.pd_caps = pcd->pcd_caps; cmn600_pmcdesc[i]->pd_phw = (struct pmc_hw *)malloc( sizeof(struct pmc_hw), M_PMC, M_WAITOK|M_ZERO); snprintf(cmn600_pmcdesc[i]->pd_descr.pd_name, 63, "CMN600_%d", i); cmn600_pmu_intr_cb(cmn600_pmcs[unit].arg, cmn600_pmu_intr); } return (0); } void pmc_cmn600_finalize(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc; KASSERT(md->pmd_classdep[PMC_MDEP_CLASS_INDEX_CMN600].pcd_class == PMC_CLASS_CMN600_PMU, ("[cmn600,%d] pmc class mismatch", __LINE__)); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_CMN600]; npmc = pcd->pcd_num; for (i = 0; i < npmc; i++) { free(cmn600_pmcdesc[i]->pd_phw, M_PMC); free(cmn600_pmcdesc[i], M_PMC); } free(cmn600_pmcdesc, M_PMC); cmn600_pmcdesc = NULL; } MODULE_DEPEND(pmc, cmn600, 1, 1, 1); diff --git a/sys/dev/hwpmc/hwpmc_dmc620.c b/sys/dev/hwpmc/hwpmc_dmc620.c index bd17d8a78093..653013e3f2ab 100644 --- a/sys/dev/hwpmc/hwpmc_dmc620.c +++ b/sys/dev/hwpmc/hwpmc_dmc620.c @@ -1,741 +1,741 @@ /*- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD * * Copyright (c) 2003-2008 Joseph Koshy * Copyright (c) 2007 The FreeBSD Foundation * Copyright (c) 2021 Ampere Computing LLC * * Portions of this software were developed by A. Joseph Koshy under * sponsorship from the FreeBSD Foundation and Google, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* Support for ARM DMC-620 Memory Controller PMU */ #include __FBSDID("$FreeBSD$"); #include #include #include #include #include #include #include #include #define DMC620_TYPE_CLKDIV2 0 #define DMC620_TYPE_CLK 1 #define CLASS2TYPE(c) ((c) - PMC_CLASS_DMC620_PMU_CD2) /* Create wrapper for each class. */ #define CLASSDEP_FN2(fn, t1, a1, t2, a2) \ static int fn(int class, t1 a1, t2 a2); \ static int fn ## _cd2(t1 a1, t2 a2) \ { \ return (fn(PMC_CLASS_DMC620_PMU_CD2, a1, a2)); \ } \ static int fn ## _c(t1 a1, t2 a2) \ { \ return (fn(PMC_CLASS_DMC620_PMU_C, a1, a2)); \ } \ static int fn(int class, t1 a1, t2 a2) #define CLASSDEP_FN3(fn, t1, a1, t2, a2, t3, a3) \ static int fn(int class, t1 a1, t2 a2, t3 a3); \ static int fn ## _cd2(t1 a1, t2 a2, t3 a3) \ { \ return (fn(PMC_CLASS_DMC620_PMU_CD2, a1, a2, a3)); \ } \ static int fn ## _c(t1 a1, t2 a2, t3 a3) \ { \ return (fn(PMC_CLASS_DMC620_PMU_C, a1, a2, a3)); \ } \ static int fn(int class, t1 a1, t2 a2, t3 a3) #define CLASSDEP_FN4(fn, t1, a1, t2, a2, t3, a3, t4, a4) \ static int fn(int class, t1 a1, t2 a2, t3 a3, t4 a4); \ static int fn ## _cd2(t1 a1, t2 a2, t3 a3, t4 a4) \ { \ return (fn(PMC_CLASS_DMC620_PMU_CD2, a1, a2, a3, a4)); \ } \ static int fn ## _c(t1 a1, t2 a2, t3 a3, t4 a4) \ { \ return (fn(PMC_CLASS_DMC620_PMU_C, a1, a2, a3, a4)); \ } \ static int fn(int class, t1 a1, t2 a2, t3 a3, t4 a4) struct dmc620_pmc { void *arg; int domain; }; struct dmc620_descr { struct pmc_descr pd_descr; /* "base class" */ void *pd_rw_arg; /* Argument to use with read/write */ struct pmc *pd_pmc; struct pmc_hw *pd_phw; uint32_t pd_config; uint32_t pd_match; uint32_t pd_mask; uint32_t pd_evsel; /* address of EVSEL register */ uint32_t pd_perfctr; /* address of PERFCTR register */ }; static struct dmc620_descr **dmc620_pmcdesc[2]; static struct dmc620_pmc dmc620_pmcs[DMC620_UNIT_MAX]; static int dmc620_npmcs = 0; void dmc620_pmc_register(int unit, void *arg, int domain) { if (unit >= DMC620_UNIT_MAX) { /* TODO */ return; } dmc620_pmcs[unit].arg = arg; dmc620_pmcs[unit].domain = domain; dmc620_npmcs++; } void dmc620_pmc_unregister(int unit) { dmc620_pmcs[unit].arg = NULL; dmc620_npmcs--; } int pmc_dmc620_nclasses() { if (dmc620_npmcs > 0) return (2); return (0); } static inline struct dmc620_descr * dmc620desc(int class, int cpu, int ri) { int c; c = CLASS2TYPE(class); KASSERT((c & 0xfffffffe) == 0, ("[dmc620,%d] 'c' can only be 0 or 1. " "now %d", __LINE__, c)); return (dmc620_pmcdesc[c][ri]); } static inline int cntr(int class, int ri) { int c; c = CLASS2TYPE(class); KASSERT((c & 0xfffffffe) == 0, ("[dmc620,%d] 'c' can only be 0 or 1. " "now %d", __LINE__, c)); if (c == DMC620_TYPE_CLKDIV2) return (ri % DMC620_CLKDIV2_COUNTERS_N); return ((ri % DMC620_CLK_COUNTERS_N) + DMC620_CLKDIV2_COUNTERS_N); } static inline int class2mdep(int class) { switch (class) { case PMC_CLASS_DMC620_PMU_CD2: return (PMC_MDEP_CLASS_INDEX_DMC620_CD2); case PMC_CLASS_DMC620_PMU_C: return (PMC_MDEP_CLASS_INDEX_DMC620_C); } return (-1); } static inline int class_ri2unit(int class, int ri) { if (class == PMC_CLASS_DMC620_PMU_CD2) return (ri / DMC620_CLKDIV2_COUNTERS_N); else return (ri / DMC620_CLK_COUNTERS_N); } /* * read a pmc register */ CLASSDEP_FN3(dmc620_read_pmc, int, cpu, int, ri, pmc_value_t *, v) { struct dmc620_descr *desc; struct pmc *pm; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); desc = dmc620desc(class, cpu, ri); pm = desc->pd_phw->phw_pmc; KASSERT(pm != NULL, ("[dmc620,%d] No owner for HWPMC [cpu%d,pmc%d]", __LINE__, cpu, ri)); PMCDBG3(MDP,REA,1,"%s id=%d class=%d", __func__, ri, class); /* * Should emulate 64bits, because 32 bits counter overflows faster than * pmcstat default period. */ /* Always CPU0. Single controller for all CPUs. */ *v = ((uint64_t)pm->pm_pcpu_state[0].pps_overflowcnt << 32) | pmu_dmc620_rd4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_VALUE_LO); PMCDBG3(MDP, REA, 2, "%s id=%d -> %jd", __func__, ri, *v); return (0); } /* * Write a pmc register. */ CLASSDEP_FN3(dmc620_write_pmc, int, cpu, int, ri, pmc_value_t, v) { struct dmc620_descr *desc; - struct pmc *pm; + struct pmc *pm __diagused; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); desc = dmc620desc(class, cpu, ri); pm = desc->pd_phw->phw_pmc; KASSERT(pm != NULL, ("[dmc620,%d] PMC not owned (cpu%d,pmc%d)", __LINE__, cpu, ri)); PMCDBG4(MDP, WRI, 1, "%s cpu=%d ri=%d v=%jx", __func__, cpu, ri, v); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_VALUE_LO, v); return (0); } /* * configure hardware pmc according to the configuration recorded in * pmc 'pm'. */ CLASSDEP_FN3(dmc620_config_pmc, int, cpu, int, ri, struct pmc *, pm) { struct pmc_hw *phw; PMCDBG4(MDP, CFG, 1, "%s cpu=%d ri=%d pm=%p", __func__, cpu, ri, pm); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); phw = dmc620desc(class, cpu, ri)->pd_phw; KASSERT(pm == NULL || phw->phw_pmc == NULL, ("[dmc620,%d] pm=%p phw->pm=%p hwpmc not unconfigured", __LINE__, pm, phw->phw_pmc)); phw->phw_pmc = pm; return (0); } /* * Retrieve a configured PMC pointer from hardware state. */ CLASSDEP_FN3(dmc620_get_config, int, cpu, int, ri, struct pmc **, ppm) { *ppm = dmc620desc(class, cpu, ri)->pd_phw->phw_pmc; return (0); } /* * Check if a given allocation is feasible. */ CLASSDEP_FN4(dmc620_allocate_pmc, int, cpu, int, ri, struct pmc *,pm, const struct pmc_op_pmcallocate *, a) { const struct pmc_descr *pd; uint64_t caps, control; enum pmc_event pe; uint8_t e; (void) cpu; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); pd = &dmc620desc(class, cpu, ri)->pd_descr; if (dmc620_pmcs[class_ri2unit(class, ri)].domain != pcpu_find(cpu)->pc_domain) return (EINVAL); /* check class match */ if (pd->pd_class != a->pm_class) return (EINVAL); caps = pm->pm_caps; PMCDBG3(MDP, ALL, 1, "%s ri=%d caps=0x%x", __func__, ri, caps); pe = a->pm_ev; if (class == PMC_CLASS_DMC620_PMU_CD2) e = pe - PMC_EV_DMC620_PMU_CD2_FIRST; else e = pe - PMC_EV_DMC620_PMU_C_FIRST; control = (e << DMC620_COUNTER_CONTROL_EVENT_SHIFT) & DMC620_COUNTER_CONTROL_EVENT_MASK; if (caps & PMC_CAP_INVERT) control |= DMC620_COUNTER_CONTROL_INVERT; pm->pm_md.pm_dmc620.pm_control = control; pm->pm_md.pm_dmc620.pm_match = a->pm_md.pm_dmc620.pm_dmc620_match; pm->pm_md.pm_dmc620.pm_mask = a->pm_md.pm_dmc620.pm_dmc620_mask; PMCDBG3(MDP, ALL, 2, "%s ri=%d -> control=0x%x", __func__, ri, control); return (0); } /* * Release machine dependent state associated with a PMC. This is a * no-op on this architecture. * */ /* ARGSUSED0 */ CLASSDEP_FN3(dmc620_release_pmc, int, cpu, int, ri, struct pmc *, pmc) { - struct pmc_hw *phw; + struct pmc_hw *phw __diagused; (void) pmc; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); phw = dmc620desc(class, cpu, ri)->pd_phw; KASSERT(phw->phw_pmc == NULL, ("[dmc620,%d] PHW pmc %p non-NULL", __LINE__, phw->phw_pmc)); return (0); } /* * start a PMC. */ CLASSDEP_FN2(dmc620_start_pmc, int, cpu, int, ri) { struct dmc620_descr *desc; struct pmc_hw *phw; uint64_t control; struct pmc *pm; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); desc = dmc620desc(class, cpu, ri); phw = desc->pd_phw; pm = phw->phw_pmc; KASSERT(pm != NULL, ("[dmc620,%d] starting cpu%d,pmc%d with null pmc record", __LINE__, cpu, ri)); PMCDBG3(MDP, STA, 1, "%s cpu=%d ri=%d", __func__, cpu, ri); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_MASK_LO, pm->pm_md.pm_dmc620.pm_mask & 0xffffffff); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_MASK_HI, pm->pm_md.pm_dmc620.pm_mask >> 32); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_MATCH_LO, pm->pm_md.pm_dmc620.pm_match & 0xffffffff); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_MATCH_HI, pm->pm_md.pm_dmc620.pm_match >> 32); /* turn on the PMC ENABLE bit */ control = pm->pm_md.pm_dmc620.pm_control | DMC620_COUNTER_CONTROL_ENABLE; PMCDBG2(MDP, STA, 2, "%s control=0x%x", __func__, control); pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_CONTROL, control); return (0); } /* * Stop a PMC. */ CLASSDEP_FN2(dmc620_stop_pmc, int, cpu, int, ri) { struct dmc620_descr *desc; struct pmc_hw *phw; struct pmc *pm; uint64_t control; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU value %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); desc = dmc620desc(class, cpu, ri); phw = desc->pd_phw; pm = phw->phw_pmc; KASSERT(pm != NULL, ("[dmc620,%d] cpu%d,pmc%d no PMC to stop", __LINE__, cpu, ri)); PMCDBG2(MDP, STO, 1, "%s ri=%d", __func__, ri); /* turn off the PMC ENABLE bit */ control = pm->pm_md.pm_dmc620.pm_control & ~DMC620_COUNTER_CONTROL_ENABLE; pmu_dmc620_wr4(desc->pd_rw_arg, cntr(class, ri), DMC620_COUNTER_CONTROL, control); return (0); } /* * describe a PMC */ CLASSDEP_FN4(dmc620_describe, int, cpu, int, ri, struct pmc_info *, pi, struct pmc **, ppmc) { struct pmc_hw *phw; size_t copied; int error; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] illegal CPU %d", __LINE__, cpu)); KASSERT(ri >= 0, ("[dmc620,%d] row-index %d out of range", __LINE__, ri)); phw = dmc620desc(class, cpu, ri)->pd_phw; if ((error = copystr(dmc620desc(class, cpu, ri)->pd_descr.pd_name, pi->pm_name, PMC_NAME_MAX, &copied)) != 0) return (error); pi->pm_class = dmc620desc(class, cpu, ri)->pd_descr.pd_class; if (phw->phw_state & PMC_PHW_FLAG_IS_ENABLED) { pi->pm_enabled = TRUE; *ppmc = phw->phw_pmc; } else { pi->pm_enabled = FALSE; *ppmc = NULL; } return (0); } /* * processor dependent initialization. */ CLASSDEP_FN2(dmc620_pcpu_init, struct pmc_mdep *, md, int, cpu) { int first_ri, n, npmc; struct pmc_hw *phw; struct pmc_cpu *pc; int mdep_class; mdep_class = class2mdep(class); KASSERT(mdep_class != -1, ("[dmc620,%d] wrong class %d", __LINE__, class)); KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] insane cpu number %d", __LINE__, cpu)); PMCDBG1(MDP, INI, 1, "dmc620-init cpu=%d", cpu); /* * Set the content of the hardware descriptors to a known * state and initialize pointers in the MI per-cpu descriptor. */ pc = pmc_pcpu[cpu]; first_ri = md->pmd_classdep[mdep_class].pcd_ri; npmc = md->pmd_classdep[mdep_class].pcd_num; for (n = 0; n < npmc; n++, phw++) { phw = dmc620desc(class, cpu, n)->pd_phw; phw->phw_state = PMC_PHW_CPU_TO_STATE(cpu) | PMC_PHW_INDEX_TO_STATE(n); /* Set enabled only if unit present. */ if (dmc620_pmcs[class_ri2unit(class, n)].arg != NULL) phw->phw_state |= PMC_PHW_FLAG_IS_ENABLED; phw->phw_pmc = NULL; pc->pc_hwpmcs[n + first_ri] = phw; } return (0); } /* * processor dependent cleanup prior to the KLD * being unloaded */ CLASSDEP_FN2(dmc620_pcpu_fini, struct pmc_mdep *, md, int, cpu) { return (0); } int dmc620_intr(struct trapframe *tf, int class, int unit, int i) { - struct pmc_cpu *pc; + struct pmc_cpu *pc __diagused; struct pmc_hw *phw; struct pmc *pm; int error, cpu, ri; ri = i + unit * ((class == PMC_CLASS_DMC620_PMU_CD2) ? DMC620_CLKDIV2_COUNTERS_N : DMC620_CLK_COUNTERS_N); cpu = curcpu; KASSERT(cpu >= 0 && cpu < pmc_cpu_max(), ("[dmc620,%d] CPU %d out of range", __LINE__, cpu)); pc = pmc_pcpu[cpu]; KASSERT(pc != NULL, ("pc != NULL")); phw = dmc620desc(class, cpu, ri)->pd_phw; KASSERT(phw != NULL, ("phw != NULL")); pm = phw->phw_pmc; if (pm == NULL) return (0); if (!PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) { /* Always CPU0. */ pm->pm_pcpu_state[0].pps_overflowcnt += 1; return (0); } if (pm->pm_state != PMC_STATE_RUNNING) return (0); error = pmc_process_interrupt(PMC_HR, pm, tf); if (error) dmc620_stop_pmc(class, cpu, ri); /* Reload sampling count */ dmc620_write_pmc(class, cpu, ri, pm->pm_sc.pm_reloadcount); return (0); } /* * Initialize ourselves. */ int pmc_dmc620_initialize_cd2(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc, unit; KASSERT(md != NULL, ("[dmc620,%d] md is NULL", __LINE__)); KASSERT(dmc620_npmcs <= DMC620_UNIT_MAX, ("[dmc620,%d] dmc620_npmcs too big", __LINE__)); PMCDBG0(MDP,INI,1, "dmc620-initialize"); npmc = DMC620_CLKDIV2_COUNTERS_N * dmc620_npmcs; pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_CD2]; pcd->pcd_caps = PMC_CAP_SYSTEM | PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_INTERRUPT | PMC_CAP_DOMWIDE; pcd->pcd_class = PMC_CLASS_DMC620_PMU_CD2; pcd->pcd_num = npmc; pcd->pcd_ri = md->pmd_npmc; pcd->pcd_width = 32; pcd->pcd_allocate_pmc = dmc620_allocate_pmc_cd2; pcd->pcd_config_pmc = dmc620_config_pmc_cd2; pcd->pcd_describe = dmc620_describe_cd2; pcd->pcd_get_config = dmc620_get_config_cd2; pcd->pcd_get_msr = NULL; pcd->pcd_pcpu_fini = dmc620_pcpu_fini_cd2; pcd->pcd_pcpu_init = dmc620_pcpu_init_cd2; pcd->pcd_read_pmc = dmc620_read_pmc_cd2; pcd->pcd_release_pmc = dmc620_release_pmc_cd2; pcd->pcd_start_pmc = dmc620_start_pmc_cd2; pcd->pcd_stop_pmc = dmc620_stop_pmc_cd2; pcd->pcd_write_pmc = dmc620_write_pmc_cd2; md->pmd_npmc += npmc; dmc620_pmcdesc[0] = malloc(sizeof(struct dmc620_descr *) * npmc * DMC620_PMU_DEFAULT_UNITS_N, M_PMC, M_WAITOK|M_ZERO); for (i = 0; i < npmc; i++) { dmc620_pmcdesc[0][i] = malloc(sizeof(struct dmc620_descr), M_PMC, M_WAITOK|M_ZERO); unit = i / DMC620_CLKDIV2_COUNTERS_N; KASSERT(unit >= 0, ("unit >= 0")); KASSERT(dmc620_pmcs[unit].arg != NULL, ("arg != NULL")); dmc620_pmcdesc[0][i]->pd_rw_arg = dmc620_pmcs[unit].arg; dmc620_pmcdesc[0][i]->pd_descr.pd_class = PMC_CLASS_DMC620_PMU_CD2; dmc620_pmcdesc[0][i]->pd_descr.pd_caps = pcd->pcd_caps; dmc620_pmcdesc[0][i]->pd_phw = malloc(sizeof(struct pmc_hw), M_PMC, M_WAITOK|M_ZERO); snprintf(dmc620_pmcdesc[0][i]->pd_descr.pd_name, 63, "DMC620_CD2_%d", i); } return (0); } int pmc_dmc620_initialize_c(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc, unit; KASSERT(md != NULL, ("[dmc620,%d] md is NULL", __LINE__)); KASSERT(dmc620_npmcs <= DMC620_UNIT_MAX, ("[dmc620,%d] dmc620_npmcs too big", __LINE__)); PMCDBG0(MDP,INI,1, "dmc620-initialize"); npmc = DMC620_CLK_COUNTERS_N * dmc620_npmcs; pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_C]; pcd->pcd_caps = PMC_CAP_SYSTEM | PMC_CAP_READ | PMC_CAP_WRITE | PMC_CAP_INVERT | PMC_CAP_QUALIFIER | PMC_CAP_INTERRUPT | PMC_CAP_DOMWIDE; pcd->pcd_class = PMC_CLASS_DMC620_PMU_C; pcd->pcd_num = npmc; pcd->pcd_ri = md->pmd_npmc; pcd->pcd_width = 32; pcd->pcd_allocate_pmc = dmc620_allocate_pmc_c; pcd->pcd_config_pmc = dmc620_config_pmc_c; pcd->pcd_describe = dmc620_describe_c; pcd->pcd_get_config = dmc620_get_config_c; pcd->pcd_get_msr = NULL; pcd->pcd_pcpu_fini = dmc620_pcpu_fini_c; pcd->pcd_pcpu_init = dmc620_pcpu_init_c; pcd->pcd_read_pmc = dmc620_read_pmc_c; pcd->pcd_release_pmc = dmc620_release_pmc_c; pcd->pcd_start_pmc = dmc620_start_pmc_c; pcd->pcd_stop_pmc = dmc620_stop_pmc_c; pcd->pcd_write_pmc = dmc620_write_pmc_c; md->pmd_npmc += npmc; dmc620_pmcdesc[1] = malloc(sizeof(struct dmc620_descr *) * npmc * DMC620_PMU_DEFAULT_UNITS_N, M_PMC, M_WAITOK|M_ZERO); for (i = 0; i < npmc; i++) { dmc620_pmcdesc[1][i] = malloc(sizeof(struct dmc620_descr), M_PMC, M_WAITOK|M_ZERO); unit = i / DMC620_CLK_COUNTERS_N; KASSERT(unit >= 0, ("unit >= 0")); KASSERT(dmc620_pmcs[unit].arg != NULL, ("arg != NULL")); dmc620_pmcdesc[1][i]->pd_rw_arg = dmc620_pmcs[unit].arg; dmc620_pmcdesc[1][i]->pd_descr.pd_class = PMC_CLASS_DMC620_PMU_C; dmc620_pmcdesc[1][i]->pd_descr.pd_caps = pcd->pcd_caps; dmc620_pmcdesc[1][i]->pd_phw = malloc(sizeof(struct pmc_hw), M_PMC, M_WAITOK|M_ZERO); snprintf(dmc620_pmcdesc[1][i]->pd_descr.pd_name, 63, "DMC620_C_%d", i); } return (0); } void pmc_dmc620_finalize_cd2(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc; KASSERT(md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_CD2].pcd_class == PMC_CLASS_DMC620_PMU_CD2, ("[dmc620,%d] pmc class mismatch", __LINE__)); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_CD2]; npmc = pcd->pcd_num; for (i = 0; i < npmc; i++) { free(dmc620_pmcdesc[0][i]->pd_phw, M_PMC); free(dmc620_pmcdesc[0][i], M_PMC); } free(dmc620_pmcdesc[0], M_PMC); dmc620_pmcdesc[0] = NULL; } void pmc_dmc620_finalize_c(struct pmc_mdep *md) { struct pmc_classdep *pcd; int i, npmc; KASSERT(md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_C].pcd_class == PMC_CLASS_DMC620_PMU_C, ("[dmc620,%d] pmc class mismatch", __LINE__)); pcd = &md->pmd_classdep[PMC_MDEP_CLASS_INDEX_DMC620_C]; npmc = pcd->pcd_num; for (i = 0; i < npmc; i++) { free(dmc620_pmcdesc[1][i]->pd_phw, M_PMC); free(dmc620_pmcdesc[1][i], M_PMC); } free(dmc620_pmcdesc[1], M_PMC); dmc620_pmcdesc[1] = NULL; }