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>
This commit is contained in:
Jared Rossi
2026-03-08 20:35:56 -04:00
committed by Thomas Huth
parent 284a595c47
commit 5ed17bb32a
3 changed files with 155 additions and 1 deletions

View File

@@ -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 clp.o
virtio-ccw.o clp.o pci.o
SLOF_DIR := $(SRC_PATH)/../../roms/SLOF

118
pc-bios/s390-ccw/pci.c Normal file
View File

@@ -0,0 +1,118 @@
/*
* s390x PCI functionality
*
* Copyright 2025 IBM Corp.
* Author(s): Jared Rossi <jrossi@linux.ibm.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "clp.h"
#include "pci.h"
#include "bswap.h"
#include <stdio.h>
#include <stdbool.h>
/* PCI load */
static inline int pcilg(uint64_t *data, uint64_t req, uint64_t offset,
uint8_t *status)
{
union register_pair req_off = {.even = req, .odd = offset};
int cc = -1;
uint64_t __data;
asm volatile (
" .insn rre,0xb9d20000,%[data],%[req_off]\n"
" ipm %[cc]\n"
" srl %[cc],28\n"
: [cc] "+d" (cc), [data] "=d" (__data),
[req_off] "+d" (req_off.pair) :: "cc");
*status = req_off.even >> 24 & 0xff;
*data = __data;
return cc;
}
/* PCI store */
static inline int pcistg(uint64_t data, uint64_t req, uint64_t offset,
uint8_t *status)
{
union register_pair req_off = {.even = req, .odd = offset};
int cc = -1;
asm volatile (
" .insn rre,0xb9d00000,%[data],%[req_off]\n"
" ipm %[cc]\n"
" srl %[cc],28\n"
: [cc] "+d" (cc), [req_off] "+d" (req_off.pair)
: [data] "d" (data)
: "cc");
*status = req_off.even >> 24 & 0xff;
return cc;
}
int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
uint8_t len)
{
uint64_t req = ZPCI_CREATE_REQ(fhandle, pcias, len);
uint8_t status;
int rc;
/* len must be non-zero power of 2 with a maximum of 8 bytes per write */
switch (len) {
case 1:
case 2:
case 4:
case 8:
rc = pcistg(data, req, offset, &status);
break;
default:
return -1;
}
/* Error condition detected */
if (rc != 0) {
printf("PCI store failed with status condition %d, return code %d\n",
status, rc);
return -1;
}
return 0;
}
int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
uint8_t len)
{
uint64_t req, data;
uint8_t status;
int rc;
req = ZPCI_CREATE_REQ(fhandle, pcias, len);
rc = pcilg(&data, req, offset, &status);
/* Error condition detected */
if (rc != 0) {
printf("PCI load failed with status condition %d, return code %d\n",
status, rc);
return -1;
}
switch (len) {
case 1:
*(uint8_t *)buf = data;
break;
case 2:
*(uint16_t *)buf = data;
break;
case 4:
*(uint32_t *)buf = data;
break;
case 8:
*(uint64_t *)buf = data;
break;
default:
return -1;
}
return 0;
}

36
pc-bios/s390-ccw/pci.h Normal file
View File

@@ -0,0 +1,36 @@
/*
* s390x PCI definitions
*
* Copyright 2025 IBM Corp.
* Author(s): Jared Rossi <jrossi@linux.ibm.com>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef PCI_H
#define PCI_H
#include <stdint.h>
#include <stdbool.h>
#include "clp.h"
#define ZPCI_CREATE_REQ(handle, space, len) \
((uint64_t) handle << 32 | space << 16 | len)
union register_pair {
unsigned __int128 pair;
struct {
unsigned long even;
unsigned long odd;
};
};
#define PCI_CFGBAR 0xF /* Base Address Register for config space */
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
int pci_write(uint32_t fhandle, uint64_t offset, uint8_t pcias, uint64_t data,
uint8_t len);
int pci_read(uint32_t fhandle, uint64_t offset, uint8_t pcias, void *buf,
uint8_t len);
#endif