Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/identcpu.c
| Show First 20 Lines • Show All 2,820 Lines • ▼ Show 20 Lines | CPU_FOREACH(cpu) { | ||||
| if (CTR_DIC_VAL(desc->ctr) == 0) | if (CTR_DIC_VAL(desc->ctr) == 0) | ||||
| dic = false; | dic = false; | ||||
| if (CTR_IDC_VAL(desc->ctr) == 0) | if (CTR_IDC_VAL(desc->ctr) == 0) | ||||
| idc = false; | idc = false; | ||||
| prev_desc = desc; | prev_desc = desc; | ||||
| } | } | ||||
| if (dic && idc) { | |||||
| arm64_icache_sync_range = &arm64_dic_idc_icache_sync_range; | |||||
| if (bootverbose) | |||||
| printf("Enabling DIC & IDC ICache sync\n"); | |||||
| } else if (idc) { | |||||
| arm64_icache_sync_range = &arm64_idc_aliasing_icache_sync_range; | |||||
| if (bootverbose) | |||||
| printf("Enabling IDC ICache sync\n"); | |||||
| } | |||||
| } | |||||
| /* | |||||
| * This needs to run early to ensure the kernel ID registers have been | |||||
| * updated for all CPUs before they are used by ifunc resolvers, etc. | |||||
| */ | |||||
| SYSINIT(identify_cpu, SI_SUB_CPU, SI_ORDER_MIDDLE, | |||||
| identify_cpu_sysinit, NULL); | |||||
| static void | |||||
| identify_hwcaps_sysinit(void *dummy __unused) | |||||
| { | |||||
| #ifdef INVARIANTS | #ifdef INVARIANTS | ||||
| /* Check we dont update the special registers after this point */ | /* Check we dont update the special registers after this point */ | ||||
| hwcaps_set = true; | hwcaps_set = true; | ||||
| #endif | #endif | ||||
| /* Find the values to export to userspace as AT_HWCAP and AT_HWCAP2 */ | /* Find the values to export to userspace as AT_HWCAP and AT_HWCAP2 */ | ||||
| parse_cpu_features(true, &user_cpu_desc, &elf_hwcap, &elf_hwcap2); | parse_cpu_features(true, &user_cpu_desc, &elf_hwcap, &elf_hwcap2); | ||||
| parse_cpu_features(true, &l_user_cpu_desc, &linux_elf_hwcap, | parse_cpu_features(true, &l_user_cpu_desc, &linux_elf_hwcap, | ||||
| &linux_elf_hwcap2); | &linux_elf_hwcap2); | ||||
| #ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
| parse_cpu_features(false, &user_cpu_desc, &elf32_hwcap, &elf32_hwcap2); | parse_cpu_features(false, &user_cpu_desc, &elf32_hwcap, &elf32_hwcap2); | ||||
| #endif | #endif | ||||
| /* We export the CPUID registers */ | /* We export the CPUID registers */ | ||||
| elf_hwcap |= HWCAP_CPUID; | elf_hwcap |= HWCAP_CPUID; | ||||
| linux_elf_hwcap |= HWCAP_CPUID; | linux_elf_hwcap |= HWCAP_CPUID; | ||||
| #ifdef COMPAT_FREEBSD32 | #ifdef COMPAT_FREEBSD32 | ||||
| /* Set the default caps and any that need to check multiple fields */ | /* Set the default caps and any that need to check multiple fields */ | ||||
| elf32_hwcap |= parse_cpu_features_hwcap32(); | elf32_hwcap |= parse_cpu_features_hwcap32(); | ||||
| #endif | #endif | ||||
| if (dic && idc) { | |||||
| arm64_icache_sync_range = &arm64_dic_idc_icache_sync_range; | |||||
| if (bootverbose) | |||||
| printf("Enabling DIC & IDC ICache sync\n"); | |||||
| } else if (idc) { | |||||
| arm64_icache_sync_range = &arm64_idc_aliasing_icache_sync_range; | |||||
| if (bootverbose) | |||||
| printf("Enabling IDC ICache sync\n"); | |||||
| } | |||||
| if ((elf_hwcap & HWCAP_ATOMICS) != 0) { | if ((elf_hwcap & HWCAP_ATOMICS) != 0) { | ||||
| lse_supported = true; | lse_supported = true; | ||||
| if (bootverbose) | if (bootverbose) | ||||
| printf("Enabling LSE atomics in the kernel\n"); | printf("Enabling LSE atomics in the kernel\n"); | ||||
| } | } | ||||
| #ifdef LSE_ATOMICS | #ifdef LSE_ATOMICS | ||||
| if (!lse_supported) | if (!lse_supported) | ||||
| panic("CPU does not support LSE atomic instructions"); | panic("CPU does not support LSE atomic instructions"); | ||||
| #endif | #endif | ||||
| install_sys_handler(user_ctr_handler); | install_sys_handler(user_ctr_handler); | ||||
| install_sys_handler(user_idreg_handler); | install_sys_handler(user_idreg_handler); | ||||
| } | } | ||||
| /* | /* | ||||
| * This needs to be after the APs have stareted as they may have errata that | * This needs to be after the APs have started as they may have errata that | ||||
| * means we need to mask out ID registers & that could affect hwcaps, etc. | * means we need to mask out ID registers & that could affect hwcaps, etc. | ||||
| * | |||||
| * The errata handling runs at SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 1, so this | |||||
| * needs to be later than that. | |||||
| */ | */ | ||||
| SYSINIT(identify_cpu, SI_SUB_CONFIGURE, SI_ORDER_ANY, identify_cpu_sysinit, | SYSINIT(identify_hwcaps, SI_SUB_CONFIGURE, SI_ORDER_MIDDLE + 2, | ||||
| NULL); | identify_hwcaps_sysinit, NULL); | ||||
| static void | static void | ||||
| cpu_features_sysinit(void *dummy __unused) | cpu_features_sysinit(void *dummy __unused) | ||||
| { | { | ||||
| struct sbuf sb; | struct sbuf sb; | ||||
| struct cpu_desc *desc, *prev_desc; | struct cpu_desc *desc, *prev_desc; | ||||
| u_int cpu; | u_int cpu; | ||||
| ▲ Show 20 Lines • Show All 534 Lines • Show Last 20 Lines | |||||