]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge tag 'arc-4.10-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/vgupt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Dec 2016 18:22:47 +0000 (10:22 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 23 Dec 2016 18:22:47 +0000 (10:22 -0800)
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

Documentation/features/io/sg-chain/arch-support.txt
arch/arc/Kconfig
arch/arc/include/asm/arcregs.h
arch/arc/include/asm/cacheflush.h
arch/arc/include/asm/irqflags-arcv2.h
arch/arc/kernel/entry-arcv2.S
arch/arc/kernel/entry-compact.S
arch/arc/kernel/intc-arcv2.c
arch/arc/mm/cache.c

index b9b675539b9df20ed3a754a01a4f5819d12bf7bb..6ca98f9911bbb31693ff342039d5c84772e37d91 100644 (file)
@@ -7,7 +7,7 @@
     |         arch |status|
     -----------------------
     |       alpha: | TODO |
-    |         arc: | TODO |
+    |         arc: |  ok  |
     |         arm: |  ok  |
     |       arm64: |  ok  |
     |       avr32: | TODO |
index ab12723d39a01d8751807728a43c7b08cdc6a814..c75d29077e4a654276219883629444deec89c955 100644 (file)
@@ -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
index da41a54ea2d747011b6c20dcc0b1738e2a2e8062..f659942744de0c474962b118292100eeed7397ce 100644 (file)
@@ -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 {
index a093adbdb017580f6da74abb551ea02e14e04da5..fc662f49c55ac91916af7cbd830b1c978f827ffe 100644 (file)
@@ -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
  */
index e880dfa3fcd370c0f7ae8f9010a79df9ab8c3399..a64c447b0337804568c69cf2e15998deabdd9b40 100644 (file)
 #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 | \
index 7a1c124ff021d53377d24ff5d1bb9cccbb2831de..0b6388a5f0b828323c03b53f0903a35bdc25b0cb 100644 (file)
@@ -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.
index 98812c1248dfaf85b28ed023287ae78f27286073..9211707634dcf57e1aa0ac13fa4a6bbc79b99eeb 100644 (file)
@@ -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.
index 62b59409a5d97eb8b95276a3f17b1e430b98899b..994dca7014db645b32cfb22753cb25bae4c46566 100644 (file)
@@ -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
index 50d71695cd4ecbeefd64f28e9f44265195b01d15..ec86ac0e33213b889cd6100e10e95fda8f3c31e4 100644 (file)
@@ -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");
+                       }
                }
        }