Cleanup, ready to merge with master

This commit is contained in:
lcbcFoo 2018-03-26 12:14:58 -03:00
parent d04f4233af
commit 7c88a1857d
12 changed files with 267 additions and 47928 deletions

View file

@ -28,7 +28,7 @@ WRAP=-Wl,-wrap,exit,-wrap,open,-wrap,close,-wrap,write,-wrap,read,-wrap,lseek,-w
#
# Targets for compiling
#
MAIN_OBJS=reonv_crt0.o posix.o main.o
MAIN_OBJS=reonv_crt0.o mini_printf.o posix.o main.o
# Compiled binary linked with reonv_crt0
#%.out : %.c reonv_crt0.o posix.o
@ -46,8 +46,8 @@ MAIN_OBJS=reonv_crt0.o posix.o main.o
main.o : main.c
${CROSS}${CC} -c $< -o $@
# mini_printf.o : mini_printf.c
# ${CROSS}${CC} -c $< -o $@
mini_printf.o : mini_printf.c
${CROSS}${CC} -c $< -o $@
posix.o : posix.c
${CROSS}${CC} -c $< -o $@ -nostdlib
@ -94,4 +94,4 @@ ahbrom : ../bin/ahbrom.c
gcc ../bin/ahbrom.c -o ahbrom
clean:
rm -rf ahbrom* tools/*.x86 *.hex *.inv *.convert *.bin *.o *log *.jou *.str acstone/*.out *.out *.read
rm -rf ahbrom* tools/*.x86 *.hex *.inv *.convert *.bin *.o *log *.jou *.str *.out *.read

View file

@ -1,243 +0,0 @@
/* Script for -z combreloc: combine and sort reloc sections */
/* Copyright (C) 2014-2017 Free Software Foundation, Inc.
Copying and distribution of this script, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. */
OUTPUT_FORMAT("elf32-littleriscv", "elf32-littleriscv",
"elf32-littleriscv")
OUTPUT_ARCH(riscv)
ENTRY(__reonv_start)
SEARCH_DIR("/home/foo/IC/riscv-leon/rv32i/rv32i-gnu/riscv32-unknown-elf/lib");
SECTIONS
{
/* Read-only sections, merged into text segment: */
PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x40000000)); . = SEGMENT_START("text-segment", 0x40000000) + 0x1000;
.interp : { *(.interp) }
.note.gnu.build-id : { *(.note.gnu.build-id) }
.hash : { *(.hash) }
.gnu.hash : { *(.gnu.hash) }
.dynsym : { *(.dynsym) }
.dynstr : { *(.dynstr) }
.gnu.version : { *(.gnu.version) }
.gnu.version_d : { *(.gnu.version_d) }
.gnu.version_r : { *(.gnu.version_r) }
.rela.dyn :
{
*(.rela.init)
*(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
*(.rela.fini)
*(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
*(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
*(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
*(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
*(.rela.ctors)
*(.rela.dtors)
*(.rela.got)
*(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*)
*(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*)
*(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*)
*(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
*(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
PROVIDE_HIDDEN (__rela_iplt_start = .);
*(.rela.iplt)
PROVIDE_HIDDEN (__rela_iplt_end = .);
}
.rela.plt :
{
*(.rela.plt)
}
.init :
{
KEEP (*(SORT_NONE(.init)))
}
.plt : { *(.plt) }
.iplt : { *(.iplt) }
.text :
{
/*
* Forced minimal ctr0 to be the first code
*/
reonv_crt0.o
posix.o
*(.text.unlikely .text.*_unlikely .text.unlikely.*)
*(.text.exit .text.exit.*)
*(.text.startup .text.startup.*)
*(.text.hot .text.hot.*)
*(.text .stub .text.* .gnu.linkonce.t.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
}
.fini :
{
KEEP (*(SORT_NONE(.fini)))
}
PROVIDE (__etext = .);
PROVIDE (_etext = .);
PROVIDE (etext = .);
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
.rodata1 : { *(.rodata1) }
.sdata2 :
{
*(.sdata2 .sdata2.* .gnu.linkonce.s2.*)
}
.sbss2 : { *(.sbss2 .sbss2.* .gnu.linkonce.sb2.*) }
.eh_frame_hdr : { *(.eh_frame_hdr) *(.eh_frame_entry .eh_frame_entry.*) }
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gcc_except_table : ONLY_IF_RO { *(.gcc_except_table
.gcc_except_table.*) }
.gnu_extab : ONLY_IF_RO { *(.gnu_extab*) }
/* These sections are generated by the Sun/Oracle C++ compiler. */
.exception_ranges : ONLY_IF_RO { *(.exception_ranges
.exception_ranges*) }
/* Adjust the address for the data segment. We want to adjust up to
the same address within the page on the next page up. */
. = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
/* Exception handling */
.eh_frame : ONLY_IF_RW { KEEP (*(.eh_frame)) *(.eh_frame.*) }
.gnu_extab : ONLY_IF_RW { *(.gnu_extab) }
.gcc_except_table : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
.exception_ranges : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
/* Thread Local Storage sections */
.tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
.tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
.preinit_array :
{
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
}
.init_array :
{
PROVIDE_HIDDEN (__init_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
PROVIDE_HIDDEN (__init_array_end = .);
}
.fini_array :
{
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
PROVIDE_HIDDEN (__fini_array_end = .);
}
.ctors :
{
/* gcc uses crtbegin.o to find the start of
the constructors, so we make sure it is
first. Because this is a wildcard, it
doesn't matter if the user does not
actually link against crtbegin.o; the
linker won't look for a file to match a
wildcard. The wildcard also means that it
doesn't matter which directory crtbegin.o
is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*crtbegin?.o(.ctors))
/* We don't want to include the .ctor section from
the crtend.o file until after the sorted ctors.
The .ctor section from the crtend file contains the
end of ctors marker and it must be last */
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
}
.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*crtbegin?.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
}
.jcr : { KEEP (*(.jcr)) }
.data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
.dynamic : { *(.dynamic) }
. = DATA_SEGMENT_RELRO_END (0, .);
.data :
{
*(.data .data.* .gnu.linkonce.d.*)
SORT(CONSTRUCTORS)
}
.data1 : { *(.data1) }
.got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) }
/* We want the small data sections together, so single-instruction offsets
can access them all, and initialized data all before uninitialized, so
we can shorten the on-disk segment size. */
.sdata :
{
__global_pointer$ = . + 0x800;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*)
*(.sdata .sdata.* .gnu.linkonce.s.*)
}
_edata = .; PROVIDE (edata = .);
. = .;
__bss_start = .;
.sbss :
{
*(.dynsbss)
*(.sbss .sbss.* .gnu.linkonce.sb.*)
*(.scommon)
}
.bss :
{
*(.dynbss)
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
/* Align here to ensure that the .bss section occupies space up to
_end. Align after .bss to ensure correct alignment even if the
.bss section disappears because there are no input sections.
FIXME: Why do we need it? When there is no .bss section, we don't
pad the .data section. */
. = ALIGN(. != 0 ? 32 / 8 : 1);
}
. = ALIGN(32 / 8);
. = SEGMENT_START("ldata-segment", .);
. = ALIGN(32 / 8);
_end = .; PROVIDE (end = .);
. = DATA_SEGMENT_END (.);
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* DWARF 3 */
.debug_pubtypes 0 : { *(.debug_pubtypes) }
.debug_ranges 0 : { *(.debug_ranges) }
/* DWARF Extension. */
.debug_macro 0 : { *(.debug_macro) }
.debug_addr 0 : { *(.debug_addr) }
.gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) }
}

View file

@ -1,14 +1,15 @@
int fib();
#include <stdio.h>
#include "mini-printf.h"
#include "mini_printf.h"
int main(){
int n = 20;
printf("Testing fib calculator, array dealing, write, read and lseek functions\n\n");
// Allocates memory for arrays
int* array = sbrk(n * sizeof(int));
int* array2 = sbrk(n * sizeof(int));
int* array = (int*)sbrk(n * sizeof(int));
int* array2 = (int*)sbrk(n * sizeof(int));
printf("Address array 1: 0x%x\n", array);
printf("Address array 2: 0x%x\n", array2);
@ -37,7 +38,7 @@ int main(){
correct = 0;
if(correct)
printf("Copied array1 into array2!\n");
printf("\nCopied array1 into array2!\n");
else
printf("Oh no, error!\n");

227
riscv/mini_printf.c Normal file
View file

@ -0,0 +1,227 @@
/*
* The Minimal snprintf() implementation
*
* Copyright (c) 2013,2014 Michal Ludvig <michal@logix.cz>
* 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 auhor 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 AUTHOR 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.
*
* ----
*
* This is a minimal snprintf() implementation optimised
* for embedded systems with a very limited program memory.
* mini_snprintf() doesn't support _all_ the formatting
* the glibc does but on the other hand is a lot smaller.
* Here are some numbers from my STM32 project (.bin file size):
* no snprintf(): 10768 bytes
* mini snprintf(): 11420 bytes (+ 652 bytes)
* glibc snprintf(): 34860 bytes (+24092 bytes)
* Wasting nearly 24kB of memory just for snprintf() on
* a chip with 32kB flash is crazy. Use mini_snprintf() instead.
*
*/
/* Ported original mini-printf (https://github.com/mludvig/mini-printf) to ReonV */
#include <unistd.h>
#include "posix_c.h"
#include "mini_printf.h"
#include "reonv.h"
static unsigned int mini_strlen(const char *s){
unsigned int len = 0;
while (s[len] != '\0') len++;
return len;
}
static unsigned int mini_itoa(int value, unsigned int radix, unsigned int uppercase,
unsigned int unsig, char *buffer, unsigned int zero_pad) {
char *pbuffer = buffer;
int negative = 0;
unsigned int i, len;
/* No support for unusual radixes. */
if (radix > 16)
return 0;
if (value < 0 && !unsig) {
negative = 1;
value = -value;
}
/* This builds the string back to front ... */
do {
int digit = value % radix;
*(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10);
value /= radix;
} while (value > 0);
for (i = (pbuffer - buffer); i < zero_pad; i++)
*(pbuffer++) = '0';
if (negative)
*(pbuffer++) = '-';
*(pbuffer) = '\0';
/* ... now we reverse it (could do it recursively but will
* conserve the stack space) */
len = (pbuffer - buffer);
for (i = 0; i < len / 2; i++) {
char j = buffer[i];
buffer[i] = buffer[len-i-1];
buffer[len-i-1] = j;
}
return len;
}
struct mini_buff {
char *buffer, *pbuffer;
unsigned int buffer_len;
};
static int _putc(int ch, struct mini_buff *b){
if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len)
return 0;
*(b->pbuffer++) = ch;
*(b->pbuffer) = '\0';
return 1;
}
static int _puts(char *s, unsigned int len, struct mini_buff *b){
unsigned int i;
if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len)
len = b->buffer_len - (b->pbuffer - b->buffer) - 1;
/* Copy to buffer */
for (i = 0; i < len; i++)
*(b->pbuffer++) = s[i];
*(b->pbuffer) = '\0';
return len;
}
int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, va_list va){
char* args = (va);
struct mini_buff b;
char bf[24];
char ch;
b.buffer = buffer;
b.pbuffer = buffer;
b.buffer_len = buffer_len;
while ((ch=*(fmt++))) {
if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len)
break;
// Move cursor bak to beginning of line when writing to console
if(buffer == console_buffer && ch == '\n'){
_putc(ch, &b);
ch = '\r';
_putc(ch, &b);
}
else if (ch!='%'){
_putc(ch, &b);
}
else {
char zero_pad = 0;
char *ptr;
unsigned int len;
unsigned int d;
ch=*(fmt++);
/* Zero padding requested, supported up to 9 zeros */
if (ch=='0') {
ch=*(fmt++);
if (ch == '\0')
goto end;
if(ch >= '0' && ch <= '9')
zero_pad = ch - '0';
ch=*(fmt++);
}
switch (ch) {
case 0:
goto end;
case 'u':
case 'd':
d = va_arg(va, unsigned int);
len = mini_itoa(d, 10, 0, (ch=='u'), bf, zero_pad);
_puts(bf, len, &b);
break;
case 'x':
case 'X':
d = va_arg(va, unsigned int);
len = mini_itoa(d, 16, (ch=='X'), 1, bf, zero_pad);
_puts(bf, len, &b);
break;
case 'c' :
ch = va_arg(va, int);
_putc(ch, &b);
break;
case 's' :
ptr = va_arg(va, char*);
_puts(ptr, mini_strlen(ptr), &b);
break;
default:
_putc(ch, &b);
break;
}
}
}
end:
return b.pbuffer - b.buffer;
}
int mini_snprintf(char* buffer, unsigned int buffer_len, const char *fmt, ...){
va_list args;
/* Emit the output into the temporary buffer */
va_start (args, fmt);
unsigned int printed_len = mini_vsnprintf (buffer, buffer_len, fmt, args);
va_end (args);
return printed_len;
}
int reonv_printf (const char *fmt, ...){
va_list args;
/* Emit output to console buffer, then call write to send it to console */
va_start (args, fmt);
unsigned int printed_len = mini_vsnprintf(console_buffer, CONSOLE_BUFFER_SIZE * sizeof (char), fmt, args);
va_end (args);
write(STDOUT_FILENO, console_buffer, printed_len);
}

View file

@ -27,24 +27,16 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Header to mini_printf functions */
#ifndef __MINI_PRINTF__
#define __MINI_PRINTF__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
int mini_vsnprintf(char* buffer, unsigned int buffer_len, const char *fmt, char** va);
int mini_vsnprintf(char* buffer, unsigned int buffer_len, const char *fmt, va_list va);
int mini_snprintf(char* buffer, unsigned int buffer_len, const char *fmt, ...);
int reonv_printf(const char* fmt, ...);
#ifdef __cplusplus
}
#endif
#define vsnprintf mini_vsnprintf
#define snprintf mini_snprintf
#define printf reonv_printf

View file

@ -22,262 +22,19 @@
#include <unistd.h>
#include "reonv.h"
#include "mini-printf.h"
#include "mini_printf.h"
#define POSIC_C
#include "posix_c.h"
// External
char* console_buffer;
// Internal
static char* heap;
static char* out_mem;
static char* console_buffer;
static LEON23_APBUART_Regs_Map *uart_regs;
/* PRINTF ********************/
/*
* The Minimal snprintf() implementation
*
* Copyright (c) 2013,2014 Michal Ludvig <michal@logix.cz>
* 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 auhor 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 AUTHOR 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.
*
* ----
*
* This is a minimal snprintf() implementation optimised
* for embedded systems with a very limited program memory.
* mini_snprintf() doesn't support _all_ the formatting
* the glibc does but on the other hand is a lot smaller.
* Here are some numbers from my STM32 project (.bin file size):
* no snprintf(): 10768 bytes
* mini snprintf(): 11420 bytes (+ 652 bytes)
* glibc snprintf(): 34860 bytes (+24092 bytes)
* Wasting nearly 24kB of memory just for snprintf() on
* a chip with 32kB flash is crazy. Use mini_snprintf() instead.
*
*/
#include <unistd.h>
#include "posix_c.h"
#include "mini-printf.h"
#include "reonv.h"
static unsigned int
mini_strlen(const char *s)
{
unsigned int len = 0;
while (s[len] != '\0') len++;
return len;
}
static unsigned int
mini_itoa(int value, unsigned int radix, unsigned int uppercase, unsigned int unsig,
char *buffer, unsigned int zero_pad)
{
//__asm("ebreak");
char *pbuffer = buffer;
int negative = 0;
unsigned int i, len;
/* No support for unusual radixes. */
if (radix > 16)
return 0;
if (value < 0 && !unsig) {
negative = 1;
value = -value;
}
/* This builds the string back to front ... */
do {
int digit = value % radix;
*(pbuffer++) = (digit < 10 ? '0' + digit : (uppercase ? 'A' : 'a') + digit - 10);
value /= radix;
} while (value > 0);
for (i = (pbuffer - buffer); i < zero_pad; i++)
*(pbuffer++) = '0';
if (negative)
*(pbuffer++) = '-';
*(pbuffer) = '\0';
/* ... now we reverse it (could do it recursively but will
* conserve the stack space) */
len = (pbuffer - buffer);
for (i = 0; i < len / 2; i++) {
char j = buffer[i];
buffer[i] = buffer[len-i-1];
buffer[len-i-1] = j;
}
return len;
}
struct mini_buff {
char *buffer, *pbuffer;
unsigned int buffer_len;
};
static int my_putc(int ch, struct mini_buff *b){
if ((unsigned int)((b->pbuffer - b->buffer) + 1) >= b->buffer_len)
return 0;
*(b->pbuffer++) = ch;
*(b->pbuffer) = '\0';
return 1;
}
static int my_puts(char *s, unsigned int len, struct mini_buff *b){
unsigned int i;
if (b->buffer_len - (b->pbuffer - b->buffer) - 1 < len)
len = b->buffer_len - (b->pbuffer - b->buffer) - 1;
/* Copy to buffer */
for (i = 0; i < len; i++)
*(b->pbuffer++) = s[i];
*(b->pbuffer) = '\0';
return len;
}
int mini_vsnprintf(char *buffer, unsigned int buffer_len, const char *fmt, char** va){
char* args = (*va);
//__asm("ebreak");
struct mini_buff b;
char bf[24];
char ch;
b.buffer = buffer;
b.pbuffer = buffer;
b.buffer_len = buffer_len;
while ((ch=*(fmt++))) {
if ((unsigned int)((b.pbuffer - b.buffer) + 1) >= b.buffer_len)
break;
if(ch == '\n'){
my_putc(ch, &b);
ch = '\r';
my_putc(ch, &b);
}
else if (ch!='%'){
my_putc(ch, &b);
}
else {
char zero_pad = 0;
char *ptr;
unsigned int len;
unsigned int d;
ch=*(fmt++);
/* Zero padding requested, supported up to 9 zeros */
if (ch=='0') {
ch=*(fmt++);
if (ch == '\0')
goto end;
if(ch >= '0' && ch <= '9')
zero_pad = ch - '0';
ch=*(fmt++);
}
switch (ch) {
case 0:
goto end;
case 'u':
case 'd':
d = (unsigned int) *((int*)args);
args += sizeof(unsigned int);
len = mini_itoa(d, 10, 0, (ch=='u'), bf, zero_pad);
my_puts(bf, len, &b);
break;
case 'x':
case 'X':
d = (unsigned int) *((int*)args);
args += sizeof(unsigned int);
len = mini_itoa(d, 16, (ch=='X'), 1, bf, zero_pad);
my_puts(bf, len, &b);
break;
case 'c' :
ch = (char) *args;
args += sizeof(int);
my_putc(ch, &b);
break;
case 's' :
ptr = (char*) *((int*)args);
args += sizeof(int);
my_puts(ptr, mini_strlen(ptr), &b);
break;
default:
my_putc(ch, &b);
break;
}
}
}
end:
return b.pbuffer - b.buffer;
}
int mini_snprintf(char* buffer, unsigned int buffer_len, const char *fmt, ...){
int ret;
va_list va;
va_start(va, fmt);
ret = mini_vsnprintf(buffer, buffer_len, fmt, va);
va_end(va);
return ret;
}
int reonv_printf (const char *fmt, ...){
va_list args;
/* Emit the output into the temporary buffer */
va_start (args, fmt);
//__asm("ebreak");
unsigned int printed_len = mini_snprintf (console_buffer, CONSOLE_BUFFER_SIZE * sizeof (char), fmt, args);
va_end (args);
write(STDOUT_FILENO, console_buffer, printed_len);
}
/* END PRINTF*/
/* Sends output via UART, adapted from BCC source code */
int send_uart (char *fmt, unsigned int len){
unsigned int i, loops, ch;
char *p = fmt;
@ -290,7 +47,8 @@ int send_uart (char *fmt, unsigned int len){
while (!(uart_regs->status & LEON_REG_UART_STATUS_THE) && (loops < UART_TIMEOUT))
loops++;
unsigned int outdata = (unsigned int) ch;
// Moves byte to beginning of TX buffer
unsigned int outdata = (unsigned int) ch;
outdata <<= 24;
uart_regs->data = outdata;
loops = 0;
@ -313,8 +71,9 @@ void _init_reonv(){
// Exit application
void _exit( int status ) {
void _exit(int status) {
__asm("ebreak");
while(1);
}
// Repositions the offset of memory section (no file descriptor implemented)
@ -380,5 +139,9 @@ int _close( int fd ) {
void* _sbrk( int incr ) {
void* addr = (void*) heap;
heap += incr;
// Keep heap byte aligned
while((int)heap % 4 != 0)
heap++;
return addr;
}

View file

@ -16,12 +16,12 @@
*/
/* Author: Lucas C. B. Castro
* Description: This file contains minimal implementations of some posix
* functions for ReonV.
* Description: Assembly header for posix functions
*/
#ifndef POSIX_H_INCLUDED
#define POSIX_H_INCLUDED
//int *console = (int *) 0x80000100;
.globl send_uart
@ -46,3 +46,5 @@
// Allocate space on heap
.globl _sbrk
#endif //POSIX_H_INCLUDED

View file

@ -32,6 +32,7 @@ int _lseek( int fd, int offset, int whence );
// Read from output memory section (no file descriptor implemented)
int _read( int fd, char *buffer, int len );
// Write to output memory section (no file descriptor implemented)
int _write( int fd, char *buffer, int len );
@ -44,4 +45,4 @@ int _close( int fd );
// Allocate space on heap
void* _sbrk( int incr );
#endif
#endif //POSIXC_H_INCLUDED

47375
riscv/read

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,10 @@
#ifndef REONV_H_INCLUDED
#define REONV_H_INCLUDED
/* Reonv constants, most of them copied from GRLIB manual or BCC compiler
* source code
*/
#define RAM_START 0x40000000
#define RAM_SIZE 0x08000000
#define SP_START 0x43FFFFF0
@ -37,3 +44,5 @@
#define LEON_REG_UART_CTRL_LB 0x00000080 /* Loop Back enable */
#define UART_TIMEOUT 5000 /* Timeout for TX */
#endif //REONV_H_INCLUDED

Binary file not shown.

View file

@ -1,38 +0,0 @@
int fib();
#include <stdio.h>
int main(){
int n = 8;
// Allocates memory for arrays
int* array = (int*)sbrk(n * sizeof(int));
int* array2 = (int*)sbrk(n * sizeof(int));
// Calculates fib(i), 1 <= i <= n
for(int i = 1; i <= n; i++)
array[i-1] = fib(i);
// Writes results on output memory section
write(0, array,n * sizeof(int));
// Sets pointer to beginning of output memory section
lseek(0, -n*sizeof(int), SEEK_CUR);
// Reads the results into array2
read(0, array2, n * sizeof(int));
// Checks if they were copied correctly
int correct = 0xAAAAAAAA;
for(int i = 0; i < n; i++)
if(array[i] != array2[i])
correct = 0xBBBBBBBB;
// Writes the check into output memory section
write(0, &correct, sizeof(int));
}
int fib(int i){
if(i == 1 || i == 2)
return 1;
return fib(i-1) + fib(i-2);
}