Microblaze init port - Kernel

This is a discussion on Microblaze init port - Kernel ; From: Michal Simek Signed-off-by: Michal Simek --- arch/microblaze/kernel/ptrace.c | 212 +++++++++++++++++++++++++++++++++++++++ include/asm-microblaze/ptrace.h | 70 +++++++++++++ 2 files changed, 282 insertions(+), 0 deletions(-) create mode 100644 arch/microblaze/kernel/ptrace.c create mode 100644 include/asm-microblaze/ptrace.h diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c new file mode 100644 index 0000000..f2939ea ...

+ Reply to Thread
Page 2 of 3 FirstFirst 1 2 3 LastLast
Results 21 to 40 of 42

Thread: Microblaze init port

  1. [PATCH 25/52] [microblaze] ptrace support

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/kernel/ptrace.c | 212 +++++++++++++++++++++++++++++++++++++++
    include/asm-microblaze/ptrace.h | 70 +++++++++++++
    2 files changed, 282 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/kernel/ptrace.c
    create mode 100644 include/asm-microblaze/ptrace.h

    diff --git a/arch/microblaze/kernel/ptrace.c b/arch/microblaze/kernel/ptrace.c
    new file mode 100644
    index 0000000..f2939ea
    --- /dev/null
    +++ b/arch/microblaze/kernel/ptrace.c
    @@ -0,0 +1,212 @@
    +/*
    + * arch/microblaze/kernel/ptrace.c -- `ptrace' system call
    + *
    + * Copyright (C) 2007 PetaLogix
    + * Copyright (C) 2004-07 John Williams
    + *
    + * derived from arch/v850/kernel/ptrace.c
    + *
    + * Copyright (C) 2002,03 NEC Electronics Corporation
    + * Copyright (C) 2002,03 Miles Bader
    + *
    + * Derived from arch/mips/kernel/ptrace.c:
    + *
    + * Copyright (C) 1992 Ross Biro
    + * Copyright (C) Linus Torvalds
    + * Copyright (C) 1994, 95, 96, 97, 98, 2000 Ralf Baechle
    + * Copyright (C) 1996 David S. Miller
    + * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
    + * Copyright (C) 1999 MIPS Technologies, Inc.
    + *
    + * This file is subject to the terms and conditions of the GNU General
    + * Public License. See the file COPYING in the main directory of this
    + * archive for more details.
    + */
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#if 0
    +#define DBPRINTK(...) printk(__VA_ARGS__)
    +#else
    +#define DBPRINTK(...)
    +#endif
    +
    +/* Returns the address where the register at REG_OFFS in P is stashed away. */
    +static microblaze_reg_t *reg_save_addr(unsigned reg_offs,
    + struct task_struct *t)
    +{
    + struct pt_regs *regs;
    +
    + /*
    + * Three basic cases:
    + *
    + * (1) A register normally saved before calling the scheduler, is
    + * available in the kernel entry pt_regs structure at the top
    + * of the kernel stack. The kernel trap/irq exit path takes
    + * care to save/restore almost all registers for ptrace'd
    + * processes.
    + *
    + * (2) A call-clobbered register, where the process P entered the
    + * kernel via [syscall] trap, is not stored anywhere; that's
    + * OK, because such registers are not expected to be preserved
    + * when the trap returns anyway (so we don't actually bother to
    + * test for this case).
    + *
    + * (3) A few registers not used at all by the kernel, and so
    + * normally never saved except by context-switches, are in the
    + * context switch state.
    + */
    +
    + /* Register saved during kernel entry (or not available). */
    + regs = task_pt_regs(t);
    +
    + return (microblaze_reg_t *)((char *)regs + reg_offs);
    +}
    +
    +long arch_ptrace(struct task_struct *child, long request, long addr, long data)
    +{
    + int rval;
    +
    + switch (request) {
    + unsigned long val, copied;
    +
    + case PTRACE_PEEKTEXT: /* read word at location addr. */
    + case PTRACE_PEEKDATA:
    + DBPRINTK("PEEKTEXT/PEEKDATA at %08lX\n", addr);
    + copied = access_process_vm(child, addr, &val, sizeof(val), 0);
    + rval = -EIO;
    + if (copied != sizeof(val))
    + break;
    + rval = put_user(val, (unsigned long *)data);
    + goto out;
    +
    + case PTRACE_POKETEXT: /* write the word at location addr. */
    + case PTRACE_POKEDATA:
    + DBPRINTK("POKETEXT/POKEDATA to %08lX\n", addr);
    + rval = 0;
    + if (access_process_vm(child, addr, &data, sizeof(data), 1)
    + == sizeof(data))
    + break;
    + rval = -EIO;
    + goto out;
    +
    + /* Read/write the word at location ADDR in the registers. */
    + case PTRACE_PEEKUSR:
    + case PTRACE_POKEUSR:
    + DBPRINTK("PEEKUSR/POKEUSR : 0x%08lx\n", addr);
    + rval = 0;
    + if (addr >= PT_SIZE && request == PTRACE_PEEKUSR) {
    + /* Special requests that don't actually correspond
    + to offsets in struct pt_regs. */
    + if (addr == PT_TEXT_ADDR) {
    + val = child->mm->start_code;
    + } else if (addr == PT_DATA_ADDR) {
    + val = child->mm->start_data;
    + } else if (addr == PT_TEXT_LEN) {
    + val = child->mm->end_code
    + - child->mm->start_code;
    + } else {
    + rval = -EIO;
    + }
    + } else if (addr >= 0 && addr < PT_SIZE && (addr & 0x3) == 0) {
    + microblaze_reg_t *reg_addr = reg_save_addr(addr, child);
    + if (request == PTRACE_PEEKUSR) {
    + val = *reg_addr;
    + } else {
    + *reg_addr = data;
    + }
    + } else
    + rval = -EIO;
    +
    + if (rval == 0 && request == PTRACE_PEEKUSR)
    + rval = put_user(val, (unsigned long *)data);
    + goto out;
    +
    + /* Continue and stop at next (return from) syscall */
    + case PTRACE_SYSCALL:
    + DBPRINTK("PTRACE_SYSCALL\n");
    + case PTRACE_SINGLESTEP:
    + DBPRINTK("PTRACE_SINGLESTEP\n");
    + /* Restart after a signal. */
    + case PTRACE_CONT:
    + DBPRINTK("PTRACE_CONT\n");
    + rval = -EIO;
    + if (!valid_signal(data))
    + break;
    +
    + if (request == PTRACE_SYSCALL)
    + set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
    + else
    + clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
    +
    + child->exit_code = data;
    + DBPRINTK("wakeup_process\n");
    + wake_up_process(child);
    + rval = 0;
    + break;
    +
    + /*
    + * make the child exit. Best I can do is send it a sigkill.
    + * perhaps it should be put in the status that it wants to
    + * exit.
    + */
    + case PTRACE_KILL:
    + DBPRINTK("PTRACE_KILL\n");
    + rval = 0;
    + if (child->exit_state == EXIT_ZOMBIE) /* already dead */
    + break;
    + child->exit_code = SIGKILL;
    + wake_up_process(child);
    + break;
    +
    + case PTRACE_DETACH: /* detach a process that was attached. */
    + DBPRINTK("PTRACE_DETACH\n");
    + rval = ptrace_detach(child, data);
    + break;
    +
    + default:
    + rval = -EIO;
    + goto out;
    + }
    + out:
    + return rval;
    +}
    +
    +#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)
    +{
    + /* nothing to do */
    +}
    diff --git a/include/asm-microblaze/ptrace.h b/include/asm-microblaze/ptrace.h
    new file mode 100644
    index 0000000..f583d72
    --- /dev/null
    +++ b/include/asm-microblaze/ptrace.h
    @@ -0,0 +1,70 @@
    +/*
    + * include/asm-microblaze/ptrace.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_PTRACE_H
    +#define _ASM_PTRACE_H
    +
    +#ifndef __ASSEMBLY__
    +#include
    +
    +typedef unsigned long microblaze_reg_t;
    +
    +struct pt_regs {
    + microblaze_reg_t r0;
    + microblaze_reg_t r1;
    + microblaze_reg_t r2;
    + microblaze_reg_t r3;
    + microblaze_reg_t r4;
    + microblaze_reg_t r5;
    + microblaze_reg_t r6;
    + microblaze_reg_t r7;
    + microblaze_reg_t r8;
    + microblaze_reg_t r9;
    + microblaze_reg_t r10;
    + microblaze_reg_t r11;
    + microblaze_reg_t r12;
    + microblaze_reg_t r13;
    + microblaze_reg_t r14;
    + microblaze_reg_t r15;
    + microblaze_reg_t r16;
    + microblaze_reg_t r17;
    + microblaze_reg_t r18;
    + microblaze_reg_t r19;
    + microblaze_reg_t r20;
    + microblaze_reg_t r21;
    + microblaze_reg_t r22;
    + microblaze_reg_t r23;
    + microblaze_reg_t r24;
    + microblaze_reg_t r25;
    + microblaze_reg_t r26;
    + microblaze_reg_t r27;
    + microblaze_reg_t r28;
    + microblaze_reg_t r29;
    + microblaze_reg_t r30;
    + microblaze_reg_t r31;
    + microblaze_reg_t pc;
    + microblaze_reg_t msr;
    + microblaze_reg_t ear;
    + microblaze_reg_t esr;
    + microblaze_reg_t fsr;
    + int kernel_mode;
    +};
    +
    +#define kernel_mode(regs) ((regs)->kernel_mode)
    +#define user_mode(regs) (!kernel_mode(regs))
    +
    +#define instruction_pointer(regs) ((regs)->pc)
    +#define profile_pc(regs) instruction_pointer(regs)
    +
    +extern void show_regs(struct pt_regs *);
    +
    +#endif /* __ASSEMBLY__ */
    +
    +#endif /* _ASM_PTRACE_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [PATCH 38/52] [microblaze] dma support

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    include/asm-microblaze/dma-mapping.h | 124 ++++++++++++++++++++++++++++++++++
    include/asm-microblaze/dma.h | 21 ++++++
    include/asm-microblaze/scatterlist.h | 21 ++++++
    3 files changed, 166 insertions(+), 0 deletions(-)
    create mode 100644 include/asm-microblaze/dma-mapping.h
    create mode 100644 include/asm-microblaze/dma.h
    create mode 100644 include/asm-microblaze/scatterlist.h

    diff --git a/include/asm-microblaze/dma-mapping.h b/include/asm-microblaze/dma-mapping.h
    new file mode 100644
    index 0000000..defe1c4
    --- /dev/null
    +++ b/include/asm-microblaze/dma-mapping.h
    @@ -0,0 +1,124 @@
    +/*
    + * include/asm-microblaze/dma-mapping.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_DMA_MAPPING_H
    +#define _ASM_DMA_MAPPING_H
    +
    +#include
    +#include
    +
    +struct scatterlist;
    +
    +#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)
    +
    +void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
    +void consistent_free(void *vaddr);
    +void consistent_sync(void *vaddr, size_t size, int direction);
    +void consistent_sync_page(struct page *page, unsigned long offset,
    + size_t size, int direction);
    +
    +/* FIXME */
    +static inline int
    +dma_supported(struct device *dev, u64 mask)
    +{
    + return 0;
    +}
    +
    +static inline dma_addr_t
    +dma_map_page(struct device *dev, struct page *page,
    + unsigned long offset, size_t size,
    + enum dma_data_direction direction)
    +{
    + BUG();
    + return 0;
    +}
    +
    +static inline void
    +dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
    + enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline int
    +dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
    + enum dma_data_direction direction)
    +{
    + BUG();
    + return 0;
    +}
    +
    +static inline void
    +dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
    + enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline void
    +dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
    + enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline void
    +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
    + size_t size, enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline void
    +dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
    + enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline void
    +dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
    + enum dma_data_direction direction)
    +{
    + BUG();
    +}
    +
    +static inline int
    +dma_mapping_error(dma_addr_t dma_addr)
    +{
    + return 0;
    +}
    +
    +static inline void *dma_alloc_coherent(struct device *dev, size_t size,
    + dma_addr_t *dma_handle, int flag)
    +{
    + return consistent_alloc(flag, size, dma_handle);
    +}
    +
    +static inline void dma_free_coherent(struct device *dev, size_t size,
    + void *vaddr, dma_addr_t dma_handle)
    +{
    + BUG();
    +}
    +
    +static inline dma_addr_t
    +dma_map_single(struct device *dev, void *ptr, size_t size,
    + enum dma_data_direction direction)
    +{
    + BUG_ON(direction == DMA_NONE);
    +
    + return virt_to_bus(ptr);
    +}
    +
    +#define dma_unmap_single(dev, addr, size, dir) do { } while (0)
    +
    +
    +#endif /* _ASM_DMA_MAPPING_H */
    diff --git a/include/asm-microblaze/dma.h b/include/asm-microblaze/dma.h
    new file mode 100644
    index 0000000..a0c5c41
    --- /dev/null
    +++ b/include/asm-microblaze/dma.h
    @@ -0,0 +1,21 @@
    +/*
    + * include/asm-microblaze/dma.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_DMA_H
    +#define _ASM_DMA_H
    +
    +/* we don't have dma address limit. define it as zero to be
    + * unlimited. */
    +#define MAX_DMA_ADDRESS (0)
    +
    +#define ISA_DMA_THRESHOLD (0)
    +
    +
    +#endif /* _ASM_DMA_H */
    diff --git a/include/asm-microblaze/scatterlist.h b/include/asm-microblaze/scatterlist.h
    new file mode 100644
    index 0000000..389bdc8
    --- /dev/null
    +++ b/include/asm-microblaze/scatterlist.h
    @@ -0,0 +1,21 @@
    +/*
    + * include/asm-microblaze/scatterlist.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_SCATTERLIST_H
    +#define _ASM_SCATTERLIST_H
    +
    +struct scatterlist {
    + unsigned long page_link;
    + unsigned int offset;
    + dma_addr_t dma_address;
    + unsigned int length;
    +};
    +
    +#endif /* _ASM_SCATTERLIST_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [PATCH 35/52] [microblaze] ioctl support

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    include/asm-microblaze/ioctl.h | 84 +++++++++++++++++++++++++++++++++++
    include/asm-microblaze/ioctls.h | 93 +++++++++++++++++++++++++++++++++++++++
    2 files changed, 177 insertions(+), 0 deletions(-)
    create mode 100644 include/asm-microblaze/ioctl.h
    create mode 100644 include/asm-microblaze/ioctls.h

    diff --git a/include/asm-microblaze/ioctl.h b/include/asm-microblaze/ioctl.h
    new file mode 100644
    index 0000000..c65a664
    --- /dev/null
    +++ b/include/asm-microblaze/ioctl.h
    @@ -0,0 +1,84 @@
    +/*
    + * include/asm-microblaze/ioctl.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _MICROBLAZE_IOCTL_H
    +#define _MICROBLAZE_IOCTL_H
    +
    +/*
    + * this was copied from the alpha as it's a bit cleaner there.
    + * -- Cort
    + */
    +
    +#define _IOC_NRBITS 8
    +#define _IOC_TYPEBITS 8
    +#define _IOC_SIZEBITS 13
    +#define _IOC_DIRBITS 3
    +
    +#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
    +#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
    +#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
    +#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
    +
    +#define _IOC_NRSHIFT 0
    +#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
    +#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
    +#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
    +
    +/*
    + * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
    + * And this turns out useful to catch old ioctl numbers in header
    + * files for us.
    + */
    +#define _IOC_NONE 1U
    +#define _IOC_READ 2U
    +#define _IOC_WRITE 4U
    +
    +#define _IOC(dir, type, nr, size) \
    + (((dir) << _IOC_DIRSHIFT) | \
    + ((type) << _IOC_TYPESHIFT) | \
    + ((nr) << _IOC_NRSHIFT) | \
    + ((size) << _IOC_SIZESHIFT))
    +
    +/* provoke compile error for invalid uses of size argument */
    +extern unsigned int __invalid_size_argument_for_IOC;
    +#define _IOC_TYPECHECK(t) \
    + ((sizeof(t) == sizeof(t[1]) && \
    + sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
    + sizeof(t) : __invalid_size_argument_for_IOC)
    +
    +/* used to create numbers */
    +#define _IO(type, nr) _IOC(_IOC_NONE, (type), (nr), 0)
    +#define _IOR(type, nr, size) \
    + _IOC(_IOC_READ, (type), (nr), (_IOC_TYPECHECK(size)))
    +#define _IOW(type, nr, size) \
    + _IOC(_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
    +#define _IOWR(type, nr, size) \
    + _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), (_IOC_TYPECHECK(size)))
    +#define _IOR_BAD(type, nr, size) \
    + _IOC(_IOC_READ, (type), (nr), sizeof(size))
    +#define _IOW_BAD(type, nr, size) \
    + _IOC(_IOC_WRITE, (type), (nr), sizeof(size))
    +#define _IOWR_BAD(type, nr, size) \
    + _IOC(_IOC_READ|_IOC_WRITE, (type), (nr), sizeof(size))
    +
    +/* used to decode them.. */
    +#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
    +#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
    +#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
    +#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
    +
    +/* various drivers, such as the pcmcia stuff, need these... */
    +#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
    +#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
    +#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
    +#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
    +#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
    +
    +#endif /* _MICROBLAZE_IOCTL_H */
    diff --git a/include/asm-microblaze/ioctls.h b/include/asm-microblaze/ioctls.h
    new file mode 100644
    index 0000000..2ea08e0
    --- /dev/null
    +++ b/include/asm-microblaze/ioctls.h
    @@ -0,0 +1,93 @@
    +/*
    + * include/asm-microblaze/ioctls.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_IOCTLS_H
    +#define _ASM_IOCTLS_H
    +
    +#include
    +
    +/* 0x54 is just a magic number to make these relatively unique ('T') */
    +
    +#define TCGETS 0x5401
    +#define TCSETS 0x5402
    +#define TCSETSW 0x5403
    +#define TCSETSF 0x5404
    +#define TCGETA 0x5405
    +#define TCSETA 0x5406
    +#define TCSETAW 0x5407
    +#define TCSETAF 0x5408
    +#define TCSBRK 0x5409
    +#define TCXONC 0x540A
    +#define TCFLSH 0x540B
    +#define TIOCEXCL 0x540C
    +#define TIOCNXCL 0x540D
    +#define TIOCSCTTY 0x540E
    +#define TIOCGPGRP 0x540F
    +#define TIOCSPGRP 0x5410
    +#define TIOCOUTQ 0x5411
    +#define TIOCSTI 0x5412
    +#define TIOCGWINSZ 0x5413
    +#define TIOCSWINSZ 0x5414
    +#define TIOCMGET 0x5415
    +#define TIOCMBIS 0x5416
    +#define TIOCMBIC 0x5417
    +#define TIOCMSET 0x5418
    +#define TIOCGSOFTCAR 0x5419
    +#define TIOCSSOFTCAR 0x541A
    +#define FIONREAD 0x541B
    +#define TIOCINQ FIONREAD
    +#define TIOCLINUX 0x541C
    +#define TIOCCONS 0x541D
    +#define TIOCGSERIAL 0x541E
    +#define TIOCSSERIAL 0x541F
    +#define TIOCPKT 0x5420
    +#define FIONBIO 0x5421
    +#define TIOCNOTTY 0x5422
    +#define TIOCSETD 0x5423
    +#define TIOCGETD 0x5424
    +#define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */
    +#define TIOCTTYGSTRUCT 0x5426 /* For debugging only */
    +#define TIOCSBRK 0x5427 /* BSD compatibility */
    +#define TIOCCBRK 0x5428 /* BSD compatibility */
    +#define TIOCGSID 0x5429 /* Return the session ID of FD */
    +/* Get Pty Number (of pty-mux device) */
    +#define TIOCGPTN _IOR('T', 0x30, unsigned int)
    +#define TIOCSPTLCK _IOW('T', 0x31, int) /* Lock/unlock Pty */
    +
    +#define FIONCLEX 0x5450 /* these numbers need to be adjusted. */
    +#define FIOCLEX 0x5451
    +#define FIOASYNC 0x5452
    +#define TIOCSERCONFIG 0x5453
    +#define TIOCSERGWILD 0x5454
    +#define TIOCSERSWILD 0x5455
    +#define TIOCGLCKTRMIOS 0x5456
    +#define TIOCSLCKTRMIOS 0x5457
    +#define TIOCSERGSTRUCT 0x5458 /* For debugging only */
    +#define TIOCSERGETLSR 0x5459 /* Get line status register */
    +#define TIOCSERGETMULTI 0x545A /* Get multiport config */
    +#define TIOCSERSETMULTI 0x545B /* Set multiport config */
    +
    +#define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */
    +#define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */
    +
    +#define FIOQSIZE 0x545E
    +
    +/* Used for packet mode */
    +#define TIOCPKT_DATA 0
    +#define TIOCPKT_FLUSHREAD 1
    +#define TIOCPKT_FLUSHWRITE 2
    +#define TIOCPKT_STOP 4
    +#define TIOCPKT_START 8
    +#define TIOCPKT_NOSTOP 16
    +#define TIOCPKT_DOSTOP 32
    +
    +#define TIOCSER_TEMT 0x01 /* Transmitter physically empty */
    +
    +#endif /* _ASM_IOCTLS_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. [PATCH 40/52] [microblaze] atomic.h bitops.h byteorder.h

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    include/asm-microblaze/atomic.h | 108 ++++++++++++++++++++++++++++++++++++
    include/asm-microblaze/bitops.h | 29 ++++++++++
    include/asm-microblaze/byteorder.h | 23 ++++++++
    3 files changed, 160 insertions(+), 0 deletions(-)
    create mode 100644 include/asm-microblaze/atomic.h
    create mode 100644 include/asm-microblaze/bitops.h
    create mode 100644 include/asm-microblaze/byteorder.h

    diff --git a/include/asm-microblaze/atomic.h b/include/asm-microblaze/atomic.h
    new file mode 100644
    index 0000000..f7be329
    --- /dev/null
    +++ b/include/asm-microblaze/atomic.h
    @@ -0,0 +1,108 @@
    +/*
    + * include/asm-microblaze/atomic.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_ATOMIC_H
    +#define _ASM_ATOMIC_H
    +
    +#include /* likely */
    +#include /* local_irq_XXX and friends */
    +
    +typedef struct { volatile int counter; } atomic_t;
    +
    +#define ATOMIC_INIT(i) { (i) }
    +#define atomic_read(v) ((v)->counter)
    +#define atomic_set(v, i) (((v)->counter) = (i))
    +
    +#define atomic_inc(v) (atomic_add_return(1, (v)))
    +#define atomic_dec(v) (atomic_sub_return(1, (v)))
    +
    +#define atomic_add(i, v) (atomic_add_return(i, (v)))
    +#define atomic_sub(i, v) (atomic_sub_return(i, (v)))
    +
    +#define atomic_inc_return(v) (atomic_add_return(1, (v)))
    +#define atomic_dec_return(v) (atomic_sub_return(1, (v)))
    +
    +#define atomic_inc_and_test(v) (atomic_add_return(1, (v)) == 0)
    +#define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
    +
    +#define atomic_inc_not_zero(v) (atomic_add_unless((v), 1, 0))
    +
    +#define atomic_sub_and_test(i, v) (atomic_sub_return((i), (v)) == 0)
    +
    +static inline int atomic_cmpxchg(atomic_t *v, int old, int new)
    +{
    + int ret;
    + unsigned long flags;
    +
    + local_irq_save(flags);
    + ret = v->counter;
    + if (likely(ret == old))
    + v->counter = new;
    + local_irq_restore(flags);
    +
    + return ret;
    +}
    +
    +static inline int atomic_add_unless(atomic_t *v, int a, int u)
    +{
    + int c, old;
    +
    + c = atomic_read(v);
    + while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c)
    + c = old;
    + return c != u;
    +}
    +
    +static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
    +{
    + unsigned long flags;
    +
    + local_irq_save(flags);
    + *addr &= ~mask;
    + local_irq_restore(flags);
    +}
    +
    +/**
    + * atomic_add_return - add and return
    + * @i: integer value to add
    + * @v: pointer of type atomic_t
    + *
    + * Atomically adds @i to @v and returns @i + @v
    + */
    +static __inline__ int atomic_add_return(int i, atomic_t *v)
    +{
    + unsigned long flags;
    + int val;
    +
    + local_irq_save(flags);
    + val = v->counter;
    + v->counter = val += i;
    + local_irq_restore(flags);
    +
    + return val;
    +}
    +
    +static inline int atomic_sub_return(int i, atomic_t *v)
    +{
    + return atomic_add_return(-i, v);
    +}
    +
    +#define atomic_add_negative(a, v) (atomic_add_return((a), (v)) < 0)
    +#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
    +
    +/* Atomic operations are already serializing */
    +#define smp_mb__before_atomic_dec() barrier()
    +#define smp_mb__after_atomic_dec() barrier()
    +#define smp_mb__before_atomic_inc() barrier()
    +#define smp_mb__after_atomic_inc() barrier()
    +
    +#include
    +
    +#endif /* _ASM_ATOMIC_H */
    diff --git a/include/asm-microblaze/bitops.h b/include/asm-microblaze/bitops.h
    new file mode 100644
    index 0000000..4078d90
    --- /dev/null
    +++ b/include/asm-microblaze/bitops.h
    @@ -0,0 +1,29 @@
    +/*
    + * include/asm-microblaze/auxvec.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _MICROBLAZE_BITOPS_H
    +#define _MICROBLAZE_BITOPS_H
    +
    +/*
    + * Copyright 1992, Linus Torvalds.
    + */
    +
    +#include
    +#include /* swab32 */
    +#include /* save_flags */
    +
    +/*
    + * clear_bit() doesn't provide any barrier for the compiler.
    + */
    +#define smp_mb__before_clear_bit() barrier()
    +#define smp_mb__after_clear_bit() barrier()
    +#include
    +
    +#endif /* _MICROBLAZE_BITOPS_H */
    diff --git a/include/asm-microblaze/byteorder.h b/include/asm-microblaze/byteorder.h
    new file mode 100644
    index 0000000..df9dbbe
    --- /dev/null
    +++ b/include/asm-microblaze/byteorder.h
    @@ -0,0 +1,23 @@
    +/*
    + * include/asm-microblaze/byteorder.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_BYTEORDER_H
    +#define _ASM_BYTEORDER_H
    +
    +#include
    +
    +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) || defined(__KERNEL__)
    +#define __BYTEORDER_HAS_U64__
    +#define __SWAB_64_THRU_32__
    +#endif
    +
    +#include
    +
    +#endif /* _ASM_BYTEORDER_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [PATCH 22/52] [microblaze] asm-offsets

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/kernel/asm-offsets.c | 118 ++++++++++++++++++++++++++++++++++
    1 files changed, 118 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/kernel/asm-offsets.c

    diff --git a/arch/microblaze/kernel/asm-offsets.c b/arch/microblaze/kernel/asm-offsets.c
    new file mode 100644
    index 0000000..f01aa3b
    --- /dev/null
    +++ b/arch/microblaze/kernel/asm-offsets.c
    @@ -0,0 +1,118 @@
    +/*
    + * arch/microblaze/kernel/asm-offset.c
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2007 PetaLogix
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#define DEFINE(sym, val) asm volatile("\n->" #sym " %0 " #val : : "i" (val))
    +#define BLANK() asm volatile("\n->" :
    +
    +int main(int argc, char *argv[])
    +{
    + /* struct pt_regs */
    + DEFINE(PT_SIZE, sizeof(struct pt_regs));
    + DEFINE(PT_MSR, offsetof(struct pt_regs, msr));
    + DEFINE(PT_EAR, offsetof(struct pt_regs, ear));
    + DEFINE(PT_ESR, offsetof(struct pt_regs, esr));
    + DEFINE(PT_FSR, offsetof(struct pt_regs, fsr));
    + DEFINE(PT_PC, offsetof(struct pt_regs, pc));
    + DEFINE(PT_R0, offsetof(struct pt_regs, r0));
    + DEFINE(PT_R1, offsetof(struct pt_regs, r1));
    + DEFINE(PT_R2, offsetof(struct pt_regs, r2));
    + DEFINE(PT_R3, offsetof(struct pt_regs, r3));
    + DEFINE(PT_R4, offsetof(struct pt_regs, r4));
    + DEFINE(PT_R5, offsetof(struct pt_regs, r5));
    + DEFINE(PT_R6, offsetof(struct pt_regs, r6));
    + DEFINE(PT_R7, offsetof(struct pt_regs, r7));
    + DEFINE(PT_R8, offsetof(struct pt_regs, r8));
    + DEFINE(PT_R9, offsetof(struct pt_regs, r9));
    + DEFINE(PT_R10, offsetof(struct pt_regs, r10));
    + DEFINE(PT_R11, offsetof(struct pt_regs, r11));
    + DEFINE(PT_R12, offsetof(struct pt_regs, r12));
    + DEFINE(PT_R13, offsetof(struct pt_regs, r13));
    + DEFINE(PT_R14, offsetof(struct pt_regs, r14));
    + DEFINE(PT_R15, offsetof(struct pt_regs, r15));
    + DEFINE(PT_R16, offsetof(struct pt_regs, r16));
    + DEFINE(PT_R17, offsetof(struct pt_regs, r17));
    + DEFINE(PT_R18, offsetof(struct pt_regs, r18));
    + DEFINE(PT_R19, offsetof(struct pt_regs, r19));
    + DEFINE(PT_R20, offsetof(struct pt_regs, r20));
    + DEFINE(PT_R21, offsetof(struct pt_regs, r21));
    + DEFINE(PT_R22, offsetof(struct pt_regs, r22));
    + DEFINE(PT_R23, offsetof(struct pt_regs, r23));
    + DEFINE(PT_R24, offsetof(struct pt_regs, r24));
    + DEFINE(PT_R25, offsetof(struct pt_regs, r25));
    + DEFINE(PT_R26, offsetof(struct pt_regs, r26));
    + DEFINE(PT_R27, offsetof(struct pt_regs, r27));
    + DEFINE(PT_R28, offsetof(struct pt_regs, r28));
    + DEFINE(PT_R29, offsetof(struct pt_regs, r29));
    + DEFINE(PT_R30, offsetof(struct pt_regs, r30));
    + DEFINE(PT_R31, offsetof(struct pt_regs, r31));
    + DEFINE(PT_MODE, offsetof(struct pt_regs, kernel_mode));
    + BLANK();
    +
    + /* Magic offsets for PTRACE PEEK/POKE etc */
    + DEFINE(PT_TEXT_ADDR, sizeof(struct pt_regs) + 1);
    + DEFINE(PT_TEXT_LEN, sizeof(struct pt_regs) + 2);
    + DEFINE(PT_DATA_ADDR, sizeof(struct pt_regs) + 3);
    + BLANK();
    +
    + /* struct task_struct */
    + DEFINE(TS_THREAD_INFO, offsetof(struct task_struct, stack));
    +
    + /* struct thread_info */
    + DEFINE(TI_TASK, offsetof(struct thread_info, task));
    + DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain));
    + DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
    + DEFINE(TI_STATUS, offsetof(struct thread_info, status));
    + DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
    + DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
    + DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit));
    + DEFINE(TI_RESTART_BLOCK, offsetof(struct thread_info, restart_block));
    + DEFINE(TI_CPU_CONTEXT, offsetof(struct thread_info, cpu_context));
    + BLANK();
    +
    + /* struct cpu_context */
    + DEFINE(CC_SP, offsetof(struct cpu_context, sp)); /* r1 */
    + DEFINE(CC_R2, offsetof(struct cpu_context, r2));
    + /* dedicated registers */
    + DEFINE(CC_R13, offsetof(struct cpu_context, r13));
    + DEFINE(CC_R14, offsetof(struct cpu_context, r14));
    + DEFINE(CC_R15, offsetof(struct cpu_context, r15));
    + DEFINE(CC_R16, offsetof(struct cpu_context, r16));
    + DEFINE(CC_R17, offsetof(struct cpu_context, r17));
    + DEFINE(CC_R18, offsetof(struct cpu_context, r18));
    + /* non-volatile registers */
    + DEFINE(CC_R19, offsetof(struct cpu_context, r19));
    + DEFINE(CC_R20, offsetof(struct cpu_context, r20));
    + DEFINE(CC_R21, offsetof(struct cpu_context, r21));
    + DEFINE(CC_R22, offsetof(struct cpu_context, r22));
    + DEFINE(CC_R23, offsetof(struct cpu_context, r23));
    + DEFINE(CC_R24, offsetof(struct cpu_context, r24));
    + DEFINE(CC_R25, offsetof(struct cpu_context, r25));
    + DEFINE(CC_R26, offsetof(struct cpu_context, r26));
    + DEFINE(CC_R27, offsetof(struct cpu_context, r27));
    + DEFINE(CC_R28, offsetof(struct cpu_context, r28));
    + DEFINE(CC_R29, offsetof(struct cpu_context, r29));
    + DEFINE(CC_R30, offsetof(struct cpu_context, r30));
    + /* special purpose registers */
    + DEFINE(CC_MSR, offsetof(struct cpu_context, msr));
    + DEFINE(CC_EAR, offsetof(struct cpu_context, ear));
    + DEFINE(CC_ESR, offsetof(struct cpu_context, esr));
    + DEFINE(CC_FSR, offsetof(struct cpu_context, fsr));
    + BLANK();
    +
    + return 0;
    +}
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. [PATCH 12/52] [microblaze] lmb support

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/mm/lmb.c | 342 ++++++++++++++++++++++++++++++++++++++++++
    include/asm-microblaze/lmb.h | 84 ++++++++++
    2 files changed, 426 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/mm/lmb.c
    create mode 100644 include/asm-microblaze/lmb.h

    diff --git a/arch/microblaze/mm/lmb.c b/arch/microblaze/mm/lmb.c
    new file mode 100644
    index 0000000..993ea49
    --- /dev/null
    +++ b/arch/microblaze/mm/lmb.c
    @@ -0,0 +1,342 @@
    +/*
    + * Procedures for maintaining information about logical memory blocks.
    + *
    + * Peter Bergner, IBM Corp. June 2001.
    + * Copyright (C) 2001 Peter Bergner.
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version
    + * 2 of the License, or (at your option) any later version.
    + */
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#ifdef CONFIG_PPC32
    +#include "mmu_decl.h" /* for __max_low_memory */
    +#endif
    +
    +#define DEBUG
    +
    +#ifdef DEBUG
    +#define DBG(fmt...) printk(fmt)
    +#else
    +#define DBG(fmt...)
    +#endif
    +
    +#define LMB_ALLOC_ANYWHERE 0
    +
    +struct lmb lmb;
    +
    +void lmb_dump_all(void)
    +{
    +#ifdef DEBUG
    + unsigned int i;
    +
    + DBG("lmb_dump_all:\n");
    + DBG(" memory.cnt = 0x%lx\n", lmb.memory.cnt);
    + DBG(" memory.size = 0x%lx\n", lmb.memory.size);
    + for (i = 0; i < lmb.memory.cnt ; i++) {
    + DBG(" memory.region[0x%x].base = 0x%lx\n",
    + i, lmb.memory.region[i].base);
    + DBG(" .size = 0x%lx\n",
    + lmb.memory.region[i].size);
    + }
    +
    + DBG("\n reserved.cnt = 0x%lx\n", lmb.reserved.cnt);
    + DBG(" reserved.size = 0x%lx\n", lmb.reserved.size);
    + for (i = 0; i < lmb.reserved.cnt ; i++) {
    + DBG(" reserved.region[0x%x].base = 0x%lx\n",
    + i, lmb.reserved.region[i].base);
    + DBG(" .size = 0x%lx\n",
    + lmb.reserved.region[i].size);
    + }
    +#endif /* DEBUG */
    +}
    +
    +static unsigned long __init lmb_addrs_overlap(unsigned long base1,
    + unsigned long size1, unsigned long base2, unsigned long size2)
    +{
    + return ((base1 < (base2+size2)) && (base2 < (base1+size1)));
    +}
    +
    +static long __init lmb_addrs_adjacent(unsigned long base1, unsigned long size1,
    + unsigned long base2, unsigned long size2)
    +{
    + if (base2 == base1 + size1)
    + return 1;
    + else if (base1 == base2 + size2)
    + return -1;
    +
    + return 0;
    +}
    +
    +static long __init lmb_regions_adjacent(struct lmb_region *rgn,
    + unsigned long r1, unsigned long r2)
    +{
    + unsigned long base1 = rgn->region[r1].base;
    + unsigned long size1 = rgn->region[r1].size;
    + unsigned long base2 = rgn->region[r2].base;
    + unsigned long size2 = rgn->region[r2].size;
    +
    + return lmb_addrs_adjacent(base1, size1, base2, size2);
    +}
    +
    +static void __init lmb_remove_region(struct lmb_region *rgn, unsigned long r)
    +{
    + unsigned long i;
    +
    + for (i = r; i < rgn->cnt - 1; i++) {
    + rgn->region[i].base = rgn->region[i + 1].base;
    + rgn->region[i].size = rgn->region[i + 1].size;
    + }
    + rgn->cnt--;
    +}
    +
    +/* Assumption: base addr of region 1 < base addr of region 2 */
    +static void __init lmb_coalesce_regions(struct lmb_region *rgn,
    + unsigned long r1, unsigned long r2)
    +{
    + rgn->region[r1].size += rgn->region[r2].size;
    + lmb_remove_region(rgn, r2);
    +}
    +
    +/* This routine called with relocation disabled. */
    +void __init lmb_init(void)
    +{
    + /* Create a dummy zero size LMB which will get coalesced away later.
    + * This simplifies the lmb_add() code below...
    + */
    + lmb.memory.region[0].base = 0;
    + lmb.memory.region[0].size = 0;
    + lmb.memory.cnt = 1;
    +
    + /* Ditto. */
    + lmb.reserved.region[0].base = 0;
    + lmb.reserved.region[0].size = 0;
    + lmb.reserved.cnt = 1;
    +}
    +
    +/* This routine may be called with relocation disabled. */
    +void __init lmb_analyze(void)
    +{
    + int i;
    +
    + lmb.memory.size = 0;
    +
    + for (i = 0; i < lmb.memory.cnt; i++)
    + lmb.memory.size += lmb.memory.region[i].size;
    +}
    +
    +/* This routine called with relocation disabled. */
    +static long __init lmb_add_region(struct lmb_region *rgn, unsigned long base,
    + unsigned long size)
    +{
    + unsigned long i, coalesced = 0;
    + long adjacent;
    +
    + /* First try and coalesce this LMB with another. */
    + for (i = 0; i < rgn->cnt; i++) {
    + unsigned long rgnbase = rgn->region[i].base;
    + unsigned long rgnsize = rgn->region[i].size;
    +
    + if ((rgnbase == base) && (rgnsize == size))
    + /* Already have this region, so we're done */
    + return 0;
    +
    + adjacent = lmb_addrs_adjacent(base, size, rgnbase, rgnsize);
    + if (adjacent > 0) {
    + rgn->region[i].base -= size;
    + rgn->region[i].size += size;
    + coalesced++;
    + break;
    + } else if (adjacent < 0) {
    + rgn->region[i].size += size;
    + coalesced++;
    + break;
    + }
    + }
    +
    + if ((i < rgn->cnt-1) && lmb_regions_adjacent(rgn, i, i + 1)) {
    + lmb_coalesce_regions(rgn, i, i+1);
    + coalesced++;
    + }
    +
    + if (coalesced)
    + return coalesced;
    + if (rgn->cnt >= MAX_LMB_REGIONS)
    + return -1;
    +
    + /* Couldn't coalesce the LMB, so add it to the sorted table. */
    + for (i = rgn->cnt-1; i >= 0; i--) {
    + if (base < rgn->region[i].base) {
    + rgn->region[i+1].base = rgn->region[i].base;
    + rgn->region[i+1].size = rgn->region[i].size;
    + } else {
    + rgn->region[i+1].base = base;
    + rgn->region[i+1].size = size;
    + break;
    + }
    + }
    + rgn->cnt++;
    +
    + return 0;
    +}
    +
    +/* This routine may be called with relocation disabled. */
    +long __init lmb_add(unsigned long base, unsigned long size)
    +{
    + struct lmb_region *_rgn = &(lmb.memory);
    +
    + /* On pSeries LPAR systems, the first LMB is our RMO region. */
    + if (base == 0)
    + lmb.rmo_size = size;
    +
    + return lmb_add_region(_rgn, base, size);
    +
    +}
    +
    +long __init lmb_reserve(unsigned long base, unsigned long size)
    +{
    + struct lmb_region *_rgn = &(lmb.reserved);
    +
    + BUG_ON(0 == size);
    +
    + return lmb_add_region(_rgn, base, size);
    +}
    +
    +long __init lmb_overlaps_region(struct lmb_region *rgn, unsigned long base,
    + unsigned long size)
    +{
    + unsigned long i;
    +
    + for (i = 0; i < rgn->cnt; i++) {
    + unsigned long rgnbase = rgn->region[i].base;
    + unsigned long rgnsize = rgn->region[i].size;
    + if (lmb_addrs_overlap(base, size, rgnbase, rgnsize))
    + break;
    + }
    +
    + return (i < rgn->cnt) ? i : -1;
    +}
    +
    +unsigned long __init lmb_alloc(unsigned long size, unsigned long align)
    +{
    + return lmb_alloc_base(size, align, LMB_ALLOC_ANYWHERE);
    +}
    +
    +unsigned long __init lmb_alloc_base(unsigned long size, unsigned long align,
    + unsigned long max_addr)
    +{
    + unsigned long alloc;
    +
    + alloc = __lmb_alloc_base(size, align, max_addr);
    +
    + if (alloc == 0)
    + panic("ERROR: Failed to allocate 0x%lx bytes below 0x%lx.\n",
    + size, max_addr);
    +
    + return alloc;
    +}
    +
    +unsigned long __init __lmb_alloc_base(unsigned long size, unsigned long align,
    + unsigned long max_addr)
    +{
    + long i, j;
    + unsigned long base = 0;
    +
    + BUG_ON(0 == size);
    +
    +#ifdef CONFIG_PPC32
    + /* On 32-bit, make sure we allocate lowmem */
    + if (max_addr == LMB_ALLOC_ANYWHERE)
    + max_addr = __max_low_memory;
    +#endif
    + for (i = lmb.memory.cnt-1; i >= 0; i--) {
    + unsigned long lmbbase = lmb.memory.region[i].base;
    + unsigned long lmbsize = lmb.memory.region[i].size;
    +
    + if (max_addr == LMB_ALLOC_ANYWHERE)
    + base = _ALIGN_DOWN(lmbbase + lmbsize - size, align);
    + else if (lmbbase < max_addr) {
    + base = min(lmbbase + lmbsize, max_addr);
    + base = _ALIGN_DOWN(base - size, align);
    + } else
    + continue;
    +
    + while ((lmbbase <= base) &&
    + ((j = lmb_overlaps_region(&lmb.reserved, base, size))
    + >= 0))
    + base = _ALIGN_DOWN(lmb.reserved.region[j].base - size,
    + align);
    +
    + if ((base != 0) && (lmbbase <= base))
    + break;
    + }
    +
    + if (i < 0)
    + return 0;
    +
    + lmb_add_region(&lmb.reserved, base, size);
    +
    + return base;
    +}
    +
    +/* You must call lmb_analyze() before this. */
    +unsigned long __init lmb_phys_mem_size(void)
    +{
    + return lmb.memory.size;
    +}
    +
    +unsigned long __init lmb_end_of_DRAM(void)
    +{
    + int idx = lmb.memory.cnt - 1;
    +
    + return (lmb.memory.region[idx].base + lmb.memory.region[idx].size);
    +}
    +
    +/* You must call lmb_analyze() after this. */
    +void __init lmb_enforce_memory_limit(unsigned long memory_limit)
    +{
    + unsigned long i, limit;
    + struct lmb_property *p;
    +
    + if (!memory_limit)
    + return;
    +
    + /* Truncate the lmb regions to satisfy the memory limit. */
    + limit = memory_limit;
    + for (i = 0; i < lmb.memory.cnt; i++) {
    + if (limit > lmb.memory.region[i].size) {
    + limit -= lmb.memory.region[i].size;
    + continue;
    + }
    +
    + lmb.memory.region[i].size = limit;
    + lmb.memory.cnt = i + 1;
    + break;
    + }
    +
    + if (lmb.memory.region[0].size < lmb.rmo_size)
    + lmb.rmo_size = lmb.memory.region[0].size;
    +
    + /* And truncate any reserves above the limit also. */
    + for (i = 0; i < lmb.reserved.cnt; i++) {
    + p = &lmb.reserved.region[i];
    +
    + if (p->base > memory_limit)
    + p->size = 0;
    + else if ((p->base + p->size) > memory_limit)
    + p->size = memory_limit - p->base;
    +
    + if (p->size == 0) {
    + lmb_remove_region(&lmb.reserved, i);
    + i--;
    + }
    + }
    +}
    diff --git a/include/asm-microblaze/lmb.h b/include/asm-microblaze/lmb.h
    new file mode 100644
    index 0000000..f27bb13
    --- /dev/null
    +++ b/include/asm-microblaze/lmb.h
    @@ -0,0 +1,84 @@
    +/*
    + * include/asm-microblaze/lmb.h
    + *
    + * Definitions for talking to the Open Firmware PROM on
    + * Power Macintosh computers.
    + *
    + * Copyright (C) 2001 Peter Bergner, IBM Corp.
    + *
    + * This program is free software; you can redistribute it and/or
    + * modify it under the terms of the GNU General Public License
    + * as published by the Free Software Foundation; either version
    + * 2 of the License, or (at your option) any later version.
    + */
    +
    +#ifndef _ASM_LMB_H
    +#define _ASM_LMB_H
    +#ifdef __KERNEL__
    +
    +#include
    +#include
    +
    +#define MAX_LMB_REGIONS 128
    +
    +struct lmb_property {
    + unsigned long base;
    + unsigned long size;
    +};
    +
    +struct lmb_region {
    + unsigned long cnt;
    + unsigned long size;
    + struct lmb_property region[MAX_LMB_REGIONS+1];
    +};
    +
    +struct lmb {
    + unsigned long debug;
    + unsigned long rmo_size;
    + struct lmb_region memory;
    + struct lmb_region reserved;
    +};
    +
    +extern struct lmb lmb;
    +
    +extern void __init lmb_init(void);
    +extern void __init lmb_analyze(void);
    +extern long __init lmb_add(unsigned long base, unsigned long size);
    +extern long __init lmb_reserve(unsigned long base, unsigned long size);
    +extern unsigned long __init lmb_alloc(unsigned long size, unsigned long align);
    +extern unsigned long __init lmb_alloc_base(unsigned long size,
    + unsigned long align, unsigned long max_addr);
    +extern unsigned long __init __lmb_alloc_base(unsigned long size,
    + unsigned long align, unsigned long max_addr);
    +extern unsigned long __init lmb_phys_mem_size(void);
    +extern unsigned long __init lmb_end_of_DRAM(void);
    +extern void __init lmb_enforce_memory_limit(unsigned long memory_limit);
    +extern long __init lmb_overlaps_region(struct lmb_region *rgn,
    + unsigned long base, unsigned long size);
    +
    +extern void lmb_dump_all(void);
    +
    +static inline unsigned long
    +lmb_size_bytes(struct lmb_region *type, unsigned long region_nr)
    +{
    + return type->region[region_nr].size;
    +}
    +static inline unsigned long
    +lmb_size_pages(struct lmb_region *type, unsigned long region_nr)
    +{
    + return lmb_size_bytes(type, region_nr) >> PAGE_SHIFT;
    +}
    +static inline unsigned long
    +lmb_start_pfn(struct lmb_region *type, unsigned long region_nr)
    +{
    + return type->region[region_nr].base >> PAGE_SHIFT;
    +}
    +static inline unsigned long
    +lmb_end_pfn(struct lmb_region *type, unsigned long region_nr)
    +{
    + return lmb_start_pfn(type, region_nr) +
    + lmb_size_pages(type, region_nr);
    +}
    +
    +#endif /* __KERNEL__ */
    +#endif /* _ASM_LMB_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [PATCH 31/52] [microblaze] pci header files

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    include/asm-microblaze/pci-bridge.h | 146 +++++++++++++++++++++++++++++++++++
    include/asm-microblaze/pci.h | 139 +++++++++++++++++++++++++++++++++
    2 files changed, 285 insertions(+), 0 deletions(-)
    create mode 100644 include/asm-microblaze/pci-bridge.h
    create mode 100644 include/asm-microblaze/pci.h

    diff --git a/include/asm-microblaze/pci-bridge.h b/include/asm-microblaze/pci-bridge.h
    new file mode 100644
    index 0000000..49d5dc4
    --- /dev/null
    +++ b/include/asm-microblaze/pci-bridge.h
    @@ -0,0 +1,146 @@
    +/*
    + * include/asm-microblaze/pci-bridge.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_PCI_BRIDGE_H
    +#define _ASM_PCI_BRIDGE_H
    +#ifdef __KERNEL__
    +
    +#include
    +#include
    +
    +struct device_node;
    +struct pci_controller;
    +
    +/*
    + * pci_io_base returns the memory address at which you can access
    + * the I/O space for PCI bus number `bus' (or NULL on error).
    + */
    +extern void __iomem *pci_bus_io_base(unsigned int bus);
    +extern unsigned long pci_bus_io_base_phys(unsigned int bus);
    +extern unsigned long pci_bus_mem_base_phys(unsigned int bus);
    +
    +/* Allocate a new PCI host bridge structure */
    +extern struct pci_controller *pcibios_alloc_controller(void);
    +
    +/* Helper function for setting up resources */
    +extern void pci_init_resource(struct resource *res, unsigned long start,
    + unsigned long end, int flags, char *name);
    +
    +/* Get the PCI host controller for a bus */
    +extern struct pci_controller *pci_bus_to_hose(int bus);
    +
    +/* Get the PCI host controller for an OF device */
    +extern struct pci_controller
    +*pci_find_hose_for_OF_device(struct device_node *node);
    +
    +/* Fill up host controller resources from the OF node */
    +extern void
    +pci_process_bridge_OF_ranges(struct pci_controller *hose,
    + struct device_node *dev, int primary);
    +
    +/*
    + * Structure of a PCI controller (host bridge)
    + */
    +struct pci_controller {
    + int index; /* PCI domain number */
    + struct pci_controller *next;
    + struct pci_bus *bus;
    + void *arch_data;
    +
    + int first_busno;
    + int last_busno;
    + int bus_offset;
    +
    + void __iomem *io_base_virt;
    + unsigned long io_base_phys;
    +
    + /* Some machines (PReP) have a non 1:1 mapping of
    + * the PCI memory space in the CPU bus space
    + */
    + unsigned long pci_mem_offset;
    +
    + struct pci_ops *ops;
    + volatile unsigned int __iomem *cfg_addr;
    + volatile void __iomem *cfg_data;
    + /*
    + * If set, indirect method will set the cfg_type bit as
    + * needed to generate type 1 configuration transactions.
    + */
    + int set_cfg_type;
    +
    + /* Currently, we limit ourselves to 1 IO range and 3 mem
    + * ranges since the common pci_bus structure can't handle more
    + */
    + struct resource io_resource;
    + struct resource mem_resources[3];
    + int mem_resource_count;
    +
    + /* Host bridge I/O and Memory space
    + * Used for BAR placement algorithms
    + */
    + struct resource io_space;
    + struct resource mem_space;
    +};
    +
    +/* These are used for config access before all the PCI probing
    + has been done. */
    +int early_read_config_byte(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u8 *val);
    +int early_read_config_word(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u16 *val);
    +int early_read_config_dword(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u32 *val);
    +int early_write_config_byte(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u8 val);
    +int early_write_config_word(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u16 val);
    +int early_write_config_dword(struct pci_controller *hose, int bus, int dev_fn,
    + int where, u32 val);
    +
    +extern void setup_indirect_pci_nomap(struct pci_controller *hose,
    + void __iomem *cfg_addr, void __iomem *cfg_data);
    +extern void setup_indirect_pci(struct pci_controller *hose,
    + u32 cfg_addr, u32 cfg_data);
    +extern void setup_grackle(struct pci_controller *hose);
    +
    +extern unsigned char common_swizzle(struct pci_dev *, unsigned char *);
    +
    +/*
    + * The following code swizzles for exactly one bridge. The routine
    + * common_swizzle below handles multiple bridges. But there are a
    + * some boards that don't follow the PCI spec's suggestion so we
    + * break this piece out separately.
    + */
    +static inline unsigned char bridge_swizzle(unsigned char pin,
    + unsigned char idsel)
    +{
    + return (((pin-1) + idsel) % 4) + 1;
    +}
    +
    +/*
    + * The following macro is used to lookup irqs in a standard table
    + * format for those PPC systems that do not already have PCI
    + * interrupts properly routed.
    + */
    +/* FIXME - double check this */
    +#define PCI_IRQ_TABLE_LOOKUP \
    +({ long _ctl_ = -1; \
    + if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \
    + _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \
    + _ctl_; })
    +
    +/*
    + * Scan the buses below a given PCI host bridge and assign suitable
    + * resources to all devices found.
    + */
    +extern int pciauto_bus_scan(struct pci_controller *, int);
    +
    +#endif /* __KERNEL__ */
    +#endif /* _ASM_PCI_BRIDGE_H */
    diff --git a/include/asm-microblaze/pci.h b/include/asm-microblaze/pci.h
    new file mode 100644
    index 0000000..c7dac52
    --- /dev/null
    +++ b/include/asm-microblaze/pci.h
    @@ -0,0 +1,139 @@
    +/*
    + * include/asm-microblaze/pci.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _MICROBLAZE_PCI_H
    +#define _MICROBLAZE_PCI_H
    +#ifdef __KERNEL__
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +struct pci_dev;
    +
    +/* Values for the `which' argument to sys_pciconfig_iobase syscall. */
    +#define IOBASE_BRIDGE_NUMBER 0
    +#define IOBASE_MEMORY 1
    +#define IOBASE_IO 2
    +#define IOBASE_ISA_IO 3
    +#define IOBASE_ISA_MEM 4
    +
    +/*
    + * Set this to 1 if you want the kernel to re-assign all PCI
    + * bus numbers
    + */
    +extern int pci_assign_all_busses;
    +
    +#define pcibios_assign_all_busses() (pci_assign_all_busses)
    +#define pcibios_scan_all_fns(a, b) 0
    +
    +#define PCIBIOS_MIN_IO 0x1000
    +#define PCIBIOS_MIN_MEM 0x10000000
    +
    +extern inline void pcibios_set_master(struct pci_dev *dev)
    +{
    + /* No special bus mastering setup handling */
    +}
    +
    +extern inline void pcibios_penalize_isa_irq(int irq, int active)
    +{
    + /* We don't do dynamic PCI IRQ allocation */
    +}
    +
    +extern unsigned long pci_resource_to_bus(struct pci_dev *pdev,
    + struct resource *res);
    +
    +/*
    + * The PCI bus bridge can translate addresses issued by the processor(s)
    + * into a different address on the PCI bus. On 32-bit cpus, we assume
    + * this mapping is 1-1, but on 64-bit systems it often isn't.
    + *
    + * Obsolete ! Drivers should now use pci_resource_to_bus
    + */
    +extern unsigned long phys_to_bus(unsigned long pa);
    +extern unsigned long pci_phys_to_bus(unsigned long pa, int busnr);
    +extern unsigned long pci_bus_to_phys(unsigned int ba, int busnr);
    +
    +/* The PCI address space does equal the physical memory
    + * address space. The networking and block device layers use
    + * this boolean for bounce buffer decisions.
    + */
    +#define PCI_DMA_BUS_IS_PHYS (1)
    +
    +/* pci_unmap_{page,single} is a nop so... */
    +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME)
    +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME)
    +#define pci_unmap_addr(PTR, ADDR_NAME) (0)
    +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) do { } while (0)
    +#define pci_unmap_len(PTR, LEN_NAME) (0)
    +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) do { } while (0)
    +
    +#ifdef CONFIG_PCI
    +static inline void pci_dma_burst_advice(struct pci_dev *pdev,
    + enum pci_dma_burst_strategy *strat,
    + unsigned long *strategy_parameter)
    +{
    + *strat = PCI_DMA_BURST_INFINITY;
    + *strategy_parameter = ~0UL;
    +}
    +#endif
    +
    +/*
    + * At present there are very few 32-bit PPC machines that can have
    + * memory above the 4GB point, and we don't support that.
    + */
    +#define pci_dac_dma_supported(pci_dev, mask) (0)
    +
    +/* Return the index of the PCI controller for device PDEV. */
    +#define pci_domain_nr(bus) ((struct pci_controller *)(bus)->sysdata)->index
    +
    +/* Set the name of the bus as it appears in /proc/bus/pci */
    +static inline int pci_proc_domain(struct pci_bus *bus)
    +{
    + return 0;
    +}
    +
    +/* Map a range of PCI memory or I/O space for a device into user space */
    +int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma,
    + enum pci_mmap_state mmap_state, int write_combine);
    +
    +/* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */
    +#define HAVE_PCI_MMAP 1
    +
    +extern void
    +pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region,
    + struct resource *res);
    +
    +extern void
    +pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res,
    + struct pci_bus_region *region);
    +
    +/* extern void pcibios_add_platform_entries(struct pci_dev *dev); */
    +
    +struct file;
    +extern pgprot_t pci_phys_mem_access_prot(struct file *file,
    + unsigned long offset,
    + unsigned long size,
    + pgprot_t prot);
    +
    +#define HAVE_ARCH_PCI_RESOURCE_TO_USER
    +extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
    + const struct resource *rsrc,
    + u64 *start, u64 *end);
    +
    +
    +#endif /* __KERNEL__ */
    +
    +#endif /* _MICROBLAZE_PCI_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [PATCH 16/52] [microblaze] supported function for memory - kernel/lib

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/lib/memcpy.c | 159 +++++++++++++++++++++++++++++++++++++
    arch/microblaze/lib/memmove.c | 174 +++++++++++++++++++++++++++++++++++++++++
    arch/microblaze/lib/memset.c | 83 +++++++++++++++++++
    3 files changed, 416 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/lib/memcpy.c
    create mode 100644 arch/microblaze/lib/memmove.c
    create mode 100644 arch/microblaze/lib/memset.c

    diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
    new file mode 100644
    index 0000000..cc13ebd
    --- /dev/null
    +++ b/arch/microblaze/lib/memcpy.c
    @@ -0,0 +1,159 @@
    +/* Filename: memcpy.c
    + *
    + * Reasonably optimised generic C-code for memcpy on Microblaze
    + * This is generic C code to do efficient, alignment-aware memcpy.
    + *
    + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
    + * http://www.embedded.com/showArticle....cleID=19205567
    + *
    + * Attempts were made, unsuccesfully, to contact the original
    + * author of this code (Michael Morrow, Intel). Below is the original
    + * copyright notice.
    + *
    + * This software has been developed by Intel Corporation.
    + * Intel specifically disclaims all warranties, express or
    + * implied, and all liability, including consequential and
    + * other indirect damages, for the use of this program, including
    + * liability for infringement of any proprietary rights,
    + * and including the warranties of merchantability and fitness
    + * for a particular purpose. Intel does not assume any
    + * responsibility for and errors which may appear in this program
    + * not any responsibility to update it.
    + */
    +
    +#include
    +#include
    +#include
    +
    +#include
    +#include
    +
    +/* Macro's for bytebliting unaligned data blocks */
    +
    +/* Big-endian MACROS */
    +
    +#define BYTE_BLIT_INIT(s, h, o) \
    + (h) = *((unsigned *)(s))++ << (o)
    +
    +#define BYTE_BLIT_STEP(d, s, h, o) \
    + { register unsigned _v_; _v_ = *((unsigned *)(s))++; \
    + *((unsigned *)(d))++ = (h) | _v_ >> (32-(o)); \
    + (h) = _v_ << (o); \
    + }
    +
    +void *memcpy(void *d, const void *s, __kernel_size_t c)
    +{
    +#if 1
    + /* This code was put into place as we transitioned from gcc3 to gcc4.
    + * gcc4 does not support the syntax *((char *)d)++ which causes the
    + * original code below to break. Short of fixing up the original code,
    + * a simpler byte oriented code was put into place.
    + */
    + /* Simple, byte oriented memcpy. */
    + const char *src = s;
    + char *dst = d;
    +
    + while (c--) *dst++ = *src++;
    +
    + return d;
    +
    +#else
    + /* The following code tries to optimize the copy by using unsigned
    + * alignment. This will work fine if both source and destination are
    + * aligned on the same boundary. However, if they are aligned on
    + * different boundaries shifts will be necessary. This might result in
    + * bad performance on MicroBlaze systems without a barrel shifter.
    + */
    + void *r = d;
    +
    + if (c >= 4) {
    + unsigned x, a, h, align;
    +
    + /* Align the destination to a word boundry. */
    + /* This is done in an endian independant manner. */
    + switch ((unsigned) d & 3) {
    + case 1:
    + *((char *) d)++ = *((char *) s)++;
    + c--;
    + case 2:
    + *((char *) d)++ = *((char *) s)++;
    + c--;
    + case 3:
    + *((char *) d)++ = *((char *) s)++;
    + c--;
    + }
    + /* Choose a copy scheme based on the source */
    + /* alignment relative to destination. */
    + switch ((unsigned) s & 3) {
    + case 0x0: /* Both byte offsets are aligned */
    +
    + for (; c >= 4; c -= 4)
    + *((unsigned *) d)++ = *((unsigned *) s)++;
    +
    + break;
    +
    + case 0x1: /* Unaligned - Off by 1 */
    + /* Word align the source */
    + a = (unsigned) s & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 8);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 8);
    +
    + /* Realign the source */
    + (unsigned) s = a - 3;
    + break;
    +
    + case 0x2: /* Unaligned - Off by 2 */
    + /* Word align the source */
    + a = (unsigned) s & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 16);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 16);
    +
    + /* Realign the source */
    + (unsigned) s = a - 2;
    + break;
    +
    + case 0x3: /* Unaligned - Off by 3 */
    + /* Word align the source */
    + a = (unsigned) s & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 24);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 24);
    +
    + /* Realign the source */
    + (unsigned) s = a - 1;
    + break;
    + }
    +
    + }
    +
    + /* Finish off any remaining bytes */
    + /* simple fast copy, ... unless a cache boundry is crossed */
    + switch (c) {
    + case 3:
    + *((char *) d)++ = *((char *) s)++;
    + case 2:
    + *((char *) d)++ = *((char *) s)++;
    + case 1:
    + *((char *) d)++ = *((char *) s)++;
    + }
    +
    + return r;
    +#endif
    +}
    +
    +
    +void *cacheable_memcpy(void *d, const void *s, __kernel_size_t c)
    +{
    + return memcpy(d, s, c);
    +}
    diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c
    new file mode 100644
    index 0000000..e9f8f04
    --- /dev/null
    +++ b/arch/microblaze/lib/memmove.c
    @@ -0,0 +1,174 @@
    +/* Filename: memmove.c
    + *
    + * Reasonably optimised generic C-code for memcpy on Microblaze
    + * This is generic C code to do efficient, alignment-aware memmove.
    + *
    + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
    + * http://www.embedded.com/showArticle....cleID=19205567
    + *
    + * Attempts were made, unsuccesfully, to contact the original
    + * author of this code (Michael Morrow, Intel). Below is the original
    + * copyright notice.
    + *
    + * This software has been developed by Intel Corporation.
    + * Intel specifically disclaims all warranties, express or
    + * implied, and all liability, including consequential and
    + * other indirect damages, for the use of this program, including
    + * liability for infringement of any proprietary rights,
    + * and including the warranties of merchantability and fitness
    + * for a particular purpose. Intel does not assume any
    + * responsibility for and errors which may appear in this program
    + * not any responsibility to update it.
    + */
    +
    +#include
    +#include
    +#include
    +
    +#include
    +
    +/* Macro's for bytebliting unaligned data blocks */
    +
    +/* Big-endian MACROS */
    +
    +#define BYTE_BLIT_INIT(s, h, o) \
    + (h) = *(--(unsigned *)(s)) >> (32-(o))
    +
    +#define BYTE_BLIT_STEP(d, s, h, o) \
    + { register unsigned _v_; _v_ = *(--(unsigned *)(s)); \
    + *(--(unsigned *)(d)) = _v_ << (o) | (h); \
    + (h) = _v_ >> (32-(o)); \
    + }
    +
    +void *memmove(void *d, const void *s, __kernel_size_t c)
    +{
    +#if 1
    + /* This code was put into place as we transitioned from gcc3 to gcc4.
    + * gcc4 does not support the syntax *((char *)d)++ which causes the
    + * original code below to break. Short of fixing up the original code,
    + * a simpler byte oriented code was put into place.
    + */
    + /* Simple, byte oriented memmove. */
    + if (d <= s) {
    + return memcpy(d, s, c);
    + } else {
    + const char *src = s;
    + char *dst = d;
    +
    + /* copy backwards, from end to beginning */
    + src += c;
    + dst += c;
    +
    + while (c--) *--dst = *--src;
    +
    + return d;
    + }
    +
    +#else
    + /* The following code tries to optimize the copy by using unsigned
    + * alignment. This will work fine if both source and destination are
    + * aligned on the same boundary. However, if they are aligned on
    + * different boundaries shifts will be necessary. This might result in
    + * bad performance on MicroBlaze systems without a barrel shifter.
    + */
    + void *r = d;
    +
    + /* Use memcpy when source is higher than dest */
    + if (d <= s)
    + return memcpy(d, s, c);
    +
    + /* Do a descending copy - this is a bit trickier! */
    + d += c;
    + s += c;
    +
    + if (c >= 4) {
    + unsigned x, a, h, align;
    +
    + /* Align the destination to a word boundry. */
    + /* This is done in an endian independant manner. */
    + switch ((unsigned) d & 3) {
    + case 3:
    + *(--(char *) d) = *(--(char *) s);
    + c--;
    + case 2:
    + *(--(char *) d) = *(--(char *) s);
    + c--;
    + case 1:
    + *(--(char *) d) = *(--(char *) s);
    + c--;
    + }
    + /* Choose a copy scheme based on the source */
    + /* alignment relative to destination. */
    + switch ((unsigned) s & 3) {
    + case 0x0: /* Both byte offsets are aligned */
    +
    + for (; c >= 4; c -= 4)
    + *(--(unsigned *) d) = *(--(unsigned *) s);
    +
    + break;
    +
    + case 0x1: /* Unaligned - Off by 1 */
    + /* Word align the source */
    + a = (unsigned) (s + 4) & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 8);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 8);
    +
    + /* Realign the source */
    + (unsigned) s = a + 1;
    + break;
    +
    + case 0x2: /* Unaligned - Off by 2 */
    + /* Word align the source */
    + a = (unsigned) (s + 4) & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 16);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 16);
    +
    + /* Realign the source */
    + (unsigned) s = a + 2;
    + break;
    +
    + case 0x3: /* Unaligned - Off by 3 */
    + /* Word align the source */
    + a = (unsigned) (s + 4) & ~3;
    +
    + /* Load the holding buffer */
    + BYTE_BLIT_INIT(a, h, 24);
    +
    + for (; c >= 4; c -= 4)
    + BYTE_BLIT_STEP(d, a, h, 24);
    +
    + /* Realign the source */
    + (unsigned) s = a + 3;
    + break;
    + }
    +
    +#if 0
    + /* Finish off any remaining bytes */
    + c &= 3;
    + goto finish;
    +#endif
    +
    + }
    +
    + /* simple fast copy, ... unless a cache boundry is crossed */
    + switch (c) {
    + case 4:
    + *(--(char *) d) = *(--(char *) s);
    + case 3:
    + *(--(char *) d) = *(--(char *) s);
    + case 2:
    + *(--(char *) d) = *(--(char *) s);
    + case 1:
    + *(--(char *) d) = *(--(char *) s);
    + }
    + return r;
    +#endif
    +}
    diff --git a/arch/microblaze/lib/memset.c b/arch/microblaze/lib/memset.c
    new file mode 100644
    index 0000000..5d3d83e
    --- /dev/null
    +++ b/arch/microblaze/lib/memset.c
    @@ -0,0 +1,83 @@
    +/* Filename: memset.c
    + *
    + * Reasonably optimised generic C-code for memset on Microblaze
    + * This is generic C code to do efficient, alignment-aware memcpy.
    + *
    + * It is based on demo code originally Copyright 2001 by Intel Corp, taken from
    + * http://www.embedded.com/showArticle....cleID=19205567
    + *
    + * Attempts were made, unsuccesfully, to contact the original
    + * author of this code (Michael Morrow, Intel). Below is the original
    + * copyright notice.
    + *
    + * This software has been developed by Intel Corporation.
    + * Intel specifically disclaims all warranties, express or
    + * implied, and all liability, including consequential and
    + * other indirect damages, for the use of this program, including
    + * liability for infringement of any proprietary rights,
    + * and including the warranties of merchantability and fitness
    + * for a particular purpose. Intel does not assume any
    + * responsibility for and errors which may appear in this program
    + * not any responsibility to update it.
    + */
    +
    +/* Filename: memcpy.c
    + *
    + * Reasonably optimised generic C-code for memset on Microblaze
    + * Based on demo code originally Copyright 2001 by Intel Corp.
    + *
    + * This software has been developed by Intel Corporation.
    + * Intel specifically disclaims all warranties, express or
    + * implied, and all liability, including consequential and
    + * other indirect damages, for the use of this program, including
    + * liability for infringement of any proprietary rights,
    + * and including the warranties of merchantability and fitness
    + * for a particular purpose. Intel does not assume any
    + * responsibility for and errors which may appear in this program
    + * not any responsibility to update it.
    + */
    +
    +#include
    +#include
    +#include
    +
    +#include
    +
    +void *memset(void *s, int c, __kernel_size_t n)
    +{
    + void *r = s;
    + unsigned int w32;
    +
    + /* Truncate c to 8 bits */
    + w32 = c = (c & 0xFF);
    +
    + /* Make a repeating word out of it */
    + w32 |= w32 << 8;
    + w32 |= w32 << 8;
    + w32 |= w32 << 8;
    +
    + if (n >= 4) {
    + /* Align the destination to a word boundary. */
    + /* This is done in an endian independant manner. */
    + switch ((unsigned) s & 3) {
    + case 1: *(char *)s = c; s = (char *)s+1; n--;
    + case 2: *(char *)s = c; s = (char *)s+1; n--;
    + case 3: *(char *)s = c; s = (char *)s+1; n--;
    + }
    +
    + /* Do as many full-word copies as we can */
    + for (; n >= 4; n -= 4) {
    + *(unsigned *)s = w32;
    + s = (unsigned *)s + 1;
    + }
    +
    + }
    +
    + /* Finish off the rest as byte sets */
    + while (n--) {
    + *(char *)s = c;
    + s = (char *)s+1;
    + }
    + return r;
    +}
    +
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. [PATCH 34/52] [microblaze] definitions of types

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    include/asm-microblaze/posix_types.h | 75 ++++++++++++++++++++++++++++++++++
    include/asm-microblaze/types.h | 64 +++++++++++++++++++++++++++++
    2 files changed, 139 insertions(+), 0 deletions(-)
    create mode 100644 include/asm-microblaze/posix_types.h
    create mode 100644 include/asm-microblaze/types.h

    diff --git a/include/asm-microblaze/posix_types.h b/include/asm-microblaze/posix_types.h
    new file mode 100644
    index 0000000..a05f61f
    --- /dev/null
    +++ b/include/asm-microblaze/posix_types.h
    @@ -0,0 +1,75 @@
    +/*
    + * include/asm-microblaze/posix_types.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_POSIX_TYPES_H
    +#define _ASM_POSIX_TYPES_H
    +
    +/*
    + * This file is generally used by user-level software, so you need to
    + * be a little careful about namespace pollution etc. Also, we cannot
    + * assume GCC is being used.
    + */
    +
    +typedef unsigned long __kernel_ino_t;
    +typedef unsigned short __kernel_mode_t;
    +typedef unsigned short __kernel_nlink_t;
    +typedef long __kernel_off_t;
    +typedef int __kernel_pid_t;
    +typedef unsigned short __kernel_ipc_pid_t;
    +typedef unsigned short __kernel_uid_t;
    +typedef unsigned short __kernel_gid_t;
    +typedef unsigned int __kernel_size_t;
    +typedef int __kernel_ssize_t;
    +typedef int __kernel_ptrdiff_t;
    +typedef long __kernel_time_t;
    +typedef long __kernel_suseconds_t;
    +typedef long __kernel_clock_t;
    +typedef int __kernel_timer_t;
    +typedef int __kernel_clockid_t;
    +typedef int __kernel_daddr_t;
    +typedef char * __kernel_caddr_t;
    +typedef unsigned short __kernel_uid16_t;
    +typedef unsigned short __kernel_gid16_t;
    +typedef unsigned int __kernel_uid32_t;
    +typedef unsigned int __kernel_gid32_t;
    +
    +typedef unsigned short __kernel_old_uid_t;
    +typedef unsigned short __kernel_old_gid_t;
    +typedef unsigned short __kernel_old_dev_t;
    +
    +#ifdef __GNUC__
    +typedef long long __kernel_loff_t;
    +#endif
    +
    +typedef struct {
    +#if defined(__KERNEL__) || defined(__USE_ALL)
    + int val[2];
    +#else /* !defined(__KERNEL__) && !defined(__USE_ALL) */
    + int __val[2];
    +#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
    +} __kernel_fsid_t;
    +
    +#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
    +
    +#undef __FD_SET
    +#define __FD_SET(d, set) ((set)->fds_bits[__FDELT(d)] |= __FDMASK(d))
    +
    +#undef __FD_CLR
    +#define __FD_CLR(d, set) ((set)->fds_bits[__FDELT(d)] &= ~__FDMASK(d))
    +
    +#undef __FD_ISSET
    +#define __FD_ISSET(d, set) (!!((set)->fds_bits[__FDELT(d)] & __FDMASK(d)))
    +
    +#undef __FD_ZERO
    +#define __FD_ZERO(fdsetp) (memset (fdsetp, 0, sizeof(*(fd_set *)fdsetp)))
    +
    +#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
    +
    +#endif /* _ASM_POSIX_TYPES_H */
    diff --git a/include/asm-microblaze/types.h b/include/asm-microblaze/types.h
    new file mode 100644
    index 0000000..3ba4b8d
    --- /dev/null
    +++ b/include/asm-microblaze/types.h
    @@ -0,0 +1,64 @@
    +/*
    + * include/asm-microblaze/types.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_TYPES_H
    +#define _ASM_TYPES_H
    +
    +#ifndef __ASSEMBLY__
    +
    +typedef unsigned short umode_t;
    +
    +/*
    + * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
    + * header files exported to user space
    + */
    +
    +typedef __signed__ char __s8;
    +typedef unsigned char __u8;
    +
    +typedef __signed__ short __s16;
    +typedef unsigned short __u16;
    +
    +typedef __signed__ int __s32;
    +typedef unsigned int __u32;
    +
    +#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
    +typedef __signed__ long long __s64;
    +typedef unsigned long long __u64;
    +#endif
    +
    +/*
    + * These aren't exported outside the kernel to avoid name space clashes
    + */
    +#ifdef __KERNEL__
    +
    +typedef __signed__ char s8;
    +typedef unsigned char u8;
    +
    +typedef __signed__ short s16;
    +typedef unsigned short u16;
    +
    +typedef __signed__ int s32;
    +typedef unsigned int u32;
    +
    +typedef __signed__ long long s64;
    +typedef unsigned long long u64;
    +
    +
    +#define BITS_PER_LONG 32
    +
    +/* Dma addresses are 32-bits wide. */
    +
    +typedef u32 dma_addr_t;
    +
    +#endif/* __KERNEL__ */
    +#endif
    +
    +#endif /* _ASM_TYPES_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. [PATCH 29/52] [microblaze] memory inicialization, MMU, TLB

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/mm/init.c | 188 ++++++++++++++++++++++++++++++++++
    include/asm-microblaze/mmu.h | 19 ++++
    include/asm-microblaze/mmu_context.h | 24 +++++
    include/asm-microblaze/tlb.h | 18 ++++
    include/asm-microblaze/tlbflush.h | 22 ++++
    5 files changed, 271 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/mm/init.c
    create mode 100644 include/asm-microblaze/mmu.h
    create mode 100644 include/asm-microblaze/mmu_context.h
    create mode 100644 include/asm-microblaze/tlb.h
    create mode 100644 include/asm-microblaze/tlbflush.h

    diff --git a/arch/microblaze/mm/init.c b/arch/microblaze/mm/init.c
    new file mode 100644
    index 0000000..ebb71bf
    --- /dev/null
    +++ b/arch/microblaze/mm/init.c
    @@ -0,0 +1,188 @@
    +/*
    + * arch/microblaze/mm/init.c
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2007 Michal Simek
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#include
    +#include
    +#include
    +#include "../../../mm/internal.h"
    +#include
    +#include
    +#include
    +#include
    +
    +#include
    +#include
    +#include
    +#include
    +
    +#undef DEBUG
    +
    +#ifdef DEBUG
    +#define DBG(fmt...) printk(fmt)
    +#else
    +#define DBG(fmt...)
    +#endif
    +
    +char *klimit = _end;
    +static unsigned int memory_start;
    +static unsigned int memory_end;
    +unsigned int PAGE_OFFSET;
    +
    +void __init setup_memory(void)
    +{
    + int i;
    + unsigned int start, end;
    + unsigned long map_size;
    + unsigned long start_pfn = 0;
    + unsigned long end_pfn = 0;
    +
    + /* Find main memory where is the kernel */
    + for (i = 0; i < lmb.memory.cnt; i++) {
    + start_pfn = lmb.memory.region[i].base >> PAGE_SHIFT;
    + end_pfn = start_pfn + lmb_size_pages(&lmb.memory, i);
    + if ((start_pfn <= (((int)_text) >> PAGE_SHIFT)) &&
    + (((int)_text >> PAGE_SHIFT) <= end_pfn)) {
    + memory_end = (end_pfn << PAGE_SHIFT) - 1;
    + PAGE_OFFSET = memory_start = start_pfn << PAGE_SHIFT;
    + DBG("%s: Main mem: 0x%x-0x%x\n", __FUNCTION__,
    + memory_start, memory_end);
    + break;
    + }
    + }
    + /*
    + * start_pfn - start page - starting point
    + * end_pfn - first unused page
    + * memory_start - base physical address of main memory
    + * memory_end - end physical address of main memory
    + * PAGE_OFFSET - moving of first page
    + *
    + * Kernel:
    + * start: base phys address of kernel - page align
    + * end: base phys address of kernel - page align
    + *
    + * min_low_pfn - the first page (mm/bootmem.c - node_boot_start)
    + * max_low_pfn
    + * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn)
    + * num_physpages - number of all pages
    + *
    + */
    +
    + /* reservation of region where is the kernel */
    + start = PFN_DOWN((int)_text) << PAGE_SHIFT;
    + end = PAGE_ALIGN((unsigned long)klimit);
    + lmb_reserve(start, end - start);
    + DBG("%s: kernel addr 0x%08x-0x%08x\n", __FUNCTION__, start, end);
    +
    + /* calculate free pages, etc. */
    + min_low_pfn = PFN_UP(start_pfn << PAGE_SHIFT);
    + max_mapnr = PFN_DOWN((end_pfn << PAGE_SHIFT));
    + max_low_pfn = max_mapnr - min_low_pfn;
    + num_physpages = max_mapnr - min_low_pfn + 1;
    + printk(KERN_INFO "%s: max_mapnr: %#lx\n", __FUNCTION__, max_mapnr);
    + printk(KERN_INFO "%s: min_low_pfn: %#lx\n", __FUNCTION__, min_low_pfn);
    + printk(KERN_INFO "%s: max_low_pfn: %#lx\n", __FUNCTION__, max_low_pfn);
    +
    + /* add place for data pages */
    + map_size = init_bootmem_node(NODE_DATA(0), PFN_UP(end),
    + min_low_pfn, max_mapnr);
    + lmb_reserve(PFN_UP(end) << PAGE_SHIFT, map_size);
    +
    + /* free bootmem is whole main memory */
    + free_bootmem(start_pfn << PAGE_SHIFT,
    + ((end_pfn - start_pfn) << PAGE_SHIFT) - 1);
    +
    + /* reserve allocate blocks */
    + for (i = 1; i < lmb.reserved.cnt; i++) {
    + DBG("reserved %d - 0x%08x-0x%08x\n", i,
    + (u32) lmb.reserved.region[i].base,
    + (u32) lmb_size_bytes(&lmb.reserved, i));
    + reserve_bootmem(lmb.reserved.region[i].base,
    + lmb_size_bytes(&lmb.reserved, i) - 1);
    + }
    +}
    +
    +void paging_init(void)
    +{
    + int i;
    + unsigned long zones_size[MAX_NR_ZONES];
    +
    + /* we can DMA to/from any address. put all page into
    + * ZONE_DMA. */
    + zones_size[ZONE_NORMAL] = max_low_pfn;
    +
    + /* every other zones are empty */
    + for (i = 1; i < MAX_NR_ZONES; i++)
    + zones_size[i] = 0;
    +
    + free_area_init_node(0, NODE_DATA(0), zones_size,
    + NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT, NULL);
    +}
    +
    +void free_init_pages(char *what, unsigned long begin, unsigned long end)
    +{
    + unsigned long addr;
    +
    + for (addr = begin; addr < end; addr += PAGE_SIZE) {
    + ClearPageReserved(virt_to_page(addr));
    + init_page_count(virt_to_page(addr));
    + memset((void *)addr, 0xcc, PAGE_SIZE);
    + free_page(addr);
    + totalram_pages++;
    + }
    + printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10);
    +}
    +
    +#ifdef CONFIG_BLK_DEV_INITRD
    +void free_initrd_mem(unsigned long start, unsigned long end)
    +{
    + int pages = 0;
    + for (; start < end; start += PAGE_SIZE) {
    + ClearPageReserved(virt_to_page(start));
    + set_page_count(virt_to_page(start), 1);
    + free_page(start);
    + totalram_pages++;
    + pages++;
    + }
    + printk(KERN_NOTICE "Freeing initrd memory: %dk freed\n", pages);
    +}
    +#endif
    +
    +void free_initmem(void)
    +{
    + free_init_pages("unused kernel memory",
    + (unsigned long)(&__init_begin),
    + (unsigned long)(&__init_end));
    +}
    +
    +/* FIXME from arch/powerpc/mm/mem.c*/
    +void show_mem(void)
    +{
    + printk(KERN_NOTICE "%s\n", __FUNCTION__);
    +}
    +
    +void __init mem_init(void)
    +{
    + high_memory = (void *)(memory_end);
    +
    + /* this will put all memory onto the freelists */
    + totalram_pages += free_all_bootmem();
    +
    + printk(KERN_INFO "Memory: %luk/%luk available\n",
    + (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
    + num_physpages << (PAGE_SHIFT-10));
    +}
    +
    +/* Check against bounds of physical memory */
    +int ___range_ok(unsigned long addr, unsigned long size)
    +{
    + return ((addr < memory_start) ||
    + ((addr + size) >= memory_end));
    +}
    diff --git a/include/asm-microblaze/mmu.h b/include/asm-microblaze/mmu.h
    new file mode 100644
    index 0000000..c0d5e55
    --- /dev/null
    +++ b/include/asm-microblaze/mmu.h
    @@ -0,0 +1,19 @@
    +/*
    + * include/asm-microblaze/mmu.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_MMU_H
    +#define _ASM_MMU_H
    +
    +typedef struct {
    + struct vm_list_struct *vmlist;
    + unsigned long end_brk;
    +} mm_context_t;
    +
    +#endif /* _ASM_MMU_H */
    diff --git a/include/asm-microblaze/mmu_context.h b/include/asm-microblaze/mmu_context.h
    new file mode 100644
    index 0000000..ad499fd
    --- /dev/null
    +++ b/include/asm-microblaze/mmu_context.h
    @@ -0,0 +1,24 @@
    +/*
    + * include/asm-microblaze/mmu_context.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_MMU_CONTEXT_H
    +#define _ASM_MMU_CONTEXT_H
    +
    +#define init_new_context(tsk, mm) ({ 0; })
    +
    +#define enter_lazy_tlb(mm, tsk) do {} while (0)
    +#define change_mm_context(old, ctx, _pml4) do {} while (0)
    +#define destroy_context(mm) do {} while (0)
    +#define deactivate_mm(tsk, mm) do {} while (0)
    +#define switch_mm(prev, next, tsk) do {} while (0)
    +#define activate_mm(prev, next) do {} while (0)
    +
    +
    +#endif /* _ASM_MMU_CONTEXT_H */
    diff --git a/include/asm-microblaze/tlb.h b/include/asm-microblaze/tlb.h
    new file mode 100644
    index 0000000..5ae1b1c
    --- /dev/null
    +++ b/include/asm-microblaze/tlb.h
    @@ -0,0 +1,18 @@
    +/*
    + * include/asm-microblaze/tlb.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_TLB_H
    +#define _ASM_TLB_H
    +
    +#define tlb_flush(tlb) do {} while (0)
    +
    +#include
    +
    +#endif /* _ASM_TLB_H */
    diff --git a/include/asm-microblaze/tlbflush.h b/include/asm-microblaze/tlbflush.h
    new file mode 100644
    index 0000000..57393ed
    --- /dev/null
    +++ b/include/asm-microblaze/tlbflush.h
    @@ -0,0 +1,22 @@
    +/*
    + * include/asm-microblaze/tlbflush.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_TLBFLUSH_H
    +#define _ASM_TLBFLUSH_H
    +
    +#define flush_tlb() BUG()
    +#define flush_tlb_all() BUG()
    +#define flush_tlb_mm(mm) BUG()
    +#define flush_tlb_page(vma, addr) BUG()
    +#define flush_tlb_range(mm, start, end) BUG()
    +#define flush_tlb_pgtables(mm, start, end) BUG()
    +#define flush_tlb_kernel_range(start, end) BUG()
    +
    +#endif /* _ASM_TLBFLUSH_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  11. [PATCH 11/52] [microblaze] kernel modules support

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/kernel/microblaze_ksyms.c | 129 +++++++++++++++++++++++++
    arch/microblaze/kernel/module.c | 149 +++++++++++++++++++++++++++++
    include/asm-microblaze/module.h | 41 ++++++++
    3 files changed, 319 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/kernel/microblaze_ksyms.c
    create mode 100644 arch/microblaze/kernel/module.c
    create mode 100644 include/asm-microblaze/module.h

    diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
    new file mode 100644
    index 0000000..7ce8b36
    --- /dev/null
    +++ b/arch/microblaze/kernel/microblaze_ksyms.c
    @@ -0,0 +1,129 @@
    +/*
    + * linux/arch/microblaze/kernel/microblazeksyms.c
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + */
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +/* module handling */
    +EXPORT_SYMBOL(PAGE_OFFSET);
    +
    +/*
    + * floating point math emulator support.
    + * These symbols will never change their calling convention...
    + */
    +/* EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter);
    +EXPORT_SYMBOL_ALIAS(fp_printk,printk);
    +EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig);
    +
    +EXPORT_SYMBOL(__backtrace); */
    +
    + /* platform dependent support */
    +/* EXPORT_SYMBOL(__udelay);
    +EXPORT_SYMBOL(__const_udelay); */
    +
    + /* networking */
    +EXPORT_SYMBOL(csum_partial);
    +EXPORT_SYMBOL(csum_partial_copy);
    +EXPORT_SYMBOL(csum_partial_copy_from_user);
    +EXPORT_SYMBOL(ip_compute_csum);
    +
    + /* io */
    +/*#ifndef __raw_readsb
    +EXPORT_SYMBOL(__raw_readsb);
    +#endif
    +#ifndef __raw_readsw
    +EXPORT_SYMBOL(__raw_readsw);
    +#endif
    +#ifndef __raw_readsl
    +EXPORT_SYMBOL(__raw_readsl);
    +#endif
    +#ifndef __raw_writesb
    +EXPORT_SYMBOL(__raw_writesb);
    +#endif
    +#ifndef __raw_writesw
    +EXPORT_SYMBOL(__raw_writesw);
    +#endif
    +#ifndef __raw_writesl
    +EXPORT_SYMBOL(__raw_writesl);
    +#endif*/
    +
    + /* string / mem functions */
    +/*EXPORT_SYMBOL(strchr);
    +EXPORT_SYMBOL(strrchr);*/
    +
    +#ifdef __HAVE_ARCH_MEMSET
    +EXPORT_SYMBOL(memset);
    +#endif
    +
    +#ifdef __HAVE_ARCH_MEMCPY
    +EXPORT_SYMBOL(memcpy);
    +#endif
    +
    +#ifdef __HAVE_ARCH_MEMMOVE
    +EXPORT_SYMBOL(memmove);
    +#endif
    +
    +/* EXPORT_SYMBOL(memchr);
    +EXPORT_SYMBOL(__memzero); */
    +
    + /* user mem (segment) */
    +/* EXPORT_SYMBOL(__strnlen_user);
    +EXPORT_SYMBOL(__strncpy_from_user); */
    +
    + /* crypto hash */
    +/* EXPORT_SYMBOL(sha_transform); */
    +
    +
    +/*
    + * libgcc functions - functions that are used internally by the
    + * compiler... (prototypes are not correct though, but that
    + * doesn't really matter since they're not versioned).
    + */
    +extern void __ashldi3(void);
    +EXPORT_SYMBOL(__ashldi3);
    +extern void __ashrdi3(void);
    +EXPORT_SYMBOL(__ashrdi3);
    +extern void __divsi3(void);
    +EXPORT_SYMBOL(__divsi3);
    +extern void __lshrdi3(void);
    +EXPORT_SYMBOL(__lshrdi3);
    +extern void __modsi3(void);
    +EXPORT_SYMBOL(__modsi3);
    +extern void __mulsi3(void);
    +EXPORT_SYMBOL(__mulsi3);
    +extern void __muldi3(void);
    +EXPORT_SYMBOL(__muldi3);
    +extern void __ucmpdi2(void);
    +EXPORT_SYMBOL(__ucmpdi2);
    +extern void __udivsi3(void);
    +EXPORT_SYMBOL(__udivsi3);
    +extern void __umodsi3(void);
    +EXPORT_SYMBOL(__umodsi3);
    +/*extern void fpundefinstr(void);
    +extern void fp_enter(void);*/
    +
    + /* bitops */
    +/* EXPORT_SYMBOL(_set_bit_le);
    +EXPORT_SYMBOL(_test_and_set_bit_le);
    +EXPORT_SYMBOL(_clear_bit_le);
    +EXPORT_SYMBOL(_test_and_clear_bit_le);
    +EXPORT_SYMBOL(_change_bit_le);
    +EXPORT_SYMBOL(_test_and_change_bit_le);
    +EXPORT_SYMBOL(_find_first_zero_bit_le);
    +EXPORT_SYMBOL(_find_next_zero_bit_le);
    +EXPORT_SYMBOL(_find_first_bit_le);
    +EXPORT_SYMBOL(_find_next_bit_le); */
    diff --git a/arch/microblaze/kernel/module.c b/arch/microblaze/kernel/module.c
    new file mode 100644
    index 0000000..d2befac
    --- /dev/null
    +++ b/arch/microblaze/kernel/module.c
    @@ -0,0 +1,149 @@
    +/*
    + * linux/arch/microblaze/kernel/module.c
    + *
    + * This program is free software; you can redistribute it and/or modify
    + * it under the terms of the GNU General Public License version 2 as
    + * published by the Free Software Foundation.
    + *
    + */
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#include
    +
    +#if 0
    +#define DBPRINTK(...) printk(__VA_ARGS__)
    +#else
    +#define DBPRINTK(...)
    +#endif
    +
    +void *module_alloc(unsigned long size)
    +{
    + void *ret;
    + ret = (size == 0) ? NULL : vmalloc(size);
    + DBPRINTK("module_alloc (%08lx@%08lx)\n", size, (unsigned long int)ret);
    + return ret;
    +}
    +
    +void module_free(struct module *module, void *region)
    +{
    + DBPRINTK("module_free(%s,%08lx)\n", module->name, region);
    + vfree(region);
    +}
    +
    +int module_frob_arch_sections(Elf_Ehdr *hdr,
    + Elf_Shdr *sechdrs,
    + char *secstrings,
    + struct module *mod)
    +{
    + return 0;
    +}
    +
    +int
    +apply_relocate(Elf32_Shdr * sechdrs, const char *strtab, unsigned int symindex,
    + unsigned int relsec, struct module *module)
    +{
    +
    + printk(KERN_ERR "module %s: ADD RELOCATION unsupported\n",
    + module->name);
    + return -ENOEXEC;
    +
    +}
    +
    +int
    +apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab,
    + unsigned int symindex, unsigned int relsec, struct module *module)
    +{
    +
    + unsigned int i;
    + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr;
    + Elf32_Sym *sym;
    + unsigned long int *location;
    + unsigned long int locoffs;
    + unsigned long int value;
    + unsigned long int old_value;
    +
    + DBPRINTK("Applying add relocation section %u to %u\n",
    + relsec, sechdrs[relsec].sh_info);
    +
    + for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rela); i++) {
    +
    + location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr +
    + rela[i].r_offset;
    + sym = (Elf32_Sym *)sechdrs[symindex].sh_addr +
    + ELF32_R_SYM(rela[i].r_info);
    + value = sym->st_value + rela[i].r_addend;
    +
    + switch (ELF32_R_TYPE(rela[i].r_info)) {
    +
    + /*
    + * Be careful! mb-gcc / mb-ld splits the relocs between the
    + * text and the reloc table. In general this means we must
    + * read the current contents of (*location), add any offset
    + * then store the result back in
    + */
    +
    + case R_MICROBLAZE_32:
    + old_value = *location;
    + *location = value + old_value;
    + DBPRINTK("R_MICROBLAZE_32 (%08lx->%08lx)\n",
    + old_value, value);
    + break;
    +
    + case R_MICROBLAZE_64:
    + old_value = ((location[0] & 0x0000FFFF) << 16) |
    + ((location[1] & 0x0000FFFF));
    + value += old_value;
    + location[0] = (location[0] & 0xFFFF0000) |
    + (value >> 16);
    + location[1] = (location[1] & 0xFFFF0000) |
    + (value & 0xFFFF);
    + DBPRINTK("R_MICROBLAZE_64 (%08lx->%08lx)\n",
    + old_value, value);
    + break;
    +
    + case R_MICROBLAZE_64_PCREL:
    + locoffs = (location[0] & 0xFFFF) << 16 |
    + (location[1] & 0xFFFF);
    + value -= (unsigned long int)(location) + 4 +
    + locoffs;
    + location[0] = (location[0] & 0xFFFF0000) |
    + (value >> 16);
    + location[1] = (location[1] & 0xFFFF0000) |
    + (value & 0xFFFF);
    + DBPRINTK("R_MICROBLAZE_64_PCREL (%08lx)\n",
    + value);
    + break;
    +
    + case R_MICROBLAZE_NONE:
    + DBPRINTK("R_MICROBLAZE_NONE\n");
    + break;
    +
    + default:
    + printk(KERN_ERR "module %s: "
    + "Unknown relocation: %u\n",
    + module->name,
    + ELF32_R_TYPE(rela->r_info));
    + return -ENOEXEC;
    + }
    + }
    + return 0;
    +}
    +
    +int
    +module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr *sechdrs,
    + struct module *module)
    +{
    + return 0;
    +}
    +
    +void
    +module_arch_cleanup(struct module *mod)
    +{
    +}
    diff --git a/include/asm-microblaze/module.h b/include/asm-microblaze/module.h
    new file mode 100644
    index 0000000..97416e0
    --- /dev/null
    +++ b/include/asm-microblaze/module.h
    @@ -0,0 +1,41 @@
    +/*
    + * include/asm-microblaze/module.h
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#ifndef _ASM_MODULE_H
    +#define _ASM_MODULE_H
    +
    +#define EM_XILINX_MICROBLAZE 0xbaab
    +
    +/* Microblaze Relocations */
    +#define R_MICROBLAZE_NONE 0
    +#define R_MICROBLAZE_32 1
    +#define R_MICROBLAZE_32_PCREL 2
    +#define R_MICROBLAZE_64_PCREL 3
    +#define R_MICROBLAZE_32_PCREL_LO 4
    +#define R_MICROBLAZE_64 5
    +#define R_MICROBLAZE_32_LO 6
    +#define R_MICROBLAZE_SRO32 7
    +#define R_MICROBLAZE_SRW32 8
    +#define R_MICROBLAZE_64_NONE 9
    +#define R_MICROBLAZE_32_SYM_OP_SYM 10
    +/* Keep this the last entry. */
    +#define R_MICROBLAZE_NUM 11
    +
    +struct mod_arch_specific {
    + int foo;
    +};
    +
    +#define Elf_Shdr Elf32_Shdr
    +#define Elf_Sym Elf32_Sym
    +#define Elf_Ehdr Elf32_Ehdr
    +
    +typedef struct { volatile int counter; } module_t;
    +
    +#endif /* _ASM_MODULE_H */
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  12. [PATCH 15/52] [microblaze] assembler files head.S, entry.S, ...

    From: Michal Simek


    Signed-off-by: Michal Simek
    ---
    arch/microblaze/kernel/entry.S | 597 ++++++++++++++++++++++++++++++++
    arch/microblaze/kernel/head.S | 40 +++
    arch/microblaze/kernel/syscall_table.S | 328 ++++++++++++++++++
    arch/microblaze/kernel/vmlinux.lds.S | 145 ++++++++
    4 files changed, 1110 insertions(+), 0 deletions(-)
    create mode 100644 arch/microblaze/kernel/entry.S
    create mode 100644 arch/microblaze/kernel/head.S
    create mode 100644 arch/microblaze/kernel/syscall_table.S
    create mode 100644 arch/microblaze/kernel/vmlinux.lds.S

    diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S
    new file mode 100644
    index 0000000..d0b487b
    --- /dev/null
    +++ b/arch/microblaze/kernel/entry.S
    @@ -0,0 +1,597 @@
    +/*
    + * arch/microblaze/kernel/entry.S
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +
    +#define PER_CPU(var) per_cpu__##var
    +
    +#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
    + .macro disable_irq
    + msrclr r0, MSR_IE
    + .endm
    +
    + .macro enable_irq
    + msrset r0, MSR_IE
    + .endm
    +
    + .macro clear_bip
    + msrclr r0, MSR_BIP
    + .endm
    +#else
    + .macro disable_irq
    + mfs r11, rmsr
    + andi r11, r11, ~MSR_IE
    + mts rmsr, r11
    + .endm
    +
    + .macro enable_irq
    + mfs r11, rmsr
    + ori r11, r11, MSR_IE
    + mts rmsr, r11
    + .endm
    +
    + .macro clear_bip
    + mfs r11, rmsr
    + andi r11, r11, ~MSR_BIP
    + mts rmsr, r11
    + .endm
    +#endif
    +
    +ENTRY(_interrupt)
    + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
    + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
    + lwi r11, r0, PER_CPU(KM) /* load mode indicator */
    + beqid r11, 1f
    + nop
    + brid 2f /* jump over */
    + addik r1, r1, (-PT_SIZE) /* room for pt_regs (delay slot) */
    +1: /* switch to kernel stack */
    + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
    + lwi r1, r1, TS_THREAD_INFO /* get the thread info */
    + /* calculate kernel stack pointer */
    + addik r1, r1, THREAD_SIZE - PT_SIZE
    +2:
    + swi r11, r1, PT_MODE /* store the mode */
    + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
    + swi r2, r1, PT_R2
    + swi r3, r1, PT_R3
    + swi r4, r1, PT_R4
    + swi r5, r1, PT_R5
    + swi r6, r1, PT_R6
    + swi r7, r1, PT_R7
    + swi r8, r1, PT_R8
    + swi r9, r1, PT_R9
    + swi r10, r1, PT_R10
    + swi r11, r1, PT_R11
    + swi r12, r1, PT_R12
    + swi r13, r1, PT_R13
    + swi r14, r1, PT_R14
    + swi r14, r1, PT_PC
    + swi r15, r1, PT_R15
    + swi r16, r1, PT_R16
    + swi r17, r1, PT_R17
    + swi r18, r1, PT_R18
    + swi r19, r1, PT_R19
    + swi r20, r1, PT_R20
    + swi r21, r1, PT_R21
    + swi r22, r1, PT_R22
    + swi r23, r1, PT_R23
    + swi r24, r1, PT_R24
    + swi r25, r1, PT_R25
    + swi r26, r1, PT_R26
    + swi r27, r1, PT_R27
    + swi r28, r1, PT_R28
    + swi r29, r1, PT_R29
    + swi r30, r1, PT_R30
    + swi r31, r1, PT_R31
    + /* special purpose registers */
    + mfs r11, rmsr
    + swi r11, r1, PT_MSR
    + mfs r11, rear
    + swi r11, r1, PT_EAR
    + mfs r11, resr
    + swi r11, r1, PT_ESR
    + mfs r11, rfsr
    + swi r11, r1, PT_FSR
    + /* reload original stack pointer and save it */
    + lwi r11, r0, PER_CPU(ENTRY_SP)
    + swi r11, r1, PT_R1
    + /* update mode indicator we are in kernel mode */
    + addik r11, r0, 1
    + swi r11, r0, PER_CPU(KM)
    + /* restore r31 */
    + lwi r31, r0, PER_CPU(CURRENT_SAVE)
    + /* prepare the link register, the argument and jump */
    + la r15, r0, ret_from_intr - 8
    + addk r6, r0, r15
    + braid do_IRQ
    + add r5, r0, r1
    +
    +ret_from_intr:
    + lwi r11, r1, PT_MODE
    + bneid r11, 3f
    +
    + lwi r6, r31, TS_THREAD_INFO /* get thread info */
    + lwi r19, r6, TI_FLAGS /* get flags in thread info */
    + /* do an extra work if any bits are set */
    +
    + andi r11, r19, _TIF_NEED_RESCHED
    + beqi r11, 1f
    + bralid r15, schedule
    + nop
    +1: andi r11, r19, _TIF_SIGPENDING
    + beqid r11, no_intr_reshed
    + addk r5, r1, r0
    + addk r7, r0, r0
    + bralid r15, do_signal
    + addk r6, r0, r0
    +
    +no_intr_reshed:
    + /* save mode indicator */
    + lwi r11, r1, PT_MODE
    +3:
    + swi r11, r0, PER_CPU(KM)
    +
    + /* save r31 */
    + swi r31, r0, PER_CPU(CURRENT_SAVE)
    +restore_context:
    + /* special purpose registers */
    + lwi r11, r1, PT_FSR
    + mts rfsr, r11
    + lwi r11, r1, PT_ESR
    + mts resr, r11
    + lwi r11, r1, PT_EAR
    + mts rear, r11
    + lwi r11, r1, PT_MSR
    + mts rmsr, r11
    +
    + lwi r31, r1, PT_R31
    + lwi r30, r1, PT_R30
    + lwi r29, r1, PT_R29
    + lwi r28, r1, PT_R28
    + lwi r27, r1, PT_R27
    + lwi r26, r1, PT_R26
    + lwi r25, r1, PT_R25
    + lwi r24, r1, PT_R24
    + lwi r23, r1, PT_R23
    + lwi r22, r1, PT_R22
    + lwi r21, r1, PT_R21
    + lwi r20, r1, PT_R20
    + lwi r19, r1, PT_R19
    + lwi r18, r1, PT_R18
    + lwi r17, r1, PT_R17
    + lwi r16, r1, PT_R16
    + lwi r15, r1, PT_R15
    + lwi r14, r1, PT_PC
    + lwi r13, r1, PT_R13
    + lwi r12, r1, PT_R12
    + lwi r11, r1, PT_R11
    + lwi r10, r1, PT_R10
    + lwi r9, r1, PT_R9
    + lwi r8, r1, PT_R8
    + lwi r7, r1, PT_R7
    + lwi r6, r1, PT_R6
    + lwi r5, r1, PT_R5
    + lwi r4, r1, PT_R4
    + lwi r3, r1, PT_R3
    + lwi r2, r1, PT_R2
    + lwi r1, r1, PT_R1
    + rtid r14, 0
    + nop
    +
    +ENTRY(_reset)
    + brai 0;
    +
    +ENTRY(_user_exception)
    + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
    + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
    + lwi r11, r0, PER_CPU(KM) /* load mode indicator */
    + beqid r11, 1f /* Already in kernel mode? */
    + nop
    + brid 2f /* jump over */
    + addik r1, r1, (-PT_SIZE) /* Room for pt_regs (delay slot) */
    +1: /* Switch to kernel stack */
    + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
    + lwi r1, r1, TS_THREAD_INFO /* get the thread info */
    + /* calculate kernel stack pointer */
    + addik r1, r1, THREAD_SIZE - PT_SIZE
    + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
    + lwi r11, r0, PER_CPU(KM) /* load mode indicator */
    +2:
    + swi r11, r1, PT_MODE /* store the mode */
    + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
    + /* save them on stack */
    + swi r2, r1, PT_R2
    + swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
    + swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
    + swi r5, r1, PT_R5
    + swi r6, r1, PT_R6
    + swi r7, r1, PT_R7
    + swi r8, r1, PT_R8
    + swi r9, r1, PT_R9
    + swi r10, r1, PT_R10
    + swi r11, r1, PT_R11
    + /* r12: _always_ in clobber list; see unistd.h */
    + swi r12, r1, PT_R12
    + swi r13, r1, PT_R13
    + /* r14: _always_ in clobber list; see unistd.h */
    + swi r14, r1, PT_R14
    + /* but we want to return to the next inst. */
    + addik r14, r14, 0x4
    + swi r14, r1, PT_PC /* increment by 4 and store in pc */
    + swi r15, r1, PT_R15
    + swi r16, r1, PT_R16
    + swi r17, r1, PT_R17
    + swi r18, r1, PT_R18
    + swi r19, r1, PT_R19
    + swi r20, r1, PT_R20
    + swi r21, r1, PT_R21
    + swi r22, r1, PT_R22
    + swi r23, r1, PT_R23
    + swi r24, r1, PT_R24
    + swi r25, r1, PT_R25
    + swi r26, r1, PT_R26
    + swi r27, r1, PT_R27
    + swi r28, r1, PT_R28
    + swi r29, r1, PT_R29
    + swi r30, r1, PT_R30
    + swi r31, r1, PT_R31
    +
    + disable_irq
    + nop /* make sure IE bit is in effect */
    + clear_bip /* once IE is in effect it is safe to clear BIP */
    + nop
    +
    + /* special purpose registers */
    + mfs r11, rmsr
    + swi r11, r1, PT_MSR
    + mfs r11, rear
    + swi r11, r1, PT_EAR
    + mfs r11, resr
    + swi r11, r1, PT_ESR
    + mfs r11, rfsr
    + swi r11, r1, PT_FSR
    + /* reload original stack pointer and save it */
    + lwi r11, r0, PER_CPU(ENTRY_SP)
    + swi r11, r1, PT_R1
    + /* update mode indicator we are in kernel mode */
    + addik r11, r0, 1
    + swi r11, r0, PER_CPU(KM)
    + /* restore r31 */
    + lwi r31, r0, PER_CPU(CURRENT_SAVE)
    + /* re-enable interrupts now we are in kernel mode */
    + enable_irq
    +
    + /* See if the system call number is valid. */
    + addi r11, r12, -NR_syscalls
    + bgei r11, 1f /* return to user if not valid */
    + /* Figure out which function to use for this system call. */
    + /* Note Microblaze barrel shift is optional, so don't rely on it */
    + add r12, r12, r12 /* convert num -> ptr */
    + add r12, r12, r12
    + lwi r12, r12, sys_call_table /* Get function pointer */
    + la r15, r0, ret_to_user-8 /* set return address */
    + bra r12 /* Make the system call. */
    + bri 0 /* won't reach here */
    +1:
    + brid ret_to_user /* jump to syscall epilogue */
    + addi r3, r0, -ENOSYS /* set errno in delay slot */
    +
    +/*
    + * Debug traps are like a system call, but entered via brki r14, 0x60
    + * All we need to do is send the SIGTRAP signal to current, ptrace and do_signal
    + * will handle the rest
    + */
    +ENTRY(_debug_exception)
    + swi r1, r0, PER_CPU(ENTRY_SP) /* save the current sp */
    + lwi r1, r0, PER_CPU(CURRENT_SAVE) /* get the saved current */
    + lwi r1, r1, TS_THREAD_INFO /* get the thread info */
    + addik r1, r1, THREAD_SIZE - PT_SIZE /* get the kernel stack */
    + swi r11, r0, PER_CPU(R11_SAVE) /* temporarily save r11 */
    + lwi r11, r0, PER_CPU(KM) /* load mode indicator */
    +//save_context:
    + swi r11, r1, PT_MODE /* store the mode */
    + lwi r11, r0, PER_CPU(R11_SAVE) /* reload r11 */
    + /* save them on stack */
    + swi r2, r1, PT_R2
    + swi r3, r1, PT_R3 /* r3: _always_ in clobber list; see unistd.h */
    + swi r4, r1, PT_R4 /* r4: _always_ in clobber list; see unistd.h */
    + swi r5, r1, PT_R5
    + swi r6, r1, PT_R6
    + swi r7, r1, PT_R7
    + swi r8, r1, PT_R8
    + swi r9, r1, PT_R9
    + swi r10, r1, PT_R10
    + swi r11, r1, PT_R11
    + /* r12: _always_ in clobber list; see unistd.h */
    + swi r12, r1, PT_R12
    + swi r13, r1, PT_R13
    + /* r14: _always_ in clobber list; see unistd.h */
    + swi r14, r1, PT_R14
    + swi r14, r1, PT_PC /* Will return to interrupted instruction */
    + swi r15, r1, PT_R15
    + swi r16, r1, PT_R16
    + swi r17, r1, PT_R17
    + swi r18, r1, PT_R18
    + swi r19, r1, PT_R19
    + swi r20, r1, PT_R20
    + swi r21, r1, PT_R21
    + swi r22, r1, PT_R22
    + swi r23, r1, PT_R23
    + swi r24, r1, PT_R24
    + swi r25, r1, PT_R25
    + swi r26, r1, PT_R26
    + swi r27, r1, PT_R27
    + swi r28, r1, PT_R28
    + swi r29, r1, PT_R29
    + swi r30, r1, PT_R30
    + swi r31, r1, PT_R31
    +
    + disable_irq
    + nop /* make sure IE bit is in effect */
    + clear_bip /* once IE is in effect it is safe to clear BIP */
    + nop
    +
    + /* special purpose registers */
    + mfs r11, rmsr
    + swi r11, r1, PT_MSR
    + mfs r11, rear
    + swi r11, r1, PT_EAR
    + mfs r11, resr
    + swi r11, r1, PT_ESR
    + mfs r11, rfsr
    + swi r11, r1, PT_FSR
    + /* reload original stack pointer and save it */
    + lwi r11, r0, PER_CPU(ENTRY_SP)
    + swi r11, r1, PT_R1
    + /* update mode indicator we are in kernel mode */
    + addik r11, r0, 1
    + swi r11, r0, PER_CPU(KM)
    + /* restore r31 */
    + lwi r31, r0, PER_CPU(CURRENT_SAVE)
    + /* re-enable interrupts now we are in kernel mode */
    + enable_irq
    +
    + addi r5, r0, SIGTRAP /* sending the trap signal */
    + add r6, r0, r31 /* to current */
    + bralid r15, send_sig
    + add r7, r0, r0 /* 3rd param zero */
    +
    + /* Restore r3/r4 to work around how ret_to_user works */
    + lwi r3, r1, PT_R3
    + lwi r4, r1, PT_R4
    + bri ret_to_user
    +
    +ENTRY(_break)
    + bri 0
    +
    +/* struct task_struct *_switch_to(struct thread_info *prev,
    + struct thread_info *next); */
    +ENTRY(_switch_to)
    + /* prepare return value */
    + addk r3, r0, r31
    +
    + /* save registers in cpu_context */
    + /* use r11 and r12, volatile registers, as temp register */
    + addik r11, r5, TI_CPU_CONTEXT
    + swi r1, r11, CC_SP
    + swi r2, r11, CC_R2
    + /* skip volatile registers.
    + * they are saved on stack when we jumped to _switch_to() */
    + /* dedicated registers */
    + swi r13, r11, CC_R13
    + swi r14, r11, CC_R14
    + swi r15, r11, CC_R15
    + swi r16, r11, CC_R16
    + swi r17, r11, CC_R17
    + swi r18, r11, CC_R18
    + /* save non-volatile registers */
    + swi r19, r11, CC_R19
    + swi r20, r11, CC_R20
    + swi r21, r11, CC_R21
    + swi r22, r11, CC_R22
    + swi r23, r11, CC_R23
    + swi r24, r11, CC_R24
    + swi r25, r11, CC_R25
    + swi r26, r11, CC_R26
    + swi r27, r11, CC_R27
    + swi r28, r11, CC_R28
    + swi r29, r11, CC_R29
    + swi r30, r11, CC_R30
    + /* special purpose registers */
    + mfs r12, rmsr
    + swi r12, r11, CC_MSR
    + mfs r12, rear
    + swi r12, r11, CC_EAR
    + mfs r12, resr
    + swi r12, r11, CC_ESR
    + mfs r12, rfsr
    + swi r12, r11, CC_FSR
    +
    + /* update r31, the current */
    + lwi r31, r6, TI_TASK
    + swi r31, r0, PER_CPU(CURRENT_SAVE)
    +
    + /* get new process' cpu context and restore */
    + addik r11, r6, TI_CPU_CONTEXT
    +
    + /* special purpose registers */
    + lwi r12, r11, CC_FSR
    + mts rfsr, r12
    + lwi r12, r11, CC_ESR
    + mts resr, r12
    + lwi r12, r11, CC_EAR
    + mts rear, r12
    + lwi r12, r11, CC_MSR
    + mts rmsr, r12
    + /* non-volatile registers */
    + lwi r30, r11, CC_R30
    + lwi r29, r11, CC_R29
    + lwi r28, r11, CC_R28
    + lwi r27, r11, CC_R27
    + lwi r26, r11, CC_R26
    + lwi r25, r11, CC_R25
    + lwi r24, r11, CC_R24
    + lwi r23, r11, CC_R23
    + lwi r22, r11, CC_R22
    + lwi r21, r11, CC_R21
    + lwi r20, r11, CC_R20
    + lwi r19, r11, CC_R19
    + /* dedicated registers */
    + lwi r18, r11, CC_R18
    + lwi r17, r11, CC_R17
    + lwi r16, r11, CC_R16
    + lwi r15, r11, CC_R15
    + lwi r14, r11, CC_R14
    + lwi r13, r11, CC_R13
    + /* skip volatile registers */
    + lwi r2, r11, CC_R2
    + lwi r1, r11, CC_SP
    +
    + rtsd r15, 8
    + nop
    +
    +ENTRY(ret_from_fork)
    + addk r5, r0, r3
    + addk r6, r0, r1
    + brlid r15, schedule_tail
    + nop
    + swi r31, r1, PT_R31 /* save r31 in user context. */
    + /* will soon be restored to r31 in ret_to_user */
    + addk r3, r0, r0
    + brid ret_to_user
    + nop
    +
    +work_pending:
    + andi r11, r19, _TIF_NEED_RESCHED
    + beqi r11, 1f
    + bralid r15, schedule
    + nop
    +1: andi r11, r19, _TIF_SIGPENDING
    + beqi r11, no_work_pending
    + addk r5, r1, r0
    + addik r7, r0, 1
    + bralid r15, do_signal
    + addk r6, r0, r0
    + bri no_work_pending
    +
    +ENTRY(ret_to_user)
    + disable_irq
    +
    + swi r4, r1, PT_R4 /* return val */
    + swi r3, r1, PT_R3 /* return val */
    +
    + lwi r6, r31, TS_THREAD_INFO /* get thread info */
    + lwi r19, r6, TI_FLAGS /* get flags in thread info */
    + bnei r19, work_pending /* do an extra work if any bits are set */
    +no_work_pending:
    + disable_irq
    +
    + /* save r31 */
    + swi r31, r0, PER_CPU(CURRENT_SAVE)
    + /* save mode indicator */
    + lwi r18, r1, PT_MODE
    + swi r18, r0, PER_CPU(KM)
    +//restore_context:
    + /* special purpose registers */
    + lwi r18, r1, PT_FSR
    + mts rfsr, r18
    + lwi r18, r1, PT_ESR
    + mts resr, r18
    + lwi r18, r1, PT_EAR
    + mts rear, r18
    + lwi r18, r1, PT_MSR
    + mts rmsr, r18
    +
    + lwi r31, r1, PT_R31
    + lwi r30, r1, PT_R30
    + lwi r29, r1, PT_R29
    + lwi r28, r1, PT_R28
    + lwi r27, r1, PT_R27
    + lwi r26, r1, PT_R26
    + lwi r25, r1, PT_R25
    + lwi r24, r1, PT_R24
    + lwi r23, r1, PT_R23
    + lwi r22, r1, PT_R22
    + lwi r21, r1, PT_R21
    + lwi r20, r1, PT_R20
    + lwi r19, r1, PT_R19
    + lwi r18, r1, PT_R18
    + lwi r17, r1, PT_R17
    + lwi r16, r1, PT_R16
    + lwi r15, r1, PT_R15
    + lwi r14, r1, PT_PC
    + lwi r13, r1, PT_R13
    + lwi r12, r1, PT_R12
    + lwi r11, r1, PT_R11
    + lwi r10, r1, PT_R10
    + lwi r9, r1, PT_R9
    + lwi r8, r1, PT_R8
    + lwi r7, r1, PT_R7
    + lwi r6, r1, PT_R6
    + lwi r5, r1, PT_R5
    + lwi r4, r1, PT_R4 /* return val */
    + lwi r3, r1, PT_R3 /* return val */
    + lwi r2, r1, PT_R2
    + lwi r1, r1, PT_R1
    +
    + rtid r14, 0
    + nop
    +
    +sys_vfork_wrapper:
    + brid sys_vfork
    + addk r5, r1, r0
    +
    +sys_clone_wrapper:
    + brid sys_clone
    + addk r7, r1, r0
    +
    +sys_execve_wrapper:
    + brid sys_execve
    + addk r8, r1, r0
    +
    +sys_sigreturn_wrapper:
    + brid sys_sigreturn
    + addk r5, r1, r0
    +
    +sys_rt_sigreturn_wrapper:
    + brid sys_rt_sigreturn
    + addk r5, r1, r0
    +
    +sys_sigsuspend_wrapper:
    + brid sys_rt_sigsuspend
    + addk r6, r1, r0
    +
    +sys_rt_sigsuspend_wrapper:
    + brid sys_rt_sigsuspend
    + addk r7, r1, r0
    +
    + /* Interrupt vector table */
    + .section .init.ivt, "ax"
    + .org 0x0
    + brai _reset
    + brai _user_exception
    + brai _interrupt
    + brai _break
    + brai _hw_exception_handler
    + .org 0x60
    + brai _debug_exception
    +
    +.section .rodata,"a"
    +#include "syscall_table.S"
    +
    +syscall_table_size=(.-sys_call_table)
    diff --git a/arch/microblaze/kernel/head.S b/arch/microblaze/kernel/head.S
    new file mode 100644
    index 0000000..8ca148b
    --- /dev/null
    +++ b/arch/microblaze/kernel/head.S
    @@ -0,0 +1,40 @@
    +/*
    + * arch/microblaze/kernel/head.S
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2007 Michal Simek
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +#include
    +#include
    +
    + .text
    +ENTRY(_start)
    + mfs r1, rmsr
    + andi r1, r1, ~2
    + mts rmsr, r1
    +
    + /* Initialize small data anchors */
    + la r13, r0, _KERNEL_SDA_BASE_
    + la r2, r0, _KERNEL_SDA2_BASE_
    +
    + /* Initialize stack pointer */
    + la r1, r0, init_thread_union + THREAD_SIZE - 4
    +
    + /* Initialize r31 with current task address */
    + la r31, r0, init_task
    +
    + /* Call platform dependent initialize function.
    + * Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
    + * the function. */
    + la r8, r0, machine_early_init
    + brald r15, r8
    + nop
    +
    + la r15, r0, machine_halt
    + braid start_kernel
    + nop
    diff --git a/arch/microblaze/kernel/syscall_table.S b/arch/microblaze/kernel/syscall_table.S
    new file mode 100644
    index 0000000..3ff41f8
    --- /dev/null
    +++ b/arch/microblaze/kernel/syscall_table.S
    @@ -0,0 +1,328 @@
    +ENTRY(sys_call_table)
    + .long sys_restart_syscall /* 0 - old "setup()" system call,
    + * used for restarting */
    + .long sys_exit
    + .long sys_ni_syscall /* was fork */
    + .long sys_read
    + .long sys_write
    + .long sys_open /* 5 */
    + .long sys_close
    + .long sys_waitpid
    + .long sys_creat
    + .long sys_link
    + .long sys_unlink /* 10 */
    + .long sys_execve_wrapper
    + .long sys_chdir
    + .long sys_time
    + .long sys_mknod
    + .long sys_chmod /* 15 */
    + .long sys_lchown16
    + .long sys_ni_syscall /* old break syscall holder */
    + .long sys_ni_syscall /* stat */
    + .long sys_lseek
    + .long sys_getpid /* 20 */
    + .long sys_mount
    + .long sys_oldumount
    + .long sys_setuid16
    + .long sys_getuid16
    + .long sys_stime /* 25 */
    + .long sys_ptrace
    + .long sys_alarm
    + .long sys_ni_syscall /* fstat */
    + .long sys_pause
    + .long sys_utime /* 30 */
    + .long sys_ni_syscall /* old stty syscall holder */
    + .long sys_ni_syscall /* old gtty syscall holder */
    + .long sys_access
    + .long sys_nice
    + .long sys_ni_syscall /* 35 - old ftime syscall holder */
    + .long sys_sync
    + .long sys_kill
    + .long sys_rename
    + .long sys_mkdir
    + .long sys_rmdir /* 40 */
    + .long sys_dup
    + .long sys_pipe
    + .long sys_times
    + .long sys_ni_syscall /* old prof syscall holder */
    + .long sys_brk /* 45 */
    + .long sys_setgid16
    + .long sys_getgid16
    + .long sys_signal
    + .long sys_geteuid16
    + .long sys_getegid16 /* 50 */
    + .long sys_acct
    + .long sys_umount /* recycled never used phys() */
    + .long sys_ni_syscall /* old lock syscall holder */
    + .long sys_ioctl
    + .long sys_fcntl /* 55 */
    + .long sys_ni_syscall /* old mpx syscall holder */
    + .long sys_setpgid
    + .long sys_ni_syscall /* old ulimit syscall holder */
    + .long sys_ni_syscall /* olduname */
    + .long sys_umask /* 60 */
    + .long sys_chroot
    + .long sys_ustat
    + .long sys_dup2
    + .long sys_getppid
    + .long sys_getpgrp /* 65 */
    + .long sys_setsid
    + .long sys_sigaction
    + .long sys_sgetmask
    + .long sys_ssetmask
    + .long sys_setreuid16 /* 70 */
    + .long sys_setregid16
    + .long sys_sigsuspend_wrapper
    + .long sys_sigpending
    + .long sys_sethostname
    + .long sys_setrlimit /* 75 */
    + .long sys_ni_syscall /* old_getrlimit */
    + .long sys_getrusage
    + .long sys_gettimeofday
    + .long sys_settimeofday
    + .long sys_getgroups16 /* 80 */
    + .long sys_setgroups16
    + .long sys_ni_syscall /* old_select */
    + .long sys_symlink
    + .long sys_ni_syscall /* lstat */
    + .long sys_readlink /* 85 */
    + .long sys_uselib
    + .long sys_swapon
    + .long sys_reboot
    + .long sys_ni_syscall /* old_readdir */
    + .long sys_mmap /* 90 */ /* old_mmap */
    + .long sys_munmap
    + .long sys_truncate
    + .long sys_ftruncate
    + .long sys_fchmod
    + .long sys_fchown16 /* 95 */
    + .long sys_getpriority
    + .long sys_setpriority
    + .long sys_ni_syscall /* old profil syscall holder */
    + .long sys_statfs
    + .long sys_fstatfs /* 100 */
    + .long sys_ni_syscall /* ioperm */
    + .long sys_socketcall
    + .long sys_syslog
    + .long sys_setitimer
    + .long sys_getitimer /* 105 */
    + .long sys_newstat
    + .long sys_newlstat
    + .long sys_newfstat
    + .long sys_ni_syscall /* uname */
    + .long sys_ni_syscall /* 110 */ /* iopl */
    + .long sys_vhangup
    + .long sys_ni_syscall /* old "idle" system call */
    + .long sys_ni_syscall /* old sys_vm86old */
    + .long sys_wait4
    + .long sys_swapoff /* 115 */
    + .long sys_sysinfo
    + .long sys_ipc
    + .long sys_fsync
    + .long sys_sigreturn_wrapper
    + .long sys_clone_wrapper /* 120 */
    + .long sys_setdomainname
    + .long sys_newuname
    + .long sys_ni_syscall /* modify_ldt */
    + .long sys_adjtimex
    + .long sys_ni_syscall /* 125: sys_mprotect */
    + .long sys_sigprocmask
    + .long sys_ni_syscall /* old "create_module" */
    + .long sys_init_module
    + .long sys_delete_module
    + .long sys_ni_syscall /* 130: old "get_kernel_syms" */
    + .long sys_quotactl
    + .long sys_getpgid
    + .long sys_fchdir
    + .long sys_bdflush
    + .long sys_sysfs /* 135 */
    + .long sys_personality
    + .long sys_ni_syscall /* reserved for afs_syscall */
    + .long sys_setfsuid16
    + .long sys_setfsgid16
    + .long sys_llseek /* 140 */
    + .long sys_getdents
    + .long sys_select
    + .long sys_flock
    + .long sys_ni_syscall /* sys_msync */
    + .long sys_readv /* 145 */
    + .long sys_writev
    + .long sys_getsid
    + .long sys_fdatasync
    + .long sys_sysctl
    + .long sys_ni_syscall /* 150: sys_mlock */
    + .long sys_ni_syscall /* sys_munlock */
    + .long sys_ni_syscall /* sys_mlockall */
    + .long sys_ni_syscall /* sys_munlockall */
    + .long sys_sched_setparam
    + .long sys_sched_getparam /* 155 */
    + .long sys_sched_setscheduler
    + .long sys_sched_getscheduler
    + .long sys_sched_yield
    + .long sys_sched_get_priority_max
    + .long sys_sched_get_priority_min /* 160 */
    + .long sys_sched_rr_get_interval
    + .long sys_nanosleep
    + .long sys_ni_syscall /* sys_mremap */
    + .long sys_setresuid16
    + .long sys_getresuid16 /* 165 */
    + .long sys_ni_syscall /* sys_vm86 */
    + .long sys_ni_syscall /* Old sys_query_module */
    + .long sys_poll
    + .long sys_nfsservctl
    + .long sys_setresgid16 /* 170 */
    + .long sys_getresgid16
    + .long sys_prctl
    + .long sys_rt_sigreturn_wrapper
    + .long sys_rt_sigaction
    + .long sys_rt_sigprocmask /* 175 */
    + .long sys_rt_sigpending
    + .long sys_rt_sigtimedwait
    + .long sys_rt_sigqueueinfo
    + .long sys_rt_sigsuspend_wrapper
    + .long sys_pread64 /* 180 */
    + .long sys_pwrite64
    + .long sys_chown16
    + .long sys_getcwd
    + .long sys_capget
    + .long sys_capset /* 185 */
    + .long sys_ni_syscall /* sigaltstack */
    + .long sys_sendfile
    + .long sys_ni_syscall /* reserved for streams1 */
    + .long sys_ni_syscall /* reserved for streams2 */
    + .long sys_vfork_wrapper /* 190 */
    + .long sys_getrlimit
    + .long sys_mmap2 /* mmap2 */
    + .long sys_truncate64
    + .long sys_ftruncate64
    + .long sys_stat64 /* 195 */
    + .long sys_lstat64
    + .long sys_fstat64
    + .long sys_lchown
    + .long sys_getuid
    + .long sys_getgid /* 200 */
    + .long sys_geteuid
    + .long sys_getegid
    + .long sys_setreuid
    + .long sys_setregid
    + .long sys_getgroups /* 205 */
    + .long sys_setgroups
    + .long sys_fchown
    + .long sys_setresuid
    + .long sys_getresuid
    + .long sys_setresgid /* 210 */
    + .long sys_getresgid
    + .long sys_chown
    + .long sys_setuid
    + .long sys_setgid
    + .long sys_setfsuid /* 215 */
    + .long sys_setfsgid
    + .long sys_pivot_root
    + .long sys_ni_syscall /* sys_mincore */
    + .long sys_ni_syscall /* sys_madvise */
    + .long sys_getdents64 /* 220 */
    + .long sys_fcntl64
    + .long sys_ni_syscall /* reserved for TUX */
    + .long sys_ni_syscall
    + .long sys_gettid
    + .long sys_readahead /* 225 */
    + .long sys_setxattr
    + .long sys_lsetxattr
    + .long sys_fsetxattr
    + .long sys_getxattr
    + .long sys_lgetxattr /* 230 */
    + .long sys_fgetxattr
    + .long sys_listxattr
    + .long sys_llistxattr
    + .long sys_flistxattr
    + .long sys_removexattr /* 235 */
    + .long sys_lremovexattr
    + .long sys_fremovexattr
    + .long sys_tkill
    + .long sys_sendfile64
    + .long sys_futex /* 240 */
    + .long sys_sched_setaffinity
    + .long sys_sched_getaffinity
    + .long sys_ni_syscall /* set_thread_area */
    + .long sys_ni_syscall /* get_thread_area */
    + .long sys_io_setup /* 245 */
    + .long sys_io_destroy
    + .long sys_io_getevents
    + .long sys_io_submit
    + .long sys_io_cancel
    + .long sys_fadvise64 /* 250 */
    + .long sys_ni_syscall
    + .long sys_exit_group
    + .long sys_lookup_dcookie
    + .long sys_epoll_create
    + .long sys_epoll_ctl /* 255 */
    + .long sys_epoll_wait
    + .long sys_ni_syscall /* sys_remap_file_pages */
    + .long sys_set_tid_address
    + .long sys_timer_create
    + .long sys_timer_settime /* 260 */
    + .long sys_timer_gettime
    + .long sys_timer_getoverrun
    + .long sys_timer_delete
    + .long sys_clock_settime
    + .long sys_clock_gettime /* 265 */
    + .long sys_clock_getres
    + .long sys_clock_nanosleep
    + .long sys_statfs64
    + .long sys_fstatfs64
    + .long sys_tgkill /* 270 */
    + .long sys_utimes
    + .long sys_fadvise64_64
    + .long sys_ni_syscall /* sys_vserver */
    + .long sys_mbind
    + .long sys_get_mempolicy
    + .long sys_set_mempolicy
    + .long sys_mq_open
    + .long sys_mq_unlink
    + .long sys_mq_timedsend
    + .long sys_mq_timedreceive /* 280 */
    + .long sys_mq_notify
    + .long sys_mq_getsetattr
    + .long sys_kexec_load
    + .long sys_waitid
    + .long sys_ni_syscall /* 285 */ /* available */
    + .long sys_add_key
    + .long sys_request_key
    + .long sys_keyctl
    + .long sys_ioprio_set
    + .long sys_ioprio_get /* 290 */
    + .long sys_inotify_init
    + .long sys_inotify_add_watch
    + .long sys_inotify_rm_watch
    + .long sys_ni_syscall /* sys_migrate_pages */
    + .long sys_ni_syscall /* 295 */ /* sys_openat */
    + .long sys_ni_syscall /* sys_mkdirat */
    + .long sys_ni_syscall /* sys_mknodat */
    + .long sys_ni_syscall /* sys_fchownat */
    + .long sys_ni_syscall /* sys_futimesat */
    + .long sys_ni_syscall /* 300 */ /* sys_fstatat64 */
    + .long sys_ni_syscall /* sys_unlinkat */
    + .long sys_ni_syscall /* sys_renameat */
    + .long sys_ni_syscall /* sys_linkat */
    + .long sys_ni_syscall /* sys_symlinkat */
    + .long sys_ni_syscall /* 305 */ /* sys_readlinkat */
    + .long sys_ni_syscall /* sys_fchmodat */
    + .long sys_ni_syscall /* sys_faccessat */
    + .long sys_ni_syscall /* pselect6 */
    + .long sys_ni_syscall /* ppoll */
    + .long sys_ni_syscall /* 310 */ /* sys_unshare */
    + .long sys_ni_syscall /* sys_set_robust_list */
    + .long sys_ni_syscall /* sys_get_robust_list */
    + .long sys_ni_syscall /* sys_splice */
    + .long sys_ni_syscall /* sys_sync_file_range */
    + .long sys_ni_syscall /* 315 */ /* sys_tee */
    + .long sys_ni_syscall /* sys_vmsplice */
    + .long sys_move_pages
    + .long sys_getcpu
    + .long sys_epoll_pwait
    + .long sys_utimensat /* 320 */
    + .long sys_signalfd
    + .long sys_timerfd
    + .long sys_eventfd
    + .long sys_fallocate
    +
    diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S
    new file mode 100644
    index 0000000..8940f1f
    --- /dev/null
    +++ b/arch/microblaze/kernel/vmlinux.lds.S
    @@ -0,0 +1,145 @@
    +/*
    + * arch/microblaze/kernel/vmlinux.lds.S
    + *
    + * This file is subject to the terms and conditions of the GNU General Public
    + * License. See the file "COPYING" in the main directory of this archive
    + * for more details.
    + *
    + * Copyright (C) 2006 Atmark Techno, Inc.
    + */
    +
    +OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
    +OUTPUT_ARCH(microblaze)
    +ENTRY(_start)
    +
    +#include
    +#include
    +
    +jiffies = jiffies_64 + 4;
    +
    +SECTIONS {
    + . = CONFIG_KERNEL_BASE_ADDR;
    +
    + .text : {
    + _text = . ;
    + _stext = . ;
    + TEXT_TEXT
    + SCHED_TEXT
    + LOCK_TEXT
    + . = ALIGN (4) ;
    + _etext = . ;
    + }
    +
    + . = ALIGN(16);
    + RODATA
    +
    + /* sdata2 section can go anywhere, but must be word aligned
    + and SDA2_BASE must point to the middle of it */
    + .sdata2 : {
    + _ssrw = .;
    + . = ALIGN(0x8);
    + *(.sdata2)
    + . = ALIGN(8);
    + _essrw = .;
    + _ssrw_size = _essrw - _ssrw;
    + _KERNEL_SDA2_BASE_ = _ssrw + (_ssrw_size / 2);
    + }
    +
    + _sdata = . ;
    + .data ALIGN (0x4) : {
    + DATA_DATA
    + }
    + . = ALIGN(32);
    + .data.cacheline_aligned : { *(.data.cacheline_aligned) }
    + _edata = . ;
    +
    + /* The initial task */
    + . = ALIGN(8192);
    + .data.init_task : { *(.data.init_task) }
    +
    + /* Under the microblaze ABI, .sdata and .sbss must be contiguous */
    + . = ALIGN(8);
    + .sdata : {
    + _ssro = .;
    + *(.sdata)
    + }
    +
    + .sbss : {
    + _ssbss = .;
    + *(.sbss)
    + _esbss = .;
    + _essro = .;
    + _ssro_size = _essro - _ssro ;
    + _KERNEL_SDA_BASE_ = _ssro + (_ssro_size / 2) ;
    + }
    +
    + . = ALIGN(16);
    + __start___ex_table = .;
    + __ex_table : { *(__ex_table) }
    + __stop___ex_table = .;
    +
    + __init_begin = .;
    +
    + . = ALIGN(4096);
    + .init.text : {
    + _sinittext = . ;
    + *(.init.text)
    + *(.exit.text)
    + *(.exit.data)
    + _einittext = .;
    + }
    +
    + .init.data : { *(.init.data) }
    +
    + . = ALIGN(4);
    + .init.ivt : {
    + __ivt_start = .;
    + *(.init.ivt)
    + __ivt_end = .;
    + }
    +
    + .init.setup : {
    + __setup_start = .;
    + *(.init.setup)
    + __setup_end = .;
    + }
    +
    + .initcall.init : {
    + __initcall_start = .;
    + INITCALLS
    + __initcall_end = .;
    + }
    +
    + .con_initcall.init : {
    + __con_initcall_start = .;
    + *(.con_initcall.init)
    + __con_initcall_end = .;
    + }
    +
    + __init_end_before_initramfs = .;
    +
    + .init.ramfs ALIGN(4096) : {
    + __initramfs_start = .;
    + *(.init.ramfs)
    + __initramfs_end = .;
    + . = ALIGN(4);
    + LONG(0);
    + . = ALIGN(4096);/* Pad init.ramfs up to page boundary, so
    + that __init_end == __bss_start. This will
    + make image.elf consistent with the image.bin */
    + }
    +
    + __init_end = .;
    +
    + .bss ALIGN (4096) : {
    + __bss_start = . ;
    + *(.bss*)
    + *(COMMON)
    + . = ALIGN (4) ;
    + __bss_stop = . ;
    + _ebss = . ;
    + }
    + . = ALIGN(4096);
    + _end = .;
    +}
    +
    --
    1.5.4.rc4.14.g6fc74

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  13. Re: [PATCH 11/52] [microblaze] kernel modules support


    On Jan 24 2008 16:02, monstr@monstr.eu wrote:
    >+
    >+/* module handling */
    >+EXPORT_SYMBOL(PAGE_OFFSET);


    This looks really ugly. PAGE_OFFSET is usually a macro.
    I looked in patch 29/52 where PAGE_OFFSET is defined (unsigned int
    PAGE_OFFSET), which got me wondered: PAGE_OFFSET can be a runtime
    variable when it is a constant on most other arches?

    That being said, I'd use

    #define PAGE_OFFSET __page_offset

    in some header file and in the .c file:

    unsigned int __page_offset;
    EXPORT_SYMBOL(__page_offset);

    that is how arch-frv and -uml seem to do it.

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  14. Re: [PATCH 17/52] [microblaze] checksum support

    On Thu, 24 Jan 2008, monstr@monstr.eu wrote:
    > From: Michal Simek
    >
    >
    > Signed-off-by: Michal Simek
    > ---
    > arch/microblaze/lib/checksum.c | 159 +++++++++++++++++++++++++++++++++++++
    > include/asm-microblaze/checksum.h | 101 +++++++++++++++++++++++
    > 2 files changed, 260 insertions(+), 0 deletions(-)
    > create mode 100644 arch/microblaze/lib/checksum.c
    > create mode 100644 include/asm-microblaze/checksum.h
    >
    > diff --git a/arch/microblaze/lib/checksum.c b/arch/microblaze/lib/checksum.c
    > new file mode 100644
    > index 0000000..21a6830
    > --- /dev/null
    > +++ b/arch/microblaze/lib/checksum.c
    > @@ -0,0 +1,159 @@
    > +/*
    > + * INET An implementation of the TCP/IP protocol suite for the LINUX
    > + * operating system. INET is implemented using the BSD Socket
    > + * interface as the means of communication with the user level.
    > + *
    > + * IP/TCP/UDP checksumming routines
    > + *
    > + * Authors: Jorge Cwik,
    > + * Arnt Gulbrandsen,
    > + * Tom May,
    > + * Andreas Schwab,
    > + * Lots of code moved from tcp.c and ip.c; see those files
    > + * for more names.
    > + *
    > + * 03/02/96 Jes Sorensen, Andreas Schwab, Roman Hodek:
    > + * Fixed some nasty bugs, causing some horrible crashes.
    > + * A: At some points, the sum (%0) was used as
    > + * length-counter instead of the length counter
    > + * (%1). Thanks to Roman Hodek for pointing this out.
    > + * B: GCC seems to mess up if one uses too many
    > + * data-registers to hold input values and one tries to
    > + * specify d0 and d1 as scratch registers. Letting gcc choose these
    > + * registers itself solves the problem.
    > + *
    > + * This program is free software; you can redistribute it and/or
    > + * modify it under the terms of the GNU General Public License
    > + * as published by the Free Software Foundation; either version
    > + * 2 of the License, or (at your option) any later version.
    > + */
    > +
    > +/* Revised by Kenneth Albanowski for m68knommu. Basic problem: unaligned access
    > + kills, so most of the assembly has to go. */


    So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
    checkpatch.pl fixes but without the sparse fixes?
    Furthermore, it's just plain C, so maybe we need a common one that can
    be shared by multiple archs?

    Gr{oetje,eeting}s,

    Geert

    --
    Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

    In personal conversations with technical people, I call myself a hacker. But
    when I'm talking to journalists I just say "programmer" or something like that.
    -- Linus Torvalds
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  15. Re: Microblaze init port

    On Thu, 24 Jan 2008, monstr@monstr.eu wrote:
    > I personally feel the biggest pain in header files.


    26, 32, and 48 gave false positives in raising my interest :-)

    + * The user_ipc_perm structure for m68k architecture.
    + * The msqid64_ds structure for m68k architecture.
    + * The shmid64_ds structure for m68k architecture.
    + * The semid64_ds structure for m68k architecture.

    Gr{oetje,eeting}s,

    Geert

    --
    Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

    In personal conversations with technical people, I call myself a hacker. But
    when I'm talking to journalists I just say "programmer" or something like that.
    -- Linus Torvalds
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  16. Re: [PATCH 12/52] [microblaze] lmb support


    On Jan 24 2008 16:02, monstr@monstr.eu wrote:
    >+
    >+#define DEBUG
    >+
    >+#ifdef DEBUG
    >+#define DBG(fmt...) printk(fmt)
    >+#else
    >+#define DBG(fmt...)
    >+#endif


    Phew, don't reinvent the wheel - use the existing pr_debug() instead.


    >+static unsigned long __init lmb_addrs_overlap(unsigned long base1,
    >+ unsigned long size1, unsigned long base2, unsigned long size2)
    >+{
    >+ return ((base1 < (base2+size2)) && (base2 < (base1+size1)));

    return base1 < base2 + size2 && base2 < base1 + size1;
    >+}


    Operator precedence makes it possible; you could omit a lot of () in the code.
    (Also try checkpatch.pl to get to know of other style 'errors')
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  17. Re: [PATCH 03/52] [microblaze] Cpuinfo handling


    On Jan 24 2008 16:03, monstr@monstr.eu wrote:
    >+
    >+static char family_string[] = CONFIG_XILINX_MICROBLAZE0_FAMILY;
    >+static char cpu_ver_string[] = CONFIG_XILINX_MICROBLAZE0_HW_VER;
    >+

    I have not checked - can mark these const?



    >--- /dev/null
    >+++ b/arch/microblaze/kernel/cpu/cpuinfo.c
    >+
    >+static struct cpuinfo the_cpuinfo;
    >+struct cpuinfo *cpuinfo = &the_cpuinfo;


    Why is this indirection needed?

    >+static struct cpu_ver_key the_cpu_ver_lookup[] = {

    ^const?

    >+ /* These key value are as per MBV field in PVR0 */
    >+ {"5.00.a", 0x01},
    >+ {"5.00.b", 0x02},
    >+ {"5.00.c", 0x03},
    >+ {"6.00.a", 0x04},
    >+ {"6.00.b", 0x06},
    >+ {"7.00.a", 0x05},
    >+ /* FIXME There is no keycode defined in MBV for these versions */
    >+ {"2.10.a", 0x10},
    >+ {"3.00.a", 0x20},
    >+ {"4.00.a", 0x30},
    >+ {"4.00.b", 0x40},
    >+ {NULL, 0},
    >+};
    >+struct cpu_ver_key *cpu_ver_lookup =
    >+ (struct cpu_ver_key *) the_cpu_ver_lookup;


    Again an indirection. And the case, you guessed it, is redundant
    (check other code too).

    >+/*
    >+ * FIXME Not sure if the actual key is defined by Xilinx in the PVR
    >+ */
    >+static struct family_string_key the_family_string_lookup[] = {

    const?

    >+ {"virtex2", 0x4},
    >+ {"virtex2pro", 0x5},
    >+ {"spartan3", 0x6},
    >+ {"virtex4", 0x7},
    >+ {"virtex5", 0x8},
    >+ {"spartan3e", 0x9},
    >+ {"spartan3a", 0xa},
    >+ {"spartan3an", 0xb},
    >+ /* FIXME There is no key code defined for spartan2 */
    >+ {"spartan2", 0xf0},
    >+ {NULL, 0},
    >+};
    >+struct family_string_key *family_string_lookup =
    >+ (struct family_string_key *) the_family_string_lookup;


    Dito.


    >+#ifndef _ASM_CPUINFO_H
    >+#define _ASM_CPUINFO_H
    >+
    >+#include
    >+
    >+extern unsigned long loops_per_jiffy;
    >+
    >+/* CPU Version and FPGA Family code conversion table type */
    >+struct cpu_ver_key {
    >+ char *s;

    const char *s; if you never modify s.

    >+ unsigned k;
    >+};
    >+
    >+struct family_string_key {
    >+ char *s;

    Dito.

    >+ unsigned k;
    >+};
    >+

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  18. Re: [PATCH 17/52] [microblaze] checksum support

    Hi Geert,
    > So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
    > checkpatch.pl fixes but without the sparse fixes?
    > Furthermore, it's just plain C, so maybe we need a common one that can
    > be shared by multiple archs?
    >
    > Gr{oetje,eeting}s,
    > Geert
    >

    I have no sparse errors and warning in checksum.c file.

    Michal Simek
    www.monstr.eu
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  19. Re: [PATCH 17/52] [microblaze] checksum support

    On Sun, 27 Jan 2008, Michal Simek wrote:
    > > So basically this is a copy of arch/m68knommu/lib/checksum.c, with some
    > > checkpatch.pl fixes but without the sparse fixes?
    > > Furthermore, it's just plain C, so maybe we need a common one that can
    > > be shared by multiple archs?
    > >

    >
    > I have no sparse errors and warning in checksum.c file.


    How come csum_partial_copy_from_user() in arch/m68knommu/lib/checksum.c
    has a __user attribute on the src parameter, while yours doesn't?

    Gr{oetje,eeting}s,

    Geert

    --
    Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

    In personal conversations with technical people, I call myself a hacker. But
    when I'm talking to journalists I just say "programmer" or something like that.
    -- Linus Torvalds
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  20. Re: [PATCH 16/52] [microblaze] supported function for memory - kernel/lib


    On Jan 24 2008 16:02, monstr@monstr.eu wrote:
    >diff --git a/arch/microblaze/lib/memcpy.c b/arch/microblaze/lib/memcpy.c
    >new file mode 100644
    >index 0000000..cc13ebd
    >--- /dev/null
    >+++ b/arch/microblaze/lib/memcpy.c
    >@@ -0,0 +1,159 @@
    >+/* Filename: memcpy.c
    >+ *


    Please, no such filenames in files. It is redundant and hard to keep
    uptodate, should things move at one point in time.

    >+#define BYTE_BLIT_STEP(d, s, h, o) \
    >+ { register unsigned _v_; _v_ = *((unsigned *)(s))++; \
    >+ *((unsigned *)(d))++ = (h) | _v_ >> (32-(o)); \
    >+ (h) = _v_ << (o); \
    >+ }


    'register' is a relict from 30 years ago. Compilers likely ignore it
    these days, so it can jsut be removed anyway.

    >+ /* This code was put into place as we transitioned from gcc3 to gcc4.
    >+ * gcc4 does not support the syntax *((char *)d)++ which causes the


    Of course not, because (char *)d is not an lvalue - and if you ask
    me, it is ambiguous and bogus code.

    Assuming 'd' was int*, d++ would cause it to be incremented by 4.

    If you incremented 'd' with char* semantics, it would be incremented
    by 1. But since 'd' is still int*, you now have an unaligned pointer,
    which is a problem in itself. We do not need more pitfalls than C
    already provides.

    >+ if (c >= 4) {
    >+ unsigned x, a, h, align;


    You will be wanting to use unsigned long since you are working with
    pointers.

    >+ /* Align the destination to a word boundry. */
    >+ /* This is done in an endian independant manner. */
    >+ switch ((unsigned) d & 3) {
    >+ case 1:
    >+ *((char *) d)++ = *((char *) s)++;
    >+ c--;
    >+ case 2:
    >+ *((char *) d)++ = *((char *) s)++;
    >+ c--;
    >+ case 3:
    >+ *((char *) d)++ = *((char *) s)++;
    >+ c--;
    >+ }


    This gets my strongest NAK. Please rewrite it in a sane manner.
    In other words, like this:

    +void *memcpy(void *v_dest, const void *v_src, __kernel_size_t c)
    +{
    + const char *src = v_src;
    + char *dest = v_dest;
    +
    + const uint32_t *i_src;
    + uint32_t *i_dest;
    +
    + if (c >= 4) {
    + unsigned x, a, h, align;
    +
    + /* Align the destination to a word boundry. */
    + /* This is done in an endian independant manner. */
    + switch ((unsigned long)dest & 3) {
    + case 1:
    + *dest++ = *src++;
    + --c;
    + case 2:
    + *dest++ = *src++;
    + --c;
    + case 3:
    + *dest++ = *src++;
    + --c;
    + }
    + /* Choose a copy scheme based on the source */
    + /* alignment relative to destination. */
    + switch ((unsigned long)src & 3) {
    + case 0x0: /* Both byte offsets are aligned */
    +
    + i_src = (const void *)src;
    + i_dest = (void *)dest;
    +
    + for (; c >= 4; c -= 4)
    + *i_dest++ = *i_src++;
    +
    + src = (const void *)i_src;
    + dest = (void *)i_dest;
    +
    + break;
    +
    + case 0x1: /* Unaligned - Off by 1 */
    ...

    The BYTE_BLIT_ macros need reworking. The suggestions
    so far should provide everything needed.

    + }
    +
    + }
    +
    + /* Finish off any remaining bytes */
    + /* simple fast copy, ... unless a cache boundry is crossed */
    + switch (c) {
    + case 3:
    + *dest++ = *src++;
    + case 2:
    + *dest++ = *src++;
    + case 1:
    + *dest++ = *src++;
    + }
    +
    + return r;
    +#endif
    +}

    - and voilĂ*, you can use it even with gcc4.
    The same goes for memmove.c and memset.c.

    By the way, I think you should just replace lib/string.c's memcpy,
    etc. (which still do per-byte copying) with this optimized variant
    instead, so everyone can benefit.
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread
Page 2 of 3 FirstFirst 1 2 3 LastLast