|
@@ -1,6 +1,6 @@
|
|
|
use crate::{Tag, TagTrait, TagType, TagTypeId};
|
|
|
use core::convert::TryInto;
|
|
|
-use core::fmt::Debug;
|
|
|
+use core::fmt::{Debug, Formatter};
|
|
|
use core::marker::PhantomData;
|
|
|
use core::mem;
|
|
|
|
|
@@ -84,17 +84,17 @@ impl StructAsBytes for MemoryMapTag {
|
|
|
pub struct MemoryArea {
|
|
|
base_addr: u64,
|
|
|
length: u64,
|
|
|
- typ: MemoryAreaType,
|
|
|
+ typ: MemoryAreaTypeId,
|
|
|
_reserved: u32,
|
|
|
}
|
|
|
|
|
|
impl MemoryArea {
|
|
|
/// Create a new MemoryArea.
|
|
|
- pub fn new(base_addr: u64, length: u64, typ: MemoryAreaType) -> Self {
|
|
|
+ pub fn new(base_addr: u64, length: u64, typ: impl Into<MemoryAreaTypeId>) -> Self {
|
|
|
Self {
|
|
|
base_addr,
|
|
|
length,
|
|
|
- typ,
|
|
|
+ typ: typ.into(),
|
|
|
_reserved: 0,
|
|
|
}
|
|
|
}
|
|
@@ -115,7 +115,7 @@ impl MemoryArea {
|
|
|
}
|
|
|
|
|
|
/// The type of the memory region.
|
|
|
- pub fn typ(&self) -> MemoryAreaType {
|
|
|
+ pub fn typ(&self) -> MemoryAreaTypeId {
|
|
|
self.typ
|
|
|
}
|
|
|
}
|
|
@@ -127,28 +127,100 @@ impl StructAsBytes for MemoryArea {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/// An enum of possible reported region types.
|
|
|
-/// Inside the Multiboot2 spec this is kind of hidden
|
|
|
-/// inside the implementation of `struct multiboot_mmap_entry`.
|
|
|
+/// ABI-friendly version of [`MemoryAreaType`].
|
|
|
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
|
+#[repr(C)]
|
|
|
+pub struct MemoryAreaTypeId(u32);
|
|
|
+
|
|
|
+impl From<u32> for MemoryAreaTypeId {
|
|
|
+ fn from(value: u32) -> Self {
|
|
|
+ Self(value)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<MemoryAreaTypeId> for u32 {
|
|
|
+ fn from(value: MemoryAreaTypeId) -> Self {
|
|
|
+ value.0
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl Debug for MemoryAreaTypeId {
|
|
|
+ fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
|
|
|
+ let mt = MemoryAreaType::from(*self);
|
|
|
+ Debug::fmt(&mt, f)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+/// Abstraction over defined memory types for the memory map as well as custom
|
|
|
+/// ones. Types 1 to 5 are defined in the Multiboot2 spec and correspond to the
|
|
|
+/// entry types of e820 memory maps.
|
|
|
+///
|
|
|
+/// This is not binary compatible with the Multiboot2 spec. Please use
|
|
|
+/// [`MemoryAreaTypeId`] instead.
|
|
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
|
-#[repr(u32)]
|
|
|
pub enum MemoryAreaType {
|
|
|
/// Available memory free to be used by the OS.
|
|
|
- Available = 1,
|
|
|
+ Available, /* 1 */
|
|
|
|
|
|
/// A reserved area that must not be used.
|
|
|
- Reserved = 2,
|
|
|
+ Reserved, /* 2, */
|
|
|
|
|
|
/// Usable memory holding ACPI information.
|
|
|
- AcpiAvailable = 3,
|
|
|
+ AcpiAvailable, /* 3, */
|
|
|
|
|
|
/// Reserved memory which needs to be preserved on hibernation.
|
|
|
/// Also called NVS in spec, which stands for "Non-Volatile Sleep/Storage",
|
|
|
/// which is part of ACPI specification.
|
|
|
- ReservedHibernate = 4,
|
|
|
+ ReservedHibernate, /* 4, */
|
|
|
|
|
|
/// Memory which is occupied by defective RAM modules.
|
|
|
- Defective = 5,
|
|
|
+ Defective, /* = 5, */
|
|
|
+
|
|
|
+ /// Custom memory map type.
|
|
|
+ Custom(u32),
|
|
|
+}
|
|
|
+
|
|
|
+impl From<MemoryAreaTypeId> for MemoryAreaType {
|
|
|
+ fn from(value: MemoryAreaTypeId) -> Self {
|
|
|
+ match value.0 {
|
|
|
+ 1 => Self::Available,
|
|
|
+ 2 => Self::Reserved,
|
|
|
+ 3 => Self::AcpiAvailable,
|
|
|
+ 4 => Self::ReservedHibernate,
|
|
|
+ 5 => Self::Defective,
|
|
|
+ val => Self::Custom(val),
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl From<MemoryAreaType> for MemoryAreaTypeId {
|
|
|
+ fn from(value: MemoryAreaType) -> Self {
|
|
|
+ let integer = match value {
|
|
|
+ MemoryAreaType::Available => 1,
|
|
|
+ MemoryAreaType::Reserved => 2,
|
|
|
+ MemoryAreaType::AcpiAvailable => 3,
|
|
|
+ MemoryAreaType::ReservedHibernate => 4,
|
|
|
+ MemoryAreaType::Defective => 5,
|
|
|
+ MemoryAreaType::Custom(val) => val,
|
|
|
+ };
|
|
|
+ integer.into()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl PartialEq<MemoryAreaType> for MemoryAreaTypeId {
|
|
|
+ fn eq(&self, other: &MemoryAreaType) -> bool {
|
|
|
+ let val: MemoryAreaTypeId = (*other).into();
|
|
|
+ let val: u32 = val.0;
|
|
|
+ self.0.eq(&val)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+impl PartialEq<MemoryAreaTypeId> for MemoryAreaType {
|
|
|
+ fn eq(&self, other: &MemoryAreaTypeId) -> bool {
|
|
|
+ let val: MemoryAreaTypeId = (*self).into();
|
|
|
+ let val: u32 = val.0;
|
|
|
+ other.0.eq(&val)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/// Basic memory info tag.
|