pci_lpc.c (268892) | pci_lpc.c (268972) |
---|---|
1/*- 2 * Copyright (c) 2013 Neel Natu <neel@freebsd.org> 3 * Copyright (c) 2013 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/*- 2 * Copyright (c) 2013 Neel Natu <neel@freebsd.org> 3 * Copyright (c) 2013 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: stable/10/usr.sbin/bhyve/pci_lpc.c 268892 2014-07-19 22:13:12Z jhb $ | 27 * $FreeBSD: stable/10/usr.sbin/bhyve/pci_lpc.c 268972 2014-07-22 03:14:37Z jhb $ |
28 */ 29 30#include <sys/cdefs.h> | 28 */ 29 30#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_lpc.c 268892 2014-07-19 22:13:12Z jhb $"); | 31__FBSDID("$FreeBSD: stable/10/usr.sbin/bhyve/pci_lpc.c 268972 2014-07-22 03:14:37Z jhb $"); |
32 33#include <sys/types.h> 34#include <machine/vmm.h> 35#include <machine/vmm_dev.h> 36 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40 41#include <vmmapi.h> 42 43#include "acpi.h" 44#include "inout.h" 45#include "pci_emul.h" | 32 33#include <sys/types.h> 34#include <machine/vmm.h> 35#include <machine/vmm_dev.h> 36 37#include <stdio.h> 38#include <stdlib.h> 39#include <string.h> 40 41#include <vmmapi.h> 42 43#include "acpi.h" 44#include "inout.h" 45#include "pci_emul.h" |
46#include "pci_irq.h" |
|
46#include "pci_lpc.h" 47#include "uart_emul.h" 48 49#define IO_ICU1 0x20 50#define IO_ICU2 0xA0 51 52SET_DECLARE(lpc_dsdt_set, struct lpc_dsdt); 53SET_DECLARE(lpc_sysres_set, struct lpc_sysres); --- 114 unchanged lines hidden (view full) --- 168 sc = &lpc_uart_softc[unit]; 169 name = lpc_uart_names[unit]; 170 171 if (uart_legacy_alloc(unit, &sc->iobase, &sc->irq) != 0) { 172 fprintf(stderr, "Unable to allocate resources for " 173 "LPC device %s\n", name); 174 return (-1); 175 } | 47#include "pci_lpc.h" 48#include "uart_emul.h" 49 50#define IO_ICU1 0x20 51#define IO_ICU2 0xA0 52 53SET_DECLARE(lpc_dsdt_set, struct lpc_dsdt); 54SET_DECLARE(lpc_sysres_set, struct lpc_sysres); --- 114 unchanged lines hidden (view full) --- 169 sc = &lpc_uart_softc[unit]; 170 name = lpc_uart_names[unit]; 171 172 if (uart_legacy_alloc(unit, &sc->iobase, &sc->irq) != 0) { 173 fprintf(stderr, "Unable to allocate resources for " 174 "LPC device %s\n", name); 175 return (-1); 176 } |
177 pci_irq_reserve(sc->irq); |
|
176 177 sc->uart_softc = uart_init(lpc_uart_intr_assert, 178 lpc_uart_intr_deassert, sc); 179 180 if (uart_set_backend(sc->uart_softc, sc->opts) != 0) { 181 fprintf(stderr, "Unable to initialize backend '%s' " 182 "for LPC device %s\n", sc->opts, name); 183 return (-1); --- 19 unchanged lines hidden (view full) --- 203pci_lpc_write_dsdt(struct pci_devinst *pi) 204{ 205 struct lpc_dsdt **ldpp, *ldp; 206 207 dsdt_line(""); 208 dsdt_line("Device (ISA)"); 209 dsdt_line("{"); 210 dsdt_line(" Name (_ADR, 0x%04X%04X)", pi->pi_slot, pi->pi_func); | 178 179 sc->uart_softc = uart_init(lpc_uart_intr_assert, 180 lpc_uart_intr_deassert, sc); 181 182 if (uart_set_backend(sc->uart_softc, sc->opts) != 0) { 183 fprintf(stderr, "Unable to initialize backend '%s' " 184 "for LPC device %s\n", sc->opts, name); 185 return (-1); --- 19 unchanged lines hidden (view full) --- 205pci_lpc_write_dsdt(struct pci_devinst *pi) 206{ 207 struct lpc_dsdt **ldpp, *ldp; 208 209 dsdt_line(""); 210 dsdt_line("Device (ISA)"); 211 dsdt_line("{"); 212 dsdt_line(" Name (_ADR, 0x%04X%04X)", pi->pi_slot, pi->pi_func); |
211 dsdt_line(" OperationRegion (P40C, PCI_Config, 0x60, 0x04)"); | 213 dsdt_line(" OperationRegion (LPCR, PCI_Config, 0x00, 0x100)"); 214 dsdt_line(" Field (LPCR, AnyAcc, NoLock, Preserve)"); 215 dsdt_line(" {"); 216 dsdt_line(" Offset (0x60),"); 217 dsdt_line(" PIRA, 8,"); 218 dsdt_line(" PIRB, 8,"); 219 dsdt_line(" PIRC, 8,"); 220 dsdt_line(" PIRD, 8,"); 221 dsdt_line(" Offset (0x68),"); 222 dsdt_line(" PIRE, 8,"); 223 dsdt_line(" PIRF, 8,"); 224 dsdt_line(" PIRG, 8,"); 225 dsdt_line(" PIRH, 8"); 226 dsdt_line(" }"); 227 dsdt_line(""); |
212 213 dsdt_indent(1); 214 SET_FOREACH(ldpp, lpc_dsdt_set) { 215 ldp = *ldpp; 216 ldp->handler(); 217 } 218 219 dsdt_line(""); --- 80 unchanged lines hidden (view full) --- 300 dsdt_fixed_irq(sc->irq); 301 dsdt_unindent(2); 302 dsdt_line(" })"); 303 dsdt_line("}"); 304 } 305} 306LPC_DSDT(pci_lpc_uart_dsdt); 307 | 228 229 dsdt_indent(1); 230 SET_FOREACH(ldpp, lpc_dsdt_set) { 231 ldp = *ldpp; 232 ldp->handler(); 233 } 234 235 dsdt_line(""); --- 80 unchanged lines hidden (view full) --- 316 dsdt_fixed_irq(sc->irq); 317 dsdt_unindent(2); 318 dsdt_line(" })"); 319 dsdt_line("}"); 320 } 321} 322LPC_DSDT(pci_lpc_uart_dsdt); 323 |
324static int 325pci_lpc_cfgwrite(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, 326 int coff, int bytes, uint32_t val) 327{ 328 int pirq_pin; 329 330 if (bytes == 1) { 331 pirq_pin = 0; 332 if (coff >= 0x60 && coff <= 0x63) 333 pirq_pin = coff - 0x60 + 1; 334 if (coff >= 0x68 && coff <= 0x6b) 335 pirq_pin = coff - 0x68 + 5; 336 if (pirq_pin != 0) { 337 pirq_write(ctx, pirq_pin, val); 338 pci_set_cfgdata8(pi, coff, pirq_read(pirq_pin)); 339 return (0); 340 } 341 } 342 return (-1); 343} 344 |
|
308static void 309pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, 310 int baridx, uint64_t offset, int size, uint64_t value) 311{ 312} 313 | 345static void 346pci_lpc_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, 347 int baridx, uint64_t offset, int size, uint64_t value) 348{ 349} 350 |
314uint64_t | 351static uint64_t |
315pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, 316 int baridx, uint64_t offset, int size) 317{ 318 return (0); 319} 320 321#define LPC_DEV 0x7000 322#define LPC_VENDOR 0x8086 323 324static int 325pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) 326{ | 352pci_lpc_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, 353 int baridx, uint64_t offset, int size) 354{ 355 return (0); 356} 357 358#define LPC_DEV 0x7000 359#define LPC_VENDOR 0x8086 360 361static int 362pci_lpc_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) 363{ |
364 |
|
327 /* 328 * Do not allow more than one LPC bridge to be configured. 329 */ 330 if (lpc_bridge != NULL) { 331 fprintf(stderr, "Only one LPC bridge is allowed.\n"); 332 return (-1); 333 } 334 --- 16 unchanged lines hidden (view full) --- 351 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); 352 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); 353 354 lpc_bridge = pi; 355 356 return (0); 357} 358 | 365 /* 366 * Do not allow more than one LPC bridge to be configured. 367 */ 368 if (lpc_bridge != NULL) { 369 fprintf(stderr, "Only one LPC bridge is allowed.\n"); 370 return (-1); 371 } 372 --- 16 unchanged lines hidden (view full) --- 389 pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_BRIDGE); 390 pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_BRIDGE_ISA); 391 392 lpc_bridge = pi; 393 394 return (0); 395} 396 |
397char * 398lpc_pirq_name(int pin) 399{ 400 char *name; 401 402 if (lpc_bridge == NULL) 403 return (NULL); 404 asprintf(&name, "\\_SB.PC00.ISA.LNK%c,", 'A' + pin - 1); 405 return (name); 406} 407 408void 409lpc_pirq_routed(void) 410{ 411 int pin; 412 413 if (lpc_bridge == NULL) 414 return; 415 416 for (pin = 0; pin < 4; pin++) 417 pci_set_cfgdata8(lpc_bridge, 0x60 + pin, pirq_read(pin + 1)); 418 for (pin = 0; pin < 4; pin++) 419 pci_set_cfgdata8(lpc_bridge, 0x68 + pin, pirq_read(pin + 5)); 420} 421 |
|
359struct pci_devemu pci_de_lpc = { 360 .pe_emu = "lpc", 361 .pe_init = pci_lpc_init, 362 .pe_write_dsdt = pci_lpc_write_dsdt, | 422struct pci_devemu pci_de_lpc = { 423 .pe_emu = "lpc", 424 .pe_init = pci_lpc_init, 425 .pe_write_dsdt = pci_lpc_write_dsdt, |
426 .pe_cfgwrite = pci_lpc_cfgwrite, |
|
363 .pe_barwrite = pci_lpc_write, 364 .pe_barread = pci_lpc_read 365}; 366PCI_EMUL_SET(pci_de_lpc); | 427 .pe_barwrite = pci_lpc_write, 428 .pe_barread = pci_lpc_read 429}; 430PCI_EMUL_SET(pci_de_lpc); |