Date: Wed, 04 Aug 2010 19:39:41 +0900 From: Takanori Watanabe <takawata@init-main.com> To: tss-project@genua.de Cc: freebsd-hackers@freebsd.org, freebsd-current@freebsd.org Subject: Re: Driver tpm(4) and third party packages for trusted platform modules Message-ID: <201008041039.o74AdfYO047937@sana.init-main.com> In-Reply-To: Your message of "Wed, 04 Aug 2010 12:47:40 JST." <201008040347.o743leeR046013@sana.init-main.com>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <201008040347.o743leeR046013@sana.init-main.com>, wrote: >Quick review and hack: > >1.How about attaching it as acpi child driver? > >In some case, TPM may appear in ACPI namespace (with _HID) and >TPM spec defines ACPI method to handle TPM specific request. > >2. Is identify method needed? > >Writing device hint will attach isa child driver, I think. > >3.Module build > >I don't know it is proper in TPM nature. Update my patch. Split bus attachment from main driver file (need to update sys/conf/files), add detach method for convinience, and attach softc to cdev.si_drv1 . ==== diff -ruN src/sys/dev/tpm/tpm.c src.new/sys/dev/tpm/tpm.c --- src/sys/dev/tpm/tpm.c 2010-08-04 12:39:05.000000000 +0900 +++ src.new/sys/dev/tpm/tpm.c 2010-08-04 19:32:44.000000000 +0900 @@ -49,6 +49,7 @@ #include <dev/isa/isareg.h> #include <dev/isa/isavar.h> #endif +#include "tpmvar.h" #ifndef __FreeBSD__ /* XXX horrible hack for tcsd (-lpthread) workaround on OpenBSD */ @@ -142,43 +143,10 @@ /* Set when enabling legacy interface in host bridge. */ int tpm_enabled; -struct tpm_softc { -#ifndef __FreeBSD__ - struct device sc_dev; -#endif - void *sc_ih; - - int (*sc_init)(struct tpm_softc *, int, const char *); - int (*sc_start)(struct tpm_softc *, int); - int (*sc_read)(struct tpm_softc *, void *, int, size_t *, int); - int (*sc_write)(struct tpm_softc *, void *, int); - int (*sc_end)(struct tpm_softc *, int, int); - - bus_space_tag_t sc_bt, sc_batm; - bus_space_handle_t sc_bh, sc_bahm; - - u_int32_t sc_devid; - u_int32_t sc_rev; - u_int32_t sc_stat; - u_int32_t sc_capabilities; - - int sc_flags; -#define TPM_OPEN 0x0001 - - int sc_vector; -#ifdef __FreeBSD__ - void *intr_cookie; -#endif - -#ifndef __FreeBSD__ - void *sc_powerhook; -#endif - int sc_suspend; -}; #ifdef __FreeBSD__ #define TPMSOFTC(dev) \ - ((struct tpm_softc *)devclass_get_softc(tpm_devclass, dev2unit(dev))) + ((struct tpm_softc *)dev->si_drv1) d_open_t tpmopen; d_close_t tpmclose; @@ -229,7 +197,6 @@ { 0, "", TPM_DEV_NOINTS }, }; -int tpm_tis12_probe(bus_space_tag_t, bus_space_handle_t); int tpm_tis12_irqinit(struct tpm_softc *, int, int); int tpm_tis12_init(struct tpm_softc *, int, const char *); int tpm_tis12_start(struct tpm_softc *, int); @@ -239,8 +206,6 @@ #ifdef __FreeBSD__ void tpm_intr(void *); -int tpm_suspend(device_t); -int tpm_resume(device_t); #else int tpm_intr(void *); void tpm_powerhook(int, void *); @@ -264,67 +229,45 @@ int tpm_legacy_end(struct tpm_softc *, int, int); #ifdef __FreeBSD__ + /* * FreeBSD specific code for probing and attaching TPM to device tree. */ +#if 0 static void tpm_identify(driver_t *driver, device_t parent) { BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "tpm", 0); } +#endif -static int -tpm_probe(device_t dev) -{ - struct tpm_softc *sc = device_get_softc(dev); - bus_space_tag_t iot; - bus_space_handle_t ioh; - struct resource *mem_res; - int rv, mem_rid; - - bzero(sc, sizeof(struct tpm_softc)); - - 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 int +int tpm_attach(device_t dev) { struct tpm_softc *sc = device_get_softc(dev); - struct resource *mem_res; - int mem_rid; - int irq_rid, irq; - struct resource *irq_res; + int irq; - mem_rid = 0; - mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &mem_rid, + sc->mem_rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, RF_ACTIVE); - if (mem_res == NULL) + if (sc->mem_res == NULL) return ENXIO; - sc->sc_bt = rman_get_bustag(mem_res); - sc->sc_bh = rman_get_bushandle(mem_res); + sc->sc_bt = rman_get_bustag(sc->mem_res); + sc->sc_bh = rman_get_bushandle(sc->mem_res); - irq_rid = 0; - irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &irq_rid, + sc->irq_rid = 0; + sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE | RF_SHAREABLE); - if (irq_res != NULL) - irq = rman_get_start(irq_res); + 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; @@ -341,42 +284,51 @@ printf("%s", device_get_name(dev)); if ((sc->sc_init)(sc, irq, "tpm")) { - bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); - bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); + tpm_detach(dev); return ENXIO; } - if (sc->sc_init == tpm_tis12_init && irq_res != NULL && - bus_setup_intr(dev, irq_res, INTR_TYPE_TTY, NULL, + 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) { - bus_release_resource(dev, SYS_RES_MEMORY, mem_rid, mem_res); - bus_release_resource(dev, SYS_RES_IRQ, irq_rid, irq_res); + tpm_detach(dev); printf(": cannot establish interrupt\n"); return 1; } - make_dev(&tpm_cdevsw, device_get_unit(dev), UID_ROOT, GID_WHEEL, - 0600, "tpm"); + 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 device_method_t tpm_methods[] = { - DEVMETHOD(device_identify, tpm_identify), - DEVMETHOD(device_probe, tpm_probe), - DEVMETHOD(device_attach, tpm_attach), - DEVMETHOD(device_suspend, tpm_suspend), - DEVMETHOD(device_resume, tpm_resume), - { 0, 0 } -}; +int +tpm_detach(device_t dev) +{ + struct tpm_softc * sc = device_get_softc(dev); -static driver_t tpm_driver = { - "tpm", tpm_methods, sizeof(struct tpm_softc), -}; + if(sc->intr_cookie){ + bus_teardown_intr(dev, sc->irq_res, sc->intr_cookie); + } + + if(sc->mem_res){ + bus_release_resource(dev, SYS_RES_MEMORY, + sc->mem_rid, sc->mem_res); + } + + if(sc->irq_res){ + bus_release_resource(dev, SYS_RES_IRQ, + sc->irq_rid, sc->irq_res); + } + if(sc->sc_cdev){ + destroy_dev(sc->sc_cdev); + } + + return 0; +} -static devclass_t tpm_devclass; -DRIVER_MODULE(tpm, isa, tpm_driver, tpm_devclass, 0, 0); #else /* * OpenBSD specific code for probing and attaching TPM to device tree. diff -ruN src/sys/dev/tpm/tpm_acpi.c src.new/sys/dev/tpm/tpm_acpi.c --- src/sys/dev/tpm/tpm_acpi.c 1970-01-01 09:00:00.000000000 +0900 +++ src.new/sys/dev/tpm/tpm_acpi.c 2010-08-04 15:43:08.000000000 +0900 @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2008, 2009 Michael Shalayeff + * Copyright (c) 2009, 2010 Hans-J$(D+S(Brg H$(D+S(Bxer + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/proc.h> + +#include <sys/module.h> +#include <sys/conf.h> +#include <sys/uio.h> +#include <sys/bus.h> + +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> + +#include <machine/md_var.h> + +#include <isa/isareg.h> +#include <isa/isavar.h> +#include "tpmvar.h" + +#include "opt_acpi.h" +#include <contrib/dev/acpica/include/acpi.h> +#include <contrib/dev/acpica/include/accommon.h> +#include <dev/acpica/acpivar.h> + + + +char *tpm_ids[] = {"ATM1200", "PNP0C31", NULL}; + +static int +tpm_acpi_probe(device_t dev) +{ + if( ACPI_ID_PROBE(device_get_parent(dev), dev, tpm_ids) != NULL){ + device_set_desc(dev, "Trusted Platform Module"); + return BUS_PROBE_DEFAULT; + } + + return ENXIO; +} + +static device_method_t tpm_acpi_methods[] = { +#if 0 + /*In some case, TPM existance is found only in TPCA header*/ + DEVMETHOD(device_identify, tpm_acpi_identify), +#endif + + DEVMETHOD(device_probe, tpm_acpi_probe), + DEVMETHOD(device_attach, tpm_attach), + DEVMETHOD(device_detach, tpm_detach), + DEVMETHOD(device_suspend, tpm_suspend), + DEVMETHOD(device_resume, tpm_resume), + { 0, 0 } +}; +static driver_t tpm_acpi_driver = { + "tpm", tpm_acpi_methods, sizeof(struct tpm_softc), +}; + +devclass_t tpm_devclass; +DRIVER_MODULE(tpm, acpi, tpm_acpi_driver, tpm_devclass, 0, 0); diff -ruN src/sys/dev/tpm/tpm_isa.c src.new/sys/dev/tpm/tpm_isa.c --- src/sys/dev/tpm/tpm_isa.c 1970-01-01 09:00:00.000000000 +0900 +++ src.new/sys/dev/tpm/tpm_isa.c 2010-08-04 15:21:07.000000000 +0900 @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2008, 2009 Michael Shalayeff + * Copyright (c) 2009, 2010 Hans-J$(D+S(Brg H$(D+S(Bxer + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/malloc.h> +#include <sys/proc.h> + +#ifdef __FreeBSD__ +#include <sys/module.h> +#include <sys/conf.h> +#include <sys/uio.h> +#include <sys/bus.h> + +#include <machine/bus.h> +#include <sys/rman.h> +#include <machine/resource.h> + +#include <machine/md_var.h> + +#include <isa/isareg.h> +#include <isa/isavar.h> +#else +#include <sys/device.h> + +#include <machine/cpu.h> +#include <machine/bus.h> +#include <machine/intr.h> +#include <machine/conf.h> + +#include <dev/isa/isareg.h> +#include <dev/isa/isavar.h> +#endif +#include "tpmvar.h" + +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 device_method_t tpm_methods[] = { +#if 0 + DEVMETHOD(device_identify, tpm_identify), +#endif + DEVMETHOD(device_probe, tpm_isa_probe), + DEVMETHOD(device_attach, tpm_attach), + DEVMETHOD(device_detach, tpm_detach), + DEVMETHOD(device_suspend, tpm_suspend), + DEVMETHOD(device_resume, tpm_resume), + { 0, 0 } +}; + +static driver_t tpm_driver = { + "tpm", tpm_methods, sizeof(struct tpm_softc), +}; + +static devclass_t tpm_devclass; + +DRIVER_MODULE(tpm, isa, tpm_driver, tpm_devclass, 0, 0); diff -ruN src/sys/dev/tpm/tpmvar.h src.new/sys/dev/tpm/tpmvar.h --- src/sys/dev/tpm/tpmvar.h 1970-01-01 09:00:00.000000000 +0900 +++ src.new/sys/dev/tpm/tpmvar.h 2010-08-04 15:22:05.000000000 +0900 @@ -0,0 +1,46 @@ +#ifndef _TPMVAR_H +#define _TPMVAR_H + +struct tpm_softc { +#ifndef __FreeBSD__ + struct device sc_dev; +#endif + void *sc_ih; + + int (*sc_init)(struct tpm_softc *, int, const char *); + int (*sc_start)(struct tpm_softc *, int); + int (*sc_read)(struct tpm_softc *, void *, int, size_t *, int); + int (*sc_write)(struct tpm_softc *, void *, int); + int (*sc_end)(struct tpm_softc *, int, int); + + bus_space_tag_t sc_bt, sc_batm; + bus_space_handle_t sc_bh, sc_bahm; + + u_int32_t sc_devid; + u_int32_t sc_rev; + u_int32_t sc_stat; + u_int32_t sc_capabilities; + + int sc_flags; +#define TPM_OPEN 0x0001 + + int sc_vector; +#ifdef __FreeBSD__ + void *intr_cookie; + int mem_rid, irq_rid; + struct resource *mem_res, *irq_res; + struct cdev *sc_cdev; +#endif + +#ifndef __FreeBSD__ + void *sc_powerhook; +#endif + int sc_suspend; +}; + +int tpm_tis12_probe(bus_space_tag_t iot, bus_space_handle_t ioh); +int tpm_attach(device_t dev); +int tpm_detach(device_t dev); +int tpm_suspend(device_t dev); +int tpm_resume(device_t dev); +#endif diff -ruN src/sys/modules/tpm/Makefile src.new/sys/modules/tpm/Makefile --- src/sys/modules/tpm/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ src.new/sys/modules/tpm/Makefile 2010-08-04 19:17:26.000000000 +0900 @@ -0,0 +1,9 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../dev/tpm + +KMOD= tpm +SRCS= tpm.c tpm_isa.c tpm_acpi.c isa_if.h opt_acpi.h acpi_if.h \ + bus_if.h device_if.h + +.include <bsd.kmod.mk>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201008041039.o74AdfYO047937>