summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-06-21 03:26:41 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-06-21 03:26:41 +0000
commit22bb7b9dc24dd3aa601fe21b0fbedda78cd80e7c (patch)
tree8b5861f93d80c2b1ddad3bf75831a8d8d3a0f8e9 /sys/dev
parente96803101c250568a4db3bd6dedecd34a2680d14 (diff)
skeleton for queue handling on the pk side of the chip. For now it just
enqueues nops and handles them.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/noct.c213
-rw-r--r--sys/dev/pci/noctreg.h66
-rw-r--r--sys/dev/pci/noctvar.h12
3 files changed, 287 insertions, 4 deletions
diff --git a/sys/dev/pci/noct.c b/sys/dev/pci/noct.c
index 2ddd302a7a4..f7ea3245d83 100644
--- a/sys/dev/pci/noct.c
+++ b/sys/dev/pci/noct.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: noct.c,v 1.2 2002/06/04 21:25:16 jason Exp $ */
+/* $OpenBSD: noct.c,v 1.3 2002/06/21 03:26:40 jason Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -74,6 +74,12 @@ void noct_rng_init(struct noct_softc *);
void noct_rng_intr(struct noct_softc *);
void noct_rng_tick(void *);
+void noct_pkh_enable(struct noct_softc *);
+void noct_pkh_disable(struct noct_softc *);
+void noct_pkh_init(struct noct_softc *);
+void noct_pkh_intr(struct noct_softc *);
+void noct_pkh_tick(void *);
+
u_int64_t noct_read_8(struct noct_softc *, u_int32_t);
void noct_write_8(struct noct_softc *, u_int32_t, u_int64_t);
@@ -156,6 +162,7 @@ noct_attach(parent, self, aux)
printf(": %s, %uMB\n", intrstr, sc->sc_ramsize);
noct_rng_init(sc);
+ noct_pkh_init(sc);
return;
@@ -179,6 +186,11 @@ noct_intr(vsc)
noct_rng_intr(sc);
}
+ if (reg & BRDGSTS_PKP_INT) {
+ r = 1;
+ noct_pkh_intr(sc);
+ }
+
return (r);
}
@@ -260,6 +272,204 @@ noct_ram_read(sc, adr)
}
void
+noct_pkh_disable(sc)
+ struct noct_softc *sc;
+{
+ u_int32_t r;
+
+ /* Turn off PK irq */
+ NOCT_WRITE_4(sc, NOCT_BRDG_CTL,
+ NOCT_READ_4(sc, NOCT_BRDG_CTL) & ~(BRDGCTL_PKIRQ_ENA));
+
+ /* Turn of PK interrupts */
+ NOCT_READ_4(sc, NOCT_PKH_IER);
+ r &= ~(PKHIER_CMDSI | PKHIER_SKSWR | PKHIER_SKSOFF | PKHIER_PKHLEN |
+ PKHIER_PKHOPCODE | PKHIER_BADQBASE | PKHIER_LOADERR |
+ PKHIER_STOREERR | PKHIER_CMDERR | PKHIER_ILL | PKHIER_PKERESV |
+ PKHIER_PKEWDT | PKHIER_PKENOTPRIME |
+ PKHIER_PKE_B | PKHIER_PKE_A | PKHIER_PKE_M | PKHIER_PKE_R |
+ PKHIER_PKEOPCODE);
+ NOCT_WRITE_4(sc, NOCT_PKH_IER, r);
+
+ /* Disable PK unit */
+ r = NOCT_READ_4(sc, NOCT_PKH_CSR);
+ r &= ~PKHCSR_PKH_ENA;
+ NOCT_WRITE_4(sc, NOCT_PKH_CSR, r);
+ for (;;) {
+ r = NOCT_READ_4(sc, NOCT_PKH_CSR);
+ if ((r & PKHCSR_PKH_BUSY) == 0)
+ break;
+ }
+
+ /* Clear status bits */
+ r |= PKHCSR_CMDSI | PKHCSR_SKSWR | PKHCSR_SKSOFF | PKHCSR_PKHLEN |
+ PKHCSR_PKHOPCODE | PKHCSR_BADQBASE | PKHCSR_LOADERR |
+ PKHCSR_STOREERR | PKHCSR_CMDERR | PKHCSR_ILL | PKHCSR_PKERESV |
+ PKHCSR_PKEWDT | PKHCSR_PKENOTPRIME |
+ PKHCSR_PKE_B | PKHCSR_PKE_A | PKHCSR_PKE_M | PKHCSR_PKE_R |
+ PKHCSR_PKEOPCODE;
+ NOCT_WRITE_4(sc, NOCT_PKH_CSR, r);
+}
+
+void
+noct_pkh_enable(sc)
+ struct noct_softc *sc;
+{
+ u_int64_t adr;
+
+ sc->sc_pkhwp = 0;
+
+ adr = sc->sc_pkhmap->dm_segs[0].ds_addr;
+ NOCT_WRITE_4(sc, NOCT_PKH_Q_BASE_HI, (adr >> 32) & 0xffffffff);
+ NOCT_WRITE_4(sc, NOCT_PKH_Q_LEN, NOCT_PKH_QLEN);
+ NOCT_WRITE_4(sc, NOCT_PKH_Q_BASE_LO, (adr >> 0) & 0xffffffff);
+
+ NOCT_WRITE_4(sc, NOCT_PKH_IER,
+ PKHIER_CMDSI | PKHIER_SKSWR | PKHIER_SKSOFF | PKHIER_PKHLEN |
+ PKHIER_PKHOPCODE | PKHIER_BADQBASE | PKHIER_LOADERR |
+ PKHIER_STOREERR | PKHIER_CMDERR | PKHIER_ILL | PKHIER_PKERESV |
+ PKHIER_PKEWDT | PKHIER_PKENOTPRIME |
+ PKHIER_PKE_B | PKHIER_PKE_A | PKHIER_PKE_M | PKHIER_PKE_R |
+ PKHIER_PKEOPCODE);
+
+ NOCT_WRITE_4(sc, NOCT_PKH_CSR,
+ NOCT_READ_4(sc, NOCT_PKH_CSR) | PKHCSR_PKH_ENA);
+
+ NOCT_WRITE_4(sc, NOCT_BRDG_CTL,
+ NOCT_READ_4(sc, NOCT_BRDG_CTL) | BRDGCTL_PKIRQ_ENA);
+}
+
+void
+noct_pkh_init(sc)
+ struct noct_softc *sc;
+{
+ bus_dma_segment_t seg;
+ int rseg;
+
+ if (bus_dmamem_alloc(sc->sc_dmat, NOCT_PKH_BUFSIZE,
+ PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) {
+ printf("%s: failed pkh buf alloc\n", sc->sc_dv.dv_xname);
+ goto fail;
+ }
+ if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, NOCT_PKH_BUFSIZE,
+ (caddr_t *)&sc->sc_pkhcmd, BUS_DMA_NOWAIT)) {
+ printf("%s: failed pkh buf map\n", sc->sc_dv.dv_xname);
+ goto fail_1;
+ }
+ if (bus_dmamap_create(sc->sc_dmat, NOCT_PKH_BUFSIZE, rseg,
+ NOCT_PKH_BUFSIZE, 0, BUS_DMA_NOWAIT, &sc->sc_pkhmap)) {
+ printf("%s: failed pkh map create\n", sc->sc_dv.dv_xname);
+ goto fail_2;
+ }
+ if (bus_dmamap_load_raw(sc->sc_dmat, sc->sc_pkhmap,
+ &seg, rseg, NOCT_PKH_BUFSIZE, BUS_DMA_NOWAIT)) {
+ printf("%s: failed pkh buf load\n", sc->sc_dv.dv_xname);
+ goto fail_3;
+ }
+
+ noct_pkh_disable(sc);
+ noct_pkh_enable(sc);
+
+ if (hz > 100)
+ sc->sc_pkhtick = hz/100;
+ else
+ sc->sc_pkhtick = 1;
+ timeout_set(&sc->sc_pkhto, noct_pkh_tick, sc);
+ timeout_add(&sc->sc_pkhto, sc->sc_pkhtick);
+
+ return;
+
+fail_3:
+ bus_dmamap_destroy(sc->sc_dmat, sc->sc_pkhmap);
+fail_2:
+ bus_dmamem_unmap(sc->sc_dmat,
+ (caddr_t)sc->sc_pkhcmd, NOCT_PKH_BUFSIZE);
+fail_1:
+ bus_dmamem_free(sc->sc_dmat, &seg, rseg);
+fail:
+ sc->sc_pkhcmd = NULL;
+ sc->sc_pkhmap = NULL;
+}
+
+void
+noct_pkh_intr(sc)
+ struct noct_softc *sc;
+{
+ u_int32_t csr;
+
+ csr = NOCT_READ_4(sc, NOCT_PKH_CSR);
+ NOCT_WRITE_4(sc, NOCT_PKH_CSR, csr |
+ PKHCSR_CMDSI | PKHCSR_SKSWR | PKHCSR_SKSOFF | PKHCSR_PKHLEN |
+ PKHCSR_PKHOPCODE | PKHCSR_BADQBASE | PKHCSR_LOADERR |
+ PKHCSR_STOREERR | PKHCSR_CMDERR | PKHCSR_ILL | PKHCSR_PKERESV |
+ PKHCSR_PKEWDT | PKHCSR_PKENOTPRIME |
+ PKHCSR_PKE_B | PKHCSR_PKE_A | PKHCSR_PKE_M | PKHCSR_PKE_R |
+ PKHCSR_PKEOPCODE);
+
+ if (csr & PKHCSR_CMDSI)
+ sc->sc_pkhbusy = 0;
+
+ if (csr & PKHCSR_SKSWR)
+ printf("%s: sks write error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_SKSOFF)
+ printf("%s: sks offset error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKHLEN)
+ printf("%s: pkh invalid length\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKHOPCODE)
+ printf("%s: pkh bad opcode\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_BADQBASE)
+ printf("%s: pkh base qbase\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_LOADERR)
+ printf("%s: pkh load error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_STOREERR)
+ printf("%s: pkh store error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_CMDERR)
+ printf("%s: pkh command error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_ILL)
+ printf("%s: pkh illegal access\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKERESV)
+ printf("%s: pke reserved error\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKEWDT)
+ printf("%s: pke watchdog\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKENOTPRIME)
+ printf("%s: pke not prime\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKE_B)
+ printf("%s: pke bad 'b'\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKE_A)
+ printf("%s: pke bad 'a'\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKE_M)
+ printf("%s: pke bad 'm'\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKE_R)
+ printf("%s: pke bad 'r'\n", sc->sc_dv.dv_xname);
+ if (csr & PKHCSR_PKEOPCODE)
+ printf("%s: pke bad opcode\n", sc->sc_dv.dv_xname);
+}
+
+void
+noct_pkh_tick(vsc)
+ void *vsc;
+{
+ struct noct_softc *sc = vsc;
+ struct noct_pkh_cmd_nop *nop;
+ int s;
+
+ s = splnet();
+ if (sc->sc_pkhbusy)
+ goto out;
+ nop = &sc->sc_pkhcmd[sc->sc_pkhwp].nop;
+ nop->op = PKH_OP_SI | PKH_OP_CODE_NOP;
+ nop->unused[0] = nop->unused[1] = nop->unused[2] = nop->unused[3] = 0;
+ nop->unused[4] = nop->unused[5] = nop->unused[6] = 0;
+ sc->sc_pkhbusy = 1;
+ if (++sc->sc_pkhwp == NOCT_PKH_ENTRIES)
+ sc->sc_pkhwp = 0;
+ NOCT_WRITE_4(sc, NOCT_PKH_Q_PTR, sc->sc_pkhwp);
+out:
+ splx(s);
+ timeout_add(&sc->sc_pkhto, sc->sc_pkhtick);
+}
+
+void
noct_rng_disable(sc)
struct noct_softc *sc;
{
@@ -376,7 +586,6 @@ fail_1:
fail:
sc->sc_rngbuf = NULL;
sc->sc_rngmap = NULL;
- return;
}
void
diff --git a/sys/dev/pci/noctreg.h b/sys/dev/pci/noctreg.h
index dfe2a89e149..ccc22395934 100644
--- a/sys/dev/pci/noctreg.h
+++ b/sys/dev/pci/noctreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: noctreg.h,v 1.2 2002/06/20 20:31:59 jason Exp $ */
+/* $OpenBSD: noctreg.h,v 1.3 2002/06/21 03:26:40 jason Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -234,3 +234,67 @@
#define PKHSKS_LOC_CACHEONLY 0x00001000
#define PKHSKS_ADDR 0x00000fff /* address mask */
+#define PKH_OP_CODE_MOD 0x00000000 /* a mod m */
+#define PKH_OP_CODE_RMOD 0x10000000 /* R mod m */
+#define PKH_OP_CODE_ADD 0x20000000 /* (a + b) mod m */
+#define PKH_OP_CODE_SUB 0x30000000 /* (a - b) mod m */
+#define PKH_OP_CODE_ADDINV 0x40000000 /* -a mod m */
+#define PKH_OP_CODE_MUL 0x50000000 /* (a * b) mod m */
+#define PKH_OP_CODE_MULINV 0x60000000 /* 1/a mod m */
+#define PKH_OP_CODE_EXP 0x70000000 /* g^e mod m */
+#define PKH_OP_CODE_LOAD 0x80000000 /* load bn cache */
+#define PKH_OP_CODE_STORE 0x90000000 /* store bn cache */
+#define PKH_OP_CODE_RSAPRIV 0xa0000000 /* rsa private key op */
+#define PKH_OP_CODE_DSASIGN 0xb0000000 /* dsa sign op */
+#define PKH_OP_CODE_NOP 0xf0000000 /* no-op */
+#define PKH_OP_SI 0x08000000 /* set interrupt */
+
+/* pkh arithmetic commands */
+struct noct_pkh_cmd_arith {
+ volatile u_int32_t op; /* opcode/si, 0x0 - 0x7 */
+ volatile u_int32_t r; /* r offset */
+ volatile u_int32_t m; /* m length, m offset */
+ volatile u_int32_t a; /* a length, a offset */
+ volatile u_int32_t b; /* b length, b offset */
+ volatile u_int32_t c; /* c offset */
+ volatile u_int32_t unused[2]; /* reserved */
+};
+
+/* pkh load/store bn cache commands */
+struct noct_pkh_cmd_cache {
+ volatile u_int32_t op; /* opcode/si, 0x8-0x9 */
+ volatile u_int32_t r; /* r offset */
+ volatile u_int32_t addrhi; /* host address, msw */
+ volatile u_int32_t addrlo; /* host address, lsw */
+ volatile u_int32_t len; /* data length (0-4096) */
+ volatile u_int32_t unused[3]; /* reserved */
+};
+
+/* pkh rsa private command */
+struct noct_pkh_cmd_rsapriv {
+ volatile u_int32_t op; /* opcode/si, 0xa */
+ volatile u_int32_t par; /* n, keylen, sksoffset */
+ volatile u_int32_t unused[6]; /* reserved */
+};
+
+/* pkh dsa sign command */
+struct noct_pkh_cmd_dsasign {
+ volatile u_int32_t op; /* opcode/si, 0xb */
+ volatile u_int32_t par; /* n, keylen, sksoffset */
+ volatile u_int32_t unused[6]; /* reserved */
+};
+
+/* pkh nop command */
+struct noct_pkh_cmd_nop {
+ volatile u_int32_t op; /* opcode/si, 0xf */
+ volatile u_int32_t unused[7]; /* reserved */
+};
+
+/* pkh generic command */
+union noct_pkh_cmd {
+ struct noct_pkh_cmd_arith arith;
+ struct noct_pkh_cmd_cache cache;
+ struct noct_pkh_cmd_rsapriv rsapriv;
+ struct noct_pkh_cmd_dsasign dsasign;
+ struct noct_pkh_cmd_nop nop;
+};
diff --git a/sys/dev/pci/noctvar.h b/sys/dev/pci/noctvar.h
index 4e4af25607e..da6482f5b2c 100644
--- a/sys/dev/pci/noctvar.h
+++ b/sys/dev/pci/noctvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: noctvar.h,v 1.1 2002/06/02 18:15:03 jason Exp $ */
+/* $OpenBSD: noctvar.h,v 1.2 2002/06/21 03:26:40 jason Exp $ */
/*
* Copyright (c) 2002 Jason L. Wright (jason@thought.net)
@@ -44,9 +44,15 @@ struct noct_softc {
void *sc_ih;
u_int sc_ramsize;
u_int64_t *sc_rngbuf;
+ union noct_pkh_cmd *sc_pkhcmd;
bus_dmamap_t sc_rngmap;
+ bus_dmamap_t sc_pkhmap;
struct timeout sc_rngto;
int sc_rngtick;
+ struct timeout sc_pkhto;
+ int sc_pkhtick;
+ int sc_pkhbusy;
+ u_int32_t sc_pkhwp; /* pkh write pointer */
};
#define NOCT_READ_4(sc,r) \
@@ -60,3 +66,7 @@ struct noct_softc {
#define NOCT_RNG_QLEN 15
#define NOCT_RNG_ENTRIES (1 << NOCT_RNG_QLEN)
#define NOCT_RNG_BUFSIZE (NOCT_RNG_ENTRIES * sizeof(u_int64_t))
+
+#define NOCT_PKH_QLEN 15
+#define NOCT_PKH_ENTRIES (1 << NOCT_PKH_QLEN)
+#define NOCT_PKH_BUFSIZE (NOCT_PKH_ENTRIES * sizeof(union noct_pkh_cmd))