startup: clear MAP_FLASH_PAGE_TO_XDATA before the C runtime initialises xdata

Hardware reset starts the firmware with SFR 0x97 = 1, which maps xdata
0x4000-0xbfff to the flash image: reads return flash bytes, writes are
lost. main() cleared it only after __mcs51_genXINIT and the XSEG clear
had run, so XISEG (initialised globals) and the part of XSEG above
0x4000 kept stale RAM contents, e.g. session_timeout = 4484 and LLDP
blocked on logical ports 0, 3 and 5. Clear it in
__sdcc_external_startup(), which SDCC calls before both.

Rename SFR_97 to MAP_FLASH_PAGE_TO_XDATA.
This commit is contained in:
Andre Brait committed 2026-10-26 17:08:27 +01:00
1 parent 80a30b705e
commit 98763e3bff
4 files changed
+17 -3

No files matched your search

+6
View File
@@ -47,6 +47,12 @@
- The web UI and the configuration upload now refuse a line the replay cannot take, - The web UI and the configuration upload now refuse a line the replay cannot take,
instead of writing it to flash. instead of writing it to flash.
- Startup
- Initialised and zero-initialised globals above xdata 0x4000 now get their values at boot.
Hardware reset leaves SFR 0x97 at 1, which maps xdata 0x4000-0xbfff to the flash image,
and it was cleared only in `main()`, after the C startup code had copied and cleared them.
This showed as a random web session timeout and LLDP blocked on some ports without config.
## Breaking changes ## Breaking changes
- Config - Config
+1 -1
View File
@@ -348,7 +348,7 @@ void installer(void)
{ {
CKCON = 0; // Initial Clock configuration CKCON = 0; // Initial Clock configuration
SFR_97 = 0; // HADDR? MAP_FLASH_PAGE_TO_XDATA = 0; // HADDR?
// Set in managed mode: // Set in managed mode:
SFR_b9 = 0x00; SFR_b9 = 0x00;
+1 -1
View File
@@ -55,7 +55,7 @@ __sfr __at(0xbb) SFR_BANK_RET;
__sfr __at(0x8e) CKCON; __sfr __at(0x8e) CKCON;
__sfr __at(0x97) SFR_97; // HADDR? __sfr __at(0x97) MAP_FLASH_PAGE_TO_XDATA; // 1 (hardware reset default): xdata 0x4000-0xbfff reads the flash image; 0: RAM
__sfr __at(0xb9) SFR_b9; __sfr __at(0xb9) SFR_b9;
__sfr __at(0xba) SFR_ba; __sfr __at(0xba) SFR_ba;
+9 -1
View File
@@ -1567,6 +1567,15 @@ void check_and_flash_update_image(void)
} }
/* Called by the SDCC startup code before it copies XINIT to XISEG and clears XSEG.
* Hardware reset starts us with MAP_FLASH_PAGE_TO_XDATA = 1, which maps xdata
* 0x4000-0xbfff to the flash image (reads return flash, writes are lost), so it
* must be 0 by then. */
unsigned char __sdcc_external_startup(void)
{
MAP_FLASH_PAGE_TO_XDATA = 0;
return 0;
}
void main(void) void main(void)
{ {
@@ -1577,7 +1586,6 @@ void main(void)
sbuf_ptr = 0; sbuf_ptr = 0;
CKCON = 0; // Initial Clock configuration CKCON = 0; // Initial Clock configuration
SFR_97 = 0; // HADDR?
// Set in managed mode: // Set in managed mode:
SFR_b9 = 0x00; SFR_b9 = 0x00;