Make sure FPSCR is properly initialized
This is a potentially breaking change as the register was left with an unpredictable/unspecified value. Config: default NaN mode enabled, flush-to-zero enabled, and round to nearest.
This commit is contained in:
parent
c36d9cc4a6
commit
11686876ac
@ -31,7 +31,20 @@ typedef struct
|
|||||||
bool srv_blocking_policy;
|
bool srv_blocking_policy;
|
||||||
} ThreadVars;
|
} ThreadVars;
|
||||||
|
|
||||||
|
struct Thread_tag
|
||||||
|
{
|
||||||
|
Handle handle;
|
||||||
|
ThreadFunc ep;
|
||||||
|
void* arg;
|
||||||
|
int rc;
|
||||||
|
bool detached, finished;
|
||||||
|
struct _reent reent;
|
||||||
|
void* stacktop;
|
||||||
|
};
|
||||||
|
|
||||||
static inline ThreadVars* getThreadVars(void)
|
static inline ThreadVars* getThreadVars(void)
|
||||||
{
|
{
|
||||||
return (ThreadVars*)getThreadLocalStorage();
|
return (ThreadVars*)getThreadLocalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initThreadVars(struct Thread_tag *thread);
|
||||||
|
@ -99,18 +99,27 @@ void __SYSCALL(exit)(int rc) {
|
|||||||
__ctru_exit(rc);
|
__ctru_exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initThreadVars(struct Thread_tag *thread)
|
||||||
|
{
|
||||||
|
ThreadVars* tv = getThreadVars();
|
||||||
|
tv->magic = THREADVARS_MAGIC;
|
||||||
|
tv->reent = thread != NULL ? &thread->reent : _impure_ptr;
|
||||||
|
tv->thread_ptr = thread;
|
||||||
|
tv->tls_tp = (thread != NULL ? (u8*)thread->stacktop : __tls_start) - 8; // Arm ELF TLS ABI mandates an 8-byte header
|
||||||
|
tv->srv_blocking_policy = false;
|
||||||
|
|
||||||
|
// Kernel does not initialize fpscr at all, so we must do it ourselves
|
||||||
|
// https://developer.arm.com/documentation/ddi0360/f/vfp-programmers-model/vfp11-system-registers/floating-point-status-and-control-register--fpscr
|
||||||
|
|
||||||
|
// All flags clear, all interrupts disabled, all instruction scalar.
|
||||||
|
// As for the 3 below fields: default NaN mode, flush-to-zero both enabled & round to nearest.
|
||||||
|
__builtin_arm_set_fpscr(BIT(25) | BIT(24) | (0u << 22));
|
||||||
|
}
|
||||||
|
|
||||||
void __system_initSyscalls(void)
|
void __system_initSyscalls(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
// Initialize thread vars for the main thread
|
// Initialize thread vars for the main thread
|
||||||
ThreadVars* tv = getThreadVars();
|
initThreadVars(NULL);
|
||||||
tv->magic = THREADVARS_MAGIC;
|
|
||||||
tv->reent = _impure_ptr;
|
|
||||||
tv->thread_ptr = NULL;
|
|
||||||
tv->tls_tp = __tls_start-8; // ARM ELF TLS ABI mandates an 8-byte header
|
|
||||||
tv->srv_blocking_policy = false;
|
|
||||||
|
|
||||||
u32 tls_size = __tdata_lma_end - __tdata_lma;
|
u32 tls_size = __tdata_lma_end - __tdata_lma;
|
||||||
if (tls_size)
|
if (tls_size)
|
||||||
memcpy(__tls_start, __tdata_lma, tls_size);
|
memcpy(__tls_start, __tdata_lma, tls_size);
|
||||||
|
@ -8,17 +8,6 @@ extern const u8 __tdata_lma_end[];
|
|||||||
extern u8 __tls_start[];
|
extern u8 __tls_start[];
|
||||||
extern u8 __tls_end[];
|
extern u8 __tls_end[];
|
||||||
|
|
||||||
struct Thread_tag
|
|
||||||
{
|
|
||||||
Handle handle;
|
|
||||||
ThreadFunc ep;
|
|
||||||
void* arg;
|
|
||||||
int rc;
|
|
||||||
bool detached, finished;
|
|
||||||
struct _reent reent;
|
|
||||||
void* stacktop;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __panic(void)
|
static void __panic(void)
|
||||||
{
|
{
|
||||||
svcBreak(USERBREAK_PANIC);
|
svcBreak(USERBREAK_PANIC);
|
||||||
@ -28,12 +17,7 @@ static void __panic(void)
|
|||||||
static void _thread_begin(void* arg)
|
static void _thread_begin(void* arg)
|
||||||
{
|
{
|
||||||
Thread t = (Thread)arg;
|
Thread t = (Thread)arg;
|
||||||
ThreadVars* tv = getThreadVars();
|
initThreadVars(t);
|
||||||
tv->magic = THREADVARS_MAGIC;
|
|
||||||
tv->reent = &t->reent;
|
|
||||||
tv->thread_ptr = t;
|
|
||||||
tv->tls_tp = (u8*)t->stacktop-8; // ARM ELF TLS ABI mandates an 8-byte header
|
|
||||||
tv->srv_blocking_policy = false;
|
|
||||||
t->ep(t->arg);
|
t->ep(t->arg);
|
||||||
threadExit(0);
|
threadExit(0);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user