// Copyright 2016 The Fuchsia Authors
//
// 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 <dev/interrupt.h>
#include <object/interrupt_dispatcher.h>
#include <object/port_dispatcher.h>
#include <object/process_dispatcher.h>
#include <platform.h>
#include <zircon/syscalls/port.h>

InterruptDispatcher::InterruptDispatcher()
    : timestamp_(0), state_(InterruptState::IDLE) {
    event_init(&event_, false, EVENT_FLAG_AUTOUNSIGNAL);
}

zx_status_t InterruptDispatcher::WaitForInterrupt(zx_time_t* out_timestamp) {
    while (true) {
        {
            Guard<SpinLock, IrqSave> guard{&spinlock_};
            if (port_dispatcher_) {
                return ZX_ERR_BAD_STATE;
            }
            switch (state_) {
            case InterruptState::DESTROYED:
                return ZX_ERR_CANCELED;
            case InterruptState::TRIGGERED:
                state_ = InterruptState::NEEDACK;
                *out_timestamp = timestamp_;
                timestamp_ = 0;
                return event_unsignal(&event_);
            case InterruptState::NEEDACK:
                if (flags_ & INTERRUPT_UNMASK_PREWAIT) {
                    UnmaskInterrupt();
                }
                break;
            case InterruptState::IDLE:
                break;
            default:
                return ZX_ERR_BAD_STATE;
            }
            state_ = InterruptState::WAITING;
        }

        {
            ThreadDispatcher::AutoBlocked by(ThreadDispatcher::Blocked::INTERRUPT);
            zx_status_t status = event_wait_deadline(&event_, ZX_TIME_INFINITE, true);
            if (status != ZX_OK) {
                // The event_wait call was interrupted and we need to retry
                // but before we retry we will set the interrupt state
                // back to IDLE if we are still in the WAITING state
                Guard<SpinLock, IrqSave> guard{&spinlock_};
                if (state_ == InterruptState::WAITING) {
                    state_ = InterruptState::IDLE;
                }
                return status;
            }
        }
    }
}

bool InterruptDispatcher::SendPacketLocked(zx_time_t timestamp) {
    bool status = port_dispatcher_->QueueInterruptPacket(&port_packet_, timestamp);
    if (flags_ & INTERRUPT_MASK_POSTWAIT) {
        MaskInterrupt();
    }
    timestamp_ = 0;
    return status;
}

zx_status_t InterruptDispatcher::Trigger(zx_time_t timestamp) {

    if (!(flags_ & INTERRUPT_VIRTUAL))
        return ZX_ERR_BAD_STATE;

    // Using AutoReschedDisable is necessary for correctness to prevent
    // context-switching to the woken thread while holding spinlock_.
    AutoReschedDisable resched_disable;
    resched_disable.Disable();
    Guard<SpinLock, IrqSave> guard{&spinlock_};

    // only record timestamp if this is the first signal since we started waiting
    if (!timestamp_) {
        timestamp_ = timestamp;
    }
    if (state_ == InterruptState::DESTROYED) {
        return ZX_ERR_CANCELED;
    }
    if (state_ == InterruptState::NEEDACK && port_dispatcher_) {
        // Cannot trigger a interrupt without ACK
        // only record timestamp if this is the first signal since we started waiting
        return ZX_OK;
    }

    if (port_dispatcher_) {
        SendPacketLocked(timestamp);
        state_ = InterruptState::NEEDACK;
    } else {
        Signal();
        state_ = InterruptState::TRIGGERED;
    }
    return ZX_OK;
}

void InterruptDispatcher::InterruptHandler() {
    Guard<SpinLock, IrqSave> guard{&spinlock_};

    // only record timestamp if this is the first IRQ since we started waiting
    if (!timestamp_) {
        timestamp_ = current_time();
    }
    if (state_ == InterruptState::NEEDACK && port_dispatcher_) {
        return;
    }
    if (port_dispatcher_) {
        SendPacketLocked(timestamp_);
        state_ = InterruptState::NEEDACK;
    } else {
        if (flags_ & INTERRUPT_MASK_POSTWAIT) {
            MaskInterrupt();
        }
        Signal();
        state_ = InterruptState::TRIGGERED;
    }
}

zx_status_t InterruptDispatcher::Destroy() {
    // Using AutoReschedDisable is necessary for correctness to prevent
    // context-switching to the woken thread while holding spinlock_.
    AutoReschedDisable resched_disable;
    resched_disable.Disable();
    Guard<SpinLock, IrqSave> guard{&spinlock_};

    MaskInterrupt();
    UnregisterInterruptHandler();

    if (port_dispatcher_) {
        bool packet_was_in_queue = port_dispatcher_->RemoveInterruptPacket(&port_packet_);
        if ((state_ == InterruptState::NEEDACK) &&
            !packet_was_in_queue) {
            state_ = InterruptState::DESTROYED;
            return ZX_ERR_NOT_FOUND;
        }
        if ((state_ == InterruptState::IDLE) ||
            ((state_ == InterruptState::NEEDACK) &&
             packet_was_in_queue)) {
            state_ = InterruptState::DESTROYED;
            return ZX_OK;
        }
    } else {
        state_ = InterruptState::DESTROYED;
        Signal();
    }
    return ZX_OK;
}

zx_status_t InterruptDispatcher::Bind(fbl::RefPtr<PortDispatcher> port_dispatcher, uint64_t key) {
    Guard<SpinLock, IrqSave> guard{&spinlock_};
    if (state_ == InterruptState::DESTROYED) {
        return ZX_ERR_CANCELED;
    }
    if (port_dispatcher_) {
        return ZX_ERR_ALREADY_BOUND;
    }
    if (state_ == InterruptState::WAITING) {
        return ZX_ERR_BAD_STATE;
    }

    port_dispatcher_ = fbl::move(port_dispatcher);
    port_packet_.key = key;
    return ZX_OK;
}

zx_status_t InterruptDispatcher::Ack() {
    // Using AutoReschedDisable is necessary for correctness to prevent
    // context-switching to the woken thread while holding spinlock_.
    AutoReschedDisable resched_disable;
    resched_disable.Disable();
    Guard<SpinLock, IrqSave> guard{&spinlock_};
    if (port_dispatcher_ == nullptr) {
        return ZX_ERR_BAD_STATE;
    }
    if (state_ == InterruptState::DESTROYED) {
        return ZX_ERR_CANCELED;
    }
    if (state_ == InterruptState::NEEDACK) {
        if (flags_ & INTERRUPT_UNMASK_PREWAIT) {
            UnmaskInterrupt();
        }
        if (timestamp_) {
            if (!SendPacketLocked(timestamp_)) {
                // We cannot queue another packet here.
                // If we reach here it means that the
                // interrupt packet has not been processed,
                // another interrupt has occurred & then the
                // interrupt was ACK'd
                return ZX_ERR_BAD_STATE;
            }
        } else {
            state_ = InterruptState::IDLE;
        }
    }
    return ZX_OK;
}

void InterruptDispatcher::on_zero_handles() {
    Destroy();
}
