Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue fixes for MinnowBoard Turbot 0.9.0-rc2 #551

Open
wants to merge 23 commits into
base: byt_fsp_parity
Choose a base branch
from

Conversation

filipleple
Copy link
Member

No description provided.

miczyg1 and others added 16 commits August 14, 2024 15:12
Implement TXE BIOS flow as per Bay Trail TXE BWG
(Document Number: 514966, Revision 0.7).

Signed-off-by: Michał Żygowski <[email protected]>
If the CBFS end is not at address 0xFFFFFFFF, then SeabIOS will not
be able to find CBFS. This option allows to set the CBFS end in
situations where COREBOOT region does not end at address 0xFFFFFFFF.

Signed-off-by: Michał Żygowski <[email protected]>
With CBFS_VERIFICATION one cannot fetch the early microcode update
from CBFS, as walkcbfs_asm is unsafe to be compiled with
CBFS_VERIFICATION. As a workaround, put a microcode copy in the IBB
under a fixed address. Bootblock and microcode will be verified by
TXE when TXE_SECURE_BOOT is enabled, so it will be safe to use.

Also put the microcode and bootblock in the BOOTBLOCK region which
will cover whole IBB to cleanly separate code and data to be verfied
by TXE from the rest of CBFS. it will make the updates easier and
keep CBFS_VERIFICATION working properly.

Signed-off-by: Michał Żygowski <[email protected]>
The spd_add_smbios17 function already assumes MEMORY_BUS_WIDTH_64
non-ECC only, but did not fill in the ecc_type information, which
resulted in SMBIOS type 16 Memory Error Correction field to be out
of specitions (0 is not defined). Fill in the ecc_type field
as MEMORY_ARRAY_ECC_NONE.

Signed-off-by: Michał Żygowski <[email protected]>
Intel Bay Trail SoCs (confirmed on Atom E3845) have leading spaces
in the CPU brand string returned by CPUID. Strip these spaces so
that SMBIOS CPU string does not look weird in the EDK2 setup page
and the dmidecode output.

Signed-off-by: Michał Żygowski <[email protected]>
@filipleple filipleple self-assigned this Aug 20, 2024
@filipleple filipleple changed the base branch from byt_fsp_parity to dasharo August 20, 2024 10:09
@filipleple filipleple changed the base branch from dasharo to byt_fsp_parity August 20, 2024 10:09
@filipleple filipleple force-pushed the minnow-fixes branch 9 times, most recently from 992cc2d to 15a2467 Compare August 22, 2024 15:15
@filipleple filipleple changed the title implement mainboard_get_spi_config wip Implement BIOS lock and SMM BWP for BYT/MinnowBoard Aug 22, 2024
@filipleple filipleple force-pushed the minnow-fixes branch 5 times, most recently from 3f25d73 to fe4b7ff Compare August 28, 2024 10:13
@filipleple filipleple changed the title Implement BIOS lock and SMM BWP for BYT/MinnowBoard Issue fixes for MinnowBoard Turbot 0.9.0-rc2 Aug 28, 2024
Required for proper BIOS lock functionality, implements
mainboard_get_spi_config

Signed-off-by: Filip Lewiński <[email protected]>
@filipleple filipleple marked this pull request as ready for review August 29, 2024 14:41
@@ -0,0 +1,69 @@
#include <stdint.h>
Copy link
Contributor

@miczyg1 miczyg1 Sep 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not needed. All the logic is obsolete. Everything is implemented in spi_finalize_ops in southbridge/intel/common/spi.c. It should be called in finalize_chipset in southcluster.c

See how soc/intel/braswell does it.

The only thing is that SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT for some reason does not enable SMM BWP, but it is generally supported by the chipset.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miczyg1 thanks for pointing me in the right direction. So IIUC, the only thing the southbridge/intel/common/spi.c implementation is missing, which I have in my mostly redundant code, is setting the SMIWPEN bit - which enables the SPI controller to generate SMI upon not SMM code is trying to set WPD from a 1'b0 to a 1'b1 while LE is set. as per E3800 docs:

#define BIOS_CNTL		0xdc
#define  BIOS_CNTL_BIOSWE	(1 << 0)
#define  BIOS_CNTL_BLE		(1 << 1)
#define  BIOS_CNTL_SMM_BWP	(1 << 5)
+ #define  BIOS_CNTL_SMIWPEN	(1 << 7)

static void spi_set_smm_only_flashing(bool enable)
{
	if (!(CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)))
		return;

	const pci_devfn_t dev = PCI_DEV(0, 31, 0);

	uint8_t bios_cntl = pci_read_config8(dev, BIOS_CNTL);

	if (enable) {
		bios_cntl &= ~BIOS_CNTL_BIOSWE;
		bios_cntl |= BIOS_CNTL_BLE | BIOS_CNTL_SMM_BWP;
+ 		if(CONFIG(SOC_INTEL_BAYTRAIL)) bios_cntl |= BIOS_CNTL_SMIWPEN;

	} else {
		bios_cntl &= ~(BIOS_CNTL_BLE | BIOS_CNTL_SMM_BWP);
		bios_cntl |= BIOS_CNTL_BIOSWE;
+		if(CONFIG(SOC_INTEL_BAYTRAIL)) bios_cntl &= ~BIOS_CNTL_SMIWPEN;
	}

	pci_write_config8(dev, BIOS_CNTL, bios_cntl);
}

Copy link
Contributor

@miczyg1 miczyg1 Sep 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, so there are couple things to do:

  1. Set BIOS_CNTL_SMIWPEN, bu depend on SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT and remove the
if (!(CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)))
		return;
  1. Modify/add the SMI handler that will set the BIOS_CNTL_BIOSWE and clear the SMIWPST bit as well on any non-SMM attempt to write to flash (SMIWPST must be cleared in SMI, because otherwise we will end up in SMI loop).
  2. The Silvermont SPI has the BIOS_CNTL at spi_bar + 0xFC, not in the PCI space of Device 31 Function 0.
  3. The Silvermont SPI has the SMIWPEN and SMIWPST at bit 7 and 6, but of the SPI BAR + 0xf8 register.
  4. The Silvermont SPI also has the SMIWPEN and SMIWPST at bit 1 and 0 in the ILB BASE + 0x6C. They need to be set as well.

Although the datasheet does not mention which SMI status event is signaled when someone tries to clear the BIOS_CNTL_BIOSWE. On newer processors it is TCO SMI. Summing it up we have to check which SMI is triggered, see src/soc/intel/baytrail/smihandler.c the southbridge_smi array. One way to determine it is to enable SMM debugging on serial (log level must be SPEW and in Debugging options in menuconfig one has to select SMI debugging). Then add prints to all the handlers in the array to see which handler is invoked. If any unhandled SMI occurs, there will be SMI_STS[%d] occurred, but no handler available printed on serial, so you will know which one. When that is done, try with flashrom again to see if an SMI is triggered.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@miczyg1 so for this logic the board refuses to boot like so:

[DEBUG]  BS: BS_PAYLOAD_LOAD run times (exec / console): 1543 / 83 ms
[DEBUG]  apm_control: Finalizing SMM.
[WARN ]  EFIVARS: No Firmware Volume header present
[WARN ]  EFIVARS: Failed to validate firmware header


[NOTE ]  coreboot-intel_minnowmax_v0.9.0-rc2-5-g34593fd51ad9-dirty-0.9.0-rc2_ALT Mon Sep 09 12:22:16 UTC 2024 x86_32 smm starting (log level: 8)...

[SPEW ]  SMI# #2
[DEBUG]  SMI_STS: PM1 APM
[DEBUG]  SMI_STS[5] occurred, calling corresponding handler
[DEBUG]  SMI#: Finalizing SMM.
[DEBUG]  SMI_STS[8] occurred, calling corresponding handler
[SPEW ]  PM1_STS: TMROF
[DEBUG]  APMC done.
[DEBUG]  Applying perf/power settings.
[DEBUG]  BS: BS_PAYLOAD_LOAD exit times (exec / console): 57 / 12 ms
[DEBUG]  Jumping to boot code at 0x00800850(0x79d6c000)
[SPEW ]  CPU0: stack: 0x79dd5f40 - 0x79dd7f40, lowest used address 0x79dd7768, stack used: 2008 bytes
[WARN ]  EFIVARS: No Firmware Volume header present
[WARN ]  EFIVARS: Failed to validate firmware header


[NOTE ]  coreboot-intel_minnowmax_v0.9.0-rc2-5-g34593fd51ad9-dirty-0.9.0-rc2_ALT Mon Sep 09 12:22:16 UTC 2024 x86_32 smm starting (log level: 8)...

[SPEW ]  SMI# #1
[DEBUG]  SMI_STS: APM
[DEBUG]  SMI_STS[5] occurred, calling corresponding handler
[DEBUG]  Raw clear SMM store, param = 0x799ea000
[DEBUG]  FMAP: area SMMSTORE found @ 210000 (262144 bytes)
[DEBUG]  ICH SPI: Command transaction error
[WARN ]  SF: Failed to send write command (0 bytes): -1
[ERROR]  smm store: erasing block failed

I realize that's because EDK2 can't initialize any variables in flash while it's locked, but I'm not sure how I should get around it. If I comment out unsetting the WPD bit - disabling the lock but leaving the SMI triggering - the platform boots but flashrom doesn't cause any SMI (specifically using the -E command) :

bash-5.2# flashrom -p internal -c "W25Q64JV-.Q" -E
flashrom v1.2-1037-g5b4a5b4 on Linux 6.6.21-yocto-standard (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
coreboot table found at 0x79d6c000.
Found chipset "Intel Bay Trail".
Enabling flash write... Warning: Setting BIOS Control at 0x0 from 0x0b to 0x09 failed.
New value is 0x0b.
SPI Configuration is locked down.
FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
FREG1: BIOS region (0x00200000-0x007fffff) is read-write.
FREG2: Management Engine region (0x00001000-0x001fffff) is read-write.
OK.
Found Winbond flash chip "W25Q64JV-.Q" (8192 kB, SPI) mapped at physical address 0x00000000ff800000.
Erasing and writing flash chip... Erase/write done.
bash-5.2#

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If WPD is set constantly, then flashrom doesn't have to set it, so SMI is not triggered.

One must ensure that SMMSTROE handler is calling the unlock function before attempting to write to flash.

Comment on lines 1125 to 1127
# define EISS (0x1 << 5)
# define BCR_LE (0x1 << 1)
# define BCR_WPD (0x1 << 0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are redundant, you have the same definitions below for BIOS_CNTL

All you need to do is:

#define BIOS_CNTL		(CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT) ? 0xfc : 0xdc)

and reuse the same definitions.

Comment on lines 1114 to 1115
#define ILB_BASE_ADDRESS 0xfed08000
#define SPI_BASE_ADDRESS 0xfed01000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, no, no. This is bad. Read it from the PCI registers of LPC bridge, like the datasheet indicates. No hardcoding.

Besides, SPI_BASE_ADDRESS can be obtained with get_spi_bar. Similar thing must be done with ILB base

@filipleple
Copy link
Member Author

@miczyg1 I have:

  • added get_ilb_bar() for reading ILB_BAR from PCI config registers here
  • switched to using get_spi_bar() and get_ilb_bar() here
  • switched to using the BIOS_CNTL define here
  • added checking and toggling SMM BWP to the SMMSTORE handler here

This partially works - I can boot to setup menu, turn on SMM BWP, reboot into DTS and observe that:

bash-5.2# flashrom -p internal
flashrom v1.2-1037-g5b4a5b4 on Linux 6.6.21-yocto-standard (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
coreboot table found at 0x79d6c000.
Found chipset "Intel Bay Trail".
Enabling flash write... Warning: BIOS region SMM protection is enabled!    <-----
Warning: Setting BIOS Control at 0x0 from 0x2b to 0x09 failed.
New value is 0x2b.
SPI Configuration is locked down.
FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
FREG1: BIOS region (0x00200000-0x007fffff) is read-write.
FREG2: Management Engine region (0x00001000-0x001fffff) is read-write.
OK.

and trying to erase the chip fails.

However, when I reboot the platform, not changing any settings, the coreboot log repeats the same error:

[SPEW ]  Found variable with state 3f and GUID: 8be4df61-93ca-11d2-aa0d00e098032b8c
[SPEW ]  Found variable with state 3f and GUID: 8be4df61-93ca-11d2-aa0d00e098032b8c
[DEBUG]  ICH SPI: Data transaction error
[WARN ]  SF: Failed to send read command 0x0b(0x216fd8, 0x3c): -1

and flashrom output after booting to DTS changes to this:

bash-5.2# flashrom -p internal
flashrom v1.2-1037-g5b4a5b4 on Linux 6.6.21-yocto-standard (x86_64)
flashrom is free software, get the source code at https://flashrom.org

Using clock_gettime for delay loops (clk_id: 1, resolution: 1ns).
coreboot table found at 0x79d6c000.
Found chipset "Intel Bay Trail".
Enabling flash write... Warning: Setting BIOS Control at 0x0 from 0x0b to 0x09 failed.
New value is 0x0b.
SPI Configuration is locked down.
FREG0: Flash Descriptor region (0x00000000-0x00000fff) is read-write.
FREG1: BIOS region (0x00200000-0x007fffff) is read-write.
FREG2: Management Engine region (0x00001000-0x001fffff) is read-write.
PR0: Warning: 0x002d0000-0x007fffff is read-only.

Which looks like bios lock enabled and SMM BWP disabled, opposite of what's set in setup menu. I would really appreciate a suggestion on where to go with this.

BTW reworking the spi_set_smm_only_flashing function to make it more generic and have less overdub in the Silvermont #if.

@miczyg1 miczyg1 force-pushed the byt_fsp_parity branch 2 times, most recently from e31753a to ebd381f Compare September 24, 2024 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants