Compare commits

3 Commits
Author SHA1 Message Date
snlavaise 7e0a580700 rtwo: switch chainload boot from bootm+FIT to bootefi (EFI stub)
bootm's ramdisk initrd delivery (boot_ramdisk_high()/LMB high-address
placement plus the fixed start/loados/ramdisk/fdt/cmdline/bdt/prep/go
ordering in bootm_run_states()) kept producing a kernel that booted
cleanly but silently discarded its initramfs, ending in "VFS: Cannot
open root device". Confirmed on hardware, multiple attempts, none
panned out (in-place mode collided with the kernel relocation;
reordering bootm substates is rejected by U-Boot itself as "out of
order"; the reserved-memory collision theory was disproven against the
compiled dtb).

Switched to bootefi instead: same FIT (no repackaging), parsed with
imxtract (kernel/fdt/ramdisk each extracted to a separate address),
then booted via the kernel's own EFI stub + LoadFile2 initrd protocol
-- a different code path in both U-Boot (efi_loader, not
boot_ramdisk_high()) and the kernel (efi_load_initrd(), never touches
reserve_initrd_mem()).

Two real bugs found and fixed along the way, both confirmed on
hardware:
- ramdisk destination must not be a hand-computed offset from
   (that address is our own scratch buffer holding the
  whole FIT, not the board's dedicated ramdisk block) -- use
  $kernel_comp_addr_r instead, a separate 64 MiB LMB block the board
  reserves for kernel decompression, unused since our Image is
  uncompressed.
- bootefi's first argument (the kernel) needs an explicit ":size"
  suffix. Without it, cmd/bootefi.c assumes the address was set by a
  prior load/tftp command tracked via efi_set_image_parameters() --
  imxtract never touches that tracking, so the address never matches
  and bootefi fails with "No UEFI binary known" even though the
  bytes there are a perfectly valid kernel image.

CONFIRMED ON HARDWARE 2026-09-18: reaches a live debug shell console.
2026-09-18 00:09:27 -03:00
snlavaise bc6a059bf8 rtwo: fix UFS bring-up and FIT boot_a chainload
Several stacked bugs were blocking boot_a resolution and kernel handoff,
found by working backwards from "could not resolve boot_a partition":

- clock-sm8550.c: add missing GCC_CFG_NOC_USB3_PRIM_AXI_CLK gate
  (offset 0x39088 bit 0, verified against upstream gcc-sm8550.c). Needed
  by the mainline USB DT nodes added to the vendor control-DTB (not
  tracked in this repo, see ~/pmos/uboot-chainload/vendor-dtb-from-
  boot_v14_dbg.dtb on the dev machine).

- bootcmd: boot_a is on `scsi 3`, not `scsi 0` -- Motorola splits UFS
  into multiple LUNs, with boot-critical A/B partitions (boot_a/b,
  dtbo_a/b, vbmeta_a/b) on a small 1.1 GB LUN separate from the ~236 GB
  "user" LUN. Confirmed via `part number scsi N boot_a` sweep on
  hardware.

- bootcmd: every setexpr call was missing the `$` before its operand
  variable names (`boot_a_size` instead of `$boot_a_size`, etc).
  setexpr always parses operands as hex via hextoul(), so the literal
  string "boot_a_size" was read as 0xb (stops at the first non-hex
  char), producing a nonsensical blksz and an integer-underflowed
  fit_blk_cnt. This silently produced garbage even before the UFS fixes
  below, since boot_a was never reached until now.

- bootcmd: `scsi read` doesn't take a device argument, it operates on
  the last device selected via `scsi dev`; add that before the read.

The UFS host controller (ufshc@1d84000) and its PHY were never binding
at all in U-Boot, independent of all of the above -- three separate
issues in the vendor control-DTB (not in this repo):
  1. Both nodes used `status = "ok"`, which fdtdec_get_is_enabled()
     treats as disabled (it only accepts "okay").
  2. The UFS PHY's compatible was the downstream
     "qcom,ufs-phy-qmp-v4-kalama", unrecognized by phy-qcom-qmp-ufs.c
     (needs "qcom,sm8550-qmp-ufs-phy").
  3. Both the host controller's and PHY's clocks lists referenced
     "qcom,kalama-rpmh-clk" (the root XO), which has no matching driver
     in this U-Boot tree -- clk_get_bulk()/clk_get_by_index() on it
     returned -ENODEV, aborting ufshcd_probe(). Removed the unused
     reference on the host controller and added a plain 19.2 MHz
     fixed-clock node for the PHY's ref_clk_src, which is the only
     actual consumer of it by index.

Confirmed on hardware (2026-09-17): boot_a resolves, the raw FIT read
from UFS succeeds, and bootm loads kernel+ramdisk+fdt with hash
verification OK and reaches "Starting kernel ...". The kernel itself
now resets very early after that -- separate, unrelated bring-up work,
not a U-Boot/chainload issue.

Diagnostic bootmenu entries (12-14) are debugging aids kept for the
next round of hardware bring-up, along with the two `pause` statements
added to bootcmd around the SCSI read and bootm calls.
2026-09-17 18:24:10 -03:00
snlavaise 8e92d068c3 rtwo: replace debug blink instrumentation with a boot progress bar
Confirmed on hardware that the chainload boots. The per-call blink
instrumentation lived in hot paths (clk_enable/qcom_gate_clk_en/serial
probe) and did a full 10 MiB framebuffer clear + cache flush on every
call, noticeably slowing boot. Replaced with a single progress bar
hooked once per INITCALL step (include/initcall.h) plus an explicit
100% draw at the end of board_late_init(), touching only the bar's
rectangle instead of the whole screen. Kept the real fixes from the
same patch (qcom,kalama-gcc-v2 GCC compatible, the IS_ERR(clk) handling
in serial_msm_geni.c) untouched.
2026-09-17 01:13:01 -03:00
7 changed files with 167 additions and 137 deletions
+77 -70
View File
@@ -519,6 +519,8 @@ void __weak qcom_late_init(void)
#define lmb_alloc(size, addr) lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE)
void rtwo_boot_progress_done(void);
/* Stolen from arch/arm/mach-apple/board.c */
int board_late_init(void)
{
@@ -578,6 +580,8 @@ int board_late_init(void)
/* Configure the dfu_string for capsule updates */
qcom_configure_capsule_updates();
rtwo_boot_progress_done();
return 0;
}
@@ -756,36 +760,42 @@ void enable_caches(void)
}
/*
* Instrumentacion temporal de bring-up (rtwo, SM8550): sin UART, la unica
* senal visible que este ABL deja disponible es el framebuffer que deja
* prendido en 0xb8000000 (splash_region). Cada zona de codigo (board_init_f
* generico, board_init_r generico, probe de serial, camino de clk_enable)
* llama a rtwo_debug_blink_zone() con su propio numero de zona, que se
* dibuja como DOS DIGITOS GRANDES ESTILO 7-SEGMENTOS (blanco sobre negro,
* el numero de zona en decimal, directo). Los esquemas anteriores (bandas
* horizontales para contar, luego un codigo binario de 6 barras) resultaron
* fragiles con luz/reflejo del vidrio: dos lecturas distintas del mismo
* codigo de barras (una por foto, otra mirando el telefono directo) sobre
* la misma pantalla congelada -- ver memoria rtwo-uboot-chainload. Un
* numero grande no necesita interpretacion. Cada sitio instrumentado en
* board.c/serial_msm_geni.c/clk-uclass.c/clock-qcom.c/clock-sm8550.c tiene
* su propio numero GLOBAL y UNICO de zona (1, 2 para los INITCALL
* genericos de board_init_f/board_init_r; 10-39 para los pasos de probe de
* serial y del camino de clk_enable). rtwo_debug_blink() (zona 1/2 segun
* GD_FLG_RELOC) es la que llama include/initcall.h en cada INITCALL de
* board_init_f/board_init_r.
* Mantenimiento de cache manual porque el framebuffer lo lee el
* controlador de display directamente de DRAM, sin pasar por la CPU.
* Barra de progreso de arranque (rtwo, SM8550): dibuja en el framebuffer que
* el ABL deja prendido en 0xb8000000 (splash_region), la unica senal visible
* sin UART. Reemplaza la instrumentacion de bring-up anterior (digitos de
* 7 segmentos por zona de codigo en board.c/serial_msm_geni.c/clk-uclass.c/
* clock-qcom.c/clock-sm8550.c, ver historial en memoria rtwo-uboot-chainload)
* una vez confirmado que el chainload arranca: aquella instrumentacion vivia
* dentro de rutas calientes (clk_enable/qcom_gate_clk_en/probe de serial, con
* un flush de cache de los 10 MiB completos del framebuffer en CADA llamada)
* y se disparaba decenas de veces por segundo, alargando bastante el arranque.
* Esta version solo se engancha una vez por paso de `include/initcall.h`
* (rtwo_boot_progress_step(), UN llamado por entrada de
* init_sequence_f[]/init_sequence_r[], no por operacion de bajo nivel) y solo
* toca/flushea el rectangulo de la barra, no la pantalla entera.
* Mantenimiento de cache manual porque el framebuffer lo lee el controlador
* de display directamente de DRAM, sin pasar por la CPU.
*/
#define RTWO_FB_BASE 0xb8000000UL
#define RTWO_FB_SIZE 0xA00000UL /* 10 MiB: cubre 1080x2400x4 con margen */
#define RTWO_FB_STRIDE_WORDS 1080UL /* ancho en palabras de 32 bits */
#define RTWO_DIGIT_W 360UL
#define RTWO_DIGIT_H 700UL
#define RTWO_DIGIT_THICK 70UL
#define RTWO_DIGIT_GAP 60UL
#define RTWO_DIGIT_Y0 850UL /* deja libre la zona de la camara punch-hole arriba */
#define RTWO_BAR_X0 140UL
#define RTWO_BAR_X1 940UL /* 800 px de ancho, centrada */
#define RTWO_BAR_Y0 1150UL
#define RTWO_BAR_Y1 1250UL /* 100 px de alto */
#define RTWO_BAR_BORDER 6UL
/*
* Estimacion aproximada de cuantos pasos de INITCALL hay entre
* board_init_f() y board_init_r() en esta config -- no hace falta que sea
* exacta, solo que la barra avance de forma pareja y no llegue a 100% antes
* de tiempo. rtwo_boot_progress_done() (llamada al final de
* board_late_init(), justo antes de bootcmd) la fuerza a 100% siempre, sin
* depender de haber contado bien.
*/
#define RTWO_BOOT_STEPS_ESTIMATE 40U
#define RTWO_BOOT_PROGRESS_CAP 96U /* tope hasta el 100% explicito */
static void rtwo_fill_rect(volatile unsigned int *fb, unsigned long x0, unsigned long y0,
unsigned long x1, unsigned long y1, unsigned int color)
@@ -800,59 +810,56 @@ static void rtwo_fill_rect(volatile unsigned int *fb, unsigned long x0, unsigned
}
}
/* Mascara de segmentos por digito: bit0=A(arriba) bit1=B(sup-der)
* bit2=C(inf-der) bit3=D(abajo) bit4=E(inf-izq) bit5=F(sup-izq) bit6=G(medio),
* codificacion estandar de un display de 7 segmentos.
*/
static void rtwo_draw_digit(volatile unsigned int *fb, unsigned long x0, unsigned int digit)
static void rtwo_flush_bar_cache(void)
{
static const unsigned char segs[10] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F,
};
unsigned char m = digit < 10 ? segs[digit] : 0;
unsigned long y0 = RTWO_DIGIT_Y0;
unsigned long yh = y0 + RTWO_DIGIT_H / 2;
unsigned long y1 = y0 + RTWO_DIGIT_H;
unsigned long t = RTWO_DIGIT_THICK;
unsigned int on = 0xFFFFFFFFu;
if (m & 0x01) /* A */
rtwo_fill_rect(fb, x0 + t, y0, x0 + RTWO_DIGIT_W - t, y0 + t, on);
if (m & 0x40) /* G */
rtwo_fill_rect(fb, x0 + t, yh - t / 2, x0 + RTWO_DIGIT_W - t, yh + t / 2, on);
if (m & 0x08) /* D */
rtwo_fill_rect(fb, x0 + t, y1 - t, x0 + RTWO_DIGIT_W - t, y1, on);
if (m & 0x20) /* F */
rtwo_fill_rect(fb, x0, y0, x0 + t, yh + t / 2, on);
if (m & 0x02) /* B */
rtwo_fill_rect(fb, x0 + RTWO_DIGIT_W - t, y0, x0 + RTWO_DIGIT_W, yh + t / 2, on);
if (m & 0x10) /* E */
rtwo_fill_rect(fb, x0, yh - t / 2, x0 + t, y1, on);
if (m & 0x04) /* C */
rtwo_fill_rect(fb, x0 + RTWO_DIGIT_W - t, yh - t / 2, x0 + RTWO_DIGIT_W, y1, on);
}
void rtwo_debug_blink_zone(unsigned int zone)
{
volatile unsigned int *fb = (volatile unsigned int *)RTWO_FB_BASE;
const unsigned long total_words = RTWO_FB_SIZE / 4;
const unsigned long total_rows = total_words / RTWO_FB_STRIDE_WORDS;
const unsigned long margin_left = (RTWO_FB_STRIDE_WORDS - (2 * RTWO_DIGIT_W + RTWO_DIGIT_GAP)) / 2;
unsigned long addr;
rtwo_fill_rect(fb, 0, 0, RTWO_FB_STRIDE_WORDS, total_rows, 0u); /* fondo negro */
rtwo_draw_digit(fb, margin_left, zone / 10U);
rtwo_draw_digit(fb, margin_left + RTWO_DIGIT_W + RTWO_DIGIT_GAP, zone % 10U);
unsigned long start = RTWO_FB_BASE + RTWO_BAR_Y0 * RTWO_FB_STRIDE_WORDS * 4;
unsigned long end = RTWO_FB_BASE + RTWO_BAR_Y1 * RTWO_FB_STRIDE_WORDS * 4;
asm volatile("dsb sy" ::: "memory");
for (addr = RTWO_FB_BASE; addr < RTWO_FB_BASE + RTWO_FB_SIZE; addr += 64)
for (addr = start & ~63UL; addr < end; addr += 64)
asm volatile("dc civac, %0" :: "r"(addr) : "memory");
asm volatile("dsb sy" ::: "memory");
asm volatile("isb" ::: "memory");
}
void rtwo_debug_blink(void)
static void rtwo_draw_progress_bar(unsigned int percent)
{
rtwo_debug_blink_zone((gd->flags & GD_FLG_RELOC) ? 2U : 1U);
volatile unsigned int *fb = (volatile unsigned int *)RTWO_FB_BASE;
unsigned long fill_x1;
if (percent > 100U)
percent = 100U;
/* borde blanco */
rtwo_fill_rect(fb, RTWO_BAR_X0, RTWO_BAR_Y0, RTWO_BAR_X1, RTWO_BAR_Y1, 0xFFFFFFFFu);
/* fondo negro, dentro del borde */
rtwo_fill_rect(fb, RTWO_BAR_X0 + RTWO_BAR_BORDER, RTWO_BAR_Y0 + RTWO_BAR_BORDER,
RTWO_BAR_X1 - RTWO_BAR_BORDER, RTWO_BAR_Y1 - RTWO_BAR_BORDER, 0u);
fill_x1 = RTWO_BAR_X0 + RTWO_BAR_BORDER +
(RTWO_BAR_X1 - RTWO_BAR_X0 - 2 * RTWO_BAR_BORDER) * percent / 100U;
if (fill_x1 > RTWO_BAR_X0 + RTWO_BAR_BORDER)
rtwo_fill_rect(fb, RTWO_BAR_X0 + RTWO_BAR_BORDER, RTWO_BAR_Y0 + RTWO_BAR_BORDER,
fill_x1, RTWO_BAR_Y1 - RTWO_BAR_BORDER, 0xFFFFFFFFu);
rtwo_flush_bar_cache();
}
void rtwo_boot_progress_step(void)
{
static unsigned int steps;
unsigned int percent;
steps++;
percent = steps * RTWO_BOOT_PROGRESS_CAP / RTWO_BOOT_STEPS_ESTIMATE;
if (percent > RTWO_BOOT_PROGRESS_CAP)
percent = RTWO_BOOT_PROGRESS_CAP;
rtwo_draw_progress_bar(percent);
}
void rtwo_boot_progress_done(void)
{
rtwo_draw_progress_bar(100U);
}
+80 -8
View File
@@ -22,14 +22,83 @@ serial_gadget=setenv stdin serial,button-kbd,usbacm; \
# then bail out to the boot menu instead (with a pause to read
# the error message)
#
# rtwo (Motorola Edge 40 Pro, SM8550): the ABL loads the FIT image
# (mainline Image + dtb + initramfs) into the ramdisk slot of the
# Android boot.img. The ABL writes that address into
# /chosen/linux,initrd-start of the fdt it hands us, and U-Boot saves
# it as $prevbl_initrd_start_addr (CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR).
# Try that first; only fall back to the phone menu if it fails.
pmos_bootargs=earlycon console=ttyMSM0,115200n8 panic=5 pmos.debug-shell clk_ignore_unused pd_ignore_unused regulator_ignore_unused allow_mismatched_32bit_el0 pmos_boot_uuid=d4373976-057c-4cf3-a43d-00734001b405 pmos_root_uuid=09804032-85bb-4d57-95a5-00d1965fb10f pmos_rootfsopts=defaults
bootcmd=setenv bootargs $pmos_bootargs; echo pmOS: booting FIT at prevbl_initrd_start_addr=$prevbl_initrd_start_addr; bootm $prevbl_initrd_start_addr; echo pmOS: bootm failed; bootefi bootmgr; pause; run menucmd
# rtwo (Motorola Edge 40 Pro, SM8550): the FIT image (mainline Image +
# dtb + initramfs) is packed by pack-fixedoff.py at a FIXED FILE OFFSET
# (0x18c000) inside boot_a -- same offset the ABL uses to load kernel/
# dtb, discovered via RE because this ABL does NOT follow the standard
# Android boot.img formula. Confirmed in hardware (2026-09-17): trusting
# $prevbl_initrd_start_addr (CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR,
# i.e. what the ABL claims via /chosen/linux,initrd-start) fails with
# "ERROR -91E: can't get kernel image!" (EPROTOTYPE, no FIT magic at
# that address) -- consistent with the ABL's fixed-offset loading not
# populating that property correctly either. So: read the FIT ourselves
# straight from boot_a at the known offset via the UFS/SCSI block layer
# (preboot already did `scsi scan`) into $ramdisk_addr_r (128 MiB
# scratch region board_late_init reserves, arch/arm/mach-snapdragon/
# board.c). Block size is derived at runtime (100663296 / blocks-in-
# partition) instead of assumed, since we don't know if this UFS LU
# reports 512B or 4096B logical blocks. Falls back to the old
# prevbl_initrd_start_addr attempt, then to the phone menu, if this
# fails -- see memoria rtwo-uboot-chainload-fit-raw-read.
pmos_bootargs=earlycon console=ttyMSM0,115200n8 console=tty0 ignore_loglevel panic=5 pmos.debug-shell clk_ignore_unused pd_ignore_unused regulator_ignore_unused allow_mismatched_32bit_el0 pmos_boot_uuid=d4373976-057c-4cf3-a43d-00734001b405 pmos_root_uuid=09804032-85bb-4d57-95a5-00d1965fb10f pmos_rootfsopts=defaults
# ESTADO 2026-09-17: vuelto a dejar tal cual quedo justo despues del PRIMER
# cambio de la implementacion EFI (antes de corregir el offset del ramdisk
# de imxtract y antes de sacar ignore_loglevel) -- checkpoint pedido para
# retomar la exploracion del camino EFI, esta vez via una particion real
# (userdata) en vez del RAM-only que se probo primero.
#
# DEBUG 2026-09-17 (quinta vuelta): probar el camino EFI en vez de bootm+FIT.
# bootefi usa boot/efi_loader (AllocatePages/LoadFile2) para el initrd, no
# boot_ramdisk_high()/LMB "high address" -- codigo completamente distinto,
# asi que el bug de orden fijo start/loados/ramdisk/fdt de bootm no aplica
# aca. Ademas, en el lado del kernel, el stub EFI arm64 (CONFIG_EFI_STUB=y,
# ya compilado) carga el initrd via efi_load_initrd()/LoadFile2, que NUNCA
# pasa por early_init_dt_check_for_initrd()/reserve_initrd_mem() -- el
# chequeo memblock_is_region_reserved() que sospechabamos ni siquiera se
# ejecuta para este camino. bootargs se sigue pasando igual (bootefi
# convierte $bootargs a UTF-16 como load options).
#
# Mismo FIT de siempre (sin repackaging), pero en vez de bootm lo parseamos
# con imxtract (CONFIG_CMD_XIMG=y, ya compilado) para sacar cada sub-imagen
# a una direccion de RAM aparte:
# - kernel -> $kernel_addr_r (misma que bootm usaba para relocar)
# - fdt -> $fdt_addr_r (la misma que bootmenu_10 ya usa con exito)
# - ramdisk -> $kernel_comp_addr_r (NO un offset inventado desde
# $ramdisk_addr_r -- eso fue el bug original: $ramdisk_addr_r + 0x8000000
# coincidia EXACTO con $kernel_addr_r y piso el kernel ya extraido
# ("No UEFI binary known at <addr>"). Investigado en la lista de U-Boot
# (parche "mach-snapdragon: dynamic load addresses", 2026): board.c
# arma estas variables como bloques LMB DEDICADOS y consecutivos --
# kernel_addr_r=128MiB, ramdisk_addr_r=128MiB (por eso el offset exacto
# de 0x8000000=128MiB), kernel_comp_addr_r=64MiB, fdt_addr_r=2MiB. El
# bug de fondo era usar $ramdisk_addr_r para algo que NO es su proposito
# (nuestro buffer crudo del FIT completo, ~55 MiB) y encima calcular un
# offset a mano dentro de ese mismo bloque de 128 MiB, invadiendo el
# vecino. $kernel_comp_addr_r es un bloque separado, dedicado a
# descomprimir un kernel comprimido -- el nuestro (Image sin comprimir,
# CONFIG_EFI_ZBOOT apagado) no lo usa, asi que esta libre y garantizado
# sin solaparse con ningun otro _addr_r por construccion.
# imxtract fija $filesize despues de cada extraccion (confirmado en
# cmd/ximg.c), por eso el tamano del ramdisk y del kernel se guardan aparte
# antes de que la siguiente llamada los pise.
#
# 2026-09-18: "No UEFI binary known at <addr>" seguia apareciendo incluso
# con las tres direcciones ya sin solaparse (kernel_comp_addr_r confirmado
# en hardware como un bloque separado y limpio). Causa real, en
# cmd/bootefi.c:204-226 (do_bootefi_image): si el PRIMER argumento de
# `bootefi` NO lleva ":tamano", el comando asume que la direccion ya viene
# de un `load`/`tftp` previo (que actualiza un registro interno de "ultima
# imagen cargada" via efi_set_image_parameters()) y compara contra ESE
# registro -- si no matchea (o nunca se seteo, como en nuestro caso porque
# usamos `imxtract`, que NO actualiza ese registro), falla con este mensaje
# sin importar que los bytes en esa direccion sean un kernel EFI valido.
# Fix: pasarle ":tamano" tambien al kernel (no solo al ramdisk, que ya lo
# llevaba) -- eso fuerza la rama que trata la direccion como explicita
# (efi_clear_bootdev()) sin depender de ningun registro previo.
#
# Si bootefi no funciona por algun motivo, cae al `bootm` de siempre como
# red de seguridad (mismo fallback que ya existia).
bootcmd=setenv bootargs $pmos_bootargs; if part start scsi 3 boot_a boot_a_start && part size scsi 3 boot_a boot_a_size; then setexpr blksz 0x6000000 / $boot_a_size; setexpr fit_blk_off 0x18c000 / $blksz; setexpr fit_lba $boot_a_start + $fit_blk_off; setexpr fit_blk_cnt $boot_a_size - $fit_blk_off; echo pmOS: boot_a start=$boot_a_start size=$boot_a_size blksz=$blksz fit_lba=$fit_lba fit_cnt=$fit_blk_cnt; scsi dev 3; if scsi read $ramdisk_addr_r $fit_lba $fit_blk_cnt; then echo pmOS: FIT read OK, addr=$ramdisk_addr_r; setenv verify no; setenv initrd_stage_addr $kernel_comp_addr_r; if imxtract $ramdisk_addr_r kernel $kernel_addr_r; then setenv kernel_stage_size $filesize; echo pmOS: kernel extracted addr=$kernel_addr_r size=$kernel_stage_size; if imxtract $ramdisk_addr_r fdt $fdt_addr_r; then echo pmOS: fdt extracted addr=$fdt_addr_r size=$filesize; if imxtract $ramdisk_addr_r ramdisk $initrd_stage_addr; then setenv initrd_stage_size $filesize; echo pmOS: ramdisk extracted addr=$initrd_stage_addr size=$initrd_stage_size; echo pmOS: trying bootefi; pause; bootefi $kernel_addr_r:$kernel_stage_size $initrd_stage_addr:$initrd_stage_size $fdt_addr_r; echo pmOS: bootefi returned, should not happen; pause; else echo pmOS: ramdisk imxtract FAILED; pause; fi; else echo pmOS: fdt imxtract FAILED; pause; fi; else echo pmOS: kernel imxtract FAILED; pause; fi; else echo pmOS: scsi read of FIT failed; pause; fi; else echo pmOS: could not resolve boot_a partition; fi; echo pmOS: bootefi path failed, trying old bootm path via prevbl_initrd_start_addr=$prevbl_initrd_start_addr; bootm $prevbl_initrd_start_addr; echo pmOS: bootm failed; bootefi bootmgr; pause; run menucmd
# When entering the menu (either from button press or failed boot)
# remap bootcmd so it will re-open the menu and we won't get stuck
@@ -50,6 +119,9 @@ bootmenu_8=Dump environment=printenv; pause
bootmenu_9=Board info=bdinfo; pause
bootmenu_10=Dump bootargs=fdt addr $fdt_addr_r; fdt print /chosen bootargs; pause
bootmenu_11=Power off=poweroff
bootmenu_12=Diag SCSI boot_a=scsi scan; scsi info; pause; if part number scsi 0 boot_a i; then echo scsi0:part=$i; else echo scsi0:no-boot_a; fi; if part number scsi 1 boot_a i; then echo scsi1:part=$i; else echo scsi1:no-boot_a; fi; if part number scsi 2 boot_a i; then echo scsi2:part=$i; else echo scsi2:no-boot_a; fi; if part number scsi 3 boot_a i; then echo scsi3:part=$i; else echo scsi3:no-boot_a; fi; pause; if part number scsi 4 boot_a i; then echo scsi4:part=$i; else echo scsi4:no-boot_a; fi; if part number scsi 5 boot_a i; then echo scsi5:part=$i; else echo scsi5:no-boot_a; fi; if part number scsi 6 boot_a i; then echo scsi6:part=$i; else echo scsi6:no-boot_a; fi; if part number scsi 7 boot_a i; then echo scsi7:part=$i; else echo scsi7:no-boot_a; fi; pause
bootmenu_13=Diag USB gadget=dm uclass usb_gadget; pause; dm uclass usb; pause; dm uclass phy; pause
bootmenu_14=Diag UFS=dm uclass ufs; pause; dm uclass phy; pause; ufs init 0; echo ufs_init_ret=$?; pause
# Allow holding the volume down button while U-Boot loads to enter
# the boot menu
+2 -11
View File
@@ -657,21 +657,15 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
return 0;
}
void rtwo_debug_blink_zone(unsigned int zone);
int clk_enable(struct clk *clk)
{
const struct clk_ops *ops;
struct clk *clkp = NULL;
int ret;
rtwo_debug_blink_zone(23); /* CLKEN-1: entrada a clk_enable */
debug("%s(clk=%p name=%s)\n", __func__, clk, clk ? clk->dev->name : "NULL");
if (!clk_valid(clk)) {
rtwo_debug_blink_zone(24); /* CLKEN-2a: clk invalido/NULL, return temprano */
if (!clk_valid(clk))
return 0;
}
rtwo_debug_blink_zone(25); /* CLKEN-2b: clk valido, seguimos */
ops = clk_dev_ops(clk->dev);
if (CONFIG_IS_ENABLED(CLK_CCF)) {
@@ -705,10 +699,7 @@ int clk_enable(struct clk *clk)
} else {
if (!ops->enable)
return -ENOSYS;
rtwo_debug_blink_zone(26); /* CLKEN-3: justo antes de ops->enable(clk) */
ret = ops->enable(clk);
rtwo_debug_blink_zone(27); /* CLKEN-4: ops->enable(clk) retorno */
return ret;
return ops->enable(clk);
}
return 0;
+2 -18
View File
@@ -28,8 +28,6 @@
#include "clock-qcom.h"
void rtwo_debug_blink_zone(unsigned int zone);
/* CBCR register fields */
#define CBCR_BRANCH_ENABLE_BIT BIT(0)
#define CBCR_BRANCH_OFF_BIT BIT(31)
@@ -78,21 +76,17 @@ void clk_enable_vote_clk(phys_addr_t base, const struct vote_clk *vclk)
int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
{
rtwo_debug_blink_zone(28); /* GATE-1: entrada a qcom_gate_clk_en */
if (id >= priv->data->num_clks || priv->data->clks[id].reg == 0) {
log_err("gcc@%#08llx: unknown clock ID %lu!\n",
priv->base, id);
return -ENOENT;
}
rtwo_debug_blink_zone(29); /* GATE-2: id valido, antes de setbits_le32 */
setbits_le32(priv->base + priv->data->clks[id].reg, priv->data->clks[id].en_val);
rtwo_debug_blink_zone(30); /* GATE-3: post setbits_le32 (el registro ya se escribio) */
if (priv->data->clks[id].cbcr_reg) {
unsigned int count;
u32 val;
rtwo_debug_blink_zone(31); /* GATE-4: hay cbcr_reg, entrando al poll acotado */
for (count = 0; count < 200; count++) {
val = readl(priv->base + priv->data->clks[id].cbcr_reg);
val &= BRANCH_CHECK_MASK;
@@ -100,14 +94,10 @@ int qcom_gate_clk_en(const struct msm_clk_priv *priv, unsigned long id)
break;
udelay(1);
}
rtwo_debug_blink_zone(33); /* GATE-5: poll terminado (por bit ok o por timeout) */
if (WARN(count == 200, "WARNING: Clock @ %#lx [%#010x] stuck at off\n",
priv->data->clks[id].cbcr_reg, val))
return -EBUSY;
} else {
rtwo_debug_blink_zone(32); /* GATE-4b: no hay cbcr_reg, no se espera nada */
}
rtwo_debug_blink_zone(34); /* GATE-6: fin de qcom_gate_clk_en, return 0 */
return 0;
}
@@ -266,14 +256,8 @@ static int msm_clk_enable(struct clk *clk)
{
struct msm_clk_data *data = (struct msm_clk_data *)dev_get_driver_data(clk->dev);
rtwo_debug_blink_zone(35); /* MSMCLK-1: entrada a msm_clk_enable */
if (data->enable) {
int ret;
rtwo_debug_blink_zone(36); /* MSMCLK-2: antes de data->enable(clk) */
ret = data->enable(clk);
rtwo_debug_blink_zone(37); /* MSMCLK-3: data->enable(clk) retorno */
return ret;
}
if (data->enable)
return data->enable(clk);
return 0;
}
+2 -5
View File
@@ -122,6 +122,7 @@ static const struct gate_clk sm8550_clks[] = {
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_CLK, 0x770e4, BIT(0)),
GATE_CLK(GCC_AGGRE_UFS_PHY_AXI_HW_CTL_CLK, 0x770e4, BIT(1)),
GATE_CLK(GCC_AGGRE_USB3_PRIM_AXI_CLK, 0x3908c, BIT(0)),
GATE_CLK(GCC_CFG_NOC_USB3_PRIM_AXI_CLK, 0x39088, BIT(0)),
GATE_CLK(GCC_CNOC_PCIE_SF_AXI_CLK, 0x52008, BIT(6)),
GATE_CLK(GCC_DDRSS_GPU_AXI_CLK, 0x71154, BIT(0)),
GATE_CLK(GCC_DDRSS_PCIE_SF_QTB_CLK, 0x52000, BIT(19)),
@@ -198,15 +199,12 @@ static const struct gate_clk sm8550_clks[] = {
GATE_CLK(GCC_USB3_PRIM_PHY_PIPE_CLK, 0x39068, BIT(0)),
};
void rtwo_debug_blink_zone(unsigned int zone);
static int sm8550_enable(struct clk *clk)
{
struct msm_clk_priv *priv = dev_get_priv(clk->dev);
rtwo_debug_blink_zone(38); /* SM8550EN-1: entrada a sm8550_enable, id=%clk->id (sin printf aqui) */
switch (clk->id) {
case GCC_CFG_NOC_USB3_PRIM_AXI_CLK:
case GCC_AGGRE_USB3_PRIM_AXI_CLK:
qcom_gate_clk_en(priv, GCC_USB30_PRIM_MASTER_CLK);
fallthrough;
@@ -224,7 +222,6 @@ static int sm8550_enable(struct clk *clk)
break;
}
rtwo_debug_blink_zone(39); /* SM8550EN-2: post switch, antes de qcom_gate_clk_en final */
return qcom_gate_clk_en(priv, clk->id);
}
-21
View File
@@ -19,8 +19,6 @@
#include <soc/qcom/qup-fw-load.h>
#include <soc/qcom/geni-se.h>
void rtwo_debug_blink_zone(unsigned int zone);
#define UART_OVERSAMPLING 32
#define STALE_TIMEOUT 160
@@ -211,15 +209,12 @@ static int msm_serial_setbrg(struct udevice *dev, int baud)
pr_err("%s: Couldn't get clock division rate\n", __func__);
return -EINVAL;
}
rtwo_debug_blink_zone(10); /* SETBRG-1: pre clk_set_rate */
ret = clk_set_rate(priv->se, clk_rate);
rtwo_debug_blink_zone(11); /* SETBRG-2: post clk_set_rate */
if (ret < 0) {
pr_err("%s: Couldn't set clock rate: %d\n", __func__, ret);
return 0;
}
geni_serial_baud(priv->base, clk_div, baud);
rtwo_debug_blink_zone(12); /* SETBRG-3: post geni_serial_baud */
return 0;
}
@@ -522,8 +517,6 @@ static int msm_serial_probe(struct udevice *dev)
u32 proto;
struct clk *clk;
rtwo_debug_blink_zone(13); /* PROBE-1: entrada */
clk = devm_clk_get_optional(dev, NULL);
if (IS_ERR(clk)) {
/*
@@ -539,13 +532,9 @@ static int msm_serial_probe(struct udevice *dev)
priv->se = clk;
}
rtwo_debug_blink_zone(14); /* PROBE-2: post devm_clk_get_optional */
/* Try enable clock */
clk_enable(clk);
rtwo_debug_blink_zone(15); /* PROBE-3: post clk_enable */
/* Check if firmware loading is needed (BT UART) */
proto = readl(priv->base + GENI_FW_REVISION_RO);
proto &= FW_REV_PROTOCOL_MSK;
@@ -558,8 +547,6 @@ static int msm_serial_probe(struct udevice *dev)
proto >>= FW_REV_PROTOCOL_SHFT;
}
rtwo_debug_blink_zone(16); /* PROBE-4: post firmware check/load */
if (proto != GENI_SE_UART) {
dev_err(dev, "Invalid proto %d\n", proto);
clk_disable(clk);
@@ -570,26 +557,18 @@ static int msm_serial_probe(struct udevice *dev)
if (ofnode_device_is_compatible(dev_ofnode(dev), "qcom,geni-uart"))
return -ENOENT;
rtwo_debug_blink_zone(17); /* PROBE-5: es geni-debug-uart, seguimos */
ret = geni_set_oversampling(dev);
if (ret < 0)
return ret;
rtwo_debug_blink_zone(18); /* PROBE-6: post geni_set_oversampling */
/* No need to reinitialize the UART after relocation */
if (gd->flags & GD_FLG_RELOC)
return 0;
geni_serial_init(dev);
rtwo_debug_blink_zone(19); /* PROBE-7: post geni_serial_init */
msm_geni_serial_setup_rx(dev);
rtwo_debug_blink_zone(20); /* PROBE-8: post msm_geni_serial_setup_rx */
qcom_geni_serial_start_rx(dev);
rtwo_debug_blink_zone(21); /* PROBE-9: post qcom_geni_serial_start_rx */
qcom_geni_serial_start_tx(priv->base);
rtwo_debug_blink_zone(22); /* PROBE-10: post qcom_geni_serial_start_tx, fin de probe */
return 0;
}
+4 -4
View File
@@ -13,15 +13,15 @@
_Static_assert(EVT_COUNT < 256, "Can only support 256 event types with 8 bits");
#ifdef CONFIG_ARCH_SNAPDRAGON
void rtwo_debug_blink(void);
#define RTWO_DEBUG_BLINK() rtwo_debug_blink()
void rtwo_boot_progress_step(void);
#define RTWO_BOOT_PROGRESS() rtwo_boot_progress_step()
#else
#define RTWO_DEBUG_BLINK()
#define RTWO_BOOT_PROGRESS()
#endif
#define INITCALL(_call) \
do { \
RTWO_DEBUG_BLINK(); \
RTWO_BOOT_PROGRESS(); \
if (_call()) { \
printf("%s(): initcall %s() failed\n", __func__, \
#_call); \