From mboxrd@z Thu Jan 1 00:00:00 1970 From: Claude Code Review Bot To: dri-devel-reviews@example.com Subject: Claude review: drm/tyr: add firmware loading and MCU boot support Date: Tue, 03 Mar 2026 12:48:20 +1000 Message-ID: In-Reply-To: <20260302232500.244489-13-deborah.brouwer@collabora.com> References: <20260302232500.244489-1-deborah.brouwer@collabora.com> <20260302232500.244489-13-deborah.brouwer@collabora.com> X-Mailer: Claude Code Patch Reviewer Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Patch Review **Author:** Deborah Brouwer / Boris Brezillon This ties everything together: loads firmware, creates MCU VM, maps firmwar= e sections, boots the MCU. 1. The `Firmware::Drop` breaks a circular reference: ```rust +impl Drop for Firmware { + fn drop(&mut self) { + self.vm.kill(); + } +} ``` This is because the VM -> VmAsData -> Seat -> SlotManager -> SlotData (Arc<= VmAsData>) creates a cycle. The `kill()` method deactivates the VM (evictin= g from slot manager, dropping the Arc) and then unmaps all region= s. This is a necessary but somewhat fragile pattern =E2=80=94 if `kill()` f= ails, the Arc cycle leaks. The error logging in `kill()` mitigates debuggab= ility. 2. `init_section_mem()` writes firmware data byte-by-byte: ```rust + for (i, &byte) in data.iter().enumerate() { + vmap.try_write8(byte, i)?; + } ``` This is functional but slow for large firmware sections. A `memcpy_to_vmap(= )` or similar bulk operation would be more efficient, but this is a correct= ness-first approach that can be optimized later. 3. The MCU boot polling has reasonable timeouts: ```rust + if let Err(e) =3D poll::read_poll_timeout( + || regs::MCU_STATUS.read(dev, &self.iomem), + |status| *status =3D=3D regs::MCU_STATUS_ENABLED, + time::Delta::from_millis(1), + time::Delta::from_millis(100), + ) { ``` 1ms polling interval, 100ms total timeout. This matches the C panthor drive= r's `panthor_fw_start()` timeouts. 4. The `SectionFlag::CacheModeNone =3D 0 << 3` is zero, which means `Sectio= nFlags::empty()` and `SectionFlag::CacheModeNone` are indistinguishable. Th= is is by design (the zero cache mode is "none"), but the `impl_flags!` macr= o may not handle zero-valued flags correctly in `contains()` checks. Howeve= r, the actual usage only checks `cache_mode !=3D SectionFlag::CacheModeCach= ed.into()`, which works correctly since cached mode is non-zero. 5. The firmware path construction looks correct: ```rust + let path =3D CString::try_from_fmt(fmt!( + "arm/mali/arch{}.{}/mali_csffw.bin", + gpu_id.arch_major, + gpu_id.arch_minor + ))?; ``` This matches the C panthor driver's firmware path format. 6. In the probe path, `firmware.boot()` is called before the DRM device is = registered (before `try_pin_init!(TyrDrmDeviceData {...})`). This means if = boot fails, cleanup is straightforward (no registered device to unregister)= . Good ordering. Overall, this is a solid v2 series. The most actionable items are the `AsRe= gister::new()` validation gap and the slightly convoluted error handling in= the firmware parser's `parse_entry()`. --- Generated by Claude Code Patch Reviewer