/branches/tracing/uspace/lib/libc/include/event.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/console.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/console/color.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/console/style.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/macros.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/mem.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/kbd/kbd.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/kbd/keycode.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/loader/loader.h |
---|
44,8 → 44,7 |
int phone_id; |
} loader_t; |
extern int loader_spawn(const char *); |
extern loader_t *loader_connect(void); |
extern loader_t *loader_spawn(char *name); |
extern int loader_get_task_id(loader_t *, task_id_t *); |
extern int loader_set_pathname(loader_t *, const char *); |
extern int loader_set_args(loader_t *, char *const []); |
/branches/tracing/uspace/lib/libc/include/ipc/bus.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/ipc/console.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/include/ipc/ipc.h |
---|
47,7 → 47,8 |
} ipc_call_t; |
typedef sysarg_t ipc_callid_t; |
typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *); |
typedef void (* ipc_async_callback_t)(void *private, int retval, |
ipc_call_t *data); |
/* |
* User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow(). |
172,20 → 173,22 |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
(arg4), (arg5), (res1), (res2), (res3), (res4), (res5)) |
extern int ipc_call_sync_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *); |
extern int ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, |
ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5); |
extern int ipc_call_sync_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *, |
ipcarg_t *); |
extern int ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4, |
ipcarg_t *result5); |
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int); |
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t); |
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags); |
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *data, uint32_t usec); |
static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data) |
{ |
return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT); |
} |
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *); |
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *data); |
/* |
* User-friendly wrappers for ipc_answer_fast() and ipc_answer_slow(). |
206,10 → 209,10 |
#define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \ |
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5)) |
extern ipcarg_t ipc_answer_fast(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t); |
extern ipcarg_t ipc_answer_slow(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t); |
extern ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4); |
extern ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5); |
/* |
* User-friendly wrappers for ipc_call_async_fast() and ipc_call_async_slow(). |
217,7 → 220,8 |
* arguments. The macros decide between the fast and the slow version according |
* to m. |
*/ |
#define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \ |
#define ipc_call_async_0(phoneid, method, private, callback, \ |
can_preempt) \ |
ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ |
(callback), (can_preempt)) |
#define ipc_call_async_1(phoneid, method, arg1, private, callback, \ |
241,24 → 245,23 |
ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
(arg4), (arg5), (private), (callback), (can_preempt)) |
extern void ipc_call_async_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, void *, ipc_async_callback_t, int); |
extern void ipc_call_async_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, void *, ipc_async_callback_t, int); |
extern void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private, |
ipc_async_callback_t callback, int can_preempt); |
extern void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private, |
ipc_async_callback_t callback, int can_preempt); |
#define IPC_FLAG_BLOCKING 0x01 |
extern int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3, |
ipcarg_t *phone); |
extern int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3); |
extern int ipc_hangup(int phoneid); |
extern int ipc_register_irq(int inr, int devno, int method, irq_code_t *code); |
extern int ipc_unregister_irq(int inr, int devno); |
extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, |
ipcarg_t arg1, ipcarg_t arg2, int mode); |
extern int ipc_connect_to_me(int, int, int, int, ipcarg_t *); |
extern int ipc_connect_me_to(int, int, int, int); |
extern int ipc_connect_me_to_blocking(int, int, int, int); |
extern int ipc_hangup(int); |
extern int ipc_register_irq(int, int, int, irq_code_t *); |
extern int ipc_unregister_irq(int, int); |
extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int); |
extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t, int); |
/* |
* User-friendly wrappers for ipc_share_in_start(). |
*/ |
271,22 → 274,24 |
#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \ |
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags)) |
extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *); |
extern int ipc_share_in_receive(ipc_callid_t *, size_t *); |
extern int ipc_share_in_finalize(ipc_callid_t, void *, int ); |
extern int ipc_share_out_start(int, void *, int); |
extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *); |
extern int ipc_share_out_finalize(ipc_callid_t, void *); |
extern int ipc_data_read_start(int, void *, size_t); |
extern int ipc_data_read_receive(ipc_callid_t *, size_t *); |
extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t); |
extern int ipc_data_write_start(int, const void *, size_t); |
extern int ipc_data_write_receive(ipc_callid_t *, size_t *); |
extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); |
extern int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg, |
int *flags); |
extern int ipc_share_in_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags); |
extern int ipc_share_out_start(int phoneid, void *src, int flags); |
extern int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags); |
extern int ipc_share_out_finalize(ipc_callid_t callid, void *dst); |
extern int ipc_data_read_start(int phoneid, void *dst, size_t size); |
extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_read_finalize(ipc_callid_t callid, const void *src, |
size_t size); |
extern int ipc_data_write_start(int phoneid, const void *src, size_t size); |
extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size); |
#include <task.h> |
extern int ipc_connect_kbox(task_id_t); |
extern int ipc_connect_kbox(task_id_t id); |
#endif |
/branches/tracing/uspace/lib/libc/include/ipc/services.h |
---|
30,8 → 30,8 |
* @{ |
*/ |
/** |
* @file services.h |
* @brief List of all known services and their codes. |
* @file services.h |
* @brief List of all known services and their codes. |
*/ |
#ifndef LIBIPC_SERVICES_H_ |
38,15 → 38,12 |
#define LIBIPC_SERVICES_H_ |
typedef enum { |
SERVICE_LOAD = 1, |
SERVICE_PCI, |
SERVICE_PCI = 1, |
SERVICE_KEYBOARD, |
SERVICE_VIDEO, |
SERVICE_CONSOLE, |
SERVICE_VFS, |
SERVICE_DEVMAP, |
SERVICE_FHC, |
SERVICE_OBIO |
SERVICE_DEVMAP |
} services_t; |
/* Memory area to be received from NS */ |
/branches/tracing/uspace/lib/libc/include/ipc/fb.h |
---|
48,11 → 48,10 |
FB_VIEWPORT_CREATE, |
FB_VIEWPORT_DELETE, |
FB_SET_STYLE, |
FB_SET_COLOR, |
FB_SET_RGB_COLOR, |
FB_GET_RESOLUTION, |
FB_DRAW_TEXT_DATA, |
FB_FLUSH, |
FB_VIEWPORT_DB, |
FB_DRAW_PPM, |
FB_PREPARE_SHM, |
FB_DROP_SHM, |
60,6 → 59,7 |
FB_VP_DRAW_PIXMAP, |
FB_VP2PIXMAP, |
FB_DROP_PIXMAP, |
FB_TRANS_PUTCHAR, |
FB_ANIM_CREATE, |
FB_ANIM_DROP, |
FB_ANIM_ADDPIXMAP, |
66,11 → 66,10 |
FB_ANIM_CHGVP, |
FB_ANIM_START, |
FB_ANIM_STOP, |
FB_POINTER_MOVE, |
FB_SCREEN_YIELD, |
FB_SCREEN_RECLAIM |
FB_POINTER_MOVE |
} fb_request_t; |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/errno.h |
---|
35,10 → 35,6 |
#ifndef LIBC_ERRNO_H_ |
#define LIBC_ERRNO_H_ |
/* TODO: support threads/fibrils */ |
extern int _errno; |
#define errno _errno |
#include <kernel/errno.h> |
#define ENAMETOOLONG (-256) |
/branches/tracing/uspace/lib/libc/include/task.h |
---|
40,7 → 40,6 |
typedef uint64_t task_id_t; |
extern task_id_t task_get_id(void); |
extern int task_set_name(const char *name); |
extern task_id_t task_spawn(const char *path, char *const argv[]); |
#endif |
/branches/tracing/uspace/lib/libc/include/string.h |
---|
35,60 → 35,32 |
#ifndef LIBC_STRING_H_ |
#define LIBC_STRING_H_ |
#include <mem.h> |
#include <sys/types.h> |
#include <bool.h> |
#define U_SPECIAL '?' |
#define U_BOM 0xfeff |
#define bzero(ptr, len) memset((ptr), 0, (len)) |
/** No size limit constant */ |
#define STR_NO_LIMIT ((size_t) -1) |
extern void * memset(void *, int, size_t); |
extern void * memcpy(void *, const void *, size_t); |
extern void * memmove(void *, const void *, size_t); |
/** Maximum size of a string containing @c length characters */ |
#define STR_BOUNDS(length) ((length) << 2) |
extern int bcmp(const char *, const char *, size_t); |
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz); |
extern int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t sz); |
extern int strcmp(const char *, const char *); |
extern int strncmp(const char *, const char *, size_t); |
extern int stricmp(const char *, const char *); |
extern size_t str_size(const char *str); |
extern size_t wstr_size(const wchar_t *str); |
extern char *strcpy(char *, const char *); |
extern char *strncpy(char *, const char *, size_t); |
extern size_t str_lsize(const char *str, count_t max_len); |
extern size_t wstr_lsize(const wchar_t *str, count_t max_len); |
extern char *strcat(char *, const char *); |
extern count_t str_length(const char *str); |
extern count_t wstr_length(const wchar_t *wstr); |
extern size_t strlen(const char *); |
extern count_t str_nlength(const char *str, size_t size); |
extern count_t wstr_nlength(const wchar_t *str, size_t size); |
extern char *strdup(const char *); |
extern bool ascii_check(wchar_t ch); |
extern bool chr_check(wchar_t ch); |
extern char *strchr(const char *, int); |
extern char *strrchr(const char *, int); |
extern int str_cmp(const char *s1, const char *s2); |
extern int str_lcmp(const char *s1, const char *s2, count_t max_len); |
extern void str_cpy(char *dest, size_t size, const char *src); |
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n); |
extern void str_append(char *dest, size_t size, const char *src); |
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size); |
extern const char *str_chr(const char *str, wchar_t ch); |
extern const char *str_rchr(const char *str, wchar_t ch); |
extern bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos); |
extern bool wstr_remove(wchar_t *str, count_t pos); |
extern char *str_dup(const char *); |
/* |
* TODO: Get rid of this. |
*/ |
extern int stricmp(const char *, const char *); |
extern long int strtol(const char *, char **, int); |
extern unsigned long strtoul(const char *, char **, int); |
/branches/tracing/uspace/lib/libc/include/vfs/vfs.h |
---|
39,8 → 39,7 |
extern char *absolutize(const char *, size_t *); |
extern int mount(const char *, const char *, const char *, const char *, |
const unsigned int flags); |
extern int mount(const char *, const char *, const char *); |
#endif |
/branches/tracing/uspace/lib/libc/include/stdio.h |
---|
49,31 → 49,17 |
int n; \ |
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ |
if (n > 0) \ |
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, str_size(buf)); \ |
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, strlen(buf)); \ |
} |
typedef struct { |
/** Underlying file descriptor. */ |
int fd; |
/** Error indicator. */ |
int error; |
/** End-of-file indicator. */ |
int eof; |
} FILE; |
extern FILE *stdin, *stdout, *stderr; |
extern int getchar(void); |
extern int puts(const char *); |
extern int putchar(int); |
extern int fflush(FILE *); |
extern int printf(const char *, ...); |
extern int asprintf(char **, const char *, ...); |
extern int sprintf(char *, const char *, ...); |
extern int sprintf(char *, const char *fmt, ...); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int vprintf(const char *, va_list); |
80,35 → 66,11 |
extern int vsprintf(char *, const char *, va_list); |
extern int vsnprintf(char *, size_t, const char *, va_list); |
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__) |
extern int rename(const char *, const char *); |
extern FILE *fopen(const char *, const char *); |
extern int fclose(FILE *); |
extern size_t fread(void *, size_t, size_t, FILE *); |
extern size_t fwrite(const void *, size_t, size_t, FILE *); |
extern int feof(FILE *); |
extern int ferror(FILE *); |
extern void clearerr(FILE *); |
extern int fgetc(FILE *); |
extern int fputc(int, FILE *); |
extern int fputs(const char *, FILE *); |
extern int fprintf(FILE *, const char *, ...); |
extern int vfprintf(FILE *, const char *, va_list); |
#define getc fgetc |
#define putc fputc |
extern int fseek(FILE *, long, int); |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/include/io/stream.h |
---|
37,12 → 37,18 |
#include <libarch/types.h> |
#define EMFILE -17 |
#define EMFILE -17 |
extern ssize_t read_stdin(void *, size_t); |
extern int klog_puts(const char *); |
extern void open_console(void); |
extern void close_console(void); |
extern void klog_update(void); |
extern ssize_t read_stdin(void *, size_t); |
extern ssize_t write_stdout(const void *, size_t); |
extern ssize_t write_stderr(const void *, size_t); |
extern int get_cons_phone(void); |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/io/printf_core.h |
---|
39,19 → 39,16 |
#include <stdarg.h> |
/** Structure for specifying output methods for different printf clones. */ |
typedef struct printf_spec { |
/* String output function, returns number of printed characters or EOF */ |
int (*str_write)(const char *, size_t, void *); |
/* Wide string output function, returns number of printed characters or EOF */ |
int (*wstr_write)(const wchar_t *, size_t, void *); |
/* User data - output stream specification, state, locks, etc. */ |
struct printf_spec { |
/* Output function, returns count of printed characters or EOF */ |
int (*write)(void *, size_t, void *); |
/* Support data - output stream specification, its state, locks,... */ |
void *data; |
} printf_spec_t; |
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap); |
}; |
int printf_core(const char *fmt, struct printf_spec *ps ,va_list ap); |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/unistd.h |
---|
44,11 → 44,9 |
#define getpagesize() (PAGE_SIZE) |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
extern ssize_t write(int, const void *, size_t); |
extern ssize_t read(int, void *, size_t); |
60,7 → 58,7 |
extern int chdir(const char *); |
extern char *getcwd(char *buf, size_t); |
extern void _exit(int status) __attribute__ ((noreturn)); |
extern void _exit(int status); |
extern void *sbrk(ssize_t incr); |
extern int usleep(unsigned long usec); |
extern unsigned int sleep(unsigned int seconds); |
/branches/tracing/uspace/lib/libc/include/sys/types.h |
---|
37,15 → 37,11 |
#include <libarch/types.h> |
typedef unsigned long size_t; |
typedef signed long ssize_t; |
typedef long off_t; |
typedef int mode_t; |
typedef int32_t wchar_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/include/async.h |
---|
76,7 → 76,7 |
#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \ |
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (dataptr)) |
extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr); |
extern aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
86,8 → 86,8 |
extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, |
suseconds_t timeout); |
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *)); |
fid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid, |
ipc_call_t *call, void (*cthread)(ipc_callid_t,ipc_call_t *)); |
void async_usleep(suseconds_t timeout); |
void async_create_manager(void); |
void async_destroy_manager(void); |
98,27 → 98,27 |
/* Wrappers for simple communication */ |
#define async_msg_0(phone, method) \ |
ipc_call_async_0((phone), (method), NULL, NULL, true) |
ipc_call_async_0((phone), (method), NULL, NULL, !in_interrupt_handler()) |
#define async_msg_1(phone, method, arg1) \ |
ipc_call_async_1((phone), (method), (arg1), NULL, NULL, \ |
true) |
!in_interrupt_handler()) |
#define async_msg_2(phone, method, arg1, arg2) \ |
ipc_call_async_2((phone), (method), (arg1), (arg2), NULL, NULL, \ |
true) |
!in_interrupt_handler()) |
#define async_msg_3(phone, method, arg1, arg2, arg3) \ |
ipc_call_async_3((phone), (method), (arg1), (arg2), (arg3), NULL, NULL, \ |
true) |
!in_interrupt_handler()) |
#define async_msg_4(phone, method, arg1, arg2, arg3, arg4) \ |
ipc_call_async_4((phone), (method), (arg1), (arg2), (arg3), (arg4), NULL, \ |
NULL, true) |
NULL, !in_interrupt_handler()) |
#define async_msg_5(phone, method, arg1, arg2, arg3, arg4, arg5) \ |
ipc_call_async_5((phone), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), NULL, NULL, true) |
(arg5), NULL, NULL, !in_interrupt_handler()) |
/* |
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros |
* are in the form async_req_m_n(), where m is the number of payload arguments |
* and n is the number of return arguments. The macros decide between the fast |
* and n is the number of return arguments. The macros decidce between the fast |
* and slow verion based on m. |
*/ |
#define async_req_0_0(phoneid, method) \ |
253,6 → 253,8 |
fibril_dec_sercount(); |
} |
extern bool in_interrupt_handler(void); |
extern atomic_t async_futex; |
#endif |
/branches/tracing/uspace/lib/libc/include/thread.h |
---|
45,7 → 45,7 |
extern void __thread_main(uspace_arg_t *); |
extern int thread_create(void (*)(void *), void *, char *, thread_id_t *); |
extern void thread_exit(int) __attribute__ ((noreturn)); |
extern void thread_exit(int); |
extern void thread_detach(thread_id_t); |
extern int thread_join(thread_id_t); |
extern thread_id_t thread_get_id(void); |
/branches/tracing/uspace/lib/libc/include/ddi.h |
---|
37,11 → 37,9 |
#include <task.h> |
extern int device_assign_devno(void); |
extern int physmem_map(void *, void *, unsigned long, int); |
extern int iospace_enable(task_id_t, void *, unsigned long); |
extern int preemption_control(int); |
extern int pio_enable(void *, size_t, void **); |
extern int physmem_map(void *pf, void *vp, unsigned long pages, int flags); |
extern int iospace_enable(task_id_t id, void *ioaddr, unsigned long size); |
extern int preemption_control(int enable); |
#endif |
/branches/tracing/uspace/lib/libc/arch/ia64/include/ddi.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2005 Jakub Jermar, Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcia64 |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
35,80 → 35,63 |
#ifndef LIBC_ia64_DDI_H_ |
#define LIBC_ia64_DDI_H_ |
#include <sys/types.h> |
#include <libarch/types.h> |
#define IO_SPACE_BOUNDARY (64 * 1024) |
typedef uint64_t ioport_t; |
uint64_t get_ia64_iospace_address(void); |
extern uint64_t ia64_iospace_address; |
#define IA64_IOSPACE_ADDRESS \ |
(ia64_iospace_address ? \ |
ia64_iospace_address : \ |
(ia64_iospace_address = get_ia64_iospace_address())) |
#define IA64_IOSPACE_ADDRESS (ia64_iospace_address?ia64_iospace_address:(ia64_iospace_address=get_ia64_iospace_address())) |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
static inline void outb(ioport_t port,uint8_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
static inline void outw(ioport_t port,uint16_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
static inline void outl(ioport_t port,uint32_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline uint8_t inb(ioport_t port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
static inline uint16_t inw(ioport_t port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xffE) | ( (port >> 2) << 12 )))); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
static inline uint32_t inl(ioport_t port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
return *((uint32_t *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
#endif |
/** @} |
/branches/tracing/uspace/lib/libc/arch/ia64/include/types.h |
---|
47,11 → 47,6 |
typedef unsigned int uint32_t; |
typedef unsigned long int uint64_t; |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef unsigned char __r8; /* Reserve byte */ |
/branches/tracing/uspace/lib/libc/arch/ia64/Makefile.inc |
---|
29,6 → 29,10 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16 |
35,10 → 39,10 |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/ddi.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c\ |
arch/$(ARCH)/src/ddi.c |
BFD_NAME = elf64-ia64-little |
BFD_ARCH = ia64-elf64 |
/branches/tracing/uspace/lib/libc/arch/ia64/src/entry.s |
---|
38,7 → 38,7 |
# |
__entry: |
alloc loc0 = ar.pfs, 0, 1, 2, 0 |
movl r1 = _gp |
mov r1 = _gp |
# Pass PCB pointer as the first argument to __main |
mov out0 = r2 |
/branches/tracing/uspace/lib/libc/arch/ia64/src/thread_entry.s |
---|
36,7 → 36,7 |
__thread_entry: |
alloc loc0 = ar.pfs, 0, 1, 1, 0 |
movl r1 = _gp |
mov r1 = _gp |
# |
# r8 contains address of uarg structure. |
/branches/tracing/uspace/lib/libc/arch/ia64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
32,11 → 32,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(.scommon); |
/branches/tracing/uspace/lib/libc/arch/ppc32/include/ddi.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/arch/ppc32/include/types.h |
---|
47,11 → 47,6 |
typedef unsigned int uint32_t; |
typedef unsigned long long int uint64_t; |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/ppc32/Makefile.inc |
---|
29,12 → 29,16 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=powerpc -msoft-float -m32 |
AFLAGS += -a32 |
/branches/tracing/uspace/lib/libc/arch/ppc32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
27,11 → 27,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(COMMON); |
/branches/tracing/uspace/lib/libc/arch/sparc64/include/ddi.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/arch/sparc64/include/types.h |
---|
47,11 → 47,6 |
typedef unsigned int uint32_t; |
typedef unsigned long int uint64_t; |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/sparc64/Makefile.inc |
---|
29,11 → 29,15 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=ultrasparc -m64 |
LFLAGS += -no-check-sections -N |
/branches/tracing/uspace/lib/libc/arch/sparc64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
31,11 → 31,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(COMMON); |
/branches/tracing/uspace/lib/libc/arch/arm32/include/ddi.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/arch/arm32/include/types.h |
---|
48,11 → 48,6 |
typedef unsigned long int uint32_t; |
typedef unsigned long long int uint64_t; |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/arm32/Makefile.inc |
---|
30,16 → 30,20 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
CFLAGS += -ffixed-r9 -mtp=soft |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
AFLAGS += |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/eabi.S |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c \ |
arch/$(ARCH)/src/eabi.S |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
/branches/tracing/uspace/lib/libc/arch/arm32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
28,11 → 28,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(.scommon); |
/branches/tracing/uspace/lib/libc/arch/amd64/include/types.h |
---|
47,11 → 47,6 |
typedef unsigned int uint32_t; |
typedef unsigned long long int uint64_t; |
typedef int64_t ssize_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/amd64/Makefile.inc |
---|
29,12 → 29,16 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
LFLAGS += -N |
/branches/tracing/uspace/lib/libc/arch/amd64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
26,11 → 26,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(COMMON); |
*(.bss); |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/syscall.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef LIBC_ppc64_SYSCALL_H_ |
#define LIBC_ppc64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/config.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_CONFIG_H_ |
#define LIBC_ppc64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_BYTEORDER_H_ |
#define LIBC_ppc64_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/tls.h |
---|
0,0 → 1,73 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_TLS_H_ |
#define LIBC_ppc64_TLS_H_ |
#define CONFIG_TLS_VARIANT_1 |
#define PPC_TP_OFFSET 0x7000 |
typedef struct { |
void *fibril_data; |
} tcb_t; |
static inline void __tcb_set(tcb_t *tcb) |
{ |
void *tp = tcb; |
tp += PPC_TP_OFFSET + sizeof(tcb_t); |
asm volatile ( |
"mr %%r2, %0\n" |
: |
: "r" (tp) |
); |
} |
static inline tcb_t * __tcb_get(void) |
{ |
void * retval; |
asm volatile ( |
"mr %0, %%r2\n" |
: "=r" (retval) |
); |
return (tcb_t *)(retval - PPC_TP_OFFSET - sizeof(tcb_t)); |
} |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/thread.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_THREAD_H_ |
#define LIBC_ppc64_THREAD_H_ |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/types.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_TYPES_H_ |
#define LIBC_ppc64_TYPES_H_ |
typedef unsigned long sysarg_t; |
typedef char int8_t; |
typedef short int int16_t; |
typedef int int32_t; |
typedef long int int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short int uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long int uint64_t; |
typedef uint64_t uintptr_t; |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/fibril.h |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_FIBRIL_H_ |
#define LIBC_ppc64_FIBRIL_H_ |
#include <sys/types.h> |
/* We define our own context_set, because we need to set |
* the TLS pointer to the tcb+0x7000 |
* |
* See tls_set in thread.h |
*/ |
#define context_set(c, _pc, stack, size, ptls) \ |
(c)->pc = (sysarg_t) (_pc); \ |
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ |
(c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t); |
#define SP_DELTA 16 |
typedef struct { |
uint64_t sp; |
uint64_t pc; |
uint64_t tls; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
} __attribute__ ((packed)) context_t; |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/atomic.h |
---|
0,0 → 1,95 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_ATOMIC_H_ |
#define LIBC_ppc64_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, 1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc"); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, -1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc"); |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count - 1; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count + 1; |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count; |
} |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/regname.h |
---|
0,0 → 1,188 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_REGNAME_H_ |
#define LIBC_ppc64_REGNAME_H_ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
#define cr1 1 |
#define cr2 2 |
#define cr3 3 |
#define cr4 4 |
#define cr5 5 |
#define cr6 6 |
#define cr7 7 |
/* General Purpose Registers (GPRs) */ |
#define r0 0 |
#define r1 1 |
#define r2 2 |
#define r3 3 |
#define r4 4 |
#define r5 5 |
#define r6 6 |
#define r7 7 |
#define r8 8 |
#define r9 9 |
#define r10 10 |
#define r11 11 |
#define r12 12 |
#define r13 13 |
#define r14 14 |
#define r15 15 |
#define r16 16 |
#define r17 17 |
#define r18 18 |
#define r19 19 |
#define r20 20 |
#define r21 21 |
#define r22 22 |
#define r23 23 |
#define r24 24 |
#define r25 25 |
#define r26 26 |
#define r27 27 |
#define r28 28 |
#define r29 29 |
#define r30 30 |
#define r31 31 |
/* GPR Aliases */ |
#define sp 1 |
/* Floating Point Registers (FPRs) */ |
#define fr0 0 |
#define fr1 1 |
#define fr2 2 |
#define fr3 3 |
#define fr4 4 |
#define fr5 5 |
#define fr6 6 |
#define fr7 7 |
#define fr8 8 |
#define fr9 9 |
#define fr10 10 |
#define fr11 11 |
#define fr12 12 |
#define fr13 13 |
#define fr14 14 |
#define fr15 15 |
#define fr16 16 |
#define fr17 17 |
#define fr18 18 |
#define fr19 19 |
#define fr20 20 |
#define fr21 21 |
#define fr22 22 |
#define fr23 23 |
#define fr24 24 |
#define fr25 25 |
#define fr26 26 |
#define fr27 27 |
#define fr28 28 |
#define fr29 29 |
#define fr30 30 |
#define fr31 31 |
#define vr0 0 |
#define vr1 1 |
#define vr2 2 |
#define vr3 3 |
#define vr4 4 |
#define vr5 5 |
#define vr6 6 |
#define vr7 7 |
#define vr8 8 |
#define vr9 9 |
#define vr10 10 |
#define vr11 11 |
#define vr12 12 |
#define vr13 13 |
#define vr14 14 |
#define vr15 15 |
#define vr16 16 |
#define vr17 17 |
#define vr18 18 |
#define vr19 19 |
#define vr20 20 |
#define vr21 21 |
#define vr22 22 |
#define vr23 23 |
#define vr24 24 |
#define vr25 25 |
#define vr26 26 |
#define vr27 27 |
#define vr28 28 |
#define vr29 29 |
#define vr30 30 |
#define vr31 31 |
#define evr0 0 |
#define evr1 1 |
#define evr2 2 |
#define evr3 3 |
#define evr4 4 |
#define evr5 5 |
#define evr6 6 |
#define evr7 7 |
#define evr8 8 |
#define evr9 9 |
#define evr10 10 |
#define evr11 11 |
#define evr12 12 |
#define evr13 13 |
#define evr14 14 |
#define evr15 15 |
#define evr16 16 |
#define evr17 17 |
#define evr18 18 |
#define evr19 19 |
#define evr20 20 |
#define evr21 21 |
#define evr22 22 |
#define evr23 23 |
#define evr24 24 |
#define evr25 25 |
#define evr26 26 |
#define evr27 27 |
#define evr28 28 |
#define evr29 29 |
#define evr30 30 |
#define evr31 31 |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/stackarg.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_STACKARG_H_ |
#define LIBC_STACKARG_H_ |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/faddr.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_FADDR_H_ |
#define LIBC_ppc64_FADDR_H_ |
#include <libarch/types.h> |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/include/limits.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_LIMITS_H_ |
#define LIBC_ppc64_LIMITS_H_ |
#define LONG_MIN MIN_INT64 |
#define LONG_MAX MAX_INT64 |
#define ULONG_MIN MIN_UINT64 |
#define ULONG_MAX MAX_UINT64 |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/Makefile.inc |
---|
0,0 → 1,48 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
LFLAGS += -N |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/entry.s |
---|
0,0 → 1,40 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.section .init, "ax" |
.org 0 |
.globl __entry |
## User-space task entry point |
# |
# |
__entry: |
bl __main |
bl __exit |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/fibril.S |
---|
0,0 → 1,62 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.global context_save |
.global context_restore |
#include <libarch/regname.h> |
#include <kernel/arch/context_offset.h> |
context_save: |
CONTEXT_SAVE_ARCH_CORE r3 |
mflr r4 |
stw r4, OFFSET_PC(r3) |
mfcr r4 |
stw r4, OFFSET_CR(r3) |
# context_save returns 1 |
li r3, 1 |
blr |
context_restore: |
CONTEXT_RESTORE_ARCH_CORE r3 |
lwz r4, OFFSET_CR(r3) |
mtcr r4 |
lwz r4, OFFSET_PC(r3) |
mtlr r4 |
# context_restore returns 0 |
li r3, 0 |
blr |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/syscall.c |
---|
0,0 → 1,66 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 ppc64 |
* @brief ppc64 architecture dependent parts of libc |
* @ingroup lc |
* @{ |
*/ |
/** @file |
*/ |
#include <libc.h> |
sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3, |
const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id) |
{ |
register sysarg_t __ppc32_reg_r3 asm("3") = p1; |
register sysarg_t __ppc32_reg_r4 asm("4") = p2; |
register sysarg_t __ppc32_reg_r5 asm("5") = p3; |
register sysarg_t __ppc32_reg_r6 asm("6") = p4; |
register sysarg_t __ppc32_reg_r7 asm("7") = p5; |
register sysarg_t __ppc32_reg_r8 asm("8") = p6; |
register sysarg_t __ppc32_reg_r9 asm("9") = id; |
asm volatile ( |
"sc\n" |
: "=r" (__ppc32_reg_r3) |
: "r" (__ppc32_reg_r3), |
"r" (__ppc32_reg_r4), |
"r" (__ppc32_reg_r5), |
"r" (__ppc32_reg_r6), |
"r" (__ppc32_reg_r7), |
"r" (__ppc32_reg_r8), |
"r" (__ppc32_reg_r9) |
); |
return __ppc32_reg_r3; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/tls.c |
---|
0,0 → 1,60 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <tls.h> |
#include <malloc.h> |
/** Allocate TLS & TCB for initial module threads |
* |
* @param data Start of data section |
* @return pointer to tcb_t structure |
* |
*/ |
tcb_t * __alloc_tls(void **data, size_t size) |
{ |
tcb_t *tcb; |
*data = malloc(sizeof(tcb_t) + size); |
tcb = (tcb_t *) (*data + size); |
return tcb; |
} |
void __free_tls_arch(tcb_t *tcb, size_t size) |
{ |
void *start = ((void *) tcb) - size; |
free(start); |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/arch/ppc64/src/thread_entry.s |
---|
0,0 → 1,39 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.globl __thread_entry |
## User-space thread entry point for all but the first threads. |
# |
# |
__thread_entry: |
b __thread_main |
.end __thread_entry |
/branches/tracing/uspace/lib/libc/arch/ppc64/_link.ld.in |
---|
0,0 → 1,52 |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
text PT_LOAD FLAGS(5); |
data PT_LOAD FLAGS(6); |
} |
SECTIONS { |
. = 0x1000 + SIZEOF_HEADERS; |
.init : { |
*(.init); |
} :text |
.text : { |
*(.text); |
*(.toc); |
*(.rodata*); |
} :text |
. = . + 0x1000; |
.data : { |
*(.opd); |
*(.data*); |
*(.sdata); |
} :data |
.tdata : { |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(COMMON); |
*(.bss); |
} :data |
. = ALIGN(0x1000); |
_heap = .; |
/DISCARD/ : { |
*(*); |
} |
} |
/branches/tracing/uspace/lib/libc/arch/mips32/include/ddi.h |
---|
File deleted |
/branches/tracing/uspace/lib/libc/arch/mips32/include/atomic.h |
---|
59,14 → 59,13 |
asm volatile ( |
"1:\n" |
" ll %0, %1\n" |
" addu %0, %0, %3\n" /* same as add, but never traps on overflow */ |
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
/* nop */ /* nop is inserted automatically by compiler */ |
" nop\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "r" (i), "i" (0) |
: "i" (i), "i" (0) |
); |
return v; |
/branches/tracing/uspace/lib/libc/arch/mips32/include/types.h |
---|
48,11 → 48,6 |
typedef unsigned long int uint32_t; |
typedef unsigned long long int uint64_t; |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/mips32/Makefile.inc |
---|
29,13 → 29,23 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
-include ../../Makefile.config |
ifeq ($(CONFIG_MIPS_FPU),y) |
CFLAGS += -DCONFIG_MIPS_FPU |
endif |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
BFD_ARCH = mips |
BFD_NAME = elf32-tradlittlemips |
/branches/tracing/uspace/lib/libc/arch/mips32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
33,11 → 33,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.sbss : { |
*(.scommon); |
/branches/tracing/uspace/lib/libc/arch/ia32/include/types.h |
---|
47,11 → 47,6 |
typedef unsigned int uint32_t; |
typedef unsigned long long int uint64_t; |
typedef int32_t ssize_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
#endif |
/branches/tracing/uspace/lib/libc/arch/ia32/include/ddi.h |
---|
33,72 → 33,43 |
#ifndef LIBC_ia32_DDI_H_ |
#define LIBC_ia32_DDI_H_ |
#include <sys/types.h> |
#include <libarch/types.h> |
static inline void outb(int16_t port, uint8_t b) |
{ |
asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port)); |
} |
#define IO_SPACE_BOUNDARY ((void *) (64 * 1024)) |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline void outw(int16_t port, int16_t w) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port)); |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
static inline void outl(int16_t port, uint32_t l) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port)); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
static inline uint8_t inb(int16_t port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
uint8_t val; |
asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline int16_t inw(int16_t port) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
int16_t val; |
asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
static inline uint32_t inl(int16_t port) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
uint32_t val; |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
#endif |
/branches/tracing/uspace/lib/libc/arch/ia32/Makefile.inc |
---|
29,13 → 29,17 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/setjmp.S |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c \ |
arch/$(ARCH)/src/setjmp.S |
LFLAGS += -N |
/branches/tracing/uspace/lib/libc/arch/ia32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
26,11 → 26,13 |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = ALIGNOF(.tdata); |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(COMMON); |
*(.bss); |
/branches/tracing/uspace/lib/libc/arch/mips32eb/Makefile.inc |
---|
29,15 → 29,19 |
## Toolchain configuration |
# |
TARGET = mips-linux-gnu |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
CFLAGS += -mips3 |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
LFLAGS += -N |
BFD_ARCH = mips |
BFD_NAME = elf32-tradbigmips |
BFD_NAME = elf32-big |
/branches/tracing/uspace/lib/libc/arch/mips32eb/include/ddi.h |
---|
File deleted |
\ No newline at end of file |
/branches/tracing/uspace/lib/libc/generic/kbd.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/mem.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/event.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/console.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/task.c |
---|
38,7 → 38,6 |
#include <stdlib.h> |
#include <errno.h> |
#include <loader/loader.h> |
#include <string.h> |
task_id_t task_get_id(void) |
{ |
49,17 → 48,6 |
return task_id; |
} |
/** Set the task name. |
* |
* @param name The new name, typically the command used to execute the |
* program. |
* @return Zero on success or negative error code. |
*/ |
int task_set_name(const char *name) |
{ |
return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, str_size(name)); |
} |
/** Create a new task by running an executable from the filesystem. |
* |
* This is really just a convenience wrapper over the more complicated |
75,8 → 63,8 |
task_id_t task_id; |
int rc; |
/* Connect to a program loader. */ |
ldr = loader_connect(); |
/* Spawn a program loader. */ |
ldr = loader_spawn(path); |
if (ldr == NULL) |
return 0; |
101,6 → 89,7 |
goto error; |
/* Run it. */ |
/* Load the program. */ |
rc = loader_run(ldr); |
if (rc != EOK) |
goto error; |
/branches/tracing/uspace/lib/libc/generic/loader.c |
---|
34,7 → 34,6 |
#include <ipc/ipc.h> |
#include <ipc/loader.h> |
#include <ipc/services.h> |
#include <libc.h> |
#include <task.h> |
#include <string.h> |
51,27 → 50,33 |
* @return Pointer to the loader connection structure (should be |
* de-allocated using free() after use). |
*/ |
int loader_spawn(const char *name) |
loader_t *loader_spawn(char *name) |
{ |
return __SYSCALL2(SYS_PROGRAM_SPAWN_LOADER, |
(sysarg_t) name, str_size(name)); |
} |
loader_t *loader_connect(void) |
{ |
int phone_id, rc; |
loader_t *ldr; |
int phone_id; |
phone_id = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_LOAD, 0, 0); |
if (phone_id < 0) |
/* |
* Ask kernel to spawn a new loader task. |
*/ |
rc = __SYSCALL3(SYS_PROGRAM_SPAWN_LOADER, (sysarg_t) &phone_id, |
(sysarg_t) name, strlen(name)); |
if (rc != 0) |
return NULL; |
/* |
* Say hello so that the loader knows the incoming connection's |
* phone hash. |
*/ |
rc = async_req_0_0(phone_id, LOADER_HELLO); |
if (rc != EOK) |
return NULL; |
ldr = malloc(sizeof(loader_t)); |
if (ldr == NULL) |
return NULL; |
ldr->phone_id = phone_id; |
return ldr; |
return ldr; |
} |
/** Get ID of the new task. |
168,7 → 173,7 |
ap = argv; |
buffer_size = 0; |
while (*ap != NULL) { |
buffer_size += str_size(*ap) + 1; |
buffer_size += strlen(*ap) + 1; |
++ap; |
} |
178,10 → 183,9 |
/* Now fill the buffer with null-terminated argument strings */ |
ap = argv; |
dp = arg_buf; |
while (*ap != NULL) { |
str_cpy(dp, buffer_size - (dp - arg_buf), *ap); |
dp += str_size(*ap) + 1; |
strcpy(dp, *ap); |
dp += strlen(*ap) + 1; |
++ap; |
} |
243,8 → 247,6 |
if (rc != EOK) |
return rc; |
ipc_hangup(ldr->phone_id); |
ldr->phone_id = 0; |
return EOK; |
} |
/branches/tracing/uspace/lib/libc/generic/thread.c |
---|
109,7 → 109,7 |
uarg->uspace_uarg = uarg; |
rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name, |
(sysarg_t) str_size(name), (sysarg_t) tid); |
(sysarg_t) strlen(name), (sysarg_t) tid); |
if (rc) { |
/* |
130,8 → 130,6 |
void thread_exit(int status) |
{ |
__SYSCALL1(SYS_THREAD_EXIT, (sysarg_t) status); |
for (;;) |
; |
} |
/** Detach thread. |
154,7 → 152,6 |
*/ |
int thread_join(thread_id_t thread) |
{ |
return 0; |
} |
/** Get current thread ID. |
/branches/tracing/uspace/lib/libc/generic/ipc.c |
---|
598,7 → 598,7 |
ipcarg_t newphid; |
int res; |
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
NULL, NULL, NULL, NULL, &newphid); |
if (res) |
return res; |
605,30 → 605,6 |
return newphid; |
} |
/** Ask through phone for a new connection to some service. |
* |
* If the connection is not available at the moment, the |
* call will block. |
* |
* @param phoneid Phone handle used for contacting the other side. |
* @param arg1 User defined argument. |
* @param arg2 User defined argument. |
* @param arg3 User defined argument. |
* |
* @return New phone handle on success or a negative error code. |
*/ |
int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3) |
{ |
ipcarg_t newphid; |
int res; |
res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); |
if (res) |
return res; |
return newphid; |
} |
/** Hang up a phone. |
* |
* @param phoneid Handle of the phone to be hung up. |
690,23 → 666,6 |
arg2, mode); |
} |
int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
int mode) |
{ |
ipc_call_t data; |
IPC_SET_METHOD(data, method); |
IPC_SET_ARG1(data, arg1); |
IPC_SET_ARG2(data, arg2); |
IPC_SET_ARG3(data, arg3); |
IPC_SET_ARG4(data, arg4); |
IPC_SET_ARG5(data, arg5); |
return __SYSCALL3(SYS_IPC_FORWARD_SLOW, callid, (sysarg_t) &data, mode); |
} |
/** Wrapper for making IPC_M_SHARE_IN calls. |
* |
* @param phoneid Phone that will be used to contact the receiving side. |
/branches/tracing/uspace/lib/libc/generic/vfs/vfs.c |
---|
31,7 → 31,7 |
*/ |
/** @file |
*/ |
#include <vfs/vfs.h> |
#include <vfs/canonify.h> |
#include <stdlib.h> |
49,7 → 49,7 |
#include <errno.h> |
#include <string.h> |
#include <ipc/devmap.h> |
#include "../../../srv/vfs/vfs.h" |
#include "../../srv/vfs/vfs.h" |
int vfs_phone = -1; |
futex_t vfs_phone_futex = FUTEX_INITIALIZER; |
57,7 → 57,7 |
futex_t cwd_futex = FUTEX_INITIALIZER; |
DIR *cwd_dir = NULL; |
char *cwd_path = NULL; |
size_t cwd_size = 0; |
size_t cwd_len = 0; |
char *absolutize(const char *path, size_t *retlen) |
{ |
65,22 → 65,22 |
char *ncwd_path_nc; |
futex_down(&cwd_futex); |
size_t size = str_size(path); |
size_t len = strlen(path); |
if (*path != '/') { |
if (!cwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path_nc = malloc(cwd_size + 1 + size + 1); |
ncwd_path_nc = malloc(cwd_len + 1 + len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
} |
str_cpy(ncwd_path_nc, cwd_size + 1 + size + 1, cwd_path); |
ncwd_path_nc[cwd_size] = '/'; |
ncwd_path_nc[cwd_size + 1] = '\0'; |
strcpy(ncwd_path_nc, cwd_path); |
ncwd_path_nc[cwd_len] = '/'; |
ncwd_path_nc[cwd_len + 1] = '\0'; |
} else { |
ncwd_path_nc = malloc(size + 1); |
ncwd_path_nc = malloc(len + 1); |
if (!ncwd_path_nc) { |
futex_up(&cwd_futex); |
return NULL; |
87,7 → 87,7 |
} |
ncwd_path_nc[0] = '\0'; |
} |
str_append(ncwd_path_nc, cwd_size + 1 + size + 1, path); |
strcat(ncwd_path_nc, path); |
ncwd_path = canonify(ncwd_path_nc, retlen); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
99,7 → 99,7 |
* the address in ncwd_path need not be the same as ncwd_path_nc, even |
* though they both point into the same dynamically allocated buffer. |
*/ |
ncwd_path = str_dup(ncwd_path); |
ncwd_path = strdup(ncwd_path); |
free(ncwd_path_nc); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
109,39 → 109,34 |
return ncwd_path; |
} |
static void vfs_connect(void) |
static int vfs_connect(void) |
{ |
while (vfs_phone < 0) |
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); |
if (vfs_phone < 0) |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
return vfs_phone; |
} |
static int device_get_handle(const char *name, dev_handle_t *handle, |
const unsigned int flags) |
static int device_get_handle(const char *name, dev_handle_t *handle) |
{ |
int phone; |
if (flags & IPC_FLAG_BLOCKING) |
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
else |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, |
0); |
if (phone < 0) |
return phone; |
ipc_call_t answer; |
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0, |
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, 0, 0, |
&answer); |
ipcarg_t retval = ipc_data_write_start(phone, name, str_size(name) + 1); |
ipcarg_t retval = ipc_data_write_start(phone, name, strlen(name) + 1); |
if (retval != EOK) { |
async_wait_for(req, NULL); |
ipc_hangup(phone); |
return retval; |
} |
async_wait_for(req, &retval); |
if (handle != NULL) |
*handle = -1; |
154,8 → 149,7 |
return retval; |
} |
int mount(const char *fs_name, const char *mp, const char *dev, |
const char *opts, const unsigned int flags) |
int mount(const char *fs_name, const char *mp, const char *dev) |
{ |
int res; |
ipcarg_t rc; |
162,30 → 156,28 |
aid_t req; |
dev_handle_t dev_handle; |
res = device_get_handle(dev, &dev_handle, flags); |
res = device_get_handle(dev, &dev_handle); |
if (res != EOK) |
return res; |
size_t mpa_size; |
char *mpa = absolutize(mp, &mpa_size); |
size_t mpa_len; |
char *mpa = absolutize(mp, &mpa_len); |
if (!mpa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL); |
rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_size); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return res; |
} |
} |
rc = ipc_data_write_start(vfs_phone, (void *) opts, str_size(opts)); |
req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL); |
rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name)); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
193,8 → 185,8 |
free(mpa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, (void *) fs_name, str_size(fs_name)); |
/* Ask VFS whether it likes fs_name. */ |
rc = async_req_0_0(vfs_phone, IPC_M_PING); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
202,9 → 194,7 |
free(mpa); |
return (int) rc; |
} |
/* Ask VFS whether it likes fs_name. */ |
rc = async_req_0_0(vfs_phone, IPC_M_PING); |
rc = ipc_data_write_start(vfs_phone, (void *)mpa, mpa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
212,32 → 202,38 |
free(mpa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
static int _open(const char *path, int lflag, int oflag, ...) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
size_t pa_size; |
char *pa = absolutize(path, &pa_size); |
size_t pa_len; |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer); |
rc = ipc_data_write_start(vfs_phone, pa, pa_size); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
262,14 → 258,22 |
int close(int fildes) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
rc = async_req_1_0(vfs_phone, VFS_CLOSE, fildes); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
278,6 → 282,7 |
ssize_t read(int fildes, void *buf, size_t nbyte) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
284,8 → 289,14 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_READ, fildes, &answer); |
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte); |
if (rc != EOK) { |
305,6 → 316,7 |
ssize_t write(int fildes, const void *buf, size_t nbyte) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
311,8 → 323,14 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer); |
rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte); |
if (rc != EOK) { |
332,12 → 350,20 |
off_t lseek(int fildes, off_t offset, int whence) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
ipcarg_t newoffs; |
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence, |
&newoffs); |
353,12 → 379,19 |
int ftruncate(int fildes, off_t length) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
400,20 → 433,28 |
int mkdir(const char *path, mode_t mode) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
size_t pa_size; |
char *pa = absolutize(path, &pa_size); |
size_t pa_len; |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL); |
rc = ipc_data_write_start(vfs_phone, pa, pa_size); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
430,20 → 471,28 |
static int _unlink(const char *path, int lflag) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
size_t pa_size; |
char *pa = absolutize(path, &pa_size); |
size_t pa_len; |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_0(vfs_phone, VFS_UNLINK, NULL); |
rc = ipc_data_write_start(vfs_phone, pa, pa_size); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
470,16 → 519,17 |
int rename(const char *old, const char *new) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
size_t olda_size; |
char *olda = absolutize(old, &olda_size); |
size_t olda_len; |
char *olda = absolutize(old, &olda_len); |
if (!olda) |
return ENOMEM; |
size_t newa_size; |
char *newa = absolutize(new, &newa_size); |
size_t newa_len; |
char *newa = absolutize(new, &newa_len); |
if (!newa) { |
free(olda); |
return ENOMEM; |
487,10 → 537,18 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(olda); |
free(newa); |
return res; |
} |
} |
req = async_send_0(vfs_phone, VFS_RENAME, NULL); |
rc = ipc_data_write_start(vfs_phone, olda, olda_size); |
rc = ipc_data_write_start(vfs_phone, olda, olda_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
499,7 → 557,7 |
free(newa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, newa, newa_size); |
rc = ipc_data_write_start(vfs_phone, newa, newa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
518,8 → 576,8 |
int chdir(const char *path) |
{ |
size_t pa_size; |
char *pa = absolutize(path, &pa_size); |
size_t pa_len; |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return ENOMEM; |
535,11 → 593,11 |
cwd_dir = NULL; |
free(cwd_path); |
cwd_path = NULL; |
cwd_size = 0; |
cwd_len = 0; |
} |
cwd_dir = d; |
cwd_path = pa; |
cwd_size = pa_size; |
cwd_len = pa_len; |
futex_up(&cwd_futex); |
return EOK; |
} |
549,11 → 607,11 |
if (!size) |
return NULL; |
futex_down(&cwd_futex); |
if (size < cwd_size + 1) { |
if (size < cwd_len + 1) { |
futex_up(&cwd_futex); |
return NULL; |
} |
str_cpy(buf, size, cwd_path); |
strcpy(buf, cwd_path); |
futex_up(&cwd_futex); |
return buf; |
} |
/branches/tracing/uspace/lib/libc/generic/string.c |
---|
1,6 → 1,7 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2008 Jiri Svoboda |
* Copyright (C) 1998 by Wes Peters <wes@softweyr.com> |
* Copyright (c) 1988, 1993 The Regents of the University of California. |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
34,665 → 35,180 |
*/ |
#include <string.h> |
#include <stdlib.h> |
#include <assert.h> |
#include <unistd.h> |
#include <ctype.h> |
#include <limits.h> |
#include <ctype.h> |
#include <align.h> |
#include <sys/types.h> |
#include <malloc.h> |
#include <errno.h> |
#include <align.h> |
#include <mem.h> |
#include <string.h> |
/** Byte mask consisting of lowest @n bits (out of 8) */ |
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1)) |
/* Dummy implementation of mem/ functions */ |
/** Byte mask consisting of lowest @n bits (out of 32) */ |
#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1)) |
/** Byte mask consisting of highest @n bits (out of 8) */ |
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n))) |
/** Number of data bits in a UTF-8 continuation byte */ |
#define CONT_BITS 6 |
/** Decode a single character from a string. |
* |
* Decode a single character from a string of size @a size. Decoding starts |
* at @a offset and this offset is moved to the beginning of the next |
* character. In case of decoding error, offset generally advances at least |
* by one. However, offset is never moved beyond size. |
* |
* @param str String (not necessarily NULL-terminated). |
* @param offset Byte offset in string where to start decoding. |
* @param size Size of the string (in bytes). |
* |
* @return Value of decoded character, U_SPECIAL on decoding error or |
* NULL if attempt to decode beyond @a size. |
* |
*/ |
wchar_t str_decode(const char *str, size_t *offset, size_t size) |
void *memset(void *s, int c, size_t n) |
{ |
if (*offset + 1 > size) |
return 0; |
char *os = s; |
/* First byte read from string */ |
uint8_t b0 = (uint8_t) str[(*offset)++]; |
while (n--) |
*(os++) = c; |
/* Determine code length */ |
unsigned int b0_bits; /* Data bits in first byte */ |
unsigned int cbytes; /* Number of continuation bytes */ |
if ((b0 & 0x80) == 0) { |
/* 0xxxxxxx (Plain ASCII) */ |
b0_bits = 7; |
cbytes = 0; |
} else if ((b0 & 0xe0) == 0xc0) { |
/* 110xxxxx 10xxxxxx */ |
b0_bits = 5; |
cbytes = 1; |
} else if ((b0 & 0xf0) == 0xe0) { |
/* 1110xxxx 10xxxxxx 10xxxxxx */ |
b0_bits = 4; |
cbytes = 2; |
} else if ((b0 & 0xf8) == 0xf0) { |
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ |
b0_bits = 3; |
cbytes = 3; |
} else { |
/* 10xxxxxx -- unexpected continuation byte */ |
return U_SPECIAL; |
} |
if (*offset + cbytes > size) |
return U_SPECIAL; |
wchar_t ch = b0 & LO_MASK_8(b0_bits); |
/* Decode continuation bytes */ |
while (cbytes > 0) { |
uint8_t b = (uint8_t) str[(*offset)++]; |
/* Must be 10xxxxxx */ |
if ((b & 0xc0) != 0x80) |
return U_SPECIAL; |
/* Shift data bits to ch */ |
ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS)); |
cbytes--; |
} |
return ch; |
return s; |
} |
/** Encode a single character to string representation. |
* |
* Encode a single character to string representation (i.e. UTF-8) and store |
* it into a buffer at @a offset. Encoding starts at @a offset and this offset |
* is moved to the position where the next character can be written to. |
* |
* @param ch Input character. |
* @param str Output buffer. |
* @param offset Byte offset where to start writing. |
* @param size Size of the output buffer (in bytes). |
* |
* @return EOK if the character was encoded successfully, EOVERFLOW if there |
* was not enough space in the output buffer or EINVAL if the character |
* code was invalid. |
*/ |
int chr_encode(const wchar_t ch, char *str, size_t *offset, size_t size) |
{ |
if (*offset >= size) |
return EOVERFLOW; |
if (!chr_check(ch)) |
return EINVAL; |
/* Unsigned version of ch (bit operations should only be done |
on unsigned types). */ |
uint32_t cc = (uint32_t) ch; |
/* Determine how many continuation bytes are needed */ |
unsigned int b0_bits; /* Data bits in first byte */ |
unsigned int cbytes; /* Number of continuation bytes */ |
if ((cc & ~LO_MASK_32(7)) == 0) { |
b0_bits = 7; |
cbytes = 0; |
} else if ((cc & ~LO_MASK_32(11)) == 0) { |
b0_bits = 5; |
cbytes = 1; |
} else if ((cc & ~LO_MASK_32(16)) == 0) { |
b0_bits = 4; |
cbytes = 2; |
} else if ((cc & ~LO_MASK_32(21)) == 0) { |
b0_bits = 3; |
cbytes = 3; |
} else { |
/* Codes longer than 21 bits are not supported */ |
return EINVAL; |
} |
/* Check for available space in buffer */ |
if (*offset + cbytes >= size) |
return EOVERFLOW; |
/* Encode continuation bytes */ |
unsigned int i; |
for (i = cbytes; i > 0; i--) { |
str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS)); |
cc = cc >> CONT_BITS; |
} |
/* Encode first byte */ |
str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1); |
/* Advance offset */ |
*offset += cbytes + 1; |
return EOK; |
} |
struct along { |
unsigned long n; |
} __attribute__ ((packed)); |
/** Get size of string. |
* |
* Get the number of bytes which are used by the string @a str (excluding the |
* NULL-terminator). |
* |
* @param str String to consider. |
* |
* @return Number of bytes used by the string |
* |
*/ |
size_t str_size(const char *str) |
static void *unaligned_memcpy(void *dst, const void *src, size_t n) |
{ |
size_t size = 0; |
while (*str++ != 0) |
size++; |
return size; |
} |
int i, j; |
struct along *adst = dst; |
const struct along *asrc = src; |
/** Get size of wide string. |
* |
* Get the number of bytes which are used by the wide string @a str (excluding the |
* NULL-terminator). |
* |
* @param str Wide string to consider. |
* |
* @return Number of bytes used by the wide string |
* |
*/ |
size_t wstr_size(const wchar_t *str) |
{ |
return (wstr_length(str) * sizeof(wchar_t)); |
} |
/** Get size of string with length limit. |
* |
* Get the number of bytes which are used by up to @a max_len first |
* characters in the string @a str. If @a max_len is greater than |
* the length of @a str, the entire string is measured (excluding the |
* NULL-terminator). |
* |
* @param str String to consider. |
* @param max_len Maximum number of characters to measure. |
* |
* @return Number of bytes used by the characters. |
* |
*/ |
size_t str_lsize(const char *str, count_t max_len) |
{ |
count_t len = 0; |
size_t offset = 0; |
while (len < max_len) { |
if (str_decode(str, &offset, STR_NO_LIMIT) == 0) |
break; |
for (i = 0; i < n / sizeof(unsigned long); i++) |
adst[i].n = asrc[i].n; |
len++; |
} |
return offset; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) dst; |
} |
/** Get size of wide string with length limit. |
* |
* Get the number of bytes which are used by up to @a max_len first |
* wide characters in the wide string @a str. If @a max_len is greater than |
* the length of @a str, the entire wide string is measured (excluding the |
* NULL-terminator). |
* |
* @param str Wide string to consider. |
* @param max_len Maximum number of wide characters to measure. |
* |
* @return Number of bytes used by the wide characters. |
* |
*/ |
size_t wstr_lsize(const wchar_t *str, count_t max_len) |
void *memcpy(void *dst, const void *src, size_t n) |
{ |
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t)); |
} |
int i, j; |
/** Get number of characters in a string. |
* |
* @param str NULL-terminated string. |
* |
* @return Number of characters in string. |
* |
*/ |
count_t str_length(const char *str) |
{ |
count_t len = 0; |
size_t offset = 0; |
while (str_decode(str, &offset, STR_NO_LIMIT) != 0) |
len++; |
return len; |
} |
if (((long) dst & (sizeof(long) - 1)) || |
((long) src & (sizeof(long) - 1))) |
return unaligned_memcpy(dst, src, n); |
/** Get number of characters in a wide string. |
* |
* @param str NULL-terminated wide string. |
* |
* @return Number of characters in @a str. |
* |
*/ |
count_t wstr_length(const wchar_t *wstr) |
{ |
count_t len = 0; |
while (*wstr++ != 0) |
len++; |
return len; |
for (i = 0; i < n / sizeof(unsigned long); i++) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = |
((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) dst; |
} |
/** Get number of characters in a string with size limit. |
* |
* @param str NULL-terminated string. |
* @param size Maximum number of bytes to consider. |
* |
* @return Number of characters in string. |
* |
*/ |
count_t str_nlength(const char *str, size_t size) |
void *memmove(void *dst, const void *src, size_t n) |
{ |
count_t len = 0; |
size_t offset = 0; |
int i, j; |
while (str_decode(str, &offset, size) != 0) |
len++; |
return len; |
} |
if (src > dst) |
return memcpy(dst, src, n); |
/** Get number of characters in a string with size limit. |
* |
* @param str NULL-terminated string. |
* @param size Maximum number of bytes to consider. |
* |
* @return Number of characters in string. |
* |
*/ |
count_t wstr_nlength(const wchar_t *str, size_t size) |
{ |
count_t len = 0; |
count_t limit = ALIGN_DOWN(size, sizeof(wchar_t)); |
count_t offset = 0; |
while ((offset < limit) && (*str++ != 0)) { |
len++; |
offset += sizeof(wchar_t); |
} |
return len; |
} |
for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--) |
((unsigned char *) ((unsigned long *) dst))[j] = |
((unsigned char *) ((unsigned long *) src))[j]; |
/** Check whether character is plain ASCII. |
* |
* @return True if character is plain ASCII. |
* |
*/ |
bool ascii_check(wchar_t ch) |
{ |
if ((ch >= 0) && (ch <= 127)) |
return true; |
return false; |
for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
return (char *) dst; |
} |
/** Check whether character is valid |
/** Compare two memory areas. |
* |
* @return True if character is a valid Unicode code point. |
* |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have |
* the same length. |
* @return If len is 0, return zero. If the areas match, return |
* zero. Otherwise return non-zero. |
*/ |
bool chr_check(wchar_t ch) |
int bcmp(const char *s1, const char *s2, size_t len) |
{ |
if ((ch >= 0) && (ch <= 1114111)) |
return true; |
return false; |
for (; len && *s1++ == *s2++; len--) |
; |
return len; |
} |
/** Compare two NULL terminated strings. |
/** Count the number of characters in the string, not including terminating 0. |
* |
* Do a char-by-char comparison of two NULL-terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths. |
* |
* @param s1 First string to compare. |
* @param s2 Second string to compare. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, |
* 1 if second smaller. |
* |
* @param str String. |
* @return Number of characters in string. |
*/ |
int str_cmp(const char *s1, const char *s2) |
size_t strlen(const char *str) |
{ |
wchar_t c1 = 0; |
wchar_t c2 = 0; |
size_t off1 = 0; |
size_t off2 = 0; |
size_t counter = 0; |
while (true) { |
c1 = str_decode(s1, &off1, STR_NO_LIMIT); |
c2 = str_decode(s2, &off2, STR_NO_LIMIT); |
while (str[counter] != 0) |
counter++; |
if (c1 < c2) |
return -1; |
if (c1 > c2) |
return 1; |
if (c1 == 0 || c2 == 0) |
break; |
} |
return 0; |
return counter; |
} |
/** Compare two NULL terminated strings with length limit. |
* |
* Do a char-by-char comparison of two NULL-terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths and the length limit. |
* |
* @param s1 First string to compare. |
* @param s2 Second string to compare. |
* @param max_len Maximum number of characters to consider. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, |
* 1 if second smaller. |
* |
*/ |
int str_lcmp(const char *s1, const char *s2, count_t max_len) |
int strcmp(const char *a, const char *b) |
{ |
wchar_t c1 = 0; |
wchar_t c2 = 0; |
int c = 0; |
size_t off1 = 0; |
size_t off2 = 0; |
while (a[c] && b[c] && (!(a[c] - b[c]))) |
c++; |
count_t len = 0; |
while (true) { |
if (len >= max_len) |
break; |
c1 = str_decode(s1, &off1, STR_NO_LIMIT); |
c2 = str_decode(s2, &off2, STR_NO_LIMIT); |
if (c1 < c2) |
return -1; |
if (c1 > c2) |
return 1; |
if (c1 == 0 || c2 == 0) |
break; |
++len; |
} |
return 0; |
return (a[c] - b[c]); |
} |
/** Copy string. |
* |
* Copy source string @a src to destination buffer @a dest. |
* No more than @a size bytes are written. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
*/ |
void str_cpy(char *dest, size_t size, const char *src) |
int strncmp(const char *a, const char *b, size_t n) |
{ |
wchar_t ch; |
size_t src_off; |
size_t dest_off; |
size_t c = 0; |
/* There must be space for a null terminator in the buffer. */ |
assert(size > 0); |
while (c < n && a[c] && b[c] && (!(a[c] - b[c]))) |
c++; |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
dest[dest_off] = '\0'; |
} |
/** Copy size-limited substring. |
* |
* Copy prefix of string @a src of max. size @a size to destination buffer |
* @a dest. No more than @a size bytes are written. The output string will |
* always be well-formed, i.e. null-terminated and containing only complete |
* characters. |
* |
* No more than @a n bytes are read from the input string, so it does not |
* have to be null-terminated. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer (must be > 0). |
* @param src Source string. |
* @param n Maximum number of bytes to read from @a src. |
*/ |
void str_ncpy(char *dest, size_t size, const char *src, size_t n) |
{ |
wchar_t ch; |
size_t src_off; |
size_t dest_off; |
/* There must be space for a null terminator in the buffer. */ |
assert(size > 0); |
return ( c < n ? a[c] - b[c] : 0); |
src_off = 0; |
dest_off = 0; |
while ((ch = str_decode(src, &src_off, n)) != 0) { |
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK) |
break; |
} |
dest[dest_off] = '\0'; |
} |
/** Append one string to another. |
* |
* Append source string @a src to string in destination buffer @a dest. |
* Size of the destination buffer is @a dest. If the size of the output buffer |
* is at least one byte, the output string will always be well-formed, i.e. |
* null-terminated and containing only complete characters. |
* |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* @param src Source string. |
*/ |
void str_append(char *dest, size_t size, const char *src) |
int stricmp(const char *a, const char *b) |
{ |
size_t dstr_size; |
dstr_size = str_size(dest); |
str_cpy(dest + dstr_size, size - dstr_size, src); |
} |
/** Copy NULL-terminated wide string to string |
* |
* Copy source wide string @a src to destination buffer @a dst. |
* No more than @a size bytes are written. NULL-terminator is always |
* written after the last succesfully copied character (i.e. if the |
* destination buffer is has at least 1 byte, it will be always |
* NULL-terminated). |
* |
* @param src Source wide string. |
* @param dst Destination buffer. |
* @param count Size of the destination buffer. |
* |
*/ |
void wstr_nstr(char *dst, const wchar_t *src, size_t size) |
{ |
/* No space for the NULL-terminator in the buffer */ |
if (size == 0) |
return; |
int c = 0; |
wchar_t ch; |
count_t src_idx = 0; |
size_t dst_off = 0; |
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
c++; |
while ((ch = src[src_idx++]) != 0) { |
if (chr_encode(ch, dst, &dst_off, size) != EOK) |
break; |
} |
if (dst_off >= size) |
dst[size - 1] = 0; |
else |
dst[dst_off] = 0; |
return (tolower(a[c]) - tolower(b[c])); |
} |
/** Find first occurence of character in string. |
/** Return pointer to the first occurence of character c in string. |
* |
* @param str String to search. |
* @param ch Character to look for. |
* |
* @return Pointer to character in @a str or NULL if not found. |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
const char *str_chr(const char *str, wchar_t ch) |
char *strchr(const char *str, int c) |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
return (str + last); |
last = off; |
while (*str != '\0') { |
if (*str == (char) c) |
return (char *) str; |
str++; |
} |
return NULL; |
} |
/** Find last occurence of character in string. |
/** Return pointer to the last occurence of character c in string. |
* |
* @param str String to search. |
* @param ch Character to look for. |
* |
* @return Pointer to character in @a str or NULL if not found. |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
*/ |
const char *str_rchr(const char *str, wchar_t ch) |
char *strrchr(const char *str, int c) |
{ |
wchar_t acc; |
size_t off = 0; |
size_t last = 0; |
char *res = NULL; |
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) { |
if (acc == ch) |
res = (str + last); |
last = off; |
char *retval = NULL; |
while (*str != '\0') { |
if (*str == (char) c) |
retval = (char *) str; |
str++; |
} |
return res; |
} |
/** Insert a wide character into a wide string. |
* |
* Insert a wide character into a wide string at position |
* @a pos. The characters after the position are shifted. |
* |
* @param str String to insert to. |
* @param ch Character to insert to. |
* @param pos Character index where to insert. |
@ @param max_pos Characters in the buffer. |
* |
* @return True if the insertion was sucessful, false if the position |
* is out of bounds. |
* |
*/ |
bool wstr_linsert(wchar_t *str, wchar_t ch, count_t pos, count_t max_pos) |
{ |
count_t len = wstr_length(str); |
if ((pos > len) || (pos + 1 > max_pos)) |
return false; |
count_t i; |
for (i = len; i + 1 > pos; i--) |
str[i + 1] = str[i]; |
str[pos] = ch; |
return true; |
return (char *) retval; |
} |
/** Remove a wide character from a wide string. |
* |
* Remove a wide character from a wide string at position |
* @a pos. The characters after the position are shifted. |
* |
* @param str String to remove from. |
* @param pos Character index to remove. |
* |
* @return True if the removal was sucessful, false if the position |
* is out of bounds. |
* |
*/ |
bool wstr_remove(wchar_t *str, count_t pos) |
{ |
count_t len = wstr_length(str); |
if (pos >= len) |
return false; |
count_t i; |
for (i = pos + 1; i <= len; i++) |
str[i - 1] = str[i]; |
return true; |
} |
int stricmp(const char *a, const char *b) |
{ |
int c = 0; |
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
c++; |
return (tolower(a[c]) - tolower(b[c])); |
} |
/** Convert string to a number. |
* Core of strtol and strtoul functions. |
* |
842,47 → 358,91 |
return (sgn ? -number : number); |
} |
char *str_dup(const char *src) |
char *strcpy(char *dest, const char *src) |
{ |
size_t size = str_size(src); |
void *dest = malloc(size + 1); |
char *orig = dest; |
while ((*(dest++) = *(src++))) |
; |
return orig; |
} |
if (dest == NULL) |
return (char *) NULL; |
char *strncpy(char *dest, const char *src, size_t n) |
{ |
char *orig = dest; |
while ((*(dest++) = *(src++)) && --n) |
; |
return orig; |
} |
return (char *) memcpy(dest, src, size + 1); |
char *strcat(char *dest, const char *src) |
{ |
char *orig = dest; |
while (*dest++) |
; |
--dest; |
while ((*dest++ = *src++)) |
; |
return orig; |
} |
char *strtok(char *s, const char *delim) |
char * strdup(const char *s1) |
{ |
static char *next; |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
return strtok_r(s, delim, &next); |
if (ret == NULL) |
return (char *) NULL; |
return (char *) memcpy(ret, s1, len); |
} |
char *strtok_r(char *s, const char *delim, char **next) |
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */ |
char * strtok_r(char *s, const char *delim, char **last) |
{ |
char *start, *end; |
char *spanp, *tok; |
int c, sc; |
if (s == NULL) |
s = *next; |
if (s == NULL && (s = *last) == NULL) |
return (NULL); |
/* Skip over leading delimiters. */ |
while (*s && (str_chr(delim, *s) != NULL)) ++s; |
start = s; |
cont: |
c = *s++; |
for (spanp = (char *)delim; (sc = *spanp++) != 0;) { |
if (c == sc) |
goto cont; |
} |
/* Skip over token characters. */ |
while (*s && (str_chr(delim, *s) == NULL)) ++s; |
end = s; |
*next = (*s ? s + 1 : s); |
if (c == 0) { /* no non-delimiter characters */ |
*last = NULL; |
return (NULL); |
} |
if (start == end) { |
return NULL; /* No more tokens. */ |
tok = s - 1; |
for (;;) { |
c = *s++; |
spanp = (char *)delim; |
do { |
if ((sc = *spanp++) == c) { |
if (c == 0) |
s = NULL; |
else |
s[-1] = '\0'; |
*last = s; |
return (tok); |
} |
} while (sc != 0); |
} |
} |
/* Overwrite delimiter with NULL terminator. */ |
*end = '\0'; |
return start; |
/* Ported from FBSD strtok.c 8.1 (Berkeley) 6/4/93 */ |
char * strtok(char *s, const char *delim) |
{ |
static char *last; |
return (strtok_r(s, delim, &last)); |
} |
/** @} |
/branches/tracing/uspace/lib/libc/generic/getopt.c |
---|
241,7 → 241,7 |
} |
} |
if ((optchar = (int)*place++) == (int)':' || |
(oli = str_chr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { |
(oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) { |
/* option letter unknown or ':' */ |
if (!*place) |
++optind; |
377,20 → 377,20 |
nonopt_start = nonopt_end = -1; |
return -1; |
} |
if ((has_equal = str_chr(current_argv, '=')) != NULL) { |
if ((has_equal = strchr(current_argv, '=')) != NULL) { |
/* argument found (--option=arg) */ |
current_argv_len = has_equal - current_argv; |
has_equal++; |
} else |
current_argv_len = str_size(current_argv); |
current_argv_len = strlen(current_argv); |
for (i = 0; long_options[i].name; i++) { |
/* find matching long option */ |
if (str_lcmp(current_argv, long_options[i].name, |
str_nlength(current_argv, current_argv_len))) |
if (strncmp(current_argv, long_options[i].name, |
current_argv_len)) |
continue; |
if (str_size(long_options[i].name) == |
if (strlen(long_options[i].name) == |
(unsigned)current_argv_len) { |
/* exact match */ |
match = i; |
/branches/tracing/uspace/lib/libc/generic/libc.c |
---|
48,14 → 48,11 |
#include <ipc/ipc.h> |
#include <async.h> |
#include <as.h> |
#include <console.h> |
#include <loader/pcb.h> |
extern char _heap; |
extern int main(int argc, char *argv[]); |
int _errno; |
void _exit(int status) |
{ |
thread_exit(status); |
72,6 → 69,8 |
f = fibril_setup(); |
__tcb_set(f->tcb); |
open_console(); |
/* Save the PCB pointer */ |
__pcb = (pcb_t *)pcb_ptr; |
84,7 → 83,6 |
} |
main(argc, argv); |
console_flush(); |
} |
void __exit(void) |
/branches/tracing/uspace/lib/libc/generic/io/fprintf.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/io/stdio.c |
---|
File deleted |
/branches/tracing/uspace/lib/libc/generic/io/vsnprintf.c |
---|
36,145 → 36,87 |
#include <stdio.h> |
#include <string.h> |
#include <io/printf_core.h> |
#include <errno.h> |
typedef struct { |
size_t size; /* Total size of the buffer (in bytes) */ |
size_t len; /* Number of already used bytes */ |
char *dst; /* Destination */ |
} vsnprintf_data_t; |
struct vsnprintf_data { |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
}; |
/** Write string to given buffer. |
* Write at most data->size characters including trailing zero. According to C99 |
* has snprintf to return number of characters that would have been written if |
* enough space had been available. Hence the return value is not number of |
* really printed characters but size of input string. Number of really used |
* characters is stored in data->len. |
* |
* Write at most data->size plain characters including trailing zero. |
* According to C99, snprintf() has to return number of characters that |
* would have been written if enough space had been available. Hence |
* the return value is not the number of actually printed characters |
* but size of the input string. |
* |
* @param str Source string to print. |
* @param size Number of plain characters in str. |
* @param data Structure describing destination string, counter |
* of used space and total string size. |
* |
* @return Number of characters to print (not characters actually |
* printed). |
* |
* @param str Source string to print. |
* @param count Size of the source string. |
* @param data Structure with destination string, counter of used space |
* and total string size. |
* @return Number of characters to print (not characters really |
* printed!) |
*/ |
static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data) |
static int |
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
{ |
size_t left = data->size - data->len; |
size_t i; |
i = data->size - data->len; |
if (i == 0) { |
return count; |
} |
if (left == 0) |
return ((int) size); |
if (left == 1) { |
/* We have only one free byte left in buffer |
* -> store trailing zero |
if (i == 1) { |
/* |
* We have only one free byte left in buffer => write there |
* trailing zero. |
*/ |
data->dst[data->size - 1] = 0; |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return ((int) size); |
return count; |
} |
if (left <= size) { |
/* We do not have enough space for the whole string |
* with the trailing zero => print only a part |
* of string |
if (i <= count) { |
/* |
* We have not enought space for whole string with the trailing |
* zero => print only a part of string. |
*/ |
index_t index = 0; |
while (index < size) { |
wchar_t uc = str_decode(str, &index, size); |
if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK) |
break; |
} |
/* Put trailing zero at end, but not count it |
* into data->len so it could be rewritten next time |
*/ |
data->dst[data->len] = 0; |
return ((int) size); |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
} |
/* Buffer is big enought to print the whole string */ |
memcpy((void *)(data->dst + data->len), (void *) str, size); |
data->len += size; |
/* Put trailing zero at end, but not count it |
* into data->len so it could be rewritten next time |
/* Buffer is big enought to print whole string */ |
memcpy((void *)(data->string + data->len), (void *)str, count); |
data->len += count; |
/* |
* Put trailing zero at end, but not count it into data->len so it could |
* be rewritten next time. |
*/ |
data->dst[data->len] = 0; |
return ((int) size); |
data->string[data->len] = 0; |
return count; |
} |
/** Write wide string to given buffer. |
* |
* Write at most data->size plain characters including trailing zero. |
* According to C99, snprintf() has to return number of characters that |
* would have been written if enough space had been available. Hence |
* the return value is not the number of actually printed characters |
* but size of the input string. |
* |
* @param str Source wide string to print. |
* @param size Number of bytes in str. |
* @param data Structure describing destination string, counter |
* of used space and total string size. |
* |
* @return Number of wide characters to print (not characters actually |
* printed). |
* |
/** Print formatted to the given buffer with limited size. |
* @param str Buffer. |
* @param size Bffer size. |
* @param fmt Format string. |
* \see For more details about format string see printf_core. |
*/ |
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data) |
{ |
index_t index = 0; |
while (index < (size / sizeof(wchar_t))) { |
size_t left = data->size - data->len; |
if (left == 0) |
return ((int) size); |
if (left == 1) { |
/* We have only one free byte left in buffer |
* -> store trailing zero |
*/ |
data->dst[data->size - 1] = 0; |
data->len = data->size; |
return ((int) size); |
} |
if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK) |
break; |
index++; |
} |
/* Put trailing zero at end, but not count it |
* into data->len so it could be rewritten next time |
*/ |
data->dst[data->len] = 0; |
return ((int) size); |
} |
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) |
{ |
vsnprintf_data_t data = { |
size, |
0, |
str |
}; |
printf_spec_t ps = { |
(int(*) (const char *, size_t, void *)) vsnprintf_str_write, |
(int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write, |
struct vsnprintf_data data = {size, 0, str}; |
struct printf_spec ps = { |
(int(*)(void *, size_t, void *)) vsnprintf_write, |
&data |
}; |
/* Print 0 at end of string - fix the case that nothing will be printed */ |
/* |
* Print 0 at end of string - fix the case that nothing will be printed. |
*/ |
if (size > 0) |
str[0] = 0; |
/branches/tracing/uspace/lib/libc/generic/io/printf_core.c |
---|
1,7 → 1,6 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
28,12 → 27,12 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup libc |
* @{ |
*/ |
/** |
* @file |
* @brief Printing functions. |
* @brief Printing functions. |
*/ |
#include <unistd.h> |
42,30 → 41,20 |
#include <ctype.h> |
#include <string.h> |
/** show prefixes 0x or 0 */ |
#define __PRINTF_FLAG_PREFIX 0x00000001 |
/** signed / unsigned number */ |
#define __PRINTF_FLAG_SIGNED 0x00000002 |
/** print leading zeroes */ |
#define __PRINTF_FLAG_ZEROPADDED 0x00000004 |
/** align to left */ |
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010 |
/** always show + sign */ |
#define __PRINTF_FLAG_SHOWPLUS 0x00000020 |
/** print space instead of plus */ |
#define __PRINTF_FLAG_SPACESIGN 0x00000040 |
/** show big characters */ |
#define __PRINTF_FLAG_BIGCHARS 0x00000080 |
/** number has - sign */ |
#define __PRINTF_FLAG_NEGATIVE 0x00000100 |
#define __PRINTF_FLAG_PREFIX 0x00000001 /**< show prefixes 0x or 0*/ |
#define __PRINTF_FLAG_SIGNED 0x00000002 /**< signed / unsigned number */ |
#define __PRINTF_FLAG_ZEROPADDED 0x00000004 /**< print leading zeroes */ |
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010 /**< align to left */ |
#define __PRINTF_FLAG_SHOWPLUS 0x00000020 /**< always show + sign */ |
#define __PRINTF_FLAG_SPACESIGN 0x00000040 /**< print space instead of plus */ |
#define __PRINTF_FLAG_BIGCHARS 0x00000080 /**< show big characters */ |
#define __PRINTF_FLAG_NEGATIVE 0x00000100 /**< number has - sign */ |
/** |
* Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0 |
* to terminate string... (last one is only for better testing end of buffer by |
* zero-filling subroutine) |
*/ |
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5) |
#define PRINT_NUMBER_BUFFER_SIZE (64+5) /**< Buffer big enought for 64 bit number |
* printed in base 2, sign, prefix and |
* 0 to terminate string.. (last one is only for better testing |
* end of buffer by zero-filling subroutine) |
*/ |
/** Enumeration of possible arguments types. |
*/ |
typedef enum { |
74,299 → 63,171 |
PrintfQualifierInt, |
PrintfQualifierLong, |
PrintfQualifierLongLong, |
PrintfQualifierSizeT, |
PrintfQualifierPointer |
} qualifier_t; |
static char nullstr[] = "(NULL)"; |
static char digits_small[] = "0123456789abcdef"; |
static char digits_big[] = "0123456789ABCDEF"; |
static char invalch = U_SPECIAL; |
static char digits_small[] = "0123456789abcdef"; /**< Small hexadecimal characters */ |
static char digits_big[] = "0123456789ABCDEF"; /**< Big hexadecimal characters */ |
/** Print one or more characters without adding newline. |
* |
* @param buf Buffer holding characters with size of |
* at least size bytes. NULL is not allowed! |
* @param size Size of the buffer in bytes. |
* @param ps Output method and its data. |
* |
* @return Number of characters printed. |
* |
/** Print count chars from buffer without adding newline |
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed! |
* @param count |
* @param ps output method and its data |
* @return number of printed characters |
*/ |
static int printf_putnchars(const char *buf, size_t size, |
printf_spec_t *ps) |
static int printf_putnchars(const char * buf, size_t count, |
struct printf_spec *ps) |
{ |
return ps->str_write((void *) buf, size, ps->data); |
return ps->write((void *)buf, count, ps->data); |
} |
/** Print one or more wide characters without adding newline. |
* |
* @param buf Buffer holding wide characters with size of |
* at least size bytes. NULL is not allowed! |
* @param size Size of the buffer in bytes. |
* @param ps Output method and its data. |
* |
* @return Number of wide characters printed. |
* |
/** Print string without added newline |
* @param str string to print |
* @param ps write function specification and support data |
* @return number of printed characters |
*/ |
static int printf_wputnchars(const wchar_t *buf, size_t size, |
printf_spec_t *ps) |
static int printf_putstr(const char * str, struct printf_spec *ps) |
{ |
return ps->wstr_write((void *) buf, size, ps->data); |
} |
size_t count; |
if (str == NULL) |
return printf_putnchars("(NULL)", 6, ps); |
/** Print string without adding a newline. |
* |
* @param str String to print. |
* @param ps Write function specification and support data. |
* |
* @return Number of characters printed. |
* |
*/ |
static int printf_putstr(const char *str, printf_spec_t *ps) |
{ |
if (str == NULL) |
return printf_putnchars(nullstr, str_size(nullstr), ps); |
return ps->str_write((void *) str, str_size(str), ps->data); |
count = strlen(str); |
return ps->write((void *) str, count, ps->data); |
} |
/** Print one ASCII character. |
* |
* @param c ASCII character to be printed. |
* @param ps Output method. |
* |
* @return Number of characters printed. |
* |
/** Print one character to output |
* @param c one character |
* @param ps output method |
* @return number of printed characters |
*/ |
static int printf_putchar(const char ch, printf_spec_t *ps) |
static int printf_putchar(int c, struct printf_spec *ps) |
{ |
if (!ascii_check(ch)) |
return ps->str_write((void *) &invalch, 1, ps->data); |
unsigned char ch = c; |
return ps->str_write(&ch, 1, ps->data); |
return ps->write((void *) &ch, 1, ps->data); |
} |
/** Print one wide character. |
* |
* @param c Wide character to be printed. |
* @param ps Output method. |
* |
* @return Number of characters printed. |
* |
/** Print one formatted character |
* @param c character to print |
* @param width |
* @param flags |
* @return number of printed characters |
*/ |
static int printf_putwchar(const wchar_t ch, printf_spec_t *ps) |
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps) |
{ |
if (!chr_check(ch)) |
return ps->str_write((void *) &invalch, 1, ps->data); |
int counter = 0; |
return ps->wstr_write(&ch, sizeof(wchar_t), ps->data); |
} |
/** Print one formatted ASCII character. |
* |
* @param ch Character to print. |
* @param width Width modifier. |
* @param flags Flags that change the way the character is printed. |
* |
* @return Number of characters printed, negative value on failure. |
* |
*/ |
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps) |
{ |
count_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
/* |
* One space is consumed by the character itself, hence the |
* predecrement. |
*/ |
while (--width > 0) { |
/* |
* One space is consumed by the character itself, hence |
* the predecrement. |
*/ |
if (printf_putchar(' ', ps) > 0) |
counter++; |
if (printf_putchar(' ', ps) > 0) |
++counter; |
} |
} |
if (printf_putchar(ch, ps) > 0) |
if (printf_putchar(c, ps) > 0) |
counter++; |
/* |
* One space is consumed by the character itself, hence the |
* predecrement. |
*/ |
while (--width > 0) { |
/* |
* One space is consumed by the character itself, hence |
* the predecrement. |
*/ |
if (printf_putchar(' ', ps) > 0) |
counter++; |
++counter; |
} |
return (int) (counter + 1); |
return ++counter; |
} |
/** Print one formatted wide character. |
* |
* @param ch Character to print. |
* @param width Width modifier. |
* @param flags Flags that change the way the character is printed. |
* |
* @return Number of characters printed, negative value on failure. |
* |
/** Print one string |
* @param s string |
* @param width |
* @param precision |
* @param flags |
* @return number of printed characters |
*/ |
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps) |
static int print_string(char *s, int width, int precision, uint64_t flags, |
struct printf_spec *ps) |
{ |
count_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (--width > 0) { |
/* |
* One space is consumed by the character itself, hence |
* the predecrement. |
*/ |
if (printf_putchar(' ', ps) > 0) |
counter++; |
} |
int counter = 0; |
size_t size; |
int retval; |
if (s == NULL) { |
return printf_putstr("(NULL)", ps); |
} |
if (printf_putwchar(ch, ps) > 0) |
counter++; |
while (--width > 0) { |
/* |
* One space is consumed by the character itself, hence |
* the predecrement. |
*/ |
if (printf_putchar(' ', ps) > 0) |
counter++; |
} |
return (int) (counter + 1); |
} |
size = strlen(s); |
/** Print string. |
* |
* @param str String to be printed. |
* @param width Width modifier. |
* @param precision Precision modifier. |
* @param flags Flags that modify the way the string is printed. |
* |
* @return Number of characters printed, negative value on failure. |
*/ |
static int print_str(char *str, int width, unsigned int precision, |
uint32_t flags, printf_spec_t *ps) |
{ |
if (str == NULL) |
return printf_putstr(nullstr, ps); |
/* print leading spaces */ |
/* Print leading spaces. */ |
count_t strw = str_length(str); |
if (precision == 0) |
precision = strw; |
if (precision == 0) |
precision = size; |
/* Left padding */ |
count_t counter = 0; |
width -= precision; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
} |
} |
/* Part of @a str fitting into the alloted space. */ |
int retval; |
size_t size = str_lsize(str, precision); |
if ((retval = printf_putnchars(str, size, ps)) < 0) |
if ((retval = printf_putnchars(s, size < precision ? size : precision, |
ps)) < 0) { |
return -counter; |
} |
counter += retval; |
counter += retval; |
/* Right padding */ |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
if (printf_putchar(' ', ps) == 1) |
++counter; |
} |
return ((int) counter); |
return counter; |
} |
/** Print wide string. |
* |
* @param str Wide string to be printed. |
* @param width Width modifier. |
* @param precision Precision modifier. |
* @param flags Flags that modify the way the string is printed. |
* |
* @return Number of wide characters printed, negative value on failure. |
*/ |
static int print_wstr(wchar_t *str, int width, unsigned int precision, |
uint32_t flags, printf_spec_t *ps) |
{ |
if (str == NULL) |
return printf_putstr(nullstr, ps); |
if (*str == U_BOM) |
str++; |
/* Print leading spaces. */ |
size_t strw = wstr_length(str); |
if (precision == 0) |
precision = strw; |
/* Left padding */ |
count_t counter = 0; |
width -= precision; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
} |
} |
/* Part of @a wstr fitting into the alloted space. */ |
int retval; |
size_t size = wstr_lsize(str, precision); |
if ((retval = printf_wputnchars(str, size, ps)) < 0) |
return -counter; |
counter += retval; |
/* Right padding */ |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
} |
return ((int) counter); |
} |
/** Print a number in a given base. |
/** Print number in given base |
* |
* Print significant digits of a number in given base. |
* Print significant digits of a number in given |
* base. |
* |
* @param num Number to print. |
* @param width Width modifier. |
* @param precision Precision modifier. |
* @param base Base to print the number in (must be between 2 and 16). |
* @param flags Flags that modify the way the number is printed. |
* @param num Number to print. |
* @param width |
* @param precision |
* @param base Base to print the number in (should |
* be in range 2 .. 16). |
* @param flags output modifiers |
* @return number of printed characters |
* |
* @return Number of characters printed. |
* |
*/ |
static int print_number(uint64_t num, int width, int precision, int base, |
uint32_t flags, printf_spec_t *ps) |
uint64_t flags, struct printf_spec *ps) |
{ |
char *digits; |
if (flags & __PRINTF_FLAG_BIGCHARS) |
digits = digits_big; |
else |
digits = digits_small; |
char *digits = digits_small; |
char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for |
* base == 2, prefix and sign */ |
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1]; |
int size = 0; /* size of number with all prefixes and signs */ |
int number_size; /* size of plain number */ |
char sgn; |
int retval; |
int counter = 0; |
char data[PRINT_NUMBER_BUFFER_SIZE]; |
char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1]; |
if (flags & __PRINTF_FLAG_BIGCHARS) |
digits = digits_big; |
/* Size of number with all prefixes and signs */ |
int size = 0; |
/* Put zero at end of string */ |
*ptr-- = 0; |
*ptr-- = 0; /* Put zero at end of string */ |
if (num == 0) { |
*ptr-- = '0'; |
size++; |
377,17 → 238,15 |
} while (num /= base); |
} |
/* Size of plain number */ |
int number_size = size; |
number_size = size; |
/* |
* Collect the sum of all prefixes/signs/etc. to calculate padding and |
* leading zeroes. |
* Collect sum of all prefixes/signs/... to calculate padding and |
* leading zeroes |
*/ |
if (flags & __PRINTF_FLAG_PREFIX) { |
switch(base) { |
case 2: |
/* Binary formating is not standard, but usefull */ |
case 2: /* Binary formating is not standard, but usefull */ |
size += 2; |
break; |
case 8: |
398,8 → 257,8 |
break; |
} |
} |
char sgn = 0; |
sgn = 0; |
if (flags & __PRINTF_FLAG_SIGNED) { |
if (flags & __PRINTF_FLAG_NEGATIVE) { |
sgn = '-'; |
412,46 → 271,47 |
size++; |
} |
} |
if (flags & __PRINTF_FLAG_LEFTALIGNED) |
if (flags & __PRINTF_FLAG_LEFTALIGNED) { |
flags &= ~__PRINTF_FLAG_ZEROPADDED; |
} |
/* |
* If the number is left-aligned or precision is specified then |
* padding with zeros is ignored. |
* If number is leftaligned or precision is specified then zeropadding |
* is ignored. |
*/ |
if (flags & __PRINTF_FLAG_ZEROPADDED) { |
if ((precision == 0) && (width > size)) |
if ((precision == 0) && (width > size)) { |
precision = width - size + number_size; |
} |
} |
/* Print leading spaces */ |
if (number_size > precision) { |
/* Print the whole number, not only a part */ |
/* print leading spaces */ |
/* We must print whole number not only a part. */ |
if (number_size > precision) |
precision = number_size; |
} |
width -= precision + size - number_size; |
count_t counter = 0; |
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) { |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
} |
} |
/* Print sign */ |
/* print sign */ |
if (sgn) { |
if (printf_putchar(sgn, ps) == 1) |
counter++; |
} |
/* Print prefix */ |
/* print prefix */ |
if (flags & __PRINTF_FLAG_PREFIX) { |
switch(base) { |
case 2: |
/* Binary formating is not standard, but usefull */ |
case 2: /* Binary formating is not standard, but usefull */ |
if (printf_putchar('0', ps) == 1) |
counter++; |
if (flags & __PRINTF_FLAG_BIGCHARS) { |
479,154 → 339,152 |
break; |
} |
} |
/* Print leading zeroes */ |
/* print leading zeroes */ |
precision -= number_size; |
while (precision-- > 0) { |
while (precision-- > 0) { |
if (printf_putchar('0', ps) == 1) |
counter++; |
} |
/* Print the number itself */ |
int retval; |
if ((retval = printf_putstr(++ptr, ps)) > 0) |
/* print number itself */ |
if ((retval = printf_putstr(++ptr, ps)) > 0) { |
counter += retval; |
} |
/* Print tailing spaces */ |
/* print ending spaces */ |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
while (width-- > 0) { |
if (printf_putchar(' ', ps) == 1) |
counter++; |
} |
return ((int) counter); |
return counter; |
} |
/** Print formatted string. |
* |
* Print string formatted according to the fmt parameter and variadic arguments. |
* Each formatting directive must have the following form: |
* |
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION |
* |
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION |
* |
* FLAGS:@n |
* - "#" Force to print prefix. For \%o conversion, the prefix is 0, for |
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the |
* prefix is 0b. |
* - "#" Force to print prefix. |
* For conversion \%o the prefix is 0, for %x and \%X prefixes are 0x and |
* 0X and for conversion \%b the prefix is 0b. |
* |
* - "-" Align to left. |
* - "-" Align to left. |
* |
* - "+" Print positive sign just as negative. |
* - "+" Print positive sign just as negative. |
* |
* - " " If the printed number is positive and "+" flag is not set, |
* print space in place of sign. |
* - " " If the printed number is positive and "+" flag is not set, |
* print space in place of sign. |
* |
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between |
* sign and the rest of the number. This flag is ignored if "-" |
* flag is specified. |
* |
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between |
* sign and the rest of the number. This flag is ignored if "-" |
* flag is specified. |
* |
* WIDTH:@n |
* - Specify the minimal width of a printed argument. If it is bigger, |
* width is ignored. If width is specified with a "*" character instead of |
* number, width is taken from parameter list. And integer parameter is |
* expected before parameter for processed conversion specification. If |
* this value is negative its absolute value is taken and the "-" flag is |
* set. |
* - Specify minimal width of printed argument. If it is bigger, width is |
* ignored. If width is specified with a "*" character instead of number, |
* width is taken from parameter list. And integer parameter is expected |
* before parameter for processed conversion specification. If this value |
* is negative its absolute value is taken and the "-" flag is set. |
* |
* PRECISION:@n |
* - Value precision. For numbers it specifies minimum valid numbers. |
* Smaller numbers are printed with leading zeroes. Bigger numbers are not |
* affected. Strings with more than precision characters are cut off. Just |
* as with width, an "*" can be used used instead of a number. An integer |
* value is then expected in parameters. When both width and precision are |
* specified using "*", the first parameter is used for width and the |
* second one for precision. |
* |
* - Value precision. For numbers it specifies minimum valid numbers. |
* Smaller numbers are printed with leading zeroes. Bigger numbers are |
* not affected. Strings with more than precision characters are cut off. |
* Just as with width, an "*" can be used used instead of a number. An |
* integer value is then expected in parameters. When both width and |
* precision are specified using "*", the first parameter is used for |
* width and the second one for precision. |
* |
* TYPE:@n |
* - "hh" Signed or unsigned char.@n |
* - "h" Signed or unsigned short.@n |
* - "" Signed or unsigned int (default value).@n |
* - "l" Signed or unsigned long int.@n |
* If conversion is "c", the character is wchar_t (wide character).@n |
* If conversion is "s", the string is wchar_t * (wide string).@n |
* - "ll" Signed or unsigned long long int.@n |
* |
* - "hh" Signed or unsigned char.@n |
* - "h" Signed or usigned short.@n |
* - "" Signed or usigned int (default value).@n |
* - "l" Signed or usigned long int.@n |
* - "ll" Signed or usigned long long int.@n |
* - "z" Type size_t.@n |
* |
* |
* CONVERSION:@n |
* - % Print percentile character itself. |
* - % Print percentile character itself. |
* |
* - c Print single character. The character is expected to be plain |
* ASCII (e.g. only values 0 .. 127 are valid).@n |
* If type is "l", then the character is expected to be wide character |
* (e.g. values 0 .. 0x10ffff are valid). |
* - c Print single character. |
* |
* - s Print zero terminated string. If a NULL value is passed as |
* value, "(NULL)" is printed instead.@n |
* If type is "l", then the string is expected to be wide string. |
* - s Print zero terminated string. If a NULL value is passed as |
* value, "(NULL)" is printed instead. |
* |
* - P, p Print value of a pointer. Void * value is expected and it is |
* printed in hexadecimal notation with prefix (as with '\%#X' or |
* '\%#x' for 32bit or '\%#X' or '\%#x' for 64bit long pointers). |
* |
* - P, p Print value of a pointer. Void * value is expected and it is |
* printed in hexadecimal notation with prefix (as with \%#X / \%#x |
* for 32-bit or \%#X / \%#x for 64-bit long pointers). |
* - b Print value as unsigned binary number. Prefix is not printed by |
* default. (Nonstandard extension.) |
* |
* - o Print value as unsigned octal number. Prefix is not printed by |
* default. |
* |
* - b Print value as unsigned binary number. Prefix is not printed by |
* default. (Nonstandard extension.) |
* - d, i Print signed decimal number. There is no difference between d |
* and i conversion. |
* |
* - o Print value as unsigned octal number. Prefix is not printed by |
* default. |
* - u Print unsigned decimal number. |
* |
* - d, i Print signed decimal number. There is no difference between d |
* and i conversion. |
* |
* - u Print unsigned decimal number. |
* |
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is |
* not printed by default. |
* |
* All other characters from fmt except the formatting directives are printed |
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is |
* not printed by default. |
* |
* All other characters from fmt except the formatting directives are printed in |
* verbatim. |
* |
* @param fmt Format NULL-terminated string. |
* |
* @return Number of characters printed, negative value on failure. |
* |
* @param fmt Formatting NULL terminated string. |
* @return Number of printed characters or negative value on failure. |
*/ |
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap) |
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap) |
{ |
size_t i; /* Index of the currently processed character from fmt */ |
size_t nxt = 0; /* Index of the next character from fmt */ |
size_t j = 0; /* Index to the first not printed nonformating character */ |
/* i is the index of the currently processed char from fmt */ |
int i = 0; |
/* j is the index to the first not printed nonformating character */ |
int j = 0; |
int end; |
int counter; /* counter of printed characters */ |
int retval; /* used to store return values from called functions */ |
char c; |
qualifier_t qualifier; /* type of argument */ |
int base; /* base in which will be a numeric parameter printed */ |
uint64_t number; /* argument value */ |
size_t size; /* byte size of integer parameter */ |
int width, precision; |
uint64_t flags; |
count_t counter = 0; /* Number of characters printed */ |
int retval; /* Return values from nested functions */ |
counter = 0; |
while (true) { |
i = nxt; |
wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (uc == 0) |
break; |
/* Control character */ |
if (uc == '%') { |
/* Print common characters if any processed */ |
while ((c = fmt[i])) { |
/* control character */ |
if (c == '%' ) { |
/* print common characters if any processed */ |
if (i > j) { |
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) { |
/* Error */ |
counter = -counter; |
goto out; |
if ((retval = printf_putnchars(&fmt[j], |
(size_t)(i - j), ps)) < 0) { /* error */ |
goto minus_out; |
} |
counter += retval; |
} |
j = i; |
/* parse modifiers */ |
flags = 0; |
end = 0; |
/* Parse modifiers */ |
uint32_t flags = 0; |
bool end = false; |
do { |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
switch (uc) { |
++i; |
switch (c = fmt[i]) { |
case '#': |
flags |= __PRINTF_FLAG_PREFIX; |
break; |
643,145 → 501,114 |
flags |= __PRINTF_FLAG_ZEROPADDED; |
break; |
default: |
end = true; |
}; |
} while (!end); |
end = 1; |
}; |
} while (end == 0); |
/* Width & '*' operator */ |
int width = 0; |
if (isdigit(uc)) { |
while (true) { |
/* width & '*' operator */ |
width = 0; |
if (isdigit(fmt[i])) { |
while (isdigit(fmt[i])) { |
width *= 10; |
width += uc - '0'; |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (uc == 0) |
break; |
if (!isdigit(uc)) |
break; |
width += fmt[i++] - '0'; |
} |
} else if (uc == '*') { |
/* Get width value from argument list */ |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
width = (int) va_arg(ap, int); |
} else if (fmt[i] == '*') { |
/* get width value from argument list*/ |
i++; |
width = (int)va_arg(ap, int); |
if (width < 0) { |
/* Negative width sets '-' flag */ |
/* negative width sets '-' flag */ |
width *= -1; |
flags |= __PRINTF_FLAG_LEFTALIGNED; |
} |
} |
/* Precision and '*' operator */ |
int precision = 0; |
if (uc == '.') { |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (isdigit(uc)) { |
while (true) { |
/* precision and '*' operator */ |
precision = 0; |
if (fmt[i] == '.') { |
++i; |
if (isdigit(fmt[i])) { |
while (isdigit(fmt[i])) { |
precision *= 10; |
precision += uc - '0'; |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (uc == 0) |
break; |
if (!isdigit(uc)) |
break; |
precision += fmt[i++] - '0'; |
} |
} else if (uc == '*') { |
/* Get precision value from the argument list */ |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
precision = (int) va_arg(ap, int); |
} else if (fmt[i] == '*') { |
/* get precision value from argument */ |
i++; |
precision = (int)va_arg(ap, int); |
if (precision < 0) { |
/* Ignore negative precision */ |
/* negative precision ignored */ |
precision = 0; |
} |
} |
} |
qualifier_t qualifier; |
switch (uc) { |
/** @todo Unimplemented qualifiers: |
* t ptrdiff_t - ISO C 99 |
switch (fmt[i++]) { |
/** @todo unimplemented qualifiers: |
* t ptrdiff_t - ISO C 99 |
*/ |
case 'h': |
/* Char or short */ |
case 'h': /* char or short */ |
qualifier = PrintfQualifierShort; |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (uc == 'h') { |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (fmt[i] == 'h') { |
i++; |
qualifier = PrintfQualifierByte; |
} |
break; |
case 'l': |
/* Long or long long */ |
case 'l': /* long or long long*/ |
qualifier = PrintfQualifierLong; |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (uc == 'l') { |
i = nxt; |
uc = str_decode(fmt, &nxt, STR_NO_LIMIT); |
if (fmt[i] == 'l') { |
i++; |
qualifier = PrintfQualifierLongLong; |
} |
break; |
case 'z': /* size_t */ |
qualifier = PrintfQualifierSizeT; |
break; |
default: |
/* Default type */ |
/* set default type */ |
qualifier = PrintfQualifierInt; |
} |
--i; |
} |
unsigned int base = 10; |
switch (uc) { |
base = 10; |
switch (c = fmt[i]) { |
/* |
* String and character conversions. |
*/ |
case 's': |
if (qualifier == PrintfQualifierLong) |
retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps); |
else |
retval = print_str(va_arg(ap, char *), width, precision, flags, ps); |
if (retval < 0) { |
counter = -counter; |
goto out; |
if ((retval = print_string(va_arg(ap, char*), |
width, precision, flags, ps)) < 0) { |
goto minus_out; |
} |
counter += retval; |
j = nxt; |
j = i + 1; |
goto next_char; |
case 'c': |
if (qualifier == PrintfQualifierLong) |
retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps); |
else |
retval = print_char(va_arg(ap, unsigned int), width, flags, ps); |
c = va_arg(ap, unsigned int); |
retval = print_char(c, width, flags, ps); |
if (retval < 0) { |
counter = -counter; |
goto out; |
}; |
goto minus_out; |
} |
counter += retval; |
j = nxt; |
j = i + 1; |
goto next_char; |
/* |
/* |
* Integer values |
*/ |
case 'P': |
/* Pointer */ |
flags |= __PRINTF_FLAG_BIGCHARS; |
case 'P': /* pointer */ |
flags |= __PRINTF_FLAG_BIGCHARS; |
case 'p': |
flags |= __PRINTF_FLAG_PREFIX; |
base = 16; |
qualifier = PrintfQualifierPointer; |
break; |
case 'b': |
break; |
case 'b': |
base = 2; |
break; |
case 'o': |
789,7 → 616,7 |
break; |
case 'd': |
case 'i': |
flags |= __PRINTF_FLAG_SIGNED; |
flags |= __PRINTF_FLAG_SIGNED; |
case 'u': |
break; |
case 'X': |
797,63 → 624,66 |
case 'x': |
base = 16; |
break; |
/* Percentile itself */ |
case '%': |
/* percentile itself */ |
case '%': |
j = i; |
goto next_char; |
/* |
* Bad formatting. |
*/ |
default: |
/* |
* Unknown format. Now, j is the index of '%' |
* so we will print whole bad format sequence. |
* Unknown format. Now, j is the index of '%', |
* so we will print the whole bad format |
* sequence. |
*/ |
goto next_char; |
goto next_char; |
} |
/* Print integers */ |
size_t size; |
uint64_t number; |
switch (qualifier) { |
case PrintfQualifierByte: |
size = sizeof(unsigned char); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierShort: |
size = sizeof(unsigned short); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierInt: |
size = sizeof(unsigned int); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierLong: |
size = sizeof(unsigned long); |
number = (uint64_t) va_arg(ap, unsigned long); |
number = (uint64_t)va_arg(ap, unsigned long); |
break; |
case PrintfQualifierLongLong: |
size = sizeof(unsigned long long); |
number = (uint64_t) va_arg(ap, unsigned long long); |
number = (uint64_t)va_arg(ap, |
unsigned long long); |
break; |
case PrintfQualifierPointer: |
size = sizeof(void *); |
number = (uint64_t) (unsigned long) va_arg(ap, void *); |
number = (uint64_t)(unsigned long)va_arg(ap, |
void *); |
break; |
default: |
/* Unknown qualifier */ |
counter = -counter; |
goto out; |
case PrintfQualifierSizeT: |
size = sizeof(size_t); |
number = (uint64_t)va_arg(ap, size_t); |
break; |
default: /* Unknown qualifier */ |
goto minus_out; |
} |
if (flags & __PRINTF_FLAG_SIGNED) { |
if (number & (0x1 << (size * 8 - 1))) { |
flags |= __PRINTF_FLAG_NEGATIVE; |
if (size == sizeof(uint64_t)) { |
number = -((int64_t) number); |
number = -((int64_t)number); |
} else { |
number = ~number; |
number &= |
863,31 → 693,31 |
} |
} |
} |
if ((retval = print_number(number, width, precision, |
base, flags, ps)) < 0) { |
counter = -counter; |
goto out; |
base, flags, ps)) < 0 ) { |
goto minus_out; |
} |
counter += retval; |
j = nxt; |
} |
j = i + 1; |
} |
next_char: |
; |
++i; |
} |
if (i > j) { |
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) { |
/* Error */ |
counter = -counter; |
goto out; |
retval = printf_putnchars(&fmt[j], (size_t)(i - j), ps); |
if (retval < 0) { /* error */ |
goto minus_out; |
} |
counter += retval; |
} |
out: |
return ((int) counter); |
return counter; |
minus_out: |
return -counter; |
} |
/** @} |
/branches/tracing/uspace/lib/libc/generic/io/stream.c |
---|
42,45 → 42,79 |
#include <ipc/ns.h> |
#include <ipc/fb.h> |
#include <ipc/services.h> |
#include <ipc/console.h> |
#include <console.h> |
#include <kbd/kbd.h> |
#include <unistd.h> |
#include <async.h> |
#include <sys/types.h> |
static int console_phone = -1; |
ssize_t write_stderr(const void *buf, size_t count) |
{ |
return count; |
} |
ssize_t read_stdin(void *buf, size_t count) |
{ |
int cons_phone = console_open(false); |
open_console(); |
if (console_phone >= 0) { |
ipcarg_t r0, r1; |
size_t i = 0; |
if (cons_phone >= 0) { |
kbd_event_t ev; |
int rc; |
size_t i = 0; |
while (i < count) { |
do { |
rc = kbd_get_event(&ev); |
if (rc < 0) return -1; |
} while (ev.c == 0 || ev.type == KE_RELEASE); |
((char *) buf)[i++] = ev.c; |
if (async_req_0_2(console_phone, CONSOLE_GETCHAR, &r0, &r1) < 0) |
return -1; |
((char *) buf)[i++] = r0; |
} |
return i; |
} else |
} else { |
return -1; |
} |
} |
/** Write a string to klog. */ |
int klog_puts(const char *str) |
ssize_t write_stdout(const void *buf, size_t count) |
{ |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) str, str_size(str)); |
open_console(); |
if (console_phone >= 0) { |
int i; |
for (i = 0; i < count; i++) |
async_msg_1(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
return count; |
} else |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); |
} |
void open_console(void) |
{ |
if (console_phone < 0) { |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0, 0); |
if (phone >= 0) |
console_phone = phone; |
} |
} |
void close_console(void) |
{ |
if (console_phone >= 0) { |
if (ipc_hangup(console_phone) == 0) { |
console_phone = -1; |
} |
} |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
} |
int get_cons_phone(void) |
{ |
open_console(); |
return console_phone; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/io/io.c |
---|
36,9 → 36,6 |
#include <unistd.h> |
#include <stdio.h> |
#include <io/io.h> |
#include <string.h> |
#include <errno.h> |
#include <console.h> |
const static char nl = '\n'; |
50,9 → 47,8 |
return putnchars("(NULL)", 6); |
for (count = 0; str[count] != 0; count++); |
if (console_write((void *) str, count) == count) { |
if (console_write(&nl, 1) == 1) |
if (write_stdout((void *) str, count) == count) { |
if (write_stdout(&nl, 1) == 1) |
return 0; |
} |
66,7 → 62,7 |
*/ |
int putnchars(const char *buf, size_t count) |
{ |
if (console_write((void *) buf, count) == count) |
if (write_stdout((void *) buf, count) == count) |
return 0; |
return EOF; |
83,7 → 79,7 |
return putnchars("(NULL)", 6); |
for (count = 0; str[count] != 0; count++); |
if (console_write((void *) str, count) == count) |
if (write_stdout((void *) str, count) == count) |
return 0; |
return EOF; |
91,16 → 87,10 |
int putchar(int c) |
{ |
char buf[STR_BOUNDS(1)]; |
size_t offs; |
offs = 0; |
if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK) |
return EOF; |
if (console_write((void *) buf, offs) == offs) |
unsigned char ch = c; |
if (write_stdout((void *) &ch, 1) == 1) |
return c; |
return EOF; |
} |
107,8 → 97,6 |
int getchar(void) |
{ |
unsigned char c; |
console_flush(); |
if (read_stdin((void *) &c, 1) == 1) |
return c; |
115,13 → 103,5 |
return EOF; |
} |
int fflush(FILE *f) |
{ |
/* Dummy implementation */ |
(void) f; |
console_flush(); |
return 0; |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/io/vprintf.c |
---|
38,45 → 38,14 |
#include <io/printf_core.h> |
#include <futex.h> |
#include <async.h> |
#include <console.h> |
static atomic_t printf_futex = FUTEX_INITIALIZER; |
static int vprintf_str_write(const char *str, size_t size, void *data) |
static int vprintf_write(const char *str, size_t count, void *unused) |
{ |
size_t offset = 0; |
size_t prev; |
count_t chars = 0; |
while (offset < size) { |
prev = offset; |
str_decode(str, &offset, size); |
console_write(str + prev, offset - prev); |
chars++; |
} |
return chars; |
return write_stdout(str, count); |
} |
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data) |
{ |
size_t offset = 0; |
size_t boff; |
count_t chars = 0; |
char buf[4]; |
while (offset < size) { |
boff = 0; |
chr_encode(str[chars], buf, &boff, 4); |
console_write(buf, boff); |
chars++; |
offset += sizeof(wchar_t); |
} |
return chars; |
} |
/** Print formatted text. |
* @param fmt format string |
* @param ap format parameters |
85,8 → 54,7 |
int vprintf(const char *fmt, va_list ap) |
{ |
struct printf_spec ps = { |
vprintf_str_write, |
vprintf_wstr_write, |
(int (*)(void *, size_t, void *)) vprintf_write, |
NULL |
}; |
/* |
/branches/tracing/uspace/lib/libc/generic/async.c |
---|
30,65 → 30,64 |
* @{ |
*/ |
/** @file |
*/ |
*/ |
/** |
* Asynchronous library |
* |
* The aim of this library is to provide a facility for writing programs which |
* utilize the asynchronous nature of HelenOS IPC, yet using a normal way of |
* programming. |
* The aim of this library is facilitating writing programs utilizing the |
* asynchronous nature of HelenOS IPC, yet using a normal way of programming. |
* |
* You should be able to write very simple multithreaded programs, the async |
* framework will automatically take care of most synchronization problems. |
* |
* Default semantics: |
* - async_send_*(): Send asynchronously. If the kernel refuses to send |
* more messages, [ try to get responses from kernel, if |
* nothing found, might try synchronous ] |
* - async_send_*(): send asynchronously. If the kernel refuses to send |
* more messages, [ try to get responses from kernel, if |
* nothing found, might try synchronous ] |
* |
* Example of use (pseudo C): |
* |
* |
* 1) Multithreaded client application |
* |
* fibril_create(fibril1, ...); |
* fibril_create(fibril2, ...); |
* ... |
* fibril_create(fibril1, ...); |
* fibril_create(fibril2, ...); |
* ... |
* |
* int fibril1(void *arg) |
* { |
* conn = ipc_connect_me_to(); |
* c1 = async_send(conn); |
* c2 = async_send(conn); |
* async_wait_for(c1); |
* async_wait_for(c2); |
* ... |
* } |
* |
* int fibril1(void *arg) |
* { |
* conn = ipc_connect_me_to(); |
* c1 = async_send(conn); |
* c2 = async_send(conn); |
* async_wait_for(c1); |
* async_wait_for(c2); |
* ... |
* } |
* |
* |
* 2) Multithreaded server application |
* main() |
* { |
* async_manager(); |
* } |
* |
* |
* main() |
* { |
* async_manager(); |
* } |
* my_client_connection(icallid, *icall) |
* { |
* if (want_refuse) { |
* ipc_answer_0(icallid, ELIMIT); |
* return; |
* } |
* ipc_answer_0(icallid, EOK); |
* |
* my_client_connection(icallid, *icall) |
* { |
* if (want_refuse) { |
* ipc_answer_0(icallid, ELIMIT); |
* return; |
* } |
* ipc_answer_0(icallid, EOK); |
* callid = async_get_call(&call); |
* handle_call(callid, call); |
* ipc_answer_2(callid, 1, 2, 3); |
* |
* callid = async_get_call(&call); |
* handle_call(callid, call); |
* ipc_answer_2(callid, 1, 2, 3); |
* callid = async_get_call(&call); |
* .... |
* } |
* |
* callid = async_get_call(&call); |
* ... |
* } |
* |
*/ |
#include <futex.h> |
105,26 → 104,24 |
#include <bool.h> |
atomic_t async_futex = FUTEX_INITIALIZER; |
static hash_table_t conn_hash_table; |
static LIST_INITIALIZE(timeout_list); |
/** Structures of this type represent a waiting fibril. */ |
typedef struct { |
/** Expiration time. */ |
struct timeval expires; |
struct timeval expires; |
/** If true, this struct is in the timeout list. */ |
bool inlist; |
int inlist; |
/** Timeout list link. */ |
link_t link; |
/** Identification of and link to the waiting fibril. */ |
fid_t fid; |
/** If true, this fibril is currently active. */ |
bool active; |
int active; |
/** If true, we have timed out. */ |
bool timedout; |
int timedout; |
} awaiter_t; |
typedef struct { |
131,11 → 128,10 |
awaiter_t wdata; |
/** If reply was received. */ |
bool done; |
int done; |
/** Pointer to where the answer data is stored. */ |
ipc_call_t *dataptr; |
ipc_call_t *dataptr; |
ipcarg_t retval; |
} amsg_t; |
151,24 → 147,24 |
typedef struct { |
awaiter_t wdata; |
/** Hash table link. */ |
link_t link; |
/** Incoming phone hash. */ |
ipcarg_t in_phone_hash; |
ipcarg_t in_phone_hash; |
/** Messages that should be delivered to this fibril. */ |
link_t msg_queue; |
link_t msg_queue; |
/** Identification of the opening call. */ |
ipc_callid_t callid; |
/** Call data of the opening call. */ |
ipc_call_t call; |
/** Identification of the closing call. */ |
ipc_callid_t close_callid; |
/** Fibril function that will be used to handle the connection. */ |
void (*cfibril)(ipc_callid_t, ipc_call_t *); |
} connection_t; |
176,6 → 172,12 |
/** Identifier of the incoming connection handled by the current fibril. */ |
__thread connection_t *FIBRIL_connection; |
/** |
* If true, it is forbidden to use async_req functions and all preemption is |
* disabled. |
*/ |
__thread int _in_interrupt_handler; |
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call); |
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call); |
183,7 → 185,6 |
* Pointer to a fibril function that will be used to handle connections. |
*/ |
static async_client_conn_t client_connection = default_client_connection; |
/** |
* Pointer to a fibril function that will be used to handle interrupt |
* notifications. |
190,39 → 191,46 |
*/ |
static async_client_conn_t interrupt_received = default_interrupt_received; |
/* |
* Getter for _in_interrupt_handler. We need to export the value of this thread |
* local variable to other modules, but the binutils 2.18 linkers die on an |
* attempt to export this symbol in the header file. For now, consider this as a |
* workaround. |
*/ |
bool in_interrupt_handler(void) |
{ |
return _in_interrupt_handler; |
} |
static hash_table_t conn_hash_table; |
static LIST_INITIALIZE(timeout_list); |
#define CONN_HASH_TABLE_CHAINS 32 |
#define CONN_HASH_TABLE_CHAINS 32 |
/** Compute hash into the connection hash table based on the source phone hash. |
* |
* @param key Pointer to source phone hash. |
* @param key Pointer to source phone hash. |
* |
* @return Index into the connection hash table. |
* |
* @return Index into the connection hash table. |
*/ |
static hash_index_t conn_hash(unsigned long *key) |
{ |
assert(key); |
return (((*key) >> 4) % CONN_HASH_TABLE_CHAINS); |
return ((*key) >> 4) % CONN_HASH_TABLE_CHAINS; |
} |
/** Compare hash table item with a key. |
* |
* @param key Array containing the source phone hash as the only item. |
* @param keys Expected 1 but ignored. |
* @param item Connection hash table item. |
* @param key Array containing the source phone hash as the only item. |
* @param keys Expected 1 but ignored. |
* @param item Connection hash table item. |
* |
* @return True on match, false otherwise. |
* |
* @return True on match, false otherwise. |
*/ |
static int conn_compare(unsigned long key[], hash_count_t keys, link_t *item) |
{ |
connection_t *hs = hash_table_get_instance(item, connection_t, link); |
return (key[0] == hs->in_phone_hash); |
connection_t *hs; |
hs = hash_table_get_instance(item, connection_t, link); |
return key[0] == hs->in_phone_hash; |
} |
/** Connection hash table removal callback function. |
230,8 → 238,7 |
* This function is called whenever a connection is removed from the connection |
* hash table. |
* |
* @param item Connection hash table item being removed. |
* |
* @param item Connection hash table item being removed. |
*/ |
static void conn_remove(link_t *item) |
{ |
248,24 → 255,23 |
/** Sort in current fibril's timeout request. |
* |
* @param wd Wait data of the current fibril. |
* |
* @param wd Wait data of the current fibril. |
*/ |
static void insert_timeout(awaiter_t *wd) |
{ |
wd->timedout = false; |
wd->inlist = true; |
link_t *tmp = timeout_list.next; |
link_t *tmp; |
awaiter_t *cur; |
wd->timedout = 0; |
wd->inlist = 1; |
tmp = timeout_list.next; |
while (tmp != &timeout_list) { |
awaiter_t *cur = list_get_instance(tmp, awaiter_t, link); |
cur = list_get_instance(tmp, awaiter_t, link); |
if (tv_gteq(&cur->expires, &wd->expires)) |
break; |
tmp = tmp->next; |
} |
list_append(&wd->link, tmp); |
} |
275,146 → 281,93 |
* its message queue. If the fibril was not active, it is activated and all |
* timeouts are unregistered. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
* @return False if the call doesn't match any connection. |
* True if the call was passed to the respective connection fibril. |
* |
* @return Zero if the call doesn't match any connection. |
* One if the call was passed to the respective connection |
* fibril. |
*/ |
static bool route_call(ipc_callid_t callid, ipc_call_t *call) |
static int route_call(ipc_callid_t callid, ipc_call_t *call) |
{ |
connection_t *conn; |
msg_t *msg; |
link_t *hlp; |
unsigned long key; |
futex_down(&async_futex); |
unsigned long key = call->in_phone_hash; |
link_t *hlp = hash_table_find(&conn_hash_table, &key); |
key = call->in_phone_hash; |
hlp = hash_table_find(&conn_hash_table, &key); |
if (!hlp) { |
futex_up(&async_futex); |
return false; |
return 0; |
} |
connection_t *conn = hash_table_get_instance(hlp, connection_t, link); |
msg_t *msg = malloc(sizeof(*msg)); |
if (!msg) { |
futex_up(&async_futex); |
return false; |
} |
conn = hash_table_get_instance(hlp, connection_t, link); |
msg = malloc(sizeof(*msg)); |
msg->callid = callid; |
msg->call = *call; |
list_append(&msg->link, &conn->msg_queue); |
if (IPC_GET_METHOD(*call) == IPC_M_PHONE_HUNGUP) |
conn->close_callid = callid; |
/* If the connection fibril is waiting for an event, activate it */ |
if (!conn->wdata.active) { |
/* If in timeout list, remove it */ |
if (conn->wdata.inlist) { |
conn->wdata.inlist = false; |
conn->wdata.inlist = 0; |
list_remove(&conn->wdata.link); |
} |
conn->wdata.active = true; |
conn->wdata.active = 1; |
fibril_add_ready(conn->wdata.fid); |
} |
futex_up(&async_futex); |
return true; |
} |
/** Notification fibril. |
* |
* When a notification arrives, a fibril with this implementing function is |
* created. It calls interrupt_received() and does the final cleanup. |
* |
* @param arg Message structure pointer. |
* |
* @return Always zero. |
* |
*/ |
static int notification_fibril(void *arg) |
{ |
msg_t *msg = (msg_t *) arg; |
interrupt_received(msg->callid, &msg->call); |
free(msg); |
return 0; |
return 1; |
} |
/** Process interrupt notification. |
* |
* A new fibril is created which would process the notification. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
* @return False if an error occured. |
* True if the call was passed to the notification fibril. |
* |
*/ |
static bool process_notification(ipc_callid_t callid, ipc_call_t *call) |
{ |
futex_down(&async_futex); |
msg_t *msg = malloc(sizeof(*msg)); |
if (!msg) { |
futex_up(&async_futex); |
return false; |
} |
msg->callid = callid; |
msg->call = *call; |
fid_t fid = fibril_create(notification_fibril, msg); |
fibril_add_ready(fid); |
futex_up(&async_futex); |
return true; |
} |
/** Return new incoming message for the current (fibril-local) connection. |
* |
* @param call Storage where the incoming call data will be stored. |
* @param usecs Timeout in microseconds. Zero denotes no timeout. |
* @param call Storage where the incoming call data will be stored. |
* @param usecs Timeout in microseconds. Zero denotes no timeout. |
* |
* @return If no timeout was specified, then a hash of the |
* incoming call is returned. If a timeout is specified, |
* then a hash of the incoming call is returned unless |
* the timeout expires prior to receiving a message. In |
* that case zero is returned. |
* |
* @return If no timeout was specified, then a hash of the |
* incoming call is returned. If a timeout is specified, |
* then a hash of the incoming call is returned unless |
* the timeout expires prior to receiving a message. In |
* that case zero is returned. |
*/ |
ipc_callid_t async_get_call_timeout(ipc_call_t *call, suseconds_t usecs) |
{ |
msg_t *msg; |
ipc_callid_t callid; |
connection_t *conn; |
assert(FIBRIL_connection); |
/* Why doing this? |
* GCC 4.1.0 coughs on FIBRIL_connection-> dereference. |
/* GCC 4.1.0 coughs on FIBRIL_connection-> dereference, |
* GCC 4.1.1 happilly puts the rdhwr instruction in delay slot. |
* I would never expect to find so many errors in |
* a compiler. |
* I would never expect to find so many errors in |
* a compiler *($&$(*&$ |
*/ |
connection_t *conn = FIBRIL_connection; |
conn = FIBRIL_connection; |
futex_down(&async_futex); |
if (usecs) { |
gettimeofday(&conn->wdata.expires, NULL); |
tv_add(&conn->wdata.expires, usecs); |
} else |
conn->wdata.inlist = false; |
} else { |
conn->wdata.inlist = 0; |
} |
/* If nothing in queue, wait until something arrives */ |
while (list_empty(&conn->msg_queue)) { |
if (usecs) |
insert_timeout(&conn->wdata); |
conn->wdata.active = false; |
conn->wdata.active = 0; |
/* |
* Note: the current fibril will be rescheduled either due to a |
* timeout or due to an arriving message destined to it. In the |
422,14 → 375,13 |
* case, route_call() will perform the wakeup. |
*/ |
fibril_switch(FIBRIL_TO_MANAGER); |
/* |
* Futex is up after getting back from async_manager. |
* Get it again. |
* Futex is up after getting back from async_manager get it |
* again. |
*/ |
futex_down(&async_futex); |
if ((usecs) && (conn->wdata.timedout) |
&& (list_empty(&conn->msg_queue))) { |
if (usecs && conn->wdata.timedout && |
list_empty(&conn->msg_queue)) { |
/* If we timed out -> exit */ |
futex_up(&async_futex); |
return 0; |
436,10 → 388,9 |
} |
} |
msg_t *msg = list_get_instance(conn->msg_queue.next, msg_t, link); |
msg = list_get_instance(conn->msg_queue.next, msg_t, link); |
list_remove(&msg->link); |
ipc_callid_t callid = msg->callid; |
callid = msg->callid; |
*call = msg->call; |
free(msg); |
451,9 → 402,8 |
* |
* This function is defined as a weak symbol - to be redefined in user code. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
*/ |
static void default_client_connection(ipc_callid_t callid, ipc_call_t *call) |
{ |
462,11 → 412,8 |
/** Default fibril function that gets called to handle interrupt notifications. |
* |
* This function is defined as a weak symbol - to be redefined in user code. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
*/ |
static void default_interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
477,17 → 424,17 |
* When a new connection arrives, a fibril with this implementing function is |
* created. It calls client_connection() and does the final cleanup. |
* |
* @param arg Connection structure pointer. |
* @param arg Connection structure pointer. |
* |
* @return Always zero. |
* |
* @return Always zero. |
*/ |
static int connection_fibril(void *arg) |
static int connection_fibril(void *arg) |
{ |
/* |
* Setup fibril-local connection pointer and call client_connection(). |
* |
*/ |
unsigned long key; |
msg_t *msg; |
int close_answered = 0; |
/* Setup fibril-local connection pointer */ |
FIBRIL_connection = (connection_t *) arg; |
FIBRIL_connection->cfibril(FIBRIL_connection->callid, |
&FIBRIL_connection->call); |
494,20 → 441,20 |
/* Remove myself from the connection hash table */ |
futex_down(&async_futex); |
unsigned long key = FIBRIL_connection->in_phone_hash; |
key = FIBRIL_connection->in_phone_hash; |
hash_table_remove(&conn_hash_table, &key, 1); |
futex_up(&async_futex); |
/* Answer all remaining messages with EHANGUP */ |
while (!list_empty(&FIBRIL_connection->msg_queue)) { |
msg_t *msg |
= list_get_instance(FIBRIL_connection->msg_queue.next, msg_t, link); |
msg = list_get_instance(FIBRIL_connection->msg_queue.next, |
msg_t, link); |
list_remove(&msg->link); |
if (msg->callid == FIBRIL_connection->close_callid) |
close_answered = 1; |
ipc_answer_0(msg->callid, EHANGUP); |
free(msg); |
} |
if (FIBRIL_connection->close_callid) |
ipc_answer_0(FIBRIL_connection->close_callid, EOK); |
516,45 → 463,43 |
/** Create a new fibril for a new connection. |
* |
* Create new fibril for connection, fill in connection structures and inserts |
* Creates new fibril for connection, fills in connection structures and inserts |
* it into the hash table, so that later we can easily do routing of messages to |
* particular fibrils. |
* |
* @param in_phone_hash Identification of the incoming connection. |
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. |
* If callid is zero, the connection was opened by |
* accepting the IPC_M_CONNECT_TO_ME call and this function |
* is called directly by the server. |
* @param call Call data of the opening call. |
* @param cfibril Fibril function that should be called upon opening the |
* connection. |
* @param in_phone_hash Identification of the incoming connection. |
* @param callid Hash of the opening IPC_M_CONNECT_ME_TO call. |
* If callid is zero, the connection was opened by |
* accepting the IPC_M_CONNECT_TO_ME call and this function |
* is called directly by the server. |
* @param call Call data of the opening call. |
* @param cfibril Fibril function that should be called upon opening the |
* connection. |
* |
* @return New fibril id or NULL on failure. |
* |
* @return New fibril id or NULL on failure. |
*/ |
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
ipc_call_t *call, void (*cfibril)(ipc_callid_t, ipc_call_t *)) |
{ |
connection_t *conn = malloc(sizeof(*conn)); |
connection_t *conn; |
unsigned long key; |
conn = malloc(sizeof(*conn)); |
if (!conn) { |
if (callid) |
ipc_answer_0(callid, ENOMEM); |
return NULL; |
} |
conn->in_phone_hash = in_phone_hash; |
list_initialize(&conn->msg_queue); |
conn->callid = callid; |
conn->close_callid = false; |
conn->close_callid = 0; |
if (call) |
conn->call = *call; |
/* We will activate the fibril ASAP */ |
conn->wdata.active = true; |
conn->wdata.active = 1; /* We will activate the fibril ASAP */ |
conn->cfibril = cfibril; |
conn->wdata.fid = fibril_create(connection_fibril, conn); |
if (!conn->wdata.fid) { |
free(conn); |
if (callid) |
561,16 → 506,14 |
ipc_answer_0(callid, ENOMEM); |
return NULL; |
} |
/* Add connection to the connection hash table */ |
ipcarg_t key = conn->in_phone_hash; |
key = conn->in_phone_hash; |
futex_down(&async_futex); |
hash_table_insert(&conn_hash_table, &key, &conn->link); |
futex_up(&async_futex); |
fibril_add_ready(conn->wdata.fid); |
return conn->wdata.fid; |
} |
579,18 → 522,19 |
* If the call has the IPC_M_CONNECT_ME_TO method, a new connection is created. |
* Otherwise the call is routed to its connection fibril. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
*/ |
static void handle_call(ipc_callid_t callid, ipc_call_t *call) |
{ |
/* Unrouted call - do some default behaviour */ |
if ((callid & IPC_CALLID_NOTIFICATION)) { |
process_notification(callid, call); |
_in_interrupt_handler = 1; |
(*interrupt_received)(callid, call); |
_in_interrupt_handler = 0; |
return; |
} |
} |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_CONNECT_ME_TO: |
/* Open new connection with fibril etc. */ |
598,11 → 542,11 |
client_connection); |
return; |
} |
/* Try to route the call through the connection hash table */ |
if (route_call(callid, call)) |
return; |
/* Unknown call from unknown phone - hang it up */ |
ipc_answer_0(callid, EHANGUP); |
} |
611,44 → 555,47 |
static void handle_expired_timeouts(void) |
{ |
struct timeval tv; |
awaiter_t *waiter; |
link_t *cur; |
gettimeofday(&tv, NULL); |
futex_down(&async_futex); |
link_t *cur = timeout_list.next; |
cur = timeout_list.next; |
while (cur != &timeout_list) { |
awaiter_t *waiter = list_get_instance(cur, awaiter_t, link); |
waiter = list_get_instance(cur, awaiter_t, link); |
if (tv_gt(&waiter->expires, &tv)) |
break; |
cur = cur->next; |
list_remove(&waiter->link); |
waiter->inlist = false; |
waiter->timedout = true; |
waiter->inlist = 0; |
waiter->timedout = 1; |
/* |
* Redundant condition? |
* The fibril should not be active when it gets here. |
* Redundant condition? |
* The fibril should not be active when it gets here. |
*/ |
if (!waiter->active) { |
waiter->active = true; |
waiter->active = 1; |
fibril_add_ready(waiter->fid); |
} |
} |
futex_up(&async_futex); |
} |
/** Endless loop dispatching incoming calls and answers. |
* |
* @return Never returns. |
* |
* @return Never returns. |
*/ |
static int async_manager_worker(void) |
{ |
while (true) { |
ipc_call_t call; |
ipc_callid_t callid; |
int timeout; |
awaiter_t *waiter; |
struct timeval tv; |
while (1) { |
if (fibril_switch(FIBRIL_FROM_MANAGER)) { |
futex_up(&async_futex); |
/* |
657,17 → 604,11 |
*/ |
continue; |
} |
futex_down(&async_futex); |
suseconds_t timeout; |
if (!list_empty(&timeout_list)) { |
awaiter_t *waiter |
= list_get_instance(timeout_list.next, awaiter_t, link); |
struct timeval tv; |
waiter = list_get_instance(timeout_list.next, awaiter_t, |
link); |
gettimeofday(&tv, NULL); |
if (tv_gteq(&tv, &waiter->expires)) { |
futex_up(&async_futex); |
handle_expired_timeouts(); |
676,21 → 617,19 |
timeout = tv_sub(&waiter->expires, &tv); |
} else |
timeout = SYNCH_NO_TIMEOUT; |
futex_up(&async_futex); |
ipc_call_t call; |
ipc_callid_t callid |
= ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE); |
callid = ipc_wait_cycle(&call, timeout, SYNCH_FLAGS_NONE); |
if (!callid) { |
handle_expired_timeouts(); |
continue; |
} |
if (callid & IPC_CALLID_ANSWERED) |
if (callid & IPC_CALLID_ANSWERED) { |
continue; |
} |
handle_call(callid, &call); |
} |
698,17 → 637,16 |
} |
/** Function to start async_manager as a standalone fibril. |
* |
* |
* When more kernel threads are used, one async manager should exist per thread. |
* |
* @param arg Unused. |
* @return Never returns. |
* @param arg Unused. |
* |
* @return Never returns. |
*/ |
static int async_manager_fibril(void *arg) |
{ |
futex_up(&async_futex); |
/* |
* async_futex is always locked when entering manager |
*/ |
720,7 → 658,9 |
/** Add one manager to manager list. */ |
void async_create_manager(void) |
{ |
fid_t fid = fibril_create(async_manager_fibril, NULL); |
fid_t fid; |
fid = fibril_create(async_manager_fibril, NULL); |
fibril_add_manager(fid); |
} |
732,7 → 672,7 |
/** Initialize the async framework. |
* |
* @return Zero on success or an error code. |
* @return Zero on success or an error code. |
*/ |
int _async_init(void) |
{ |
752,33 → 692,30 |
* |
* Notify the fibril which is waiting for this message that it has arrived. |
* |
* @param arg Pointer to the asynchronous message record. |
* @param retval Value returned in the answer. |
* @param data Call data of the answer. |
* @param private Pointer to the asynchronous message record. |
* @param retval Value returned in the answer. |
* @param data Call data of the answer. |
*/ |
static void reply_received(void *arg, int retval, ipc_call_t *data) |
static void reply_received(void *private, int retval, ipc_call_t *data) |
{ |
amsg_t *msg = (amsg_t *) arg; |
amsg_t *msg = (amsg_t *) private; |
msg->retval = retval; |
futex_down(&async_futex); |
/* Copy data after futex_down, just in case the call was detached */ |
if (msg->dataptr) |
*msg->dataptr = *data; |
*msg->dataptr = *data; |
write_barrier(); |
/* Remove message from timeout list */ |
if (msg->wdata.inlist) |
list_remove(&msg->wdata.link); |
msg->done = true; |
msg->done = 1; |
if (!msg->wdata.active) { |
msg->wdata.active = true; |
msg->wdata.active = 1; |
fibril_add_ready(msg->wdata.fid); |
} |
futex_up(&async_futex); |
} |
787,35 → 724,38 |
* The return value can be used as input for async_wait() to wait for |
* completion. |
* |
* @param phoneid Handle of the phone that will be used for the send. |
* @param method Service-defined method. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param dataptr If non-NULL, storage where the reply data will be |
* stored. |
* @param phoneid Handle of the phone that will be used for the send. |
* @param method Service-defined method. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param dataptr If non-NULL, storage where the reply data will be |
* stored. |
* |
* @return Hash of the sent message or 0 on error. |
* |
* @return Hash of the sent message. |
*/ |
aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) |
{ |
amsg_t *msg = malloc(sizeof(*msg)); |
if (!msg) |
return 0; |
msg->done = false; |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot send asynchronous request in interrupt " |
"handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
msg->done = 0; |
msg->dataptr = dataptr; |
/* We may sleep in the next method, but it will use its own mechanism */ |
msg->wdata.active = true; |
msg->wdata.active = 1; |
ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg, |
reply_received, true); |
reply_received, 1); |
return (aid_t) msg; |
} |
824,118 → 764,113 |
* The return value can be used as input for async_wait() to wait for |
* completion. |
* |
* @param phoneid Handle of the phone that will be used for the send. |
* @param method Service-defined method. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param arg5 Service-defined payload argument. |
* @param dataptr If non-NULL, storage where the reply data will be |
* stored. |
* @param phoneid Handle of the phone that will be used for the send. |
* @param method Service-defined method. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param arg5 Service-defined payload argument. |
* @param dataptr If non-NULL, storage where the reply data will be |
* stored. |
* |
* @return Hash of the sent message or 0 on error. |
* |
* @return Hash of the sent message. |
*/ |
aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
ipc_call_t *dataptr) |
{ |
amsg_t *msg = malloc(sizeof(*msg)); |
if (!msg) |
return 0; |
msg->done = false; |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot send asynchronous request in interrupt " |
"handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
msg->done = 0; |
msg->dataptr = dataptr; |
/* We may sleep in next method, but it will use its own mechanism */ |
msg->wdata.active = true; |
msg->wdata.active = 1; |
ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg, |
reply_received, true); |
reply_received, 1); |
return (aid_t) msg; |
} |
/** Wait for a message sent by the async framework. |
* |
* @param amsgid Hash of the message to wait for. |
* @param retval Pointer to storage where the retval of the answer will |
* be stored. |
* |
* @param amsgid Hash of the message to wait for. |
* @param retval Pointer to storage where the retval of the answer will |
* be stored. |
*/ |
void async_wait_for(aid_t amsgid, ipcarg_t *retval) |
{ |
amsg_t *msg = (amsg_t *) amsgid; |
futex_down(&async_futex); |
if (msg->done) { |
futex_up(&async_futex); |
goto done; |
} |
msg->wdata.fid = fibril_get_id(); |
msg->wdata.active = false; |
msg->wdata.inlist = false; |
msg->wdata.active = 0; |
msg->wdata.inlist = 0; |
/* Leave the async_futex locked when entering this function */ |
fibril_switch(FIBRIL_TO_MANAGER); |
/* Futex is up automatically after fibril_switch */ |
/* futex is up automatically after fibril_switch...*/ |
done: |
if (retval) |
*retval = msg->retval; |
free(msg); |
} |
/** Wait for a message sent by the async framework, timeout variant. |
* |
* @param amsgid Hash of the message to wait for. |
* @param retval Pointer to storage where the retval of the answer will |
* be stored. |
* @param timeout Timeout in microseconds. |
* @param amsgid Hash of the message to wait for. |
* @param retval Pointer to storage where the retval of the answer will |
* be stored. |
* @param timeout Timeout in microseconds. |
* |
* @return Zero on success, ETIMEOUT if the timeout has expired. |
* |
* @return Zero on success, ETIMEOUT if the timeout has expired. |
*/ |
int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, suseconds_t timeout) |
{ |
amsg_t *msg = (amsg_t *) amsgid; |
/* TODO: Let it go through the event read at least once */ |
if (timeout < 0) |
return ETIMEOUT; |
futex_down(&async_futex); |
if (msg->done) { |
futex_up(&async_futex); |
goto done; |
} |
gettimeofday(&msg->wdata.expires, NULL); |
tv_add(&msg->wdata.expires, timeout); |
msg->wdata.fid = fibril_get_id(); |
msg->wdata.active = false; |
msg->wdata.active = 0; |
insert_timeout(&msg->wdata); |
/* Leave the async_futex locked when entering this function */ |
fibril_switch(FIBRIL_TO_MANAGER); |
/* Futex is up automatically after fibril_switch */ |
/* futex is up automatically after fibril_switch...*/ |
if (!msg->done) |
return ETIMEOUT; |
done: |
if (retval) |
*retval = msg->retval; |
free(msg); |
return 0; |
} |
943,38 → 878,38 |
* |
* The current fibril is suspended but the thread continues to execute. |
* |
* @param timeout Duration of the wait in microseconds. |
* |
* @param timeout Duration of the wait in microseconds. |
*/ |
void async_usleep(suseconds_t timeout) |
{ |
amsg_t *msg = malloc(sizeof(*msg)); |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot call async_usleep in interrupt handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
if (!msg) |
return; |
msg->wdata.fid = fibril_get_id(); |
msg->wdata.active = false; |
msg->wdata.active = 0; |
gettimeofday(&msg->wdata.expires, NULL); |
tv_add(&msg->wdata.expires, timeout); |
futex_down(&async_futex); |
insert_timeout(&msg->wdata); |
/* Leave the async_futex locked when entering this function */ |
fibril_switch(FIBRIL_TO_MANAGER); |
/* Futex is up automatically after fibril_switch() */ |
/* futex is up automatically after fibril_switch()...*/ |
free(msg); |
} |
/** Setter for client_connection function pointer. |
* |
* @param conn Function that will implement a new connection fibril. |
* |
* @param conn Function that will implement a new connection fibril. |
*/ |
void async_set_client_connection(async_client_conn_t conn) |
{ |
983,12 → 918,12 |
/** Setter for interrupt_received function pointer. |
* |
* @param intr Function that will implement a new interrupt |
* notification fibril. |
* @param conn Function that will implement a new interrupt |
* notification fibril. |
*/ |
void async_set_interrupt_received(async_client_conn_t intr) |
void async_set_interrupt_received(async_client_conn_t conn) |
{ |
interrupt_received = intr; |
interrupt_received = conn; |
} |
/** Pseudo-synchronous message sending - fast version. |
998,20 → 933,18 |
* This function can only transfer 4 register payload arguments. For |
* transferring more arguments, see the slower async_req_slow(). |
* |
* @param phoneid Hash of the phone through which to make the call. |
* @param method Method of the call. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param r1 If non-NULL, storage for the 1st reply argument. |
* @param r2 If non-NULL, storage for the 2nd reply argument. |
* @param r3 If non-NULL, storage for the 3rd reply argument. |
* @param r4 If non-NULL, storage for the 4th reply argument. |
* @param r5 If non-NULL, storage for the 5th reply argument. |
* |
* @return Return code of the reply or a negative error code. |
* |
* @param phoneid Hash of the phone through which to make the call. |
* @param method Method of the call. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param r1 If non-NULL, storage for the 1st reply argument. |
* @param r2 If non-NULL, storage for the 2nd reply argument. |
* @param r3 If non-NULL, storage for the 3rd reply argument. |
* @param r4 If non-NULL, storage for the 4th reply argument. |
* @param r5 If non-NULL, storage for the 5th reply argument. |
* @return Return code of the reply or a negative error code. |
*/ |
ipcarg_t async_req_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t *r1, ipcarg_t *r2, |
1018,27 → 951,21 |
ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5) |
{ |
ipc_call_t result; |
ipcarg_t rc; |
aid_t eid = async_send_4(phoneid, method, arg1, arg2, arg3, arg4, |
&result); |
ipcarg_t rc; |
async_wait_for(eid, &rc); |
if (r1) |
if (r1) |
*r1 = IPC_GET_ARG1(result); |
if (r2) |
*r2 = IPC_GET_ARG2(result); |
if (r3) |
*r3 = IPC_GET_ARG3(result); |
if (r4) |
*r4 = IPC_GET_ARG4(result); |
if (r5) |
*r5 = IPC_GET_ARG5(result); |
return rc; |
} |
1046,21 → 973,19 |
* |
* Send message asynchronously and return only after the reply arrives. |
* |
* @param phoneid Hash of the phone through which to make the call. |
* @param method Method of the call. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param arg5 Service-defined payload argument. |
* @param r1 If non-NULL, storage for the 1st reply argument. |
* @param r2 If non-NULL, storage for the 2nd reply argument. |
* @param r3 If non-NULL, storage for the 3rd reply argument. |
* @param r4 If non-NULL, storage for the 4th reply argument. |
* @param r5 If non-NULL, storage for the 5th reply argument. |
* |
* @return Return code of the reply or a negative error code. |
* |
* @param phoneid Hash of the phone through which to make the call. |
* @param method Method of the call. |
* @param arg1 Service-defined payload argument. |
* @param arg2 Service-defined payload argument. |
* @param arg3 Service-defined payload argument. |
* @param arg4 Service-defined payload argument. |
* @param arg5 Service-defined payload argument. |
* @param r1 If non-NULL, storage for the 1st reply argument. |
* @param r2 If non-NULL, storage for the 2nd reply argument. |
* @param r3 If non-NULL, storage for the 3rd reply argument. |
* @param r4 If non-NULL, storage for the 4th reply argument. |
* @param r5 If non-NULL, storage for the 5th reply argument. |
* @return Return code of the reply or a negative error code. |
*/ |
ipcarg_t async_req_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, ipcarg_t *r1, |
1067,27 → 992,21 |
ipcarg_t *r2, ipcarg_t *r3, ipcarg_t *r4, ipcarg_t *r5) |
{ |
ipc_call_t result; |
ipcarg_t rc; |
aid_t eid = async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, |
&result); |
ipcarg_t rc; |
async_wait_for(eid, &rc); |
if (r1) |
if (r1) |
*r1 = IPC_GET_ARG1(result); |
if (r2) |
*r2 = IPC_GET_ARG2(result); |
if (r3) |
*r3 = IPC_GET_ARG3(result); |
if (r4) |
*r4 = IPC_GET_ARG4(result); |
if (r5) |
*r5 = IPC_GET_ARG5(result); |
return rc; |
} |
/branches/tracing/uspace/lib/libc/generic/ddi.c |
---|
33,42 → 33,26 |
*/ |
#include <ddi.h> |
#include <libarch/ddi.h> |
#include <libc.h> |
#include <task.h> |
#include <as.h> |
#include <align.h> |
#include <libarch/config.h> |
#include <kernel/ddi/ddi_arg.h> |
/** Return unique device number. |
* |
* @return New unique device number. |
* |
*/ |
int device_assign_devno(void) |
{ |
return __SYSCALL0(SYS_DEVICE_ASSIGN_DEVNO); |
} |
/** Map piece of physical memory to task. |
* |
* Caller of this function must have the CAP_MEM_MANAGER capability. |
* |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pages Number of pages to map. |
* @param flags Flags for the new address space area. |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the sterting page. |
* @param pages Number of pages to map. |
* @param flags Flags for the new address space area. |
* |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_MEM_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in creating address space area. |
* @return 0 on success, EPERM if the caller lacks the CAP_MEM_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in creating address space area. |
*/ |
int physmem_map(void *pf, void *vp, unsigned long pages, int flags) |
{ |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, |
flags); |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, flags); |
} |
/** Enable I/O space range to task. |
75,14 → 59,13 |
* |
* Caller of this function must have the IO_MEM_MANAGER capability. |
* |
* @param id Task ID. |
* @param ioaddr Starting address of the I/O range. |
* @param size Size of the range. |
* @param id Task ID. |
* @param ioaddr Starting address of the I/O range. |
* @param size Size of the range. |
* |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_IO_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in allocating memory. |
* @return 0 on success, EPERM if the caller lacks the CAP_IO_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in allocating memory. |
*/ |
int iospace_enable(task_id_t id, void *ioaddr, unsigned long size) |
{ |
97,7 → 80,7 |
/** Interrupt control |
* |
* @param enable 1 - enable interrupts, 0 - disable interrupts |
* @param enable 1 - enable interrupts, 0 - disable interrupts |
*/ |
int preemption_control(int enable) |
{ |
104,36 → 87,5 |
return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable); |
} |
/** Enable PIO for specified I/O range. |
* |
* @param pio_addr I/O start address. |
* @param size Size of the I/O region. |
* @param use_addr Address where the final address for application's PIO |
* will be stored. |
* |
* @return Zero on success or negative error code. |
*/ |
int pio_enable(void *pio_addr, size_t size, void **use_addr) |
{ |
void *phys; |
void *virt; |
size_t offset; |
unsigned int pages; |
#ifdef IO_SPACE_BOUNDARY |
if (pio_addr < IO_SPACE_BOUNDARY) { |
*use_addr = pio_addr; |
return iospace_enable(task_get_id(), pio_addr, size); |
} |
#endif |
phys = ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); |
offset = pio_addr - phys; |
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH; |
virt = as_get_mappable_page(pages); |
*use_addr = virt + offset; |
return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE); |
} |
/** @} |
*/ |
/branches/tracing/uspace/lib/libc/generic/sysinfo.c |
---|
38,8 → 38,7 |
sysarg_t sysinfo_value(char *name) |
{ |
return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t ) name, |
(sysarg_t) str_size(name)); |
return __SYSCALL2(SYS_SYSINFO_VALUE, (sysarg_t ) name, (sysarg_t) strlen(name)); |
} |
/** @} |
/branches/tracing/uspace/lib/libc/Makefile |
---|
29,8 → 29,11 |
## Common compiler flags |
# |
include ../../Makefile.config |
LIBC_PREFIX = $(shell pwd) |
SOFTINT_PREFIX = ../softint |
CONSOLE_PREFIX = ../../srv/console |
## Setup toolchain |
# |
37,18 → 40,17 |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I$(CONSOLE_PREFIX) |
## Sources |
# |
GENERIC_SOURCES = \ |
generic/libc.c \ |
generic/ddi.c \ |
generic/as.c \ |
generic/cap.c \ |
generic/console.c \ |
generic/event.c \ |
generic/mem.c \ |
generic/string.c \ |
generic/fibril.c \ |
generic/pcb.c \ |
60,8 → 62,6 |
generic/io/asprintf.c \ |
generic/io/io.c \ |
generic/io/printf.c \ |
generic/io/fprintf.c \ |
generic/io/stdio.c \ |
generic/io/stream.c \ |
generic/io/sprintf.c \ |
generic/io/snprintf.c \ |
80,7 → 80,6 |
generic/time.c \ |
generic/err.c \ |
generic/stdlib.c \ |
generic/kbd.c \ |
generic/mman.c \ |
generic/udebug.c \ |
generic/vfs/vfs.c \ |
87,35 → 86,34 |
generic/vfs/canonify.c |
ARCH_SOURCES += \ |
arch/$(UARCH)/src/entry.s \ |
arch/$(UARCH)/src/thread_entry.s |
arch/$(ARCH)/src/entry.s \ |
arch/$(ARCH)/src/thread_entry.s |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS) |
.PHONY: all clean depend kerninc |
all: kerninc libc.a arch/$(UARCH)/_link.ld |
all: kerninc libc.a arch/$(ARCH)/_link.ld |
kerninc: |
ln -sfn ../../../../kernel/generic/include include/kernel |
ln -sfn kernel/arch include/arch |
ln -sfn ../arch/$(UARCH)/include include/libarch |
ln -sfn ../arch/$(ARCH)/include include/libarch |
-include Makefile.depend |
clean: |
-rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend |
find generic/ arch/$(UARCH)/ malloc -name '*.o' -follow -exec rm \{\} \; |
-rm -f include/kernel include/arch include/libarch libc.a arch/$(ARCH)/_link.ld Makefile.depend |
find generic/ arch/$(ARCH)/ -name '*.o' -follow -exec rm \{\} \; |
depend: kerninc |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in |
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in |
$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ |
%.o: %.S |
/branches/tracing/uspace/lib/libc/Makefile.toolchain |
---|
26,26 → 26,16 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration \ |
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32 -finput-charset=UTF-8 \ |
-Wmissing-prototypes -O3 -nostdlib -nostdinc -imacros \ |
$(LIBC_PREFIX)/../../../config.h -I$(LIBC_PREFIX)/include -pipe -g |
DEFS = -DARCH=$(ARCH) |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include -pipe |
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS = |
#-Werror |
## Cross-toolchain prefix |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
## Setup platform configuration |
# |
-include $(LIBC_PREFIX)/../../../Makefile.config |
-include $(LIBC_PREFIX)/../../../config.defs |
-include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc |
include $(LIBC_PREFIX)/arch/$(ARCH)/Makefile.inc |
## Simple detection of the host system |
# |
69,7 → 59,6 |
AR = $(BINUTILS_PREFIX)ar |
OBJCOPY = $(BINUTILS_PREFIX)objcopy |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),icc_native) |
79,7 → 68,6 |
AR = ar |
OBJCOPY = objcopy |
OBJDUMP = objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),gcc_cross) |
89,5 → 77,5 |
AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar |
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
/branches/tracing/uspace/lib/libfs/libfs.c |
---|
148,9 → 148,9 |
if (last < next) |
last += PLB_SIZE; |
fs_node_t *par = NULL; |
fs_node_t *cur = ops->root_get(dev_handle); |
fs_node_t *tmp = NULL; |
void *par = NULL; |
void *cur = ops->root_get(dev_handle); |
void *tmp = NULL; |
if (ops->plb_get_char(next) == '/') |
next++; /* eat slash */ |
189,33 → 189,39 |
ipc_answer_0(rid, ENOTDIR); |
goto out; |
} |
fs_node_t *fn; |
void *nodep; |
if (lflag & L_CREATE) |
fn = ops->create(dev_handle, lflag); |
nodep = ops->create(dev_handle, lflag); |
else |
fn = ops->node_get(dev_handle, |
nodep = ops->node_get(dev_handle, |
index); |
if (fn) { |
if (nodep) { |
int rc; |
rc = ops->link(cur, fn, component); |
rc = ops->link(cur, nodep, component); |
if (rc != EOK) { |
if (lflag & L_CREATE) { |
(void)ops->destroy(fn); |
(void)ops->destroy( |
nodep); |
} |
ipc_answer_0(rid, rc); |
} else { |
ipc_answer_5(rid, EOK, |
fs_handle, dev_handle, |
ops->index_get(fn), |
ops->size_get(fn), |
ops->lnkcnt_get(fn)); |
ops->node_put(fn); |
ops->index_get(nodep), |
ops->size_get(nodep), |
ops->lnkcnt_get(nodep)); |
ops->node_put(nodep); |
} |
} else { |
ipc_answer_0(rid, ENOSPC); |
} |
goto out; |
} else if (lflag & L_PARENT) { |
/* return parent */ |
ipc_answer_5(rid, EOK, fs_handle, dev_handle, |
ops->index_get(cur), ops->size_get(cur), |
ops->lnkcnt_get(cur)); |
} |
ipc_answer_0(rid, ENOENT); |
goto out; |
257,26 → 263,26 |
assert(len); |
component[len] = '\0'; |
fs_node_t *fn; |
void *nodep; |
if (lflag & L_CREATE) |
fn = ops->create(dev_handle, lflag); |
nodep = ops->create(dev_handle, lflag); |
else |
fn = ops->node_get(dev_handle, index); |
if (fn) { |
nodep = ops->node_get(dev_handle, index); |
if (nodep) { |
int rc; |
rc = ops->link(cur, fn, component); |
rc = ops->link(cur, nodep, component); |
if (rc != EOK) { |
if (lflag & L_CREATE) |
(void)ops->destroy(fn); |
(void)ops->destroy(nodep); |
ipc_answer_0(rid, rc); |
} else { |
ipc_answer_5(rid, EOK, |
fs_handle, dev_handle, |
ops->index_get(fn), |
ops->size_get(fn), |
ops->lnkcnt_get(fn)); |
ops->node_put(fn); |
ops->index_get(nodep), |
ops->size_get(nodep), |
ops->lnkcnt_get(nodep)); |
ops->node_put(nodep); |
} |
} else { |
ipc_answer_0(rid, ENOSPC); |
288,9 → 294,18 |
} |
/* handle hit */ |
if (lflag & L_PARENT) { |
ops->node_put(cur); |
cur = par; |
par = NULL; |
if (!cur) { |
ipc_answer_0(rid, ENOENT); |
goto out; |
} |
} |
if (lflag & L_UNLINK) { |
unsigned old_lnkcnt = ops->lnkcnt_get(cur); |
int res = ops->unlink(par, cur, component); |
int res = ops->unlink(par, cur); |
ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle, |
ops->index_get(cur), ops->size_get(cur), old_lnkcnt); |
goto out; |
/branches/tracing/uspace/lib/libfs/libfs.h |
---|
42,25 → 42,21 |
#include <async.h> |
typedef struct { |
void *data; /**< Data of the file system implementation. */ |
} fs_node_t; |
typedef struct { |
fs_node_t * (* match)(fs_node_t *, const char *); |
fs_node_t * (* node_get)(dev_handle_t, fs_index_t); |
void (* node_put)(fs_node_t *); |
fs_node_t * (* create)(dev_handle_t, int); |
int (* destroy)(fs_node_t *); |
int (* link)(fs_node_t *, fs_node_t *, const char *); |
int (* unlink)(fs_node_t *, fs_node_t *, const char *); |
fs_index_t (* index_get)(fs_node_t *); |
size_t (* size_get)(fs_node_t *); |
unsigned (* lnkcnt_get)(fs_node_t *); |
bool (* has_children)(fs_node_t *); |
fs_node_t *(* root_get)(dev_handle_t); |
void * (* match)(void *, const char *); |
void * (* node_get)(dev_handle_t, fs_index_t); |
void (* node_put)(void *); |
void * (* create)(dev_handle_t, int); |
int (* destroy)(void *); |
int (* link)(void *, void *, const char *); |
int (* unlink)(void *, void *); |
fs_index_t (* index_get)(void *); |
size_t (* size_get)(void *); |
unsigned (* lnkcnt_get)(void *); |
bool (* has_children)(void *); |
void *(* root_get)(dev_handle_t); |
char (* plb_get_char)(unsigned pos); |
bool (* is_directory)(fs_node_t *); |
bool (* is_file)(fs_node_t *); |
bool (* is_directory)(void *); |
bool (* is_file)(void *); |
} libfs_ops_t; |
typedef struct { |
/branches/tracing/uspace/lib/libfs/Makefile |
---|
30,8 → 30,9 |
## Common compiler flags |
# |
include ../../Makefile.config |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
58,7 → 59,7 |
find . -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
libfs.a: depend $(OBJECTS) |
$(AR) rc libfs.a $(OBJECTS) |
/branches/tracing/uspace/lib/libblock/libblock.c |
---|
27,15 → 27,15 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libblock |
/** @addtogroup libblock |
* @{ |
*/ |
*/ |
/** |
* @file |
* @brief |
*/ |
#include "libblock.h" |
#include "libblock.h" |
#include "../../srv/vfs/vfs.h" |
#include "../../srv/rd/rd.h" |
#include <ipc/devmap.h> |
146,7 → 146,7 |
if (!com_area) { |
return ENOMEM; |
} |
dev_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, |
dev_phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_CONNECT_TO_DEVICE, dev_handle); |
if (dev_phone < 0) { |
/branches/tracing/uspace/lib/libblock/Makefile |
---|
30,8 → 30,9 |
## Common compiler flags |
# |
include ../../Makefile.config |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
58,7 → 59,7 |
find . -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
libblock.a: depend $(OBJECTS) |
$(AR) rc libblock.a $(OBJECTS) |
/branches/tracing/uspace/lib/softfloat/Makefile |
---|
29,27 → 29,28 |
## Common compiler flags |
# |
include ../../Makefile.config |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS +=-Iinclude -Iarch/$(UARCH)/include/ |
CFLAGS +=-Iinclude -Iarch/$(ARCH)/include/ |
## Sources |
# |
GENERIC_SOURCES = \ |
generic/add.c \ |
generic/common.c \ |
generic/comparison.c \ |
generic/conversion.c \ |
generic/div.c \ |
generic/mul.c \ |
generic/other.c \ |
generic/softfloat.c \ |
GENERIC_SOURCES = \ |
generic/add.c \ |
generic/common.c \ |
generic/comparison.c \ |
generic/conversion.c \ |
generic/div.c \ |
generic/mul.c \ |
generic/other.c \ |
generic/softfloat.c \ |
generic/sub.c |
ARCH_SOURCES = |
67,7 → 68,7 |
find generic/ -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
/branches/tracing/uspace/lib/softfloat/arch/ppc64/include/functions.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup softfloatppc64 ppc64 |
* @ingroup sfl |
* @brief softfloat architecture dependent definitions |
* @{ |
*/ |
/** @file |
*/ |
#ifndef __SOFTFLOAT_FUNCTIONS_H__ |
#define __SOFTFLOAT_FUNCTIONS_H__ |
#define float32_to_int(X) float32_to_int32(X); |
#define float32_to_long(X) float32_to_int64(X); |
#define float32_to_longlong(X) float32_to_int64(X); |
#define float64_to_int(X) float64_to_int32(X); |
#define float64_to_long(X) float64_to_int64(X); |
#define float64_to_longlong(X) float64_to_int64(X); |
#define float32_to_uint(X) float32_to_uint32(X); |
#define float32_to_ulong(X) float32_to_uint64(X); |
#define float32_to_ulonglong(X) float32_to_uint64(X); |
#define float64_to_uint(X) float64_to_uint32(X); |
#define float64_to_ulong(X) float64_to_uint64(X); |
#define float64_to_ulonglong(X) float64_to_uint64(X); |
#define int_to_float32(X) int32_to_float32(X); |
#define long_to_float32(X) int64_to_float32(X); |
#define longlong_to_float32(X) int64_to_float32(X); |
#define int_to_float64(X) int32_to_float64(X); |
#define long_to_float64(X) int64_to_float64(X); |
#define longlong_to_float64(X) int64_to_float64(X); |
#define uint_to_float32(X) uint32_to_float32(X); |
#define ulong_to_float32(X) uint64_to_float32(X); |
#define ulonglong_to_float32(X) uint64_to_float32(X); |
#define uint_to_float64(X) uint32_to_float64(X); |
#define ulong_to_float64(X) uint64_to_float64(X); |
#define ulonglong_to_float64(X) uint64_to_float64(X); |
#endif |
/** @} |
*/ |
/branches/tracing/uspace/lib/softint/Makefile |
---|
29,8 → 29,9 |
## Common compiler flags |
# |
include ../../Makefile.config |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
59,7 → 60,7 |
find generic/ -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |