Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc
Browse files Browse the repository at this point in the history
Pull Sparc updates from David S. Miller:

 1) Remove the idiotic situation wherein Leon was a special case in all
    of the TLB/cache handling code.

    The worst side effect of this bogosity is that you couldn't build a
    kernel with Leon support enabled (to get better build coverage), and
    test boot it on a non-LEON cpu.

    Leon is, in all core respects, programatically identical to the
    32-bit SRMMU.  Except that they put the TLB registers in a different
    alternate address space location.

    Through code patching (for fast paths) and run time checks, this
    issue is now a thing of the past.

    From Sam Ravnborg.

 2) There was a mis-merge of arch/sparc/Kconfig for one of the
    clockevents changes that went in, causing 32-bit sparc to start
    failing to build.

    I merged in your tree to get those clockevents changes (and added a
    note to the merge commit) then added Stephen Rothwell's fix for the
    merge error.

 3) Software quad floating point emulation was not working properly on
    more recent Niagara chips, because the way the situation is reported
    by the cpu has changed.

    Nobody noticed because gcc emits calls to software emulation
    routines in glibc.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc: (25 commits)
  sparc: fix sparc64 build due to leon.h inclusion
  sparc32: remove unused variable in head_32.S
  sparc32,leon: fix leon bootup
  sparc32: Export leon_dma_ops to modules.
  sparc32: support leon + sun in dma_make_coherent()
  sparc32,leon: always support leon in ioport
  sparc32,leon: always include leon_pmc in build
  sparc32: refactor cpu_idle()
  sparc32: srmmu_probe now knows about leon too
  sparc32: drop LEON hack for ASI_M_MMUREGS
  sparc32: introduce run-time patching of srmmu access functions
  sparc32: introduce support for run-time patching for all shared assembler code
  sparc32,leon: fix section mismatch warning
  sparc32,leon: always include leon_smp + leon_mm in build
  sparc32,leon: always include leon_kernel in build
  sparc32,leon: clean up leon.h
  sparc32: handle leon in cpu.c
  sparc32: handle leon in irq_32.c
  sparc32: add support for run-time patching of leon/sun single instructions
  sparc32: introduce sparc32_start_kernel called from head_32.S
  ...
  • Loading branch information
Linus Torvalds committed May 31, 2012
2 parents 13199a0 + e49e6ff commit f737c77
Show file tree
Hide file tree
Showing 34 changed files with 444 additions and 382 deletions.
1 change: 0 additions & 1 deletion arch/sparc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ config SPARC32
def_bool !64BIT
select GENERIC_ATOMIC64
select CLZ_TAB
select ARCH_USES_GETTIMEOFFSET

config SPARC64
def_bool 64BIT
Expand Down
4 changes: 0 additions & 4 deletions arch/sparc/include/asm/asi.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,7 @@
#define ASI_M_UNA01 0x01 /* Same here... */
#define ASI_M_MXCC 0x02 /* Access to TI VIKING MXCC registers */
#define ASI_M_FLUSH_PROBE 0x03 /* Reference MMU Flush/Probe; rw, ss */
#ifndef CONFIG_SPARC_LEON
#define ASI_M_MMUREGS 0x04 /* MMU Registers; rw, ss */
#else
#define ASI_M_MMUREGS 0x19
#endif /* CONFIG_SPARC_LEON */
#define ASI_M_TLBDIAG 0x05 /* MMU TLB only Diagnostics */
#define ASI_M_DIAGS 0x06 /* Reference MMU Diagnostics */
#define ASI_M_IODIAG 0x07 /* MMU I/O TLB only Diagnostics */
Expand Down
22 changes: 22 additions & 0 deletions arch/sparc/include/asm/asmmacro.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,26 @@
/* All traps low-level code here must end with this macro. */
#define RESTORE_ALL b ret_trap_entry; clr %l6;

/* Support for run-time patching of single instructions.
* This is used to handle the differences in the ASI for
* MMUREGS for LEON and SUN.
*
* Sample:
* LEON_PI(lda [%g0] ASI_LEON_MMUREGS, %o0
* SUN_PI_(lda [%g0] ASI_M_MMUREGS, %o0
* PI == Patch Instruction
*
* For LEON we will use the first variant,
* and for all other we will use the SUN variant.
* The order is important.
*/
#define LEON_PI(...) \
662: __VA_ARGS__

#define SUN_PI_(...) \
.section .leon_1insn_patch, "ax"; \
.word 662b; \
__VA_ARGS__; \
.previous

#endif /* !(_SPARC_ASMMACRO_H) */
9 changes: 7 additions & 2 deletions arch/sparc/include/asm/dma-mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,18 @@ extern int dma_supported(struct device *dev, u64 mask);
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)

extern struct dma_map_ops *dma_ops, pci32_dma_ops;
extern struct dma_map_ops *dma_ops;
extern struct dma_map_ops *leon_dma_ops;
extern struct dma_map_ops pci32_dma_ops;

extern struct bus_type pci_bus_type;

static inline struct dma_map_ops *get_dma_ops(struct device *dev)
{
#if defined(CONFIG_SPARC32) && defined(CONFIG_PCI)
if (dev->bus == &pci_bus_type)
if (sparc_cpu_model == sparc_leon)
return leon_dma_ops;
else if (dev->bus == &pci_bus_type)
return &pci32_dma_ops;
#endif
return dma_ops;
Expand Down
82 changes: 3 additions & 79 deletions arch/sparc/include/asm/leon.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#ifndef LEON_H_INCLUDE
#define LEON_H_INCLUDE

#ifdef CONFIG_SPARC_LEON

/* mmu register access, ASI_LEON_MMUREGS */
#define LEON_CNR_CTRL 0x000
#define LEON_CNR_CTXP 0x100
Expand Down Expand Up @@ -62,15 +60,6 @@

#ifndef __ASSEMBLY__

/* do a virtual address read without cache */
static inline unsigned long leon_readnobuffer_reg(unsigned long paddr)
{
unsigned long retval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r"(retval) : "r"(paddr), "i"(ASI_LEON_NOCACHE));
return retval;
}

/* do a physical address bypass write, i.e. for 0x80000000 */
static inline void leon_store_reg(unsigned long paddr, unsigned long value)
{
Expand All @@ -87,47 +76,16 @@ static inline unsigned long leon_load_reg(unsigned long paddr)
return retval;
}

static inline void leon_srmmu_disabletlb(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
"i"(ASI_LEON_MMUREGS));
retval |= LEON_CNR_CTRL_TLBDIS;
__asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
"i"(ASI_LEON_MMUREGS) : "memory");
}

static inline void leon_srmmu_enabletlb(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %2, %0\n\t" : "=r"(retval) : "r"(0),
"i"(ASI_LEON_MMUREGS));
retval = retval & ~LEON_CNR_CTRL_TLBDIS;
__asm__ __volatile__("sta %0, [%%g0] %2\n\t" : : "r"(retval), "r"(0),
"i"(ASI_LEON_MMUREGS) : "memory");
}

/* macro access for leon_load_reg() and leon_store_reg() */
#define LEON3_BYPASS_LOAD_PA(x) (leon_load_reg((unsigned long)(x)))
#define LEON3_BYPASS_STORE_PA(x, v) (leon_store_reg((unsigned long)(x), (unsigned long)(v)))
#define LEON3_BYPASS_ANDIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) & v)
#define LEON3_BYPASS_ORIN_PA(x, v) LEON3_BYPASS_STORE_PA(x, LEON3_BYPASS_LOAD_PA(x) | v)
#define LEON_BYPASS_LOAD_PA(x) leon_load_reg((unsigned long)(x))
#define LEON_BYPASS_STORE_PA(x, v) leon_store_reg((unsigned long)(x), (unsigned long)(v))
#define LEON_REGLOAD_PA(x) leon_load_reg((unsigned long)(x)+LEON_PREGS)
#define LEON_REGSTORE_PA(x, v) leon_store_reg((unsigned long)(x)+LEON_PREGS, (unsigned long)(v))
#define LEON_REGSTORE_OR_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) | (unsigned long)(v))
#define LEON_REGSTORE_AND_PA(x, v) LEON_REGSTORE_PA(x, LEON_REGLOAD_PA(x) & (unsigned long)(v))

/* macro access for leon_readnobuffer_reg() */
#define LEON_BYPASSCACHE_LOAD_VA(x) leon_readnobuffer_reg((unsigned long)(x))

extern void leon_init(void);
extern void leon_switch_mm(void);
extern void leon_init_IRQ(void);

extern unsigned long last_valid_pfn;

static inline unsigned long sparc_leon3_get_dcachecfg(void)
{
unsigned int retval;
Expand Down Expand Up @@ -230,9 +188,6 @@ static inline int sparc_leon3_cpuid(void)
#error cannot determine LEON_PAGE_SIZE_LEON
#endif

#define PAGE_MIN_SHIFT (12)
#define PAGE_MIN_SIZE (1UL << PAGE_MIN_SHIFT)

#define LEON3_XCCR_SETS_MASK 0x07000000UL
#define LEON3_XCCR_SSIZE_MASK 0x00f00000UL

Expand All @@ -242,7 +197,7 @@ static inline int sparc_leon3_cpuid(void)
#ifndef __ASSEMBLY__
struct vm_area_struct;

extern unsigned long srmmu_swprobe(unsigned long vaddr, unsigned long *paddr);
extern unsigned long leon_swprobe(unsigned long vaddr, unsigned long *paddr);
extern void leon_flush_icache_all(void);
extern void leon_flush_dcache_all(void);
extern void leon_flush_cache_all(void);
Expand All @@ -258,15 +213,7 @@ struct leon3_cacheregs {
unsigned long dccr; /* 0x0c - Data Cache Configuration Register */
};

/* struct that hold LEON2 cache configuration register
* & configuration register
*/
struct leon2_cacheregs {
unsigned long ccr, cfg;
};

#ifdef __KERNEL__

#include <linux/irq.h>
#include <linux/interrupt.h>

struct device_node;
Expand All @@ -292,43 +239,20 @@ extern void leon_smp_done(void);
extern void leon_boot_cpus(void);
extern int leon_boot_one_cpu(int i, struct task_struct *);
void leon_init_smp(void);
extern void cpu_idle(void);
extern void init_IRQ(void);
extern void cpu_panic(void);
extern int __leon_processor_id(void);
void leon_enable_irq_cpu(unsigned int irq_nr, unsigned int cpu);
extern irqreturn_t leon_percpu_timer_interrupt(int irq, void *unused);

extern unsigned int real_irq_entry[];
extern unsigned int smpleon_ipi[];
extern unsigned int patchme_maybe_smp_msg[];
extern unsigned int t_nmi[], linux_trap_ipi15_leon[];
extern unsigned int linux_trap_ipi15_sun4m[];
extern unsigned int linux_trap_ipi15_leon[];
extern int leon_ipi_irq;

#endif /* CONFIG_SMP */

#endif /* __KERNEL__ */

#endif /* __ASSEMBLY__ */

/* macros used in leon_mm.c */
#define PFN(x) ((x) >> PAGE_SHIFT)
#define _pfn_valid(pfn) ((pfn < last_valid_pfn) && (pfn >= PFN(phys_base)))
#define _SRMMU_PTE_PMASK_LEON 0xffffffff

#else /* defined(CONFIG_SPARC_LEON) */

/* nop definitions for !LEON case */
#define leon_init() do {} while (0)
#define leon_switch_mm() do {} while (0)
#define leon_init_IRQ() do {} while (0)
#define init_leon() do {} while (0)
#define leon_smp_done() do {} while (0)
#define leon_boot_cpus() do {} while (0)
#define leon_boot_one_cpu(i, t) 1
#define leon_init_smp() do {} while (0)

#endif /* !defined(CONFIG_SPARC_LEON) */

#endif
4 changes: 0 additions & 4 deletions arch/sparc/include/asm/leon_amba.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ struct amba_prom_registers {
#define LEON3_GPTIMER_CONFIG_NRTIMERS(c) ((c)->config & 0x7)
#define LEON3_GPTIMER_CTRL_ISPENDING(r) (((r)&LEON3_GPTIMER_CTRL_PENDING) ? 1 : 0)

#ifdef CONFIG_SPARC_LEON

#ifndef __ASSEMBLY__

struct leon3_irqctrl_regs_map {
Expand Down Expand Up @@ -264,6 +262,4 @@ extern unsigned int sparc_leon_eirq;

#define amba_device(x) (((x) >> 12) & 0xfff)

#endif /* !defined(CONFIG_SPARC_LEON) */

#endif
86 changes: 8 additions & 78 deletions arch/sparc/include/asm/pgtsrmmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@
restore %g0, %g0, %g0;

#ifndef __ASSEMBLY__
extern unsigned long last_valid_pfn;

/* This makes sense. Honest it does - Anton */
/* XXX Yes but it's ugly as sin. FIXME. -KMW */
Expand All @@ -148,67 +149,13 @@ extern void *srmmu_nocache_pool;
#define __nocache_fix(VADDR) __va(__nocache_pa(VADDR))

/* Accessing the MMU control register. */
static inline unsigned int srmmu_get_mmureg(void)
{
unsigned int retval;
__asm__ __volatile__("lda [%%g0] %1, %0\n\t" :
"=r" (retval) :
"i" (ASI_M_MMUREGS));
return retval;
}

static inline void srmmu_set_mmureg(unsigned long regval)
{
__asm__ __volatile__("sta %0, [%%g0] %1\n\t" : :
"r" (regval), "i" (ASI_M_MMUREGS) : "memory");

}

static inline void srmmu_set_ctable_ptr(unsigned long paddr)
{
paddr = ((paddr >> 4) & SRMMU_CTX_PMASK);
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (paddr), "r" (SRMMU_CTXTBL_PTR),
"i" (ASI_M_MMUREGS) :
"memory");
}

static inline void srmmu_set_context(int context)
{
__asm__ __volatile__("sta %0, [%1] %2\n\t" : :
"r" (context), "r" (SRMMU_CTX_REG),
"i" (ASI_M_MMUREGS) : "memory");
}

static inline int srmmu_get_context(void)
{
register int retval;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (retval) :
"r" (SRMMU_CTX_REG),
"i" (ASI_M_MMUREGS));
return retval;
}

static inline unsigned int srmmu_get_fstatus(void)
{
unsigned int retval;

__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (retval) :
"r" (SRMMU_FAULT_STATUS), "i" (ASI_M_MMUREGS));
return retval;
}

static inline unsigned int srmmu_get_faddr(void)
{
unsigned int retval;

__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (retval) :
"r" (SRMMU_FAULT_ADDR), "i" (ASI_M_MMUREGS));
return retval;
}
unsigned int srmmu_get_mmureg(void);
void srmmu_set_mmureg(unsigned long regval);
void srmmu_set_ctable_ptr(unsigned long paddr);
void srmmu_set_context(int context);
int srmmu_get_context(void);
unsigned int srmmu_get_fstatus(void);
unsigned int srmmu_get_faddr(void);

/* This is guaranteed on all SRMMU's. */
static inline void srmmu_flush_whole_tlb(void)
Expand All @@ -219,23 +166,6 @@ static inline void srmmu_flush_whole_tlb(void)

}

/* These flush types are not available on all chips... */
#ifndef CONFIG_SPARC_LEON
static inline unsigned long srmmu_hwprobe(unsigned long vaddr)
{
unsigned long retval;

vaddr &= PAGE_MASK;
__asm__ __volatile__("lda [%1] %2, %0\n\t" :
"=r" (retval) :
"r" (vaddr | 0x400), "i" (ASI_M_FLUSH_PROBE));

return retval;
}
#else
#define srmmu_hwprobe(addr) srmmu_swprobe(addr, 0)
#endif

static inline int
srmmu_get_pte (unsigned long addr)
{
Expand Down
8 changes: 8 additions & 0 deletions arch/sparc/include/asm/psr.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
#define PSR_VERS 0x0f000000 /* cpu-version field */
#define PSR_IMPL 0xf0000000 /* cpu-implementation field */

#define PSR_VERS_SHIFT 24
#define PSR_IMPL_SHIFT 28
#define PSR_VERS_SHIFTED_MASK 0xf
#define PSR_IMPL_SHIFTED_MASK 0xf

#define PSR_IMPL_TI 0x4
#define PSR_IMPL_LEON 0xf

#ifdef __KERNEL__

#ifndef __ASSEMBLY__
Expand Down
3 changes: 3 additions & 0 deletions arch/sparc/include/asm/sections.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@
/* sparc entry point */
extern char _start[];

extern char __leon_1insn_patch[];
extern char __leon_1insn_patch_end[];

#endif
4 changes: 2 additions & 2 deletions arch/sparc/kernel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,8 @@ obj-y += of_device_common.o
obj-y += of_device_$(BITS).o
obj-$(CONFIG_SPARC64) += prom_irqtrans.o

obj-$(CONFIG_SPARC_LEON)+= leon_kernel.o
obj-$(CONFIG_SPARC_LEON)+= leon_pmc.o
obj-$(CONFIG_SPARC32) += leon_kernel.o
obj-$(CONFIG_SPARC32) += leon_pmc.o

obj-$(CONFIG_SPARC64) += reboot.o
obj-$(CONFIG_SPARC64) += sysfs.o
Expand Down
Loading

0 comments on commit f737c77

Please sign in to comment.