/* * This file is part of the ReonV distribution (https://github.com/lcbcFoo/ReonV). * Copyright (c) 2018 to Lucas C. B. Castro. * * This program 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, version 3. * * 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* Author: Lucas C. B. Castro * Description: This file contains minimal implementations of some posix * functions for ReonV. */ #include #include "reonv.h" #include "mini_printf.h" #define POSIC_C #include "posix_c.h" // External char* console_buffer; // Internal static char* heap; char* out_mem; static LEON23_APBUART_Regs_Map *uart_regs; /* 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; if (uart_regs){ while (len-- != 0){ ch = *p++; if (uart_regs){ loops = 0; while (!((uart_regs->status >> 24) & LEON_REG_UART_STATUS_THE) && (loops < UART_TIMEOUT)) loops++; // Moves byte to beginning of TX buffer unsigned int outdata = (unsigned int) ch; outdata <<= 24; uart_regs->data = outdata; loops = 0; while (!((uart_regs->status >> 24) & LEON_REG_UART_STATUS_TSE) && (loops < UART_TIMEOUT)) loops++; } } } return p - fmt; //--------------------- } void _init_reonv(){ uart_regs = (LEON23_APBUART_Regs_Map*) 0x80000100; heap = (char*) HEAP_START; out_mem = (char*)OUT_MEM_BEGIN; console_buffer = (char*) sbrk(CONSOLE_BUFFER_SIZE); } int memcmp(const void* s1, const void* s2,size_t n){ const unsigned char *p1 = s1, *p2 = s2; while(n--) if( *p1 != *p2 ) return *p1 - *p2; else p1++,p2++; return 0; } void *memcpy(void *dest, const void *src, unsigned int n){ for(int i = 0; i < n; i++){ *((char*)dest++) = *((char*)src++); } } // Exit application void _exit(int status) { __asm("ebreak"); while(1); } // Repositions the offset of memory section (no file descriptor implemented) int _lseek( int fd, int offset, int whence ) { if(whence == SEEK_SET) out_mem = (char*) (OUT_MEM_BEGIN + offset); else if(whence == SEEK_CUR) out_mem = (char*) (out_mem + offset); else if(whence == SEEK_END) out_mem = (char*) (OUT_MEM_END + offset); else return -1; if(out_mem < (char*) OUT_MEM_BEGIN) return -1; else if(out_mem > (char*) OUT_MEM_END) return -1; return out_mem - (char*) OUT_MEM_BEGIN; } // Read from output memory section (no file descriptor implemented) int _read( int fd, char *buffer, int len ) { int i; for(i = 0; (i < len) && (&out_mem[i] < (char*)OUT_MEM_END); i++){ buffer[i] = out_mem[i]; } out_mem += i; return i; } // Write to output memory section (no file descriptor implemented) int _write( int fd, char *buffer, int len ) { int i; if(fd == STDOUT_FILENO){ return send_uart(buffer, len); } for(i = 0; (i < len) && (&out_mem[i] < (char*)OUT_MEM_END); i++){ out_mem[i] = buffer[i]; } out_mem += i; return i; } // Open a file (no file descriptor implemented) int _open( const char *path, int flags, int mode ) { return 0; } // Close fd (no file descriptor implemented) int _close( int fd ) { return 0; } // Allocate space on heap void* _sbrk( int incr ) { void* addr = (void*) heap; heap += incr; // Keep heap byte aligned while((int)heap % 4 != 0) heap++; return addr; }