On 3/8/26 8:35 PM, [email protected] wrote: > From: Jared Rossi <[email protected]> > > Call Logical Processor (CLP) Architecture is used for managing PCI functions > on > s390x. Define and include the structures and routines needed to interact with > PCI devices during IPL. > > Acked-by: Thomas Huth <[email protected]> > Reviewed-by: Eric Farman <[email protected]> > Signed-off-by: Jared Rossi <[email protected]>
Reviewed-by: Matthew Rosato <[email protected]> > --- > pc-bios/s390-ccw/Makefile | 2 +- > pc-bios/s390-ccw/clp.c | 99 +++++++++++++++++++++++++++++++++++++++ > pc-bios/s390-ccw/clp.h | 24 ++++++++++ > 3 files changed, 124 insertions(+), 1 deletion(-) > create mode 100644 pc-bios/s390-ccw/clp.c > create mode 100644 pc-bios/s390-ccw/clp.h > > diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile > index 259cff09db..9c29548f84 100644 > --- a/pc-bios/s390-ccw/Makefile > +++ b/pc-bios/s390-ccw/Makefile > @@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d > > OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \ > virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \ > - virtio-ccw.o > + virtio-ccw.o clp.o > > SLOF_DIR := $(SRC_PATH)/../../roms/SLOF > > diff --git a/pc-bios/s390-ccw/clp.c b/pc-bios/s390-ccw/clp.c > new file mode 100644 > index 0000000000..8c04738bbf > --- /dev/null > +++ b/pc-bios/s390-ccw/clp.c > @@ -0,0 +1,99 @@ > +/* > + * Call Logical Processor (CLP) architecture > + * > + * Copyright 2025 IBM Corp. > + * Author(s): Jared Rossi <[email protected]> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#include "clp.h" > +#include <stdio.h> > +#include <string.h> > + > +int clp_pci(void *data) > +{ > + struct { uint8_t _[CLP_BLK_SIZE]; } *req = data; > + int cc = 3; > + > + asm volatile ( > + " .insn rrf,0xb9a00000,0,%[req],0,2\n" > + " ipm %[cc]\n" > + " srl %[cc],28\n" > + : [cc] "+d" (cc), "+m" (*req) > + : [req] "a" (req) > + : "cc"); > + if (cc) { > + printf("CLP returned with non-zero condition code %d\n", cc); > + } > + return cc; > +} > + > +/* > + * Get the PCI function entry for a given function ID > + * Return 0 on success, 1 if the FID is not found, or a negative RC on error > + */ > +int find_pci_function(uint32_t fid, ClpFhListEntry *entry) > +{ > + int count = 0; > + int limit = PCI_MAX_FUNCTIONS; > + ClpReqRspListPci rrb; > + > + rrb.request.hdr.len = sizeof(ClpReqListPci); > + rrb.request.hdr.cmd = 0x02; > + rrb.request.resume_token = 0; > + rrb.response.hdr.len = sizeof(ClpRspListPci); > + > + do { > + if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) { > + puts("Failed to list PCI functions"); > + return -1; > + } > + > + /* Resume token set when max enteries are returned */ > + if (rrb.response.resume_token) { > + count = CLP_FH_LIST_NR_ENTRIES; > + rrb.request.resume_token = rrb.response.resume_token; > + } else { > + count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry); > + } > + > + limit -= count; > + > + for (int i = 0; i < count; i++) { > + if (rrb.response.fh_list[i].fid == fid) { > + memcpy(entry, &rrb.response.fh_list[i], > sizeof(ClpFhListEntry)); > + return 0; > + } > + } > + > + } while (rrb.request.resume_token && limit > 0); > + > + puts("No function entry found for FID!"); > + > + return 1; > +} > + > +/* > + * Enable the PCI function associated with a given handle > + * Return 0 on success or a negative RC on error > + */ > +int enable_pci_function(uint32_t *fhandle) > +{ > + ClpReqRspSetPci rrb; > + > + rrb.request.hdr.len = sizeof(ClpReqSetPci); > + rrb.request.hdr.cmd = 0x05; > + rrb.request.fh = *fhandle; > + rrb.request.oc = 0; > + rrb.request.ndas = 1; > + rrb.response.hdr.len = sizeof(ClpRspSetPci); > + > + if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) { > + puts("Failed to enable PCI function"); > + return -1; > + } > + > + *fhandle = rrb.response.fh; > + return 0; > +} > diff --git a/pc-bios/s390-ccw/clp.h b/pc-bios/s390-ccw/clp.h > new file mode 100644 > index 0000000000..1ac2f8c177 > --- /dev/null > +++ b/pc-bios/s390-ccw/clp.h > @@ -0,0 +1,24 @@ > +/* > + * Call Logical Processor (CLP) architecture definitions > + * > + * Copyright 2025 IBM Corp. > + * Author(s): Jared Rossi <[email protected]> > + * > + * SPDX-License-Identifier: GPL-2.0-or-later > + */ > + > +#ifndef CLP_H > +#define CLP_H > + > +#ifndef QEMU_PACKED > +#define QEMU_PACKED __attribute__((packed)) > +#endif > + > +#include <stdint.h> > +#include <s390-pci-clp.h> > + > +int clp_pci(void *data); > +int find_pci_function(uint32_t fid, ClpFhListEntry *entry); > +int enable_pci_function(uint32_t *fhandle); > + > +#endif
