/*
* Low-level system-call handling, trap handlers and context-switching
*
* Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
* Copyright (C) 2008-2009 PetaLogix
* Copyright (C) 2003 John Williams <jwilliams@itee.uq.edu.au>
* Copyright (C) 2001,2002 NEC Corporation
* Copyright (C) 2001,2002 Miles Bader <miles@gnu.org>
*
* 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.
*
* Written by Miles Bader <miles@gnu.org>
* Heavily modified by John Williams for Microblaze
*/
#include <linux/sys.h>
#include <linux/linkage.h>
#include <asm/entry.h>
#include <asm/current.h>
#include <asm/processor.h>
#include <asm/exceptions.h>
#include <asm/asm-offsets.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/unistd.h>
#include <linux/errno.h>
#include <asm/signal.h>
#undef DEBUG
#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
/*
* Various ways of setting and clearing BIP in flags reg.
* This is mucky, but necessary using microblaze version that
* allows msr ops to write to BIP
*/
#if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR
.macro clear_bip
msrclr r0, MSR_BIP
.endm
.macro set_bip
msrset r0, MSR_BIP
.endm
.macro clear_eip
msrclr r0, MSR_EIP
.endm
.macro set_ee
msrset r0, MSR_EE
.endm
.macro disable_irq
msrclr r0, MSR_IE
.endm
.macro enable_irq
msrset r0, MSR_IE
.endm
.macro set_ums
msrset r0, MSR_UMS
msrclr r0, MSR_VMS
.endm
.macro set_vms
msrclr r0, MSR_UMS
msrset r0, MSR_VMS
.endm
.macro clear_ums
msrclr r0, MSR_UMS
.endm
.macro clear_vms_ums
msrclr r0, MSR_VMS | MSR_UMS
.endm
#else
.macro clear_bip
mfs r11, rmsr
andi r11, r11, ~MSR_BIP
mts rmsr, r11
.endm
.macro set_bip
mfs r11, rmsr
ori r11, r11, MSR_BIP
mts rmsr, r11
.endm
.macro clear_eip
mfs r11, rmsr
andi r11, r11, ~MSR_EIP
mts rmsr, r11
.endm
.macro set_ee
mfs r11, rmsr
ori r11, r11, MSR_EE
mts rmsr, r11
.endm
.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 set_ums
mfs r11, rmsr
ori r11, r11, MSR_VMS
andni r11, r11, MSR_UMS
mts rmsr, r11
.endm
.macro set_vms
mfs r11, rmsr
ori r11, r11, MSR_VMS
andni r11, r11, MSR_UMS
mts rmsr, r11
.endm
.macro clear_ums
mfs r11, rmsr
andni r11, r11, MSR_UMS
mts rmsr,r11
.endm
.macro clear_vms_ums
mfs r11, rmsr
andni r11, r11, (MSR_VMS|MSR_UMS)
mts rmsr,r11
.endm
#endif
/* Define how to call high-level functions. With MMU, virtual mode must be
* enabled when calling the high-level function. Clobbers R11.
* VM_ON, VM_OFF, DO_JUMP_BIPCLR, DO_CALL
*/
/* turn on virtual protected mode save */
#define VM_ON \
set_ums; \
rted r0, 2f; \
nop; \
2:
/* turn off virtual protected mode save and user mode save*/
#define VM_OFF \
clear_vms_ums; \
rted r0, TOPHYS(1f); \
nop; \
1:
#define SAVE_REGS \
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