Page MenuHomeFreeBSD

D45590.id139839.diff
No OneTemporary

D45590.id139839.diff

diff --git a/sys/arm64/qoriq/caam/caam.c b/sys/arm64/qoriq/caam/caam.c
--- a/sys/arm64/qoriq/caam/caam.c
+++ b/sys/arm64/qoriq/caam/caam.c
@@ -12,6 +12,8 @@
__FBSDID("$FreeBSD$");
+#include "opt_caam.h" /* For the CAAM_DEBUG option */
+
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/endian.h>
@@ -31,6 +33,7 @@
#include "caam.h"
#include "caam_debug.h"
#include "caam_internal.h"
+#include "caam_test.h"
#include "jr/caam_jobdesc.h"
#include "jr/caam_jr.h"
#include "jr/caam_jr_hw.h"
@@ -439,8 +442,21 @@
goto cleanup_rman;
}
+#ifdef CAAM_DEBUG
+ /* Add the caam test device for development */
+ rv = caam_test_attach(dev);
+ if (rv != 0) {
+ CAAM_LOG_ERROR("caam_test_attach failed rv=(%d)\n", rv);
+ goto cleanup_jobrings;
+ }
+#endif
+
return (0);
+#ifdef CAAM_DEBUG
+cleanup_jobrings:
+ caam_jobrings_detach(dev);
+#endif
cleanup_rman:
rman_fini(&sc->mem_rman);
cleanup_resource:
@@ -505,6 +521,11 @@
{
struct caam_softc *sc = device_get_softc(dev);
+#ifdef CAAM_DEBUG
+ /* Remove the caam test device */
+ caam_test_detach(dev);
+#endif
+
caam_jobrings_detach(dev);
rman_fini(&sc->mem_rman);
diff --git a/sys/arm64/qoriq/caam/caam_test.h b/sys/arm64/qoriq/caam/caam_test.h
new file mode 100644
--- /dev/null
+++ b/sys/arm64/qoriq/caam/caam_test.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2024 Alstom Group
+ * Copyright 2024 Sii Poland
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef CAAM_TEST_H
+#define CAAM_TEST_H
+
+#include <sys/types.h>
+
+/* These functions are used to setup and free the test drivers*/
+int caam_test_attach(device_t dev);
+int caam_test_detach(device_t dev);
+
+#endif /* CAAM_TEST_H */
\ No newline at end of file
diff --git a/sys/arm64/qoriq/caam/caam_test.c b/sys/arm64/qoriq/caam/caam_test.c
new file mode 100644
--- /dev/null
+++ b/sys/arm64/qoriq/caam/caam_test.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright 2024 Alstom Group
+ * Copyright 2024 Sii Poland
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/conf.h> /* cdevsw struct */
+#include <sys/ctype.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/random.h>
+#include <sys/uio.h> /* uio struct */
+
+#include <machine/bus.h>
+
+#include <dev/random/randomdev.h>
+
+#include "caam.h"
+#include "caam_debug.h"
+#include "caam_internal.h"
+#include "caam_test.h"
+#include "jr/caam_jobdesc.h"
+#include "jr/caam_jr_hw.h"
+
+/* Reference to the CAAM device on witch to execute the tests. */
+static device_t g_caam_dev;
+
+/* Utility static functions */
+/* `borrowed` from sys/cam/ctl/ctl.c */
+static int
+hex2bin(const char *str, uint8_t *buf, int buf_size)
+{
+ int i;
+ u_char c;
+
+ memset(buf, 0, buf_size);
+ while (isspace(str[0]))
+ str++;
+ if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
+ str += 2;
+ buf_size *= 2;
+ for (i = 0; str[i] != 0 && i < buf_size; i++) {
+ while (str[i] == '-') /* Skip dashes in UUIDs. */
+ str++;
+ c = str[i];
+ if (isdigit(c))
+ c -= '0';
+ else if (isalpha(c))
+ c -= isupper(c) ? 'A' - 10 : 'a' - 10;
+ else
+ break;
+ if (c >= 16)
+ break;
+ if ((i & 1) == 0)
+ buf[i / 2] |= (c << 4);
+ else
+ buf[i / 2] |= c;
+ }
+ return ((i + 1) / 2);
+}
+
+static void
+print_hex(const char *message, const uint8_t *buf, int buf_size)
+{
+ char tmp_buff[buf_size * 2 + 1];
+
+ for (int i = 0; i < buf_size; i++) {
+ tmp_buff[2 * i] = hex2ascii(buf[i] >> 4u);
+ tmp_buff[2 * i + 1] = hex2ascii(buf[i] & 0xFu);
+ }
+ tmp_buff[buf_size * 2] = '\0';
+
+ uprintf("caam_test: %s `%s`\n", message, tmp_buff);
+}
+
+/*------------------ Functions to execute any descriptor ------------------*/
+/* Construct descriptor from provided template */
+static int
+cnstr_test_jobdesc(uint32_t *desc, char *template,
+ const caam_jr_dma_map_t *data_map)
+{
+ bus_addr_t phys_addr;
+ char *buffer, *command, *endptr;
+ uint32_t command_word;
+
+ /* Current descriptor support only 64K length */
+ if (data_map->buflen > 0xffffu)
+ return EINVAL;
+
+ CAAM_LOG_INFO("Constructing descriptor '%s'\n", template);
+ caam_jobdesc_init(desc);
+
+ buffer = template;
+ while ((command = strsep(&buffer, ";")) != NULL) {
+ if (strlen(command) != 8) {
+ CAAM_LOG_ERROR("Received bad command! '%s'\n", command);
+ return (EINVAL);
+ }
+ CAAM_LOG_INFO("Interpreting command `%s`\n", command);
+
+ command_word = (uint32_t)strtoul(command, &endptr, 16);
+ if ((command_word & 0xFFFF0000) == 0xA5A50000u) {
+ CAAM_LOG_INFO("Received adress with offset %i\n",
+ command_word & 0xFFFF);
+ phys_addr = data_map->bus_addr +
+ (command_word & 0xFFFF);
+
+ CAAM_LOG_INFO("Adding address: '%lX'\n", phys_addr);
+ caam_jobdesc_add_ptr(desc, phys_addr);
+ } else {
+ CAAM_LOG_INFO("Adding word: '%08X'\n", command_word);
+ caam_jobdesc_add_word(desc, command_word);
+ }
+ }
+
+ return 0;
+}
+
+/* Execute test job descriptor
+ * Parameters:
+ * uint8_t* data_buff - user specified byte array
+ * uint32_t data_buff_len - number of bytes of data_buff
+ * Return code:
+ * 0 - SUCCESS
+ * !0 - ERROR
+ */
+static int
+run_test_generate_job(device_t dev, char *template, uint8_t *data_buff,
+ uint32_t data_buff_len)
+{
+ int ret = 0;
+ struct job_descriptor desc;
+ struct job_descriptor *jobdesc = &desc;
+ caam_jr_dma_map_t data_map;
+ struct caam_softc *sc;
+ device_t jr_dev;
+
+ sc = device_get_softc(dev);
+ jobdesc->arg = NULL;
+ jobdesc->callback = NULL;
+
+ jr_dev = jr_pool_acquire(&sc->jr_pool);
+ if (jr_dev == 0) {
+ CAAM_LOG_ERROR("Failed to acquire JR device\n");
+ return EIO;
+ }
+
+ /* Map the buffer to the DMA memory */
+ ret = caam_jr_dma_map(jr_dev, &data_map, data_buff, data_buff_len, 0,
+ BUS_DMA_NOWAIT, JR_MAP_SYNC);
+ if (ret != 0) {
+ CAAM_LOG_ERROR("DMA mapping failed\n");
+ jr_pool_release(&sc->jr_pool, jr_dev);
+ return ret;
+ }
+
+ /* create the hw_rng descriptor */
+ ret = cnstr_test_jobdesc(jobdesc->desc, template, &data_map);
+ if (ret != 0) {
+ CAAM_LOG_ERROR("Descriptor construction failed\n");
+ goto caam_unmap;
+ }
+
+ print_hex("Descriptor:", (void *)jobdesc->desc,
+ caam_jobdesc_length(jobdesc->desc) * sizeof(uint32_t));
+
+ /* Finally, execute the descriptor */
+ ret = caam_run_descriptor_jr_blocking(dev, jobdesc, jr_dev);
+ if (ret != 0) {
+ CAAM_LOG_ERROR("Error in running descriptor\n");
+ goto caam_unmap;
+ }
+
+caam_unmap:
+ jr_pool_release(&sc->jr_pool, jr_dev);
+ caam_jr_dma_unmap(jr_dev, &data_map, JR_MAP_SYNC);
+
+ return ret;
+}
+
+/*------ CAAM test character device (caam_test_cdev) interface functions -----*/
+#define BUFFERSIZE 1024
+
+/* Static buffers used to store descriptors and input data */
+static uint8_t test_in_buf[BUFFERSIZE];
+
+/* Function prototypes */
+static d_open_t caam_test_cdev_open;
+static d_close_t caam_test_cdev_close;
+static d_write_t caam_test_cdev_write;
+
+/* Character device entry points */
+static struct cdevsw caam_test_cdevsw = {
+ .d_version = D_VERSION,
+ .d_open = caam_test_cdev_open,
+ .d_close = caam_test_cdev_close,
+ .d_write = caam_test_cdev_write,
+ .d_name = "caam_test_cdev",
+};
+
+/* vars */
+static struct cdev *caam_test_cdev;
+
+static int
+caam_test_cdev_open(struct cdev *dev __unused, int oflags __unused,
+ int devtype __unused, struct thread *td __unused)
+{
+ device_t caam_dev = g_caam_dev;
+
+ if (caam_dev == NULL) {
+ CAAM_LOG_ERROR("No CAAM module available!\n");
+ return (ENXIO);
+ }
+
+ CAAM_LOG_DEBUG("Opened CAAM TEST character device successfully.\n");
+ return (0);
+}
+
+static int
+caam_test_cdev_close(struct cdev *dev __unused, int fflag __unused,
+ int devtype __unused, struct thread *td __unused)
+{
+ CAAM_LOG_DEBUG("Closing CAAM TEST character device.\n");
+ return (0);
+}
+
+/*
+ * The read function reads from random device and set it to userland for
+ * accessing.
+ */
+static int
+caam_test_cdev_write(struct cdev *dev __unused, struct uio *uio,
+ int ioflag __unused)
+{
+ size_t amt;
+ int error;
+ uint8_t command_buffer[BUFFERSIZE];
+ char *buffer, *command, *param, *value, *endptr;
+
+ /*
+ * We allow write only at begining - atomic command
+ */
+ if (uio->uio_offset != 0)
+ return (EINVAL);
+
+ /* Copy the string in from user memory to kernel memory */
+ amt = MIN(uio->uio_resid, sizeof(command_buffer));
+ error = uiomove(command_buffer, amt, uio);
+
+ /* Now we need to null terminate the command string */
+ command_buffer[uio->uio_offset] = 0;
+ uprintf("caam_test: Execute: `%s`\n", command_buffer);
+
+ buffer = command_buffer;
+
+ command = strsep(&buffer, ":");
+ uprintf("caam_test: Command: `%s`\n", command);
+
+ if (strcmp(command, "LOAD") == 0) {
+ int offset = 0, length = 0;
+
+ param = strsep(&buffer, ":");
+ offset = (uint32_t)strtoul(param, &endptr, 16);
+ uprintf("caam_test: Param Offset: `%s` -> %i\n", param, offset);
+
+ value = buffer;
+ length = strlen(value) / 2;
+
+ uprintf("caam_test: Value: `%s`, len:%i\n", value, length);
+ hex2bin(value, &test_in_buf[offset], length);
+ } else if (strcmp(command, "READ") == 0) {
+ int offset, length;
+
+ param = strsep(&buffer, ":");
+ offset = (uint32_t)strtoul(param, &endptr, 16);
+ uprintf("caam_test: Param Offset: `%s` -> %i\n", param, offset);
+
+ param = buffer;
+ length = (uint32_t)strtoul(param, &endptr, 16);
+ uprintf("caam_test: Param Length: `%s` -> %i\n", param, length);
+
+ print_hex("Data:", &test_in_buf[offset], length);
+ } else if (strcmp(command, "EXEC") == 0) {
+ param = buffer;
+ uprintf("caam_test: Param Templates: `%s`\n", param);
+
+ run_test_generate_job(g_caam_dev, param, test_in_buf,
+ sizeof(test_in_buf));
+ } else {
+ uprintf("caam_test: Unknown command `%s`\n", command);
+ }
+
+ if (error != 0)
+ uprintf("Write failed: bad address!\n");
+ return (error);
+}
+
+/*--------------------- CAAM device management functions --------------------*/
+int
+caam_test_attach(device_t dev)
+{
+ int error = 0;
+ struct make_dev_args args;
+
+ /* Add the character device only on the first CAAM device.*/
+ if (g_caam_dev == NULL) {
+ g_caam_dev = dev;
+
+ /* Register the device as read/write */
+ make_dev_args_init(&args);
+ args.mda_flags = MAKEDEV_CHECKNAME | MAKEDEV_WAITOK;
+ args.mda_devsw = &caam_test_cdevsw;
+ args.mda_cr = 0;
+ args.mda_uid = UID_ROOT;
+ args.mda_gid = GID_WHEEL;
+ args.mda_mode = 0600;
+
+ error = make_dev_s(&args, &caam_test_cdev, "test_caam");
+
+ CAAM_LOG_INFO(
+ "CAAM TEST /dev/test_caam character device loaded.\n");
+ }
+
+ return error;
+}
+
+int
+caam_test_detach(device_t dev)
+{
+ /* Remove character device only if correct CAAM
+ * device is detached */
+ if (dev == g_caam_dev) {
+ CAAM_LOG_INFO(
+ "CAAM TEST /dev/test_caam character device removed.\n");
+ destroy_dev(caam_test_cdev);
+
+ /* at this time no clients should exist that can use the
+ * g_caam_dev */
+ g_caam_dev = NULL;
+ }
+
+ return 0;
+}
diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64
--- a/sys/conf/files.arm64
+++ b/sys/conf/files.arm64
@@ -687,6 +687,7 @@
arm64/qoriq/clk/qoriq_clk_pll.c optional clk soc_nxp_ls
arm64/qoriq/clk/qoriq_clkgen.c optional clk soc_nxp_ls fdt
arm64/qoriq/caam/caam.c optional caam soc_nxp_ls
+arm64/qoriq/caam/caam_test.c optional caam caam_debug soc_nxp_ls
arm64/qoriq/caam/jr/caam_jr.c optional caam soc_nxp_ls
arm64/qoriq/caam/jr/caam_jr_pool.c optional caam soc_nxp_ls
arm64/qoriq/caam/jr/caam_jobdesc.c optional caam soc_nxp_ls
diff --git a/sys/conf/options b/sys/conf/options
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -1009,6 +1009,9 @@
GCOV opt_global.h
LINDEBUGFS
+# caam options
+CAAM_DEBUG opt_caam.h
+
# options for HID support
HID_DEBUG opt_hid.h
IICHID_DEBUG opt_hid.h

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 9:16 AM (19 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28562169
Default Alt Text
D45590.id139839.diff (11 KB)

Event Timeline