diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-23 10:22:47 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-23 10:22:47 -0800 |
commit | 42e0372c0e7ea3617a4ab28c7f83ce66cb0f868d (patch) | |
tree | f6b94f1baaa27270d9c7c76256cb67aa4df0597e /arch | |
parent | 50f6584e4c626b8fa39edb66f33fec27bab3996c (diff) | |
parent | 08fe007968b2b45e831daf74899f79a54d73f773 (diff) |
Merge tag 'arc-4.10-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc
Pull more ARC updates from Vineet Gupta:
- Fix for aliasing VIPT dcache in old ARC700 cores
- micro-optimization in ARC700 ProtV handler
- Enable SG_CHAIN [Vladimir]
- ARC HS38 core intc default to prio 1
* tag 'arc-4.10-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupta/arc:
ARC: mm: arc700: Don't assume 2 colours for aliasing VIPT dcache
ARC: mm: No need to save cache version in @cpuinfo
ARC: enable SG chaining
ARCv2: intc: default all interrupts to priority 1
ARCv2: entry: document intr disable in hard isr
ARC: ARCompact entry: elide re-reading ECR in ProtV handler
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/Kconfig | 1 | ||||
-rw-r--r-- | arch/arc/include/asm/arcregs.h | 2 | ||||
-rw-r--r-- | arch/arc/include/asm/cacheflush.h | 6 | ||||
-rw-r--r-- | arch/arc/include/asm/irqflags-arcv2.h | 6 | ||||
-rw-r--r-- | arch/arc/kernel/entry-arcv2.S | 24 | ||||
-rw-r--r-- | arch/arc/kernel/entry-compact.S | 2 | ||||
-rw-r--r-- | arch/arc/kernel/intc-arcv2.c | 10 | ||||
-rw-r--r-- | arch/arc/mm/cache.c | 28 |
8 files changed, 45 insertions, 34 deletions
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index ab12723d39a0..c75d29077e4a 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -9,6 +9,7 @@ config ARC def_bool y select ARC_TIMERS + select ARCH_HAS_SG_CHAIN select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC select BUILDTIME_EXTABLE_SORT select CLONE_BACKWARDS diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h index da41a54ea2d7..f659942744de 100644 --- a/arch/arc/include/asm/arcregs.h +++ b/arch/arc/include/asm/arcregs.h @@ -244,7 +244,7 @@ struct cpuinfo_arc_mmu { }; struct cpuinfo_arc_cache { - unsigned int sz_k:14, line_len:8, assoc:4, ver:4, alias:1, vipt:1; + unsigned int sz_k:14, line_len:8, assoc:4, alias:1, vipt:1, pad:4; }; struct cpuinfo_arc_bpu { diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h index a093adbdb017..fc662f49c55a 100644 --- a/arch/arc/include/asm/cacheflush.h +++ b/arch/arc/include/asm/cacheflush.h @@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma, */ #define PG_dc_clean PG_arch_1 +#define CACHE_COLORS_NUM 4 +#define CACHE_COLORS_MSK (CACHE_COLORS_NUM - 1) +#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & CACHE_COLORS_MSK) + /* * Simple wrapper over config option * Bootup code ensures that hardware matches kernel configuration @@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void) return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); } -#define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1) - /* * checks if two addresses (after page aligning) index into same cache set */ diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h index e880dfa3fcd3..a64c447b0337 100644 --- a/arch/arc/include/asm/irqflags-arcv2.h +++ b/arch/arc/include/asm/irqflags-arcv2.h @@ -38,10 +38,10 @@ #define AUX_IRQ_ACT_BIT_U 31 /* - * User space should be interruptable even by lowest prio interrupt - * Safe even if actual interrupt priorities is fewer or even one + * Hardware supports 16 priorities (0 highest, 15 lowest) + * Linux by default runs at 1, priority 0 reserved for NMI style interrupts */ -#define ARCV2_IRQ_DEF_PRIO 15 +#define ARCV2_IRQ_DEF_PRIO 1 /* seed value for status register */ #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ diff --git a/arch/arc/kernel/entry-arcv2.S b/arch/arc/kernel/entry-arcv2.S index 7a1c124ff021..0b6388a5f0b8 100644 --- a/arch/arc/kernel/entry-arcv2.S +++ b/arch/arc/kernel/entry-arcv2.S @@ -67,12 +67,23 @@ ENTRY(handle_interrupt) INTERRUPT_PROLOGUE irq - clri ; To make status32.IE agree with CPU internal state - -#ifdef CONFIG_TRACE_IRQFLAGS - TRACE_ASM_IRQ_DISABLE -#endif - + # irq control APIs local_irq_save/restore/disable/enable fiddle with + # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio) + # However a taken interrupt doesn't clear these bits. Thus irqs_disabled() + # query in hard ISR path would return false (since .IE is set) which would + # trips genirq interrupt handling asserts. + # + # So do a "soft" disable of interrutps here. + # + # Note this disable is only for consistent book-keeping as further interrupts + # will be disabled anyways even w/o this. Hardware tracks active interrupts + # seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts + # unless this one returns (or higher prio becomes pending in 2-prio scheme) + + IRQ_DISABLE + + ; icause is banked: one per priority level + ; so a higher prio interrupt taken here won't clobber prev prio icause lr r0, [ICAUSE] mov blink, ret_from_exception @@ -171,6 +182,7 @@ END(EV_TLBProtV) ; All 2 entry points to here already disable interrupts .Lrestore_regs: +restore_regs: # Interrpts are actually disabled from this point on, but will get # reenabled after we return from interrupt/exception. diff --git a/arch/arc/kernel/entry-compact.S b/arch/arc/kernel/entry-compact.S index 98812c1248df..9211707634dc 100644 --- a/arch/arc/kernel/entry-compact.S +++ b/arch/arc/kernel/entry-compact.S @@ -259,7 +259,7 @@ ENTRY(EV_TLBProtV) EXCEPTION_PROLOGUE - lr r2, [ecr] + mov r2, r9 ; ECR set into r9 already lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) ; Exception auto-disables further Intr/exceptions. diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c index 62b59409a5d9..994dca7014db 100644 --- a/arch/arc/kernel/intc-arcv2.c +++ b/arch/arc/kernel/intc-arcv2.c @@ -14,8 +14,6 @@ #include <linux/irqchip.h> #include <asm/irq.h> -static int irq_prio; - /* * Early Hardware specific Interrupt setup * -Called very early (start_kernel -> setup_arch -> setup_processor) @@ -24,7 +22,7 @@ static int irq_prio; */ void arc_init_IRQ(void) { - unsigned int tmp; + unsigned int tmp, irq_prio; struct irq_build { #ifdef CONFIG_CPU_BIG_ENDIAN @@ -67,12 +65,12 @@ void arc_init_IRQ(void) irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */ pr_info("archs-intc\t: %d priority levels (default %d)%s\n", - irq_prio + 1, irq_prio, + irq_prio + 1, ARCV2_IRQ_DEF_PRIO, irq_bcr.firq ? " FIRQ (not used)":""); /* setup status32, don't enable intr yet as kernel doesn't want */ tmp = read_aux_reg(0xa); - tmp |= STATUS_AD_MASK | (irq_prio << 1); + tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); tmp &= ~STATUS_IE_MASK; asm volatile("kflag %0 \n"::"r"(tmp)); } @@ -93,7 +91,7 @@ void arcv2_irq_enable(struct irq_data *data) { /* set default priority */ write_aux_reg(AUX_IRQ_SELECT, data->irq); - write_aux_reg(AUX_IRQ_PRIORITY, irq_prio); + write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO); /* * hw auto enables (linux unmask) all by default diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c index 50d71695cd4e..ec86ac0e3321 100644 --- a/arch/arc/mm/cache.c +++ b/arch/arc/mm/cache.c @@ -40,7 +40,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) struct cpuinfo_arc_cache *p; #define PR_CACHE(p, cfg, str) \ - if (!(p)->ver) \ + if (!(p)->line_len) \ n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \ else \ n += scnprintf(buf + n, len - n, \ @@ -54,7 +54,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache"); p = &cpuinfo_arc700[c].slc; - if (p->ver) + if (p->line_len) n += scnprintf(buf + n, len - n, "SLC\t\t: %uK, %uB Line%s\n", p->sz_k, p->line_len, IS_USED_RUN(slc_enable)); @@ -104,7 +104,6 @@ static void read_decode_cache_bcr_arcv2(int cpu) READ_BCR(ARC_REG_SLC_BCR, sbcr); if (sbcr.ver) { READ_BCR(ARC_REG_SLC_CFG, slc_cfg); - p_slc->ver = sbcr.ver; p_slc->sz_k = 128 << slc_cfg.sz; l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64; } @@ -152,7 +151,6 @@ void read_decode_cache_bcr(void) p_ic->line_len = 8 << ibcr.line_len; p_ic->sz_k = 1 << (ibcr.sz - 1); - p_ic->ver = ibcr.ver; p_ic->vipt = 1; p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1; @@ -176,7 +174,6 @@ dc_chk: p_dc->line_len = 16 << dbcr.line_len; p_dc->sz_k = 1 << (dbcr.sz - 1); - p_dc->ver = dbcr.ver; slc_chk: if (is_isa_arcv2()) @@ -945,17 +942,13 @@ void arc_cache_init(void) if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; - if (!ic->ver) + if (!ic->line_len) panic("cache support enabled but non-existent cache\n"); if (ic->line_len != L1_CACHE_BYTES) panic("ICache line [%d] != kernel Config [%d]", ic->line_len, L1_CACHE_BYTES); - if (ic->ver != CONFIG_ARC_MMU_VER) - panic("Cache ver [%d] doesn't match MMU ver [%d]\n", - ic->ver, CONFIG_ARC_MMU_VER); - /* * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG * pair to provide vaddr/paddr respectively, just as in MMU v3 @@ -969,7 +962,7 @@ void arc_cache_init(void) if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) { struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; - if (!dc->ver) + if (!dc->line_len) panic("cache support enabled but non-existent cache\n"); if (dc->line_len != L1_CACHE_BYTES) @@ -979,11 +972,16 @@ void arc_cache_init(void) /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ if (is_isa_arcompact()) { int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); - - if (dc->alias && !handled) - panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); - else if (!dc->alias && handled) + int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE); + + if (dc->alias) { + if (!handled) + panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); + if (CACHE_COLORS_NUM != num_colors) + panic("CACHE_COLORS_NUM not optimized for config\n"); + } else if (!dc->alias && handled) { panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); + } } } |