2018-10-21 20:27:57 +02:00
|
|
|
/*
|
2022-11-05 21:44:11 -04:00
|
|
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
|
|
|
|
* running old operating systems and software designed for IBM
|
|
|
|
|
* PC systems and compatibles from 1981 through fairly recent
|
|
|
|
|
* system designs based on the PCI bus.
|
2018-10-21 20:27:57 +02:00
|
|
|
*
|
2022-11-05 21:44:11 -04:00
|
|
|
* This file is part of the 86Box distribution.
|
2018-10-21 20:27:57 +02:00
|
|
|
*
|
2022-11-05 21:44:11 -04:00
|
|
|
* Definitions for the PCI handler module.
|
2018-10-21 20:27:57 +02:00
|
|
|
*
|
2020-03-25 00:46:02 +02:00
|
|
|
*
|
2018-10-21 20:27:57 +02:00
|
|
|
*
|
2022-11-05 21:44:11 -04:00
|
|
|
* Authors: Miran Grca, <mgrca8@gmail.com>
|
2018-10-21 20:27:57 +02:00
|
|
|
*
|
2023-08-07 03:04:52 +02:00
|
|
|
* Copyright 2023 Miran Grca.
|
2018-10-21 20:27:57 +02:00
|
|
|
*/
|
|
|
|
|
#ifndef EMU_PCI_H
|
2022-09-18 17:15:38 -04:00
|
|
|
#define EMU_PCI_H
|
2017-06-21 19:42:36 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
#define PCI_REG_VENDOR_ID_L 0x00
|
|
|
|
|
#define PCI_REG_VENDOR_ID_H 0x01
|
|
|
|
|
#define PCI_REG_DEVICE_ID_L 0x02
|
|
|
|
|
#define PCI_REG_DEVICE_ID_H 0x03
|
|
|
|
|
#define PCI_REG_COMMAND_L 0x04
|
|
|
|
|
#define PCI_REG_COMMAND_H 0x05
|
|
|
|
|
#define PCI_REG_STATUS_L 0x06
|
|
|
|
|
#define PCI_REG_STATUS_H 0x07
|
|
|
|
|
#define PCI_REG_REVISION 0x08
|
|
|
|
|
#define PCI_REG_PROG_IF 0x09
|
|
|
|
|
#define PCI_REG_SUBCLASS 0x0a
|
|
|
|
|
#define PCI_REG_CLASS 0x0b
|
|
|
|
|
#define PCI_REG_CACHELINE_SIZE 0x0c
|
|
|
|
|
#define PCI_REG_LATENCY_TIMER 0x0d
|
|
|
|
|
#define PCI_REG_HEADER_TYPE 0x0e
|
|
|
|
|
#define PCI_REG_BIST 0x0f
|
|
|
|
|
|
|
|
|
|
#define PCI_COMMAND_L_IO 0x01
|
|
|
|
|
#define PCI_COMMAND_L_MEM 0x02
|
|
|
|
|
#define PCI_COMMAND_L_BM 0x04
|
|
|
|
|
#define PCI_COMMAND_L_SPECIAL 0x08
|
|
|
|
|
#define PCI_COMMAND_L_MEM_WIEN 0x10
|
|
|
|
|
#define PCI_COMMAND_L_VGASNOOP 0x20
|
|
|
|
|
#define PCI_COMMAND_L_PARITY 0x40
|
|
|
|
|
|
|
|
|
|
#define PCI_COMMAND_H_SERR 0x01
|
|
|
|
|
#define PCI_COMMAND_H_FAST_B2B 0x02
|
|
|
|
|
#define PCI_COMMAND_H_INT_DIS 0x04
|
|
|
|
|
|
|
|
|
|
#define PCI_STATUS_L_INT 0x08
|
|
|
|
|
#define PCI_STATUS_L_CAPAB 0x10
|
|
|
|
|
#define PCI_STATUS_L_66MHZ 0x20
|
|
|
|
|
#define PCI_STATUS_L_FAST_B2B 0x80
|
|
|
|
|
|
|
|
|
|
#define PCI_STATUS_H_MDPERR 0x01 /* Master Data Parity Error */
|
|
|
|
|
#define PCI_STATUS_H_DEVSEL 0x06
|
|
|
|
|
#define PCI_STATUS_H_STA 0x08 /* Signaled Target Abort */
|
|
|
|
|
#define PCI_STATUS_H_RTA 0x10 /* Received Target Abort */
|
|
|
|
|
#define PCI_STATUS_H_RMA 0x20 /* Received Master Abort */
|
|
|
|
|
#define PCI_STATUS_H_SSE 0x40 /* Signaled System Error */
|
|
|
|
|
#define PCI_STATUS_H_DPERR 0x80 /* Detected Parity Error */
|
|
|
|
|
|
|
|
|
|
#define PCI_DEVSEL_FAST 0x00
|
|
|
|
|
#define PCI_DEVSEL_MEDIUM 0x02
|
|
|
|
|
#define PCI_DEVSEL_SLOW 0x04
|
|
|
|
|
|
|
|
|
|
#define FLAG_MECHANISM_1 0x00000001
|
|
|
|
|
#define FLAG_MECHANISM_2 0x00000002
|
|
|
|
|
#define FLAG_MECHANISM_SWITCH 0x00000004
|
|
|
|
|
#define FLAG_CONFIG_IO_ON 0x00000008
|
|
|
|
|
#define FLAG_CONFIG_DEV0_IO_ON 0x00000010
|
|
|
|
|
#define FLAG_CONFIG_M1_IO_ON 0x00000020
|
|
|
|
|
#define FLAG_NO_IRQ_STEERING 0x00000040
|
|
|
|
|
#define FLAG_NO_BRIDGES 0x00000080
|
|
|
|
|
|
|
|
|
|
#define FLAG_MECHANISM_MASK FLAG_MECHANISM_1 | FLAG_MECHANISM_2
|
|
|
|
|
#define FLAG_MASK 0x0000007f
|
|
|
|
|
|
|
|
|
|
#define PCI_INTA 1
|
|
|
|
|
#define PCI_INTB 2
|
|
|
|
|
#define PCI_INTC 3
|
|
|
|
|
#define PCI_INTD 4
|
|
|
|
|
|
|
|
|
|
#define PCI_MIRQ0 0
|
|
|
|
|
#define PCI_MIRQ1 1
|
|
|
|
|
#define PCI_MIRQ2 2
|
|
|
|
|
#define PCI_MIRQ3 3
|
|
|
|
|
#define PCI_MIRQ4 4
|
|
|
|
|
#define PCI_MIRQ5 5
|
|
|
|
|
#define PCI_MIRQ6 6
|
|
|
|
|
#define PCI_MIRQ7 7
|
|
|
|
|
|
|
|
|
|
#define PCI_IRQ_DISABLED -1
|
|
|
|
|
|
|
|
|
|
#define PCI_ADD_STRICT 0x40
|
|
|
|
|
#define PCI_ADD_MASK (PCI_ADD_STRICT - 1)
|
|
|
|
|
#define PCI_ADD_VFIO 0x80
|
|
|
|
|
#define PCI_ADD_VFIO_MASK (PCI_ADD_VFIO - 1)
|
|
|
|
|
|
|
|
|
|
#define PCI_CARD_VFIO PCI_ADD_VFIO
|
|
|
|
|
|
|
|
|
|
#define PCI_BUS_INVALID 0xff
|
|
|
|
|
|
|
|
|
|
#define PCI_IGNORE_NO_SLOT 0xff
|
|
|
|
|
|
|
|
|
|
/* The number of an invalid PCI card. */
|
|
|
|
|
#define PCI_CARD_INVALID 0xef
|
|
|
|
|
/* PCI cards (currently 32). */
|
|
|
|
|
#define PCI_CARDS_NUM 0x20
|
|
|
|
|
#define PCI_CARD_MAX (PCI_CARDS_NUM - 1)
|
|
|
|
|
/* The number of PCI card INT pins - always at 4 per the PCI specification. */
|
|
|
|
|
#define PCI_INT_PINS_NUM 4
|
|
|
|
|
/* The base for MIRQ lines accepted by pci_irq(). */
|
|
|
|
|
#define PCI_MIRQ_BASE PCI_CARDS_NUM
|
|
|
|
|
/* PCI MIRQ lines (currently 8, this many are needed by the ALi M1543(C). */
|
|
|
|
|
#define PCI_MIRQS_NUM 8
|
|
|
|
|
#define PCI_MIRQ_MAX (PCI_MIRQS_NUM - 1)
|
|
|
|
|
/* The base for direct IRQ lines accepted by pci_irq(). */
|
|
|
|
|
#define PCI_DIRQ_BASE 0xf0
|
|
|
|
|
/* PCI direct IRQ lines (currently 16 because we only emulate the legacy PIC). */
|
|
|
|
|
#define PCI_DIRQS_NUM 16
|
|
|
|
|
#define PCI_DIRQ_MAX (PCI_DIRQS_NUM - 1)
|
|
|
|
|
/* PCI IRQ routings (currently 16, this many are needed by the OPTi 822). */
|
|
|
|
|
#define PCI_IRQS_NUM 16
|
|
|
|
|
#define PCI_IRQ_MAX (PCI_IRQS_NUM - 1)
|
|
|
|
|
|
|
|
|
|
/* Legacy flags. */
|
|
|
|
|
#define PCI_REG_COMMAND PCI_REG_COMMAND_L
|
|
|
|
|
|
|
|
|
|
#define PCI_COMMAND_IO PCI_COMMAND_L_IO
|
|
|
|
|
#define PCI_COMMAND_MEM PCI_COMMAND_L_MEM
|
|
|
|
|
|
|
|
|
|
#define PCI_CONFIG_TYPE_1 FLAG_MECHANISM_1
|
|
|
|
|
#define PCI_CONFIG_TYPE_2 FLAG_MECHANISM_2
|
|
|
|
|
|
|
|
|
|
#define PCI_CAN_SWITCH_TYPE FLAG_MECHANISM_SWITCH
|
|
|
|
|
#define PCI_ALWAYS_EXPOSE_DEV0 FLAG_CONFIG_DEV0_IO_ON
|
|
|
|
|
#define PCI_NO_IRQ_STEERING FLAG_NO_IRQ_STEERING
|
|
|
|
|
#define PCI_NO_BRIDGES FLAG_NO_BRIDGES
|
|
|
|
|
|
|
|
|
|
#define PCI_CONFIG_TYPE_MASK FLAG_MECHANISM_MASK
|
|
|
|
|
|
|
|
|
|
#define bar_t pci_bar_t
|
|
|
|
|
#define trc_init pci_trc_init
|
|
|
|
|
|
|
|
|
|
#define pci_register_slot(card, type, inta, intb, intc, intd) \
|
|
|
|
|
pci_register_bus_slot(0, card, type, inta, intb, intc, intd)
|
|
|
|
|
|
|
|
|
|
#define pci_set_mirq(mirq, level, irq_state) \
|
|
|
|
|
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 1, irq_state)
|
|
|
|
|
#define pci_set_irq(slot, pci_int, irq_state) \
|
|
|
|
|
pci_irq(slot, pci_int, 0, 1, irq_state)
|
|
|
|
|
#define pci_clear_mirq(mirq, level, irq_state) \
|
|
|
|
|
pci_irq(PCI_MIRQ_BASE | mirq, 0, level, 0, irq_state)
|
|
|
|
|
#define pci_clear_irq(slot, pci_int, irq_state) \
|
|
|
|
|
pci_irq(slot, pci_int, 0, 0, irq_state)
|
2021-08-21 18:19:10 +02:00
|
|
|
|
2018-10-21 20:27:57 +02:00
|
|
|
enum {
|
2023-06-26 12:47:04 -04:00
|
|
|
PCI_CARD_NORTHBRIDGE = 0,
|
2023-08-07 03:04:52 +02:00
|
|
|
PCI_CARD_NORTHBRIDGE_SEC = 1,
|
|
|
|
|
PCI_CARD_AGPBRIDGE = 2,
|
|
|
|
|
PCI_CARD_SOUTHBRIDGE = 3,
|
|
|
|
|
PCI_CARD_SOUTHBRIDGE_IDE = 4,
|
|
|
|
|
PCI_CARD_SOUTHBRIDGE_PMU = 5,
|
|
|
|
|
PCI_CARD_SOUTHBRIDGE_USB = 6,
|
2023-06-26 12:47:04 -04:00
|
|
|
PCI_CARD_AGP = 0x0f,
|
|
|
|
|
PCI_CARD_NORMAL = 0x10,
|
|
|
|
|
PCI_CARD_VIDEO = 0x11,
|
2023-08-07 03:04:52 +02:00
|
|
|
PCI_CARD_HANGUL = 0x12,
|
|
|
|
|
PCI_CARD_IDE = 0x13,
|
|
|
|
|
PCI_CARD_SCSI = 0x14,
|
|
|
|
|
PCI_CARD_SOUND = 0x15,
|
|
|
|
|
PCI_CARD_MODEM = 0x16,
|
|
|
|
|
PCI_CARD_NETWORK = 0x17,
|
|
|
|
|
PCI_CARD_UART = 0x18,
|
|
|
|
|
PCI_CARD_USB = 0x19,
|
|
|
|
|
PCI_CARD_BRIDGE = 0x1a
|
2017-08-30 04:49:20 +02:00
|
|
|
};
|
|
|
|
|
|
2020-02-29 19:12:23 +01:00
|
|
|
enum {
|
2023-06-26 12:47:04 -04:00
|
|
|
PCI_ADD_NORTHBRIDGE = 0,
|
2023-08-07 03:04:52 +02:00
|
|
|
PCI_ADD_NORTHBRIDGE_SEC = 1,
|
|
|
|
|
PCI_ADD_AGPBRIDGE = 2,
|
|
|
|
|
PCI_ADD_SOUTHBRIDGE = 3,
|
|
|
|
|
PCI_ADD_SOUTHBRIDGE_IDE = 4,
|
|
|
|
|
PCI_ADD_SOUTHBRIDGE_PMU = 5,
|
|
|
|
|
PCI_ADD_SOUTHBRIDGE_USB = 6,
|
2023-06-26 12:47:04 -04:00
|
|
|
PCI_ADD_AGP = 0x0f,
|
|
|
|
|
PCI_ADD_NORMAL = 0x10,
|
|
|
|
|
PCI_ADD_VIDEO = 0x11,
|
2023-08-07 03:04:52 +02:00
|
|
|
PCI_ADD_HANGUL = 0x12,
|
|
|
|
|
PCI_ADD_IDE = 0x13,
|
|
|
|
|
PCI_ADD_SCSI = 0x14,
|
|
|
|
|
PCI_ADD_SOUND = 0x15,
|
|
|
|
|
PCI_ADD_MODEM = 0x16,
|
|
|
|
|
PCI_ADD_NETWORK = 0x17,
|
|
|
|
|
PCI_ADD_UART = 0x18,
|
|
|
|
|
PCI_ADD_USB = 0x19,
|
|
|
|
|
PCI_ADD_BRIDGE = 0x1a
|
2020-02-29 19:12:23 +01:00
|
|
|
};
|
2017-08-30 04:49:20 +02:00
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
|
uint32_t addr;
|
2023-07-06 19:55:59 +02:00
|
|
|
uint8_t addr_regs[4];
|
2023-08-07 03:04:52 +02:00
|
|
|
} pci_bar_t;
|
|
|
|
|
|
|
|
|
|
extern int pci_burst_time;
|
|
|
|
|
extern int agp_burst_time;
|
|
|
|
|
extern int pci_nonburst_time;
|
|
|
|
|
extern int agp_nonburst_time;
|
2017-11-05 01:57:04 -05:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern int pci_flags;
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern uint32_t pci_base;
|
|
|
|
|
extern uint32_t pci_size;
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern void pci_set_irq_routing(int pci_int, int irq);
|
|
|
|
|
extern void pci_set_irq_level(int pci_int, int level);
|
|
|
|
|
extern void pci_enable_mirq(int mirq);
|
|
|
|
|
extern void pci_set_mirq_routing(int mirq, int irq);
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* PCI raise IRQ: the first parameter is slot if < PCI_MIRQ_BASE, MIRQ if >= PCI_MIRQ_BASE
|
|
|
|
|
and < PCI_DIRQ_BASE, and direct IRQ line if >= PCI_DIRQ_BASE (RichardG's
|
|
|
|
|
hack that may no longer be needed). */
|
|
|
|
|
extern void pci_irq(uint8_t slot, uint8_t pci_int, int level, int set, uint8_t *irq_state);
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern uint8_t pci_get_int(uint8_t slot, uint8_t pci_int);
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Relocate a PCI device to a new slot, required for the configurable
|
|
|
|
|
IDSEL's of ALi M1543(c). */
|
|
|
|
|
extern void pci_relocate_slot(int type, int new_slot);
|
2023-07-06 19:55:59 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Write PCI enable/disable key, split for the ALi M1435. */
|
|
|
|
|
extern void pci_key_write(uint8_t val);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Set PMC (ie. change PCI configuration mechanism), 0 = #2, 1 = #1. */
|
|
|
|
|
extern void pci_set_pmc(uint8_t pmc);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern void pci_pic_reset(void);
|
|
|
|
|
extern void pci_reset(void);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Needed for the io.c handling of configuration mechanism #2 ports C000-CFFF. */
|
|
|
|
|
extern void pci_write(uint16_t port, uint8_t val, void *priv);
|
|
|
|
|
extern void pci_writew(uint16_t port, uint16_t val, void *priv);
|
|
|
|
|
extern void pci_writel(uint16_t port, uint32_t val, void *priv);
|
|
|
|
|
extern uint8_t pci_read(uint16_t port, void *priv);
|
|
|
|
|
extern uint16_t pci_readw(uint16_t port, void *priv);
|
|
|
|
|
extern uint32_t pci_readl(uint16_t port, void *priv);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern uint8_t pci_register_bus(void);
|
|
|
|
|
extern void pci_remap_bus(uint8_t bus_index, uint8_t bus_number);
|
|
|
|
|
extern void pci_register_bus_slot(int bus, int card, int type, int inta, int intb, int intc, int intd);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Add a PCI card. */
|
|
|
|
|
extern void pci_add_card(uint8_t add_type, uint8_t (*read)(int func, int addr, void *priv),
|
|
|
|
|
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv, uint8_t *slot);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Add an instance of the PCI bridge. */
|
2023-08-10 01:37:33 +02:00
|
|
|
extern void pci_add_bridge(uint8_t agp, uint8_t (*read)(int func, int addr, void *priv),
|
|
|
|
|
void (*write)(int func, int addr, uint8_t val, void *priv), void *priv,
|
|
|
|
|
uint8_t *slot);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* Register the cards that have been added into slots. */
|
|
|
|
|
extern void pci_register_cards(void);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
extern void pci_init(int flags);
|
2021-12-19 23:41:23 +01:00
|
|
|
|
2023-08-07 03:04:52 +02:00
|
|
|
/* PCI bridge stuff. */
|
|
|
|
|
extern void pci_bridge_set_ctl(void *priv, uint8_t ctl);
|
2018-10-21 20:27:57 +02:00
|
|
|
|
2020-09-19 00:56:12 -03:00
|
|
|
#ifdef EMU_DEVICE_H
|
|
|
|
|
extern const device_t dec21150_device;
|
|
|
|
|
|
2021-07-04 18:16:35 +02:00
|
|
|
extern const device_t ali5243_agp_device;
|
2021-07-12 05:56:06 +02:00
|
|
|
extern const device_t ali5247_agp_device;
|
2020-09-19 00:56:12 -03:00
|
|
|
extern const device_t i440lx_agp_device;
|
|
|
|
|
extern const device_t i440bx_agp_device;
|
|
|
|
|
extern const device_t i440gx_agp_device;
|
2020-09-19 01:29:35 -03:00
|
|
|
extern const device_t via_vp3_agp_device;
|
|
|
|
|
extern const device_t via_mvp3_agp_device;
|
|
|
|
|
extern const device_t via_apro_agp_device;
|
2020-10-20 20:45:12 +03:00
|
|
|
extern const device_t via_vt8601_agp_device;
|
2020-09-19 00:56:12 -03:00
|
|
|
#endif
|
|
|
|
|
|
2022-09-18 17:15:38 -04:00
|
|
|
#endif /*EMU_PCI_H*/
|