diff --git a/src/device/net/mod.rs b/src/device/net/mod.rs
index fa13b44..8375946 100644
--- a/src/device/net/mod.rs
+++ b/src/device/net/mod.rs
@@ -82,7 +82,7 @@ bitflags! {

 bitflags! {
     #[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
-    struct Status: u16 {
+    pub(crate) struct Status: u16 {
         const LINK_UP = 1;
         const ANNOUNCE = 2;
     }
diff --git a/src/transport/pci/bus.rs b/src/transport/pci/bus.rs
index 0a3014b..52f861e 100644
--- a/src/transport/pci/bus.rs
+++ b/src/transport/pci/bus.rs
@@ -202,7 +202,19 @@ impl PciRoot {
         // resulting pointer is within the MMIO range of the CAM.
         unsafe {
             // Right shift to convert from byte offset to word offset.
-            (self.mmio_base.add((address >> 2) as usize)).write_volatile(data)
+            let ptr = self.mmio_base.add((address >> 2) as usize);
+            #[cfg(not(target_arch = "aarch64"))]
+            {
+                ptr.write_volatile(data)
+            }
+            #[cfg(target_arch = "aarch64")]
+            {
+                core::arch::asm!(
+                    "str {value:w}, [{ptr}]",
+                    value = in(reg) data,
+                    ptr = in(reg) ptr,
+                )
+            }
         }
     }

diff --git a/src/volatile.rs b/src/volatile.rs
index b7059d1..67ebba3 100644
--- a/src/volatile.rs
+++ b/src/volatile.rs
@@ -33,12 +33,14 @@ pub trait VolatileReadable<T> {
     unsafe fn vread(self) -> T;
 }

+#[cfg(not(target_arch = "aarch64"))]
 impl<T: Copy> VolatileReadable<T> for *const ReadOnly<T> {
     unsafe fn vread(self) -> T {
         self.read_volatile().0
     }
 }

+#[cfg(not(target_arch = "aarch64"))]
 impl<T: Copy> VolatileReadable<T> for *const Volatile<T> {
     unsafe fn vread(self) -> T {
         self.read_volatile().0
@@ -51,18 +53,173 @@ pub trait VolatileWritable<T> {
     unsafe fn vwrite(self, value: T);
 }

+#[cfg(not(target_arch = "aarch64"))]
 impl<T: Copy> VolatileWritable<T> for *mut WriteOnly<T> {
     unsafe fn vwrite(self, value: T) {
         (self as *mut T).write_volatile(value)
     }
 }

+#[cfg(not(target_arch = "aarch64"))]
 impl<T: Copy> VolatileWritable<T> for *mut Volatile<T> {
     unsafe fn vwrite(self, value: T) {
         (self as *mut T).write_volatile(value)
     }
 }

+#[cfg(target_arch = "aarch64")]
+mod aarch64_mmio {
+    use super::{ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly};
+    use crate::{device::net::Status, transport::DeviceStatus};
+    use core::arch::asm;
+
+    macro_rules! asm_mmio_write {
+        ($t:ty, $assembly:literal) => {
+            impl VolatileWritable<$t> for *mut WriteOnly<$t> {
+                unsafe fn vwrite(self, value: $t) {
+                    asm!(
+                        $assembly,
+                        value = in(reg) value,
+                        ptr = in(reg) (self as *mut $t),
+                    );
+                }
+            }
+
+            impl VolatileWritable<$t> for *mut Volatile<$t> {
+                unsafe fn vwrite(self, value: $t) {
+                    asm!(
+                        $assembly,
+                        value = in(reg) value,
+                        ptr = in(reg) (self as *mut $t),
+                    );
+                }
+            }
+        };
+    }
+
+    macro_rules! asm_mmio_read {
+        ($t:ty, $assembly:literal) => {
+            impl VolatileReadable<$t> for *const ReadOnly<$t> {
+                unsafe fn vread(self) -> $t {
+                    let value;
+                    asm!(
+                        $assembly,
+                        value = out(reg) value,
+                        ptr = in(reg) (self as *const $t),
+                    );
+                    value
+                }
+            }
+
+            impl VolatileReadable<$t> for *const Volatile<$t> {
+                unsafe fn vread(self) -> $t {
+                    let value;
+                    asm!(
+                        $assembly,
+                        value = out(reg) value,
+                        ptr = in(reg) (self as *const $t),
+                    );
+                    value
+                }
+            }
+        };
+    }
+
+    asm_mmio_write!(u8, "strb {value:w}, [{ptr}]");
+    asm_mmio_write!(u16, "strh {value:w}, [{ptr}]");
+    asm_mmio_write!(u32, "str {value:w}, [{ptr}]");
+    asm_mmio_write!(u64, "str {value:x}, [{ptr}]");
+
+    impl VolatileWritable<DeviceStatus> for *mut WriteOnly<DeviceStatus> {
+        unsafe fn vwrite(self, value: DeviceStatus) {
+            let value: u32 = value.bits();
+            asm!(
+                "str {value:w}, [{ptr}]",
+                value = in(reg) value,
+                ptr = in(reg) (self as *mut u32),
+            );
+        }
+    }
+
+    impl VolatileWritable<DeviceStatus> for *mut Volatile<DeviceStatus> {
+        unsafe fn vwrite(self, value: DeviceStatus) {
+            let value: u32 = value.bits();
+            asm!(
+                "str {value:w}, [{ptr}]",
+                value = in(reg) value,
+                ptr = in(reg) (self as *mut u32),
+            );
+        }
+    }
+
+    asm_mmio_read!(u8, "ldrb {value:w}, [{ptr}]");
+    asm_mmio_read!(u16, "ldrh {value:w}, [{ptr}]");
+    asm_mmio_read!(u32, "ldr {value:w}, [{ptr}]");
+    asm_mmio_read!(u64, "ldr {value:x}, [{ptr}]");
+
+    impl VolatileReadable<DeviceStatus> for *const ReadOnly<DeviceStatus> {
+        unsafe fn vread(self) -> DeviceStatus {
+            let value: u32;
+            asm!(
+                "ldr {value:w}, [{ptr}]",
+                value = out(reg) value,
+                ptr = in(reg) (self as *const u32),
+            );
+            DeviceStatus::from_bits_retain(value)
+        }
+    }
+
+    impl VolatileReadable<DeviceStatus> for *const Volatile<DeviceStatus> {
+        unsafe fn vread(self) -> DeviceStatus {
+            let value: u32;
+            asm!(
+                "ldr {value:w}, [{ptr}]",
+                value = out(reg) value,
+                ptr = in(reg) (self as *const u32),
+            );
+            DeviceStatus::from_bits_retain(value)
+        }
+    }
+
+    impl VolatileReadable<Status> for *const ReadOnly<Status> {
+        unsafe fn vread(self) -> Status {
+            let value: u16;
+            asm!(
+                "ldrh {value:w}, [{ptr}]",
+                value = out(reg) value,
+                ptr = in(reg) (self as *const u16),
+            );
+            Status::from_bits_retain(value)
+        }
+    }
+
+    impl VolatileReadable<Status> for *const Volatile<Status> {
+        unsafe fn vread(self) -> Status {
+            let value: u16;
+            asm!(
+                "ldrh {value:w}, [{ptr}]",
+                value = out(reg) value,
+                ptr = in(reg) (self as *const u16),
+            );
+            Status::from_bits_retain(value)
+        }
+    }
+
+    impl<const SIZE: usize> VolatileReadable<[u8; SIZE]> for *const ReadOnly<[u8; SIZE]> {
+        unsafe fn vread(self) -> [u8; SIZE] {
+            let mut value = [0; SIZE];
+            for i in 0..SIZE {
+                asm!(
+                    "ldrb {value:w}, [{ptr}]",
+                    value = out(reg) value[i],
+                    ptr = in(reg) (self as *const u8).add(i),
+                );
+            }
+            value
+        }
+    }
+}
+
 /// Performs a volatile read from the given field of pointer to a struct representing an MMIO region.
 ///
 /// # Usage
