Loading arch/arc/include/asm/arcregs.h +53 −24 Original line number Diff line number Diff line Loading @@ -12,14 +12,13 @@ /* Build Configuration Registers */ #define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ #define ARC_REG_CRC_BCR 0x62 #define ARC_REG_DVFB_BCR 0x64 #define ARC_REG_EXTARITH_BCR 0x65 #define ARC_REG_VECBASE_BCR 0x68 #define ARC_REG_PERIBASE_BCR 0x69 #define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ #define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ #define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */ #define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */ #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ #define ARC_REG_TIMERS_BCR 0x75 #define ARC_REG_AP_BCR 0x76 #define ARC_REG_ICCM_BCR 0x78 #define ARC_REG_XY_MEM_BCR 0x79 #define ARC_REG_MAC_BCR 0x7a Loading @@ -29,6 +28,9 @@ #define ARC_REG_MIXMAX_BCR 0x7e #define ARC_REG_BARREL_BCR 0x7f #define ARC_REG_D_UNCACH_BCR 0x6A #define ARC_REG_BPU_BCR 0xc0 #define ARC_REG_ISA_CFG_BCR 0xc1 #define ARC_REG_SMART_BCR 0xFF /* status32 Bits Positions */ #define STATUS_AE_BIT 5 /* Exception active */ Loading Loading @@ -202,27 +204,19 @@ struct bcr_identity { #endif }; #define EXTN_SWAP_VALID 0x1 #define EXTN_NORM_VALID 0x2 #define EXTN_MINMAX_VALID 0x2 #define EXTN_BARREL_VALID 0x2 struct bcr_extn { struct bcr_isa { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2, norm:2, swap:1; unsigned int pad1:23, atomic1:1, ver:8; #else unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2, crc:1, pad:20; unsigned int ver:8, atomic1:1, pad1:23; #endif }; /* DSP Options Ref Manual */ struct bcr_extn_mac_mul { struct bcr_mpy { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:16, type:8, ver:8; unsigned int pad:8, x1616:8, dsp:4, cycles:2, type:2, ver:8; #else unsigned int ver:8, type:8, pad:16; unsigned int ver:8, type:2, cycles:2, dsp:4, x1616:8, pad:8; #endif }; Loading @@ -241,6 +235,7 @@ struct bcr_perip { unsigned int pad:8, sz:8, pad2:8, start:8; #endif }; struct bcr_iccm { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int base:16, pad:5, sz:3, ver:8; Loading @@ -267,8 +262,8 @@ struct bcr_dccm { #endif }; /* Both SP and DP FPU BCRs have same format */ struct bcr_fp { /* ARCompact: Both SP and DP FPU BCRs have same format */ struct bcr_fp_arcompact { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int fast:1, ver:8; #else Loading @@ -276,6 +271,30 @@ struct bcr_fp { #endif }; struct bcr_timer { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8; #else unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15; #endif }; struct bcr_bpu_arcompact { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad2:19, fam:1, pad:2, ent:2, ver:8; #else unsigned int ver:8, ent:2, pad:2, fam:1, pad2:19; #endif }; struct bcr_generic { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:24, ver:8; #else unsigned int ver:8, pad:24; #endif }; /* ******************************************************************* * Generic structures to hold build configuration used at runtime Loading @@ -289,6 +308,10 @@ struct cpuinfo_arc_cache { unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6; }; struct cpuinfo_arc_bpu { unsigned int ver, full, num_cache, num_pred; }; struct cpuinfo_arc_ccm { unsigned int base_addr, sz; }; Loading @@ -296,15 +319,21 @@ struct cpuinfo_arc_ccm { struct cpuinfo_arc { struct cpuinfo_arc_cache icache, dcache; struct cpuinfo_arc_mmu mmu; struct cpuinfo_arc_bpu bpu; struct bcr_identity core; unsigned int timers; struct bcr_isa isa; struct bcr_timer timers; unsigned int vec_base; unsigned int uncached_base; struct cpuinfo_arc_ccm iccm, dccm; struct bcr_extn extn; struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3, fpu_sp:1, fpu_dp:1, pad2:6, debug:1, ap:1, smart:1, rtt:1, pad3:4, pad4:8; } extn; struct bcr_mpy extn_mpy; struct bcr_extn_xymem extn_xymem; struct bcr_extn_mac_mul extn_mac_mul; struct bcr_fp fp, dpfp; }; extern struct cpuinfo_arc cpuinfo_arc700[]; Loading arch/arc/kernel/perf_event.c +10 −12 Original line number Diff line number Diff line Loading @@ -244,25 +244,23 @@ static int arc_pmu_device_probe(struct platform_device *pdev) pr_err("This core does not have performance counters!\n"); return -ENODEV; } BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS); arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); READ_BCR(ARC_REG_CC_BUILD, cc_bcr); if (!cc_bcr.v) { pr_err("Performance counters exist, but no countable conditions?\n"); return -ENODEV; } arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); if (!arc_pmu) return -ENOMEM; arc_pmu->n_counters = pct_bcr.c; BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS); arc_pmu->counter_size = 32 + (pct_bcr.s << 4); pr_info("ARC PMU found with %d counters of size %d bits\n", arc_pmu->n_counters, arc_pmu->counter_size); READ_BCR(ARC_REG_CC_BUILD, cc_bcr); if (!cc_bcr.v) pr_err("Strange! Performance counters exist, but no countable conditions?\n"); pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c); pr_info("ARC perf\t: %d counters (%d bits), %d countable conditions\n", arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c); cc_name.str[8] = 0; for (i = 0; i < PERF_COUNT_HW_MAX; i++) Loading arch/arc/kernel/setup.c +110 −97 Original line number Diff line number Diff line Loading @@ -43,26 +43,26 @@ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; static void read_arc_build_cfg_regs(void) { struct bcr_perip uncached_space; struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR); READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers); cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); cpu->uncached_base = uncached_space.start << 24; cpu->extn.mul = read_aux_reg(ARC_REG_MUL_BCR); cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR); cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR); cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR); READ_BCR(ARC_REG_MAC_BCR, cpu->extn_mac_mul); READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR); cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */ cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR) > 1 ? 1 : 0; /* 2,3 */ cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0; /* 1,3 */ cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0; cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */ /* Note that we read the CCM BCRs independent of kernel config * This is to catch the cases where user doesn't know that Loading Loading @@ -96,43 +96,76 @@ static void read_arc_build_cfg_regs(void) read_decode_mmu_bcr(); read_decode_cache_bcr(); READ_BCR(ARC_REG_FP_BCR, cpu->fp); READ_BCR(ARC_REG_DPFP_BCR, cpu->dpfp); { struct bcr_fp_arcompact sp, dp; struct bcr_bpu_arcompact bpu; READ_BCR(ARC_REG_FP_BCR, sp); READ_BCR(ARC_REG_DPFP_BCR, dp); cpu->extn.fpu_sp = sp.ver ? 1 : 0; cpu->extn.fpu_dp = dp.ver ? 1 : 0; READ_BCR(ARC_REG_BPU_BCR, bpu); cpu->bpu.ver = bpu.ver; cpu->bpu.full = bpu.fam ? 1 : 0; if (bpu.ent) { cpu->bpu.num_cache = 256 << (bpu.ent - 1); cpu->bpu.num_pred = 256 << (bpu.ent - 1); } } READ_BCR(ARC_REG_AP_BCR, bcr); cpu->extn.ap = bcr.ver ? 1 : 0; READ_BCR(ARC_REG_SMART_BCR, bcr); cpu->extn.smart = bcr.ver ? 1 : 0; cpu->extn.debug = cpu->extn.ap | cpu->extn.smart; } static const struct cpuinfo_data arc_cpu_tbl[] = { { {0x10, "ARCTangent A5"}, 0x1F}, { {0x20, "ARC 600" }, 0x2F}, { {0x30, "ARC 700" }, 0x33}, { {0x34, "ARC 700 R4.10"}, 0x34}, { {0x35, "ARC 700 R4.11"}, 0x35}, { {0x00, NULL } } }; #define IS_AVAIL1(v, str) ((v) ? str : "") #define IS_USED(cfg) (IS_ENABLED(cfg) ? "" : "(not used) ") #define IS_AVAIL2(v, str, cfg) IS_AVAIL1(v, str), IS_AVAIL1(v, IS_USED(cfg)) static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; struct bcr_identity *core = &cpu->core; const struct cpuinfo_data *tbl; int be = 0; #ifdef CONFIG_CPU_BIG_ENDIAN be = 1; #endif char *isa_nm; int i, be, atomic; int n = 0; FIX_PTR(cpu); { isa_nm = "ARCompact"; be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); atomic = cpu->isa.atomic1; if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); } n += scnprintf(buf + n, len - n, "\nARC IDENTITY\t: Family [%#02x]" " Cpu-id [%#02x] Chip-id [%#4x]\n", core->family, core->cpu_id, core->chip_id); "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", core->family, core->cpu_id, core->chip_id); for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) { if ((core->family >= tbl->info.id) && (core->family <= tbl->up_range)) { n += scnprintf(buf + n, len - n, "processor\t: %s %s\n", tbl->info.str, be ? "[Big Endian]" : ""); "processor [%d]\t: %s (%s ISA) %s\n", cpu_id, tbl->info.str, isa_nm, IS_AVAIL1(be, "[Big-Endian]")); break; } } Loading @@ -144,34 +177,35 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) (unsigned int)(arc_get_core_freq() / 1000000), (unsigned int)(arc_get_core_freq() / 10000) % 100); n += scnprintf(buf + n, len - n, "Timers\t\t: %s %s\n", (cpu->timers & 0x200) ? "TIMER1" : "", (cpu->timers & 0x100) ? "TIMER0" : ""); n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", IS_AVAIL1(cpu->timers.t0, "Timer0 "), IS_AVAIL1(cpu->timers.t1, "Timer1 "), IS_AVAIL2(cpu->timers.rtsc, "64-bit RTSC ", CONFIG_ARC_HAS_RTSC)); n += scnprintf(buf + n, len - n, "Vect Tbl Base\t: %#x\n", cpu->vec_base); n += i = scnprintf(buf + n, len - n, "%s%s", IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC)); n += scnprintf(buf + n, len - n, "UNCACHED Base\t: %#x\n", cpu->uncached_base); if (i) n += scnprintf(buf + n, len - n, "\n\t\t: "); return buf; } n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", IS_AVAIL1(cpu->extn_mpy.ver, "mpy "), IS_AVAIL1(cpu->extn.norm, "norm "), IS_AVAIL1(cpu->extn.barrel, "barrel-shift "), IS_AVAIL1(cpu->extn.swap, "swap "), IS_AVAIL1(cpu->extn.minmax, "minmax "), IS_AVAIL1(cpu->extn.crc, "crc "), IS_AVAIL2(1, "swape", CONFIG_ARC_HAS_SWAPE)); static const struct id_to_str mul_type_nm[] = { { 0x0, "N/A"}, { 0x1, "32x32 (spl Result Reg)" }, { 0x2, "32x32 (ANY Result Reg)" } }; if (cpu->bpu.ver) n += scnprintf(buf + n, len - n, "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n", IS_AVAIL1(cpu->bpu.full, "full"), IS_AVAIL1(!cpu->bpu.full, "partial"), cpu->bpu.num_cache, cpu->bpu.num_pred); static const struct id_to_str mac_mul_nm[] = { {0x0, "N/A"}, {0x1, "N/A"}, {0x2, "Dual 16 x 16"}, {0x3, "N/A"}, {0x4, "32x16"}, {0x5, "N/A"}, {0x6, "Dual 16x16 and 32x16"} }; return buf; } static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) { Loading @@ -179,57 +213,27 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; FIX_PTR(cpu); #define IS_AVAIL1(var, str) ((var) ? str : "") #define IS_AVAIL2(var, str) ((var == 0x2) ? str : "") #define IS_USED(cfg) (IS_ENABLED(cfg) ? "(in-use)" : "(not used)") n += scnprintf(buf + n, len - n, "Extn [700-Base]\t: %s %s %s %s %s %s\n", IS_AVAIL2(cpu->extn.norm, "norm,"), IS_AVAIL2(cpu->extn.barrel, "barrel-shift,"), IS_AVAIL1(cpu->extn.swap, "swap,"), IS_AVAIL2(cpu->extn.minmax, "minmax,"), IS_AVAIL1(cpu->extn.crc, "crc,"), IS_AVAIL2(cpu->extn.ext_arith, "ext-arith")); n += scnprintf(buf + n, len - n, "Extn [700-MPY]\t: %s", mul_type_nm[cpu->extn.mul].str); n += scnprintf(buf + n, len - n, " MAC MPY: %s\n", mac_mul_nm[cpu->extn_mac_mul.type].str); if (cpu->core.family == 0x34) { n += scnprintf(buf + n, len - n, "Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n", IS_USED(CONFIG_ARC_HAS_LLSC), IS_USED(CONFIG_ARC_HAS_SWAPE), IS_USED(CONFIG_ARC_HAS_RTSC)); } n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s", !(cpu->dccm.sz || cpu->iccm.sz) ? "N/A" : ""); if (cpu->dccm.sz) n += scnprintf(buf + n, len - n, "DCCM: @ %x, %d KB ", cpu->dccm.base_addr, TO_KB(cpu->dccm.sz)); if (cpu->iccm.sz) n += scnprintf(buf + n, len - n, "ICCM: @ %x, %d KB", "Vector Table\t: %#x\nUncached Base\t: %#x\n", cpu->vec_base, cpu->uncached_base); if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", IS_AVAIL1(cpu->extn.fpu_sp, "SP "), IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); if (cpu->extn.debug) n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n", IS_AVAIL1(cpu->extn.ap, "ActionPoint "), IS_AVAIL1(cpu->extn.smart, "smaRT "), IS_AVAIL1(cpu->extn.rtt, "RTT ")); if (cpu->dccm.sz || cpu->iccm.sz) n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); n += scnprintf(buf + n, len - n, "\nExtn [FPU]\t: %s", !(cpu->fp.ver || cpu->dpfp.ver) ? "N/A" : ""); if (cpu->fp.ver) n += scnprintf(buf + n, len - n, "SP [v%d] %s", cpu->fp.ver, cpu->fp.fast ? "(fast)" : ""); if (cpu->dpfp.ver) n += scnprintf(buf + n, len - n, "DP [v%d] %s", cpu->dpfp.ver, cpu->dpfp.fast ? "(fast)" : ""); n += scnprintf(buf + n, len - n, "\n"); n += scnprintf(buf + n, len - n, "OS ABI [v3]\t: no-legacy-syscalls\n"); Loading @@ -241,6 +245,15 @@ static void arc_chk_core_config(void) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; int fpu_enabled; if (!cpu->timers.t0) panic("Timer0 is not present!\n"); if (!cpu->timers.t1) panic("Timer1 is not present!\n"); if (IS_ENABLED(CONFIG_ARC_HAS_RTSC) && !cpu->timers.rtsc) panic("RTSC is not present\n"); #ifdef CONFIG_ARC_HAS_DCCM /* * DCCM can be arbit placed in hardware. Loading @@ -267,9 +280,9 @@ static void arc_chk_core_config(void) */ fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); if (cpu->dpfp.ver && !fpu_enabled) if (cpu->extn.fpu_dp && !fpu_enabled) pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); else if (!cpu->dpfp.ver && fpu_enabled) else if (!cpu->extn.fpu_dp && fpu_enabled) panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); } Loading Loading @@ -405,7 +418,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n", seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100); Loading arch/arc/mm/tlb.c +3 −5 Original line number Diff line number Diff line Loading @@ -609,14 +609,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) int n = 0; struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", p_mmu->ver, TO_KB(p_mmu->pg_sz)); n += scnprintf(buf + n, len - n, "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", "MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, TO_KB(p_mmu->pg_sz), p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, p_mmu->u_dtlb, p_mmu->u_itlb, IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : ""); IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : ""); return buf; } Loading Loading
arch/arc/include/asm/arcregs.h +53 −24 Original line number Diff line number Diff line Loading @@ -12,14 +12,13 @@ /* Build Configuration Registers */ #define ARC_REG_DCCMBASE_BCR 0x61 /* DCCM Base Addr */ #define ARC_REG_CRC_BCR 0x62 #define ARC_REG_DVFB_BCR 0x64 #define ARC_REG_EXTARITH_BCR 0x65 #define ARC_REG_VECBASE_BCR 0x68 #define ARC_REG_PERIBASE_BCR 0x69 #define ARC_REG_FP_BCR 0x6B /* Single-Precision FPU */ #define ARC_REG_DPFP_BCR 0x6C /* Dbl Precision FPU */ #define ARC_REG_FP_BCR 0x6B /* ARCompact: Single-Precision FPU */ #define ARC_REG_DPFP_BCR 0x6C /* ARCompact: Dbl Precision FPU */ #define ARC_REG_DCCM_BCR 0x74 /* DCCM Present + SZ */ #define ARC_REG_TIMERS_BCR 0x75 #define ARC_REG_AP_BCR 0x76 #define ARC_REG_ICCM_BCR 0x78 #define ARC_REG_XY_MEM_BCR 0x79 #define ARC_REG_MAC_BCR 0x7a Loading @@ -29,6 +28,9 @@ #define ARC_REG_MIXMAX_BCR 0x7e #define ARC_REG_BARREL_BCR 0x7f #define ARC_REG_D_UNCACH_BCR 0x6A #define ARC_REG_BPU_BCR 0xc0 #define ARC_REG_ISA_CFG_BCR 0xc1 #define ARC_REG_SMART_BCR 0xFF /* status32 Bits Positions */ #define STATUS_AE_BIT 5 /* Exception active */ Loading Loading @@ -202,27 +204,19 @@ struct bcr_identity { #endif }; #define EXTN_SWAP_VALID 0x1 #define EXTN_NORM_VALID 0x2 #define EXTN_MINMAX_VALID 0x2 #define EXTN_BARREL_VALID 0x2 struct bcr_extn { struct bcr_isa { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:20, crc:1, ext_arith:2, mul:2, barrel:2, minmax:2, norm:2, swap:1; unsigned int pad1:23, atomic1:1, ver:8; #else unsigned int swap:1, norm:2, minmax:2, barrel:2, mul:2, ext_arith:2, crc:1, pad:20; unsigned int ver:8, atomic1:1, pad1:23; #endif }; /* DSP Options Ref Manual */ struct bcr_extn_mac_mul { struct bcr_mpy { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:16, type:8, ver:8; unsigned int pad:8, x1616:8, dsp:4, cycles:2, type:2, ver:8; #else unsigned int ver:8, type:8, pad:16; unsigned int ver:8, type:2, cycles:2, dsp:4, x1616:8, pad:8; #endif }; Loading @@ -241,6 +235,7 @@ struct bcr_perip { unsigned int pad:8, sz:8, pad2:8, start:8; #endif }; struct bcr_iccm { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int base:16, pad:5, sz:3, ver:8; Loading @@ -267,8 +262,8 @@ struct bcr_dccm { #endif }; /* Both SP and DP FPU BCRs have same format */ struct bcr_fp { /* ARCompact: Both SP and DP FPU BCRs have same format */ struct bcr_fp_arcompact { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int fast:1, ver:8; #else Loading @@ -276,6 +271,30 @@ struct bcr_fp { #endif }; struct bcr_timer { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad2:15, rtsc:1, pad1:6, t1:1, t0:1, ver:8; #else unsigned int ver:8, t0:1, t1:1, pad1:6, rtsc:1, pad2:15; #endif }; struct bcr_bpu_arcompact { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad2:19, fam:1, pad:2, ent:2, ver:8; #else unsigned int ver:8, ent:2, pad:2, fam:1, pad2:19; #endif }; struct bcr_generic { #ifdef CONFIG_CPU_BIG_ENDIAN unsigned int pad:24, ver:8; #else unsigned int ver:8, pad:24; #endif }; /* ******************************************************************* * Generic structures to hold build configuration used at runtime Loading @@ -289,6 +308,10 @@ struct cpuinfo_arc_cache { unsigned int sz_k:8, line_len:8, assoc:4, ver:4, alias:1, vipt:1, pad:6; }; struct cpuinfo_arc_bpu { unsigned int ver, full, num_cache, num_pred; }; struct cpuinfo_arc_ccm { unsigned int base_addr, sz; }; Loading @@ -296,15 +319,21 @@ struct cpuinfo_arc_ccm { struct cpuinfo_arc { struct cpuinfo_arc_cache icache, dcache; struct cpuinfo_arc_mmu mmu; struct cpuinfo_arc_bpu bpu; struct bcr_identity core; unsigned int timers; struct bcr_isa isa; struct bcr_timer timers; unsigned int vec_base; unsigned int uncached_base; struct cpuinfo_arc_ccm iccm, dccm; struct bcr_extn extn; struct { unsigned int swap:1, norm:1, minmax:1, barrel:1, crc:1, pad1:3, fpu_sp:1, fpu_dp:1, pad2:6, debug:1, ap:1, smart:1, rtt:1, pad3:4, pad4:8; } extn; struct bcr_mpy extn_mpy; struct bcr_extn_xymem extn_xymem; struct bcr_extn_mac_mul extn_mac_mul; struct bcr_fp fp, dpfp; }; extern struct cpuinfo_arc cpuinfo_arc700[]; Loading
arch/arc/kernel/perf_event.c +10 −12 Original line number Diff line number Diff line Loading @@ -244,25 +244,23 @@ static int arc_pmu_device_probe(struct platform_device *pdev) pr_err("This core does not have performance counters!\n"); return -ENODEV; } BUG_ON(pct_bcr.c > ARC_PMU_MAX_HWEVENTS); arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); READ_BCR(ARC_REG_CC_BUILD, cc_bcr); if (!cc_bcr.v) { pr_err("Performance counters exist, but no countable conditions?\n"); return -ENODEV; } arc_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_pmu), GFP_KERNEL); if (!arc_pmu) return -ENOMEM; arc_pmu->n_counters = pct_bcr.c; BUG_ON(arc_pmu->n_counters > ARC_PMU_MAX_HWEVENTS); arc_pmu->counter_size = 32 + (pct_bcr.s << 4); pr_info("ARC PMU found with %d counters of size %d bits\n", arc_pmu->n_counters, arc_pmu->counter_size); READ_BCR(ARC_REG_CC_BUILD, cc_bcr); if (!cc_bcr.v) pr_err("Strange! Performance counters exist, but no countable conditions?\n"); pr_info("ARC PMU has %d countable conditions\n", cc_bcr.c); pr_info("ARC perf\t: %d counters (%d bits), %d countable conditions\n", arc_pmu->n_counters, arc_pmu->counter_size, cc_bcr.c); cc_name.str[8] = 0; for (i = 0; i < PERF_COUNT_HW_MAX; i++) Loading
arch/arc/kernel/setup.c +110 −97 Original line number Diff line number Diff line Loading @@ -43,26 +43,26 @@ struct cpuinfo_arc cpuinfo_arc700[NR_CPUS]; static void read_arc_build_cfg_regs(void) { struct bcr_perip uncached_space; struct bcr_generic bcr; struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; FIX_PTR(cpu); READ_BCR(AUX_IDENTITY, cpu->core); READ_BCR(ARC_REG_ISA_CFG_BCR, cpu->isa); cpu->timers = read_aux_reg(ARC_REG_TIMERS_BCR); READ_BCR(ARC_REG_TIMERS_BCR, cpu->timers); cpu->vec_base = read_aux_reg(AUX_INTR_VEC_BASE); READ_BCR(ARC_REG_D_UNCACH_BCR, uncached_space); cpu->uncached_base = uncached_space.start << 24; cpu->extn.mul = read_aux_reg(ARC_REG_MUL_BCR); cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR); cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR); cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR); READ_BCR(ARC_REG_MAC_BCR, cpu->extn_mac_mul); READ_BCR(ARC_REG_MUL_BCR, cpu->extn_mpy); cpu->extn.ext_arith = read_aux_reg(ARC_REG_EXTARITH_BCR); cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR); cpu->extn.norm = read_aux_reg(ARC_REG_NORM_BCR) > 1 ? 1 : 0; /* 2,3 */ cpu->extn.barrel = read_aux_reg(ARC_REG_BARREL_BCR) > 1 ? 1 : 0; /* 2,3 */ cpu->extn.swap = read_aux_reg(ARC_REG_SWAP_BCR) ? 1 : 0; /* 1,3 */ cpu->extn.crc = read_aux_reg(ARC_REG_CRC_BCR) ? 1 : 0; cpu->extn.minmax = read_aux_reg(ARC_REG_MIXMAX_BCR) > 1 ? 1 : 0; /* 2 */ /* Note that we read the CCM BCRs independent of kernel config * This is to catch the cases where user doesn't know that Loading Loading @@ -96,43 +96,76 @@ static void read_arc_build_cfg_regs(void) read_decode_mmu_bcr(); read_decode_cache_bcr(); READ_BCR(ARC_REG_FP_BCR, cpu->fp); READ_BCR(ARC_REG_DPFP_BCR, cpu->dpfp); { struct bcr_fp_arcompact sp, dp; struct bcr_bpu_arcompact bpu; READ_BCR(ARC_REG_FP_BCR, sp); READ_BCR(ARC_REG_DPFP_BCR, dp); cpu->extn.fpu_sp = sp.ver ? 1 : 0; cpu->extn.fpu_dp = dp.ver ? 1 : 0; READ_BCR(ARC_REG_BPU_BCR, bpu); cpu->bpu.ver = bpu.ver; cpu->bpu.full = bpu.fam ? 1 : 0; if (bpu.ent) { cpu->bpu.num_cache = 256 << (bpu.ent - 1); cpu->bpu.num_pred = 256 << (bpu.ent - 1); } } READ_BCR(ARC_REG_AP_BCR, bcr); cpu->extn.ap = bcr.ver ? 1 : 0; READ_BCR(ARC_REG_SMART_BCR, bcr); cpu->extn.smart = bcr.ver ? 1 : 0; cpu->extn.debug = cpu->extn.ap | cpu->extn.smart; } static const struct cpuinfo_data arc_cpu_tbl[] = { { {0x10, "ARCTangent A5"}, 0x1F}, { {0x20, "ARC 600" }, 0x2F}, { {0x30, "ARC 700" }, 0x33}, { {0x34, "ARC 700 R4.10"}, 0x34}, { {0x35, "ARC 700 R4.11"}, 0x35}, { {0x00, NULL } } }; #define IS_AVAIL1(v, str) ((v) ? str : "") #define IS_USED(cfg) (IS_ENABLED(cfg) ? "" : "(not used) ") #define IS_AVAIL2(v, str, cfg) IS_AVAIL1(v, str), IS_AVAIL1(v, IS_USED(cfg)) static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) { int n = 0; struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; struct bcr_identity *core = &cpu->core; const struct cpuinfo_data *tbl; int be = 0; #ifdef CONFIG_CPU_BIG_ENDIAN be = 1; #endif char *isa_nm; int i, be, atomic; int n = 0; FIX_PTR(cpu); { isa_nm = "ARCompact"; be = IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); atomic = cpu->isa.atomic1; if (!cpu->isa.ver) /* ISA BCR absent, use Kconfig info */ atomic = IS_ENABLED(CONFIG_ARC_HAS_LLSC); } n += scnprintf(buf + n, len - n, "\nARC IDENTITY\t: Family [%#02x]" " Cpu-id [%#02x] Chip-id [%#4x]\n", core->family, core->cpu_id, core->chip_id); "\nIDENTITY\t: ARCVER [%#02x] ARCNUM [%#02x] CHIPID [%#4x]\n", core->family, core->cpu_id, core->chip_id); for (tbl = &arc_cpu_tbl[0]; tbl->info.id != 0; tbl++) { if ((core->family >= tbl->info.id) && (core->family <= tbl->up_range)) { n += scnprintf(buf + n, len - n, "processor\t: %s %s\n", tbl->info.str, be ? "[Big Endian]" : ""); "processor [%d]\t: %s (%s ISA) %s\n", cpu_id, tbl->info.str, isa_nm, IS_AVAIL1(be, "[Big-Endian]")); break; } } Loading @@ -144,34 +177,35 @@ static char *arc_cpu_mumbojumbo(int cpu_id, char *buf, int len) (unsigned int)(arc_get_core_freq() / 1000000), (unsigned int)(arc_get_core_freq() / 10000) % 100); n += scnprintf(buf + n, len - n, "Timers\t\t: %s %s\n", (cpu->timers & 0x200) ? "TIMER1" : "", (cpu->timers & 0x100) ? "TIMER0" : ""); n += scnprintf(buf + n, len - n, "Timers\t\t: %s%s%s%s\nISA Extn\t: ", IS_AVAIL1(cpu->timers.t0, "Timer0 "), IS_AVAIL1(cpu->timers.t1, "Timer1 "), IS_AVAIL2(cpu->timers.rtsc, "64-bit RTSC ", CONFIG_ARC_HAS_RTSC)); n += scnprintf(buf + n, len - n, "Vect Tbl Base\t: %#x\n", cpu->vec_base); n += i = scnprintf(buf + n, len - n, "%s%s", IS_AVAIL2(atomic, "atomic ", CONFIG_ARC_HAS_LLSC)); n += scnprintf(buf + n, len - n, "UNCACHED Base\t: %#x\n", cpu->uncached_base); if (i) n += scnprintf(buf + n, len - n, "\n\t\t: "); return buf; } n += scnprintf(buf + n, len - n, "%s%s%s%s%s%s%s%s\n", IS_AVAIL1(cpu->extn_mpy.ver, "mpy "), IS_AVAIL1(cpu->extn.norm, "norm "), IS_AVAIL1(cpu->extn.barrel, "barrel-shift "), IS_AVAIL1(cpu->extn.swap, "swap "), IS_AVAIL1(cpu->extn.minmax, "minmax "), IS_AVAIL1(cpu->extn.crc, "crc "), IS_AVAIL2(1, "swape", CONFIG_ARC_HAS_SWAPE)); static const struct id_to_str mul_type_nm[] = { { 0x0, "N/A"}, { 0x1, "32x32 (spl Result Reg)" }, { 0x2, "32x32 (ANY Result Reg)" } }; if (cpu->bpu.ver) n += scnprintf(buf + n, len - n, "BPU\t\t: %s%s match, cache:%d, Predict Table:%d\n", IS_AVAIL1(cpu->bpu.full, "full"), IS_AVAIL1(!cpu->bpu.full, "partial"), cpu->bpu.num_cache, cpu->bpu.num_pred); static const struct id_to_str mac_mul_nm[] = { {0x0, "N/A"}, {0x1, "N/A"}, {0x2, "Dual 16 x 16"}, {0x3, "N/A"}, {0x4, "32x16"}, {0x5, "N/A"}, {0x6, "Dual 16x16 and 32x16"} }; return buf; } static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) { Loading @@ -179,57 +213,27 @@ static char *arc_extn_mumbojumbo(int cpu_id, char *buf, int len) struct cpuinfo_arc *cpu = &cpuinfo_arc700[cpu_id]; FIX_PTR(cpu); #define IS_AVAIL1(var, str) ((var) ? str : "") #define IS_AVAIL2(var, str) ((var == 0x2) ? str : "") #define IS_USED(cfg) (IS_ENABLED(cfg) ? "(in-use)" : "(not used)") n += scnprintf(buf + n, len - n, "Extn [700-Base]\t: %s %s %s %s %s %s\n", IS_AVAIL2(cpu->extn.norm, "norm,"), IS_AVAIL2(cpu->extn.barrel, "barrel-shift,"), IS_AVAIL1(cpu->extn.swap, "swap,"), IS_AVAIL2(cpu->extn.minmax, "minmax,"), IS_AVAIL1(cpu->extn.crc, "crc,"), IS_AVAIL2(cpu->extn.ext_arith, "ext-arith")); n += scnprintf(buf + n, len - n, "Extn [700-MPY]\t: %s", mul_type_nm[cpu->extn.mul].str); n += scnprintf(buf + n, len - n, " MAC MPY: %s\n", mac_mul_nm[cpu->extn_mac_mul.type].str); if (cpu->core.family == 0x34) { n += scnprintf(buf + n, len - n, "Extn [700-4.10]\t: LLOCK/SCOND %s, SWAPE %s, RTSC %s\n", IS_USED(CONFIG_ARC_HAS_LLSC), IS_USED(CONFIG_ARC_HAS_SWAPE), IS_USED(CONFIG_ARC_HAS_RTSC)); } n += scnprintf(buf + n, len - n, "Extn [CCM]\t: %s", !(cpu->dccm.sz || cpu->iccm.sz) ? "N/A" : ""); if (cpu->dccm.sz) n += scnprintf(buf + n, len - n, "DCCM: @ %x, %d KB ", cpu->dccm.base_addr, TO_KB(cpu->dccm.sz)); if (cpu->iccm.sz) n += scnprintf(buf + n, len - n, "ICCM: @ %x, %d KB", "Vector Table\t: %#x\nUncached Base\t: %#x\n", cpu->vec_base, cpu->uncached_base); if (cpu->extn.fpu_sp || cpu->extn.fpu_dp) n += scnprintf(buf + n, len - n, "FPU\t\t: %s%s\n", IS_AVAIL1(cpu->extn.fpu_sp, "SP "), IS_AVAIL1(cpu->extn.fpu_dp, "DP ")); if (cpu->extn.debug) n += scnprintf(buf + n, len - n, "DEBUG\t\t: %s%s%s\n", IS_AVAIL1(cpu->extn.ap, "ActionPoint "), IS_AVAIL1(cpu->extn.smart, "smaRT "), IS_AVAIL1(cpu->extn.rtt, "RTT ")); if (cpu->dccm.sz || cpu->iccm.sz) n += scnprintf(buf + n, len - n, "Extn [CCM]\t: DCCM @ %x, %d KB / ICCM: @ %x, %d KB\n", cpu->dccm.base_addr, TO_KB(cpu->dccm.sz), cpu->iccm.base_addr, TO_KB(cpu->iccm.sz)); n += scnprintf(buf + n, len - n, "\nExtn [FPU]\t: %s", !(cpu->fp.ver || cpu->dpfp.ver) ? "N/A" : ""); if (cpu->fp.ver) n += scnprintf(buf + n, len - n, "SP [v%d] %s", cpu->fp.ver, cpu->fp.fast ? "(fast)" : ""); if (cpu->dpfp.ver) n += scnprintf(buf + n, len - n, "DP [v%d] %s", cpu->dpfp.ver, cpu->dpfp.fast ? "(fast)" : ""); n += scnprintf(buf + n, len - n, "\n"); n += scnprintf(buf + n, len - n, "OS ABI [v3]\t: no-legacy-syscalls\n"); Loading @@ -241,6 +245,15 @@ static void arc_chk_core_config(void) struct cpuinfo_arc *cpu = &cpuinfo_arc700[smp_processor_id()]; int fpu_enabled; if (!cpu->timers.t0) panic("Timer0 is not present!\n"); if (!cpu->timers.t1) panic("Timer1 is not present!\n"); if (IS_ENABLED(CONFIG_ARC_HAS_RTSC) && !cpu->timers.rtsc) panic("RTSC is not present\n"); #ifdef CONFIG_ARC_HAS_DCCM /* * DCCM can be arbit placed in hardware. Loading @@ -267,9 +280,9 @@ static void arc_chk_core_config(void) */ fpu_enabled = IS_ENABLED(CONFIG_ARC_FPU_SAVE_RESTORE); if (cpu->dpfp.ver && !fpu_enabled) if (cpu->extn.fpu_dp && !fpu_enabled) pr_warn("CONFIG_ARC_FPU_SAVE_RESTORE needed for working apps\n"); else if (!cpu->dpfp.ver && fpu_enabled) else if (!cpu->extn.fpu_dp && fpu_enabled) panic("FPU non-existent, disable CONFIG_ARC_FPU_SAVE_RESTORE\n"); } Loading Loading @@ -405,7 +418,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) seq_printf(m, arc_cpu_mumbojumbo(cpu_id, str, PAGE_SIZE)); seq_printf(m, "Bogo MIPS : \t%lu.%02lu\n", seq_printf(m, "Bogo MIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000 / HZ), (loops_per_jiffy / (5000 / HZ)) % 100); Loading
arch/arc/mm/tlb.c +3 −5 Original line number Diff line number Diff line Loading @@ -609,14 +609,12 @@ char *arc_mmu_mumbojumbo(int cpu_id, char *buf, int len) int n = 0; struct cpuinfo_arc_mmu *p_mmu = &cpuinfo_arc700[cpu_id].mmu; n += scnprintf(buf + n, len - n, "ARC700 MMU [v%x]\t: %dk PAGE, ", p_mmu->ver, TO_KB(p_mmu->pg_sz)); n += scnprintf(buf + n, len - n, "J-TLB %d (%dx%d), uDTLB %d, uITLB %d, %s\n", "MMU [v%x]\t: %dk PAGE, JTLB %d (%dx%d), uDTLB %d, uITLB %d %s\n", p_mmu->ver, TO_KB(p_mmu->pg_sz), p_mmu->num_tlb, p_mmu->sets, p_mmu->ways, p_mmu->u_dtlb, p_mmu->u_itlb, IS_ENABLED(CONFIG_ARC_MMU_SASID) ? "SASID" : ""); IS_ENABLED(CONFIG_ARC_MMU_SASID) ? ",SASID" : ""); return buf; } Loading