@samitouri / QOSamiQemu / commits / d3da8afd1d

pc-bios/s390-ccw: Introduce CLP Architecture

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. Reviewed-by: Eric Farman <farman@linux.ibm.com> Signed-off-by: Jared Rossi <jrossi@linux.ibm.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Reviewed-by: Farhan Ali <alifm@linux.ibm.com> Message-ID: <20260309003601.242634-9-jrossi@linux.ibm.com> [thuth: fix a typo in one of the comments] Signed-off-by: Thomas Huth <thuth@redhat.com>

Jared Rossi committed Mar 8, 2026 at 20:35 UTC d3da8afd1dd5623ebaef8be45c3ad40eb57a2edb
3 files changed +124 -1
pc-bios/s390-ccw/Makefile
+1 -1
@@ -35,7 +35,7 @@ QEMU_DGFLAGS = -MMD -MP -MT $@ -MF $(@D)/$(*F).d
35
36 OBJECTS = start.o main.o bootmap.o jump2ipl.o sclp.o menu.o netmain.o \
37 virtio.o virtio-net.o virtio-scsi.o virtio-blkdev.o cio.o dasd-ipl.o \
38 - virtio-ccw.o
38 + virtio-ccw.o clp.o
39
40 SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
41
pc-bios/s390-ccw/clp.c new
+99
@@ -0,0 +1,99 @@
1 +/*
2 + * Call Logical Processor (CLP) architecture
3 + *
4 + * Copyright 2025 IBM Corp.
5 + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
6 + *
7 + * SPDX-License-Identifier: GPL-2.0-or-later
8 + */
9 +
10 +#include "clp.h"
11 +#include <stdio.h>
12 +#include <string.h>
13 +
14 +int clp_pci(void *data)
15 +{
16 + struct { uint8_t _[CLP_BLK_SIZE]; } *req = data;
17 + int cc = 3;
18 +
19 + asm volatile (
20 + " .insn rrf,0xb9a00000,0,%[req],0,2\n"
21 + " ipm %[cc]\n"
22 + " srl %[cc],28\n"
23 + : [cc] "+d" (cc), "+m" (*req)
24 + : [req] "a" (req)
25 + : "cc");
26 + if (cc) {
27 + printf("CLP returned with non-zero condition code %d\n", cc);
28 + }
29 + return cc;
30 +}
31 +
32 +/*
33 + * Get the PCI function entry for a given function ID
34 + * Return 0 on success, 1 if the FID is not found, or a negative RC on error
35 + */
36 +int find_pci_function(uint32_t fid, ClpFhListEntry *entry)
37 +{
38 + int count = 0;
39 + int limit = PCI_MAX_FUNCTIONS;
40 + ClpReqRspListPci rrb;
41 +
42 + rrb.request.hdr.len = sizeof(ClpReqListPci);
43 + rrb.request.hdr.cmd = 0x02;
44 + rrb.request.resume_token = 0;
45 + rrb.response.hdr.len = sizeof(ClpRspListPci);
46 +
47 + do {
48 + if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
49 + puts("Failed to list PCI functions");
50 + return -1;
51 + }
52 +
53 + /* Resume token set when max entries are returned */
54 + if (rrb.response.resume_token) {
55 + count = CLP_FH_LIST_NR_ENTRIES;
56 + rrb.request.resume_token = rrb.response.resume_token;
57 + } else {
58 + count = (rrb.response.hdr.len - 32) / sizeof(ClpFhListEntry);
59 + }
60 +
61 + limit -= count;
62 +
63 + for (int i = 0; i < count; i++) {
64 + if (rrb.response.fh_list[i].fid == fid) {
65 + memcpy(entry, &rrb.response.fh_list[i], sizeof(ClpFhListEntry));
66 + return 0;
67 + }
68 + }
69 +
70 + } while (rrb.request.resume_token && limit > 0);
71 +
72 + puts("No function entry found for FID!");
73 +
74 + return 1;
75 +}
76 +
77 +/*
78 + * Enable the PCI function associated with a given handle
79 + * Return 0 on success or a negative RC on error
80 + */
81 +int enable_pci_function(uint32_t *fhandle)
82 +{
83 + ClpReqRspSetPci rrb;
84 +
85 + rrb.request.hdr.len = sizeof(ClpReqSetPci);
86 + rrb.request.hdr.cmd = 0x05;
87 + rrb.request.fh = *fhandle;
88 + rrb.request.oc = 0;
89 + rrb.request.ndas = 1;
90 + rrb.response.hdr.len = sizeof(ClpRspSetPci);
91 +
92 + if (clp_pci(&rrb) || rrb.response.hdr.rsp != 0x0010) {
93 + puts("Failed to enable PCI function");
94 + return -1;
95 + }
96 +
97 + *fhandle = rrb.response.fh;
98 + return 0;
99 +}
pc-bios/s390-ccw/clp.h new
+24
@@ -0,0 +1,24 @@
1 +/*
2 + * Call Logical Processor (CLP) architecture definitions
3 + *
4 + * Copyright 2025 IBM Corp.
5 + * Author(s): Jared Rossi <jrossi@linux.ibm.com>
6 + *
7 + * SPDX-License-Identifier: GPL-2.0-or-later
8 + */
9 +
10 +#ifndef CLP_H
11 +#define CLP_H
12 +
13 +#ifndef QEMU_PACKED
14 +#define QEMU_PACKED __attribute__((packed))
15 +#endif
16 +
17 +#include <stdint.h>
18 +#include <s390-pci-clp.h>
19 +
20 +int clp_pci(void *data);
21 +int find_pci_function(uint32_t fid, ClpFhListEntry *entry);
22 +int enable_pci_function(uint32_t *fhandle);
23 +
24 +#endif