/*
* OpenRISC entry.S
*
* Linux architectural port borrowing liberally from similar works of
* others. All original copyrights apply as per the original source
* declaration.
*
* Modifications for the OpenRISC architecture:
* Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
* Copyright (C) 2005 Gyorgy Jeney <nog@bsemi.com>
* Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
*
* 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 <linux/linkage.h>
#include <asm/processor.h>
#include <asm/unistd.h>
#include <asm/thread_info.h>
#include <asm/errno.h>
#include <asm/spr_defs.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/pgtable.h>
#include <asm/asm-offsets.h>
#define DISABLE_INTERRUPTS(t1,t2) \
l.mfspr t2,r0,SPR_SR ;\
l.movhi t1,hi(~(SPR_SR_IEE|SPR_SR_TEE)) ;\
l.ori t1,t1,lo(~(SPR_SR_IEE|SPR_SR_TEE)) ;\
l.and t2,t2,t1 ;\
l.mtspr r0,t2,SPR_SR
#define ENABLE_INTERRUPTS(t1) \
l.mfspr t1,r0,SPR_SR ;\
l.ori t1,t1,lo(SPR_SR_IEE|SPR_SR_TEE) ;\
l.mtspr r0,t1,SPR_SR
/* =========================================================[ macros ]=== */
#ifdef CONFIG_TRACE_IRQFLAGS
/*
* Trace irq on/off creating a stack frame.
*/
#define TRACE_IRQS_OP(trace_op) \
l.sw -8(r1),r2 /* store frame pointer */ ;\
l.sw -4(r1),r9 /* store return address */ ;\
l.addi r2,r1,0 /* move sp to fp */ ;\
l.jal trace_op ;\
l.addi r1,r1,-8 ;\
l.ori r1,r2,0 /* restore sp */ ;\
l.lwz r9,-4(r1) /* restore return address */ ;\
l.lwz r2,-8(r1) /* restore fp */ ;\
/*
* Trace irq on/off and save registers we need that would otherwise be
* clobbered.
*/
#define TRACE_IRQS_SAVE(t1,trace_op) \
l.sw -12(r1),t1 /* save extra reg */ ;\
l.sw -8(r1),r2 /* store frame pointer */ ;\
l.sw -4(r1),r9 /* store return address */ ;\
l.addi r2,r1,0 /* move sp to fp */ ;\
l.jal trace_op ;\
l.addi r1,r1,-12 ;\
l.ori r1,r2,0 /* restore sp */ ;\
l.lwz r9,-4(r1) /* restore return address */ ;\
l.lwz r2,-8(r1) /* restore fp */ ;\
l.lwz t1,-12(r1) /* restore extra reg */
#define TRACE_IRQS_OFF TRACE_IRQS_OP(trace_hardirqs_off)
#define TRACE_IRQS_ON TRACE_IRQS_OP(trace_hardirqs_on)
#define TRACE_IRQS_ON_SYSCALL \
TRACE_IRQS_SAVE(r10,trace_hardirqs_on) ;\
l.lwz r3,PT_GPR3(r1) ;\
l.lwz r4,PT_GPR4(r1) ;\
l.lwz r5,PT_GPR5(r1) ;\
l.lwz r6,PT_GPR6(r1) ;\
l.lwz r7,PT_GPR7(r1) ;\
l.lwz r8,PT_GPR8(r1) ;\
l.lwz r11,PT_GPR11(r1)
#define TRACE_IRQS_OFF_ENTRY \
l.lwz r5,PT_SR(r1) ;\
l.andi r3,r5,(SPR_SR_IEE|SPR_SR_TEE) ;\
l.sfeq