Fix kelvin libgloss and stack * Fix sp initialization * Fix _sbrk * Fix faulty exit * Fix _write to support printf Change-Id: I4f20d07b0b7681ffdd37dff7faac8e97ff221c4b
diff --git a/sw/device/lib/testing/test_framework/kelvin_gloss.c b/sw/device/lib/testing/test_framework/kelvin_gloss.c index f08e0f4..becd61a 100644 --- a/sw/device/lib/testing/test_framework/kelvin_gloss.c +++ b/sw/device/lib/testing/test_framework/kelvin_gloss.c
@@ -17,6 +17,7 @@ /* Syscall stubs for newlib on Kelvin */ #include <errno.h> #include <sys/stat.h> +#include <unistd.h> int _close(int file) { return -1; } @@ -34,33 +35,79 @@ return -1; } -int _write(int file, char* ptr, int len) { - errno = EBADF; - return -1; +#ifndef LOG_MAX_SZ +#define LOG_MAX_SZ 256 +#endif +// TODO(lundong): Handle stdout and stderr separately +int _write(int file, char* buf, int nbytes) { + static int _write_line_buffer_len = 0; + static char _write_line_buffer[LOG_MAX_SZ]; + + if (file != STDOUT_FILENO && file != STDERR_FILENO) { + errno = EBADF; + return -1; + } + + if (nbytes <= 0) { + return 0; + } + + if (buf == NULL) { + errno = EFAULT; + return -1; + } + + int bytes_read = 0; + char c; + do { + int len = _write_line_buffer_len; + c = *(buf++); + bytes_read++; + + _write_line_buffer[len++] = c; + if (len == LOG_MAX_SZ - 1 || c == '\n') { + _write_line_buffer[len] = '\0'; + } + if ((_write_line_buffer[len] == '\0')) { + asm volatile("flog %0" : : "r"(_write_line_buffer)); + len = 0; + } + _write_line_buffer_len = len; + } while (bytes_read < nbytes); + + return bytes_read; } int _open(const char* path, int flags, ...) { return -1; } void _exit(int status) { + asm volatile("ebreak"); while (1) { } } -int _kill(int pid, int sig) { return -1; } +int _kill(int pid, int sig) { + asm volatile("ebreak"); + return -1; +} -int _getpid(void) { return -1; } +int _getpid(void) { + asm volatile("ebreak"); + return -1; +} +char* _heap_ptr; // Set to __heap_start__ in kelvin_start.S // Based on newlib's nosys sbrk void* _sbrk(int bytes) { extern char __heap_end__; - static char* heap_end; char* prev_heap_end; - - if (heap_end == 0) { - heap_end = &__heap_end__; + if ((bytes < 0) || (_heap_ptr + bytes > &__heap_end__)) { + errno = ENOMEM; + return (void*)-1; } - prev_heap_end = heap_end; - heap_end += bytes; + + prev_heap_end = _heap_ptr; + _heap_ptr += bytes; return (void*)prev_heap_end; }
diff --git a/sw/device/lib/testing/test_framework/kelvin_start.S b/sw/device/lib/testing/test_framework/kelvin_start.S index 479b96c..568aec7 100644 --- a/sw/device/lib/testing/test_framework/kelvin_start.S +++ b/sw/device/lib/testing/test_framework/kelvin_start.S
@@ -25,7 +25,7 @@ ############################################### # Put all scalar registers into a known state # ############################################### - la sp, _stack_end + la sp, __stack_end__ la gp, _global_pointer mv tp, zero mv t1, zero @@ -59,6 +59,10 @@ la a1, __bss_end__ call crt_section_clear + # Initialize the heap ptr after clearing BSS + la s0, __heap_start__ + sw s0, _heap_ptr, s1 + # Initialize arrays la s0, __init_array_start la s1, __init_array_end
diff --git a/sw/device/tests/kelvin/kelvin_hello_world.c b/sw/device/tests/kelvin/kelvin_hello_world.c index 7109422..f3b2aaf 100644 --- a/sw/device/tests/kelvin/kelvin_hello_world.c +++ b/sw/device/tests/kelvin/kelvin_hello_world.c
@@ -18,12 +18,14 @@ #include <stddef.h> #include <stdint.h> +#include <stdio.h> const uint32_t kDataInput = 0x100000; const uint32_t kDataSize = 0x1000; int main(int argc, char *argv[]) { uint32_t *data = (uint32_t *)kDataInput; + printf("hello world!!\n"); for (uint32_t i = 0; i < kDataSize / sizeof(uint32_t); ++i) { data[i] += 1; }