aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-06-11 23:14:04 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-06-11 23:14:04 +0000
commitdf748b6fb99607e4efede023d477f325f300d557 (patch)
tree99bfd8028072b55eb00c53b2ecb1196a770ab441
parent1e156af2fd18080b53d748d706d0050a4544dbf6 (diff)
parent37a3fb637b6c5b296d843e1c96e7918a96ae9fd0 (diff)
downloadvirtio-drivers-sdk-release.tar.gz
Snap for 11955768 from 37a3fb637b6c5b296d843e1c96e7918a96ae9fd0 to sdk-releasesdk-release
Change-Id: I159dc92fdbb314b6972280914f68b3f2c8656169
-rw-r--r--patches/Android.bp.patch27
-rw-r--r--patches/mmio.patch231
-rw-r--r--src/device/net.rs2
-rw-r--r--src/transport/pci/bus.rs14
-rw-r--r--src/volatile.rs157
5 files changed, 426 insertions, 5 deletions
diff --git a/patches/Android.bp.patch b/patches/Android.bp.patch
index 2a063c6..d2c3c5b 100644
--- a/patches/Android.bp.patch
+++ b/patches/Android.bp.patch
@@ -1,8 +1,15 @@
diff --git a/Android.bp b/Android.bp
-index e2b5dd5..6132b98 100644
+index 81021c8..916b74c 100644
--- a/Android.bp
+++ b/Android.bp
-@@ -30,8 +30,8 @@ rust_library_rlib {
+@@ -25,22 +25,22 @@ license {
+ rust_library_rlib {
+ name: "libvirtio_drivers",
+ crate_name: "virtio_drivers",
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.7.1",
+ crate_root: "src/lib.rs",
+ edition: "2018",
features: ["alloc"],
rustlibs: [
"libbitflags",
@@ -13,7 +20,21 @@ index e2b5dd5..6132b98 100644
],
apex_available: [
"//apex_available:platform",
-@@ -58,6 +58,6 @@ rust_test {
+ "//apex_available:anyapex",
+ ],
+ prefer_rlib: true,
+ no_stdlibs: true,
+ stdlibs: [
+ "libcompiler_builtins.rust_sysroot",
+ "libcore.rust_sysroot",
+@@ -53,13 +53,13 @@ rust_test {
+ cargo_env_compat: true,
+ cargo_pkg_version: "0.7.1",
+ crate_root: "src/lib.rs",
+ test_suites: ["general-tests"],
+ auto_gen_config: true,
+ edition: "2018",
+ features: ["alloc"],
rustlibs: [
"libbitflags",
"liblog_rust",
diff --git a/patches/mmio.patch b/patches/mmio.patch
new file mode 100644
index 0000000..8e684f6
--- /dev/null
+++ b/patches/mmio.patch
@@ -0,0 +1,231 @@
+diff --git a/src/device/net.rs b/src/device/net.rs
+index b32cd72..c7732a4 100644
+--- a/src/device/net.rs
++++ b/src/device/net.rs
+@@ -340,7 +340,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..af7ef27 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),
++ );
++ }
++ value
++ }
++ }
++}
++
+ /// Performs a volatile read from the given field of pointer to a struct representing an MMIO region.
+ ///
+ /// # Usage
diff --git a/src/device/net.rs b/src/device/net.rs
index b32cd72..c7732a4 100644
--- a/src/device/net.rs
+++ b/src/device/net.rs
@@ -340,7 +340,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..af7ef27 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),
+ );
+ }
+ value
+ }
+ }
+}
+
/// Performs a volatile read from the given field of pointer to a struct representing an MMIO region.
///
/// # Usage