URL
https://opencores.org/ocsvn/ion/ion/trunk
Subversion Repositories ion
Compare Revisions
- This comparison shows the changes necessary to convert path
/ion/trunk
- from Rev 171 to Rev 172
- ↔ Reverse comparison
Rev 171 → Rev 172
/src/common/libsoc/src/hw.h
0,0 → 1,20
/** |
@file hw.h |
@brief Declarations for the hardware-dependent part of the library. |
|
The library is not meant to be ported across architectures; but it is |
meant to be ported to different FPGA projects using the Ion CPU core. |
*/ |
|
#ifndef HW_H_INCLUDED |
#define HW_H_INCLUDED |
|
/*-- Hardware configuration (other than memory map) --------------------------*/ |
|
#define UART_TX (0x20000000) /**< Addr of TX buffer */ |
#define UART_RX (0x20000000) /**< Addr of RX buffer */ |
#define UART_STATUS (0x20000020) /**< Addr of status register */ |
#define UART_RXRDY_MASK (0x00000001) /**< Flag mask for 'RX ready' */ |
#define UART_TXRDY_MASK (0x00000002) /**< Flag mask for 'TX ready' */ |
|
#endif // HW_H_INCLUDED |
/src/common/libsoc/src/hw_ion_mpu.c
0,0 → 1,38
/** |
@file hw_ion_mpu.c |
@brief Hardware-dependent code for the default Ion MPU. |
|
|
This is the file that needs to be modified in order to use the library in |
an FPGA project other than the default one supplied with the Ion core. |
|
This code targets the 'default' MPU built around the Ion core. That is, the |
MPU built from vhdl template 'mips_mpu1_template.vhdl' which includes the |
CPU, cache module, a timer and a simple UART. |
|
@note The functionality of the functions is not entirely compatible to the |
libc standard. For example, neither getchar nor putchar update errno, etc. |
*/ |
#include <stdint.h> |
|
#include "hw.h" |
|
/** Replacement for the standard C library putchar. */ |
int putchar(int c){ |
while( !((*((volatile uint32_t *)UART_STATUS) ) & UART_TXRDY_MASK)); |
*((volatile uint32_t *)UART_TX) = (uint32_t)c; |
return c; |
} |
|
/** Replacement for the standard C library getchar. */ |
int getchar(void){ |
uint32_t uart; |
|
while(1){ |
uart = *((volatile uint32_t *)UART_STATUS); |
if(uart & UART_RXRDY_MASK) break; |
} |
uart = *((volatile uint32_t *)UART_RX); |
uart = (uart >> 24) & 0x0ff; |
return (int)uart; |
} |
/src/common/libsoc/src/printf-stdarg.c
0,0 → 1,305
/** |
@file printf-stdarg.c |
@brief Replacement for printf. Limited functionality (e.g. no float format). |
|
This code relies on external functions getchar and putchar. |
*/ |
/* |
Copyright 2001, 2002 Georges Menie (www.menie.org) |
stdarg version contributed by Christian Ettinger |
|
This program 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 2 of the License, or |
(at your option) any later version. |
|
This program 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 this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
|
/* |
putchar is the only external dependency for this file, |
if you have a working putchar, leave it commented out. |
If not, uncomment the define below and |
replace outbyte(c) by your own function call. |
|
#define putchar(c) outbyte(c) |
*/ |
|
#include <stdarg.h> |
|
/** Prints character to string buffer. |
Used by printf, not to be used directly.*/ |
static void printchar(char **str, int c) |
{ |
extern int putchar(int c); |
|
if (str) { |
**str = c; |
++(*str); |
} |
else (void)putchar(c); |
} |
|
#define PAD_RIGHT (1) /**< */ |
#define PAD_ZERO (2) /**< */ |
|
/** Prints formatted string to string buffer. |
Used by printf, not to be used directly.*/ |
static int prints(char **out, const char *string, int width, int pad) |
{ |
register int pc = 0, padchar = ' '; |
|
if (width > 0) { |
register int len = 0; |
register const char *ptr; |
for (ptr = string; *ptr; ++ptr) ++len; |
if (len >= width) width = 0; |
else width -= len; |
if (pad & PAD_ZERO) padchar = '0'; |
} |
if (!(pad & PAD_RIGHT)) { |
for ( ; width > 0; --width) { |
printchar (out, padchar); |
++pc; |
} |
} |
for ( ; *string ; ++string) { |
printchar (out, *string); |
++pc; |
} |
for ( ; width > 0; --width) { |
printchar (out, padchar); |
++pc; |
} |
|
return pc; |
} |
|
/** Temporary buffer used to print numbers to */ |
/* the following should be enough for 32 bit int */ |
#define PRINT_BUF_LEN 12 |
|
/** Prints formatted integer to string buffer. |
Used by printf, not to be used directly.*/ |
static int printi(char **out, int i, int b, int sg, int width, int pad, int letbase) |
{ |
char print_buf[PRINT_BUF_LEN]; |
register char *s; |
register int t, neg = 0, pc = 0; |
register unsigned int u = i; |
|
if (i == 0) { |
print_buf[0] = '0'; |
print_buf[1] = '\0'; |
return prints (out, print_buf, width, pad); |
} |
|
if (sg && b == 10 && i < 0) { |
neg = 1; |
u = -i; |
} |
|
s = print_buf + PRINT_BUF_LEN-1; |
*s = '\0'; |
|
while (u) { |
t = u % b; |
if( t >= 10 ) |
t += letbase - '0' - 10; |
*--s = t + '0'; |
u /= b; |
} |
|
if (neg) { |
if( width && (pad & PAD_ZERO) ) { |
printchar (out, '-'); |
++pc; |
--width; |
} |
else { |
*--s = '-'; |
} |
} |
|
return pc + prints (out, s, width, pad); |
} |
|
/** Main print function; parses format string and calls aux functions. |
Used by printf, not to be used directly.*/ |
static int print( char **out, const char *format, va_list args ) |
{ |
register int width, pad; |
register int pc = 0; |
char scr[2]; |
|
for (; *format != 0; ++format) { |
if (*format == '%') { |
++format; |
width = pad = 0; |
if (*format == '\0') break; |
if (*format == '%') goto out; |
if (*format == '-') { |
++format; |
pad = PAD_RIGHT; |
} |
while (*format == '0') { |
++format; |
pad |= PAD_ZERO; |
} |
for ( ; *format >= '0' && *format <= '9'; ++format) { |
width *= 10; |
width += *format - '0'; |
} |
if( *format == 's' ) { |
register char *s = (char *)va_arg( args, int ); |
pc += prints (out, s?s:"(null)", width, pad); |
continue; |
} |
if( *format == 'd' ) { |
pc += printi (out, va_arg( args, int ), 10, 1, width, pad, 'a'); |
continue; |
} |
if( *format == 'x' ) { |
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'a'); |
continue; |
} |
if( *format == 'X' ) { |
pc += printi (out, va_arg( args, int ), 16, 0, width, pad, 'A'); |
continue; |
} |
if( *format == 'u' ) { |
pc += printi (out, va_arg( args, int ), 10, 0, width, pad, 'a'); |
continue; |
} |
if( *format == 'c' ) { |
/* char are converted to int then pushed on the stack */ |
scr[0] = (char)va_arg( args, int ); |
scr[1] = '\0'; |
pc += prints (out, scr, width, pad); |
continue; |
} |
} |
else { |
out: |
printchar (out, *format); |
++pc; |
} |
} |
if (out) **out = '\0'; |
va_end( args ); |
return pc; |
} |
|
/** Replacement for standard printf. */ |
int printf(const char *format, ...) |
{ |
va_list args; |
|
va_start( args, format ); |
return print( 0, format, args ); |
} |
|
/** Replacement for standard sprintf. */ |
int sprintf(char *out, const char *format, ...) |
{ |
va_list args; |
|
va_start( args, format ); |
return print( &out, format, args ); |
} |
|
/**Replacement for standard snprintf. */ |
int snprintf( char *buf, unsigned int count, const char *format, ... ) |
{ |
va_list args; |
|
( void ) count; |
|
va_start( args, format ); |
return print( &buf, format, args ); |
} |
|
|
#ifdef TEST_PRINTF |
int main(void) |
{ |
#if 1 |
char *ptr = "Hello world!"; |
char *np = 0; |
int i = 5; |
unsigned int bs = sizeof(int)*8; |
int mi; |
char buf[80]; |
|
mi = (1 << (bs-1)) + 1; |
printf("%s\n", ptr); |
printf("printf test\n"); |
printf("%s is null pointer\n", np); |
printf("%d = 5\n", i); |
printf("%d = - max int\n", mi); |
printf("char %c = 'a'\n", 'a'); |
printf("hex %x = ff\n", 0xff); |
printf("hex %02x = 00\n", 0); |
printf("signed %d = unsigned %u = hex %x\n", -3, -3, -3); |
printf("%d %s(s)%", 0, "message"); |
printf("\n"); |
printf("%d %s(s) with %%\n", 0, "message"); |
sprintf(buf, "justif: \"%-10s\"\n", "left"); printf("%s", buf); |
sprintf(buf, "justif: \"%10s\"\n", "right"); printf("%s", buf); |
sprintf(buf, " 3: %04d zero padded\n", 3); printf("%s", buf); |
sprintf(buf, " 3: %-4d left justif.\n", 3); printf("%s", buf); |
sprintf(buf, " 3: %4d right justif.\n", 3); printf("%s", buf); |
sprintf(buf, "-3: %04d zero padded\n", -3); printf("%s", buf); |
sprintf(buf, "-3: %-4d left justif.\n", -3); printf("%s", buf); |
sprintf(buf, "-3: %4d right justif.\n", -3); printf("%s", buf); |
#endif |
return 0; |
} |
|
/* |
* if you compile this file with |
* gcc -Wall $(YOUR_C_OPTIONS) -DTEST_PRINTF -c printf.c |
* you will get a normal warning: |
* printf.c:214: warning: spurious trailing `%' in format |
* this line is testing an invalid % at the end of the format string. |
* |
* this should display (on 32bit int machine) : |
* |
* Hello world! |
* printf test |
* (null) is null pointer |
* 5 = 5 |
* -2147483647 = - max int |
* char a = 'a' |
* hex ff = ff |
* hex 00 = 00 |
* signed -3 = unsigned 4294967293 = hex fffffffd |
* 0 message(s) |
* 0 message(s) with % |
* justif: "left " |
* justif: " right" |
* 3: 0003 zero padded |
* 3: 3 left justif. |
* 3: 3 right justif. |
* -3: -003 zero padded |
* -3: -3 left justif. |
* -3: -3 right justif. |
*/ |
|
#endif |
|
|
/** Stub function, only used to deceive the linker. */ |
/* To keep linker happy. */ |
int write( int i, char* c, int n) |
{ |
return 0; |
} |
|
/src/common/libsoc/src/soc.c
0,0 → 1,89
/** |
@file soc.c |
@brief Supporting functions that do not warrant their own file. |
|
@bug Any attempt to use gets() or puts() triggers a linker error (undefined |
reference to '_impure_ptr') in this file, despite the fact that this |
file does not reference those symbols; newlib's gets and puts DO, and |
the linker is somehow getting confused. |
Right now I have no idea how to sort that out. |
*/ |
|
#include <stdint.h> |
#include <stdio.h> |
|
#include "soc.h" |
|
/* Linker-defined symbols usd to access the data section */ |
extern char data_start []; /**< Where .data section should be in RAM */ |
extern char data_load_start []; /**< Where .data section is in ROM */ |
extern char data_size []; /**< Size of .data section */ |
|
|
/*-- Non-standard utility functions ------------------------------------------*/ |
|
/** Return time elapsed since the last HW reset in clock cycles */ |
unsigned ctime(void){ |
unsigned cycles; |
|
cycles = *((volatile unsigned *)0x20000100); |
return cycles; |
} |
|
/** Copies .data sections (initialized data) from ROM to RAM. |
Will be called from the startup code IIF the program was linked to run |
from FLASH. */ |
void copy_data_sections(void){ |
uint32_t i; |
/* Move data section image from flash to RAM */ |
if (data_start != data_load_start){ |
for(i=0;i<(uint32_t)data_size;i++){ |
data_start[i] = data_load_start[i]; |
} |
} |
} |
|
|
/*-- Libc replacement functions ----------------------------------------------*/ |
|
/** Write character to console; replacement for standard puts. |
Uses no buffering. */ |
int puts(const char *string){ |
while(*string){ |
/* Implicit CR with every NL if requested */ |
if(IMPLICIT_CR_WITH_NL & (*string == '\n')){ |
putchar('\r'); |
} |
putchar(*string++); |
} |
/* A newline character is appended to the output. */ |
if(IMPLICIT_CR_WITH_NL & (*string == '\n')){ |
putchar('\r'); |
} |
putchar('\n'); |
|
return 0; /* on success return anything non-negative */ |
} |
|
/** Read character from console, blocking; replacement for standard puts. |
Uses no buffering. */ |
char *gets (char *str){ |
uint32_t i=0; |
char c; |
|
while(1){ |
c = getchar(); |
|
if(c=='\0'){ |
break; |
} |
else if(c=='\n' || c=='\r'){ |
break; |
} |
else{ |
str[i++] = c; |
} |
} |
str[i] = '\0'; |
return str; |
} |
/src/common/libsoc/src/soc.h
0,0 → 1,38
/** |
@file soc.h |
@brief |
|
This mini-library is meant for use in systems where no underlying OS or |
even a libc is available. |
|
The usual toolchains for MIPS (e.g. CodeSourcery) ship with precompiled |
libraries that target the MIPS32 architecture and are not easily useable |
on the Ion CPU core (which is compatible to an R3000). This code is intended |
to replace libc entirely in applications that don't demand the whole POSIX |
package. |
|
@note SOC conventionally stands for System On a Chip. |
*/ |
|
#ifndef SOC_H_INCLUDED |
#define SOC_H_INCLUDED |
|
#include <stdint.h> |
|
/*-- Library options ---------------------------------------------------------*/ |
|
/** !=0 to print a CR after each NL automatically */ |
#define IMPLICIT_CR_WITH_NL (1) |
|
|
/*-- Functions not present in libc -------------------------------------------*/ |
|
/** Return the time elapsed since last HW reset in clock cycles */ |
unsigned ctime(void); |
|
/** Copy initialized '.data' sections from ROM to RAM. |
This function relies on symbols defined by the kernel script. |
*/ |
void copy_data_sections(void); |
|
#endif // SOC_H_INCLUDED |
/src/common/libsoc/src/syscalls.c
0,0 → 1,62
/* |
syscalls.c -- Hardware-dependent functions for CodeSourcery libraries. |
|
These are just stubs meant to keep the compiler happy. Once I find out how |
to exclude newlib stuff from the compilation, thses functions will be |
removed. |
*/ |
|
#include <sys/stat.h> |
|
|
int close(int file){ |
return -1; |
} |
|
int fstat(int file, struct stat *st){ |
st->st_mode = S_IFCHR; |
return 0; |
} |
|
int isatty(int file){ |
return 1; |
} |
|
int lseek(int file, int ptr, int dir){ |
return 0; |
} |
|
int open(const char *name, int flags, int mode){ |
return -1; |
} |
|
int read(int file, char *ptr, int len){ |
/* use gets() to read from console */ |
return 0; |
} |
|
char *heap_end = 0; |
|
/* Stub -- broken -- do not use */ |
caddr_t sbrk(int incr){ |
//extern char heap_low; /* Defined by the linker */ |
//extern char heap_top; /* Defined by the linker */ |
char *prev_heap_end; |
|
if (heap_end == 0){ |
heap_end = (char *)0x00010000; //&heap_low; |
} |
prev_heap_end = heap_end; |
|
if ((unsigned)(heap_end + incr) > 0x00020000 /*&heap_top */){ |
/* Heap and stack collision */ |
return (caddr_t)0; |
} |
|
heap_end += incr; |
return (caddr_t) prev_heap_end; |
} |
|
int write(int file, char *ptr, int len){ |
puts(ptr); |
} |
/src/common/libsoc/makefile
0,0 → 1,46
|
#-- Set up toolchain -- modify as needed --------------------------------------- |
|
BIN_MIPS = C:/dev/embedded/SourceryGpp/mips-elf-11-03.52/bin |
CC = $(BIN_MIPS)/mips-sde-elf-gcc.exe $(CFLAGS) |
AS = $(BIN_MIPS)/mips-sde-elf-as |
AR = $(BIN_MIPS)/mips-sde-elf-ar |
LD = $(BIN_MIPS)/mips-sde-elf-ld |
DUMP = $(BIN_MIPS)/mips-sde-elf-objdump |
COPY = $(BIN_MIPS)/mips-sde-elf-objcopy |
|
|
#-- Common variables ----------------------------------------------------------- |
|
CFLAGS = -O2 -Wall -c -s -fno-builtin -nostdlib -nodefaultlibs \ |
-msoft-float -mips1 -G0 |
|
#-- IMPORTANT: List of object files to be included in the library |
OBJS = hw_ion_mpu.o soc.o syscalls.o printf-stdarg.o |
|
SRC = ./src |
|
#-- Targets & rules ------------------------------------------------------------ |
|
libsoc.a: $(OBJS) |
$(AR) rvs libsoc.a $(OBJS) |
# -@$(DUMP) -m mips --disassemble soc.o > soc.lst |
|
soc.o: $(SRC)/soc.h |
printf-stdarg.o: |
syscalls.o: $(SRC)/soc.h |
hw_ion_mpu.o: $(SRC)/soc.h $(SRC)/hw.h |
|
|
#-- Let's make some implicit rules explicit for clarity (well, 'clarity') |
|
%.o: $(SRC)/%.c |
$(CC) $(CFLAGS) $< -o $@ |
|
#-- And now the usual housekeeping stuff --------------------------------------- |
|
.PHONY: clean |
|
clean: |
-$(RM) *.o *.obj *.map *.lst *.hex *.exe *.axf *.code *.data *.bin |
|