From patchwork Wed Oct 28 16:52:13 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?5q2m55SwID0/SVNPLTIwMjItSlA/Qj9JQnNrUWoxVFRHa2JLRUk9Pz0=?= X-Patchwork-Id: 37154 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3F56BB7B93 for ; Thu, 29 Oct 2009 08:55:26 +1100 (EST) Received: from localhost ([127.0.0.1]:52829 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N3D1t-0006Qz-PN for incoming@patchwork.ozlabs.org; Wed, 28 Oct 2009 14:13:53 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N3Bwm-0008Ed-DM for qemu-devel@nongnu.org; Wed, 28 Oct 2009 13:04:32 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N3Bwd-000866-SB for qemu-devel@nongnu.org; Wed, 28 Oct 2009 13:04:28 -0400 Received: from [199.232.76.173] (port=52302 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N3Bwc-00084Q-H5 for qemu-devel@nongnu.org; Wed, 28 Oct 2009 13:04:22 -0400 Received: from smtp-vip.mem.interq.net ([210.157.1.50]:34127 helo=smtp01.mem.internal-gmo) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N3Bwa-0004kX-TC for qemu-devel@nongnu.org; Wed, 28 Oct 2009 13:04:21 -0400 Received: (from root@localhost) by smtp01.mem.internal-gmo (8.13.8/8.12.6) id n9SH4J5F019239 for qemu-devel@nongnu.org; Thu, 29 Oct 2009 02:04:19 +0900 (JST) Received: (from root@localhost) by smtp01.mem.internal-gmo (8.13.8/8.12.6) id n9SGsIgB018818 for qemu-devel@nongnu.org; Thu, 29 Oct 2009 01:54:18 +0900 (JST) Received: (from root@localhost) by smtp01.mem.internal-gmo (8.13.8/8.12.6) id n9SGs7XF018723 for qemu-devel@nongnu.org; Thu, 29 Oct 2009 01:54:07 +0900 (JST) Received: from YOUR-BD18D6DD63.m1.interq.or.jp (ntymns039132.ymns.nt.ftth.ppp.infoweb.ne.jp [121.92.167.132]) by smtp01.mem.internal-gmo with ESMTP id n9SGs5ZY018647 for ; (me101664 for with PLAIN) Thu, 29 Oct 2009 01:54:07 +0900 (JST) Message-Id: <200910281652.AA00176@YOUR-BD18D6DD63.m1.interq.or.jp> Date: Thu, 29 Oct 2009 01:52:13 +0900 To: qemu-devel From: "TAKEDA, toshiya" MIME-Version: 1.0 X-Mailer: AL-Mail32 Version 1.13 X-detected-operating-system: by monty-python.gnu.org: Solaris 10 (beta) Subject: [Qemu-devel] [PATCH v3 13/25] piix_pci: add NEC PC-9821 family interface X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org diff --git a/qemu/hw/pci_ids.h b/qemu/hw/pci_ids.h index 63379c2..ca32656 100644 --- a/qemu/hw/pci_ids.h +++ b/qemu/hw/pci_ids.h @@ -57,6 +57,10 @@ #define PCI_VENDOR_ID_AMD 0x1022 #define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_VENDOR_ID_NEC 0x1033 +#define PCI_DEVICE_ID_NEC_CBUS_BRIDGE 0x0001 +#define PCI_DEVICE_ID_NEC_PC98_GRAPHICS 0x0009 + #define PCI_VENDOR_ID_MOTOROLA 0x1057 #define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 #define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 diff --git a/qemu/hw/piix_pci.c b/qemu/hw/piix_pci.c index ed036fe..8b7ff9d 100644 --- a/qemu/hw/piix_pci.c +++ b/qemu/hw/piix_pci.c @@ -44,6 +44,9 @@ struct PCII440FXState { target_phys_addr_t isa_page_descs[384 / 4]; uint8_t smm_enabled; PIIX3State *piix3; + /* NEC PC-9821 */ + uint8_t drb; + uint8_t errsts_no_error; }; static void i440fx_addr_writel(void* opaque, uint32_t addr, uint32_t val) @@ -139,6 +142,20 @@ void i440fx_init_memory_mappings(PCII440FXState *d) } } +void i440fx_update_isa_page_descs(PCII440FXState *d, + target_phys_addr_t start_addr, + ram_addr_t size) +{ + target_phys_addr_t addr; + + for (addr = start_addr; addr < start_addr + size; addr += 0x1000) { + if (addr >= 0xa0000 && addr < 0x100000) { + int i = (addr - 0xa0000) >> 12; + d->isa_page_descs[i] = cpu_get_physical_page_desc(addr); + } + } +} + static void i440fx_write_config(PCIDevice *dev, uint32_t address, uint32_t val, int len) { @@ -146,8 +163,17 @@ static void i440fx_write_config(PCIDevice *dev, /* XXX: implement SMRAM.D_LOCK */ pci_default_write_config(dev, address, val, len); - if ((address >= 0x59 && address <= 0x5f) || address == 0x72) + if ((address >= 0x59 && address <= 0x5f) || address == 0x72) { i440fx_update_memory_mappings(d); + } else if (address >= 0x60 && address <= 0x67) { + if (d->drb) { + d->dev.config[address] = d->drb; /* DRB */ + } + } else if (address == 0x91) { + if (d->errsts_no_error) { + d->dev.config[address] = 0x00; /* ERRSTS */ + } + } } static int i440fx_load_old(QEMUFile* f, void *opaque, int version_id) @@ -222,7 +248,9 @@ static int i440fx_initfn(PCIDevice *dev) return 0; } -PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic) +static PCIBus *i440fx_init_common(PCII440FXState **pi440fx_state, + int *piix3_devfn, qemu_irq *pic, + const char *piix3_name, int devfn) { DeviceState *dev; PCIBus *b; @@ -240,7 +268,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d); piix3 = DO_UPCAST(PIIX3State, dev, - pci_create_simple(b, -1, "PIIX3")); + pci_create_simple(b, devfn, piix3_name)); piix3->pic = pic; pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4); (*pi440fx_state)->piix3 = piix3; @@ -250,6 +278,11 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq * return b; } +PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic) +{ + return i440fx_init_common(pi440fx_state, piix3_devfn, pic, "PIIX3", -1); +} + /* PIIX3 PCI to ISA bridge */ static void piix3_set_irq(void *opaque, int irq_num, int level) @@ -346,6 +379,87 @@ static int piix3_initfn(PCIDevice *dev) return 0; } +/* NEC PC-9821 */ + +PCIBus *pc98_i440fx_init(PCII440FXState **pi440fx_state, + int *piix3_devfn, qemu_irq *pic, ram_addr_t ram_size) +{ + PCIBus *pci_bus; + PCII440FXState *d; + int i; + + /* XXX: implement PC-98 graphics bus bridge */ + pci_bus = i440fx_init_common(pi440fx_state, piix3_devfn, pic, + "STAR_ALPHA", 0x30); + d = *pi440fx_state; + d->drb = (uint8_t)(ram_size / 0x800000); + for (i = 0; i < 8; i++) { + d->dev.config[0x60 + i] = d->drb; + } + d->errsts_no_error = 1; + + return pci_bus; +} + +static void pc98_piix3_reset(void *opaque) +{ + static const struct { + int port; + uint32_t data; + } params[] = { + /* initialized in PC-9821Rv20 ITF */ + { 0x04, 0x3a000107 }, + { 0x40, 0x00ef0010 }, + { 0x44, 0xfffbfffa }, + { 0x48, 0xfffefffe }, + { 0x4c, 0x0000ffff }, + { 0x50, 0x0f020100 }, + { 0x54, 0x078a0504 }, + { 0x58, 0x0b8a0908 }, + { 0x5c, 0x8f0e0d8c }, + { 0x60, 0x80808080 }, + { 0x64, 0x18073f50 }, + { 0x68, 0xac000000 }, + { 0x6c, 0x00000000 }, + { 0x70, 0x0000c00c }, + { 0x78, 0x000fd9b2 }, + /* end of params */ + { -1, 0xffffffff }, + }; + PIIX3State *d = opaque; + uint8_t *pci_conf = d->dev.config; + int i; + + for (i = 0; params[i].port != -1; i++) { + pci_conf[params[i].port + 0] = (params[i].data >> 0) & 0xff; + pci_conf[params[i].port + 1] = (params[i].data >> 8) & 0xff; + pci_conf[params[i].port + 2] = (params[i].data >> 16) & 0xff; + pci_conf[params[i].port + 3] = (params[i].data >> 24) & 0xff; + } + + memset(d->pci_irq_levels, 0, sizeof(d->pci_irq_levels)); +} + +static int pc98_piix3_initfn(PCIDevice *dev) +{ + PIIX3State *d = DO_UPCAST(PIIX3State, dev, dev); + uint8_t *pci_conf; + + isa_bus_new(&d->dev.qdev); + vmstate_register(0, &vmstate_piix3, d); + + pci_conf = d->dev.config; + pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_NEC); + pci_config_set_device_id(pci_conf, PCI_DEVICE_ID_NEC_CBUS_BRIDGE); // STAR ALPHA + pci_config_set_class(pci_conf, PCI_CLASS_BRIDGE_OTHER); + pci_conf[PCI_HEADER_TYPE] = + PCI_HEADER_TYPE_NORMAL | PCI_HEADER_TYPE_MULTI_FUNCTION; // header_type = PCI_multifunction, generic + + pc98_piix3_reset(d); + qemu_register_reset(pc98_piix3_reset, d); + return 0; +} + static PCIDeviceInfo i440fx_info[] = { { .qdev.name = "i440FX", @@ -361,6 +475,12 @@ static PCIDeviceInfo i440fx_info[] = { .qdev.no_user = 1, .init = piix3_initfn, },{ + .qdev.name = "STAR_ALPHA", + .qdev.desc = "ISA bridge", + .qdev.size = sizeof(PIIX3State), + .qdev.no_user = 1, + .init = pc98_piix3_initfn, + },{ /* end of list */ } };