Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144424803
D45590.id139839.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D45590.id139839.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D45590: caam: Add caam_test support in caam driver
Attached
Detach File
Event Timeline
Log In to Comment