Commit 464480f7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze

* 'for-linus' of git://git.monstr.eu/linux-2.6-microblaze: (46 commits)
  microblaze: Remove rt_sigsuspend wrapper
  microblaze: nommu: Don't clobber R11 on syscalls
  microblaze: Remove show_tmem function
  microblaze: Support for WB cache
  microblaze: Add PVR for Microblaze v7.30.a
  microblaze: Remove ancient and fake microblaze version from cpu_ver table
  microblaze: Remove panic_timeout init value
  microblaze: Do not count system calls in default
  microblaze: Enable DTC compilation
  microblaze: Core oprofile configs and hooks
  microblaze: Fix level interrupt ACKing
  microblaze: Enable futimesat syscall
  microblaze: Checking DTS against PVR for write-back cache
  microblaze: Remove duplicity from pgalloc.h
  microblaze: Futex support
  microblaze: Adding dev_arch_data functions
  microblaze: Fix the heartbeat gpio to be more robust
  microblaze: Simple __copy_tofrom_user for noMMU
  microblaze: Export memory_start for modules
  microblaze: Use lowest-common-denominator default CPU settings
  ...
parents 37222e1c 571202f5
......@@ -6,8 +6,15 @@ mainmenu "Linux/Microblaze Kernel Configuration"
config MICROBLAZE
def_bool y
select HAVE_LMB
select HAVE_FUNCTION_TRACER
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD
select USB_ARCH_HAS_EHCI
select ARCH_WANT_OPTIONAL_GPIOLIB
select HAVE_OPROFILE
select TRACING_SUPPORT
config SWAP
def_bool n
......@@ -57,12 +64,24 @@ config GENERIC_GPIO
config GENERIC_CSUM
def_bool y
config STACKTRACE_SUPPORT
def_bool y
config LOCKDEP_SUPPORT
def_bool y
config HAVE_LATENCYTOP_SUPPORT
def_bool y
config PCI
def_bool n
config NO_DMA
def_bool y
config DTC
def_bool y
source "init/Kconfig"
source "kernel/Kconfig.freezer"
......
......@@ -3,6 +3,9 @@
menu "Kernel hacking"
config TRACE_IRQFLAGS_SUPPORT
def_bool y
source "lib/Kconfig.debug"
config EARLY_PRINTK
......
......@@ -51,6 +51,8 @@ core-y += arch/microblaze/kernel/
core-y += arch/microblaze/mm/
core-y += arch/microblaze/platform/
drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/
boot := arch/microblaze/boot
# Are we making a simpleImage.<boardname> target? If so, crack out the boardname
......
......@@ -2,11 +2,13 @@
# arch/microblaze/boot/Makefile
#
MKIMAGE := $(srctree)/scripts/mkuboot.sh
obj-y += linked_dtb.o
targets := linux.bin linux.bin.gz simpleImage.%
OBJCOPYFLAGS_linux.bin := -O binary
OBJCOPYFLAGS := -O binary
# Where the DTS files live
dtstree := $(srctree)/$(src)/dts
......@@ -24,6 +26,7 @@ $(obj)/linux.bin: vmlinux FORCE
[ -n $(CONFIG_INITRAMFS_SOURCE) ] && [ ! -e $(CONFIG_INITRAMFS_SOURCE) ] && \
touch $(CONFIG_INITRAMFS_SOURCE) || echo "No CPIO image"
$(call if_changed,objcopy)
$(call if_changed,uimage)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
$(obj)/linux.bin.gz: $(obj)/linux.bin FORCE
......@@ -36,8 +39,16 @@ quiet_cmd_cp = CP $< $@$2
quiet_cmd_strip = STRIP $@
cmd_strip = $(STRIP) -K _start -K _end -K __log_buf -K _fdt_start vmlinux -o $@
quiet_cmd_uimage = UIMAGE $@.ub
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A microblaze -O linux -T kernel \
-C none -n 'Linux-$(KERNELRELEASE)' \
-a $(CONFIG_KERNEL_BASE_ADDR) -e $(CONFIG_KERNEL_BASE_ADDR) \
-d $@ $@.ub
$(obj)/simpleImage.%: vmlinux FORCE
$(call if_changed,cp,.unstrip)
$(call if_changed,objcopy)
$(call if_changed,uimage)
$(call if_changed,strip)
@echo 'Kernel: $@ is ready' ' (#'`cat .version`')'
......@@ -53,4 +64,4 @@ $(obj)/%.dtb: $(dtstree)/%.dts FORCE
clean-kernel += linux.bin linux.bin.gz simpleImage.*
clean-files += *.dtb
clean-files += *.dtb simpleImage.*.unstrip
......@@ -21,20 +21,4 @@
#define SMP_CACHE_BYTES L1_CACHE_BYTES
void _enable_icache(void);
void _disable_icache(void);
void _invalidate_icache(unsigned int addr);
#define __enable_icache() _enable_icache()
#define __disable_icache() _disable_icache()
#define __invalidate_icache(addr) _invalidate_icache(addr)
void _enable_dcache(void);
void _disable_dcache(void);
void _invalidate_dcache(unsigned int addr);
#define __enable_dcache() _enable_dcache()
#define __disable_dcache() _disable_dcache()
#define __invalidate_dcache(addr) _invalidate_dcache(addr)
#endif /* _ASM_MICROBLAZE_CACHE_H */
......@@ -18,6 +18,8 @@
/* Somebody depends on this; sigh... */
#include <linux/mm.h>
/* Look at Documentation/cachetlb.txt */
/*
* Cache handling functions.
* Microblaze has a write-through data cache, meaning that the data cache
......@@ -27,78 +29,81 @@
* instruction cache to make sure we don't fetch old, bad code.
*/
/* struct cache, d=dcache, i=icache, fl = flush, iv = invalidate,
* suffix r = range */
struct scache {
/* icache */
void (*ie)(void); /* enable */
void (*id)(void); /* disable */
void (*ifl)(void); /* flush */
void (*iflr)(unsigned long a, unsigned long b);
void (*iin)(void); /* invalidate */
void (*iinr)(unsigned long a, unsigned long b);
/* dcache */
void (*de)(void); /* enable */
void (*dd)(void); /* disable */
void (*dfl)(void); /* flush */
void (*dflr)(unsigned long a, unsigned long b);
void (*din)(void); /* invalidate */
void (*dinr)(unsigned long a, unsigned long b);
};
/* microblaze cache */
extern struct scache *mbc;
void microblaze_cache_init(void);
#define enable_icache() mbc->ie();
#define disable_icache() mbc->id();
#define flush_icache() mbc->ifl();
#define flush_icache_range(start, end) mbc->iflr(start, end);
#define invalidate_icache() mbc->iin();
#define invalidate_icache_range(start, end) mbc->iinr(start, end);
#define flush_icache_user_range(vma, pg, adr, len) flush_icache();
#define flush_icache_page(vma, pg) do { } while (0)
#define enable_dcache() mbc->de();
#define disable_dcache() mbc->dd();
/* FIXME for LL-temac driver */
#define invalidate_dcache_range(start, end) \
__invalidate_dcache_range(start, end)
#define flush_cache_all() __invalidate_cache_all()
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_range(vma, start, end) __invalidate_cache_all()
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
#define invalidate_dcache() mbc->din();
#define invalidate_dcache_range(start, end) mbc->dinr(start, end);
#define flush_dcache() mbc->dfl();
#define flush_dcache_range(start, end) mbc->dflr(start, end);
#define flush_dcache_range(start, end) __invalidate_dcache_range(start, end)
#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
/* D-cache aliasing problem can't happen - cache is between MMU and ram */
#define flush_dcache_page(page) do { } while (0)
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_icache_range(start, len) __invalidate_icache_range(start, len)
#define flush_icache_page(vma, pg) do { } while (0)
#ifndef CONFIG_MMU
# define flush_icache_user_range(start, len) do { } while (0)
#else
# define flush_icache_user_range(vma, pg, adr, len) __invalidate_icache_all()
# define flush_page_to_ram(page) do { } while (0)
# define flush_icache() __invalidate_icache_all()
# define flush_cache_sigtramp(vaddr) \
__invalidate_icache_range(vaddr, vaddr + 8)
# define flush_dcache_mmap_lock(mapping) do { } while (0)
# define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
# define flush_cache_dup_mm(mm) do { } while (0)
/* MS: kgdb code use this macro, wrong len with FLASH */
#if 0
#define flush_cache_range(vma, start, len) { \
flush_icache_range((unsigned) (start), (unsigned) (start) + (len)); \
flush_dcache_range((unsigned) (start), (unsigned) (start) + (len)); \
}
#endif
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
struct page;
struct mm_struct;
struct vm_area_struct;
/* see arch/microblaze/kernel/cache.c */
extern void __invalidate_icache_all(void);
extern void __invalidate_icache_range(unsigned long start, unsigned long end);
extern void __invalidate_icache_page(struct vm_area_struct *vma,
struct page *page);
extern void __invalidate_icache_user_range(struct vm_area_struct *vma,
struct page *page,
unsigned long adr, int len);
extern void __invalidate_cache_sigtramp(unsigned long addr);
extern void __invalidate_dcache_all(void);
extern void __invalidate_dcache_range(unsigned long start, unsigned long end);
extern void __invalidate_dcache_page(struct vm_area_struct *vma,
struct page *page);
extern void __invalidate_dcache_user_range(struct vm_area_struct *vma,
struct page *page,
unsigned long adr, int len);
extern inline void __invalidate_cache_all(void)
{
__invalidate_icache_all();
__invalidate_dcache_all();
}
#define flush_cache_range(vma, start, len) do { } while (0)
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { memcpy((dst), (src), (len)); \
flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy((dst), (src), (len)); \
flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
memcpy((dst), (src), (len))
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
do { \
memcpy((dst), (src), (len)); \
} while (0)
#endif /* _ASM_MICROBLAZE_CACHEFLUSH_H */
......@@ -43,7 +43,7 @@ struct cpuinfo {
u32 use_icache;
u32 icache_tagbits;
u32 icache_write;
u32 icache_line;
u32 icache_line_length;
u32 icache_size;
unsigned long icache_base;
unsigned long icache_high;
......@@ -51,8 +51,9 @@ struct cpuinfo {
u32 use_dcache;
u32 dcache_tagbits;
u32 dcache_write;
u32 dcache_line;
u32 dcache_line_length;
u32 dcache_size;
u32 dcache_wb;
unsigned long dcache_base;
unsigned long dcache_high;
......
......@@ -19,6 +19,18 @@ struct dev_archdata {
struct pdev_archdata {
};
static inline void dev_archdata_set_node(struct dev_archdata *ad,
struct device_node *np)
{
ad->of_node = np;
}
static inline struct device_node *
dev_archdata_get_node(const struct dev_archdata *ad)
{
return ad->of_node;
}
#endif /* _ASM_MICROBLAZE_DEVICE_H */
#ifndef _ASM_MICROBLAZE_FTRACE
#define _ASM_MICROBLAZE_FTRACE
#ifdef CONFIG_FUNCTION_TRACER
#define MCOUNT_ADDR ((long)(_mcount))
#define MCOUNT_INSN_SIZE 8 /* sizeof mcount call */
#ifndef __ASSEMBLY__
extern void _mcount(void);
extern void ftrace_call_graph(void);
#endif
#ifdef CONFIG_DYNAMIC_FTRACE
/* reloction of mcount call site is the same as the address */
static inline unsigned long ftrace_call_adjust(unsigned long addr)
{
return addr;
}
struct dyn_arch_ftrace {
};
#endif /* CONFIG_DYNAMIC_FTRACE */
#endif /* CONFIG_FUNCTION_TRACER */
#endif /* _ASM_MICROBLAZE_FTRACE */
#include <asm-generic/futex.h>
#ifndef _ASM_MICROBLAZE_FUTEX_H
#define _ASM_MICROBLAZE_FUTEX_H
#ifdef __KERNEL__
#include <linux/futex.h>
#include <linux/uaccess.h>
#include <asm/errno.h>
#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
({ \
__asm__ __volatile__ ( \
"1: lwx %0, %2, r0; " \
insn \
"2: swx %1, %2, r0; \
addic %1, r0, 0; \
bnei %1, 1b; \
3: \
.section .fixup,\"ax\"; \
4: brid 3b; \
addik %1, r0, %3; \
.previous; \
.section __ex_table,\"a\"; \
.word 1b,4b,2b,4b; \
.previous;" \
: "=&r" (oldval), "=&r" (ret) \
: "b" (uaddr), "i" (-EFAULT), "r" (oparg) \
); \
})
static inline int
futex_atomic_op_inuser(int encoded_op, int __user *uaddr)
{
int op = (encoded_op >> 28) & 7;
int cmp = (encoded_op >> 24) & 15;
int oparg = (encoded_op << 8) >> 20;
int cmparg = (encoded_op << 20) >> 20;
int oldval = 0, ret;
if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))
oparg = 1 << oparg;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
pagefault_disable();
switch (op) {
case FUTEX_OP_SET:
__futex_atomic_op("or %1,%4,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ADD:
__futex_atomic_op("add %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_OR:
__futex_atomic_op("or %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_ANDN:
__futex_atomic_op("and %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
case FUTEX_OP_XOR:
__futex_atomic_op("xor %1,%0,%4;", ret, oldval, uaddr, oparg);
break;
default:
ret = -ENOSYS;
}
pagefault_enable();
if (!ret) {
switch (cmp) {
case FUTEX_OP_CMP_EQ:
ret = (oldval == cmparg);
break;
case FUTEX_OP_CMP_NE:
ret = (oldval != cmparg);
break;
case FUTEX_OP_CMP_LT:
ret = (oldval < cmparg);
break;
case FUTEX_OP_CMP_GE:
ret = (oldval >= cmparg);
break;
case FUTEX_OP_CMP_LE:
ret = (oldval <= cmparg);
break;
case FUTEX_OP_CMP_GT:
ret = (oldval > cmparg);
break;
default:
ret = -ENOSYS;
}
}
return ret;
}
static inline int
futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
{
int prev, cmp;
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int)))
return -EFAULT;
__asm__ __volatile__ ("1: lwx %0, %2, r0; \
cmp %1, %0, %3; \
beqi %1, 3f; \
2: swx %4, %2, r0; \
addic %1, r0, 0; \
bnei %1, 1b; \
3: \
.section .fixup,\"ax\"; \
4: brid 3b; \
addik %0, r0, %5; \
.previous; \
.section __ex_table,\"a\"; \
.word 1b,4b,2b,4b; \
.previous;" \
: "=&r" (prev), "=&r"(cmp) \
: "r" (uaddr), "r" (oldval), "r" (newval), "i" (-EFAULT));
return prev;
}
#endif /* __KERNEL__ */
#endif
......@@ -10,78 +10,73 @@
#define _ASM_MICROBLAZE_IRQFLAGS_H
#include <linux/irqflags.h>
#include <asm/registers.h>
# if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
# define local_irq_save(flags) \
# define raw_local_irq_save(flags) \
do { \
asm volatile ("# local_irq_save \n\t" \
"msrclr %0, %1 \n\t" \
"nop \n\t" \
asm volatile (" msrclr %0, %1; \
nop;" \
: "=r"(flags) \
: "i"(MSR_IE) \
: "memory"); \
} while (0)
# define local_irq_disable() \
do { \
asm volatile ("# local_irq_disable \n\t" \
"msrclr r0, %0 \n\t" \
"nop \n\t" \
: \
: "i"(MSR_IE) \
: "memory"); \
# define raw_local_irq_disable() \
do { \
asm volatile (" msrclr r0, %0; \
nop;" \
: \
: "i"(MSR_IE) \
: "memory"); \
} while (0)
# define local_irq_enable() \
do { \
asm volatile ("# local_irq_enable \n\t" \
"msrset r0, %0 \n\t" \
"nop \n\t" \
: \
: "i"(MSR_IE) \
: "memory"); \
# define raw_local_irq_enable() \
do { \
asm volatile (" msrset r0, %0; \
nop;" \
: \
: "i"(MSR_IE) \
: "memory"); \
} while (0)
# else /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR == 0 */
# define local_irq_save(flags) \
# define raw_local_irq_save(flags) \
do { \
register unsigned tmp; \
asm volatile ("# local_irq_save \n\t" \
"mfs %0, rmsr \n\t" \
"nop \n\t" \
"andi %1, %0, %2 \n\t" \
"mts rmsr, %1 \n\t" \
"nop \n\t" \
asm volatile (" mfs %0, rmsr; \
nop; \
andi %1, %0, %2; \
mts rmsr, %1; \
nop;" \
: "=r"(flags), "=r" (tmp) \
: "i"(~MSR_IE) \
: "memory"); \
} while (0)
# define local_irq_disable() \
# define raw_local_irq_disable() \
do { \
register unsigned tmp; \
asm volatile ("# local_irq_disable \n\t" \
"mfs %0, rmsr \n\t" \
"nop \n\t" \
"andi %0, %0, %1 \n\t" \
"mts rmsr, %0 \n\t" \
"nop \n\t" \
asm volatile (" mfs %0, rmsr; \
nop; \
andi %0, %0, %1; \
mts rmsr, %0; \
nop;" \
: "=r"(tmp) \
: "i"(~MSR_IE) \
: "memory"); \
} while (0)
# define local_irq_enable() \
# define raw_local_irq_enable() \
do { \
register unsigned tmp; \
asm volatile ("# local_irq_enable \n\t" \
"mfs %0, rmsr \n\t" \
"nop \n\t" \
"ori %0, %0, %1 \n\t" \
"mts rmsr, %0 \n\t" \
"nop \n\t" \
asm volatile (" mfs %0, rmsr; \
nop; \
ori %0, %0, %1; \
mts rmsr, %0; \
nop;" \
: "=r"(tmp) \
: "i"(MSR_IE) \
: "memory"); \
......@@ -89,35 +84,28 @@
# endif /* CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR */
#define local_save_flags(flags) \
#define raw_local_irq_restore(flags) \
do { \
asm volatile ("# local_save_flags \n\t" \
"mfs %0, rmsr \n\t" \
"nop \n\t" \
: "=r"(flags) \
asm volatile (" mts rmsr, %0; \
nop;" \
: \
: "r"(flags) \
: "memory"); \
} while (0)
#define local_irq_restore(flags) \
do { \
asm volatile ("# local_irq_restore \n\t"\
"mts rmsr, %0 \n\t" \
"nop \n\t" \
: \
: "r"(flags) \
: "memory"); \
} while (0)
static inline int irqs_disabled(void)
static inline unsigned long get_msr(void)
{
unsigned long flags;
local_save_flags(flags);
return ((flags & MSR_IE) == 0);
asm volatile (" mfs %0, rmsr; \
nop;" \
: "=r"(flags) \
: \
: "memory"); \