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

* 'next' of git://git.monstr.eu/linux-2.6-microblaze: (33 commits)
  microblaze: Do not copy reset vectors/manual reset vector setup
  microblaze: Fix _reset function
  microblaze: Fix microblaze init vectors
  microblaze: Fix circular headers dependency when ftrace is enabled.
  microblaze: Fix typo in Kconfig
  microblaze: Add missing export symbols for lib functions
  microblaze: Fix /dev/zero corruption from __clear_user()
  microblaze: Convert irq_chip to new functions
  microblaze: Select GENERIC_HARDIRQS_NO_DEPRECATED
  microblaze: Remove stale irq_chip.end
  microblaze: Fix sparse warnings - signal.c
  microblaze: Fix sparse warning - fault.c
  microblaze: Fix missing microblaze specific syscalls declaration
  microblaze: Fix sparse warnings - cache.c
  microblaze: Fix sparse warning - cpuinfo.h
  microblaze: Fix sparse warning - unwind.c
  microblaze: Fix sparse warning - consistent_alloc function
  microblaze: Fix sparse warnings - ptrace
  microblaze: Fix sparse warning - sw_exceptions
  microblaze: Fix sparse warning - timer.c
  ...
This commit is contained in:
Linus Torvalds 2011-03-16 10:48:16 -07:00
Родитель 1fd06bb157 0b9b0200b0
Коммит 51e8703bdf
36 изменённых файлов: 347 добавлений и 317 удалений

Просмотреть файл

@ -17,6 +17,7 @@ config MICROBLAZE
select OF_EARLY_FLATTREE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_HARDIRQS_NO_DEPRECATED
config SWAP
def_bool n
@ -183,6 +184,17 @@ config LOWMEM_SIZE
hex "Maximum low memory size (in bytes)" if LOWMEM_SIZE_BOOL
default "0x30000000"
config MANUAL_RESET_VECTOR
hex "Microblaze reset vector address setup"
default "0x0"
help
Set this option to have the kernel override the CPU Reset vector.
If zero, no change will be made to the MicroBlaze reset vector at
address 0x0.
If non-zero, a jump instruction to this address, will be written
to the reset vector at address 0x0.
If you are unsure, set it to default value 0x0.
config KERNEL_START_BOOL
bool "Set custom kernel base address"
depends on ADVANCED_OPTIONS
@ -247,7 +259,7 @@ endmenu
source "mm/Kconfig"
menu "Exectuable file formats"
menu "Executable file formats"
source "fs/Kconfig.binfmt"

Просмотреть файл

@ -84,12 +84,13 @@ do { \
#define flush_dcache_mmap_lock(mapping) do { } while (0)
#define flush_dcache_mmap_unlock(mapping) do { } while (0)
#define flush_cache_dup_mm(mm) do { } while (0)
#define flush_cache_vmap(start, end) do { } while (0)
#define flush_cache_vunmap(start, end) do { } while (0)
#define flush_cache_mm(mm) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) do { } while (0)
#define flush_cache_page(vma, vmaddr, pfn) \
flush_dcache_range(pfn << PAGE_SHIFT, (pfn << PAGE_SHIFT) + PAGE_SIZE);
/* MS: kgdb code use this macro, wrong len with FLASH */
#if 0
@ -104,9 +105,13 @@ do { \
#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
do { \
u32 addr = virt_to_phys(dst); \
invalidate_icache_range((unsigned) (addr), (unsigned) (addr) + (len));\
memcpy((dst), (src), (len)); \
flush_dcache_range((unsigned) (addr), (unsigned) (addr) + (len));\
if (vma->vm_flags & VM_EXEC) { \
invalidate_icache_range((unsigned) (addr), \
(unsigned) (addr) + PAGE_SIZE); \
flush_dcache_range((unsigned) (addr), \
(unsigned) (addr) + PAGE_SIZE); \
} \
} while (0)
#define copy_from_user_page(vma, page, vaddr, dst, src, len) \

Просмотреть файл

@ -96,8 +96,8 @@ void set_cpuinfo_pvr_full(struct cpuinfo *ci, struct device_node *cpu);
static inline unsigned int fcpu(struct device_node *cpu, char *n)
{
int *val;
return (val = (int *) of_get_property(cpu, n, NULL)) ?
const __be32 *val;
return (val = of_get_property(cpu, n, NULL)) ?
be32_to_cpup(val) : 0;
}

Просмотреть файл

@ -31,40 +31,4 @@ DECLARE_PER_CPU(unsigned int, R11_SAVE); /* Temp variable for entry */
DECLARE_PER_CPU(unsigned int, CURRENT_SAVE); /* Saved current pointer */
# endif /* __ASSEMBLY__ */
#ifndef CONFIG_MMU
/* noMMU hasn't any space for args */
# define STATE_SAVE_ARG_SPACE (0)
#else /* CONFIG_MMU */
/* If true, system calls save and restore all registers (except result
* registers, of course). If false, then `call clobbered' registers
* will not be preserved, on the theory that system calls are basically
* function calls anyway, and the caller should be able to deal with it.
* This is a security risk, of course, as `internal' values may leak out
* after a system call, but that certainly doesn't matter very much for
* a processor with no MMU protection! For a protected-mode kernel, it
* would be faster to just zero those registers before returning.
*
* I can not rely on the glibc implementation. If you turn it off make
* sure that r11/r12 is saved in user-space. --KAA
*
* These are special variables using by the kernel trap/interrupt code
* to save registers in, at a time when there are no spare registers we
* can use to do so, and we can't depend on the value of the stack
* pointer. This means that they must be within a signed 16-bit
* displacement of 0x00000000.
*/
/* A `state save frame' is a struct pt_regs preceded by some extra space
* suitable for a function call stack frame. */
/* Amount of room on the stack reserved for arguments and to satisfy the
* C calling conventions, in addition to the space used by the struct
* pt_regs that actually holds saved values. */
#define STATE_SAVE_ARG_SPACE (6*4) /* Up to six arguments */
#endif /* CONFIG_MMU */
#endif /* _ASM_MICROBLAZE_ENTRY_H */

Просмотреть файл

@ -66,6 +66,9 @@
asmlinkage void full_exception(struct pt_regs *regs, unsigned int type,
int fsr, int addr);
asmlinkage void sw_exception(struct pt_regs *regs);
void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig);
void die(const char *str, struct pt_regs *fp, long err);
void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr);

Просмотреть файл

@ -12,8 +12,6 @@
#define NR_IRQS 32
#include <asm-generic/irq.h>
#include <linux/interrupt.h>
/* This type is the placeholder for a hardware interrupt number. It has to
* be big enough to enclose whatever representation is used by a given
* platform.

Просмотреть файл

@ -572,7 +572,7 @@ void __init *early_get_page(void);
extern unsigned long ioremap_bot, ioremap_base;
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle);
void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle);
void consistent_free(size_t size, void *vaddr);
void consistent_sync(void *vaddr, size_t size, int direction);
void consistent_sync_page(struct page *page, unsigned long offset,

Просмотреть файл

@ -155,7 +155,7 @@ unsigned long get_wchan(struct task_struct *p);
# define task_regs(task) ((struct pt_regs *)task_tos(task) - 1)
# define task_pt_regs_plus_args(tsk) \
(((void *)task_pt_regs(tsk)) - STATE_SAVE_ARG_SPACE)
((void *)task_pt_regs(tsk))
# define task_sp(task) (task_regs(task)->r1)
# define task_pc(task) (task_regs(task)->pc)

Просмотреть файл

@ -66,13 +66,13 @@ void show_regs(struct pt_regs *);
#else /* __KERNEL__ */
/* pt_regs offsets used by gdbserver etc in ptrace syscalls */
#define PT_GPR(n) ((n) * sizeof(microblaze_reg_t))
#define PT_PC (32 * sizeof(microblaze_reg_t))
#define PT_MSR (33 * sizeof(microblaze_reg_t))
#define PT_EAR (34 * sizeof(microblaze_reg_t))
#define PT_ESR (35 * sizeof(microblaze_reg_t))
#define PT_FSR (36 * sizeof(microblaze_reg_t))
#define PT_KERNEL_MODE (37 * sizeof(microblaze_reg_t))
#define PT_GPR(n) ((n) * sizeof(microblaze_reg_t))
#define PT_PC (32 * sizeof(microblaze_reg_t))
#define PT_MSR (33 * sizeof(microblaze_reg_t))
#define PT_EAR (34 * sizeof(microblaze_reg_t))
#define PT_ESR (35 * sizeof(microblaze_reg_t))
#define PT_FSR (36 * sizeof(microblaze_reg_t))
#define PT_KERNEL_MODE (37 * sizeof(microblaze_reg_t))
#endif /* __KERNEL */

Просмотреть файл

@ -96,4 +96,7 @@ static inline void syscall_set_arguments(struct task_struct *task,
microblaze_set_syscall_arg(regs, i++, *args++);
}
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
asmlinkage void do_syscall_trace_leave(struct pt_regs *regs);
#endif /* __ASM_MICROBLAZE_SYSCALL_H */

Просмотреть файл

@ -1,5 +1,13 @@
#ifndef __ASM_MICROBLAZE_SYSCALLS_H
asmlinkage long microblaze_vfork(struct pt_regs *regs);
asmlinkage long microblaze_clone(int flags, unsigned long stack,
struct pt_regs *regs);
asmlinkage long microblaze_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs);
asmlinkage long sys_clone(int flags, unsigned long stack, struct pt_regs *regs);
#define sys_clone sys_clone

Просмотреть файл

@ -120,16 +120,16 @@ static inline unsigned long __must_check __clear_user(void __user *to,
{
/* normal memset with two words to __ex_table */
__asm__ __volatile__ ( \
"1: sb r0, %2, r0;" \
"1: sb r0, %1, r0;" \
" addik %0, %0, -1;" \
" bneid %0, 1b;" \
" addik %2, %2, 1;" \
" addik %1, %1, 1;" \
"2: " \
__EX_TABLE_SECTION \
".word 1b,2b;" \
".previous;" \
: "=r"(n) \
: "0"(n), "r"(to)
: "=r"(n), "=r"(to) \
: "0"(n), "1"(to)
);
return n;
}

Просмотреть файл

@ -12,18 +12,19 @@
# ifdef __KERNEL__
# include <linux/unaligned/be_byteshift.h>
# include <linux/unaligned/le_byteshift.h>
# include <linux/unaligned/generic.h>
# ifdef __MICROBLAZEEL__
# include <linux/unaligned/le_struct.h>
# include <linux/unaligned/be_byteshift.h>
# define get_unaligned __get_unaligned_le
# define put_unaligned __put_unaligned_le
# else
# include <linux/unaligned/be_struct.h>
# include <linux/unaligned/le_byteshift.h>
# define get_unaligned __get_unaligned_be
# define put_unaligned __put_unaligned_be
# endif
# include <linux/unaligned/generic.h>
# endif /* __KERNEL__ */
#endif /* _ASM_MICROBLAZE_UNALIGNED_H */

Просмотреть файл

@ -519,7 +519,7 @@ static void __flush_dcache_range_wb(unsigned long start, unsigned long end)
struct scache *mbc;
/* new wb cache model */
const struct scache wb_msr = {
static const struct scache wb_msr = {
.ie = __enable_icache_msr,
.id = __disable_icache_msr,
.ifl = __flush_icache_all_noirq,
@ -535,7 +535,7 @@ const struct scache wb_msr = {
};
/* There is only difference in ie, id, de, dd functions */
const struct scache wb_nomsr = {
static const struct scache wb_nomsr = {
.ie = __enable_icache_nomsr,
.id = __disable_icache_nomsr,
.ifl = __flush_icache_all_noirq,
@ -551,7 +551,7 @@ const struct scache wb_nomsr = {
};
/* Old wt cache model with disabling irq and turn off cache */
const struct scache wt_msr = {
static const struct scache wt_msr = {
.ie = __enable_icache_msr,
.id = __disable_icache_msr,
.ifl = __flush_icache_all_msr_irq,
@ -566,7 +566,7 @@ const struct scache wt_msr = {
.dinr = __invalidate_dcache_range_msr_irq_wt,
};
const struct scache wt_nomsr = {
static const struct scache wt_nomsr = {
.ie = __enable_icache_nomsr,
.id = __disable_icache_nomsr,
.ifl = __flush_icache_all_nomsr_irq,
@ -582,7 +582,7 @@ const struct scache wt_nomsr = {
};
/* New wt cache model for newer Microblaze versions */
const struct scache wt_msr_noirq = {
static const struct scache wt_msr_noirq = {
.ie = __enable_icache_msr,
.id = __disable_icache_msr,
.ifl = __flush_icache_all_noirq,
@ -597,7 +597,7 @@ const struct scache wt_msr_noirq = {
.dinr = __invalidate_dcache_range_nomsr_wt,
};
const struct scache wt_nomsr_noirq = {
static const struct scache wt_nomsr_noirq = {
.ie = __enable_icache_nomsr,
.id = __disable_icache_nomsr,
.ifl = __flush_icache_all_noirq,
@ -624,7 +624,7 @@ void microblaze_cache_init(void)
if (cpuinfo.dcache_wb) {
INFO("wb_msr");
mbc = (struct scache *)&wb_msr;
if (cpuinfo.ver_code < CPUVER_7_20_D) {
if (cpuinfo.ver_code <= CPUVER_7_20_D) {
/* MS: problem with signal handling - hw bug */
INFO("WB won't work properly");
}
@ -641,7 +641,7 @@ void microblaze_cache_init(void)
if (cpuinfo.dcache_wb) {
INFO("wb_nomsr");
mbc = (struct scache *)&wb_nomsr;
if (cpuinfo.ver_code < CPUVER_7_20_D) {
if (cpuinfo.ver_code <= CPUVER_7_20_D) {
/* MS: problem with signal handling - hw bug */
INFO("WB won't work properly");
}

Просмотреть файл

@ -33,6 +33,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
{"7.30.b", 0x11},
{"8.00.a", 0x12},
{"8.00.b", 0x13},
{"8.10.a", 0x14},
{NULL, 0},
};

Просмотреть файл

@ -26,6 +26,7 @@ static inline void __dma_sync_page(unsigned long paddr, unsigned long offset,
{
switch (direction) {
case DMA_TO_DEVICE:
case DMA_BIDIRECTIONAL:
flush_dcache_range(paddr + offset, paddr + offset + size);
break;
case DMA_FROM_DEVICE:

Просмотреть файл

@ -115,7 +115,7 @@ ENTRY(_interrupt)
/* restore r31 */
lwi r31, r0, PER_CPU(CURRENT_SAVE)
/* prepare the link register, the argument and jump */
la r15, r0, ret_from_intr - 8
addik r15, r0, ret_from_intr - 8
addk r6, r0, r15
braid do_IRQ
add r5, r0, r1
@ -283,7 +283,7 @@ ENTRY(_user_exception)
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 */
addik r15, r0, ret_to_user-8 /* set return address */
bra r12 /* Make the system call. */
bri 0 /* won't reach here */
1:

Просмотреть файл

@ -33,11 +33,14 @@
#undef DEBUG
/* The size of a state save frame. */
#define STATE_SAVE_SIZE (PT_SIZE + STATE_SAVE_ARG_SPACE)
/* The offset of the struct pt_regs in a `state save frame' on the stack. */
#define PTO STATE_SAVE_ARG_SPACE /* 24 the space for args */
#ifdef DEBUG
/* Create space for syscalls counting. */
.section .data
.global syscall_debug_table
.align 4
syscall_debug_table:
.space (__NR_syscalls * 4)
#endif /* DEBUG */
#define C_ENTRY(name) .globl name; .align 4; name
@ -172,72 +175,72 @@
1:
#define SAVE_REGS \
swi r2, r1, PTO+PT_R2; /* Save SDA */ \
swi r3, r1, PTO+PT_R3; \
swi r4, r1, PTO+PT_R4; \
swi r5, r1, PTO+PT_R5; \
swi r6, r1, PTO+PT_R6; \
swi r7, r1, PTO+PT_R7; \
swi r8, r1, PTO+PT_R8; \
swi r9, r1, PTO+PT_R9; \
swi r10, r1, PTO+PT_R10; \
swi r11, r1, PTO+PT_R11; /* save clobbered regs after rval */\
swi r12, r1, PTO+PT_R12; \
swi r13, r1, PTO+PT_R13; /* Save SDA2 */ \
swi r14, r1, PTO+PT_PC; /* PC, before IRQ/trap */ \
swi r15, r1, PTO+PT_R15; /* Save LP */ \
swi r16, r1, PTO+PT_R16; \
swi r17, r1, PTO+PT_R17; \
swi r18, r1, PTO+PT_R18; /* Save asm scratch reg */ \
swi r19, r1, PTO+PT_R19; \
swi r20, r1, PTO+PT_R20; \
swi r21, r1, PTO+PT_R21; \
swi r22, r1, PTO+PT_R22; \
swi r23, r1, PTO+PT_R23; \
swi r24, r1, PTO+PT_R24; \
swi r25, r1, PTO+PT_R25; \
swi r26, r1, PTO+PT_R26; \
swi r27, r1, PTO+PT_R27; \
swi r28, r1, PTO+PT_R28; \
swi r29, r1, PTO+PT_R29; \
swi r30, r1, PTO+PT_R30; \
swi r31, r1, PTO+PT_R31; /* Save current task reg */ \
swi r2, r1, PT_R2; /* Save SDA */ \
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; /* save clobbered regs after rval */\
swi r12, r1, PT_R12; \
swi r13, r1, PT_R13; /* Save SDA2 */ \
swi r14, r1, PT_PC; /* PC, before IRQ/trap */ \
swi r15, r1, PT_R15; /* Save LP */ \
swi r16, r1, PT_R16; \
swi r17, r1, PT_R17; \
swi r18, r1, PT_R18; /* Save asm scratch reg */ \
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; /* Save current task reg */ \
mfs r11, rmsr; /* save MSR */ \
swi r11, r1, PTO+PT_MSR;
swi r11, r1, PT_MSR;
#define RESTORE_REGS \
lwi r11, r1, PTO+PT_MSR; \
lwi r11, r1, PT_MSR; \
mts rmsr , r11; \
lwi r2, r1, PTO+PT_R2; /* restore SDA */ \
lwi r3, r1, PTO+PT_R3; \
lwi r4, r1, PTO+PT_R4; \
lwi r5, r1, PTO+PT_R5; \
lwi r6, r1, PTO+PT_R6; \
lwi r7, r1, PTO+PT_R7; \
lwi r8, r1, PTO+PT_R8; \
lwi r9, r1, PTO+PT_R9; \
lwi r10, r1, PTO+PT_R10; \
lwi r11, r1, PTO+PT_R11; /* restore clobbered regs after rval */\
lwi r12, r1, PTO+PT_R12; \
lwi r13, r1, PTO+PT_R13; /* restore SDA2 */ \
lwi r14, r1, PTO+PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
lwi r15, r1, PTO+PT_R15; /* restore LP */ \
lwi r16, r1, PTO+PT_R16; \
lwi r17, r1, PTO+PT_R17; \
lwi r18, r1, PTO+PT_R18; /* restore asm scratch reg */ \
lwi r19, r1, PTO+PT_R19; \
lwi r20, r1, PTO+PT_R20; \
lwi r21, r1, PTO+PT_R21; \
lwi r22, r1, PTO+PT_R22; \
lwi r23, r1, PTO+PT_R23; \
lwi r24, r1, PTO+PT_R24; \
lwi r25, r1, PTO+PT_R25; \
lwi r26, r1, PTO+PT_R26; \
lwi r27, r1, PTO+PT_R27; \
lwi r28, r1, PTO+PT_R28; \
lwi r29, r1, PTO+PT_R29; \
lwi r30, r1, PTO+PT_R30; \
lwi r31, r1, PTO+PT_R31; /* Restore cur task reg */
lwi r2, r1, PT_R2; /* restore SDA */ \
lwi r3, r1, PT_R3; \
lwi r4, r1, PT_R4; \
lwi r5, r1, PT_R5; \
lwi r6, r1, PT_R6; \
lwi r7, r1, PT_R7; \
lwi r8, r1, PT_R8; \
lwi r9, r1, PT_R9; \
lwi r10, r1, PT_R10; \
lwi r11, r1, PT_R11; /* restore clobbered regs after rval */\
lwi r12, r1, PT_R12; \
lwi r13, r1, PT_R13; /* restore SDA2 */ \
lwi r14, r1, PT_PC; /* RESTORE_LINK PC, before IRQ/trap */\
lwi r15, r1, PT_R15; /* restore LP */ \
lwi r16, r1, PT_R16; \
lwi r17, r1, PT_R17; \
lwi r18, r1, PT_R18; /* restore asm scratch reg */ \
lwi r19, r1, PT_R19; \
lwi r20, r1, PT_R20; \
lwi r21, r1, PT_R21; \
lwi r22, r1, PT_R22; \
lwi r23, r1, PT_R23; \
lwi r24, r1, PT_R24; \
lwi r25, r1, PT_R25; \
lwi r26, r1, PT_R26; \
lwi r27, r1, PT_R27; \
lwi r28, r1, PT_R28; \
lwi r29, r1, PT_R29; \
lwi r30, r1, PT_R30; \
lwi r31, r1, PT_R31; /* Restore cur task reg */
#define SAVE_STATE \
swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* save stack */ \
@ -250,11 +253,11 @@
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
/* FIXME: I can add these two lines to one */ \
/* tophys(r1,r1); */ \
/* addik r1, r1, -STATE_SAVE_SIZE; */ \
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \
/* addik r1, r1, -PT_SIZE; */ \
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
SAVE_REGS \
brid 2f; \
swi r1, r1, PTO+PT_MODE; \
swi r1, r1, PT_MODE; \
1: /* User-mode state save. */ \
lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */\
tophys(r1,r1); \
@ -262,12 +265,12 @@
/* MS these three instructions can be added to one */ \
/* addik r1, r1, THREAD_SIZE; */ \
/* tophys(r1,r1); */ \
/* addik r1, r1, -STATE_SAVE_SIZE; */ \
addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; \
/* addik r1, r1, -PT_SIZE; */ \
addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE; \
SAVE_REGS \
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); \
swi r11, r1, PTO+PT_R1; /* Store user SP. */ \
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ \
swi r11, r1, PT_R1; /* Store user SP. */ \
swi r0, r1, PT_MODE; /* Was in user-mode. */ \
/* MS: I am clearing UMS even in case when I come from kernel space */ \
clear_ums; \
2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
@ -299,10 +302,10 @@ C_ENTRY(_user_exception):
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
tophys(r1,r1);
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
addik r1, r1, -PT_SIZE; /* Make room on the stack. */
SAVE_REGS
swi r1, r1, PTO + PT_MODE; /* pt_regs -> kernel mode */
swi r1, r1, PT_MODE; /* pt_regs -> kernel mode */
brid 2f;
nop; /* Fill delay slot */
@ -315,18 +318,18 @@ C_ENTRY(_user_exception):
addik r1, r1, THREAD_SIZE;
tophys(r1,r1);
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
addik r1, r1, -PT_SIZE; /* Make room on the stack. */
SAVE_REGS
swi r0, r1, PTO + PT_R3
swi r0, r1, PTO + PT_R4
swi r0, r1, PT_R3
swi r0, r1, PT_R4
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
swi r0, r1, PT_MODE; /* Was in user-mode. */
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1; /* Store user SP. */
swi r11, r1, PT_R1; /* Store user SP. */
clear_ums;
2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
/* Save away the syscall number. */
swi r12, r1, PTO+PT_R0;
swi r12, r1, PT_R0;
tovirt(r1,r1)
/* where the trap should return need -8 to adjust for rtsd r15, 8*/
@ -345,18 +348,18 @@ C_ENTRY(_user_exception):
beqi r11, 4f
addik r3, r0, -ENOSYS
swi r3, r1, PTO + PT_R3
swi r3, r1, PT_R3
brlid r15, do_syscall_trace_enter
addik r5, r1, PTO + PT_R0
addik r5, r1, PT_R0
# do_syscall_trace_enter returns the new syscall nr.
addk r12, r0, r3
lwi r5, r1, PTO+PT_R5;
lwi r6, r1, PTO+PT_R6;
lwi r7, r1, PTO+PT_R7;
lwi r8, r1, PTO+PT_R8;
lwi r9, r1, PTO+PT_R9;
lwi r10, r1, PTO+PT_R10;
lwi r5, r1, PT_R5;
lwi r6, r1, PT_R6;
lwi r7, r1, PT_R7;
lwi r8, r1, PT_R8;
lwi r9, r1, PT_R9;
lwi r10, r1, PT_R10;
4:
/* Jump to the appropriate function for the system call number in r12
* (r12 is not preserved), or return an error if r12 is not valid.
@ -371,10 +374,14 @@ C_ENTRY(_user_exception):
add r12, r12, r12;
#ifdef DEBUG
/* Trac syscalls and stored them to r0_ram */
lwi r3, r12, 0x400 + r0_ram
/* Trac syscalls and stored them to syscall_debug_table */
/* The first syscall location stores total syscall number */
lwi r3, r0, syscall_debug_table
addi r3, r3, 1
swi r3, r12, 0x400 + r0_ram
swi r3, r0, syscall_debug_table
lwi r3, r12, syscall_debug_table
addi r3, r3, 1
swi r3, r12, syscall_debug_table
#endif
# Find and jump into the syscall handler.
@ -391,10 +398,10 @@ C_ENTRY(_user_exception):
/* Entry point used to return from a syscall/trap */
/* We re-enable BIP bit before state restore */
C_ENTRY(ret_from_trap):
swi r3, r1, PTO + PT_R3
swi r4, r1, PTO + PT_R4
swi r3, r1, PT_R3
swi r4, r1, PT_R4
lwi r11, r1, PTO + PT_MODE;
lwi r11, r1, PT_MODE;
/* See if returning to kernel mode, if so, skip resched &c. */
bnei r11, 2f;
/* We're returning to user mode, so check for various conditions that
@ -406,7 +413,7 @@ C_ENTRY(ret_from_trap):
beqi r11, 1f
brlid r15, do_syscall_trace_leave
addik r5, r1, PTO + PT_R0
addik r5, r1, PT_R0
1:
/* We're returning to user mode, so check for various conditions that
* trigger rescheduling. */
@ -426,7 +433,7 @@ C_ENTRY(ret_from_trap):
andi r11, r11, _TIF_SIGPENDING;
beqi r11, 1f; /* Signals to handle, handle them */
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
addi r7, r0, 1; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@ -437,7 +444,7 @@ C_ENTRY(ret_from_trap):
VM_OFF;
tophys(r1,r1);
RESTORE_REGS;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
addik r1, r1, PT_SIZE /* Clean up stack space. */
lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */
bri 6f;
@ -446,7 +453,7 @@ C_ENTRY(ret_from_trap):
VM_OFF;
tophys(r1,r1);
RESTORE_REGS;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
addik r1, r1, PT_SIZE /* Clean up stack space. */
tovirt(r1,r1);
6:
TRAP_return: /* Make global symbol for debugging */
@ -459,8 +466,8 @@ TRAP_return: /* Make global symbol for debugging */
C_ENTRY(sys_fork_wrapper):
addi r5, r0, SIGCHLD /* Arg 0: flags */
lwi r6, r1, PTO+PT_R1 /* Arg 1: child SP (use parent's) */
addik r7, r1, PTO /* Arg 2: parent context */
lwi r6, r1, PT_R1 /* Arg 1: child SP (use parent's) */
addik r7, r1, 0 /* Arg 2: parent context */
add r8. r0, r0 /* Arg 3: (unused) */
add r9, r0, r0; /* Arg 4: (unused) */
brid do_fork /* Do real work (tail-call) */
@ -480,12 +487,12 @@ C_ENTRY(ret_from_fork):
C_ENTRY(sys_vfork):
brid microblaze_vfork /* Do real work (tail-call) */
addik r5, r1, PTO
addik r5, r1, 0
C_ENTRY(sys_clone):
bnei r6, 1f; /* See if child SP arg (arg 1) is 0. */
lwi r6, r1, PTO + PT_R1; /* If so, use paret's stack ptr */
1: addik r7, r1, PTO; /* Arg 2: parent context */
lwi r6, r1, PT_R1; /* If so, use paret's stack ptr */
1: addik r7, r1, 0; /* Arg 2: parent context */
add r8, r0, r0; /* Arg 3: (unused) */
add r9, r0, r0; /* Arg 4: (unused) */
brid do_fork /* Do real work (tail-call) */
@ -493,11 +500,11 @@ C_ENTRY(sys_clone):
C_ENTRY(sys_execve):
brid microblaze_execve; /* Do real work (tail-call).*/
addik r8, r1, PTO; /* add user context as 4th arg */
addik r8, r1, 0; /* add user context as 4th arg */
C_ENTRY(sys_rt_sigreturn_wrapper):
brid sys_rt_sigreturn /* Do real work */
addik r5, r1, PTO; /* add user context as 1st arg */
addik r5, r1, 0; /* add user context as 1st arg */
/*
* HW EXCEPTION rutine start
@ -508,7 +515,7 @@ C_ENTRY(full_exception_trap):
addik r17, r17, -4
SAVE_STATE /* Save registers */
/* PC, before IRQ/trap - this is one instruction above */
swi r17, r1, PTO+PT_PC;
swi r17, r1, PT_PC;
tovirt(r1,r1)
/* FIXME this can be store directly in PT_ESR reg.
* I tested it but there is a fault */
@ -518,7 +525,7 @@ C_ENTRY(full_exception_trap):
mfs r7, rfsr; /* save FSR */
mts rfsr, r0; /* Clear sticky fsr */
rted r0, full_exception
addik r5, r1, PTO /* parameter struct pt_regs * regs */
addik r5, r1, 0 /* parameter struct pt_regs * regs */
/*
* Unaligned data trap.
@ -544,14 +551,14 @@ C_ENTRY(unaligned_data_trap):
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
SAVE_STATE /* Save registers.*/
/* PC, before IRQ/trap - this is one instruction above */
swi r17, r1, PTO+PT_PC;
swi r17, r1, PT_PC;
tovirt(r1,r1)
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
addik r15, r0, ret_from_exc-8
mfs r3, resr /* ESR */
mfs r4, rear /* EAR */
rtbd r0, _unaligned_data_exception
addik r7, r1, PTO /* parameter struct pt_regs * regs */
addik r7, r1, 0 /* parameter struct pt_regs * regs */
/*
* Page fault traps.
@ -574,30 +581,30 @@ C_ENTRY(unaligned_data_trap):
C_ENTRY(page_fault_data_trap):
SAVE_STATE /* Save registers.*/
/* PC, before IRQ/trap - this is one instruction above */
swi r17, r1, PTO+PT_PC;
swi r17, r1, PT_PC;
tovirt(r1,r1)
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
addik r15, r0, ret_from_exc-8
mfs r6, rear /* parameter unsigned long address */
mfs r7, resr /* parameter unsigned long error_code */
rted r0, do_page_fault
addik r5, r1, PTO /* parameter struct pt_regs * regs */
addik r5, r1, 0 /* parameter struct pt_regs * regs */
C_ENTRY(page_fault_instr_trap):
SAVE_STATE /* Save registers.*/
/* PC, before IRQ/trap - this is one instruction above */
swi r17, r1, PTO+PT_PC;
swi r17, r1, PT_PC;
tovirt(r1,r1)
/* where the trap should return need -8 to adjust for rtsd r15, 8 */
addik r15, r0, ret_from_exc-8
mfs r6, rear /* parameter unsigned long address */
ori r7, r0, 0 /* parameter unsigned long error_code */
rted r0, do_page_fault
addik r5, r1, PTO /* parameter struct pt_regs * regs */
addik r5, r1, 0 /* parameter struct pt_regs * regs */
/* Entry point used to return from an exception. */
C_ENTRY(ret_from_exc):
lwi r11, r1, PTO + PT_MODE;
lwi r11, r1, PT_MODE;
bnei r11, 2f; /* See if returning to kernel mode, */
/* ... if so, skip resched &c. */
@ -629,7 +636,7 @@ C_ENTRY(ret_from_exc):
* complete register state. Here we save anything not saved by
* the normal entry sequence, so that it may be safely restored
* (in a possibly modified form) after do_signal returns. */
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
addi r7, r0, 0; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@ -641,7 +648,7 @@ C_ENTRY(ret_from_exc):
tophys(r1,r1);
RESTORE_REGS;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
addik r1, r1, PT_SIZE /* Clean up stack space. */
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer. */
bri 6f;
@ -650,7 +657,7 @@ C_ENTRY(ret_from_exc):
VM_OFF;
tophys(r1,r1);
RESTORE_REGS;
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */
addik r1, r1, PT_SIZE /* Clean up stack space. */
tovirt(r1,r1);
6:
@ -683,10 +690,10 @@ C_ENTRY(_interrupt):
tophys(r1,r1); /* MS: I have in r1 physical address where stack is */
/* save registers */
/* MS: Make room on the stack -> activation record */
addik r1, r1, -STATE_SAVE_SIZE;
addik r1, r1, -PT_SIZE;
SAVE_REGS
brid 2f;
swi r1, r1, PTO + PT_MODE; /* 0 - user mode, 1 - kernel mode */
swi r1, r1, PT_MODE; /* 0 - user mode, 1 - kernel mode */
1:
/* User-mode state save. */
/* MS: get the saved current */
@ -696,23 +703,23 @@ C_ENTRY(_interrupt):
addik r1, r1, THREAD_SIZE;
tophys(r1,r1);
/* save registers */
addik r1, r1, -STATE_SAVE_SIZE;
addik r1, r1, -PT_SIZE;
SAVE_REGS
/* calculate mode */
swi r0, r1, PTO + PT_MODE;
swi r0, r1, PT_MODE;
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1;
swi r11, r1, PT_R1;
clear_ums;
2:
lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
tovirt(r1,r1)
addik r15, r0, irq_call;
irq_call:rtbd r0, do_IRQ;
addik r5, r1, PTO;
addik r5, r1, 0;
/* MS: we are in virtual mode */
ret_from_irq:
lwi r11, r1, PTO + PT_MODE;
lwi r11, r1, PT_MODE;
bnei r11, 2f;
lwi r11, CURRENT_TASK, TS_THREAD_INFO;
@ -729,7 +736,7 @@ ret_from_irq:
beqid r11, no_intr_resched
/* Handle a signal return; Pending signals should be in r18. */
addi r7, r0, 0; /* Arg 3: int in_syscall */
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
bralid r15, do_signal; /* Handle any signals */
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@ -741,7 +748,7 @@ no_intr_resched:
VM_OFF;
tophys(r1,r1);
RESTORE_REGS
addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */
addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
lwi r1, r1, PT_R1 - PT_SIZE;
bri 6f;
/* MS: Return to kernel state. */
@ -769,7 +776,7 @@ restore:
VM_OFF /* MS: turn off MMU */
tophys(r1,r1)
RESTORE_REGS
addik r1, r1, STATE_SAVE_SIZE /* MS: Clean up stack space. */
addik r1, r1, PT_SIZE /* MS: Clean up stack space. */
tovirt(r1,r1);
6:
IRQ_return: /* MS: Make global symbol for debugging */
@ -792,29 +799,29 @@ C_ENTRY(_debug_exception):
lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/
/* BIP bit is set on entry, no interrupts can occur */
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE;
addik r1, r1, CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - PT_SIZE;
SAVE_REGS;
/* save all regs to pt_reg structure */
swi r0, r1, PTO+PT_R0; /* R0 must be saved too */
swi r14, r1, PTO+PT_R14 /* rewrite saved R14 value */
swi r16, r1, PTO+PT_PC; /* PC and r16 are the same */
swi r0, r1, PT_R0; /* R0 must be saved too */
swi r14, r1, PT_R14 /* rewrite saved R14 value */
swi r16, r1, PT_PC; /* PC and r16 are the same */
/* save special purpose registers to pt_regs */
mfs r11, rear;
swi r11, r1, PTO+PT_EAR;
swi r11, r1, PT_EAR;
mfs r11, resr;
swi r11, r1, PTO+PT_ESR;
swi r11, r1, PT_ESR;
mfs r11, rfsr;
swi r11, r1, PTO+PT_FSR;
swi r11, r1, PT_FSR;
/* stack pointer is in physical address at it is decrease
* by STATE_SAVE_SIZE but we need to get correct R1 value */
addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + STATE_SAVE_SIZE;
swi r11, r1, PTO+PT_R1
* by PT_SIZE but we need to get correct R1 value */
addik r11, r1, CONFIG_KERNEL_START - CONFIG_KERNEL_BASE_ADDR + PT_SIZE;
swi r11, r1, PT_R1
/* MS: r31 - current pointer isn't changed */
tovirt(r1,r1)
#ifdef CONFIG_KGDB
addi r5, r1, PTO /* pass pt_reg address as the first arg */
la r15, r0, dbtrap_call; /* return address */
addi r5, r1, 0 /* pass pt_reg address as the first arg */
addik r15, r0, dbtrap_call; /* return address */
rtbd r0, microblaze_kgdb_break
nop;
#endif
@ -829,16 +836,16 @@ C_ENTRY(_debug_exception):
addik r1, r1, THREAD_SIZE; /* calculate kernel stack pointer */
tophys(r1,r1);
addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */
addik r1, r1, -PT_SIZE; /* Make room on the stack. */
SAVE_REGS;
swi r16, r1, PTO+PT_PC; /* Save LP */
swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */
swi r16, r1, PT_PC; /* Save LP */
swi r0, r1, PT_MODE; /* Was in user-mode. */
lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP));
swi r11, r1, PTO+PT_R1; /* Store user SP. */
swi r11, r1, PT_R1; /* Store user SP. */
lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE));
tovirt(r1,r1)
set_vms;
addik r5, r1, PTO;
addik r5, r1, 0;
addik r15, r0, dbtrap_call;
dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
rtbd r0, sw_exception
@ -846,7 +853,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
/* MS: The first instruction for the second part of the gdb/kgdb */
set_bip; /* Ints masked for state restore */
lwi r11, r1, PTO + PT_MODE;
lwi r11, r1, PT_MODE;
bnei r11, 2f;
/* MS: Return to user space - gdb */
/* Get current task ptr into r11 */
@ -865,7 +872,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
andi r11, r11, _TIF_SIGPENDING;
beqi r11, 1f; /* Signals to handle, handle them */
addik r5, r1, PTO; /* Arg 1: struct pt_regs *regs */
addik r5, r1, 0; /* Arg 1: struct pt_regs *regs */
addi r7, r0, 0; /* Arg 3: int in_syscall */
bralid r15, do_signal; /* Handle any signals */
add r6, r0, r0; /* Arg 2: sigset_t *oldset */
@ -876,7 +883,7 @@ dbtrap_call: /* Return point for kernel/user entry + 8 because of rtsd r15, 8 */
tophys(r1,r1);
/* MS: Restore all regs */
RESTORE_REGS
addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space */
addik r1, r1, PT_SIZE /* Clean up stack space */
lwi r1, r1, PT_R1 - PT_SIZE; /* Restore user stack pointer */
DBTRAP_return_user: /* MS: Make global symbol for debugging */
rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@ -887,9 +894,9 @@ DBTRAP_return_user: /* MS: Make global symbol for debugging */
tophys(r1,r1);
/* MS: Restore all regs */
RESTORE_REGS
lwi r14, r1, PTO+PT_R14;
lwi r16, r1, PTO+PT_PC;
addik r1, r1, STATE_SAVE_SIZE; /* MS: Clean up stack space */
lwi r14, r1, PT_R14;
lwi r16, r1, PT_PC;
addik r1, r1, PT_SIZE; /* MS: Clean up stack space */
tovirt(r1,r1);
DBTRAP_return_kernel: /* MS: Make global symbol for debugging */
rtbd r16, 0; /* MS: Instructions to return from a debug trap */
@ -981,20 +988,22 @@ ENTRY(_switch_to)
nop
ENTRY(_reset)
brai 0x70; /* Jump back to FS-boot */
brai 0; /* Jump to reset vector */
/* These are compiled and loaded into high memory, then
* copied into place in mach_early_setup */
.section .init.ivt, "ax"
#if CONFIG_MANUAL_RESET_VECTOR
.org 0x0
/* this is very important - here is the reset vector */
/* in current MMU branch you don't care what is here - it is
* used from bootloader site - but this is correct for FS-BOOT */
brai 0x70
nop
brai CONFIG_MANUAL_RESET_VECTOR
#endif
.org 0x8
brai TOPHYS(_user_exception); /* syscall handler */
.org 0x10
brai TOPHYS(_interrupt); /* Interrupt handler */
.org 0x18
brai TOPHYS(_debug_exception); /* debug trap handler */
.org 0x20
brai TOPHYS(_hw_exception_handler); /* HW exception handler */
.section .rodata,"a"

Просмотреть файл

@ -50,7 +50,7 @@ void die(const char *str, struct pt_regs *fp, long err)
}
/* for user application debugging */
void sw_exception(struct pt_regs *regs)
asmlinkage void sw_exception(struct pt_regs *regs)
{
_exception(SIGTRAP, regs, TRAP_BRKPT, regs->r16);
flush_dcache_range(regs->r16, regs->r16 + 0x4);

Просмотреть файл

@ -39,7 +39,7 @@
#include <asm/mmu.h>
#include <asm/processor.h>
.data
.section .data
.global empty_zero_page
.align 12
empty_zero_page:
@ -50,6 +50,11 @@ swapper_pg_dir:
#endif /* CONFIG_MMU */
.section .rodata
.align 4
endian_check:
.word 1
__HEAD
ENTRY(_start)
#if CONFIG_KERNEL_BASE_ADDR == 0
@ -79,10 +84,7 @@ real_start:
/* Does r7 point to a valid FDT? Load HEADER magic number */
/* Run time Big/Little endian platform */
/* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */
addik r11, r0, 0x1 /* BIG/LITTLE checking value */
/* __bss_start will be zeroed later - it is just temp location */
swi r11, r0, TOPHYS(__bss_start)
lbui r11, r0, TOPHYS(__bss_start)
lbui r11, r0, TOPHYS(endian_check)
beqid r11, big_endian /* DO NOT break delay stop dependency */
lw r11, r0, r7 /* Big endian load in delay slot */
lwr r11, r0, r7 /* Little endian load */
@ -222,26 +224,26 @@ start_here:
#endif /* CONFIG_MMU */
/* Initialize small data anchors */
la r13, r0, _KERNEL_SDA_BASE_
la r2, r0, _KERNEL_SDA2_BASE_
addik r13, r0, _KERNEL_SDA_BASE_
addik r2, r0, _KERNEL_SDA2_BASE_
/* Initialize stack pointer */
la r1, r0, init_thread_union + THREAD_SIZE - 4
addik r1, r0, init_thread_union + THREAD_SIZE - 4
/* Initialize r31 with current task address */
la r31, r0, init_task
addik r31, r0, init_task
/*
* Call platform dependent initialize function.
* Please see $(ARCH)/mach-$(SUBARCH)/setup.c for
* the function.
*/
la r9, r0, machine_early_init
addik r9, r0, machine_early_init
brald r15, r9
nop
#ifndef CONFIG_MMU
la r15, r0, machine_halt
addik r15, r0, machine_halt
braid start_kernel
nop
#else

Просмотреть файл

@ -77,6 +77,8 @@
#include <asm/signal.h>
#include <asm/asm-offsets.h>
#undef DEBUG
/* Helpful Macros */
#define NUM_TO_REG(num) r ## num
@ -91,7 +93,7 @@
lwi r6, r1, PT_R6; \
lwi r11, r1, PT_R11; \
lwi r31, r1, PT_R31; \
lwi r1, r0, TOPHYS(r0_ram + 0);
lwi r1, r1, PT_R1;
#endif /* CONFIG_MMU */
#define LWREG_NOP \
@ -206,8 +208,8 @@
* | . |
* | . |
*
* NO_MMU kernel use the same r0_ram pointed space - look to vmlinux.lds.S
* which is used for storing register values - old style was, that value were
* MMU kernel uses the same 'pt_pool_space' pointed space
* which is used for storing register values - noMMu style was, that values were
* stored in stack but in case of failure you lost information about register.
* Currently you can see register value in memory in specific place.
* In compare to with previous solution the speed should be the same.
@ -226,8 +228,22 @@
*/
/* wrappers to restore state before coming to entry.S */
#ifdef CONFIG_MMU
.section .data
.align 4
pt_pool_space:
.space PT_SIZE
#ifdef DEBUG
/* Create space for exception counting. */
.section .data
.global exception_debug_table
.align 4
exception_debug_table:
/* Look at exception vector table. There is 32 exceptions * word size */
.space (32 * 4)
#endif /* DEBUG */
.section .rodata
.align 4
_MB_HW_ExceptionVectorTable:
@ -287,10 +303,10 @@ _hw_exception_handler:
#ifndef CONFIG_MMU
addik r1, r1, -(EX_HANDLER_STACK_SIZ); /* Create stack frame */
#else
swi r1, r0, TOPHYS(r0_ram + 0); /* GET_SP */
swi r1, r0, TOPHYS(pt_pool_space + PT_R1); /* GET_SP */
/* Save date to kernel memory. Here is the problem
* when you came from user space */
ori r1, r0, TOPHYS(r0_ram + 28);
ori r1, r0, TOPHYS(pt_pool_space);
#endif
swi r3, r1, PT_R3
swi r4, r1, PT_R4
@ -329,12 +345,12 @@ not_in_delay_slot:
#ifdef DEBUG
/* counting which exception happen */
lwi r5, r0, 0x200 + TOPHYS(r0_ram)
lwi r5, r0, TOPHYS(exception_debug_table)
addi r5, r5, 1
swi r5, r0, 0x200 + TOPHYS(r0_ram)
lwi r5, r6, 0x200 + TOPHYS(r0_ram)
swi r5, r0, TOPHYS(exception_debug_table)
lwi r5, r6, TOPHYS(exception_debug_table)
addi r5, r5, 1
swi r5, r6, 0x200 + TOPHYS(r0_ram)
swi r5, r6, TOPHYS(exception_debug_table)
#endif
/* end */
/* Load the HW Exception vector */
@ -474,7 +490,7 @@ ex_lw_tail:
/* Get the destination register number into r5 */
lbui r5, r0, TOPHYS(ex_reg_op);
/* Form load_word jump table offset (lw_table + (8 * regnum)) */
la r6, r0, TOPHYS(lw_table);
addik r6, r0, TOPHYS(lw_table);
addk r5, r5, r5;
addk r5, r5, r5;
addk r5, r5, r5;
@ -485,7 +501,7 @@ ex_sw:
/* Get the destination register number into r5 */
lbui r5, r0, TOPHYS(ex_reg_op);
/* Form store_word jump table offset (sw_table + (8 * regnum)) */
la r6, r0, TOPHYS(sw_table);
addik r6, r0, TOPHYS(sw_table);
add r5, r5, r5;
add r5, r5, r5;
add r5, r5, r5;
@ -896,7 +912,7 @@ ex_lw_vm:
beqid r6, ex_lhw_vm;
load1: lbui r5, r4, 0; /* Exception address in r4 - delay slot */
/* Load a word, byte-by-byte from destination address and save it in tmp space*/
la r6, r0, ex_tmp_data_loc_0;
addik r6, r0, ex_tmp_data_loc_0;
sbi r5, r6, 0;
load2: lbui r5, r4, 1;
sbi r5, r6, 1;
@ -910,7 +926,7 @@ load4: lbui r5, r4, 3;
ex_lhw_vm:
/* Load a half-word, byte-by-byte from destination address and
* save it in tmp space */
la r6, r0, ex_tmp_data_loc_0;
addik r6, r0, ex_tmp_data_loc_0;
sbi r5, r6, 0;
load5: lbui r5, r4, 1;
sbi r5, r6, 1;
@ -926,7 +942,7 @@ ex_sw_vm:
addik r5, r8, sw_table_vm;
bra r5;
ex_sw_tail_vm:
la r5, r0, ex_tmp_data_loc_0;
addik r5, r0, ex_tmp_data_loc_0;
beqid r6, ex_shw_vm;
swi r3, r5, 0; /* Get the word - delay slot */
/* Store the word, byte-by-byte into destination address */
@ -969,7 +985,7 @@ ex_unaligned_fixup:
addik r7, r0, SIGSEGV
/* call bad_page_fault for finding aligned fixup, fixup address is saved
* in PT_PC which is used as return address from exception */
la r15, r0, ret_from_exc-8 /* setup return address */
addik r15, r0, ret_from_exc-8 /* setup return address */
brid bad_page_fault
nop

Просмотреть файл

@ -40,59 +40,46 @@ unsigned int nr_irq;
#define MER_ME (1<<0)
#define MER_HIE (1<<1)
static void intc_enable_or_unmask(unsigned int irq)
static void intc_enable_or_unmask(struct irq_data *d)
{
unsigned long mask = 1 << irq;
pr_debug("enable_or_unmask: %d\n", irq);
unsigned long mask = 1 << d->irq;
pr_debug("enable_or_unmask: %d\n", d->irq);
out_be32(INTC_BASE + SIE, mask);
/* ack level irqs because they can't be acked during
* ack function since the handle_level_irq function
* acks the irq before calling the interrupt handler
*/
if (irq_desc[irq].status & IRQ_LEVEL)
if (irq_to_desc(d->irq)->status & IRQ_LEVEL)
out_be32(INTC_BASE + IAR, mask);
}
static void intc_disable_or_mask(unsigned int irq)
static void intc_disable_or_mask(struct irq_data *d)
{
pr_debug("disable: %d\n", irq);
out_be32(INTC_BASE + CIE, 1 << irq);
pr_debug("disable: %d\n", d->irq);
out_be32(INTC_BASE + CIE, 1 << d->irq);
}
static void intc_ack(unsigned int irq)
static void intc_ack(struct irq_data *d)
{
pr_debug("ack: %d\n", irq);
out_be32(INTC_BASE + IAR, 1 << irq);
pr_debug("ack: %d\n", d->irq);
out_be32(INTC_BASE + IAR, 1 << d->irq);
}
static void intc_mask_ack(unsigned int irq)
static void intc_mask_ack(struct irq_data *d)
{
unsigned long mask = 1 << irq;
pr_debug("disable_and_ack: %d\n", irq);
unsigned long mask = 1 << d->irq;
pr_debug("disable_and_ack: %d\n", d->irq);
out_be32(INTC_BASE + CIE, mask);
out_be32(INTC_BASE + IAR, mask);
}
static void intc_end(unsigned int irq)
{
unsigned long mask = 1 << irq;
pr_debug("end: %d\n", irq);
if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
out_be32(INTC_BASE + SIE, mask);
/* ack level sensitive intr */
if (irq_desc[irq].status & IRQ_LEVEL)
out_be32(INTC_BASE + IAR, mask);
}
}
static struct irq_chip intc_dev = {
.name = "Xilinx INTC",
.unmask = intc_enable_or_unmask,
.mask = intc_disable_or_mask,
.ack = intc_ack,
.mask_ack = intc_mask_ack,
.end = intc_end,
.irq_unmask = intc_enable_or_unmask,
.irq_mask = intc_disable_or_mask,
.irq_ack = intc_ack,
.irq_mask_ack = intc_mask_ack,
};
unsigned int get_irq(struct pt_regs *regs)
@ -172,11 +159,11 @@ void __init init_IRQ(void)
if (intr_type & (0x00000001 << i)) {
set_irq_chip_and_handler_name(i, &intc_dev,
handle_edge_irq, intc_dev.name);
irq_desc[i].status &= ~IRQ_LEVEL;
irq_clear_status_flags(i, IRQ_LEVEL);
} else {
set_irq_chip_and_handler_name(i, &intc_dev,
handle_level_irq, intc_dev.name);
irq_desc[i].status |= IRQ_LEVEL;
irq_set_status_flags(i, IRQ_LEVEL);
}
}
}

Просмотреть файл

@ -50,6 +50,7 @@ next_irq:
int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *) v, j;
struct irq_desc *desc;
struct irqaction *action;
unsigned long flags;
@ -61,8 +62,9 @@ int show_interrupts(struct seq_file *p, void *v)
}
if (i < nr_irq) {
raw_spin_lock_irqsave(&irq_desc[i].lock, flags);
action = irq_desc[i].action;
desc = irq_to_desc(i);
raw_spin_lock_irqsave(&desc->lock, flags);
action = desc->action;
if (!action)
goto skip;
seq_printf(p, "%3d: ", i);
@ -72,9 +74,9 @@ int show_interrupts(struct seq_file *p, void *v)
for_each_online_cpu(j)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %8s", irq_desc[i].status &
seq_printf(p, " %8s", desc->status &
IRQ_LEVEL ? "level" : "edge");
seq_printf(p, " %8s", irq_desc[i].chip->name);
seq_printf(p, " %8s", desc->irq_data.chip->name);
seq_printf(p, " %s", action->name);
for (action = action->next; action; action = action->next)
@ -82,7 +84,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
skip:
raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags);
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
return 0;
}

Просмотреть файл

@ -24,6 +24,7 @@
extern char *_ebss;
EXPORT_SYMBOL_GPL(_ebss);
#ifdef CONFIG_FUNCTION_TRACER
extern void _mcount(void);
EXPORT_SYMBOL(_mcount);
@ -45,3 +46,14 @@ EXPORT_SYMBOL(empty_zero_page);
#endif
EXPORT_SYMBOL(mbc);
extern void __divsi3(void);
EXPORT_SYMBOL(__divsi3);
extern void __modsi3(void);
EXPORT_SYMBOL(__modsi3);
extern void __mulsi3(void);
EXPORT_SYMBOL(__mulsi3);
extern void __udivsi3(void);
EXPORT_SYMBOL(__udivsi3);
extern void __umodsi3(void);
EXPORT_SYMBOL(__umodsi3);

Просмотреть файл

@ -159,7 +159,7 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
}
/* FIXME STATE_SAVE_PT_OFFSET; */
ti->cpu_context.r1 = (unsigned long)childregs - STATE_SAVE_ARG_SPACE;
ti->cpu_context.r1 = (unsigned long)childregs;
/* we should consider the fact that childregs is a copy of the parent
* regs which were saved immediately after entering the kernel state
* before enabling VM. This MSR will be restored in switch_to and

Просмотреть файл

@ -59,7 +59,7 @@ static int __init early_init_dt_scan_serial(unsigned long node,
{
unsigned long l;
char *p;
int *addr;
const __be32 *addr;
pr_debug("search \"serial\", depth: %d, uname: %s\n", depth, uname);

Просмотреть файл

@ -39,6 +39,7 @@
#include <linux/uaccess.h>
#include <asm/asm-offsets.h>
#include <asm/cacheflush.h>
#include <asm/syscall.h>
#include <asm/io.h>
/* Returns the address where the register at REG_OFFS in P is stashed away. */
@ -123,7 +124,7 @@ long arch_ptrace(struct task_struct *child, long request,
rval = -EIO;
if (rval == 0 && request == PTRACE_PEEKUSR)
rval = put_user(val, (unsigned long *)data);
rval = put_user(val, (unsigned long __user *)data);
break;
default:
rval = ptrace_request(child, request, addr, data);

Просмотреть файл

@ -95,7 +95,8 @@ inline unsigned get_romfs_len(unsigned *addr)
void __init machine_early_init(const char *cmdline, unsigned int ram,
unsigned int fdt, unsigned int msr)
{
unsigned long *src, *dst = (unsigned long *)0x0;
unsigned long *src, *dst;
unsigned int offset = 0;
/* If CONFIG_MTD_UCLINUX is defined, assume ROMFS is at the
* end of kernel. There are two position which we want to check.
@ -168,7 +169,14 @@ void __init machine_early_init(const char *cmdline, unsigned int ram,
"CPU have it %x\n", msr);
#endif
for (src = __ivt_start; src < __ivt_end; src++, dst++)
/* Do not copy reset vectors. offset = 0x2 means skip the first
* two instructions. dst is pointer to MB vectors which are placed
* in block ram. If you want to copy reset vector setup offset to 0x0 */
#if !CONFIG_MANUAL_RESET_VECTOR
offset = 0x2;
#endif
dst = (unsigned long *) (offset * sizeof(u32));
for (src = __ivt_start + offset; src < __ivt_end; src++, dst++)
*dst = *src;
/* Initialize global data */

Просмотреть файл

@ -93,7 +93,7 @@ static int restore_sigcontext(struct pt_regs *regs,
asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe __user *frame =
(struct rt_sigframe __user *)(regs->r1 + STATE_SAVE_ARG_SPACE);
(struct rt_sigframe __user *)(regs->r1);
sigset_t set;
int rval;
@ -197,8 +197,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
err |= __put_user(0, &frame->uc.uc_link);
err |= __put_user((void *)current->sas_ss_sp,
err |= __put_user(NULL, &frame->uc.uc_link);
err |= __put_user((void __user *)current->sas_ss_sp,
&frame->uc.uc_stack.ss_sp);
err |= __put_user(sas_ss_flags(regs->r1),
&frame->uc.uc_stack.ss_flags);
@ -247,7 +247,7 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
goto give_sigsegv;
/* Set up registers for signal handler */
regs->r1 = (unsigned long) frame - STATE_SAVE_ARG_SPACE;
regs->r1 = (unsigned long) frame;
/* Signal handler args: */
regs->r5 = signal; /* arg 0: signum */

Просмотреть файл

@ -40,7 +40,8 @@ asmlinkage long microblaze_vfork(struct pt_regs *regs)
regs, 0, NULL, NULL);
}
asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs)
asmlinkage long microblaze_clone(int flags, unsigned long stack,
struct pt_regs *regs)
{
if (!stack)
stack = regs->r1;

Просмотреть файл

@ -38,8 +38,8 @@ static unsigned int timer_baseaddr;
#define TIMER_BASE timer_baseaddr
#endif
unsigned int freq_div_hz;
unsigned int timer_clock_freq;
static unsigned int freq_div_hz;
static unsigned int timer_clock_freq;
#define TCSR0 (0x00)
#define TLR0 (0x04)
@ -202,7 +202,7 @@ static struct cyclecounter microblaze_cc = {
.shift = 8,
};
int __init init_microblaze_timecounter(void)
static int __init init_microblaze_timecounter(void)
{
microblaze_cc.mult = div_sc(timer_clock_freq, NSEC_PER_SEC,
microblaze_cc.shift);

Просмотреть файл

@ -183,7 +183,7 @@ static inline void unwind_trap(struct task_struct *task, unsigned long pc,
* @trace : Where to store stack backtrace (PC values).
* NULL == print backtrace to kernel log
*/
void microblaze_unwind_inner(struct task_struct *task,
static void microblaze_unwind_inner(struct task_struct *task,
unsigned long pc, unsigned long fp,
unsigned long leaf_return,
struct stack_trace *trace)

Просмотреть файл

@ -70,11 +70,6 @@ SECTIONS {
RW_DATA_SECTION(32, PAGE_SIZE, THREAD_SIZE)
_edata = . ;
/* Reserve some low RAM for r0 based memory references */
. = ALIGN(0x4) ;
r0_ram = . ;
. = . + PAGE_SIZE; /* a page should be enough */
/* Under the microblaze ABI, .sdata and .sbss must be contiguous */
. = ALIGN(8);
.sdata : AT(ADDR(.sdata) - LOAD_OFFSET) {

Просмотреть файл

@ -58,3 +58,4 @@ DWtype __muldi3(DWtype u, DWtype v)
return w.ll;
}
EXPORT_SYMBOL(__muldi3);

Просмотреть файл

@ -59,7 +59,7 @@
* uncached region. This will no doubt cause big problems if memory allocated
* here is not also freed properly. -- JW
*/
void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
void *consistent_alloc(gfp_t gfp, size_t size, dma_addr_t *dma_handle)
{
unsigned long order, vaddr;
void *ret;

Просмотреть файл

@ -48,7 +48,7 @@ static int store_updates_sp(struct pt_regs *regs)
{
unsigned int inst;
if (get_user(inst, (unsigned int *)regs->pc))
if (get_user(inst, (unsigned int __user *)regs->pc))
return 0;
/* check for 1 in the rD field */
if (((inst >> 21) & 0x1f) != 1)