#[repr(C)]
pub enum MemoryType {
    ReservedMemoryType,
    LoaderCode,
    BootServicesCode,
    BootServicesData,
    RuntimeServicesCode,
    RuntimeServiceData,
    ConventionalMemory,
    UnusableMemory,
    ACPIReclaimMemory,
    APCIMemoryNVS,
    MemoryMappedIO,
    MemoryMappedIOPortSpace,
    PalCode,
    PersistentMemory,
    UnacceptedMemoryType,
    MaxMemoryType,
}

pub type PhysicalAddress = u64;
pub type VirtualAddress = u64;

#[repr(C)]
pub struct MemoryDescriptor {
    r#type: u32,
    physical_start: PhysicalAddress,
    virtual_start: VirtualAddress,
    number_of_pages: u64,
    attribute: Attribute,
}

#[repr(C)]
pub enum AllocateType {
    /// Allocation requests of Type AllocateAnyPages allocate any available range of pages that satisfies the request. On input, the address pointed to by Memory is ignored.
    AllocateAnyPages,
    /// Allocation requests of Type AllocateMaxAddress allocate any available range of pages whose uppermost address is less than or equal to the address pointed to by Memory on input.
    AllocateMaxAddress,
    /// Allocation requests of Type AllocateAddress allocate pages at the address pointed to by Memory on input.
    AllocateAddress,
    MaxAllocateType,
}

#[repr(u64)]
pub enum Attribute {
    /// The memory region supports being configured as not cacheable.
    MemoryUC = 0x0000000000000001,
    /// The memory region supports being configured as write combining.
    MemoryWC = 0x0000000000000002,
    /// The memory region supports being configured as cacheable with a “write through” policy. Writes that hit in the cache will also be written to main memory.
    MemoryWT = 0x0000000000000004,
    /// The memory region supports being configured as cacheable with a “write back” policy. Reads and writes that hit in the cache do not propagate to main memory. Dirty data is written back to main memory when a new cache line is allocated.
    MemoryWB = 0x0000000000000008,
    /// The memory region supports being configured as not cacheable, exported, and supports the “fetch and add” semaphore mechanism.
    MemoryUCE = 0x0000000000000010,
    /// Physical memory protection attribute: The memory region supports being configured as write protected by system hardware. This is typically used as a cacheability attribute today. The memory region supports being configured as cacheable with a “write protected” policy. Reads come from cache lines when possible, and read misses cause cache fills. Writes are propagated to the system bus and cause corresponding cache lines on all processors on the bus to be invalidated.
    MemoryWP = 0x0000000000001000,
    /// Physical memory protection attribute: The memory region supports being configured as read- protected by system hardware.
    MemoryRP = 0x0000000000002000,
    /// Physical memory protection attribute: The memory region supports being configured so it is protected by system hardware from executing code.
    MemoryXP = 0x0000000000004000,
    /// Runtime memory attribute: The memory region refers to persistent memory
    MemoryNV = 0x0000000000008000,
    /// The memory region provides higher reliability relative to other memory in the system. If all memory has the same reliability, then this bit is not used.
    MemoryMoreReliable = 0x0000000000010000,
    /// Physical memory protection attribute: The memory region supports making this memory range read-only by system hardware.
    MemoryRO = 0x0000000000020000,
    /// Specific-purpose memory (SPM). The memory is earmarked for specific purposes such as for specific device drivers or applications. The SPM attribute serves as a hint to the OS to avoid allocating this memory for core OS data or code that can not be relocated. Prolonged use of this memory for purposes other than the intended purpose may result in suboptimal platform performance.
    MemorySP = 0x0000000000040000,
    /// If this flag is set, the memory region is capable of being protected with the CPU’s memory cryptographic capabilities. If this flag is clear, the memory region is not capable of being protected with the CPU’s memory cryptographic capabilities or the CPU does not support CPU memory cryptographic capabilities.
    MemoryCpuCrypto = 0x0000000000080000,
    /// Runtime memory attribute: The memory region needs to be given a virtual mapping by the operating system when SetVirtualAddressMap() is called (described in Virtual Memory Services.
    MemoryRuntime = 0x8000000000000000,
    /// If this flag is set, the memory region is described with additional ISA-specific memory attributes as specified in EFI_MEMORY_ISA_MASK
    MemoryISAValid = 0x4000000000000000,
    /// Defines the bits reserved for describing optional ISA-specific cacheability attributes that are not covered by the standard UEFI Memory Attributes cacheability bits (EFI_MEMORY_UC, EFI_MEMORY_WC, EFI_MEMORY_WT, EFI_MEMORY_WB and EFI_MEMORY_UCE). See Calling Conventions for further ISA-specific enumeration of these bits.
    MemoryISAMask = 0x0FFFF00000000000,
}
