Subject: Re: TCPA Driver for NetBSD
To: None <firstname.lastname@example.org>
From: Rick Wash <email@example.com>
Date: 12/10/2003 16:39:50
On Sat, Nov 08, 2003 at 09:11:57PM -0500, Rick Wash wrote:
> I've been working on a driver for the tcpa chip for NetBSD (my current
> operating system of choice :) ). Right now I have an IBM T30 laptop that
> has the chip in it. IBM has released a linux driver , and I've written a
> BSD-licenced driver loosely based on this driver. Currently it works on my
> laptop. If anyone else has an IBM computer with the "IBM Security
> Subsystem" in it, feel free to try the driver and see if you can get it to
> work. Some instructions are available here:
> and the patch can be found here:
I've updated the patch slightly based on some comments I have received.
The new patch is available at:
I'd appreciate any comments you have. This patch is fairly similar to the
There are a couple of questions I have regarding pci/bus_space functions, as
I haven't been able to get the working yet.
In particular, the TCPA chip is attached to the LPC (low-pin-count) bus on
the motherboard, and doesn't have its own PCI ID. The driver looks for
appropriate LPC bridge devices, and then checks that device to see if the
TCPA chip is attached to it.
As such, I'm not sure if the pci_attach_args structure or the pci_conf
BAR's contain the information that is needed to use bus_space_ routines.
I'd like to use these routines as they are vastly better than inb/outb, but
I can't figure out how to map (with pci_mapreg_map(PCI_MAPREG_TYPE_IO...) or
bus_space_map(...). I do know that this device is ONLY accessable via
polling and i/o ports.
Any suggestions how I can accomplish this? What information do I need to
find in order to use these?
Also, I have written man pages for the libtcpa, which are available on my
project's site at:
P.S. Some responsed to David Young's comments are below.
On Sat, Nov 8, 2003, David Young wrote:
> I see a few ways to improve the driver. In tcpa_init,
> x = splhigh();
> /* talk directly to chip */
> outb(TPM_ADDR, 0x0D); /* unlock 4F */
> outb(TPM_DATA, 0x55);
> outb(TPM_ADDR, 0x0A); /* int disable */
> outb(TPM_DATA, 0x00);
> outb(TPM_ADDR, 0x08); /* base addr lo */
> outb(TPM_DATA, sc->base & 0xFF);
> outb(TPM_ADDR, 0x09); /* base addr hi */
> outb(TPM_DATA, (sc->base & 0xFF00) >> 8);
> outb(TPM_ADDR, 0x0D); /* lock 4F */
> outb(TPM_DATA, 0xAA);
> Is it necessary to synchronize tcpa_init's access to those registers
> with splhigh()? It seems like tcpa_init() is only run once during
If this is loaded via an LKM into an already-running system, I think using
splhigh() is warranted.
> Name constants like 0xAA and 0x55 so that the driver is
> "self-documenting." It might be appropriate to name the individual bits
> of the constants, and then bitwise-OR them together, like BIT_ABC|BIT_XYZ.
Looking for documentation for better names right now.
> The use of outb()/inb() is not *necessarily* wrong, but it is not
> ordinarily used by NetBSD drivers. The bus_space_ routines are preferred
> because they are architecture/bus-independent.
> Your driver seems to expect for the TPM registers to always map to the
> same I/O addresses---TPM_ADDR and TPM_DATA. In general, I don't think
> that you can count on that. Again, bus_space_ routines will "do the
> right thing." The actual mapping ought to be provided by the autoconf
> system to tcpa_pci_attach.
I've been having issues with this, as discussed above.
> Without knowing much about the opencrypto framework, my guess is that
> its API suits the functions of the TPM.
As the tcpa chip is fairly different from a standard crypto offload
processor, I'm not sure if it will fit. It uses a different security model
that allows things such as "only let the key be used if the system is in a
given state" and "don't ever let the private key leave the chip
unencrypted". I will look into it, though.