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