diff options
Diffstat (limited to 'src/pdclib/platform')
-rw-r--r-- | src/pdclib/platform/stmos/functions/os/syscalls.c | 163 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/functions/stdio/remove.c | 79 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/functions/stdio/tmpfile.c | 124 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/functions/time/clock.c | 15 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/functions/time/time.c | 16 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/functions/time/timespec_get.c | 15 | ||||
-rw-r--r-- | src/pdclib/platform/stmos/include/syscalls.h | 53 |
7 files changed, 337 insertions, 128 deletions
diff --git a/src/pdclib/platform/stmos/functions/os/syscalls.c b/src/pdclib/platform/stmos/functions/os/syscalls.c new file mode 100644 index 0000000..a58dc50 --- /dev/null +++ b/src/pdclib/platform/stmos/functions/os/syscalls.c @@ -0,0 +1,163 @@ +#include "syscalls.h" + +// +// Task-related calls + +void _exit(int code) +{ + register uint32_t r1 __asm("r1") = code; + __asm("\ + mov r0, 0; \ + mov r1, %0; \ + svc 0; \ + " :: "r" (r1)); +} + +int fork(void) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = (uint32_t)&ret; + __asm("\ + mov r0, 1; \ + mov r1, %0; \ + svc 0; \ + " :: "r" (r1)); + return ret; +} + +int getpid(void) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = (uint32_t)&ret; + __asm("\ + mov r0, 2; \ + mov r1, %0; \ + svc 0; \ + " :: "r" (r1)); + return ret; +} + +void *sbrk(unsigned int bytes) +{ + void *ret = 0; + register uint32_t r1 __asm("r1") = bytes; + register uint32_t r2 __asm("r2") = (uint32_t)&ret; + __asm("\ + mov r0, 4; \ + mov r1, %0; \ + mov r2, %1; \ + svc 0; \ + " :: "r" (r1), "r" (r2)); + return ret; +} + +// +// Clock-related calls + +void delay(unsigned int ms) +{ + register uint32_t r1 __asm("r1") = ms; + __asm("\ + mov r0, 0; \ + mov r1, %0; \ + svc 2; \ + " :: "r" (r1)); +} + +unsigned int ticks(void) +{ + unsigned int ret = 0; + register uint32_t r1 __asm("r1") = (uint32_t)&ret; + __asm("\ + mov r0, 2; \ + mov r1, %0; \ + svc 2; \ + " :: "r" (r1)); + return ret; +} + +// +// File-related calls + +int mount(vfs_volume_funcs *funcs, uint32_t flags) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = (uint32_t)funcs; + register uint32_t r2 __asm("r2") = flags; + register uint32_t r3 __asm("r3") = (uint32_t)&ret; + __asm("\ + mov r0, 0; \ + mov r1, %0; \ + mov r2, %1; \ + mov r3, %2; \ + svc 3; \ + " :: "r" (r1), "r" (r2), "r" (r3)); + return ret; +} + +int open(const char *path, uint32_t flags) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = (uint32_t)path; + register uint32_t r2 __asm("r2") = flags; + register uint32_t r3 __asm("r3") = (uint32_t)&ret; + __asm("\ + mov r0, 1; \ + mov r1, %0; \ + mov r2, %1; \ + mov r3, %2; \ + svc 3; \ + " :: "r" (r1), "r" (r2), "r" (r3)); + return ret; +} + +int close(int fd) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = fd; + register uint32_t r2 __asm("r2") = (uint32_t)&ret; + __asm("\ + mov r0, 2; \ + mov r1, %0; \ + mov r2, %1; \ + svc 3; \ + " :: "r" (r1), "r" (r2)); + return ret; +} + +int read(int fd, uint32_t count, uint8_t *buffer) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = fd; + register uint32_t r2 __asm("r2") = count; + register uint32_t r3 __asm("r3") = (uint32_t)buffer; + register uint32_t r4 __asm("r4") = (uint32_t)&ret; + __asm("\ + mov r0, 3; \ + mov r1, %0; \ + mov r2, %1; \ + mov r3, %2; \ + mov r4, %3; \ + svc 3; \ + " :: "r" (r1), "r" (r2), "r" (r3), "r" (r4)); + return ret; +} + +int write(int fd, uint32_t count, const uint8_t *buffer) +{ + int ret = 0; + register uint32_t r1 __asm("r1") = fd; + register uint32_t r2 __asm("r2") = count; + register uint32_t r3 __asm("r3") = (uint32_t)buffer; + register uint32_t r4 __asm("r4") = (uint32_t)&ret; + __asm("\ + mov r0, 4; \ + mov r1, %0; \ + mov r2, %1; \ + mov r3, %2; \ + mov r4, %3; \ + svc 3; \ + " :: "r" (r1), "r" (r2), "r" (r3), "r" (r4)); + return ret; +} + diff --git a/src/pdclib/platform/stmos/functions/stdio/remove.c b/src/pdclib/platform/stmos/functions/stdio/remove.c index aca3eaf..c1ed6a0 100644 --- a/src/pdclib/platform/stmos/functions/stdio/remove.c +++ b/src/pdclib/platform/stmos/functions/stdio/remove.c @@ -7,57 +7,58 @@ /* This is an example implementation of remove() fit for use with POSIX kernels. */ -#include <stdio.h> +#include <syscalls.h> #ifndef REGTEST -#include <string.h> +//#include <string.h> -#include "/usr/include/errno.h" +//#include "/usr/include/errno.h" extern struct _PDCLIB_file_t * _PDCLIB_filelist; -extern int unlink( const char * pathname ); +//extern int unlink( const char * pathname ); int remove( const char * pathname ) { - int rc; - struct _PDCLIB_file_t * current = _PDCLIB_filelist; - while ( current != NULL ) - { - if ( ( current->filename != NULL ) && ( strcmp( current->filename, pathname ) == 0 ) ) - { - return EOF; - } - current = current->next; - } - if ( ( rc = unlink( pathname ) ) == -1 ) - { - switch ( errno ) - { - /* See the comments on implementation-defined errno values in - <_PDCLIB_config.h>. - */ - case EACCES: - case EFAULT: - case EIO: - case EISDIR: - case ELOOP: - case ENAMETOOLONG: - case ENOENT: - case ENOMEM: - case ENOTDIR: - case EPERM: - case EROFS: - _PDCLIB_errno = _PDCLIB_ERROR; - break; - default: +// int rc; +// struct _PDCLIB_file_t * current = _PDCLIB_filelist; +// while ( current != NULL ) +// { +// if ( ( current->filename != NULL ) && ( strcmp( current->filename, pathname ) == 0 ) ) +// { +// return EOF; +// } +// current = current->next; +// } +// if ( ( rc = unlink( pathname ) ) == -1 ) +// { +// switch ( errno ) +// { +// /* See the comments on implementation-defined errno values in +// <_PDCLIB_config.h>. +// */ +// case EACCES: +// case EFAULT: +// case EIO: +// case EISDIR: +// case ELOOP: +// case ENAMETOOLONG: +// case ENOENT: +// case ENOMEM: +// case ENOTDIR: +// case EPERM: +// case EROFS: +// _PDCLIB_errno = _PDCLIB_ERROR; +// break; +// default: /* This should be something like EUNKNOWN. */ _PDCLIB_errno = _PDCLIB_ERROR; - break; - } - } - return rc; +// break; +// } +// } +// return rc; + return EOF; } #endif diff --git a/src/pdclib/platform/stmos/functions/stdio/tmpfile.c b/src/pdclib/platform/stmos/functions/stdio/tmpfile.c index 585a61d..f8a697b 100644 --- a/src/pdclib/platform/stmos/functions/stdio/tmpfile.c +++ b/src/pdclib/platform/stmos/functions/stdio/tmpfile.c @@ -4,20 +4,20 @@ Permission is granted to use, modify, and / or redistribute at will. */ -#include <stdio.h> +//#include <stdio.h> #ifndef REGTEST #include "pdclib/_PDCLIB_glue.h" -#include <inttypes.h> +//#include <inttypes.h> #include <stdlib.h> -#include <string.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> +//#include <string.h> +// +//#include <sys/types.h> +//#include <sys/stat.h> +//#include <fcntl.h> +//#include <unistd.h> extern struct _PDCLIB_file_t * _PDCLIB_filelist; @@ -26,61 +26,61 @@ extern struct _PDCLIB_file_t * _PDCLIB_filelist; */ struct _PDCLIB_file_t * tmpfile( void ) { - FILE * rc; - /* This is the chosen way to get high-quality randomness. Replace as - appropriate. - */ - FILE * randomsource = fopen( "/proc/sys/kernel/random/uuid", "rb" ); - char filename[ L_tmpnam ]; - _PDCLIB_fd_t fd; - if ( randomsource == NULL ) - { - return NULL; - } - for ( ;; ) - { - /* Get a filename candidate. What constitutes a valid filename and - where temporary files are usually located is platform-dependent, - which is one reason why this function is located in the platform - overlay. The other reason is that a *good* implementation should - use high-quality randomness instead of a pseudo-random sequence to - generate the filename candidate, which is *also* platform-dependent. - */ - unsigned int random; - fscanf( randomsource, "%u", &random ); - sprintf( filename, "/tmp/%u.tmp", random ); - /* Check if file of this name exists. Note that fopen() is a very weak - check, which does not take e.g. access permissions into account - (file might exist but not readable). Replace with something more - appropriate. - */ - fd = open( filename, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR ); - if ( fd != -1 ) - { - break; - } - close( fd ); - } - fclose( randomsource ); - /* See fopen(). */ - if ( ( rc = calloc( 1, sizeof( struct _PDCLIB_file_t ) + _PDCLIB_UNGETCBUFSIZE + L_tmpnam + BUFSIZ ) ) == NULL ) - { - /* No memory to set up FILE structure */ - close( fd ); +// FILE * rc; +// /* This is the chosen way to get high-quality randomness. Replace as +// appropriate. +// */ +// FILE * randomsource = fopen( "/proc/sys/kernel/random/uuid", "rb" ); +// char filename[ L_tmpnam ]; +// _PDCLIB_fd_t fd; +// if ( randomsource == NULL ) +// { return NULL; - } - rc->status = _PDCLIB_filemode( "wb+" ) | _IOLBF | _PDCLIB_DELONCLOSE; - rc->handle = fd; - rc->ungetbuf = (unsigned char *)rc + sizeof( struct _PDCLIB_file_t ); - rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE; - rc->buffer = rc->filename + L_tmpnam; - strcpy( rc->filename, filename ); - rc->bufsize = BUFSIZ; - rc->bufidx = 0; - rc->ungetidx = 0; - rc->next = _PDCLIB_filelist; - _PDCLIB_filelist = rc; - return rc; +// } +// for ( ;; ) +// { +// /* Get a filename candidate. What constitutes a valid filename and +// where temporary files are usually located is platform-dependent, +// which is one reason why this function is located in the platform +// overlay. The other reason is that a *good* implementation should +// use high-quality randomness instead of a pseudo-random sequence to +// generate the filename candidate, which is *also* platform-dependent. +// */ +// unsigned int random; +// fscanf( randomsource, "%u", &random ); +// sprintf( filename, "/tmp/%u.tmp", random ); +// /* Check if file of this name exists. Note that fopen() is a very weak +// check, which does not take e.g. access permissions into account +// (file might exist but not readable). Replace with something more +// appropriate. +// */ +// fd = open( filename, O_CREAT | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR ); +// if ( fd != -1 ) +// { +// break; +// } +// close( fd ); +// } +// fclose( randomsource ); +// /* See fopen(). */ +// if ( ( rc = calloc( 1, sizeof( struct _PDCLIB_file_t ) + _PDCLIB_UNGETCBUFSIZE + L_tmpnam + BUFSIZ ) ) == NULL ) +// { +// /* No memory to set up FILE structure */ +// close( fd ); +// return NULL; +// } +// rc->status = _PDCLIB_filemode( "wb+" ) | _IOLBF | _PDCLIB_DELONCLOSE; +// rc->handle = fd; +// rc->ungetbuf = (unsigned char *)rc + sizeof( struct _PDCLIB_file_t ); +// rc->filename = (char *)rc->ungetbuf + _PDCLIB_UNGETCBUFSIZE; +// rc->buffer = rc->filename + L_tmpnam; +// strcpy( rc->filename, filename ); +// rc->bufsize = BUFSIZ; +// rc->bufidx = 0; +// rc->ungetidx = 0; +// rc->next = _PDCLIB_filelist; +// _PDCLIB_filelist = rc; +// return rc; } #endif diff --git a/src/pdclib/platform/stmos/functions/time/clock.c b/src/pdclib/platform/stmos/functions/time/clock.c index 825e040..b7880af 100644 --- a/src/pdclib/platform/stmos/functions/time/clock.c +++ b/src/pdclib/platform/stmos/functions/time/clock.c @@ -8,16 +8,17 @@ #ifndef REGTEST -#include <sys/times.h> +#include <syscalls.h> clock_t clock( void ) { - struct tms buf; - if ( times( &buf ) != (clock_t)-1 ) - { - return buf.tms_utime + buf.tms_stime; - } - return -1; + return ticks(); +// struct tms buf; +// if ( times( &buf ) != (clock_t)-1 ) +// { +// return buf.tms_utime + buf.tms_stime; +// } +// return -1; } #endif diff --git a/src/pdclib/platform/stmos/functions/time/time.c b/src/pdclib/platform/stmos/functions/time/time.c index cbb29e1..814c925 100644 --- a/src/pdclib/platform/stmos/functions/time/time.c +++ b/src/pdclib/platform/stmos/functions/time/time.c @@ -8,22 +8,16 @@ #ifndef REGTEST -#include <sys/time.h> +#include <syscalls.h> /* See comments in time.h on the semantics of time_t. */ time_t time( time_t * timer ) { - struct timeval tv; - if ( gettimeofday( &tv, NULL ) == 0 ) - { - if ( timer != NULL ) - { - *timer = tv.tv_sec; - } - return tv.tv_sec; - } - return -1; + if ( timer != NULL ) + *timer = ticks(); + + return ticks(); } #endif diff --git a/src/pdclib/platform/stmos/functions/time/timespec_get.c b/src/pdclib/platform/stmos/functions/time/timespec_get.c index d8cbab7..df17f1a 100644 --- a/src/pdclib/platform/stmos/functions/time/timespec_get.c +++ b/src/pdclib/platform/stmos/functions/time/timespec_get.c @@ -8,21 +8,18 @@ #ifndef REGTEST -#include <sys/time.h> +#include <syscalls.h> int timespec_get( struct timespec * ts, int base ) { if ( base == TIME_UTC ) { - /* We can make do with a really thin wrapper here. */ - struct timeval tv; - if ( gettimeofday( &tv, NULL ) == 0 ) - { - ts->tv_sec = tv.tv_sec; - ts->tv_nsec = tv.tv_usec * 1000; - return base; - } + unsigned int t = ticks(); + ts->tv_sec = t / 1000; + ts->tv_nsec = t * 1000000; + return base; } + /* Not supporting any other time base than TIME_UTC for now. */ return 0; } diff --git a/src/pdclib/platform/stmos/include/syscalls.h b/src/pdclib/platform/stmos/include/syscalls.h new file mode 100644 index 0000000..2acb59c --- /dev/null +++ b/src/pdclib/platform/stmos/include/syscalls.h @@ -0,0 +1,53 @@ +#ifndef SYSCALLS_H_ +#define SYSCALLS_H_ + +#include <stdint.h> + +// +// Task-related calls + +void _exit(int code); + +int fork(void); +int getpid(void); +void *sbrk(unsigned int bytes); + +// +// Clock-related calls + +void delay(unsigned int ms); +unsigned int ticks(void); + +// +// File-related calls + +// Indicates mounted volume +#define VFS_MOUNTED (1 << 0) +// Set if filesystem is read-only +#define VFS_READONLY (1 << 1) + +// Indicates an opened file +#define VFS_FILE_OPEN (1 << 0) +// Indicates read permission on file +#define VFS_FILE_READ (1 << 1) +// Indicates write permission on file +#define VFS_FILE_WRITE (1 << 2) +// Set if EOF has been reached +#define VFS_EOF (1 << 3) + +#define EOF (-1) + +struct dirent { + char name[32]; +}; + +struct vfs_volume_funcs_t; +typedef struct vfs_volume_funcs_t vfs_volume_funcs; + +int mount(vfs_volume_funcs *funcs, uint32_t flags); +int open(const char *path, uint32_t flags); +int close(int fd); +int read(int fd, uint32_t count, uint8_t *buffer); +int write(int fd, uint32_t count, const uint8_t *buffer); + +#endif // SYSCALLS_H_ |