initial "working" version

This should print something on the UART.

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
2019-01-01 22:10:02 +08:00
parent 049a52022c
commit c864db3eec
33 changed files with 417 additions and 2040 deletions

View File

@ -1,85 +0,0 @@
#include <uart.h>
#include <console.h>
#include <stdio.h>
#include <stdarg.h>
FILE *stdin, *stdout, *stderr;
static console_write_hook write_hook;
static console_read_hook read_hook;
static console_read_nonblock_hook read_nonblock_hook;
void console_set_write_hook(console_write_hook h)
{
write_hook = h;
}
void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
{
read_hook = r;
read_nonblock_hook = rn;
}
int putchar(int c)
{
uart_write(c);
if(write_hook != NULL)
write_hook(c);
return c;
}
char readchar(void)
{
while(1) {
if(uart_read_nonblock())
return uart_read();
if((read_nonblock_hook != NULL) && read_nonblock_hook())
return read_hook();
}
}
int readchar_nonblock(void)
{
return (uart_read_nonblock()
|| ((read_nonblock_hook != NULL) && read_nonblock_hook()));
}
int puts(const char *s)
{
while(*s) {
putchar(*s);
s++;
}
putchar('\n');
return 1;
}
void putsnonl(const char *s)
{
while(*s) {
putchar(*s);
s++;
}
}
#define PRINTF_BUFFER_SIZE 256
int vprintf(const char *fmt, va_list args)
{
int len;
char outbuf[PRINTF_BUFFER_SIZE];
len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
outbuf[len] = 0;
putsnonl(outbuf);
return len;
}
int printf(const char *fmt, ...)
{
int len;
va_list args;
va_start(args, fmt);
len = vprintf(fmt, args);
va_end(args);
return len;
}

View File

@ -83,7 +83,8 @@ unsigned int crc32(const unsigned char *buffer, unsigned int len)
}
#else
unsigned int crc32(const unsigned char *message, unsigned int len) {
int i, j;
int j;
unsigned int i;
unsigned int byte, crc, mask;
i = 0;

View File

@ -1,208 +0,0 @@
#include <string.h>
#include <errno.h>
int errno;
/************************************************************************
* Based on: lib/string/lib_strerror.c
*
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
************************************************************************/
struct errno_strmap_s
{
int errnum;
char *str;
};
/* This table maps all error numbers to descriptive strings.
* The only assumption that the code makes with regard to this
* this table is that it is order by error number.
*
* The size of this table is quite large. Its size can be
* reduced by eliminating some of the more obscure error
* strings.
*/
struct errno_strmap_s g_errnomap[] =
{
{ EPERM, EPERM_STR },
{ ENOENT, ENOENT_STR },
{ ESRCH, ESRCH_STR },
{ EINTR, EINTR_STR },
{ EIO, EIO_STR },
{ ENXIO, ENXIO_STR },
{ E2BIG, E2BIG_STR },
{ ENOEXEC, ENOEXEC_STR },
{ EBADF, EBADF_STR },
{ ECHILD, ECHILD_STR },
{ EAGAIN, EAGAIN_STR },
{ ENOMEM, ENOMEM_STR },
{ EACCES, EACCES_STR },
{ EFAULT, EFAULT_STR },
{ ENOTBLK, ENOTBLK_STR },
{ EBUSY, EBUSY_STR },
{ EEXIST, EEXIST_STR },
{ EXDEV, EXDEV_STR },
{ ENODEV, ENODEV_STR },
{ ENOTDIR, ENOTDIR_STR },
{ EISDIR, EISDIR_STR },
{ EINVAL, EINVAL_STR },
{ ENFILE, ENFILE_STR },
{ EMFILE, EMFILE_STR },
{ ENOTTY, ENOTTY_STR },
{ ETXTBSY, ETXTBSY_STR },
{ EFBIG, EFBIG_STR },
{ ENOSPC, ENOSPC_STR },
{ ESPIPE, ESPIPE_STR },
{ EROFS, EROFS_STR },
{ EMLINK, EMLINK_STR },
{ EPIPE, EPIPE_STR },
{ EDOM, EDOM_STR },
{ ERANGE, ERANGE_STR },
{ EDEADLK, EDEADLK_STR },
{ ENAMETOOLONG, ENAMETOOLONG_STR },
{ ENOLCK, ENOLCK_STR },
{ ENOSYS, ENOSYS_STR },
{ ENOTEMPTY, ENOTEMPTY_STR },
{ ELOOP, ELOOP_STR },
{ ENOMSG, ENOMSG_STR },
{ EIDRM, EIDRM_STR },
{ ECHRNG, ECHRNG_STR },
{ EL2NSYNC, EL2NSYNC_STR },
{ EL3HLT, EL3HLT_STR },
{ EL3RST, EL3RST_STR },
{ ELNRNG, ELNRNG_STR },
{ EUNATCH, EUNATCH_STR },
{ ENOCSI, ENOCSI_STR },
{ EL2HLT, EL2HLT_STR },
{ EBADE, EBADE_STR },
{ EBADR, EBADR_STR },
{ EXFULL, EXFULL_STR },
{ ENOANO, ENOANO_STR },
{ EBADRQC, EBADRQC_STR },
{ EBADSLT, EBADSLT_STR },
{ EBFONT, EBFONT_STR },
{ ENOSTR, ENOSTR_STR },
{ ENODATA, ENODATA_STR },
{ ETIME, ETIME_STR },
{ ENOSR, ENOSR_STR },
{ ENONET, ENONET_STR },
{ ENOPKG, ENOPKG_STR },
{ EREMOTE, EREMOTE_STR },
{ ENOLINK, ENOLINK_STR },
{ EADV, EADV_STR },
{ ESRMNT, ESRMNT_STR },
{ ECOMM, ECOMM_STR },
{ EPROTO, EPROTO_STR },
{ EMULTIHOP, EMULTIHOP_STR },
{ EDOTDOT, EDOTDOT_STR },
{ EBADMSG, EBADMSG_STR },
{ EOVERFLOW, EOVERFLOW_STR },
{ ENOTUNIQ, ENOTUNIQ_STR },
{ EBADFD, EBADFD_STR },
{ EREMCHG, EREMCHG_STR },
{ ELIBACC, ELIBACC_STR },
{ ELIBBAD, ELIBBAD_STR },
{ ELIBSCN, ELIBSCN_STR },
{ ELIBMAX, ELIBMAX_STR },
{ ELIBEXEC, ELIBEXEC_STR },
{ EILSEQ, EILSEQ_STR },
{ ERESTART, ERESTART_STR },
{ ESTRPIPE, ESTRPIPE_STR },
{ EUSERS, EUSERS_STR },
{ ENOTSOCK, ENOTSOCK_STR },
{ EDESTADDRREQ, EDESTADDRREQ_STR },
{ EMSGSIZE, EMSGSIZE_STR },
{ EPROTOTYPE, EPROTOTYPE_STR },
{ ENOPROTOOPT, ENOPROTOOPT_STR },
{ EPROTONOSUPPORT, EPROTONOSUPPORT_STR },
{ ESOCKTNOSUPPORT, ESOCKTNOSUPPORT_STR },
{ EOPNOTSUPP, EOPNOTSUPP_STR },
{ EPFNOSUPPORT, EPFNOSUPPORT_STR },
{ EAFNOSUPPORT, EAFNOSUPPORT_STR },
{ EADDRINUSE, EADDRINUSE_STR },
{ EADDRNOTAVAIL, EADDRNOTAVAIL_STR },
{ ENETDOWN, ENETDOWN_STR },
{ ENETUNREACH, ENETUNREACH_STR },
{ ENETRESET, ENETRESET_STR },
{ ECONNABORTED, ECONNABORTED_STR },
{ ECONNRESET, ECONNRESET_STR },
{ ENOBUFS, ENOBUFS_STR },
{ EISCONN, EISCONN_STR },
{ ENOTCONN, ENOTCONN_STR },
{ ESHUTDOWN, ESHUTDOWN_STR },
{ ETOOMANYREFS, ETOOMANYREFS_STR },
{ ETIMEDOUT, ETIMEDOUT_STR },
{ ECONNREFUSED, ECONNREFUSED_STR },
{ EHOSTDOWN, EHOSTDOWN_STR },
{ EHOSTUNREACH, EHOSTUNREACH_STR },
{ EALREADY, EALREADY_STR },
{ EINPROGRESS, EINPROGRESS_STR },
{ ESTALE, ESTALE_STR },
{ EUCLEAN, EUCLEAN_STR },
{ ENOTNAM, ENOTNAM_STR },
{ ENAVAIL, ENAVAIL_STR },
{ EISNAM, EISNAM_STR },
{ EREMOTEIO, EREMOTEIO_STR },
{ EDQUOT, EDQUOT_STR },
{ ENOMEDIUM, ENOMEDIUM_STR },
{ EMEDIUMTYPE, EMEDIUMTYPE_STR }
};
#define NERRNO_STRS (sizeof(g_errnomap) / sizeof(struct errno_strmap_s))
char *strerror(int errnum)
{
int ndxlow = 0;
int ndxhi = NERRNO_STRS - 1;
int ndxmid;
do
{
ndxmid = (ndxlow + ndxhi) >> 1;
if (errnum > g_errnomap[ndxmid].errnum)
{
ndxlow = ndxmid + 1;
}
else if (errnum < g_errnomap[ndxmid].errnum)
{
ndxhi = ndxmid - 1;
}
else
{
return g_errnomap[ndxmid].str;
}
}
while (ndxlow <= ndxhi);
return "Unknown error";
}

View File

@ -1,211 +0,0 @@
#include <generated/csr.h>
#include <stdio.h>
#include <stdarg.h>
void isr(void);
#ifdef __or1k__
#include <hw/flags.h>
#define EXTERNAL_IRQ 0x8
static void emerg_printf(const char *fmt, ...)
{
char buf[512];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
char *p = buf;
while(*p) {
while(uart_txfull_read());
uart_rxtx_write(*p++);
}
}
static char emerg_getc(void)
{
while(uart_rxempty_read());
char c = uart_rxtx_read();
uart_ev_pending_write(UART_EV_RX);
return c;
}
static const char hex[] = "0123456789abcdef";
static void gdb_send(const char *txbuf)
{
unsigned char cksum = 0;
const char *p = txbuf;
while(*p) cksum += *p++;
emerg_printf("+$%s#%c%c", txbuf, hex[cksum >> 4], hex[cksum & 0xf]);
}
static void gdb_recv(char *rxbuf, size_t size)
{
size_t pos = (size_t)-1;
for(;;) {
char c = emerg_getc();
if(c == '$')
pos = 0;
else if(c == '#')
return;
else if(pos < size - 1) {
rxbuf[pos++] = c;
rxbuf[pos] = 0;
}
}
}
static void gdb_stub(unsigned long pc, unsigned long sr,
unsigned long r1, unsigned long *regs)
{
gdb_send("S05");
char buf[385];
for(;;) {
gdb_recv(buf, sizeof(buf));
switch(buf[0]) {
case '?': {
snprintf(buf, sizeof(buf), "S05");
break;
}
case 'g': {
snprintf(buf, sizeof(buf),
"%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x"
"%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x%08x"
"%08x%08x%08x",
0, r1, regs[2], regs[3], regs[4], regs[5], regs[6], regs[7],
regs[8], regs[9], regs[10], regs[11], regs[12], regs[13], regs[14], regs[15],
regs[16], regs[17], regs[18], regs[19], regs[20], regs[21], regs[22], regs[23],
regs[24], regs[25], regs[26], regs[27], regs[28], regs[29], regs[30], regs[31],
pc-4, pc, sr);
break;
}
case 'm': {
unsigned long addr, len;
char *endptr = &buf[0];
addr = strtoul(endptr + 1, &endptr, 16);
len = strtoul(endptr + 1, &endptr, 16);
unsigned char *ptr = (unsigned char *)addr;
if(len > sizeof(buf) / 2) len = sizeof(buf) / 2;
for(size_t i = 0; i < len; i++) {
buf[i*2 ] = hex[ptr[i] >> 4];
buf[i*2+1] = hex[ptr[i] & 15];
buf[i*2+2] = 0;
}
break;
}
case 'p': {
unsigned long reg, value;
char *endptr = &buf[0];
reg = strtoul(endptr + 1, &endptr, 16);
if(reg == 0)
value = 0;
else if(reg == 1)
value = r1;
else if(reg >= 2 && reg <= 31)
value = regs[reg];
else if(reg == 33)
value = pc;
else if(reg == 34)
value = sr;
else {
snprintf(buf, sizeof(buf), "E01");
break;
}
snprintf(buf, sizeof(buf), "%08x", value);
break;
}
case 'P': {
unsigned long reg, value;
char *endptr = &buf[0];
reg = strtoul(endptr + 1, &endptr, 16);
value = strtoul(endptr + 1, &endptr, 16);
if(reg == 0)
/* ignore */;
else if(reg == 1)
r1 = value;
else if(reg >= 2 && reg <= 31)
regs[reg] = value;
else if(reg == 33)
pc = value;
else if(reg == 34)
sr = value;
else {
snprintf(buf, sizeof(buf), "E01");
break;
}
snprintf(buf, sizeof(buf), "OK");
break;
}
case 'c': {
if(buf[1] != '\0') {
snprintf(buf, sizeof(buf), "E01");
break;
}
return;
}
default:
snprintf(buf, sizeof(buf), "");
break;
}
do {
gdb_send(buf);
} while(emerg_getc() == '-');
}
}
void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea, unsigned long sr);
void exception_handler(unsigned long vect, unsigned long *regs,
unsigned long pc, unsigned long ea, unsigned long sr)
{
if(vect == EXTERNAL_IRQ) {
isr();
} else {
emerg_printf("\n *** Unhandled exception %d *** \n", vect);
emerg_printf(" pc %08x sr %08x ea %08x\n",
pc, sr, ea);
unsigned long r1 = (unsigned long)regs + 4*32;
regs -= 2;
emerg_printf(" r0 %08x r1 %08x r2 %08x r3 %08x\n",
0, r1, regs[2], regs[3]);
emerg_printf(" r4 %08x r5 %08x r6 %08x r7 %08x\n",
regs[4], regs[5], regs[6], regs[7]);
emerg_printf(" r8 %08x r9 %08x r10 %08x r11 %08x\n",
regs[8], regs[9], regs[10], regs[11]);
emerg_printf(" r12 %08x r13 %08x r14 %08x r15 %08x\n",
regs[12], regs[13], regs[14], regs[15]);
emerg_printf(" r16 %08x r17 %08x r18 %08x r19 %08x\n",
regs[16], regs[17], regs[18], regs[19]);
emerg_printf(" r20 %08x r21 %08x r22 %08x r23 %08x\n",
regs[20], regs[21], regs[22], regs[23]);
emerg_printf(" r24 %08x r25 %08x r26 %08x r27 %08x\n",
regs[24], regs[25], regs[26], regs[27]);
emerg_printf(" r28 %08x r29 %08x r30 %08x r31 %08x\n",
regs[28], regs[29], regs[30], regs[31]);
emerg_printf(" stack:\n");
unsigned long *sp = (unsigned long *)r1;
for(unsigned long spoff = 0; spoff < 16; spoff += 4) {
emerg_printf(" %08x:", &sp[spoff]);
for(unsigned long spoff2 = 0; spoff2 < 4; spoff2++) {
emerg_printf(" %08x", sp[spoff + spoff2]);
}
emerg_printf("\n");
}
emerg_printf(" waiting for gdb... ");
gdb_stub(pc, sr, r1, regs);
}
}
#endif

View File

@ -1,20 +0,0 @@
#include <generated/csr.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <id.h>
void get_ident(char *ident)
{
#ifdef CSR_IDENTIFIER_MEM_BASE
int len, i;
len = MMPTR(CSR_IDENTIFIER_MEM_BASE);
for(i=0;i<len;i++)
ident[i] = MMPTR(CSR_IDENTIFIER_MEM_BASE + 4*i);
ident[i] = 0;
#else
ident[0] = 0;
#endif
}

View File

@ -1,141 +0,0 @@
#include <generated/csr.h>
#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
#include <spiflash.h>
#define PAGE_PROGRAM_CMD 0x02
#define WRDI_CMD 0x04
#define RDSR_CMD 0x05
#define WREN_CMD 0x06
#define SE_CMD 0xd8
#define BITBANG_CLK (1 << 1)
#define BITBANG_CS_N (1 << 2)
#define BITBANG_DQ_INPUT (1 << 3)
#define SR_WIP 1
static void flash_write_byte(unsigned char b);
static void flash_write_addr(unsigned int addr);
static void wait_for_device_ready(void);
#define min(a,b) (a>b?b:a)
static void flash_write_byte(unsigned char b)
{
int i;
spiflash_bitbang_write(0); // ~CS_N ~CLK
for(i = 0; i < 8; i++, b <<= 1) {
spiflash_bitbang_write((b & 0x80) >> 7);
spiflash_bitbang_write(((b & 0x80) >> 7) | BITBANG_CLK);
}
spiflash_bitbang_write(0); // ~CS_N ~CLK
}
static void flash_write_addr(unsigned int addr)
{
int i;
spiflash_bitbang_write(0);
for(i = 0; i < 24; i++, addr <<= 1) {
spiflash_bitbang_write((addr & 0x800000) >> 23);
spiflash_bitbang_write(((addr & 0x800000) >> 23) | BITBANG_CLK);
}
spiflash_bitbang_write(0);
}
static void wait_for_device_ready(void)
{
unsigned char sr;
unsigned char i;
do {
sr = 0;
flash_write_byte(RDSR_CMD);
spiflash_bitbang_write(BITBANG_DQ_INPUT);
for(i = 0; i < 8; i++) {
sr <<= 1;
spiflash_bitbang_write(BITBANG_CLK | BITBANG_DQ_INPUT);
sr |= spiflash_miso_read();
spiflash_bitbang_write(0 | BITBANG_DQ_INPUT);
}
spiflash_bitbang_write(0);
spiflash_bitbang_write(BITBANG_CS_N);
} while(sr & SR_WIP);
}
void erase_flash_sector(unsigned int addr)
{
unsigned int sector_addr = addr & ~(SPIFLASH_SECTOR_SIZE - 1);
spiflash_bitbang_en_write(1);
wait_for_device_ready();
flash_write_byte(WREN_CMD);
spiflash_bitbang_write(BITBANG_CS_N);
flash_write_byte(SE_CMD);
flash_write_addr(sector_addr);
spiflash_bitbang_write(BITBANG_CS_N);
wait_for_device_ready();
spiflash_bitbang_en_write(0);
}
void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len)
{
unsigned int i;
if(len > SPIFLASH_PAGE_SIZE)
len = SPIFLASH_PAGE_SIZE;
spiflash_bitbang_en_write(1);
wait_for_device_ready();
flash_write_byte(WREN_CMD);
spiflash_bitbang_write(BITBANG_CS_N);
flash_write_byte(PAGE_PROGRAM_CMD);
flash_write_addr((unsigned int)addr);
for(i = 0; i < len; i++)
flash_write_byte(*c++);
spiflash_bitbang_write(BITBANG_CS_N);
spiflash_bitbang_write(0);
wait_for_device_ready();
spiflash_bitbang_en_write(0);
}
#define SPIFLASH_PAGE_MASK (SPIFLASH_PAGE_SIZE - 1)
void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len)
{
unsigned int written = 0;
if(addr & SPIFLASH_PAGE_MASK) {
written = min(SPIFLASH_PAGE_SIZE - (addr & SPIFLASH_PAGE_MASK), len);
write_to_flash_page(addr, c, written);
c += written;
addr += written;
len -= written;
}
while(len > 0) {
written = min(len, SPIFLASH_PAGE_SIZE);
write_to_flash_page(addr, c, written);
c += written;
addr += written;
len -= written;
}
}
#endif /* CSR_SPIFLASH_BASE && SPIFLASH_PAGE_SIZE */

View File

@ -1,61 +0,0 @@
/****************************************************************************
* libc/string/lib_strcasecmp.c
*
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*****************************************************************************/
/****************************************************************************
* Included Files
*****************************************************************************/
#include <string.h>
#include <ctype.h>
/****************************************************************************
* Public Functions
*****************************************************************************/
int strcasecmp(const char *cs, const char *ct)
{
int result;
for (;;)
{
if ((result = (int)toupper(*cs) - (int)toupper(*ct)) != 0 || !*cs)
{
break;
}
cs++;
ct++;
}
return result;
}

View File

@ -1,234 +0,0 @@
/****************************************************************************
* lib/string/lib_strtod.c
* Convert string to double
*
* Copyright (C) 2002 Michael Ringgaard. All rights reserved.
* Copyright (C) 2006-2007 H. Peter Anvin.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
/****************************************************************************
* Pre-processor definitions
****************************************************************************/
/* These are predefined with GCC, but could be issues for other compilers. If
* not defined, an arbitrary big number is put in for now. These should be
* added to nuttx/compiler for your compiler.
*/
#if !defined(__DBL_MIN_EXP__) || !defined(__DBL_MAX_EXP__)
# ifdef CONFIG_CPP_HAVE_WARNING
# warning "Size of exponent is unknown"
# endif
# undef __DBL_MIN_EXP__
# define __DBL_MIN_EXP__ (-1021)
# undef __DBL_MAX_EXP__
# define __DBL_MAX_EXP__ (1024)
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
static inline int is_real(double x)
{
const double infinite = 1.0/0.0;
return (x < infinite) && (x >= -infinite);
}
/****************************************************************************
* Public Functions
****************************************************************************/
/***************************************************(************************
* Name: strtod
*
* Description:
* Convert a string to a double value
*
****************************************************************************/
double strtod(const char *str, char **endptr)
{
double number;
int exponent;
int negative;
char *p = (char *) str;
double p10;
int n;
int num_digits;
int num_decimals;
const double infinite = 1.0/0.0;
/* Skip leading whitespace */
while (isspace(*p))
{
p++;
}
/* Handle optional sign */
negative = 0;
switch (*p)
{
case '-':
negative = 1; /* Fall through to increment position */
case '+':
p++;
}
number = 0.;
exponent = 0;
num_digits = 0;
num_decimals = 0;
/* Process string of digits */
while (isdigit(*p))
{
number = number * 10. + (*p - '0');
p++;
num_digits++;
}
/* Process decimal part */
if (*p == '.')
{
p++;
while (isdigit(*p))
{
number = number * 10. + (*p - '0');
p++;
num_digits++;
num_decimals++;
}
exponent -= num_decimals;
}
if (num_digits == 0)
{
errno = ERANGE;
return 0.0;
}
/* Correct for sign */
if (negative)
{
number = -number;
}
/* Process an exponent string */
if (*p == 'e' || *p == 'E')
{
/* Handle optional sign */
negative = 0;
switch(*++p)
{
case '-':
negative = 1; /* Fall through to increment pos */
case '+':
p++;
}
/* Process string of digits */
n = 0;
while (isdigit(*p))
{
n = n * 10 + (*p - '0');
p++;
}
if (negative)
{
exponent -= n;
}
else
{
exponent += n;
}
}
if (exponent < __DBL_MIN_EXP__ ||
exponent > __DBL_MAX_EXP__)
{
errno = ERANGE;
return infinite;
}
/* Scale the result */
p10 = 10.;
n = exponent;
if (n < 0) n = -n;
while (n)
{
if (n & 1)
{
if (exponent < 0)
{
number /= p10;
}
else
{
number *= p10;
}
}
n >>= 1;
p10 *= p10;
}
if (!is_real(number))
{
errno = ERANGE;
}
if (endptr)
{
*endptr = p;
}
return number;
}

View File

@ -1,111 +0,0 @@
#include <irq.h>
#include <uart.h>
#ifdef __or1k__
#include <spr-defs.h>
#endif
#if defined (__vexriscv__)
#include <csr-defs.h>
#endif
#include <system.h>
#include <generated/mem.h>
#include <generated/csr.h>
void flush_cpu_icache(void)
{
#if defined (__lm32__)
asm volatile(
"wcsr ICC, r0\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);
#elif defined (__or1k__)
unsigned long iccfgr;
unsigned long cache_set_size;
unsigned long cache_ways;
unsigned long cache_block_size;
unsigned long cache_size;
int i;
iccfgr = mfspr(SPR_ICCFGR);
cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
cache_size = cache_set_size * cache_ways * cache_block_size;
for (i = 0; i < cache_size; i += cache_block_size)
mtspr(SPR_ICBIR, i);
#elif defined (__picorv32__)
/* no instruction cache */
asm volatile("nop");
#elif defined (__vexriscv__)
asm volatile(
".word(0x400F)\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
"nop\n"
);
#elif defined (__minerva__)
/* no instruction cache */
asm volatile("nop");
#else
#error Unsupported architecture
#endif
}
void flush_cpu_dcache(void)
{
#if defined (__lm32__)
asm volatile(
"wcsr DCC, r0\n"
"nop\n"
);
#elif defined (__or1k__)
unsigned long dccfgr;
unsigned long cache_set_size;
unsigned long cache_ways;
unsigned long cache_block_size;
unsigned long cache_size;
int i;
dccfgr = mfspr(SPR_DCCFGR);
cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
cache_size = cache_set_size * cache_ways * cache_block_size;
for (i = 0; i < cache_size; i += cache_block_size)
mtspr(SPR_DCBIR, i);
#elif defined (__picorv32__)
/* no data cache */
asm volatile("nop");
#elif defined (__vexriscv__)
unsigned long cache_info;
asm volatile ("csrr %0, %1" : "=r"(cache_info) : "i"(CSR_DCACHE_INFO));
unsigned long cache_way_size = cache_info & 0xFFFFF;
unsigned long cache_line_size = (cache_info >> 20) & 0xFFF;
for(register unsigned long idx = 0;idx < cache_way_size;idx += cache_line_size){
asm volatile("mv x10, %0 \n .word(0b01110000000001010101000000001111)"::"r"(idx));
}
#elif defined (__minerva__)
/* no data cache */
asm volatile("nop");
#else
#error Unsupported architecture
#endif
}
#ifdef L2_SIZE
void flush_l2_cache(void)
{
unsigned int i;
for(i=0;i<2*L2_SIZE/4;i++) {
((volatile unsigned int *) MAIN_RAM_BASE)[i];
}
}
#endif

245
third_party/printf.c vendored Normal file
View File

@ -0,0 +1,245 @@
/*
* Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
#include "printf.h"
typedef void (*putcf) (void*,char);
static putcf stdout_putf;
static void* stdout_putp;
#ifdef PRINTF_LONG_SUPPORT
static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf)
{
int n=0;
unsigned int d=1;
while (num/d >= base)
d*=base;
while (d!=0) {
int dgt = num / d;
num%=d;
d/=base;
if (n || dgt>0|| d==0) {
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
++n;
}
}
*bf=0;
}
static void li2a (long num, char * bf)
{
if (num<0) {
num=-num;
*bf++ = '-';
}
uli2a(num,10,0,bf);
}
#endif
static void ui2a(unsigned int num, unsigned int base, int uc,char * bf)
{
int n=0;
unsigned int d=1;
while (num/d >= base)
d*=base;
while (d!=0) {
int dgt = num / d;
num%= d;
d/=base;
if (n || dgt>0 || d==0) {
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
++n;
}
}
*bf=0;
}
static void i2a (int num, char * bf)
{
if (num<0) {
num=-num;
*bf++ = '-';
}
ui2a(num,10,0,bf);
}
static int a2d(char ch)
{
if (ch>='0' && ch<='9')
return ch-'0';
else if (ch>='a' && ch<='f')
return ch-'a'+10;
else if (ch>='A' && ch<='F')
return ch-'A'+10;
else return -1;
}
static char a2i(char ch, char** src,int base,int* nump)
{
char* p= *src;
int num=0;
int digit;
while ((digit=a2d(ch))>=0) {
if (digit>base) break;
num=num*base+digit;
ch=*p++;
}
*src=p;
*nump=num;
return ch;
}
static void putchw(void* putp,putcf putf,int n, char z, char* bf)
{
char fc=z? '0' : ' ';
char ch;
char* p=bf;
while (*p++ && n > 0)
n--;
while (n-- > 0)
putf(putp,fc);
while ((ch= *bf++))
putf(putp,ch);
}
void tfp_format(void* putp,putcf putf,char *fmt, va_list va)
{
char bf[12];
char ch;
while ((ch=*(fmt++))) {
if (ch!='%')
putf(putp,ch);
else {
char lz=0;
#ifdef PRINTF_LONG_SUPPORT
char lng=0;
#endif
int w=0;
ch=*(fmt++);
if (ch=='0') {
ch=*(fmt++);
lz=1;
}
if (ch>='0' && ch<='9') {
ch=a2i(ch,&fmt,10,&w);
}
#ifdef PRINTF_LONG_SUPPORT
if (ch=='l') {
ch=*(fmt++);
lng=1;
}
#endif
switch (ch) {
case 0:
goto abort;
case 'u' : {
#ifdef PRINTF_LONG_SUPPORT
if (lng)
uli2a(va_arg(va, unsigned long int),10,0,bf);
else
#endif
ui2a(va_arg(va, unsigned int),10,0,bf);
putchw(putp,putf,w,lz,bf);
break;
}
case 'd' : {
#ifdef PRINTF_LONG_SUPPORT
if (lng)
li2a(va_arg(va, unsigned long int),bf);
else
#endif
i2a(va_arg(va, int),bf);
putchw(putp,putf,w,lz,bf);
break;
}
case 'x': case 'X' :
#ifdef PRINTF_LONG_SUPPORT
if (lng)
uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf);
else
#endif
ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf);
putchw(putp,putf,w,lz,bf);
break;
case 'c' :
putf(putp,(char)(va_arg(va, int)));
break;
case 's' :
putchw(putp,putf,w,0,va_arg(va, char*));
break;
case '%' :
putf(putp,ch);
default:
break;
}
}
}
abort:;
}
void init_printf(void* putp,void (*putf) (void*,char))
{
stdout_putf=putf;
stdout_putp=putp;
}
void tfp_printf(char *fmt, ...)
{
va_list va;
va_start(va,fmt);
tfp_format(stdout_putp,stdout_putf,fmt,va);
va_end(va);
}
static void putcp(void* p,char c)
{
*(*((char**)p))++ = c;
}
void tfp_sprintf(char* s,char *fmt, ...)
{
va_list va;
va_start(va,fmt);
tfp_format(&s,putcp,fmt,va);
putcp(&s,0);
va_end(va);
}