Commit 42e0372c authored by Linus Torvalds's avatar Linus Torvalds

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
parents 50f6584e 08fe0079
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
| arch |status| | arch |status|
----------------------- -----------------------
| alpha: | TODO | | alpha: | TODO |
| arc: | TODO | | arc: | ok |
| arm: | ok | | arm: | ok |
| arm64: | ok | | arm64: | ok |
| avr32: | TODO | | avr32: | TODO |
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
config ARC config ARC
def_bool y def_bool y
select ARC_TIMERS select ARC_TIMERS
select ARCH_HAS_SG_CHAIN
select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC select ARCH_SUPPORTS_ATOMIC_RMW if ARC_HAS_LLSC
select BUILDTIME_EXTABLE_SORT select BUILDTIME_EXTABLE_SORT
select CLONE_BACKWARDS select CLONE_BACKWARDS
......
...@@ -244,7 +244,7 @@ struct cpuinfo_arc_mmu { ...@@ -244,7 +244,7 @@ struct cpuinfo_arc_mmu {
}; };
struct cpuinfo_arc_cache { 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 { struct cpuinfo_arc_bpu {
......
...@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma, ...@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma,
*/ */
#define PG_dc_clean PG_arch_1 #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 * Simple wrapper over config option
* Bootup code ensures that hardware matches kernel configuration * Bootup code ensures that hardware matches kernel configuration
...@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void) ...@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void)
return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); 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 * checks if two addresses (after page aligning) index into same cache set
*/ */
......
...@@ -38,10 +38,10 @@ ...@@ -38,10 +38,10 @@
#define AUX_IRQ_ACT_BIT_U 31 #define AUX_IRQ_ACT_BIT_U 31
/* /*
* User space should be interruptable even by lowest prio interrupt * Hardware supports 16 priorities (0 highest, 15 lowest)
* Safe even if actual interrupt priorities is fewer or even one * 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 */ /* seed value for status register */
#define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \ #define ISA_INIT_STATUS_BITS (STATUS_IE_MASK | STATUS_AD_MASK | \
......
...@@ -67,12 +67,23 @@ ENTRY(handle_interrupt) ...@@ -67,12 +67,23 @@ ENTRY(handle_interrupt)
INTERRUPT_PROLOGUE irq INTERRUPT_PROLOGUE irq
clri ; To make status32.IE agree with CPU internal state # 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)
#ifdef CONFIG_TRACE_IRQFLAGS # However a taken interrupt doesn't clear these bits. Thus irqs_disabled()
TRACE_ASM_IRQ_DISABLE # query in hard ISR path would return false (since .IE is set) which would
#endif # 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] lr r0, [ICAUSE]
mov blink, ret_from_exception mov blink, ret_from_exception
...@@ -171,6 +182,7 @@ END(EV_TLBProtV) ...@@ -171,6 +182,7 @@ END(EV_TLBProtV)
; All 2 entry points to here already disable interrupts ; All 2 entry points to here already disable interrupts
.Lrestore_regs: .Lrestore_regs:
restore_regs:
# Interrpts are actually disabled from this point on, but will get # Interrpts are actually disabled from this point on, but will get
# reenabled after we return from interrupt/exception. # reenabled after we return from interrupt/exception.
......
...@@ -259,7 +259,7 @@ ENTRY(EV_TLBProtV) ...@@ -259,7 +259,7 @@ ENTRY(EV_TLBProtV)
EXCEPTION_PROLOGUE 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) lr r0, [efa] ; Faulting Data address (not part of pt_regs saved above)
; Exception auto-disables further Intr/exceptions. ; Exception auto-disables further Intr/exceptions.
......
...@@ -14,8 +14,6 @@ ...@@ -14,8 +14,6 @@
#include <linux/irqchip.h> #include <linux/irqchip.h>
#include <asm/irq.h> #include <asm/irq.h>
static int irq_prio;
/* /*
* Early Hardware specific Interrupt setup * Early Hardware specific Interrupt setup
* -Called very early (start_kernel -> setup_arch -> setup_processor) * -Called very early (start_kernel -> setup_arch -> setup_processor)
...@@ -24,7 +22,7 @@ static int irq_prio; ...@@ -24,7 +22,7 @@ static int irq_prio;
*/ */
void arc_init_IRQ(void) void arc_init_IRQ(void)
{ {
unsigned int tmp; unsigned int tmp, irq_prio;
struct irq_build { struct irq_build {
#ifdef CONFIG_CPU_BIG_ENDIAN #ifdef CONFIG_CPU_BIG_ENDIAN
...@@ -67,12 +65,12 @@ void arc_init_IRQ(void) ...@@ -67,12 +65,12 @@ void arc_init_IRQ(void)
irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */ irq_prio = irq_bcr.prio; /* Encoded as N-1 for N levels */
pr_info("archs-intc\t: %d priority levels (default %d)%s\n", 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)":""); irq_bcr.firq ? " FIRQ (not used)":"");
/* setup status32, don't enable intr yet as kernel doesn't want */ /* setup status32, don't enable intr yet as kernel doesn't want */
tmp = read_aux_reg(0xa); 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; tmp &= ~STATUS_IE_MASK;
asm volatile("kflag %0 \n"::"r"(tmp)); asm volatile("kflag %0 \n"::"r"(tmp));
} }
...@@ -93,7 +91,7 @@ void arcv2_irq_enable(struct irq_data *data) ...@@ -93,7 +91,7 @@ void arcv2_irq_enable(struct irq_data *data)
{ {
/* set default priority */ /* set default priority */
write_aux_reg(AUX_IRQ_SELECT, data->irq); 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 * hw auto enables (linux unmask) all by default
......
...@@ -40,7 +40,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) ...@@ -40,7 +40,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len)
struct cpuinfo_arc_cache *p; struct cpuinfo_arc_cache *p;
#define PR_CACHE(p, cfg, str) \ #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"); \ n += scnprintf(buf + n, len - n, str"\t\t: N/A\n"); \
else \ else \
n += scnprintf(buf + n, len - n, \ n += scnprintf(buf + n, len - n, \
...@@ -54,7 +54,7 @@ char *arc_cache_mumbojumbo(int c, char *buf, int len) ...@@ -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"); PR_CACHE(&cpuinfo_arc700[c].dcache, CONFIG_ARC_HAS_DCACHE, "D-Cache");
p = &cpuinfo_arc700[c].slc; p = &cpuinfo_arc700[c].slc;
if (p->ver) if (p->line_len)
n += scnprintf(buf + n, len - n, n += scnprintf(buf + n, len - n,
"SLC\t\t: %uK, %uB Line%s\n", "SLC\t\t: %uK, %uB Line%s\n",
p->sz_k, p->line_len, IS_USED_RUN(slc_enable)); 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,7 +104,6 @@ static void read_decode_cache_bcr_arcv2(int cpu)
READ_BCR(ARC_REG_SLC_BCR, sbcr); READ_BCR(ARC_REG_SLC_BCR, sbcr);
if (sbcr.ver) { if (sbcr.ver) {
READ_BCR(ARC_REG_SLC_CFG, slc_cfg); READ_BCR(ARC_REG_SLC_CFG, slc_cfg);
p_slc->ver = sbcr.ver;
p_slc->sz_k = 128 << slc_cfg.sz; p_slc->sz_k = 128 << slc_cfg.sz;
l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64; l2_line_sz = p_slc->line_len = (slc_cfg.lsz == 0) ? 128 : 64;
} }
...@@ -152,7 +151,6 @@ void read_decode_cache_bcr(void) ...@@ -152,7 +151,6 @@ void read_decode_cache_bcr(void)
p_ic->line_len = 8 << ibcr.line_len; p_ic->line_len = 8 << ibcr.line_len;
p_ic->sz_k = 1 << (ibcr.sz - 1); p_ic->sz_k = 1 << (ibcr.sz - 1);
p_ic->ver = ibcr.ver;
p_ic->vipt = 1; p_ic->vipt = 1;
p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1; p_ic->alias = p_ic->sz_k/p_ic->assoc/TO_KB(PAGE_SIZE) > 1;
...@@ -176,7 +174,6 @@ void read_decode_cache_bcr(void) ...@@ -176,7 +174,6 @@ void read_decode_cache_bcr(void)
p_dc->line_len = 16 << dbcr.line_len; p_dc->line_len = 16 << dbcr.line_len;
p_dc->sz_k = 1 << (dbcr.sz - 1); p_dc->sz_k = 1 << (dbcr.sz - 1);
p_dc->ver = dbcr.ver;
slc_chk: slc_chk:
if (is_isa_arcv2()) if (is_isa_arcv2())
...@@ -945,17 +942,13 @@ void arc_cache_init(void) ...@@ -945,17 +942,13 @@ void arc_cache_init(void)
if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) { if (IS_ENABLED(CONFIG_ARC_HAS_ICACHE)) {
struct cpuinfo_arc_cache *ic = &cpuinfo_arc700[cpu].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"); panic("cache support enabled but non-existent cache\n");
if (ic->line_len != L1_CACHE_BYTES) if (ic->line_len != L1_CACHE_BYTES)
panic("ICache line [%d] != kernel Config [%d]", panic("ICache line [%d] != kernel Config [%d]",
ic->line_len, L1_CACHE_BYTES); 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 * In MMU v4 (HS38x) the aliasing icache config uses IVIL/PTAG
* pair to provide vaddr/paddr respectively, just as in MMU v3 * pair to provide vaddr/paddr respectively, just as in MMU v3
...@@ -969,7 +962,7 @@ void arc_cache_init(void) ...@@ -969,7 +962,7 @@ void arc_cache_init(void)
if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) { if (IS_ENABLED(CONFIG_ARC_HAS_DCACHE)) {
struct cpuinfo_arc_cache *dc = &cpuinfo_arc700[cpu].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"); panic("cache support enabled but non-existent cache\n");
if (dc->line_len != L1_CACHE_BYTES) if (dc->line_len != L1_CACHE_BYTES)
...@@ -979,11 +972,16 @@ void arc_cache_init(void) ...@@ -979,11 +972,16 @@ void arc_cache_init(void)
/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */ /* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
if (is_isa_arcompact()) { if (is_isa_arcompact()) {
int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING); int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE);
if (dc->alias && !handled)
panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n"); if (dc->alias) {
else if (!dc->alias && handled) 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"); panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
}
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment