Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 594ff7d0 authored by Christophe Lombard's avatar Christophe Lombard Committed by Michael Ellerman
Browse files

cxl: Support to flash a new image on the adapter from a guest



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: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarFrederic Barrat <fbarrat@linux.vnet.ibm.com>
Signed-off-by: default avatarChristophe Lombard <clombard@linux.vnet.ibm.com>
Reviewed-by: default avatarManoj Kumar <manoj@linux.vnet.ibm.com>
Acked-by: default avatarIan Munsie <imunsie@au1.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 4752876c
Loading
Loading
Loading
Loading
+55 −0
Original line number Diff line number Diff line
@@ -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
@@ -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
===========

+1 −1
Original line number Diff line number Diff line
@@ -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

+7 −0
Original line number Diff line number Diff line
@@ -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 −0
Original line number Diff line number Diff line
@@ -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,
@@ -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);
+7 −4
Original line number Diff line number Diff line
@@ -26,9 +26,7 @@
#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)
@@ -36,7 +34,6 @@
#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)
@@ -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
@@ -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;
Loading