Wed Oct 9 14:03:58 2019 UTC ()
Provide a better abstraction for the TPM interface. Report it in the ioctl.


(maxv)
diff -r1.10 -r1.11 src/sys/dev/acpi/tpm_acpi.c
diff -r1.15 -r1.16 src/sys/dev/ic/tpm.c
diff -r1.6 -r1.7 src/sys/dev/ic/tpmvar.h
diff -r1.6 -r1.7 src/sys/dev/isa/tpm_isa.c

cvs diff -r1.10 -r1.11 src/sys/dev/acpi/tpm_acpi.c (expand / switch to unified diff)

--- src/sys/dev/acpi/tpm_acpi.c 2019/10/09 07:30:58 1.10
+++ src/sys/dev/acpi/tpm_acpi.c 2019/10/09 14:03:57 1.11
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tpm_acpi.c,v 1.10 2019/10/09 07:30:58 maxv Exp $ */ 1/* $NetBSD: tpm_acpi.c,v 1.11 2019/10/09 14:03:57 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2012, 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2012, 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Christos Zoulas and Maxime Villard. 8 * by Christos Zoulas and Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -20,27 +20,27 @@ @@ -20,27 +20,27 @@
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: tpm_acpi.c,v 1.10 2019/10/09 07:30:58 maxv Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: tpm_acpi.c,v 1.11 2019/10/09 14:03:57 maxv Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/device.h> 37#include <sys/device.h>
38#include <sys/bus.h> 38#include <sys/bus.h>
39#include <sys/pmf.h> 39#include <sys/pmf.h>
40 40
41#include <dev/ic/tpmreg.h> 41#include <dev/ic/tpmreg.h>
42#include <dev/ic/tpmvar.h> 42#include <dev/ic/tpmvar.h>
43 43
44#include <dev/acpi/acpireg.h> 44#include <dev/acpi/acpireg.h>
45#include <dev/acpi/acpivar.h> 45#include <dev/acpi/acpivar.h>
46 46
@@ -108,53 +108,46 @@ tpm_acpi_attach(device_t parent, device_ @@ -108,53 +108,46 @@ tpm_acpi_attach(device_t parent, device_
108 return; 108 return;
109 } 109 }
110 110
111 mem = acpi_res_mem(&res, 0); 111 mem = acpi_res_mem(&res, 0);
112 if (mem == NULL) { 112 if (mem == NULL) {
113 aprint_error_dev(self, "cannot find mem\n"); 113 aprint_error_dev(self, "cannot find mem\n");
114 goto out; 114 goto out;
115 } 115 }
116 if (mem->ar_length != TPM_SPACE_SIZE) { 116 if (mem->ar_length != TPM_SPACE_SIZE) {
117 aprint_error_dev(self, "wrong size mem %"PRIu64" != %u\n", 117 aprint_error_dev(self, "wrong size mem %"PRIu64" != %u\n",
118 (uint64_t)mem->ar_length, TPM_SPACE_SIZE); 118 (uint64_t)mem->ar_length, TPM_SPACE_SIZE);
119 goto out; 119 goto out;
120 } 120 }
 121 base = mem->ar_base;
 122 size = mem->ar_length;
121 123
122 sc->sc_dev = self; 124 sc->sc_dev = self;
123 sc->sc_ver = TPM_2_0; 125 sc->sc_ver = TPM_2_0;
124 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 126 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
125 sc->sc_busy = false; 127 sc->sc_busy = false;
126 sc->sc_init = tpm_tis12_init; 128 sc->sc_intf = &tpm_intf_tis12;
127 sc->sc_start = tpm_tis12_start; 
128 sc->sc_read = tpm_tis12_read; 
129 sc->sc_write = tpm_tis12_write; 
130 sc->sc_end = tpm_tis12_end; 
131 sc->sc_bt = aa->aa_memt; 129 sc->sc_bt = aa->aa_memt;
132 
133 base = mem->ar_base; 
134 size = mem->ar_length; 
135 
136 if (bus_space_map(sc->sc_bt, base, size, 0, &sc->sc_bh)) { 130 if (bus_space_map(sc->sc_bt, base, size, 0, &sc->sc_bh)) {
137 aprint_error_dev(sc->sc_dev, "cannot map registers\n"); 131 aprint_error_dev(sc->sc_dev, "cannot map registers\n");
138 goto out; 132 goto out;
139 } 133 }
140 134
141 if (!tpm_tis12_probe(sc->sc_bt, sc->sc_bh)) { 135 if ((rv = (*sc->sc_intf->probe)(sc->sc_bt, sc->sc_bh)) != 0) {
142 aprint_error_dev(sc->sc_dev, "TIS1.2 probe failed\n"); 136 aprint_error_dev(sc->sc_dev, "probe failed, rv=%d\n", rv);
143 goto out1; 137 goto out1;
144 } 138 }
145 139 if ((rv = (*sc->sc_intf->init)(sc)) != 0) {
146 if ((*sc->sc_init)(sc) != 0) { 140 aprint_error_dev(sc->sc_dev, "cannot init device, rv=%d\n", rv);
147 aprint_error_dev(sc->sc_dev, "cannot init device %d\n", rv); 
148 goto out1; 141 goto out1;
149 } 142 }
150 143
151 if (!pmf_device_register(self, tpm_suspend, tpm_resume)) 144 if (!pmf_device_register(self, tpm_suspend, tpm_resume))
152 aprint_error_dev(self, "couldn't establish power handler\n"); 145 aprint_error_dev(self, "couldn't establish power handler\n");
153 acpi_resource_cleanup(&res); 146 acpi_resource_cleanup(&res);
154 return; 147 return;
155 148
156out1: 149out1:
157 bus_space_unmap(sc->sc_bt, sc->sc_bh, size); 150 bus_space_unmap(sc->sc_bt, sc->sc_bh, size);
158out: 151out:
159 acpi_resource_cleanup(&res); 152 acpi_resource_cleanup(&res);
160} 153}

cvs diff -r1.15 -r1.16 src/sys/dev/ic/tpm.c (expand / switch to unified diff)

--- src/sys/dev/ic/tpm.c 2019/10/09 07:30:58 1.15
+++ src/sys/dev/ic/tpm.c 2019/10/09 14:03:58 1.16
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tpm.c,v 1.15 2019/10/09 07:30:58 maxv Exp $ */ 1/* $NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Maxime Villard. 8 * by Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -38,27 +38,27 @@ @@ -38,27 +38,27 @@
38 * purpose with or without fee is hereby granted, provided that the above 38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies. 39 * copyright notice and this permission notice appear in all copies.
40 * 40 *
41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 45 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
46 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 46 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
47 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.15 2019/10/09 07:30:58 maxv Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.16 2019/10/09 14:03:58 maxv Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/malloc.h> 56#include <sys/malloc.h>
57#include <sys/proc.h> 57#include <sys/proc.h>
58#include <sys/device.h> 58#include <sys/device.h>
59#include <sys/conf.h> 59#include <sys/conf.h>
60#include <sys/bus.h> 60#include <sys/bus.h>
61#include <sys/pmf.h> 61#include <sys/pmf.h>
62 62
63#include <dev/ic/tpmreg.h> 63#include <dev/ic/tpmreg.h>
64#include <dev/ic/tpmvar.h> 64#include <dev/ic/tpmvar.h>
@@ -83,62 +83,26 @@ CTASSERT(sizeof(struct tpm_header) == 10 @@ -83,62 +83,26 @@ CTASSERT(sizeof(struct tpm_header) == 10
83 83
84static inline int 84static inline int
85tpm_tmotohz(int tmo) 85tpm_tmotohz(int tmo)
86{ 86{
87 struct timeval tv; 87 struct timeval tv;
88 88
89 tv.tv_sec = tmo / 1000; 89 tv.tv_sec = tmo / 1000;
90 tv.tv_usec = 1000 * (tmo % 1000); 90 tv.tv_usec = 1000 * (tmo % 1000);
91 91
92 return tvtohz(&tv); 92 return tvtohz(&tv);
93} 93}
94 94
95static int 95static int
96tpm_request_locality(struct tpm_softc *sc, int l) 
97{ 
98 uint32_t r; 
99 int to, rv; 
100 
101 if (l != 0) 
102 return EINVAL; 
103 
104 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 
105 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) == 
106 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) 
107 return 0; 
108 
109 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS, 
110 TPM_ACCESS_REQUEST_USE); 
111 
112 to = tpm_tmotohz(TPM_ACCESS_TMO); 
113 
114 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) & 
115 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 
116 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) { 
117 rv = tsleep(sc->sc_init, PCATCH, "tpm_locality", 1); 
118 if (rv && rv != EWOULDBLOCK) { 
119 return rv; 
120 } 
121 } 
122 
123 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 
124 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 
125 return EBUSY; 
126 } 
127 
128 return 0; 
129} 
130 
131static int 
132tpm_getburst(struct tpm_softc *sc) 96tpm_getburst(struct tpm_softc *sc)
133{ 97{
134 int burst, to, rv; 98 int burst, to, rv;
135 99
136 to = tpm_tmotohz(TPM_BURST_TMO); 100 to = tpm_tmotohz(TPM_BURST_TMO);
137 101
138 while (to--) { 102 while (to--) {
139 /* 103 /*
140 * Burst count is in bits 23:8, so read the two higher bytes. 104 * Burst count is in bits 23:8, so read the two higher bytes.
141 */ 105 */
142 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1); 106 burst = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 1);
143 burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2) 107 burst |= bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_STS + 2)
144 << 8; 108 << 8;
@@ -164,50 +128,50 @@ tpm_status(struct tpm_softc *sc) @@ -164,50 +128,50 @@ tpm_status(struct tpm_softc *sc)
164 128
165/* -------------------------------------------------------------------------- */ 129/* -------------------------------------------------------------------------- */
166 130
167static bool 131static bool
168tpm12_suspend(struct tpm_softc *sc) 132tpm12_suspend(struct tpm_softc *sc)
169{ 133{
170 static const uint8_t command[10] = { 134 static const uint8_t command[10] = {
171 0x00, 0xC1, /* TPM_TAG_RQU_COMMAND */ 135 0x00, 0xC1, /* TPM_TAG_RQU_COMMAND */
172 0x00, 0x00, 0x00, 10, /* Length in bytes */ 136 0x00, 0x00, 0x00, 10, /* Length in bytes */
173 0x00, 0x00, 0x00, 0x98 /* TPM_ORD_SaveState */ 137 0x00, 0x00, 0x00, 0x98 /* TPM_ORD_SaveState */
174 }; 138 };
175 struct tpm_header response; 139 struct tpm_header response;
176 140
177 if ((*sc->sc_write)(sc, &command, sizeof(command)) != 0) 141 if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0)
178 return false; 142 return false;
179 if ((*sc->sc_read)(sc, &response, sizeof(response), NULL, 0) != 0) 143 if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0)
180 return false; 144 return false;
181 if (TPM_BE32(response.code) != 0) 145 if (TPM_BE32(response.code) != 0)
182 return false; 146 return false;
183 147
184 return true; 148 return true;
185} 149}
186 150
187static bool 151static bool
188tpm20_suspend(struct tpm_softc *sc) 152tpm20_suspend(struct tpm_softc *sc)
189{ 153{
190 static const uint8_t command[12] = { 154 static const uint8_t command[12] = {
191 0x80, 0x01, /* TPM_ST_NO_SESSIONS */ 155 0x80, 0x01, /* TPM_ST_NO_SESSIONS */
192 0x00, 0x00, 0x00, 12, /* Length in bytes */ 156 0x00, 0x00, 0x00, 12, /* Length in bytes */
193 0x00, 0x00, 0x01, 0x45, /* TPM_CC_Shutdown */ 157 0x00, 0x00, 0x01, 0x45, /* TPM_CC_Shutdown */
194 0x00, 0x01 /* TPM_SU_STATE */ 158 0x00, 0x01 /* TPM_SU_STATE */
195 }; 159 };
196 struct tpm_header response; 160 struct tpm_header response;
197 161
198 if ((*sc->sc_write)(sc, &command, sizeof(command)) != 0) 162 if ((*sc->sc_intf->write)(sc, &command, sizeof(command)) != 0)
199 return false; 163 return false;
200 if ((*sc->sc_read)(sc, &response, sizeof(response), NULL, 0) != 0) 164 if ((*sc->sc_intf->read)(sc, &response, sizeof(response), NULL, 0) != 0)
201 return false; 165 return false;
202 if (TPM_BE32(response.code) != 0) 166 if (TPM_BE32(response.code) != 0)
203 return false; 167 return false;
204 168
205 return true; 169 return true;
206} 170}
207 171
208bool 172bool
209tpm_suspend(device_t dev, const pmf_qual_t *qual) 173tpm_suspend(device_t dev, const pmf_qual_t *qual)
210{ 174{
211 struct tpm_softc *sc = device_private(dev); 175 struct tpm_softc *sc = device_private(dev);
212 176
213 switch (sc->sc_ver) { 177 switch (sc->sc_ver) {
@@ -276,154 +240,192 @@ restart: @@ -276,154 +240,192 @@ restart:
276 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 240 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
277 TPM_STS_RESP_RETRY); 241 TPM_STS_RESP_RETRY);
278 goto restart; 242 goto restart;
279 } 243 }
280 return EIO; 244 return EIO;
281 } 245 }
282 246
283 return 0; 247 return 0;
284} 248}
285 249
286/* -------------------------------------------------------------------------- */ 250/* -------------------------------------------------------------------------- */
287 251
288/* 252/*
289 * TPM using TIS 1.2 interface. 253 * TPM using the TIS 1.2 interface.
290 */ 254 */
291 255
292int 256static int
 257tpm12_request_locality(struct tpm_softc *sc, int l)
 258{
 259 uint32_t r;
 260 int to, rv;
 261
 262 if (l != 0)
 263 return EINVAL;
 264
 265 if ((bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
 266 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) ==
 267 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY))
 268 return 0;
 269
 270 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS,
 271 TPM_ACCESS_REQUEST_USE);
 272
 273 to = tpm_tmotohz(TPM_ACCESS_TMO);
 274
 275 while ((r = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_ACCESS) &
 276 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
 277 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && to--) {
 278 rv = tsleep(sc->sc_intf->init, PCATCH, "tpm_locality", 1);
 279 if (rv && rv != EWOULDBLOCK) {
 280 return rv;
 281 }
 282 }
 283
 284 if ((r & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
 285 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
 286 return EBUSY;
 287 }
 288
 289 return 0;
 290}
 291
 292static int
293tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh) 293tpm_tis12_probe(bus_space_tag_t bt, bus_space_handle_t bh)
294{ 294{
295 uint32_t cap; 295 uint32_t cap;
296 uint8_t reg; 296 uint8_t reg;
297 int tmo; 297 int tmo;
298 298
299 cap = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITY); 299 cap = bus_space_read_4(bt, bh, TPM_INTF_CAPABILITY);
300 if (cap == 0xffffffff) 300 if (cap == 0xffffffff)
301 return 0; 301 return EINVAL;
302 if ((cap & TPM_CAPS_REQUIRED) != TPM_CAPS_REQUIRED) 302 if ((cap & TPM_CAPS_REQUIRED) != TPM_CAPS_REQUIRED)
303 return 0; 303 return ENOTSUP;
304 304
305 /* Request locality 0. */ 305 /* Request locality 0. */
306 bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE); 306 bus_space_write_1(bt, bh, TPM_ACCESS, TPM_ACCESS_REQUEST_USE);
307 307
308 /* Wait for it to become active. */ 308 /* Wait for it to become active. */
309 tmo = TPM_ACCESS_TMO; /* Milliseconds. */ 309 tmo = TPM_ACCESS_TMO; /* Milliseconds. */
310 while ((reg = bus_space_read_1(bt, bh, TPM_ACCESS) & 310 while ((reg = bus_space_read_1(bt, bh, TPM_ACCESS) &
311 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 311 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
312 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && tmo--) { 312 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY) && tmo--) {
313 DELAY(1000); /* 1 millisecond. */ 313 DELAY(1000); /* 1 millisecond. */
314 } 314 }
315 if ((reg & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) != 315 if ((reg & (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) !=
316 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) { 316 (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
317 return 0; 317 return ETIMEDOUT;
318 } 318 }
319 319
320 if (bus_space_read_4(bt, bh, TPM_ID) == 0xffffffff) 320 if (bus_space_read_4(bt, bh, TPM_ID) == 0xffffffff)
321 return 0; 321 return EINVAL;
322 322
323 return 1; 323 return 0;
324} 324}
325 325
326int 326static int
327tpm_tis12_init(struct tpm_softc *sc) 327tpm_tis12_init(struct tpm_softc *sc)
328{ 328{
 329 int rv;
 330
329 sc->sc_caps = bus_space_read_4(sc->sc_bt, sc->sc_bh, 331 sc->sc_caps = bus_space_read_4(sc->sc_bt, sc->sc_bh,
330 TPM_INTF_CAPABILITY); 332 TPM_INTF_CAPABILITY);
331 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID); 333 sc->sc_devid = bus_space_read_4(sc->sc_bt, sc->sc_bh, TPM_ID);
332 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV); 334 sc->sc_rev = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_REV);
333 335
334 aprint_normal_dev(sc->sc_dev, "device 0x%08x rev 0x%x\n", 336 aprint_normal_dev(sc->sc_dev, "device 0x%08x rev 0x%x\n",
335 sc->sc_devid, sc->sc_rev); 337 sc->sc_devid, sc->sc_rev);
336 338
337 if (tpm_request_locality(sc, 0)) 339 if ((rv = tpm12_request_locality(sc, 0)) != 0)
338 return 1; 340 return rv;
339 341
340 /* Abort whatever it thought it was doing. */ 342 /* Abort whatever it thought it was doing. */
341 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 343 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
342 344
343 return 0; 345 return 0;
344} 346}
345 347
346int 348static int
347tpm_tis12_start(struct tpm_softc *sc, int rw) 349tpm_tis12_start(struct tpm_softc *sc, int rw)
348{ 350{
349 int rv; 351 int rv;
350 352
351 if (rw == UIO_READ) { 353 if (rw == UIO_READ) {
352 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 354 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
353 TPM_READ_TMO, sc->sc_read); 355 TPM_READ_TMO, sc->sc_intf->read);
354 return rv; 356 return rv;
355 } 357 }
356 358
357 /* Request the 0th locality. */ 359 /* Request the 0th locality. */
358 if ((rv = tpm_request_locality(sc, 0)) != 0) 360 if ((rv = tpm12_request_locality(sc, 0)) != 0)
359 return rv; 361 return rv;
360 362
361 sc->sc_status = tpm_status(sc); 363 sc->sc_status = tpm_status(sc);
362 if (sc->sc_status & TPM_STS_CMD_READY) 364 if (sc->sc_status & TPM_STS_CMD_READY)
363 return 0; 365 return 0;
364 366
365 /* Abort previous and restart. */ 367 /* Abort previous and restart. */
366 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY); 368 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, TPM_STS_CMD_READY);
367 rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO, sc->sc_write); 369 rv = tpm_waitfor(sc, TPM_STS_CMD_READY, TPM_READY_TMO, sc->sc_intf->write);
368 if (rv) 370 if (rv)
369 return rv; 371 return rv;
370 372
371 return 0; 373 return 0;
372} 374}
373 375
374int 376static int
375tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count, 377tpm_tis12_read(struct tpm_softc *sc, void *buf, size_t len, size_t *count,
376 int flags) 378 int flags)
377{ 379{
378 uint8_t *p = buf; 380 uint8_t *p = buf;
379 size_t cnt; 381 size_t cnt;
380 int rv, n; 382 int rv, n;
381 383
382 cnt = 0; 384 cnt = 0;
383 while (len > 0) { 385 while (len > 0) {
384 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID, 386 rv = tpm_waitfor(sc, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
385 TPM_READ_TMO, sc->sc_read); 387 TPM_READ_TMO, sc->sc_intf->read);
386 if (rv) 388 if (rv)
387 return rv; 389 return rv;
388 390
389 n = MIN(len, tpm_getburst(sc)); 391 n = MIN(len, tpm_getburst(sc));
390 while (n > 0) { 392 while (n > 0) {
391 *p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA); 393 *p++ = bus_space_read_1(sc->sc_bt, sc->sc_bh, TPM_DATA);
392 cnt++; 394 cnt++;
393 len--; 395 len--;
394 n--; 396 n--;
395 } 397 }
396 398
397 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6) 399 if ((flags & TPM_PARAM_SIZE) == 0 && cnt >= 6)
398 break; 400 break;
399 } 401 }
400 402
401 if (count) 403 if (count)
402 *count = cnt; 404 *count = cnt;
403 405
404 return 0; 406 return 0;
405} 407}
406 408
407int 409static int
408tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len) 410tpm_tis12_write(struct tpm_softc *sc, const void *buf, size_t len)
409{ 411{
410 const uint8_t *p = buf; 412 const uint8_t *p = buf;
411 size_t cnt; 413 size_t cnt;
412 int rv, r; 414 int rv, r;
413 415
414 if (len == 0) 416 if (len == 0)
415 return 0; 417 return 0;
416 if ((rv = tpm_request_locality(sc, 0)) != 0) 418 if ((rv = tpm12_request_locality(sc, 0)) != 0)
417 return rv; 419 return rv;
418 420
419 cnt = 0; 421 cnt = 0;
420 while (cnt < len - 1) { 422 while (cnt < len - 1) {
421 for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) { 423 for (r = tpm_getburst(sc); r > 0 && cnt < len - 1; r--) {
422 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 424 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
423 cnt++; 425 cnt++;
424 } 426 }
425 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 427 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
426 return rv; 428 return rv;
427 } 429 }
428 sc->sc_status = tpm_status(sc); 430 sc->sc_status = tpm_status(sc);
429 if (!(sc->sc_status & TPM_STS_DATA_EXPECT)) { 431 if (!(sc->sc_status & TPM_STS_DATA_EXPECT)) {
@@ -434,33 +436,33 @@ tpm_tis12_write(struct tpm_softc *sc, co @@ -434,33 +436,33 @@ tpm_tis12_write(struct tpm_softc *sc, co
434 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++); 436 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_DATA, *p++);
435 cnt++; 437 cnt++;
436 438
437 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) { 439 if ((rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc))) {
438 return rv; 440 return rv;
439 } 441 }
440 if ((sc->sc_status & TPM_STS_DATA_EXPECT) != 0) { 442 if ((sc->sc_status & TPM_STS_DATA_EXPECT) != 0) {
441 return EIO; 443 return EIO;
442 } 444 }
443 445
444 return 0; 446 return 0;
445} 447}
446 448
447int 449static int
448tpm_tis12_end(struct tpm_softc *sc, int rw, int err) 450tpm_tis12_end(struct tpm_softc *sc, int rw, int err)
449{ 451{
450 int rv = 0; 452 int rv = 0;
451 453
452 if (rw == UIO_READ) { 454 if (rw == UIO_READ) {
453 rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc->sc_read); 455 rv = tpm_waitfor(sc, TPM_STS_VALID, TPM_READ_TMO, sc->sc_intf->read);
454 if (rv) 456 if (rv)
455 return rv; 457 return rv;
456 458
457 /* Still more data? */ 459 /* Still more data? */
458 sc->sc_status = tpm_status(sc); 460 sc->sc_status = tpm_status(sc);
459 if (!err && (sc->sc_status & TPM_STS_DATA_AVAIL)) { 461 if (!err && (sc->sc_status & TPM_STS_DATA_AVAIL)) {
460 rv = EIO; 462 rv = EIO;
461 } 463 }
462 464
463 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 465 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
464 TPM_STS_CMD_READY); 466 TPM_STS_CMD_READY);
465 467
466 /* Release the 0th locality. */ 468 /* Release the 0th locality. */
@@ -470,26 +472,36 @@ tpm_tis12_end(struct tpm_softc *sc, int  @@ -470,26 +472,36 @@ tpm_tis12_end(struct tpm_softc *sc, int
470 /* Hungry for more? */ 472 /* Hungry for more? */
471 sc->sc_status = tpm_status(sc); 473 sc->sc_status = tpm_status(sc);
472 if (!err && (sc->sc_status & TPM_STS_DATA_EXPECT)) { 474 if (!err && (sc->sc_status & TPM_STS_DATA_EXPECT)) {
473 rv = EIO; 475 rv = EIO;
474 } 476 }
475 477
476 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS, 478 bus_space_write_1(sc->sc_bt, sc->sc_bh, TPM_STS,
477 err ? TPM_STS_CMD_READY : TPM_STS_GO); 479 err ? TPM_STS_CMD_READY : TPM_STS_GO);
478 } 480 }
479 481
480 return rv; 482 return rv;
481} 483}
482 484
 485const struct tpm_intf tpm_intf_tis12 = {
 486 .version = TIS_1_2,
 487 .probe = tpm_tis12_probe,
 488 .init = tpm_tis12_init,
 489 .start = tpm_tis12_start,
 490 .read = tpm_tis12_read,
 491 .write = tpm_tis12_write,
 492 .end = tpm_tis12_end
 493};
 494
483/* -------------------------------------------------------------------------- */ 495/* -------------------------------------------------------------------------- */
484 496
485static dev_type_open(tpmopen); 497static dev_type_open(tpmopen);
486static dev_type_close(tpmclose); 498static dev_type_close(tpmclose);
487static dev_type_read(tpmread); 499static dev_type_read(tpmread);
488static dev_type_write(tpmwrite); 500static dev_type_write(tpmwrite);
489static dev_type_ioctl(tpmioctl); 501static dev_type_ioctl(tpmioctl);
490 502
491const struct cdevsw tpm_cdevsw = { 503const struct cdevsw tpm_cdevsw = {
492 .d_open = tpmopen, 504 .d_open = tpmopen,
493 .d_close = tpmclose, 505 .d_close = tpmclose,
494 .d_read = tpmread, 506 .d_read = tpmread,
495 .d_write = tpmwrite, 507 .d_write = tpmwrite,
@@ -545,104 +557,100 @@ tpmclose(dev_t dev, int flag, int mode,  @@ -545,104 +557,100 @@ tpmclose(dev_t dev, int flag, int mode,
545 557
546static int 558static int
547tpmread(dev_t dev, struct uio *uio, int flags) 559tpmread(dev_t dev, struct uio *uio, int flags)
548{ 560{
549 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 561 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
550 struct tpm_header hdr; 562 struct tpm_header hdr;
551 uint8_t buf[TPM_BUFSIZ]; 563 uint8_t buf[TPM_BUFSIZ];
552 size_t cnt, len, n; 564 size_t cnt, len, n;
553 int rv; 565 int rv;
554 566
555 if (sc == NULL) 567 if (sc == NULL)
556 return ENXIO; 568 return ENXIO;
557 569
558 if ((rv = (*sc->sc_start)(sc, UIO_READ))) 570 if ((rv = (*sc->sc_intf->start)(sc, UIO_READ)))
559 goto out; 571 return rv;
560 572
561 /* Get the header. */ 573 /* Get the header. */
562 if ((rv = (*sc->sc_read)(sc, &hdr, sizeof(hdr), &cnt, 0))) { 574 if ((rv = (*sc->sc_intf->read)(sc, &hdr, sizeof(hdr), &cnt, 0))) {
563 (*sc->sc_end)(sc, UIO_READ, rv); 
564 goto out; 575 goto out;
565 } 576 }
566 len = TPM_BE32(hdr.length); 577 len = TPM_BE32(hdr.length);
567 if (len > uio->uio_resid || len < cnt) { 578 if (len > uio->uio_resid || len < cnt) {
568 rv = EIO; 579 rv = EIO;
569 (*sc->sc_end)(sc, UIO_READ, rv); 
570 goto out; 580 goto out;
571 } 581 }
572 582
573 /* Copy out the header. */ 583 /* Copy out the header. */
574 if ((rv = uiomove(&hdr, cnt, uio))) { 584 if ((rv = uiomove(&hdr, cnt, uio))) {
575 (*sc->sc_end)(sc, UIO_READ, rv); 
576 goto out; 585 goto out;
577 } 586 }
578 587
579 /* Process the rest. */ 588 /* Process the rest. */
580 len -= cnt; 589 len -= cnt;
581 while (len > 0) { 590 while (len > 0) {
582 n = MIN(sizeof(buf), len); 591 n = MIN(sizeof(buf), len);
583 if ((rv = (*sc->sc_read)(sc, buf, n, NULL, TPM_PARAM_SIZE))) { 592 if ((rv = (*sc->sc_intf->read)(sc, buf, n, NULL, TPM_PARAM_SIZE))) {
584 (*sc->sc_end)(sc, UIO_READ, rv); 
585 goto out; 593 goto out;
586 } 594 }
587 if ((rv = uiomove(buf, n, uio))) { 595 if ((rv = uiomove(buf, n, uio))) {
588 (*sc->sc_end)(sc, UIO_READ, rv); 
589 goto out; 596 goto out;
590 } 597 }
591 len -= n; 598 len -= n;
592 } 599 }
593 600
594 rv = (*sc->sc_end)(sc, UIO_READ, rv); 
595out: 601out:
 602 rv = (*sc->sc_intf->end)(sc, UIO_READ, rv);
596 return rv; 603 return rv;
597} 604}
598 605
599static int 606static int
600tpmwrite(dev_t dev, struct uio *uio, int flags) 607tpmwrite(dev_t dev, struct uio *uio, int flags)
601{ 608{
602 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 609 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
603 uint8_t buf[TPM_BUFSIZ]; 610 uint8_t buf[TPM_BUFSIZ];
604 int n, rv; 611 int n, rv;
605 612
606 if (sc == NULL) 613 if (sc == NULL)
607 return ENXIO; 614 return ENXIO;
608 615
609 n = MIN(sizeof(buf), uio->uio_resid); 616 n = MIN(sizeof(buf), uio->uio_resid);
610 if ((rv = uiomove(buf, n, uio))) { 617 if ((rv = uiomove(buf, n, uio))) {
611 goto out; 618 goto out;
612 } 619 }
613 if ((rv = (*sc->sc_start)(sc, UIO_WRITE))) { 620 if ((rv = (*sc->sc_intf->start)(sc, UIO_WRITE))) {
614 goto out; 621 goto out;
615 } 622 }
616 if ((rv = (*sc->sc_write)(sc, buf, n))) { 623 if ((rv = (*sc->sc_intf->write)(sc, buf, n))) {
617 goto out; 624 goto out;
618 } 625 }
619 626
620 rv = (*sc->sc_end)(sc, UIO_WRITE, rv); 627 rv = (*sc->sc_intf->end)(sc, UIO_WRITE, rv);
621out: 628out:
622 return rv; 629 return rv;
623} 630}
624 631
625static int 632static int
626tpmioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) 633tpmioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
627{ 634{
628 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev)); 635 struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
629 struct tpm_ioc_getinfo *info; 636 struct tpm_ioc_getinfo *info;
630 637
631 if (sc == NULL) 638 if (sc == NULL)
632 return ENXIO; 639 return ENXIO;
633 640
634 switch (cmd) { 641 switch (cmd) {
635 case TPM_IOC_GETINFO: 642 case TPM_IOC_GETINFO:
636 info = addr; 643 info = addr;
637 info->api_version = TPM_API_VERSION; 644 info->api_version = TPM_API_VERSION;
638 info->tpm_version = sc->sc_ver; 645 info->tpm_version = sc->sc_ver;
 646 info->itf_version = sc->sc_intf->version;
639 info->device_id = sc->sc_devid; 647 info->device_id = sc->sc_devid;
640 info->device_rev = sc->sc_rev; 648 info->device_rev = sc->sc_rev;
641 info->device_caps = sc->sc_caps; 649 info->device_caps = sc->sc_caps;
642 return 0; 650 return 0;
643 default: 651 default:
644 break; 652 break;
645 } 653 }
646 654
647 return ENOTTY; 655 return ENOTTY;
648} 656}

cvs diff -r1.6 -r1.7 src/sys/dev/ic/tpmvar.h (expand / switch to unified diff)

--- src/sys/dev/ic/tpmvar.h 2019/10/09 07:30:58 1.6
+++ src/sys/dev/ic/tpmvar.h 2019/10/09 14:03:58 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tpmvar.h,v 1.6 2019/10/09 07:30:58 maxv Exp $ */ 1/* $NetBSD: tpmvar.h,v 1.7 2019/10/09 14:03:58 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Maxime Villard. 8 * by Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -26,57 +26,65 @@ @@ -26,57 +26,65 @@
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#define TPM_API_VERSION 1 32#define TPM_API_VERSION 1
33 33
34enum tpm_version { 34enum tpm_version {
35 TPM_1_2, 35 TPM_1_2,
36 TPM_2_0 36 TPM_2_0
37}; 37};
38 38
 39enum itf_version {
 40 TIS_1_2,
 41 CRB
 42};
 43
39struct tpm_ioc_getinfo { 44struct tpm_ioc_getinfo {
40 uint32_t api_version; 45 uint32_t api_version;
41 uint32_t tpm_version; 46 uint32_t tpm_version;
 47 uint32_t itf_version;
42 uint32_t device_id; 48 uint32_t device_id;
43 uint32_t device_rev; 49 uint32_t device_rev;
44 uint32_t device_caps; 50 uint32_t device_caps;
45}; 51};
46 52
47#define TPM_IOC_GETINFO _IOR ('N', 0, struct tpm_ioc_getinfo) 53#define TPM_IOC_GETINFO _IOR ('N', 0, struct tpm_ioc_getinfo)
48 54
49#ifdef _KERNEL 55#ifdef _KERNEL
50 56
 57struct tpm_softc;
 58
 59struct tpm_intf {
 60 enum itf_version version;
 61 int (*probe)(bus_space_tag_t, bus_space_handle_t);
 62 int (*init)(struct tpm_softc *);
 63 int (*start)(struct tpm_softc *, int);
 64 int (*read)(struct tpm_softc *, void *, size_t, size_t *, int);
 65 int (*write)(struct tpm_softc *, const void *, size_t);
 66 int (*end)(struct tpm_softc *, int, int);
 67};
 68
 69extern const struct tpm_intf tpm_intf_tis12;
 70
51struct tpm_softc { 71struct tpm_softc {
52 device_t sc_dev; 72 device_t sc_dev;
53 enum tpm_version sc_ver; 73 enum tpm_version sc_ver;
54 kmutex_t sc_lock; 74 kmutex_t sc_lock;
55 bool sc_busy; 75 bool sc_busy;
56 76
57 int (*sc_init)(struct tpm_softc *); 77 const struct tpm_intf *sc_intf;
58 int (*sc_start)(struct tpm_softc *, int); 
59 int (*sc_read)(struct tpm_softc *, void *, size_t, size_t *, int); 
60 int (*sc_write)(struct tpm_softc *, const void *, size_t); 
61 int (*sc_end)(struct tpm_softc *, int, int); 
62 
63 bus_space_tag_t sc_bt; 78 bus_space_tag_t sc_bt;
64 bus_space_handle_t sc_bh; 79 bus_space_handle_t sc_bh;
65 80
66 uint32_t sc_devid; 81 uint32_t sc_devid;
67 uint32_t sc_rev; 82 uint32_t sc_rev;
68 uint32_t sc_status; 83 uint32_t sc_status;
69 uint32_t sc_caps; 84 uint32_t sc_caps;
70}; 85};
71 86
72bool tpm_suspend(device_t, const pmf_qual_t *); 87bool tpm_suspend(device_t, const pmf_qual_t *);
73bool tpm_resume(device_t, const pmf_qual_t *); 88bool tpm_resume(device_t, const pmf_qual_t *);
74 89
75int tpm_tis12_probe(bus_space_tag_t, bus_space_handle_t); 
76int tpm_tis12_init(struct tpm_softc *); 
77int tpm_tis12_start(struct tpm_softc *, int); 
78int tpm_tis12_read(struct tpm_softc *, void *, size_t, size_t *, int); 
79int tpm_tis12_write(struct tpm_softc *, const void *, size_t); 
80int tpm_tis12_end(struct tpm_softc *, int, int); 
81 
82#endif 90#endif

cvs diff -r1.6 -r1.7 src/sys/dev/isa/tpm_isa.c (expand / switch to unified diff)

--- src/sys/dev/isa/tpm_isa.c 2019/10/09 07:30:58 1.6
+++ src/sys/dev/isa/tpm_isa.c 2019/10/09 14:03:58 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tpm_isa.c,v 1.6 2019/10/09 07:30:58 maxv Exp $ */ 1/* $NetBSD: tpm_isa.c,v 1.7 2019/10/09 14:03:58 maxv Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Maxime Villard. 8 * by Maxime Villard.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -38,27 +38,27 @@ @@ -38,27 +38,27 @@
38 * purpose with or without fee is hereby granted, provided that the above 38 * purpose with or without fee is hereby granted, provided that the above
39 * copyright notice and this permission notice appear in all copies. 39 * copyright notice and this permission notice appear in all copies.
40 * 40 *
41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 41 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 42 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 43 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 44 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
45 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN 45 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
46 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 46 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
47 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 47 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: tpm_isa.c,v 1.6 2019/10/09 07:30:58 maxv Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: tpm_isa.c,v 1.7 2019/10/09 14:03:58 maxv Exp $");
52 52
53#include <sys/param.h> 53#include <sys/param.h>
54#include <sys/systm.h> 54#include <sys/systm.h>
55#include <sys/device.h> 55#include <sys/device.h>
56#include <sys/bus.h> 56#include <sys/bus.h>
57#include <sys/pmf.h> 57#include <sys/pmf.h>
58 58
59#include <dev/ic/tpmreg.h> 59#include <dev/ic/tpmreg.h>
60#include <dev/ic/tpmvar.h> 60#include <dev/ic/tpmvar.h>
61 61
62#include <dev/isa/isareg.h> 62#include <dev/isa/isareg.h>
63#include <dev/isa/isavar.h> 63#include <dev/isa/isavar.h>
64 64
@@ -80,59 +80,56 @@ tpm_isa_match(device_t parent, cfdata_t  @@ -80,59 +80,56 @@ tpm_isa_match(device_t parent, cfdata_t
80 80
81 /* There can be only one. */ 81 /* There can be only one. */
82 if (tpm_cd.cd_devs && tpm_cd.cd_devs[0]) 82 if (tpm_cd.cd_devs && tpm_cd.cd_devs[0])
83 return 0; 83 return 0;
84 84
85 if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM) 85 if (ia->ia_iomem[0].ir_addr == ISA_UNKNOWN_IOMEM)
86 return 0; 86 return 0;
87 87
88 /* XXX: integer locator sign extension */ 88 /* XXX: integer locator sign extension */
89 if (bus_space_map(bt, (unsigned int)ia->ia_iomem[0].ir_addr, 89 if (bus_space_map(bt, (unsigned int)ia->ia_iomem[0].ir_addr,
90 TPM_SPACE_SIZE, 0, &bh)) 90 TPM_SPACE_SIZE, 0, &bh))
91 return 0; 91 return 0;
92 92
93 if ((rv = tpm_tis12_probe(bt, bh))) { 93 if ((rv = (*tpm_intf_tis12.probe)(bt, bh)) == 0) {
94 ia->ia_nio = 0; 94 ia->ia_nio = 0;
95 ia->ia_io[0].ir_size = 0; 95 ia->ia_io[0].ir_size = 0;
96 ia->ia_iomem[0].ir_size = TPM_SPACE_SIZE; 96 ia->ia_iomem[0].ir_size = TPM_SPACE_SIZE;
97 } 97 }
98 ia->ia_ndrq = 0; 98 ia->ia_ndrq = 0;
99 99
100 bus_space_unmap(bt, bh, TPM_SPACE_SIZE); 100 bus_space_unmap(bt, bh, TPM_SPACE_SIZE);
101 return rv; 101 return (rv == 0) ? 1 : 0;
102} 102}
103 103
104static void 104static void
105tpm_isa_attach(device_t parent, device_t self, void *aux) 105tpm_isa_attach(device_t parent, device_t self, void *aux)
106{ 106{
107 struct tpm_softc *sc = device_private(self); 107 struct tpm_softc *sc = device_private(self);
108 struct isa_attach_args *ia = aux; 108 struct isa_attach_args *ia = aux;
109 bus_addr_t base; 109 bus_addr_t base;
110 bus_size_t size; 110 bus_size_t size;
 111 int rv;
 112
 113 base = (unsigned int)ia->ia_iomem[0].ir_addr;
 114 size = TPM_SPACE_SIZE;
111 115
112 sc->sc_dev = self; 116 sc->sc_dev = self;
113 sc->sc_ver = TPM_1_2; 117 sc->sc_ver = TPM_1_2;
114 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); 118 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
115 sc->sc_busy = false; 119 sc->sc_busy = false;
116 sc->sc_init = tpm_tis12_init; 120 sc->sc_intf = &tpm_intf_tis12;
117 sc->sc_start = tpm_tis12_start; 
118 sc->sc_read = tpm_tis12_read; 
119 sc->sc_write = tpm_tis12_write; 
120 sc->sc_end = tpm_tis12_end; 
121 sc->sc_bt = ia->ia_memt; 121 sc->sc_bt = ia->ia_memt;
122 
123 base = (unsigned int)ia->ia_iomem[0].ir_addr; 
124 size = TPM_SPACE_SIZE; 
125 
126 if (bus_space_map(sc->sc_bt, base, size, 0, &sc->sc_bh)) { 122 if (bus_space_map(sc->sc_bt, base, size, 0, &sc->sc_bh)) {
127 aprint_error_dev(sc->sc_dev, "cannot map registers\n"); 123 aprint_error_dev(sc->sc_dev, "cannot map registers\n");
128 return; 124 return;
129 } 125 }
130 126
131 if ((*sc->sc_init)(sc) != 0) { 127 if ((rv = (*sc->sc_intf->init)(sc)) != 0) {
 128 aprint_error_dev(sc->sc_dev, "cannot init device, rv=%d\n", rv);
132 bus_space_unmap(sc->sc_bt, sc->sc_bh, size); 129 bus_space_unmap(sc->sc_bt, sc->sc_bh, size);
133 return; 130 return;
134 } 131 }
135 132
136 if (!pmf_device_register(self, tpm_suspend, tpm_resume)) 133 if (!pmf_device_register(self, tpm_suspend, tpm_resume))
137 aprint_error_dev(self, "couldn't establish power handler\n"); 134 aprint_error_dev(self, "couldn't establish power handler\n");
138} 135}