Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm64/arm64/identcpu.c
Show First 20 Lines • Show All 108 Lines • ▼ Show 20 Lines | struct cpu_desc { | ||||
uint64_t id_aa64isar1; | uint64_t id_aa64isar1; | ||||
uint64_t id_aa64mmfr0; | uint64_t id_aa64mmfr0; | ||||
uint64_t id_aa64mmfr1; | uint64_t id_aa64mmfr1; | ||||
uint64_t id_aa64mmfr2; | uint64_t id_aa64mmfr2; | ||||
uint64_t id_aa64pfr0; | uint64_t id_aa64pfr0; | ||||
uint64_t id_aa64pfr1; | uint64_t id_aa64pfr1; | ||||
}; | }; | ||||
struct cpu_desc cpu_desc[MAXCPU]; | static struct cpu_desc cpu_desc[MAXCPU]; | ||||
struct cpu_desc user_cpu_desc; | static struct cpu_desc user_cpu_desc; | ||||
static u_int cpu_print_regs; | static u_int cpu_print_regs; | ||||
#define PRINT_ID_AA64_AFR0 0x00000001 | #define PRINT_ID_AA64_AFR0 0x00000001 | ||||
#define PRINT_ID_AA64_AFR1 0x00000002 | #define PRINT_ID_AA64_AFR1 0x00000002 | ||||
#define PRINT_ID_AA64_DFR0 0x00000010 | #define PRINT_ID_AA64_DFR0 0x00000010 | ||||
#define PRINT_ID_AA64_DFR1 0x00000020 | #define PRINT_ID_AA64_DFR1 0x00000020 | ||||
#define PRINT_ID_AA64_ISAR0 0x00000100 | #define PRINT_ID_AA64_ISAR0 0x00000100 | ||||
#define PRINT_ID_AA64_ISAR1 0x00000200 | #define PRINT_ID_AA64_ISAR1 0x00000200 | ||||
#define PRINT_ID_AA64_MMFR0 0x00001000 | #define PRINT_ID_AA64_MMFR0 0x00001000 | ||||
▲ Show 20 Lines • Show All 829 Lines • ▼ Show 20 Lines | for (i = 0; i < nitems(user_regs); i++) { | ||||
} | } | ||||
CPU_DESC_FIELD(user_cpu_desc, i) = cur; | CPU_DESC_FIELD(user_cpu_desc, i) = cur; | ||||
} | } | ||||
} | } | ||||
/* HWCAP */ | /* HWCAP */ | ||||
extern u_long elf_hwcap; | extern u_long elf_hwcap; | ||||
bool __read_frequently lse_supported = false; | |||||
static void | static void | ||||
identify_cpu_sysinit(void *dummy __unused) | identify_cpu_sysinit(void *dummy __unused) | ||||
{ | { | ||||
int cpu; | int cpu; | ||||
u_long hwcap; | u_long hwcap; | ||||
/* Create a user visible cpu description with safe values */ | /* Create a user visible cpu description with safe values */ | ||||
memset(&user_cpu_desc, 0, sizeof(user_cpu_desc)); | memset(&user_cpu_desc, 0, sizeof(user_cpu_desc)); | ||||
/* Safe values for these registers */ | /* Safe values for these registers */ | ||||
user_cpu_desc.id_aa64pfr0 = ID_AA64PFR0_AdvSIMD_NONE | | user_cpu_desc.id_aa64pfr0 = ID_AA64PFR0_AdvSIMD_NONE | | ||||
ID_AA64PFR0_FP_NONE | ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64; | ID_AA64PFR0_FP_NONE | ID_AA64PFR0_EL1_64 | ID_AA64PFR0_EL0_64; | ||||
user_cpu_desc.id_aa64dfr0 = ID_AA64DFR0_DebugVer_8; | user_cpu_desc.id_aa64dfr0 = ID_AA64DFR0_DebugVer_8; | ||||
CPU_FOREACH(cpu) { | CPU_FOREACH(cpu) { | ||||
print_cpu_features(cpu); | print_cpu_features(cpu); | ||||
hwcap = parse_cpu_features_hwcap(cpu); | hwcap = parse_cpu_features_hwcap(cpu); | ||||
if (elf_hwcap == 0) | if (elf_hwcap == 0) | ||||
elf_hwcap = hwcap; | elf_hwcap = hwcap; | ||||
else | else | ||||
elf_hwcap &= hwcap; | elf_hwcap &= hwcap; | ||||
update_user_regs(cpu); | update_user_regs(cpu); | ||||
} | } | ||||
if ((elf_hwcap & HWCAP_ATOMICS) != 0) { | |||||
lse_supported = true; | |||||
if (bootverbose) | |||||
printf("Enabling LSE atomics in the kernel\n"); | |||||
} | |||||
#ifdef LSE_ATOMICS | |||||
if (!lse_supported) | |||||
panic("CPU does not support LSE atomic instructions"); | |||||
#endif | |||||
install_undef_handler(true, user_mrs_handler); | install_undef_handler(true, user_mrs_handler); | ||||
} | } | ||||
SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); | SYSINIT(idenrity_cpu, SI_SUB_SMP, SI_ORDER_ANY, identify_cpu_sysinit, NULL); | ||||
static u_long | static u_long | ||||
parse_cpu_features_hwcap(u_int cpu) | parse_cpu_features_hwcap(u_int cpu) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 366 Lines • Show Last 20 Lines |