diff options
-rw-r--r-- | arch/sparc/lib/atomic32.c | 4 | ||||
-rw-r--r-- | arch/sparc64/kernel/entry.S | 72 | ||||
-rw-r--r-- | drivers/sbus/char/flash.c | 1 | ||||
-rw-r--r-- | include/asm-sparc64/hypervisor.h | 168 |
4 files changed, 243 insertions, 2 deletions
diff --git a/arch/sparc/lib/atomic32.c b/arch/sparc/lib/atomic32.c index 617d29832e1..cbddeb38ffd 100644 --- a/arch/sparc/lib/atomic32.c +++ b/arch/sparc/lib/atomic32.c @@ -124,10 +124,10 @@ unsigned long __cmpxchg_u32(volatile u32 *ptr, u32 old, u32 new) unsigned long flags; u32 prev; - spin_lock_irqsave(ATOMIC_HASH(addr), flags); + spin_lock_irqsave(ATOMIC_HASH(ptr), flags); if ((prev = *ptr) == old) *ptr = new; - spin_unlock_irqrestore(ATOMIC_HASH(addr), flags); + spin_unlock_irqrestore(ATOMIC_HASH(ptr), flags); return (unsigned long)prev; } diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 8f10dda0f5c..ed712e0b337 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -2498,3 +2498,75 @@ sun4v_vintr_set_target: retl nop .size sun4v_vintr_set_target, .-sun4v_vintr_set_target + + /* %o0: NCS sub-function + * %o1: sub-function arg real-address + * %o2: sub-function arg size + * + * returns %o0: status + */ + .globl sun4v_ncs_request + .type sun4v_ncs_request,#function +sun4v_ncs_request: + mov HV_FAST_NCS_REQUEST, %o5 + ta HV_FAST_TRAP + retl + nop + .size sun4v_ncs_request, .-sun4v_ncs_request + + .globl sun4v_scv_send + .type sun4v_scv_send,#function +sun4v_scv_send: + save %sp, -192, %sp + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov HV_FAST_SVC_SEND, %o5 + ta HV_FAST_TRAP + stx %o1, [%i3] + ret + restore + .size sun4v_scv_send, .-sun4v_scv_send + + .globl sun4v_scv_recv + .type sun4v_scv_recv,#function +sun4v_scv_recv: + save %sp, -192, %sp + mov %i0, %o0 + mov %i1, %o1 + mov %i2, %o2 + mov HV_FAST_SVC_RECV, %o5 + ta HV_FAST_TRAP + stx %o1, [%i3] + ret + restore + .size sun4v_scv_recv, .-sun4v_scv_recv + + .globl sun4v_scv_getstatus + .type sun4v_scv_getstatus,#function +sun4v_scv_getstatus: + mov HV_FAST_SVC_GETSTATUS, %o5 + mov %o1, %o4 + ta HV_FAST_TRAP + stx %o1, [%o4] + retl + nop + .size sun4v_scv_getstatus, .-sun4v_scv_getstatus + + .globl sun4v_scv_setstatus + .type sun4v_scv_setstatus,#function +sun4v_scv_setstatus: + mov HV_FAST_SVC_SETSTATUS, %o5 + ta HV_FAST_TRAP + retl + nop + .size sun4v_scv_setstatus, .-sun4v_scv_setstatus + + .globl sun4v_scv_clrstatus + .type sun4v_scv_clrstatus,#function +sun4v_scv_clrstatus: + mov HV_FAST_SVC_CLRSTATUS, %o5 + ta HV_FAST_TRAP + retl + nop + .size sun4v_scv_clrstatus, .-sun4v_scv_clrstatus diff --git a/drivers/sbus/char/flash.c b/drivers/sbus/char/flash.c index 262f01e6859..44e039865aa 100644 --- a/drivers/sbus/char/flash.c +++ b/drivers/sbus/char/flash.c @@ -14,6 +14,7 @@ #include <linux/init.h> #include <linux/smp_lock.h> #include <linux/spinlock.h> +#include <linux/mm.h> #include <asm/system.h> #include <asm/uaccess.h> diff --git a/include/asm-sparc64/hypervisor.h b/include/asm-sparc64/hypervisor.h index 5cdb1ff0483..4a43075a061 100644 --- a/include/asm-sparc64/hypervisor.h +++ b/include/asm-sparc64/hypervisor.h @@ -1097,6 +1097,80 @@ extern unsigned long sun4v_mach_set_soft_state(unsigned long soft_state, */ #define HV_FAST_MACH_GET_SOFT_STATE 0x71 +/* svc_send() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SVC_SEND + * ARG0: service ID + * ARG1: buffer real address + * ARG2: buffer size + * RET0: STATUS + * RET1: sent_bytes + * + * Be careful, all output registers are clobbered by this operation, + * so for example it is not possible to save away a value in %o4 + * across the trap. + */ +#define HV_FAST_SVC_SEND 0x80 + +/* svc_recv() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SVC_RECV + * ARG0: service ID + * ARG1: buffer real address + * ARG2: buffer size + * RET0: STATUS + * RET1: recv_bytes + * + * Be careful, all output registers are clobbered by this operation, + * so for example it is not possible to save away a value in %o4 + * across the trap. + */ +#define HV_FAST_SVC_RECV 0x81 + +/* svc_getstatus() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SVC_GETSTATUS + * ARG0: service ID + * RET0: STATUS + * RET1: status bits + */ +#define HV_FAST_SVC_GETSTATUS 0x82 + +/* svc_setstatus() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SVC_SETSTATUS + * ARG0: service ID + * ARG1: bits to set + * RET0: STATUS + */ +#define HV_FAST_SVC_SETSTATUS 0x83 + +/* svc_clrstatus() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_SVC_CLRSTATUS + * ARG0: service ID + * ARG1: bits to clear + * RET0: STATUS + */ +#define HV_FAST_SVC_CLRSTATUS 0x84 + +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_svc_send(unsigned long svc_id, + unsigned long buffer, + unsigned long buffer_size, + unsigned long *sent_bytes); +extern unsigned long sun4v_svc_recv(unsigned long svc_id, + unsigned long buffer, + unsigned long buffer_size, + unsigned long *recv_bytes); +extern unsigned long sun4v_svc_getstatus(unsigned long svc_id, + unsigned long *status_bits); +extern unsigned long sun4v_svc_setstatus(unsigned long svc_id, + unsigned long status_bits); +extern unsigned long sun4v_svc_clrstatus(unsigned long svc_id, + unsigned long status_bits); +#endif + /* Trap trace services. * * The hypervisor provides a trap tracing capability for privileged @@ -2724,6 +2798,100 @@ struct hv_mmu_statistics { */ #define HV_FAST_MMUSTAT_INFO 0x103 +/* NCS crypto services */ + +/* ncs_request() sub-function numbers */ +#define HV_NCS_QCONF 0x01 +#define HV_NCS_QTAIL_UPDATE 0x02 + +#ifndef __ASSEMBLY__ +struct hv_ncs_queue_entry { + /* MAU Control Register */ + unsigned long mau_control; +#define MAU_CONTROL_INV_PARITY 0x0000000000002000 +#define MAU_CONTROL_STRAND 0x0000000000001800 +#define MAU_CONTROL_BUSY 0x0000000000000400 +#define MAU_CONTROL_INT 0x0000000000000200 +#define MAU_CONTROL_OP 0x00000000000001c0 +#define MAU_CONTROL_OP_SHIFT 6 +#define MAU_OP_LOAD_MA_MEMORY 0x0 +#define MAU_OP_STORE_MA_MEMORY 0x1 +#define MAU_OP_MODULAR_MULT 0x2 +#define MAU_OP_MODULAR_REDUCE 0x3 +#define MAU_OP_MODULAR_EXP_LOOP 0x4 +#define MAU_CONTROL_LEN 0x000000000000003f +#define MAU_CONTROL_LEN_SHIFT 0 + + /* Real address of bytes to load or store bytes + * into/out-of the MAU. + */ + unsigned long mau_mpa; + + /* Modular Arithmetic MA Offset Register. */ + unsigned long mau_ma; + + /* Modular Arithmetic N Prime Register. */ + unsigned long mau_np; +}; + +struct hv_ncs_qconf_arg { + unsigned long mid; /* MAU ID, 1 per core on Niagara */ + unsigned long base; /* Real address base of queue */ + unsigned long end; /* Real address end of queue */ + unsigned long num_ents; /* Number of entries in queue */ +}; + +struct hv_ncs_qtail_update_arg { + unsigned long mid; /* MAU ID, 1 per core on Niagara */ + unsigned long tail; /* New tail index to use */ + unsigned long syncflag; /* only SYNCFLAG_SYNC is implemented */ +#define HV_NCS_SYNCFLAG_SYNC 0x00 +#define HV_NCS_SYNCFLAG_ASYNC 0x01 +}; +#endif + +/* ncs_request() + * TRAP: HV_FAST_TRAP + * FUNCTION: HV_FAST_NCS_REQUEST + * ARG0: NCS sub-function + * ARG1: sub-function argument real address + * ARG2: size in bytes of sub-function argument + * RET0: status + * + * The MAU chip of the Niagara processor is not directly accessible + * to privileged code, instead it is programmed indirectly via this + * hypervisor API. + * + * The interfaces defines a queue of MAU operations to perform. + * Privileged code registers a queue with the hypervisor by invoking + * this HVAPI with the HV_NCS_QCONF sub-function, which defines the + * base, end, and number of entries of the queue. Each queue entry + * contains a MAU register struct block. + * + * The privileged code then proceeds to add entries to the queue and + * then invoke the HV_NCS_QTAIL_UPDATE sub-function. Since only + * synchronous operations are supported by the current hypervisor, + * HV_NCS_QTAIL_UPDATE will run all the pending queue entries to + * completion and return HV_EOK, or return an error code. + * + * The real address of the sub-function argument must be aligned on at + * least an 8-byte boundary. + * + * The tail argument of HV_NCS_QTAIL_UPDATE is an index, not a byte + * offset, into the queue and must be less than or equal the 'num_ents' + * argument given in the HV_NCS_QCONF call. + */ +#define HV_FAST_NCS_REQUEST 0x110 + +#ifndef __ASSEMBLY__ +extern unsigned long sun4v_ncs_request(unsigned long request, + unsigned long arg_ra, + unsigned long arg_size); +#endif + +#define HV_FAST_FIRE_GET_PERFREG 0x120 +#define HV_FAST_FIRE_SET_PERFREG 0x121 + /* Function numbers for HV_CORE_TRAP. */ #define HV_CORE_SET_VER 0x00 #define HV_CORE_PUTCHAR 0x01 |