diff options
Diffstat (limited to 'rust/hw/char/pl011')
| -rw-r--r-- | rust/hw/char/pl011/Cargo.lock | 134 | ||||
| -rw-r--r-- | rust/hw/char/pl011/Cargo.toml | 3 | ||||
| -rw-r--r-- | rust/hw/char/pl011/src/device.rs | 162 | ||||
| -rw-r--r-- | rust/hw/char/pl011/src/device_class.rs | 80 | ||||
| -rw-r--r-- | rust/hw/char/pl011/src/lib.rs | 6 | ||||
| -rw-r--r-- | rust/hw/char/pl011/src/memory_ops.rs | 24 |
6 files changed, 197 insertions, 212 deletions
diff --git a/rust/hw/char/pl011/Cargo.lock b/rust/hw/char/pl011/Cargo.lock deleted file mode 100644 index b58cebb186..0000000000 --- a/rust/hw/char/pl011/Cargo.lock +++ /dev/null @@ -1,134 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "arbitrary-int" -version = "1.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84fc003e338a6f69fbd4f7fe9f92b535ff13e9af8997f3b14b6ddff8b1df46d" - -[[package]] -name = "bilge" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e67b57" -dependencies = [ - "arbitrary-int", - "bilge-impl", -] - -[[package]] -name = "bilge-impl" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000adb2d8" -dependencies = [ - "itertools", - "proc-macro-error", - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "either" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3dca9240753cf90908d7e4aac30f630662b02aebaa1b58a3cadabdb23385b58b" - -[[package]] -name = "itertools" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" -dependencies = [ - "either", -] - -[[package]] -name = "pl011" -version = "0.1.0" -dependencies = [ - "bilge", - "bilge-impl", - "qemu_api", - "qemu_api_macros", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.84" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96c6a92621310b51366f1e28d05ef11489516e93be030060e5fc12024a49d6" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "qemu_api" -version = "0.1.0" - -[[package]] -name = "qemu_api_macros" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "quote" -version = "1.0.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "syn" -version = "2.0.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" diff --git a/rust/hw/char/pl011/Cargo.toml b/rust/hw/char/pl011/Cargo.toml index b089e3dded..a373906b9f 100644 --- a/rust/hw/char/pl011/Cargo.toml +++ b/rust/hw/char/pl011/Cargo.toml @@ -21,6 +21,3 @@ bilge = { version = "0.2.0" } bilge-impl = { version = "0.2.0" } qemu_api = { path = "../../../qemu-api" } qemu_api_macros = { path = "../../../qemu-api-macros" } - -# Do not include in any global workspace -[workspace] diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index c7193b41be..2a85960b81 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -2,14 +2,17 @@ // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> // SPDX-License-Identifier: GPL-2.0-or-later -use core::{ - ffi::{c_int, c_uchar, c_uint, c_void, CStr}, - ptr::{addr_of, addr_of_mut, NonNull}, +use core::ptr::{addr_of, addr_of_mut, NonNull}; +use std::{ + ffi::CStr, + os::raw::{c_int, c_uchar, c_uint, c_void}, }; use qemu_api::{ bindings::{self, *}, + c_str, definitions::ObjectImpl, + device_class::TYPE_SYS_BUS_DEVICE, }; use crate::{ @@ -18,15 +21,42 @@ use crate::{ RegisterOffset, }; -static PL011_ID_ARM: [c_uchar; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; +/// Integer Baud Rate Divider, `UARTIBRD` +const IBRD_MASK: u32 = 0xffff; + +/// Fractional Baud Rate Divider, `UARTFBRD` +const FBRD_MASK: u32 = 0x3f; const DATA_BREAK: u32 = 1 << 10; /// QEMU sourced constant. pub const PL011_FIFO_DEPTH: usize = 16_usize; +#[derive(Clone, Copy, Debug)] +enum DeviceId { + #[allow(dead_code)] + Arm = 0, + Luminary, +} + +impl std::ops::Index<hwaddr> for DeviceId { + type Output = c_uchar; + + fn index(&self, idx: hwaddr) -> &Self::Output { + match self { + Self::Arm => &Self::PL011_ID_ARM[idx as usize], + Self::Luminary => &Self::PL011_ID_LUMINARY[idx as usize], + } + } +} + +impl DeviceId { + const PL011_ID_ARM: [c_uchar; 8] = [0x11, 0x10, 0x14, 0x00, 0x0d, 0xf0, 0x05, 0xb1]; + const PL011_ID_LUMINARY: [c_uchar; 8] = [0x11, 0x00, 0x18, 0x01, 0x0d, 0xf0, 0x05, 0xb1]; +} + #[repr(C)] -#[derive(Debug, qemu_api_macros::Object)] +#[derive(Debug, qemu_api_macros::Object, qemu_api_macros::offsets)] /// PL011 Device Model in QEMU pub struct PL011State { pub parent_obj: SysBusDevice, @@ -69,6 +99,8 @@ pub struct PL011State { pub clock: NonNull<Clock>, #[doc(alias = "migrate_clk")] pub migrate_clock: bool, + /// The byte string that identifies the device. + device_id: DeviceId, } impl ObjectImpl for PL011State { @@ -88,17 +120,13 @@ pub struct PL011Class { } impl qemu_api::definitions::Class for PL011Class { - const CLASS_INIT: Option< - unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut core::ffi::c_void), - > = Some(crate::device_class::pl011_class_init); + const CLASS_INIT: Option<unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void)> = + Some(crate::device_class::pl011_class_init); const CLASS_BASE_INIT: Option< - unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut core::ffi::c_void), + unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void), > = None; } -#[used] -pub static CLK_NAME: &CStr = c"clk"; - impl PL011State { /// Initializes a pre-allocated, unitialized instance of `PL011State`. /// @@ -108,7 +136,9 @@ impl PL011State { /// `PL011State` type. It must not be called more than once on the same /// location/instance. All its fields are expected to hold unitialized /// values with the sole exception of `parent_obj`. - pub unsafe fn init(&mut self) { + unsafe fn init(&mut self) { + const CLK_NAME: &CStr = c_str!("clk"); + let dev = addr_of_mut!(*self).cast::<DeviceState>(); // SAFETY: // @@ -148,23 +178,18 @@ impl PL011State { } } - pub fn read( - &mut self, - offset: hwaddr, - _size: core::ffi::c_uint, - ) -> std::ops::ControlFlow<u64, u64> { + pub fn read(&mut self, offset: hwaddr, _size: c_uint) -> std::ops::ControlFlow<u64, u64> { use RegisterOffset::*; std::ops::ControlFlow::Break(match RegisterOffset::try_from(offset) { Err(v) if (0x3f8..0x400).contains(&v) => { - u64::from(PL011_ID_ARM[((offset - 0xfe0) >> 2) as usize]) + u64::from(self.device_id[(offset - 0xfe0) >> 2]) } Err(_) => { // qemu_log_mask(LOG_GUEST_ERROR, "pl011_read: Bad offset 0x%x\n", (int)offset); 0 } Ok(DR) => { - // s->flags &= ~PL011_FLAG_RXFF; self.flags.set_receive_fifo_full(false); let c = self.read_fifo[self.read_pos]; if self.read_count > 0 { @@ -172,11 +197,9 @@ impl PL011State { self.read_pos = (self.read_pos + 1) & (self.fifo_depth() - 1); } if self.read_count == 0 { - // self.flags |= PL011_FLAG_RXFE; self.flags.set_receive_fifo_empty(true); } if self.read_count + 1 == self.read_trigger { - //self.int_level &= ~ INT_RX; self.int_level &= !registers::INT_RX; } // Update error bits. @@ -346,13 +369,6 @@ impl PL011State { * dealt with here. */ - //fr = s->flags & ~(PL011_FLAG_RI | PL011_FLAG_DCD | - // PL011_FLAG_DSR | PL011_FLAG_CTS); - //fr |= (cr & CR_OUT2) ? PL011_FLAG_RI : 0; - //fr |= (cr & CR_OUT1) ? PL011_FLAG_DCD : 0; - //fr |= (cr & CR_RTS) ? PL011_FLAG_CTS : 0; - //fr |= (cr & CR_DTR) ? PL011_FLAG_DSR : 0; - // self.flags.set_ring_indicator(self.control.out_2()); self.flags.set_data_carrier_detect(self.control.out_1()); self.flags.set_clear_to_send(self.control.request_to_send()); @@ -363,10 +379,6 @@ impl PL011State { let mut il = self.int_level; il &= !Interrupt::MS; - //il |= (fr & PL011_FLAG_DSR) ? INT_DSR : 0; - //il |= (fr & PL011_FLAG_DCD) ? INT_DCD : 0; - //il |= (fr & PL011_FLAG_CTS) ? INT_CTS : 0; - //il |= (fr & PL011_FLAG_RI) ? INT_RI : 0; if self.flags.data_set_ready() { il |= Interrupt::DSR as u32; @@ -472,10 +484,8 @@ impl PL011State { let slot = (self.read_pos + self.read_count) & (depth - 1); self.read_fifo[slot] = value; self.read_count += 1; - // s->flags &= ~PL011_FLAG_RXFE; self.flags.set_receive_fifo_empty(false); if self.read_count == depth { - //s->flags |= PL011_FLAG_RXFF; self.flags.set_receive_fifo_full(true); } @@ -492,6 +502,27 @@ impl PL011State { unsafe { qemu_set_irq(*irq, i32::from(flags & i != 0)) }; } } + + pub fn post_load(&mut self, _version_id: u32) -> Result<(), ()> { + /* Sanity-check input state */ + if self.read_pos >= self.read_fifo.len() || self.read_count > self.read_fifo.len() { + return Err(()); + } + + if !self.fifo_enabled() && self.read_count > 0 && self.read_pos > 0 { + // Older versions of PL011 didn't ensure that the single + // character in the FIFO in FIFO-disabled mode is in + // element 0 of the array; convert to follow the current + // code's assumptions. + self.read_fifo[0] = self.read_fifo[self.read_pos]; + self.read_pos = 0; + } + + self.ibrd &= IBRD_MASK; + self.fbrd &= FBRD_MASK; + + Ok(()) + } } /// Which bits in the interrupt status matter for each outbound IRQ line ? @@ -514,7 +545,6 @@ pub const IRQMASK: [u32; 6] = [ /// We expect the FFI user of this function to pass a valid pointer, that has /// the same size as [`PL011State`]. We also expect the device is /// readable/writeable from one thread at any time. -#[no_mangle] pub unsafe extern "C" fn pl011_can_receive(opaque: *mut c_void) -> c_int { unsafe { debug_assert!(!opaque.is_null()); @@ -530,12 +560,7 @@ pub unsafe extern "C" fn pl011_can_receive(opaque: *mut c_void) -> c_int { /// readable/writeable from one thread at any time. /// /// The buffer and size arguments must also be valid. -#[no_mangle] -pub unsafe extern "C" fn pl011_receive( - opaque: *mut core::ffi::c_void, - buf: *const u8, - size: core::ffi::c_int, -) { +pub unsafe extern "C" fn pl011_receive(opaque: *mut c_void, buf: *const u8, size: c_int) { unsafe { debug_assert!(!opaque.is_null()); let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>()); @@ -554,8 +579,7 @@ pub unsafe extern "C" fn pl011_receive( /// We expect the FFI user of this function to pass a valid pointer, that has /// the same size as [`PL011State`]. We also expect the device is /// readable/writeable from one thread at any time. -#[no_mangle] -pub unsafe extern "C" fn pl011_event(opaque: *mut core::ffi::c_void, event: QEMUChrEvent) { +pub unsafe extern "C" fn pl011_event(opaque: *mut c_void, event: QEMUChrEvent) { unsafe { debug_assert!(!opaque.is_null()); let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>()); @@ -576,7 +600,7 @@ pub unsafe extern "C" fn pl011_create( let dev: *mut DeviceState = qdev_new(PL011State::TYPE_INFO.name); let sysbus: *mut SysBusDevice = dev.cast::<SysBusDevice>(); - qdev_prop_set_chr(dev, bindings::TYPE_CHARDEV.as_ptr(), chr); + qdev_prop_set_chr(dev, c_str!("chardev").as_ptr(), chr); sysbus_realize_and_unref(sysbus, addr_of!(error_fatal) as *mut *mut Error); sysbus_mmio_map(sysbus, 0, addr); sysbus_connect_irq(sysbus, 0, irq); @@ -589,7 +613,6 @@ pub unsafe extern "C" fn pl011_create( /// We expect the FFI user of this function to pass a valid pointer, that has /// the same size as [`PL011State`]. We also expect the device is /// readable/writeable from one thread at any time. -#[no_mangle] pub unsafe extern "C" fn pl011_init(obj: *mut Object) { unsafe { debug_assert!(!obj.is_null()); @@ -597,3 +620,50 @@ pub unsafe extern "C" fn pl011_init(obj: *mut Object) { state.as_mut().init(); } } + +#[repr(C)] +#[derive(Debug, qemu_api_macros::Object)] +/// PL011 Luminary device model. +pub struct PL011Luminary { + parent_obj: PL011State, +} + +#[repr(C)] +pub struct PL011LuminaryClass { + _inner: [u8; 0], +} + +/// Initializes a pre-allocated, unitialized instance of `PL011Luminary`. +/// +/// # Safety +/// +/// We expect the FFI user of this function to pass a valid pointer, that has +/// the same size as [`PL011Luminary`]. We also expect the device is +/// readable/writeable from one thread at any time. +pub unsafe extern "C" fn pl011_luminary_init(obj: *mut Object) { + unsafe { + debug_assert!(!obj.is_null()); + let mut state = NonNull::new_unchecked(obj.cast::<PL011Luminary>()); + let state = state.as_mut(); + state.parent_obj.device_id = DeviceId::Luminary; + } +} + +impl qemu_api::definitions::Class for PL011LuminaryClass { + const CLASS_INIT: Option<unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void)> = + None; + const CLASS_BASE_INIT: Option< + unsafe extern "C" fn(klass: *mut ObjectClass, data: *mut c_void), + > = None; +} + +impl ObjectImpl for PL011Luminary { + type Class = PL011LuminaryClass; + const TYPE_INFO: qemu_api::bindings::TypeInfo = qemu_api::type_info! { Self }; + const TYPE_NAME: &'static CStr = crate::TYPE_PL011_LUMINARY; + const PARENT_TYPE_NAME: Option<&'static CStr> = Some(crate::TYPE_PL011); + const ABSTRACT: bool = false; + const INSTANCE_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = Some(pl011_luminary_init); + const INSTANCE_POST_INIT: Option<unsafe extern "C" fn(obj: *mut Object)> = None; + const INSTANCE_FINALIZE: Option<unsafe extern "C" fn(obj: *mut Object)> = None; +} diff --git a/rust/hw/char/pl011/src/device_class.rs b/rust/hw/char/pl011/src/device_class.rs index b7ab31af02..a707fde138 100644 --- a/rust/hw/char/pl011/src/device_class.rs +++ b/rust/hw/char/pl011/src/device_class.rs @@ -3,33 +3,93 @@ // SPDX-License-Identifier: GPL-2.0-or-later use core::ptr::NonNull; +use std::os::raw::{c_int, c_void}; -use qemu_api::{bindings::*, definitions::ObjectImpl}; +use qemu_api::{ + bindings::*, c_str, vmstate_clock, vmstate_fields, vmstate_int32, vmstate_subsections, + vmstate_uint32, vmstate_uint32_array, vmstate_unused, zeroable::Zeroable, +}; + +use crate::device::{PL011State, PL011_FIFO_DEPTH}; + +extern "C" fn pl011_clock_needed(opaque: *mut c_void) -> bool { + unsafe { + debug_assert!(!opaque.is_null()); + let state = NonNull::new_unchecked(opaque.cast::<PL011State>()); + state.as_ref().migrate_clock + } +} -use crate::device::PL011State; +/// Migration subsection for [`PL011State`] clock. +pub static VMSTATE_PL011_CLOCK: VMStateDescription = VMStateDescription { + name: c_str!("pl011/clock").as_ptr(), + version_id: 1, + minimum_version_id: 1, + needed: Some(pl011_clock_needed), + fields: vmstate_fields! { + vmstate_clock!(clock, PL011State), + }, + ..Zeroable::ZERO +}; + +extern "C" fn pl011_post_load(opaque: *mut c_void, version_id: c_int) -> c_int { + unsafe { + debug_assert!(!opaque.is_null()); + let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>()); + let result = state.as_mut().post_load(version_id as u32); + if result.is_err() { + -1 + } else { + 0 + } + } +} -#[used] pub static VMSTATE_PL011: VMStateDescription = VMStateDescription { - name: PL011State::TYPE_INFO.name, - unmigratable: true, - ..unsafe { ::core::mem::MaybeUninit::<VMStateDescription>::zeroed().assume_init() } + name: c_str!("pl011").as_ptr(), + version_id: 2, + minimum_version_id: 2, + post_load: Some(pl011_post_load), + fields: vmstate_fields! { + vmstate_unused!(core::mem::size_of::<u32>()), + vmstate_uint32!(flags, PL011State), + vmstate_uint32!(line_control, PL011State), + vmstate_uint32!(receive_status_error_clear, PL011State), + vmstate_uint32!(control, PL011State), + vmstate_uint32!(dmacr, PL011State), + vmstate_uint32!(int_enabled, PL011State), + vmstate_uint32!(int_level, PL011State), + vmstate_uint32_array!(read_fifo, PL011State, PL011_FIFO_DEPTH), + vmstate_uint32!(ilpr, PL011State), + vmstate_uint32!(ibrd, PL011State), + vmstate_uint32!(fbrd, PL011State), + vmstate_uint32!(ifl, PL011State), + vmstate_int32!(read_pos, PL011State), + vmstate_int32!(read_count, PL011State), + vmstate_int32!(read_trigger, PL011State), + }, + subsections: vmstate_subsections! { + VMSTATE_PL011_CLOCK + }, + ..Zeroable::ZERO }; qemu_api::declare_properties! { PL011_PROPERTIES, qemu_api::define_property!( - c"chardev", + c_str!("chardev"), PL011State, char_backend, unsafe { &qdev_prop_chr }, CharBackend ), qemu_api::define_property!( - c"migrate-clk", + c_str!("migrate-clk"), PL011State, migrate_clock, unsafe { &qdev_prop_bool }, - bool + bool, + default = true ), } @@ -46,7 +106,6 @@ qemu_api::device_class_init! { /// We expect the FFI user of this function to pass a valid pointer, that has /// the same size as [`PL011State`]. We also expect the device is /// readable/writeable from one thread at any time. -#[no_mangle] pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut Error) { unsafe { assert!(!dev.is_null()); @@ -60,7 +119,6 @@ pub unsafe extern "C" fn pl011_realize(dev: *mut DeviceState, _errp: *mut *mut E /// We expect the FFI user of this function to pass a valid pointer, that has /// the same size as [`PL011State`]. We also expect the device is /// readable/writeable from one thread at any time. -#[no_mangle] pub unsafe extern "C" fn pl011_reset(dev: *mut DeviceState) { unsafe { assert!(!dev.is_null()); diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 2939ee50c9..cd0a49acb9 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -36,16 +36,20 @@ clippy::cognitive_complexity, clippy::missing_safety_doc, )] +#![allow(clippy::result_unit_err)] extern crate bilge; extern crate bilge_impl; extern crate qemu_api; +use qemu_api::c_str; + pub mod device; pub mod device_class; pub mod memory_ops; -pub const TYPE_PL011: &::core::ffi::CStr = c"pl011"; +pub const TYPE_PL011: &::std::ffi::CStr = c_str!("pl011"); +pub const TYPE_PL011_LUMINARY: &::std::ffi::CStr = c_str!("pl011_luminary"); /// Offset of each register from the base memory address of the device. /// diff --git a/rust/hw/char/pl011/src/memory_ops.rs b/rust/hw/char/pl011/src/memory_ops.rs index 8d066ebf6d..169d485a4d 100644 --- a/rust/hw/char/pl011/src/memory_ops.rs +++ b/rust/hw/char/pl011/src/memory_ops.rs @@ -2,9 +2,10 @@ // Author(s): Manos Pitsidianakis <manos.pitsidianakis@linaro.org> // SPDX-License-Identifier: GPL-2.0-or-later -use core::{mem::MaybeUninit, ptr::NonNull}; +use core::ptr::NonNull; +use std::os::raw::{c_uint, c_void}; -use qemu_api::bindings::*; +use qemu_api::{bindings::*, zeroable::Zeroable}; use crate::device::PL011State; @@ -14,20 +15,15 @@ pub static PL011_OPS: MemoryRegionOps = MemoryRegionOps { read_with_attrs: None, write_with_attrs: None, endianness: device_endian::DEVICE_NATIVE_ENDIAN, - valid: unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_1>::zeroed().assume_init() }, + valid: Zeroable::ZERO, impl_: MemoryRegionOps__bindgen_ty_2 { min_access_size: 4, max_access_size: 4, - ..unsafe { MaybeUninit::<MemoryRegionOps__bindgen_ty_2>::zeroed().assume_init() } + ..Zeroable::ZERO }, }; -#[no_mangle] -unsafe extern "C" fn pl011_read( - opaque: *mut core::ffi::c_void, - addr: hwaddr, - size: core::ffi::c_uint, -) -> u64 { +unsafe extern "C" fn pl011_read(opaque: *mut c_void, addr: hwaddr, size: c_uint) -> u64 { assert!(!opaque.is_null()); let mut state = unsafe { NonNull::new_unchecked(opaque.cast::<PL011State>()) }; let val = unsafe { state.as_mut().read(addr, size) }; @@ -44,13 +40,7 @@ unsafe extern "C" fn pl011_read( } } -#[no_mangle] -unsafe extern "C" fn pl011_write( - opaque: *mut core::ffi::c_void, - addr: hwaddr, - data: u64, - _size: core::ffi::c_uint, -) { +unsafe extern "C" fn pl011_write(opaque: *mut c_void, addr: hwaddr, data: u64, _size: c_uint) { unsafe { assert!(!opaque.is_null()); let mut state = NonNull::new_unchecked(opaque.cast::<PL011State>()); |