summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--chip/stm32/build.mk2
-rw-r--r--chip/stm32/config-stm32f07x.h3
-rw-r--r--chip/stm32/config-stm32f373.h3
-rw-r--r--chip/stm32/config-stm32f4.h3
-rw-r--r--chip/stm32/config-stm32f76x.h3
-rw-r--r--chip/stm32/config-stm32g41xb.h3
-rw-r--r--chip/stm32/config-stm32g473xc.h3
-rw-r--r--chip/stm32/config-stm32h7x3.h3
-rw-r--r--chip/stm32/config-stm32l100.h3
-rw-r--r--chip/stm32/config-stm32l15x.h3
-rw-r--r--chip/stm32/config-stm32l431.h3
-rw-r--r--chip/stm32/config-stm32l442.h3
-rw-r--r--chip/stm32/config-stm32l476.h3
-rw-r--r--chip/stm32/config-stm32l552xe.h3
-rw-r--r--chip/stm32/dfu_bootmanager_main.c181
-rw-r--r--chip/stm32/dfu_bootmanager_shared.c52
-rw-r--r--chip/stm32/dfu_bootmanager_shared.h62
-rw-r--r--chip/stm32/usb_dfu_runtime.c3
-rw-r--r--common/build.mk2
-rw-r--r--include/config.h18
-rw-r--r--include/task.h2
-rw-r--r--util/config_allowed.txt3
23 files changed, 366 insertions, 2 deletions
diff --git a/Makefile b/Makefile
index e0aff80f67..43712434a3 100644
--- a/Makefile
+++ b/Makefile
@@ -212,7 +212,8 @@ _mock_cfg := $(foreach t,$(_mock_lst) ,HAS_MOCK_$(t))
CPPFLAGS += $(foreach t,$(_mock_cfg),-D$(t)=$(EMPTY))
$(foreach c,$(_mock_cfg),$(eval $(c)=y))
-ifneq "$(CONFIG_COMMON_RUNTIME)" "y"
+ifneq ($(CONFIG_COMMON_RUNTIME),y)
+ifneq ($(CONFIG_DFU_BOOTMANAGER_MAIN),ro)
_irq_list:=$(shell $(CPP) $(CPPFLAGS) -P -Ichip/$(CHIP) -I$(BASEDIR) \
-I$(BDIR) -D"ENABLE_IRQ(x)=EN_IRQ x" \
-imacros chip/$(CHIP)/registers.h \
@@ -220,6 +221,7 @@ ifneq "$(CONFIG_COMMON_RUNTIME)" "y"
CPPFLAGS+=$(foreach irq,$(_irq_list),\
-D"irq_$(irq)_handler_optional=irq_$(irq)_handler")
endif
+endif
# Compute RW firmware size and offset
_rw_off_str:=$(shell echo "CONFIG_RW_MEM_OFF" | $(CPP) $(CPPFLAGS) -P \
diff --git a/chip/stm32/build.mk b/chip/stm32/build.mk
index 3990b8d4d7..5eefc00d4f 100644
--- a/chip/stm32/build.mk
+++ b/chip/stm32/build.mk
@@ -81,6 +81,8 @@ chip-$(CHIP_FAMILY_STM32F3)+=flash-f.o
chip-$(CHIP_FAMILY_STM32F4)+=flash-f.o
endif
chip-$(CONFIG_ADC)+=adc-$(CHIP_FAMILY).o
+chip-$(CONFIG_DFU_BOOTMANAGER_MAIN)+=dfu_bootmanager_main.o
+chip-$(CONFIG_DFU_BOOTMANAGER_SHARED)+=dfu_bootmanager_shared.o
chip-$(CONFIG_DFU_RUNTIME)+=usb_dfu_runtime.o
chip-$(CONFIG_STM32_CHARGER_DETECT)+=charger_detect.o
chip-$(CONFIG_DEBUG_PRINTF)+=debug_printf.o
diff --git a/chip/stm32/config-stm32f07x.h b/chip/stm32/config-stm32f07x.h
index 918a117a22..2aa8f6d37d 100644
--- a/chip/stm32/config-stm32f07x.h
+++ b/chip/stm32/config-stm32f07x.h
@@ -27,3 +27,6 @@
#define CONFIG_USB_RAM_SIZE 1024
#define CONFIG_USB_RAM_ACCESS_TYPE uint16_t
#define CONFIG_USB_RAM_ACCESS_SIZE 2
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fffC800
diff --git a/chip/stm32/config-stm32f373.h b/chip/stm32/config-stm32f373.h
index 3df5bfce67..7694db4421 100644
--- a/chip/stm32/config-stm32f373.h
+++ b/chip/stm32/config-stm32f373.h
@@ -23,3 +23,6 @@
#define CONFIG_USB_RAM_SIZE 512
#define CONFIG_USB_RAM_ACCESS_TYPE uint32_t
#define CONFIG_USB_RAM_ACCESS_SIZE 4
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fffd800
diff --git a/chip/stm32/config-stm32f4.h b/chip/stm32/config-stm32f4.h
index 73c9a3694f..46303444fc 100644
--- a/chip/stm32/config-stm32f4.h
+++ b/chip/stm32/config-stm32f4.h
@@ -70,3 +70,6 @@
#define CONFIG_IRQ_COUNT 97
#undef CONFIG_CMD_CHARGEN
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32f76x.h b/chip/stm32/config-stm32f76x.h
index d027ad62fb..aa7f7ac5c0 100644
--- a/chip/stm32/config-stm32f76x.h
+++ b/chip/stm32/config-stm32f76x.h
@@ -58,3 +58,6 @@
/* Number of IRQ vectors on the NVIC */
#define CONFIG_IRQ_COUNT 109
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1ff00000
diff --git a/chip/stm32/config-stm32g41xb.h b/chip/stm32/config-stm32g41xb.h
index 4f1ed96871..d6ec8696fb 100644
--- a/chip/stm32/config-stm32g41xb.h
+++ b/chip/stm32/config-stm32g41xb.h
@@ -58,3 +58,6 @@
#define CONFIG_USB_RAM_SIZE 1024
#define CONFIG_USB_RAM_ACCESS_TYPE uint16_t
#define CONFIG_USB_RAM_ACCESS_SIZE 2
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32g473xc.h b/chip/stm32/config-stm32g473xc.h
index 1cb5133121..0317b69491 100644
--- a/chip/stm32/config-stm32g473xc.h
+++ b/chip/stm32/config-stm32g473xc.h
@@ -63,3 +63,6 @@
#define CONFIG_USB_RAM_SIZE 1024
#define CONFIG_USB_RAM_ACCESS_TYPE uint16_t
#define CONFIG_USB_RAM_ACCESS_SIZE 2
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32h7x3.h b/chip/stm32/config-stm32h7x3.h
index da94b09069..11da24b849 100644
--- a/chip/stm32/config-stm32h7x3.h
+++ b/chip/stm32/config-stm32h7x3.h
@@ -71,3 +71,6 @@
#define MPU_ATTR_FLASH_MEMORY 0x02
/* SRAM Data is Normal memory type / non-shareable / write-back, write-alloc */
#define MPU_ATTR_INTERNAL_SRAM 0x0B
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1ff00000
diff --git a/chip/stm32/config-stm32l100.h b/chip/stm32/config-stm32l100.h
index 2c4efcc6df..2132fab4dd 100644
--- a/chip/stm32/config-stm32l100.h
+++ b/chip/stm32/config-stm32l100.h
@@ -41,3 +41,6 @@
#define CONFIG_USB_RAM_SIZE 512
#define CONFIG_USB_RAM_ACCESS_TYPE uint32_t
#define CONFIG_USB_RAM_ACCESS_SIZE 4
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1ff00000
diff --git a/chip/stm32/config-stm32l15x.h b/chip/stm32/config-stm32l15x.h
index 0b32f95572..9f957d8981 100644
--- a/chip/stm32/config-stm32l15x.h
+++ b/chip/stm32/config-stm32l15x.h
@@ -42,3 +42,6 @@
#define CONFIG_USB_RAM_SIZE 512
#define CONFIG_USB_RAM_ACCESS_TYPE uint32_t
#define CONFIG_USB_RAM_ACCESS_SIZE 4
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1ff00000
diff --git a/chip/stm32/config-stm32l431.h b/chip/stm32/config-stm32l431.h
index 7021bc2ce8..64d8d39327 100644
--- a/chip/stm32/config-stm32l431.h
+++ b/chip/stm32/config-stm32l431.h
@@ -75,3 +75,6 @@
#define WP_BANK_COUNT 63
#define PSTATE_BANK 62
#define PSTATE_BANK_COUNT 1
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32l442.h b/chip/stm32/config-stm32l442.h
index 54ba9bac8d..8a2a284d69 100644
--- a/chip/stm32/config-stm32l442.h
+++ b/chip/stm32/config-stm32l442.h
@@ -22,3 +22,6 @@
/* Number of IRQ vectors on the NVIC */
#define CONFIG_IRQ_COUNT 82
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32l476.h b/chip/stm32/config-stm32l476.h
index 2e0084fd94..7f6fbb0f84 100644
--- a/chip/stm32/config-stm32l476.h
+++ b/chip/stm32/config-stm32l476.h
@@ -18,3 +18,6 @@
/* Number of IRQ vectors on the NVIC */
#define CONFIG_IRQ_COUNT 82
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x1fff0000
diff --git a/chip/stm32/config-stm32l552xe.h b/chip/stm32/config-stm32l552xe.h
index dab0400775..1b9c34c4aa 100644
--- a/chip/stm32/config-stm32l552xe.h
+++ b/chip/stm32/config-stm32l552xe.h
@@ -34,3 +34,6 @@
/* Number of DMA channels supported (8 channels each for DMA1 and DMA2) */
#define DMAC_COUNT 16
+
+/* DFU Address */
+#define STM32_DFU_BASE 0x0bf90000
diff --git a/chip/stm32/dfu_bootmanager_main.c b/chip/stm32/dfu_bootmanager_main.c
new file mode 100644
index 0000000000..462dd08b60
--- /dev/null
+++ b/chip/stm32/dfu_bootmanager_main.c
@@ -0,0 +1,181 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * DFU Boot Manager Main for STM32
+ *
+ * When the Boot Manager Main is enabled, the RO application skips the
+ * common runtime and setup. This reduces the flash size and avoids clock,
+ * interrupt, and setup steps which conflict with the built in Boot Loaders
+ * while minimizing the Flash Size.
+ *
+ * The Boot Manager Main will perform self checks of the Flash and backup
+ * memory. Based on these results it will boot into the DFU or RW Application.
+ */
+
+#include "clock.h"
+#include "dfu_bootmanager_shared.h"
+#include "flash.h"
+#include "registers.h"
+#include "task.h"
+
+#ifdef CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT
+#if CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT <= 0 || \
+ CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT > DFU_BOOTMANAGER_VALUE_DFU
+#error "Max reboot count is out of range"
+#endif
+#endif /* CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT */
+
+/*
+ * Checks if the RW region is valid by reading the first 8 bytes of flash, it
+ * should not start with an erased block.
+ *
+ * The DFU boot manager should not jump into the RW region if it contains
+ * invalid code as the EC is be unstable. A check will be performed to validate
+ * the start of the RW region to verify that it contains valid data.
+ * DFU programmers should erase this section of flash first and at this point,
+ * the EC will no longer be able to jump into the RW application.
+ *
+ * The normal DFU programming sequence programming will work, but by
+ * splitting into the following sequence we can protect against additional
+ * failures.
+ *
+ * 1. Erase the first RW flash section. This will lock the EC out of RW.
+ * 2. Update the remaining flash. Erase, program, and read back flash to
+ * to verify the operation was successful. Regions of the flash which
+ * are difficult to repair if an error occurs should be programmed next.
+ * 3. Program the first RW flash section and exit DFU mode if verification is
+ * successful.
+ *
+ * @return 1 if erased, 0 if not erased
+ */
+static int rw_is_empty(void)
+{
+ return crec_flash_is_erased(CONFIG_RW_MEM_OFF, 8);
+}
+
+/*
+ * Reads the backup registers. This will trigger a jump to DFU if either
+ * the application has requested it or if the reboot counter indicates
+ * the device is likely in a bad state. A counter recording the number
+ * of reboots will be incremented.
+ *
+ * @returns True if the backup memory region indicates we should boot into DFU.
+ */
+static bool backup_boot_checks(void)
+{
+ uint8_t value;
+
+ if (dfu_bootmanager_backup_read(&value)) {
+ /* Value stored is not valid, set it to a valid value. */
+ dfu_bootmanager_backup_write(DFU_BOOTMANAGER_VALUE_CLEAR);
+ return false;
+ }
+ if (value == DFU_BOOTMANAGER_VALUE_DFU)
+ return true;
+#ifdef CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT
+ if (value >= CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT)
+ return true;
+ /* Increment the reboot loop counter. */
+ value++;
+ dfu_bootmanager_backup_write(value);
+#endif /* CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT */
+ return false;
+}
+
+/*
+ * Performs the minimal set of initialization required for the boot manager.
+ * The main application region or DFU boot loader have different prerequisites,
+ * any configurations that are enabled either need to be benign with both
+ * images or disabled prior to the jumps.
+ */
+static void dfu_bootmanager_init(void)
+{
+ /* enable clock on Power module */
+#ifndef CHIP_FAMILY_STM32H7
+#ifdef CHIP_FAMILY_STM32L4
+ STM32_RCC_APB1ENR1 |= STM32_RCC_PWREN;
+#else
+ STM32_RCC_APB1ENR |= STM32_RCC_PWREN;
+#endif
+#endif
+#if defined(CHIP_FAMILY_STM32F4)
+ /* enable backup registers */
+ STM32_RCC_AHB1ENR |= STM32_RCC_AHB1ENR_BKPSRAMEN;
+#elif defined(CHIP_FAMILY_STM32H7)
+ /* enable backup registers */
+ STM32_RCC_AHB4ENR |= BIT(28);
+#elif defined(CHIP_FAMILY_STM32L4)
+ /* enable RTC APB clock */
+ STM32_RCC_APB1ENR1 |= STM32_RCC_APB1ENR1_RTCAPBEN;
+#else
+ /* enable backup registers */
+ STM32_RCC_APB1ENR |= BIT(27);
+#endif
+ /* Delay 1 APB clock cycle after the clock is enabled */
+ clock_wait_bus_cycles(BUS_APB, 1);
+ /* Enable access to RCC CSR register and RTC backup registers */
+ STM32_PWR_CR |= BIT(8);
+}
+
+static void jump_to_rw(void)
+{
+ void (*addr)(void);
+
+ addr = (void (*)(void)) (*((uint32_t *) (CONFIG_PROGRAM_MEMORY_BASE +
+ CONFIG_RW_MEM_OFF + 4)));
+
+ addr();
+}
+
+static void jump_to_dfu(void)
+{
+ void (*addr)(void);
+
+ addr = (void (*)(void)) (*((uint32_t *) (STM32_DFU_BASE + 4)));
+
+ /* Clear the scratchpad. */
+ dfu_bootmanager_backup_write(DFU_BOOTMANAGER_VALUE_CLEAR);
+ addr();
+}
+
+/*
+ * DFU Boot Manager main. It'll check if the RW region is not fully programmed
+ * or if the backup memory indicates we should reboot into DFU.
+ */
+int main(void)
+{
+ dfu_bootmanager_init();
+
+ if (rw_is_empty() || backup_boot_checks())
+ jump_to_dfu();
+ jump_to_rw();
+
+ return 0;
+}
+
+/*
+ * The RW application will replace the vector table and exception handlers
+ * shortly after the jump. If the application is corrupt and fails before
+ * this, the only action that can be done is jumping into DFU mode.
+ */
+void exception_panic(void)
+{
+ dfu_bootmanager_enter_dfu();
+}
+
+/*
+ * Function stubs which are required by bkpdata.c and system.c:
+ * Interrupts are always disabled in the Boot Manager so we do not
+ * need to worry about concurrent access.
+ */
+
+void task_clear_pending_irq(int irq) {}
+void interrupt_disable(void) {}
+void mutex_lock(mutex_t *mtx) {}
+void mutex_unlock(mutex_t *mtx) {}
+
+bool in_interrupt_context(void)
+{
+ return false;
+}
diff --git a/chip/stm32/dfu_bootmanager_shared.c b/chip/stm32/dfu_bootmanager_shared.c
new file mode 100644
index 0000000000..212ee0a9e9
--- /dev/null
+++ b/chip/stm32/dfu_bootmanager_shared.c
@@ -0,0 +1,52 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * DFU Boot Manager shared utilities for STM32
+ */
+
+#include "bkpdata.h"
+#include "clock.h"
+#include "dfu_bootmanager_shared.h"
+#include "flash.h"
+#include "registers.h"
+#include "task.h"
+
+/*
+ * The Servo platforms do not have any free backup regions. The scratchpad
+ * is only with the console command scratchpad and on some of the tests so
+ * we'll use the scratchpad region.
+ */
+#ifdef CONFIG_CMD_SCRATCHPAD
+#error "The scratchpad is used, define a backup region for the DFU fields."
+#endif /* CONFIG_CMD_SCRATCHPAD */
+
+int dfu_bootmanager_enter_dfu(void)
+{
+ dfu_bootmanager_backup_write(DFU_BOOTMANAGER_VALUE_DFU);
+ system_reset(0);
+ return 0;
+}
+
+void dfu_bootmanager_clear(void)
+{
+ dfu_bootmanager_backup_write(DFU_BOOTMANAGER_VALUE_CLEAR);
+}
+
+void dfu_bootmanager_backup_write(uint8_t value)
+{
+ uint16_t data = DFU_BOOTMANAGER_VALID_CHECK | value;
+
+ bkpdata_write(BKPDATA_INDEX_SCRATCHPAD, data);
+}
+
+int dfu_bootmanager_backup_read(uint8_t *value)
+{
+ uint16_t data = bkpdata_read(BKPDATA_INDEX_SCRATCHPAD);
+ uint16_t valid_check = data & DFU_BOOTMANAGER_VALID_MASK;
+
+ *value = (uint8_t)(data & DFU_BOOTMANAGER_VALUE_MASK);
+ if (valid_check != DFU_BOOTMANAGER_VALID_CHECK)
+ return EC_ERROR_UNKNOWN;
+ return EC_SUCCESS;
+}
diff --git a/chip/stm32/dfu_bootmanager_shared.h b/chip/stm32/dfu_bootmanager_shared.h
new file mode 100644
index 0000000000..4003583ee2
--- /dev/null
+++ b/chip/stm32/dfu_bootmanager_shared.h
@@ -0,0 +1,62 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * DFU Boot Manager shared utilities for STM32
+ *
+ * These of utilities required by the Boot Manager Main and RW Application.
+ * These allow the systems to start the sequence to enter DFU, clear the
+ * state, and access the backup registers.
+ */
+
+#ifndef __DFU_BOOTMANAGER_SHARED_H
+#define __DFU_BOOTMANAGER_SHARED_H
+
+#include "common.h"
+
+/* Registers to validate the backup memory region. */
+#define DFU_BOOTMANAGER_VALUE_MASK 0x00FF
+#define DFU_BOOTMANAGER_VALID_MASK 0xFF00
+#define DFU_BOOTMANAGER_VALID_CHECK 0xAA00
+
+#define DFU_BOOTMANAGER_VALUE_CLEAR 0
+#define DFU_BOOTMANAGER_VALUE_DFU UINT8_MAX
+
+/*
+ * Reset and enter the DFU mode.
+ *
+ * The system will set flags to the backup memory to enter DFU and issue
+ * a reset. The Boot Manager will send the system to DFU mode.
+ *
+ * @return EC_SUCCESS, or non-zero if error.
+ */
+int dfu_bootmanager_enter_dfu(void);
+
+/*
+ * Clear the DFU Boot Manager backup memory state.
+ *
+ * If the CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT setting is enabled, this
+ * allows the RW application to clear the counter to indicate the application
+ * is working as expected.
+ */
+void dfu_bootmanager_clear(void);
+
+/*
+ * Write the value to the backup registers and sets the bitmasks
+ * indicating the field is valid.
+ *
+ * @param value New value to store.
+ */
+void dfu_bootmanager_backup_write(uint8_t value);
+
+/*
+ * Reads the backup registers and performs validation. The value stored
+ * within the VALUE_MASK is returned and the status code indicates
+ * if the valid check passed.
+ *
+ * @param value[out] Value stored within the DFU_BOOTMANAGER_VALUE_MASK
+ * @return EC_SUCCESS, or non-zero if validation failed.
+ */
+int dfu_bootmanager_backup_read(uint8_t *value);
+
+#endif /* __DFU_BOOTMANAGER_SHARED_H */
diff --git a/chip/stm32/usb_dfu_runtime.c b/chip/stm32/usb_dfu_runtime.c
index b902f32af2..7626faec8e 100644
--- a/chip/stm32/usb_dfu_runtime.c
+++ b/chip/stm32/usb_dfu_runtime.c
@@ -3,6 +3,7 @@
* found in the LICENSE file.
*/
+#include "dfu_bootmanager_shared.h"
#include "registers.h"
#include "usb_descriptor.h"
#include "usb_dfu_runtime.h"
@@ -51,7 +52,7 @@ static int dfu_runtime_request(usb_uint *ep0_buf_rx, usb_uint *ep0_buf_tx)
/* Host is requesting a jump from application to DFU mode. */
STM32_TOGGLE_EP(0, EP_TX_RX_MASK, EP_TX_RX_VALID, 0);
- return 0;
+ return dfu_bootmanager_enter_dfu();
} else if (packet.bmRequestType ==
(USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) {
if (packet.bRequest == USB_DFU_RUNTIME_REQ_GET_STATUS) {
diff --git a/common/build.mk b/common/build.mk
index d00a7f8bb1..25dbce2333 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -215,9 +215,11 @@ common-$(CONFIG_AUDIO_CODEC_WOV)+=hotword_dsp_api.o
endif
ifneq ($(CONFIG_COMMON_RUNTIME),)
+ifneq ($(CONFIG_DFU_BOOTMANAGER_MAIN),ro)
common-$(CONFIG_MALLOC)+=shmalloc.o
common-$(call not_cfg,$(CONFIG_MALLOC))+=shared_mem.o
endif
+endif
ifeq ($(CTS_MODULE),)
common-$(TEST_BUILD)+=test_util.o
diff --git a/include/config.h b/include/config.h
index a7cbf5a6fe..393db87432 100644
--- a/include/config.h
+++ b/include/config.h
@@ -5425,6 +5425,24 @@
#undef CONFIG_DFU_RUNTIME
/*
+ * Indicates this region is a DFU Boot Manager and is a minimal runtime.
+ */
+#undef CONFIG_DFU_BOOTMANAGER_MAIN
+/*
+ * Enables DFU Boot Manager reboot loop protection. When unexpected reboots
+ * occur, a counter is incremented which will enter DFU once it exceeds
+ * the value defined. This parameter should only be enabled on setups which
+ * can issue the command to exit DFU.
+ */
+#undef CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT
+
+/*
+ * Enables access to shared utilities required for the application
+ * and DFU Boot Manager. This allows the application to enter DFU.
+ */
+#undef CONFIG_DFU_BOOTMANAGER_SHARED
+
+/*
* If defined, charge_get_state returns a special status if battery is
* discharging and battery is nearly full.
*/
diff --git a/include/task.h b/include/task.h
index a99c2af79e..d2a19e7a52 100644
--- a/include/task.h
+++ b/include/task.h
@@ -463,7 +463,9 @@ struct irq_def {
/* Include ec.irqlist here for compilation dependency */
#define ENABLE_IRQ(x)
+#if !defined(CONFIG_DFU_BOOTMANAGER_MAIN)
#include "ec.irqlist"
+#endif /* !defined(CONFIG_DFU_BOOTMANAGER_MAIN) */
#endif /* CONFIG_COMMON_RUNTIME */
#endif /* !CONFIG_ZEPHYR */
diff --git a/util/config_allowed.txt b/util/config_allowed.txt
index 805ff8b627..abe12413cc 100644
--- a/util/config_allowed.txt
+++ b/util/config_allowed.txt
@@ -362,6 +362,9 @@ CONFIG_DELAY_DSW_PWROK_TO_PWRBTN
CONFIG_DETACHABLE_BASE
CONFIG_DEVICE_EVENT
CONFIG_DEVICE_STATE
+CONFIG_DFU_BOOTMANAGER_MAIN
+CONFIG_DFU_BOOTMANAGER_MAX_REBOOT_COUNT
+CONFIG_DFU_BOOTMANAGER_SHARED
CONFIG_DFU_RUNTIME
CONFIG_DMA
CONFIG_DMA_DEFAULT_HANDLERS