Merge Official Source
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
@@ -13,7 +13,7 @@ include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
define U-Boot/Default
|
||||
BUILD_TARGET:=airoha
|
||||
FIP_COMPRESS:=1
|
||||
LZMA_COMPRESS:=1
|
||||
endef
|
||||
|
||||
define U-Boot/an7581_rfb
|
||||
@@ -36,9 +36,18 @@ define U-Boot/an7583_rfb
|
||||
BL31_IMAGE:=an7583-bl31.bin
|
||||
endef
|
||||
|
||||
define U-Boot/an7581_gemtek_w1700k
|
||||
NAME:=Gemtek W1700K (UBI)
|
||||
UBOOT_CONFIG:=an7581_w1700k
|
||||
BUILD_DEVICES:=gemtek_w1700k-ubi
|
||||
BUILD_SUBTARGET:=an7581
|
||||
UBOOT_IMAGE:=u-boot.bin
|
||||
endef
|
||||
|
||||
UBOOT_TARGETS := \
|
||||
an7581_rfb \
|
||||
an7583_rfb
|
||||
an7583_rfb \
|
||||
an7581_gemtek_w1700k
|
||||
|
||||
UBOOT_CUSTOMIZE_CONFIG := \
|
||||
--disable TOOLS_KWBIMAGE \
|
||||
@@ -54,15 +63,12 @@ define Build/fip-image-bl2
|
||||
endef
|
||||
|
||||
define Build/fip-image
|
||||
$(if $(FIP_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \
|
||||
$(PKG_BUILD_DIR)/u-boot.bin \
|
||||
$(PKG_BUILD_DIR)/u-boot.bin.lzma)
|
||||
$(if $(FIP_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \
|
||||
$(if $(LZMA_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \
|
||||
files/$(BL31_IMAGE) \
|
||||
$(PKG_BUILD_DIR)/bl31.bin.lzma)
|
||||
$(STAGING_DIR_HOST)/bin/fiptool create \
|
||||
--soc-fw $(PKG_BUILD_DIR)/bl31.bin$(if $(FIP_COMPRESS),.lzma) \
|
||||
--nt-fw $(PKG_BUILD_DIR)/u-boot.bin$(if $(FIP_COMPRESS),.lzma) \
|
||||
--soc-fw $(PKG_BUILD_DIR)/bl31.bin$(if $(LZMA_COMPRESS),.lzma) \
|
||||
--nt-fw $(PKG_BUILD_DIR)/u-boot.bin$(if $(LZMA_COMPRESS),.lzma) \
|
||||
$(PKG_BUILD_DIR)/u-boot.fip
|
||||
endef
|
||||
|
||||
@@ -73,6 +79,9 @@ endef
|
||||
|
||||
define Build/Compile
|
||||
$(call Build/Compile/U-Boot)
|
||||
$(if $(LZMA_COMPRESS), $(STAGING_DIR_HOST)/bin/lzma e \
|
||||
$(PKG_BUILD_DIR)/u-boot.bin \
|
||||
$(PKG_BUILD_DIR)/u-boot.bin.lzma)
|
||||
ifeq ($(UBOOT_IMAGE),u-boot.fip)
|
||||
$(call Build/fip-image-bl2)
|
||||
$(call Build/fip-image)
|
||||
@@ -88,6 +97,11 @@ define Build/InstallDev
|
||||
ifeq ($(UBOOT_IMAGE),u-boot.fip)
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/bl2.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl2.fip
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.fip $(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-bl31-u-boot.fip
|
||||
else
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.bin$(if $(LZMA_COMPRESS),.lzma) \
|
||||
$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.bin$(if $(LZMA_COMPRESS),.lzma)
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/u-boot.dtb \
|
||||
$(STAGING_DIR_IMAGE)/$(BUILD_VARIANT)-u-boot.dtb
|
||||
endif
|
||||
endef
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
From 6ecd1312f85bdd0a9be8cc1cdada58c83f68ad99 Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Kasilag <kenneth@kasilag.me>
|
||||
Date: Fri, 6 Mar 2026 06:26:03 +0000
|
||||
Subject: [PATCH] uboot-airoha: add ethernet node for an7581 dtsi
|
||||
|
||||
The ethernet driver (airoha_eth) supports an7581 however it is
|
||||
not declared in the dtsi. Add the ethernet node for the built in
|
||||
airoha ethernet controller.
|
||||
|
||||
Signed-off-by: Kenneth Kasilag <kenneth@kasilag.me>
|
||||
---
|
||||
dts/upstream/src/arm64/airoha/en7581.dtsi | 36 +++++++++++++++++++
|
||||
1 file changed, 36 insertions(+)
|
||||
|
||||
diff --git a/dts/upstream/src/arm64/airoha/en7581.dtsi b/dts/upstream/src/arm64/airoha/en7581.dtsi
|
||||
index 69265e4a1fea97..3b319e7b72fb57 100644
|
||||
--- a/dts/upstream/src/arm64/airoha/en7581.dtsi
|
||||
+++ b/dts/upstream/src/arm64/airoha/en7581.dtsi
|
||||
@@ -346,5 +346,33 @@
|
||||
|
||||
status = "disabled";
|
||||
};
|
||||
+
|
||||
+ eth: ethernet@1fb50000 {
|
||||
+ compatible = "airoha,en7581-eth";
|
||||
+ reg = <0 0x1fb50000 0 0x2600>,
|
||||
+ <0 0x1fb54000 0 0x2000>,
|
||||
+ <0 0x1fb56000 0 0x2000>;
|
||||
+ reg-names = "fe", "qdma0", "qdma1";
|
||||
+
|
||||
+ resets = <&scuclk EN7581_FE_RST>,
|
||||
+ <&scuclk EN7581_FE_PDMA_RST>,
|
||||
+ <&scuclk EN7581_FE_QDMA_RST>,
|
||||
+ <&scuclk EN7581_DUAL_HSI0_MAC_RST>,
|
||||
+ <&scuclk EN7581_DUAL_HSI1_MAC_RST>,
|
||||
+ <&scuclk EN7581_HSI_MAC_RST>,
|
||||
+ <&scuclk EN7581_XFP_MAC_RST>;
|
||||
+ reset-names = "fe", "pdma", "qdma",
|
||||
+ "hsi0-mac", "hsi1-mac",
|
||||
+ "hsi-mac", "xfp-mac";
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
+
|
||||
+ switch: switch@1fb58000 {
|
||||
+ compatible = "airoha,en7581-switch";
|
||||
+ reg = <0 0x1fb58000 0 0x8000>;
|
||||
+
|
||||
+ status = "disabled";
|
||||
+ };
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
From 4fb890cd92dcf8985e76a544c949ad455784ed81 Mon Sep 17 00:00:00 2001
|
||||
From: Dirk Buchwalder <buchwalder@posteo.de>
|
||||
Date: Sun, 1 Mar 2026 13:48:42 +0100
|
||||
Subject: [PATCH] uboot-airoha: add a label to the spi node
|
||||
|
||||
Signed-off-by: Dirk Buchwalder <buchwalder@posteo.de>
|
||||
---
|
||||
dts/upstream/src/arm64/airoha/en7581.dtsi | 2 -+
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
--- a/dts/upstream/src/arm64/airoha/en7581.dtsi
|
||||
+++ b/dts/upstream/src/arm64/airoha/en7581.dtsi
|
||||
@@ -150,7 +150,7 @@
|
||||
interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>;
|
||||
};
|
||||
|
||||
- spi@1fa10000 {
|
||||
+ snfi: spi@1fa10000 {
|
||||
compatible = "airoha,en7581-snand";
|
||||
reg = <0x0 0x1fa10000 0x0 0x140>,
|
||||
<0x0 0x1fa11000 0x0 0x160>;
|
||||
@@ -0,0 +1,318 @@
|
||||
From d6402eadaa56494b382e389d739b9f80d6883788 Mon Sep 17 00:00:00 2001
|
||||
From: Kenneth Kasilag <kenneth@kasilag.me>
|
||||
Date: Sat, 21 Feb 2026 21:49:46 +0000
|
||||
Subject: [PATCH] an7581: add uboot chainloader for w1700k
|
||||
|
||||
Due to issues surrounding the implementation of the vendor BMT/BBT
|
||||
on Airoha, upstream ATF + uboot has switched to UBI flash partitions.
|
||||
|
||||
However, some devices shipped on this platform are bootloader locked,
|
||||
and thus it is impossible to replace ATF + uboot.
|
||||
|
||||
During testing for the Gemtek W1700K (#17869), sysupgrades from Linux
|
||||
(which is unaware of the underlying BMT/BBT) would occasionally write
|
||||
data into blocks which were remapped by the vendor uboot when it was
|
||||
read on the following reboot, causing a soft brick.
|
||||
|
||||
An acceptable workaround [1],[2] was discussed where an intermediate
|
||||
uboot would be written by the vendor uboot (which is aware of Airoha
|
||||
BMT/BBT). This chainloader would then ignore the regions of flash
|
||||
used by the vendor uboot, and store all relevant data inside of UBI.
|
||||
|
||||
UBI would then be used to handle bad block management. As the vendor
|
||||
ATF + uboot do not read or interact with the UBI region, we would avoid
|
||||
unwanted remaps from BMT/BBT.
|
||||
|
||||
This commit introduces support for building such a chainloader, by
|
||||
packaging u-boot and DTS into a FIT image; to be flashed like a kernel.
|
||||
|
||||
Configuration for the Gemtek W1700K is provided as an example of how the
|
||||
chainloader is used.
|
||||
|
||||
[1] https://github.com/openwrt/openwrt/pull/17869#discussion_r2836066746
|
||||
[2] https://github.com/openwrt/openwrt/pull/17869#discussion_r2838395671
|
||||
|
||||
Signed-off-by: Kenneth Kasilag <kenneth@kasilag.me>
|
||||
---
|
||||
configs/an7581_w1700k_defconfig | 107 ++++++++++
|
||||
defenvs/an7581_w1700k_env | 21 ++
|
||||
dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts | 87 +++++
|
||||
3 files changed, 215 insertions(+), 0 deletions(-)
|
||||
create mode 100644 configs/an7581_w1700k_defconfig
|
||||
create mode 100644 defenvs/an7581_w1700k_env
|
||||
create mode 100644 dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts
|
||||
|
||||
--- /dev/null
|
||||
+++ b/configs/an7581_w1700k_defconfig
|
||||
@@ -0,0 +1,107 @@
|
||||
+CONFIG_ARM=y
|
||||
+CONFIG_ARCH_AIROHA=y
|
||||
+CONFIG_AUTOBOOT_KEYED=y
|
||||
+CONFIG_AUTOBOOT_MENU_SHOW=y
|
||||
+CONFIG_POSITION_INDEPENDENT=y
|
||||
+CONFIG_TARGET_AN7581=y
|
||||
+CONFIG_TEXT_BASE=0x81E00000
|
||||
+CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
+CONFIG_NR_DRAM_BANKS=1
|
||||
+CONFIG_ENV_SIZE=0x4000
|
||||
+CONFIG_ENV_OFFSET=0x7c000
|
||||
+CONFIG_DM_GPIO=y
|
||||
+CONFIG_DEFAULT_DEVICE_TREE="airoha/an7581-w1700k-ubi"
|
||||
+CONFIG_SYS_LOAD_ADDR=0x81800000
|
||||
+CONFIG_BUILD_TARGET="u-boot.bin"
|
||||
+# CONFIG_EFI_LOADER is not set
|
||||
+CONFIG_FIT=y
|
||||
+CONFIG_FIT_VERBOSE=y
|
||||
+CONFIG_BOOTDELAY=30
|
||||
+CONFIG_DEFAULT_FDT_FILE="an7581-w1700k-ubi"
|
||||
+CONFIG_SYS_PBSIZE=1049
|
||||
+CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
+# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
+CONFIG_HUSH_PARSER=y
|
||||
+CONFIG_SYS_PROMPT="U-Boot> "
|
||||
+CONFIG_SYS_MAXARGS=8
|
||||
+CONFIG_CMD_BOOTZ=y
|
||||
+CONFIG_CMD_BOOTMENU=y
|
||||
+# CONFIG_CMD_ELF is not set
|
||||
+# CONFIG_CMD_XIMG is not set
|
||||
+CONFIG_CMD_BIND=y
|
||||
+CONFIG_CMD_GPIO=y
|
||||
+CONFIG_CMD_MMC=y
|
||||
+CONFIG_CMD_MTD=y
|
||||
+CONFIG_CMD_SF_TEST=y
|
||||
+CONFIG_CMD_SPI=y
|
||||
+# CONFIG_CMD_SETEXPR is not set
|
||||
+CONFIG_CMD_PING=y
|
||||
+CONFIG_CMD_EXT4=y
|
||||
+CONFIG_CMD_FAT=y
|
||||
+CONFIG_CMD_FS_GENERIC=y
|
||||
+CONFIG_CMD_MTDPARTS=y
|
||||
+CONFIG_CMD_LOG=y
|
||||
+CONFIG_OF_UPSTREAM=y
|
||||
+CONFIG_ENV_OVERWRITE=y
|
||||
+CONFIG_ENV_IS_IN_MMC=y
|
||||
+# CONFIG_ENV_IS_IN_MTD is not set
|
||||
+CONFIG_ENV_RELOC_GD_ENV_ADDR=y
|
||||
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
+CONFIG_NET_RANDOM_ETHADDR=y
|
||||
+CONFIG_SYS_RX_ETH_BUFFER=8
|
||||
+CONFIG_REGMAP=y
|
||||
+CONFIG_SYSCON=y
|
||||
+CONFIG_CLK=y
|
||||
+CONFIG_DMA=y
|
||||
+CONFIG_LED=y
|
||||
+CONFIG_LED_GPIO=y
|
||||
+CONFIG_MMC_HS200_SUPPORT=y
|
||||
+CONFIG_MMC_MTK=y
|
||||
+CONFIG_MTD=y
|
||||
+CONFIG_DM_MTD=y
|
||||
+CONFIG_MTD_SPI_NAND=y
|
||||
+CONFIG_DM_SPI_FLASH=y
|
||||
+CONFIG_SPI_FLASH_EON=y
|
||||
+CONFIG_SPI_FLASH_GIGADEVICE=y
|
||||
+CONFIG_SPI_FLASH_ISSI=y
|
||||
+CONFIG_SPI_FLASH_MACRONIX=y
|
||||
+CONFIG_SPI_FLASH_SPANSION=y
|
||||
+CONFIG_SPI_FLASH_STMICRO=y
|
||||
+CONFIG_SPI_FLASH_WINBOND=y
|
||||
+CONFIG_SPI_FLASH_MTD=y
|
||||
+CONFIG_AIROHA_ETH=y
|
||||
+CONFIG_DM_MDIO=y
|
||||
+CONFIG_CMD_MII=y
|
||||
+CONFIG_CMD_MDIO=y
|
||||
+CONFIG_PHY=y
|
||||
+CONFIG_PINCTRL=y
|
||||
+CONFIG_PINCONF=y
|
||||
+CONFIG_POWER_DOMAIN=y
|
||||
+CONFIG_DM_REGULATOR=y
|
||||
+CONFIG_DM_REGULATOR_FIXED=y
|
||||
+CONFIG_RAM=y
|
||||
+CONFIG_DM_SERIAL=y
|
||||
+CONFIG_SYS_NS16550=y
|
||||
+CONFIG_SPI=y
|
||||
+CONFIG_DM_SPI=y
|
||||
+CONFIG_AIROHA_SNFI_SPI=y
|
||||
+CONFIG_CMD_UBI=y
|
||||
+# CONFIG_CMD_UBI_RENAME is not set
|
||||
+CONFIG_CMD_UBIFS=y
|
||||
+CONFIG_ENV_IS_IN_UBI=y
|
||||
+CONFIG_ENV_REDUNDANT=y
|
||||
+CONFIG_ENV_UBI_PART="ubi"
|
||||
+CONFIG_ENV_UBI_VOLUME="ubootenv"
|
||||
+CONFIG_ENV_UBI_VOLUME_REDUND="ubootenv2"
|
||||
+CONFIG_ENV_UBI_VID_OFFSET=0
|
||||
+CONFIG_MTD_UBI=y
|
||||
+CONFIG_MTD_UBI_MODULE=y
|
||||
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
+CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
+# CONFIG_MTD_UBI_FASTMAP is not set
|
||||
+CONFIG_UBI_BLOCK=y
|
||||
+# CONFIG_UBIFS_SILENCE_MSG is not set
|
||||
+# CONFIG_UBIFS_SILENCE_DEBUG_DUMP is not set
|
||||
+CONFIG_ENV_USE_DEFAULT_ENV_TEXT_FILE=y
|
||||
+CONFIG_ENV_DEFAULT_ENV_TEXT_FILE="defenvs/an7581_w1700k_env"
|
||||
+CONFIG_SHA512=y
|
||||
--- /dev/null
|
||||
+++ b/defenvs/an7581_w1700k_env
|
||||
@@ -0,0 +1,27 @@
|
||||
+loadaddr=0x81800000
|
||||
+initaddr=0x89000000
|
||||
+ipaddr=192.168.1.1
|
||||
+serverip=192.168.1.10
|
||||
+bootfile=openwrt-airoha-an7581-gemtek_w1700k-ubi-initramfs-recovery.itb
|
||||
+installfile=openwrt-airoha-an7581-gemtek_w1700k-ubi-initramfs-installer.itb
|
||||
+bootled_pwr=status:red
|
||||
+bootled_rec=status:blue
|
||||
+boot_ubi=ubi part ubi && run boot_production ; run boot_recovery
|
||||
+boot_production=led $bootled_pwr on ; run ubi_read_production && bootm $loadaddr#$bootconf ; led $bootled_pwr off
|
||||
+boot_recovery=led $bootled_rec on ; run ubi_read_recovery ; bootm $initaddr#$bootconf ; led $bootled_rec off
|
||||
+boot_tftp=tftpboot $initaddr $bootfile && bootm $initaddr#$bootconf
|
||||
+boot_installer=tftpboot $initaddr $installfile && bootm $initaddr#$bootconf
|
||||
+bootconf=config-1
|
||||
+bootcmd=boot_ubi
|
||||
+bootdelay=3
|
||||
+bootmenu_confirm_return=askenv - Press ENTER to return to menu ; bootmenu 60
|
||||
+bootmenu_default=0
|
||||
+bootmenu_delay=3
|
||||
+bootmenu_title= 34m( ( ( mOpenWrt34m ) ) )
|
||||
+bootmenu_0=Run default boot command.=run boot_production
|
||||
+bootmenu_1=Boot system via TFTP.=run boot_tftp ; run bootmenu_confirm_return
|
||||
+bootmenu_2=Boot recovery system from flash.=run boot_recovery ; run bootmenu_confirm_return
|
||||
+bootmenu_3=Boot installer via TFTP.=run boot_installer ; run bootmenu_confirm_return
|
||||
+bootmenu_4=Reboot.=reset
|
||||
+ubi_read_production=ubi read $loadaddr fit && iminfo $loadaddr
|
||||
+ubi_read_recovery=ubi check recovery && ubi read $initaddr recovery
|
||||
--- /dev/null
|
||||
+++ b/dts/upstream/src/arm64/airoha/an7581-w1700k-ubi.dts
|
||||
@@ -0,0 +1,131 @@
|
||||
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
+/dts-v1/;
|
||||
+
|
||||
+/* Bootloader installs ATF here */
|
||||
+/memreserve/ 0x80000000 0x200000;
|
||||
+
|
||||
+#include <dt-bindings/input/linux-event-codes.h>
|
||||
+#include <dt-bindings/gpio/gpio.h>
|
||||
+#include "en7581.dtsi"
|
||||
+
|
||||
+/ {
|
||||
+ model = "Gemtek W1700K (UBI)";
|
||||
+ compatible = "gemtek,w1700k-ubi", "airoha,an7581", "airoha,en7581";
|
||||
+
|
||||
+ aliases {
|
||||
+ serial0 = &uart1;
|
||||
+ };
|
||||
+
|
||||
+ chosen {
|
||||
+ stdout-path = "serial0:115200n8";
|
||||
+ linux,usable-memory-range = <0x0 0x80200000 0x0 0x7fe00000>;
|
||||
+ };
|
||||
+
|
||||
+ memory@80000000 {
|
||||
+ device_type = "memory";
|
||||
+ reg = <0x0 0x80000000 0x2 0x00000000>;
|
||||
+ };
|
||||
+
|
||||
+ gpio-keys {
|
||||
+ compatible = "gpio-keys";
|
||||
+
|
||||
+ key-restart {
|
||||
+ label = "reset";
|
||||
+ gpios = <&en7581_pinctrl 0 GPIO_ACTIVE_LOW>;
|
||||
+ linux,code = <KEY_RESTART>;
|
||||
+ };
|
||||
+ };
|
||||
+
|
||||
+ gpio-leds {
|
||||
+ compatible = "gpio-leds";
|
||||
+
|
||||
+ led_status_green {
|
||||
+ label = "status:green";
|
||||
+ gpios = <&en7581_pinctrl 17 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+
|
||||
+ led_status_blue {
|
||||
+ label = "status:blue";
|
||||
+ gpios = <&en7581_pinctrl 19 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+
|
||||
+ led_status_red {
|
||||
+ label = "status:red";
|
||||
+ gpios = <&en7581_pinctrl 29 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+
|
||||
+ led_status_white {
|
||||
+ label = "status:white";
|
||||
+ gpios = <&en7581_pinctrl 20 GPIO_ACTIVE_LOW>;
|
||||
+ default-state = "off";
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&snfi {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&spi_nand {
|
||||
+ partitions {
|
||||
+ compatible = "fixed-partitions";
|
||||
+ #address-cells = <1>;
|
||||
+ #size-cells = <1>;
|
||||
+
|
||||
+ vendor@0 {
|
||||
+ label = "vendor";
|
||||
+ reg = <0x00000000 0x00600000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+
|
||||
+ chainloader@600000 {
|
||||
+ label = "chainloader";
|
||||
+ reg = <0x00600000 0x00100000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+
|
||||
+ ubi@700000 {
|
||||
+ label = "ubi";
|
||||
+ reg = <0x00700000 0x1b700000>;
|
||||
+ };
|
||||
+
|
||||
+ /* reserved for bad block table */
|
||||
+ reserved_bmt@1be00000 {
|
||||
+ label = "reserved_bmt";
|
||||
+ reg = <0x1be00000 0x04200000>;
|
||||
+ read-only;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&en7581_pinctrl {
|
||||
+ gpio-ranges = <&en7581_pinctrl 0 13 47>;
|
||||
+
|
||||
+ pcie0_rst_pins: pcie0-rst-pins {
|
||||
+ conf {
|
||||
+ pins = "pcie_reset0";
|
||||
+ drive-open-drain = <1>;
|
||||
+ };
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+&pcie0 {
|
||||
+ pinctrl-names = "default";
|
||||
+ pinctrl-0 = <&pcie0_rst_pins>;
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&i2c0 {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+ð {
|
||||
+ status = "okay";
|
||||
+};
|
||||
+
|
||||
+&switch {
|
||||
+ status = "okay";
|
||||
+};
|
||||
@@ -237,6 +237,7 @@ CONFIG_MTD_SPLIT_FIT_FW=y
|
||||
CONFIG_MTD_UBI=y
|
||||
CONFIG_MTD_UBI_BEB_LIMIT=20
|
||||
CONFIG_MTD_UBI_BLOCK=y
|
||||
CONFIG_MTD_UBI_NVMEM=y
|
||||
CONFIG_MTD_UBI_WL_THRESHOLD=4096
|
||||
CONFIG_MTK_NET_PHYLIB=y
|
||||
CONFIG_MUTEX_SPIN_ON_OWNER=y
|
||||
@@ -396,6 +397,7 @@ CONFIG_TREE_RCU=y
|
||||
CONFIG_TREE_SRCU=y
|
||||
CONFIG_UBIFS_FS=y
|
||||
# CONFIG_UNMAP_KERNEL_AT_EL0 is not set
|
||||
CONFIG_UIMAGE_FIT_BLK=y
|
||||
CONFIG_USB_SUPPORT=y
|
||||
CONFIG_USER_STACKTRACE_SUPPORT=y
|
||||
CONFIG_VDSO_GETRANDOM=y
|
||||
|
||||
@@ -1003,7 +1003,6 @@
|
||||
gsw_phy1: ethernet-phy@9 {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <9>;
|
||||
interrupts = <1>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -1026,7 +1025,6 @@
|
||||
gsw_phy2: ethernet-phy@a {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <10>;
|
||||
interrupts = <2>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -1049,7 +1047,6 @@
|
||||
gsw_phy3: ethernet-phy@b {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <11>;
|
||||
interrupts = <3>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
@@ -1072,7 +1069,6 @@
|
||||
gsw_phy4: ethernet-phy@c {
|
||||
compatible = "ethernet-phy-ieee802.3-c22";
|
||||
reg = <12>;
|
||||
interrupts = <4>;
|
||||
phy-mode = "internal";
|
||||
status = "disabled";
|
||||
|
||||
|
||||
@@ -12,6 +12,33 @@ define Build/an7581-bl31-uboot
|
||||
cat $(STAGING_DIR_IMAGE)/an7581_$1-bl31-u-boot.fip >> $@
|
||||
endef
|
||||
|
||||
define Build/an7581-chainloader
|
||||
$(INSTALL_DIR) $(KDIR)/chainload-fit-$(notdir $@)
|
||||
@if [ -f "$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin.lzma" ]; then \
|
||||
KERNEL="$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin.lzma"; \
|
||||
COMP="lzma"; \
|
||||
else \
|
||||
KERNEL="$(STAGING_DIR_IMAGE)/an7581_$1-u-boot.bin"; \
|
||||
COMP="none"; \
|
||||
fi; \
|
||||
$(TOPDIR)/scripts/mkits.sh \
|
||||
-D $(DEVICE_NAME) \
|
||||
-o $(KDIR)/chainload-fit-$(notdir $@)/u-boot.its \
|
||||
-k $$KERNEL \
|
||||
-C $$COMP \
|
||||
-a 0x80200000 -e 0x80200000 \
|
||||
-c conf-uboot \
|
||||
-A arm64 -v u-boot \
|
||||
-d $(STAGING_DIR_IMAGE)/an7581_$1-u-boot.dtb \
|
||||
-s 0x82000000
|
||||
PATH=$(LINUX_DIR)/scripts/dtc:$(PATH) \
|
||||
$(STAGING_DIR_HOST)/bin/mkimage \
|
||||
-D "-i $(KDIR)/chainload-fit-$(notdir $@)" \
|
||||
-f $(KDIR)/chainload-fit-$(notdir $@)/u-boot.its \
|
||||
$(STAGING_DIR_IMAGE)/an7581_$1-chainload-u-boot.itb
|
||||
cat $(STAGING_DIR_IMAGE)/an7581_$1-chainload-u-boot.itb >> $@
|
||||
endef
|
||||
|
||||
define Device/FitImageLzma
|
||||
KERNEL_SUFFIX := -uImage.itb
|
||||
KERNEL = kernel-bin | lzma | fit lzma $$(KDIR)/image-$$(DEVICE_DTS).dtb
|
||||
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
From b61fcc3c7f95734e14741d8787fc9eb69b8437d4 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Sat, 11 Apr 2026 22:47:15 +0100
|
||||
Subject: [PATCH 1/2] PM / devfreq: mtk-cci: use devres for resource management
|
||||
in probe
|
||||
|
||||
Convert mtk_ccifreq_probe() to use devm-managed resource cleanup
|
||||
instead of manual goto-based error handling.
|
||||
|
||||
This pattern (devm_add_action_or_reset with a regulator disable
|
||||
callback) is well-established in the kernel, used by drivers such as
|
||||
ads7846, max6639 and others.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/devfreq/mtk-cci-devfreq.c | 150 +++++++++++++++---------------
|
||||
1 file changed, 73 insertions(+), 77 deletions(-)
|
||||
|
||||
--- a/drivers/devfreq/mtk-cci-devfreq.c
|
||||
+++ b/drivers/devfreq/mtk-cci-devfreq.c
|
||||
@@ -246,6 +246,21 @@ static struct devfreq_dev_profile mtk_cc
|
||||
.target = mtk_ccifreq_target,
|
||||
};
|
||||
|
||||
+static void mtk_ccifreq_regulator_disable(void *data)
|
||||
+{
|
||||
+ regulator_disable(data);
|
||||
+}
|
||||
+
|
||||
+static void mtk_ccifreq_clk_disable_unprepare(void *data)
|
||||
+{
|
||||
+ clk_disable_unprepare(data);
|
||||
+}
|
||||
+
|
||||
+static void mtk_ccifreq_opp_of_remove_table(void *data)
|
||||
+{
|
||||
+ dev_pm_opp_of_remove_table(data);
|
||||
+}
|
||||
+
|
||||
static int mtk_ccifreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -266,44 +281,47 @@ static int mtk_ccifreq_probe(struct plat
|
||||
platform_set_drvdata(pdev, drv);
|
||||
|
||||
drv->cci_clk = devm_clk_get(dev, "cci");
|
||||
- if (IS_ERR(drv->cci_clk)) {
|
||||
- ret = PTR_ERR(drv->cci_clk);
|
||||
- return dev_err_probe(dev, ret, "failed to get cci clk\n");
|
||||
- }
|
||||
+ if (IS_ERR(drv->cci_clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(drv->cci_clk),
|
||||
+ "failed to get cci clk\n");
|
||||
|
||||
drv->inter_clk = devm_clk_get(dev, "intermediate");
|
||||
- if (IS_ERR(drv->inter_clk)) {
|
||||
- ret = PTR_ERR(drv->inter_clk);
|
||||
- return dev_err_probe(dev, ret,
|
||||
+ if (IS_ERR(drv->inter_clk))
|
||||
+ return dev_err_probe(dev, PTR_ERR(drv->inter_clk),
|
||||
"failed to get intermediate clk\n");
|
||||
- }
|
||||
|
||||
drv->proc_reg = devm_regulator_get_optional(dev, "proc");
|
||||
- if (IS_ERR(drv->proc_reg)) {
|
||||
- ret = PTR_ERR(drv->proc_reg);
|
||||
- return dev_err_probe(dev, ret,
|
||||
+ if (IS_ERR(drv->proc_reg))
|
||||
+ return dev_err_probe(dev, PTR_ERR(drv->proc_reg),
|
||||
"failed to get proc regulator\n");
|
||||
- }
|
||||
|
||||
ret = regulator_enable(drv->proc_reg);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to enable proc regulator\n");
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "failed to enable proc regulator\n");
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev, mtk_ccifreq_regulator_disable,
|
||||
+ drv->proc_reg);
|
||||
+ if (ret)
|
||||
return ret;
|
||||
- }
|
||||
|
||||
drv->sram_reg = devm_regulator_get_optional(dev, "sram");
|
||||
if (IS_ERR(drv->sram_reg)) {
|
||||
- ret = PTR_ERR(drv->sram_reg);
|
||||
- if (ret == -EPROBE_DEFER)
|
||||
- goto out_free_resources;
|
||||
+ if (PTR_ERR(drv->sram_reg) == -EPROBE_DEFER)
|
||||
+ return -EPROBE_DEFER;
|
||||
|
||||
drv->sram_reg = NULL;
|
||||
} else {
|
||||
ret = regulator_enable(drv->sram_reg);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to enable sram regulator\n");
|
||||
- goto out_free_resources;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "failed to enable sram regulator\n");
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev,
|
||||
+ mtk_ccifreq_regulator_disable,
|
||||
+ drv->sram_reg);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -317,31 +335,36 @@ static int mtk_ccifreq_probe(struct plat
|
||||
|
||||
ret = clk_prepare_enable(drv->cci_clk);
|
||||
if (ret)
|
||||
- goto out_free_resources;
|
||||
+ return ret;
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev, mtk_ccifreq_clk_disable_unprepare,
|
||||
+ drv->cci_clk);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
ret = dev_pm_opp_of_add_table(dev);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to add opp table: %d\n", ret);
|
||||
- goto out_disable_cci_clk;
|
||||
- }
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret, "failed to add opp table\n");
|
||||
+
|
||||
+ ret = devm_add_action_or_reset(dev, mtk_ccifreq_opp_of_remove_table,
|
||||
+ dev);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
rate = clk_get_rate(drv->inter_clk);
|
||||
opp = dev_pm_opp_find_freq_ceil(dev, &rate);
|
||||
- if (IS_ERR(opp)) {
|
||||
- ret = PTR_ERR(opp);
|
||||
- dev_err(dev, "failed to get intermediate opp: %d\n", ret);
|
||||
- goto out_remove_opp_table;
|
||||
- }
|
||||
+ if (IS_ERR(opp))
|
||||
+ return dev_err_probe(dev, PTR_ERR(opp),
|
||||
+ "failed to get intermediate opp\n");
|
||||
+
|
||||
drv->inter_voltage = dev_pm_opp_get_voltage(opp);
|
||||
dev_pm_opp_put(opp);
|
||||
|
||||
rate = U32_MAX;
|
||||
opp = dev_pm_opp_find_freq_floor(drv->dev, &rate);
|
||||
- if (IS_ERR(opp)) {
|
||||
- dev_err(dev, "failed to get opp\n");
|
||||
- ret = PTR_ERR(opp);
|
||||
- goto out_remove_opp_table;
|
||||
- }
|
||||
+ if (IS_ERR(opp))
|
||||
+ return dev_err_probe(dev, PTR_ERR(opp),
|
||||
+ "failed to get opp\n");
|
||||
|
||||
opp_volt = dev_pm_opp_get_voltage(opp);
|
||||
dev_pm_opp_put(opp);
|
||||
@@ -349,63 +372,36 @@ static int mtk_ccifreq_probe(struct plat
|
||||
if (ret) {
|
||||
dev_err(dev, "failed to scale to highest voltage %lu in proc_reg\n",
|
||||
opp_volt);
|
||||
- goto out_remove_opp_table;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
passive_data = devm_kzalloc(dev, sizeof(*passive_data), GFP_KERNEL);
|
||||
- if (!passive_data) {
|
||||
- ret = -ENOMEM;
|
||||
- goto out_remove_opp_table;
|
||||
- }
|
||||
+ if (!passive_data)
|
||||
+ return -ENOMEM;
|
||||
|
||||
passive_data->parent_type = CPUFREQ_PARENT_DEV;
|
||||
drv->devfreq = devm_devfreq_add_device(dev, &mtk_ccifreq_profile,
|
||||
DEVFREQ_GOV_PASSIVE,
|
||||
passive_data);
|
||||
- if (IS_ERR(drv->devfreq)) {
|
||||
- ret = -EPROBE_DEFER;
|
||||
- dev_err(dev, "failed to add devfreq device: %ld\n",
|
||||
- PTR_ERR(drv->devfreq));
|
||||
- goto out_remove_opp_table;
|
||||
- }
|
||||
+ if (IS_ERR(drv->devfreq))
|
||||
+ return dev_err_probe(dev, -EPROBE_DEFER,
|
||||
+ "failed to add devfreq device: %ld\n",
|
||||
+ PTR_ERR(drv->devfreq));
|
||||
|
||||
drv->opp_nb.notifier_call = mtk_ccifreq_opp_notifier;
|
||||
ret = dev_pm_opp_register_notifier(dev, &drv->opp_nb);
|
||||
- if (ret) {
|
||||
- dev_err(dev, "failed to register opp notifier: %d\n", ret);
|
||||
- goto out_remove_opp_table;
|
||||
- }
|
||||
- return 0;
|
||||
-
|
||||
-out_remove_opp_table:
|
||||
- dev_pm_opp_of_remove_table(dev);
|
||||
-
|
||||
-out_disable_cci_clk:
|
||||
- clk_disable_unprepare(drv->cci_clk);
|
||||
-
|
||||
-out_free_resources:
|
||||
- if (regulator_is_enabled(drv->proc_reg))
|
||||
- regulator_disable(drv->proc_reg);
|
||||
- if (!IS_ERR_OR_NULL(drv->sram_reg) &&
|
||||
- regulator_is_enabled(drv->sram_reg))
|
||||
- regulator_disable(drv->sram_reg);
|
||||
+ if (ret)
|
||||
+ return dev_err_probe(dev, ret,
|
||||
+ "failed to register opp notifier\n");
|
||||
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static void mtk_ccifreq_remove(struct platform_device *pdev)
|
||||
{
|
||||
- struct device *dev = &pdev->dev;
|
||||
- struct mtk_ccifreq_drv *drv;
|
||||
-
|
||||
- drv = platform_get_drvdata(pdev);
|
||||
+ struct mtk_ccifreq_drv *drv = platform_get_drvdata(pdev);
|
||||
|
||||
- dev_pm_opp_unregister_notifier(dev, &drv->opp_nb);
|
||||
- dev_pm_opp_of_remove_table(dev);
|
||||
- clk_disable_unprepare(drv->cci_clk);
|
||||
- regulator_disable(drv->proc_reg);
|
||||
- if (drv->sram_reg)
|
||||
- regulator_disable(drv->sram_reg);
|
||||
+ dev_pm_opp_unregister_notifier(&pdev->dev, &drv->opp_nb);
|
||||
}
|
||||
|
||||
static const struct mtk_ccifreq_platform_data mt8183_platform_data = {
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
From b19968e432fe2ebe3af4bc9190923edb70b6aeee Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Golle <daniel@makrotopia.org>
|
||||
Date: Mon, 13 Apr 2026 15:22:05 +0100
|
||||
Subject: [PATCH 2/2] PM / devfreq: mtk-cci: check cpufreq availability early
|
||||
|
||||
Check spufreq availablility early at probe so -EPROBE_DEFER is emitted
|
||||
before touching any regulators.
|
||||
|
||||
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
|
||||
---
|
||||
drivers/devfreq/mtk-cci-devfreq.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/drivers/devfreq/mtk-cci-devfreq.c
|
||||
+++ b/drivers/devfreq/mtk-cci-devfreq.c
|
||||
@@ -4,6 +4,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
+#include <linux/cpufreq.h>
|
||||
#include <linux/devfreq.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/module.h>
|
||||
@@ -263,13 +264,28 @@ static void mtk_ccifreq_opp_of_remove_ta
|
||||
|
||||
static int mtk_ccifreq_probe(struct platform_device *pdev)
|
||||
{
|
||||
+ struct devfreq_passive_data *passive_data;
|
||||
struct device *dev = &pdev->dev;
|
||||
+ struct cpufreq_policy *policy;
|
||||
struct mtk_ccifreq_drv *drv;
|
||||
- struct devfreq_passive_data *passive_data;
|
||||
struct dev_pm_opp *opp;
|
||||
unsigned long rate, opp_volt;
|
||||
int ret;
|
||||
|
||||
+ /*
|
||||
+ * Check if cpufreq is available before touching any regulators.
|
||||
+ * The passive devfreq governor needs cpufreq as its parent and
|
||||
+ * will return -EPROBE_DEFER if it is not yet registered. If we
|
||||
+ * enable the proc regulator (CPU core power) before this check,
|
||||
+ * the subsequent probe failure causes devres to disable that
|
||||
+ * regulator, potentially cutting CPU core voltage and hanging
|
||||
+ * the system.
|
||||
+ */
|
||||
+ policy = cpufreq_cpu_get(0);
|
||||
+ if (!policy)
|
||||
+ return -EPROBE_DEFER;
|
||||
+ cpufreq_cpu_put(policy);
|
||||
+
|
||||
drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
|
||||
if (!drv)
|
||||
return -ENOMEM;
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
From 67219f0130ec7c876ac0b299046460fad31caabf Mon Sep 17 00:00:00 2001
|
||||
From: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Mon, 30 Mar 2026 16:00:50 -0400
|
||||
Subject: fix pathological slowness & incorrect mappings in iconv gb18030
|
||||
decoder
|
||||
|
||||
in order to implement the "UTF" aspect of gb18030 (ability to
|
||||
represent arbitrary unicode characters not present in the 2-byte
|
||||
mapping), we have to apply the index obtained from the encoded 4-byte
|
||||
sequence into the set of unmapped characters. this was done by
|
||||
scanning repeatedly over the table of mapped characters and counting
|
||||
off mapped characters below a running index by which to adjust the
|
||||
running index by on each iteration. this iterative process eventually
|
||||
leaves us with the value of the Nth unmapped character replacing the
|
||||
index, but depending on which particular character that is, the number
|
||||
of iterations needed to find it can be in the tens of thousands, and
|
||||
each iteration traverses the whole 126x190 table in the inner loop.
|
||||
this can lead to run times exceeding an entire second per character on
|
||||
moderate-speed machines.
|
||||
|
||||
on top of that, the transformation logic produced wrong results for
|
||||
BMP characters above the the surrogate range, as a result of not
|
||||
correctly accounting for it being excluded, and for characters outside
|
||||
the BMP, as a result of a misunderstanding of how gb18030 encodes
|
||||
them.
|
||||
|
||||
this patch replaces the unmapped character lookup with a single linear
|
||||
search of a list of unmapped ranges. there are only 206 such ranges,
|
||||
and these are permanently assigned and unchangeable as a consequence
|
||||
of the character encoding having to be stable, so a simple array of
|
||||
16-bit start/length values for each range consumes only 824 bytes, a
|
||||
very reasonable size cost here.
|
||||
|
||||
this new table accounts for the previously-incorrect surrogate
|
||||
handling, and non-BMP characters are handled correctly by a single
|
||||
offset, without the need for any unmapped-range search.
|
||||
|
||||
there are still a small number of mappings that are incorrect due to
|
||||
late changes made in the definition of gb18030, swapping PUA
|
||||
codepoints with proper Unicode characters. correcting these requires a
|
||||
postprocessing step that will be added later.
|
||||
---
|
||||
src/locale/gb18030utf.h | 206 ++++++++++++++++++++++++++++++++++++++++
|
||||
src/locale/iconv.c | 33 +++++--
|
||||
2 files changed, 230 insertions(+), 9 deletions(-)
|
||||
create mode 100644 src/locale/gb18030utf.h
|
||||
|
||||
--- /dev/null
|
||||
+++ b/src/locale/gb18030utf.h
|
||||
@@ -0,0 +1,206 @@
|
||||
+{ 0x80, 36 },
|
||||
+{ 0xa5, 2 },
|
||||
+{ 0xa9, 7 },
|
||||
+{ 0xb2, 5 },
|
||||
+{ 0xb8, 31 },
|
||||
+{ 0xd8, 8 },
|
||||
+{ 0xe2, 6 },
|
||||
+{ 0xeb, 1 },
|
||||
+{ 0xee, 4 },
|
||||
+{ 0xf4, 3 },
|
||||
+{ 0xf8, 1 },
|
||||
+{ 0xfb, 1 },
|
||||
+{ 0xfd, 4 },
|
||||
+{ 0x102, 17 },
|
||||
+{ 0x114, 7 },
|
||||
+{ 0x11c, 15 },
|
||||
+{ 0x12c, 24 },
|
||||
+{ 0x145, 3 },
|
||||
+{ 0x149, 4 },
|
||||
+{ 0x14e, 29 },
|
||||
+{ 0x16c, 98 },
|
||||
+{ 0x1cf, 1 },
|
||||
+{ 0x1d1, 1 },
|
||||
+{ 0x1d3, 1 },
|
||||
+{ 0x1d5, 1 },
|
||||
+{ 0x1d7, 1 },
|
||||
+{ 0x1d9, 1 },
|
||||
+{ 0x1db, 1 },
|
||||
+{ 0x1dd, 28 },
|
||||
+{ 0x1fa, 87 },
|
||||
+{ 0x252, 15 },
|
||||
+{ 0x262, 101 },
|
||||
+{ 0x2c8, 1 },
|
||||
+{ 0x2cc, 13 },
|
||||
+{ 0x2da, 183 },
|
||||
+{ 0x3a2, 1 },
|
||||
+{ 0x3aa, 7 },
|
||||
+{ 0x3c2, 1 },
|
||||
+{ 0x3ca, 55 },
|
||||
+{ 0x402, 14 },
|
||||
+{ 0x450, 1 },
|
||||
+{ 0x452, 7102 },
|
||||
+{ 0x2011, 2 },
|
||||
+{ 0x2017, 1 },
|
||||
+{ 0x201a, 2 },
|
||||
+{ 0x201e, 7 },
|
||||
+{ 0x2027, 9 },
|
||||
+{ 0x2031, 1 },
|
||||
+{ 0x2034, 1 },
|
||||
+{ 0x2036, 5 },
|
||||
+{ 0x203c, 112 },
|
||||
+{ 0x20ad, 86 },
|
||||
+{ 0x2104, 1 },
|
||||
+{ 0x2106, 3 },
|
||||
+{ 0x210a, 12 },
|
||||
+{ 0x2117, 10 },
|
||||
+{ 0x2122, 62 },
|
||||
+{ 0x216c, 4 },
|
||||
+{ 0x217a, 22 },
|
||||
+{ 0x2194, 2 },
|
||||
+{ 0x219a, 110 },
|
||||
+{ 0x2209, 6 },
|
||||
+{ 0x2210, 1 },
|
||||
+{ 0x2212, 3 },
|
||||
+{ 0x2216, 4 },
|
||||
+{ 0x221b, 2 },
|
||||
+{ 0x2221, 2 },
|
||||
+{ 0x2224, 1 },
|
||||
+{ 0x2226, 1 },
|
||||
+{ 0x222c, 2 },
|
||||
+{ 0x222f, 5 },
|
||||
+{ 0x2238, 5 },
|
||||
+{ 0x223e, 10 },
|
||||
+{ 0x2249, 3 },
|
||||
+{ 0x224d, 5 },
|
||||
+{ 0x2253, 13 },
|
||||
+{ 0x2262, 2 },
|
||||
+{ 0x2268, 6 },
|
||||
+{ 0x2270, 37 },
|
||||
+{ 0x2296, 3 },
|
||||
+{ 0x229a, 11 },
|
||||
+{ 0x22a6, 25 },
|
||||
+{ 0x22c0, 82 },
|
||||
+{ 0x2313, 333 },
|
||||
+{ 0x246a, 10 },
|
||||
+{ 0x249c, 100 },
|
||||
+{ 0x254c, 4 },
|
||||
+{ 0x2574, 13 },
|
||||
+{ 0x2590, 3 },
|
||||
+{ 0x2596, 10 },
|
||||
+{ 0x25a2, 16 },
|
||||
+{ 0x25b4, 8 },
|
||||
+{ 0x25be, 8 },
|
||||
+{ 0x25c8, 3 },
|
||||
+{ 0x25cc, 2 },
|
||||
+{ 0x25d0, 18 },
|
||||
+{ 0x25e6, 31 },
|
||||
+{ 0x2607, 2 },
|
||||
+{ 0x260a, 54 },
|
||||
+{ 0x2641, 1 },
|
||||
+{ 0x2643, 2110 },
|
||||
+{ 0x2e82, 2 },
|
||||
+{ 0x2e85, 3 },
|
||||
+{ 0x2e89, 2 },
|
||||
+{ 0x2e8d, 10 },
|
||||
+{ 0x2e98, 15 },
|
||||
+{ 0x2ea8, 2 },
|
||||
+{ 0x2eab, 3 },
|
||||
+{ 0x2eaf, 4 },
|
||||
+{ 0x2eb4, 2 },
|
||||
+{ 0x2eb8, 3 },
|
||||
+{ 0x2ebc, 14 },
|
||||
+{ 0x2ecb, 293 },
|
||||
+{ 0x2ffc, 4 },
|
||||
+{ 0x3004, 1 },
|
||||
+{ 0x3018, 5 },
|
||||
+{ 0x301f, 2 },
|
||||
+{ 0x302a, 20 },
|
||||
+{ 0x303f, 2 },
|
||||
+{ 0x3094, 7 },
|
||||
+{ 0x309f, 2 },
|
||||
+{ 0x30f7, 5 },
|
||||
+{ 0x30ff, 6 },
|
||||
+{ 0x312a, 246 },
|
||||
+{ 0x322a, 7 },
|
||||
+{ 0x3232, 113 },
|
||||
+{ 0x32a4, 234 },
|
||||
+{ 0x3390, 12 },
|
||||
+{ 0x339f, 2 },
|
||||
+{ 0x33a2, 34 },
|
||||
+{ 0x33c5, 9 },
|
||||
+{ 0x33cf, 2 },
|
||||
+{ 0x33d3, 2 },
|
||||
+{ 0x33d6, 113 },
|
||||
+{ 0x3448, 43 },
|
||||
+{ 0x3474, 298 },
|
||||
+{ 0x359f, 111 },
|
||||
+{ 0x360f, 11 },
|
||||
+{ 0x361b, 765 },
|
||||
+{ 0x3919, 85 },
|
||||
+{ 0x396f, 96 },
|
||||
+{ 0x39d1, 14 },
|
||||
+{ 0x39e0, 147 },
|
||||
+{ 0x3a74, 218 },
|
||||
+{ 0x3b4f, 287 },
|
||||
+{ 0x3c6f, 113 },
|
||||
+{ 0x3ce1, 885 },
|
||||
+{ 0x4057, 264 },
|
||||
+{ 0x4160, 471 },
|
||||
+{ 0x4338, 116 },
|
||||
+{ 0x43ad, 4 },
|
||||
+{ 0x43b2, 43 },
|
||||
+{ 0x43de, 248 },
|
||||
+{ 0x44d7, 373 },
|
||||
+{ 0x464d, 20 },
|
||||
+{ 0x4662, 193 },
|
||||
+{ 0x4724, 5 },
|
||||
+{ 0x472a, 82 },
|
||||
+{ 0x477d, 16 },
|
||||
+{ 0x478e, 441 },
|
||||
+{ 0x4948, 50 },
|
||||
+{ 0x497b, 2 },
|
||||
+{ 0x497e, 4 },
|
||||
+{ 0x4984, 1 },
|
||||
+{ 0x4987, 20 },
|
||||
+{ 0x499c, 3 },
|
||||
+{ 0x49a0, 22 },
|
||||
+{ 0x49b8, 703 },
|
||||
+{ 0x4c78, 39 },
|
||||
+{ 0x4ca4, 111 },
|
||||
+{ 0x4d1a, 148 },
|
||||
+{ 0x4daf, 81 },
|
||||
+{ 0x9fa6, 14426 },
|
||||
+{ 0xe76c, 1 },
|
||||
+{ 0xe7c8, 1 },
|
||||
+{ 0xe7e7, 13 },
|
||||
+{ 0xe815, 1 },
|
||||
+{ 0xe819, 5 },
|
||||
+{ 0xe81f, 7 },
|
||||
+{ 0xe827, 4 },
|
||||
+{ 0xe82d, 4 },
|
||||
+{ 0xe833, 8 },
|
||||
+{ 0xe83c, 7 },
|
||||
+{ 0xe844, 16 },
|
||||
+{ 0xe856, 14 },
|
||||
+{ 0xe865, 4295 },
|
||||
+{ 0xf92d, 76 },
|
||||
+{ 0xf97a, 27 },
|
||||
+{ 0xf996, 81 },
|
||||
+{ 0xf9e8, 9 },
|
||||
+{ 0xf9f2, 26 },
|
||||
+{ 0xfa10, 1 },
|
||||
+{ 0xfa12, 1 },
|
||||
+{ 0xfa15, 3 },
|
||||
+{ 0xfa19, 6 },
|
||||
+{ 0xfa22, 1 },
|
||||
+{ 0xfa25, 2 },
|
||||
+{ 0xfa2a, 1030 },
|
||||
+{ 0xfe32, 1 },
|
||||
+{ 0xfe45, 4 },
|
||||
+{ 0xfe53, 1 },
|
||||
+{ 0xfe58, 1 },
|
||||
+{ 0xfe67, 1 },
|
||||
+{ 0xfe6c, 149 },
|
||||
+{ 0xff5f, 129 },
|
||||
+{ 0xffe6, 26 },
|
||||
--- a/src/locale/iconv.c
|
||||
+++ b/src/locale/iconv.c
|
||||
@@ -74,6 +74,10 @@ static const unsigned short gb18030[126]
|
||||
#include "gb18030.h"
|
||||
};
|
||||
|
||||
+static const unsigned short gb18030utf[][2] = {
|
||||
+#include "gb18030utf.h"
|
||||
+};
|
||||
+
|
||||
static const unsigned short big5[89][157] = {
|
||||
#include "big5.h"
|
||||
};
|
||||
@@ -224,6 +228,8 @@ static unsigned uni_to_jis(unsigned c)
|
||||
}
|
||||
}
|
||||
|
||||
+#define countof(a) (sizeof (a) / sizeof *(a))
|
||||
+
|
||||
size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
|
||||
{
|
||||
size_t x=0;
|
||||
@@ -423,15 +429,24 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
d = *((unsigned char *)*in + 3);
|
||||
if (d-'0'>9) goto ilseq;
|
||||
c += d-'0';
|
||||
- c += 128;
|
||||
- for (d=0; d<=c; ) {
|
||||
- k = 0;
|
||||
- for (int i=0; i<126; i++)
|
||||
- for (int j=0; j<190; j++)
|
||||
- if (gb18030[i][j]-d <= c-d)
|
||||
- k++;
|
||||
- d = c+1;
|
||||
- c += k;
|
||||
+ /* Starting at 90 30 81 30 (189000), mapping is
|
||||
+ * linear without gaps, to U+10000 and up. */
|
||||
+ if (c >= 189000) {
|
||||
+ c -= 189000;
|
||||
+ c += 0x10000;
|
||||
+ if (c >= 0x110000) goto ilseq;
|
||||
+ break;
|
||||
+ }
|
||||
+ /* Otherwise we must process an index into set
|
||||
+ * of characters unmapped by 2-byte table. */
|
||||
+ for (int i=0; ; i++) {
|
||||
+ if (i==countof(gb18030utf))
|
||||
+ goto ilseq;
|
||||
+ if (c<gb18030utf[i][1]) {
|
||||
+ c += gb18030utf[i][0];
|
||||
+ break;
|
||||
+ }
|
||||
+ c -= gb18030utf[i][1];
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
From 228da39e38c1cae13cbe637e771412c1984dba5d Mon Sep 17 00:00:00 2001
|
||||
From: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Thu, 9 Apr 2026 22:51:30 -0400
|
||||
Subject: qsort: fix leonardo heap corruption from bug in doubleword ctz
|
||||
primitive
|
||||
|
||||
the pntz function, implementing a "count trailing zeros" variant for a
|
||||
bit vector consisting of two size_t words, erroneously returned zero
|
||||
rather than the number of bits in the low word when the first bit set
|
||||
was the low bit of the high word.
|
||||
|
||||
as a result, a loop in the trinkle function which should have a
|
||||
guaranteed small bound on the number of iterations, could run
|
||||
unboundedly, thereby overflowing a stack-based working-space array
|
||||
which was sized for the bound.
|
||||
|
||||
CVE-2026-40200 has been assigned for this issue.
|
||||
---
|
||||
src/stdlib/qsort.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
--- a/src/stdlib/qsort.c
|
||||
+++ b/src/stdlib/qsort.c
|
||||
@@ -34,11 +34,11 @@
|
||||
|
||||
typedef int (*cmpfun)(const void *, const void *, void *);
|
||||
|
||||
+/* returns index of first bit set, excluding the low bit assumed to always
|
||||
+ * be set, starting from low bit of p[0] up through high bit of p[1] */
|
||||
static inline int pntz(size_t p[2]) {
|
||||
- int r = ntz(p[0] - 1);
|
||||
- if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) {
|
||||
- return r;
|
||||
- }
|
||||
+ if (p[0] != 1) return ntz(p[0] - 1);
|
||||
+ if (p[1]) return 8*sizeof(size_t) + ntz(p[1]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
From b3291b9a9f77f1f993d2b4f8c68a26cf09221ae7 Mon Sep 17 00:00:00 2001
|
||||
From: Rich Felker <dalias@aerifal.cx>
|
||||
Date: Thu, 9 Apr 2026 23:40:53 -0400
|
||||
Subject: qsort: hard-preclude oob array writes independent of any invariants
|
||||
|
||||
while the root cause of CVE-2026-40200 was a faulty ctz primitive, the
|
||||
fallout of the bug would have been limited to erroneous sorting or
|
||||
infinite loop if not for the stores to a stack-based array that
|
||||
depended on trusting invariants in order not to go out of bounds.
|
||||
|
||||
increase the size of the array to a power of two so that we can mask
|
||||
indices into it to force them into range. in the absence of any
|
||||
further bug, the masking is a no-op, but it does not have any
|
||||
measurable performance cost, and it makes spatial memory safety
|
||||
trivial to prove (and for readers not familiar with the algorithms to
|
||||
trust).
|
||||
---
|
||||
src/stdlib/qsort.c | 20 +++++++++++++-------
|
||||
1 file changed, 13 insertions(+), 7 deletions(-)
|
||||
|
||||
--- a/src/stdlib/qsort.c
|
||||
+++ b/src/stdlib/qsort.c
|
||||
@@ -89,10 +89,16 @@ static inline void shr(size_t p[2], int
|
||||
p[1] >>= n;
|
||||
}
|
||||
|
||||
+/* power-of-two length for working array so that we can mask indices and
|
||||
+ * not depend on any invariant of the algorithm for spatial memory safety.
|
||||
+ * the original size was just 14*sizeof(size_t)+1 */
|
||||
+#define AR_LEN (16 * sizeof(size_t))
|
||||
+#define AR_MASK (AR_LEN - 1)
|
||||
+
|
||||
static void sift(unsigned char *head, size_t width, cmpfun cmp, void *arg, int pshift, size_t lp[])
|
||||
{
|
||||
unsigned char *rt, *lf;
|
||||
- unsigned char *ar[14 * sizeof(size_t) + 1];
|
||||
+ unsigned char *ar[AR_LEN];
|
||||
int i = 1;
|
||||
|
||||
ar[0] = head;
|
||||
@@ -104,16 +110,16 @@ static void sift(unsigned char *head, si
|
||||
break;
|
||||
}
|
||||
if(cmp(lf, rt, arg) >= 0) {
|
||||
- ar[i++] = lf;
|
||||
+ ar[i++ & AR_MASK] = lf;
|
||||
head = lf;
|
||||
pshift -= 1;
|
||||
} else {
|
||||
- ar[i++] = rt;
|
||||
+ ar[i++ & AR_MASK] = rt;
|
||||
head = rt;
|
||||
pshift -= 2;
|
||||
}
|
||||
}
|
||||
- cycle(width, ar, i);
|
||||
+ cycle(width, ar, i & AR_MASK);
|
||||
}
|
||||
|
||||
static void trinkle(unsigned char *head, size_t width, cmpfun cmp, void *arg, size_t pp[2], int pshift, int trusty, size_t lp[])
|
||||
@@ -121,7 +127,7 @@ static void trinkle(unsigned char *head,
|
||||
unsigned char *stepson,
|
||||
*rt, *lf;
|
||||
size_t p[2];
|
||||
- unsigned char *ar[14 * sizeof(size_t) + 1];
|
||||
+ unsigned char *ar[AR_LEN];
|
||||
int i = 1;
|
||||
int trail;
|
||||
|
||||
@@ -142,7 +148,7 @@ static void trinkle(unsigned char *head,
|
||||
}
|
||||
}
|
||||
|
||||
- ar[i++] = stepson;
|
||||
+ ar[i++ & AR_MASK] = stepson;
|
||||
head = stepson;
|
||||
trail = pntz(p);
|
||||
shr(p, trail);
|
||||
@@ -150,7 +156,7 @@ static void trinkle(unsigned char *head,
|
||||
trusty = 0;
|
||||
}
|
||||
if(!trusty) {
|
||||
- cycle(width, ar, i);
|
||||
+ cycle(width, ar, i & AR_MASK);
|
||||
sift(head, width, cmp, arg, pshift, lp);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
From 5122f9f3c99fee366167c5de98b31546312921ab Mon Sep 17 00:00:00 2001
|
||||
From: Luca Kellermann <mailto.luca.kellermann@gmail.com>
|
||||
Date: Fri, 10 Apr 2026 03:03:22 +0200
|
||||
Subject: qsort: fix shift UB in shl and shr
|
||||
|
||||
if shl() or shr() are called with n==8*sizeof(size_t), n is adjusted
|
||||
to 0. the shift by (sizeof(size_t) * 8 - n) that then follows will
|
||||
consequently shift by the width of size_t, which is UB and in practice
|
||||
produces an incorrect result.
|
||||
|
||||
return early in this case. the bitvector p was already shifted by the
|
||||
required amount.
|
||||
---
|
||||
src/stdlib/qsort.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
--- a/src/stdlib/qsort.c
|
||||
+++ b/src/stdlib/qsort.c
|
||||
@@ -71,6 +71,7 @@ static inline void shl(size_t p[2], int
|
||||
n -= 8 * sizeof(size_t);
|
||||
p[1] = p[0];
|
||||
p[0] = 0;
|
||||
+ if (!n) return;
|
||||
}
|
||||
p[1] <<= n;
|
||||
p[1] |= p[0] >> (sizeof(size_t) * 8 - n);
|
||||
@@ -83,6 +84,7 @@ static inline void shr(size_t p[2], int
|
||||
n -= 8 * sizeof(size_t);
|
||||
p[0] = p[1];
|
||||
p[1] = 0;
|
||||
+ if (!n) return;
|
||||
}
|
||||
p[0] >>= n;
|
||||
p[0] |= p[1] << (sizeof(size_t) * 8 - n);
|
||||
@@ -24,7 +24,7 @@
|
||||
static const unsigned short jis0208[84][94] = {
|
||||
#include "jis0208.h"
|
||||
};
|
||||
@@ -85,6 +88,7 @@ static const unsigned short hkscs[] = {
|
||||
@@ -89,6 +92,7 @@ static const unsigned short hkscs[] = {
|
||||
static const unsigned short ksc[93][94] = {
|
||||
#include "ksc.h"
|
||||
};
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
static const unsigned short rev_jis[] = {
|
||||
#include "revjis.h"
|
||||
@@ -205,6 +209,7 @@ static unsigned legacy_map(const unsigne
|
||||
@@ -209,6 +213,7 @@ static unsigned legacy_map(const unsigne
|
||||
return x < 256 ? x : legacy_chars[x-256];
|
||||
}
|
||||
|
||||
@@ -40,15 +40,15 @@
|
||||
static unsigned uni_to_jis(unsigned c)
|
||||
{
|
||||
unsigned nel = sizeof rev_jis / sizeof *rev_jis;
|
||||
@@ -223,6 +228,7 @@ static unsigned uni_to_jis(unsigned c)
|
||||
@@ -227,6 +232,7 @@ static unsigned uni_to_jis(unsigned c)
|
||||
}
|
||||
}
|
||||
}
|
||||
+#endif
|
||||
|
||||
size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
|
||||
{
|
||||
@@ -319,6 +325,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
#define countof(a) (sizeof (a) / sizeof *(a))
|
||||
|
||||
@@ -325,6 +331,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
}
|
||||
type = scd->state;
|
||||
continue;
|
||||
@@ -56,7 +56,7 @@
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) break;
|
||||
if (c-0xa1 <= 0xdf-0xa1) {
|
||||
@@ -518,6 +525,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
@@ -533,6 +540,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
c = ksc[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
@@ -64,7 +64,7 @@
|
||||
default:
|
||||
if (!c) break;
|
||||
c = legacy_map(map, c);
|
||||
@@ -559,6 +567,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
@@ -574,6 +582,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
}
|
||||
}
|
||||
goto subst;
|
||||
@@ -72,7 +72,7 @@
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) goto revout;
|
||||
if (c == 0xa5) {
|
||||
@@ -632,6 +641,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
@@ -647,6 +656,7 @@ size_t iconv(iconv_t cd, char **restrict
|
||||
*(*out)++ = 'B';
|
||||
*outb -= 8;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user