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#ifndef CONFIG_SUN3
  52#define TASK_SIZE       (0xF0000000UL)
  53#else
  54#define TASK_SIZE       (0x0E000000UL)
  55#endif
  56#else
  57#define TASK_SIZE       (0xFFFFFFFFUL)
  58#endif
  59
  60#ifdef __KERNEL__
  61#define STACK_TOP       TASK_SIZE
  62#define STACK_TOP_MAX   STACK_TOP
  63#endif
  64
  65/* This decides where the kernel will search for a free chunk of vm
  66 * space during mmap's.
  67 */
  68#ifdef CONFIG_MMU
  69#ifndef CONFIG_SUN3
  70#define TASK_UNMAPPED_BASE      0xC0000000UL
  71#else
  72#define TASK_UNMAPPED_BASE      0x0A000000UL
  73#endif
  74#define TASK_UNMAPPED_ALIGN(addr, off)  PAGE_ALIGN(addr)
  75#else
  76#define TASK_UNMAPPED_BASE      0
  77#endif
  78
  79struct thread_struct {
  80        unsigned long  ksp;             /* kernel stack pointer */
  81        unsigned long  usp;             /* user stack pointer */
  82        unsigned short sr;              /* saved status register */
  83        unsigned short fs;              /* saved fs (sfc, dfc) */
  84        unsigned long  crp[2];          /* cpu root pointer */
  85        unsigned long  esp0;            /* points to SR of stack frame */
  86        unsigned long  faddr;           /* info about last fault */
  87        int            signo, code;
  88        unsigned long  fp[8*3];
  89        unsigned long  fpcntl[3];       /* fp control regs */
  90        unsigned char  fpstate[FPSTATESIZE];  /* floating point state */
  91        struct thread_info info;
  92};
  93
  94#define INIT_THREAD  {                                                  \
  95        .ksp    = sizeof(init_stack) + (unsigned long) init_stack,      \
  96        .sr     = PS_S,                                                 \
  97        .fs     = __KERNEL_DS,                                          \
  98        .info   = INIT_THREAD_INFO(init_task),                          \
  99}
 100
 101#ifdef CONFIG_MMU
 102/*
 103 * Do necessary setup to start up a newly executed thread.
 104 */
 105static inline void start_thread(struct pt_regs * regs, unsigned long pc,
 106                                unsigned long usp)
 107{
 108        regs->pc = pc;
 109        regs->sr &= ~0x2000;
 110        wrusp(usp);
 111}
 112
 113extern int handle_kernel_fault(struct pt_regs *regs);
 114
 115#else
 116
 117/*
 118 * Coldfire stacks need to be re-aligned on trap exit, conventional
 119 * 68k can handle this case cleanly.
 120 */
 121#ifdef CONFIG_COLDFIRE
 122#define reformat(_regs)         do { (_regs)->format = 0x4; } while(0)
 123#else
 124#define reformat(_regs)         do { } while (0)
 125#endif
 126
 127#define start_thread(_regs, _pc, _usp)                  \
 128do {                                                    \
 129        (_regs)->pc = (_pc);                            \
 130        ((struct switch_stack *)(_regs))[-1].a6 = 0;    \
 131        reformat(_regs);                                \
 132        if (current->mm)                                \
 133                (_regs)->d5 = current->mm->start_data;  \
 134        (_regs)->sr &= ~0x2000;                         \
 135        wrusp(_usp);                                    \
 136} while(0)
 137
 138#endif
 139
 140/* Forward declaration, a strange C thing */
 141struct task_struct;
 142
 143/* Free all resources held by a thread. */
 144static inline void release_thread(struct task_struct *dead_task)
 145{
 146}
 147
 148/* Prepare to copy thread state - unlazy all lazy status */
 149#define prepare_to_copy(tsk)    do { } while (0)
 150
 151extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
 152
 153/*
 154 * Free current thread data structures etc..
 155 */
 156static inline void exit_thread(void)
 157{
 158}
 159
 160extern unsigned long thread_saved_pc(struct task_struct *tsk);
 161
 162unsigned long get_wchan(struct task_struct *p);
 163
 164#define KSTK_EIP(tsk)   \
 165    ({                  \
 166        unsigned long eip = 0;   \
 167        if ((tsk)->thread.esp0 > PAGE_SIZE && \
 168            (virt_addr_valid((tsk)->thread.esp0))) \
 169              eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
 170        eip; })
 171#define KSTK_ESP(tsk)   ((tsk) == current ? rdusp() : (tsk)->thread.usp)
 172
 173#define task_pt_regs(tsk)       ((struct pt_regs *) ((tsk)->thread.esp0))
 174
 175#define cpu_relax()     barrier()
 176
 177#endif
 178