18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * Copyright (c) 2008 Silicon Graphics, Inc. All Rights Reserved. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci#ifndef __GRU_KSERVICES_H_ 78c2ecf20Sopenharmony_ci#define __GRU_KSERVICES_H_ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci/* 118c2ecf20Sopenharmony_ci * Message queues using the GRU to send/receive messages. 128c2ecf20Sopenharmony_ci * 138c2ecf20Sopenharmony_ci * These function allow the user to create a message queue for 148c2ecf20Sopenharmony_ci * sending/receiving 1 or 2 cacheline messages using the GRU. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Processes SENDING messages will use a kernel CBR/DSR to send 178c2ecf20Sopenharmony_ci * the message. This is transparent to the caller. 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * The receiver does not use any GRU resources. 208c2ecf20Sopenharmony_ci * 218c2ecf20Sopenharmony_ci * The functions support: 228c2ecf20Sopenharmony_ci * - single receiver 238c2ecf20Sopenharmony_ci * - multiple senders 248c2ecf20Sopenharmony_ci * - cross partition message 258c2ecf20Sopenharmony_ci * 268c2ecf20Sopenharmony_ci * Missing features ZZZ: 278c2ecf20Sopenharmony_ci * - user options for dealing with timeouts, queue full, etc. 288c2ecf20Sopenharmony_ci * - gru_create_message_queue() needs interrupt vector info 298c2ecf20Sopenharmony_ci */ 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_cistruct gru_message_queue_desc { 328c2ecf20Sopenharmony_ci void *mq; /* message queue vaddress */ 338c2ecf20Sopenharmony_ci unsigned long mq_gpa; /* global address of mq */ 348c2ecf20Sopenharmony_ci int qlines; /* queue size in CL */ 358c2ecf20Sopenharmony_ci int interrupt_vector; /* interrupt vector */ 368c2ecf20Sopenharmony_ci int interrupt_pnode; /* pnode for interrupt */ 378c2ecf20Sopenharmony_ci int interrupt_apicid; /* lapicid for interrupt */ 388c2ecf20Sopenharmony_ci}; 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* 418c2ecf20Sopenharmony_ci * Initialize a user allocated chunk of memory to be used as 428c2ecf20Sopenharmony_ci * a message queue. The caller must ensure that the queue is 438c2ecf20Sopenharmony_ci * in contiguous physical memory and is cacheline aligned. 448c2ecf20Sopenharmony_ci * 458c2ecf20Sopenharmony_ci * Message queue size is the total number of bytes allocated 468c2ecf20Sopenharmony_ci * to the queue including a 2 cacheline header that is used 478c2ecf20Sopenharmony_ci * to manage the queue. 488c2ecf20Sopenharmony_ci * 498c2ecf20Sopenharmony_ci * Input: 508c2ecf20Sopenharmony_ci * mqd pointer to message queue descriptor 518c2ecf20Sopenharmony_ci * p pointer to user allocated mesq memory. 528c2ecf20Sopenharmony_ci * bytes size of message queue in bytes 538c2ecf20Sopenharmony_ci * vector interrupt vector (zero if no interrupts) 548c2ecf20Sopenharmony_ci * nasid nasid of blade where interrupt is delivered 558c2ecf20Sopenharmony_ci * apicid apicid of cpu for interrupt 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * Errors: 588c2ecf20Sopenharmony_ci * 0 OK 598c2ecf20Sopenharmony_ci * >0 error 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ciextern int gru_create_message_queue(struct gru_message_queue_desc *mqd, 628c2ecf20Sopenharmony_ci void *p, unsigned int bytes, int nasid, int vector, int apicid); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* 658c2ecf20Sopenharmony_ci * Send a message to a message queue. 668c2ecf20Sopenharmony_ci * 678c2ecf20Sopenharmony_ci * Note: The message queue transport mechanism uses the first 32 688c2ecf20Sopenharmony_ci * bits of the message. Users should avoid using these bits. 698c2ecf20Sopenharmony_ci * 708c2ecf20Sopenharmony_ci * 718c2ecf20Sopenharmony_ci * Input: 728c2ecf20Sopenharmony_ci * mqd pointer to message queue descriptor 738c2ecf20Sopenharmony_ci * mesg pointer to message. Must be 64-bit aligned 748c2ecf20Sopenharmony_ci * bytes size of message in bytes 758c2ecf20Sopenharmony_ci * 768c2ecf20Sopenharmony_ci * Output: 778c2ecf20Sopenharmony_ci * 0 message sent 788c2ecf20Sopenharmony_ci * >0 Send failure - see error codes below 798c2ecf20Sopenharmony_ci * 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ciextern int gru_send_message_gpa(struct gru_message_queue_desc *mqd, 828c2ecf20Sopenharmony_ci void *mesg, unsigned int bytes); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci/* Status values for gru_send_message() */ 858c2ecf20Sopenharmony_ci#define MQE_OK 0 /* message sent successfully */ 868c2ecf20Sopenharmony_ci#define MQE_CONGESTION 1 /* temporary congestion, try again */ 878c2ecf20Sopenharmony_ci#define MQE_QUEUE_FULL 2 /* queue is full */ 888c2ecf20Sopenharmony_ci#define MQE_UNEXPECTED_CB_ERR 3 /* unexpected CB error */ 898c2ecf20Sopenharmony_ci#define MQE_PAGE_OVERFLOW 10 /* BUG - queue overflowed a page */ 908c2ecf20Sopenharmony_ci#define MQE_BUG_NO_RESOURCES 11 /* BUG - could not alloc GRU cb/dsr */ 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci/* 938c2ecf20Sopenharmony_ci * Advance the receive pointer for the message queue to the next message. 948c2ecf20Sopenharmony_ci * Note: current API requires messages to be gotten & freed in order. Future 958c2ecf20Sopenharmony_ci * API extensions may allow for out-of-order freeing. 968c2ecf20Sopenharmony_ci * 978c2ecf20Sopenharmony_ci * Input 988c2ecf20Sopenharmony_ci * mqd pointer to message queue descriptor 998c2ecf20Sopenharmony_ci * mesq message being freed 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ciextern void gru_free_message(struct gru_message_queue_desc *mqd, 1028c2ecf20Sopenharmony_ci void *mesq); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* 1058c2ecf20Sopenharmony_ci * Get next message from message queue. Returns pointer to 1068c2ecf20Sopenharmony_ci * message OR NULL if no message present. 1078c2ecf20Sopenharmony_ci * User must call gru_free_message() after message is processed 1088c2ecf20Sopenharmony_ci * in order to move the queue pointers to next message. 1098c2ecf20Sopenharmony_ci * 1108c2ecf20Sopenharmony_ci * Input 1118c2ecf20Sopenharmony_ci * mqd pointer to message queue descriptor 1128c2ecf20Sopenharmony_ci * 1138c2ecf20Sopenharmony_ci * Output: 1148c2ecf20Sopenharmony_ci * p pointer to message 1158c2ecf20Sopenharmony_ci * NULL no message available 1168c2ecf20Sopenharmony_ci */ 1178c2ecf20Sopenharmony_ciextern void *gru_get_next_message(struct gru_message_queue_desc *mqd); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci/* 1218c2ecf20Sopenharmony_ci * Read a GRU global GPA. Source can be located in a remote partition. 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * Input: 1248c2ecf20Sopenharmony_ci * value memory address where MMR value is returned 1258c2ecf20Sopenharmony_ci * gpa source numalink physical address of GPA 1268c2ecf20Sopenharmony_ci * 1278c2ecf20Sopenharmony_ci * Output: 1288c2ecf20Sopenharmony_ci * 0 OK 1298c2ecf20Sopenharmony_ci * >0 error 1308c2ecf20Sopenharmony_ci */ 1318c2ecf20Sopenharmony_ciint gru_read_gpa(unsigned long *value, unsigned long gpa); 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci/* 1358c2ecf20Sopenharmony_ci * Copy data using the GRU. Source or destination can be located in a remote 1368c2ecf20Sopenharmony_ci * partition. 1378c2ecf20Sopenharmony_ci * 1388c2ecf20Sopenharmony_ci * Input: 1398c2ecf20Sopenharmony_ci * dest_gpa destination global physical address 1408c2ecf20Sopenharmony_ci * src_gpa source global physical address 1418c2ecf20Sopenharmony_ci * bytes number of bytes to copy 1428c2ecf20Sopenharmony_ci * 1438c2ecf20Sopenharmony_ci * Output: 1448c2ecf20Sopenharmony_ci * 0 OK 1458c2ecf20Sopenharmony_ci * >0 error 1468c2ecf20Sopenharmony_ci */ 1478c2ecf20Sopenharmony_ciextern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa, 1488c2ecf20Sopenharmony_ci unsigned int bytes); 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci/* 1518c2ecf20Sopenharmony_ci * Reserve GRU resources to be used asynchronously. 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * input: 1548c2ecf20Sopenharmony_ci * blade_id - blade on which resources should be reserved 1558c2ecf20Sopenharmony_ci * cbrs - number of CBRs 1568c2ecf20Sopenharmony_ci * dsr_bytes - number of DSR bytes needed 1578c2ecf20Sopenharmony_ci * cmp - completion structure for waiting for 1588c2ecf20Sopenharmony_ci * async completions 1598c2ecf20Sopenharmony_ci * output: 1608c2ecf20Sopenharmony_ci * handle to identify resource 1618c2ecf20Sopenharmony_ci * (0 = no resources) 1628c2ecf20Sopenharmony_ci */ 1638c2ecf20Sopenharmony_ciextern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes, 1648c2ecf20Sopenharmony_ci struct completion *cmp); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci/* 1678c2ecf20Sopenharmony_ci * Release async resources previously reserved. 1688c2ecf20Sopenharmony_ci * 1698c2ecf20Sopenharmony_ci * input: 1708c2ecf20Sopenharmony_ci * han - handle to identify resources 1718c2ecf20Sopenharmony_ci */ 1728c2ecf20Sopenharmony_ciextern void gru_release_async_resources(unsigned long han); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci/* 1758c2ecf20Sopenharmony_ci * Wait for async GRU instructions to complete. 1768c2ecf20Sopenharmony_ci * 1778c2ecf20Sopenharmony_ci * input: 1788c2ecf20Sopenharmony_ci * han - handle to identify resources 1798c2ecf20Sopenharmony_ci */ 1808c2ecf20Sopenharmony_ciextern void gru_wait_async_cbr(unsigned long han); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci/* 1838c2ecf20Sopenharmony_ci * Lock previous reserved async GRU resources 1848c2ecf20Sopenharmony_ci * 1858c2ecf20Sopenharmony_ci * input: 1868c2ecf20Sopenharmony_ci * han - handle to identify resources 1878c2ecf20Sopenharmony_ci * output: 1888c2ecf20Sopenharmony_ci * cb - pointer to first CBR 1898c2ecf20Sopenharmony_ci * dsr - pointer to first DSR 1908c2ecf20Sopenharmony_ci */ 1918c2ecf20Sopenharmony_ciextern void gru_lock_async_resource(unsigned long han, void **cb, void **dsr); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci/* 1948c2ecf20Sopenharmony_ci * Unlock previous reserved async GRU resources 1958c2ecf20Sopenharmony_ci * 1968c2ecf20Sopenharmony_ci * input: 1978c2ecf20Sopenharmony_ci * han - handle to identify resources 1988c2ecf20Sopenharmony_ci */ 1998c2ecf20Sopenharmony_ciextern void gru_unlock_async_resource(unsigned long han); 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci#endif /* __GRU_KSERVICES_H_ */ 202