exception_t invokeTCB_WriteRegisters(tcb_t *dest, bool_t resumeTarget, unsigned int n, word_t arch, word_t *buffer) { unsigned int i; word_t pc; exception_t e; e = Arch_performTransfer(arch, ksCurThread, dest); if (e != EXCEPTION_NONE) { return e; } if (n > n_frameRegisters + n_gpRegisters) { n = n_frameRegisters + n_gpRegisters; } for (i = 0; i < n_frameRegisters && i < n; i++) { /* Offset of 2 to get past the initial syscall arguments */ setRegister(dest, frameRegisters[i], sanitiseRegister(frameRegisters[i], getSyscallArg(i + 2, buffer))); } for (i = 0; i < n_gpRegisters && i + n_frameRegisters < n; i++) { setRegister(dest, gpRegisters[i], sanitiseRegister(gpRegisters[i], getSyscallArg(i + n_frameRegisters + 2, buffer))); } pc = getRestartPC(dest); setNextPC(dest, pc); if (resumeTarget) { restart(dest); } return EXCEPTION_NONE; }
static inline void copyMRsFaultReply(tcb_t *sender, tcb_t *receiver, MessageID_t id, word_t length) { word_t i; bool_t archInfo; archInfo = Arch_getSanitiseRegisterInfo(receiver); for (i = 0; i < MIN(length, n_msgRegisters); i++) { register_t r = fault_messages[id][i]; word_t v = getRegister(sender, msgRegisters[i]); setRegister(receiver, r, sanitiseRegister(r, v, archInfo)); } if (i < length) { word_t *sendBuf = lookupIPCBuffer(false, sender); if (sendBuf) { for (; i < length; i++) { register_t r = fault_messages[id][i]; word_t v = sendBuf[i + 1]; setRegister(receiver, r, sanitiseRegister(r, v, archInfo)); } } } }
bool_t handleFaultReply(tcb_t *receiver, tcb_t *sender) { message_info_t tag; word_t label; fault_t fault; unsigned int length; /* These lookups are moved inward from doReplyTransfer */ tag = messageInfoFromWord(getRegister(sender, msgInfoRegister)); label = message_info_get_msgLabel(tag); length = message_info_get_msgLength(tag); fault = receiver->tcbFault; switch (fault_get_faultType(fault)) { case fault_cap_fault: return true; case fault_vm_fault: return true; case fault_unknown_syscall: { unsigned int i; register_t r; word_t v; word_t *sendBuf; sendBuf = lookupIPCBuffer(false, sender); /* Assumes n_syscallMessage > n_msgRegisters */ for (i = 0; i < length && i < n_msgRegisters; i++) { r = syscallMessage[i]; v = getRegister(sender, msgRegisters[i]); setRegister(receiver, r, sanitiseRegister(r, v)); } if (sendBuf) { for (; i < length && i < n_syscallMessage; i++) { r = syscallMessage[i]; v = sendBuf[i + 1]; setRegister(receiver, r, sanitiseRegister(r, v)); } } } return (label == 0); case fault_user_exception: { unsigned int i; register_t r; word_t v; /* Assumes n_exceptionMessage <= n_msgRegisters */ for (i = 0; i < length && i < n_exceptionMessage; i++) { r = exceptionMessage[i]; v = getRegister(sender, msgRegisters[i]); setRegister(receiver, r, sanitiseRegister(r, v)); } } return (label == 0); default: fail("Invalid fault"); } }