summaryrefslogtreecommitdiffstats
path: root/include/misc
diff options
context:
space:
mode:
authorMichael Neuling <mikey@neuling.org>2015-05-27 02:07:18 -0400
committerMichael Ellerman <mpe@ellerman.id.au>2015-06-02 23:27:20 -0400
commit6f7f0b3df6d49316c6f27390bb5ec250255be548 (patch)
tree28c8e7d088f936e08a66344c723003b71a5ca29b /include/misc
parent0520336afe5de76324c73f793bc40732e5c13359 (diff)
cxl: Add AFU virtual PHB and kernel API
This patch does two things. Firstly it presents the Accelerator Function Unit (AFUs) behind the POWER Service Layer (PSL) as PCI devices on a virtual PCI Host Bridge (vPHB). This in in addition to the PSL being a PCI device itself. As part of the Coherent Accelerator Interface Architecture (CAIA) AFUs can provide an AFU configuration. This AFU configuration recored is architected to be the same as a PCI config space. This patch sets discovers the AFU configuration records, provides AFU config space read/write functions to these configuration records. It then enumerates the PCI bus. It also hooks in PCI ops where appropriate. It also destroys the vPHB when the physical card is removed. Secondly, it add an in kernel API for AFU to use CXL. AFUs must present a driver that firstly binds as a PCI device. This PCI device can then be using to do CXL specific operations (that can't sit in the PCI ops) using this API. Signed-off-by: Michael Neuling <mikey@neuling.org> Acked-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'include/misc')
-rw-r--r--include/misc/cxl.h203
1 files changed, 203 insertions, 0 deletions
diff --git a/include/misc/cxl.h b/include/misc/cxl.h
new file mode 100644
index 000000000000..7a6c1d6cc173
--- /dev/null
+++ b/include/misc/cxl.h
@@ -0,0 +1,203 @@
1/*
2 * Copyright 2015 IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 */
9
10#ifndef _MISC_CXL_H
11#define _MISC_CXL_H
12
13#include <linux/pci.h>
14#include <linux/poll.h>
15#include <linux/interrupt.h>
16#include <uapi/misc/cxl.h>
17
18/*
19 * This documents the in kernel API for driver to use CXL. It allows kernel
20 * drivers to bind to AFUs using an AFU configuration record exposed as a PCI
21 * configuration record.
22 *
23 * This API enables control over AFU and contexts which can't be part of the
24 * generic PCI API. This API is agnostic to the actual AFU.
25 */
26
27/* Get the AFU associated with a pci_dev */
28struct cxl_afu *cxl_pci_to_afu(struct pci_dev *dev);
29
30/* Get the AFU conf record number associated with a pci_dev */
31unsigned int cxl_pci_to_cfg_record(struct pci_dev *dev);
32
33/* Get the physical device (ie. the PCIe card) which the AFU is attached */
34struct device *cxl_get_phys_dev(struct pci_dev *dev);
35
36
37/*
38 * Context lifetime overview:
39 *
40 * An AFU context may be inited and then started and stoppped multiple times
41 * before it's released. ie.
42 * - cxl_dev_context_init()
43 * - cxl_start_context()
44 * - cxl_stop_context()
45 * - cxl_start_context()
46 * - cxl_stop_context()
47 * ...repeat...
48 * - cxl_release_context()
49 * Once released, a context can't be started again.
50 *
51 * One context is inited by the cxl driver for every pci_dev. This is to be
52 * used as a default kernel context. cxl_get_context() will get this
53 * context. This context will be released by PCI hot unplug, so doesn't need to
54 * be released explicitly by drivers.
55 *
56 * Additional kernel contexts may be inited using cxl_dev_context_init().
57 * These must be released using cxl_context_detach().
58 *
59 * Once a context has been inited, IRQs may be configured. Firstly these IRQs
60 * must be allocated (cxl_allocate_afu_irqs()), then individually mapped to
61 * specific handlers (cxl_map_afu_irq()).
62 *
63 * These IRQs can be unmapped (cxl_unmap_afu_irq()) and finally released
64 * (cxl_free_afu_irqs()).
65 *
66 * The AFU can be reset (cxl_afu_reset()). This will cause the PSL/AFU
67 * hardware to lose track of all contexts. It's upto the caller of
68 * cxl_afu_reset() to restart these contexts.
69 */
70
71/*
72 * On pci_enabled_device(), the cxl driver will init a single cxl context for
73 * use by the driver. It doesn't start this context (as that will likely
74 * generate DMA traffic for most AFUs).
75 *
76 * This gets the default context associated with this pci_dev. This context
77 * doesn't need to be released as this will be done by the PCI subsystem on hot
78 * unplug.
79 */
80struct cxl_context *cxl_get_context(struct pci_dev *dev);
81/*
82 * Allocate and initalise a context associated with a AFU PCI device. This
83 * doesn't start the context in the AFU.
84 */
85struct cxl_context *cxl_dev_context_init(struct pci_dev *dev);
86/*
87 * Release and free a context. Context should be stopped before calling.
88 */
89int cxl_release_context(struct cxl_context *ctx);
90
91/*
92 * Allocate AFU interrupts for this context. num=0 will allocate the default
93 * for this AFU as given in the AFU descriptor. This number doesn't include the
94 * interrupt 0 (CAIA defines AFU IRQ 0 for page faults). Each interrupt to be
95 * used must map a handler with cxl_map_afu_irq.
96 */
97int cxl_allocate_afu_irqs(struct cxl_context *cxl, int num);
98/* Free allocated interrupts */
99void cxl_free_afu_irqs(struct cxl_context *cxl);
100
101/*
102 * Map a handler for an AFU interrupt associated with a particular context. AFU
103 * IRQS numbers start from 1 (CAIA defines AFU IRQ 0 for page faults). cookie
104 * is private data is that will be provided to the interrupt handler.
105 */
106int cxl_map_afu_irq(struct cxl_context *cxl, int num,
107 irq_handler_t handler, void *cookie, char *name);
108/* unmap mapped IRQ handlers */
109void cxl_unmap_afu_irq(struct cxl_context *cxl, int num, void *cookie);
110
111/*
112 * Start work on the AFU. This starts an cxl context and associates it with a
113 * task. task == NULL will make it a kernel context.
114 */
115int cxl_start_context(struct cxl_context *ctx, u64 wed,
116 struct task_struct *task);
117/*
118 * Stop a context and remove it from the PSL
119 */
120int cxl_stop_context(struct cxl_context *ctx);
121
122/* Reset the AFU */
123int cxl_afu_reset(struct cxl_context *ctx);
124
125/*
126 * Set a context as a master context.
127 * This sets the default problem space area mapped as the full space, rather
128 * than just the per context area (for slaves).
129 */
130void cxl_set_master(struct cxl_context *ctx);
131
132/*
133 * Map and unmap the AFU Problem Space area. The amount and location mapped
134 * depends on if this context is a master or slave.
135 */
136void __iomem *cxl_psa_map(struct cxl_context *ctx);
137void cxl_psa_unmap(void __iomem *addr);
138
139/* Get the process element for this context */
140int cxl_process_element(struct cxl_context *ctx);
141
142
143/*
144 * These calls allow drivers to create their own file descriptors and make them
145 * identical to the cxl file descriptor user API. An example use case:
146 *
147 * struct file_operations cxl_my_fops = {};
148 * ......
149 * // Init the context
150 * ctx = cxl_dev_context_init(dev);
151 * if (IS_ERR(ctx))
152 * return PTR_ERR(ctx);
153 * // Create and attach a new file descriptor to my file ops
154 * file = cxl_get_fd(ctx, &cxl_my_fops, &fd);
155 * // Start context
156 * rc = cxl_start_work(ctx, &work.work);
157 * if (rc) {
158 * fput(file);
159 * put_unused_fd(fd);
160 * return -ENODEV;
161 * }
162 * // No error paths after installing the fd
163 * fd_install(fd, file);
164 * return fd;
165 *
166 * This inits a context, and gets a file descriptor and associates some file
167 * ops to that file descriptor. If the file ops are blank, the cxl driver will
168 * fill them in with the default ones that mimic the standard user API. Once
169 * completed, the file descriptor can be installed. Once the file descriptor is
170 * installed, it's visible to the user so no errors must occur past this point.
171 *
172 * If cxl_fd_release() file op call is installed, the context will be stopped
173 * and released when the fd is released. Hence the driver won't need to manage
174 * this itself.
175 */
176
177/*
178 * Take a context and associate it with my file ops. Returns the associated
179 * file and file descriptor. Any file ops which are blank are filled in by the
180 * cxl driver with the default ops to mimic the standard API.
181 */
182struct file *cxl_get_fd(struct cxl_context *ctx, struct file_operations *fops,
183 int *fd);
184/* Get the context associated with this file */
185struct cxl_context *cxl_fops_get_context(struct file *file);
186/*
187 * Start a context associated a struct cxl_ioctl_start_work used by the
188 * standard cxl user API.
189 */
190int cxl_start_work(struct cxl_context *ctx,
191 struct cxl_ioctl_start_work *work);
192/*
193 * Export all the existing fops so drivers can use them
194 */
195int cxl_fd_open(struct inode *inode, struct file *file);
196int cxl_fd_release(struct inode *inode, struct file *file);
197long cxl_fd_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
198int cxl_fd_mmap(struct file *file, struct vm_area_struct *vm);
199unsigned int cxl_fd_poll(struct file *file, struct poll_table_struct *poll);
200ssize_t cxl_fd_read(struct file *file, char __user *buf, size_t count,
201 loff_t *off);
202
203#endif /* _MISC_CXL_H */