refactor tcb_t to remove duplication between x86 and arm header files

This commit is contained in:
Anna Lyons 2015-10-16 15:55:34 +11:00 committed by Adrian Danis
parent 5d64d156f4
commit 88d73db06c
10 changed files with 195 additions and 291 deletions

View file

@ -20,73 +20,14 @@
#include <arch/machine/registerset.h>
/* Object sizes */
#define EP_SIZE_BITS 4
#define AEP_SIZE_BITS 4
#define CTE_SIZE_BITS 4
#define TCB_BLOCK_SIZE_BITS (TCB_SIZE_BITS+1)
/* Ensure object sizes are sane */
compile_assert(cte_size_sane, sizeof(cte_t) <= (1 << CTE_SIZE_BITS))
compile_assert(ep_size_sane, sizeof(endpoint_t) <= (1 << EP_SIZE_BITS))
compile_assert(aep_size_sane, sizeof(async_endpoint_t) <= (1 << AEP_SIZE_BITS))
/* TCB CNode: size = 256 bytes */
/* typedef cte_t[16] tcb_cnode; */
/* update this when you modify the tcb struct */
#define EXPECTED_TCB_SIZE 140
/* TCB: alignment = 256 bytes */
struct tcb {
/* Saved user-level context of thread, 72 bytes */
typedef struct arch_tcb {
/* saved user-level context of thread (72 bytes) */
user_context_t tcbContext;
/* Thread state, 12 bytes */
thread_state_t tcbState;
/* Async endpoint that this TCB is bound to. If this is set, when this TCB waits on
* any sync endpoint, it may receive an async notification from the AEP.
* 4 bytes*/
async_endpoint_t *boundAsyncEndpoint;
/* Current fault, 8 bytes */
fault_t tcbFault;
/* Current lookup failure, 8 bytes */
lookup_fault_t tcbLookupFailure;
/* Domain, 1 byte, padded to 4 bytes */
dom_t tcbDomain;
/* Priority, 1 byte, padded to 4 bytes */
prio_t tcbPriority;
/* Timeslice remaining, 4 bytes */
uint32_t tcbTimeSlice;
/* Capability pointer to thread fault handler, 4 bytes */
cptr_t tcbFaultHandler;
/* Physical address of thread IPC buffer, 4 bytes */
word_t tcbIPCBuffer;
/* Previous and next pointers for endpoint & scheduler queues, 16 bytes */
struct tcb *tcbSchedNext, *tcbSchedPrev, *tcbEPNext, *tcbEPPrev;
#ifdef DEBUG
/* Use any remaining space for a thread name */
char tcbName[];
#endif
};
typedef struct tcb tcb_t;
} arch_tcb_t;
/* Ensure TCB size is sane. */
compile_assert(tcb_size_sane,
(1 << TCB_SIZE_BITS) + sizeof(tcb_t) <= (1 << TCB_BLOCK_SIZE_BITS))
compile_assert(tcb_size_expected, sizeof(tcb_t) == EXPECTED_TCB_SIZE)
/* ARM-specific object types */
#define EXPECTED_TCB_SIZE 140
enum vm_rights {
VMNoAccess = 0,
@ -319,28 +260,13 @@ generic_frame_cap_get_capFMappedAddress(cap_t cap)
}
static inline unsigned int CONST
cap_get_capSizeBits(cap_t cap)
cap_get_archCapSizeBits(cap_t cap)
{
cap_tag_t ctag;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return cap_untyped_cap_get_capBlockSize(cap);
case cap_endpoint_cap:
return EP_SIZE_BITS;
case cap_async_endpoint_cap:
return AEP_SIZE_BITS;
case cap_cnode_cap:
return cap_cnode_cap_get_capCNodeRadix(cap) + CTE_SIZE_BITS;
case cap_thread_cap:
return TCB_BLOCK_SIZE_BITS;
case cap_small_frame_cap:
case cap_frame_cap:
return pageBitsForSize(generic_frame_cap_get_capFSize(cap));
@ -354,19 +280,6 @@ cap_get_capSizeBits(cap_t cap)
case cap_asid_pool_cap:
return ASID_POOL_SIZE_BITS;
case cap_zombie_cap: {
uint32_t type = cap_zombie_cap_get_capZombieType(cap);
if (type == ZombieType_ZombieTCB) {
return TCB_BLOCK_SIZE_BITS;
}
return ZombieType_ZombieCNode(type) + CTE_SIZE_BITS;
}
case cap_null_cap:
case cap_domain_cap:
case cap_reply_cap:
case cap_irq_control_cap:
case cap_irq_handler_cap:
case cap_asid_control_cap:
return 0;
@ -377,27 +290,13 @@ cap_get_capSizeBits(cap_t cap)
}
static inline void * CONST
cap_get_capPtr(cap_t cap)
cap_get_archCapPtr(cap_t cap)
{
cap_tag_t ctag;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return WORD_PTR(cap_untyped_cap_get_capPtr(cap));
case cap_endpoint_cap:
return EP_PTR(cap_endpoint_cap_get_capEPPtr(cap));
case cap_async_endpoint_cap:
return AEP_PTR(cap_async_endpoint_cap_get_capAEPPtr(cap));
case cap_cnode_cap:
return CTE_PTR(cap_cnode_cap_get_capCNodePtr(cap));
case cap_thread_cap:
return TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), 0);
case cap_small_frame_cap:
case cap_frame_cap:
@ -412,14 +311,6 @@ cap_get_capPtr(cap_t cap)
case cap_asid_pool_cap:
return ASID_POOL_PTR(cap_asid_pool_cap_get_capASIDPool(cap));
case cap_zombie_cap:
return CTE_PTR(cap_zombie_cap_get_capZombiePtr(cap));
case cap_null_cap:
case cap_domain_cap:
case cap_reply_cap:
case cap_irq_control_cap:
case cap_irq_handler_cap:
case cap_asid_control_cap:
return NULL;
@ -429,12 +320,6 @@ cap_get_capPtr(cap_t cap)
}
}
static inline word_t CONST
isArchCap(cap_t cap)
{
return (cap_get_capType(cap) % 2);
}
/* We need to supply different type getters for the bitfield generated PTE type
* because there is an implicit third type that PTEs can be. If the type bit is
* set but the reserved bit is not set, the type of the PTE is invalid, not a

View file

@ -98,8 +98,8 @@ fastpath_mi_check(word_t msgInfo)
static inline bool_t hasDefaultSelectors(tcb_t *thread)
{
return thread->tcbContext.registers[DS] == SEL_DS_3 &&
thread->tcbContext.registers[ES] == SEL_DS_3;
return thread->tcbArch.tcbContext.registers[DS] == SEL_DS_3 &&
thread->tcbArch.tcbContext.registers[ES] == SEL_DS_3;
}
static inline void FASTCALL NORETURN
@ -116,7 +116,7 @@ fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread)
* is currently disabled */
}
tss_ptr_set_esp0(&ia32KStss, ((uint32_t)cur_thread) + 0x4c);
cur_thread->tcbContext.registers[EFLAGS] &= ~0x200;
cur_thread->tcbArch.tcbContext.registers[EFLAGS] &= ~0x200;
if (likely(hasDefaultSelectors(cur_thread))) {
asm volatile("\
movl %%ecx, %%esp \n\
@ -134,8 +134,8 @@ fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread)
sysexit \n\
"
:
: "c"(&cur_thread->tcbContext.registers[EDI]),
"a" (cur_thread->tcbContext.registers[EAX]),
: "c"(&cur_thread->tcbArch.tcbContext.registers[EDI]),
"a" (cur_thread->tcbArch.tcbContext.registers[EAX]),
"b" (badge),
"S" (msgInfo)
: "memory"
@ -158,8 +158,8 @@ fastpath_restore(word_t badge, word_t msgInfo, tcb_t *cur_thread)
sysexit \n\
"
:
: "c"(&cur_thread->tcbContext.registers[EDI]),
"a" (cur_thread->tcbContext.registers[EAX]),
: "c"(&cur_thread->tcbArch.tcbContext.registers[EDI]),
"a" (cur_thread->tcbArch.tcbContext.registers[EAX]),
"b" (badge),
"S" (msgInfo)
: "memory"

View file

@ -21,73 +21,14 @@
#include <arch/machine/registerset.h>
/* Object sizes*/
#define EP_SIZE_BITS 4
#define AEP_SIZE_BITS 4
#define CTE_SIZE_BITS 4
#define TCB_BLOCK_SIZE_BITS 10
/* Ensure object sizes are sane */
compile_assert(cte_size_sane, sizeof(cte_t) <= (1 << CTE_SIZE_BITS))
compile_assert(ep_size_sane, sizeof(endpoint_t) <= (1 << EP_SIZE_BITS))
compile_assert(aep_size_sane, sizeof(async_endpoint_t) <= (1 << AEP_SIZE_BITS))
/* TCB CNode: size = 256 bytes */
/* typedef cte_t[16] tcb_cnode; */
typedef struct arch_tcb {
user_context_t tcbContext;
} arch_tcb_t;
/* update this when you modify the tcb struct */
#define EXPECTED_TCB_SIZE 660
/* TCB: alignment = 1024 bytes */
struct tcb {
/* Saved user-level context of thread, 592 bytes */
user_context_t tcbContext;
/* Thread state, 12 bytes */
thread_state_t tcbState;
/* Async endpoint that this TCB is bound to. If this is set, when this tcb waits
* on any sync endpoint, it may receive an async notification from the AEP */
async_endpoint_t *boundAsyncEndpoint;
/* Current fault, 8 bytes */
fault_t tcbFault;
/* Current lookup failure, 8 bytes */
lookup_fault_t tcbLookupFailure;
/* Domain, 1 byte (packed to 4) */
uint32_t tcbDomain;
/* Priority, 1 byte (packed to 4) */
uint32_t tcbPriority;
/* Timeslice remaining, 4 bytes */
word_t tcbTimeSlice;
/* Capability pointer to thread fault handler, 4 bytes */
cptr_t tcbFaultHandler;
/* userland virtual address of thread IPC buffer, 4 bytes */
word_t tcbIPCBuffer;
/* Previous and next pointers for endpoint & scheduler queues, 16 bytes */
struct tcb* tcbSchedNext;
struct tcb* tcbSchedPrev;
struct tcb* tcbEPNext;
struct tcb* tcbEPPrev;
#ifdef DEBUG
/* Use any remaining space for a thread name */
char tcbName[];
#endif
};
typedef struct tcb tcb_t;
/* Ensure TCB size is what we expected */
compile_assert(tcb_size_expected, sizeof(tcb_t) == EXPECTED_TCB_SIZE)
/* IA32-specific object types */
#define GDT_NULL 0
#define GDT_CS_0 1
#define GDT_DS_0 2
@ -250,29 +191,13 @@ cap_get_capMappedASID(cap_t cap)
}
static inline unsigned int CONST
cap_get_capSizeBits(cap_t cap)
cap_get_archCapSizeBits(cap_t cap)
{
cap_tag_t ctag;
uint32_t type;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return cap_untyped_cap_get_capBlockSize(cap);
case cap_endpoint_cap:
return EP_SIZE_BITS;
case cap_async_endpoint_cap:
return AEP_SIZE_BITS;
case cap_cnode_cap:
return cap_cnode_cap_get_capCNodeRadix(cap) + CTE_SIZE_BITS;
case cap_thread_cap:
return TCB_BLOCK_SIZE_BITS;
case cap_frame_cap:
return pageBitsForSize(cap_frame_cap_get_capFSize(cap));
@ -282,28 +207,6 @@ cap_get_capSizeBits(cap_t cap)
case cap_page_directory_cap:
return PD_SIZE_BITS;
case cap_zombie_cap:
type = cap_zombie_cap_get_capZombieType(cap);
if (type == ZombieType_ZombieTCB) {
return TCB_BLOCK_SIZE_BITS;
}
return ZombieType_ZombieCNode(type) + CTE_SIZE_BITS;
case cap_null_cap:
return 0;
case cap_domain_cap:
return 0;
case cap_reply_cap:
return 0;
case cap_irq_control_cap:
return 0;
case cap_irq_handler_cap:
return 0;
case cap_io_port_cap:
return 0;
#ifdef CONFIG_IOMMU
@ -325,27 +228,13 @@ cap_get_capSizeBits(cap_t cap)
}
static inline void * CONST
cap_get_capPtr(cap_t cap)
cap_get_archCapPtr(cap_t cap)
{
cap_tag_t ctag;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return WORD_PTR(cap_untyped_cap_get_capPtr(cap));
case cap_endpoint_cap:
return EP_PTR(cap_endpoint_cap_get_capEPPtr(cap));
case cap_async_endpoint_cap:
return AEP_PTR(cap_async_endpoint_cap_get_capAEPPtr(cap));
case cap_cnode_cap:
return CTE_PTR(cap_cnode_cap_get_capCNodePtr(cap));
case cap_thread_cap:
return TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), 0);
case cap_frame_cap:
return (void *)(cap_frame_cap_get_capFBasePtr(cap));
@ -359,24 +248,6 @@ cap_get_capPtr(cap_t cap)
case cap_pdpt_cap:
return PDPT_PTR(cap_pdpt_cap_get_capPDPTBasePtr(cap));
case cap_zombie_cap:
return CTE_PTR(cap_zombie_cap_get_capZombiePtr(cap));
case cap_null_cap:
return NULL;
case cap_domain_cap:
return NULL;
case cap_reply_cap:
return NULL;
case cap_irq_control_cap:
return NULL;
case cap_irq_handler_cap:
return NULL;
case cap_io_port_cap:
return NULL;
#ifdef CONFIG_IOMMU
@ -397,10 +268,4 @@ cap_get_capPtr(cap_t cap)
}
}
static inline word_t CONST
isArchCap(cap_t cap)
{
return (cap_get_capType(cap) % 2);
}
#endif

View file

@ -18,13 +18,13 @@
static inline void
setRegister(tcb_t *thread, register_t reg, word_t w)
{
thread->tcbContext.registers[reg] = w;
thread->tcbArch.tcbContext.registers[reg] = w;
}
static inline word_t PURE
getRegister(tcb_t *thread, register_t reg)
{
return thread->tcbContext.registers[reg];
return thread->tcbArch.tcbContext.registers[reg];
}
#endif

View file

@ -36,6 +36,8 @@ enum endpoint_state {
};
typedef uint32_t endpoint_state_t;
#define EP_SIZE_BITS 4
enum async_endpoint_state {
AEPState_Idle = 0,
AEPState_Waiting = 1,
@ -43,16 +45,14 @@ enum async_endpoint_state {
};
typedef uint32_t async_endpoint_state_t;
/* Declare object casts. As the sizes of objects may
* differ by architecture, they are declared in the
* arch structures.h
*/
#define EP_PTR(r) ((endpoint_t *)(r))
#define EP_REF(p) ((unsigned int)(p))
#define AEP_SIZE_BITS 4
#define AEP_PTR(r) ((async_endpoint_t *)(r))
#define AEP_REF(p) ((unsigned int)(p))
#define CTE_SIZE_BITS 4
#define CTE_PTR(r) ((cte_t *)(r))
#define CTE_REF(p) ((unsigned int)(p))
@ -193,11 +193,165 @@ vmAttributesFromWord(word_t w)
return attr;
}
/* TCB: size 64 bytes + sizeof(arch_tcb_t) (aligned to nearest power of 2) */
struct tcb {
/* arch specific tcb state (including context)*/
arch_tcb_t tcbArch;
/* Thread state, 12 bytes */
thread_state_t tcbState;
/* Async endpoint that this TCB is bound to. If this is set, when this TCB waits on
* any sync endpoint, it may receive an async notification from the AEP.
* 4 bytes*/
async_endpoint_t *boundAsyncEndpoint;
/* Current fault, 8 bytes */
fault_t tcbFault;
/* Current lookup failure, 8 bytes */
lookup_fault_t tcbLookupFailure;
/* Domain, 1 byte (packed to 4) */
uint32_t tcbDomain;
/* Priority, 1 byte (packed to 4) */
uint32_t tcbPriority;
/* Timeslice remaining, 4 bytes */
word_t tcbTimeSlice;
/* Capability pointer to thread fault handler, 4 bytes */
cptr_t tcbFaultHandler;
/* userland virtual address of thread IPC buffer, 4 bytes */
word_t tcbIPCBuffer;
/* Previous and next pointers for endpoint & scheduler queues, 16 bytes */
struct tcb* tcbSchedNext;
struct tcb* tcbSchedPrev;
struct tcb* tcbEPNext;
struct tcb* tcbEPPrev;
#ifdef DEBUG
/* Use any remaining space for a thread name */
char tcbName[];
#endif
};
typedef struct tcb tcb_t;
/* Ensure object sizes are sane */
compile_assert(cte_size_sane, sizeof(cte_t) <= (1 << CTE_SIZE_BITS))
compile_assert(tcb_size_expected, sizeof(tcb_t) == EXPECTED_TCB_SIZE)
compile_assert(tcb_size_sane,
(1 << TCB_SIZE_BITS) + sizeof(tcb_t) <= (1 << TCB_BLOCK_SIZE_BITS))
compile_assert(ep_size_sane, sizeof(endpoint_t) <= (1 << EP_SIZE_BITS))
compile_assert(aep_size_sane, sizeof(async_endpoint_t) <= (1 << AEP_SIZE_BITS))
/* helper functions */
static inline word_t CONST
isArchCap(cap_t cap)
{
return (cap_get_capType(cap) % 2);
}
static inline unsigned int CONST
cap_get_capSizeBits(cap_t cap)
{
cap_tag_t ctag;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return cap_untyped_cap_get_capBlockSize(cap);
case cap_endpoint_cap:
return EP_SIZE_BITS;
case cap_async_endpoint_cap:
return AEP_SIZE_BITS;
case cap_cnode_cap:
return cap_cnode_cap_get_capCNodeRadix(cap) + CTE_SIZE_BITS;
case cap_thread_cap:
return TCB_BLOCK_SIZE_BITS;
case cap_zombie_cap: {
uint32_t type = cap_zombie_cap_get_capZombieType(cap);
if (type == ZombieType_ZombieTCB) {
return TCB_BLOCK_SIZE_BITS;
}
return ZombieType_ZombieCNode(type) + CTE_SIZE_BITS;
}
case cap_null_cap:
return 0;
case cap_domain_cap:
return 0;
case cap_reply_cap:
return 0;
case cap_irq_control_cap:
return 0;
case cap_irq_handler_cap:
return 0;
default:
return cap_get_archCapSizeBits(cap);
}
}
static inline void * CONST
cap_get_capPtr(cap_t cap)
{
cap_tag_t ctag;
ctag = cap_get_capType(cap);
switch (ctag) {
case cap_untyped_cap:
return WORD_PTR(cap_untyped_cap_get_capPtr(cap));
case cap_endpoint_cap:
return EP_PTR(cap_endpoint_cap_get_capEPPtr(cap));
case cap_async_endpoint_cap:
return AEP_PTR(cap_async_endpoint_cap_get_capAEPPtr(cap));
case cap_cnode_cap:
return CTE_PTR(cap_cnode_cap_get_capCNodePtr(cap));
case cap_thread_cap:
return TCB_PTR_CTE_PTR(cap_thread_cap_get_capTCBPtr(cap), 0);
case cap_zombie_cap:
return CTE_PTR(cap_zombie_cap_get_capZombiePtr(cap));
case cap_domain_cap:
return NULL;
case cap_reply_cap:
return NULL;
case cap_irq_control_cap:
return NULL;
case cap_irq_handler_cap:
return NULL;
default:
return cap_get_archCapPtr(cap);
}
}
#endif

View file

@ -68,14 +68,14 @@ software_breakpoint(uint32_t va, user_context_t *context)
printf("ksCurThread context:\n");
for (i = 0; i < 10; i++) {
printf("r%d %x\n", i,
(unsigned int)ksCurThread->tcbContext.registers[i]);
(unsigned int)ksCurThread->tcbArch.tcbContext.registers[i]);
}
for (i = 10; i < 15; i++) {
printf("r%d %x\n", i,
(unsigned int)ksCurThread->tcbContext.registers[i]);
(unsigned int)ksCurThread->tcbArch.tcbContext.registers[i]);
}
printf("LR_abt %x\n", (unsigned int)ksCurThread->tcbContext.registers[15]);
printf("CPSR %x\n", (unsigned int)ksCurThread->tcbContext.registers[16]);
printf("LR_abt %x\n", (unsigned int)ksCurThread->tcbArch.tcbContext.registers[15]);
printf("CPSR %x\n", (unsigned int)ksCurThread->tcbArch.tcbContext.registers[16]);
}
void

View file

@ -32,8 +32,8 @@ void __attribute__((noreturn)) __attribute__((externally_visible)) restore_user_
* is currently disabled */
}
/* see if we entered via syscall */
if (likely(ksCurThread->tcbContext.registers[Error] == -1)) {
ksCurThread->tcbContext.registers[EFLAGS] &= ~0x200;
if (likely(ksCurThread->tcbArch.tcbContext.registers[Error] == -1)) {
ksCurThread->tcbArch.tcbContext.registers[EFLAGS] &= ~0x200;
asm volatile(
// Set our stack pointer to the top of the tcb so we can efficiently pop
"movl %0, %%esp\n"
@ -80,7 +80,7 @@ void __attribute__((noreturn)) __attribute__((externally_visible)) restore_user_
"sti\n"
"sysexit\n"
:
: "r"(&ksCurThread->tcbContext.registers[EAX])
: "r"(&ksCurThread->tcbArch.tcbContext.registers[EAX])
// Clobber memory so the compiler is forced to complete all stores
// before running this assembler
: "memory"
@ -104,7 +104,7 @@ void __attribute__((noreturn)) __attribute__((externally_visible)) restore_user_
"addl $12, %%esp\n"
"iret\n"
:
: "r"(&ksCurThread->tcbContext.registers[EAX])
: "r"(&ksCurThread->tcbArch.tcbContext.registers[EAX])
// Clobber memory so the compiler is forced to complete all stores
// before running this assembler
: "memory"
@ -120,9 +120,9 @@ void __attribute__((fastcall)) __attribute__((externally_visible)) c_handle_inte
handleUnimplementedDevice();
} else if (irq == int_page_fault) {
/* Error code is in Error. Pull out bit 5, which is whether it was instruction or data */
handleVMFaultEvent((ksCurThread->tcbContext.registers[Error] >> 4) & 1);
handleVMFaultEvent((ksCurThread->tcbArch.tcbContext.registers[Error] >> 4) & 1);
} else if (irq < int_irq_min) {
handleUserLevelFault(irq, ksCurThread->tcbContext.registers[Error]);
handleUserLevelFault(irq, ksCurThread->tcbArch.tcbContext.registers[Error]);
} else if (likely(irq < int_trap_min)) {
ia32KScurInterrupt = irq;
handleInterruptEntry();
@ -133,7 +133,7 @@ void __attribute__((fastcall)) __attribute__((externally_visible)) c_handle_inte
/* Adjust FaultEIP to point to trapping INT
* instruction by subtracting 2 */
int sys_num;
ksCurThread->tcbContext.registers[FaultEIP] -= 2;
ksCurThread->tcbArch.tcbContext.registers[FaultEIP] -= 2;
/* trap number is MSBs of the syscall number and the LSBS of EAX */
sys_num = (irq << 24) | (syscall & 0x00ffffff);
handleUnknownSyscall(sys_num);
@ -146,7 +146,7 @@ slowpath(syscall_t syscall)
{
ia32KScurInterrupt = -1;
/* increment nextEIP to skip sysenter */
ksCurThread->tcbContext.registers[NextEIP] += 2;
ksCurThread->tcbArch.tcbContext.registers[NextEIP] += 2;
/* check for undefined syscall */
if (unlikely(syscall < SYSCALL_MIN || syscall > SYSCALL_MAX)) {
handleUnknownSyscall(syscall);

View file

@ -33,10 +33,10 @@ switchFpuOwner(tcb_t *new_owner)
{
enableFpu();
if (ia32KSfpuOwner) {
saveFpuState(&ia32KSfpuOwner->tcbContext.fpuState);
saveFpuState(&ia32KSfpuOwner->tcbArch.tcbContext.fpuState);
}
if (new_owner) {
loadFpuState(&new_owner->tcbContext.fpuState);
loadFpuState(&new_owner->tcbArch.tcbContext.fpuState);
} else {
disableFpu();
}

View file

@ -381,7 +381,7 @@ create_initial_thread(
memzero((void*)pptr, 1 << TCB_BLOCK_SIZE_BITS);
tcb = TCB_PTR(pptr + TCB_OFFSET);
tcb->tcbTimeSlice = CONFIG_TIME_SLICE;
Arch_initContext(&tcb->tcbContext);
Arch_initContext(&tcb->tcbArch.tcbContext);
/* derive a copy of the IPC buffer cap for inserting */
dc_ret = deriveCap(SLOT_PTR(pptr_of_cap(root_cnode_cap), BI_CAP_IT_IPCBUF), ipcbuf_cap);

View file

@ -244,7 +244,7 @@ recycleCap(bool_t is_final, cap_t cap)
* here by zeroing the TCB part of the structure, while leaving
* the CNode alone. */
memzero(tcb, sizeof (tcb_t));
Arch_initContext(&tcb->tcbContext);
Arch_initContext(&tcb->tcbArch.tcbContext);
tcb->tcbTimeSlice = CONFIG_TIME_SLICE;
tcb->tcbDomain = ksCurDomain;
@ -515,7 +515,7 @@ createObject(object_t t, void *regionBase, word_t userSize)
/* Setup non-zero parts of the TCB. */
Arch_initContext(&tcb->tcbContext);
Arch_initContext(&tcb->tcbArch.tcbContext);
tcb->tcbTimeSlice = CONFIG_TIME_SLICE;
tcb->tcbDomain = ksCurDomain;