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