aboutsummaryrefslogtreecommitdiff
path: root/arch/metag/include/asm/processor.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/metag/include/asm/processor.h')
-rw-r--r--arch/metag/include/asm/processor.h202
1 files changed, 202 insertions, 0 deletions
diff --git a/arch/metag/include/asm/processor.h b/arch/metag/include/asm/processor.h
new file mode 100644
index 00000000000..9b029a7911c
--- /dev/null
+++ b/arch/metag/include/asm/processor.h
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2005,2006,2007,2008 Imagination Technologies
+ */
+
+#ifndef __ASM_METAG_PROCESSOR_H
+#define __ASM_METAG_PROCESSOR_H
+
+#include <linux/atomic.h>
+
+#include <asm/page.h>
+#include <asm/ptrace.h>
+#include <asm/metag_regs.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() ({ __label__ _l; _l: &&_l; })
+
+/* The task stops where the kernel starts */
+#define TASK_SIZE PAGE_OFFSET
+/* Add an extra page of padding at the top of the stack for the guard page. */
+#define STACK_TOP (TASK_SIZE - PAGE_SIZE)
+#define STACK_TOP_MAX STACK_TOP
+
+/* This decides where the kernel will search for a free chunk of vm
+ * space during mmap's.
+ */
+#define TASK_UNMAPPED_BASE META_MEMORY_BASE
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+#ifdef CONFIG_METAG_FPU
+struct meta_fpu_context {
+ TBICTXEXTFPU fpstate;
+ union {
+ struct {
+ TBICTXEXTBB4 fx8_15;
+ TBICTXEXTFPACC fpacc;
+ } fx8_15;
+ struct {
+ TBICTXEXTFPACC fpacc;
+ TBICTXEXTBB4 unused;
+ } nofx8_15;
+ } extfpstate;
+ bool needs_restore;
+};
+#else
+struct meta_fpu_context {};
+#endif
+
+#ifdef CONFIG_METAG_DSP
+struct meta_ext_context {
+ struct {
+ TBIEXTCTX ctx;
+ TBICTXEXTBB8 bb8;
+ TBIDUAL ax[TBICTXEXTAXX_BYTES / sizeof(TBIDUAL)];
+ TBICTXEXTHL2 hl2;
+ TBICTXEXTTDPR ext;
+ TBICTXEXTRP6 rp;
+ } regs;
+
+ /* DSPRAM A and B save areas. */
+ void *ram[2];
+
+ /* ECH encoded size of DSPRAM save areas. */
+ unsigned int ram_sz[2];
+};
+#else
+struct meta_ext_context {};
+#endif
+
+struct thread_struct {
+ PTBICTX kernel_context;
+ /* A copy of the user process Sig.SaveMask. */
+ unsigned int user_flags;
+ struct meta_fpu_context *fpu_context;
+ void __user *tls_ptr;
+ unsigned short int_depth;
+ unsigned short txdefr_failure;
+ struct meta_ext_context *dsp_context;
+};
+
+#define INIT_THREAD { \
+ NULL, /* kernel_context */ \
+ 0, /* user_flags */ \
+ NULL, /* fpu_context */ \
+ NULL, /* tls_ptr */ \
+ 1, /* int_depth - we start in kernel */ \
+ 0, /* txdefr_failure */ \
+ NULL, /* dsp_context */ \
+}
+
+/* Needed to make #define as we are referencing 'current', that is not visible
+ * yet.
+ *
+ * Stack layout is as below.
+
+ argc argument counter (integer)
+ argv[0] program name (pointer)
+ argv[1...N] program args (pointers)
+ argv[argc-1] end of args (integer)
+ NULL
+ env[0...N] environment variables (pointers)
+ NULL
+
+ */
+#define start_thread(regs, pc, usp) do { \
+ unsigned int *argc = (unsigned int *) bprm->exec; \
+ set_fs(USER_DS); \
+ current->thread.int_depth = 1; \
+ /* Force this process down to user land */ \
+ regs->ctx.SaveMask = TBICTX_PRIV_BIT; \
+ regs->ctx.CurrPC = pc; \
+ regs->ctx.AX[0].U0 = usp; \
+ regs->ctx.DX[3].U1 = *((int *)argc); /* argc */ \
+ regs->ctx.DX[3].U0 = (int)((int *)argc + 1); /* argv */ \
+ regs->ctx.DX[2].U1 = (int)((int *)argc + \
+ regs->ctx.DX[3].U1 + 2); /* envp */ \
+ regs->ctx.DX[2].U0 = 0; /* rtld_fini */ \
+} while (0)
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+#define copy_segments(tsk, mm) do { } while (0)
+#define release_segments(mm) do { } while (0)
+
+extern void exit_thread(void);
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+#define thread_saved_pc(tsk) \
+ ((unsigned long)(tsk)->thread.kernel_context->CurrPC)
+#define thread_saved_sp(tsk) \
+ ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0)
+#define thread_saved_fp(tsk) \
+ ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0)
+
+unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) ((tsk)->thread.kernel_context->CurrPC)
+#define KSTK_ESP(tsk) ((tsk)->thread.kernel_context->AX[0].U0)
+
+#define user_stack_pointer(regs) ((regs)->ctx.AX[0].U0)
+
+#define cpu_relax() barrier()
+
+extern void setup_priv(void);
+
+static inline unsigned int hard_processor_id(void)
+{
+ unsigned int id;
+
+ asm volatile ("MOV %0, TXENABLE\n"
+ "AND %0, %0, %1\n"
+ "LSR %0, %0, %2\n"
+ : "=&d" (id)
+ : "I" (TXENABLE_THREAD_BITS),
+ "K" (TXENABLE_THREAD_S)
+ );
+
+ return id;
+}
+
+#define OP3_EXIT 0
+
+#define HALT_OK 0
+#define HALT_PANIC -1
+
+/*
+ * Halt (stop) the hardware thread. This instruction sequence is the
+ * standard way to cause a Meta hardware thread to exit. The exit code
+ * is pushed onto the stack which is interpreted by the debug adapter.
+ */
+static inline void hard_processor_halt(int exit_code)
+{
+ asm volatile ("MOV D1Ar1, %0\n"
+ "MOV D0Ar6, %1\n"
+ "MSETL [A0StP],D0Ar6,D0Ar4,D0Ar2\n"
+ "1:\n"
+ "SWITCH #0xC30006\n"
+ "B 1b\n"
+ : : "r" (exit_code), "K" (OP3_EXIT));
+}
+
+/* Set these hooks to call SoC specific code to restart/halt/power off. */
+extern void (*soc_restart)(char *cmd);
+extern void (*soc_halt)(void);
+
+extern void show_trace(struct task_struct *tsk, unsigned long *sp,
+ struct pt_regs *regs);
+
+#endif