void M68KVMTranslationMap::Flush() { if (fInvalidPagesCount <= 0) return; Thread* thread = thread_get_current_thread(); thread_pin_to_current_cpu(thread); if (fInvalidPagesCount > PAGE_INVALIDATE_CACHE_SIZE) { // invalidate all pages TRACE("flush_tmap: %d pages to invalidate, invalidate all\n", fInvalidPagesCount); if (fIsKernelMap) { arch_cpu_global_TLB_invalidate(); smp_send_broadcast_ici(SMP_MSG_GLOBAL_INVALIDATE_PAGES, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); } else { cpu_status state = disable_interrupts(); arch_cpu_user_TLB_invalidate(); restore_interrupts(state); int cpu = smp_get_current_cpu(); CPUSet cpuMask = PagingStructures()->active_on_cpus; cpuMask.ClearBit(cpu); if (!cpuMask.IsEmpty()) { smp_send_multicast_ici(cpuMask, SMP_MSG_USER_INVALIDATE_PAGES, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); } } } else { TRACE("flush_tmap: %d pages to invalidate, invalidate list\n", fInvalidPagesCount); arch_cpu_invalidate_TLB_list(fInvalidPages, fInvalidPagesCount); if (fIsKernelMap) { smp_send_broadcast_ici(SMP_MSG_INVALIDATE_PAGE_LIST, (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } else { int cpu = smp_get_current_cpu(); CPUSet cpuMask = PagingStructures()->active_on_cpus; cpuMask.ClearBit(cpu); if (!cpuMask.IsEmpty()) { smp_send_multicast_ici(cpuMask, SMP_MSG_INVALIDATE_PAGE_LIST, (addr_t)fInvalidPages, fInvalidPagesCount, 0, NULL, SMP_MSG_FLAG_SYNC); } } } fInvalidPagesCount = 0; thread_unpin_from_current_cpu(thread); }
static status_t process_pending_ici(int32 currentCPU) { mailbox_source sourceMailbox; struct smp_msg* msg = check_for_message(currentCPU, sourceMailbox); if (msg == NULL) return B_ENTRY_NOT_FOUND; TRACE((" cpu %ld message = %ld\n", currentCPU, msg->message)); bool haltCPU = false; switch (msg->message) { case SMP_MSG_INVALIDATE_PAGE_RANGE: arch_cpu_invalidate_TLB_range(msg->data, msg->data2); break; case SMP_MSG_INVALIDATE_PAGE_LIST: arch_cpu_invalidate_TLB_list((addr_t*)msg->data, (int)msg->data2); break; case SMP_MSG_USER_INVALIDATE_PAGES: arch_cpu_user_TLB_invalidate(); break; case SMP_MSG_GLOBAL_INVALIDATE_PAGES: arch_cpu_global_TLB_invalidate(); break; case SMP_MSG_CPU_HALT: haltCPU = true; break; case SMP_MSG_CALL_FUNCTION: { smp_call_func func = (smp_call_func)msg->data_ptr; func(msg->data, currentCPU, msg->data2, msg->data3); break; } case SMP_MSG_RESCHEDULE: { cpu_ent* cpu = thread_get_current_thread()->cpu; cpu->invoke_scheduler = true; cpu->invoke_scheduler_if_idle = false; break; } case SMP_MSG_RESCHEDULE_IF_IDLE: { cpu_ent* cpu = thread_get_current_thread()->cpu; if (!cpu->invoke_scheduler) { cpu->invoke_scheduler = true; cpu->invoke_scheduler_if_idle = true; } break; } default: dprintf("smp_intercpu_int_handler: got unknown message %" B_PRId32 "\n", msg->message); break; } // finish dealing with this message, possibly removing it from the list finish_message_processing(currentCPU, msg, sourceMailbox); // special case for the halt message if (haltCPU) debug_trap_cpu_in_kdl(currentCPU, false); return B_OK; }