1 /* include/asm-sparc/processor.h
2 *
3 * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
4 */
5
6 #ifndef __ASM_SPARC_PROCESSOR_H
7 #define __ASM_SPARC_PROCESSOR_H
8
9 #include <linux/sched.h> /* For intr_count */
10
11 #include <asm/ptrace.h> /* For pt_regs declaration */
12
13 /*
14 * Bus types
15 */
16 #define EISA_bus 0
17 #define EISA_bus__is_a_macro /* for versions in ksyms.c */
18 #define MCA_bus 0
19 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
20
21 /*
22 * Write Protection works right in supervisor mode on the Sparc
23 */
24 #if 0 /* Let's try this out ;) */
25 #define wp_works_ok 1
26 #define wp_works_ok__is_a_macro /* for versions in ksyms.c */
27 #else
28 extern char wp_works_ok;
29 #endif
30
31 /*
32 * User space process size: 3GB. This is hardcoded into a few places,
33 * so don't change it unless you know what you are doing.
34 *
35 * With the way identity mapping works on the sun4c, this is the best
36 * value to use.
37 *
38 * This has to be looked into for a unified sun4c/sun4m task size.
39 */
40 #define TASK_SIZE (0xC000000UL)
41
42 /*
43 * Size of io_bitmap in longwords: 32 is ports 0-0x3ff.
44 */
45 #define IO_BITMAP_SIZE 32
46
47 /* The first four entries here MUST be the first four. This allows me to
48 * do %lo(offset) loads and stores in entry.S. See TRAP_WIN_CLEAN to see
49 * why.
50 */
51
52 struct thread_struct {
53 unsigned long uwindows; /* how many user windows are in the set */
54 unsigned long wim; /* user's window invalid mask */
55 unsigned long w_saved; /* how many windows saved in reg_window[] */
56 unsigned long ksp; /* kernel stack pointer */
57 unsigned long usp; /* user's sp, throw reg windows here */
58 unsigned long psr; /* save for condition codes */
59 unsigned long pc; /* program counter */
60 unsigned long npc; /* next program counter */
61 unsigned long yreg;
62 unsigned long align; /* to get 8-byte alignment XXX */
63 unsigned long reg_window[16];
64 unsigned long pgd_ptr;
65 int context; /* The context allocated to this thread */
66
67 /* 8 local registers + 8 in registers * 24 register windows.
68 * Most sparcs I know of only have 7 or 8 windows implemented,
69 * we determine how many at boot time and store that value
70 * in nwindows.
71 */
72 unsigned long float_regs[64]; /* V8 and below have 32, V9 has 64 */
73 };
74
75 #define INIT_MMAP { &init_task, (PAGE_OFFSET), (0xff000000UL), \
76 0x0 , VM_READ | VM_WRITE | VM_EXEC }
77
78 #define INIT_TSS { \
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
80 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
81 (long) &swapper_pg_dir, -1, \
82 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
83 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
84 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
85 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, \
86 }
87
88 /* The thread_frame is what needs to be set up in certain circumstances
89 * upon entry to a trap. It is also loaded sometimes during a window
90 * spill if things don't go right (bad user stack pointer). In reality
91 * it is not per-process per se, it just sits in the kernel stack while
92 * the current process is in a handler then it is basically forgotten
93 * about the next time flow control goes back to that process.
94 */
95
96 /* Sparc stack save area allocated for each save, not very exciting. */
97 struct sparc_save_stack {
98 unsigned int locals[8];
99 unsigned int ins[8];
100 unsigned int padd[8];
101 };
102
103 /*
104 * These are the "cli()" and "sti()" for software interrupts
105 * They work by increasing/decreasing the "intr_count" value,
106 * and as such can be nested arbitrarily.
107 */
108 extern inline void start_bh_atomic(void)
/* ![[previous]](../icons/n_left.png)
![[next]](../icons/right.png)
![[first]](../icons/n_first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
109 {
110 __asm__ __volatile__("rd %%psr, %%g2\n\t"
111 "wr %%g2, 0x20, %%psr\n\t" /* disable traps */
112 "ld %0,%%g3\n\t"
113 "add %%g3,1,%%g3\n\t"
114 "st %%g3,%0\n\t"
115 "wr %%g2, 0x0, %%psr\n\t" /* enable traps */
116 : "=m" (intr_count)
117 : : "g2", "g3", "memory");
118 }
119
120 extern inline void end_bh_atomic(void)
/* ![[previous]](../icons/left.png)
![[next]](../icons/right.png)
![[first]](../icons/first.png)
![[last]](../icons/last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
121 {
122 __asm__ __volatile__("rd %%psr, %%g2\n\t"
123 "wr %%g2, 0x20, %%psr\n\t"
124 "ld %0,%%g3\n\t"
125 "sub %%g3,1,%%g3\n\t"
126 "st %%g3,%0\n\t"
127 "wr %%g2, 0x0, %%psr\n\t"
128 : "=m" (intr_count)
129 : : "g2", "g3", "memory");
130 }
131
132 /*
133 * Do necessary setup to start up a newly executed thread.
134 */
135 static inline void start_thread(struct pt_regs * regs, unsigned long sp,
/* ![[previous]](../icons/left.png)
![[next]](../icons/n_right.png)
![[first]](../icons/first.png)
![[last]](../icons/n_last.png)
![[top]](../icons/top.png)
![[bottom]](../icons/bottom.png)
![[index]](../icons/index.png)
*/
136 unsigned long fp)
137 {
138 printk("start_thread called, halting..n");
139 halt();
140 }
141
142 #endif /* __ASM_SPARC_PROCESSOR_H */
143