Skip to content

Commit

Permalink
cxl: Support to flash a new image on the adapter from a guest
Browse files Browse the repository at this point in the history
The new flash.c file contains the logic to flash a new image on the
adapter, through a hcall. It is an iterative process, with chunks of
data of 1M at a time. There are also 2 phases: write and verify. The
flash operation itself is driven from a user-land tool.
Once flashing is successful, an rtas call is made to update the device
tree with the new properties values for the adapter and the AFU(s)

Add a new char device for the adapter, so that the flash tool can
access the card, even if there is no valid AFU on it.

Co-authored-by: Frederic Barrat <[email protected]>
Signed-off-by: Frederic Barrat <[email protected]>
Signed-off-by: Christophe Lombard <[email protected]>
Reviewed-by: Manoj Kumar <[email protected]>
Acked-by: Ian Munsie <[email protected]>
Signed-off-by: Michael Ellerman <[email protected]>
  • Loading branch information
2 people authored and mpe committed Mar 9, 2016
1 parent 4752876 commit 594ff7d
Show file tree
Hide file tree
Showing 8 changed files with 653 additions and 5 deletions.
55 changes: 55 additions & 0 deletions Documentation/powerpc/cxl.txt
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ Work Element Descriptor (WED)
User API
========

1. AFU character devices

For AFUs operating in AFU directed mode, two character device
files will be created. /dev/cxl/afu0.0m will correspond to a
master context and /dev/cxl/afu0.0s will correspond to a slave
Expand Down Expand Up @@ -362,6 +364,59 @@ read
reserved fields:
For future extensions and padding


2. Card character device (powerVM guest only)

In a powerVM guest, an extra character device is created for the
card. The device is only used to write (flash) a new image on the
FPGA accelerator. Once the image is written and verified, the
device tree is updated and the card is reset to reload the updated
image.

open
----

Opens the device and allocates a file descriptor to be used with
the rest of the API. The device can only be opened once.

ioctl
-----

CXL_IOCTL_DOWNLOAD_IMAGE:
CXL_IOCTL_VALIDATE_IMAGE:
Starts and controls flashing a new FPGA image. Partial
reconfiguration is not supported (yet), so the image must contain
a copy of the PSL and AFU(s). Since an image can be quite large,
the caller may have to iterate, splitting the image in smaller
chunks.

Takes a pointer to a struct cxl_adapter_image:
struct cxl_adapter_image {
__u64 flags;
__u64 data;
__u64 len_data;
__u64 len_image;
__u64 reserved1;
__u64 reserved2;
__u64 reserved3;
__u64 reserved4;
};

flags:
These flags indicate which optional fields are present in
this struct. Currently all fields are mandatory.

data:
Pointer to a buffer with part of the image to write to the
card.

len_data:
Size of the buffer pointed to by data.

len_image:
Full size of the image.


Sysfs Class
===========

Expand Down
2 changes: 1 addition & 1 deletion drivers/misc/cxl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ccflags-$(CONFIG_PPC_WERROR) += -Werror
cxl-y += main.o file.o irq.o fault.o native.o
cxl-y += context.o sysfs.o debugfs.o pci.o trace.o
cxl-y += vphb.o api.o
cxl-$(CONFIG_PPC_PSERIES) += guest.o of.o hcalls.o
cxl-$(CONFIG_PPC_PSERIES) += flash.o guest.o of.o hcalls.o
obj-$(CONFIG_CXL) += cxl.o
obj-$(CONFIG_CXL_BASE) += base.o

Expand Down
7 changes: 7 additions & 0 deletions drivers/misc/cxl/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,10 @@ void unregister_cxl_calls(struct cxl_calls *calls)
synchronize_rcu();
}
EXPORT_SYMBOL_GPL(unregister_cxl_calls);

int cxl_update_properties(struct device_node *dn,
struct property *new_prop)
{
return of_update_property(dn, new_prop);
}
EXPORT_SYMBOL_GPL(cxl_update_properties);
6 changes: 6 additions & 0 deletions drivers/misc/cxl/cxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,10 @@ static const cxl_p2n_reg_t CXL_PSL_WED_An = {0x0A0};
#define CXL_MODE_TIME_SLICED 0x4
#define CXL_SUPPORTED_MODES (CXL_MODE_DEDICATED | CXL_MODE_DIRECTED)

#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */
#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)

enum cxl_context_status {
CLOSED,
OPENED,
Expand Down Expand Up @@ -692,12 +696,14 @@ struct cxl_calls {
};
int register_cxl_calls(struct cxl_calls *calls);
void unregister_cxl_calls(struct cxl_calls *calls);
int cxl_update_properties(struct device_node *dn, struct property *new_prop);

void cxl_remove_adapter_nr(struct cxl *adapter);

int cxl_alloc_spa(struct cxl_afu *afu);
void cxl_release_spa(struct cxl_afu *afu);

dev_t cxl_get_dev(void);
int cxl_file_init(void);
void cxl_file_exit(void);
int cxl_register_adapter(struct cxl *adapter);
Expand Down
11 changes: 7 additions & 4 deletions drivers/misc/cxl/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,14 @@
#include "trace.h"

#define CXL_NUM_MINORS 256 /* Total to reserve */
#define CXL_DEV_MINORS 13 /* 1 control + 4 AFUs * 3 (dedicated/master/shared) */

#define CXL_CARD_MINOR(adapter) (adapter->adapter_num * CXL_DEV_MINORS)
#define CXL_AFU_MINOR_D(afu) (CXL_CARD_MINOR(afu->adapter) + 1 + (3 * afu->slice))
#define CXL_AFU_MINOR_M(afu) (CXL_AFU_MINOR_D(afu) + 1)
#define CXL_AFU_MINOR_S(afu) (CXL_AFU_MINOR_D(afu) + 2)
#define CXL_AFU_MKDEV_D(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_D(afu))
#define CXL_AFU_MKDEV_M(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_M(afu))
#define CXL_AFU_MKDEV_S(afu) MKDEV(MAJOR(cxl_dev), CXL_AFU_MINOR_S(afu))

#define CXL_DEVT_ADAPTER(dev) (MINOR(dev) / CXL_DEV_MINORS)
#define CXL_DEVT_AFU(dev) ((MINOR(dev) % CXL_DEV_MINORS - 1) / 3)

#define CXL_DEVT_IS_CARD(dev) (MINOR(dev) % CXL_DEV_MINORS == 0)
Expand Down Expand Up @@ -446,7 +443,8 @@ static const struct file_operations afu_master_fops = {

static char *cxl_devnode(struct device *dev, umode_t *mode)
{
if (CXL_DEVT_IS_CARD(dev->devt)) {
if (cpu_has_feature(CPU_FTR_HVMODE) &&
CXL_DEVT_IS_CARD(dev->devt)) {
/*
* These minor numbers will eventually be used to program the
* PSL and AFUs once we have dynamic reprogramming support
Expand Down Expand Up @@ -547,6 +545,11 @@ int cxl_register_adapter(struct cxl *adapter)
return device_register(&adapter->dev);
}

dev_t cxl_get_dev(void)
{
return cxl_dev;
}

int __init cxl_file_init(void)
{
int rc;
Expand Down
Loading

0 comments on commit 594ff7d

Please sign in to comment.