// Copyright 2016 The Fuchsia Authors
// Copyright (c) 2014 Travis Geiselbrecht
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

#include <kernel/mp.h>

#include <arch/mp.h>
#include <arch/ops.h>
#include <assert.h>
#include <debug.h>
#include <dev/interrupt.h>
#include <err.h>
#include <fbl/algorithm.h>
#include <inttypes.h>
#include <kernel/align.h>
#include <kernel/dpc.h>
#include <kernel/event.h>
#include <kernel/mp.h>
#include <kernel/mutex.h>
#include <kernel/sched.h>
#include <kernel/spinlock.h>
#include <kernel/stats.h>
#include <kernel/timer.h>
#include <lk/init.h>
#include <platform.h>
#include <platform/timer.h>
#include <stdlib.h>
#include <trace.h>
#include <zircon/types.h>

#define LOCAL_TRACE 0

// a global state structure, aligned on cpu cache line to minimize aliasing
struct mp_state mp __CPU_ALIGN_EXCLUSIVE;

// Helpers used for implementing mp_sync
struct mp_sync_context;
static void mp_sync_task(void* context);

void mp_init(void) {
    mp.ipi_task_lock = SPIN_LOCK_INITIAL_VALUE;
    for (uint i = 0; i < fbl::count_of(mp.ipi_task_list); ++i) {
        list_initialize(&mp.ipi_task_list[i]);
    }
}

void mp_prepare_current_cpu_idle_state(bool idle) {
    arch_prepare_current_cpu_idle_state(idle);
}

void mp_reschedule(cpu_mask_t mask, uint flags) {
    // we must be holding the thread lock to access some of the cpu
    // state bitmaps and some arch_mp_reschedule implementations.
    DEBUG_ASSERT(thread_lock_held());

    const cpu_num_t local_cpu = arch_curr_cpu_num();

    LTRACEF("local %u, mask %#x\n", local_cpu, mask);

    // mask out cpus that are not active and the local cpu
    mask &= mp.active_cpus;
    mask &= ~cpu_num_to_mask(local_cpu);

    // mask out cpus that are currently running realtime code
    if ((flags & MP_RESCHEDULE_FLAG_REALTIME) == 0) {
        mask &= ~mp.realtime_cpus;
    }

    LTRACEF("local %u, post mask target now 0x%x\n", local_cpu, mask);

    // if we have no work to do, return
    if (mask == 0) {
        return;
    }

    arch_mp_reschedule(mask);
}

void mp_interrupt(mp_ipi_target_t target, cpu_mask_t mask) {
    arch_mp_send_ipi(target, mask, MP_IPI_INTERRUPT);
}

struct mp_sync_context {
    mp_sync_task_t task;
    void* task_context;
    // Mask of which CPUs need to finish the task
    volatile cpu_mask_t outstanding_cpus;
};

static void mp_sync_task(void* raw_context) {
    auto context = reinterpret_cast<mp_sync_context*>(raw_context);
    context->task(context->task_context);
    // use seq-cst atomic to ensure this update is not seen before the
    // side-effects of context->task
    atomic_and((int*)&context->outstanding_cpus, ~cpu_num_to_mask(arch_curr_cpu_num()));
}

/* @brief Execute a task on the specified CPUs, and block on the calling
 *        CPU until all CPUs have finished the task.
 *
 *  If MP_IPI_TARGET_ALL or MP_IPI_TARGET_ALL_BUT_LOCAL is the target, the online CPU
 *  mask will be used to determine actual targets.
 *
 * Interrupts must be disabled if calling with MP_IPI_TARGET_ALL_BUT_LOCAL as target
 *
 * The callback in |task| will always be called with |arch_blocking_disallowed()|
 * set to true.
 */
void mp_sync_exec(mp_ipi_target_t target, cpu_mask_t mask, mp_sync_task_t task, void* context) {
    uint num_cpus = arch_max_num_cpus();

    if (target == MP_IPI_TARGET_ALL) {
        mask = mp_get_online_mask();
    } else if (target == MP_IPI_TARGET_ALL_BUT_LOCAL) {
        // targeting all other CPUs but the current one is hazardous
        // if the local CPU may be changed underneath us
        DEBUG_ASSERT(arch_ints_disabled());
        mask = mp_get_online_mask() & ~cpu_num_to_mask(arch_curr_cpu_num());
    } else {
        // Mask any offline CPUs from target list
        mask &= mp_get_online_mask();
    }

    // disable interrupts so our current CPU doesn't change
    spin_lock_saved_state_t irqstate;
    arch_interrupt_save(&irqstate, SPIN_LOCK_FLAG_INTERRUPTS);
    smp_mb();

    const uint local_cpu = arch_curr_cpu_num();

    // remove self from target lists, since no need to IPI ourselves
    bool targetting_self = !!(mask & cpu_num_to_mask(local_cpu));
    mask &= ~cpu_num_to_mask(local_cpu);

    // create tasks to enqueue (we need one per target due to each containing
    // a linked list node
    struct mp_sync_context sync_context = {
        .task = task,
        .task_context = context,
        .outstanding_cpus = mask,
    };

    struct mp_ipi_task sync_tasks[SMP_MAX_CPUS] = {};
    for (uint i = 0; i < num_cpus; ++i) {
        sync_tasks[i].func = mp_sync_task;
        sync_tasks[i].context = &sync_context;
    }

    // enqueue tasks
    spin_lock(&mp.ipi_task_lock);
    cpu_mask_t remaining = mask;
    uint cpu_id = 0;
    while (remaining && cpu_id < num_cpus) {
        if (remaining & 1) {
            list_add_tail(&mp.ipi_task_list[cpu_id], &sync_tasks[cpu_id].node);
        }
        remaining >>= 1;
        cpu_id++;
    }
    spin_unlock(&mp.ipi_task_lock);

    // let CPUs know to begin executing
    __UNUSED zx_status_t status = arch_mp_send_ipi(MP_IPI_TARGET_MASK, mask, MP_IPI_GENERIC);
    DEBUG_ASSERT(status == ZX_OK);

    if (targetting_self) {
        bool previous_blocking_disallowed = arch_blocking_disallowed();
        arch_set_blocking_disallowed(true);
        mp_sync_task(&sync_context);
        arch_set_blocking_disallowed(previous_blocking_disallowed);
    }
    smp_mb();

    // we can take interrupts again once we've executed our task
    arch_interrupt_restore(irqstate, SPIN_LOCK_FLAG_INTERRUPTS);

    bool ints_disabled = arch_ints_disabled();
    // wait for all other CPUs to be done with the context
    while (1) {
        // See comment in mp_unplug_trampoline about related CPU hotplug
        // guarantees.
        cpu_mask_t outstanding = atomic_load_relaxed(
            (int*)&sync_context.outstanding_cpus);
        cpu_mask_t online = mp_get_online_mask();
        if ((outstanding & online) == 0) {
            break;
        }

        // If interrupts are still disabled, we need to attempt to process any
        // tasks queued for us in order to prevent deadlock.
        if (ints_disabled) {
            // Optimistically check if our task list has work without the lock.
            // mp_mbx_generic_irq will take the lock and check again.
            if (!list_is_empty(&mp.ipi_task_list[local_cpu])) {
                bool previous_blocking_disallowed = arch_blocking_disallowed();
                arch_set_blocking_disallowed(true);
                mp_mbx_generic_irq(nullptr);
                arch_set_blocking_disallowed(previous_blocking_disallowed);
                continue;
            }
        }

        arch_spinloop_pause();
    }
    smp_mb();

    // make sure the sync_tasks aren't in lists anymore, since they're
    // stack allocated
    spin_lock_irqsave(&mp.ipi_task_lock, irqstate);
    for (uint i = 0; i < num_cpus; ++i) {
        // If a task is still around, it's because the CPU went offline.
        if (list_in_list(&sync_tasks[i].node)) {
            list_delete(&sync_tasks[i].node);
        }
    }
    spin_unlock_irqrestore(&mp.ipi_task_lock, irqstate);
}

static void mp_unplug_trampoline(void) TA_REQ(thread_lock) __NO_RETURN;
static void mp_unplug_trampoline(void) {
    // We're still holding the thread lock from the reschedule that took us
    // here.

    thread_t* ct = get_current_thread();
    auto unplug_done = reinterpret_cast<event_t*>(ct->arg);

    cpu_num_t cpu_num = arch_curr_cpu_num();
    sched_transition_off_cpu(cpu_num);

    // Note that before this invocation, but after we stopped accepting
    // interrupts, we may have received a synchronous task to perform.
    // Clearing this flag will cause the mp_sync_exec caller to consider
    // this CPU done.  If this CPU comes back online before other all
    // of the other CPUs finish their work (very unlikely, since tasks
    // should be quick), then this CPU may execute the task.
    mp_set_curr_cpu_online(false);

    // do *not* enable interrupts, we want this CPU to never receive another
    // interrupt
    spin_unlock(&thread_lock);

    // Stop and then shutdown this CPU's platform timer.
    platform_stop_timer();
    platform_shutdown_timer();

    // Shutdown the interrupt controller for this CPU.  On some platforms (arm64 with GIC) receiving
    // an interrupt at a powered off CPU can result in implementation defined behavior (including
    // resetting the whole system).
    shutdown_interrupts_curr_cpu();

    // flush all of our caches
    arch_flush_state_and_halt(unplug_done);
}

// Hotplug the given cpus.  Blocks until the CPUs are up, or a failure is
// detected.
//
// This should be called in a thread context
zx_status_t mp_hotplug_cpu_mask(cpu_mask_t cpu_mask) {
    DEBUG_ASSERT(!arch_ints_disabled());

    zx_status_t status = ZX_OK;

    mutex_acquire(&mp.hotplug_lock);

    // Make sure all of the requested CPUs are offline
    if (cpu_mask & mp_get_online_mask()) {
        status = ZX_ERR_BAD_STATE;
        goto cleanup_mutex;
    }

    while (cpu_mask != 0) {
        cpu_num_t cpu_id = highest_cpu_set(cpu_mask);
        cpu_mask &= ~cpu_num_to_mask(cpu_id);

        status = platform_mp_cpu_hotplug(cpu_id);
        if (status != ZX_OK) {
            break;
        }
    }
cleanup_mutex:
    mutex_release(&mp.hotplug_lock);
    return status;
}

// Unplug a single CPU.  Must be called while hodling the hotplug lock
static zx_status_t mp_unplug_cpu_mask_single_locked(cpu_num_t cpu_id) {
    // Wait for |cpu_id| to complete any in-progress DPCs and terminate its DPC thread.  Later, once
    // nothing is running on it, we'll migrate its queued DPCs to another CPU.
    dpc_shutdown(cpu_id);

    // TODO(maniscalco): |cpu_id| is about to shutdown.  We should ensure it has no pinned threads
    // (except maybe the idle thread).  Once we're confident we've terminated/migrated them all,
    // this would be a good place to DEBUG_ASSERT.

    // Create a thread for the unplug.  We will cause the target CPU to
    // context switch to this thread.  After this happens, it should no
    // longer be accessing system state and can be safely shut down.
    //
    // This thread is pinned to the target CPU and set to run with the
    // highest priority.  This should cause it to pick up the thread
    // immediately (or very soon, if for some reason there is another
    // HIGHEST_PRIORITY task scheduled in between when we resume the
    // thread and when the CPU is woken up).
    event_t unplug_done = EVENT_INITIAL_VALUE(unplug_done, false, 0);
    thread_t* t = thread_create_etc(
        NULL,
        "unplug_thread",
        NULL,
        &unplug_done,
        HIGHEST_PRIORITY,
        mp_unplug_trampoline);
    if (t == NULL) {
        return ZX_ERR_NO_MEMORY;
    }

    zx_status_t status = platform_mp_prep_cpu_unplug(cpu_id);
    if (status != ZX_OK) {
        return status;
    }

    // Pin to the target CPU
    thread_set_cpu_affinity(t, cpu_num_to_mask(cpu_id));
    // Set real time to cancel the pre-emption timer
    thread_set_real_time(t);

    status = thread_detach_and_resume(t);
    if (status != ZX_OK) {
        goto cleanup_thread;
    }

    // Wait for the unplug thread to get scheduled on the target
    do {
        status = event_wait(&unplug_done);
    } while (status != ZX_OK);

    // Now that the CPU is no longer processing tasks, move all of its timers
    timer_transition_off_cpu(cpu_id);
    // Move the CPU's queued DPCs to the current CPU.
    dpc_shutdown_transition_off_cpu(cpu_id);

    status = platform_mp_cpu_unplug(cpu_id);
    if (status != ZX_OK) {
        // Do not cleanup the unplug thread in this case.  We have successfully
        // unplugged the CPU from the scheduler's perspective, but the platform
        // may have failed to shut down the CPU
        return status;
    }

// Fall through.  Since the thread is scheduled, it should not be in any
// queues.  Since the CPU running this thread is now shutdown, we can just
// erase the thread's existence.
cleanup_thread:
    thread_forget(t);
    return status;
}

// Unplug the given cpus.  Blocks until the CPUs are removed.  Partial
// failure may occur (in which some CPUs are removed but not others).
//
// This should be called in a thread context
zx_status_t mp_unplug_cpu_mask(cpu_mask_t cpu_mask) {
    DEBUG_ASSERT(!arch_ints_disabled());

    zx_status_t status = ZX_OK;

    mutex_acquire(&mp.hotplug_lock);

    // Make sure all of the requested CPUs are online
    if (cpu_mask & ~mp_get_online_mask()) {
        status = ZX_ERR_BAD_STATE;
        goto cleanup_mutex;
    }

    while (cpu_mask != 0) {
        cpu_num_t cpu_id = highest_cpu_set(cpu_mask);
        cpu_mask &= ~cpu_num_to_mask(cpu_id);

        status = mp_unplug_cpu_mask_single_locked(cpu_id);
        if (status != ZX_OK) {
            break;
        }
    }

cleanup_mutex:
    mutex_release(&mp.hotplug_lock);
    return status;
}

interrupt_eoi mp_mbx_generic_irq(void*) {
    DEBUG_ASSERT(arch_ints_disabled());
    const cpu_num_t local_cpu = arch_curr_cpu_num();

    CPU_STATS_INC(generic_ipis);

    while (1) {
        struct mp_ipi_task* task;
        spin_lock(&mp.ipi_task_lock);
        task = list_remove_head_type(&mp.ipi_task_list[local_cpu], struct mp_ipi_task, node);
        spin_unlock(&mp.ipi_task_lock);
        if (task == NULL) {
            break;
        }

        task->func(task->context);
    }

    return IRQ_EOI_DEACTIVATE;
}

interrupt_eoi mp_mbx_reschedule_irq(void*) {
    const cpu_num_t cpu = arch_curr_cpu_num();

    LTRACEF("cpu %u\n", cpu);

    CPU_STATS_INC(reschedule_ipis);

    if (mp.active_cpus & cpu_num_to_mask(cpu)) {
        thread_preempt_set_pending();
    }

    return IRQ_EOI_DEACTIVATE;
}

interrupt_eoi mp_mbx_interrupt_irq(void*) {
    const cpu_num_t cpu = arch_curr_cpu_num();

    LTRACEF("cpu %u\n", cpu);

    // do nothing, the entire point of this interrupt is to simply have one
    // delivered to the cpu.

    return IRQ_EOI_DEACTIVATE;
}

__WEAK zx_status_t arch_mp_cpu_hotplug(uint cpu_id) {
    return ZX_ERR_NOT_SUPPORTED;
}
__WEAK zx_status_t arch_mp_prep_cpu_unplug(uint cpu_id) {
    return ZX_ERR_NOT_SUPPORTED;
}
__WEAK zx_status_t arch_mp_cpu_unplug(uint cpu_id) {
    return ZX_ERR_NOT_SUPPORTED;
}
__WEAK zx_status_t platform_mp_cpu_hotplug(uint cpu_id) {
    return arch_mp_cpu_hotplug(cpu_id);
}
__WEAK zx_status_t platform_mp_prep_cpu_unplug(uint cpu_id) {
    return arch_mp_prep_cpu_unplug(cpu_id);
}
__WEAK zx_status_t platform_mp_cpu_unplug(uint cpu_id) {
    return arch_mp_cpu_unplug(cpu_id);
}
