ITE Tech makes 8051-based laptop embedded controllers (EC), such as the IT5570. Their chips have a hardware mechanism to check if e-flash firmware is programmed by a 16-byte signature check at power-on. The default code address for this is 0x40.
The introduction of the atomic functions in r14916 ("Full atomic_flag for mcs51, ds390. Some infrastructure for lock-free atomics.") introduces a conflict with this address.
HOME segment, reset vector is silently moved to 0x50, producing an unbootable imageHOME segment, reset vector remain at 0Using debian:trixie-20251208-slim container:
# sdcc --version
SDCC : mcs51/z80/z180/r2k/r2ka/r3ka/sm83/tlcs90/ez80_z80/z80n/r800/ds390/TININative/ds400/hc08/s08/stm8/pdk13/pdk14/pdk15/mos6502/mos65c02/f8 TD- 4.5.0 #15242 (Linux)
main.c:
// ITE code signature for eSPI host
static __code const unsigned char __at(0x40) SIGNATURE[16] = {
0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA4, 0x95,
0x85, 0x12, 0x5A, 0x5A, 0xAA, 0x00, 0x55, 0x55,
};
void main(void) {
for (;;) {}
}
Built with:
sdcc -mmcs51 --model-large --Werror -o main.ihx main.c
According to the datasheet, the signature can be at any 16-byte aligned at 0x40-0xF0.
The 8051-based SoC datasheets are still only available under NDA, but the RISC-V ones are publicly available and have the same functions. e.g.: IT82302:
Doing a quick search, the signature was fixed and documented in this Zephyr pull request: https://github.com/zephyrproject-rtos/zephyr/pull/36379
...Which is more informative than the literal datasheets, because it actually defines the LPC/eSPI bus function in byte 7.
Proprietary firmware for the 8051-based SoCs still use 0x40, so I'd like to continue using that for the signature for parity if possible. But can at least look into using 0x80 to match the RISC-V Zephyr SoCs.
Last edit: Tim Crawford 2026-01-08
If this signature can indeed be moved that would be the most easy way to fix this.
The alternative is to modify SDCC itself as the start up code with the interrupt vectors and the atomic functions is generated when main() is compiled.
https://sourceforge.net/p/sdcc/code/HEAD/tree/trunk/sdcc/src/mcs51/main.c#l339
Or to rename main() to e.g. mymain() and create your own startup.asm from the currently generated main.asm.
Note that the sdcc_atomic_* functions must start at a multiple of 8 address for the rollback to work properly.
Once the linker can handle .bndry directives the generated sdcc_atomic_* implementations can be moved into a separate module.