mirror of
https://github.com/wiiu-env/wut.git
synced 2025-01-05 21:38:18 +01:00
wutnewlib: Implement the new __syscalls from upcoming devkitPPC release.
This commit is contained in:
parent
35d05358c4
commit
f7a698388c
@ -2,8 +2,13 @@ cmake_minimum_required(VERSION 3.2)
|
||||
project(wutnewlib C)
|
||||
|
||||
add_library(wutnewlib
|
||||
sleep.c
|
||||
syscalls.c)
|
||||
wut_clock.c
|
||||
wut_gettod_r.c
|
||||
wut_lock.c
|
||||
wut_malloc_lock.c
|
||||
wut_nanosleep.c
|
||||
wut_newlib.c
|
||||
wut_sbrk.c)
|
||||
target_include_directories(wutnewlib PRIVATE "${WUT_ROOT}/include")
|
||||
|
||||
install(TARGETS wutnewlib
|
||||
|
@ -1,16 +0,0 @@
|
||||
#include <coreinit/thread.h>
|
||||
#include <coreinit/systeminfo.h>
|
||||
#include <coreinit/time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
unsigned sleep(unsigned seconds)
|
||||
{
|
||||
OSSleepTicks(OSSeconds(seconds));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int usleep(useconds_t microseconds)
|
||||
{
|
||||
OSSleepTicks(OSMicroseconds(microseconds));
|
||||
return 0;
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
#include <wut.h>
|
||||
|
||||
#include <coreinit/atomic.h>
|
||||
#include <coreinit/baseheap.h>
|
||||
#include <coreinit/exit.h>
|
||||
#include <coreinit/expandedheap.h>
|
||||
#include <coreinit/mutex.h>
|
||||
#include <coreinit/time.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/iosupport.h>
|
||||
#include <sys/reent.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
static OSMutex sMallocMutex;
|
||||
static uint8_t *sHeapBase = NULL;
|
||||
static uint32_t sHeapMaxSize = 0;
|
||||
static volatile uint32_t sHeapSize = 0;
|
||||
|
||||
static void *
|
||||
__libwut_sbrk_r(struct _reent *r,
|
||||
ptrdiff_t incr)
|
||||
{
|
||||
uint32_t oldSize, newSize;
|
||||
|
||||
do {
|
||||
oldSize = sHeapSize;
|
||||
newSize = oldSize + incr;
|
||||
|
||||
if (newSize > sHeapMaxSize) {
|
||||
r->_errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
} while (!OSCompareAndSwapAtomic(&sHeapSize, oldSize, newSize));
|
||||
|
||||
return sHeapBase + oldSize;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_init(int *lock,
|
||||
int recursive)
|
||||
{
|
||||
OSMutex *mutex = NULL;
|
||||
if (!lock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex = (OSMutex *)malloc(sizeof(OSMutex));
|
||||
if (!mutex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSInitMutex(mutex);
|
||||
*lock = (int)mutex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_close(int *lock)
|
||||
{
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
free((void *)*lock);
|
||||
*lock = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_acquire(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_lock_release(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSUnlockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_malloc_lock(struct _reent *r)
|
||||
{
|
||||
OSLockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_malloc_unlock(struct _reent *r)
|
||||
{
|
||||
OSUnlockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__libwut_exit(int code)
|
||||
{
|
||||
exit(code);
|
||||
}
|
||||
|
||||
static int
|
||||
__libwut_gettod_r(struct _reent *ptr,
|
||||
struct timeval *tp,
|
||||
struct timezone *tz)
|
||||
{
|
||||
OSCalendarTime tm;
|
||||
OSTicksToCalendarTime(OSGetTime(), &tm);
|
||||
|
||||
if (tp != NULL) {
|
||||
tp->tv_sec = tm.tm_sec;
|
||||
tp->tv_usec = tm.tm_usec + tm.tm_msec * 1000;
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
tz->tz_minuteswest = 0;
|
||||
tz->tz_dsttime = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__init_malloc_lock()
|
||||
{
|
||||
OSInitMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
static void
|
||||
__init_libc_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
uint32_t freeSize = MEMGetAllocatableSizeForExpHeapEx(heap, 0x1000);
|
||||
|
||||
sHeapMaxSize = (uint32_t)(0.9f * (float)freeSize) & ~0xFFF;
|
||||
sHeapBase = (uint8_t *)MEMAllocFromExpHeapEx(heap, sHeapMaxSize, 0x1000);
|
||||
sHeapSize = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
__free_libc_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
MEMFreeToExpHeap(heap, sHeapBase);
|
||||
}
|
||||
|
||||
static void
|
||||
__init_syscall_array()
|
||||
{
|
||||
__syscalls.sbrk_r = __libwut_sbrk_r;
|
||||
__syscalls.lock_init = __libwut_lock_init;
|
||||
__syscalls.lock_close = __libwut_lock_close;
|
||||
__syscalls.lock_acquire = __libwut_lock_acquire;
|
||||
__syscalls.lock_release = __libwut_lock_release;
|
||||
__syscalls.malloc_lock = __libwut_malloc_lock;
|
||||
__syscalls.malloc_unlock = __libwut_malloc_unlock;
|
||||
__syscalls.exit = __libwut_exit;
|
||||
__syscalls.gettod_r = __libwut_gettod_r;
|
||||
}
|
||||
|
||||
void
|
||||
__init_wut_newlib()
|
||||
{
|
||||
__init_libc_heap();
|
||||
__init_malloc_lock();
|
||||
__init_syscall_array();
|
||||
}
|
||||
|
||||
void
|
||||
__fini_wut_newlib()
|
||||
{
|
||||
__free_libc_heap();
|
||||
}
|
66
libraries/wutnewlib/wut_clock.c
Normal file
66
libraries/wutnewlib/wut_clock.c
Normal file
@ -0,0 +1,66 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/systeminfo.h>
|
||||
#include <coreinit/time.h>
|
||||
|
||||
// The Wii U epoch is at 2000, so we must map it to 1970 for gettime
|
||||
#define WIIU_EPOCH_YEAR (2000)
|
||||
|
||||
#define EPOCH_YEAR (1970)
|
||||
#define EPOCH_YEARS_SINCE_LEAP 2
|
||||
#define EPOCH_YEARS_SINCE_CENTURY 70
|
||||
#define EPOCH_YEARS_SINCE_LEAP_CENTURY 370
|
||||
|
||||
#define EPOCH_DIFF_YEARS (2000 - EPOCH_YEAR)
|
||||
#define EPOCH_DIFF_DAYS \
|
||||
((EPOCH_DIFF_YEARS * 365) + \
|
||||
(EPOCH_DIFF_YEARS - 1 + EPOCH_YEARS_SINCE_LEAP) / 4 - \
|
||||
(EPOCH_DIFF_YEARS - 1 + EPOCH_YEARS_SINCE_CENTURY) / 100 + \
|
||||
(EPOCH_DIFF_YEARS - 1 + EPOCH_YEARS_SINCE_LEAP_CENTURY) / 400)
|
||||
#define EPOCH_DIFF_SECS (60ull * 60ull * 24ull * (uint64_t)EPOCH_DIFF_DAYS)
|
||||
|
||||
int
|
||||
__wut_clock_gettime(clockid_t clock_id,
|
||||
struct timespec *tp)
|
||||
{
|
||||
if (clock_id == CLOCK_MONOTONIC) {
|
||||
OSTime time = OSGetSystemTime();
|
||||
tp->tv_sec = (time_t)OSTicksToSeconds(time);
|
||||
|
||||
time -= OSSecondsToTicks(tp->tv_sec);
|
||||
tp->tv_nsec = (long)OSTicksToNanoseconds(time);
|
||||
} else if (clock_id == CLOCK_REALTIME) {
|
||||
OSTime time = OSGetTime();
|
||||
tp->tv_sec = (time_t)OSTicksToSeconds(time);
|
||||
|
||||
time -= OSSecondsToTicks(tp->tv_sec);
|
||||
tp->tv_nsec = (long)OSTicksToNanoseconds(time);
|
||||
|
||||
tp->tv_sec += EPOCH_DIFF_SECS;
|
||||
} else {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_clock_settime(clockid_t clock_id,
|
||||
const struct timespec *tp)
|
||||
{
|
||||
return EPERM;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_clock_getres(clockid_t clock_id,
|
||||
struct timespec *res)
|
||||
{
|
||||
if (clock_id != CLOCK_MONOTONIC &&
|
||||
clock_id != CLOCK_REALTIME) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
res->tv_sec = 0;
|
||||
res->tv_nsec = (long)((1000000000ull + (uint64_t)OSTimerClockSpeed) / (uint64_t)OSTimerClockSpeed);
|
||||
return 0;
|
||||
}
|
24
libraries/wutnewlib/wut_gettod_r.c
Normal file
24
libraries/wutnewlib/wut_gettod_r.c
Normal file
@ -0,0 +1,24 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/time.h>
|
||||
|
||||
int
|
||||
__wut_gettod_r(struct _reent *ptr,
|
||||
struct timeval *tp,
|
||||
struct timezone *tz)
|
||||
{
|
||||
OSCalendarTime tm;
|
||||
OSTicksToCalendarTime(OSGetTime(), &tm);
|
||||
|
||||
if (tp != NULL) {
|
||||
tp->tv_sec = tm.tm_sec;
|
||||
tp->tv_usec = tm.tm_usec + tm.tm_msec * 1000;
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
tz->tz_minuteswest = 0;
|
||||
tz->tz_dsttime = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
59
libraries/wutnewlib/wut_lock.c
Normal file
59
libraries/wutnewlib/wut_lock.c
Normal file
@ -0,0 +1,59 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/mutex.h>
|
||||
#include <malloc.h>
|
||||
|
||||
int
|
||||
__wut_lock_init(int *lock,
|
||||
int recursive)
|
||||
{
|
||||
OSMutex *mutex = NULL;
|
||||
if (!lock) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
mutex = (OSMutex *)malloc(sizeof(OSMutex));
|
||||
if (!mutex) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSInitMutex(mutex);
|
||||
*lock = (int)mutex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_lock_close(int *lock)
|
||||
{
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
free((void *)*lock);
|
||||
*lock = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_lock_acquire(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSLockMutex(mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
__wut_lock_release(int *lock)
|
||||
{
|
||||
OSMutex *mutex = (OSMutex *)*lock;
|
||||
if (!lock || *lock == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
OSUnlockMutex(mutex);
|
||||
return 0;
|
||||
}
|
23
libraries/wutnewlib/wut_malloc_lock.c
Normal file
23
libraries/wutnewlib/wut_malloc_lock.c
Normal file
@ -0,0 +1,23 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/mutex.h>
|
||||
|
||||
static OSMutex sMallocMutex;
|
||||
|
||||
void
|
||||
__wut_malloc_lock(struct _reent *r)
|
||||
{
|
||||
OSLockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
void
|
||||
__wut_malloc_unlock(struct _reent *r)
|
||||
{
|
||||
OSUnlockMutex(&sMallocMutex);
|
||||
}
|
||||
|
||||
void
|
||||
__init_wut_malloc_lock()
|
||||
{
|
||||
OSInitMutex(&sMallocMutex);
|
||||
}
|
16
libraries/wutnewlib/wut_nanosleep.c
Normal file
16
libraries/wutnewlib/wut_nanosleep.c
Normal file
@ -0,0 +1,16 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/thread.h>
|
||||
#include <coreinit/systeminfo.h>
|
||||
#include <coreinit/time.h>
|
||||
|
||||
int
|
||||
__wut_nanosleep(const struct timespec *req,
|
||||
struct timespec *rem)
|
||||
{
|
||||
OSSleepTicks(OSSecondsToTicks(req->tv_sec) +
|
||||
OSNanosecondsToTicks(req->tv_nsec));
|
||||
rem->tv_sec = 0;
|
||||
rem->tv_nsec = 0;
|
||||
return 0;
|
||||
}
|
34
libraries/wutnewlib/wut_newlib.c
Normal file
34
libraries/wutnewlib/wut_newlib.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "wut_newlib.h"
|
||||
#include <coreinit/exit.h>
|
||||
|
||||
static void
|
||||
__init_wut_syscall_array()
|
||||
{
|
||||
__syscalls.sbrk_r = __wut_sbrk_r;
|
||||
__syscalls.lock_init = __wut_lock_init;
|
||||
__syscalls.lock_close = __wut_lock_close;
|
||||
__syscalls.lock_acquire = __wut_lock_acquire;
|
||||
__syscalls.lock_release = __wut_lock_release;
|
||||
__syscalls.malloc_lock = __wut_malloc_lock;
|
||||
__syscalls.malloc_unlock = __wut_malloc_unlock;
|
||||
__syscalls.exit = exit;
|
||||
__syscalls.gettod_r = __wut_gettod_r;
|
||||
__syscalls.clock_gettime = __wut_clock_gettime;
|
||||
__syscalls.clock_settime = __wut_clock_settime;
|
||||
__syscalls.clock_getres = __wut_clock_getres;
|
||||
__syscalls.nanosleep = __wut_nanosleep;
|
||||
}
|
||||
|
||||
void
|
||||
__init_wut_newlib()
|
||||
{
|
||||
__init_wut_sbrk_heap();
|
||||
__init_wut_malloc_lock();
|
||||
__init_wut_syscall_array();
|
||||
}
|
||||
|
||||
void
|
||||
__fini_wut_newlib()
|
||||
{
|
||||
__fini_wut_sbrk_heap();
|
||||
}
|
27
libraries/wutnewlib/wut_newlib.h
Normal file
27
libraries/wutnewlib/wut_newlib.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __WUT_NEWLIB_H
|
||||
#define __WUT_NEWLIB_H
|
||||
|
||||
#include <sys/errno.h>
|
||||
#include <sys/reent.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/iosupport.h>
|
||||
|
||||
void * __wut_sbrk_r(struct _reent *r, ptrdiff_t incr);
|
||||
int __wut_lock_init(int *lock, int recursive);
|
||||
int __wut_lock_close(int *lock);
|
||||
int __wut_lock_acquire(int *lock);
|
||||
int __wut_lock_release(int *lock);
|
||||
void __wut_malloc_lock(struct _reent *r);
|
||||
void __wut_malloc_unlock(struct _reent *r);
|
||||
int __wut_gettod_r(struct _reent *ptr, struct timeval *tp,
|
||||
struct timezone *tz);
|
||||
int __wut_clock_gettime(clockid_t clock_id, struct timespec *tp);
|
||||
int __wut_clock_settime(clockid_t clock_id, const struct timespec *tp);
|
||||
int __wut_clock_getres(clockid_t clock_id, struct timespec *res);
|
||||
int __wut_nanosleep(const struct timespec *req, struct timespec *rem);
|
||||
|
||||
void __init_wut_malloc_lock();
|
||||
void __init_wut_sbrk_heap();
|
||||
void __fini_wut_sbrk_heap();
|
||||
|
||||
#endif // ifndef __WUT_NEWLIB_H
|
46
libraries/wutnewlib/wut_sbrk.c
Normal file
46
libraries/wutnewlib/wut_sbrk.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include "wut_newlib.h"
|
||||
|
||||
#include <coreinit/atomic.h>
|
||||
#include <coreinit/baseheap.h>
|
||||
#include <coreinit/expandedheap.h>
|
||||
|
||||
static uint8_t *sHeapBase = NULL;
|
||||
static uint32_t sHeapMaxSize = 0;
|
||||
static volatile uint32_t sHeapSize = 0;
|
||||
|
||||
void *
|
||||
__wut_sbrk_r(struct _reent *r,
|
||||
ptrdiff_t incr)
|
||||
{
|
||||
uint32_t oldSize, newSize;
|
||||
|
||||
do {
|
||||
oldSize = sHeapSize;
|
||||
newSize = oldSize + incr;
|
||||
|
||||
if (newSize > sHeapMaxSize) {
|
||||
r->_errno = ENOMEM;
|
||||
return (void *)-1;
|
||||
}
|
||||
} while (!OSCompareAndSwapAtomic(&sHeapSize, oldSize, newSize));
|
||||
|
||||
return sHeapBase + oldSize;
|
||||
}
|
||||
|
||||
void
|
||||
__init_wut_sbrk_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
uint32_t freeSize = MEMGetAllocatableSizeForExpHeapEx(heap, 0x1000);
|
||||
|
||||
sHeapMaxSize = (uint32_t)(0.9f * (float)freeSize) & ~0xFFF;
|
||||
sHeapBase = (uint8_t *)MEMAllocFromExpHeapEx(heap, sHeapMaxSize, 0x1000);
|
||||
sHeapSize = 0;
|
||||
}
|
||||
|
||||
void
|
||||
__fini_wut_sbrk_heap()
|
||||
{
|
||||
MEMExpandedHeap *heap = (MEMExpandedHeap *)MEMGetBaseHeapHandle(MEM_BASE_HEAP_MEM2);
|
||||
MEMFreeToExpHeap(heap, sHeapBase);
|
||||
}
|
Loading…
Reference in New Issue
Block a user