aboutsummaryrefslogtreecommitdiffstats
path: root/opencores/aemb/sw/c
diff options
context:
space:
mode:
authorjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
committerjcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5>2008-09-08 01:00:12 +0000
commit61f2f0214c5999ea42a368a4fc99f03d8eb28d1e (patch)
treee7e24a9adc05ff1422fe3ada9926a51634741b47 /opencores/aemb/sw/c
downloaduhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.gz
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.tar.bz2
uhd-61f2f0214c5999ea42a368a4fc99f03d8eb28d1e.zip
Merged r9433:9527 from features/gr-usrp2 into trunk. Adds usrp2 and gr-usrp2 top-level components. Trunk passes distcheck with mb-gcc installed, but currently not without them. The key issue is that when mb-gcc is not installed, the build system skips over the usrp2/firmware directory, and the firmware include files don't get put into the dist tarball. But we can't do the usual DIST_SUBDIRS method as the firmware is a subpackage.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@9528 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'opencores/aemb/sw/c')
-rw-r--r--opencores/aemb/sw/c/CVS/Entries3
-rw-r--r--opencores/aemb/sw/c/CVS/Repository1
-rw-r--r--opencores/aemb/sw/c/CVS/Root1
-rw-r--r--opencores/aemb/sw/c/CVS/Template0
-rw-r--r--opencores/aemb/sw/c/aeMB_testbench.c385
-rw-r--r--opencores/aemb/sw/c/endian-test.c86
-rw-r--r--opencores/aemb/sw/c/libaemb.h218
7 files changed, 694 insertions, 0 deletions
diff --git a/opencores/aemb/sw/c/CVS/Entries b/opencores/aemb/sw/c/CVS/Entries
new file mode 100644
index 000000000..4867b6318
--- /dev/null
+++ b/opencores/aemb/sw/c/CVS/Entries
@@ -0,0 +1,3 @@
+/aeMB_testbench.c/1.14/Tue Jan 15 18:38:57 2008//
+/libaemb.h/1.3/Tue Jan 15 18:38:57 2008//
+D
diff --git a/opencores/aemb/sw/c/CVS/Repository b/opencores/aemb/sw/c/CVS/Repository
new file mode 100644
index 000000000..86c411d03
--- /dev/null
+++ b/opencores/aemb/sw/c/CVS/Repository
@@ -0,0 +1 @@
+aemb/sw/c
diff --git a/opencores/aemb/sw/c/CVS/Root b/opencores/aemb/sw/c/CVS/Root
new file mode 100644
index 000000000..44b2aa23b
--- /dev/null
+++ b/opencores/aemb/sw/c/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.opencores.org:/cvsroot/anonymous
diff --git a/opencores/aemb/sw/c/CVS/Template b/opencores/aemb/sw/c/CVS/Template
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/opencores/aemb/sw/c/CVS/Template
diff --git a/opencores/aemb/sw/c/aeMB_testbench.c b/opencores/aemb/sw/c/aeMB_testbench.c
new file mode 100644
index 000000000..c3402e0ef
--- /dev/null
+++ b/opencores/aemb/sw/c/aeMB_testbench.c
@@ -0,0 +1,385 @@
+/* $Id: aeMB_testbench.c,v 1.14 2007/12/28 21:44:04 sybreon Exp $
+**
+** AEMB Function Verification C Testbench
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
+**
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+** License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with AEMB. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <malloc.h>
+#include <errno.h>
+#include <reent.h>
+
+#include "libaemb.h"
+
+/**
+ INTERRUPT TEST
+
+ This tests for the following:
+ - Pointer addressing
+ - Interrupt handling
+ */
+
+void __attribute__ ((interrupt_handler)) int_handler();
+volatile int service = 0xDEADDEAD;
+
+void int_service()
+{
+ int* pio = (int*)0xFFFFFFFC;
+ *pio = 0x52544E49; // "INTR"
+ service = 0;
+}
+
+void int_handler()
+{
+ int_service();
+}
+
+/**
+ INTERRUPT TEST ROUTINE
+*/
+int int_test ()
+{
+ // Delay loop until hardware interrupt triggers
+ volatile int i;
+ for (i=0; i < 999; i++) {
+ if (service == 0) return 0;
+ };
+
+ return -1;
+}
+
+/**
+ FIBONACCI TEST
+ http://en.literateprograms.org/Fibonacci_numbers_(C)
+
+ This tests for the following:
+ - Recursion & Iteration
+ - 32/16/8-bit data handling
+*/
+
+unsigned int fib_slow(unsigned int n)
+{
+ return n < 2 ? n : fib_slow(n-1) + fib_slow(n-2);
+}
+
+unsigned int fib_fast(unsigned int n)
+{
+ unsigned int a[3];
+ unsigned int *p=a;
+ unsigned int i;
+
+ for(i=0; i<=n; ++i) {
+ if(i<2) *p=i;
+ else {
+ if(p==a) *p=*(a+1)+*(a+2);
+ else if(p==a+1) *p=*a+*(a+2);
+ else *p=*a+*(a+1);
+ }
+ if(++p>a+2) p=a;
+ }
+
+ return p==a?*(p+2):*(p-1);
+}
+
+int fib_test(int max) {
+ unsigned int n;
+ unsigned int fast, slow;
+ // 32-bit LUT
+ unsigned int fib_lut32[] = {
+ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
+ };
+ // 16-bit LUT
+ unsigned short fib_lut16[] = {
+ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
+ };
+ // 8-bit LUT
+ unsigned char fib_lut8[] = {
+ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233
+ };
+
+ for (n=0;n<max;n++) {
+ slow = fib_slow(n);
+ fast = fib_fast(n);
+ if ((slow != fast) ||
+ (fast != fib_lut32[n]) ||
+ (fast != fib_lut16[n]) ||
+ (fast != fib_lut8[n])) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ EUCLIDEAN TEST
+ http://en.literateprograms.org/Euclidean_algorithm_(C)
+
+ This tests for the following:
+ - Modulo arithmetic
+ - Goto
+*/
+
+int euclid_gcd(int a, int b) {
+ if (b > a) goto b_larger;
+ while (1) {
+ a = a % b;
+ if (a == 0) return b;
+ b_larger:
+ b = b % a;
+ if (b == 0) return a;
+ }
+}
+
+int euclid_test(int max)
+{
+ int n;
+ int euclid;
+ // Random Numbers
+ int euclid_a[] = {
+ 1804289383, 1681692777, 1957747793, 719885386, 596516649,
+ 1025202362, 783368690, 2044897763, 1365180540, 304089172,
+ 35005211, 294702567, 336465782, 278722862
+ };
+ int euclid_b[] = {
+ 846930886, 1714636915, 424238335, 1649760492, 1189641421,
+ 1350490027, 1102520059, 1967513926, 1540383426, 1303455736,
+ 521595368, 1726956429, 861021530, 233665123
+ };
+
+ // GCD
+ int euclid_lut[] = {
+ 1, 1, 1, 2, 1, 1, 1, 1, 6, 4, 1, 3, 2, 1
+ };
+
+ for (n=0;n<max;n++) {
+ euclid = euclid_gcd(euclid_a[n],euclid_b[n]);
+ if (euclid != euclid_lut[n]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+/**
+ NEWTON-RHAPSON
+ http://en.literateprograms.org/Newton-Raphson's_method_for_root_finding_(C)
+
+ This tests for the following:
+ - Multiplication & Division
+ - Floating point arithmetic
+ - Integer to Float conversion
+*/
+
+float newton_sqrt(float n)
+{
+ float x = 0.0;
+ float xn = 0.0;
+ int iters = 0;
+ int i;
+ for (i = 0; i <= (int)n; ++i)
+ {
+ float val = i*i-n;
+ if (val == 0.0)
+ return i;
+ if (val > 0.0)
+ {
+ xn = (i+(i-1))/2.0;
+ break;
+ }
+ }
+ while (!(iters++ >= 100
+ || x == xn))
+ {
+ x = xn;
+ xn = x - (x * x - n) / (2 * x);
+ }
+ return xn;
+}
+
+int newton_test (int max) {
+ int n;
+ float newt;
+ // 32-bit LUT
+ float newt_lut[] = {
+ 0.000000000000000000000000,
+ 1.000000000000000000000000,
+ 1.414213538169860839843750,
+ 1.732050776481628417968750,
+ 2.000000000000000000000000,
+ 2.236068010330200195312500,
+ 2.449489831924438476562500,
+ 2.645751237869262695312500,
+ 2.828427076339721679687500,
+ 3.000000000000000000000000,
+ 3.162277698516845703125000,
+ 3.316624879837036132812500,
+ 3.464101552963256835937500,
+ 3.605551242828369140625000,
+ 3.741657495498657226562500
+ };
+
+ for (n=0;n<max;n++) {
+ newt = newton_sqrt(n);
+ if (newt != newt_lut[n]) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+/**
+ FSL TEST ROUTINE
+*/
+
+int fsl_test ()
+{
+ // TEST FSL1 ONLY
+ int FSL = 0xCAFEF00D;
+
+ asm ("PUT %0, RFSL1" :: "r"(FSL));
+ asm ("GET %0, RFSL1" : "=r"(FSL));
+
+ if (FSL != 0x01) return -1;
+
+ asm ("PUT %0, RFSL31" :: "r"(FSL));
+ asm ("GET %0, RFSL31" : "=r"(FSL));
+
+ if (FSL != 0x1F) return -1;
+
+ return 0;
+}
+
+// static int errnum;
+/*
+int *__errno ()
+{
+ return &_REENT->_errno;
+ // return &errnum;
+}
+*/
+
+int malloc_test()
+{
+ void *alloc;
+
+ alloc = (void *)malloc(256); // allocate 32 bytes
+
+ if (alloc == NULL)
+ return -1;
+ else
+ return (int) alloc;
+}
+
+/**
+ MAIN TEST PROGRAMME
+
+ This is the main test procedure. It will output signals onto the
+ MPI port that is checked by the testbench.
+ */
+
+int main ()
+{
+ // Message Passing Port
+ int* mpi = (int*)0xFFFFFFFF;
+
+ // Number of each test to run
+ int max = 10;
+
+ // lock T0 if it's multi-threaded
+ /*
+ if ((aemb_isthreaded() == 0) && (aemb_isthread1() != 0)) {
+ while (1) {
+ asm volatile ("nop;");
+ }
+ }
+ */
+
+ // Enable Global Interrupts
+ aemb_enable_interrupt();
+
+ // INT TEST
+ //if (int_test() == -1) { *mpi = 0x4641494C; }
+
+ // TEST MALLOC
+ if (malloc_test() == -1) { *mpi = 0x4641494C; }
+
+ // FSL TEST
+ //if (fsl_test() == -1) { *mpi = 0x4641494C; }
+
+ // Fibonacci Test
+ if (fib_test(max) == -1) { *mpi = 0x4641494C; }
+
+ // Euclid Test
+ if (euclid_test(max) == -1) { *mpi = 0x4641494C; }
+
+ // Newton-Rhapson Test
+ if (newton_test(max) == -1) { *mpi = 0x4641494C; }
+
+ // Disable Global Interrupts
+ aemb_disable_interrupt();
+
+ // ALL PASSED
+ return 0;
+}
+
+/*
+ HISTORY
+ $Log: aeMB_testbench.c,v $
+ Revision 1.14 2007/12/28 21:44:04 sybreon
+ Added malloc() test
+
+ Revision 1.13 2007/12/11 00:44:31 sybreon
+ Modified for AEMB2
+
+ Revision 1.12 2007/11/18 19:41:45 sybreon
+ Minor simulation fixes.
+
+ Revision 1.11 2007/11/14 23:41:06 sybreon
+ Fixed minor interrupt test typo.
+
+ Revision 1.10 2007/11/14 22:12:02 sybreon
+ Added interrupt test routine.
+
+ Revision 1.9 2007/11/09 20:51:53 sybreon
+ Added GET/PUT support through a FSL bus.
+
+ Revision 1.8 2007/11/03 08:40:18 sybreon
+ Minor code cleanup.
+
+ Revision 1.7 2007/11/02 18:32:19 sybreon
+ Enable MSR_IE with software.
+
+ Revision 1.6 2007/04/30 15:57:10 sybreon
+ Removed byte acrobatics.
+
+ Revision 1.5 2007/04/27 15:17:59 sybreon
+ Added code documentation.
+ Added new tests that test floating point, modulo arithmetic and multiplication/division.
+
+ Revision 1.4 2007/04/25 22:15:05 sybreon
+ Added support for 8-bit and 16-bit data types.
+
+ Revision 1.3 2007/04/04 14:09:04 sybreon
+ Added initial interrupt/exception support.
+
+ Revision 1.2 2007/04/04 06:07:45 sybreon
+ Fixed C code bug which passes the test
+
+ Revision 1.1 2007/03/09 17:41:57 sybreon
+ initial import
+*/
diff --git a/opencores/aemb/sw/c/endian-test.c b/opencores/aemb/sw/c/endian-test.c
new file mode 100644
index 000000000..b585f7a30
--- /dev/null
+++ b/opencores/aemb/sw/c/endian-test.c
@@ -0,0 +1,86 @@
+
+#include "memory_map.h"
+
+int main() {
+ char *p = (char *)0x4000;
+ short *q = (short *)0x5000;
+ int *r= (int *)0x6000;
+
+ int *output = (int *)0x7000;
+
+ char s;
+ short t;
+ int u;
+
+ // Write
+ // Bytes
+ *p = (char)1;
+ p++;
+ *p = (char)2;
+ p++;
+ *p = (char)3;
+ p++;
+ *p = (char)4;
+ p++;
+ *p = (char)5;
+
+ // Words
+ *q = (short) 0x1112;
+ q++;
+ *q = (short) 0x1314;
+ q++;
+ *q = (short) 0x1516;
+
+ // Double Words
+ *r = 0x21222324;
+ r++;
+ *r = 0x25262728;
+ r++;
+ *r = 0x292a2b2c;
+
+
+ // Read
+ p = (char *)0x6000;
+ s = *p;
+ if(s == 0x21)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+ p = (char *)0x6001;
+ s = *p;
+ if(s == 0x22)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+ p = (char *)0x6002;
+ s = *p;
+ if(s == 0x23)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+
+ p = (char *)0x6003;
+ s = *p;
+ if(s == 0x24)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+ q = (short *)0x4000;
+ t = *q;
+ if(t == 0x0102)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+ r = (int *)0x4000;
+ u = *r;
+ if(u == 0x01020304)
+ *output = 0x53534150; // PASS
+ else
+ *output = 0x4C494146; // FAIL
+
+}
diff --git a/opencores/aemb/sw/c/libaemb.h b/opencores/aemb/sw/c/libaemb.h
new file mode 100644
index 000000000..329a327a1
--- /dev/null
+++ b/opencores/aemb/sw/c/libaemb.h
@@ -0,0 +1,218 @@
+/* $Id: libaemb.h,v 1.3 2007/12/16 03:26:37 sybreon Exp $
+**
+** AEMB2 CUSTOM LIBRARY
+**
+** Copyright (C) 2004-2007 Shawn Tan Ser Ngiap <shawn.tan@aeste.net>
+**
+** This file is part of AEMB.
+**
+** AEMB is free software: you can redistribute it and/or modify it
+** under the terms of the GNU Lesser General Public License as
+** published by the Free Software Foundation, either version 3 of the
+** License, or (at your option) any later version.
+**
+** AEMB is distributed in the hope that it will be useful, but WITHOUT
+** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
+** Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public
+** License along with AEMB. If not, see <http:**www.gnu.org/licenses/>.
+*/
+
+#ifndef LIBAEMB_H
+#define LIBAEMB_H
+
+#define AEMB_TXE 0x0100
+#define AEMB_TXP 0x0400
+#define AEMB_TX0 0x0300
+#define AEMB_TX1 0x0700
+#define AEMB_MSK 0x0F00
+
+#define AEMB_BIP 0x0008
+#define AEMB_CCC 0x0004
+#define AEMB_ITE 0x0002
+#define AEMB_BLE 0x0001
+
+
+// Linker symbols
+extern void* _STACK_SIZE;
+extern void* _stack_end;
+
+
+void aemb_hook_init () asm ("_program_init");
+void aemb_hook_clean () asm ("_program_clean");
+
+inline void aemb_enable_interrupt ();
+inline void aemb_disable_interrupt ();
+inline int aemb_isthread1();
+inline int aemb_isthread0();
+inline int aemb_isthreaded();
+
+/*!
+* Assembly macro to enable MSR_IE
+*/
+void aemb_enable_interrupt ()
+{
+ int msr, tmp;
+ asm volatile ("mfs %0, rmsr;"
+ "ori %1, %0, 0x02;"
+ "mts rmsr, %1;"
+ : "=r"(msr)
+ : "r" (tmp)
+ );
+}
+
+/*!
+* Assembly macro to disable MSR_IE
+*/
+void aemb_disable_interrupt ()
+{
+ int msr, tmp;
+ asm volatile ("mfs %0, rmsr;"
+ "andi %1, %0, 0xFD;"
+ "mts rmsr, %1;"
+ : "=r"(msr)
+ : "r" (tmp)
+ );
+}
+
+/*!
+* Bootstrap Hook Override
+*/
+
+void aemb_hook_init ()
+{
+ int msr, tmp;
+ int stk_end, stk_siz;
+
+ /*
+ // Check to see if hardware threads are enabled
+ if (((msr & AEMB_TXE) != AEMB_TXE) ||
+ // Check to see if second thread is started
+ ((msr & AEMB_TX1) == AEMB_TX1)) return;
+ */
+ //return;
+ asm volatile ("mfs %0, rmsr;"
+ // Check for BIP
+ "andi %1, %0, %5;"
+ "xori %1, %1, %5;"
+ "beqi %1, 44;"
+
+ // Check for TXE
+ "andi %1, %0, %2;"
+ "xori %1, %1, %2;"
+ "bnei %1, 36;"
+
+ // Check for TX1
+ "andi %1, %0, %3;"
+ "xori %1, %1, %3;"
+ "beqi %1, 20;"
+
+ // reallocate stack pointer for T0
+ "ori %1, r0, %4;"
+ "sra %1, %1;"
+ "rsubk r1, %1, r1;"
+
+ // reboot the machine
+ //"brki r0, _crtinit;"
+ "brid 0;"
+ "nop;"
+
+ // clear BIP
+ "andni %1, %0, %5;"
+ "mts rmsr, %1;"
+
+ :"=r"(msr), "=r"(tmp)
+ :"i"(AEMB_TXE), "i"(AEMB_TX1), "i"(&_STACK_SIZE), "i"(AEMB_BIP)
+ );
+
+}
+
+/*!
+ Undo the changes made by programme init
+*/
+
+void aemb_hook_clean ()
+{
+ int msr, tmp;
+ int stk_end, stk_siz;
+
+ /*
+ // Check to see if hardware threads are enabled
+ if (((msr & AEMB_TXE) != AEMB_TXE) ||
+ // Check to see if second thread is started
+ ((msr & AEMB_TX1) == AEMB_TX1)) return;
+ */
+ return;
+ asm volatile ("mfs %0, rmsr;"
+ "andi %1, %0, %2;"
+ "xori %1, %1, %2;"
+ "bnei %1, 28;"
+ "andi %1, %0, %3;"
+ "xori %1, %1, %3;"
+ "beqi %1, 16;"
+
+ // reallocate stack pointer for T0
+ "ori %1, r0, %4;"
+ "sra %1, %1;"
+ "addk r1, %1, r1;"
+
+ :"=r"(msr), "=r"(tmp)
+ :"i"(AEMB_TXE), "i"(AEMB_TX1), "i"(&_STACK_SIZE)
+ );
+
+
+}
+
+/* Checks if it's T1, and returns 0 if true */
+
+int aemb_isthread1 ()
+{
+ int msr, tmp, res;
+ asm volatile ("mfs %0, rmsr;"
+ "andi %1, %0, %3;"
+ "xori %1, %1, %3;"
+ :"=r"(msr), "=r"(tmp)
+ :"i"(AEMB_TXE), "i"(AEMB_TXP)
+ );
+ return tmp;
+}
+
+/* Checks if it's T0, and returns 0 if true */
+
+int aemb_isthread0 ()
+{
+ int msr, tmp, res;
+ asm volatile ("mfs %0, rmsr;"
+ "andi %1, %0, %3;"
+ "xori %1, %1, %2;"
+ :"=r"(msr), "=r"(tmp)
+ :"i"(AEMB_TXP), "i"(AEMB_MSK)
+ );
+ return tmp;
+}
+
+/* Checks if TXE is available, and returns 0 if true */
+
+int aemb_isthreaded ()
+{
+ int msr, tmp, res;
+ asm volatile ("mfs %0, rmsr;"
+ "andi %1, %0, %2;"
+ "xori %1, %1, %2;"
+ :"=r"(msr), "=r"(tmp)
+ :"i"(AEMB_TXE), "i"(AEMB_MSK)
+ );
+ return tmp;
+}
+
+#endif
+
+/* $Log: libaemb.h,v $
+/* Revision 1.3 2007/12/16 03:26:37 sybreon
+/* Made T0 loop.
+/*
+/* Revision 1.1 2007/12/11 00:44:04 sybreon
+/* initial import
+/* */