trivial: style and comment
Signed-off-by: Oliver Scott <Oliver.Scott@data61.csiro.au>
This commit is contained in:
parent
935714a4cb
commit
c66d9cee7a
12 changed files with 855 additions and 827 deletions
|
|
@ -125,8 +125,10 @@ unset(CONFIGURE_CLK_SHIFT CACHE)
|
||||||
unset(CONFIGURE_CLK_MAGIC CACHE)
|
unset(CONFIGURE_CLK_MAGIC CACHE)
|
||||||
unset(CONFIGURE_KERNEL_WCET CACHE)
|
unset(CONFIGURE_KERNEL_WCET CACHE)
|
||||||
unset(CONFIGURE_TIMER_PRECISION CACHE)
|
unset(CONFIGURE_TIMER_PRECISION CACHE)
|
||||||
|
# CONFIGURE_MAX_CB and CONFIGURE_MAX_SID are related to the kernel SMMU on Arm.
|
||||||
unset(CONFIGURE_MAX_SID CACHE)
|
unset(CONFIGURE_MAX_SID CACHE)
|
||||||
unset(CONFIGURE_MAX_CB CACHE)
|
unset(CONFIGURE_MAX_CB CACHE)
|
||||||
|
|
||||||
# CLK_SHIFT and CLK_MAGIC are generated from tools/reciprocal.py
|
# CLK_SHIFT and CLK_MAGIC are generated from tools/reciprocal.py
|
||||||
# based on the TIMER_CLK_HZ to simulate division.
|
# based on the TIMER_CLK_HZ to simulate division.
|
||||||
# This could be moved to a cmake function
|
# This could be moved to a cmake function
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
#define SMMU_SID_CNODE_SLOT_BITS 8
|
#define SMMU_SID_CNODE_SLOT_BITS 8
|
||||||
#define SMMU_CB_CNODE_SLOT_BITS 6
|
#define SMMU_CB_CNODE_SLOT_BITS 6
|
||||||
#define SID_INVALID SMMU_MAX_SID
|
#define SID_INVALID SMMU_MAX_SID
|
||||||
#define CB_INVALID SMMU_MAX_CB
|
#define CB_INVALID SMMU_MAX_CB
|
||||||
#define ASID_INVALID nASIDs
|
#define ASID_INVALID nASIDs
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -30,7 +30,7 @@ exception_t decodeARMCBInvocation(word_t label, unsigned int length, cptr_t cptr
|
||||||
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
||||||
bool_t call, word_t *buffer);
|
bool_t call, word_t *buffer);
|
||||||
exception_t smmu_delete_cb(cap_t cap);
|
exception_t smmu_delete_cb(cap_t cap);
|
||||||
exception_t smmu_delete_sid(cap_t cap);
|
exception_t smmu_delete_sid(cap_t cap);
|
||||||
void smmu_cb_delete_vspace(word_t cb, asid_t asid);
|
void smmu_cb_delete_vspace(word_t cb, asid_t asid);
|
||||||
void invalidateSMMUTLBByASID(asid_t asid, word_t bind_cb);
|
void invalidateSMMUTLBByASID(asid_t asid, word_t bind_cb);
|
||||||
void invalidateSMMUTLBByASIDVA(asid_t asid, vptr_t vaddr, word_t bind_cb);
|
void invalidateSMMUTLBByASIDVA(asid_t asid, vptr_t vaddr, word_t bind_cb);
|
||||||
|
|
|
||||||
|
|
@ -285,9 +285,9 @@
|
||||||
#define CBn_FSR_TF BIT(1)
|
#define CBn_FSR_TF BIT(1)
|
||||||
|
|
||||||
#define CBn_FSR_CLEAR_ALL (CBn_FSR_MULTI | CBn_FSR_SS | \
|
#define CBn_FSR_CLEAR_ALL (CBn_FSR_MULTI | CBn_FSR_SS | \
|
||||||
CBn_FSR_UUT | CBn_FSR_ASF | CBn_FSR_TLBLKF | \
|
CBn_FSR_UUT | CBn_FSR_ASF | CBn_FSR_TLBLKF | \
|
||||||
CBn_FSR_TLBLMCF | CBn_FSR_EF | CBn_FSR_PF | \
|
CBn_FSR_TLBLMCF | CBn_FSR_EF | CBn_FSR_PF | \
|
||||||
CBn_FSR_AFF | CBn_FSR_TF)
|
CBn_FSR_AFF | CBn_FSR_TF)
|
||||||
|
|
||||||
/*SMMU_CBn_ACTLR defined in SMMU500*/
|
/*SMMU_CBn_ACTLR defined in SMMU500*/
|
||||||
#define CBn_ACTLR_CPRE BIT(1)
|
#define CBn_ACTLR_CPRE BIT(1)
|
||||||
|
|
@ -344,7 +344,7 @@
|
||||||
#define CBn_TCR_TG_64K 1
|
#define CBn_TCR_TG_64K 1
|
||||||
#define CBn_TCR_TG_16K 2
|
#define CBn_TCR_TG_16K 2
|
||||||
|
|
||||||
#define CBn_TCR_SH_NONE 0
|
#define CBn_TCR_SH_NONE 0
|
||||||
#define CBn_TCR_SH_OUTER 2
|
#define CBn_TCR_SH_OUTER 2
|
||||||
#define CBn_TCR_SH_INNER 3
|
#define CBn_TCR_SH_INNER 3
|
||||||
|
|
||||||
|
|
@ -404,7 +404,7 @@ this is the same as the MAIR in core*/
|
||||||
/*8 bit per attribute*/
|
/*8 bit per attribute*/
|
||||||
#define CBn_MAIRm_ATTR_SHIFT(n) ((n) << 3)
|
#define CBn_MAIRm_ATTR_SHIFT(n) ((n) << 3)
|
||||||
|
|
||||||
/*SMMU_CBn_SCTLR*/
|
/*SMMU_CBn_SCTLR*/
|
||||||
#define CBn_SCTLR_CFIE (1 << 6)
|
#define CBn_SCTLR_CFIE (1 << 6)
|
||||||
#define CBn_SCTLR_CFRE (1 << 5)
|
#define CBn_SCTLR_CFRE (1 << 5)
|
||||||
#define CBn_SCTLR_AFE (1 << 2)
|
#define CBn_SCTLR_AFE (1 << 2)
|
||||||
|
|
@ -423,14 +423,14 @@ this is the same as the MAIR in core*/
|
||||||
/*SMMU_CBn_TLBIIPAS2*/
|
/*SMMU_CBn_TLBIIPAS2*/
|
||||||
#define CBn_TLBIIPAS2_SET(vaddr) ((vaddr) >> 12 & 0xfffffffff)
|
#define CBn_TLBIIPAS2_SET(vaddr) ((vaddr) >> 12 & 0xfffffffff)
|
||||||
|
|
||||||
void smmu_cb_assign_vspace(word_t cb, vspace_root_t *vspace, asid_t asid);
|
void smmu_cb_assign_vspace(word_t cb, vspace_root_t *vspace, asid_t asid);
|
||||||
void smmu_sid_bind_cb(word_t sid, word_t cb);
|
void smmu_sid_bind_cb(word_t sid, word_t cb);
|
||||||
void plat_smmu_init(void);
|
void plat_smmu_init(void);
|
||||||
void smmu_tlb_invalidate_all(void);
|
void smmu_tlb_invalidate_all(void);
|
||||||
void smmu_tlb_invalidate_cb(int cb, asid_t asid);
|
void smmu_tlb_invalidate_cb(int cb, asid_t asid);
|
||||||
void smmu_tlb_invalidate_cb_va(int cb, asid_t asid, vptr_t vaddr);
|
void smmu_tlb_invalidate_cb_va(int cb, asid_t asid, vptr_t vaddr);
|
||||||
void smmu_cb_disable(word_t cb, asid_t asid);
|
void smmu_cb_disable(word_t cb, asid_t asid);
|
||||||
void smmu_sid_unbind(word_t sid);
|
void smmu_sid_unbind(word_t sid);
|
||||||
void smmu_read_fault_state(uint32_t *status, uint32_t *syndrome_0, uint32_t *syndrome_1);
|
void smmu_read_fault_state(uint32_t *status, uint32_t *syndrome_0, uint32_t *syndrome_1);
|
||||||
void smmu_clear_fault_state(void);
|
void smmu_clear_fault_state(void);
|
||||||
void smmu_cb_read_fault_state(int cb, uint32_t *status, word_t *address);
|
void smmu_cb_read_fault_state(int cb, uint32_t *status, word_t *address);
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,12 @@ enum {
|
||||||
seL4_CapInitThreadIPCBuffer = 10, /* initial thread's IPC buffer frame cap */
|
seL4_CapInitThreadIPCBuffer = 10, /* initial thread's IPC buffer frame cap */
|
||||||
seL4_CapDomain = 11, /* global domain controller cap */
|
seL4_CapDomain = 11, /* global domain controller cap */
|
||||||
seL4_CapSMMUSIDControl = 12, /*global SMMU SID controller cap, null cap if not supported*/
|
seL4_CapSMMUSIDControl = 12, /*global SMMU SID controller cap, null cap if not supported*/
|
||||||
seL4_CapSMMUCBControl = 13, /*global SMMU CB controller cap, null cap if not supported*/
|
seL4_CapSMMUCBControl = 13, /*global SMMU CB controller cap, null cap if not supported*/
|
||||||
#ifdef CONFIG_KERNEL_MCS
|
#ifdef CONFIG_KERNEL_MCS
|
||||||
seL4_CapInitThreadSC = 14, /* initial thread's scheduling context cap */
|
seL4_CapInitThreadSC = 14, /* initial thread's scheduling context cap */
|
||||||
seL4_NumInitialCaps = 15
|
seL4_NumInitialCaps = 15
|
||||||
#else
|
#else
|
||||||
seL4_NumInitialCaps = 14
|
seL4_NumInitialCaps = 14
|
||||||
#endif /* !CONFIG_KERNEL_MCS */
|
#endif /* !CONFIG_KERNEL_MCS */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1218,8 +1218,9 @@ static inline void invalidateTLBByASID(asid_t asid)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
vspace_root_t bind_cb = getASIDBindCB(asid);
|
vspace_root_t bind_cb = getASIDBindCB(asid);
|
||||||
if (unlikely(vtable_invalid_get_bind_cb(bind_cb)))
|
if (unlikely(vtable_invalid_get_bind_cb(bind_cb))) {
|
||||||
invalidateSMMUTLBByASID(asid, vtable_invalid_get_bind_cb(bind_cb));
|
invalidateSMMUTLBByASID(asid, vtable_invalid_get_bind_cb(bind_cb));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||||
vspace_root_t stored_hw_asid;
|
vspace_root_t stored_hw_asid;
|
||||||
|
|
@ -1238,8 +1239,9 @@ static inline void invalidateTLBByASIDVA(asid_t asid, vptr_t vaddr)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
vspace_root_t bind_cb = getASIDBindCB(asid);
|
vspace_root_t bind_cb = getASIDBindCB(asid);
|
||||||
if (unlikely(vtable_invalid_get_bind_cb(bind_cb)))
|
if (unlikely(vtable_invalid_get_bind_cb(bind_cb))) {
|
||||||
invalidateSMMUTLBByASIDVA(asid, vaddr, vtable_invalid_get_bind_cb(bind_cb));
|
invalidateSMMUTLBByASIDVA(asid, vaddr, vtable_invalid_get_bind_cb(bind_cb));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
|
||||||
vspace_root_t stored_hw_asid;
|
vspace_root_t stored_hw_asid;
|
||||||
|
|
|
||||||
|
|
@ -216,10 +216,10 @@ finaliseCap_ret_t Arch_finaliseCap(cap_t cap, bool_t final)
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
case cap_cb_cap:
|
case cap_cb_cap:
|
||||||
if (cap_cb_cap_get_capBindSID(cap) != SID_INVALID) {
|
if (cap_cb_cap_get_capBindSID(cap) != SID_INVALID) {
|
||||||
smmu_sid_unbind(cap_cb_cap_get_capBindSID(cap));
|
smmu_sid_unbind(cap_cb_cap_get_capBindSID(cap));
|
||||||
}
|
}
|
||||||
if (final) {
|
if (final) {
|
||||||
smmu_delete_cb(cap);
|
smmu_delete_cb(cap);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case cap_sid_cap:
|
case cap_sid_cap:
|
||||||
|
|
@ -227,7 +227,7 @@ finaliseCap_ret_t Arch_finaliseCap(cap_t cap, bool_t final)
|
||||||
smmu_delete_sid(cap);
|
smmu_delete_sid(cap);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
fc_ret.remainder = cap_null_cap_new();
|
fc_ret.remainder = cap_null_cap_new();
|
||||||
|
|
@ -309,17 +309,17 @@ bool_t CONST Arch_sameRegionAs(cap_t cap_a, cap_t cap_b)
|
||||||
cap_get_capType(cap_b) == cap_cb_cap) {
|
cap_get_capType(cap_b) == cap_cb_cap) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case cap_sid_cap:
|
case cap_sid_cap:
|
||||||
if (cap_get_capType(cap_b) == cap_sid_cap) {
|
if (cap_get_capType(cap_b) == cap_sid_cap) {
|
||||||
return cap_sid_cap_get_capSID(cap_a) ==
|
return cap_sid_cap_get_capSID(cap_a) ==
|
||||||
cap_sid_cap_get_capSID(cap_b);
|
cap_sid_cap_get_capSID(cap_b);
|
||||||
}
|
}
|
||||||
case cap_cb_cap:
|
case cap_cb_cap:
|
||||||
if (cap_get_capType(cap_b) == cap_cb_cap) {
|
if (cap_get_capType(cap_b) == cap_cb_cap) {
|
||||||
return cap_cb_cap_get_capCB(cap_a) ==
|
return cap_cb_cap_get_capCB(cap_a) ==
|
||||||
cap_cb_cap_get_capCB(cap_b);
|
cap_cb_cap_get_capCB(cap_b);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -412,22 +412,22 @@ cap_t Arch_createObject(object_t t, void *regionBase, word_t userSize, bool_t de
|
||||||
);
|
);
|
||||||
#ifndef AARCH64_VSPACE_S2_START_L1
|
#ifndef AARCH64_VSPACE_S2_START_L1
|
||||||
case seL4_ARM_PageGlobalDirectoryObject:
|
case seL4_ARM_PageGlobalDirectoryObject:
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
|
|
||||||
return cap_page_global_directory_cap_new(
|
return cap_page_global_directory_cap_new(
|
||||||
asidInvalid, /* capPGDMappedASID */
|
asidInvalid, /* capPGDMappedASID */
|
||||||
(word_t)regionBase, /* capPGDBasePtr */
|
(word_t)regionBase, /* capPGDBasePtr */
|
||||||
0, /* capPGDIsMapped */
|
0, /* capPGDIsMapped */
|
||||||
CB_INVALID /* capPGDMappedCB */
|
CB_INVALID /* capPGDMappedCB */
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return cap_page_global_directory_cap_new(
|
return cap_page_global_directory_cap_new(
|
||||||
asidInvalid, /* capPGDMappedASID */
|
asidInvalid, /* capPGDMappedASID */
|
||||||
(word_t)regionBase, /* capPGDBasePtr */
|
(word_t)regionBase, /* capPGDBasePtr */
|
||||||
0 /* capPGDIsMapped */
|
0 /* capPGDIsMapped */
|
||||||
);
|
);
|
||||||
#endif /*!CONFIG_ARM_SMMU*/
|
#endif /*!CONFIG_ARM_SMMU*/
|
||||||
#endif /*!AARCH64_VSPACE_S2_START_L1*/
|
#endif /*!AARCH64_VSPACE_S2_START_L1*/
|
||||||
case seL4_ARM_PageUpperDirectoryObject:
|
case seL4_ARM_PageUpperDirectoryObject:
|
||||||
return cap_page_upper_directory_cap_new(
|
return cap_page_upper_directory_cap_new(
|
||||||
|
|
@ -482,13 +482,13 @@ exception_t Arch_decodeInvocation(word_t label, word_t length, cptr_t cptr,
|
||||||
#endif /* end of CONFIG_ARM_HYPERVISOR_SUPPORT */
|
#endif /* end of CONFIG_ARM_HYPERVISOR_SUPPORT */
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
case cap_sid_control_cap:
|
case cap_sid_control_cap:
|
||||||
return decodeARMSIDControlInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
return decodeARMSIDControlInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
||||||
case cap_sid_cap:
|
case cap_sid_cap:
|
||||||
return decodeARMSIDInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
return decodeARMSIDInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
||||||
case cap_cb_control_cap:
|
case cap_cb_control_cap:
|
||||||
return decodeARMCBControlInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
return decodeARMCBControlInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
||||||
case cap_cb_cap:
|
case cap_cb_cap:
|
||||||
return decodeARMCBInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
return decodeARMCBInvocation(label, length, cptr, slot, cap, extraCaps, call, buffer);
|
||||||
#endif /*CONFIG_ARM_SMMU*/
|
#endif /*CONFIG_ARM_SMMU*/
|
||||||
default:
|
default:
|
||||||
#else
|
#else
|
||||||
|
|
|
||||||
|
|
@ -113,11 +113,7 @@ config_option(
|
||||||
DEFAULT_DISABLED OFF
|
DEFAULT_DISABLED OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
config_option(
|
config_option(KernelArmSMMU ARM_SMMU "Enable SystemMMU" DEFAULT OFF DEPENDS "KernelPlatformTx2")
|
||||||
KernelArmSMMU ARM_SMMU "Enable SystemMMU"
|
|
||||||
DEFAULT OFF
|
|
||||||
DEPENDS "KernelPlatformTx2"
|
|
||||||
)
|
|
||||||
|
|
||||||
config_option(
|
config_option(
|
||||||
KernelTk1SMMU TK1_SMMU "Enable SystemMMU for the Tegra TK1 SoC"
|
KernelTk1SMMU TK1_SMMU "Enable SystemMMU for the Tegra TK1 SoC"
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,8 @@ BOOT_CODE static void init_irqs(cap_t root_cnode_cap)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
BOOT_CODE static void init_smmu (cap_t root_cnode_cap) {
|
BOOT_CODE static void init_smmu(cap_t root_cnode_cap)
|
||||||
|
{
|
||||||
plat_smmu_init();
|
plat_smmu_init();
|
||||||
/*provide the SID and CB control cap*/
|
/*provide the SID and CB control cap*/
|
||||||
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapSMMUSIDControl), cap_sid_control_cap_new());
|
write_slot(SLOT_PTR(pptr_of_cap(root_cnode_cap), seL4_CapSMMUSIDControl), cap_sid_control_cap_new());
|
||||||
|
|
|
||||||
|
|
@ -8,392 +8,396 @@
|
||||||
#ifdef CONFIG_ARM_SMMU
|
#ifdef CONFIG_ARM_SMMU
|
||||||
#include <arch/object/smmu.h>
|
#include <arch/object/smmu.h>
|
||||||
|
|
||||||
static exception_t checkARMCBVspace(cap_t cap)
|
static exception_t checkARMCBVspace(cap_t cap)
|
||||||
{
|
{
|
||||||
word_t cb = cap_cb_cap_get_capCB(cap);
|
word_t cb = cap_cb_cap_get_capCB(cap);
|
||||||
cte_t *cbSlot = smmuStateCBNode + cb;
|
cte_t *cbSlot = smmuStateCBNode + cb;
|
||||||
if (unlikely(!isVTableRoot(cbSlot->cap))) {
|
if (unlikely(!isVTableRoot(cbSlot->cap))) {
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_t decodeARMSIDControlInvocation(word_t label, unsigned int length, cptr_t cptr,
|
exception_t decodeARMSIDControlInvocation(word_t label, unsigned int length, cptr_t cptr,
|
||||||
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
||||||
bool_t call, word_t *buffer) {
|
bool_t call, word_t *buffer)
|
||||||
|
{
|
||||||
|
|
||||||
word_t index, depth, sid;
|
word_t index, depth, sid;
|
||||||
cte_t *destSlot;
|
cte_t *destSlot;
|
||||||
cap_t cnodeCap;
|
cap_t cnodeCap;
|
||||||
lookupSlot_ret_t lu_ret;
|
lookupSlot_ret_t lu_ret;
|
||||||
exception_t status;
|
exception_t status;
|
||||||
uint32_t faultStatus, faultSyndrome_0, faultSyndrome_1;
|
uint32_t faultStatus, faultSyndrome_0, faultSyndrome_1;
|
||||||
|
|
||||||
if (label == ARMSIDGetFault) {
|
if (label == ARMSIDGetFault) {
|
||||||
smmu_read_fault_state(&faultStatus, &faultSyndrome_0, &faultSyndrome_1);
|
smmu_read_fault_state(&faultStatus, &faultSyndrome_0, &faultSyndrome_1);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgRegisters[0], faultStatus);
|
setRegister(NODE_STATE(ksCurThread), msgRegisters[0], faultStatus);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgRegisters[1], faultSyndrome_0);
|
setRegister(NODE_STATE(ksCurThread), msgRegisters[1], faultSyndrome_0);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgRegisters[2], faultSyndrome_1);
|
setRegister(NODE_STATE(ksCurThread), msgRegisters[2], faultSyndrome_1);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgInfoRegister,
|
setRegister(NODE_STATE(ksCurThread), msgInfoRegister,
|
||||||
wordFromMessageInfo(seL4_MessageInfo_new(0, 0, 0, 3)));
|
wordFromMessageInfo(seL4_MessageInfo_new(0, 0, 0, 3)));
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label == ARMSIDClearFault) {
|
if (label == ARMSIDClearFault) {
|
||||||
smmu_clear_fault_state();
|
smmu_clear_fault_state();
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label != ARMSIDIssueSIDManager) {
|
if (label != ARMSIDIssueSIDManager) {
|
||||||
userError("SIDControl: Illegal operation.");
|
userError("SIDControl: Illegal operation.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
if (length < 3 || extraCaps.excaprefs[0] == NULL) {
|
if (length < 3 || extraCaps.excaprefs[0] == NULL) {
|
||||||
current_syscall_error.type = seL4_TruncatedMessage;
|
current_syscall_error.type = seL4_TruncatedMessage;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
sid = getSyscallArg(0, buffer);
|
sid = getSyscallArg(0, buffer);
|
||||||
index = getSyscallArg(1, buffer);
|
index = getSyscallArg(1, buffer);
|
||||||
depth = getSyscallArg(2, buffer);
|
depth = getSyscallArg(2, buffer);
|
||||||
cnodeCap = extraCaps.excaprefs[0]->cap;
|
cnodeCap = extraCaps.excaprefs[0]->cap;
|
||||||
|
|
||||||
if (sid >= SMMU_MAX_SID) {
|
if (sid >= SMMU_MAX_SID) {
|
||||||
current_syscall_error.type = seL4_RangeError;
|
current_syscall_error.type = seL4_RangeError;
|
||||||
current_syscall_error.rangeErrorMin = 0;
|
current_syscall_error.rangeErrorMin = 0;
|
||||||
current_syscall_error.rangeErrorMax = SMMU_MAX_SID - 1;
|
current_syscall_error.rangeErrorMax = SMMU_MAX_SID - 1;
|
||||||
userError("Rejecting request for SID %u. SID is greater than or equal to SMMU_MAX_SID.", (int)sid);
|
userError("Rejecting request for SID %u. SID is greater than or equal to SMMU_MAX_SID.", (int)sid);
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
if (smmuStateSIDTable[sid]) {
|
if (smmuStateSIDTable[sid]) {
|
||||||
current_syscall_error.type = seL4_RevokeFirst;
|
current_syscall_error.type = seL4_RevokeFirst;
|
||||||
userError("Rejecting request for SID %u. Already active.", (int)sid);
|
userError("Rejecting request for SID %u. Already active.", (int)sid);
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
lu_ret = lookupTargetSlot(cnodeCap, index, depth);
|
lu_ret = lookupTargetSlot(cnodeCap, index, depth);
|
||||||
if (lu_ret.status != EXCEPTION_NONE) {
|
if (lu_ret.status != EXCEPTION_NONE) {
|
||||||
userError("Target slot for new SID Handler cap invalid: cap %lu, SID %u.",
|
userError("Target slot for new SID Handler cap invalid: cap %lu, SID %u.",
|
||||||
getExtraCPtr(buffer, 0), (int)sid);
|
getExtraCPtr(buffer, 0), (int)sid);
|
||||||
return lu_ret.status;
|
return lu_ret.status;
|
||||||
}
|
}
|
||||||
destSlot = lu_ret.slot;
|
destSlot = lu_ret.slot;
|
||||||
status = ensureEmptySlot(destSlot);
|
status = ensureEmptySlot(destSlot);
|
||||||
if (status != EXCEPTION_NONE) {
|
if (status != EXCEPTION_NONE) {
|
||||||
userError("Target slot for new SID Handler cap not empty: cap %lu, SID %u.",
|
userError("Target slot for new SID Handler cap not empty: cap %lu, SID %u.",
|
||||||
getExtraCPtr(buffer, 0), (int)sid);
|
getExtraCPtr(buffer, 0), (int)sid);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
smmuStateSIDTable[sid] = true;
|
smmuStateSIDTable[sid] = true;
|
||||||
cteInsert(cap_sid_cap_new(sid), srcSlot, destSlot);
|
cteInsert(cap_sid_cap_new(sid), srcSlot, destSlot);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_t decodeARMSIDInvocation(word_t label, unsigned int length, cptr_t cptr,
|
exception_t decodeARMSIDInvocation(word_t label, unsigned int length, cptr_t cptr,
|
||||||
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
||||||
bool_t call, word_t *buffer) {
|
bool_t call, word_t *buffer)
|
||||||
cap_t cbCap;
|
{
|
||||||
cte_t *cbCapSlot;
|
cap_t cbCap;
|
||||||
cte_t *cbAssignSlot;
|
cte_t *cbCapSlot;
|
||||||
exception_t status;
|
cte_t *cbAssignSlot;
|
||||||
word_t sid;
|
exception_t status;
|
||||||
|
word_t sid;
|
||||||
|
|
||||||
switch (label) {
|
switch (label) {
|
||||||
case ARMSIDBindCB:
|
case ARMSIDBindCB:
|
||||||
if (unlikely(extraCaps.excaprefs[0] == NULL)) {
|
if (unlikely(extraCaps.excaprefs[0] == NULL)) {
|
||||||
userError("ARMSIDBindCB: Invalid CB cap.");
|
userError("ARMSIDBindCB: Invalid CB cap.");
|
||||||
current_syscall_error.type = seL4_TruncatedMessage;
|
current_syscall_error.type = seL4_TruncatedMessage;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
cbCapSlot = extraCaps.excaprefs[0];
|
cbCapSlot = extraCaps.excaprefs[0];
|
||||||
cbCap = cbCapSlot->cap;
|
cbCap = cbCapSlot->cap;
|
||||||
if (unlikely(cap_get_capType(cbCap) != cap_cb_cap)) {
|
if (unlikely(cap_get_capType(cbCap) != cap_cb_cap)) {
|
||||||
userError("ARMSIDBindCB: Invalid CB cap.");
|
userError("ARMSIDBindCB: Invalid CB cap.");
|
||||||
current_syscall_error.type = seL4_InvalidCapability;
|
current_syscall_error.type = seL4_InvalidCapability;
|
||||||
current_syscall_error.invalidCapNumber = 1;
|
current_syscall_error.invalidCapNumber = 1;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
if (unlikely(checkARMCBVspace(cbCap) != EXCEPTION_NONE)) {
|
if (unlikely(checkARMCBVspace(cbCap) != EXCEPTION_NONE)) {
|
||||||
userError("ARMSIDBindCB: Invalid CB cap.");
|
userError("ARMSIDBindCB: Invalid CB cap.");
|
||||||
current_syscall_error.type = seL4_InvalidCapability;
|
current_syscall_error.type = seL4_InvalidCapability;
|
||||||
current_syscall_error.invalidCapNumber = 1;
|
current_syscall_error.invalidCapNumber = 1;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
sid = cap_sid_cap_get_capSID(cap);
|
sid = cap_sid_cap_get_capSID(cap);
|
||||||
cbAssignSlot = smmuStateSIDNode + sid;
|
cbAssignSlot = smmuStateSIDNode + sid;
|
||||||
status = ensureEmptySlot(cbAssignSlot);
|
status = ensureEmptySlot(cbAssignSlot);
|
||||||
if (status != EXCEPTION_NONE) {
|
if (status != EXCEPTION_NONE) {
|
||||||
userError("ARMSIDBindCB: The SID is already bound with a context bank.");
|
userError("ARMSIDBindCB: The SID is already bound with a context bank.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
/*binding the sid to cb in SMMU*/
|
/*binding the sid to cb in SMMU*/
|
||||||
smmu_sid_bind_cb(sid, cap_cb_cap_get_capCB(cbCap));
|
smmu_sid_bind_cb(sid, cap_cb_cap_get_capCB(cbCap));
|
||||||
/* Building the connection between SID and CB caps by placing a
|
/* Building the connection between SID and CB caps by placing a
|
||||||
* copy of the given cb cap in sid's cnode*/
|
* copy of the given cb cap in sid's cnode*/
|
||||||
cteInsert(cbCap, cbCapSlot, cbAssignSlot);
|
cteInsert(cbCap, cbCapSlot, cbAssignSlot);
|
||||||
/* Recording the SID number in the copied CB cap.
|
/* Recording the SID number in the copied CB cap.
|
||||||
* Deleting the copied CB cap will trigger unbinding
|
* Deleting the copied CB cap will trigger unbinding
|
||||||
* operations. As a CB can be used (bound)
|
* operations. As a CB can be used (bound)
|
||||||
* by multiple SID caps, each copied CB caps resulted from
|
* by multiple SID caps, each copied CB caps resulted from
|
||||||
* binding operations keeps track of its serving SID numbers.*/
|
* binding operations keeps track of its serving SID numbers.*/
|
||||||
cap_cb_cap_ptr_set_capBindSID(&(cbAssignSlot->cap), sid);
|
cap_cb_cap_ptr_set_capBindSID(&(cbAssignSlot->cap), sid);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
case ARMSIDUnbindCB:
|
case ARMSIDUnbindCB:
|
||||||
sid = cap_sid_cap_get_capSID(cap);
|
sid = cap_sid_cap_get_capSID(cap);
|
||||||
cbAssignSlot = smmuStateSIDNode + sid;
|
cbAssignSlot = smmuStateSIDNode + sid;
|
||||||
if (unlikely(cap_get_capType(cbAssignSlot->cap) != cap_cb_cap)) {
|
if (unlikely(cap_get_capType(cbAssignSlot->cap) != cap_cb_cap)) {
|
||||||
userError("ARMSIDUnbindCB: The SID is not assigned with a context bank.");
|
userError("ARMSIDUnbindCB: The SID is not assigned with a context bank.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
status = cteDelete(cbAssignSlot, true);
|
status = cteDelete(cbAssignSlot, true);
|
||||||
if (unlikely(status != EXCEPTION_NONE)) {
|
if (unlikely(status != EXCEPTION_NONE)) {
|
||||||
userError("ARMSIDUnbindCB: the Assigned context bank cannot be unassigned.");
|
userError("ARMSIDUnbindCB: the Assigned context bank cannot be unassigned.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
default:
|
default:
|
||||||
userError("ARMSID: Illegal operation.");
|
userError("ARMSID: Illegal operation.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_t smmu_delete_sid(cap_t cap)
|
exception_t smmu_delete_sid(cap_t cap)
|
||||||
{
|
{
|
||||||
word_t sid = cap_sid_cap_get_capSID(cap);
|
word_t sid = cap_sid_cap_get_capSID(cap);
|
||||||
cte_t *cbAssignSlot = smmuStateSIDNode + sid;
|
cte_t *cbAssignSlot = smmuStateSIDNode + sid;
|
||||||
exception_t status = EXCEPTION_NONE;
|
exception_t status = EXCEPTION_NONE;
|
||||||
/*deleting the assigned context bank cap if exsits*/
|
/*deleting the assigned context bank cap if exsits*/
|
||||||
if (unlikely(cap_get_capType(cbAssignSlot->cap) == cap_cb_cap)) {
|
if (unlikely(cap_get_capType(cbAssignSlot->cap) == cap_cb_cap)) {
|
||||||
status = cteDelete(cbAssignSlot, true);
|
status = cteDelete(cbAssignSlot, true);
|
||||||
}
|
}
|
||||||
smmuStateSIDTable[sid] = false;
|
smmuStateSIDTable[sid] = false;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_t decodeARMCBControlInvocation(word_t label, unsigned int length, cptr_t cptr,
|
exception_t decodeARMCBControlInvocation(word_t label, unsigned int length, cptr_t cptr,
|
||||||
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
||||||
bool_t call, word_t *buffer) {
|
bool_t call, word_t *buffer)
|
||||||
|
{
|
||||||
|
|
||||||
word_t index, depth, cb;
|
word_t index, depth, cb;
|
||||||
cte_t *destSlot;
|
cte_t *destSlot;
|
||||||
cap_t cnodeCap;
|
cap_t cnodeCap;
|
||||||
lookupSlot_ret_t lu_ret;
|
lookupSlot_ret_t lu_ret;
|
||||||
exception_t status;
|
exception_t status;
|
||||||
|
|
||||||
if (label == ARMCBTLBInvalidateAll) {
|
if (label == ARMCBTLBInvalidateAll) {
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
smmu_tlb_invalidate_all();
|
smmu_tlb_invalidate_all();
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label != ARMCBIssueCBManager) {
|
if (label != ARMCBIssueCBManager) {
|
||||||
userError("ARMCBControl: Illegal operation.");
|
userError("ARMCBControl: Illegal operation.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
if (length < 3 || extraCaps.excaprefs[0] == NULL) {
|
if (length < 3 || extraCaps.excaprefs[0] == NULL) {
|
||||||
current_syscall_error.type = seL4_TruncatedMessage;
|
current_syscall_error.type = seL4_TruncatedMessage;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
cb = getSyscallArg(0, buffer);
|
cb = getSyscallArg(0, buffer);
|
||||||
index = getSyscallArg(1, buffer);
|
index = getSyscallArg(1, buffer);
|
||||||
depth = getSyscallArg(2, buffer);
|
depth = getSyscallArg(2, buffer);
|
||||||
cnodeCap = extraCaps.excaprefs[0]->cap;
|
cnodeCap = extraCaps.excaprefs[0]->cap;
|
||||||
|
|
||||||
if (cb >= SMMU_MAX_CB) {
|
if (cb >= SMMU_MAX_CB) {
|
||||||
current_syscall_error.type = seL4_RangeError;
|
current_syscall_error.type = seL4_RangeError;
|
||||||
current_syscall_error.rangeErrorMin = 0;
|
current_syscall_error.rangeErrorMin = 0;
|
||||||
current_syscall_error.rangeErrorMax = SMMU_MAX_CB - 1;
|
current_syscall_error.rangeErrorMax = SMMU_MAX_CB - 1;
|
||||||
userError("Rejecting request for CB %u. CB is greater than or equal to SMMU_MAX_CB.", (int)cb);
|
userError("Rejecting request for CB %u. CB is greater than or equal to SMMU_MAX_CB.", (int)cb);
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
if (smmuStateCBTable[cb]) {
|
if (smmuStateCBTable[cb]) {
|
||||||
current_syscall_error.type = seL4_RevokeFirst;
|
current_syscall_error.type = seL4_RevokeFirst;
|
||||||
userError("Rejecting request for CB %u. Already active.", (int)cb);
|
userError("Rejecting request for CB %u. Already active.", (int)cb);
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
lu_ret = lookupTargetSlot(cnodeCap, index, depth);
|
lu_ret = lookupTargetSlot(cnodeCap, index, depth);
|
||||||
if (lu_ret.status != EXCEPTION_NONE) {
|
if (lu_ret.status != EXCEPTION_NONE) {
|
||||||
userError("Target slot for new CB Handler cap invalid: cap %lu, CB %u.",
|
userError("Target slot for new CB Handler cap invalid: cap %lu, CB %u.",
|
||||||
getExtraCPtr(buffer, 0), (int)cb);
|
getExtraCPtr(buffer, 0), (int)cb);
|
||||||
return lu_ret.status;
|
return lu_ret.status;
|
||||||
}
|
}
|
||||||
destSlot = lu_ret.slot;
|
destSlot = lu_ret.slot;
|
||||||
status = ensureEmptySlot(destSlot);
|
status = ensureEmptySlot(destSlot);
|
||||||
if (status != EXCEPTION_NONE) {
|
if (status != EXCEPTION_NONE) {
|
||||||
userError("Target slot for new CB Handler cap not empty: cap %lu, CB %u.",
|
userError("Target slot for new CB Handler cap not empty: cap %lu, CB %u.",
|
||||||
getExtraCPtr(buffer, 0), (int)cb);
|
getExtraCPtr(buffer, 0), (int)cb);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
smmuStateCBTable[cb] = true;
|
smmuStateCBTable[cb] = true;
|
||||||
cteInsert(cap_cb_cap_new(SID_INVALID, cb), srcSlot, destSlot);
|
cteInsert(cap_cb_cap_new(SID_INVALID, cb), srcSlot, destSlot);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
exception_t decodeARMCBInvocation(word_t label, unsigned int length, cptr_t cptr,
|
exception_t decodeARMCBInvocation(word_t label, unsigned int length, cptr_t cptr,
|
||||||
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
cte_t *srcSlot, cap_t cap, extra_caps_t extraCaps,
|
||||||
bool_t call, word_t *buffer) {
|
bool_t call, word_t *buffer)
|
||||||
|
{
|
||||||
|
|
||||||
cap_t vspaceCap;
|
cap_t vspaceCap;
|
||||||
cte_t *vspaceCapSlot;
|
cte_t *vspaceCapSlot;
|
||||||
cte_t *cbSlot;
|
cte_t *cbSlot;
|
||||||
exception_t status;
|
exception_t status;
|
||||||
word_t cb;
|
word_t cb;
|
||||||
uint32_t faultStatus;
|
uint32_t faultStatus;
|
||||||
word_t faultAddress;
|
word_t faultAddress;
|
||||||
|
|
||||||
switch (label) {
|
switch (label) {
|
||||||
case ARMCBTLBInvalidate:
|
case ARMCBTLBInvalidate:
|
||||||
if (unlikely(checkARMCBVspace(cap) != EXCEPTION_NONE)) {
|
if (unlikely(checkARMCBVspace(cap) != EXCEPTION_NONE)) {
|
||||||
userError("ARMCBTLBInvalidate: the CB does not have a vspace root.");
|
userError("ARMCBTLBInvalidate: the CB does not have a vspace root.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
cb = cap_cb_cap_get_capCB(cap);
|
cb = cap_cb_cap_get_capCB(cap);
|
||||||
cbSlot = smmuStateCBNode + cb;
|
cbSlot = smmuStateCBNode + cb;
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
smmu_tlb_invalidate_cb(cb, cap_vtable_root_get_mappedASID(cbSlot->cap));
|
smmu_tlb_invalidate_cb(cb, cap_vtable_root_get_mappedASID(cbSlot->cap));
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
case ARMCBAssignVspace:
|
case ARMCBAssignVspace:
|
||||||
if (unlikely(extraCaps.excaprefs[0] == NULL)) {
|
if (unlikely(extraCaps.excaprefs[0] == NULL)) {
|
||||||
current_syscall_error.type = seL4_TruncatedMessage;
|
current_syscall_error.type = seL4_TruncatedMessage;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
vspaceCapSlot = extraCaps.excaprefs[0];
|
vspaceCapSlot = extraCaps.excaprefs[0];
|
||||||
vspaceCap = vspaceCapSlot->cap;
|
vspaceCap = vspaceCapSlot->cap;
|
||||||
|
|
||||||
if (unlikely(!isVTableRoot(vspaceCap) || !cap_vtable_root_isMapped(vspaceCap))) {
|
if (unlikely(!isVTableRoot(vspaceCap) || !cap_vtable_root_isMapped(vspaceCap))) {
|
||||||
userError("ARMCBAssignVspace: the vspace is invalid");
|
userError("ARMCBAssignVspace: the vspace is invalid");
|
||||||
current_syscall_error.type = seL4_InvalidCapability;
|
current_syscall_error.type = seL4_InvalidCapability;
|
||||||
current_syscall_error.invalidCapNumber = 1;
|
current_syscall_error.invalidCapNumber = 1;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*the cb number must be valid as it is created via the ARMCBIssueCBManager*/
|
/*the cb number must be valid as it is created via the ARMCBIssueCBManager*/
|
||||||
cb = cap_cb_cap_get_capCB(cap);
|
cb = cap_cb_cap_get_capCB(cap);
|
||||||
cbSlot = smmuStateCBNode + cb;
|
cbSlot = smmuStateCBNode + cb;
|
||||||
status = ensureEmptySlot(cbSlot);
|
status = ensureEmptySlot(cbSlot);
|
||||||
if (status != EXCEPTION_NONE) {
|
if (status != EXCEPTION_NONE) {
|
||||||
userError("ARMCBAssignVspace: the CB already assigned with a vspace root.");
|
userError("ARMCBAssignVspace: the CB already assigned with a vspace root.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
/*setting up vspace for the context bank in SMMU*/
|
/*setting up vspace for the context bank in SMMU*/
|
||||||
smmu_cb_assign_vspace(cb, cap_vtable_root_get_basePtr(vspaceCap),
|
smmu_cb_assign_vspace(cb, cap_vtable_root_get_basePtr(vspaceCap),
|
||||||
cap_vtable_root_get_mappedASID(vspaceCap));
|
cap_vtable_root_get_mappedASID(vspaceCap));
|
||||||
/*Connecting vspace cap to context bank*/
|
/*Connecting vspace cap to context bank*/
|
||||||
cteInsert(vspaceCap, vspaceCapSlot, cbSlot);
|
cteInsert(vspaceCap, vspaceCapSlot, cbSlot);
|
||||||
cap_vtable_root_ptr_set_mappedCB(&(cbSlot->cap), cb);
|
cap_vtable_root_ptr_set_mappedCB(&(cbSlot->cap), cb);
|
||||||
/*set relationship between CB and ASID*/
|
/*set relationship between CB and ASID*/
|
||||||
smmuStateCBAsidTable[cb] = cap_vtable_root_get_mappedASID(vspaceCap);
|
smmuStateCBAsidTable[cb] = cap_vtable_root_get_mappedASID(vspaceCap);
|
||||||
increaseASIDBindCB(cap_vtable_root_get_mappedASID(vspaceCap));
|
increaseASIDBindCB(cap_vtable_root_get_mappedASID(vspaceCap));
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
case ARMCBUnassignVspace:
|
case ARMCBUnassignVspace:
|
||||||
if (unlikely(checkARMCBVspace(cap) != EXCEPTION_NONE)) {
|
if (unlikely(checkARMCBVspace(cap) != EXCEPTION_NONE)) {
|
||||||
userError("ARMCBUnassignVspace: the CB does not have an assigned VSpace.");
|
userError("ARMCBUnassignVspace: the CB does not have an assigned VSpace.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
cb = cap_cb_cap_get_capCB(cap);
|
cb = cap_cb_cap_get_capCB(cap);
|
||||||
cbSlot = smmuStateCBNode + cb;
|
cbSlot = smmuStateCBNode + cb;
|
||||||
status = cteDelete(cbSlot, true);
|
status = cteDelete(cbSlot, true);
|
||||||
if (unlikely(status != EXCEPTION_NONE)) {
|
if (unlikely(status != EXCEPTION_NONE)) {
|
||||||
userError("ARMCBUnassignVspace: the Assigned VSpace cannot be deleted.");
|
userError("ARMCBUnassignVspace: the Assigned VSpace cannot be deleted.");
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
case ARMCBGetFault:
|
case ARMCBGetFault:
|
||||||
smmu_cb_read_fault_state(cap_cb_cap_get_capCB(cap), &faultStatus, &faultAddress);
|
smmu_cb_read_fault_state(cap_cb_cap_get_capCB(cap), &faultStatus, &faultAddress);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgRegisters[0], faultStatus);
|
setRegister(NODE_STATE(ksCurThread), msgRegisters[0], faultStatus);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgRegisters[1], faultAddress);
|
setRegister(NODE_STATE(ksCurThread), msgRegisters[1], faultAddress);
|
||||||
setRegister(NODE_STATE(ksCurThread), msgInfoRegister,
|
setRegister(NODE_STATE(ksCurThread), msgInfoRegister,
|
||||||
wordFromMessageInfo(seL4_MessageInfo_new(0, 0, 0, 2)));
|
wordFromMessageInfo(seL4_MessageInfo_new(0, 0, 0, 2)));
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
case ARMCBClearFault:
|
case ARMCBClearFault:
|
||||||
smmu_cb_clear_fault_state(cap_cb_cap_get_capCB(cap));
|
smmu_cb_clear_fault_state(cap_cb_cap_get_capCB(cap));
|
||||||
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
setThreadState(NODE_STATE(ksCurThread), ThreadState_Restart);
|
||||||
return EXCEPTION_NONE;
|
return EXCEPTION_NONE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
userError("ARMCBInvocation: Illegal operation.");
|
userError("ARMCBInvocation: Illegal operation.");
|
||||||
current_syscall_error.type = seL4_IllegalOperation;
|
current_syscall_error.type = seL4_IllegalOperation;
|
||||||
return EXCEPTION_SYSCALL_ERROR;
|
return EXCEPTION_SYSCALL_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
exception_t smmu_delete_cb(cap_t cap)
|
exception_t smmu_delete_cb(cap_t cap)
|
||||||
{
|
{
|
||||||
word_t cb = cap_cb_cap_get_capCB(cap);
|
word_t cb = cap_cb_cap_get_capCB(cap);
|
||||||
cte_t *cbSlot;
|
cte_t *cbSlot;
|
||||||
exception_t status = EXCEPTION_NONE;
|
exception_t status = EXCEPTION_NONE;
|
||||||
/*deleting assigned vspace root if exists*/
|
/*deleting assigned vspace root if exists*/
|
||||||
if (unlikely(checkARMCBVspace(cap) == EXCEPTION_NONE)) {
|
if (unlikely(checkARMCBVspace(cap) == EXCEPTION_NONE)) {
|
||||||
cbSlot = smmuStateCBNode + cb;
|
cbSlot = smmuStateCBNode + cb;
|
||||||
/*the relationship between CB and ASID is reset at the vspace deletion
|
/*the relationship between CB and ASID is reset at the vspace deletion
|
||||||
triggered by the cteDelete*/
|
triggered by the cteDelete*/
|
||||||
status = cteDelete(cbSlot, true);
|
status = cteDelete(cbSlot, true);
|
||||||
}
|
}
|
||||||
smmuStateCBTable[cb] = false;
|
smmuStateCBTable[cb] = false;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void smmu_cb_delete_vspace(word_t cb, asid_t asid)
|
void smmu_cb_delete_vspace(word_t cb, asid_t asid)
|
||||||
{
|
{
|
||||||
/* Deleting the vsapce cap stored in context bank's CNode, causing:
|
/* Deleting the vsapce cap stored in context bank's CNode, causing:
|
||||||
* -reset the relationship between context bank and vspace's ASID
|
* -reset the relationship between context bank and vspace's ASID
|
||||||
* -disabe the context bank as its vspace no longer exists*/
|
* -disabe the context bank as its vspace no longer exists*/
|
||||||
smmuStateCBAsidTable[cb] = ASID_INVALID;
|
smmuStateCBAsidTable[cb] = ASID_INVALID;
|
||||||
decreaseASIDBindCB(asid);
|
decreaseASIDBindCB(asid);
|
||||||
smmu_cb_disable(cb, asid);
|
smmu_cb_disable(cb, asid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidateSMMUTLBByASID(asid_t asid, word_t bind_cb)
|
void invalidateSMMUTLBByASID(asid_t asid, word_t bind_cb)
|
||||||
{
|
{
|
||||||
/* Due to the requirement of one vspace (ASID) can be shared by
|
/* Due to the requirement of one vspace (ASID) can be shared by
|
||||||
* multiple threads and drivers, there is no obvious way to
|
* multiple threads and drivers, there is no obvious way to
|
||||||
* directly locate all context banks associated with a given ASID without a
|
* directly locate all context banks associated with a given ASID without a
|
||||||
* serch. Another possible solution is representing all context banks in
|
* serch. Another possible solution is representing all context banks in
|
||||||
* bitmaps, which also requires a search. This operation can only be triggered
|
* bitmaps, which also requires a search. This operation can only be triggered
|
||||||
* by ASID invalidation or similar operations, hence the performance is not a major issue.*/
|
* by ASID invalidation or similar operations, hence the performance is not a major issue.*/
|
||||||
for (int cb = 0; cb < SMMU_MAX_CB && bind_cb; cb++) {
|
for (int cb = 0; cb < SMMU_MAX_CB && bind_cb; cb++) {
|
||||||
if (unlikely(smmuStateCBAsidTable[cb] == asid)) {
|
if (unlikely(smmuStateCBAsidTable[cb] == asid)) {
|
||||||
smmu_tlb_invalidate_cb(cb, asid);
|
smmu_tlb_invalidate_cb(cb, asid);
|
||||||
bind_cb--;
|
bind_cb--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidateSMMUTLBByASIDVA(asid_t asid, vptr_t vaddr, word_t bind_cb)
|
void invalidateSMMUTLBByASIDVA(asid_t asid, vptr_t vaddr, word_t bind_cb)
|
||||||
{
|
{
|
||||||
/* Implemeneted in the same way as invalidateSMMUTLBByASID */
|
/* Implemeneted in the same way as invalidateSMMUTLBByASID */
|
||||||
for (int cb = 0; cb < SMMU_MAX_CB && bind_cb; cb++) {
|
for (int cb = 0; cb < SMMU_MAX_CB && bind_cb; cb++) {
|
||||||
if (unlikely(smmuStateCBAsidTable[cb] == asid)) {
|
if (unlikely(smmuStateCBAsidTable[cb] == asid)) {
|
||||||
smmu_tlb_invalidate_cb_va(cb, asid, vaddr);
|
smmu_tlb_invalidate_cb_va(cb, asid, vaddr);
|
||||||
bind_cb--;
|
bind_cb--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,4 @@
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.7.2)
|
cmake_minimum_required(VERSION 3.7.2)
|
||||||
|
|
||||||
register_driver(
|
register_driver(compatibility_strings "arm,mmu-500" PREFIX src/drivers/smmu CFILES "smmuv2.c")
|
||||||
compatibility_strings "arm,mmu-500"
|
|
||||||
PREFIX src/drivers/smmu
|
|
||||||
CFILES "smmuv2.c"
|
|
||||||
)
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -27,10 +27,9 @@ if(KernelPlatformTx2)
|
||||||
TIMER drivers/timer/arm_generic.h
|
TIMER drivers/timer/arm_generic.h
|
||||||
CLK_SHIFT 57u
|
CLK_SHIFT 57u
|
||||||
CLK_MAGIC 4611686019u
|
CLK_MAGIC 4611686019u
|
||||||
KERNEL_WCET 10u
|
KERNEL_WCET 10u SMMU drivers/smmu/smmuv2.h
|
||||||
SMMU drivers/smmu/smmuv2.h
|
MAX_SID 128
|
||||||
MAX_SID 128
|
MAX_CB 64
|
||||||
MAX_CB 64
|
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue