hw: move headers to include/

Many of these should be cleaned up with proper qdev-/QOM-ification.
Right now there are many catch-all headers in include/hw/ARCH depending
on cpu.h, and this makes it necessary to compile these files per-target.
However, fixing this does not belong in these patches.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2013-02-05 17:06:20 +01:00
parent bb585a784e
commit 0d09e41a51
511 changed files with 829 additions and 830 deletions

157
include/hw/acpi/acpi.h Normal file
View file

@ -0,0 +1,157 @@
#ifndef QEMU_HW_ACPI_H
#define QEMU_HW_ACPI_H
/*
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* 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/>.
*/
/* from linux include/acpi/actype.h */
/* Default ACPI register widths */
#define ACPI_GPE_REGISTER_WIDTH 8
#define ACPI_PM1_REGISTER_WIDTH 16
#define ACPI_PM2_REGISTER_WIDTH 8
#define ACPI_PM_TIMER_WIDTH 32
/* PM Timer ticks per second (HZ) */
#define PM_TIMER_FREQUENCY 3579545
/* ACPI fixed hardware registers */
/* from linux/drivers/acpi/acpica/aclocal.h */
/* Masks used to access the bit_registers */
/* PM1x_STS */
#define ACPI_BITMASK_TIMER_STATUS 0x0001
#define ACPI_BITMASK_BUS_MASTER_STATUS 0x0010
#define ACPI_BITMASK_GLOBAL_LOCK_STATUS 0x0020
#define ACPI_BITMASK_POWER_BUTTON_STATUS 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_STATUS 0x0200
#define ACPI_BITMASK_RT_CLOCK_STATUS 0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_STATUS 0x4000 /* ACPI 3.0 */
#define ACPI_BITMASK_WAKE_STATUS 0x8000
#define ACPI_BITMASK_ALL_FIXED_STATUS (\
ACPI_BITMASK_TIMER_STATUS | \
ACPI_BITMASK_BUS_MASTER_STATUS | \
ACPI_BITMASK_GLOBAL_LOCK_STATUS | \
ACPI_BITMASK_POWER_BUTTON_STATUS | \
ACPI_BITMASK_SLEEP_BUTTON_STATUS | \
ACPI_BITMASK_RT_CLOCK_STATUS | \
ACPI_BITMASK_WAKE_STATUS)
/* PM1x_EN */
#define ACPI_BITMASK_TIMER_ENABLE 0x0001
#define ACPI_BITMASK_GLOBAL_LOCK_ENABLE 0x0020
#define ACPI_BITMASK_POWER_BUTTON_ENABLE 0x0100
#define ACPI_BITMASK_SLEEP_BUTTON_ENABLE 0x0200
#define ACPI_BITMASK_RT_CLOCK_ENABLE 0x0400
#define ACPI_BITMASK_PCIEXP_WAKE_DISABLE 0x4000 /* ACPI 3.0 */
/* PM1x_CNT */
#define ACPI_BITMASK_SCI_ENABLE 0x0001
#define ACPI_BITMASK_BUS_MASTER_RLD 0x0002
#define ACPI_BITMASK_GLOBAL_LOCK_RELEASE 0x0004
#define ACPI_BITMASK_SLEEP_TYPE 0x1C00
#define ACPI_BITMASK_SLEEP_ENABLE 0x2000
/* PM2_CNT */
#define ACPI_BITMASK_ARB_DISABLE 0x0001
/* structs */
typedef struct ACPIPMTimer ACPIPMTimer;
typedef struct ACPIPM1EVT ACPIPM1EVT;
typedef struct ACPIPM1CNT ACPIPM1CNT;
typedef struct ACPIGPE ACPIGPE;
typedef struct ACPIREGS ACPIREGS;
typedef void (*acpi_update_sci_fn)(ACPIREGS *ar);
struct ACPIPMTimer {
QEMUTimer *timer;
MemoryRegion io;
int64_t overflow_time;
acpi_update_sci_fn update_sci;
};
struct ACPIPM1EVT {
MemoryRegion io;
uint16_t sts;
uint16_t en;
acpi_update_sci_fn update_sci;
};
struct ACPIPM1CNT {
MemoryRegion io;
uint16_t cnt;
uint8_t s4_val;
};
struct ACPIGPE {
uint8_t len;
uint8_t *sts;
uint8_t *en;
};
struct ACPIREGS {
ACPIPMTimer tmr;
ACPIGPE gpe;
struct {
ACPIPM1EVT evt;
ACPIPM1CNT cnt;
} pm1;
Notifier wakeup;
};
/* PM_TMR */
void acpi_pm_tmr_update(ACPIREGS *ar, bool enable);
void acpi_pm_tmr_calc_overflow_time(ACPIREGS *ar);
void acpi_pm_tmr_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
MemoryRegion *parent);
void acpi_pm_tmr_reset(ACPIREGS *ar);
#include "qemu/timer.h"
static inline int64_t acpi_pm_tmr_get_clock(void)
{
return muldiv64(qemu_get_clock_ns(vm_clock), PM_TIMER_FREQUENCY,
get_ticks_per_sec());
}
/* PM1a_EVT: piix and ich9 don't implement PM1b. */
uint16_t acpi_pm1_evt_get_sts(ACPIREGS *ar);
void acpi_pm1_evt_power_down(ACPIREGS *ar);
void acpi_pm1_evt_reset(ACPIREGS *ar);
void acpi_pm1_evt_init(ACPIREGS *ar, acpi_update_sci_fn update_sci,
MemoryRegion *parent);
/* PM1a_CNT: piix and ich9 don't implement PM1b CNT. */
void acpi_pm1_cnt_init(ACPIREGS *ar, MemoryRegion *parent, uint8_t s4_val);
void acpi_pm1_cnt_update(ACPIREGS *ar,
bool sci_enable, bool sci_disable);
void acpi_pm1_cnt_reset(ACPIREGS *ar);
/* GPE0 */
void acpi_gpe_init(ACPIREGS *ar, uint8_t len);
void acpi_gpe_reset(ACPIREGS *ar);
void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
#endif /* !QEMU_HW_ACPI_H */

52
include/hw/acpi/ich9.h Normal file
View file

@ -0,0 +1,52 @@
/*
* QEMU GMCH/ICH9 LPC PM Emulation
*
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* 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/>
*/
#ifndef HW_ACPI_ICH9_H
#define HW_ACPI_ICH9_H
#include "hw/acpi/acpi.h"
typedef struct ICH9LPCPMRegs {
/*
* In ich9 spec says that pm1_cnt register is 32bit width and
* that the upper 16bits are reserved and unused.
* PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t.
*/
ACPIREGS acpi_regs;
MemoryRegion io;
MemoryRegion io_gpe;
MemoryRegion io_smi;
uint32_t smi_en;
uint32_t smi_sts;
qemu_irq irq; /* SCI */
uint32_t pm_io_base;
Notifier powerdown_notifier;
} ICH9LPCPMRegs;
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
qemu_irq sci_irq, qemu_irq cmos_s3_resume);
void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base);
extern const VMStateDescription vmstate_ich9_pm;
#endif /* HW_ACPI_ICH9_H */

70
include/hw/arm.h Normal file
View file

@ -0,0 +1,70 @@
/*
* Misc ARM declarations
*
* Copyright (c) 2006 CodeSourcery.
* Written by Paul Brook
*
* This code is licensed under the LGPL.
*
*/
#ifndef ARM_MISC_H
#define ARM_MISC_H 1
#include "exec/memory.h"
#include "hw/irq.h"
/* The CPU is also modelled as an interrupt controller. */
#define ARM_PIC_CPU_IRQ 0
#define ARM_PIC_CPU_FIQ 1
qemu_irq *arm_pic_init_cpu(ARMCPU *cpu);
/* armv7m.c */
qemu_irq *armv7m_init(MemoryRegion *address_space_mem,
int flash_size, int sram_size,
const char *kernel_filename, const char *cpu_model);
/* arm_boot.c */
struct arm_boot_info {
uint64_t ram_size;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
const char *dtb_filename;
hwaddr loader_start;
/* multicore boards that use the default secondary core boot functions
* need to put the address of the secondary boot code, the boot reg,
* and the GIC address in the next 3 values, respectively. boards that
* have their own boot functions can use these values as they want.
*/
hwaddr smp_loader_start;
hwaddr smp_bootreg_addr;
hwaddr gic_cpu_if_addr;
int nb_cpus;
int board_id;
int (*atag_board)(const struct arm_boot_info *info, void *p);
/* multicore boards that use the default secondary core boot functions
* can ignore these two function calls. If the default functions won't
* work, then write_secondary_boot() should write a suitable blob of
* code mimicking the secondary CPU startup process used by the board's
* boot loader/boot ROM code, and secondary_cpu_reset_hook() should
* perform any necessary CPU reset handling and set the PC for the
* secondary CPUs to point at this boot blob.
*/
void (*write_secondary_boot)(ARMCPU *cpu,
const struct arm_boot_info *info);
void (*secondary_cpu_reset_hook)(ARMCPU *cpu,
const struct arm_boot_info *info);
/* Used internally by arm_boot.c */
int is_linux;
hwaddr initrd_start;
hwaddr initrd_size;
hwaddr entry;
};
void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
/* Multiplication factor to convert from system clock ticks to qemu timer
ticks. */
extern int system_clock_scale;
#endif /* !ARM_MISC_H */

70
include/hw/arm/devices.h Normal file
View file

@ -0,0 +1,70 @@
#ifndef QEMU_DEVICES_H
#define QEMU_DEVICES_H
#include "hw/irq.h"
/* ??? Not all users of this file can include cpu-common.h. */
struct MemoryRegion;
/* Devices that have nowhere better to go. */
/* smc91c111.c */
void smc91c111_init(NICInfo *, uint32_t, qemu_irq);
/* lan9118.c */
void lan9118_init(NICInfo *, uint32_t, qemu_irq);
/* tsc210x.c */
uWireSlave *tsc2102_init(qemu_irq pint);
uWireSlave *tsc2301_init(qemu_irq penirq, qemu_irq kbirq, qemu_irq dav);
I2SCodec *tsc210x_codec(uWireSlave *chip);
uint32_t tsc210x_txrx(void *opaque, uint32_t value, int len);
void tsc210x_set_transform(uWireSlave *chip,
MouseTransformInfo *info);
void tsc210x_key_event(uWireSlave *chip, int key, int down);
/* tsc2005.c */
void *tsc2005_init(qemu_irq pintdav);
uint32_t tsc2005_txrx(void *opaque, uint32_t value, int len);
void tsc2005_set_transform(void *opaque, MouseTransformInfo *info);
/* stellaris_input.c */
void stellaris_gamepad_init(int n, qemu_irq *irq, const int *keycode);
/* blizzard.c */
void *s1d13745_init(qemu_irq gpio_int);
void s1d13745_write(void *opaque, int dc, uint16_t value);
void s1d13745_write_block(void *opaque, int dc,
void *buf, size_t len, int pitch);
uint16_t s1d13745_read(void *opaque, int dc);
/* cbus.c */
typedef struct {
qemu_irq clk;
qemu_irq dat;
qemu_irq sel;
} CBus;
CBus *cbus_init(qemu_irq dat_out);
void cbus_attach(CBus *bus, void *slave_opaque);
void *retu_init(qemu_irq irq, int vilma);
void *tahvo_init(qemu_irq irq, int betty);
void retu_key_event(void *retu, int state);
/* tc6393xb.c */
typedef struct TC6393xbState TC6393xbState;
#define TC6393XB_RAM 0x110000 /* amount of ram for Video and USB */
TC6393xbState *tc6393xb_init(struct MemoryRegion *sysmem,
uint32_t base, qemu_irq irq);
void tc6393xb_gpio_out_set(TC6393xbState *s, int line,
qemu_irq handler);
qemu_irq *tc6393xb_gpio_in_get(TC6393xbState *s);
qemu_irq tc6393xb_l3v_get(TC6393xbState *s);
/* sm501.c */
void sm501_init(struct MemoryRegion *address_space_mem, uint32_t base,
uint32_t local_mem_bytes, qemu_irq irq,
CharDriverState *chr);
#endif

137
include/hw/arm/exynos4210.h Normal file
View file

@ -0,0 +1,137 @@
/*
* Samsung exynos4210 SoC emulation
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved.
* Maksim Kozlov <m.kozlov@samsung.com>
* Evgeny Voevodin <e.voevodin@samsung.com>
* Igor Mitsyanko <i.mitsyanko@samsung.com>
*
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef EXYNOS4210_H_
#define EXYNOS4210_H_
#include "qemu-common.h"
#include "exec/memory.h"
#define EXYNOS4210_NCPUS 2
#define EXYNOS4210_DRAM0_BASE_ADDR 0x40000000
#define EXYNOS4210_DRAM1_BASE_ADDR 0xa0000000
#define EXYNOS4210_DRAM_MAX_SIZE 0x60000000 /* 1.5 GB */
#define EXYNOS4210_IROM_BASE_ADDR 0x00000000
#define EXYNOS4210_IROM_SIZE 0x00010000 /* 64 KB */
#define EXYNOS4210_IROM_MIRROR_BASE_ADDR 0x02000000
#define EXYNOS4210_IROM_MIRROR_SIZE 0x00010000 /* 64 KB */
#define EXYNOS4210_IRAM_BASE_ADDR 0x02020000
#define EXYNOS4210_IRAM_SIZE 0x00020000 /* 128 KB */
/* Secondary CPU startup code is in IROM memory */
#define EXYNOS4210_SMP_BOOT_ADDR EXYNOS4210_IROM_BASE_ADDR
#define EXYNOS4210_SMP_BOOT_SIZE 0x1000
#define EXYNOS4210_BASE_BOOT_ADDR EXYNOS4210_DRAM0_BASE_ADDR
/* Secondary CPU polling address to get loader start from */
#define EXYNOS4210_SECOND_CPU_BOOTREG 0x10020814
#define EXYNOS4210_SMP_PRIVATE_BASE_ADDR 0x10500000
#define EXYNOS4210_L2X0_BASE_ADDR 0x10502000
/*
* exynos4210 IRQ subsystem stub definitions.
*/
#define EXYNOS4210_IRQ_GATE_NINPUTS 2 /* Internal and External GIC */
#define EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ 64
#define EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ 16
#define EXYNOS4210_MAX_INT_COMBINER_IN_IRQ \
(EXYNOS4210_MAX_INT_COMBINER_OUT_IRQ * 8)
#define EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ \
(EXYNOS4210_MAX_EXT_COMBINER_OUT_IRQ * 8)
#define EXYNOS4210_COMBINER_GET_IRQ_NUM(grp, bit) ((grp)*8 + (bit))
#define EXYNOS4210_COMBINER_GET_GRP_NUM(irq) ((irq) / 8)
#define EXYNOS4210_COMBINER_GET_BIT_NUM(irq) \
((irq) - 8 * EXYNOS4210_COMBINER_GET_GRP_NUM(irq))
/* IRQs number for external and internal GIC */
#define EXYNOS4210_EXT_GIC_NIRQ (160-32)
#define EXYNOS4210_INT_GIC_NIRQ 64
#define EXYNOS4210_I2C_NUMBER 9
typedef struct Exynos4210Irq {
qemu_irq int_combiner_irq[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
qemu_irq ext_combiner_irq[EXYNOS4210_MAX_EXT_COMBINER_IN_IRQ];
qemu_irq int_gic_irq[EXYNOS4210_INT_GIC_NIRQ];
qemu_irq ext_gic_irq[EXYNOS4210_EXT_GIC_NIRQ];
qemu_irq board_irqs[EXYNOS4210_MAX_INT_COMBINER_IN_IRQ];
} Exynos4210Irq;
typedef struct Exynos4210State {
ARMCPU *cpu[EXYNOS4210_NCPUS];
Exynos4210Irq irqs;
qemu_irq *irq_table;
MemoryRegion chipid_mem;
MemoryRegion iram_mem;
MemoryRegion irom_mem;
MemoryRegion irom_alias_mem;
MemoryRegion dram0_mem;
MemoryRegion dram1_mem;
MemoryRegion boot_secondary;
MemoryRegion bootreg_mem;
i2c_bus *i2c_if[EXYNOS4210_I2C_NUMBER];
} Exynos4210State;
void exynos4210_write_secondary(ARMCPU *cpu,
const struct arm_boot_info *info);
Exynos4210State *exynos4210_init(MemoryRegion *system_mem,
unsigned long ram_size);
/* Initialize exynos4210 IRQ subsystem stub */
qemu_irq *exynos4210_init_irq(Exynos4210Irq *env);
/* Initialize board IRQs.
* These IRQs contain splitted Int/External Combiner and External Gic IRQs */
void exynos4210_init_board_irqs(Exynos4210Irq *s);
/* Get IRQ number from exynos4210 IRQ subsystem stub.
* To identify IRQ source use internal combiner group and bit number
* grp - group number
* bit - bit number inside group */
uint32_t exynos4210_get_irq(uint32_t grp, uint32_t bit);
/*
* Get Combiner input GPIO into irqs structure
*/
void exynos4210_combiner_get_gpioin(Exynos4210Irq *irqs, DeviceState *dev,
int ext);
/*
* exynos4210 UART
*/
DeviceState *exynos4210_uart_create(hwaddr addr,
int fifo_size,
int channel,
CharDriverState *chr,
qemu_irq irq);
#endif /* EXYNOS4210_H_ */

34
include/hw/arm/imx.h Normal file
View file

@ -0,0 +1,34 @@
/*
* i.MX31 emulation
*
* Copyright (C) 2012 Peter Chubb
* NICTA
*
* This code is released under the GPL, version 2.0 or later
* See the file `../COPYING' for details.
*/
#ifndef IMX_H
#define IMX_H
void imx_serial_create(int uart, const hwaddr addr, qemu_irq irq);
typedef enum {
NOCLK,
MCU,
HSP,
IPG,
CLK_32k
} IMXClk;
uint32_t imx_clock_frequency(DeviceState *s, IMXClk clock);
void imx_timerp_create(const hwaddr addr,
qemu_irq irq,
DeviceState *ccm);
void imx_timerg_create(const hwaddr addr,
qemu_irq irq,
DeviceState *ccm);
#endif /* IMX_H */

1015
include/hw/arm/omap.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
#ifndef PRIMECELL_H
#define PRIMECELL_H
/* Declarations for ARM PrimeCell based periperals. */
/* Also includes some devices that are currently only used by the
ARM boards. */
/* arm_sysctl GPIO lines */
#define ARM_SYSCTL_GPIO_MMC_WPROT 0
#define ARM_SYSCTL_GPIO_MMC_CARDIN 1
#endif

191
include/hw/arm/pxa.h Normal file
View file

@ -0,0 +1,191 @@
/*
* Intel XScale PXA255/270 processor support.
*
* Copyright (c) 2006 Openedhand Ltd.
* Written by Andrzej Zaborowski <balrog@zabor.org>
*
* This code is licensed under the GNU GPL v2.
*/
#ifndef PXA_H
# define PXA_H "pxa.h"
#include "exec/memory.h"
/* Interrupt numbers */
# define PXA2XX_PIC_SSP3 0
# define PXA2XX_PIC_USBH2 2
# define PXA2XX_PIC_USBH1 3
# define PXA2XX_PIC_KEYPAD 4
# define PXA2XX_PIC_PWRI2C 6
# define PXA25X_PIC_HWUART 7
# define PXA27X_PIC_OST_4_11 7
# define PXA2XX_PIC_GPIO_0 8
# define PXA2XX_PIC_GPIO_1 9
# define PXA2XX_PIC_GPIO_X 10
# define PXA2XX_PIC_I2S 13
# define PXA26X_PIC_ASSP 15
# define PXA25X_PIC_NSSP 16
# define PXA27X_PIC_SSP2 16
# define PXA2XX_PIC_LCD 17
# define PXA2XX_PIC_I2C 18
# define PXA2XX_PIC_ICP 19
# define PXA2XX_PIC_STUART 20
# define PXA2XX_PIC_BTUART 21
# define PXA2XX_PIC_FFUART 22
# define PXA2XX_PIC_MMC 23
# define PXA2XX_PIC_SSP 24
# define PXA2XX_PIC_DMA 25
# define PXA2XX_PIC_OST_0 26
# define PXA2XX_PIC_RTC1HZ 30
# define PXA2XX_PIC_RTCALARM 31
/* DMA requests */
# define PXA2XX_RX_RQ_I2S 2
# define PXA2XX_TX_RQ_I2S 3
# define PXA2XX_RX_RQ_BTUART 4
# define PXA2XX_TX_RQ_BTUART 5
# define PXA2XX_RX_RQ_FFUART 6
# define PXA2XX_TX_RQ_FFUART 7
# define PXA2XX_RX_RQ_SSP1 13
# define PXA2XX_TX_RQ_SSP1 14
# define PXA2XX_RX_RQ_SSP2 15
# define PXA2XX_TX_RQ_SSP2 16
# define PXA2XX_RX_RQ_ICP 17
# define PXA2XX_TX_RQ_ICP 18
# define PXA2XX_RX_RQ_STUART 19
# define PXA2XX_TX_RQ_STUART 20
# define PXA2XX_RX_RQ_MMCI 21
# define PXA2XX_TX_RQ_MMCI 22
# define PXA2XX_USB_RQ(x) ((x) + 24)
# define PXA2XX_RX_RQ_SSP3 66
# define PXA2XX_TX_RQ_SSP3 67
# define PXA2XX_SDRAM_BASE 0xa0000000
# define PXA2XX_INTERNAL_BASE 0x5c000000
# define PXA2XX_INTERNAL_SIZE 0x40000
/* pxa2xx_pic.c */
DeviceState *pxa2xx_pic_init(hwaddr base, ARMCPU *cpu);
/* pxa2xx_gpio.c */
DeviceState *pxa2xx_gpio_init(hwaddr base,
ARMCPU *cpu, DeviceState *pic, int lines);
void pxa2xx_gpio_read_notifier(DeviceState *dev, qemu_irq handler);
/* pxa2xx_dma.c */
DeviceState *pxa255_dma_init(hwaddr base, qemu_irq irq);
DeviceState *pxa27x_dma_init(hwaddr base, qemu_irq irq);
/* pxa2xx_lcd.c */
typedef struct PXA2xxLCDState PXA2xxLCDState;
PXA2xxLCDState *pxa2xx_lcdc_init(MemoryRegion *sysmem,
hwaddr base, qemu_irq irq);
void pxa2xx_lcd_vsync_notifier(PXA2xxLCDState *s, qemu_irq handler);
void pxa2xx_lcdc_oritentation(void *opaque, int angle);
/* pxa2xx_mmci.c */
typedef struct PXA2xxMMCIState PXA2xxMMCIState;
PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,
hwaddr base,
BlockDriverState *bd, qemu_irq irq,
qemu_irq rx_dma, qemu_irq tx_dma);
void pxa2xx_mmci_handlers(PXA2xxMMCIState *s, qemu_irq readonly,
qemu_irq coverswitch);
/* pxa2xx_pcmcia.c */
typedef struct PXA2xxPCMCIAState PXA2xxPCMCIAState;
PXA2xxPCMCIAState *pxa2xx_pcmcia_init(MemoryRegion *sysmem,
hwaddr base);
int pxa2xx_pcmcia_attach(void *opaque, PCMCIACardState *card);
int pxa2xx_pcmcia_dettach(void *opaque);
void pxa2xx_pcmcia_set_irq_cb(void *opaque, qemu_irq irq, qemu_irq cd_irq);
/* pxa2xx_keypad.c */
struct keymap {
int column;
int row;
};
typedef struct PXA2xxKeyPadState PXA2xxKeyPadState;
PXA2xxKeyPadState *pxa27x_keypad_init(MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq);
void pxa27x_register_keypad(PXA2xxKeyPadState *kp, struct keymap *map,
int size);
/* pxa2xx.c */
typedef struct PXA2xxI2CState PXA2xxI2CState;
PXA2xxI2CState *pxa2xx_i2c_init(hwaddr base,
qemu_irq irq, uint32_t page_size);
i2c_bus *pxa2xx_i2c_bus(PXA2xxI2CState *s);
typedef struct PXA2xxI2SState PXA2xxI2SState;
typedef struct PXA2xxFIrState PXA2xxFIrState;
typedef struct {
ARMCPU *cpu;
DeviceState *pic;
qemu_irq reset;
MemoryRegion sdram;
MemoryRegion internal;
MemoryRegion cm_iomem;
MemoryRegion mm_iomem;
MemoryRegion pm_iomem;
DeviceState *dma;
DeviceState *gpio;
PXA2xxLCDState *lcd;
SSIBus **ssp;
PXA2xxI2CState *i2c[2];
PXA2xxMMCIState *mmc;
PXA2xxPCMCIAState *pcmcia[2];
PXA2xxI2SState *i2s;
PXA2xxFIrState *fir;
PXA2xxKeyPadState *kp;
/* Power management */
hwaddr pm_base;
uint32_t pm_regs[0x40];
/* Clock management */
hwaddr cm_base;
uint32_t cm_regs[4];
uint32_t clkcfg;
/* Memory management */
hwaddr mm_base;
uint32_t mm_regs[0x1a];
/* Performance monitoring */
uint32_t pmnc;
} PXA2xxState;
struct PXA2xxI2SState {
MemoryRegion iomem;
qemu_irq irq;
qemu_irq rx_dma;
qemu_irq tx_dma;
void (*data_req)(void *, int, int);
uint32_t control[2];
uint32_t status;
uint32_t mask;
uint32_t clk;
int enable;
int rx_len;
int tx_len;
void (*codec_out)(void *, uint32_t);
uint32_t (*codec_in)(void *);
void *opaque;
int fifo_len;
uint32_t fifo[16];
};
# define PA_FMT "0x%08lx"
# define REG_FMT "0x" TARGET_FMT_plx
PXA2xxState *pxa270_init(MemoryRegion *address_space, unsigned int sdram_size,
const char *revision);
PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size);
#endif /* PXA_H */

17
include/hw/arm/sharpsl.h Normal file
View file

@ -0,0 +1,17 @@
/*
* Common declarations for the Zaurii.
*
* This file is licensed under the GNU GPL.
*/
#ifndef QEMU_SHARPSL_H
#define QEMU_SHARPSL_H
#define zaurus_printf(format, ...) \
fprintf(stderr, "%s: " format, __FUNCTION__, ##__VA_ARGS__)
/* zaurus.c */
#define SL_PXA_PARAM_BASE 0xa0000a00
void sl_bootparam_write(hwaddr ptr);
#endif

116
include/hw/arm/soc_dma.h Normal file
View file

@ -0,0 +1,116 @@
/*
* On-chip DMA controller framework.
*
* Copyright (C) 2008 Nokia Corporation
* Written by Andrzej Zaborowski <andrew@openedhand.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 or
* (at your option) version 3 of the License.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef HW_SOC_DMA_H
#define HW_SOC_DMA_H 1
#include "exec/memory.h"
#include "hw/irq.h"
struct soc_dma_s;
struct soc_dma_ch_s;
typedef void (*soc_dma_io_t)(void *opaque, uint8_t *buf, int len);
typedef void (*soc_dma_transfer_t)(struct soc_dma_ch_s *ch);
enum soc_dma_port_type {
soc_dma_port_mem,
soc_dma_port_fifo,
soc_dma_port_other,
};
enum soc_dma_access_type {
soc_dma_access_const,
soc_dma_access_linear,
soc_dma_access_other,
};
struct soc_dma_ch_s {
/* Private */
struct soc_dma_s *dma;
int num;
QEMUTimer *timer;
/* Set by soc_dma.c */
int enable;
int update;
/* This should be set by dma->setup_fn(). */
int bytes;
/* Initialised by the DMA module, call soc_dma_ch_update after writing. */
enum soc_dma_access_type type[2];
hwaddr vaddr[2]; /* Updated by .transfer_fn(). */
/* Private */
void *paddr[2];
soc_dma_io_t io_fn[2];
void *io_opaque[2];
int running;
soc_dma_transfer_t transfer_fn;
/* Set and used by the DMA module. */
void *opaque;
};
struct soc_dma_s {
/* Following fields are set by the SoC DMA module and can be used
* by anybody. */
uint64_t drqbmp; /* Is zeroed by soc_dma_reset() */
qemu_irq *drq;
void *opaque;
int64_t freq;
soc_dma_transfer_t transfer_fn;
soc_dma_transfer_t setup_fn;
/* Set by soc_dma_init() for use by the DMA module. */
struct soc_dma_ch_s *ch;
};
/* Call to activate or stop a DMA channel. */
void soc_dma_set_request(struct soc_dma_ch_s *ch, int level);
/* Call after every write to one of the following fields and before
* calling soc_dma_set_request(ch, 1):
* ch->type[0...1],
* ch->vaddr[0...1],
* ch->paddr[0...1],
* or after a soc_dma_port_add_fifo() or soc_dma_port_add_mem(). */
void soc_dma_ch_update(struct soc_dma_ch_s *ch);
/* The SoC should call this when the DMA module is being reset. */
void soc_dma_reset(struct soc_dma_s *s);
struct soc_dma_s *soc_dma_init(int n);
void soc_dma_port_add_fifo(struct soc_dma_s *dma, hwaddr virt_base,
soc_dma_io_t fn, void *opaque, int out);
void soc_dma_port_add_mem(struct soc_dma_s *dma, uint8_t *phys_base,
hwaddr virt_base, size_t size);
static inline void soc_dma_port_add_fifo_in(struct soc_dma_s *dma,
hwaddr virt_base, soc_dma_io_t fn, void *opaque)
{
return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 0);
}
static inline void soc_dma_port_add_fifo_out(struct soc_dma_s *dma,
hwaddr virt_base, soc_dma_io_t fn, void *opaque)
{
return soc_dma_port_add_fifo(dma, virt_base, fn, opaque, 1);
}
#endif

25
include/hw/audio/audio.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef HW_AUDIODEV_H
#define HW_AUDIODEV_H 1
/* es1370.c */
int es1370_init(PCIBus *bus);
/* sb16.c */
int SB16_init(ISABus *bus);
/* adlib.c */
int Adlib_init(ISABus *bus);
/* gus.c */
int GUS_init(ISABus *bus);
/* ac97.c */
int ac97_init(PCIBus *bus);
/* cs4231a.c */
int cs4231a_init(ISABus *bus);
/* intel-hda.c + hda-audio.c */
int intel_hda_and_codec_init(PCIBus *bus);
#endif

45
include/hw/audio/pcspk.h Normal file
View file

@ -0,0 +1,45 @@
/*
* QEMU PC speaker emulation
*
* Copyright (c) 2006 Joachim Henke
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_PCSPK_H
#define HW_PCSPK_H
#include "hw/hw.h"
#include "hw/isa/isa.h"
static inline ISADevice *pcspk_init(ISABus *bus, ISADevice *pit)
{
ISADevice *dev;
dev = isa_create(bus, "isa-pcspk");
qdev_prop_set_uint32(&dev->qdev, "iobase", 0x61);
qdev_prop_set_ptr(&dev->qdev, "pit", pit);
qdev_init_nofail(&dev->qdev);
return dev;
}
int pcspk_audio_init(ISABus *bus);
#endif /* !HW_PCSPK_H */

79
include/hw/block/block.h Normal file
View file

@ -0,0 +1,79 @@
/*
* Common code for block device models
*
* Copyright (C) 2012 Red Hat, Inc.
* Copyright (c) 2003-2008 Fabrice Bellard
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#ifndef HW_BLOCK_COMMON_H
#define HW_BLOCK_COMMON_H
#include "qemu-common.h"
/* Configuration */
typedef struct BlockConf {
BlockDriverState *bs;
uint16_t physical_block_size;
uint16_t logical_block_size;
uint16_t min_io_size;
uint32_t opt_io_size;
int32_t bootindex;
uint32_t discard_granularity;
/* geometry, not all devices use this */
uint32_t cyls, heads, secs;
} BlockConf;
static inline unsigned int get_physical_block_exp(BlockConf *conf)
{
unsigned int exp = 0, size;
for (size = conf->physical_block_size;
size > conf->logical_block_size;
size >>= 1) {
exp++;
}
return exp;
}
#define DEFINE_BLOCK_PROPERTIES(_state, _conf) \
DEFINE_PROP_DRIVE("drive", _state, _conf.bs), \
DEFINE_PROP_BLOCKSIZE("logical_block_size", _state, \
_conf.logical_block_size, 512), \
DEFINE_PROP_BLOCKSIZE("physical_block_size", _state, \
_conf.physical_block_size, 512), \
DEFINE_PROP_UINT16("min_io_size", _state, _conf.min_io_size, 0), \
DEFINE_PROP_UINT32("opt_io_size", _state, _conf.opt_io_size, 0), \
DEFINE_PROP_INT32("bootindex", _state, _conf.bootindex, -1), \
DEFINE_PROP_UINT32("discard_granularity", _state, \
_conf.discard_granularity, -1)
#define DEFINE_BLOCK_CHS_PROPERTIES(_state, _conf) \
DEFINE_PROP_UINT32("cyls", _state, _conf.cyls, 0), \
DEFINE_PROP_UINT32("heads", _state, _conf.heads, 0), \
DEFINE_PROP_UINT32("secs", _state, _conf.secs, 0)
/* Configuration helpers */
void blkconf_serial(BlockConf *conf, char **serial);
int blkconf_geometry(BlockConf *conf, int *trans,
unsigned cyls_max, unsigned heads_max, unsigned secs_max);
/* Hard disk geometry */
#define BIOS_ATA_TRANSLATION_AUTO 0
#define BIOS_ATA_TRANSLATION_NONE 1
#define BIOS_ATA_TRANSLATION_LBA 2
#define BIOS_ATA_TRANSLATION_LARGE 3
#define BIOS_ATA_TRANSLATION_RECHS 4
void hd_geometry_guess(BlockDriverState *bs,
uint32_t *pcyls, uint32_t *pheads, uint32_t *psecs,
int *ptrans);
int hd_bios_chs_auto_trans(uint32_t cyls, uint32_t heads, uint32_t secs);
#endif

24
include/hw/block/fdc.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef HW_FDC_H
#define HW_FDC_H
#include "qemu-common.h"
/* fdc.c */
#define MAX_FD 2
typedef enum FDriveType {
FDRIVE_DRV_144 = 0x00, /* 1.44 MB 3"5 drive */
FDRIVE_DRV_288 = 0x01, /* 2.88 MB 3"5 drive */
FDRIVE_DRV_120 = 0x02, /* 1.2 MB 5"25 drive */
FDRIVE_DRV_NONE = 0x03, /* No drive connected */
} FDriveType;
ISADevice *fdctrl_init_isa(ISABus *bus, DriveInfo **fds);
void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
hwaddr mmio_base, DriveInfo **fds);
void sun4m_fdctrl_init(qemu_irq irq, hwaddr io_base,
DriveInfo **fds, qemu_irq *fdc_tc);
FDriveType isa_fdc_get_drive_type(ISADevice *fdc, int i);
#endif

64
include/hw/block/flash.h Normal file
View file

@ -0,0 +1,64 @@
#ifndef HW_FLASH_H
#define HW_FLASH_H 1
/* NOR flash devices */
#include "exec/memory.h"
typedef struct pflash_t pflash_t;
/* pflash_cfi01.c */
pflash_t *pflash_cfi01_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockDriverState *bs,
uint32_t sector_len, int nb_blocs, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3, int be);
/* pflash_cfi02.c */
pflash_t *pflash_cfi02_register(hwaddr base,
DeviceState *qdev, const char *name,
hwaddr size,
BlockDriverState *bs, uint32_t sector_len,
int nb_blocs, int nb_mappings, int width,
uint16_t id0, uint16_t id1,
uint16_t id2, uint16_t id3,
uint16_t unlock_addr0, uint16_t unlock_addr1,
int be);
MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl);
/* nand.c */
DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id);
void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale,
uint8_t ce, uint8_t wp, uint8_t gnd);
void nand_getpins(DeviceState *dev, int *rb);
void nand_setio(DeviceState *dev, uint32_t value);
uint32_t nand_getio(DeviceState *dev);
uint32_t nand_getbuswidth(DeviceState *dev);
#define NAND_MFR_TOSHIBA 0x98
#define NAND_MFR_SAMSUNG 0xec
#define NAND_MFR_FUJITSU 0x04
#define NAND_MFR_NATIONAL 0x8f
#define NAND_MFR_RENESAS 0x07
#define NAND_MFR_STMICRO 0x20
#define NAND_MFR_HYNIX 0xad
#define NAND_MFR_MICRON 0x2c
/* onenand.c */
void *onenand_raw_otp(DeviceState *onenand_device);
/* ecc.c */
typedef struct {
uint8_t cp; /* Column parity */
uint16_t lp[2]; /* Line parity */
uint16_t count;
} ECCState;
uint8_t ecc_digest(ECCState *s, uint8_t sample);
void ecc_reset(ECCState *s);
extern VMStateDescription vmstate_ecc_state;
#endif

53
include/hw/boards.h Normal file
View file

@ -0,0 +1,53 @@
/* Declarations for use by board files for creating devices. */
#ifndef HW_BOARDS_H
#define HW_BOARDS_H
#include "sysemu/blockdev.h"
#include "hw/qdev.h"
#define DEFAULT_MACHINE_OPTIONS \
.boot_order = "cad"
typedef struct QEMUMachineInitArgs {
ram_addr_t ram_size;
const char *boot_device;
const char *kernel_filename;
const char *kernel_cmdline;
const char *initrd_filename;
const char *cpu_model;
} QEMUMachineInitArgs;
typedef void QEMUMachineInitFunc(QEMUMachineInitArgs *args);
typedef void QEMUMachineResetFunc(void);
typedef struct QEMUMachine {
const char *name;
const char *alias;
const char *desc;
QEMUMachineInitFunc *init;
QEMUMachineResetFunc *reset;
BlockInterfaceType block_default_type;
int max_cpus;
unsigned int no_serial:1,
no_parallel:1,
use_virtcon:1,
use_sclp:1,
no_floppy:1,
no_cdrom:1,
no_sdcard:1;
int is_default;
const char *default_machine_opts;
const char *boot_order;
GlobalProperty *compat_props;
struct QEMUMachine *next;
const char *hw_version;
} QEMUMachine;
int qemu_register_machine(QEMUMachine *m);
QEMUMachine *find_default_machine(void);
extern QEMUMachine *current_machine;
#endif

2190
include/hw/bt.h Normal file

File diff suppressed because it is too large Load diff

13
include/hw/char/escc.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef HW_ESCC_H
#define HW_ESCC_H 1
/* escc.c */
#define ESCC_SIZE 4
MemoryRegion *escc_init(hwaddr base, qemu_irq irqA, qemu_irq irqB,
CharDriverState *chrA, CharDriverState *chrB,
int clock, int it_shift);
void slavio_serial_ms_kbd_init(hwaddr base, qemu_irq irq,
int disabled, int clock, int it_shift);
#endif

101
include/hw/char/serial.h Normal file
View file

@ -0,0 +1,101 @@
/*
* QEMU 16550A UART emulation
*
* Copyright (c) 2003-2004 Fabrice Bellard
* Copyright (c) 2008 Citrix Systems, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_SERIAL_H
#define HW_SERIAL_H 1
#include "hw/hw.h"
#include "sysemu/sysemu.h"
#include "exec/memory.h"
#define UART_FIFO_LENGTH 16 /* 16550A Fifo Length */
typedef struct SerialFIFO {
uint8_t data[UART_FIFO_LENGTH];
uint8_t count;
uint8_t itl; /* Interrupt Trigger Level */
uint8_t tail;
uint8_t head;
} SerialFIFO;
struct SerialState {
uint16_t divider;
uint8_t rbr; /* receive register */
uint8_t thr; /* transmit holding register */
uint8_t tsr; /* transmit shift register */
uint8_t ier;
uint8_t iir; /* read only */
uint8_t lcr;
uint8_t mcr;
uint8_t lsr; /* read only */
uint8_t msr; /* read only */
uint8_t scr;
uint8_t fcr;
uint8_t fcr_vmstate; /* we can't write directly this value
it has side effects */
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
int it_shift;
int baudbase;
int tsr_retry;
uint32_t wakeup;
/* Time when the last byte was successfully sent out of the tsr */
uint64_t last_xmit_ts;
SerialFIFO recv_fifo;
SerialFIFO xmit_fifo;
struct QEMUTimer *fifo_timeout_timer;
int timeout_ipending; /* timeout interrupt pending state */
uint64_t char_transmit_time; /* time to transmit a char in ticks */
int poll_msl;
struct QEMUTimer *modem_status_poll;
MemoryRegion io;
};
extern const VMStateDescription vmstate_serial;
extern const MemoryRegionOps serial_io_ops;
void serial_init_core(SerialState *s);
void serial_exit_core(SerialState *s);
void serial_set_frequency(SerialState *s, uint32_t frequency);
/* legacy pre qom */
SerialState *serial_init(int base, qemu_irq irq, int baudbase,
CharDriverState *chr, MemoryRegion *system_io);
SerialState *serial_mm_init(MemoryRegion *address_space,
hwaddr base, int it_shift,
qemu_irq irq, int baudbase,
CharDriverState *chr, enum device_endian end);
/* serial-isa.c */
bool serial_isa_init(ISABus *bus, int index, CharDriverState *chr);
#endif

51
include/hw/cris/etraxfs.h Normal file
View file

@ -0,0 +1,51 @@
/*
* QEMU ETRAX System Emulator
*
* Copyright (c) 2008 Edgar E. Iglesias, Axis Communications AB.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_EXTRAXFS_H
#define HW_EXTRAXFS_H 1
#include "net/net.h"
#include "hw/cris/etraxfs_dma.h"
qemu_irq *cris_pic_init_cpu(CPUCRISState *env);
/* Instantiate an ETRAXFS Ethernet MAC. */
static inline DeviceState *
etraxfs_eth_init(NICInfo *nd, hwaddr base, int phyaddr,
void *dma_out, void *dma_in)
{
DeviceState *dev;
qemu_check_nic_model(nd, "fseth");
dev = qdev_create(NULL, "etraxfs-eth");
qdev_set_nic_properties(dev, nd);
qdev_prop_set_uint32(dev, "phyaddr", phyaddr);
qdev_prop_set_ptr(dev, "dma_out", dma_out);
qdev_prop_set_ptr(dev, "dma_in", dma_in);
qdev_init_nofail(dev);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
return dev;
}
#endif

View file

@ -0,0 +1,34 @@
#ifndef HW_ETRAXFS_DMA_H
#define HW_ETRAXFS_DMA_H 1
struct dma_context_metadata {
/* data descriptor md */
uint16_t metadata;
};
struct etraxfs_dma_client
{
/* DMA controller. */
int channel;
void *ctrl;
/* client. */
struct {
int (*push)(void *opaque, unsigned char *buf,
int len, bool eop);
void (*pull)(void *opaque);
void (*metadata_push)(void *opaque,
const struct dma_context_metadata *md);
void *opaque;
} client;
};
void *etraxfs_dmac_init(hwaddr base, int nr_channels);
void etraxfs_dmac_connect(void *opaque, int channel, qemu_irq *line,
int input);
void etraxfs_dmac_connect_client(void *opaque, int c,
struct etraxfs_dma_client *cl);
int etraxfs_dmac_input(struct etraxfs_dma_client *client,
void *buf, int len, int eop);
#endif

309
include/hw/elf_ops.h Normal file
View file

@ -0,0 +1,309 @@
static void glue(bswap_ehdr, SZ)(struct elfhdr *ehdr)
{
bswap16s(&ehdr->e_type); /* Object file type */
bswap16s(&ehdr->e_machine); /* Architecture */
bswap32s(&ehdr->e_version); /* Object file version */
bswapSZs(&ehdr->e_entry); /* Entry point virtual address */
bswapSZs(&ehdr->e_phoff); /* Program header table file offset */
bswapSZs(&ehdr->e_shoff); /* Section header table file offset */
bswap32s(&ehdr->e_flags); /* Processor-specific flags */
bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */
bswap16s(&ehdr->e_phentsize); /* Program header table entry size */
bswap16s(&ehdr->e_phnum); /* Program header table entry count */
bswap16s(&ehdr->e_shentsize); /* Section header table entry size */
bswap16s(&ehdr->e_shnum); /* Section header table entry count */
bswap16s(&ehdr->e_shstrndx); /* Section header string table index */
}
static void glue(bswap_phdr, SZ)(struct elf_phdr *phdr)
{
bswap32s(&phdr->p_type); /* Segment type */
bswapSZs(&phdr->p_offset); /* Segment file offset */
bswapSZs(&phdr->p_vaddr); /* Segment virtual address */
bswapSZs(&phdr->p_paddr); /* Segment physical address */
bswapSZs(&phdr->p_filesz); /* Segment size in file */
bswapSZs(&phdr->p_memsz); /* Segment size in memory */
bswap32s(&phdr->p_flags); /* Segment flags */
bswapSZs(&phdr->p_align); /* Segment alignment */
}
static void glue(bswap_shdr, SZ)(struct elf_shdr *shdr)
{
bswap32s(&shdr->sh_name);
bswap32s(&shdr->sh_type);
bswapSZs(&shdr->sh_flags);
bswapSZs(&shdr->sh_addr);
bswapSZs(&shdr->sh_offset);
bswapSZs(&shdr->sh_size);
bswap32s(&shdr->sh_link);
bswap32s(&shdr->sh_info);
bswapSZs(&shdr->sh_addralign);
bswapSZs(&shdr->sh_entsize);
}
static void glue(bswap_sym, SZ)(struct elf_sym *sym)
{
bswap32s(&sym->st_name);
bswapSZs(&sym->st_value);
bswapSZs(&sym->st_size);
bswap16s(&sym->st_shndx);
}
static struct elf_shdr *glue(find_section, SZ)(struct elf_shdr *shdr_table,
int n, int type)
{
int i;
for(i=0;i<n;i++) {
if (shdr_table[i].sh_type == type)
return shdr_table + i;
}
return NULL;
}
static int glue(symfind, SZ)(const void *s0, const void *s1)
{
hwaddr addr = *(hwaddr *)s0;
struct elf_sym *sym = (struct elf_sym *)s1;
int result = 0;
if (addr < sym->st_value) {
result = -1;
} else if (addr >= sym->st_value + sym->st_size) {
result = 1;
}
return result;
}
static const char *glue(lookup_symbol, SZ)(struct syminfo *s,
hwaddr orig_addr)
{
struct elf_sym *syms = glue(s->disas_symtab.elf, SZ);
struct elf_sym *sym;
sym = bsearch(&orig_addr, syms, s->disas_num_syms, sizeof(*syms),
glue(symfind, SZ));
if (sym != NULL) {
return s->disas_strtab + sym->st_name;
}
return "";
}
static int glue(symcmp, SZ)(const void *s0, const void *s1)
{
struct elf_sym *sym0 = (struct elf_sym *)s0;
struct elf_sym *sym1 = (struct elf_sym *)s1;
return (sym0->st_value < sym1->st_value)
? -1
: ((sym0->st_value > sym1->st_value) ? 1 : 0);
}
static int glue(load_symbols, SZ)(struct elfhdr *ehdr, int fd, int must_swab,
int clear_lsb)
{
struct elf_shdr *symtab, *strtab, *shdr_table = NULL;
struct elf_sym *syms = NULL;
struct syminfo *s;
int nsyms, i;
char *str = NULL;
shdr_table = load_at(fd, ehdr->e_shoff,
sizeof(struct elf_shdr) * ehdr->e_shnum);
if (!shdr_table)
return -1;
if (must_swab) {
for (i = 0; i < ehdr->e_shnum; i++) {
glue(bswap_shdr, SZ)(shdr_table + i);
}
}
symtab = glue(find_section, SZ)(shdr_table, ehdr->e_shnum, SHT_SYMTAB);
if (!symtab)
goto fail;
syms = load_at(fd, symtab->sh_offset, symtab->sh_size);
if (!syms)
goto fail;
nsyms = symtab->sh_size / sizeof(struct elf_sym);
i = 0;
while (i < nsyms) {
if (must_swab)
glue(bswap_sym, SZ)(&syms[i]);
/* We are only interested in function symbols.
Throw everything else away. */
if (syms[i].st_shndx == SHN_UNDEF ||
syms[i].st_shndx >= SHN_LORESERVE ||
ELF_ST_TYPE(syms[i].st_info) != STT_FUNC) {
nsyms--;
if (i < nsyms) {
syms[i] = syms[nsyms];
}
continue;
}
if (clear_lsb) {
/* The bottom address bit marks a Thumb or MIPS16 symbol. */
syms[i].st_value &= ~(glue(glue(Elf, SZ), _Addr))1;
}
i++;
}
if (nsyms) {
syms = g_realloc(syms, nsyms * sizeof(*syms));
qsort(syms, nsyms, sizeof(*syms), glue(symcmp, SZ));
for (i = 0; i < nsyms - 1; i++) {
if (syms[i].st_size == 0) {
syms[i].st_size = syms[i + 1].st_value - syms[i].st_value;
}
}
} else {
g_free(syms);
syms = NULL;
}
/* String table */
if (symtab->sh_link >= ehdr->e_shnum)
goto fail;
strtab = &shdr_table[symtab->sh_link];
str = load_at(fd, strtab->sh_offset, strtab->sh_size);
if (!str)
goto fail;
/* Commit */
s = g_malloc0(sizeof(*s));
s->lookup_symbol = glue(lookup_symbol, SZ);
glue(s->disas_symtab.elf, SZ) = syms;
s->disas_num_syms = nsyms;
s->disas_strtab = str;
s->next = syminfos;
syminfos = s;
g_free(shdr_table);
return 0;
fail:
g_free(syms);
g_free(str);
g_free(shdr_table);
return -1;
}
static int glue(load_elf, SZ)(const char *name, int fd,
uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque,
int must_swab, uint64_t *pentry,
uint64_t *lowaddr, uint64_t *highaddr,
int elf_machine, int clear_lsb)
{
struct elfhdr ehdr;
struct elf_phdr *phdr = NULL, *ph;
int size, i, total_size;
elf_word mem_size, file_size;
uint64_t addr, low = (uint64_t)-1, high = 0;
uint8_t *data = NULL;
char label[128];
if (read(fd, &ehdr, sizeof(ehdr)) != sizeof(ehdr))
goto fail;
if (must_swab) {
glue(bswap_ehdr, SZ)(&ehdr);
}
switch (elf_machine) {
case EM_PPC64:
if (EM_PPC64 != ehdr.e_machine)
if (EM_PPC != ehdr.e_machine)
goto fail;
break;
case EM_X86_64:
if (EM_X86_64 != ehdr.e_machine)
if (EM_386 != ehdr.e_machine)
goto fail;
break;
case EM_MICROBLAZE:
if (EM_MICROBLAZE != ehdr.e_machine)
if (EM_MICROBLAZE_OLD != ehdr.e_machine)
goto fail;
break;
default:
if (elf_machine != ehdr.e_machine)
goto fail;
}
if (pentry)
*pentry = (uint64_t)(elf_sword)ehdr.e_entry;
glue(load_symbols, SZ)(&ehdr, fd, must_swab, clear_lsb);
size = ehdr.e_phnum * sizeof(phdr[0]);
lseek(fd, ehdr.e_phoff, SEEK_SET);
phdr = g_malloc0(size);
if (!phdr)
goto fail;
if (read(fd, phdr, size) != size)
goto fail;
if (must_swab) {
for(i = 0; i < ehdr.e_phnum; i++) {
ph = &phdr[i];
glue(bswap_phdr, SZ)(ph);
}
}
total_size = 0;
for(i = 0; i < ehdr.e_phnum; i++) {
ph = &phdr[i];
if (ph->p_type == PT_LOAD) {
mem_size = ph->p_memsz; /* Size of the ROM */
file_size = ph->p_filesz; /* Size of the allocated data */
data = g_malloc0(file_size);
if (ph->p_filesz > 0) {
if (lseek(fd, ph->p_offset, SEEK_SET) < 0) {
goto fail;
}
if (read(fd, data, file_size) != file_size) {
goto fail;
}
}
/* address_offset is hack for kernel images that are
linked at the wrong physical address. */
if (translate_fn) {
addr = translate_fn(translate_opaque, ph->p_paddr);
} else {
addr = ph->p_paddr;
}
/* the entry pointer in the ELF header is a virtual
* address, if the text segments paddr and vaddr differ
* we need to adjust the entry */
if (pentry && !translate_fn &&
ph->p_vaddr != ph->p_paddr &&
ehdr.e_entry >= ph->p_vaddr &&
ehdr.e_entry < ph->p_vaddr + ph->p_filesz &&
ph->p_flags & PF_X) {
*pentry = ehdr.e_entry - ph->p_vaddr + ph->p_paddr;
}
snprintf(label, sizeof(label), "phdr #%d: %s", i, name);
/* rom_add_elf_program() seize the ownership of 'data' */
rom_add_elf_program(label, data, file_size, mem_size, addr);
total_size += mem_size;
if (addr < low)
low = addr;
if ((addr + mem_size) > high)
high = addr + mem_size;
data = NULL;
}
}
g_free(phdr);
if (lowaddr)
*lowaddr = (uint64_t)(elf_sword)low;
if (highaddr)
*highaddr = (uint64_t)(elf_sword)high;
return total_size;
fail:
g_free(data);
g_free(phdr);
return -1;
}

7
include/hw/empty_slot.h Normal file
View file

@ -0,0 +1,7 @@
#ifndef HW_EMPTY_SLOT_H
#define HW_EMPTY_SLOT_H 1
/* empty_slot.c */
void empty_slot_init(hwaddr addr, uint64_t slot_size);
#endif

76
include/hw/hw.h Normal file
View file

@ -0,0 +1,76 @@
/* Declarations for use by hardware emulation. */
#ifndef QEMU_HW_H
#define QEMU_HW_H
#include "qemu-common.h"
#if !defined(CONFIG_USER_ONLY) && !defined(NEED_CPU_H)
#include "exec/cpu-common.h"
#endif
#include "exec/ioport.h"
#include "hw/irq.h"
#include "block/aio.h"
#include "migration/qemu-file.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#ifdef NEED_CPU_H
#if TARGET_LONG_BITS == 64
#define qemu_put_betl qemu_put_be64
#define qemu_get_betl qemu_get_be64
#define qemu_put_betls qemu_put_be64s
#define qemu_get_betls qemu_get_be64s
#define qemu_put_sbetl qemu_put_sbe64
#define qemu_get_sbetl qemu_get_sbe64
#define qemu_put_sbetls qemu_put_sbe64s
#define qemu_get_sbetls qemu_get_sbe64s
#else
#define qemu_put_betl qemu_put_be32
#define qemu_get_betl qemu_get_be32
#define qemu_put_betls qemu_put_be32s
#define qemu_get_betls qemu_get_be32s
#define qemu_put_sbetl qemu_put_sbe32
#define qemu_get_sbetl qemu_get_sbe32
#define qemu_put_sbetls qemu_put_sbe32s
#define qemu_get_sbetls qemu_get_sbe32s
#endif
#endif
typedef void QEMUResetHandler(void *opaque);
void qemu_register_reset(QEMUResetHandler *func, void *opaque);
void qemu_unregister_reset(QEMUResetHandler *func, void *opaque);
/* handler to set the boot_device order for a specific type of QEMUMachine */
/* return 0 if success */
typedef int QEMUBootSetHandler(void *opaque, const char *boot_devices);
void qemu_register_boot_set(QEMUBootSetHandler *func, void *opaque);
int qemu_boot_set(const char *boot_devices);
#ifdef NEED_CPU_H
#if TARGET_LONG_BITS == 64
#define VMSTATE_UINTTL_V(_f, _s, _v) \
VMSTATE_UINT64_V(_f, _s, _v)
#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \
VMSTATE_UINT64_EQUAL_V(_f, _s, _v)
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v)
#else
#define VMSTATE_UINTTL_V(_f, _s, _v) \
VMSTATE_UINT32_V(_f, _s, _v)
#define VMSTATE_UINTTL_EQUAL_V(_f, _s, _v) \
VMSTATE_UINT32_EQUAL_V(_f, _s, _v)
#define VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, _v) \
VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v)
#endif
#define VMSTATE_UINTTL(_f, _s) \
VMSTATE_UINTTL_V(_f, _s, 0)
#define VMSTATE_UINTTL_EQUAL(_f, _s) \
VMSTATE_UINTTL_EQUAL_V(_f, _s, 0)
#define VMSTATE_UINTTL_ARRAY(_f, _s, _n) \
VMSTATE_UINTTL_ARRAY_V(_f, _s, _n, 0)
#endif
#endif

88
include/hw/i2c/i2c.h Normal file
View file

@ -0,0 +1,88 @@
#ifndef QEMU_I2C_H
#define QEMU_I2C_H
#include "hw/qdev.h"
/* The QEMU I2C implementation only supports simple transfers that complete
immediately. It does not support slave devices that need to be able to
defer their response (eg. CPU slave interfaces where the data is supplied
by the device driver in response to an interrupt). */
enum i2c_event {
I2C_START_RECV,
I2C_START_SEND,
I2C_FINISH,
I2C_NACK /* Masker NACKed a receive byte. */
};
typedef struct I2CSlave I2CSlave;
#define TYPE_I2C_SLAVE "i2c-slave"
#define I2C_SLAVE(obj) \
OBJECT_CHECK(I2CSlave, (obj), TYPE_I2C_SLAVE)
#define I2C_SLAVE_CLASS(klass) \
OBJECT_CLASS_CHECK(I2CSlaveClass, (klass), TYPE_I2C_SLAVE)
#define I2C_SLAVE_GET_CLASS(obj) \
OBJECT_GET_CLASS(I2CSlaveClass, (obj), TYPE_I2C_SLAVE)
typedef struct I2CSlaveClass
{
DeviceClass parent_class;
/* Callbacks provided by the device. */
int (*init)(I2CSlave *dev);
/* Master to slave. */
int (*send)(I2CSlave *s, uint8_t data);
/* Slave to master. */
int (*recv)(I2CSlave *s);
/* Notify the slave of a bus state change. */
void (*event)(I2CSlave *s, enum i2c_event event);
} I2CSlaveClass;
struct I2CSlave
{
DeviceState qdev;
/* Remaining fields for internal use by the I2C code. */
uint8_t address;
};
i2c_bus *i2c_init_bus(DeviceState *parent, const char *name);
void i2c_set_slave_address(I2CSlave *dev, uint8_t address);
int i2c_bus_busy(i2c_bus *bus);
int i2c_start_transfer(i2c_bus *bus, uint8_t address, int recv);
void i2c_end_transfer(i2c_bus *bus);
void i2c_nack(i2c_bus *bus);
int i2c_send(i2c_bus *bus, uint8_t data);
int i2c_recv(i2c_bus *bus);
#define FROM_I2C_SLAVE(type, dev) DO_UPCAST(type, i2c, dev)
DeviceState *i2c_create_slave(i2c_bus *bus, const char *name, uint8_t addr);
/* wm8750.c */
void wm8750_data_req_set(DeviceState *dev,
void (*data_req)(void *, int, int), void *opaque);
void wm8750_dac_dat(void *opaque, uint32_t sample);
uint32_t wm8750_adc_dat(void *opaque);
void *wm8750_dac_buffer(void *opaque, int samples);
void wm8750_dac_commit(void *opaque);
void wm8750_set_bclk_in(void *opaque, int new_hz);
/* lm832x.c */
void lm832x_key_event(DeviceState *dev, int key, int state);
extern const VMStateDescription vmstate_i2c_slave;
#define VMSTATE_I2C_SLAVE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(I2CSlave), \
.vmsd = &vmstate_i2c_slave, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, I2CSlave), \
}
#endif

20
include/hw/i2c/pm_smbus.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef PM_SMBUS_H
#define PM_SMBUS_H
typedef struct PMSMBus {
i2c_bus *smbus;
MemoryRegion io;
uint8_t smb_stat;
uint8_t smb_ctl;
uint8_t smb_cmd;
uint8_t smb_addr;
uint8_t smb_data0;
uint8_t smb_data1;
uint8_t smb_data[32];
uint8_t smb_index;
} PMSMBus;
void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
#endif /* !PM_SMBUS_H */

83
include/hw/i2c/smbus.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef QEMU_SMBUS_H
#define QEMU_SMBUS_H
/*
* QEMU SMBus API
*
* Copyright (c) 2007 Arastra, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "hw/i2c/i2c.h"
#define TYPE_SMBUS_DEVICE "smbus-device"
#define SMBUS_DEVICE(obj) \
OBJECT_CHECK(SMBusDevice, (obj), TYPE_SMBUS_DEVICE)
#define SMBUS_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(SMBusDeviceClass, (klass), TYPE_SMBUS_DEVICE)
#define SMBUS_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(SMBusDeviceClass, (obj), TYPE_SMBUS_DEVICE)
typedef struct SMBusDeviceClass
{
I2CSlaveClass parent_class;
int (*init)(SMBusDevice *dev);
void (*quick_cmd)(SMBusDevice *dev, uint8_t read);
void (*send_byte)(SMBusDevice *dev, uint8_t val);
uint8_t (*receive_byte)(SMBusDevice *dev);
/* We can't distinguish between a word write and a block write with
length 1, so pass the whole data block including the length byte
(if present). The device is responsible figuring out what type of
command this is. */
void (*write_data)(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len);
/* Likewise we can't distinguish between different reads, or even know
the length of the read until the read is complete, so read data a
byte at a time. The device is responsible for adding the length
byte on block reads. */
uint8_t (*read_data)(SMBusDevice *dev, uint8_t cmd, int n);
} SMBusDeviceClass;
struct SMBusDevice {
/* The SMBus protocol is implemented on top of I2C. */
I2CSlave i2c;
/* Remaining fields for internal use only. */
int mode;
int data_len;
uint8_t data_buf[34]; /* command + len + 32 bytes of data. */
uint8_t command;
};
/* Master device commands. */
void smbus_quick_command(i2c_bus *bus, uint8_t addr, int read);
uint8_t smbus_receive_byte(i2c_bus *bus, uint8_t addr);
void smbus_send_byte(i2c_bus *bus, uint8_t addr, uint8_t data);
uint8_t smbus_read_byte(i2c_bus *bus, uint8_t addr, uint8_t command);
void smbus_write_byte(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t data);
uint16_t smbus_read_word(i2c_bus *bus, uint8_t addr, uint8_t command);
void smbus_write_word(i2c_bus *bus, uint8_t addr, uint8_t command, uint16_t data);
int smbus_read_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data);
void smbus_write_block(i2c_bus *bus, uint8_t addr, uint8_t command, uint8_t *data,
int len);
void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
const uint8_t *eeprom_spd, int size);
#endif

View file

@ -0,0 +1,30 @@
#ifndef HW_APIC_MSIDEF_H
#define HW_APIC_MSIDEF_H
/*
* Intel APIC constants: from include/asm/msidef.h
*/
/*
* Shifts for MSI data
*/
#define MSI_DATA_VECTOR_SHIFT 0
#define MSI_DATA_VECTOR_MASK 0x000000ff
#define MSI_DATA_DELIVERY_MODE_SHIFT 8
#define MSI_DATA_LEVEL_SHIFT 14
#define MSI_DATA_TRIGGER_SHIFT 15
/*
* Shift/mask fields for msi address
*/
#define MSI_ADDR_DEST_MODE_SHIFT 2
#define MSI_ADDR_REDIRECTION_SHIFT 3
#define MSI_ADDR_DEST_ID_SHIFT 12
#define MSI_ADDR_DEST_ID_MASK 0x00ffff0
#endif /* HW_APIC_MSIDEF_H */

32
include/hw/i386/apic.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef APIC_H
#define APIC_H
#include "qemu-common.h"
/* apic.c */
void apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode,
uint8_t vector_num, uint8_t trigger_mode);
int apic_accept_pic_intr(DeviceState *s);
void apic_deliver_pic_intr(DeviceState *s, int level);
void apic_deliver_nmi(DeviceState *d);
int apic_get_interrupt(DeviceState *s);
void apic_reset_irq_delivered(void);
int apic_get_irq_delivered(void);
void cpu_set_apic_base(DeviceState *s, uint64_t val);
uint64_t cpu_get_apic_base(DeviceState *s);
void cpu_set_apic_tpr(DeviceState *s, uint8_t val);
uint8_t cpu_get_apic_tpr(DeviceState *s);
void apic_init_reset(DeviceState *s);
void apic_sipi(DeviceState *s);
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
TPRAccess access);
void apic_poll_irq(DeviceState *d);
void apic_designate_bsp(DeviceState *d);
/* pc.c */
DeviceState *cpu_get_current_apic(void);
/* cpu.c */
bool cpu_is_bsp(X86CPU *cpu);
#endif

View file

@ -0,0 +1,149 @@
/*
* APIC support - internal interfaces
*
* Copyright (c) 2004-2005 Fabrice Bellard
* Copyright (c) 2011 Jan Kiszka, Siemens AG
*
* 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/>
*/
#ifndef QEMU_APIC_INTERNAL_H
#define QEMU_APIC_INTERNAL_H
#include "exec/memory.h"
#include "hw/sysbus.h"
#include "qemu/timer.h"
/* APIC Local Vector Table */
#define APIC_LVT_TIMER 0
#define APIC_LVT_THERMAL 1
#define APIC_LVT_PERFORM 2
#define APIC_LVT_LINT0 3
#define APIC_LVT_LINT1 4
#define APIC_LVT_ERROR 5
#define APIC_LVT_NB 6
/* APIC delivery modes */
#define APIC_DM_FIXED 0
#define APIC_DM_LOWPRI 1
#define APIC_DM_SMI 2
#define APIC_DM_NMI 4
#define APIC_DM_INIT 5
#define APIC_DM_SIPI 6
#define APIC_DM_EXTINT 7
/* APIC destination mode */
#define APIC_DESTMODE_FLAT 0xf
#define APIC_DESTMODE_CLUSTER 1
#define APIC_TRIGGER_EDGE 0
#define APIC_TRIGGER_LEVEL 1
#define APIC_LVT_TIMER_PERIODIC (1<<17)
#define APIC_LVT_MASKED (1<<16)
#define APIC_LVT_LEVEL_TRIGGER (1<<15)
#define APIC_LVT_REMOTE_IRR (1<<14)
#define APIC_INPUT_POLARITY (1<<13)
#define APIC_SEND_PENDING (1<<12)
#define ESR_ILLEGAL_ADDRESS (1 << 7)
#define APIC_SV_DIRECTED_IO (1<<12)
#define APIC_SV_ENABLE (1<<8)
#define VAPIC_ENABLE_BIT 0
#define VAPIC_ENABLE_MASK (1 << VAPIC_ENABLE_BIT)
#define MAX_APICS 255
#define MSI_SPACE_SIZE 0x100000
typedef struct APICCommonState APICCommonState;
#define TYPE_APIC_COMMON "apic-common"
#define APIC_COMMON(obj) \
OBJECT_CHECK(APICCommonState, (obj), TYPE_APIC_COMMON)
#define APIC_COMMON_CLASS(klass) \
OBJECT_CLASS_CHECK(APICCommonClass, (klass), TYPE_APIC_COMMON)
#define APIC_COMMON_GET_CLASS(obj) \
OBJECT_GET_CLASS(APICCommonClass, (obj), TYPE_APIC_COMMON)
typedef struct APICCommonClass
{
SysBusDeviceClass parent_class;
void (*init)(APICCommonState *s);
void (*set_base)(APICCommonState *s, uint64_t val);
void (*set_tpr)(APICCommonState *s, uint8_t val);
uint8_t (*get_tpr)(APICCommonState *s);
void (*enable_tpr_reporting)(APICCommonState *s, bool enable);
void (*vapic_base_update)(APICCommonState *s);
void (*external_nmi)(APICCommonState *s);
void (*pre_save)(APICCommonState *s);
void (*post_load)(APICCommonState *s);
} APICCommonClass;
struct APICCommonState {
SysBusDevice busdev;
MemoryRegion io_memory;
X86CPU *cpu;
uint32_t apicbase;
uint8_t id;
uint8_t arb_id;
uint8_t tpr;
uint32_t spurious_vec;
uint8_t log_dest;
uint8_t dest_mode;
uint32_t isr[8]; /* in service register */
uint32_t tmr[8]; /* trigger mode register */
uint32_t irr[8]; /* interrupt request register */
uint32_t lvt[APIC_LVT_NB];
uint32_t esr; /* error register */
uint32_t icr[2];
uint32_t divide_conf;
int count_shift;
uint32_t initial_count;
int64_t initial_count_load_time;
int64_t next_time;
int idx;
QEMUTimer *timer;
int64_t timer_expiry;
int sipi_vector;
int wait_for_sipi;
uint32_t vapic_control;
DeviceState *vapic;
hwaddr vapic_paddr; /* note: persistence via kvmvapic */
};
typedef struct VAPICState {
uint8_t tpr;
uint8_t isr;
uint8_t zero;
uint8_t irr;
uint8_t enabled;
} QEMU_PACKED VAPICState;
extern bool apic_report_tpr_access;
void apic_report_irq_delivered(int delivered);
bool apic_next_timer(APICCommonState *s, int64_t current_time);
void apic_enable_tpr_access_reporting(DeviceState *d, bool enable);
void apic_enable_vapic(DeviceState *d, hwaddr paddr);
void vapic_report_tpr_access(DeviceState *dev, CPUState *cpu, target_ulong ip,
TPRAccess access);
#endif /* !QEMU_APIC_INTERNAL_H */

219
include/hw/i386/ich9.h Normal file
View file

@ -0,0 +1,219 @@
#ifndef HW_ICH9_H
#define HW_ICH9_H
#include "hw/hw.h"
#include "qemu/range.h"
#include "hw/isa/isa.h"
#include "hw/sysbus.h"
#include "hw/i386/pc.h"
#include "hw/isa/apm.h"
#include "hw/i386/ioapic.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie_host.h"
#include "hw/pci/pci_bridge.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/ich9.h"
#include "hw/pci/pci_bus.h"
void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
void ich9_lpc_pm_init(PCIDevice *pci_lpc, qemu_irq cmos_s3);
PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus);
i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
#define TYPE_ICH9_LPC_DEVICE "ICH9 LPC"
#define ICH9_LPC_DEVICE(obj) \
OBJECT_CHECK(ICH9LPCState, (obj), TYPE_ICH9_LPC_DEVICE)
typedef struct ICH9LPCState {
/* ICH9 LPC PCI to ISA bridge */
PCIDevice d;
/* (pci device, intx) -> pirq
* In real chipset case, the unused slots are never used
* as ICH9 supports only D25-D32 irq routing.
* On the other hand in qemu case, any slot/function can be populated
* via command line option.
* So fallback interrupt routing for any devices in any slots is necessary.
*/
uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS];
APMState apm;
ICH9LPCPMRegs pm;
uint32_t sci_level; /* track sci level */
/* 10.1 Chipset Configuration registers(Memory Space)
which is pointed by RCBA */
uint8_t chip_config[ICH9_CC_SIZE];
/*
* 13.7.5 RST_CNT---Reset Control Register (LPC I/F---D31:F0)
*
* register contents and IO memory region
*/
uint8_t rst_cnt;
MemoryRegion rst_cnt_mem;
/* isa bus */
ISABus *isa_bus;
MemoryRegion rbca_mem;
Notifier machine_ready;
qemu_irq *pic;
qemu_irq *ioapic;
} ICH9LPCState;
#define Q35_MASK(bit, ms_bit, ls_bit) \
((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1)))
/* ICH9: Chipset Configuration Registers */
#define ICH9_CC_ADDR_MASK (ICH9_CC_SIZE - 1)
#define ICH9_CC
#define ICH9_CC_D28IP 0x310C
#define ICH9_CC_D28IP_SHIFT 4
#define ICH9_CC_D28IP_MASK 0xf
#define ICH9_CC_D28IP_DEFAULT 0x00214321
#define ICH9_CC_D31IR 0x3140
#define ICH9_CC_D30IR 0x3142
#define ICH9_CC_D29IR 0x3144
#define ICH9_CC_D28IR 0x3146
#define ICH9_CC_D27IR 0x3148
#define ICH9_CC_D26IR 0x314C
#define ICH9_CC_D25IR 0x3150
#define ICH9_CC_DIR_DEFAULT 0x3210
#define ICH9_CC_D30IR_DEFAULT 0x0
#define ICH9_CC_DIR_SHIFT 4
#define ICH9_CC_DIR_MASK 0x7
#define ICH9_CC_OIC 0x31FF
#define ICH9_CC_OIC_AEN 0x1
/* D28:F[0-5] */
#define ICH9_PCIE_DEV 28
#define ICH9_PCIE_FUNC_MAX 6
/* D29:F0 USB UHCI Controller #1 */
#define ICH9_USB_UHCI1_DEV 29
#define ICH9_USB_UHCI1_FUNC 0
/* D30:F0 DMI-to-PCI brdige */
#define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE"
#define ICH9_D2P_BRIDGE_SAVEVM_VERSION 0
#define ICH9_D2P_BRIDGE_DEV 30
#define ICH9_D2P_BRIDGE_FUNC 0
#define ICH9_D2P_SECONDARY_DEFAULT (256 - 8)
#define ICH9_D2P_A2_REVISION 0x92
/* D31:F0 LPC Processor Interface */
#define ICH9_RST_CNT_IOPORT 0xCF9
/* D31:F1 LPC controller */
#define ICH9_A2_LPC "ICH9 A2 LPC"
#define ICH9_A2_LPC_SAVEVM_VERSION 0
#define ICH9_LPC_DEV 31
#define ICH9_LPC_FUNC 0
#define ICH9_A2_LPC_REVISION 0x2
#define ICH9_LPC_NB_PIRQS 8 /* PCI A-H */
#define ICH9_LPC_PMBASE 0x40
#define ICH9_LPC_PMBASE_BASE_ADDRESS_MASK Q35_MASK(32, 15, 7)
#define ICH9_LPC_PMBASE_RTE 0x1
#define ICH9_LPC_PMBASE_DEFAULT 0x1
#define ICH9_LPC_ACPI_CTRL 0x44
#define ICH9_LPC_ACPI_CTRL_ACPI_EN 0x80
#define ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK Q35_MASK(8, 2, 0)
#define ICH9_LPC_ACPI_CTRL_9 0x0
#define ICH9_LPC_ACPI_CTRL_10 0x1
#define ICH9_LPC_ACPI_CTRL_11 0x2
#define ICH9_LPC_ACPI_CTRL_20 0x4
#define ICH9_LPC_ACPI_CTRL_21 0x5
#define ICH9_LPC_ACPI_CTRL_DEFAULT 0x0
#define ICH9_LPC_PIRQA_ROUT 0x60
#define ICH9_LPC_PIRQB_ROUT 0x61
#define ICH9_LPC_PIRQC_ROUT 0x62
#define ICH9_LPC_PIRQD_ROUT 0x63
#define ICH9_LPC_PIRQE_ROUT 0x68
#define ICH9_LPC_PIRQF_ROUT 0x69
#define ICH9_LPC_PIRQG_ROUT 0x6a
#define ICH9_LPC_PIRQH_ROUT 0x6b
#define ICH9_LPC_PIRQ_ROUT_IRQEN 0x80
#define ICH9_LPC_PIRQ_ROUT_MASK Q35_MASK(8, 3, 0)
#define ICH9_LPC_PIRQ_ROUT_DEFAULT 0x80
#define ICH9_LPC_RCBA 0xf0
#define ICH9_LPC_RCBA_BA_MASK Q35_MASK(32, 31, 14)
#define ICH9_LPC_RCBA_EN 0x1
#define ICH9_LPC_RCBA_DEFAULT 0x0
#define ICH9_LPC_PIC_NUM_PINS 16
#define ICH9_LPC_IOAPIC_NUM_PINS 24
/* D31:F2 SATA Controller #1 */
#define ICH9_SATA1_DEV 31
#define ICH9_SATA1_FUNC 2
/* D30:F1 power management I/O registers
offset from the address ICH9_LPC_PMBASE */
/* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */
#define ICH9_PMIO_SIZE 128
#define ICH9_PMIO_MASK (ICH9_PMIO_SIZE - 1)
#define ICH9_PMIO_PM1_STS 0x00
#define ICH9_PMIO_PM1_EN 0x02
#define ICH9_PMIO_PM1_CNT 0x04
#define ICH9_PMIO_PM1_TMR 0x08
#define ICH9_PMIO_GPE0_STS 0x20
#define ICH9_PMIO_GPE0_EN 0x28
#define ICH9_PMIO_GPE0_LEN 16
#define ICH9_PMIO_SMI_EN 0x30
#define ICH9_PMIO_SMI_EN_APMC_EN (1 << 5)
#define ICH9_PMIO_SMI_STS 0x34
/* FADT ACPI_ENABLE/ACPI_DISABLE */
#define ICH9_APM_ACPI_ENABLE 0x2
#define ICH9_APM_ACPI_DISABLE 0x3
/* D31:F3 SMBus controller */
#define ICH9_A2_SMB_REVISION 0x02
#define ICH9_SMB_PI 0x00
#define ICH9_SMB_SMBMBAR0 0x10
#define ICH9_SMB_SMBMBAR1 0x14
#define ICH9_SMB_SMBM_BAR 0
#define ICH9_SMB_SMBM_SIZE (1 << 8)
#define ICH9_SMB_SMB_BASE 0x20
#define ICH9_SMB_SMB_BASE_BAR 4
#define ICH9_SMB_SMB_BASE_SIZE (1 << 5)
#define ICH9_SMB_HOSTC 0x40
#define ICH9_SMB_HOSTC_SSRESET ((uint8_t)(1 << 3))
#define ICH9_SMB_HOSTC_I2C_EN ((uint8_t)(1 << 2))
#define ICH9_SMB_HOSTC_SMB_SMI_EN ((uint8_t)(1 << 1))
#define ICH9_SMB_HOSTC_HST_EN ((uint8_t)(1 << 0))
/* D31:F3 SMBus I/O and memory mapped I/O registers */
#define ICH9_SMB_DEV 31
#define ICH9_SMB_FUNC 3
#define ICH9_SMB_HST_STS 0x00
#define ICH9_SMB_HST_CNT 0x02
#define ICH9_SMB_HST_CMD 0x03
#define ICH9_SMB_XMIT_SLVA 0x04
#define ICH9_SMB_HST_D0 0x05
#define ICH9_SMB_HST_D1 0x06
#define ICH9_SMB_HOST_BLOCK_DB 0x07
#endif /* HW_ICH9_H */

27
include/hw/i386/ioapic.h Normal file
View file

@ -0,0 +1,27 @@
/*
* ioapic.c IOAPIC emulation logic
*
* Copyright (c) 2011 Jan Kiszka, Siemens AG
*
* 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/>.
*/
#ifndef HW_IOAPIC_H
#define HW_IOAPIC_H
#define IOAPIC_NUM_PINS 24
void ioapic_eoi_broadcast(int vector);
#endif /* !HW_IOAPIC_H */

View file

@ -0,0 +1,102 @@
/*
* IOAPIC emulation logic - internal interfaces
*
* Copyright (c) 2004-2005 Fabrice Bellard
* Copyright (c) 2009 Xiantao Zhang, Intel
* Copyright (c) 2011 Jan Kiszka, Siemens AG
*
* 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/>.
*/
#ifndef QEMU_IOAPIC_INTERNAL_H
#define QEMU_IOAPIC_INTERNAL_H
#include "hw/hw.h"
#include "exec/memory.h"
#include "hw/sysbus.h"
#define MAX_IOAPICS 1
#define IOAPIC_VERSION 0x11
#define IOAPIC_LVT_DEST_SHIFT 56
#define IOAPIC_LVT_MASKED_SHIFT 16
#define IOAPIC_LVT_TRIGGER_MODE_SHIFT 15
#define IOAPIC_LVT_REMOTE_IRR_SHIFT 14
#define IOAPIC_LVT_POLARITY_SHIFT 13
#define IOAPIC_LVT_DELIV_STATUS_SHIFT 12
#define IOAPIC_LVT_DEST_MODE_SHIFT 11
#define IOAPIC_LVT_DELIV_MODE_SHIFT 8
#define IOAPIC_LVT_MASKED (1 << IOAPIC_LVT_MASKED_SHIFT)
#define IOAPIC_LVT_REMOTE_IRR (1 << IOAPIC_LVT_REMOTE_IRR_SHIFT)
#define IOAPIC_TRIGGER_EDGE 0
#define IOAPIC_TRIGGER_LEVEL 1
/*io{apic,sapic} delivery mode*/
#define IOAPIC_DM_FIXED 0x0
#define IOAPIC_DM_LOWEST_PRIORITY 0x1
#define IOAPIC_DM_PMI 0x2
#define IOAPIC_DM_NMI 0x4
#define IOAPIC_DM_INIT 0x5
#define IOAPIC_DM_SIPI 0x6
#define IOAPIC_DM_EXTINT 0x7
#define IOAPIC_DM_MASK 0x7
#define IOAPIC_VECTOR_MASK 0xff
#define IOAPIC_IOREGSEL 0x00
#define IOAPIC_IOWIN 0x10
#define IOAPIC_REG_ID 0x00
#define IOAPIC_REG_VER 0x01
#define IOAPIC_REG_ARB 0x02
#define IOAPIC_REG_REDTBL_BASE 0x10
#define IOAPIC_ID 0x00
#define IOAPIC_ID_SHIFT 24
#define IOAPIC_ID_MASK 0xf
#define IOAPIC_VER_ENTRIES_SHIFT 16
typedef struct IOAPICCommonState IOAPICCommonState;
#define TYPE_IOAPIC_COMMON "ioapic-common"
#define IOAPIC_COMMON(obj) \
OBJECT_CHECK(IOAPICCommonState, (obj), TYPE_IOAPIC_COMMON)
#define IOAPIC_COMMON_CLASS(klass) \
OBJECT_CLASS_CHECK(IOAPICCommonClass, (klass), TYPE_IOAPIC_COMMON)
#define IOAPIC_COMMON_GET_CLASS(obj) \
OBJECT_GET_CLASS(IOAPICCommonClass, (obj), TYPE_IOAPIC_COMMON)
typedef struct IOAPICCommonClass {
SysBusDeviceClass parent_class;
void (*init)(IOAPICCommonState *s, int instance_no);
void (*pre_save)(IOAPICCommonState *s);
void (*post_load)(IOAPICCommonState *s);
} IOAPICCommonClass;
struct IOAPICCommonState {
SysBusDevice busdev;
MemoryRegion io_memory;
uint8_t id;
uint8_t ioregsel;
uint32_t irr;
uint64_t ioredtbl[IOAPIC_NUM_PINS];
};
void ioapic_reset_common(DeviceState *dev);
#endif /* !QEMU_IOAPIC_INTERNAL_H */

246
include/hw/i386/pc.h Normal file
View file

@ -0,0 +1,246 @@
#ifndef HW_PC_H
#define HW_PC_H
#include "qemu-common.h"
#include "exec/memory.h"
#include "exec/ioport.h"
#include "hw/isa/isa.h"
#include "hw/block/fdc.h"
#include "net/net.h"
#include "exec/memory.h"
#include "hw/i386/ioapic.h"
/* PC-style peripherals (also used by other machines). */
/* parallel.c */
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
{
ISADevice *dev;
dev = isa_try_create(bus, "isa-parallel");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "index", index);
qdev_prop_set_chr(&dev->qdev, "chardev", chr);
if (qdev_init(&dev->qdev) < 0) {
return false;
}
return true;
}
bool parallel_mm_init(MemoryRegion *address_space,
hwaddr base, int it_shift, qemu_irq irq,
CharDriverState *chr);
/* i8259.c */
extern DeviceState *isa_pic;
qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq);
qemu_irq *kvm_i8259_init(ISABus *bus);
int pic_read_irq(DeviceState *d);
int pic_get_output(DeviceState *d);
void pic_info(Monitor *mon, const QDict *qdict);
void irq_info(Monitor *mon, const QDict *qdict);
/* Global System Interrupts */
#define GSI_NUM_PINS IOAPIC_NUM_PINS
typedef struct GSIState {
qemu_irq i8259_irq[ISA_NUM_IRQS];
qemu_irq ioapic_irq[IOAPIC_NUM_PINS];
} GSIState;
void gsi_handler(void *opaque, int n, int level);
/* vmport.c */
static inline void vmport_init(ISABus *bus)
{
isa_create_simple(bus, "vmport");
}
void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque);
void vmmouse_get_data(uint32_t *data);
void vmmouse_set_data(const uint32_t *data);
/* pckbd.c */
void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
void i8042_mm_init(qemu_irq kbd_irq, qemu_irq mouse_irq,
MemoryRegion *region, ram_addr_t size,
hwaddr mask);
void i8042_isa_mouse_fake_event(void *opaque);
void i8042_setup_a20_line(ISADevice *dev, qemu_irq *a20_out);
/* pc.c */
extern int fd_bootchk;
void pc_register_ferr_irq(qemu_irq irq);
void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
void pc_cpus_init(const char *cpu_model);
void pc_acpi_init(const char *default_dsdt);
void *pc_memory_init(MemoryRegion *system_memory,
const char *kernel_filename,
const char *kernel_cmdline,
const char *initrd_filename,
ram_addr_t below_4g_mem_size,
ram_addr_t above_4g_mem_size,
MemoryRegion *rom_memory,
MemoryRegion **ram_memory);
qemu_irq *pc_allocate_cpu_irq(void);
DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
ISADevice **rtc_state,
ISADevice **floppy,
bool no_vmport);
void pc_init_ne2k_isa(ISABus *bus, NICInfo *nd);
void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
const char *boot_device,
ISADevice *floppy, BusState *ide0, BusState *ide1,
ISADevice *s);
void pc_nic_init(ISABus *isa_bus, PCIBus *pci_bus);
void pc_pci_device_init(PCIBus *pci_bus);
typedef void (*cpu_set_smm_t)(int smm, void *arg);
void cpu_smm_register(cpu_set_smm_t callback, void *arg);
void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
/* acpi.c */
extern int acpi_enabled;
extern char unsigned *acpi_tables;
extern size_t acpi_tables_len;
void acpi_bios_init(void);
void acpi_table_add(const QemuOpts *opts, Error **errp);
/* acpi_piix.c */
i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq, qemu_irq smi_irq,
int kvm_enabled, void *fw_cfg);
void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
/* hpet.c */
extern int no_hpet;
/* piix_pci.c */
struct PCII440FXState;
typedef struct PCII440FXState PCII440FXState;
PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix_devfn,
ISABus **isa_bus, qemu_irq *pic,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
ram_addr_t ram_size,
hwaddr pci_hole_start,
hwaddr pci_hole_size,
hwaddr pci_hole64_start,
hwaddr pci_hole64_size,
MemoryRegion *pci_memory,
MemoryRegion *ram_memory);
/* piix4.c */
extern PCIDevice *piix4_dev;
int piix4_init(PCIBus *bus, ISABus **isa_bus, int devfn);
/* vga.c */
enum vga_retrace_method {
VGA_RETRACE_DUMB,
VGA_RETRACE_PRECISE
};
extern enum vga_retrace_method vga_retrace_method;
int isa_vga_mm_init(hwaddr vram_base,
hwaddr ctrl_base, int it_shift,
MemoryRegion *address_space);
/* ne2000.c */
static inline bool isa_ne2000_init(ISABus *bus, int base, int irq, NICInfo *nd)
{
ISADevice *dev;
qemu_check_nic_model(nd, "ne2k_isa");
dev = isa_try_create(bus, "ne2k_isa");
if (!dev) {
return false;
}
qdev_prop_set_uint32(&dev->qdev, "iobase", base);
qdev_prop_set_uint32(&dev->qdev, "irq", irq);
qdev_set_nic_properties(&dev->qdev, nd);
qdev_init_nofail(&dev->qdev);
return true;
}
/* pc_sysfw.c */
void pc_system_firmware_init(MemoryRegion *rom_memory);
/* e820 types */
#define E820_RAM 1
#define E820_RESERVED 2
#define E820_ACPI 3
#define E820_NVS 4
#define E820_UNUSABLE 5
int e820_add_entry(uint64_t, uint64_t, uint32_t);
#define PC_COMPAT_1_4 \
{\
.driver = "scsi-hd",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "scsi-cd",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "scsi-disk",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "ide-hd",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "ide-cd",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "ide-drive",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "virtio-blk-pci",\
.property = "discard_granularity",\
.value = stringify(0),\
},{\
.driver = "virtio-serial-pci",\
.property = "vectors",\
/* DEV_NVECTORS_UNSPECIFIED as a uint32_t string */\
.value = stringify(0xFFFFFFFF),\
},{\
.driver = "e1000",\
.property = "romfile",\
.value = "pxe-e1000.rom",\
},{\
.driver = "ne2k_pci",\
.property = "romfile",\
.value = "pxe-ne2k_pci.rom",\
},{\
.driver = "pcnet",\
.property = "romfile",\
.value = "pxe-pcnet.rom",\
},{\
.driver = "rtl8139",\
.property = "romfile",\
.value = "pxe-rtl8139.rom",\
},{\
.driver = "virtio-net-pci",\
.property = "romfile",\
.value = "pxe-virtio.rom",\
}
#endif

162
include/hw/i386/smbios.h Normal file
View file

@ -0,0 +1,162 @@
#ifndef QEMU_SMBIOS_H
#define QEMU_SMBIOS_H
/*
* SMBIOS Support
*
* Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
*
* Authors:
* Alex Williamson <alex.williamson@hp.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
int smbios_entry_add(const char *t);
void smbios_add_field(int type, int offset, int len, void *data);
uint8_t *smbios_get_table(size_t *length);
/*
* SMBIOS spec defined tables
*/
/* This goes at the beginning of every SMBIOS structure. */
struct smbios_structure_header {
uint8_t type;
uint8_t length;
uint16_t handle;
} QEMU_PACKED;
/* SMBIOS type 0 - BIOS Information */
struct smbios_type_0 {
struct smbios_structure_header header;
uint8_t vendor_str;
uint8_t bios_version_str;
uint16_t bios_starting_address_segment;
uint8_t bios_release_date_str;
uint8_t bios_rom_size;
uint8_t bios_characteristics[8];
uint8_t bios_characteristics_extension_bytes[2];
uint8_t system_bios_major_release;
uint8_t system_bios_minor_release;
uint8_t embedded_controller_major_release;
uint8_t embedded_controller_minor_release;
} QEMU_PACKED;
/* SMBIOS type 1 - System Information */
struct smbios_type_1 {
struct smbios_structure_header header;
uint8_t manufacturer_str;
uint8_t product_name_str;
uint8_t version_str;
uint8_t serial_number_str;
uint8_t uuid[16];
uint8_t wake_up_type;
uint8_t sku_number_str;
uint8_t family_str;
} QEMU_PACKED;
/* SMBIOS type 3 - System Enclosure (v2.3) */
struct smbios_type_3 {
struct smbios_structure_header header;
uint8_t manufacturer_str;
uint8_t type;
uint8_t version_str;
uint8_t serial_number_str;
uint8_t asset_tag_number_str;
uint8_t boot_up_state;
uint8_t power_supply_state;
uint8_t thermal_state;
uint8_t security_status;
uint32_t oem_defined;
uint8_t height;
uint8_t number_of_power_cords;
uint8_t contained_element_count;
// contained elements follow
} QEMU_PACKED;
/* SMBIOS type 4 - Processor Information (v2.0) */
struct smbios_type_4 {
struct smbios_structure_header header;
uint8_t socket_designation_str;
uint8_t processor_type;
uint8_t processor_family;
uint8_t processor_manufacturer_str;
uint32_t processor_id[2];
uint8_t processor_version_str;
uint8_t voltage;
uint16_t external_clock;
uint16_t max_speed;
uint16_t current_speed;
uint8_t status;
uint8_t processor_upgrade;
uint16_t l1_cache_handle;
uint16_t l2_cache_handle;
uint16_t l3_cache_handle;
} QEMU_PACKED;
/* SMBIOS type 16 - Physical Memory Array
* Associated with one type 17 (Memory Device).
*/
struct smbios_type_16 {
struct smbios_structure_header header;
uint8_t location;
uint8_t use;
uint8_t error_correction;
uint32_t maximum_capacity;
uint16_t memory_error_information_handle;
uint16_t number_of_memory_devices;
} QEMU_PACKED;
/* SMBIOS type 17 - Memory Device
* Associated with one type 19
*/
struct smbios_type_17 {
struct smbios_structure_header header;
uint16_t physical_memory_array_handle;
uint16_t memory_error_information_handle;
uint16_t total_width;
uint16_t data_width;
uint16_t size;
uint8_t form_factor;
uint8_t device_set;
uint8_t device_locator_str;
uint8_t bank_locator_str;
uint8_t memory_type;
uint16_t type_detail;
} QEMU_PACKED;
/* SMBIOS type 19 - Memory Array Mapped Address */
struct smbios_type_19 {
struct smbios_structure_header header;
uint32_t starting_address;
uint32_t ending_address;
uint16_t memory_array_handle;
uint8_t partition_width;
} QEMU_PACKED;
/* SMBIOS type 20 - Memory Device Mapped Address */
struct smbios_type_20 {
struct smbios_structure_header header;
uint32_t starting_address;
uint32_t ending_address;
uint16_t memory_device_handle;
uint16_t memory_array_mapped_address_handle;
uint8_t partition_row_position;
uint8_t interleave_position;
uint8_t interleaved_data_depth;
} QEMU_PACKED;
/* SMBIOS type 32 - System Boot Information */
struct smbios_type_32 {
struct smbios_structure_header header;
uint8_t reserved[6];
uint8_t boot_status;
} QEMU_PACKED;
/* SMBIOS type 127 -- End-of-table */
struct smbios_type_127 {
struct smbios_structure_header header;
} QEMU_PACKED;
#endif /*QEMU_SMBIOS_H */

32
include/hw/ide.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef HW_IDE_H
#define HW_IDE_H
#include "hw/isa/isa.h"
#include "hw/pci/pci.h"
#include "exec/memory.h"
#define MAX_IDE_DEVS 2
/* ide-isa.c */
ISADevice *isa_ide_init(ISABus *bus, int iobase, int iobase2, int isairq,
DriveInfo *hd0, DriveInfo *hd1);
/* ide-pci.c */
void pci_cmd646_ide_init(PCIBus *bus, DriveInfo **hd_table,
int secondary_ide_enabled);
PCIDevice *pci_piix3_xen_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix3_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
PCIDevice *pci_piix4_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
void vt82c686b_ide_init(PCIBus *bus, DriveInfo **hd_table, int devfn);
/* ide-mmio.c */
void mmio_ide_init_drives(DeviceState *dev, DriveInfo *hd0, DriveInfo *hd1);
int ide_get_geometry(BusState *bus, int unit,
int16_t *cyls, int8_t *heads, int8_t *secs);
int ide_get_bios_chs_trans(BusState *bus, int unit);
/* ide/core.c */
void ide_drive_get(DriveInfo **hd, int max_bus);
#endif /* HW_IDE_H */

87
include/hw/input/adb.h Normal file
View file

@ -0,0 +1,87 @@
/*
* QEMU ADB emulation shared definitions and prototypes
*
* Copyright (c) 2004-2007 Fabrice Bellard
* Copyright (c) 2007 Jocelyn Mayer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if !defined(__ADB_H__)
#define __ADB_H__
#include "hw/qdev.h"
#define MAX_ADB_DEVICES 16
#define ADB_MAX_OUT_LEN 16
typedef struct ADBBusState ADBBusState;
typedef struct ADBDevice ADBDevice;
/* buf = NULL means polling */
typedef int ADBDeviceRequest(ADBDevice *d, uint8_t *buf_out,
const uint8_t *buf, int len);
#define TYPE_ADB_DEVICE "adb-device"
#define ADB_DEVICE(obj) OBJECT_CHECK(ADBDevice, (obj), TYPE_ADB_DEVICE)
struct ADBDevice {
/*< private >*/
DeviceState parent_obj;
/*< public >*/
int devaddr;
int handler;
};
#define ADB_DEVICE_CLASS(cls) \
OBJECT_CLASS_CHECK(ADBDeviceClass, (cls), TYPE_ADB_DEVICE)
#define ADB_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(ADBDeviceClass, (obj), TYPE_ADB_DEVICE)
typedef struct ADBDeviceClass {
/*< private >*/
DeviceClass parent_class;
/*< public >*/
ADBDeviceRequest *devreq;
} ADBDeviceClass;
#define TYPE_ADB_BUS "apple-desktop-bus"
#define ADB_BUS(obj) OBJECT_CHECK(ADBBusState, (obj), TYPE_ADB_BUS)
struct ADBBusState {
/*< private >*/
BusState parent_obj;
/*< public >*/
ADBDevice *devices[MAX_ADB_DEVICES];
int nb_devices;
int poll_index;
};
int adb_request(ADBBusState *s, uint8_t *buf_out,
const uint8_t *buf, int len);
int adb_poll(ADBBusState *s, uint8_t *buf_out);
#define TYPE_ADB_KEYBOARD "adb-keyboard"
#define TYPE_ADB_MOUSE "adb-mouse"
#endif /* !defined(__ADB_H__) */

83
include/hw/input/hid.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef QEMU_HID_H
#define QEMU_HID_H
#include "migration/vmstate.h"
#define HID_MOUSE 1
#define HID_TABLET 2
#define HID_KEYBOARD 3
typedef struct HIDPointerEvent {
int32_t xdx, ydy; /* relative iff it's a mouse, otherwise absolute */
int32_t dz, buttons_state;
} HIDPointerEvent;
#define QUEUE_LENGTH 16 /* should be enough for a triple-click */
#define QUEUE_MASK (QUEUE_LENGTH-1u)
#define QUEUE_INCR(v) ((v)++, (v) &= QUEUE_MASK)
typedef struct HIDState HIDState;
typedef void (*HIDEventFunc)(HIDState *s);
typedef struct HIDMouseState {
HIDPointerEvent queue[QUEUE_LENGTH];
int mouse_grabbed;
QEMUPutMouseEntry *eh_entry;
} HIDMouseState;
typedef struct HIDKeyboardState {
uint32_t keycodes[QUEUE_LENGTH];
uint16_t modifiers;
uint8_t leds;
uint8_t key[16];
int32_t keys;
} HIDKeyboardState;
struct HIDState {
union {
HIDMouseState ptr;
HIDKeyboardState kbd;
};
uint32_t head; /* index into circular queue */
uint32_t n;
int kind;
int32_t protocol;
uint8_t idle;
bool idle_pending;
QEMUTimer *idle_timer;
HIDEventFunc event;
};
void hid_init(HIDState *hs, int kind, HIDEventFunc event);
void hid_reset(HIDState *hs);
void hid_free(HIDState *hs);
bool hid_has_events(HIDState *hs);
void hid_set_next_idle(HIDState *hs);
void hid_pointer_activate(HIDState *hs);
int hid_pointer_poll(HIDState *hs, uint8_t *buf, int len);
int hid_keyboard_poll(HIDState *hs, uint8_t *buf, int len);
int hid_keyboard_write(HIDState *hs, uint8_t *buf, int len);
extern const VMStateDescription vmstate_hid_keyboard_device;
#define VMSTATE_HID_KEYBOARD_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(HIDState), \
.vmsd = &vmstate_hid_keyboard_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, HIDState), \
}
extern const VMStateDescription vmstate_hid_ptr_device;
#define VMSTATE_HID_POINTER_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(HIDState), \
.vmsd = &vmstate_hid_ptr_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, HIDState), \
}
#endif /* QEMU_HID_H */

38
include/hw/input/ps2.h Normal file
View file

@ -0,0 +1,38 @@
/*
* QEMU PS/2 keyboard/mouse emulation
*
* Copyright (C) 2003 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_PS2_H
#define HW_PS2_H
/* ps2.c */
void *ps2_kbd_init(void (*update_irq)(void *, int), void *update_arg);
void *ps2_mouse_init(void (*update_irq)(void *, int), void *update_arg);
void ps2_write_mouse(void *, int val);
void ps2_write_keyboard(void *, int val);
uint32_t ps2_read_data(void *);
void ps2_queue(void *, int b);
void ps2_keyboard_set_translation(void *opaque, int mode);
void ps2_mouse_fake_event(void *opaque);
#endif /* !HW_PS2_H */

57
include/hw/irq.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef QEMU_IRQ_H
#define QEMU_IRQ_H
/* Generic IRQ/GPIO pin infrastructure. */
typedef struct IRQState *qemu_irq;
typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
void qemu_set_irq(qemu_irq irq, int level);
static inline void qemu_irq_raise(qemu_irq irq)
{
qemu_set_irq(irq, 1);
}
static inline void qemu_irq_lower(qemu_irq irq)
{
qemu_set_irq(irq, 0);
}
static inline void qemu_irq_pulse(qemu_irq irq)
{
qemu_set_irq(irq, 1);
qemu_set_irq(irq, 0);
}
/* Returns an array of N IRQs. Each IRQ is assigned the argument handler and
* opaque data.
*/
qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
/* Extends an Array of IRQs. Old IRQs have their handlers and opaque data
* preserved. New IRQs are assigned the argument handler and opaque data.
*/
qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler,
void *opaque, int n);
void qemu_free_irqs(qemu_irq *s);
/* Returns a new IRQ with opposite polarity. */
qemu_irq qemu_irq_invert(qemu_irq irq);
/* Returns a new IRQ which feeds into both the passed IRQs */
qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2);
/* Returns a new IRQ set which connects 1:1 to another IRQ set, which
* may be set later.
*/
qemu_irq *qemu_irq_proxy(qemu_irq **target, int n);
/* For internal use in qtest. Similar to qemu_irq_split, but operating
on an existing vector of qemu_irq. */
void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n);
void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n);
#endif

25
include/hw/isa/apm.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef APM_H
#define APM_H
#include <stdint.h>
#include "qemu-common.h"
#include "hw/hw.h"
#include "exec/memory.h"
typedef void (*apm_ctrl_changed_t)(uint32_t val, void *arg);
typedef struct APMState {
uint8_t apmc;
uint8_t apms;
apm_ctrl_changed_t callback;
void *arg;
MemoryRegion io;
} APMState;
void apm_init(PCIDevice *dev, APMState *s, apm_ctrl_changed_t callback,
void *arg);
extern const VMStateDescription vmstate_apm;
#endif /* APM_H */

View file

@ -0,0 +1,82 @@
/*
* QEMU 8259 - internal interfaces
*
* Copyright (c) 2011 Jan Kiszka, Siemens AG
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef QEMU_I8259_INTERNAL_H
#define QEMU_I8259_INTERNAL_H
#include "hw/hw.h"
#include "hw/i386/pc.h"
#include "hw/isa/isa.h"
typedef struct PICCommonState PICCommonState;
#define TYPE_PIC_COMMON "pic-common"
#define PIC_COMMON(obj) \
OBJECT_CHECK(PICCommonState, (obj), TYPE_PIC_COMMON)
#define PIC_COMMON_CLASS(klass) \
OBJECT_CLASS_CHECK(PICCommonClass, (klass), TYPE_PIC_COMMON)
#define PIC_COMMON_GET_CLASS(obj) \
OBJECT_GET_CLASS(PICCommonClass, (obj), TYPE_PIC_COMMON)
typedef struct PICCommonClass
{
ISADeviceClass parent_class;
void (*init)(PICCommonState *s);
void (*pre_save)(PICCommonState *s);
void (*post_load)(PICCommonState *s);
} PICCommonClass;
struct PICCommonState {
ISADevice dev;
uint8_t last_irr; /* edge detection */
uint8_t irr; /* interrupt request register */
uint8_t imr; /* interrupt mask register */
uint8_t isr; /* interrupt service register */
uint8_t priority_add; /* highest irq priority */
uint8_t irq_base;
uint8_t read_reg_select;
uint8_t poll;
uint8_t special_mask;
uint8_t init_state;
uint8_t auto_eoi;
uint8_t rotate_on_auto_eoi;
uint8_t special_fully_nested_mode;
uint8_t init4; /* true if 4 byte init */
uint8_t single_mode; /* true if slave pic is not initialized */
uint8_t elcr; /* PIIX edge/trigger selection*/
uint8_t elcr_mask;
qemu_irq int_out[1];
uint32_t master; /* reflects /SP input pin */
uint32_t iobase;
uint32_t elcr_addr;
MemoryRegion base_io;
MemoryRegion elcr_io;
};
void pic_reset_common(PICCommonState *s);
ISADevice *i8259_init_chip(const char *name, ISABus *bus, bool master);
#endif /* !QEMU_I8259_INTERNAL_H */

104
include/hw/isa/isa.h Normal file
View file

@ -0,0 +1,104 @@
#ifndef HW_ISA_H
#define HW_ISA_H
/* ISA bus */
#include "exec/ioport.h"
#include "exec/memory.h"
#include "hw/qdev.h"
#define ISA_NUM_IRQS 16
#define TYPE_ISA_DEVICE "isa-device"
#define ISA_DEVICE(obj) \
OBJECT_CHECK(ISADevice, (obj), TYPE_ISA_DEVICE)
#define ISA_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(ISADeviceClass, (klass), TYPE_ISA_DEVICE)
#define ISA_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(ISADeviceClass, (obj), TYPE_ISA_DEVICE)
#define TYPE_ISA_BUS "ISA"
#define ISA_BUS(obj) OBJECT_CHECK(ISABus, (obj), TYPE_ISA_BUS)
typedef struct ISADeviceClass {
DeviceClass parent_class;
int (*init)(ISADevice *dev);
} ISADeviceClass;
struct ISABus {
BusState qbus;
MemoryRegion *address_space_io;
qemu_irq *irqs;
};
struct ISADevice {
DeviceState qdev;
uint32_t isairq[2];
int nirqs;
int ioport_id;
};
ISABus *isa_bus_new(DeviceState *dev, MemoryRegion *address_space_io);
void isa_bus_irqs(ISABus *bus, qemu_irq *irqs);
qemu_irq isa_get_irq(ISADevice *dev, int isairq);
void isa_init_irq(ISADevice *dev, qemu_irq *p, int isairq);
MemoryRegion *isa_address_space(ISADevice *dev);
MemoryRegion *isa_address_space_io(ISADevice *dev);
ISADevice *isa_create(ISABus *bus, const char *name);
ISADevice *isa_try_create(ISABus *bus, const char *name);
ISADevice *isa_create_simple(ISABus *bus, const char *name);
ISADevice *isa_vga_init(ISABus *bus);
/**
* isa_register_ioport: Install an I/O port region on the ISA bus.
*
* Register an I/O port region via memory_region_add_subregion
* inside the ISA I/O address space.
*
* @dev: the ISADevice against which these are registered; may be NULL.
* @io: the #MemoryRegion being registered.
* @start: the base I/O port.
*/
void isa_register_ioport(ISADevice *dev, MemoryRegion *io, uint16_t start);
/**
* isa_register_portio_list: Initialize a set of ISA io ports
*
* Several ISA devices have many dis-joint I/O ports. Worse, these I/O
* ports can be interleaved with I/O ports from other devices. This
* function makes it easy to create multiple MemoryRegions for a single
* device and use the legacy portio routines.
*
* @dev: the ISADevice against which these are registered; may be NULL.
* @start: the base I/O port against which the portio->offset is applied.
* @portio: the ports, sorted by offset.
* @opaque: passed into the old_portio callbacks.
* @name: passed into memory_region_init_io.
*/
void isa_register_portio_list(ISADevice *dev, uint16_t start,
const MemoryRegionPortio *portio,
void *opaque, const char *name);
static inline ISABus *isa_bus_from_device(ISADevice *d)
{
return ISA_BUS(qdev_get_parent_bus(DEVICE(d)));
}
extern hwaddr isa_mem_base;
void isa_mmio_setup(MemoryRegion *mr, hwaddr size);
void isa_mmio_init(hwaddr base, hwaddr size);
/* dma.c */
int DMA_get_channel_mode (int nchan);
int DMA_read_memory (int nchan, void *buf, int pos, int size);
int DMA_write_memory (int nchan, void *buf, int pos, int size);
void DMA_hold_DREQ (int nchan);
void DMA_release_DREQ (int nchan);
void DMA_schedule(int nchan);
void DMA_init(int high_page_enable, qemu_irq *cpu_request_exit);
void DMA_register_channel (int nchan,
DMA_transfer_handler transfer_handler,
void *opaque);
#endif

68
include/hw/isa/pc87312.h Normal file
View file

@ -0,0 +1,68 @@
/*
* QEMU National Semiconductor PC87312 (Super I/O)
*
* Copyright (c) 2010-2012 Herve Poussineau
* Copyright (c) 2011-2012 Andreas Färber
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef QEMU_PC87312_H
#define QEMU_PC87312_H
#include "hw/isa/isa.h"
#define TYPE_PC87312 "pc87312"
#define PC87312(obj) OBJECT_CHECK(PC87312State, (obj), TYPE_PC87312)
typedef struct PC87312State {
ISADevice dev;
uint32_t iobase;
uint8_t config; /* initial configuration */
struct {
ISADevice *dev;
} parallel;
struct {
ISADevice *dev;
} uart[2];
struct {
ISADevice *dev;
BlockDriverState *drive[2];
uint32_t base;
} fdc;
struct {
ISADevice *dev;
uint32_t base;
} ide;
MemoryRegion io;
uint8_t read_id_step;
uint8_t selected_index;
uint8_t regs[3];
} PC87312State;
#endif

11
include/hw/isa/vt82c686.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef HW_VT82C686_H
#define HW_VT82C686_H
/* vt82c686.c */
ISABus *vt82c686b_init(PCIBus * bus, int devfn);
void vt82c686b_ac97_init(PCIBus *bus, int devfn);
void vt82c686b_mc97_init(PCIBus *bus, int devfn);
i2c_bus *vt82c686b_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
qemu_irq sci_irq);
#endif

24
include/hw/kvm/clock.h Normal file
View file

@ -0,0 +1,24 @@
/*
* QEMU KVM support, paravirtual clock device
*
* Copyright (C) 2011 Siemens AG
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
*
* This work is licensed under the terms of the GNU GPL version 2.
* See the COPYING file in the top-level directory.
*
*/
#ifdef CONFIG_KVM
void kvmclock_create(void);
#else /* CONFIG_KVM */
static inline void kvmclock_create(void)
{
}
#endif /* !CONFIG_KVM */

View file

@ -0,0 +1,11 @@
#ifndef QEMU_HW_LM32_JUART_H
#define QEMU_HW_LM32_JUART_H
#include "qemu-common.h"
uint32_t lm32_juart_get_jtx(DeviceState *d);
uint32_t lm32_juart_get_jrx(DeviceState *d);
void lm32_juart_set_jtx(DeviceState *d, uint32_t jtx);
void lm32_juart_set_jrx(DeviceState *d, uint32_t jrx);
#endif /* QEMU_HW_LM32_JUART_H */

View file

@ -0,0 +1,14 @@
#ifndef QEMU_HW_LM32_PIC_H
#define QEMU_HW_LM32_PIC_H
#include "qemu-common.h"
uint32_t lm32_pic_get_ip(DeviceState *d);
uint32_t lm32_pic_get_im(DeviceState *d);
void lm32_pic_set_ip(DeviceState *d, uint32_t ip);
void lm32_pic_set_im(DeviceState *d, uint32_t im);
void lm32_do_pic_info(Monitor *mon, const QDict *qdict);
void lm32_irq_info(Monitor *mon, const QDict *qdict);
#endif /* QEMU_HW_LM32_PIC_H */

52
include/hw/loader.h Normal file
View file

@ -0,0 +1,52 @@
#ifndef LOADER_H
#define LOADER_H
#include "qapi/qmp/qdict.h"
/* loader.c */
int get_image_size(const char *filename);
int load_image(const char *filename, uint8_t *addr); /* deprecated */
int load_image_targphys(const char *filename, hwaddr,
uint64_t max_sz);
int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
uint64_t *highaddr, int big_endian, int elf_machine,
int clear_lsb);
int load_aout(const char *filename, hwaddr addr, int max_sz,
int bswap_needed, hwaddr target_page_size);
int load_uimage(const char *filename, hwaddr *ep,
hwaddr *loadaddr, int *is_linux);
ssize_t read_targphys(const char *name,
int fd, hwaddr dst_addr, size_t nbytes);
void pstrcpy_targphys(const char *name,
hwaddr dest, int buf_size,
const char *source);
int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex);
int rom_add_blob(const char *name, const void *blob, size_t len,
hwaddr addr);
int rom_add_elf_program(const char *name, void *data, size_t datasize,
size_t romsize, hwaddr addr);
int rom_load_all(void);
void rom_set_fw(void *f);
int rom_copy(uint8_t *dest, hwaddr addr, size_t size);
void *rom_ptr(hwaddr addr);
void do_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
rom_add_file(_f, NULL, _a, _i)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _a)
#define PC_ROM_MIN_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000
#define PC_ROM_MAX 0xe0000
#define PC_ROM_ALIGN 0x800
#define PC_ROM_SIZE (PC_ROM_MAX - PC_ROM_MIN_VGA)
int rom_add_vga(const char *file);
int rom_add_option(const char *file, int32_t bootindex);
#endif

30
include/hw/m68k/mcf.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef HW_MCF_H
#define HW_MCF_H
/* Motorola ColdFire device prototypes. */
struct MemoryRegion;
/* mcf_uart.c */
uint64_t mcf_uart_read(void *opaque, hwaddr addr,
unsigned size);
void mcf_uart_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size);
void *mcf_uart_init(qemu_irq irq, CharDriverState *chr);
void mcf_uart_mm_init(struct MemoryRegion *sysmem,
hwaddr base,
qemu_irq irq, CharDriverState *chr);
/* mcf_intc.c */
qemu_irq *mcf_intc_init(struct MemoryRegion *sysmem,
hwaddr base,
M68kCPU *cpu);
/* mcf_fec.c */
void mcf_fec_init(struct MemoryRegion *sysmem, NICInfo *nd,
hwaddr base, qemu_irq *irq);
/* mcf5206.c */
qemu_irq *mcf5206_init(struct MemoryRegion *sysmem,
uint32_t base, M68kCPU *cpu);
#endif

8
include/hw/mips/bios.h Normal file
View file

@ -0,0 +1,8 @@
#include "cpu.h"
#define BIOS_SIZE (4 * 1024 * 1024)
#ifdef TARGET_WORDS_BIGENDIAN
#define BIOS_FILENAME "mips_bios.bin"
#else
#define BIOS_FILENAME "mipsel_bios.bin"
#endif

15
include/hw/mips/cpudevs.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef HW_MIPS_CPUDEVS_H
#define HW_MIPS_CPUDEVS_H
/* Definitions for MIPS CPU internal devices. */
/* mips_addr.c */
uint64_t cpu_mips_kseg0_to_phys(void *opaque, uint64_t addr);
uint64_t cpu_mips_phys_to_kseg0(void *opaque, uint64_t addr);
/* mips_int.c */
void cpu_mips_irq_init_cpu(CPUMIPSState *env);
/* mips_timer.c */
void cpu_mips_clock_init(CPUMIPSState *);
#endif

29
include/hw/mips/mips.h Normal file
View file

@ -0,0 +1,29 @@
#ifndef HW_MIPS_H
#define HW_MIPS_H
/* Definitions for mips board emulation. */
#include "exec/memory.h"
/* gt64xxx.c */
PCIBus *gt64120_register(qemu_irq *pic);
/* bonito.c */
PCIBus *bonito_init(qemu_irq *pic);
/* rc4030.c */
typedef struct rc4030DMAState *rc4030_dma;
void rc4030_dma_memory_rw(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write);
void rc4030_dma_read(void *dma, uint8_t *buf, int len);
void rc4030_dma_write(void *dma, uint8_t *buf, int len);
void *rc4030_init(qemu_irq timer, qemu_irq jazz_bus,
qemu_irq **irqs, rc4030_dma **dmas,
MemoryRegion *sysmem);
/* dp8393x.c */
void dp83932_init(NICInfo *nd, hwaddr base, int it_shift,
MemoryRegion *address_space,
qemu_irq irq, void* mem_opaque,
void (*memory_rw)(void *opaque, hwaddr addr, uint8_t *buf, int len, int is_write));
#endif

View file

@ -0,0 +1,50 @@
/*
* Texas Instruments TMP105 Temperature Sensor I2C messages
*
* Browse the data sheet:
*
* http://www.ti.com/lit/gpn/tmp105
*
* Copyright (C) 2012 Alex Horn <alex.horn@cs.ox.ac.uk>
* Copyright (C) 2008-2012 Andrzej Zaborowski <balrogg@gmail.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or
* later. See the COPYING file in the top-level directory.
*/
#ifndef QEMU_TMP105_MSGS_H
#define QEMU_TMP105_MSGS_H
/**
* TMP105Reg:
* @TMP105_REG_TEMPERATURE: Temperature register
* @TMP105_REG_CONFIG: Configuration register
* @TMP105_REG_T_LOW: Low temperature register (also known as T_hyst)
* @TMP105_REG_T_HIGH: High temperature register (also known as T_OS)
*
* The following temperature sensors are
* compatible with the TMP105 registers:
* - adt75
* - ds1775
* - ds75
* - lm75
* - lm75a
* - max6625
* - max6626
* - mcp980x
* - stds75
* - tcn75
* - tmp100
* - tmp101
* - tmp105
* - tmp175
* - tmp275
* - tmp75
**/
typedef enum TMP105Reg {
TMP105_REG_TEMPERATURE = 0,
TMP105_REG_CONFIG,
TMP105_REG_T_LOW,
TMP105_REG_T_HIGH,
} TMP105Reg;
#endif

View file

@ -0,0 +1,40 @@
/*
* QEMU EEPROM 93xx emulation
*
* Copyright (c) 2006-2007 Stefan Weil
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef EEPROM93XX_H
#define EEPROM93XX_H
typedef struct _eeprom_t eeprom_t;
/* Create a new EEPROM with (nwords * 2) bytes. */
eeprom_t *eeprom93xx_new(DeviceState *dev, uint16_t nwords);
/* Destroy an existing EEPROM. */
void eeprom93xx_free(DeviceState *dev, eeprom_t *eeprom);
/* Read from the EEPROM. */
uint16_t eeprom93xx_read(eeprom_t *eeprom);
/* Write to the EEPROM. */
void eeprom93xx_write(eeprom_t *eeprom, int eecs, int eesk, int eedi);
/* Get EEPROM data array. */
uint16_t *eeprom93xx_data(eeprom_t *eeprom);
#endif /* EEPROM93XX_H */

71
include/hw/nvram/fw_cfg.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef FW_CFG_H
#define FW_CFG_H
#define FW_CFG_SIGNATURE 0x00
#define FW_CFG_ID 0x01
#define FW_CFG_UUID 0x02
#define FW_CFG_RAM_SIZE 0x03
#define FW_CFG_NOGRAPHIC 0x04
#define FW_CFG_NB_CPUS 0x05
#define FW_CFG_MACHINE_ID 0x06
#define FW_CFG_KERNEL_ADDR 0x07
#define FW_CFG_KERNEL_SIZE 0x08
#define FW_CFG_KERNEL_CMDLINE 0x09
#define FW_CFG_INITRD_ADDR 0x0a
#define FW_CFG_INITRD_SIZE 0x0b
#define FW_CFG_BOOT_DEVICE 0x0c
#define FW_CFG_NUMA 0x0d
#define FW_CFG_BOOT_MENU 0x0e
#define FW_CFG_MAX_CPUS 0x0f
#define FW_CFG_KERNEL_ENTRY 0x10
#define FW_CFG_KERNEL_DATA 0x11
#define FW_CFG_INITRD_DATA 0x12
#define FW_CFG_CMDLINE_ADDR 0x13
#define FW_CFG_CMDLINE_SIZE 0x14
#define FW_CFG_CMDLINE_DATA 0x15
#define FW_CFG_SETUP_ADDR 0x16
#define FW_CFG_SETUP_SIZE 0x17
#define FW_CFG_SETUP_DATA 0x18
#define FW_CFG_FILE_DIR 0x19
#define FW_CFG_FILE_FIRST 0x20
#define FW_CFG_FILE_SLOTS 0x10
#define FW_CFG_MAX_ENTRY (FW_CFG_FILE_FIRST+FW_CFG_FILE_SLOTS)
#define FW_CFG_WRITE_CHANNEL 0x4000
#define FW_CFG_ARCH_LOCAL 0x8000
#define FW_CFG_ENTRY_MASK ~(FW_CFG_WRITE_CHANNEL | FW_CFG_ARCH_LOCAL)
#define FW_CFG_INVALID 0xffff
#ifndef NO_QEMU_PROTOS
typedef struct FWCfgFile {
uint32_t size; /* file size */
uint16_t select; /* write this to 0x510 to read it */
uint16_t reserved;
char name[56];
} FWCfgFile;
typedef struct FWCfgFiles {
uint32_t count;
FWCfgFile f[];
} FWCfgFiles;
typedef void (*FWCfgCallback)(void *opaque, uint8_t *data);
typedef struct FWCfgState FWCfgState;
void fw_cfg_add_bytes(FWCfgState *s, uint16_t key, void *data, size_t len);
void fw_cfg_add_string(FWCfgState *s, uint16_t key, const char *value);
void fw_cfg_add_i16(FWCfgState *s, uint16_t key, uint16_t value);
void fw_cfg_add_i32(FWCfgState *s, uint16_t key, uint32_t value);
void fw_cfg_add_i64(FWCfgState *s, uint16_t key, uint64_t value);
void fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
void *callback_opaque, void *data, size_t len);
void fw_cfg_add_file(FWCfgState *s, const char *filename, void *data,
size_t len);
FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
hwaddr crl_addr, hwaddr data_addr);
#endif /* NO_QEMU_PROTOS */
#endif

10
include/hw/pci-host/apb.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef APB_PCI_H
#define APB_PCI_H
#include "qemu-common.h"
PCIBus *pci_apb_init(hwaddr special_base,
hwaddr mem_base,
qemu_irq *ivec_irqs, PCIBus **bus2, PCIBus **bus3,
qemu_irq **pbm_irqs);
#endif

97
include/hw/pci-host/pam.h Normal file
View file

@ -0,0 +1,97 @@
#ifndef QEMU_PAM_H
#define QEMU_PAM_H
/*
* Copyright (c) 2006 Fabrice Bellard
* Copyright (c) 2011 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
* Copyright (c) 2012 Jason Baron <jbaron@redhat.com>
*
* Split out from piix_pci.c
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/*
* SMRAM memory area and PAM memory area in Legacy address range for PC.
* PAM: Programmable Attribute Map registers
*
* 0xa0000 - 0xbffff compatible SMRAM
*
* 0xc0000 - 0xc3fff Expansion area memory segments
* 0xc4000 - 0xc7fff
* 0xc8000 - 0xcbfff
* 0xcc000 - 0xcffff
* 0xd0000 - 0xd3fff
* 0xd4000 - 0xd7fff
* 0xd8000 - 0xdbfff
* 0xdc000 - 0xdffff
* 0xe0000 - 0xe3fff Extended System BIOS Area Memory Segments
* 0xe4000 - 0xe7fff
* 0xe8000 - 0xebfff
* 0xec000 - 0xeffff
*
* 0xf0000 - 0xfffff System BIOS Area Memory Segments
*/
#include "qemu-common.h"
#include "exec/memory.h"
#define SMRAM_C_BASE 0xa0000
#define SMRAM_C_END 0xc0000
#define SMRAM_C_SIZE 0x20000
#define PAM_EXPAN_BASE 0xc0000
#define PAM_EXPAN_SIZE 0x04000
#define PAM_EXBIOS_BASE 0xe0000
#define PAM_EXBIOS_SIZE 0x04000
#define PAM_BIOS_BASE 0xf0000
#define PAM_BIOS_END 0xfffff
/* 64KB: Intel 3 series express chipset family p. 58*/
#define PAM_BIOS_SIZE 0x10000
/* PAM registers: log nibble and high nibble*/
#define PAM_ATTR_WE ((uint8_t)2)
#define PAM_ATTR_RE ((uint8_t)1)
#define PAM_ATTR_MASK ((uint8_t)3)
/* SMRAM register */
#define SMRAM_D_OPEN ((uint8_t)(1 << 6))
#define SMRAM_D_CLS ((uint8_t)(1 << 5))
#define SMRAM_D_LCK ((uint8_t)(1 << 4))
#define SMRAM_G_SMRAME ((uint8_t)(1 << 3))
#define SMRAM_C_BASE_SEG_MASK ((uint8_t)0x7)
#define SMRAM_C_BASE_SEG ((uint8_t)0x2) /* hardwired to b010 */
typedef struct PAMMemoryRegion {
MemoryRegion alias[4]; /* index = PAM value */
unsigned current;
} PAMMemoryRegion;
void smram_update(MemoryRegion *smram_region, uint8_t smram,
uint8_t smm_enabled);
void smram_set_smm(uint8_t *host_smm_enabled, int smm, uint8_t smram,
MemoryRegion *smram_region);
void init_pam(MemoryRegion *ram, MemoryRegion *system, MemoryRegion *pci,
PAMMemoryRegion *mem, uint32_t start, uint32_t size);
void pam_update(PAMMemoryRegion *mem, int idx, uint8_t val);
#endif /* QEMU_PAM_H */

View file

@ -0,0 +1,9 @@
#ifndef PPCE500_PCI_H
#define PPCE500_PCI_H
static inline int ppce500_pci_map_irq_slot(int devno, int irq_num)
{
return (devno + irq_num) % 4;
}
#endif

150
include/hw/pci-host/q35.h Normal file
View file

@ -0,0 +1,150 @@
/*
* q35.h
*
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
* Copyright (C) 2012 Jason Baron <jbaron@redhat.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 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/>
*/
#ifndef HW_Q35_H
#define HW_Q35_H
#include "hw/hw.h"
#include "qemu/range.h"
#include "hw/isa/isa.h"
#include "hw/sysbus.h"
#include "hw/i386/pc.h"
#include "hw/isa/apm.h"
#include "hw/i386/apic.h"
#include "hw/pci/pci.h"
#include "hw/pci/pcie_host.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/ich9.h"
#include "hw/pci-host/pam.h"
#define TYPE_Q35_HOST_DEVICE "q35-pcihost"
#define Q35_HOST_DEVICE(obj) \
OBJECT_CHECK(Q35PCIHost, (obj), TYPE_Q35_HOST_DEVICE)
#define TYPE_MCH_PCI_DEVICE "mch"
#define MCH_PCI_DEVICE(obj) \
OBJECT_CHECK(MCHPCIState, (obj), TYPE_MCH_PCI_DEVICE)
typedef struct MCHPCIState {
PCIDevice d;
MemoryRegion *ram_memory;
MemoryRegion *pci_address_space;
MemoryRegion *system_memory;
MemoryRegion *address_space_io;
PAMMemoryRegion pam_regions[13];
MemoryRegion smram_region;
MemoryRegion pci_hole;
MemoryRegion pci_hole_64bit;
uint8_t smm_enabled;
ram_addr_t below_4g_mem_size;
ram_addr_t above_4g_mem_size;
} MCHPCIState;
typedef struct Q35PCIHost {
PCIExpressHost host;
MCHPCIState mch;
} Q35PCIHost;
#define Q35_MASK(bit, ms_bit, ls_bit) \
((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1)))
/*
* gmch part
*/
/* PCI configuration */
#define MCH_HOST_BRIDGE "MCH"
#define MCH_HOST_BRIDGE_CONFIG_ADDR 0xcf8
#define MCH_HOST_BRIDGE_CONFIG_DATA 0xcfc
/* D0:F0 configuration space */
#define MCH_HOST_BRIDGE_REVISION_DEFUALT 0x0
#define MCH_HOST_BRIDGE_PCIEXBAR 0x60 /* 64bit register */
#define MCH_HOST_BRIDGE_PCIEXBAR_SIZE 8 /* 64bit register */
#define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT 0xb0000000
#define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK Q35_MASK(64, 35, 28)
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK ((uint64_t)(1 << 26))
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK ((uint64_t)(1 << 25))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK ((uint64_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M ((uint64_t)(0x0 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M ((uint64_t)(0x1 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M ((uint64_t)(0x2 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD ((uint64_t)(0x3 << 1))
#define MCH_HOST_BRIDGE_PCIEXBAREN ((uint64_t)1)
#define MCH_HOST_BRIDGE_PAM_NB 7
#define MCH_HOST_BRIDGE_PAM_SIZE 7
#define MCH_HOST_BRIDGE_PAM0 0x90
#define MCH_HOST_BRIDGE_PAM_BIOS_AREA 0xf0000
#define MCH_HOST_BRIDGE_PAM_AREA_SIZE 0x10000 /* 16KB */
#define MCH_HOST_BRIDGE_PAM1 0x91
#define MCH_HOST_BRIDGE_PAM_EXPAN_AREA 0xc0000
#define MCH_HOST_BRIDGE_PAM_EXPAN_SIZE 0x04000
#define MCH_HOST_BRIDGE_PAM2 0x92
#define MCH_HOST_BRIDGE_PAM3 0x93
#define MCH_HOST_BRIDGE_PAM4 0x94
#define MCH_HOST_BRIDGE_PAM_EXBIOS_AREA 0xe0000
#define MCH_HOST_BRIDGE_PAM_EXBIOS_SIZE 0x04000
#define MCH_HOST_BRIDGE_PAM5 0x95
#define MCH_HOST_BRIDGE_PAM6 0x96
#define MCH_HOST_BRIDGE_PAM_WE_HI ((uint8_t)(0x2 << 4))
#define MCH_HOST_BRIDGE_PAM_RE_HI ((uint8_t)(0x1 << 4))
#define MCH_HOST_BRIDGE_PAM_HI_MASK ((uint8_t)(0x3 << 4))
#define MCH_HOST_BRIDGE_PAM_WE_LO ((uint8_t)0x2)
#define MCH_HOST_BRIDGE_PAM_RE_LO ((uint8_t)0x1)
#define MCH_HOST_BRIDGE_PAM_LO_MASK ((uint8_t)0x3)
#define MCH_HOST_BRIDGE_PAM_WE ((uint8_t)0x2)
#define MCH_HOST_BRIDGE_PAM_RE ((uint8_t)0x1)
#define MCH_HOST_BRIDGE_PAM_MASK ((uint8_t)0x3)
#define MCH_HOST_BRDIGE_SMRAM 0x9d
#define MCH_HOST_BRDIGE_SMRAM_SIZE 1
#define MCH_HOST_BRIDGE_SMRAM_DEFAULT ((uint8_t)0x2)
#define MCH_HOST_BRIDGE_SMRAM_D_OPEN ((uint8_t)(1 << 6))
#define MCH_HOST_BRIDGE_SMRAM_D_CLS ((uint8_t)(1 << 5))
#define MCH_HOST_BRIDGE_SMRAM_D_LCK ((uint8_t)(1 << 4))
#define MCH_HOST_BRIDGE_SMRAM_G_SMRAME ((uint8_t)(1 << 3))
#define MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG_MASK ((uint8_t)0x7)
#define MCH_HOST_BRIDGE_SMRAM_C_BASE_SEG ((uint8_t)0x2) /* hardwired to b010 */
#define MCH_HOST_BRIDGE_SMRAM_C_BASE 0xa0000
#define MCH_HOST_BRIDGE_SMRAM_C_END 0xc0000
#define MCH_HOST_BRIDGE_SMRAM_C_SIZE 0x20000
#define MCH_HOST_BRIDGE_UPPER_SYSTEM_BIOS_END 0x100000
#define MCH_HOST_BRIDGE_ESMRAMC 0x9e
#define MCH_HOST_BRDIGE_ESMRAMC_H_SMRAME ((uint8_t)(1 << 6))
#define MCH_HOST_BRDIGE_ESMRAMC_E_SMERR ((uint8_t)(1 << 5))
#define MCH_HOST_BRDIGE_ESMRAMC_SM_CACHE ((uint8_t)(1 << 4))
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L1 ((uint8_t)(1 << 3))
#define MCH_HOST_BRDIGE_ESMRAMC_SM_L2 ((uint8_t)(1 << 2))
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_MASK ((uint8_t)(0x3 << 1))
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_1MB ((uint8_t)(0x0 << 1))
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_2MB ((uint8_t)(0x1 << 1))
#define MCH_HOST_BRDIGE_ESMRAMC_TSEG_SZ_8MB ((uint8_t)(0x2 << 1))
#define MCH_HOST_BRDIGE_ESMRAMC_T_EN ((uint8_t)1)
/* D1:F0 PCIE* port*/
#define MCH_PCIE_DEV 1
#define MCH_PCIE_FUNC 0
#endif /* HW_Q35_H */

View file

@ -0,0 +1,92 @@
/*
* QEMU SPAPR PCI BUS definitions
*
* Copyright (c) 2011 Alexey Kardashevskiy <aik@au1.ibm.com>
*
* 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/>.
*/
#if !defined(__HW_SPAPR_H__)
#error Please include spapr.h before this file!
#endif
#if !defined(__HW_SPAPR_PCI_H__)
#define __HW_SPAPR_PCI_H__
#include "hw/pci/pci.h"
#include "hw/pci/pci_host.h"
#include "hw/ppc/xics.h"
#define SPAPR_MSIX_MAX_DEVS 32
#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
#define SPAPR_PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(sPAPRPHBState, (obj), TYPE_SPAPR_PCI_HOST_BRIDGE)
typedef struct sPAPRPHBState {
PCIHostState parent_obj;
int32_t index;
uint64_t buid;
char *dtbusname;
MemoryRegion memspace, iospace;
hwaddr mem_win_addr, mem_win_size, io_win_addr, io_win_size;
hwaddr msi_win_addr;
MemoryRegion memwindow, iowindow, msiwindow;
uint32_t dma_liobn;
uint64_t dma_window_start;
uint64_t dma_window_size;
DMAContext *dma;
struct {
uint32_t irq;
} lsi_table[PCI_NUM_PINS];
struct {
uint32_t config_addr;
uint32_t irq;
int nvec;
} msi_table[SPAPR_MSIX_MAX_DEVS];
QLIST_ENTRY(sPAPRPHBState) list;
} sPAPRPHBState;
#define SPAPR_PCI_BASE_BUID 0x800000020000000ULL
#define SPAPR_PCI_WINDOW_BASE 0x10000000000ULL
#define SPAPR_PCI_WINDOW_SPACING 0x1000000000ULL
#define SPAPR_PCI_MMIO_WIN_OFF 0xA0000000
#define SPAPR_PCI_MMIO_WIN_SIZE 0x20000000
#define SPAPR_PCI_IO_WIN_OFF 0x80000000
#define SPAPR_PCI_IO_WIN_SIZE 0x10000
#define SPAPR_PCI_MSI_WIN_OFF 0x90000000
#define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL
static inline qemu_irq spapr_phb_lsi_qirq(struct sPAPRPHBState *phb, int pin)
{
return xics_get_qirq(spapr->icp, phb->lsi_table[pin].irq);
}
PCIHostState *spapr_create_phb(sPAPREnvironment *spapr, int index);
int spapr_populate_pci_dt(sPAPRPHBState *phb,
uint32_t xics_phandle,
void *fdt);
void spapr_pci_rtas_init(void);
#endif /* __HW_SPAPR_PCI_H__ */

50
include/hw/pci/msi.h Normal file
View file

@ -0,0 +1,50 @@
/*
* msi.h
*
* Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_MSI_H
#define QEMU_MSI_H
#include "qemu-common.h"
#include "hw/pci/pci.h"
struct MSIMessage {
uint64_t address;
uint32_t data;
};
extern bool msi_supported;
void msi_set_message(PCIDevice *dev, MSIMessage msg);
MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector);
bool msi_enabled(const PCIDevice *dev);
int msi_init(struct PCIDevice *dev, uint8_t offset,
unsigned int nr_vectors, bool msi64bit, bool msi_per_vector_mask);
void msi_uninit(struct PCIDevice *dev);
void msi_reset(PCIDevice *dev);
void msi_notify(PCIDevice *dev, unsigned int vector);
void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len);
unsigned int msi_nr_vectors_allocated(const PCIDevice *dev);
static inline bool msi_present(const PCIDevice *dev)
{
return dev->cap_present & QEMU_PCI_CAP_MSI;
}
#endif /* QEMU_MSI_H */

46
include/hw/pci/msix.h Normal file
View file

@ -0,0 +1,46 @@
#ifndef QEMU_MSIX_H
#define QEMU_MSIX_H
#include "qemu-common.h"
#include "hw/pci/pci.h"
void msix_set_message(PCIDevice *dev, int vector, MSIMessage msg);
MSIMessage msix_get_message(PCIDevice *dev, unsigned int vector);
int msix_init(PCIDevice *dev, unsigned short nentries,
MemoryRegion *table_bar, uint8_t table_bar_nr,
unsigned table_offset, MemoryRegion *pba_bar,
uint8_t pba_bar_nr, unsigned pba_offset, uint8_t cap_pos);
int msix_init_exclusive_bar(PCIDevice *dev, unsigned short nentries,
uint8_t bar_nr);
void msix_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len);
void msix_uninit(PCIDevice *dev, MemoryRegion *table_bar,
MemoryRegion *pba_bar);
void msix_uninit_exclusive_bar(PCIDevice *dev);
unsigned int msix_nr_vectors_allocated(const PCIDevice *dev);
void msix_save(PCIDevice *dev, QEMUFile *f);
void msix_load(PCIDevice *dev, QEMUFile *f);
int msix_enabled(PCIDevice *dev);
int msix_present(PCIDevice *dev);
bool msix_is_masked(PCIDevice *dev, unsigned vector);
void msix_set_pending(PCIDevice *dev, unsigned vector);
int msix_vector_use(PCIDevice *dev, unsigned vector);
void msix_vector_unuse(PCIDevice *dev, unsigned vector);
void msix_unuse_all_vectors(PCIDevice *dev);
void msix_notify(PCIDevice *dev, unsigned vector);
void msix_reset(PCIDevice *dev);
int msix_set_vector_notifiers(PCIDevice *dev,
MSIVectorUseNotifier use_notifier,
MSIVectorReleaseNotifier release_notifier,
MSIVectorPollNotifier poll_notifier);
void msix_unset_vector_notifiers(PCIDevice *dev);
#endif

725
include/hw/pci/pci.h Normal file
View file

@ -0,0 +1,725 @@
#ifndef QEMU_PCI_H
#define QEMU_PCI_H
#include "qemu-common.h"
#include "hw/qdev.h"
#include "exec/memory.h"
#include "sysemu/dma.h"
/* PCI includes legacy ISA access. */
#include "hw/isa/isa.h"
#include "hw/pci/pcie.h"
/* PCI bus */
#define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07)
#define PCI_SLOT_MAX 32
#define PCI_FUNC_MAX 8
/* Class, Vendor and Device IDs from Linux's pci_ids.h */
#include "hw/pci/pci_ids.h"
/* QEMU-specific Vendor and Device ID definitions */
/* IBM (0x1014) */
#define PCI_DEVICE_ID_IBM_440GX 0x027f
#define PCI_DEVICE_ID_IBM_OPENPIC2 0xffff
/* Hitachi (0x1054) */
#define PCI_VENDOR_ID_HITACHI 0x1054
#define PCI_DEVICE_ID_HITACHI_SH7751R 0x350e
/* Apple (0x106b) */
#define PCI_DEVICE_ID_APPLE_343S1201 0x0010
#define PCI_DEVICE_ID_APPLE_UNI_N_I_PCI 0x001e
#define PCI_DEVICE_ID_APPLE_UNI_N_PCI 0x001f
#define PCI_DEVICE_ID_APPLE_UNI_N_KEYL 0x0022
#define PCI_DEVICE_ID_APPLE_IPID_USB 0x003f
/* Realtek (0x10ec) */
#define PCI_DEVICE_ID_REALTEK_8029 0x8029
/* Xilinx (0x10ee) */
#define PCI_DEVICE_ID_XILINX_XC2VP30 0x0300
/* Marvell (0x11ab) */
#define PCI_DEVICE_ID_MARVELL_GT6412X 0x4620
/* QEMU/Bochs VGA (0x1234) */
#define PCI_VENDOR_ID_QEMU 0x1234
#define PCI_DEVICE_ID_QEMU_VGA 0x1111
/* VMWare (0x15ad) */
#define PCI_VENDOR_ID_VMWARE 0x15ad
#define PCI_DEVICE_ID_VMWARE_SVGA2 0x0405
#define PCI_DEVICE_ID_VMWARE_SVGA 0x0710
#define PCI_DEVICE_ID_VMWARE_NET 0x0720
#define PCI_DEVICE_ID_VMWARE_SCSI 0x0730
#define PCI_DEVICE_ID_VMWARE_IDE 0x1729
#define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07B0
/* Intel (0x8086) */
#define PCI_DEVICE_ID_INTEL_82551IT 0x1209
#define PCI_DEVICE_ID_INTEL_82557 0x1229
#define PCI_DEVICE_ID_INTEL_82801IR 0x2922
/* Red Hat / Qumranet (for QEMU) -- see pci-ids.txt */
#define PCI_VENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_SUBVENDOR_ID_REDHAT_QUMRANET 0x1af4
#define PCI_SUBDEVICE_ID_QEMU 0x1100
#define PCI_DEVICE_ID_VIRTIO_NET 0x1000
#define PCI_DEVICE_ID_VIRTIO_BLOCK 0x1001
#define PCI_DEVICE_ID_VIRTIO_BALLOON 0x1002
#define PCI_DEVICE_ID_VIRTIO_CONSOLE 0x1003
#define PCI_DEVICE_ID_VIRTIO_SCSI 0x1004
#define PCI_DEVICE_ID_VIRTIO_RNG 0x1005
#define PCI_DEVICE_ID_VIRTIO_9P 0x1009
#define PCI_VENDOR_ID_REDHAT 0x1b36
#define PCI_DEVICE_ID_REDHAT_BRIDGE 0x0001
#define PCI_DEVICE_ID_REDHAT_SERIAL 0x0002
#define PCI_DEVICE_ID_REDHAT_SERIAL2 0x0003
#define PCI_DEVICE_ID_REDHAT_SERIAL4 0x0004
#define PCI_DEVICE_ID_REDHAT_QXL 0x0100
#define FMT_PCIBUS PRIx64
typedef void PCIConfigWriteFunc(PCIDevice *pci_dev,
uint32_t address, uint32_t data, int len);
typedef uint32_t PCIConfigReadFunc(PCIDevice *pci_dev,
uint32_t address, int len);
typedef void PCIMapIORegionFunc(PCIDevice *pci_dev, int region_num,
pcibus_t addr, pcibus_t size, int type);
typedef void PCIUnregisterFunc(PCIDevice *pci_dev);
typedef struct PCIIORegion {
pcibus_t addr; /* current PCI mapping address. -1 means not mapped */
#define PCI_BAR_UNMAPPED (~(pcibus_t)0)
pcibus_t size;
uint8_t type;
MemoryRegion *memory;
MemoryRegion *address_space;
} PCIIORegion;
#define PCI_ROM_SLOT 6
#define PCI_NUM_REGIONS 7
enum {
QEMU_PCI_VGA_MEM,
QEMU_PCI_VGA_IO_LO,
QEMU_PCI_VGA_IO_HI,
QEMU_PCI_VGA_NUM_REGIONS,
};
#define QEMU_PCI_VGA_MEM_BASE 0xa0000
#define QEMU_PCI_VGA_MEM_SIZE 0x20000
#define QEMU_PCI_VGA_IO_LO_BASE 0x3b0
#define QEMU_PCI_VGA_IO_LO_SIZE 0xc
#define QEMU_PCI_VGA_IO_HI_BASE 0x3c0
#define QEMU_PCI_VGA_IO_HI_SIZE 0x20
#include "hw/pci/pci_regs.h"
/* PCI HEADER_TYPE */
#define PCI_HEADER_TYPE_MULTI_FUNCTION 0x80
/* Size of the standard PCI config header */
#define PCI_CONFIG_HEADER_SIZE 0x40
/* Size of the standard PCI config space */
#define PCI_CONFIG_SPACE_SIZE 0x100
/* Size of the standart PCIe config space: 4KB */
#define PCIE_CONFIG_SPACE_SIZE 0x1000
#define PCI_NUM_PINS 4 /* A-D */
/* Bits in cap_present field. */
enum {
QEMU_PCI_CAP_MSI = 0x1,
QEMU_PCI_CAP_MSIX = 0x2,
QEMU_PCI_CAP_EXPRESS = 0x4,
/* multifunction capable device */
#define QEMU_PCI_CAP_MULTIFUNCTION_BITNR 3
QEMU_PCI_CAP_MULTIFUNCTION = (1 << QEMU_PCI_CAP_MULTIFUNCTION_BITNR),
/* command register SERR bit enabled */
#define QEMU_PCI_CAP_SERR_BITNR 4
QEMU_PCI_CAP_SERR = (1 << QEMU_PCI_CAP_SERR_BITNR),
/* Standard hot plug controller. */
#define QEMU_PCI_SHPC_BITNR 5
QEMU_PCI_CAP_SHPC = (1 << QEMU_PCI_SHPC_BITNR),
#define QEMU_PCI_SLOTID_BITNR 6
QEMU_PCI_CAP_SLOTID = (1 << QEMU_PCI_SLOTID_BITNR),
};
#define TYPE_PCI_DEVICE "pci-device"
#define PCI_DEVICE(obj) \
OBJECT_CHECK(PCIDevice, (obj), TYPE_PCI_DEVICE)
#define PCI_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(PCIDeviceClass, (klass), TYPE_PCI_DEVICE)
#define PCI_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(PCIDeviceClass, (obj), TYPE_PCI_DEVICE)
typedef struct PCIINTxRoute {
enum {
PCI_INTX_ENABLED,
PCI_INTX_INVERTED,
PCI_INTX_DISABLED,
} mode;
int irq;
} PCIINTxRoute;
typedef struct PCIDeviceClass {
DeviceClass parent_class;
int (*init)(PCIDevice *dev);
PCIUnregisterFunc *exit;
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
uint16_t vendor_id;
uint16_t device_id;
uint8_t revision;
uint16_t class_id;
uint16_t subsystem_vendor_id; /* only for header type = 0 */
uint16_t subsystem_id; /* only for header type = 0 */
/*
* pci-to-pci bridge or normal device.
* This doesn't mean pci host switch.
* When card bus bridge is supported, this would be enhanced.
*/
int is_bridge;
/* pcie stuff */
int is_express; /* is this device pci express? */
/* device isn't hot-pluggable */
int no_hotplug;
/* rom bar */
const char *romfile;
} PCIDeviceClass;
typedef void (*PCIINTxRoutingNotifier)(PCIDevice *dev);
typedef int (*MSIVectorUseNotifier)(PCIDevice *dev, unsigned int vector,
MSIMessage msg);
typedef void (*MSIVectorReleaseNotifier)(PCIDevice *dev, unsigned int vector);
typedef void (*MSIVectorPollNotifier)(PCIDevice *dev,
unsigned int vector_start,
unsigned int vector_end);
struct PCIDevice {
DeviceState qdev;
/* PCI config space */
uint8_t *config;
/* Used to enable config checks on load. Note that writable bits are
* never checked even if set in cmask. */
uint8_t *cmask;
/* Used to implement R/W bytes */
uint8_t *wmask;
/* Used to implement RW1C(Write 1 to Clear) bytes */
uint8_t *w1cmask;
/* Used to allocate config space for capabilities. */
uint8_t *used;
/* the following fields are read only */
PCIBus *bus;
int32_t devfn;
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
AddressSpace bus_master_as;
MemoryRegion bus_master_enable_region;
DMAContext *dma;
/* do not access the following fields */
PCIConfigReadFunc *config_read;
PCIConfigWriteFunc *config_write;
/* IRQ objects for the INTA-INTD pins. */
qemu_irq *irq;
/* Legacy PCI VGA regions */
MemoryRegion *vga_regions[QEMU_PCI_VGA_NUM_REGIONS];
bool has_vga;
/* Current IRQ levels. Used internally by the generic PCI code. */
uint8_t irq_state;
/* Capability bits */
uint32_t cap_present;
/* Offset of MSI-X capability in config space */
uint8_t msix_cap;
/* MSI-X entries */
int msix_entries_nr;
/* Space to store MSIX table & pending bit array */
uint8_t *msix_table;
uint8_t *msix_pba;
/* MemoryRegion container for msix exclusive BAR setup */
MemoryRegion msix_exclusive_bar;
/* Memory Regions for MSIX table and pending bit entries. */
MemoryRegion msix_table_mmio;
MemoryRegion msix_pba_mmio;
/* Reference-count for entries actually in use by driver. */
unsigned *msix_entry_used;
/* MSIX function mask set or MSIX disabled */
bool msix_function_masked;
/* Version id needed for VMState */
int32_t version_id;
/* Offset of MSI capability in config space */
uint8_t msi_cap;
/* PCI Express */
PCIExpressDevice exp;
/* SHPC */
SHPCDevice *shpc;
/* Location of option rom */
char *romfile;
bool has_rom;
MemoryRegion rom;
uint32_t rom_bar;
/* INTx routing notifier */
PCIINTxRoutingNotifier intx_routing_notifier;
/* MSI-X notifiers */
MSIVectorUseNotifier msix_vector_use_notifier;
MSIVectorReleaseNotifier msix_vector_release_notifier;
MSIVectorPollNotifier msix_vector_poll_notifier;
};
void pci_register_bar(PCIDevice *pci_dev, int region_num,
uint8_t attr, MemoryRegion *memory);
void pci_register_vga(PCIDevice *pci_dev, MemoryRegion *mem,
MemoryRegion *io_lo, MemoryRegion *io_hi);
void pci_unregister_vga(PCIDevice *pci_dev);
pcibus_t pci_get_bar_addr(PCIDevice *pci_dev, int region_num);
int pci_add_capability(PCIDevice *pdev, uint8_t cap_id,
uint8_t offset, uint8_t size);
void pci_del_capability(PCIDevice *pci_dev, uint8_t cap_id, uint8_t cap_size);
uint8_t pci_find_capability(PCIDevice *pci_dev, uint8_t cap_id);
uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len);
void pci_default_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len);
void pci_device_save(PCIDevice *s, QEMUFile *f);
int pci_device_load(PCIDevice *s, QEMUFile *f);
MemoryRegion *pci_address_space(PCIDevice *dev);
MemoryRegion *pci_address_space_io(PCIDevice *dev);
typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
typedef enum {
PCI_HOTPLUG_DISABLED,
PCI_HOTPLUG_ENABLED,
PCI_COLDPLUG_ENABLED,
} PCIHotplugState;
typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
PCIHotplugState state);
#define TYPE_PCI_BUS "PCI"
#define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
#define TYPE_PCIE_BUS "PCIE"
bool pci_bus_is_express(PCIBus *bus);
bool pci_bus_is_root(PCIBus *bus);
void pci_bus_new_inplace(PCIBus *bus, DeviceState *parent,
const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min, const char *typename);
PCIBus *pci_bus_new(DeviceState *parent, const char *name,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min, const char *typename);
void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque, int nirq);
int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
/* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin);
PCIBus *pci_register_bus(DeviceState *parent, const char *name,
pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
void *irq_opaque,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
uint8_t devfn_min, int nirq, const char *typename);
void pci_bus_set_route_irq_fn(PCIBus *, pci_route_irq_fn);
PCIINTxRoute pci_device_route_intx_to_irq(PCIDevice *dev, int pin);
bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new);
void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
void pci_device_set_intx_routing_notifier(PCIDevice *dev,
PCIINTxRoutingNotifier notifier);
void pci_device_reset(PCIDevice *dev);
void pci_bus_reset(PCIBus *bus);
PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model,
const char *default_devaddr);
PCIDevice *pci_nic_init_nofail(NICInfo *nd, const char *default_model,
const char *default_devaddr);
PCIDevice *pci_vga_init(PCIBus *bus);
int pci_bus_num(PCIBus *s);
void pci_for_each_device(PCIBus *bus, int bus_num,
void (*fn)(PCIBus *bus, PCIDevice *d, void *opaque),
void *opaque);
PCIBus *pci_find_root_bus(int domain);
int pci_find_domain(const PCIBus *bus);
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
int pci_qdev_find_device(const char *id, PCIDevice **pdev);
PCIBus *pci_get_bus_devfn(int *devfnp, const char *devaddr);
int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp,
unsigned *slotp);
void pci_device_deassert_intx(PCIDevice *dev);
typedef DMAContext *(*PCIDMAContextFunc)(PCIBus *, void *, int);
void pci_setup_iommu(PCIBus *bus, PCIDMAContextFunc fn, void *opaque);
static inline void
pci_set_byte(uint8_t *config, uint8_t val)
{
*config = val;
}
static inline uint8_t
pci_get_byte(const uint8_t *config)
{
return *config;
}
static inline void
pci_set_word(uint8_t *config, uint16_t val)
{
cpu_to_le16wu((uint16_t *)config, val);
}
static inline uint16_t
pci_get_word(const uint8_t *config)
{
return le16_to_cpupu((const uint16_t *)config);
}
static inline void
pci_set_long(uint8_t *config, uint32_t val)
{
cpu_to_le32wu((uint32_t *)config, val);
}
static inline uint32_t
pci_get_long(const uint8_t *config)
{
return le32_to_cpupu((const uint32_t *)config);
}
static inline void
pci_set_quad(uint8_t *config, uint64_t val)
{
cpu_to_le64w((uint64_t *)config, val);
}
static inline uint64_t
pci_get_quad(const uint8_t *config)
{
return le64_to_cpup((const uint64_t *)config);
}
static inline void
pci_config_set_vendor_id(uint8_t *pci_config, uint16_t val)
{
pci_set_word(&pci_config[PCI_VENDOR_ID], val);
}
static inline void
pci_config_set_device_id(uint8_t *pci_config, uint16_t val)
{
pci_set_word(&pci_config[PCI_DEVICE_ID], val);
}
static inline void
pci_config_set_revision(uint8_t *pci_config, uint8_t val)
{
pci_set_byte(&pci_config[PCI_REVISION_ID], val);
}
static inline void
pci_config_set_class(uint8_t *pci_config, uint16_t val)
{
pci_set_word(&pci_config[PCI_CLASS_DEVICE], val);
}
static inline void
pci_config_set_prog_interface(uint8_t *pci_config, uint8_t val)
{
pci_set_byte(&pci_config[PCI_CLASS_PROG], val);
}
static inline void
pci_config_set_interrupt_pin(uint8_t *pci_config, uint8_t val)
{
pci_set_byte(&pci_config[PCI_INTERRUPT_PIN], val);
}
/*
* helper functions to do bit mask operation on configuration space.
* Just to set bit, use test-and-set and discard returned value.
* Just to clear bit, use test-and-clear and discard returned value.
* NOTE: They aren't atomic.
*/
static inline uint8_t
pci_byte_test_and_clear_mask(uint8_t *config, uint8_t mask)
{
uint8_t val = pci_get_byte(config);
pci_set_byte(config, val & ~mask);
return val & mask;
}
static inline uint8_t
pci_byte_test_and_set_mask(uint8_t *config, uint8_t mask)
{
uint8_t val = pci_get_byte(config);
pci_set_byte(config, val | mask);
return val & mask;
}
static inline uint16_t
pci_word_test_and_clear_mask(uint8_t *config, uint16_t mask)
{
uint16_t val = pci_get_word(config);
pci_set_word(config, val & ~mask);
return val & mask;
}
static inline uint16_t
pci_word_test_and_set_mask(uint8_t *config, uint16_t mask)
{
uint16_t val = pci_get_word(config);
pci_set_word(config, val | mask);
return val & mask;
}
static inline uint32_t
pci_long_test_and_clear_mask(uint8_t *config, uint32_t mask)
{
uint32_t val = pci_get_long(config);
pci_set_long(config, val & ~mask);
return val & mask;
}
static inline uint32_t
pci_long_test_and_set_mask(uint8_t *config, uint32_t mask)
{
uint32_t val = pci_get_long(config);
pci_set_long(config, val | mask);
return val & mask;
}
static inline uint64_t
pci_quad_test_and_clear_mask(uint8_t *config, uint64_t mask)
{
uint64_t val = pci_get_quad(config);
pci_set_quad(config, val & ~mask);
return val & mask;
}
static inline uint64_t
pci_quad_test_and_set_mask(uint8_t *config, uint64_t mask)
{
uint64_t val = pci_get_quad(config);
pci_set_quad(config, val | mask);
return val & mask;
}
/* Access a register specified by a mask */
static inline void
pci_set_byte_by_mask(uint8_t *config, uint8_t mask, uint8_t reg)
{
uint8_t val = pci_get_byte(config);
uint8_t rval = reg << (ffs(mask) - 1);
pci_set_byte(config, (~mask & val) | (mask & rval));
}
static inline uint8_t
pci_get_byte_by_mask(uint8_t *config, uint8_t mask)
{
uint8_t val = pci_get_byte(config);
return (val & mask) >> (ffs(mask) - 1);
}
static inline void
pci_set_word_by_mask(uint8_t *config, uint16_t mask, uint16_t reg)
{
uint16_t val = pci_get_word(config);
uint16_t rval = reg << (ffs(mask) - 1);
pci_set_word(config, (~mask & val) | (mask & rval));
}
static inline uint16_t
pci_get_word_by_mask(uint8_t *config, uint16_t mask)
{
uint16_t val = pci_get_word(config);
return (val & mask) >> (ffs(mask) - 1);
}
static inline void
pci_set_long_by_mask(uint8_t *config, uint32_t mask, uint32_t reg)
{
uint32_t val = pci_get_long(config);
uint32_t rval = reg << (ffs(mask) - 1);
pci_set_long(config, (~mask & val) | (mask & rval));
}
static inline uint32_t
pci_get_long_by_mask(uint8_t *config, uint32_t mask)
{
uint32_t val = pci_get_long(config);
return (val & mask) >> (ffs(mask) - 1);
}
static inline void
pci_set_quad_by_mask(uint8_t *config, uint64_t mask, uint64_t reg)
{
uint64_t val = pci_get_quad(config);
uint64_t rval = reg << (ffs(mask) - 1);
pci_set_quad(config, (~mask & val) | (mask & rval));
}
static inline uint64_t
pci_get_quad_by_mask(uint8_t *config, uint64_t mask)
{
uint64_t val = pci_get_quad(config);
return (val & mask) >> (ffs(mask) - 1);
}
PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
const char *name);
PCIDevice *pci_create_simple_multifunction(PCIBus *bus, int devfn,
bool multifunction,
const char *name);
PCIDevice *pci_create(PCIBus *bus, int devfn, const char *name);
PCIDevice *pci_create_simple(PCIBus *bus, int devfn, const char *name);
static inline int pci_is_express(const PCIDevice *d)
{
return d->cap_present & QEMU_PCI_CAP_EXPRESS;
}
static inline uint32_t pci_config_size(const PCIDevice *d)
{
return pci_is_express(d) ? PCIE_CONFIG_SPACE_SIZE : PCI_CONFIG_SPACE_SIZE;
}
/* DMA access functions */
static inline DMAContext *pci_dma_context(PCIDevice *dev)
{
return dev->dma;
}
static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr,
void *buf, dma_addr_t len, DMADirection dir)
{
dma_memory_rw(pci_dma_context(dev), addr, buf, len, dir);
return 0;
}
static inline int pci_dma_read(PCIDevice *dev, dma_addr_t addr,
void *buf, dma_addr_t len)
{
return pci_dma_rw(dev, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
}
static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr,
const void *buf, dma_addr_t len)
{
return pci_dma_rw(dev, addr, (void *) buf, len, DMA_DIRECTION_FROM_DEVICE);
}
#define PCI_DMA_DEFINE_LDST(_l, _s, _bits) \
static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \
dma_addr_t addr) \
{ \
return ld##_l##_dma(pci_dma_context(dev), addr); \
} \
static inline void st##_s##_pci_dma(PCIDevice *dev, \
dma_addr_t addr, uint##_bits##_t val) \
{ \
st##_s##_dma(pci_dma_context(dev), addr, val); \
}
PCI_DMA_DEFINE_LDST(ub, b, 8);
PCI_DMA_DEFINE_LDST(uw_le, w_le, 16)
PCI_DMA_DEFINE_LDST(l_le, l_le, 32);
PCI_DMA_DEFINE_LDST(q_le, q_le, 64);
PCI_DMA_DEFINE_LDST(uw_be, w_be, 16)
PCI_DMA_DEFINE_LDST(l_be, l_be, 32);
PCI_DMA_DEFINE_LDST(q_be, q_be, 64);
#undef PCI_DMA_DEFINE_LDST
static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr,
dma_addr_t *plen, DMADirection dir)
{
void *buf;
buf = dma_memory_map(pci_dma_context(dev), addr, plen, dir);
return buf;
}
static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len,
DMADirection dir, dma_addr_t access_len)
{
dma_memory_unmap(pci_dma_context(dev), buffer, len, dir, access_len);
}
static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev,
int alloc_hint)
{
qemu_sglist_init(qsg, alloc_hint, pci_dma_context(dev));
}
extern const VMStateDescription vmstate_pci_device;
#define VMSTATE_PCI_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(PCIDevice), \
.vmsd = &vmstate_pci_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, PCIDevice), \
}
#define VMSTATE_PCI_DEVICE_POINTER(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(PCIDevice), \
.vmsd = &vmstate_pci_device, \
.flags = VMS_STRUCT|VMS_POINTER, \
.offset = vmstate_offset_pointer(_state, _field, PCIDevice), \
}
#endif

View file

@ -0,0 +1,65 @@
/*
* QEMU PCI bridge
*
* Copyright (c) 2004 Fabrice Bellard
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* split out pci bus specific stuff from pci.[hc] to pci_bridge.[hc]
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
*/
#ifndef QEMU_PCI_BRIDGE_H
#define QEMU_PCI_BRIDGE_H
#include "hw/pci/pci.h"
int pci_bridge_ssvid_init(PCIDevice *dev, uint8_t offset,
uint16_t svid, uint16_t ssid);
PCIDevice *pci_bridge_get_device(PCIBus *bus);
PCIBus *pci_bridge_get_sec_bus(PCIBridge *br);
pcibus_t pci_bridge_get_base(const PCIDevice *bridge, uint8_t type);
pcibus_t pci_bridge_get_limit(const PCIDevice *bridge, uint8_t type);
void pci_bridge_write_config(PCIDevice *d,
uint32_t address, uint32_t val, int len);
void pci_bridge_disable_base_limit(PCIDevice *dev);
void pci_bridge_reset_reg(PCIDevice *dev);
void pci_bridge_reset(DeviceState *qdev);
int pci_bridge_initfn(PCIDevice *pci_dev, const char *typename);
void pci_bridge_exitfn(PCIDevice *pci_dev);
/*
* before qdev initialization(qdev_init()), this function sets bus_name and
* map_irq callback which are necessry for pci_bridge_initfn() to
* initialize bus.
*/
void pci_bridge_map_irq(PCIBridge *br, const char* bus_name,
pci_map_irq_fn map_irq);
/* TODO: add this define to pci_regs.h in linux and then in qemu. */
#define PCI_BRIDGE_CTL_VGA_16BIT 0x10 /* VGA 16-bit decode */
#define PCI_BRIDGE_CTL_DISCARD 0x100 /* Primary discard timer */
#define PCI_BRIDGE_CTL_SEC_DISCARD 0x200 /* Secondary discard timer */
#define PCI_BRIDGE_CTL_DISCARD_STATUS 0x400 /* Discard timer status */
#define PCI_BRIDGE_CTL_DISCARD_SERR 0x800 /* Discard timer SERR# enable */
#endif /* QEMU_PCI_BRIDGE_H */

78
include/hw/pci/pci_bus.h Normal file
View file

@ -0,0 +1,78 @@
#ifndef QEMU_PCI_BUS_H
#define QEMU_PCI_BUS_H
/*
* PCI Bus and Bridge datastructures.
*
* Do not access the following members directly;
* use accessor functions in pci.h, pci_bridge.h
*/
struct PCIBus {
BusState qbus;
PCIDMAContextFunc dma_context_fn;
void *dma_context_opaque;
uint8_t devfn_min;
pci_set_irq_fn set_irq;
pci_map_irq_fn map_irq;
pci_route_irq_fn route_intx_to_irq;
pci_hotplug_fn hotplug;
DeviceState *hotplug_qdev;
void *irq_opaque;
PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
PCIDevice *parent_dev;
MemoryRegion *address_space_mem;
MemoryRegion *address_space_io;
QLIST_HEAD(, PCIBus) child; /* this will be replaced by qdev later */
QLIST_ENTRY(PCIBus) sibling;/* this will be replaced by qdev later */
/* The bus IRQ state is the logical OR of the connected devices.
Keep a count of the number of devices with raised IRQs. */
int nirq;
int *irq_count;
};
typedef struct PCIBridgeWindows PCIBridgeWindows;
/*
* Aliases for each of the address space windows that the bridge
* can forward. Mapped into the bridge's parent's address space,
* as subregions.
*/
struct PCIBridgeWindows {
MemoryRegion alias_pref_mem;
MemoryRegion alias_mem;
MemoryRegion alias_io;
/*
* When bridge control VGA forwarding is enabled, bridges will
* provide positive decode on the PCI VGA defined I/O port and
* MMIO ranges. When enabled forwarding is only qualified on the
* I/O and memory enable bits in the bridge command register.
*/
MemoryRegion alias_vga[QEMU_PCI_VGA_NUM_REGIONS];
};
struct PCIBridge {
PCIDevice dev;
/* private member */
PCIBus sec_bus;
/*
* Memory regions for the bridge's address spaces. These regions are not
* directly added to system_memory/system_io or its descendants.
* Bridge's secondary bus points to these, so that devices
* under the bridge see these regions as its address spaces.
* The regions are as large as the entire address space -
* they don't take into account any windows.
*/
MemoryRegion address_space_mem;
MemoryRegion address_space_io;
PCIBridgeWindows *windows;
pci_map_irq_fn map_irq;
const char *bus_name;
};
#endif /* QEMU_PCI_BUS_H */

61
include/hw/pci/pci_host.h Normal file
View file

@ -0,0 +1,61 @@
/*
* QEMU Common PCI Host bridge configuration data space access routines.
*
* Copyright (c) 2006 Fabrice Bellard
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/* Worker routines for a PCI host controller that uses an {address,data}
register pair to access PCI configuration space. */
#ifndef PCI_HOST_H
#define PCI_HOST_H
#include "hw/sysbus.h"
#define TYPE_PCI_HOST_BRIDGE "pci-host-bridge"
#define PCI_HOST_BRIDGE(obj) \
OBJECT_CHECK(PCIHostState, (obj), TYPE_PCI_HOST_BRIDGE)
struct PCIHostState {
SysBusDevice busdev;
MemoryRegion conf_mem;
MemoryRegion data_mem;
MemoryRegion mmcfg;
uint32_t config_reg;
PCIBus *bus;
};
/* common internal helpers for PCI/PCIe hosts, cut off overflows */
void pci_host_config_write_common(PCIDevice *pci_dev, uint32_t addr,
uint32_t limit, uint32_t val, uint32_t len);
uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
uint32_t limit, uint32_t len);
void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len);
uint32_t pci_data_read(PCIBus *s, uint32_t addr, int len);
extern const MemoryRegionOps pci_host_conf_le_ops;
extern const MemoryRegionOps pci_host_conf_be_ops;
extern const MemoryRegionOps pci_host_data_le_ops;
extern const MemoryRegionOps pci_host_data_be_ops;
#endif /* PCI_HOST_H */

154
include/hw/pci/pci_ids.h Normal file
View file

@ -0,0 +1,154 @@
/*
* PCI Class, Vendor and Device IDs
*
* Please keep sorted.
*
* Abbreviated version of linux/pci_ids.h
*
* QEMU-specific definitions belong in pci.h
*/
#ifndef HW_PCI_IDS_H
#define HW_PCI_IDS_H 1
/* Device classes and subclasses */
#define PCI_BASE_CLASS_STORAGE 0x01
#define PCI_BASE_CLASS_NETWORK 0x02
#define PCI_CLASS_STORAGE_SCSI 0x0100
#define PCI_CLASS_STORAGE_IDE 0x0101
#define PCI_CLASS_STORAGE_RAID 0x0104
#define PCI_CLASS_STORAGE_SATA 0x0106
#define PCI_CLASS_STORAGE_OTHER 0x0180
#define PCI_CLASS_NETWORK_ETHERNET 0x0200
#define PCI_CLASS_DISPLAY_VGA 0x0300
#define PCI_CLASS_DISPLAY_OTHER 0x0380
#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401
#define PCI_CLASS_MEMORY_RAM 0x0500
#define PCI_CLASS_SYSTEM_OTHER 0x0880
#define PCI_CLASS_SERIAL_USB 0x0c03
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
#define PCI_CLASS_BRIDGE_HOST 0x0600
#define PCI_CLASS_BRIDGE_ISA 0x0601
#define PCI_CLASS_BRIDGE_PCI 0x0604
#define PCI_CLASS_BRDIGE_PCI_INF_SUB 0x01
#define PCI_CLASS_BRIDGE_OTHER 0x0680
#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700
#define PCI_CLASS_COMMUNICATION_OTHER 0x0780
#define PCI_CLASS_PROCESSOR_CO 0x0b40
#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20
#define PCI_CLASS_OTHERS 0xff
/* Vendors and devices. Sort key: vendor first, device next. */
#define PCI_VENDOR_ID_LSI_LOGIC 0x1000
#define PCI_DEVICE_ID_LSI_53C895A 0x0012
#define PCI_DEVICE_ID_LSI_SAS1078 0x0060
#define PCI_VENDOR_ID_DEC 0x1011
#define PCI_DEVICE_ID_DEC_21154 0x0026
#define PCI_VENDOR_ID_CIRRUS 0x1013
#define PCI_VENDOR_ID_IBM 0x1014
#define PCI_VENDOR_ID_AMD 0x1022
#define PCI_DEVICE_ID_AMD_LANCE 0x2000
#define PCI_DEVICE_ID_AMD_SCSI 0x2020
#define PCI_VENDOR_ID_TI 0x104c
#define PCI_VENDOR_ID_MOTOROLA 0x1057
#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002
#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801
#define PCI_VENDOR_ID_APPLE 0x106b
#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020
#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b
#define PCI_VENDOR_ID_SUN 0x108e
#define PCI_DEVICE_ID_SUN_EBUS 0x1000
#define PCI_DEVICE_ID_SUN_SIMBA 0x5000
#define PCI_DEVICE_ID_SUN_SABRE 0xa000
#define PCI_VENDOR_ID_CMD 0x1095
#define PCI_DEVICE_ID_CMD_646 0x0646
#define PCI_VENDOR_ID_REALTEK 0x10ec
#define PCI_DEVICE_ID_REALTEK_8139 0x8139
#define PCI_VENDOR_ID_XILINX 0x10ee
#define PCI_VENDOR_ID_VIA 0x1106
#define PCI_DEVICE_ID_VIA_ISA_BRIDGE 0x0686
#define PCI_DEVICE_ID_VIA_IDE 0x0571
#define PCI_DEVICE_ID_VIA_UHCI 0x3038
#define PCI_DEVICE_ID_VIA_ACPI 0x3057
#define PCI_DEVICE_ID_VIA_AC97 0x3058
#define PCI_DEVICE_ID_VIA_MC97 0x3068
#define PCI_VENDOR_ID_MARVELL 0x11ab
#define PCI_VENDOR_ID_ENSONIQ 0x1274
#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000
#define PCI_VENDOR_ID_FREESCALE 0x1957
#define PCI_DEVICE_ID_MPC8533E 0x0030
#define PCI_VENDOR_ID_INTEL 0x8086
#define PCI_DEVICE_ID_INTEL_82378 0x0484
#define PCI_DEVICE_ID_INTEL_82441 0x1237
#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415
#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e
#define PCI_DEVICE_ID_INTEL_82801D 0x24CD
#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab
#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010
#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020
#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110
#define PCI_DEVICE_ID_INTEL_82371AB 0x7111
#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112
#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113
#define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910
#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917
#define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912
#define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913
#define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914
#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919
#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930
#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916
#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918
#define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934
#define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935
#define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936
#define PCI_DEVICE_ID_INTEL_82801I_UHCI4 0x2937
#define PCI_DEVICE_ID_INTEL_82801I_UHCI5 0x2938
#define PCI_DEVICE_ID_INTEL_82801I_UHCI6 0x2939
#define PCI_DEVICE_ID_INTEL_82801I_EHCI1 0x293a
#define PCI_DEVICE_ID_INTEL_82801I_EHCI2 0x293c
#define PCI_DEVICE_ID_INTEL_82599_SFP_VF 0x10ed
#define PCI_DEVICE_ID_INTEL_Q35_MCH 0x29c0
#define PCI_VENDOR_ID_XEN 0x5853
#define PCI_DEVICE_ID_XEN_PLATFORM 0x0001
#define PCI_VENDOR_ID_NEC 0x1033
#define PCI_DEVICE_ID_NEC_UPD720200 0x0194
#define PCI_VENDOR_ID_TEWS 0x1498
#define PCI_DEVICE_ID_TEWS_TPCI200 0x30C8
#endif

717
include/hw/pci/pci_regs.h Normal file
View file

@ -0,0 +1,717 @@
/*
* pci_regs.h
*
* PCI standard defines
* Copyright 1994, Drew Eckhardt
* Copyright 1997--1999 Martin Mares <mj@ucw.cz>
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
*
* PCI BIOS Specification
* PCI Local Bus Specification
* PCI to PCI Bridge Specification
* PCI System Design Guide
*
* For hypertransport information, please consult the following manuals
* from http://www.hypertransport.org
*
* The Hypertransport I/O Link Specification
*/
#ifndef LINUX_PCI_REGS_H
#define LINUX_PCI_REGS_H
/*
* Under PCI, each device has 256 bytes of configuration address space,
* of which the first 64 bytes are standardized as follows:
*/
#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
#define PCI_COMMAND 0x04 /* 16 bits */
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */
#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */
#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */
#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */
#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */
#define PCI_COMMAND_SERR 0x100 /* Enable SERR */
#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_INTERRUPT 0x08 /* Interrupt status */
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */
#define PCI_STATUS_PARITY 0x100 /* Detected parity error */
#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */
#define PCI_STATUS_DEVSEL_FAST 0x000
#define PCI_STATUS_DEVSEL_MEDIUM 0x200
#define PCI_STATUS_DEVSEL_SLOW 0x400
#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */
#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */
#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */
#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */
#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
#define PCI_REVISION_ID 0x08 /* Revision ID */
#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */
#define PCI_CLASS_DEVICE 0x0a /* Device class */
#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */
#define PCI_LATENCY_TIMER 0x0d /* 8 bits */
#define PCI_HEADER_TYPE 0x0e /* 8 bits */
#define PCI_HEADER_TYPE_NORMAL 0
#define PCI_HEADER_TYPE_BRIDGE 1
#define PCI_HEADER_TYPE_CARDBUS 2
#define PCI_BIST 0x0f /* 8 bits */
#define PCI_BIST_CODE_MASK 0x0f /* Return result */
#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */
#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */
/*
* Base addresses specify locations in memory or I/O space.
* Decoded size can be determined by writing a value of
* 0xffffffff to the register, and reading it back. Only
* 1 bits are decoded.
*/
#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */
#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */
#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */
#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */
#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */
#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */
#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */
#define PCI_BASE_ADDRESS_SPACE_IO 0x01
#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00
#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06
#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */
#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */
#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL)
#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL)
/* bit 1 is reserved if address_space = 1 */
/* Header type 0 (normal devices) */
#define PCI_CARDBUS_CIS 0x28
#define PCI_SUBSYSTEM_VENDOR_ID 0x2c
#define PCI_SUBSYSTEM_ID 0x2e
#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */
#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */
/* 0x35-0x3b are reserved */
#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */
#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */
#define PCI_MIN_GNT 0x3e /* 8 bits */
#define PCI_MAX_LAT 0x3f /* 8 bits */
/* Header type 1 (PCI-to-PCI bridges) */
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
#define PCI_IO_LIMIT 0x1d
#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
#define PCI_IO_RANGE_TYPE_16 0x00
#define PCI_IO_RANGE_TYPE_32 0x01
#define PCI_IO_RANGE_MASK (~0x0fUL)
#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
#define PCI_MEMORY_LIMIT 0x22
#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
#define PCI_PREF_MEMORY_LIMIT 0x26
#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
#define PCI_PREF_RANGE_TYPE_32 0x00
#define PCI_PREF_RANGE_TYPE_64 0x01
#define PCI_PREF_RANGE_MASK (~0x0fUL)
#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
#define PCI_PREF_LIMIT_UPPER32 0x2c
#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
#define PCI_IO_LIMIT_UPPER16 0x32
/* 0x34 same as for htype 0 */
/* 0x35-0x3b is reserved */
#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */
/* 0x3c-0x3d are same as for htype 0 */
#define PCI_BRIDGE_CONTROL 0x3e
#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */
#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */
#define PCI_BRIDGE_CTL_ISA 0x04 /* Enable ISA mode */
#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */
#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */
#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */
#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */
/* Header type 2 (CardBus bridges) */
#define PCI_CB_CAPABILITY_LIST 0x14
/* 0x15 reserved */
#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */
#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */
#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */
#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */
#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */
#define PCI_CB_MEMORY_BASE_0 0x1c
#define PCI_CB_MEMORY_LIMIT_0 0x20
#define PCI_CB_MEMORY_BASE_1 0x24
#define PCI_CB_MEMORY_LIMIT_1 0x28
#define PCI_CB_IO_BASE_0 0x2c
#define PCI_CB_IO_BASE_0_HI 0x2e
#define PCI_CB_IO_LIMIT_0 0x30
#define PCI_CB_IO_LIMIT_0_HI 0x32
#define PCI_CB_IO_BASE_1 0x34
#define PCI_CB_IO_BASE_1_HI 0x36
#define PCI_CB_IO_LIMIT_1 0x38
#define PCI_CB_IO_LIMIT_1_HI 0x3a
#define PCI_CB_IO_RANGE_MASK (~0x03UL)
/* 0x3c-0x3d are same as for htype 0 */
#define PCI_CB_BRIDGE_CONTROL 0x3e
#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */
#define PCI_CB_BRIDGE_CTL_SERR 0x02
#define PCI_CB_BRIDGE_CTL_ISA 0x04
#define PCI_CB_BRIDGE_CTL_VGA 0x08
#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20
#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */
#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */
#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200
#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400
#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40
#define PCI_CB_SUBSYSTEM_ID 0x42
#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */
/* 0x48-0x7f reserved */
/* Capability lists */
#define PCI_CAP_LIST_ID 0 /* Capability ID */
#define PCI_CAP_ID_PM 0x01 /* Power Management */
#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */
#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */
#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */
#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */
#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */
#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */
#define PCI_CAP_ID_HT 0x08 /* HyperTransport */
#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific */
#define PCI_CAP_ID_DBG 0x0A /* Debug port */
#define PCI_CAP_ID_CCRC 0x0B /* CompactPCI Central Resource Control */
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
#define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */
#define PCI_CAP_ID_AGP3 0x0E /* AGP Target PCI-PCI bridge */
#define PCI_CAP_ID_EXP 0x10 /* PCI Express */
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#define PCI_CAP_ID_SATA 0x12 /* Serial ATA */
#define PCI_CAP_ID_AF 0x13 /* PCI Advanced Features */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */
#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */
#define PCI_CAP_SIZEOF 4
/* Power Management Registers */
#define PCI_PM_PMC 2 /* PM Capabilities Register */
#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */
#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */
#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */
#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */
#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxiliary power support mask */
#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */
#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */
#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */
#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */
#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */
#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */
#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */
#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */
#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */
#define PCI_PM_CAP_PME_SHIFT 11 /* Start of the PME Mask in PMC */
#define PCI_PM_CTRL 4 /* PM control and status register */
#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */
#define PCI_PM_CTRL_NO_SOFT_RESET 0x0008 /* No reset for D3hot->D0 */
#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */
#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */
#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */
#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */
#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */
#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */
#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */
#define PCI_PM_DATA_REGISTER 7 /* (??) */
#define PCI_PM_SIZEOF 8
/* AGP registers */
#define PCI_AGP_VERSION 2 /* BCD version number */
#define PCI_AGP_RFU 3 /* Rest of capability flags */
#define PCI_AGP_STATUS 4 /* Status register */
#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */
#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */
#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */
#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */
#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */
#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */
#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */
#define PCI_AGP_COMMAND 8 /* Control register */
#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */
#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */
#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */
#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */
#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */
#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */
#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */
#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */
#define PCI_AGP_SIZEOF 12
/* Vital Product Data */
#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */
#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */
#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */
#define PCI_VPD_DATA 4 /* 32-bits of data returned here */
/* Slot Identification */
#define PCI_SID_ESR 2 /* Expansion Slot Register */
#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */
#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */
#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */
/* Message Signalled Interrupts registers */
#define PCI_MSI_FLAGS 2 /* Various flags */
#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */
#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */
#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */
#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */
#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */
#define PCI_MSI_RFU 3 /* Rest of capability flags */
#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */
#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */
#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */
#define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */
#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */
#define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */
/* MSI-X registers */
#define PCI_MSIX_FLAGS 2
#define PCI_MSIX_FLAGS_QSIZE 0x7FF
#define PCI_MSIX_FLAGS_ENABLE (1 << 15)
#define PCI_MSIX_FLAGS_MASKALL (1 << 14)
#define PCI_MSIX_TABLE 4
#define PCI_MSIX_PBA 8
#define PCI_MSIX_FLAGS_BIRMASK (7 << 0)
/* MSI-X entry's format */
#define PCI_MSIX_ENTRY_SIZE 16
#define PCI_MSIX_ENTRY_LOWER_ADDR 0
#define PCI_MSIX_ENTRY_UPPER_ADDR 4
#define PCI_MSIX_ENTRY_DATA 8
#define PCI_MSIX_ENTRY_VECTOR_CTRL 12
#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1
/* CompactPCI Hotswap Register */
#define PCI_CHSWP_CSR 2 /* Control and Status Register */
#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */
#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */
#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */
#define PCI_CHSWP_LOO 0x08 /* LED On / Off */
#define PCI_CHSWP_PI 0x30 /* Programming Interface */
#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */
#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */
/* PCI Advanced Feature registers */
#define PCI_AF_LENGTH 2
#define PCI_AF_CAP 3
#define PCI_AF_CAP_TP 0x01
#define PCI_AF_CAP_FLR 0x02
#define PCI_AF_CTRL 4
#define PCI_AF_CTRL_FLR 0x01
#define PCI_AF_STATUS 5
#define PCI_AF_STATUS_TP 0x01
/* PCI-X registers */
#define PCI_X_CMD 2 /* Modes & Features */
#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */
#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */
#define PCI_X_CMD_READ_512 0x0000 /* 512 byte maximum read byte count */
#define PCI_X_CMD_READ_1K 0x0004 /* 1Kbyte maximum read byte count */
#define PCI_X_CMD_READ_2K 0x0008 /* 2Kbyte maximum read byte count */
#define PCI_X_CMD_READ_4K 0x000c /* 4Kbyte maximum read byte count */
#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */
/* Max # of outstanding split transactions */
#define PCI_X_CMD_SPLIT_1 0x0000 /* Max 1 */
#define PCI_X_CMD_SPLIT_2 0x0010 /* Max 2 */
#define PCI_X_CMD_SPLIT_3 0x0020 /* Max 3 */
#define PCI_X_CMD_SPLIT_4 0x0030 /* Max 4 */
#define PCI_X_CMD_SPLIT_8 0x0040 /* Max 8 */
#define PCI_X_CMD_SPLIT_12 0x0050 /* Max 12 */
#define PCI_X_CMD_SPLIT_16 0x0060 /* Max 16 */
#define PCI_X_CMD_SPLIT_32 0x0070 /* Max 32 */
#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */
#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */
#define PCI_X_STATUS 4 /* PCI-X capabilities */
#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */
#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */
#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */
#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */
#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */
#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */
#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */
#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */
#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */
#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */
#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */
#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */
#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */
/* PCI Bridge Subsystem ID registers */
#define PCI_SSVID_VENDOR_ID 4 /* PCI-Bridge subsystem vendor id register */
#define PCI_SSVID_DEVICE_ID 6 /* PCI-Bridge subsystem device id register */
/* PCI Express capability registers */
#define PCI_EXP_FLAGS 2 /* Capabilities register */
#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */
#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */
#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */
#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */
#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */
#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */
#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */
#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */
#define PCI_EXP_TYPE_PCIE_BRIDGE 0x8 /* PCI/PCI-X to PCIE Bridge */
#define PCI_EXP_TYPE_RC_END 0x9 /* Root Complex Integrated Endpoint */
#define PCI_EXP_TYPE_RC_EC 0xa /* Root Complex Event Collector */
#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */
#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */
#define PCI_EXP_DEVCAP 4 /* Device capabilities */
#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
#define PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */
#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
#define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
#define PCI_EXP_DEVCTL 8 /* Device Control */
#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
#define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
#define PCI_EXP_DEVSTA 10 /* Device Status */
#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#define PCI_EXP_LNKCAP 12 /* Link Capabilities */
#define PCI_EXP_LNKCAP_SLS 0x0000000f /* Supported Link Speeds */
#define PCI_EXP_LNKCAP_MLW 0x000003f0 /* Maximum Link Width */
#define PCI_EXP_LNKCAP_ASPMS 0x00000c00 /* ASPM Support */
#define PCI_EXP_LNKCAP_L0SEL 0x00007000 /* L0s Exit Latency */
#define PCI_EXP_LNKCAP_L1EL 0x00038000 /* L1 Exit Latency */
#define PCI_EXP_LNKCAP_CLKPM 0x00040000 /* L1 Clock Power Management */
#define PCI_EXP_LNKCAP_SDERC 0x00080000 /* Surprise Down Error Reporting Capable */
#define PCI_EXP_LNKCAP_DLLLARC 0x00100000 /* Data Link Layer Link Active Reporting Capable */
#define PCI_EXP_LNKCAP_LBNC 0x00200000 /* Link Bandwidth Notification Capability */
#define PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */
#define PCI_EXP_LNKCTL 16 /* Link Control */
#define PCI_EXP_LNKCTL_ASPMC 0x0003 /* ASPM Control */
#define PCI_EXP_LNKCTL_RCB 0x0008 /* Read Completion Boundary */
#define PCI_EXP_LNKCTL_LD 0x0010 /* Link Disable */
#define PCI_EXP_LNKCTL_RL 0x0020 /* Retrain Link */
#define PCI_EXP_LNKCTL_CCC 0x0040 /* Common Clock Configuration */
#define PCI_EXP_LNKCTL_ES 0x0080 /* Extended Synch */
#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */
#define PCI_EXP_LNKCTL_HAWD 0x0200 /* Hardware Autonomous Width Disable */
#define PCI_EXP_LNKCTL_LBMIE 0x0400 /* Link Bandwidth Management Interrupt Enable */
#define PCI_EXP_LNKCTL_LABIE 0x0800 /* Lnk Autonomous Bandwidth Interrupt Enable */
#define PCI_EXP_LNKSTA 18 /* Link Status */
#define PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */
#define PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */
#define PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */
#define PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */
#define PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */
#define PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */
#define PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */
#define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
#define PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */
#define PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */
#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */
#define PCI_EXP_SLTCAP_ABP 0x00000001 /* Attention Button Present */
#define PCI_EXP_SLTCAP_PCP 0x00000002 /* Power Controller Present */
#define PCI_EXP_SLTCAP_MRLSP 0x00000004 /* MRL Sensor Present */
#define PCI_EXP_SLTCAP_AIP 0x00000008 /* Attention Indicator Present */
#define PCI_EXP_SLTCAP_PIP 0x00000010 /* Power Indicator Present */
#define PCI_EXP_SLTCAP_HPS 0x00000020 /* Hot-Plug Surprise */
#define PCI_EXP_SLTCAP_HPC 0x00000040 /* Hot-Plug Capable */
#define PCI_EXP_SLTCAP_SPLV 0x00007f80 /* Slot Power Limit Value */
#define PCI_EXP_SLTCAP_SPLS 0x00018000 /* Slot Power Limit Scale */
#define PCI_EXP_SLTCAP_EIP 0x00020000 /* Electromechanical Interlock Present */
#define PCI_EXP_SLTCAP_NCCS 0x00040000 /* No Command Completed Support */
#define PCI_EXP_SLTCAP_PSN 0xfff80000 /* Physical Slot Number */
#define PCI_EXP_SLTCTL 24 /* Slot Control */
#define PCI_EXP_SLTCTL_ABPE 0x0001 /* Attention Button Pressed Enable */
#define PCI_EXP_SLTCTL_PFDE 0x0002 /* Power Fault Detected Enable */
#define PCI_EXP_SLTCTL_MRLSCE 0x0004 /* MRL Sensor Changed Enable */
#define PCI_EXP_SLTCTL_PDCE 0x0008 /* Presence Detect Changed Enable */
#define PCI_EXP_SLTCTL_CCIE 0x0010 /* Command Completed Interrupt Enable */
#define PCI_EXP_SLTCTL_HPIE 0x0020 /* Hot-Plug Interrupt Enable */
#define PCI_EXP_SLTCTL_AIC 0x00c0 /* Attention Indicator Control */
#define PCI_EXP_SLTCTL_PIC 0x0300 /* Power Indicator Control */
#define PCI_EXP_SLTCTL_PCC 0x0400 /* Power Controller Control */
#define PCI_EXP_SLTCTL_EIC 0x0800 /* Electromechanical Interlock Control */
#define PCI_EXP_SLTCTL_DLLSCE 0x1000 /* Data Link Layer State Changed Enable */
#define PCI_EXP_SLTSTA 26 /* Slot Status */
#define PCI_EXP_SLTSTA_ABP 0x0001 /* Attention Button Pressed */
#define PCI_EXP_SLTSTA_PFD 0x0002 /* Power Fault Detected */
#define PCI_EXP_SLTSTA_MRLSC 0x0004 /* MRL Sensor Changed */
#define PCI_EXP_SLTSTA_PDC 0x0008 /* Presence Detect Changed */
#define PCI_EXP_SLTSTA_CC 0x0010 /* Command Completed */
#define PCI_EXP_SLTSTA_MRLSS 0x0020 /* MRL Sensor State */
#define PCI_EXP_SLTSTA_PDS 0x0040 /* Presence Detect State */
#define PCI_EXP_SLTSTA_EIS 0x0080 /* Electromechanical Interlock Status */
#define PCI_EXP_SLTSTA_DLLSC 0x0100 /* Data Link Layer State Changed */
#define PCI_EXP_RTCTL 28 /* Root Control */
#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */
#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */
#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */
#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */
#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
#define PCI_EXP_RTCAP 30 /* Root Capabilities */
#define PCI_EXP_RTSTA 32 /* Root Status */
#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
#define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
#define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */
#define PCI_EXP_DEVCAP2_LTR 0x800 /* Latency tolerance reporting */
#define PCI_EXP_OBFF_MASK 0xc0000 /* OBFF support mechanism */
#define PCI_EXP_OBFF_MSG 0x40000 /* New message signaling */
#define PCI_EXP_OBFF_WAKE 0x80000 /* Re-use WAKE# for OBFF */
#define PCI_EXP_DEVCTL2 40 /* Device Control 2 */
#define PCI_EXP_DEVCTL2_ARI 0x20 /* Alternative Routing-ID */
#define PCI_EXP_IDO_REQ_EN 0x100 /* ID-based ordering request enable */
#define PCI_EXP_IDO_CMP_EN 0x200 /* ID-based ordering completion enable */
#define PCI_EXP_LTR_EN 0x400 /* Latency tolerance reporting */
#define PCI_EXP_OBFF_MSGA_EN 0x2000 /* OBFF enable with Message type A */
#define PCI_EXP_OBFF_MSGB_EN 0x4000 /* OBFF enable with Message type B */
#define PCI_EXP_OBFF_WAKE_EN 0x6000 /* OBFF using WAKE# signaling */
#define PCI_EXP_LNKCTL2 48 /* Link Control 2 */
#define PCI_EXP_SLTCTL2 56 /* Slot Control 2 */
/* Extended Capabilities (PCI-X 2.0 and Express) */
#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff)
#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf)
#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc)
#define PCI_EXT_CAP_ID_ERR 1
#define PCI_EXT_CAP_ID_VC 2
#define PCI_EXT_CAP_ID_DSN 3
#define PCI_EXT_CAP_ID_PWR 4
#define PCI_EXT_CAP_ID_VNDR 11
#define PCI_EXT_CAP_ID_ACS 13
#define PCI_EXT_CAP_ID_ARI 14
#define PCI_EXT_CAP_ID_ATS 15
#define PCI_EXT_CAP_ID_SRIOV 16
#define PCI_EXT_CAP_ID_LTR 24
/* Advanced Error Reporting */
#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */
#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */
#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */
#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */
#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */
#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */
#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */
#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */
#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */
#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */
#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */
#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */
#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */
/* Same bits as above */
#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */
/* Same bits as above */
#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */
#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */
#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */
#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */
#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */
#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */
#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */
/* Same bits as above */
#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */
#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */
#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */
#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */
#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */
#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */
#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */
#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */
/* Correctable Err Reporting Enable */
#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001
/* Non-fatal Err Reporting Enable */
#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002
/* Fatal Err Reporting Enable */
#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004
#define PCI_ERR_ROOT_STATUS 48
#define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */
/* Multi ERR_COR Received */
#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002
/* ERR_FATAL/NONFATAL Recevied */
#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004
/* Multi ERR_FATAL/NONFATAL Recevied */
#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008
#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */
#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */
#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */
#define PCI_ERR_ROOT_ERR_SRC 52 /* Error Source Identification */
/* Virtual Channel */
#define PCI_VC_PORT_REG1 4
#define PCI_VC_PORT_REG2 8
#define PCI_VC_PORT_CTRL 12
#define PCI_VC_PORT_STATUS 14
#define PCI_VC_RES_CAP 16
#define PCI_VC_RES_CTRL 20
#define PCI_VC_RES_STATUS 26
/* Power Budgeting */
#define PCI_PWR_DSR 4 /* Data Select Register */
#define PCI_PWR_DATA 8 /* Data Register */
#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */
#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */
#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */
#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */
#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */
#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */
#define PCI_PWR_CAP 12 /* Capability */
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
/*
* Hypertransport sub capability types
*
* Unfortunately there are both 3 bit and 5 bit capability types defined
* in the HT spec, catering for that is a little messy. You probably don't
* want to use these directly, just use pci_find_ht_capability() and it
* will do the right thing for you.
*/
#define HT_3BIT_CAP_MASK 0xE0
#define HT_CAPTYPE_SLAVE 0x00 /* Slave/Primary link configuration */
#define HT_CAPTYPE_HOST 0x20 /* Host/Secondary link configuration */
#define HT_5BIT_CAP_MASK 0xF8
#define HT_CAPTYPE_IRQ 0x80 /* IRQ Configuration */
#define HT_CAPTYPE_REMAPPING_40 0xA0 /* 40 bit address remapping */
#define HT_CAPTYPE_REMAPPING_64 0xA2 /* 64 bit address remapping */
#define HT_CAPTYPE_UNITID_CLUMP 0x90 /* Unit ID clumping */
#define HT_CAPTYPE_EXTCONF 0x98 /* Extended Configuration Space Access */
#define HT_CAPTYPE_MSI_MAPPING 0xA8 /* MSI Mapping Capability */
#define HT_MSI_FLAGS 0x02 /* Offset to flags */
#define HT_MSI_FLAGS_ENABLE 0x1 /* Mapping enable */
#define HT_MSI_FLAGS_FIXED 0x2 /* Fixed mapping only */
#define HT_MSI_FIXED_ADDR 0x00000000FEE00000ULL /* Fixed addr */
#define HT_MSI_ADDR_LO 0x04 /* Offset to low addr bits */
#define HT_MSI_ADDR_LO_MASK 0xFFF00000 /* Low address bit mask */
#define HT_MSI_ADDR_HI 0x08 /* Offset to high addr bits */
#define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */
#define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */
#define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */
#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */
#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */
/* Alternative Routing-ID Interpretation */
#define PCI_ARI_CAP 0x04 /* ARI Capability Register */
#define PCI_ARI_CAP_MFVC 0x0001 /* MFVC Function Groups Capability */
#define PCI_ARI_CAP_ACS 0x0002 /* ACS Function Groups Capability */
#define PCI_ARI_CAP_NFN(x) (((x) >> 8) & 0xff) /* Next Function Number */
#define PCI_ARI_CTRL 0x06 /* ARI Control Register */
#define PCI_ARI_CTRL_MFVC 0x0001 /* MFVC Function Groups Enable */
#define PCI_ARI_CTRL_ACS 0x0002 /* ACS Function Groups Enable */
#define PCI_ARI_CTRL_FG(x) (((x) >> 4) & 7) /* Function Group */
/* Address Translation Service */
#define PCI_ATS_CAP 0x04 /* ATS Capability Register */
#define PCI_ATS_CAP_QDEP(x) ((x) & 0x1f) /* Invalidate Queue Depth */
#define PCI_ATS_MAX_QDEP 32 /* Max Invalidate Queue Depth */
#define PCI_ATS_CTRL 0x06 /* ATS Control Register */
#define PCI_ATS_CTRL_ENABLE 0x8000 /* ATS Enable */
#define PCI_ATS_CTRL_STU(x) ((x) & 0x1f) /* Smallest Translation Unit */
#define PCI_ATS_MIN_STU 12 /* shift of minimum STU block */
/* Single Root I/O Virtualization */
#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */
#define PCI_SRIOV_CAP_VFM 0x01 /* VF Migration Capable */
#define PCI_SRIOV_CAP_INTR(x) ((x) >> 21) /* Interrupt Message Number */
#define PCI_SRIOV_CTRL 0x08 /* SR-IOV Control */
#define PCI_SRIOV_CTRL_VFE 0x01 /* VF Enable */
#define PCI_SRIOV_CTRL_VFM 0x02 /* VF Migration Enable */
#define PCI_SRIOV_CTRL_INTR 0x04 /* VF Migration Interrupt Enable */
#define PCI_SRIOV_CTRL_MSE 0x08 /* VF Memory Space Enable */
#define PCI_SRIOV_CTRL_ARI 0x10 /* ARI Capable Hierarchy */
#define PCI_SRIOV_STATUS 0x0a /* SR-IOV Status */
#define PCI_SRIOV_STATUS_VFM 0x01 /* VF Migration Status */
#define PCI_SRIOV_INITIAL_VF 0x0c /* Initial VFs */
#define PCI_SRIOV_TOTAL_VF 0x0e /* Total VFs */
#define PCI_SRIOV_NUM_VF 0x10 /* Number of VFs */
#define PCI_SRIOV_FUNC_LINK 0x12 /* Function Dependency Link */
#define PCI_SRIOV_VF_OFFSET 0x14 /* First VF Offset */
#define PCI_SRIOV_VF_STRIDE 0x16 /* Following VF Stride */
#define PCI_SRIOV_VF_DID 0x1a /* VF Device ID */
#define PCI_SRIOV_SUP_PGSIZE 0x1c /* Supported Page Sizes */
#define PCI_SRIOV_SYS_PGSIZE 0x20 /* System Page Size */
#define PCI_SRIOV_BAR 0x24 /* VF BAR0 */
#define PCI_SRIOV_NUM_BARS 6 /* Number of VF BARs */
#define PCI_SRIOV_VFM 0x3c /* VF Migration State Array Offset*/
#define PCI_SRIOV_VFM_BIR(x) ((x) & 7) /* State BIR */
#define PCI_SRIOV_VFM_OFFSET(x) ((x) & ~7) /* State Offset */
#define PCI_SRIOV_VFM_UA 0x0 /* Inactive.Unavailable */
#define PCI_SRIOV_VFM_MI 0x1 /* Dormant.MigrateIn */
#define PCI_SRIOV_VFM_MO 0x2 /* Active.MigrateOut */
#define PCI_SRIOV_VFM_AV 0x3 /* Active.Available */
#define PCI_LTR_MAX_SNOOP_LAT 0x4
#define PCI_LTR_MAX_NOSNOOP_LAT 0x6
#define PCI_LTR_VALUE_MASK 0x000003ff
#define PCI_LTR_SCALE_MASK 0x00001c00
#define PCI_LTR_SCALE_SHIFT 10
/* Access Control Service */
#define PCI_ACS_CAP 0x04 /* ACS Capability Register */
#define PCI_ACS_SV 0x01 /* Source Validation */
#define PCI_ACS_TB 0x02 /* Translation Blocking */
#define PCI_ACS_RR 0x04 /* P2P Request Redirect */
#define PCI_ACS_CR 0x08 /* P2P Completion Redirect */
#define PCI_ACS_UF 0x10 /* Upstream Forwarding */
#define PCI_ACS_EC 0x20 /* P2P Egress Control */
#define PCI_ACS_DT 0x40 /* Direct Translated P2P */
#define PCI_ACS_CTRL 0x06 /* ACS Control Register */
#define PCI_ACS_EGRESS_CTL_V 0x08 /* ACS Egress Control Vector */
#endif /* LINUX_PCI_REGS_H */

143
include/hw/pci/pcie.h Normal file
View file

@ -0,0 +1,143 @@
/*
* pcie.h
*
* Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_PCIE_H
#define QEMU_PCIE_H
#include "hw/hw.h"
#include "hw/pci/pci_regs.h"
#include "hw/pci/pcie_regs.h"
#include "hw/pci/pcie_aer.h"
typedef enum {
/* for attention and power indicator */
PCI_EXP_HP_IND_RESERVED = PCI_EXP_SLTCTL_IND_RESERVED,
PCI_EXP_HP_IND_ON = PCI_EXP_SLTCTL_IND_ON,
PCI_EXP_HP_IND_BLINK = PCI_EXP_SLTCTL_IND_BLINK,
PCI_EXP_HP_IND_OFF = PCI_EXP_SLTCTL_IND_OFF,
} PCIExpressIndicator;
typedef enum {
/* these bits must match the bits in Slot Control/Status registers.
* PCI_EXP_HP_EV_xxx = PCI_EXP_SLTCTL_xxxE = PCI_EXP_SLTSTA_xxx
*
* Not all the bits of slot control register match with the ones of
* slot status. Not some bits of slot status register is used to
* show status, not to report event occurrence.
* So such bits must be masked out when checking the software
* notification condition.
*/
PCI_EXP_HP_EV_ABP = PCI_EXP_SLTCTL_ABPE,
/* attention button pressed */
PCI_EXP_HP_EV_PDC = PCI_EXP_SLTCTL_PDCE,
/* presence detect changed */
PCI_EXP_HP_EV_CCI = PCI_EXP_SLTCTL_CCIE,
/* command completed */
PCI_EXP_HP_EV_SUPPORTED = PCI_EXP_HP_EV_ABP |
PCI_EXP_HP_EV_PDC |
PCI_EXP_HP_EV_CCI,
/* supported event mask */
/* events not listed aren't supported */
} PCIExpressHotPlugEvent;
struct PCIExpressDevice {
/* Offset of express capability in config space */
uint8_t exp_cap;
/* SLOT */
unsigned int hpev_intx; /* INTx for hot plug event (0-3:INT[A-D]#)
* default is 0 = INTA#
* If the chip wants to use other interrupt
* line, initialize this member with the
* desired number.
* If the chip dynamically changes this member,
* also initialize it when loaded as
* appropreately.
*/
bool hpev_notified; /* Logical AND of conditions for hot plug event.
Following 6.7.3.4:
Software Notification of Hot-Plug Events, an interrupt
is sent whenever the logical and of these conditions
transitions from false to true. */
/* AER */
uint16_t aer_cap;
PCIEAERLog aer_log;
unsigned int aer_intx; /* INTx for error reporting
* default is 0 = INTA#
* If the chip wants to use other interrupt
* line, initialize this member with the
* desired number.
* If the chip dynamically changes this member,
* also initialize it when loaded as
* appropreately.
*/
};
/* PCI express capability helper functions */
int pcie_cap_init(PCIDevice *dev, uint8_t offset, uint8_t type, uint8_t port);
int pcie_endpoint_cap_init(PCIDevice *dev, uint8_t offset);
void pcie_cap_exit(PCIDevice *dev);
uint8_t pcie_cap_get_type(const PCIDevice *dev);
void pcie_cap_flags_set_vector(PCIDevice *dev, uint8_t vector);
uint8_t pcie_cap_flags_get_vector(PCIDevice *dev);
void pcie_cap_deverr_init(PCIDevice *dev);
void pcie_cap_deverr_reset(PCIDevice *dev);
void pcie_cap_slot_init(PCIDevice *dev, uint16_t slot);
void pcie_cap_slot_reset(PCIDevice *dev);
void pcie_cap_slot_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);
int pcie_cap_slot_post_load(void *opaque, int version_id);
void pcie_cap_slot_push_attention_button(PCIDevice *dev);
void pcie_cap_root_init(PCIDevice *dev);
void pcie_cap_root_reset(PCIDevice *dev);
void pcie_cap_flr_init(PCIDevice *dev);
void pcie_cap_flr_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);
void pcie_cap_ari_init(PCIDevice *dev);
void pcie_cap_ari_reset(PCIDevice *dev);
bool pcie_cap_is_ari_enabled(const PCIDevice *dev);
/* PCI express extended capability helper functions */
uint16_t pcie_find_capability(PCIDevice *dev, uint16_t cap_id);
void pcie_add_capability(PCIDevice *dev,
uint16_t cap_id, uint8_t cap_ver,
uint16_t offset, uint16_t size);
void pcie_ari_init(PCIDevice *dev, uint16_t offset, uint16_t nextfn);
extern const VMStateDescription vmstate_pcie_device;
#define VMSTATE_PCIE_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(PCIDevice), \
.vmsd = &vmstate_pcie_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, PCIDevice), \
}
#endif /* QEMU_PCIE_H */

106
include/hw/pci/pcie_aer.h Normal file
View file

@ -0,0 +1,106 @@
/*
* pcie_aer.h
*
* Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_PCIE_AER_H
#define QEMU_PCIE_AER_H
#include "hw/hw.h"
/* definitions which PCIExpressDevice uses */
/* AER log */
struct PCIEAERLog {
/* This structure is saved/loaded.
So explicitly size them instead of unsigned int */
/* the number of currently recorded log in log member */
uint16_t log_num;
/*
* The maximum number of the log. Errors can be logged up to this.
*
* This is configurable property.
* The specified value will be clipped down to PCIE_AER_LOG_MAX_LIMIT
* to avoid unreasonable memory usage.
* I bet that 128 log size would be big enough, otherwise too many errors
* for system to function normaly. But could consecutive errors occur?
*/
#define PCIE_AER_LOG_MAX_DEFAULT 8
#define PCIE_AER_LOG_MAX_LIMIT 128
#define PCIE_AER_LOG_MAX_UNSET 0xffff
uint16_t log_max;
/* Error log. log_max-sized array */
PCIEAERErr *log;
};
/* aer error message: error signaling message has only error sevirity and
source id. See 2.2.8.3 error signaling messages */
struct PCIEAERMsg {
/*
* PCI_ERR_ROOT_CMD_{COR, NONFATAL, FATAL}_EN
* = PCI_EXP_DEVCTL_{CERE, NFERE, FERE}
*/
uint32_t severity;
uint16_t source_id; /* bdf */
};
static inline bool
pcie_aer_msg_is_uncor(const PCIEAERMsg *msg)
{
return msg->severity == PCI_ERR_ROOT_CMD_NONFATAL_EN ||
msg->severity == PCI_ERR_ROOT_CMD_FATAL_EN;
}
/* error */
struct PCIEAERErr {
uint32_t status; /* error status bits */
uint16_t source_id; /* bdf */
#define PCIE_AER_ERR_IS_CORRECTABLE 0x1 /* correctable/uncorrectable */
#define PCIE_AER_ERR_MAYBE_ADVISORY 0x2 /* maybe advisory non-fatal */
#define PCIE_AER_ERR_HEADER_VALID 0x4 /* TLP header is logged */
#define PCIE_AER_ERR_TLP_PREFIX_PRESENT 0x8 /* TLP Prefix is logged */
uint16_t flags;
uint32_t header[4]; /* TLP header */
uint32_t prefix[4]; /* TLP header prefix */
};
extern const VMStateDescription vmstate_pcie_aer_log;
int pcie_aer_init(PCIDevice *dev, uint16_t offset);
void pcie_aer_exit(PCIDevice *dev);
void pcie_aer_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len);
/* aer root port */
void pcie_aer_root_set_vector(PCIDevice *dev, unsigned int vector);
void pcie_aer_root_init(PCIDevice *dev);
void pcie_aer_root_reset(PCIDevice *dev);
void pcie_aer_root_write_config(PCIDevice *dev,
uint32_t addr, uint32_t val, int len,
uint32_t root_cmd_prev);
/* error injection */
int pcie_aer_inject_error(PCIDevice *dev, const PCIEAERErr *err);
#endif /* QEMU_PCIE_AER_H */

View file

@ -0,0 +1,54 @@
/*
* pcie_host.h
*
* Copyright (c) 2009 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program 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 General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PCIE_HOST_H
#define PCIE_HOST_H
#include "hw/pci/pci_host.h"
#include "exec/memory.h"
#define TYPE_PCIE_HOST_BRIDGE "pcie-host-bridge"
#define PCIE_HOST_BRIDGE(obj) \
OBJECT_CHECK(PCIExpressHost, (obj), TYPE_PCIE_HOST_BRIDGE)
struct PCIExpressHost {
PCIHostState pci;
/* express part */
/* base address where MMCONFIG area is mapped. */
hwaddr base_addr;
/* the size of MMCONFIG area. It's host bridge dependent */
hwaddr size;
/* MMCONFIG mmio area */
MemoryRegion mmio;
};
int pcie_host_init(PCIExpressHost *e);
void pcie_host_mmcfg_unmap(PCIExpressHost *e);
void pcie_host_mmcfg_map(PCIExpressHost *e, hwaddr addr, uint32_t size);
void pcie_host_mmcfg_update(PCIExpressHost *e,
int enable,
hwaddr addr,
uint32_t size);
#endif /* PCIE_HOST_H */

View file

@ -0,0 +1,51 @@
/*
* pcie_port.h
*
* Copyright (c) 2010 Isaku Yamahata <yamahata at valinux co jp>
* VA Linux Systems Japan K.K.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef QEMU_PCIE_PORT_H
#define QEMU_PCIE_PORT_H
#include "hw/pci/pci_bridge.h"
#include "hw/pci/pci_bus.h"
struct PCIEPort {
PCIBridge br;
/* pci express switch port */
uint8_t port;
};
void pcie_port_init_reg(PCIDevice *d);
struct PCIESlot {
PCIEPort port;
/* pci express switch port with slot */
uint8_t chassis;
uint16_t slot;
QLIST_ENTRY(PCIESlot) next;
};
void pcie_chassis_create(uint8_t chassis_number);
void pcie_main_chassis_create(void);
PCIESlot *pcie_chassis_find_slot(uint8_t chassis, uint16_t slot);
int pcie_chassis_add_slot(struct PCIESlot *slot);
void pcie_chassis_del_slot(PCIESlot *s);
#endif /* QEMU_PCIE_PORT_H */

156
include/hw/pci/pcie_regs.h Normal file
View file

@ -0,0 +1,156 @@
/*
* constants for pcie configurations space from pci express spec.
*
* TODO:
* Those constants and macros should go to Linux pci_regs.h
* Once they're merged, they will go away.
*/
#ifndef QEMU_PCIE_REGS_H
#define QEMU_PCIE_REGS_H
/* express capability */
#define PCI_EXP_VER2_SIZEOF 0x3c /* express capability of ver. 2 */
#define PCI_EXT_CAP_VER_SHIFT 16
#define PCI_EXT_CAP_NEXT_SHIFT 20
#define PCI_EXT_CAP_NEXT_MASK (0xffc << PCI_EXT_CAP_NEXT_SHIFT)
#define PCI_EXT_CAP(id, ver, next) \
((id) | \
((ver) << PCI_EXT_CAP_VER_SHIFT) | \
((next) << PCI_EXT_CAP_NEXT_SHIFT))
#define PCI_EXT_CAP_ALIGN 4
#define PCI_EXT_CAP_ALIGNUP(x) \
(((x) + PCI_EXT_CAP_ALIGN - 1) & ~(PCI_EXT_CAP_ALIGN - 1))
/* PCI_EXP_FLAGS */
#define PCI_EXP_FLAGS_VER2 2 /* for now, supports only ver. 2 */
#define PCI_EXP_FLAGS_IRQ_SHIFT (ffs(PCI_EXP_FLAGS_IRQ) - 1)
#define PCI_EXP_FLAGS_TYPE_SHIFT (ffs(PCI_EXP_FLAGS_TYPE) - 1)
/* PCI_EXP_LINK{CAP, STA} */
/* link speed */
#define PCI_EXP_LNK_LS_25 1
#define PCI_EXP_LNK_MLW_SHIFT (ffs(PCI_EXP_LNKCAP_MLW) - 1)
#define PCI_EXP_LNK_MLW_1 (1 << PCI_EXP_LNK_MLW_SHIFT)
/* PCI_EXP_LINKCAP */
#define PCI_EXP_LNKCAP_ASPMS_SHIFT (ffs(PCI_EXP_LNKCAP_ASPMS) - 1)
#define PCI_EXP_LNKCAP_ASPMS_0S (1 << PCI_EXP_LNKCAP_ASPMS_SHIFT)
#define PCI_EXP_LNKCAP_PN_SHIFT (ffs(PCI_EXP_LNKCAP_PN) - 1)
#define PCI_EXP_SLTCAP_PSN_SHIFT (ffs(PCI_EXP_SLTCAP_PSN) - 1)
#define PCI_EXP_SLTCTL_IND_RESERVED 0x0
#define PCI_EXP_SLTCTL_IND_ON 0x1
#define PCI_EXP_SLTCTL_IND_BLINK 0x2
#define PCI_EXP_SLTCTL_IND_OFF 0x3
#define PCI_EXP_SLTCTL_AIC_SHIFT (ffs(PCI_EXP_SLTCTL_AIC) - 1)
#define PCI_EXP_SLTCTL_AIC_OFF \
(PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_AIC_SHIFT)
#define PCI_EXP_SLTCTL_PIC_SHIFT (ffs(PCI_EXP_SLTCTL_PIC) - 1)
#define PCI_EXP_SLTCTL_PIC_OFF \
(PCI_EXP_SLTCTL_IND_OFF << PCI_EXP_SLTCTL_PIC_SHIFT)
#define PCI_EXP_SLTCTL_SUPPORTED \
(PCI_EXP_SLTCTL_ABPE | \
PCI_EXP_SLTCTL_PDCE | \
PCI_EXP_SLTCTL_CCIE | \
PCI_EXP_SLTCTL_HPIE | \
PCI_EXP_SLTCTL_AIC | \
PCI_EXP_SLTCTL_PCC | \
PCI_EXP_SLTCTL_EIC)
#define PCI_EXP_DEVCAP2_EFF 0x100000
#define PCI_EXP_DEVCAP2_EETLPP 0x200000
#define PCI_EXP_DEVCTL2_EETLPPB 0x80
/* ARI */
#define PCI_ARI_VER 1
#define PCI_ARI_SIZEOF 8
/* AER */
#define PCI_ERR_VER 2
#define PCI_ERR_SIZEOF 0x48
#define PCI_ERR_UNC_SDN 0x00000020 /* surprise down */
#define PCI_ERR_UNC_ACSV 0x00200000 /* ACS Violation */
#define PCI_ERR_UNC_INTN 0x00400000 /* Internal Error */
#define PCI_ERR_UNC_MCBTLP 0x00800000 /* MC Blcoked TLP */
#define PCI_ERR_UNC_ATOP_EBLOCKED 0x01000000 /* atomic op egress blocked */
#define PCI_ERR_UNC_TLP_PRF_BLOCKED 0x02000000 /* TLP Prefix Blocked */
#define PCI_ERR_COR_ADV_NONFATAL 0x00002000 /* Advisory Non-Fatal */
#define PCI_ERR_COR_INTERNAL 0x00004000 /* Corrected Internal */
#define PCI_ERR_COR_HL_OVERFLOW 0x00008000 /* Header Long Overflow */
#define PCI_ERR_CAP_FEP_MASK 0x0000001f
#define PCI_ERR_CAP_MHRC 0x00000200
#define PCI_ERR_CAP_MHRE 0x00000400
#define PCI_ERR_CAP_TLP 0x00000800
#define PCI_ERR_HEADER_LOG_SIZE 16
#define PCI_ERR_TLP_PREFIX_LOG 0x38
#define PCI_ERR_TLP_PREFIX_LOG_SIZE 16
#define PCI_SEC_STATUS_RCV_SYSTEM_ERROR 0x4000
/* aer root error command/status */
#define PCI_ERR_ROOT_CMD_EN_MASK (PCI_ERR_ROOT_CMD_COR_EN | \
PCI_ERR_ROOT_CMD_NONFATAL_EN | \
PCI_ERR_ROOT_CMD_FATAL_EN)
#define PCI_ERR_ROOT_IRQ_MAX 32
#define PCI_ERR_ROOT_IRQ 0xf8000000
#define PCI_ERR_ROOT_IRQ_SHIFT (ffs(PCI_ERR_ROOT_IRQ) - 1)
#define PCI_ERR_ROOT_STATUS_REPORT_MASK (PCI_ERR_ROOT_COR_RCV | \
PCI_ERR_ROOT_MULTI_COR_RCV | \
PCI_ERR_ROOT_UNCOR_RCV | \
PCI_ERR_ROOT_MULTI_UNCOR_RCV | \
PCI_ERR_ROOT_FIRST_FATAL | \
PCI_ERR_ROOT_NONFATAL_RCV | \
PCI_ERR_ROOT_FATAL_RCV)
#define PCI_ERR_UNC_SUPPORTED (PCI_ERR_UNC_DLP | \
PCI_ERR_UNC_SDN | \
PCI_ERR_UNC_POISON_TLP | \
PCI_ERR_UNC_FCP | \
PCI_ERR_UNC_COMP_TIME | \
PCI_ERR_UNC_COMP_ABORT | \
PCI_ERR_UNC_UNX_COMP | \
PCI_ERR_UNC_RX_OVER | \
PCI_ERR_UNC_MALF_TLP | \
PCI_ERR_UNC_ECRC | \
PCI_ERR_UNC_UNSUP | \
PCI_ERR_UNC_ACSV | \
PCI_ERR_UNC_INTN | \
PCI_ERR_UNC_MCBTLP | \
PCI_ERR_UNC_ATOP_EBLOCKED | \
PCI_ERR_UNC_TLP_PRF_BLOCKED)
#define PCI_ERR_UNC_SEVERITY_DEFAULT (PCI_ERR_UNC_DLP | \
PCI_ERR_UNC_SDN | \
PCI_ERR_UNC_FCP | \
PCI_ERR_UNC_RX_OVER | \
PCI_ERR_UNC_MALF_TLP | \
PCI_ERR_UNC_INTN)
#define PCI_ERR_COR_SUPPORTED (PCI_ERR_COR_RCVR | \
PCI_ERR_COR_BAD_TLP | \
PCI_ERR_COR_BAD_DLLP | \
PCI_ERR_COR_REP_ROLL | \
PCI_ERR_COR_REP_TIMER | \
PCI_ERR_COR_ADV_NONFATAL | \
PCI_ERR_COR_INTERNAL | \
PCI_ERR_COR_HL_OVERFLOW)
#define PCI_ERR_COR_MASK_DEFAULT (PCI_ERR_COR_ADV_NONFATAL | \
PCI_ERR_COR_INTERNAL | \
PCI_ERR_COR_HL_OVERFLOW)
#endif /* QEMU_PCIE_REGS_H */

48
include/hw/pci/shpc.h Normal file
View file

@ -0,0 +1,48 @@
#ifndef SHPC_H
#define SHPC_H
#include "qemu-common.h"
#include "exec/memory.h"
#include "migration/vmstate.h"
struct SHPCDevice {
/* Capability offset in device's config space */
int cap;
/* # of hot-pluggable slots */
int nslots;
/* SHPC WRS: working register set */
uint8_t *config;
/* Used to enable checks on load. Note that writable bits are
* never checked even if set in cmask. */
uint8_t *cmask;
/* Used to implement R/W bytes */
uint8_t *wmask;
/* Used to implement RW1C(Write 1 to Clear) bytes */
uint8_t *w1cmask;
/* MMIO for the SHPC BAR */
MemoryRegion mmio;
/* Bus controlled by this SHPC */
PCIBus *sec_bus;
/* MSI already requested for this event */
int msi_requested;
};
void shpc_reset(PCIDevice *d);
int shpc_bar_size(PCIDevice *dev);
int shpc_init(PCIDevice *dev, PCIBus *sec_bus, MemoryRegion *bar, unsigned off);
void shpc_cleanup(PCIDevice *dev, MemoryRegion *bar);
void shpc_cap_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int len);
extern VMStateInfo shpc_vmstate_info;
#define SHPC_VMSTATE(_field, _type) \
VMSTATE_BUFFER_UNSAFE_INFO(_field, _type, 0, shpc_vmstate_info, 0)
#endif

View file

@ -0,0 +1,11 @@
#ifndef PCI_SLOTID_CAP_H
#define PCI_SLOTID_CAP_H
#include "qemu-common.h"
int slotid_cap_init(PCIDevice *dev, int nslots,
uint8_t chassis,
unsigned offset);
void slotid_cap_cleanup(PCIDevice *dev);
#endif

56
include/hw/pcmcia.h Normal file
View file

@ -0,0 +1,56 @@
#ifndef HW_PCMCIA_H
#define HW_PCMCIA_H 1
/* PCMCIA/Cardbus */
#include "qemu-common.h"
typedef struct {
qemu_irq irq;
int attached;
const char *slot_string;
const char *card_string;
} PCMCIASocket;
void pcmcia_socket_register(PCMCIASocket *socket);
void pcmcia_socket_unregister(PCMCIASocket *socket);
void pcmcia_info(Monitor *mon, const QDict *qdict);
struct PCMCIACardState {
void *state;
PCMCIASocket *slot;
int (*attach)(void *state);
int (*detach)(void *state);
const uint8_t *cis;
int cis_len;
/* Only valid if attached */
uint8_t (*attr_read)(void *state, uint32_t address);
void (*attr_write)(void *state, uint32_t address, uint8_t value);
uint16_t (*common_read)(void *state, uint32_t address);
void (*common_write)(void *state, uint32_t address, uint16_t value);
uint16_t (*io_read)(void *state, uint32_t address);
void (*io_write)(void *state, uint32_t address, uint16_t value);
};
#define CISTPL_DEVICE 0x01 /* 5V Device Information Tuple */
#define CISTPL_NO_LINK 0x14 /* No Link Tuple */
#define CISTPL_VERS_1 0x15 /* Level 1 Version Tuple */
#define CISTPL_JEDEC_C 0x18 /* JEDEC ID Tuple */
#define CISTPL_JEDEC_A 0x19 /* JEDEC ID Tuple */
#define CISTPL_CONFIG 0x1a /* Configuration Tuple */
#define CISTPL_CFTABLE_ENTRY 0x1b /* 16-bit PCCard Configuration */
#define CISTPL_DEVICE_OC 0x1c /* Additional Device Information */
#define CISTPL_DEVICE_OA 0x1d /* Additional Device Information */
#define CISTPL_DEVICE_GEO 0x1e /* Additional Device Information */
#define CISTPL_DEVICE_GEO_A 0x1f /* Additional Device Information */
#define CISTPL_MANFID 0x20 /* Manufacture ID Tuple */
#define CISTPL_FUNCID 0x21 /* Function ID Tuple */
#define CISTPL_FUNCE 0x22 /* Function Extension Tuple */
#define CISTPL_END 0xff /* Tuple End */
#define CISTPL_ENDMARK 0xff
/* dscm1xxxx.c */
PCMCIACardState *dscm1xxxx_init(DriveInfo *bdrv);
#endif

View file

@ -0,0 +1,48 @@
/*
* Copyright (c) 2009 Laurent Vivier
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef HW_MAC_DBDMA_H
#define HW_MAC_DBDMA_H 1
#include "exec/memory.h"
typedef struct DBDMA_io DBDMA_io;
typedef void (*DBDMA_flush)(DBDMA_io *io);
typedef void (*DBDMA_rw)(DBDMA_io *io);
typedef void (*DBDMA_end)(DBDMA_io *io);
struct DBDMA_io {
void *opaque;
void *channel;
hwaddr addr;
int len;
int is_last;
int is_dma_out;
DBDMA_end dma_end;
};
void DBDMA_register_channel(void *dbdma, int nchan, qemu_irq irq,
DBDMA_rw rw, DBDMA_flush flush,
void *opaque);
void* DBDMA_init (MemoryRegion **dbdma_mem);
#endif

18
include/hw/ppc/openpic.h Normal file
View file

@ -0,0 +1,18 @@
#if !defined(__OPENPIC_H__)
#define __OPENPIC_H__
/* OpenPIC have 5 outputs per CPU connected and one IRQ out single output */
enum {
OPENPIC_OUTPUT_INT = 0, /* IRQ */
OPENPIC_OUTPUT_CINT, /* critical IRQ */
OPENPIC_OUTPUT_MCK, /* Machine check event */
OPENPIC_OUTPUT_DEBUG, /* Inconditional debug event */
OPENPIC_OUTPUT_RESET, /* Core reset event */
OPENPIC_OUTPUT_NB,
};
#define OPENPIC_MODEL_RAVEN 0
#define OPENPIC_MODEL_FSL_MPIC_20 1
#define OPENPIC_MODEL_FSL_MPIC_42 2
#endif /* __OPENPIC_H__ */

99
include/hw/ppc/ppc.h Normal file
View file

@ -0,0 +1,99 @@
#ifndef HW_PPC_H
#define HW_PPC_H 1
void ppc_set_irq(PowerPCCPU *cpu, int n_IRQ, int level);
/* PowerPC hardware exceptions management helpers */
typedef void (*clk_setup_cb)(void *opaque, uint32_t freq);
typedef struct clk_setup_t clk_setup_t;
struct clk_setup_t {
clk_setup_cb cb;
void *opaque;
};
static inline void clk_setup (clk_setup_t *clk, uint32_t freq)
{
if (clk->cb != NULL)
(*clk->cb)(clk->opaque, freq);
}
struct ppc_tb_t {
/* Time base management */
int64_t tb_offset; /* Compensation */
int64_t atb_offset; /* Compensation */
uint32_t tb_freq; /* TB frequency */
/* Decrementer management */
uint64_t decr_next; /* Tick for next decr interrupt */
uint32_t decr_freq; /* decrementer frequency */
struct QEMUTimer *decr_timer;
/* Hypervisor decrementer management */
uint64_t hdecr_next; /* Tick for next hdecr interrupt */
struct QEMUTimer *hdecr_timer;
uint64_t purr_load;
uint64_t purr_start;
void *opaque;
uint32_t flags;
};
/* PPC Timers flags */
#define PPC_TIMER_BOOKE (1 << 0) /* Enable Booke support */
#define PPC_TIMER_E500 (1 << 1) /* Enable e500 support */
#define PPC_DECR_UNDERFLOW_TRIGGERED (1 << 2) /* Decr interrupt triggered when
* the most significant bit
* changes from 0 to 1.
*/
#define PPC_DECR_ZERO_TRIGGERED (1 << 3) /* Decr interrupt triggered when
* the decrementer reaches zero.
*/
uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset);
clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq);
/* Embedded PowerPC DCR management */
typedef uint32_t (*dcr_read_cb)(void *opaque, int dcrn);
typedef void (*dcr_write_cb)(void *opaque, int dcrn, uint32_t val);
int ppc_dcr_init (CPUPPCState *env, int (*dcr_read_error)(int dcrn),
int (*dcr_write_error)(int dcrn));
int ppc_dcr_register (CPUPPCState *env, int dcrn, void *opaque,
dcr_read_cb drc_read, dcr_write_cb dcr_write);
clk_setup_cb ppc_40x_timers_init (CPUPPCState *env, uint32_t freq,
unsigned int decr_excp);
/* Embedded PowerPC reset */
void ppc40x_core_reset(PowerPCCPU *cpu);
void ppc40x_chip_reset(PowerPCCPU *cpu);
void ppc40x_system_reset(PowerPCCPU *cpu);
void PREP_debug_write (void *opaque, uint32_t addr, uint32_t val);
extern CPUWriteMemoryFunc * const PPC_io_write[];
extern CPUReadMemoryFunc * const PPC_io_read[];
void PPC_debug_write (void *opaque, uint32_t addr, uint32_t val);
void ppc40x_irq_init (CPUPPCState *env);
void ppce500_irq_init (CPUPPCState *env);
void ppc6xx_irq_init (CPUPPCState *env);
void ppc970_irq_init (CPUPPCState *env);
void ppcPOWER7_irq_init (CPUPPCState *env);
void ppce500_set_mpic_proxy(bool enabled);
/* PPC machines for OpenBIOS */
enum {
ARCH_PREP = 0,
ARCH_MAC99,
ARCH_HEATHROW,
ARCH_MAC99_U3,
};
#define FW_CFG_PPC_WIDTH (FW_CFG_ARCH_LOCAL + 0x00)
#define FW_CFG_PPC_HEIGHT (FW_CFG_ARCH_LOCAL + 0x01)
#define FW_CFG_PPC_DEPTH (FW_CFG_ARCH_LOCAL + 0x02)
#define FW_CFG_PPC_TBFREQ (FW_CFG_ARCH_LOCAL + 0x03)
#define FW_CFG_PPC_IS_KVM (FW_CFG_ARCH_LOCAL + 0x05)
#define FW_CFG_PPC_KVM_HC (FW_CFG_ARCH_LOCAL + 0x06)
#define FW_CFG_PPC_KVM_PID (FW_CFG_ARCH_LOCAL + 0x07)
#define PPC_SERIAL_MM_BAUDBASE 399193
/* ppc_booke.c */
void ppc_booke_timers_init(PowerPCCPU *cpu, uint32_t freq, uint32_t flags);
#endif

64
include/hw/ppc/ppc4xx.h Normal file
View file

@ -0,0 +1,64 @@
/*
* QEMU PowerPC 4xx emulation shared definitions
*
* Copyright (c) 2007 Jocelyn Mayer
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#if !defined(PPC_4XX_H)
#define PPC_4XX_H
#include "hw/pci/pci.h"
/* PowerPC 4xx core initialization */
PowerPCCPU *ppc4xx_init(const char *cpu_model,
clk_setup_t *cpu_clk, clk_setup_t *tb_clk,
uint32_t sysclk);
/* PowerPC 4xx universal interrupt controller */
enum {
PPCUIC_OUTPUT_INT = 0,
PPCUIC_OUTPUT_CINT = 1,
PPCUIC_OUTPUT_NB,
};
qemu_irq *ppcuic_init (CPUPPCState *env, qemu_irq *irqs,
uint32_t dcr_base, int has_ssr, int has_vr);
ram_addr_t ppc4xx_sdram_adjust(ram_addr_t ram_size, int nr_banks,
MemoryRegion ram_memories[],
hwaddr ram_bases[],
hwaddr ram_sizes[],
const unsigned int sdram_bank_sizes[]);
void ppc4xx_sdram_init (CPUPPCState *env, qemu_irq irq, int nbanks,
MemoryRegion ram_memories[],
hwaddr *ram_bases,
hwaddr *ram_sizes,
int do_init);
#define TYPE_PPC4xx_PCI_HOST_BRIDGE "ppc4xx-pcihost"
PCIBus *ppc4xx_pci_init(CPUPPCState *env, qemu_irq pci_irqs[4],
hwaddr config_space,
hwaddr int_ack,
hwaddr special_cycle,
hwaddr registers);
#endif /* !defined(PPC_4XX_H) */

358
include/hw/ppc/spapr.h Normal file
View file

@ -0,0 +1,358 @@
#if !defined(__HW_SPAPR_H__)
#define __HW_SPAPR_H__
#include "sysemu/dma.h"
#include "hw/ppc/xics.h"
struct VIOsPAPRBus;
struct sPAPRPHBState;
struct sPAPRNVRAM;
struct icp_state;
typedef struct sPAPREnvironment {
struct VIOsPAPRBus *vio_bus;
QLIST_HEAD(, sPAPRPHBState) phbs;
struct sPAPRNVRAM *nvram;
struct icp_state *icp;
hwaddr ram_limit;
void *htab;
long htab_shift;
hwaddr rma_size;
int vrma_adjust;
hwaddr fdt_addr, rtas_addr;
long rtas_size;
void *fdt_skel;
target_ulong entry_point;
int next_irq;
int rtc_offset;
char *cpu_model;
bool has_graphics;
uint32_t epow_irq;
Notifier epow_notifier;
} sPAPREnvironment;
#define H_SUCCESS 0
#define H_BUSY 1 /* Hardware busy -- retry later */
#define H_CLOSED 2 /* Resource closed */
#define H_NOT_AVAILABLE 3
#define H_CONSTRAINED 4 /* Resource request constrained to max allowed */
#define H_PARTIAL 5
#define H_IN_PROGRESS 14 /* Kind of like busy */
#define H_PAGE_REGISTERED 15
#define H_PARTIAL_STORE 16
#define H_PENDING 17 /* returned from H_POLL_PENDING */
#define H_CONTINUE 18 /* Returned from H_Join on success */
#define H_LONG_BUSY_START_RANGE 9900 /* Start of long busy range */
#define H_LONG_BUSY_ORDER_1_MSEC 9900 /* Long busy, hint that 1msec \
is a good time to retry */
#define H_LONG_BUSY_ORDER_10_MSEC 9901 /* Long busy, hint that 10msec \
is a good time to retry */
#define H_LONG_BUSY_ORDER_100_MSEC 9902 /* Long busy, hint that 100msec \
is a good time to retry */
#define H_LONG_BUSY_ORDER_1_SEC 9903 /* Long busy, hint that 1sec \
is a good time to retry */
#define H_LONG_BUSY_ORDER_10_SEC 9904 /* Long busy, hint that 10sec \
is a good time to retry */
#define H_LONG_BUSY_ORDER_100_SEC 9905 /* Long busy, hint that 100sec \
is a good time to retry */
#define H_LONG_BUSY_END_RANGE 9905 /* End of long busy range */
#define H_HARDWARE -1 /* Hardware error */
#define H_FUNCTION -2 /* Function not supported */
#define H_PRIVILEGE -3 /* Caller not privileged */
#define H_PARAMETER -4 /* Parameter invalid, out-of-range or conflicting */
#define H_BAD_MODE -5 /* Illegal msr value */
#define H_PTEG_FULL -6 /* PTEG is full */
#define H_NOT_FOUND -7 /* PTE was not found" */
#define H_RESERVED_DABR -8 /* DABR address is reserved by the hypervisor on this processor" */
#define H_NO_MEM -9
#define H_AUTHORITY -10
#define H_PERMISSION -11
#define H_DROPPED -12
#define H_SOURCE_PARM -13
#define H_DEST_PARM -14
#define H_REMOTE_PARM -15
#define H_RESOURCE -16
#define H_ADAPTER_PARM -17
#define H_RH_PARM -18
#define H_RCQ_PARM -19
#define H_SCQ_PARM -20
#define H_EQ_PARM -21
#define H_RT_PARM -22
#define H_ST_PARM -23
#define H_SIGT_PARM -24
#define H_TOKEN_PARM -25
#define H_MLENGTH_PARM -27
#define H_MEM_PARM -28
#define H_MEM_ACCESS_PARM -29
#define H_ATTR_PARM -30
#define H_PORT_PARM -31
#define H_MCG_PARM -32
#define H_VL_PARM -33
#define H_TSIZE_PARM -34
#define H_TRACE_PARM -35
#define H_MASK_PARM -37
#define H_MCG_FULL -38
#define H_ALIAS_EXIST -39
#define H_P_COUNTER -40
#define H_TABLE_FULL -41
#define H_ALT_TABLE -42
#define H_MR_CONDITION -43
#define H_NOT_ENOUGH_RESOURCES -44
#define H_R_STATE -45
#define H_RESCINDEND -46
#define H_MULTI_THREADS_ACTIVE -9005
/* Long Busy is a condition that can be returned by the firmware
* when a call cannot be completed now, but the identical call
* should be retried later. This prevents calls blocking in the
* firmware for long periods of time. Annoyingly the firmware can return
* a range of return codes, hinting at how long we should wait before
* retrying. If you don't care for the hint, the macro below is a good
* way to check for the long_busy return codes
*/
#define H_IS_LONG_BUSY(x) ((x >= H_LONG_BUSY_START_RANGE) \
&& (x <= H_LONG_BUSY_END_RANGE))
/* Flags */
#define H_LARGE_PAGE (1ULL<<(63-16))
#define H_EXACT (1ULL<<(63-24)) /* Use exact PTE or return H_PTEG_FULL */
#define H_R_XLATE (1ULL<<(63-25)) /* include a valid logical page num in the pte if the valid bit is set */
#define H_READ_4 (1ULL<<(63-26)) /* Return 4 PTEs */
#define H_PAGE_STATE_CHANGE (1ULL<<(63-28))
#define H_PAGE_UNUSED ((1ULL<<(63-29)) | (1ULL<<(63-30)))
#define H_PAGE_SET_UNUSED (H_PAGE_STATE_CHANGE | H_PAGE_UNUSED)
#define H_PAGE_SET_LOANED (H_PAGE_SET_UNUSED | (1ULL<<(63-31)))
#define H_PAGE_SET_ACTIVE H_PAGE_STATE_CHANGE
#define H_AVPN (1ULL<<(63-32)) /* An avpn is provided as a sanity test */
#define H_ANDCOND (1ULL<<(63-33))
#define H_ICACHE_INVALIDATE (1ULL<<(63-40)) /* icbi, etc. (ignored for IO pages) */
#define H_ICACHE_SYNCHRONIZE (1ULL<<(63-41)) /* dcbst, icbi, etc (ignored for IO pages */
#define H_ZERO_PAGE (1ULL<<(63-48)) /* zero the page before mapping (ignored for IO pages) */
#define H_COPY_PAGE (1ULL<<(63-49))
#define H_N (1ULL<<(63-61))
#define H_PP1 (1ULL<<(63-62))
#define H_PP2 (1ULL<<(63-63))
/* VASI States */
#define H_VASI_INVALID 0
#define H_VASI_ENABLED 1
#define H_VASI_ABORTED 2
#define H_VASI_SUSPENDING 3
#define H_VASI_SUSPENDED 4
#define H_VASI_RESUMED 5
#define H_VASI_COMPLETED 6
/* DABRX flags */
#define H_DABRX_HYPERVISOR (1ULL<<(63-61))
#define H_DABRX_KERNEL (1ULL<<(63-62))
#define H_DABRX_USER (1ULL<<(63-63))
/* Each control block has to be on a 4K boundary */
#define H_CB_ALIGNMENT 4096
/* pSeries hypervisor opcodes */
#define H_REMOVE 0x04
#define H_ENTER 0x08
#define H_READ 0x0c
#define H_CLEAR_MOD 0x10
#define H_CLEAR_REF 0x14
#define H_PROTECT 0x18
#define H_GET_TCE 0x1c
#define H_PUT_TCE 0x20
#define H_SET_SPRG0 0x24
#define H_SET_DABR 0x28
#define H_PAGE_INIT 0x2c
#define H_SET_ASR 0x30
#define H_ASR_ON 0x34
#define H_ASR_OFF 0x38
#define H_LOGICAL_CI_LOAD 0x3c
#define H_LOGICAL_CI_STORE 0x40
#define H_LOGICAL_CACHE_LOAD 0x44
#define H_LOGICAL_CACHE_STORE 0x48
#define H_LOGICAL_ICBI 0x4c
#define H_LOGICAL_DCBF 0x50
#define H_GET_TERM_CHAR 0x54
#define H_PUT_TERM_CHAR 0x58
#define H_REAL_TO_LOGICAL 0x5c
#define H_HYPERVISOR_DATA 0x60
#define H_EOI 0x64
#define H_CPPR 0x68
#define H_IPI 0x6c
#define H_IPOLL 0x70
#define H_XIRR 0x74
#define H_PERFMON 0x7c
#define H_MIGRATE_DMA 0x78
#define H_REGISTER_VPA 0xDC
#define H_CEDE 0xE0
#define H_CONFER 0xE4
#define H_PROD 0xE8
#define H_GET_PPP 0xEC
#define H_SET_PPP 0xF0
#define H_PURR 0xF4
#define H_PIC 0xF8
#define H_REG_CRQ 0xFC
#define H_FREE_CRQ 0x100
#define H_VIO_SIGNAL 0x104
#define H_SEND_CRQ 0x108
#define H_COPY_RDMA 0x110
#define H_REGISTER_LOGICAL_LAN 0x114
#define H_FREE_LOGICAL_LAN 0x118
#define H_ADD_LOGICAL_LAN_BUFFER 0x11C
#define H_SEND_LOGICAL_LAN 0x120
#define H_BULK_REMOVE 0x124
#define H_MULTICAST_CTRL 0x130
#define H_SET_XDABR 0x134
#define H_STUFF_TCE 0x138
#define H_PUT_TCE_INDIRECT 0x13C
#define H_CHANGE_LOGICAL_LAN_MAC 0x14C
#define H_VTERM_PARTNER_INFO 0x150
#define H_REGISTER_VTERM 0x154
#define H_FREE_VTERM 0x158
#define H_RESET_EVENTS 0x15C
#define H_ALLOC_RESOURCE 0x160
#define H_FREE_RESOURCE 0x164
#define H_MODIFY_QP 0x168
#define H_QUERY_QP 0x16C
#define H_REREGISTER_PMR 0x170
#define H_REGISTER_SMR 0x174
#define H_QUERY_MR 0x178
#define H_QUERY_MW 0x17C
#define H_QUERY_HCA 0x180
#define H_QUERY_PORT 0x184
#define H_MODIFY_PORT 0x188
#define H_DEFINE_AQP1 0x18C
#define H_GET_TRACE_BUFFER 0x190
#define H_DEFINE_AQP0 0x194
#define H_RESIZE_MR 0x198
#define H_ATTACH_MCQP 0x19C
#define H_DETACH_MCQP 0x1A0
#define H_CREATE_RPT 0x1A4
#define H_REMOVE_RPT 0x1A8
#define H_REGISTER_RPAGES 0x1AC
#define H_DISABLE_AND_GETC 0x1B0
#define H_ERROR_DATA 0x1B4
#define H_GET_HCA_INFO 0x1B8
#define H_GET_PERF_COUNT 0x1BC
#define H_MANAGE_TRACE 0x1C0
#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
#define H_QUERY_INT_STATE 0x1E4
#define H_POLL_PENDING 0x1D8
#define H_ILLAN_ATTRIBUTES 0x244
#define H_MODIFY_HEA_QP 0x250
#define H_QUERY_HEA_QP 0x254
#define H_QUERY_HEA 0x258
#define H_QUERY_HEA_PORT 0x25C
#define H_MODIFY_HEA_PORT 0x260
#define H_REG_BCMC 0x264
#define H_DEREG_BCMC 0x268
#define H_REGISTER_HEA_RPAGES 0x26C
#define H_DISABLE_AND_GET_HEA 0x270
#define H_GET_HEA_INFO 0x274
#define H_ALLOC_HEA_RESOURCE 0x278
#define H_ADD_CONN 0x284
#define H_DEL_CONN 0x288
#define H_JOIN 0x298
#define H_VASI_STATE 0x2A4
#define H_ENABLE_CRQ 0x2B0
#define H_GET_EM_PARMS 0x2B8
#define H_SET_MPP 0x2D0
#define H_GET_MPP 0x2D4
#define MAX_HCALL_OPCODE H_GET_MPP
/* The hcalls above are standardized in PAPR and implemented by pHyp
* as well.
*
* We also need some hcalls which are specific to qemu / KVM-on-POWER.
* So far we just need one for H_RTAS, but in future we'll need more
* for extensions like virtio. We put those into the 0xf000-0xfffc
* range which is reserved by PAPR for "platform-specific" hcalls.
*/
#define KVMPPC_HCALL_BASE 0xf000
#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0)
#define KVMPPC_H_LOGICAL_MEMOP (KVMPPC_HCALL_BASE + 0x1)
#define KVMPPC_HCALL_MAX KVMPPC_H_LOGICAL_MEMOP
extern sPAPREnvironment *spapr;
/*#define DEBUG_SPAPR_HCALLS*/
#ifdef DEBUG_SPAPR_HCALLS
#define hcall_dprintf(fmt, ...) \
do { fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); } while (0)
#else
#define hcall_dprintf(fmt, ...) \
do { } while (0)
#endif
typedef target_ulong (*spapr_hcall_fn)(PowerPCCPU *cpu, sPAPREnvironment *spapr,
target_ulong opcode,
target_ulong *args);
void spapr_register_hypercall(target_ulong opcode, spapr_hcall_fn fn);
target_ulong spapr_hypercall(PowerPCCPU *cpu, target_ulong opcode,
target_ulong *args);
int spapr_allocate_irq(int hint, bool lsi);
int spapr_allocate_irq_block(int num, bool lsi);
static inline int spapr_allocate_msi(int hint)
{
return spapr_allocate_irq(hint, false);
}
static inline int spapr_allocate_lsi(int hint)
{
return spapr_allocate_irq(hint, true);
}
static inline uint32_t rtas_ld(target_ulong phys, int n)
{
return ldl_be_phys(phys + 4*n);
}
static inline void rtas_st(target_ulong phys, int n, uint32_t val)
{
stl_be_phys(phys + 4*n, val);
}
typedef void (*spapr_rtas_fn)(sPAPREnvironment *spapr, uint32_t token,
uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
int spapr_rtas_register(const char *name, spapr_rtas_fn fn);
target_ulong spapr_rtas_call(sPAPREnvironment *spapr,
uint32_t token, uint32_t nargs, target_ulong args,
uint32_t nret, target_ulong rets);
int spapr_rtas_device_tree_setup(void *fdt, hwaddr rtas_addr,
hwaddr rtas_size);
#define SPAPR_TCE_PAGE_SHIFT 12
#define SPAPR_TCE_PAGE_SIZE (1ULL << SPAPR_TCE_PAGE_SHIFT)
#define SPAPR_TCE_PAGE_MASK (SPAPR_TCE_PAGE_SIZE - 1)
typedef struct sPAPRTCE {
uint64_t tce;
} sPAPRTCE;
#define SPAPR_VIO_BASE_LIOBN 0x00000000
#define SPAPR_PCI_BASE_LIOBN 0x80000000
#define RTAS_ERROR_LOG_MAX 2048
void spapr_iommu_init(void);
void spapr_events_init(sPAPREnvironment *spapr);
void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq);
DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size);
void spapr_tce_free(DMAContext *dma);
void spapr_tce_reset(DMAContext *dma);
void spapr_tce_set_bypass(DMAContext *dma, bool bypass);
int spapr_dma_dt(void *fdt, int node_off, const char *propname,
uint32_t liobn, uint64_t window, uint32_t size);
int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname,
DMAContext *dma);
#endif /* !defined (__HW_SPAPR_H__) */

136
include/hw/ppc/spapr_vio.h Normal file
View file

@ -0,0 +1,136 @@
#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/>.
*/
#include "sysemu/dma.h"
#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)
#define TYPE_SPAPR_VIO_BUS "spapr-vio-bus"
#define SPAPR_VIO_BUS(obj) OBJECT_CHECK(VIOsPAPRBus, (obj), TYPE_SPAPR_VIO_BUS)
struct VIOsPAPRDevice;
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;
uint32_t rtce_window_size;
int (*init)(VIOsPAPRDevice *dev);
void (*reset)(VIOsPAPRDevice *dev);
int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off);
} VIOsPAPRDeviceClass;
struct VIOsPAPRDevice {
DeviceState qdev;
uint32_t reg;
uint32_t irq;
target_ulong signal_state;
VIOsPAPR_CRQ crq;
DMAContext *dma;
};
#define DEFINE_SPAPR_PROPERTIES(type, field) \
DEFINE_PROP_UINT32("reg", type, field.reg, -1)
struct VIOsPAPRBus {
BusState bus;
uint32_t next_reg;
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);
static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev)
{
return xics_get_qirq(spapr->icp, dev->irq);
}
static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr,
uint32_t size, DMADirection dir)
{
return dma_memory_valid(dev->dma, taddr, size, dir);
}
static inline int spapr_vio_dma_read(VIOsPAPRDevice *dev, uint64_t taddr,
void *buf, uint32_t size)
{
return (dma_memory_read(dev->dma, taddr, buf, size) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
static inline int spapr_vio_dma_write(VIOsPAPRDevice *dev, uint64_t taddr,
const void *buf, uint32_t size)
{
return (dma_memory_write(dev->dma, taddr, buf, size) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr,
uint8_t c, uint32_t size)
{
return (dma_memory_set(dev->dma, taddr, c, size) != 0) ?
H_DEST_PARM : H_SUCCESS;
}
#define vio_stb(_dev, _addr, _val) (stb_dma((_dev)->dma, (_addr), (_val)))
#define vio_sth(_dev, _addr, _val) (stw_be_dma((_dev)->dma, (_addr), (_val)))
#define vio_stl(_dev, _addr, _val) (stl_be_dma((_dev)->dma, (_addr), (_val)))
#define vio_stq(_dev, _addr, _val) (stq_be_dma((_dev)->dma, (_addr), (_val)))
#define vio_ldq(_dev, _addr) (ldq_be_dma((_dev)->dma, (_addr)))
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, CharDriverState *chardev);
void spapr_vlan_create(VIOsPAPRBus *bus, NICInfo *nd);
void spapr_vscsi_create(VIOsPAPRBus *bus);
VIOsPAPRDevice *spapr_vty_get_default(VIOsPAPRBus *bus);
void spapr_vio_quiesce(void);
#endif /* _HW_SPAPR_VIO_H */

41
include/hw/ppc/xics.h Normal file
View file

@ -0,0 +1,41 @@
/*
* QEMU PowerPC pSeries Logical Partition (aka sPAPR) hardware System Emulator
*
* PAPR Virtualized Interrupt System, aka ICS/ICP aka xics
*
* Copyright (c) 2010,2011 David Gibson, IBM Corporation.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#if !defined(__XICS_H__)
#define __XICS_H__
#define XICS_IPI 0x2
#define XICS_IRQ_BASE 0x10
struct icp_state;
qemu_irq xics_get_qirq(struct icp_state *icp, int irq);
void xics_set_irq_type(struct icp_state *icp, int irq, bool lsi);
struct icp_state *xics_system_init(int nr_servers, int nr_irqs);
void xics_cpu_setup(struct icp_state *icp, PowerPCCPU *cpu);
#endif /* __XICS_H__ */

39
include/hw/ptimer.h Normal file
View file

@ -0,0 +1,39 @@
/*
* General purpose implementation of a simple periodic countdown timer.
*
* Copyright (c) 2007 CodeSourcery.
*
* This code is licensed under the GNU LGPL.
*/
#ifndef PTIMER_H
#define PTIMER_H
#include "qemu-common.h"
#include "qemu/timer.h"
#include "migration/vmstate.h"
/* ptimer.c */
typedef struct ptimer_state ptimer_state;
typedef void (*ptimer_cb)(void *opaque);
ptimer_state *ptimer_init(QEMUBH *bh);
void ptimer_set_period(ptimer_state *s, int64_t period);
void ptimer_set_freq(ptimer_state *s, uint32_t freq);
void ptimer_set_limit(ptimer_state *s, uint64_t limit, int reload);
uint64_t ptimer_get_count(ptimer_state *s);
void ptimer_set_count(ptimer_state *s, uint64_t count);
void ptimer_run(ptimer_state *s, int oneshot);
void ptimer_stop(ptimer_state *s);
extern const VMStateDescription vmstate_ptimer;
#define VMSTATE_PTIMER(_field, _state) { \
.name = (stringify(_field)), \
.version_id = (1), \
.vmsd = &vmstate_ptimer, \
.size = sizeof(ptimer_state *), \
.flags = VMS_STRUCT|VMS_POINTER, \
.offset = vmstate_offset_pointer(_state, _field, ptimer_state), \
}
#endif

10
include/hw/qdev-addr.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef HW_QDEV_ADDR_H
#define HW_QDEV_ADDR_H 1
#define DEFINE_PROP_TADDR(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_taddr, hwaddr)
extern PropertyInfo qdev_prop_taddr;
void qdev_prop_set_taddr(DeviceState *dev, const char *name, hwaddr value);
#endif

299
include/hw/qdev-core.h Normal file
View file

@ -0,0 +1,299 @@
#ifndef QDEV_CORE_H
#define QDEV_CORE_H
#include "qemu/queue.h"
#include "qemu/option.h"
#include "qemu/typedefs.h"
#include "qom/object.h"
#include "hw/irq.h"
#include "qapi/error.h"
enum {
DEV_NVECTORS_UNSPECIFIED = -1,
};
#define TYPE_DEVICE "device"
#define DEVICE(obj) OBJECT_CHECK(DeviceState, (obj), TYPE_DEVICE)
#define DEVICE_CLASS(klass) OBJECT_CLASS_CHECK(DeviceClass, (klass), TYPE_DEVICE)
#define DEVICE_GET_CLASS(obj) OBJECT_GET_CLASS(DeviceClass, (obj), TYPE_DEVICE)
typedef int (*qdev_initfn)(DeviceState *dev);
typedef int (*qdev_event)(DeviceState *dev);
typedef void (*qdev_resetfn)(DeviceState *dev);
typedef void (*DeviceRealize)(DeviceState *dev, Error **errp);
typedef void (*DeviceUnrealize)(DeviceState *dev, Error **errp);
struct VMStateDescription;
/**
* DeviceClass:
* @props: Properties accessing state fields.
* @realize: Callback function invoked when the #DeviceState:realized
* property is changed to %true. The default invokes @init if not %NULL.
* @unrealize: Callback function invoked when the #DeviceState:realized
* property is changed to %false.
* @init: Callback function invoked when the #DeviceState::realized property
* is changed to %true. Deprecated, new types inheriting directly from
* TYPE_DEVICE should use @realize instead, new leaf types should consult
* their respective parent type.
*
* # Realization #
* Devices are constructed in two stages,
* 1) object instantiation via object_initialize() and
* 2) device realization via #DeviceState:realized property.
* The former may not fail (it might assert or exit), the latter may return
* error information to the caller and must be re-entrant.
* Trivial field initializations should go into #TypeInfo.instance_init.
* Operations depending on @props static properties should go into @realize.
* After successful realization, setting static properties will fail.
*
* As an interim step, the #DeviceState:realized property is set by deprecated
* functions qdev_init() and qdev_init_nofail().
* In the future, devices will propagate this state change to their children
* and along busses they expose.
* The point in time will be deferred to machine creation, so that values
* set in @realize will not be introspectable beforehand. Therefore devices
* must not create children during @realize; they should initialize them via
* object_initialize() in their own #TypeInfo.instance_init and forward the
* realization events appropriately.
*
* The @init callback is considered private to a particular bus implementation
* (immediate abstract child types of TYPE_DEVICE). Derived leaf types set an
* "init" callback on their parent class instead.
*
* Any type may override the @realize and/or @unrealize callbacks but needs
* to call the parent type's implementation if keeping their functionality
* is desired. Refer to QOM documentation for further discussion and examples.
*
* <note>
* <para>
* If a type derived directly from TYPE_DEVICE implements @realize, it does
* not need to implement @init and therefore does not need to store and call
* #DeviceClass' default @realize callback.
* For other types consult the documentation and implementation of the
* respective parent types.
* </para>
* </note>
*/
typedef struct DeviceClass {
/*< private >*/
ObjectClass parent_class;
/*< public >*/
const char *fw_name;
const char *desc;
Property *props;
int no_user;
/* callbacks */
void (*reset)(DeviceState *dev);
DeviceRealize realize;
DeviceUnrealize unrealize;
/* device state */
const struct VMStateDescription *vmsd;
/* Private to qdev / bus. */
qdev_initfn init; /* TODO remove, once users are converted to realize */
qdev_event unplug;
qdev_event exit;
const char *bus_type;
} DeviceClass;
/**
* DeviceState:
* @realized: Indicates whether the device has been fully constructed.
*
* This structure should not be accessed directly. We declare it here
* so that it can be embedded in individual device state structures.
*/
struct DeviceState {
/*< private >*/
Object parent_obj;
/*< public >*/
const char *id;
bool realized;
QemuOpts *opts;
int hotplugged;
BusState *parent_bus;
int num_gpio_out;
qemu_irq *gpio_out;
int num_gpio_in;
qemu_irq *gpio_in;
QLIST_HEAD(, BusState) child_bus;
int num_child_bus;
int instance_id_alias;
int alias_required_for_version;
};
#define TYPE_BUS "bus"
#define BUS(obj) OBJECT_CHECK(BusState, (obj), TYPE_BUS)
#define BUS_CLASS(klass) OBJECT_CLASS_CHECK(BusClass, (klass), TYPE_BUS)
#define BUS_GET_CLASS(obj) OBJECT_GET_CLASS(BusClass, (obj), TYPE_BUS)
struct BusClass {
ObjectClass parent_class;
/* FIXME first arg should be BusState */
void (*print_dev)(Monitor *mon, DeviceState *dev, int indent);
char *(*get_dev_path)(DeviceState *dev);
/*
* This callback is used to create Open Firmware device path in accordance
* with OF spec http://forthworks.com/standards/of1275.pdf. Individual bus
* bindings can be found at http://playground.sun.com/1275/bindings/.
*/
char *(*get_fw_dev_path)(DeviceState *dev);
int (*reset)(BusState *bus);
/* maximum devices allowed on the bus, 0: no limit. */
int max_dev;
};
typedef struct BusChild {
DeviceState *child;
int index;
QTAILQ_ENTRY(BusChild) sibling;
} BusChild;
/**
* BusState:
*/
struct BusState {
Object obj;
DeviceState *parent;
const char *name;
int allow_hotplug;
int max_index;
QTAILQ_HEAD(ChildrenHead, BusChild) children;
QLIST_ENTRY(BusState) sibling;
};
struct Property {
const char *name;
PropertyInfo *info;
int offset;
uint8_t bitnr;
uint8_t qtype;
int64_t defval;
int arrayoffset;
PropertyInfo *arrayinfo;
int arrayfieldsize;
};
struct PropertyInfo {
const char *name;
const char *legacy_name;
const char **enum_table;
int (*parse)(DeviceState *dev, Property *prop, const char *str);
int (*print)(DeviceState *dev, Property *prop, char *dest, size_t len);
ObjectPropertyAccessor *get;
ObjectPropertyAccessor *set;
ObjectPropertyRelease *release;
};
typedef struct GlobalProperty {
const char *driver;
const char *property;
const char *value;
QTAILQ_ENTRY(GlobalProperty) next;
} GlobalProperty;
/*** Board API. This should go away once we have a machine config file. ***/
DeviceState *qdev_create(BusState *bus, const char *name);
DeviceState *qdev_try_create(BusState *bus, const char *name);
int qdev_init(DeviceState *dev) QEMU_WARN_UNUSED_RESULT;
void qdev_init_nofail(DeviceState *dev);
void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
int required_for_version);
void qdev_unplug(DeviceState *dev, Error **errp);
void qdev_free(DeviceState *dev);
int qdev_simple_unplug_cb(DeviceState *dev);
void qdev_machine_creation_done(void);
bool qdev_machine_modified(void);
qemu_irq qdev_get_gpio_in(DeviceState *dev, int n);
void qdev_connect_gpio_out(DeviceState *dev, int n, qemu_irq pin);
BusState *qdev_get_child_bus(DeviceState *dev, const char *name);
/*** Device API. ***/
/* Register device properties. */
/* GPIO inputs also double as IRQ sinks. */
void qdev_init_gpio_in(DeviceState *dev, qemu_irq_handler handler, int n);
void qdev_init_gpio_out(DeviceState *dev, qemu_irq *pins, int n);
BusState *qdev_get_parent_bus(DeviceState *dev);
/*** BUS API. ***/
DeviceState *qdev_find_recursive(BusState *bus, const char *id);
/* Returns 0 to walk children, > 0 to skip walk, < 0 to terminate walk. */
typedef int (qbus_walkerfn)(BusState *bus, void *opaque);
typedef int (qdev_walkerfn)(DeviceState *dev, void *opaque);
void qbus_create_inplace(void *bus, const char *typename,
DeviceState *parent, const char *name);
BusState *qbus_create(const char *typename, DeviceState *parent, const char *name);
/* Returns > 0 if either devfn or busfn skip walk somewhere in cursion,
* < 0 if either devfn or busfn terminate walk somewhere in cursion,
* 0 otherwise. */
int qbus_walk_children(BusState *bus, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque);
int qdev_walk_children(DeviceState *dev, qdev_walkerfn *devfn,
qbus_walkerfn *busfn, void *opaque);
void qdev_reset_all(DeviceState *dev);
/**
* @qbus_reset_all:
* @bus: Bus to be reset.
*
* Reset @bus and perform a bus-level ("hard") reset of all devices connected
* to it, including recursive processing of all buses below @bus itself. A
* hard reset means that qbus_reset_all will reset all state of the device.
* For PCI devices, for example, this will include the base address registers
* or configuration space.
*/
void qbus_reset_all(BusState *bus);
void qbus_reset_all_fn(void *opaque);
void qbus_free(BusState *bus);
#define FROM_QBUS(type, dev) DO_UPCAST(type, qbus, dev)
/* This should go away once we get rid of the NULL bus hack */
BusState *sysbus_get_default(void);
char *qdev_get_fw_dev_path(DeviceState *dev);
/**
* @qdev_machine_init
*
* Initialize platform devices before machine init. This is a hack until full
* support for composition is added.
*/
void qdev_machine_init(void);
/**
* @device_reset
*
* Reset a single device (by calling the reset method).
*/
void device_reset(DeviceState *dev);
const struct VMStateDescription *qdev_get_vmsd(DeviceState *dev);
const char *qdev_fw_name(DeviceState *dev);
Object *qdev_get_machine(void);
/* FIXME: make this a link<> */
void qdev_set_parent_bus(DeviceState *dev, BusState *bus);
extern int qdev_hotplug;
char *qdev_get_dev_path(DeviceState *dev);
#endif

10
include/hw/qdev-dma.h Normal file
View file

@ -0,0 +1,10 @@
/*
* Support for dma_addr_t typed properties
*
* Copyright (C) 2012 David Gibson, IBM Corporation.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#define DEFINE_PROP_DMAADDR(_n, _s, _f, _d) \
DEFINE_PROP_HEX64(_n, _s, _f, _d)

View file

@ -0,0 +1,182 @@
#ifndef QEMU_QDEV_PROPERTIES_H
#define QEMU_QDEV_PROPERTIES_H
#include "hw/qdev-core.h"
/*** qdev-properties.c ***/
extern PropertyInfo qdev_prop_bit;
extern PropertyInfo qdev_prop_uint8;
extern PropertyInfo qdev_prop_uint16;
extern PropertyInfo qdev_prop_uint32;
extern PropertyInfo qdev_prop_int32;
extern PropertyInfo qdev_prop_uint64;
extern PropertyInfo qdev_prop_hex8;
extern PropertyInfo qdev_prop_hex32;
extern PropertyInfo qdev_prop_hex64;
extern PropertyInfo qdev_prop_string;
extern PropertyInfo qdev_prop_chr;
extern PropertyInfo qdev_prop_ptr;
extern PropertyInfo qdev_prop_macaddr;
extern PropertyInfo qdev_prop_losttickpolicy;
extern PropertyInfo qdev_prop_bios_chs_trans;
extern PropertyInfo qdev_prop_drive;
extern PropertyInfo qdev_prop_netdev;
extern PropertyInfo qdev_prop_vlan;
extern PropertyInfo qdev_prop_pci_devfn;
extern PropertyInfo qdev_prop_blocksize;
extern PropertyInfo qdev_prop_pci_host_devaddr;
extern PropertyInfo qdev_prop_arraylen;
#define DEFINE_PROP(_name, _state, _field, _prop, _type) { \
.name = (_name), \
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type, typeof_field(_state, _field)), \
}
#define DEFINE_PROP_DEFAULT(_name, _state, _field, _defval, _prop, _type) { \
.name = (_name), \
.info = &(_prop), \
.offset = offsetof(_state, _field) \
+ type_check(_type,typeof_field(_state, _field)), \
.qtype = QTYPE_QINT, \
.defval = (_type)_defval, \
}
#define DEFINE_PROP_BIT(_name, _state, _field, _bit, _defval) { \
.name = (_name), \
.info = &(qdev_prop_bit), \
.bitnr = (_bit), \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t,typeof_field(_state, _field)), \
.qtype = QTYPE_QBOOL, \
.defval = (bool)_defval, \
}
#define PROP_ARRAY_LEN_PREFIX "len-"
/**
* DEFINE_PROP_ARRAY:
* @_name: name of the array
* @_state: name of the device state structure type
* @_field: uint32_t field in @_state to hold the array length
* @_arrayfield: field in @_state (of type '@_arraytype *') which
* will point to the array
* @_arrayprop: PropertyInfo defining what property the array elements have
* @_arraytype: C type of the array elements
*
* Define device properties for a variable-length array _name. A
* static property "len-arrayname" is defined. When the device creator
* sets this property to the desired length of array, further dynamic
* properties "arrayname[0]", "arrayname[1]", ... are defined so the
* device creator can set the array element values. Setting the
* "len-arrayname" property more than once is an error.
*
* When the array length is set, the @_field member of the device
* struct is set to the array length, and @_arrayfield is set to point
* to (zero-initialised) memory allocated for the array. For a zero
* length array, @_field will be set to 0 and @_arrayfield to NULL.
* It is the responsibility of the device deinit code to free the
* @_arrayfield memory.
*/
#define DEFINE_PROP_ARRAY(_name, _state, _field, \
_arrayfield, _arrayprop, _arraytype) { \
.name = (PROP_ARRAY_LEN_PREFIX _name), \
.info = &(qdev_prop_arraylen), \
.offset = offsetof(_state, _field) \
+ type_check(uint32_t, typeof_field(_state, _field)), \
.qtype = QTYPE_QINT, \
.arrayinfo = &(_arrayprop), \
.arrayfieldsize = sizeof(_arraytype), \
.arrayoffset = offsetof(_state, _arrayfield), \
}
#define DEFINE_PROP_UINT8(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint8, uint8_t)
#define DEFINE_PROP_UINT16(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint16, uint16_t)
#define DEFINE_PROP_UINT32(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint32, uint32_t)
#define DEFINE_PROP_INT32(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_int32, int32_t)
#define DEFINE_PROP_UINT64(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_uint64, uint64_t)
#define DEFINE_PROP_HEX8(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex8, uint8_t)
#define DEFINE_PROP_HEX32(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex32, uint32_t)
#define DEFINE_PROP_HEX64(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_hex64, uint64_t)
#define DEFINE_PROP_PCI_DEVFN(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_pci_devfn, int32_t)
#define DEFINE_PROP_PTR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_ptr, void*)
#define DEFINE_PROP_CHR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_chr, CharDriverState*)
#define DEFINE_PROP_STRING(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_string, char*)
#define DEFINE_PROP_NETDEV(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_netdev, NICPeers)
#define DEFINE_PROP_VLAN(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_vlan, NICPeers)
#define DEFINE_PROP_DRIVE(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_drive, BlockDriverState *)
#define DEFINE_PROP_MACADDR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_macaddr, MACAddr)
#define DEFINE_PROP_LOSTTICKPOLICY(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_losttickpolicy, \
LostTickPolicy)
#define DEFINE_PROP_BIOS_CHS_TRANS(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_bios_chs_trans, int)
#define DEFINE_PROP_BLOCKSIZE(_n, _s, _f, _d) \
DEFINE_PROP_DEFAULT(_n, _s, _f, _d, qdev_prop_blocksize, uint16_t)
#define DEFINE_PROP_PCI_HOST_DEVADDR(_n, _s, _f) \
DEFINE_PROP(_n, _s, _f, qdev_prop_pci_host_devaddr, PCIHostDeviceAddress)
#define DEFINE_PROP_END_OF_LIST() \
{}
/* Set properties between creation and init. */
void *qdev_get_prop_ptr(DeviceState *dev, Property *prop);
int qdev_prop_parse(DeviceState *dev, const char *name, const char *value);
void qdev_prop_set_bit(DeviceState *dev, const char *name, bool value);
void qdev_prop_set_uint8(DeviceState *dev, const char *name, uint8_t value);
void qdev_prop_set_uint16(DeviceState *dev, const char *name, uint16_t value);
void qdev_prop_set_uint32(DeviceState *dev, const char *name, uint32_t value);
void qdev_prop_set_int32(DeviceState *dev, const char *name, int32_t value);
void qdev_prop_set_uint64(DeviceState *dev, const char *name, uint64_t value);
void qdev_prop_set_string(DeviceState *dev, const char *name, const char *value);
void qdev_prop_set_chr(DeviceState *dev, const char *name, CharDriverState *value);
void qdev_prop_set_netdev(DeviceState *dev, const char *name, NetClientState *value);
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) QEMU_WARN_UNUSED_RESULT;
void qdev_prop_set_drive_nofail(DeviceState *dev, const char *name, BlockDriverState *value);
void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
void qdev_prop_set_enum(DeviceState *dev, const char *name, int value);
/* FIXME: Remove opaque pointer properties. */
void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
void qdev_prop_register_global(GlobalProperty *prop);
void qdev_prop_register_global_list(GlobalProperty *props);
void qdev_prop_set_globals(DeviceState *dev);
void error_set_from_qdev_prop_error(Error **errp, int ret, DeviceState *dev,
Property *prop, const char *value);
/**
* @qdev_property_add_static - add a @Property to a device referencing a
* field in a struct.
*/
void qdev_property_add_static(DeviceState *dev, Property *prop, Error **errp);
/**
* @qdev_prop_set_after_realize:
* @dev: device
* @name: name of property
* @errp: indirect pointer to Error to be set
* Set the Error object to report that an attempt was made to set a property
* on a device after it has already been realized. This is a utility function
* which allows property-setter functions to easily report the error in
* a friendly format identifying both the device and the property.
*/
void qdev_prop_set_after_realize(DeviceState *dev, const char *name,
Error **errp);
#endif

8
include/hw/qdev.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef QDEV_H
#define QDEV_H
#include "hw/hw.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#endif

View file

@ -0,0 +1,96 @@
/*
* SCLP
* Event Facility definitions
*
* Copyright IBM, Corp. 2012
*
* Authors:
* Heinz Graalfs <graalfs@de.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at your
* option) any later version. See the COPYING file in the top-level directory.
*
*/
#ifndef HW_S390_SCLP_EVENT_FACILITY_H
#define HW_S390_SCLP_EVENT_FACILITY_H
#include <hw/qdev.h>
#include "qemu/thread.h"
/* SCLP event types */
#define SCLP_EVENT_ASCII_CONSOLE_DATA 0x1a
#define SCLP_EVENT_SIGNAL_QUIESCE 0x1d
/* SCLP event masks */
#define SCLP_EVENT_MASK_SIGNAL_QUIESCE 0x00000008
#define SCLP_EVENT_MASK_MSG_ASCII 0x00000040
#define SCLP_UNCONDITIONAL_READ 0x00
#define SCLP_SELECTIVE_READ 0x01
#define TYPE_SCLP_EVENT "s390-sclp-event-type"
#define SCLP_EVENT(obj) \
OBJECT_CHECK(SCLPEvent, (obj), TYPE_SCLP_EVENT)
#define SCLP_EVENT_CLASS(klass) \
OBJECT_CLASS_CHECK(SCLPEventClass, (klass), TYPE_SCLP_EVENT)
#define SCLP_EVENT_GET_CLASS(obj) \
OBJECT_GET_CLASS(SCLPEventClass, (obj), TYPE_SCLP_EVENT)
typedef struct WriteEventMask {
SCCBHeader h;
uint16_t _reserved;
uint16_t mask_length;
uint32_t cp_receive_mask;
uint32_t cp_send_mask;
uint32_t send_mask;
uint32_t receive_mask;
} QEMU_PACKED WriteEventMask;
typedef struct EventBufferHeader {
uint16_t length;
uint8_t type;
uint8_t flags;
uint16_t _reserved;
} QEMU_PACKED EventBufferHeader;
typedef struct WriteEventData {
SCCBHeader h;
EventBufferHeader ebh;
} QEMU_PACKED WriteEventData;
typedef struct ReadEventData {
SCCBHeader h;
EventBufferHeader ebh;
uint32_t mask;
} QEMU_PACKED ReadEventData;
typedef struct SCLPEvent {
DeviceState qdev;
bool event_pending;
uint32_t event_type;
char *name;
} SCLPEvent;
typedef struct SCLPEventClass {
DeviceClass parent_class;
int (*init)(SCLPEvent *event);
int (*exit)(SCLPEvent *event);
/* get SCLP's send mask */
unsigned int (*get_send_mask)(void);
/* get SCLP's receive mask */
unsigned int (*get_receive_mask)(void);
int (*read_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
int *slen);
int (*write_event_data)(SCLPEvent *event, EventBufferHeader *evt_buf_hdr);
/* returns the supported event type */
int (*event_type)(void);
} SCLPEventClass;
#endif

118
include/hw/s390x/sclp.h Normal file
View file

@ -0,0 +1,118 @@
/*
* SCLP Support
*
* Copyright IBM, Corp. 2012
*
* Authors:
* Christian Borntraeger <borntraeger@de.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or (at your
* option) any later version. See the COPYING file in the top-level directory.
*
*/
#ifndef HW_S390_SCLP_H
#define HW_S390_SCLP_H
#include <hw/sysbus.h>
#include <hw/qdev.h>
/* SCLP command codes */
#define SCLP_CMDW_READ_SCP_INFO 0x00020001
#define SCLP_CMDW_READ_SCP_INFO_FORCED 0x00120001
#define SCLP_CMD_READ_EVENT_DATA 0x00770005
#define SCLP_CMD_WRITE_EVENT_DATA 0x00760005
#define SCLP_CMD_READ_EVENT_DATA 0x00770005
#define SCLP_CMD_WRITE_EVENT_DATA 0x00760005
#define SCLP_CMD_WRITE_EVENT_MASK 0x00780005
/* SCLP response codes */
#define SCLP_RC_NORMAL_READ_COMPLETION 0x0010
#define SCLP_RC_NORMAL_COMPLETION 0x0020
#define SCLP_RC_INVALID_SCLP_COMMAND 0x01f0
#define SCLP_RC_CONTAINED_EQUIPMENT_CHECK 0x0340
#define SCLP_RC_INSUFFICIENT_SCCB_LENGTH 0x0300
#define SCLP_RC_INVALID_FUNCTION 0x40f0
#define SCLP_RC_NO_EVENT_BUFFERS_STORED 0x60f0
#define SCLP_RC_INVALID_SELECTION_MASK 0x70f0
#define SCLP_RC_INCONSISTENT_LENGTHS 0x72f0
#define SCLP_RC_EVENT_BUFFER_SYNTAX_ERROR 0x73f0
#define SCLP_RC_INVALID_MASK_LENGTH 0x74f0
/* Service Call Control Block (SCCB) and its elements */
#define SCCB_SIZE 4096
#define SCLP_VARIABLE_LENGTH_RESPONSE 0x80
#define SCLP_EVENT_BUFFER_ACCEPTED 0x80
#define SCLP_FC_NORMAL_WRITE 0
/*
* Normally packed structures are not the right thing to do, since all code
* must take care of endianness. We cannot use ldl_phys and friends for two
* reasons, though:
* - some of the embedded structures below the SCCB can appear multiple times
* at different locations, so there is no fixed offset
* - we work on a private copy of the SCCB, since there are several length
* fields, that would cause a security nightmare if we allow the guest to
* alter the structure while we parse it. We cannot use ldl_p and friends
* either without doing pointer arithmetics
* So we have to double check that all users of sclp data structures use the
* right endianness wrappers.
*/
typedef struct SCCBHeader {
uint16_t length;
uint8_t function_code;
uint8_t control_mask[3];
uint16_t response_code;
} QEMU_PACKED SCCBHeader;
#define SCCB_DATA_LEN (SCCB_SIZE - sizeof(SCCBHeader))
typedef struct ReadInfo {
SCCBHeader h;
uint16_t rnmax;
uint8_t rnsize;
} QEMU_PACKED ReadInfo;
typedef struct SCCB {
SCCBHeader h;
char data[SCCB_DATA_LEN];
} QEMU_PACKED SCCB;
static inline int sccb_data_len(SCCB *sccb)
{
return be16_to_cpu(sccb->h.length) - sizeof(sccb->h);
}
#define TYPE_DEVICE_S390_SCLP "s390-sclp-device"
#define SCLP_S390_DEVICE(obj) \
OBJECT_CHECK(S390SCLPDevice, (obj), TYPE_DEVICE_S390_SCLP)
#define SCLP_S390_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(S390SCLPDeviceClass, (klass), \
TYPE_DEVICE_S390_SCLP)
#define SCLP_S390_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(S390SCLPDeviceClass, (obj), \
TYPE_DEVICE_S390_SCLP)
typedef struct SCLPEventFacility SCLPEventFacility;
typedef struct S390SCLPDevice {
SysBusDevice busdev;
SCLPEventFacility *ef;
void (*sclp_command_handler)(SCLPEventFacility *ef, SCCB *sccb,
uint64_t code);
bool (*event_pending)(SCLPEventFacility *ef);
} S390SCLPDevice;
typedef struct S390SCLPDeviceClass {
DeviceClass qdev;
int (*init)(S390SCLPDevice *sdev);
} S390SCLPDeviceClass;
void s390_sclp_init(void);
void sclp_service_interrupt(uint32_t sccb);
#endif

132
include/hw/scsi/esp.h Normal file
View file

@ -0,0 +1,132 @@
#ifndef QEMU_HW_ESP_H
#define QEMU_HW_ESP_H
#include "hw/scsi/scsi.h"
/* esp.c */
#define ESP_MAX_DEVS 7
typedef void (*ESPDMAMemoryReadWriteFunc)(void *opaque, uint8_t *buf, int len);
void esp_init(hwaddr espaddr, int it_shift,
ESPDMAMemoryReadWriteFunc dma_memory_read,
ESPDMAMemoryReadWriteFunc dma_memory_write,
void *dma_opaque, qemu_irq irq, qemu_irq *reset,
qemu_irq *dma_enable);
#define ESP_REGS 16
#define TI_BUFSZ 16
typedef struct ESPState ESPState;
struct ESPState {
uint8_t rregs[ESP_REGS];
uint8_t wregs[ESP_REGS];
qemu_irq irq;
uint8_t chip_id;
int32_t ti_size;
uint32_t ti_rptr, ti_wptr;
uint32_t status;
uint32_t dma;
uint8_t ti_buf[TI_BUFSZ];
SCSIBus bus;
SCSIDevice *current_dev;
SCSIRequest *current_req;
uint8_t cmdbuf[TI_BUFSZ];
uint32_t cmdlen;
uint32_t do_cmd;
/* The amount of data left in the current DMA transfer. */
uint32_t dma_left;
/* The size of the current DMA transfer. Zero if no transfer is in
progress. */
uint32_t dma_counter;
int dma_enabled;
uint32_t async_len;
uint8_t *async_buf;
ESPDMAMemoryReadWriteFunc dma_memory_read;
ESPDMAMemoryReadWriteFunc dma_memory_write;
void *dma_opaque;
void (*dma_cb)(ESPState *s);
};
#define ESP_TCLO 0x0
#define ESP_TCMID 0x1
#define ESP_FIFO 0x2
#define ESP_CMD 0x3
#define ESP_RSTAT 0x4
#define ESP_WBUSID 0x4
#define ESP_RINTR 0x5
#define ESP_WSEL 0x5
#define ESP_RSEQ 0x6
#define ESP_WSYNTP 0x6
#define ESP_RFLAGS 0x7
#define ESP_WSYNO 0x7
#define ESP_CFG1 0x8
#define ESP_RRES1 0x9
#define ESP_WCCF 0x9
#define ESP_RRES2 0xa
#define ESP_WTEST 0xa
#define ESP_CFG2 0xb
#define ESP_CFG3 0xc
#define ESP_RES3 0xd
#define ESP_TCHI 0xe
#define ESP_RES4 0xf
#define CMD_DMA 0x80
#define CMD_CMD 0x7f
#define CMD_NOP 0x00
#define CMD_FLUSH 0x01
#define CMD_RESET 0x02
#define CMD_BUSRESET 0x03
#define CMD_TI 0x10
#define CMD_ICCS 0x11
#define CMD_MSGACC 0x12
#define CMD_PAD 0x18
#define CMD_SATN 0x1a
#define CMD_RSTATN 0x1b
#define CMD_SEL 0x41
#define CMD_SELATN 0x42
#define CMD_SELATNS 0x43
#define CMD_ENSEL 0x44
#define CMD_DISSEL 0x45
#define STAT_DO 0x00
#define STAT_DI 0x01
#define STAT_CD 0x02
#define STAT_ST 0x03
#define STAT_MO 0x06
#define STAT_MI 0x07
#define STAT_PIO_MASK 0x06
#define STAT_TC 0x10
#define STAT_PE 0x20
#define STAT_GE 0x40
#define STAT_INT 0x80
#define BUSID_DID 0x07
#define INTR_FC 0x08
#define INTR_BS 0x10
#define INTR_DC 0x20
#define INTR_RST 0x80
#define SEQ_0 0x0
#define SEQ_CD 0x4
#define CFG1_RESREPT 0x40
#define TCHI_FAS100A 0x4
#define TCHI_AM53C974 0x12
void esp_dma_enable(ESPState *s, int irq, int level);
void esp_request_cancelled(SCSIRequest *req);
void esp_command_complete(SCSIRequest *req, uint32_t status, size_t resid);
void esp_transfer_data(SCSIRequest *req, uint32_t len);
void esp_hard_reset(ESPState *s);
uint64_t esp_reg_read(ESPState *s, uint32_t saddr);
void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val);
extern const VMStateDescription vmstate_esp;
#endif

256
include/hw/scsi/scsi.h Normal file
View file

@ -0,0 +1,256 @@
#ifndef QEMU_HW_SCSI_H
#define QEMU_HW_SCSI_H
#include "hw/qdev.h"
#include "block/block.h"
#include "hw/block/block.h"
#include "sysemu/sysemu.h"
#define MAX_SCSI_DEVS 255
#define SCSI_CMD_BUF_SIZE 16
typedef struct SCSIBus SCSIBus;
typedef struct SCSIBusInfo SCSIBusInfo;
typedef struct SCSICommand SCSICommand;
typedef struct SCSIDevice SCSIDevice;
typedef struct SCSIRequest SCSIRequest;
typedef struct SCSIReqOps SCSIReqOps;
enum SCSIXferMode {
SCSI_XFER_NONE, /* TEST_UNIT_READY, ... */
SCSI_XFER_FROM_DEV, /* READ, INQUIRY, MODE_SENSE, ... */
SCSI_XFER_TO_DEV, /* WRITE, MODE_SELECT, ... */
};
typedef struct SCSISense {
uint8_t key;
uint8_t asc;
uint8_t ascq;
} SCSISense;
#define SCSI_SENSE_BUF_SIZE 96
struct SCSICommand {
uint8_t buf[SCSI_CMD_BUF_SIZE];
int len;
size_t xfer;
uint64_t lba;
enum SCSIXferMode mode;
};
struct SCSIRequest {
SCSIBus *bus;
SCSIDevice *dev;
const SCSIReqOps *ops;
uint32_t refcount;
uint32_t tag;
uint32_t lun;
uint32_t status;
size_t resid;
SCSICommand cmd;
BlockDriverAIOCB *aiocb;
QEMUSGList *sg;
bool dma_started;
uint8_t sense[SCSI_SENSE_BUF_SIZE];
uint32_t sense_len;
bool enqueued;
bool io_canceled;
bool retry;
void *hba_private;
QTAILQ_ENTRY(SCSIRequest) next;
};
#define TYPE_SCSI_DEVICE "scsi-device"
#define SCSI_DEVICE(obj) \
OBJECT_CHECK(SCSIDevice, (obj), TYPE_SCSI_DEVICE)
#define SCSI_DEVICE_CLASS(klass) \
OBJECT_CLASS_CHECK(SCSIDeviceClass, (klass), TYPE_SCSI_DEVICE)
#define SCSI_DEVICE_GET_CLASS(obj) \
OBJECT_GET_CLASS(SCSIDeviceClass, (obj), TYPE_SCSI_DEVICE)
typedef struct SCSIDeviceClass {
DeviceClass parent_class;
int (*init)(SCSIDevice *dev);
void (*destroy)(SCSIDevice *s);
SCSIRequest *(*alloc_req)(SCSIDevice *s, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private);
void (*unit_attention_reported)(SCSIDevice *s);
} SCSIDeviceClass;
struct SCSIDevice
{
DeviceState qdev;
VMChangeStateEntry *vmsentry;
QEMUBH *bh;
uint32_t id;
BlockConf conf;
SCSISense unit_attention;
bool sense_is_ua;
uint8_t sense[SCSI_SENSE_BUF_SIZE];
uint32_t sense_len;
QTAILQ_HEAD(, SCSIRequest) requests;
uint32_t channel;
uint32_t lun;
int blocksize;
int type;
uint64_t max_lba;
};
extern const VMStateDescription vmstate_scsi_device;
#define VMSTATE_SCSI_DEVICE(_field, _state) { \
.name = (stringify(_field)), \
.size = sizeof(SCSIDevice), \
.vmsd = &vmstate_scsi_device, \
.flags = VMS_STRUCT, \
.offset = vmstate_offset_value(_state, _field, SCSIDevice), \
}
/* cdrom.c */
int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track);
int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num);
/* scsi-bus.c */
struct SCSIReqOps {
size_t size;
void (*free_req)(SCSIRequest *req);
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
void (*read_data)(SCSIRequest *req);
void (*write_data)(SCSIRequest *req);
void (*cancel_io)(SCSIRequest *req);
uint8_t *(*get_buf)(SCSIRequest *req);
void (*save_request)(QEMUFile *f, SCSIRequest *req);
void (*load_request)(QEMUFile *f, SCSIRequest *req);
};
struct SCSIBusInfo {
int tcq;
int max_channel, max_target, max_lun;
void (*transfer_data)(SCSIRequest *req, uint32_t arg);
void (*complete)(SCSIRequest *req, uint32_t arg, size_t resid);
void (*cancel)(SCSIRequest *req);
void (*hotplug)(SCSIBus *bus, SCSIDevice *dev);
void (*hot_unplug)(SCSIBus *bus, SCSIDevice *dev);
void (*change)(SCSIBus *bus, SCSIDevice *dev, SCSISense sense);
QEMUSGList *(*get_sg_list)(SCSIRequest *req);
void (*save_request)(QEMUFile *f, SCSIRequest *req);
void *(*load_request)(QEMUFile *f, SCSIRequest *req);
void (*free_request)(SCSIBus *bus, void *priv);
};
#define TYPE_SCSI_BUS "SCSI"
#define SCSI_BUS(obj) OBJECT_CHECK(SCSIBus, (obj), TYPE_SCSI_BUS)
struct SCSIBus {
BusState qbus;
int busnr;
SCSISense unit_attention;
const SCSIBusInfo *info;
};
void scsi_bus_new(SCSIBus *bus, DeviceState *host, const SCSIBusInfo *info);
static inline SCSIBus *scsi_bus_from_device(SCSIDevice *d)
{
return DO_UPCAST(SCSIBus, qbus, d->qdev.parent_bus);
}
SCSIDevice *scsi_bus_legacy_add_drive(SCSIBus *bus, BlockDriverState *bdrv,
int unit, bool removable, int bootindex,
const char *serial);
int scsi_bus_legacy_handle_cmdline(SCSIBus *bus);
/*
* Predefined sense codes
*/
/* No sense data available */
extern const struct SCSISense sense_code_NO_SENSE;
/* LUN not ready, Manual intervention required */
extern const struct SCSISense sense_code_LUN_NOT_READY;
/* LUN not ready, Medium not present */
extern const struct SCSISense sense_code_NO_MEDIUM;
/* LUN not ready, medium removal prevented */
extern const struct SCSISense sense_code_NOT_READY_REMOVAL_PREVENTED;
/* Hardware error, internal target failure */
extern const struct SCSISense sense_code_TARGET_FAILURE;
/* Illegal request, invalid command operation code */
extern const struct SCSISense sense_code_INVALID_OPCODE;
/* Illegal request, LBA out of range */
extern const struct SCSISense sense_code_LBA_OUT_OF_RANGE;
/* Illegal request, Invalid field in CDB */
extern const struct SCSISense sense_code_INVALID_FIELD;
/* Illegal request, Invalid field in parameter list */
extern const struct SCSISense sense_code_INVALID_PARAM;
/* Illegal request, Parameter list length error */
extern const struct SCSISense sense_code_INVALID_PARAM_LEN;
/* Illegal request, LUN not supported */
extern const struct SCSISense sense_code_LUN_NOT_SUPPORTED;
/* Illegal request, Saving parameters not supported */
extern const struct SCSISense sense_code_SAVING_PARAMS_NOT_SUPPORTED;
/* Illegal request, Incompatible format */
extern const struct SCSISense sense_code_INCOMPATIBLE_FORMAT;
/* Illegal request, medium removal prevented */
extern const struct SCSISense sense_code_ILLEGAL_REQ_REMOVAL_PREVENTED;
/* Command aborted, I/O process terminated */
extern const struct SCSISense sense_code_IO_ERROR;
/* Command aborted, I_T Nexus loss occurred */
extern const struct SCSISense sense_code_I_T_NEXUS_LOSS;
/* Command aborted, Logical Unit failure */
extern const struct SCSISense sense_code_LUN_FAILURE;
/* LUN not ready, Capacity data has changed */
extern const struct SCSISense sense_code_CAPACITY_CHANGED;
/* LUN not ready, Medium not present */
extern const struct SCSISense sense_code_UNIT_ATTENTION_NO_MEDIUM;
/* Unit attention, Power on, reset or bus device reset occurred */
extern const struct SCSISense sense_code_RESET;
/* Unit attention, Medium may have changed*/
extern const struct SCSISense sense_code_MEDIUM_CHANGED;
/* Unit attention, Reported LUNs data has changed */
extern const struct SCSISense sense_code_REPORTED_LUNS_CHANGED;
/* Unit attention, Device internal reset */
extern const struct SCSISense sense_code_DEVICE_INTERNAL_RESET;
/* Data Protection, Write Protected */
extern const struct SCSISense sense_code_WRITE_PROTECTED;
#define SENSE_CODE(x) sense_code_ ## x
uint32_t scsi_data_cdb_length(uint8_t *buf);
uint32_t scsi_cdb_length(uint8_t *buf);
int scsi_sense_valid(SCSISense sense);
int scsi_build_sense(uint8_t *in_buf, int in_len,
uint8_t *buf, int len, bool fixed);
SCSIRequest *scsi_req_alloc(const SCSIReqOps *reqops, SCSIDevice *d,
uint32_t tag, uint32_t lun, void *hba_private);
SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,
uint8_t *buf, void *hba_private);
int32_t scsi_req_enqueue(SCSIRequest *req);
void scsi_req_free(SCSIRequest *req);
SCSIRequest *scsi_req_ref(SCSIRequest *req);
void scsi_req_unref(SCSIRequest *req);
void scsi_req_build_sense(SCSIRequest *req, SCSISense sense);
void scsi_req_print(SCSIRequest *req);
void scsi_req_continue(SCSIRequest *req);
void scsi_req_data(SCSIRequest *req, int len);
void scsi_req_complete(SCSIRequest *req, int status);
uint8_t *scsi_req_get_buf(SCSIRequest *req);
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
void scsi_req_abort(SCSIRequest *req, int status);
void scsi_req_cancel(SCSIRequest *req);
void scsi_req_retry(SCSIRequest *req);
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);
void scsi_device_report_change(SCSIDevice *dev, SCSISense sense);
int scsi_device_get_sense(SCSIDevice *dev, uint8_t *buf, int len, bool fixed);
SCSIDevice *scsi_device_find(SCSIBus *bus, int channel, int target, int lun);
/* scsi-generic.c. */
extern const SCSIReqOps scsi_generic_req_ops;
#endif

80
include/hw/sd.h Normal file
View file

@ -0,0 +1,80 @@
/*
* SD Memory Card emulation. Mostly correct for MMC too.
*
* Copyright (c) 2006 Andrzej Zaborowski <balrog@zabor.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __hw_sd_h
#define __hw_sd_h 1
#define OUT_OF_RANGE (1 << 31)
#define ADDRESS_ERROR (1 << 30)
#define BLOCK_LEN_ERROR (1 << 29)
#define ERASE_SEQ_ERROR (1 << 28)
#define ERASE_PARAM (1 << 27)
#define WP_VIOLATION (1 << 26)
#define CARD_IS_LOCKED (1 << 25)
#define LOCK_UNLOCK_FAILED (1 << 24)
#define COM_CRC_ERROR (1 << 23)
#define ILLEGAL_COMMAND (1 << 22)
#define CARD_ECC_FAILED (1 << 21)
#define CC_ERROR (1 << 20)
#define SD_ERROR (1 << 19)
#define CID_CSD_OVERWRITE (1 << 16)
#define WP_ERASE_SKIP (1 << 15)
#define CARD_ECC_DISABLED (1 << 14)
#define ERASE_RESET (1 << 13)
#define CURRENT_STATE (7 << 9)
#define READY_FOR_DATA (1 << 8)
#define APP_CMD (1 << 5)
#define AKE_SEQ_ERROR (1 << 3)
#define OCR_CCS_BITN 30
typedef enum {
sd_none = -1,
sd_bc = 0, /* broadcast -- no response */
sd_bcr, /* broadcast with response */
sd_ac, /* addressed -- no data transfer */
sd_adtc, /* addressed with data transfer */
} sd_cmd_type_t;
typedef struct {
uint8_t cmd;
uint32_t arg;
uint8_t crc;
} SDRequest;
typedef struct SDState SDState;
SDState *sd_init(BlockDriverState *bs, bool is_spi);
int sd_do_command(SDState *sd, SDRequest *req,
uint8_t *response);
void sd_write_data(SDState *sd, uint8_t value);
uint8_t sd_read_data(SDState *sd);
void sd_set_cb(SDState *sd, qemu_irq readonly, qemu_irq insert);
bool sd_data_ready(SDState *sd);
void sd_enable(SDState *sd, bool enable);
#endif /* __hw_sd_h */

57
include/hw/sh4/sh.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef QEMU_SH_H
#define QEMU_SH_H
/* Definitions for SH board emulation. */
#include "hw/sh4/sh_intc.h"
#define A7ADDR(x) ((x) & 0x1fffffff)
#define P4ADDR(x) ((x) | 0xe0000000)
/* sh7750.c */
struct SH7750State;
struct MemoryRegion;
struct SH7750State *sh7750_init(CPUSH4State * cpu, struct MemoryRegion *sysmem);
typedef struct {
/* The callback will be triggered if any of the designated lines change */
uint16_t portamask_trigger;
uint16_t portbmask_trigger;
/* Return 0 if no action was taken */
int (*port_change_cb) (uint16_t porta, uint16_t portb,
uint16_t * periph_pdtra,
uint16_t * periph_portdira,
uint16_t * periph_pdtrb,
uint16_t * periph_portdirb);
} sh7750_io_device;
int sh7750_register_io_device(struct SH7750State *s,
sh7750_io_device * device);
/* sh_timer.c */
#define TMU012_FEAT_TOCR (1 << 0)
#define TMU012_FEAT_3CHAN (1 << 1)
#define TMU012_FEAT_EXTCLK (1 << 2)
void tmu012_init(struct MemoryRegion *sysmem, hwaddr base,
int feat, uint32_t freq,
qemu_irq ch0_irq, qemu_irq ch1_irq,
qemu_irq ch2_irq0, qemu_irq ch2_irq1);
/* sh_serial.c */
#define SH_SERIAL_FEAT_SCIF (1 << 0)
void sh_serial_init(MemoryRegion *sysmem,
hwaddr base, int feat,
uint32_t freq, CharDriverState *chr,
qemu_irq eri_source,
qemu_irq rxi_source,
qemu_irq txi_source,
qemu_irq tei_source,
qemu_irq bri_source);
/* sh7750.c */
qemu_irq sh7750_irl(struct SH7750State *s);
/* tc58128.c */
int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2);
#endif

83
include/hw/sh4/sh_intc.h Normal file
View file

@ -0,0 +1,83 @@
#ifndef __SH_INTC_H__
#define __SH_INTC_H__
#include "qemu-common.h"
#include "hw/irq.h"
#include "exec/address-spaces.h"
typedef unsigned char intc_enum;
struct intc_vect {
intc_enum enum_id;
unsigned short vect;
};
#define INTC_VECT(enum_id, vect) { enum_id, vect }
struct intc_group {
intc_enum enum_id;
intc_enum enum_ids[32];
};
#define INTC_GROUP(enum_id, ...) { enum_id, { __VA_ARGS__ } }
struct intc_mask_reg {
unsigned long set_reg, clr_reg, reg_width;
intc_enum enum_ids[32];
unsigned long value;
};
struct intc_prio_reg {
unsigned long set_reg, clr_reg, reg_width, field_width;
intc_enum enum_ids[16];
unsigned long value;
};
#define _INTC_ARRAY(a) a, ARRAY_SIZE(a)
struct intc_source {
unsigned short vect;
intc_enum next_enum_id;
int asserted; /* emulates the interrupt signal line from device to intc */
int enable_count;
int enable_max;
int pending; /* emulates the result of signal and masking */
struct intc_desc *parent;
};
struct intc_desc {
MemoryRegion iomem;
MemoryRegion *iomem_aliases;
qemu_irq *irqs;
struct intc_source *sources;
int nr_sources;
struct intc_mask_reg *mask_regs;
int nr_mask_regs;
struct intc_prio_reg *prio_regs;
int nr_prio_regs;
int pending; /* number of interrupt sources that has pending set */
};
int sh_intc_get_pending_vector(struct intc_desc *desc, int imask);
struct intc_source *sh_intc_source(struct intc_desc *desc, intc_enum id);
void sh_intc_toggle_source(struct intc_source *source,
int enable_adj, int assert_adj);
void sh_intc_register_sources(struct intc_desc *desc,
struct intc_vect *vectors,
int nr_vectors,
struct intc_group *groups,
int nr_groups);
int sh_intc_init(MemoryRegion *sysmem,
struct intc_desc *desc,
int nr_sources,
struct intc_mask_reg *mask_regs,
int nr_mask_regs,
struct intc_prio_reg *prio_regs,
int nr_prio_regs);
void sh_intc_set_irl(void *opaque, int n, int level);
#endif /* __SH_INTC_H__ */

View file

@ -0,0 +1,73 @@
#ifndef FIRMWARE_ABI_H
#define FIRMWARE_ABI_H
/* OpenBIOS NVRAM partition */
struct OpenBIOS_nvpart_v1 {
uint8_t signature;
uint8_t checksum;
uint16_t len; // BE, length divided by 16
char name[12];
};
#define OPENBIOS_PART_SYSTEM 0x70
#define OPENBIOS_PART_FREE 0x7f
static inline void
OpenBIOS_finish_partition(struct OpenBIOS_nvpart_v1 *header, uint32_t size)
{
unsigned int i, sum;
uint8_t *tmpptr;
// Length divided by 16
header->len = cpu_to_be16(size >> 4);
// Checksum
tmpptr = (uint8_t *)header;
sum = *tmpptr;
for (i = 0; i < 14; i++) {
sum += tmpptr[2 + i];
sum = (sum + ((sum & 0xff00) >> 8)) & 0xff;
}
header->checksum = sum & 0xff;
}
static inline uint32_t
OpenBIOS_set_var(uint8_t *nvram, uint32_t addr, const char *str)
{
uint32_t len;
len = strlen(str) + 1;
memcpy(&nvram[addr], str, len);
return addr + len;
}
/* Sun IDPROM structure at the end of NVRAM */
/* from http://www.squirrel.com/squirrel/sun-nvram-hostid.faq.html */
struct Sun_nvram {
uint8_t type; /* always 01 */
uint8_t machine_id; /* first byte of host id (machine type) */
uint8_t macaddr[6]; /* 6 byte ethernet address (first 3 bytes 08, 00, 20) */
uint8_t date[4]; /* date of manufacture */
uint8_t hostid[3]; /* remaining 3 bytes of host id (serial number) */
uint8_t checksum; /* bitwise xor of previous bytes */
};
static inline void
Sun_init_header(struct Sun_nvram *header, const uint8_t *macaddr, int machine_id)
{
uint8_t tmp, *tmpptr;
unsigned int i;
header->type = 1;
header->machine_id = machine_id & 0xff;
memcpy(&header->macaddr, macaddr, 6);
/* Calculate checksum */
tmp = 0;
tmpptr = (uint8_t *)header;
for (i = 0; i < 15; i++)
tmp ^= tmpptr[i];
header->checksum = tmp;
}
#endif /* FIRMWARE_ABI_H */

126
include/hw/sparc/grlib.h Normal file
View file

@ -0,0 +1,126 @@
/*
* QEMU GRLIB Components
*
* Copyright (c) 2010-2011 AdaCore
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef _GRLIB_H_
#define _GRLIB_H_
#include "hw/qdev.h"
#include "hw/sysbus.h"
/* Emulation of GrLib device is base on the GRLIB IP Core User's Manual:
* http://www.gaisler.com/products/grlib/grip.pdf
*/
/* IRQMP */
typedef void (*set_pil_in_fn) (void *opaque, uint32_t pil_in);
void grlib_irqmp_set_irq(void *opaque, int irq, int level);
void grlib_irqmp_ack(DeviceState *dev, int intno);
static inline
DeviceState *grlib_irqmp_create(hwaddr base,
CPUSPARCState *env,
qemu_irq **cpu_irqs,
uint32_t nr_irqs,
set_pil_in_fn set_pil_in)
{
DeviceState *dev;
assert(cpu_irqs != NULL);
dev = qdev_create(NULL, "grlib,irqmp");
qdev_prop_set_ptr(dev, "set_pil_in", set_pil_in);
qdev_prop_set_ptr(dev, "set_pil_in_opaque", env);
if (qdev_init(dev)) {
return NULL;
}
env->irq_manager = dev;
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
*cpu_irqs = qemu_allocate_irqs(grlib_irqmp_set_irq,
dev,
nr_irqs);
return dev;
}
/* GPTimer */
static inline
DeviceState *grlib_gptimer_create(hwaddr base,
uint32_t nr_timers,
uint32_t freq,
qemu_irq *cpu_irqs,
int base_irq)
{
DeviceState *dev;
int i;
dev = qdev_create(NULL, "grlib,gptimer");
qdev_prop_set_uint32(dev, "nr-timers", nr_timers);
qdev_prop_set_uint32(dev, "frequency", freq);
qdev_prop_set_uint32(dev, "irq-line", base_irq);
if (qdev_init(dev)) {
return NULL;
}
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
for (i = 0; i < nr_timers; i++) {
sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, cpu_irqs[base_irq + i]);
}
return dev;
}
/* APB UART */
static inline
DeviceState *grlib_apbuart_create(hwaddr base,
CharDriverState *serial,
qemu_irq irq)
{
DeviceState *dev;
dev = qdev_create(NULL, "grlib,apbuart");
qdev_prop_set_chr(dev, "chrdev", serial);
if (qdev_init(dev)) {
return NULL;
}
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
return dev;
}
#endif /* ! _GRLIB_H_ */

Some files were not shown because too many files have changed in this diff Show more