Commit 1a7c55368c7c8749aa9326c29a50e79a4eba5d26

Authored by Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6:
  sparc64: Get rid of indirect p1275 PROM call buffer.
  sparc64: Fill a missing delay slot.
  sparc64: Make lock backoff really a NOP on UP builds.
  sparc64: simple microoptimizations for atomic functions
  sparc64: Make rwsems 64-bit.
  sparc64: Really fix atomic64_t interface types.

Showing 16 changed files Side-by-side Diff

arch/sparc/include/asm/atomic_64.h
... ... @@ -20,14 +20,14 @@
20 20 #define atomic64_set(v, i) (((v)->counter) = i)
21 21  
22 22 extern void atomic_add(int, atomic_t *);
23   -extern void atomic64_add(int, atomic64_t *);
  23 +extern void atomic64_add(long, atomic64_t *);
24 24 extern void atomic_sub(int, atomic_t *);
25   -extern void atomic64_sub(int, atomic64_t *);
  25 +extern void atomic64_sub(long, atomic64_t *);
26 26  
27 27 extern int atomic_add_ret(int, atomic_t *);
28   -extern long atomic64_add_ret(int, atomic64_t *);
  28 +extern long atomic64_add_ret(long, atomic64_t *);
29 29 extern int atomic_sub_ret(int, atomic_t *);
30   -extern long atomic64_sub_ret(int, atomic64_t *);
  30 +extern long atomic64_sub_ret(long, atomic64_t *);
31 31  
32 32 #define atomic_dec_return(v) atomic_sub_ret(1, v)
33 33 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
arch/sparc/include/asm/backoff.h
... ... @@ -8,6 +8,9 @@
8 8 #define BACKOFF_SETUP(reg) \
9 9 mov 1, reg
10 10  
  11 +#define BACKOFF_LABEL(spin_label, continue_label) \
  12 + spin_label
  13 +
11 14 #define BACKOFF_SPIN(reg, tmp, label) \
12 15 mov reg, tmp; \
13 16 88: brnz,pt tmp, 88b; \
... ... @@ -22,9 +25,11 @@
22 25 #else
23 26  
24 27 #define BACKOFF_SETUP(reg)
25   -#define BACKOFF_SPIN(reg, tmp, label) \
26   - ba,pt %xcc, label; \
27   - nop;
  28 +
  29 +#define BACKOFF_LABEL(spin_label, continue_label) \
  30 + continue_label
  31 +
  32 +#define BACKOFF_SPIN(reg, tmp, label)
28 33  
29 34 #endif
30 35  
arch/sparc/include/asm/oplib_64.h
... ... @@ -185,9 +185,8 @@
185 185 char *buf, int buflen);
186 186  
187 187 /* Retain physical memory to the caller across soft resets. */
188   -extern unsigned long prom_retain(const char *name,
189   - unsigned long pa_low, unsigned long pa_high,
190   - long size, long align);
  188 +extern int prom_retain(const char *name, unsigned long size,
  189 + unsigned long align, unsigned long *paddr);
191 190  
192 191 /* Load explicit I/D TLB entries into the calling processor. */
193 192 extern long prom_itlb_load(unsigned long index,
... ... @@ -287,27 +286,7 @@
287 286 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
288 287  
289 288 /* Client interface level routines. */
290   -extern long p1275_cmd(const char *, long, ...);
291   -
292   -#if 0
293   -#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
294   -#else
295   -#define P1275_SIZE(x) x
296   -#endif
297   -
298   -/* We support at most 16 input and 1 output argument */
299   -#define P1275_ARG_NUMBER 0
300   -#define P1275_ARG_IN_STRING 1
301   -#define P1275_ARG_OUT_BUF 2
302   -#define P1275_ARG_OUT_32B 3
303   -#define P1275_ARG_IN_FUNCTION 4
304   -#define P1275_ARG_IN_BUF 5
305   -#define P1275_ARG_IN_64B 6
306   -
307   -#define P1275_IN(x) ((x) & 0xf)
308   -#define P1275_OUT(x) (((x) << 4) & 0xf0)
309   -#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
310   -#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
  289 +extern void p1275_cmd_direct(unsigned long *);
311 290  
312 291 #endif /* !(__SPARC64_OPLIB_H) */
arch/sparc/include/asm/rwsem-const.h
1   -/* rwsem-const.h: RW semaphore counter constants. */
2   -#ifndef _SPARC64_RWSEM_CONST_H
3   -#define _SPARC64_RWSEM_CONST_H
4   -
5   -#define RWSEM_UNLOCKED_VALUE 0x00000000
6   -#define RWSEM_ACTIVE_BIAS 0x00000001
7   -#define RWSEM_ACTIVE_MASK 0x0000ffff
8   -#define RWSEM_WAITING_BIAS (-0x00010000)
9   -#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
10   -#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
11   -
12   -#endif /* _SPARC64_RWSEM_CONST_H */
arch/sparc/include/asm/rwsem.h
... ... @@ -15,16 +15,21 @@
15 15  
16 16 #include <linux/list.h>
17 17 #include <linux/spinlock.h>
18   -#include <asm/rwsem-const.h>
19 18  
20 19 struct rwsem_waiter;
21 20  
22 21 struct rw_semaphore {
23   - signed int count;
24   - spinlock_t wait_lock;
25   - struct list_head wait_list;
  22 + signed long count;
  23 +#define RWSEM_UNLOCKED_VALUE 0x00000000L
  24 +#define RWSEM_ACTIVE_BIAS 0x00000001L
  25 +#define RWSEM_ACTIVE_MASK 0xffffffffL
  26 +#define RWSEM_WAITING_BIAS (-RWSEM_ACTIVE_MASK-1)
  27 +#define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS
  28 +#define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
  29 + spinlock_t wait_lock;
  30 + struct list_head wait_list;
26 31 #ifdef CONFIG_DEBUG_LOCK_ALLOC
27   - struct lockdep_map dep_map;
  32 + struct lockdep_map dep_map;
28 33 #endif
29 34 };
30 35  
... ... @@ -41,6 +46,11 @@
41 46 #define DECLARE_RWSEM(name) \
42 47 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
43 48  
  49 +extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
  50 +extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
  51 +extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
  52 +extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
  53 +
44 54 extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
45 55 struct lock_class_key *key);
46 56  
47 57  
48 58  
49 59  
50 60  
51 61  
52 62  
... ... @@ -51,27 +61,103 @@
51 61 __init_rwsem((sem), #sem, &__key); \
52 62 } while (0)
53 63  
54   -extern void __down_read(struct rw_semaphore *sem);
55   -extern int __down_read_trylock(struct rw_semaphore *sem);
56   -extern void __down_write(struct rw_semaphore *sem);
57   -extern int __down_write_trylock(struct rw_semaphore *sem);
58   -extern void __up_read(struct rw_semaphore *sem);
59   -extern void __up_write(struct rw_semaphore *sem);
60   -extern void __downgrade_write(struct rw_semaphore *sem);
  64 +/*
  65 + * lock for reading
  66 + */
  67 +static inline void __down_read(struct rw_semaphore *sem)
  68 +{
  69 + if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
  70 + rwsem_down_read_failed(sem);
  71 +}
61 72  
  73 +static inline int __down_read_trylock(struct rw_semaphore *sem)
  74 +{
  75 + long tmp;
  76 +
  77 + while ((tmp = sem->count) >= 0L) {
  78 + if (tmp == cmpxchg(&sem->count, tmp,
  79 + tmp + RWSEM_ACTIVE_READ_BIAS)) {
  80 + return 1;
  81 + }
  82 + }
  83 + return 0;
  84 +}
  85 +
  86 +/*
  87 + * lock for writing
  88 + */
62 89 static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
63 90 {
64   - __down_write(sem);
  91 + long tmp;
  92 +
  93 + tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
  94 + (atomic64_t *)(&sem->count));
  95 + if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
  96 + rwsem_down_write_failed(sem);
65 97 }
66 98  
67   -static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
  99 +static inline void __down_write(struct rw_semaphore *sem)
68 100 {
69   - return atomic_add_return(delta, (atomic_t *)(&sem->count));
  101 + __down_write_nested(sem, 0);
70 102 }
71 103  
72   -static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
  104 +static inline int __down_write_trylock(struct rw_semaphore *sem)
73 105 {
74   - atomic_add(delta, (atomic_t *)(&sem->count));
  106 + long tmp;
  107 +
  108 + tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
  109 + RWSEM_ACTIVE_WRITE_BIAS);
  110 + return tmp == RWSEM_UNLOCKED_VALUE;
  111 +}
  112 +
  113 +/*
  114 + * unlock after reading
  115 + */
  116 +static inline void __up_read(struct rw_semaphore *sem)
  117 +{
  118 + long tmp;
  119 +
  120 + tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
  121 + if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
  122 + rwsem_wake(sem);
  123 +}
  124 +
  125 +/*
  126 + * unlock after writing
  127 + */
  128 +static inline void __up_write(struct rw_semaphore *sem)
  129 +{
  130 + if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
  131 + (atomic64_t *)(&sem->count)) < 0L))
  132 + rwsem_wake(sem);
  133 +}
  134 +
  135 +/*
  136 + * implement atomic add functionality
  137 + */
  138 +static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
  139 +{
  140 + atomic64_add(delta, (atomic64_t *)(&sem->count));
  141 +}
  142 +
  143 +/*
  144 + * downgrade write lock to read lock
  145 + */
  146 +static inline void __downgrade_write(struct rw_semaphore *sem)
  147 +{
  148 + long tmp;
  149 +
  150 + tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
  151 + if (tmp < 0L)
  152 + rwsem_downgrade_wake(sem);
  153 +}
  154 +
  155 +/*
  156 + * implement exchange and add functionality
  157 + */
  158 +static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
  159 +{
  160 + return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
75 161 }
76 162  
77 163 static inline int rwsem_is_locked(struct rw_semaphore *sem)
arch/sparc/include/asm/system_64.h
... ... @@ -106,6 +106,7 @@
106 106 */
107 107 #define write_pic(__p) \
108 108 __asm__ __volatile__("ba,pt %%xcc, 99f\n\t" \
  109 + " nop\n\t" \
109 110 ".align 64\n" \
110 111 "99:wr %0, 0x0, %%pic\n\t" \
111 112 "rd %%pic, %%g0" : : "r" (__p))
arch/sparc/lib/Makefile
... ... @@ -15,7 +15,7 @@
15 15 lib-$(CONFIG_SPARC32) += copy_user.o locks.o
16 16 lib-y += atomic_$(BITS).o
17 17 lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
18   -lib-y += rwsem_$(BITS).o
  18 +lib-$(CONFIG_SPARC32) += rwsem_32.o
19 19 lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
20 20  
21 21 lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
arch/sparc/lib/atomic_64.S
... ... @@ -21,7 +21,7 @@
21 21 add %g1, %o0, %g7
22 22 cas [%o1], %g1, %g7
23 23 cmp %g1, %g7
24   - bne,pn %icc, 2f
  24 + bne,pn %icc, BACKOFF_LABEL(2f, 1b)
25 25 nop
26 26 retl
27 27 nop
... ... @@ -36,7 +36,7 @@
36 36 sub %g1, %o0, %g7
37 37 cas [%o1], %g1, %g7
38 38 cmp %g1, %g7
39   - bne,pn %icc, 2f
  39 + bne,pn %icc, BACKOFF_LABEL(2f, 1b)
40 40 nop
41 41 retl
42 42 nop
43 43  
... ... @@ -51,11 +51,10 @@
51 51 add %g1, %o0, %g7
52 52 cas [%o1], %g1, %g7
53 53 cmp %g1, %g7
54   - bne,pn %icc, 2f
55   - add %g7, %o0, %g7
56   - sra %g7, 0, %o0
  54 + bne,pn %icc, BACKOFF_LABEL(2f, 1b)
  55 + add %g1, %o0, %g1
57 56 retl
58   - nop
  57 + sra %g1, 0, %o0
59 58 2: BACKOFF_SPIN(%o2, %o3, 1b)
60 59 .size atomic_add_ret, .-atomic_add_ret
61 60  
62 61  
... ... @@ -67,11 +66,10 @@
67 66 sub %g1, %o0, %g7
68 67 cas [%o1], %g1, %g7
69 68 cmp %g1, %g7
70   - bne,pn %icc, 2f
71   - sub %g7, %o0, %g7
72   - sra %g7, 0, %o0
  69 + bne,pn %icc, BACKOFF_LABEL(2f, 1b)
  70 + sub %g1, %o0, %g1
73 71 retl
74   - nop
  72 + sra %g1, 0, %o0
75 73 2: BACKOFF_SPIN(%o2, %o3, 1b)
76 74 .size atomic_sub_ret, .-atomic_sub_ret
77 75  
... ... @@ -83,7 +81,7 @@
83 81 add %g1, %o0, %g7
84 82 casx [%o1], %g1, %g7
85 83 cmp %g1, %g7
86   - bne,pn %xcc, 2f
  84 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
87 85 nop
88 86 retl
89 87 nop
... ... @@ -98,7 +96,7 @@
98 96 sub %g1, %o0, %g7
99 97 casx [%o1], %g1, %g7
100 98 cmp %g1, %g7
101   - bne,pn %xcc, 2f
  99 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
102 100 nop
103 101 retl
104 102 nop
105 103  
... ... @@ -113,11 +111,10 @@
113 111 add %g1, %o0, %g7
114 112 casx [%o1], %g1, %g7
115 113 cmp %g1, %g7
116   - bne,pn %xcc, 2f
117   - add %g7, %o0, %g7
118   - mov %g7, %o0
119   - retl
  114 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
120 115 nop
  116 + retl
  117 + add %g1, %o0, %o0
121 118 2: BACKOFF_SPIN(%o2, %o3, 1b)
122 119 .size atomic64_add_ret, .-atomic64_add_ret
123 120  
124 121  
... ... @@ -129,11 +126,10 @@
129 126 sub %g1, %o0, %g7
130 127 casx [%o1], %g1, %g7
131 128 cmp %g1, %g7
132   - bne,pn %xcc, 2f
133   - sub %g7, %o0, %g7
134   - mov %g7, %o0
135   - retl
  129 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
136 130 nop
  131 + retl
  132 + sub %g1, %o0, %o0
137 133 2: BACKOFF_SPIN(%o2, %o3, 1b)
138 134 .size atomic64_sub_ret, .-atomic64_sub_ret
arch/sparc/lib/bitops.S
... ... @@ -22,7 +22,7 @@
22 22 or %g7, %o2, %g1
23 23 casx [%o1], %g7, %g1
24 24 cmp %g7, %g1
25   - bne,pn %xcc, 2f
  25 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
26 26 and %g7, %o2, %g2
27 27 clr %o0
28 28 movrne %g2, 1, %o0
... ... @@ -45,7 +45,7 @@
45 45 andn %g7, %o2, %g1
46 46 casx [%o1], %g7, %g1
47 47 cmp %g7, %g1
48   - bne,pn %xcc, 2f
  48 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
49 49 and %g7, %o2, %g2
50 50 clr %o0
51 51 movrne %g2, 1, %o0
... ... @@ -68,7 +68,7 @@
68 68 xor %g7, %o2, %g1
69 69 casx [%o1], %g7, %g1
70 70 cmp %g7, %g1
71   - bne,pn %xcc, 2f
  71 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
72 72 and %g7, %o2, %g2
73 73 clr %o0
74 74 movrne %g2, 1, %o0
... ... @@ -91,7 +91,7 @@
91 91 or %g7, %o2, %g1
92 92 casx [%o1], %g7, %g1
93 93 cmp %g7, %g1
94   - bne,pn %xcc, 2f
  94 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
95 95 nop
96 96 retl
97 97 nop
... ... @@ -112,7 +112,7 @@
112 112 andn %g7, %o2, %g1
113 113 casx [%o1], %g7, %g1
114 114 cmp %g7, %g1
115   - bne,pn %xcc, 2f
  115 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
116 116 nop
117 117 retl
118 118 nop
... ... @@ -133,7 +133,7 @@
133 133 xor %g7, %o2, %g1
134 134 casx [%o1], %g7, %g1
135 135 cmp %g7, %g1
136   - bne,pn %xcc, 2f
  136 + bne,pn %xcc, BACKOFF_LABEL(2f, 1b)
137 137 nop
138 138 retl
139 139 nop
arch/sparc/lib/rwsem_64.S
1   -/* rwsem.S: RW semaphore assembler.
2   - *
3   - * Written by David S. Miller (davem@redhat.com), 2001.
4   - * Derived from asm-i386/rwsem.h
5   - */
6   -
7   -#include <asm/rwsem-const.h>
8   -
9   - .section .sched.text, "ax"
10   -
11   - .globl __down_read
12   -__down_read:
13   -1: lduw [%o0], %g1
14   - add %g1, 1, %g7
15   - cas [%o0], %g1, %g7
16   - cmp %g1, %g7
17   - bne,pn %icc, 1b
18   - add %g7, 1, %g7
19   - cmp %g7, 0
20   - bl,pn %icc, 3f
21   - nop
22   -2:
23   - retl
24   - nop
25   -3:
26   - save %sp, -192, %sp
27   - call rwsem_down_read_failed
28   - mov %i0, %o0
29   - ret
30   - restore
31   - .size __down_read, .-__down_read
32   -
33   - .globl __down_read_trylock
34   -__down_read_trylock:
35   -1: lduw [%o0], %g1
36   - add %g1, 1, %g7
37   - cmp %g7, 0
38   - bl,pn %icc, 2f
39   - mov 0, %o1
40   - cas [%o0], %g1, %g7
41   - cmp %g1, %g7
42   - bne,pn %icc, 1b
43   - mov 1, %o1
44   -2: retl
45   - mov %o1, %o0
46   - .size __down_read_trylock, .-__down_read_trylock
47   -
48   - .globl __down_write
49   -__down_write:
50   - sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
51   - or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
52   -1:
53   - lduw [%o0], %g3
54   - add %g3, %g1, %g7
55   - cas [%o0], %g3, %g7
56   - cmp %g3, %g7
57   - bne,pn %icc, 1b
58   - cmp %g7, 0
59   - bne,pn %icc, 3f
60   - nop
61   -2: retl
62   - nop
63   -3:
64   - save %sp, -192, %sp
65   - call rwsem_down_write_failed
66   - mov %i0, %o0
67   - ret
68   - restore
69   - .size __down_write, .-__down_write
70   -
71   - .globl __down_write_trylock
72   -__down_write_trylock:
73   - sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
74   - or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
75   -1:
76   - lduw [%o0], %g3
77   - cmp %g3, 0
78   - bne,pn %icc, 2f
79   - mov 0, %o1
80   - add %g3, %g1, %g7
81   - cas [%o0], %g3, %g7
82   - cmp %g3, %g7
83   - bne,pn %icc, 1b
84   - mov 1, %o1
85   -2: retl
86   - mov %o1, %o0
87   - .size __down_write_trylock, .-__down_write_trylock
88   -
89   - .globl __up_read
90   -__up_read:
91   -1:
92   - lduw [%o0], %g1
93   - sub %g1, 1, %g7
94   - cas [%o0], %g1, %g7
95   - cmp %g1, %g7
96   - bne,pn %icc, 1b
97   - cmp %g7, 0
98   - bl,pn %icc, 3f
99   - nop
100   -2: retl
101   - nop
102   -3: sethi %hi(RWSEM_ACTIVE_MASK), %g1
103   - sub %g7, 1, %g7
104   - or %g1, %lo(RWSEM_ACTIVE_MASK), %g1
105   - andcc %g7, %g1, %g0
106   - bne,pn %icc, 2b
107   - nop
108   - save %sp, -192, %sp
109   - call rwsem_wake
110   - mov %i0, %o0
111   - ret
112   - restore
113   - .size __up_read, .-__up_read
114   -
115   - .globl __up_write
116   -__up_write:
117   - sethi %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
118   - or %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
119   -1:
120   - lduw [%o0], %g3
121   - sub %g3, %g1, %g7
122   - cas [%o0], %g3, %g7
123   - cmp %g3, %g7
124   - bne,pn %icc, 1b
125   - sub %g7, %g1, %g7
126   - cmp %g7, 0
127   - bl,pn %icc, 3f
128   - nop
129   -2:
130   - retl
131   - nop
132   -3:
133   - save %sp, -192, %sp
134   - call rwsem_wake
135   - mov %i0, %o0
136   - ret
137   - restore
138   - .size __up_write, .-__up_write
139   -
140   - .globl __downgrade_write
141   -__downgrade_write:
142   - sethi %hi(RWSEM_WAITING_BIAS), %g1
143   - or %g1, %lo(RWSEM_WAITING_BIAS), %g1
144   -1:
145   - lduw [%o0], %g3
146   - sub %g3, %g1, %g7
147   - cas [%o0], %g3, %g7
148   - cmp %g3, %g7
149   - bne,pn %icc, 1b
150   - sub %g7, %g1, %g7
151   - cmp %g7, 0
152   - bl,pn %icc, 3f
153   - nop
154   -2:
155   - retl
156   - nop
157   -3:
158   - save %sp, -192, %sp
159   - call rwsem_downgrade_wake
160   - mov %i0, %o0
161   - ret
162   - restore
163   - .size __downgrade_write, .-__downgrade_write
arch/sparc/prom/cif.S
... ... @@ -9,18 +9,18 @@
9 9 #include <asm/thread_info.h>
10 10  
11 11 .text
12   - .globl prom_cif_interface
13   -prom_cif_interface:
14   - sethi %hi(p1275buf), %o0
15   - or %o0, %lo(p1275buf), %o0
16   - ldx [%o0 + 0x010], %o1 ! prom_cif_stack
17   - save %o1, -192, %sp
18   - ldx [%i0 + 0x008], %l2 ! prom_cif_handler
  12 + .globl prom_cif_direct
  13 +prom_cif_direct:
  14 + sethi %hi(p1275buf), %o1
  15 + or %o1, %lo(p1275buf), %o1
  16 + ldx [%o1 + 0x0010], %o2 ! prom_cif_stack
  17 + save %o2, -192, %sp
  18 + ldx [%i1 + 0x0008], %l2 ! prom_cif_handler
19 19 mov %g4, %l0
20 20 mov %g5, %l1
21 21 mov %g6, %l3
22 22 call %l2
23   - add %i0, 0x018, %o0 ! prom_args
  23 + mov %i0, %o0 ! prom_args
24 24 mov %l0, %g4
25 25 mov %l1, %g5
26 26 mov %l3, %g6
arch/sparc/prom/console_64.c
... ... @@ -21,14 +21,22 @@
21 21 inline int
22 22 prom_nbgetchar(void)
23 23 {
  24 + unsigned long args[7];
24 25 char inc;
25 26  
26   - if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)|
27   - P1275_INOUT(3,1),
28   - prom_stdin, &inc, P1275_SIZE(1)) == 1)
  27 + args[0] = (unsigned long) "read";
  28 + args[1] = 3;
  29 + args[2] = 1;
  30 + args[3] = (unsigned int) prom_stdin;
  31 + args[4] = (unsigned long) &inc;
  32 + args[5] = 1;
  33 + args[6] = (unsigned long) -1;
  34 +
  35 + p1275_cmd_direct(args);
  36 +
  37 + if (args[6] == 1)
29 38 return inc;
30   - else
31   - return -1;
  39 + return -1;
32 40 }
33 41  
34 42 /* Non blocking put character to console device, returns -1 if
35 43  
... ... @@ -37,12 +45,22 @@
37 45 inline int
38 46 prom_nbputchar(char c)
39 47 {
  48 + unsigned long args[7];
40 49 char outc;
41 50  
42 51 outc = c;
43   - if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
44   - P1275_INOUT(3,1),
45   - prom_stdout, &outc, P1275_SIZE(1)) == 1)
  52 +
  53 + args[0] = (unsigned long) "write";
  54 + args[1] = 3;
  55 + args[2] = 1;
  56 + args[3] = (unsigned int) prom_stdout;
  57 + args[4] = (unsigned long) &outc;
  58 + args[5] = 1;
  59 + args[6] = (unsigned long) -1;
  60 +
  61 + p1275_cmd_direct(args);
  62 +
  63 + if (args[6] == 1)
46 64 return 0;
47 65 else
48 66 return -1;
... ... @@ -67,8 +85,16 @@
67 85 void
68 86 prom_puts(const char *s, int len)
69 87 {
70   - p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
71   - P1275_INOUT(3,1),
72   - prom_stdout, s, P1275_SIZE(len));
  88 + unsigned long args[7];
  89 +
  90 + args[0] = (unsigned long) "write";
  91 + args[1] = 3;
  92 + args[2] = 1;
  93 + args[3] = (unsigned int) prom_stdout;
  94 + args[4] = (unsigned long) s;
  95 + args[5] = len;
  96 + args[6] = (unsigned long) -1;
  97 +
  98 + p1275_cmd_direct(args);
73 99 }
arch/sparc/prom/devops_64.c
... ... @@ -18,16 +18,32 @@
18 18 int
19 19 prom_devopen(const char *dstr)
20 20 {
21   - return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
22   - P1275_INOUT(1,1),
23   - dstr);
  21 + unsigned long args[5];
  22 +
  23 + args[0] = (unsigned long) "open";
  24 + args[1] = 1;
  25 + args[2] = 1;
  26 + args[3] = (unsigned long) dstr;
  27 + args[4] = (unsigned long) -1;
  28 +
  29 + p1275_cmd_direct(args);
  30 +
  31 + return (int) args[4];
24 32 }
25 33  
26 34 /* Close the device described by device handle 'dhandle'. */
27 35 int
28 36 prom_devclose(int dhandle)
29 37 {
30   - p1275_cmd ("close", P1275_INOUT(1,0), dhandle);
  38 + unsigned long args[4];
  39 +
  40 + args[0] = (unsigned long) "close";
  41 + args[1] = 1;
  42 + args[2] = 0;
  43 + args[3] = (unsigned int) dhandle;
  44 +
  45 + p1275_cmd_direct(args);
  46 +
31 47 return 0;
32 48 }
33 49  
... ... @@ -37,6 +53,16 @@
37 53 void
38 54 prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
39 55 {
40   - p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
  56 + unsigned long args[7];
  57 +
  58 + args[0] = (unsigned long) "seek";
  59 + args[1] = 3;
  60 + args[2] = 1;
  61 + args[3] = (unsigned int) dhandle;
  62 + args[4] = seekhi;
  63 + args[5] = seeklo;
  64 + args[6] = (unsigned long) -1;
  65 +
  66 + p1275_cmd_direct(args);
41 67 }
arch/sparc/prom/misc_64.c
... ... @@ -20,10 +20,17 @@
20 20  
21 21 int prom_service_exists(const char *service_name)
22 22 {
23   - int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
24   - P1275_INOUT(1, 1), service_name);
  23 + unsigned long args[5];
25 24  
26   - if (err)
  25 + args[0] = (unsigned long) "test";
  26 + args[1] = 1;
  27 + args[2] = 1;
  28 + args[3] = (unsigned long) service_name;
  29 + args[4] = (unsigned long) -1;
  30 +
  31 + p1275_cmd_direct(args);
  32 +
  33 + if (args[4])
27 34 return 0;
28 35 return 1;
29 36 }
30 37  
31 38  
32 39  
33 40  
34 41  
... ... @@ -31,30 +38,47 @@
31 38 void prom_sun4v_guest_soft_state(void)
32 39 {
33 40 const char *svc = "SUNW,soft-state-supported";
  41 + unsigned long args[3];
34 42  
35 43 if (!prom_service_exists(svc))
36 44 return;
37   - p1275_cmd(svc, P1275_INOUT(0, 0));
  45 + args[0] = (unsigned long) svc;
  46 + args[1] = 0;
  47 + args[2] = 0;
  48 + p1275_cmd_direct(args);
38 49 }
39 50  
40 51 /* Reset and reboot the machine with the command 'bcommand'. */
41 52 void prom_reboot(const char *bcommand)
42 53 {
  54 + unsigned long args[4];
  55 +
43 56 #ifdef CONFIG_SUN_LDOMS
44 57 if (ldom_domaining_enabled)
45 58 ldom_reboot(bcommand);
46 59 #endif
47   - p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
48   - P1275_INOUT(1, 0), bcommand);
  60 + args[0] = (unsigned long) "boot";
  61 + args[1] = 1;
  62 + args[2] = 0;
  63 + args[3] = (unsigned long) bcommand;
  64 +
  65 + p1275_cmd_direct(args);
49 66 }
50 67  
51 68 /* Forth evaluate the expression contained in 'fstring'. */
52 69 void prom_feval(const char *fstring)
53 70 {
  71 + unsigned long args[5];
  72 +
54 73 if (!fstring || fstring[0] == 0)
55 74 return;
56   - p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
57   - P1275_INOUT(1, 1), fstring);
  75 + args[0] = (unsigned long) "interpret";
  76 + args[1] = 1;
  77 + args[2] = 1;
  78 + args[3] = (unsigned long) fstring;
  79 + args[4] = (unsigned long) -1;
  80 +
  81 + p1275_cmd_direct(args);
58 82 }
59 83 EXPORT_SYMBOL(prom_feval);
60 84  
... ... @@ -68,6 +92,7 @@
68 92 */
69 93 void prom_cmdline(void)
70 94 {
  95 + unsigned long args[3];
71 96 unsigned long flags;
72 97  
73 98 local_irq_save(flags);
74 99  
... ... @@ -76,8 +101,12 @@
76 101 smp_capture();
77 102 #endif
78 103  
79   - p1275_cmd("enter", P1275_INOUT(0, 0));
  104 + args[0] = (unsigned long) "enter";
  105 + args[1] = 0;
  106 + args[2] = 0;
80 107  
  108 + p1275_cmd_direct(args);
  109 +
81 110 #ifdef CONFIG_SMP
82 111 smp_release();
83 112 #endif
84 113  
85 114  
86 115  
... ... @@ -90,22 +119,32 @@
90 119 */
91 120 void notrace prom_halt(void)
92 121 {
  122 + unsigned long args[3];
  123 +
93 124 #ifdef CONFIG_SUN_LDOMS
94 125 if (ldom_domaining_enabled)
95 126 ldom_power_off();
96 127 #endif
97 128 again:
98   - p1275_cmd("exit", P1275_INOUT(0, 0));
  129 + args[0] = (unsigned long) "exit";
  130 + args[1] = 0;
  131 + args[2] = 0;
  132 + p1275_cmd_direct(args);
99 133 goto again; /* PROM is out to get me -DaveM */
100 134 }
101 135  
102 136 void prom_halt_power_off(void)
103 137 {
  138 + unsigned long args[3];
  139 +
104 140 #ifdef CONFIG_SUN_LDOMS
105 141 if (ldom_domaining_enabled)
106 142 ldom_power_off();
107 143 #endif
108   - p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
  144 + args[0] = (unsigned long) "SUNW,power-off";
  145 + args[1] = 0;
  146 + args[2] = 0;
  147 + p1275_cmd_direct(args);
109 148  
110 149 /* if nothing else helps, we just halt */
111 150 prom_halt();
112 151  
... ... @@ -114,10 +153,15 @@
114 153 /* Set prom sync handler to call function 'funcp'. */
115 154 void prom_setcallback(callback_func_t funcp)
116 155 {
  156 + unsigned long args[5];
117 157 if (!funcp)
118 158 return;
119   - p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
120   - P1275_INOUT(1, 1), funcp);
  159 + args[0] = (unsigned long) "set-callback";
  160 + args[1] = 1;
  161 + args[2] = 1;
  162 + args[3] = (unsigned long) funcp;
  163 + args[4] = (unsigned long) -1;
  164 + p1275_cmd_direct(args);
121 165 }
122 166  
123 167 /* Get the idprom and stuff it into buffer 'idbuf'. Returns the
124 168  
125 169  
126 170  
127 171  
... ... @@ -173,57 +217,61 @@
173 217 }
174 218  
175 219 /* Load explicit I/D TLB entries. */
  220 +static long tlb_load(const char *type, unsigned long index,
  221 + unsigned long tte_data, unsigned long vaddr)
  222 +{
  223 + unsigned long args[9];
  224 +
  225 + args[0] = (unsigned long) prom_callmethod_name;
  226 + args[1] = 5;
  227 + args[2] = 1;
  228 + args[3] = (unsigned long) type;
  229 + args[4] = (unsigned int) prom_get_mmu_ihandle();
  230 + args[5] = vaddr;
  231 + args[6] = tte_data;
  232 + args[7] = index;
  233 + args[8] = (unsigned long) -1;
  234 +
  235 + p1275_cmd_direct(args);
  236 +
  237 + return (long) args[8];
  238 +}
  239 +
176 240 long prom_itlb_load(unsigned long index,
177 241 unsigned long tte_data,
178 242 unsigned long vaddr)
179 243 {
180   - return p1275_cmd(prom_callmethod_name,
181   - (P1275_ARG(0, P1275_ARG_IN_STRING) |
182   - P1275_ARG(2, P1275_ARG_IN_64B) |
183   - P1275_ARG(3, P1275_ARG_IN_64B) |
184   - P1275_INOUT(5, 1)),
185   - "SUNW,itlb-load",
186   - prom_get_mmu_ihandle(),
187   - /* And then our actual args are pushed backwards. */
188   - vaddr,
189   - tte_data,
190   - index);
  244 + return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
191 245 }
192 246  
193 247 long prom_dtlb_load(unsigned long index,
194 248 unsigned long tte_data,
195 249 unsigned long vaddr)
196 250 {
197   - return p1275_cmd(prom_callmethod_name,
198   - (P1275_ARG(0, P1275_ARG_IN_STRING) |
199   - P1275_ARG(2, P1275_ARG_IN_64B) |
200   - P1275_ARG(3, P1275_ARG_IN_64B) |
201   - P1275_INOUT(5, 1)),
202   - "SUNW,dtlb-load",
203   - prom_get_mmu_ihandle(),
204   - /* And then our actual args are pushed backwards. */
205   - vaddr,
206   - tte_data,
207   - index);
  251 + return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
208 252 }
209 253  
210 254 int prom_map(int mode, unsigned long size,
211 255 unsigned long vaddr, unsigned long paddr)
212 256 {
213   - int ret = p1275_cmd(prom_callmethod_name,
214   - (P1275_ARG(0, P1275_ARG_IN_STRING) |
215   - P1275_ARG(3, P1275_ARG_IN_64B) |
216   - P1275_ARG(4, P1275_ARG_IN_64B) |
217   - P1275_ARG(6, P1275_ARG_IN_64B) |
218   - P1275_INOUT(7, 1)),
219   - prom_map_name,
220   - prom_get_mmu_ihandle(),
221   - mode,
222   - size,
223   - vaddr,
224   - 0,
225   - paddr);
  257 + unsigned long args[11];
  258 + int ret;
226 259  
  260 + args[0] = (unsigned long) prom_callmethod_name;
  261 + args[1] = 7;
  262 + args[2] = 1;
  263 + args[3] = (unsigned long) prom_map_name;
  264 + args[4] = (unsigned int) prom_get_mmu_ihandle();
  265 + args[5] = (unsigned int) mode;
  266 + args[6] = size;
  267 + args[7] = vaddr;
  268 + args[8] = 0;
  269 + args[9] = paddr;
  270 + args[10] = (unsigned long) -1;
  271 +
  272 + p1275_cmd_direct(args);
  273 +
  274 + ret = (int) args[10];
227 275 if (ret == 0)
228 276 ret = -1;
229 277 return ret;
230 278  
231 279  
232 280  
233 281  
... ... @@ -231,40 +279,51 @@
231 279  
232 280 void prom_unmap(unsigned long size, unsigned long vaddr)
233 281 {
234   - p1275_cmd(prom_callmethod_name,
235   - (P1275_ARG(0, P1275_ARG_IN_STRING) |
236   - P1275_ARG(2, P1275_ARG_IN_64B) |
237   - P1275_ARG(3, P1275_ARG_IN_64B) |
238   - P1275_INOUT(4, 0)),
239   - prom_unmap_name,
240   - prom_get_mmu_ihandle(),
241   - size,
242   - vaddr);
  282 + unsigned long args[7];
  283 +
  284 + args[0] = (unsigned long) prom_callmethod_name;
  285 + args[1] = 4;
  286 + args[2] = 0;
  287 + args[3] = (unsigned long) prom_unmap_name;
  288 + args[4] = (unsigned int) prom_get_mmu_ihandle();
  289 + args[5] = size;
  290 + args[6] = vaddr;
  291 +
  292 + p1275_cmd_direct(args);
243 293 }
244 294  
245 295 /* Set aside physical memory which is not touched or modified
246 296 * across soft resets.
247 297 */
248   -unsigned long prom_retain(const char *name,
249   - unsigned long pa_low, unsigned long pa_high,
250   - long size, long align)
  298 +int prom_retain(const char *name, unsigned long size,
  299 + unsigned long align, unsigned long *paddr)
251 300 {
252   - /* XXX I don't think we return multiple values correctly.
253   - * XXX OBP supposedly returns pa_low/pa_high here, how does
254   - * XXX it work?
255   - */
  301 + unsigned long args[11];
256 302  
257   - /* If align is zero, the pa_low/pa_high args are passed,
258   - * else they are not.
  303 + args[0] = (unsigned long) prom_callmethod_name;
  304 + args[1] = 5;
  305 + args[2] = 3;
  306 + args[3] = (unsigned long) "SUNW,retain";
  307 + args[4] = (unsigned int) prom_get_memory_ihandle();
  308 + args[5] = align;
  309 + args[6] = size;
  310 + args[7] = (unsigned long) name;
  311 + args[8] = (unsigned long) -1;
  312 + args[9] = (unsigned long) -1;
  313 + args[10] = (unsigned long) -1;
  314 +
  315 + p1275_cmd_direct(args);
  316 +
  317 + if (args[8])
  318 + return (int) args[8];
  319 +
  320 + /* Next we get "phys_high" then "phys_low". On 64-bit
  321 + * the phys_high cell is don't care since the phys_low
  322 + * cell has the full value.
259 323 */
260   - if (align == 0)
261   - return p1275_cmd("SUNW,retain",
262   - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
263   - name, pa_low, pa_high, size, align);
264   - else
265   - return p1275_cmd("SUNW,retain",
266   - (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
267   - name, size, align);
  324 + *paddr = args[10];
  325 +
  326 + return 0;
268 327 }
269 328  
270 329 /* Get "Unumber" string for the SIMM at the given
271 330  
272 331  
273 332  
274 333  
275 334  
276 335  
277 336  
278 337  
279 338  
... ... @@ -277,63 +336,130 @@
277 336 unsigned long phys_addr,
278 337 char *buf, int buflen)
279 338 {
280   - return p1275_cmd(prom_callmethod_name,
281   - (P1275_ARG(0, P1275_ARG_IN_STRING) |
282   - P1275_ARG(3, P1275_ARG_OUT_BUF) |
283   - P1275_ARG(6, P1275_ARG_IN_64B) |
284   - P1275_INOUT(8, 2)),
285   - "SUNW,get-unumber", prom_get_memory_ihandle(),
286   - buflen, buf, P1275_SIZE(buflen),
287   - 0, phys_addr, syndrome_code);
  339 + unsigned long args[12];
  340 +
  341 + args[0] = (unsigned long) prom_callmethod_name;
  342 + args[1] = 7;
  343 + args[2] = 2;
  344 + args[3] = (unsigned long) "SUNW,get-unumber";
  345 + args[4] = (unsigned int) prom_get_memory_ihandle();
  346 + args[5] = buflen;
  347 + args[6] = (unsigned long) buf;
  348 + args[7] = 0;
  349 + args[8] = phys_addr;
  350 + args[9] = (unsigned int) syndrome_code;
  351 + args[10] = (unsigned long) -1;
  352 + args[11] = (unsigned long) -1;
  353 +
  354 + p1275_cmd_direct(args);
  355 +
  356 + return (int) args[10];
288 357 }
289 358  
290 359 /* Power management extensions. */
291 360 void prom_sleepself(void)
292 361 {
293   - p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
  362 + unsigned long args[3];
  363 +
  364 + args[0] = (unsigned long) "SUNW,sleep-self";
  365 + args[1] = 0;
  366 + args[2] = 0;
  367 + p1275_cmd_direct(args);
294 368 }
295 369  
296 370 int prom_sleepsystem(void)
297 371 {
298   - return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
  372 + unsigned long args[4];
  373 +
  374 + args[0] = (unsigned long) "SUNW,sleep-system";
  375 + args[1] = 0;
  376 + args[2] = 1;
  377 + args[3] = (unsigned long) -1;
  378 + p1275_cmd_direct(args);
  379 +
  380 + return (int) args[3];
299 381 }
300 382  
301 383 int prom_wakeupsystem(void)
302 384 {
303   - return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
  385 + unsigned long args[4];
  386 +
  387 + args[0] = (unsigned long) "SUNW,wakeup-system";
  388 + args[1] = 0;
  389 + args[2] = 1;
  390 + args[3] = (unsigned long) -1;
  391 + p1275_cmd_direct(args);
  392 +
  393 + return (int) args[3];
304 394 }
305 395  
306 396 #ifdef CONFIG_SMP
307 397 void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
308 398 {
309   - p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg);
  399 + unsigned long args[6];
  400 +
  401 + args[0] = (unsigned long) "SUNW,start-cpu";
  402 + args[1] = 3;
  403 + args[2] = 0;
  404 + args[3] = (unsigned int) cpunode;
  405 + args[4] = pc;
  406 + args[5] = arg;
  407 + p1275_cmd_direct(args);
310 408 }
311 409  
312 410 void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
313 411 {
314   - p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0),
315   - cpuid, pc, arg);
  412 + unsigned long args[6];
  413 +
  414 + args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
  415 + args[1] = 3;
  416 + args[2] = 0;
  417 + args[3] = (unsigned int) cpuid;
  418 + args[4] = pc;
  419 + args[5] = arg;
  420 + p1275_cmd_direct(args);
316 421 }
317 422  
318 423 void prom_stopcpu_cpuid(int cpuid)
319 424 {
320   - p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0),
321   - cpuid);
  425 + unsigned long args[4];
  426 +
  427 + args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
  428 + args[1] = 1;
  429 + args[2] = 0;
  430 + args[3] = (unsigned int) cpuid;
  431 + p1275_cmd_direct(args);
322 432 }
323 433  
324 434 void prom_stopself(void)
325 435 {
326   - p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
  436 + unsigned long args[3];
  437 +
  438 + args[0] = (unsigned long) "SUNW,stop-self";
  439 + args[1] = 0;
  440 + args[2] = 0;
  441 + p1275_cmd_direct(args);
327 442 }
328 443  
329 444 void prom_idleself(void)
330 445 {
331   - p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
  446 + unsigned long args[3];
  447 +
  448 + args[0] = (unsigned long) "SUNW,idle-self";
  449 + args[1] = 0;
  450 + args[2] = 0;
  451 + p1275_cmd_direct(args);
332 452 }
333 453  
334 454 void prom_resumecpu(int cpunode)
335 455 {
336   - p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
  456 + unsigned long args[4];
  457 +
  458 + args[0] = (unsigned long) "SUNW,resume-cpu";
  459 + args[1] = 1;
  460 + args[2] = 0;
  461 + args[3] = (unsigned int) cpunode;
  462 + p1275_cmd_direct(args);
337 463 }
338 464 #endif
arch/sparc/prom/p1275.c
... ... @@ -22,13 +22,11 @@
22 22 long prom_callback; /* 0x00 */
23 23 void (*prom_cif_handler)(long *); /* 0x08 */
24 24 unsigned long prom_cif_stack; /* 0x10 */
25   - unsigned long prom_args [23]; /* 0x18 */
26   - char prom_buffer [3000];
27 25 } p1275buf;
28 26  
29 27 extern void prom_world(int);
30 28  
31   -extern void prom_cif_interface(void);
  29 +extern void prom_cif_direct(unsigned long *args);
32 30 extern void prom_cif_callback(void);
33 31  
34 32 /*
35 33  
36 34  
37 35  
38 36  
39 37  
40 38  
... ... @@ -36,114 +34,20 @@
36 34 */
37 35 DEFINE_RAW_SPINLOCK(prom_entry_lock);
38 36  
39   -long p1275_cmd(const char *service, long fmt, ...)
  37 +void p1275_cmd_direct(unsigned long *args)
40 38 {
41   - char *p, *q;
42 39 unsigned long flags;
43   - int nargs, nrets, i;
44   - va_list list;
45   - long attrs, x;
46   -
47   - p = p1275buf.prom_buffer;
48 40  
49 41 raw_local_save_flags(flags);
50 42 raw_local_irq_restore(PIL_NMI);
51 43 raw_spin_lock(&prom_entry_lock);
52 44  
53   - p1275buf.prom_args[0] = (unsigned long)p; /* service */
54   - strcpy (p, service);
55   - p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
56   - p1275buf.prom_args[1] = nargs = (fmt & 0x0f); /* nargs */
57   - p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4); /* nrets */
58   - attrs = fmt >> 8;
59   - va_start(list, fmt);
60   - for (i = 0; i < nargs; i++, attrs >>= 3) {
61   - switch (attrs & 0x7) {
62   - case P1275_ARG_NUMBER:
63   - p1275buf.prom_args[i + 3] =
64   - (unsigned)va_arg(list, long);
65   - break;
66   - case P1275_ARG_IN_64B:
67   - p1275buf.prom_args[i + 3] =
68   - va_arg(list, unsigned long);
69   - break;
70   - case P1275_ARG_IN_STRING:
71   - strcpy (p, va_arg(list, char *));
72   - p1275buf.prom_args[i + 3] = (unsigned long)p;
73   - p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
74   - break;
75   - case P1275_ARG_OUT_BUF:
76   - (void) va_arg(list, char *);
77   - p1275buf.prom_args[i + 3] = (unsigned long)p;
78   - x = va_arg(list, long);
79   - i++; attrs >>= 3;
80   - p = (char *)(((long)(p + (int)x + 7)) & ~7);
81   - p1275buf.prom_args[i + 3] = x;
82   - break;
83   - case P1275_ARG_IN_BUF:
84   - q = va_arg(list, char *);
85   - p1275buf.prom_args[i + 3] = (unsigned long)p;
86   - x = va_arg(list, long);
87   - i++; attrs >>= 3;
88   - memcpy (p, q, (int)x);
89   - p = (char *)(((long)(p + (int)x + 7)) & ~7);
90   - p1275buf.prom_args[i + 3] = x;
91   - break;
92   - case P1275_ARG_OUT_32B:
93   - (void) va_arg(list, char *);
94   - p1275buf.prom_args[i + 3] = (unsigned long)p;
95   - p += 32;
96   - break;
97   - case P1275_ARG_IN_FUNCTION:
98   - p1275buf.prom_args[i + 3] =
99   - (unsigned long)prom_cif_callback;
100   - p1275buf.prom_callback = va_arg(list, long);
101   - break;
102   - }
103   - }
104   - va_end(list);
105   -
106 45 prom_world(1);
107   - prom_cif_interface();
  46 + prom_cif_direct(args);
108 47 prom_world(0);
109 48  
110   - attrs = fmt >> 8;
111   - va_start(list, fmt);
112   - for (i = 0; i < nargs; i++, attrs >>= 3) {
113   - switch (attrs & 0x7) {
114   - case P1275_ARG_NUMBER:
115   - (void) va_arg(list, long);
116   - break;
117   - case P1275_ARG_IN_STRING:
118   - (void) va_arg(list, char *);
119   - break;
120   - case P1275_ARG_IN_FUNCTION:
121   - (void) va_arg(list, long);
122   - break;
123   - case P1275_ARG_IN_BUF:
124   - (void) va_arg(list, char *);
125   - (void) va_arg(list, long);
126   - i++; attrs >>= 3;
127   - break;
128   - case P1275_ARG_OUT_BUF:
129   - p = va_arg(list, char *);
130   - x = va_arg(list, long);
131   - memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
132   - i++; attrs >>= 3;
133   - break;
134   - case P1275_ARG_OUT_32B:
135   - p = va_arg(list, char *);
136   - memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
137   - break;
138   - }
139   - }
140   - va_end(list);
141   - x = p1275buf.prom_args [nargs + 3];
142   -
143 49 raw_spin_unlock(&prom_entry_lock);
144 50 raw_local_irq_restore(flags);
145   -
146   - return x;
147 51 }
148 52  
149 53 void prom_cif_init(void *cif_handler, void *cif_stack)
arch/sparc/prom/tree_64.c
... ... @@ -16,22 +16,39 @@
16 16 #include <asm/oplib.h>
17 17 #include <asm/ldc.h>
18 18  
  19 +static int prom_node_to_node(const char *type, int node)
  20 +{
  21 + unsigned long args[5];
  22 +
  23 + args[0] = (unsigned long) type;
  24 + args[1] = 1;
  25 + args[2] = 1;
  26 + args[3] = (unsigned int) node;
  27 + args[4] = (unsigned long) -1;
  28 +
  29 + p1275_cmd_direct(args);
  30 +
  31 + return (int) args[4];
  32 +}
  33 +
19 34 /* Return the child of node 'node' or zero if no this node has no
20 35 * direct descendent.
21 36 */
22 37 inline int __prom_getchild(int node)
23 38 {
24   - return p1275_cmd ("child", P1275_INOUT(1, 1), node);
  39 + return prom_node_to_node("child", node);
25 40 }
26 41  
27 42 inline int prom_getchild(int node)
28 43 {
29 44 int cnode;
30 45  
31   - if(node == -1) return 0;
  46 + if (node == -1)
  47 + return 0;
32 48 cnode = __prom_getchild(node);
33   - if(cnode == -1) return 0;
34   - return (int)cnode;
  49 + if (cnode == -1)
  50 + return 0;
  51 + return cnode;
35 52 }
36 53 EXPORT_SYMBOL(prom_getchild);
37 54  
... ... @@ -39,10 +56,12 @@
39 56 {
40 57 int cnode;
41 58  
42   - if(node == -1) return 0;
43   - cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node);
44   - if(cnode == -1) return 0;
45   - return (int)cnode;
  59 + if (node == -1)
  60 + return 0;
  61 + cnode = prom_node_to_node("parent", node);
  62 + if (cnode == -1)
  63 + return 0;
  64 + return cnode;
46 65 }
47 66  
48 67 /* Return the next sibling of node 'node' or zero if no more siblings
... ... @@ -50,7 +69,7 @@
50 69 */
51 70 inline int __prom_getsibling(int node)
52 71 {
53   - return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
  72 + return prom_node_to_node(prom_peer_name, node);
54 73 }
55 74  
56 75 inline int prom_getsibling(int node)
... ... @@ -72,11 +91,21 @@
72 91 */
73 92 inline int prom_getproplen(int node, const char *prop)
74 93 {
75   - if((!node) || (!prop)) return -1;
76   - return p1275_cmd ("getproplen",
77   - P1275_ARG(1,P1275_ARG_IN_STRING)|
78   - P1275_INOUT(2, 1),
79   - node, prop);
  94 + unsigned long args[6];
  95 +
  96 + if (!node || !prop)
  97 + return -1;
  98 +
  99 + args[0] = (unsigned long) "getproplen";
  100 + args[1] = 2;
  101 + args[2] = 1;
  102 + args[3] = (unsigned int) node;
  103 + args[4] = (unsigned long) prop;
  104 + args[5] = (unsigned long) -1;
  105 +
  106 + p1275_cmd_direct(args);
  107 +
  108 + return (int) args[5];
80 109 }
81 110 EXPORT_SYMBOL(prom_getproplen);
82 111  
83 112  
84 113  
... ... @@ -87,19 +116,25 @@
87 116 inline int prom_getproperty(int node, const char *prop,
88 117 char *buffer, int bufsize)
89 118 {
  119 + unsigned long args[8];
90 120 int plen;
91 121  
92 122 plen = prom_getproplen(node, prop);
93   - if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
  123 + if ((plen > bufsize) || (plen == 0) || (plen == -1))
94 124 return -1;
95   - } else {
96   - /* Ok, things seem all right. */
97   - return p1275_cmd(prom_getprop_name,
98   - P1275_ARG(1,P1275_ARG_IN_STRING)|
99   - P1275_ARG(2,P1275_ARG_OUT_BUF)|
100   - P1275_INOUT(4, 1),
101   - node, prop, buffer, P1275_SIZE(plen));
102   - }
  125 +
  126 + args[0] = (unsigned long) prom_getprop_name;
  127 + args[1] = 4;
  128 + args[2] = 1;
  129 + args[3] = (unsigned int) node;
  130 + args[4] = (unsigned long) prop;
  131 + args[5] = (unsigned long) buffer;
  132 + args[6] = bufsize;
  133 + args[7] = (unsigned long) -1;
  134 +
  135 + p1275_cmd_direct(args);
  136 +
  137 + return (int) args[7];
103 138 }
104 139 EXPORT_SYMBOL(prom_getproperty);
105 140  
... ... @@ -110,7 +145,7 @@
110 145 {
111 146 int intprop;
112 147  
113   - if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
  148 + if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
114 149 return intprop;
115 150  
116 151 return -1;
... ... @@ -126,7 +161,8 @@
126 161 int retval;
127 162  
128 163 retval = prom_getint(node, property);
129   - if(retval == -1) return deflt;
  164 + if (retval == -1)
  165 + return deflt;
130 166  
131 167 return retval;
132 168 }
... ... @@ -138,7 +174,8 @@
138 174 int retval;
139 175  
140 176 retval = prom_getproplen(node, prop);
141   - if(retval == -1) return 0;
  177 + if (retval == -1)
  178 + return 0;
142 179 return 1;
143 180 }
144 181 EXPORT_SYMBOL(prom_getbool);
... ... @@ -152,7 +189,8 @@
152 189 int len;
153 190  
154 191 len = prom_getproperty(node, prop, user_buf, ubuf_size);
155   - if(len != -1) return;
  192 + if (len != -1)
  193 + return;
156 194 user_buf[0] = 0;
157 195 }
158 196 EXPORT_SYMBOL(prom_getstring);
... ... @@ -164,7 +202,8 @@
164 202 {
165 203 char namebuf[128];
166 204 prom_getproperty(node, "name", namebuf, sizeof(namebuf));
167   - if(strcmp(namebuf, name) == 0) return 1;
  205 + if (strcmp(namebuf, name) == 0)
  206 + return 1;
168 207 return 0;
169 208 }
170 209  
171 210  
172 211  
... ... @@ -190,16 +229,29 @@
190 229 }
191 230 EXPORT_SYMBOL(prom_searchsiblings);
192 231  
  232 +static const char *prom_nextprop_name = "nextprop";
  233 +
193 234 /* Return the first property type for node 'node'.
194 235 * buffer should be at least 32B in length
195 236 */
196 237 inline char *prom_firstprop(int node, char *buffer)
197 238 {
  239 + unsigned long args[7];
  240 +
198 241 *buffer = 0;
199   - if(node == -1) return buffer;
200   - p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
201   - P1275_INOUT(3, 0),
202   - node, (char *) 0x0, buffer);
  242 + if (node == -1)
  243 + return buffer;
  244 +
  245 + args[0] = (unsigned long) prom_nextprop_name;
  246 + args[1] = 3;
  247 + args[2] = 1;
  248 + args[3] = (unsigned int) node;
  249 + args[4] = 0;
  250 + args[5] = (unsigned long) buffer;
  251 + args[6] = (unsigned long) -1;
  252 +
  253 + p1275_cmd_direct(args);
  254 +
203 255 return buffer;
204 256 }
205 257 EXPORT_SYMBOL(prom_firstprop);
206 258  
... ... @@ -210,9 +262,10 @@
210 262 */
211 263 inline char *prom_nextprop(int node, const char *oprop, char *buffer)
212 264 {
  265 + unsigned long args[7];
213 266 char buf[32];
214 267  
215   - if(node == -1) {
  268 + if (node == -1) {
216 269 *buffer = 0;
217 270 return buffer;
218 271 }
... ... @@ -220,10 +273,17 @@
220 273 strcpy (buf, oprop);
221 274 oprop = buf;
222 275 }
223   - p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
224   - P1275_ARG(2,P1275_ARG_OUT_32B)|
225   - P1275_INOUT(3, 0),
226   - node, oprop, buffer);
  276 +
  277 + args[0] = (unsigned long) prom_nextprop_name;
  278 + args[1] = 3;
  279 + args[2] = 1;
  280 + args[3] = (unsigned int) node;
  281 + args[4] = (unsigned long) oprop;
  282 + args[5] = (unsigned long) buffer;
  283 + args[6] = (unsigned long) -1;
  284 +
  285 + p1275_cmd_direct(args);
  286 +
227 287 return buffer;
228 288 }
229 289 EXPORT_SYMBOL(prom_nextprop);
230 290  
... ... @@ -231,12 +291,19 @@
231 291 int
232 292 prom_finddevice(const char *name)
233 293 {
  294 + unsigned long args[5];
  295 +
234 296 if (!name)
235 297 return 0;
236   - return p1275_cmd(prom_finddev_name,
237   - P1275_ARG(0,P1275_ARG_IN_STRING)|
238   - P1275_INOUT(1, 1),
239   - name);
  298 + args[0] = (unsigned long) "finddevice";
  299 + args[1] = 1;
  300 + args[2] = 1;
  301 + args[3] = (unsigned long) name;
  302 + args[4] = (unsigned long) -1;
  303 +
  304 + p1275_cmd_direct(args);
  305 +
  306 + return (int) args[4];
240 307 }
241 308 EXPORT_SYMBOL(prom_finddevice);
242 309  
... ... @@ -247,7 +314,7 @@
247 314 *buf = 0;
248 315 do {
249 316 prom_nextprop(node, buf, buf);
250   - if(!strcmp(buf, prop))
  317 + if (!strcmp(buf, prop))
251 318 return 1;
252 319 } while (*buf);
253 320 return 0;
... ... @@ -260,6 +327,8 @@
260 327 int
261 328 prom_setprop(int node, const char *pname, char *value, int size)
262 329 {
  330 + unsigned long args[8];
  331 +
263 332 if (size == 0)
264 333 return 0;
265 334 if ((pname == 0) || (value == 0))
266 335  
267 336  
... ... @@ -271,19 +340,37 @@
271 340 return 0;
272 341 }
273 342 #endif
274   - return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
275   - P1275_ARG(2,P1275_ARG_IN_BUF)|
276   - P1275_INOUT(4, 1),
277   - node, pname, value, P1275_SIZE(size));
  343 + args[0] = (unsigned long) "setprop";
  344 + args[1] = 4;
  345 + args[2] = 1;
  346 + args[3] = (unsigned int) node;
  347 + args[4] = (unsigned long) pname;
  348 + args[5] = (unsigned long) value;
  349 + args[6] = size;
  350 + args[7] = (unsigned long) -1;
  351 +
  352 + p1275_cmd_direct(args);
  353 +
  354 + return (int) args[7];
278 355 }
279 356 EXPORT_SYMBOL(prom_setprop);
280 357  
281 358 inline int prom_inst2pkg(int inst)
282 359 {
  360 + unsigned long args[5];
283 361 int node;
284 362  
285   - node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst);
286   - if (node == -1) return 0;
  363 + args[0] = (unsigned long) "instance-to-package";
  364 + args[1] = 1;
  365 + args[2] = 1;
  366 + args[3] = (unsigned int) inst;
  367 + args[4] = (unsigned long) -1;
  368 +
  369 + p1275_cmd_direct(args);
  370 +
  371 + node = (int) args[4];
  372 + if (node == -1)
  373 + return 0;
287 374 return node;
288 375 }
289 376  
290 377  
... ... @@ -296,18 +383,29 @@
296 383 int node, inst;
297 384  
298 385 inst = prom_devopen (path);
299   - if (inst == 0) return 0;
300   - node = prom_inst2pkg (inst);
301   - prom_devclose (inst);
302   - if (node == -1) return 0;
  386 + if (inst == 0)
  387 + return 0;
  388 + node = prom_inst2pkg(inst);
  389 + prom_devclose(inst);
  390 + if (node == -1)
  391 + return 0;
303 392 return node;
304 393 }
305 394  
306 395 int prom_ihandle2path(int handle, char *buffer, int bufsize)
307 396 {
308   - return p1275_cmd("instance-to-path",
309   - P1275_ARG(1,P1275_ARG_OUT_BUF)|
310   - P1275_INOUT(3, 1),
311   - handle, buffer, P1275_SIZE(bufsize));
  397 + unsigned long args[7];
  398 +
  399 + args[0] = (unsigned long) "instance-to-path";
  400 + args[1] = 3;
  401 + args[2] = 1;
  402 + args[3] = (unsigned int) handle;
  403 + args[4] = (unsigned long) buffer;
  404 + args[5] = bufsize;
  405 + args[6] = (unsigned long) -1;
  406 +
  407 + p1275_cmd_direct(args);
  408 +
  409 + return (int) args[6];
312 410 }