Commit c8d34f0d authored by Stephen Rothwell's avatar Stephen Rothwell

Merge commit 'microblaze/next'

Conflicts:
	kernel/gcov/Kconfig
parents b274b7cf de0dfed4
...@@ -47,7 +47,7 @@ Possible uses: ...@@ -47,7 +47,7 @@ Possible uses:
Configure the kernel with: Configure the kernel with:
CONFIG_DEBUGFS=y CONFIG_DEBUG_FS=y
CONFIG_GCOV_KERNEL=y CONFIG_GCOV_KERNEL=y
and to get coverage data for the entire kernel: and to get coverage data for the entire kernel:
......
...@@ -6,6 +6,7 @@ mainmenu "Linux/Microblaze Kernel Configuration" ...@@ -6,6 +6,7 @@ mainmenu "Linux/Microblaze Kernel Configuration"
config MICROBLAZE config MICROBLAZE
def_bool y def_bool y
select HAVE_LMB select HAVE_LMB
select USB_ARCH_HAS_EHCI
select ARCH_WANT_OPTIONAL_GPIOLIB select ARCH_WANT_OPTIONAL_GPIOLIB
config SWAP config SWAP
......
...@@ -210,6 +210,9 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size, ...@@ -210,6 +210,9 @@ static inline void __iomem *__ioremap(phys_addr_t address, unsigned long size,
#define in_be32(a) __raw_readl((const void __iomem __force *)(a)) #define in_be32(a) __raw_readl((const void __iomem __force *)(a))
#define in_be16(a) __raw_readw(a) #define in_be16(a) __raw_readw(a)
#define writel_be(v, a) out_be32((__force unsigned *)a, v)
#define readl_be(a) in_be32((__force unsigned *)a)
/* /*
* Little endian * Little endian
*/ */
......
...@@ -38,7 +38,7 @@ extern void early_console_reg_tlb_alloc(unsigned int addr); ...@@ -38,7 +38,7 @@ extern void early_console_reg_tlb_alloc(unsigned int addr);
void time_init(void); void time_init(void);
void init_IRQ(void); void init_IRQ(void);
void machine_early_init(const char *cmdline, unsigned int ram, void machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt); unsigned int fdt, unsigned int msr);
void machine_restart(char *cmd); void machine_restart(char *cmd);
void machine_shutdown(void); void machine_shutdown(void);
......
#ifndef __ASM_MICROBLAZE_SYSCALL_H
#define __ASM_MICROBLAZE_SYSCALL_H
#include <linux/kernel.h>
#include <linux/sched.h>
#include <asm/ptrace.h>
/* The system call number is given by the user in R12 */
static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
{
return regs->r12;
}
static inline void syscall_rollback(struct task_struct *task,
struct pt_regs *regs)
{
/* TODO. */
}
static inline long syscall_get_error(struct task_struct *task,
struct pt_regs *regs)
{
return IS_ERR_VALUE(regs->r3) ? regs->r3 : 0;
}
static inline long syscall_get_return_value(struct task_struct *task,
struct pt_regs *regs)
{
return regs->r3;
}
static inline void syscall_set_return_value(struct task_struct *task,
struct pt_regs *regs,
int error, long val)
{
if (error)
regs->r3 = -error;
else
regs->r3 = val;
}
static inline microblaze_reg_t microblaze_get_syscall_arg(struct pt_regs *regs,
unsigned int n)
{
switch (n) {
case 5: return regs->r10;
case 4: return regs->r9;
case 3: return regs->r8;
case 2: return regs->r7;
case 1: return regs->r6;
case 0: return regs->r5;
default:
BUG();
}
return ~0;
}
static inline void microblaze_set_syscall_arg(struct pt_regs *regs,
unsigned int n,
unsigned long val)
{
switch (n) {
case 5:
regs->r10 = val;
case 4:
regs->r9 = val;
case 3:
regs->r8 = val;
case 2:
regs->r7 = val;
case 1:
regs->r6 = val;
case 0:
regs->r5 = val;
default:
BUG();
}
}
static inline void syscall_get_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned int i, unsigned int n,
unsigned long *args)
{
while (n--)
*args++ = microblaze_get_syscall_arg(regs, i++);
}
static inline void syscall_set_arguments(struct task_struct *task,
struct pt_regs *regs,
unsigned int i, unsigned int n,
const unsigned long *args)
{
while (n--)
microblaze_set_syscall_arg(regs, i++, *args++);
}
#endif /* __ASM_MICROBLAZE_SYSCALL_H */
...@@ -308,32 +308,62 @@ C_ENTRY(_user_exception): ...@@ -308,32 +308,62 @@ C_ENTRY(_user_exception):
swi r12, r1, PTO+PT_R0; swi r12, r1, PTO+PT_R0;
tovirt(r1,r1) tovirt(r1,r1)
la r15, r0, ret_from_trap-8
/* where the trap should return need -8 to adjust for rtsd r15, 8*/ /* where the trap should return need -8 to adjust for rtsd r15, 8*/
/* Jump to the appropriate function for the system call number in r12 /* Jump to the appropriate function for the system call number in r12
* (r12 is not preserved), or return an error if r12 is not valid. The LP * (r12 is not preserved), or return an error if r12 is not valid. The LP
* register should point to the location where * register should point to the location where
* the called function should return. [note that MAKE_SYS_CALL uses label 1] */ * the called function should return. [note that MAKE_SYS_CALL uses label 1] */
# Step into virtual mode.
set_vms;
addik r11, r0, 3f
rtid r11, 0
nop
3:
add r11, r0, CURRENT_TASK /* Get current task ptr into r11 */
lwi r11, r11, TS_THREAD_INFO /* get thread info */
lwi r11, r11, TI_FLAGS /* get flags in thread info */
andi r11, r11, _TIF_WORK_SYSCALL_MASK
beqi r11, 4f
addik r3, r0, -ENOSYS
swi r3, r1, PTO + PT_R3
brlid r15, do_syscall_trace_enter
addik r5, r1, PTO + PT_R0
# do_syscall_trace_enter returns the new syscall nr.
addk r12, r0, r3
lwi r5, r1, PTO+PT_R5;
lwi r6, r1, PTO+PT_R6;
lwi r7, r1, PTO+PT_R7;
lwi r8, r1, PTO+PT_R8;
lwi r9, r1, PTO+PT_R9;
lwi r10, r1, PTO+PT_R10;
4:
/* Jump to the appropriate function for the system call number in r12 (r12 is not preserved),
* or return an error if r12 is not valid. The LP register should point to the location where
* the called function should return. [note that MAKE_SYS_CALL uses label 1] */
/* See if the system call number is valid. */ /* See if the system call number is valid. */
addi r11, r12, -__NR_syscalls; addi r11, r12, -__NR_syscalls;
bgei r11,1f; bgei r11,5f;
/* Figure out which function to use for this system call. */ /* Figure out which function to use for this system call. */
/* Note Microblaze barrel shift is optional, so don't rely on it */ /* Note Microblaze barrel shift is optional, so don't rely on it */
add r12, r12, r12; /* convert num -> ptr */ add r12, r12, r12; /* convert num -> ptr */
add r12, r12, r12; add r12, r12, r12;
/* Trac syscalls and stored them to r0_ram */ /* Trac syscalls and stored them to r0_ram */
lwi r3, r12, 0x400 + TOPHYS(r0_ram) lwi r3, r12, 0x400 + r0_ram
addi r3, r3, 1 addi r3, r3, 1
swi r3, r12, 0x400 + TOPHYS(r0_ram) swi r3, r12, 0x400 + r0_ram
# Find and jump into the syscall handler.
lwi r12, r12, sys_call_table
la r15, r0, ret_from_trap-8 /* where the trap should return need -8 to adjust for rtsd r15, 8*/
bra r12
lwi r12, r12, TOPHYS(sys_call_table); /* Function ptr */
/* Make the system call. to r12*/
set_vms;
rtid r12, 0;
nop;
/* The syscall number is invalid, return an error. */ /* The syscall number is invalid, return an error. */
1: VM_ON; /* RETURN() expects virtual mode*/ 5:
addi r3, r0, -ENOSYS; addi r3, r0, -ENOSYS;
rtsd r15,8; /* looks like a normal subroutine return */ rtsd r15,8; /* looks like a normal subroutine return */
or r0, r0, r0 or r0, r0, r0
...@@ -349,6 +379,22 @@ C_ENTRY(ret_from_trap): ...@@ -349,6 +379,22 @@ C_ENTRY(ret_from_trap):
/* We're returning to user mode, so check for various conditions that /* We're returning to user mode, so check for various conditions that
* trigger rescheduling. */ * trigger rescheduling. */
# FIXME: Restructure all these flag checks.
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
lwi r11, r11, TS_THREAD_INFO; /* get thread info */
lwi r11, r11, TI_FLAGS; /* get flags in thread info */
andi r11, r11, _TIF_WORK_SYSCALL_MASK
beqi r11, 1f
swi r3, r1, PTO + PT_R3
swi r4, r1, PTO + PT_R4
brlid r15, do_syscall_trace_leave
addik r5, r1, PTO + PT_R0
lwi r3, r1, PTO + PT_R3
lwi r4, r1, PTO + PT_R4
1:
/* We're returning to user mode, so check for various conditions that trigger rescheduling. */
/* Get current task ptr into r11 */ /* Get current task ptr into r11 */
add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */ add r11, r0, CURRENT_TASK; /* Get current task ptr into r11 */
lwi r11, r11, TS_THREAD_INFO; /* get thread info */ lwi r11, r11, TS_THREAD_INFO; /* get thread info */
......
...@@ -54,6 +54,16 @@ ENTRY(_start) ...@@ -54,6 +54,16 @@ ENTRY(_start)
mfs r1, rmsr mfs r1, rmsr
andi r1, r1, ~2 andi r1, r1, ~2
mts rmsr, r1 mts rmsr, r1
/*
* Here is checking mechanism which check if Microblaze has msr instructions
* We load msr and compare it with previous r1 value - if is the same,
* msr instructions works if not - cpu don't have them.
*/
/* r8=0 - I have msr instr, 1 - I don't have them */
rsubi r0, r0, 1 /* set the carry bit */
msrclr r0, 0x4 /* try to clear it */
/* read the carry bit, r8 will be '0' if msrclr exists */
addik r8, r0, 0
/* r7 may point to an FDT, or there may be one linked in. /* r7 may point to an FDT, or there may be one linked in.
if it's in r7, we've got to save it away ASAP. if it's in r7, we've got to save it away ASAP.
...@@ -209,8 +219,8 @@ start_here: ...@@ -209,8 +219,8 @@ start_here:
* Please see $(ARCH)/mach-$(SUBARCH)/setup.c for * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
* the function. * the function.
*/ */
la r8, r0, machine_early_init la r9, r0, machine_early_init
brald r15, r8 brald r15, r9
nop nop
#ifndef CONFIG_MMU #ifndef CONFIG_MMU
......
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/elf.h>
#include <linux/audit.h>
#include <linux/seccomp.h>
#include <linux/tracehook.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/processor.h> #include <asm/processor.h>
...@@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) ...@@ -174,6 +178,64 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
return rval; return rval;
} }
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{
long ret = 0;
secure_computing(regs->r12);
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs))
/*
* Tracing decided this syscall should not happen.
* We'll return a bogus call number to get an ENOSYS
* error, but leave the original number in regs->regs[0].
*/
ret = -1L;
if (unlikely(current->audit_context))
audit_syscall_entry(EM_XILINX_MICROBLAZE, regs->r12,
regs->r5, regs->r6,
regs->r7, regs->r8);
return ret ?: regs->r12;
}
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
{
int step;
if (unlikely(current->audit_context))
audit_syscall_exit(AUDITSC_RESULT(regs->r3), regs->r3);
step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step);
}
#if 0
static asmlinkage void syscall_trace(void)
{
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
if (!(current->ptrace & PT_PTRACED))
return;
/* The 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
* stopping signal is not SIGTRAP. -brl
*/
if (current->exit_code) {
send_sig(current->exit_code, current, 1);
current->exit_code = 0;
}
}
#endif
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
/* nothing to do */ /* nothing to do */
......
...@@ -94,7 +94,7 @@ inline unsigned get_romfs_len(unsigned *addr) ...@@ -94,7 +94,7 @@ inline unsigned get_romfs_len(unsigned *addr)
#endif /* CONFIG_MTD_UCLINUX_EBSS */ #endif /* CONFIG_MTD_UCLINUX_EBSS */
void __init machine_early_init(const char *cmdline, unsigned int ram, void __init machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt) unsigned int fdt, unsigned int msr)
{ {
unsigned long *src, *dst = (unsigned long *)0x0; unsigned long *src, *dst = (unsigned long *)0x0;
...@@ -157,6 +157,16 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, ...@@ -157,6 +157,16 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
early_printk("New klimit: 0x%08x\n", (unsigned)klimit); early_printk("New klimit: 0x%08x\n", (unsigned)klimit);
#endif #endif
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
if (msr)
early_printk("!!!Your kernel has setup MSR instruction but "
"CPU don't have it %d\n", msr);
#else
if (!msr)
early_printk("!!!Your kernel not setup MSR instruction but "
"CPU have it %d\n", msr);
#endif
for (src = __ivt_start; src < __ivt_end; src++, dst++) for (src = __ivt_start; src < __ivt_end; src++, dst++)
*dst = *src; *dst = *src;
......
...@@ -13,6 +13,8 @@ OUTPUT_ARCH(microblaze) ...@@ -13,6 +13,8 @@ OUTPUT_ARCH(microblaze)
ENTRY(_start) ENTRY(_start)
#include <asm-generic/vmlinux.lds.h> #include <asm-generic/vmlinux.lds.h>
#include <asm/page.h>
#include <asm/thread_info.h>
jiffies = jiffies_64 + 4; jiffies = jiffies_64 + 4;
...@@ -39,12 +41,7 @@ SECTIONS { ...@@ -39,12 +41,7 @@ SECTIONS {
. = ALIGN(16); . = ALIGN(16);
RODATA RODATA
. = ALIGN(16); EXCEPTION_TABLE(16)
__ex_table : {
__start___ex_table = .;
*(__ex_table)
__stop___ex_table = .;
}
/* /*
* sdata2 section can go anywhere, but must be word aligned * sdata2 section can go anywhere, but must be word aligned
...@@ -61,12 +58,7 @@ SECTIONS { ...@@ -61,12 +58,7 @@ SECTIONS {
} }
_sdata = . ; _sdata = . ;
.data ALIGN (4096) : { /* page aligned when MMU used - origin 0x4 */ RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
DATA_DATA
CONSTRUCTORS
}
. = ALIGN(32);
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
_edata = . ; _edata = . ;
/* Reserve some low RAM for r0 based memory references */ /* Reserve some low RAM for r0 based memory references */
...@@ -74,10 +66,6 @@ SECTIONS { ...@@ -74,10 +66,6 @@ SECTIONS {
r0_ram = . ; r0_ram = . ;
. = . + 4096; /* a page should be enough */ . = . + 4096; /* a page should be enough */
/* The initial task */
. = ALIGN(8192);
.data.init_task : { *(.data.init_task) }
/* Under the microblaze ABI, .sdata and .sbss must be contiguous */ /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
. = ALIGN(8); . = ALIGN(8);
.sdata : { .sdata : {
...@@ -96,12 +84,7 @@ SECTIONS { ...@@ -96,12 +84,7 @@ SECTIONS {
__init_begin = .; __init_begin = .;
. = ALIGN(4096); INIT_TEXT_SECTION(PAGE_SIZE)
.init.text : {
_sinittext = . ;
INIT_TEXT
_einittext = .;
}
.init.data : { .init.data : {
INIT_DATA INIT_DATA
...@@ -115,21 +98,15 @@ SECTIONS { ...@@ -115,21 +98,15 @@ SECTIONS {
} }
.init.setup : { .init.setup : {
__setup_start = .; INIT_SETUP(0)
*(.init.setup)
__setup_end = .;
} }
.initcall.init : { .initcall.init : {
__initcall_start = .; INIT_CALLS
INITCALLS
__initcall_end = .;
} }
.con_initcall.init : { .con_initcall.init : {
__con_initcall_start = .; CON_INITCALL
*(.con_initcall.init)
__con_initcall_end = .;
} }
SECURITY_INIT SECURITY_INIT
......
...@@ -159,7 +159,7 @@ config MTD_AFS_PARTS ...@@ -159,7 +159,7 @@ config MTD_AFS_PARTS
config MTD_OF_PARTS config MTD_OF_PARTS
tristate "Flash partition map based on OF description" tristate "Flash partition map based on OF description"
depends on PPC_OF && MTD_PARTITIONS depends on (MICROBLAZE || PPC_OF) && MTD_PARTITIONS
help help
This provides a partition parsing function which derives This provides a partition parsing function which derives
the partition map from the children of the flash node, the partition map from the children of the flash node,
......
...@@ -74,7 +74,7 @@ config MTD_PHYSMAP_BANKWIDTH ...@@ -74,7 +74,7 @@ config MTD_PHYSMAP_BANKWIDTH
config MTD_PHYSMAP_OF config MTD_PHYSMAP_OF
tristate "Flash device in physical memory map based on OF description" tristate "Flash device in physical memory map based on OF description"
depends on PPC_OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM) depends on (MICROBLAZE || PPC_OF) && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM)
help help
This provides a 'mapping' driver which allows the NOR Flash and This provides a 'mapping' driver which allows the NOR Flash and
ROM driver code to communicate with chips which are mapped ROM driver code to communicate with chips which are mapped
......
...@@ -22,7 +22,6 @@ config USB_ARCH_HAS_HCD ...@@ -22,7 +22,6 @@ config USB_ARCH_HAS_HCD
default y if PCMCIA && !M32R # sl811_cs default y if PCMCIA && !M32R # sl811_cs
default y if ARM # SL-811 default y if ARM # SL-811
default y if SUPERH # r8a66597-hcd default y if SUPERH # r8a66597-hcd
default y if MICROBLAZE
default PCI default PCI
# many non-PCI SOC chips embed OHCI # many non-PCI SOC chips embed OHCI
......
...@@ -34,7 +34,7 @@ config GCOV_KERNEL ...@@ -34,7 +34,7 @@ config GCOV_KERNEL
config GCOV_PROFILE_ALL config GCOV_PROFILE_ALL
bool "Profile entire Kernel" bool "Profile entire Kernel"
depends on GCOV_KERNEL depends on GCOV_KERNEL
depends on S390 || X86 || (PPC && EXPERIMENTAL) depends on S390 || X86 || MICROBLAZE || (PPC && EXPERIMENTAL)
default n default n
---help--- ---help---
This options activates profiling for the entire kernel. This options activates profiling for the entire kernel.
......
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