Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 360647
b: refs/heads/master
c: ac919f0
h: refs/heads/master
i:
  360645: c4c43b4
  360643: d6cb6b1
  360639: ad8a9e7
v: v3
  • Loading branch information
James Hogan committed Mar 2, 2013
1 parent f152ffa commit 7c4ce03
Show file tree
Hide file tree
Showing 6 changed files with 1,168 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a2c5d4ed92bbc02ff4a37efc2adffe7d145abe4f
refs/heads/master: ac919f0883e53d7785745566692c8a0620abd7ea
21 changes: 21 additions & 0 deletions trunk/arch/metag/include/asm/switch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (C) 2012 Imagination Technologies Ltd.
*
* 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_METAG_SWITCH_H
#define _ASM_METAG_SWITCH_H

/* metag SWITCH codes */
#define __METAG_SW_PERM_BREAK 0x400002 /* compiled in breakpoint */
#define __METAG_SW_SYS_LEGACY 0x440000 /* legacy system calls */
#define __METAG_SW_SYS 0x440001 /* system calls */

/* metag SWITCH instruction encoding */
#define __METAG_SW_ENCODING(TYPE) (0xaf000000 | (__METAG_SW_##TYPE))

#endif /* _ASM_METAG_SWITCH_H */
48 changes: 48 additions & 0 deletions trunk/arch/metag/include/asm/traps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (C) 2005,2008 Imagination Technologies
*
* 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.
*/

#ifndef _METAG_TBIVECTORS_H
#define _METAG_TBIVECTORS_H

#ifndef __ASSEMBLY__

#include <asm/tbx.h>

typedef TBIRES (*kick_irq_func_t)(TBIRES, int, int, int, PTBI, int *);

extern TBIRES kick_handler(TBIRES, int, int, int, PTBI);
struct kick_irq_handler {
struct list_head list;
kick_irq_func_t func;
};

extern void kick_register_func(struct kick_irq_handler *);
extern void kick_unregister_func(struct kick_irq_handler *);

extern void head_end(TBIRES, unsigned long);
extern void restart_critical_section(TBIRES State);
extern TBIRES tail_end_sys(TBIRES, int, int *);
static inline TBIRES tail_end(TBIRES state)
{
return tail_end_sys(state, -1, NULL);
}

DECLARE_PER_CPU(PTBI, pTBI);
extern PTBI pTBI_get(unsigned int);

extern int ret_from_fork(TBIRES arg);

extern int do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned int write_access, unsigned int trapno);

extern TBIRES __TBIUnExpXXX(TBIRES State, int SigNum, int Triggers, int Inst,
PTBI pTBI);

#endif

#endif /* _METAG_TBIVECTORS_H */
98 changes: 98 additions & 0 deletions trunk/arch/metag/kernel/kick.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (C) 2009 Imagination Technologies
*
* 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.
*
* The Meta KICK interrupt mechanism is generally a useful feature, so
* we provide an interface for registering multiple interrupt
* handlers. All the registered interrupt handlers are "chained". When
* a KICK interrupt is received the first function in the list is
* called. If that interrupt handler cannot handle the KICK the next
* one is called, then the next until someone handles it (or we run
* out of functions). As soon as one function handles the interrupt no
* other handlers are called.
*
* The only downside of chaining interrupt handlers is that each
* handler must be able to detect whether the KICK was intended for it
* or not. For example, when the IPI handler runs and it sees that
* there are no IPI messages it must not signal that the KICK was
* handled, thereby giving the other handlers a chance to run.
*
* The reason that we provide our own interface for calling KICK
* handlers instead of using the generic kernel infrastructure is that
* the KICK handlers require access to a CPU's pTBI structure. So we
* pass it as an argument.
*/
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/types.h>

#include <asm/traps.h>

/*
* All accesses/manipulations of kick_handlers_list should be
* performed while holding kick_handlers_lock.
*/
static DEFINE_SPINLOCK(kick_handlers_lock);
static LIST_HEAD(kick_handlers_list);

void kick_register_func(struct kick_irq_handler *kh)
{
unsigned long flags;

spin_lock_irqsave(&kick_handlers_lock, flags);

list_add_tail(&kh->list, &kick_handlers_list);

spin_unlock_irqrestore(&kick_handlers_lock, flags);
}

void kick_unregister_func(struct kick_irq_handler *kh)
{
unsigned long flags;

spin_lock_irqsave(&kick_handlers_lock, flags);

list_del(&kh->list);

spin_unlock_irqrestore(&kick_handlers_lock, flags);
}

TBIRES
kick_handler(TBIRES State, int SigNum, int Triggers, int Inst, PTBI pTBI)
{
struct kick_irq_handler *kh;
struct list_head *lh;
int handled = 0;
TBIRES ret;

head_end(State, ~INTS_OFF_MASK);

/* If we interrupted user code handle any critical sections. */
if (State.Sig.SaveMask & TBICTX_PRIV_BIT)
restart_critical_section(State);

trace_hardirqs_off();

/*
* There is no need to disable interrupts here because we
* can't nest KICK interrupts in a KICK interrupt handler.
*/
spin_lock(&kick_handlers_lock);

list_for_each(lh, &kick_handlers_list) {
kh = list_entry(lh, struct kick_irq_handler, list);

ret = kh->func(State, SigNum, Triggers, Inst, pTBI, &handled);
if (handled)
break;
}

spin_unlock(&kick_handlers_lock);

WARN_ON(!handled);

return tail_end(ret);
}
22 changes: 22 additions & 0 deletions trunk/arch/metag/kernel/tbiunexp.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Pass a breakpoint through to Codescape */

#include <asm/tbx.h>

.text
.global ___TBIUnExpXXX
.type ___TBIUnExpXXX,function
___TBIUnExpXXX:
TSTT D0Ar2,#TBICTX_CRIT_BIT ! Result of nestable int call?
BZ $LTBINormCase ! UnExpXXX at background level
MOV D0Re0,TXMASKI ! Read TXMASKI
XOR TXMASKI,D1Re0,D1Re0 ! Turn off BGNDHALT handling!
OR D0Ar2,D0Ar2,D0Re0 ! Preserve bits cleared
$LTBINormCase:
MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2 ! Save args on stack
SETL [A0StP++],D0Ar2,D1Ar1 ! Init area for returned values
SWITCH #0xC20208 ! Total stack frame size 8 Dwords
! write back size 2 Dwords
GETL D0Re0,D1Re0,[--A0StP] ! Get result
SUB A0StP,A0StP,#(8*3) ! Recover stack frame
MOV PC,D1RtP
.size ___TBIUnExpXXX,.-___TBIUnExpXXX
Loading

0 comments on commit 7c4ce03

Please sign in to comment.