mirror of https://github.com/flysand7/ciabatta.git
TinyRT abstraction layer
This commit is contained in:
parent
42e9d208fb
commit
d49add907c
|
@ -12,5 +12,6 @@ a.out
|
||||||
*.o
|
*.o
|
||||||
*.4coder
|
*.4coder
|
||||||
*.rdbg
|
*.rdbg
|
||||||
|
*.iface.h
|
||||||
test/
|
test/
|
||||||
test_folder/
|
test_folder/
|
34
build.lua
34
build.lua
|
@ -97,10 +97,43 @@ function prefix_quote(prefix)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Generate TinyRT interface file for the platform
|
||||||
|
print('==> Generating TinyRT interface definitions')
|
||||||
|
local tinyrt_manifest_path = path.join('src', platform, 'tinyrt.mf')
|
||||||
|
if not path.exists(tinyrt_manifest_path) then
|
||||||
|
print('ERROR: tinyrt manifest wasnt found: '..tinyrt_manifest_path)
|
||||||
|
end
|
||||||
|
tinyrt_iface_hdr = io.open(path.join('src', platform, 'tinyrt.iface.h'), 'wb')
|
||||||
|
tinyrt_iface_hdr:write('\n')
|
||||||
|
tinyrt_iface_hdr:write('// This file is AUTO-GENERATED\n')
|
||||||
|
tinyrt_iface_hdr:write('// See tinyrt.mf\n')
|
||||||
|
tinyrt_iface_hdr:write('\n')
|
||||||
|
n = 1
|
||||||
|
for line in io.lines(tinyrt_manifest_path) do
|
||||||
|
if line:len() ~= 0 and line:sub(1,1) ~= '#' and line:gsub('%s+', '') ~= '' then
|
||||||
|
local line_it = line:gmatch('[a-zA-Z0-9]+')
|
||||||
|
local api_name = line_it():upper()
|
||||||
|
local has_impl = line_it()
|
||||||
|
if has_impl == '0' or has_impl == '1' then
|
||||||
|
if has_impl == '1' then
|
||||||
|
local api_define = '#define RT_API_' .. api_name .. '\n'
|
||||||
|
tinyrt_iface_hdr:write(api_define)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
print('SYNTAX ERROR AT LINE '..i..': Expected 1 or 0 for the value')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
n = n+1
|
||||||
|
end
|
||||||
|
io.close(tinyrt_iface_hdr)
|
||||||
|
|
||||||
|
-- Figure out compiler flags
|
||||||
local cflags = table.concat(compiler_flags, ' ')..' '..
|
local cflags = table.concat(compiler_flags, ' ')..' '..
|
||||||
table.concat(map(compiler_defines, prefix('-D ')), ' ')..' '..
|
table.concat(map(compiler_defines, prefix('-D ')), ' ')..' '..
|
||||||
table.concat(map(includes, prefix_quote('-I ')), ' ')..' '
|
table.concat(map(includes, prefix_quote('-I ')), ' ')..' '
|
||||||
|
|
||||||
|
print('==> Compiling ciabatta')
|
||||||
print('Flags: ' .. cflags)
|
print('Flags: ' .. cflags)
|
||||||
|
|
||||||
-- Functions for compiling, linking and assembling individual files
|
-- Functions for compiling, linking and assembling individual files
|
||||||
|
@ -130,6 +163,7 @@ function archive(srcs, out)
|
||||||
os.execute(cmdline)
|
os.execute(cmdline)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Build ciabatta
|
||||||
path.mkdir('lib')
|
path.mkdir('lib')
|
||||||
path.mkdir('bin')
|
path.mkdir('bin')
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,11 @@ typedef unsigned int uint32_t;
|
||||||
#error "Platform not implemented"
|
#error "Platform not implemented"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// stdbool.h
|
||||||
|
typedef _Bool bool;
|
||||||
|
#define true ((bool)1)
|
||||||
|
#define false ((bool)0)
|
||||||
|
|
||||||
// Short type definitions
|
// Short type definitions
|
||||||
typedef int8_t i8;
|
typedef int8_t i8;
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
|
|
|
@ -3,5 +3,12 @@
|
||||||
|
|
||||||
#if os_is_linux()
|
#if os_is_linux()
|
||||||
#include "linux/syscall.c"
|
#include "linux/syscall.c"
|
||||||
|
#include "linux/errno.c"
|
||||||
#include "linux/entry.c"
|
#include "linux/entry.c"
|
||||||
|
// TinyRT interface
|
||||||
|
#include "linux/tinyrt.iface.h"
|
||||||
|
#include "tinyrt.h"
|
||||||
|
#include "linux/tinyrt.c"
|
||||||
|
#elif os_is_windows()
|
||||||
|
#error "Not implemented yet"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,6 +24,6 @@ void __libc_start_main(
|
||||||
main(argc, argv, envp);
|
main(argc, argv, envp);
|
||||||
fini();
|
fini();
|
||||||
// glibc bug
|
// glibc bug
|
||||||
dl_fini();
|
// dl_fini();
|
||||||
syscall_exit(0);
|
syscall_exit(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
|
||||||
|
#define EPERM 1 /* Operation not permitted */
|
||||||
|
#define ENOENT 2 /* No such file or directory */
|
||||||
|
#define ESRCH 3 /* No such process */
|
||||||
|
#define EINTR 4 /* Interrupted system call */
|
||||||
|
#define EIO 5 /* Input/output error */
|
||||||
|
#define ENXIO 6 /* Device not configured */
|
||||||
|
#define E2BIG 7 /* Argument list too long */
|
||||||
|
#define ENOEXEC 8 /* Exec format error */
|
||||||
|
#define EBADF 9 /* Bad file descriptor */
|
||||||
|
#define ECHILD 10 /* No child processes */
|
||||||
|
#define EDEADLK 11 /* Resource deadlock avoided */
|
||||||
|
#define ENOMEM 12 /* Cannot allocate memory */
|
||||||
|
#define EACCES 13 /* Permission denied */
|
||||||
|
#define EFAULT 14 /* Bad address */
|
||||||
|
#define EBUSY 16 /* Device busy */
|
||||||
|
#define EEXIST 17 /* File exists */
|
||||||
|
#define EXDEV 18 /* Cross-device link */
|
||||||
|
#define ENODEV 19 /* Operation not supported by device */
|
||||||
|
#define ENOTDIR 20 /* Not a directory */
|
||||||
|
#define EISDIR 21 /* Is a directory */
|
||||||
|
#define EINVAL 22 /* Invalid argument */
|
||||||
|
#define ENFILE 23 /* Too many open files in system */
|
||||||
|
#define EMFILE 24 /* Too many open files */
|
||||||
|
#define ENOTTY 25 /* Inappropriate ioctl for device */
|
||||||
|
#define ETXTBSY 26 /* Text file busy */
|
||||||
|
#define EFBIG 27 /* File too large */
|
||||||
|
#define ENOSPC 28 /* No space left on device */
|
||||||
|
#define ESPIPE 29 /* Illegal seek */
|
||||||
|
#define EROFS 30 /* Read-only file system */
|
||||||
|
#define EMLINK 31 /* Too many links */
|
||||||
|
#define EPIPE 32 /* Broken pipe */
|
||||||
|
#define EDOM 33 /* Numerical argument out of domain */
|
||||||
|
#define ERANGE 34 /* Result too large */
|
||||||
|
#define EAGAIN 35 /* Resource temporarily unavailable */
|
||||||
|
#define EWOULDBLOCK 35 /* Operation would block */
|
||||||
|
#define EINPROGRESS 36 /* Operation now in progress */
|
||||||
|
#define EALREADY 37 /* Operation already in progress */
|
||||||
|
#define ENOTSOCK 38 /* Socket operation on non-socket */
|
||||||
|
#define EDESTADDRREQ 39 /* Destination address required */
|
||||||
|
#define EMSGSIZE 40 /* Message too long */
|
||||||
|
#define EPROTOTYPE 41 /* Protocol wrong type for socket */
|
||||||
|
#define ENOPROTOOPT 42 /* Protocol not available */
|
||||||
|
#define EPROTONOSUPPORT 43 /* Protocol not supported */
|
||||||
|
#define EOPNOTSUPP 45 /* Operation not supported */
|
||||||
|
#define EAFNOSUPPORT 47 /* Address family not supported by protocol family */
|
||||||
|
#define EADDRINUSE 48 /* Address already in use */
|
||||||
|
#define EADDRNOTAVAIL 49 /* Can't assign requested address */
|
||||||
|
#define ENETDOWN 50 /* Network is down */
|
||||||
|
#define ENETUNREACH 51 /* Network is unreachable */
|
||||||
|
#define ENETRESET 52 /* Network dropped connection on reset */
|
||||||
|
#define ECONNABORTED 53 /* Software caused connection abort */
|
||||||
|
#define ECONNRESET 54 /* Connection reset by peer */
|
||||||
|
#define ENOBUFS 55 /* No buffer space available */
|
||||||
|
#define EISCONN 56 /* Socket is already connected */
|
||||||
|
#define ENOTCONN 57 /* Socket is not connected */
|
||||||
|
#define ETIMEDOUT 60 /* Operation timed out */
|
||||||
|
#define ECONNREFUSED 61 /* Connection refused */
|
||||||
|
#define ELOOP 62 /* Too many levels of symbolic links */
|
||||||
|
#define ENAMETOOLONG 63 /* File name too long */
|
||||||
|
#define EHOSTUNREACH 65 /* No route to host */
|
||||||
|
#define ENOTEMPTY 66 /* Directory not empty */
|
||||||
|
#define EDQUOT 69 /* Disk quota exceeded */
|
||||||
|
#define ENOLCK 77 /* No locks available */
|
||||||
|
#define ENOSYS 78 /* Function not implemented */
|
||||||
|
#define EILSEQ 84 /* Illegal byte sequence */
|
||||||
|
#define EOVERFLOW 87 /* Value too large to be stored in data type */
|
||||||
|
#define ECANCELED 88 /* Operation canceled */
|
||||||
|
#define EIDRM 89 /* Identifier removed */
|
||||||
|
#define ENOMSG 90 /* No message of desired type */
|
||||||
|
#define ENOTSUP 91 /* Not supported */
|
||||||
|
#define EBADMSG 92 /* Bad message */
|
||||||
|
#define ENOTRECOVERABLE 93 /* State not recoverable */
|
||||||
|
#define EOWNERDEAD 94 /* Previous owner died */
|
||||||
|
#define EPROTO 95 /* Protocol error */
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
|
||||||
|
// See src/tinyrt.h file for the interface this file implements
|
||||||
|
|
||||||
|
static RT_Status rt_file_open(RT_File *file, char *name, int rt_flags) {
|
||||||
|
if((rt_flags & 0x3) == 0) {
|
||||||
|
return RT_ERROR_BAD_PARAM;
|
||||||
|
}
|
||||||
|
int mode = 0;
|
||||||
|
int flags = 0;
|
||||||
|
if((rt_flags & 0x03) == 0x03) mode = O_RDWR;
|
||||||
|
else if(rt_flags & RT_FILE_READ) mode = O_RDONLY;
|
||||||
|
else if(rt_flags & RT_FILE_WRITE) mode = O_RDWR;
|
||||||
|
if(rt_flags & RT_FILE_CREATE) flags |= O_CREAT;
|
||||||
|
if(rt_flags & RT_FILE_EXCLUSIVE) flags |= O_EXCL;
|
||||||
|
if(rt_flags & RT_FILE_TRUNCATE) flags |= O_TRUNC;
|
||||||
|
i64 fd = syscall_open(name, flags, mode);
|
||||||
|
if(-fd == EACCES) return RT_STATUS_FILE_ACCESS;
|
||||||
|
if(-fd == EEXIST) return RT_STATUS_FILE_EXISTS;
|
||||||
|
if(-fd == ENOENT) return RT_STATUS_FILE_NOT_EXISTS;
|
||||||
|
if(-fd == EINVAL) return RT_ERROR_BAD_PARAM;
|
||||||
|
if(-fd == EISDIR) return RT_STATUS_FILE_DIRECTORY;
|
||||||
|
// I'm too lazy to fill in the rest so lets leave it at that for now
|
||||||
|
if(fd < 0) return RT_STATUS_FILE_IO_ERROR;
|
||||||
|
file->fd = (u64)fd;
|
||||||
|
file->flags = rt_flags;
|
||||||
|
return RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RT_Status rt_file_read(u64 size, void *buffer, RT_File *from, u64 *out_bytes_read) {
|
||||||
|
i64 bytes_read = syscall_read(from->fd, buffer, size);
|
||||||
|
if(bytes_read == 0) {
|
||||||
|
return RT_STATUS_FILE_EOF;
|
||||||
|
}
|
||||||
|
if(bytes_read < 0) {
|
||||||
|
return RT_STATUS_FILE_IO_ERROR;
|
||||||
|
}
|
||||||
|
*out_bytes_read = bytes_read;
|
||||||
|
return RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RT_Status rt_file_write(RT_File *to, u64 size, void *buffer, u64 *out_bytes_written) {
|
||||||
|
i64 bytes_written = syscall_write(to->fd, buffer, size);
|
||||||
|
if(bytes_written < 0) {
|
||||||
|
return RT_STATUS_FILE_IO_ERROR;
|
||||||
|
}
|
||||||
|
*out_bytes_written = bytes_written;
|
||||||
|
return RT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RT_Status rt_file_close(RT_File *file) {
|
||||||
|
i64 result = syscall_close(file->fd);
|
||||||
|
if(result < 0) {
|
||||||
|
return RT_STATUS_FILE_IO_ERROR;
|
||||||
|
}
|
||||||
|
return RT_STATUS_OK;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
# This file contains TinyRT API subsets that are exported
|
||||||
|
# for this operating system, one name per line. This file
|
||||||
|
# is used in a build script to generate tinyrt_macro file
|
||||||
|
# and to resolve higher-level API dependencies
|
||||||
|
|
||||||
|
# For example file = 1 means that the file API is
|
||||||
|
# implemented on this operating system and during building
|
||||||
|
# a header file will be generated containing definition of
|
||||||
|
# the form
|
||||||
|
# #define RT_API_FILE
|
||||||
|
|
||||||
|
file = 1
|
|
@ -0,0 +1,58 @@
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cia_definitions.h>
|
||||||
|
|
||||||
|
// Common errors
|
||||||
|
#define RT_STATUS_OK 0 // No errors
|
||||||
|
#define RT_ERROR_NOT_IMPLEMENTED -1 // Function not implemented
|
||||||
|
#define RT_ERROR_BAD_PARAM -2 // One of the function parameters was wrong
|
||||||
|
|
||||||
|
// File API errors
|
||||||
|
#define RT_STATUS_FILE_ACCESS 1 // No access to the file
|
||||||
|
#define RT_STATUS_FILE_NO_SPACE 2 // Storage device has no space for the file
|
||||||
|
#define RT_STATUS_FILE_EXISTS 3 // File exists when shouldn't
|
||||||
|
#define RT_STATUS_FILE_NOT_EXISTS 4 // File doesn't exist when should
|
||||||
|
#define RT_STATUS_FILE_DIRECTORY 5 // The file was a directory when shouldn't've been
|
||||||
|
#define RT_STATUS_FILE_NOT_DIRECTORY 6 // The file wasn't a directory when should've been
|
||||||
|
#define RT_STATUS_FILE_NAME_TOO_LONG 7 // The filename was too long for the Filesystem
|
||||||
|
#define RT_STATUS_FILE_LOOP 8 // Too many symlinks followed or a symlink encountered when expected none
|
||||||
|
#define RT_STATUS_FILE_BUSY 9 // The device is busy if exclusive access is requested
|
||||||
|
#define RT_STATUS_FILE_TOO_MANY_OPEN 10 // Too many open files in the process
|
||||||
|
#define RT_STATUS_FILE_NO_MEMORY 11 // No kernel memory or user limit on memory allocation exceeded
|
||||||
|
#define RT_STATUS_FILE_IO_ERROR 12 // I/O error
|
||||||
|
#define RT_STATUS_FILE_BAD_FILE 13 // Bad file handle
|
||||||
|
#define RT_STATUS_FILE_EOF 14 // Read operation reached the end-of-file
|
||||||
|
|
||||||
|
// File API flags
|
||||||
|
#define RT_FILE_READ 0x01
|
||||||
|
#define RT_FILE_WRITE 0x02
|
||||||
|
#define RT_FILE_CREATE 0x04
|
||||||
|
#define RT_FILE_EXCLUSIVE 0x08
|
||||||
|
#define RT_FILE_TRUNCATE 0x10
|
||||||
|
|
||||||
|
typedef i32 RT_Status;
|
||||||
|
|
||||||
|
// API implementation flags (managed and used by the layers on top of tinyrt)
|
||||||
|
static bool _rt_api_file;
|
||||||
|
static bool _rt_api_tmpfile;
|
||||||
|
|
||||||
|
// Initialization & termination of minirt
|
||||||
|
static RT_Status rt_init();
|
||||||
|
static RT_Status rt_deinit();
|
||||||
|
|
||||||
|
// File API
|
||||||
|
#if defined(RT_API_FILE)
|
||||||
|
struct RT_File typedef RT_File;
|
||||||
|
struct RT_File {
|
||||||
|
union {
|
||||||
|
void *handle;
|
||||||
|
u64 fd;
|
||||||
|
};
|
||||||
|
i32 flags;
|
||||||
|
};
|
||||||
|
static RT_Status rt_file_open(RT_File *file, char *name, int flags);
|
||||||
|
static RT_Status rt_file_read(u64 size, void *buffer, RT_File *from, u64 *out_bytes_read);
|
||||||
|
static RT_Status rt_file_write(RT_File *to, u64 size, void *buffer, u64 *out_bytes_written);
|
||||||
|
static RT_Status rt_file_close(RT_File *file);
|
||||||
|
#endif
|
Loading…
Reference in New Issue