@samitouri / QOSamiQemu / commits / 5ed17bb32a

pc-bios/s390-ccw: Introduce PCI device

Define selected s390x PCI instructions. Signed-off-by: Jared Rossi <jrossi@linux.ibm.com> Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com> Acked-by: Thomas Huth <thuth@redhat.com> Message-ID: <20260309003601.242634-11-jrossi@linux.ibm.com> Reviewed-by: Farhan Ali <alifm@linux.ibm.com> [thuth: Remove unused defines as suggested by Farhan] Signed-off-by: Thomas Huth <thuth@redhat.com>

Jared Rossi committed Mar 8, 2026 at 20:35 UTC 5ed17bb32abc5aa78dc321ae672a1520f4730873
3 files changed +155 -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 clp.o
38 + virtio-ccw.o clp.o pci.o
39
40 SLOF_DIR := $(SRC_PATH)/../../roms/SLOF
41
pc-bios/s390-ccw/pci.c new
+118
@@ -0,0 +1,118 @@
1 +/*
2 + * s390x PCI functionality
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 "pci.h"
12 +#include "bswap.h"
13 +#include <stdio.h>
14 +#include <stdbool.h>
15 +
16 +/* PCI load */
17 +static inline int pcilg(uint64_t *data, uint64_t req, uint64_t offset,
18 + uint8_t *status)
19 +{
20 + union register_pair req_off = {.even = req, .odd = offset};
21 + int cc = -1;
22 + uint64_t __data;
23 +
24 + asm volatile (
25 + " .insn rre,0xb9d20000,%[data],%[req_off]\n"
26 + " ipm %[cc]\n"
27 + " srl %[cc],28\n"
28 + : [cc] "+d" (cc), [data] "=d" (__data),
29 + [req_off] "+d" (req_off.pair) :: "cc");
30 + *status = req_off.even >> 24 & 0xff;
31 + *data = __data;
32 + return cc;
33 +}
34 +
35 +/* PCI store */
36 +static inline int pcistg(uint64_t data, uint64_t req, uint64_t offset,
37 + uint8_t *status)
38 +{
39 + union register_pair req_off = {.even = req, .odd = offset};
40 + int cc = -1;
41 +
42 + asm volatile (
43 + " .insn rre,0xb9d00000,%[data],%[req_off]\n"
44 + " ipm %[cc]\n"
45 + " srl %[cc],28\n"
46 + : [cc] "+d" (cc), [req_off] "+d" (req_off.pair)
47 + : [data] "d" (data)
48 + : "cc");
49 + *status = req_off.even >> 24 & 0xff;
50 + return cc;
51 +}
52 +
53 +int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
54 + uint8_t len)
55 +{
56 +
57 + uint64_t req = ZPCI_CREATE_REQ(fhandle, pcias, len);
58 + uint8_t status;
59 + int rc;
60 +
61 + /* len must be non-zero power of 2 with a maximum of 8 bytes per write */
62 + switch (len) {
63 + case 1:
64 + case 2:
65 + case 4:
66 + case 8:
67 + rc = pcistg(data, req, offset, &status);
68 + break;
69 + default:
70 + return -1;
71 + }
72 +
73 + /* Error condition detected */
74 + if (rc != 0) {
75 + printf("PCI store failed with status condition %d, return code %d\n",
76 + status, rc);
77 + return -1;
78 + }
79 +
80 + return 0;
81 +}
82 +
83 +int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
84 + uint8_t len)
85 +{
86 + uint64_t req, data;
87 + uint8_t status;
88 + int rc;
89 +
90 + req = ZPCI_CREATE_REQ(fhandle, pcias, len);
91 + rc = pcilg(&data, req, offset, &status);
92 +
93 + /* Error condition detected */
94 + if (rc != 0) {
95 + printf("PCI load failed with status condition %d, return code %d\n",
96 + status, rc);
97 + return -1;
98 + }
99 +
100 + switch (len) {
101 + case 1:
102 + *(uint8_t *)buf = data;
103 + break;
104 + case 2:
105 + *(uint16_t *)buf = data;
106 + break;
107 + case 4:
108 + *(uint32_t *)buf = data;
109 + break;
110 + case 8:
111 + *(uint64_t *)buf = data;
112 + break;
113 + default:
114 + return -1;
115 + }
116 +
117 + return 0;
118 +}
pc-bios/s390-ccw/pci.h new
+36
@@ -0,0 +1,36 @@
1 +/*
2 + * s390x PCI 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 PCI_H
11 +#define PCI_H
12 +
13 +#include <stdint.h>
14 +#include <stdbool.h>
15 +#include "clp.h"
16 +
17 +#define ZPCI_CREATE_REQ(handle, space, len) \
18 + ((uint64_t) handle << 32 | space << 16 | len)
19 +
20 +union register_pair {
21 + unsigned __int128 pair;
22 + struct {
23 + unsigned long even;
24 + unsigned long odd;
25 + };
26 +};
27 +
28 +#define PCI_CFGBAR 0xF /* Base Address Register for config space */
29 +#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
30 +
31 +int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
32 + uint8_t len);
33 +int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
34 + uint8_t len);
35 +
36 +#endif