ソースを参照

waterDataStatisticsCrossAssociation correlationCalculationWaterTankSpray.c 徐寅秋 commit at 2021-03-25

徐寅秋 4 年 前
コミット
27d3904289

+ 106 - 0
waterDataStatisticsCrossAssociation/waterTankDataAssociation/correlationCalculationWaterTankSpray.c

@@ -626,3 +626,109 @@ int vfp_restore_user_hwstate(struct user_vfp __user *ufp,
 
 	return err ? -EFAULT : 0;
 }
+
+/*
+ * VFP hardware can lose all context when a CPU goes offline.
+ * As we will be running in SMP mode with CPU hotplug, we will save the
+ * hardware state at every thread switch.  We clear our held state when
+ * a CPU has been killed, indicating that the VFP hardware doesn't contain
+ * a threads VFP state.  When a CPU starts up, we re-enable access to the
+ * VFP hardware.
+ *
+ * Both CPU_DYING and CPU_STARTING are called on the CPU which
+ * is being offlined/onlined.
+ */
+static int vfp_hotplug(struct notifier_block *b, unsigned long action,
+	void *hcpu)
+{
+	if (action == CPU_DYING || action == CPU_DYING_FROZEN) {
+		vfp_force_reload((long)hcpu, current_thread_info());
+	} else if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
+		vfp_enable(NULL);
+	return NOTIFY_OK;
+}
+
+/*
+ * VFP support code initialisation.
+ */
+static int __init vfp_init(void)
+{
+	unsigned int vfpsid;
+	unsigned int cpu_arch = cpu_architecture();
+
+	if (cpu_arch >= CPU_ARCH_ARMv6)
+		on_each_cpu(vfp_enable, NULL, 1);
+
+	/*
+	 * First check that there is a VFP that we can use.
+	 * The handler is already setup to just log calls, so
+	 * we just need to read the VFPSID register.
+	 */
+	vfp_vector = vfp_testing_entry;
+	barrier();
+	vfpsid = fmrx(FPSID);
+	barrier();
+	vfp_vector = vfp_null_entry;
+
+	pr_info("VFP support v0.3: ");
+	if (VFP_arch)
+		pr_cont("not present\n");
+	else if (vfpsid & FPSID_NODOUBLE) {
+		pr_cont("no double precision support\n");
+	} else {
+		hotcpu_notifier(vfp_hotplug, 0);
+
+		VFP_arch = (vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT;  /* Extract the architecture version */
+		pr_cont("implementor %02x architecture %d part %02x variant %x rev %x\n",
+			(vfpsid & FPSID_IMPLEMENTER_MASK) >> FPSID_IMPLEMENTER_BIT,
+			(vfpsid & FPSID_ARCH_MASK) >> FPSID_ARCH_BIT,
+			(vfpsid & FPSID_PART_MASK) >> FPSID_PART_BIT,
+			(vfpsid & FPSID_VARIANT_MASK) >> FPSID_VARIANT_BIT,
+			(vfpsid & FPSID_REV_MASK) >> FPSID_REV_BIT);
+
+		vfp_vector = vfp_support_entry;
+
+		thread_register_notifier(&vfp_notifier_block);
+		vfp_pm_init();
+
+		/*
+		 * We detected VFP, and the support code is
+		 * in place; report VFP support to userspace.
+		 */
+		elf_hwcap |= HWCAP_VFP;
+#ifdef CONFIG_VFPv3
+		if (VFP_arch >= 2) {
+			elf_hwcap |= HWCAP_VFPv3;
+
+			/*
+			 * Check for VFPv3 D16 and VFPv4 D16.  CPUs in
+			 * this configuration only have 16 x 64bit
+			 * registers.
+			 */
+			if (((fmrx(MVFR0) & MVFR0_A_SIMD_MASK)) == 1)
+				elf_hwcap |= HWCAP_VFPv3D16; /* also v4-D16 */
+			else
+				elf_hwcap |= HWCAP_VFPD32;
+		}
+#endif
+		/*
+		 * Check for the presence of the Advanced SIMD
+		 * load/store instructions, integer and single
+		 * precision floating point operations. Only check
+		 * for NEON if the hardware has the MVFR registers.
+		 */
+		if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) {
+#ifdef CONFIG_NEON
+			if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100)
+				elf_hwcap |= HWCAP_NEON;
+#endif
+#ifdef CONFIG_VFPv3
+			if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000)
+				elf_hwcap |= HWCAP_VFPv4;
+#endif
+		}
+	}
+	return 0;
+}
+
+late_initcall(vfp_init);