File: system.h

package info (click to toggle)
kernel-source-2.0.38 2.0.38-3
  • links: PTS
  • area: main
  • in suites: potato
  • size: 34,660 kB
  • ctags: 102,964
  • sloc: ansic: 632,204; asm: 26,444; makefile: 4,286; sh: 1,276; perl: 761; tcl: 408; cpp: 277; lisp: 211; awk: 134
file content (167 lines) | stat: -rw-r--r-- 4,495 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* $Id: system.h,v 1.29 1996/04/03 02:17:52 davem Exp $ */
#ifndef __SPARC_SYSTEM_H
#define __SPARC_SYSTEM_H

#include <linux/kernel.h>

#include <asm/segment.h>

#ifdef __KERNEL__
#include <asm/page.h>
#include <asm/oplib.h>
#include <asm/psr.h>
#endif

#define EMPTY_PGT       (&empty_bad_page)
#define EMPTY_PGE	(&empty_bad_page_table)

#ifndef __ASSEMBLY__

/*
 * Sparc (general) CPU types
 */
enum sparc_cpu {
  sun4        = 0x00,
  sun4c       = 0x01,
  sun4m       = 0x02,
  sun4d       = 0x03,
  sun4e       = 0x04,
  sun4u       = 0x05, /* V8 ploos ploos */
  sun_unknown = 0x06,
};

extern enum sparc_cpu sparc_cpu_model;

extern unsigned long empty_bad_page;
extern unsigned long empty_bad_page_table;
extern unsigned long empty_zero_page;

extern struct linux_romvec *romvec;
#define halt() romvec->pv_halt()

/* When a context switch happens we must flush all user windows so that
 * the windows of the current process are flushed onto its stack. This
 * way the windows are all clean for the next process and the stack
 * frames are up to date.
 */
extern void flush_user_windows(void);
extern void synchronize_user_stack(void);
extern void sparc_switch_to(void *new_task);
#ifndef __SMP__
#define switch_to(prev, next) do { \
			  flush_user_windows(); \
		          switch_to_context(next); \
			  prev->tss.current_ds = active_ds; \
                          active_ds = next->tss.current_ds; \
			  if(last_task_used_math != next) \
				  next->tss.kregs->psr &= ~PSR_EF; \
                          sparc_switch_to(next); \
                     } while(0)
#else

extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
		   void *fpqueue, unsigned long *fpqdepth);

#define switch_to(prev, next) do { \
			  cli(); \
			  if(prev->flags & PF_USEDFPU) { \
                          	fpsave(&prev->tss.float_regs[0], &prev->tss.fsr, \
                          	       &prev->tss.fpqueue[0], &prev->tss.fpqdepth); \
                          	prev->flags &= ~PF_USEDFPU; \
                          	prev->tss.kregs->psr &= ~PSR_EF; \
                          } \
			  prev->lock_depth = syscall_count; \
			  kernel_counter += (next->lock_depth - prev->lock_depth); \
			  syscall_count = next->lock_depth; \
			  flush_user_windows(); \
		          switch_to_context(next); \
			  prev->tss.current_ds = active_ds; \
                          active_ds = next->tss.current_ds; \
                          sparc_switch_to(next); \
			  sti(); \
                     } while(0)
#endif

/* Changing the IRQ level on the Sparc. */
extern inline void setipl(int __new_ipl)
{
	__asm__ __volatile__("rd %%psr, %%g1\n\t"
			     "andn %%g1, %1, %%g1\n\t"
			     "sll %0, 8, %%g2\n\t"
			     "and %%g2, %1, %%g2\n\t"
			     "or %%g1, %%g2, %%g1\n\t"
			     "wr %%g1, 0x0, %%psr\n\t"
			     "nop; nop; nop\n\t" : :
			     "r" (__new_ipl), "i" (PSR_PIL) :
			     "g1", "g2");
}

extern inline int getipl(void)
{
	int retval;

	__asm__ __volatile__("rd %%psr, %0\n\t"
			     "and %0, %1, %0\n\t"
			     "srl %0, 8, %0\n\t" :
			     "=r" (retval) :
			     "i" (PSR_PIL));
	return retval;
}

extern inline int swpipl(int __new_ipl)
{
	int retval;

	__asm__ __volatile__("rd %%psr, %%g1\n\t"
			     "srl %%g1, 8, %0\n\t"
			     "and %0, 15, %0\n\t"
			     "andn %%g1, %2, %%g1\n\t"
			     "and %1, 15, %%g2\n\t"
			     "sll %%g2, 8, %%g2\n\t"
			     "or %%g1, %%g2, %%g1\n\t"
			     "wr %%g1, 0x0, %%psr\n\t"
			     "nop; nop; nop\n\t" :
			     "=r" (retval) :
			     "r" (__new_ipl), "i" (PSR_PIL) :
			     "g1", "g2");
	return retval;
}

extern char spdeb_buf[256];

#define cli()			setipl(15)  /* 15 = no int's except nmi's */
#define sti()			setipl(0)   /* I'm scared */
#define save_flags(flags)	do { flags = getipl(); } while (0)
#define restore_flags(flags)	setipl(flags)

#define nop() __asm__ __volatile__ ("nop");

extern inline unsigned long xchg_u32(volatile unsigned long *m, unsigned long val)
{
	unsigned long flags, retval;

	save_flags(flags); cli();
	retval = *m;
	*m = val;
	restore_flags(flags);
	return retval;
}

#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
#define tas(ptr) (xchg((ptr),1))

extern void __xchg_called_with_bad_pointer(void);

static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
{
	switch (size) {
	case 4:
		return xchg_u32(ptr, x);
	};
	__xchg_called_with_bad_pointer();
	return x;
}

#endif /* __ASSEMBLY__ */

#endif /* !(__SPARC_SYSTEM_H) */