aboutsummaryrefslogtreecommitdiff
path: root/smc_fuzz
diff options
context:
space:
mode:
authorMark Dykes <mark.dykes@arm.com>2020-06-03 15:46:55 -0500
committerManish Pandey <manish.pandey2@arm.com>2020-10-19 11:22:34 +0000
commite7810b57c8e671f3b10f7dc901ac3712109564e9 (patch)
tree971eaeeae533ac6d4605bb26948c1d641e8a7a06 /smc_fuzz
parent12c20464817a98348b06069c75a3cfe4dbc6f85d (diff)
downloadtf-a-tests-e7810b57c8e671f3b10f7dc901ac3712109564e9.tar.gz
SMC fuzzing module integration.
This includes one test with one seed as the initial implementation. A future upgrade will include an enhanced seeding strategy. The patch includes an example device tree file with the actual test (sdei.dts) leveraging the SDEI functions that can be called without reference to system state. Platform CI will have a single TFTF config to be used in all future testing. Once both branches of TFA tests and platform CI are checked in a user can invoke the testing with: workspace=<workspace location> test_groups=fvp-aarch64-sdei,fvp-smcfuzzing:fvp-tftf-fip.tftf-aemv8a test_run=1 bin_mode=debug retain_paths=1 ./platform-ci/script/run_local_ci.sh Signed-off-by: Mark Dykes <mark.dykes@arm.com> Change-Id: Ic290e7255bcfd845c0d22037e0b670a6691541df
Diffstat (limited to 'smc_fuzz')
-rw-r--r--smc_fuzz/dts/sample_dts_randsmc.dts122
-rw-r--r--smc_fuzz/dts/sdei.dts46
-rw-r--r--smc_fuzz/include/fifo3d.h42
-rw-r--r--smc_fuzz/include/smcmalloc.h64
-rw-r--r--smc_fuzz/src/fifo3d.c202
-rw-r--r--smc_fuzz/src/randsmcmod.c570
-rw-r--r--smc_fuzz/src/smcmalloc.c559
7 files changed, 1605 insertions, 0 deletions
diff --git a/smc_fuzz/dts/sample_dts_randsmc.dts b/smc_fuzz/dts/sample_dts_randsmc.dts
new file mode 100644
index 000000000..458802c00
--- /dev/null
+++ b/smc_fuzz/dts/sample_dts_randsmc.dts
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+/dts-v1/;
+
+/ {
+
+ svc_var1 {
+ bias = <65>;
+ svc_var1_var1 {
+ bias = <30>;
+ functionname = "svc_var1_var1";
+ };
+ smc_var1_var2 {
+ bias = <30>;
+ functionname = "smc_var1_var2";
+ };
+ smc_var1_var3 {
+ bias = <35>;
+ smc_var1_var3_var1 {
+ bias = <30>;
+ functionname = "smc_var1_var3_var1";
+ };
+ smc_var1_var3_var2 {
+ bias = <30>;
+ functionname = "smc_var1_var3_var2";
+ };
+ smc_var1_var3_var3 {
+ bias = <40>;
+ functionname = "smc_var1_var3_var3";
+ };
+ smc_var1_var3_var4 {
+ bias = <55>;
+ smc_var1_var3_var4_var1 {
+ bias = <89>;
+ functionname = "smc_var1_var3_var4_var1";
+ };
+ smc_var1_var3_var4_var2 {
+ bias = <95>;
+ functionname = "smc_var1_var3_var4_var2";
+ };
+ smc_var1_var3_var4_var3 {
+ bias = <35>;
+ smc_var1_var3_var4_var3_var1 {
+ bias = <30>;
+ functionname = "smc_var1_var3_var4_var3_var1";
+ };
+ smc_var1_var3_var4_var3_var2 {
+ bias = <30>;
+ functionname = "smc_var1_var3_var4_var3_var2";
+ };
+ smc_var1_var3_var4_var3_var3 {
+ bias = <40>;
+ functionname = "smc_var1_var3_var4_var3_var3";
+ };
+ smc_var1_var3_var4_var3_var4 {
+ bias = <55>;
+ smc_var1_var3_var4_var3_var4_var1 {
+ bias = <89>;
+ functionname = "smc_var1_var3_var4_var3_var4_var1";
+ };
+ smc_var1_var3_var4_var3_var4_var2 {
+ bias = <95>;
+ functionname = "smc_var1_var3_var4_var3_var4_var2";
+ };
+ };
+ };
+ };
+ };
+ smc_var1_var4 {
+ bias = <35>;
+ smc_var1_var4_var1 {
+ bias = <30>;
+ functionname = "smc_var1_var4_var1";
+ };
+ smc_var1_var4_var2 {
+ bias = <30>;
+ functionname = "smc_var1_var4_var2";
+ };
+ smc_var1_var4_var3 {
+ bias = <40>;
+ functionname = "smc_var1_var4_var3";
+ };
+ };
+ };
+
+ smc_var2 {
+ bias = <35>;
+ smc_var2_var1 {
+ bias = <30>;
+ functionname = "smc_var2_var1";
+ };
+ smc_var2_var2 {
+ bias = <30>;
+ functionname = "smc_var2_var2";
+ };
+ smc_var2_var3 {
+ bias = <40>;
+ functionname = "smc_var2_var3";
+ };
+ };
+
+ smc_var3 {
+ bias = <55>;
+ smc_var3_var1 {
+ bias = <30>;
+ functionname = "smc_var3_var1";
+ };
+ smc_var3_var2 {
+ bias = <30>;
+ functionname = "smc_var3_var2";
+ };
+ smc_var3_var3 {
+ bias = <40>;
+ functionname = "smc_var3_var3";
+ };
+ };
+};
diff --git a/smc_fuzz/dts/sdei.dts b/smc_fuzz/dts/sdei.dts
new file mode 100644
index 000000000..2418916ad
--- /dev/null
+++ b/smc_fuzz/dts/sdei.dts
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+
+
+/dts-v1/;
+
+/ {
+
+ sdei {
+ bias = <30>;
+ sdei_version {
+ bias = <30>;
+ functionname = "sdei_version";
+ };
+ sdei_pe_unmask {
+ bias = <30>;
+ functionname = "sdei_pe_unmask";
+ };
+ sdei_pe_mask {
+ bias = <30>;
+ functionname = "sdei_pe_mask";
+ };
+ sdei_event_status {
+ bias = <30>;
+ functionname = "sdei_event_status";
+ };
+ sdei_event_signal {
+ bias = <30>;
+ functionname = "sdei_event_signal";
+ };
+ sdei_private_reset {
+ bias = <30>;
+ functionname = "sdei_private_reset";
+ };
+ sdei_shared_reset {
+ bias = <30>;
+ functionname = "sdei_shared_reset";
+ };
+ };
+
+};
diff --git a/smc_fuzz/include/fifo3d.h b/smc_fuzz/include/fifo3d.h
new file mode 100644
index 000000000..c04567ce1
--- /dev/null
+++ b/smc_fuzz/include/fifo3d.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+
+#ifndef FIFO3D_H
+#define FIFO3D_H
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "smcmalloc.h"
+
+struct fifo3d {
+ char ***nnfifo;
+ char ***fnamefifo;
+ int **biasfifo;
+ int col;
+ int curr_col;
+ int *row;
+};
+
+/*
+ * Push function name string into raw data structure
+ */
+void push_3dfifo_fname(struct fifo3d *f3d, char *fname);
+
+/*
+ * Push bias value into raw data structure
+ */
+void push_3dfifo_bias(struct fifo3d *f3d, int bias);
+
+/*
+ * Create new column and/or row for raw data structure for newly
+ * found node from device tree
+ */
+void push_3dfifo_col(struct fifo3d *f3d, char *entry, struct memmod *mmod);
+
+#endif /* FIFO3D_H */
diff --git a/smc_fuzz/include/smcmalloc.h b/smc_fuzz/include/smcmalloc.h
new file mode 100644
index 000000000..129e07c6e
--- /dev/null
+++ b/smc_fuzz/include/smcmalloc.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef SMCMALLOC_H
+#define SMCMALLOC_H
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "fifo3d.h"
+
+#define TOTALMEMORYSIZE (0x10000)
+#define BLKSPACEDIV (4)
+#define TOPBITSIZE (20)
+#define MAX_NAME_CHARS 50
+
+struct memblk {
+ unsigned int address;
+ unsigned int size;
+ int valid;
+};
+
+struct memmod {
+ char memory[TOTALMEMORYSIZE];
+ unsigned int nmemblk;
+ unsigned int maxmemblk;
+ unsigned int checkadd;
+ struct memblk *memptr;
+ struct memblk *memptrend;
+ unsigned int mallocdeladd[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ struct memblk *precblock[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ struct memblk *trailblock[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ struct memblk *memblkqueue[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int memallocsize[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int mallocdeladd_valid[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int mallocdeladd_queue[((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int checksa[4*((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int checkea[4*((TOTALMEMORYSIZE/BLKSPACEDIV)/sizeof(struct memblk))];
+ unsigned int cntdeladd;
+ unsigned int ptrmemblkqueue;
+ unsigned int mallocdeladd_queue_cnt;
+ unsigned int checknumentries;
+ unsigned int memerror;
+};
+
+struct peret {
+ unsigned int tbit;
+ unsigned int pow2;
+};
+
+void initmem(void);
+struct peret priorityencoder(unsigned int);
+void *smcmalloc(unsigned int, struct memmod*);
+int smcfree(void*, struct memmod *);
+#ifdef DEBUG_SMC_MALLOC
+void displayblocks(struct memmod *);
+void displaymalloctable(struct memmod *);
+#endif
+
+#endif /* SMCMALLOC_H */
diff --git a/smc_fuzz/src/fifo3d.c b/smc_fuzz/src/fifo3d.c
new file mode 100644
index 000000000..119b26c7e
--- /dev/null
+++ b/smc_fuzz/src/fifo3d.c
@@ -0,0 +1,202 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <drivers/arm/private_timer.h>
+#include <events.h>
+#include "fifo3d.h"
+#include <libfdt.h>
+
+#include <power_management.h>
+#include <sdei.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+#include <plat_topology.h>
+#include <platform.h>
+
+#ifdef SMC_FUZZ_TMALLOC
+#define GENMALLOC(x) malloc((x))
+#define GENFREE(x) free((x))
+#else
+#define GENMALLOC(x) smcmalloc((x), mmod)
+#define GENFREE(x) smcfree((x), mmod)
+#endif
+
+/*
+ * Push function name string into raw data structure
+ */
+void push_3dfifo_fname(struct fifo3d *f3d, char *fname)
+{
+ strlcpy(f3d->fnamefifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1],
+ fname, MAX_NAME_CHARS);
+}
+
+/*
+ * Push bias value into raw data structure
+ */
+void push_3dfifo_bias(struct fifo3d *f3d, int bias)
+{
+ f3d->biasfifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1] = bias;
+}
+
+/*
+ * Create new column and/or row for raw data structure for newly
+ * found node from device tree
+ */
+void push_3dfifo_col(struct fifo3d *f3d, char *entry, struct memmod *mmod)
+{
+ char ***tnnfifo;
+ char ***tfnamefifo;
+ int **tbiasfifo;
+
+ if (f3d->col == f3d->curr_col) {
+ f3d->col++;
+ f3d->curr_col++;
+ int *trow;
+ trow = GENMALLOC(f3d->col * sizeof(int));
+
+ /*
+ * return if error found
+ */
+ if (mmod->memerror != 0) {
+ return;
+ }
+
+ for (unsigned int i = 0U; (int)i < f3d->col - 1; i++) {
+ trow[i] = f3d->row[i];
+ }
+ if (f3d->col > 1) {
+ GENFREE(f3d->row);
+ }
+ f3d->row = trow;
+ f3d->row[f3d->col - 1] = 1;
+
+ /*
+ * Create new raw data memory
+ */
+ tnnfifo = GENMALLOC(f3d->col * sizeof(char **));
+ tfnamefifo = GENMALLOC(f3d->col * sizeof(char **));
+ tbiasfifo = GENMALLOC((f3d->col) * sizeof(int *));
+ for (unsigned int i = 0U; (int)i < f3d->col; i++) {
+ tnnfifo[i] = GENMALLOC(f3d->row[i] * sizeof(char *));
+ tfnamefifo[i] = GENMALLOC(f3d->row[i] * sizeof(char *));
+ tbiasfifo[i] = GENMALLOC((f3d->row[i]) * sizeof(int));
+ for (unsigned int j = 0U; (int)j < f3d->row[i]; j++) {
+ tnnfifo[i][j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ tfnamefifo[i][j] =
+ GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ if (!((j == f3d->row[f3d->col - 1] - 1) &&
+ (i == (f3d->col - 1)))) {
+ strlcpy(tnnfifo[i][j], f3d->nnfifo[i][j], MAX_NAME_CHARS);
+ strlcpy(tfnamefifo[i][j],
+ f3d->fnamefifo[i][j], MAX_NAME_CHARS);
+ tbiasfifo[i][j] = f3d->biasfifo[i][j];
+ }
+ }
+ }
+
+ /*
+ * Copy data from old raw data to new memory location
+ */
+ strlcpy(tnnfifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1], entry,
+ MAX_NAME_CHARS);
+ strlcpy(tfnamefifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1],
+ "none", MAX_NAME_CHARS);
+ tbiasfifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1] = 0;
+
+ /*
+ * Free the old raw data structres
+ */
+ for (unsigned int i = 0U; (int)i < f3d->col - 1; i++) {
+ for (unsigned int j = 0U; (int)j < f3d->row[i]; j++) {
+ GENFREE(f3d->nnfifo[i][j]);
+ GENFREE(f3d->fnamefifo[i][j]);
+ }
+ GENFREE(f3d->nnfifo[i]);
+ GENFREE(f3d->fnamefifo[i]);
+ GENFREE(f3d->biasfifo[i]);
+ }
+ if (f3d->col > 1) {
+ GENFREE(f3d->nnfifo);
+ GENFREE(f3d->fnamefifo);
+ GENFREE(f3d->biasfifo);
+ }
+
+ /*
+ * Point to new data
+ */
+ f3d->nnfifo = tnnfifo;
+ f3d->fnamefifo = tfnamefifo;
+ f3d->biasfifo = tbiasfifo;
+ }
+ if (f3d->col != f3d->curr_col) {
+ /*
+ * Adding new node to raw data
+ */
+ f3d->col++;
+ f3d->row[f3d->col - 1]++;
+
+ /*
+ * Create new raw data memory
+ */
+ tnnfifo = GENMALLOC(f3d->col * sizeof(char **));
+ tfnamefifo = GENMALLOC(f3d->col * sizeof(char **));
+ tbiasfifo = GENMALLOC((f3d->col) * sizeof(int *));
+ for (unsigned int i = 0U; (int)i < f3d->col; i++) {
+ tnnfifo[i] = GENMALLOC(f3d->row[i] * sizeof(char *));
+ tfnamefifo[i] = GENMALLOC(f3d->row[i] * sizeof(char *));
+ tbiasfifo[i] = GENMALLOC((f3d->row[i]) * sizeof(int));
+ for (unsigned int j = 0U; (int)j < f3d->row[i]; j++) {
+ tnnfifo[i][j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ tfnamefifo[i][j] =
+ GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ if (!((j == f3d->row[f3d->col - 1] - 1) &&
+ (i == (f3d->col - 1)))) {
+ strlcpy(tnnfifo[i][j], f3d->nnfifo[i][j], MAX_NAME_CHARS);
+ strlcpy(tfnamefifo[i][j],
+ f3d->fnamefifo[i][j], MAX_NAME_CHARS);
+ tbiasfifo[i][j] = f3d->biasfifo[i][j];
+ }
+ }
+ }
+
+ /*
+ * Copy data from old raw data to new memory location
+ */
+ strlcpy(tnnfifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1], entry,
+ MAX_NAME_CHARS);
+ strlcpy(tfnamefifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1],
+ "none", MAX_NAME_CHARS);
+ tbiasfifo[f3d->col - 1][f3d->row[f3d->col - 1] - 1] = 0;
+
+ /*
+ * Free the old raw data structres
+ */
+ for (unsigned int i = 0U; (int)i < f3d->col; i++) {
+ for (unsigned int j = 0U; (int)j < f3d->row[i]; j++) {
+ if (!((i == f3d->col - 1) &&
+ (j == f3d->row[i] - 1))) {
+ GENFREE(f3d->nnfifo[i][j]);
+ GENFREE(f3d->fnamefifo[i][j]);
+ }
+ }
+ GENFREE(f3d->nnfifo[i]);
+ GENFREE(f3d->fnamefifo[i]);
+ GENFREE(f3d->biasfifo[i]);
+ }
+ GENFREE(f3d->nnfifo);
+ GENFREE(f3d->fnamefifo);
+ GENFREE(f3d->biasfifo);
+
+ /*
+ * Point to new data
+ */
+ f3d->nnfifo = tnnfifo;
+ f3d->fnamefifo = tfnamefifo;
+ f3d->biasfifo = tbiasfifo;
+ }
+}
diff --git a/smc_fuzz/src/randsmcmod.c b/smc_fuzz/src/randsmcmod.c
new file mode 100644
index 000000000..2b8d01729
--- /dev/null
+++ b/smc_fuzz/src/randsmcmod.c
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <debug.h>
+#include <drivers/arm/private_timer.h>
+#include <events.h>
+#include "fifo3d.h"
+#include <libfdt.h>
+
+#include <power_management.h>
+#include <sdei.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+#include <plat_topology.h>
+#include <platform.h>
+
+extern char _binary___dtb_start[];
+
+struct memmod tmod __aligned(65536) __section("smcfuzz");
+
+/*
+ * switch to use either standard C malloc or custom SMC malloc
+ */
+
+#define FIRST_NODE_DEVTREE_OFFSET (8)
+
+#ifdef SMC_FUZZ_TMALLOC
+#define GENMALLOC(x) malloc((x))
+#define GENFREE(x) free((x))
+#else
+#define GENMALLOC(x) smcmalloc((x), mmod)
+#define GENFREE(x) smcfree((x), mmod)
+#endif
+
+/*
+ * Device tree parameter struct
+ */
+
+struct fdt_header_sf {
+ unsigned int magic;
+ unsigned int totalsize;
+ unsigned int off_dt_struct;
+ unsigned int off_dt_strings;
+ unsigned int off_mem_rsvmap;
+ unsigned int version;
+ unsigned int last_comp_version;
+ unsigned int boot_cpuid_phys;
+ unsigned int size_dt_strings;
+ unsigned int size_dt_struct;
+};
+
+/*
+ * Structure to read the fields of the device tree
+ */
+struct propval {
+ unsigned int len;
+ unsigned int nameoff;
+};
+
+/*
+ * Converting from big endian to little endian to read values
+ * of device tree
+ */
+unsigned int lendconv(unsigned int val)
+{
+ unsigned int res;
+
+ res = val << 24;
+ res |= ((val << 8) & 0xFF0000U);
+ res |= ((val >> 8) & 0xFF00U);
+ res |= ((val >> 24) & 0xFFU);
+ return res;
+}
+
+/*
+ * Function to read strings from device tree
+ */
+void pullstringdt(void **dtb,
+ void *dtb_beg,
+ unsigned int offset,
+ char *cset)
+{
+ int fistr;
+ int cntchr;
+ char rval;
+
+ if (offset != 0U) {
+ *dtb = dtb_beg + offset;
+ }
+ fistr = 0;
+
+ cntchr = 0;
+ while (fistr == 0) {
+ rval = *((char *)*dtb);
+ *dtb += sizeof(char);
+ cset[cntchr] = rval;
+ if (cset[cntchr] == 0) {
+ fistr = 1;
+ }
+ cntchr++;
+ }
+
+ if ((cntchr % 4) != 0) {
+ for (unsigned int i = 0U; (int)i < (4 - (cntchr % 4)); i++) {
+ *dtb += sizeof(char);
+ }
+ }
+}
+
+/*
+ * Structure for Node information extracted from device tree
+ */
+struct rand_smc_node {
+ int *biases; // Biases of the individual nodes
+ int *biasarray; // Array of biases across all nodes
+ char **snames; // String that is unique to the SMC call called in test
+ struct rand_smc_node *treenodes; // Selection of nodes that are farther down in the tree
+ // that reference further rand_smc_node objects
+ int *norcall; // Specifies whether a particular node is a leaf node or tree node
+ int entries; // Number of nodes in object
+ int biasent; // Number that gives the total number of entries in biasarray
+ // based on all biases of the nodes
+ char **nname; // Array of node names
+};
+
+
+/*
+ * Create bias tree from given device tree description
+ */
+
+struct rand_smc_node *createsmctree(int *casz,
+ struct memmod *mmod)
+{
+ void *dtb;
+ void *dtb_pn;
+ void *dtb_beg;
+ struct fdt_header fhd;
+ unsigned int rval;
+ struct propval pv;
+ char cset[MAX_NAME_CHARS];
+ char nodename[MAX_NAME_CHARS];
+ int dtdone;
+ struct fifo3d f3d;
+ int leafnode = 0;
+ unsigned int fnode = 0U;
+ unsigned int bias_count = 0U;
+ unsigned int bintnode = 0U;
+ unsigned int treenodetrack = 0U;
+ struct fdt_header *fhdptr;
+ struct rand_smc_node *ndarray = NULL;
+ int cntndarray;
+ struct rand_smc_node nrnode;
+ struct rand_smc_node *tndarray;
+
+ f3d.col = 0;
+ f3d.curr_col = 0;
+
+ /*
+ * Read device tree header and check for valid type
+ */
+
+ fhdptr = (struct fdt_header *)_binary___dtb_start;
+
+ if (fdt_check_header((void *)fhdptr) != 0) {
+ printf("ERROR, not device tree compliant\n");
+ }
+ fhd = *fhdptr;
+ cntndarray = 0;
+ nrnode.entries = 0;
+
+ /*
+ * Create pointers to device tree data
+ */
+ dtb = _binary___dtb_start;
+ dtb_pn = _binary___dtb_start;
+
+ dtb_beg = dtb;
+ fhd = *((struct fdt_header *)dtb);
+ dtb += (fdt32_to_cpu(fhd.off_dt_struct) + FIRST_NODE_DEVTREE_OFFSET);
+ dtdone = 0;
+
+ /*
+ * Reading device tree file
+ */
+ while (dtdone == 0) {
+ rval = *((unsigned int *)dtb);
+ dtb += sizeof(unsigned int);
+
+ /*
+ * Reading node name from device tree and pushing it into the raw data
+ * Table of possible values reading from device tree binary file:
+ * 1 New node found within current tree, possible leaf or tree variant
+ * 2 Node termination of current hiearchy.
+ * Could indicate end of tree or preparation for another branch
+ * 3 Leaf node indication where a bias with a function name should be
+ * found for the current node
+ * 9 End of device tree file and we end the read of the bias tree
+ */
+ if (fdt32_to_cpu(rval) == 1) {
+ pullstringdt(&dtb, dtb_beg, 0U, cset);
+ push_3dfifo_col(&f3d, cset, mmod);
+ strlcpy(nodename, cset, MAX_NAME_CHARS);
+
+ /*
+ * Error checking to make sure that bias is specified
+ */
+ if (fnode == 0U) {
+ fnode = 1U;
+ } else {
+ if (!((fnode == 1U) && (bias_count == 1U))) {
+ printf("ERROR: Did not find bias or multiple bias ");
+ printf("designations before %s %u %u\n",
+ cset, fnode, bias_count);
+ }
+ bias_count = 0U;
+ }
+ }
+
+ /*
+ * Reading node parameters of bias and function name
+ */
+ if (fdt32_to_cpu(rval) == 3) {
+ pv = *((struct propval *)dtb);
+ dtb += sizeof(struct propval);
+ pullstringdt(&dtb_pn, dtb_beg,
+ (fdt32_to_cpu(fhd.off_dt_strings) +
+ fdt32_to_cpu(pv.nameoff)), cset);
+ if (strcmp(cset, "bias") == 0) {
+ rval = *((unsigned int *)dtb);
+ dtb += sizeof(unsigned int);
+ push_3dfifo_bias(&f3d, fdt32_to_cpu(rval));
+ bias_count++;
+ if (bintnode == 1U) {
+ fnode = 0U;
+ bintnode = 0U;
+ bias_count = 0U;
+ }
+ }
+ if (strcmp(cset, "functionname") == 0) {
+ pullstringdt(&dtb, dtb_beg, 0, cset);
+ push_3dfifo_fname(&f3d, cset);
+ leafnode = 1;
+ if (bias_count == 0U) {
+ bintnode = 1U;
+ fnode = 1U;
+ } else {
+ bias_count = 0U;
+ fnode = 0U;
+ }
+ }
+ }
+
+ /*
+ * Node termination and evaluate whether the bias tree requires addition.
+ * The non tree nodes are added.
+ */
+ if (fdt32_to_cpu(rval) == 2) {
+ if ((fnode > 0U) || (bias_count > 0U)) {
+ printf("ERROR: early node termination... ");
+ printf("no bias or functionname field for leaf node, near %s %u\n",
+ nodename, fnode);
+ }
+ f3d.col--;
+ if (leafnode == 1) {
+ leafnode = 0;
+ } else {
+ /*
+ * Create bias tree in memory from raw data
+ */
+ tndarray =
+ GENMALLOC((cntndarray + 1) *
+ sizeof(struct rand_smc_node));
+ unsigned int treenodetrackmal = 0;
+ for (unsigned int j = 0U; (int)j < cntndarray; j++) {
+ tndarray[j].biases = GENMALLOC(ndarray[j].entries * sizeof(int));
+ tndarray[j].snames = GENMALLOC(ndarray[j].entries * sizeof(char *));
+ tndarray[j].norcall = GENMALLOC(ndarray[j].entries * sizeof(int));
+ tndarray[j].nname = GENMALLOC(ndarray[j].entries * sizeof(char *));
+ tndarray[j].treenodes = GENMALLOC(ndarray[j].entries * sizeof(struct rand_smc_node));
+ tndarray[j].entries = ndarray[j].entries;
+ for (unsigned int i = 0U; (int)i < ndarray[j].entries; i++) {
+ tndarray[j].snames[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ strlcpy(tndarray[j].snames[i], ndarray[j].snames[i], MAX_NAME_CHARS);
+ tndarray[j].nname[i] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ strlcpy(tndarray[j].nname[i], ndarray[j].nname[i], MAX_NAME_CHARS);
+ tndarray[j].biases[i] = ndarray[j].biases[i];
+ tndarray[j].norcall[i] = ndarray[j].norcall[i];
+ if (tndarray[j].norcall[i] == 1) {
+ tndarray[j].treenodes[i] = tndarray[treenodetrackmal];
+ treenodetrackmal++;
+ }
+ }
+ tndarray[j].biasent = ndarray[j].biasent;
+ tndarray[j].biasarray = GENMALLOC((tndarray[j].biasent) * sizeof(int));
+ for (unsigned int i = 0U; (int)i < ndarray[j].biasent; i++) {
+ tndarray[j].biasarray[i] = ndarray[j].biasarray[i];
+ }
+ }
+ tndarray[cntndarray].biases = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int));
+ tndarray[cntndarray].snames = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *));
+ tndarray[cntndarray].norcall = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(int));
+ tndarray[cntndarray].nname = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(char *));
+ tndarray[cntndarray].treenodes = GENMALLOC(f3d.row[f3d.col + 1] * sizeof(struct rand_smc_node));
+ tndarray[cntndarray].entries = f3d.row[f3d.col + 1];
+
+ /*
+ * Populate bias tree with former values in tree
+ */
+ int cntbias = 0;
+ int bias_count = 0;
+ for (unsigned int j = 0U; (int)j < f3d.row[f3d.col + 1]; j++) {
+ tndarray[cntndarray].snames[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ strlcpy(tndarray[cntndarray].snames[j], f3d.fnamefifo[f3d.col + 1][j], MAX_NAME_CHARS);
+ tndarray[cntndarray].nname[j] = GENMALLOC(1 * sizeof(char[MAX_NAME_CHARS]));
+ strlcpy(tndarray[cntndarray].nname[j], f3d.nnfifo[f3d.col + 1][j], MAX_NAME_CHARS);
+ tndarray[cntndarray].biases[j] = f3d.biasfifo[f3d.col + 1][j];
+ cntbias += tndarray[cntndarray].biases[j];
+ if (strcmp(tndarray[cntndarray].snames[j], "none") != 0) {
+ strlcpy(tndarray[cntndarray].snames[j], f3d.fnamefifo[f3d.col + 1][j], MAX_NAME_CHARS);
+ tndarray[cntndarray].norcall[j] = 0;
+ tndarray[cntndarray].treenodes[j] = nrnode;
+ } else {
+ tndarray[cntndarray].norcall[j] = 1;
+ tndarray[cntndarray].treenodes[j] = tndarray[treenodetrack];
+ treenodetrack++;
+ }
+ }
+
+ tndarray[cntndarray].biasent = cntbias;
+ tndarray[cntndarray].biasarray = GENMALLOC((tndarray[cntndarray].biasent) * sizeof(int));
+ for (unsigned int j = 0U; j < tndarray[cntndarray].entries; j++) {
+ for (unsigned int i = 0U; i < tndarray[cntndarray].biases[j]; i++) {
+ tndarray[cntndarray].biasarray[bias_count] = j;
+ bias_count++;
+ }
+ }
+
+ /*
+ * Free memory of old bias tree
+ */
+ if (cntndarray > 0) {
+ for (unsigned int j = 0U; (int)j < cntndarray; j++) {
+ for (unsigned int i = 0U;
+ (int)i < ndarray[j].entries;
+ i++) {
+ GENFREE(ndarray[j].snames[i]);
+ GENFREE(ndarray[j].nname[i]);
+ }
+ GENFREE(ndarray[j].biases);
+ GENFREE(ndarray[j].norcall);
+ GENFREE(ndarray[j].biasarray);
+ GENFREE(ndarray[j].snames);
+ GENFREE(ndarray[j].nname);
+ GENFREE(ndarray[j].treenodes);
+ }
+ GENFREE(ndarray);
+ }
+
+ /*
+ * Move pointers to new bias tree to current tree
+ */
+ ndarray = tndarray;
+ cntndarray++;
+
+ /*
+ * Free raw data
+ */
+ for (unsigned int j = 0U; (int)j < f3d.row[f3d.col + 1]; j++) {
+ GENFREE(f3d.nnfifo[f3d.col + 1][j]);
+ GENFREE(f3d.fnamefifo[f3d.col + 1][j]);
+ }
+ GENFREE(f3d.nnfifo[f3d.col + 1]);
+ GENFREE(f3d.fnamefifo[f3d.col + 1]);
+ GENFREE(f3d.biasfifo[f3d.col + 1]);
+ f3d.curr_col -= 1;
+ }
+ }
+
+ /*
+ * Ending device tree file and freeing raw data
+ */
+ if (fdt32_to_cpu(rval) == 9) {
+ for (unsigned int i = 0U; (int)i < f3d.col; i++) {
+ for (unsigned int j = 0U; (int)j < f3d.row[i]; j++) {
+ GENFREE(f3d.nnfifo[i][j]);
+ GENFREE(f3d.fnamefifo[i][j]);
+ }
+ GENFREE(f3d.nnfifo[i]);
+ GENFREE(f3d.fnamefifo[i]);
+ GENFREE(f3d.biasfifo[i]);
+ }
+ GENFREE(f3d.nnfifo);
+ GENFREE(f3d.fnamefifo);
+ GENFREE(f3d.biasfifo);
+ GENFREE(f3d.row);
+ dtdone = 1;
+ }
+ }
+
+
+ *casz = cntndarray;
+ return ndarray;
+}
+
+/*
+ * Running SMC call from what function name is selected
+ */
+void runtestfunction(char *funcstr)
+{
+ if (strcmp(funcstr, "sdei_version") == 0) {
+ long long ret = sdei_version();
+ if (ret != MAKE_SDEI_VERSION(1, 0, 0)) {
+ tftf_testcase_printf("Unexpected SDEI version: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_pe_unmask") == 0) {
+ long long ret = sdei_pe_unmask();
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI pe unmask failed: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_pe_mask") == 0) {
+ int64_t ret = sdei_pe_mask();
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI pe mask failed: 0x%llx\n", ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_event_status") == 0) {
+ int64_t ret = sdei_event_status(0);
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI event status failed: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_event_signal") == 0) {
+ int64_t ret = sdei_event_signal(0);
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI event signal failed: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_private_reset") == 0) {
+ int64_t ret = sdei_private_reset();
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI private reset failed: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+ if (strcmp(funcstr, "sdei_shared_reset") == 0) {
+ int64_t ret = sdei_shared_reset();
+ if (ret < 0) {
+ tftf_testcase_printf("SDEI shared reset failed: 0x%llx\n",
+ ret);
+ }
+ printf("running %s\n", funcstr);
+ }
+}
+
+/*
+ * Top of SMC fuzzing module
+ */
+test_result_t smc_fuzzing_top(void)
+{
+ /*
+ * Setting up malloc block parameters
+ */
+ tmod.memptr = (void *)tmod.memory;
+ tmod.memptrend = (void *)tmod.memory;
+ tmod.maxmemblk = ((TOTALMEMORYSIZE / BLKSPACEDIV) / sizeof(struct memblk));
+ tmod.nmemblk = 1;
+ tmod.memptr->address = 0U;
+ tmod.memptr->size = TOTALMEMORYSIZE - (TOTALMEMORYSIZE / BLKSPACEDIV);
+ tmod.memptr->valid = 1;
+ tmod.mallocdeladd[0] = 0U;
+ tmod.precblock[0] = (void *)tmod.memory;
+ tmod.trailblock[0] = NULL;
+ tmod.cntdeladd = 0U;
+ tmod.ptrmemblkqueue = 0U;
+ tmod.mallocdeladd_queue_cnt = 0U;
+ tmod.checkadd = 1U;
+ tmod.checknumentries = 0U;
+ tmod.memerror = 0U;
+ struct memmod *mmod;
+ mmod = &tmod;
+ int cntndarray;
+ struct rand_smc_node *tlnode;
+
+ /*
+ * Creating SMC bias tree
+ */
+ struct rand_smc_node *ndarray = createsmctree(&cntndarray, &tmod);
+
+ if (tmod.memerror != 0) {
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Hard coded seed, will change in the near future for better strategy
+ */
+ srand(89758389);
+
+ /*
+ * Code to traverse the bias tree and select function based on the biaes within
+ *
+ * The algorithm starts with the first node to pull up the biasarray. The
+ * array is specified as a series of values that reflect the bias of the nodes
+ * in question. So for instance if there are three nodes with a bias of 2,5,7
+ * the biasarray would have the following constituency:
+ *
+ * 0,0,1,1,1,1,1,2,2,2,2,2,2,2.
+ *
+ * Mapping 0 as node 1, 1 as node 2, and 2 as node 3.
+ * The biasent variable contains the count of the size of the biasarray which
+ * provides the input for random selection. This is subsequently applied as an
+ * index to the biasarray. The selection pulls up the node and then is checked
+ * for whether it is a leaf or tree node using the norcall variable.
+ * If it is a leaf then the bias tree traversal ends with an SMC call.
+ * If it is a tree node then the process begins again with
+ * another loop to continue the process of selection until an eventual leaf
+ * node is found.
+ */
+ for (unsigned int i = 0U; i < 100U; i++) {
+ tlnode = &ndarray[cntndarray - 1];
+ int nd = 0;
+ while (nd == 0) {
+ int nch = rand()%tlnode->biasent;
+ int selent = tlnode->biasarray[nch];
+ if (tlnode->norcall[selent] == 0) {
+ runtestfunction(tlnode->snames[selent]);
+ nd = 1;
+ } else {
+ tlnode = &tlnode->treenodes[selent];
+ }
+ }
+ }
+
+ /*
+ * End of test SMC selection and freeing of nodes
+ */
+ if (cntndarray > 0) {
+ for (unsigned int j = 0U; j < cntndarray; j++) {
+ for (unsigned int i = 0U; i < ndarray[j].entries; i++) {
+ GENFREE(ndarray[j].snames[i]);
+ GENFREE(ndarray[j].nname[i]);
+ }
+ GENFREE(ndarray[j].biases);
+ GENFREE(ndarray[j].norcall);
+ GENFREE(ndarray[j].biasarray);
+ GENFREE(ndarray[j].snames);
+ GENFREE(ndarray[j].nname);
+ GENFREE(ndarray[j].treenodes);
+ }
+ GENFREE(ndarray);
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/smc_fuzz/src/smcmalloc.c b/smc_fuzz/src/smcmalloc.c
new file mode 100644
index 000000000..10544f9c0
--- /dev/null
+++ b/smc_fuzz/src/smcmalloc.c
@@ -0,0 +1,559 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <debug.h>
+#include <drivers/arm/private_timer.h>
+#include <events.h>
+#include "fifo3d.h"
+#include <libfdt.h>
+
+#include <power_management.h>
+#include <sdei.h>
+#include <tftf_lib.h>
+#include <timer.h>
+
+#include <plat_topology.h>
+#include <platform.h>
+
+/*
+ * Priority encoder for enabling proper alignment of returned malloc
+ * addresses
+ */
+struct peret priorityencoder(unsigned int num)
+{
+ unsigned int topbit = 0U;
+ struct peret prt;
+ unsigned int cntbit = 0U;
+
+ for (unsigned int i = TOPBITSIZE; i != 0U; i--) {
+ if (((num >> i) & 1U) == 1U) {
+ if (topbit < i) {
+ topbit = i;
+ }
+ cntbit++;
+ }
+ }
+ if ((num & 1U) == 1U) {
+ cntbit++;
+ }
+
+ prt.pow2 = 0U;
+ if (cntbit == 1U) {
+ prt.pow2 = 1U;
+ }
+ prt.tbit = topbit;
+ return prt;
+}
+
+/*
+ * Generic malloc function requesting memory. Alignment of
+ * returned memory is the next largest size if not a power
+ * of two. The memmod structure is required to represent memory image
+ */
+void *smcmalloc(unsigned int rsize,
+ struct memmod *mmod)
+{
+ unsigned int alignnum;
+ unsigned int modval;
+ unsigned int aladd;
+ unsigned int mallocdeladd_pos = 0U;
+ struct memblk *newblk = NULL;
+ bool foundmem = false;
+ struct peret prt;
+ int incrnmemblk = 0;
+ int incrcntdeladd = 0;
+
+ /*
+ * minimum size is 16
+ */
+ if (rsize < 16U) {
+ rsize = 16U;
+ }
+
+ /*
+ * Is size on a power of 2 boundary? if not select next largest power of 2
+ * to place the memory request in
+ */
+ prt = priorityencoder(rsize);
+ if (prt.pow2 == 1U) {
+ alignnum = 1U << prt.tbit;
+ } else {
+ alignnum = 1U << (prt.tbit + 1);
+ }
+ mmod->memptr = (void *)mmod->memory;
+ for (unsigned int i = 0U; i < mmod->nmemblk; i++) {
+ modval = mmod->memptr->address % alignnum;
+ if (modval == 0U) {
+ aladd = 0U;
+ } else {
+ aladd = alignnum - modval;
+ }
+
+ /*
+ * Searching sizes and alignments of memory blocks to find a candidate that will
+ * accept the size
+ */
+ if ((rsize <= (mmod->memptr->size - aladd)) &&
+ (mmod->memptr->size > aladd) && (mmod->memptr->valid == 1)) {
+ foundmem = true;
+
+ /*
+ * Reuse malloc table entries that have been retired.
+ * If none exists create new entry
+ */
+ if (mmod->mallocdeladd_queue_cnt > 0U) {
+ mmod->mallocdeladd_queue_cnt--;
+ mallocdeladd_pos =
+ mmod->mallocdeladd_queue[mmod->
+ mallocdeladd_queue_cnt];
+ } else {
+ mallocdeladd_pos = mmod->cntdeladd;
+ incrcntdeladd = 1;
+ }
+
+ /*
+ * Determining if the size adheres to power of 2 boundary and
+ * if a retired malloc block
+ * can be utilized from the malloc table
+ */
+ if (modval == 0U) {
+ if (mmod->ptrmemblkqueue > 0U) {
+ newblk = mmod->memblkqueue[mmod->ptrmemblkqueue - 1U];
+ mmod->ptrmemblkqueue--;
+ } else {
+ newblk = mmod->memptrend;
+ newblk++;
+ incrnmemblk = 1;
+ }
+
+ /*
+ * Setting memory block parameters for newly created memory
+ */
+ newblk->size = 0U;
+ newblk->address = mmod->memptr->address;
+ newblk->valid = 1;
+ mmod->precblock[mallocdeladd_pos] = newblk;
+
+ /*
+ * Scrolling through the malloc attribute table to
+ * find entries that have values that
+ * match the newly created block and replace them with it
+ */
+ unsigned int fadd = newblk->address + newblk->size;
+ for (unsigned int j = 0U; j < mmod->cntdeladd; j++) {
+ if ((fadd == mmod->mallocdeladd[j]) && (mmod->mallocdeladd_valid[j] == 1U)) {
+ mmod->precblock[j] = newblk;
+ }
+ if ((fadd ==
+ (mmod->mallocdeladd[j] + mmod->memallocsize[j])) && (mmod->mallocdeladd_valid[j] == 1U)) {
+ mmod->trailblock[j] = newblk;
+ }
+ }
+
+ /*
+ * Setting table parameters
+ */
+ mmod->mallocdeladd[mallocdeladd_pos] =
+ mmod->memptr->address;
+ mmod->memallocsize[mallocdeladd_pos] = rsize;
+ mmod->memptr->size -= rsize;
+ mmod->memptr->address += (rsize);
+ mmod->trailblock[mallocdeladd_pos] = mmod->memptr;
+ mmod->mallocdeladd_valid[mallocdeladd_pos] = 1U;
+ mmod->memptr = (void *)mmod->memory;
+
+ /*
+ * Removing entries from malloc table that can be
+ * merged with other blocks
+ */
+ for (unsigned int j = 0U; j < mmod->nmemblk; j++) {
+ if (mmod->memptr->valid == 1) {
+ if ((mmod->trailblock[mallocdeladd_pos]->address +
+ mmod->trailblock[mallocdeladd_pos]->size) == mmod->memptr->address) {
+ if ((mmod->memptr->size ==
+ 0U) && (mmod->trailblock[mallocdeladd_pos]->size != 0U)) {
+ mmod->memptr->valid = 0;
+ mmod->memblkqueue[mmod->ptrmemblkqueue] = mmod->memptr;
+ mmod->ptrmemblkqueue++;
+ if (mmod->ptrmemblkqueue >= mmod->maxmemblk) {
+ mmod->memerror = 1U;
+ }
+ }
+ }
+ }
+ mmod->memptr++;
+ }
+ } else {
+ /*
+ * Allocating memory that is aligned with power of 2
+ */
+ unsigned int nblksize = mmod->memptr->size - rsize - (alignnum - modval);
+ if (mmod->ptrmemblkqueue > 0U) {
+ newblk = mmod->memblkqueue[mmod->ptrmemblkqueue - 1U];
+ mmod->ptrmemblkqueue--;
+ } else {
+ newblk = mmod->memptrend;
+ newblk++;
+ incrnmemblk = 1;
+ }
+ newblk->size = nblksize;
+ newblk->address = mmod->memptr->address +
+ (alignnum - modval) + rsize;
+ newblk->valid = 1;
+ mmod->trailblock[mallocdeladd_pos] = newblk;
+
+ /*
+ * Scrolling through the malloc attribute table to find entries
+ * that have values that
+ * match the newly created block and replace them with it
+ */
+ unsigned int fadd = newblk->address + newblk->size;
+ for (unsigned int i = 0U; i < mmod->cntdeladd; i++) {
+ if ((fadd == mmod->mallocdeladd[i]) && (mmod->mallocdeladd_valid[i] == 1U)) {
+ mmod->precblock[i] = newblk;
+ }
+ if ((fadd == (mmod->mallocdeladd[i] +
+ mmod->memallocsize[i])) && (mmod->mallocdeladd_valid[i] == 1U)) {
+ mmod->trailblock[i] = newblk;
+ }
+ }
+
+ /*
+ * Setting table parameters
+ */
+ mmod->memallocsize[mallocdeladd_pos] = rsize;
+ mmod->memptr->size = (alignnum - modval);
+ mmod->mallocdeladd[mallocdeladd_pos] = mmod->memptr->address + mmod->memptr->size;
+ mmod->precblock[mallocdeladd_pos] = mmod->memptr;
+ mmod->mallocdeladd_valid[mallocdeladd_pos] = 1U;
+ }
+ if (incrcntdeladd == 1) {
+ mmod->cntdeladd++;
+ if (mmod->cntdeladd >= mmod->maxmemblk) {
+ printf("ERROR: size of GENMALLOC table exceeded\n");
+ mmod->memerror = 2U;
+ }
+ }
+ break;
+ }
+ mmod->memptr++;
+ }
+ if (incrnmemblk == 1) {
+ mmod->nmemblk++;
+ mmod->memptrend++;
+ if (mmod->nmemblk >=
+ ((TOTALMEMORYSIZE / BLKSPACEDIV)/sizeof(struct memblk))) {
+ printf("SMC GENMALLOC exceeded block limit of %ld\n",
+ ((TOTALMEMORYSIZE / BLKSPACEDIV) / sizeof(struct memblk)));
+ mmod->memerror = 3U;
+ }
+ }
+ if (foundmem == false) {
+ printf("ERROR: SMC GENMALLOC did not find memory region, size is %u\n", rsize);
+ mmod->memerror = 4U;
+ }
+
+/*
+ * Debug functions
+ */
+
+#ifdef DEBUG_SMC_MALLOC
+ if (mmod->checkadd == 1) {
+ for (unsigned int i = 0U; i < mmod->checknumentries; i++) {
+ if (((mmod->mallocdeladd[mallocdeladd_pos] >
+ mmod->checksa[i])
+ && (mmod->mallocdeladd[mallocdeladd_pos] <
+ mmod->checkea[i]))
+ || (((mmod->mallocdeladd[mallocdeladd_pos] + rsize) >
+ mmod->checksa[i])
+ && ((mmod->mallocdeladd[mallocdeladd_pos] + rsize) <
+ mmod->checkea[i]))) {
+ printf("ERROR: found overlap with previous addressin smc GENMALLOC\n");
+ printf("New address %u size %u\n", mmod->mallocdeladd[mallocdeladd_pos], rsize);
+ printf("Conflicting address %u size %u\n", mmod->checksa[i], (mmod->checkea[i] - mmod->checksa[i]));
+ mmod->memerror = 5U;
+ }
+ }
+ mmod->checksa[mmod->checknumentries] =
+ mmod->mallocdeladd[mallocdeladd_pos];
+ mmod->checkea[mmod->checknumentries] =
+ mmod->mallocdeladd[mallocdeladd_pos] + rsize;
+ mmod->checknumentries++;
+ if (mmod->checknumentries >= (4U * mmod->maxmemblk)) {
+ printf("ERROR: check queue size exceeded\n"); mmod->memerror = 6U;
+ }
+ mmod->memptr = (void *)mmod->memory;
+ for (unsigned int i = 0U; i < mmod->nmemblk; i++) {
+ if (mmod->memptr->valid == 1) {
+ if (((mmod->mallocdeladd[mallocdeladd_pos] >
+ mmod->memptr->address)
+ && (mmod->mallocdeladd[mallocdeladd_pos] < (mmod->memptr->address + mmod->memptr->size)))
+ || (((mmod->mallocdeladd[mallocdeladd_pos] + rsize) > mmod->memptr->address)
+ && ((mmod->mallocdeladd[mallocdeladd_pos] +
+ rsize) < (mmod->memptr->address + mmod->memptr->size)))) {
+ printf("ERROR: found overlap with GENFREE memory region in smc GENMALLOC\n");
+ printf("New address %u size %u\n", mmod->mallocdeladd[mallocdeladd_pos], rsize);
+ printf("Conflicting address %u size %u\n", mmod->memptr->address, mmod->memptr->size);
+ mmod->memerror = 7U;
+ }
+ }
+ mmod->memptr++;
+ }
+ for (unsigned int i = 0U; i < mmod->cntdeladd; i++) {
+ if (mmod->mallocdeladd_valid[i] == 1) {
+ mmod->memptr = (void *)mmod->memory;
+ for (unsigned int j = 0U; j < mmod->nmemblk; j++) {
+ if (mmod->memptr->valid == 1) {
+ if (((mmod->mallocdeladd[i] >
+ mmod->memptr->address)
+ && (mmod->mallocdeladd[i] < (mmod->memptr->address + mmod->memptr->size)))
+ || (((mmod->mallocdeladd[i] + mmod->memallocsize[i]) > mmod->memptr->address)
+ && ((mmod->mallocdeladd[i] + mmod->memallocsize[i]) <
+ (mmod->memptr->address + mmod->memptr->size)))) {
+ printf("ERROR: found overlap with GENFREE memory region ");
+ printf("full search in smc GENMALLOC\n");
+ printf("New address %u size %u\n", mmod->mallocdeladd[i],
+ mmod->memallocsize[i]);
+ printf("Conflicting address %u size %u\n", mmod->memptr->address,
+ mmod->memptr->size);
+ mmod->memerror = 8U;
+ }
+ }
+ mmod->memptr++;
+ }
+ }
+ }
+ mmod->memptr = (void *)mmod->memory;
+ newblk = (void *)mmod->memory;
+ for (unsigned int i = 0U; i < mmod->nmemblk; i++) {
+ if (mmod->memptr->valid == 1) {
+ for (unsigned int j = 0U; j < mmod->nmemblk; j++) {
+ if (newblk->valid == 1) {
+ if (((mmod->memptr->address >
+ newblk->address) && (mmod->memptr->address < (newblk->address + newblk->size)))
+ || (((mmod->memptr->address + mmod->memptr->size) >
+ newblk->address) && ((mmod->memptr->address +
+ mmod->memptr->size) < (newblk->address + newblk->size)))) {
+ printf("ERROR: found overlap in GENFREE memory regions in smc GENMALLOC\n");
+ printf("Region 1 address %u size %u\n", mmod->memptr->address, mmod->memptr->size);
+ printf("Region 2 address %u size %u\n", newblk->address, newblk->size);
+ mmod->memerror = 9U;
+ }
+ }
+ newblk++;
+ }
+ }
+ mmod->memptr++;
+ newblk = (void *)mmod->memory;
+ }
+ }
+#endif
+ return (void *)mmod->memory + ((TOTALMEMORYSIZE / BLKSPACEDIV)) +
+ mmod->mallocdeladd[mallocdeladd_pos];
+#ifdef DEBUG_SMC_MALLOC
+ return (void *)mmod->memory + 0x100U + mmod->mallocdeladd[mallocdeladd_pos];
+#endif
+}
+
+/*
+ * Memory free function for memory allocated from malloc function.
+ * The memmod structure is
+ * required to represent memory image
+ */
+
+int smcfree(void *faddptr,
+ struct memmod *mmod)
+{
+ unsigned int fadd = faddptr - ((TOTALMEMORYSIZE/BLKSPACEDIV)) -
+ (void *)mmod->memory;
+ int fentry = 0;
+ struct memblk *newblk = NULL;
+ int incrnmemblk = 0;
+
+ /*
+ * Scrolling through the malloc attribute table to find entries that match
+ * the user supplied address
+ */
+
+
+ for (unsigned int i = 0U; i < mmod->cntdeladd; i++) {
+ if ((fadd == mmod->mallocdeladd[i]) &&
+ (mmod->mallocdeladd_valid[i] == 1U)) {
+ fentry = 1;
+ if (mmod->trailblock[i] != NULL) {
+ if ((mmod->precblock[i]->address + mmod->precblock[i]->size) == fadd) {
+
+ /*
+ * Found matching attribute block and then proceed to merge with
+ * surrounding blocks
+ */
+
+ mmod->precblock[i]->size += mmod->memallocsize[i] + mmod->trailblock[i]->size;
+ mmod->memblkqueue[mmod->ptrmemblkqueue] = mmod->trailblock[i];
+ mmod->ptrmemblkqueue++;
+ if (mmod->ptrmemblkqueue >= mmod->maxmemblk) {
+ printf("ERROR: GENMALLOC size exceeded in memory block queue\n");
+ exit(1);
+ }
+ mmod->trailblock[i]->valid = 0;
+ newblk = mmod->precblock[i];
+ mmod->memptr = (void *)mmod->memory;
+
+ /*
+ * Scrolling through the malloc attribute table to find entries that have values that
+ * match the newly merged block and replace them with it
+ */
+
+ for (unsigned int j = 0U; j < mmod->nmemblk; j++) {
+ if (mmod->memptr->valid == 1) {
+ if ((mmod->trailblock[i]->address + mmod->trailblock[i]->size) == mmod->memptr->address) {
+ if ((mmod->memptr->size == 0U) &&
+ (mmod->trailblock[i]->size != 0U)) {
+ mmod->memptr->valid = 0;
+ mmod->memblkqueue[mmod->ptrmemblkqueue] = mmod->memptr;
+ mmod->ptrmemblkqueue++;
+ if (mmod->ptrmemblkqueue >= mmod->maxmemblk) {
+ printf("ERROR: GENMALLOC size exceeded in memory block queue\n");
+ exit(1);
+ }
+ }
+ }
+ }
+ mmod->memptr++;
+ }
+ }
+ }
+
+ /*
+ * Setting table parameters
+ */
+
+ mmod->mallocdeladd_valid[i] = 0U;
+ mmod->mallocdeladd_queue[mmod->mallocdeladd_queue_cnt] = i;
+ mmod->mallocdeladd_queue_cnt++;
+ if (mmod->mallocdeladd_queue_cnt >= mmod->maxmemblk) {
+ printf("ERROR: GENMALLOC reuse queue size exceeded\n");
+ exit(1);
+ }
+
+ /*
+ * Scrolling through the malloc attribute table to find entries
+ * that have values that
+ * match the newly merged block and replace them with it
+ */
+
+ unsigned int faddGENFREE = newblk->address + newblk->size;
+ for (unsigned int j = 0U; j < mmod->cntdeladd; j++) {
+ if ((faddGENFREE == mmod->mallocdeladd[j]) &&
+ (mmod->mallocdeladd_valid[j] == 1U))
+ mmod->precblock[j] = newblk;
+ if ((faddGENFREE ==
+ (mmod->mallocdeladd[j] +
+ mmod->memallocsize[i])) &&
+ (mmod->mallocdeladd_valid[j] == 1U))
+ mmod->trailblock[j] = newblk;
+ }
+ }
+ }
+ if (incrnmemblk == 1) {
+ mmod->nmemblk++;
+ mmod->memptrend++;
+ if (mmod->nmemblk >=
+ ((TOTALMEMORYSIZE / BLKSPACEDIV) / sizeof(struct memblk))) {
+ printf("SMC GENFREE exceeded block limit of %ld\n",
+ ((TOTALMEMORYSIZE / BLKSPACEDIV) / sizeof(struct memblk)));
+ exit(1);
+ }
+ }
+ if (fentry == 0) {
+ printf("ERROR: smcGENFREE cannot find address to GENFREE %u\n", fadd);
+ exit(1);
+ }
+#ifdef DEBUG_SMC_MALLOC
+
+/*
+ * Debug functions
+ */
+
+ if (mmod->checkadd == 1) {
+ for (unsigned int i = 0U; i < mmod->checknumentries; i++) {
+ if (fadd == mmod->checksa[i]) {
+ mmod->checksa[i] = 0U;
+ mmod->checkea[i] = 0U;
+ }
+ }
+ mmod->memptr = (void *)mmod->memory;
+ newblk = (void *)mmod->memory;
+ for (unsigned int i = 0U; i < mmod->nmemblk; i++) {
+ if (mmod->memptr->valid == 1) {
+ for (unsigned int j = 0U; j < mmod->nmemblk; j++) {
+ if (newblk->valid == 1) {
+ if (((mmod->memptr->address > newblk->address)
+ && (mmod->memptr->address < (newblk->address + newblk->size)))
+ || (((mmod->memptr->address + mmod->memptr->size) > newblk->address)
+ && ((mmod->memptr->address + mmod->memptr->size) < ((newblk->address + newblk->size))))) {
+ printf("ERROR: found overlap in GENFREE memory regions in smc GENMALLOC\n");
+ printf("Region 1 address %u size %u\n", mmod->memptr->address, mmod->memptr->size);
+ printf("Region 2 address %u size %u\n", newblk->address, newblk->size);
+ }
+ }
+ newblk++;
+ }
+ }
+ mmod->memptr++;
+ newblk = (void *)mmod->memory;
+ }
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Diplay malloc tables for debug purposes
+ */
+
+#ifdef DEBUG_SMC_MALLOC
+void displayblocks(struct memmod *mmod)
+{
+ mmod->memptr = (void *)mmod->memory;
+ printf("Displaying blocks:\n");
+ for (unsigned int i = 0U; i < mmod->nmemblk; i++) {
+ if (mmod->memptr->valid == 1) {
+ printf("*********************************************************************************************\n");
+ printf("%u * Address: %u * Size: %u * Valid: %u *\n", i, mmod->memptr->address, mmod->memptr->size, mmod->memptr->valid);
+ }
+ mmod->memptr++;
+ }
+}
+
+void displaymalloctable(struct memmod *mmod)
+{
+ printf("\n\nDisplaying GENMALLOC table\n");
+ for (unsigned int i = 0U; i < mmod->cntdeladd; i++) {
+ if (mmod->mallocdeladd_valid[i] == 1U) {
+ printf("**********************************************************************************************\n");
+ printf("GENMALLOC Address: %u\n", mmod->mallocdeladd[i]);
+ printf("**********************************************************************************************\n");
+ printf("GENMALLOC Size: %u\n", mmod->memallocsize[i]);
+ printf("**********************************************************************************************\n");
+ if (mmod->trailblock[i] != NULL) {
+ printf("Trail Block:\n");
+ printf("* Address: %u * Size: %u *\n",
+ mmod->trailblock[i]->address,
+ mmod->trailblock[i]->size);
+ }
+ printf("**********************************************************************************************\n");
+ if (mmod->precblock[i] != NULL) {
+ printf("Previous Block:\n");
+ printf("* Address: %u * Size: %u *\n",
+ mmod->precblock[i]->address,
+ mmod->precblock[i]->size);
+ }
+ printf("**********************************************************************************************\n\n\n");
+ }
+ }
+}
+#endif