linux/arch/m68k/include/asm/processor.h
<<
>>
Prefs
   1/*
   2 * include/asm-m68k/processor.h
   3 *
   4 * Copyright (C) 1995 Hamish Macdonald
   5 */
   6
   7#ifndef __ASM_M68K_PROCESSOR_H
   8#define __ASM_M68K_PROCESSOR_H
   9
  10/*
  11 * Default implementation of macro that returns current
  12 * instruction pointer ("program counter").
  13 */
  14#define current_text_addr() ({ __label__ _l; _l: &&_l;})
  15
  16#include <linux/thread_info.h>
  17#include <asm/segment.h>
  18#include <asm/fpu.h>
  19#include <asm/ptrace.h>
  20
  21static inline unsigned long rdusp(void)
  22{
  23#ifdef CONFIG_COLDFIRE_SW_A7
  24        extern unsigned int sw_usp;
  25        return sw_usp;
  26#else
  27        register unsigned long usp __asm__("a0");
  28        /* move %usp,%a0 */
  29        __asm__ __volatile__(".word 0x4e68" : "=a" (usp));
  30        return usp;
  31#endif
  32}
  33
  34static inline void wrusp(unsigned long usp)
  35{
  36#ifdef CONFIG_COLDFIRE_SW_A7
  37        extern unsigned int sw_usp;
  38        sw_usp = usp;
  39#else
  40        register unsigned long a0 __asm__("a0") = usp;
  41        /* move %a0,%usp */
  42        __asm__ __volatile__(".word 0x4e60" : : "a" (a0) );
  43#endif
  44}
  45
  46/*
  47 * User space process size: 3.75GB. This is hardcoded into a few places,
  48 * so don't change it unless you know what you are doing.
  49 */
  50#ifdef CONFIG_MMU
  51#if defined(CONFIG_COLDFIRE)
  52#define TASK_SIZE       (0xC0000000UL)
  53#elif defined(CONFIG_SUN3)
  54#define TASK_SIZE       (0x0E000000UL)
  55#else
  56#define TASK_SIZE       (0xF0000000UL)
  57#endif
  58#else
  59#define TASK_SIZE       (0xFFFFFFFFUL)
  60#endif
  61
  62#ifdef __KERNEL__
  63#define STACK_TOP       TASK_SIZE
  64#define STACK_TOP_MAX   STACK_TOP
  65#endif
  66
  67/* This decides where the kernel will search for a free chunk of vm
  68 * space during mmap's.
  69 */
  70#ifdef CONFIG_MMU
  71#if defined(CONFIG_COLDFIRE)
  72#define TASK_UNMAPPED_BASE      0x60000000UL
  73#elif defined(CONFIG_SUN3)
  74#define TASK_UNMAPPED_BASE      0x0A000000UL
  75#else
  76#define TASK_UNMAPPED_BASE      0xC0000000UL
  77#endif
  78#define TASK_UNMAPPED_ALIGN(addr, off)  PAGE_ALIGN(addr)
  79#else
  80#define TASK_UNMAPPED_BASE      0
  81#endif
  82
  83struct thread_struct {
  84        unsigned long  ksp;             /* kernel stack pointer */
  85        unsigned long  usp;             /* user stack pointer */
  86        unsigned short sr;              /* saved status register */
  87        unsigned short fs;              /* saved fs (sfc, dfc) */
  88        unsigned long  crp[2];          /* cpu root pointer */
  89        unsigned long  esp0;            /* points to SR of stack frame */
  90        unsigned long  faddr;           /* info about last fault */
  91        int            signo, code;
  92        unsigned long  fp[8*3];
  93        unsigned long  fpcntl[3];       /* fp control regs */
  94        unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
  95};
  96
  97#define INIT_THREAD  {                                                  \
  98        .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
  99        .sr     = PS_S,                                                 \
 100        .fs     = __KERNEL_DS,                                          \
 101}
 102
 103/*
 104 * ColdFire stack format sbould be 0x4 for an aligned usp (will always be
 105 * true on thread creation). We need to set this explicitly.
 106 */
 107#ifdef CONFIG_COLDFIRE
 108#define setframeformat(_regs)   do { (_regs)->format = 0x4; } while(0)
 109#else
 110#define setframeformat(_regs)   do { } while (0)
 111#endif
 112
 113#ifdef CONFIG_MMU
 114/*
 115 * Do necessary setup to start up a newly executed thread.
 116 */
 117static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 118                                unsigned long usp)
 119{
 120        regs->pc = pc;
 121        regs->sr &= ~0x2000;
 122        setframeformat(regs);
 123        wrusp(usp);
 124}
 125
 126extern int handle_kernel_fault(struct pt_regs *regs);
 127
 128#else
 129
 130#define start_thread(_regs, _pc, _usp)                  \
 131do {                                                    \
 132        (_regs)->pc = (_pc);                            \
 133        setframeformat(_regs);                          \
 134        if (current->mm)                                \
 135                (_regs)->d5 = current->mm->start_data;  \
 136        (_regs)->sr &= ~0x2000;                         \
 137        wrusp(_usp);                                    \
 138} while(0)
 139
 140static inline  int handle_kernel_fault(struct pt_regs *regs)
 141{
 142        /* Any fault in kernel is fatal on non-mmu */
 143        return 0;
 144}
 145
 146#endif
 147
 148/* Forward declaration, a strange C thing */
 149struct task_struct;
 150
 151/* Free all resources held by a thread. */
 152static inline void release_thread(struct task_struct *dead_task)
 153{
 154}
 155
 156/*
 157 * Free current thread data structures etc..
 158 */
 159static inline void exit_thread(void)
 160{
 161}
 162
 163extern unsigned long thread_saved_pc(struct task_struct *tsk);
 164
 165unsigned long get_wchan(struct task_struct *p);
 166
 167#define KSTK_EIP(tsk)   \
 168    ({                  \
 169        unsigned long eip = 0;   \
 170        if ((tsk)->thread.esp0 > PAGE_SIZE && \
 171            (virt_addr_valid((tsk)->thread.esp0))) \
 172              eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
 173        eip; })
 174#define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 175
 176#define task_pt_regs(tsk)       ((struct pt_regs *) ((tsk)->thread.esp0))
 177
 178#define cpu_relax()     barrier()
 179
 180#endif
 181