mirror of
https://git.planet-casio.com/Vhex-Kernel-Core/fxlibc.git
synced 2024-12-28 04:23:38 +01:00
project architecture rework + handle ABI specific code (WIP)
This commit is contained in:
parent
ac36fce54d
commit
aeedfcdb02
75 changed files with 1241 additions and 3819 deletions
35
include/asm-casio/__trapa.h
Normal file
35
include/asm-casio/__trapa.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef __ASM_CASIO_TRAPA_H__
|
||||
# define __ASM_CASIO_TRAPA_H__
|
||||
|
||||
/*
|
||||
** Normally the SH3/SH4 processor provide a "trapa" instruction which allow
|
||||
** tipping between userland and kernel. But Casio's don't use this method
|
||||
** (this is why we are always in "privilegied mode" and we can do whatever
|
||||
** we whant) but use custom calling convention to access the syscall call.
|
||||
**
|
||||
** The convention whant that the user jump into the syscall trampoline code
|
||||
** located at 0x80010070 for fx9860g and 0x80020070 for fxcg20/50.
|
||||
*/
|
||||
#ifdef __SUPPORT_CASIO_ABI_FX9860G
|
||||
# define casio_trapa(id) \
|
||||
mov.l syscall_table, r2 ;\
|
||||
mov.l syscall_id, r0 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
syscall_table: .long 0x80010070 ;\
|
||||
syscall_id: .long id
|
||||
#endif
|
||||
|
||||
#ifdef __SUPPORT_CASIO_ABI_FXCG50
|
||||
# define casio_trapa(id) \
|
||||
mov.l syscall_table, r2 ;\
|
||||
mov.l syscall_id, r0 ;\
|
||||
jmp @r2 ;\
|
||||
nop ;\
|
||||
.align 4 ;\
|
||||
syscall_table: .long 0x80020070 ;\
|
||||
syscall_id: .long id
|
||||
#endif
|
||||
|
||||
#endif /*__ASM__CASIO_TRAPA_H__*/
|
1
include/asm/unistd.h
Normal file
1
include/asm/unistd.h
Normal file
|
@ -0,0 +1 @@
|
|||
#include <asm/unistd_32.h>
|
|
@ -1,45 +1,13 @@
|
|||
#ifndef __ASM_UNISTD_32_H__
|
||||
# define __ASM_UNISTD_32_H__
|
||||
|
||||
// Define the number of syscall
|
||||
#define __NR_MAX 21
|
||||
|
||||
// Kernel Test
|
||||
#define __NR_test_syscall 0
|
||||
|
||||
// Process
|
||||
#define __NR_exit 1
|
||||
#define __NR_fork_execve 2 // (custom)
|
||||
#define __NR_waitpid 3
|
||||
#define __NR_wait 4
|
||||
#define __NR_getpid 5
|
||||
#define __NR_getppid 6
|
||||
#define __NR_getpgid 7
|
||||
#define __NR_setpgid 8
|
||||
|
||||
// Signal
|
||||
#define __NR_signal 9
|
||||
#define __NR_sigreturn 10
|
||||
#define __NR_sigaction 11
|
||||
#define __NR_kill 12
|
||||
#define __NR_sigprogmask 13
|
||||
#define __NR_sigpending 14
|
||||
#define __NR_sigaltstack 15
|
||||
|
||||
// VFS
|
||||
#define __NR_read 16
|
||||
#define __NR_write 17
|
||||
#define __NR_open 18
|
||||
#define __NR_close 19
|
||||
#define __NR_lseek 20
|
||||
#define __NR_pread 21
|
||||
#define __NR_pwrite 22
|
||||
|
||||
// Memory
|
||||
#define __NR_mmap 23
|
||||
#define __NR_munmap 24
|
||||
#define __NR_proc_heap_alloc 25 // (custom)
|
||||
#define __NR_proc_heap_free 26 // (custom)
|
||||
#define __NR_proc_heap_realloc 27 // (custom)
|
||||
// ABI redirection
|
||||
#if defined(__SUPPORT_VHEX_KERNEL)
|
||||
# include <vhex/unistd_32.h>
|
||||
#elif defined(__SUPPORT_CASIO_ABI_FX9860G)
|
||||
# include <fx9860g/unistd_32.h>
|
||||
#elif defined(__SUPPORT_CASIO_ABI_FXCG50)
|
||||
# include <fxcg50/unistd_32.h>
|
||||
#endif
|
||||
|
||||
#endif /*__ASM_UNISTD_32_H__*/
|
||||
|
|
8
include/bits/confname.h
Normal file
8
include/bits/confname.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef __BITS_CONFNAME_H__
|
||||
# define __BITS_CONFNAME_H__
|
||||
|
||||
//FIXME: this part is probably arch-specific(?)
|
||||
#define _SC_PAGE_SIZE 0
|
||||
#define _SC_PAGESIZE _SC_PAGE_SIZE
|
||||
|
||||
#endif /*__BITS_CONFNAME_H__*/
|
9
include/bits/fcntl.h
Normal file
9
include/bits/fcntl.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef __BITS_FCNTL_H__
|
||||
# define __BITS_FCNTL_H__
|
||||
|
||||
/* open/fcntl. */
|
||||
#define O_RDONLY 0
|
||||
#define O_WRONLY 1
|
||||
#define O_RDWR 2
|
||||
|
||||
#endif /*__BITS_FCNTL_H__*/
|
26
include/bits/setjmp.h
Normal file
26
include/bits/setjmp.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef __BITS_SETJMP_H__
|
||||
# define __BITS_SETJMP_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*
|
||||
** Custom(?) jmp_buf struct
|
||||
** @note: save only r8 ~ r15 and SR / PC registers
|
||||
** The SR register is saved first because the longjump can be involved with
|
||||
** different register bank. So to avoid this, it's more simple to restore the
|
||||
** saved SR first then restore all register (see <src/setjmp/longjmp.S>)
|
||||
**
|
||||
** TODO: save process signal mask ?
|
||||
*/
|
||||
struct __jmp_buf
|
||||
{
|
||||
uint32_t sr;
|
||||
uint32_t reg[8];
|
||||
uint32_t gbr;
|
||||
uint32_t macl;
|
||||
uint32_t mach;
|
||||
uint32_t pr;
|
||||
};
|
||||
|
||||
#endif /*__BITS_SETJMP_H__*/
|
12
include/bits/sigaction.h
Normal file
12
include/bits/sigaction.h
Normal file
|
@ -0,0 +1,12 @@
|
|||
#ifndef __BITS_SIGACTION_H__
|
||||
# define __BITS_SIGACTION_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/* Values for the HOW argument to `sigprocmask'. */
|
||||
#define SIG_BLOCK 0 /* Block signals. */
|
||||
#define SIG_UNBLOCK 1 /* Unblock signals. */
|
||||
#define SIG_SETMASK 2 /* Set the set of blocked signals. */
|
||||
|
||||
#endif /*__BITS_SIGACTION_H__*/
|
|
@ -1,9 +1,13 @@
|
|||
#ifndef __LIB_BITS_TYPES_FILE_H__
|
||||
# define __LIB_BITS_TYPES_FILE_H__
|
||||
#ifndef __BITS_TYPES_FILE_H__
|
||||
# define __BITS_TYPES_FILE_H__
|
||||
|
||||
// opaque definition of the _IO_FILE
|
||||
struct _IO_FILE;
|
||||
|
||||
/* The opaque type of streams. This is the definition used elsewhere. */
|
||||
/*
|
||||
** The opaque type of streams.
|
||||
** This is the definition used elsewhere.
|
||||
*/
|
||||
typedef struct _IO_FILE FILE;
|
||||
|
||||
#endif /*__LIB_BITS_TYPES_FILE_H__*/
|
||||
#endif /*__BITS_TYPES_FILE_H__*/
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#ifndef __LIB_BITS_TYPES___FILE_H__
|
||||
# define __LIB_BITS_TYPES___FILE_H__
|
||||
#ifndef __BITS_TYPES__FILE_H__
|
||||
# define ___LIB_BITS_TYPES__FILE_H__
|
||||
|
||||
// define opaque definition of the FILE type
|
||||
struct _IO_FILE;
|
||||
typedef struct _IO_FILE __FILE;
|
||||
|
||||
#endif /*__LIB_BITS_TYPES___FILE_H__*/
|
||||
#endif /*__BITS_TYPES__FILE_H__*/
|
||||
|
|
|
@ -5,10 +5,12 @@
|
|||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
//TODO: remove me !!!
|
||||
#include <kernel/bits/filesystem.h>
|
||||
//---
|
||||
// TODO: VFS abstraction ? or ABI-spesific abstraction ?
|
||||
//---
|
||||
|
||||
// Define _IO_FILE
|
||||
|
||||
// Define _IO_FILE
|
||||
// TODO: add open flags
|
||||
// TODO: add file descriptor ?
|
||||
// TODO: update me !
|
||||
|
@ -16,7 +18,7 @@ struct _IO_FILE
|
|||
{
|
||||
off_t cursor;
|
||||
int permission;
|
||||
struct file_operations *file_op;
|
||||
void *file_op;
|
||||
void *private;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
#ifndef __LIB_DISPLAY_H__
|
||||
# define __LIB_DISPLAY_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Internal struct used in each draw function
|
||||
typedef struct display_s
|
||||
{
|
||||
uint32_t vram[256];
|
||||
struct font_s *font;
|
||||
struct {
|
||||
size_t width;
|
||||
size_t height;
|
||||
} display;
|
||||
|
||||
// Internal pre-calculated value
|
||||
int nb_char_width;
|
||||
} display_t;
|
||||
|
||||
// Internal struct used to define font structure object.
|
||||
// TODO: move me ?
|
||||
struct font_s
|
||||
{
|
||||
// Bitmap informations
|
||||
struct {
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
uint8_t cwidth;
|
||||
uint8_t cheight;
|
||||
uint8_t *raw;
|
||||
} bitmap;
|
||||
|
||||
// Character information
|
||||
struct {
|
||||
uint8_t width;
|
||||
uint8_t height;
|
||||
} font;
|
||||
};
|
||||
|
||||
// Internal struct used to draw
|
||||
// the ASCII character.
|
||||
struct font_block_s
|
||||
{
|
||||
int16_t height;
|
||||
int16_t width;
|
||||
struct {
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
} bitmap;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
};
|
||||
|
||||
// Draw primitives
|
||||
extern int dopen(display_t *disp, const char *fontname);
|
||||
extern void dclear(display_t *disp);
|
||||
extern void dascii(display_t *disp, int row, int colomn, char const c, int mode);
|
||||
extern size_t dprint(display_t *disp, int x, int y, char const *str, ...);
|
||||
extern void dscroll(display_t *disp, int line);
|
||||
extern void dreverse(display_t *disp, int x, int y, int width, int height);
|
||||
extern void drect(display_t *disp, int x, int y, int width, int height);
|
||||
extern void dupdate(display_t *disp);
|
||||
|
||||
#endif /*__LIB_DISPLAY_H__*/
|
3350
include/elf.h
3350
include/elf.h
File diff suppressed because it is too large
Load diff
|
@ -4,17 +4,17 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//TODO: update me !!
|
||||
#define O_RDONLY 0
|
||||
#define O_WRONLY 1
|
||||
#define O_RDWR 2
|
||||
|
||||
//TODO: define also in <stdio.h>
|
||||
/* also defined in <stdio.h> */
|
||||
#define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
#define SEEK_CUR 1 /* Seek from current position. */
|
||||
#define SEEK_END 2 /* Seek from end of file. */
|
||||
|
||||
// Functions
|
||||
/*
|
||||
** Open FILE and return a new file descriptor for it, or -1 on error.
|
||||
** OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set
|
||||
** in OFLAG, the third argument is taken as a `mode_t', the mode of the
|
||||
** created file.
|
||||
*/
|
||||
extern int open(const char *pathname, int flags, ...);
|
||||
|
||||
#endif /*__LIB_FCNTL_H__*/
|
||||
|
|
57
include/fx9860g/unistd_32.h
Normal file
57
include/fx9860g/unistd_32.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
#ifndef __ASM_UNISTD32_FX9860G_H__
|
||||
# define __ASM_UNISTD32_FX9860G_H__
|
||||
|
||||
// File manipulation
|
||||
#define __NR_Bfile_CreateFile 0x00000434
|
||||
#define __NR_Bfile_OpenFile 0x0000042c
|
||||
#define __NR_Bfile_WriteFile 0x00000435
|
||||
#define __NR_Bfile_ReadFile 0x00000432
|
||||
#define __NR_Bfile_SeekFile 0x00000431
|
||||
#define __NR_Bfile_CloseFile 0x0000042d
|
||||
#define __NR_Bfile_FindFirst 0x0000043b
|
||||
#define __NR_Bfile_FindNext 0x0000043c
|
||||
#define __NR_Bfile_FindClose 0x0000043d
|
||||
#define __NR_Bfile_GetMediaFree 0x0000042e
|
||||
#define __NR_Bfile_RemoveFile 0x00000439
|
||||
|
||||
// Display syscalls
|
||||
#define __NR_Bdisp_GetVRAM 0x00000135
|
||||
#define __NR_Bdisp_DrawLine 0x00000030
|
||||
#define __NR_Bdisp_AllClr_VRAM 0x00000143
|
||||
#define __NR_Bdisp_Display 0x00000028
|
||||
#define __NR_Bdisp_PrintMini 0x00000c4f
|
||||
#define __NR_Bdisp_ClearArea 0x0000014b
|
||||
#define __NR_Bdisp_ReverseArea 0x0000014d
|
||||
#define __NR_Bdisp_RestoreDisp 0x00000814
|
||||
#define __NR_Bdisp_SaveDisp 0x00000813
|
||||
|
||||
// Keyboard primitives
|
||||
#define __NR_Bkey_GetKey 0x0000090f
|
||||
#define __NR_Bkey_PutKeycode 0x0000024f
|
||||
#define __NR_BKey_GetKeyWait 0x00000247
|
||||
|
||||
// Memory management
|
||||
#define __NR_Bmem_malloc 0x00000acd
|
||||
#define __NR_Bmem_realloc 0x00000e6d
|
||||
#define __NR_Bmem_called 0x00000e6b
|
||||
#define __NR_Bmem_free 0x00000acc
|
||||
|
||||
// USB primitive
|
||||
#define __NR_USB_Open 0x000002ac // not sure
|
||||
#define __NR_USB_Close 0x000004a4 // not sure
|
||||
|
||||
// SD Card primitives
|
||||
#define __NR_SDC_Init 0x0000017a // not sure
|
||||
#define __NR_SDC_Mount 0x0000044b // not sure
|
||||
#define __NR_SDC_Umount 0x0000044a
|
||||
|
||||
// Timer interface
|
||||
#define __NR_TimerInstall 0x00000118
|
||||
#define __NR_TimerDeinstall 0x00000119
|
||||
#define __NR_TimerStart 0x0000011a
|
||||
#define __NR_TimerStop 0x0000011b
|
||||
|
||||
// power management
|
||||
#define __NR_PowerOff 0x000003f4
|
||||
|
||||
#endif /*__ASM_UNISTD32_FX9860G_H__*/
|
34
include/fxcg50/unistd_32.h
Normal file
34
include/fxcg50/unistd_32.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#ifndef __ASM_UNISTD32_FXCG50_H__
|
||||
# define __ASM_UNISTD32_FXCG50_H__
|
||||
|
||||
// File manipulation
|
||||
#define __NR_BFile_Remove 0x00001db4
|
||||
#define __NR_BFile_Create 0x00001dae
|
||||
#define __NR_BFile_Open 0x00001da3
|
||||
#define __NR_BFile_Close 0x00001da4
|
||||
#define __NR_BFile_Size 0x00001da6
|
||||
#define __NR_BFile_Write 0x00001daf
|
||||
#define __NR_BFile_Read 0x00001dac
|
||||
#define __NR_BFile_FindFirst 0x00001db7
|
||||
#define __NR_BFile_FindNext 0x00001db9
|
||||
#define __NR_BFile_FindClose 0x00001dba
|
||||
|
||||
// Keyboard interface
|
||||
#define __NR_PutKeyCode 0x000012c6
|
||||
#define __NR_GetKeyWait 0x000012bf
|
||||
#define __NR_ClearKeyBuffer 0x000012c7
|
||||
#define __NR_GetVRAMAddress 0x000001e6
|
||||
|
||||
// Memory management
|
||||
#define __NR_Bmem_malloc 0x00001f44
|
||||
#define __NR_Bmem_free 0x00001f42
|
||||
#define __NR_Bmem_calloc 0x00001f40
|
||||
#define __NR_Bmem_realloc 0x00001f46
|
||||
|
||||
// Timer interface
|
||||
#define __NR_Timer_Install 0x000008d9
|
||||
#define __NR_Timer_Deinstall 0x000008da
|
||||
#define __NR_Timer_Start 0x000008db
|
||||
#define __NR_Timer_Stop 0x000008dc
|
||||
|
||||
#endif /*__ASM_UNISTD32_FXCG50_H__*/
|
|
@ -4,27 +4,23 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Real jmp_buf struct
|
||||
// @note: save only r8 ~ r15 and SR / PC registers
|
||||
// The SR register is saved first because the longjump can be involved with
|
||||
// differentregister bank. So to avoid this it's more simple to restore the
|
||||
// saved SR first then restore all register (see <lib/libc/setjmp/longjmp.S>)
|
||||
struct __jmp_buf
|
||||
{
|
||||
uint32_t sr;
|
||||
uint32_t reg[8];
|
||||
uint32_t gbr;
|
||||
uint32_t macl;
|
||||
uint32_t mach;
|
||||
uint32_t pr;
|
||||
};
|
||||
/* Get '__jmp_buf' */
|
||||
#include <bits/setjmp.h>
|
||||
|
||||
// User jmp_buf alias
|
||||
/* User jmp_buf alias */
|
||||
typedef struct __jmp_buf jmp_buf[1];
|
||||
|
||||
|
||||
// Functions
|
||||
/*
|
||||
** Store the calling environment in ENV, also saving the signal mask.
|
||||
** Return 0.
|
||||
*/
|
||||
extern int setjmp(jmp_buf env);
|
||||
|
||||
/*
|
||||
** Store the calling environment in ENV, not saving the signal mask.
|
||||
** Return 0.
|
||||
*/
|
||||
extern void longjmp(jmp_buf env, int val);
|
||||
|
||||
#endif /*__LIB_SETJMP_H__*/
|
||||
|
|
|
@ -5,22 +5,34 @@
|
|||
#include <stdint.h>
|
||||
#include <bits/signum.h>
|
||||
|
||||
// Type of a signal handler
|
||||
typedef void (*__sighandler_t)(int);
|
||||
typedef __sighandler_t sighandler_t;
|
||||
|
||||
// Type of signal set
|
||||
/* Type of signal set */
|
||||
typedef uint32_t sigset_t;
|
||||
typedef uint32_t kernel_sigset_t;
|
||||
|
||||
// Define sigprocmask() value for "how" argument
|
||||
#define SIG_BLOCK 0
|
||||
#define SIG_UNBLOCK 1
|
||||
#define SIG_SETMASK 2
|
||||
/* Type of a signal handler.*/
|
||||
typedef void (*__sighandler_t)(int);
|
||||
typedef __sighandler_t sighandler_t;
|
||||
|
||||
// Prototype
|
||||
// TODO: doc
|
||||
/*
|
||||
** Get the system-specific definitions of `struct sigaction' and the `SA_*'
|
||||
** and `SIG_*'. constants.
|
||||
*/
|
||||
#include <bits/sigaction.h>
|
||||
|
||||
/* Get and/or change the set of blocked signals. */
|
||||
extern int sigprocmask (int how, const sigset_t *restrict set, sigset_t *restrict oldset);
|
||||
|
||||
/*
|
||||
** Send signal SIG to process number PID. If PID is zero, send SIG to all
|
||||
** processes in the current process's process group. If PID is < -1, send SIG to
|
||||
** all processes in process group - PID.
|
||||
*/
|
||||
extern int kill(pid_t pid, int sig);
|
||||
|
||||
/*
|
||||
** Set the handler for the signal SIG to HANDLER, returning the old handler, or
|
||||
** SIG_ERR on error. By default `signal' has the BSD semantic.
|
||||
*/
|
||||
extern void (*signal(int signum, void (*handler)(int)))(int);
|
||||
|
||||
#endif /*__LIB_SIGNAL_H__*/
|
||||
|
|
|
@ -10,7 +10,6 @@ extern int printf(const char *restrict format, ...);
|
|||
extern int dprintf(int fd, const char *restrict format, ...);
|
||||
extern int sprintf(char *restrict str, const char *restrict format, ...);
|
||||
extern int snprintf(char *restrict str, size_t size, const char *restrict format, ...);
|
||||
|
||||
extern int vdprintf(int fd, const char *restrict format, va_list ap);
|
||||
extern int vsprintf(char *restrict str, const char *restrict format, va_list ap);
|
||||
extern int vsnprintf(char *restrict str, size_t size, const char *restrict format, va_list ap);
|
||||
|
@ -19,60 +18,4 @@ extern int vsnprintf(char *restrict str, size_t size, const char *restrict forma
|
|||
extern int putchar(int c);
|
||||
extern int puts(const char *s);
|
||||
|
||||
|
||||
|
||||
|
||||
//---
|
||||
// Internal part
|
||||
// TODO: move me ?
|
||||
//---
|
||||
#define PRINTF_INTERNAL_BUFFER_SIZE 32
|
||||
|
||||
struct printf_opt
|
||||
{
|
||||
// Internal buffer to avoid syscall flux
|
||||
char buffer[PRINTF_INTERNAL_BUFFER_SIZE];
|
||||
size_t buffer_cursor;
|
||||
|
||||
// Common part
|
||||
int counter;
|
||||
va_list ap;
|
||||
|
||||
// *dprintf part
|
||||
int fd;
|
||||
|
||||
// *sprintf part
|
||||
char *str;
|
||||
size_t str_size;
|
||||
|
||||
// For string / fd common support
|
||||
void (*disp_char)(struct printf_opt *opt, char n);
|
||||
void (*disp_fflush)(struct printf_opt *opt);
|
||||
|
||||
// Printf-options
|
||||
struct {
|
||||
uint8_t diez : 1;
|
||||
uint8_t zero : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t space : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t const : 3;
|
||||
} flags;
|
||||
int width;
|
||||
int precision;
|
||||
int uppercase;
|
||||
int lenght;
|
||||
|
||||
// Internal format management.
|
||||
char sign;
|
||||
char base[2];
|
||||
char format[32];
|
||||
int digits;
|
||||
};
|
||||
|
||||
// Internal symbols used to define all actions possibility
|
||||
extern void (*action[26])(struct printf_opt *opt, char n);
|
||||
|
||||
|
||||
|
||||
#endif /*__LIB_STDIO_H__*/
|
||||
|
|
|
@ -4,27 +4,28 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
#define HEAP_BLOCK_MIN (16)
|
||||
struct heap_block
|
||||
{
|
||||
uint16_t status; /* status of the block (1=used,0=free) */
|
||||
uint16_t size; /* size of the block (without block header) */
|
||||
} __attribute__((packed, aligned(2)));
|
||||
|
||||
struct heap_page
|
||||
{
|
||||
void *brk; /* break (address of the limit area) */
|
||||
size_t size; /* Page size (without header) */
|
||||
struct heap_page *next; /* Next heap page */
|
||||
struct heap_block heap; /* Start of block informations */
|
||||
} __attribute__((packed, aligned(4)));
|
||||
|
||||
// Functions
|
||||
//---
|
||||
// Dynamic memory management
|
||||
//---
|
||||
/* Allocate SIZE bytes of memory. */
|
||||
extern void *malloc(size_t size);
|
||||
|
||||
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
|
||||
extern void *calloc(size_t nmemb, size_t size);
|
||||
|
||||
/*
|
||||
** Re-allocate the previously allocated block in PTR, making the new block
|
||||
** SIZE bytes long.
|
||||
*/
|
||||
extern void *realloc(void *ptr, size_t size);
|
||||
|
||||
/*
|
||||
** Re-allocate the previously allocated block in PTR, making the new block large
|
||||
** enough for NMEMB elements of SIZE bytes each.
|
||||
*/
|
||||
extern void *reallocarray(void *ptr, size_t nmemb, size_t size);
|
||||
|
||||
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
|
||||
extern void free(void *ptr);
|
||||
|
||||
#endif /*__LIB_STDLIB_H__*/
|
||||
|
|
|
@ -37,8 +37,22 @@
|
|||
#define MAP_FAILED ((void*) -1)
|
||||
#endif
|
||||
|
||||
// Prototype
|
||||
/*
|
||||
** Map addresses starting near ADDR and extending for LEN bytes. from
|
||||
** OFFSET into the file FD describes according to PROT and FLAGS. If ADDR
|
||||
** is nonzero, it is the desired mapping address. If the MAP_FIXED bit is
|
||||
** set in FLAGS, the mapping will be at ADDR exactly (which must be
|
||||
** page-aligned); otherwise the system chooses a convenient nearby address.
|
||||
** The return value is the actual mapping address chosen or MAP_FAILED
|
||||
** for errors (in which case `errno' is set). A successful `mmap' call
|
||||
** deallocates any previous mapping for the affected region.
|
||||
*/
|
||||
extern void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
|
||||
|
||||
/*
|
||||
** Deallocate any mapping for the region starting at ADDR and extending LEN bytes.
|
||||
** Returns 0 if successful, -1 for errors (and sets errno).
|
||||
*/
|
||||
extern int munmap(void *addr, size_t length);
|
||||
|
||||
#endif /*__LIB_SYS_MMAN_H__*/
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#define __S_IWRITE 0000200 /* Write by owner. */
|
||||
#define __S_IEXEC 0000100 /* Execute by owner. */
|
||||
|
||||
|
||||
#define S_IRUSR __S_IREAD /* Read by owner. */
|
||||
#define S_IWUSR __S_IWRITE /* Write by owner. */
|
||||
#define S_IXUSR __S_IEXEC /* Execute by owner. */
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
#ifndef __LIB_SYS_SYSCALL_H__
|
||||
# define __LIB_SYS_SYSCALL_H__
|
||||
#ifndef __SYSCALL_H__
|
||||
# define __SYSCALL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
/*
|
||||
** This file should list the numbers of the system calls the system knows.
|
||||
** But instead of duplicating this we use the information available
|
||||
** from the kernel sources.
|
||||
*/
|
||||
#include <asm/unistd.h>
|
||||
|
||||
// include Vhex kernel real syscall
|
||||
#include <asm/unistd_32.h>
|
||||
/*
|
||||
** The Linux kernel header file defines macros __NR_*, but some
|
||||
** programs expect the traditional form SYS_*. <bits/syscall.h>
|
||||
** defines SYS_* macros for __NR_* macros of known names.
|
||||
*/
|
||||
#include <bits/syscall.h>
|
||||
|
||||
//TODO include Casio's syscall !!
|
||||
|
||||
#endif /*__LIB_SYS_SYSCALL_H__*/
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,7 @@ typedef int32_t ssize_t;
|
|||
#endif
|
||||
|
||||
// Define alias
|
||||
//FIXME: potential conflict with the real glibc(?)
|
||||
typedef int32_t pid_t;
|
||||
typedef int16_t mode_t;
|
||||
typedef uint16_t dev_t;
|
||||
|
|
|
@ -4,7 +4,14 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
** This will define the `W*' macros for the flag bits to `waitpid', `wait3',
|
||||
** and `wait4'.
|
||||
*/
|
||||
#include <bits/waitflags.h>
|
||||
|
||||
/* This will define all the `__W*' macros.*/
|
||||
#include <bits/waitstatus.h>
|
||||
|
||||
/* Macros for the `waitpid`'s wstatus argument. */
|
||||
|
@ -17,8 +24,26 @@
|
|||
#define WIFCONTINUED(status) __WIFCONTINUED(status)
|
||||
#define WCOREDUMP(status) __WCOREDUMP(status)
|
||||
|
||||
// Wait process
|
||||
/*
|
||||
** Wait for a child matching PID to die.
|
||||
** - If PID is greater than 0, match any process whose process ID is PID.
|
||||
** - If PID is (pid_t) -1, match any process.
|
||||
** - If PID is (pid_t) 0, match any process with the same process group as the
|
||||
** current process.
|
||||
** - If PID is less than -1, match any process whose process group is the absolute
|
||||
** value of PID.
|
||||
** - If the WNOHANG bit is set in OPTIONS, and that child is not already dead,
|
||||
** return (pid_t) 0. If successful, return PID and store the dead child's
|
||||
** status in STAT_LOC.
|
||||
** - Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS,
|
||||
** return status for stopped children; otherwise don't.
|
||||
*/
|
||||
extern pid_t waitpid(pid_t pid, int *wstatus, int options);
|
||||
|
||||
/*
|
||||
** Wait for a child to die. When one does, put its status in *STAT_LOC
|
||||
** and return its process ID. For errors, return (pid_t) -1.
|
||||
*/
|
||||
extern pid_t wait(int *wstatus);
|
||||
|
||||
#endif /*__LIB_SYS_WAIT_H__*/
|
||||
|
|
|
@ -4,15 +4,19 @@
|
|||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//---
|
||||
// Warnig, this part is experimental and reserved for Vhex
|
||||
//---
|
||||
|
||||
// Define Mutex type
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
mtx_plain = 0,
|
||||
mtx_recursive = 1,
|
||||
mtx_timed = 2
|
||||
};
|
||||
|
||||
// Define mutex structure
|
||||
// @note: This is a custom implementation
|
||||
#define MTX_WATERMARK (0xdeadbeef)
|
||||
struct __mtx_s
|
||||
{
|
||||
|
@ -23,40 +27,52 @@ struct __mtx_s
|
|||
typedef struct __mtx_s mtx_t;
|
||||
|
||||
|
||||
//
|
||||
//---
|
||||
// Mutex functions
|
||||
//
|
||||
//---
|
||||
|
||||
// Creates a new mutex object with type __TYPE.
|
||||
// @note: If successful the new object is pointed by __MUTEX.
|
||||
/*
|
||||
** Creates a new mutex object with type __TYPE.
|
||||
** @note: If successful the new object is pointed by __MUTEX.
|
||||
*/
|
||||
extern int mtx_init(mtx_t *__mutex, int __type);
|
||||
|
||||
// Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
// In that case current thread will not be blocked.
|
||||
/*
|
||||
** Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
** In that case current thread will not be blocked.
|
||||
*/
|
||||
extern int mtx_lock(mtx_t *__mutex);
|
||||
|
||||
// Try to lock the mutex pointed by __MUTEX without blocking.
|
||||
// @note: If the mutex is free the current threads takes control of it,
|
||||
// otherwise it returns immediately.
|
||||
/*
|
||||
** Try to lock the mutex pointed by __MUTEX without blocking.
|
||||
** @note: If the mutex is free the current threads takes control of it,
|
||||
** otherwise it returns immediately.
|
||||
*/
|
||||
extern int mtx_trylock(mtx_t *__mutex);
|
||||
|
||||
// Unlock the mutex pointed by __MUTEX.
|
||||
// @note: It may potentially awake other threads waiting on this mutex.
|
||||
/*
|
||||
** Unlock the mutex pointed by __MUTEX.
|
||||
** @note: It may potentially awake other threads waiting on this mutex.
|
||||
*/
|
||||
extern int mtx_unlock (mtx_t *__mutex);
|
||||
|
||||
// Destroy the mutex object pointed by __MUTEX.
|
||||
/* Destroy the mutex object pointed by __MUTEX. */
|
||||
extern void mtx_destroy(mtx_t *__mutex);
|
||||
|
||||
|
||||
//
|
||||
//---
|
||||
// Atomic operations
|
||||
//
|
||||
|
||||
// Save the current SR register and set the SR.BIT bit up (start atomic operations)
|
||||
// @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
|
||||
//---
|
||||
/*
|
||||
** Save the current SR register and set the SR.BIT bit up (start atomic operations)
|
||||
** @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
|
||||
*/
|
||||
extern uint32_t __thread_atomic_start(void);
|
||||
|
||||
// Restore the saved SR register
|
||||
// @note: return the restored SR register or -1 otherwise.
|
||||
/*
|
||||
** Restore the saved SR register
|
||||
** @note: return the restored SR register or -1 otherwise.
|
||||
*/
|
||||
extern uint32_t __thread_atomic_stop(void);
|
||||
|
||||
#endif /*__LIB_PTHREAD_H__*/
|
||||
|
|
|
@ -5,32 +5,90 @@
|
|||
#include <stdint.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
// TODO: move me
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
|
||||
//TODO: move me
|
||||
#define _SC_PAGE_SIZE 0
|
||||
#define _SC_PAGESIZE _SC_PAGE_SIZE
|
||||
|
||||
|
||||
//---
|
||||
// Process part
|
||||
///---
|
||||
/* Get the process ID of the calling process. */
|
||||
extern pid_t getpid(void);
|
||||
extern pid_t getpgid(void);
|
||||
extern pid_t getppid(void);
|
||||
extern int setpgid(pid_t pid, pid_t pgid);
|
||||
|
||||
// CUSTOM function (fork() + exeve()) !
|
||||
/* Get the process group ID of the calling process. */
|
||||
extern pid_t getpgid(void);
|
||||
|
||||
/* Get the process ID of the calling process's parent. */
|
||||
extern pid_t getppid(void);
|
||||
|
||||
/*
|
||||
** Set the process group ID of the process matching PID to PGID.
|
||||
** If PID is zero, the current process's process group ID is set.
|
||||
** If PGID is zero, the process ID of the process is used.
|
||||
*/
|
||||
extern int setpgid(pid_t __pid, pid_t __pgid);
|
||||
|
||||
// CUSTOM syscall for Vhex (fork() + exeve()) !
|
||||
//TODO: move me !!
|
||||
extern pid_t fork_execve(const char *pathname, char **argv, char **envp);
|
||||
|
||||
//---
|
||||
// File part
|
||||
extern ssize_t write(int fd, const void *buf, size_t count);
|
||||
extern ssize_t read(int fd, void *buf, size_t count);
|
||||
extern off_t lseek(int fd, off_t offset, int whence);
|
||||
extern int close(int fd);
|
||||
//---
|
||||
/* Standard file descriptors. */
|
||||
#define STDIN_FILENO 0 /* Standard input. */
|
||||
#define STDOUT_FILENO 1 /* Standard output. */
|
||||
#define STDERR_FILENO 2 /* Standard error output. */
|
||||
|
||||
/*
|
||||
** Write N bytes of BUF to FD.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
|
||||
|
||||
/*
|
||||
** Read NBYTES into BUF from FD.
|
||||
** Return the number read, -1 for errors or 0 for EOF.
|
||||
*/
|
||||
extern ssize_t read(int __fd, void *__buf, size_t __nbytes);
|
||||
|
||||
/*
|
||||
** Read NBYTES into BUF from FD at the given position OFFSET without
|
||||
** changing the file pointer.
|
||||
** Return the number read, -1 for errors or 0 for EOF.
|
||||
*/
|
||||
extern ssize_t pread (int __fd, void *__buf, size_t __nbytes, off_t __offset);
|
||||
|
||||
/*
|
||||
** Write N bytes of BUF to FD at the given position OFFSET without
|
||||
** changing the file pointer.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
extern ssize_t pwrite (int __fd, const void *__buf, size_t __n, off_t __offset);
|
||||
|
||||
/* Values for the WHENCE argument to lseek. */
|
||||
#define SEEK_SET 0 /* Seek from beginning of file. */
|
||||
#define SEEK_CUR 1 /* Seek from current position. */
|
||||
#define SEEK_END 2 /* Seek from end of file. */
|
||||
|
||||
/*
|
||||
** Move FD's file position to OFFSET bytes from the beginning of the file
|
||||
** (if WHENCE is SEEK_SET), the current position (if WHENCE is SEEK_CUR),
|
||||
** or the end of the file (if WHENCE is SEEK_END).
|
||||
** Return the new file position.
|
||||
*/
|
||||
extern __off_t lseek (int __fd, off_t __offset, int __whence);
|
||||
|
||||
/* Close the file descriptor FD */
|
||||
extern int close(int __fd);
|
||||
|
||||
//---
|
||||
// System part
|
||||
extern long sysconf(int name);
|
||||
//---
|
||||
/*
|
||||
** Get the `_PC_*' symbols for the NAME argument to `pathconf' and `fpathconf';
|
||||
** the `_SC_*' symbols for the NAME argument to `sysconf'; and the `_CS_*'
|
||||
** symbols for the NAME argument to `confstr'.
|
||||
*/
|
||||
#include <bits/confname.h>
|
||||
|
||||
/* Get the value of the system variable NAME. */
|
||||
extern long int sysconf(int __name);
|
||||
|
||||
#endif /*__LIB_UNISTD_H__*/
|
||||
|
|
45
include/vhex/unistd_32.h
Normal file
45
include/vhex/unistd_32.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __ASM_UNISTD32_VHEX_H__
|
||||
# define __ASM_UNISTD32_VHEX_H__
|
||||
|
||||
// Define the number of syscall
|
||||
#define __NR_MAX 21
|
||||
|
||||
// Kernel Test
|
||||
#define __NR_test_syscall 0
|
||||
|
||||
// Process
|
||||
#define __NR_exit 1
|
||||
#define __NR_fork_execve 2 // (custom)
|
||||
#define __NR_waitpid 3
|
||||
#define __NR_wait 4
|
||||
#define __NR_getpid 5
|
||||
#define __NR_getppid 6
|
||||
#define __NR_getpgid 7
|
||||
#define __NR_setpgid 8
|
||||
|
||||
// Signal
|
||||
#define __NR_signal 9
|
||||
#define __NR_sigreturn 10
|
||||
#define __NR_sigaction 11
|
||||
#define __NR_kill 12
|
||||
#define __NR_sigprogmask 13
|
||||
#define __NR_sigpending 14
|
||||
#define __NR_sigaltstack 15
|
||||
|
||||
// VFS
|
||||
#define __NR_read 16
|
||||
#define __NR_write 17
|
||||
#define __NR_open 18
|
||||
#define __NR_close 19
|
||||
#define __NR_lseek 20
|
||||
#define __NR_pread 21
|
||||
#define __NR_pwrite 22
|
||||
|
||||
// Memory
|
||||
#define __NR_mmap 23
|
||||
#define __NR_munmap 24
|
||||
#define __NR_proc_heap_alloc 25 // (custom)
|
||||
#define __NR_proc_heap_free 26 // (custom)
|
||||
#define __NR_proc_heap_realloc 27 // (custom)
|
||||
|
||||
#endif /*__ASM_UNISTD32_VHEX_H__*/
|
|
@ -33,8 +33,8 @@
|
|||
# * handle versionning
|
||||
#---
|
||||
MAJOR := 0
|
||||
MINOR := 1
|
||||
PATCH := 1
|
||||
MINOR := 2
|
||||
PATCH := 0
|
||||
EXTRAVERSION := -alpha
|
||||
|
||||
|
||||
|
|
21
src/fcntl/arch/vhex/open.S
Normal file
21
src/fcntl/arch/vhex/open.S
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _open
|
||||
.type _open, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int open(const char *pathname, int flags, ...);
|
||||
** Open FILE and return a new file descriptor for it, or -1 on error.
|
||||
** OFLAG determines the type of access used. If O_CREAT or O_TMPFILE is set
|
||||
** in OFLAG, the third argument is taken as a `mode_t', the mode of the
|
||||
** created file.
|
||||
*/
|
||||
_open:
|
||||
trapa #__NR_open
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -6,7 +6,8 @@
|
|||
.align 2
|
||||
/*
|
||||
** void longjmp(jmp_buf env, int val)
|
||||
** @note: TODO
|
||||
** Store the calling environment in ENV, not saving the signal mask.
|
||||
** Return 0.
|
||||
*/
|
||||
_longjmp:
|
||||
! save the context into unbankable register
|
||||
|
|
|
@ -5,7 +5,10 @@
|
|||
.align 2
|
||||
/*
|
||||
** int setjmp(jmp_buf env)
|
||||
** @note: TODO
|
||||
** Store the calling environment in ENV, also saving the signal mask.
|
||||
** Return 0.
|
||||
**
|
||||
** TODO: hande signal mask
|
||||
*/
|
||||
_setjmp:
|
||||
! block interrupt
|
||||
|
@ -40,4 +43,4 @@ _setjmp:
|
|||
! return
|
||||
rts
|
||||
mov #0, r0
|
||||
|
||||
.end
|
||||
|
|
20
src/signal/arch/vhex/kill.S
Normal file
20
src/signal/arch/vhex/kill.S
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _kill
|
||||
.type _kill, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int kill(pid_t pid, int sig);
|
||||
** Send signal SIG to process number PID. If PID is zero, send SIG to all
|
||||
** processes in the current process's process group. If PID is < -1, send SIG to
|
||||
** all processes in process group - PID.
|
||||
*/
|
||||
_kill:
|
||||
trapa #__NR_kill
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
19
src/signal/arch/vhex/signal.S
Normal file
19
src/signal/arch/vhex/signal.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _signal
|
||||
.type _signal, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void (*signal(int signum, void (*handler)(int)))(int);
|
||||
** Set the handler for the signal SIG to HANDLER, returning the old handler, or
|
||||
** SIG_ERR on error. By default `signal' has the BSD semantic.
|
||||
*/
|
||||
_signal:
|
||||
trapa #__NR_signal
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _kill
|
||||
.type _kill, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** TODO: doc
|
||||
*/
|
||||
_kill:
|
||||
trapa #__NR_kill
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,15 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _signal
|
||||
.type _signal, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** TODO: doc
|
||||
*/
|
||||
_signal:
|
||||
trapa #__NR_signal
|
||||
rts
|
||||
nop
|
||||
.end
|
58
src/stdio/internal/printf.h
Normal file
58
src/stdio/internal/printf.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
#ifndef _SRC_STDIO_PRINTF_H__
|
||||
# define _SRC_STDIO_PRINTF_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
//---
|
||||
// Internal printf() part
|
||||
//---
|
||||
#define PRINTF_INTERNAL_BUFFER_SIZE 32
|
||||
|
||||
// internal structure used by any printf function familly
|
||||
struct printf_opt
|
||||
{
|
||||
// Internal buffer to avoid syscall flux
|
||||
char buffer[PRINTF_INTERNAL_BUFFER_SIZE];
|
||||
size_t buffer_cursor;
|
||||
|
||||
// Common part
|
||||
int counter;
|
||||
va_list ap;
|
||||
|
||||
// *dprintf part
|
||||
int fd;
|
||||
|
||||
// *sprintf part
|
||||
char *str;
|
||||
size_t str_size;
|
||||
|
||||
// For string / fd common support
|
||||
void (*disp_char)(struct printf_opt *opt, char n);
|
||||
void (*disp_fflush)(struct printf_opt *opt);
|
||||
|
||||
// Printf-options
|
||||
struct {
|
||||
uint8_t diez : 1;
|
||||
uint8_t zero : 1;
|
||||
uint8_t minus : 1;
|
||||
uint8_t space : 1;
|
||||
uint8_t plus : 1;
|
||||
uint8_t const : 3;
|
||||
} flags;
|
||||
int width;
|
||||
int precision;
|
||||
int uppercase;
|
||||
int lenght;
|
||||
|
||||
// Internal format management.
|
||||
char sign;
|
||||
char base[2];
|
||||
char format[32];
|
||||
int digits;
|
||||
};
|
||||
|
||||
// Internal symbols used to define all actions possibility
|
||||
extern void (*action[26])(struct printf_opt *opt, char n);
|
||||
|
||||
#endif /*_SRC_STDIO_PRINTF_H__*/
|
23
src/stdlib/arch/vhex/free.S
Normal file
23
src/stdlib/arch/vhex/free.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _free
|
||||
.type _free, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void free(void *ptr)
|
||||
** Custom syscall which free a block allocated by `malloc', `realloc' or `calloc'.
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_free:
|
||||
trapa #__NR_proc_heap_free
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
23
src/stdlib/arch/vhex/malloc.S
Normal file
23
src/stdlib/arch/vhex/malloc.S
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _malloc
|
||||
.type _malloc, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void *malloc(size_t size);
|
||||
** Allocate SIZE bytes of memory.
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_malloc:
|
||||
trapa #__NR_proc_heap_alloc
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
43
src/stdlib/arch/vhex/realloc.S
Normal file
43
src/stdlib/arch/vhex/realloc.S
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _realloc
|
||||
.type _realloc, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern void *realloc(void ptr, size_t size)
|
||||
**
|
||||
** @note:
|
||||
** The MMU is used by Casio so we cannot implement brk or skr for technical
|
||||
** reason (non-continius heap, no shared page, ...), so all memory management
|
||||
** is performed by the Vhex kernel.
|
||||
*/
|
||||
_realloc:
|
||||
! Check if the PTR is NULL
|
||||
! In this case, realloc() work like malloc(), so lets call it
|
||||
tst r4, r4
|
||||
bf check_free
|
||||
mov r5, r4
|
||||
trapa #__NR_proc_head_alloc
|
||||
rts
|
||||
nop
|
||||
|
||||
! Check is the size is NULL
|
||||
! In this case, realloc() work like free(), so lets call it
|
||||
! then return NULL pointer
|
||||
check_free:
|
||||
tst r5, r5
|
||||
bf call_realloc
|
||||
trapa #__NR_proc_heap_free
|
||||
rts
|
||||
xor r0, r0
|
||||
|
||||
! Call realloc
|
||||
call_realloc:
|
||||
trapa #__NR_proc_heap_realloc
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -2,15 +2,28 @@
|
|||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/*
|
||||
** The calloc() function allocates memory for an array of nmemb elements of size
|
||||
** bytes each and returns a pointer to the allocated memory. The memory is set
|
||||
** to zero. If nmemb or size is 0, then calloc() returns either NULL, or a
|
||||
** unique pointer value that can later be successfully passed to free(). If the
|
||||
** multiplication of nmemb and size would result in integer overflow, then
|
||||
** calloc() returns an error. By contrast, an integer overflow would not be
|
||||
** detected in the following call to malloc(), with the result that an incorrectly
|
||||
** sized block of memory would be allocated: `malloc(nmemb * size);`
|
||||
*/
|
||||
void *calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
if (size == 0 || nmemb == 0)
|
||||
return (NULL);
|
||||
// check error
|
||||
if (size == 0 || nmemb == 0)
|
||||
return (NULL);
|
||||
|
||||
void *ret = malloc(nmemb * size);
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
// Try to allowate the area
|
||||
void *ret = malloc(nmemb * size);
|
||||
if (ret == NULL)
|
||||
return (NULL);
|
||||
|
||||
memset(ret, 0x00, size);
|
||||
return (ret);
|
||||
// wipe the area
|
||||
memset(ret, 0x00, size);
|
||||
return (ret);
|
||||
}
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _free
|
||||
.type _free, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** @note: the MMU is used by Casio so we
|
||||
** can not implement brk or skr because
|
||||
** of non continuous heap.
|
||||
*/
|
||||
_free:
|
||||
trapa #__NR_proc_heap_free
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,16 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _malloc
|
||||
.type _malloc, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** @note: We can not implement brk or skr
|
||||
** because the MMU is used by Casio.
|
||||
*/
|
||||
_malloc:
|
||||
trapa #__NR_proc_heap_alloc
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,46 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _realloc
|
||||
.type _realloc, @function
|
||||
|
||||
.extern _malloc
|
||||
.extern _free
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** void *realloc(void ptr, size_t size)
|
||||
**
|
||||
** @note: the MMU is used by Casio so we
|
||||
** can not implement brk or skr because
|
||||
** of non continuous heap.
|
||||
*/
|
||||
_realloc:
|
||||
! Check malloc part
|
||||
tst r4, r4 ! if ptr == NULL...
|
||||
bf.s check_free ! ...if not, jump at <check_free>
|
||||
mov.l .malloc, r0 ! get malloc() address
|
||||
jmp @r0 ! call malloc(size)
|
||||
mov r5, r4 ! (db) send size
|
||||
|
||||
! Check free
|
||||
check_free:
|
||||
tst r5, r5 ! if size == 0...
|
||||
bf.s call_realloc ! ...if not, jump at <call_realloc>
|
||||
mov.l .free, r0 ! get free() address
|
||||
sts.l pr, @-r15 ! save pr register
|
||||
jmp @r0 ! call free(ptr)
|
||||
nop ! (db) nop
|
||||
rts ! return...
|
||||
xor r0, r0 ! (db) ...NULL
|
||||
|
||||
|
||||
! Call realloc
|
||||
call_realloc:
|
||||
trapa #__NR_proc_heap_realloc
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 4
|
||||
.malloc: .long _malloc
|
||||
.free: .long _free
|
||||
.end
|
|
@ -1,7 +1,18 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
//FIXME: check safe !!!!
|
||||
//FIXME: Check underflow !!
|
||||
/*
|
||||
** The reallocarray() function changes the size of the memory block pointed to
|
||||
** by ptr to be large enough for an array of nmemb elements, each of which is
|
||||
** size bytes. It is equivalent to the call: `realloc(ptr, nmemb * size);`
|
||||
**
|
||||
** However, unlike that realloc() call, reallocarray() fails safely in the case
|
||||
** where the multiplication would overflow. If such an overflow occurs,
|
||||
** reallocarray() returns NULL, sets errno to ENOMEM, and leaves the original
|
||||
** block of memory unchanged.
|
||||
**
|
||||
** FIXME: check safe !!!!
|
||||
** FIXME: Check underflow !!
|
||||
*/
|
||||
void *reallocarray(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
return (realloc(ptr, nmemb * size));
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The memcpy() function copies n bytes from memory area src to memory area dest.
|
||||
** The memory areas must not overlap. Use memmove(3) if the memory areas do
|
||||
** overlap.
|
||||
**
|
||||
** TODO: use DMA ?
|
||||
** TODO: use DSP ?
|
||||
*/
|
||||
void *memcpy(void *dest, const void *src, size_t count)
|
||||
{
|
||||
for (size_t i = 0 ; i < count ; i = i + 1)
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#include <string.h>
|
||||
|
||||
//TODO: update me :(
|
||||
/*
|
||||
** The memset() function fills the first n bytes of the memory area pointed to
|
||||
** by s with the constant byte c.
|
||||
**
|
||||
** TODO: use DMA !
|
||||
** TODO: use DSP ?
|
||||
*/
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
while ((int)--n >= 0)
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The strcat() function appends the src string to the dest string,
|
||||
** overwriting the terminating null byte ('\0') at the end of dest, and then
|
||||
** adds a terminating null byte. The strings may not overlap, and the dest
|
||||
** string must have enough space for the result. If dest is not large enough,
|
||||
** program behavior is unpredictable; buffer overruns are a favorite avenue for
|
||||
** attacking secure programs.
|
||||
**
|
||||
** TODO: use the DMA !
|
||||
** TODO: look at the DSP ?
|
||||
*/
|
||||
char *strcat(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -15,3 +26,25 @@ char *strcat(char *dest, char const *src)
|
|||
dest[i + start] = '\0';
|
||||
return (dest);
|
||||
}
|
||||
|
||||
/*
|
||||
** The strncat() function is similar, except that:
|
||||
** * it will use at most n bytes from src; and
|
||||
** * src does not need to be null-terminated if it contains n or more bytes.
|
||||
**
|
||||
** As with strcat(), the resulting string in dest is always null-terminated.
|
||||
**
|
||||
** If src contains n or more bytes, strncat() writes n+1 bytes to dest (n from
|
||||
** src plus the terminating null byte). Therefore, the size of dest must be at
|
||||
** least strlen(dest)+n+1.
|
||||
*/
|
||||
char *strncat(char *dest, const char *src, size_t n)
|
||||
{
|
||||
size_t dest_len = strlen(dest);
|
||||
size_t i;
|
||||
|
||||
for (i = 0 ; i < n && src[i] != '\0' ; i++)
|
||||
dest[dest_len + i] = src[i];
|
||||
dest[dest_len + i] = '\0';
|
||||
return (dest);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include <string.h>
|
||||
|
||||
//TODO: asm ?
|
||||
/*
|
||||
** The strchr() function returns a pointer to the first occurrence of the
|
||||
** character c in the strings.
|
||||
*/
|
||||
char *strchr(const char *s1, int c)
|
||||
{
|
||||
int i = -1;
|
||||
|
@ -8,7 +11,11 @@ char *strchr(const char *s1, int c)
|
|||
return ((s1[i] == '\0') ? NULL : (void*)&s1[i]);
|
||||
}
|
||||
|
||||
//TODO: asm ?
|
||||
/*
|
||||
** The strchrnul() function is like strchr() except that if c is not found in
|
||||
** s, then it returns a pointer to the null byte at the end of s, rather
|
||||
** than NULL.
|
||||
*/
|
||||
char *strchrnul(const char *s1, int c)
|
||||
{
|
||||
int i = -1;
|
||||
|
@ -16,14 +23,16 @@ char *strchrnul(const char *s1, int c)
|
|||
return ((void*)&s1[i]);
|
||||
}
|
||||
|
||||
//TODO asm ?
|
||||
/*
|
||||
** The strrchr() function returns a pointer to the last occurrence of the
|
||||
** character c in the strings.
|
||||
*/
|
||||
char *strrchr(const char *s1, int c)
|
||||
{
|
||||
void *saved;
|
||||
|
||||
saved = NULL;
|
||||
for (int i = 0 ; s1[i] != '\0' ; i++)
|
||||
{
|
||||
for (int i = 0 ; s1[i] != '\0' ; i++) {
|
||||
if (s1[i] == c)
|
||||
saved = (void *)&s1[i];
|
||||
}
|
||||
|
|
|
@ -1,17 +1,34 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The strcmp() function compares the two strings s1 and s2. The locale is not
|
||||
** taken into account (for a locale-aware comparison, see strcoll(3)).
|
||||
** The comparison is done using unsigned characters.
|
||||
**
|
||||
** strcmp() returns an integer indicating the result of the comparison, as follows:
|
||||
** * 0, if the s1 and s2 are equal;
|
||||
** * a negative value if s1 is less than s2;
|
||||
** * a positive value if s1 is greater than s2.
|
||||
**
|
||||
** TODO: quad-word access !
|
||||
*/
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL)
|
||||
return (0);
|
||||
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2)
|
||||
{
|
||||
while (*s1 != '\0' && *s2 != '\0' && *s1 == *s2) {
|
||||
s1 += 1;
|
||||
s2 += 1;
|
||||
}
|
||||
return (*s1 - *s2);
|
||||
}
|
||||
|
||||
/*
|
||||
** The strncmp() function is similar, except it compares only the first (at most)
|
||||
** n bytes of s1 and s2.
|
||||
**
|
||||
** TODO: quad-word access !
|
||||
*/
|
||||
int strncmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
if (s1 == NULL || s2 == NULL || n == 0)
|
||||
|
|
|
@ -1,5 +1,14 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The strcpy() function copies the string pointed to by src, including the
|
||||
** terminating null byte ('\0'), to the buffer pointed to by dest.
|
||||
** The strings may not overlap, and the destination string dest must be
|
||||
** large enough to receive the copy. Beware of buffer overruns!
|
||||
**
|
||||
** TODO: use quad-word access and/or DMA !
|
||||
** TODO: look at the DSP ?
|
||||
*/
|
||||
char *strcpy(char *dest, char const *src)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -13,6 +22,11 @@ char *strcpy(char *dest, char const *src)
|
|||
return (dest);
|
||||
}
|
||||
|
||||
/*
|
||||
** The strncpy() function is similar, except that at most n bytes of src are
|
||||
** copied. Warning: If there is no null byte among the first n bytes of src, the
|
||||
** string placed in dest will not be null-terminated.
|
||||
*/
|
||||
char *strncpy(char *dest, char const *str, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
** The strdup() function returns a pointer to a new string which is a
|
||||
** duplicate of the string s. Memory for the new string is obtained with
|
||||
** malloc(), and can be freed with free().
|
||||
*/
|
||||
char *strdup(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
|
@ -12,11 +17,48 @@ char *strdup(const char *s)
|
|||
|
||||
// Check len
|
||||
len = strlen(s);
|
||||
if (len == 0)
|
||||
if (len == 0)
|
||||
return (NULL);
|
||||
|
||||
// Dump string and return
|
||||
// try to allocate the new area
|
||||
dump = malloc(len);
|
||||
if (dump == NULL)
|
||||
return (NULL);
|
||||
|
||||
// dump the area and return
|
||||
memcpy(dump, s, len);
|
||||
return (dump);
|
||||
}
|
||||
|
||||
/*
|
||||
** The strndup() function is similar, but copies at most n bytes. If s is longer
|
||||
** than n, only n bytes are copied, and a terminating null byte ('\0') is added.
|
||||
*/
|
||||
char *strndump(const char *s, size_t n)
|
||||
{
|
||||
size_t len;
|
||||
char *dump;
|
||||
|
||||
// Check error
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
|
||||
// Check len
|
||||
len = strnlen(s, n);
|
||||
if (len == 0)
|
||||
return (NULL);
|
||||
|
||||
// try to allocate the new area
|
||||
dump = malloc(len);
|
||||
if (dump == NULL)
|
||||
return (NULL);
|
||||
|
||||
// dump the area, set the null byte and return
|
||||
memcpy(dump, s, len);
|
||||
dump[len - 1] = '\0';
|
||||
return (dump);
|
||||
|
||||
}
|
||||
|
||||
//TODO: strdupa()
|
||||
//TODO: strndupa()
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#include <string.h>
|
||||
|
||||
/*
|
||||
** The strlen() function calculates the length of the string pointed to by s,
|
||||
** excluding the termi‐nating null byte ('\0').
|
||||
**
|
||||
** TODO: use quad-word access !
|
||||
*/
|
||||
size_t strlen(char const *str)
|
||||
{
|
||||
size_t i;
|
||||
|
@ -11,6 +17,14 @@ size_t strlen(char const *str)
|
|||
return (i);
|
||||
}
|
||||
|
||||
/*
|
||||
** The strnlen() function returns the number of bytes in the string pointed to
|
||||
** by s, excluding the terminating null byte ('\0'), but at most maxlen.
|
||||
** In doing this, strnlen() looks only at the first maxlen characters in the
|
||||
** string pointed to by s and never beyond s+maxlen.
|
||||
**
|
||||
** TODO: use quad-word access !
|
||||
*/
|
||||
size_t strnlen(char const *str, size_t maxlen)
|
||||
{
|
||||
size_t i;
|
||||
|
|
19
src/sys/wait/arch/vhex/wait.S
Normal file
19
src/sys/wait/arch/vhex/wait.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _wait
|
||||
.type _wait, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t wait(int *wstatus);
|
||||
** Wait for a child to die. When one does, put its status in *STAT_LOC
|
||||
** and return its process ID. For errors, return (pid_t) -1.
|
||||
*/
|
||||
_wait:
|
||||
trapa #__NR_wait
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
29
src/sys/wait/arch/vhex/waitpid.S
Normal file
29
src/sys/wait/arch/vhex/waitpid.S
Normal file
|
@ -0,0 +1,29 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _waitpid
|
||||
.type _waitpid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t waitpid(pid_t pid, int *wstatus, int options);
|
||||
** Wait for a child matching PID to die.
|
||||
** - If PID is greater than 0, match any process whose process ID is PID.
|
||||
** - If PID is (pid_t) -1, match any process.
|
||||
** - If PID is (pid_t) 0, match any process with the same process group as the
|
||||
** current process.
|
||||
** - If PID is less than -1, match any process whose process group is the absolute
|
||||
** value of PID.
|
||||
** - If the WNOHANG bit is set in OPTIONS, and that child is not already dead,
|
||||
** return (pid_t) 0. If successful, return PID and store the dead child's
|
||||
** status in STAT_LOC.
|
||||
** - Return (pid_t) -1 for errors. If the WUNTRACED bit is set in OPTIONS,
|
||||
** return status for stopped children; otherwise don't.
|
||||
*/
|
||||
_waitpid:
|
||||
trapa #__NR_waitpid
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -6,64 +6,72 @@
|
|||
.type ___thread_atomic_stop, @function
|
||||
|
||||
.align 2
|
||||
// Save the current SR register and set the SR.BIT bit up (start atomic operations)
|
||||
// @note: return the saved SR register (if has been saved), 0xffffffff otherwise.
|
||||
/*
|
||||
** extern uint32_t __thread_atomic_start(void)
|
||||
** Save the current SR register and set the SR.BIT bit up to start an atomic
|
||||
** context (interrupt is blocked).
|
||||
** Return the saved SR register (only if the we enter into an atomic context),
|
||||
** 0xffffffff otherwise.
|
||||
*/
|
||||
___thread_atomic_start:
|
||||
! Check if the calculator is currently
|
||||
! into an atomic operation and update
|
||||
! atomic counter.
|
||||
mov.l atomic_counter, r1 ! r1 = atomic counter address
|
||||
mov.l @r1, r2 ! r2 = atomic counter data
|
||||
tst r2, r2 ! if atomic counter == 0...
|
||||
add #1, r2 ! update atomic counter data
|
||||
mov.l r2, @r1 ! update atomic counter.
|
||||
bf.s atomic_start_exit ! ...if not, jump <atomic_start_exit>
|
||||
mov #-1, r0 ! (db) return 0xffffffff
|
||||
! Check if the user is currently into an atomic operation
|
||||
! and update atomic counter.
|
||||
mov.l atomic_counter, r1
|
||||
mov.l @r1, r2
|
||||
tst r2, r2
|
||||
add #1, r2
|
||||
mov.l r2, @r1
|
||||
bf.s atomic_start_exit
|
||||
mov #-1, r0
|
||||
|
||||
! Block interrupt if needed.
|
||||
stc sr, r1 ! get SR register.
|
||||
mov r1, r0 ! save current SR register.
|
||||
mov.l bl_mask, r2 ! get SR.BL mask.
|
||||
or r2, r1 ! set SR.BL = 1 and SR.IMASK = 0b1111.
|
||||
ldc r1, sr ! update SR register.
|
||||
stc sr, r1
|
||||
mov r1, r0
|
||||
mov.l bl_mask, r2
|
||||
or r2, r1
|
||||
ldc r1, sr
|
||||
|
||||
! Save "old" SR register.
|
||||
mov.l sr_save, r1 ! r1 = sr_save address
|
||||
mov.l r0, @r1 ! save "old" SR register data.
|
||||
mov.l sr_save, r1
|
||||
mov.l r0, @r1
|
||||
|
||||
atomic_start_exit:
|
||||
rts ! exit.
|
||||
nop ! (db) nop.
|
||||
rts
|
||||
nop
|
||||
|
||||
// Restore the saved SR register
|
||||
// @note: return the restored SR register or -1 otherwise.
|
||||
/*
|
||||
** extern uint32_t __thread_atomic_stop(void)
|
||||
** Decreate the internal "atomic context counter" and if the counter is 0,
|
||||
** restore the saved SR register status.
|
||||
** Return the restored SR register (if restored) or -1 otherwise.
|
||||
*/
|
||||
___thread_atomic_stop:
|
||||
|
||||
! Check if the calculator is currently
|
||||
! into an atomic operation and update
|
||||
! atomic counter if pssible.
|
||||
mov.l atomic_counter, r1 ! r1 = atomic counter address
|
||||
mov.l @r1, r0 ! r0 = atomic counter data
|
||||
tst r0, r0 ! if atomic counter == 0...
|
||||
bt atomic_end_error ! ...if yes, jump at <atomic_end_error>
|
||||
cmp/eq #1, r0 ! if atomic counter == 1...
|
||||
add #-1, r0 ! update atomic counter data
|
||||
mov.l r0, @r1 ! update atomic counter
|
||||
bf atomic_end_error ! ...if not, jump at <atomic_end_error>
|
||||
! Check if the device is currently into an atomic operation
|
||||
! and update atomic counter and, if needed, restore the SR
|
||||
! regsiter
|
||||
mov.l atomic_counter, r1
|
||||
mov.l @r1, r0
|
||||
tst r0, r0
|
||||
bt atomic_end_error
|
||||
cmp/eq #1, r0
|
||||
add #-1, r0
|
||||
mov.l r0, @r1
|
||||
bf atomic_end_error
|
||||
|
||||
! Restore saved SR register data.
|
||||
mov.l sr_save, r1 ! get sr_save address
|
||||
mov.l @r1, r0 ! r0 = "old" SR register data
|
||||
ldc r0, sr ! restore SR register.
|
||||
bra atomic_end_exit ! return the resotred SR register.
|
||||
nop ! (db) nop
|
||||
mov.l sr_save, r1
|
||||
mov.l @r1, r0
|
||||
ldc r0, sr
|
||||
bra atomic_end_exit
|
||||
nop
|
||||
|
||||
atomic_end_error:
|
||||
mov #-1, r0 ! return 0xffffffff
|
||||
mov #-1, r0
|
||||
|
||||
atomic_end_exit:
|
||||
rts ! exit.
|
||||
nop ! (db) nop.
|
||||
rts
|
||||
nop
|
||||
|
||||
.align 4
|
||||
bl_mask: .long 0x100000f0
|
||||
|
@ -72,9 +80,8 @@ atomic_counter: .long ___thread_atomic_counter
|
|||
|
||||
|
||||
|
||||
|
||||
##---
|
||||
## Global part.
|
||||
## Global part.
|
||||
##---
|
||||
.data
|
||||
.global ___thread_atomic_sr_save
|
||||
|
|
|
@ -16,7 +16,7 @@ int mtx_init (mtx_t *__mutex, int __type)
|
|||
return (0);
|
||||
}
|
||||
|
||||
// Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
// Block the current thread until the mutex pointed to by __MUTEX is unlocked.
|
||||
// In that case current thread will not be blocked.
|
||||
int mtx_lock(mtx_t *__mutex)
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ int mtx_trylock(mtx_t *__mutex)
|
|||
// Check mutex validity
|
||||
if (__mutex->__watermark != MTX_WATERMARK)
|
||||
return (-1);
|
||||
|
||||
|
||||
// Start atomic operations
|
||||
__thread_atomic_start();
|
||||
|
||||
|
|
20
src/unistd/arch/fx9860g/close.S
Normal file
20
src/unistd/arch/fx9860g/close.S
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifdef __SUPPORT_CASIO_ABI_FX9860G
|
||||
#include <asm/unistd_32.h>
|
||||
#include <asm-casio/__trapa.h>
|
||||
.text
|
||||
.global _close
|
||||
.type _close, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** int close(int fd)
|
||||
** close() closes a file descriptor, so that it no longer refers to any file
|
||||
** and may be reused.
|
||||
*/
|
||||
_close:
|
||||
casio_trapa(__NR_close)
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
19
src/unistd/arch/vhex/close.S
Normal file
19
src/unistd/arch/vhex/close.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _close
|
||||
.type _close, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** int close(int fd)
|
||||
** close() closes a file descriptor, so that it no longer refers to any file
|
||||
** and may be reused.
|
||||
*/
|
||||
_close:
|
||||
trapa #__NR_close
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
24
src/unistd/arch/vhex/fork_execve.S
Normal file
24
src/unistd/arch/vhex/fork_execve.S
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _fork_execve
|
||||
.type _fork_execve, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** pid_t fork_execve(const char *pathname, char **argv, char **envp);
|
||||
** Custom syscall used to create a new process based on the new command passed
|
||||
** using the `argv` and `envp` parametter. This sycall is equivalent of fork()
|
||||
** and execve() combined.
|
||||
**
|
||||
** This custom syscall exist because the Vhex kernel doesn't have access to the
|
||||
** MMU, so we cannot ensure that the memory requested by the potential new
|
||||
** process is enough when execve() is involved by the user.
|
||||
*/
|
||||
_fork_execve:
|
||||
trapa #__NR_fork_execve
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -1,3 +1,4 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _getpgid
|
||||
|
@ -5,8 +6,13 @@
|
|||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpgid(void);
|
||||
** Get the process group ID of the calling process.
|
||||
*/
|
||||
_getpgid:
|
||||
trapa #__NR_getpgid
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -1,3 +1,4 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _getpid
|
||||
|
@ -5,8 +6,13 @@
|
|||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpid(void);
|
||||
** Get the process ID of the calling process.
|
||||
*/
|
||||
_getpid:
|
||||
trapa #__NR_getpid
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -1,3 +1,4 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _getppid
|
||||
|
@ -5,8 +6,13 @@
|
|||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern pid_t getpgid(void);
|
||||
** Get the parent process ID of the calling process.
|
||||
*/
|
||||
_getppid:
|
||||
trapa #__NR_getppid
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
21
src/unistd/arch/vhex/lseek.S
Normal file
21
src/unistd/arch/vhex/lseek.S
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _lseek
|
||||
.type _lseek, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern off_t lseek(int fd, off_t offset, int whence)
|
||||
** Move FD's file position to OFFSET bytes from the beginning of the file
|
||||
** (if WHENCE is SEEK_SET), the current position (if WHENCE is SEEK_CUR),
|
||||
** or the end of the file (if WHENCE is SEEK_END).
|
||||
** Return the new file position.
|
||||
*/
|
||||
_lseek:
|
||||
trapa #__NR_lseek
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
19
src/unistd/arch/vhex/read.S
Normal file
19
src/unistd/arch/vhex/read.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _read
|
||||
.type _read, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
|
||||
** Write N bytes of BUF to FD.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
_read:
|
||||
trapa #__NR_read
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
20
src/unistd/arch/vhex/setpgid.S
Normal file
20
src/unistd/arch/vhex/setpgid.S
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _setpgid
|
||||
.type _setpgid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern int setpgid(pid_t __pid, pid_t __pgid);
|
||||
** Set the process group ID of the process matching PID to PGID.
|
||||
** If PID is zero, the current process's process group ID is set.
|
||||
** If PGID is zero, the process ID of the process is used.
|
||||
*/
|
||||
_setpgid:
|
||||
trapa #__NR_setpgid
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
19
src/unistd/arch/vhex/write.S
Normal file
19
src/unistd/arch/vhex/write.S
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifdef __SUPPORT_VHEX_KERNEL
|
||||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _write
|
||||
.type _write, @function
|
||||
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** extern ssize_t write(int __fd, const void *__buf, size_t __nbytes);
|
||||
** Write N bytes of BUF to FD.
|
||||
** Return the number written, or -1.
|
||||
*/
|
||||
_write:
|
||||
trapa #__NR_write
|
||||
rts
|
||||
nop
|
||||
.end
|
||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _close
|
||||
.type _close, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_close:
|
||||
trapa #__NR_close
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _fork_execve
|
||||
.type _fork_execve, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_fork_execve:
|
||||
trapa #__NR_fork_execve
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _lseek
|
||||
.type _lseek, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_lseek:
|
||||
trapa #__NR_lseek
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _open
|
||||
.type _open, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_open:
|
||||
trapa #__NR_open
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _read
|
||||
.type _read, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_read:
|
||||
trapa #__NR_read
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _setpgid
|
||||
.type _setpgid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_setpgid:
|
||||
trapa #__NR_setpgid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _wait
|
||||
.type _wait, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_wait:
|
||||
trapa #__NR_wait
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _waitpid
|
||||
.type _waitpid, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_waitpid:
|
||||
trapa #__NR_waitpid
|
||||
rts
|
||||
nop
|
||||
.end
|
|
@ -1,12 +0,0 @@
|
|||
#include <asm/unistd_32.h>
|
||||
.text
|
||||
.global _write
|
||||
.type _write, @function
|
||||
|
||||
|
||||
.align 2
|
||||
_write:
|
||||
trapa #__NR_write
|
||||
rts
|
||||
nop
|
||||
.end
|
Loading…
Reference in a new issue