/* * OpenBSD specific code for probing and attaching TPM to device tree. */ int tpm_match(struct device *parent, void *match, void *aux) { struct isa_attach_args *ia = aux; struct cfdata *cf = match; bus_space_tag_t bt = ia->ia_memt; bus_space_handle_t bh; int rv; /* There can be only one. */ if (cf->cf_unit) return 0; if (tpm_legacy_probe(ia->ia_iot, ia->ia_iobase)) { ia->ia_iosize = 2; return 1; } if (ia->ia_maddr == -1) return 0; if (bus_space_map(bt, ia->ia_maddr, TPM_SIZE, 0, &bh)) return 0; if ((rv = tpm_tis12_probe(bt, bh))) { ia->ia_iosize = 0; ia->ia_msize = TPM_SIZE; } bus_space_unmap(bt, bh, TPM_SIZE); return rv; }
int tpm_attach(device_t dev) { struct tpm_softc *sc = device_get_softc(dev); int irq; sc->mem_rid = 0; sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, RF_ACTIVE); if (sc->mem_res == NULL) return ENXIO; sc->sc_bt = rman_get_bustag(sc->mem_res); sc->sc_bh = rman_get_bushandle(sc->mem_res); sc->irq_rid = 0; sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE); if (sc->irq_res != NULL) irq = rman_get_start(sc->irq_res); else irq = IRQUNK; /* In case PnP probe this may contain some initialization. */ tpm_tis12_probe(sc->sc_bt, sc->sc_bh); if (tpm_legacy_probe(sc->sc_bt, sc->sc_bh)) { sc->sc_init = tpm_legacy_init; sc->sc_start = tpm_legacy_start; sc->sc_read = tpm_legacy_read; sc->sc_write = tpm_legacy_write; sc->sc_end = tpm_legacy_end; } else { sc->sc_init = tpm_tis12_init; sc->sc_start = tpm_tis12_start; sc->sc_read = tpm_tis12_read; sc->sc_write = tpm_tis12_write; sc->sc_end = tpm_tis12_end; } printf("%s", device_get_name(dev)); if ((sc->sc_init)(sc, irq, "tpm")) { tpm_detach(dev); return ENXIO; } if (sc->sc_init == tpm_tis12_init && sc->irq_res != NULL && bus_setup_intr(dev, sc->irq_res, INTR_TYPE_TTY, NULL, tpm_intr, sc, &sc->intr_cookie) != 0) { tpm_detach(dev); printf(": cannot establish interrupt\n"); return 1; } sc->sc_cdev = make_dev(&tpm_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, 0600, "tpm"); sc->sc_cdev->si_drv1 = sc; return 0; }
static int tpm_isa_match(device_t parent, cfdata_t match, void *aux) { struct isa_attach_args *ia = aux; bus_space_tag_t bt = ia->ia_memt; bus_space_handle_t bh; int rv; /* There can be only one. */ if (tpm_cd.cd_devs && tpm_cd.cd_devs[0]) return 0; if (tpm_legacy_probe(ia->ia_iot, ia->ia_io[0].ir_addr)) { ia->ia_io[0].ir_size = 2; return 1; } if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM) return 0; /* XXX: integer locator sign extension */ if (bus_space_map(bt, (unsigned int)ia->ia_iomem[0].ir_addr, TPM_SIZE, 0, &bh)) return 0; if ((rv = tpm_tis12_probe(bt, bh))) { ia->ia_nio = 0; ia->ia_io[0].ir_size = 0; ia->ia_iomem[0].ir_size = TPM_SIZE; } ia->ia_ndrq = 0; bus_space_unmap(bt, bh, TPM_SIZE); return rv; }
static int tpm_isa_probe(device_t dev) { bus_space_tag_t iot; bus_space_handle_t ioh; struct resource *mem_res; int rv, mem_rid; mem_rid = 0; mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid, RF_ACTIVE); if (mem_res == NULL) return (ENXIO); iot = rman_get_bustag(mem_res); ioh = rman_get_bushandle(mem_res); if ((rv = tpm_tis12_probe(iot, ioh))) device_set_desc(dev, "Trusted Platform Module"); bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); return rv ? 0 : ENXIO; }
static void tpm_acpi_attach(device_t parent, device_t self, void *aux) { struct tpm_softc *sc = device_private(self); struct acpi_attach_args *aa = aux; struct acpi_resources res; struct acpi_io *io; struct acpi_mem *mem; struct acpi_irq *irq; bus_addr_t base; bus_addr_t size; int rv, inum; sc->sc_dev = self; /* Parse our resources */ rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS", &res, &acpi_resource_parse_ops_default); if (ACPI_FAILURE(rv)) { aprint_error_dev(sc->sc_dev, "cannot parse resources %d\n", rv); return; } io = acpi_res_io(&res, 0); if (io && tpm_legacy_probe(aa->aa_iot, io->ar_base)) { sc->sc_bt = aa->aa_iot; base = io->ar_base; size = io->ar_length; sc->sc_batm = aa->aa_iot; sc->sc_init = tpm_legacy_init; sc->sc_start = tpm_legacy_start; sc->sc_read = tpm_legacy_read; sc->sc_write = tpm_legacy_write; sc->sc_end = tpm_legacy_end; mem = NULL; } else { mem = acpi_res_mem(&res, 0); if (mem == NULL) { aprint_error_dev(sc->sc_dev, "cannot find mem\n"); goto out; } if (mem->ar_length != TPM_SIZE) { aprint_error_dev(sc->sc_dev, "wrong size mem %u != %u\n", mem->ar_length, TPM_SIZE); goto out; } base = mem->ar_base; size = mem->ar_length; sc->sc_bt = aa->aa_memt; sc->sc_init = tpm_tis12_init; sc->sc_start = tpm_tis12_start; sc->sc_read = tpm_tis12_read; sc->sc_write = tpm_tis12_write; sc->sc_end = tpm_tis12_end; } if (bus_space_map(sc->sc_bt, base, size, 0, &sc->sc_bh)) { aprint_error_dev(sc->sc_dev, "cannot map registers\n"); goto out; } if (mem && !tpm_tis12_probe(sc->sc_bt, sc->sc_bh)) { aprint_error_dev(sc->sc_dev, "1.2 probe failed\n"); goto out1; } irq = acpi_res_irq(&res, 0); if (irq == NULL) inum = -1; else inum = irq->ar_irq; if ((rv = (*sc->sc_init)(sc, inum, device_xname(sc->sc_dev))) != 0) aprint_error_dev(sc->sc_dev, "cannot init device %d\n", rv); goto out1; if (inum != -1 && (sc->sc_ih = isa_intr_establish(aa->aa_ic, irq->ar_irq, IST_EDGE, IPL_TTY, tpm_intr, sc)) == NULL) { aprint_error_dev(sc->sc_dev, "cannot establish interrupt\n"); goto out1; } if (!pmf_device_register(sc->sc_dev, tpm_suspend, tpm_resume)) aprint_error_dev(sc->sc_dev, "Cannot set power mgmt handler\n"); return; out1: bus_space_unmap(sc->sc_bt, sc->sc_bh, size); out: acpi_resource_cleanup(&res); }