// 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;
    void CountTotalStates(uint64_t state_count[VM_PAGE_STATE_COUNT_]) 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 FreePageLocked(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;
}
