Currently the pseries machine contains not one but two somewhat ugly hacks to allow printing of early debug messages before the guest has properly read the device tree. First, we special case H_PUT_TERM_CHAR so that a vtermno of 0 (usually invalid) will look for a suitable vty and use that. This supports Linux's early debug code which will use H_PUT_TERM_CHAR with vtermno==0 before reading the device tree. Second, we support the RTAS display-character call. This takes no vtermno so we assume the address of the default first VTY. This patch makes things more consistent by folding the second hack into the first. Now, display-character uses the existing vty_lookup() function to do the same search for a suitable VTY. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Andreas Färber <afaerber@suse.de>
132 lines
4.6 KiB
C
132 lines
4.6 KiB
C
#ifndef _HW_SPAPR_VIO_H
|
|
#define _HW_SPAPR_VIO_H
|
|
/*
|
|
* QEMU sPAPR VIO bus definitions
|
|
*
|
|
* Copyright (c) 2010 David Gibson, IBM Corporation <david@gibson.dropbear.id.au>
|
|
* Based on the s390 virtio bus definitions:
|
|
* Copyright (c) 2009 Alexander Graf <agraf@suse.de>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define SPAPR_VIO_TCE_PAGE_SHIFT 12
|
|
#define SPAPR_VIO_TCE_PAGE_SIZE (1ULL << SPAPR_VIO_TCE_PAGE_SHIFT)
|
|
#define SPAPR_VIO_TCE_PAGE_MASK (SPAPR_VIO_TCE_PAGE_SIZE - 1)
|
|
|
|
enum VIOsPAPR_TCEAccess {
|
|
SPAPR_TCE_FAULT = 0,
|
|
SPAPR_TCE_RO = 1,
|
|
SPAPR_TCE_WO = 2,
|
|
SPAPR_TCE_RW = 3,
|
|
};
|
|
|
|
#define SPAPR_VTY_BASE_ADDRESS 0x30000000
|
|
|
|
#define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device"
|
|
#define VIO_SPAPR_DEVICE(obj) \
|
|
OBJECT_CHECK(VIOsPAPRDevice, (obj), TYPE_VIO_SPAPR_DEVICE)
|
|
#define VIO_SPAPR_DEVICE_CLASS(klass) \
|
|
OBJECT_CLASS_CHECK(VIOsPAPRDeviceClass, (klass), TYPE_VIO_SPAPR_DEVICE)
|
|
#define VIO_SPAPR_DEVICE_GET_CLASS(obj) \
|
|
OBJECT_GET_CLASS(VIOsPAPRDeviceClass, (obj), TYPE_VIO_SPAPR_DEVICE)
|
|
|
|
struct VIOsPAPRDevice;
|
|
|
|
typedef struct VIOsPAPR_RTCE {
|
|
uint64_t tce;
|
|
} VIOsPAPR_RTCE;
|
|
|
|
typedef struct VIOsPAPR_CRQ {
|
|
uint64_t qladdr;
|
|
uint32_t qsize;
|
|
uint32_t qnext;
|
|
int(*SendFunc)(struct VIOsPAPRDevice *vdev, uint8_t *crq);
|
|
} VIOsPAPR_CRQ;
|
|
|
|
typedef struct VIOsPAPRDevice VIOsPAPRDevice;
|
|
typedef struct VIOsPAPRBus VIOsPAPRBus;
|
|
|
|
typedef struct VIOsPAPRDeviceClass {
|
|
DeviceClass parent_class;
|
|
|
|
const char *dt_name, *dt_type, *dt_compatible;
|
|
target_ulong signal_mask;
|
|
int (*init)(VIOsPAPRDevice *dev);
|
|
void (*hcalls)(VIOsPAPRBus *bus);
|
|
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
|
|
} VIOsPAPRDeviceClass;
|
|
|
|
struct VIOsPAPRDevice {
|
|
DeviceState qdev;
|
|
uint32_t reg;
|
|
uint32_t flags;
|
|
#define VIO_PAPR_FLAG_DMA_BYPASS 0x1
|
|
qemu_irq qirq;
|
|
uint32_t vio_irq_num;
|
|
target_ulong signal_state;
|
|
uint32_t rtce_window_size;
|
|
VIOsPAPR_RTCE *rtce_table;
|
|
int kvmtce_fd;
|
|
VIOsPAPR_CRQ crq;
|
|
};
|
|
|
|
#define DEFINE_SPAPR_PROPERTIES(type, field, default_reg, default_dma_window) \
|
|
DEFINE_PROP_UINT32("reg", type, field.reg, default_reg), \
|
|
DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \
|
|
default_dma_window)
|
|
|
|
struct VIOsPAPRBus {
|
|
BusState bus;
|
|
int (*init)(VIOsPAPRDevice *dev);
|
|
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
|
|
};
|
|
|
|
extern VIOsPAPRBus *spapr_vio_bus_init(void);
|
|
extern VIOsPAPRDevice *spapr_vio_find_by_reg(VIOsPAPRBus *bus, uint32_t reg);
|
|
extern int spapr_populate_vdevice(VIOsPAPRBus *bus, void *fdt);
|
|
extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus);
|
|
|
|
extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode);
|
|
|
|
int spapr_vio_check_tces(VIOsPAPRDevice *dev, target_ulong ioba,
|
|
target_ulong len,
|
|
enum VIOsPAPR_TCEAccess access);
|
|
|
|
int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr,
|
|
void *buf, uint32_t size);
|
|
int spapr_tce_dma_write(VIOsPAPRDevice *dev, uint64_t taddr,
|
|
const void *buf, uint32_t size);
|
|
int spapr_tce_dma_zero(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t size);
|
|
void stb_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t val);
|
|
void sth_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint16_t val);
|
|
void stw_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t val);
|
|
void stq_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint64_t val);
|
|
uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr);
|
|
|
|
int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq);
|
|
|
|
VIOsPAPRDevice *vty_lookup(sPAPREnvironment *spapr, target_ulong reg);
|
|
void vty_putchars(VIOsPAPRDevice *sdev, uint8_t *buf, int len);
|
|
void spapr_vty_create(VIOsPAPRBus *bus, uint32_t reg, CharDriverState *chardev);
|
|
void spapr_vlan_create(VIOsPAPRBus *bus, uint32_t reg, NICInfo *nd);
|
|
void spapr_vscsi_create(VIOsPAPRBus *bus, uint32_t reg);
|
|
|
|
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
|
|
|
|
int spapr_tce_set_bypass(uint32_t unit, uint32_t enable);
|
|
void spapr_vio_quiesce(void);
|
|
|
|
#endif /* _HW_SPAPR_VIO_H */
|