// 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,
                                      fbl::RefPtr<InterruptDispatcher> interrupt, 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();
}
