1
0
mirror of synced 2026-04-14 23:38:00 +00:00

Trying to integrate Bestrusted's Curve25519 engine ; trivial program works but not after a few repetition :-(

This commit is contained in:
Romain Dolbeau
2021-07-25 06:52:05 -04:00
parent 0c5e750453
commit 42c5086885
11 changed files with 3541 additions and 41 deletions

View File

@@ -0,0 +1,615 @@
/* $NetBSD$ */
/*-
* Copyright (c) 2020 Romain Dolbeau <romain@dolbeau.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/errno.h>
#include <sys/device.h>
#include <sys/malloc.h>
#include <sys/bus.h>
#include <machine/autoconf.h>
#include <sys/cpu.h>
#include <sys/conf.h>
#include <sys/ioccom.h>
#include <dev/sbus/sbusvar.h>
#include <dev/sbus/sbusfpga_curve25519engine.h>
#include <machine/param.h>
int sbusfpga_curve25519engine_print(void *, const char *);
int sbusfpga_curve25519engine_match(device_t, cfdata_t, void *);
void sbusfpga_curve25519engine_attach(device_t, device_t, void *);
CFATTACH_DECL_NEW(sbusfpga_c29e, sizeof(struct sbusfpga_curve25519engine_softc),
sbusfpga_curve25519engine_match, sbusfpga_curve25519engine_attach, NULL, NULL);
dev_type_open(sbusfpga_curve25519engine_open);
dev_type_close(sbusfpga_curve25519engine_close);
dev_type_ioctl(sbusfpga_curve25519engine_ioctl);
const struct cdevsw sbusfpga_c29e_cdevsw = {
.d_open = sbusfpga_curve25519engine_open,
.d_close = sbusfpga_curve25519engine_close,
.d_read = noread,
.d_write = nowrite,
.d_ioctl = sbusfpga_curve25519engine_ioctl,
.d_stop = nostop,
.d_tty = notty,
.d_poll = nopoll,
.d_mmap = nommap,
.d_kqfilter = nokqfilter,
.d_discard = nodiscard,
.d_flag = 0
};
extern struct cfdriver sbusfpga_c29e_cd;
struct sbusfpga_curve25519engine_montgomeryjob {
uint32_t x0_u[8];
uint32_t x0_w[8];
uint32_t x1_u[8];
uint32_t x1_w[8];
uint32_t affine_u[8];
uint32_t scalar[8];
};
static int init_program(struct sbusfpga_curve25519engine_softc *sc);
static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusfpga_curve25519engine_montgomeryjob *job, const int window);
static int start_job(struct sbusfpga_curve25519engine_softc *sc);
static int wait_job(struct sbusfpga_curve25519engine_softc *sc);
static int read_outputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusfpga_curve25519engine_montgomeryjob *job, const int window);
#define SBUSFPGA_DO_MONTGOMERYJOB _IOWR(0, 0, struct sbusfpga_curve25519engine_montgomeryjob)
int
sbusfpga_curve25519engine_ioctl (dev_t dev, u_long cmd, void *data, int flag, struct lwp *l)
{
struct sbusfpga_curve25519engine_softc *sc = device_lookup_private(&sbusfpga_c29e_cd, minor(dev));
struct sbusfpga_curve25519engine_montgomeryjob* job = (struct sbusfpga_curve25519engine_montgomeryjob*)data;
int err = 0;
if (!sc->initialized) {
if (init_program(sc)) {
return ENXIO;
} else {
sc->initialized = 1;
}
}
switch (cmd) {
case SBUSFPGA_DO_MONTGOMERYJOB: {
err = write_inputs(sc, job, 0);
if (err)
return err;
err = start_job(sc);
if (err)
return err;
delay(10);
err = wait_job(sc);
if (err)
return err;
err = read_outputs(sc, job, 0);
if (err)
return err;
}
break;
default:
err = EINVAL;
break;
}
return(err);
}
int
sbusfpga_curve25519engine_open(dev_t dev, int flags, int mode, struct lwp *l)
{
return (0);
}
int
sbusfpga_curve25519engine_close(dev_t dev, int flags, int mode, struct lwp *l)
{
return (0);
}
int
sbusfpga_curve25519engine_print(void *aux, const char *busname)
{
sbus_print(aux, busname);
return (UNCONF);
}
int
sbusfpga_curve25519engine_match(device_t parent, cfdata_t cf, void *aux)
{
struct sbus_attach_args *sa = (struct sbus_attach_args *)aux;
return (strcmp("betrustedc25519e", sa->sa_name) == 0);
}
#if 0
static const uint32_t program[192] = {0x00480800,
0x007407cc,
0x007c07cb,
0x0049d483,
0x0079b643,
0x0079e482,
0x00659783,
0x006db783,
0x0079c683,
0x0079e482,
0x0069a783,
0x0071c783,
0x00480740,
0x00500640,
0x00540680,
0x005806c0,
0x005c0700,
0x00015505,
0x00780008,
0x0001e006,
0x005558c6,
0x00055505,
0x00780048,
0x0005e046,
0x00097585,
0x00780088,
0x0009e086,
0x005d78c6,
0x000d7585,
0x007800c8,
0x000de0c6,
0x00100007,
0x00141047,
0x007458c6,
0x0019d105,
0x00780188,
0x0019e186,
0x001c3007,
0x00202047,
0x002481c5,
0x00780248,
0x0025e246,
0x007488c6,
0x0029d1c5,
0x00780288,
0x0029e286,
0x002c9247,
0x0030a287,
0x00346907,
0x00385107,
0x003c5345,
0x007803c8,
0x003de3c6,
0x0040f187,
0x0044c607,
0x00500380,
0x00540400,
0x005802c0,
0x005c0440,
0x00640500,
0x00680540,
0x006c0580,
0x007005c0,
0x010004c9,
0x004e14c6,
0xdf800809,
0x0079b643,
0x0079e482,
0x00659783,
0x006db783,
0x0079c683,
0x0079e482,
0x0069a783,
0x0071c783,
0x00740640,
0x00780680,
0x0001e787,
0x00040007,
0x00041047,
0x00081787,
0x000c2007,
0x001030c7,
0x00144087,
0x00700940,
0x00185147,
0x00721706,
0x01000709,
0x00186187,
0xfe000809,
0x001c5187,
0x00700980,
0x002071c7,
0x00721706,
0x01000709,
0x00208207,
0xfe000809,
0x00247207,
0x007009c0,
0x00289247,
0x00721706,
0x01000709,
0x0028a287,
0xfe000809,
0x002c9287,
0x00700980,
0x0030b2c7,
0x00721706,
0x01000709,
0x0030c307,
0xfe000809,
0x00347307,
0x00700a00,
0x0038d347,
0x00721706,
0x01000709,
0x0038e387,
0xfe000809,
0x003cd387,
0x00700a40,
0x0040f3c7,
0x00721706,
0x01000709,
0x00410407,
0xfe000809,
0x0044f407,
0x00700a00,
0x00491447,
0x00721706,
0x01000709,
0x00492487,
0xfe000809,
0x004cd487,
0x00700940,
0x005134c7,
0x00721706,
0x01000709,
0x00514507,
0xfe000809,
0x00543507,
0x007d5747,
0x0000000a,
0x0000000a,
0x0000000a,
0x0000000a,
};
static const uint32_t program_len = 141;
#else
static const uint32_t program[16] = {
0x00640a40,
0x00680840,
0x0000000a,
0x0000000a
};
static const uint32_t program_len = 3;
#endif
/*
* Attach all the sub-devices we can find
*/
void
sbusfpga_curve25519engine_attach(device_t parent, device_t self, void *aux)
{
struct sbus_attach_args *sa = aux;
struct sbusfpga_curve25519engine_softc *sc = device_private(self);
struct sbus_softc *sbsc = device_private(parent);
int node;
int sbusburst;
sc->sc_bustag = sa->sa_bustag;
sc->sc_dmatag = sa->sa_dmatag;
sc->sc_dev = self;
aprint_normal("\n");
if (sa->sa_nreg < 3) {
aprint_error(": Not enough registers spaces\n");
return;
}
/* map registers */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[0].oa_space /* sa_slot */,
sa->sa_reg[0].oa_base /* sa_offset */,
sa->sa_reg[0].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_curve25519engine) != 0) {
aprint_error(": cannot map Curve25519Engine registers\n");
return;
} else {
aprint_normal_dev(self, "Curve25519Engine registers @ %p\n", (void*)sc->sc_bhregs_curve25519engine);
}
/* map microcode */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[1].oa_space /* sa_slot */,
sa->sa_reg[1].oa_base /* sa_offset */,
sa->sa_reg[1].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_microcode) != 0) {
aprint_error(": cannot map Curve25519Engine microcode\n");
return;
} else {
aprint_normal_dev(self, "Curve25519Engine microcode @ %p\n", (void*)sc->sc_bhregs_microcode);
}
/* map register file */
if (sbus_bus_map(sc->sc_bustag,
sa->sa_reg[2].oa_space /* sa_slot */,
sa->sa_reg[2].oa_base /* sa_offset */,
sa->sa_reg[2].oa_size /* sa_size */,
BUS_SPACE_MAP_LINEAR,
&sc->sc_bhregs_regfile) != 0) {
aprint_error(": cannot map Curve25519Engine regfile\n");
return;
} else {
aprint_normal_dev(self, "Curve25519Engine regfile @ %p\n", (void*)sc->sc_bhregs_regfile);
}
sc->sc_bufsiz_curve25519engine = sa->sa_reg[0].oa_size;
sc->sc_bufsiz_microcode = sa->sa_reg[1].oa_size;
sc->sc_bufsiz_regfile = sa->sa_reg[2].oa_size;
node = sc->sc_node = sa->sa_node;
/*
* Get transfer burst size from PROM
*/
sbusburst = sbsc->sc_burst;
if (sbusburst == 0)
sbusburst = SBUS_BURST_32 - 1; /* 1->16 */
sc->sc_burst = prom_getpropint(node, "burst-sizes", -1);
if (sc->sc_burst == -1)
/* take SBus burst sizes */
sc->sc_burst = sbusburst;
/* Clamp at parent's burst sizes */
sc->sc_burst &= sbusburst;
aprint_normal("\n");
aprint_normal_dev(self, "nid 0x%x, bustag %p, burst 0x%x (parent 0x%0x)\n",
sc->sc_node,
sc->sc_bustag,
sc->sc_burst,
sbsc->sc_burst);
if (init_program(sc)) {
if (init_program(sc)) {
aprint_normal_dev(sc->sc_dev, "INIT - FAILED\n");
sc->initialized = 0;
} else {
sc->initialized = 1;
}
} else {
sc->initialized = 1;
}
}
#define CONFIG_CSR_DATA_WIDTH 32
// define CSR_LEDS_BASE & others to avoid defining the CSRs of HW we don't handle
#define CSR_LEDS_BASE
//#define CSR_CURVE25519ENGINE_BASE
#define CSR_DDRPHY_BASE
#define CSR_EXCHANGE_WITH_MEM_BASE
#define CSR_SDRAM_BASE
#define CSR_SDBLOCK2MEM_BASE
#define CSR_SDCORE_BASE
#define CSR_SDIRQ_BASE
#define CSR_SDMEM2BLOCK_BASE
#define CSR_SDPHY_BASE
#define CSR_TRNG_BASE
#include "dev/sbus/litex_csr.h"
#undef CSR_LEDS_BASE
//#undef CSR_CURVE25519ENGINE_BASE
#undef CSR_DDRPHY_BASE
#undef CSR_EXCHANGE_WITH_MEM_BASE
#undef CSR_SDRAM_BASE
#undef CSR_SDBLOCK2MEM_BASE
#undef CSR_SDCORE_BASE
#undef CSR_SDIRQ_BASE
#undef CSR_SDMEM2BLOCK_BASE
#undef CSR_SDPHY_BASE
#undef CSR_TRNG_BASE
static int init_program(struct sbusfpga_curve25519engine_softc *sc) {
/* the microcode is a the beginning */
int err = 0;
uint32_t i;
/* first we need to turn the engine power on ... */
if ((curve25519engine_power_read(sc) & 1) == 0) {
curve25519engine_power_write(sc, 1);
delay(2);
}
for (i = 0 ; i < program_len + 1 ; i++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4), program[i]);
if ((i%8)==7)
delay(1);
}
curve25519engine_window_write(sc, 0); /* could use window_window to access fields, but it creates a RMW cycle for nothing */
curve25519engine_mpstart_write(sc, 0);
curve25519engine_mplen_write(sc, program_len);
aprint_normal_dev(sc->sc_dev, "INIT - Curve25519Engine status: 0x%08x\n", curve25519engine_status_read(sc));
#if 1
/* double check */
u_int32_t x;
int count = 0;
for (i = 0 ; i < program_len + 1 && count < 10; i++) {
x = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_microcode, (i*4));
if (x != program[i]) {
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine program failure: [%d] 0x%08x <> 0x%08x\n", i, x, program[i]);
err = 1;
count ++;
}
if ((i%8)==7)
delay(1);
}
if ((x = curve25519engine_window_read(sc)) != 0) {
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine register failure: window = 0x%08x\n", x);
err = 1;
}
if ((x = curve25519engine_mpstart_read(sc)) != 0) {
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine register failure: mpstart = 0x%08x\n", x);
err = 1;
}
if ((x = curve25519engine_mplen_read(sc)) != program_len) {
aprint_error_dev(sc->sc_dev, "INIT - Curve25519Engine register failure: mplen = 0x%08x\n", x);
err = 1;
}
#endif
curve25519engine_power_write(sc, 0);
return err;
}
static int write_inputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusfpga_curve25519engine_montgomeryjob *job, const int window) {
const uint32_t base = window * 0x400;
int i;
uint32_t status = curve25519engine_status_read(sc);
int err = 0;
if (status & 1) {
aprint_error_dev(sc->sc_dev, "WRITE - Curve25519Engine status: 0x%08x, still running?\n", status);
return -ENXIO;
}
/* first we need to turn the engine power on ... */
if ((curve25519engine_power_read(sc) & 1) == 0) {
curve25519engine_power_write(sc, 1);
delay(2);
}
#define REG_BASE(reg) (base + (reg * 32))
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
for (i = 0 ; i < 8 ; i ++) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i), job->affine_u[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i), job->x0_u[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(26,i), job->x0_w[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(27,i), job->x1_u[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(28,i), job->x1_w[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(31,i), job->scalar[i]);
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(19,i), ((i == 0) ? 254 : 0));
delay(1);
}
#undef SUBREG_ADDR
#undef REG_BASE
#if 1
#define REG_BASE(reg) (base + (reg * 32))
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
for (i = 0 ; i < 8 && !err; i ++) {
if (job->affine_u[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i))) err = ENXIO;
if (job->x0_u[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i))) err = ENXIO;
if (job->x0_w[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(26,i))) err = ENXIO;
if (job->x1_u[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(27,i))) err = ENXIO;
if (job->x1_w[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(28,i))) err = ENXIO;
if (job->scalar[i] != bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(31,i))) err = ENXIO;
delay(1);
}
if (err) aprint_error_dev(sc->sc_dev, "WRITE - data did not read-write properly\n");
#undef SUBREG_ADDR
#undef REG_BASE
#endif
return err;
}
static int start_job(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t status = curve25519engine_status_read(sc);
if (status & 1) {
aprint_error_dev(sc->sc_dev, "START - Curve25519Engine status: 0x%08x, still running?\n", status);
return -ENXIO;
}
curve25519engine_control_write(sc, 1);
aprint_normal_dev(sc->sc_dev, "START - Curve25519Engine status: 0x%08x\n", curve25519engine_status_read(sc));
return 0;
}
static int wait_job(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t status = curve25519engine_status_read(sc);
int count = 0;
while ((status & 1) && (count < 50)) {
aprint_normal_dev(sc->sc_dev, "WAIT - ongoing, Curve25519Engine status: 0x%08x [%d]\n", status, count);
count ++;
delay(20);
status = curve25519engine_status_read(sc);
}
//curve25519engine_control_write(sc, 0);
if (status & 1) {
aprint_error_dev(sc->sc_dev, "WAIT - Curve25519Engine status: 0x%08x, did not finish in time? [0x%08x]\n", status, curve25519engine_instruction_read(sc));
return -ENXIO;
} else {
aprint_normal_dev(sc->sc_dev, "WAIT - Curve25519Engine status: 0x%08x [%d, 0x%08x]\n", status, count, curve25519engine_instruction_read(sc));
}
return 0;
}
static int read_outputs(struct sbusfpga_curve25519engine_softc *sc, struct sbusfpga_curve25519engine_montgomeryjob *job, const int window) {
const uint32_t base = window * 0x400;
int i;
uint32_t status = curve25519engine_status_read(sc);
if (status & 1) {
aprint_error_dev(sc->sc_dev, "READ - Curve25519Engine status: 0x%08x, still running?\n", status);
return -ENXIO;
}
#define REG_BASE(reg) (base + (reg * 32))
#define SUBREG_ADDR(reg, off) (REG_BASE(reg) + (off)*4)
for (i = 0 ; i < 8 ; i ++) {
job->affine_u[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(24,i));
job->x0_u[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(25,i));
job->x0_w[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(26,i));
job->x1_u[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(27,i));
job->x1_w[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(28,i));
job->scalar[i] = bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(31,i));
delay(1);
}
aprint_normal_dev(sc->sc_dev, "READ - Curve25519Engine 19 low 32 bits: 0x%08x\n", bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_regfile,SUBREG_ADDR(19,0)));
#undef SUBREG_ADDR
#undef REG_BASE
curve25519engine_power_write(sc, 0);
return 0;
}

View File

@@ -0,0 +1,49 @@
/* $NetBSD$ */
/*-
* Copyright (c) 2020 Romain Dolbeau <romain@dolbeau.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SBUSFPGA_CURVE25519ENGINE_H_
#define _SBUSFPGA_CURVE25519ENGINE_H_
struct sbusfpga_curve25519engine_softc {
device_t sc_dev; /* us as a device */
u_int sc_rev; /* revision */
int sc_node; /* PROM node ID */
int sc_burst; /* DVMA burst size in effect */
bus_space_tag_t sc_bustag; /* bus tag */
bus_space_handle_t sc_bhregs_curve25519engine; /* bus handle */
bus_space_handle_t sc_bhregs_microcode; /* bus handle */
bus_space_handle_t sc_bhregs_regfile; /* bus handle */
//void * sc_buffer; /* VA of the registers */
int sc_bufsiz_curve25519engine; /* Size of buffer */
int sc_bufsiz_microcode; /* Size of buffer */
int sc_bufsiz_regfile; /* Size of buffer */
bus_dma_tag_t sc_dmatag;
int initialized;
};
#endif /* _SBUSFPGA_CURVE25519ENGINE_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,21 @@
[package]
name = "engine_code"
version = "0.1.0"
authors = ["Romain Dolbeau <romain@dolbeau.org>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.engine25519-as]
git="https://github.com/betrusted-io/engine25519-as.git"
rev="6681e73c1fdc4a460b5ef9f9c7c91aef546d00f3"
[dev-dependencies.engine25519-as]
git="https://github.com/betrusted-io/engine25519-as.git"
rev="6681e73c1fdc4a460b5ef9f9c7c91aef546d00f3"
[[bin]]
name = "engine_code"
path = "engine_code.rs"

View File

@@ -0,0 +1,296 @@
#![recursion_limit="512"]
extern crate engine25519_as;
use engine25519_as::*;
fn main() -> std::io::Result<()> {
let mcode = assemble_engine25519!(
start:
// P.U in %20
// P.W in %21
// Q.U in %22
// Q.W in %23
// affine_PmQ in %24 // I
// %30 is the TRD scratch register and cswap dummy
// %29 is the subtraction temporary value register and k_t
// x0.U in %25 // I
// x0.W in %26 // I
// x1.U in %27 // I
// x1.W in %28 /// I
// %19 is the loop counter, starts with 254 (if 0, loop runs exactly once) // I
// %31 is the scalar // I
// %18 is the swap variable
psa %18, #0
// for i in (0..255).rev()
mainloop:
// let choice: u8 = (bits[i + 1] ^ bits[i]) as u8;
// ProjectivePoint::conditional_swap(&mut x0, &mut x1, choice.into());
xbt %29, %31 // orignally[k_t = (k>>t) & 1] now[k_t = k[254]]
shl %31, %31 // k = k<<1
xor %18, %18, %29 // swap ^= k_t
// cswap x0.U (%25), x1.U (%27)
xor %30, %25, %27
msk %30, %18, %30
xor %25, %30, %25
xor %27, %30, %27
// cswap x0.W (%26), x1.W (%28)
xor %30, %26, %28
msk %30, %18, %30
xor %26, %30, %26
xor %28, %30, %28
psa %18, %29 // swap = k_t
// differential_add_and_double(&mut x0, &mut x1, &affine_u);
psa %20, %25
psa %21, %26
psa %22, %27
psa %23, %28
// affine_u is already in %24
// let t0 = &P.U + &P.W;
add %0, %20, %21
trd %30, %0
sub %0, %0, %30
// let t1 = &P.U - &P.W;
sub %21, #3, %21 // negate &P.W using #FIELDPRIME (#3)
add %1, %20, %21
trd %30, %1
sub %1, %1, %30
// let t2 = &Q.U + &Q.W;
add %2, %22, %23
trd %30, %2
sub %2, %2, %30
// let t3 = &Q.U - &Q.W;
sub %23, #3, %23
add %3, %22, %23
trd %30, %3
sub %3, %3, %30
// let t4 = t0.square(); // (U_P + W_P)^2 = U_P^2 + 2 U_P W_P + W_P^2
mul %4, %0, %0
// let t5 = t1.square(); // (U_P - W_P)^2 = U_P^2 - 2 U_P W_P + W_P^2
mul %5, %1, %1
// let t6 = &t4 - &t5; // 4 U_P W_P
sub %29, #3, %5
add %6, %4, %29
trd %30, %6
sub %6, %6, %30
// let t7 = &t0 * &t3; // (U_P + W_P) (U_Q - W_Q) = U_P U_Q + W_P U_Q - U_P W_Q - W_P W_Q
mul %7, %0, %3
// let t8 = &t1 * &t2; // (U_P - W_P) (U_Q + W_Q) = U_P U_Q - W_P U_Q + U_P W_Q - W_P W_Q
mul %8, %1, %2
// let t9 = &t7 + &t8; // 2 (U_P U_Q - W_P W_Q)
add %9, %7, %8
trd %30, %9
sub %9, %9, %30
// let t10 = &t7 - &t8; // 2 (W_P U_Q - U_P W_Q)
sub %29, #3, %8
add %10, %7, %29
trd %30, %10
sub %10, %10, %30
// let t11 = t9.square(); // 4 (U_P U_Q - W_P W_Q)^2
mul %11, %9, %9
// let t12 = t10.square(); // 4 (W_P U_Q - U_P W_Q)^2
mul %12, %10, %10
// let t13 = &APLUS2_OVER_FOUR * &t6; // (A + 2) U_P U_Q
mul %13, #4, %6 // #4 is A+2/4
// let t14 = &t4 * &t5; // ((U_P + W_P)(U_P - W_P))^2 = (U_P^2 - W_P^2)^2
mul %14, %4, %5
// let t15 = &t13 + &t5; // (U_P - W_P)^2 + (A + 2) U_P W_P
add %15, %13, %5
trd %30, %15
sub %15, %15, %30
// let t16 = &t6 * &t15; // 4 (U_P W_P) ((U_P - W_P)^2 + (A + 2) U_P W_P)
mul %16, %6, %15
// let t17 = affine_PmQ * &t12; // U_D * 4 (W_P U_Q - U_P W_Q)^2
mul %17, %24, %12 // affine_PmQ loaded into %24
///// these can be eliminated down the road, but included for 1:1 algorithm correspodence to reference in early testing
// P.U = t14; // U_{P'} = (U_P + W_P)^2 (U_P - W_P)^2
psa %20, %14
// P.W = t16; // W_{P'} = (4 U_P W_P) ((U_P - W_P)^2 + ((A + 2)/4) 4 U_P W_P)
psa %21, %16
// let t18 = t11; // W_D * 4 (U_P U_Q - W_P W_Q)^2
// Q.U = t18; // U_{Q'} = W_D * 4 (U_P U_Q - W_P W_Q)^2
psa %22, %11 // collapsed two to save a register
// Q.W = t17; // W_{Q'} = U_D * 4 (W_P U_Q - U_P W_Q)^2
psa %23, %17
///// 'return' arguments for next iteration, can be optimized out later
psa %25, %20
psa %26, %21
psa %27, %22
psa %28, %23
brz end, %19 // if loop counter is 0, quit
sub %19, %19, #1 // subtract one from the loop counter and run again
brz mainloop, #0 // go back to the top
end:
// ProjectivePoint::conditional_swap(&mut x0, &mut x1, Choice::from(bits[0] as u8));
// cswap x0.U (%25), x1.U (%27)
xor %30, %25, %27
msk %30, %18, %30
xor %25, %30, %25
xor %27, %30, %27
// cswap x0.W (%26), x1.W (%28)
xor %30, %26, %28
msk %30, %18, %30
xor %26, %30, %26
xor %28, %30, %28
// AFFINE SPLICE -- pass arguments to the affine block
psa %29, %25
psa %30, %26
// W.invert() in %21
// U in %29
// W in %30
// result in %31
// loop counter in %28
// from FieldElement.invert()
// let (t19, t3) = self.pow22501(); // t19: 249..0 ; t3: 3,1,0
// let t0 = self.square(); // 1 e_0 = 2^1
mul %0, %30, %30 // self is W, e.g. %30
// let t1 = t0.square().square(); // 3 e_1 = 2^3
mul %1, %0, %0
mul %1, %1, %1
// let t2 = self * &t1; // 3,0 e_2 = 2^3 + 2^0
mul %2, %30, %1
// let t3 = &t0 * &t2; // 3,1,0
mul %3, %0, %2
// let t4 = t3.square(); // 4,2,1
mul %4, %3, %3
// let t5 = &t2 * &t4; // 4,3,2,1,0
mul %5, %2, %4
// let t6 = t5.pow2k(5); // 9,8,7,6,5
psa %28, #5 // coincidentally, constant #5 is the number 5
mul %6, %5, %5
pow2k_5:
sub %28, %28, #1 // %28 = %28 - 1
brz pow2k_5_exit, %28
mul %6, %6, %6
brz pow2k_5, #0
pow2k_5_exit:
// let t7 = &t6 * &t5; // 9,8,7,6,5,4,3,2,1,0
mul %7, %6, %5
// let t8 = t7.pow2k(10); // 19..10
psa %28, #6 // constant #6 is the number 10
mul %8, %7, %7
pow2k_10:
sub %28, %28, #1
brz pow2k_10_exit, %28
mul %8, %8, %8
brz pow2k_10, #0
pow2k_10_exit:
// let t9 = &t8 * &t7; // 19..0
mul %9, %8, %7
// let t10 = t9.pow2k(20); // 39..20
psa %28, #7 // constant #7 is the number 20
mul %10, %9, %9
pow2k_20:
sub %28, %28, #1
brz pow2k_20_exit, %28
mul %10, %10, %10
brz pow2k_20, #0
pow2k_20_exit:
// let t11 = &t10 * &t9; // 39..0
mul %11, %10, %9
// let t12 = t11.pow2k(10); // 49..10
psa %28, #6 // constant #6 is the number 10
mul %12, %11, %11
pow2k_10b:
sub %28, %28, #1
brz pow2k_10b_exit, %28
mul %12, %12, %12
brz pow2k_10b, #0
pow2k_10b_exit:
// let t13 = &t12 * &t7; // 49..0
mul %13, %12, %7
// let t14 = t13.pow2k(50); // 99..50
psa %28, #8 // constant #8 is the number 50
mul %14, %13, %13
pow2k_50a:
sub %28, %28, #1
brz pow2k_50a_exit, %28
mul %14, %14, %14
brz pow2k_50a, #0
pow2k_50a_exit:
// let t15 = &t14 * &t13; // 99..0
mul %15, %14, %13
// let t16 = t15.pow2k(100); // 199..100
psa %28, #9 // constant #9 is the number 100
mul %16, %15, %15
pow2k_100:
sub %28, %28, #1
brz pow2k_100_exit, %28
mul %16, %16, %16
brz pow2k_100, #0
pow2k_100_exit:
// let t17 = &t16 * &t15; // 199..0
mul %17, %16, %15
// let t18 = t17.pow2k(50); // 249..50
psa %28, #8 // constant #8 is the number 50
mul %18, %17, %17
pow2k_50b:
sub %28, %28, #1
brz pow2k_50b_exit, %28
mul %18, %18, %18
brz pow2k_50b, #0
pow2k_50b_exit:
// let t19 = &t18 * &t13; // 249..0
mul %19, %18, %13
//(t19, t3) // just a return value, values are already there, do nothing
//let t20 = t19.pow2k(5); // 254..5
psa %28, #5
mul %20, %19, %19
pow2k_5_last:
sub %28, %28, #1
brz pow2k_5_last_exit, %28
mul %20, %20, %20
brz pow2k_5_last, #0
pow2k_5_last_exit:
//let t21 = &t20 * &t3; // 254..5,3,1,0
mul %21, %20, %3
// u = &self.U * &self.W.invert()
mul %31, %29, %21
fin // finish execution
);
let mcode2 = assemble_engine25519!(
start:
// P.U in %20
// P.W in %21
// Q.U in %22
// Q.W in %23
// affine_PmQ in %24 // I
// %30 is the TRD scratch register and cswap dummy
// %29 is the subtraction temporary value register and k_t
// x0.U in %25 // I
// x0.W in %26 // I
// x1.U in %27 // I
// x1.W in %28 /// I
// %19 is the loop counter, starts with 254 (if 0, loop runs exactly once) // I
// %31 is the scalar // I
// %18 is the swap variable
psa %25, #9
psa %26, #1
fin
);
let mut pos = 0;
while pos < mcode2.len() {
println!("0x{:08x},", mcode2[pos]);
pos = pos + 1;
}
Ok(())
}

View File

@@ -1,5 +1,5 @@
//--------------------------------------------------------------------------------
// Auto-generated by Migen (3ffd64c) & LiteX (8a644c90) on 2021-07-20 07:32:43
// Auto-generated by Migen (3ffd64c) & LiteX (8a644c90) on 2021-07-25 05:25:02
//--------------------------------------------------------------------------------
#ifndef __GENERATED_CSR_H
#define __GENERATED_CSR_H
@@ -20,9 +20,430 @@ static inline void leds_out_write(struct sbusfpga_leds_softc *sc, uint32_t v) {
}
#endif // CSR_LEDS_BASE
/* curve25519engine */
#ifndef CSR_CURVE25519ENGINE_BASE
#define CSR_CURVE25519ENGINE_BASE (CSR_BASE + 0x1000L)
#define CSR_CURVE25519ENGINE_WINDOW_ADDR (CSR_CURVE25519ENGINE_BASE + 0x0L)
#define CSR_CURVE25519ENGINE_WINDOW_SIZE 1
static inline uint32_t curve25519engine_window_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x0L);
}
static inline void curve25519engine_window_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x0L, v);
}
#define CSR_CURVE25519ENGINE_WINDOW_WINDOW_OFFSET 0
#define CSR_CURVE25519ENGINE_WINDOW_WINDOW_SIZE 4
static inline uint32_t curve25519engine_window_window_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 4)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_window_window_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_window_read(sc);
return curve25519engine_window_window_extract(sc, word);
}
static inline uint32_t curve25519engine_window_window_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 4)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_window_window_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_window_read(sc);
uint32_t newword = curve25519engine_window_window_replace(sc, oldword, plain_value);
curve25519engine_window_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_MPSTART_ADDR (CSR_CURVE25519ENGINE_BASE + 0x4L)
#define CSR_CURVE25519ENGINE_MPSTART_SIZE 1
static inline uint32_t curve25519engine_mpstart_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x4L);
}
static inline void curve25519engine_mpstart_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x4L, v);
}
#define CSR_CURVE25519ENGINE_MPSTART_MPSTART_OFFSET 0
#define CSR_CURVE25519ENGINE_MPSTART_MPSTART_SIZE 10
static inline uint32_t curve25519engine_mpstart_mpstart_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 10)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_mpstart_mpstart_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_mpstart_read(sc);
return curve25519engine_mpstart_mpstart_extract(sc, word);
}
static inline uint32_t curve25519engine_mpstart_mpstart_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 10)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_mpstart_mpstart_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_mpstart_read(sc);
uint32_t newword = curve25519engine_mpstart_mpstart_replace(sc, oldword, plain_value);
curve25519engine_mpstart_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_MPLEN_ADDR (CSR_CURVE25519ENGINE_BASE + 0x8L)
#define CSR_CURVE25519ENGINE_MPLEN_SIZE 1
static inline uint32_t curve25519engine_mplen_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x8L);
}
static inline void curve25519engine_mplen_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x8L, v);
}
#define CSR_CURVE25519ENGINE_MPLEN_MPLEN_OFFSET 0
#define CSR_CURVE25519ENGINE_MPLEN_MPLEN_SIZE 10
static inline uint32_t curve25519engine_mplen_mplen_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 10)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_mplen_mplen_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_mplen_read(sc);
return curve25519engine_mplen_mplen_extract(sc, word);
}
static inline uint32_t curve25519engine_mplen_mplen_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 10)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_mplen_mplen_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_mplen_read(sc);
uint32_t newword = curve25519engine_mplen_mplen_replace(sc, oldword, plain_value);
curve25519engine_mplen_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_CONTROL_ADDR (CSR_CURVE25519ENGINE_BASE + 0xcL)
#define CSR_CURVE25519ENGINE_CONTROL_SIZE 1
static inline uint32_t curve25519engine_control_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0xcL);
}
static inline void curve25519engine_control_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0xcL, v);
}
#define CSR_CURVE25519ENGINE_CONTROL_GO_OFFSET 0
#define CSR_CURVE25519ENGINE_CONTROL_GO_SIZE 1
static inline uint32_t curve25519engine_control_go_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_control_go_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_control_read(sc);
return curve25519engine_control_go_extract(sc, word);
}
static inline uint32_t curve25519engine_control_go_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_control_go_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_control_read(sc);
uint32_t newword = curve25519engine_control_go_replace(sc, oldword, plain_value);
curve25519engine_control_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_MPRESUME_ADDR (CSR_CURVE25519ENGINE_BASE + 0x10L)
#define CSR_CURVE25519ENGINE_MPRESUME_SIZE 1
static inline uint32_t curve25519engine_mpresume_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x10L);
}
#define CSR_CURVE25519ENGINE_MPRESUME_MPRESUME_OFFSET 0
#define CSR_CURVE25519ENGINE_MPRESUME_MPRESUME_SIZE 10
static inline uint32_t curve25519engine_mpresume_mpresume_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 10)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_mpresume_mpresume_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_mpresume_read(sc);
return curve25519engine_mpresume_mpresume_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_POWER_ADDR (CSR_CURVE25519ENGINE_BASE + 0x14L)
#define CSR_CURVE25519ENGINE_POWER_SIZE 1
static inline uint32_t curve25519engine_power_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x14L);
}
static inline void curve25519engine_power_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x14L, v);
}
#define CSR_CURVE25519ENGINE_POWER_ON_OFFSET 0
#define CSR_CURVE25519ENGINE_POWER_ON_SIZE 1
static inline uint32_t curve25519engine_power_on_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_power_on_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_power_read(sc);
return curve25519engine_power_on_extract(sc, word);
}
static inline uint32_t curve25519engine_power_on_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_power_on_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_power_read(sc);
uint32_t newword = curve25519engine_power_on_replace(sc, oldword, plain_value);
curve25519engine_power_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_POWER_PAUSE_REQ_OFFSET 1
#define CSR_CURVE25519ENGINE_POWER_PAUSE_REQ_SIZE 1
static inline uint32_t curve25519engine_power_pause_req_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t curve25519engine_power_pause_req_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_power_read(sc);
return curve25519engine_power_pause_req_extract(sc, word);
}
static inline uint32_t curve25519engine_power_pause_req_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void curve25519engine_power_pause_req_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_power_read(sc);
uint32_t newword = curve25519engine_power_pause_req_replace(sc, oldword, plain_value);
curve25519engine_power_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_STATUS_ADDR (CSR_CURVE25519ENGINE_BASE + 0x18L)
#define CSR_CURVE25519ENGINE_STATUS_SIZE 1
static inline uint32_t curve25519engine_status_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x18L);
}
#define CSR_CURVE25519ENGINE_STATUS_RUNNING_OFFSET 0
#define CSR_CURVE25519ENGINE_STATUS_RUNNING_SIZE 1
static inline uint32_t curve25519engine_status_running_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_status_running_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_status_read(sc);
return curve25519engine_status_running_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_STATUS_MPC_OFFSET 1
#define CSR_CURVE25519ENGINE_STATUS_MPC_SIZE 10
static inline uint32_t curve25519engine_status_mpc_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 10)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t curve25519engine_status_mpc_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_status_read(sc);
return curve25519engine_status_mpc_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_STATUS_PAUSE_GNT_OFFSET 11
#define CSR_CURVE25519ENGINE_STATUS_PAUSE_GNT_SIZE 1
static inline uint32_t curve25519engine_status_pause_gnt_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 11) & mask );
}
static inline uint32_t curve25519engine_status_pause_gnt_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_status_read(sc);
return curve25519engine_status_pause_gnt_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_STATUS_SIGILL_OFFSET 12
#define CSR_CURVE25519ENGINE_STATUS_SIGILL_SIZE 1
static inline uint32_t curve25519engine_status_sigill_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 12) & mask );
}
static inline uint32_t curve25519engine_status_sigill_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_status_read(sc);
return curve25519engine_status_sigill_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_STATUS_FINISHED_OFFSET 13
#define CSR_CURVE25519ENGINE_STATUS_FINISHED_SIZE 1
static inline uint32_t curve25519engine_status_finished_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 13) & mask );
}
static inline uint32_t curve25519engine_status_finished_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_status_read(sc);
return curve25519engine_status_finished_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_EV_STATUS_ADDR (CSR_CURVE25519ENGINE_BASE + 0x1cL)
#define CSR_CURVE25519ENGINE_EV_STATUS_SIZE 1
static inline uint32_t curve25519engine_ev_status_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x1cL);
}
#define CSR_CURVE25519ENGINE_EV_STATUS_FINISHED_OFFSET 0
#define CSR_CURVE25519ENGINE_EV_STATUS_FINISHED_SIZE 1
static inline uint32_t curve25519engine_ev_status_finished_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_ev_status_finished_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_status_read(sc);
return curve25519engine_ev_status_finished_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_EV_STATUS_ILLEGAL_OPCODE_OFFSET 1
#define CSR_CURVE25519ENGINE_EV_STATUS_ILLEGAL_OPCODE_SIZE 1
static inline uint32_t curve25519engine_ev_status_illegal_opcode_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t curve25519engine_ev_status_illegal_opcode_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_status_read(sc);
return curve25519engine_ev_status_illegal_opcode_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_EV_PENDING_ADDR (CSR_CURVE25519ENGINE_BASE + 0x20L)
#define CSR_CURVE25519ENGINE_EV_PENDING_SIZE 1
static inline uint32_t curve25519engine_ev_pending_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x20L);
}
static inline void curve25519engine_ev_pending_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x20L, v);
}
#define CSR_CURVE25519ENGINE_EV_PENDING_FINISHED_OFFSET 0
#define CSR_CURVE25519ENGINE_EV_PENDING_FINISHED_SIZE 1
static inline uint32_t curve25519engine_ev_pending_finished_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_ev_pending_finished_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_pending_read(sc);
return curve25519engine_ev_pending_finished_extract(sc, word);
}
static inline uint32_t curve25519engine_ev_pending_finished_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_ev_pending_finished_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_ev_pending_read(sc);
uint32_t newword = curve25519engine_ev_pending_finished_replace(sc, oldword, plain_value);
curve25519engine_ev_pending_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_EV_PENDING_ILLEGAL_OPCODE_OFFSET 1
#define CSR_CURVE25519ENGINE_EV_PENDING_ILLEGAL_OPCODE_SIZE 1
static inline uint32_t curve25519engine_ev_pending_illegal_opcode_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t curve25519engine_ev_pending_illegal_opcode_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_pending_read(sc);
return curve25519engine_ev_pending_illegal_opcode_extract(sc, word);
}
static inline uint32_t curve25519engine_ev_pending_illegal_opcode_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void curve25519engine_ev_pending_illegal_opcode_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_ev_pending_read(sc);
uint32_t newword = curve25519engine_ev_pending_illegal_opcode_replace(sc, oldword, plain_value);
curve25519engine_ev_pending_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_EV_ENABLE_ADDR (CSR_CURVE25519ENGINE_BASE + 0x24L)
#define CSR_CURVE25519ENGINE_EV_ENABLE_SIZE 1
static inline uint32_t curve25519engine_ev_enable_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x24L);
}
static inline void curve25519engine_ev_enable_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t v) {
bus_space_write_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x24L, v);
}
#define CSR_CURVE25519ENGINE_EV_ENABLE_FINISHED_OFFSET 0
#define CSR_CURVE25519ENGINE_EV_ENABLE_FINISHED_SIZE 1
static inline uint32_t curve25519engine_ev_enable_finished_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_ev_enable_finished_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_enable_read(sc);
return curve25519engine_ev_enable_finished_extract(sc, word);
}
static inline uint32_t curve25519engine_ev_enable_finished_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 0))) | (mask & plain_value)<< 0 ;
}
static inline void curve25519engine_ev_enable_finished_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_ev_enable_read(sc);
uint32_t newword = curve25519engine_ev_enable_finished_replace(sc, oldword, plain_value);
curve25519engine_ev_enable_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_EV_ENABLE_ILLEGAL_OPCODE_OFFSET 1
#define CSR_CURVE25519ENGINE_EV_ENABLE_ILLEGAL_OPCODE_SIZE 1
static inline uint32_t curve25519engine_ev_enable_illegal_opcode_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 1) & mask );
}
static inline uint32_t curve25519engine_ev_enable_illegal_opcode_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_ev_enable_read(sc);
return curve25519engine_ev_enable_illegal_opcode_extract(sc, word);
}
static inline uint32_t curve25519engine_ev_enable_illegal_opcode_replace(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword, uint32_t plain_value) {
uint32_t mask = ((1 << 1)-1);
return (oldword & (~(mask << 1))) | (mask & plain_value)<< 1 ;
}
static inline void curve25519engine_ev_enable_illegal_opcode_write(struct sbusfpga_curve25519engine_softc *sc, uint32_t plain_value) {
uint32_t oldword = curve25519engine_ev_enable_read(sc);
uint32_t newword = curve25519engine_ev_enable_illegal_opcode_replace(sc, oldword, plain_value);
curve25519engine_ev_enable_write(sc, newword);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_ADDR (CSR_CURVE25519ENGINE_BASE + 0x28L)
#define CSR_CURVE25519ENGINE_INSTRUCTION_SIZE 1
static inline uint32_t curve25519engine_instruction_read(struct sbusfpga_curve25519engine_softc *sc) {
return bus_space_read_4(sc->sc_bustag, sc->sc_bhregs_curve25519engine, 0x28L);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_OPCODE_OFFSET 0
#define CSR_CURVE25519ENGINE_INSTRUCTION_OPCODE_SIZE 6
static inline uint32_t curve25519engine_instruction_opcode_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 6)-1);
return ( (oldword >> 0) & mask );
}
static inline uint32_t curve25519engine_instruction_opcode_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_opcode_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_RA_OFFSET 6
#define CSR_CURVE25519ENGINE_INSTRUCTION_RA_SIZE 5
static inline uint32_t curve25519engine_instruction_ra_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 5)-1);
return ( (oldword >> 6) & mask );
}
static inline uint32_t curve25519engine_instruction_ra_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_ra_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_CA_OFFSET 11
#define CSR_CURVE25519ENGINE_INSTRUCTION_CA_SIZE 1
static inline uint32_t curve25519engine_instruction_ca_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 11) & mask );
}
static inline uint32_t curve25519engine_instruction_ca_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_ca_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_RB_OFFSET 12
#define CSR_CURVE25519ENGINE_INSTRUCTION_RB_SIZE 5
static inline uint32_t curve25519engine_instruction_rb_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 5)-1);
return ( (oldword >> 12) & mask );
}
static inline uint32_t curve25519engine_instruction_rb_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_rb_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_CB_OFFSET 17
#define CSR_CURVE25519ENGINE_INSTRUCTION_CB_SIZE 1
static inline uint32_t curve25519engine_instruction_cb_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 1)-1);
return ( (oldword >> 17) & mask );
}
static inline uint32_t curve25519engine_instruction_cb_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_cb_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_WD_OFFSET 18
#define CSR_CURVE25519ENGINE_INSTRUCTION_WD_SIZE 5
static inline uint32_t curve25519engine_instruction_wd_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 5)-1);
return ( (oldword >> 18) & mask );
}
static inline uint32_t curve25519engine_instruction_wd_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_wd_extract(sc, word);
}
#define CSR_CURVE25519ENGINE_INSTRUCTION_IMMEDIATE_OFFSET 23
#define CSR_CURVE25519ENGINE_INSTRUCTION_IMMEDIATE_SIZE 9
static inline uint32_t curve25519engine_instruction_immediate_extract(struct sbusfpga_curve25519engine_softc *sc, uint32_t oldword) {
uint32_t mask = ((1 << 9)-1);
return ( (oldword >> 23) & mask );
}
static inline uint32_t curve25519engine_instruction_immediate_read(struct sbusfpga_curve25519engine_softc *sc) {
uint32_t word = curve25519engine_instruction_read(sc);
return curve25519engine_instruction_immediate_extract(sc, word);
}
#endif // CSR_CURVE25519ENGINE_BASE
/* ddrphy */
#ifndef CSR_DDRPHY_BASE
#define CSR_DDRPHY_BASE (CSR_BASE + 0x1000L)
#define CSR_DDRPHY_BASE (CSR_BASE + 0x2000L)
#define CSR_DDRPHY_RST_ADDR (CSR_DDRPHY_BASE + 0x0L)
#define CSR_DDRPHY_RST_SIZE 1
static inline uint32_t ddrphy_rst_read(struct sbusfpga_ddrphy_softc *sc) {
@@ -131,7 +552,7 @@ static inline void ddrphy_wrphase_write(struct sbusfpga_ddrphy_softc *sc, uint32
/* exchange_with_mem */
#ifndef CSR_EXCHANGE_WITH_MEM_BASE
#define CSR_EXCHANGE_WITH_MEM_BASE (CSR_BASE + 0x2000L)
#define CSR_EXCHANGE_WITH_MEM_BASE (CSR_BASE + 0x3000L)
#define CSR_EXCHANGE_WITH_MEM_BLK_SIZE_ADDR (CSR_EXCHANGE_WITH_MEM_BASE + 0x0L)
#define CSR_EXCHANGE_WITH_MEM_BLK_SIZE_SIZE 1
static inline uint32_t exchange_with_mem_blk_size_read(struct sbusfpga_exchange_with_mem_softc *sc) {
@@ -200,7 +621,7 @@ static inline uint32_t exchange_with_mem_wr_tosdram_read(struct sbusfpga_exchang
/* sdram */
#ifndef CSR_SDRAM_BASE
#define CSR_SDRAM_BASE (CSR_BASE + 0x3000L)
#define CSR_SDRAM_BASE (CSR_BASE + 0x4000L)
#define CSR_SDRAM_DFII_CONTROL_ADDR (CSR_SDRAM_BASE + 0x0L)
#define CSR_SDRAM_DFII_CONTROL_SIZE 1
static inline uint32_t sdram_dfii_control_read(struct sbusfpga_sdram_softc *sc) {
@@ -469,7 +890,7 @@ static inline uint32_t sdram_dfii_pi3_rddata_read(struct sbusfpga_sdram_softc *s
/* trng */
#ifndef CSR_TRNG_BASE
#define CSR_TRNG_BASE (CSR_BASE + 0x4000L)
#define CSR_TRNG_BASE (CSR_BASE + 0x5000L)
#define CSR_TRNG_CTRL_ADDR (CSR_TRNG_BASE + 0x0L)
#define CSR_TRNG_CTRL_SIZE 1
static inline uint32_t trng_ctrl_read(struct sbusfpga_trng_softc *sc) {

View File

@@ -1,11 +1,13 @@
\ auto-generated base regions for CSRs in the PROM
h# 40000 constant sbusfpga_csraddr_leds
h# 41000 constant sbusfpga_csraddr_ddrphy
h# 42000 constant sbusfpga_csraddr_exchange_with_mem
h# 43000 constant sbusfpga_csraddr_sdram
h# 44000 constant sbusfpga_csraddr_trng
h# 41000 constant sbusfpga_csraddr_curve25519engine
h# 42000 constant sbusfpga_csraddr_ddrphy
h# 43000 constant sbusfpga_csraddr_exchange_with_mem
h# 44000 constant sbusfpga_csraddr_sdram
h# 45000 constant sbusfpga_csraddr_trng
h# 80000 constant sbusfpga_regionaddr_usb_host_ctrl
h# 0 constant sbusfpga_regionaddr_prom
h# 80000000 constant sbusfpga_regionaddr_main_ram
h# fc000000 constant sbusfpga_regionaddr_usb_fake_dma
h# a0000 constant sbusfpga_regionaddr_curve25519engine
h# 40000 constant sbusfpga_regionaddr_csr

View File

@@ -24,8 +24,6 @@ my-space constant my-sbus-space
: map-in-led ( -- ) my-sbus-address sbusfpga_csraddr_leds + my-sbus-space h# 4 map-in is led-virt ;
: map-out-led ( -- ) led-virt h# 4 map-out ;
\ external
: setled! ( pattern -- )
map-in-led
led-virt l! ( pattern virt -- )
@@ -160,8 +158,6 @@ my-space constant my-sbus-space
: map-in-trng ( -- ) my-sbus-address sbusfpga_csraddr_trng + my-sbus-space h# 8 map-in is trng-virt ;
: map-out-trng ( -- ) trng-virt h# 8 map-out ;
\ external
: disabletrng! ( -- )
map-in-trng
1 trng-virt l! ( pattern virt -- )
@@ -170,4 +166,55 @@ my-space constant my-sbus-space
disabletrng!
\ OpenBIOS tokenizer won't accept finish-device without new-device
\ Cheat by using the tokenizer so we can do OpenBoot 2.x siblings
\ tokenizer[ 01 emit-byte h# 27 emit-byte h# 01 emit-byte h# 1f emit-byte ]tokenizer
\ The OpenFirmware tokenizer does accept the 'clean' syntax
finish-device
\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ CURVE25519
new-device
\ Absolute minimal stuff; name & registers def.
" betrustedc25519e" device-name
\ one page of CSR registers, plus the memory
\ we might want to replace the slave memory access
\ by another instance of exchange_with_mem ?
\ we split the memory space in two
\ 0x1000 @ 0x0 for the microcode
\ 0x10000 @ 0x10000 for the register file
my-address sbusfpga_csraddr_curve25519engine + my-space xdrphys \ Offset#1
h# 1000 xdrint xdr+ \ Merge size#1
my-address sbusfpga_regionaddr_curve25519engine + my-space xdrphys xdr+ \ Merge offset#2
h# 1000 xdrint xdr+ \ Merge size#2
my-address sbusfpga_regionaddr_curve25519engine h# 10000 + + my-space xdrphys xdr+ \ Merge offset#3
h# 10000 xdrint xdr+ \ Merge size#3
" reg" attribute
\ we don't support ET or HWORD
h# 7d xdrint " slave-burst-sizes" attribute
h# 7d xdrint " burst-sizes" attribute
headers
-1 instance value curve25519engine-virt
-1 instance value curve25519engine-microcode-virt
-1 instance value curve25519engine-regfile-virt
my-address constant my-sbus-address
my-space constant my-sbus-space
: map-in ( adr space size -- virt ) " map-in" $call-parent ;
: map-out ( virt size -- ) " map-out" $call-parent ;
: map-in-curve25519engine ( -- )
my-sbus-address sbusfpga_csraddr_curve25519engine + my-sbus-space h# 1000 map-in is curve25519engine-virt
my-sbus-address sbusfpga_regionaddr_curve25519engine + my-sbus-space h# 1000 map-in is curve25519engine-microcode-virt
my-sbus-address sbusfpga_regionaddr_curve25519engine h# 10000 + + my-sbus-space h# 10000 map-in is curve25519engine-regfile-virt
;
: map-out-curve25519engine ( -- )
curve25519engine-virt h# 1000 map-out
curve25519engine-microcode-virt h# 1000 map-out
curve25519engine-regfile-virt h# 10000 map-out
;
end0

View File

@@ -25,11 +25,13 @@ ADDR_PHYS_LOW = 0
ADDR_PFX_HIGH = ADDR_PHYS_HIGH
ADDR_PFX_LOW = 16 ## 64 KiB per prefix
ADDR_PFX_LENGTH = 12 #(1 + ADDR_PFX_HIGH - ADDR_PFX_LOW)
ROM_ADDR_PFX = Signal(12, reset = 0)
WISHBONE_CSR_ADDR_PFX = Signal(12, reset = 4)
USBOHCI_ADDR_PFX = Signal(12, reset = 8)
SRAM_ADDR_PFX = Signal(12, reset = 9)
SDRAM_ADDR_PFX = Signal(12, reset = 2048)
ROM_ADDR_PFX = Signal(12, reset = 0x000)
WISHBONE_CSR_ADDR_PFX = Signal(12, reset = 0x004)
USBOHCI_ADDR_PFX = Signal(12, reset = 0x008)
SRAM_ADDR_PFX = Signal(12, reset = 0x009)
ENGINE_ADDR_PFXA = Signal(12, reset = 0x00a)
ENGINE_ADDR_PFXB = Signal(12, reset = 0x00b)
#SDRAM_ADDR_PFX = Signal(12, reset = 2048)
wishbone_default_timeout = 120 ## must be > sbus_default_timeout
sbus_default_timeout = 100 ## must be below 127 as we can wait twice on it inside the 255 cycles
@@ -430,7 +432,8 @@ class SBusFPGABus(Module):
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == USBOHCI_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ENGINE_ADDR_PFXA) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ENGINE_ADDR_PFXB)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@@ -462,8 +465,7 @@ class SBusFPGABus(Module):
NextValue(sbus_oe_master_in, 1),
NextValue(sbus_last_pa, SBUS_3V3_PA_i),
If(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)|
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@@ -500,8 +502,7 @@ class SBusFPGABus(Module):
#NextValue(led0123, led0123 | LED_PARITY),
NextState("Slave_Error")
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)|
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), # need to wait for data, don't ACK yet
NextValue(SBUS_3V3_ERRs_o, 1),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
@@ -548,7 +549,8 @@ class SBusFPGABus(Module):
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == USBOHCI_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ENGINE_ADDR_PFXA) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ENGINE_ADDR_PFXB)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_WORD),
@@ -574,8 +576,7 @@ class SBusFPGABus(Module):
(SBUS_3V3_PPRD_i == 0)),
NextValue(sbus_oe_master_in, 1),
NextValue(sbus_last_pa, SBUS_3V3_PA_i),
If(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
If(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_BYTE),
@@ -606,8 +607,7 @@ class SBusFPGABus(Module):
NextValue(SBUS_3V3_ERRs_o, 1),
#NextValue(led0123, led0123 | LED_PARITY),
NextState("Slave_Error")
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX) |
(SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SDRAM_ADDR_PFX)),
).Elif(((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
NextValue(sbus_wishbone_le, (SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == SRAM_ADDR_PFX)),
If(~self.wishbone_master.cyc,
NextValue(SBUS_3V3_ACKs_o, ACK_HWORD),

View File

@@ -22,6 +22,9 @@ from sbus_to_fpga_trng import *
from litedram.frontend.dma import *
from engine import Engine;
from migen.genlib.resetsync import AsyncResetSynchronizer;
import sbus_to_fpga_export;
# CRG ----------------------------------------------------------------------------------------------
@@ -37,10 +40,24 @@ class _CRG(Module):
self.clock_domains.cd_sbus = ClockDomain() # 16.67-25 MHz SBus, reset'ed by SBus, native SBus clock domain
# self.clock_domains.cd_por = ClockDomain() # 48 MHz native, reset'ed by SBus, power-on-reset timer
self.clock_domains.cd_usb = ClockDomain() # 48 MHZ PLL, reset'ed by SBus (via pll), for USB controller
self.clock_domains.cd_clk50 = ClockDomain() # 50 MHz for curve25519engine -> eng_clk
self.clock_domains.cd_clk100 = ClockDomain() # 100 MHz for curve25519engine -> mul_clk
self.clock_domains.cd_clk200 = ClockDomain() # 200 MHz for curve25519engine -> rf_clk
# # #
clk48 = platform.request("clk48")
self.cd_native.clk = clk48
###### explanations from betrusted-io/betrusted-soc/betrusted_soc.py
# Note: below feature cannot be used because Litex appends this *after* platform commands! This causes the generated
# clock derived constraints immediately below to fail, because .xdc file is parsed in-order, and the main clock needs
# to be created before the derived clocks. Instead, we use the line afterwards.
platform.add_platform_command("create_clock -name clk48 -period 20.8333 [get_nets clk48]")
# The above constraint must strictly proceed the below create_generated_clock constraints in the .XDC file
# This allows PLLs/MMCMEs to be placed anywhere and reference the input clock
self.clk48_bufg = Signal()
self.specials += Instance("BUFG", i_I=clk48, o_O=self.clk48_bufg)
self.comb += self.cd_native.clk.eq(self.clk48_bufg)
#self.cd_native.clk = clk48
clk_sbus = platform.request("SBUS_3V3_CLK")
self.cd_sbus.clk = clk_sbus
rst_sbus = platform.request("SBUS_3V3_RSTs")
@@ -49,16 +66,39 @@ class _CRG(Module):
##self.comb += self.cd_sys.rst.eq(~rst_sbus)
self.submodules.pll = pll = S7MMCM(speedgrade=-1)
pll.register_clkin(clk48, 48e6)
#pll.register_clkin(clk48, 48e6)
pll.register_clkin(self.clk48_bufg, 48e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
platform.add_platform_command("create_generated_clock -name sysclk [get_pins {{MMCME2_ADV/CLKOUT0}}]")
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
platform.add_platform_command("create_generated_clock -name sys4xclk [get_pins {{MMCME2_ADV/CLKOUT1}}]")
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
platform.add_platform_command("create_generated_clock -name sys4x90clk [get_pins {{MMCME2_ADV/CLKOUT2}}]")
self.comb += pll.reset.eq(~rst_sbus) # | ~por_done
platform.add_false_path_constraints(self.cd_native.clk, self.cd_sbus.clk)
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_sbus.clk)
platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_native.clk)
platform.add_false_path_constraints(self.cd_sbus.clk, self.cd_sys.clk)
##platform.add_false_path_constraints(self.cd_native.clk, self.cd_sys.clk)
self.submodules.curve25519_pll = curve25519_pll = S7MMCM(speedgrade=-1)
curve25519_clk_freq = 80e6
#curve25519_pll.register_clkin(clk48, 48e6)
curve25519_pll.register_clkin(self.clk48_bufg, 48e6)
curve25519_pll.create_clkout(self.cd_clk50, curve25519_clk_freq/2, margin=0)
platform.add_platform_command("create_generated_clock -name clk50 [get_pins {{MMCME2_ADV_1/CLKOUT0}}]")
curve25519_pll.create_clkout(self.cd_clk100, curve25519_clk_freq, margin=0)
platform.add_platform_command("create_generated_clock -name clk100 [get_pins {{MMCME2_ADV_1/CLKOUT1}}]")
curve25519_pll.create_clkout(self.cd_clk200, curve25519_clk_freq*2, margin=0)
platform.add_platform_command("create_generated_clock -name clk200 [get_pins {{MMCME2_ADV_1/CLKOUT2}}]")
#self.comb += curve25519_pll.reset.eq(~rst_sbus) # | ~por_done
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_clk50.clk)
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_clk100.clk)
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_clk200.clk)
platform.add_false_path_constraints(self.cd_clk50.clk, self.cd_sys.clk)
platform.add_false_path_constraints(self.cd_clk100.clk, self.cd_sys.clk)
platform.add_false_path_constraints(self.cd_clk200.clk, self.cd_sys.clk)
# Power on reset, reset propagate from SBus to SYS
# por_count = Signal(16, reset=2**16-1)
@@ -71,15 +111,19 @@ class _CRG(Module):
# USB
self.submodules.usb_pll = usb_pll = S7MMCM(speedgrade=-1)
usb_pll.register_clkin(clk48, 48e6)
#usb_pll.register_clkin(clk48, 48e6)
usb_pll.register_clkin(self.clk48_bufg, 48e6)
usb_pll.create_clkout(self.cd_usb, 48e6, margin = 0)
platform.add_platform_command("create_generated_clock -name usbclk [get_pins {{MMCME2_ADV_2/CLKOUT0}}]")
self.comb += usb_pll.reset.eq(~rst_sbus) # | ~por_done
platform.add_false_path_constraints(self.cd_sys.clk, self.cd_usb.clk)
self.submodules.pll_idelay = pll_idelay = S7PLL(speedgrade=-1)
pll_idelay.register_clkin(clk48, 48e6)
self.submodules.pll_idelay = pll_idelay = S7MMCM(speedgrade=-1)
#pll_idelay.register_clkin(clk48, 48e6)
pll_idelay.register_clkin(self.clk48_bufg, 48e6)
pll_idelay.create_clkout(self.cd_idelay, 200e6, margin = 0)
self.comb += pll_idelay.reset.eq(~rst_sbus) # | ~por_done
platform.add_platform_command("create_generated_clock -name idelayclk [get_pins {{MMCME2_ADV_3/CLKOUT0}}]")
self.comb += pll_idelay.reset.eq(~rst_sbus) # | ~por_done
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
@@ -112,12 +156,13 @@ class SBusFPGA(SoCCore):
# The position of the 'usb_fake_dma' is so it overlaps
# the virtual address space used by NetBSD DMA allocators
self.wb_mem_map = wb_mem_map = {
"prom": 0x00000000,
"csr" : 0x00040000,
"usb_host": 0x00080000,
"usb_shared_mem": 0x00090000,
"main_ram": 0x80000000,
"usb_fake_dma": 0xfc000000,
"prom": 0x00000000,
"csr" : 0x00040000,
"usb_host": 0x00080000,
"usb_shared_mem": 0x00090000,
"curve25519engine": 0x000a0000,
"main_ram": 0x80000000,
"usb_fake_dma": 0xfc000000,
}
self.mem_map.update(wb_mem_map)
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq)
@@ -229,6 +274,14 @@ class SBusFPGA(SoCCore):
self.submodules.trng = NeoRV32TrngWrapper(platform=platform)
# beware the naming, as 'clk50' 'sysclk' 'clk200' are used in the original platform constraints
# the local engine.py was slightly modified to have configurable names, so we can have 'clk50', 'clk100', 'clk200'
# Beware that Engine implicitely runs in 'sys' by default, need to rename that one as well
self.submodules.curve25519engine = ClockDomainsRenamer({"eng_clk":"clk50", "rf_clk":"clk200", "mul_clk":"clk100", "sys":"clk100"})(Engine(platform=platform,prefix=self.mem_map.get("curve25519engine", None)))
self.submodules.curve25519engine_wishbone_cdc = wishbone.WishboneDomainCrossingMaster(platform=self.platform, slave=self.curve25519engine.bus, cd_master="sys", cd_slave="clk100")
self.bus.add_slave("curve25519engine", self.curve25519engine_wishbone_cdc, SoCRegion(origin=self.mem_map.get("curve25519engine", None), size=0x20000, cached=False))
#self.bus.add_slave("curve25519engine", self.curve25519engine.bus, SoCRegion(origin=self.mem_map.get("curve25519engine", None), size=0x20000, cached=False))
def main():
parser = argparse.ArgumentParser(description="SbusFPGA")
parser.add_argument("--build", action="store_true", help="Build bitstream")

View File

@@ -158,4 +158,4 @@ class Platform(XilinxPlatform):
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk48", loose=True), 1e9/48e6)
#self.add_period_constraint(self.lookup_request("clk48", loose=True), 1e9/48e6)