diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-09-30 21:48:33 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2019-09-30 21:48:33 +0000 |
commit | 289cf3ed97e55cd08c9bddd2c0c4cfabc8d717f9 (patch) | |
tree | 49235561c5cb171fbf05d8c0aa53dea536f3a664 | |
parent | 2879b446fc9e7ed04cabbc0df31cd0bb5f8f22ee (diff) |
Synch the cpu match/attach/identify code with arm64. This drops some
information from dmesg that is no longer relevant to ARMv7 CPUs in favour
of printing the full architected cache hierarchy in the same way as we
do on arm64. It also is another small step towards SMP support on armv7.
ok patrick@
-rw-r--r-- | sys/arch/arm/arm/cpu.c | 587 | ||||
-rw-r--r-- | sys/arch/arm/arm/cpufunc.c | 3 | ||||
-rw-r--r-- | sys/arch/arm/include/armreg.h | 37 | ||||
-rw-r--r-- | sys/arch/arm/include/cpu.h | 53 |
4 files changed, 384 insertions, 296 deletions
diff --git a/sys/arch/arm/arm/cpu.c b/sys/arch/arm/arm/cpu.c index b2ab59a75ca..02c88da1b7d 100644 --- a/sys/arch/arm/arm/cpu.c +++ b/sys/arch/arm/arm/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.50 2019/09/30 20:47:38 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.51 2019/09/30 21:48:32 kettenis Exp $ */ /* $NetBSD: cpu.c,v 1.56 2004/04/14 04:01:49 bsh Exp $ */ @@ -44,7 +44,6 @@ */ #include <sys/param.h> - #include <sys/systm.h> #include <sys/malloc.h> #include <sys/device.h> @@ -71,7 +70,83 @@ #include <dev/ofw/ofw_thermal.h> #include <dev/ofw/fdt.h> -char cpu_model[256]; +#include "psci.h" +#if NPSCI > 0 +#include <dev/fdt/pscivar.h> +#endif + +/* CPU Identification */ +#define CPU_IMPL_ARM 0x41 +#define CPU_IMPL_AMCC 0x50 + +#define CPU_PART_CORTEX_A5 0xc05 +#define CPU_PART_CORTEX_A7 0xc07 +#define CPU_PART_CORTEX_A8 0xc08 +#define CPU_PART_CORTEX_A9 0xc09 +#define CPU_PART_CORTEX_A12 0xc0d +#define CPU_PART_CORTEX_A15 0xc0f +#define CPU_PART_CORTEX_A17 0xc0e +#define CPU_PART_CORTEX_A32 0xd01 +#define CPU_PART_CORTEX_A53 0xd03 +#define CPU_PART_CORTEX_A35 0xd04 +#define CPU_PART_CORTEX_A55 0xd05 +#define CPU_PART_CORTEX_A57 0xd07 +#define CPU_PART_CORTEX_A72 0xd08 +#define CPU_PART_CORTEX_A73 0xd09 +#define CPU_PART_CORTEX_A75 0xd0a + +#define CPU_PART_X_GENE 0x000 + +#define CPU_IMPL(midr) (((midr) >> 24) & 0xff) +#define CPU_PART(midr) (((midr) >> 4) & 0xfff) +#define CPU_VAR(midr) (((midr) >> 20) & 0xf) +#define CPU_REV(midr) (((midr) >> 0) & 0xf) + +struct cpu_cores { + int id; + char *name; +}; + +struct cpu_cores cpu_cores_none[] = { + { 0, NULL }, +}; + +struct cpu_cores cpu_cores_arm[] = { + { CPU_PART_CORTEX_A5, "Cortex-A5" }, + { CPU_PART_CORTEX_A7, "Cortex-A7" }, + { CPU_PART_CORTEX_A8, "Cortex-A8" }, + { CPU_PART_CORTEX_A9, "Cortex-A9" }, + { CPU_PART_CORTEX_A12, "Cortex-A12" }, + { CPU_PART_CORTEX_A15, "Cortex-A15" }, + { CPU_PART_CORTEX_A17, "Cortex-A17" }, + { CPU_PART_CORTEX_A32, "Cortex-A32" }, + { CPU_PART_CORTEX_A35, "Cortex-A35" }, + { CPU_PART_CORTEX_A53, "Cortex-A53" }, + { CPU_PART_CORTEX_A55, "Cortex-A55" }, + { CPU_PART_CORTEX_A57, "Cortex-A57" }, + { CPU_PART_CORTEX_A72, "Cortex-A72" }, + { CPU_PART_CORTEX_A73, "Cortex-A73" }, + { CPU_PART_CORTEX_A75, "Cortex-A75" }, + { 0, NULL }, +}; + +struct cpu_cores cpu_cores_amcc[] = { + { CPU_PART_X_GENE, "X-Gene" }, + { 0, NULL }, +}; + +/* arm cores makers */ +const struct implementers { + int id; + char *name; + struct cpu_cores *corelist; +} cpu_implementers[] = { + { CPU_IMPL_ARM, "ARM", cpu_cores_arm }, + { CPU_IMPL_AMCC, "Applied Micro", cpu_cores_amcc }, + { 0, NULL }, +}; + +char cpu_model[64]; int cpu_node; int cpu_match(struct device *, void *, void *); @@ -88,318 +163,292 @@ struct cfdriver cpu_cd = { void cpu_opp_init_legacy(struct cpu_info *); void cpu_opp_init(struct cpu_info *, uint32_t); -void identify_arm_cpu(struct device *, struct cpu_info *); -int cpu_clockspeed(int *); +void cpu_flush_bp_noop(void); -int -cpu_match(struct device *parent, void *cfdata, void *aux) +void +cpu_identify(struct cpu_info *ci) { - struct fdt_attach_args *faa = aux; - char buf[32]; + uint32_t midr, impl, part; + uint32_t clidr; + uint32_t ctr, ccsidr, sets, ways, line; + const char *impl_name = NULL; + const char *part_name = NULL; + const char *il1p_name = NULL; + const char *sep; + struct cpu_cores *coreselecter = cpu_cores_none; + int i; - if (OF_getprop(faa->fa_node, "device_type", buf, sizeof(buf)) > 0 && - strcmp(buf, "cpu") == 0) - return 1; + __asm volatile("mrc p15, 0, %0, c0, c0, 0" : "=r"(midr)); + impl = CPU_IMPL(midr); + part = CPU_PART(midr); - return 0; -} + for (i = 0; cpu_implementers[i].name; i++) { + if (impl == cpu_implementers[i].id) { + impl_name = cpu_implementers[i].name; + coreselecter = cpu_implementers[i].corelist; + break; + } + } -void -cpu_attach(struct device *parent, struct device *dev, void *aux) -{ - struct fdt_attach_args *faa = aux; - struct cpu_info *ci; - uint32_t opp; + for (i = 0; coreselecter[i].name; i++) { + if (part == coreselecter[i].id) { + part_name = coreselecter[i].name; + break; + } + } - if (dev->dv_unit == 0) { - ci = curcpu(); - ci->ci_dev = dev; + if (impl_name && part_name) { + printf(" %s %s r%up%u", impl_name, part_name, CPU_VAR(midr), + CPU_REV(midr)); - /* Get the CPU ID from coprocessor 15 */ - ci->ci_arm_cpuid = cpu_id(); - ci->ci_arm_cputype = - ci->ci_arm_cpuid & CPU_ID_CPU_MASK; - ci->ci_arm_cpurev = - ci->ci_arm_cpuid & CPU_ID_REVISION_MASK; + if (CPU_IS_PRIMARY(ci)) + snprintf(cpu_model, sizeof(cpu_model), + "%s %s r%up%u", impl_name, part_name, + CPU_VAR(midr), CPU_REV(midr)); + } else { + printf(" Unknown, MIDR 0x%x", midr); - identify_arm_cpu(dev, ci); + if (CPU_IS_PRIMARY(ci)) + snprintf(cpu_model, sizeof(cpu_model), "Unknown"); + } - vfp_init(); + /* Print cache information. */ - if (OF_getproplen(faa->fa_node, "clocks") > 0) { - cpu_node = faa->fa_node; - cpu_cpuspeed = cpu_clockspeed; - } - } else { - printf(": not configured"); - return; + __asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r"(ctr)); + switch (ctr & CTR_IL1P_MASK) { + case CTR_IL1P_AIVIVT: + il1p_name = "AIVIVT "; + break; + case CTR_IL1P_VIPT: + il1p_name = "VIPT "; + break; + case CTR_IL1P_PIPT: + il1p_name = "PIPT "; + break; } - ci->ci_node = faa->fa_node; + __asm volatile("mrc p15, 1, %0, c0, c0, 1" : "=r"(clidr)); + for (i = 0; i < 7; i++) { + if ((clidr & CLIDR_CTYPE_MASK) == 0) + break; + printf("\n%s:", ci->ci_dev->dv_xname); + sep = ""; + if (clidr & CLIDR_CTYPE_INSN) { + __asm volatile("mcr p15, 2, %0, c0, c0, 0" :: + "r"(i << CSSELR_LEVEL_SHIFT | CSSELR_IND)); + __asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r"(ccsidr)); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d %sI-cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1), + il1p_name); + il1p_name = ""; + sep = ","; + } + if (clidr & CLIDR_CTYPE_DATA) { + __asm volatile("mcr p15, 2, %0, c0, c0, 0" :: + "r"(i << CSSELR_LEVEL_SHIFT)); + __asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r"(ccsidr)); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d D-cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1)); + sep = ","; + } + if (clidr & CLIDR_CTYPE_UNIFIED) { + __asm volatile("mcr p15, 2, %0, c0, c0, 0" :: + "r"(i << CSSELR_LEVEL_SHIFT)); + __asm volatile("mrc p15, 1, %0, c0, c0, 0" : "=r"(ccsidr)); + sets = CCSIDR_SETS(ccsidr); + ways = CCSIDR_WAYS(ccsidr); + line = CCSIDR_LINE_SIZE(ccsidr); + printf("%s %dKB %db/line %d-way L%d cache", sep, + (sets * ways * line) / 1024, line, ways, (i + 1)); + } + clidr >>= 3; + } - opp = OF_getpropint(ci->ci_node, "operating-points-v2", 0); - if (opp) - cpu_opp_init(ci, opp); - else - cpu_opp_init_legacy(ci); + /* + * Some ARM processors are vulnerable to branch target + * injection attacks (CVE-2017-5715). + */ + switch (impl) { + case CPU_IMPL_ARM: + switch (part) { + case CPU_PART_CORTEX_A5: + case CPU_PART_CORTEX_A7: + case CPU_PART_CORTEX_A32: + case CPU_PART_CORTEX_A35: + case CPU_PART_CORTEX_A53: + case CPU_PART_CORTEX_A55: + /* Not vulnerable. */ + ci->ci_flush_bp = cpu_flush_bp_noop; + break; + case CPU_PART_CORTEX_A8: + case CPU_PART_CORTEX_A9: + case CPU_PART_CORTEX_A12: + case CPU_PART_CORTEX_A17: + case CPU_PART_CORTEX_A73: + case CPU_PART_CORTEX_A75: + default: + /* Vulnerable; flush BP cache. */ + ci->ci_flush_bp = armv7_flush_bp; + break; + case CPU_PART_CORTEX_A15: + case CPU_PART_CORTEX_A72: + /* + * Vulnerable; BPIALL is "not effective" so + * must use ICIALLU and hope the firmware set + * the magic bit in the ACTLR that actually + * forces a BTB flush. + */ + ci->ci_flush_bp = cortex_a15_flush_bp; + break; + case CPU_PART_CORTEX_A57: + /* + * Vulnerable; must disable and enable the MMU + * which can be done by a PSCI call on + * firmware with the appropriate fixes. Punt + * for now. + */ + ci->ci_flush_bp = cpu_flush_bp_noop; + } + break; + default: + /* Not much we can do for an unknown processor. */ + ci->ci_flush_bp = cpu_flush_bp_noop; + break; + } } -enum cpu_class { - CPU_CLASS_NONE, - CPU_CLASS_ARMv7, - CPU_CLASS_ARMv8 -}; - -struct cpuidtab { - u_int32_t cpuid; - enum cpu_class cpu_class; - const char *cpu_name; -}; +int cpu_hatch_secondary(struct cpu_info *ci, int, uint64_t); +int cpu_clockspeed(int *); -const struct cpuidtab cpuids[] = { - { CPU_ID_CORTEX_A5, CPU_CLASS_ARMv7, "ARM Cortex-A5" }, - { CPU_ID_CORTEX_A7, CPU_CLASS_ARMv7, "ARM Cortex-A7" }, - { CPU_ID_CORTEX_A8, CPU_CLASS_ARMv7, "ARM Cortex-A8" }, - { CPU_ID_CORTEX_A9, CPU_CLASS_ARMv7, "ARM Cortex-A9" }, - { CPU_ID_CORTEX_A12, CPU_CLASS_ARMv7, "ARM Cortex-A12" }, - { CPU_ID_CORTEX_A15, CPU_CLASS_ARMv7, "ARM Cortex-A15" }, - { CPU_ID_CORTEX_A17, CPU_CLASS_ARMv7, "ARM Cortex-A17" }, - - { CPU_ID_CORTEX_A32, CPU_CLASS_ARMv8, "ARM Cortex-A32" }, - { CPU_ID_CORTEX_A35, CPU_CLASS_ARMv8, "ARM Cortex-A35" }, - { CPU_ID_CORTEX_A53, CPU_CLASS_ARMv8, "ARM Cortex-A53" }, - { CPU_ID_CORTEX_A55, CPU_CLASS_ARMv8, "ARM Cortex-A55" }, - { CPU_ID_CORTEX_A57, CPU_CLASS_ARMv8, "ARM Cortex-A57" }, - { CPU_ID_CORTEX_A72, CPU_CLASS_ARMv8, "ARM Cortex-A72" }, - { CPU_ID_CORTEX_A73, CPU_CLASS_ARMv8, "ARM Cortex-A73" }, - { CPU_ID_CORTEX_A75, CPU_CLASS_ARMv8, "ARM Cortex-A75" }, - - { 0, CPU_CLASS_NONE, NULL } -}; +int +cpu_match(struct device *parent, void *cfdata, void *aux) +{ + struct fdt_attach_args *faa = aux; + uint32_t mpidr; + char buf[32]; -struct cpu_classtab { - const char *class_name; - const char *class_option; -}; + __asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(mpidr)); -const char *cpu_classes[] = { - "unknown", /* CPU_CLASS_NONE */ - "ARMv7", /* CPU_CLASS_ARMv7 */ - "ARMv8" /* CPU_CLASS_ARMv8 */ -}; + if (OF_getprop(faa->fa_node, "device_type", buf, sizeof(buf)) <= 0 || + strcmp(buf, "cpu") != 0) + return 0; -/* - * Report the type of the specified arm processor. This uses the generic and - * arm specific information in the cpu structure to identify the processor. - * The remaining fields in the cpu structure are filled in appropriately. - */ + if (ncpus < MAXCPUS || faa->fa_reg[0].addr == (mpidr & MPIDR_AFF)) + return 1; -static const char * const wtnames[] = { - "wr-thru", - "wr-back", - "wr-back", - "**unknown 3**", - "**unknown 4**", - "wr-back-lock", /* XXX XScale-specific? */ - "wr-back-lock-A", - "wr-back-lock-B", - "**unknown 8**", - "**unknown 9**", - "**unknown 10**", - "**unknown 11**", - "**unknown 12**", - "**unknown 13**", - "**unknown 14**", - "**unknown 15**" -}; + return 0; +} void -identify_arm_cpu(struct device *dv, struct cpu_info *ci) +cpu_attach(struct device *parent, struct device *dev, void *aux) { - u_int cpuid; - enum cpu_class cpu_class = CPU_CLASS_NONE; - int i; + struct fdt_attach_args *faa = aux; + struct cpu_info *ci; + uint32_t mpidr; + uint32_t opp; - cpuid = ci->ci_arm_cpuid; + __asm volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(mpidr)); + KASSERT(faa->fa_nreg > 0); - if (cpuid == 0) { - printf("Processor failed probe - no CPU ID\n"); - return; + if (faa->fa_reg[0].addr == (mpidr & MPIDR_AFF)) { + ci = &cpu_info_primary; +#ifdef MULTIPROCESSOR + ci->ci_flags |= CPUF_RUNNING | CPUF_PRESENT | CPUF_PRIMARY; +#endif } - - for (i = 0; cpuids[i].cpuid != 0; i++) - if (cpuids[i].cpuid == (cpuid & CPU_ID_CORTEX_MASK)) { - cpu_class = cpuids[i].cpu_class; - snprintf(cpu_model, sizeof(cpu_model), - "%s r%dp%d (%s)", cpuids[i].cpu_name, - (cpuid & CPU_ID_VARIANT_MASK) >> 20, - cpuid & CPU_ID_REVISION_MASK, - cpu_classes[cpu_class]); - break; - } - - if (cpuids[i].cpuid == 0) - snprintf(cpu_model, sizeof(cpu_model), - "unknown CPU (ID = 0x%x)", cpuid); - - printf(": %s\n", cpu_model); - - printf("%s:", dv->dv_xname); - - switch (cpu_class) { - case CPU_CLASS_ARMv7: - case CPU_CLASS_ARMv8: - if ((ci->ci_ctrl & CPU_CONTROL_DC_ENABLE) == 0) - printf(" DC disabled"); - else - printf(" DC enabled"); - if ((ci->ci_ctrl & CPU_CONTROL_IC_ENABLE) == 0) - printf(" IC disabled"); - else - printf(" IC enabled"); - break; - default: - break; +#ifdef MULTIPROCESSOR + else { + ci = malloc(sizeof(*ci), M_DEVBUF, M_WAITOK | M_ZERO); + cpu_info[dev->dv_unit] = ci; + ci->ci_next = cpu_info_list->ci_next; + cpu_info_list->ci_next = ci; + ci->ci_flags |= CPUF_AP; + ncpus++; } - if ((ci->ci_ctrl & CPU_CONTROL_WBUF_ENABLE) == 0) - printf(" WB disabled"); - else - printf(" WB enabled"); - - if (ci->ci_ctrl & CPU_CONTROL_LABT_ENABLE) - printf(" LABT"); - else - printf(" EABT"); - - if (ci->ci_ctrl & CPU_CONTROL_BPRD_ENABLE) - printf(" branch prediction enabled"); +#endif - printf("\n"); + ci->ci_dev = dev; + ci->ci_cpuid = dev->dv_unit; + ci->ci_mpidr = faa->fa_reg[0].addr; + ci->ci_node = faa->fa_node; + ci->ci_self = ci; - /* - * Some ARM processors are vulnerable to branch target - * injection attacks. - */ - switch (cpuid & CPU_ID_CORTEX_MASK) { - case CPU_ID_CORTEX_A5: - case CPU_ID_CORTEX_A7: - case CPU_ID_CORTEX_A32: - case CPU_ID_CORTEX_A35: - case CPU_ID_CORTEX_A53: - case CPU_ID_CORTEX_A55: - /* Not vulnerable; no need to flush. */ - ci->ci_flush_bp = cpufunc_nullop; - break; - case CPU_ID_CORTEX_A8: - case CPU_ID_CORTEX_A9: - case CPU_ID_CORTEX_A12: - case CPU_ID_CORTEX_A17: - case CPU_ID_CORTEX_A73: - case CPU_ID_CORTEX_A75: - default: - /* Vulnerable; flush BP cache. */ - ci->ci_flush_bp = armv7_flush_bp; - break; - case CPU_ID_CORTEX_A15: - case CPU_ID_CORTEX_A72: - /* - * Vulnerable; BPIALL is "not effective" so must use - * ICIALLU and hope the firmware set the magic bit in - * the ACTLR that actually forces a BTB flush. - */ - ci->ci_flush_bp = cortex_a15_flush_bp; - break; - case CPU_ID_CORTEX_A57: - /* - * Vulnerable; must disable and enable the MMU which - * can be done by a PSCI call on firmware with the - * appropriate fixes. Punt for now. - */ - ci->ci_flush_bp = cpufunc_nullop; - break; - } + printf(" mpidr %llx:", ci->ci_mpidr); - /* Print cache info. */ - if (arm_picache_line_size == 0 && arm_pdcache_line_size == 0) - goto skip_pcache; +#ifdef MULTIPROCESSOR + if (ci->ci_flags & CPUF_AP) { + char buf[32]; + uint64_t spinup_data = 0; + int spinup_method = 0; + int timeout = 10000; + int len; + + len = OF_getprop(ci->ci_node, "enable-method", + buf, sizeof(buf)); + if (strcmp(buf, "psci") == 0) { + spinup_method = 1; + } else if (strcmp(buf, "spin-table") == 0) { + spinup_method = 2; + spinup_data = OF_getpropint64(ci->ci_node, + "cpu-release-addr", 0); + } - if (arm_pcache_unified) { - printf("%s: %dKB/%dB %d-way %s unified cache\n", - dv->dv_xname, arm_pdcache_size / 1024, - arm_pdcache_line_size, arm_pdcache_ways, - wtnames[arm_pcache_type]); + sched_init_cpu(ci); + if (cpu_hatch_secondary(ci, spinup_method, spinup_data)) { + atomic_setbits_int(&ci->ci_flags, CPUF_IDENTIFY); + __asm volatile("dsb sy; sev"); + + while ((ci->ci_flags & CPUF_IDENTIFIED) == 0 && + --timeout) + delay(1000); + if (timeout == 0) { + printf(" failed to identify"); + ci->ci_flags = 0; + } + } else { + printf(" failed to spin up"); + ci->ci_flags = 0; + } } else { - printf("%s: %dKB(%db/l,%dway) I-cache, %dKB(%db/l,%dway) %s D-cache\n", - dv->dv_xname, arm_picache_size / 1024, - arm_picache_line_size, arm_picache_ways, - arm_pdcache_size / 1024, arm_pdcache_line_size, - arm_pdcache_ways, wtnames[arm_pcache_type]); - } +#endif + cpu_identify(ci); - skip_pcache: + vfp_init(); - switch (cpu_class) { - case CPU_CLASS_ARMv7: - case CPU_CLASS_ARMv8: - break; - default: - printf("%s: %s does not fully support this CPU." - "\n", dv->dv_xname, ostype); - break; + if (OF_getproplen(ci->ci_node, "clocks") > 0) { + cpu_node = ci->ci_node; + cpu_cpuspeed = cpu_clockspeed; + } +#ifdef MULTIPROCESSOR } -} +#endif -int -cpu_clockspeed(int *freq) -{ - *freq = clock_get_frequency(cpu_node, NULL) / 1000000; - return 0; -} + opp = OF_getpropint(ci->ci_node, "operating-points-v2", 0); + if (opp) + cpu_opp_init(ci, opp); + else + cpu_opp_init_legacy(ci); -#ifdef MULTIPROCESSOR + printf("\n"); +} void -cpu_boot_secondary_processors(void) +cpu_flush_bp_noop(void) { } int -cpu_alloc_idle_pcb(struct cpu_info *ci) +cpu_clockspeed(int *freq) { - vaddr_t uaddr; - struct pcb *pcb; - struct trapframe *tf; - - /* - * Generate a kernel stack and PCB (in essence, a u-area) for the - * new CPU. - */ - uaddr = (vaddr_t)km_alloc(USPACE, &kv_any, &kp_zero, &kd_nowait); - if (uaddr == 0) { - printf("%s: unable to allocate idle stack\n", - __func__); - return ENOMEM; - } - ci->ci_idle_pcb = pcb = (struct pcb *)uaddr; - - /* - * This code is largely derived from cpu_fork(), with which it - * should perhaps be shared. - */ - - /* Copy the pcb */ - *pcb = proc0.p_addr->u_pcb; - - /* Set up the undefined stack for the process. */ - pcb->pcb_un.un_32.pcb32_und_sp = uaddr + USPACE_UNDEF_STACK_TOP; - pcb->pcb_un.un_32.pcb32_sp = uaddr + USPACE_SVC_STACK_TOP; - - pcb->pcb_tf = tf = - (struct trapframe *)pcb->pcb_un.un_32.pcb32_sp - 1; - *tf = *proc0.p_addr->u_pcb.pcb_tf; + *freq = clock_get_frequency(cpu_node, NULL) / 1000000; return 0; } -#endif /* MULTIPROCESSOR */ /* * Dynamic voltage and frequency scaling implementation. diff --git a/sys/arch/arm/arm/cpufunc.c b/sys/arch/arm/arm/cpufunc.c index 634d693b169..202c9078f2d 100644 --- a/sys/arch/arm/arm/cpufunc.c +++ b/sys/arch/arm/arm/cpufunc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpufunc.c,v 1.54 2018/06/04 22:10:58 kettenis Exp $ */ +/* $OpenBSD: cpufunc.c,v 1.55 2019/09/30 21:48:32 kettenis Exp $ */ /* $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */ /* @@ -423,7 +423,6 @@ armv7_setup() cpu_auxcontrol(auxctrlmask, auxctrl); /* Set the control register */ - curcpu()->ci_ctrl = cpuctrl; cpu_control(cpuctrlmask, cpuctrl); /* And again. */ diff --git a/sys/arch/arm/include/armreg.h b/sys/arch/arm/include/armreg.h index 25dd0b5cce7..612173dab60 100644 --- a/sys/arch/arm/include/armreg.h +++ b/sys/arch/arm/include/armreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: armreg.h,v 1.42 2017/08/20 04:22:57 jsg Exp $ */ +/* $OpenBSD: armreg.h,v 1.43 2019/09/30 21:48:32 kettenis Exp $ */ /* $NetBSD: armreg.h,v 1.27 2003/09/06 08:43:02 rearnsha Exp $ */ /* @@ -40,6 +40,41 @@ #ifndef _ARM_ARMREG_H #define _ARM_ARMREG_H +/* CCSIDR - Current Cache Size ID Register */ +#define CCSIDR_SETS_MASK 0x0fffe000 +#define CCSIDR_SETS_SHIFT 13 +#define CCSIDR_SETS(reg) \ + ((((reg) & CCSIDR_SETS_MASK) >> CCSIDR_SETS_SHIFT) + 1) +#define CCSIDR_WAYS_MASK 0x00001ff8 +#define CCSIDR_WAYS_SHIFT 3 +#define CCSIDR_WAYS(reg) \ + ((((reg) & CCSIDR_WAYS_MASK) >> CCSIDR_WAYS_SHIFT) + 1) +#define CCSIDR_LINE_MASK 0x00000007 +#define CCSIDR_LINE_SIZE(reg) (1 << (((reg) & CCSIDR_LINE_MASK) + 4)) + +/* CLIDR - Cache Level ID Register */ +#define CLIDR_CTYPE_MASK 0x7 +#define CLIDR_CTYPE_INSN 0x1 +#define CLIDR_CTYPE_DATA 0x2 +#define CLIDR_CTYPE_UNIFIED 0x4 + +/* CSSELR - Cache Size Selection Register */ +#define CSSELR_IND (1 << 0) +#define CSSELR_LEVEL_SHIFT 1 + +/* CTR - Cache Type Register */ +#define CTR_DLINE_SHIFT 16 +#define CTR_DLINE_MASK (0xf << CTR_DLINE_SHIFT) +#define CTR_DLINE_SIZE(reg) (((reg) & CTR_DLINE_MASK) >> CTR_DLINE_SHIFT) +#define CTR_IL1P_SHIFT 14 +#define CTR_IL1P_MASK (0x3 << CTR_IL1P_SHIFT) +#define CTR_IL1P_AIVIVT (0x1 << CTR_IL1P_SHIFT) +#define CTR_IL1P_VIPT (0x2 << CTR_IL1P_SHIFT) +#define CTR_IL1P_PIPT (0x3 << CTR_IL1P_SHIFT) +#define CTR_ILINE_SHIFT 0 +#define CTR_ILINE_MASK (0xf << CTR_ILINE_SHIFT) +#define CTR_ILINE_SIZE(reg) (((reg) & CTR_ILINE_MASK) >> CTR_ILINE_SHIFT) + /* * ARM Process Status Register * diff --git a/sys/arch/arm/include/cpu.h b/sys/arch/arm/include/cpu.h index 531ffd3767e..445dd08b241 100644 --- a/sys/arch/arm/include/cpu.h +++ b/sys/arch/arm/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.54 2019/09/23 18:10:43 kettenis Exp $ */ +/* $OpenBSD: cpu.h,v 1.55 2019/09/30 21:48:32 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.34 2003/06/23 11:01:08 martin Exp $ */ /* @@ -152,31 +152,31 @@ void arm32_vector_init(vaddr_t, int); #include <sys/srp.h> struct cpu_info { - struct device *ci_dev; /* Device corresponding to this CPU */ - struct cpu_info *ci_next; + struct device *ci_dev; /* Device corresponding to this CPU */ + struct cpu_info *ci_next; struct schedstate_percpu ci_schedstate; /* scheduler state */ + u_int32_t ci_cpuid; + uint64_t ci_mpidr; int ci_node; - - struct proc *ci_curproc; - struct proc *ci_fpuproc; - u_int32_t ci_cpuid; - u_int32_t ci_randseed; - - struct pcb *ci_curpcb; - struct pcb *ci_idle_pcb; - - u_int32_t ci_arm_cpuid; /* aggregate CPU id */ - u_int32_t ci_arm_cputype; /* CPU type */ - u_int32_t ci_arm_cpurev; /* CPU revision */ - u_int32_t ci_ctrl; /* The CPU control register */ - - uint32_t ci_cpl; - uint32_t ci_ipending; - uint32_t ci_idepth; + struct cpu_info *ci_self; + + struct proc *ci_curproc; + struct proc *ci_fpuproc; + u_int32_t ci_randseed; + + struct pcb *ci_curpcb; + struct pcb *ci_idle_pcb; + + uint32_t ci_cpl; + uint32_t ci_ipending; + uint32_t ci_idepth; #ifdef DIAGNOSTIC - int ci_mutex_level; + int ci_mutex_level; #endif + int ci_want_resched; + + void (*ci_flush_bp)(void); struct opp_table *ci_opp_table; volatile int ci_opp_idx; @@ -190,10 +190,16 @@ struct cpu_info { #ifdef GPROF struct gmonparam *ci_gmon; #endif - - void (*ci_flush_bp)(void); }; +#define CPUF_PRIMARY (1<<0) +#define CPUF_AP (1<<1) +#define CPUF_IDENTIFY (1<<2) +#define CPUF_IDENTIFIED (1<<3) +#define CPUF_PRESENT (1<<4) +#define CPUF_GO (1<<5) +#define CPUF_RUNNING (1<<6) + static inline struct cpu_info * curcpu(void) { @@ -220,7 +226,6 @@ extern struct cpu_info *cpu_info_list; #define CPU_INFO_ITERATOR int #define CPU_INFO_FOREACH(cii, ci) for (cii = 0, ci = cpu_info_list; \ ci != NULL; ci = ci->ci_next) - #define CPU_INFO_UNIT(ci) ((ci)->ci_dev ? (ci)->ci_dev->dv_unit : 0) #define MAXCPUS 4 #define cpu_unidle(ci) |