Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 
0003 /*
0004  *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
0005  */
0006 #ifndef __GRU_KSERVICES_H_
0007 #define __GRU_KSERVICES_H_
0008 
0009 
0010 /*
0011  * Message queues using the GRU to send/receive messages.
0012  *
0013  * These function allow the user to create a message queue for
0014  * sending/receiving 1 or 2 cacheline messages using the GRU.
0015  *
0016  * Processes SENDING messages will use a kernel CBR/DSR to send
0017  * the message. This is transparent to the caller.
0018  *
0019  * The receiver does not use any GRU resources.
0020  *
0021  * The functions support:
0022  *  - single receiver
0023  *  - multiple senders
0024  *  - cross partition message
0025  *
0026  * Missing features ZZZ:
0027  *  - user options for dealing with timeouts, queue full, etc.
0028  *  - gru_create_message_queue() needs interrupt vector info
0029  */
0030 
0031 struct gru_message_queue_desc {
0032     void        *mq;            /* message queue vaddress */
0033     unsigned long   mq_gpa;         /* global address of mq */
0034     int     qlines;         /* queue size in CL */
0035     int     interrupt_vector;   /* interrupt vector */
0036     int     interrupt_pnode;    /* pnode for interrupt */
0037     int     interrupt_apicid;   /* lapicid for interrupt */
0038 };
0039 
0040 /*
0041  * Initialize a user allocated chunk of memory to be used as
0042  * a message queue. The caller must ensure that the queue is
0043  * in contiguous physical memory and is cacheline aligned.
0044  *
0045  * Message queue size is the total number of bytes allocated
0046  * to the queue including a 2 cacheline header that is used
0047  * to manage the queue.
0048  *
0049  *  Input:
0050  *  mqd pointer to message queue descriptor
0051  *  p   pointer to user allocated mesq memory.
0052  *  bytes   size of message queue in bytes
0053  *      vector  interrupt vector (zero if no interrupts)
0054  *      nasid   nasid of blade where interrupt is delivered
0055  *      apicid  apicid of cpu for interrupt
0056  *
0057  *  Errors:
0058  *      0   OK
0059  *      >0  error
0060  */
0061 extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
0062         void *p, unsigned int bytes, int nasid, int vector, int apicid);
0063 
0064 /*
0065  * Send a message to a message queue.
0066  *
0067  * Note: The message queue transport mechanism uses the first 32
0068  * bits of the message. Users should avoid using these bits.
0069  *
0070  *
0071  *   Input:
0072  *  mqd pointer to message queue descriptor
0073  *  mesg    pointer to message. Must be 64-bit aligned
0074  *  bytes   size of message in bytes
0075  *
0076  *   Output:
0077  *      0   message sent
0078  *     >0   Send failure - see error codes below
0079  *
0080  */
0081 extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
0082             void *mesg, unsigned int bytes);
0083 
0084 /* Status values for gru_send_message() */
0085 #define MQE_OK          0   /* message sent successfully */
0086 #define MQE_CONGESTION      1   /* temporary congestion, try again */
0087 #define MQE_QUEUE_FULL      2   /* queue is full */
0088 #define MQE_UNEXPECTED_CB_ERR   3   /* unexpected CB error */
0089 #define MQE_PAGE_OVERFLOW   10  /* BUG - queue overflowed a page */
0090 #define MQE_BUG_NO_RESOURCES    11  /* BUG - could not alloc GRU cb/dsr */
0091 
0092 /*
0093  * Advance the receive pointer for the message queue to the next message.
0094  * Note: current API requires messages to be gotten & freed in order. Future
0095  * API extensions may allow for out-of-order freeing.
0096  *
0097  *   Input
0098  *  mqd pointer to message queue descriptor
0099  *  mesq    message being freed
0100  */
0101 extern void gru_free_message(struct gru_message_queue_desc *mqd,
0102                  void *mesq);
0103 
0104 /*
0105  * Get next message from message queue. Returns pointer to
0106  * message OR NULL if no message present.
0107  * User must call gru_free_message() after message is processed
0108  * in order to move the queue pointers to next message.
0109  *
0110  *   Input
0111  *  mqd pointer to message queue descriptor
0112  *
0113  *   Output:
0114  *  p   pointer to message
0115  *  NULL    no message available
0116  */
0117 extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
0118 
0119 
0120 /*
0121  * Read a GRU global GPA. Source can be located in a remote partition.
0122  *
0123  *    Input:
0124  *      value       memory address where MMR value is returned
0125  *      gpa     source numalink physical address of GPA
0126  *
0127  *    Output:
0128  *  0       OK
0129  *  >0      error
0130  */
0131 int gru_read_gpa(unsigned long *value, unsigned long gpa);
0132 
0133 
0134 /*
0135  * Copy data using the GRU. Source or destination can be located in a remote
0136  * partition.
0137  *
0138  *    Input:
0139  *      dest_gpa    destination global physical address
0140  *      src_gpa     source global physical address
0141  *      bytes       number of bytes to copy
0142  *
0143  *    Output:
0144  *  0       OK
0145  *  >0      error
0146  */
0147 extern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
0148                             unsigned int bytes);
0149 
0150 /*
0151  * Reserve GRU resources to be used asynchronously.
0152  *
0153  *  input:
0154  *      blade_id  - blade on which resources should be reserved
0155  *      cbrs      - number of CBRs
0156  *      dsr_bytes - number of DSR bytes needed
0157  *      cmp   - completion structure for waiting for
0158  *              async completions
0159  *  output:
0160  *      handle to identify resource
0161  *      (0 = no resources)
0162  */
0163 extern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
0164                 struct completion *cmp);
0165 
0166 /*
0167  * Release async resources previously reserved.
0168  *
0169  *  input:
0170  *      han - handle to identify resources
0171  */
0172 extern void gru_release_async_resources(unsigned long han);
0173 
0174 /*
0175  * Wait for async GRU instructions to complete.
0176  *
0177  *  input:
0178  *      han - handle to identify resources
0179  */
0180 extern void gru_wait_async_cbr(unsigned long han);
0181 
0182 /*
0183  * Lock previous reserved async GRU resources
0184  *
0185  *  input:
0186  *      han - handle to identify resources
0187  *  output:
0188  *      cb  - pointer to first CBR
0189  *      dsr - pointer to first DSR
0190  */
0191 extern void gru_lock_async_resource(unsigned long han,  void **cb, void **dsr);
0192 
0193 /*
0194  * Unlock previous reserved async GRU resources
0195  *
0196  *  input:
0197  *      han - handle to identify resources
0198  */
0199 extern void gru_unlock_async_resource(unsigned long han);
0200 
0201 #endif      /* __GRU_KSERVICES_H_ */