URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 680 to Rev 681
- ↔ Reverse comparison
Rev 680 → Rev 681
/trunk/uclinux/uClinux-2.0.x/include/asm-or32/user.h
41,7 → 41,7
/* We start with the registers, to mimic the way that "memory" is returned |
from the ptrace(3,...) function. */ |
struct pt_regs regs; /* Where the registers are actually stored */ |
struct switch_stack regs2; /* Backward compatibility, sort of */ |
/* struct switch_stack regs2; /* Backward compatibility, sort of */ |
/* ptrace does not yet supply these. Someday.... */ |
int u_fpvalid; /* True if math co-processor being used. */ |
/* for this mess. Not yet used. */ |
/trunk/uclinux/uClinux-2.0.x/include/asm-or32/processor.h
84,12 → 84,7
*/ |
extern inline unsigned long thread_saved_pc(struct thread_struct *t) |
{ |
/*extern unsigned long high_memory;*/ |
unsigned long frame = ((struct switch_stack *)t->ksp)->a6; |
/*if (frame > PAGE_SIZE && frame < high_memory)*/ |
return ((unsigned long *)frame)[1]; |
/*else |
return 0;*/ |
return t->pc; |
} |
|
#endif |
/trunk/uclinux/uClinux-2.0.x/include/asm-or32/ptrace.h
48,8 → 48,10
#define GPR29 120 |
#define GPR30 124 |
#define GPR31 128 |
#define ORIG_GPR3 132 |
#define RESULT 136 |
|
#define INT_FRAME_SIZE 132 |
#define INT_FRAME_SIZE 140 |
|
#ifndef __ASSEMBLY__ |
|
61,6 → 63,8
long sr; |
long sp; |
long gprs[30]; |
long orig_gpr3; /* Used for restarting system calls */ |
long result; /* Result of a system call */ |
}; |
|
/* |
68,7 → 72,7
* switcher: it's pushed after the normal "struct pt_regs". |
*/ |
/* SIMON: This is can not be like this */ |
struct switch_stack { |
/*struct switch_stack { |
unsigned long d6; |
unsigned long d7; |
unsigned long a2; |
78,7 → 82,7
unsigned long a6; |
unsigned long retpc; |
}; |
|
*/ |
#ifdef __KERNEL__ |
|
#ifndef PS_S |
/trunk/uclinux/uClinux-2.0.x/include/asm-or32/board.h
12,8 → 12,8
#define CRT_BASE_ADD 0xb0000000 |
|
/* Define this if you want to use I and/or D cache */ |
#define ICACHE 1 |
#define DCACHE 1 |
#define ICACHE 0 |
#define DCACHE 0 |
|
#define IC_SIZE 4096 |
#define IC_LINE 16 |
22,7 → 22,7
|
/* Define this if you want to use I and/or D MMU */ |
#define IMMU 0 |
#define DMMU 1 |
#define DMMU 0 |
|
#define DMMU_SET_NB 64 |
#define DMMU_PAGE_ADD_BITS 13 /* 13 for 8k, 12 for 4k page size */ |
/trunk/uclinux/uClinux-2.0.x/arch/or32/kernel/signal.c
1,36 → 1,10
/* |
* linux/arch/m68knommu/kernel/signal.c |
* linux/arch/ppc/kernel/signal.c |
* |
* Copyright (C) 1998 D. Jeff Dionne <jeff@ryeham.ee.ryerson.ca>, |
* Kenneth Albanowski <kjahds@kjahds.com>, |
* The Silver Hammer Group, Ltd. |
* |
* Based on: |
* |
* linux/arch/m68k/kernel/signal.c |
* |
* Copyright (C) 1991, 1992 Linus Torvalds |
* |
* 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. |
* Adapted for PowerPC by Gary Thomas |
*/ |
|
/* |
* Linux/m68k support by Hamish Macdonald |
* |
* 68000 and CPU32 support D. Jeff Dionne |
* 68060 fixes by Jesper Skov |
*/ |
|
/* |
* ++roman (07/09/96): implemented signal stacks (specially for tosemu on |
* Atari :-) Current limitation: Only one sigstack can be active at one time. |
* If a second signal with SA_STACK set arrives while working on a sigstack, |
* SA_STACK is ignored. This behaviour avoids lots of trouble with nested |
* signal handlers! |
*/ |
|
#include <linux/config.h> |
|
#include <linux/sched.h> |
81,219 → 55,51
} |
} |
|
/* |
* This sets regs->esp even though we don't actually use sigstacks yet.. |
*/ |
asmlinkage int sys_sigreturn(struct pt_regs *regs) |
{ |
/* SIMON */ |
printk("%s - %s:%d\n",__FILE__,__FUNCTION__,__LINE__); |
printk(" sys_sigreturn is not implemented !!!!\n"); |
return 0; |
#if 0 |
struct sigcontext_struct *sc; |
struct pt_regs *int_regs; |
int signo; |
sc = (struct sigcontext_struct *)regs->sp; |
current->blocked = sc->oldmask & _BLOCKABLE; |
int_regs = sc->regs; |
signo = sc->signal; |
sc++; /* Pop signal 'context' */ |
if (sc == (struct sigcontext_struct *)(int_regs)) |
{ /* Last stacked signal */ |
#if 0 |
/* This doesn't work - it blows away the return address! */ |
memcpy(regs, int_regs, sizeof(*regs)); |
struct sigcontext_struct *sc; |
struct pt_regs *int_regs; |
int signo; |
sc = (struct sigcontext_struct *)regs->sp; |
current->blocked = sc->oldmask & _BLOCKABLE; |
int_regs = sc->regs; |
signo = sc->signal; |
sc++; /* Pop signal 'context' */ |
if (sc == (struct sigcontext_struct *)(int_regs)) |
{ /* Last stacked signal */ |
int i; |
#if 0 |
/* This doesn't work - it blows away the return address! */ |
memcpy(regs, int_regs, sizeof(*regs)); |
#else |
/* Don't mess up 'my' stack frame */ |
memcpy(®s->gprs, &int_regs->gprs, sizeof(regs->gprs)); |
#endif |
if ((int)regs->orig_gpr3 >= 0 && |
((int)regs->result == -ERESTARTNOHAND || |
(int)regs->result == -ERESTARTSYS || |
(int)regs->result == -ERESTARTNOINTR)) |
{ |
regs->gpr[3] = regs->orig_gpr3; |
regs->nip -= 4; /* Back up & retry system call */ |
regs->result = 0; |
} |
return (regs->result); |
} else |
{ /* More signals to go */ |
regs->gpr[1] = (unsigned long)sc; |
regs->gpr[3] = sc->signal; |
regs->gpr[4] = sc->regs; |
regs->link = (unsigned long)((sc->regs)+1); |
regs->nip = sc->handler; |
return (sc->signal); |
} |
#endif |
} |
|
/* |
* Set up a signal frame... |
* |
* This routine is somewhat complicated by the fact that if the |
* kernel may be entered by an exception other than a system call; |
* e.g. a bus error or other "bad" exception. If this is the case, |
* then *all* the context on the kernel stack frame must be saved. |
* |
* For a large number of exceptions, the stack frame format is the same |
* as that which will be created when the process traps back to the kernel |
* when finished executing the signal handler. In this case, nothing |
* must be done. This is exception frame format "0". For exception frame |
* formats "2", "9", "A" and "B", the extra information on the frame must |
* be saved. This information is saved on the user stack and restored |
* when the signal handler is returned. |
* |
* The format of the user stack when executing the signal handler is: |
* |
* usp -> RETADDR (points to code below) |
* signum (parm #1) |
* sigcode (parm #2 ; vector number) |
* scp (parm #3 ; sigcontext pointer, pointer to #1 below) |
* code1 (addaw #20,sp) ; pop parms and code off stack |
* code2 (moveq #119,d0; trap #0) ; sigreturn syscall |
* #1| oldmask |
* | old usp |
* | d0 (first saved reg) |
* | d1 |
* | a0 |
* | a1 |
* | sr (saved status register) |
* | pc (old pc; one to return to) |
* ----->| forvec (format and vector word of old supervisor stack frame) |
* | floating point context |
* |
* These are optionally followed by some extra stuff, depending on the |
* stack frame interrupted. This is 1 longword for format "2", 3 |
* longwords for format "9", 6 longwords for format "A", and 21 |
* longwords for format "B". |
* |
* everything after ------> is not present if the processor does not push a vector |
* format. Only 68000 and the new 68000 modular core are like this |
*/ |
|
#define UFRAME_SIZE(fs) (sizeof(struct sigcontext_struct)/4 + 6 + fs/4) |
|
static void setup_frame (struct sigaction * sa, struct pt_regs *regs, |
int signr, unsigned long oldmask) |
{ |
/* SIMON */ |
#if 0 |
struct sigcontext_struct context; |
unsigned long *frame, *tframe; |
#define fsize 0 |
|
frame = (unsigned long *)rdusp(); |
if (!(current->flags & PF_ONSIGSTK) && (sa->sa_flags & SA_STACK)) { |
frame = (unsigned long *)sa->sa_restorer; |
current->flags |= PF_ONSIGSTK; |
} |
#ifdef DEBUG |
printk("setup_frame: usp %.8x\n",frame); |
#endif |
frame -= UFRAME_SIZE(fsize); |
#ifdef DEBUG |
printk("setup_frame: frame %.8x\n",frame); |
#endif |
if (verify_area(VERIFY_WRITE,frame,UFRAME_SIZE(fsize)*4)) |
do_exit(SIGSEGV); |
if (fsize) { |
memcpy_tofs (frame + UFRAME_SIZE(0), regs + 1, fsize); |
regs->stkadj = fsize; |
} |
|
/* set up the "normal" stack seen by the signal handler */ |
tframe = frame; |
|
/* return address points to code on stack */ |
put_user((ulong)(frame+4), tframe); tframe++; |
if (current->exec_domain && current->exec_domain->signal_invmap) |
put_user(current->exec_domain->signal_invmap[signr], tframe); |
else |
put_user(signr, tframe); |
tframe++; |
tframe++; |
/* "scp" parameter. points to sigcontext */ |
put_user((ulong)(frame+6), tframe); tframe++; |
|
/* set up the return code... */ |
put_user(0xdefc0014,tframe); tframe++; /* addaw #20,sp */ |
put_user(0x70774e40,tframe); tframe++; /* moveq #119,d0; trap #0 */ |
|
/* setup and copy the sigcontext structure */ |
context.sc_mask = oldmask; |
context.sc_usp = rdusp(); |
context.sc_d0 = regs->d0; |
context.sc_d1 = regs->d1; |
context.sc_a0 = regs->a0; |
context.sc_a1 = regs->a1; |
context.sc_sr = regs->sr; |
context.sc_pc = regs->pc; |
|
memcpy_tofs (tframe, &context, sizeof(context)); |
#ifdef DEBUG |
printk("setup_frame: top tframe %.8x\n",tframe + sizeof(context)); |
#endif |
|
/* Set up registers for signal handler */ |
wrusp ((unsigned long) frame); |
regs->pc = (unsigned long) sa->sa_handler; |
|
/* Prepare to skip over the extra stuff in the exception frame. */ |
if (regs->stkadj) { |
struct pt_regs *tregs = |
(struct pt_regs *)((ulong)regs + regs->stkadj); |
|
#ifdef DEBUG |
printk("Performing stackadjust=%04x\n", regs->stkadj); |
#endif |
|
/* This must be copied with decreasing addresses to |
handle overlaps. */ |
tregs->pc = regs->pc; |
tregs->sr = regs->sr; |
} |
#endif |
} |
|
/* |
* OK, we're invoking a handler |
*/ |
static void handle_signal(unsigned long signr, struct sigaction *sa, |
unsigned long oldmask, struct pt_regs *regs) |
{ |
/* SIMON */ |
#if 0 |
#ifdef DEBUG |
printk("Entering handle_signal, signr=%d\n", signr); |
#endif |
/* are we from a system call? */ |
if (regs->orig_d0 >= 0) { |
/* If so, check system call restarting.. */ |
switch (regs->d0) { |
case -ERESTARTNOHAND: |
regs->d0 = -EINTR; |
break; |
|
case -ERESTARTSYS: |
if (!(sa->sa_flags & SA_RESTART)) { |
regs->d0 = -EINTR; |
break; |
} |
/* fallthrough */ |
case -ERESTARTNOINTR: |
regs->d0 = regs->orig_d0; |
regs->pc -= 2; |
/* Don't mess up 'my' stack frame */ |
for(i = 0; i < 30; i++) |
if(i != 7) |
regs->gprs[i] = int_regs->gprs[i]; |
regs->sp = int_regs->sp; |
#endif |
if ((int)regs->orig_gpr3 >= 0 && |
((int)regs->result == -ERESTARTNOHAND || |
(int)regs->result == -ERESTARTSYS || |
(int)regs->result == -ERESTARTNOINTR)) |
{ |
regs->gprs[1] = regs->orig_gpr3; |
regs->pc -= 4; /* Back up & retry system call */ |
regs->result = 0; |
} |
return (regs->result); |
} else |
{ /* More signals to go */ |
regs->sp = (unsigned long)sc; |
regs->gprs[1] = sc->signal; /* r3 */ |
regs->gprs[2] = (unsigned long)sc->regs; /* r4 */ |
regs->gprs[7] = (unsigned long)((sc->regs)+1); /* r9 - link register */ |
regs->pc = sc->handler; |
return (sc->signal); |
} |
|
/* set up the stack frame */ |
setup_frame(sa, regs, signr, oldmask); |
|
if (sa->sa_flags & SA_ONESHOT) |
sa->sa_handler = NULL; |
if (!(sa->sa_flags & SA_NOMASK)) |
current->blocked |= (sa->sa_mask | _S(signr)) & _BLOCKABLE; |
#endif |
} |
|
/* |
301,67 → 107,57
* want to handle. Thus you cannot kill init even with a SIGKILL even by |
* mistake. |
* |
* Note that we go through the signals twice: once to check the signals |
* that the kernel can handle, and then we build all the user-level signal |
* handling stack-frames in one go after that. |
* Note that we go through the signals twice: once to check the signals that |
* the kernel can handle, and then we build all the user-level signal handling |
* stack-frames in one go after that. |
*/ |
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs *regs) |
asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) |
{ |
/* SIMON */ |
#if 0 |
unsigned long mask = ~current->blocked; |
unsigned long handler_signal = 0; |
unsigned long *frame = NULL; |
unsigned long *trampoline; |
unsigned long *regs_ptr; |
unsigned long nip = 0; |
unsigned long signr; |
int bitno; |
struct sigcontext_struct *sc; |
struct sigaction * sa; |
unsigned long flags; |
|
current->tss.esp0 = (unsigned long) regs; |
save_flags(flags); |
cli(); |
|
/* If the process is traced, all signals are passed to the debugger. */ |
if (current->flags & PF_PTRACED) |
mask = ~0UL; |
while ((signr = current->signal & mask) != 0) { |
signr = ffz(~signr); |
clear_bit(signr, ¤t->signal); |
while ((signr = current->signal & mask)) { |
#if 0 |
signr = ffz(~signr); /* Compute bit # */ |
#else |
for (bitno = 0; bitno < 32; bitno++) |
{ |
if (signr & (1<<bitno)) break; |
} |
signr = bitno; |
#endif |
current->signal &= ~(1<<signr); /* Clear bit */ |
sa = current->sig->action + signr; |
signr++; |
|
#ifdef DEBUG |
printk("Signal %d: ", sa->sa_handler); |
#endif |
|
if ((current->flags & PF_PTRACED) && signr != SIGKILL) { |
current->exit_code = signr; |
current->state = TASK_STOPPED; |
|
/* Did we come from a system call? */ |
if (regs->orig_d0 >= 0) { |
/* Restart the system call */ |
if (regs->d0 == -ERESTARTNOHAND || |
regs->d0 == -ERESTARTSYS || |
regs->d0 == -ERESTARTNOINTR) { |
regs->d0 = regs->orig_d0; |
regs->pc -= 2; |
} |
} |
notify_parent(current, SIGCHLD); |
schedule(); |
if (!(signr = current->exit_code)) { |
discard_frame: |
continue; |
} |
if (!(signr = current->exit_code)) |
continue; |
current->exit_code = 0; |
if (signr == SIGSTOP) |
goto discard_frame; |
continue; |
if (_S(signr) & current->blocked) { |
current->signal |= _S(signr); |
mask &= ~_S(signr); |
continue; |
} |
sa = current->sig->action + signr - 1; |
} |
if (sa->sa_handler == SIG_IGN) { |
#ifdef DEBUG |
printk("Ignoring.\n"); |
#endif |
if (signr != SIGCHLD) |
continue; |
/* check for SIGCHLD: it's special */ |
370,9 → 166,6
continue; |
} |
if (sa->sa_handler == SIG_DFL) { |
#ifdef DEBUG |
printk("Default.\n"); |
#endif |
if (current->pid == 1) |
continue; |
switch (signr) { |
379,16 → 172,13
case SIGCONT: case SIGCHLD: case SIGWINCH: |
continue; |
|
case SIGTSTP: case SIGTTIN: case SIGTTOU: |
if (is_orphaned_pgrp(current->pgrp)) |
continue; |
case SIGSTOP: |
case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU: |
if (current->flags & PF_PTRACED) |
continue; |
current->state = TASK_STOPPED; |
current->exit_code = signr; |
if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & |
SA_NOCLDSTOP)) |
if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags & |
SA_NOCLDSTOP)) |
notify_parent(current, SIGCHLD); |
schedule(); |
continue; |
396,44 → 186,78
case SIGQUIT: case SIGILL: case SIGTRAP: |
case SIGIOT: case SIGFPE: case SIGSEGV: |
if (current->binfmt && current->binfmt->core_dump) { |
if (current->binfmt->core_dump(signr, regs)) |
signr |= 0x80; |
if (current->binfmt->core_dump(signr, regs)) |
signr |= 0x80; |
} |
/* fall through */ |
default: |
current->signal |= _S(signr & 0x7f); |
current->flags |= PF_SIGNALED; |
do_exit(signr); |
} |
} |
handle_signal(signr, sa, oldmask, regs); |
return 1; |
} |
|
/* Did we come from a system call? */ |
if (regs->orig_d0 >= 0) { |
/* Restart the system call - no handlers present */ |
if (regs->d0 == -ERESTARTNOHAND || |
regs->d0 == -ERESTARTSYS || |
regs->d0 == -ERESTARTNOINTR) { |
regs->d0 = regs->orig_d0; |
regs->pc -= 2; |
/* |
* OK, we're invoking a handler |
*/ |
if ((int)regs->orig_gpr3 >= 0) { |
if ((int)regs->result == -ERESTARTNOHAND || |
((int)regs->result == -ERESTARTSYS && !(sa->sa_flags & SA_RESTART))) |
(int)regs->result = -EINTR; |
} |
handler_signal |= 1 << (signr-1); |
mask &= ~sa->sa_mask; |
} |
|
/* If we are about to discard some frame stuff we must copy |
over the remaining frame. */ |
if (regs->stkadj) { |
struct pt_regs *tregs = |
(struct pt_regs *) ((ulong) regs + regs->stkadj); |
#if defined(DEBUG) || 1 |
printk("!!!!!!!!!!!!!! stkadj !!!\n"); |
#endif |
/* This must be copied with decreasing addresses to |
handle overlaps. */ |
tregs->pc = regs->pc; |
tregs->sr = regs->sr; |
if (!handler_signal) /* no handler will be called - return 0 */ |
{ |
restore_flags(flags); |
return 0; |
} |
nip = regs->pc; |
frame = (unsigned long *) regs->sp; |
/* Build trampoline code on stack */ |
frame -= 3; |
trampoline = frame; |
trampoline[0] = 0x9d607777; /* l.addi r11,r0,0x7777 */ |
trampoline[1] = 0x20000001; /* l.sys 1 */ |
trampoline[2] = 0x15000000; /* l.nop 0 */ |
frame -= sizeof(*regs) / sizeof(long); |
regs_ptr = frame; |
memcpy(regs_ptr, regs, sizeof(*regs)); |
signr = 1; |
sa = current->sig->action; |
for (mask = 1 ; mask ; sa++,signr++,mask += mask) { |
if (mask > handler_signal) |
break; |
if (!(mask & handler_signal)) |
continue; |
frame -= sizeof(struct sigcontext_struct) / sizeof(long); |
sc = (struct sigcontext_struct *)frame; |
nip = (unsigned long) sa->sa_handler; |
#if 0 /* Old compiler */ |
nip = *(unsigned long *)nip; |
#endif |
if (sa->sa_flags & SA_ONESHOT) |
sa->sa_handler = NULL; |
sc->handler = nip; |
sc->oldmask = current->blocked; |
sc->regs = (struct pt_regs *)regs_ptr; |
sc->signal = signr; |
current->blocked |= sa->sa_mask; |
regs->gprs[1] = signr; /* r3 = signr */ |
regs->gprs[2] = (unsigned long)regs_ptr; /* r4 = regs_ptr */ |
} |
regs->gprs[7] = (unsigned long)trampoline; /* r9 = trampoline (r9 is link register) */ |
regs->pc = nip; |
regs->sp = (unsigned long)sc; |
/* The DATA cache must be flushed here to insure coherency */ |
/* between the DATA & INSTRUCTION caches. Since we just */ |
/* created an instruction stream using the DATA [cache] space */ |
/* and since the instruction cache will not look in the DATA */ |
/* cache for new data, we have to force the data to go on to */ |
/* memory and flush the instruction cache to force it to look */ |
/* there. The following function performs this magic */ |
#if ICACHE |
ic_invalidate(); |
#endif |
return 0; |
restore_flags(flags); |
return 1; |
} |
/trunk/uclinux/uClinux-2.0.x/arch/or32/kernel/process.c
85,6 → 85,7
{ |
unsigned long clone_flags = (unsigned long)p1; |
unsigned long newsp = regs->sp - INT_FRAME_SIZE; /* SIMON check!!!!!! */ |
|
return do_fork(clone_flags, newsp, regs); |
} |
|
96,24 → 97,14
struct task_struct * p, struct pt_regs * regs) |
{ |
struct pt_regs * childregs; |
if ((p->mm->context == 0) || (p->mm->count == 1)) |
{ |
p->mm->context = (nr<<4); |
} |
|
|
/* Copy registers */ |
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 2; |
childregs = ((struct pt_regs *) (p->kernel_stack_page + PAGE_SIZE)) - 1; |
*childregs = *regs; /* STRUCT COPY */ |
childregs->gprs[9] = 0; /* Result from fork() */ |
childregs->gprs[9] = 0x0; /* Result from fork() */ |
p->tss.ksp = childregs; |
|
if (usp >= (unsigned long)regs) |
{ /* Stack is in kernel space - must adjust */ |
childregs->sp = (unsigned long)(childregs+1); |
} else |
{ /* Provided stack is in user space */ |
childregs->sp = (unsigned long)usp; |
} |
childregs->sp = (unsigned long)(childregs+1); |
} |
|
/* Fill in the fpu structure for a core dump. */ |
121,7 → 112,7
int dump_fpu (struct pt_regs *regs, struct user_or32fp_struct *fpu) |
{ |
return 0; |
} |
} |
|
void switch_to(struct task_struct *prev, struct task_struct *new) |
{ |
158,7 → 149,6
|
dump->u_ar0 = (struct pt_regs *)(((int)(&dump->regs)) -((int)(dump))); |
dump->regs = *regs; |
dump->regs2 = ((struct switch_stack *)regs)[-1]; |
/* dump floating point stuff */ |
dump->u_fpvalid = dump_fpu (regs, &dump->or32fp); |
} |
/trunk/uclinux/uClinux-2.0.x/arch/or32/kernel/ptrace.c
45,10 → 45,6
/* sets the trace bits. */ |
#define TRACE_BITS 0x8000 |
|
/* Find the stack offset for a register, relative to tss.esp0. */ |
#define PT_REG(reg) ((long)&((struct pt_regs *)0)->reg) |
#define SW_REG(reg) ((long)&((struct switch_stack *)0)->reg \ |
- sizeof(struct switch_stack)) |
/* Mapping from PT_xxx to the stack offset at which the register is |
saved. Notice that usp has no stack-slot and needs to be treated |
specially (see get_reg/put_reg below). */ |
/trunk/uclinux/uClinux-2.0.x/arch/or32/kernel/head.S
66,6 → 66,8
l.sw GPR31(r1),r31; \ |
l.lwz r3,0(r0); /* Read r3 from tmp location */ \ |
l.sw GPR3(r1),r3 |
l.sw ORIG_GPR3(r1),r3 |
l.sw RESULT(r1),r0 |
|
#define SAVE_INT_REGS(mark) \ |
l.sw 0(r0),r3; /* Temporary store r3 to add 0!!! */ \ |
83,7 → 85,7
l.nop; \ |
l.movhi r3,hi(_current_set); \ |
l.ori r3,r3,lo(_current_set); \ |
l.lwz r3,(0)(r3); \ |
l.lwz r3,0(r3); \ |
l.sw TSS+TSS_USP(r3),r1; \ |
l.mfspr r1,r0,SPR_EPCR_BASE; \ |
l.sw TSS+TSS_PC(r3),r1; \ |
101,27 → 103,27
l.mtspr r0,r3,SPR_SR; \ |
l.movhi r2,hi(_intr_count); \ |
l.ori r2,r2,lo(_intr_count); \ |
l.lwz r3,(0)(r2); \ |
l.lwz r3,0(r2); \ |
l.sfeqi r3,0; \ |
l.bnf 00f; \ |
l.nop; \ |
l.movhi r4,hi(_bh_mask); \ |
l.ori r4,r4,lo(_bh_mask); \ |
l.lwz r4,(0)(r4); \ |
l.lwz r4,0(r4); \ |
l.movhi r5,hi(_bh_active); \ |
l.ori r5,r5,lo(_bh_active); \ |
l.lwz r5,(0)(r5); \ |
l.lwz r5,0(r5); \ |
l.and r4,r4,r5; \ |
l.sfeqi r4,0; \ |
l.bf 00f; \ |
l.nop; \ |
l.addi r3,r3,1; \ |
l.sw (0)(r2),r3; \ |
l.sw 0(r2),r3; \ |
l.jal _do_bottom_half; \ |
l.nop; \ |
l.movhi r2,hi(_intr_count); \ |
l.ori r2,r2,lo(_intr_count); \ |
l.lwz r3,(0)(r2); \ |
l.lwz r3,0(r2); \ |
l.addi r3,r3,-1; \ |
l.sw 0(r2),r3; \ |
00: l.lwz r2,SR(r1); \ |
137,7 → 139,7
l.nop; \ |
05: l.movhi r3,hi(_current_set); /* need to save kernel stack pointer */ \ |
l.ori r3,r3,lo(_current_set); \ |
l.lwz r3,(0)(r3); \ |
l.lwz r3,0(r3); \ |
l.addi r4,r1,INT_FRAME_SIZE; \ |
l.sw TSS+TSS_KSP(r3),r4; \ |
l.lwz r4,STATE(r3); /* If state != 0, can't run */ \ |
574,9 → 576,22
|
_sys_call: |
SAVE_INT_REGS(0x0c00) |
l.lwz r2,PC(r1) |
/* l.addi r2,r2,4 /* EPCR was pointing to l.sys instruction, we have to incremet it */ |
/* EPCR was pointing to l.sys instruction, we have to incremet it */ |
/* l.lwz r2,PC(r1) |
l.addi r2,r2,4 |
l.sw PC(r1),r2 |
*/ |
l.sfeqi r11,0x7777 /* Special case for 'sys_sigreturn' */ |
l.bnf 10f |
l.nop |
l.jal _sys_sigreturn |
l.addi r3,r1,0 |
l.sfgtsi r11,0 /* Check for restarted system call */ |
l.bf 99f |
l.nop |
l.j 20f |
l.nop |
10: |
l.movhi r2,hi(_sys_call_table) |
l.ori r2,r2,lo(_sys_call_table) |
l.slli r11,r11,2 |
586,7 → 601,18
l.jalr r2 |
l.nop |
l.sw GPR11(r1),r11 /* save return value */ |
|
20: |
l.sw RESULT(r1),r11 /* save result */ |
l.sfgesi r11,0 |
l.bf 99f |
l.nop |
l.sfeqi r11,-ERESTARTNOHAND |
l.bnf 22f |
l.nop |
l.addi r11,r0,EINTR |
22: |
l.sw RESULT(r1),r11 |
99: |
RETURN_FROM_INT(0xc00) |
|
/* |