2007-11-09 17:08:54 +09:00
# ifndef __ASM_SH_PROCESSOR_64_H
# define __ASM_SH_PROCESSOR_64_H
2005-04-16 15:20:36 -07:00
/*
2007-11-09 17:08:54 +09:00
* include / asm - sh / processor_64 . h
2005-04-16 15:20:36 -07:00
*
* Copyright ( C ) 2000 , 2001 Paolo Alberelli
* Copyright ( C ) 2003 Paul Mundt
* Copyright ( C ) 2004 Richard Curnow
*
2007-11-09 17:08:54 +09:00
* This file is subject to the terms and conditions of the GNU General Public
* License . See the file " COPYING " in the main directory of this archive
* for more details .
2005-04-16 15:20:36 -07:00
*/
# ifndef __ASSEMBLY__
2007-11-09 17:08:54 +09:00
# include <linux/compiler.h>
# include <asm/page.h>
2005-04-16 15:20:36 -07:00
# include <asm/types.h>
# include <asm/cache.h>
2007-11-10 20:27:03 +09:00
# include <asm/ptrace.h>
2007-11-09 17:08:54 +09:00
# include <asm/cpu/registers.h>
2005-04-16 15:20:36 -07:00
/*
* Default implementation of macro that returns current
* instruction pointer ( " program counter " ) .
*/
# define current_text_addr() ({ \
void * pc ; \
unsigned long long __dummy = 0 ; \
__asm__ ( " gettr tr0, %1 \n \t " \
" pta 4, tr0 \n \t " \
" gettr tr0, %0 \n \t " \
" ptabs %1, tr0 \n \t " \
: " =r " ( pc ) , " =r " ( __dummy ) \
: " 1 " ( __dummy ) ) ; \
pc ; } )
/*
* TLB information structure
*
* Defined for both I and D tlb , per - processor .
*/
struct tlb_info {
unsigned long long next ;
unsigned long long first ;
unsigned long long last ;
unsigned int entries ;
unsigned int step ;
unsigned long flags ;
} ;
struct sh_cpuinfo {
enum cpu_type type ;
unsigned long loops_per_jiffy ;
2007-11-10 19:54:16 +09:00
unsigned long asid_cache ;
2005-04-16 15:20:36 -07:00
unsigned int cpu_clock , master_clock , bus_clock , module_clock ;
/* Cache info */
struct cache_info icache ;
struct cache_info dcache ;
2007-11-10 19:54:16 +09:00
struct cache_info scache ;
2005-04-16 15:20:36 -07:00
/* TLB info */
struct tlb_info itlb ;
struct tlb_info dtlb ;
2007-11-10 20:01:51 +09:00
unsigned long flags ;
} ;
2005-04-16 15:20:36 -07:00
2007-11-10 20:01:51 +09:00
extern struct sh_cpuinfo cpu_data [ ] ;
# define boot_cpu_data cpu_data[0]
# define current_cpu_data cpu_data[smp_processor_id()]
# define raw_current_cpu_data cpu_data[raw_smp_processor_id()]
2005-04-16 15:20:36 -07:00
# endif
/*
* User space process size : 2 GB - 4 k .
*/
# define TASK_SIZE 0x7ffff000UL
2008-02-08 04:19:26 -08:00
# define STACK_TOP TASK_SIZE
# define STACK_TOP_MAX STACK_TOP
2005-04-16 15:20:36 -07:00
/* This decides where the kernel will search for a free chunk of vm
* space during mmap ' s .
*/
# define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
/*
* Bit of SR register
*
* FD - bit :
* When it ' s set , it means the processor doesn ' t have right to use FPU ,
* and it results exception when the floating operation is executed .
*
* IMASK - bit :
* Interrupt level mask
*
* STEP - bit :
* Single step bit
*
*/
# if defined(CONFIG_SH64_SR_WATCH)
# define SR_MMU 0x84000000
# else
# define SR_MMU 0x80000000
# endif
# define SR_IMASK 0x000000f0
2008-03-26 19:02:47 +09:00
# define SR_FD 0x00008000
2005-04-16 15:20:36 -07:00
# define SR_SSTEP 0x08000000
# ifndef __ASSEMBLY__
/*
* FPU structure and data : require 8 - byte alignment as we need to access it
with fld . p , fst . p
*/
struct sh_fpu_hard_struct {
unsigned long fp_regs [ 64 ] ;
unsigned int fpscr ;
/* long status; * software status information */
} ;
#if 0
/* Dummy fpu emulator */
struct sh_fpu_soft_struct {
unsigned long long fp_regs [ 32 ] ;
unsigned int fpscr ;
unsigned char lookahead ;
unsigned long entry_pc ;
} ;
# endif
union sh_fpu_union {
struct sh_fpu_hard_struct hard ;
/* 'hard' itself only produces 32 bit alignment, yet we need
to access it using 64 bit load / store as well . */
unsigned long long alignment_dummy ;
} ;
struct thread_struct {
unsigned long sp ;
unsigned long pc ;
/* This stores the address of the pt_regs built during a context
switch , or of the register save area built for a kernel mode
exception . It is used for backtracing the stack of a sleeping task
or one that traps in kernel mode . */
struct pt_regs * kregs ;
/* This stores the address of the pt_regs constructed on entry from
user mode . It is a fixed value over the lifetime of a process , or
NULL for a kernel thread . */
struct pt_regs * uregs ;
unsigned long trap_no , error_code ;
unsigned long address ;
/* Hardware debugging registers may come here */
/* floating point info */
union sh_fpu_union fpu ;
} ;
2007-11-09 17:08:54 +09:00
typedef struct {
unsigned long seg ;
} mm_segment_t ;
2005-04-16 15:20:36 -07:00
# define INIT_MMAP \
{ & init_mm , 0 , 0 , NULL , PAGE_SHARED , VM_READ | VM_WRITE | VM_EXEC , 1 , NULL , NULL }
extern struct pt_regs fake_swapper_regs ;
# define INIT_THREAD { \
. sp = sizeof ( init_stack ) + \
( long ) & init_stack , \
. pc = 0 , \
. kregs = & fake_swapper_regs , \
. uregs = NULL , \
. trap_no = 0 , \
. error_code = 0 , \
. address = 0 , \
. fpu = { { { 0 , } } , } \
}
/*
* Do necessary setup to start up a newly executed thread .
*/
# define SR_USER (SR_MMU | SR_FD)
2007-11-09 17:08:54 +09:00
# define start_thread(regs, new_pc, new_sp) \
set_fs ( USER_DS ) ; \
regs - > sr = SR_USER ; /* User mode. */ \
2005-04-16 15:20:36 -07:00
regs - > pc = new_pc - 4 ; /* Compensate syscall exit */ \
regs - > pc | = 1 ; /* Set SHmedia ! */ \
2007-11-09 17:08:54 +09:00
regs - > regs [ 18 ] = 0 ; \
2005-04-16 15:20:36 -07:00
regs - > regs [ 15 ] = new_sp
/* Forward declaration, a strange C thing */
struct task_struct ;
struct mm_struct ;
/* Free all resources held by a thread. */
extern void release_thread ( struct task_struct * ) ;
/*
* create a kernel thread without removing it from tasklists
*/
extern int kernel_thread ( int ( * fn ) ( void * ) , void * arg , unsigned long flags ) ;
/* Copy and release all segment info associated with a VM */
# define copy_segments(p, mm) do { } while (0)
# define release_segments(mm) do { } while (0)
# define forget_segments() do { } while (0)
# define prepare_to_copy(tsk) do { } while (0)
/*
* FPU lazy state save handling .
*/
2007-11-10 20:27:03 +09:00
static inline void disable_fpu ( void )
2005-04-16 15:20:36 -07:00
{
unsigned long long __dummy ;
/* Set FD flag in SR */
__asm__ __volatile__ ( " getcon " __SR " , %0 \n \t "
" or %0, %1, %0 \n \t "
" putcon %0, " __SR " \n \t "
: " =&r " ( __dummy )
: " r " ( SR_FD ) ) ;
}
2007-11-10 20:27:03 +09:00
static inline void enable_fpu ( void )
2005-04-16 15:20:36 -07:00
{
unsigned long long __dummy ;
/* Clear out FD flag in SR */
__asm__ __volatile__ ( " getcon " __SR " , %0 \n \t "
" and %0, %1, %0 \n \t "
" putcon %0, " __SR " \n \t "
: " =&r " ( __dummy )
: " r " ( ~ SR_FD ) ) ;
}
/* Round to nearest, no exceptions on inexact, overflow, underflow,
zero - divide , invalid . Configure option for whether to flush denorms to
zero , or except if a denorm is encountered . */
# if defined(CONFIG_SH64_FPU_DENORM_FLUSH)
# define FPSCR_INIT 0x00040000
# else
# define FPSCR_INIT 0x00000000
# endif
2007-11-20 18:44:39 +09:00
# ifdef CONFIG_SH_FPU
2005-04-16 15:20:36 -07:00
/* Initialise the FP state of a task */
void fpinit ( struct sh_fpu_hard_struct * fpregs ) ;
2007-11-20 18:44:39 +09:00
# else
# define fpinit(fpregs) do { } while (0)
# endif
2005-04-16 15:20:36 -07:00
extern struct task_struct * last_task_used_math ;
/*
* Return saved PC of a blocked thread .
*/
# define thread_saved_pc(tsk) (tsk->thread.pc)
extern unsigned long get_wchan ( struct task_struct * p ) ;
# define KSTK_EIP(tsk) ((tsk)->thread.pc)
# define KSTK_ESP(tsk) ((tsk)->thread.sp)
2006-07-08 11:10:29 -05:00
# define cpu_relax() barrier()
2005-04-16 15:20:36 -07:00
# endif /* __ASSEMBLY__ */
2007-11-09 17:08:54 +09:00
# endif /* __ASM_SH_PROCESSOR_64_H */