util: Add coremark repository
This remove coremark code from core repository and adds
external githun repository with unmodified code.
apps/coremark is now stripped to minimum
Coremark is not package in util/coremark and can
be included in any application it also provides
shell command 'coremark' that can be execute
when SHELL_TASK is enabled.
Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
diff --git a/apps/coremark/include/coremark.h b/apps/coremark/include/coremark.h
deleted file mode 100644
index 075f791..0000000
--- a/apps/coremark/include/coremark.h
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-/* Topic: Description
- This file contains declarations of the various benchmark functions.
-*/
-
-/* Configuration: TOTAL_DATA_SIZE
- Define total size for data algorithms will operate on
-*/
-#ifndef TOTAL_DATA_SIZE
-#define TOTAL_DATA_SIZE 2*1000
-#endif
-
-#define SEED_ARG 0
-#define SEED_FUNC 1
-#define SEED_VOLATILE 2
-
-#define MEM_STATIC 0
-#define MEM_MALLOC 1
-#define MEM_STACK 2
-
-#include "core_portme.h"
-
-#if HAS_STDIO
-#include <stdio.h>
-#endif
-#if HAS_PRINTF
-#define ee_printf printf
-#endif
-
-/* Actual benchmark execution in iterate */
-void *iterate(void *pres);
-
-/* Typedef: secs_ret
- For machines that have floating point support, get number of seconds as a double.
- Otherwise an unsigned int.
-*/
-#if HAS_FLOAT
-typedef double secs_ret;
-#else
-typedef ee_u32 secs_ret;
-#endif
-
-#if MAIN_HAS_NORETURN
-#define MAIN_RETURN_VAL
-#define MAIN_RETURN_TYPE void
-#else
-#define MAIN_RETURN_VAL 0
-#define MAIN_RETURN_TYPE int
-#endif
-
-void start_time(void);
-void stop_time(void);
-CORE_TICKS get_time(void);
-secs_ret time_in_secs(CORE_TICKS ticks);
-
-/* Misc useful functions */
-ee_u16 crcu8(ee_u8 data, ee_u16 crc);
-ee_u16 crc16(ee_s16 newval, ee_u16 crc);
-ee_u16 crcu16(ee_u16 newval, ee_u16 crc);
-ee_u16 crcu32(ee_u32 newval, ee_u16 crc);
-ee_u8 check_data_types();
-void *portable_malloc(ee_size_t size);
-void portable_free(void *p);
-ee_s32 parseval(char *valstring);
-
-/* Algorithm IDS */
-#define ID_LIST (1<<0)
-#define ID_MATRIX (1<<1)
-#define ID_STATE (1<<2)
-#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE)
-#define NUM_ALGORITHMS 3
-
-/* list data structures */
-typedef struct list_data_s {
- ee_s16 data16;
- ee_s16 idx;
-} list_data;
-
-typedef struct list_head_s {
- struct list_head_s *next;
- struct list_data_s *info;
-} list_head;
-
-
-/*matrix benchmark related stuff */
-#define MATDAT_INT 1
-#if MATDAT_INT
-typedef ee_s16 MATDAT;
-typedef ee_s32 MATRES;
-#else
-typedef ee_f16 MATDAT;
-typedef ee_f32 MATRES;
-#endif
-
-typedef struct MAT_PARAMS_S {
- int N;
- MATDAT *A;
- MATDAT *B;
- MATRES *C;
-} mat_params;
-
-/* state machine related stuff */
-/* List of all the possible states for the FSM */
-typedef enum CORE_STATE {
- CORE_START=0,
- CORE_INVALID,
- CORE_S1,
- CORE_S2,
- CORE_INT,
- CORE_FLOAT,
- CORE_EXPONENT,
- CORE_SCIENTIFIC,
- NUM_CORE_STATES
-} core_state_e ;
-
-
-/* Helper structure to hold results */
-typedef struct RESULTS_S {
- /* inputs */
- ee_s16 seed1; /* Initializing seed */
- ee_s16 seed2; /* Initializing seed */
- ee_s16 seed3; /* Initializing seed */
- void *memblock[4]; /* Pointer to safe memory location */
- ee_u32 size; /* Size of the data */
- ee_u32 iterations; /* Number of iterations to execute */
- ee_u32 execs; /* Bitmask of operations to execute */
- struct list_head_s *list;
- mat_params mat;
- /* outputs */
- ee_u16 crc;
- ee_u16 crclist;
- ee_u16 crcmatrix;
- ee_u16 crcstate;
- ee_s16 err;
- /* ultithread specific */
- core_portable port;
-} core_results;
-
-/* Multicore execution handling */
-#if (MULTITHREAD>1)
-ee_u8 core_start_parallel(core_results *res);
-ee_u8 core_stop_parallel(core_results *res);
-#endif
-
-/* list benchmark functions */
-list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed);
-ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx);
-
-/* state benchmark functions */
-void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p);
-ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
- ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc);
-
-/* matrix benchmark functions */
-ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p);
-ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc);
-
diff --git a/apps/coremark/pkg.yml b/apps/coremark/pkg.yml
index 39bea07..f3ec0a8 100644
--- a/apps/coremark/pkg.yml
+++ b/apps/coremark/pkg.yml
@@ -30,3 +30,4 @@
- "@apache-mynewt-core/sys/stats"
- "@apache-mynewt-core/sys/log"
- "@apache-mynewt-core/sys/console"
+ - "@apache-mynewt-core/util/coremark"
diff --git a/apps/coremark/src/core_list_join.c b/apps/coremark/src/core_list_join.c
deleted file mode 100644
index f3fa086..0000000
--- a/apps/coremark/src/core_list_join.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-#include "coremark.h"
-/*
-Topic: Description
- Benchmark using a linked list.
-
- Linked list is a common data structure used in many applications.
-
- For our purposes, this will excercise the memory units of the processor.
- In particular, usage of the list pointers to find and alter data.
-
- We are not using Malloc since some platforms do not support this library.
-
- Instead, the memory block being passed in is used to create a list,
- and the benchmark takes care not to add more items then can be
- accomodated by the memory block. The porting layer will make sure
- that we have a valid memory block.
-
- All operations are done in place, without using any extra memory.
-
- The list itself contains list pointers and pointers to data items.
- Data items contain the following:
-
- idx - An index that captures the initial order of the list.
- data - Variable data initialized based on the input parameters. The 16b are divided as follows:
- o Upper 8b are backup of original data.
- o Bit 7 indicates if the lower 7 bits are to be used as is or calculated.
- o Bits 0-2 indicate type of operation to perform to get a 7b value.
- o Bits 3-6 provide input for the operation.
-
-*/
-
-/* local functions */
-
-list_head *core_list_find(list_head *list,list_data *info);
-list_head *core_list_reverse(list_head *list);
-list_head *core_list_remove(list_head *item);
-list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified);
-list_head *core_list_insert_new(list_head *insert_point
- , list_data *info, list_head **memblock, list_data **datablock
- , list_head *memblock_end, list_data *datablock_end);
-typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res);
-list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res);
-
-ee_s16 calc_func(ee_s16 *pdata, core_results *res) {
- ee_s16 data=*pdata;
- ee_s16 retval;
- ee_u8 optype=(data>>7) & 1; /* bit 7 indicates if the function result has been cached */
- if (optype) /* if cached, use cache */
- return (data & 0x007f);
- else { /* otherwise calculate and cache the result */
- ee_s16 flag=data & 0x7; /* bits 0-2 is type of function to perform */
- ee_s16 dtype=((data>>3) & 0xf); /* bits 3-6 is specific data for the operation */
- dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */
- switch (flag) {
- case 0:
- if (dtype<0x22) /* set min period for bit corruption */
- dtype=0x22;
- retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc);
- if (res->crcstate==0)
- res->crcstate=retval;
- break;
- case 1:
- retval=core_bench_matrix(&(res->mat),dtype,res->crc);
- if (res->crcmatrix==0)
- res->crcmatrix=retval;
- break;
- default:
- retval=data;
- break;
- }
- res->crc=crcu16(retval,res->crc);
- retval &= 0x007f;
- *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */
- return retval;
- }
-}
-/* Function: cmp_complex
- Compare the data item in a list cell.
-
- Can be used by mergesort.
-*/
-ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) {
- ee_s16 val1=calc_func(&(a->data16),res);
- ee_s16 val2=calc_func(&(b->data16),res);
- return val1 - val2;
-}
-
-/* Function: cmp_idx
- Compare the idx item in a list cell, and regen the data.
-
- Can be used by mergesort.
-*/
-ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) {
- if (res==NULL) {
- a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8));
- b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8));
- }
- return a->idx - b->idx;
-}
-
-void copy_info(list_data *to,list_data *from) {
- to->data16=from->data16;
- to->idx=from->idx;
-}
-
-/* Benchmark for linked list:
- - Try to find multiple data items.
- - List sort
- - Operate on data from list (crc)
- - Single remove/reinsert
- * At the end of this function, the list is back to original state
-*/
-ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) {
- ee_u16 retval=0;
- ee_u16 found=0,missed=0;
- list_head *list=res->list;
- ee_s16 find_num=res->seed3;
- list_head *this_find;
- list_head *finder, *remover;
- list_data info;
- ee_s16 i;
-
- info.idx=finder_idx;
- /* find <find_num> values in the list, and change the list each time (reverse and cache if value found) */
- for (i=0; i<find_num; i++) {
- info.data16= (i & 0xff) ;
- this_find=core_list_find(list,&info);
- list=core_list_reverse(list);
- if (this_find==NULL) {
- missed++;
- retval+=(list->next->info->data16 >> 8) & 1;
- }
- else {
- found++;
- if (this_find->info->data16 & 0x1) /* use found value */
- retval+=(this_find->info->data16 >> 9) & 1;
- /* and cache next item at the head of the list (if any) */
- if (this_find->next != NULL) {
- finder = this_find->next;
- this_find->next = finder->next;
- finder->next=list->next;
- list->next=finder;
- }
- }
- if (info.idx>=0)
- info.idx++;
-#if CORE_DEBUG
- ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found);
-#endif
- }
- retval+=found*4-missed;
- /* sort the list by data content and remove one item*/
- if (finder_idx>0)
- list=core_list_mergesort(list,cmp_complex,res);
- remover=core_list_remove(list->next);
- /* CRC data content of list from location of index N forward, and then undo remove */
- finder=core_list_find(list,&info);
- if (!finder)
- finder=list->next;
- while (finder) {
- retval=crc16(list->info->data16,retval);
- finder=finder->next;
- }
-#if CORE_DEBUG
- ee_printf("List sort 1: %04x\n",retval);
-#endif
- remover=core_list_undo_remove(remover,list->next);
- /* sort the list by index, in effect returning the list to original state */
- list=core_list_mergesort(list,cmp_idx,NULL);
- /* CRC data content of list */
- finder=list->next;
- while (finder) {
- retval=crc16(list->info->data16,retval);
- finder=finder->next;
- }
-#if CORE_DEBUG
- ee_printf("List sort 2: %04x\n",retval);
-#endif
- return retval;
-}
-/* Function: core_list_init
- Initialize list with data.
-
- Parameters:
- blksize - Size of memory to be initialized.
- memblock - Pointer to memory block.
- seed - Actual values chosen depend on the seed parameter.
- The seed parameter MUST be supplied from a source that cannot be determined at compile time
-
- Returns:
- Pointer to the head of the list.
-
-*/
-list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) {
- /* calculated pointers for the list */
- ee_u32 per_item=16+sizeof(struct list_data_s);
- ee_u32 size=(blksize/per_item)-2; /* to accomodate systems with 64b pointers, and make sure same code is executed, set max list elements */
- list_head *memblock_end=memblock+size;
- list_data *datablock=(list_data *)(memblock_end);
- list_data *datablock_end=datablock+size;
- /* some useful variables */
- ee_u32 i;
- list_head *finder,*list=memblock;
- list_data info;
-
- /* create a fake items for the list head and tail */
- list->next=NULL;
- list->info=datablock;
- list->info->idx=0x0000;
- list->info->data16=(ee_s16)0x8080;
- memblock++;
- datablock++;
- info.idx=0x7fff;
- info.data16=(ee_s16)0xffff;
- core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
-
- /* then insert size items */
- for (i=0; i<size; i++) {
- ee_u16 datpat=((ee_u16)(seed^i) & 0xf);
- ee_u16 dat=(datpat<<3) | (i&0x7); /* alternate between algorithms */
- info.data16=(dat<<8) | dat; /* fill the data with actual data and upper bits with rebuild value */
- core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
- }
- /* and now index the list so we know initial seed order of the list */
- finder=list->next;
- i=1;
- while (finder->next!=NULL) {
- if (i<size/5) /* first 20% of the list in order */
- finder->info->idx=i++;
- else {
- ee_u16 pat=(ee_u16)(i++ ^ seed); /* get a pseudo random number */
- finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat); /* make sure the mixed items end up after the ones in sequence */
- }
- finder=finder->next;
- }
- list = core_list_mergesort(list,cmp_idx,NULL);
-#if CORE_DEBUG
- ee_printf("Initialized list:\n");
- finder=list;
- while (finder) {
- ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16);
- finder=finder->next;
- }
- ee_printf("\n");
-#endif
- return list;
-}
-
-/* Function: core_list_insert
- Insert an item to the list
-
- Parameters:
- insert_point - where to insert the item.
- info - data for the cell.
- memblock - pointer for the list header
- datablock - pointer for the list data
- memblock_end - end of region for list headers
- datablock_end - end of region for list data
-
- Returns:
- Pointer to new item.
-*/
-list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock
- , list_head *memblock_end, list_data *datablock_end) {
- list_head *newitem;
-
- if ((*memblock+1) >= memblock_end)
- return NULL;
- if ((*datablock+1) >= datablock_end)
- return NULL;
-
- newitem=*memblock;
- (*memblock)++;
- newitem->next=insert_point->next;
- insert_point->next=newitem;
-
- newitem->info=*datablock;
- (*datablock)++;
- copy_info(newitem->info,info);
-
- return newitem;
-}
-
-/* Function: core_list_remove
- Remove an item from the list.
-
- Operation:
- For a singly linked list, remove by copying the data from the next item
- over to the current cell, and unlinking the next item.
-
- Note:
- since there is always a fake item at the end of the list, no need to check for NULL.
-
- Returns:
- Removed item.
-*/
-list_head *core_list_remove(list_head *item) {
- list_data *tmp;
- list_head *ret=item->next;
- /* swap data pointers */
- tmp=item->info;
- item->info=ret->info;
- ret->info=tmp;
- /* and eliminate item */
- item->next=item->next->next;
- ret->next=NULL;
- return ret;
-}
-
-/* Function: core_list_undo_remove
- Undo a remove operation.
-
- Operation:
- Since we want each iteration of the benchmark to be exactly the same,
- we need to be able to undo a remove.
- Link the removed item back into the list, and switch the info items.
-
- Parameters:
- item_removed - Return value from the <core_list_remove>
- item_modified - List item that was modified during <core_list_remove>
-
- Returns:
- The item that was linked back to the list.
-
-*/
-list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) {
- list_data *tmp;
- /* swap data pointers */
- tmp=item_removed->info;
- item_removed->info=item_modified->info;
- item_modified->info=tmp;
- /* and insert item */
- item_removed->next=item_modified->next;
- item_modified->next=item_removed;
- return item_removed;
-}
-
-/* Function: core_list_find
- Find an item in the list
-
- Operation:
- Find an item by idx (if not 0) or specific data value
-
- Parameters:
- list - list head
- info - idx or data to find
-
- Returns:
- Found item, or NULL if not found.
-*/
-list_head *core_list_find(list_head *list,list_data *info) {
- if (info->idx>=0) {
- while (list && (list->info->idx != info->idx))
- list=list->next;
- return list;
- } else {
- while (list && ((list->info->data16 & 0xff) != info->data16))
- list=list->next;
- return list;
- }
-}
-/* Function: core_list_reverse
- Reverse a list
-
- Operation:
- Rearrange the pointers so the list is reversed.
-
- Parameters:
- list - list head
- info - idx or data to find
-
- Returns:
- Found item, or NULL if not found.
-*/
-
-list_head *core_list_reverse(list_head *list) {
- list_head *next=NULL, *tmp;
- while (list) {
- tmp=list->next;
- list->next=next;
- next=list;
- list=tmp;
- }
- return next;
-}
-/* Function: core_list_mergesort
- Sort the list in place without recursion.
-
- Description:
- Use mergesort, as for linked list this is a realistic solution.
- Also, since this is aimed at embedded, care was taken to use iterative rather then recursive algorithm.
- The sort can either return the list to original order (by idx) ,
- or use the data item to invoke other other algorithms and change the order of the list.
-
- Parameters:
- list - list to be sorted.
- cmp - cmp function to use
-
- Returns:
- New head of the list.
-
- Note:
- We have a special header for the list that will always be first,
- but the algorithm could theoretically modify where the list starts.
-
- */
-list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) {
- list_head *p, *q, *e, *tail;
- ee_s32 insize, nmerges, psize, qsize, i;
-
- insize = 1;
-
- while (1) {
- p = list;
- list = NULL;
- tail = NULL;
-
- nmerges = 0; /* count number of merges we do in this pass */
-
- while (p) {
- nmerges++; /* there exists a merge to be done */
- /* step `insize' places along from p */
- q = p;
- psize = 0;
- for (i = 0; i < insize; i++) {
- psize++;
- q = q->next;
- if (!q) break;
- }
-
- /* if q hasn't fallen off end, we have two lists to merge */
- qsize = insize;
-
- /* now we have two lists; merge them */
- while (psize > 0 || (qsize > 0 && q)) {
-
- /* decide whether next element of merge comes from p or q */
- if (psize == 0) {
- /* p is empty; e must come from q. */
- e = q; q = q->next; qsize--;
- } else if (qsize == 0 || !q) {
- /* q is empty; e must come from p. */
- e = p; p = p->next; psize--;
- } else if (cmp(p->info,q->info,res) <= 0) {
- /* First element of p is lower (or same); e must come from p. */
- e = p; p = p->next; psize--;
- } else {
- /* First element of q is lower; e must come from q. */
- e = q; q = q->next; qsize--;
- }
-
- /* add the next element to the merged list */
- if (tail) {
- tail->next = e;
- } else {
- list = e;
- }
- tail = e;
- }
-
- /* now p has stepped `insize' places along, and q has too */
- p = q;
- }
-
- tail->next = NULL;
-
- /* If we have done only one merge, we're finished. */
- if (nmerges <= 1) /* allow for nmerges==0, the empty list case */
- return list;
-
- /* Otherwise repeat, merging lists twice the size */
- insize *= 2;
- }
-#if COMPILER_REQUIRES_SORT_RETURN
- return list;
-#endif
-}
diff --git a/apps/coremark/src/core_main.c b/apps/coremark/src/core_main.c
deleted file mode 100644
index e7c1898..0000000
--- a/apps/coremark/src/core_main.c
+++ /dev/null
@@ -1,366 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-/* File: core_main.c
- This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results.
-*/
-#include "coremark.h"
-
-/* Function: iterate
- Run the benchmark for a specified number of iterations.
-
- Operation:
- For each type of benchmarked algorithm:
- a - Initialize the data block for the algorithm.
- b - Execute the algorithm N times.
-
- Returns:
- NULL.
-*/
-static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
-static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
-static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
-void *iterate(void *pres) {
- ee_u32 i;
- ee_u16 crc;
- core_results *res=(core_results *)pres;
- ee_u32 iterations=res->iterations;
- res->crc=0;
- res->crclist=0;
- res->crcmatrix=0;
- res->crcstate=0;
-
- for (i=0; i<iterations; i++) {
- crc=core_bench_list(res,1);
- res->crc=crcu16(crc,res->crc);
- crc=core_bench_list(res,-1);
- res->crc=crcu16(crc,res->crc);
- if (i==0) res->crclist=res->crc;
- }
- return NULL;
-}
-
-#if (SEED_METHOD==SEED_ARG)
-ee_s32 get_seed_args(int i, int argc, char *argv[]);
-#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv)
-#define get_seed_32(x) get_seed_args(x,argc,argv)
-#else /* via function or volatile */
-ee_s32 get_seed_32(int i);
-#define get_seed(x) (ee_s16)get_seed_32(x)
-#endif
-
-#if (MEM_METHOD==MEM_STATIC)
-ee_u8 static_memblk[TOTAL_DATA_SIZE];
-#endif
-char *mem_name[3] = {"Static","Heap","Stack"};
-/* Function: main
- Main entry routine for the benchmark.
- This function is responsible for the following steps:
-
- 1 - Initialize input seeds from a source that cannot be determined at compile time.
- 2 - Initialize memory block for use.
- 3 - Run and time the benchmark.
- 4 - Report results, testing the validity of the output if the seeds are known.
-
- Arguments:
- 1 - first seed : Any value
- 2 - second seed : Must be identical to first for iterations to be identical
- 3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32.
- 4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs
-
-*/
-
-#if MAIN_HAS_NOARGC
-MAIN_RETURN_TYPE coremark_main(void) {
- int argc=0;
- char *argv[1];
-#else
-MAIN_RETURN_TYPE coremark_main(int argc, char *argv[]) {
-#endif
- ee_u16 i,j=0,num_algorithms=0;
- ee_s16 known_id=-1,total_errors=0;
- ee_u16 seedcrc=0;
- CORE_TICKS total_time;
- core_results results[MULTITHREAD];
-#if (MEM_METHOD==MEM_STACK)
- ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
-#endif
- /* first call any initializations needed */
- portable_init(&(results[0].port), &argc, argv);
- /* First some checks to make sure benchmark will run ok */
- if (sizeof(struct list_head_s)>128) {
- ee_printf("list_head structure too big for comparable data!\n");
- return MAIN_RETURN_VAL;
- }
- results[0].seed1=get_seed(1);
- results[0].seed2=get_seed(2);
- results[0].seed3=get_seed(3);
- results[0].iterations=get_seed_32(4);
-#if CORE_DEBUG
- results[0].iterations=1;
-#endif
- results[0].execs=get_seed_32(5);
- if (results[0].execs==0) { /* if not supplied, execute all algorithms */
- results[0].execs=ALL_ALGORITHMS_MASK;
- }
- /* put in some default values based on one seed only for easy testing */
- if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */
- results[0].seed1=0;
- results[0].seed2=0;
- results[0].seed3=0x66;
- }
- if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */
- results[0].seed1=0x3415;
- results[0].seed2=0x3415;
- results[0].seed3=0x66;
- }
-#if (MEM_METHOD==MEM_STATIC)
- results[0].memblock[0]=(void *)static_memblk;
- results[0].size=TOTAL_DATA_SIZE;
- results[0].err=0;
- #if (MULTITHREAD>1)
- #error "Cannot use a static data area with multiple contexts!"
- #endif
-#elif (MEM_METHOD==MEM_MALLOC)
- for (i=0 ; i<MULTITHREAD; i++) {
- ee_s32 malloc_override=get_seed(7);
- if (malloc_override != 0)
- results[i].size=malloc_override;
- else
- results[i].size=TOTAL_DATA_SIZE;
- results[i].memblock[0]=portable_malloc(results[i].size);
- results[i].seed1=results[0].seed1;
- results[i].seed2=results[0].seed2;
- results[i].seed3=results[0].seed3;
- results[i].err=0;
- results[i].execs=results[0].execs;
- }
-#elif (MEM_METHOD==MEM_STACK)
- for (i=0 ; i<MULTITHREAD; i++) {
- results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE;
- results[i].size=TOTAL_DATA_SIZE;
- results[i].seed1=results[0].seed1;
- results[i].seed2=results[0].seed2;
- results[i].seed3=results[0].seed3;
- results[i].err=0;
- results[i].execs=results[0].execs;
- }
-#else
-#error "Please define a way to initialize a memory block."
-#endif
- /* Data init */
- /* Find out how space much we have based on number of algorithms */
- for (i=0; i<NUM_ALGORITHMS; i++) {
- if ((1<<(ee_u32)i) & results[0].execs)
- num_algorithms++;
- }
- for (i=0 ; i<MULTITHREAD; i++)
- results[i].size=results[i].size/num_algorithms;
- /* Assign pointers */
- for (i=0; i<NUM_ALGORITHMS; i++) {
- ee_u32 ctx;
- if ((1<<(ee_u32)i) & results[0].execs) {
- for (ctx=0 ; ctx<MULTITHREAD; ctx++)
- results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j;
- j++;
- }
- }
- /* call inits */
- for (i=0 ; i<MULTITHREAD; i++) {
- if (results[i].execs & ID_LIST) {
- results[i].list=core_list_init(results[0].size,results[i].memblock[1],results[i].seed1);
- }
- if (results[i].execs & ID_MATRIX) {
- core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) );
- }
- if (results[i].execs & ID_STATE) {
- core_init_state(results[0].size,results[i].seed1,results[i].memblock[3]);
- }
- }
-
- /* automatically determine number of iterations if not set */
- if (results[0].iterations==0) {
- secs_ret secs_passed=0;
- ee_u32 divisor;
- results[0].iterations=1;
- while (secs_passed < (secs_ret)1) {
- results[0].iterations*=10;
- start_time();
- iterate(&results[0]);
- stop_time();
- secs_passed=time_in_secs(get_time());
- }
- /* now we know it executes for at least 1 sec, set actual run time at about 10 secs */
- divisor=(ee_u32)secs_passed;
- if (divisor==0) /* some machines cast float to int as 0 since this conversion is not defined by ANSI, but we know at least one second passed */
- divisor=1;
- results[0].iterations*=1+10/divisor;
- }
- /* perform actual benchmark */
- start_time();
-#if (MULTITHREAD>1)
- if (default_num_contexts>MULTITHREAD) {
- default_num_contexts=MULTITHREAD;
- }
- for (i=0 ; i<default_num_contexts; i++) {
- results[i].iterations=results[0].iterations;
- results[i].execs=results[0].execs;
- core_start_parallel(&results[i]);
- }
- for (i=0 ; i<default_num_contexts; i++) {
- core_stop_parallel(&results[i]);
- }
-#else
- iterate(&results[0]);
-#endif
- stop_time();
- total_time=get_time();
- /* get a function of the input to report */
- seedcrc=crc16(results[0].seed1,seedcrc);
- seedcrc=crc16(results[0].seed2,seedcrc);
- seedcrc=crc16(results[0].seed3,seedcrc);
- seedcrc=crc16(results[0].size,seedcrc);
-
- switch (seedcrc) { /* test known output for common seeds */
- case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
- known_id=0;
- ee_printf("6k performance run parameters for coremark.\n");
- break;
- case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
- known_id=1;
- ee_printf("6k validation run parameters for coremark.\n");
- break;
- case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
- known_id=2;
- ee_printf("Profile generation run parameters for coremark.\n");
- break;
- case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
- known_id=3;
- ee_printf("2K performance run parameters for coremark.\n");
- break;
- case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
- known_id=4;
- ee_printf("2K validation run parameters for coremark.\n");
- break;
- default:
- total_errors=-1;
- break;
- }
- if (known_id>=0) {
- for (i=0 ; i<default_num_contexts; i++) {
- results[i].err=0;
- if ((results[i].execs & ID_LIST) &&
- (results[i].crclist!=list_known_crc[known_id])) {
- ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
- results[i].err++;
- }
- if ((results[i].execs & ID_MATRIX) &&
- (results[i].crcmatrix!=matrix_known_crc[known_id])) {
- ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
- results[i].err++;
- }
- if ((results[i].execs & ID_STATE) &&
- (results[i].crcstate!=state_known_crc[known_id])) {
- ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
- results[i].err++;
- }
- total_errors+=results[i].err;
- }
- }
- total_errors+=check_data_types();
- /* and report results */
- ee_printf("CoreMark Size : %lu\n", (long unsigned) results[0].size);
- ee_printf("Total ticks : %lu\n", (long unsigned) total_time);
-#if HAS_FLOAT
- ee_printf("Total time (secs): %f\n",time_in_secs(total_time));
- if (time_in_secs(total_time) > 0)
- ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
-#else
- ee_printf("Total time (secs): %d\n",time_in_secs(total_time));
- if (time_in_secs(total_time) > 0)
- ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
-#endif
- if (time_in_secs(total_time) < 10) {
- ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
- total_errors++;
- }
-
- ee_printf("Iterations : %lu\n", (long unsigned) default_num_contexts*results[0].iterations);
- ee_printf("Compiler version : %s\n",COMPILER_VERSION);
- ee_printf("Compiler flags : %s\n",COMPILER_FLAGS);
-#if (MULTITHREAD>1)
- ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
-#endif
- ee_printf("Memory location : %s\n",MEM_LOCATION);
- /* output for verification */
- ee_printf("seedcrc : 0x%04x\n",seedcrc);
- if (results[0].execs & ID_LIST)
- for (i=0 ; i<default_num_contexts; i++)
- ee_printf("[%d]crclist : 0x%04x\n",i,results[i].crclist);
- if (results[0].execs & ID_MATRIX)
- for (i=0 ; i<default_num_contexts; i++)
- ee_printf("[%d]crcmatrix : 0x%04x\n",i,results[i].crcmatrix);
- if (results[0].execs & ID_STATE)
- for (i=0 ; i<default_num_contexts; i++)
- ee_printf("[%d]crcstate : 0x%04x\n",i,results[i].crcstate);
- for (i=0 ; i<default_num_contexts; i++)
- ee_printf("[%d]crcfinal : 0x%04x\n",i,results[i].crc);
- if (total_errors==0) {
- ee_printf("Correct operation validated. See README.md for run and reporting rules.\n");
-#if HAS_FLOAT
- if (known_id==3) {
- ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS);
-#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
- ee_printf(" / %s",MEM_LOCATION);
-#else
- ee_printf(" / %s",mem_name[MEM_METHOD]);
-#endif
-
-#if (MULTITHREAD>1)
- ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD);
-#endif
- ee_printf("\n");
- }
-#endif
- }
- if (total_errors>0)
- ee_printf("Errors detected\n");
- if (total_errors<0)
- ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
-
-#if (MEM_METHOD==MEM_MALLOC)
- for (i=0 ; i<MULTITHREAD; i++)
- portable_free(results[i].memblock[0]);
-#endif
- /* And last call any target specific code for finalizing */
- portable_fini(&(results[0].port));
-
- return MAIN_RETURN_VAL;
-}
-
-int
-mynewt_main(int argc, char **argv)
-{
- sysinit();
-
- coremark_main(argc, argv);
-
- while (1) {
- os_eventq_run(os_eventq_dflt_get());
- }
-}
diff --git a/apps/coremark/src/core_matrix.c b/apps/coremark/src/core_matrix.c
deleted file mode 100644
index 06b706b..0000000
--- a/apps/coremark/src/core_matrix.c
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-#include "coremark.h"
-/*
-Topic: Description
- Matrix manipulation benchmark
-
- This very simple algorithm forms the basis of many more complex algorithms.
-
- The tight inner loop is the focus of many optimizations (compiler as well as hardware based)
- and is thus relevant for embedded processing.
-
- The total available data space will be divided to 3 parts:
- NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
- NxN Matrix B - initialized with medium values (upper half of the bits all zero).
- NxN Matrix C - used for the result.
-
- The actual values for A and B must be derived based on input that is not available at compile time.
-*/
-ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
-ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
-void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
-void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
-void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
-void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
-void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
-
-#define matrix_test_next(x) (x+1)
-#define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
-#define matrix_big(x) (0xf000 | (x))
-#define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
-
-#if CORE_DEBUG
-void printmat(MATDAT *A, ee_u32 N, char *name) {
- ee_u32 i,j;
- ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- if (j!=0)
- ee_printf(",");
- ee_printf("%d",A[i*N+j]);
- }
- ee_printf("\n");
- }
-}
-void printmatC(MATRES *C, ee_u32 N, char *name) {
- ee_u32 i,j;
- ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- if (j!=0)
- ee_printf(",");
- ee_printf("%d",C[i*N+j]);
- }
- ee_printf("\n");
- }
-}
-#endif
-/* Function: core_bench_matrix
- Benchmark function
-
- Iterate <matrix_test> N times,
- changing the matrix values slightly by a constant amount each time.
-*/
-ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
- ee_u32 N=p->N;
- MATRES *C=p->C;
- MATDAT *A=p->A;
- MATDAT *B=p->B;
- MATDAT val=(MATDAT)seed;
-
- crc=crc16(matrix_test(N,C,A,B,val),crc);
-
- return crc;
-}
-
-/* Function: matrix_test
- Perform matrix manipulation.
-
- Parameters:
- N - Dimensions of the matrix.
- C - memory for result matrix.
- A - input matrix
- B - operator matrix (not changed during operations)
-
- Returns:
- A CRC value that captures all results calculated in the function.
- In particular, crc of the value calculated on the result matrix
- after each step by <matrix_sum>.
-
- Operation:
-
- 1 - Add a constant value to all elements of a matrix.
- 2 - Multiply a matrix by a constant.
- 3 - Multiply a matrix by a vector.
- 4 - Multiply a matrix by a matrix.
- 5 - Add a constant value to all elements of a matrix.
-
- After the last step, matrix A is back to original contents.
-*/
-ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
- ee_u16 crc=0;
- MATDAT clipval=matrix_big(val);
-
- matrix_add_const(N,A,val); /* make sure data changes */
-#if CORE_DEBUG
- printmat(A,N,"matrix_add_const");
-#endif
- matrix_mul_const(N,C,A,val);
- crc=crc16(matrix_sum(N,C,clipval),crc);
-#if CORE_DEBUG
- printmatC(C,N,"matrix_mul_const");
-#endif
- matrix_mul_vect(N,C,A,B);
- crc=crc16(matrix_sum(N,C,clipval),crc);
-#if CORE_DEBUG
- printmatC(C,N,"matrix_mul_vect");
-#endif
- matrix_mul_matrix(N,C,A,B);
- crc=crc16(matrix_sum(N,C,clipval),crc);
-#if CORE_DEBUG
- printmatC(C,N,"matrix_mul_matrix");
-#endif
- matrix_mul_matrix_bitextract(N,C,A,B);
- crc=crc16(matrix_sum(N,C,clipval),crc);
-#if CORE_DEBUG
- printmatC(C,N,"matrix_mul_matrix_bitextract");
-#endif
-
- matrix_add_const(N,A,-val); /* return matrix to initial value */
- return crc;
-}
-
-/* Function : matrix_init
- Initialize the memory block for matrix benchmarking.
-
- Parameters:
- blksize - Size of memory to be initialized.
- memblk - Pointer to memory block.
- seed - Actual values chosen depend on the seed parameter.
- p - pointers to <mat_params> containing initialized matrixes.
-
- Returns:
- Matrix dimensions.
-
- Note:
- The seed parameter MUST be supplied from a source that cannot be determined at compile time
-*/
-ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
- ee_u32 N=0;
- MATDAT *A;
- MATDAT *B;
- ee_s32 order=1;
- MATDAT val;
- ee_u32 i=0,j=0;
- if (seed==0)
- seed=1;
- while (j<blksize) {
- i++;
- j=i*i*2*4;
- }
- N=i-1;
- A=(MATDAT *)align_mem(memblk);
- B=A+N*N;
-
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- seed = ( ( order * seed ) % 65536 );
- val = (seed + order);
- val=matrix_clip(val,0);
- B[i*N+j] = val;
- val = (val + order);
- val=matrix_clip(val,1);
- A[i*N+j] = val;
- order++;
- }
- }
-
- p->A=A;
- p->B=B;
- p->C=(MATRES *)align_mem(B+N*N);
- p->N=N;
-#if CORE_DEBUG
- printmat(A,N,"A");
- printmat(B,N,"B");
-#endif
- return N;
-}
-
-/* Function: matrix_sum
- Calculate a function that depends on the values of elements in the matrix.
-
- For each element, accumulate into a temporary variable.
-
- As long as this value is under the parameter clipval,
- add 1 to the result if the element is bigger then the previous.
-
- Otherwise, reset the accumulator and add 10 to the result.
-*/
-ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
- MATRES tmp=0,prev=0,cur=0;
- ee_s16 ret=0;
- ee_u32 i,j;
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- cur=C[i*N+j];
- tmp+=cur;
- if (tmp>clipval) {
- ret+=10;
- tmp=0;
- } else {
- ret += (cur>prev) ? 1 : 0;
- }
- prev=cur;
- }
- }
- return ret;
-}
-
-/* Function: matrix_mul_const
- Multiply a matrix by a constant.
- This could be used as a scaler for instance.
-*/
-void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
- ee_u32 i,j;
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
- }
- }
-}
-
-/* Function: matrix_add_const
- Add a constant value to all elements of a matrix.
-*/
-void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
- ee_u32 i,j;
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- A[i*N+j] += val;
- }
- }
-}
-
-/* Function: matrix_mul_vect
- Multiply a matrix by a vector.
- This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
-*/
-void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
- ee_u32 i,j;
- for (i=0; i<N; i++) {
- C[i]=0;
- for (j=0; j<N; j++) {
- C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
- }
- }
-}
-
-/* Function: matrix_mul_matrix
- Multiply a matrix by a matrix.
- Basic code is used in many algorithms, mostly with minor changes such as scaling.
-*/
-void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
- ee_u32 i,j,k;
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- C[i*N+j]=0;
- for(k=0;k<N;k++)
- {
- C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
- }
- }
- }
-}
-
-/* Function: matrix_mul_matrix_bitextract
- Multiply a matrix by a matrix, and extract some bits from the result.
- Basic code is used in many algorithms, mostly with minor changes such as scaling.
-*/
-void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
- ee_u32 i,j,k;
- for (i=0; i<N; i++) {
- for (j=0; j<N; j++) {
- C[i*N+j]=0;
- for(k=0;k<N;k++)
- {
- MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
- C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
- }
- }
- }
-}
diff --git a/apps/coremark/src/core_state.c b/apps/coremark/src/core_state.c
deleted file mode 100644
index 8b4e4b5..0000000
--- a/apps/coremark/src/core_state.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-#include "coremark.h"
-/* local functions */
-enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
-
-/*
-Topic: Description
- Simple state machines like this one are used in many embedded products.
-
- For more complex state machines, sometimes a state transition table implementation is used instead,
- trading speed of direct coding for ease of maintenance.
-
- Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
- we are using a small moore machine.
-
- In particular, this machine tests type of string input,
- trying to determine whether the input is a number or something else.
- (see core_state.png).
-*/
-
-/* Function: core_bench_state
- Benchmark function
-
- Go over the input twice, once direct, and once after introducing some corruption.
-*/
-ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
- ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
-{
- ee_u32 final_counts[NUM_CORE_STATES];
- ee_u32 track_counts[NUM_CORE_STATES];
- ee_u8 *p=memblock;
- ee_u32 i;
-
-
-#if CORE_DEBUG
- ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
-#endif
- for (i=0; i<NUM_CORE_STATES; i++) {
- final_counts[i]=track_counts[i]=0;
- }
- /* run the state machine over the input */
- while (*p!=0) {
- enum CORE_STATE fstate=core_state_transition(&p,track_counts);
- final_counts[fstate]++;
-#if CORE_DEBUG
- ee_printf("%d,",fstate);
- }
- ee_printf("\n");
-#else
- }
-#endif
- p=memblock;
- while (p < (memblock+blksize)) { /* insert some corruption */
- if (*p!=',')
- *p^=(ee_u8)seed1;
- p+=step;
- }
- p=memblock;
- /* run the state machine over the input again */
- while (*p!=0) {
- enum CORE_STATE fstate=core_state_transition(&p,track_counts);
- final_counts[fstate]++;
-#if CORE_DEBUG
- ee_printf("%d,",fstate);
- }
- ee_printf("\n");
-#else
- }
-#endif
- p=memblock;
- while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
- if (*p!=',')
- *p^=(ee_u8)seed2;
- p+=step;
- }
- /* end timing */
- for (i=0; i<NUM_CORE_STATES; i++) {
- crc=crcu32(final_counts[i],crc);
- crc=crcu32(track_counts[i],crc);
- }
- return crc;
-}
-
-/* Default initialization patterns */
-static ee_u8 *intpat[4] ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
-static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
-static ee_u8 *scipat[4] ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
-static ee_u8 *errpat[4] ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
-
-/* Function: core_init_state
- Initialize the input data for the state machine.
-
- Populate the input with several predetermined strings, interspersed.
- Actual patterns chosen depend on the seed parameter.
-
- Note:
- The seed parameter MUST be supplied from a source that cannot be determined at compile time
-*/
-void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
- ee_u32 total=0,next=0,i;
- ee_u8 *buf=0;
-#if CORE_DEBUG
- ee_u8 *start=p;
- ee_printf("State: %d,%d\n",size,seed);
-#endif
- size--;
- next=0;
- while ((total+next+1)<size) {
- if (next>0) {
- for(i=0;i<next;i++)
- *(p+total+i)=buf[i];
- *(p+total+i)=',';
- total+=next+1;
- }
- seed++;
- switch (seed & 0x7) {
- case 0: /* int */
- case 1: /* int */
- case 2: /* int */
- buf=intpat[(seed>>3) & 0x3];
- next=4;
- break;
- case 3: /* float */
- case 4: /* float */
- buf=floatpat[(seed>>3) & 0x3];
- next=8;
- break;
- case 5: /* scientific */
- case 6: /* scientific */
- buf=scipat[(seed>>3) & 0x3];
- next=8;
- break;
- case 7: /* invalid */
- buf=errpat[(seed>>3) & 0x3];
- next=8;
- break;
- default: /* Never happen, just to make some compilers happy */
- break;
- }
- }
- size++;
- while (total<size) { /* fill the rest with 0 */
- *(p+total)=0;
- total++;
- }
-#if CORE_DEBUG
- ee_printf("State Input: %s\n",start);
-#endif
-}
-
-static ee_u8 ee_isdigit(ee_u8 c) {
- ee_u8 retval;
- retval = ((c>='0') & (c<='9')) ? 1 : 0;
- return retval;
-}
-
-/* Function: core_state_transition
- Actual state machine.
-
- The state machine will continue scanning until either:
- 1 - an invalid input is detcted.
- 2 - a valid number has been detected.
-
- The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid).
-*/
-
-enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
- ee_u8 *str=*instr;
- ee_u8 NEXT_SYMBOL;
- enum CORE_STATE state=CORE_START;
- for( ; *str && state != CORE_INVALID; str++ ) {
- NEXT_SYMBOL = *str;
- if (NEXT_SYMBOL==',') /* end of this input */ {
- str++;
- break;
- }
- switch(state) {
- case CORE_START:
- if(ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_INT;
- }
- else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
- state = CORE_S1;
- }
- else if( NEXT_SYMBOL == '.' ) {
- state = CORE_FLOAT;
- }
- else {
- state = CORE_INVALID;
- transition_count[CORE_INVALID]++;
- }
- transition_count[CORE_START]++;
- break;
- case CORE_S1:
- if(ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_INT;
- transition_count[CORE_S1]++;
- }
- else if( NEXT_SYMBOL == '.' ) {
- state = CORE_FLOAT;
- transition_count[CORE_S1]++;
- }
- else {
- state = CORE_INVALID;
- transition_count[CORE_S1]++;
- }
- break;
- case CORE_INT:
- if( NEXT_SYMBOL == '.' ) {
- state = CORE_FLOAT;
- transition_count[CORE_INT]++;
- }
- else if(!ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_INVALID;
- transition_count[CORE_INT]++;
- }
- break;
- case CORE_FLOAT:
- if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
- state = CORE_S2;
- transition_count[CORE_FLOAT]++;
- }
- else if(!ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_INVALID;
- transition_count[CORE_FLOAT]++;
- }
- break;
- case CORE_S2:
- if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
- state = CORE_EXPONENT;
- transition_count[CORE_S2]++;
- }
- else {
- state = CORE_INVALID;
- transition_count[CORE_S2]++;
- }
- break;
- case CORE_EXPONENT:
- if(ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_SCIENTIFIC;
- transition_count[CORE_EXPONENT]++;
- }
- else {
- state = CORE_INVALID;
- transition_count[CORE_EXPONENT]++;
- }
- break;
- case CORE_SCIENTIFIC:
- if(!ee_isdigit(NEXT_SYMBOL)) {
- state = CORE_INVALID;
- transition_count[CORE_INVALID]++;
- }
- break;
- default:
- break;
- }
- }
- *instr=str;
- return state;
-}
diff --git a/apps/coremark/src/core_util.c b/apps/coremark/src/core_util.c
deleted file mode 100644
index 5c2a4de..0000000
--- a/apps/coremark/src/core_util.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
-Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-
-Original Author: Shay Gal-on
-*/
-
-#include "coremark.h"
-/* Function: get_seed
- Get a values that cannot be determined at compile time.
-
- Since different embedded systems and compilers are used, 3 different methods are provided:
- 1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that
- reads the value of a volatile variable from memory at run time.
- Please note, if using this method, you would need to modify core_portme.c to generate training profile.
- 2 - Command line arguments. This is the preferred method if command line arguments are supported.
- 3 - System function. If none of the first 2 methods is available on the platform,
- a system function which is not a stub can be used.
-
- e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions.
-*/
-#if (SEED_METHOD==SEED_VOLATILE)
- extern volatile ee_s32 seed1_volatile;
- extern volatile ee_s32 seed2_volatile;
- extern volatile ee_s32 seed3_volatile;
- extern volatile ee_s32 seed4_volatile;
- extern volatile ee_s32 seed5_volatile;
- ee_s32 get_seed_32(int i) {
- ee_s32 retval;
- switch (i) {
- case 1:
- retval=seed1_volatile;
- break;
- case 2:
- retval=seed2_volatile;
- break;
- case 3:
- retval=seed3_volatile;
- break;
- case 4:
- retval=seed4_volatile;
- break;
- case 5:
- retval=seed5_volatile;
- break;
- default:
- retval=0;
- break;
- }
- return retval;
- }
-#elif (SEED_METHOD==SEED_ARG)
-ee_s32 parseval(char *valstring) {
- ee_s32 retval=0;
- ee_s32 neg=1;
- int hexmode=0;
- if (*valstring == '-') {
- neg=-1;
- valstring++;
- }
- if ((valstring[0] == '0') && (valstring[1] == 'x')) {
- hexmode=1;
- valstring+=2;
- }
- /* first look for digits */
- if (hexmode) {
- while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) {
- ee_s32 digit=*valstring-'0';
- if (digit>9)
- digit=10+*valstring-'a';
- retval*=16;
- retval+=digit;
- valstring++;
- }
- } else {
- while ((*valstring >= '0') && (*valstring <= '9')) {
- ee_s32 digit=*valstring-'0';
- retval*=10;
- retval+=digit;
- valstring++;
- }
- }
- /* now add qualifiers */
- if (*valstring=='K')
- retval*=1024;
- if (*valstring=='M')
- retval*=1024*1024;
-
- retval*=neg;
- return retval;
-}
-
-ee_s32 get_seed_args(int i, int argc, char *argv[]) {
- if (argc>i)
- return parseval(argv[i]);
- return 0;
-}
-
-#elif (SEED_METHOD==SEED_FUNC)
-/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */
-ee_s32 get_seed_32(int i) {
- ee_s32 retval;
- switch (i) {
- case 1:
- retval=portme_sys1();
- break;
- case 2:
- retval=portme_sys2();
- break;
- case 3:
- retval=portme_sys3();
- break;
- case 4:
- retval=portme_sys4();
- break;
- case 5:
- retval=portme_sys5();
- break;
- default:
- retval=0;
- break;
- }
- return retval;
-}
-#endif
-
-/* Function: crc*
- Service functions to calculate 16b CRC code.
-
-*/
-ee_u16 crcu8(ee_u8 data, ee_u16 crc )
-{
- ee_u8 i=0,x16=0,carry=0;
-
- for (i = 0; i < 8; i++)
- {
- x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1));
- data >>= 1;
-
- if (x16 == 1)
- {
- crc ^= 0x4002;
- carry = 1;
- }
- else
- carry = 0;
- crc >>= 1;
- if (carry)
- crc |= 0x8000;
- else
- crc &= 0x7fff;
- }
- return crc;
-}
-ee_u16 crcu16(ee_u16 newval, ee_u16 crc) {
- crc=crcu8( (ee_u8) (newval) ,crc);
- crc=crcu8( (ee_u8) ((newval)>>8) ,crc);
- return crc;
-}
-ee_u16 crcu32(ee_u32 newval, ee_u16 crc) {
- crc=crc16((ee_s16) newval ,crc);
- crc=crc16((ee_s16) (newval>>16) ,crc);
- return crc;
-}
-ee_u16 crc16(ee_s16 newval, ee_u16 crc) {
- return crcu16((ee_u16)newval, crc);
-}
-
-ee_u8 check_data_types() {
- ee_u8 retval=0;
- if (sizeof(ee_u8) != 1) {
- ee_printf("ERROR: ee_u8 is not an 8b datatype!\n");
- retval++;
- }
- if (sizeof(ee_u16) != 2) {
- ee_printf("ERROR: ee_u16 is not a 16b datatype!\n");
- retval++;
- }
- if (sizeof(ee_s16) != 2) {
- ee_printf("ERROR: ee_s16 is not a 16b datatype!\n");
- retval++;
- }
- if (sizeof(ee_s32) != 4) {
- ee_printf("ERROR: ee_s32 is not a 32b datatype!\n");
- retval++;
- }
- if (sizeof(ee_u32) != 4) {
- ee_printf("ERROR: ee_u32 is not a 32b datatype!\n");
- retval++;
- }
- if (sizeof(ee_ptr_int) != sizeof(int *)) {
- ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n");
- retval++;
- }
- if (retval>0) {
- ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n");
- }
- return retval;
-}
diff --git a/apps/coremark/src/main.c b/apps/coremark/src/main.c
new file mode 100644
index 0000000..8eed66d
--- /dev/null
+++ b/apps/coremark/src/main.c
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include "console/console.h"
+#include "coremark/coremark_api.h"
+
+extern uint32_t SystemCoreClock;
+
+int
+mynewt_main(int argc, char **argv)
+{
+ sysinit();
+
+ printf("Coremark running on %s at %lu MHz\n\n", MYNEWT_VAL(BSP_NAME), SystemCoreClock / 1000000L);
+
+ coremark_run();
+
+ while (1) {
+ os_eventq_run(os_eventq_dflt_get());
+ }
+}
diff --git a/apps/coremark/syscfg.yml b/apps/coremark/syscfg.yml
index 0a9983d..630e671 100644
--- a/apps/coremark/syscfg.yml
+++ b/apps/coremark/syscfg.yml
@@ -16,15 +16,11 @@
# under the License.
#
-syscfg.defs:
- COREMARK_ITERATIONS:
- description: Number of iterations to run
- value: 0
-
syscfg.vals:
CONSOLE_IMPLEMENTATION: full
LOG_IMPLEMENTATION: stub
STATS_IMPLEMENTATION: stub
+ COREMARK_SHELL: 0
syscfg.vals.HARDFLOAT:
FLOAT_USER: 1
diff --git a/util/coremark/include/coremark/coremark_api.h b/util/coremark/include/coremark/coremark_api.h
new file mode 100644
index 0000000..bdd324e
--- /dev/null
+++ b/util/coremark/include/coremark/coremark_api.h
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef _COREMARK_API_H_
+#define _COREMARK_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void coremark_run(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _COREMARK_API_H_ */
diff --git a/util/coremark/pkg.yml b/util/coremark/pkg.yml
new file mode 100644
index 0000000..fc9e802
--- /dev/null
+++ b/util/coremark/pkg.yml
@@ -0,0 +1,43 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: util/coremark
+pkg.description: Industry-standard benchmark to measures the MCU performance.
+pkg.author: "EEMBC"
+pkg.homepage: "https://github.com/eembc/coremark"
+pkg.keywords:
+ - benchmark
+
+pkg.deps:
+ - "@apache-mynewt-core/kernel/os"
+ - "@apache-mynewt-core/hw/hal"
+ - "@apache-mynewt-core/sys/console"
+ - "@apache-mynewt-core/util/parse"
+ - "@apache-mynewt-core/util/coremark/repo"
+
+pkg.cflags:
+
+pkg.source_files:
+ - src/core_portme.c
+
+pkg.source_files.COREMARK_SHELL:
+ - src/coremark_shell.c
+
+pkg.init.COREMARK_SHELL:
+ coremark_shell_init_pkg: $after:shell_init
diff --git a/apps/coremark/include/core_portme.h b/util/coremark/repo/include/core_portme.h
similarity index 99%
rename from apps/coremark/include/core_portme.h
rename to util/coremark/repo/include/core_portme.h
index 7d57f73..4d0f038 100644
--- a/apps/coremark/include/core_portme.h
+++ b/util/coremark/repo/include/core_portme.h
@@ -151,7 +151,7 @@
This flag only matters if MULTITHREAD has been defined to a value greater then 1.
*/
#ifndef MAIN_HAS_NOARGC
-#define MAIN_HAS_NOARGC 0
+#define MAIN_HAS_NOARGC 1
#endif
/* Configuration : MAIN_HAS_NORETURN
diff --git a/util/coremark/repo/pkg.yml b/util/coremark/repo/pkg.yml
new file mode 100644
index 0000000..239d5f2
--- /dev/null
+++ b/util/coremark/repo/pkg.yml
@@ -0,0 +1,57 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: util/coremark/repo
+pkg.type: sdk
+pkg.description: Industry-standard benchmark to measures the MCU performance.
+pkg.author: "EEMBC"
+pkg.homepage: "https://github.com/eembc/coremark"
+pkg.keywords:
+ - benchmark
+
+pkg.deps:
+ - "@apache-mynewt-core/kernel/os"
+ - "@apache-mynewt-core/hw/hal"
+ - "@apache-mynewt-core/sys/stats"
+ - "@apache-mynewt-core/sys/log"
+ - "@apache-mynewt-core/sys/console"
+
+pkg.include_dirs:
+ - "@eembc-coremark/."
+
+pkg.source_files:
+ - "@eembc-coremark/core_list_join.c"
+ - "@eembc-coremark/core_main.c"
+ - "@eembc-coremark/core_matrix.c"
+ - "@eembc-coremark/core_state.c"
+ - "@eembc-coremark/core_util.c"
+
+pkg.cflags:
+ - -DFLAGS_STR=""
+ - -Wno-format
+ - -Wno-maybe-uninitialized
+
+pkg.build_profile: speed
+
+repository.eembc-coremark:
+ type: github
+ vers: v1.01-commit
+ branch: main
+ user: eembc
+ repo: coremark
diff --git a/apps/coremark/src/core_portme.c b/util/coremark/src/core_portme.c
similarity index 98%
rename from apps/coremark/src/core_portme.c
rename to util/coremark/src/core_portme.c
index d8b9181..43d6ffe 100644
--- a/apps/coremark/src/core_portme.c
+++ b/util/coremark/src/core_portme.c
@@ -130,3 +130,11 @@
{
p->portable_id=0;
}
+
+void
+coremark_run()
+{
+ int main();
+
+ main();
+}
diff --git a/util/coremark/src/coremark_shell.c b/util/coremark/src/coremark_shell.c
new file mode 100644
index 0000000..a736da8
--- /dev/null
+++ b/util/coremark/src/coremark_shell.c
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <os/mynewt.h>
+
+#include <shell/shell.h>
+#include <parse/parse.h>
+#include <stdio.h>
+#include <coremark/coremark_api.h>
+
+extern uint32_t SystemCoreClock;
+
+static int
+coremark_shell_cmd(int argc, char **argv)
+{
+ printf("Coremark running on %s at %lu MHz\n\n",
+ MYNEWT_VAL(BSP_NAME), SystemCoreClock / 1000000L);
+
+ coremark_run();
+
+ return 0;
+}
+
+static const struct shell_cmd_help coremark_help = {
+ .summary = "Run coremark benchmark",
+ .params = NULL,
+ .usage = NULL,
+};
+
+static const struct shell_cmd coremark_shell_cmd_struct = {
+ .sc_cmd = "coremark",
+ .sc_cmd_func = coremark_shell_cmd,
+ .help = &coremark_help,
+};
+
+void
+coremark_shell_init_pkg(void)
+{
+#if MYNEWT_VAL(SHELL_COMPAT)
+ int rc;
+ rc = shell_cmd_register(&coremark_shell_cmd_struct);
+ SYSINIT_PANIC_ASSERT(rc == 0);
+#endif
+}
diff --git a/util/coremark/syscfg.yml b/util/coremark/syscfg.yml
new file mode 100644
index 0000000..5917d87
--- /dev/null
+++ b/util/coremark/syscfg.yml
@@ -0,0 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+syscfg.defs:
+ COREMARK_ITERATIONS:
+ description: Number of iterations to run
+ value: 0
+
+ COREMARK_SHELL:
+ description:
+ If set to 1 adds coremark command to shell.
+ value: 1