trivial: style and comment

Signed-off-by: Oliver Scott <Oliver.Scott@data61.csiro.au>
This commit is contained in:
Oliver Scott 2020-08-04 13:37:36 +10:00
parent 935714a4cb
commit c66d9cee7a
12 changed files with 855 additions and 827 deletions

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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 */
}; };

View file

@ -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;

View file

@ -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

View file

@ -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"

View file

@ -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());

View file

@ -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

View file

@ -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

View file

@ -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()