From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LoIc7-0008I0-UE for qemu-devel@nongnu.org; Mon, 30 Mar 2009 10:37:24 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LoIc2-00088r-2C for qemu-devel@nongnu.org; Mon, 30 Mar 2009 10:37:22 -0400 Received: from [199.232.76.173] (port=54223 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LoIc1-00088W-JT for qemu-devel@nongnu.org; Mon, 30 Mar 2009 10:37:17 -0400 Received: from mel.act-europe.fr ([212.99.106.210]:60605) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LoIc0-0000xT-Ny for qemu-devel@nongnu.org; Mon, 30 Mar 2009 10:37:17 -0400 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 630D729003C for ; Mon, 30 Mar 2009 16:36:36 +0200 (CEST) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ANNJs5szYVV5 for ; Mon, 30 Mar 2009 16:36:35 +0200 (CEST) Received: from ulanbator.act-europe.fr (ulanbator.act-europe.fr [10.10.1.67]) by mel.act-europe.fr (Postfix) with ESMTP id 1F256290046 for ; Mon, 30 Mar 2009 16:36:35 +0200 (CEST) From: Tristan Gingold Date: Mon, 30 Mar 2009 16:36:25 +0200 Message-Id: <1238423794-25455-11-git-send-email-gingold@adacore.com> In-Reply-To: <1238423794-25455-10-git-send-email-gingold@adacore.com> References: <1238423794-25455-1-git-send-email-gingold@adacore.com> <1238423794-25455-2-git-send-email-gingold@adacore.com> <1238423794-25455-3-git-send-email-gingold@adacore.com> <1238423794-25455-4-git-send-email-gingold@adacore.com> <1238423794-25455-5-git-send-email-gingold@adacore.com> <1238423794-25455-6-git-send-email-gingold@adacore.com> <1238423794-25455-7-git-send-email-gingold@adacore.com> <1238423794-25455-8-git-send-email-gingold@adacore.com> <1238423794-25455-9-git-send-email-gingold@adacore.com> <1238423794-25455-10-git-send-email-gingold@adacore.com> Subject: [Qemu-devel] [PATCH 10/19] Add ali1543 super IO pci device. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a very partial implementation just enough for es40 firmware. Signed-off-by: Tristan Gingold --- hw/ali1543.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/pci.h | 5 ++ hw/pci_ids.h | 3 + 3 files changed, 158 insertions(+), 0 deletions(-) create mode 100644 hw/ali1543.c diff --git a/hw/ali1543.c b/hw/ali1543.c new file mode 100644 index 0000000..c4b0572 --- /dev/null +++ b/hw/ali1543.c @@ -0,0 +1,150 @@ +/* + * QEMU Ali 1543c emulation + * + * Copyright (c) 2009 AdaCore + * + * Written by Tristan Gingold. + * + * This work is licensed under the GNU GPL license version 2 or later. + * + */ +#include +#include +#include "hw.h" +#include "net.h" +#include "sysemu.h" +#include "devices.h" +#include "boards.h" +#include "pc.h" +#include "isa.h" +#include "qemu-char.h" +#include "pci.h" + +/* Ali 1543 is a south-bridge super-IO. It contains a DMA, a PIC, a PIT, + a ps/2 kbd interface, 2 IDE controller, 1 USB controller (OHCI), 1 FDC, + 2 serials ports, 1 parallel port and a PMU. */ + +//#define DEBUG_CFG + +struct ALI1543State { + PCIDevice pci; + + qemu_irq *irq; /* Upstream handler. */ + PITState *pit; + qemu_irq *i8259; + + /* Configuration. */ + enum cfg_state { CFG_SNOOP, CFG_51, CFG_EN } cfg_state; + unsigned char cfg_index; +}; + +static void ali_cfg_write(void *opaque, uint32_t addr, uint32_t val) +{ + ALI1543State *ali = opaque; + + if ((addr & 1) == 0) { + switch (ali->cfg_state) { + case CFG_SNOOP: + if (val == 0x51) + ali->cfg_state = CFG_51; + else + qemu_log("ali1543-cfg: write %02x to cfg_port\n", val); + break; + case CFG_51: + if (val == 0x23) + ali->cfg_state = CFG_EN; + else { + qemu_log("ali1543-cfg: write %02x to cfg_port (51)\n", val); + ali->cfg_state = CFG_SNOOP; + } + break; + case CFG_EN: + ali->cfg_index = val; + break; + } + } + else { +#ifdef DEBUG_CFG + qemu_log("ali1543-cfg: write %02x to cfg reg %02x (addr=%x)\n", + val, ali->cfg_index, addr); +#endif + } +} + +static uint32_t ali_cfg_read(void *opaque, uint32_t addr) +{ + ALI1543State *ali = opaque; + uint32_t res; + + if ((addr & 1) == 0) { + if (ali->cfg_state != CFG_EN) { + qemu_log("ali1543-cfg: read fromcfg_port\n"); + res = 0; + } + else + res = ali->cfg_index; + } + else { + switch (ali->cfg_index) { + case 0x20: + res = 0x43; + break; + case 0x21: + res = 0x15; + break; + default: +#ifdef DEBUG_CFG + qemu_log("ali1543-cfg: read from reg %02x\n", ali->cfg_index); +#endif + res = 0; + break; + } + } + return res; +} + +ALI1543State *ali1543_init (PCIBus *bus, int devfn, qemu_irq irq) +{ + ALI1543State *ali; + uint8_t *pci_conf; + + ali = (ALI1543State*)pci_register_device(bus, "Ali1543", + sizeof(ALI1543State), + devfn, NULL, NULL); + + pci_conf = ali->pci.config; + + pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_AL); + pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_AL_M1533); + pci_conf[0x08] = 0xc3; // Revision + pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_ISA); + pci_conf[0x2c] = 0; // Subsystem + pci_conf[0x2d] = 0; + pci_conf[0x2e] = 0; + pci_conf[0x2f] = 0; + + register_ioport_read(0x370, 2, 1, ali_cfg_read, ali); + register_ioport_write(0x370, 2, 1, ali_cfg_write, ali); + + ali->i8259 = i8259_init(irq); + + /* serial_init already handles NULL CharDriverState but this code adds + a more useful label. */ + if (serial_hds[0] == NULL) + serial_hds[0] = qemu_chr_open("com1", "nul", NULL); + if (serial_hds[1] == NULL) + serial_hds[1] = qemu_chr_open("com2", "nul", NULL); + + serial_init(0x3f8, ali->i8259[4], 115200, serial_hds[0]); + serial_init(0x2f8, ali->i8259[3], 115200, serial_hds[1]); + ali->pit = pit_init(0x40, ali->i8259[0]); + pcspk_init(ali->pit); + DMA_init(0); + + return ali; +} + +qemu_irq ali1543_get_irq(ALI1543State *c, int n) +{ + return c->i8259[n]; +} diff --git a/hw/pci.h b/hw/pci.h index 831f1b1..e4e0738 100644 --- a/hw/pci.h +++ b/hw/pci.h @@ -261,4 +261,9 @@ PCIBus *pci_apb_init(target_phys_addr_t special_base, PCIBus *sh_pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq, qemu_irq *pic, int devfn_min, int nirq); +/* ali1543.c */ +typedef struct ALI1543State ALI1543State; +ALI1543State *ali1543_init (PCIBus *bus, int devfn, qemu_irq irq); +qemu_irq ali1543_get_irq(ALI1543State *c, int n); + #endif diff --git a/hw/pci_ids.h b/hw/pci_ids.h index 427fcd5..4119ead 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -70,6 +70,9 @@ #define PCI_VENDOR_ID_CMD 0x1095 #define PCI_DEVICE_ID_CMD_646 0x0646 +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_DEVICE_ID_AL_M1533 0x1533 + #define PCI_VENDOR_ID_REALTEK 0x10ec #define PCI_DEVICE_ID_REALTEK_8139 0x8139 -- 1.6.2