mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:17 +00:00
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:
@@ -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
118
pc-bios/s390-ccw/pci.c
Normal 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
36
pc-bios/s390-ccw/pci.h
Normal 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
|
||||
Reference in New Issue
Block a user