]> rtime.felk.cvut.cz Git - lisovros/linux_canprio.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Aug 2010 17:10:13 +0000 (10:10 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 24 Aug 2010 17:10:13 +0000 (10:10 -0700)
* 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.

16 files changed:
arch/sparc/include/asm/atomic_64.h
arch/sparc/include/asm/backoff.h
arch/sparc/include/asm/oplib_64.h
arch/sparc/include/asm/rwsem-const.h [deleted file]
arch/sparc/include/asm/rwsem.h
arch/sparc/include/asm/system_64.h
arch/sparc/lib/Makefile
arch/sparc/lib/atomic_64.S
arch/sparc/lib/bitops.S
arch/sparc/lib/rwsem_64.S [deleted file]
arch/sparc/prom/cif.S
arch/sparc/prom/console_64.c
arch/sparc/prom/devops_64.c
arch/sparc/prom/misc_64.c
arch/sparc/prom/p1275.c
arch/sparc/prom/tree_64.c

index f0c74227c737e0a94efb33c95640375ad38c89bc..bdb2ff880bdd68f58c0b4357479f31bd32ff19d9 100644 (file)
 #define atomic64_set(v, i)     (((v)->counter) = i)
 
 extern void atomic_add(int, atomic_t *);
-extern void atomic64_add(int, atomic64_t *);
+extern void atomic64_add(long, atomic64_t *);
 extern void atomic_sub(int, atomic_t *);
-extern void atomic64_sub(int, atomic64_t *);
+extern void atomic64_sub(long, atomic64_t *);
 
 extern int atomic_add_ret(int, atomic_t *);
-extern long atomic64_add_ret(int, atomic64_t *);
+extern long atomic64_add_ret(long, atomic64_t *);
 extern int atomic_sub_ret(int, atomic_t *);
-extern long atomic64_sub_ret(int, atomic64_t *);
+extern long atomic64_sub_ret(long, atomic64_t *);
 
 #define atomic_dec_return(v) atomic_sub_ret(1, v)
 #define atomic64_dec_return(v) atomic64_sub_ret(1, v)
index fa1fdf67e350e07d950107289f25bdf3c41a73b3..db3af0d30fb10129124c594d1f1195bb59f2a6f2 100644 (file)
@@ -8,6 +8,9 @@
 #define BACKOFF_SETUP(reg)     \
        mov     1, reg
 
+#define BACKOFF_LABEL(spin_label, continue_label) \
+       spin_label
+
 #define BACKOFF_SPIN(reg, tmp, label)  \
        mov     reg, tmp; \
 88:    brnz,pt tmp, 88b; \
 #else
 
 #define BACKOFF_SETUP(reg)
-#define BACKOFF_SPIN(reg, tmp, label) \
-       ba,pt   %xcc, label; \
-        nop;
+
+#define BACKOFF_LABEL(spin_label, continue_label) \
+       continue_label
+
+#define BACKOFF_SPIN(reg, tmp, label)
 
 #endif
 
index a5db0317b5fbfecc523e82b7a27172252cb1f4a2..3e0b2d62303df55133d1f9547e8c984ba5dbbeb2 100644 (file)
@@ -185,9 +185,8 @@ extern int prom_getunumber(int syndrome_code,
                           char *buf, int buflen);
 
 /* Retain physical memory to the caller across soft resets. */
-extern unsigned long prom_retain(const char *name,
-                                unsigned long pa_low, unsigned long pa_high,
-                                long size, long align);
+extern int prom_retain(const char *name, unsigned long size,
+                      unsigned long align, unsigned long *paddr);
 
 /* Load explicit I/D TLB entries into the calling processor. */
 extern long prom_itlb_load(unsigned long index,
@@ -287,26 +286,6 @@ extern void prom_sun4v_guest_soft_state(void);
 extern int prom_ihandle2path(int handle, char *buffer, int bufsize);
 
 /* Client interface level routines. */
-extern long p1275_cmd(const char *, long, ...);
-
-#if 0
-#define P1275_SIZE(x) ((((long)((x) / 32)) << 32) | (x))
-#else
-#define P1275_SIZE(x) x
-#endif
-
-/* We support at most 16 input and 1 output argument */
-#define P1275_ARG_NUMBER               0
-#define P1275_ARG_IN_STRING            1
-#define P1275_ARG_OUT_BUF              2
-#define P1275_ARG_OUT_32B              3
-#define P1275_ARG_IN_FUNCTION          4
-#define P1275_ARG_IN_BUF               5
-#define P1275_ARG_IN_64B               6
-
-#define P1275_IN(x) ((x) & 0xf)
-#define P1275_OUT(x) (((x) << 4) & 0xf0)
-#define P1275_INOUT(i,o) (P1275_IN(i)|P1275_OUT(o))
-#define P1275_ARG(n,x) ((x) << ((n)*3 + 8))
+extern void p1275_cmd_direct(unsigned long *);
 
 #endif /* !(__SPARC64_OPLIB_H) */
diff --git a/arch/sparc/include/asm/rwsem-const.h b/arch/sparc/include/asm/rwsem-const.h
deleted file mode 100644 (file)
index e4c61a1..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-/* rwsem-const.h: RW semaphore counter constants.  */
-#ifndef _SPARC64_RWSEM_CONST_H
-#define _SPARC64_RWSEM_CONST_H
-
-#define RWSEM_UNLOCKED_VALUE           0x00000000
-#define RWSEM_ACTIVE_BIAS              0x00000001
-#define RWSEM_ACTIVE_MASK              0x0000ffff
-#define RWSEM_WAITING_BIAS             (-0x00010000)
-#define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
-#define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
-
-#endif /* _SPARC64_RWSEM_CONST_H */
index 6e5621006f85114d3356090b1ce66681021375a9..a2b4302869bcfb8ffe1d54ee3282293a18aeae83 100644 (file)
 
 #include <linux/list.h>
 #include <linux/spinlock.h>
-#include <asm/rwsem-const.h>
 
 struct rwsem_waiter;
 
 struct rw_semaphore {
-       signed int count;
-       spinlock_t              wait_lock;
-       struct list_head        wait_list;
+       signed long                     count;
+#define RWSEM_UNLOCKED_VALUE           0x00000000L
+#define RWSEM_ACTIVE_BIAS              0x00000001L
+#define RWSEM_ACTIVE_MASK              0xffffffffL
+#define RWSEM_WAITING_BIAS             (-RWSEM_ACTIVE_MASK-1)
+#define RWSEM_ACTIVE_READ_BIAS         RWSEM_ACTIVE_BIAS
+#define RWSEM_ACTIVE_WRITE_BIAS                (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS)
+       spinlock_t                      wait_lock;
+       struct list_head                wait_list;
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-       struct lockdep_map      dep_map;
+       struct lockdep_map              dep_map;
 #endif
 };
 
@@ -41,6 +46,11 @@ struct rw_semaphore {
 #define DECLARE_RWSEM(name) \
        struct rw_semaphore name = __RWSEM_INITIALIZER(name)
 
+extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *sem);
+extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem);
+
 extern void __init_rwsem(struct rw_semaphore *sem, const char *name,
                         struct lock_class_key *key);
 
@@ -51,27 +61,103 @@ do {                                                               \
        __init_rwsem((sem), #sem, &__key);                      \
 } while (0)
 
-extern void __down_read(struct rw_semaphore *sem);
-extern int __down_read_trylock(struct rw_semaphore *sem);
-extern void __down_write(struct rw_semaphore *sem);
-extern int __down_write_trylock(struct rw_semaphore *sem);
-extern void __up_read(struct rw_semaphore *sem);
-extern void __up_write(struct rw_semaphore *sem);
-extern void __downgrade_write(struct rw_semaphore *sem);
+/*
+ * lock for reading
+ */
+static inline void __down_read(struct rw_semaphore *sem)
+{
+       if (unlikely(atomic64_inc_return((atomic64_t *)(&sem->count)) <= 0L))
+               rwsem_down_read_failed(sem);
+}
+
+static inline int __down_read_trylock(struct rw_semaphore *sem)
+{
+       long tmp;
+
+       while ((tmp = sem->count) >= 0L) {
+               if (tmp == cmpxchg(&sem->count, tmp,
+                                  tmp + RWSEM_ACTIVE_READ_BIAS)) {
+                       return 1;
+               }
+       }
+       return 0;
+}
 
+/*
+ * lock for writing
+ */
 static inline void __down_write_nested(struct rw_semaphore *sem, int subclass)
 {
-       __down_write(sem);
+       long tmp;
+
+       tmp = atomic64_add_return(RWSEM_ACTIVE_WRITE_BIAS,
+                                 (atomic64_t *)(&sem->count));
+       if (unlikely(tmp != RWSEM_ACTIVE_WRITE_BIAS))
+               rwsem_down_write_failed(sem);
 }
 
-static inline int rwsem_atomic_update(int delta, struct rw_semaphore *sem)
+static inline void __down_write(struct rw_semaphore *sem)
 {
-       return atomic_add_return(delta, (atomic_t *)(&sem->count));
+       __down_write_nested(sem, 0);
+}
+
+static inline int __down_write_trylock(struct rw_semaphore *sem)
+{
+       long tmp;
+
+       tmp = cmpxchg(&sem->count, RWSEM_UNLOCKED_VALUE,
+                     RWSEM_ACTIVE_WRITE_BIAS);
+       return tmp == RWSEM_UNLOCKED_VALUE;
 }
 
-static inline void rwsem_atomic_add(int delta, struct rw_semaphore *sem)
+/*
+ * unlock after reading
+ */
+static inline void __up_read(struct rw_semaphore *sem)
+{
+       long tmp;
+
+       tmp = atomic64_dec_return((atomic64_t *)(&sem->count));
+       if (unlikely(tmp < -1L && (tmp & RWSEM_ACTIVE_MASK) == 0L))
+               rwsem_wake(sem);
+}
+
+/*
+ * unlock after writing
+ */
+static inline void __up_write(struct rw_semaphore *sem)
+{
+       if (unlikely(atomic64_sub_return(RWSEM_ACTIVE_WRITE_BIAS,
+                                        (atomic64_t *)(&sem->count)) < 0L))
+               rwsem_wake(sem);
+}
+
+/*
+ * implement atomic add functionality
+ */
+static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem)
+{
+       atomic64_add(delta, (atomic64_t *)(&sem->count));
+}
+
+/*
+ * downgrade write lock to read lock
+ */
+static inline void __downgrade_write(struct rw_semaphore *sem)
+{
+       long tmp;
+
+       tmp = atomic64_add_return(-RWSEM_WAITING_BIAS, (atomic64_t *)(&sem->count));
+       if (tmp < 0L)
+               rwsem_downgrade_wake(sem);
+}
+
+/*
+ * implement exchange and add functionality
+ */
+static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem)
 {
-       atomic_add(delta, (atomic_t *)(&sem->count));
+       return atomic64_add_return(delta, (atomic64_t *)(&sem->count));
 }
 
 static inline int rwsem_is_locked(struct rw_semaphore *sem)
index d24cfe16afc1babc4feb78f0c697555754304346..e3b65d8cf41b715bb71b9339c9184e42feea01d0 100644 (file)
@@ -106,6 +106,7 @@ do {        __asm__ __volatile__("ba,pt     %%xcc, 1f\n\t" \
  */
 #define write_pic(__p)                                         \
        __asm__ __volatile__("ba,pt     %%xcc, 99f\n\t"         \
+                            " nop\n\t"                         \
                             ".align    64\n"                   \
                          "99:wr        %0, 0x0, %%pic\n\t"     \
                             "rd        %%pic, %%g0" : : "r" (__p))
index c4b5e03af11557efa6ae42aa11f9ce0d74dfa42a..846d1c4374ea9c0c24a64bc4088185388274afd3 100644 (file)
@@ -15,7 +15,7 @@ lib-$(CONFIG_SPARC32) += divdi3.o udivdi3.o
 lib-$(CONFIG_SPARC32) += copy_user.o locks.o
 lib-y                 += atomic_$(BITS).o
 lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
-lib-y                 += rwsem_$(BITS).o
+lib-$(CONFIG_SPARC32) += rwsem_32.o
 lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
 
 lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
index 0268210ca1683f7bd0bb018953d93a22e207c701..59186e0fcf398feb5880b37fa28624230e0c756b 100644 (file)
@@ -21,7 +21,7 @@ atomic_add: /* %o0 = increment, %o1 = atomic_ptr */
        add     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 2f
+       bne,pn  %icc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -36,7 +36,7 @@ atomic_sub: /* %o0 = decrement, %o1 = atomic_ptr */
        sub     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 2f
+       bne,pn  %icc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -51,11 +51,10 @@ atomic_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
        add     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 2f
-        add    %g7, %o0, %g7
-       sra     %g7, 0, %o0
+       bne,pn  %icc, BACKOFF_LABEL(2f, 1b)
+        add    %g1, %o0, %g1
        retl
-        nop
+        sra    %g1, 0, %o0
 2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_add_ret, .-atomic_add_ret
 
@@ -67,11 +66,10 @@ atomic_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
        sub     %g1, %o0, %g7
        cas     [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %icc, 2f
-        sub    %g7, %o0, %g7
-       sra     %g7, 0, %o0
+       bne,pn  %icc, BACKOFF_LABEL(2f, 1b)
+        sub    %g1, %o0, %g1
        retl
-        nop
+        sra    %g1, 0, %o0
 2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic_sub_ret, .-atomic_sub_ret
 
@@ -83,7 +81,7 @@ atomic64_add: /* %o0 = increment, %o1 = atomic_ptr */
        add     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -98,7 +96,7 @@ atomic64_sub: /* %o0 = decrement, %o1 = atomic_ptr */
        sub     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -113,11 +111,10 @@ atomic64_add_ret: /* %o0 = increment, %o1 = atomic_ptr */
        add     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 2f
-        add    %g7, %o0, %g7
-       mov     %g7, %o0
-       retl
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
+       retl
+        add    %g1, %o0, %o0
 2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_add_ret, .-atomic64_add_ret
 
@@ -129,10 +126,9 @@ atomic64_sub_ret: /* %o0 = decrement, %o1 = atomic_ptr */
        sub     %g1, %o0, %g7
        casx    [%o1], %g1, %g7
        cmp     %g1, %g7
-       bne,pn  %xcc, 2f
-        sub    %g7, %o0, %g7
-       mov     %g7, %o0
-       retl
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
+       retl
+        sub    %g1, %o0, %o0
 2:     BACKOFF_SPIN(%o2, %o3, 1b)
        .size   atomic64_sub_ret, .-atomic64_sub_ret
index 2b7228cb8c2209332000d429257f16f4dbcf730f..3dc61d5537c08a6ad56f37b90df340a527298bb7 100644 (file)
@@ -22,7 +22,7 @@ test_and_set_bit:     /* %o0=nr, %o1=addr */
        or      %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
@@ -45,7 +45,7 @@ test_and_clear_bit:   /* %o0=nr, %o1=addr */
        andn    %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
@@ -68,7 +68,7 @@ test_and_change_bit:  /* %o0=nr, %o1=addr */
        xor     %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         and    %g7, %o2, %g2
        clr     %o0
        movrne  %g2, 1, %o0
@@ -91,7 +91,7 @@ set_bit:              /* %o0=nr, %o1=addr */
        or      %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -112,7 +112,7 @@ clear_bit:          /* %o0=nr, %o1=addr */
        andn    %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
@@ -133,7 +133,7 @@ change_bit:         /* %o0=nr, %o1=addr */
        xor     %g7, %o2, %g1
        casx    [%o1], %g7, %g1
        cmp     %g7, %g1
-       bne,pn  %xcc, 2f
+       bne,pn  %xcc, BACKOFF_LABEL(2f, 1b)
         nop
        retl
         nop
diff --git a/arch/sparc/lib/rwsem_64.S b/arch/sparc/lib/rwsem_64.S
deleted file mode 100644 (file)
index 91a7d29..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/* rwsem.S: RW semaphore assembler.
- *
- * Written by David S. Miller (davem@redhat.com), 2001.
- * Derived from asm-i386/rwsem.h
- */
-
-#include <asm/rwsem-const.h>
-
-       .section        .sched.text, "ax"
-
-       .globl          __down_read
-__down_read:
-1:     lduw            [%o0], %g1
-       add             %g1, 1, %g7
-       cas             [%o0], %g1, %g7
-       cmp             %g1, %g7
-       bne,pn          %icc, 1b
-        add            %g7, 1, %g7
-       cmp             %g7, 0
-       bl,pn           %icc, 3f
-        nop
-2:
-       retl
-        nop
-3:
-       save            %sp, -192, %sp
-       call            rwsem_down_read_failed
-        mov            %i0, %o0
-       ret
-        restore
-       .size           __down_read, .-__down_read
-
-       .globl          __down_read_trylock
-__down_read_trylock:
-1:     lduw            [%o0], %g1
-       add             %g1, 1, %g7
-       cmp             %g7, 0
-       bl,pn           %icc, 2f
-        mov            0, %o1
-       cas             [%o0], %g1, %g7
-       cmp             %g1, %g7
-       bne,pn          %icc, 1b
-        mov            1, %o1
-2:     retl
-        mov            %o1, %o0
-       .size           __down_read_trylock, .-__down_read_trylock
-
-       .globl          __down_write
-__down_write:
-       sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
-       or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
-1:
-       lduw            [%o0], %g3
-       add             %g3, %g1, %g7
-       cas             [%o0], %g3, %g7
-       cmp             %g3, %g7
-       bne,pn          %icc, 1b
-        cmp            %g7, 0
-       bne,pn          %icc, 3f
-        nop
-2:     retl
-        nop
-3:
-       save            %sp, -192, %sp
-       call            rwsem_down_write_failed
-        mov            %i0, %o0
-       ret
-        restore
-       .size           __down_write, .-__down_write
-
-       .globl          __down_write_trylock
-__down_write_trylock:
-       sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
-       or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
-1:
-       lduw            [%o0], %g3
-       cmp             %g3, 0
-       bne,pn          %icc, 2f
-        mov            0, %o1
-       add             %g3, %g1, %g7
-       cas             [%o0], %g3, %g7
-       cmp             %g3, %g7
-       bne,pn          %icc, 1b
-        mov            1, %o1
-2:     retl
-        mov            %o1, %o0
-       .size           __down_write_trylock, .-__down_write_trylock
-
-       .globl          __up_read
-__up_read:
-1:
-       lduw            [%o0], %g1
-       sub             %g1, 1, %g7
-       cas             [%o0], %g1, %g7
-       cmp             %g1, %g7
-       bne,pn          %icc, 1b
-        cmp            %g7, 0
-       bl,pn           %icc, 3f
-        nop
-2:     retl
-        nop
-3:     sethi           %hi(RWSEM_ACTIVE_MASK), %g1
-       sub             %g7, 1, %g7
-       or              %g1, %lo(RWSEM_ACTIVE_MASK), %g1
-       andcc           %g7, %g1, %g0
-       bne,pn          %icc, 2b
-        nop
-       save            %sp, -192, %sp
-       call            rwsem_wake
-        mov            %i0, %o0
-       ret
-        restore
-       .size           __up_read, .-__up_read
-
-       .globl          __up_write
-__up_write:
-       sethi           %hi(RWSEM_ACTIVE_WRITE_BIAS), %g1
-       or              %g1, %lo(RWSEM_ACTIVE_WRITE_BIAS), %g1
-1:
-       lduw            [%o0], %g3
-       sub             %g3, %g1, %g7
-       cas             [%o0], %g3, %g7
-       cmp             %g3, %g7
-       bne,pn          %icc, 1b
-        sub            %g7, %g1, %g7
-       cmp             %g7, 0
-       bl,pn           %icc, 3f
-        nop
-2:
-       retl
-        nop
-3:
-       save            %sp, -192, %sp
-       call            rwsem_wake
-        mov            %i0, %o0
-       ret
-        restore
-       .size           __up_write, .-__up_write
-
-       .globl          __downgrade_write
-__downgrade_write:
-       sethi           %hi(RWSEM_WAITING_BIAS), %g1
-       or              %g1, %lo(RWSEM_WAITING_BIAS), %g1
-1:
-       lduw            [%o0], %g3
-       sub             %g3, %g1, %g7
-       cas             [%o0], %g3, %g7
-       cmp             %g3, %g7
-       bne,pn          %icc, 1b
-        sub            %g7, %g1, %g7
-       cmp             %g7, 0
-       bl,pn           %icc, 3f
-        nop
-2:
-       retl
-        nop
-3:
-       save            %sp, -192, %sp
-       call            rwsem_downgrade_wake
-        mov            %i0, %o0
-       ret
-        restore
-       .size           __downgrade_write, .-__downgrade_write
index 5f27ad779c0c578097218e44b005eaed770acf7d..9c86b4b7d4290b75a5967c28790c59b3ee24b5c9 100644 (file)
@@ -9,18 +9,18 @@
 #include <asm/thread_info.h>
 
        .text
-       .globl  prom_cif_interface
-prom_cif_interface:
-       sethi   %hi(p1275buf), %o0
-       or      %o0, %lo(p1275buf), %o0
-       ldx     [%o0 + 0x010], %o1      ! prom_cif_stack
-       save    %o1, -192, %sp
-       ldx     [%i0 + 0x008], %l2      ! prom_cif_handler
+       .globl  prom_cif_direct
+prom_cif_direct:
+       sethi   %hi(p1275buf), %o1
+       or      %o1, %lo(p1275buf), %o1
+       ldx     [%o1 + 0x0010], %o2     ! prom_cif_stack
+       save    %o2, -192, %sp
+       ldx     [%i1 + 0x0008], %l2     ! prom_cif_handler
        mov     %g4, %l0
        mov     %g5, %l1
        mov     %g6, %l3
        call    %l2
-        add    %i0, 0x018, %o0         ! prom_args
+        mov    %i0, %o0                ! prom_args
        mov     %l0, %g4
        mov     %l1, %g5
        mov     %l3, %g6
index f55d58a8a1567a653f8517598edcfe7f777b4257..10322dc2f557a22d5befcc17dd4a27d8b6604f89 100644 (file)
@@ -21,14 +21,22 @@ extern int prom_stdin, prom_stdout;
 inline int
 prom_nbgetchar(void)
 {
+       unsigned long args[7];
        char inc;
 
-       if (p1275_cmd("read", P1275_ARG(1,P1275_ARG_OUT_BUF)|
-                             P1275_INOUT(3,1),
-                             prom_stdin, &inc, P1275_SIZE(1)) == 1)
+       args[0] = (unsigned long) "read";
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) prom_stdin;
+       args[4] = (unsigned long) &inc;
+       args[5] = 1;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       if (args[6] == 1)
                return inc;
-       else
-               return -1;
+       return -1;
 }
 
 /* Non blocking put character to console device, returns -1 if
@@ -37,12 +45,22 @@ prom_nbgetchar(void)
 inline int
 prom_nbputchar(char c)
 {
+       unsigned long args[7];
        char outc;
        
        outc = c;
-       if (p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
-                              P1275_INOUT(3,1),
-                              prom_stdout, &outc, P1275_SIZE(1)) == 1)
+
+       args[0] = (unsigned long) "write";
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) prom_stdout;
+       args[4] = (unsigned long) &outc;
+       args[5] = 1;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       if (args[6] == 1)
                return 0;
        else
                return -1;
@@ -67,7 +85,15 @@ prom_putchar(char c)
 void
 prom_puts(const char *s, int len)
 {
-       p1275_cmd("write", P1275_ARG(1,P1275_ARG_IN_BUF)|
-                          P1275_INOUT(3,1),
-                          prom_stdout, s, P1275_SIZE(len));
+       unsigned long args[7];
+
+       args[0] = (unsigned long) "write";
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) prom_stdout;
+       args[4] = (unsigned long) s;
+       args[5] = len;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
 }
index 9dbd803e46e1f4c460300c6f5f2485f3d6c54e7d..a017119e7ef17c40ee8fa8328252f921c59a6ca8 100644 (file)
 int
 prom_devopen(const char *dstr)
 {
-       return p1275_cmd ("open", P1275_ARG(0,P1275_ARG_IN_STRING)|
-                                 P1275_INOUT(1,1),
-                                 dstr);
+       unsigned long args[5];
+
+       args[0] = (unsigned long) "open";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned long) dstr;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[4];
 }
 
 /* Close the device described by device handle 'dhandle'. */
 int
 prom_devclose(int dhandle)
 {
-       p1275_cmd ("close", P1275_INOUT(1,0), dhandle);
+       unsigned long args[4];
+
+       args[0] = (unsigned long) "close";
+       args[1] = 1;
+       args[2] = 0;
+       args[3] = (unsigned int) dhandle;
+
+       p1275_cmd_direct(args);
+
        return 0;
 }
 
@@ -37,5 +53,15 @@ prom_devclose(int dhandle)
 void
 prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
 {
-       p1275_cmd ("seek", P1275_INOUT(3,1), dhandle, seekhi, seeklo);
+       unsigned long args[7];
+
+       args[0] = (unsigned long) "seek";
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) dhandle;
+       args[4] = seekhi;
+       args[5] = seeklo;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
 }
index 39fc6af21b7c55ddc0e752c80c745ed6c018820a..6cb1581d6aef507fca9c036708cebe24e5ab053c 100644 (file)
 
 int prom_service_exists(const char *service_name)
 {
-       int err = p1275_cmd("test", P1275_ARG(0, P1275_ARG_IN_STRING) |
-                           P1275_INOUT(1, 1), service_name);
+       unsigned long args[5];
 
-       if (err)
+       args[0] = (unsigned long) "test";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned long) service_name;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       if (args[4])
                return 0;
        return 1;
 }
@@ -31,30 +38,47 @@ int prom_service_exists(const char *service_name)
 void prom_sun4v_guest_soft_state(void)
 {
        const char *svc = "SUNW,soft-state-supported";
+       unsigned long args[3];
 
        if (!prom_service_exists(svc))
                return;
-       p1275_cmd(svc, P1275_INOUT(0, 0));
+       args[0] = (unsigned long) svc;
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
 }
 
 /* Reset and reboot the machine with the command 'bcommand'. */
 void prom_reboot(const char *bcommand)
 {
+       unsigned long args[4];
+
 #ifdef CONFIG_SUN_LDOMS
        if (ldom_domaining_enabled)
                ldom_reboot(bcommand);
 #endif
-       p1275_cmd("boot", P1275_ARG(0, P1275_ARG_IN_STRING) |
-                 P1275_INOUT(1, 0), bcommand);
+       args[0] = (unsigned long) "boot";
+       args[1] = 1;
+       args[2] = 0;
+       args[3] = (unsigned long) bcommand;
+
+       p1275_cmd_direct(args);
 }
 
 /* Forth evaluate the expression contained in 'fstring'. */
 void prom_feval(const char *fstring)
 {
+       unsigned long args[5];
+
        if (!fstring || fstring[0] == 0)
                return;
-       p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
-                 P1275_INOUT(1, 1), fstring);
+       args[0] = (unsigned long) "interpret";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned long) fstring;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
 }
 EXPORT_SYMBOL(prom_feval);
 
@@ -68,6 +92,7 @@ extern void smp_release(void);
  */
 void prom_cmdline(void)
 {
+       unsigned long args[3];
        unsigned long flags;
 
        local_irq_save(flags);
@@ -76,7 +101,11 @@ void prom_cmdline(void)
        smp_capture();
 #endif
 
-       p1275_cmd("enter", P1275_INOUT(0, 0));
+       args[0] = (unsigned long) "enter";
+       args[1] = 0;
+       args[2] = 0;
+
+       p1275_cmd_direct(args);
 
 #ifdef CONFIG_SMP
        smp_release();
@@ -90,22 +119,32 @@ void prom_cmdline(void)
  */
 void notrace prom_halt(void)
 {
+       unsigned long args[3];
+
 #ifdef CONFIG_SUN_LDOMS
        if (ldom_domaining_enabled)
                ldom_power_off();
 #endif
 again:
-       p1275_cmd("exit", P1275_INOUT(0, 0));
+       args[0] = (unsigned long) "exit";
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
        goto again; /* PROM is out to get me -DaveM */
 }
 
 void prom_halt_power_off(void)
 {
+       unsigned long args[3];
+
 #ifdef CONFIG_SUN_LDOMS
        if (ldom_domaining_enabled)
                ldom_power_off();
 #endif
-       p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
+       args[0] = (unsigned long) "SUNW,power-off";
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
 
        /* if nothing else helps, we just halt */
        prom_halt();
@@ -114,10 +153,15 @@ void prom_halt_power_off(void)
 /* Set prom sync handler to call function 'funcp'. */
 void prom_setcallback(callback_func_t funcp)
 {
+       unsigned long args[5];
        if (!funcp)
                return;
-       p1275_cmd("set-callback", P1275_ARG(0, P1275_ARG_IN_FUNCTION) |
-                 P1275_INOUT(1, 1), funcp);
+       args[0] = (unsigned long) "set-callback";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned long) funcp;
+       args[4] = (unsigned long) -1;
+       p1275_cmd_direct(args);
 }
 
 /* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
@@ -173,57 +217,61 @@ static int prom_get_memory_ihandle(void)
 }
 
 /* Load explicit I/D TLB entries. */
+static long tlb_load(const char *type, unsigned long index,
+                    unsigned long tte_data, unsigned long vaddr)
+{
+       unsigned long args[9];
+
+       args[0] = (unsigned long) prom_callmethod_name;
+       args[1] = 5;
+       args[2] = 1;
+       args[3] = (unsigned long) type;
+       args[4] = (unsigned int) prom_get_mmu_ihandle();
+       args[5] = vaddr;
+       args[6] = tte_data;
+       args[7] = index;
+       args[8] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (long) args[8];
+}
+
 long prom_itlb_load(unsigned long index,
                    unsigned long tte_data,
                    unsigned long vaddr)
 {
-       return p1275_cmd(prom_callmethod_name,
-                        (P1275_ARG(0, P1275_ARG_IN_STRING) |
-                         P1275_ARG(2, P1275_ARG_IN_64B) |
-                         P1275_ARG(3, P1275_ARG_IN_64B) |
-                         P1275_INOUT(5, 1)),
-                        "SUNW,itlb-load",
-                        prom_get_mmu_ihandle(),
-                        /* And then our actual args are pushed backwards. */
-                        vaddr,
-                        tte_data,
-                        index);
+       return tlb_load("SUNW,itlb-load", index, tte_data, vaddr);
 }
 
 long prom_dtlb_load(unsigned long index,
                    unsigned long tte_data,
                    unsigned long vaddr)
 {
-       return p1275_cmd(prom_callmethod_name,
-                        (P1275_ARG(0, P1275_ARG_IN_STRING) |
-                         P1275_ARG(2, P1275_ARG_IN_64B) |
-                         P1275_ARG(3, P1275_ARG_IN_64B) |
-                         P1275_INOUT(5, 1)),
-                        "SUNW,dtlb-load",
-                        prom_get_mmu_ihandle(),
-                        /* And then our actual args are pushed backwards. */
-                        vaddr,
-                        tte_data,
-                        index);
+       return tlb_load("SUNW,dtlb-load", index, tte_data, vaddr);
 }
 
 int prom_map(int mode, unsigned long size,
             unsigned long vaddr, unsigned long paddr)
 {
-       int ret = p1275_cmd(prom_callmethod_name,
-                           (P1275_ARG(0, P1275_ARG_IN_STRING) |
-                            P1275_ARG(3, P1275_ARG_IN_64B) |
-                            P1275_ARG(4, P1275_ARG_IN_64B) |
-                            P1275_ARG(6, P1275_ARG_IN_64B) |
-                            P1275_INOUT(7, 1)),
-                           prom_map_name,
-                           prom_get_mmu_ihandle(),
-                           mode,
-                           size,
-                           vaddr,
-                           0,
-                           paddr);
-
+       unsigned long args[11];
+       int ret;
+
+       args[0] = (unsigned long) prom_callmethod_name;
+       args[1] = 7;
+       args[2] = 1;
+       args[3] = (unsigned long) prom_map_name;
+       args[4] = (unsigned int) prom_get_mmu_ihandle();
+       args[5] = (unsigned int) mode;
+       args[6] = size;
+       args[7] = vaddr;
+       args[8] = 0;
+       args[9] = paddr;
+       args[10] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       ret = (int) args[10];
        if (ret == 0)
                ret = -1;
        return ret;
@@ -231,40 +279,51 @@ int prom_map(int mode, unsigned long size,
 
 void prom_unmap(unsigned long size, unsigned long vaddr)
 {
-       p1275_cmd(prom_callmethod_name,
-                 (P1275_ARG(0, P1275_ARG_IN_STRING) |
-                  P1275_ARG(2, P1275_ARG_IN_64B) |
-                  P1275_ARG(3, P1275_ARG_IN_64B) |
-                  P1275_INOUT(4, 0)),
-                 prom_unmap_name,
-                 prom_get_mmu_ihandle(),
-                 size,
-                 vaddr);
+       unsigned long args[7];
+
+       args[0] = (unsigned long) prom_callmethod_name;
+       args[1] = 4;
+       args[2] = 0;
+       args[3] = (unsigned long) prom_unmap_name;
+       args[4] = (unsigned int) prom_get_mmu_ihandle();
+       args[5] = size;
+       args[6] = vaddr;
+
+       p1275_cmd_direct(args);
 }
 
 /* Set aside physical memory which is not touched or modified
  * across soft resets.
  */
-unsigned long prom_retain(const char *name,
-                         unsigned long pa_low, unsigned long pa_high,
-                         long size, long align)
+int prom_retain(const char *name, unsigned long size,
+               unsigned long align, unsigned long *paddr)
 {
-       /* XXX I don't think we return multiple values correctly.
-        * XXX OBP supposedly returns pa_low/pa_high here, how does
-        * XXX it work?
+       unsigned long args[11];
+
+       args[0] = (unsigned long) prom_callmethod_name;
+       args[1] = 5;
+       args[2] = 3;
+       args[3] = (unsigned long) "SUNW,retain";
+       args[4] = (unsigned int) prom_get_memory_ihandle();
+       args[5] = align;
+       args[6] = size;
+       args[7] = (unsigned long) name;
+       args[8] = (unsigned long) -1;
+       args[9] = (unsigned long) -1;
+       args[10] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       if (args[8])
+               return (int) args[8];
+
+       /* Next we get "phys_high" then "phys_low".  On 64-bit
+        * the phys_high cell is don't care since the phys_low
+        * cell has the full value.
         */
+       *paddr = args[10];
 
-       /* If align is zero, the pa_low/pa_high args are passed,
-        * else they are not.
-        */
-       if (align == 0)
-               return p1275_cmd("SUNW,retain",
-                                (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(5, 2)),
-                                name, pa_low, pa_high, size, align);
-       else
-               return p1275_cmd("SUNW,retain",
-                                (P1275_ARG(0, P1275_ARG_IN_BUF) | P1275_INOUT(3, 2)),
-                                name, size, align);
+       return 0;
 }
 
 /* Get "Unumber" string for the SIMM at the given
@@ -277,62 +336,129 @@ int prom_getunumber(int syndrome_code,
                    unsigned long phys_addr,
                    char *buf, int buflen)
 {
-       return p1275_cmd(prom_callmethod_name,
-                        (P1275_ARG(0, P1275_ARG_IN_STRING)     |
-                         P1275_ARG(3, P1275_ARG_OUT_BUF)       |
-                         P1275_ARG(6, P1275_ARG_IN_64B)        |
-                         P1275_INOUT(8, 2)),
-                        "SUNW,get-unumber", prom_get_memory_ihandle(),
-                        buflen, buf, P1275_SIZE(buflen),
-                        0, phys_addr, syndrome_code);
+       unsigned long args[12];
+
+       args[0] = (unsigned long) prom_callmethod_name;
+       args[1] = 7;
+       args[2] = 2;
+       args[3] = (unsigned long) "SUNW,get-unumber";
+       args[4] = (unsigned int) prom_get_memory_ihandle();
+       args[5] = buflen;
+       args[6] = (unsigned long) buf;
+       args[7] = 0;
+       args[8] = phys_addr;
+       args[9] = (unsigned int) syndrome_code;
+       args[10] = (unsigned long) -1;
+       args[11] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[10];
 }
 
 /* Power management extensions. */
 void prom_sleepself(void)
 {
-       p1275_cmd("SUNW,sleep-self", P1275_INOUT(0, 0));
+       unsigned long args[3];
+
+       args[0] = (unsigned long) "SUNW,sleep-self";
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
 }
 
 int prom_sleepsystem(void)
 {
-       return p1275_cmd("SUNW,sleep-system", P1275_INOUT(0, 1));
+       unsigned long args[4];
+
+       args[0] = (unsigned long) "SUNW,sleep-system";
+       args[1] = 0;
+       args[2] = 1;
+       args[3] = (unsigned long) -1;
+       p1275_cmd_direct(args);
+
+       return (int) args[3];
 }
 
 int prom_wakeupsystem(void)
 {
-       return p1275_cmd("SUNW,wakeup-system", P1275_INOUT(0, 1));
+       unsigned long args[4];
+
+       args[0] = (unsigned long) "SUNW,wakeup-system";
+       args[1] = 0;
+       args[2] = 1;
+       args[3] = (unsigned long) -1;
+       p1275_cmd_direct(args);
+
+       return (int) args[3];
 }
 
 #ifdef CONFIG_SMP
 void prom_startcpu(int cpunode, unsigned long pc, unsigned long arg)
 {
-       p1275_cmd("SUNW,start-cpu", P1275_INOUT(3, 0), cpunode, pc, arg);
+       unsigned long args[6];
+
+       args[0] = (unsigned long) "SUNW,start-cpu";
+       args[1] = 3;
+       args[2] = 0;
+       args[3] = (unsigned int) cpunode;
+       args[4] = pc;
+       args[5] = arg;
+       p1275_cmd_direct(args);
 }
 
 void prom_startcpu_cpuid(int cpuid, unsigned long pc, unsigned long arg)
 {
-       p1275_cmd("SUNW,start-cpu-by-cpuid", P1275_INOUT(3, 0),
-                 cpuid, pc, arg);
+       unsigned long args[6];
+
+       args[0] = (unsigned long) "SUNW,start-cpu-by-cpuid";
+       args[1] = 3;
+       args[2] = 0;
+       args[3] = (unsigned int) cpuid;
+       args[4] = pc;
+       args[5] = arg;
+       p1275_cmd_direct(args);
 }
 
 void prom_stopcpu_cpuid(int cpuid)
 {
-       p1275_cmd("SUNW,stop-cpu-by-cpuid", P1275_INOUT(1, 0),
-                 cpuid);
+       unsigned long args[4];
+
+       args[0] = (unsigned long) "SUNW,stop-cpu-by-cpuid";
+       args[1] = 1;
+       args[2] = 0;
+       args[3] = (unsigned int) cpuid;
+       p1275_cmd_direct(args);
 }
 
 void prom_stopself(void)
 {
-       p1275_cmd("SUNW,stop-self", P1275_INOUT(0, 0));
+       unsigned long args[3];
+
+       args[0] = (unsigned long) "SUNW,stop-self";
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
 }
 
 void prom_idleself(void)
 {
-       p1275_cmd("SUNW,idle-self", P1275_INOUT(0, 0));
+       unsigned long args[3];
+
+       args[0] = (unsigned long) "SUNW,idle-self";
+       args[1] = 0;
+       args[2] = 0;
+       p1275_cmd_direct(args);
 }
 
 void prom_resumecpu(int cpunode)
 {
-       p1275_cmd("SUNW,resume-cpu", P1275_INOUT(1, 0), cpunode);
+       unsigned long args[4];
+
+       args[0] = (unsigned long) "SUNW,resume-cpu";
+       args[1] = 1;
+       args[2] = 0;
+       args[3] = (unsigned int) cpunode;
+       p1275_cmd_direct(args);
 }
 #endif
index 2d8b70d397f154318612858c1bf7811160ee7f49..fa6e4e219b9ce436db25fcf3aa168d4b9f559ae2 100644 (file)
@@ -22,13 +22,11 @@ struct {
        long prom_callback;                     /* 0x00 */
        void (*prom_cif_handler)(long *);       /* 0x08 */
        unsigned long prom_cif_stack;           /* 0x10 */
-       unsigned long prom_args [23];           /* 0x18 */
-       char prom_buffer [3000];
 } p1275buf;
 
 extern void prom_world(int);
 
-extern void prom_cif_interface(void);
+extern void prom_cif_direct(unsigned long *args);
 extern void prom_cif_callback(void);
 
 /*
@@ -36,114 +34,20 @@ extern void prom_cif_callback(void);
  */
 DEFINE_RAW_SPINLOCK(prom_entry_lock);
 
-long p1275_cmd(const char *service, long fmt, ...)
+void p1275_cmd_direct(unsigned long *args)
 {
-       char *p, *q;
        unsigned long flags;
-       int nargs, nrets, i;
-       va_list list;
-       long attrs, x;
-       
-       p = p1275buf.prom_buffer;
 
        raw_local_save_flags(flags);
        raw_local_irq_restore(PIL_NMI);
        raw_spin_lock(&prom_entry_lock);
 
-       p1275buf.prom_args[0] = (unsigned long)p;               /* service */
-       strcpy (p, service);
-       p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
-       p1275buf.prom_args[1] = nargs = (fmt & 0x0f);           /* nargs */
-       p1275buf.prom_args[2] = nrets = ((fmt & 0xf0) >> 4);    /* nrets */
-       attrs = fmt >> 8;
-       va_start(list, fmt);
-       for (i = 0; i < nargs; i++, attrs >>= 3) {
-               switch (attrs & 0x7) {
-               case P1275_ARG_NUMBER:
-                       p1275buf.prom_args[i + 3] =
-                                               (unsigned)va_arg(list, long);
-                       break;
-               case P1275_ARG_IN_64B:
-                       p1275buf.prom_args[i + 3] =
-                               va_arg(list, unsigned long);
-                       break;
-               case P1275_ARG_IN_STRING:
-                       strcpy (p, va_arg(list, char *));
-                       p1275buf.prom_args[i + 3] = (unsigned long)p;
-                       p = (char *)(((long)(strchr (p, 0) + 8)) & ~7);
-                       break;
-               case P1275_ARG_OUT_BUF:
-                       (void) va_arg(list, char *);
-                       p1275buf.prom_args[i + 3] = (unsigned long)p;
-                       x = va_arg(list, long);
-                       i++; attrs >>= 3;
-                       p = (char *)(((long)(p + (int)x + 7)) & ~7);
-                       p1275buf.prom_args[i + 3] = x;
-                       break;
-               case P1275_ARG_IN_BUF:
-                       q = va_arg(list, char *);
-                       p1275buf.prom_args[i + 3] = (unsigned long)p;
-                       x = va_arg(list, long);
-                       i++; attrs >>= 3;
-                       memcpy (p, q, (int)x);
-                       p = (char *)(((long)(p + (int)x + 7)) & ~7);
-                       p1275buf.prom_args[i + 3] = x;
-                       break;
-               case P1275_ARG_OUT_32B:
-                       (void) va_arg(list, char *);
-                       p1275buf.prom_args[i + 3] = (unsigned long)p;
-                       p += 32;
-                       break;
-               case P1275_ARG_IN_FUNCTION:
-                       p1275buf.prom_args[i + 3] =
-                                       (unsigned long)prom_cif_callback;
-                       p1275buf.prom_callback = va_arg(list, long);
-                       break;
-               }
-       }
-       va_end(list);
-
        prom_world(1);
-       prom_cif_interface();
+       prom_cif_direct(args);
        prom_world(0);
 
-       attrs = fmt >> 8;
-       va_start(list, fmt);
-       for (i = 0; i < nargs; i++, attrs >>= 3) {
-               switch (attrs & 0x7) {
-               case P1275_ARG_NUMBER:
-                       (void) va_arg(list, long);
-                       break;
-               case P1275_ARG_IN_STRING:
-                       (void) va_arg(list, char *);
-                       break;
-               case P1275_ARG_IN_FUNCTION:
-                       (void) va_arg(list, long);
-                       break;
-               case P1275_ARG_IN_BUF:
-                       (void) va_arg(list, char *);
-                       (void) va_arg(list, long);
-                       i++; attrs >>= 3;
-                       break;
-               case P1275_ARG_OUT_BUF:
-                       p = va_arg(list, char *);
-                       x = va_arg(list, long);
-                       memcpy (p, (char *)(p1275buf.prom_args[i + 3]), (int)x);
-                       i++; attrs >>= 3;
-                       break;
-               case P1275_ARG_OUT_32B:
-                       p = va_arg(list, char *);
-                       memcpy (p, (char *)(p1275buf.prom_args[i + 3]), 32);
-                       break;
-               }
-       }
-       va_end(list);
-       x = p1275buf.prom_args [nargs + 3];
-
        raw_spin_unlock(&prom_entry_lock);
        raw_local_irq_restore(flags);
-
-       return x;
 }
 
 void prom_cif_init(void *cif_handler, void *cif_stack)
index 3c0d2dd9f6939faf1daf53f61141c785001429b4..9d3f9137a43ae1307ea698d81e13896af7504453 100644 (file)
 #include <asm/oplib.h>
 #include <asm/ldc.h>
 
+static int prom_node_to_node(const char *type, int node)
+{
+       unsigned long args[5];
+
+       args[0] = (unsigned long) type;
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[4];
+}
+
 /* Return the child of node 'node' or zero if no this node has no
  * direct descendent.
  */
 inline int __prom_getchild(int node)
 {
-       return p1275_cmd ("child", P1275_INOUT(1, 1), node);
+       return prom_node_to_node("child", node);
 }
 
 inline int prom_getchild(int node)
 {
        int cnode;
 
-       if(node == -1) return 0;
+       if (node == -1)
+               return 0;
        cnode = __prom_getchild(node);
-       if(cnode == -1) return 0;
-       return (int)cnode;
+       if (cnode == -1)
+               return 0;
+       return cnode;
 }
 EXPORT_SYMBOL(prom_getchild);
 
@@ -39,10 +56,12 @@ inline int prom_getparent(int node)
 {
        int cnode;
 
-       if(node == -1) return 0;
-       cnode = p1275_cmd ("parent", P1275_INOUT(1, 1), node);
-       if(cnode == -1) return 0;
-       return (int)cnode;
+       if (node == -1)
+               return 0;
+       cnode = prom_node_to_node("parent", node);
+       if (cnode == -1)
+               return 0;
+       return cnode;
 }
 
 /* Return the next sibling of node 'node' or zero if no more siblings
@@ -50,7 +69,7 @@ inline int prom_getparent(int node)
  */
 inline int __prom_getsibling(int node)
 {
-       return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
+       return prom_node_to_node(prom_peer_name, node);
 }
 
 inline int prom_getsibling(int node)
@@ -72,11 +91,21 @@ EXPORT_SYMBOL(prom_getsibling);
  */
 inline int prom_getproplen(int node, const char *prop)
 {
-       if((!node) || (!prop)) return -1;
-       return p1275_cmd ("getproplen", 
-                         P1275_ARG(1,P1275_ARG_IN_STRING)|
-                         P1275_INOUT(2, 1), 
-                         node, prop);
+       unsigned long args[6];
+
+       if (!node || !prop)
+               return -1;
+
+       args[0] = (unsigned long) "getproplen";
+       args[1] = 2;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = (unsigned long) prop;
+       args[5] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[5];
 }
 EXPORT_SYMBOL(prom_getproplen);
 
@@ -87,19 +116,25 @@ EXPORT_SYMBOL(prom_getproplen);
 inline int prom_getproperty(int node, const char *prop,
                            char *buffer, int bufsize)
 {
+       unsigned long args[8];
        int plen;
 
        plen = prom_getproplen(node, prop);
-       if ((plen > bufsize) || (plen == 0) || (plen == -1)) {
+       if ((plen > bufsize) || (plen == 0) || (plen == -1))
                return -1;
-       } else {
-               /* Ok, things seem all right. */
-               return p1275_cmd(prom_getprop_name, 
-                                P1275_ARG(1,P1275_ARG_IN_STRING)|
-                                P1275_ARG(2,P1275_ARG_OUT_BUF)|
-                                P1275_INOUT(4, 1), 
-                                node, prop, buffer, P1275_SIZE(plen));
-       }
+
+       args[0] = (unsigned long) prom_getprop_name;
+       args[1] = 4;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = (unsigned long) prop;
+       args[5] = (unsigned long) buffer;
+       args[6] = bufsize;
+       args[7] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[7];
 }
 EXPORT_SYMBOL(prom_getproperty);
 
@@ -110,7 +145,7 @@ inline int prom_getint(int node, const char *prop)
 {
        int intprop;
 
-       if(prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
+       if (prom_getproperty(node, prop, (char *) &intprop, sizeof(int)) != -1)
                return intprop;
 
        return -1;
@@ -126,7 +161,8 @@ int prom_getintdefault(int node, const char *property, int deflt)
        int retval;
 
        retval = prom_getint(node, property);
-       if(retval == -1) return deflt;
+       if (retval == -1)
+               return deflt;
 
        return retval;
 }
@@ -138,7 +174,8 @@ int prom_getbool(int node, const char *prop)
        int retval;
 
        retval = prom_getproplen(node, prop);
-       if(retval == -1) return 0;
+       if (retval == -1)
+               return 0;
        return 1;
 }
 EXPORT_SYMBOL(prom_getbool);
@@ -152,7 +189,8 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
        int len;
 
        len = prom_getproperty(node, prop, user_buf, ubuf_size);
-       if(len != -1) return;
+       if (len != -1)
+               return;
        user_buf[0] = 0;
 }
 EXPORT_SYMBOL(prom_getstring);
@@ -164,7 +202,8 @@ int prom_nodematch(int node, const char *name)
 {
        char namebuf[128];
        prom_getproperty(node, "name", namebuf, sizeof(namebuf));
-       if(strcmp(namebuf, name) == 0) return 1;
+       if (strcmp(namebuf, name) == 0)
+               return 1;
        return 0;
 }
 
@@ -190,16 +229,29 @@ int prom_searchsiblings(int node_start, const char *nodename)
 }
 EXPORT_SYMBOL(prom_searchsiblings);
 
+static const char *prom_nextprop_name = "nextprop";
+
 /* Return the first property type for node 'node'.
  * buffer should be at least 32B in length
  */
 inline char *prom_firstprop(int node, char *buffer)
 {
+       unsigned long args[7];
+
        *buffer = 0;
-       if(node == -1) return buffer;
-       p1275_cmd ("nextprop", P1275_ARG(2,P1275_ARG_OUT_32B)|
-                              P1275_INOUT(3, 0), 
-                              node, (char *) 0x0, buffer);
+       if (node == -1)
+               return buffer;
+
+       args[0] = (unsigned long) prom_nextprop_name;
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = 0;
+       args[5] = (unsigned long) buffer;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
        return buffer;
 }
 EXPORT_SYMBOL(prom_firstprop);
@@ -210,9 +262,10 @@ EXPORT_SYMBOL(prom_firstprop);
  */
 inline char *prom_nextprop(int node, const char *oprop, char *buffer)
 {
+       unsigned long args[7];
        char buf[32];
 
-       if(node == -1) {
+       if (node == -1) {
                *buffer = 0;
                return buffer;
        }
@@ -220,10 +273,17 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
                strcpy (buf, oprop);
                oprop = buf;
        }
-       p1275_cmd ("nextprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
-                                   P1275_ARG(2,P1275_ARG_OUT_32B)|
-                                   P1275_INOUT(3, 0), 
-                                   node, oprop, buffer); 
+
+       args[0] = (unsigned long) prom_nextprop_name;
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = (unsigned long) oprop;
+       args[5] = (unsigned long) buffer;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
        return buffer;
 }
 EXPORT_SYMBOL(prom_nextprop);
@@ -231,12 +291,19 @@ EXPORT_SYMBOL(prom_nextprop);
 int
 prom_finddevice(const char *name)
 {
+       unsigned long args[5];
+
        if (!name)
                return 0;
-       return p1275_cmd(prom_finddev_name,
-                        P1275_ARG(0,P1275_ARG_IN_STRING)|
-                        P1275_INOUT(1, 1), 
-                        name);
+       args[0] = (unsigned long) "finddevice";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned long) name;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[4];
 }
 EXPORT_SYMBOL(prom_finddevice);
 
@@ -247,7 +314,7 @@ int prom_node_has_property(int node, const char *prop)
        *buf = 0;
        do {
                prom_nextprop(node, buf, buf);
-               if(!strcmp(buf, prop))
+               if (!strcmp(buf, prop))
                        return 1;
        } while (*buf);
        return 0;
@@ -260,6 +327,8 @@ EXPORT_SYMBOL(prom_node_has_property);
 int
 prom_setprop(int node, const char *pname, char *value, int size)
 {
+       unsigned long args[8];
+
        if (size == 0)
                return 0;
        if ((pname == 0) || (value == 0))
@@ -271,19 +340,37 @@ prom_setprop(int node, const char *pname, char *value, int size)
                return 0;
        }
 #endif
-       return p1275_cmd ("setprop", P1275_ARG(1,P1275_ARG_IN_STRING)|
-                                         P1275_ARG(2,P1275_ARG_IN_BUF)|
-                                         P1275_INOUT(4, 1), 
-                                         node, pname, value, P1275_SIZE(size));
+       args[0] = (unsigned long) "setprop";
+       args[1] = 4;
+       args[2] = 1;
+       args[3] = (unsigned int) node;
+       args[4] = (unsigned long) pname;
+       args[5] = (unsigned long) value;
+       args[6] = size;
+       args[7] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[7];
 }
 EXPORT_SYMBOL(prom_setprop);
 
 inline int prom_inst2pkg(int inst)
 {
+       unsigned long args[5];
        int node;
        
-       node = p1275_cmd ("instance-to-package", P1275_INOUT(1, 1), inst);
-       if (node == -1) return 0;
+       args[0] = (unsigned long) "instance-to-package";
+       args[1] = 1;
+       args[2] = 1;
+       args[3] = (unsigned int) inst;
+       args[4] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       node = (int) args[4];
+       if (node == -1)
+               return 0;
        return node;
 }
 
@@ -296,17 +383,28 @@ prom_pathtoinode(const char *path)
        int node, inst;
 
        inst = prom_devopen (path);
-       if (inst == 0) return 0;
-       node = prom_inst2pkg (inst);
-       prom_devclose (inst);
-       if (node == -1) return 0;
+       if (inst == 0)
+               return 0;
+       node = prom_inst2pkg(inst);
+       prom_devclose(inst);
+       if (node == -1)
+               return 0;
        return node;
 }
 
 int prom_ihandle2path(int handle, char *buffer, int bufsize)
 {
-       return p1275_cmd("instance-to-path",
-                        P1275_ARG(1,P1275_ARG_OUT_BUF)|
-                        P1275_INOUT(3, 1),
-                        handle, buffer, P1275_SIZE(bufsize));
+       unsigned long args[7];
+
+       args[0] = (unsigned long) "instance-to-path";
+       args[1] = 3;
+       args[2] = 1;
+       args[3] = (unsigned int) handle;
+       args[4] = (unsigned long) buffer;
+       args[5] = bufsize;
+       args[6] = (unsigned long) -1;
+
+       p1275_cmd_direct(args);
+
+       return (int) args[6];
 }