├── .gitignore ├── LICENSE ├── Makefile ├── Makefile.rules ├── Makefile.vars ├── README.md ├── libcxl.c ├── libcxl.h ├── libcxl_internal.h ├── libcxl_sysfs.c ├── man3 ├── Makefile ├── cxl.3 ├── cxl_adapter_afu_next.3 ├── cxl_adapter_dev_name.3 ├── cxl_adapter_free.3 ├── cxl_adapter_next.3 ├── cxl_afu_attach.3 ├── cxl_afu_attach_full.3 ├── cxl_afu_attach_work.3 ├── cxl_afu_dev_name.3 ├── cxl_afu_fd.3 ├── cxl_afu_fd_to_h.3 ├── cxl_afu_free.3 ├── cxl_afu_get_process_element.3 ├── cxl_afu_host_thread_wait.3 ├── cxl_afu_next.3 ├── cxl_afu_open_dev.3 ├── cxl_afu_open_h.3 ├── cxl_afu_opened.3 ├── cxl_afu_sysfs_pci.3 ├── cxl_errinfo_read.3 ├── cxl_errinfo_size.3 ├── cxl_event_pending.3 ├── cxl_for_each_adapter.3 ├── cxl_for_each_adapter_afu.3 ├── cxl_for_each_afu.3 ├── cxl_fprint_event.3 ├── cxl_fprint_unknown_event.3 ├── cxl_get_api_version.3 ├── cxl_get_api_version_compatible.3 ├── cxl_get_base_image.3 ├── cxl_get_caia_version.3 ├── cxl_get_cr_class.3 ├── cxl_get_cr_device.3 ├── cxl_get_cr_vendor.3 ├── cxl_get_image_loaded.3 ├── cxl_get_irqs_max.3 ├── cxl_get_irqs_min.3 ├── cxl_get_mmio_size.3 ├── cxl_get_mode.3 ├── cxl_get_modes_supported.3 ├── cxl_get_pp_mmio_len.3 ├── cxl_get_pp_mmio_off.3 ├── cxl_get_prefault_mode.3 ├── cxl_get_psl_revision.3 ├── cxl_get_psl_timebase_synced.3 ├── cxl_get_tunneled_ops_supported.3 ├── cxl_mmio_install_sigbus_handler.3 ├── cxl_mmio_map.3 ├── cxl_mmio_ptr.3 ├── cxl_mmio_read32.3 ├── cxl_mmio_read64.3 ├── cxl_mmio_unmap.3 ├── cxl_mmio_write32.3 ├── cxl_mmio_write64.3 ├── cxl_read_event.3 ├── cxl_read_expected_event.3 ├── cxl_set_irqs_max.3 ├── cxl_set_mode.3 ├── cxl_set_prefault_mode.3 ├── cxl_work_alloc.3 ├── cxl_work_disable_wait.3 ├── cxl_work_enable_wait.3 ├── cxl_work_free.3 ├── cxl_work_get_amr.3 ├── cxl_work_get_num_irqs.3 ├── cxl_work_get_tid.3 ├── cxl_work_get_wed.3 ├── cxl_work_set_amr.3 ├── cxl_work_set_num_irqs.3 ├── cxl_work_set_wed.3 ├── foldtbl └── man2txt └── symver.map /.gitignore: -------------------------------------------------------------------------------- 1 | *.d 2 | *.o 3 | *.so 4 | *.a 5 | *~ 6 | *.orig 7 | .*.swp 8 | include/misc/cxl.h 9 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | srcdir = $(PWD) 2 | include Makefile.vars 3 | 4 | OBJS = libcxl.o libcxl_sysfs.o 5 | CFLAGS += -I include 6 | 7 | # change VERS_LIB if new git tag 8 | VERS_LIB = 1.7 9 | LIBNAME = libcxl.so.$(VERS_LIB) 10 | # change VERS_SONAME only if library breaks backward compatibility. 11 | # refer to file symver.map 12 | VERS_SONAME=1 13 | LIBSONAME = libcxl.so.$(VERS_SONAME) 14 | SONAMEOPT = -Wl,-soname,$(LIBSONAME) 15 | 16 | all: check_cxl_header $(LIBSONAME) libcxl.so libcxl.a 17 | 18 | HAS_WGET = $(shell /bin/which wget > /dev/null 2>&1 && echo y || echo n) 19 | HAS_CURL = $(shell /bin/which curl > /dev/null 2>&1 && echo y || echo n) 20 | 21 | # Update this to test a single feature from the most recent header we require. 22 | # 23 | # Note that a backward-incompatible change in make 4.3 modified the 24 | # handling \# in a function invocation, so we define the test code in 25 | # a separate variable to work around it and keep consistent behavior 26 | # across all versions of make 27 | TEST_CODE = '\#include \nint i = CXL_START_WORK_TID;' 28 | CHECK_CXL_HEADER_IS_UP_TO_DATE = $(shell /bin/echo -e $(TEST_CODE) | \ 29 | $(CC) $(CFLAGS) -Werror -x c -S -o /dev/null - >/dev/null 2>&1 && echo y || echo n) 30 | 31 | check_cxl_header: 32 | ifeq (${CHECK_CXL_HEADER_IS_UP_TO_DATE},n) 33 | mkdir -p include/misc 34 | ifeq (${HAS_WGET},y) 35 | $(call Q,WGET include/misc/cxl.h, wget -O include/misc/cxl.h -q https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/misc/cxl.h) 36 | else ifeq (${HAS_CURL},y) 37 | $(call Q,CURL include/misc/cxl.h, curl -o include/misc/cxl.h -s https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/misc/cxl.h) 38 | else 39 | $(error 'cxl.h is non-existant or out of date, Download from https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/misc/cxl.h and place in ${PWD}/include/misc/cxl.h') 40 | endif 41 | endif 42 | 43 | libcxl.o libcxl_sysfs.o : CFLAGS += -fPIC 44 | 45 | libcxl.so: $(LIBNAME) 46 | ln -sf $(LIBNAME) libcxl.so 47 | 48 | $(LIBSONAME): $(LIBNAME) 49 | ln -sf $(LIBNAME) $(LIBSONAME) 50 | 51 | $(LIBNAME): libcxl.o libcxl_sysfs.o symver.map 52 | $(call Q,CC, $(CC) $(CFLAGS) $(LDFLAGS) -shared libcxl.o libcxl_sysfs.o -o $(LIBNAME), $(LIBNAME)) -Wl,--version-script symver.map $(SONAMEOPT) 53 | 54 | libcxl.a: libcxl.o libcxl_sysfs.o 55 | $(call Q,AR, ar rcs libcxl.a libcxl.o libcxl_sysfs.o, libcxl.a) 56 | 57 | include Makefile.rules 58 | 59 | clean: 60 | rm -f *.o *.d libcxl.so* libcxl.a include/misc/cxl.h 61 | 62 | install: all 63 | mkdir -p $(DESTDIR)$(libdir) 64 | mkdir -p $(DESTDIR)$(includedir) 65 | install -m 0755 $(LIBNAME) $(DESTDIR)$(libdir)/ 66 | cp -d libcxl.so $(LIBSONAME) $(DESTDIR)$(libdir)/ 67 | install -m 0644 libcxl.h $(DESTDIR)$(includedir)/ 68 | 69 | .PHONY: clean all install 70 | -------------------------------------------------------------------------------- /Makefile.rules: -------------------------------------------------------------------------------- 1 | # Basic makefile rules 2 | -include $(OBJS:.o=.d) 3 | 4 | ifdef V 5 | VERBOSE:= $(V) 6 | else 7 | VERBOSE:= 0 8 | endif 9 | 10 | ifeq ($(VERBOSE),1) 11 | define Q 12 | $(2) 13 | endef 14 | else 15 | define Q 16 | @/bin/echo -e " [$1]\t$(3)" 17 | @$(2) 18 | endef 19 | endif 20 | 21 | %.o : %.c 22 | $(call Q,CC, $(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<, $@) 23 | $(call Q,CC, $(CC) -MM $(CPPFLAGS) $(CFLAGS) $^ > $*.d, $*.d) 24 | $(call Q,SED, sed -i -e "s#^$(@F)#$@#" $*.d, $*.d) 25 | 26 | ifeq ($(BIT32),y) 27 | libdir = $(prefix)/lib 28 | else 29 | libdir = $(prefix)/lib64 30 | endif 31 | prefix = /usr/local/ 32 | datadir = $(prefix)/share 33 | includedir = $(prefix)/include 34 | mandir = $(datadir)/man 35 | -------------------------------------------------------------------------------- /Makefile.vars: -------------------------------------------------------------------------------- 1 | # Disable built-in rules 2 | MAKEFLAGS += -rR 3 | 4 | AS = $(CROSS_COMPILE)as 5 | LD = $(CROSS_COMPILE)ld 6 | CC = $(CROSS_COMPILE)gcc 7 | CFLAGS += -g -Wall -Werror -O2 -I$(CURDIR) 8 | ifeq ($(BIT32),y) 9 | CFLAGS += -m32 10 | else 11 | CFLAGS += -m64 12 | endif 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | libcxl 2 | ====== 3 | The coherent accelerator interface is designed to allow the coherent connection 4 | of accelerators (FPGAs and other devices) to a POWER system. Coherent in this 5 | context means that the accelerator and CPUs can both access system memory 6 | directly and with the same effective addresses. IBM refers to this as the 7 | Coherent Accelerator Processor Interface (CAPI). In the Linux world it is 8 | referred to by the name CXL to avoid confusion with the ISDN CAPI subsystem. 9 | 10 | The Linux kernel interacts with the device POWER Service Layer (PSL). Userland 11 | interacts with the device Accelerator Function Unit (AFU). See the Linux kernel 12 | source file [Documentation/powerpc/cxl.txt][1] for a detailed description of 13 | the coherent accelerator interface. 14 | 15 | The CXL library provides a userland API to coherently attached devices. CXL 16 | devices can be enumerated. Their capabilities can be queried. AFUs can be 17 | opened, attached to the current process, and started. Jobs, described by AFU 18 | specific Work Element Descriptors (WEDs), can be submitted and executed by 19 | AFUs. AFU MMIO space can be mapped into the current process memory, and AFUs 20 | can be configured and controlled via MMIO reads and writes. 21 | 22 | [1]: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/powerpc/cxl.rst 23 | -------------------------------------------------------------------------------- /libcxl.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014,2015 International Business Machines 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define _GNU_SOURCE /* For asprintf */ 18 | #define _DEFAULT_SOURCE 19 | #define __STDC_FORMAT_MACROS 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "libcxl.h" 43 | #include 44 | 45 | #include "libcxl_internal.h" 46 | 47 | #if defined CXL_START_WORK_TID 48 | #include 49 | #endif 50 | 51 | #undef DEBUG 52 | 53 | #ifdef DEBUG 54 | #define _s1(x) #x 55 | #define _s(x) _s1(x) 56 | #define pr_devel(...) \ 57 | fprintf(stderr, _s(__FILE__) ":" _s(__LINE__) ": " __VA_ARGS__ ); 58 | #define pr_here() \ 59 | pr_devel("<-- DEBUG TRACE -->\n"); 60 | #else 61 | #define pr_devel(...) do { } while (0); 62 | #define pr_here() do { } while (0); 63 | #endif 64 | 65 | #define CXL_EVENT_READ_FAIL 0xffff 66 | 67 | static struct cxl_adapter_h * malloc_adapter(void) 68 | { 69 | struct cxl_adapter_h *adapter; 70 | 71 | if (!(adapter = malloc(sizeof(struct cxl_adapter_h)))) 72 | return NULL; 73 | 74 | memset(adapter, 0, sizeof(struct cxl_adapter_h)); 75 | 76 | return adapter; 77 | } 78 | 79 | char * cxl_adapter_dev_name(struct cxl_adapter_h *adapter) 80 | { 81 | return adapter->enum_ent->d_name; 82 | } 83 | 84 | static struct cxl_afu_h * malloc_afu(void) 85 | { 86 | struct cxl_afu_h *afu; 87 | 88 | if (!(afu = malloc(sizeof(struct cxl_afu_h)))) 89 | return NULL; 90 | 91 | memset(afu, 0, sizeof(struct cxl_afu_h)); 92 | afu->fd = -1; 93 | afu->process_element = -1; 94 | afu->mmio_addr = NULL; 95 | afu->dev_name = NULL; 96 | afu->sysfs_path = NULL; 97 | afu->fd_errbuff = -1; 98 | afu->errbuff_size = -1; 99 | #if defined CXL_START_WORK_TID 100 | afu->pid = -1; 101 | #endif 102 | 103 | return afu; 104 | } 105 | 106 | char * cxl_afu_dev_name(struct cxl_afu_h *afu) 107 | { 108 | if (afu->enum_ent) 109 | return afu->enum_ent->d_name; 110 | return afu->dev_name; 111 | } 112 | 113 | int cxl_afu_fd(struct cxl_afu_h *afu) 114 | { 115 | return afu->fd; 116 | } 117 | 118 | 119 | /* 120 | * Adapter Enumeration 121 | */ 122 | 123 | static int is_cxl_adapter_filename(char *name) 124 | { 125 | int rc; 126 | regex_t preg; 127 | 128 | if (*name != 'c') 129 | return 0; 130 | 131 | if (regcomp(&preg, "^card[0-9]\\+$", REG_NOSUB)) 132 | return 0; 133 | rc = (regexec(&preg, name, 0, NULL, 0) != REG_NOMATCH); 134 | 135 | regfree(&preg); 136 | return rc; 137 | } 138 | 139 | static int is_cxl_afu_filename(char *name) 140 | { 141 | int rc; 142 | regex_t preg; 143 | 144 | if (*name != 'a') 145 | return 0; 146 | 147 | if (regcomp(&preg, "^afu[0-9]\\+\\.[0-9]\\+$", REG_NOSUB)) 148 | return 0; 149 | rc = (regexec(&preg, name, 0, NULL, 0) != REG_NOMATCH); 150 | 151 | regfree(&preg); 152 | return rc; 153 | } 154 | 155 | static int cxl_sysfs_adapter(char **bufp, struct cxl_adapter_h *adapter) 156 | { 157 | return asprintf(bufp, CXL_SYSFS_CLASS"/%s", 158 | cxl_adapter_dev_name(adapter)); 159 | } 160 | 161 | struct cxl_adapter_h * cxl_adapter_next(struct cxl_adapter_h *adapter) 162 | { 163 | if (adapter == NULL) { 164 | if (!(adapter = malloc_adapter())) 165 | return NULL; 166 | memset(adapter, 0, sizeof(struct cxl_adapter_h)); 167 | if (!(adapter->enum_dir = opendir(CXL_SYSFS_CLASS))) { 168 | if (errno == ENOENT) 169 | errno = ENODEV; 170 | goto end; 171 | } 172 | } 173 | errno = 0; 174 | do { 175 | if (!(adapter->enum_ent = readdir(adapter->enum_dir))) 176 | goto end; 177 | } while (!is_cxl_adapter_filename(adapter->enum_ent->d_name)); 178 | 179 | if (cxl_sysfs_adapter(&adapter->sysfs_path, adapter) == -1) 180 | goto end; 181 | 182 | return adapter; 183 | 184 | end: 185 | cxl_adapter_free(adapter); 186 | return NULL; 187 | } 188 | 189 | void cxl_adapter_free(struct cxl_adapter_h *adapter) 190 | { 191 | if (!adapter) 192 | return; 193 | if (adapter->enum_dir) 194 | closedir(adapter->enum_dir); 195 | if (adapter->sysfs_path) 196 | free(adapter->sysfs_path); 197 | free(adapter); 198 | } 199 | 200 | /* 201 | * AFU Enumeration 202 | */ 203 | 204 | static void _cxl_afu_free(struct cxl_afu_h *afu, int free_adapter) 205 | { 206 | if (!afu) 207 | return; 208 | if (afu->enum_dir) 209 | closedir(afu->enum_dir); 210 | if (afu->sysfs_path) 211 | free(afu->sysfs_path); 212 | if (free_adapter && afu->adapter) 213 | cxl_adapter_free(afu->adapter); 214 | if (afu->mmio_addr) 215 | cxl_mmio_unmap(afu); 216 | if (afu->fd != -1) 217 | close(afu->fd); 218 | if (afu->fd_errbuff != -1) 219 | close(afu->fd_errbuff); 220 | if (afu->dev_name) 221 | free(afu->dev_name); 222 | if (afu->event_buf) { 223 | free(afu->event_buf); 224 | afu->event_buf = NULL; 225 | } 226 | free(afu); 227 | } 228 | 229 | void cxl_afu_free(struct cxl_afu_h *afu) 230 | { 231 | _cxl_afu_free(afu, 1); 232 | } 233 | 234 | int cxl_afu_opened(struct cxl_afu_h *afu) 235 | { 236 | if (afu == NULL) { 237 | errno = EINVAL; 238 | return -1; 239 | } 240 | return (afu->fd != -1); 241 | } 242 | 243 | static int cxl_sysfs_fd(char **bufp, struct cxl_afu_h *afu) 244 | { 245 | struct cxl_afu_id afuid; 246 | char suffix = '\0'; 247 | int fd = cxl_afu_fd(afu); 248 | 249 | /* fetch the afu id via ioctl to the kernel driver */ 250 | if (ioctl(fd, CXL_IOCTL_GET_AFU_ID, &afuid) < 0) { 251 | struct stat sb; 252 | 253 | /* if the ioctl is not recognized, fallback to old method */ 254 | if ((errno != EINVAL) || (fstat(fd, &sb) < 0) || 255 | !S_ISCHR(sb.st_mode)) 256 | return -1; 257 | 258 | return asprintf(bufp, "/sys/dev/char/%i:%i", major(sb.st_rdev), 259 | minor(sb.st_rdev)); 260 | } 261 | 262 | switch (afuid.afu_mode) { 263 | case CXL_MODE_DEDICATED: 264 | suffix = 'd'; 265 | break; 266 | case CXL_MODE_DIRECTED: 267 | suffix = (afuid.flags & CXL_AFUID_FLAG_SLAVE) ? 's' : 'm'; 268 | break; 269 | default: 270 | errno = EINVAL; 271 | return -1; 272 | } 273 | 274 | return asprintf(bufp, "/sys/class/cxl/afu%i.%i%c", afuid.card_id, 275 | afuid.afu_offset, suffix); 276 | } 277 | 278 | static int cxl_afu_sysfs(struct cxl_afu_h *afu, char **bufp) 279 | { 280 | if (afu->fd >= 0) 281 | return cxl_sysfs_fd(bufp, afu); 282 | 283 | return asprintf(bufp, CXL_SYSFS_CLASS"/%s", cxl_afu_dev_name(afu)); 284 | } 285 | 286 | struct cxl_afu_h * 287 | cxl_adapter_afu_next(struct cxl_adapter_h *adapter, struct cxl_afu_h *afu) 288 | { 289 | char *dir_path; 290 | 291 | if (afu == NULL) { 292 | assert(adapter); 293 | if (!(afu = malloc_afu())) 294 | return NULL; 295 | if (cxl_sysfs_adapter(&dir_path, adapter) == -1) 296 | goto end; 297 | if (!(afu->enum_dir = opendir(dir_path))) 298 | goto err_free; 299 | } 300 | errno = 0; 301 | do { 302 | if (!(afu->enum_ent = readdir(afu->enum_dir))) 303 | goto end; 304 | } while (!is_cxl_afu_filename(afu->enum_ent->d_name)); 305 | if (cxl_afu_sysfs(afu, &afu->sysfs_path) == -1) 306 | goto err_free; 307 | return afu; 308 | 309 | err_free: 310 | free(dir_path); 311 | end: 312 | _cxl_afu_free(afu, 0); 313 | return NULL; 314 | } 315 | 316 | struct cxl_afu_h * cxl_afu_next(struct cxl_afu_h *afu) 317 | { 318 | struct cxl_adapter_h *adapter = NULL; 319 | 320 | if (afu) 321 | adapter = afu->adapter; 322 | else if (!(adapter = cxl_adapter_next(NULL))) 323 | return NULL; 324 | 325 | do { 326 | if ((afu = cxl_adapter_afu_next(adapter, afu))) 327 | afu->adapter = adapter; 328 | else 329 | adapter = cxl_adapter_next(adapter); 330 | } while (adapter && !afu); 331 | 332 | return afu; 333 | } 334 | 335 | static int sysfs_subsystem(char **bufp, const char *path) 336 | { 337 | char *subsystem_path, *name, *buf; 338 | char subsystem_link[256]; 339 | int len; 340 | int rc = -1; 341 | 342 | if ((asprintf(&subsystem_path, "%s/subsystem", path)) == -1) 343 | return -1; 344 | 345 | /* lstat returns sb.st_size == 0 for symlinks in /sys (WTF WHY???), so 346 | * we use a static buffer since we have NFI how large to allocate */ 347 | if ((len = readlink(subsystem_path, subsystem_link, sizeof(subsystem_link) - 1)) == -1) 348 | goto out; 349 | if (len >= sizeof(subsystem_link) - 1) 350 | goto out; 351 | subsystem_link[len] = '\0'; 352 | 353 | name = basename(subsystem_link); 354 | if (!(buf = malloc(strlen(name) + 1))) 355 | goto out; 356 | 357 | strcpy(buf, name); 358 | *bufp = buf; 359 | rc = 0; 360 | 361 | out: 362 | free(subsystem_path); 363 | return rc; 364 | } 365 | 366 | int cxl_afu_sysfs_pci(struct cxl_afu_h *afu, char **pathp) 367 | { 368 | char *path, *new_path, *subsys; 369 | struct stat sb; 370 | 371 | if (afu == NULL || pathp == NULL) { 372 | errno = EINVAL; 373 | return -1; 374 | } 375 | if ((path = strdup(afu->sysfs_path)) == NULL) 376 | return -1; 377 | 378 | do { 379 | if ((asprintf(&new_path, "%s/device", path)) == -1) 380 | goto err; 381 | free(path); 382 | path = new_path; 383 | 384 | if ((sysfs_subsystem(&subsys, path)) == -1) { 385 | if (errno == ENOENT) 386 | continue; 387 | goto err; 388 | } 389 | if (!(strcmp(subsys, "pci"))) { 390 | free(subsys); 391 | *pathp = path; 392 | return 0; 393 | } 394 | free(subsys); 395 | } while (stat(path, &sb) != -1); 396 | 397 | err: 398 | free(path); 399 | return -1; 400 | } 401 | 402 | static int major_minor_match(int dirfd, char *dev_name, int major, int minor) 403 | { 404 | struct stat sb; 405 | 406 | if (fstatat(dirfd, dev_name, &sb, 0) == -1) 407 | return 0; 408 | if (!S_ISCHR(sb.st_mode)) 409 | return 0; 410 | return major(sb.st_rdev) == major && minor(sb.st_rdev) == minor; 411 | } 412 | 413 | static char *find_dev_name(int major, int minor) 414 | { 415 | int saved_errno; 416 | DIR *enum_dir; 417 | struct dirent *enum_ent; 418 | int fd; 419 | char *dev_name = NULL; 420 | 421 | if ((enum_dir = opendir(CXL_DEV_DIR)) == NULL) 422 | return NULL; 423 | fd = dirfd(enum_dir); 424 | saved_errno = errno; 425 | errno = 0; 426 | do { 427 | if (!(enum_ent = readdir(enum_dir))) { 428 | if (errno == 0) 429 | errno = saved_errno; 430 | goto err_exit; 431 | } 432 | } while (!major_minor_match(fd, enum_ent->d_name, major, minor)); 433 | 434 | if ((dev_name = strdup(enum_ent->d_name)) == NULL) 435 | goto err_exit; 436 | closedir(enum_dir); 437 | return dev_name; 438 | 439 | err_exit: 440 | closedir(enum_dir); 441 | return NULL; 442 | } 443 | 444 | int cxl_afu_get_process_element(struct cxl_afu_h *afu) 445 | { 446 | int process_element; 447 | int rc; 448 | 449 | if (afu == NULL) { 450 | errno = EINVAL; 451 | return -1; 452 | } 453 | if (afu->process_element >= 0) 454 | /* return cached version */ 455 | return afu->process_element; 456 | 457 | rc = ioctl(afu->fd, CXL_IOCTL_GET_PROCESS_ELEMENT, &process_element); 458 | if (rc < 0) 459 | return rc; 460 | afu->process_element = process_element; 461 | 462 | return process_element; 463 | } 464 | 465 | /* Open Functions */ 466 | 467 | static int open_afu_dev(struct cxl_afu_h *afu, char *path) 468 | { 469 | struct stat sb; 470 | long api_version; 471 | int fd; 472 | 473 | if ((fd = open(path, O_RDWR | O_CLOEXEC)) < 0) 474 | return fd; 475 | afu->fd = fd; 476 | /* Verify that this is an AFU file we just opened */ 477 | if (fstat(fd, &sb) < 0) 478 | goto err; 479 | if (!S_ISCHR(sb.st_mode)) 480 | goto err; 481 | if (!(afu->dev_name = find_dev_name(major(sb.st_rdev), 482 | minor(sb.st_rdev)))) 483 | goto err; 484 | if (! afu->sysfs_path) 485 | if (cxl_afu_sysfs(afu, &afu->sysfs_path) == -1) 486 | goto err; 487 | if (cxl_get_api_version_compatible(afu, &api_version)) 488 | goto err; 489 | if (api_version > CXL_KERNEL_API_VERSION) { 490 | errno = EPROTO; 491 | goto err_close; 492 | } 493 | return 0; 494 | 495 | err: 496 | errno = ENODEV; 497 | err_close: 498 | if (afu->dev_name) 499 | free(afu->dev_name); 500 | close(fd); 501 | afu->fd = -1; 502 | return -1; 503 | } 504 | 505 | struct cxl_afu_h * cxl_afu_open_dev(char *path) 506 | { 507 | struct cxl_afu_h *afu; 508 | 509 | if (!(afu = malloc_afu())) 510 | return NULL; 511 | 512 | if (open_afu_dev(afu, path) < 0) 513 | goto err; 514 | return afu; 515 | err: 516 | cxl_afu_free(afu); 517 | return NULL; 518 | } 519 | 520 | static char *new_sysfs_path(char *sysfs_path, enum cxl_views view) 521 | { 522 | char lastchar; 523 | char *newpath; 524 | 525 | switch (view) { 526 | case CXL_VIEW_DEDICATED: 527 | lastchar = 'd'; 528 | break; 529 | case CXL_VIEW_MASTER: 530 | lastchar = 'm'; 531 | break; 532 | case CXL_VIEW_SLAVE: 533 | lastchar = 's'; 534 | break; 535 | default: 536 | return NULL; 537 | } 538 | switch (*(sysfs_path + strlen(sysfs_path) - 1)) { 539 | case 'd': 540 | case 'm': 541 | case 's': 542 | if ((newpath = strdup(sysfs_path)) == NULL) 543 | return NULL; 544 | *(newpath + strlen(newpath) - 1) = lastchar; 545 | break; 546 | default: 547 | if (asprintf(&newpath, "%s%c", sysfs_path, lastchar) == -1) 548 | return NULL; 549 | } 550 | return newpath; 551 | } 552 | 553 | struct cxl_afu_h * cxl_afu_open_h(struct cxl_afu_h *afu, enum cxl_views view) 554 | { 555 | char *dev_name = NULL; 556 | char *dev_path = NULL; 557 | struct cxl_afu_h *new_afu = NULL; 558 | long sysfs_major, sysfs_minor; 559 | 560 | if (!(new_afu = malloc_afu())) 561 | goto err_pass; 562 | if (!(new_afu->sysfs_path = new_sysfs_path(afu->sysfs_path, view))) 563 | goto err_pass; 564 | if (cxl_get_dev(new_afu, &sysfs_major, &sysfs_minor) < 0) 565 | goto err_exit; 566 | if (!(dev_name = find_dev_name(sysfs_major, sysfs_minor))) 567 | goto err_exit; 568 | if (asprintf(&dev_path, CXL_DEV_DIR"/%s", dev_name) == -1) 569 | goto err_pass; 570 | if (open_afu_dev(new_afu, dev_path) < 0) 571 | goto err_pass; 572 | free(dev_name); 573 | free(dev_path); 574 | return new_afu; 575 | 576 | err_exit: 577 | errno = ENODEV; 578 | err_pass: 579 | if (dev_name) 580 | free(dev_name); 581 | if (dev_path) 582 | free(dev_path); 583 | if (new_afu) 584 | free(new_afu); 585 | return NULL; 586 | } 587 | 588 | struct cxl_afu_h * cxl_afu_fd_to_h(int fd) 589 | { 590 | struct cxl_afu_h *afu; 591 | struct stat sb; 592 | long api_version; 593 | 594 | if (!(afu = malloc_afu())) 595 | return NULL; 596 | /* Verify that the passed in fd is an AFU fd */ 597 | if (fstat(fd, &sb) < 0) 598 | goto err_exit; 599 | afu->fd = fd; 600 | 601 | if (S_ISCHR(sb.st_mode)) { 602 | afu->dev_name = find_dev_name(major(sb.st_rdev), minor(sb.st_rdev)); 603 | if (!afu->dev_name) 604 | goto enodev; 605 | } else { 606 | /* Could be an anonymous inode - see if the get_afu_id ioctl succeeds */ 607 | afu->dev_name = NULL; 608 | } 609 | 610 | if (cxl_afu_sysfs(afu, &afu->sysfs_path) == -1) 611 | goto err_exit; 612 | if (cxl_get_api_version_compatible(afu, &api_version)) 613 | goto err_exit; 614 | if (api_version > CXL_KERNEL_API_VERSION) { 615 | errno = EPROTO; 616 | goto err_exit; 617 | } 618 | return afu; 619 | 620 | enodev: 621 | errno = ENODEV; 622 | err_exit: 623 | free(afu); 624 | return NULL; 625 | } 626 | 627 | int cxl_afu_attach(struct cxl_afu_h *afu, __u64 wed) 628 | { 629 | struct cxl_ioctl_start_work work; 630 | 631 | if (afu == NULL || afu->fd < 0) { 632 | errno = EINVAL; 633 | return -1; 634 | } 635 | #if defined CXL_START_WORK_TID 636 | /* get the internal kernel "pid" of the Thread ID */ 637 | afu->pid = syscall(SYS_gettid); 638 | #endif 639 | 640 | memset(&work, 0, sizeof(work)); 641 | work.work_element_descriptor = wed; 642 | 643 | return ioctl(afu->fd, CXL_IOCTL_START_WORK, &work); 644 | } 645 | 646 | int cxl_afu_attach_full(struct cxl_afu_h *afu, __u64 wed, __u16 num_interrupts, 647 | __u64 amr) 648 | { 649 | struct cxl_ioctl_start_work work; 650 | 651 | if (afu == NULL || afu->fd < 0) { 652 | errno = EINVAL; 653 | return -1; 654 | } 655 | #if defined CXL_START_WORK_TID 656 | /* get the internal kernel "pid" of the Thread ID */ 657 | afu->pid = syscall(SYS_gettid); 658 | #endif 659 | 660 | memset(&work, 0, sizeof(work)); 661 | work.work_element_descriptor = wed; 662 | work.flags = CXL_START_WORK_NUM_IRQS | CXL_START_WORK_AMR; 663 | work.num_interrupts = num_interrupts; 664 | work.amr = amr; 665 | 666 | return ioctl(afu->fd, CXL_IOCTL_START_WORK, &work); 667 | } 668 | 669 | inline 670 | int cxl_afu_attach_work(struct cxl_afu_h *afu, 671 | struct cxl_ioctl_start_work *work) 672 | { 673 | if (afu == NULL || afu->fd < 0 || work == NULL) { 674 | errno = EINVAL; 675 | return -1; 676 | } 677 | #if defined CXL_START_WORK_TID 678 | /* get the internal kernel "pid" of the Thread ID */ 679 | afu->pid = syscall(SYS_gettid); 680 | #endif 681 | 682 | return ioctl(afu->fd, CXL_IOCTL_START_WORK, work); 683 | } 684 | 685 | inline 686 | struct cxl_ioctl_start_work *cxl_work_alloc(void) 687 | { 688 | return calloc(1, sizeof(struct cxl_ioctl_start_work)); 689 | } 690 | 691 | inline 692 | int cxl_work_free(struct cxl_ioctl_start_work *work) 693 | { 694 | if (work == NULL) { 695 | errno = EINVAL; 696 | return -1; 697 | } 698 | free(work); 699 | return 0; 700 | } 701 | 702 | inline 703 | int cxl_work_get_amr(struct cxl_ioctl_start_work *work, __u64 *valp) 704 | { 705 | if (work == NULL) { 706 | errno = EINVAL; 707 | return -1; 708 | } 709 | *valp = work->amr; 710 | return 0; 711 | } 712 | 713 | inline 714 | int cxl_work_get_num_irqs(struct cxl_ioctl_start_work *work, __s16 *valp) 715 | { 716 | if (work == NULL) { 717 | errno = EINVAL; 718 | return -1; 719 | } 720 | *valp = work->num_interrupts; 721 | return 0; 722 | } 723 | 724 | inline 725 | int cxl_work_get_wed(struct cxl_ioctl_start_work *work, __u64 *valp) 726 | { 727 | if (work == NULL) { 728 | errno = EINVAL; 729 | return -1; 730 | } 731 | *valp = work->work_element_descriptor; 732 | return 0; 733 | } 734 | 735 | #if defined CXL_START_WORK_TID 736 | inline 737 | int cxl_work_get_tid(struct cxl_ioctl_start_work *work, __u16 *valp) 738 | { 739 | if (work == NULL || work->tid == -1) { 740 | errno = EINVAL; 741 | return -1; 742 | } 743 | *valp = work->tid; 744 | return 0; 745 | } 746 | #endif 747 | 748 | inline 749 | int cxl_work_set_amr(struct cxl_ioctl_start_work *work, __u64 amr) 750 | { 751 | if (work == NULL) { 752 | errno = EINVAL; 753 | return -1; 754 | } 755 | work->amr = amr; 756 | if (amr) 757 | work->flags |= CXL_START_WORK_AMR; 758 | else 759 | work->flags &= ~(CXL_START_WORK_AMR); 760 | return 0; 761 | } 762 | 763 | inline 764 | int cxl_work_set_num_irqs(struct cxl_ioctl_start_work *work, __s16 irqs) 765 | { 766 | if (work == NULL) { 767 | errno = EINVAL; 768 | return -1; 769 | } 770 | work->num_interrupts = irqs; 771 | if (irqs >= 0) 772 | work->flags |= CXL_START_WORK_NUM_IRQS; 773 | else 774 | work->flags &= ~(CXL_START_WORK_NUM_IRQS); 775 | return 0; 776 | } 777 | 778 | inline 779 | int cxl_work_set_wed(struct cxl_ioctl_start_work *work, __u64 wed) 780 | { 781 | if (work == NULL) { 782 | errno = EINVAL; 783 | return -1; 784 | } 785 | work->work_element_descriptor = wed; 786 | return 0; 787 | } 788 | 789 | #if defined CXL_START_WORK_TID 790 | inline 791 | int cxl_work_enable_wait(struct cxl_ioctl_start_work *work) 792 | { 793 | if (work == NULL) { 794 | errno = EINVAL; 795 | return -1; 796 | } 797 | work->flags |= CXL_START_WORK_TID; 798 | return 0; 799 | } 800 | 801 | inline 802 | int cxl_work_disable_wait(struct cxl_ioctl_start_work *work) 803 | { 804 | if (work == NULL) { 805 | errno = EINVAL; 806 | return -1; 807 | } 808 | work->flags &= ~(CXL_START_WORK_TID); 809 | return 0; 810 | } 811 | #endif 812 | 813 | /* 814 | * Event description print helpers 815 | */ 816 | 817 | static int 818 | cxl_fprint_afu_interrupt(FILE *stream, struct cxl_event_afu_interrupt *event) 819 | { 820 | return fprintf(stream, "AFU Interrupt %i\n", event->irq); 821 | } 822 | 823 | static int 824 | cxl_fprint_data_storage(FILE *stream, struct cxl_event_data_storage *event) 825 | { 826 | return fprintf(stream, "AFU Invalid memory reference: 0x%"PRIx64"\n", 827 | (uint64_t) event->addr); 828 | } 829 | 830 | static int 831 | cxl_fprint_afu_error(FILE *stream, struct cxl_event_afu_error *event) 832 | { 833 | return fprintf(stream, "AFU Error: 0x%"PRIx64"\n", 834 | (uint64_t) event->error); 835 | } 836 | 837 | static int hexdump(FILE *stream, __u8 *addr, ssize_t size) 838 | { 839 | unsigned i, j, c = 0; 840 | 841 | for (i = 0; i < size; i += 4) { 842 | for (j = i; j < size && j < i + 4; j++) 843 | c += fprintf(stream, "%.2x", addr[j]); 844 | c += fprintf(stream, " "); 845 | } 846 | c += fprintf(stream, "\n"); 847 | return c; 848 | } 849 | 850 | int 851 | cxl_fprint_unknown_event(FILE *stream, struct cxl_event *event) 852 | { 853 | int ret; 854 | 855 | if (!event) { 856 | errno = EINVAL; 857 | return -1; 858 | } 859 | ret = fprintf(stream, "CXL Unknown Event %i: ", event->header.type); 860 | if (ret < 0) 861 | return ret; 862 | ret += hexdump(stream, (__u8 *)event, event->header.size); 863 | return ret; 864 | } 865 | 866 | /* 867 | * Print a description of the given event to the file stream. 868 | */ 869 | int 870 | cxl_fprint_event(FILE *stream, struct cxl_event *event) 871 | { 872 | if (!event) { 873 | errno = EINVAL; 874 | return -1; 875 | } 876 | switch (event->header.type) { 877 | case CXL_EVENT_READ_FAIL: 878 | fprintf(stderr, "cxl_fprint_event: CXL Read failed\n"); 879 | errno = ENODATA; 880 | return -1; 881 | case CXL_EVENT_AFU_INTERRUPT: 882 | return cxl_fprint_afu_interrupt(stream, &event->irq); 883 | case CXL_EVENT_DATA_STORAGE: 884 | return cxl_fprint_data_storage(stream, &event->fault); 885 | case CXL_EVENT_AFU_ERROR: 886 | return cxl_fprint_afu_error(stream, &event->afu_error); 887 | default: 888 | return cxl_fprint_unknown_event(stream, event); 889 | } 890 | } 891 | 892 | static inline void poison(__u8 *ptr, ssize_t len) 893 | { 894 | unsigned int toxin = 0xDEADBEEF; 895 | __u8 *end; 896 | 897 | for (end = ptr + len; ptr < end; ptr++) 898 | *ptr = (toxin >> (8 * (3 - ((uintptr_t)ptr % 4)))) & 0xff; 899 | } 900 | 901 | static inline int fetch_cached_event(struct cxl_afu_h *afu, 902 | struct cxl_event *event) 903 | { 904 | int size; 905 | 906 | /* Local events caches, let's send it out */ 907 | size = afu->event_buf_first->header.size; 908 | memcpy(event, afu->event_buf_first, size); 909 | afu->event_buf_first = (struct cxl_event *) 910 | ((char *)afu->event_buf_first + size); 911 | assert(afu->event_buf_first <= afu->event_buf_end); 912 | return 0; 913 | } 914 | 915 | static int event_cached(struct cxl_afu_h *afu) 916 | { 917 | return afu->event_buf_first != afu->event_buf_end; 918 | } 919 | 920 | int cxl_event_pending(struct cxl_afu_h *afu) 921 | { 922 | struct pollfd fds[1] = {{cxl_afu_fd(afu), POLLIN, 0}}; 923 | 924 | if (afu == NULL) { 925 | errno = EINVAL; 926 | return -1; 927 | } 928 | if (event_cached(afu)) 929 | return 1; 930 | 931 | return poll(fds, 1, 0); 932 | } 933 | 934 | int cxl_read_event(struct cxl_afu_h *afu, struct cxl_event *event) 935 | { 936 | struct cxl_event *p = NULL; 937 | ssize_t size; 938 | int rc = 0; 939 | 940 | if (afu == NULL || event == NULL) { 941 | errno = EINVAL; 942 | return -1; 943 | } 944 | /* Init buffer */ 945 | if (!afu->event_buf) { 946 | p = malloc(CXL_READ_MIN_SIZE); 947 | if (!p) { 948 | errno = ENOMEM; 949 | return -1; 950 | } 951 | afu->event_buf = p; 952 | afu->event_buf_first = afu->event_buf; 953 | afu->event_buf_end = afu->event_buf; 954 | } 955 | 956 | /* Send buffered event */ 957 | if (event_cached(afu)) { 958 | rc = fetch_cached_event(afu, event); 959 | return rc; 960 | } 961 | 962 | if (afu->fd < 0) { 963 | errno = EINVAL; 964 | return -1; 965 | } 966 | 967 | /* Looks like we need to go read some data from the kernel */ 968 | size = read(afu->fd, afu->event_buf, CXL_READ_MIN_SIZE); 969 | if (size <= 0) { 970 | poison((__u8 *)event, sizeof(*event)); 971 | event->header.type = CXL_EVENT_READ_FAIL; 972 | event->header.size = 0; 973 | if (size < 0) 974 | return size; 975 | errno = ENODATA; 976 | return -1; 977 | } 978 | 979 | /* check for at least 1 event */ 980 | assert(size >= afu->event_buf->header.size); 981 | 982 | afu->event_buf_first = afu->event_buf; 983 | afu->event_buf_end = (struct cxl_event *) 984 | ((char *)afu->event_buf + size); 985 | 986 | return fetch_cached_event(afu, event); 987 | } 988 | 989 | /* 990 | * Read an event from the AFU when an event of type is expected. For AFU 991 | * interrupts, the expected AFU interrupt number may also be supplied (0 will 992 | * accept any AFU interrupt). 993 | * 994 | * Returns 0 if the read event was of the expected type and (if applicable) 995 | * AFU interrupt number. If the event did not match the type & interrupt 996 | * number, it returns -1. 997 | * 998 | * If the read() syscall failed for some reason (e.g. no event pending when 999 | * using non-blocking IO, etc) it will return -2 and errno will be set 1000 | * appropriately. 1001 | */ 1002 | int cxl_read_expected_event(struct cxl_afu_h *afu, struct cxl_event *event, 1003 | __u32 type, __u16 irq) 1004 | { 1005 | int rv; 1006 | 1007 | if ((rv = cxl_read_event(afu, event)) < 0) 1008 | return rv; 1009 | 1010 | #if 0 1011 | printf("cxl_read_expected_event: Poisoning %li bytes from %p, event: %p, size: %li, rv: %i\n", 1012 | size - rv, (void*)(((__u8 *)event) + rv), (void*)event, size, rv); 1013 | hexdump(stderr, (__u8 *)event, size); 1014 | #endif 1015 | 1016 | if (event->header.type != type) 1017 | return -1; 1018 | 1019 | if ((type == CXL_EVENT_AFU_INTERRUPT) && irq) { 1020 | if (!(event->irq.irq == irq)) 1021 | return -1; 1022 | } 1023 | 1024 | return 0; 1025 | } 1026 | 1027 | /* Userspace MMIO functions */ 1028 | 1029 | int cxl_mmio_map(struct cxl_afu_h *afu, __u32 flags) 1030 | { 1031 | void *addr; 1032 | long size; 1033 | 1034 | if (afu == NULL) { 1035 | errno = EINVAL; 1036 | return -1; 1037 | } 1038 | if (flags & ~(CXL_MMIO_FLAGS)) 1039 | goto err; 1040 | if (!cxl_afu_opened(afu)) 1041 | goto err; 1042 | if (cxl_get_mmio_size(afu, &size) < 0) 1043 | return -1; 1044 | 1045 | afu->mmio_size = (size_t)size; 1046 | addr = mmap(NULL, afu->mmio_size, PROT_READ|PROT_WRITE, MAP_SHARED, 1047 | afu->fd, 0); 1048 | if (addr == MAP_FAILED) 1049 | return -1; 1050 | 1051 | afu->mmio_flags = flags; 1052 | afu->mmio_addr = addr; 1053 | return 0; 1054 | err: 1055 | errno = ENODEV; 1056 | return -1; 1057 | } 1058 | 1059 | int cxl_mmio_unmap(struct cxl_afu_h *afu) 1060 | { 1061 | if (!afu || !afu->mmio_addr) { 1062 | errno = EINVAL; 1063 | return -1; 1064 | } 1065 | if (munmap(afu->mmio_addr, afu->mmio_size)) 1066 | return -1; 1067 | 1068 | afu->mmio_addr = NULL; 1069 | return 0; 1070 | } 1071 | 1072 | int cxl_mmio_ptr(struct cxl_afu_h *afu, void **mmio_ptrp) 1073 | { 1074 | if (afu == NULL || afu->mmio_addr == NULL) { 1075 | errno = EINVAL; 1076 | return -1; 1077 | } 1078 | *mmio_ptrp = afu->mmio_addr; 1079 | return 0; 1080 | } 1081 | 1082 | static int cxl_sigbus_handler_installed; 1083 | static struct sigaction cxl_sigbus_old_action; 1084 | static __thread jmp_buf cxl_sigbus_env; 1085 | static __thread int cxl_sigbus_jmp_enabled; 1086 | 1087 | static inline int cxl_mmio_try(void) 1088 | { 1089 | int ret; 1090 | 1091 | if (!cxl_sigbus_handler_installed) 1092 | return 0; 1093 | 1094 | ret = sigsetjmp(cxl_sigbus_env, 1); 1095 | if (!ret) 1096 | cxl_sigbus_jmp_enabled = 1; 1097 | 1098 | return ret; 1099 | } 1100 | 1101 | static inline void cxl_mmio_success(void) 1102 | { 1103 | cxl_sigbus_jmp_enabled = 0; 1104 | } 1105 | 1106 | #ifdef __PPC64__ 1107 | 1108 | static inline void _cxl_mmio_write64(struct cxl_afu_h *afu, uint64_t offset, uint64_t data) 1109 | { 1110 | __asm__ __volatile__("sync ; std%U0%X0 %1,%0" 1111 | : "=m"(*(__u64 *)(afu->mmio_addr + offset)) 1112 | : "r"(data)); 1113 | } 1114 | 1115 | static inline uint64_t _cxl_mmio_read64(struct cxl_afu_h *afu, uint64_t offset) 1116 | { 1117 | uint64_t d; 1118 | 1119 | __asm__ __volatile__("ld%U1%X1 %0,%1; sync" 1120 | : "=r"(d) 1121 | : "m"(*(__u64 *)(afu->mmio_addr + offset))); 1122 | return d; 1123 | } 1124 | 1125 | #else /* __PPC64__ */ 1126 | 1127 | static inline void _cxl_mmio_write64(struct cxl_afu_h *afu, uint64_t offset, uint64_t data) 1128 | { 1129 | uint32_t d32; 1130 | 1131 | d32 = (data >> 32); 1132 | __asm__ __volatile__("sync ; stw%U0%X0 %1,%0" 1133 | : "=m"(*(__u64 *)(afu->mmio_addr + offset)) 1134 | : "r"(d32)); 1135 | d32 = data; 1136 | __asm__ __volatile__("sync ; stw%U0%X0 %1,%0" 1137 | : "=m"(*(__u64 *)(afu->mmio_addr + offset + 4)) 1138 | : "r"(d32)); 1139 | } 1140 | 1141 | static inline uint64_t _cxl_mmio_read64(struct cxl_afu_h *afu, uint64_t offset) 1142 | { 1143 | uint64_t d; 1144 | uint32_t d32; 1145 | 1146 | __asm__ __volatile__("lwz%U1%X1 %0,%1; sync" 1147 | : "=r"(d32) 1148 | : "m"(*(__u64 *)(afu->mmio_addr + offset))); 1149 | d = d32; 1150 | __asm__ __volatile__("lwz%U1%X1 %0,%1; sync" 1151 | : "=r"(d32) 1152 | : "m"(*(__u64 *)(afu->mmio_addr + offset + 4))); 1153 | 1154 | return (d << 32) | d32; 1155 | } 1156 | 1157 | #endif /* __PPC64__ */ 1158 | 1159 | static inline void _cxl_mmio_write32(struct cxl_afu_h *afu, uint64_t offset, uint32_t data) 1160 | { 1161 | __asm__ __volatile__("sync ; stw%U0%X0 %1,%0" 1162 | : "=m"(*(__u64 *)(afu->mmio_addr + offset)) 1163 | : "r"(data)); 1164 | } 1165 | 1166 | static inline uint32_t _cxl_mmio_read32(struct cxl_afu_h *afu, uint64_t offset) 1167 | { 1168 | uint32_t d; 1169 | 1170 | __asm__ __volatile__("lwz%U1%X1 %0,%1; sync" 1171 | : "=r"(d) 1172 | : "m"(*(__u64 *)(afu->mmio_addr + offset))); 1173 | return d; 1174 | } 1175 | 1176 | int cxl_mmio_write64(struct cxl_afu_h *afu, uint64_t offset, uint64_t data) 1177 | { 1178 | if (!afu || !afu->mmio_addr) 1179 | goto out; 1180 | if (offset >= afu->mmio_size) 1181 | goto out; 1182 | if (offset & 0x7) 1183 | goto out; 1184 | 1185 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_LITTLE_ENDIAN) 1186 | data = htole64(data); 1187 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_BIG_ENDIAN) 1188 | data = htobe64(data); 1189 | 1190 | if (cxl_mmio_try()) 1191 | goto fail; 1192 | _cxl_mmio_write64(afu, offset, data); 1193 | cxl_mmio_success(); 1194 | 1195 | return 0; 1196 | 1197 | out: 1198 | errno = EINVAL; 1199 | return -1; 1200 | fail: 1201 | if (!cxl_sigbus_handler_installed) { 1202 | /* TODO: use pthread_sigqueue / sigqueue / rt_tgsigqueueinfo to 1203 | * pass the faulting address */ 1204 | raise(SIGBUS); 1205 | } 1206 | 1207 | errno = EIO; 1208 | return -1; 1209 | } 1210 | 1211 | int cxl_mmio_read64(struct cxl_afu_h *afu, uint64_t offset, uint64_t *data) 1212 | { 1213 | uint64_t d; 1214 | 1215 | if (!afu || !afu->mmio_addr) 1216 | goto out; 1217 | if (offset >= afu->mmio_size) 1218 | goto out; 1219 | if (offset & 0x7) 1220 | goto out; 1221 | 1222 | if (cxl_mmio_try()) 1223 | goto fail; 1224 | d = _cxl_mmio_read64(afu, offset); 1225 | cxl_mmio_success(); 1226 | 1227 | if (d == 0xffffffffffffffffull) 1228 | goto fail; 1229 | 1230 | *data = d; 1231 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_LITTLE_ENDIAN) 1232 | *data = le64toh(d); 1233 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_BIG_ENDIAN) 1234 | *data = be64toh(d); 1235 | return 0; 1236 | 1237 | out: 1238 | errno = EINVAL; 1239 | return -1; 1240 | 1241 | fail: 1242 | if (!cxl_sigbus_handler_installed) { 1243 | /* TODO: use pthread_sigqueue / sigqueue / rt_tgsigqueueinfo to 1244 | * pass the faulting address */ 1245 | raise(SIGBUS); 1246 | } 1247 | 1248 | *data = 0xffffffffffffffffull; 1249 | errno = EIO; 1250 | return -1; 1251 | } 1252 | 1253 | int cxl_mmio_write32(struct cxl_afu_h *afu, uint64_t offset, uint32_t data) 1254 | { 1255 | if (!afu || !afu->mmio_addr) 1256 | goto out; 1257 | if (offset >= afu->mmio_size) 1258 | goto out; 1259 | if (offset & 0x3) 1260 | goto out; 1261 | 1262 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_LITTLE_ENDIAN) 1263 | data = htole32(data); 1264 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_BIG_ENDIAN) 1265 | data = htobe32(data); 1266 | 1267 | if (cxl_mmio_try()) 1268 | goto fail; 1269 | _cxl_mmio_write32(afu, offset, data); 1270 | cxl_mmio_success(); 1271 | 1272 | return 0; 1273 | 1274 | out: 1275 | errno = EINVAL; 1276 | return -1; 1277 | fail: 1278 | if (!cxl_sigbus_handler_installed) { 1279 | /* TODO: use pthread_sigqueue / sigqueue / rt_tgsigqueueinfo to 1280 | * pass the faulting address */ 1281 | raise(SIGBUS); 1282 | } 1283 | 1284 | errno = EIO; 1285 | return -1; 1286 | 1287 | } 1288 | 1289 | int cxl_mmio_read32(struct cxl_afu_h *afu, uint64_t offset, uint32_t *data) 1290 | { 1291 | uint32_t d; 1292 | 1293 | if (!afu || !afu->mmio_addr) 1294 | goto out; 1295 | if (offset >= afu->mmio_size) 1296 | goto out; 1297 | if (offset & 0x3) 1298 | goto out; 1299 | 1300 | if (cxl_mmio_try()) 1301 | goto fail; 1302 | d = _cxl_mmio_read32(afu, offset); 1303 | cxl_mmio_success(); 1304 | 1305 | if (d == 0xffffffff) 1306 | goto fail; 1307 | 1308 | *data = d; 1309 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_LITTLE_ENDIAN) 1310 | *data = le32toh(d); 1311 | if ((afu->mmio_flags & CXL_MMIO_ENDIAN_MASK) == CXL_MMIO_BIG_ENDIAN) 1312 | *data = be32toh(d); 1313 | return 0; 1314 | 1315 | out: 1316 | errno = EINVAL; 1317 | return -1; 1318 | fail: 1319 | if (!cxl_sigbus_handler_installed) { 1320 | /* TODO: use pthread_sigqueue / sigqueue / rt_tgsigqueueinfo to 1321 | * pass the faulting address */ 1322 | raise(SIGBUS); 1323 | } 1324 | 1325 | *data = 0xffffffff; 1326 | errno = EIO; 1327 | return -1; 1328 | } 1329 | 1330 | static void cxl_sigbus_action(int sig, siginfo_t *info, void *context) 1331 | { 1332 | if (info->si_code == BUS_ADRERR && cxl_sigbus_jmp_enabled) { 1333 | /* fprintf(stderr, "libcxl: SIGBUS handler caught bad access to %p\n", info->si_addr); */ 1334 | siglongjmp(cxl_sigbus_env, 1); 1335 | } 1336 | 1337 | if (cxl_sigbus_old_action.sa_handler == SIG_IGN) { 1338 | /* fprintf(stderr, "libcxl: Ignoring SIGBUS\n"); */ 1339 | return; 1340 | } 1341 | 1342 | if (cxl_sigbus_old_action.sa_handler == SIG_DFL) { 1343 | /* fprintf(stderr, "libcxl: Raising default SIGBUS handler\n"); */ 1344 | sigaction(SIGBUS, &cxl_sigbus_old_action, NULL); 1345 | raise(SIGBUS); 1346 | } 1347 | 1348 | /* 1349 | * Chain to any other installed SIGBUS handlers. Do this after checking 1350 | * valid values of sa_handler as the two are stored as a union. 1351 | */ 1352 | if (cxl_sigbus_old_action.sa_sigaction) { 1353 | /* fprintf(stderr, "libcxl: Calling chained SIGBUS handler\n"); */ 1354 | cxl_sigbus_old_action.sa_sigaction(sig, info, context); 1355 | } 1356 | } 1357 | 1358 | int cxl_mmio_install_sigbus_handler(void) 1359 | { 1360 | struct sigaction act; 1361 | 1362 | if (cxl_sigbus_handler_installed) 1363 | return 0; 1364 | cxl_sigbus_handler_installed = 1; 1365 | 1366 | memset(&act, 0, sizeof(struct sigaction)); 1367 | act.sa_sigaction = cxl_sigbus_action; 1368 | act.sa_flags = SA_SIGINFO; 1369 | 1370 | return sigaction(SIGBUS, &act, &cxl_sigbus_old_action); 1371 | } 1372 | 1373 | #if defined CXL_START_WORK_TID 1374 | int cxl_afu_host_thread_wait(struct cxl_afu_h *afu, volatile __u64 *uword) 1375 | { 1376 | if (afu == NULL) { 1377 | errno = EINVAL; 1378 | return -1; 1379 | } 1380 | if (afu->pid != syscall(SYS_gettid)) { 1381 | errno = EPERM; 1382 | return -1; 1383 | } 1384 | 1385 | while (*uword == 0) { 1386 | asm volatile ("wait"); 1387 | } 1388 | return 0; 1389 | } 1390 | #endif 1391 | -------------------------------------------------------------------------------- /libcxl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014,2015 International Business Machines 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBCXL_H 18 | #define _LIBCXL_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | #define CXL_KERNEL_API_VERSION 1 29 | 30 | #define CXL_SYSFS_CLASS "/sys/class/cxl" 31 | #define CXL_DEV_DIR "/dev/cxl" 32 | 33 | /* 34 | * Opaque types 35 | */ 36 | struct cxl_adapter_h; 37 | struct cxl_afu_h; 38 | struct cxl_ioctl_start_work; 39 | 40 | /* 41 | * Adapter Enumeration 42 | * 43 | * Repeatedly call cxl_adapter_next() (or use the cxl_for_each_adapter macro) 44 | * to enumerate the available CXL adapters. 45 | * 46 | * cxl_adapter_next() will implicitly free used buffers if it is called on the 47 | * last adapter, or cxl_adapter_free() can be called explicitly. 48 | */ 49 | struct cxl_adapter_h * cxl_adapter_next(struct cxl_adapter_h *adapter); 50 | char * cxl_adapter_dev_name(struct cxl_adapter_h *adapter); 51 | void cxl_adapter_free(struct cxl_adapter_h *adapter); 52 | #define cxl_for_each_adapter(adapter) \ 53 | for (adapter = cxl_adapter_next(NULL); adapter; adapter = cxl_adapter_next(adapter)) 54 | 55 | /* 56 | * AFU Enumeration 57 | * 58 | * Repeatedly call cxl_adapter_afu_next() (or use the 59 | * cxl_for_each_adapter_afu macro) to enumerate AFUs on a specific CXL 60 | * adapter, or use cxl_afu_next() or cxl_for_each_afu to enumerate AFUs over 61 | * all CXL adapters in the system. 62 | * 63 | * For instance, if you just want to find any AFU attached to the system but 64 | * don't particularly care which one, just do: 65 | * struct cxl_afu_h *afu_h = cxl_afu_next(NULL); 66 | * 67 | * cxl_[adapter]_afu_next() will implicitly free used buffers if it is called 68 | * on the last AFU, or cxl_afu_free() can be called explicitly. 69 | */ 70 | struct cxl_afu_h * cxl_adapter_afu_next(struct cxl_adapter_h *adapter, struct cxl_afu_h *afu); 71 | struct cxl_afu_h * cxl_afu_next(struct cxl_afu_h *afu); 72 | char * cxl_afu_dev_name(struct cxl_afu_h *afu); 73 | #define cxl_for_each_adapter_afu(adapter, afu) \ 74 | for (afu = cxl_adapter_afu_next(adapter, NULL); afu; afu = cxl_adapter_afu_next(adapter, afu)) 75 | #define cxl_for_each_afu(afu) \ 76 | for (afu = cxl_afu_next(NULL); afu; afu = cxl_afu_next(afu)) 77 | 78 | enum cxl_views { 79 | CXL_VIEW_DEDICATED = 0, 80 | CXL_VIEW_MASTER, 81 | CXL_VIEW_SLAVE 82 | }; 83 | 84 | /* 85 | * Open AFU - either by path, by AFU being enumerated, or tie into an AFU file 86 | * descriptor that has already been opened. The AFU file descriptor will be 87 | * closed by cxl_afu_free() regardless of how it was opened. 88 | */ 89 | struct cxl_afu_h * cxl_afu_open_dev(char *path); 90 | struct cxl_afu_h * cxl_afu_open_h(struct cxl_afu_h *afu, enum cxl_views view); 91 | struct cxl_afu_h * cxl_afu_fd_to_h(int fd); 92 | void cxl_afu_free(struct cxl_afu_h *afu); 93 | int cxl_afu_opened(struct cxl_afu_h *afu); 94 | 95 | /* 96 | * Attach AFU context to this process 97 | */ 98 | struct cxl_ioctl_start_work *cxl_work_alloc(void); 99 | int cxl_work_free(struct cxl_ioctl_start_work *work); 100 | int cxl_work_get_amr(struct cxl_ioctl_start_work *work, __u64 *valp); 101 | int cxl_work_get_num_irqs(struct cxl_ioctl_start_work *work, __s16 *valp); 102 | int cxl_work_get_wed(struct cxl_ioctl_start_work *work, __u64 *valp); 103 | int cxl_work_set_amr(struct cxl_ioctl_start_work *work, __u64 amr); 104 | int cxl_work_set_num_irqs(struct cxl_ioctl_start_work *work, __s16 num_irqs); 105 | int cxl_work_set_wed(struct cxl_ioctl_start_work *work, __u64 wed); 106 | #if defined CXL_START_WORK_TID 107 | int cxl_work_get_tid(struct cxl_ioctl_start_work *work, __u16 *valp); 108 | int cxl_work_enable_wait(struct cxl_ioctl_start_work *work); 109 | int cxl_work_disable_wait(struct cxl_ioctl_start_work *work); 110 | #endif 111 | 112 | int cxl_afu_attach(struct cxl_afu_h *afu, __u64 wed); 113 | int cxl_afu_attach_work(struct cxl_afu_h *afu, 114 | struct cxl_ioctl_start_work *work); 115 | 116 | /* Deprecated interface */ 117 | int cxl_afu_attach_full(struct cxl_afu_h *afu, __u64 wed, __u16 num_interrupts, 118 | __u64 amr); 119 | 120 | /* 121 | * Get AFU process element 122 | */ 123 | int cxl_afu_get_process_element(struct cxl_afu_h *afu); 124 | 125 | /* 126 | * Returns the file descriptor for the open AFU to use with event loops. 127 | * Returns -1 if the AFU is not open. 128 | */ 129 | int cxl_afu_fd(struct cxl_afu_h *afu); 130 | 131 | /* 132 | * sysfs helpers 133 | */ 134 | 135 | /* 136 | * NOTE: On success, this function automatically allocates the returned 137 | * buffer, which must be freed by the caller (much like asprintf). 138 | */ 139 | int cxl_afu_sysfs_pci(struct cxl_afu_h *afu, char **pathp); 140 | 141 | /* Flags for cxl_get/set_mode and cxl_get_modes_supported */ 142 | #define CXL_MODE_DEDICATED 0x1 143 | #define CXL_MODE_DIRECTED 0x2 144 | #define CXL_MODE_TIME_SLICED 0x4 145 | 146 | /* Values for cxl_get/set_prefault_mode */ 147 | enum cxl_prefault_mode { 148 | CXL_PREFAULT_MODE_NONE = 0, 149 | CXL_PREFAULT_MODE_WED, 150 | CXL_PREFAULT_MODE_ALL, 151 | }; 152 | 153 | /* Values for cxl_get_image_loaded */ 154 | enum cxl_image { 155 | CXL_IMAGE_FACTORY = 0, 156 | CXL_IMAGE_USER, 157 | }; 158 | 159 | /* 160 | * Get/set attribute values. 161 | * Return 0 on success, -1 on error. 162 | */ 163 | int cxl_get_api_version(struct cxl_afu_h *afu, long *valp); 164 | int cxl_get_api_version_compatible(struct cxl_afu_h *afu, long *valp); 165 | int cxl_get_cr_class(struct cxl_afu_h *afu, long cr_num, long *valp); 166 | int cxl_get_cr_device(struct cxl_afu_h *afu, long cr_num, long *valp); 167 | int cxl_get_cr_vendor(struct cxl_afu_h *afu, long cr_num, long *valp); 168 | int cxl_get_irqs_max(struct cxl_afu_h *afu, long *valp); 169 | int cxl_set_irqs_max(struct cxl_afu_h *afu, long value); 170 | int cxl_get_irqs_min(struct cxl_afu_h *afu, long *valp); 171 | int cxl_get_mmio_size(struct cxl_afu_h *afu, long *valp); 172 | int cxl_get_mode(struct cxl_afu_h *afu, long *valp); 173 | int cxl_set_mode(struct cxl_afu_h *afu, long value); 174 | int cxl_get_modes_supported(struct cxl_afu_h *afu, long *valp); 175 | int cxl_get_prefault_mode(struct cxl_afu_h *afu, enum cxl_prefault_mode *valp); 176 | int cxl_set_prefault_mode(struct cxl_afu_h *afu, enum cxl_prefault_mode value); 177 | int cxl_get_pp_mmio_len(struct cxl_afu_h *afu, long *valp); 178 | int cxl_get_pp_mmio_off(struct cxl_afu_h *afu, long *valp); 179 | int cxl_get_base_image(struct cxl_adapter_h *adapter, long *valp); 180 | int cxl_get_caia_version(struct cxl_adapter_h *adapter, long *majorp, 181 | long *minorp); 182 | int cxl_get_image_loaded(struct cxl_adapter_h *adapter, enum cxl_image *valp); 183 | int cxl_get_psl_revision(struct cxl_adapter_h *adapter, long *valp); 184 | int cxl_get_psl_timebase_synced(struct cxl_adapter_h *adapter, long *valp); 185 | int cxl_get_tunneled_ops_supported(struct cxl_adapter_h *adapter, long *valp); 186 | 187 | /* 188 | * Events 189 | */ 190 | int cxl_event_pending(struct cxl_afu_h *afu); 191 | int cxl_read_event(struct cxl_afu_h *afu, struct cxl_event *event); 192 | int cxl_read_expected_event(struct cxl_afu_h *afu, struct cxl_event *event, 193 | __u32 type, __u16 irq); 194 | 195 | /* 196 | * fprint wrappers to print out CXL events - useful for debugging. 197 | * cxl_fprint_event will select the appropriate implementation based on the 198 | * event type and cxl_fprint_unknown_event will print out a hex dump of the 199 | * raw event. 200 | */ 201 | int cxl_fprint_event(FILE *stream, struct cxl_event *event); 202 | int cxl_fprint_unknown_event(FILE *stream, struct cxl_event *event); 203 | 204 | /* 205 | * AFU MMIO functions 206 | * 207 | * The below assessors will byte swap based on what is passed to map. Also a 208 | * full memory barrier 'sync' will proceed a write and follow a read. More 209 | * relaxed assessors can be created using a pointer derived from cxl_mmio_ptr(). 210 | */ 211 | #define CXL_MMIO_BIG_ENDIAN 0x1 212 | #define CXL_MMIO_LITTLE_ENDIAN 0x2 213 | #define CXL_MMIO_HOST_ENDIAN 0x3 214 | #define CXL_MMIO_ENDIAN_MASK 0x3 215 | #define CXL_MMIO_FLAGS 0x3 216 | int cxl_mmio_map(struct cxl_afu_h *afu, __u32 flags); 217 | int cxl_mmio_unmap(struct cxl_afu_h *afu); 218 | int cxl_mmio_ptr(struct cxl_afu_h *afu, void **mmio_ptrp); 219 | int cxl_mmio_write64(struct cxl_afu_h *afu, uint64_t offset, uint64_t data); 220 | int cxl_mmio_read64(struct cxl_afu_h *afu, uint64_t offset, uint64_t *data); 221 | int cxl_mmio_write32(struct cxl_afu_h *afu, uint64_t offset, uint32_t data); 222 | int cxl_mmio_read32(struct cxl_afu_h *afu, uint64_t offset, uint32_t *data); 223 | 224 | /* 225 | * Calling this function will install the libcxl SIGBUS handler. This will 226 | * catch bad MMIO accesses (e.g. due to hardware failures) that would otherwise 227 | * terminate the program and make the above mmio functions return errors 228 | * instead. 229 | * 230 | * Call this once per process prior to any MMIO accesses. 231 | */ 232 | int cxl_mmio_install_sigbus_handler(void); 233 | 234 | /** 235 | * Returns the size of afu_err_buff in bytes. 236 | * @param afu Handle to the afu. 237 | * @param valp Pointer to the location where size is copied to. 238 | * @return In case of success '0' is returned. In case of an error or 239 | * the afu_err_buff doesn't exist, -1 is returned and errno is set 240 | * appropriately. 241 | */ 242 | int cxl_errinfo_size(struct cxl_afu_h *afu, size_t *valp); 243 | 244 | /** 245 | * Read and copy the contents of afu_err_info buffer into the provided buffer. 246 | * @param afu Handle to the afu 247 | * @param dst Pointer to the buffer where data would be copied. 248 | * @param off Start offset within the afu_err_info handle. 249 | * @param len Number of bytes to be copied after the start offset. 250 | * @return The number of bytes copied from the afu_err_buff to dst. In case of 251 | * an error or the afu_err_buff doesn't exist, -1 is returned and errno is set 252 | * appropriately. 253 | */ 254 | ssize_t cxl_errinfo_read(struct cxl_afu_h *afu, void *dst, off_t off, 255 | size_t len); 256 | 257 | 258 | #if defined CXL_START_WORK_TID 259 | /** 260 | * Execute the instruction "wait" while the value of the shared 261 | * memory (uword) has not changed. Only the current thread, which has 262 | * attached the work, may be asleep. 263 | * @param uword Pointer to the shared memory to exit from the loop. 264 | * @return In case of success '0' is returned. In case of an error or 265 | * the afu doesn't exist, -1 is returned and errno is set 266 | * appropriately. 267 | */ 268 | int cxl_afu_host_thread_wait(struct cxl_afu_h *afu, volatile __u64 *uword); 269 | #endif 270 | #ifdef __cplusplus 271 | } 272 | #endif 273 | 274 | #endif 275 | -------------------------------------------------------------------------------- /libcxl_internal.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014,2015 International Business Machines 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef _LIBCXL_INTERNAL_H 18 | #define _LIBCXL_INTERNAL_H 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | struct cxl_adapter_h { 25 | DIR *enum_dir; 26 | struct dirent *enum_ent; 27 | char *sysfs_path; 28 | }; 29 | 30 | struct cxl_afu_h { 31 | struct cxl_adapter_h *adapter; /* Only used if allocated by us */ 32 | DIR *enum_dir; 33 | int process_element; 34 | struct dirent *enum_ent; 35 | struct cxl_event *event_buf; /* Event buffer storage */ 36 | struct cxl_event *event_buf_first; /* First event to read */ 37 | struct cxl_event *event_buf_end; /* End of events */ 38 | char *dev_name; 39 | char *sysfs_path; 40 | int fd; 41 | void *mmio_addr; 42 | __u32 mmio_flags; 43 | size_t mmio_size; 44 | int fd_errbuff; /* fd to the afu_err_buff */ 45 | size_t errbuff_size; 46 | #if defined CXL_START_WORK_TID 47 | int pid; 48 | #endif 49 | }; 50 | 51 | int cxl_get_dev(struct cxl_afu_h *afu, long *majorp, long *minorp); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /libcxl_sysfs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014,2015 International Business Machines 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #define _GNU_SOURCE 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include "libcxl.h" 29 | 30 | #include "libcxl_internal.h" 31 | 32 | enum cxl_sysfs_attr { 33 | /* AFU */ 34 | API_VERSION = 0, 35 | API_VERSION_COMPATIBLE, 36 | CR_CLASS, 37 | CR_DEVICE, 38 | CR_VENDOR, 39 | IRQS_MAX, 40 | IRQS_MIN, 41 | MMIO_SIZE, 42 | MODE, 43 | MODES_SUPPORTED, 44 | PREFAULT_MODE, 45 | 46 | /* AFU Master or Slave */ 47 | DEV, 48 | PP_MMIO_LEN, 49 | PP_MMIO_OFF, 50 | 51 | /* Card */ 52 | BASE_IMAGE, 53 | CAIA_VERSION, 54 | IMAGE_LOADED, 55 | PSL_REVISION, 56 | PSL_TIMEBASE_SYNCED, 57 | TUNNELED_OPS_SUPPORTED, 58 | 59 | /* Add new attrs above this */ 60 | CXL_ATTR_MAX 61 | }; 62 | 63 | struct cxl_sysfs_entry { 64 | char *name; 65 | int (*scan_func)(char *attr_str, long *major, long *minor); 66 | int expected_num; 67 | }; 68 | 69 | static int scan_int(char *attr_str, long *majorp, long *minorp); 70 | static int scan_hex(char *attr_str, long *majorp, long *minorp); 71 | static int scan_dev(char *attr_str, long *majorp, long *minorp); 72 | static int scan_mode(char *attr_str, long *majorp, long *minorp); 73 | static int scan_modes(char *attr_str, long *majorp, long *minorp); 74 | static int scan_prefault_mode(char *attr_str, long *majorp, long *minorp); 75 | static int scan_caia_version(char *attr_str, long *majorp, long *minorp); 76 | static int scan_image(char *attr_str, long *majorp, long *minorp); 77 | 78 | static struct cxl_sysfs_entry sysfs_entry[CXL_ATTR_MAX] = { 79 | [API_VERSION] = { "api_version", scan_int, 1 }, 80 | [API_VERSION_COMPATIBLE] = { "api_version_compatible", scan_int, 1 }, 81 | [CR_CLASS] = { "cr%ld/class", scan_hex, 1 }, 82 | [CR_DEVICE] = { "cr%ld/device", scan_hex, 1 }, 83 | [CR_VENDOR] = { "cr%ld/vendor", scan_hex, 1 }, 84 | [IRQS_MAX] = { "irqs_max", scan_int, 1 }, 85 | [IRQS_MIN] = { "irqs_min", scan_int, 1 }, 86 | [MMIO_SIZE] = { "mmio_size", scan_int, 1 }, 87 | [MODE] = { "mode", scan_mode, 1 }, 88 | [MODES_SUPPORTED] = { "modes_supported", scan_modes, 1 }, 89 | [PREFAULT_MODE] = { "prefault_mode", scan_prefault_mode, 1 }, 90 | [DEV] = { "dev", scan_dev, 2 }, 91 | [PP_MMIO_LEN] = { "pp_mmio_len", scan_int, 1 }, 92 | [PP_MMIO_OFF] = { "pp_mmio_off", scan_int, 1 }, 93 | [BASE_IMAGE] = { "base_image", scan_int, 1 }, 94 | [CAIA_VERSION] = { "caia_version", scan_caia_version, 2 }, 95 | [IMAGE_LOADED] = { "image_loaded", scan_image, 1 }, 96 | [PSL_REVISION] = { "psl_revision", scan_int, 1 }, 97 | [PSL_TIMEBASE_SYNCED] = { "psl_timebase_synced", scan_int, 1 }, 98 | [TUNNELED_OPS_SUPPORTED] = { "tunneled_ops_supported", scan_int, 1 }, 99 | }; 100 | 101 | #define OUT_OF_RANGE(attr) ((attr) < 0 || (attr) >= CXL_ATTR_MAX || \ 102 | (sysfs_entry[attr].name == NULL)) 103 | 104 | static int scan_int(char *attr_str, long *majorp, long *minorp) 105 | { 106 | return sscanf(attr_str, "%ld", majorp); 107 | } 108 | 109 | static int scan_hex(char *attr_str, long *majorp, long *minorp) 110 | { 111 | return sscanf(attr_str, "0x%lx", majorp); 112 | } 113 | 114 | static int scan_dev(char *attr_str, long *majorp, long *minorp) 115 | { 116 | return sscanf(attr_str, "%ld:%ld", majorp, minorp); 117 | } 118 | 119 | static int scan_caia_version(char *attr_str, long *majorp, long *minorp) 120 | { 121 | return sscanf(attr_str, "%ld.%ld", majorp, minorp); 122 | } 123 | 124 | static int scan_mode(char *attr_str, long *majorp, long *minorp) 125 | { 126 | int count; 127 | char buf[18]; 128 | 129 | if ((count = sscanf(attr_str, "%17s", buf)) != 1) 130 | return -1; 131 | if (!strcmp(buf, "dedicated_process")) { 132 | *majorp = CXL_MODE_DEDICATED; 133 | count = 0; 134 | } else if (!strcmp(buf, "afu_directed")) { 135 | *majorp = CXL_MODE_DIRECTED; 136 | count = 0; 137 | } 138 | return (count == 0); 139 | } 140 | 141 | static int scan_modes(char *attr_str, long *majorp, long *minorp) 142 | { 143 | long val1, val2 = 0; 144 | char buf1[18], buf2[18]; 145 | int rc; 146 | 147 | if ((rc = sscanf(attr_str, "%17s\n%17s", buf1, buf2)) <= 0) 148 | return -1; 149 | if (rc == 2 && scan_mode(buf2, &val2, NULL) != 1) 150 | return -1; 151 | if (scan_mode(buf1, &val1, NULL) != 1) 152 | return -1; 153 | *majorp = val1|val2; 154 | return 1; 155 | } 156 | 157 | static int scan_prefault_mode(char *attr_str, long *majorp, long *minorp) 158 | { 159 | int count; 160 | char buf[24]; 161 | if ((count = sscanf(attr_str, "%23s", buf)) != 1) 162 | return -1; 163 | if (!strcmp(buf, "none")) { 164 | *majorp = CXL_PREFAULT_MODE_NONE; 165 | count = 0; 166 | } else if (!strcmp(buf, "work_element_descriptor")) { 167 | *majorp = CXL_PREFAULT_MODE_WED; 168 | count = 0; 169 | } else if (!strcmp(buf, "all")) { 170 | *majorp = CXL_PREFAULT_MODE_ALL; 171 | count = 0; 172 | } 173 | return (count == 0); 174 | } 175 | 176 | static int scan_image(char *attr_str, long *majorp, long *minorp) 177 | { 178 | int count; 179 | char buf[8]; 180 | 181 | if ((count = sscanf(attr_str, "%7s", buf)) != 1) 182 | return -1; 183 | if (!strcmp(buf, "factory")) { 184 | *majorp = CXL_IMAGE_FACTORY; 185 | count = 0; 186 | } else if (!strcmp(buf, "user")) { 187 | *majorp = CXL_IMAGE_USER; 188 | count = 0; 189 | } 190 | return (count == 0); 191 | } 192 | 193 | static char *sysfs_attr_name(enum cxl_sysfs_attr attr) 194 | { 195 | if (OUT_OF_RANGE(attr)) 196 | return NULL; 197 | return sysfs_entry[attr].name; 198 | } 199 | 200 | #define BUFLEN 256 201 | 202 | static char *sysfs_get_path(char *path, char *attr_name) 203 | { 204 | char *attr_path = NULL; 205 | char *new_path; 206 | struct stat sb; 207 | 208 | path = strdup(path); 209 | if (path == NULL) 210 | return NULL; 211 | 212 | /* 213 | * Try to open the attribute in sysfs. If it doesn't exist, keep 214 | * following "device/" path down until we find it. 215 | */ 216 | while (stat(path, &sb) != -1) { 217 | if (asprintf(&attr_path, "%s/%s", path, attr_name) == -1) 218 | goto out; 219 | 220 | if (stat(attr_path, &sb) == 0) { 221 | free(path); 222 | return attr_path; 223 | } 224 | 225 | if (errno != ENOENT) 226 | /* Something unexpected beside it not existing */ 227 | goto enodev; 228 | 229 | /* If it doesn't exist, walk down "device/" link */ 230 | if (asprintf(&new_path, "%s/device", path) == -1) 231 | goto out; 232 | 233 | free(path); 234 | path = new_path; 235 | free(attr_path); 236 | } 237 | /* Directory doesn't exist */ 238 | enodev: 239 | errno = ENODEV; 240 | out: 241 | if (attr_path) 242 | free(attr_path); 243 | free(path); 244 | return NULL; 245 | } 246 | 247 | static char *read_sysfs_str(char *attr_path) 248 | { 249 | int fd, count; 250 | char buf[BUFLEN]; 251 | 252 | fd = open(attr_path, O_RDONLY); 253 | free(attr_path); 254 | if (fd == -1) 255 | return NULL; 256 | count = read(fd, buf, BUFLEN); 257 | close(fd); 258 | if (count == -1) 259 | return NULL; 260 | buf[count - 1] = '\0'; 261 | return strdup(buf); 262 | } 263 | 264 | static int scan_sysfs_str(enum cxl_sysfs_attr attr, char *attr_str, 265 | long *majorp, long *minorp) 266 | { 267 | int (*scan_func)(char *attr_str, long *majorp, long *minorp); 268 | 269 | if (OUT_OF_RANGE(attr)) 270 | return -1; 271 | scan_func = sysfs_entry[attr].scan_func; 272 | if (scan_func == NULL) 273 | return -1; 274 | return (*scan_func)(attr_str, majorp, minorp); 275 | } 276 | 277 | static int read_sysfs(char *sysfs_path, enum cxl_sysfs_attr attr, long *majorp, 278 | long *minorp) 279 | { 280 | char *attr_name; 281 | char *attr_path; 282 | char *buf; 283 | int expected, ret; 284 | 285 | if (OUT_OF_RANGE(attr)) 286 | return -1; 287 | attr_name = sysfs_attr_name(attr); 288 | if (attr_name == NULL) 289 | return -1; 290 | /* 291 | * Hack: 292 | * For configuration record attributes, attr_name is a printf 293 | * format with one parameter, the configuration record number, 294 | * pointed to by minorp. 295 | */ 296 | switch (attr) { 297 | case CR_CLASS: 298 | case CR_DEVICE: 299 | case CR_VENDOR: 300 | if (asprintf(&buf, attr_name, *minorp) == -1) 301 | return -1; 302 | attr_path = sysfs_get_path(sysfs_path, buf); 303 | free(buf); 304 | break; 305 | default: 306 | attr_path = sysfs_get_path(sysfs_path, attr_name); 307 | } 308 | if (attr_path == NULL) 309 | return -1; 310 | if ((buf = read_sysfs_str(attr_path)) == NULL) 311 | return -1; 312 | expected = sysfs_entry[attr].expected_num; 313 | ret = scan_sysfs_str(attr, buf, majorp, minorp); 314 | free(buf); 315 | return (ret == expected) ? 0 : -1; 316 | } 317 | 318 | static int read_sysfs_afu(struct cxl_afu_h *afu, enum cxl_sysfs_attr attr, 319 | long *majorp, long *minorp) 320 | { 321 | if ((afu == NULL) || (afu->sysfs_path == NULL)) { 322 | errno = EINVAL; 323 | return -1; 324 | } 325 | return read_sysfs(afu->sysfs_path, attr, majorp, minorp); 326 | 327 | } 328 | 329 | static int read_sysfs_adapter(struct cxl_adapter_h *adapter, 330 | enum cxl_sysfs_attr attr, long *majorp, 331 | long *minorp) 332 | { 333 | if ((adapter == NULL) || (adapter->sysfs_path == NULL)) { 334 | errno = EINVAL; 335 | return -1; 336 | } 337 | return read_sysfs(adapter->sysfs_path, attr, majorp, minorp); 338 | } 339 | 340 | int cxl_get_api_version(struct cxl_afu_h *afu, long *valp) 341 | { 342 | return read_sysfs_afu(afu, API_VERSION, valp, NULL); 343 | } 344 | 345 | int cxl_get_api_version_compatible(struct cxl_afu_h *afu, long *valp) 346 | { 347 | return read_sysfs_afu(afu, API_VERSION_COMPATIBLE, valp, NULL); 348 | } 349 | 350 | int cxl_get_cr_class(struct cxl_afu_h *afu, long cr_num, long *valp) 351 | { 352 | return read_sysfs_afu(afu, CR_CLASS, valp, &cr_num); 353 | } 354 | 355 | int cxl_get_cr_device(struct cxl_afu_h *afu, long cr_num, long *valp) 356 | { 357 | return read_sysfs_afu(afu, CR_DEVICE, valp, &cr_num); 358 | } 359 | 360 | int cxl_get_cr_vendor(struct cxl_afu_h *afu, long cr_num, long *valp) 361 | { 362 | return read_sysfs_afu(afu, CR_VENDOR, valp, &cr_num); 363 | } 364 | 365 | int cxl_get_irqs_max(struct cxl_afu_h *afu, long *valp) 366 | { 367 | return read_sysfs_afu(afu, IRQS_MAX, valp, NULL); 368 | } 369 | 370 | int cxl_get_irqs_min(struct cxl_afu_h *afu, long *valp) 371 | { 372 | return read_sysfs_afu(afu, IRQS_MIN, valp, NULL); 373 | } 374 | 375 | int cxl_get_mmio_size(struct cxl_afu_h *afu, long *valp) 376 | { 377 | return read_sysfs_afu(afu, MMIO_SIZE, valp, NULL); 378 | } 379 | 380 | int cxl_get_mode(struct cxl_afu_h *afu, long *valp) 381 | { 382 | return read_sysfs_afu(afu, MODE, valp, NULL); 383 | } 384 | 385 | int cxl_get_modes_supported(struct cxl_afu_h *afu, long *valp) 386 | { 387 | return read_sysfs_afu(afu, MODES_SUPPORTED, valp, NULL); 388 | } 389 | 390 | int cxl_get_prefault_mode(struct cxl_afu_h *afu, enum cxl_prefault_mode *valp) 391 | { 392 | long value; 393 | int ret; 394 | 395 | ret = read_sysfs_afu(afu, PREFAULT_MODE, &value, NULL); 396 | *valp = (enum cxl_prefault_mode)value; 397 | return ret; 398 | } 399 | 400 | int cxl_get_dev(struct cxl_afu_h *afu, long *majorp, long *minorp) 401 | { 402 | return read_sysfs_afu(afu, DEV, majorp, minorp); 403 | } 404 | 405 | int cxl_get_pp_mmio_len(struct cxl_afu_h *afu, long *valp) 406 | { 407 | return read_sysfs_afu(afu, PP_MMIO_LEN, valp, NULL); 408 | } 409 | 410 | int cxl_get_pp_mmio_off(struct cxl_afu_h *afu, long *valp) 411 | { 412 | return read_sysfs_afu(afu, PP_MMIO_OFF, valp, NULL); 413 | } 414 | 415 | int cxl_get_base_image(struct cxl_adapter_h *adapter, long *valp) 416 | { 417 | return read_sysfs_adapter(adapter, BASE_IMAGE, valp, NULL); 418 | } 419 | 420 | int cxl_get_caia_version(struct cxl_adapter_h *adapter, long *majorp, 421 | long *minorp) 422 | { 423 | return read_sysfs_adapter(adapter, CAIA_VERSION, majorp, minorp); 424 | } 425 | 426 | int cxl_get_image_loaded(struct cxl_adapter_h *adapter, enum cxl_image *valp) 427 | { 428 | return read_sysfs_adapter(adapter, IMAGE_LOADED, (long *)valp, NULL); 429 | } 430 | 431 | int cxl_get_psl_revision(struct cxl_adapter_h *adapter, long *valp) 432 | { 433 | return read_sysfs_adapter(adapter, PSL_REVISION, valp, NULL); 434 | } 435 | 436 | int cxl_get_psl_timebase_synced(struct cxl_adapter_h *adapter, long *valp) 437 | { 438 | return read_sysfs_adapter(adapter, PSL_TIMEBASE_SYNCED, valp, NULL); 439 | } 440 | 441 | int cxl_get_tunneled_ops_supported(struct cxl_adapter_h *adapter, long *valp) 442 | { 443 | return read_sysfs_adapter(adapter, TUNNELED_OPS_SUPPORTED, valp, NULL); 444 | } 445 | 446 | static int write_sysfs_str(char *path, enum cxl_sysfs_attr attr, char *str) 447 | { 448 | char *attr_name; 449 | char *attr_path; 450 | int fd, count; 451 | 452 | if (OUT_OF_RANGE(attr)) 453 | return -1; 454 | if (path == NULL) 455 | return -1; 456 | attr_name = sysfs_attr_name(attr); 457 | if (attr_name == NULL) 458 | return -1; 459 | attr_path = sysfs_get_path(path, attr_name); 460 | if (attr_path == NULL) 461 | return -1; 462 | fd = open(attr_path, O_WRONLY); 463 | free(attr_path); 464 | if (fd == -1) 465 | return -1; 466 | count = write(fd, str, strlen(str)); 467 | close(fd); 468 | if (count == -1) 469 | return -1; 470 | return 0; 471 | } 472 | 473 | static int write_sysfs_afu(struct cxl_afu_h *afu, enum cxl_sysfs_attr attr, 474 | char* str) 475 | { 476 | if ((afu == NULL) || (afu->sysfs_path == NULL)) { 477 | errno = EINVAL; 478 | return -1; 479 | } 480 | return write_sysfs_str(afu->sysfs_path, attr, str); 481 | 482 | } 483 | 484 | int cxl_set_irqs_max(struct cxl_afu_h *afu, long value) 485 | { 486 | char *buf; 487 | int ret; 488 | 489 | if (asprintf(&buf, "%ld", value) == -1) 490 | return -1; 491 | ret = write_sysfs_afu(afu, IRQS_MAX, buf); 492 | free(buf); 493 | return ret; 494 | } 495 | 496 | int cxl_set_mode(struct cxl_afu_h *afu, long value) 497 | { 498 | char *str; 499 | 500 | switch (value) { 501 | case CXL_MODE_DEDICATED: 502 | str = "dedicated_process"; 503 | break; 504 | case CXL_MODE_DIRECTED: 505 | str = "afu_directed"; 506 | break; 507 | default: 508 | errno = EINVAL; 509 | return -1; 510 | } 511 | return write_sysfs_afu(afu, MODE, str); 512 | } 513 | 514 | int cxl_set_prefault_mode(struct cxl_afu_h *afu, enum cxl_prefault_mode value) 515 | { 516 | char *str; 517 | 518 | switch (value) { 519 | case CXL_PREFAULT_MODE_NONE: 520 | str = "none"; 521 | break; 522 | case CXL_PREFAULT_MODE_WED: 523 | str = "work_element_descriptor"; 524 | break; 525 | case CXL_PREFAULT_MODE_ALL: 526 | str = "all"; 527 | break; 528 | default: 529 | errno = EINVAL; 530 | return -1; 531 | } 532 | return write_sysfs_afu(afu, PREFAULT_MODE, str); 533 | } 534 | 535 | /* Returns the total size of the afu_err_buff in bytes */ 536 | int cxl_errinfo_size(struct cxl_afu_h *afu, size_t *valp) 537 | { 538 | /* check if we need to fetch the size of the buffer */ 539 | if (afu->errbuff_size == -1) { 540 | char * path; 541 | struct stat st; 542 | 543 | path = sysfs_get_path(afu->sysfs_path, "afu_err_buff"); 544 | if (path == NULL) 545 | return -1; 546 | 547 | /* get the file size */ 548 | if (stat(path, &st) < 0) { 549 | free(path); 550 | return -1; 551 | } 552 | 553 | afu->errbuff_size = st.st_size; 554 | free(path); 555 | } 556 | 557 | *valp = afu->errbuff_size; 558 | return 0; 559 | } 560 | 561 | /* Read and copies contents to afu_err_buff to the provided buffer */ 562 | ssize_t cxl_errinfo_read(struct cxl_afu_h *afu, void *dst, off_t off, 563 | size_t len) 564 | { 565 | /* check if we need to open the descriptor */ 566 | if (afu->fd_errbuff == -1) { 567 | char * path; 568 | 569 | path = sysfs_get_path(afu->sysfs_path, "afu_err_buff"); 570 | if (path == NULL) 571 | return -1; 572 | 573 | afu->fd_errbuff = open(path, O_RDONLY | O_CLOEXEC); 574 | free(path); 575 | 576 | if (afu->fd_errbuff == -1) 577 | return -1; 578 | } 579 | 580 | /* seek to right offset and read contents */ 581 | if (lseek(afu->fd_errbuff, off, SEEK_SET) < 0) 582 | return -1; 583 | 584 | return read(afu->fd_errbuff, dst, len); 585 | } 586 | -------------------------------------------------------------------------------- /man3/Makefile: -------------------------------------------------------------------------------- 1 | SRC = $(wildcard *.3) 2 | HTML = $(SRC:.3=.3.html) 3 | TXT = $(SRC:.3=.3.txt) 4 | 5 | all: $(HTML) $(TXT) 6 | 7 | clean: 8 | rm -f *.3.html *.3.txt 9 | 10 | %.3.html: %.3 11 | man2html -r <$< >$@; [ -s $@ ] 12 | 13 | %.3.txt: %.3 14 | ./man2txt <$< >$@; [ -s $@ ] 15 | 16 | cxl.3.txt: cxl.3 17 | ./man2txt <$< | ./foldtbl >$@; [ -s $@ ] 18 | 19 | cxl_for_each_adapter.3.html: cxl_adapter_next.3.html 20 | cp -f $< $@ 21 | 22 | cxl_for_each_adapter_afu.3.html: cxl_adapter_afu_next.3.html 23 | cp -f $< $@ 24 | 25 | cxl_for_each_afu.3.html: cxl_afu_next.3.html 26 | cp -f $< $@ 27 | 28 | include ../Makefile.rules 29 | 30 | install: 31 | mkdir -p $(DESTDIR)$(mandir)/man3 32 | install -m 0644 $(SRC) $(DESTDIR)$(mandir)/man3/ 33 | 34 | .PHONY: all clean install 35 | -------------------------------------------------------------------------------- /man3/cxl.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2018 IBM Corp. 2 | .\" 3 | .TH CXL 3 2018-04-26 "LIBCXL 1.7" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl \- Coherent Accelerator Interface (CXL) library functions 6 | .SH SYNOPSIS 7 | .B #include 8 | .SH DESCRIPTION 9 | .SS Introduction 10 | The coherent accelerator interface is designed to allow the 11 | coherent connection of accelerators (FPGAs and other devices) 12 | to a POWER system. 13 | Coherent in this context means that the accelerator and CPUs can 14 | both access system memory directly and with the same effective 15 | addresses. 16 | IBM refers to this as the Coherent Accelerator Processor Interface 17 | (CAPI). 18 | In the Linux world it is referred to by the name CXL to 19 | avoid confusion with the ISDN CAPI subsystem. 20 | .PP 21 | The Linux kernel interacts with the device POWER Service Layer (PSL). 22 | Userland interacts with the device Accelerator Function Unit (AFU). 23 | See the Linux kernel source file 24 | .B Documentation/powerpc/cxl.txt 25 | for a detailed description of the coherent accelerator interface. 26 | .PP 27 | The CXL library provides a userland API to coherently attached 28 | devices. 29 | CXL devices can be enumerated. 30 | Their capabilities can be queried. 31 | AFUs can be opened, attached to the current process, and started. 32 | Jobs, described by AFU specific Work Element Descriptors (WEDs), 33 | can be submitted and executed by AFUs. 34 | AFU MMIO space can be mapped into the current process memory, and 35 | AFUs can be configured and controlled via MMIO reads and writes. 36 | Also if an AFU exports an AFU Error Buffer (afu_err_buff), its contents 37 | can be queried. 38 | .SS Constant macros 39 | .TS 40 | ; 41 | lb lb 42 | lb l. 43 | Macro Description 44 | _ 45 | CXL_DEV_DIR CXL device directory pathname 46 | CXL_KERNEL_API_VERSION maximum supported CXL kernel API compatible version 47 | CXL_MMIO_BIG_ENDIAN big-endian AFU flag 48 | CXL_MMIO_HOST_ENDIAN host-endian AFU flag 49 | CXL_MMIO_LITTLE_ENDIAN little-endian AFU flag 50 | CXL_MODE_DEDICATED dedicated process mode flag 51 | CXL_MODE_DIRECTED AFU directed mode flag 52 | CXL_SYSFS_CLASS sysfs CXL class pathname 53 | 54 | .TE 55 | .SS Enumeration macros 56 | .TS 57 | ; 58 | lb lb 59 | lb l. 60 | Macro Description 61 | _ 62 | cxl_for_each_adapter enumerate the available CXL adapters 63 | cxl_for_each_adapter_afu enumerate the AFUs of a CXL adapter 64 | cxl_for_each_afu enumerate the available AFUs 65 | .TE 66 | .SS Enumeration functions 67 | .TS 68 | ; 69 | lb lb 70 | lb l. 71 | Function Description 72 | _ 73 | cxl_adapter_dev_name return the CXL adapter device name 74 | cxl_adapter_free free the CXL adapter data structures 75 | cxl_adapter_next iterate to the next CXL adapter 76 | cxl_adapter_afu_next iterate to the next AFU of a CXL adapter 77 | cxl_afu_dev_name return the AFU device name 78 | cxl_afu_next iterate to the next AFU 79 | .TE 80 | .SS Open AFU functions 81 | .TS 82 | ; 83 | lb lb 84 | lb l. 85 | Function Description 86 | _ 87 | cxl_afu_fd return the file descriptor of an AFU handle 88 | cxl_afu_fd_to_h create an AFU handle from the file descriptor of an already open AFU 89 | cxl_afu_free free the data structures of an AFU handle 90 | cxl_afu_get_process_element get the process element associated with an open AFU handle 91 | cxl_afu_open_dev open an AFU by device name 92 | cxl_afu_open_h open an AFU by AFU handle 93 | cxl_afu_opened return whether an AFU handle is opened 94 | .TE 95 | .SS Work Structure Handling functions 96 | .TS 97 | ; 98 | lb lb 99 | lb l. 100 | Function Description 101 | _ 102 | cxl_work_alloc allocate and initialize a work structure 103 | cxl_work_disable_wait indicate that a host thread will not wait 104 | cxl_work_enable_wait indicate that a host thread will wait 105 | cxl_work_free free a work structure 106 | cxl_work_get_amr get the value of the authority mask register 107 | cxl_work_get_num_irqs get the number of interrupts requested 108 | cxl_work_get_tid get the tid of the thread that will wait 109 | cxl_work_get_wed get the value of the work element descriptor 110 | cxl_work_set_amr set the value of the authority mask register 111 | cxl_work_set_num_irqs set the number of interrupts requested 112 | cxl_work_set_wed set the value of the work element descriptor 113 | .TE 114 | .SS Attach AFU Context functions 115 | .TS 116 | ; 117 | lb lb 118 | lb l. 119 | Function Description 120 | _ 121 | cxl_afu_attach attach the calling process's memory to an open AFU 122 | cxl_afu_attach_full attach the calling process's memory to an open AFU (Deprecated Interface) 123 | cxl_afu_attach_work attach the calling process's memory to an open AFU 124 | .TE 125 | .SS Wait for AFU Notification function 126 | .TS 127 | ; 128 | lb lb 129 | lb l. 130 | Function Description 131 | _ 132 | cxl_afu_host_thread_wait wait for AFU notification 133 | .TE 134 | .SS CXL Adapter Sysfs Helper functions 135 | .TS 136 | ; 137 | lb lb 138 | lb l. 139 | Function Description 140 | _ 141 | cxl_get_base_image get the revision level of the initial PSL image loaded on the CXL device 142 | cxl_get_caia_version get the CAIA version supported by a CXL adapter 143 | cxl_get_image_loaded returns which of the user and factory PSL images is currently loaded on the CXL device 144 | cxl_get_psl_revision get the revision level of the current PSL image loaded on the CXL device 145 | cxl_get_psl_timebase_synced get the status of timebase on the CXL device 146 | cxl_get_tunneled_ops_supported get the status of tunneled operations on the CXL device 147 | .TE 148 | .SS AFU Directed Master Context Sysfs Helper functions 149 | .TS 150 | ; 151 | lb lb 152 | lb l. 153 | Function Description 154 | _ 155 | cxl_get_mmio_size get the total size of the MMIO space of an AFU, including all per-process areas 156 | cxl_get_pp_mmio_len get the per-process MMIO space length 157 | cxl_get_pp_mmio_off get the per-process MMIO space offset 158 | .TE 159 | .SS AFU Context Sysfs Helper functions 160 | .TS 161 | ; 162 | lb lb 163 | lb l. 164 | Function Description 165 | _ 166 | cxl_afu_sysfs_pci get the sysfs path to the PCI device corresponding with an AFU 167 | cxl_get_mmio_size get the size of the MMIO space available to a non-master process 168 | cxl_get_mode get the current programming mode of an AFU 169 | cxl_get_modes_supported get the programming modes supported by an AFU 170 | cxl_get_prefault_mode get the mode for prefaulting segments 171 | cxl_get_api_version get the version of the kernel CXL API 172 | cxl_get_api_version_compatible get the lowest CXL API version compatible with the kernel 173 | cxl_get_cr_class get the class code out of an AFU configuration record 174 | cxl_get_cr_device get the device ID out of an AFU configuration record 175 | cxl_get_cr_vendor get the vendor ID out of an AFU configuration record 176 | cxl_get_irqs_max get the maximum number of AFU interrupts available to a context, 177 | if it was the only context running 178 | cxl_get_irqs_min get the minimum number of AFU interrupts required for each context 179 | cxl_set_irqs_max administratively restrict the maximum number of AFU interrupts 180 | that can be used by a single context 181 | cxl_set_mode set the programming mode of an AFU 182 | cxl_set_prefault_mode set the mode for prefaulting segments 183 | .TE 184 | .SS Events functions 185 | .TS 186 | ; 187 | lb lb 188 | lb l. 189 | Function Description 190 | _ 191 | cxl_fprint_event print out a description of a CXL event for debugging 192 | cxl_fprint_unknown_event print out a hex dump of a raw CXL event for debugging 193 | cxl_event_pending return whether a CXL event is pending 194 | cxl_read_event read one CXL event from an AFU 195 | cxl_read_expected_event read one CXL event from an AFU, and treat it as a failure, 196 | if it did not match an expected event 197 | .TE 198 | .SS AFU MMIO functions 199 | .TS 200 | ; 201 | lb lb 202 | lb l. 203 | Function Description 204 | _ 205 | cxl_mmio_map map the per-process Problem State Area of an AFU to memory 206 | cxl_mmio_ptr return the address of the mapped AFU Problem State Area 207 | cxl_mmio_read32 read a 32-bit word from the mapped AFU Problem State Area 208 | cxl_mmio_read64 read a 64-bit word from the mapped AFU Problem State Area 209 | cxl_mmio_unmap unmap an AFU Problem State Area 210 | cxl_mmio_write32 write a 32-bit word to the mapped AFU Problem State Area 211 | cxl_mmio_write64 write a 32-bit word to the mapped AFU Problem State Area 212 | .TE 213 | .SS AFU Error Buffer query functions 214 | .TS 215 | ; 216 | lb lb 217 | lb l. 218 | Function Description 219 | _ 220 | cxl_errinfo_read read and copy the contents of afu_err_info buffer into the provided buffer 221 | cxl_errinfo_size returns the size of afu_err_buff in bytes 222 | .TE 223 | .SH SEE ALSO 224 | .BR cxl_adapter_afu_next (3), 225 | .BR cxl_adapter_dev_name (3), 226 | .BR cxl_adapter_free (3), 227 | .BR cxl_adapter_next (3), 228 | .BR cxl_afu_attach (3), 229 | .BR cxl_afu_attach_full (3), 230 | .BR cxl_afu_attach_work (3), 231 | .BR cxl_afu_attach_work (3), 232 | .BR cxl_afu_dev_name (3), 233 | .BR cxl_afu_fd (3), 234 | .BR cxl_afu_fd_to_h (3), 235 | .BR cxl_afu_free (3), 236 | .BR cxl_afu_get_process_element (3), 237 | .BR cxl_afu_host_thread_wait (3), 238 | .BR cxl_afu_next (3), 239 | .BR cxl_afu_open_dev (3), 240 | .BR cxl_afu_open_h (3), 241 | .BR cxl_afu_opened (3), 242 | .BR cxl_afu_sysfs_pci (3), 243 | .BR cxl_errinfo_read (3), 244 | .BR cxl_errinfo_size (3), 245 | .BR cxl_event_pending (3), 246 | .BR cxl_for_each_adapter (3), 247 | .BR cxl_for_each_adapter_afu (3), 248 | .BR cxl_for_each_afu (3), 249 | .BR cxl_fprint_event (3), 250 | .BR cxl_fprint_unknown_event (3), 251 | .BR cxl_get_api_version (3), 252 | .BR cxl_get_api_version_compatible (3), 253 | .BR cxl_get_base_image (3), 254 | .BR cxl_get_caia_version (3), 255 | .BR cxl_get_cr_class (3), 256 | .BR cxl_get_cr_device (3), 257 | .BR cxl_get_cr_vendor (3), 258 | .BR cxl_get_image_loaded (3), 259 | .BR cxl_get_irqs_max (3), 260 | .BR cxl_get_irqs_min (3), 261 | .BR cxl_get_mmio_size (3), 262 | .BR cxl_get_mode (3), 263 | .BR cxl_get_modes_supported (3), 264 | .BR cxl_get_pp_mmio_len (3), 265 | .BR cxl_get_pp_mmio_off (3), 266 | .BR cxl_get_prefault_mode (3), 267 | .BR cxl_get_psl_revision (3), 268 | .BR cxl_get_psl_timebase_synced (3), 269 | .BR cxl_get_tunneled_ops_supported (3), 270 | .BR cxl_mmio_install_sigbus_handler (3), 271 | .BR cxl_mmio_map (3), 272 | .BR cxl_mmio_ptr (3), 273 | .BR cxl_mmio_read32 (3), 274 | .BR cxl_mmio_read64 (3), 275 | .BR cxl_mmio_unmap (3), 276 | .BR cxl_mmio_write32 (3), 277 | .BR cxl_mmio_write64 (3), 278 | .BR cxl_read_event (3), 279 | .BR cxl_read_expected_event (3), 280 | .BR cxl_set_irqs_max (3), 281 | .BR cxl_set_mode (3), 282 | .BR cxl_set_prefault_mode (3) 283 | .BR cxl_work_alloc (3), 284 | .BR cxl_work_disable_wait (3), 285 | .BR cxl_work_enable_wait (3), 286 | .BR cxl_work_free (3), 287 | .BR cxl_work_get_amr (3), 288 | .BR cxl_work_get_num_irqs (3), 289 | .BR cxl_work_get_tid (3), 290 | .BR cxl_work_get_wed (3), 291 | .BR cxl_work_set_amr (3), 292 | .BR cxl_work_set_num_irqs (3), 293 | .BR cxl_work_set_wed (3) 294 | -------------------------------------------------------------------------------- /man3/cxl_adapter_afu_next.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ADAPTER_AFU_NEXT 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_adapter_afu_next \- iterate to the next AFU of a CXL adapter 6 | .PP 7 | cxl_for_each_adapter_afu \- iteration macro 8 | .SH SYNOPSIS 9 | .B #include 10 | .PP 11 | .B "struct cxl_afu_h *cxl_adapter_afu_next(struct cxl_adapter_h" 12 | .BI * adapter ", struct cxl_afu_h *" afu ); 13 | .SH DESCRIPTION 14 | .BR cxl_adapter_afu_next () 15 | returns an AFU handle describing the next AFU of the CXL 16 | .IR adapter . 17 | .PP 18 | When 19 | .I afu 20 | is NULL, then an AFU handle is allocated, and the first available 21 | AFU of 22 | .I adapter 23 | is returned. 24 | .PP 25 | When 26 | .I afu 27 | is the last AFU of the current 28 | .IR adapter , 29 | then the AFU handle is freed, 30 | .I errno 31 | is set to zero, and NULL is returned. 32 | Alternatively, the AFU handle can be freed explicitly with 33 | .BR cxl_afu_free (). 34 | .SH RETURN VALUE 35 | On success, an AFU handle is returned, or NULL is returned and 36 | .I errno 37 | is set to zero. 38 | On error, NULL is returned, and 39 | .I errno 40 | is set appropriately. 41 | .SH ERRORS 42 | .TP 43 | .B ENODEV 44 | Unsupported kernel CXL API. 45 | .TP 46 | .B ENOMEM 47 | Insufficient memory. 48 | .SH EXAMPLE 49 | The CXL library provides the following macro to enumerate the 50 | AFUs of a CXL adapter: 51 | .PP 52 | .nf 53 | #define cxl_for_each_adapter_afu(adapter, afu) \\ 54 | for (afu = cxl_adapter_afu_next(adapter, NULL); afu; \\ 55 | afu = cxl_adapter_afu_next(NULL, afu)) 56 | .fi 57 | .SH SEE ALSO 58 | .BR cxl (3), 59 | .BR cxl_adapter_next (3), 60 | .BR cxl_afu_dev_name (3), 61 | .BR cxl_afu_free (3), 62 | .BR cxl_afu_next (3), 63 | .BR cxl_afu_sysfs_pci (3), 64 | .BR cxl_get_mmio_size (3), 65 | .BR cxl_get_mode (3), 66 | .BR cxl_get_modes_supported (3), 67 | .BR cxl_get_pp_mmio_len (3), 68 | .BR cxl_get_pp_mmio_off (3), 69 | .BR cxl_get_prefault_mode (3), 70 | .BR cxl_set_mode (3), 71 | .BR cxl_set_prefault_mode (3) 72 | -------------------------------------------------------------------------------- /man3/cxl_adapter_dev_name.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ADAPTER_DEV_NAME 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_adapter_dev_name \- return the CXL adapter device name 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "char *cxl_adapter_dev_name(struct cxl_adapter_h" 10 | .BI * adapter ); 11 | .SH DESCRIPTION 12 | .BR cxl_adapter_dev_name () 13 | returns the basename of the device associated to the CXL adapter handle 14 | .IR adapter . 15 | The devices of the CXL adapters are named 16 | .BR card0 , 17 | .BR card1 , 18 | etc. 19 | .SH SEE ALSO 20 | .BR cxl (3), 21 | .BR cxl_adapter_next (3) 22 | -------------------------------------------------------------------------------- /man3/cxl_adapter_free.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ADAPTER_FREE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_adapter_free \- free the CXL adapter data structures 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "void cxl_adapter_free(struct cxl_adapter_h" 10 | .BI * adapter ); 11 | .SH DESCRIPTION 12 | .BR cxl_adapter_free () 13 | frees the CXL 14 | .I adapter 15 | handle, 16 | previously allocated by 17 | .BR cxl_adapter_next (), 18 | as well as its associated data structures and memory buffers. 19 | .SH SEE ALSO 20 | .BR cxl (3), 21 | .BR cxl_adapter_next (3) 22 | -------------------------------------------------------------------------------- /man3/cxl_adapter_next.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ADAPTER_NEXT 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_adapter_next \- iterate to the next CXL adapter 6 | .PP 7 | cxl_for_each_adapter \- iteration macro 8 | .SH SYNOPSIS 9 | .B #include 10 | .PP 11 | .B "struct cxl_adapter_h *cxl_adapter_next(struct cxl_adapter_h" 12 | .BI * adapter ); 13 | .SH DESCRIPTION 14 | .BR cxl_adapter_next () 15 | returns an adapter handle describing the next available CXL 16 | adapter. 17 | .PP 18 | When 19 | .I adapter 20 | is NULL, then an adapter handle is allocated, and the first available 21 | adapter is returned. 22 | .PP 23 | When 24 | .I adapter 25 | is the last CXL adapter available, then the adapter handle is freed, 26 | .I errno 27 | is set to zero, and NULL is returned. 28 | Alternatively, the adapter handle can be freed explicitly with 29 | .BR cxl_adapter_free (). 30 | .SH RETURN VALUE 31 | On success, an adapter handle is returned, or NULL is returned and 32 | .I errno 33 | is set to zero. 34 | On error, NULL is returned, and 35 | .I errno 36 | is set appropriately. 37 | .SH ERRORS 38 | .TP 39 | .B ENODEV 40 | Unsupported kernel CXL API. 41 | .TP 42 | .B ENOMEM 43 | Insufficient memory. 44 | .SH EXAMPLE 45 | The CXL library provides the following macro to enumerate all 46 | CXL adapters: 47 | .PP 48 | .nf 49 | #define cxl_for_each_adapter(adapter) \\ 50 | for (adapter = cxl_adapter_next(NULL); adapter; \\ 51 | adapter = cxl_adapter_next(adapter)) 52 | .fi 53 | .SH SEE ALSO 54 | .BR cxl (3), 55 | .BR cxl_adapter_afu_next (3), 56 | .BR cxl_adapter_dev_name (3), 57 | .BR cxl_adapter_free (3), 58 | .BR cxl_afu_next (3), 59 | .BR cxl_get_base_image (3), 60 | .BR cxl_get_caia_version (3), 61 | .BR cxl_get_image_loaded (3), 62 | .BR cxl_get_psl_revision (3), 63 | .BR cxl_get_psl_timebase_synced (3), 64 | .BR cxl_get_tunneled_ops_supported (3) 65 | -------------------------------------------------------------------------------- /man3/cxl_afu_attach.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_ATTACH 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_attach \- attach the calling process's memory to an open AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_attach(struct cxl_afu_h" 10 | .BI * afu ", __u64 " wed ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_attach () 13 | attaches a context of 14 | .I afu 15 | to the current process, specifies 16 | .I wed 17 | as the initial work element descriptor, and starts the AFU context. 18 | .PP 19 | On success, all memory mapped into this process is accessible to the 20 | AFU context using the same effective addresses. 21 | No additional calls are required to map/unmap memory. 22 | The AFU memory context will be updated as userspace allocates and 23 | frees memory. 24 | .PP 25 | The work element descriptor 26 | .I wed 27 | is a 64-bit argument defined by the AFU. 28 | Typically this is an effective address pointing to an AFU specific 29 | structure describing what work to perform. 30 | .PP 31 | The minimum number of userspace interrupts required by the AFU 32 | will be allocated. 33 | This value is returned by 34 | .BR cxl_get_irqs_min (). 35 | .SH RETURN VALUE 36 | On success, 0 is returned. 37 | On error, \-1 is returned and 38 | .I errno 39 | is set appropriately. 40 | .SH ERRORS 41 | .TP 42 | .B EBUSY 43 | Process Element Command timeout. 44 | .TP 45 | .B EINVAL 46 | Invalid argument value, or AFU not opened. 47 | .TP 48 | .B EIO 49 | Device link down. 50 | .TP 51 | .B ENOMEM 52 | Not enough memory. 53 | .TP 54 | .B ENOSPC 55 | Not enough interrupts available. 56 | .SH SEE ALSO 57 | .BR cxl (3), 58 | .BR cxl_afu_attach_full (3), 59 | .BR cxl_afu_attach_work (3), 60 | .BR cxl_afu_fd_to_h (3), 61 | .BR cxl_afu_free (3), 62 | .BR cxl_afu_open_dev (3), 63 | .BR cxl_afu_opened (3), 64 | .BR cxl_get_irqs_max (3), 65 | .BR cxl_get_irqs_min (3), 66 | .BR cxl_get_prefault_mode (3), 67 | .BR cxl_mmio_map (3), 68 | .BR cxl_set_mode (3), 69 | .BR cxl_set_prefault_mode (3) 70 | -------------------------------------------------------------------------------- /man3/cxl_afu_attach_full.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_ATTACH_FULL 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_attach_full \- attach the calling process's memory to an open AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_attach_full(struct cxl_afu_h" 10 | .BI * afu ", __u64 " wed , 11 | .BI "__u16 " num_interrupts ", __u64 " amr ); 12 | .SH DESCRIPTION 13 | .BR cxl_afu_attach_full () 14 | attaches a context of 15 | .I afu 16 | to the current process, specifies 17 | .I wed 18 | as the initial work element descriptor, requests 19 | .IR num_interrupts , 20 | sets the authority mask register 21 | .IR amr , 22 | and starts the AFU context. 23 | .PP 24 | On success, all memory mapped into this process is accessible to the 25 | AFU context using the same effective addresses. 26 | No additional calls are required to map/unmap memory. 27 | The AFU memory context will be updated as userspace allocates and 28 | frees memory. 29 | .PP 30 | The work element descriptor 31 | .I wed 32 | is a 64-bit argument defined by the AFU. 33 | Typically this is an effective address pointing to an AFU specific 34 | structure describing what work to perform. 35 | .PP 36 | The number of requested userspace interrupts 37 | .I num_interrupts 38 | must be in the range defined by 39 | .BR cxl_get_irqs_min () 40 | and 41 | .BR cxl_get_irqs_max (). 42 | .PP 43 | The authority mask register 44 | .I amr 45 | is the same as the powerpc AMR. 46 | .SH RETURN VALUE 47 | On success, 0 is returned. 48 | On error, \-1 is returned and 49 | .I errno 50 | is set appropriately. 51 | .SH ERRORS 52 | .TP 53 | .B EBUSY 54 | Process Element Command timeout. 55 | .TP 56 | .B EINVAL 57 | Invalid argument value, or AFU not opened. 58 | .TP 59 | .B EIO 60 | Device link down. 61 | .TP 62 | .B ENOMEM 63 | Not enough memory. 64 | .TP 65 | .B ENOSPC 66 | Not enough interrupts available. 67 | .SH SEE ALSO 68 | .BR cxl (3), 69 | .BR cxl_afu_attach (3), 70 | .BR cxl_afu_attach_work (3), 71 | .BR cxl_afu_fd_to_h (3), 72 | .BR cxl_afu_free (3), 73 | .BR cxl_afu_open_dev (3), 74 | .BR cxl_afu_opened (3), 75 | .BR cxl_get_irqs_max (3), 76 | .BR cxl_get_irqs_min (3), 77 | .BR cxl_get_prefault_mode (3), 78 | .BR cxl_mmio_map (3), 79 | .BR cxl_set_irqs_max (3), 80 | .BR cxl_set_mode (3), 81 | .BR cxl_set_prefault_mode (3) 82 | -------------------------------------------------------------------------------- /man3/cxl_afu_attach_work.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2018 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_ATTACH_WORK 3 2018-02-13 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_attach_work \- attach the calling process's memory to an open AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_attach_work(struct cxl_afu_h" 10 | .BI * afu ", struct cxl_ioctl_start_work *" work ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_attach_work () 13 | attaches a context of 14 | .I afu 15 | to the current process, specifying various parameters via the 16 | .I work 17 | structure, and starts the AFU context. 18 | .PP 19 | On success, all memory mapped into this process is accessible to the 20 | AFU context using the same effective addresses. 21 | No additional calls are required to map/unmap memory. 22 | The AFU memory context will be updated as userspace allocates and 23 | frees memory. 24 | .PP 25 | Four parameters can be set in the 26 | .I work 27 | structure: 28 | .PP 29 | .BR cxl_work_set_wed () 30 | sets the work element descriptor, a 64-bit argument defined by the AFU. 31 | Typically this is an effective address pointing to an AFU specific 32 | structure describing what work to perform. 33 | .PP 34 | .BR cxl_work_set_num_irqs () 35 | requests a number of userspace interrupts, 36 | in the range defined by 37 | .BR cxl_get_irqs_min () 38 | and 39 | .BR cxl_get_irqs_max (). 40 | A negative value specifies that 41 | .BR cxl_afu_attach_work () 42 | should allocate the minimum number of interrupts required 43 | by an AFU context, returned by 44 | .BR cxl_get_irqs_min (). 45 | .PP 46 | .BR cxl_work_set_amr () 47 | sets the authority mask register (same as the powerpc AMR). 48 | A null value indicates that the authority mask register 49 | should not be set. 50 | .PP 51 | .BR cxl_work_enable_wait() 52 | indicates that the thread that will attach an AFU context 53 | requires to be able to wait and be notified by the AFU with 54 | .BR cxl_afu_host_thread_wait (). 55 | .SH RETURN VALUE 56 | On success, 0 is returned. 57 | On error, \-1 is returned and 58 | .I errno 59 | is set appropriately. 60 | .SH ERRORS 61 | .TP 62 | .B EBUSY 63 | Process Element Command timeout. 64 | .TP 65 | .B EINVAL 66 | Invalid argument value, or AFU not opened. 67 | .TP 68 | .B EIO 69 | Device link down. 70 | .TP 71 | .B ENOMEM 72 | Not enough memory. 73 | .TP 74 | .B ENOSPC 75 | Not enough interrupts available. 76 | .SH SEE ALSO 77 | .BR cxl (3), 78 | .BR cxl_afu_attach (3), 79 | .BR cxl_afu_attach_full (3), 80 | .BR cxl_afu_fd_to_h (3), 81 | .BR cxl_afu_free (3), 82 | .BR cxl_afu_host_thread_wait(3), 83 | .BR cxl_afu_open_dev (3), 84 | .BR cxl_afu_opened (3), 85 | .BR cxl_get_irqs_max (3), 86 | .BR cxl_get_irqs_min (3), 87 | .BR cxl_get_prefault_mode (3), 88 | .BR cxl_mmio_map (3), 89 | .BR cxl_set_irqs_max (3), 90 | .BR cxl_set_mode (3), 91 | .BR cxl_set_prefault_mode (3), 92 | .BR cxl_work_alloc (3), 93 | .BR cxl_work_disable_wait (3), 94 | .BR cxl_work_enable_wait (3), 95 | .BR cxl_work_free (3), 96 | .BR cxl_work_get_amr (3), 97 | .BR cxl_work_get_num_irqs (3), 98 | .BR cxl_work_get_tid (3), 99 | .BR cxl_work_get_wed (3), 100 | .BR cxl_work_set_amr (3), 101 | .BR cxl_work_set_num_irqs (3), 102 | .BR cxl_work_set_wed (3) 103 | -------------------------------------------------------------------------------- /man3/cxl_afu_dev_name.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_DEV_NAME 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_dev_name \- return the AFU device name 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "char *cxl_afu_dev_name(struct cxl_afu_h" 10 | .BI * afu ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_dev_name () 13 | returns the basename of the device associated to 14 | .IR afu . 15 | The AFU devices of the CXL adapter 16 | .BI card 17 | are named 18 | .BI afu .0 \fR, 19 | .BI afu .1 \fR, 20 | etc. 21 | AFUs opened in dedicated process mode, or AFU directed mode 22 | in master or slave context, are respectly suffixed with 23 | .BR d , 24 | .BR m , 25 | and 26 | .BR s . 27 | .SH FILES 28 | .TP 29 | .BI /dev/cxl/afu . d 30 | AFU device in dedicated process mode. 31 | .TP 32 | .BI /dev/cxl/afu . m 33 | AFU device in AFU directed mode, master context. 34 | .TP 35 | .BI /dev/cxl/afu . s 36 | AFU device in AFU directed mode, slave context. 37 | .SH SEE ALSO 38 | .BR cxl (3), 39 | .BR cxl_adapter_afu_next (3), 40 | .BR cxl_afu_fd (3), 41 | .BR cxl_afu_fd_to_h (3), 42 | .BR cxl_afu_get_process_element (3), 43 | .BR cxl_afu_next (3), 44 | .BR cxl_afu_open_dev (3), 45 | .BR cxl_afu_open_h (3), 46 | .BR cxl_afu_opened (3), 47 | .BR cxl_afu_sysfs_pci (3) 48 | -------------------------------------------------------------------------------- /man3/cxl_afu_fd.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_FD 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_fd \- return the file descriptor of an AFU handle 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_fd(struct cxl_afu_h" 10 | .BI * afu ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_fd () 13 | returns the file descriptor of an open AFU, 14 | or \-1 if 15 | .I afu 16 | has not been opened. 17 | .SH SEE ALSO 18 | .BR cxl (3), 19 | .BR cxl_afu_dev_name (3), 20 | .BR cxl_afu_fd_to_h (3), 21 | .BR cxl_afu_free (3), 22 | .BR cxl_afu_get_process_element (3), 23 | .BR cxl_afu_open_dev (3), 24 | .BR cxl_afu_open_h (3), 25 | .BR cxl_afu_opened (3) 26 | -------------------------------------------------------------------------------- /man3/cxl_afu_fd_to_h.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_FD_TO_H 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_fd_to_h \- create an AFU handle from the file descriptor of an already open AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "struct cxl_afu_h cxl_afu_fd_to_h(int" 10 | .IB fd ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_fd_to_h () 13 | returns an AFU handle from the already open AFU device associated to the 14 | file descriptor 15 | .IR fd . 16 | .PP 17 | A dedicated process mode AFU only has one context and only allows 18 | the device to be opened once. 19 | An AFU directed mode AFU can have many contexts, the device can 20 | be opened once for each context that is available. 21 | .SH RETURN VALUE 22 | On success, an AFU handle is returned. 23 | On error, NULL is returned, and 24 | .I errno 25 | is set appropriately. 26 | .SH ERRORS 27 | .TP 28 | .B EBADF 29 | Bad file descriptor. 30 | .TP 31 | .B ENODEV 32 | Kernel does not support CXL devices, or device is not an AFU. 33 | .TP 34 | .B ENOMEM 35 | Insufficient memory. 36 | .TP 37 | .B ENOSPC 38 | No AFU context available. 39 | .TP 40 | .B EPROTO 41 | Unsupported kernel CXL API version. 42 | .SH FILES 43 | .TP 44 | .BI /dev/cxl/afu . d 45 | AFU device in dedicated process mode. 46 | .TP 47 | .BI /dev/cxl/afu . m 48 | AFU device in AFU directed mode, master context. 49 | .TP 50 | .BI /dev/cxl/afu . s 51 | AFU device in AFU directed mode, slave context. 52 | .SH SEE ALSO 53 | .BR cxl (3), 54 | .BR cxl_afu_attach (3), 55 | .BR cxl_afu_attach_work (3), 56 | .BR cxl_afu_attach_full (3), 57 | .BR cxl_afu_dev_name (3), 58 | .BR cxl_afu_fd (3), 59 | .BR cxl_afu_free (3), 60 | .BR cxl_afu_get_process_element (3), 61 | .BR cxl_afu_open_dev (3), 62 | .BR cxl_afu_open_h (3), 63 | .BR cxl_afu_opened (3), 64 | .BR cxl_get_api_version (3), 65 | .BR cxl_get_api_version_compatible (3), 66 | .BR cxl_get_cr_class (3), 67 | .BR cxl_get_cr_device (3), 68 | .BR cxl_get_cr_vendor (3), 69 | .BR cxl_get_mode (3), 70 | .BR cxl_get_modes_supported (3), 71 | .BR cxl_read_event (3), 72 | .BR cxl_read_expected_event (3), 73 | .BR cxl_set_mode (3), 74 | .BR open (2) 75 | -------------------------------------------------------------------------------- /man3/cxl_afu_free.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_FREE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_free \- free the data structures of an AFU handle 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "void cxl_afu_free(struct cxl_afu_h" 10 | .BI * afu ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_free () 13 | frees the data structures and memory buffers of 14 | .IR afu . 15 | .SH SEE ALSO 16 | .BR cxl (3), 17 | .BR cxl_adapter_afu_next (3), 18 | .BR cxl_afu_attach (3), 19 | .BR cxl_afu_attach_full (3), 20 | .BR cxl_afu_attach_work (3), 21 | .BR cxl_afu_fd (3), 22 | .BR cxl_afu_fd_to_h (3), 23 | .BR cxl_afu_next (3), 24 | .BR cxl_afu_open_dev (3), 25 | .BR cxl_afu_open_h (3), 26 | .BR cxl_afu_opened (3) 27 | -------------------------------------------------------------------------------- /man3/cxl_afu_get_process_element.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_GET_PROCESS_ELEMENT 3 2017-05-24 "LIBCXL 1.5" "CXL Manual" 4 | .SH NAME 5 | cxl_afu_get_process_element \- get the process element associated with an open AFU handle 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .BI "int cxl_afu_get_process_element(struct cxl_afu_h *" afu ); 10 | .SH DESCRIPTION 11 | .BR cxl_afu_get_process_element () 12 | returns the process element number associated with the open 13 | .IR afu . 14 | .SH RETURN VALUE 15 | On success, the process element number is returned. 16 | On error, \-1 is returned and 17 | .I errno 18 | is set appropriately. 19 | .SH ERRORS 20 | .TP 21 | .B EINVAL 22 | Invalid argument value. 23 | .TP 24 | .B EIO 25 | AFU not opened. 26 | .SH SEE ALSO 27 | .BR cxl (3), 28 | .BR cxl_afu_dev_name (3), 29 | .BR cxl_afu_fd (3), 30 | .BR cxl_afu_fd_to_h (3), 31 | .BR cxl_afu_open_dev (3), 32 | .BR cxl_afu_open_h (3), 33 | .BR cxl_afu_opened (3) 34 | -------------------------------------------------------------------------------- /man3/cxl_afu_host_thread_wait.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2018 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_HOST_THREAD_WAIT 3 2018-04-24 "LIBCXL 1.6" "CXL Manual" 4 | .SH NAME 5 | cxl_afu_host_thread_wait \- wait for AFU notification 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_host_thread_wait(struct cxl_afu_h" 10 | .BI * afu ", volatile __u64 *" uword ); 11 | .SH DESCRIPTION 12 | The tunneled operation as_notify is supported on POWER9. See 13 | .BR cxl_get_tunneled_ops_supported (). 14 | .PP 15 | The thread calling 16 | .BR cxl_afu_host_thread_wait () 17 | executes the instruction "wait" and goes to sleep. 18 | It will resume execution upon receiving an interrupt or an 19 | .I afu 20 | notification. It will then check the value 21 | of the shared memory word pointed to by 22 | .IR uword . 23 | The thread will loop and sleep again while the value of 24 | .I uword 25 | is equal to zero. It will return from 26 | .BR cxl_afu_host_thread_wait () 27 | when the value of 28 | .I uword 29 | becomes different from zero. 30 | .PP 31 | The thread calling 32 | .BR cxl_afu_host_thread_wait () 33 | must have attached an 34 | .I afu 35 | context to a work structure with 36 | .BR cxl_afu_attach_work () 37 | The work structure must have been wait-enabled with 38 | .BR cxl_work_enable_wait (). 39 | .SH RETURN VALUE 40 | On success, 0 is returned. 41 | On error, \-1 is returned and 42 | .I errno 43 | is set appropriately. 44 | .SH ERRORS 45 | .TP 46 | .B EINVAL 47 | Invalid argument value 48 | .TP 49 | .B EPERM 50 | AFU context not attached by current thread, or wait not enabled 51 | .SH SEE ALSO 52 | .BR cxl (3), 53 | .BR cxl_afu_attach_work (3), 54 | .BR cxl_afu_host_thread_wait (3), 55 | .BR cxl_get_tunneled_ops_supported (3), 56 | .BR cxl_work_disable_wait (3), 57 | .BR cxl_work_enable_wait (3), 58 | .BR cxl_work_get_tid (3) 59 | -------------------------------------------------------------------------------- /man3/cxl_afu_next.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_NEXT 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_next \- iterate to the next AFU 6 | .PP 7 | cxl_for_each_afu \- iteration macro 8 | .SH SYNOPSIS 9 | .B #include 10 | .PP 11 | .B "struct cxl_afu_h *cxl_afu_next(struct cxl_afu_h" 12 | .BI * afu ); 13 | .SH DESCRIPTION 14 | .BR cxl_afu_next () 15 | returns an AFU handle describing the next available AFU. 16 | .PP 17 | When 18 | .I afu 19 | is NULL, then an AFU handle is allocated, and the first available 20 | AFU is returned. 21 | .PP 22 | When 23 | .I afu 24 | is the last AFU available, then the AFU handle is freed, 25 | .I errno 26 | is set to zero, and NULL is returned. 27 | Alternatively, the AFU handle can be freed explicitly with 28 | .BR cxl_afu_free (). 29 | .SH RETURN VALUE 30 | On success, an AFU handle is returned, or NULL is returned and 31 | .I errno 32 | is set to zero. 33 | On error, NULL is returned, and 34 | .I errno 35 | is set appropriately. 36 | .SH ERRORS 37 | .TP 38 | .B ENODEV 39 | Kernel does not support CXL devices. 40 | .TP 41 | .B ENOMEM 42 | Insufficient memory. 43 | .SH EXAMPLE 44 | The CXL library provides the following macro to enumerate all AFUs: 45 | .PP 46 | .nf 47 | #define cxl_for_each_afu(afu) \\ 48 | for (afu = cxl_afu_next(NULL); afu; afu = cxl_afu_next(afu)) 49 | .fi 50 | .SH SEE ALSO 51 | .BR cxl (3), 52 | .BR cxl_adapter_afu_next (3), 53 | .BR cxl_adapter_next (3), 54 | .BR cxl_afu_dev_name (3), 55 | .BR cxl_afu_free (3), 56 | .BR cxl_afu_sysfs_pci (3), 57 | .BR cxl_get_mmio_size (3), 58 | .BR cxl_get_mode (3), 59 | .BR cxl_get_modes_supported (3), 60 | .BR cxl_get_pp_mmio_len (3), 61 | .BR cxl_get_pp_mmio_off (3), 62 | .BR cxl_get_prefault_mode (3), 63 | .BR cxl_set_mode (3), 64 | .BR cxl_set_prefault_mode (3) 65 | -------------------------------------------------------------------------------- /man3/cxl_afu_open_dev.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_OPEN_DEV 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_open_dev \- open an AFU by device name 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "struct cxl_afu_h cxl_afu_open_dev(char" 10 | .BI * path ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_open_dev () 13 | opens the device 14 | .I path 15 | and returns an AFU handle. 16 | .PP 17 | A dedicated process mode AFU only has one context and only allows 18 | the device to be opened once. 19 | An AFU directed mode AFU can have many contexts, the device can 20 | be opened once for each context that is available. 21 | .SH RETURN VALUE 22 | On success, an AFU handle is returned. 23 | On error, NULL is returned, and 24 | .I errno 25 | is set appropriately. 26 | .SH ERRORS 27 | .TP 28 | .B ENODEV 29 | Kernel does not support CXL devices, or device is not an AFU. 30 | .TP 31 | .B ENOENT 32 | Device does not exist. 33 | .TP 34 | .B ENOMEM 35 | Insufficient memory. 36 | .TP 37 | .B ENOSPC 38 | No AFU context available. 39 | .TP 40 | .B EPROTO 41 | Unsupported kernel CXL API version. 42 | .SH FILES 43 | .TP 44 | .BI /dev/cxl/afu . d 45 | AFU device in dedicated process mode. 46 | .TP 47 | .BI /dev/cxl/afu . m 48 | AFU device in AFU directed mode, master context. 49 | .TP 50 | .BI /dev/cxl/afu . s 51 | AFU device in AFU directed mode, slave context. 52 | .SH SEE ALSO 53 | .BR cxl (3), 54 | .BR cxl_afu_attach (3), 55 | .BR cxl_afu_attach_full (3), 56 | .BR cxl_afu_attach_work (3), 57 | .BR cxl_afu_dev_name (3), 58 | .BR cxl_afu_fd (3), 59 | .BR cxl_afu_fd_to_h (3), 60 | .BR cxl_afu_free (3), 61 | .BR cxl_afu_get_process_element (3), 62 | .BR cxl_afu_open_h (3), 63 | .BR cxl_afu_opened (3), 64 | .BR cxl_get_api_version (3), 65 | .BR cxl_get_api_version_compatible (3), 66 | .BR cxl_get_cr_class (3), 67 | .BR cxl_get_cr_device (3), 68 | .BR cxl_get_cr_vendor (3), 69 | .BR cxl_get_mode (3), 70 | .BR cxl_get_modes_supported (3), 71 | .BR cxl_read_event (3), 72 | .BR cxl_read_expected_event (3), 73 | .BR cxl_set_mode (3), 74 | .BR open (2) 75 | -------------------------------------------------------------------------------- /man3/cxl_afu_open_h.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_OPEN_H 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_open_h \- open an AFU by AFU handle 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "struct cxl_afu_h cxl_afu_open_h(struct cxl_afu_h" 10 | .BI * afu ", enum cxl_views " view ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_open_h () 13 | opens the device and returns a new AFU handle for 14 | .IR afu , 15 | as specified by the CXL 16 | .IR view : 17 | .TP 18 | .B CXL_VIEW_DEDICATED 19 | AFU opened in dedicated process mode, 20 | .TP 21 | .B CXL_VIEW_MASTER 22 | AFU opened in AFU directed mode, master context, 23 | .TP 24 | .B CXL_VIEW_SLAVE 25 | AFU opened in AFU directed mode, slave context. 26 | .PP 27 | A dedicated process mode AFU only has one context and only allows 28 | the device to be opened once. 29 | An AFU directed mode AFU can have many contexts, the device can 30 | be opened once for each context that is available. 31 | .SH RETURN VALUE 32 | On success, an AFU handle is returned. 33 | On error, NULL is returned, and 34 | .I errno 35 | is set appropriately. 36 | .SH ERRORS 37 | .TP 38 | .B ENODEV 39 | The AFU does not support this view. 40 | .TP 41 | .B ENOMEM 42 | Insufficient memory. 43 | .TP 44 | .B ENOSPC 45 | No AFU context available. 46 | .TP 47 | .B EPROTO 48 | Unsupported kernel CXL API version. 49 | .SH FILES 50 | .TP 51 | .BI /dev/cxl/afu . d 52 | AFU device in dedicated process mode. 53 | .TP 54 | .BI /dev/cxl/afu . m 55 | AFU device in AFU directed mode, master context. 56 | .TP 57 | .BI /dev/cxl/afu . s 58 | AFU device in AFU directed mode, slave context. 59 | .SH SEE ALSO 60 | .BR cxl (3), 61 | .BR cxl_afu_dev_name (3), 62 | .BR cxl_afu_fd (3), 63 | .BR cxl_afu_fd_to_h (3), 64 | .BR cxl_afu_free (3), 65 | .BR cxl_afu_get_process_element (3), 66 | .BR cxl_afu_open_dev (3), 67 | .BR cxl_afu_opened (3), 68 | .BR cxl_get_api_version (3), 69 | .BR cxl_get_api_version_compatible (3), 70 | .BR cxl_get_cr_class (3), 71 | .BR cxl_get_cr_device (3), 72 | .BR cxl_get_cr_vendor (3), 73 | .BR cxl_get_mode (3), 74 | .BR cxl_get_modes_supported (3), 75 | .BR cxl_read_event (3), 76 | .BR cxl_read_expected_event (3), 77 | .BR cxl_set_mode (3), 78 | .BR open (2) 79 | -------------------------------------------------------------------------------- /man3/cxl_afu_opened.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_OPENED 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_opened \- return whether an AFU handle is opened 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_afu_opened(struct cxl_afu_h" 10 | .BI * afu ); 11 | .SH DESCRIPTION 12 | .BR cxl_afu_opened () 13 | returns 1 if 14 | .I afu 15 | is open, or else 0. 16 | .SH RETURN VALUE 17 | On success, 0 or 1 is returned. 18 | On error, \-1 is returned and 19 | .I errno 20 | is set appropriately. 21 | .SH ERRORS 22 | .TP 23 | .B EINVAL 24 | Invalid argument value. 25 | .SH SEE ALSO 26 | .BR cxl (3), 27 | .BR cxl_afu_attach (3), 28 | .BR cxl_afu_attach_full (3), 29 | .BR cxl_afu_attach_work (3), 30 | .BR cxl_afu_dev_name (3), 31 | .BR cxl_afu_fd (3), 32 | .BR cxl_afu_fd_to_h (3), 33 | .BR cxl_afu_free (3), 34 | .BR cxl_afu_get_process_element (3), 35 | .BR cxl_afu_open_dev (3), 36 | .BR cxl_afu_open_h (3), 37 | .BR cxl_read_event (3), 38 | .BR cxl_read_expected_event (3) 39 | -------------------------------------------------------------------------------- /man3/cxl_afu_sysfs_pci.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_AFU_SYSFS_PCI 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_afu_sysfs_pci \- get the sysfs path to the PCI device corresponding with 6 | an AFU 7 | .SH SYNOPSIS 8 | .B #include 9 | .PP 10 | .B "int cxl_afu_sysfs_pci(struct cxl_afu_h" 11 | .BI * afu ", char **" pathp ); 12 | .SH DESCRIPTION 13 | .BR cxl_afu_sysfs_pci () 14 | copies the address of a buffer containing the sysfs path to the 15 | PCI device corresponding with 16 | .I afu 17 | into the pointer 18 | .IR pathp . 19 | .PP 20 | On success, this function automatically allocates the returned 21 | buffer, which must be freed by the caller (much like asprintf). 22 | .SH RETURN VALUE 23 | On success, 0 is returned. 24 | On error, \-1 is returned and 25 | .I errno 26 | is set appropriately. 27 | .SH ERRORS 28 | .TP 29 | .B EINVAL 30 | Invalid argument value. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR asprintf (3), 36 | .BR cxl (3), 37 | .BR cxl_adapter_afu_next (3), 38 | .BR cxl_afu_dev_name (3), 39 | .BR cxl_afu_next (3), 40 | .BR free (3) 41 | -------------------------------------------------------------------------------- /man3/cxl_errinfo_read.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ERRINFO_READ 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_errinfo_read \- Read and copy the contents of afu_err_info buffer 6 | .SH SYNOPSIS 7 | .BR #include 8 | .PP 9 | .BI "ssize_t cxl_errinfo_read(struct cxl_afu_h " 10 | .BI * afu ", void *" dst ", off_t " off ", size_t " len ); 11 | .SH DESCRIPTION 12 | .PP 13 | .BR cxl_errinfo_read " attempts to read upto" 14 | .IR len " bytes located at offset " off " in " 15 | AFU Error Buffer and copy it to user provided buffer located at 16 | .IR dst "." 17 | .PP 18 | AFU Error Buffer is used by the afu to report 19 | application specific errors. 20 | The contents of this buffer are afu 21 | specific and are intended to be interpreted by the application 22 | interacting with the afu. 23 | .SH RETURN VALUE 24 | On success, returns the number of bytes copied from the afu_err_buff to 25 | .IB dst . 26 | 27 | On error, -1 is returned, 28 | .I errno 29 | is set appropriately and the contents at 30 | .I dst 31 | are not touched. 32 | .SH ERRORS 33 | .TP 34 | .B ENOENT 35 | The AFU does not export afu_err_buff region. 36 | .TP 37 | .B EACCES 38 | Permission to read the contents of AFU Error buffer is denied. 39 | .TP 40 | .B ENOMEM 41 | Insufficient memory. 42 | .TP 43 | .B ENOSPC 44 | No AFU context available. 45 | .TP 46 | .B EPROTO 47 | Unsupported kernel CXL API version. 48 | .SH FILES 49 | .TP 50 | .BI /dev/cxl/afu . d 51 | AFU device in dedicated process mode. 52 | .TP 53 | .BI /dev/cxl/afu . m 54 | AFU device in AFU directed mode, master context. 55 | .TP 56 | .BI /dev/cxl/afu . s 57 | AFU device in AFU directed mode, slave context. 58 | .TP 59 | .BI /dev/cxl/afu . /afu_err_buff 60 | AFU Error Buffer contents. The contents of this file are 61 | application specific and depends on the AFU being used. 62 | 63 | .SH SEE ALSO 64 | .BR cxl (3), 65 | .BR cxl_errinfo_size (3) 66 | -------------------------------------------------------------------------------- /man3/cxl_errinfo_size.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_ERRINFO_SIZE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_errinfo_size \- returns the size of afu_err_buff in bytes 6 | .SH SYNOPSIS 7 | .BR #include 8 | .PP 9 | .BI "int cxl_errinfo_size(struct cxl_afu_h " 10 | .BI * afu ", size_t *" valp ); 11 | .SH DESCRIPTION 12 | .PP 13 | .BR cxl_errinfo_size 14 | stores the size (in bytes) of the 15 | .B AFU Error Buffer 16 | associated with the provided 17 | .IB afu 18 | context handle at 19 | .IB valp . 20 | .PP 21 | Applications can also use this function to determine if the afu_err_buff 22 | exists for the attached 23 | .IR afu . 24 | .SH RETURN VALUE 25 | On success, 0 is returned and size of the buffer is stored at 26 | .I valp 27 | 28 | On error, -1 is returned, 29 | .I errno 30 | is set appropriately and the contents at 31 | .I valp 32 | are not touched 33 | .SH ERRORS 34 | .TP 35 | .B ENOENT 36 | The AFU does not export afu_err_buff region. 37 | .TP 38 | .B EACCES 39 | Permission to read the contents of AFU Error buffer is denied. 40 | .TP 41 | .B ENOMEM 42 | Insufficient memory. 43 | .TP 44 | .B ENOSPC 45 | No AFU context available. 46 | .TP 47 | .B EPROTO 48 | Unsupported kernel CXL API version. 49 | .SH FILES 50 | .TP 51 | .BI /dev/cxl/afu . d 52 | AFU device in dedicated process mode. 53 | .TP 54 | .BI /dev/cxl/afu . m 55 | AFU device in AFU directed mode, master context. 56 | .TP 57 | .BI /dev/cxl/afu . s 58 | AFU device in AFU directed mode, slave context. 59 | .TP 60 | .BI /dev/cxl/afu . /afu_err_buff 61 | AFU Error Buffer contents. The contents of this file are 62 | application specific and depends on the AFU being used. 63 | 64 | .SH SEE ALSO 65 | .BR cxl (3), 66 | .BR cxl_errinfo_read (3) 67 | -------------------------------------------------------------------------------- /man3/cxl_event_pending.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_EVENT_PENDING 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_event_pending \- return whether a CXL event is pending 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_event_pending(struct cxl_afu_h" 10 | .BI * afu ); 11 | .SH DESCRIPTION 12 | .BR cxl_event_pending () 13 | returns 1 if a CXL event can be read from 14 | .IR afu , 15 | or else 0. 16 | .SH RETURN VALUE 17 | On success, 0 or 1 is returned. 18 | On error, \-1 is returned and 19 | .I errno 20 | is set appropriately. 21 | .SH ERRORS 22 | .TP 23 | .B EINVAL 24 | Invalid argument value. 25 | .SH SEE ALSO 26 | .BR cxl (3), 27 | .BR cxl_fprint_event (3), 28 | .BR cxl_fprint_unknown_event (3), 29 | .BR cxl_read_event (3), 30 | .BR cxl_read_expected_event (3) 31 | -------------------------------------------------------------------------------- /man3/cxl_for_each_adapter.3: -------------------------------------------------------------------------------- 1 | .so man3/cxl_adapter_next.3 2 | -------------------------------------------------------------------------------- /man3/cxl_for_each_adapter_afu.3: -------------------------------------------------------------------------------- 1 | .so man3/cxl_adapter_afu_next.3 2 | -------------------------------------------------------------------------------- /man3/cxl_for_each_afu.3: -------------------------------------------------------------------------------- 1 | .so man3/cxl_afu_next.3 2 | -------------------------------------------------------------------------------- /man3/cxl_fprint_event.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_FPRINT_EVENT 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_fprint_event \- print out a description of a CXL event for debugging 6 | .SH SYNOPSIS 7 | .B #include 8 | .br 9 | .B #include 10 | .PP 11 | .BI "int cxl_fprint_event(FILE *" stream , 12 | .BI "struct cxl_event *" event ); 13 | .SH DESCRIPTION 14 | .BR cxl_fprint_event () 15 | prints out a description of the CXL 16 | .I event 17 | to the file 18 | .IR stream . 19 | .PP 20 | The description is based on the event type. 21 | If the type is unknown, then 22 | .BR cxl_fprint_event () 23 | calls 24 | .BR cxl_fprint_unknown_event () 25 | instead, and prints out a hex dump of the raw event. 26 | .SH RETURN VALUE 27 | On success, the number of bytes written to 28 | .I stream 29 | is returned. 30 | On error, \-1 is returned and 31 | .I errno 32 | is set appropriately. 33 | .SH ERRORS 34 | .TP 35 | .B EINVAL 36 | Invalid argument value. 37 | .TP 38 | .B ENODATA 39 | No data available. 40 | .SH SEE ALSO 41 | .BR cxl (3), 42 | .BR cxl_fprint_unknown_event (3), 43 | .BR cxl_event_pending (3), 44 | .BR cxl_read_event (3), 45 | .BR cxl_read_expected_event (3) 46 | -------------------------------------------------------------------------------- /man3/cxl_fprint_unknown_event.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_FPRINT_UNKNOWN_EVENT 3 2017-05-24 "LIBCXL 1.5" "CXL Manual" 4 | .SH NAME 5 | cxl_fprint_unknown_event \- print out a hex dump of a raw CXL event for debugging 6 | .SH SYNOPSIS 7 | .B #include 8 | .br 9 | .B #include 10 | .PP 11 | .BI "int cxl_fprint_unknown_event(FILE *" stream , 12 | .BI "struct cxl_event *" event ); 13 | .SH DESCRIPTION 14 | .BR cxl_fprint_unknown_event () 15 | prints out a hex dump of the raw CXL 16 | .I event 17 | to the file 18 | .IR stream . 19 | .SH RETURN VALUE 20 | On success, the number of bytes written to 21 | .I stream 22 | is returned. 23 | On error, \-1 is returned and 24 | .I errno 25 | is set appropriately. 26 | .SH ERRORS 27 | .TP 28 | .B EINVAL 29 | Invalid argument value. 30 | .SH SEE ALSO 31 | .BR cxl (3), 32 | .BR cxl_fprint_event (3), 33 | .BR cxl_event_pending (3), 34 | .BR cxl_read_event (3), 35 | .BR cxl_read_expected_event (3) 36 | -------------------------------------------------------------------------------- /man3/cxl_get_api_version.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_API_VERSION 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_api_version \- get the version of the kernel CXL API 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_api_version(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_api_version () 13 | copies the CXL API version of 14 | .I afu 15 | to the long integer pointed to by 16 | .IR valp . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .TP 27 | .B ENOMEM 28 | Insufficient memory. 29 | .SH SEE ALSO 30 | .BR cxl (3), 31 | .BR cxl_afu_fd_to_h (3), 32 | .BR cxl_afu_open_dev (3), 33 | .BR cxl_afu_open_h (3), 34 | .BR cxl_get_api_version_compatible (3), 35 | .BR cxl_get_mode (3), 36 | .BR cxl_get_modes_supported (3), 37 | .BR cxl_get_prefault_mode (3) 38 | -------------------------------------------------------------------------------- /man3/cxl_get_api_version_compatible.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_API_VERSION_COMPATIBLE 3 2017-05-24 "LIBCXL 1.5" "CXL Manual" 4 | .SH NAME 5 | cxl_get_api_version_compatible \- get the lowest CXL API version compatible with the kernel 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_api_version_compatible(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_api_version_compatible () 13 | copies the lowest CXL API version compatible with the kernel, 14 | supported by 15 | .IR afu , 16 | to the long integer pointed to by 17 | .IR valp . 18 | .SH RETURN VALUE 19 | On success, 0 is returned. 20 | On error, \-1 is returned and 21 | .I errno 22 | is set appropriately. 23 | .SH ERRORS 24 | .TP 25 | .B EINVAL 26 | Invalid argument value. 27 | .TP 28 | .B ENOMEM 29 | Insufficient memory. 30 | .SH SEE ALSO 31 | .BR cxl (3), 32 | .BR cxl_afu_fd_to_h (3), 33 | .BR cxl_afu_open_dev (3), 34 | .BR cxl_afu_open_h (3), 35 | .BR cxl_get_api_version (3), 36 | .BR cxl_get_mode (3), 37 | .BR cxl_get_modes_supported (3), 38 | .BR cxl_get_prefault_mode (3) 39 | -------------------------------------------------------------------------------- /man3/cxl_get_base_image.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_BASE_IMAGE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_base_image \- get the revision level of the initial PSL image loaded on the CXL device 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_base_image(struct cxl_adapter_h" 10 | .BI * adapter ", long *" valp ); 11 | .SH DESCRIPTION 12 | For CXL devices that support loadable PSLs, 13 | .BR cxl_get_base_image () 14 | identifies the revision level of the base image. 15 | For FPGAs, this attribute identifies the image contained in the 16 | on-card flash which is loaded during the initial program load. 17 | The 18 | .I adapter 19 | base image revision level is copied to the long integer 20 | pointed to by 21 | .IR valp . 22 | .SH RETURN VALUE 23 | On success, 0 is returned. 24 | On error, \-1 is returned and 25 | .I errno 26 | is set appropriately. 27 | .SH ERRORS 28 | .TP 29 | .B EINVAL 30 | Invalid argument value. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_next (3), 37 | .BR cxl_get_caia_version (3), 38 | .BR cxl_get_image_loaded (3), 39 | .BR cxl_get_psl_revision (3), 40 | .BR cxl_get_psl_timebase_synced (3), 41 | .BR cxl_get_tunneled_ops_supported (3) 42 | -------------------------------------------------------------------------------- /man3/cxl_get_caia_version.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_CAIA_VERSION 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_caia_version \- get the CAIA version supported by a CXL adapter 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_caia_version(struct cxl_adapter_h" 10 | .BI * adapter ", long *" majorp , 11 | .BI "long *" minorp ); 12 | .SH DESCRIPTION 13 | .BR cxl_get_caia_version () 14 | copies the major and minor values of the CAIA version implemented on 15 | .I adapter 16 | to the long integers pointed to by 17 | .I majorp 18 | and 19 | .IR minorp . 20 | .SH RETURN VALUE 21 | On success, 0 is returned. 22 | On error, \-1 is returned and 23 | .I errno 24 | is set appropriately. 25 | .SH ERRORS 26 | .TP 27 | .B EINVAL 28 | Invalid argument value. 29 | .TP 30 | .B ENOMEM 31 | Insufficient memory. 32 | .SH SEE ALSO 33 | .BR cxl (3), 34 | .BR cxl_adapter_next (3), 35 | .BR cxl_get_base_image (3), 36 | .BR cxl_get_image_loaded (3), 37 | .BR cxl_get_psl_revision (3), 38 | .BR cxl_get_psl_timebase_synced (3), 39 | .BR cxl_get_tunneled_ops_supported (3) 40 | -------------------------------------------------------------------------------- /man3/cxl_get_cr_class.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_CR_CLASS 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_cr_class \- get the class code out of an AFU configuration record 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_cr_class(struct cxl_afu_h" 10 | .BI * afu ", long " cr_num ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_cr_class () 13 | copies the class code found in the 14 | .I afu 15 | configuration record number 16 | .IR cr_num , 17 | to the long integer pointed to by 18 | .IR valp . 19 | .SH RETURN VALUE 20 | On success, 0 is returned. 21 | On error, \-1 is returned and 22 | .I errno 23 | is set appropriately. 24 | .SH ERRORS 25 | .TP 26 | .B EINVAL 27 | Invalid argument value. 28 | .TP 29 | .B ENODEV 30 | Configuration record does not exist. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_afu_next (3), 37 | .BR cxl_afu_fd_to_h (3), 38 | .BR cxl_afu_next (3), 39 | .BR cxl_afu_open_dev (3), 40 | .BR cxl_afu_open_h (3), 41 | .BR cxl_get_cr_device (3), 42 | .BR cxl_get_cr_vendor (3) 43 | -------------------------------------------------------------------------------- /man3/cxl_get_cr_device.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_CR_DEVICE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_cr_device \- get the device ID out of an AFU configuration record 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_cr_device(struct cxl_afu_h" 10 | .BI * afu ", long " cr_num ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_cr_device () 13 | copies the device ID found in the 14 | .I afu 15 | configuration record number 16 | .IR cr_num , 17 | to the long integer pointed to by 18 | .IR valp . 19 | .SH RETURN VALUE 20 | On success, 0 is returned. 21 | On error, \-1 is returned and 22 | .I errno 23 | is set appropriately. 24 | .SH ERRORS 25 | .TP 26 | .B EINVAL 27 | Invalid argument value. 28 | .TP 29 | .B ENODEV 30 | Configuration record does not exist. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_afu_next (3), 37 | .BR cxl_afu_fd_to_h (3), 38 | .BR cxl_afu_next (3), 39 | .BR cxl_afu_open_dev (3), 40 | .BR cxl_afu_open_h (3), 41 | .BR cxl_get_cr_class (3), 42 | .BR cxl_get_cr_vendor (3) 43 | -------------------------------------------------------------------------------- /man3/cxl_get_cr_vendor.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_CR_VENDOR 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_cr_vendor \- get the vendor ID out of an AFU configuration record 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_cr_vendor(struct cxl_afu_h" 10 | .BI * afu ", long " cr_num ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_cr_vendor () 13 | copies the vendor ID found in the 14 | .I afu 15 | configuration record number 16 | .IR cr_num , 17 | to the long integer pointed to by 18 | .IR valp . 19 | .SH RETURN VALUE 20 | On success, 0 is returned. 21 | On error, \-1 is returned and 22 | .I errno 23 | is set appropriately. 24 | .SH ERRORS 25 | .TP 26 | .B EINVAL 27 | Invalid argument value. 28 | .TP 29 | .B ENODEV 30 | Configuration record does not exist. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_afu_next (3), 37 | .BR cxl_afu_fd_to_h (3), 38 | .BR cxl_afu_next (3), 39 | .BR cxl_afu_open_dev (3), 40 | .BR cxl_afu_open_h (3), 41 | .BR cxl_get_cr_class (3), 42 | .BR cxl_get_cr_device (3) 43 | -------------------------------------------------------------------------------- /man3/cxl_get_image_loaded.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_IMAGE_LOADED 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_image_loaded \- returns which of the user and factory PSL images is currently loaded on the CXL device 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_image_loaded(struct cxl_adapter_h" 10 | .BI * adapter ", enum cxl_image *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_image_loaded () 13 | copies which of the user and factory PSL images is current 14 | ly loaded on the CXL device 15 | .I adapter 16 | to the long integer pointed to by 17 | .IR valp . 18 | The 19 | .B "enum cxl_image" 20 | value will be 21 | .B CXL_IMAGE_FACTORY 22 | or 23 | .BR CXL_IMAGE_USER . 24 | .SH RETURN VALUE 25 | On success, 0 is returned. 26 | On error, \-1 is returned and 27 | .I errno 28 | is set appropriately. 29 | .SH ERRORS 30 | .TP 31 | .B EINVAL 32 | Invalid argument value. 33 | .TP 34 | .B ENOMEM 35 | Insufficient memory. 36 | .SH SEE ALSO 37 | .BR cxl (3), 38 | .BR cxl_adapter_next (3), 39 | .BR cxl_get_base_image (3), 40 | .BR cxl_get_caia_version (3), 41 | .BR cxl_get_psl_revision (3), 42 | .BR cxl_get_psl_timebase_synced (3), 43 | .BR cxl_get_tunneled_ops_supported (3) 44 | -------------------------------------------------------------------------------- /man3/cxl_get_irqs_max.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_IRQS_MAX 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_irqs_max \- get the maximum number of AFU interrupts available to a context, if it was the only context running 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_irqs_max(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_irqs_max () 13 | copies to the long integer pointed to by 14 | .I valp 15 | the maximum number of AFU interrupts available to a context of 16 | .IR afu , 17 | if it was the only context running. 18 | .PP 19 | This is the maximum number of interrupts that may be requested 20 | when calling 21 | .BR cxl_afu_attach_full () 22 | or 23 | .BR cxl_afu_attach_work () 24 | for 25 | .IR afu . 26 | The default on probe is the maximum that hardware can support. 27 | It can be administratively restricted with 28 | .BR cxl_set_irqs_max (). 29 | .SH RETURN VALUE 30 | On success, 0 is returned. 31 | On error, \-1 is returned and 32 | .I errno 33 | is set appropriately. 34 | .SH ERRORS 35 | .TP 36 | .B EINVAL 37 | Invalid argument value. 38 | .TP 39 | .B ENOMEM 40 | Insufficient memory. 41 | .SH SEE ALSO 42 | .BR cxl (3), 43 | .BR cxl_afu_attach (3), 44 | .BR cxl_afu_attach_full (3), 45 | .BR cxl_afu_attach_work (3), 46 | .BR cxl_get_irqs_min (3), 47 | .BR cxl_get_mode (3), 48 | .BR cxl_get_modes_supported (3), 49 | .BR cxl_get_prefault_mode (3), 50 | .BR cxl_set_irqs_max (3), 51 | .BR cxl_work_set_num_irqs (3) 52 | -------------------------------------------------------------------------------- /man3/cxl_get_irqs_min.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_IRQS_MIN 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_irqs_min \- get the minimum number of AFU interrupts required for each context 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_irqs_min(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_irqs_min () 13 | copies to the long integer pointed to by 14 | .I valp 15 | the minimum number of AFU interrupts required 16 | for each context of 17 | .IR afu . 18 | .PP 19 | This is the minimum number that must be requested when calling 20 | .BR cxl_afu_attach_full () 21 | or 22 | .BR cxl_afu_attach_work () 23 | for 24 | .IR afu . 25 | It is implicitly requested by 26 | .BR cxl_afu_attach (). 27 | .SH RETURN VALUE 28 | On success, 0 is returned. 29 | On error, \-1 is returned and 30 | .I errno 31 | is set appropriately. 32 | .SH ERRORS 33 | .TP 34 | .B EINVAL 35 | Invalid argument value. 36 | .TP 37 | .B ENOMEM 38 | Insufficient memory. 39 | .SH SEE ALSO 40 | .BR cxl (3), 41 | .BR cxl_afu_attach (3), 42 | .BR cxl_afu_attach_full (3), 43 | .BR cxl_afu_attach_work (3), 44 | .BR cxl_get_irqs_max (3), 45 | .BR cxl_get_mode (3), 46 | .BR cxl_get_modes_supported (3), 47 | .BR cxl_get_prefault_mode (3), 48 | .BR cxl_set_irqs_max (3), 49 | .BR cxl_work_set_num_irqs (3) 50 | -------------------------------------------------------------------------------- /man3/cxl_get_mmio_size.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_MMIO_SIZE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_mmio_size \- get the total size of the MMIO space of an AFU, including all per-process areas 6 | .PP 7 | cxl_get_mmio_size \- get the size of the MMIO space available to a non-master process 8 | .SH SYNOPSIS 9 | .B #include 10 | .PP 11 | .B "int cxl_get_mmio_size(struct cxl_afu_h" 12 | .BI * afu ", long *" valp ); 13 | .SH DESCRIPTION 14 | .BR cxl_get_mmio_size () 15 | copies the size of the 16 | MMIO space of 17 | .I afu 18 | to the long integer pointed to by 19 | .IR valp . 20 | .PP 21 | In AFU directed mode, the master context MMIO space includes all 22 | slave context per-process MMIO areas. 23 | In slave context, 24 | .BR cxl_get_mmio_size () 25 | returns the size of the per-process MMIO space. 26 | .SH RETURN VALUE 27 | On success, 0 is returned. 28 | On error, \-1 is returned and 29 | .I errno 30 | is set appropriately. 31 | .SH ERRORS 32 | .TP 33 | .B EINVAL 34 | Invalid argument value. 35 | .TP 36 | .B ENODEV 37 | Invalid AFU device. 38 | .TP 39 | .B ENOMEM 40 | Insufficient memory. 41 | .SH FILES 42 | .TP 43 | .BI /dev/cxl/afu . d 44 | AFU device in dedicated process mode. 45 | .TP 46 | .BI /dev/cxl/afu . m 47 | AFU device in AFU directed mode, master context. 48 | .TP 49 | .BI /dev/cxl/afu . s 50 | AFU device in AFU directed mode, slave context. 51 | .SH SEE ALSO 52 | .BR cxl (3), 53 | .BR cxl_adapter_afu_next (3), 54 | .BR cxl_afu_next (3), 55 | .BR cxl_mmio_map (3), 56 | .BR cxl_mmio_ptr (3), 57 | .BR cxl_mmio_read32 (3), 58 | .BR cxl_mmio_read64 (3), 59 | .BR cxl_mmio_unmap (3), 60 | .BR cxl_mmio_write32 (3), 61 | .BR cxl_mmio_write64 (3) 62 | -------------------------------------------------------------------------------- /man3/cxl_get_mode.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_MODE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_mode \- get the current programming mode of an AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_mode(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_mode () 13 | copies the current programming mode used by 14 | .I afu 15 | to the long integer pointed to by 16 | .IR valp . 17 | Mode will be one of the modes returned by 18 | .BR cxl_get_modes_supported (): 19 | .B CXL_MODE_DEDICATED 20 | or 21 | .BR CXL_MODE_DIRECTED , 22 | .SH RETURN VALUE 23 | On success, 0 is returned. 24 | On error, \-1 is returned and 25 | .I errno 26 | is set appropriately. 27 | .SH ERRORS 28 | .TP 29 | .B EINVAL 30 | Invalid argument value. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_afu_next (3), 37 | .BR cxl_afu_fd_to_h (3), 38 | .BR cxl_afu_next (3), 39 | .BR cxl_afu_open_dev (3), 40 | .BR cxl_afu_open_h (3), 41 | .BR cxl_get_api_version (3), 42 | .BR cxl_get_api_version_compatible (3), 43 | .BR cxl_get_irqs_max (3), 44 | .BR cxl_get_irqs_min (3), 45 | .BR cxl_get_modes_supported (3), 46 | .BR cxl_get_prefault_mode (3), 47 | .BR cxl_set_mode (3) 48 | -------------------------------------------------------------------------------- /man3/cxl_get_modes_supported.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_MODES_SUPPORTED 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_modes_supported \- get the programming modes supported by an AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_mode_supported(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_mode_supported () 13 | copies the mask of the modes supported by 14 | .I afu 15 | to the long integer pointed to by 16 | .IR valp . 17 | The following bits may be set in the mode mask: 18 | .B CXL_MODE_DEDICATED 19 | and 20 | .BR CXL_MODE_DIRECTED . 21 | .SH RETURN VALUE 22 | On success, 0 is returned. 23 | On error, \-1 is returned and 24 | .I errno 25 | is set appropriately. 26 | .SH ERRORS 27 | .TP 28 | .B EINVAL 29 | Invalid argument value. 30 | .TP 31 | .B ENOMEM 32 | Insufficient memory. 33 | .SH SEE ALSO 34 | .BR cxl (3), 35 | .BR cxl_adapter_afu_next (3), 36 | .BR cxl_afu_fd_to_h (3), 37 | .BR cxl_afu_next (3), 38 | .BR cxl_afu_open_dev (3), 39 | .BR cxl_afu_open_h (3), 40 | .BR cxl_get_api_version (3), 41 | .BR cxl_get_api_version_compatible (3), 42 | .BR cxl_get_irqs_max (3), 43 | .BR cxl_get_irqs_min (3), 44 | .BR cxl_get_mode (3), 45 | .BR cxl_get_prefault_mode (3), 46 | .BR cxl_set_mode (3) 47 | -------------------------------------------------------------------------------- /man3/cxl_get_pp_mmio_len.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_PP_MMIO_LEN 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_pp_mmio_len \- get the per-process MMIO space length 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_pp_mmio_len(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_pp_mmio_len () 13 | copies the per-process MMIO space length of 14 | .I afu 15 | to the long integer pointed to by 16 | .IR valp . 17 | The AFU must be opened in AFU directed mode, master context. 18 | .SH RETURN VALUE 19 | On success, 0 is returned. 20 | On error, \-1 is returned and 21 | .I errno 22 | is set appropriately. 23 | .SH ERRORS 24 | .TP 25 | .B EINVAL 26 | Invalid argument value. 27 | .TP 28 | .B ENODEV 29 | Invalid AFU device. 30 | .TP 31 | .B ENOMEM 32 | Insufficient memory. 33 | .SH FILES 34 | .TP 35 | .BI /dev/cxl/afu . m 36 | AFU device in directed mode, master context. 37 | .SH SEE ALSO 38 | .BR cxl (3), 39 | .BR cxl_adapter_afu_next (3), 40 | .BR cxl_afu_next (3), 41 | .BR cxl_get_pp_mmio_off (3) 42 | -------------------------------------------------------------------------------- /man3/cxl_get_pp_mmio_off.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_PP_MMIO_OFF 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_pp_mmio_off \- get the per-process MMIO space offset 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_pp_mmio_off(struct cxl_afu_h" 10 | .BI * afu ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_pp_mmio_off () 13 | copies the per-process MMIO space offset of 14 | .I afu 15 | to the long integer pointed to by 16 | .IR valp . 17 | The AFU must be opened in AFU directed mode, master context. 18 | .SH RETURN VALUE 19 | On success, 0 is returned. 20 | On error, \-1 is returned and 21 | .I errno 22 | is set appropriately. 23 | .SH ERRORS 24 | .TP 25 | .B EINVAL 26 | Invalid argument value. 27 | .TP 28 | .B ENODEV 29 | Invalid AFU device. 30 | .TP 31 | .B ENOMEM 32 | Insufficient memory. 33 | .SH FILES 34 | .TP 35 | .BI /dev/cxl/afu . m 36 | AFU device in directed mode, master context. 37 | .SH SEE ALSO 38 | .BR cxl (3), 39 | .BR cxl_adapter_afu_next (3), 40 | .BR cxl_afu_next (3), 41 | .BR cxl_get_pp_mmio_len (3) 42 | -------------------------------------------------------------------------------- /man3/cxl_get_prefault_mode.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_PREFAULT_MODE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_prefault_mode \- get the mode for prefaulting segments 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_prefault_mode(struct cxl_afu_h" 10 | .BI * afu ", enum cxl_prefault_mode *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_prefault_mode () 13 | gets the current mode used for prefaulting in segments 14 | into the segment table when performing 15 | .BR cxl_afu_attach (). 16 | The prefault_mode of 17 | .I afu 18 | is copied to the long integer pointed to by 19 | .IR valp . 20 | Mode will be one of the 21 | .B "enum cxl_prefault_mode" 22 | values: 23 | .TP 24 | .B CXL_PREFAULT_MODE_NONE 25 | No prefaulting (default). 26 | .TP 27 | .B CXL_PREFAULT_MODE_WED 28 | Treat the work element descriptor as an effective address and 29 | prefault what it points to. 30 | .TP 31 | .B CXL_PREFAULT_MODE_ALL 32 | Prefault all the segments mapped by the process calling 33 | .BR cxl_afu_attach (), 34 | .BR cxl_afu_attach_full () 35 | or 36 | .BR cxl_afu_attach_work (). 37 | .SH RETURN VALUE 38 | On success, 0 is returned. 39 | On error, \-1 is returned and 40 | .I errno 41 | is set appropriately. 42 | .SH ERRORS 43 | .TP 44 | .B EINVAL 45 | Invalid argument value. 46 | .TP 47 | .B ENOMEM 48 | Insufficient memory. 49 | .SH SEE ALSO 50 | .BR cxl (3), 51 | .BR cxl_adapter_afu_next (3), 52 | .BR cxl_afu_attach (3), 53 | .BR cxl_afu_attach_full (3), 54 | .BR cxl_afu_attach_work (3), 55 | .BR cxl_afu_next (3), 56 | .BR cxl_get_api_version (3), 57 | .BR cxl_get_api_version_compatible (3), 58 | .BR cxl_get_irqs_max (3), 59 | .BR cxl_get_irqs_min (3), 60 | .BR cxl_get_mode (3), 61 | .BR cxl_get_modes_supported (3), 62 | .BR cxl_set_prefault_mode (3) 63 | -------------------------------------------------------------------------------- /man3/cxl_get_psl_revision.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_PSL_REVISION 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_get_psl_revision \- get the revision level of the current PSL image loaded on the CXL device 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_psl_revision(struct cxl_adapter_h" 10 | .BI * adapter ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_psl_revision () 13 | copies the revision level of the current PSL image loaded on the CXL 14 | .I adapter 15 | to the long integer pointed to by 16 | .IR valp . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .TP 27 | .B ENOMEM 28 | Insufficient memory. 29 | .SH SEE ALSO 30 | .BR cxl (3), 31 | .BR cxl_adapter_next (3), 32 | .BR cxl_get_base_image (3), 33 | .BR cxl_get_caia_version (3), 34 | .BR cxl_get_image_loaded (3) 35 | .BR cxl_get_psl_timebase_synced (3), 36 | .BR cxl_get_tunneled_ops_supported (3) 37 | -------------------------------------------------------------------------------- /man3/cxl_get_psl_timebase_synced.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_GET_PSL_TIMEBASE_SYNCED 3 2017-05-24 "LIBCXL 1.5" "CXL Manual" 4 | .SH NAME 5 | cxl_get_psl_timebase_synced \- get the status of timebase on the CXL device 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_psl_timebase_synced(struct cxl_adapter_h" 10 | .BI * adapter ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_psl_timebase_synced () 13 | copies the status of timebase on the CXL 14 | .I adapter 15 | to the long integer pointed to by 16 | .IR valp . 17 | This value will be 1 if the PSL timebase register is synchronized 18 | with the core timebase register, 0 otherwise. 19 | .SH RETURN VALUE 20 | On success, 0 is returned. 21 | On error, \-1 is returned and 22 | .I errno 23 | is set appropriately. 24 | .SH ERRORS 25 | .TP 26 | .B EINVAL 27 | Invalid argument value. 28 | .TP 29 | .B ENODEV 30 | The kernel does not export the PSL timebase status. 31 | .TP 32 | .B ENOMEM 33 | Insufficient memory. 34 | .SH SEE ALSO 35 | .BR cxl (3), 36 | .BR cxl_adapter_next (3), 37 | .BR cxl_get_base_image (3), 38 | .BR cxl_get_caia_version (3), 39 | .BR cxl_get_image_loaded (3), 40 | .BR cxl_get_psl_revision (3), 41 | .BR cxl_get_tunneled_ops_supported(3) 42 | -------------------------------------------------------------------------------- /man3/cxl_get_tunneled_ops_supported.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2018 IBM Corp. 2 | .\" 3 | .TH CXL_GET_TUNNELED_OPS_SUPPORTED 3 2018-04-26 "LIBCXL 1.7" "CXL Manual" 4 | .SH NAME 5 | cxl_get_tunneled_ops_supported \- get the status of tunneled operations on the CXL device 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_get_tunneled_ops_supported(struct cxl_adapter_h" 10 | .BI * adapter ", long *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_get_tunneled_ops_supported () 13 | copies the status of tunneled operations on the CXL 14 | .I adapter 15 | to the long integer pointed to by 16 | .IR valp . 17 | This value will be 1 if tunneled operations are supported in capi mode, 18 | 0 otherwise. 19 | .PP 20 | Tunneled operations (atomics and as_notify) are supported on POWER9. 21 | Libcxl functions related to as_notify are 22 | .BR cxl_afu_host_thread_wait (), 23 | .BR cxl_work_disable_wait (), 24 | .BR cxl_work_enable_wait () 25 | and 26 | .BR cxl_work_get_tid (). 27 | .SH RETURN VALUE 28 | On success, 0 is returned. 29 | On error, \-1 is returned and 30 | .I errno 31 | is set appropriately. 32 | .SH ERRORS 33 | .TP 34 | .B EINVAL 35 | Invalid argument value. 36 | .TP 37 | .B ENODEV 38 | The kernel does not export the tunneled operations status. 39 | .TP 40 | .B ENOMEM 41 | Insufficient memory. 42 | .SH SEE ALSO 43 | .BR cxl (3), 44 | .BR cxl_adapter_next (3), 45 | .BR cxl_afu_host_thread_wait (3), 46 | .BR cxl_get_base_image (3), 47 | .BR cxl_get_caia_version (3), 48 | .BR cxl_get_image_loaded (3), 49 | .BR cxl_get_psl_revision (3), 50 | .BR cxl_get_timebase_synced (3) 51 | .BR cxl_work_disable_wait (3), 52 | .BR cxl_work_enable_wait (3), 53 | .BR cxl_work_get_tid (3) 54 | -------------------------------------------------------------------------------- /man3/cxl_mmio_install_sigbus_handler.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_INSTALL_SIGBUS_HANDLER 3 2017-05-24 "" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_install_sigbus_handler \- install the libcxl SIGBUS handler to catch MMIO access errors 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_install_sigbus_handler();" 10 | .SH DESCRIPTION 11 | .BR cxl_mmio_install_sigbus_handler () 12 | installs the libcxl SIGBUS handler, which changes the behaviour of 13 | .BR cxl_mmio_read32 (), 14 | .BR cxl_mmio_read64 (), 15 | .BR cxl_mmio_write32 () 16 | and 17 | .BR cxl_mmio_write64 () 18 | on IO errors. If a SIGBUS is received from the kernel during one of these calls 19 | the libcxl SIGBUS handler will catch it and cause these calls to return -1 and 20 | set errno to EIO. 21 | 22 | If the libcxl SIGBUS handler has not been installed before these calls are 23 | made (and the application has not installed it's own handler), the SIGBUS from 24 | the kernel would terminate the program, which may be preferable in many cases 25 | for simplicity. 26 | 27 | Additionally, if the handler has not been installed and the cxl_mmio_read* 28 | calls detect an error due to a read of all F's, they will themselves raise a 29 | SIGBUS to terminate the program. This simplifies handling of IO errors for the 30 | application as it needs to either install the sigbus handler and be prepared to 31 | handle errors from the MMIO accessor functions, or treat any such error as 32 | fatal and receive a SIGBUS. 33 | 34 | The libcxl SIGBUS handler can chain to a handler installed by the application 35 | prior to calling 36 | .BR cxl_mmio_install_sigbus_handler(). 37 | If the handler is invoked and libcxl determines that the signal was not due to 38 | an IO error from a CXL MMIO access, it will call any SIGBUS handler that was 39 | previously installed. If the handler had previously been set to SIG_IGN it will 40 | ignore the signal and if it had been set to SIG_DFL it will remove itself and 41 | re-raise the signal, thereby terminating the program. 42 | .SH RETURN VALUE 43 | On success, 0 is returned. 44 | On error, \-1 is returned and 45 | .I errno 46 | is set appropriately. 47 | .SH SEE ALSO 48 | .BR cxl (3), 49 | .BR cxl_mmio_read32 (3), 50 | .BR cxl_mmio_read64 (3), 51 | .BR cxl_mmio_write32 (3), 52 | .BR cxl_mmio_write64 (3) 53 | -------------------------------------------------------------------------------- /man3/cxl_mmio_map.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_MAP 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_map \- map the per-process Problem State Area of an AFU to memory 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_map(struct cxl_afu_h" 10 | .BI * afu ", __u32 " flag ); 11 | .SH DESCRIPTION 12 | .BR cxl_mmio_map () 13 | maps the per-process Problem State Area of 14 | .I afu 15 | to the current process memory, and declares AFU endianness according to 16 | .IR flag . 17 | The size and contents of this area are specific each AFU. 18 | The size can be discovered with 19 | .BR cxl_get_mmio_size (). 20 | .PP 21 | In AFU directed mode, master contexts are allowed to map all of 22 | the MMIO space and slave contexts are allowed to only map the per 23 | process MMIO space associated with the context. 24 | In dedicated process mode the entire MMIO space can always be mapped. 25 | .PP 26 | The possible values of 27 | .I flag 28 | are: 29 | .TP 30 | .B CXL_MMIO_BIG_ENDIAN 31 | AFU data is big-endian 32 | .TP 33 | .B CXL_MMIO_LITTLE_ENDIAN 34 | AFU data is little-endian 35 | .TP 36 | .B CXL_MMIO_HOST_ENDIAN 37 | AFU uses the same endianness as host. 38 | .PP 39 | Subsequent 40 | .BR cxl_mmio_read32 (), 41 | .BR cxl_mmio_read64 (), 42 | .BR cxl_mmio_write32 () 43 | and 44 | .BR cxl_mmio_write64 () 45 | will honor 46 | .I flag 47 | and swap bytes on behalf of the application when required. 48 | Only 32 and 64-bit accesses are supported by POWER8 and POWER9. 49 | .SH RETURN VALUE 50 | On success, 0 is returned. 51 | On error, \-1 is returned and 52 | .I errno 53 | is set appropriately. 54 | .SH ERRORS 55 | .TP 56 | .B EINVAL 57 | Invalid argument value, or AFU does not support MMIO space. 58 | .TP 59 | .B EIO 60 | AFU context is not attached. 61 | .TP 62 | .B ENODEV 63 | AFU not opened, or missing flags. 64 | .TP 65 | .B ENOMEM 66 | Insufficient memory. 67 | .SH FILES 68 | .TP 69 | .BI /dev/cxl/afu . d 70 | AFU device in dedicated process mode. 71 | .TP 72 | .BI /dev/cxl/afu . m 73 | AFU device in AFU directed mode, master context. 74 | .TP 75 | .BI /dev/cxl/afu . s 76 | AFU device in AFU directed mode, slave context. 77 | .SH SEE ALSO 78 | .BR cxl (3), 79 | .BR cxl_afu_attach (3), 80 | .BR cxl_afu_attach_full (3), 81 | .BR cxl_afu_attach_work (3), 82 | .BR cxl_get_mmio_size (3), 83 | .BR cxl_mmio_ptr (3), 84 | .BR cxl_mmio_read32 (3), 85 | .BR cxl_mmio_read64 (3), 86 | .BR cxl_mmio_unmap (3), 87 | .BR cxl_mmio_write32 (3), 88 | .BR cxl_mmio_write64 (3), 89 | .BR mmap (3) 90 | -------------------------------------------------------------------------------- /man3/cxl_mmio_ptr.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_PTR 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_ptr \- return the address of the mapped AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_ptr(struct cxl_afu_h" 10 | .BI * afu ", void **" mmio_ptr ); 11 | .SH DESCRIPTION 12 | .BR cxl_mmio_ptr () 13 | copies the address of the mapped Problem State Area of 14 | .I afu 15 | to the pointer 16 | .IR mmio_ptr . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value, or MMIO space not mapped. 26 | .TP 27 | .B ENOMEM 28 | Insufficient memory. 29 | .SH SEE ALSO 30 | .BR cxl (3), 31 | .BR cxl_get_mmio_size (3), 32 | .BR cxl_mmio_map (3), 33 | .BR cxl_mmio_read32 (3), 34 | .BR cxl_mmio_read64 (3), 35 | .BR cxl_mmio_unmap (3), 36 | .BR cxl_mmio_write32 (3), 37 | .BR cxl_mmio_write64 (3) 38 | -------------------------------------------------------------------------------- /man3/cxl_mmio_read32.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_READ32 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_read32 \- read a 32-bit word from the mapped AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_read32(struct cxl_afu_h " 10 | .BI * afu ", uint64_t " offset , 11 | .BI "uint32_t *" data ); 12 | .SH DESCRIPTION 13 | .BR cxl_mmio_read32 () 14 | reads the 32-bit word at 15 | .I offset 16 | from the address of the mapped Problem State Area of 17 | .IR afu , 18 | and copies its value to the word pointed to by 19 | .IR data . 20 | The copy will include byte swapping if the AFU endianness declared by 21 | .BR cxl_mmio_map () 22 | differs from the host endianness. 23 | .PP 24 | .I offset 25 | is a byte address that is aligned on a word (4 byte) boundary. 26 | It must be lower than the MMIO size returned by 27 | .BR cxl_get_mmio_size (). 28 | The address of the mapped MMIO space is returned by 29 | .BR cxl_mmio_ptr (). 30 | .PP 31 | If the MMIO access fails due to an IO error, a SIGBUS may be sent to the 32 | application, which would ordinarily result in the process being terminated. 33 | libcxl provides an optional SIGBUS handler, which can be installed with 34 | .BR cxl_mmio_install_sigbus_handler (). 35 | .PP 36 | Installing this signal handler prior to using the MMIO accessor functions will 37 | cause them to return -1 and set 38 | .I errno 39 | to EIO in the event of an IO error. Additionally, if this handler has NOT been 40 | installed, the cxl_mmio_read* functions will raise a SIGBUS in the event that 41 | they detect an IO error due to a read of all F's for consistency. 42 | .SH RETURN VALUE 43 | On success, 0 is returned. 44 | On error, \-1 is returned and 45 | .I errno 46 | is set appropriately. 47 | .SH ERRORS 48 | .TP 49 | .B EINVAL 50 | Invalid argument value, or unmapped MMIO space. 51 | .TP 52 | .B EIO 53 | An unrecoverable error 54 | .RB ( cxl_mmio_install_sigbus_handler () 55 | must have been previously called) 56 | .SH SEE ALSO 57 | .BR cxl (3), 58 | .BR cxl_get_mmio_size (3), 59 | .BR cxl_mmio_install_sigbus_handler (3), 60 | .BR cxl_mmio_map (3), 61 | .BR cxl_mmio_ptr (3), 62 | .BR cxl_mmio_read64 (3), 63 | .BR cxl_mmio_unmap (3), 64 | .BR cxl_mmio_write32 (3), 65 | .BR cxl_mmio_write64 (3) 66 | -------------------------------------------------------------------------------- /man3/cxl_mmio_read64.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_READ64 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_read64 \- read a 64-bit word from the mapped AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_read64(struct cxl_afu_h " 10 | .BI * afu ", uint64_t " offset , 11 | .BI "uint64_t *" data ); 12 | .SH DESCRIPTION 13 | .BR cxl_mmio_read64 () 14 | reads the 64-bit word at 15 | .I offset 16 | from the address of the mapped Problem State Area of 17 | .IR afu , 18 | and copies its value to the word pointed to by 19 | .IR data . 20 | The copy will include byte swapping if the AFU endianness declared by 21 | .BR cxl_mmio_map () 22 | differs from the host endianness. 23 | .PP 24 | .I offset 25 | is a byte address, aligned on a double word (8-byte) boundary. 26 | It must be lower than the MMIO size returned by 27 | .BR cxl_get_mmio_size (). 28 | The address of the mapped MMIO space is returned by 29 | .BR cxl_mmio_ptr (). 30 | .PP 31 | If the MMIO access fails due to an IO error, a SIGBUS may be sent to the 32 | application, which would ordinarily result in the process being terminated. 33 | libcxl provides an optional SIGBUS handler, which can be installed with 34 | .BR cxl_mmio_install_sigbus_handler (). 35 | Installing this signal handler prior to using the MMIO accessor functions will 36 | cause them to return -1 and set 37 | .I errno 38 | to EIO in the event of an IO error. Additionally, if this handler has NOT been 39 | installed, the cxl_mmio_read* functions will raise a SIGBUS in the event that 40 | they detect an IO error due to a read of all F's for consistency. 41 | .SH RETURN VALUE 42 | On success, 0 is returned. 43 | On error, \-1 is returned and 44 | .I errno 45 | is set appropriately. 46 | .SH ERRORS 47 | .TP 48 | .B EINVAL 49 | Invalid argument value, or unmapped MMIO space. 50 | .TP 51 | .B EIO 52 | An unrecoverable error 53 | .RB ( cxl_mmio_install_sigbus_handler () 54 | must have been previously called) 55 | .SH SEE ALSO 56 | .BR cxl (3), 57 | .BR cxl_get_mmio_size (3), 58 | .BR cxl_mmio_install_sigbus_handler (3), 59 | .BR cxl_mmio_map (3), 60 | .BR cxl_mmio_ptr (3), 61 | .BR cxl_mmio_read32 (3), 62 | .BR cxl_mmio_unmap (3), 63 | .BR cxl_mmio_write32 (3), 64 | .BR cxl_mmio_write64 (3) 65 | -------------------------------------------------------------------------------- /man3/cxl_mmio_unmap.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_UNMAP 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_unmap \- unmap an AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .BI "int cxl_mmio_unmap(struct cxl_afu_h *" afu ); 10 | .SH DESCRIPTION 11 | .BR cxl_mmio_map () 12 | unmaps the AFU Problem State Area of 13 | .IR afu . 14 | .SH RETURN VALUE 15 | On success, 0 is returned. 16 | On error, \-1 is returned and 17 | .I errno 18 | is set appropriately. 19 | .SH ERRORS 20 | .TP 21 | .B EINVAL 22 | Invalid argument value, or unmapped AFU Problem State Area 23 | .SH SEE ALSO 24 | .BR cxl (3), 25 | .BR cxl_get_mmio_size (3), 26 | .BR cxl_mmio_map (3), 27 | .BR cxl_mmio_ptr (3), 28 | .BR cxl_mmio_read32 (3), 29 | .BR cxl_mmio_read64 (3), 30 | .BR cxl_mmio_write32 (3), 31 | .BR cxl_mmio_write64 (3), 32 | .BR munmap (3) 33 | -------------------------------------------------------------------------------- /man3/cxl_mmio_write32.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_WRITE32 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_write32 \- write a 32-bit word to the mapped AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_write32(struct cxl_afu_h " 10 | .BI * afu ", uint64_t " offset , 11 | .BI "uint32_t " data ); 12 | .SH DESCRIPTION 13 | .BR cxl_mmio_write32 () 14 | writes the 32-bit word 15 | .I data 16 | at 17 | .I offset 18 | from the address of the mapped Problem State Area of 19 | .IR afu . 20 | Bytes will be swapped if the AFU endianness declared by 21 | .BR cxl_mmio_map () 22 | differs from the host endianness. 23 | .PP 24 | .I offset 25 | is a byte address that is aligned on a word (4 byte) boundary. 26 | It must be lower than the MMIO size returned by 27 | .BR cxl_get_mmio_size (). 28 | The address of the mapped MMIO space is returned by 29 | .BR cxl_mmio_ptr (). 30 | .PP 31 | If the MMIO access fails due to an IO error, a SIGBUS may be sent to the 32 | application, which would ordinarily result in the process being terminated. 33 | libcxl provides an optional SIGBUS handler, which can be installed with 34 | .BR cxl_mmio_install_sigbus_handler (). 35 | Installing this signal handler prior to using the MMIO accessor functions will 36 | cause them to return -1 and set 37 | .I errno 38 | to EIO in the event of an IO error. 39 | .SH RETURN VALUE 40 | On success, 0 is returned. 41 | On error, \-1 is returned and 42 | .I errno 43 | is set appropriately. 44 | .SH ERRORS 45 | .TP 46 | .B EINVAL 47 | Invalid argument value, or unmapped MMIO space. 48 | .TP 49 | .B EIO 50 | An unrecoverable error 51 | .RB ( cxl_mmio_install_sigbus_handler () 52 | must have been previously called) 53 | .SH SEE ALSO 54 | .BR cxl (3), 55 | .BR cxl_get_mmio_size (3), 56 | .BR cxl_mmio_install_sigbus_handler (3), 57 | .BR cxl_mmio_map (3), 58 | .BR cxl_mmio_ptr (3), 59 | .BR cxl_mmio_read32 (3), 60 | .BR cxl_mmio_read64 (3), 61 | .BR cxl_mmio_unmap (3), 62 | .BR cxl_mmio_write64 (3) 63 | -------------------------------------------------------------------------------- /man3/cxl_mmio_write64.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_MMIO_WRITE64 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_mmio_write64 \- write a 64-bit word to the mapped AFU Problem State Area 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_mmio_write64(struct cxl_afu_h " 10 | .BI * afu ", uint64_t " offset , 11 | .BI "uint64_t " data ); 12 | .SH DESCRIPTION 13 | .BR cxl_mmio_write64 () 14 | writes the 64-bit word 15 | .I data 16 | at 17 | .I offset 18 | from the address of the mapped Problem State Area of 19 | .IR afu . 20 | Bytes will be swapped if the AFU endianness declared by 21 | .BR cxl_mmio_map () 22 | differs from the host endianness. 23 | .PP 24 | .I offset 25 | is a byte address, aligned on a double word (8-byte) boundary. 26 | It must be lower than the MMIO size returned by 27 | .BR cxl_get_mmio_size (). 28 | The address of the mapped MMIO space is returned by 29 | .BR cxl_mmio_ptr (). 30 | .PP 31 | If the MMIO access fails due to an IO error, a SIGBUS may be sent to the 32 | application, which would ordinarily result in the process being terminated. 33 | libcxl provides an optional SIGBUS handler, which can be installed with 34 | .BR cxl_mmio_install_sigbus_handler (). 35 | Installing this signal handler prior to using the MMIO accessor functions will 36 | cause them to return -1 and set 37 | .I errno 38 | to EIO in the event of an IO error. 39 | .SH RETURN VALUE 40 | On success, 0 is returned. 41 | On error, \-1 is returned and 42 | .I errno 43 | is set appropriately. 44 | .SH ERRORS 45 | .TP 46 | .B EINVAL 47 | Invalid argument value, or unmapped MMIO space. 48 | .TP 49 | .B EIO 50 | An unrecoverable error 51 | .RB ( cxl_mmio_install_sigbus_handler () 52 | must have been previously called) 53 | .SH SEE ALSO 54 | .BR cxl (3), 55 | .BR cxl_get_mmio_size (3), 56 | .BR cxl_mmio_install_sigbus_handler (3), 57 | .BR cxl_mmio_map (3), 58 | .BR cxl_mmio_ptr (3), 59 | .BR cxl_mmio_read32 (3), 60 | .BR cxl_mmio_read64 (3), 61 | .BR cxl_mmio_unmap (3), 62 | .BR cxl_mmio_write32 (3) 63 | -------------------------------------------------------------------------------- /man3/cxl_read_event.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_READ_EVENT 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_read_event \- read one CXL event from an AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .BI "int cxl_read_event(struct cxl_afu_h *" afu , 10 | .BI "struct cxl_event *" event ); 11 | .SH DESCRIPTION 12 | .BR cxl_read_event () 13 | reads one CXL event from 14 | .IR afu , 15 | and copies it to the structure pointed to by 16 | .IR event . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EAGAIN 25 | AFU device opened with 26 | .BR O_NONBLOCK , 27 | and no data immediately available. 28 | .TP 29 | .B EINTR 30 | Interrupted 31 | .BR read () 32 | system call. 33 | .TP 34 | .B EINVAL 35 | Invalid argument value, or AFU not opened. 36 | .TP 37 | .B EIO 38 | Unrecoverable error. 39 | .TP 40 | .B ENODATA 41 | No data returned by 42 | .BR read (). 43 | .TP 44 | .B ENOMEM 45 | Insufficient memory. 46 | .SH FILES 47 | .TP 48 | .BI /dev/cxl/afu . d 49 | AFU device in dedicated process mode. 50 | .TP 51 | .BI /dev/cxl/afu . m 52 | AFU device in AFU directed mode, master context. 53 | .TP 54 | .BI /dev/cxl/afu . s 55 | AFU device in AFU directed mode, slave context. 56 | .SH SEE ALSO 57 | .BR cxl (3), 58 | .BR cxl_afu_fd_to_h (3), 59 | .BR cxl_afu_open_dev (3), 60 | .BR cxl_afu_open_h (3), 61 | .BR cxl_afu_opened (3), 62 | .BR cxl_fprint_event (3), 63 | .BR cxl_fprint_unknown_event (3), 64 | .BR cxl_event_pending (3), 65 | .BR cxl_read_expected_event (3), 66 | .BR open (2), 67 | .BR read (2) 68 | -------------------------------------------------------------------------------- /man3/cxl_read_expected_event.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_READ_EXPECTED_EVENT 3 2017-05-24 "LIBCXL 1.5" "CXL Manual" 4 | .SH NAME 5 | cxl_read_expected_event \- read one CXL event from an AFU, and treat it as a failure, if it did not match an expected event 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .BI "int cxl_read_expected_event(struct cxl_afu_h *" afu , 10 | .BI "struct cxl_event *" event ", __u32 " type , 11 | .BI "__u16 " irq ); 12 | .SH DESCRIPTION 13 | .BR cxl_read_expected_event () 14 | reads one CXL event from 15 | .IR afu , 16 | when an event of 17 | .I type 18 | is expected, 19 | and copies it to the structure pointed to by 20 | .IR event . 21 | For AFU interrupts, the expected AFU interrupt number 22 | .I irq 23 | may also be supplied (0 will accept any AFU interrupt). 24 | .SH RETURN VALUE 25 | On success, 0 is returned if the read event was of the expected type 26 | and (if applicable) AFU interrupt number. 27 | If the event did not match the type and interrupt, -1 is returned. 28 | .PP 29 | On error, \-2 is returned and 30 | .I errno 31 | is set appropriately. 32 | .SH ERRORS 33 | .TP 34 | .B EAGAIN 35 | AFU device opened with 36 | .BR O_NONBLOCK , 37 | and no data immediately available. 38 | .TP 39 | .B EINTR 40 | Interrupted 41 | .BR read () 42 | system call. 43 | .TP 44 | .B EINVAL 45 | Invalid argument value, or AFU not opened. 46 | .TP 47 | .B EIO 48 | Unrecoverable error. 49 | .TP 50 | .B ENODATA 51 | No data returned by 52 | .BR read (). 53 | .TP 54 | .B ENOMEM 55 | Insufficient memory. 56 | .SH FILES 57 | .TP 58 | .BI /dev/cxl/afu . d 59 | AFU device in dedicated process mode. 60 | .TP 61 | .BI /dev/cxl/afu . m 62 | AFU device in AFU directed mode, master context. 63 | .TP 64 | .BI /dev/cxl/afu . s 65 | AFU device in AFU directed mode, slave context. 66 | .SH SEE ALSO 67 | .BR cxl (3), 68 | .BR cxl_afu_fd_to_h (3), 69 | .BR cxl_afu_open_dev (3), 70 | .BR cxl_afu_open_h (3), 71 | .BR cxl_afu_opened (3), 72 | .BR cxl_fprint_event (3), 73 | .BR cxl_fprint_unknown_event (3), 74 | .BR cxl_event_pending (3), 75 | .BR cxl_read_event (3), 76 | .BR open (2), 77 | .BR read (2) 78 | -------------------------------------------------------------------------------- /man3/cxl_set_irqs_max.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_SET_IRQS_MAX 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_set_irqs_max \- administratively restrict the maximum number of AFU interrupts 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_set_irqs_max(struct cxl_afu_h" 10 | .BI * afu ", long " value ); 11 | .SH DESCRIPTION 12 | .BR cxl_set_irqs_max () 13 | sets the maximum number of interrupts that can be 14 | requested for 15 | .IR afu , 16 | when calling 17 | .BR cxl_afu_attach_full () 18 | or 19 | .BR cxl_afu_attach_work (). 20 | .I value 21 | must be greater or equal to the value returned by 22 | .BR cxl_get_irqs_min (). 23 | .SH RETURN VALUE 24 | On success, 0 is returned. 25 | On error, \-1 is returned and 26 | .I errno 27 | is set appropriately. 28 | .SH ERRORS 29 | .TP 30 | .B EINVAL 31 | Invalid argument value. 32 | .SH SEE ALSO 33 | .BR cxl (3), 34 | .BR cxl_afu_attach_full (3), 35 | .BR cxl_afu_attach_work (3), 36 | .BR cxl_get_irqs_max (3), 37 | .BR cxl_get_irqs_min (3) 38 | -------------------------------------------------------------------------------- /man3/cxl_set_mode.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_SET_MODE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_set_mode \- set the programming mode of an AFU 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_set_mode(struct cxl_afu_h" 10 | .BI * afu ", long " value ); 11 | .SH DESCRIPTION 12 | .BR cxl_set_mode () 13 | sets the programming mode of 14 | .I afu 15 | to 16 | .IR value . 17 | .I value 18 | must be one of the modes returned by 19 | .BR cxl_get_modes_supported (): 20 | .B CXL_MODE_DEDICATED 21 | or 22 | .BR CXL_MODE_DIRECTED . 23 | Mode will be changed provided that no user contexts 24 | are attached. 25 | .SH RETURN VALUE 26 | On success, 0 is returned. 27 | On error, \-1 is returned and 28 | .I errno 29 | is set appropriately. 30 | .SH ERRORS 31 | .TP 32 | .B EBUSY 33 | User context attached. 34 | .TP 35 | .B EINVAL 36 | Invalid argument value. 37 | .SH SEE ALSO 38 | .BR cxl (3), 39 | .BR cxl_adapter_afu_next (3), 40 | .BR cxl_afu_attach (3), 41 | .BR cxl_afu_attach_full (3), 42 | .BR cxl_afu_attach_work (3), 43 | .BR cxl_afu_fd_to_h (3), 44 | .BR cxl_afu_next (3), 45 | .BR cxl_afu_open_dev (3), 46 | .BR cxl_afu_open_h (3), 47 | .BR cxl_get_mode (3), 48 | .BR cxl_get_modes_supported (3) 49 | -------------------------------------------------------------------------------- /man3/cxl_set_prefault_mode.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_SET_PREFAULT_MODE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_set_prefault_mode \- set the mode for prefaulting segments 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_set_prefault_mode(struct cxl_afu_h" 10 | .BI * afu ", enum cxl_prefault_mode " value ); 11 | .SH DESCRIPTION 12 | .BR cxl_set_prefault_mode () 13 | sets the prefault mode of 14 | .I afu 15 | to 16 | .IR value . 17 | The current mode will be used for prefaulting in segments 18 | into the segment table when performing 19 | .BR cxl_afu_attach (), 20 | .BR cxl_afu_attach_full () 21 | or 22 | .BR cxl_afu_attach_work (). 23 | Mode must be one of the 24 | .B "enum cxl_prefault_mode" 25 | values: 26 | .TP 27 | .B CXL_PREFAULT_MODE_NONE 28 | No prefaulting (default). 29 | .TP 30 | .B CXL_PREFAULT_MODE_WED 31 | Treat the work element descriptor as an effective address and 32 | prefault what it points to. 33 | .TP 34 | .B CXL_PREFAULT_MODE_ALL 35 | Prefault all the segments mapped by the process calling 36 | .BR cxl_afu_attach (). 37 | .SH RETURN VALUE 38 | On success, 0 is returned. 39 | On error, \-1 is returned and 40 | .I errno 41 | is set appropriately. 42 | .SH ERRORS 43 | .TP 44 | .B EINVAL 45 | Invalid argument value. 46 | .SH SEE ALSO 47 | .BR cxl (3), 48 | .BR cxl_adapter_afu_next (3), 49 | .BR cxl_afu_attach (3), 50 | .BR cxl_afu_attach_full (3), 51 | .BR cxl_afu_attach_work (3), 52 | .BR cxl_afu_next (3), 53 | .BR cxl_get_prefault_mode (3) 54 | -------------------------------------------------------------------------------- /man3/cxl_work_alloc.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2018 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_ALLOC 3 2018-02-13 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_alloc \- allocate and initialize a work structure 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "struct cxl_ioctl_start_work *cxl_work_alloc();" 10 | .SH DESCRIPTION 11 | .BR cxl_work_alloc () 12 | allocates, initializes, and returns a pointer to a work 13 | structure, that can be populated and passed to 14 | .BR cxl_afu_attach_work (). 15 | .SH RETURN VALUE 16 | On success, a pointer to the allocated 17 | structure is returned. 18 | On error, NULL is returned and 19 | .I errno 20 | is set appropriately. 21 | .SH ERRORS 22 | .TP 23 | .B ENOMEM 24 | Not enough memory. 25 | .SH SEE ALSO 26 | .BR cxl (3), 27 | .BR cxl_afu_attach_work (3), 28 | .BR cxl_work_disable_wait (3), 29 | .BR cxl_work_enable_wait (3), 30 | .BR cxl_work_free (3), 31 | .BR cxl_work_get_amr (3), 32 | .BR cxl_work_get_num_irqs (3), 33 | .BR cxl_work_get_tid (3), 34 | .BR cxl_work_get_wed (3), 35 | .BR cxl_work_set_amr (3), 36 | .BR cxl_work_set_num_irqs (3), 37 | .BR cxl_work_set_wed (3) 38 | -------------------------------------------------------------------------------- /man3/cxl_work_disable_wait.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2018 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_DISABLE_WAIT 3 2018-04-24 "LIBCXL 1.6" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_disable_wait \- indicate that a host thread will not wait 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_disable_wait(struct cxl_ioctl_start_work" 10 | .BI * work ); 11 | .SH DESCRIPTION 12 | The tunneled operation as_notify is supported on POWER9. See 13 | .BR cxl_get_tunneled_ops_supported (). 14 | .PP 15 | .BR cxl_work_disable_wait () 16 | indicates in the 17 | .I work 18 | structure allocated by 19 | .BR cxl_work_alloc (), 20 | that the thread that will attach an AFU context with 21 | .BR cxl_afu_attach_work () 22 | will not call 23 | .BR cxl_afu_host_thread_wait (). 24 | .PP 25 | This is the default behaviour. Calling this function is only required to cancel 26 | a previous call to 27 | .BR cxl_work_enable_wait (). 28 | .SH RETURN VALUE 29 | On success, 0 is returned. 30 | On error, \-1 is returned and 31 | .I errno 32 | is set appropriately. 33 | .SH ERRORS 34 | .TP 35 | .B EINVAL 36 | Invalid argument value. 37 | .SH SEE ALSO 38 | .BR cxl (3), 39 | .BR cxl_afu_attach_work (3), 40 | .BR cxl_afu_host_thread_wait (3), 41 | .BR cxl_get_tunneled_ops_supported (3), 42 | .BR cxl_work_alloc (3), 43 | .BR cxl_work_enable_wait (3), 44 | .BR cxl_work_get_tid (3) 45 | -------------------------------------------------------------------------------- /man3/cxl_work_enable_wait.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2018 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_ENABLE_WAIT 3 2018-04-24 "LIBCXL 1.6" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_enable_wait \- indicate that a host thread will wait 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_enable_wait(struct cxl_ioctl_start_work" 10 | .BI * work ); 11 | .SH DESCRIPTION 12 | The tunneled operation as_notify is supported on POWER9. See 13 | .BR cxl_get_tunneled_ops_supported (). 14 | .PP 15 | .BR cxl_work_enable_wait () 16 | indicates in the 17 | .I work 18 | structure allocated by 19 | .BR cxl_work_alloc (), 20 | that the thread that will attach an AFU context with 21 | .BR cxl_afu_attach_work () 22 | requires to be able to wait and be notified by the AFU with 23 | .BR cxl_afu_host_thread_wait (). 24 | .SH RETURN VALUE 25 | On success, 0 is returned. 26 | On error, \-1 is returned and 27 | .I errno 28 | is set appropriately. 29 | .SH ERRORS 30 | .TP 31 | .B EINVAL 32 | Invalid argument value. 33 | .SH SEE ALSO 34 | .BR cxl (3), 35 | .BR cxl_afu_attach_work (3), 36 | .BR cxl_afu_host_thread_wait (3), 37 | .BR cxl_get_tunneled_ops_supported (3), 38 | .BR cxl_work_alloc (3), 39 | .BR cxl_work_disable_wait (3), 40 | .BR cxl_work_get_tid (3) 41 | -------------------------------------------------------------------------------- /man3/cxl_work_free.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_FREE 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_get_free \- free a work structure 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_free(struct cxl_ioctl_start_work" 10 | .BI * work ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_free () 13 | frees the 14 | .I work 15 | structure allocated by 16 | .BR cxl_work_alloc (). 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .SH SEE ALSO 27 | .BR cxl (3), 28 | .BR cxl_afu_attach_work (3), 29 | .BR cxl_work_alloc (3), 30 | .BR cxl_work_get_amr (3), 31 | .BR cxl_work_get_num_irqs (3), 32 | .BR cxl_work_get_wed (3), 33 | .BR cxl_work_set_amr (3), 34 | .BR cxl_work_set_num_irqs (3), 35 | .BR cxl_work_set_wed (3) 36 | -------------------------------------------------------------------------------- /man3/cxl_work_get_amr.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_GET_AMR 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_get_amr \- get the value of the authority mask register 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_get_amr(struct cxl_ioctl_start_work" 10 | .BI * work ", __u64 *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_get_amr () 13 | copies the value of the authority mask register from the struct 14 | .I work 15 | to the unsigned word pointed to by 16 | .IR valp . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .SH SEE ALSO 27 | .BR cxl (3), 28 | .BR cxl_afu_attach_work (3), 29 | .BR cxl_work_alloc (3), 30 | .BR cxl_work_free (3), 31 | .BR cxl_work_get_num_irqs (3), 32 | .BR cxl_work_get_wed (3), 33 | .BR cxl_work_set_amr (3), 34 | .BR cxl_work_set_num_irqs (3), 35 | .BR cxl_work_set_wed (3) 36 | -------------------------------------------------------------------------------- /man3/cxl_work_get_num_irqs.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_GET_NUM_IRQS 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_get_num_irqs \- get the number of interrupts requested 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_get_num_irqs(struct cxl_ioctl_start_work" 10 | .BI * work ", __s16 *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_get_num_irqs () 13 | copies the requested number of interrupts from 14 | .I work 15 | to the short integer pointed to by 16 | .IR valp . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .SH SEE ALSO 27 | .BR cxl (3), 28 | .BR cxl_afu_attach_work (3), 29 | .BR cxl_work_alloc (3), 30 | .BR cxl_work_free (3), 31 | .BR cxl_work_get_amr (3), 32 | .BR cxl_work_get_wed (3), 33 | .BR cxl_work_set_amr (3), 34 | .BR cxl_work_set_num_irqs (3), 35 | .BR cxl_work_set_wed (3) 36 | -------------------------------------------------------------------------------- /man3/cxl_work_get_tid.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2018 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_GET_TID 3 2018-04-24 "LIBCXL 1.6" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_get_tid \- get the tid of the thread that will wait 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_get_tid(struct cxl_ioctl_start_work" 10 | .BI * work ", __u16 *" valp ); 11 | .SH DESCRIPTION 12 | The tunneled operation as_notify is supported on POWER9. See 13 | .BR cxl_get_tunneled_ops_supported (). 14 | .PP 15 | .BR cxl_work_get_tid () 16 | copies to the address pointed to by 17 | .I valp 18 | the 16-bit tid value assigned by 19 | .BR cxl_afu_attach_work () 20 | to the thread that will wait to be notified by the AFU with 21 | .BR cxl_afu_host_thread_wait (). 22 | The 23 | .I work 24 | structure must have been wait-enabled with 25 | .BR cxl_work_enable_wait (). 26 | .PP 27 | Note: the 16-bit tid returned by 28 | .BR cxl_work_get_tid () 29 | is a capi-specific value, unrelated to the thread ID 30 | returned by the Linux system call 31 | .BR gettid (). 32 | .SH RETURN VALUE 33 | On success, 0 is returned. 34 | On error, \-1 is returned and 35 | .I errno 36 | is set appropriately. 37 | .SH ERRORS 38 | .TP 39 | .B EINVAL 40 | Invalid argument value, or AFU context not attached, or wait not enabled 41 | .SH SEE ALSO 42 | .BR cxl (3), 43 | .BR cxl_afu_attach_work (3), 44 | .BR cxl_afu_host_thread_wait (3), 45 | .BR cxl_get_tunneled_ops_supported (3), 46 | .BR cxl_work_disable_wait (3), 47 | .BR cxl_work_enable_wait (3), 48 | .BR gettid(2) 49 | -------------------------------------------------------------------------------- /man3/cxl_work_get_wed.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_GET_WED 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_get_wed \- get the value of the work element descriptor 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_get_wed(struct cxl_ioctl_start_work" 10 | .BI * work ", __u64 *" valp ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_get_wed () 13 | copies the value of the work element descriptor from the struct 14 | .I work 15 | to the unsigned word pointed to by 16 | .IR valp . 17 | .SH RETURN VALUE 18 | On success, 0 is returned. 19 | On error, \-1 is returned and 20 | .I errno 21 | is set appropriately. 22 | .SH ERRORS 23 | .TP 24 | .B EINVAL 25 | Invalid argument value. 26 | .SH SEE ALSO 27 | .BR cxl (3), 28 | .BR cxl_afu_attach_work (3), 29 | .BR cxl_work_alloc (3), 30 | .BR cxl_work_free (3), 31 | .BR cxl_work_get_amr (3), 32 | .BR cxl_work_get_num_irqs (3), 33 | .BR cxl_work_set_amr (3), 34 | .BR cxl_work_set_num_irqs (3), 35 | .BR cxl_work_set_wed (3) 36 | -------------------------------------------------------------------------------- /man3/cxl_work_set_amr.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_SET_AMR 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_set_amr \- set the value of the authority mask register 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_set_amr(struct cxl_ioctl_start_work" 10 | .BI * work ", __u64 " amr ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_set_amr () 13 | sets the value of the authority mask register 14 | .I amr 15 | into the struct 16 | .IR work . 17 | A null value indicates that the authority mask register 18 | should not be set by 19 | .BR cxl_afu_attach_work (). 20 | .SH RETURN VALUE 21 | On success, 0 is returned. 22 | On error, \-1 is returned and 23 | .I errno 24 | is set appropriately. 25 | .SH ERRORS 26 | .TP 27 | .B EINVAL 28 | Invalid argument value. 29 | .SH SEE ALSO 30 | .BR cxl (3), 31 | .BR cxl_afu_attach_work (3), 32 | .BR cxl_work_alloc (3), 33 | .BR cxl_work_free (3), 34 | .BR cxl_work_get_amr (3), 35 | .BR cxl_work_get_num_irqs (3), 36 | .BR cxl_work_get_wed (3), 37 | .BR cxl_work_set_num_irqs (3), 38 | .BR cxl_work_set_wed (3) 39 | -------------------------------------------------------------------------------- /man3/cxl_work_set_num_irqs.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_SET_NUM_IRQS 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_set_num_irqs \- set the number of interrupts requested 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_set_num_irqs(struct cxl_ioctl_start_work" 10 | .BI * work ", __s16 " num_irqs ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_set_num_irqs () 13 | sets the number of interrupts requested 14 | .I num_irqs 15 | into the struct 16 | .IR work . 17 | If the value is negative, then 18 | .BR cxl_afu_attach_work (), 19 | will allocate the minimum number of interrupts required 20 | by an AFU context, returned by 21 | .BR cxl_get_irqs_min (). 22 | .SH RETURN VALUE 23 | On success, 0 is returned. 24 | On error, \-1 is returned and 25 | .I errno 26 | is set appropriately. 27 | .SH ERRORS 28 | .TP 29 | .B EINVAL 30 | Invalid argument value. 31 | .SH SEE ALSO 32 | .BR cxl (3), 33 | .BR cxl_afu_attach_work (3), 34 | .BR cxl_get_irqs_min (3), 35 | .BR cxl_work_alloc (3), 36 | .BR cxl_work_free (3), 37 | .BR cxl_work_get_amr (3), 38 | .BR cxl_work_get_num_irqs (3), 39 | .BR cxl_work_get_wed (3), 40 | .BR cxl_work_set_amr (3), 41 | .BR cxl_work_set_wed (3) 42 | -------------------------------------------------------------------------------- /man3/cxl_work_set_wed.3: -------------------------------------------------------------------------------- 1 | .\" Copyright 2015-2017 IBM Corp. 2 | .\" 3 | .TH CXL_WORK_SET_WED 3 2017-05-24 "LIBCXL 1.5" "CXL Programmer's Manual" 4 | .SH NAME 5 | cxl_work_set_wed \- set the value of the work element descriptor 6 | .SH SYNOPSIS 7 | .B #include 8 | .PP 9 | .B "int cxl_work_set_wed(struct cxl_ioctl_start_work" 10 | .BI * work ", __u64 " wed ); 11 | .SH DESCRIPTION 12 | .BR cxl_work_set_wed () 13 | sets the value of the work element descriptor 14 | .I wed 15 | into the struct 16 | .IR work . 17 | The work element descriptor 18 | .I wed 19 | is a 64-bit argument defined by the AFU. 20 | Typically this is an effective address pointing to an AFU specific 21 | structure describing what work to perform. 22 | .SH RETURN VALUE 23 | On success, 0 is returned. 24 | On error, \-1 is returned and 25 | .I errno 26 | is set appropriately. 27 | .SH ERRORS 28 | .TP 29 | .B EINVAL 30 | Invalid argument value. 31 | .SH SEE ALSO 32 | .BR cxl (3), 33 | .BR cxl_afu_attach_work (3), 34 | .BR cxl_work_alloc (3), 35 | .BR cxl_work_free (3), 36 | .BR cxl_work_get_amr (3), 37 | .BR cxl_work_get_num_irqs (3), 38 | .BR cxl_work_get_wed (3), 39 | .BR cxl_work_set_amr (3), 40 | .BR cxl_work_set_num_irqs (3) 41 | -------------------------------------------------------------------------------- /man3/foldtbl: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # foldtbl - fold long table lines 4 | 5 | awk 'BEGIN { 6 | sep = " " 7 | for (i = 0; i < 72; i++) 8 | sep = sep "-" 9 | } 10 | length() > 79 && $1 ~ /^-/ { 11 | print sep 12 | next 13 | } 14 | length() > 79 { 15 | line1 = $0 16 | line2 = "" 17 | tab = index($0, " " $2 " ") 18 | len = length() 19 | # move words exceeding column 78 to line2 20 | while (len > 79) { 21 | len = len - length($NF) -1 22 | line2 = " " $NF line2 23 | NF = NF - 1 24 | } 25 | # prepend initial white spaces to line2 26 | for (i = 1; i < tab; i++) 27 | line2 = " " line2 28 | # print truncated line1 and line2 29 | print substr(line1, 1, len) 30 | print line2 31 | next 32 | } 33 | { print }' 34 | -------------------------------------------------------------------------------- /man3/man2txt: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # man2txt - format a man page into plain text 4 | 5 | tbl | groff -man -I.. -Tascii | 6 | sed -e 's/\(.\)\o010\1/\1/g' -e 's/_\o010//g' -e 's/\o033\[[0-9][0-9]*m//g' 7 | -------------------------------------------------------------------------------- /symver.map: -------------------------------------------------------------------------------- 1 | LIBCXL_1 { 2 | global: 3 | cxl_adapter_next; 4 | cxl_adapter_dev_name; 5 | cxl_adapter_free; 6 | 7 | cxl_adapter_afu_next; 8 | cxl_afu_next; 9 | cxl_afu_dev_name; 10 | 11 | cxl_afu_open_dev; 12 | cxl_afu_open_h; 13 | cxl_afu_fd_to_h; 14 | cxl_afu_free; 15 | cxl_afu_opened; 16 | 17 | cxl_afu_attach_full; 18 | cxl_afu_attach; 19 | 20 | cxl_afu_get_process_element; 21 | 22 | cxl_afu_fd; 23 | 24 | cxl_afu_sysfs_pci; 25 | 26 | cxl_get_api_version; 27 | cxl_get_api_version_compatible; 28 | cxl_get_irqs_max; 29 | cxl_set_irqs_max; 30 | cxl_get_irqs_min; 31 | cxl_get_mmio_size; 32 | cxl_get_mode; 33 | cxl_set_mode; 34 | cxl_get_modes_supported; 35 | cxl_get_prefault_mode; 36 | cxl_set_prefault_mode; 37 | cxl_get_pp_mmio_len; 38 | cxl_get_pp_mmio_off; 39 | cxl_get_base_image; 40 | cxl_get_caia_version; 41 | cxl_get_image_loaded; 42 | cxl_get_psl_revision; 43 | 44 | cxl_read_event; 45 | cxl_read_expected_event; 46 | 47 | cxl_fprint_event; 48 | cxl_fprint_unknown_event; 49 | 50 | cxl_mmio_map; 51 | cxl_mmio_unmap; 52 | cxl_mmio_ptr; 53 | cxl_mmio_write64; 54 | cxl_mmio_read64; 55 | cxl_mmio_write32; 56 | cxl_mmio_read32; 57 | 58 | cxl_mmio_install_sigbus_handler; 59 | 60 | cxl_errinfo_size; 61 | cxl_errinfo_read; 62 | 63 | local: 64 | *; 65 | }; 66 | 67 | LIBCXL_1.1 { 68 | global: 69 | cxl_get_cr_class; 70 | cxl_get_cr_device; 71 | cxl_get_cr_vendor; 72 | } LIBCXL_1; 73 | 74 | LIBCXL_1.2 { 75 | global: 76 | cxl_afu_attach_work; 77 | cxl_work_alloc; 78 | cxl_work_free; 79 | cxl_work_get_amr; 80 | cxl_work_get_num_irqs; 81 | cxl_work_get_wed; 82 | cxl_work_set_amr; 83 | cxl_work_set_num_irqs; 84 | cxl_work_set_wed; 85 | 86 | cxl_event_pending; 87 | } LIBCXL_1.1; 88 | 89 | LIBCXL_1.4 { 90 | global: 91 | cxl_get_psl_timebase_synced; 92 | } LIBCXL_1.2; 93 | 94 | LIBCXL_1.6 { 95 | global: 96 | cxl_afu_host_thread_wait; 97 | cxl_work_disable_wait; 98 | cxl_work_enable_wait; 99 | cxl_work_get_tid; 100 | } LIBCXL_1.4; 101 | 102 | LIBCXL_1.7 { 103 | global: 104 | cxl_get_tunneled_ops_supported; 105 | } LIBCXL_1.6; 106 | --------------------------------------------------------------------------------