// Copyright 2018 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
#pragma once

#include <fbl/canary.h>
#include <fbl/intrusive_double_list.h>
#include <fbl/mutex.h>

#include <kernel/lockdep.h>
#include <vm/pmm.h>

#include "pmm_arena.h"

#define PMM_ENABLE_FREE_FILL 0
#define PMM_FREE_FILL_BYTE 0x42

// per numa node collection of pmm arenas and worker threads
class PmmNode {
public:
    PmmNode();
    ~PmmNode();

    DISALLOW_COPY_ASSIGN_AND_MOVE(PmmNode);

    paddr_t PageToPaddr(const vm_page_t* page) TA_NO_THREAD_SAFETY_ANALYSIS;
    vm_page_t* PaddrToPage(paddr_t addr) TA_NO_THREAD_SAFETY_ANALYSIS;

    // main allocator routines
    zx_status_t AllocPage(uint alloc_flags, vm_page_t** page, paddr_t* pa);
    zx_status_t AllocPages(size_t count, uint alloc_flags, list_node* list);
    zx_status_t AllocRange(paddr_t address, size_t count, list_node* list);
    zx_status_t AllocContiguous(size_t count, uint alloc_flags, uint8_t alignment_log2, paddr_t* pa, list_node* list);
    void FreePage(vm_page* page);
    void FreeList(list_node* list);

    uint64_t CountFreePages() const;
    uint64_t CountTotalBytes() const;

    // printf free and overall state of the internal arenas
    // NOTE: both functions skip mutexes and can be called inside timer or crash context
    // though the data they return may be questionable
    void DumpFree() const TA_NO_THREAD_SAFETY_ANALYSIS;
    void Dump(bool is_panic) const TA_NO_THREAD_SAFETY_ANALYSIS;

#if PMM_ENABLE_FREE_FILL
    void EnforceFill() TA_NO_THREAD_SAFETY_ANALYSIS;
#endif

    zx_status_t AddArena(const pmm_arena_info_t* info);

    // add new pages to the free queue. used when boostrapping a PmmArena
    void AddFreePages(list_node* list);

private:
    void FreePageHelperLocked(vm_page* page) TA_REQ(lock_);
    void FreeListLocked(list_node* list) TA_REQ(lock_);

    fbl::Canary<fbl::magic("PNOD")> canary_;

    mutable DECLARE_MUTEX(PmmNode) lock_;

    uint64_t arena_cumulative_size_ TA_GUARDED(lock_) = 0;
    uint64_t free_count_ TA_GUARDED(lock_) = 0;

    fbl::DoublyLinkedList<PmmArena*> arena_list_ TA_GUARDED(lock_);

    // page queues
    list_node free_list_ TA_GUARDED(lock_) = LIST_INITIAL_VALUE(free_list_);
    list_node inactive_list_ TA_GUARDED(lock_) = LIST_INITIAL_VALUE(inactive_list_);
    list_node active_list_ TA_GUARDED(lock_) = LIST_INITIAL_VALUE(active_list_);
    list_node modified_list_ TA_GUARDED(lock_) = LIST_INITIAL_VALUE(modified_list_);
    list_node wired_list_ TA_GUARDED(lock_) = LIST_INITIAL_VALUE(wired_list_);

#if PMM_ENABLE_FREE_FILL
    void FreeFill(vm_page_t* page);
    void CheckFreeFill(vm_page_t* page);

    bool enforce_fill_ = false;
#endif
};

// We don't need to hold the arena lock while executing this, since it is
// only accesses values that are set once during system initialization.
inline vm_page_t* PmmNode::PaddrToPage(paddr_t addr) TA_NO_THREAD_SAFETY_ANALYSIS {
    for (auto& a : arena_list_) {
        if (a.address_in_arena(addr)) {
            size_t index = (addr - a.base()) / PAGE_SIZE;
            return a.get_page(index);
        }
    }
    return nullptr;
}
