diff options
| -rw-r--r-- | Documentation/features/io/sg-chain/arch-support.txt | 2 | ||||
| -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 |
9 files changed, 46 insertions, 35 deletions
diff --git a/Documentation/features/io/sg-chain/arch-support.txt b/Documentation/features/io/sg-chain/arch-support.txt index b9b675539b9d..6ca98f9911bb 100644 --- a/Documentation/features/io/sg-chain/arch-support.txt +++ b/Documentation/features/io/sg-chain/arch-support.txt | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | | arch |status| | 7 | | arch |status| |
| 8 | ----------------------- | 8 | ----------------------- |
| 9 | | alpha: | TODO | | 9 | | alpha: | TODO | |
| 10 | | arc: | TODO | | 10 | | arc: | ok | |
| 11 | | arm: | ok | | 11 | | arm: | ok | |
| 12 | | arm64: | ok | | 12 | | arm64: | ok | |
| 13 | | avr32: | TODO | | 13 | | avr32: | TODO | |
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 @@ | |||
| 9 | config ARC | 9 | config ARC |
| 10 | def_bool y | 10 | def_bool y |
| 11 | select ARC_TIMERS | 11 | select ARC_TIMERS |
| 12 | select ARCH_HAS_SG_CHAIN | ||
| 12 | select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC | 13 | select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC |
| 13 | select BUILDTIME_EXTABLE_SORT | 14 | select BUILDTIME_EXTABLE_SORT |
| 14 | select CLONE_BACKWARDS | 15 | 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 { | |||
| 244 | }; | 244 | }; |
| 245 | 245 | ||
| 246 | struct cpuinfo_arc_cache { | 246 | struct cpuinfo_arc_cache { |
| 247 | unsigned int sz_k:14, line_len:8, assoc:4, ver:4, alias:1, vipt:1; | 247 | unsigned int sz_k:14, line_len:8, assoc:4, alias:1, vipt:1, pad:4; |
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | struct cpuinfo_arc_bpu { | 250 | 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, | |||
| 85 | */ | 85 | */ |
| 86 | #define PG_dc_clean PG_arch_1 | 86 | #define PG_dc_clean PG_arch_1 |
| 87 | 87 | ||
| 88 | #define CACHE_COLORS_NUM 4 | ||
| 89 | #define CACHE_COLORS_MSK (CACHE_COLORS_NUM - 1) | ||
| 90 | #define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & CACHE_COLORS_MSK) | ||
| 91 | |||
| 88 | /* | 92 | /* |
| 89 | * Simple wrapper over config option | 93 | * Simple wrapper over config option |
| 90 | * Bootup code ensures that hardware matches kernel configuration | 94 | * Bootup code ensures that hardware matches kernel configuration |
| @@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void) | |||
| 94 | return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); | 98 | return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); |
| 95 | } | 99 | } |
| 96 | 100 | ||
| 97 | #define CACHE_COLOR(addr) (((unsigned long)(addr) >> (PAGE_SHIFT)) & 1) | ||
| 98 | |||
| 99 | /* | 101 | /* |
| 100 | * checks if two addresses (after page aligning) index into same cache set | 102 | * checks if two addresses (after page aligning) index into same cache set |
| 101 | */ | 103 | */ |
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 @@ | |||
| 38 | #define AUX_IRQ_ACT_BIT_U 31 | 38 | #define AUX_IRQ_ACT_BIT_U 31 |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * User space should be interruptable even by lowest prio interrupt | 41 | * Hardware supports 16 priorities (0 highest, 15 lowest) |
| 42 | * Safe even if actual interrupt priorities is fewer or even one | 42 | * Linux by default runs at 1, priority 0 reserved for NMI style interrupts |
| 43 | */ | 43 | */ |
| 44 | #define ARCV2_IRQ_DEF_PRIO 15 | 44 | #define ARCV2_IRQ_DEF_PRIO 1 |
| 45 | 45 | ||
| 46 | /* seed value for status register */ | 46 | /* seed value for status register */ |
| 47 | #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ | 47 | #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) | |||
| 67 | 67 | ||
| 68 | INTERRUPT_PROLOGUE irq | 68 | INTERRUPT_PROLOGUE irq |
| 69 | 69 | ||
| 70 | clri ; To make status32.IE agree with CPU internal state | 70 | # irq control APIs local_irq_save/restore/disable/enable fiddle with |
| 71 | 71 | # global interrupt enable bits in STATUS32 (.IE for 1 prio, .E[] for 2 prio) | |
| 72 | #ifdef CONFIG_TRACE_IRQFLAGS | 72 | # However a taken interrupt doesn't clear these bits. Thus irqs_disabled() |
| 73 | TRACE_ASM_IRQ_DISABLE | 73 | # query in hard ISR path would return false (since .IE is set) which would |
| 74 | #endif | 74 | # trips genirq interrupt handling asserts. |
| 75 | 75 | # | |
| 76 | # So do a "soft" disable of interrutps here. | ||
| 77 | # | ||
| 78 | # Note this disable is only for consistent book-keeping as further interrupts | ||
| 79 | # will be disabled anyways even w/o this. Hardware tracks active interrupts | ||
| 80 | # seperately in AUX_IRQ_ACTIVE.active and will not take new interrupts | ||
| 81 | # unless this one returns (or higher prio becomes pending in 2-prio scheme) | ||
| 82 | |||
| 83 | IRQ_DISABLE | ||
| 84 | |||
| 85 | ; icause is banked: one per priority level | ||
| 86 | ; so a higher prio interrupt taken here won't clobber prev prio icause | ||
| 76 | lr r0, [ICAUSE] | 87 | lr r0, [ICAUSE] |
| 77 | mov blink, ret_from_exception | 88 | mov blink, ret_from_exception |
| 78 | 89 | ||
| @@ -171,6 +182,7 @@ END(EV_TLBProtV) | |||
| 171 | ; All 2 entry points to here already disable interrupts | 182 | ; All 2 entry points to here already disable interrupts |
| 172 | 183 | ||
| 173 | .Lrestore_regs: | 184 | .Lrestore_regs: |
| 185 | restore_regs: | ||
| 174 | 186 | ||
| 175 | # Interrpts are actually disabled from this point on, but will get | 187 | # Interrpts are actually disabled from this point on, but will get |
| 176 | # reenabled after we return from interrupt/exception. | 188 | # 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) | |||
| 259 | 259 | ||
| 260 | EXCEPTION_PROLOGUE | 260 | EXCEPTION_PROLOGUE |
| 261 | 261 | ||
| 262 | lr r2, [ecr] | 262 | mov r2, r9 ; ECR set into r9 already |
| 263 | lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) | 263 | lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above) |
| 264 | 264 | ||
| 265 | ; Exception auto-disables further Intr/exceptions. | 265 | ; 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 @@ | |||
| 14 | #include <linux/irqchip.h> | 14 | #include <linux/irqchip.h> |
| 15 | #include <asm/irq.h> | 15 | #include <asm/irq.h> |
| 16 | 16 | ||
| 17 | static int irq_prio; | ||
| 18 | |||
| 19 | /* | 17 | /* |
| 20 | * Early Hardware specific Interrupt setup | 18 | * Early Hardware specific Interrupt setup |
| 21 | * -Called very early (start_kernel -> setup_arch -> setup_processor) | 19 | * -Called very early (start_kernel -> setup_arch -> setup_processor) |
| @@ -24,7 +22,7 @@ static int irq_prio; | |||
| 24 | */ | 22 | */ |
| 25 | void arc_init_IRQ(void) | 23 | void arc_init_IRQ(void) |
| 26 | { | 24 | { |
| 27 | unsigned int tmp; | 25 | unsigned int tmp, irq_prio; |
| 28 | 26 | ||
| 29 | struct irq_build { | 27 | struct irq_build { |
| 30 | #ifdef CONFIG_CPU_BIG_ENDIAN | 28 | #ifdef CONFIG_CPU_BIG_ENDIAN |
| @@ -67,12 +65,12 @@ void arc_init_IRQ(void) | |||
| 67 | 65 | ||
| 68 | irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */ | 66 | irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */ |
| 69 | pr_info("archs-intc\t: %d priority levels (default %d)%s\n", | 67 | pr_info("archs-intc\t: %d priority levels (default %d)%s\n", |
| 70 | irq_prio + 1, irq_prio, | 68 | irq_prio + 1, ARCV2_IRQ_DEF_PRIO, |
| 71 | irq_bcr.firq ? " FIRQ (not used)":""); | 69 | irq_bcr.firq ? " FIRQ (not used)":""); |
| 72 | 70 | ||
| 73 | /* setup status32, don't enable intr yet as kernel doesn't want */ | 71 | /* setup status32, don't enable intr yet as kernel doesn't want */ |
| 74 | tmp = read_aux_reg(0xa); | 72 | tmp = read_aux_reg(0xa); |
| 75 | tmp |= STATUS_AD_MASK | (irq_prio << 1); | 73 | tmp |= STATUS_AD_MASK | (ARCV2_IRQ_DEF_PRIO << 1); |
| 76 | tmp &= ~STATUS_IE_MASK; | 74 | tmp &= ~STATUS_IE_MASK; |
| 77 | asm volatile("kflag %0 \n"::"r"(tmp)); | 75 | asm volatile("kflag %0 \n"::"r"(tmp)); |
| 78 | } | 76 | } |
| @@ -93,7 +91,7 @@ void arcv2_irq_enable(struct irq_data *data) | |||
| 93 | { | 91 | { |
| 94 | /* set default priority */ | 92 | /* set default priority */ |
| 95 | write_aux_reg(AUX_IRQ_SELECT, data->irq); | 93 | write_aux_reg(AUX_IRQ_SELECT, data->irq); |
| 96 | write_aux_reg(AUX_IRQ_PRIORITY, irq_prio); | 94 | write_aux_reg(AUX_IRQ_PRIORITY, ARCV2_IRQ_DEF_PRIO); |
| 97 | 95 | ||
| 98 | /* | 96 | /* |
| 99 | * hw auto enables (linux unmask) all by default | 97 | * 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) | |||
| 40 | struct cpuinfo_arc_cache *p; | 40 | struct cpuinfo_arc_cache *p; |
| 41 | 41 | ||
| 42 | #define PR_CACHE(p, cfg, str) \ | 42 | #define PR_CACHE(p, cfg, str) \ |
| 43 | if (!(p)->ver) \ | 43 | if (!(p)->line_len) \ |
| 44 | n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \ | 44 | n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \ |
| 45 | else \ | 45 | else \ |
| 46 | n += scnprintf(buf + n, len - n, \ | 46 | n += scnprintf(buf + n, len - n, \ |
| @@ -54,7 +54,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) | |||
| 54 | PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache"); | 54 | PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache"); |
| 55 | 55 | ||
| 56 | p = &cpuinfo_arc700[c].slc; | 56 | p = &cpuinfo_arc700[c].slc; |
| 57 | if (p->ver) | 57 | if (p->line_len) |
| 58 | n += scnprintf(buf + n, len - n, | 58 | n += scnprintf(buf + n, len - n, |
| 59 | "SLC\t\t: %uK, %uB Line%s\n", | 59 | "SLC\t\t: %uK, %uB Line%s\n", |
| 60 | p->sz_k, p->line_len, IS_USED_RUN(slc_enable)); | 60 | p->sz_k, p->line_len, IS_USED_RUN(slc_enable)); |
| @@ -104,7 +104,6 @@ static void read_decode_cache_bcr_arcv2(int cpu) | |||
| 104 | READ_BCR(ARC_REG_SLC_BCR, sbcr); | 104 | READ_BCR(ARC_REG_SLC_BCR, sbcr); |
| 105 | if (sbcr.ver) { | 105 | if (sbcr.ver) { |
| 106 | READ_BCR(ARC_REG_SLC_CFG, slc_cfg); | 106 | READ_BCR(ARC_REG_SLC_CFG, slc_cfg); |
| 107 | p_slc->ver = sbcr.ver; | ||
| 108 | p_slc->sz_k = 128 << slc_cfg.sz; | 107 | p_slc->sz_k = 128 << slc_cfg.sz; |
| 109 | l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64; | 108 | l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64; |
| 110 | } | 109 | } |
| @@ -152,7 +151,6 @@ void read_decode_cache_bcr(void) | |||
| 152 | 151 | ||
| 153 | p_ic->line_len = 8 << ibcr.line_len; | 152 | p_ic->line_len = 8 << ibcr.line_len; |
| 154 | p_ic->sz_k = 1 << (ibcr.sz - 1); | 153 | p_ic->sz_k = 1 << (ibcr.sz - 1); |
| 155 | p_ic->ver = ibcr.ver; | ||
| 156 | p_ic->vipt = 1; | 154 | p_ic->vipt = 1; |
| 157 | p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1; | 155 | p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1; |
| 158 | 156 | ||
| @@ -176,7 +174,6 @@ dc_chk: | |||
| 176 | 174 | ||
| 177 | p_dc->line_len = 16 << dbcr.line_len; | 175 | p_dc->line_len = 16 << dbcr.line_len; |
| 178 | p_dc->sz_k = 1 << (dbcr.sz - 1); | 176 | p_dc->sz_k = 1 << (dbcr.sz - 1); |
| 179 | p_dc->ver = dbcr.ver; | ||
| 180 | 177 | ||
| 181 | slc_chk: | 178 | slc_chk: |
| 182 | if (is_isa_arcv2()) | 179 | if (is_isa_arcv2()) |
| @@ -945,17 +942,13 @@ void arc_cache_init(void) | |||
| 945 | if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { | 942 | if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { |
| 946 | struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; | 943 | struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].icache; |
| 947 | 944 | ||
| 948 | if (!ic->ver) | 945 | if (!ic->line_len) |
| 949 | panic("cache support enabled but non-existent cache\n"); | 946 | panic("cache support enabled but non-existent cache\n"); |
| 950 | 947 | ||
| 951 | if (ic->line_len != L1_CACHE_BYTES) | 948 | if (ic->line_len != L1_CACHE_BYTES) |
| 952 | panic("ICache line [%d] != kernel Config [%d]", | 949 | panic("ICache line [%d] != kernel Config [%d]", |
| 953 | ic->line_len, L1_CACHE_BYTES); | 950 | ic->line_len, L1_CACHE_BYTES); |
| 954 | 951 | ||
| 955 | if (ic->ver != CONFIG_ARC_MMU_VER) | ||
| 956 | panic("Cache ver [%d] doesn't match MMU ver [%d]\n", | ||
| 957 | ic->ver, CONFIG_ARC_MMU_VER); | ||
| 958 | |||
| 959 | /* | 952 | /* |
| 960 | * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG | 953 | * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG |
| 961 | * pair to provide vaddr/paddr respectively, just as in MMU v3 | 954 | * pair to provide vaddr/paddr respectively, just as in MMU v3 |
| @@ -969,7 +962,7 @@ void arc_cache_init(void) | |||
| 969 | if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) { | 962 | if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) { |
| 970 | struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; | 963 | struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].dcache; |
| 971 | 964 | ||
| 972 | if (!dc->ver) | 965 | if (!dc->line_len) |
| 973 | panic("cache support enabled but non-existent cache\n"); | 966 | panic("cache support enabled but non-existent cache\n"); |
| 974 | 967 | ||
| 975 | if (dc->line_len != L1_CACHE_BYTES) | 968 | if (dc->line_len != L1_CACHE_BYTES) |
| @@ -979,11 +972,16 @@ void arc_cache_init(void) | |||
| 979 | /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ | 972 | /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ |
| 980 | if (is_isa_arcompact()) { | 973 | if (is_isa_arcompact()) { |
| 981 | int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); | 974 | int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); |
| 982 | 975 | int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE); | |
| 983 | if (dc->alias && !handled) | 976 | |
| 984 | panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); | 977 | if (dc->alias) { |
| 985 | else if (!dc->alias && handled) | 978 | if (!handled) |
| 979 | panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); | ||
| 980 | if (CACHE_COLORS_NUM != num_colors) | ||
| 981 | panic("CACHE_COLORS_NUM not optimized for config\n"); | ||
| 982 | } else if (!dc->alias && handled) { | ||
| 986 | panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); | 983 | panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); |
| 984 | } | ||
| 987 | } | 985 | } |
| 988 | } | 986 | } |
| 989 | 987 | ||
