// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ADDRESS_MANAGER_H_
#define ADDRESS_MANAGER_H_

#include <zircon/compiler.h>

#include <condition_variable>
#include <mutex>
#include <vector>

#include "address_space.h"
#include "msd_arm_atom.h"
#include "msd_arm_connection.h"
#include "registers.h"

// The address manager can be modified by the device thread (to assign and
// unassign address spaces from registers before mapping and unmapping them)
// and by the connection thread that owns an address space, to ensure that
// the page mappings are flushed properly.
class AddressManager final : public AddressSpaceObserver {
public:
    class Owner {
    public:
        virtual magma::RegisterIo* register_io() = 0;
    };

    AddressManager(Owner* owner, uint32_t address_slot_count);

    // Used to clear all address mappings if the hardware will be reset. It
    // waits until all current address-space operations are done, and ensures no
    // more will start.
    void ClearAddressMappings(bool force_expire);

    bool AssignAddressSpace(MsdArmAtom* atom);

    void AtomFinished(MsdArmAtom* atom);

    std::shared_ptr<AddressSlotMapping> GetMappingForSlot(uint32_t slot);

    std::shared_ptr<AddressSlotMapping>
    AllocateMappingForAddressSpace(std::shared_ptr<MsdArmConnection> connection);

    // AddressSpaceObserver implementation.
    void FlushAddressMappingRange(AddressSpace*, uint64_t start, uint64_t length,
                                  bool synchronous) override;
    void ReleaseSpaceMappings(const AddressSpace* address_space) override;

    void UnlockAddressSpace(AddressSpace*) override;

    void set_acquire_slot_timeout_seconds(uint32_t timeout)
    {
        acquire_slot_timeout_seconds_ = timeout;
    }

private:
    // AddressSlots handle the mappings between AddressSpaces and the hardware
    // registers.
    struct AddressSlot {
        std::weak_ptr<AddressSlotMapping> mapping;

        // This is the AddressSpace* that the slot is attached to.  Will be
        // set to null by AddressSpace destructor if this is attached to an
        // address space. This can't be a weak pointer because we need to
        // compare against it in the AddressSpace destructor.
        const void* address_space = nullptr;
    };

    // A HardwareSlot handles the registers for a specific address space. Each
    // slot has its own lock because flushing a slot can take a long time and we
    // want to be able to flush multiple slots in parallel.
    struct HardwareSlot {
        HardwareSlot(uint32_t slot) : registers(slot) {}

        void FlushMmuRange(magma::RegisterIo* io, uint64_t start, uint64_t length, bool synchronous)
            __TA_REQUIRES(lock);
        // Wait for the MMU to finish processing any existing commands.
        void WaitForMmuIdle(magma::RegisterIo* io) __TA_REQUIRES(lock);
        void InvalidateSlot(magma::RegisterIo* io) __TA_REQUIRES(lock);
        void UnlockMmu(magma::RegisterIo* io) __TA_REQUIRES(lock);

        std::mutex lock; // This lock should only be taken while address_slot_lock_ is held.
        __TA_GUARDED(lock) registers::AsRegisters registers;
    };

    std::shared_ptr<AddressSlotMapping>
    GetMappingForAddressSpaceUnlocked(const AddressSpace* address_space)
        __TA_REQUIRES(address_slot_lock_);
    std::shared_ptr<AddressSlotMapping> AssignToSlot(std::shared_ptr<MsdArmConnection> connection,
                                                     uint32_t slot)
        __TA_REQUIRES(address_slot_lock_);

    Owner* owner_;
    uint32_t acquire_slot_timeout_seconds_ = 10;
    std::mutex address_slot_lock_;
    __TA_GUARDED(address_slot_lock_) std::vector<AddressSlot> address_slots_;
    std::condition_variable address_slot_free_;

    // Before a slot is modified, the corresponding lock should be taken.
    // It should only be taken while address_slot_lock_ is
    // locked.
    std::vector<std::unique_ptr<HardwareSlot>> registers_;
};

#endif // ADDRESS_MANAGER_H_
