linux/arch/metag/include/asm/processor.h
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2005,2006,2007,2008 Imagination Technologies
   3 */
   4
   5#ifndef __ASM_METAG_PROCESSOR_H
   6#define __ASM_METAG_PROCESSOR_H
   7
   8#include <linux/atomic.h>
   9
  10#include <asm/page.h>
  11#include <asm/ptrace.h>
  12#include <asm/metag_regs.h>
  13
  14/*
  15 * Default implementation of macro that returns current
  16 * instruction pointer ("program counter").
  17 */
  18#define current_text_addr() ({ __label__ _l; _l: &&_l; })
  19
  20/* The task stops where the kernel starts */
  21#define TASK_SIZE       PAGE_OFFSET
  22/* Add an extra page of padding at the top of the stack for the guard page. */
  23#define STACK_TOP       (TASK_SIZE - PAGE_SIZE)
  24#define STACK_TOP_MAX   STACK_TOP
  25
  26/* This decides where the kernel will search for a free chunk of vm
  27 * space during mmap's.
  28 */
  29#define TASK_UNMAPPED_BASE      META_MEMORY_BASE
  30
  31typedef struct {
  32        unsigned long seg;
  33} mm_segment_t;
  34
  35#ifdef CONFIG_METAG_FPU
  36struct meta_fpu_context {
  37        TBICTXEXTFPU fpstate;
  38        union {
  39                struct {
  40                        TBICTXEXTBB4 fx8_15;
  41                        TBICTXEXTFPACC fpacc;
  42                } fx8_15;
  43                struct {
  44                        TBICTXEXTFPACC fpacc;
  45                        TBICTXEXTBB4 unused;
  46                } nofx8_15;
  47        } extfpstate;
  48        bool needs_restore;
  49};
  50#else
  51struct meta_fpu_context {};
  52#endif
  53
  54#ifdef CONFIG_METAG_DSP
  55struct meta_ext_context {
  56        struct {
  57                TBIEXTCTX ctx;
  58                TBICTXEXTBB8 bb8;
  59                TBIDUAL ax[TBICTXEXTAXX_BYTES / sizeof(TBIDUAL)];
  60                TBICTXEXTHL2 hl2;
  61                TBICTXEXTTDPR ext;
  62                TBICTXEXTRP6 rp;
  63        } regs;
  64
  65        /* DSPRAM A and B save areas. */
  66        void *ram[2];
  67
  68        /* ECH encoded size of DSPRAM save areas. */
  69        unsigned int ram_sz[2];
  70};
  71#else
  72struct meta_ext_context {};
  73#endif
  74
  75struct thread_struct {
  76        PTBICTX kernel_context;
  77        /* A copy of the user process Sig.SaveMask. */
  78        unsigned int user_flags;
  79        struct meta_fpu_context *fpu_context;
  80        void __user *tls_ptr;
  81        unsigned short int_depth;
  82        unsigned short txdefr_failure;
  83        struct meta_ext_context *dsp_context;
  84};
  85
  86#define INIT_THREAD  { \
  87        NULL,                   /* kernel_context */    \
  88        0,                      /* user_flags */        \
  89        NULL,                   /* fpu_context */       \
  90        NULL,                   /* tls_ptr */           \
  91        1,                      /* int_depth - we start in kernel */    \
  92        0,                      /* txdefr_failure */    \
  93        NULL,                   /* dsp_context */       \
  94}
  95
  96/* Needed to make #define as we are referencing 'current', that is not visible
  97 * yet.
  98 *
  99 * Stack layout is as below.
 100
 101      argc            argument counter (integer)
 102      argv[0]         program name (pointer)
 103      argv[1...N]     program args (pointers)
 104      argv[argc-1]    end of args (integer)
 105      NULL
 106      env[0...N]      environment variables (pointers)
 107      NULL
 108
 109 */
 110#define start_thread(regs, pc, usp) do {                                   \
 111        unsigned int *argc = (unsigned int *) bprm->exec;                  \
 112        set_fs(USER_DS);                                                   \
 113        current->thread.int_depth = 1;                                     \
 114        /* Force this process down to user land */                         \
 115        regs->ctx.SaveMask = TBICTX_PRIV_BIT;                              \
 116        regs->ctx.CurrPC = pc;                                             \
 117        regs->ctx.AX[0].U0 = usp;                                          \
 118        regs->ctx.DX[3].U1 = *((int *)argc);                    /* argc */ \
 119        regs->ctx.DX[3].U0 = (int)((int *)argc + 1);            /* argv */ \
 120        regs->ctx.DX[2].U1 = (int)((int *)argc +                           \
 121                                   regs->ctx.DX[3].U1 + 2);     /* envp */ \
 122        regs->ctx.DX[2].U0 = 0;                            /* rtld_fini */ \
 123} while (0)
 124
 125/* Forward declaration, a strange C thing */
 126struct task_struct;
 127
 128/* Free all resources held by a thread. */
 129static inline void release_thread(struct task_struct *dead_task)
 130{
 131}
 132
 133#define copy_segments(tsk, mm)          do { } while (0)
 134#define release_segments(mm)            do { } while (0)
 135
 136extern void exit_thread(void);
 137
 138/*
 139 * Return saved PC of a blocked thread.
 140 */
 141#define thread_saved_pc(tsk)    \
 142        ((unsigned long)(tsk)->thread.kernel_context->CurrPC)
 143#define thread_saved_sp(tsk)    \
 144        ((unsigned long)(tsk)->thread.kernel_context->AX[0].U0)
 145#define thread_saved_fp(tsk)    \
 146        ((unsigned long)(tsk)->thread.kernel_context->AX[1].U0)
 147
 148unsigned long get_wchan(struct task_struct *p);
 149
 150#define KSTK_EIP(tsk)   ((tsk)->thread.kernel_context->CurrPC)
 151#define KSTK_ESP(tsk)   ((tsk)->thread.kernel_context->AX[0].U0)
 152
 153#define user_stack_pointer(regs)        ((regs)->ctx.AX[0].U0)
 154
 155#define cpu_relax()     barrier()
 156
 157extern void setup_priv(void);
 158
 159static inline unsigned int hard_processor_id(void)
 160{
 161        unsigned int id;
 162
 163        asm volatile ("MOV      %0, TXENABLE\n"
 164                      "AND      %0, %0, %1\n"
 165                      "LSR      %0, %0, %2\n"
 166                      : "=&d" (id)
 167                      : "I" (TXENABLE_THREAD_BITS),
 168                        "K" (TXENABLE_THREAD_S)
 169                      );
 170
 171        return id;
 172}
 173
 174#define OP3_EXIT        0
 175
 176#define HALT_OK         0
 177#define HALT_PANIC      -1
 178
 179/*
 180 * Halt (stop) the hardware thread. This instruction sequence is the
 181 * standard way to cause a Meta hardware thread to exit. The exit code
 182 * is pushed onto the stack which is interpreted by the debug adapter.
 183 */
 184static inline void hard_processor_halt(int exit_code)
 185{
 186        asm volatile ("MOV      D1Ar1, %0\n"
 187                      "MOV      D0Ar6, %1\n"
 188                      "MSETL    [A0StP],D0Ar6,D0Ar4,D0Ar2\n"
 189                      "1:\n"
 190                      "SWITCH   #0xC30006\n"
 191                      "B                1b\n"
 192                      : : "r" (exit_code), "K" (OP3_EXIT));
 193}
 194
 195/* Set these hooks to call SoC specific code to restart/halt/power off. */
 196extern void (*soc_restart)(char *cmd);
 197extern void (*soc_halt)(void);
 198
 199extern void show_trace(struct task_struct *tsk, unsigned long *sp,
 200                       struct pt_regs *regs);
 201
 202extern const struct seq_operations cpuinfo_op;
 203
 204#endif
 205