|
| 1 | +# --- T2-COPYRIGHT-NOTE-BEGIN --- |
| 2 | +# This copyright note is auto-generated by ./scripts/Create-CopyPatch. |
| 3 | +# |
| 4 | +# T2 SDE: package/.../kvm/03-qemu-lpc.patch |
| 5 | +# Copyright (C) 2011 The T2 SDE Project |
| 6 | +# |
| 7 | +# More information can be found in the files COPYING and README. |
| 8 | +# |
| 9 | +# This patch file is dual-licensed. It is available under the license the |
| 10 | +# patched project is licensed under, as long as it is an OpenSource license |
| 11 | +# as defined at http://www.opensource.org/ (e.g. BSD, X11) or under the terms |
| 12 | +# of the GNU General Public License as published by the Free Software |
| 13 | +# Foundation; either version 2 of the License, or (at your option) any later |
| 14 | +# version. |
| 15 | +# --- T2-COPYRIGHT-NOTE-END --- |
| 16 | + |
| 17 | +From: Alexander Graf < [email protected]> |
| 18 | +Date: Tue, 30 Nov 2010 14:24:04 +0000 (+0100) |
| 19 | +Subject: Add LPC device emulation |
| 20 | +X-Git-Url: http://repo.or.cz/w/qemu/agraf.git/commitdiff_plain/71f1f25277f2e2035eec1badf76b6035a0390efa |
| 21 | + |
| 22 | +Add LPC device emulation |
| 23 | + |
| 24 | +Signed-off-by: Alexander Graf < [email protected]> |
| 25 | +--- |
| 26 | + |
| 27 | +--- qemu-kvm-0.15.0/Makefile.objs.vanilla 2011-12-07 19:15:50.237204501 +0000 |
| 28 | ++++ qemu-kvm-0.15.0/Makefile.objs 2011-12-07 19:16:32.413199084 +0000 |
| 29 | +@@ -205,7 +205,7 @@ |
| 30 | + hw-obj-$(CONFIG_APM) += pm_smbus.o apm.o |
| 31 | + hw-obj-$(CONFIG_DMA) += dma.o |
| 32 | + hw-obj-$(CONFIG_HPET) += hpet.o |
| 33 | +-hw-obj-$(CONFIG_APPLESMC) += applesmc.o |
| 34 | ++hw-obj-$(CONFIG_APPLESMC) += applesmc.o lpc.o |
| 35 | + hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o |
| 36 | + hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o |
| 37 | + hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o |
| 38 | +--- /dev/null |
| 39 | ++++ b/hw/lpc.c |
| 40 | +@@ -0,0 +1,200 @@ |
| 41 | ++/* |
| 42 | ++ * Low Pin Count emulation |
| 43 | ++ * |
| 44 | ++ * Copyright (c) 2007 Alexander Graf |
| 45 | ++ * |
| 46 | ++ * This library is free software; you can redistribute it and/or |
| 47 | ++ * modify it under the terms of the GNU Lesser General Public |
| 48 | ++ * License as published by the Free Software Foundation; either |
| 49 | ++ * version 2 of the License, or (at your option) any later version. |
| 50 | ++ * |
| 51 | ++ * This library is distributed in the hope that it will be useful, |
| 52 | ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 53 | ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 54 | ++ * Lesser General Public License for more details. |
| 55 | ++ * |
| 56 | ++ * You should have received a copy of the GNU Lesser General Public |
| 57 | ++ * License along with this library; if not, write to the Free Software |
| 58 | ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 59 | ++ * |
| 60 | ++ * ***************************************************************** |
| 61 | ++ * |
| 62 | ++ * This driver emulates an ICH-7 LPC partially. The LPC is basically the |
| 63 | ++ * same as the ISA-bridge in the existing PIIX implementation, but |
| 64 | ++ * more recent and includes support for HPET and Power Management. |
| 65 | ++ * |
| 66 | ++ * |
| 67 | ++ * 00:1f.0 0601: 8086:27b9 (rev 02) |
| 68 | ++ * Subsystem: 1025:0107 |
| 69 | ++ * Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- |
| 70 | ++ * Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- |
| 71 | ++ * Latency: 0 |
| 72 | ++ * Capabilities: [e0] Vendor Specific Information |
| 73 | ++ * 00: 86 80 b9 27 07 01 10 02 02 00 01 06 00 00 80 00 |
| 74 | ++ * 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
| 75 | ++ * 20: 00 00 00 00 00 00 00 00 00 00 00 00 25 10 07 01 |
| 76 | ++ * 30: 00 00 00 00 e0 00 00 00 00 00 00 00 00 00 00 00 |
| 77 | ++ * 40: 01 10 00 00 80 00 00 00 81 11 00 00 10 00 00 00 |
| 78 | ++ * 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
| 79 | ++ * 60: 80 80 80 80 90 00 00 00 80 80 80 80 00 00 00 00 |
| 80 | ++ * 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
| 81 | ++ * 80: 10 00 02 3f 00 00 00 00 01 12 04 00 00 00 00 00 |
| 82 | ++ * 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
| 83 | ++ * a0: 24 06 00 00 01 00 00 00 13 1c 0a 00 00 03 00 00 |
| 84 | ++ * b0: 00 00 f0 00 00 00 00 00 00 80 09 00 00 00 00 00 |
| 85 | ++ * c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
| 86 | ++ * d0: 33 22 11 00 67 45 00 00 cf ff 00 00 00 00 00 00 |
| 87 | ++ * e0: 09 00 0c 10 b4 02 24 17 00 00 00 00 00 00 00 00 |
| 88 | ++ * f0: 01 c0 d1 fe 00 00 00 00 86 0f 02 00 00 00 00 00 |
| 89 | ++ */ |
| 90 | ++#include "hw.h" |
| 91 | ++#include "pci.h" |
| 92 | ++#include "console.h" |
| 93 | ++ |
| 94 | ++#define RCBA_BASE 0xFED1C000 |
| 95 | ++ |
| 96 | ++typedef struct LPCState { |
| 97 | ++ PCIDevice card; |
| 98 | ++} LPCState; |
| 99 | ++ |
| 100 | ++static uint32_t rcba_ram_readl(void *opaque, target_phys_addr_t addr) |
| 101 | ++{ |
| 102 | ++ printf("qemu: rcba_read l at %#lx\n", addr); |
| 103 | ++ if(addr == RCBA_BASE + 0x3404) { /* This is the HPET config pointer */ |
| 104 | ++ printf("qemu: rcba_read HPET_CONFIG_POINTER\n"); |
| 105 | ++ return 0xf0; // enabled at 0xfed00000 |
| 106 | ++ } else if(addr == RCBA_BASE + 0x3410) { /* This is the HPET config pointer */ |
| 107 | ++ printf("qemu: rcba_read GCS\n"); |
| 108 | ++ return 0; |
| 109 | ++ } else { |
| 110 | ++ return 0x0; |
| 111 | ++ } |
| 112 | ++} |
| 113 | ++ |
| 114 | ++static void rcba_ram_writel(void *opaque, target_phys_addr_t addr, |
| 115 | ++ uint32_t value) |
| 116 | ++{ |
| 117 | ++ printf("qemu: rcba_write l %#lx = %#x\n", addr, value); |
| 118 | ++} |
| 119 | ++ |
| 120 | ++static CPUReadMemoryFunc *rcba_ram_read[] = { |
| 121 | ++ NULL, |
| 122 | ++ NULL, |
| 123 | ++ rcba_ram_readl, |
| 124 | ++}; |
| 125 | ++ |
| 126 | ++static CPUWriteMemoryFunc *rcba_ram_write[] = { |
| 127 | ++ NULL, |
| 128 | ++ NULL, |
| 129 | ++ rcba_ram_writel, |
| 130 | ++}; |
| 131 | ++ |
| 132 | ++static int lpc_init(PCIDevice *dev) |
| 133 | ++{ |
| 134 | ++ int iomemtype; |
| 135 | ++ uint8_t *pci_conf; |
| 136 | ++ |
| 137 | ++#if 0 |
| 138 | ++ /* register a function 1 of PIIX3 */ |
| 139 | ++ d = (PCIDevice *)pci_register_device(bus, "LPC", |
| 140 | ++ sizeof(PCIDevice), |
| 141 | ++ 31 << 3, |
| 142 | ++ NULL, NULL); |
| 143 | ++#endif |
| 144 | ++ pci_conf = dev->config; |
| 145 | ++ pci_conf[0x00] = 0x86; |
| 146 | ++ pci_conf[0x01] = 0x80; |
| 147 | ++ pci_conf[0x02] = 0xb9; |
| 148 | ++ pci_conf[0x03] = 0x27; |
| 149 | ++ pci_conf[0x08] = 0x02; // Revision 2 |
| 150 | ++ |
| 151 | ++ pci_conf[0x0a] = 0x01; // PCI-to-ISA Bridge |
| 152 | ++ pci_conf[0x0b] = 0x06; // Bridge |
| 153 | ++ |
| 154 | ++ pci_conf[0x0e] = 0xf0; |
| 155 | ++ |
| 156 | ++ // Subsystem |
| 157 | ++ pci_conf[0x2c] = 0x86; |
| 158 | ++ pci_conf[0x2d] = 0x80; |
| 159 | ++ pci_conf[0x2e] = 0x70; |
| 160 | ++ pci_conf[0x2f] = 0x72; |
| 161 | ++ |
| 162 | ++ pci_conf[0x3d] = 0x03; |
| 163 | ++ |
| 164 | ++ // PMBASE |
| 165 | ++ pci_conf[0x40] = 0x01; |
| 166 | ++ pci_conf[0x41] = 0x0b; |
| 167 | ++ |
| 168 | ++ pci_set_long(pci_conf + 0xf0, RCBA_BASE | 1); |
| 169 | ++ |
| 170 | ++ /* RCBA Area */ |
| 171 | ++ |
| 172 | ++ iomemtype = cpu_register_io_memory(rcba_ram_read, rcba_ram_write, dev, DEVICE_NATIVE_ENDIAN); |
| 173 | ++ |
| 174 | ++ cpu_register_physical_memory(RCBA_BASE, 0x4000, iomemtype); |
| 175 | ++#if 0 |
| 176 | ++ cpu_register_physical_memory(0x00CDA000, 0x4000, iomemtype); |
| 177 | ++#endif |
| 178 | ++ |
| 179 | ++ pci_conf[0x04] = 0x07; // master, memory and I/O |
| 180 | ++ pci_conf[0x05] = 0x00; |
| 181 | ++ pci_conf[0x06] = 0x00; |
| 182 | ++ pci_conf[0x07] = 0x02; // PCI_status_devsel_medium |
| 183 | ++ pci_conf[0x4c] = 0x4d; |
| 184 | ++ pci_conf[0x4e] = 0x03; |
| 185 | ++ pci_conf[0x4f] = 0x00; |
| 186 | ++ pci_conf[0x60] = 0x0a; // PCI A -> IRQ 10 |
| 187 | ++ pci_conf[0x61] = 0x0a; // PCI B -> IRQ 10 |
| 188 | ++ pci_conf[0x62] = 0x0b; // PCI C -> IRQ 11 |
| 189 | ++ pci_conf[0x63] = 0x0b; // PCI D -> IRQ 11 |
| 190 | ++ pci_conf[0x69] = 0x02; |
| 191 | ++ pci_conf[0x70] = 0x80; |
| 192 | ++ pci_conf[0x76] = 0x0c; |
| 193 | ++ pci_conf[0x77] = 0x0c; |
| 194 | ++ pci_conf[0x78] = 0x02; |
| 195 | ++ pci_conf[0x79] = 0x00; |
| 196 | ++ pci_conf[0x80] = 0x00; |
| 197 | ++ pci_conf[0x82] = 0x00; |
| 198 | ++ pci_conf[0xa0] = 0x08; |
| 199 | ++ pci_conf[0xa2] = 0x00; |
| 200 | ++ pci_conf[0xa3] = 0x00; |
| 201 | ++ pci_conf[0xa4] = 0x00; |
| 202 | ++ pci_conf[0xa5] = 0x00; |
| 203 | ++ pci_conf[0xa6] = 0x00; |
| 204 | ++ pci_conf[0xa7] = 0x00; |
| 205 | ++ pci_conf[0xa8] = 0x0f; |
| 206 | ++ pci_conf[0xaa] = 0x00; |
| 207 | ++ pci_conf[0xab] = 0x00; |
| 208 | ++ pci_conf[0xac] = 0x00; |
| 209 | ++ pci_conf[0xae] = 0x00; |
| 210 | ++ |
| 211 | ++#if 0 |
| 212 | ++ register_ioport_read(0x1000, 128, 1, pmbase_readb, d); |
| 213 | ++ register_ioport_write(0x1000, 128, 1, pmbase_writeb, d); |
| 214 | ++ register_ioport_read(0x1000, 64, 2, pmbase_readw, d); |
| 215 | ++ register_ioport_write(0x1000, 64, 2, pmbase_writew, d); |
| 216 | ++ register_ioport_read(0x1000, 32, 4, pmbase_readl, d); |
| 217 | ++ register_ioport_write(0x1000, 32, 5, pmbase_writel, d); |
| 218 | ++#endif |
| 219 | ++ |
| 220 | ++ return 0; |
| 221 | ++} |
| 222 | ++ |
| 223 | ++static int lpc_uninit(PCIDevice *dev) |
| 224 | ++{ |
| 225 | ++ return 0; |
| 226 | ++} |
| 227 | ++ |
| 228 | ++static PCIDeviceInfo lpc_info = { |
| 229 | ++ .qdev.name = "lpc", |
| 230 | ++ .qdev.size = sizeof(LPCState), |
| 231 | ++ .init = lpc_init, |
| 232 | ++ .exit = lpc_uninit, |
| 233 | ++}; |
| 234 | ++ |
| 235 | ++static void lpc_register_device(void) |
| 236 | ++{ |
| 237 | ++ pci_qdev_register(&lpc_info); |
| 238 | ++} |
| 239 | ++ |
| 240 | ++device_init(lpc_register_device) |
0 commit comments