refactor tcb_t to remove duplication between x86 and arm header files
This commit is contained in:
parent
5d64d156f4
commit
88d73db06c
10 changed files with 195 additions and 291 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue