root/headers/private/kernel/vm/VMTranslationMap.h
/*
 * Copyright 2002-2010, Haiku. All rights reserved.
 * Distributed under the terms of the MIT License.
 *
 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
 * Distributed under the terms of the NewOS License.
 */
#ifndef KERNEL_VM_VM_TRANSLATION_MAP_H
#define KERNEL_VM_VM_TRANSLATION_MAP_H


#include <kernel.h>
#include <lock.h>
#include <smp.h>

#include <vm/VMArea.h>


struct kernel_args;
struct vm_page_reservation;


struct VMTranslationMap {
                        struct ReverseMappingInfoCallback;

public:
                                                                VMTranslationMap();
        virtual                                         ~VMTranslationMap();

        virtual bool                            Lock() = 0;
        virtual void                            Unlock() = 0;

        virtual addr_t                          MappedSize() const = 0;
        virtual size_t                          MaxPagesNeededToMap(addr_t start,
                                                                        addr_t end) const = 0;

        virtual status_t                        Map(addr_t virtualAddress,
                                                                        phys_addr_t physicalAddress,
                                                                        uint32 attributes, uint32 memoryType,
                                                                        vm_page_reservation* reservation) = 0;
        virtual status_t                        Unmap(addr_t start, addr_t end) = 0;

        // map not locked
        virtual status_t                        UnmapPage(VMArea* area, addr_t address,
                                                                        bool updatePageQueue,
                                                                        bool deletingAddressSpace = false,
                                                                        uint32* _flags = NULL) = 0;
        virtual void                            UnmapPages(VMArea* area, addr_t base,
                                                                        size_t size, bool updatePageQueue,
                                                                        bool deletingAddressSpace = false);
        virtual void                            UnmapArea(VMArea* area,
                                                                        bool deletingAddressSpace,
                                                                        bool ignoreTopCachePageFlags);

        virtual status_t                        Query(addr_t virtualAddress,
                                                                        phys_addr_t* _physicalAddress,
                                                                        uint32* _flags) = 0;
        virtual status_t                        QueryInterrupt(addr_t virtualAddress,
                                                                        phys_addr_t* _physicalAddress,
                                                                        uint32* _flags) = 0;

        virtual status_t                        Protect(addr_t base, addr_t top,
                                                                        uint32 attributes, uint32 memoryType) = 0;
                        status_t                        ProtectPage(VMArea* area, addr_t address,
                                                                        uint32 attributes);
                        status_t                        ProtectArea(VMArea* area,
                                                                        uint32 attributes);

        virtual status_t                        ClearFlags(addr_t virtualAddress,
                                                                        uint32 flags) = 0;

        virtual bool                            ClearAccessedAndModified(
                                                                        VMArea* area, addr_t address,
                                                                        bool unmapIfUnaccessed,
                                                                        bool& _modified) = 0;

        virtual void                            Flush() = 0;

        // backends for KDL commands
        virtual void                            DebugPrintMappingInfo(addr_t virtualAddress);
        virtual bool                            DebugGetReverseMappingInfo(
                                                                        phys_addr_t physicalAddress,
                                                                        ReverseMappingInfoCallback& callback);

protected:
                        void                            PageUnmapped(VMArea* area,
                                                                        page_num_t pageNumber, bool accessed,
                                                                        bool modified, bool updatePageQueue,
                                                                        VMAreaMappings* mappingsQueue = NULL);
                        void                            UnaccessedPageUnmapped(VMArea* area,
                                                                        page_num_t pageNumber);

        static  void                            InvalidateUserTLB(CPUSet cpus, intptr_t context);
        static  void                            InvalidateTLBList(CPUSet cpus, intptr_t context,
                                                                        addr_t* invalidPages, int32 count);

protected:
                        recursive_lock          fLock;
                        int32                           fMapCount;
};


struct VMTranslationMap::ReverseMappingInfoCallback {
        virtual                                         ~ReverseMappingInfoCallback();

        virtual bool                            HandleVirtualAddress(addr_t virtualAddress) = 0;
};


struct VMPhysicalPageMapper {
                                                                VMPhysicalPageMapper();
        virtual                                         ~VMPhysicalPageMapper();

        // get/put virtual address for physical page -- will be usuable on all CPUs
        // (usually more expensive than the *_current_cpu() versions)
        virtual status_t                        GetPage(phys_addr_t physicalAddress,
                                                                        addr_t* _virtualAddress,
                                                                        void** _handle) = 0;
        virtual status_t                        PutPage(addr_t virtualAddress,
                                                                        void* handle) = 0;

        // get/put virtual address for physical page -- thread must be pinned the
        // whole time
        virtual status_t                        GetPageCurrentCPU(
                                                                        phys_addr_t physicalAddress,
                                                                        addr_t* _virtualAddress,
                                                                        void** _handle) = 0;
        virtual status_t                        PutPageCurrentCPU(addr_t virtualAddress,
                                                                        void* _handle) = 0;

        // get/put virtual address for physical in KDL
        virtual status_t                        GetPageDebug(phys_addr_t physicalAddress,
                                                                        addr_t* _virtualAddress,
                                                                        void** _handle) = 0;
        virtual status_t                        PutPageDebug(addr_t virtualAddress,
                                                                        void* handle) = 0;

        // memory operations on pages
        virtual status_t                        MemsetPhysical(phys_addr_t address, int value,
                                                                        phys_size_t length) = 0;
        virtual status_t                        MemcpyFromPhysical(void* to, phys_addr_t from,
                                                                        size_t length, bool user) = 0;
        virtual status_t                        MemcpyToPhysical(phys_addr_t to,
                                                                        const void* from, size_t length,
                                                                        bool user) = 0;
        virtual void                            MemcpyPhysicalPage(phys_addr_t to,
                                                                        phys_addr_t from) = 0;
};



inline status_t
VMTranslationMap::ProtectPage(VMArea* area, addr_t address, uint32 attributes)
{
        return Protect(address, address + B_PAGE_SIZE - 1, attributes,
                area->MemoryType());
}


inline status_t
VMTranslationMap::ProtectArea(VMArea* area, uint32 attributes)
{
        return Protect(area->Base(), area->Base() + area->Size() - 1, attributes,
                area->MemoryType());
}


#include <arch/vm_translation_map.h>

#endif  /* KERNEL_VM_VM_TRANSLATION_MAP_H */