Skip to content

Commit

Permalink
Merge tag 'arc-4.10-rc1-part2' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…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
  • Loading branch information
torvalds committed Dec 23, 2016
2 parents 50f6584 + 08fe007 commit 42e0372
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 35 deletions.
2 changes: 1 addition & 1 deletion Documentation/features/io/sg-chain/arch-support.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
| arch |status|
-----------------------
| alpha: | TODO |
| arc: | TODO |
| arc: | ok |
| arm: | ok |
| arm64: | ok |
| avr32: | TODO |
Expand Down
1 change: 1 addition & 0 deletions arch/arc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion arch/arc/include/asm/arcregs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions arch/arc/include/asm/cacheflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
*/
Expand Down
6 changes: 3 additions & 3 deletions arch/arc/include/asm/irqflags-arcv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 | \
Expand Down
24 changes: 18 additions & 6 deletions arch/arc/kernel/entry-arcv2.S
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion arch/arc/kernel/entry-compact.S
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
10 changes: 4 additions & 6 deletions arch/arc/kernel/intc-arcv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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));
}
Expand All @@ -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
Expand Down
28 changes: 13 additions & 15 deletions arch/arc/mm/cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand All @@ -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));
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand All @@ -176,7 +174,6 @@ void read_decode_cache_bcr(void)

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())
Expand Down Expand Up @@ -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
Expand All @@ -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)
Expand All @@ -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");
}
}
}

Expand Down

0 comments on commit 42e0372

Please sign in to comment.