From postmarketOS
Jump to navigation Jump to search


This user's main device is a Google Pixel 3a (google-sargo).

GitLab logo This user has a GitLab profile.

Element logo This user has a Matrix account.

This user has ported 1 device(s) to postmarketOS.

This user mainlined 1 devices.

The tools that I have for debugging are a USB cable, a screwdriver, and a chair.

Owns Devices

Device Notes
Google Pixel 3a (google-sargo) PVT 1.0, daily driver + mainlining target

Various information I found for mainlining


There are 7 valid IOMMU stream match registers on the Pixel 3a provided by the bootloader:

<&apps_smmu 0x140 0xf> // for eMMC
<&apps_smmu 0xa0 0xf> // unknown, might be for SD card
<&apps_smmu 0xc0 0xf> // unknown
<&apps_smmu 0x100 0xf> // unknown, might be for UFS HC
<&apps_smmu 0x740 0x0> // for USB
<&apps_smmu 0x880 0x8> // for MDSS
<&apps_smmu 0xc80 0x8> // for MDSS

The vendor kernel preserves the bootloader's settings on these streams and doesn't specify what all of them are used for. If you're experiencing insane behaviour trying to add a device node (reboot not initiated by the kernel, bring down of all peripherals, etc.), then you might have some luck trying these.

Patch used to fetch these (this patch can also be used under GPL v2):

diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index 2ff7a72cf377..e2c7e123285d 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -2057,6 +2057,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	int num_irqs, i, err;
 	u32 global_irqs, pmu_irqs;
 	irqreturn_t (*global_fault)(int irq, void *dev);
+	u32 smr;
 	smmu = devm_kzalloc(dev, sizeof(*smmu), GFP_KERNEL);
 	if (!smmu) {
@@ -2174,6 +2175,15 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 	/* Check for RMRs and install bypass SMRs if any */
+	for (i = 0; i < smmu->num_mapping_groups; i++) {
+		smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+		if (smr & ARM_SMMU_SMR_VALID)
+			dev_info(dev, "Stream match register: <&apps_smmu 0x%lx 0x%lx>",
+				      FIELD_GET(ARM_SMMU_SMR_ID, smr),
+	}

Dissecting the device tree on Android

It might be hard to find device tree nodes that prevent crashes on remote processors in the downstream device tree. For example, the Pixel 3a (SDM670) needs a modemsmem and smp2p sleepstate node for modem and audio, emitting unintelligible fatal error messages otherwise. To find these, it's useful to set up an environment where you can remove each device tree node (or a few at once, don't hold back too much!) from the same file and quickly pack a boot image. If the crash is caused by a missing device tree node, you'll see some crashes pop up in Android dmesg after a while.

Here is a Makefile and the commands to set up such an environment.


boot.img: cmdline dtb kernel ramdisk
	mkbootimg --output boot.img $(file < cmdline)

flash: boot.img
	fastboot flash boot boot.img

dtb: sdm670-google-sargo.dts
	gcc -E -x assembler-with-cpp $< | dtc -o $@

Command line:

$ unpack_bootimg --boot_img ../boot.img --out . --format mkbootimg > cmdline
$ fdtoverlay -i dtb -o sdm670-google-sargo.dtb ../android_kernel_google_msm-4.9/.output/arch/arm64/boot/dts/google/sdm670-s4-pvt.dtbo
$ dtc sdm670-google-sargo.dtb -o sdm670-google-sargo.dts
$ fastboot erase dtbo

The C preprocessor is run on the DTS because it lets you use the #if 0 and #endif directives and nest them.