diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2002-06-21 03:26:41 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2002-06-21 03:26:41 +0000 |
commit | 22bb7b9dc24dd3aa601fe21b0fbedda78cd80e7c (patch) | |
tree | 8b5861f93d80c2b1ddad3bf75831a8d8d3a0f8e9 /sys/dev | |
parent | e96803101c250568a4db3bd6dedecd34a2680d14 (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.c | 213 | ||||
-rw-r--r-- | sys/dev/pci/noctreg.h | 66 | ||||
-rw-r--r-- | sys/dev/pci/noctvar.h | 12 |
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)) |