1 /*
2  * include/asm-h8300/processor.h
3  *
4  * Copyright (C) 2002 Yoshinori Sato
5  *
6  * Based on: linux/asm-m68nommu/processor.h
7  *
8  * Copyright (C) 1995 Hamish Macdonald
9  */
10 
11 #ifndef __ASM_H8300_PROCESSOR_H
12 #define __ASM_H8300_PROCESSOR_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 #include <linux/compiler.h>
21 #include <asm/segment.h>
22 #include <asm/ptrace.h>
23 #include <asm/current.h>
24 
rdusp(void)25 static inline unsigned long rdusp(void)
26 {
27 	extern unsigned int	_sw_usp;
28 
29 	return _sw_usp;
30 }
31 
wrusp(unsigned long usp)32 static inline void wrusp(unsigned long usp)
33 {
34 	extern unsigned int	_sw_usp;
35 
36 	_sw_usp = usp;
37 }
38 
39 /*
40  * User space process size: 3.75GB. This is hardcoded into a few places,
41  * so don't change it unless you know what you are doing.
42  */
43 #define TASK_SIZE	(0xFFFFFFFFUL)
44 
45 #ifdef __KERNEL__
46 #define STACK_TOP	TASK_SIZE
47 #define STACK_TOP_MAX	STACK_TOP
48 #endif
49 
50 /*
51  * This decides where the kernel will search for a free chunk of vm
52  * space during mmap's. We won't be using it
53  */
54 #define TASK_UNMAPPED_BASE	0
55 
56 struct thread_struct {
57 	unsigned long  ksp;		/* kernel stack pointer */
58 	unsigned long  usp;		/* user stack pointer */
59 	unsigned long  ccr;		/* saved status register */
60 	unsigned long  esp0;            /* points to SR of stack frame */
61 	struct {
62 		unsigned short *addr;
63 		unsigned short inst;
64 	} breakinfo;
65 };
66 
67 #define INIT_THREAD  {						\
68 	.ksp  = sizeof(init_stack) + (unsigned long)init_stack, \
69 	.usp  = 0,						\
70 	.ccr  = PS_S,						\
71 	.esp0 = 0,						\
72 	.breakinfo = {						\
73 		.addr = (unsigned short *)-1,			\
74 		.inst = 0					\
75 	}							\
76 }
77 
78 /*
79  * Do necessary setup to start up a newly executed thread.
80  *
81  * pass the data segment into user programs if it exists,
82  * it can't hurt anything as far as I can tell
83  */
84 #if defined(CONFIG_CPU_H8300H)
85 #define start_thread(_regs, _pc, _usp)				\
86 do {								\
87 	(_regs)->pc = (_pc);					\
88 	(_regs)->ccr = 0x00;	   /* clear all flags */	\
89 	(_regs)->er5 = current->mm->start_data;	/* GOT base */	\
90 	(_regs)->sp = ((unsigned long)(_usp)) - sizeof(unsigned long) * 3; \
91 } while (0)
92 #endif
93 #if defined(CONFIG_CPU_H8S)
94 #define start_thread(_regs, _pc, _usp)				\
95 do {								\
96 	(_regs)->pc = (_pc);					\
97 	(_regs)->ccr = 0x00;	   /* clear kernel flag */	\
98 	(_regs)->exr = 0x78;	   /* enable all interrupts */	\
99 	(_regs)->er5 = current->mm->start_data;	/* GOT base */	\
100 	/* 14 = space for retaddr(4), vector(4), er0(4) and exr(2) on stack */ \
101 	(_regs)->sp = ((unsigned long)(_usp)) - 14;		\
102 } while (0)
103 #endif
104 
105 /* Forward declaration, a strange C thing */
106 struct task_struct;
107 
108 /* Free all resources held by a thread. */
release_thread(struct task_struct * dead_task)109 static inline void release_thread(struct task_struct *dead_task)
110 {
111 }
112 
113 /*
114  * Free current thread data structures etc..
115  */
exit_thread(void)116 static inline void exit_thread(void)
117 {
118 }
119 
120 /*
121  * Return saved PC of a blocked thread.
122  */
123 unsigned long thread_saved_pc(struct task_struct *tsk);
124 unsigned long get_wchan(struct task_struct *p);
125 
126 #define	KSTK_EIP(tsk)	\
127 	({			 \
128 		unsigned long eip = 0;	      \
129 		if ((tsk)->thread.esp0 > PAGE_SIZE &&	\
130 		    MAP_NR((tsk)->thread.esp0) < max_mapnr)	 \
131 			eip = ((struct pt_regs *) (tsk)->thread.esp0)->pc; \
132 		eip; })
133 
134 #define	KSTK_ESP(tsk)	((tsk) == current ? rdusp() : (tsk)->thread.usp)
135 
136 #define cpu_relax()    barrier()
137 #define cpu_relax_lowlatency()	cpu_relax()
138 
139 #define HARD_RESET_NOW() ({		\
140 	local_irq_disable();		\
141 	asm("jmp @@0");			\
142 })
143 
144 #endif
145