Component
Dasharo firmware
Device
ASRock Rack TURIND8UD-2T/X550
Dasharo version
v0.9.0 (UEFI & LinuxBoot)
Dasharo Tools Suite version
No response
Test case ID
No response
Brief summary
No POST code ever reaches the BMC. The onboard two digit code display works,
so the codes are being written, but the BMC's POST code log stays empty for
every boot.
The FCH has two eSPI controllers, each with its own pins and its own decode
register. A device is wired to one of them. On this board the code display is
on eSPI 0 and the BMC is on eSPI 1, and firmware opens the port 0x80 window on
eSPI 0 only, so the cycles never reach the bus the BMC is on.
Setting the same bit on eSPI 1 at runtime is enough to make POST codes appear
in the BMC, with the code display still working, so the two windows are
independent and both can be open at once.
How reproducible
100%
How to reproduce
-
Boot the host and open the POST code page in the BMC web interface. It is
empty for the current boot, while the onboard code display shows codes
during boot as normal.
-
From the host, read the port 0x80 decode bit of both eSPI controllers.
Bit 2 is the port 0x80 window:
sudo busybox devmem 0xfec20040 32
sudo busybox devmem 0xfec30040 32
eSPI 0 reads 0x707, so bit 2 is set. eSPI 1 reads 0x30F00, so bit 2 is
clear.
-
Write a byte to port 0x80 from the host and reload the BMC's POST code
page. Nothing new appears:
printf "\347" | sudo dd of=/dev/port bs=1 seek=$((0x80)) count=1
-
Open the same window on eSPI 1. With both windows open the FCH alternates
between the two buses, so take port 0x80 off eSPI 0 for the moment to make
a single write deterministic, then repeat the write:
sudo busybox devmem 0xfec30040 32 0x30F04
sudo busybox devmem 0xfec20040 32 0x703
printf "\347" | sudo dd of=/dev/port bs=1 seek=$((0x80)) count=1
e7 now shows up in the BMC's POST code log. The code display is unchanged
while eSPI 0 has no window.
-
Put eSPI 0 back and write the same byte twice, one dd per write so both
land on port 0x80. A doubled write always survives the alternation, so it
arrives with both windows open and the code display working:
sudo busybox devmem 0xfec20040 32 0x707
printf "\347" | sudo dd of=/dev/port bs=1 seek=$((0x80)) count=1
printf "\347" | sudo dd of=/dev/port bs=1 seek=$((0x80)) count=1
The BMC web interface fetches the POST code log when the page is created and
does not poll, so the page has to be reloaded to see anything new.
Expected behavior
The BMC receives the POST codes that firmware writes to port 0x80, so its
POST code log is populated for every boot.
Actual behavior
The BMC's POST code log is empty for every boot. Nothing reaches it until bit
2 of the eSPI 1 decode register is set by hand from the host, which is lost on
the next power cycle.
Additional context
- Measured on Dasharo (coreboot+LinuxBoot). The window is opened in coreboot
before the payload runs, so UEFI is affected the same way.
- With both windows open the FCH does not put the cycle on both buses, it
alternates strictly, one cycle to each. Writing port 0x80 a hundred times
from the host delivered fifty to the BMC, twice in a row, and a sequence of
the values 1 to 100 came back as its odd half with no even value anywhere.
- Writing each of thirty two values twice delivered all thirty two, so a
value written twice always survives the split, while a value written once
goes to one consumer or the other.
arch_post_code() writes each code once, a single outb to
CONFIG_POST_IO_PORT, and this board defines no mainboard_post. So with
both windows open a boot log is halved, and the alternation is visible in
firmware codes too. The early order is 40 in romstage, 13 and 6e from
c_start.S, 39 and 6f from hardwaremain.c, then 70 as the first
boot state, each with one call site. One boot logged 40 6e 6f, positions
one, three and five of those six, and another logged 13 39 70, positions
two, four and six. One of them ends 9c 43 7b, BS_PAYLOAD_BOOT, and the
other ends 76 79 7a fe f8, so which of the closing codes the BMC keeps
varies by boot.
- same issue on vendor firmware
Solutions you've tried
espi_open_io_window() programs the first controller and stops, which is
why espi_open_io_window(0x80, 1) reaches only the code display on this
board. Writing bit 2 of 0xfec30040 from the mainboard code as well is
enough, and it does not disturb the eSPI 0 window.
- Programming the BMC's side as a generic IO window instead of the standard
port 0x80 decode bit, base 0x0080 in 0xfec30080 with size 0 in
0xfec30088, changes nothing. The alternation is about two controllers
claiming one address rather than about which decode matched it.
- Taking port 0x80 off eSPI 0 instead,
0xfec20040 to 0x703, gives the BMC
every write, a hundred out of a hundred, and leaves the code display unchanged.
That is a trade between the two consumers rather than a fix, so opening the
window on both controllers is the better default.
Component
Dasharo firmware
Device
ASRock Rack TURIND8UD-2T/X550
Dasharo version
v0.9.0 (UEFI & LinuxBoot)
Dasharo Tools Suite version
No response
Test case ID
No response
Brief summary
No POST code ever reaches the BMC. The onboard two digit code display works,
so the codes are being written, but the BMC's POST code log stays empty for
every boot.
The FCH has two eSPI controllers, each with its own pins and its own decode
register. A device is wired to one of them. On this board the code display is
on eSPI 0 and the BMC is on eSPI 1, and firmware opens the port 0x80 window on
eSPI 0 only, so the cycles never reach the bus the BMC is on.
Setting the same bit on eSPI 1 at runtime is enough to make POST codes appear
in the BMC, with the code display still working, so the two windows are
independent and both can be open at once.
How reproducible
100%
How to reproduce
Boot the host and open the POST code page in the BMC web interface. It is
empty for the current boot, while the onboard code display shows codes
during boot as normal.
From the host, read the port 0x80 decode bit of both eSPI controllers.
Bit 2 is the port 0x80 window:
eSPI 0 reads
0x707, so bit 2 is set. eSPI 1 reads0x30F00, so bit 2 isclear.
Write a byte to port 0x80 from the host and reload the BMC's POST code
page. Nothing new appears:
Open the same window on eSPI 1. With both windows open the FCH alternates
between the two buses, so take port 0x80 off eSPI 0 for the moment to make
a single write deterministic, then repeat the write:
e7now shows up in the BMC's POST code log. The code display is unchangedwhile eSPI 0 has no window.
Put eSPI 0 back and write the same byte twice, one
ddper write so bothland on port 0x80. A doubled write always survives the alternation, so it
arrives with both windows open and the code display working:
The BMC web interface fetches the POST code log when the page is created and
does not poll, so the page has to be reloaded to see anything new.
Expected behavior
The BMC receives the POST codes that firmware writes to port 0x80, so its
POST code log is populated for every boot.
Actual behavior
The BMC's POST code log is empty for every boot. Nothing reaches it until bit
2 of the eSPI 1 decode register is set by hand from the host, which is lost on
the next power cycle.
Additional context
before the payload runs, so UEFI is affected the same way.
alternates strictly, one cycle to each. Writing port 0x80 a hundred times
from the host delivered fifty to the BMC, twice in a row, and a sequence of
the values 1 to 100 came back as its odd half with no even value anywhere.
value written twice always survives the split, while a value written once
goes to one consumer or the other.
arch_post_code()writes each code once, a singleoutbtoCONFIG_POST_IO_PORT, and this board defines nomainboard_post. So withboth windows open a boot log is halved, and the alternation is visible in
firmware codes too. The early order is
40in romstage,13and6efromc_start.S,39and6ffromhardwaremain.c, then70as the firstboot state, each with one call site. One boot logged
40 6e 6f, positionsone, three and five of those six, and another logged
13 39 70, positionstwo, four and six. One of them ends
9c 43 7b,BS_PAYLOAD_BOOT, and theother ends
76 79 7a fe f8, so which of the closing codes the BMC keepsvaries by boot.
Solutions you've tried
espi_open_io_window()programs the first controller and stops, which iswhy
espi_open_io_window(0x80, 1)reaches only the code display on thisboard. Writing bit 2 of
0xfec30040from the mainboard code as well isenough, and it does not disturb the eSPI 0 window.
port 0x80 decode bit, base
0x0080in0xfec30080with size 0 in0xfec30088, changes nothing. The alternation is about two controllersclaiming one address rather than about which decode matched it.
0xfec20040to0x703, gives the BMCevery write, a hundred out of a hundred, and leaves the code display unchanged.
That is a trade between the two consumers rather than a fix, so opening the
window on both controllers is the better default.