From 75380d3a162aa5864c8864923f621806b32e2f23 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 16 Apr 2019 18:26:26 +0200 Subject: [PATCH 001/588] src/mb/Kconfig: Fix PCI subsystem IDs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit References to MAINBOARD_PCI_SUBSYSTEM_{DEVICE_ID,VENDOR_ID} were removed in commits dbd3132 sb/intel/{i82801g/i/j,bd82x6x}: Make use of generic set_subsystem() 00bb441 sb/intel/lynxpoint: Remove PCI bridge function Change-Id: I72bba8406eea4a264e36cc9bcf467cf5cfbed379 Signed-off-by: Elyes HAOUAS Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/32107 Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/mainboard/aopen/dxplplusu/Kconfig | 8 -------- src/mainboard/apple/macbookair4_2/Kconfig | 8 -------- src/mainboard/asrock/b75pro3-m/Kconfig | 8 -------- src/mainboard/asrock/h81m-hds/Kconfig | 8 -------- src/mainboard/asus/h61m-cs/Kconfig | 8 -------- src/mainboard/asus/maximus_iv_gene-z/Kconfig | 8 -------- src/mainboard/asus/p8h61-m_lx/Kconfig | 8 -------- src/mainboard/asus/p8h61-m_pro/Kconfig | 8 -------- src/mainboard/compulab/intense_pc/Kconfig | 8 -------- src/mainboard/gigabyte/ga-h61m-s2pv/Kconfig | 8 -------- src/mainboard/google/butterfly/Kconfig | 8 -------- src/mainboard/google/parrot/Kconfig | 8 -------- src/mainboard/google/stout/Kconfig | 8 -------- src/mainboard/hp/2570p/Kconfig | 8 -------- src/mainboard/hp/2760p/Kconfig | 8 -------- src/mainboard/hp/8460p/Kconfig | 8 -------- src/mainboard/hp/8470p/Kconfig | 8 -------- src/mainboard/hp/8770w/Kconfig | 8 -------- src/mainboard/hp/compaq_8200_elite_sff/Kconfig | 8 -------- src/mainboard/hp/folio_9470m/Kconfig | 8 -------- src/mainboard/hp/revolve_810_g1/Kconfig | 8 -------- src/mainboard/intel/dcp847ske/Kconfig | 8 -------- src/mainboard/kontron/ktqm77/Kconfig | 8 -------- src/mainboard/lenovo/l520/Kconfig | 8 -------- src/mainboard/lenovo/s230u/Kconfig | 8 -------- src/mainboard/lenovo/t420/Kconfig | 8 -------- src/mainboard/lenovo/t420s/Kconfig | 8 -------- src/mainboard/lenovo/t430/Kconfig | 8 -------- src/mainboard/lenovo/t430s/Kconfig | 9 --------- src/mainboard/lenovo/t520/Kconfig | 8 -------- src/mainboard/lenovo/t530/Kconfig | 8 -------- src/mainboard/lenovo/x131e/Kconfig | 8 -------- src/mainboard/lenovo/x1_carbon_gen1/Kconfig | 8 -------- src/mainboard/lenovo/x220/Kconfig | 9 --------- src/mainboard/lenovo/x230/Kconfig | 8 -------- src/mainboard/sapphire/pureplatinumh61/Kconfig | 8 -------- src/mainboard/supermicro/x10slm-f/Kconfig | 8 -------- util/autoport/bd82x6x.go | 6 ------ 38 files changed, 304 deletions(-) diff --git a/src/mainboard/aopen/dxplplusu/Kconfig b/src/mainboard/aopen/dxplplusu/Kconfig index 3a729ce17a7..905ddd58007 100644 --- a/src/mainboard/aopen/dxplplusu/Kconfig +++ b/src/mainboard/aopen/dxplplusu/Kconfig @@ -33,12 +33,4 @@ config C_ENV_BOOTBLOCK_SIZE hex default 0x4000 -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x0 - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x0 - endif # BOARD_AOPEN_DXPLPLUSU diff --git a/src/mainboard/apple/macbookair4_2/Kconfig b/src/mainboard/apple/macbookair4_2/Kconfig index 9d4047dc9ba..82f120ab08e 100644 --- a/src/mainboard/apple/macbookair4_2/Kconfig +++ b/src/mainboard/apple/macbookair4_2/Kconfig @@ -31,14 +31,6 @@ config VGA_BIOS_ID string default "8086,0116" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x7270 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x8086 - config DRAM_RESET_GATE_GPIO int default 60 diff --git a/src/mainboard/asrock/b75pro3-m/Kconfig b/src/mainboard/asrock/b75pro3-m/Kconfig index 5fc3c5e4baf..8db0eba7634 100644 --- a/src/mainboard/asrock/b75pro3-m/Kconfig +++ b/src/mainboard/asrock/b75pro3-m/Kconfig @@ -37,14 +37,6 @@ config MAINBOARD_PART_NUMBER string default "B75 Pro3-M" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x1e49 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1849 - config MAX_CPUS int default 8 diff --git a/src/mainboard/asrock/h81m-hds/Kconfig b/src/mainboard/asrock/h81m-hds/Kconfig index 55f163769f5..db2768d324b 100644 --- a/src/mainboard/asrock/h81m-hds/Kconfig +++ b/src/mainboard/asrock/h81m-hds/Kconfig @@ -56,14 +56,6 @@ config MAINBOARD_PART_NUMBER string default "H81M-HDS" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x8c5c - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1849 - config MAX_CPUS int default 8 diff --git a/src/mainboard/asus/h61m-cs/Kconfig b/src/mainboard/asus/h61m-cs/Kconfig index d21c76191b1..60dafda5c76 100644 --- a/src/mainboard/asus/h61m-cs/Kconfig +++ b/src/mainboard/asus/h61m-cs/Kconfig @@ -25,14 +25,6 @@ config MAINBOARD_PART_NUMBER string default "H61M-CS" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x844d - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1043 - config MAX_CPUS int default 8 diff --git a/src/mainboard/asus/maximus_iv_gene-z/Kconfig b/src/mainboard/asus/maximus_iv_gene-z/Kconfig index 92d7840031b..a0bc31864eb 100644 --- a/src/mainboard/asus/maximus_iv_gene-z/Kconfig +++ b/src/mainboard/asus/maximus_iv_gene-z/Kconfig @@ -46,14 +46,6 @@ config VGA_BIOS_ID string default "8086,0112" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x844d - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1043 - config MAX_CPUS int default 8 diff --git a/src/mainboard/asus/p8h61-m_lx/Kconfig b/src/mainboard/asus/p8h61-m_lx/Kconfig index cc2f8a9979d..010641ac66d 100644 --- a/src/mainboard/asus/p8h61-m_lx/Kconfig +++ b/src/mainboard/asus/p8h61-m_lx/Kconfig @@ -43,14 +43,6 @@ config MAINBOARD_PART_NUMBER string default "P8H61-M LX" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x844d - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1043 - config MAX_CPUS int default 8 diff --git a/src/mainboard/asus/p8h61-m_pro/Kconfig b/src/mainboard/asus/p8h61-m_pro/Kconfig index 082d3e4028a..93da2cdf58e 100644 --- a/src/mainboard/asus/p8h61-m_pro/Kconfig +++ b/src/mainboard/asus/p8h61-m_pro/Kconfig @@ -48,14 +48,6 @@ config VGA_BIOS_ID string default "8086,0152" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x844d - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1043 - config MAX_CPUS int default 8 diff --git a/src/mainboard/compulab/intense_pc/Kconfig b/src/mainboard/compulab/intense_pc/Kconfig index 0bfde495fff..ff697b922f0 100644 --- a/src/mainboard/compulab/intense_pc/Kconfig +++ b/src/mainboard/compulab/intense_pc/Kconfig @@ -28,14 +28,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x7270 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x8086 - config DRAM_RESET_GATE_GPIO # FIXME: check this int default 60 diff --git a/src/mainboard/gigabyte/ga-h61m-s2pv/Kconfig b/src/mainboard/gigabyte/ga-h61m-s2pv/Kconfig index 5fba47a90fe..5e46365bba5 100644 --- a/src/mainboard/gigabyte/ga-h61m-s2pv/Kconfig +++ b/src/mainboard/gigabyte/ga-h61m-s2pv/Kconfig @@ -40,14 +40,6 @@ config MAINBOARD_PART_NUMBER string default "GA-H61M-S2PV" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x5001 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1458 - config MAX_CPUS int default 8 diff --git a/src/mainboard/google/butterfly/Kconfig b/src/mainboard/google/butterfly/Kconfig index 570a1b3573f..24797be46c7 100644 --- a/src/mainboard/google/butterfly/Kconfig +++ b/src/mainboard/google/butterfly/Kconfig @@ -40,14 +40,6 @@ config VGA_BIOS_FILE string default "pci8086,0106.rom" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1ae0 - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0xc000 - config MAINBOARD_VENDOR string default "Hewlett-Packard" diff --git a/src/mainboard/google/parrot/Kconfig b/src/mainboard/google/parrot/Kconfig index f2c9b20a1cf..1a31da7b55e 100644 --- a/src/mainboard/google/parrot/Kconfig +++ b/src/mainboard/google/parrot/Kconfig @@ -41,12 +41,4 @@ config VGA_BIOS_FILE string default "pci8086,0106.rom" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1ae0 - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0xc000 - endif # BOARD_GOOGLE_PARROT diff --git a/src/mainboard/google/stout/Kconfig b/src/mainboard/google/stout/Kconfig index c9b67ccee16..8b3eb0f0301 100644 --- a/src/mainboard/google/stout/Kconfig +++ b/src/mainboard/google/stout/Kconfig @@ -43,12 +43,4 @@ config VGA_BIOS_ID string default "8086,0156" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1ae0 - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0xc000 - endif # BOARD_GOOGLE_STOUT diff --git a/src/mainboard/hp/2570p/Kconfig b/src/mainboard/hp/2570p/Kconfig index f9da619ad28..ff91e4dafe2 100644 --- a/src/mainboard/hp/2570p/Kconfig +++ b/src/mainboard/hp/2570p/Kconfig @@ -49,14 +49,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x17df - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/2760p/Kconfig b/src/mainboard/hp/2760p/Kconfig index af3e31b8bc4..ab298369e17 100644 --- a/src/mainboard/hp/2760p/Kconfig +++ b/src/mainboard/hp/2760p/Kconfig @@ -49,14 +49,6 @@ config VGA_BIOS_ID string default "8086,0116" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x162a - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/8460p/Kconfig b/src/mainboard/hp/8460p/Kconfig index ca737ea65b0..ca97cd69f68 100644 --- a/src/mainboard/hp/8460p/Kconfig +++ b/src/mainboard/hp/8460p/Kconfig @@ -52,14 +52,6 @@ config VGA_BIOS_ID string default "8086,0116" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x161c - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/8470p/Kconfig b/src/mainboard/hp/8470p/Kconfig index d8bf5ec2b5c..f23c02faf37 100644 --- a/src/mainboard/hp/8470p/Kconfig +++ b/src/mainboard/hp/8470p/Kconfig @@ -50,14 +50,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x179b - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/8770w/Kconfig b/src/mainboard/hp/8770w/Kconfig index c60283d009d..6752085574c 100644 --- a/src/mainboard/hp/8770w/Kconfig +++ b/src/mainboard/hp/8770w/Kconfig @@ -41,14 +41,6 @@ config MAINBOARD_PART_NUMBER string default "EliteBook 8770w" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x176c - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/compaq_8200_elite_sff/Kconfig b/src/mainboard/hp/compaq_8200_elite_sff/Kconfig index c4b9d6db6b4..cbfb0ed387e 100644 --- a/src/mainboard/hp/compaq_8200_elite_sff/Kconfig +++ b/src/mainboard/hp/compaq_8200_elite_sff/Kconfig @@ -35,14 +35,6 @@ config VGA_BIOS_ID string default "8086,0102" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x1495 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config DRAM_RESET_GATE_GPIO int default 60 diff --git a/src/mainboard/hp/folio_9470m/Kconfig b/src/mainboard/hp/folio_9470m/Kconfig index f65aeed93d6..06ca7935736 100644 --- a/src/mainboard/hp/folio_9470m/Kconfig +++ b/src/mainboard/hp/folio_9470m/Kconfig @@ -35,14 +35,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x18df - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config MAX_CPUS int default 8 diff --git a/src/mainboard/hp/revolve_810_g1/Kconfig b/src/mainboard/hp/revolve_810_g1/Kconfig index a08a9e5b893..475e9783eb5 100644 --- a/src/mainboard/hp/revolve_810_g1/Kconfig +++ b/src/mainboard/hp/revolve_810_g1/Kconfig @@ -37,14 +37,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x18f8 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x103c - config DRAM_RESET_GATE_GPIO # FIXME: check this int default 60 diff --git a/src/mainboard/intel/dcp847ske/Kconfig b/src/mainboard/intel/dcp847ske/Kconfig index dd7f1ca497b..b1c7bab07d8 100644 --- a/src/mainboard/intel/dcp847ske/Kconfig +++ b/src/mainboard/intel/dcp847ske/Kconfig @@ -41,14 +41,6 @@ config VGA_BIOS_ID string default "8086,0106" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x2044 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x8086 - config MAX_CPUS int default 2 diff --git a/src/mainboard/kontron/ktqm77/Kconfig b/src/mainboard/kontron/ktqm77/Kconfig index b85d9381caa..043eb019ddc 100644 --- a/src/mainboard/kontron/ktqm77/Kconfig +++ b/src/mainboard/kontron/ktqm77/Kconfig @@ -31,14 +31,6 @@ config VGA_BIOS_FILE string default "pci8086,0166.rom" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x0000 # TODO - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x0000 # TODO - config MAINBOARD_VENDOR string default "Kontron" diff --git a/src/mainboard/lenovo/l520/Kconfig b/src/mainboard/lenovo/l520/Kconfig index a807316bbf6..4495d79bb26 100644 --- a/src/mainboard/lenovo/l520/Kconfig +++ b/src/mainboard/lenovo/l520/Kconfig @@ -34,14 +34,6 @@ config VGA_BIOS_ID string default "8086,0126" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21dd - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - config DRAM_RESET_GATE_GPIO int default 10 diff --git a/src/mainboard/lenovo/s230u/Kconfig b/src/mainboard/lenovo/s230u/Kconfig index 714f13f3420..9200ad5ed91 100644 --- a/src/mainboard/lenovo/s230u/Kconfig +++ b/src/mainboard/lenovo/s230u/Kconfig @@ -52,12 +52,4 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x2205 - endif # BOARD_LENOVO_S230U diff --git a/src/mainboard/lenovo/t420/Kconfig b/src/mainboard/lenovo/t420/Kconfig index f40e9c0c923..ce81907ccbc 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -56,14 +56,6 @@ config VGA_BIOS_ID string default "8086,0126" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21ce - config ONBOARD_VGA_IS_PRIMARY bool default y diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index 71b94afa520..c5efb556537 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -55,14 +55,6 @@ config VGA_BIOS_ID string default "8086,0126" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21d2 - config ONBOARD_VGA_IS_PRIMARY bool default y diff --git a/src/mainboard/lenovo/t430/Kconfig b/src/mainboard/lenovo/t430/Kconfig index 687edea021a..dbeaadb0c47 100644 --- a/src/mainboard/lenovo/t430/Kconfig +++ b/src/mainboard/lenovo/t430/Kconfig @@ -38,14 +38,6 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21f3 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - config DRAM_RESET_GATE_GPIO int default 10 diff --git a/src/mainboard/lenovo/t430s/Kconfig b/src/mainboard/lenovo/t430s/Kconfig index 47ff441d833..bad1837546c 100644 --- a/src/mainboard/lenovo/t430s/Kconfig +++ b/src/mainboard/lenovo/t430s/Kconfig @@ -60,15 +60,6 @@ config VGA_BIOS_FILE string default "pci8086,0166.rom" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21fb if BOARD_LENOVO_T430S - default 0x2208 if BOARD_LENOVO_T431S - config ONBOARD_VGA_IS_PRIMARY bool default y diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index c4140836dad..06f296bc6df 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -65,14 +65,6 @@ config VGA_BIOS_FILE string default "pci8086,0126.rom" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21cf - config ONBOARD_VGA_IS_PRIMARY bool default y diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index 14f9fb2478c..b36460d55fd 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -62,14 +62,6 @@ config VGA_BIOS_FILE default "pci8086,0106.rom" if BOARD_LENOVO_T530 default "pci8086,0166.rom" if BOARD_LENOVO_W530 -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21fa - config ONBOARD_VGA_IS_PRIMARY bool default y diff --git a/src/mainboard/lenovo/x131e/Kconfig b/src/mainboard/lenovo/x131e/Kconfig index 2f936a915dd..e7da8d0d770 100644 --- a/src/mainboard/lenovo/x131e/Kconfig +++ b/src/mainboard/lenovo/x131e/Kconfig @@ -37,12 +37,4 @@ config USBDEBUG_HCD_INDEX int default 2 -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21fe - endif # BOARD_LENOVO_X131E diff --git a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig index 202fabd5fd5..520853c800c 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig +++ b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig @@ -54,12 +54,4 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21fa - endif # BOARD_LENOVO_X1_CARBON_GEN1 diff --git a/src/mainboard/lenovo/x220/Kconfig b/src/mainboard/lenovo/x220/Kconfig index 70245d20bce..16f42e850ec 100644 --- a/src/mainboard/lenovo/x220/Kconfig +++ b/src/mainboard/lenovo/x220/Kconfig @@ -69,13 +69,4 @@ config VGA_BIOS_ID default "8086,0116" if BOARD_LENOVO_X220I default "8086,0126" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21db if BOARD_LENOVO_X220 || BOARD_LENOVO_X220I - default 0x21e8 if BOARD_LENOVO_X1 - endif # BOARD_LENOVO_X220 || BOARD_LENOVO_X220I || BOARD_LENOVO_X1 diff --git a/src/mainboard/lenovo/x230/Kconfig b/src/mainboard/lenovo/x230/Kconfig index 3ec537a2428..5b34b83bcd5 100644 --- a/src/mainboard/lenovo/x230/Kconfig +++ b/src/mainboard/lenovo/x230/Kconfig @@ -55,12 +55,4 @@ config VGA_BIOS_ID string default "8086,0166" -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x17aa - -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x21fa - endif # BOARD_LENOVO_X230 diff --git a/src/mainboard/sapphire/pureplatinumh61/Kconfig b/src/mainboard/sapphire/pureplatinumh61/Kconfig index 85b2f36cda2..13a93c5c27c 100644 --- a/src/mainboard/sapphire/pureplatinumh61/Kconfig +++ b/src/mainboard/sapphire/pureplatinumh61/Kconfig @@ -32,14 +32,6 @@ config VGA_BIOS_ID string default "8086,0162" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x1007 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x174b - config DRAM_RESET_GATE_GPIO int default 60 diff --git a/src/mainboard/supermicro/x10slm-f/Kconfig b/src/mainboard/supermicro/x10slm-f/Kconfig index 6bf0b2a1990..430bed379ab 100644 --- a/src/mainboard/supermicro/x10slm-f/Kconfig +++ b/src/mainboard/supermicro/x10slm-f/Kconfig @@ -44,14 +44,6 @@ config MAINBOARD_PART_NUMBER string default "X10SLM+-F" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x0803 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x15d9 - config MAX_CPUS int default 8 diff --git a/util/autoport/bd82x6x.go b/util/autoport/bd82x6x.go index 265cb6f4b37..a97ff1d9613 100644 --- a/util/autoport/bd82x6x.go +++ b/util/autoport/bd82x6x.go @@ -181,12 +181,6 @@ func (b bd82x6x) Scan(ctx Context, addr PCIDevData) { } KconfigComment["DRAM_RESET_GATE_GPIO"] = "FIXME: check this" - /* Not strictly speaking correct. These subsys/subvendor referer to PCI devices. - But most systems don't have any of those. But the config needs to be set - nevertheless. So set it to southbridge subsys/subvendor. */ - KconfigHex["MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID"] = uint32(GetLE16(addr.ConfigDump[0x2c:0x2e])) - KconfigHex["MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID"] = uint32(GetLE16(addr.ConfigDump[0x2e:0x30])) - ich9GetFlashSize(ctx) DSDTDefines = append(DSDTDefines, From 5397f194ccfd160803467d3d8643aab52871f876 Mon Sep 17 00:00:00 2001 From: Nathan_chen Date: Wed, 17 Apr 2019 10:32:13 +0800 Subject: [PATCH 002/588] mb/google/arcada: Set psys_pmax to 140W arcada is designed to operate at max power of 140 Watt. Hence set psys_max to 140W. BUG=b:124792558 TEST=Build and boot arcada. Change-Id: I280dfb81b3e25c7619a68db487e2b18867f52fda Signed-off-by: nathan chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32335 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 9ecbf001520..2056dd62801 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -28,6 +28,7 @@ chip soc/intel/cannonlake register "PchPmSlpAMinAssert" = "4" # 2s register "speed_shift_enable" = "1" + register "psys_pmax" = "140" register "s0ix_enable" = "1" register "dptf_enable" = "1" register "dmipwroptimize" = "1" From 6cd9e631b018049c08484708e0afc8cc00089df5 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Wed, 17 Apr 2019 21:13:15 +0800 Subject: [PATCH 003/588] mb/google/octopus/variants/baseboard: Disable unused I2C 1 I2C 1 is not being used in any of the octopus variants, so disable it. BUG=none BRANCH=octopus TEST=Verify on meep and bloog reboot and s0ix suspend successfully Change-Id: I7ed5065cfd0b9780d13feb27cc78b8090d7a03a6 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/32349 Tested-by: build bot (Jenkins) Reviewed-by: Karthik Ramasubramanian Reviewed-by: Justin TerAvest --- src/mainboard/google/octopus/variants/baseboard/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb index e134aa222d6..fc609cd125a 100644 --- a/src/mainboard/google/octopus/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/octopus/variants/baseboard/devicetree.cb @@ -165,7 +165,7 @@ chip soc/intel/apollolake end # - XHCI device pci 15.1 on end # - XDCI device pci 16.0 on end # - I2C 0 - device pci 16.1 on end # - I2C 1 + device pci 16.1 off end # - I2C 1 device pci 16.2 off end # - I2C 2 device pci 16.3 off end # - I2C 3 device pci 17.0 on end # - I2C 4 From 4c15ea5bab3a92c441b27bd64e594eeba981ad48 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 13 Apr 2019 09:31:03 +0200 Subject: [PATCH 004/588] mb/facebook/watson: Don't use deprecated IS_ENABLED Change-Id: Ia4b7311f30f8ec951d02d3c31c30cf8895ed0eb2 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32312 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/facebook/watson/mainboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/facebook/watson/mainboard.c b/src/mainboard/facebook/watson/mainboard.c index 3a1692fa1d6..403090a06fc 100644 --- a/src/mainboard/facebook/watson/mainboard.c +++ b/src/mainboard/facebook/watson/mainboard.c @@ -29,7 +29,7 @@ static void mainboard_enable(struct device *dev) static void mainboard_init(void *chip_info) { -#if !IS_ENABLED(CONFIG_ENABLE_TURBO) +#if !CONFIG(ENABLE_TURBO) disable_turbo(); #endif } From b3282093308d62c4fc3e6bf4e4183d2bd01bb09f Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 14 Apr 2019 17:53:28 +0200 Subject: [PATCH 005/588] nb/intel/nehalem: Hide some raminit output messages Hide some debug output behind CONFIG_DEBUG_RAM_SETUP. That way the pre-ram console does not overflow. Change-Id: Idc425f4d10443f6ee7f9b4da67eb6542069cc40c Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32318 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/nehalem/Kconfig | 1 + src/northbridge/intel/nehalem/raminit.c | 34 +++++++++++++------------ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/northbridge/intel/nehalem/Kconfig b/src/northbridge/intel/nehalem/Kconfig index 9eb6e75eacf..1e504593ca6 100644 --- a/src/northbridge/intel/nehalem/Kconfig +++ b/src/northbridge/intel/nehalem/Kconfig @@ -23,6 +23,7 @@ config NORTHBRIDGE_INTEL_NEHALEM select CACHE_MRC_SETTINGS select POSTCAR_STAGE select POSTCAR_CONSOLE + select HAVE_DEBUG_RAM_SETUP if NORTHBRIDGE_INTEL_NEHALEM diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 78bc6de70a5..3164a58fbf2 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -1568,14 +1568,14 @@ static void write_training_data(struct raminfo *info) static void dump_timings(struct raminfo *info) { int channel, slot, rank, lane, i; - printk(BIOS_DEBUG, "Timings:\n"); + printk(RAM_DEBUG, "Timings:\n"); FOR_POPULATED_RANKS { - printk(BIOS_DEBUG, "channel %d, slot %d, rank %d\n", channel, + printk(RAM_DEBUG, "channel %d, slot %d, rank %d\n", channel, slot, rank); for (lane = 0; lane < 9; lane++) { - printk(BIOS_DEBUG, "lane %d: ", lane); + printk(RAM_DEBUG, "lane %d: ", lane); for (i = 0; i < 4; i++) { - printk(BIOS_DEBUG, "%x (%x) ", + printk(RAM_DEBUG, "%x (%x) ", read_500(info, channel, get_timing_register_addr (lane, i, slot, rank), @@ -1584,12 +1584,12 @@ static void dump_timings(struct raminfo *info) lane_timings[i][channel][slot][rank] [lane]); } - printk(BIOS_DEBUG, "\n"); + printk(RAM_DEBUG, "\n"); } } - printk(BIOS_DEBUG, "[178] = %x (%x)\n", read_1d0(0x178, 7), + printk(RAM_DEBUG, "[178] = %x (%x)\n", read_1d0(0x178, 7), info->training.reg_178); - printk(BIOS_DEBUG, "[10b] = %x (%x)\n", read_1d0(0x10b, 6), + printk(RAM_DEBUG, "[10b] = %x (%x)\n", read_1d0(0x10b, 6), info->training.reg_10b); } @@ -1623,8 +1623,8 @@ static void save_timings(struct raminfo *info) train.reg_6dc = MCHBAR32(0x6dc); train.reg_6e8 = MCHBAR32(0x6e8); - printk (BIOS_SPEW, "[6dc] = %x\n", train.reg_6dc); - printk (BIOS_SPEW, "[6e8] = %x\n", train.reg_6e8); + printk(RAM_SPEW, "[6dc] = %x\n", train.reg_6dc); + printk(RAM_SPEW, "[6e8] = %x\n", train.reg_6e8); /* Save the MRC S3 restore data to cbmem */ mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, @@ -3403,7 +3403,7 @@ set_6d_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2, 0, 1, &ratios2); compute_frequence_ratios(info, freq1, freq2, num_cycles_3, num_cycles_4, 0, 1, &ratios1); - printk (BIOS_SPEW, "[%x] <= %x\n", reg, + printk(RAM_SPEW, "[%x] <= %x\n", reg, ratios1.freq4_to_max_remainder | (ratios2. freq4_to_max_remainder << 8) @@ -3486,7 +3486,8 @@ static void set_2dxx_series(struct raminfo *info, int s3resume) frequency_11(info) / 2, 4000, 4000, 0, 0); if (s3resume) { - printk (BIOS_SPEW, "[6dc] <= %x\n", info->cached_training->reg_6dc); + printk(RAM_SPEW, "[6dc] <= %x\n", + info->cached_training->reg_6dc); MCHBAR32(0x6dc) = info->cached_training->reg_6dc; } else set_6d_reg(info, 0x6dc, 2 * info->fsb_frequency, frequency_11(info), 0, @@ -3497,7 +3498,8 @@ static void set_2dxx_series(struct raminfo *info, int s3resume) set_2dx8_reg(info, 0x6e4, 1, 2 * info->fsb_frequency, frequency_11(info) / 2, 3500, 0, 0, 0); if (s3resume) { - printk (BIOS_SPEW, "[6e8] <= %x\n", info->cached_training->reg_6e8); + printk(RAM_SPEW, "[6e8] <= %x\n", + info->cached_training->reg_6e8); MCHBAR32(0x6e8) = info->cached_training->reg_6e8; } else set_6d_reg(info, 0x6e8, 2 * info->fsb_frequency, frequency_11(info), 0, @@ -4026,19 +4028,19 @@ void raminit(const int s3resume, const u8 *spd_addrmap) int j; if (s3resume && info.cached_training) { restore_274265(&info); - printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n", + printk(RAM_DEBUG, "reg2ca9_bit0 = %x\n", info.cached_training->reg2ca9_bit0); for (i = 0; i < 2; i++) for (j = 0; j < 3; j++) - printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n", + printk(RAM_DEBUG, "reg274265[%d][%d] = %x\n", i, j, info.cached_training->reg274265[i][j]); } else { set_274265(&info); - printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n", + printk(RAM_DEBUG, "reg2ca9_bit0 = %x\n", info.training.reg2ca9_bit0); for (i = 0; i < 2; i++) for (j = 0; j < 3; j++) - printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n", + printk(RAM_DEBUG, "reg274265[%d][%d] = %x\n", i, j, info.training.reg274265[i][j]); } From 6d3b7e6f627989ed96de3576a6b19878eb2220a5 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Thu, 18 Apr 2019 17:01:01 -0600 Subject: [PATCH 006/588] soc/amd/stoneyridge: Fix gnvs aoac initialization Correct the SD and SATA assignments. TEST=Boot Grunt BUG=b:130788333 Change-Id: Ib75e1dbb0cd7f90a8d297d11d3a7c3bad47a8d21 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32355 Tested-by: build bot (Jenkins) Reviewed-by: Raul Rangel --- src/soc/amd/stoneyridge/southbridge.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 2f32c5c86eb..9c546947e34 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -927,9 +927,9 @@ static void set_sb_final_nvs(void) gnvs->aoac.xhce = is_aoac_device_enabled(FCH_AOAC_D3_STATE_USB3); /* Rely on these being in sync with devicetree */ sd = pcidev_path_on_root(SD_DEVFN); - gnvs->aoac.st_e = sd && sd->enabled ? 1 : 0; + gnvs->aoac.sd_e = sd && sd->enabled ? 1 : 0; sata = pcidev_path_on_root(SATA_DEVFN); - gnvs->aoac.sd_e = sata && sata->enabled ? 1 : 0; + gnvs->aoac.st_e = sata && sata->enabled ? 1 : 0; gnvs->aoac.espi = 1; amdfw_rom = 0x20000 - (0x80000 << CONFIG_AMD_FWM_POSITION_INDEX); From 0800194f95933d6337ba2e7900a1f02671aed3ba Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Wed, 17 Apr 2019 09:28:30 -0600 Subject: [PATCH 007/588] ipxe: Update stable version from 2017.3 to to 2019.3 Updating iPXE stable from commit id fd6d1f4660: Fri Mar 31 09:08:13 2017 +0300 [thunderx] Use ThunderxConfigProtocol to obtain board configuration to commit id ebf2eaf515: Mar 18 10:24:08 2019 +0000 [intel] Add PCI ID for I219-V and -LM 6 to 9 This brings in 176 new commits Change-Id: Id35fee38e0e61897a623dae35f42fc580e32d3ee Signed-off-by: Martin Roth Reviewed-on: https://review.coreboot.org/c/coreboot/+/32345 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Philipp Deppenwiese --- payloads/external/iPXE/Kconfig | 4 ++-- payloads/external/iPXE/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/payloads/external/iPXE/Kconfig b/payloads/external/iPXE/Kconfig index ce0a7aea14e..f99182c908b 100644 --- a/payloads/external/iPXE/Kconfig +++ b/payloads/external/iPXE/Kconfig @@ -42,12 +42,12 @@ choice depends on BUILD_IPXE config IPXE_STABLE - bool "2017.3" + bool "2019.3" help iPXE uses a rolling release with no stable version, for reproducibility, use the last commit of a given month as the 'stable' version. - This is iPXE from the end of March, 2017. + This is iPXE from the end of March, 2019. config IPXE_MASTER bool "master" diff --git a/payloads/external/iPXE/Makefile b/payloads/external/iPXE/Makefile index a8b1245ca5f..3a0585fc787 100644 --- a/payloads/external/iPXE/Makefile +++ b/payloads/external/iPXE/Makefile @@ -13,9 +13,9 @@ ## GNU General Public License for more details. ## -# 2017.3 - Last commit of March 2017 +# 2019.3 - Last commit of March 2019 # When updating, change the name both here and in payloads/external/iPXE/Kconfig -STABLE_COMMIT_ID=fd6d1f4660a37d75acba1c64e2e5f137307bbc31 +STABLE_COMMIT_ID=ebf2eaf515e46abd43bc798e7e4ba77bfe529218 TAG-$(CONFIG_IPXE_MASTER)=origin/master TAG-$(CONFIG_IPXE_STABLE)=$(STABLE_COMMIT_ID) From c4772b9fd7fcc29d09d7617dc8cff922118814d7 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 14 Apr 2019 18:38:35 +0200 Subject: [PATCH 008/588] cpu/x86: Move checking for MTRR's as a proxy for proper CPU reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Checking for empty MTRR_DEF_TYPE_MSR as a proxy for proper CPU reset is common across multiple platforms. Therefore place it in a common location. Change-Id: I81d82fb9fe27cd9de6085251fe1a5685cdd651fc Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32319 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Kyösti Mälkki Reviewed-by: Furquan Shaikh --- src/cpu/x86/early_reset.S | 45 +++++++++++++++++++ src/soc/intel/common/block/cpu/Makefile.inc | 1 + .../intel/common/block/cpu/car/cache_as_ram.S | 17 +------ 3 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 src/cpu/x86/early_reset.S diff --git a/src/cpu/x86/early_reset.S b/src/cpu/x86/early_reset.S new file mode 100644 index 00000000000..ec015abe22e --- /dev/null +++ b/src/cpu/x86/early_reset.S @@ -0,0 +1,45 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * input %esp: return address (not pointer to return address!) + * clobber the content of eax, ecx, edx + */ + +#include + +.section .text +.global check_mtrr + +check_mtrr: + /* Use the MTRR default type MSR as a proxy for detecting INIT#. + * Reset the system if any known bits are set in that MSR. That is + * an indication of the CPU not being properly reset. */ + +check_for_clean_reset: + movl $MTRR_DEF_TYPE_MSR, %ecx + rdmsr + andl $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax + cmp $0, %eax + jnz warm_reset + jmp *%esp + /* perform warm reset */ +warm_reset: + movw $0xcf9, %dx + movb $0x06, %al + outb %al, %dx + /* Should not reach this*/ +.Lhlt: + hlt + jmp .Lhlt diff --git a/src/soc/intel/common/block/cpu/Makefile.inc b/src/soc/intel/common/block/cpu/Makefile.inc index 5207227b491..a6c4f37cc43 100644 --- a/src/soc/intel/common/block/cpu/Makefile.inc +++ b/src/soc/intel/common/block/cpu/Makefile.inc @@ -1,4 +1,5 @@ bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += car/cache_as_ram.S +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CAR) += ../../../../../cpu/x86/early_reset.S bootblock-$(CONFIG_FSP_CAR)+= car/cache_as_ram_fsp.S bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += cpulib.c diff --git a/src/soc/intel/common/block/cpu/car/cache_as_ram.S b/src/soc/intel/common/block/cpu/car/cache_as_ram.S index d3ee671bef2..b1648e8eedd 100644 --- a/src/soc/intel/common/block/cpu/car/cache_as_ram.S +++ b/src/soc/intel/common/block/cpu/car/cache_as_ram.S @@ -28,21 +28,8 @@ bootblock_pre_c_entry: post_code(0x20) - /* - * Use the MTRR default type MSR as a proxy for detecting INIT#. - * Reset the system if any known bits are set in that MSR. That is - * an indication of the CPU not being properly reset. - */ -check_for_clean_reset: - mov $MTRR_DEF_TYPE_MSR, %ecx - rdmsr - and $(MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN), %eax - cmp $0, %eax - jz no_reset - /* perform warm reset */ - movw $0xcf9, %dx - movb $0x06, %al - outb %al, %dx + movl $no_reset, %esp /* return address */ + jmp check_mtrr /* Check if CPU properly reset */ no_reset: post_code(0x21) From 8e646e74b3d5e1d4a5e8114f03046f3d7b6ad042 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 5 Jun 2018 11:19:22 +0200 Subject: [PATCH 009/588] cpu/intel/haswell: Use C_ENVIRONMENT_BOOTBLOCK This puts the cache-as-ram init in the bootblock. Before setting up cache as ram the microcode updates are applied. This removes the possibility for a normal/fallback setup although implementing this should be quite easy. Tested on Google peppy (Acer C720). Setting up LPC in the bootblock to output console on SuperIOs is not done in this patch, hence BOOTBLOCK_CONSOLE is not yet enabled by default. Change-Id: Ia96499a9d478127f6b9d880883ac41397b58dbea Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/26859 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/cpu/intel/car/non-evict/cache_as_ram.S | 5 ++ src/cpu/intel/haswell/Kconfig | 4 -- src/cpu/intel/haswell/Makefile.inc | 6 ++- src/cpu/intel/haswell/bootblock.c | 57 ++------------------ src/northbridge/intel/haswell/Kconfig | 13 +++-- src/northbridge/intel/haswell/Makefile.inc | 3 +- src/northbridge/intel/haswell/bootblock.c | 11 ++-- src/southbridge/intel/lynxpoint/Kconfig | 4 -- src/southbridge/intel/lynxpoint/Makefile.inc | 2 + src/southbridge/intel/lynxpoint/bootblock.c | 3 +- src/southbridge/intel/lynxpoint/early_pch.c | 2 - 11 files changed, 33 insertions(+), 77 deletions(-) diff --git a/src/cpu/intel/car/non-evict/cache_as_ram.S b/src/cpu/intel/car/non-evict/cache_as_ram.S index b2b915fe76c..251714cb8f2 100644 --- a/src/cpu/intel/car/non-evict/cache_as_ram.S +++ b/src/cpu/intel/car/non-evict/cache_as_ram.S @@ -33,6 +33,11 @@ _cache_as_ram_setup: bootblock_pre_c_entry: +#if CONFIG(C_ENVIRONMENT_BOOTBLOCK) + movl $cache_as_ram, %esp /* return address */ + jmp check_mtrr /* Check if CPU properly reset */ +#endif + cache_as_ram: post_code(0x20) diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig index 3aadfdee5a6..3fd8bb484a5 100644 --- a/src/cpu/intel/haswell/Kconfig +++ b/src/cpu/intel/haswell/Kconfig @@ -24,10 +24,6 @@ config CPU_SPECIFIC_OPTIONS select PARALLEL_MP select CPU_INTEL_COMMON -config BOOTBLOCK_CPU_INIT - string - default "cpu/intel/haswell/bootblock.c" - config SMM_TSEG_SIZE hex default 0x800000 diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc index 1fa71c9521d..3b5229455ee 100644 --- a/src/cpu/intel/haswell/Makefile.inc +++ b/src/cpu/intel/haswell/Makefile.inc @@ -21,7 +21,11 @@ ramstage-y += monotonic_timer.c smm-y += monotonic_timer.c endif -cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S +bootblock-y += ../car/non-evict/cache_as_ram.S +bootblock-y += ../car/bootblock.c +bootblock-y += ../../x86/early_reset.S +bootblock-y += bootblock.c + postcar-y += ../car/non-evict/exit_car.S subdirs-y += ../../x86/tsc diff --git a/src/cpu/intel/haswell/bootblock.c b/src/cpu/intel/haswell/bootblock.c index 722cc0102e0..7baa2a81ec6 100644 --- a/src/cpu/intel/haswell/bootblock.c +++ b/src/cpu/intel/haswell/bootblock.c @@ -14,7 +14,7 @@ */ #include -#include +#include #include #include #include @@ -23,41 +23,8 @@ #include #include "haswell.h" -#if CONFIG(SOUTHBRIDGE_INTEL_LYNXPOINT) -/* Needed for RCBA access to set Soft Reset Data register */ #include -#else -#error "CPU must be paired with Intel LynxPoint southbridge" -#endif - -static void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, - unsigned int type) - -{ - /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */ - /* FIXME: It only support 4G less range */ - msr_t basem, maskm; - basem.lo = base | type; - basem.hi = 0; - wrmsr(MTRR_PHYS_BASE(reg), basem); - maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; - maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1; - wrmsr(MTRR_PHYS_MASK(reg), maskm); -} - -static void enable_rom_caching(void) -{ - msr_t msr; - - disable_cache(); - set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT); - enable_cache(); - - /* Enable Variable MTRRs */ - msr.hi = 0x00000000; - msr.lo = 0x00000800; - wrmsr(MTRR_DEF_TYPE_MSR, msr); -} +#include static void set_flex_ratio_to_tdp_nominal(void) { @@ -105,26 +72,8 @@ static void set_flex_ratio_to_tdp_nominal(void) halt(); } -static void check_for_clean_reset(void) -{ - msr_t msr; - msr = rdmsr(MTRR_DEF_TYPE_MSR); - - /* Use the MTRR default type MSR as a proxy for detecting INIT#. - * Reset the system if any known bits are set in that MSR. That is - * an indication of the CPU not being properly reset. */ - if (msr.lo & (MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)) { - outb(0x0, 0xcf9); - outb(0x6, 0xcf9); - halt(); - } -} - -static void bootblock_cpu_init(void) +void bootblock_early_cpu_init(void) { /* Set flex ratio and reset if needed */ set_flex_ratio_to_tdp_nominal(); - check_for_clean_reset(); - enable_rom_caching(); - intel_update_microcode_from_cbfs(); } diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig index 082f2d63d98..242ab18c498 100644 --- a/src/northbridge/intel/haswell/Kconfig +++ b/src/northbridge/intel/haswell/Kconfig @@ -22,6 +22,8 @@ config NORTHBRIDGE_INTEL_HASWELL select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select POSTCAR_STAGE select POSTCAR_CONSOLE + select C_ENVIRONMENT_BOOTBLOCK +# select BOOTBLOCK_CONSOLE TODO: route LPC if NORTHBRIDGE_INTEL_HASWELL @@ -29,10 +31,6 @@ config VBOOT select VBOOT_OPROM_MATTERS select VBOOT_STARTS_IN_ROMSTAGE -config BOOTBLOCK_NORTHBRIDGE_INIT - string - default "northbridge/intel/haswell/bootblock.c" - config VGA_BIOS_ID string default "8086,0166" @@ -63,6 +61,13 @@ config DCACHE_RAM_MRC_VAR_SIZE help The amount of cache-as-ram region required by the reference code. +config DCACHE_BSP_STACK_SIZE + hex + default 0x2000 + help + The amount of anticipated stack usage in CAR by bootblock and + other stages. + config HAVE_MRC bool "Add a System Agent binary" help diff --git a/src/northbridge/intel/haswell/Makefile.inc b/src/northbridge/intel/haswell/Makefile.inc index 055c2a8a0d6..7abbccacd2b 100644 --- a/src/northbridge/intel/haswell/Makefile.inc +++ b/src/northbridge/intel/haswell/Makefile.inc @@ -15,6 +15,8 @@ ifeq ($(CONFIG_NORTHBRIDGE_INTEL_HASWELL),y) +bootblock-y += bootblock.c + ramstage-y += ram_calc.c ramstage-y += northbridge.c ramstage-y += gma.c @@ -26,7 +28,6 @@ romstage-y += ram_calc.c romstage-y += raminit.c romstage-y += early_init.c romstage-y += report_platform.c -romstage-y += ../../../arch/x86/walkcbfs.S smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c diff --git a/src/northbridge/intel/haswell/bootblock.c b/src/northbridge/intel/haswell/bootblock.c index e503e01fa15..2c1bd58dde2 100644 --- a/src/northbridge/intel/haswell/bootblock.c +++ b/src/northbridge/intel/haswell/bootblock.c @@ -12,11 +12,10 @@ */ #include +#include +#include "haswell.h" -/* Just re-define this instead of including haswell.h. It blows up romcc. */ -#define PCIEXBAR 0x60 - -static void bootblock_northbridge_init(void) +void bootblock_early_northbridge_init(void) { uint32_t reg; @@ -33,7 +32,7 @@ static void bootblock_northbridge_init(void) * 4GiB. */ reg = 0; - pci_io_write_config32(PCI_DEV(0,0,0), PCIEXBAR + 4, reg); + pci_io_write_config32(PCI_DEV(0, 0, 0), PCIEXBAR + 4, reg); reg = CONFIG_MMCONF_BASE_ADDRESS | 4 | 1; /* 64MiB - 0-63 buses. */ - pci_io_write_config32(PCI_DEV(0,0,0), PCIEXBAR, reg); + pci_io_write_config32(PCI_DEV(0, 0, 0), PCIEXBAR, reg); } diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig index 431744f08c5..5573ec96adc 100644 --- a/src/southbridge/intel/lynxpoint/Kconfig +++ b/src/southbridge/intel/lynxpoint/Kconfig @@ -53,10 +53,6 @@ config EHCI_BAR hex default 0xe8000000 -config BOOTBLOCK_SOUTHBRIDGE_INIT - string - default "southbridge/intel/lynxpoint/bootblock.c" - config SERIRQ_CONTINUOUS_MODE bool default n diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index b18e6dafc88..62766dfe904 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -15,6 +15,8 @@ ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_LYNXPOINT),y) +bootblock-y += bootblock.c + ramstage-y += pch.c ramstage-y += azalia.c ramstage-y += lpc.c diff --git a/src/southbridge/intel/lynxpoint/bootblock.c b/src/southbridge/intel/lynxpoint/bootblock.c index 16f4ef90bc0..69fdd611d2c 100644 --- a/src/southbridge/intel/lynxpoint/bootblock.c +++ b/src/southbridge/intel/lynxpoint/bootblock.c @@ -14,6 +14,7 @@ */ #include +#include #include "pch.h" /* @@ -69,7 +70,7 @@ static void set_spi_speed(void) SPIBAR8(SSFC + 2) = ssfc; } -static void bootblock_southbridge_init(void) +void bootblock_early_southbridge_init(void) { map_rcba(); enable_spi_prefetch(); diff --git a/src/southbridge/intel/lynxpoint/early_pch.c b/src/southbridge/intel/lynxpoint/early_pch.c index 3d2d2c48faf..f615507dade 100644 --- a/src/southbridge/intel/lynxpoint/early_pch.c +++ b/src/southbridge/intel/lynxpoint/early_pch.c @@ -116,8 +116,6 @@ int early_pch_init(const void *gpio_map, mainboard_config_superio(); - console_init(); - pch_generic_setup(); /* Enable SMBus for reading SPDs. */ From 77d5e7481b56ac396e02e73259d1fb414b375470 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 3 Jan 2019 21:11:45 +0100 Subject: [PATCH 010/588] nb/intel/haswell: Add an option for where verstage starts Previously Haswell used a romcc bootblock and starting verstage in romstage was madatory but with C_ENVIRONMENT_BOOTBLOCK it is also possible to have a separate verstage. This selects using a separate verstage by default but still keeps the option around to use verstage in romstage. Also make sure mrc.bin is only added to the COREBOOT fmap region as it requires to be run at a specific offset. This means that coreboot will have to jump from a RW region to the RO region for that binary and back to that RW region after that binary is done initializing the memory. Change-Id: I3b7b29f4a24c0fb830ff76fe31a35b6afcae4e67 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/26926 Reviewed-by: Duncan Laurie Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/cpu/intel/haswell/Makefile.inc | 2 ++ src/mainboard/google/beltino/Makefile.inc | 1 + src/mainboard/intel/baskingridge/Makefile.inc | 1 + src/northbridge/intel/haswell/Kconfig | 25 ++++++++++++++++++- src/southbridge/intel/common/Makefile.inc | 2 ++ src/southbridge/intel/lynxpoint/Makefile.inc | 3 +++ src/southbridge/intel/lynxpoint/pmutil.c | 3 +++ 7 files changed, 36 insertions(+), 1 deletion(-) diff --git a/src/cpu/intel/haswell/Makefile.inc b/src/cpu/intel/haswell/Makefile.inc index 3b5229455ee..f83d5db9703 100644 --- a/src/cpu/intel/haswell/Makefile.inc +++ b/src/cpu/intel/haswell/Makefile.inc @@ -28,6 +28,8 @@ bootblock-y += bootblock.c postcar-y += ../car/non-evict/exit_car.S +verstage-y += tsc_freq.c + subdirs-y += ../../x86/tsc subdirs-y += ../../x86/mtrr subdirs-y += ../../x86/lapic diff --git a/src/mainboard/google/beltino/Makefile.inc b/src/mainboard/google/beltino/Makefile.inc index 5e45472cedc..bb90e9780b7 100644 --- a/src/mainboard/google/beltino/Makefile.inc +++ b/src/mainboard/google/beltino/Makefile.inc @@ -15,6 +15,7 @@ romstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c +verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += chromeos.c ramstage-y += lan.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c variants/$(VARIANT_DIR)/led.c diff --git a/src/mainboard/intel/baskingridge/Makefile.inc b/src/mainboard/intel/baskingridge/Makefile.inc index 5ef8363e35f..06e86c1d6cb 100644 --- a/src/mainboard/intel/baskingridge/Makefile.inc +++ b/src/mainboard/intel/baskingridge/Makefile.inc @@ -15,5 +15,6 @@ romstage-y += chromeos.c ramstage-y += chromeos.c +verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += chromeos.c smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig index 242ab18c498..e0c55d2f929 100644 --- a/src/northbridge/intel/haswell/Kconfig +++ b/src/northbridge/intel/haswell/Kconfig @@ -27,9 +27,25 @@ config NORTHBRIDGE_INTEL_HASWELL if NORTHBRIDGE_INTEL_HASWELL +config HASWELL_VBOOT_IN_BOOTBLOCK + depends on VBOOT + bool "Start verstage in bootblock" + default y + select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_SEPARATE_VERSTAGE + help + Haswell can either start verstage in a separate stage + right after the bootblock has run or it can start it + after romstage for compatibility reasons. + Haswell however uses a mrc.bin to initialse memory which + needs to be located at a fixed offset. Therefore even with + a separate verstage starting after the bootblock that same + binary is used meaning a jump is made from RW to the RO region + and back to the RW region after the binary is done. + config VBOOT select VBOOT_OPROM_MATTERS - select VBOOT_STARTS_IN_ROMSTAGE + select VBOOT_STARTS_IN_ROMSTAGE if !HASWELL_VBOOT_IN_BOOTBLOCK config VGA_BIOS_ID string @@ -93,4 +109,11 @@ config PRE_GRAPHICS_DELAY VBIOS. On those systems we need to wait for a bit before executing the VBIOS. +# The UEFI System Agent binary needs to be at a fixed offset in the flash +# and can therefore only reside in the COREBOOT fmap region +config RO_REGION_ONLY + string + depends on VBOOT + default "mrc.bin" + endif diff --git a/src/southbridge/intel/common/Makefile.inc b/src/southbridge/intel/common/Makefile.inc index ac339a29159..1085f6c66a0 100644 --- a/src/southbridge/intel/common/Makefile.inc +++ b/src/southbridge/intel/common/Makefile.inc @@ -29,6 +29,7 @@ romstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_PMCLIB) += pmclib.c ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_COMMON),y) +verstage-y += pmbase.c romstage-y += pmbase.c ramstage-y += pmbase.c postcar-y += pmbase.c @@ -59,6 +60,7 @@ ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_ACPI_MADT) += madt.c smm-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_FINALIZE) += finalize.c +verstage-y += rtc.c romstage-y += rtc.c ramstage-y += rtc.c postcar-y += rtc.c diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index 62766dfe904..fd00f6c50e0 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -55,4 +55,7 @@ ramstage-y += lp_gpio.c smm-$(CONFIG_HAVE_SMI_HANDLER) += lp_gpio.c endif +verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += pmutil.c +verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += lp_gpio.c + endif diff --git a/src/southbridge/intel/lynxpoint/pmutil.c b/src/southbridge/intel/lynxpoint/pmutil.c index 3c63723f726..cc494771dd6 100644 --- a/src/southbridge/intel/lynxpoint/pmutil.c +++ b/src/southbridge/intel/lynxpoint/pmutil.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include "pch.h" #if CONFIG(INTEL_LYNXPOINT_LP) From 1db39a44661f57c2ffe0d795e21c0a4d5dddb494 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Tue, 15 Jan 2019 06:50:03 +0100 Subject: [PATCH 011/588] drivers/intel/fsp2_0: Set basename for FSP binaries Since there is no standardized naming scheme for the FSP binaries, the option USE_FSP_REPO can't be used on some platforms, because some of the filenames differ and the build process awaits "Fsp_*.fd" as filename. As a workaround, add the option -n to SplitFspBin.py, which defines the basename. Change-Id: Idc684ad00033ffafd1090fc32b23549ce9603b4f Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/30930 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/drivers/intel/fsp2_0/Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/intel/fsp2_0/Makefile.inc b/src/drivers/intel/fsp2_0/Makefile.inc index f26a7761330..d627a3dbb1d 100644 --- a/src/drivers/intel/fsp2_0/Makefile.inc +++ b/src/drivers/intel/fsp2_0/Makefile.inc @@ -69,7 +69,7 @@ $(CONFIG_FSP_S_CBFS)-type := fsp ifeq ($(CONFIG_FSP_USE_REPO),y) $(obj)/Fsp_M.fd: $(call strip_quotes,$(CONFIG_FSP_FD_PATH)) - python2 3rdparty/fsp/Tools/SplitFspBin.py split -f $(CONFIG_FSP_FD_PATH) -o "$(obj)" + python2 3rdparty/fsp/Tools/SplitFspBin.py split -f $(CONFIG_FSP_FD_PATH) -o "$(obj)" -n "Fsp.fd" $(obj)/Fsp_S.fd: $(call strip_quotes,$(CONFIG_FSP_FD_PATH)) $(obj)/Fsp_M.fd true From c94ba798d6f3aa3bf49f6d00d7bb18a4cc00268f Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 22 Apr 2019 00:25:05 +0200 Subject: [PATCH 012/588] arch/x86/car.ld: Also check mrc.bin heap for Ivybridge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sandy- and ivybridge use the same mrc.bin that has the heap in an awkward location. Change-Id: If985a48c6703c8a86d8051e67595cf0fd409d99a Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32385 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Kyösti Mälkki --- src/arch/x86/car.ld | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld index 37fb087ebdb..d97df19a376 100644 --- a/src/arch/x86/car.ld +++ b/src/arch/x86/car.ld @@ -89,7 +89,8 @@ _car_global_end = .; _car_relocatable_data_end = .; -#if CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) && \ +#if (CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) || \ + CONFIG(NORTHBRIDGE_INTEL_IVYBRIDGE)) && \ !CONFIG(USE_NATIVE_RAMINIT) . = ABSOLUTE(0xff7e1000); _mrc_pool = .; From e3f5f2155a75687ab50d53c49977748f4cecdb2b Mon Sep 17 00:00:00 2001 From: Roy Mingi Park Date: Sat, 13 Apr 2019 15:16:50 -0700 Subject: [PATCH 013/588] mb/google/sarien: Configure both GPP_H12 and GPP_H13 for SSD on Arcada Currently, Arcada only supports D3hot during S0iX and there is leakage power around 5~10mW depending on SSD vendors. To support D3cold for SSD during S0iX, one MOSFET will be added on DVT2 and two GPIOs are required to be configured. GPP_H13 is to control SSD_SCP_PWR_EN(power enable) and GPP_H12 is to control SSD reset. BUG=b:130741066 TEST=Measure SSD power during S0iX from Arcada(DVT2) Change-Id: I868590e9e85d5df07930a3681884e3fc3a5c4d50 Signed-off-by: Roy Mingi Park Reviewed-on: https://review.coreboot.org/c/coreboot/+/32361 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/variants/arcada/gpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/gpio.c b/src/mainboard/google/sarien/variants/arcada/gpio.c index b66e1dda435..2a0ead82a93 100644 --- a/src/mainboard/google/sarien/variants/arcada/gpio.c +++ b/src/mainboard/google/sarien/variants/arcada/gpio.c @@ -211,8 +211,8 @@ static const struct pad_config gpio_table[] = { /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* I2C5_SDA */ PAD_NC(GPP_H10, NONE), /* ISH_I2C2_SDA */ /* I2C5_SCL */ PAD_NC(GPP_H11, NONE), /* ISH_I2C2_SCL */ -/* M2_SKT2_CFG0 */ PAD_NC(GPP_H12, NONE), -/* M2_SKT2_CFG1 */ PAD_NC(GPP_H13, NONE), +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ +/* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* M2_SKT2_CFG2 */ PAD_NC(GPP_H14, NONE), /* M2_SKT2_CFG3 */ PAD_CFG_GPO(GPP_H15, 1, DEEP), /* BT_RADIO_DIS# */ /* DDPF_CTRLCLK */ PAD_NC(GPP_H16, NONE), From 69eae2762fc34f8303e8a41065df437295262586 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Thu, 18 Apr 2019 17:31:55 +0800 Subject: [PATCH 014/588] board/kukui: Support ADC value for NC When the components like LCM ID are not installed (i.e., NC), ADC will return some value with much larger variation from standard value (out of the tolerance we set). To support that, we should check tolerance only on non-NC voltages. Also improve the error messages so we can see the ADC raw values instead of simple assertion error (which makes debugging more difficult since we have to build another firmware image just to print the values). BUG=None TEST=Booted on Kukui and got correct SKU ID for NC LCMID. BRANCH=None Change-Id: I8d00956e0e3b48ddbcaa505dd3ade24720c3b4ad Signed-off-by: Hung-Te Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/32353 Reviewed-by: Julius Werner Reviewed-by: You-Cheng Syu Tested-by: build bot (Jenkins) --- src/mainboard/google/kukui/boardid.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/kukui/boardid.c b/src/mainboard/google/kukui/boardid.c index b9f1ba2226e..71f051f3120 100644 --- a/src/mainboard/google/kukui/boardid.c +++ b/src/mainboard/google/kukui/boardid.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -82,8 +83,13 @@ static uint32_t get_adc_index(unsigned int channel) if (value < (voltages[id] + voltages[id + 1]) / 2) break; + /* The last level is NC and may be larger than standard tolerance. */ const int tolerance = 10000; /* 10,000 uV */ - assert(ABS(value - voltages[id]) < tolerance); + if (id < ADC_LEVELS - 1 && ABS(value - voltages[id]) > tolerance) { + printk(BIOS_ERR, "ADC channel %u value out of range: %d\n", + channel, value); + assert(0); + } return id; } From 7f1a0e6b4c6a319d3cd552c708195d94b99bbb97 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Mon, 22 Apr 2019 21:17:58 +0000 Subject: [PATCH 015/588] Revert "soc/intel/cannonlake: Enable coreboot MP PPI service for WHL/CML" This reverts commit 41dad286d846819242a84fc65faed2bbb35845ac. The change will make s0ix fail on Sarien/Arcada Platform. Signed-off-by: Lijian Zhao Change-Id: I169bc6f41fba82fcf515267e8e1d08aa5ee2dce4 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32391 Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 8 -------- src/soc/intel/cannonlake/fsp_params.c | 5 ----- src/soc/intel/cannonlake/romstage/fsp_params.c | 5 +---- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 026aaf20ffd..40b40d65ad2 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -27,8 +27,6 @@ config SOC_INTEL_WHISKEYLAKE bool default n select SOC_INTEL_COMMON_CANNONLAKE_BASE - select FSP_PEIM_TO_PEIM_INTERFACE - select USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI help Intel Whiskeylake support @@ -36,12 +34,6 @@ config SOC_INTEL_COMETLAKE bool default n select SOC_INTEL_COMMON_CANNONLAKE_BASE - # TODO: - # Delete FSP_PEIM_TO_PEIM_INTERFACE and - # USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI selection - # and select PLATFORM_USES_FSP2_1 once FSP support for CML is ready - select FSP_PEIM_TO_PEIM_INTERFACE - select USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI help Intel Cometlake support diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index 1fd42cda178..b8dba184cb7 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -18,9 +18,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -144,9 +142,6 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) params->Usb3OverCurrentPin[i] = 0; } - if (CONFIG(USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI)) - params->CpuMpPpi = (uintptr_t) mp_fill_ppi_services_data(); - mainboard_silicon_init_params(params); /* Set PsysPmax if it is available from DT */ diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 2ad2c935b77..86160f68aef 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -65,10 +65,7 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, const config_t *config) m_cfg->VmxEnable = CONFIG(ENABLE_VMX); #if CONFIG(SOC_INTEL_COMMON_CANNONLAKE_BASE) - if (CONFIG(USE_INTEL_FSP_TO_CALL_COREBOOT_PUBLISH_MP_PPI)) - m_cfg->SkipMpInit = 0; - else - m_cfg->SkipMpInit = !CONFIG_USE_INTEL_FSP_MP_INIT; + m_cfg->SkipMpInit = !CONFIG_USE_INTEL_FSP_MP_INIT; #endif /* Set CpuRatio to match existing MSR value */ From 6b6dc6eddd8e31a99167b19219a20cca115df3cc Mon Sep 17 00:00:00 2001 From: Philipp Hug Date: Thu, 4 Apr 2019 15:57:24 +0200 Subject: [PATCH 016/588] hifive-unleashed: update documentation to match current state Signed-off-by: Philipp Hug Change-Id: I3f1b7dd4ef52a64c9a222f2d5cffe2b73806fe4e Reviewed-on: https://review.coreboot.org/c/coreboot/+/32182 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- Documentation/mainboard/sifive/hifive-unleashed.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Documentation/mainboard/sifive/hifive-unleashed.md b/Documentation/mainboard/sifive/hifive-unleashed.md index cd7c93ca0b9..495dade2122 100644 --- a/Documentation/mainboard/sifive/hifive-unleashed.md +++ b/Documentation/mainboard/sifive/hifive-unleashed.md @@ -12,15 +12,13 @@ For general setup instructions, please refer to the [Getting Started Guide]. The following things are still missing from this coreboot port: - Support running romstage from flash (fix stack) to support boot mode 1 -- CBMEM support -- FU540 clock configuration -- FU540 RAM init -- Placing the ramstage in DRAM - Starting the U54 cores - FU540 PIN configuration and GPIO access macros - Provide serial number to payload (e.g. in device tree) +- Implement instruction emulation - Support for booting Linux on RISC-V - +- Add support to run OpenSBI payload in m-mode +- SMP support in trap handler ## Configuration From 8b784004d3190e6bc1e49994f726f8edcbd36460 Mon Sep 17 00:00:00 2001 From: Sheng-Liang Pan Date: Thu, 11 Apr 2019 16:31:12 +0800 Subject: [PATCH 017/588] mb/google/octopus: Add keyboard backlight support for Droid/Blorb Droid/Blorb supports keyboard backlight feature, so enable the ASL code. BUG=b:130330141 BRANCH=octopus TEST=Build and boot to OS, verify that the string 'KBLT' is in the DSDT. Change-Id: I74684e3905d34b61fa4b851798dbca018f986e5a Signed-off-by: Pan Sheng-Liang Reviewed-on: https://review.coreboot.org/c/coreboot/+/32298 Tested-by: build bot (Jenkins) Reviewed-by: Marco Chen Reviewed-by: Justin TerAvest Reviewed-by: David Wu Reviewed-by: Furquan Shaikh --- .../google/octopus/variants/bobba/include/variant/ec.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/mainboard/google/octopus/variants/bobba/include/variant/ec.h b/src/mainboard/google/octopus/variants/bobba/include/variant/ec.h index 16f931b6cdf..196d52e3e97 100644 --- a/src/mainboard/google/octopus/variants/bobba/include/variant/ec.h +++ b/src/mainboard/google/octopus/variants/bobba/include/variant/ec.h @@ -18,4 +18,7 @@ #include +/* Enable EC backed Keyboard Backlight in ACPI */ +#define EC_ENABLE_KEYBOARD_BACKLIGHT + #endif From 52cb8a7fec55ba3c27235b29691b4ff0741daed5 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 12 Apr 2019 15:23:41 +0200 Subject: [PATCH 018/588] payloads/U-Boot: Unexport the coreboot_exports Without this U-Boot ends up overwriting the coreboot .config when generating a configfile. Change-Id: I62fc0aa3ede0287ffc96915182a2ed5a4877f29d Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32303 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- payloads/external/U-Boot/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/payloads/external/U-Boot/Makefile b/payloads/external/U-Boot/Makefile index 67c60c15355..653662f0ff5 100644 --- a/payloads/external/U-Boot/Makefile +++ b/payloads/external/U-Boot/Makefile @@ -30,6 +30,7 @@ unexport KCONFIG_DEPENDENCIES unexport KCONFIG_SPLITCONFIG unexport KCONFIG_TRISTATE unexport KCONFIG_NEGATIVES +unexport $(COREBOOT_EXPORTS) all: build From f4af723fd86fe0b2aa7cd5eed9b6c8362a3d48fe Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 12 Apr 2019 15:24:57 +0200 Subject: [PATCH 019/588] payloads/U-Boot: Use a phony target for checking out a revision Change-Id: I5ea4df33545f69c06e4ae2158a1a6c14ead784a7 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32304 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- payloads/external/U-Boot/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/payloads/external/U-Boot/Makefile b/payloads/external/U-Boot/Makefile index 653662f0ff5..c17b67fd4e9 100644 --- a/payloads/external/U-Boot/Makefile +++ b/payloads/external/U-Boot/Makefile @@ -51,11 +51,11 @@ else touch $(project_dir)/$(STABLE_COMMIT_ID) endif -$(project_dir)/tag-$(TAG-y): fetch +checkout: fetch echo " Checking out $(project_name) revision $(TAG-y)" cd $(project_dir); git checkout master; git branch -D coreboot 2>/dev/null; git checkout -b coreboot $(TAG-y) -config: $(project_dir)/$(TAG-y) +config: checkout rm -f $(project_config_file) ifneq ($(CONFIG_PAYLOAD_CONFIGFILE),) ifneq ("$(wildcard $(CONFIG_PAYLOAD_CONFIGFILE))","") @@ -83,4 +83,4 @@ distclean: print-repo-info: echo "$(project_git_repo) $(project_dir)" -.PHONY: config build clean distclean fetch print-repo-info +.PHONY: checkout config build clean distclean fetch print-repo-info From 89d4a601f501f4bfa04dfcd73502651d1531f48c Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 12 Apr 2019 15:26:33 +0200 Subject: [PATCH 020/588] payload/U-Boot: Fix generating a default config on the master branch The name of the default configuration file for x86 coreboot changed. Change-Id: I6544142a70bd3e1e13ee52eccbd5335f8375a4f6 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32305 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- payloads/external/U-Boot/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/external/U-Boot/Makefile b/payloads/external/U-Boot/Makefile index c17b67fd4e9..b47e74c7388 100644 --- a/payloads/external/U-Boot/Makefile +++ b/payloads/external/U-Boot/Makefile @@ -65,7 +65,7 @@ else false endif else - cat $(project_dir)/configs/coreboot-x86_defconfig >> $(project_config_file) + cat $(project_dir)/configs/coreboot_defconfig >> $(project_config_file) endif $(MAKE) -C $(project_dir) olddefconfig From b524dfca40709dc6dbe07fded48799fe11b561ef Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 12 Apr 2019 15:32:24 +0200 Subject: [PATCH 021/588] payloads/U-Boot: Update to the latest stable 2019.4 Change-Id: I4740aa80e3c0faf9b18730390af778abcc92aac3 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32306 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- payloads/external/U-Boot/Kconfig | 2 +- payloads/external/U-Boot/Makefile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/payloads/external/U-Boot/Kconfig b/payloads/external/U-Boot/Kconfig index 2afe1cd5e11..a2bc512395f 100644 --- a/payloads/external/U-Boot/Kconfig +++ b/payloads/external/U-Boot/Kconfig @@ -9,7 +9,7 @@ choice default UBOOT_STABLE config UBOOT_STABLE - bool "v2016.1" + bool "v2019.4" help Stable U-Boot version diff --git a/payloads/external/U-Boot/Makefile b/payloads/external/U-Boot/Makefile index b47e74c7388..5cd89569d75 100644 --- a/payloads/external/U-Boot/Makefile +++ b/payloads/external/U-Boot/Makefile @@ -13,8 +13,8 @@ ## GNU General Public License for more details. ## -# 2016-1 tag -STABLE_COMMIT_ID=fa85e826c16b9ce1ad302a57e9c4b24db0d8b930 +# 2019-4 tag +STABLE_COMMIT_ID=3c99166441bf3ea325af2da83cfe65430b49c066 TAG-$(CONFIG_UBOOT_MASTER)=origin/master TAG-$(CONFIG_UBOOT_STABLE)=$(STABLE_COMMIT_ID) From 21f9b3ecd7babefa51f497bd61495316ebf41851 Mon Sep 17 00:00:00 2001 From: Robin Broda Date: Thu, 11 Apr 2019 21:14:15 +0200 Subject: [PATCH 022/588] util/intelmetool: Add Intel Cannon Lake PCH HECI Controller to supported PCI devices Signed-off-by: Robin Broda Change-Id: I0f9e83b3bdf35e3e3e119ffcb93b092121a67666 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32285 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- util/intelmetool/intelmetool.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/util/intelmetool/intelmetool.h b/util/intelmetool/intelmetool.h index ed86b23e336..27bf46dde20 100644 --- a/util/intelmetool/intelmetool.h +++ b/util/intelmetool/intelmetool.h @@ -454,6 +454,7 @@ static inline void print_cap(const char *name, int state) #define PCI_DEVICE_ID_INTEL_LEWISBURG_IE1 0xA1F8 /* IE Lewisburg #1 */ #define PCI_DEVICE_ID_INTEL_LEWISBURG_IE2 0xA1F9 /* IE Lewisburg #2 */ #define PCI_DEVICE_ID_INTEL_LEWISBURG_IE3 0xA1FC /* IE Lewisburg #3 */ +#define PCI_DEVICE_ID_INTEL_CANNONLAKE 0xA360 /* Cannon Lake */ #define PCI_DEV_HAS_SUPPORTED_ME(x) ( \ ((x) == PCI_DEVICE_ID_INTEL_COUGARPOINT_1) || \ @@ -505,6 +506,7 @@ static inline void print_cap(const char *name, int state) ((x) == PCI_DEVICE_ID_INTEL_LEWISBURG_IE1) || \ ((x) == PCI_DEVICE_ID_INTEL_LEWISBURG_IE2) || \ ((x) == PCI_DEVICE_ID_INTEL_LEWISBURG_IE3) || \ + ((x) == PCI_DEVICE_ID_INTEL_CANNONLAKE) || \ 0) #define BOOTGUARD_DISABLED 0x400000000 From 6f5225c7e0ad7a373af1decc212cde5c33b00730 Mon Sep 17 00:00:00 2001 From: Thejaswani Putta Date: Thu, 11 Apr 2019 18:36:08 -0700 Subject: [PATCH 023/588] Klocwork: Fix the Null pointer derefernce found by klocwork Signed-off-by: Thejaswani Putta Change-Id: I15973ac28e9645826986cf63d2160eedb83024e4 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32290 Reviewed-by: Julius Werner Reviewed-by: Lijian Zhao Tested-by: build bot (Jenkins) --- src/lib/string.c | 9 ++++++--- src/soc/intel/broadwell/ramstage.c | 3 +++ util/cbfstool/cbfs_sections.c | 5 +++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/lib/string.c b/src/lib/string.c index df2fd808491..2e71489ff60 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -6,7 +6,8 @@ char *strdup(const char *s) { size_t sz = strlen(s) + 1; char *d = malloc(sz); - memcpy(d, s, sz); + if (d) + memcpy(d, s, sz); return d; } @@ -15,7 +16,9 @@ char *strconcat(const char *s1, const char *s2) size_t sz_1 = strlen(s1); size_t sz_2 = strlen(s2); char *d = malloc(sz_1 + sz_2 + 1); - memcpy(d, s1, sz_1); - memcpy(d + sz_1, s2, sz_2 + 1); + if (d) { + memcpy(d, s1, sz_1); + memcpy(d + sz_1, s2, sz_2 + 1); + } return d; } diff --git a/src/soc/intel/broadwell/ramstage.c b/src/soc/intel/broadwell/ramstage.c index e1883f2ecd1..706536940de 100644 --- a/src/soc/intel/broadwell/ramstage.c +++ b/src/soc/intel/broadwell/ramstage.c @@ -23,6 +23,7 @@ #include #include #include +#include /* Save wake source information for calculating ACPI _SWS values */ int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0) @@ -31,6 +32,8 @@ int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0) static uint32_t gpe0_sts[GPE0_REG_MAX]; int i; + assert(ps != NULL); + *pm1 = ps->pm1_sts & ps->pm1_en; /* Mask off GPE0 status bits that are not enabled */ diff --git a/util/cbfstool/cbfs_sections.c b/util/cbfstool/cbfs_sections.c index 285725760b6..088534adc97 100644 --- a/util/cbfstool/cbfs_sections.c +++ b/util/cbfstool/cbfs_sections.c @@ -14,6 +14,7 @@ */ #include "cbfs_sections.h" +#include "common.h" #include #include @@ -65,6 +66,10 @@ bool fmd_process_flag_cbfs(const struct flashmap_descriptor *node) return false; list_node = (struct descriptor_node *)malloc(sizeof(*list_node)); + if (!list_node) { + ERROR("Cannot allocate CBFS flag node!\n"); + return false; + } list_node->val = node; list_node->next = NULL; From 7a50554e2965e02045bf314b5d4aa3e3af082c1e Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 12 Apr 2019 20:10:45 +0200 Subject: [PATCH 024/588] src/mainboard/{foxconn/d41s,intel/d510mo}: Use pci_or_config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pci_or_configx function makes the code shorter and more readable. Change-Id: Ic1ba250f8ac9fb75cf3252aec18af80842bda7dd Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32310 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Kyösti Mälkki --- src/mainboard/foxconn/d41s/romstage.c | 3 +-- src/mainboard/intel/d510mo/romstage.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mainboard/foxconn/d41s/romstage.c b/src/mainboard/foxconn/d41s/romstage.c index ecff4b9a2df..cdd12dc3ac5 100644 --- a/src/mainboard/foxconn/d41s/romstage.c +++ b/src/mainboard/foxconn/d41s/romstage.c @@ -28,8 +28,7 @@ void mb_enable_lpc(void) /* Disable Serial IRQ */ pci_write_config8(PCI_DEV(0, 0x1f, 0), SERIRQ_CNTL, 0xd0); /* Decode range */ - pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC, - pci_read_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC) | 0x0010); + pci_or_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC, 0x0010); pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_EN, CNF1_LPC_EN | KBC_LPC_EN | FDD_LPC_EN | LPT_LPC_EN | COMB_LPC_EN | COMA_LPC_EN); diff --git a/src/mainboard/intel/d510mo/romstage.c b/src/mainboard/intel/d510mo/romstage.c index c91d40e8900..024c3e10fe4 100644 --- a/src/mainboard/intel/d510mo/romstage.c +++ b/src/mainboard/intel/d510mo/romstage.c @@ -28,8 +28,7 @@ void mb_enable_lpc(void) /* Disable Serial IRQ */ pci_write_config8(PCI_DEV(0, 0x1f, 0), SERIRQ_CNTL, 0x00); /* Decode range */ - pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC, - pci_read_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC) | 0x0010); + pci_or_config16(PCI_DEV(0, 0x1f, 0), LPC_IO_DEC, 0x0010); pci_write_config16(PCI_DEV(0, 0x1f, 0), LPC_EN, CNF1_LPC_EN | CNF2_LPC_EN | KBC_LPC_EN | COMA_LPC_EN | COMB_LPC_EN); From 7118701e96c46e641cb4527e34fa48b77d105c43 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 10 Feb 2019 14:58:13 +0100 Subject: [PATCH 025/588] sb/intel/i82801gx/lpc: Use {read,write}_pmbase32 and lpc_get_pmbase Also use macros instead of magic numbers. Change-Id: I00bd687c487894c72d4e4363774dbcdfaf62dd54 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31310 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/southbridge/intel/i82801gx/lpc.c | 34 ++++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c index a1cc45af653..9a6c9cfefd6 100644 --- a/src/southbridge/intel/i82801gx/lpc.c +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -25,7 +25,6 @@ #include #include #include -#include "i82801gx.h" #include #include #include @@ -33,6 +32,9 @@ #include #include #include +#include + +#include "i82801gx.h" #include "nvs.h" #define NMI_OFF 0 @@ -167,7 +169,7 @@ static void i82801gx_gpi_routing(struct device *dev) static void i82801gx_power_options(struct device *dev) { u8 reg8; - u16 reg16, pmbase; + u16 reg16; u32 reg32; const char *state; /* Get the chip configuration */ @@ -254,18 +256,16 @@ static void i82801gx_power_options(struct device *dev) // Set the board's GPI routing. i82801gx_gpi_routing(dev); - pmbase = pci_read_config16(dev, 0x40) & 0xfffe; - - outl(config->gpe0_en, pmbase + GPE0_EN); - outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN); + write_pmbase32(GPE0_EN, config->gpe0_en); + write_pmbase16(ALT_GP_SMI_EN, config->alt_gp_smi_en); /* Set up power management block and determine sleep mode */ - reg32 = inl(pmbase + 0x04); // PM1_CNT + reg32 = read_pmbase32(PM1_CNT); reg32 &= ~(7 << 10); // SLP_TYP reg32 |= (1 << 1); // enable C3->C0 transition on bus master reg32 |= (1 << 0); // SCI_EN - outl(reg32, pmbase + 0x04); + write_pmbase32(PM1_CNT, reg32); } static void i82801gx_configure_cstates(struct device *dev) @@ -486,15 +486,15 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) { struct device *dev = pcidev_on_root(0x1f, 0); config_t *chip = dev->chip_info; - u16 pmbase = pci_read_config16(dev, 0x40) & 0xfffe; + u16 pmbase = lpc_get_pmbase(); fadt->pm1a_evt_blk = pmbase; fadt->pm1b_evt_blk = 0x0; - fadt->pm1a_cnt_blk = pmbase + 0x4; + fadt->pm1a_cnt_blk = pmbase + PM1_CNT; fadt->pm1b_cnt_blk = 0x0; - fadt->pm2_cnt_blk = pmbase + 0x20; - fadt->pm_tmr_blk = pmbase + 0x8; - fadt->gpe0_blk = pmbase + 0x28; + fadt->pm2_cnt_blk = pmbase + PM2_CNT; + fadt->pm_tmr_blk = pmbase + PM1_TMR; + fadt->gpe0_blk = pmbase + GPE0_STS; fadt->gpe1_blk = 0; fadt->pm1_evt_len = 4; @@ -532,7 +532,7 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) fadt->x_pm1a_cnt_blk.bit_width = 16; fadt->x_pm1a_cnt_blk.bit_offset = 0; fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS; - fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4; + fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT; fadt->x_pm1a_cnt_blk.addrh = 0x0; fadt->x_pm1b_cnt_blk.space_id = 0; @@ -546,21 +546,21 @@ void acpi_fill_fadt(acpi_fadt_t *fadt) fadt->x_pm2_cnt_blk.bit_width = 8; fadt->x_pm2_cnt_blk.bit_offset = 0; fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS; - fadt->x_pm2_cnt_blk.addrl = pmbase + 0x20; + fadt->x_pm2_cnt_blk.addrl = pmbase + PM2_CNT; fadt->x_pm2_cnt_blk.addrh = 0x0; fadt->x_pm_tmr_blk.space_id = 1; fadt->x_pm_tmr_blk.bit_width = 32; fadt->x_pm_tmr_blk.bit_offset = 0; fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; - fadt->x_pm_tmr_blk.addrl = pmbase + 0x8; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; fadt->x_pm_tmr_blk.addrh = 0x0; fadt->x_gpe0_blk.space_id = 1; fadt->x_gpe0_blk.bit_width = 64; fadt->x_gpe0_blk.bit_offset = 0; fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS; - fadt->x_gpe0_blk.addrl = pmbase + 0x28; + fadt->x_gpe0_blk.addrl = pmbase + GPE0_STS; fadt->x_gpe0_blk.addrh = 0x0; fadt->x_gpe1_blk.space_id = 0; From 20eaef024cb06677de10d018e6f70c28d1841290 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 29 Mar 2019 17:45:28 +0100 Subject: [PATCH 026/588] src: Add missing include 'console.h' Change-Id: Ie21c390ab04adb5b05d5f9760d227d2a175ccb56 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32122 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh --- src/arch/arm64/arm_tf.c | 1 + src/arch/riscv/boot.c | 1 - src/commonlib/storage/sdhci_adma.c | 1 + src/cpu/amd/family_10h-family_15h/fidvid.c | 1 + src/cpu/amd/family_10h-family_15h/init_cpus.c | 1 + src/cpu/amd/family_10h-family_15h/init_cpus.h | 1 - src/drivers/amd/agesa/def_callouts.c | 1 + src/drivers/amd/agesa/heapmanager.c | 1 + src/drivers/amd/agesa/oem_s3.c | 1 + src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c | 1 + src/drivers/spi/spi_flash.c | 1 + src/lib/generic_dump_spd.c | 2 ++ src/mainboard/amd/bettong/BiosCallOuts.c | 1 + src/mainboard/bap/ode_e20XX/BiosCallOuts.c | 1 + src/mainboard/bap/ode_e21XX/BiosCallOuts.c | 1 + src/mainboard/biostar/am1ml/BiosCallOuts.c | 1 + src/mainboard/foxconn/g41s-k/romstage.c | 1 + src/mainboard/google/poppy/variants/nami/mainboard.c | 1 + src/mainboard/lippert/frontrunner-af/BiosCallOuts.c | 1 + src/mainboard/lippert/toucan-af/BiosCallOuts.c | 1 + src/mainboard/pcengines/apu1/BiosCallOuts.c | 2 ++ src/mainboard/pcengines/apu2/BiosCallOuts.c | 1 + src/northbridge/amd/agesa/family14/state_machine.c | 3 +-- src/northbridge/amd/amdmct/mct/mct_d.c | 2 ++ src/northbridge/amd/amdmct/mct/mctdqs_d.c | 2 ++ src/northbridge/amd/amdmct/mct/mcttmrl.c | 2 ++ src/northbridge/amd/pi/agesawrapper.c | 1 + src/northbridge/via/vx900/memmap.c | 5 +++-- src/northbridge/via/vx900/pci_util.c | 2 ++ src/soc/amd/common/block/pi/agesawrapper.c | 1 + src/soc/amd/common/block/pi/def_callouts.c | 1 + src/soc/amd/common/block/pi/refcode_loader.c | 1 + src/soc/amd/stoneyridge/BiosCallOuts.c | 5 +++-- src/soc/amd/stoneyridge/ramtop.c | 1 + src/soc/amd/stoneyridge/smbus_spd.c | 1 + src/soc/intel/apollolake/acpi.c | 2 ++ src/soc/intel/apollolake/uart.c | 1 + src/soc/intel/cannonlake/uart.c | 1 + src/soc/intel/common/block/acpi/acpi.c | 1 + src/soc/intel/common/block/cpu/mp_init.c | 1 + src/soc/intel/common/block/gpio/gpio.c | 2 ++ src/soc/intel/denverton_ns/acpi.c | 2 +- src/soc/intel/denverton_ns/include/soc/hob_mem.h | 1 + src/soc/intel/fsp_baytrail/i2c.c | 1 + src/soc/intel/icelake/uart.c | 1 + src/soc/intel/quark/acpi.c | 1 + src/soc/mediatek/common/spi.c | 1 + src/soc/mediatek/mt8173/dramc_pi_calibration_api.c | 1 + src/soc/mediatek/mt8173/i2c.c | 1 + src/soc/mediatek/mt8173/pmic_wrap.c | 1 + src/soc/mediatek/mt8183/mt6358.c | 1 + src/soc/nvidia/tegra210/funitcfg.c | 1 + src/soc/nvidia/tegra210/ramstage.c | 1 + src/soc/rockchip/rk3288/crypto.c | 1 + src/southbridge/amd/agesa/hudson/resume.c | 2 +- src/southbridge/amd/agesa/hudson/smbus_spd.c | 3 +-- src/southbridge/amd/cimx/sb900/cfg.c | 4 ++-- src/southbridge/amd/pi/hudson/smbus_spd.c | 2 +- src/southbridge/broadcom/bcm5785/early_smbus.c | 2 ++ 59 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/arch/arm64/arm_tf.c b/src/arch/arm64/arm_tf.c index 7cf173b5bb4..f43bc028d27 100644 --- a/src/arch/arm64/arm_tf.c +++ b/src/arch/arm64/arm_tf.c @@ -21,6 +21,7 @@ #include #include #include +#include #include /* diff --git a/src/arch/riscv/boot.c b/src/arch/riscv/boot.c index 29064b1dc10..edf5295d79f 100644 --- a/src/arch/riscv/boot.c +++ b/src/arch/riscv/boot.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/src/commonlib/storage/sdhci_adma.c b/src/commonlib/storage/sdhci_adma.c index 1bae3fbff2d..bf6f457a466 100644 --- a/src/commonlib/storage/sdhci_adma.c +++ b/src/commonlib/storage/sdhci_adma.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/cpu/amd/family_10h-family_15h/fidvid.c b/src/cpu/amd/family_10h-family_15h/fidvid.c index 579cae5d1de..2c6e08cf0a3 100644 --- a/src/cpu/amd/family_10h-family_15h/fidvid.c +++ b/src/cpu/amd/family_10h-family_15h/fidvid.c @@ -89,6 +89,7 @@ b.- prep_fid_change(...) */ +#include #include #include #include diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c index 76bc6d99e50..719d62fbcc0 100644 --- a/src/cpu/amd/family_10h-family_15h/init_cpus.c +++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include "init_cpus.h" diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.h b/src/cpu/amd/family_10h-family_15h/init_cpus.h index d09fc8241c5..5d653d123b0 100644 --- a/src/cpu/amd/family_10h-family_15h/init_cpus.h +++ b/src/cpu/amd/family_10h-family_15h/init_cpus.h @@ -17,7 +17,6 @@ #define INIT_CPUS_H #include -#include #include #include #include diff --git a/src/drivers/amd/agesa/def_callouts.c b/src/drivers/amd/agesa/def_callouts.c index 92ccff8b73a..fa41500e409 100644 --- a/src/drivers/amd/agesa/def_callouts.c +++ b/src/drivers/amd/agesa/def_callouts.c @@ -15,6 +15,7 @@ */ #include +#include #include #include diff --git a/src/drivers/amd/agesa/heapmanager.c b/src/drivers/amd/agesa/heapmanager.c index a38696fc0f3..513e8049b13 100644 --- a/src/drivers/amd/agesa/heapmanager.c +++ b/src/drivers/amd/agesa/heapmanager.c @@ -20,6 +20,7 @@ #include #include +#include #include /* BIOS_HEAP_START_ADDRESS is only for cold boots. */ diff --git a/src/drivers/amd/agesa/oem_s3.c b/src/drivers/amd/agesa/oem_s3.c index 586189b406c..acd34b8edfc 100644 --- a/src/drivers/amd/agesa/oem_s3.c +++ b/src/drivers/amd/agesa/oem_s3.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c index fe6c4b36b81..00f630747ad 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index 82398ddf06b..fc831c3e9c4 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include diff --git a/src/lib/generic_dump_spd.c b/src/lib/generic_dump_spd.c index 63e47a2d281..fdde0263b66 100644 --- a/src/lib/generic_dump_spd.c +++ b/src/lib/generic_dump_spd.c @@ -3,6 +3,8 @@ * It should go away either there or here, depending what fits better. */ +#include + static void dump_spd_registers(const struct mem_controller *ctrl) { int i; diff --git a/src/mainboard/amd/bettong/BiosCallOuts.c b/src/mainboard/amd/bettong/BiosCallOuts.c index e4020b0ed02..d318d0c43f5 100644 --- a/src/mainboard/amd/bettong/BiosCallOuts.c +++ b/src/mainboard/amd/bettong/BiosCallOuts.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/src/mainboard/bap/ode_e20XX/BiosCallOuts.c b/src/mainboard/bap/ode_e20XX/BiosCallOuts.c index 9f7fbf89f66..4f5ab882329 100644 --- a/src/mainboard/bap/ode_e20XX/BiosCallOuts.c +++ b/src/mainboard/bap/ode_e20XX/BiosCallOuts.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/src/mainboard/bap/ode_e21XX/BiosCallOuts.c b/src/mainboard/bap/ode_e21XX/BiosCallOuts.c index 1d86d53be9f..6458b974ff4 100644 --- a/src/mainboard/bap/ode_e21XX/BiosCallOuts.c +++ b/src/mainboard/bap/ode_e21XX/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/biostar/am1ml/BiosCallOuts.c b/src/mainboard/biostar/am1ml/BiosCallOuts.c index 43db0d755b3..17c25aece6e 100644 --- a/src/mainboard/biostar/am1ml/BiosCallOuts.c +++ b/src/mainboard/biostar/am1ml/BiosCallOuts.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/src/mainboard/foxconn/g41s-k/romstage.c b/src/mainboard/foxconn/g41s-k/romstage.c index 01c6edd0976..ec4541f92eb 100644 --- a/src/mainboard/foxconn/g41s-k/romstage.c +++ b/src/mainboard/foxconn/g41s-k/romstage.c @@ -16,6 +16,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/src/mainboard/google/poppy/variants/nami/mainboard.c b/src/mainboard/google/poppy/variants/nami/mainboard.c index 836c97ea40f..dff62c217cc 100644 --- a/src/mainboard/google/poppy/variants/nami/mainboard.c +++ b/src/mainboard/google/poppy/variants/nami/mainboard.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include diff --git a/src/mainboard/lippert/frontrunner-af/BiosCallOuts.c b/src/mainboard/lippert/frontrunner-af/BiosCallOuts.c index eca687c6e74..9ce9ec768ed 100644 --- a/src/mainboard/lippert/frontrunner-af/BiosCallOuts.c +++ b/src/mainboard/lippert/frontrunner-af/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/lippert/toucan-af/BiosCallOuts.c b/src/mainboard/lippert/toucan-af/BiosCallOuts.c index 48410085353..7e6d0c485e5 100644 --- a/src/mainboard/lippert/toucan-af/BiosCallOuts.c +++ b/src/mainboard/lippert/toucan-af/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/pcengines/apu1/BiosCallOuts.c b/src/mainboard/pcengines/apu1/BiosCallOuts.c index 906ecb648fc..df5f03731b9 100644 --- a/src/mainboard/pcengines/apu1/BiosCallOuts.c +++ b/src/mainboard/pcengines/apu1/BiosCallOuts.c @@ -13,11 +13,13 @@ * GNU General Public License for more details. */ +#include #include #include #include #include #include + #include "gpio_ftns.h" static AGESA_STATUS board_BeforeDramInit (UINT32 Func, UINTN Data, VOID *ConfigPtr); diff --git a/src/mainboard/pcengines/apu2/BiosCallOuts.c b/src/mainboard/pcengines/apu2/BiosCallOuts.c index 535024a86f5..edacb22beee 100644 --- a/src/mainboard/pcengines/apu2/BiosCallOuts.c +++ b/src/mainboard/pcengines/apu2/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/northbridge/amd/agesa/family14/state_machine.c b/src/northbridge/amd/agesa/family14/state_machine.c index d29656cd22e..df55efa7494 100644 --- a/src/northbridge/amd/agesa/family14/state_machine.c +++ b/src/northbridge/amd/agesa/family14/state_machine.c @@ -15,17 +15,16 @@ #include #include - #include #include #include +#include #include #include #include #include #include #include - #include void platform_BeforeInitReset(struct sysinfo *cb, AMD_RESET_PARAMS *Reset) diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index d9563152267..629bc0f5544 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -34,8 +34,10 @@ */ #include +#include #include #include + #include "mct_d.h" static u8 ReconfigureDIMMspare_D(struct MCTStatStruc *pMCTstat, diff --git a/src/northbridge/amd/amdmct/mct/mctdqs_d.c b/src/northbridge/amd/amdmct/mct/mctdqs_d.c index 75fc8a427e1..e2dd56fc1a5 100644 --- a/src/northbridge/amd/amdmct/mct/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct/mctdqs_d.c @@ -13,9 +13,11 @@ * GNU General Public License for more details. */ +#include #include #include #include + #include "mct_d.h" static void CalcEccDQSPos_D(struct MCTStatStruc *pMCTstat, diff --git a/src/northbridge/amd/amdmct/mct/mcttmrl.c b/src/northbridge/amd/amdmct/mct/mcttmrl.c index 192288a2c4a..a78d42df85e 100644 --- a/src/northbridge/amd/amdmct/mct/mcttmrl.c +++ b/src/northbridge/amd/amdmct/mct/mcttmrl.c @@ -13,8 +13,10 @@ * GNU General Public License for more details. */ +#include #include #include + #include "mct_d.h" /* diff --git a/src/northbridge/amd/pi/agesawrapper.c b/src/northbridge/amd/pi/agesawrapper.c index cda5e019803..1563216ba14 100644 --- a/src/northbridge/amd/pi/agesawrapper.c +++ b/src/northbridge/amd/pi/agesawrapper.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/src/northbridge/via/vx900/memmap.c b/src/northbridge/via/vx900/memmap.c index 18d9635379a..0c3b7bfc761 100644 --- a/src/northbridge/via/vx900/memmap.c +++ b/src/northbridge/via/vx900/memmap.c @@ -17,11 +17,12 @@ #define __SIMPLE_DEVICE__ -#include "vx900.h" - #include #include #include +#include + +#include "vx900.h" #define MCU PCI_DEV(0, 0, 3) diff --git a/src/northbridge/via/vx900/pci_util.c b/src/northbridge/via/vx900/pci_util.c index afd35a18e8d..07a9a71f73d 100644 --- a/src/northbridge/via/vx900/pci_util.c +++ b/src/northbridge/via/vx900/pci_util.c @@ -14,6 +14,8 @@ * GNU General Public License for more details. */ +#include + #include "vx900.h" #ifdef __SIMPLE_DEVICE__ diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index 1b9e0fca51b..d65400e43c9 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/amd/common/block/pi/def_callouts.c b/src/soc/amd/common/block/pi/def_callouts.c index 0b119b71d3e..6734b55fde7 100644 --- a/src/soc/amd/common/block/pi/def_callouts.c +++ b/src/soc/amd/common/block/pi/def_callouts.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/amd/common/block/pi/refcode_loader.c b/src/soc/amd/common/block/pi/refcode_loader.c index 47402b670bb..3ffaf36485c 100644 --- a/src/soc/amd/common/block/pi/refcode_loader.c +++ b/src/soc/amd/common/block/pi/refcode_loader.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/amd/stoneyridge/BiosCallOuts.c b/src/soc/amd/stoneyridge/BiosCallOuts.c index 1027ae0294a..c55e73499a2 100644 --- a/src/soc/amd/stoneyridge/BiosCallOuts.c +++ b/src/soc/amd/stoneyridge/BiosCallOuts.c @@ -18,15 +18,16 @@ #include #include #include +#include #include #include #include - #include #include -#include "chip.h" #include +#include "chip.h" + void __weak platform_FchParams_reset(FCH_RESET_DATA_BLOCK *FchParams_reset) {} AGESA_STATUS agesa_fch_initreset(uint32_t Func, uintptr_t FchData, diff --git a/src/soc/amd/stoneyridge/ramtop.c b/src/soc/amd/stoneyridge/ramtop.c index edd5c2394e5..f43fcf37ec4 100644 --- a/src/soc/amd/stoneyridge/ramtop.c +++ b/src/soc/amd/stoneyridge/ramtop.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c index 63b457c2c86..ed73a6e51be 100644 --- a/src/soc/amd/stoneyridge/smbus_spd.c +++ b/src/soc/amd/stoneyridge/smbus_spd.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c index 07cb2adef79..9696a580c0f 100644 --- a/src/soc/intel/apollolake/acpi.c +++ b/src/soc/intel/apollolake/acpi.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include + #include "chip.h" #define CSTATE_RES(address_space, width, offset, address) \ diff --git a/src/soc/intel/apollolake/uart.c b/src/soc/intel/apollolake/uart.c index e8e26612438..1a31e2025d0 100644 --- a/src/soc/intel/apollolake/uart.c +++ b/src/soc/intel/apollolake/uart.c @@ -21,6 +21,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c index 421cafc7184..1b72b24d5ff 100644 --- a/src/soc/intel/cannonlake/uart.c +++ b/src/soc/intel/cannonlake/uart.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/intel/common/block/acpi/acpi.c b/src/soc/intel/common/block/acpi/acpi.c index c872e51578e..3a34c79304f 100644 --- a/src/soc/intel/common/block/acpi/acpi.c +++ b/src/soc/intel/common/block/acpi/acpi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index 342a1203e45..0a59c56f1f3 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 0065a6c54fa..47e2817a47b 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -13,7 +13,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include +#include #include #include #include diff --git a/src/soc/intel/denverton_ns/acpi.c b/src/soc/intel/denverton_ns/acpi.c index f3e91ff451d..e969a044a12 100644 --- a/src/soc/intel/denverton_ns/acpi.c +++ b/src/soc/intel/denverton_ns/acpi.c @@ -26,7 +26,7 @@ #include #include #include - +#include #include #include #include diff --git a/src/soc/intel/denverton_ns/include/soc/hob_mem.h b/src/soc/intel/denverton_ns/include/soc/hob_mem.h index d98295b6f29..44d73fa428f 100644 --- a/src/soc/intel/denverton_ns/include/soc/hob_mem.h +++ b/src/soc/intel/denverton_ns/include/soc/hob_mem.h @@ -19,6 +19,7 @@ #ifndef _DENVERTON_NS_HOB_MEM_H #define _DENVERTON_NS_HOB_MEM_H +#include #include void soc_display_fsp_smbios_memory_info_hob( diff --git a/src/soc/intel/fsp_baytrail/i2c.c b/src/soc/intel/fsp_baytrail/i2c.c index 68f56261d3a..3ea91e3b5e5 100644 --- a/src/soc/intel/fsp_baytrail/i2c.c +++ b/src/soc/intel/fsp_baytrail/i2c.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/intel/icelake/uart.c b/src/soc/intel/icelake/uart.c index 421cafc7184..1b72b24d5ff 100644 --- a/src/soc/intel/icelake/uart.c +++ b/src/soc/intel/icelake/uart.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/intel/quark/acpi.c b/src/soc/intel/quark/acpi.c index 83bed34347d..2cb5adf4f29 100644 --- a/src/soc/intel/quark/acpi.c +++ b/src/soc/intel/quark/acpi.c @@ -15,6 +15,7 @@ * GNU General Public License for more details. */ +#include #include #include diff --git a/src/soc/mediatek/common/spi.c b/src/soc/mediatek/common/spi.c index 3e7186ae8e3..71ed95a228e 100644 --- a/src/soc/mediatek/common/spi.c +++ b/src/soc/mediatek/common/spi.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c index 529ebde3f1a..01a32e3cb4a 100644 --- a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/mediatek/mt8173/i2c.c b/src/soc/mediatek/mt8173/i2c.c index 2d998947bbf..3395539bf1f 100644 --- a/src/soc/mediatek/mt8173/i2c.c +++ b/src/soc/mediatek/mt8173/i2c.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/soc/mediatek/mt8173/pmic_wrap.c b/src/soc/mediatek/mt8173/pmic_wrap.c index 469653a26c7..6acaee2bee0 100644 --- a/src/soc/mediatek/mt8173/pmic_wrap.c +++ b/src/soc/mediatek/mt8173/pmic_wrap.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/mediatek/mt8183/mt6358.c b/src/soc/mediatek/mt8183/mt6358.c index 3dc9fe23b42..d338e1682da 100644 --- a/src/soc/mediatek/mt8183/mt6358.c +++ b/src/soc/mediatek/mt8183/mt6358.c @@ -14,6 +14,7 @@ */ #include +#include #include #include diff --git a/src/soc/nvidia/tegra210/funitcfg.c b/src/soc/nvidia/tegra210/funitcfg.c index a218862f3ef..887f9f08014 100644 --- a/src/soc/nvidia/tegra210/funitcfg.c +++ b/src/soc/nvidia/tegra210/funitcfg.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/src/soc/nvidia/tegra210/ramstage.c b/src/soc/nvidia/tegra210/ramstage.c index 54f42047020..13fa1c6a024 100644 --- a/src/soc/nvidia/tegra210/ramstage.c +++ b/src/soc/nvidia/tegra210/ramstage.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/rockchip/rk3288/crypto.c b/src/soc/rockchip/rk3288/crypto.c index 90275ff94e9..c429258e100 100644 --- a/src/soc/rockchip/rk3288/crypto.c +++ b/src/soc/rockchip/rk3288/crypto.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/southbridge/amd/agesa/hudson/resume.c b/src/southbridge/amd/agesa/hudson/resume.c index 8a07565c9a4..efc35bd8d17 100644 --- a/src/southbridge/amd/agesa/hudson/resume.c +++ b/src/southbridge/amd/agesa/hudson/resume.c @@ -18,7 +18,7 @@ #include #include "hudson.h" #include - +#include #include extern FCH_DATA_BLOCK InitEnvCfgDefault; diff --git a/src/southbridge/amd/agesa/hudson/smbus_spd.c b/src/southbridge/amd/agesa/hudson/smbus_spd.c index cb2fbe727d5..8eb36f46ee6 100644 --- a/src/southbridge/amd/agesa/hudson/smbus_spd.c +++ b/src/southbridge/amd/agesa/hudson/smbus_spd.c @@ -15,12 +15,11 @@ #include #include - +#include /* warning: Porting.h includes an open #pragma pack(1) */ #include #include #include - #include /*----------------------------------------------------------------------------- diff --git a/src/southbridge/amd/cimx/sb900/cfg.c b/src/southbridge/amd/cimx/sb900/cfg.c index bc7e742b285..353d5771e0d 100644 --- a/src/southbridge/amd/cimx/sb900/cfg.c +++ b/src/southbridge/amd/cimx/sb900/cfg.c @@ -13,12 +13,12 @@ * GNU General Public License for more details. */ - +#include #include + #include "SbPlatform.h" #include "platform_cfg.h" - /** * @brief South Bridge CIMx configuration * diff --git a/src/southbridge/amd/pi/hudson/smbus_spd.c b/src/southbridge/amd/pi/hudson/smbus_spd.c index 8d67b1e6784..c49ccffc4db 100644 --- a/src/southbridge/amd/pi/hudson/smbus_spd.c +++ b/src/southbridge/amd/pi/hudson/smbus_spd.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include #include #include @@ -20,7 +21,6 @@ #include #include #include - #include /*----------------------------------------------------------------------------- diff --git a/src/southbridge/broadcom/bcm5785/early_smbus.c b/src/southbridge/broadcom/bcm5785/early_smbus.c index bcbfb129905..5aa6ee2ad18 100644 --- a/src/southbridge/broadcom/bcm5785/early_smbus.c +++ b/src/southbridge/broadcom/bcm5785/early_smbus.c @@ -15,7 +15,9 @@ */ #include +#include #include + #include "smbus.h" #define SMBUS_IO_BASE 0x1000 From 351e3e520ba71b4aafaf930af37f78b71c1d7251 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 5 Apr 2019 18:11:19 +0200 Subject: [PATCH 027/588] src: Use include when appropriate Change-Id: Iddba5b03fc554a6edc4b26458d834e47958a6b08 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32214 Tested-by: build bot (Jenkins) Reviewed-by: Werner Zeh Reviewed-by: David Guckian --- src/arch/riscv/sbi.c | 1 - src/device/oprom/include/x86emu/x86emu.h | 1 - src/drivers/amd/agesa/state_machine.c | 4 +--- src/drivers/generic/gpio_keys/gpio_keys.c | 1 - src/drivers/generic/gpio_regulator/gpio_regulator.c | 1 - src/drivers/intel/fsp1_0/fsp_util.h | 2 ++ src/drivers/intel/gma/int15.c | 2 ++ src/include/device/azalia_device.h | 2 -- src/lib/cbfs.c | 1 + src/lib/cbmem_console.c | 1 - src/lib/fit.c | 1 + src/mainboard/amd/db-ft3b-lc/BiosCallOuts.c | 1 + src/mainboard/amd/lamar/BiosCallOuts.c | 1 + src/mainboard/amd/olivehillplus/BiosCallOuts.c | 1 + src/mainboard/amd/thatcher/romstage.c | 2 +- src/mainboard/asus/am1i-a/BiosCallOuts.c | 1 + src/mainboard/asus/f2a85-m/romstage.c | 3 +-- src/mainboard/asus/m4a785-m/acpi_tables.c | 1 - src/mainboard/cubietech/cubieboard/bootblock.c | 1 - src/mainboard/google/beltino/smihandler.c | 2 +- src/mainboard/google/daisy/chromeos.c | 1 - src/mainboard/google/dragonegg/romstage_fsp_params.c | 1 - src/mainboard/google/foster/chromeos.c | 1 - src/mainboard/google/gru/bootblock.c | 1 - src/mainboard/google/octopus/variants/phaser/gpio.c | 1 - src/mainboard/google/peach_pit/chromeos.c | 1 - src/mainboard/google/poppy/variants/nami/smihandler.c | 2 +- src/mainboard/google/urara/bootblock.c | 1 + src/mainboard/intel/baskingridge/mainboard_smi.c | 1 - src/mainboard/intel/cannonlake_rvp/spd/spd_util.c | 3 ++- src/mainboard/intel/icelake_rvp/romstage_fsp_params.c | 4 ++-- src/mainboard/intel/icelake_rvp/spd/spd_util.c | 3 ++- src/mainboard/intel/kblrvp/spd/spd_util.c | 3 ++- src/mainboard/kontron/986lcd-m/mptable.c | 1 - src/mainboard/roda/rk886ex/mptable.c | 1 - src/mainboard/sifive/hifive-unleashed/mainboard.c | 2 +- src/northbridge/amd/amdht/h3ncmn.h | 2 +- src/northbridge/amd/amdmct/mct/mct_d.h | 4 ++-- src/northbridge/amd/amdmct/mct/mctsrc.c | 2 ++ src/northbridge/via/vx900/vx900.h | 1 - src/soc/intel/apollolake/memmap.c | 4 +++- src/soc/intel/fsp_baytrail/include/soc/i2c.h | 1 - src/soc/intel/icelake/bootblock/pch.c | 1 - src/soc/intel/icelake/chip.c | 1 - src/soc/intel/icelake/lpc.c | 1 - src/soc/intel/icelake/systemagent.c | 1 - src/soc/mediatek/mt8183/auxadc.c | 1 - src/soc/qualcomm/ipq806x/uart.c | 1 - src/soc/qualcomm/qcs405/clock.c | 2 -- src/soc/qualcomm/qcs405/gpio.c | 2 -- src/soc/qualcomm/sdm845/clock.c | 1 - src/southbridge/amd/amd8111/early_smbus.c | 2 ++ src/southbridge/amd/cimx/sb800/SBPLATFORM.h | 1 - src/southbridge/amd/cimx/sb900/SbPlatform.h | 1 - src/southbridge/amd/sb800/early_setup.c | 2 ++ src/southbridge/nvidia/ck804/early_setup_car.c | 1 + src/southbridge/nvidia/mcp55/early_setup_car.c | 1 + 57 files changed, 39 insertions(+), 51 deletions(-) diff --git a/src/arch/riscv/sbi.c b/src/arch/riscv/sbi.c index a5f3fd40654..e0d7c60e5f6 100644 --- a/src/arch/riscv/sbi.c +++ b/src/arch/riscv/sbi.c @@ -20,7 +20,6 @@ #include #include #include -#include #include static uintptr_t send_ipi(uintptr_t *pmask, intptr_t type) diff --git a/src/device/oprom/include/x86emu/x86emu.h b/src/device/oprom/include/x86emu/x86emu.h index fa23e55cd30..4ae82d96ff5 100644 --- a/src/device/oprom/include/x86emu/x86emu.h +++ b/src/device/oprom/include/x86emu/x86emu.h @@ -42,7 +42,6 @@ #define __X86EMU_X86EMU_H #include -#include #if CONFIG(X86EMU_DEBUG) #define DEBUG #endif diff --git a/src/drivers/amd/agesa/state_machine.c b/src/drivers/amd/agesa/state_machine.c index c6e36b22595..dfd64c3d522 100644 --- a/src/drivers/amd/agesa/state_machine.c +++ b/src/drivers/amd/agesa/state_machine.c @@ -16,17 +16,15 @@ #include #include - #include #include #include #include - +#include #include #include #include #include - #include #if CONFIG(CPU_AMD_AGESA_OPENSOURCE) diff --git a/src/drivers/generic/gpio_keys/gpio_keys.c b/src/drivers/generic/gpio_keys/gpio_keys.c index 6e18a8a1b09..2cf8f28e0b0 100644 --- a/src/drivers/generic/gpio_keys/gpio_keys.c +++ b/src/drivers/generic/gpio_keys/gpio_keys.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/drivers/generic/gpio_regulator/gpio_regulator.c b/src/drivers/generic/gpio_regulator/gpio_regulator.c index 3b335252bbe..3b7718c6f0a 100644 --- a/src/drivers/generic/gpio_regulator/gpio_regulator.c +++ b/src/drivers/generic/gpio_regulator/gpio_regulator.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/drivers/intel/fsp1_0/fsp_util.h b/src/drivers/intel/fsp1_0/fsp_util.h index e0da19e8ac0..e09bbd9b655 100644 --- a/src/drivers/intel/fsp1_0/fsp_util.h +++ b/src/drivers/intel/fsp1_0/fsp_util.h @@ -17,6 +17,8 @@ #define FSP_UTIL_H #include +#include + #include "fsp_values.h" #if CONFIG(ENABLE_MRC_CACHE) diff --git a/src/drivers/intel/gma/int15.c b/src/drivers/intel/gma/int15.c index 5caa1b38d8a..80949d1bf8a 100644 --- a/src/drivers/intel/gma/int15.c +++ b/src/drivers/intel/gma/int15.c @@ -16,6 +16,8 @@ #include #include +#include + #include "int15.h" static int active_lfp, pfit, display, panel_type; diff --git a/src/include/device/azalia_device.h b/src/include/device/azalia_device.h index 9ff332e964b..343e261d060 100644 --- a/src/include/device/azalia_device.h +++ b/src/include/device/azalia_device.h @@ -17,11 +17,9 @@ #define DEVICE_AZALIA_H #include -#include #include #include #include - #include void azalia_audio_init(struct device *dev); diff --git a/src/lib/cbfs.c b/src/lib/cbfs.c index 728674f0da7..91368fb67df 100644 --- a/src/lib/cbfs.c +++ b/src/lib/cbfs.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include diff --git a/src/lib/cbmem_console.c b/src/lib/cbmem_console.c index faa937b3813..df2d1ffa96a 100644 --- a/src/lib/cbmem_console.c +++ b/src/lib/cbmem_console.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/lib/fit.c b/src/lib/fit.c index 4e2b75c1a47..a8bca47bdc6 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/amd/db-ft3b-lc/BiosCallOuts.c b/src/mainboard/amd/db-ft3b-lc/BiosCallOuts.c index af5d34e6130..056daa248bd 100644 --- a/src/mainboard/amd/db-ft3b-lc/BiosCallOuts.c +++ b/src/mainboard/amd/db-ft3b-lc/BiosCallOuts.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/amd/lamar/BiosCallOuts.c b/src/mainboard/amd/lamar/BiosCallOuts.c index 8891abb57db..8e49e8e966d 100644 --- a/src/mainboard/amd/lamar/BiosCallOuts.c +++ b/src/mainboard/amd/lamar/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/amd/olivehillplus/BiosCallOuts.c b/src/mainboard/amd/olivehillplus/BiosCallOuts.c index e3107b18a5f..8975dc8e5d7 100644 --- a/src/mainboard/amd/olivehillplus/BiosCallOuts.c +++ b/src/mainboard/amd/olivehillplus/BiosCallOuts.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include diff --git a/src/mainboard/amd/thatcher/romstage.c b/src/mainboard/amd/thatcher/romstage.c index 65ed138c8d0..1d89e4d6d16 100644 --- a/src/mainboard/amd/thatcher/romstage.c +++ b/src/mainboard/amd/thatcher/romstage.c @@ -16,10 +16,10 @@ #include #include #include +#include #include #include #include - #include #define SERIAL_DEV PNP_DEV(0x2e, LPC47N217_SP1) diff --git a/src/mainboard/asus/am1i-a/BiosCallOuts.c b/src/mainboard/asus/am1i-a/BiosCallOuts.c index a1018b3e5f6..ce547419d26 100644 --- a/src/mainboard/asus/am1i-a/BiosCallOuts.c +++ b/src/mainboard/asus/am1i-a/BiosCallOuts.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include diff --git a/src/mainboard/asus/f2a85-m/romstage.c b/src/mainboard/asus/f2a85-m/romstage.c index 2727904641e..d5acdb55e30 100644 --- a/src/mainboard/asus/f2a85-m/romstage.c +++ b/src/mainboard/asus/f2a85-m/romstage.c @@ -15,15 +15,14 @@ */ #include +#include #include #include - #include #include #include #include #include - #include #include #include diff --git a/src/mainboard/asus/m4a785-m/acpi_tables.c b/src/mainboard/asus/m4a785-m/acpi_tables.c index 1170ed7a497..cb263f90f24 100644 --- a/src/mainboard/asus/m4a785-m/acpi_tables.c +++ b/src/mainboard/asus/m4a785-m/acpi_tables.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/mainboard/cubietech/cubieboard/bootblock.c b/src/mainboard/cubietech/cubieboard/bootblock.c index e1eb8206e7b..05e3847d396 100644 --- a/src/mainboard/cubietech/cubieboard/bootblock.c +++ b/src/mainboard/cubietech/cubieboard/bootblock.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/google/beltino/smihandler.c b/src/mainboard/google/beltino/smihandler.c index 1a03f2340bb..e786ef56fd0 100644 --- a/src/mainboard/google/beltino/smihandler.c +++ b/src/mainboard/google/beltino/smihandler.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -24,6 +23,7 @@ #include #include #include + #include "onboard.h" void mainboard_smi_sleep(u8 slp_typ) diff --git a/src/mainboard/google/daisy/chromeos.c b/src/mainboard/google/daisy/chromeos.c index c06f8394eb0..968f1f9d5b0 100644 --- a/src/mainboard/google/daisy/chromeos.c +++ b/src/mainboard/google/daisy/chromeos.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/mainboard/google/dragonegg/romstage_fsp_params.c b/src/mainboard/google/dragonegg/romstage_fsp_params.c index e866c620d9a..e357ee78c05 100644 --- a/src/mainboard/google/dragonegg/romstage_fsp_params.c +++ b/src/mainboard/google/dragonegg/romstage_fsp_params.c @@ -15,7 +15,6 @@ #include #include -#include #include void mainboard_memory_init_params(FSPM_UPD *mupd) diff --git a/src/mainboard/google/foster/chromeos.c b/src/mainboard/google/foster/chromeos.c index 026dd3e5dd1..591cfd00258 100644 --- a/src/mainboard/google/foster/chromeos.c +++ b/src/mainboard/google/foster/chromeos.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/src/mainboard/google/gru/bootblock.c b/src/mainboard/google/gru/bootblock.c index 7c18e12fd12..79d9b0f6404 100644 --- a/src/mainboard/google/gru/bootblock.c +++ b/src/mainboard/google/gru/bootblock.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/google/octopus/variants/phaser/gpio.c b/src/mainboard/google/octopus/variants/phaser/gpio.c index 076476bbdd6..281bde06a48 100644 --- a/src/mainboard/google/octopus/variants/phaser/gpio.c +++ b/src/mainboard/google/octopus/variants/phaser/gpio.c @@ -19,7 +19,6 @@ #include #include #include -#include #define SKU_UNKNOWN 0xFFFFFFFF diff --git a/src/mainboard/google/peach_pit/chromeos.c b/src/mainboard/google/peach_pit/chromeos.c index 00dd1f39872..b2d90d9e903 100644 --- a/src/mainboard/google/peach_pit/chromeos.c +++ b/src/mainboard/google/peach_pit/chromeos.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/google/poppy/variants/nami/smihandler.c b/src/mainboard/google/poppy/variants/nami/smihandler.c index 6816508f24e..61162b40b1a 100644 --- a/src/mainboard/google/poppy/variants/nami/smihandler.c +++ b/src/mainboard/google/poppy/variants/nami/smihandler.c @@ -15,8 +15,8 @@ #include #include -#include #include + #include "gpio.h" #define TOUCH_DISABLE GPP_C3 diff --git a/src/mainboard/google/urara/bootblock.c b/src/mainboard/google/urara/bootblock.c index 5b0b29d0f76..16e75809d39 100644 --- a/src/mainboard/google/urara/bootblock.c +++ b/src/mainboard/google/urara/bootblock.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include diff --git a/src/mainboard/intel/baskingridge/mainboard_smi.c b/src/mainboard/intel/baskingridge/mainboard_smi.c index 0fd0639b562..da6f8e81990 100644 --- a/src/mainboard/intel/baskingridge/mainboard_smi.c +++ b/src/mainboard/intel/baskingridge/mainboard_smi.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/intel/cannonlake_rvp/spd/spd_util.c b/src/mainboard/intel/cannonlake_rvp/spd/spd_util.c index 5ceff51f446..dd209dce557 100644 --- a/src/mainboard/intel/cannonlake_rvp/spd/spd_util.c +++ b/src/mainboard/intel/cannonlake_rvp/spd/spd_util.c @@ -12,10 +12,11 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include -#include #include #include + #include "spd.h" void mainboard_fill_dq_map_ch0(void *dq_map_ptr) diff --git a/src/mainboard/intel/icelake_rvp/romstage_fsp_params.c b/src/mainboard/intel/icelake_rvp/romstage_fsp_params.c index dd33021ae5f..b9ce3941f49 100644 --- a/src/mainboard/intel/icelake_rvp/romstage_fsp_params.c +++ b/src/mainboard/intel/icelake_rvp/romstage_fsp_params.c @@ -14,12 +14,12 @@ */ #include -#include #include #include -#include "spd/spd.h" #include +#include "spd/spd.h" + void mainboard_memory_init_params(FSPM_UPD *mupd) { } diff --git a/src/mainboard/intel/icelake_rvp/spd/spd_util.c b/src/mainboard/intel/icelake_rvp/spd/spd_util.c index 6b733642cdc..8d7eaf69cee 100644 --- a/src/mainboard/intel/icelake_rvp/spd/spd_util.c +++ b/src/mainboard/intel/icelake_rvp/spd/spd_util.c @@ -12,12 +12,13 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include #include -#include #include #include #include + #include "../board_id.h" #include "spd.h" diff --git a/src/mainboard/intel/kblrvp/spd/spd_util.c b/src/mainboard/intel/kblrvp/spd/spd_util.c index 12d9d10b361..10043843a22 100644 --- a/src/mainboard/intel/kblrvp/spd/spd_util.c +++ b/src/mainboard/intel/kblrvp/spd/spd_util.c @@ -12,12 +12,13 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + #include -#include #include #include #include #include + #include "../board_id.h" #include "spd.h" diff --git a/src/mainboard/kontron/986lcd-m/mptable.c b/src/mainboard/kontron/986lcd-m/mptable.c index 2edb7daf0ed..1b5d45efb33 100644 --- a/src/mainboard/kontron/986lcd-m/mptable.c +++ b/src/mainboard/kontron/986lcd-m/mptable.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/roda/rk886ex/mptable.c b/src/mainboard/roda/rk886ex/mptable.c index cf87d7fa953..2db0f759643 100644 --- a/src/mainboard/roda/rk886ex/mptable.c +++ b/src/mainboard/roda/rk886ex/mptable.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/sifive/hifive-unleashed/mainboard.c b/src/mainboard/sifive/hifive-unleashed/mainboard.c index 2d62cd077aa..96a2678ee0b 100644 --- a/src/mainboard/sifive/hifive-unleashed/mainboard.c +++ b/src/mainboard/sifive/hifive-unleashed/mainboard.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include diff --git a/src/northbridge/amd/amdht/h3ncmn.h b/src/northbridge/amd/amdht/h3ncmn.h index f4a782d63bc..c007089e03e 100644 --- a/src/northbridge/amd/amdht/h3ncmn.h +++ b/src/northbridge/amd/amdht/h3ncmn.h @@ -19,8 +19,8 @@ #include #include -#include #include + #include "comlib.h" #include "h3finit.h" #include "h3ffeat.h" diff --git a/src/northbridge/amd/amdmct/mct/mct_d.h b/src/northbridge/amd/amdmct/mct/mct_d.h index 5d31d444280..14da928719b 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.h +++ b/src/northbridge/amd/amdmct/mct/mct_d.h @@ -23,11 +23,11 @@ #define DQS_TRAIN_DEBUG 0 #include -#include "mct_d_gcc.h" -#include #include #include +#include "mct_d_gcc.h" + extern const u8 Table_DQSRcvEn_Offset[]; extern const u32 TestPattern0_D[]; extern const u32 TestPattern1_D[]; diff --git a/src/northbridge/amd/amdmct/mct/mctsrc.c b/src/northbridge/amd/amdmct/mct/mctsrc.c index 4689c7b982f..649c1c85c24 100644 --- a/src/northbridge/amd/amdmct/mct/mctsrc.c +++ b/src/northbridge/amd/amdmct/mct/mctsrc.c @@ -14,8 +14,10 @@ * GNU General Public License for more details. */ +#include #include #include + #include "mct_d.h" /****************************************************************************** diff --git a/src/northbridge/via/vx900/vx900.h b/src/northbridge/via/vx900/vx900.h index 9e306388925..96d821ac4d6 100644 --- a/src/northbridge/via/vx900/vx900.h +++ b/src/northbridge/via/vx900/vx900.h @@ -28,7 +28,6 @@ #include #include -#include u32 vx900_get_tolm(void); void vx900_set_chrome9hd_fb_size(u32 size_mb); diff --git a/src/soc/intel/apollolake/memmap.c b/src/soc/intel/apollolake/memmap.c index ba1433c53b7..4f91b8aea52 100644 --- a/src/soc/intel/apollolake/memmap.c +++ b/src/soc/intel/apollolake/memmap.c @@ -17,13 +17,15 @@ #include #include -#include "chip.h" +#include #include #include #include #include #include +#include "chip.h" + void *cbmem_top(void) { const struct device *dev; diff --git a/src/soc/intel/fsp_baytrail/include/soc/i2c.h b/src/soc/intel/fsp_baytrail/include/soc/i2c.h index 7b3a3c89186..f0ae0b37ad3 100644 --- a/src/soc/intel/fsp_baytrail/include/soc/i2c.h +++ b/src/soc/intel/fsp_baytrail/include/soc/i2c.h @@ -16,7 +16,6 @@ #ifndef __SOC_INTEL_FSP_BAYTRAIL_I2C_H__ #define __SOC_INTEL_FSP_BAYTRAIL_I2C_H__ -#include #include #include diff --git a/src/soc/intel/icelake/bootblock/pch.c b/src/soc/intel/icelake/bootblock/pch.c index 2d35f5bf39c..094079140d0 100644 --- a/src/soc/intel/icelake/bootblock/pch.c +++ b/src/soc/intel/icelake/bootblock/pch.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c index 0e4388efd62..464c25e509b 100644 --- a/src/soc/intel/icelake/chip.c +++ b/src/soc/intel/icelake/chip.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/intel/icelake/lpc.c b/src/soc/intel/icelake/lpc.c index 8fe05072554..3d058242798 100644 --- a/src/soc/intel/icelake/lpc.c +++ b/src/soc/intel/icelake/lpc.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/icelake/systemagent.c b/src/soc/intel/icelake/systemagent.c index 7903667e9e2..930e78ed5e8 100644 --- a/src/soc/intel/icelake/systemagent.c +++ b/src/soc/intel/icelake/systemagent.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/mediatek/mt8183/auxadc.c b/src/soc/mediatek/mt8183/auxadc.c index caf9a0346a4..a167d2b58e1 100644 --- a/src/soc/mediatek/mt8183/auxadc.c +++ b/src/soc/mediatek/mt8183/auxadc.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/soc/qualcomm/ipq806x/uart.c b/src/soc/qualcomm/ipq806x/uart.c index fe2d673d47b..66c31034fa7 100644 --- a/src/soc/qualcomm/ipq806x/uart.c +++ b/src/soc/qualcomm/ipq806x/uart.c @@ -33,7 +33,6 @@ #include #include -#include #include #include #include diff --git a/src/soc/qualcomm/qcs405/clock.c b/src/soc/qualcomm/qcs405/clock.c index cd7c1f2f417..369bcdf531f 100644 --- a/src/soc/qualcomm/qcs405/clock.c +++ b/src/soc/qualcomm/qcs405/clock.c @@ -14,12 +14,10 @@ #include #include -#include #include #include #include #include - #include #define DIV(div) (div ? (2*div - 1) : 0) diff --git a/src/soc/qualcomm/qcs405/gpio.c b/src/soc/qualcomm/qcs405/gpio.c index 5904cb3dc5b..18aacf4ce4d 100644 --- a/src/soc/qualcomm/qcs405/gpio.c +++ b/src/soc/qualcomm/qcs405/gpio.c @@ -15,10 +15,8 @@ #include #include -#include #include #include - #include void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, diff --git a/src/soc/qualcomm/sdm845/clock.c b/src/soc/qualcomm/sdm845/clock.c index 382e5a691e5..addac5ef404 100644 --- a/src/soc/qualcomm/sdm845/clock.c +++ b/src/soc/qualcomm/sdm845/clock.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/southbridge/amd/amd8111/early_smbus.c b/src/southbridge/amd/amd8111/early_smbus.c index 2e6781ae003..cabb31b52b4 100644 --- a/src/southbridge/amd/amd8111/early_smbus.c +++ b/src/southbridge/amd/amd8111/early_smbus.c @@ -12,7 +12,9 @@ */ #include +#include #include + #include "amd8111_smbus.h" #define SMBUS_IO_BASE 0x0f00 diff --git a/src/southbridge/amd/cimx/sb800/SBPLATFORM.h b/src/southbridge/amd/cimx/sb800/SBPLATFORM.h index 04b8abcc675..7ea2caa83bd 100644 --- a/src/southbridge/amd/cimx/sb800/SBPLATFORM.h +++ b/src/southbridge/amd/cimx/sb800/SBPLATFORM.h @@ -53,7 +53,6 @@ typedef union _PCI_ADDR { #define IMC_ENABLE_OVER_WRITE 0x01 #endif -#include #include "AmdSbLib.h" #include "Amd.h" #include diff --git a/src/southbridge/amd/cimx/sb900/SbPlatform.h b/src/southbridge/amd/cimx/sb900/SbPlatform.h index 660553fbd8e..f5c11d4ce09 100644 --- a/src/southbridge/amd/cimx/sb900/SbPlatform.h +++ b/src/southbridge/amd/cimx/sb900/SbPlatform.h @@ -49,7 +49,6 @@ typedef union _PCI_ADDR { #endif #define FIXUP_PTR(ptr) ptr -#include #include "AmdSbLib.h" #include "Amd.h" #include "Hudson-2.h" diff --git a/src/southbridge/amd/sb800/early_setup.c b/src/southbridge/amd/sb800/early_setup.c index 6a575e316c1..eaa47e3c2c4 100644 --- a/src/southbridge/amd/sb800/early_setup.c +++ b/src/southbridge/amd/sb800/early_setup.c @@ -17,9 +17,11 @@ #define _SB800_EARLY_SETUP_C_ #include +#include #include #include #include + #include "sb800.h" #include "smbus.c" diff --git a/src/southbridge/nvidia/ck804/early_setup_car.c b/src/southbridge/nvidia/ck804/early_setup_car.c index 1e357df85aa..156c38745ba 100644 --- a/src/southbridge/nvidia/ck804/early_setup_car.c +++ b/src/southbridge/nvidia/ck804/early_setup_car.c @@ -17,6 +17,7 @@ */ #include +#include #include #include diff --git a/src/southbridge/nvidia/mcp55/early_setup_car.c b/src/southbridge/nvidia/mcp55/early_setup_car.c index 09414af3dec..908cdd595f8 100644 --- a/src/southbridge/nvidia/mcp55/early_setup_car.c +++ b/src/southbridge/nvidia/mcp55/early_setup_car.c @@ -17,6 +17,7 @@ #include #include +#include #ifdef UNUSED_CODE int set_ht_link_buffer_counts_chain(u8 ht_c_num, unsigned vendorid, unsigned val); From cd4fe0f718cfc49e5d58f1770e23cd065a26241e Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 29 Mar 2019 17:12:15 +0100 Subject: [PATCH 028/588] src: include when appropriate Change-Id: Ib843eb7144b7dc2932931b9e8f3f1d816bcc1e1a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/26796 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer Reviewed-by: David Guckian --- src/arch/arm64/arm_tf.c | 1 - src/arch/x86/acpigen.c | 1 + src/arch/x86/include/arch/acpigen.h | 1 - src/commonlib/storage/pci_sdhci.c | 1 - src/commonlib/storage/sd.c | 1 - src/commonlib/storage/sd_mmc.c | 1 - src/commonlib/storage/sdhci.c | 1 - src/commonlib/storage/sdhci_adma.c | 1 - src/commonlib/storage/storage.c | 1 - src/cpu/intel/hyperthreading/intel_sibling.c | 1 - src/cpu/intel/model_206ax/model_206ax_init.c | 1 - src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c | 1 - src/drivers/spi/winbond.c | 1 - src/lib/gpio.c | 1 - src/mainboard/google/dragonegg/romstage_fsp_params.c | 1 - src/mainboard/intel/galileo/vboot.c | 1 - src/northbridge/amd/pi/00630F01/northbridge.c | 1 - src/security/vboot/vbnv_flash.c | 1 - src/soc/cavium/cn81xx/ecam0.c | 1 - src/soc/cavium/cn81xx/twsi.c | 1 - src/soc/cavium/common/ecam.c | 1 - src/soc/intel/apollolake/acpi.c | 1 + src/soc/intel/apollolake/gpio_apl.c | 1 - src/soc/intel/apollolake/gpio_glk.c | 1 - src/soc/intel/apollolake/uart.c | 1 - src/soc/intel/cannonlake/romstage/romstage.c | 1 - src/soc/intel/cannonlake/uart.c | 1 - src/soc/intel/common/block/sgx/sgx.c | 1 - src/soc/intel/common/block/uart/uart.c | 1 - src/soc/intel/denverton_ns/gpio.c | 1 - src/soc/intel/icelake/romstage/romstage.c | 1 - src/soc/intel/icelake/uart.c | 1 - src/soc/intel/quark/spi.c | 1 - src/soc/intel/skylake/cpu.c | 1 - src/soc/intel/skylake/gpio.c | 1 - src/soc/mediatek/common/include/soc/rtc_common.h | 1 - src/soc/mediatek/common/pmic_wrap.c | 1 - src/soc/mediatek/mt8173/dramc_pi_calibration_api.c | 1 - src/soc/mediatek/mt8173/emi.c | 1 - src/soc/mediatek/mt8173/pmic_wrap.c | 1 - src/soc/mediatek/mt8183/mt6358.c | 1 - src/soc/qualcomm/ipq40xx/i2c.c | 1 - src/soc/qualcomm/ipq806x/i2c.c | 1 - src/soc/rockchip/common/edp.c | 1 - src/soc/rockchip/common/pwm.c | 1 - src/soc/rockchip/rk3288/hdmi.c | 1 - src/soc/rockchip/rk3288/tsadc.c | 1 - src/soc/rockchip/rk3399/bl31_plat_params.c | 1 - src/soc/rockchip/rk3399/mipi.c | 1 - src/soc/rockchip/rk3399/tsadc.c | 1 - src/soc/samsung/exynos5250/alternate_cbfs.c | 1 - src/soc/samsung/exynos5250/pinmux.c | 1 - src/soc/samsung/exynos5420/alternate_cbfs.c | 1 - src/soc/samsung/exynos5420/pinmux.c | 1 - src/superio/renesas/m3885x/superio.c | 1 - src/superio/smsc/lpc47n227/early_serial.c | 2 ++ 56 files changed, 4 insertions(+), 53 deletions(-) diff --git a/src/arch/arm64/arm_tf.c b/src/arch/arm64/arm_tf.c index f43bc028d27..291e4eef3ee 100644 --- a/src/arch/arm64/arm_tf.c +++ b/src/arch/arm64/arm_tf.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/arch/x86/acpigen.c b/src/arch/x86/acpigen.c index 3f9f99422d6..e283f4da31a 100644 --- a/src/arch/x86/acpigen.c +++ b/src/arch/x86/acpigen.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/src/arch/x86/include/arch/acpigen.h b/src/arch/x86/include/arch/acpigen.h index 9e5769304b8..6114667c6c7 100644 --- a/src/arch/x86/include/arch/acpigen.h +++ b/src/arch/x86/include/arch/acpigen.h @@ -18,7 +18,6 @@ #ifndef LIBACPI_H #define LIBACPI_H -#include #include #include #include diff --git a/src/commonlib/storage/pci_sdhci.c b/src/commonlib/storage/pci_sdhci.c index a2d30949b35..1798c2cac7e 100644 --- a/src/commonlib/storage/pci_sdhci.c +++ b/src/commonlib/storage/pci_sdhci.c @@ -18,7 +18,6 @@ #endif #include -#include #include #include #include diff --git a/src/commonlib/storage/sd.c b/src/commonlib/storage/sd.c index 2e1ae85f06e..06f0156c82e 100644 --- a/src/commonlib/storage/sd.c +++ b/src/commonlib/storage/sd.c @@ -19,7 +19,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/commonlib/storage/sd_mmc.c b/src/commonlib/storage/sd_mmc.c index fd59bd0b6fc..348d3fe17d7 100644 --- a/src/commonlib/storage/sd_mmc.c +++ b/src/commonlib/storage/sd_mmc.c @@ -20,7 +20,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/commonlib/storage/sdhci.c b/src/commonlib/storage/sdhci.c index 5c85e99655d..19daa2ee7eb 100644 --- a/src/commonlib/storage/sdhci.c +++ b/src/commonlib/storage/sdhci.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include "bouncebuf.h" #include #include diff --git a/src/commonlib/storage/sdhci_adma.c b/src/commonlib/storage/sdhci_adma.c index bf6f457a466..e3209734bab 100644 --- a/src/commonlib/storage/sdhci_adma.c +++ b/src/commonlib/storage/sdhci_adma.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/commonlib/storage/storage.c b/src/commonlib/storage/storage.c index d8ff4bc729d..f434a6c0b69 100644 --- a/src/commonlib/storage/storage.c +++ b/src/commonlib/storage/storage.c @@ -21,7 +21,6 @@ * GNU General Public License for more details. */ -#include #include #include "sd_mmc.h" #include "storage.h" diff --git a/src/cpu/intel/hyperthreading/intel_sibling.c b/src/cpu/intel/hyperthreading/intel_sibling.c index e634f85fc33..3c3e53a8391 100644 --- a/src/cpu/intel/hyperthreading/intel_sibling.c +++ b/src/cpu/intel/hyperthreading/intel_sibling.c @@ -17,7 +17,6 @@ #include #include #include -#include #if CONFIG(PARALLEL_CPU_INIT) #error Intel hyper-threading requires serialized CPU init diff --git a/src/cpu/intel/model_206ax/model_206ax_init.c b/src/cpu/intel/model_206ax/model_206ax_init.c index 85b0937b9c9..524e49c5c60 100644 --- a/src/cpu/intel/model_206ax/model_206ax_init.c +++ b/src/cpu/intel/model_206ax/model_206ax_init.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c index 00f630747ad..e26701b0991 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/drivers/spi/winbond.c b/src/drivers/spi/winbond.c index be0850493fd..11a518746c8 100644 --- a/src/drivers/spi/winbond.c +++ b/src/drivers/spi/winbond.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/src/lib/gpio.c b/src/lib/gpio.c index ab473cb229c..8ea3b5eb8e7 100644 --- a/src/lib/gpio.c +++ b/src/lib/gpio.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/mainboard/google/dragonegg/romstage_fsp_params.c b/src/mainboard/google/dragonegg/romstage_fsp_params.c index e357ee78c05..f2c6851a3fe 100644 --- a/src/mainboard/google/dragonegg/romstage_fsp_params.c +++ b/src/mainboard/google/dragonegg/romstage_fsp_params.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include diff --git a/src/mainboard/intel/galileo/vboot.c b/src/mainboard/intel/galileo/vboot.c index 4b1f09f2e8b..8b6706c15ce 100644 --- a/src/mainboard/intel/galileo/vboot.c +++ b/src/mainboard/intel/galileo/vboot.c @@ -12,7 +12,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/northbridge/amd/pi/00630F01/northbridge.c b/src/northbridge/amd/pi/00630F01/northbridge.c index 2b94daa1276..eca2f0c73d5 100644 --- a/src/northbridge/amd/pi/00630F01/northbridge.c +++ b/src/northbridge/amd/pi/00630F01/northbridge.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #if CONFIG(BINARYPI_LEGACY_WRAPPER) diff --git a/src/security/vboot/vbnv_flash.c b/src/security/vboot/vbnv_flash.c index 85cd04a8e5d..908846fe70f 100644 --- a/src/security/vboot/vbnv_flash.c +++ b/src/security/vboot/vbnv_flash.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/cavium/cn81xx/ecam0.c b/src/soc/cavium/cn81xx/ecam0.c index 6e0cb9c7313..6659cdf3bc1 100644 --- a/src/soc/cavium/cn81xx/ecam0.c +++ b/src/soc/cavium/cn81xx/ecam0.c @@ -23,7 +23,6 @@ #include #include #include -#include #define CAVM_PCCPF_XXX_VSEC_CTL 0x108 #define CAVM_PCCPF_XXX_VSEC_SCTL 0x10c diff --git a/src/soc/cavium/cn81xx/twsi.c b/src/soc/cavium/cn81xx/twsi.c index d29bcda121b..7137531d490 100644 --- a/src/soc/cavium/cn81xx/twsi.c +++ b/src/soc/cavium/cn81xx/twsi.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/src/soc/cavium/common/ecam.c b/src/soc/cavium/common/ecam.c index aaf9085ccfa..ae2a91fe0d9 100644 --- a/src/soc/cavium/common/ecam.c +++ b/src/soc/cavium/common/ecam.c @@ -22,7 +22,6 @@ #include #include #include -#include /** * Get PCI BAR address from cavium specific extended capability. diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c index 9696a580c0f..6208c9c739d 100644 --- a/src/soc/intel/apollolake/acpi.c +++ b/src/soc/intel/apollolake/acpi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/intel/apollolake/gpio_apl.c b/src/soc/intel/apollolake/gpio_apl.c index 265e613d61e..b76c9b09fe8 100644 --- a/src/soc/intel/apollolake/gpio_apl.c +++ b/src/soc/intel/apollolake/gpio_apl.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/apollolake/gpio_glk.c b/src/soc/intel/apollolake/gpio_glk.c index 037273c3fa2..99f4e4ddc0c 100644 --- a/src/soc/intel/apollolake/gpio_glk.c +++ b/src/soc/intel/apollolake/gpio_glk.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/apollolake/uart.c b/src/soc/intel/apollolake/uart.c index 1a31e2025d0..27be4e65f9c 100644 --- a/src/soc/intel/apollolake/uart.c +++ b/src/soc/intel/apollolake/uart.c @@ -20,7 +20,6 @@ * shouldn't cause any fragmentation. */ -#include #include #include #include diff --git a/src/soc/intel/cannonlake/romstage/romstage.c b/src/soc/intel/cannonlake/romstage/romstage.c index 893f37d421c..c168da9a384 100644 --- a/src/soc/intel/cannonlake/romstage/romstage.c +++ b/src/soc/intel/cannonlake/romstage/romstage.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c index 1b72b24d5ff..2bd906adf89 100644 --- a/src/soc/intel/cannonlake/uart.c +++ b/src/soc/intel/cannonlake/uart.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/common/block/sgx/sgx.c b/src/soc/intel/common/block/sgx/sgx.c index 3a4a5332805..2d4cc53aa71 100644 --- a/src/soc/intel/common/block/sgx/sgx.c +++ b/src/soc/intel/common/block/sgx/sgx.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index b89bf6f31e1..a8e5792a860 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/intel/denverton_ns/gpio.c b/src/soc/intel/denverton_ns/gpio.c index 30851fd75b9..7c45d40de54 100644 --- a/src/soc/intel/denverton_ns/gpio.c +++ b/src/soc/intel/denverton_ns/gpio.c @@ -16,7 +16,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/icelake/romstage/romstage.c b/src/soc/intel/icelake/romstage/romstage.c index a61370a1ee6..b0a2b6c0cd7 100644 --- a/src/soc/intel/icelake/romstage/romstage.c +++ b/src/soc/intel/icelake/romstage/romstage.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/icelake/uart.c b/src/soc/intel/icelake/uart.c index 1b72b24d5ff..2bd906adf89 100644 --- a/src/soc/intel/icelake/uart.c +++ b/src/soc/intel/icelake/uart.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/quark/spi.c b/src/soc/intel/quark/spi.c index 7ffa203bdc5..0bd0473db5f 100644 --- a/src/soc/intel/quark/spi.c +++ b/src/soc/intel/quark/spi.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 3e77b03c3fe..47d484162d8 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/skylake/gpio.c b/src/soc/intel/skylake/gpio.c index 3d66fa46020..39cbde6cc2d 100644 --- a/src/soc/intel/skylake/gpio.c +++ b/src/soc/intel/skylake/gpio.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/mediatek/common/include/soc/rtc_common.h b/src/soc/mediatek/common/include/soc/rtc_common.h index d039e0becff..ff5dd34d89a 100644 --- a/src/soc/mediatek/common/include/soc/rtc_common.h +++ b/src/soc/mediatek/common/include/soc/rtc_common.h @@ -16,7 +16,6 @@ #ifndef SOC_MEDIATEK_RTC_COMMON_H #define SOC_MEDIATEK_RTC_COMMON_H -#include #include #include #include diff --git a/src/soc/mediatek/common/pmic_wrap.c b/src/soc/mediatek/common/pmic_wrap.c index 1b8bc5d3a08..6785c0a0bd0 100644 --- a/src/soc/mediatek/common/pmic_wrap.c +++ b/src/soc/mediatek/common/pmic_wrap.c @@ -14,7 +14,6 @@ */ #include -#include #include #include diff --git a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c index 01a32e3cb4a..0a8e69be1e9 100644 --- a/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c +++ b/src/soc/mediatek/mt8173/dramc_pi_calibration_api.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/mediatek/mt8173/emi.c b/src/soc/mediatek/mt8173/emi.c index d4cd02aa09f..be84668abee 100644 --- a/src/soc/mediatek/mt8173/emi.c +++ b/src/soc/mediatek/mt8173/emi.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/mediatek/mt8173/pmic_wrap.c b/src/soc/mediatek/mt8173/pmic_wrap.c index 6acaee2bee0..af88343c14f 100644 --- a/src/soc/mediatek/mt8173/pmic_wrap.c +++ b/src/soc/mediatek/mt8173/pmic_wrap.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/mediatek/mt8183/mt6358.c b/src/soc/mediatek/mt8183/mt6358.c index d338e1682da..580327183ce 100644 --- a/src/soc/mediatek/mt8183/mt6358.c +++ b/src/soc/mediatek/mt8183/mt6358.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/qualcomm/ipq40xx/i2c.c b/src/soc/qualcomm/ipq40xx/i2c.c index f5c9943cfa6..f20dada0b06 100644 --- a/src/soc/qualcomm/ipq40xx/i2c.c +++ b/src/soc/qualcomm/ipq40xx/i2c.c @@ -29,7 +29,6 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include diff --git a/src/soc/qualcomm/ipq806x/i2c.c b/src/soc/qualcomm/ipq806x/i2c.c index cd57591bebf..c81373fade9 100644 --- a/src/soc/qualcomm/ipq806x/i2c.c +++ b/src/soc/qualcomm/ipq806x/i2c.c @@ -27,7 +27,6 @@ * SUCH DAMAGE. */ -#include #include #include #include diff --git a/src/soc/rockchip/common/edp.c b/src/soc/rockchip/common/edp.c index 98381a0d1a1..91e2de9ff4c 100644 --- a/src/soc/rockchip/common/edp.c +++ b/src/soc/rockchip/common/edp.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/rockchip/common/pwm.c b/src/soc/rockchip/common/pwm.c index ad0453b612b..e5da05e6724 100644 --- a/src/soc/rockchip/common/pwm.c +++ b/src/soc/rockchip/common/pwm.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/rockchip/rk3288/hdmi.c b/src/soc/rockchip/rk3288/hdmi.c index 425d302fbbc..b4de270fc54 100644 --- a/src/soc/rockchip/rk3288/hdmi.c +++ b/src/soc/rockchip/rk3288/hdmi.c @@ -20,7 +20,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/rockchip/rk3288/tsadc.c b/src/soc/rockchip/rk3288/tsadc.c index a34105d9acb..3223a4ddd46 100644 --- a/src/soc/rockchip/rk3288/tsadc.c +++ b/src/soc/rockchip/rk3288/tsadc.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/rockchip/rk3399/bl31_plat_params.c b/src/soc/rockchip/rk3399/bl31_plat_params.c index 647566ba2d9..9c11552301f 100644 --- a/src/soc/rockchip/rk3399/bl31_plat_params.c +++ b/src/soc/rockchip/rk3399/bl31_plat_params.c @@ -15,7 +15,6 @@ */ #include -#include #include #include diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c index ee8cc2e4452..cc16563c435 100644 --- a/src/soc/rockchip/rk3399/mipi.c +++ b/src/soc/rockchip/rk3399/mipi.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/rockchip/rk3399/tsadc.c b/src/soc/rockchip/rk3399/tsadc.c index d5aeccdec62..7ec24648a22 100644 --- a/src/soc/rockchip/rk3399/tsadc.c +++ b/src/soc/rockchip/rk3399/tsadc.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/samsung/exynos5250/alternate_cbfs.c b/src/soc/samsung/exynos5250/alternate_cbfs.c index 9fef9ae377b..e4316725793 100644 --- a/src/soc/samsung/exynos5250/alternate_cbfs.c +++ b/src/soc/samsung/exynos5250/alternate_cbfs.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/samsung/exynos5250/pinmux.c b/src/soc/samsung/exynos5250/pinmux.c index 10c8c953cd9..9ddbea56b2a 100644 --- a/src/soc/samsung/exynos5250/pinmux.c +++ b/src/soc/samsung/exynos5250/pinmux.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/samsung/exynos5420/alternate_cbfs.c b/src/soc/samsung/exynos5420/alternate_cbfs.c index a1e92a08bc4..ba3f9a3c874 100644 --- a/src/soc/samsung/exynos5420/alternate_cbfs.c +++ b/src/soc/samsung/exynos5420/alternate_cbfs.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/samsung/exynos5420/pinmux.c b/src/soc/samsung/exynos5420/pinmux.c index d8c13780a49..999afa0247c 100644 --- a/src/soc/samsung/exynos5420/pinmux.c +++ b/src/soc/samsung/exynos5420/pinmux.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/superio/renesas/m3885x/superio.c b/src/superio/renesas/m3885x/superio.c index b200855abd7..522d64796a5 100644 --- a/src/superio/renesas/m3885x/superio.c +++ b/src/superio/renesas/m3885x/superio.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/src/superio/smsc/lpc47n227/early_serial.c b/src/superio/smsc/lpc47n227/early_serial.c index c02b8506d1f..42213b74ccb 100644 --- a/src/superio/smsc/lpc47n227/early_serial.c +++ b/src/superio/smsc/lpc47n227/early_serial.c @@ -17,7 +17,9 @@ /* Pre-RAM driver for SMSC LPC47N227 Super I/O chip. */ #include +#include #include + #include "lpc47n227.h" void pnp_enter_conf_state(pnp_devfn_t dev) From 095c2617a368536f482f0b9ca16a4a5e69cd55ec Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 24 Feb 2019 10:33:18 +0100 Subject: [PATCH 029/588] crossgcc: Upgrade GCC to version 8.3.0 Change-Id: I135fd62619fc33bbc3fd29e93eeafcf695700c9a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31598 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- util/crossgcc/buildgcc | 2 +- ...usl_workaround.patch => gcc-8.3.0_ada-musl_workaround.patch} | 0 .../patches/{gcc-8.2.0_gnat.patch => gcc-8.3.0_gnat.patch} | 0 .../patches/{gcc-8.2.0_libgcc.patch => gcc-8.3.0_libgcc.patch} | 0 .../{gcc-8.2.0_nds32_ite.patch => gcc-8.3.0_nds32_ite.patch} | 0 util/crossgcc/sum/gcc-8.2.0.tar.xz.cksum | 1 - util/crossgcc/sum/gcc-8.3.0.tar.xz.cksum | 1 + 7 files changed, 2 insertions(+), 2 deletions(-) rename util/crossgcc/patches/{gcc-8.2.0_ada-musl_workaround.patch => gcc-8.3.0_ada-musl_workaround.patch} (100%) rename util/crossgcc/patches/{gcc-8.2.0_gnat.patch => gcc-8.3.0_gnat.patch} (100%) rename util/crossgcc/patches/{gcc-8.2.0_libgcc.patch => gcc-8.3.0_libgcc.patch} (100%) rename util/crossgcc/patches/{gcc-8.2.0_nds32_ite.patch => gcc-8.3.0_nds32_ite.patch} (100%) delete mode 100644 util/crossgcc/sum/gcc-8.2.0.tar.xz.cksum create mode 100644 util/crossgcc/sum/gcc-8.3.0.tar.xz.cksum diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index 5ee663821af..12bb23dcf33 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -50,7 +50,7 @@ THREADS=1 GMP_VERSION=6.1.2 MPFR_VERSION=4.0.2 MPC_VERSION=1.1.0 -GCC_VERSION=8.2.0 +GCC_VERSION=8.3.0 GCC_AUTOCONF_VERSION=2.69 BINUTILS_VERSION=2.32 GDB_VERSION=8.2.1 diff --git a/util/crossgcc/patches/gcc-8.2.0_ada-musl_workaround.patch b/util/crossgcc/patches/gcc-8.3.0_ada-musl_workaround.patch similarity index 100% rename from util/crossgcc/patches/gcc-8.2.0_ada-musl_workaround.patch rename to util/crossgcc/patches/gcc-8.3.0_ada-musl_workaround.patch diff --git a/util/crossgcc/patches/gcc-8.2.0_gnat.patch b/util/crossgcc/patches/gcc-8.3.0_gnat.patch similarity index 100% rename from util/crossgcc/patches/gcc-8.2.0_gnat.patch rename to util/crossgcc/patches/gcc-8.3.0_gnat.patch diff --git a/util/crossgcc/patches/gcc-8.2.0_libgcc.patch b/util/crossgcc/patches/gcc-8.3.0_libgcc.patch similarity index 100% rename from util/crossgcc/patches/gcc-8.2.0_libgcc.patch rename to util/crossgcc/patches/gcc-8.3.0_libgcc.patch diff --git a/util/crossgcc/patches/gcc-8.2.0_nds32_ite.patch b/util/crossgcc/patches/gcc-8.3.0_nds32_ite.patch similarity index 100% rename from util/crossgcc/patches/gcc-8.2.0_nds32_ite.patch rename to util/crossgcc/patches/gcc-8.3.0_nds32_ite.patch diff --git a/util/crossgcc/sum/gcc-8.2.0.tar.xz.cksum b/util/crossgcc/sum/gcc-8.2.0.tar.xz.cksum deleted file mode 100644 index 1ef301a5d31..00000000000 --- a/util/crossgcc/sum/gcc-8.2.0.tar.xz.cksum +++ /dev/null @@ -1 +0,0 @@ -19926bdb6c4b58891015929853d41aeff019d400 tarballs/gcc-8.2.0.tar.xz diff --git a/util/crossgcc/sum/gcc-8.3.0.tar.xz.cksum b/util/crossgcc/sum/gcc-8.3.0.tar.xz.cksum new file mode 100644 index 00000000000..b46ef8c46f6 --- /dev/null +++ b/util/crossgcc/sum/gcc-8.3.0.tar.xz.cksum @@ -0,0 +1 @@ +c27f4499dd263fe4fb01bcc5565917f3698583b2 tarballs/gcc-8.3.0.tar.xz From b1f4d5258005b685f07f195157467e20181b8a21 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 2 Apr 2019 20:02:23 +0200 Subject: [PATCH 030/588] crossgcc: Update CMake to version 3.14.2 Release Note : https://cmake.org/cmake/help/v3.14/release/3.14.html "The FindFontconfig module added by 3.14.0 accidentally used uppercase FONTCONFIG_* variable names that do not match our conventions. 3.14.1 revises the module to use Fontconfig_* variable names. This is incompatible with 3.14.0 but since the module is new in the 3.14 series usage should not yet be widespread" Change-Id: Ief7f5e8309597093f061789926bd3bd2ed3aec2d Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32141 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- util/crossgcc/buildgcc | 2 +- util/crossgcc/sum/cmake-3.14.0.tar.gz.cksum | 1 - util/crossgcc/sum/cmake-3.14.2.tar.gz.cksum | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 util/crossgcc/sum/cmake-3.14.0.tar.gz.cksum create mode 100644 util/crossgcc/sum/cmake-3.14.2.tar.gz.cksum diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index 12bb23dcf33..5e0199bfcb8 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -60,7 +60,7 @@ EXPAT_VERSION=2.2.6 # CLANG version number CLANG_VERSION=8.0.0 MAKE_VERSION=4.2.1 -CMAKE_VERSION=3.14.0 +CMAKE_VERSION=3.14.2 # GCC toolchain archive locations # These are sanitized by the jenkins toolchain test builder, so if diff --git a/util/crossgcc/sum/cmake-3.14.0.tar.gz.cksum b/util/crossgcc/sum/cmake-3.14.0.tar.gz.cksum deleted file mode 100644 index 997b8a03fdf..00000000000 --- a/util/crossgcc/sum/cmake-3.14.0.tar.gz.cksum +++ /dev/null @@ -1 +0,0 @@ -30e5423245d98ad98f6ee0c5f73c587846b99d6b tarballs/cmake-3.14.0.tar.gz diff --git a/util/crossgcc/sum/cmake-3.14.2.tar.gz.cksum b/util/crossgcc/sum/cmake-3.14.2.tar.gz.cksum new file mode 100644 index 00000000000..6369ac38dbe --- /dev/null +++ b/util/crossgcc/sum/cmake-3.14.2.tar.gz.cksum @@ -0,0 +1 @@ +94ef8e36fa93edaf6f194e0ce0065ea769b3e57c tarballs/cmake-3.14.2.tar.gz From 5f28639a93d4d59a28ba04fb3f7218a7c9e02334 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 16 Feb 2019 19:17:39 +0100 Subject: [PATCH 031/588] crossgcc: Update acpica to version 20190215 Support for ACPI specification version 6.3: Add PCC operation region support for the AML interpreter. This adds PCC operation region support in the AML interpreter and a default handler for acpiexec. The change also renames the PCC region address space keyword to PlatformCommChannel. Support for new predefined methods _NBS, _NCH, _NIC, _NIH, and _NIG. These methods provide OSPM with health information and device boot status. PDTT: Add TriggerOrder to the PCC Identifier structure. The field value defines if the trigger needs to be invoked by OSPM before or at the end of kernel crash dump processing/handling operation. SRAT: Add Generic Affinity Structure subtable. This subtable in the SRAT is used for describing devices such as heterogeneous processors, accelerators, GPUs, and IO devices with integrated compute or DMA engines. MADT: Add support for statistical profiling in GICC. Statistical profiling extension (SPE) is an architecture-specific feature for ARM. MADT: Add online capable flag. If this bit is set, system hardware supports enabling this processor during OS runtime. New Error Disconnect Recover Notification value. There are a number of scenarios where system Firmware in collaboration with hardware may disconnect one or more devices from the rest of the system for purposes of error containment. Firmware can use this new notification value to alert OSPM of such a removal. PPTT: New additional fields in Processor Structure Flags. These flags provide more information about processor topology. NFIT/Disassembler: Change a field name from "Address Range" to "Region Type". HMAT updates: make several existing fields to be reserved as well as rename subtable 0 to "memory proximity domain attributes". GTDT: Add support for new GTDT Revision 3. This revision adds information for the EL2 timer. iASL: Update the HMAT example template for new fields. iASL: Add support for the new revision of the GTDT (Rev 3). More changes in this version at https://acpica.org/node/166 Change-Id: I3a825f568423c3a703ad1c13da976af322ed9de2 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31443 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer Reviewed-by: Paul Menzel --- util/crossgcc/buildgcc | 2 +- ...ix2-20190108_iasl.patch => acpica-unix2-20190215_iasl.patch} | 2 +- util/crossgcc/sum/acpica-unix2-20190108.tar.gz.cksum | 1 - util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum | 1 + 4 files changed, 3 insertions(+), 3 deletions(-) rename util/crossgcc/patches/{acpica-unix2-20190108_iasl.patch => acpica-unix2-20190215_iasl.patch} (84%) delete mode 100644 util/crossgcc/sum/acpica-unix2-20190108.tar.gz.cksum create mode 100644 util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index 5e0199bfcb8..0951fb60e43 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -54,7 +54,7 @@ GCC_VERSION=8.3.0 GCC_AUTOCONF_VERSION=2.69 BINUTILS_VERSION=2.32 GDB_VERSION=8.2.1 -IASL_VERSION=20190108 +IASL_VERSION=20190215 PYTHON_VERSION=3.7.2 EXPAT_VERSION=2.2.6 # CLANG version number diff --git a/util/crossgcc/patches/acpica-unix2-20190108_iasl.patch b/util/crossgcc/patches/acpica-unix2-20190215_iasl.patch similarity index 84% rename from util/crossgcc/patches/acpica-unix2-20190108_iasl.patch rename to util/crossgcc/patches/acpica-unix2-20190215_iasl.patch index 65322554996..c4f605292be 100644 --- a/util/crossgcc/patches/acpica-unix2-20190108_iasl.patch +++ b/util/crossgcc/patches/acpica-unix2-20190215_iasl.patch @@ -1,4 +1,4 @@ -diff -Naur acpica-unix2-20190108_/source/compiler/asloptions.c acpica-unix2-20190108/source/compiler/asloptions.c > acpica-unix2-20190108_iasl.patch +diff -Naur acpica-unix2-20190215_/source/compiler/asloptions.c acpica-unix2-20190215/source/compiler/asloptions.c > acpica-unix2-20190215_iasl.patch --- acpica-unix2-20190108_/source/compiler/asloptions.c +++ acpica-unix2-20190108/source/compiler/asloptions.c @@ -126,6 +126,7 @@ diff --git a/util/crossgcc/sum/acpica-unix2-20190108.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20190108.tar.gz.cksum deleted file mode 100644 index c5cfb4c3f41..00000000000 --- a/util/crossgcc/sum/acpica-unix2-20190108.tar.gz.cksum +++ /dev/null @@ -1 +0,0 @@ -50d96dd38b89c69260ad209cf61035cda1fcdd67 tarballs/acpica-unix2-20190108.tar.gz diff --git a/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum new file mode 100644 index 00000000000..310454d6030 --- /dev/null +++ b/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum @@ -0,0 +1 @@ +82d729cb09edc50ee11669651683ca5a5c0f4d5a tarballs/acpica-unix2-20190215.tar.gz From 78fbe3d8319bc8fdf82b76378d29c6c902fd13e5 Mon Sep 17 00:00:00 2001 From: Aamir Bohra Date: Mon, 15 Apr 2019 10:16:36 +0530 Subject: [PATCH 032/588] soc/intel/cannonlake: Add null reference check for Cnvi and Xdci Change-Id: I2e1011d9ac93ed764b6c2aa425928a972ec2aa43 Signed-off-by: Aamir Bohra Reviewed-on: https://review.coreboot.org/c/coreboot/+/32322 Reviewed-by: Maulik V Vaghela Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/fsp_params.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index b8dba184cb7..2b83275df10 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -245,9 +245,12 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Enable xDCI controller if enabled in devicetree and allowed */ dev = dev_find_slot(0, PCH_DEVFN_USBOTG); - if (!xdci_can_enable()) - dev->enabled = 0; - params->XdciEnable = dev->enabled; + if (dev) { + if (!xdci_can_enable()) + dev->enabled = 0; + params->XdciEnable = dev->enabled; + } else + params->XdciEnable = 0; /* Set Debug serial port */ params->SerialIoDebugUartNumber = CONFIG_UART_FOR_CONSOLE; @@ -255,9 +258,15 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Enable CNVi Wifi if enabled in device tree */ dev = dev_find_slot(0, PCH_DEVFN_CNViWIFI); #if CONFIG(SOC_INTEL_COMETLAKE) - params->CnviMode = dev->enabled; + if (dev) + params->CnviMode = dev->enabled; + else + params->CnviMode = 0; #else - params->PchCnviMode = dev->enabled; + if (dev) + params->PchCnviMode = dev->enabled; + else + params->PchCnviMode = 0; #endif /* PCI Express */ for (i = 0; i < ARRAY_SIZE(config->PcieClkSrcUsage); i++) { From da9302a2c42038594ed0127b8887c7d984cd65e1 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 24 Mar 2019 17:01:41 +0100 Subject: [PATCH 033/588] nb/intel/sandybridge: Drop pch.h from sandybridge.h Include pch.h in the source files instead in sandybridge.h. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to OS, no errors visible in dmesg. Change-Id: I9e5b678e979a8d136d8d00b49486d0a882f77d81 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32065 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/mainboard/asrock/b75pro3-m/romstage.c | 1 + src/mainboard/compulab/intense_pc/romstage.c | 1 + src/mainboard/google/link/romstage.c | 1 + src/mainboard/intel/dcp847ske/early_southbridge.c | 1 + src/mainboard/intel/dcp847ske/romstage.c | 1 + src/northbridge/intel/sandybridge/gma.c | 1 + src/northbridge/intel/sandybridge/raminit.c | 1 + src/northbridge/intel/sandybridge/sandybridge.h | 2 -- src/southbridge/intel/bd82x6x/acpi/pch.asl | 1 + 9 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/mainboard/asrock/b75pro3-m/romstage.c b/src/mainboard/asrock/b75pro3-m/romstage.c index 51991248afd..cbd26a52ac0 100644 --- a/src/mainboard/asrock/b75pro3-m/romstage.c +++ b/src/mainboard/asrock/b75pro3-m/romstage.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/src/mainboard/compulab/intense_pc/romstage.c b/src/mainboard/compulab/intense_pc/romstage.c index dbd28c8affe..6d0b3af8c04 100644 --- a/src/mainboard/compulab/intense_pc/romstage.c +++ b/src/mainboard/compulab/intense_pc/romstage.c @@ -18,6 +18,7 @@ #include #include #include +#include #define SIO_PORT 0x164e diff --git a/src/mainboard/google/link/romstage.c b/src/mainboard/google/link/romstage.c index 66a503d0b18..8da13080b3a 100644 --- a/src/mainboard/google/link/romstage.c +++ b/src/mainboard/google/link/romstage.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "ec/google/chromeec/ec.h" #include diff --git a/src/mainboard/intel/dcp847ske/early_southbridge.c b/src/mainboard/intel/dcp847ske/early_southbridge.c index 510073540f2..39aeb8f6e26 100644 --- a/src/mainboard/intel/dcp847ske/early_southbridge.c +++ b/src/mainboard/intel/dcp847ske/early_southbridge.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "superio.h" #include "thermal.h" diff --git a/src/mainboard/intel/dcp847ske/romstage.c b/src/mainboard/intel/dcp847ske/romstage.c index 24ec912a4c3..235ad228f80 100644 --- a/src/mainboard/intel/dcp847ske/romstage.c +++ b/src/mainboard/intel/dcp847ske/romstage.c @@ -23,6 +23,7 @@ #else #include #endif +#include #if !CONFIG(USE_NATIVE_RAMINIT) void mainboard_fill_pei_data(struct pei_data *pei_data) diff --git a/src/northbridge/intel/sandybridge/gma.c b/src/northbridge/intel/sandybridge/gma.c index 0d28d676020..cb6782e9b77 100644 --- a/src/northbridge/intel/sandybridge/gma.c +++ b/src/northbridge/intel/sandybridge/gma.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "chip.h" diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index c0666343123..050f4c2ba04 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include "raminit_native.h" diff --git a/src/northbridge/intel/sandybridge/sandybridge.h b/src/northbridge/intel/sandybridge/sandybridge.h index e315fa463f1..92cb888a418 100644 --- a/src/northbridge/intel/sandybridge/sandybridge.h +++ b/src/northbridge/intel/sandybridge/sandybridge.h @@ -52,8 +52,6 @@ #define IOMMU_BASE1 0xfed90000ULL #define IOMMU_BASE2 0xfed91000ULL -#include - /* Everything below this line is ignored in the DSDT */ #ifndef __ACPI__ #include diff --git a/src/southbridge/intel/bd82x6x/acpi/pch.asl b/src/southbridge/intel/bd82x6x/acpi/pch.asl index 72e284d08f3..20182192f24 100644 --- a/src/southbridge/intel/bd82x6x/acpi/pch.asl +++ b/src/southbridge/intel/bd82x6x/acpi/pch.asl @@ -15,6 +15,7 @@ */ /* Intel Cougar Point PCH support */ +#include Scope(\) { From 34564ed154b6734cc51bf05d61b45d9a74cdc2b5 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 16 Apr 2019 08:12:10 +0200 Subject: [PATCH 034/588] ACPI: Clarify serial bus revision and specific revision Serial bus revision [Byte 3] and serial bus specific revision [Byte 9] are not the same. Change-Id: I366f62e6aa0e9c0dfbc1ec17adeebc42a0e777eb Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32329 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/arch/x86/acpi_device.c | 8 ++++---- src/arch/x86/include/arch/acpi_device.h | 9 ++++++--- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index c57ba480941..5d8777f37f1 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -377,7 +377,7 @@ void acpi_device_write_i2c(const struct acpi_i2c *i2c) desc_length = acpi_device_write_zero_len(); /* Byte 3: Revision ID */ - acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID); + acpigen_emit_byte(ACPI_I2C_SERIAL_BUS_REVISION_ID); /* Byte 4: Resource Source Index is Reserved */ acpigen_emit_byte(0); @@ -401,7 +401,7 @@ void acpi_device_write_i2c(const struct acpi_i2c *i2c) acpigen_emit_word(i2c->mode_10bit); /* Byte 9: Type Specific Revision ID */ - acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID); + acpigen_emit_byte(ACPI_I2C_TYPE_SPECIFIC_REVISION_ID); /* Byte 10-11: I2C Type Data Length */ type_length = acpi_device_write_zero_len(); @@ -435,7 +435,7 @@ void acpi_device_write_spi(const struct acpi_spi *spi) desc_length = acpi_device_write_zero_len(); /* Byte 3: Revision ID */ - acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID); + acpigen_emit_byte(ACPI_SPI_SERIAL_BUS_REVISION_ID); /* Byte 4: Resource Source Index is Reserved */ acpigen_emit_byte(0); @@ -464,7 +464,7 @@ void acpi_device_write_spi(const struct acpi_spi *spi) acpigen_emit_word(flags); /* Byte 9: Type Specific Revision ID */ - acpigen_emit_byte(ACPI_SERIAL_BUS_REVISION_ID); + acpigen_emit_byte(ACPI_SPI_TYPE_SPECIFIC_REVISION_ID); /* Byte 10-11: SPI Type Data Length */ type_length = acpi_device_write_zero_len(); diff --git a/src/arch/x86/include/arch/acpi_device.h b/src/arch/x86/include/arch/acpi_device.h index d26f3306957..35695467cbd 100644 --- a/src/arch/x86/include/arch/acpi_device.h +++ b/src/arch/x86/include/arch/acpi_device.h @@ -309,9 +309,12 @@ void acpi_device_write_gpio(const struct acpi_gpio *gpio); * ACPI Descriptors for Serial Bus interfaces */ -#define ACPI_SERIAL_BUS_TYPE_I2C 1 -#define ACPI_SERIAL_BUS_TYPE_SPI 2 -#define ACPI_SERIAL_BUS_REVISION_ID 1 +#define ACPI_SERIAL_BUS_TYPE_I2C 1 +#define ACPI_SERIAL_BUS_TYPE_SPI 2 +#define ACPI_I2C_SERIAL_BUS_REVISION_ID 1 /* TODO: upgrade to 2 */ +#define ACPI_I2C_TYPE_SPECIFIC_REVISION_ID 1 +#define ACPI_SPI_SERIAL_BUS_REVISION_ID 1 +#define ACPI_SPI_TYPE_SPECIFIC_REVISION_ID 1 /* * ACPI I2C Bus From 0556f6132b28ff8da45a5a1b4ef4c66e95b5bcb9 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Wed, 12 Dec 2018 08:13:30 +0100 Subject: [PATCH 035/588] soc/intel/braswell/acpi/lpss.asl: Remove SPI1 and PWM asl code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Linux remains using SPI1 and PWM ASL even if these devices are disabled. SPI1 and PWM are disabled by Intel FSP. Remove ASL code. BUG=N/A TEST=Boot Ubuntu on Intel CherryHill CRB Change-Id: Iec2ca7520081d00bf7a53d58ee054aa6f23e5606 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/29417 Tested-by: build bot (Jenkins) Reviewed-by: Michał Żygowski Reviewed-by: Matt DeVillier --- src/soc/intel/braswell/acpi/lpss.asl | 110 +-------------------------- 1 file changed, 1 insertion(+), 109 deletions(-) diff --git a/src/soc/intel/braswell/acpi/lpss.asl b/src/soc/intel/braswell/acpi/lpss.asl index 4cc93cc2d2a..f9b376ccb30 100644 --- a/src/soc/intel/braswell/acpi/lpss.asl +++ b/src/soc/intel/braswell/acpi/lpss.asl @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2013 Google Inc. + * Copyright (C) 2018 Eltan B.V. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -522,115 +523,6 @@ Device (I2C7) } } -Device (SPI1) -{ - Name (_HID, "8086228E") - Name (_UID, 1) - Name (_DDN, "SPI Controller #2") - - Name (RBUF, ResourceTemplate() - { - Memory32Fixed (ReadWrite, 0, 0x1000, BAR0) - Interrupt (ResourceConsumer, Level, ActiveLow, Exclusive,,,) - { - LPSS_SPI_IRQ - } - FixedDMA (0x0, 0x0, Width32Bit, ) - FixedDMA (0x1, 0x1, Width32Bit, ) - }) - - Method (_CRS) - { - CreateDwordField (^RBUF, ^BAR0._BAS, RBAS) - Store (\S9B0, RBAS) - Return (^RBUF) - } - - Method (_STA) - { - If (LEqual (\S9EN, 1)) { - Return (0xF) - } Else { - Return (0x0) - } - } - - OperationRegion (KEYS, SystemMemory, S9B1, 0x100) - Field (KEYS, DWordAcc, NoLock, WriteAsZeros) - { - Offset (0x84), - PSAT, 32, - } - - Method (_PS3) - { - Or (PSAT, 0x00000003, PSAT) - Or (PSAT, 0x00000000, PSAT) - } - - Method (_PS0) - { - And (PSAT, 0xfffffffc, PSAT) - Or (PSAT, 0x00000000, PSAT) - } -} - -Device (PWM1) -{ - Name (_HID, "80862288") - Name (_UID, 1) - Name (_DDN, "PWM Controller #1") - - Name (RBUF, ResourceTemplate() - { - Memory32Fixed (ReadWrite, 0, 0x1000, BAR0) - }) - - Method (_CRS) - { - CreateDwordField (^RBUF, ^BAR0._BAS, RBAS) - Store (\SAB0, RBAS) - Return (^RBUF) - } - - Method (_STA) - { - If (LEqual (\SAEN, 1)) { - Return (0xF) - } Else { - Return (0x0) - } - } -} - -Device (PWM2) -{ - Name (_HID, "80862288") - Name (_UID, 2) - Name (_DDN, "PWM Controller #2") - - Name (RBUF, ResourceTemplate() - { - Memory32Fixed (ReadWrite, 0, 0x1000, BAR0) - }) - - Method (_CRS) - { - CreateDwordField (^RBUF, ^BAR0._BAS, RBAS) - Store (\SBB0, RBAS) - Return (^RBUF) - } - - Method (_STA) - { - If (LEqual (\SBEN, 1)) { - Return (0xF) - } Else { - Return (0x0) - } - } -} - Device (UAR1) { Name (_HID, "8086228A") From f5e8b29be6fc32ded30f25e4706ea55c42c13b41 Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Wed, 17 Apr 2019 10:42:00 +0800 Subject: [PATCH 036/588] soc/intel/common: Add SOC_INTEL_DEBUG_CONSENT to control debug interface SOC_INTEL_DEBUG_CONSENT config is generally to enable default debug interface of SoC. Ex: USB DBC, DCI debug interface on cnl, whl, cml. Change-Id: I313d80d6c63fd37164c63f78e9e69d3cb4a5566b Signed-off-by: Kane Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32337 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/common/Kconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/soc/intel/common/Kconfig b/src/soc/intel/common/Kconfig index b5caf400975..318cc25c877 100644 --- a/src/soc/intel/common/Kconfig +++ b/src/soc/intel/common/Kconfig @@ -68,4 +68,11 @@ config TPM_TIS_ACPI_INTERRUPT acpi_get_gpe() is used to provide interrupt status to TPM layer. This option specifies the GPE number. +config SOC_INTEL_DEBUG_CONSENT + bool "Enable SOC debug interface" + default n + help + Set this option to enable default debug interface of SoC such as DBC + or DCI. + endif # SOC_INTEL_COMMON From 3717256d5a37710c5d39004afcbc5d5b74737e4b Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Thu, 11 Apr 2019 21:55:20 +0800 Subject: [PATCH 037/588] soc/intel/cannonlake: Enable PlatformDebugConsent by Kconfig This change is mainly to control PlatformDebugConsent FSP UPD. PlatformDebugConsent is enabled if SOC_INTEL_CANNONLAKE_DEBUG_CONSENT != 0. PlatformDebugConsent in FspmUpd.h has the details. BUG=b:130203864 TEST=boot ok and PlatformDebugConsent can be controlled by Kconfig Change-Id: Ib845b5e42bc78fb352a0c97c6301f2aeca522f29 Signed-off-by: Kane Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32297 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 11 +++++++++++ src/soc/intel/cannonlake/chip.h | 9 --------- src/soc/intel/cannonlake/romstage/fsp_params.c | 5 +++-- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 40b40d65ad2..6af05c88481 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -292,4 +292,15 @@ config FSP_FD_PATH depends on FSP_USE_REPO default "3rdparty/fsp/CoffeeLakeFspBinPkg/Fsp.fd" if SOC_INTEL_COFFEELAKE || SOC_INTEL_WHISKEYLAKE +config SOC_INTEL_CANNONLAKE_DEBUG_CONSENT + int "Debug Consent for CNL" + # USB DBC is more common for developers so make this default to 3 if + # SOC_INTEL_DEBUG_CONSENT=y + default 3 if SOC_INTEL_DEBUG_CONSENT + default 0 + help + This is to control debug interface on SOC. + Setting non-zero value will allow to use DBC or DCI to debug SOC. + PlatformDebugConsent in FspmUpd.h has the details. + endif diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 58b540cac09..9bba226e58e 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -292,15 +292,6 @@ struct soc_intel_cannonlake_config { */ uint8_t PchPmSlpAMinAssert; - /* Desired platform debug type. */ - enum { - DebugConsent_Disabled, - DebugConsent_DCI_DBC, - DebugConsent_DCI, - DebugConsent_USB3_DBC, - DebugConsent_XDP, /* XDP/Mipi60 */ - DebugConsent_USB2_DBC, - } DebugConsent; /* * SerialIO device mode selection: * diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index 86160f68aef..ce5863855e9 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -108,9 +108,10 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) m_cfg->SmbusEnable = 0; else m_cfg->SmbusEnable = smbus->enabled; - /* Set debug probe type */ - m_cfg->PlatformDebugConsent = config->DebugConsent; + /* Set debug probe type */ + m_cfg->PlatformDebugConsent = + CONFIG_SOC_INTEL_CANNONLAKE_DEBUG_CONSENT; mainboard_memory_init_params(mupd); } From e98a7518234978ab0efbe7868f7c172302033757 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Thu, 11 Apr 2019 23:28:09 -0700 Subject: [PATCH 038/588] smbios: Add memory type 9 system slot support Add SMBIOS type 9 system slots into coreboot, the definiation is up to date with SMBIOS spec 3.2 Signed-off-by: Lijian Zhao Change-Id: Ibcfa377c260083203c1daf5562e103001f76b257 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32293 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/arch/x86/smbios.c | 35 ++++++++++ src/include/smbios.h | 150 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 1aa5be927de..7c87c693e1d 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -833,6 +833,41 @@ static int smbios_write_type7_cache_parameters(unsigned long *current, return len; } +int smbios_write_type9(unsigned long *current, int *handle, + const char *name, const enum misc_slot_type type, + const enum slot_data_bus_bandwidth bandwidth, + const enum misc_slot_usage usage, + const enum misc_slot_length length, + u8 slot_char1, u8 slot_char2, u8 bus, u8 dev_func) +{ + struct smbios_type9 *t = (struct smbios_type9 *)*current; + int len = sizeof(struct smbios_type9); + + memset(t, 0, sizeof(struct smbios_type9)); + t->type = SMBIOS_SYSTEM_SLOTS; + t->handle = *handle; + t->length = len - 2; + if (name) + t->slot_designation = smbios_add_string(t->eos, name); + else + t->slot_designation = smbios_add_string(t->eos, "SLOT"); + t->slot_type = type; + /* TODO add slot_id supoort, will be "_SUN" for ACPI devices */ + t->slot_data_bus_width = bandwidth; + t->current_usage = usage; + t->slot_length = length; + t->slot_characteristics_1 = slot_char1; + t->slot_characteristics_2 = slot_char2; + t->segment_group_number = 0; + t->bus_number = bus; + t->device_function_number = dev_func; + t->data_bus_width = SlotDataBusWidthOther; + + len = t->length + smbios_string_table_len(t->eos); + *current += len; + *handle += 1; + return len; +} static int smbios_write_type11(unsigned long *current, int *handle) { diff --git a/src/include/smbios.h b/src/include/smbios.h index 5e069470e19..afe77d6ad9f 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -26,6 +26,16 @@ int smbios_add_string(u8 *start, const char *str); int smbios_string_table_len(u8 *start); /* Used by mainboard to add an on-board device */ +enum misc_slot_type; +enum misc_slot_length; +enum misc_slot_usage; +enum slot_data_bus_bandwidth; +int smbios_write_type9(unsigned long *current, int *handle, + const char *name, const enum misc_slot_type type, + const enum slot_data_bus_bandwidth bandwidth, + const enum misc_slot_usage usage, + const enum misc_slot_length length, + u8 slot_char1, u8 slot_char2, u8 bus, u8 dev_func); enum smbios_bmc_interface_type; int smbios_write_type38(unsigned long *current, int *handle, const enum smbios_bmc_interface_type interface_type, @@ -481,6 +491,146 @@ struct smbios_type7 { u8 eos[2]; } __packed; +/* System Slots - Slot Type */ +enum misc_slot_type { + SlotTypeOther = 0x01, + SlotTypeUnknown = 0x02, + SlotTypeIsa = 0x03, + SlotTypeMca = 0x04, + SlotTypeEisa = 0x05, + SlotTypePci = 0x06, + SlotTypePcmcia = 0x07, + SlotTypeVlVesa = 0x08, + SlotTypeProprietary = 0x09, + SlotTypeProcessorCardSlot = 0x0A, + SlotTypeProprietaryMemoryCardSlot = 0x0B, + SlotTypeIORiserCardSlot = 0x0C, + SlotTypeNuBus = 0x0D, + SlotTypePci66MhzCapable = 0x0E, + SlotTypeAgp = 0x0F, + SlotTypeApg2X = 0x10, + SlotTypeAgp4X = 0x11, + SlotTypePciX = 0x12, + SlotTypeAgp8X = 0x13, + SlotTypeM2Socket1_DP = 0x14, + SlotTypeM2Socket1_SD = 0x15, + SlotTypeM2Socket2 = 0x16, + SlotTypeM2Socket3 = 0x17, + SlotTypeMxmTypeI = 0x18, + SlotTypeMxmTypeII = 0x19, + SlotTypeMxmTypeIIIStandard = 0x1A, + SlotTypeMxmTypeIIIHe = 0x1B, + SlotTypeMxmTypeIV = 0x1C, + SlotTypeMxm30TypeA = 0x1D, + SlotTypeMxm30TypeB = 0x1E, + SlotTypePciExpressGen2Sff_8639 = 0x1F, + SlotTypePciExpressGen3Sff_8639 = 0x20, + SlotTypePciExpressMini52pinWithBSKO = 0x21, + SlotTypePciExpressMini52pinWithoutBSKO = 0x22, + SlotTypePciExpressMini76pin = 0x23, + SlotTypePC98C20 = 0xA0, + SlotTypePC98C24 = 0xA1, + SlotTypePC98E = 0xA2, + SlotTypePC98LocalBus = 0xA3, + SlotTypePC98Card = 0xA4, + SlotTypePciExpress = 0xA5, + SlotTypePciExpressX1 = 0xA6, + SlotTypePciExpressX2 = 0xA7, + SlotTypePciExpressX4 = 0xA8, + SlotTypePciExpressX8 = 0xA9, + SlotTypePciExpressX16 = 0xAA, + SlotTypePciExpressGen2 = 0xAB, + SlotTypePciExpressGen2X1 = 0xAC, + SlotTypePciExpressGen2X2 = 0xAD, + SlotTypePciExpressGen2X4 = 0xAE, + SlotTypePciExpressGen2X8 = 0xAF, + SlotTypePciExpressGen2X16 = 0xB0, + SlotTypePciExpressGen3 = 0xB1, + SlotTypePciExpressGen3X1 = 0xB2, + SlotTypePciExpressGen3X2 = 0xB3, + SlotTypePciExpressGen3X4 = 0xB4, + SlotTypePciExpressGen3X8 = 0xB5, + SlotTypePciExpressGen3X16 = 0xB6 +}; + +/* System Slots - Slot Data Bus Width. */ +enum slot_data_bus_bandwidth { + SlotDataBusWidthOther = 0x01, + SlotDataBusWidthUnknown = 0x02, + SlotDataBusWidth8Bit = 0x03, + SlotDataBusWidth16Bit = 0x04, + SlotDataBusWidth32Bit = 0x05, + SlotDataBusWidth64Bit = 0x06, + SlotDataBusWidth128Bit = 0x07, + SlotDataBusWidth1X = 0x08, + SlotDataBusWidth2X = 0x09, + SlotDataBusWidth4X = 0x0A, + SlotDataBusWidth8X = 0x0B, + SlotDataBusWidth12X = 0x0C, + SlotDataBusWidth16X = 0x0D, + SlotDataBusWidth32X = 0x0E +}; + +/* System Slots - Current Usage. */ +enum misc_slot_usage { + SlotUsageOther = 0x01, + SlotUsageUnknown = 0x02, + SlotUsageAvailable = 0x03, + SlotUsageInUse = 0x04, + SlotUsageUnavailable = 0x05 +}; + +/* System Slots - Slot Length.*/ +enum misc_slot_length { + SlotLengthOther = 0x01, + SlotLengthUnknown = 0x02, + SlotLengthShort = 0x03, + SlotLengthLong = 0x04 +}; + +/* System Slots - Slot Characteristics 1. */ +#define SMBIOS_SLOT_UNKNOWN (1 << 0) +#define SMBIOS_SLOT_5V (1 << 1) +#define SMBIOS_SLOT_3P3V (1 << 2) +#define SMBIOS_SLOT_SHARED (1 << 3) +#define SMBIOS_SLOT_PCCARD_16 (1 << 4) +#define SMBIOS_SLOT_PCCARD_CARDBUS (1 << 5) +#define SMBIOS_SLOT_PCCARD_ZOOM (1 << 6) +#define SMBIOS_SLOT_PCCARD_MODEM_RING (1 << 7) +/* System Slots - Slot Characteristics 2. */ +#define SMBIOS_SLOT_PME (1 << 0) +#define SMBIOS_SLOT_HOTPLUG (1 << 1) +#define SMBIOS_SLOT_SMBUS (1 << 2) +#define SMBIOS_SLOT_BIFURCATION (1 << 3) + +struct slot_peer_groups { + u16 peer_seg_num; + u8 peer_bus_num; + u8 peer_dev_fn_num; + u8 peer_data_bus_width; +} __packed; + +struct smbios_type9 { + u8 type; + u8 length; + u16 handle; + u8 slot_designation; + u8 slot_type; + u8 slot_data_bus_width; + u8 current_usage; + u8 slot_length; + u16 slot_id; + u8 slot_characteristics_1; + u8 slot_characteristics_2; + u16 segment_group_number; + u8 bus_number; + u8 device_function_number; + u8 data_bus_width; + u8 peer_group_count; + struct slot_peer_groups peer[0]; + u8 eos[2]; +} __packed; + struct smbios_type11 { u8 type; u8 length; From ba851170fba9157b45bfdc74fe60873c187cac96 Mon Sep 17 00:00:00 2001 From: Roy Mingi Park Date: Fri, 12 Apr 2019 21:29:14 -0700 Subject: [PATCH 039/588] mb/google/sarein: Add power control for Arcada touchscreen This change will save touchscreen power leakage 2-3mW in S0iX and increase T2 display time delay to meet display panel requirement. BUG=b:129899315 TEST= Measure touchscreen power from Arcada during S0iX Change-Id: I4b8f3fdc0d107b080c5febe6fa5d29ea5d1ed0fc Signed-off-by: Roy Mingi Park Reviewed-on: https://review.coreboot.org/c/coreboot/+/32311 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 2056dd62801..57c4e65e709 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -302,8 +302,10 @@ chip soc/intel/cannonlake register "generic.desc" = ""Wacom Touchscreen"" register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C23_IRQ)" register "generic.probed" = "1" - register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" - register "generic.enable_delay_ms" = "5" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E7)" + register "generic.reset_delay_ms" = "10" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B21)" + register "generic.enable_delay_ms" = "55" register "generic.has_power_resource" = "1" register "generic.disable_gpio_export_in_crs" = "1" register "hid_desc_reg_offset" = "0x1" From 6e512c4d7a4faa68bf64b37c68bae8141d9e4518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 14 Jun 2018 06:57:05 +0300 Subject: [PATCH 040/588] soc/amd/common: Introduce agesa_execute_state() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each entrypoint to AGESA goes through the same sequence and have same the function signature. To avoid introducing bunch of preprocessor magic, rename all the agesawrapper_amdXXX() functions that are actual entrypoints to AGESA API, make them static, and provide a single exposed entry function agesa_execute_state(). Change-Id: I96ae1874132da3843aa42c2f4e8a59ec771d3893 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31483 Reviewed-by: Arthur Heymans Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- .../block/include/amdblocks/agesawrapper.h | 13 +--- .../include/amdblocks/agesawrapper_call.h | 4 +- src/soc/amd/common/block/pi/agesawrapper.c | 74 ++++++++++++++++--- src/soc/amd/common/block/pi/amd_late_init.c | 4 +- .../amd/common/block/pi/amd_resume_final.c | 2 +- src/soc/amd/common/block/s3/Makefile.inc | 4 +- src/soc/amd/stoneyridge/chip.c | 5 +- src/soc/amd/stoneyridge/northbridge.c | 2 +- src/soc/amd/stoneyridge/romstage.c | 8 +- 9 files changed, 78 insertions(+), 38 deletions(-) diff --git a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h index 2f3b8a62686..04db4242cf1 100644 --- a/src/soc/amd/common/block/include/amdblocks/agesawrapper.h +++ b/src/soc/amd/common/block/include/amdblocks/agesawrapper.h @@ -34,22 +34,11 @@ enum { /* Return current dispatcher or NULL on error. */ MODULE_ENTRY agesa_get_dispatcher(void); +AGESA_STATUS agesa_execute_state(AGESA_STRUCT_NAME func); AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams); -AGESA_STATUS agesawrapper_amdinitreset(void); -AGESA_STATUS agesawrapper_amdinitearly(void); -AGESA_STATUS agesawrapper_amdinitenv(void); -AGESA_STATUS agesawrapper_amdinitlate(void); -AGESA_STATUS agesawrapper_amdinitpost(void); -AGESA_STATUS agesawrapper_amdinitmid(void); void *agesawrapper_getlateinitptr(int pick); -AGESA_STATUS agesawrapper_amdinitrtb(void); -AGESA_STATUS agesawrapper_amdinitresume(void); -AGESA_STATUS agesawrapper_amds3laterestore(void); -AGESA_STATUS agesawrapper_amds3finalrestore(void); -AGESA_STATUS agesawrapper_fchs3earlyrestore(void); -AGESA_STATUS agesawrapper_fchs3laterestore(void); void OemCustomizeInitEarly(AMD_EARLY_PARAMS *InitEarly); void amd_initcpuio(void); diff --git a/src/soc/amd/common/block/include/amdblocks/agesawrapper_call.h b/src/soc/amd/common/block/include/amdblocks/agesawrapper_call.h index 1188f054f5b..86e32aff798 100644 --- a/src/soc/amd/common/block/include/amdblocks/agesawrapper_call.h +++ b/src/soc/amd/common/block/include/amdblocks/agesawrapper_call.h @@ -42,11 +42,11 @@ static const char *decodeAGESA_STATUS(AGESA_STATUS sret) return statusStrings[sret]; } -static inline u32 do_agesawrapper(AGESA_STATUS (*func)(void), const char *name) +static inline u32 do_agesawrapper(AGESA_STRUCT_NAME func, const char *name) { AGESA_STATUS ret; printk(BIOS_DEBUG, "agesawrapper_%s() entry\n", name); - ret = func(); + ret = agesa_execute_state(func); printk(BIOS_DEBUG, "agesawrapper_%s() returned %s\n", name, decodeAGESA_STATUS(ret)); return (u32)ret; diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index d65400e43c9..6cdabd3a6cf 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -2,7 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2012 - 2017 Advanced Micro Devices, Inc. - * Copyright (C) 2018 Kyösti Mälkki + * Copyright (C) 2018 - 2019 Kyösti Mälkki * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -88,7 +88,7 @@ static void *create_struct(AMD_INTERFACE_PARAMS *interface_struct) return interface_struct->NewStructPtr; } -AGESA_STATUS agesawrapper_amdinitreset(void) +static AGESA_STATUS amd_init_reset(void) { AGESA_STATUS status; AMD_RESET_PARAMS _ResetParams; @@ -113,7 +113,7 @@ AGESA_STATUS agesawrapper_amdinitreset(void) return status; } -AGESA_STATUS agesawrapper_amdinitearly(void) +static AGESA_STATUS amd_init_early(void) { AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -170,7 +170,7 @@ static void print_init_post_settings(AMD_POST_PARAMS *parms) uma_size / MiB, uma_start); } -AGESA_STATUS agesawrapper_amdinitpost(void) +static AGESA_STATUS amd_init_post(void) { AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -225,7 +225,7 @@ AGESA_STATUS agesawrapper_amdinitpost(void) return status; } -AGESA_STATUS agesawrapper_amdinitenv(void) +static AGESA_STATUS amd_init_env(void) { AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -275,7 +275,7 @@ void *agesawrapper_getlateinitptr(int pick) } } -AGESA_STATUS agesawrapper_amdinitmid(void) +static AGESA_STATUS amd_init_mid(void) { AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -302,7 +302,7 @@ AGESA_STATUS agesawrapper_amdinitmid(void) return status; } -AGESA_STATUS agesawrapper_amdinitlate(void) +static AGESA_STATUS amd_init_late(void) { AGESA_STATUS Status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -357,7 +357,7 @@ AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams) return AmdLateRunApTask(ApExeParams); } -AGESA_STATUS agesawrapper_amdinitrtb(void) +static AGESA_STATUS amd_init_rtb(void) { AGESA_STATUS Status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -387,7 +387,7 @@ AGESA_STATUS agesawrapper_amdinitrtb(void) return Status; } -AGESA_STATUS agesawrapper_amdinitresume(void) +static AGESA_STATUS amd_init_resume(void) { AGESA_STATUS status; AMD_INTERFACE_PARAMS AmdParamStruct = { @@ -412,7 +412,7 @@ AGESA_STATUS agesawrapper_amdinitresume(void) return status; } -AGESA_STATUS agesawrapper_amds3laterestore(void) +static AGESA_STATUS amd_s3late_restore(void) { AGESA_STATUS Status; AMD_S3LATE_PARAMS _S3LateParams; @@ -444,7 +444,7 @@ AGESA_STATUS agesawrapper_amds3laterestore(void) return Status; } -AGESA_STATUS agesawrapper_amds3finalrestore(void) +static AGESA_STATUS amd_s3final_restore(void) { AGESA_STATUS Status; AMD_S3FINAL_PARAMS _S3FinalParams; @@ -473,3 +473,55 @@ AGESA_STATUS agesawrapper_amds3finalrestore(void) return Status; } + +static AGESA_STATUS romstage_dispatch(AMD_CONFIG_PARAMS *StdHeader) +{ + switch (StdHeader->Func) { + case AMD_INIT_RESET: + return amd_init_reset(); + case AMD_INIT_EARLY: + return amd_init_early(); + case AMD_INIT_POST: + return amd_init_post(); + case AMD_INIT_RESUME: + return amd_init_resume(); + default: + return AGESA_UNSUPPORTED; + } +} + +static AGESA_STATUS ramstage_dispatch(AMD_CONFIG_PARAMS *StdHeader) +{ + switch (StdHeader->Func) { + case AMD_INIT_ENV: + return amd_init_env(); + case AMD_INIT_MID: + return amd_init_mid(); + case AMD_INIT_LATE: + return amd_init_late(); + case AMD_INIT_RTB: + return amd_init_rtb(); + case AMD_S3LATE_RESTORE: + return amd_s3late_restore(); + case AMD_S3FINAL_RESTORE: + return amd_s3final_restore(); + default: + return AGESA_UNSUPPORTED; + } +} + +AGESA_STATUS agesa_execute_state(AGESA_STRUCT_NAME func) +{ + AGESA_STATUS status = AGESA_UNSUPPORTED; + AMD_CONFIG_PARAMS template = {}; + AMD_CONFIG_PARAMS *StdHeader = &template; + + StdHeader->Func = func; + + if (ENV_ROMSTAGE) + status = romstage_dispatch(StdHeader); + if (ENV_RAMSTAGE) + status = ramstage_dispatch(StdHeader); + + return status; +} diff --git a/src/soc/amd/common/block/pi/amd_late_init.c b/src/soc/amd/common/block/pi/amd_late_init.c index fdecf005817..80c7add2614 100644 --- a/src/soc/amd/common/block/pi/amd_late_init.c +++ b/src/soc/amd/common/block/pi/amd_late_init.c @@ -179,12 +179,12 @@ static void agesawrapper_post_device(void *unused) if (acpi_is_wakeup_s3()) return; - do_agesawrapper(agesawrapper_amdinitlate, "amdinitlate"); + do_agesawrapper(AMD_INIT_LATE, "amdinitlate"); if (!acpi_s3_resume_allowed()) return; - do_agesawrapper(agesawrapper_amdinitrtb, "amdinitrtb"); + do_agesawrapper(AMD_INIT_RTB, "amdinitrtb"); } BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, agesawrapper_post_device, diff --git a/src/soc/amd/common/block/pi/amd_resume_final.c b/src/soc/amd/common/block/pi/amd_resume_final.c index a2826659d33..363ba83a0fe 100644 --- a/src/soc/amd/common/block/pi/amd_resume_final.c +++ b/src/soc/amd/common/block/pi/amd_resume_final.c @@ -18,7 +18,7 @@ static void agesawrapper_s3finalrestore(void *unused) { - do_agesawrapper(agesawrapper_amds3finalrestore, "amds3finalrestore"); + do_agesawrapper(AMD_S3FINAL_RESTORE, "amds3finalrestore"); } BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, diff --git a/src/soc/amd/common/block/s3/Makefile.inc b/src/soc/amd/common/block/s3/Makefile.inc index 7d950b0b3ad..9efc6bc4148 100644 --- a/src/soc/amd/common/block/s3/Makefile.inc +++ b/src/soc/amd/common/block/s3/Makefile.inc @@ -1,6 +1,6 @@ ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_S3),y) -romstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c -ramstage-$(CONFIG_HAVE_ACPI_RESUME) += s3_resume.c +romstage-y += s3_resume.c +ramstage-y += s3_resume.c endif diff --git a/src/soc/amd/stoneyridge/chip.c b/src/soc/amd/stoneyridge/chip.c index 1bd8cbf2f89..033af6ec211 100644 --- a/src/soc/amd/stoneyridge/chip.c +++ b/src/soc/amd/stoneyridge/chip.c @@ -163,12 +163,11 @@ static void earliest_ramstage(void *unused) psp_load_named_blob(MBOX_BIOS_CMD_SMU_FW2, "smu_fw2"); post_code(0x47); - do_agesawrapper(agesawrapper_amdinitenv, "amdinitenv"); + do_agesawrapper(AMD_INIT_ENV, "amdinitenv"); } else { /* Complete the initial system restoration */ post_code(0x46); - do_agesawrapper(agesawrapper_amds3laterestore, - "amds3laterestore"); + do_agesawrapper(AMD_S3LATE_RESTORE, "amds3laterestore"); } } diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c index 927cce0c1f7..9380d1f945f 100644 --- a/src/soc/amd/stoneyridge/northbridge.c +++ b/src/soc/amd/stoneyridge/northbridge.c @@ -391,7 +391,7 @@ void domain_enable_resources(struct device *dev) { /* Must be called after PCI enumeration and resource allocation */ if (!romstage_handoff_is_resume()) - do_agesawrapper(agesawrapper_amdinitmid, "amdinitmid"); + do_agesawrapper(AMD_INIT_MID, "amdinitmid"); } void domain_set_resources(struct device *dev) diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c index f2263b7aa91..92922c0662c 100644 --- a/src/soc/amd/stoneyridge/romstage.c +++ b/src/soc/amd/stoneyridge/romstage.c @@ -65,11 +65,11 @@ static void load_smu_fw1(void) static void agesa_call(void) { post_code(0x37); - do_agesawrapper(agesawrapper_amdinitreset, "amdinitreset"); + do_agesawrapper(AMD_INIT_RESET, "amdinitreset"); post_code(0x38); /* APs will not exit amdinitearly */ - do_agesawrapper(agesawrapper_amdinitearly, "amdinitearly"); + do_agesawrapper(AMD_INIT_EARLY, "amdinitearly"); } static void bsp_agesa_call(void) @@ -102,7 +102,7 @@ asmlinkage void car_stage_entry(void) if (!s3_resume) { post_code(0x40); - do_agesawrapper(agesawrapper_amdinitpost, "amdinitpost"); + do_agesawrapper(AMD_INIT_POST, "amdinitpost"); post_code(0x41); /* @@ -137,7 +137,7 @@ asmlinkage void car_stage_entry(void) } else { printk(BIOS_INFO, "S3 detected\n"); post_code(0x60); - do_agesawrapper(agesawrapper_amdinitresume, "amdinitresume"); + do_agesawrapper(AMD_INIT_RESUME, "amdinitresume"); post_code(0x61); } From 63bc18e3285bf00d3239d89bc0c4cad97cbbc383 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 28 Jun 2018 22:12:20 +0300 Subject: [PATCH 041/588] soc/amd/common: Remove AmdReadEventLog() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parameter passing is incorrect here, it should pass complete StdHeader instead of attempting to fill in HeapStatus that should be treated as a field private to AGESA, based on where it is defined in the header files. Furthermore the while() loop did not evaluate the return value. Feature can be brought back at a later date after someone verifies it actually works correctly across different stages. Change-Id: Ib243b275f8700ecaeb330772c795d305c61899c5 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31484 Reviewed-by: Arthur Heymans Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/pi/agesawrapper.c | 58 ------------------- .../amd/pi/00670F00/binaryPI/AGESA.c | 14 ----- 2 files changed, 72 deletions(-) diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index 6cdabd3a6cf..0570b5a3ee2 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -41,34 +41,6 @@ static void *AcpiAlib; static void *AcpiIvrs; static void *AcpiCrat; -static AGESA_STATUS agesawrapper_readeventlog(uint8_t HeapStatus) -{ - AGESA_STATUS Status; - EVENT_PARAMS AmdEventParams = { - .StdHeader.CalloutPtr = &GetBiosCallout, - .StdHeader.HeapStatus = HeapStatus, - }; - - Status = AmdReadEventLog(&AmdEventParams); - if (AmdEventParams.EventClass) - printk(BIOS_DEBUG, "AGESA Event Log:\n"); - - while (AmdEventParams.EventClass != 0) { - printk(BIOS_DEBUG, " Class = %x, Info = %x," - " Param1 = 0x%x, Param2 = 0x%x" - " Param3 = 0x%x, Param4 = 0x%x\n", - (u32)AmdEventParams.EventClass, - (u32)AmdEventParams.EventInfo, - (u32)AmdEventParams.DataParam1, - (u32)AmdEventParams.DataParam2, - (u32)AmdEventParams.DataParam3, - (u32)AmdEventParams.DataParam4); - Status = AmdReadEventLog(&AmdEventParams); - } - - return Status; -} - static void *create_struct(AMD_INTERFACE_PARAMS *interface_struct) { /* Should clone entire StdHeader here. */ @@ -107,8 +79,6 @@ static AGESA_STATUS amd_init_reset(void) status = AmdInitReset(ResetParams); timestamp_add_now(TS_AGESA_INIT_RESET_DONE); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; } @@ -130,8 +100,6 @@ static AGESA_STATUS amd_init_early(void) status = AmdInitEarly(EarlyParams); timestamp_add_now(TS_AGESA_INIT_EARLY_DONE); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; @@ -218,8 +186,6 @@ static AGESA_STATUS amd_init_post(void) print_init_post_settings(PostParams); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(PostParams->StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; @@ -242,8 +208,6 @@ static AGESA_STATUS amd_init_env(void) status = AmdInitEnv(EnvParams); timestamp_add_now(TS_AGESA_INIT_ENV_DONE); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(EnvParams->StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; @@ -295,8 +259,6 @@ static AGESA_STATUS amd_init_mid(void) status = AmdInitMid(MidParams); timestamp_add_now(TS_AGESA_INIT_MID_DONE); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; @@ -327,11 +289,6 @@ static AGESA_STATUS amd_init_late(void) Status = AmdInitLate(LateParams); timestamp_add_now(TS_AGESA_INIT_LATE_DONE); - if (Status != AGESA_SUCCESS) { - agesawrapper_readeventlog(LateParams->StdHeader.HeapStatus); - ASSERT(Status == AGESA_SUCCESS); - } - DmiTable = LateParams->DmiTable; AcpiPstate = LateParams->AcpiPState; @@ -371,11 +328,6 @@ static AGESA_STATUS amd_init_rtb(void) Status = AmdInitRtb(RtbParams); timestamp_add_now(TS_AGESA_INIT_RTB_DONE); - if (Status != AGESA_SUCCESS) { - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); - ASSERT(Status == AGESA_SUCCESS); - } - if (save_s3_info(RtbParams->S3DataBlock.NvStorage, RtbParams->S3DataBlock.NvStorageSize, RtbParams->S3DataBlock.VolatileStorage, @@ -405,8 +357,6 @@ static AGESA_STATUS amd_init_resume(void) status = AmdInitResume(InitResumeParams); timestamp_add_now(TS_AGESA_INIT_RESUME_DONE); - if (status != AGESA_SUCCESS) - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); AmdReleaseStruct(&AmdParamStruct); return status; @@ -435,10 +385,6 @@ static AGESA_STATUS amd_s3late_restore(void) Status = AmdS3LateRestore(S3LateParams); timestamp_add_now(TS_AGESA_S3_LATE_DONE); - if (Status != AGESA_SUCCESS) { - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); - ASSERT(Status == AGESA_SUCCESS); - } AmdReleaseStruct(&AmdParamStruct); return Status; @@ -465,10 +411,6 @@ static AGESA_STATUS amd_s3final_restore(void) Status = AmdS3FinalRestore(S3FinalParams); timestamp_add_now(TS_AGESA_S3_FINAL_DONE); - if (Status != AGESA_SUCCESS) { - agesawrapper_readeventlog(AmdParamStruct.StdHeader.HeapStatus); - ASSERT(Status == AGESA_SUCCESS); - } AmdReleaseStruct(&AmdParamStruct); return Status; diff --git a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c index c42df59bd41..2efee4eb62e 100644 --- a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c +++ b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c @@ -226,17 +226,3 @@ AmdLateRunApTask ( if (!Dispatcher) return AGESA_UNSUPPORTED; return Dispatcher(AmdApExeParams); } - -/********************************************************************** - * Interface service call: AmdReadEventLog - **********************************************************************/ -AGESA_STATUS -AmdReadEventLog ( - IN EVENT_PARAMS *Event -) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - Event->StdHeader.Func = AMD_READ_EVENT_LOG; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(Event); -} From d893a2635fdd02e3fc12021aa4b0200a30d5a0de Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 19 Dec 2018 16:54:06 +0100 Subject: [PATCH 042/588] sb/intel/lynxpoint: Enable LPC/SIO setup in bootblock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows for serial console during the bootblock and enables console in general for the bootblock. Change-Id: I5c6e107c267a7acb5bf9cbeb54eb5361af3b6db4 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30315 Reviewed-by: Duncan Laurie Reviewed-by: Patrick Rudolph Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/mainboard/asrock/h81m-hds/Makefile.inc | 1 + src/mainboard/asrock/h81m-hds/bootblock.c | 50 ++++++++++++++++++++ src/mainboard/asrock/h81m-hds/romstage.c | 31 ------------ src/northbridge/intel/haswell/Kconfig | 2 +- src/southbridge/intel/lynxpoint/Makefile.inc | 1 + src/southbridge/intel/lynxpoint/bootblock.c | 3 ++ src/southbridge/intel/lynxpoint/early_pch.c | 5 -- 7 files changed, 56 insertions(+), 37 deletions(-) create mode 100644 src/mainboard/asrock/h81m-hds/bootblock.c diff --git a/src/mainboard/asrock/h81m-hds/Makefile.inc b/src/mainboard/asrock/h81m-hds/Makefile.inc index 7c1bf9ecd4b..de18bc5aa80 100644 --- a/src/mainboard/asrock/h81m-hds/Makefile.inc +++ b/src/mainboard/asrock/h81m-hds/Makefile.inc @@ -16,3 +16,4 @@ romstage-y += gpio.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +bootblock-y += bootblock.c diff --git a/src/mainboard/asrock/h81m-hds/bootblock.c b/src/mainboard/asrock/h81m-hds/bootblock.c new file mode 100644 index 00000000000..7a841b84aa7 --- /dev/null +++ b/src/mainboard/asrock/h81m-hds/bootblock.c @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2010 coresystems GmbH + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2018 Tristan Corrick + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +void mainboard_config_superio(void) +{ + const pnp_devfn_t GLOBAL_PSEUDO_DEV = PNP_DEV(0x2e, 0); + const pnp_devfn_t SERIAL_DEV = PNP_DEV(0x2e, NCT6776_SP1); + const pnp_devfn_t ACPI_DEV = PNP_DEV(0x2e, NCT6776_ACPI); + const pnp_devfn_t IR_DEV = PNP_DEV(0x2e, NCT6776_SP2); + + nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); + + nuvoton_pnp_enter_conf_state(GLOBAL_PSEUDO_DEV); + + /* Select HWM/LED functions instead of floppy functions. */ + pnp_write_config(GLOBAL_PSEUDO_DEV, 0x1c, 0x03); + pnp_write_config(GLOBAL_PSEUDO_DEV, 0x24, 0x24); + + /* Power RAM in S3 and let the PCH handle power failure actions. */ + pnp_set_logical_device(ACPI_DEV); + pnp_write_config(ACPI_DEV, 0xe4, 0x70); + + /* + * Don't know what's needed here, just set the same as the vendor + * firmware. + */ + pnp_set_logical_device(IR_DEV); + pnp_write_config(IR_DEV, 0xf1, 0x5c); + + nuvoton_pnp_exit_conf_state(GLOBAL_PSEUDO_DEV); +} diff --git a/src/mainboard/asrock/h81m-hds/romstage.c b/src/mainboard/asrock/h81m-hds/romstage.c index a9177223063..3af82f2907b 100644 --- a/src/mainboard/asrock/h81m-hds/romstage.c +++ b/src/mainboard/asrock/h81m-hds/romstage.c @@ -23,8 +23,6 @@ #include #include #include -#include -#include static const struct rcba_config_instruction rcba_config[] = { RCBA_SET_REG_16(D31IR, DIR_ROUTE(PIRQA, PIRQD, PIRQC, PIRQA)), @@ -41,35 +39,6 @@ static const struct rcba_config_instruction rcba_config[] = { RCBA_END_CONFIG, }; -void mainboard_config_superio(void) -{ - const pnp_devfn_t GLOBAL_PSEUDO_DEV = PNP_DEV(0x2e, 0); - const pnp_devfn_t SERIAL_DEV = PNP_DEV(0x2e, NCT6776_SP1); - const pnp_devfn_t ACPI_DEV = PNP_DEV(0x2e, NCT6776_ACPI); - const pnp_devfn_t IR_DEV = PNP_DEV(0x2e, NCT6776_SP2); - - nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); - - nuvoton_pnp_enter_conf_state(GLOBAL_PSEUDO_DEV); - - /* Select HWM/LED functions instead of floppy functions. */ - pnp_write_config(GLOBAL_PSEUDO_DEV, 0x1c, 0x03); - pnp_write_config(GLOBAL_PSEUDO_DEV, 0x24, 0x24); - - /* Power RAM in S3 and let the PCH handle power failure actions. */ - pnp_set_logical_device(ACPI_DEV); - pnp_write_config(ACPI_DEV, 0xe4, 0x70); - - /* - * Don't know what's needed here, just set the same as the vendor - * firmware. - */ - pnp_set_logical_device(IR_DEV); - pnp_write_config(IR_DEV, 0xf1, 0x5c); - - nuvoton_pnp_exit_conf_state(GLOBAL_PSEUDO_DEV); -} - void mainboard_romstage_entry(unsigned long bist) { struct pei_data pei_data = { diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig index e0c55d2f929..49466bc569f 100644 --- a/src/northbridge/intel/haswell/Kconfig +++ b/src/northbridge/intel/haswell/Kconfig @@ -23,7 +23,7 @@ config NORTHBRIDGE_INTEL_HASWELL select POSTCAR_STAGE select POSTCAR_CONSOLE select C_ENVIRONMENT_BOOTBLOCK -# select BOOTBLOCK_CONSOLE TODO: route LPC + select BOOTBLOCK_CONSOLE if NORTHBRIDGE_INTEL_HASWELL diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index fd00f6c50e0..04e0bc9909a 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -46,6 +46,7 @@ ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c pmutil.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c pch.c smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c usb_ehci.c usb_xhci.c +bootblock-y += early_pch.c romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c romstage-y += early_spi.c rcba.c pmutil.c diff --git a/src/southbridge/intel/lynxpoint/bootblock.c b/src/southbridge/intel/lynxpoint/bootblock.c index 69fdd611d2c..39e69257eb8 100644 --- a/src/southbridge/intel/lynxpoint/bootblock.c +++ b/src/southbridge/intel/lynxpoint/bootblock.c @@ -79,4 +79,7 @@ void bootblock_early_southbridge_init(void) /* Enable upper 128bytes of CMOS */ RCBA32(RC) = (1 << 2); + + pch_enable_lpc(); + mainboard_config_superio(); } diff --git a/src/southbridge/intel/lynxpoint/early_pch.c b/src/southbridge/intel/lynxpoint/early_pch.c index f615507dade..c36257747d2 100644 --- a/src/southbridge/intel/lynxpoint/early_pch.c +++ b/src/southbridge/intel/lynxpoint/early_pch.c @@ -104,8 +104,6 @@ int early_pch_init(const void *gpio_map, { int wake_from_s3; - pch_enable_lpc(); - pch_enable_bars(); #if CONFIG(INTEL_LYNXPOINT_LP) @@ -113,9 +111,6 @@ int early_pch_init(const void *gpio_map, #else setup_pch_gpios(gpio_map); #endif - - mainboard_config_superio(); - pch_generic_setup(); /* Enable SMBus for reading SPDs. */ From 420d7e009decb93b4d2499cf6d8f6100163eecac Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 21 Apr 2019 18:39:34 +0200 Subject: [PATCH 043/588] ich7/i945: Use full_reset() For full reset, use already defined full_reset() function. Change-Id: Iec7dcf285f3cb1cdc8f48d348ff8496879625db5 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32377 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/northbridge/intel/i945/raminit.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index be3d17a2fd9..d41b913ab16 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -272,9 +273,7 @@ static void sdram_detect_errors(struct sys_info *sysinfo) if (do_reset) { printk(BIOS_DEBUG, "Reset required.\n"); - outb(0x00, 0xcf9); - outb(0x0e, 0xcf9); - halt(); /* Wait for reset! */ + full_reset(); } } @@ -303,9 +302,7 @@ static void sdram_detect_errors(struct sys_info *sysinfo) if (do_reset) { printk(BIOS_DEBUG, "Reset required.\n"); - outb(0x00, 0xcf9); - outb(0x0e, 0xcf9); - halt(); /* Wait for reset! */ + full_reset(); } } From d6d6771b97f9f21c8758c102498e375e8f684f69 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 21 Apr 2019 16:49:14 -0500 Subject: [PATCH 044/588] sb/intel/bd82x6x: fix linking for non-native raminit case Commit 45d4b17 [nb/intel/sandybridge: Move southbridge code to bd82x6x] moved early_pch_init() to the southbridge, but failed to include early_pch.c for the non-native raminit case, which now fails to link. As all boards default to native raminit, this was missed by the autobuilder. Adjust early_pch.c to be compiled regardles of ram init type used Test: build/boot google/stout with MRC ram init selected Change-Id: I50db30fda9a1099fb434c04ea97bcc38f8455233 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32382 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Arthur Heymans --- src/southbridge/intel/bd82x6x/Makefile.inc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index 7ce3da70adf..a950e5ce5db 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -40,9 +40,10 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c pch.c romstage-y += early_smbus.c me_status.c romstage-y += early_spi.c romstage-y += early_rcba.c +romstage-y += early_pch.c ifeq ($(CONFIG_USE_NATIVE_RAMINIT),y) -romstage-y += early_thermal.c early_pch.c early_me.c early_usb.c +romstage-y += early_thermal.c early_me.c early_usb.c else romstage-y += early_me_mrc.c early_usb_mrc.c endif From 01912201a4ad176dbcf0244c96a53865ef2fcaa0 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 19 Jan 2019 16:36:38 +0100 Subject: [PATCH 045/588] nb/intel/i945: Check if interleaved even if rank #4 size is zero Tested config: Interleaved (config; status before, after): DIMM{0 + 2}: ok, ok DIMM{0 + 3}: Nok, ok DIMM{1 + 2}: ok, ok DIMM{1 + 3}: Nok, ok DIMM{1 + 2 + 3}: ok, ok DIMM{0 + 2 + 3}: ok, ok DIMM{0 + 1 + 2}: ok, ok DIMM{0 + 1 + 3}: Nok, ok Not Interleaved: DIMM{0 + 1 + 3}: Nok, Nok DIMM{0 + 1 + 2}: ok, ok (with single ranked) DIMM{0 + 1 + 2}: Nok, Nok (with only dual ranked) DIMM{0 + 2 + 3}: Nok, ok DIMM{1 + 2 + 3}: ok, ok Change-Id: Ibf130a3d4b6f8fa816f7a5f06822a9b8807be3d4 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31007 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/i945/raminit.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index d41b913ab16..1e8cf655814 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -2546,29 +2546,19 @@ static void sdram_jedec_enable(struct sys_info *sysinfo) u32 bankaddr = 0, tmpaddr, mrsaddr = 0; for (i = 0, nonzero = -1; i < 8; i++) { - if (sysinfo->banksize[i] == 0) + if (sysinfo->banksize[i] == 0) continue; printk(BIOS_DEBUG, "jedec enable sequence: bank %d\n", i); - switch (i) { - case 0: - /* Start at address 0 */ - bankaddr = 0; - break; - case 4: - if (sysinfo->interleaved) { + + if (nonzero != -1) { + if (sysinfo->interleaved && nonzero < 4 && i >= 4) { bankaddr = 0x40; - break; - } - default: - if (nonzero != -1) { + } else { printk(BIOS_DEBUG, "bankaddr from bank size of rank %d\n", nonzero); bankaddr += sysinfo->banksize[nonzero] << (sysinfo->interleaved ? 26 : 25); - break; } - /* No populated bank hit before. Start at address 0 */ - bankaddr = 0; } /* We have a bank with a non-zero size.. Remember it From 3c61304a9f39fe25421d64b00e35631478d6456c Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 21 Apr 2019 23:59:47 +0200 Subject: [PATCH 046/588] arch/x86/car.ld: Make the vboot tpm log symbols conditional Without VBOOT_MEASURED_BOOT there is no need for these symbols. Change-Id: I96391b7817c79f760713c67bc469164b5514879e Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32383 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Patrick Georgi --- src/arch/x86/car.ld | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld index d97df19a376..7b20a14f215 100644 --- a/src/arch/x86/car.ld +++ b/src/arch/x86/car.ld @@ -34,7 +34,9 @@ /* Vboot measured boot TCPA log measurements. * Needs to be transferred until CBMEM is available */ +#if CONFIG(VBOOT_MEASURED_BOOT) VBOOT2_TPM_LOG(., 2K) +#endif /* Stack for CAR stages. Since it persists across all stages that * use CAR it can be reused. The chipset/SoC is expected to provide * the stack size. */ From c58525ee46ef40f64d7be675bb273493306f8567 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 22 Apr 2019 00:01:39 +0200 Subject: [PATCH 047/588] configs: Add a target to buildtest the ivybridge mrc.bin bootpath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iff15e9586cd3e39850d986582b5943cbb8a184a7 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32384 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- configs/config.lenovo_x220_mrc_bin | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 configs/config.lenovo_x220_mrc_bin diff --git a/configs/config.lenovo_x220_mrc_bin b/configs/config.lenovo_x220_mrc_bin new file mode 100644 index 00000000000..a51c4989049 --- /dev/null +++ b/configs/config.lenovo_x220_mrc_bin @@ -0,0 +1,3 @@ +CONFIG_VENDOR_LENOVO=y +CONFIG_BOARD_LENOVO_X220=y +# CONFIG_USE_NATIVE_RAMINIT is not set From 31438f73c043c1d33b9e054f9fd76260630a3595 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 15 Feb 2019 13:21:42 +0100 Subject: [PATCH 048/588] cpu/intel/speedstep/acpi: Use get_ia32_fsb_x3() function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ie8c5d5f7dd5b43becc144fd5e62d7de2f1ed3b80 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31432 Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/cpu/intel/speedstep/acpi.c | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) diff --git a/src/cpu/intel/speedstep/acpi.c b/src/cpu/intel/speedstep/acpi.c index 5cff4125ae1..7111f5efd5e 100644 --- a/src/cpu/intel/speedstep/acpi.c +++ b/src/cpu/intel/speedstep/acpi.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -40,29 +41,6 @@ static int determine_total_number_of_cores(void) return count; } -/** - * @brief Returns three times the FSB clock in MHz - * - * The result of calculations with the returned value shall be divided by 3. - * This helps to avoid rounding errors. - */ -static int get_fsb(void) -{ - const u32 fsbcode = rdmsr(MSR_FSB_FREQ).lo & 7; - switch (fsbcode) { - case 0: return 800; /* / 3 == 266 */ - case 1: return 400; /* / 3 == 133 */ - case 2: return 600; /* / 3 == 200 */ - case 3: return 500; /* / 3 == 166 */ - case 4: return 1000; /* / 3 == 333 */ - case 5: return 300; /* / 3 == 100 */ - case 6: return 1200; /* / 3 == 400 */ - } - printk(BIOS_WARNING, - "Warning: No supported FSB frequency. Assuming 200MHz\n"); - return 600; -} - static void gen_pstate_entries(const sst_table_t *const pstates, const int cpuID, const int cores_per_package, const uint8_t coordination) @@ -75,7 +53,12 @@ static void gen_pstate_entries(const sst_table_t *const pstates, cpuID, cores_per_package, coordination); acpigen_write_name("_PSS"); - const int fsb3 = get_fsb(); + int fsb3 = get_ia32_fsb_x3(); + if (fsb3 <= 0) { + printk(BIOS_ERR, "CPU or FSB not supported. Assuming 200MHz\n"); + fsb3 = 600; + } + const int min_ratio2 = SPEEDSTEP_DOUBLE_RATIO( pstates->states[pstates->num_states - 1]); const int max_ratio2 = SPEEDSTEP_DOUBLE_RATIO(pstates->states[0]); From c5d734b3f9a8cc2e6df8f5e6c111f0fe32201ad3 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Fri, 19 Apr 2019 16:57:46 -0700 Subject: [PATCH 049/588] soc/intel/common/acpi: Add dynamic method around sleep Declare plaform level hook method before and after system sleep for possible power management related usage. BUG=N/A TEST=pass with make what-jenkins-does Signed-off-by: Lijian Zhao Change-Id: Ie63711748b6dbb99d34910824f2059464543e162 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32366 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/soc/intel/common/acpi/platform.asl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/soc/intel/common/acpi/platform.asl b/src/soc/intel/common/acpi/platform.asl index bdc0d5c15c9..8b85d440578 100644 --- a/src/soc/intel/common/acpi/platform.asl +++ b/src/soc/intel/common/acpi/platform.asl @@ -17,6 +17,9 @@ #include +External(\_SB.MPTS, MethodObj) +External(\_SB.MWAK, MethodObj) + /* Port 80 POST */ OperationRegion (POST, SystemIO, CONFIG_POST_IO_PORT, 1) @@ -38,6 +41,10 @@ Method (_PTS, 1) /* Call EC _PTS handler */ \_SB.PCI0.LPCB.EC0.PTS (Arg0) #endif + If (CondRefOf (\_SB.MPTS)) + { + \_SB.MPTS (Arg0) + } } /* The _WAK method is called on system wakeup */ @@ -46,6 +53,11 @@ Method (_WAK, 1) { Store (POST_OS_ENTER_WAKE, DBG0) + If (CondRefOf (\_SB.MWAK)) + { + \_SB.MWAK (Arg0) + } + #if CONFIG(SOC_INTEL_COMMON_ACPI_EC_PTS_WAK) /* Call EC _WAK handler */ \_SB.PCI0.LPCB.EC0.WAK (Arg0) From 00dbf449c929933d7cdb31140d609269c68d3671 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 19 Apr 2019 14:02:02 -0600 Subject: [PATCH 050/588] coreboot: Run mainboard specific code before Cr50 reset When coreboot checks the TPM and key-ladder state it issues a reboot of the Cr50 with a delay parameter. Older Cr50 code doesn't support the delay parameter and reboots immediately, which prevented coreboot from running the mainboard specific code needed for the AP to come back up. This change calls mainboard_prepare_cr50_reset() prior to sending the VENDOR_CC_IMMEDIATE_RESET command. This change also fixes a false error message from the coreboot log that indicated "Unexpected Cr50 TPM mode 3" when the Cr50 key ladder is disabled. BUG=b:130830178 BRANCH=none TEST=build coreboot on sarien and grunt platforms. TEST=Load Cr50 v3.15, run 'gsctool -a -m disable; reboot'. Verify corebot send the VENDOR_CC_IMMEDIATE_RESET command and that the AP boots normally. Verify event log shows "cr50 Reset Required" TEST=Force Cr50 automatic update. Verify event log shows "cr50 Update Reset". Change-Id: Ib05c9cfde8e87daffd4233114263de5b30822872 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32365 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../google/chromeos/cr50_enable_update.c | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/vendorcode/google/chromeos/cr50_enable_update.c b/src/vendorcode/google/chromeos/cr50_enable_update.c index 91a10cb9aad..f2cdbfd39c5 100644 --- a/src/vendorcode/google/chromeos/cr50_enable_update.c +++ b/src/vendorcode/google/chromeos/cr50_enable_update.c @@ -23,7 +23,7 @@ #include #include -#define C50_RESET_DELAY_MS 1000 +#define CR50_RESET_DELAY_MS 1000 void __weak mainboard_prepare_cr50_reset(void) {} @@ -31,12 +31,11 @@ void __weak mainboard_prepare_cr50_reset(void) {} * Check if the Cr50 TPM state requires a chip reset of the Cr50 device. * * Returns 0 if the Cr50 TPM state is good or if the TPM_MODE command is - * unsupported. Returns 1 if the Cr50 was reset. + * unsupported. Returns 1 if the Cr50 requires a reset. */ -static int cr50_reset_if_needed(uint16_t timeout_ms) +static int cr50_is_reset_needed(void) { int ret; - int cr50_must_reset = 0; uint8_t tpm_mode; ret = tlcl_cr50_get_tpm_mode(&tpm_mode); @@ -53,7 +52,7 @@ static int cr50_reset_if_needed(uint16_t timeout_ms) * Cr50 indicated a reboot is required to restore TPM * functionality. */ - cr50_must_reset = 1; + return 1; } else if (ret != TPM_SUCCESS) { /* TPM command failed, continue booting. */ printk(BIOS_ERR, @@ -61,7 +60,8 @@ static int cr50_reset_if_needed(uint16_t timeout_ms) return 0; } - /* If the TPM mode is not enabled-tentative, then the TPM mode is locked + /* + * If the TPM mode is not enabled-tentative, then the TPM mode is locked * and cannot be changed. Perform a Cr50 reset because vboot may need * to disable TPM as part of booting an untrusted OS. * @@ -72,30 +72,17 @@ static int cr50_reset_if_needed(uint16_t timeout_ms) printk(BIOS_NOTICE, "NOTICE: Unexpected Cr50 TPM mode (%d). " "A Cr50 reset is required.\n", tpm_mode); - cr50_must_reset = 1; + return 1; } /* If TPM state is okay, no reset needed. */ - if (!cr50_must_reset) - return 0; - - ret = tlcl_cr50_immediate_reset(timeout_ms); - - if (ret != TPM_SUCCESS) { - /* TPM command failed, continue booting. */ - printk(BIOS_ERR, - "ERROR: Attempt to reset CR50 failed: %x\n", - ret); - return 0; - } - - /* Cr50 is about to be reset, caller needs to prepare */ - return 1; + return 0; } static void enable_update(void *unused) { int ret; + int cr50_reset_reqd = 0; uint8_t num_restored_headers; /* Nothing to do on recovery mode. */ @@ -112,7 +99,7 @@ static void enable_update(void *unused) } /* Reboot in 1000 ms if necessary. */ - ret = tlcl_cr50_enable_update(C50_RESET_DELAY_MS, + ret = tlcl_cr50_enable_update(CR50_RESET_DELAY_MS, &num_restored_headers); if (ret != TPM_SUCCESS) { @@ -134,9 +121,10 @@ static void enable_update(void *unused) */ /* - * If the Cr50 was not reset, continue booting. + * If the Cr50 doesn't requires a reset, continue booting. */ - if (!cr50_reset_if_needed(C50_RESET_DELAY_MS)) + cr50_reset_reqd = cr50_is_reset_needed(); + if (!cr50_reset_reqd) return; printk(BIOS_INFO, "Waiting for CR50 reset to enable TPM.\n"); @@ -153,6 +141,27 @@ static void enable_update(void *unused) /* clear current post code avoid chatty eventlog on subsequent boot*/ post_code(0); + /* + * Older Cr50 firmware doesn't support the timeout parameter for the + * immediate reset request, so the reset request must be sent after + * the mainboard specific code runs. + */ + if (cr50_reset_reqd) { + ret = tlcl_cr50_immediate_reset(CR50_RESET_DELAY_MS); + + if (ret != TPM_SUCCESS) { + /* + * Reset request failed due to TPM error, continue + * booting but the current boot will likely end up at + * the recovery screen. + */ + printk(BIOS_ERR, + "ERROR: Attempt to reset CR50 failed: %x\n", + ret); + return; + } + } + if (CONFIG(POWER_OFF_ON_CR50_UPDATE)) poweroff(); halt(); From d61c5ea7f5cc87a58db3d0d004b94dfab3897ac1 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Mon, 22 Apr 2019 12:18:02 +0200 Subject: [PATCH 051/588] linuxboot/Kconfig: Remove symbol name of a `choice` Kconfig somehow adds spurious booleans for each alternative when the choice itself has a name. That's fixed simply by removing the name. Change-Id: Ic35f0697f1f7bb92c12414c17a8790464b376012 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32390 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- payloads/external/LinuxBoot/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/external/LinuxBoot/Kconfig b/payloads/external/LinuxBoot/Kconfig index ccf62b82371..84af49ccc0a 100644 --- a/payloads/external/LinuxBoot/Kconfig +++ b/payloads/external/LinuxBoot/Kconfig @@ -123,7 +123,7 @@ config LINUXBOOT_KERNEL_CONFIGFILE Note: this can be a defconfig file or a complete .config file. -choice LINUXBOOT_KERNEL_FORMAT +choice prompt "Kernel binary format" default LINUXBOOT_KERNEL_BZIMAGE if LINUXBOOT_X86 || LINUXBOOT_X86_64 default LINUXBOOT_KERNEL_UIMAGE if LINUXBOOT_ARM64 From 19fcc89fe085fad2e7aba52375b4190463667fdb Mon Sep 17 00:00:00 2001 From: T Michael Turney Date: Wed, 20 Mar 2019 14:37:34 -0700 Subject: [PATCH 052/588] lib/fmap: Add area read/write functions Change-Id: I7669b8dc07b1aa5f00e7d8d0b1305b3de6c5949c Signed-off-by: T Michael Turney Reviewed-on: https://review.coreboot.org/c/coreboot/+/32287 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/include/fmap.h | 8 ++++++++ src/lib/fmap.c | 22 ++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/include/fmap.h b/src/include/fmap.h index 5834831489a..ab7e5ab8956 100644 --- a/src/include/fmap.h +++ b/src/include/fmap.h @@ -40,4 +40,12 @@ int fmap_locate_area(const char *name, struct region *r); * Return 0 on success, < 0 on error. */ int fmap_find_region_name(const struct region * const ar, char name[FMAP_STRLEN]); + +/* Read fmap area into provided buffer. + * Return size read on success, < 0 on error. */ +ssize_t fmap_read_area(const char *name, void *buffer, size_t size); + +/* Write provided buffer into fmap area. + * Return size written on success, < 0 on error. */ +ssize_t fmap_overwrite_area(const char *name, const void *buffer, size_t size); #endif diff --git a/src/lib/fmap.c b/src/lib/fmap.c index 9602134d942..2b4e3bae2c6 100644 --- a/src/lib/fmap.c +++ b/src/lib/fmap.c @@ -173,3 +173,25 @@ int fmap_find_region_name(const struct region * const ar, return -1; } + +ssize_t fmap_read_area(const char *name, void *buffer, size_t size) +{ + struct region_device rdev; + if (fmap_locate_area_as_rdev(name, &rdev)) + return -1; + return rdev_readat(&rdev, buffer, 0, + MIN(size, region_device_sz(&rdev))); +} + +ssize_t fmap_overwrite_area(const char *name, const void *buffer, size_t size) +{ + struct region_device rdev; + + if (fmap_locate_area_as_rdev_rw(name, &rdev)) + return -1; + if (size > region_device_sz(&rdev)) + return -1; + if (rdev_eraseat(&rdev, 0, region_device_sz(&rdev)) < 0) + return -1; + return rdev_writeat(&rdev, buffer, 0, size); +} From e28fa4049d6a9c584bdf499fbaee2ee459b40118 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 14 Feb 2019 11:19:07 +0100 Subject: [PATCH 053/588] cbfstool: Fix cbfs_file_next_attr The last attribute was never returned. Fix size compare to retrieve all attributes. Manually tested and seen all attributes, including the last one. Change-Id: I08df073158a0f285f96048c92aa8066fa4f57e6f Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/31494 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner Reviewed-by: Furquan Shaikh --- util/cbfstool/cbfs_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index 6ccc4f904ed..5ff81309f41 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -1844,7 +1844,7 @@ struct cbfs_file_attribute *cbfs_file_next_attr(struct cbfs_file *file, /* Is there enough space for another attribute? */ if ((uint8_t *)attr + ntohl(attr->len) + - sizeof(struct cbfs_file_attribute) >= + sizeof(struct cbfs_file_attribute) > (uint8_t *)file + ntohl(file->offset)) return NULL; From 39c3d3951a83b59744b4a6ce91031bda13f4f493 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 23 Apr 2019 12:27:22 +0200 Subject: [PATCH 054/588] soc/intel/cannonlake: add missing console.h include Change-Id: Ic23eb57a4096d4301d7f9478d8e65aaeb233de7b Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32399 Reviewed-by: Arthur Heymans --- src/soc/intel/cannonlake/acpi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c index 43d91d3f83e..19469dc94fa 100644 --- a/src/soc/intel/cannonlake/acpi.c +++ b/src/soc/intel/cannonlake/acpi.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include From 27fbbcffc53d1a4df8b47aaa50c85f85c93b8e40 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 23 Apr 2019 12:33:23 +0200 Subject: [PATCH 055/588] nb/intel/sandybridge: add pch.h include Fixes src/northbridge/intel/sandybridge/raminit_mrc.c:286:3: error: implicit declaration of function 'enable_usb_bar' Change-Id: I48bf59c56b518477a3fc0d75902fc58df6b7def7 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32400 Reviewed-by: Arthur Heymans Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/raminit_mrc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index 852da7aa264..8c4f27d9fcb 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -33,6 +33,7 @@ #include "pei_data.h" #include "sandybridge.h" #include +#include /* Management Engine is in the southbridge */ #include From 3ee485741bede7535377ef10516596524f8008a8 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 28 Mar 2019 16:54:15 +0530 Subject: [PATCH 056/588] qcs405: clock: Update SPI API Update SPI enable/disable and configure clock API for supporting all the blsp and qup for qcs405. Change-Id: I39622571cb671f62312283a010129ceecb654f61 Signed-off-by: Shefali Jain Signed-off-by: Taniya Das Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/32240 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/soc/qualcomm/qcs405/clock.c | 101 +++++++++++++++----- src/soc/qualcomm/qcs405/include/soc/clock.h | 43 ++++++--- 2 files changed, 109 insertions(+), 35 deletions(-) diff --git a/src/soc/qualcomm/qcs405/clock.c b/src/soc/qualcomm/qcs405/clock.c index 369bcdf531f..ebad13b7215 100644 --- a/src/soc/qualcomm/qcs405/clock.c +++ b/src/soc/qualcomm/qcs405/clock.c @@ -209,11 +209,38 @@ void clock_configure_uart(uint32_t hz) clock_configure(uart_clk, uart_cfg, hz, ARRAY_SIZE(uart_cfg)); } -void clock_configure_spi(int blsp, uint32_t hz) +void clock_configure_spi(int blsp, int qup, uint32_t hz) { - struct qcs405_clock *spi_clk = (blsp == 1) ? - (struct qcs405_clock *)&gcc->blsp1_qup4_spi_clk - : (struct qcs405_clock *)&gcc->blsp2_qup0_spi_clk; + struct qcs405_clock *spi_clk = 0; + + if (blsp == 1) { + switch (qup) { + case 0: + spi_clk = (struct qcs405_clock *) + &gcc->blsp1_qup0_spi_clk; + break; + case 1: + spi_clk = (struct qcs405_clock *) + &gcc->blsp1_qup1_spi_clk; + break; + case 2: + spi_clk = (struct qcs405_clock *) + &gcc->blsp1_qup2_spi_clk; + break; + case 3: + spi_clk = (struct qcs405_clock *) + &gcc->blsp1_qup3_spi_clk; + break; + case 4: + spi_clk = (struct qcs405_clock *) + &gcc->blsp1_qup4_spi_clk; + break; + } + } else if (blsp == 2) + spi_clk = (struct qcs405_clock *)&gcc->blsp2_qup0_spi_clk; + + else + printk(BIOS_ERR, "BLSP%d not supported\n", blsp); clock_configure(spi_clk, spi_cfg, hz, ARRAY_SIZE(spi_cfg)); } @@ -228,38 +255,66 @@ void clock_disable_uart(void) clock_disable(&gcc->blsp1_uart2_apps_cbcr); } -void clock_enable_spi(int blsp) +void clock_enable_spi(int blsp, int qup) { - (blsp == 1) ? clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr) - : clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr); + if (blsp == 1) { + switch (qup) { + case 0: + clock_enable(&gcc->blsp1_qup0_spi_apps_cbcr); + break; + case 1: + clock_enable(&gcc->blsp1_qup1_spi_apps_cbcr); + break; + case 2: + clock_enable(&gcc->blsp1_qup2_spi_apps_cbcr); + break; + case 3: + clock_enable(&gcc->blsp1_qup3_spi_apps_cbcr); + break; + case 4: + clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr); + break; + } + } else if (blsp == 2) + clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr); + else + printk(BIOS_ERR, "BLSP%d not supported\n", blsp); } -void clock_disable_spi(int blsp) +void clock_disable_spi(int blsp, int qup) { - (blsp == 1) ? clock_disable(&gcc->blsp1_qup4_spi_apps_cbcr) - : clock_disable(&gcc->blsp2_qup0_spi_apps_cbcr); + if (blsp == 1) { + switch (qup) { + case 0: + clock_enable(&gcc->blsp1_qup0_spi_apps_cbcr); + break; + case 1: + clock_enable(&gcc->blsp1_qup1_spi_apps_cbcr); + break; + case 2: + clock_enable(&gcc->blsp1_qup2_spi_apps_cbcr); + break; + case 3: + clock_enable(&gcc->blsp1_qup3_spi_apps_cbcr); + break; + case 4: + clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr); + break; + } + } else if (blsp == 2) + clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr); + else + printk(BIOS_ERR, "BLSP%d not supported\n", blsp); + } void clock_init(void) { - clock_configure_gpll0(); - - clock_configure(&gcc->blsp1_uart2_apps_clk, uart_cfg, 1843200, - ARRAY_SIZE(uart_cfg)); - - clock_enable(&gcc->blsp1_uart2_apps_cbcr); clock_enable_vote(&gcc->blsp1_ahb_cbcr, &gcc->gcc_apcs_clock_branch_en_vote, BLSP1_AHB_CLK_ENA); - clock_configure(&gcc->blsp1_qup4_spi_clk, spi_cfg, 1000000, - ARRAY_SIZE(spi_cfg)); - clock_enable(&gcc->blsp1_qup4_spi_apps_cbcr); - - clock_configure(&gcc->blsp2_qup0_spi_clk, spi_cfg, 50000000, - ARRAY_SIZE(spi_cfg)); - clock_enable(&gcc->blsp2_qup0_spi_apps_cbcr); clock_enable_vote(&gcc->blsp2_ahb_cbcr, &gcc->gcc_apcs_clock_branch_en_vote, BLSP2_AHB_CLK_ENA); diff --git a/src/soc/qualcomm/qcs405/include/soc/clock.h b/src/soc/qualcomm/qcs405/include/soc/clock.h index d0f307b308a..8638128b15c 100644 --- a/src/soc/qualcomm/qcs405/include/soc/clock.h +++ b/src/soc/qualcomm/qcs405/include/soc/clock.h @@ -21,7 +21,6 @@ #define BLSP2_AHB_CLK_ENA 20 #define SRC_XO_19_2MHZ 0 #define SRC_GPLL0_MAIN_800MHZ 1 -#define REG(addr) ((void *)addr) /** * USB BCR registers @@ -66,28 +65,48 @@ struct qcs405_gcc { u32 blsp1_bcr; u32 blsp1_sleep_cbcr; u32 blsp1_ahb_cbcr; - u8 _res1[0x3028 - 0x100c]; + struct qcs405_rcg gcc_blsp_uart_sim_rcg; + u8 _res1[0x2000 - 0x1014]; + u32 blsp1_qup1_bcr; + u32 blsp1_qup1_spi_apps_cbcr; + u8 _res2[0x2024 - 0x2008]; + struct qcs405_clock blsp1_qup1_spi_clk; + u8 _res3[0x3008-0x2038]; + u32 blsp1_qup2_bcr; + u32 blsp1_qup2_spi_apps_cbcr; + u8 _res4[0x3014 - 0x3010]; + struct qcs405_clock blsp1_qup2_spi_clk; u32 blsp1_uart2_bcr; u32 blsp1_uart2_apps_cbcr; u32 blsp1_uart2_sim_cbcr; struct qcs405_clock blsp1_uart2_apps_clk; - u8 _res2[0x5018 - 0x3048]; + u8 _res5[0x4018 - 0x3048]; + u32 blsp1_qup3_bcr; + u32 blsp1_qup3_spi_apps_cbcr; + u8 _res6[0x4024 - 0x4020]; + struct qcs405_clock blsp1_qup3_spi_clk; + u8 _res7[0x5018 - 0x4038]; u32 blsp1_qup4_bcr; u32 blsp1_qup4_spi_apps_cbcr; - u8 _res3[0x5024 - 0x5020]; + u8 _res8[0x5024 - 0x5020]; struct qcs405_clock blsp1_qup4_spi_clk; - u8 _res4[0xB000 - 0x5038]; + u8 _res9[0x6020 - 0x5038]; + u32 blsp1_qup0_bcr; + u32 blsp1_qup0_spi_apps_cbcr; + u8 _res10[0x6034 - 0x6028]; + struct qcs405_clock blsp1_qup0_spi_clk; + u8 _res11[0xB000 - 0x6048]; u32 blsp2_bcr; u32 blsp2_sleep_cbcr; u32 blsp2_ahb_cbcr; - u8 _res5[0xC000 - 0xB00C]; + u8 _res12[0xC000 - 0xB00C]; u32 blsp2_qup0_bcr; u32 blsp2_qup0_spi_apps_cbcr; - u8 _res6[0xC024 - 0xC008]; + u8 _res13[0xC024 - 0xC008]; struct qcs405_clock blsp2_qup0_spi_clk; - u8 _res7[0x21000 - 0xC038]; + u8 _res14[0x21000 - 0xC038]; struct qcs405_gpll gpll0; - u8 _res8[0x45004 - 0x21024]; + u8 _res15[0x45004 - 0x21024]; u32 gcc_apcs_clock_branch_en_vote; }; @@ -160,10 +179,10 @@ void clock_reset_aop(void); int clock_configure_qspi(uint32_t hz); int clock_reset_bcr(void *bcr_addr, bool reset); void clock_configure_uart(uint32_t hz); -void clock_configure_spi(int blsp, uint32_t hz); +void clock_configure_spi(int blsp, int qup, uint32_t hz); void clock_enable_uart(void); void clock_disable_uart(void); -void clock_enable_spi(int blsp); -void clock_disable_spi(int blsp); +void clock_enable_spi(int blsp, int qup); +void clock_disable_spi(int blsp, int qup); #endif // __SOC_QUALCOMM_QCS405_CLOCK_H__ From 4b766393e2436bc678a4717043522a77cbddd2f8 Mon Sep 17 00:00:00 2001 From: Taniya Das Date: Thu, 4 Apr 2019 15:28:36 +0530 Subject: [PATCH 057/588] qcs405: Add support of GPIO IRQ APIs Add support of GPIO IRQ APIs. Change-Id: I11715a93999012622a5e28455731cbe249ba8f2c Signed-off-by: Shefali Jain Signed-off-by: Taniya Das Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/32241 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/soc/qualcomm/qcs405/gpio.c | 25 +++++++++++++++++ src/soc/qualcomm/qcs405/include/soc/gpio.h | 31 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/soc/qualcomm/qcs405/gpio.c b/src/soc/qualcomm/qcs405/gpio.c index 18aacf4ce4d..7b2238d77ff 100644 --- a/src/soc/qualcomm/qcs405/gpio.c +++ b/src/soc/qualcomm/qcs405/gpio.c @@ -71,3 +71,28 @@ void gpio_output(gpio_t gpio, int value) gpio_configure(gpio, GPIO_FUNC_GPIO, GPIO_NO_PULL, GPIO_2MA, GPIO_ENABLE); } + +void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + gpio_configure(gpio, GPIO_FUNC_GPIO, + pull, GPIO_2MA, GPIO_DISABLE); + + clrsetbits_le32(®s->intr_cfg, GPIO_INTR_DECT_CTL_MASK << + GPIO_INTR_DECT_CTL_SHIFT, type << GPIO_INTR_DECT_CTL_SHIFT); + clrsetbits_le32(®s->intr_cfg, GPIO_INTR_RAW_STATUS_ENABLE + << GPIO_INTR_RAW_STATUS_EN_SHIFT, GPIO_INTR_RAW_STATUS_ENABLE + << GPIO_INTR_RAW_STATUS_EN_SHIFT); +} + +int gpio_irq_status(gpio_t gpio) +{ + struct tlmm_gpio *regs = (void *)(uintptr_t)gpio.addr; + + if (!(read32(®s->intr_status) & GPIO_INTR_STATUS_MASK)) + return 0; + + write32(®s->intr_status, GPIO_INTR_STATUS_DISABLE); + return 1; +} diff --git a/src/soc/qualcomm/qcs405/include/soc/gpio.h b/src/soc/qualcomm/qcs405/include/soc/gpio.h index fce435056f1..232e05e672c 100644 --- a/src/soc/qualcomm/qcs405/include/soc/gpio.h +++ b/src/soc/qualcomm/qcs405/include/soc/gpio.h @@ -30,6 +30,26 @@ typedef struct { #define TLMM_GPIO_IN_OUT_OFF 0x4 #define TLMM_GPIO_ID_STATUS_OFF 0x10 + +/* GPIO INTR CFG MASK */ +#define GPIO_INTR_DECT_CTL_MASK 0x3 +#define GPIO_INTR_RAW_STATUS_EN_MASK 0x1 + +/* GPIO INTR CFG SHIFT */ +#define GPIO_INTR_DECT_CTL_SHIFT 2 +#define GPIO_INTR_RAW_STATUS_EN_SHIFT 4 + +/* GPIO INTR STATUS MASK */ +#define GPIO_INTR_STATUS_MASK 0x1 + +/* GPIO INTR RAW STATUS */ +#define GPIO_INTR_RAW_STATUS_ENABLE 1 +#define GPIO_INTR_RAW_STATUS_DISABLE 0 + +/* GPIO INTR STATUS */ +#define GPIO_INTR_STATUS_ENABLE 1 +#define GPIO_INTR_STATUS_DISABLE 0 + /* GPIO TLMM: Direction */ #define GPIO_INPUT 0 #define GPIO_OUTPUT 1 @@ -304,12 +324,23 @@ enum { PIN(119, EAST, RES_1, RES_2, RES_3, RES_4, RES_5, RES_6, RES_7), }; +enum gpio_irq_type { + IRQ_TYPE_LEVEL = 0, + IRQ_TYPE_RISING_EDGE = 1, + IRQ_TYPE_FALLING_EDGE = 2, + IRQ_TYPE_DUAL_EDGE = 3, +}; + struct tlmm_gpio { uint32_t cfg; uint32_t in_out; + uint32_t intr_cfg; + uint32_t intr_status; }; void gpio_configure(gpio_t gpio, uint32_t func, uint32_t pull, uint32_t drive_str, uint32_t enable); +void gpio_input_irq(gpio_t gpio, enum gpio_irq_type type, uint32_t pull); +int gpio_irq_status(gpio_t gpio); #endif // _SOC_QUALCOMM_QCS405_GPIO_H_ From c323963bede283493e4cb8fad1bca1ce3342b90f Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 23 Apr 2019 21:31:24 +0200 Subject: [PATCH 058/588] soc/qualcomm/qcs405: add console.h include Change-Id: I556d00e8b06f631a5ca51ae2b5ba646e5f536480 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32422 Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/soc/qualcomm/qcs405/clock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/qualcomm/qcs405/clock.c b/src/soc/qualcomm/qcs405/clock.c index ebad13b7215..302652ba71e 100644 --- a/src/soc/qualcomm/qcs405/clock.c +++ b/src/soc/qualcomm/qcs405/clock.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ +#include #include #include #include From 283fdcfbc26db3d1d5475544f2849ee6f19f49d5 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Mon, 22 Apr 2019 20:11:37 +0800 Subject: [PATCH 059/588] mb/google/octopus/variants/bloog: Add goodix touchscreen support Add goodix touchscreen support BUG=b:131082228 BRANCH=octopus TEST=emerge-octopus coreboot and verify that touchscreen works on bloog. Change-Id: I0b3b481ca806b6452d67ace5dfe53f12a14ac3be Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/32387 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Karthik Ramasubramanian --- .../google/octopus/variants/bloog/overridetree.cb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/mainboard/google/octopus/variants/bloog/overridetree.cb b/src/mainboard/google/octopus/variants/bloog/overridetree.cb index 20b5dd3b71e..21a10f74c8e 100644 --- a/src/mainboard/google/octopus/variants/bloog/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bloog/overridetree.cb @@ -101,6 +101,20 @@ chip soc/intel/apollolake register "has_power_resource" = "1" device i2c 10 on end end + chip drivers/i2c/hid + register "generic.hid" = ""GDIX0000"" + register "generic.desc" = ""Goodix Touchscreen"" + register "generic.irq" = "ACPI_IRQ_EDGE_LOW(GPIO_212_IRQ)" + register "generic.probed" = "1" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_105)" + register "generic.reset_delay_ms" = "120" + register "generic.reset_off_delay_ms" = "3" + register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_146)" + register "generic.has_power_resource" = "1" + register "generic.enable_delay_ms" = "10" + register "hid_desc_reg_offset" = "0x01" + device i2c 5d on end + end end # - I2C 7 end From 8725e5f639cb71f405005586e01d6efa0042dc4b Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Tue, 23 Apr 2019 22:05:01 +0800 Subject: [PATCH 060/588] mb/google/octopus: I2C clock tuning for bloog Tune I2C params for I2C buses 5, 6, and 7 to ensure that the frequency does not exceed 400KHz. BUG=b:131132499, b:128998988 BRANCH=octopus TEST=emerge-octopus coreboot chromeos-bootimage and measured frequency under 400 KHz Change-Id: Ie8cfba72a0654402ccb0274c00b44fbfa2deea21 Signed-off-by: Tony Huang Reviewed-on: https://review.coreboot.org/c/coreboot/+/32404 Tested-by: build bot (Jenkins) Reviewed-by: Karthik Ramasubramanian Reviewed-by: Justin TerAvest Reviewed-by: Furquan Shaikh --- .../octopus/variants/bloog/overridetree.cb | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/mainboard/google/octopus/variants/bloog/overridetree.cb b/src/mainboard/google/octopus/variants/bloog/overridetree.cb index 21a10f74c8e..cf70bb31085 100644 --- a/src/mainboard/google/octopus/variants/bloog/overridetree.cb +++ b/src/mainboard/google/octopus/variants/bloog/overridetree.cb @@ -49,12 +49,32 @@ chip soc/intel/apollolake #| | required to set up a BAR | #| | for TPM communication | #| | before memory is up | + #| I2C5 | Audio | + #| I2C6 | Trackpad | + #| I2C7 | Touchscreen | #+-------------------+---------------------------+ register "common_soc_config" = "{ .gspi[0] = { .speed_mhz = 1, .early_init = 1, }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[6] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 66, + .fall_time_ns = 90, + .data_hold_time_ns = 350, + }, + .i2c[7] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 44, + .fall_time_ns = 90, + }, + }" device domain 0 on From f9c9fa2df8077d323f7c45a4a3f19ae40282ff44 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Tue, 23 Apr 2019 16:17:37 -0700 Subject: [PATCH 061/588] mb/google/sarien: Toggle SSD reset pin on DVT2 SSD reset pin had been added on DVT2, the power sequnence requires toggle in boot stage. BUG=b:130741066 TEST=Boot up with simulated DVT2 platform and confirm SSD can be detected during warm reboot. Signed-off-by: Lijian Zhao Change-Id: Ie734875a49b8b61f8b813c473d30cbcaf4dd13d1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32434 Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/variants/arcada/gpio.c | 4 +++- src/mainboard/google/sarien/variants/sarien/gpio.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/gpio.c b/src/mainboard/google/sarien/variants/arcada/gpio.c index 2a0ead82a93..a88e0b1190a 100644 --- a/src/mainboard/google/sarien/variants/arcada/gpio.c +++ b/src/mainboard/google/sarien/variants/arcada/gpio.c @@ -211,7 +211,6 @@ static const struct pad_config gpio_table[] = { /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* I2C5_SDA */ PAD_NC(GPP_H10, NONE), /* ISH_I2C2_SDA */ /* I2C5_SCL */ PAD_NC(GPP_H11, NONE), /* ISH_I2C2_SCL */ -/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ /* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* M2_SKT2_CFG2 */ PAD_NC(GPP_H14, NONE), /* M2_SKT2_CFG3 */ PAD_CFG_GPO(GPP_H15, 1, DEEP), /* BT_RADIO_DIS# */ @@ -240,6 +239,8 @@ static const struct pad_config gpio_table[] = { /* Early pad configuration in bootblock */ static const struct pad_config early_gpio_table[] = { +/* SSD RESET pin will stay low first */ +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 0, DEEP), /* D3 cold RST */ /* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* SERVOTX_UART */ /* UART2_TXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* SERVORX_UART */ /* I2C4_SDA */ PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1), /* I2C_SDA_H1 */ @@ -251,6 +252,7 @@ static const struct pad_config early_gpio_table[] = { /* CPU_GP0 */ PAD_CFG_GPI(GPP_E3, NONE, DEEP), /* MEM_INTERLEAVED */ /* SATALED# */ PAD_CFG_GPI(GPP_E8, NONE, DEEP), /* RECOVERY# */ /* DDPD_HPD2 */ PAD_CFG_GPI(GPP_E15, NONE, DEEP), /* PCH_WP */ +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ }; const struct pad_config *variant_gpio_table(size_t *num) diff --git a/src/mainboard/google/sarien/variants/sarien/gpio.c b/src/mainboard/google/sarien/variants/sarien/gpio.c index 19fd45cdeaa..53a937ff39a 100644 --- a/src/mainboard/google/sarien/variants/sarien/gpio.c +++ b/src/mainboard/google/sarien/variants/sarien/gpio.c @@ -197,7 +197,6 @@ static const struct pad_config gpio_table[] = { /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* I2C5_SDA */ PAD_NC(GPP_H10, NONE), /* I2C5_SCL */ PAD_NC(GPP_H11, NONE), -/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* /D3 cold RST */ /* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* M2_SKT2_CFG2 */ PAD_NC(GPP_H14, NONE), /* M2_SKT2_CFG3 */ PAD_CFG_GPO(GPP_H15, 1, DEEP), /* BT_RADIO_DIS# */ @@ -225,6 +224,7 @@ static const struct pad_config gpio_table[] = { /* Early pad configuration in bootblock */ static const struct pad_config early_gpio_table[] = { +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 0, DEEP), /* D3 cold RST */ /* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* SERVOTX_UART */ /* UART2_TXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* SERVORX_UART */ /* I2C4_SDA */ PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1), /* I2C_SDA_H1 */ @@ -236,6 +236,8 @@ static const struct pad_config early_gpio_table[] = { /* CPU_GP0 */ PAD_CFG_GPI(GPP_E3, NONE, DEEP), /* MEM_INTERLEAVED */ /* SATALED# */ PAD_CFG_GPI(GPP_E8, NONE, DEEP), /* RECOVERY# */ /* DDPD_HPD2 */ PAD_CFG_GPI(GPP_E15, NONE, DEEP), /* H1_FLASH_WP */ +/* SSD RESET need to stay low first */ +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ /* PWRBTN# */ PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* SIO_PWRBTN# */ }; From 29035f3c3618c44bed2be2508af6583e5ea8681d Mon Sep 17 00:00:00 2001 From: zaolin Date: Tue, 23 Apr 2019 18:10:56 +0200 Subject: [PATCH 062/588] 3rdparty/opensbi: Add submodule * Add opensbi for RISC-v Change-Id: I1a6baa6b6c05095ff5545492aabf7408a23af181 Signed-off-by: Philipp Deppenwiese Reviewed-on: https://review.coreboot.org/c/coreboot/+/32418 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- .gitmodules | 3 +++ 3rdparty/opensbi | 1 + 2 files changed, 4 insertions(+) create mode 160000 3rdparty/opensbi diff --git a/.gitmodules b/.gitmodules index f4f7c4ff270..78e2c880f6b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -26,3 +26,6 @@ url = ../fsp.git update = none ignore = dirty +[submodule "opensbi"] + path = 3rdparty/opensbi + url = ../opensbi.git diff --git a/3rdparty/opensbi b/3rdparty/opensbi new file mode 160000 index 00000000000..804b997ed41 --- /dev/null +++ b/3rdparty/opensbi @@ -0,0 +1 @@ +Subproject commit 804b997ed415001097803e4b537fd63d043874b9 From 9f3aa702a9a7b6fe3bd1d03a1c5f8cfca2f51177 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Wed, 3 Apr 2019 13:13:51 +0200 Subject: [PATCH 063/588] payloads/seabios: Update the stable git hash of 1.12.1 The Kconfig file has been updated to show 1.12.1 but this is only what gets displayed for the "stable" option. Fix this by updating the actual git hash for the SeaBIOS 1.12.1 release tag. Fixes: fb83ff1a8b ("Update stable from 1.12.0 to 1.12.1") Change-Id: I76dc0dc8b651df0c6ff6f3c02819a70bab8c04cd Signed-off-by: Martin Kepplinger Reviewed-on: https://review.coreboot.org/c/coreboot/+/32173 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Patrick Rudolph --- payloads/external/SeaBIOS/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/payloads/external/SeaBIOS/Makefile b/payloads/external/SeaBIOS/Makefile index e505c8c6b76..fd05c0c12a5 100644 --- a/payloads/external/SeaBIOS/Makefile +++ b/payloads/external/SeaBIOS/Makefile @@ -1,5 +1,5 @@ TAG-$(CONFIG_SEABIOS_MASTER)=origin/master -TAG-$(CONFIG_SEABIOS_STABLE)=a698c8995ffb2838296ec284fe3c4ad33dfca307 +TAG-$(CONFIG_SEABIOS_STABLE)=a5cab58e9a3fb6e168aba919c5669bea406573b4 TAG-$(CONFIG_SEABIOS_REVISION)=$(CONFIG_SEABIOS_REVISION_ID) project_git_repo=https://review.coreboot.org/seabios.git From dcb2eef582960095ead8c6ba6cb6d3f3c03f6c94 Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Tue, 23 Apr 2019 14:09:52 +0800 Subject: [PATCH 064/588] mediatek/mt8183: Set processor voltage to 1.05v The maximum CPU frequency is 1417MHz with current processor voltage (0.8v). Set processor voltage to 1.05v for higher CPU frequency. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: I24ecdac2c85d3f012d9235449c0d727d727dc185 Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32396 Tested-by: build bot (Jenkins) Reviewed-by: You-Cheng Syu Reviewed-by: Hung-Te Lin --- src/soc/mediatek/mt8183/mt6358.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/soc/mediatek/mt8183/mt6358.c b/src/soc/mediatek/mt8183/mt6358.c index 580327183ce..8162e3aaf17 100644 --- a/src/soc/mediatek/mt8183/mt6358.c +++ b/src/soc/mediatek/mt8183/mt6358.c @@ -493,6 +493,10 @@ static struct pmic_setting init_setting[] = { /* [2:1]: RG_LDO_VSRAM_PROC12_TRACK_ON_CTRL */ /* [2:2]: RG_LDO_VSRAM_PROC12_TRACK_VPROC12_ON_CTRL */ {0x1B6C, 0x6, 0x6, 0}, + + /* Vproc11/Vproc12 to 1.05V */ + {0x13a6, 0x58, 0x7F, 0}, + {0x140a, 0x58, 0x7F, 0}, }; static struct pmic_setting lp_setting[] = { From d228c1ef32daf0affe211cd8e79b31e0a2e5f45c Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Tue, 23 Apr 2019 14:24:22 +0800 Subject: [PATCH 065/588] mediatek/mt8183: Set CPU frequency to 1989MHz Set CPU frequency from 1100MHz to 1989MHz to improve booting time. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: Id41c7ea8905c4db2537a5c32f96eb7c6b2c008ea Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32397 Reviewed-by: Hung-Te Lin Reviewed-by: You-Cheng Syu Tested-by: build bot (Jenkins) --- src/soc/mediatek/mt8183/include/soc/pll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/mediatek/mt8183/include/soc/pll.h b/src/soc/mediatek/mt8183/include/soc/pll.h index 5a5f58db3b2..e6f5711549b 100644 --- a/src/soc/mediatek/mt8183/include/soc/pll.h +++ b/src/soc/mediatek/mt8183/include/soc/pll.h @@ -244,7 +244,7 @@ enum { /* PLL rate */ enum { - ARMPLL_LL_HZ = 1100 * MHz, + ARMPLL_LL_HZ = 1989 * MHz, ARMPLL_L_HZ = 1200 * MHz, CCIPLL_HZ = 598 * 2 * MHz, MAINPLL_HZ = 1092 * MHz, From 18060d7d92a924dde1aff73f7792e64c6c0c34cd Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Wed, 24 Apr 2019 14:21:04 +0800 Subject: [PATCH 066/588] mb/google/sarien: Disable touch by strap pin GPP_B4 We want to disable touch for non-touch sku. We can use strap pin GPP_B4 to identify it is connected with touch or not. touch sku: GPP_B4 is low non-touch sku: GPP_B4 is high BUG=b:131132419 TEST=boot up and check no touch device exist Signed-off-by: Eric Lai Change-Id: If6681262c25e4b01e061a8520e38905d40345509 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32438 Reviewed-by: Duncan Laurie Reviewed-by: Paul Menzel Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/drivers/i2c/hid/hid.c | 19 +++++++++++++++++++ .../sarien/variants/sarien/devicetree.cb | 4 ++++ 2 files changed, 23 insertions(+) diff --git a/src/drivers/i2c/hid/hid.c b/src/drivers/i2c/hid/hid.c index d570892c1d0..035e5633c6e 100644 --- a/src/drivers/i2c/hid/hid.c +++ b/src/drivers/i2c/hid/hid.c @@ -18,6 +18,8 @@ #include #include #include "chip.h" +#include +#include #if CONFIG(HAVE_ACPI_TABLES) static void i2c_hid_fill_dsm(struct device *dev) @@ -60,6 +62,23 @@ static void i2c_hid_enable(struct device *dev) { struct drivers_i2c_hid_config *config = dev->chip_info; + if (!config) + return; + + /* Check if device is present by reading GPIO */ + if (config->generic.device_present_gpio) { + int present = gpio_get(config->generic.device_present_gpio); + present ^= config->generic.device_present_gpio_invert; + + printk(BIOS_INFO, "%s is %spresent\n", + dev->chip_ops->name, present ? "" : "not "); + + if (!present) { + dev->enabled = 0; + return; + } + } + dev->ops = &i2c_hid_ops; if (config && config->generic.desc) { diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 625655b38c2..12e5dea4aac 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -329,6 +329,8 @@ chip soc/intel/cannonlake register "generic.enable_off_delay_ms" = "100" register "generic.has_power_resource" = "1" register "hid_desc_reg_offset" = "0x01" + register "generic.device_present_gpio" = "GPP_B4" + register "generic.device_present_gpio_invert" = "1" device i2c 10 on end end chip drivers/i2c/generic @@ -339,6 +341,8 @@ chip soc/intel/cannonlake register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" register "enable_delay_ms" = "5" register "has_power_resource" = "1" + register "device_present_gpio" = "GPP_B4" + register "device_present_gpio_invert" = "1" device i2c 34 on end end end # I2C #0 From 389f9277518e93c24741581da58f5d3809377357 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Wed, 24 Apr 2019 14:10:34 +0800 Subject: [PATCH 067/588] mb/google/sarien: Remove touch VPD support and Melfas HID touch Sarien will change Melfas from HID to I2C and change address from 0x10 to 0x34. So we don't need VPD to separate Elan and Melfas anymore. BUG=b:131194574 TEST=boot up and check no Melfas HID device exist Signed-off-by: Eric Lai Change-Id: Ic002f61b226743e1c18dbdbc51ce8b733916d8a0 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32437 Reviewed-by: Duncan Laurie Reviewed-by: Paul Menzel Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/Kconfig | 5 -- .../sarien/variants/sarien/Makefile.inc | 2 +- .../sarien/variants/sarien/devicetree.cb | 13 ---- .../google/sarien/variants/sarien/ramstage.c | 73 ------------------- 4 files changed, 1 insertion(+), 92 deletions(-) delete mode 100644 src/mainboard/google/sarien/variants/sarien/ramstage.c diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index 9d658fa3a26..f1046ec9528 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -100,11 +100,6 @@ config DEVICETREE string default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb" -config TOUCHSCREEN_HID - string "Specify the touchscreen HID enabled for the OS" - default "WCOM48E2" if BOARD_GOOGLE_ARCADA - default "ELAN900C" if BOARD_GOOGLE_SARIEN - config VBOOT select HAS_RECOVERY_MRC_CACHE select MRC_CLEAR_NORMAL_CACHE_ON_RECOVERY_RETRAIN diff --git a/src/mainboard/google/sarien/variants/sarien/Makefile.inc b/src/mainboard/google/sarien/variants/sarien/Makefile.inc index fa5b2ea36a5..2bf028eb1f2 100644 --- a/src/mainboard/google/sarien/variants/sarien/Makefile.inc +++ b/src/mainboard/google/sarien/variants/sarien/Makefile.inc @@ -14,6 +14,6 @@ ## bootblock-y += gpio.c -ramstage-y += gpio.c ramstage.c +ramstage-y += gpio.c romstage-y += gpio.c verstage-y += gpio.c diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 12e5dea4aac..d5e8afbc347 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -305,19 +305,6 @@ chip soc/intel/cannonlake end device pci 14.5 off end # SDCard device pci 15.0 on - chip drivers/i2c/hid - register "generic.hid" = ""ACPI0C50"" - register "generic.desc" = ""Touchscreen"" - register "generic.irq" = "ACPI_IRQ_EDGE_LOW(GPP_C23_IRQ)" - register "generic.probed" = "1" - register "generic.enable_gpio" = - "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" - register "generic.enable_delay_ms" = "5" - register "generic.enable_off_delay_ms" = "100" - register "generic.has_power_resource" = "1" - register "hid_desc_reg_offset" = "0x0" - device i2c 10 on end - end chip drivers/i2c/hid register "generic.hid" = ""ELAN900C"" register "generic.desc" = ""ELAN Touchscreen"" diff --git a/src/mainboard/google/sarien/variants/sarien/ramstage.c b/src/mainboard/google/sarien/variants/sarien/ramstage.c deleted file mode 100644 index d20260cc91f..00000000000 --- a/src/mainboard/google/sarien/variants/sarien/ramstage.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2019 Google LLC - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include - -/* - * This board may have different touchscreen devices that are at the - * same I2C slave address but need different drivers or ACPI configuration. - * - * The default touchscreen to be enabled is specified in Kconfig by the - * ACPI HID of the device. If a board is connected to a different - * touchscreen device it can be enabled in Kconfig or by setting the - * VPD key 'touchscreen_hid'. - */ - -#define TOUCHSCREEN_I2C_ADDR 0x10 -#define TOUCHSCREEN_VPD_KEY "touchscreen_hid" - -static void disable_unused_touchscreen(void *unused) -{ - struct device *i2c0 = PCH_DEV_I2C0; - struct bus *i2c_slaves = i2c0->link_list; - struct device *slave = i2c_slaves->children; - char touchscreen_hid[9] = CONFIG_TOUCHSCREEN_HID; - struct drivers_i2c_hid_config *info; - - /* Look for VPD key that indicates which touchscreen is present */ - if (CONFIG(VPD) && - !vpd_gets(TOUCHSCREEN_VPD_KEY, touchscreen_hid, - ARRAY_SIZE(touchscreen_hid), VPD_ANY)) - printk(BIOS_INFO, "%s: VPD key '%s' not found, default to %s\n", - __func__, TOUCHSCREEN_VPD_KEY, touchscreen_hid); - - /* Go through all I2C slave devices on this bus */ - while (slave) { - /* Find all the I2C slaves with the matching address */ - if (slave->path.type == DEVICE_PATH_I2C && - slave->path.i2c.device == TOUCHSCREEN_I2C_ADDR) { - info = slave->chip_info; - /* Disable all devices except the matching HID */ - if (strncmp(info->generic.hid, touchscreen_hid, - ARRAY_SIZE(touchscreen_hid))) { - printk(BIOS_INFO, "%s: Disable %s\n", __func__, - info->generic.hid); - slave->enabled = 0; - } else { - printk(BIOS_INFO, "%s: Enable %s\n", __func__, - info->generic.hid); - } - } - slave = slave->sibling; - } -} -BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY, - disable_unused_touchscreen, NULL); From 1a1fe6e3841f861d00aec62a2c0a4d6ee3e0d6c3 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Tue, 16 Apr 2019 14:30:49 +0800 Subject: [PATCH 068/588] mb/google/sarien: Add power control for Sarien touchscreen This change will save touchscreen power leakage 2-3mW in S0iX and increase T2 display time delay to meet display panel requirement. BUG=b:129899315 TEST= Measure touchscreen power from Sarien during S0iX Signed-off-by: Eric Lai Change-Id: I48419132ba734f20ad5cf484c2dda609570a6dd0 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32330 Reviewed-by: Duncan Laurie Reviewed-by: Paul Menzel Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- .../google/sarien/variants/sarien/devicetree.cb | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index d5e8afbc347..27c0913c6f9 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -310,10 +310,12 @@ chip soc/intel/cannonlake register "generic.desc" = ""ELAN Touchscreen"" register "generic.irq" = "ACPI_IRQ_EDGE_LOW(GPP_C23_IRQ)" register "generic.probed" = "1" + register "generic.reset_gpio" = + "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E7)" + register "generic.reset_delay_ms" = "10" register "generic.enable_gpio" = - "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" - register "generic.enable_delay_ms" = "5" - register "generic.enable_off_delay_ms" = "100" + "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B21)" + register "generic.enable_delay_ms" = "55" register "generic.has_power_resource" = "1" register "hid_desc_reg_offset" = "0x01" register "generic.device_present_gpio" = "GPP_B4" @@ -325,8 +327,10 @@ chip soc/intel/cannonlake register "desc" = ""Melfas Touchscreen"" register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_C23_IRQ)" register "probed" = "1" - register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_E7)" - register "enable_delay_ms" = "5" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E7)" + register "reset_delay_ms" = "10" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B21)" + register "enable_delay_ms" = "55" register "has_power_resource" = "1" register "device_present_gpio" = "GPP_B4" register "device_present_gpio_invert" = "1" From 97f8029ad4377fa3b5fd835512665e2656ed7275 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Tue, 23 Apr 2019 17:27:36 -0600 Subject: [PATCH 069/588] security/tpm: Change POWER_OFF_ON_CR50_UPDATE so it can be disabled Modify the POWER_OFF_ON_CR50_UPDATE Kconfig option so that specific mainboard implementations can disable the option. BUG=b:126632503 BRANCH=none TEST=Build coreboot on sarien/arcada. TEST=Perform Cr50 firmware update on Sarien, confirm the platform boots normally after sending TURN_UPDATE_ON to the Cr50. Change-Id: I3beefaae21de61e53ae232dbdc8ea9dbb2c78cd5 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32435 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh --- src/security/tpm/tss/vendor/cr50/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/security/tpm/tss/vendor/cr50/Kconfig b/src/security/tpm/tss/vendor/cr50/Kconfig index 4d40c08da65..4a2ad4f8801 100644 --- a/src/security/tpm/tss/vendor/cr50/Kconfig +++ b/src/security/tpm/tss/vendor/cr50/Kconfig @@ -16,12 +16,12 @@ config TPM_CR50 bool default y if MAINBOARD_HAS_I2C_TPM_CR50 || MAINBOARD_HAS_SPI_TPM_CR50 - select POWER_OFF_ON_CR50_UPDATE if ARCH_X86 if TPM_CR50 config POWER_OFF_ON_CR50_UPDATE bool + default y if ARCH_X86 help Power off machine while waiting for CR50 update to take effect. From bb4759c15d210753e54d0568392c3c3871a37917 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Tue, 23 Apr 2019 17:52:36 -0600 Subject: [PATCH 070/588] mb/google/sarien: Disable POWER_OFF_ON_CR50_UPDATE Disable the POWER_OFF_ON_CR50_UPDATE option on sarien/arcada. This is needed so that platform properly boots after doing a Cr50 firmware update when running on battery. BUG=b:126632503 BRANCH=none TEST=Build coreboot on sarien/arcada. TEST=Perform Cr50 firmware update on Sarien, confirm the platform boots normally after sending TURN_UPDATE_ON to the Cr50. Change-Id: I0b687285eb95070eaffb68611a7d98eb8434ce2c Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32436 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh --- src/mainboard/google/sarien/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index f1046ec9528..1e6df57f2f6 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -59,6 +59,10 @@ config TPM_TIS_ACPI_INTERRUPT int default 82 # GPE0_DW2_18 (GPP_D18) +config POWER_OFF_ON_CR50_UPDATE + bool + default n + config GBB_HWID string depends on CHROMEOS From 77fb3632a4a3d3004b3aa4950967be9164d9711d Mon Sep 17 00:00:00 2001 From: Nathan_chen Date: Tue, 23 Apr 2019 21:53:27 +0800 Subject: [PATCH 071/588] mb/google/arcada: Add settings for noise mitgation Enable acoustic noise mitgation for arcada platform, the slow slew rates for Ia and Gt are fast time dived by 8. BUG=b:131144464 TEST=waveform test and hardware validation result pass. Signed-off-by: nathan chen Change-Id: I37315ecfa245fce3085e62d1566ff037d8aa8ab4 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32403 Reviewed-by: Duncan Laurie Reviewed-by: Lijian Zhao Tested-by: build bot (Jenkins) --- coreboot | 1 + src/mainboard/google/sarien/variants/arcada/devicetree.cb | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) create mode 160000 coreboot diff --git a/coreboot b/coreboot new file mode 160000 index 00000000000..1db39a44661 --- /dev/null +++ b/coreboot @@ -0,0 +1 @@ +Subproject commit 1db39a44661f57c2ffe0d795e21c0a4d5dddb494 diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 57c4e65e709..426bdae88d9 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -37,10 +37,10 @@ chip soc/intel/cannonlake register "tdp_pl2_override" = "51" register "Device4Enable" = "1" register "AcousticNoiseMitigation" = "1" - register "SlowSlewRateForIa" = "0" - register "SlowSlewRateForGt" = "0" + register "SlowSlewRateForIa" = "2" + register "SlowSlewRateForGt" = "2" register "SlowSlewRateForSa" = "0" - register "SlowSlewRateForFivr" = "0" + register "SlowSlewRateForFivr" = "2" # Enable eDP device register "DdiPortEdp" = "1" # Enable HPD for DDI ports B/C From 131134288be3d8851e7e4e7268fac8b9072ef83c Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Mon, 22 Apr 2019 23:45:06 -0700 Subject: [PATCH 072/588] mb/google/hatch/var/kohaku: Skip UART0 config in FSP Similar to hatch(CB:32278), this change sets SerialIo config for UART0 to PchSerialIoSkipInit to skip initialization in FSP. This change also adds a device to kohaku override tree to ensure that the settings in it take effect. BUG=b:130310626 Change-Id: Ia25b45811be26d55fc0019e4cd22eb7310b5a4c4 Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32398 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/mainboard/google/hatch/variants/kohaku/overridetree.cb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb index 6e6414e8a82..d564918a577 100644 --- a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb +++ b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb @@ -10,9 +10,12 @@ chip soc/intel/cannonlake [PchSerialIoIndexSPI0] = PchSerialIoPci, [PchSerialIoIndexSPI1] = PchSerialIoPci, [PchSerialIoIndexSPI2] = PchSerialIoDisabled, - [PchSerialIoIndexUART0] = PchSerialIoPci, + [PchSerialIoIndexUART0] = PchSerialIoSkipInit, [PchSerialIoIndexUART1] = PchSerialIoDisabled, [PchSerialIoIndexUART2] = PchSerialIoDisabled, }" + device domain 0 on + end + end From 4d99b270187ac8c297404e811c268bb3470f283e Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Thu, 11 Apr 2019 15:13:25 -0700 Subject: [PATCH 073/588] util/sconfig: Throw an error if override tree has no devices If override tree does not have any device, then the chip info structure in it cannot be associated with the correct device and ends up being added as a standalone chip info structure without any device actually using it. This change prevents this condition by throwing an error during compilation. BUG=b:130342895 Change-Id: I7b8bb6b3228030a465976ca32ce8ef63f41365dd Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32289 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Aaron Durbin --- util/sconfig/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/util/sconfig/main.c b/util/sconfig/main.c index 4ac935e7b10..5382f470fd0 100644 --- a/util/sconfig/main.c +++ b/util/sconfig/main.c @@ -1316,6 +1316,11 @@ int main(int argc, char **argv) override_devtree = argv[OVERRIDE_DEVICEFILE_ARG]; parse_devicetree(override_devtree, &override_root_bus); + if (!dev_has_children(&override_root_dev)) { + fprintf(stderr, "ERROR: Override tree needs at least one device!\n"); + exit(1); + } + override_devicetree(&base_root_bus, &override_root_bus); } From 40dee3d5065ff294b8c1ded6ac9187b584a59d42 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 23 Apr 2019 10:50:27 -0600 Subject: [PATCH 074/588] mb/google/hatch: Move SD card detect GPIO. Not all Hatch variants utilize the SoC's native SD card support. Move the support to board-specific variants instead of the base device tree. BUG=none BRANCH=none TEST=compiles (no Hatch device to test with) Change-Id: Iae24114aad2c4d042c25da6f8cb740ccc8960082 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32417 Reviewed-by: Stefan Reinauer Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/variants/baseboard/devicetree.cb | 3 --- src/mainboard/google/hatch/variants/hatch/overridetree.cb | 3 +++ src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb | 3 +++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb index e39f1405889..3889d752626 100644 --- a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb @@ -77,9 +77,6 @@ chip soc/intel/cannonlake # ClkReq-to-ClkSrc mapping for CLK SRC 1 register "PcieClkSrcClkReq[1]" = "1" - # GPIO for SD card detect - register "sdcard_cd_gpio" = "vSD3_CD_B" - # PCIe port 14 for M.2 E-key WLAN register "PcieRpEnable[13]" = "1" # RP 14 uses CLK SRC 3 diff --git a/src/mainboard/google/hatch/variants/hatch/overridetree.cb b/src/mainboard/google/hatch/variants/hatch/overridetree.cb index 22a0947b77e..13e7766747a 100644 --- a/src/mainboard/google/hatch/variants/hatch/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch/overridetree.cb @@ -44,6 +44,9 @@ chip soc/intel/cannonlake }, }" + # GPIO for SD card detect + register "sdcard_cd_gpio" = "vSD3_CD_B" + device domain 0 on device pci 15.0 on chip drivers/i2c/generic diff --git a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb index 5bcb67e9c7c..15b93f38d49 100644 --- a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb @@ -29,6 +29,9 @@ chip soc/intel/cannonlake }, }" + # GPIO for SD card detect + register "sdcard_cd_gpio" = "vSD3_CD_B" + device domain 0 on device pci 15.0 on chip drivers/i2c/generic From c60a830e448180935a0b3405f7e74421a9ad6882 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 23 Apr 2019 10:51:20 -0600 Subject: [PATCH 075/588] mb/google/kohaku: Update overridetree.cb Add common SoC config. Disable PCIe WiFi. Add digitizer. Turn off native SD card interface. No WWAN. Add DA7219 driver to Kconfig. BUG=b:130310626 BRANCH=none TEST=compiles (no Hatch ref or Kohaku device to test) Change-Id: I17d5ba6ce4ec412384e4a1678474b8d26499ba40 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32405 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/hatch/Kconfig | 1 + .../hatch/variants/baseboard/devicetree.cb | 2 +- .../hatch/variants/kohaku/overridetree.cb | 109 ++++++++++++++++-- 3 files changed, 103 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index 63339f2dd8f..07ae7d214ea 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -3,6 +3,7 @@ config BOARD_GOOGLE_BASEBOARD_HATCH def_bool n select DRIVERS_GENERIC_GPIO_KEYS select DRIVERS_GENERIC_MAX98357A + select DRIVERS_I2C_DA7219 select DRIVERS_I2C_GENERIC select DRIVERS_I2C_HID select DRIVERS_I2C_SX9310 diff --git a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb index 3889d752626..09e004e84c6 100644 --- a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb @@ -201,7 +201,7 @@ chip soc/intel/cannonlake device pci 16.4 off end # Management Engine Interface 3 device pci 16.5 off end # Management Engine Interface 4 device pci 17.0 on end # SATA - device pci 19.0 on end #I2C #4 + device pci 19.0 on end # I2C #4 device pci 19.1 off end # I2C #5 device pci 19.2 off end # UART #2 device pci 1a.0 off end # eMMC diff --git a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb index d564918a577..9546420e351 100644 --- a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb +++ b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb @@ -1,12 +1,11 @@ chip soc/intel/cannonlake - register "SerialIoDevMode" = "{ - [PchSerialIoIndexI2C0] = PchSerialIoPci, - [PchSerialIoIndexI2C1] = PchSerialIoPci, - [PchSerialIoIndexI2C2] = PchSerialIoPci, - [PchSerialIoIndexI2C3] = PchSerialIoPci, - [PchSerialIoIndexI2C4] = PchSerialIoPci, - [PchSerialIoIndexI2C5] = PchSerialIoPci, + [PchSerialIoIndexI2C0] = PchSerialIoPci, + [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoPci, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoPci, [PchSerialIoIndexSPI0] = PchSerialIoPci, [PchSerialIoIndexSPI1] = PchSerialIoPci, [PchSerialIoIndexSPI2] = PchSerialIoDisabled, @@ -15,7 +14,101 @@ chip soc/intel/cannonlake [PchSerialIoIndexUART2] = PchSerialIoDisabled, }" + # No PCIe WiFi + register "PcieRpEnable[13]" = "0" + + # Intel Common SoC Config + #+-------------------+---------------------------+ + #| Field | Value | + #+-------------------+---------------------------+ + #| I2C0 | Trackpad | + #| I2C1 | Touchscreen | + #| I2C2 | Digitizer | + #| I2C4 | Audio | + #+-------------------+---------------------------+ + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[1] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[2] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + }, + .gspi[0] = { + .speed_mhz = 1, + .early_init = 1, + }, + }" + device domain 0 on - end + device pci 14.0 on + chip drivers/usb/acpi + device usb 0.0 on + chip drivers/usb/acpi + device usb 2.5 off end + end + chip drivers/usb/acpi + device usb 3.4 off end + end + end + end + end + device pci 14.5 off end # SDCard + + device pci 15.0 on + chip drivers/i2c/hid + register "generic.hid" = ""PNP0C50"" + register "generic.desc" = ""Synaptics Touchpad"" + # TODO: enable this when b/123967687 is fixed. + # register "generic.wake" = "GPE0_DW2_27" + # also set next line to ACPI_IRQ_WAKE_EDGE_LOW + register "generic.irq" = "ACPI_IRQ_EDGE_LOW(GPP_D21_IRQ)" + register "generic.probed" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x2c on end + end + end # I2C 0 + + device pci 15.2 on + chip drivers/i2c/hid + register "generic.hid" = ""WCOM50C1"" + register "generic.desc" = ""WCOM Digitizer"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C7_IRQ)" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_A10)" + register "generic.reset_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x1" + device i2c 0x09 on end + end + end # I2C #2 + device pci 19.0 on + chip drivers/i2c/da7219 + # TODO: these settings were copied from another board + # with the same chip. verify the settings + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_H0_IRQ)" + register "btn_cfg" = "50" + register "mic_det_thr" = "500" + register "jack_ins_deb" = "20" + register "jack_det_rate" = ""32ms_64ms"" + register "jack_rem_deb" = "1" + register "a_d_btn_thr" = "0xa" + register "d_b_btn_thr" = "0x16" + register "b_c_btn_thr" = "0x21" + register "c_mic_btn_thr" = "0x3e" + register "btn_avg" = "4" + register "adc_1bit_rpt" = "1" + register "micbias_lvl" = "2600" + register "mic_amp_in_sel" = ""diff"" + device i2c 0x1a on end + end + end + # No PCIe WiFi + device pci 1d.5 off end + end # domain end From 0987e43aa05bfbafbfdd4952638b79a5084369f8 Mon Sep 17 00:00:00 2001 From: "Marty E. Plummer" Date: Mon, 22 Apr 2019 20:46:27 -0500 Subject: [PATCH 076/588] src/Kconfig: increase heap size if using flattened image tree FIT support takes more heap memory than most coreboot payloads. Change-Id: Id17f25e94d97e937b0e9a9cee3dd1a8aef1d525d Signed-off-by: Marty E. Plummer Reviewed-on: https://review.coreboot.org/c/coreboot/+/32392 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Kconfig b/src/Kconfig index 62b3818fe49..90c724ebb52 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -428,6 +428,7 @@ config RTC config HEAP_SIZE hex + default 0x100000 if FLATTENED_DEVICE_TREE default 0x4000 config STACK_SIZE From 5849b14705a2994f8386a265998d415b01c43996 Mon Sep 17 00:00:00 2001 From: Philip Chen Date: Thu, 11 Apr 2019 22:27:08 -0700 Subject: [PATCH 077/588] mb/google/hatch: Pull up GPP_C13 for hatch and hatch_whl On EC end, we want to change this pin from push-pull to open-drain. And since there is no external pull-up resistor on the board, we'll have to configure this pin as internal-pull-up on AP end. BUG=b:129306003 TEST=None Change-Id: Ibc1f89fc25773220db009c6571400b01390dd756 Signed-off-by: Philip Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32292 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../google/hatch/variants/baseboard/gpio.c | 2 +- .../google/hatch/variants/hatch/Makefile.inc | 2 ++ .../google/hatch/variants/hatch/gpio.c | 32 +++++++++++++++++++ .../hatch/variants/hatch_whl/Makefile.inc | 2 ++ .../google/hatch/variants/hatch_whl/gpio.c | 32 +++++++++++++++++++ 5 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 src/mainboard/google/hatch/variants/hatch/gpio.c create mode 100644 src/mainboard/google/hatch/variants/hatch_whl/gpio.c diff --git a/src/mainboard/google/hatch/variants/baseboard/gpio.c b/src/mainboard/google/hatch/variants/baseboard/gpio.c index 7e82b9b6ec6..df1c65ea1f1 100644 --- a/src/mainboard/google/hatch/variants/baseboard/gpio.c +++ b/src/mainboard/google/hatch/variants/baseboard/gpio.c @@ -428,7 +428,7 @@ static const struct pad_config s5_sleep_gpio_table[] = { PAD_CFG_GPO(GPP_A18, 0, DEEP), /* EN_PP3300_WWAN */ }; -const struct pad_config * __weak variant_sleep_gpio_table( +const struct pad_config *__weak variant_sleep_gpio_table( u8 slp_typ, size_t *num) { if (slp_typ == ACPI_S5) { diff --git a/src/mainboard/google/hatch/variants/hatch/Makefile.inc b/src/mainboard/google/hatch/variants/hatch/Makefile.inc index cf6ee5ac97d..555cbb463c1 100644 --- a/src/mainboard/google/hatch/variants/hatch/Makefile.inc +++ b/src/mainboard/google/hatch/variants/hatch/Makefile.inc @@ -18,3 +18,5 @@ SPD_SOURCES += 8G_2400 # 0b010 SPD_SOURCES += 8G_2666 # 0b011 SPD_SOURCES += 16G_2400 # 0b100 SPD_SOURCES += 16G_2666 # 0b101 + +ramstage-y += gpio.c diff --git a/src/mainboard/google/hatch/variants/hatch/gpio.c b/src/mainboard/google/hatch/variants/hatch/gpio.c new file mode 100644 index 00000000000..7e737243873 --- /dev/null +++ b/src/mainboard/google/hatch/variants/hatch/gpio.c @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +static const struct pad_config gpio_table[] = { + /* C13 : EC_PCH_INT_L + * TODO Configure it back to invert mode, when + * ITSS IPCx configuration is fixed in FSP. + */ + PAD_CFG_GPI_APIC(GPP_C13, UP_20K, PLTRST, LEVEL, NONE)}; + +const struct pad_config *override_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} diff --git a/src/mainboard/google/hatch/variants/hatch_whl/Makefile.inc b/src/mainboard/google/hatch/variants/hatch_whl/Makefile.inc index 4fa98eacf26..ecf5c2fbdbd 100644 --- a/src/mainboard/google/hatch/variants/hatch_whl/Makefile.inc +++ b/src/mainboard/google/hatch/variants/hatch_whl/Makefile.inc @@ -18,3 +18,5 @@ SPD_SOURCES += empty_ddr4 # 0b010 SPD_SOURCES += empty_ddr4 # 0b011 SPD_SOURCES += empty_ddr4 # 0b100 SPD_SOURCES += 8G_2666 # 0b101 + +ramstage-y += gpio.c diff --git a/src/mainboard/google/hatch/variants/hatch_whl/gpio.c b/src/mainboard/google/hatch/variants/hatch_whl/gpio.c new file mode 100644 index 00000000000..7e737243873 --- /dev/null +++ b/src/mainboard/google/hatch/variants/hatch_whl/gpio.c @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +static const struct pad_config gpio_table[] = { + /* C13 : EC_PCH_INT_L + * TODO Configure it back to invert mode, when + * ITSS IPCx configuration is fixed in FSP. + */ + PAD_CFG_GPI_APIC(GPP_C13, UP_20K, PLTRST, LEVEL, NONE)}; + +const struct pad_config *override_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(gpio_table); + return gpio_table; +} From 478a1212ef0725fe86c59527f5aa30be5606c329 Mon Sep 17 00:00:00 2001 From: Tristan Corrick Date: Wed, 24 Apr 2019 01:24:30 +1200 Subject: [PATCH 078/588] mb/supermicro/x10slm-f: Do SIO setup in bootblock Lynx Point switched to doing mainboard-specific super I/O setup in the bootblock with commit d893a2635fdd ("sb/intel/lynxpoint: Enable LPC/SIO setup in bootblock"). The X10SLM+-F was added while that commit was in review, and hence did not receive the necessary changes to SIO setup. This patch has not been tested on hardware. Change-Id: I7a648ec967dea2113cbbde1a93c1963ca6dd3c88 Signed-off-by: Tristan Corrick Reviewed-on: https://review.coreboot.org/c/coreboot/+/32406 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- .../supermicro/x10slm-f/Makefile.inc | 1 + src/mainboard/supermicro/x10slm-f/bootblock.c | 41 +++++++++++++++++++ src/mainboard/supermicro/x10slm-f/romstage.c | 24 ----------- 3 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 src/mainboard/supermicro/x10slm-f/bootblock.c diff --git a/src/mainboard/supermicro/x10slm-f/Makefile.inc b/src/mainboard/supermicro/x10slm-f/Makefile.inc index ea9cc8ab889..301070b0842 100644 --- a/src/mainboard/supermicro/x10slm-f/Makefile.inc +++ b/src/mainboard/supermicro/x10slm-f/Makefile.inc @@ -15,3 +15,4 @@ ## romstage-y += gpio.c +bootblock-y += bootblock.c diff --git a/src/mainboard/supermicro/x10slm-f/bootblock.c b/src/mainboard/supermicro/x10slm-f/bootblock.c new file mode 100644 index 00000000000..aeffa69e88c --- /dev/null +++ b/src/mainboard/supermicro/x10slm-f/bootblock.c @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Tristan Corrick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +void mainboard_config_superio(void) +{ + const pnp_devfn_t GLOBAL_PSEUDO_DEV = PNP_DEV(0x2e, 0); + const pnp_devfn_t SERIAL_DEV = PNP_DEV(0x2e, NCT6776_SP1); + const pnp_devfn_t ACPI_DEV = PNP_DEV(0x2e, NCT6776_ACPI); + + nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); + + nuvoton_pnp_enter_conf_state(GLOBAL_PSEUDO_DEV); + + /* Select HWM/LED functions instead of floppy functions. */ + pnp_write_config(GLOBAL_PSEUDO_DEV, 0x1c, 0x03); + pnp_write_config(GLOBAL_PSEUDO_DEV, 0x24, 0x24); + + /* Power RAM in S3 and let the PCH handle power failure actions. */ + pnp_set_logical_device(ACPI_DEV); + pnp_write_config(ACPI_DEV, 0xe4, 0x70); + + nuvoton_pnp_exit_conf_state(GLOBAL_PSEUDO_DEV); +} diff --git a/src/mainboard/supermicro/x10slm-f/romstage.c b/src/mainboard/supermicro/x10slm-f/romstage.c index 84ad0477257..e43302af24a 100644 --- a/src/mainboard/supermicro/x10slm-f/romstage.c +++ b/src/mainboard/supermicro/x10slm-f/romstage.c @@ -17,14 +17,11 @@ #include #include -#include #include #include #include #include #include -#include -#include static const struct rcba_config_instruction rcba_config[] = { RCBA_SET_REG_16(D31IR, DIR_ROUTE(PIRQA, PIRQD, PIRQC, PIRQA)), @@ -41,27 +38,6 @@ static const struct rcba_config_instruction rcba_config[] = { RCBA_END_CONFIG, }; -void mainboard_config_superio(void) -{ - const pnp_devfn_t GLOBAL_PSEUDO_DEV = PNP_DEV(0x2e, 0); - const pnp_devfn_t SERIAL_DEV = PNP_DEV(0x2e, NCT6776_SP1); - const pnp_devfn_t ACPI_DEV = PNP_DEV(0x2e, NCT6776_ACPI); - - nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); - - nuvoton_pnp_enter_conf_state(GLOBAL_PSEUDO_DEV); - - /* Select HWM/LED functions instead of floppy functions. */ - pnp_write_config(GLOBAL_PSEUDO_DEV, 0x1c, 0x03); - pnp_write_config(GLOBAL_PSEUDO_DEV, 0x24, 0x24); - - /* Power RAM in S3 and let the PCH handle power failure actions. */ - pnp_set_logical_device(ACPI_DEV); - pnp_write_config(ACPI_DEV, 0xe4, 0x70); - - nuvoton_pnp_exit_conf_state(GLOBAL_PSEUDO_DEV); -} - void mainboard_romstage_entry(unsigned long bist) { struct pei_data pei_data = { From 7391fd8084b1267ca3413e1c12b98bf7d690dfdf Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 23 Apr 2019 09:42:43 -0600 Subject: [PATCH 079/588] mb/google/hatch/: FPMCU not rebooted when DUT reboots Add FP_RST_ODL to early GPIO table, configured as low, so that the FPMCU will get reset when coreboot enters bootblock. BUG=b:130229952 BRANCH=none TEST=Compiles (no Hatch device w/FP to test) Change-Id: I8a8d8cc2c560f6518337f7500575fdc2265b6347 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32419 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg --- src/mainboard/google/hatch/variants/baseboard/gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/hatch/variants/baseboard/gpio.c b/src/mainboard/google/hatch/variants/baseboard/gpio.c index df1c65ea1f1..c12aa640b63 100644 --- a/src/mainboard/google/hatch/variants/baseboard/gpio.c +++ b/src/mainboard/google/hatch/variants/baseboard/gpio.c @@ -441,6 +441,8 @@ const struct pad_config *__weak variant_sleep_gpio_table( /* GPIOs needed prior to ramstage. */ static const struct pad_config early_gpio_table[] = { + /* A12 : FPMCU_RST_ODL */ + PAD_CFG_GPO(GPP_A12, 0, DEEP), /* B15 : H1_SLAVE_SPI_CS_L */ PAD_CFG_NF(GPP_B15, NONE, DEEP, NF1), /* B16 : H1_SLAVE_SPI_CLK */ From 73b0136fa3570c35e0444854d108d7759323a3e7 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 23 Apr 2019 12:03:03 -0500 Subject: [PATCH 080/588] 3rdparty/fsp: Update submodule pointer to upstream master Update submodule pointer to pull in newly-updated Braswell FSP. Adjust FSP_FD_PATH for soc/cannonlake due to filename case change. Change-Id: I02ee0d32fd4c04cd4971eff20fc5a7de3f9b07ec Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32420 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- 3rdparty/fsp | 2 +- src/soc/intel/cannonlake/Kconfig | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/3rdparty/fsp b/3rdparty/fsp index 162719b6cb5..1d2b7e1a94c 160000 --- a/3rdparty/fsp +++ b/3rdparty/fsp @@ -1 +1 @@ -Subproject commit 162719b6cb5efc6c50dcb23dfdb378358573e2b6 +Subproject commit 1d2b7e1a94c6a7c25a6fed1ac37caebf500f5f1a diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 6af05c88481..b730b7a26f3 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -290,7 +290,7 @@ config FSP_HEADER_PATH config FSP_FD_PATH string depends on FSP_USE_REPO - default "3rdparty/fsp/CoffeeLakeFspBinPkg/Fsp.fd" if SOC_INTEL_COFFEELAKE || SOC_INTEL_WHISKEYLAKE + default "3rdparty/fsp/CoffeeLakeFspBinPkg/FSP.fd" if SOC_INTEL_COFFEELAKE || SOC_INTEL_WHISKEYLAKE config SOC_INTEL_CANNONLAKE_DEBUG_CONSENT int "Debug Consent for CNL" From d768e919aec6f4efd52ae109a47be23388d16bf2 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:10:41 +0200 Subject: [PATCH 081/588] src/northbridge/amd: Remove unused variables Change-Id: Ibdfbf1031130ff861c4313d1271d6ccb68bf8837 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/29917 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/northbridge/amd/amdmct/mct/mct_d.c | 12 ++++-------- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 7 +------ src/northbridge/amd/pi/00730F01/northbridge.c | 4 ---- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct/mct_d.c b/src/northbridge/amd/amdmct/mct/mct_d.c index 629bc0f5544..60a2c66de3f 100644 --- a/src/northbridge/amd/amdmct/mct/mct_d.c +++ b/src/northbridge/amd/amdmct/mct/mct_d.c @@ -523,7 +523,7 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, { u8 Node; u32 NextBase, BottomIO; - u8 _MemHoleRemap, DramHoleBase, DramHoleOffset; + u8 _MemHoleRemap, DramHoleBase; u32 HoleSize, DramSelBaseAddr; u32 val; @@ -583,7 +583,6 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO)) base = DramSelBaseAddr; val = ((base + HoleSize) >> (24-8)) & 0xFF; - DramHoleOffset = val; val <<= 8; /* shl 16, rol 24 */ val |= DramHoleBase << 24; val |= 1 << DramHoleValid; @@ -972,7 +971,7 @@ static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, u8 Twr, Trtp; u8 Trp, Trrd, Trcd, Tras, Trc, Trfc[4], Rows; u32 DramTimingLo, DramTimingHi; - u16 Tk10, Tk40; + u16 Tk40; u8 Twtr; u8 LDIMM; u8 DDR2_1066; @@ -1095,7 +1094,6 @@ static u8 AutoCycTiming_D(struct MCTStatStruc *pMCTstat, if (byte == 5) DDR2_1066 = 1; Tk40 = Get_40Tk_D(byte); - Tk10 = Tk40 >> 2; /* Notes: 1. All secondary time values given in SPDs are in binary with units of ns. @@ -1740,7 +1738,7 @@ static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, * and PCI 0:24N:2x60,64,68,6C config registers (CS Mask 0-3). */ - u8 ChipSel, Rows, Cols, Ranks, Banks, DevWidth; + u8 ChipSel, Rows, Cols, Ranks, Banks; u32 BankAddrReg, csMask; u32 val; @@ -1773,7 +1771,6 @@ static void SPDSetBanks_D(struct MCTStatStruc *pMCTstat, Banks = mctRead_SPD(smbaddr, SPD_LBANKS); byte = mctRead_SPD(smbaddr, SPD_DEVWIDTH); - DevWidth = byte & 0x7f; /* bits 0-6 = bank 0 width */ byte = mctRead_SPD(smbaddr, SPD_DMBANKS); Ranks = (byte & 7) + 1; @@ -1933,7 +1930,7 @@ static void StitchMemory_D(struct MCTStatStruc *pMCTstat, u8 b = 0; u32 nxtcsBase, curcsBase; u8 p, q; - u32 Sizeq, BiggestBank; + u32 BiggestBank; u8 _DSpareEn; u16 word; @@ -1989,7 +1986,6 @@ static void StitchMemory_D(struct MCTStatStruc *pMCTstat, val >>= 19; val++; val <<= 19; - Sizeq = val; //never used if (val > BiggestBank) { /*Bingo! possibly Map this chip-select next! */ BiggestBank = val; diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 9178c782d49..74e52345359 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -5164,9 +5164,7 @@ static u8 AutoConfig_D(struct MCTStatStruc *pMCTstat, /* Special Jedec SPD diagnostic bit - "enable all clocks" */ if (!(pDCTstat->Status & (1<>= 19; val++; val <<= 19; - Sizeq = val; /* never used */ if (val > BiggestBank) { /*Bingo! possibly Map this chip-select next! */ BiggestBank = val; @@ -6983,7 +6980,6 @@ static void SetODTTriState(struct MCTStatStruc *pMCTstat, u32 index_reg = 0x98; u8 cs; u8 odt; - u8 max_dimms; dev = pDCTstat->dev_dct; @@ -6993,7 +6989,6 @@ static void SetODTTriState(struct MCTStatStruc *pMCTstat, /* FIXME: skip for Ax */ /* Tri-state unused ODTs when motherboard termination is available */ - max_dimms = (u8) mctGet_NVbits(NV_MAX_DIMMS); odt = 0x0f; /* ODT tri-state setting */ if (pDCTstat->Status & (1 <length; @@ -910,7 +908,6 @@ static void domain_set_resources(struct device *dev) struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info mem_hole; - u32 reset_memhole = 1; #endif pci_tolm = 0xffffffffUL; @@ -941,7 +938,6 @@ static void domain_set_resources(struct device *dev) // Use hole_basek as mmio_basek, and we don't need to reset hole anymore if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) { mmio_basek = mem_hole.hole_startk; - reset_memhole = 0; } #endif From 0f49dd26ad5ee726d5d36c9eefaff72494d0bb3a Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:12:10 +0200 Subject: [PATCH 082/588] src/northbridge/intel: Remove unused variables Change-Id: Idd339e324b833d2d024edb45e33c3d74af4473e8 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32423 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/northbridge/intel/pineview/raminit.c | 17 ++++------------- src/northbridge/intel/x4x/dq_dqs.c | 4 ---- 2 files changed, 4 insertions(+), 17 deletions(-) diff --git a/src/northbridge/intel/pineview/raminit.c b/src/northbridge/intel/pineview/raminit.c index bf00099bab1..48bca36faa2 100644 --- a/src/northbridge/intel/pineview/raminit.c +++ b/src/northbridge/intel/pineview/raminit.c @@ -1173,7 +1173,7 @@ static void sdram_dlltiming(struct sysinfo *s) static void sdram_rcomp(struct sysinfo *s) { - u8 i, j, reg8, f, rcompp, rcompn, srup, srun; + u8 i, j, reg8, rcompp, rcompn, srup, srun; u16 reg16; u32 reg32, rcomp1, rcomp2; @@ -1263,10 +1263,8 @@ static void sdram_rcomp(struct sysinfo *s) srun = 0; if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) { - f = 0; rcomp1 = 0x00050431; } else { - f = 1; rcomp1 = 0x00050542; } if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) { @@ -2125,31 +2123,25 @@ static void sdram_enhancedmode(struct sysinfo *s) reg8 = pci_read_config8(PCI_DEV(0,0,0), 0xf0); pci_write_config8(PCI_DEV(0,0,0), 0xf0, reg8 & ~1); - u32 nranks, curranksize, maxranksize, maxdra, dra; - u8 rankmismatch, dramismatch; + u32 nranks, curranksize, maxranksize, dra; + u8 rankmismatch; static const u8 drbtab[10] = { 0x4, 0x2, 0x8, 0x4, 0x8, 0x4, 0x10, 0x8, 0x20, 0x10 }; nranks = 0; curranksize = 0; maxranksize = 0; - maxdra = 0; rankmismatch = 0; - dramismatch = 0; FOR_EACH_POPULATED_RANK(s->dimms, ch, r) { nranks++; dra = (u8) ((MCHBAR32(0x208) >> (8*r)) & 0x7f); curranksize = drbtab[dra]; if (maxranksize == 0) { maxranksize = curranksize; - maxdra = dra; } if (curranksize != maxranksize) { rankmismatch = 1; } - if (dra != maxdra) { - dramismatch = 1; - } } reg8 = 0; @@ -2220,7 +2212,7 @@ static void sdram_periodic_rcomp(void) static void sdram_new_trd(struct sysinfo *s) { u8 pidelay, i, j, k, cc, trd_perphase[5]; - u8 bypass, freqgb, trd, reg8, txfifo, cas; + u8 bypass, freqgb, trd, reg8, txfifo; u32 reg32, datadelay, tio, rcvendelay, maxrcvendelay; u16 tmclk, thclk, buffertocore, postcalib; static const u8 txfifo_lut[8] = { 0, 7, 6, 5, 2, 1, 4, 3 }; @@ -2236,7 +2228,6 @@ static void sdram_new_trd(struct sysinfo *s) freqgb = 110; buffertocore = 5000; - cas = s->selected_timings.CAS; postcalib = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 1250 : 500; tmclk = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 3000 : 2500; tmclk = tmclk * 100 / freqgb; diff --git a/src/northbridge/intel/x4x/dq_dqs.c b/src/northbridge/intel/x4x/dq_dqs.c index ce184405319..ed372b538f2 100644 --- a/src/northbridge/intel/x4x/dq_dqs.c +++ b/src/northbridge/intel/x4x/dq_dqs.c @@ -282,16 +282,12 @@ int do_write_training(struct sysinfo *s) u8 dq_lower[TOTAL_BYTELANES]; u8 dq_upper[TOTAL_BYTELANES]; struct dll_setting dq_setting[TOTAL_BYTELANES]; - u8 dq_average; - u32 dq_absolute; printk(BIOS_DEBUG, "Starting DQ write training\n"); FOR_EACH_POPULATED_CHANNEL(s->dimms, channel) { printk(BIOS_DEBUG, "Doing DQ write training on CH%d\n", channel); - dq_average = 0; - dq_absolute = 0; /* Start all lanes at DQS values */ FOR_EACH_BYTELANE(lane) { dqset(channel, lane, &s->dqs_settings[channel][lane]); From 358ec83d03d67a0215c6cad7c18f2119b55dc8c2 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:13:07 +0200 Subject: [PATCH 083/588] northbridge/via/vx900: Remove unused variables The `printram` function only expands to a value only in debug builds. This isn't done in default builds. Change-Id: Ic88c4cc730ae2d0d0718c7f71260cd2b45a3ddcd Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32424 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/northbridge/via/vx900/raminit_ddr3.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/northbridge/via/vx900/raminit_ddr3.c b/src/northbridge/via/vx900/raminit_ddr3.c index e03470c7044..4f79ed35b0e 100644 --- a/src/northbridge/via/vx900/raminit_ddr3.c +++ b/src/northbridge/via/vx900/raminit_ddr3.c @@ -554,7 +554,6 @@ static u8 vx900_get_CWL(u8 CAS) static void vx900_dram_timing(ramctr_timing * ctrl) { u8 reg8, val, tFAW, tRRD; - u32 val32; /* Maximum supported DDR3 frequency is 533MHz (DDR3 1066) so make sure * we cap it if we have faster DIMMs. @@ -569,8 +568,7 @@ static void vx900_dram_timing(ramctr_timing * ctrl) ctrl->tCK = TCK_266MHZ; } - val32 = (1000 << 8) / ctrl->tCK; - printram("Selected DRAM frequency: %u MHz\n", val32); + printram("Selected DRAM frequency: %u MHz\n", (1000 << 8) / ctrl->tCK); /* Find CAS and CWL latencies */ val = DIV_ROUND_UP(ctrl->tAA, ctrl->tCK); From a4a9ad58ba685d5755a943c4a267c98a34f21599 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:14:00 +0200 Subject: [PATCH 084/588] src/soc/intel: Remove unused variables Change-Id: Ie81377a31e6527c5fd5aaea99f08527912e870a0 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32425 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/soc/intel/fsp_broadwell_de/acpi.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c index a0c9ee538ef..b1ea0935a72 100644 --- a/src/soc/intel/fsp_broadwell_de/acpi.c +++ b/src/soc/intel/fsp_broadwell_de/acpi.c @@ -433,7 +433,7 @@ static void generate_P_state_entries(int core, int cores_per_package) { int ratio_min, ratio_max, ratio_step; int coord_type, power_max, power_unit, num_entries; - int ratio, power, clock, clock_max; + int ratio, power, clock; int turbo; u32 control_status; msr_t msr; @@ -448,7 +448,6 @@ static void generate_P_state_entries(int core, int cores_per_package) msr = rdmsr(MSR_PLATFORM_INFO); ratio_min = (msr.hi >> 8) & 0xff; // LFM ratio_max = (msr.lo >> 8) & 0xff; // HFM - clock_max = (ratio_max * 100); /* Calculate CPU TDP in mW */ msr = rdmsr(MSR_PKG_POWER_SKU_UNIT); From f4ed5dc7f47b465707170c2ad9bab11826dea12c Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:14:50 +0200 Subject: [PATCH 085/588] src/southbridge/amd: Remove unused variables Change-Id: I143f3395a385e170cce0979707d6a7f61107f40b Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32426 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/southbridge/amd/common/amd_pci_util.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/southbridge/amd/common/amd_pci_util.c b/src/southbridge/amd/common/amd_pci_util.c index 103db988ef7..f10a459bfd5 100644 --- a/src/southbridge/amd/common/amd_pci_util.c +++ b/src/southbridge/amd/common/amd_pci_util.c @@ -100,7 +100,6 @@ void write_pci_cfg_irqs(void) u16 target_pin = 0; /* Pin we will search our tables for */ u16 int_line = 0; /* IRQ number read from PCI_INTR table and programmed to INT_LINE reg 0x3C */ u16 pci_intr_idx = 0; /* Index into PCI_INTR table, 0xC00/0xC01 */ - u8 bus = 0; /* A PCI Device Bus number */ u16 devfn = 0; /* A PCI Device and Function number */ u8 bridged_device = 0; /* This device is on a PCI bridge */ u32 i = 0; @@ -132,7 +131,6 @@ void write_pci_cfg_irqs(void) if (int_pin < 1 || int_pin > 4) continue; /* Device has invalid INT_PIN so skip it */ - bus = target_dev->bus->secondary; devfn = target_dev->path.pci.devfn; /* From d5d433e07f8adf29ef02a2a99596299cc2cf473d Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:15:24 +0200 Subject: [PATCH 086/588] src/southbridge/intel: Remove unused variables Change-Id: I3b5092aa076b9693f78c86ffb9b99805696bb0bb Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32427 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/southbridge/intel/i82371eb/fadt.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/southbridge/intel/i82371eb/fadt.c b/src/southbridge/intel/i82371eb/fadt.c index a05e6688cc6..9515c01371a 100644 --- a/src/southbridge/intel/i82371eb/fadt.c +++ b/src/southbridge/intel/i82371eb/fadt.c @@ -33,11 +33,8 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) { acpi_header_t *header = &(fadt->header); - struct device *dev; /* Power management controller */ - dev = dev_find_device(PCI_VENDOR_ID_INTEL, - PCI_DEVICE_ID_INTEL_82371AB_SMB_ACPI, 0); memset((void *) fadt, 0, sizeof(acpi_fadt_t)); memcpy(header->signature, "FACP", 4); From 05c04556990c74f7d4f3303c33be2c43c3051e20 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:15:57 +0200 Subject: [PATCH 087/588] device/dram/ddr3: Remove unused variable 'param' variable is unused because 'printram' function only expands to something in debug builds (not default ones). Change-Id: I0cdf34cbb9aaed5045db5294eeefeaac642aeb1a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32428 Reviewed-by: Angel Pons Reviewed-by: Jacob Garber Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/device/dram/ddr3.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c index f27fdcb1e01..e545b4d0365 100644 --- a/src/device/dram/ddr3.c +++ b/src/device/dram/ddr3.c @@ -136,7 +136,7 @@ int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd) u8 reg8; u32 mtb; /* medium time base */ u32 ftb; /* fine time base */ - unsigned int val, param; + unsigned int val; ret = SPD_STATUS_OK; @@ -173,8 +173,7 @@ int spd_decode_ddr3(dimm_attr * dimm, spd_raw_data spd) printram(" Invalid number of memory banks\n"); ret = SPD_STATUS_INVALID_FIELD; } - param = 1 << (val + 3); - printram(" Banks : %u\n", param); + printram(" Banks : %u\n", 1 << (val + 3)); /* SDRAM capacity */ capacity_shift = reg8 & 0x0f; if (capacity_shift > 0x06) { From 6ee9ee4cab5bb47f660234400393ac8d2ef50998 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:16:30 +0200 Subject: [PATCH 088/588] drivers/spi/sst: Remove unused variables Change-Id: Ic6eb9c7dbfc5fde97f0f45f09431c617cb850c38 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32429 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/drivers/spi/sst.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/spi/sst.c b/src/drivers/spi/sst.c index 71bdac72a2e..e4ea7805dd3 100644 --- a/src/drivers/spi/sst.c +++ b/src/drivers/spi/sst.c @@ -187,7 +187,7 @@ sst_byte_write(const struct spi_flash *flash, u32 offset, const void *buf) static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len, const void *buf) { - size_t actual, chunk_len, cmd_len; + size_t actual, chunk_len; unsigned long byte_addr; unsigned long page_size; int ret = 0; @@ -208,7 +208,6 @@ static int sst_write_256(const struct spi_flash *flash, u32 offset, size_t len, if (ret) goto done; - cmd_len = 4; cmd[0] = CMD_SST_AAI_WP; cmd[1] = offset >> 16; cmd[2] = offset >> 8; From d84e20b33c9907e671fe44d9955ee5b1540ede80 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:17:04 +0200 Subject: [PATCH 089/588] src/lib/selfboot: Remove unused variables Change-Id: I8d80084095912c30bfd8fc100bf27b522485a08a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32430 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/lib/selfboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index 9aa47413c5c..a0bb711f8a1 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -146,10 +146,10 @@ static int check_payload_segments(struct cbfs_payload_segment *cbfssegs, { uint8_t *dest; size_t memsz; - struct cbfs_payload_segment *first_segment, *seg, segment; + struct cbfs_payload_segment *seg, segment; enum bootmem_type dest_type = *(enum bootmem_type *)args; - for (first_segment = seg = cbfssegs;; ++seg) { + for (seg = cbfssegs;; ++seg) { printk(BIOS_DEBUG, "Checking segment from ROM address 0x%p\n", seg); cbfs_decode_payload_segment(&segment, seg); dest = (uint8_t *)(uintptr_t)segment.load_addr; From 5417c84f7d525d1db8f4abbf3ef4da527dd52cd6 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 23 Apr 2019 22:17:34 +0200 Subject: [PATCH 090/588] soc/cavium/common/bootblock: Remove unused variables Change-Id: I4835ca3e20f2e53598bfc77b633aca946d3fde9c Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32431 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Angel Pons --- src/soc/cavium/common/bootblock.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/soc/cavium/common/bootblock.c b/src/soc/cavium/common/bootblock.c index c3f08668594..0c3b367891e 100644 --- a/src/soc/cavium/common/bootblock.c +++ b/src/soc/cavium/common/bootblock.c @@ -34,16 +34,12 @@ __attribute__((weak)) void bootblock_mainboard_init(void) { /* do nothing */ } void bootblock_main(const uint64_t reg_x0, const uint64_t reg_pc) { - uint64_t base_timestamp = 0; init_timer(); - if (CONFIG(COLLECT_TIMESTAMPS)) - base_timestamp = timestamp_get(); - /* Initialize timestamps if we have TIMESTAMP region in memlayout.ld. */ if (CONFIG(COLLECT_TIMESTAMPS) && REGION_SIZE(timestamp) > 0) - timestamp_init(base_timestamp); + timestamp_init(timestamp_get()); bootblock_soc_early_init(); bootblock_mainboard_early_init(); From 74f9fe6e58f949001a34866505cecca16aa0de03 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 24 Apr 2019 12:29:44 +0200 Subject: [PATCH 091/588] cpu/intel/car/non-evict: Select NO_FIXED_XIP_ROM_SIZE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CPU's featuring a non eviction mode cache the whole ROM. Therefore XIP stages don't need to follow some alignment constraints. Change-Id: I4a30f31baa0f90279c0690ceb6aefea6de461bd9 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32442 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Kyösti Mälkki --- src/cpu/intel/haswell/Kconfig | 1 + src/cpu/intel/model_2065x/Kconfig | 5 +---- src/cpu/intel/model_206ax/Kconfig | 5 +---- src/cpu/intel/socket_FCBGA559/Kconfig | 1 + src/soc/intel/broadwell/Kconfig | 1 + 5 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/cpu/intel/haswell/Kconfig b/src/cpu/intel/haswell/Kconfig index 3fd8bb484a5..5936953b526 100644 --- a/src/cpu/intel/haswell/Kconfig +++ b/src/cpu/intel/haswell/Kconfig @@ -23,6 +23,7 @@ config CPU_SPECIFIC_OPTIONS select CPU_INTEL_FIRMWARE_INTERFACE_TABLE select PARALLEL_MP select CPU_INTEL_COMMON + select NO_FIXED_XIP_ROM_SIZE config SMM_TSEG_SIZE hex diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig index 9481917ff8d..ba2b7de74d8 100644 --- a/src/cpu/intel/model_2065x/Kconfig +++ b/src/cpu/intel/model_2065x/Kconfig @@ -19,6 +19,7 @@ config CPU_SPECIFIC_OPTIONS #select AP_IN_SIPI_WAIT select TSC_SYNC_MFENCE select CPU_INTEL_COMMON + select NO_FIXED_XIP_ROM_SIZE config BOOTBLOCK_CPU_INIT string @@ -28,8 +29,4 @@ config SMM_TSEG_SIZE hex default 0x800000 -config XIP_ROM_SIZE - hex - default 0x20000 - endif diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig index 7f73da9ab4e..f045e9aac51 100644 --- a/src/cpu/intel/model_206ax/Kconfig +++ b/src/cpu/intel/model_206ax/Kconfig @@ -25,15 +25,12 @@ config CPU_SPECIFIC_OPTIONS select CPU_INTEL_COMMON select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select PARALLEL_MP + select NO_FIXED_XIP_ROM_SIZE config BOOTBLOCK_CPU_INIT string default "cpu/intel/model_206ax/bootblock.c" -config XIP_ROM_SIZE - hex - default 0x20000 if USE_NATIVE_RAMINIT - config SMM_TSEG_SIZE hex default 0x800000 diff --git a/src/cpu/intel/socket_FCBGA559/Kconfig b/src/cpu/intel/socket_FCBGA559/Kconfig index 6566a01cf81..b1b310d3cc9 100644 --- a/src/cpu/intel/socket_FCBGA559/Kconfig +++ b/src/cpu/intel/socket_FCBGA559/Kconfig @@ -11,6 +11,7 @@ config SOCKET_SPECIFIC_OPTIONS select MMX select SSE select CPU_HAS_L2_ENABLE_MSR + select NO_FIXED_XIP_ROM_SIZE config DCACHE_RAM_BASE hex diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 5f503da3409..25984f14e20 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -43,6 +43,7 @@ config CPU_SPECIFIC_OPTIONS select POSTCAR_CONSOLE select HAVE_POWER_STATE_AFTER_FAILURE select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE + select NO_FIXED_XIP_ROM_SIZE config PCIEXP_ASPM bool From a11553dabdfbc4641e3fa73a3c4d0cb8eade2ea1 Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Wed, 24 Apr 2019 11:20:01 -0600 Subject: [PATCH 092/588] soc/amd/stoneyridge: Generate MCFG table BUG=crbug:948241 TEST=Booted and decompiled the table [000h 0000 4] Signature : "MCFG" [004h 0004 4] Table Length : 0000003C [008h 0008 1] Revision : 01 [009h 0009 1] Checksum : 15 [00Ah 0010 6] Oem ID : "COREv4" [010h 0016 8] Oem Table ID : "COREBOOT" [018h 0024 4] Oem Revision : 00000000 [01Ch 0028 4] Asl Compiler ID : "CORE" [020h 0032 4] Asl Compiler Revision : 00000000 [024h 0036 8] Reserved : 0000000000000000 [02Ch 0044 8] Base Address : 00000000F8000000 [034h 0052 2] Segment Group Number : 0000 [036h 0054 1] Start Bus Number : 00 [037h 0055 1] End Bus Number : 40 [038h 0056 4] Reserved : 00000000 Change-Id: I46dc1959971af4685a7ffd285429175d6882ae86 Signed-off-by: Raul E Rangel Reviewed-on: https://review.coreboot.org/c/coreboot/+/32445 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Marshall Dawson Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/lpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c index e3475eebcb6..87da9f12711 100644 --- a/src/soc/amd/stoneyridge/lpc.c +++ b/src/soc/amd/stoneyridge/lpc.c @@ -328,7 +328,13 @@ static void lpc_enable_resources(struct device *dev) unsigned long acpi_fill_mcfg(unsigned long current) { - /* Just a dummy */ + + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, + CONFIG_MMCONF_BASE_ADDRESS, + 0, + 0, + CONFIG_MMCONF_BUS_NUMBER); + return current; } From 56d66ae854168f65c9cb6181d89f264778f5e76a Mon Sep 17 00:00:00 2001 From: Gaggery Tsai Date: Thu, 18 Apr 2019 08:54:38 -0700 Subject: [PATCH 093/588] mb/google/poppy/variants/atlas: Revise AC/DC loadline This patch revises the AC/DC loadline settings because some major layout changes between proto and evt boards. BUG=b:130740639 BRANCH=None TEST=emerge-atlas coreboot chromeos-bootimage and boot to the OS. Change-Id: Iea12c621e7fab427a0de8f43f0290bf01d0c5a09 Signed-off-by: Gaggery Tsai Reviewed-on: https://review.coreboot.org/c/coreboot/+/32359 Tested-by: build bot (Jenkins) Reviewed-by: caveh jalali Reviewed-by: Caveh Jalali --- .../google/poppy/variants/atlas/devicetree.cb | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/poppy/variants/atlas/devicetree.cb b/src/mainboard/google/poppy/variants/atlas/devicetree.cb index 53af87d49e3..ad79bcab0e2 100644 --- a/src/mainboard/google/poppy/variants/atlas/devicetree.cb +++ b/src/mainboard/google/poppy/variants/atlas/devicetree.cb @@ -88,8 +88,8 @@ chip soc/intel/skylake #| ImonOffset | 0 | 0 | 0 | 0 | #| IccMax | set by SoC code per CPU SKU | #| VrVoltageLimit | 1.52V | 1.52V | 1.52V | 1.52V | - #| AcLoadline | 14.75 | 4.42 | 4.7 | 4.7 | - #| DcLoadline | 14.2 | 4.2 | 4.41 | 4.41 | + #| AcLoadline | 16.20 | 5.24 | 4.62 | 4.62 | + #| DcLoadline | 14.2 | 4.94 | 4.25 | 4.25 | #+----------------+-------+-------+-------+-------+ register "domain_vr_config[VR_SYSTEM_AGENT]" = "{ .vr_config_enable = 1, @@ -101,7 +101,7 @@ chip soc/intel/skylake .imon_slope = 0x0, .imon_offset = 0x0, .voltage_limit = 1520, - .ac_loadline = 1475, + .ac_loadline = 1620, .dc_loadline = 1420, }" @@ -115,8 +115,8 @@ chip soc/intel/skylake .imon_slope = 0x0, .imon_offset = 0x0, .voltage_limit = 1520, - .ac_loadline = 442, - .dc_loadline = 420, + .ac_loadline = 524, + .dc_loadline = 494, }" register "domain_vr_config[VR_GT_UNSLICED]" = "{ @@ -129,8 +129,8 @@ chip soc/intel/skylake .imon_slope = 0x0, .imon_offset = 0x0, .voltage_limit = 1520, - .ac_loadline = 470, - .dc_loadline = 441, + .ac_loadline = 462, + .dc_loadline = 425, }" register "domain_vr_config[VR_GT_SLICED]" = "{ @@ -143,8 +143,8 @@ chip soc/intel/skylake .imon_slope = 0x0, .imon_offset = 0x0, .voltage_limit = 1520, - .ac_loadline = 470, - .dc_loadline = 441, + .ac_loadline = 462, + .dc_loadline = 425, }" # PCIe Root port 1 with SRCCLKREQ1# (WLAN) From 3be4c7ba64d426d4aa496d70a30555a52e4b3990 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 26 Apr 2019 14:22:02 +0000 Subject: [PATCH 094/588] Revert "mb/google/arcada: Add settings for noise mitgation" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 77fb3632a4a3d3004b3aa4950967be9164d9711d. Reason for revert: This change inadvertently added a submodule. Change-Id: I6cc2a3cd9d88986a2599a5ff2e5a066b1396a8c0 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32472 Reviewed-by: Kyösti Mälkki Reviewed-by: Michał Żygowski Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- coreboot | 1 - src/mainboard/google/sarien/variants/arcada/devicetree.cb | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) delete mode 160000 coreboot diff --git a/coreboot b/coreboot deleted file mode 160000 index 1db39a44661..00000000000 --- a/coreboot +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 1db39a44661f57c2ffe0d795e21c0a4d5dddb494 diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 426bdae88d9..57c4e65e709 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -37,10 +37,10 @@ chip soc/intel/cannonlake register "tdp_pl2_override" = "51" register "Device4Enable" = "1" register "AcousticNoiseMitigation" = "1" - register "SlowSlewRateForIa" = "2" - register "SlowSlewRateForGt" = "2" + register "SlowSlewRateForIa" = "0" + register "SlowSlewRateForGt" = "0" register "SlowSlewRateForSa" = "0" - register "SlowSlewRateForFivr" = "2" + register "SlowSlewRateForFivr" = "0" # Enable eDP device register "DdiPortEdp" = "1" # Enable HPD for DDI ports B/C From 9df72e0471296d9bc2981646490c1f8b5b1e54e0 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 24 Nov 2018 18:25:50 +0100 Subject: [PATCH 095/588] x86/acpi: Add Kconfig to toggle 8259 reporting Change-Id: If3c9783ebc41c103c915788139d91644b805f397 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/29832 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/arch/x86/Kconfig | 8 ++++++++ src/arch/x86/acpi.c | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/Kconfig b/src/arch/x86/Kconfig index 242a7cfa1f9..827c1cba028 100644 --- a/src/arch/x86/Kconfig +++ b/src/arch/x86/Kconfig @@ -265,6 +265,14 @@ config SKIP_MAX_REBOOT_CNT_CLEAR Note that it is the responsibility of the payload to reset the normal boot bit to 1 after each successful boot. +config ACPI_NO_PCAT_8259 + bool + help + Selected by platforms that don't expose a PC/AT 8259 PIC pair. + +config ACPI_HAVE_PCAT_8259 + def_bool y if !ACPI_NO_PCAT_8259 + config ACPI_CPU_STRING string default "\\_PR.CP%02d" diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index f08a401a6e4..8a620bb2c1d 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -229,7 +229,8 @@ void acpi_create_madt(acpi_madt_t *madt) header->revision = get_acpi_table_revision(MADT); madt->lapic_addr = LOCAL_APIC_ADDR; - madt->flags = 0x1; /* PCAT_COMPAT */ + if (CONFIG(ACPI_HAVE_PCAT_8259)) + madt->flags |= 1; current = acpi_fill_madt(current); From c3385070d6e86dbde71dddbdef94ffa5579f9d11 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 21 Mar 2019 15:38:06 +0100 Subject: [PATCH 096/588] soc/{amd,intel}/chip: Use local include for chip.h Change-Id: Ic1fcbf4b54b7d0b5cda04ca9f7fc145050c867b8 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32014 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/soc/amd/stoneyridge/chip.c | 3 ++- src/soc/amd/stoneyridge/northbridge.c | 4 ++-- src/soc/amd/stoneyridge/romstage.c | 3 ++- src/soc/intel/braswell/chip.c | 3 ++- src/soc/intel/braswell/include/soc/ramstage.h | 3 ++- src/soc/intel/braswell/romstage/romstage.c | 3 ++- src/soc/intel/cannonlake/acpi.c | 3 ++- src/soc/intel/cannonlake/chip.c | 3 ++- src/soc/intel/cannonlake/cpu.c | 3 ++- src/soc/intel/cannonlake/finalize.c | 3 ++- src/soc/intel/cannonlake/fsp_params.c | 3 ++- src/soc/intel/cannonlake/include/soc/ramstage.h | 3 ++- src/soc/intel/cannonlake/memmap.c | 3 ++- src/soc/intel/cannonlake/pmc.c | 3 ++- src/soc/intel/cannonlake/romstage/fsp_params.c | 3 ++- src/soc/intel/cannonlake/romstage/romstage.c | 3 ++- src/soc/intel/cannonlake/smihandler.c | 3 ++- src/soc/intel/fsp_broadwell_de/acpi.c | 3 ++- src/soc/intel/fsp_broadwell_de/chip.c | 3 ++- src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c | 3 ++- src/soc/intel/fsp_broadwell_de/southcluster.c | 3 ++- src/soc/intel/icelake/acpi.c | 3 ++- src/soc/intel/icelake/chip.c | 3 ++- src/soc/intel/icelake/cpu.c | 3 ++- src/soc/intel/icelake/finalize.c | 3 ++- src/soc/intel/icelake/include/soc/ramstage.h | 3 ++- src/soc/intel/icelake/memmap.c | 3 ++- src/soc/intel/icelake/pmc.c | 3 ++- src/soc/intel/icelake/romstage/romstage.c | 3 ++- src/soc/intel/icelake/smihandler.c | 3 ++- src/soc/intel/quark/include/soc/ramstage.h | 3 ++- src/soc/intel/skylake/acpi.c | 3 ++- src/soc/intel/skylake/bootblock/pch.c | 3 ++- src/soc/intel/skylake/chip.c | 3 ++- src/soc/intel/skylake/chip_fsp20.c | 3 ++- src/soc/intel/skylake/cpu.c | 3 ++- src/soc/intel/skylake/finalize.c | 3 ++- src/soc/intel/skylake/include/fsp11/soc/ramstage.h | 3 ++- src/soc/intel/skylake/include/fsp20/soc/ramstage.h | 3 ++- src/soc/intel/skylake/memmap.c | 3 ++- src/soc/intel/skylake/pei_data.c | 3 ++- src/soc/intel/skylake/pmc.c | 3 ++- src/soc/intel/skylake/romstage/romstage.c | 3 ++- src/soc/intel/skylake/romstage/romstage_fsp20.c | 3 ++- src/soc/intel/skylake/thermal.c | 3 ++- 45 files changed, 90 insertions(+), 46 deletions(-) diff --git a/src/soc/amd/stoneyridge/chip.c b/src/soc/amd/stoneyridge/chip.c index 033af6ec211..7221f955f6c 100644 --- a/src/soc/amd/stoneyridge/chip.c +++ b/src/soc/amd/stoneyridge/chip.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -30,6 +29,8 @@ #include #include +#include "chip.h" + /* Supplied by i2c.c */ extern struct device_operations stoneyridge_i2c_mmio_ops; extern const char *i2c_acpi_name(const struct device *dev); diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c index 9380d1f945f..42963c09415 100644 --- a/src/soc/amd/stoneyridge/northbridge.c +++ b/src/soc/amd/stoneyridge/northbridge.c @@ -13,13 +13,11 @@ * GNU General Public License for more details. */ - #include #include #include #include #include -#include #include #include #include @@ -42,6 +40,8 @@ #include #include +#include "chip.h" + static void set_io_addr_reg(struct device *dev, u32 nodeid, u32 linkn, u32 reg, u32 io_min, u32 io_max) { diff --git a/src/soc/amd/stoneyridge/romstage.c b/src/soc/amd/stoneyridge/romstage.c index 92922c0662c..12ee2a8aca3 100644 --- a/src/soc/amd/stoneyridge/romstage.c +++ b/src/soc/amd/stoneyridge/romstage.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,8 @@ #include #include +#include "chip.h" + void __weak mainboard_romstage_entry(int s3_resume) { /* By default, don't do anything */ diff --git a/src/soc/intel/braswell/chip.c b/src/soc/intel/braswell/chip.c index 7617d536443..4be13cdea3a 100644 --- a/src/soc/intel/braswell/chip.c +++ b/src/soc/intel/braswell/chip.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -23,6 +22,8 @@ #include #include +#include "chip.h" + static void pci_domain_set_resources(struct device *dev) { printk(BIOS_SPEW, "%s/%s (%s)\n", diff --git a/src/soc/intel/braswell/include/soc/ramstage.h b/src/soc/intel/braswell/include/soc/ramstage.h index d735de58856..f197bc8e1fc 100644 --- a/src/soc/intel/braswell/include/soc/ramstage.h +++ b/src/soc/intel/braswell/include/soc/ramstage.h @@ -17,10 +17,11 @@ #ifndef _SOC_RAMSTAGE_H_ #define _SOC_RAMSTAGE_H_ -#include #include #include +#include "../../chip.h" + #define V_PCH_LPC_RID_A0 0x00 // A0 Stepping #define V_PCH_LPC_RID_A1 0x04 // A1 Stepping #define V_PCH_LPC_RID_A2 0x08 // A2 Stepping diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c index ae2eac8e202..342b05cf508 100644 --- a/src/soc/intel/braswell/romstage/romstage.c +++ b/src/soc/intel/braswell/romstage/romstage.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -44,6 +43,8 @@ #include #include +#include "../chip.h" + void program_base_addresses(void) { uint32_t reg; diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c index 19469dc94fa..209e7c52d4e 100644 --- a/src/soc/intel/cannonlake/acpi.c +++ b/src/soc/intel/cannonlake/acpi.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -38,6 +37,8 @@ #include #include +#include "chip.h" + /* * List of supported C-states in this processor. */ diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c index 845e9ef34ff..1bd34c34e01 100644 --- a/src/soc/intel/cannonlake/chip.c +++ b/src/soc/intel/cannonlake/chip.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -27,6 +26,8 @@ #include #include +#include "chip.h" + #if CONFIG(HAVE_ACPI_TABLES) const char *soc_acpi_name(const struct device *dev) { diff --git a/src/soc/intel/cannonlake/cpu.c b/src/soc/intel/cannonlake/cpu.c index 34b7891ea8b..8552424749b 100644 --- a/src/soc/intel/cannonlake/cpu.c +++ b/src/soc/intel/cannonlake/cpu.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,8 @@ #include #include +#include "chip.h" + /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { [0] = 0x00, diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c index e334555ac0d..4dfd15bc4a6 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -35,6 +34,8 @@ #include #include +#include "chip.h" + #define CAMERA1_CLK 0x8000 /* Camera 1 Clock */ #define CAMERA2_CLK 0x8080 /* Camera 2 Clock */ #define CAM_CLK_EN (1 << 1) diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index 2b83275df10..61d25206939 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include "chip.h" + static const int serial_io_dev[] = { PCH_DEVFN_I2C0, PCH_DEVFN_I2C1, diff --git a/src/soc/intel/cannonlake/include/soc/ramstage.h b/src/soc/intel/cannonlake/include/soc/ramstage.h index 4a96185e6bc..486839852ce 100644 --- a/src/soc/intel/cannonlake/include/soc/ramstage.h +++ b/src/soc/intel/cannonlake/include/soc/ramstage.h @@ -17,11 +17,12 @@ #ifndef _SOC_RAMSTAGE_H_ #define _SOC_RAMSTAGE_H_ -#include #include #include #include +#include "../../chip.h" + void mainboard_silicon_init_params(FSP_S_CONFIG *params); void soc_init_pre_device(void *chip_info); diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c index b2dd26dcf09..3512e2c4b4e 100644 --- a/src/soc/intel/cannonlake/memmap.c +++ b/src/soc/intel/cannonlake/memmap.c @@ -16,7 +16,6 @@ #include #include -#include #include #include #include @@ -28,6 +27,8 @@ #include #include +#include "chip.h" + void smm_region(void **start, size_t *size) { *start = (void *)sa_get_tseg_base(); diff --git a/src/soc/intel/cannonlake/pmc.c b/src/soc/intel/cannonlake/pmc.c index 5cd31f9f97e..6834aa2d17f 100644 --- a/src/soc/intel/cannonlake/pmc.c +++ b/src/soc/intel/cannonlake/pmc.c @@ -16,7 +16,6 @@ */ #include -#include #include #include #include @@ -27,6 +26,8 @@ #include #include +#include "chip.h" + /* * Set which power state system will be after reapplying * the power (from G3 State) diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index ce5863855e9..c71e4b551a5 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include "../chip.h" + static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, const config_t *config) { unsigned int i; diff --git a/src/soc/intel/cannonlake/romstage/romstage.c b/src/soc/intel/cannonlake/romstage/romstage.c index c168da9a384..661c98a466c 100644 --- a/src/soc/intel/cannonlake/romstage/romstage.c +++ b/src/soc/intel/cannonlake/romstage/romstage.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -30,6 +29,8 @@ #include #include +#include "../chip.h" + #define FSP_SMBIOS_MEMORY_INFO_GUID \ { \ 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \ diff --git a/src/soc/intel/cannonlake/smihandler.c b/src/soc/intel/cannonlake/smihandler.c index 643fad645fa..9af291700ba 100644 --- a/src/soc/intel/cannonlake/smihandler.c +++ b/src/soc/intel/cannonlake/smihandler.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -27,6 +26,8 @@ #include #include +#include "chip.h" + #define CSME0_FBE 0xf #define CSME0_BAR 0x0 #define CSME0_FID 0xb0 diff --git a/src/soc/intel/fsp_broadwell_de/acpi.c b/src/soc/intel/fsp_broadwell_de/acpi.c index b1ea0935a72..fef7773cf97 100644 --- a/src/soc/intel/fsp_broadwell_de/acpi.c +++ b/src/soc/intel/fsp_broadwell_de/acpi.c @@ -38,9 +38,10 @@ #include #include #include -#include #include +#include "chip.h" + uint16_t get_pmbase(void) { return ACPI_BASE_ADDRESS; diff --git a/src/soc/intel/fsp_broadwell_de/chip.c b/src/soc/intel/fsp_broadwell_de/chip.c index ba825f4aae3..a0b3f7ca6cd 100644 --- a/src/soc/intel/fsp_broadwell_de/chip.c +++ b/src/soc/intel/fsp_broadwell_de/chip.c @@ -22,7 +22,8 @@ #include #include #include -#include + +#include "chip.h" static void pci_domain_set_resources(struct device *dev) { diff --git a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c index fd8ca38ab6d..edb313e7d5d 100644 --- a/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c +++ b/src/soc/intel/fsp_broadwell_de/fsp/chipset_fsp_util.c @@ -25,9 +25,10 @@ #include #include #include -#include #include +#include "../chip.h" + /* Copy the default UPD region and settings to a buffer for modification */ static void GetUpdDefaultFromFsp (FSP_INFO_HEADER *FspInfo, UPD_DATA_REGION *UpdData) { diff --git a/src/soc/intel/fsp_broadwell_de/southcluster.c b/src/soc/intel/fsp_broadwell_de/southcluster.c index a1e183adca2..2f87cad9dab 100644 --- a/src/soc/intel/fsp_broadwell_de/southcluster.c +++ b/src/soc/intel/fsp_broadwell_de/southcluster.c @@ -32,7 +32,8 @@ #include #include #include -#include + +#include "chip.h" typedef struct soc_intel_fsp_broadwell_de_config config_t; diff --git a/src/soc/intel/icelake/acpi.c b/src/soc/intel/icelake/acpi.c index 1ad89600c1b..f16469eb633 100644 --- a/src/soc/intel/icelake/acpi.c +++ b/src/soc/intel/icelake/acpi.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -32,6 +31,8 @@ #include #include +#include "chip.h" + /* * List of supported C-states in this processor. */ diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c index 464c25e509b..11d14de0842 100644 --- a/src/soc/intel/icelake/chip.c +++ b/src/soc/intel/icelake/chip.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -28,6 +27,8 @@ #include #include +#include "chip.h" + #if CONFIG(HAVE_ACPI_TABLES) const char *soc_acpi_name(const struct device *dev) { diff --git a/src/soc/intel/icelake/cpu.c b/src/soc/intel/icelake/cpu.c index 62bcff68442..b1776a09a46 100644 --- a/src/soc/intel/icelake/cpu.c +++ b/src/soc/intel/icelake/cpu.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -33,6 +32,8 @@ #include #include +#include "chip.h" + static void soc_fsp_load(void) { fsps_load(romstage_handoff_is_resume()); diff --git a/src/soc/intel/icelake/finalize.c b/src/soc/intel/icelake/finalize.c index 3ada73d79c6..c1e6dd0d4af 100644 --- a/src/soc/intel/icelake/finalize.c +++ b/src/soc/intel/icelake/finalize.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,8 @@ #include #include +#include "chip.h" + #define CAMERA1_CLK 0x8000 /* Camera 1 Clock */ #define CAMERA2_CLK 0x8080 /* Camera 2 Clock */ #define CAM_CLK_EN (1 << 1) diff --git a/src/soc/intel/icelake/include/soc/ramstage.h b/src/soc/intel/icelake/include/soc/ramstage.h index d0b500d1353..d78380a6dc3 100644 --- a/src/soc/intel/icelake/include/soc/ramstage.h +++ b/src/soc/intel/icelake/include/soc/ramstage.h @@ -16,11 +16,12 @@ #ifndef _SOC_RAMSTAGE_H_ #define _SOC_RAMSTAGE_H_ -#include #include #include #include +#include "../../chip.h" + void mainboard_silicon_init_params(FSP_S_CONFIG *params); void soc_init_pre_device(void *chip_info); diff --git a/src/soc/intel/icelake/memmap.c b/src/soc/intel/icelake/memmap.c index 821162e768e..7d6e4e65924 100644 --- a/src/soc/intel/icelake/memmap.c +++ b/src/soc/intel/icelake/memmap.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -27,6 +26,8 @@ #include #include +#include "chip.h" + void smm_region(void **start, size_t *size) { *start = (void *)sa_get_tseg_base(); diff --git a/src/soc/intel/icelake/pmc.c b/src/soc/intel/icelake/pmc.c index ac48da24f8a..8f61d70955c 100644 --- a/src/soc/intel/icelake/pmc.c +++ b/src/soc/intel/icelake/pmc.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include "chip.h" + /* * Set which power state system will be after reapplying * the power (from G3 State) diff --git a/src/soc/intel/icelake/romstage/romstage.c b/src/soc/intel/icelake/romstage/romstage.c index b0a2b6c0cd7..1a0c4ffaee6 100644 --- a/src/soc/intel/icelake/romstage/romstage.c +++ b/src/soc/intel/icelake/romstage/romstage.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -30,6 +29,8 @@ #include #include +#include "../chip.h" + #define FSP_SMBIOS_MEMORY_INFO_GUID \ { \ 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \ diff --git a/src/soc/intel/icelake/smihandler.c b/src/soc/intel/icelake/smihandler.c index ddf642003f0..5c00b63720b 100644 --- a/src/soc/intel/icelake/smihandler.c +++ b/src/soc/intel/icelake/smihandler.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include "chip.h" + #define CSME0_FBE 0xf #define CSME0_BAR 0x0 #define CSME0_FID 0xb0 diff --git a/src/soc/intel/quark/include/soc/ramstage.h b/src/soc/intel/quark/include/soc/ramstage.h index 67e37de9430..56be795dcd7 100644 --- a/src/soc/intel/quark/include/soc/ramstage.h +++ b/src/soc/intel/quark/include/soc/ramstage.h @@ -18,11 +18,12 @@ #define _SOC_RAMSTAGE_H_ #include -#include #include #include #include +#include "../../chip.h" + void mainboard_gpio_i2c_init(struct device *dev); asmlinkage void chipset_teardown_car(void); diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index 26a131ddc26..bd944dac16e 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -51,6 +50,8 @@ #include #include +#include "chip.h" + /* * List of suported C-states in this processor. */ diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c index 0f6c8a85d43..c95a8d80e84 100644 --- a/src/soc/intel/skylake/bootblock/pch.c +++ b/src/soc/intel/skylake/bootblock/pch.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include +#include "../chip.h" + #define PCR_DMI_DMICTL 0x2234 #define PCR_DMI_DMICTL_SRLOCK (1 << 31) #define PCR_DMI_ACPIBA 0x27B4 diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c index 9094348e787..6f90178f524 100644 --- a/src/soc/intel/skylake/chip.c +++ b/src/soc/intel/skylake/chip.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include @@ -33,6 +32,8 @@ #include #include +#include "chip.h" + void soc_init_pre_device(void *chip_info) { /* Snapshot the current GPIO IRQ polarities. FSP is setting a diff --git a/src/soc/intel/skylake/chip_fsp20.c b/src/soc/intel/skylake/chip_fsp20.c index c16a913218a..d179598699e 100644 --- a/src/soc/intel/skylake/chip_fsp20.c +++ b/src/soc/intel/skylake/chip_fsp20.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -42,6 +41,8 @@ #include #include +#include "chip.h" + struct pcie_entry { unsigned int devfn; unsigned int func_count; diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 47d484162d8..52b0e194e6e 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -46,6 +45,8 @@ #include #include +#include "chip.h" + /* Convert time in seconds to POWER_LIMIT_1_TIME MSR value */ static const u8 power_limit_time_sec_to_msr[] = { [0] = 0x00, diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index c69dffbe41b..5d7e1e00341 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -41,6 +40,8 @@ #include #include +#include "chip.h" + #define PSF_BASE_ADDRESS 0xA00 #define PCR_PSFX_T0_SHDW_PCIEN 0x1C #define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8) diff --git a/src/soc/intel/skylake/include/fsp11/soc/ramstage.h b/src/soc/intel/skylake/include/fsp11/soc/ramstage.h index 3ab0efa7e56..2071d58b49e 100644 --- a/src/soc/intel/skylake/include/fsp11/soc/ramstage.h +++ b/src/soc/intel/skylake/include/fsp11/soc/ramstage.h @@ -17,11 +17,12 @@ #ifndef _SOC_RAMSTAGE_H_ #define _SOC_RAMSTAGE_H_ -#include #include #include #include +#include "../../../chip.h" + #define FSP_SIL_UPD SILICON_INIT_UPD #define FSP_MEM_UPD MEMORY_INIT_UPD diff --git a/src/soc/intel/skylake/include/fsp20/soc/ramstage.h b/src/soc/intel/skylake/include/fsp20/soc/ramstage.h index e75b3500495..e5660a6f66c 100644 --- a/src/soc/intel/skylake/include/fsp20/soc/ramstage.h +++ b/src/soc/intel/skylake/include/fsp20/soc/ramstage.h @@ -17,11 +17,12 @@ #ifndef _SOC_RAMSTAGE_H_ #define _SOC_RAMSTAGE_H_ -#include #include #include #include +#include "../../../chip.h" + #define FSP_SIL_UPD FSP_S_CONFIG #define FSP_MEM_UPD FSP_M_CONFIG diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c index 60a7070408f..fde916a9221 100644 --- a/src/soc/intel/skylake/memmap.c +++ b/src/soc/intel/skylake/memmap.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,8 @@ #include #include +#include "chip.h" + size_t mmap_region_granularity(void) { if (CONFIG(HAVE_SMI_HANDLER)) diff --git a/src/soc/intel/skylake/pei_data.c b/src/soc/intel/skylake/pei_data.c index a2887ac4c4f..203a1d8e367 100644 --- a/src/soc/intel/skylake/pei_data.c +++ b/src/soc/intel/skylake/pei_data.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -25,6 +24,8 @@ #include #include +#include "chip.h" + static void ABI_X86 send_to_console(unsigned char b) { console_tx_byte(b); diff --git a/src/soc/intel/skylake/pmc.c b/src/soc/intel/skylake/pmc.c index 5ff05c26c25..01def44b069 100644 --- a/src/soc/intel/skylake/pmc.c +++ b/src/soc/intel/skylake/pmc.c @@ -16,7 +16,6 @@ */ #include -#include #include #include #include @@ -28,6 +27,8 @@ #include #include +#include "chip.h" + void pmc_set_disb(void) { /* Set the DISB after DRAM init */ diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index d8188f69245..0501b04493c 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include +#include "../chip.h" + /* SOC initialization before RAM is enabled */ void soc_pre_ram_init(struct romstage_params *params) { diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index dcfc3632ca2..1e81d7aa05c 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -37,6 +36,8 @@ #include #include +#include "../chip.h" + #define FSP_SMBIOS_MEMORY_INFO_GUID \ { \ 0xd4, 0x71, 0x20, 0x9b, 0x54, 0xb0, 0x0c, 0x4e, \ diff --git a/src/soc/intel/skylake/thermal.c b/src/soc/intel/skylake/thermal.c index 711b714b049..97cd1b77793 100644 --- a/src/soc/intel/skylake/thermal.c +++ b/src/soc/intel/skylake/thermal.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -23,6 +22,8 @@ #include #include +#include "chip.h" + #define MAX_TRIP_TEMP 205 #define DEFAULT_TRIP_TEMP 50 From 44c6cf67c325245b4d78915fff4a0ade2b2bec45 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 24 Nov 2018 17:53:17 +0100 Subject: [PATCH 097/588] soc/intel/apl/acpi: Do not report 8259 PICs The IRQ tables don't support this path, so we shouldn't report presence of the legacy PICs. As the _PIC method is optional and we ignore the passed parameter anyway, drop it. Change-Id: I51301a600e16f74fde00fdcb4595e1f47a52e207 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/29833 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Lance Zhao --- src/soc/intel/apollolake/Kconfig | 1 + src/soc/intel/apollolake/acpi/platform.asl | 16 ---------------- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index d715f39eb40..98fdb022e85 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -20,6 +20,7 @@ if SOC_INTEL_APOLLOLAKE config CPU_SPECIFIC_OPTIONS def_bool y select ACPI_INTEL_HARDWARE_SLEEP_VALUES + select ACPI_NO_PCAT_8259 select ARCH_BOOTBLOCK_X86_32 select ARCH_RAMSTAGE_X86_32 select ARCH_ROMSTAGE_X86_32 diff --git a/src/soc/intel/apollolake/acpi/platform.asl b/src/soc/intel/apollolake/acpi/platform.asl index ec1844a512c..f3202a0c48b 100644 --- a/src/soc/intel/apollolake/acpi/platform.asl +++ b/src/soc/intel/apollolake/acpi/platform.asl @@ -18,19 +18,3 @@ /* Enable ACPI _SWS methods */ #include #include - -Name(\PICM, Zero) // IOAPIC/8259 - -/* - * The _PIC method is called by the OS to choose between interrupt - * routing via the i8259 interrupt controller or the APIC. - * - * _PIC is called with a parameter of 0 for i8259 configuration and - * with a parameter of 1 for Local Apic/IOAPIC configuration. - */ - -Method (_PIC, 1) -{ - /* Remember the OS' IRQ routing choice. */ - Store (Arg0, PICM) -} From 76e70675d9ac9c78260c1e42d4c67f8fa1c806ce Mon Sep 17 00:00:00 2001 From: John Zhao Date: Thu, 4 Apr 2019 11:03:28 -0700 Subject: [PATCH 098/588] ACPI: Add RHSA and ANDD structures for DMAR table Remapping Hardware Status Affinity (RHSA) structure is applicable for platforms supporting non-uniform memory. An ACPI Name-space Device Declaration (ANDD) structure uniquely represents an ACPI name-space enumerated device capable of issuing DMA requests in the platform. Add RHSA and ANDD structures support for DMAR table generation. BUG=b:130351429 TEST=Image built and booted to kernel Change-Id: I042925a7c03831061870d9bca03f11bf25aeb3e7 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/32189 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Furquan Shaikh --- src/arch/x86/acpi.c | 27 +++++++++++++++++++++++++++ src/arch/x86/include/arch/acpi.h | 20 ++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index 8a620bb2c1d..d1dcd036527 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -569,6 +569,33 @@ unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, return atsr->length; } +unsigned long acpi_create_dmar_rhsa(unsigned long current, u64 base_addr, + u32 proximity_domain) +{ + dmar_rhsa_entry_t *rhsa = (dmar_rhsa_entry_t *)current; + memset(rhsa, 0, sizeof(*rhsa)); + rhsa->type = DMAR_RHSA; + rhsa->length = sizeof(*rhsa); + rhsa->base_address = base_addr; + rhsa->proximity_domain = proximity_domain; + + return rhsa->length; +} + +unsigned long acpi_create_dmar_andd(unsigned long current, u8 device_number, + const char *device_name) +{ + dmar_andd_entry_t *andd = (dmar_andd_entry_t *)current; + int andd_len = sizeof(dmar_andd_entry_t) + strlen(device_name) + 1; + memset(andd, 0, andd_len); + andd->type = DMAR_ANDD; + andd->length = andd_len; + andd->device_number = device_number; + memcpy(&andd->device_name, device_name, strlen(device_name)); + + return andd->length; +} + void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current) { dmar_entry_t *drhd = (dmar_entry_t *)base; diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index f4ed7440c5a..1b9438d13c8 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -366,6 +366,22 @@ typedef struct dmar_atsr_entry { u16 segment; } __packed dmar_atsr_entry_t; +typedef struct dmar_rhsa_entry { + u16 type; + u16 length; + u32 reserved; + u64 base_address; + u32 proximity_domain; +} __packed dmar_rhsa_entry_t; + +typedef struct dmar_andd_entry { + u16 type; + u16 length; + u8 reserved[3]; + u8 device_number; + u8 device_name[]; +} __packed dmar_andd_entry_t; + /* DMAR (DMA Remapping Reporting Structure) */ typedef struct acpi_dmar { struct acpi_table_header header; @@ -850,6 +866,10 @@ unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment, u64 bar, u64 limit); unsigned long acpi_create_dmar_atsr(unsigned long current, u8 flags, u16 segment); +unsigned long acpi_create_dmar_rhsa(unsigned long current, u64 base_addr, + u32 proximity_domain); +unsigned long acpi_create_dmar_andd(unsigned long current, u8 device_number, + const char *device_name); void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current); void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current); void acpi_dmar_atsr_fixup(unsigned long base, unsigned long current); From a2e7ee729ee955d168d887aa73fe0e77024ec2f3 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 25 Apr 2019 09:06:49 -0700 Subject: [PATCH 099/588] mb/google/sarien: Enable LTR for PCIe NVMe root port Enable LTR for NVMe so it can use ASPM L1.2. BUG=b:127593309 TEST=build and boot on sarien and check L1 substate with lspci before: L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2- ASPM_L1.1+ after: L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ Change-Id: I9842beda6767f758556747f83cfcedbd00612698 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32456 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Roy Mingi Park --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 1 + src/mainboard/google/sarien/variants/sarien/devicetree.cb | 1 + 2 files changed, 2 insertions(+) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 57c4e65e709..cf64c4bb896 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -196,6 +196,7 @@ chip soc/intel/cannonlake # PCIe port 13 for M.2 2280 SSD register "PcieRpEnable[12]" = "1" + register "PcieRpLtrEnable[12]" = "1" register "PcieClkSrcUsage[4]" = "12" register "PcieClkSrcClkReq[4]" = "4" diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 27c0913c6f9..96146baf1e7 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -197,6 +197,7 @@ chip soc/intel/cannonlake # PCIe port 13 for M.2 2280 SSD register "PcieRpEnable[12]" = "1" + register "PcieRpLtrEnable[12]" = "1" register "PcieClkSrcUsage[2]" = "12" register "PcieClkSrcClkReq[2]" = "2" From e7168edeb8dead2699d0bddf98006a8e86823244 Mon Sep 17 00:00:00 2001 From: Daniel Maslowski Date: Fri, 26 Apr 2019 16:33:18 +0200 Subject: [PATCH 100/588] Documentation/northbridge/intel/haswell/mrc.bin.md: add SPD addresses Change-Id: I8bf81637f582373d9bba1d47fe5205d459151f3e Signed-off-by: Daniel Maslowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/32473 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- .../northbridge/intel/haswell/mrc.bin.md | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/Documentation/northbridge/intel/haswell/mrc.bin.md b/Documentation/northbridge/intel/haswell/mrc.bin.md index 36ab4c4385d..edfe4b8b84a 100644 --- a/Documentation/northbridge/intel/haswell/mrc.bin.md +++ b/Documentation/northbridge/intel/haswell/mrc.bin.md @@ -27,6 +27,83 @@ Now, place `mrc.bin` in the root of the coreboot directory. Alternatively, place `mrc.bin` anywhere you want, and set `MRC_FILE` to its location when building coreboot. +## SPD Addresses + +When porting a board from vendor firmware, the SPD addresses can be obtained +through `i2c-tools`, which can be found in many GNU/Linux distributions. A more +[detailed description](https://hannuhartikainen.fi/blog/hacking-ddr3-spd/) of +the procedure and beyond can be found in +[Hannu Hartikainen's blog](https://hannuhartikainen.fi). + +First load the kernel modules: + +```bash +modprobe i2c-dev +modprobe eeprom +``` + +Find the SMBus and the addresses of the DIMM's EEPROMs (example output): +```bash +$ decode-dimms | grep Decoding +Decoding EEPROM: /sys/bus/i2c/drivers/eeprom/7-0050 +Decoding EEPROM: /sys/bus/i2c/drivers/eeprom/7-0052 +``` + +Alternatively, look at the sys filesystem: +```bash +$ ls -l /sys/bus/i2c/drivers/eeprom/ +total 0 +lrwxrwxrwx 1 root root 0 Apr 4 01:46 6-0050 -> ../../../../devices/pci0000:00/0000:00:02.0/drm/card0/card0-eDP-1/i2c-6/6-0050/ +lrwxrwxrwx 1 root root 0 Apr 4 01:46 7-0050 -> ../../../../devices/pci0000:00/0000:00:1f.3/i2c-7/7-0050/ +lrwxrwxrwx 1 root root 0 Apr 4 01:46 7-0052 -> ../../../../devices/pci0000:00/0000:00:1f.3/i2c-7/7-0052/ +--w------- 1 root root 4096 Apr 4 01:47 bind +lrwxrwxrwx 1 root root 0 Apr 4 01:47 module -> ../../../../module/eeprom/ +--w------- 1 root root 4096 Apr 4 01:46 uevent +--w------- 1 root root 4096 Apr 4 01:47 unbind +``` + +The correct I2C bus is 7 in this case, and the EEPROMs are at `0x50` and `0x52`. +Note that the above values are actually hex values. + +You can check the correctness of the SMBus and the addresses of the EEPROMs via +`i2cdetect`: + +```bash +$ i2cdetect -l +i2c-3 unknown i915 gmbus dpc N/A +i2c-1 unknown i915 gmbus vga N/A +i2c-6 unknown DPDDC-A N/A +i2c-4 unknown i915 gmbus dpb N/A +i2c-2 unknown i915 gmbus panel N/A +i2c-0 unknown i915 gmbus ssc N/A +i2c-7 unknown SMBus I801 adapter at f040 N/A +i2c-5 unknown i915 gmbus dpd N/A +``` + +Probing the SMBus: + +```bash +$ i2cdetect -r 7 +WARNING! This program can confuse your I2C bus, cause data loss and worse! +I will probe file /dev/i2c-7 using receive byte commands. +I will probe address range 0x03-0x77. +Continue? [Y/n] + 0 1 2 3 4 5 6 7 8 9 a b c d e f +00: -- -- -- -- -- -- -- -- -- -- -- -- -- +10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +30: 30 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +40: -- -- -- -- 44 -- -- -- -- -- -- -- -- -- -- -- +50: UU -- UU -- -- -- -- -- -- -- -- -- -- -- -- -- +60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- +70: -- -- -- -- -- -- -- -- +``` + +The SPD addresses need to be left-shifted by 1 for `mrc.bin`, i.e., multiplied +by 2. For example, if the addresses read through `i2c-tools` when booted from +vendor firmware are `0x50` and `0x52`, the correct values would be `0xa0` and +`0xa4`. This is because the I2C addresses are 7 bits long. + ## ECC DRAM When `mrc.bin` has finished executing, ECC is active on the channels From e54c15aa729d2b9ae2978e1aedf4fd7bc92cf97d Mon Sep 17 00:00:00 2001 From: Lukasz Siudut Date: Wed, 24 Apr 2019 12:00:10 +0100 Subject: [PATCH 101/588] mb/ocp/monolake: add TPM and IPMI support Changes includes: - enable TPM1 + add entry in devicetree - configure LPC IO to make IPMI work + add entry in devicetree - introduce DSDT and SMBIOS entries for IPMI to make it detectable by ipmi_si driver Signed-off-by: Lukasz Siudut Change-Id: Ia975643064075f1f861f4ead6f24ed71f345ea04 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32443 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Philipp Deppenwiese --- src/mainboard/ocp/monolake/Kconfig | 5 ++ src/mainboard/ocp/monolake/devicetree.cb | 9 ++- src/mainboard/ocp/monolake/dsdt.asl | 95 ++++++++++++++++++++++++ src/mainboard/ocp/monolake/mainboard.c | 34 +++++++++ src/mainboard/ocp/monolake/romstage.c | 8 +- 5 files changed, 148 insertions(+), 3 deletions(-) diff --git a/src/mainboard/ocp/monolake/Kconfig b/src/mainboard/ocp/monolake/Kconfig index aff6619b873..037c3226201 100644 --- a/src/mainboard/ocp/monolake/Kconfig +++ b/src/mainboard/ocp/monolake/Kconfig @@ -11,6 +11,11 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_FSP_BIN if FSP_PACKAGE_DEFAULT select SERIRQ_CONTINUOUS_MODE select MAINBOARD_USES_IFD_GBE_REGION + select MAINBOARD_HAS_LPC_TPM + select MAINBOARD_HAS_TPM1 + +config INTEGRATED_UART + def_bool n config MAINBOARD_DIR string diff --git a/src/mainboard/ocp/monolake/devicetree.cb b/src/mainboard/ocp/monolake/devicetree.cb index 30d99c22ebe..2d91b73b023 100644 --- a/src/mainboard/ocp/monolake/devicetree.cb +++ b/src/mainboard/ocp/monolake/devicetree.cb @@ -7,7 +7,14 @@ chip soc/intel/fsp_broadwell_de device pci 14.0 on end # xHCI Controller device pci 19.0 on end # Gigabit LAN Controller device pci 1d.0 on end # EHCI Controller - device pci 1f.0 on end # LPC Bridge + device pci 1f.0 on + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + chip drivers/generic/generic # BMC KCS + device pnp ca2.0 on end + end + end # LPC Bridge device pci 1f.2 on end # SATA Controller device pci 1f.3 on end # SMBus Controller device pci 1f.5 on end # SATA Controller diff --git a/src/mainboard/ocp/monolake/dsdt.asl b/src/mainboard/ocp/monolake/dsdt.asl index 1248703266a..72b1c3c0868 100644 --- a/src/mainboard/ocp/monolake/dsdt.asl +++ b/src/mainboard/ocp/monolake/dsdt.asl @@ -27,6 +27,9 @@ DefinitionBlock( { #include "acpi/platform.asl" + Name (IDTP, 0x0CA2) + Name (ICDP, 0x0CA6) + Name(_S0, Package() { 0x00, 0x00, 0x00, 0x00 }) Name(_S5, Package() { 0x07, 0x00, 0x00, 0x00 }) @@ -290,5 +293,97 @@ DefinitionBlock( } } + Scope (_SB.PCI0.LPC0) + { + Device (SPMI) + { + Name (_HID, EisaId ("IPI0001")) + Name (_STR, Unicode ("IPMI_KCS")) + Name (_UID, 0x00) + OperationRegion (IPST, SystemIO, ICDP, 0x01) + Field (IPST, ByteAcc, NoLock, Preserve) + { + STAS, 8 + } + Method (_STA, 0, NotSerialized) { + Return (0x0f) + } + Name (ICRS, ResourceTemplate () + { + IO (Decode16, + 0x0000, + 0x0000, + 0x00, + 0x00, + _Y01) + IO (Decode16, + 0x0000, + 0x0000, + 0x00, + 0x00, + _Y02) + + }) + Method (_CRS, 0, NotSerialized) + { + CreateWordField (ICRS, \_SB.PCI0.LPC0.SPMI._Y01._MIN, IPDB) + CreateWordField (ICRS, \_SB.PCI0.LPC0.SPMI._Y01._MAX, IPDH) + CreateByteField (ICRS, \_SB.PCI0.LPC0.SPMI._Y01._LEN, IPDL) + CreateWordField (ICRS, \_SB.PCI0.LPC0.SPMI._Y02._MIN, IPCB) + CreateWordField (ICRS, \_SB.PCI0.LPC0.SPMI._Y02._MAX, IPCH) + CreateByteField (ICRS, \_SB.PCI0.LPC0.SPMI._Y02._LEN, IPCL) + + IPDB = IDTP + IPDH = IDTP + IPDL = 0x01 + + IPCB = ICDP + IPCH = ICDP + IPCL = 0x01 + + Return (ICRS) + } + Method (_IFT, 0, NotSerialized) { + Return (0x01) + } + Method(_SRV, 0, NotSerialized) { + Return (0x0200) + } + } + + Device (SYSR) + { + Name (_HID, EisaId ("PNP0C02")) + + Name (_CRS, ResourceTemplate () // _CRS: Current Resource Settings + { + IO (Decode16, + 0x0CA2, + 0x0CA2, + 0x01, + 0x01, + ) + IO (Decode16, + 0x0CA6, + 0x0CA6, + 0x01, + 0x01, + ) + IO (Decode16, + 0x0CA8, + 0x0CA8, + 0x01, + 0x01, + ) + IO (Decode16, + 0x0CAC, + 0x0CAC, + 0x01, + 0x01, + ) + }) + } + } + #include "acpi/mainboard.asl" } diff --git a/src/mainboard/ocp/monolake/mainboard.c b/src/mainboard/ocp/monolake/mainboard.c index 93c2a58f743..d457859d443 100644 --- a/src/mainboard/ocp/monolake/mainboard.c +++ b/src/mainboard/ocp/monolake/mainboard.c @@ -15,17 +15,51 @@ */ #include +#include #if CONFIG(VGA_ROM_RUN) #include #endif +#define BMC_KCS_BASE 0xca2 +#define INTERFACE_IS_IO 0x1 + +#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) +static int mainboard_smbios_data(struct device *dev, int *handle, + unsigned long *current) +{ + int len = 0; + + // add IPMI Device Information + len += smbios_write_type38( + current, handle, + SMBIOS_BMC_INTERFACE_KCS, + 0x20, // IPMI Version + 0x20, // I2C address + 0xff, // no NV storage + BMC_KCS_BASE | INTERFACE_IS_IO, // IO port interface address + 0x40, + 0); // no IRQ + + return len; +} +#endif + /* * mainboard_enable is executed as first thing after enumerate_buses(). * This is the earliest point to add customization. */ static void mainboard_enable(struct device *dev) { +#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) + dev->ops->get_smbios_data = mainboard_smbios_data; +#endif + /* Enable access to the BMC IPMI via KCS */ + struct device *lpc_sio_dev = dev_find_slot_pnp(BMC_KCS_BASE, 0); + struct resource *res = new_resource(lpc_sio_dev, BMC_KCS_BASE); + res->base = BMC_KCS_BASE; + res->size = 1; + res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; } struct chip_operations mainboard_ops = { diff --git a/src/mainboard/ocp/monolake/romstage.c b/src/mainboard/ocp/monolake/romstage.c index 2bb50f097b4..f3ec7e32b88 100644 --- a/src/mainboard/ocp/monolake/romstage.c +++ b/src/mainboard/ocp/monolake/romstage.c @@ -20,6 +20,9 @@ #include #include #include +#include +#include +#include /** * /brief mainboard call for setup that needs to be done before fsp init @@ -49,7 +52,9 @@ void early_mainboard_romstage_entry(void) */ void late_mainboard_romstage_entry(void) { - + // IPMI through BIC + pci_write_config32(PCI_DEV(0, LPC_DEV, LPC_FUNC), LPC_GEN2_DEC, + 0x0c0ca1); } /** @@ -57,5 +62,4 @@ void late_mainboard_romstage_entry(void) */ void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer) { - } From cb42f4d467846f4b7e0b1dd5ce5f32c4c33e2ff9 Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Fri, 26 Apr 2019 13:29:29 -0600 Subject: [PATCH 102/588] soc/intel/cannonlake: Modify dq_map to provide for 6 entries Intel's DQ_DQS_RComp_Info_Utility generates data for 6 entries. MRC will return errors if we don't have all 6 entries in the map. BRANCH=none BUG=b:131103736 TEST=ensure the firmware builds without error; I don't have hardware available to test this just yet. Change-Id: I20a768de0e4440d7dde7b717794c4e2d0c62819c Signed-off-by: Paul Fagerburg Reviewed-on: https://review.coreboot.org/c/coreboot/+/32475 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../intel/cannonlake/include/soc/cnl_memcfg_init.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h index c6021805924..e602a33f785 100644 --- a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h +++ b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h @@ -52,17 +52,19 @@ struct spd_info { /* Board-specific memory dq mapping information */ struct cnl_mb_cfg { /* - * For each channel, there are 3 sets of DQ byte mappings, + * For each channel, there are 6 sets of DQ byte mappings, * where each set has a package 0 and a package 1 value (package 0 * represents the first 64-bit lpddr4 chip combination, and package 1 * represents the second 64-bit lpddr4 chip combination). * The first three sets are for CLK, CMD, and CTL. - * The fsp package actually expects 6 sets, but the last 3 sets are - * not used in CNL, so we only define the three sets that are used - * and let the meminit_lpddr4() routine take care of clearing the + * The fsp package actually expects 6 sets, even though the last 3 sets + * are not used in CNL. + * We let the meminit_lpddr4() routine take care of clearing the * unused fields for the caller. + * Note that dq_map is only used by LPDDR; it does not need to be + * initialized for designs using DDR4. */ - uint8_t dq_map[DDR_NUM_CHANNELS][3][DDR_NUM_PACKAGES]; + uint8_t dq_map[DDR_NUM_CHANNELS][6][DDR_NUM_PACKAGES]; /* * DQS CPU<>DRAM map Ch0 and Ch1. Each array entry represents a @@ -70,6 +72,8 @@ struct cnl_mb_cfg { * the memory part. The array index represents the dqs bit number * on the memory part, and the values in the array represent which * pin on the CPU that DRAM pin connects to. + * dqs_map is only used by LPDDR; same comments apply as for dq_map + * above. */ uint8_t dqs_map[DDR_NUM_CHANNELS][DQ_BITS_PER_DQS]; From d3d41b348d2af281c08529e7ba7832dca44d4ca9 Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Thu, 18 Apr 2019 16:52:06 -0600 Subject: [PATCH 103/588] mb/google/hatch/variants/kohaku: Add support for LPDDR3 configurations First configuration supported is 8 GB system memory: 4 x 2 GB (K4E6E304ED-EGCG). BRANCH=none BUG=b:129706819 TEST=ensure the firmware builds without error; I don't have hardware available to test this just yet. Signed-off-by: Paul Fagerburg Change-Id: Ibd92d585118ff75492e8a7188dcdb2a286836d56 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32364 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../google/hatch/spd/LP_8G_2133.spd.hex | 32 +++++++ .../google/hatch/variants/kohaku/Makefile.inc | 9 +- .../google/hatch/variants/kohaku/memory.c | 85 +++++++++++++++++++ 3 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/mainboard/google/hatch/spd/LP_8G_2133.spd.hex create mode 100644 src/mainboard/google/hatch/variants/kohaku/memory.c diff --git a/src/mainboard/google/hatch/spd/LP_8G_2133.spd.hex b/src/mainboard/google/hatch/spd/LP_8G_2133.spd.hex new file mode 100644 index 00000000000..5fd8533ab73 --- /dev/null +++ b/src/mainboard/google/hatch/spd/LP_8G_2133.spd.hex @@ -0,0 +1,32 @@ +21 01 0F 0E 15 19 90 08 00 00 00 0B 0B 03 00 00 +00 00 08 FF D4 01 00 00 78 00 90 A8 90 90 06 D0 +02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 08 7F C2 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/google/hatch/variants/kohaku/Makefile.inc b/src/mainboard/google/hatch/variants/kohaku/Makefile.inc index 2f590bf0261..9cdff32074e 100644 --- a/src/mainboard/google/hatch/variants/kohaku/Makefile.inc +++ b/src/mainboard/google/hatch/variants/kohaku/Makefile.inc @@ -12,12 +12,9 @@ ## GNU General Public License for more details. ## -SPD_SOURCES = 4G_2400 # 0b000 -SPD_SOURCES += empty_ddr4 # 0b001 -SPD_SOURCES += 8G_2400 # 0b010 -SPD_SOURCES += 8G_2666 # 0b011 -SPD_SOURCES += 16G_2400 # 0b100 -SPD_SOURCES += 16G_2666 # 0b101 +SPD_SOURCES = LP_8G_2133 # 0b000 + +romstage-y += memory.c bootblock-y += gpio.c ramstage-y += gpio.c diff --git a/src/mainboard/google/hatch/variants/kohaku/memory.c b/src/mainboard/google/hatch/variants/kohaku/memory.c new file mode 100644 index 00000000000..27ae3d8fb26 --- /dev/null +++ b/src/mainboard/google/hatch/variants/kohaku/memory.c @@ -0,0 +1,85 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +static const struct cnl_mb_cfg baseboard_memcfg = { + /* + * The dqs_map arrays map the SoC pins to the lpddr3 pins + * for both channels. + * + * "The index of the array is CPU byte number, the values are DRAM byte + * numbers." - doc #573387 + * + * the index = pin number on SoC + * the value = pin number on lpddr3 part + */ + .dqs_map[DDR_CH0] = { 0, 1, 3, 2, 5, 7, 6, 4 }, + .dqs_map[DDR_CH1] = { 1, 3, 2, 0, 5, 7, 6, 4 }, + + .dq_map[DDR_CH0] = { + {0xf, 0xf0}, + {0x0, 0xf0}, + {0xf, 0xf0}, + {0xf, 0x0}, + {0xff, 0x0}, + {0xff, 0x0} + }, + .dq_map[DDR_CH1] = { + {0xf, 0xf0}, + {0x0, 0xf0}, + {0xf, 0xf0}, + {0xf, 0x0}, + {0xff, 0x0}, + {0xff, 0x0} + }, + + /* Kohaku uses 200, 80.6 and 162 rcomp resistors */ + .rcomp_resistor = { 200, 81, 162 }, + + /* Kohaku Rcomp target values */ + .rcomp_targets = { 100, 40, 40, 23, 40 }, + + /* Set CaVref config to 0 for LPDDR3 */ + .vref_ca_config = 0, + + /* Disable Early Command Training */ + .ect = 0, +}; + +void variant_memory_params(struct cnl_mb_cfg *bcfg) +{ + memcpy(bcfg, &baseboard_memcfg, sizeof(baseboard_memcfg)); + /* + * GPP_F2 is the MEM_CH_SEL gpio, which is set to 1 for single + * channel skus and 0 for dual channel skus. + */ + if (gpio_get(GPP_F2) == 1) { + /* + * Single channel config: for kohaku, Channel 0 is + * always populated. + */ + bcfg->channel_empty[0] = 0; + bcfg->channel_empty[1] = 1; + } else { + /* Dual channel config: both channels populated. */ + bcfg->channel_empty[0] = 0; + bcfg->channel_empty[1] = 0; + } +} From a1b187ab29f16532de413e2d315728cd01d9afca Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Fri, 26 Apr 2019 15:12:21 -0600 Subject: [PATCH 104/588] mb/google/hatch/variants/baseboard: remove unused dqs_map The dqs_map array is used only for LPDDR3 and LPDDR4. It is not used for DDR4, and so it can be removed from the baseboard memory initialization code. BRANCH=none BUG=b:129706819 TEST=ensure the firmware builds without error; I don't have hardware available to test this just yet. Change-Id: I07fac3097d68f37b4630d3f0010f987da2f03bd7 Signed-off-by: Paul Fagerburg Reviewed-on: https://review.coreboot.org/c/coreboot/+/32484 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/variants/baseboard/memory.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/memory.c b/src/mainboard/google/hatch/variants/baseboard/memory.c index b6a66150fa3..580bdc9ab37 100644 --- a/src/mainboard/google/hatch/variants/baseboard/memory.c +++ b/src/mainboard/google/hatch/variants/baseboard/memory.c @@ -20,16 +20,6 @@ #include static const struct cnl_mb_cfg baseboard_memcfg = { - /* - * The dqs_map arrays map the ddr4 pins to the SoC pins - * for both channels. - * - * the index = pin number on ddr4 part - * the value = pin number on SoC - */ - .dqs_map[DDR_CH0] = { 0, 1, 4, 5, 2, 3, 6, 7 }, - .dqs_map[DDR_CH1] = { 0, 1, 4, 5, 2, 3, 6, 7 }, - /* Baseboard uses 121, 81 and 100 rcomp resistors */ .rcomp_resistor = { 121, 81, 100 }, From bac27d5ebbc9114df2e6e43e45bfe3f2b6613e06 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Fri, 26 Apr 2019 15:37:21 +0200 Subject: [PATCH 105/588] soc/intel/braswell: Move LPE ACPI code to mainboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ACPI code of LPE device is included regardless of the availability of the LPE controller. Linux remains requesting the status of device LPEA even if this device is disabled. Include ACPI LPE controller code at Braswell mainboards with LPE enabled. BUG=N/A TEST=Linux 4.17+ on Portwell PQ7-M107 Change-Id: Ic8acf9ea9e9b0ba9b272e20beb2023b7a4716a73 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/29414 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Michał Żygowski --- src/mainboard/google/cyan/dsdt.asl | 1 + src/mainboard/intel/strago/dsdt.asl | 2 +- src/soc/intel/braswell/acpi/southcluster.asl | 3 --- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/cyan/dsdt.asl b/src/mainboard/google/cyan/dsdt.asl index 397f6d2637d..3afdaaab55f 100644 --- a/src/mainboard/google/cyan/dsdt.asl +++ b/src/mainboard/google/cyan/dsdt.asl @@ -42,6 +42,7 @@ DefinitionBlock( #else #include #endif + #include } /* Dynamic Platform Thermal Framework */ diff --git a/src/mainboard/intel/strago/dsdt.asl b/src/mainboard/intel/strago/dsdt.asl index c8be3cea17b..5052ba265c4 100644 --- a/src/mainboard/intel/strago/dsdt.asl +++ b/src/mainboard/intel/strago/dsdt.asl @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ - #include DefinitionBlock( "dsdt.aml", @@ -39,6 +38,7 @@ DefinitionBlock( { #include #include + #include } /* Dynamic Platform Thermal Framework */ diff --git a/src/soc/intel/braswell/acpi/southcluster.asl b/src/soc/intel/braswell/acpi/southcluster.asl index f7e31681267..9ecf67a971a 100644 --- a/src/soc/intel/braswell/acpi/southcluster.asl +++ b/src/soc/intel/braswell/acpi/southcluster.asl @@ -286,7 +286,4 @@ Scope (\_SB.PCI0) /* SCC Devices */ #include "scc.asl" - - /* LPE Device */ - #include "lpe.asl" } From c056729bfdc30eab6ae3729c7ce2a6d58be16604 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 17:57:47 +0200 Subject: [PATCH 106/588] nb/intel/sandybridge: Use system_reset() Use already defined system_reset() function. Change-Id: Ic4716a3bb1dc6c6b29a028fc0ab28f9195f08416 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32493 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Paul Menzel --- src/northbridge/intel/sandybridge/raminit.c | 14 +++++--------- src/northbridge/intel/sandybridge/raminit_mrc.c | 7 +++---- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 050f4c2ba04..cea3f2cd70d 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -312,9 +313,7 @@ static void init_dram_ddr3(int min_tck, int s3resume) && reg_5d10 && !s3resume) { MCHBAR32(0x5d10) = 0; /* Need reset. */ - outb(0x6, 0xcf9); - - halt(); + system_reset(); } early_pch_init_native(); @@ -326,8 +325,7 @@ static void init_dram_ddr3(int min_tck, int s3resume) if (cache_not_found || (region_device_sz(&rdev) < sizeof(ctrl))) { if (s3resume) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } ctrl_cached = NULL; } else { @@ -356,8 +354,7 @@ static void init_dram_ddr3(int min_tck, int s3resume) if (err) { if (s3resume) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* no need to erase bad mrc cache here, it gets overwritten on * successful boot. */ @@ -430,8 +427,7 @@ static void init_dram_ddr3(int min_tck, int s3resume) save_timings(&ctrl); if (s3resume && !cbmem_was_inited) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } if (!s3resume) diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index 8c4f27d9fcb..a68ae49c7cf 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -212,8 +213,7 @@ void sdram_initialize(struct pei_data *pei_data) /* If MRC data is not found we cannot continue S3 resume. */ if (pei_data->boot_mode == 2 && !pei_data->mrc_input) { printk(BIOS_DEBUG, "Giving up in sdram_initialize: No MRC data\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Pass console handler in pei_data */ @@ -310,7 +310,6 @@ void perform_raminit(int s3resume) if (s3resume && !cbmem_was_initted) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } } From 91ead42f4bcfcc41190876343ab1cae2c35fb846 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 26 Apr 2019 15:11:42 +0200 Subject: [PATCH 107/588] Makefile: Check for errors in ACPI decompilation, too We only grep'ed for "ACPI Warning" resulting in an actual more severe "ACPI Error" being ignored. Change-Id: I9cec8a388f5558b1ffc383cc2fc69405252cbb37 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32469 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Paul Menzel Reviewed-by: Frans Hendriks Reviewed-by: Patrick Georgi --- Makefile.inc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index 36c05dbac47..fc04a16fadf 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -267,7 +267,14 @@ $(obj)/$(1).aml: $(src)/mainboard/$(MAINBOARDDIR)/$(1).asl $(obj)/config.h @printf " IASL $$(subst $(top)/,,$$(@))\n" $(CC_ramstage) -x assembler-with-cpp -E -MMD -MT $$(@) $$(CPPFLAGS_ramstage) -D__ACPI__ -P -include $(src)/include/kconfig.h -I$(obj) -I$(src) -I$(src)/include -I$(src)/arch/$(ARCHDIR-$(ARCH-ramstage-y))/include -I$(src)/mainboard/$(MAINBOARDDIR) $$< -o $(obj)/$(1).asl cd $$(dir $$@); $(IASL) $(IGNORED_IASL_WARNINGS) -we -p $$(notdir $$@) $(1).asl - if [ -z "$$$$($(IASL) -d $$@ 2>&1 | grep 'ACPI Warning')" ]; then echo " IASL $$@ disassembled correctly."; true; else echo "Error: Could not correctly disassemble $$@"; $(IASL) -d $$@; false; fi + if ! $(IASL) -d $$@ 2>&1 | grep -Eq 'ACPI (Warning|Error)'; then \ + echo " IASL $$@ disassembled correctly."; \ + true; \ + else \ + echo "Error: Could not correctly disassemble $$@"; \ + $(IASL) -d $$@; \ + false; \ + fi endef ####################################################################### From c126084bc53e0f74f6085f4f84b5bc387d701a4f Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Tue, 23 Apr 2019 15:18:51 -0600 Subject: [PATCH 108/588] soc/intel: Add GPI interrupt config register offset info Add the offset information for GPI interrupt status and enable register in the pad_community structure. Populate the concerned information for individual SoCs. This offset information is required to clear the interrupt configuration during the bootup. BUG=b:130593883 BRANCH=None TEST=Ensure that the interrupt configuration are cleared during bootup. Ensured that the system boots to ChromeOS. Change-Id: I8af877a734e8d49b700d720b736da8764985a8f8 Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/32446 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/apollolake/gpio_apl.c | 8 ++++++++ src/soc/intel/apollolake/gpio_glk.c | 8 ++++++++ src/soc/intel/apollolake/include/soc/gpio_apl.h | 1 + src/soc/intel/apollolake/include/soc/gpio_glk.h | 1 + src/soc/intel/cannonlake/gpio.c | 10 ++++++++++ src/soc/intel/cannonlake/gpio_cnp_h.c | 10 ++++++++++ src/soc/intel/cannonlake/include/soc/gpio_defs.h | 2 ++ src/soc/intel/cannonlake/include/soc/gpio_defs_cnp_h.h | 2 ++ src/soc/intel/common/block/include/intelblocks/gpio.h | 6 ++++-- src/soc/intel/denverton_ns/gpio.c | 8 ++++++++ src/soc/intel/icelake/gpio.c | 10 ++++++++++ src/soc/intel/icelake/include/soc/gpio_defs.h | 2 ++ src/soc/intel/skylake/gpio.c | 8 ++++++++ src/soc/intel/skylake/include/soc/gpio_defs.h | 2 ++ 14 files changed, 76 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/apollolake/gpio_apl.c b/src/soc/intel/apollolake/gpio_apl.c index b76c9b09fe8..10b7ba635bb 100644 --- a/src/soc/intel/apollolake/gpio_apl.c +++ b/src/soc/intel/apollolake/gpio_apl.c @@ -57,6 +57,8 @@ static const struct pad_community apl_gpio_communities[] = { .gpi_status_offset = 0, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -74,6 +76,8 @@ static const struct pad_community apl_gpio_communities[] = { .gpi_status_offset = NUM_SW_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -91,6 +95,8 @@ static const struct pad_community apl_gpio_communities[] = { .gpi_status_offset = NUM_W_GPI_REGS + NUM_SW_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -109,6 +115,8 @@ static const struct pad_community apl_gpio_communities[] = { + NUM_SW_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/apollolake/gpio_glk.c b/src/soc/intel/apollolake/gpio_glk.c index 99f4e4ddc0c..014751905ff 100644 --- a/src/soc/intel/apollolake/gpio_glk.c +++ b/src/soc/intel/apollolake/gpio_glk.c @@ -57,6 +57,8 @@ static const struct pad_community glk_gpio_communities[] = { .gpi_status_offset = 0, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -74,6 +76,8 @@ static const struct pad_community glk_gpio_communities[] = { .gpi_status_offset = NUM_NW_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -91,6 +95,8 @@ static const struct pad_community glk_gpio_communities[] = { .gpi_status_offset = NUM_NW_GPI_REGS + NUM_N_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -109,6 +115,8 @@ static const struct pad_community glk_gpio_communities[] = { NUM_AUDIO_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/apollolake/include/soc/gpio_apl.h b/src/soc/intel/apollolake/include/soc/gpio_apl.h index 67c8a756b6b..ecd9101e76e 100644 --- a/src/soc/intel/apollolake/include/soc/gpio_apl.h +++ b/src/soc/intel/apollolake/include/soc/gpio_apl.h @@ -49,6 +49,7 @@ #define PAD_CFG_BASE 0x500 +#define GPI_INT_STS_0 0x100 #define GPI_INT_EN_0 0x110 #define GPI_SMI_STS_0 0x140 diff --git a/src/soc/intel/apollolake/include/soc/gpio_glk.h b/src/soc/intel/apollolake/include/soc/gpio_glk.h index f1ae49e4577..54ce9526096 100644 --- a/src/soc/intel/apollolake/include/soc/gpio_glk.h +++ b/src/soc/intel/apollolake/include/soc/gpio_glk.h @@ -282,6 +282,7 @@ */ #define HOSTSW_OWN_REG_0 0xB0 +#define GPI_INT_STS_0 0x100 #define GPI_INT_EN_0 0x110 #define GPI_SMI_STS_0 0x170 diff --git a/src/soc/intel/cannonlake/gpio.c b/src/soc/intel/cannonlake/gpio.c index 30ee9398d52..dd514643d73 100644 --- a/src/soc/intel/cannonlake/gpio.c +++ b/src/soc/intel/cannonlake/gpio.c @@ -85,6 +85,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -101,6 +103,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -117,6 +121,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -133,6 +139,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -149,6 +157,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM4_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/cannonlake/gpio_cnp_h.c b/src/soc/intel/cannonlake/gpio_cnp_h.c index d59dea5cbc9..102444a9f81 100644 --- a/src/soc/intel/cannonlake/gpio_cnp_h.c +++ b/src/soc/intel/cannonlake/gpio_cnp_h.c @@ -87,6 +87,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -103,6 +105,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -119,6 +123,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -135,6 +141,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -151,6 +159,8 @@ static const struct pad_community cnl_communities[] = { .num_gpi_regs = NUM_GPIO_COM4_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/cannonlake/include/soc/gpio_defs.h b/src/soc/intel/cannonlake/include/soc/gpio_defs.h index 8a944b1b482..5c12e4cb674 100644 --- a/src/soc/intel/cannonlake/include/soc/gpio_defs.h +++ b/src/soc/intel/cannonlake/include/soc/gpio_defs.h @@ -246,6 +246,8 @@ #define GPE_DW_SHIFT 8 #define GPE_DW_MASK 0xfff00 #define HOSTSW_OWN_REG_0 0xb0 +#define GPI_INT_STS_0 0x100 +#define GPI_INT_EN_0 0x120 #define GPI_SMI_STS_0 0x180 #define GPI_SMI_EN_0 0x1A0 #define PAD_CFG_BASE 0x600 diff --git a/src/soc/intel/cannonlake/include/soc/gpio_defs_cnp_h.h b/src/soc/intel/cannonlake/include/soc/gpio_defs_cnp_h.h index e77dbf88cf6..d03723dae1f 100644 --- a/src/soc/intel/cannonlake/include/soc/gpio_defs_cnp_h.h +++ b/src/soc/intel/cannonlake/include/soc/gpio_defs_cnp_h.h @@ -320,6 +320,8 @@ #define GPE_DW_SHIFT 8 #define GPE_DW_MASK 0xfff00 #define HOSTSW_OWN_REG_0 0xc0 +#define GPI_INT_STS_0 0x100 +#define GPI_INT_EN_0 0x120 #define GPI_SMI_STS_0 0x180 #define GPI_SMI_EN_0 0x1A0 #define PAD_CFG_BASE 0x600 diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 11a03d029cd..147f6897a88 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -105,8 +105,10 @@ struct pad_community { gpio_t first_pad; /* first pad in community */ gpio_t last_pad; /* last pad in community */ uint16_t host_own_reg_0; /* offset to Host Ownership Reg 0 */ - uint16_t gpi_smi_sts_reg_0; /* offset to GPI SMI EN Reg 0 */ - uint16_t gpi_smi_en_reg_0; /* offset to GPI SMI STS Reg 0 */ + uint16_t gpi_int_sts_reg_0; /* offset to GPI Int STS Reg 0 */ + uint16_t gpi_int_en_reg_0; /* offset to GPI Int Enable Reg 0 */ + uint16_t gpi_smi_sts_reg_0; /* offset to GPI SMI STS Reg 0 */ + uint16_t gpi_smi_en_reg_0; /* offset to GPI SMI EN Reg 0 */ uint16_t pad_cfg_base; /* offset to first PAD_GFG_DW0 Reg */ uint8_t gpi_status_offset; /* specifies offset in struct gpi_status */ diff --git a/src/soc/intel/denverton_ns/gpio.c b/src/soc/intel/denverton_ns/gpio.c index 7c45d40de54..64099583a3a 100644 --- a/src/soc/intel/denverton_ns/gpio.c +++ b/src/soc/intel/denverton_ns/gpio.c @@ -58,6 +58,8 @@ static const struct pad_community dnv_gpio_communities[] = { NUM_SC0_GPI_REGS, .pad_cfg_base = R_PCH_PCR_GPIO_SC1_PADCFG_OFFSET, .host_own_reg_0 = R_PCH_PCR_GPIO_SC1_PAD_OWN, + .gpi_int_sts_reg_0 = R_PCH_PCR_GPIO_SC1_GPI_IS, + .gpi_int_en_reg_0 = R_PCH_PCR_GPIO_SC1_GPI_IE, .gpi_smi_sts_reg_0 = R_PCH_PCR_GPIO_SC1_GPI_GPE_STS, .gpi_smi_en_reg_0 = R_PCH_PCR_GPIO_SC1_GPI_GPE_EN, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -75,6 +77,8 @@ static const struct pad_community dnv_gpio_communities[] = { .gpi_status_offset = NUM_NC_GPI_REGS + NUM_SC_DFX_GPI_REGS, .pad_cfg_base = R_PCH_PCR_GPIO_SC0_PADCFG_OFFSET, .host_own_reg_0 = R_PCH_PCR_GPIO_SC0_PAD_OWN, + .gpi_int_sts_reg_0 = R_PCH_PCR_GPIO_SC0_GPI_IS, + .gpi_int_en_reg_0 = R_PCH_PCR_GPIO_SC0_GPI_IE, .gpi_smi_sts_reg_0 = R_PCH_PCR_GPIO_SC0_GPI_GPE_STS, .gpi_smi_en_reg_0 = R_PCH_PCR_GPIO_SC0_GPI_GPE_EN, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -92,6 +96,8 @@ static const struct pad_community dnv_gpio_communities[] = { .gpi_status_offset = NUM_NC_GPI_REGS, .pad_cfg_base = R_PCH_PCR_GPIO_SC_DFX_PADCFG_OFFSET, .host_own_reg_0 = R_PCH_PCR_GPIO_SC_DFX_HOSTSW_OWN, + .gpi_int_sts_reg_0 = R_PCH_PCR_GPIO_SC_DFX_GPI_IS, + .gpi_int_en_reg_0 = R_PCH_PCR_GPIO_SC_DFX_GPI_IE, .gpi_smi_sts_reg_0 = R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_STS, .gpi_smi_en_reg_0 = R_PCH_PCR_GPIO_SC_DFX_GPI_GPE_EN, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -109,6 +115,8 @@ static const struct pad_community dnv_gpio_communities[] = { .gpi_status_offset = 0, .pad_cfg_base = R_PCH_PCR_GPIO_NC_PADCFG_OFFSET, .host_own_reg_0 = R_PCH_PCR_GPIO_NC_PAD_OWN, + .gpi_int_sts_reg_0 = R_PCH_PCR_GPIO_NC_GPI_IS, + .gpi_int_en_reg_0 = R_PCH_PCR_GPIO_NC_GPI_IE, .gpi_smi_sts_reg_0 = R_PCH_PCR_GPIO_NC_GPI_GPE_STS, .gpi_smi_en_reg_0 = R_PCH_PCR_GPIO_NC_GPI_GPE_EN, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/icelake/gpio.c b/src/soc/intel/icelake/gpio.c index 53620054ce8..b1c46abe29d 100644 --- a/src/soc/intel/icelake/gpio.c +++ b/src/soc/intel/icelake/gpio.c @@ -84,6 +84,8 @@ static const struct pad_community icl_communities[] = { .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -100,6 +102,8 @@ static const struct pad_community icl_communities[] = { .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -116,6 +120,8 @@ static const struct pad_community icl_communities[] = { .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -132,6 +138,8 @@ static const struct pad_community icl_communities[] = { .num_gpi_regs = NUM_GPIO_COM4_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -148,6 +156,8 @@ static const struct pad_community icl_communities[] = { .num_gpi_regs = NUM_GPIO_COM5_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/icelake/include/soc/gpio_defs.h b/src/soc/intel/icelake/include/soc/gpio_defs.h index 86d5fb26710..6ecda855d64 100644 --- a/src/soc/intel/icelake/include/soc/gpio_defs.h +++ b/src/soc/intel/icelake/include/soc/gpio_defs.h @@ -265,6 +265,8 @@ #define GPE_DW_SHIFT 8 #define GPE_DW_MASK 0xfff00 #define HOSTSW_OWN_REG_0 0xb0 +#define GPI_INT_STS_0 0x100 +#define GPI_INT_EN_0 0x110 #define GPI_SMI_STS_0 0x180 #define GPI_SMI_EN_0 0x1A0 #define PAD_CFG_BASE 0x600 diff --git a/src/soc/intel/skylake/gpio.c b/src/soc/intel/skylake/gpio.c index 39cbde6cc2d..67edeae126a 100644 --- a/src/soc/intel/skylake/gpio.c +++ b/src/soc/intel/skylake/gpio.c @@ -73,6 +73,8 @@ static const struct pad_community skl_gpio_communities[] = { .num_gpi_regs = NUM_GPIO_COM0_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -93,6 +95,8 @@ static const struct pad_community skl_gpio_communities[] = { .num_gpi_regs = NUM_GPIO_COM1_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -114,6 +118,8 @@ static const struct pad_community skl_gpio_communities[] = { .num_gpi_regs = NUM_GPIO_COM3_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, @@ -130,6 +136,8 @@ static const struct pad_community skl_gpio_communities[] = { .num_gpi_regs = NUM_GPIO_COM2_GPI_REGS, .pad_cfg_base = PAD_CFG_BASE, .host_own_reg_0 = HOSTSW_OWN_REG_0, + .gpi_int_sts_reg_0 = GPI_INT_STS_0, + .gpi_int_en_reg_0 = GPI_INT_EN_0, .gpi_smi_sts_reg_0 = GPI_SMI_STS_0, .gpi_smi_en_reg_0 = GPI_SMI_EN_0, .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP, diff --git a/src/soc/intel/skylake/include/soc/gpio_defs.h b/src/soc/intel/skylake/include/soc/gpio_defs.h index 1c143a2c43c..321d3c20c34 100644 --- a/src/soc/intel/skylake/include/soc/gpio_defs.h +++ b/src/soc/intel/skylake/include/soc/gpio_defs.h @@ -225,6 +225,8 @@ #define GPIO_DRIVER_IRQ_ROUTE_IRQ15 8 #define HOSTSW_OWN_REG_0 0xd0 #define PAD_CFG_BASE 0x400 +#define GPI_INT_STS_0 0x100 +#define GPI_INT_EN_0 0x120 #define GPI_SMI_STS_0 0x180 #define GPI_SMI_EN_0 0x1a0 From 3391a31cf9e74fc9e40d876aa6689e98af38882d Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Wed, 24 Apr 2019 10:12:38 -0600 Subject: [PATCH 109/588] soc/intel/common: Add support to clear GPI IS & IE registers Add support to reset the GPI Interrupt Status & Enable registers so that the system does not experience any interrupt storm from a GPI when it comes out of one of the sleep states. BUG=b:130593883 BRANCH=None TEST=Ensure that the Interrupt status & enable registers are reset during the boot up. Ensure that the system boots fine to ChromeOS. Change-Id: I99f36d88cbab8bb75f12ab1a4d06437f837841cb Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/32447 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/common/block/gpio/gpio.c | 27 +++++++++++++++++++ .../common/block/include/intelblocks/gpio.h | 6 +++++ 2 files changed, 33 insertions(+) diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 47e2817a47b..3a0594cba1f 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -62,6 +62,10 @@ ((group) * sizeof(uint32_t))) #define GPI_SMI_EN_OFFSET(comm, group) ((comm)->gpi_smi_en_reg_0 + \ ((group) * sizeof(uint32_t))) +#define GPI_IS_OFFSET(comm, group) ((comm)->gpi_int_sts_reg_0 + \ + ((group) * sizeof(uint32_t))) +#define GPI_IE_OFFSET(comm, group) ((comm)->gpi_int_en_reg_0 + \ + ((group) * sizeof(uint32_t))) static inline size_t relative_pad_in_comm(const struct pad_community *comm, gpio_t gpio) @@ -582,3 +586,26 @@ uint32_t __weak soc_gpio_pad_config_fixup(const struct pad_config *cfg, { return reg_val; } + +void gpi_clear_int_cfg(void) +{ + int i, group, num_groups; + uint32_t sts_value; + size_t gpio_communities; + const struct pad_community *comm; + + comm = soc_gpio_get_community(&gpio_communities); + for (i = 0; i < gpio_communities; i++, comm++) { + num_groups = comm->num_gpi_regs; + for (group = 0; group < num_groups; group++) { + /* Clear the enable register */ + pcr_write32(comm->port, GPI_IE_OFFSET(comm, group), 0); + + /* Read and clear the set status register bits*/ + sts_value = pcr_read32(comm->port, + GPI_IS_OFFSET(comm, group)); + pcr_write32(comm->port, + GPI_IS_OFFSET(comm, group), sts_value); + } + } +} diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 147f6897a88..417929329f5 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -209,5 +209,11 @@ uint8_t gpio_get_pad_portid(const gpio_t pad); uint32_t soc_gpio_pad_config_fixup(const struct pad_config *cfg, int dw_reg, uint32_t reg_val); +/* + * Function to reset/clear the GPI Interrupt Enable & Status registers for + * all GPIO pad communities. + */ +void gpi_clear_int_cfg(void); + #endif #endif /* _SOC_INTELBLOCKS_GPIO_H_ */ From f81c589ad25580b82a0c61031168385e8057293d Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Wed, 24 Apr 2019 10:19:07 -0600 Subject: [PATCH 110/588] soc/intel/apollolake/bootblock: Clear the GPI IS & IE registers Clear the GPI Interrupt Status & Enable registers to prevent any interrupt storms due to GPI. BUG=b:130593883 BRANCH=octopus TEST=Ensure that the Interrupt status & enable registers are reset during the boot up when the system is brought out of G3, S5 & S3. Ensure that the system boots fine to ChromeOS. Change-Id: Ia3b9d3bf08472219348e20b53bae470c589039fb Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/32448 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/apollolake/bootblock/bootblock.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c index ac6903a9d21..c791378f133 100644 --- a/src/soc/intel/apollolake/bootblock/bootblock.c +++ b/src/soc/intel/apollolake/bootblock/bootblock.c @@ -122,3 +122,12 @@ void bootblock_soc_early_init(void) paging_enable_for_car("pdpt", "pt"); } } + +void bootblock_soc_init(void) +{ + /* + * Clear the GPI interrupt enable & status registers to avoid any + * interrupt storm during the kernel bootup. + */ + gpi_clear_int_cfg(); +} From da79f5c91d94883589a3530f4cc30231a9826bf0 Mon Sep 17 00:00:00 2001 From: Gaggery Tsai Date: Thu, 25 Apr 2019 12:06:23 -0700 Subject: [PATCH 111/588] mb/google/sarien: Add psys_pmax setting to 136W This patch adds the setting of psys_pmax to 136W. According to the design, Rpsys is 11.8Kohm. Here is the equation to come out the Psys_pmax value: Psys_pmax * 1.493uA/W * 11.8Kohm / 2 = 1.2V Hence, Psys_pmax is 136W. BUG=b:124792558 BRANCH=None TEST=emerge-sarien coreboot chromeos-bootimage & Ensure the value is passed to FSP by enabling FSP log & Boot into the OS Change-Id: Id3f6be5f0c2346a7763195a992c0ae45faede056 Signed-off-by: Gaggery Tsai Reviewed-on: https://review.coreboot.org/c/coreboot/+/32457 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/google/sarien/variants/sarien/devicetree.cb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 96146baf1e7..7dd9f154efd 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -43,6 +43,7 @@ chip soc/intel/cannonlake register "SlowSlewRateForFivr" = "2" register "tdp_pl1_override" = "15" register "tdp_pl2_override" = "51" + register "psys_pmax" = "136" register "Device4Enable" = "1" # Enable eDP device register "DdiPortEdp" = "1" From 5a69491a01b6fe32a975aee557348acc84fc7a40 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Thu, 25 Apr 2019 17:14:26 +0800 Subject: [PATCH 112/588] mediatek/mt8183: Init audio related clock Enable audio clock, intbus clock, infra clock and mtkaif 26m clock.Needed by audio playback in firmware. BUG=b:117254418 BRANCH=none TEST=Build pass and verified on kukui p1 board Change-Id: I88060d9796cc23ad7f524943f36869e1ec85073d Signed-off-by: Jiaxin Yu Reviewed-on: https://review.coreboot.org/c/coreboot/+/32458 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin --- src/soc/mediatek/mt8183/pll.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/soc/mediatek/mt8183/pll.c b/src/soc/mediatek/mt8183/pll.c index 61aa2de7fb9..8608b4ac107 100644 --- a/src/soc/mediatek/mt8183/pll.c +++ b/src/soc/mediatek/mt8183/pll.c @@ -356,4 +356,16 @@ void mt_pll_init(void) /* enable [14] dramc_pll104m_ck */ setbits_le32(&mtk_topckgen->clk_misc_cfg_0, 1 << 14); + + /* enable audio clock */ + setbits_le32(&mtk_topckgen->clk_cfg_5_clr, 1 << 7); + + /* enable intbus clock */ + setbits_le32(&mtk_topckgen->clk_cfg_5_clr, 1 << 15); + + /* enable infra clock */ + setbits_le32(&mt8183_infracfg->module_sw_cg_1_clr, 1 << 25); + + /* enable mtkaif 26m clock */ + setbits_le32(&mt8183_infracfg->module_sw_cg_2_clr, 1 << 4); } From 5806665059f1483665c1b2a8ad386e1e90265dcd Mon Sep 17 00:00:00 2001 From: Maxim Polyakov Date: Thu, 25 Apr 2019 12:32:15 +0300 Subject: [PATCH 113/588] soc/skl: set IGD resources only if device is enabled If the Intel IGD device pci 02.0 is disabled or undefined in the device tree, then internal graphics pre-allocated memory and GFX-VT MMIO memory for virtualization won`t be allocated in the SoC address space. Thus, patch resolves the FSP-S hang problem on Skylake/ Kaby Lake processors when the IGD device is disabled. This should provide to run FSP 2.0-based coreboot on these CPUs families without integrated graphics card. The following boards were used for testing: - Asrock H110M-DVS board (desktop i5-6600) & NVIDIA GTX 1060 as external GPU. Virtualization and GFX 3D acceleration with nouveau driver still works well (tested on VirtualBox 5.1.38 with Ubuntu 18.04.1 as guest and host OS) - Intel KBL-R U RVP board (mobile i5-8350u) without GFX. Payload: tianocore edk2-stable201811-216-g51be9d0. Change-Id: Id7a0cba582d83e3fe7e8d20342ee219cdd369a53 Signed-off-by: Maxim Polyakov Reviewed-on: https://review.coreboot.org/c/coreboot/+/32467 Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- .../intel/skylake/include/soc/systemagent.h | 14 +++++++++++--- .../intel/skylake/romstage/romstage_fsp20.c | 18 ++++++++++-------- src/soc/intel/skylake/romstage/systemagent.c | 12 ++++++++---- src/soc/intel/skylake/systemagent.c | 12 +++++++++--- 4 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/soc/intel/skylake/include/soc/systemagent.h b/src/soc/intel/skylake/include/soc/systemagent.h index 8e53f54b750..d7dec65f585 100644 --- a/src/soc/intel/skylake/include/soc/systemagent.h +++ b/src/soc/intel/skylake/include/soc/systemagent.h @@ -48,9 +48,17 @@ bool soc_is_vtd_capable(void); -static const struct sa_mmio_descriptor soc_vtd_resources[] = { - { GFXVTBAR, GFXVT_BASE_ADDRESS, GFXVT_BASE_SIZE, "GFXVTBAR" }, - { VTVC0BAR, VTVC0_BASE_ADDRESS, VTVC0_BASE_SIZE, "VTVC0BAR" }, +static const struct sa_mmio_descriptor soc_gfxvt_mmio_descriptor = { + GFXVTBAR, + GFXVT_BASE_ADDRESS, + GFXVT_BASE_SIZE, + "GFXVTBAR" }; +static const struct sa_mmio_descriptor soc_vtvc0_mmio_descriptor = { + VTVC0BAR, + VTVC0_BASE_ADDRESS, + VTVC0_BASE_SIZE, + "VTVC0BAR" +}; #endif diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index 1e81d7aa05c..c166e3a7c18 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -264,14 +264,6 @@ static void soc_memory_init_params(FSP_M_CONFIG *m_cfg, int i; uint32_t mask = 0; - /* - * Set IGD stolen size to 64MB. The FBC hardware for skylake does not - * have access to the bios_reserved range so it always assumes 8MB is - * used and so the kernel will avoid the last 8MB of the stolen window. - * With the default stolen size of 32MB(-8MB) there is not enough space - * for FBC to work with a high resolution panel. - */ - m_cfg->IgdDvmt50PreAlloc = 2; m_cfg->MmioSize = 0x800; /* 2GB in MB */ m_cfg->TsegSize = CONFIG_SMM_TSEG_SIZE; m_cfg->IedSize = CONFIG_IED_REGION_SIZE; @@ -311,12 +303,22 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, * the FSP does not initialize this device */ m_cfg->InternalGfx = 0; + m_cfg->IgdDvmt50PreAlloc = 0; if (config->PrimaryDisplay == Display_iGFX) m_cfg->PrimaryDisplay = Display_Auto; else m_cfg->PrimaryDisplay = config->PrimaryDisplay; } else { m_cfg->InternalGfx = 1; + /* + * Set IGD stolen size to 64MB. The FBC hardware for skylake + * does not have access to the bios_reserved range so it always + * assumes 8MB is used and so the kernel will avoid the last + * 8MB of the stolen window. With the default stolen size of + * 32MB(-8MB) there is not enough space for FBC to work with + * a high resolution panel + */ + m_cfg->IgdDvmt50PreAlloc = 2; m_cfg->PrimaryDisplay = config->PrimaryDisplay; } } diff --git a/src/soc/intel/skylake/romstage/systemagent.c b/src/soc/intel/skylake/romstage/systemagent.c index 00a27827230..71a9bee1e0e 100644 --- a/src/soc/intel/skylake/romstage/systemagent.c +++ b/src/soc/intel/skylake/romstage/systemagent.c @@ -26,11 +26,12 @@ static void systemagent_vtd_init(void) { - const struct device *const dev = dev_find_slot(0, SA_DEVFN_ROOT); + const struct device *const root_dev = dev_find_slot(0, SA_DEVFN_ROOT); + const struct device *const igd_dev = dev_find_slot(0, SA_DEVFN_IGD); const struct soc_intel_skylake_config *config = NULL; - if (dev) - config = dev->chip_info; + if (root_dev) + config = root_dev->chip_info; if (config && config->ignore_vtd) return; @@ -39,7 +40,10 @@ static void systemagent_vtd_init(void) if (!vtd_capable) return; - sa_set_mch_bar(soc_vtd_resources, ARRAY_SIZE(soc_vtd_resources)); + if (igd_dev && igd_dev->enabled) + sa_set_mch_bar(&soc_gfxvt_mmio_descriptor, 1); + + sa_set_mch_bar(&soc_vtvc0_mmio_descriptor, 1); } void systemagent_early_init(void) diff --git a/src/soc/intel/skylake/systemagent.c b/src/soc/intel/skylake/systemagent.c index fa0cd5e6dbb..bfaadfd3a96 100644 --- a/src/soc/intel/skylake/systemagent.c +++ b/src/soc/intel/skylake/systemagent.c @@ -42,6 +42,7 @@ bool soc_is_vtd_capable(void) */ void soc_add_fixed_mmio_resources(struct device *dev, int *index) { + struct device *const igd_dev = SA_DEV_IGD; static const struct sa_mmio_descriptor soc_fixed_resources[] = { { PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH, "PCIEXBAR" }, @@ -56,9 +57,14 @@ void soc_add_fixed_mmio_resources(struct device *dev, int *index) sa_add_fixed_mmio_resources(dev, index, soc_fixed_resources, ARRAY_SIZE(soc_fixed_resources)); - if (!(config && config->ignore_vtd) && soc_is_vtd_capable()) - sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, - ARRAY_SIZE(soc_vtd_resources)); + if (!(config && config->ignore_vtd) && soc_is_vtd_capable()) { + if (igd_dev && igd_dev->enabled) + sa_add_fixed_mmio_resources(dev, index, + &soc_gfxvt_mmio_descriptor, 1); + + sa_add_fixed_mmio_resources(dev, index, + &soc_vtvc0_mmio_descriptor, 1); + } } /* From c426be6ae29ad345d5f6a42726859fd8457f9814 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Thu, 25 Apr 2019 14:21:52 -0600 Subject: [PATCH 114/588] arcada: add internal pull to ISH UART RX We do not want the RX signal to be floating on the board as that could cause the ISH to remain in a higher power state (because there is logic to keep the ISH in an higher power state when there is an active UART). Add an internal 20K pull up on the RX line. In normal configuration this will burn an additional 544uW. BRANCH=R75 BUG=b:131241969 TEST=verify that ISH console still works with rework Change-Id: Ifc9621bcafe4c86edfa9cd6d58b307254d3a81ca Signed-off-by: Jett Rink Reviewed-on: https://review.coreboot.org/c/coreboot/+/32471 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Duncan Laurie --- src/mainboard/google/sarien/variants/arcada/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/sarien/variants/arcada/gpio.c b/src/mainboard/google/sarien/variants/arcada/gpio.c index a88e0b1190a..da954976573 100644 --- a/src/mainboard/google/sarien/variants/arcada/gpio.c +++ b/src/mainboard/google/sarien/variants/arcada/gpio.c @@ -123,7 +123,7 @@ static const struct pad_config gpio_table[] = { /* ISH_SPI_MISO */ PAD_CFG_GPI(GPP_D11, NONE, DEEP), /* TBT_DET# */ /* ISH_SPI_MOSI */ PAD_NC(GPP_D12, NONE), /* ISH_CPU_UART0_RX */ -/* ISH_UART0_RXD */ PAD_CFG_NF(GPP_D13, NONE, DEEP, NF1), +/* ISH_UART0_RXD */ PAD_CFG_NF(GPP_D13, UP_20K, DEEP, NF1), /* ISH_CPU_UART0_TX */ /* ISH_UART0_TXD */ PAD_CFG_NF(GPP_D14, NONE, DEEP, NF1), /* ISH_UART0_RTS# */ PAD_CFG_GPO(GPP_D15, 1, DEEP), /* WWAN_FULL_PWR_EN */ From 9a1d057f5f25caf42bc12b6ca6da48c5c9fe9d16 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 17 Nov 2018 23:33:40 +0100 Subject: [PATCH 115/588] Revert "soc/intel/common/block: add VMX support" This reverts commit 9aae51ad1141a47d5c2f7133b02f5f0ab6168860. Proper code in cpu/intel/common/ shall be used instead. Change-Id: I4a5d558b03497d106083eece10c5b34e0e7cbb2d Signed-off-by: Nico Huber Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/29683 Reviewed-by: Ronak Kanabar Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- .../common/block/include/intelblocks/vmx.h | 32 -------- src/soc/intel/common/block/vmx/Kconfig | 3 - src/soc/intel/common/block/vmx/Makefile.inc | 1 - src/soc/intel/common/block/vmx/vmx.c | 74 ------------------- 4 files changed, 110 deletions(-) delete mode 100644 src/soc/intel/common/block/include/intelblocks/vmx.h delete mode 100644 src/soc/intel/common/block/vmx/Kconfig delete mode 100644 src/soc/intel/common/block/vmx/Makefile.inc delete mode 100644 src/soc/intel/common/block/vmx/vmx.c diff --git a/src/soc/intel/common/block/include/intelblocks/vmx.h b/src/soc/intel/common/block/include/intelblocks/vmx.h deleted file mode 100644 index b93ceeb8c14..00000000000 --- a/src/soc/intel/common/block/include/intelblocks/vmx.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef SOC_INTEL_COMMON_BLOCK_VMX_H -#define SOC_INTEL_COMMON_BLOCK_VMX_H - -#include - -struct vmx_param { - uint8_t enable; -}; - -/* - * Configure VMX. - */ -void vmx_configure(void *unused); - -/* SOC specific API to get VMX params. - * returns 0, if able to get VMX params; otherwise returns -1 */ -int soc_fill_vmx_param(struct vmx_param *vmx_param); - -#endif /* SOC_INTEL_COMMON_BLOCK_VMX_H */ diff --git a/src/soc/intel/common/block/vmx/Kconfig b/src/soc/intel/common/block/vmx/Kconfig deleted file mode 100644 index f8dce0791fd..00000000000 --- a/src/soc/intel/common/block/vmx/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config SOC_INTEL_COMMON_BLOCK_VMX - bool "Enable VMX for virtualization" - default n diff --git a/src/soc/intel/common/block/vmx/Makefile.inc b/src/soc/intel/common/block/vmx/Makefile.inc deleted file mode 100644 index 861e2f97d20..00000000000 --- a/src/soc/intel/common/block/vmx/Makefile.inc +++ /dev/null @@ -1 +0,0 @@ -ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_VMX) += vmx.c diff --git a/src/soc/intel/common/block/vmx/vmx.c b/src/soc/intel/common/block/vmx/vmx.c deleted file mode 100644 index d0086d080ef..00000000000 --- a/src/soc/intel/common/block/vmx/vmx.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -static bool vmx_param_valid; -static struct vmx_param g_vmx_param; - -static const struct vmx_param *get_vmx_param(void) -{ - if (vmx_param_valid) - return &g_vmx_param; - - memset(&g_vmx_param, 0, sizeof(g_vmx_param)); - if (soc_fill_vmx_param(&g_vmx_param) < 0) { - printk(BIOS_ERR, "VMX : Failed to get soc vmx param\n"); - return NULL; - } - vmx_param_valid = true; - printk(BIOS_INFO, "VMX : param.enable = %d\n", g_vmx_param.enable); - - return &g_vmx_param; -} - -static int soc_vmx_enabled(void) -{ - const struct vmx_param *vmx_param = get_vmx_param(); - return vmx_param ? vmx_param->enable : 0; -} - -void vmx_configure(void *unused) -{ - msr_t msr; - uint32_t feature_flag; - - feature_flag = cpu_get_feature_flags_ecx(); - - if (!soc_vmx_enabled() || !(feature_flag & CPUID_VMX)) { - printk(BIOS_ERR, "VMX: pre-conditions not met\n"); - return; - } - - msr = rdmsr(IA32_FEATURE_CONTROL); - - /* Only enable it when it is not locked */ - if ((msr.lo & FEATURE_CONTROL_LOCK_BIT) == 0) { - /* Enable VMX */ - msr.lo |= FEATURE_ENABLE_VMX; - wrmsr(IA32_FEATURE_CONTROL, msr); - } - - /* Report current status */ - msr = rdmsr(IA32_FEATURE_CONTROL); - printk(BIOS_DEBUG, "VMX status: %s, %s\n", - (msr.lo & FEATURE_ENABLE_VMX) ? "enabled" : "disabled", - (msr.lo & FEATURE_CONTROL_LOCK_BIT) ? "locked" : "unlocked"); -} From 053de0d812ac22921deb39b69a9fdbb17f89033a Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 26 Apr 2019 13:10:10 -0700 Subject: [PATCH 116/588] mb/google/sarien: Update GBB flags Disable the GBB flag forcing manual recovery now that we can read the manual recovery from H1. Enable the GBB flag to skip EC software sync, since images built from coreboot.org do not include the EC binaries by default. Change-Id: I0e1d6304e3e29eda68c7b807cf0774275c37d710 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32476 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/sarien/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index 1e6df57f2f6..c48a908dc18 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -37,7 +37,7 @@ config CHROMEOS select GBB_FLAG_FORCE_DEV_SWITCH_ON select GBB_FLAG_FORCE_DEV_BOOT_USB select GBB_FLAG_FORCE_DEV_BOOT_LEGACY - select GBB_FLAG_FORCE_MANUAL_RECOVERY + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC config DIMM_MAX int From 4114aa8375f152312e9f43260124092f031680a9 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Thu, 25 Apr 2019 17:10:52 +0800 Subject: [PATCH 117/588] vboot: specify NEED_VB20_INTERNALS when needed NEED_VB20_INTERNALS should always be specified when peeking into vboot internal data structures. BUG=b:124141368, chromium:956474 TEST=make clean && make test-abuild BRANCH=none Change-Id: I5a47a28350fd5a68efeff0d06ca150c1ae145412 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32452 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/security/vboot/bootmode.c | 2 ++ src/security/vboot/vboot_handoff.c | 7 ++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/security/vboot/bootmode.c b/src/security/vboot/bootmode.c index 1d6525f966c..e6e53b6f334 100644 --- a/src/security/vboot/bootmode.c +++ b/src/security/vboot/bootmode.c @@ -13,6 +13,8 @@ * GNU General Public License for more details. */ +#define NEED_VB20_INTERNALS /* Peeking into vb2_shared_data */ + #include #include #include diff --git a/src/security/vboot/vboot_handoff.c b/src/security/vboot/vboot_handoff.c index 047fcafb3d8..ff938e15ce8 100644 --- a/src/security/vboot/vboot_handoff.c +++ b/src/security/vboot/vboot_handoff.c @@ -13,11 +13,8 @@ * GNU General Public License for more details. */ -/* This needs to be pulled in first so that the handoff code below and - * peek into the vb2 data structures. Additionally, vboot doesn't currently - * include what it uses in its own headers. Provide the types it's after. - * TODO: fix this necessity. */ -#define NEED_VB20_INTERNALS +#define NEED_VB20_INTERNALS /* Peeking into vb2_shared_data */ + #include #include #include From d95425c51a6cd11a9a22d007afb66ef841359e96 Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Fri, 26 Apr 2019 11:36:13 +0800 Subject: [PATCH 118/588] mediatek/mt8183: Set CPU frequency to 1417MHz With the default CPU voltage (0.8v), CPU frequency should be 1417Mhz at most. We have to raise CPU frequency to 1989MHz after increasing CPU voltage to 1.05v in romstage. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: I4c3e0fa27ccda8e0efe422b6ab503a1efb1697e9 Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32464 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin Reviewed-by: Julius Werner --- src/soc/mediatek/mt8183/include/soc/pll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/mediatek/mt8183/include/soc/pll.h b/src/soc/mediatek/mt8183/include/soc/pll.h index e6f5711549b..2a72e2c61c2 100644 --- a/src/soc/mediatek/mt8183/include/soc/pll.h +++ b/src/soc/mediatek/mt8183/include/soc/pll.h @@ -244,7 +244,7 @@ enum { /* PLL rate */ enum { - ARMPLL_LL_HZ = 1989 * MHz, + ARMPLL_LL_HZ = 1417 * MHz, ARMPLL_L_HZ = 1200 * MHz, CCIPLL_HZ = 598 * 2 * MHz, MAINPLL_HZ = 1092 * MHz, From 3d96f6040901dea0b83939a9bceb49babe91c614 Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Fri, 26 Apr 2019 11:58:30 +0800 Subject: [PATCH 119/588] mediatek: Add function to raise the CPU frequency Implement mt_pll_raise_ca53_freq() in MT8183 to raise the CPU frequency. Move the function declaration to common header. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: Ide8d767486d68177fa2bfbcc5b559879eca1bcda Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32465 Tested-by: build bot (Jenkins) Reviewed-by: Hung-Te Lin Reviewed-by: Julius Werner --- src/soc/mediatek/common/include/soc/pll_common.h | 1 + src/soc/mediatek/mt8173/include/soc/pll.h | 1 - src/soc/mediatek/mt8173/pll.c | 3 ++- src/soc/mediatek/mt8183/Makefile.inc | 1 + src/soc/mediatek/mt8183/pll.c | 5 +++++ 5 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/soc/mediatek/common/include/soc/pll_common.h b/src/soc/mediatek/common/include/soc/pll_common.h index 480371b67c9..d0ffa86c485 100644 --- a/src/soc/mediatek/common/include/soc/pll_common.h +++ b/src/soc/mediatek/common/include/soc/pll_common.h @@ -69,5 +69,6 @@ void pll_set_pcw_change(const struct pll *pll); void mux_set_sel(const struct mux *mux, u32 sel); int pll_set_rate(const struct pll *pll, u32 rate); void mt_pll_init(void); +void mt_pll_raise_ca53_freq(u32 freq); #endif diff --git a/src/soc/mediatek/mt8173/include/soc/pll.h b/src/soc/mediatek/mt8173/include/soc/pll.h index 4106d2a9242..480ffbfb2d6 100644 --- a/src/soc/mediatek/mt8173/include/soc/pll.h +++ b/src/soc/mediatek/mt8173/include/soc/pll.h @@ -292,7 +292,6 @@ enum { void mt_pll_post_init(void); void mt_pll_set_aud_div(u32 rate); void mt_pll_enable_ssusb_clk(void); -void mt_pll_raise_ca53_freq(u32 freq); void mt_mem_pll_set_clk_cfg(void); void mt_mem_pll_config_pre(const struct mt8173_sdram_params *sdram_params); void mt_mem_pll_config_post(void); diff --git a/src/soc/mediatek/mt8173/pll.c b/src/soc/mediatek/mt8173/pll.c index c59fa3f528e..7eb12b12820 100644 --- a/src/soc/mediatek/mt8173/pll.c +++ b/src/soc/mediatek/mt8173/pll.c @@ -432,7 +432,8 @@ void mt_pll_set_aud_div(u32 rate) } } -void mt_pll_raise_ca53_freq(u32 freq) { +void mt_pll_raise_ca53_freq(u32 freq) +{ pll_set_rate(&plls[APMIXED_ARMCA7PLL], freq); /* freq in Hz */ } diff --git a/src/soc/mediatek/mt8183/Makefile.inc b/src/soc/mediatek/mt8183/Makefile.inc index 3fce0a81fd4..5392a9e6358 100644 --- a/src/soc/mediatek/mt8183/Makefile.inc +++ b/src/soc/mediatek/mt8183/Makefile.inc @@ -32,6 +32,7 @@ romstage-$(CONFIG_MEMORY_TEST) += ../common/memory_test.c romstage-y += mt8183.c romstage-y += ../common/gpio.c gpio.c romstage-y += ../common/mmu_operations.c mmu_operations.c +romstage-y += ../common/pll.c pll.c romstage-y += ../common/pmic_wrap.c pmic_wrap.c mt6358.c romstage-y += ../common/rtc.c rtc.c romstage-$(CONFIG_SPI_FLASH) += ../common/spi.c spi.c diff --git a/src/soc/mediatek/mt8183/pll.c b/src/soc/mediatek/mt8183/pll.c index 8608b4ac107..07ce6603f67 100644 --- a/src/soc/mediatek/mt8183/pll.c +++ b/src/soc/mediatek/mt8183/pll.c @@ -369,3 +369,8 @@ void mt_pll_init(void) /* enable mtkaif 26m clock */ setbits_le32(&mt8183_infracfg->module_sw_cg_2_clr, 1 << 4); } + +void mt_pll_raise_ca53_freq(u32 freq) +{ + pll_set_rate(&plls[APMIXED_ARMPLL_LL], freq); +} From cee06c458a915487cf6f5ee7053533f73084b603 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 26 Apr 2019 15:39:21 -0700 Subject: [PATCH 120/588] rockchip/rk3399: Select VBOOT_MIGRATE_WORKING_DATA Trusted Firmware places some components in SRAM on RK3399 and therefore restricts accesses to SRAM to the secure world. This makes the vboot working data inaccessible to normal world payloads, so we need to migrate it into CBMEM. Change-Id: Ic7c95790f2f118ccbdd897550f13b5f987bdd831 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32490 Tested-by: build bot (Jenkins) Reviewed-by: Joel Kitching --- src/soc/rockchip/rk3399/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/rockchip/rk3399/Kconfig b/src/soc/rockchip/rk3399/Kconfig index 6e45df30a21..fb95499efbe 100644 --- a/src/soc/rockchip/rk3399/Kconfig +++ b/src/soc/rockchip/rk3399/Kconfig @@ -17,6 +17,7 @@ config SOC_ROCKCHIP_RK3399 if SOC_ROCKCHIP_RK3399 config VBOOT + select VBOOT_MIGRATE_WORKING_DATA select VBOOT_SEPARATE_VERSTAGE select VBOOT_RETURN_FROM_VERSTAGE select VBOOT_OPROM_MATTERS From b559b3c78548c5b9089bed39c89ff72535f07814 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 17:52:10 +0200 Subject: [PATCH 121/588] nb/x4x: Use system_reset() and full_reset() Use already defined system_reset() and full_reset() functions. Change-Id: I0a05f3ac5c5340a509024de2b444960f498c3e99 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32492 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/x4x/raminit.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c index 4943428d0eb..4d5bdce9ac5 100644 --- a/src/northbridge/intel/x4x/raminit.c +++ b/src/northbridge/intel/x4x/raminit.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -654,13 +655,11 @@ void sdram_initialize(int boot_path, const u8 *spd_map) if (cache_not_found || (region_device_sz(&rdev) < sizeof(s))) { if (boot_path == BOOT_PATH_RESUME) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } else if (boot_path == BOOT_PATH_WARM_RESET) { /* On warm reset some of dram calibrations fail and therefore requiring valid cached settings */ - outb(0xe, 0xcf9); - halt(); + full_reset(); } ctrl_cached = NULL; } else { @@ -728,8 +727,7 @@ void sdram_initialize(int boot_path, const u8 *spd_map) &s, sizeof(s)); if (s.boot_path == BOOT_PATH_RESUME && !cbmem_was_inited) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } timestamp_add_now(TS_AFTER_INITRAM); From 82d4642805bb3d5018e2580c4a7edfc6bdb9138a Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 18:01:48 +0200 Subject: [PATCH 122/588] nb/intel/haswell: Use system_reset() Use already defined system_reset() function. Change-Id: I436f62c4402736fb74c59d8b359d0b3963f0e659 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32494 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/haswell/raminit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index faaa9d04126..fddada4ba0a 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -136,8 +137,7 @@ void sdram_initialize(struct pei_data *pei_data) post_code(POST_RESUME_FAILURE); printk(BIOS_DEBUG, "Giving up in sdram_initialize: " "No MRC data\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Pass console handler in pei_data */ From d45f33804db1e4181e2f657727adc51842aa9a60 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 18:04:35 +0200 Subject: [PATCH 123/588] nb/intel/nehalem: Use system_reset() and full_reset() Use already defined system_reset() and full_reset() functions. Change-Id: Ib7e399b5186aa704d0388c4a4b18480f2e3799f3 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32495 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/nehalem/raminit.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 3164a58fbf2..5b6077f5eae 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -3681,8 +3682,7 @@ void chipset_init(const int s3resume) if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); MCHBAR8(0x2ca8) = 0; - outb(0x6, 0xcf9); - halt(); + system_reset(); } #if 0 if (!s3resume) { @@ -3907,8 +3907,7 @@ void raminit(const int s3resume, const u8 *spd_addrmap) printk(BIOS_INFO, "Interrupted RAM init, reset required.\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } } @@ -4346,8 +4345,7 @@ void raminit(const int s3resume, const u8 *spd_addrmap) "Couldn't find training data. Rebooting\n"); reg32 = inl(DEFAULT_PMBASE + 0x04); outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); - outb(0xe, 0xcf9); - halt(); + full_reset(); } int tm; info.training = *info.cached_training; @@ -4788,7 +4786,6 @@ void raminit(const int s3resume, const u8 *spd_addrmap) outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04); /* Failed S3 resume, reset to come up cleanly */ - outb(0xe, 0xcf9); - halt(); + full_reset(); } } From 363b77177ea4bb7349dc418e355465b84d8accb5 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 18:07:02 +0200 Subject: [PATCH 124/588] nb/intel/pineview: Use system_reset() Use already defined system_reset() function. Change-Id: I32c731de0c30940d15fd01fec6f10b3b33c04370 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32496 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/pineview/romstage.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/pineview/romstage.c b/src/northbridge/intel/pineview/romstage.c index 771434472e2..bdb685b2526 100644 --- a/src/northbridge/intel/pineview/romstage.c +++ b/src/northbridge/intel/pineview/romstage.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -113,8 +114,7 @@ void mainboard_romstage_entry(unsigned long bist) if (!cbmem_was_initted && s3resume) { /* Failed S3 resume, reset to come up cleanly */ - outb(0x6, 0xcf9); - halt(); + system_reset(); } romstage_handoff_init(s3resume); From d07048a7f932aa779dc64d7c503df121c2a76f0b Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 21 Apr 2019 20:17:11 +0200 Subject: [PATCH 125/588] src/mb: Use system_reset() Use already defined system_reset() function. Change-Id: I68ff4cffa2bfab6a15299795c3e1837fc9b85806 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32379 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/apple/macbook21/romstage.c | 4 ++-- src/mainboard/asus/p5gc-mx/romstage.c | 4 ++-- src/mainboard/asus/p5qpl-am/romstage.c | 4 ++-- src/mainboard/getac/p470/romstage.c | 4 ++-- src/mainboard/ibase/mb899/romstage.c | 4 ++-- src/mainboard/intel/dcp847ske/early_southbridge.c | 4 ++-- src/mainboard/kontron/986lcd-m/romstage.c | 4 ++-- src/mainboard/lenovo/t60/romstage.c | 4 ++-- src/mainboard/lenovo/z61t/romstage.c | 4 ++-- src/mainboard/roda/rk886ex/romstage.c | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/mainboard/apple/macbook21/romstage.c b/src/mainboard/apple/macbook21/romstage.c index c524446274a..c056ac8fcbf 100644 --- a/src/mainboard/apple/macbook21/romstage.c +++ b/src/mainboard/apple/macbook21/romstage.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -245,8 +246,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "Soft reset detected, rebooting properly.\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/asus/p5gc-mx/romstage.c b/src/mainboard/asus/p5gc-mx/romstage.c index 6727f4ab885..beb276c7daf 100644 --- a/src/mainboard/asus/p5gc-mx/romstage.c +++ b/src/mainboard/asus/p5gc-mx/romstage.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -214,8 +215,7 @@ void mainboard_romstage_entry(unsigned long bist) if (!s3resume && setup_sio_gpio(c_bsel)) { printk(BIOS_DEBUG, "Needs reset to configure CPU BSEL straps\n"); - outb(0xe, 0xcf9); - halt(); + full_reset(); } /* Enable SPD ROMs and DDR-II DRAM */ diff --git a/src/mainboard/asus/p5qpl-am/romstage.c b/src/mainboard/asus/p5qpl-am/romstage.c index 8ce59799981..4174981ac2e 100644 --- a/src/mainboard/asus/p5qpl-am/romstage.c +++ b/src/mainboard/asus/p5qpl-am/romstage.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -191,8 +192,7 @@ void mainboard_romstage_entry(unsigned long bist) if (!s3_resume && setup_sio_gpio()) { printk(BIOS_DEBUG, "Needs reset to configure CPU BSEL straps\n"); - outb(0xe, 0xcf9); - halt(); + full_reset(); } sdram_initialize(boot_path, spd_addrmap); diff --git a/src/mainboard/getac/p470/romstage.c b/src/mainboard/getac/p470/romstage.c index 81669ed8231..d643b12f8a0 100644 --- a/src/mainboard/getac/p470/romstage.c +++ b/src/mainboard/getac/p470/romstage.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -256,8 +257,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/ibase/mb899/romstage.c b/src/mainboard/ibase/mb899/romstage.c index a35619516d8..7e3b7dba686 100644 --- a/src/mainboard/ibase/mb899/romstage.c +++ b/src/mainboard/ibase/mb899/romstage.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -218,8 +219,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/intel/dcp847ske/early_southbridge.c b/src/mainboard/intel/dcp847ske/early_southbridge.c index 39aeb8f6e26..46f9a94e9e7 100644 --- a/src/mainboard/intel/dcp847ske/early_southbridge.c +++ b/src/mainboard/intel/dcp847ske/early_southbridge.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -53,8 +54,7 @@ void mainboard_rcba_config(void) RCBA32(BUC) &= ~PCH_DISABLE_GBE; /* Datasheet says clearing the bit requires a reset after */ printk(BIOS_DEBUG, "Enabled gigabit ethernet, reset once.\n"); - outb(0xe, 0xcf9); - halt(); + full_reset(); } #endif diff --git a/src/mainboard/kontron/986lcd-m/romstage.c b/src/mainboard/kontron/986lcd-m/romstage.c index 05f9d1fd2a5..3d01eb1e0fe 100644 --- a/src/mainboard/kontron/986lcd-m/romstage.c +++ b/src/mainboard/kontron/986lcd-m/romstage.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -266,8 +267,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c index be71cf4bb23..ea207e80a92 100644 --- a/src/mainboard/lenovo/t60/romstage.c +++ b/src/mainboard/lenovo/t60/romstage.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -195,8 +196,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/lenovo/z61t/romstage.c b/src/mainboard/lenovo/z61t/romstage.c index 86d94a6c853..0d68faca2c6 100644 --- a/src/mainboard/lenovo/z61t/romstage.c +++ b/src/mainboard/lenovo/z61t/romstage.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -196,8 +197,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required diff --git a/src/mainboard/roda/rk886ex/romstage.c b/src/mainboard/roda/rk886ex/romstage.c index efb376cf386..e85da1f4804 100644 --- a/src/mainboard/roda/rk886ex/romstage.c +++ b/src/mainboard/roda/rk886ex/romstage.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -228,8 +229,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required From 5db9871a5ec53dc9a1901133128c367974002ba0 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 21 Apr 2019 18:50:34 +0200 Subject: [PATCH 126/588] ich7/i945: Use system_reset() Use already defined system_reset() function. Change-Id: Ieff4271c4a09d564d5f3415d8bc2c3843c8460f2 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32378 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/i945/early_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c index 0c92c4bd7de..a9de844f150 100644 --- a/src/northbridge/intel/i945/early_init.c +++ b/src/northbridge/intel/i945/early_init.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -518,8 +519,7 @@ static void i945_setup_dmi_rcrb(void) reg32 &= ~(7 << 0); reg32 |= (3 << 0); DMIBAR32(0x224) = reg32; - outb(0x06, 0xcf9); - halt(); /* wait for reset */ + system_reset(); } } } From 46c5807d29a1fae542d22c82f6c07955f0296f78 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 28 Apr 2019 18:17:17 +0200 Subject: [PATCH 127/588] sb/intel/bd82x6x: Use system_reset() Use already defined system_reset() function. Change-Id: I6e5aff96e06830931acf700593d3e1689857efdc Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32497 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Paul Menzel --- src/southbridge/intel/bd82x6x/early_me.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/southbridge/intel/bd82x6x/early_me.c b/src/southbridge/intel/bd82x6x/early_me.c index edb514bda75..f82ed3e9790 100644 --- a/src/southbridge/intel/bd82x6x/early_me.c +++ b/src/southbridge/intel/bd82x6x/early_me.c @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -179,8 +180,7 @@ int intel_early_me_init_done(u8 status) reg16 = pci_read_config16(PCI_DEV(0, 31, 0), 0xa2) & ~0x80; pci_write_config16(PCI_DEV(0, 31, 0), 0xa2, reg16); set_global_reset(0); - outb(0x6, 0xcf9); - halt(); + system_reset(); } if (((me_fws2 & 0x10) == 0x10) && (me_fws2 & 0x80) == 0x00) { From 345d202d662fae57ab7a13432f213cd4109e5e3c Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 15 Apr 2019 16:17:59 +0200 Subject: [PATCH 128/588] Documentation: Add FIT Describe the Firmware Interface Table and reference useful documentation. Change-Id: I00abc1fd13be7b48d56ba8cb65d2542ed07f9017 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32325 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- Documentation/soc/intel/fit.dia | Bin 0 -> 3178 bytes Documentation/soc/intel/fit.md | 60 ++++++++++++++ Documentation/soc/intel/fit.svg | 132 +++++++++++++++++++++++++++++++ Documentation/soc/intel/index.md | 1 + 4 files changed, 193 insertions(+) create mode 100644 Documentation/soc/intel/fit.dia create mode 100644 Documentation/soc/intel/fit.md create mode 100644 Documentation/soc/intel/fit.svg diff --git a/Documentation/soc/intel/fit.dia b/Documentation/soc/intel/fit.dia new file mode 100644 index 0000000000000000000000000000000000000000..7e07978f710c125ab1f166f1d3a76a9d683e2472 GIT binary patch literal 3178 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 QS8reaAF88z640#x0JR4iH~;_u literal 0 HcmV?d00001 diff --git a/Documentation/soc/intel/fit.md b/Documentation/soc/intel/fit.md new file mode 100644 index 00000000000..8b638f04332 --- /dev/null +++ b/Documentation/soc/intel/fit.md @@ -0,0 +1,60 @@ +# Intel Firmware Interface Table + +The FIT allows to run code before the actual IA32 reset vector is executed +by the CPU. The FIT resides in the BIOS region (usually near the reset vector) +and is pointed to by the FIT pointer residing at `0xFFFFFFC0`. + +## Table layout +The table consists of blocks each 16 bytes in size. +The first is called *FIT header* the other are called *FIT entry*. + +![FIT in x86 memory map][fit] + +[fit]: fit.svg + +## Fit types + +Each entry has a *type* that give the other bits in the entry a different +meaning. The following types are known: + +```eval_rst ++-----------+------------------------------------------------------------------+ +| no. | Description | ++===========+==================================================================+ +| 0x0 | HEADER. | ++-----------+------------------------------------------------------------------+ +| 0x1 | MICROCODE. | ++-----------+------------------------------------------------------------------+ +| 0x2 | STARTUP_ACM. | ++-----------+------------------------------------------------------------------+ +| 0x7 | BIOS_STARTUP_MODULE. | ++-----------+------------------------------------------------------------------+ +| 0x8 | TPM_POLICY. | ++-----------+------------------------------------------------------------------+ +| 0x9 | BIOS_POLICY. | ++-----------+------------------------------------------------------------------+ +| 0xa | TXT_POLICY. | ++-----------+------------------------------------------------------------------+ +| 0xb | KEY_MANIFEST. | ++-----------+------------------------------------------------------------------+ +| 0xc | BOOT_POLICY_MANIFEST. | ++-----------+------------------------------------------------------------------+ +| 0x10 | CSE_SECURE_BOOT. | ++-----------+------------------------------------------------------------------+ +| 0x2d | TXTSX_POLICY. | ++-----------+------------------------------------------------------------------+ +| 0x2f | JMP_DEBUG_POLICY. | ++-----------+------------------------------------------------------------------+ +| 0x7f | SKIP. | ++-----------+------------------------------------------------------------------+ +``` + +## Usage in coreboot + +The most common usage of FIT is to use *Type1* to update microcode before +execution of the IA32 reset vector happens. + +## References + +* [Intel TXT LAB handout](https://downloadmirror.intel.com/18931/eng/Intel%20TXT%20LAB%20Handout.pdf) +* [FIT bios specification](https://www.intel.com/content/dam/www/public/us/en/documents/guides/fit-bios-specification.pdf) diff --git a/Documentation/soc/intel/fit.svg b/Documentation/soc/intel/fit.svg new file mode 100644 index 00000000000..eb6c696bb78 --- /dev/null +++ b/Documentation/soc/intel/fit.svg @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + bootblock + + + + + + + + + + + + + + + 4 GiB + + + 4 GiB - 10h + + + 4 GiB - x + + + 4 GiB - 40 h + + + + FIT Ptr + + + IA32 reset vec + + + + + + + + + + + + 4 GiB - z + + + + + + + + + + + 4 GiB - y + + + ACM + + + BOOTBLOCK + CODE + + + uCode + + + + + + + + + + + + + + + + FIT header + + + Type1 entry + + + Type2 entry + + + Type7 entry + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Documentation/soc/intel/index.md b/Documentation/soc/intel/index.md index 4f6b4f21b6b..86f4de71559 100644 --- a/Documentation/soc/intel/index.md +++ b/Documentation/soc/intel/index.md @@ -8,3 +8,4 @@ This section contains documentation about coreboot on specific Intel SOCs. - [FSP](fsp/index.md) - [Ice Lake/9th Gen Core-i series](icelake/index.md) - [MP Initialization](mp_init/mp_init.md) +- [Firmware Interface Table](fit.md) From 2b8789bb3bf186b64ead7a92c341eb70ed57bbcf Mon Sep 17 00:00:00 2001 From: Naveen Manohar Date: Thu, 11 Apr 2019 20:25:42 +0530 Subject: [PATCH 129/588] mb/google/hatch: Modify IRQ configuration to enable RT5682 headset INT Patch corrects IRQ and GPIO configuration for RT5682 codec's Jack INT. Switching IOAPIC to GpioInt because ACPI Interrupt() doesn't support jack triggering on both edges. BUG=b:130180492 TEST=build and boot on a CML EVT board. Use evtest & verify headset jack detection functions as expected. Change-Id: Ia9bf8d554b54554f9ac1e78fd44a508964c8a14d Signed-off-by: Naveen Manohar Suggested-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32474 Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg Reviewed-by: Tim Wawrzynczak Reviewed-by: Shelley Chen Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/variants/baseboard/gpio.c | 4 +--- src/mainboard/google/hatch/variants/hatch/overridetree.cb | 2 +- src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/gpio.c b/src/mainboard/google/hatch/variants/baseboard/gpio.c index c12aa640b63..198d930abaa 100644 --- a/src/mainboard/google/hatch/variants/baseboard/gpio.c +++ b/src/mainboard/google/hatch/variants/baseboard/gpio.c @@ -346,10 +346,8 @@ static const struct pad_config gpio_table[] = { PAD_NC(GPP_G7, DN_20K), /* * H0 : HP_INT_L - * TODO Configure it back to invert mode, when - * ITSS IPCx configuration is fixed in FSP. */ - PAD_CFG_GPI_APIC(GPP_H0, NONE, PLTRST, LEVEL, NONE), + PAD_CFG_GPI_INT(GPP_H0, NONE, PLTRST, LEVEL), /* H1 : CNV_RF_RESET_L */ PAD_CFG_NF(GPP_H1, NONE, DEEP, NF3), /* H2 : CNV_CLKREQ0 */ diff --git a/src/mainboard/google/hatch/variants/hatch/overridetree.cb b/src/mainboard/google/hatch/variants/hatch/overridetree.cb index 13e7766747a..4b1b8d85f23 100644 --- a/src/mainboard/google/hatch/variants/hatch/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch/overridetree.cb @@ -132,7 +132,7 @@ chip soc/intel/cannonlake register "hid" = ""10EC5682"" register "name" = ""RT58"" register "desc" = ""Realtek RT5682"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_H0_IRQ)" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_H0)" register "property_count" = "1" # Set the jd_src to RT5668_JD1 for jack detection register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" diff --git a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb index 15b93f38d49..c5d5964663f 100644 --- a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb @@ -117,7 +117,7 @@ chip soc/intel/cannonlake register "hid" = ""10EC5682"" register "name" = ""RT58"" register "desc" = ""Realtek RT5682"" - register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_H0_IRQ)" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_H0)" register "property_count" = "1" # Set the jd_src to RT5668_JD1 for jack detection register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" From 6672bd8e6b808300a98be0ce308a2bfe5b4685d6 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Wed, 10 Apr 2019 16:06:21 +0800 Subject: [PATCH 130/588] vboot: refactor OPROM code The name OPROM is somewhat inaccurate, since other steps to bring up display and graphics are needed depending on mainboard/SoC. This patch cleans up OPROM code nomenclature, and works towards the goal of deprecating vboot1: * Rename CONFIG_VBOOT_OPROM_MATTERS to CONFIG_VBOOT_MUST_REQUEST_DISPLAY and clarify Kconfig description * Remove function vboot_handoff_skip_display_init * Remove use of the VbInit oflag VB_INIT_OUT_ENABLE_DISPLAY * Add |flags| field to vboot_working_data struct * Create VBOOT_FLAG_DISPLAY_REQUESTED and set in vboot_handoff BUG=b:124141368, b:124192753, chromium:948529 TEST=make clean && make test-abuild TEST=build and flash eve device; attempt loading dev/rec modes BRANCH=none Change-Id: Idf111a533c3953448b4b9084885a9a65a2432a8b Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32262 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/lib/bootmode.c | 10 ++++++---- src/northbridge/intel/haswell/Kconfig | 2 +- src/security/vboot/Kconfig | 8 +++----- src/security/vboot/misc.h | 11 +++++++++-- src/security/vboot/vboot_common.c | 5 ----- src/security/vboot/vboot_common.h | 1 - src/security/vboot/vboot_handoff.c | 23 +++++++++-------------- src/soc/intel/apollolake/Kconfig | 2 +- src/soc/intel/baytrail/Kconfig | 2 +- src/soc/intel/braswell/Kconfig | 2 +- src/soc/intel/broadwell/Kconfig | 2 +- src/soc/intel/cannonlake/Kconfig | 2 +- src/soc/intel/icelake/Kconfig | 2 +- src/soc/intel/skylake/Kconfig | 2 +- src/soc/mediatek/mt8173/Kconfig | 2 +- src/soc/mediatek/mt8183/Kconfig | 2 +- src/soc/nvidia/tegra124/Kconfig | 2 +- src/soc/nvidia/tegra210/Kconfig | 2 +- src/soc/qualcomm/sdm845/Kconfig | 2 +- src/soc/rockchip/rk3288/Kconfig | 2 +- src/soc/rockchip/rk3399/Kconfig | 2 +- 21 files changed, 42 insertions(+), 46 deletions(-) diff --git a/src/lib/bootmode.c b/src/lib/bootmode.c index 052eb8f2823..18f6d5dcac4 100644 --- a/src/lib/bootmode.c +++ b/src/lib/bootmode.c @@ -35,12 +35,14 @@ void gfx_set_init_done(int done) int display_init_required(void) { - /* For vboot always honor vboot_handoff_skip_display_init(). */ + /* For vboot, always honor VBOOT_WD_FLAG_DISPLAY_INIT. */ if (CONFIG(VBOOT)) { - /* Must always select OPROM_MATTERS when using this function. */ - if (!CONFIG(VBOOT_OPROM_MATTERS)) + /* Must always select MUST_REQUEST_DISPLAY when using this + function. */ + if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) dead_code(); - return !vboot_handoff_skip_display_init(); + return vboot_get_working_data()->flags + & VBOOT_WD_FLAG_DISPLAY_INIT; } /* By default always initialize display. */ diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig index 49466bc569f..8c1e0b18f7d 100644 --- a/src/northbridge/intel/haswell/Kconfig +++ b/src/northbridge/intel/haswell/Kconfig @@ -44,7 +44,7 @@ config HASWELL_VBOOT_IN_BOOTBLOCK and back to the RW region after the binary is done. config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_ROMSTAGE if !HASWELL_VBOOT_IN_BOOTBLOCK config VGA_BIOS_ID diff --git a/src/security/vboot/Kconfig b/src/security/vboot/Kconfig index 4815cb10f97..66bcc1ed6f2 100644 --- a/src/security/vboot/Kconfig +++ b/src/security/vboot/Kconfig @@ -169,17 +169,15 @@ config VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT reboots caused after vboot verification is run. e.g. reboots caused by FSP components on Intel platforms. -config VBOOT_OPROM_MATTERS +config VBOOT_MUST_REQUEST_DISPLAY bool default y if VGA_ROM_RUN default n help Set this option to indicate to vboot that this platform will skip its display initialization on a normal (non-recovery, non-developer) boot. - Vboot calls this "oprom matters" because on x86 devices this - traditionally meant that the video option ROM will not be loaded, but - it works functionally the same for other platforms that can skip their - native display initialization code instead. + Unless display is specifically requested, the video option ROM is not + loaded, and any other native display initialization code is not run. config VBOOT_HAS_REC_HASH_SPACE bool diff --git a/src/security/vboot/misc.h b/src/security/vboot/misc.h index 27317ad32d3..b4fae19d74d 100644 --- a/src/security/vboot/misc.h +++ b/src/security/vboot/misc.h @@ -34,11 +34,18 @@ struct selected_region { */ struct vboot_working_data { struct selected_region selected_region; + uint32_t flags; /* offset of the buffer from the start of this struct */ - uint32_t buffer_offset; - uint32_t buffer_size; + uint16_t buffer_offset; + uint16_t buffer_size; }; +/* + * Definitions for vboot_working_data.flags values. + */ +/* vboot requests display initialization from coreboot. */ +#define VBOOT_WD_FLAG_DISPLAY_INIT (1 << 0) + /* * Source: security/vboot/common.c */ diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 5e95c6215c0..3dddc765564 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -88,11 +88,6 @@ static int vboot_get_handoff_flag(uint32_t flag) return !!(vbho->init_params.out_flags & flag); } -int vboot_handoff_skip_display_init(void) -{ - return !vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DISPLAY); -} - int vboot_handoff_check_developer_flag(void) { return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER); diff --git a/src/security/vboot/vboot_common.h b/src/security/vboot/vboot_common.h index 8c92437a3c6..768b29d4fc8 100644 --- a/src/security/vboot/vboot_common.h +++ b/src/security/vboot/vboot_common.h @@ -60,7 +60,6 @@ int vboot_get_handoff_info(void **addr, uint32_t *size); * Returns 0 for flag if false * Returns value read for other fields */ -int vboot_handoff_skip_display_init(void); int vboot_handoff_check_recovery_flag(void); int vboot_handoff_check_developer_flag(void); int vboot_handoff_get_recovery_reason(void); diff --git a/src/security/vboot/vboot_handoff.c b/src/security/vboot/vboot_handoff.c index ff938e15ce8..178877d847f 100644 --- a/src/security/vboot/vboot_handoff.c +++ b/src/security/vboot/vboot_handoff.c @@ -61,30 +61,25 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON; *oflags |= VB_INIT_OUT_ENABLE_RECOVERY; *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; } if (vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) { *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER; *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON; vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON; } - /* TODO: Set these in depthcharge */ - if (CONFIG(VBOOT_OPROM_MATTERS)) { - vb_sd->flags |= VBSD_OPROM_MATTERS; - /* - * Inform vboot if the display was enabled by dev/rec - * mode or was requested by vboot kernel phase. - */ - if ((*oflags & VB_INIT_OUT_ENABLE_DISPLAY) || - vboot_wants_oprom()) { - vb_sd->flags |= VBSD_OPROM_LOADED; - *oflags |= VB_INIT_OUT_ENABLE_DISPLAY; - } + /* Inform vboot if the display was requested by vboot kernel phase + or enabled by dev/rec mode. */ + if (vboot_wants_oprom() || vb2_sd->recovery_reason || + vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) { + vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; + vb_sd->flags |= VBSD_OPROM_LOADED; } + /* TODO: Remove when depthcharge no longer reads this flag. */ + if (CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) + vb_sd->flags |= VBSD_OPROM_MATTERS; /* In vboot1, VBSD_FWB_TRIED is * set only if B is booted as explicitly requested. Therefore, if B is diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 98fdb022e85..217d1eab24f 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -119,7 +119,7 @@ config CHROMEOS config VBOOT select VBOOT_SEPARATE_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_VBNV_CMOS diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index a83a7e9ee6d..03ad31d41fa 100644 --- a/src/soc/intel/baytrail/Kconfig +++ b/src/soc/intel/baytrail/Kconfig @@ -43,7 +43,7 @@ config CPU_SPECIFIC_OPTIONS select CPU_HAS_L2_ENABLE_MSR config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_ROMSTAGE config BOOTBLOCK_CPU_INIT diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig index 8db47955a6b..a0c07084b8c 100644 --- a/src/soc/intel/braswell/Kconfig +++ b/src/soc/intel/braswell/Kconfig @@ -53,7 +53,7 @@ config CPU_SPECIFIC_OPTIONS select SOUTHBRIDGE_INTEL_COMMON_SMBUS config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_ROMSTAGE config BOOTBLOCK_CPU_INIT diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 25984f14e20..83ccf7b9d81 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -66,7 +66,7 @@ config PCIEXP_L1_SUB_STATE default y config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_ROMSTAGE config BOOTBLOCK_CPU_INIT diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index b730b7a26f3..6759b7ff993 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -231,7 +231,7 @@ config CHROMEOS config VBOOT select VBOOT_SEPARATE_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_VBNV_CMOS diff --git a/src/soc/intel/icelake/Kconfig b/src/soc/intel/icelake/Kconfig index 2e9e3e251fd..2fbc6da15f9 100644 --- a/src/soc/intel/icelake/Kconfig +++ b/src/soc/intel/icelake/Kconfig @@ -151,7 +151,7 @@ config CHROMEOS config VBOOT select VBOOT_SEPARATE_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_VBNV_CMOS diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index 5116f3ab251..fcfe2b65910 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -106,7 +106,7 @@ config CHROMEOS config VBOOT select VBOOT_SEPARATE_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_SAVE_RECOVERY_REASON_ON_REBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_VBNV_CMOS diff --git a/src/soc/mediatek/mt8173/Kconfig b/src/soc/mediatek/mt8173/Kconfig index b0d6fa0fade..e966b8e58bd 100644 --- a/src/soc/mediatek/mt8173/Kconfig +++ b/src/soc/mediatek/mt8173/Kconfig @@ -16,7 +16,7 @@ config SOC_MEDIATEK_MT8173 if SOC_MEDIATEK_MT8173 config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE diff --git a/src/soc/mediatek/mt8183/Kconfig b/src/soc/mediatek/mt8183/Kconfig index 6582e4e43c7..f96282cf625 100644 --- a/src/soc/mediatek/mt8183/Kconfig +++ b/src/soc/mediatek/mt8183/Kconfig @@ -14,7 +14,7 @@ config SOC_MEDIATEK_MT8183 if SOC_MEDIATEK_MT8183 config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE diff --git a/src/soc/nvidia/tegra124/Kconfig b/src/soc/nvidia/tegra124/Kconfig index eecb59b0278..475d50e210b 100644 --- a/src/soc/nvidia/tegra124/Kconfig +++ b/src/soc/nvidia/tegra124/Kconfig @@ -18,7 +18,7 @@ config SOC_NVIDIA_TEGRA124 if SOC_NVIDIA_TEGRA124 config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE diff --git a/src/soc/nvidia/tegra210/Kconfig b/src/soc/nvidia/tegra210/Kconfig index 8883baa3585..6750aa9f9a6 100644 --- a/src/soc/nvidia/tegra210/Kconfig +++ b/src/soc/nvidia/tegra210/Kconfig @@ -18,7 +18,7 @@ if SOC_NVIDIA_TEGRA210 config VBOOT select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY config MAINBOARD_DO_DSI_INIT bool "Use dsi graphics interface" diff --git a/src/soc/qualcomm/sdm845/Kconfig b/src/soc/qualcomm/sdm845/Kconfig index c0e3294e39e..ba064889f08 100644 --- a/src/soc/qualcomm/sdm845/Kconfig +++ b/src/soc/qualcomm/sdm845/Kconfig @@ -16,7 +16,7 @@ if SOC_QUALCOMM_SDM845 config VBOOT select VBOOT_SEPARATE_VERSTAGE select VBOOT_RETURN_FROM_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK config SDM845_QSPI diff --git a/src/soc/rockchip/rk3288/Kconfig b/src/soc/rockchip/rk3288/Kconfig index 53666c28f31..38d87524b77 100644 --- a/src/soc/rockchip/rk3288/Kconfig +++ b/src/soc/rockchip/rk3288/Kconfig @@ -34,7 +34,7 @@ config SOC_ROCKCHIP_RK3288 if SOC_ROCKCHIP_RK3288 config VBOOT - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK select VBOOT_SEPARATE_VERSTAGE select VBOOT_RETURN_FROM_VERSTAGE diff --git a/src/soc/rockchip/rk3399/Kconfig b/src/soc/rockchip/rk3399/Kconfig index fb95499efbe..897a5979d4c 100644 --- a/src/soc/rockchip/rk3399/Kconfig +++ b/src/soc/rockchip/rk3399/Kconfig @@ -20,7 +20,7 @@ config VBOOT select VBOOT_MIGRATE_WORKING_DATA select VBOOT_SEPARATE_VERSTAGE select VBOOT_RETURN_FROM_VERSTAGE - select VBOOT_OPROM_MATTERS + select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK config PMIC_BUS From 22e605c2c06f553b98131a87b634709aa1818e1f Mon Sep 17 00:00:00 2001 From: "Marty E. Plummer" Date: Sat, 20 Apr 2019 01:38:51 -0500 Subject: [PATCH 131/588] rockchip: rk3399: increase memory for fit payload. Increase ramstage to 2M, required to actually embed the 7.2mb uImage into the coreboot.rom, increase the postram cbfs cache in order for the fit image to be loadable (without this increase the fit payload is found but not loaded) Change-Id: Iee0ed9f7958588ceda54bb32253c84cac68abea2 Signed-off-by: Marty E. Plummer Reviewed-on: https://review.coreboot.org/c/coreboot/+/32373 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/rockchip/rk3399/include/soc/memlayout.ld | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/rockchip/rk3399/include/soc/memlayout.ld b/src/soc/rockchip/rk3399/include/soc/memlayout.ld index 73fc499d1c6..293057a091b 100644 --- a/src/soc/rockchip/rk3399/include/soc/memlayout.ld +++ b/src/soc/rockchip/rk3399/include/soc/memlayout.ld @@ -20,8 +20,8 @@ SECTIONS { DRAM_START(0x00000000) BL31(0, 0x100000) - POSTRAM_CBFS_CACHE(0x00100000, 1M) - RAMSTAGE(0x00300000, 256K) + POSTRAM_CBFS_CACHE(0x00100000, 8M) + RAMSTAGE(0x00900000, 2M) DMA_COHERENT(0x10000000, 2M) /* 8K of special SRAM in PMU power domain. */ From 13bfd04a99544f5114e823eaa3ce06fece390915 Mon Sep 17 00:00:00 2001 From: Max Blau Date: Mon, 29 Apr 2019 23:46:20 +0200 Subject: [PATCH 132/588] superio/fintek/f71808a: Add more optional ramstage registers Add more registers and make them optional, so they keep untouched/ their default if omitted. Change-Id: I5d8008176d2972976b387c558658b8e70b50af8e Signed-off-by: Max Blau Reviewed-on: https://review.coreboot.org/c/coreboot/+/32376 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Felix Held --- src/superio/fintek/f71808a/chip.h | 7 +++++++ src/superio/fintek/f71808a/f71808a_hwm.c | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/src/superio/fintek/f71808a/chip.h b/src/superio/fintek/f71808a/chip.h index f4e80ff8398..d838f3aec19 100644 --- a/src/superio/fintek/f71808a/chip.h +++ b/src/superio/fintek/f71808a/chip.h @@ -22,6 +22,13 @@ struct superio_fintek_f71808a_config { + uint8_t hwm_vt1_boundary_1_temperature; + uint8_t hwm_vt1_boundary_2_temperature; + uint8_t hwm_vt1_boundary_3_temperature; + uint8_t hwm_vt1_boundary_4_temperature; + uint8_t hwm_fan1_boundary_hysteresis; + uint8_t hwm_domain1_en; + /* Multi function registers */ uint8_t multi_function_register_0; uint8_t multi_function_register_1; diff --git a/src/superio/fintek/f71808a/f71808a_hwm.c b/src/superio/fintek/f71808a/f71808a_hwm.c index a3702194cba..f5e62f942ed 100644 --- a/src/superio/fintek/f71808a/f71808a_hwm.c +++ b/src/superio/fintek/f71808a/f71808a_hwm.c @@ -23,6 +23,7 @@ /* Intel Ibex Peak/PECI/AMD TSI */ #define HWM_PECI_TSI_CTRL_REG 0x0a +#define HWM_DOMAIN1_EN 0x0b #define HWM_TCC_TEMPERATURE_REG 0x0c /* Fan 1 control */ @@ -33,6 +34,12 @@ #define HWM_FAN1_SEG5_SPEED_REG 0xae #define HWM_FAN1_TEMP_SRC_REG 0xaf +#define HWM_FAN1_BOUNDARY_HYSTERESIS 0x98 +#define HWM_VT1_BOUNDARY_1_TEMPERATURE 0xa6 +#define HWM_VT1_BOUNDARY_2_TEMPERATURE 0xa7 +#define HWM_VT1_BOUNDARY_3_TEMPERATURE 0xa8 +#define HWM_VT1_BOUNDARY_4_TEMPERATURE 0xa9 + /* Fan 2 control */ #define HWM_FAN2_SEG1_SPEED_REG 0xba #define HWM_FAN2_SEG2_SPEED_REG 0xbb @@ -55,6 +62,21 @@ void f71808a_hwm_init(struct device *dev) pnp_enter_conf_mode(dev); + if (reg->hwm_vt1_boundary_1_temperature) { + pnp_write_index(port, HWM_VT1_BOUNDARY_4_TEMPERATURE, + reg->hwm_vt1_boundary_4_temperature); + pnp_write_index(port, HWM_VT1_BOUNDARY_3_TEMPERATURE, + reg->hwm_vt1_boundary_3_temperature); + pnp_write_index(port, HWM_VT1_BOUNDARY_2_TEMPERATURE, + reg->hwm_vt1_boundary_2_temperature); + pnp_write_index(port, HWM_VT1_BOUNDARY_1_TEMPERATURE, + reg->hwm_vt1_boundary_1_temperature); + pnp_write_index(port, HWM_FAN1_BOUNDARY_HYSTERESIS, + reg->hwm_fan1_boundary_hysteresis); + pnp_write_index(port, HWM_DOMAIN1_EN, + reg->hwm_domain1_en); + } + pnp_write_index(port, HWM_PECI_TSI_CTRL_REG, reg->hwm_peci_tsi_ctrl); pnp_write_index(port, HWM_TCC_TEMPERATURE_REG, reg->hwm_tcc_temp); From 517eda5ca48014ae53315f3afa731be7f39a20f6 Mon Sep 17 00:00:00 2001 From: Max Blau Date: Mon, 29 Apr 2019 23:48:31 +0200 Subject: [PATCH 133/588] mainboard: Add MSI MS-7707 * MSI MS-7707 V1.1 (Medion OEM Akoya P4385D MSN10014555) * SandyBridge Intel P67 (BD82x6x) * Winbond 25Q32BV (4MB) * Fintek F71808A * Intel 82579V Gigabit * NEC uPD720200 USB 3.0 Host Controller * IME 7.0.4.1197 Working: * PCIe gfx adapter * PS/2 Keyboard * USB3.0 * Ethernet * S0/S3/S5 * HWM Change-Id: I999149bb95d553ed217b2288cc34bce4fe88abb3 Signed-off-by: Max Blau Reviewed-on: https://review.coreboot.org/c/coreboot/+/32235 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/msi/ms7707/Kconfig | 57 +++++++ src/mainboard/msi/ms7707/Kconfig.name | 2 + src/mainboard/msi/ms7707/Makefile.inc | 1 + src/mainboard/msi/ms7707/acpi/ec.asl | 0 src/mainboard/msi/ms7707/acpi/platform.asl | 24 +++ src/mainboard/msi/ms7707/acpi/superio.asl | 0 src/mainboard/msi/ms7707/acpi_tables.c | 32 ++++ src/mainboard/msi/ms7707/board_info.txt | 6 + src/mainboard/msi/ms7707/devicetree.cb | 117 +++++++++++++ src/mainboard/msi/ms7707/dsdt.asl | 41 +++++ src/mainboard/msi/ms7707/gpio.c | 189 +++++++++++++++++++++ src/mainboard/msi/ms7707/hda_verb.c | 73 ++++++++ src/mainboard/msi/ms7707/romstage.c | 70 ++++++++ 13 files changed, 612 insertions(+) create mode 100644 src/mainboard/msi/ms7707/Kconfig create mode 100644 src/mainboard/msi/ms7707/Kconfig.name create mode 100644 src/mainboard/msi/ms7707/Makefile.inc create mode 100644 src/mainboard/msi/ms7707/acpi/ec.asl create mode 100644 src/mainboard/msi/ms7707/acpi/platform.asl create mode 100644 src/mainboard/msi/ms7707/acpi/superio.asl create mode 100644 src/mainboard/msi/ms7707/acpi_tables.c create mode 100644 src/mainboard/msi/ms7707/board_info.txt create mode 100644 src/mainboard/msi/ms7707/devicetree.cb create mode 100644 src/mainboard/msi/ms7707/dsdt.asl create mode 100644 src/mainboard/msi/ms7707/gpio.c create mode 100644 src/mainboard/msi/ms7707/hda_verb.c create mode 100644 src/mainboard/msi/ms7707/romstage.c diff --git a/src/mainboard/msi/ms7707/Kconfig b/src/mainboard/msi/ms7707/Kconfig new file mode 100644 index 00000000000..45ff73e57a3 --- /dev/null +++ b/src/mainboard/msi/ms7707/Kconfig @@ -0,0 +1,57 @@ +if BOARD_MSI_MS7707 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select ARCH_X86 + select NORTHBRIDGE_INTEL_SANDYBRIDGE + select USE_NATIVE_RAMINIT + select SOUTHBRIDGE_INTEL_BD82X6X + select SUPERIO_FINTEK_F71808A + select BOARD_ROMSIZE_KB_4096 + select HAVE_ACPI_TABLES + select HAVE_ACPI_RESUME + select MAINBOARD_USES_IFD_GBE_REGION + select NO_UART_ON_SUPERIO + select SERIRQ_CONTINUOUS_MODE + +config MAINBOARD_DIR + string + default msi/ms7707 + +config MAINBOARD_PART_NUMBER + string + default "MS-7707" + +config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID + hex + default 0x7707 + +config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID + hex + default 0x1462 + +config DRAM_RESET_GATE_GPIO + int + default 60 + +config MAX_CPUS + int + default 8 + +config USBDEBUG_HCD_INDEX # FIXME: check this + int + default 2 + +config CBFS_SIZE + hex + default 0x200000 + +config VGA_BIOS_FILE + string + default "3rdparty/blobs/mainboard/$(MAINBOARDDIR)/vgabios.bin" + +config VGA_BIOS_ID + string + default "8086,0102" + +endif diff --git a/src/mainboard/msi/ms7707/Kconfig.name b/src/mainboard/msi/ms7707/Kconfig.name new file mode 100644 index 00000000000..f6217ef2a66 --- /dev/null +++ b/src/mainboard/msi/ms7707/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_MSI_MS7707 + bool "MS-7707" diff --git a/src/mainboard/msi/ms7707/Makefile.inc b/src/mainboard/msi/ms7707/Makefile.inc new file mode 100644 index 00000000000..3dae61e8a80 --- /dev/null +++ b/src/mainboard/msi/ms7707/Makefile.inc @@ -0,0 +1 @@ +romstage-y += gpio.c diff --git a/src/mainboard/msi/ms7707/acpi/ec.asl b/src/mainboard/msi/ms7707/acpi/ec.asl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/mainboard/msi/ms7707/acpi/platform.asl b/src/mainboard/msi/ms7707/acpi/platform.asl new file mode 100644 index 00000000000..7c3b3c61ff9 --- /dev/null +++ b/src/mainboard/msi/ms7707/acpi/platform.asl @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Tristan Corrick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Method(_WAK,1) +{ + Return(Package(){0,0}) +} + +Method(_PTS,1) +{ +} diff --git a/src/mainboard/msi/ms7707/acpi/superio.asl b/src/mainboard/msi/ms7707/acpi/superio.asl new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/mainboard/msi/ms7707/acpi_tables.c b/src/mainboard/msi/ms7707/acpi_tables.c new file mode 100644 index 00000000000..370b70935fa --- /dev/null +++ b/src/mainboard/msi/ms7707/acpi_tables.c @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +void acpi_create_gnvs(global_nvs_t *gnvs) +{ + /* Disable USB ports in S3 by default */ + gnvs->s3u0 = 0; + gnvs->s3u1 = 0; + + /* Disable USB ports in S5 by default */ + gnvs->s5u0 = 0; + gnvs->s5u1 = 0; + + gnvs->tcrt = 100; + gnvs->tpsv = 90; +} diff --git a/src/mainboard/msi/ms7707/board_info.txt b/src/mainboard/msi/ms7707/board_info.txt new file mode 100644 index 00000000000..eebec48438b --- /dev/null +++ b/src/mainboard/msi/ms7707/board_info.txt @@ -0,0 +1,6 @@ +Category: desktop +ROM package: SOIC-8 +ROM protocol: SPI +ROM socketed: n +Flashrom support: y +Release year: 2011 diff --git a/src/mainboard/msi/ms7707/devicetree.cb b/src/mainboard/msi/ms7707/devicetree.cb new file mode 100644 index 00000000000..4db2536148e --- /dev/null +++ b/src/mainboard/msi/ms7707/devicetree.cb @@ -0,0 +1,117 @@ +chip northbridge/intel/sandybridge + register "gfx.did" = "{ 0x80000100, 0x80000240, 0x80000410 }" + register "gfx.link_frequency_270_mhz" = "0" + register "gfx.ndid" = "3" + device cpu_cluster 0x0 on + chip cpu/intel/model_206ax + register "c1_acpower" = "1" + register "c1_battery" = "1" + register "c2_acpower" = "3" + register "c2_battery" = "3" + register "c3_acpower" = "5" + register "c3_battery" = "5" + device lapic 0x0 on end + device lapic 0xacac off end + end + end + device domain 0x0 on + subsystemid 0x1462 0x7707 inherit + chip southbridge/intel/bd82x6x # Intel Series 6 Cougar Point PCH + register "c2_latency" = "0x0065" + register "docking_supported" = "0" + register "gen1_dec" = "0x000c0291" + register "gen2_dec" = "0x000c0a01" + register "p_cnt_throttling_supported" = "1" + register "pcie_port_coalesce" = "1" + register "sata_interface_speed_support" = "0x3" + register "sata_port_map" = "0x33" + register "spi_lvscc" = "0x2005" + register "spi_uvscc" = "0x2005" + register "gpe0_en" = "0x28000040" + device pci 16.0 on end # Management Engine Interface 1 + device pci 16.1 off end # Management Engine Interface 2 + device pci 16.2 off end # Management Engine IDE-R + device pci 16.3 off end # Management Engine KT + device pci 19.0 on end # Intel Gigabit Ethernet + device pci 1a.0 on end # USB2 EHCI #2 + device pci 1b.0 on end # High Definition Audio Audio controller + device pci 1c.0 on end # PCIe Port #1 + device pci 1c.1 off end # PCIe Port #2 + device pci 1c.2 off end # PCIe Port #3 + device pci 1c.3 off end # PCIe Port #4 + device pci 1c.4 off end # PCIe Port #5 + device pci 1c.5 off end # PCIe Port #6 + device pci 1c.6 on end # PCIe Port #7 + device pci 1c.7 off end # PCIe Port #8 + device pci 1d.0 on end # USB2 EHCI #1 + device pci 1e.0 off end # PCI bridge + device pci 1f.0 on # LPC bridge PCI-LPC bridge + chip superio/fintek/f71808a + register "multi_function_register_0" = "0x00" # 0x28 + register "multi_function_register_1" = "0xc0" # 0x29 + register "multi_function_register_2" = "0x20" # 0x2a + register "multi_function_register_3" = "0x4f" # 0x2b + register "multi_function_register_4" = "0x90" # 0x2c + register "hwm_peci_tsi_ctrl" = "0x02" # 0x0a - PECI enabled, 1.23 V + register "hwm_tcc_temp" = "0x64" # 0x0c - TCC temperature = 100 °C + register "hwm_fan1_seg1_speed" = "0xff" # 0xaa - Fan 1 segment 1 + register "hwm_fan1_seg2_speed" = "0xe2" # 0xab - Fan 1 segment 2 + register "hwm_fan1_seg3_speed" = "0xaf" # 0xac - Fan 1 segment 3 + register "hwm_fan1_seg4_speed" = "0x89" # 0xad - Fan 1 segment 4 + register "hwm_fan1_seg5_speed" = "0x72" # 0xae - Fan 1 segment 5 + register "hwm_fan1_temp_src" = "0x10" # 0xaf - Fan 1 source = PECI + register "hwm_fan2_seg1_speed" = "0xff" # 0xba - Fan 2 segment 1 = 100% + register "hwm_fan2_seg2_speed" = "0xd9" # 0xbb - Fan 2 segment 2 = 86% + register "hwm_fan2_seg3_speed" = "0xb2" # 0xbc - Fan 2 segment 3 = 74% + register "hwm_fan2_seg4_speed" = "0x99" # 0xbd - Fan 2 segment 4 = 62% + register "hwm_fan2_seg5_speed" = "0x80" # 0xbe - Fan 2 segment 5 = 50% + register "hwm_fan2_temp_src" = "0x1e" # 0xbf - Fan 2 source = temperature 2 + + register "hwm_domain1_en" = "0x01" + register "hwm_fan1_boundary_hysteresis" = "0x43" + register "hwm_vt1_boundary_1_temperature" = "0x52" # 82°C + register "hwm_vt1_boundary_2_temperature" = "0x46" # 70°C + register "hwm_vt1_boundary_3_temperature" = "0x41" # 65°C + register "hwm_vt1_boundary_4_temperature" = "0x37" # 55°C + + device pnp 4e.1 off end # Serial Port + device pnp 4e.4 on # Hardware monitor + io 0x60 = 0x295 + irq 0x70 = 0 + # global + irq 0x27 = 0x10 # PWOK follows Intel sequence + irq 0x2d = 0x2e # Anykey+MouseButton wakeup + end + device pnp 4e.5 on # Keyboard + io 0x60 = 0x060 + irq 0x70 = 1 + irq 0x72 = 12 + end + device pnp 4e.6 on # GPIO + irq 0x70 = 0 + irq 0xd0 = 0x20 # GPIO2 Output Enable + irq 0xd1 = 0x20 # GPIO2 Output Data + irq 0xd3 = 0x20 # GPIO2 Drive Enable + end + device pnp 4e.7 off # WDT + io 0x60 = 0xa00 + end + device pnp 4e.8 off end # CIR + device pnp 4e.a on # PME, ACPI, Power Saving Registers + irq 0xe2 = 0x0c # EuP control + irq 0xed = 0xc0 # EuP Watchdog Control + irq 0xf4 = 0x10 # Keep Last State Select + irq 0xf9 = 0x09 # LED VSB Mode Select + end + end + end + device pci 1f.2 on end # SATA Controller 1 + device pci 1f.3 on end # SMBus + device pci 1f.5 off end # SATA Controller 2 + device pci 1f.6 off end # Thermal + end + device pci 00.0 on end # Host bridge + device pci 01.0 on end # PCIe Bridge for discrete graphics + device pci 02.0 off end # Internal graphics + end +end diff --git a/src/mainboard/msi/ms7707/dsdt.asl b/src/mainboard/msi/ms7707/dsdt.asl new file mode 100644 index 00000000000..88085399b9c --- /dev/null +++ b/src/mainboard/msi/ms7707/dsdt.asl @@ -0,0 +1,41 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Tristan Corrick + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x02, // DSDT revision: ACPI 2.0 and up + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20141018 // OEM revision +) +{ + /* Some generic macros */ + #include "acpi/platform.asl" + #include + #include + /* global NVS and variables. */ + #include + #include + + Device (\_SB.PCI0) + { + #include + #include + #include + } +} diff --git a/src/mainboard/msi/ms7707/gpio.c b/src/mainboard/msi/ms7707/gpio.c new file mode 100644 index 00000000000..8fd8e445814 --- /dev/null +++ b/src/mainboard/msi/ms7707/gpio.c @@ -0,0 +1,189 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static const struct pch_gpio_set1 pch_gpio_set1_mode = { + .gpio0 = GPIO_MODE_GPIO, + .gpio1 = GPIO_MODE_GPIO, + .gpio2 = GPIO_MODE_NATIVE, + .gpio3 = GPIO_MODE_NATIVE, + .gpio4 = GPIO_MODE_NATIVE, + .gpio5 = GPIO_MODE_NATIVE, + .gpio6 = GPIO_MODE_GPIO, + .gpio7 = GPIO_MODE_GPIO, + .gpio8 = GPIO_MODE_GPIO, + .gpio9 = GPIO_MODE_NATIVE, + .gpio10 = GPIO_MODE_NATIVE, + .gpio11 = GPIO_MODE_NATIVE, + .gpio12 = GPIO_MODE_NATIVE, + .gpio13 = GPIO_MODE_GPIO, + .gpio14 = GPIO_MODE_NATIVE, + .gpio15 = GPIO_MODE_GPIO, + .gpio16 = GPIO_MODE_GPIO, + .gpio17 = GPIO_MODE_GPIO, + .gpio18 = GPIO_MODE_NATIVE, + .gpio19 = GPIO_MODE_NATIVE, + .gpio20 = GPIO_MODE_GPIO, + .gpio21 = GPIO_MODE_NATIVE, + .gpio22 = GPIO_MODE_NATIVE, + .gpio23 = GPIO_MODE_NATIVE, + .gpio24 = GPIO_MODE_GPIO, + .gpio25 = GPIO_MODE_NATIVE, + .gpio26 = GPIO_MODE_NATIVE, + .gpio27 = GPIO_MODE_GPIO, + .gpio28 = GPIO_MODE_GPIO, + .gpio29 = GPIO_MODE_GPIO, + .gpio30 = GPIO_MODE_NATIVE, + .gpio31 = GPIO_MODE_GPIO, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_direction = { + .gpio0 = GPIO_DIR_INPUT, + .gpio1 = GPIO_DIR_INPUT, + .gpio6 = GPIO_DIR_INPUT, + .gpio7 = GPIO_DIR_INPUT, + .gpio8 = GPIO_DIR_OUTPUT, + .gpio13 = GPIO_DIR_INPUT, + .gpio15 = GPIO_DIR_OUTPUT, + .gpio16 = GPIO_DIR_INPUT, + .gpio17 = GPIO_DIR_INPUT, + .gpio20 = GPIO_DIR_OUTPUT, + .gpio24 = GPIO_DIR_OUTPUT, + .gpio27 = GPIO_DIR_INPUT, + .gpio28 = GPIO_DIR_OUTPUT, + .gpio29 = GPIO_DIR_OUTPUT, + .gpio31 = GPIO_DIR_INPUT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_level = { + .gpio8 = GPIO_LEVEL_HIGH, + .gpio15 = GPIO_LEVEL_LOW, + .gpio20 = GPIO_LEVEL_HIGH, + .gpio24 = GPIO_LEVEL_LOW, + .gpio28 = GPIO_LEVEL_HIGH, + .gpio29 = GPIO_LEVEL_HIGH, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_reset = {}; + +static const struct pch_gpio_set1 pch_gpio_set1_invert = { + .gpio13 = GPIO_INVERT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_blink = {}; + +static const struct pch_gpio_set2 pch_gpio_set2_mode = { + .gpio32 = GPIO_MODE_GPIO, + .gpio33 = GPIO_MODE_GPIO, + .gpio34 = GPIO_MODE_GPIO, + .gpio35 = GPIO_MODE_NATIVE, + .gpio36 = GPIO_MODE_NATIVE, + .gpio37 = GPIO_MODE_NATIVE, + .gpio38 = GPIO_MODE_NATIVE, + .gpio39 = GPIO_MODE_NATIVE, + .gpio40 = GPIO_MODE_NATIVE, + .gpio41 = GPIO_MODE_NATIVE, + .gpio42 = GPIO_MODE_NATIVE, + .gpio43 = GPIO_MODE_NATIVE, + .gpio44 = GPIO_MODE_NATIVE, + .gpio45 = GPIO_MODE_GPIO, + .gpio46 = GPIO_MODE_NATIVE, + .gpio47 = GPIO_MODE_NATIVE, + .gpio48 = GPIO_MODE_NATIVE, + .gpio49 = GPIO_MODE_GPIO, + .gpio50 = GPIO_MODE_NATIVE, + .gpio51 = GPIO_MODE_NATIVE, + .gpio52 = GPIO_MODE_NATIVE, + .gpio53 = GPIO_MODE_NATIVE, + .gpio54 = GPIO_MODE_NATIVE, + .gpio55 = GPIO_MODE_NATIVE, + .gpio56 = GPIO_MODE_NATIVE, + .gpio57 = GPIO_MODE_GPIO, + .gpio58 = GPIO_MODE_NATIVE, + .gpio59 = GPIO_MODE_NATIVE, + .gpio60 = GPIO_MODE_NATIVE, + .gpio61 = GPIO_MODE_NATIVE, + .gpio62 = GPIO_MODE_NATIVE, + .gpio63 = GPIO_MODE_NATIVE, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_direction = { + .gpio32 = GPIO_DIR_OUTPUT, + .gpio33 = GPIO_DIR_OUTPUT, + .gpio34 = GPIO_DIR_INPUT, + .gpio45 = GPIO_DIR_OUTPUT, + .gpio49 = GPIO_DIR_INPUT, + .gpio57 = GPIO_DIR_OUTPUT, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_level = { + .gpio32 = GPIO_LEVEL_HIGH, + .gpio33 = GPIO_LEVEL_HIGH, + .gpio45 = GPIO_LEVEL_HIGH, + .gpio57 = GPIO_LEVEL_HIGH, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_reset = {}; + +static const struct pch_gpio_set3 pch_gpio_set3_mode = { + .gpio64 = GPIO_MODE_NATIVE, + .gpio65 = GPIO_MODE_NATIVE, + .gpio66 = GPIO_MODE_NATIVE, + .gpio67 = GPIO_MODE_NATIVE, + .gpio68 = GPIO_MODE_GPIO, + .gpio69 = GPIO_MODE_GPIO, + .gpio70 = GPIO_MODE_NATIVE, + .gpio71 = GPIO_MODE_NATIVE, + .gpio72 = GPIO_MODE_GPIO, + .gpio73 = GPIO_MODE_NATIVE, + .gpio74 = GPIO_MODE_NATIVE, + .gpio75 = GPIO_MODE_NATIVE, +}; + +static const struct pch_gpio_set3 pch_gpio_set3_direction = { + .gpio68 = GPIO_DIR_INPUT, + .gpio69 = GPIO_DIR_INPUT, + .gpio72 = GPIO_DIR_INPUT, +}; + +static const struct pch_gpio_set3 pch_gpio_set3_level = {}; + +static const struct pch_gpio_set3 pch_gpio_set3_reset = {}; + +const struct pch_gpio_map mainboard_gpio_map = { + .set1 = { + .mode = &pch_gpio_set1_mode, + .direction = &pch_gpio_set1_direction, + .level = &pch_gpio_set1_level, + .blink = &pch_gpio_set1_blink, + .invert = &pch_gpio_set1_invert, + .reset = &pch_gpio_set1_reset, + }, + .set2 = { + .mode = &pch_gpio_set2_mode, + .direction = &pch_gpio_set2_direction, + .level = &pch_gpio_set2_level, + .reset = &pch_gpio_set2_reset, + }, + .set3 = { + .mode = &pch_gpio_set3_mode, + .direction = &pch_gpio_set3_direction, + .level = &pch_gpio_set3_level, + .reset = &pch_gpio_set3_reset, + }, +}; diff --git a/src/mainboard/msi/ms7707/hda_verb.c b/src/mainboard/msi/ms7707/hda_verb.c new file mode 100644 index 00000000000..6a6cf41553f --- /dev/null +++ b/src/mainboard/msi/ms7707/hda_verb.c @@ -0,0 +1,73 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +const u32 cim_verb_data[] = { + 0x10ec0887, /* Codec Vendor / Device ID: Realtek */ + 0x14627707, /* Subsystem ID */ + + 0x0000000f, /* Number of 4 dword sets */ + /* NID 0x01: Subsystem ID. */ + AZALIA_SUBVENDOR(0x0, 0x14627707), + + /* NID 0x11. */ + AZALIA_PIN_CFG(0x0, 0x11, 0x411111f0), + + /* NID 0x12. */ + AZALIA_PIN_CFG(0x0, 0x12, 0x411111f0), + + /* NID 0x14. */ + AZALIA_PIN_CFG(0x0, 0x14, 0x01014410), + + /* NID 0x15. */ + AZALIA_PIN_CFG(0x0, 0x15, 0x01011412), + + /* NID 0x16. */ + AZALIA_PIN_CFG(0x0, 0x16, 0x01016411), + + /* NID 0x17. */ + AZALIA_PIN_CFG(0x0, 0x17, 0x01012414), + + /* NID 0x18. */ + AZALIA_PIN_CFG(0x0, 0x18, 0x01813c40), + + /* NID 0x19. */ + AZALIA_PIN_CFG(0x0, 0x19, 0x02a19c50), + + /* NID 0x1a. */ + AZALIA_PIN_CFG(0x0, 0x1a, 0x411111f0), + + /* NID 0x1b. */ + AZALIA_PIN_CFG(0x0, 0x1b, 0x02214c20), + + /* NID 0x1c. */ + AZALIA_PIN_CFG(0x0, 0x1c, 0x411111f0), + + /* NID 0x1d. */ + AZALIA_PIN_CFG(0x0, 0x1d, 0x411111f0), + + /* NID 0x1e. */ + AZALIA_PIN_CFG(0x0, 0x1e, 0x01454130), + + /* NID 0x1f. */ + AZALIA_PIN_CFG(0x0, 0x1f, 0x411111f0), +}; + +const u32 pc_beep_verbs[0] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/msi/ms7707/romstage.c b/src/mainboard/msi/ms7707/romstage.c new file mode 100644 index 00000000000..30bb545328a --- /dev/null +++ b/src/mainboard/msi/ms7707/romstage.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +void pch_enable_lpc(void) +{ + /* IO Decode Ranges Register */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0000); + /* LPC IF Enables Register (CNF2_LPC_EN|KBC_LPC_EN) */ + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x2400); + + u16 reg16; + reg16 = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xa4); + reg16 |= (1 << 13); // WOL Enable Override (WOL_EN_OVRD) + pci_write_config16(PCI_DEV(0, 0x1f, 0), 0xa4, reg16); +} + +void mainboard_rcba_config(void) +{ +} + +const struct southbridge_usb_port mainboard_usb_ports[] = { + {1, 0, 0}, + {1, 0, 0}, + {1, 0, 1}, + {1, 0, 1}, + {1, 0, 2}, + {1, 0, 2}, + {1, 0, 3}, + {1, 0, 3}, + {1, 0, 4}, + {1, 0, 4}, + {1, 0, 6}, + {1, 0, 5}, + {1, 0, 5}, + {1, 0, 6}, +}; + +void mainboard_early_init(int s3resume) +{ +} + +void mainboard_config_superio(void) +{ +} + +void mainboard_get_spd(spd_raw_data *spd, bool id_only) +{ + read_spd(&spd[0], 0x50, id_only); + read_spd(&spd[2], 0x52, id_only); +} From 4c8726574cb36fe0e836bc32fbd453f8770a2ff0 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Mon, 29 Apr 2019 14:09:17 -0700 Subject: [PATCH 134/588] soc/intel/common: Set RX_DISABLE for pads configured as NC For GPIO pads that are configured as no-connect (PAD_NC), setting it as GPI (with Rx enabled) leads to GPE0_STS being set incorrectly. Though this is not an issue in practice (GPE0_EN is not set, so no events triggered), it can confuse users when debugging GPE related issues. This change configures PAD_NC to have Rx disabled along with Tx to ensure that it does not end up setting GPE0_STS bits for unwanted GPIO pads. P.S.: IOSSTATE config does not have a TxDRxD setting, so leaving that configuration as is. BUG=b:129235068 TEST=Verified that GPE0_STS bits are not set for pads that are marked as PAD_NC. Change-Id: I726cc7b86a94e7449352cd8a8806d4d775c593dc Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32514 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Subrata Banik Reviewed-by: Ronak Kanabar --- .../common/block/include/intelblocks/gpio_defs.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h index 0ad3e5c32a8..91d8f00a89e 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h @@ -264,10 +264,16 @@ PAD_CFG0_TRIG_##trig | PAD_CFG0_RX_POL_NONE, \ PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TxDRxE)) -/* No Connect configuration for unused pad. - * NC should be GPI with Term as PU20K, PD20K, NONE depending upon default Term +/* + * No Connect configuration for unused pad. + * Both TX and RX are disabled. RX disabling is done to avoid unnecessary + * setting of GPI_STS. */ -#define PAD_NC(pad, pull) PAD_CFG_GPI(pad, pull, DEEP) +#define PAD_NC(pad, pull) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(DEEP) | \ + PAD_CFG0_TX_DISABLE | PAD_CFG0_RX_DISABLE, \ + PAD_PULL(pull) | PAD_IOSSTATE(TxDRxE)) #if CONFIG(SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS) From 37b26261cc56bbb4ea423e1834071847c372dacf Mon Sep 17 00:00:00 2001 From: John Zhao Date: Mon, 29 Apr 2019 14:48:51 -0700 Subject: [PATCH 135/588] arch/x86/acpi: Update VT-d DMA remapping structure flags setting DMA remapping structure flags settings are Bit 0: INTR_REMAP, Bit 1: X2APIC_OPT_OUT, Bit 2: DMA_CTRL_PLATFORM_OPT_IN_FLAG, Bits 3-7: Reserved (0). BUG=b:130351429 TEST=Image built and kernel booted to kernel. Signed-off-by: John Zhao Change-Id: Iaf4764a9062756cadc335d1932b0da8628797f5f Reviewed-on: https://review.coreboot.org/c/coreboot/+/32516 Reviewed-by: Lijian Zhao Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/arch/x86/include/arch/acpi.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 1b9438d13c8..79feaad0702 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -335,9 +335,9 @@ enum { }; enum dmar_flags { - DMAR_INTR_REMAP = 1, - DMAR_X2APIC_OPT_OUT = 2, - DMA_CTRL_PLATFORM_OPT_IN_FLAG = 3, + DMAR_INTR_REMAP = 1 << 0, + DMAR_X2APIC_OPT_OUT = 1 << 1, + DMA_CTRL_PLATFORM_OPT_IN_FLAG = 1 << 2, }; typedef struct dmar_entry { From 7144702f8340ff09d85c0a780b71f94dfac5d7ea Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 30 Apr 2019 11:10:03 -0500 Subject: [PATCH 136/588] google/cyan,intel/strago: increase default CBFS size a 1M CBFS size is inadequate when adding the FSP binary to image due to default FSP location in CBFS, so bump to 2M to ensure autobuilds succeed. Change-Id: I0683bea43cc71fad32bc42bfbd72f3913256d53c Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32525 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth Reviewed-by: Nico Huber --- src/mainboard/google/cyan/Kconfig | 4 ++++ src/mainboard/intel/strago/Kconfig | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index 1d9b7b791b3..b3c6790e57f 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -107,4 +107,8 @@ config GBB_HWID default "ULTIMA TEST A-A 6017" if BOARD_GOOGLE_ULTIMA default "WIZPIG TEST A-A 0597" if BOARD_GOOGLE_WIZPIG +config CBFS_SIZE + hex + default 0x200000 + endif # BOARD_GOOGLE_BASEBOARD_CYAN diff --git a/src/mainboard/intel/strago/Kconfig b/src/mainboard/intel/strago/Kconfig index 4aa7640974a..da04d78a054 100644 --- a/src/mainboard/intel/strago/Kconfig +++ b/src/mainboard/intel/strago/Kconfig @@ -58,4 +58,9 @@ config GBB_HWID string depends on CHROMEOS default "STRAGO TEST A-A 9657" + +config CBFS_SIZE + hex + default 0x200000 + endif # BOARD_INTEL_STRAGO From 43a3c513f85b5af8958da253aa5ca377a4470ab3 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Mon, 29 Apr 2019 16:25:01 +0800 Subject: [PATCH 137/588] mb/google/sarien: Disable S5 wake on LAN by default Chromebook doesn't require support wake on LAN in S5. Disable it by default for power saving. BUG=b:131571666 TEST= check LAN indicator is off under S5 Signed-off-by: Eric Lai Change-Id: Ia90c9d2f3ea9b3580e9a7bbfb47c917dd51e3c03 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32502 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Simon Glass Reviewed-by: Simon Glass --- src/mainboard/google/sarien/variants/sarien/devicetree.cb | 3 +++ src/soc/intel/cannonlake/chip.h | 4 ++++ src/soc/intel/cannonlake/fsp_params.c | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 7dd9f154efd..e9786f14ebf 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -53,6 +53,9 @@ chip soc/intel/cannonlake # Enable DDC for DDI port B register "DdiPortBDdc" = "1" + register "LanWakeFromDeepSx" = "0" + register "WolEnableOverride" = "0" + # VR Settings Configuration for 4 Domains #+----------------+-------+-------+-------+-------+ #| Domain/Setting | SA | IA | GTUS | GTS | diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 9bba226e58e..40d9f71eedb 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -400,6 +400,10 @@ struct soc_intel_cannonlake_config { /* Unlock all GPIO Pads */ uint8_t PchUnlockGpioPads; + + /* Enable GBE wakeup */ + uint8_t LanWakeFromDeepSx; + uint8_t WolEnableOverride; }; typedef struct soc_intel_cannonlake_config config_t; diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index 61d25206939..cc01d10fe81 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -212,6 +212,10 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) params->DdiPortDDdc = config->DdiPortDDdc; params->DdiPortFDdc = config->DdiPortFDdc; + /* WOL */ + params->PchPmPcieWakeFromDeepSx = config->LanWakeFromDeepSx; + params->PchPmWolEnableOverride = config->WolEnableOverride; + /* S0ix */ params->PchPmSlpS0Enable = config->s0ix_enable; From d32a4930910dbe5dea47777902fcb966a4854114 Mon Sep 17 00:00:00 2001 From: Martin Kepplinger Date: Mon, 29 Apr 2019 06:51:33 +0200 Subject: [PATCH 138/588] x86emu: add console.h header to fix compilation Commit 351e3e5 ("src: Use include when appropriate") has broken the build here, see below, so we include console.h here again. In file included from src/device/oprom/x86emu/x86emui.h:65, from src/device/oprom/x86emu/debug.c:40: src/device/oprom/x86emu/debug.c: In function 'x86emu_dump_regs': src/device/oprom/x86emu/debug.h:46:22: error: implicit declaration of function 'printk'; did you mean 'printf'? [-Werror=implicit-function-declaration] #define printf(x...) printk(BIOS_DEBUG, x) ^~~~~~ src/device/oprom/x86emu/debug.c:366:5: note: in expansion of macro 'printf' printf("\tAX=%04x ", M.x86.R_AX ); ^~~~~~ Fixes: 351e3e5 ("src: Use include when appropriate") Change-Id: I75d0b7c08bfa6dcb07778bbb762223b62cfc3da7 Signed-off-by: Martin Kepplinger Reviewed-on: https://review.coreboot.org/c/coreboot/+/32499 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Werner Zeh --- src/device/oprom/x86emu/debug.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/device/oprom/x86emu/debug.h b/src/device/oprom/x86emu/debug.h index f89d5abc4aa..01f633cb5c1 100644 --- a/src/device/oprom/x86emu/debug.h +++ b/src/device/oprom/x86emu/debug.h @@ -39,6 +39,8 @@ #ifndef __X86EMU_DEBUG_H #define __X86EMU_DEBUG_H +#include + /*---------------------- Macros and type definitions ----------------------*/ /* printf is not available in coreboot... use printk */ From ff9104eae3512e554b4790b40b0bdd3fca2036b3 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 12:37:27 +0530 Subject: [PATCH 139/588] soc/intel/icelake: Clear PMCON status bits This patch ports CB:31902 changes from CNL to ICL. The prev_sleep_state value was showing 5 even after warm reboot, once the SUS_PWR_FLR bit is being set. This bit was not being cleared. Hence clearing the PMCON status bits. Change-Id: Ia07aa17b4491216a277c36edfe6ed2aa489287c6 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32503 Reviewed-by: Rizwan Qureshi Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/icelake/finalize.c | 2 ++ src/soc/intel/icelake/include/soc/pm.h | 3 +++ src/soc/intel/icelake/pmutil.c | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/src/soc/intel/icelake/finalize.c b/src/soc/intel/icelake/finalize.c index c1e6dd0d4af..e061cda2f09 100644 --- a/src/soc/intel/icelake/finalize.c +++ b/src/soc/intel/icelake/finalize.c @@ -87,6 +87,8 @@ static void pch_finalize(void) } pch_handle_sideband(config); + + pmc_clear_pmcon_sts(); } static void soc_finalize(void *unused) diff --git a/src/soc/intel/icelake/include/soc/pm.h b/src/soc/intel/icelake/include/soc/pm.h index 9caf49fa9af..44888ec7472 100644 --- a/src/soc/intel/icelake/include/soc/pm.h +++ b/src/soc/intel/icelake/include/soc/pm.h @@ -168,5 +168,8 @@ uint16_t smbus_tco_regs(void); /* Set the DISB after DRAM init */ void pmc_set_disb(void); +/* Clear PMCON status bits */ +void pmc_clear_pmcon_sts(void); + #endif /* !defined(__ACPI__) */ #endif diff --git a/src/soc/intel/icelake/pmutil.c b/src/soc/intel/icelake/pmutil.c index 96ff52d1229..e1b16653687 100644 --- a/src/soc/intel/icelake/pmutil.c +++ b/src/soc/intel/icelake/pmutil.c @@ -141,6 +141,20 @@ void pmc_set_disb(void) write8(addr, disb_val); } +void pmc_clear_pmcon_sts(void) +{ + uint32_t reg_val; + uint8_t *addr; + addr = pmc_mmio_regs(); + + reg_val = read32(addr + GEN_PMCON_A); + /* Clear SUS_PWR_FLR, GBL_RST_STS, HOST_RST_STS, PWR_FLR bits + * while retaining MS4V write-1-to-clear bit */ + reg_val &= ~(MS4V); + + write32((addr + GEN_PMCON_A), reg_val); +} + /* * PMC controller gets hidden from PCI bus * during FSP-Silicon init call. Hence PWRMBASE From 5489341e6380cb8c7d1249a495486ae9cfcd4fa2 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 13:28:11 +0530 Subject: [PATCH 140/588] soc/intel/icelake: Add chipset event logging This patch ports CB:30718 and CB:31908 changes from CNL to ICL. Add logging of chipset events on boot into the flash event log. This was tested on a google/dragonegg board to ensure that events like "System Reset" are added to the log as expected. Also fix GEN_PMCON bit checks as below: ICL PCH has PWR_FLR, SUS_PWR_FLR and HOST_RST_STS bits in GEN_PMCON_A and so this change updates the check for these bits to use GEN_PMCON_A instead of GEN_PMCON_B. Change-Id: I25ec32e81f8801f8d5e69c6095ffed73d75dded6 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32504 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Rizwan Qureshi --- src/soc/intel/icelake/Makefile.inc | 1 + src/soc/intel/icelake/elog.c | 132 ++++++++++++++++++++++++ src/soc/intel/icelake/include/soc/pch.h | 2 - 3 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 src/soc/intel/icelake/elog.c diff --git a/src/soc/intel/icelake/Makefile.inc b/src/soc/intel/icelake/Makefile.inc index 74c9182067e..cd6a6ba8422 100644 --- a/src/soc/intel/icelake/Makefile.inc +++ b/src/soc/intel/icelake/Makefile.inc @@ -35,6 +35,7 @@ romstage-y += uart.c ramstage-y += acpi.c ramstage-y += chip.c ramstage-y += cpu.c +ramstage-y += elog.c ramstage-y += finalize.c ramstage-y += fsp_params.c ramstage-y += gpio.c diff --git a/src/soc/intel/icelake/elog.c b/src/soc/intel/icelake/elog.c new file mode 100644 index 00000000000..2ec6b410dfa --- /dev/null +++ b/src/soc/intel/icelake/elog.c @@ -0,0 +1,132 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Intel Corporation. + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static void pch_log_gpio_gpe(u32 gpe0_sts, u32 gpe0_en, int start) +{ + int i; + + gpe0_sts &= gpe0_en; + + for (i = 0; i <= 31; i++) { + if (gpe0_sts & (1 << i)) + elog_add_event_wake(ELOG_WAKE_SOURCE_GPIO, i + start); + } +} + +static void pch_log_wake_source(struct chipset_power_state *ps) +{ + /* Power Button */ + if (ps->pm1_sts & PWRBTN_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PWRBTN, 0); + + /* RTC */ + if (ps->pm1_sts & RTC_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_RTC, 0); + + /* PCI Express (TODO: determine wake device) */ + if (ps->pm1_sts & PCIEXPWAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PCIE, 0); + + /* PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME, 0); + + /* Internal PME (TODO: determine wake device) */ + if (ps->gpe0_sts[GPE_STD] & PME_B0_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_PME_INTERNAL, 0); + + /* SMBUS Wake */ + if (ps->gpe0_sts[GPE_STD] & SMB_WAK_STS) + elog_add_event_wake(ELOG_WAKE_SOURCE_SMBUS, 0); + + /* Log GPIO events in set 1-3 */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_31_0], ps->gpe0_en[GPE_31_0], 0); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_63_32], ps->gpe0_en[GPE_63_32], 32); + pch_log_gpio_gpe(ps->gpe0_sts[GPE_95_64], ps->gpe0_en[GPE_95_64], 64); + /* Treat the STD as an extension of GPIO to obtain visibility. */ + pch_log_gpio_gpe(ps->gpe0_sts[GPE_STD], ps->gpe0_en[GPE_STD], 96); +} + +static void pch_log_power_and_resets(struct chipset_power_state *ps) +{ + /* Thermal Trip */ + if (ps->gblrst_cause[0] & GBLRST_CAUSE0_THERMTRIP) + elog_add_event(ELOG_TYPE_THERM_TRIP); + + /* PWR_FLR Power Failure */ + if (ps->gen_pmcon_a & PWR_FLR) + elog_add_event(ELOG_TYPE_POWER_FAIL); + + /* SUS Well Power Failure */ + if (ps->gen_pmcon_a & SUS_PWR_FLR) + elog_add_event(ELOG_TYPE_SUS_POWER_FAIL); + + /* TCO Timeout */ + if (ps->prev_sleep_state != ACPI_S3 && + ps->tco2_sts & TCO_STS_SECOND_TO) + elog_add_event(ELOG_TYPE_TCO_RESET); + + /* Power Button Override */ + if (ps->pm1_sts & PRBTNOR_STS) + elog_add_event(ELOG_TYPE_POWER_BUTTON_OVERRIDE); + + /* RTC reset */ + if (ps->gen_pmcon_b & RTC_BATTERY_DEAD) + elog_add_event(ELOG_TYPE_RTC_RESET); + + /* Host Reset Status */ + if (ps->gen_pmcon_a & HOST_RST_STS) + elog_add_event(ELOG_TYPE_SYSTEM_RESET); + + /* ACPI Wake Event */ + if (ps->prev_sleep_state != ACPI_S0) + elog_add_event_byte(ELOG_TYPE_ACPI_WAKE, ps->prev_sleep_state); +} + +static void pch_log_state(void *unused) +{ + struct chipset_power_state *ps = pmc_get_power_state(); + + if (!ps) { + printk(BIOS_ERR, "chipset_power_state not found!\n"); + return; + } + + /* Power and Reset */ + pch_log_power_and_resets(ps); + + /* Wake Sources */ + if (ps->prev_sleep_state > ACPI_S0) + pch_log_wake_source(ps); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, pch_log_state, NULL); + +void elog_gsmi_cb_platform_log_wake_source(void) +{ + struct chipset_power_state ps; + pmc_fill_pm_reg_info(&ps); + pch_log_wake_source(&ps); +} diff --git a/src/soc/intel/icelake/include/soc/pch.h b/src/soc/intel/icelake/include/soc/pch.h index d5478d26e9d..e1560c1657d 100644 --- a/src/soc/intel/icelake/include/soc/pch.h +++ b/src/soc/intel/icelake/include/soc/pch.h @@ -26,6 +26,4 @@ #define PCIE_CLK_LAN 0x70 #define PCIE_CLK_FREE 0x80 -void pch_log_state(void); - #endif From 83fe4c4e4796b10f2a21d11c2b6a3543851271f7 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 13:29:14 +0530 Subject: [PATCH 141/588] soc/intel/{broadwell, skylake}: Remove unused pch_log_state() declaration This patch removes unused pch_log_state() function declaration from pch.h because elog.c has static implementation of pch_log_state(). Change-Id: Ib0f3831dc3b60af2ee432a76866e401a51b96fb7 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32505 Reviewed-by: Rizwan Qureshi Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/broadwell/include/soc/pch.h | 1 - src/soc/intel/skylake/include/soc/pch.h | 1 - 2 files changed, 2 deletions(-) diff --git a/src/soc/intel/broadwell/include/soc/pch.h b/src/soc/intel/broadwell/include/soc/pch.h index 19ba2e0b643..ef8a87a4dba 100644 --- a/src/soc/intel/broadwell/include/soc/pch.h +++ b/src/soc/intel/broadwell/include/soc/pch.h @@ -42,7 +42,6 @@ u16 pch_type(void); int pch_is_wpt(void); int pch_is_wpt_ulx(void); u32 pch_read_soft_strap(int id); -void pch_log_state(void); void pch_disable_devfn(struct device *dev); #endif diff --git a/src/soc/intel/skylake/include/soc/pch.h b/src/soc/intel/skylake/include/soc/pch.h index d95bcaf2598..e2bf5a119c6 100644 --- a/src/soc/intel/skylake/include/soc/pch.h +++ b/src/soc/intel/skylake/include/soc/pch.h @@ -20,7 +20,6 @@ #include -void pch_log_state(void); #if ENV_RAMSTAGE void pch_disable_devfn(struct device *dev); #endif From 67524b57af238490de9d00ba0caf08dfb73a2b10 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 13:38:59 +0530 Subject: [PATCH 142/588] soc/intel/icelake: Move power_state functions to pmutil.c This patch ports CB:31787 and CB:31908 changes from CNL to ICL. This change moves soc_fill_power_state and soc_prev_sleep_state to pmutil.c. It allows the functions to be used across romstage and smm. Also fix GEN_PMCON bit checks as below: ICL PCH has PWR_FLR, SUS_PWR_FLR and HOST_RST_STS bits in GEN_PMCON_A and so this change updates the check for these bits to use GEN_PMCON_A instead of GEN_PMCON_B. Change-Id: Ib7ab95b7bbcc97a076d27a11db2105f7b976b521 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32506 Reviewed-by: Rizwan Qureshi Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/icelake/pmutil.c | 64 +++++++++++++++ src/soc/intel/icelake/romstage/Makefile.inc | 1 - src/soc/intel/icelake/romstage/power_state.c | 86 -------------------- 3 files changed, 64 insertions(+), 87 deletions(-) delete mode 100644 src/soc/intel/icelake/romstage/power_state.c diff --git a/src/soc/intel/icelake/pmutil.c b/src/soc/intel/icelake/pmutil.c index e1b16653687..1c477835558 100644 --- a/src/soc/intel/icelake/pmutil.c +++ b/src/soc/intel/icelake/pmutil.c @@ -210,3 +210,67 @@ int vbnv_cmos_failed(void) { return rtc_failed(read32(pmc_mmio_regs() + GEN_PMCON_B)); } + +static inline int deep_s3_enabled(void) +{ + uint32_t deep_s3_pol; + + deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); + return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); +} + +/* Return 0, 3, or 5 to indicate the previous sleep state. */ +int soc_prev_sleep_state(const struct chipset_power_state *ps, + int prev_sleep_state) +{ + + /* + * Check for any power failure to determine if this a wake from + * S5 because the PCH does not set the WAK_STS bit when waking + * from a true G3 state. + */ + if (ps->gen_pmcon_a & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = ACPI_S5; + + /* + * If waking from S3 determine if deep S3 is enabled. If not, + * need to check both deep sleep well and normal suspend well. + * Otherwise just check deep sleep well. + */ + if (prev_sleep_state == ACPI_S3) { + /* PWR_FLR represents deep sleep power well loss. */ + uint32_t mask = PWR_FLR; + + /* If deep s3 isn't enabled check the suspend well too. */ + if (!deep_s3_enabled()) + mask |= SUS_PWR_FLR; + + if (ps->gen_pmcon_a & mask) + prev_sleep_state = ACPI_S5; + } + + return prev_sleep_state; +} + +void soc_fill_power_state(struct chipset_power_state *ps) +{ + uint8_t *pmc; + + ps->tco1_sts = tco_read_reg(TCO1_STS); + ps->tco2_sts = tco_read_reg(TCO2_STS); + + printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", + ps->tco1_sts, ps->tco2_sts); + + pmc = pmc_mmio_regs(); + ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); + ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); + ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); + ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); + + printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", + ps->gen_pmcon_a, ps->gen_pmcon_b); + + printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", + ps->gblrst_cause[0], ps->gblrst_cause[1]); +} diff --git a/src/soc/intel/icelake/romstage/Makefile.inc b/src/soc/intel/icelake/romstage/Makefile.inc index 9fc199deeec..28e7eada551 100644 --- a/src/soc/intel/icelake/romstage/Makefile.inc +++ b/src/soc/intel/icelake/romstage/Makefile.inc @@ -14,6 +14,5 @@ # romstage-y += fsp_params.c -romstage-y += power_state.c romstage-y += romstage.c romstage-y += systemagent.c diff --git a/src/soc/intel/icelake/romstage/power_state.c b/src/soc/intel/icelake/romstage/power_state.c deleted file mode 100644 index 40775509e4f..00000000000 --- a/src/soc/intel/icelake/romstage/power_state.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2018 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include - -static inline int deep_s3_enabled(void) -{ - uint32_t deep_s3_pol; - - deep_s3_pol = read32(pmc_mmio_regs() + S3_PWRGATE_POL); - return !!(deep_s3_pol & (S3DC_GATE_SUS | S3AC_GATE_SUS)); -} - -/* Return 0, 3, or 5 to indicate the previous sleep state. */ -int soc_prev_sleep_state(const struct chipset_power_state *ps, - int prev_sleep_state) -{ - - /* - * Check for any power failure to determine if this a wake from - * S5 because the PCH does not set the WAK_STS bit when waking - * from a true G3 state. - */ - if (ps->gen_pmcon_b & (PWR_FLR | SUS_PWR_FLR)) - prev_sleep_state = ACPI_S5; - - /* - * If waking from S3 determine if deep S3 is enabled. If not, - * need to check both deep sleep well and normal suspend well. - * Otherwise just check deep sleep well. - */ - if (prev_sleep_state == ACPI_S3) { - /* PWR_FLR represents deep sleep power well loss. */ - uint32_t mask = PWR_FLR; - - /* If deep s3 isn't enabled check the suspend well too. */ - if (!deep_s3_enabled()) - mask |= SUS_PWR_FLR; - - if (ps->gen_pmcon_b & mask) - prev_sleep_state = ACPI_S5; - } - - return prev_sleep_state; -} - -void soc_fill_power_state(struct chipset_power_state *ps) -{ - uint8_t *pmc; - - ps->tco1_sts = tco_read_reg(TCO1_STS); - ps->tco2_sts = tco_read_reg(TCO2_STS); - - printk(BIOS_DEBUG, "TCO_STS: %04x %04x\n", - ps->tco1_sts, ps->tco2_sts); - - pmc = pmc_mmio_regs(); - ps->gen_pmcon_a = read32(pmc + GEN_PMCON_A); - ps->gen_pmcon_b = read32(pmc + GEN_PMCON_B); - ps->gblrst_cause[0] = read32(pmc + GBLRST_CAUSE0); - ps->gblrst_cause[1] = read32(pmc + GBLRST_CAUSE1); - - printk(BIOS_DEBUG, "GEN_PMCON: %08x %08x\n", - ps->gen_pmcon_a, ps->gen_pmcon_b); - - printk(BIOS_DEBUG, "GBLRST_CAUSE: %08x %08x\n", - ps->gblrst_cause[0], ps->gblrst_cause[1]); -} From ffb83bee2627f1e33f8302a3e630e036e93891a9 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 13:58:43 +0530 Subject: [PATCH 143/588] soc/intel/icelake: Select FSP_M_XIP This patch ports CB:32275 changes from CNL to ICL. Ice Lake require that FSP-M component should be XIP. This change selects FSP_M_XIP so that the right arguments are passed into cbfstool when adding this component. Change-Id: Icc5550f1f94957fa1b28c8bba6fc0efee98e233e Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32507 Reviewed-by: Rizwan Qureshi Reviewed-by: Ronak Kanabar Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/icelake/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/intel/icelake/Kconfig b/src/soc/intel/icelake/Kconfig index 2fbc6da15f9..a4b46baab5c 100644 --- a/src/soc/intel/icelake/Kconfig +++ b/src/soc/intel/icelake/Kconfig @@ -19,6 +19,7 @@ config CPU_SPECIFIC_OPTIONS select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM select COMMON_FADT select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + select FSP_M_XIP select GENERIC_GPIO_LIB select HAVE_FSP_GOP select INTEL_DESCRIPTOR_MODE_CAPABLE From 42f9f14a61d7e71fabaf87125ecee992a5bd0dfa Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 29 Apr 2019 14:58:20 +0530 Subject: [PATCH 144/588] soc/intel/icelake: Correct the GPE DWx mapping for GPIO groups This implementation corrects the GPE DWx mapping for GPIO groups. The assignments is done in GPIO MISCFG register for all GPIO communities. And configures the which GPIO communities get register as Tier1. Change-Id: I9c306d46e5194944def26c24cdb95f5ebada42b8 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32508 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Rizwan Qureshi --- .../intel/icelake/include/soc/gpio_soc_defs.h | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/soc/intel/icelake/include/soc/gpio_soc_defs.h b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h index e3eaf62d5c4..5a27a15bd6d 100644 --- a/src/soc/intel/icelake/include/soc/gpio_soc_defs.h +++ b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h @@ -21,17 +21,18 @@ * The GPIO groups are accessed through register blocks called * communities. */ -#define GPP_G 0 -#define GPP_B 1 -#define GPP_A 2 -#define GPP_H 3 -#define GPP_D 4 -#define GPP_F 5 -#define GPD 6 -#define GPP_C 7 -#define GPP_E 8 -#define GPP_R 9 -#define GPP_S 0xA +#define GPP_G 0x0 +#define GPP_B 0x1 +#define GPP_A 0x2 +#define GPP_R 0x3 +#define GPP_S 0x4 +#define GPD 0x5 +#define GPP_H 0x6 +#define GPP_D 0x7 +#define GPP_F 0x8 +#define GPP_VGPIO 0x9 +#define GPP_C 0xA +#define GPP_E 0xB #define GPIO_NUM_GROUPS 11 #define GPIO_MAX_NUM_PER_GROUP 24 From 4d6cfc82ede3bd1e0a25793e3bc81a6966d1ab8e Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 30 Apr 2019 14:26:14 +0530 Subject: [PATCH 145/588] mainboard/intel/icelake_rvp: Add support to read board ID from EC This patch selects EC_ACPI kconfig to identify Intel Ice Lake RVP board by querying EC. Change-Id: I0082e04ef1b21d533e40d232209ee630f748aec6 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32523 Tested-by: build bot (Jenkins) Reviewed-by: Maulik V Vaghela --- src/mainboard/intel/icelake_rvp/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/intel/icelake_rvp/Kconfig b/src/mainboard/intel/icelake_rvp/Kconfig index 7cc4e535b81..728a532054f 100644 --- a/src/mainboard/intel/icelake_rvp/Kconfig +++ b/src/mainboard/intel/icelake_rvp/Kconfig @@ -3,6 +3,7 @@ if BOARD_INTEL_ICELAKE_RVPU || BOARD_INTEL_ICELAKE_RVPY config BOARD_SPECIFIC_OPTIONS def_bool y select BOARD_ROMSIZE_KB_16384 + select EC_ACPI select GENERIC_SPD_BIN select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES From 32851c6df794d194d1c1f4c0cf987ac66c8b5e8a Mon Sep 17 00:00:00 2001 From: T Michael Turney Date: Tue, 23 Apr 2019 13:47:04 -0700 Subject: [PATCH 146/588] sdm845: Select VBOOT_MIGRATE_WORKING_DATA, now required Change-Id: Idebbbd89de05d949e6f953aa49d8662d64383d1a Signed-off-by: T Michael Turney Reviewed-on: https://review.coreboot.org/c/coreboot/+/32449 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/qualcomm/sdm845/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/qualcomm/sdm845/Kconfig b/src/soc/qualcomm/sdm845/Kconfig index ba064889f08..ffb95cb4cda 100644 --- a/src/soc/qualcomm/sdm845/Kconfig +++ b/src/soc/qualcomm/sdm845/Kconfig @@ -18,6 +18,7 @@ config VBOOT select VBOOT_RETURN_FROM_VERSTAGE select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_MIGRATE_WORKING_DATA config SDM845_QSPI bool From 7a3e46d767890f502b09771e19decc5033e27079 Mon Sep 17 00:00:00 2001 From: T Michael Turney Date: Thu, 21 Mar 2019 14:21:26 -0700 Subject: [PATCH 147/588] qualcomm: Add QCLib interface support to common/ Change-Id: I38d086c379a3c2f54d1603a2fed5b33860f7f4d7 Signed-off-by: T Michael Turney Reviewed-on: https://review.coreboot.org/c/coreboot/+/32288 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/qualcomm/common/Kconfig | 5 + .../qualcomm/common/include/soc/mmu_common.h | 31 +++ .../common/include/soc/qclib_common.h | 76 ++++++ .../common/include/soc/symbols_common.h | 25 ++ src/soc/qualcomm/common/mmu.c | 26 ++ src/soc/qualcomm/common/qclib.c | 227 ++++++++++++++++++ 6 files changed, 390 insertions(+) create mode 100644 src/soc/qualcomm/common/Kconfig create mode 100644 src/soc/qualcomm/common/include/soc/mmu_common.h create mode 100644 src/soc/qualcomm/common/include/soc/qclib_common.h create mode 100644 src/soc/qualcomm/common/include/soc/symbols_common.h create mode 100644 src/soc/qualcomm/common/mmu.c create mode 100644 src/soc/qualcomm/common/qclib.c diff --git a/src/soc/qualcomm/common/Kconfig b/src/soc/qualcomm/common/Kconfig new file mode 100644 index 00000000000..f3d12629fb2 --- /dev/null +++ b/src/soc/qualcomm/common/Kconfig @@ -0,0 +1,5 @@ + +config QC_SDI_ENABLE + bool + default n + prompt "Debug Build: enable SDI" diff --git a/src/soc/qualcomm/common/include/soc/mmu_common.h b/src/soc/qualcomm/common/include/soc/mmu_common.h new file mode 100644 index 00000000000..ee781224bd4 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/mmu_common.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_MMU_COMMON_H_ +#define _SOC_QUALCOMM_MMU_COMMON_H_ + +#include +#include + +#define CACHED_RAM (MA_MEM | MA_S | MA_RW) +#define UNCACHED_RAM (MA_MEM | MA_S | MA_RW | MA_MEM_NC) +#define DEV_MEM (MA_DEV | MA_S | MA_RW) + +static struct region * const ddr_region = (struct region *)_ddr_information; + +void soc_mmu_dram_config_post_dram_init(void); +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size); + +#endif /* _SOC_QUALCOMM_MMU_COMMON_H_ */ diff --git a/src/soc/qualcomm/common/include/soc/qclib_common.h b/src/soc/qualcomm/common/include/soc/qclib_common.h new file mode 100644 index 00000000000..19ec083bfd1 --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/qclib_common.h @@ -0,0 +1,76 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_QCLIB_COMMON_H__ +#define _SOC_QUALCOMM_QCLIB_COMMON_H__ + +/* coreboot & QCLib I/F definitions */ + +/* string field lengths */ +#define QCLIB_MAGIC_NUMBER_LENGTH 8 +#define QCLIB_FMAP_NAME_LENGTH 24 +#define QCLIB_TE_NAME_LENGTH 24 + +/* FMAP_REGION names */ +#define QCLIB_FR_DDR_TRAINING_DATA "RO_DDR_TRAINING" +#define QCLIB_FR_LIMITS_CFG_DATA "RO_LIMITS_CFG" + +/* TE_NAME (table entry name) */ +#define QCLIB_TE_DDR_INFORMATION "ddr_information" +#define QCLIB_TE_QCLIB_LOG_BUFFER "qclib_log_buffer" +#define QCLIB_TE_DCB_SETTINGS "dcb_settings" +#define QCLIB_TE_CDT_SETTINGS "cdt_settings" +#define QCLIB_TE_PMIC_SETTINGS "pmic_settings" +#define QCLIB_TE_DDR_TRAINING_DATA "ddr_training_data" +#define QCLIB_TE_LIMITS_CFG_DATA "limits_cfg_data" +#define QCLIB_TE_QCSDI "qcsdi" + +/* BA_BMASK_VALUES (blob_attributes bit mask values) */ +#define QCLIB_BA_SAVE_TO_STORAGE 0x00000001 + +struct qclib_cb_if_table_entry { + char name[QCLIB_TE_NAME_LENGTH]; /* 0x00 TE_NAME */ + uint64_t blob_address; /* 0x18 blob addr in SRAM */ + uint32_t size; /* 0x20 blob size in SRAM */ + uint32_t blob_attributes; /* 0x24 BA_BMASK_VALUES */ +}; + +/* GA_BMASK_VALUES (global_attributes bit mask values) */ +#define QCLIB_GA_ENABLE_UART_LOGGING 0x00000001 + +#define QCLIB_INTERFACE_VERSION 0x00000001 +#define QCLIB_MAX_NUMBER_OF_ENTRIES 16 + +#define QCLIB_MAGIC_NUMBER "QCLIB_CB" + +struct qclib_cb_if_table { + char magic[8]; /* 0x00 */ + uint32_t version; /* 0x08 */ + uint32_t num_entries; /* 0x0C */ + uint32_t max_entries; /* 0x10 */ + uint32_t global_attributes; /* 0x14 */ + uint64_t reserved; /* 0x18 */ + struct qclib_cb_if_table_entry + te[QCLIB_MAX_NUMBER_OF_ENTRIES]; /* 0x20 */ +}; + +extern struct qclib_cb_if_table qclib_cb_if_table; + +void qclib_add_if_table_entry(const char *name, void *base, + uint32_t size, uint32_t attrs); +void qclib_load_and_run(void); +int qclib_soc_blob_load(void); + +#endif // _SOC_QUALCOMM_QCLIB_COMMON_H_ diff --git a/src/soc/qualcomm/common/include/soc/symbols_common.h b/src/soc/qualcomm/common/include/soc/symbols_common.h new file mode 100644 index 00000000000..ffa535c493f --- /dev/null +++ b/src/soc/qualcomm/common/include/soc/symbols_common.h @@ -0,0 +1,25 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_QUALCOMM_SYMBOLS_COMMON_H_ +#define _SOC_QUALCOMM_SYMBOLS_COMMON_H_ + +#include + +DECLARE_REGION(ddr_training); +DECLARE_REGION(qclib_serial_log); +DECLARE_REGION(ddr_information); + +#endif // _SOC_QUALCOMM_SYMBOLS_COMMON_H_ diff --git a/src/soc/qualcomm/common/mmu.c b/src/soc/qualcomm/common/mmu.c new file mode 100644 index 00000000000..79d2eb72710 --- /dev/null +++ b/src/soc/qualcomm/common/mmu.c @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +__weak void soc_mmu_dram_config_post_dram_init(void) { /* no-op */ } + +void qc_mmu_dram_config_post_dram_init(void *ddr_base, size_t ddr_size) +{ + mmu_config_range((void *)ddr_base, ddr_size, CACHED_RAM); + soc_mmu_dram_config_post_dram_init(); +} diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c new file mode 100644 index 00000000000..1fd79b57b5a --- /dev/null +++ b/src/soc/qualcomm/common/qclib.c @@ -0,0 +1,227 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct qclib_cb_if_table qclib_cb_if_table = { + .magic = QCLIB_MAGIC_NUMBER, + .version = QCLIB_INTERFACE_VERSION, + .num_entries = 0, + .max_entries = QCLIB_MAX_NUMBER_OF_ENTRIES, + .global_attributes = 0, + .reserved = 0, +}; + +void qclib_add_if_table_entry(const char *name, void *base, + uint32_t size, uint32_t attrs) +{ + struct qclib_cb_if_table_entry *te = + &qclib_cb_if_table.te[qclib_cb_if_table.num_entries++]; + assert(qclib_cb_if_table.num_entries <= qclib_cb_if_table.max_entries); + strncpy(te->name, name, sizeof(te->name)); + te->blob_address = (uintptr_t)base; + te->size = size; + te->blob_attributes = attrs; +} + +static void write_ddr_information(struct qclib_cb_if_table_entry *te) +{ + uint64_t ddr_size; + + /* Save DDR info in SRAM region to share with ramstage */ + ddr_region->offset = te->blob_address; + ddr_size = te->size; + ddr_region->size = ddr_size * MiB; + + /* Use DDR info to configure MMU */ + qc_mmu_dram_config_post_dram_init((void *)ddr_region->offset, + (size_t)ddr_region->size); +} + +static void write_qclib_log_to_cbmemc(struct qclib_cb_if_table_entry *te) +{ + int i; + char *ptr = (char *)te->blob_address; + + for (i = 0; i < te->size; i++) + __cbmemc_tx_byte(*ptr++); +} + +static void write_table_entry(struct qclib_cb_if_table_entry *te) +{ + + if (!strncmp(QCLIB_TE_DDR_INFORMATION, te->name, + sizeof(te->name))) { + + write_ddr_information(te); + + } else if (!strncmp(QCLIB_TE_DDR_TRAINING_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_DDR_TRAINING_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_LIMITS_CFG_DATA, te->name, + sizeof(te->name))) { + + assert(fmap_overwrite_area(QCLIB_FR_LIMITS_CFG_DATA, + (const void *)te->blob_address, te->size)); + + } else if (!strncmp(QCLIB_TE_QCLIB_LOG_BUFFER, te->name, + sizeof(te->name))) { + + write_qclib_log_to_cbmemc(te); + + } else { + + printk(BIOS_WARNING, "%s write not implemented\n", te->name); + printk(BIOS_WARNING, " blob_address[%llx]..size[%x]\n", + te->blob_address, te->size); + + } +} + +static void dump_te_table(void) +{ + struct qclib_cb_if_table_entry *te; + int i; + + for (i = 0; i < qclib_cb_if_table.num_entries; i++) { + te = &qclib_cb_if_table.te[i]; + printk(BIOS_DEBUG, "[%s][%llx][%x][%x]\n", + te->name, te->blob_address, + te->size, te->blob_attributes); + } +} + +__weak int qclib_soc_blob_load(void) { return 0; } + +void qclib_load_and_run(void) +{ + int i; + ssize_t ssize; + struct mmu_context pre_qclib_mmu_context; + + /* zero ddr_information SRAM region, needs new data each boot */ + memset(ddr_region, 0, sizeof(struct region)); + + /* output area, QCLib copies console log buffer out */ + if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + qclib_add_if_table_entry(QCLIB_TE_QCLIB_LOG_BUFFER, + _qclib_serial_log, + REGION_SIZE(qclib_serial_log), 0); + + /* output area, QCLib fills in DDR details */ + qclib_add_if_table_entry(QCLIB_TE_DDR_INFORMATION, NULL, 0, 0); + + /* Attempt to load DDR Training Blob */ + ssize = fmap_read_area(QCLIB_FR_DDR_TRAINING_DATA, _ddr_training, + REGION_SIZE(ddr_training)); + if (ssize < 0) + goto fail; + qclib_add_if_table_entry(QCLIB_TE_DDR_TRAINING_DATA, + _ddr_training, ssize, 0); + + /* hook for SoC specific binary blob loads */ + if (qclib_soc_blob_load()) { + printk(BIOS_ERR, "qclib_soc_blob_load failed\n"); + goto fail; + } + + /* Enable QCLib serial output, based on Kconfig */ + if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + qclib_cb_if_table.global_attributes = + QCLIB_GA_ENABLE_UART_LOGGING; + + if (IS_ENABLED(CONFIG_QC_SDI_ENABLE)) { + struct prog qcsdi = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/qcsdi"); + + /* Attempt to load QCSDI elf */ + if (prog_locate(&qcsdi)) + goto fail; + + if (cbfs_prog_stage_load(&qcsdi)) + goto fail; + + qclib_add_if_table_entry(QCLIB_TE_QCSDI, prog_entry(&qcsdi), + prog_size(&qcsdi), 0); + printk(BIOS_INFO, "qcsdi.entry[%p]\n", qcsdi.entry); + } + + dump_te_table(); + + /* Attempt to load QCLib elf */ + struct prog qclib = + PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/qclib"); + + if (prog_locate(&qclib)) + goto fail; + + if (cbfs_prog_stage_load(&qclib)) + goto fail; + + prog_set_entry(&qclib, prog_entry(&qclib), &qclib_cb_if_table); + + printk(BIOS_DEBUG, "\n\n\nQCLib is about to Initialize DDR\n"); + printk(BIOS_DEBUG, "Global Attributes[%x]..Table Entries Count[%d]\n", + qclib_cb_if_table.global_attributes, + qclib_cb_if_table.num_entries); + printk(BIOS_DEBUG, "Jumping to QCLib code at %p(%p)\n", + prog_entry(&qclib), prog_entry_arg(&qclib)); + + /* back-up mmu context before disabling mmu and executing qclib */ + mmu_save_context(&pre_qclib_mmu_context); + /* disable mmu before jumping to qclib. mmu_disable also + flushes and invalidates caches before disabling mmu. */ + mmu_disable(); + + prog_run(&qclib); + + /* Before returning, QCLib flushes cache and disables mmu. + Explicitly disable mmu (flush, invalidate and disable mmu) + before re-enabling mmu with backed-up mmu context */ + mmu_disable(); + mmu_restore_context(&pre_qclib_mmu_context); + mmu_enable(); + + /* step through I/F table, handling return values */ + for (i = 0; i < qclib_cb_if_table.num_entries; i++) + if (qclib_cb_if_table.te[i].blob_attributes & + QCLIB_BA_SAVE_TO_STORAGE) + write_table_entry(&qclib_cb_if_table.te[i]); + + /* confirm that we received valid ddr information from QCLib */ + assert((uintptr_t)_dram == region_offset(ddr_region) && + region_sz(ddr_region) >= (u8 *)cbmem_top() - _dram); + + printk(BIOS_DEBUG, "QCLib completed\n\n\n"); + + return; + +fail: + die("Couldn't run QCLib.\n"); +} From c0fe0b28a9461e963d6dff5d91cf70231dcae0e8 Mon Sep 17 00:00:00 2001 From: Chandana Kishori Chiluveru Date: Mon, 26 Mar 2018 15:13:36 -0700 Subject: [PATCH 148/588] sdm845: Add USB support on cheza platform This patch adds code to initialize two USB DWC3.0 controllers and its associated QUSB V2 10nm PHYs to the SDM845 SOC, and uses them to initialize USB3.0 on the cheza mainboard. Synopsis controller initialization and configuration sequences taken from USB 3.0 HPG chapter 2.2 and refer PHY HPG chapter 10.2 for QUSB phy programming. Includes Super speed mode support. TEST=USB keypad and mass-storage device enumeration tested with this patch Change-Id: I475a7757239acb8ef22a4d61afd59b304a7f0acc Signed-off-by: Chandana Kishori Chiluveru Reviewed-on: https://review.coreboot.org/c/coreboot/+/25213 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/mainboard/google/cheza/mainboard.c | 14 + src/mainboard/google/cheza/romstage.c | 11 + src/soc/qualcomm/sdm845/Makefile.inc | 2 + .../qualcomm/sdm845/include/soc/addressmap.h | 19 + src/soc/qualcomm/sdm845/include/soc/clock.h | 33 +- src/soc/qualcomm/sdm845/include/soc/efuse.h | 30 + src/soc/qualcomm/sdm845/include/soc/usb.h | 96 ++ src/soc/qualcomm/sdm845/usb.c | 915 ++++++++++++++++++ 8 files changed, 1114 insertions(+), 6 deletions(-) create mode 100644 src/soc/qualcomm/sdm845/include/soc/efuse.h create mode 100644 src/soc/qualcomm/sdm845/include/soc/usb.h create mode 100644 src/soc/qualcomm/sdm845/usb.c diff --git a/src/mainboard/google/cheza/mainboard.c b/src/mainboard/google/cheza/mainboard.c index cb4f5d061a2..42adf56c795 100644 --- a/src/mainboard/google/cheza/mainboard.c +++ b/src/mainboard/google/cheza/mainboard.c @@ -16,9 +16,23 @@ #include #include #include +#include +#include + +static struct usb_board_data usb1_board_data = { + .pll_bias_control_2 = 0x28, + .imp_ctrl1 = 0x08, + .port_tune1 = 0x20, +}; static void setup_usb(void) { + /* + * Primary USB is used only for DP functionality on cheza platform. + * Hence Setting up only Secondary USB DWC3 controller. + */ + setup_usb_host1(&usb1_board_data); + gpio_output(GPIO(120), 1); /* Deassert HUB_RST_L to enable hub. */ } diff --git a/src/mainboard/google/cheza/romstage.c b/src/mainboard/google/cheza/romstage.c index ad8506193d9..7b7da4ce8c2 100644 --- a/src/mainboard/google/cheza/romstage.c +++ b/src/mainboard/google/cheza/romstage.c @@ -14,7 +14,18 @@ */ #include +#include + +static void prepare_usb(void) +{ + /* + * Do DWC3 core and phy reset. Kick these resets + * off early so they get at least 1ms to settle. + */ + reset_usb1(); +} void platform_romstage_main(void) { + prepare_usb(); } diff --git a/src/soc/qualcomm/sdm845/Makefile.inc b/src/soc/qualcomm/sdm845/Makefile.inc index 896ae58e5fa..d099bff7174 100644 --- a/src/soc/qualcomm/sdm845/Makefile.inc +++ b/src/soc/qualcomm/sdm845/Makefile.inc @@ -24,6 +24,7 @@ romstage-y += timer.c romstage-y += gpio.c romstage-y += clock.c romstage-$(CONFIG_SDM845_QSPI) += qspi.c +romstage-y += usb.c ################################################################################ ramstage-y += soc.c @@ -33,6 +34,7 @@ ramstage-y += timer.c ramstage-y += gpio.c ramstage-y += clock.c ramstage-$(CONFIG_SDM845_QSPI) += qspi.c +ramstage-y += usb.c ################################################################################ diff --git a/src/soc/qualcomm/sdm845/include/soc/addressmap.h b/src/soc/qualcomm/sdm845/include/soc/addressmap.h index 5a94e23e96a..bf4b30b32b7 100644 --- a/src/soc/qualcomm/sdm845/include/soc/addressmap.h +++ b/src/soc/qualcomm/sdm845/include/soc/addressmap.h @@ -25,4 +25,23 @@ #define GCC_BASE 0x00100000 #define AOSS_CC_BASE 0x0C2F0000 +/* + * USB BASE ADDRESSES + */ +#define QFPROM_BASE 0x00780000 +#define QUSB_PRIM_PHY_BASE 0x088e2000 +#define QUSB_PRIM_PHY_DIG_BASE 0x088e2200 +#define QUSB_SEC_PHY_BASE 0x088e3000 +#define QUSB_SEC_PHY_DIG_BASE 0x088e3200 +#define QMP_PHY_QSERDES_COM_REG_BASE 0x088e9000 +#define QMP_PHY_QSERDES_TX_REG_BASE 0x088e9200 +#define QMP_PHY_QSERDES_RX_REG_BASE 0x088e9400 +#define QMP_PHY_PCS_REG_BASE 0x088e9c00 +#define QMP_UNIPHY_QSERDES_COM_REG_BASE 0x088eb000 +#define QMP_UNIPHY_QSERDES_TX_REG_BASE 0x088eb200 +#define QMP_UNIPHY_QSERDES_RX_REG_BASE 0x088eb400 +#define QMP_UNIPHY_PCS_REG_BASE 0x088eb800 +#define USB_HOST0_DWC3_BASE 0x0a60c100 +#define USB_HOST1_DWC3_BASE 0x0a80c100 + #endif /* __SOC_QUALCOMM_SDM845_ADDRESS_MAP_H__ */ diff --git a/src/soc/qualcomm/sdm845/include/soc/clock.h b/src/soc/qualcomm/sdm845/include/soc/clock.h index 9f0533f33f4..6aee9c14f34 100644 --- a/src/soc/qualcomm/sdm845/include/soc/clock.h +++ b/src/soc/qualcomm/sdm845/include/soc/clock.h @@ -74,7 +74,14 @@ struct sdm845_gpll { struct sdm845_gcc { struct sdm845_gpll gpll0; - u8 _res0[0x17000 - 0x1000]; + u8 _res0[0xf000 - 0x1000]; + u32 usb30_prim_bcr; + u8 _res1[0x10000 - 0xf004]; + u32 usb30_sec_bcr; + u8 _res2[0x12000 - 0x10004]; + u32 qusb2phy_prim_bcr; + u32 qusb2phy_sec_bcr; + u8 _res3[0x17000 - 0x12008]; u32 qup_wrap0_bcr; u32 qup_wrap0_m_ahb_cbcr; u32 qup_wrap0_s_ahb_cbcr; @@ -82,9 +89,9 @@ struct sdm845_gcc { u32 qup_wrap0_core_cdivr; u32 qup_wrap0_core_2x_cbcr; struct sdm845_rcg qup_wrap0_core_2x; - u8 _res1[0x17030 - 0x17020]; + u8 _res4[0x17030 - 0x17020]; struct sdm845_qupv3_clock qup_wrap0_s[8]; - u8 _res2[0x18000 - 0x179b0]; + u8 _res5[0x18000 - 0x179b0]; u32 qup_wrap1_bcr; u32 qup_wrap1_core_2x_cbcr; u32 qup_wrap1_core_cbcr; @@ -92,14 +99,28 @@ struct sdm845_gcc { u32 qup_wrap1_s_ahb_cbcr; struct sdm845_qupv3_clock qup_wrap1_s[8]; u32 qup_wrap1_core_cdivr; - u8 _res4[0x4B000 - 0x18998]; + u8 _res6[0x4B000 - 0x18998]; u32 qspi_cnoc_ahb_cbcr; u32 qspi_core_cbcr; struct sdm845_rcg qspi_core; - u8 _res5[0x5200c-0x4b010]; + u8 _res7[0x50000-0x4b010]; + u32 usb3_phy_prim_bcr; + u32 usb3phy_phy_prim_bcr; + u32 usb3_dp_phy_prim_bcr; + u32 usb3_phy_sec_bcr; + u32 usb3phy_phy_sec_bcr; + u8 _res8[0x5200c-0x50014]; u32 apcs_clk_br_en1; - u8 _res6[0x1000000-0x52010]; + u8 _res9[0x1000000-0x52010]; }; +check_member(sdm845_gcc, usb30_prim_bcr, 0xf000); +check_member(sdm845_gcc, usb30_sec_bcr, 0x10000); +check_member(sdm845_gcc, qusb2phy_prim_bcr, 0x12000); +check_member(sdm845_gcc, qusb2phy_sec_bcr, 0x12004); +check_member(sdm845_gcc, usb3phy_phy_prim_bcr, 0x50004); +check_member(sdm845_gcc, usb3_phy_prim_bcr, 0x50000); +check_member(sdm845_gcc, usb3_phy_sec_bcr, 0x5000c); +check_member(sdm845_gcc, usb3phy_phy_sec_bcr, 0x50010); check_member(sdm845_gcc, apcs_clk_br_en1, 0x5200c); struct sdm845_aoss { diff --git a/src/soc/qualcomm/sdm845/include/soc/efuse.h b/src/soc/qualcomm/sdm845/include/soc/efuse.h new file mode 100644 index 00000000000..309193cf436 --- /dev/null +++ b/src/soc/qualcomm/sdm845/include/soc/efuse.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __SOC_QUALCOMM_SDM845_EFUSE_ADDRESS_MAP_H__ +#define __SOC_QUALCOMM_SDM845_EFUSE_ADDRESS_MAP_H__ + +/** + * USB EFUSE registers + */ +struct qfprom_corr { + u8 rsvd[0x41E8 - 0x0]; + u32 qusb_hstx_trim_lsb; + u32 qusb_hstx_trim_msb; +}; + +check_member(qfprom_corr, qusb_hstx_trim_lsb, 0x41E8); +check_member(qfprom_corr, qusb_hstx_trim_msb, 0x41EC); +#endif /* __SOC_QUALCOMM_SDM845_EFUSE_ADDRESS_MAP_H__ */ diff --git a/src/soc/qualcomm/sdm845/include/soc/usb.h b/src/soc/qualcomm/sdm845/include/soc/usb.h new file mode 100644 index 00000000000..b6576767632 --- /dev/null +++ b/src/soc/qualcomm/sdm845/include/soc/usb.h @@ -0,0 +1,96 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +#include + +#ifndef _SDM845_USB_H_ +#define _SDM845_USB_H_ + +/* QSCRATCH_GENERAL_CFG register bit offset */ +#define PIPE_UTMI_CLK_SEL BIT(0) +#define PIPE3_PHYSTATUS_SW BIT(3) +#define PIPE_UTMI_CLK_DIS BIT(8) + +/* Global USB3 Control Registers */ +#define DWC3_GUSB3PIPECTL_DELAYP1TRANS BIT(18) +#define DWC3_GUSB3PIPECTL_UX_EXIT_IN_PX BIT(27) +#define DWC3_GCTL_PRTCAPDIR(n) ((n) << 12) +#define DWC3_GCTL_PRTCAP_OTG 3 +#define DWC3_GCTL_PRTCAP_HOST 1 + +/* Global USB2 PHY Configuration Register */ +#define DWC3_GUSB2PHYCFG_USBTRDTIM(n) ((n) << 10) +#define DWC3_GUSB2PHYCFG_USB2TRDTIM_MASK DWC3_GUSB2PHYCFG_USBTRDTIM(0xf) +#define DWC3_GUSB2PHYCFG_PHYIF(n) ((n) << 3) +#define DWC3_GUSB2PHYCFG_PHYIF_MASK DWC3_GUSB2PHYCFG_PHYIF(1) +#define USBTRDTIM_UTMI_8_BIT 9 +#define UTMI_PHYIF_8_BIT 0 + +#define DWC3_GCTL_SCALEDOWN(n) ((n) << 4) +#define DWC3_GCTL_SCALEDOWN_MASK DWC3_GCTL_SCALEDOWN(3) +#define DWC3_GCTL_DISSCRAMBLE (1 << 3) +#define DWC3_GCTL_U2EXIT_LFPS (1 << 2) +#define DWC3_GCTL_DSBLCLKGTNG (1 << 0) + +#define PORT_TUNE1_MASK 0xf0 + +/* QUSB2PHY_PWR_CTRL1 register related bits */ +#define POWER_DOWN BIT(0) + +/* DEBUG_CTRL2 register value to program VSTATUS MUX for PHY status */ +#define DEBUG_CTRL2_MUX_PLL_LOCK_STATUS 0x4 + +/* STAT5 register bits */ +#define VSTATUS_PLL_LOCK_STATUS_MASK BIT(0) + +/* QUSB PHY register values */ +#define QUSB2PHY_PLL_ANALOG_CONTROLS_TWO 0x03 +#define QUSB2PHY_PLL_CLOCK_INVERTERS 0x7c +#define QUSB2PHY_PLL_CMODE 0x80 +#define QUSB2PHY_PLL_LOCK_DELAY 0x0a +#define QUSB2PHY_PLL_DIGITAL_TIMERS_TWO 0x19 +#define QUSB2PHY_PLL_BIAS_CONTROL_1 0x40 +#define QUSB2PHY_PLL_BIAS_CONTROL_2 0x20 +#define QUSB2PHY_PWR_CTRL2 0x21 +#define QUSB2PHY_IMP_CTRL1 0x0 +#define QUSB2PHY_IMP_CTRL2 0x58 +#define QUSB2PHY_PORT_TUNE1 0x30 +#define QUSB2PHY_PORT_TUNE2 0x29 +#define QUSB2PHY_PORT_TUNE3 0xca +#define QUSB2PHY_PORT_TUNE4 0x04 +#define QUSB2PHY_PORT_TUNE5 0x03 +#define QUSB2PHY_CHG_CTRL2 0x0 + +/* USB3PHY_PCIE_USB3_PCS_PCS_STATUS bit */ +#define USB3_PCS_PHYSTATUS BIT(6) + +struct usb_board_data { + /* Register values going to override from the boardfile */ + u32 pll_bias_control_2; + u32 imp_ctrl1; + u32 port_tune1; +}; + +struct qmp_phy_init_tbl { + u32 *address; + u32 val; +}; + +void setup_usb_host0(struct usb_board_data *data); +void setup_usb_host1(struct usb_board_data *data); +/* Call reset_ before setup_ */ +void reset_usb0(void); +void reset_usb1(void); + +#endif /* _SDM845_USB_H_ */ diff --git a/src/soc/qualcomm/sdm845/usb.c b/src/soc/qualcomm/sdm845/usb.c new file mode 100644 index 00000000000..c7d65e6b426 --- /dev/null +++ b/src/soc/qualcomm/sdm845/usb.c @@ -0,0 +1,915 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2018 Qualcomm Technologies + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct usb_qusb_phy_dig { + u8 rsvd1[16]; + u32 pwr_ctrl1; + u32 pwr_ctrl2; + u8 rsvd2[8]; + u32 imp_ctrl1; + u32 imp_ctrl2; + u8 rsvd3[20]; + u32 chg_ctrl2; + u32 tune1; + u32 tune2; + u32 tune3; + u32 tune4; + u32 tune5; + u8 rsvd4[44]; + u32 debug_ctrl2; + u8 rsvd5[28]; + u32 debug_stat5; +}; +check_member(usb_qusb_phy_dig, tune5, 0x50); +check_member(usb_qusb_phy_dig, debug_ctrl2, 0x80); +check_member(usb_qusb_phy_dig, debug_stat5, 0xA0); + +struct usb_qusb_phy_pll { + u8 rsvd0[4]; + u32 analog_controls_two; + u8 rsvd1[36]; + u32 cmode; + u8 rsvd2[132]; + u32 dig_tim; + u8 rsvd3[204]; + u32 lock_delay; + u8 rsvd4[4]; + u32 clock_inverters; + u8 rsvd5[4]; + u32 bias_ctrl_1; + u32 bias_ctrl_2; +}; +check_member(usb_qusb_phy_pll, cmode, 0x2C); +check_member(usb_qusb_phy_pll, bias_ctrl_2, 0x198); +check_member(usb_qusb_phy_pll, dig_tim, 0xB4); + +/* Only for QMP V3 PHY - QSERDES COM registers */ +struct usb3_phy_qserdes_com_reg_layout { + u8 _reserved1[16]; + u32 com_ssc_en_center; + u32 com_ssc_adj_per1; + u32 com_ssc_adj_per2; + u32 com_ssc_per1; + u32 com_ssc_per2; + u32 com_ssc_step_size1; + u32 com_ssc_step_size2; + u8 _reserved2[8]; + u32 com_bias_en_clkbuflr_en; + u32 com_sys_clk_enable1; + u32 com_sys_clk_ctrl; + u32 com_sysclk_buf_enable; + u32 com_pll_en; + u32 com_pll_ivco; + u8 _reserved3[20]; + u32 com_cp_ctrl_mode0; + u8 _reserved4[4]; + u32 com_pll_rctrl_mode0; + u8 _reserved5[4]; + u32 com_pll_cctrl_mode0; + u8 _reserved6[12]; + u32 com_sysclk_en_sel; + u8 _reserved7[8]; + u32 com_resetsm_ctrl2; + u32 com_lock_cmp_en; + u32 com_lock_cmp_cfg; + u32 com_lock_cmp1_mode0; + u32 com_lock_cmp2_mode0; + u32 com_lock_cmp3_mode0; + u8 _reserved8[12]; + u32 com_dec_start_mode0; + u8 _reserved9[4]; + u32 com_div_frac_start1_mode0; + u32 com_div_frac_start2_mode0; + u32 com_div_frac_start3_mode0; + u8 _reserved10[20]; + u32 com_integloop_gain0_mode0; + u32 com_integloop_gain1_mode0; + u8 _reserved11[16]; + u32 com_vco_tune_map; + u32 com_vco_tune1_mode0; + u32 com_vco_tune2_mode0; + u8 _reserved12[60]; + u32 com_clk_select; + u32 com_hsclk_sel; + u8 _reserved13[8]; + u32 com_coreclk_div_mode0; + u8 _reserved14[8]; + u32 com_core_clk_en; + u32 com_c_ready_status; + u32 com_cmn_config; + u32 com_cmn_rate_override; + u32 com_svs_mode_clk_sel; +}; +check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_en_center, 0x010); +check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per1, 0x014); +check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_adj_per2, 0x018); +check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per1, 0x01c); +check_member(usb3_phy_qserdes_com_reg_layout, com_ssc_per2, 0x020); +check_member(usb3_phy_qserdes_com_reg_layout, com_bias_en_clkbuflr_en, 0x034); +check_member(usb3_phy_qserdes_com_reg_layout, com_pll_ivco, 0x048); +check_member(usb3_phy_qserdes_com_reg_layout, com_cp_ctrl_mode0, 0x060); +check_member(usb3_phy_qserdes_com_reg_layout, com_sysclk_en_sel, 0x080); +check_member(usb3_phy_qserdes_com_reg_layout, com_resetsm_ctrl2, 0x08c); +check_member(usb3_phy_qserdes_com_reg_layout, com_dec_start_mode0, 0x0b0); +check_member(usb3_phy_qserdes_com_reg_layout, com_div_frac_start1_mode0, 0x0b8); +check_member(usb3_phy_qserdes_com_reg_layout, com_integloop_gain0_mode0, 0x0d8); +check_member(usb3_phy_qserdes_com_reg_layout, com_vco_tune_map, 0x0f0); +check_member(usb3_phy_qserdes_com_reg_layout, com_clk_select, 0x138); +check_member(usb3_phy_qserdes_com_reg_layout, com_coreclk_div_mode0, 0x148); +check_member(usb3_phy_qserdes_com_reg_layout, com_core_clk_en, 0x154); +check_member(usb3_phy_qserdes_com_reg_layout, com_svs_mode_clk_sel, 0x164); + +/* Only for QMP V3 PHY - TX registers */ +struct usb3_phy_qserdes_tx_reg_layout { + u8 _reserved1[68]; + u32 tx_res_code_lane_offset_tx; + u32 tx_res_code_lane_offset_rx; + u8 _reserved2[20]; + u32 tx_highz_drvr_en; + u8 _reserved3[40]; + u32 tx_lane_mode_1; + u8 _reserved4[20]; + u32 tx_rcv_detect_lvl_2; +}; +check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_tx, 0x044); +check_member(usb3_phy_qserdes_tx_reg_layout, tx_res_code_lane_offset_rx, 0x048); +check_member(usb3_phy_qserdes_tx_reg_layout, tx_highz_drvr_en, 0x060); +check_member(usb3_phy_qserdes_tx_reg_layout, tx_lane_mode_1, 0x08c); +check_member(usb3_phy_qserdes_tx_reg_layout, tx_rcv_detect_lvl_2, 0x0a4); + +/* Only for QMP V3 PHY - RX registers */ +struct usb3_phy_qserdes_rx_reg_layout { + u8 _reserved1[8]; + u32 rx_ucdr_fo_gain; + u32 rx_ucdr_so_gain_half; + u8 _reserved2[32]; + u32 rx_ucdr_fastlock_fo_gain; + u32 rx_ucdr_so_saturtn_and_en; + u8 _reserved3[12]; + u32 rx_ucdr_pi_cntrls; + u8 _reserved4[120]; + u32 rx_vga_cal_ctrl2; + u8 _reserved5[16]; + u32 rx_rx_equ_adap_ctrl2; + u32 rx_rx_equ_adap_ctrl3; + u32 rx_rx_equ_adap_ctrl4; + u8 _reserved6[24]; + u32 rx_rx_eq_offset_adap_ctrl1; + u32 rx_rx_offset_adap_ctrl2; + u32 rx_sigdet_enables; + u32 rx_sigdet_ctrl; + u8 _reserved7[4]; + u32 rx_sigdet_deglitch_ctrl; + u32 rx_rx_band; + u8 _reserved8[80]; + u32 rx_rx_mode_00; +}; +check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fo_gain, 0x008); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_gain_half, 0x00c); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_fastlock_fo_gain, 0x030); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_so_saturtn_and_en, 0x034); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_ucdr_pi_cntrls, 0x044); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_vga_cal_ctrl2, 0x0c0); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl2, 0x0d4); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl3, 0x0d8); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_equ_adap_ctrl4, 0x0dc); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_eq_offset_adap_ctrl1, 0x0f8); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_offset_adap_ctrl2, 0x0fc); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_enables, 0x100); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_ctrl, 0x104); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_sigdet_deglitch_ctrl, 0x10c); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_band, 0x110); +check_member(usb3_phy_qserdes_rx_reg_layout, rx_rx_mode_00, 0x164); + +/* Only for QMP V3 PHY - PCS registers */ +struct usb3_phy_pcs_reg_layout { + u32 pcs_sw_reset; + u32 pcs_power_down_control; + u32 pcs_start_control; + u32 pcs_txmgn_v0; + u32 pcs_txmgn_v1; + u32 pcs_txmgn_v2; + u32 pcs_txmgn_v3; + u32 pcs_txmgn_v4; + u32 pcs_txmgn_ls; + u32 pcs_txdeemph_m6db_v0; + u32 pcs_txdeemph_m3p5db_v0; + u32 pcs_txdeemph_m6db_v1; + u32 pcs_txdeemph_m3p5db_v1; + u32 pcs_txdeemph_m6db_v2; + u32 pcs_txdeemph_m3p5db_v2; + u32 pcs_txdeemph_m6db_v3; + u32 pcs_txdeemph_m3p5db_v3; + u32 pcs_txdeemph_m6db_v4; + u32 pcs_txdeemph_m3p5db_v4; + u32 pcs_txdeemph_m6db_ls; + u32 pcs_txdeemph_m3p5db_ls; + u8 _reserved1[8]; + u32 pcs_rate_slew_cntrl; + u8 _reserved2[4]; + u32 pcs_power_state_config2; + u8 _reserved3[8]; + u32 pcs_rcvr_dtct_dly_p1u2_l; + u32 pcs_rcvr_dtct_dly_p1u2_h; + u32 pcs_rcvr_dtct_dly_u3_l; + u32 pcs_rcvr_dtct_dly_u3_h; + u32 pcs_lock_detect_config1; + u32 pcs_lock_detect_config2; + u32 pcs_lock_detect_config3; + u32 pcs_tsync_rsync_time; + u8 _reserved4[16]; + u32 pcs_pwrup_reset_dly_time_auxclk; + u8 _reserved5[12]; + u32 pcs_lfps_ecstart_eqtlock; + u8 _reserved6[4]; + u32 pcs_rxeqtraining_wait_time; + u32 pcs_rxeqtraining_run_time; + u8 _reserved7[4]; + u32 pcs_fll_ctrl1; + u32 pcs_fll_ctrl2; + u32 pcs_fll_cnt_val_l; + u32 pcs_fll_cnt_val_h_tol; + u32 pcs_fll_man_code; + u32 pcs_autonomous_mode_ctrl; + u8 _reserved8[152]; + u32 pcs_ready_status; + u8 _reserved9[96]; + u32 pcs_rx_sigdet_lvl; + u8 _reserved10[48]; + u32 pcs_refgen_req_config1; + u32 pcs_refgen_req_config2; +}; +check_member(usb3_phy_pcs_reg_layout, pcs_sw_reset, 0x000); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v0, 0x00c); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v1, 0x010); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v2, 0x014); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v3, 0x018); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_v4, 0x01c); +check_member(usb3_phy_pcs_reg_layout, pcs_txmgn_ls, 0x020); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v0, 0x024); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v0, 0x028); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v1, 0x02c); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v1, 0x030); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v2, 0x034); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v2, 0x038); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v3, 0x03c); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v3, 0x040); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_v4, 0x044); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_v4, 0x048); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m6db_ls, 0x04c); +check_member(usb3_phy_pcs_reg_layout, pcs_txdeemph_m3p5db_ls, 0x050); +check_member(usb3_phy_pcs_reg_layout, pcs_rate_slew_cntrl, 0x05c); +check_member(usb3_phy_pcs_reg_layout, pcs_power_state_config2, 0x064); +check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_l, 0x070); +check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_p1u2_h, 0x074); +check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_l, 0x078); +check_member(usb3_phy_pcs_reg_layout, pcs_rcvr_dtct_dly_u3_h, 0x07c); +check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config1, 0x080); +check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config2, 0x084); +check_member(usb3_phy_pcs_reg_layout, pcs_lock_detect_config3, 0x088); +check_member(usb3_phy_pcs_reg_layout, pcs_pwrup_reset_dly_time_auxclk, 0x0a0); +check_member(usb3_phy_pcs_reg_layout, pcs_rxeqtraining_wait_time, 0x0b8); +check_member(usb3_phy_pcs_reg_layout, pcs_fll_cnt_val_h_tol, 0x0d0); +check_member(usb3_phy_pcs_reg_layout, pcs_autonomous_mode_ctrl, 0x0d8); +check_member(usb3_phy_pcs_reg_layout, pcs_ready_status, 0x174); +check_member(usb3_phy_pcs_reg_layout, pcs_refgen_req_config2, 0x210); + +static struct usb3_phy_qserdes_com_reg_layout *const qserdes_com_reg_layout = + (void *)QMP_PHY_QSERDES_COM_REG_BASE; +static struct usb3_phy_qserdes_tx_reg_layout *const qserdes_tx_reg_layout = + (void *)QMP_PHY_QSERDES_TX_REG_BASE; +static struct usb3_phy_qserdes_rx_reg_layout *const qserdes_rx_reg_layout = + (void *)QMP_PHY_QSERDES_RX_REG_BASE; +static struct usb3_phy_pcs_reg_layout *const pcs_reg_layout = + (void *)QMP_PHY_PCS_REG_BASE; + +static struct usb3_phy_qserdes_com_reg_layout *const + uniphy_qserdes_com_reg_layout = + (void *)QMP_UNIPHY_QSERDES_COM_REG_BASE; +static struct usb3_phy_qserdes_tx_reg_layout + *const uniphy_qserdes_tx_reg_layout = + (void *)QMP_UNIPHY_QSERDES_TX_REG_BASE; +static struct usb3_phy_qserdes_rx_reg_layout + *const uniphy_qserdes_rx_reg_layout = + (void *)QMP_UNIPHY_QSERDES_RX_REG_BASE; +static struct usb3_phy_pcs_reg_layout *const uniphy_pcs_reg_layout = + (void *)QMP_UNIPHY_PCS_REG_BASE; + +struct usb_dwc3 { + u32 sbuscfg0; + u32 sbuscfg1; + u32 txthrcfg; + u32 rxthrcfg; + u32 ctl; + u32 pmsts; + u32 sts; + u32 uctl1; + u32 snpsid; + u32 gpio; + u32 uid; + u32 uctl; + u64 buserraddr; + u64 prtbimap; + u8 reserved1[32]; + u32 dbgfifospace; + u32 dbgltssm; + u32 dbglnmcc; + u32 dbgbmu; + u32 dbglspmux; + u32 dbglsp; + u32 dbgepinfo0; + u32 dbgepinfo1; + u64 prtbimap_hs; + u64 prtbimap_fs; + u8 reserved2[112]; + u32 usb2phycfg; + u8 reserved3[60]; + u32 usb2i2cctl; + u8 reserved4[60]; + u32 usb2phyacc; + u8 reserved5[60]; + u32 usb3pipectl; + u8 reserved6[60]; +}; +check_member(usb_dwc3, usb3pipectl, 0x1c0); + +static const struct qmp_phy_init_tbl qmp_v3_usb3_serdes_tbl[] = { + {&qserdes_com_reg_layout->com_pll_ivco, 0x07}, + {&qserdes_com_reg_layout->com_sysclk_en_sel, 0x14}, + {&qserdes_com_reg_layout->com_bias_en_clkbuflr_en, 0x08}, + {&qserdes_com_reg_layout->com_clk_select, 0x30}, + {&qserdes_com_reg_layout->com_sys_clk_ctrl, 0x02}, + {&qserdes_com_reg_layout->com_resetsm_ctrl2, 0x08}, + {&qserdes_com_reg_layout->com_cmn_config, 0x16}, + {&qserdes_com_reg_layout->com_svs_mode_clk_sel, 0x01}, + {&qserdes_com_reg_layout->com_hsclk_sel, 0x80}, + {&qserdes_com_reg_layout->com_dec_start_mode0, 0x82}, + {&qserdes_com_reg_layout->com_div_frac_start1_mode0, 0xab}, + {&qserdes_com_reg_layout->com_div_frac_start2_mode0, 0xea}, + {&qserdes_com_reg_layout->com_div_frac_start3_mode0, 0x02}, + {&qserdes_com_reg_layout->com_cp_ctrl_mode0, 0x06}, + {&qserdes_com_reg_layout->com_pll_rctrl_mode0, 0x16}, + {&qserdes_com_reg_layout->com_pll_cctrl_mode0, 0x36}, + {&qserdes_com_reg_layout->com_integloop_gain1_mode0, 0x00}, + {&qserdes_com_reg_layout->com_integloop_gain0_mode0, 0x3f}, + {&qserdes_com_reg_layout->com_vco_tune2_mode0, 0x01}, + {&qserdes_com_reg_layout->com_vco_tune1_mode0, 0xc9}, + {&qserdes_com_reg_layout->com_coreclk_div_mode0, 0x0a}, + {&qserdes_com_reg_layout->com_lock_cmp3_mode0, 0x00}, + {&qserdes_com_reg_layout->com_lock_cmp2_mode0, 0x34}, + {&qserdes_com_reg_layout->com_lock_cmp1_mode0, 0x15}, + {&qserdes_com_reg_layout->com_lock_cmp_en, 0x04}, + {&qserdes_com_reg_layout->com_core_clk_en, 0x00}, + {&qserdes_com_reg_layout->com_lock_cmp_cfg, 0x00}, + {&qserdes_com_reg_layout->com_vco_tune_map, 0x00}, + {&qserdes_com_reg_layout->com_sysclk_buf_enable, 0x0a}, + {&qserdes_com_reg_layout->com_ssc_en_center, 0x01}, + {&qserdes_com_reg_layout->com_ssc_per1, 0x31}, + {&qserdes_com_reg_layout->com_ssc_per2, 0x01}, + {&qserdes_com_reg_layout->com_ssc_adj_per1, 0x00}, + {&qserdes_com_reg_layout->com_ssc_adj_per2, 0x00}, + {&qserdes_com_reg_layout->com_ssc_step_size1, 0x85}, + {&qserdes_com_reg_layout->com_ssc_step_size2, 0x07}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_tx_tbl[] = { + {&qserdes_tx_reg_layout->tx_highz_drvr_en, 0x10}, + {&qserdes_tx_reg_layout->tx_rcv_detect_lvl_2, 0x12}, + {&qserdes_tx_reg_layout->tx_lane_mode_1, 0x16}, + {&qserdes_tx_reg_layout->tx_res_code_lane_offset_rx, 0x09}, + {&qserdes_tx_reg_layout->tx_res_code_lane_offset_tx, 0x06}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_rx_tbl[] = { + {&qserdes_rx_reg_layout->rx_ucdr_fastlock_fo_gain, 0x0b}, + {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl2, 0x0f}, + {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl3, 0x4e}, + {&qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl4, 0x18}, + {&qserdes_rx_reg_layout->rx_rx_eq_offset_adap_ctrl1, 0x77}, + {&qserdes_rx_reg_layout->rx_rx_offset_adap_ctrl2, 0x80}, + {&qserdes_rx_reg_layout->rx_sigdet_ctrl, 0x03}, + {&qserdes_rx_reg_layout->rx_sigdet_deglitch_ctrl, 0x16}, + {&qserdes_rx_reg_layout->rx_ucdr_so_saturtn_and_en, 0x75}, + {&qserdes_rx_reg_layout->rx_ucdr_pi_cntrls, 0x80}, + {&qserdes_rx_reg_layout->rx_ucdr_fo_gain, 0x0a}, + {&qserdes_rx_reg_layout->rx_ucdr_so_gain_half, 0x06}, + {&qserdes_rx_reg_layout->rx_sigdet_enables, 0x00}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_pcs_tbl[] = { + /* FLL settings */ + {&pcs_reg_layout->pcs_fll_ctrl2, 0x83}, + {&pcs_reg_layout->pcs_fll_cnt_val_l, 0x09}, + {&pcs_reg_layout->pcs_fll_cnt_val_h_tol, 0xa2}, + {&pcs_reg_layout->pcs_fll_man_code, 0x40}, + {&pcs_reg_layout->pcs_fll_ctrl1, 0x02}, + + /* Lock Det settings */ + {&pcs_reg_layout->pcs_lock_detect_config1, 0xd1}, + {&pcs_reg_layout->pcs_lock_detect_config2, 0x1f}, + {&pcs_reg_layout->pcs_lock_detect_config3, 0x47}, + {&pcs_reg_layout->pcs_power_state_config2, 0x1b}, + + {&pcs_reg_layout->pcs_rx_sigdet_lvl, 0xba}, + {&pcs_reg_layout->pcs_txmgn_v0, 0x9f}, + {&pcs_reg_layout->pcs_txmgn_v1, 0x9f}, + {&pcs_reg_layout->pcs_txmgn_v2, 0xb7}, + {&pcs_reg_layout->pcs_txmgn_v3, 0x4e}, + {&pcs_reg_layout->pcs_txmgn_v4, 0x65}, + {&pcs_reg_layout->pcs_txmgn_ls, 0x6b}, + {&pcs_reg_layout->pcs_txdeemph_m6db_v0, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_v0, 0x0d}, + {&pcs_reg_layout->pcs_txdeemph_m6db_v1, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_v1, 0x0d}, + {&pcs_reg_layout->pcs_txdeemph_m6db_v2, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_v2, 0x0d}, + {&pcs_reg_layout->pcs_txdeemph_m6db_v3, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_v3, 0x1d}, + {&pcs_reg_layout->pcs_txdeemph_m6db_v4, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_v4, 0x0d}, + {&pcs_reg_layout->pcs_txdeemph_m6db_ls, 0x15}, + {&pcs_reg_layout->pcs_txdeemph_m3p5db_ls, 0x0d}, + {&pcs_reg_layout->pcs_rate_slew_cntrl, 0x02}, + {&pcs_reg_layout->pcs_pwrup_reset_dly_time_auxclk, 0x04}, + {&pcs_reg_layout->pcs_tsync_rsync_time, 0x44}, + {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_l, 0xe7}, + {&pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_h, 0x03}, + {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_l, 0x40}, + {&pcs_reg_layout->pcs_rcvr_dtct_dly_u3_h, 0x00}, + {&pcs_reg_layout->pcs_rxeqtraining_wait_time, 0x75}, + {&pcs_reg_layout->pcs_lfps_ecstart_eqtlock, 0x86}, + {&pcs_reg_layout->pcs_rxeqtraining_run_time, 0x13}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_serdes_tbl[] = { + {&uniphy_qserdes_com_reg_layout->com_pll_ivco, 0x07}, + {&uniphy_qserdes_com_reg_layout->com_sysclk_en_sel, 0x14}, + {&uniphy_qserdes_com_reg_layout->com_bias_en_clkbuflr_en, 0x04}, + {&uniphy_qserdes_com_reg_layout->com_clk_select, 0x30}, + {&uniphy_qserdes_com_reg_layout->com_sys_clk_ctrl, 0x02}, + {&uniphy_qserdes_com_reg_layout->com_resetsm_ctrl2, 0x08}, + {&uniphy_qserdes_com_reg_layout->com_cmn_config, 0x06}, + {&uniphy_qserdes_com_reg_layout->com_svs_mode_clk_sel, 0x01}, + {&uniphy_qserdes_com_reg_layout->com_hsclk_sel, 0x80}, + {&uniphy_qserdes_com_reg_layout->com_dec_start_mode0, 0x82}, + {&uniphy_qserdes_com_reg_layout->com_div_frac_start1_mode0, 0xab}, + {&uniphy_qserdes_com_reg_layout->com_div_frac_start2_mode0, 0xea}, + {&uniphy_qserdes_com_reg_layout->com_div_frac_start3_mode0, 0x02}, + {&uniphy_qserdes_com_reg_layout->com_cp_ctrl_mode0, 0x06}, + {&uniphy_qserdes_com_reg_layout->com_pll_rctrl_mode0, 0x16}, + {&uniphy_qserdes_com_reg_layout->com_pll_cctrl_mode0, 0x36}, + {&uniphy_qserdes_com_reg_layout->com_integloop_gain1_mode0, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_integloop_gain0_mode0, 0x3f}, + {&uniphy_qserdes_com_reg_layout->com_vco_tune2_mode0, 0x01}, + {&uniphy_qserdes_com_reg_layout->com_vco_tune1_mode0, 0xc9}, + {&uniphy_qserdes_com_reg_layout->com_coreclk_div_mode0, 0x0a}, + {&uniphy_qserdes_com_reg_layout->com_lock_cmp3_mode0, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_lock_cmp2_mode0, 0x34}, + {&uniphy_qserdes_com_reg_layout->com_lock_cmp1_mode0, 0x15}, + {&uniphy_qserdes_com_reg_layout->com_lock_cmp_en, 0x04}, + {&uniphy_qserdes_com_reg_layout->com_core_clk_en, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_lock_cmp_cfg, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_vco_tune_map, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_sysclk_buf_enable, 0x0a}, + {&uniphy_qserdes_com_reg_layout->com_ssc_en_center, 0x01}, + {&uniphy_qserdes_com_reg_layout->com_ssc_per1, 0x31}, + {&uniphy_qserdes_com_reg_layout->com_ssc_per2, 0x01}, + {&uniphy_qserdes_com_reg_layout->com_ssc_adj_per1, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_ssc_adj_per2, 0x00}, + {&uniphy_qserdes_com_reg_layout->com_ssc_step_size1, 0x85}, + {&uniphy_qserdes_com_reg_layout->com_ssc_step_size2, 0x07}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_tx_tbl[] = { + {&uniphy_qserdes_tx_reg_layout->tx_highz_drvr_en, 0x10}, + {&uniphy_qserdes_tx_reg_layout->tx_rcv_detect_lvl_2, 0x12}, + {&uniphy_qserdes_tx_reg_layout->tx_lane_mode_1, 0xc6}, + {&uniphy_qserdes_tx_reg_layout->tx_res_code_lane_offset_rx, 0x06}, + {&uniphy_qserdes_tx_reg_layout->tx_res_code_lane_offset_tx, 0x06}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_rx_tbl[] = { + {&uniphy_qserdes_rx_reg_layout->rx_vga_cal_ctrl2, 0x0c}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_mode_00, 0x50}, + {&uniphy_qserdes_rx_reg_layout->rx_ucdr_fastlock_fo_gain, 0x0b}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl2, 0x0e}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl3, 0x4e}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_equ_adap_ctrl4, 0x18}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_eq_offset_adap_ctrl1, 0x77}, + {&uniphy_qserdes_rx_reg_layout->rx_rx_offset_adap_ctrl2, 0x80}, + {&uniphy_qserdes_rx_reg_layout->rx_sigdet_ctrl, 0x03}, + {&uniphy_qserdes_rx_reg_layout->rx_sigdet_deglitch_ctrl, 0x1c}, + {&uniphy_qserdes_rx_reg_layout->rx_ucdr_so_saturtn_and_en, 0x75}, + {&uniphy_qserdes_rx_reg_layout->rx_ucdr_pi_cntrls, 0x80}, + {&uniphy_qserdes_rx_reg_layout->rx_ucdr_fo_gain, 0x0a}, + {&uniphy_qserdes_rx_reg_layout->rx_ucdr_so_gain_half, 0x06}, + {&uniphy_qserdes_rx_reg_layout->rx_sigdet_enables, 0x00}, +}; + +static const struct qmp_phy_init_tbl qmp_v3_usb3_uniphy_pcs_tbl[] = { + /* FLL settings */ + {&uniphy_pcs_reg_layout->pcs_fll_ctrl2, 0x83}, + {&uniphy_pcs_reg_layout->pcs_fll_cnt_val_l, 0x09}, + {&uniphy_pcs_reg_layout->pcs_fll_cnt_val_h_tol, 0xa2}, + {&uniphy_pcs_reg_layout->pcs_fll_man_code, 0x40}, + {&uniphy_pcs_reg_layout->pcs_fll_ctrl1, 0x02}, + + /* Lock Det settings */ + {&uniphy_pcs_reg_layout->pcs_lock_detect_config1, 0xd1}, + {&uniphy_pcs_reg_layout->pcs_lock_detect_config2, 0x1f}, + {&uniphy_pcs_reg_layout->pcs_lock_detect_config3, 0x47}, + {&uniphy_pcs_reg_layout->pcs_power_state_config2, 0x1b}, + + {&uniphy_pcs_reg_layout->pcs_rx_sigdet_lvl, 0xba}, + {&uniphy_pcs_reg_layout->pcs_txmgn_v0, 0x9f}, + {&uniphy_pcs_reg_layout->pcs_txmgn_v1, 0x9f}, + {&uniphy_pcs_reg_layout->pcs_txmgn_v2, 0xb5}, + {&uniphy_pcs_reg_layout->pcs_txmgn_v3, 0x4c}, + {&uniphy_pcs_reg_layout->pcs_txmgn_v4, 0x64}, + {&uniphy_pcs_reg_layout->pcs_txmgn_ls, 0x6a}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_v0, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_v0, 0x0d}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_v1, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_v1, 0x0d}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_v2, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_v2, 0x0d}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_v3, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_v3, 0x1d}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_v4, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_v4, 0x0d}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m6db_ls, 0x15}, + {&uniphy_pcs_reg_layout->pcs_txdeemph_m3p5db_ls, 0x0d}, + {&uniphy_pcs_reg_layout->pcs_rate_slew_cntrl, 0x02}, + {&uniphy_pcs_reg_layout->pcs_pwrup_reset_dly_time_auxclk, 0x04}, + {&uniphy_pcs_reg_layout->pcs_tsync_rsync_time, 0x44}, + {&uniphy_pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_l, 0xe7}, + {&uniphy_pcs_reg_layout->pcs_rcvr_dtct_dly_p1u2_h, 0x03}, + {&uniphy_pcs_reg_layout->pcs_rcvr_dtct_dly_u3_l, 0x40}, + {&uniphy_pcs_reg_layout->pcs_rcvr_dtct_dly_u3_h, 0x00}, + {&uniphy_pcs_reg_layout->pcs_rxeqtraining_wait_time, 0x75}, + {&uniphy_pcs_reg_layout->pcs_lfps_ecstart_eqtlock, 0x86}, + {&uniphy_pcs_reg_layout->pcs_rxeqtraining_run_time, 0x13}, + {&uniphy_pcs_reg_layout->pcs_refgen_req_config1, 0x21}, + {&uniphy_pcs_reg_layout->pcs_refgen_req_config2, 0x60}, +}; + +struct usb_dwc3_cfg { + struct usb_dwc3 *usb_host_dwc3; + struct usb_qusb_phy_pll *qusb_phy_pll; + struct usb_qusb_phy_dig *qusb_phy_dig; + /* Init sequence for QMP PHY blocks - serdes, tx, rx, pcs */ + const struct qmp_phy_init_tbl *serdes_tbl; + int serdes_tbl_num; + const struct qmp_phy_init_tbl *tx_tbl; + int tx_tbl_num; + const struct qmp_phy_init_tbl *rx_tbl; + int rx_tbl_num; + const struct qmp_phy_init_tbl *pcs_tbl; + int pcs_tbl_num; + struct usb3_phy_pcs_reg_layout *qmp_pcs_reg; + + u32 *usb3_bcr; + u32 *qusb2phy_bcr; + u32 *gcc_usb3phy_bcr_reg; + u32 *gcc_qmpphy_bcr_reg; + struct usb_board_data *board_data; + u32 efuse_offset; +}; + +static struct usb_dwc3_cfg usb_port0 = { + .usb_host_dwc3 = (void *)USB_HOST0_DWC3_BASE, + .qusb_phy_pll = (void *)QUSB_PRIM_PHY_BASE, + .qusb_phy_dig = (void *)QUSB_PRIM_PHY_DIG_BASE, + .serdes_tbl = qmp_v3_usb3_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_serdes_tbl), + .tx_tbl = qmp_v3_usb3_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_tx_tbl), + .rx_tbl = qmp_v3_usb3_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_rx_tbl), + .pcs_tbl = qmp_v3_usb3_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_pcs_tbl), + .qmp_pcs_reg = (void *)QMP_PHY_PCS_REG_BASE, + .usb3_bcr = &gcc->usb30_prim_bcr, + .qusb2phy_bcr = &gcc->qusb2phy_prim_bcr, + .gcc_usb3phy_bcr_reg = &gcc->usb3_dp_phy_prim_bcr, + .gcc_qmpphy_bcr_reg = &gcc->usb3_phy_prim_bcr, + .efuse_offset = 25, +}; +static struct usb_dwc3_cfg usb_port1 = { + .usb_host_dwc3 = (void *)USB_HOST1_DWC3_BASE, + .qusb_phy_pll = (void *)QUSB_SEC_PHY_BASE, + .qusb_phy_dig = (void *)QUSB_SEC_PHY_DIG_BASE, + .serdes_tbl = qmp_v3_usb3_uniphy_serdes_tbl, + .serdes_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_serdes_tbl), + .tx_tbl = qmp_v3_usb3_uniphy_tx_tbl, + .tx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_tx_tbl), + .rx_tbl = qmp_v3_usb3_uniphy_rx_tbl, + .rx_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_rx_tbl), + .pcs_tbl = qmp_v3_usb3_uniphy_pcs_tbl, + .pcs_tbl_num = ARRAY_SIZE(qmp_v3_usb3_uniphy_pcs_tbl), + .qmp_pcs_reg = (void *)QMP_UNIPHY_PCS_REG_BASE, + .usb3_bcr = &gcc->usb30_sec_bcr, + .qusb2phy_bcr = &gcc->qusb2phy_sec_bcr, + .gcc_usb3phy_bcr_reg = &gcc->usb3phy_phy_sec_bcr, + .gcc_qmpphy_bcr_reg = &gcc->usb3_phy_sec_bcr, + .efuse_offset = 30, +}; + +static struct qfprom_corr * const qfprom_corr_efuse = (void *)QFPROM_BASE; + +static void reset_usb(struct usb_dwc3_cfg *dwc3) +{ + /* Assert Core reset */ + clock_reset_bcr(dwc3->usb3_bcr, 1); + + /* Assert QUSB PHY reset */ + clock_reset_bcr(dwc3->qusb2phy_bcr, 1); + + /* Assert QMP PHY reset */ + clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 1); + clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 1); +} + +void reset_usb0(void) +{ + /* Before Resetting PHY, put Core in Reset */ + printk(BIOS_INFO, "Starting DWC3 and PHY resets for USB(0)\n"); + + reset_usb(&usb_port0); +} + +void reset_usb1(void) +{ + /* Before Resetting PHY, put Core in Reset */ + printk(BIOS_INFO, "Starting DWC3 and PHY resets for USB(1)\n"); + + reset_usb(&usb_port1); +} +/* + * Update board specific PHY tuning override values that specified from + * board file. + */ +static void qusb2_phy_override_phy_params(struct usb_dwc3_cfg *dwc3) +{ + /* Override preemphasis value */ + write32(&dwc3->qusb_phy_dig->tune1, + dwc3->board_data->port_tune1); + + /* Override BIAS_CTRL_2 to reduce the TX swing overshooting. */ + write32(&dwc3->qusb_phy_pll->bias_ctrl_2, + dwc3->board_data->pll_bias_control_2); + + /* Override IMP_RES_OFFSET value */ + write32(&dwc3->qusb_phy_dig->imp_ctrl1, + dwc3->board_data->imp_ctrl1); +} + +/* + * Fetches HS Tx tuning value from efuse register and sets the + * QUSB2PHY_PORT_TUNE1/2 register. + * For error case, skip setting the value and use the default value. + */ +static void qusb2_phy_set_tune_param(struct usb_dwc3_cfg *dwc3) +{ + /* + * Efuse registers 4 bit value specifies tuning for HSTX + * output current in TUNE1 Register. Hence Extract 4 bits from + * EFUSE at correct position. + */ + + const int efuse_bits = 4; + int bit_pos = dwc3->efuse_offset; + + u32 bit_mask = (1 << efuse_bits) - 1; + u32 tune_val = + (read32(&qfprom_corr_efuse->qusb_hstx_trim_lsb) >> bit_pos) + & bit_mask; + + if (bit_pos + efuse_bits > 32) { + /* + * Value split between two EFUSE registers, + * get the second part. + */ + int done_bits = 32 - bit_pos; + + bit_mask = (1 << (efuse_bits - done_bits)) - 1; + tune_val |= + (read32(&qfprom_corr_efuse->qusb_hstx_trim_msb) & + bit_mask) << done_bits; + } + + /* + * if efuse reg is updated (i.e non-zero) then use it to program + * tune parameters. + */ + if (tune_val) + clrsetbits_le32(&dwc3->qusb_phy_dig->tune1, + PORT_TUNE1_MASK, tune_val << 4); +} + +static void tune_phy(struct usb_dwc3_cfg *dwc3, struct usb_qusb_phy_dig *phy) +{ + write32(&phy->pwr_ctrl2, QUSB2PHY_PWR_CTRL2); + /* IMP_CTRL1: Control the impedance reduction */ + write32(&phy->imp_ctrl1, QUSB2PHY_IMP_CTRL1); + /* IMP_CTRL2: Impedance offset/mapping slope */ + write32(&phy->imp_ctrl2, QUSB2PHY_IMP_CTRL1); + write32(&phy->chg_ctrl2, QUSB2PHY_IMP_CTRL2); + /* + * TUNE1: Sets HS Impedance to approx 45 ohms + * then override with efuse value. + */ + write32(&phy->tune1, QUSB2PHY_PORT_TUNE1); + /* TUNE2: Tuning for HS Disconnect Level */ + write32(&phy->tune2, QUSB2PHY_PORT_TUNE2); + /* TUNE3: Tune squelch range */ + write32(&phy->tune3, QUSB2PHY_PORT_TUNE3); + /* TUNE4: Sets EOP_DLY(Squelch rising edge to linestate falling edge) */ + write32(&phy->tune4, QUSB2PHY_PORT_TUNE4); + write32(&phy->tune5, QUSB2PHY_PORT_TUNE5); + + if (dwc3->board_data) { + /* Override board specific PHY tuning values */ + qusb2_phy_override_phy_params(dwc3); + + /* Set efuse value for tuning the PHY */ + qusb2_phy_set_tune_param(dwc3); + } +} + +static void hs_qusb_phy_init(struct usb_dwc3_cfg *dwc3) +{ + /* PWR_CTRL: set the power down bit to disable the PHY */ + setbits_le32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN); + + write32(&dwc3->qusb_phy_pll->analog_controls_two, + QUSB2PHY_PLL_ANALOG_CONTROLS_TWO); + write32(&dwc3->qusb_phy_pll->clock_inverters, + QUSB2PHY_PLL_CLOCK_INVERTERS); + write32(&dwc3->qusb_phy_pll->cmode, + QUSB2PHY_PLL_CMODE); + write32(&dwc3->qusb_phy_pll->lock_delay, + QUSB2PHY_PLL_LOCK_DELAY); + write32(&dwc3->qusb_phy_pll->dig_tim, + QUSB2PHY_PLL_DIGITAL_TIMERS_TWO); + write32(&dwc3->qusb_phy_pll->bias_ctrl_1, + QUSB2PHY_PLL_BIAS_CONTROL_1); + write32(&dwc3->qusb_phy_pll->bias_ctrl_2, + QUSB2PHY_PLL_BIAS_CONTROL_2); + + tune_phy(dwc3, dwc3->qusb_phy_dig); + + /* PWR_CTRL1: Clear the power down bit to enable the PHY */ + clrbits_le32(&dwc3->qusb_phy_dig->pwr_ctrl1, POWER_DOWN); + + write32(&dwc3->qusb_phy_dig->debug_ctrl2, + DEBUG_CTRL2_MUX_PLL_LOCK_STATUS); + + /* + * DEBUG_STAT5: wait for 160uS for PLL lock; + * vstatus[0] changes from 0 to 1. + */ + long lock_us = wait_us(160, read32(&dwc3->qusb_phy_dig->debug_stat5) & + VSTATUS_PLL_LOCK_STATUS_MASK); + if (!lock_us) + printk(BIOS_ERR, "ERROR: QUSB PHY PLL LOCK fails\n"); + else + printk(BIOS_DEBUG, "QUSB PHY initialized and locked in %ldus\n", + lock_us); +} + +static void qcom_qmp_phy_configure(const struct qmp_phy_init_tbl tbl[], + int num) +{ + int i; + const struct qmp_phy_init_tbl *t = tbl; + + if (!t) + return; + + for (i = 0; i < num; i++, t++) + write32(t->address, t->val); +} + +static void ss_qmp_phy_init(struct usb_dwc3_cfg *dwc3) +{ + /* power up USB3 PHY */ + write32(&dwc3->qmp_pcs_reg->pcs_power_down_control, 0x01); + + /* Serdes configuration */ + qcom_qmp_phy_configure(dwc3->serdes_tbl, dwc3->serdes_tbl_num); + /* Tx, Rx, and PCS configurations */ + qcom_qmp_phy_configure(dwc3->tx_tbl, dwc3->tx_tbl_num); + qcom_qmp_phy_configure(dwc3->rx_tbl, dwc3->rx_tbl_num); + qcom_qmp_phy_configure(dwc3->pcs_tbl, dwc3->pcs_tbl_num); + + /* perform software reset of PCS/Serdes */ + write32(&dwc3->qmp_pcs_reg->pcs_sw_reset, 0x00); + /* start PCS/Serdes to operation mode */ + write32(&dwc3->qmp_pcs_reg->pcs_start_control, 0x03); + + /* + * Wait for PHY initialization to be done + * PCS_STATUS: wait for 1ms for PHY STATUS; + * SW can continuously check for PHYSTATUS = 1.b0. + */ + long lock_us = wait_us(1000, + !(read32(&dwc3->qmp_pcs_reg->pcs_ready_status) & + USB3_PCS_PHYSTATUS)); + if (!lock_us) + printk(BIOS_ERR, "ERROR: QMP PHY PLL LOCK fails:\n"); + else + printk(BIOS_DEBUG, "QMP PHY initialized and locked in %ldus\n", + lock_us); +} + +static void setup_dwc3(struct usb_dwc3 *dwc3) +{ + /* core exits U1/U2/U3 only in PHY power state P1/P2/P3 respectively */ + clrsetbits_le32(&dwc3->usb3pipectl, + DWC3_GUSB3PIPECTL_DELAYP1TRANS, + DWC3_GUSB3PIPECTL_UX_EXIT_IN_PX); + + /* + * Configure USB phy interface of DWC3 core. + * 1. Select UTMI+ PHY with 16-bit interface. + * 2. Set USBTRDTIM to the corresponding value + * according to the UTMI+ PHY interface. + */ + clrsetbits_le32(&dwc3->usb2phycfg, + (DWC3_GUSB2PHYCFG_USB2TRDTIM_MASK | + DWC3_GUSB2PHYCFG_PHYIF_MASK), + (DWC3_GUSB2PHYCFG_PHYIF(UTMI_PHYIF_8_BIT) | + DWC3_GUSB2PHYCFG_USBTRDTIM(USBTRDTIM_UTMI_8_BIT))); + + clrsetbits_le32(&dwc3->ctl, (DWC3_GCTL_SCALEDOWN_MASK | + DWC3_GCTL_DISSCRAMBLE), + DWC3_GCTL_U2EXIT_LFPS | DWC3_GCTL_DSBLCLKGTNG); + + /* configure controller in Host mode */ + clrsetbits_le32(&dwc3->ctl, (DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG)), + DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_HOST)); + printk(BIOS_SPEW, "Configure USB in Host mode\n"); +} + +/* Initialization of DWC3 Core and PHY */ +static void setup_usb_host(struct usb_dwc3_cfg *dwc3, + struct usb_board_data *board_data) +{ + dwc3->board_data = board_data; + + /* Clear core reset. */ + clock_reset_bcr(dwc3->usb3_bcr, 0); + + /* Clear QUSB PHY reset. */ + clock_reset_bcr(dwc3->qusb2phy_bcr, 0); + + /* Initialize QUSB PHY */ + hs_qusb_phy_init(dwc3); + + /* Clear QMP PHY resets. */ + clock_reset_bcr(dwc3->gcc_usb3phy_bcr_reg, 0); + clock_reset_bcr(dwc3->gcc_qmpphy_bcr_reg, 0); + + /* Initialize QMP PHY */ + ss_qmp_phy_init(dwc3); + + setup_dwc3(dwc3->usb_host_dwc3); + + printk(BIOS_INFO, "DWC3 and PHY setup finished\n"); +} + +void setup_usb_host0(struct usb_board_data *board_data) +{ + printk(BIOS_INFO, "Setting up USB HOST0 controller.\n"); + setup_usb_host(&usb_port0, board_data); +} + +void setup_usb_host1(struct usb_board_data *board_data) +{ + printk(BIOS_INFO, "Setting up USB HOST1 controller.\n"); + setup_usb_host(&usb_port1, board_data); +} From 82d73e2d5a44bee097d02d41a450f5bfd703bd5b Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Tue, 30 Apr 2019 13:13:40 +0800 Subject: [PATCH 149/588] nb/intel/haswell: correct a typo in Kconfig Change-Id: I115e065ce11946b85571e7233203be68c1789d70 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32518 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner Reviewed-by: Angel Pons --- src/northbridge/intel/haswell/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/haswell/Kconfig b/src/northbridge/intel/haswell/Kconfig index 8c1e0b18f7d..e1067c59494 100644 --- a/src/northbridge/intel/haswell/Kconfig +++ b/src/northbridge/intel/haswell/Kconfig @@ -37,7 +37,7 @@ config HASWELL_VBOOT_IN_BOOTBLOCK Haswell can either start verstage in a separate stage right after the bootblock has run or it can start it after romstage for compatibility reasons. - Haswell however uses a mrc.bin to initialse memory which + Haswell however uses a mrc.bin to initialize memory which needs to be located at a fixed offset. Therefore even with a separate verstage starting after the bootblock that same binary is used meaning a jump is made from RW to the RO region From aa0929d101ddfb9e64d8febd2bd31ce1037e62ff Mon Sep 17 00:00:00 2001 From: Gaggery Tsai Date: Tue, 8 Jan 2019 15:13:25 -0800 Subject: [PATCH 150/588] mb/google/poppy/variant/atlas: enable USB acpi Main objective for this change is to export the bluetooth reset gpio to the kernel for use in an rf-kill operation. To do so, we enable USB acpi and define all of the USB2 devices, which includes bluetooth's reset gpio information. BUG=b:122540489 BRANCH=None TEST=emerge-atlas coreboot chromeos-bootimage $cat sys/firmware/acpi/tables/SSDT > /tmp/ssdt.dat & retrieve ssdt.dat from DUT & $iasl -d ./ssdt.dat & check the HS03 node is with "reset-gpio" under _DSD object Change-Id: I411ef707782655361bd1b8ac2b914b8ae64defeb Signed-off-by: Gaggery Tsai Reviewed-on: https://review.coreboot.org/c/coreboot/+/30754 Tested-by: build bot (Jenkins) Reviewed-by: Nick Vaccaro Reviewed-by: Paul Menzel Reviewed-by: Caveh Jalali --- src/mainboard/google/poppy/Kconfig | 1 + .../google/poppy/variants/atlas/devicetree.cb | 25 ++++++++++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/poppy/Kconfig b/src/mainboard/google/poppy/Kconfig index 419b10eb3d2..b7f479f888d 100644 --- a/src/mainboard/google/poppy/Kconfig +++ b/src/mainboard/google/poppy/Kconfig @@ -151,6 +151,7 @@ config VARIANT_SPECIFIC_OPTIONS_ATLAS select DRIVERS_I2C_MAX98373 select DRIVERS_I2C_DA7219 select DRIVERS_SPI_ACPI + select DRIVERS_USB_ACPI select EXCLUDE_NATIVE_SD_INTERFACE select MAINBOARD_HAS_SPI_TPM_CR50 select VARIANT_HAS_CAMERA_ACPI diff --git a/src/mainboard/google/poppy/variants/atlas/devicetree.cb b/src/mainboard/google/poppy/variants/atlas/devicetree.cb index ad79bcab0e2..1ea28a0e5f4 100644 --- a/src/mainboard/google/poppy/variants/atlas/devicetree.cb +++ b/src/mainboard/google/poppy/variants/atlas/devicetree.cb @@ -265,7 +265,30 @@ chip soc/intel/skylake device pci 00.0 on end # Host Bridge device pci 02.0 on end # Integrated Graphics Device device pci 13.0 off end # Integrated Sensor Hub - device pci 14.0 on end # USB xHCI + device pci 14.0 on + chip drivers/usb/acpi + register "desc" = ""Root Hub"" + register "type" = "UPC_TYPE_HUB" + device usb 0.0 on + chip drivers/usb/acpi + register "desc" = ""USB Type C Port 1"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device usb 2.0 on end + end + chip drivers/usb/acpi + register "desc" = ""Bluetooth"" + register "type" = "UPC_TYPE_INTERNAL" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E2)" + device usb 2.2 on end + end + chip drivers/usb/acpi + register "desc" = ""USB Type C Port 2"" + register "type" = "UPC_TYPE_C_USB2_SS_SWITCH" + device usb 2.4 on end + end + end + end + end # USB xHCI device pci 14.1 on end # USB xDCI (OTG) device pci 14.2 on end # Thermal Subsystem device pci 15.0 on From b242de5bfc99ef2b63d21a9d1bd9f19bf79ee687 Mon Sep 17 00:00:00 2001 From: Nathan_chen Date: Tue, 30 Apr 2019 16:11:35 +0800 Subject: [PATCH 151/588] mb/google/arcada: Add settings for noise mitgation Enable acoustic noise mitgation for arcada platform, the slow slew rates for Ia and Gt are fast time dived by 8. BUG=b:131144464 TEST=waveform test and hardware validation result pass. Signed-off-by: nathan chen Change-Id: I395b2fc527705ab207325cfd7147e6af5f300fce Reviewed-on: https://review.coreboot.org/c/coreboot/+/32521 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index cf64c4bb896..77bd82a64b6 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -37,10 +37,10 @@ chip soc/intel/cannonlake register "tdp_pl2_override" = "51" register "Device4Enable" = "1" register "AcousticNoiseMitigation" = "1" - register "SlowSlewRateForIa" = "0" - register "SlowSlewRateForGt" = "0" + register "SlowSlewRateForIa" = "2" + register "SlowSlewRateForGt" = "2" register "SlowSlewRateForSa" = "0" - register "SlowSlewRateForFivr" = "0" + register "SlowSlewRateForFivr" = "2" # Enable eDP device register "DdiPortEdp" = "1" # Enable HPD for DDI ports B/C From 8c99a4859e7830fd1cac0b729fc29412cd773b75 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 3 May 2019 10:49:51 -0500 Subject: [PATCH 152/588] Makefile.inc: Update fsp submodule for all FSP platforms Rather than selectively update the fsp submodule based on FSP version or platform selection, update it when building for any FSP-enabled platform, so all have latest version available. Change-Id: If07d55828a1863623e04a4ecdd1514c3cb6d9c11 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32526 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- Makefile.inc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Makefile.inc b/Makefile.inc index fc04a16fadf..a9aaaed783b 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -196,15 +196,12 @@ ifeq ($(CONFIG_USE_BLOBS),y) # this is necessary because 3rdparty/blobs is update=none, and so is ignored # unless explicitly requested and enabled through --checkout forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/blobs)) -ifeq ($(CONFIG_PLATFORM_USES_FSP2_0),y) -forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/fsp)) -endif -ifeq ($(CONFIG_PLATFORM_USES_FSP1_0),y) -ifeq ($(CONFIG_SOC_INTEL_FSP_BROADWELL_DE),y) +ifeq ($(CONFIG_PLATFORM_USES_FSP1_0)$(CONFIG_PLATFORM_USES_FSP1_1)$(CONFIG_PLATFORM_USES_FSP2_0),y) +# this is necessary because 3rdparty/fsp is update=none, and so is ignored +# unless explicitly requested and enabled through --checkout forgetthis:=$(if $(GIT),$(shell git submodule update --init --checkout 3rdparty/fsp)) endif endif -endif UPDATED_SUBMODULES:=1 COREBOOT_EXPORTS += UPDATED_SUBMODULES endif From fd7440d23126a0133e2563849fceec55a772de80 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 23 Apr 2019 12:21:17 -0500 Subject: [PATCH 153/588] soc/intel/braswell: add default option to use public FSP The current Braswell FSP 1.1 header in vendorcode/intel, for which there is no publicly available FSP binary, contains silicon init UPDs which are not found in the publicly available header/binary in the FSP Github repo. This prevents new boards from being added which use the public Braswell FSP header/binary. To resolve this, move the UPDs not found in the public header from the soc's chip.c to ramstage.c for the boards which use them. Add a Kconfig option to use the current non-public FSP header and select it for boards which need it (google/cyan variants); set the public FSP option as the default. Use the Kconfig option to set FSP_HEADER_PATH to ensure the correct header is used. Test: build google/cyan and intel/strago using non-public and public FSP header/binaries respectively. Change-Id: I43cf18b98c844175a87b61fdbe4b0b24484e5702 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32381 Tested-by: build bot (Jenkins) Reviewed-by: Frans Hendriks Reviewed-by: Nico Huber --- src/mainboard/google/cyan/Kconfig | 1 + .../google/cyan/variants/celes/devicetree.cb | 6 ---- .../google/cyan/variants/celes/ramstage.c | 7 +++++ .../google/cyan/variants/kefka/Makefile.inc | 1 + .../google/cyan/variants/kefka/devicetree.cb | 7 ----- .../google/cyan/variants/kefka/ramstage.c | 30 +++++++++++++++++++ .../google/cyan/variants/relm/devicetree.cb | 7 ----- .../google/cyan/variants/relm/ramstage.c | 8 +++++ src/soc/intel/braswell/Kconfig | 14 +++++++++ src/soc/intel/braswell/Makefile.inc | 2 +- src/soc/intel/braswell/chip.c | 25 ---------------- src/soc/intel/braswell/chip.h | 5 ---- 12 files changed, 62 insertions(+), 51 deletions(-) create mode 100644 src/mainboard/google/cyan/variants/kefka/ramstage.c diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index b3c6790e57f..aac14c06c30 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -16,6 +16,7 @@ config BOARD_GOOGLE_BASEBOARD_CYAN select HAVE_ACPI_RESUME select PCIEXP_L1_SUB_STATE if !BOARD_GOOGLE_CYAN select SYSTEM_TYPE_LAPTOP + select USE_GOOGLE_FSP if BOARD_GOOGLE_BASEBOARD_CYAN diff --git a/src/mainboard/google/cyan/variants/celes/devicetree.cb b/src/mainboard/google/cyan/variants/celes/devicetree.cb index 2e708af0d6a..a1ab5108109 100644 --- a/src/mainboard/google/cyan/variants/celes/devicetree.cb +++ b/src/mainboard/google/cyan/variants/celes/devicetree.cb @@ -73,12 +73,6 @@ chip soc/intel/braswell register "ISPEnable" = "0" # Disable IUNIT register "ISPPciDevConfig" = "3" register "PcdSdDetectChk" = "0" # Disable SD card detect - # Follow Intel recommendation to set BSW D-stepping PERPORTRXISET 2 (low strength) - register "D0Usb2Port0PerPortRXISet" = "2" - register "D0Usb2Port1PerPortRXISet" = "2" - register "D0Usb2Port2PerPortRXISet" = "2" - register "D0Usb2Port3PerPortRXISet" = "2" - register "D0Usb2Port4PerPortRXISet" = "2" # LPE audio codec settings register "lpe_codec_clk_src" = "LPE_CLK_SRC_XTAL" # 19.2MHz clock diff --git a/src/mainboard/google/cyan/variants/celes/ramstage.c b/src/mainboard/google/cyan/variants/celes/ramstage.c index 88b17f5da7e..6c522a1d0ce 100644 --- a/src/mainboard/google/cyan/variants/celes/ramstage.c +++ b/src/mainboard/google/cyan/variants/celes/ramstage.c @@ -19,29 +19,36 @@ void board_silicon_USB2_override(SILICON_INIT_UPD *params) { if (SocStepping() >= SocD0) { + //Follow Intel recommendation to set + //BSW D-stepping PERPORTRXISET 2 (low strength) params->Usb2Port0PerPortPeTxiSet = 7; params->Usb2Port0PerPortTxiSet = 0; params->Usb2Port0IUsbTxEmphasisEn = 3; params->Usb2Port0PerPortTxPeHalf = 1; + params->D0Usb2Port0PerPortRXISet = 2; params->Usb2Port1PerPortPeTxiSet = 7; params->Usb2Port1PerPortTxiSet = 0; params->Usb2Port1IUsbTxEmphasisEn = 3; params->Usb2Port1PerPortTxPeHalf = 1; + params->D0Usb2Port1PerPortRXISet = 2; params->Usb2Port2PerPortPeTxiSet = 7; params->Usb2Port2PerPortTxiSet = 6; params->Usb2Port2IUsbTxEmphasisEn = 3; params->Usb2Port2PerPortTxPeHalf = 1; + params->D0Usb2Port2PerPortRXISet = 2; params->Usb2Port3PerPortPeTxiSet = 7; params->Usb2Port3PerPortTxiSet = 6; params->Usb2Port3IUsbTxEmphasisEn = 3; params->Usb2Port3PerPortTxPeHalf = 1; + params->D0Usb2Port3PerPortRXISet = 2; params->Usb2Port4PerPortPeTxiSet = 7; params->Usb2Port4PerPortTxiSet = 6; params->Usb2Port4IUsbTxEmphasisEn = 3; params->Usb2Port4PerPortTxPeHalf = 1; + params->D0Usb2Port4PerPortRXISet = 2; } } diff --git a/src/mainboard/google/cyan/variants/kefka/Makefile.inc b/src/mainboard/google/cyan/variants/kefka/Makefile.inc index 5e94e715fa6..7799e8d2b33 100644 --- a/src/mainboard/google/cyan/variants/kefka/Makefile.inc +++ b/src/mainboard/google/cyan/variants/kefka/Makefile.inc @@ -18,6 +18,7 @@ romstage-y += romstage.c romstage-y += spd_util.c ramstage-y += gpio.c +ramstage-y += ramstage.c SPD_BIN = $(obj)/spd.bin diff --git a/src/mainboard/google/cyan/variants/kefka/devicetree.cb b/src/mainboard/google/cyan/variants/kefka/devicetree.cb index 1ce056f32e4..807dbcb2fed 100644 --- a/src/mainboard/google/cyan/variants/kefka/devicetree.cb +++ b/src/mainboard/google/cyan/variants/kefka/devicetree.cb @@ -80,13 +80,6 @@ chip soc/intel/braswell register "I2C5Frequency" = "1" register "I2C6Frequency" = "1" - # Follow Intel recommendation to set BSW D-stepping PERPORTRXISET 2 (low strength) - register "D0Usb2Port0PerPortRXISet" = "2" - register "D0Usb2Port1PerPortRXISet" = "2" - register "D0Usb2Port2PerPortRXISet" = "2" - register "D0Usb2Port3PerPortRXISet" = "2" - register "D0Usb2Port4PerPortRXISet" = "2" - # LPE audio codec settings register "lpe_codec_clk_src" = "LPE_CLK_SRC_XTAL" # 19.2MHz clock diff --git a/src/mainboard/google/cyan/variants/kefka/ramstage.c b/src/mainboard/google/cyan/variants/kefka/ramstage.c new file mode 100644 index 00000000000..d790708cce5 --- /dev/null +++ b/src/mainboard/google/cyan/variants/kefka/ramstage.c @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +void board_silicon_USB2_override(SILICON_INIT_UPD *params) +{ + if (SocStepping() >= SocD0) { + + //Follow Intel recommendation to set + //BSW D-stepping PERPORTRXISET 2 (low strength) + params->D0Usb2Port0PerPortRXISet = 2; + params->D0Usb2Port1PerPortRXISet = 2; + params->D0Usb2Port2PerPortRXISet = 2; + params->D0Usb2Port3PerPortRXISet = 2; + params->D0Usb2Port4PerPortRXISet = 2; + } +} diff --git a/src/mainboard/google/cyan/variants/relm/devicetree.cb b/src/mainboard/google/cyan/variants/relm/devicetree.cb index 65e662c5dd6..e1bbb0ac5b8 100644 --- a/src/mainboard/google/cyan/variants/relm/devicetree.cb +++ b/src/mainboard/google/cyan/variants/relm/devicetree.cb @@ -80,13 +80,6 @@ chip soc/intel/braswell register "I2C5Frequency" = "1" register "I2C6Frequency" = "1" - # Follow Intel recommendation to set BSW D-stepping PERPORTRXISET 2 (low strength) - register "D0Usb2Port0PerPortRXISet" = "2" - register "D0Usb2Port1PerPortRXISet" = "2" - register "D0Usb2Port2PerPortRXISet" = "2" - register "D0Usb2Port3PerPortRXISet" = "2" - register "D0Usb2Port4PerPortRXISet" = "2" - # LPE audio codec settings register "lpe_codec_clk_src" = "LPE_CLK_SRC_XTAL" # 19.2MHz clock diff --git a/src/mainboard/google/cyan/variants/relm/ramstage.c b/src/mainboard/google/cyan/variants/relm/ramstage.c index 27f9dfa2413..3fbd2aebd96 100644 --- a/src/mainboard/google/cyan/variants/relm/ramstage.c +++ b/src/mainboard/google/cyan/variants/relm/ramstage.c @@ -36,5 +36,13 @@ void board_silicon_USB2_override(SILICON_INIT_UPD *params) params->Usb2Port3PerPortTxiSet = 0; params->Usb2Port3IUsbTxEmphasisEn = 2; params->Usb2Port3PerPortTxPeHalf = 1; + + //Follow Intel recommendation to set + //BSW D-stepping PERPORTRXISET 2 (low strength) + params->D0Usb2Port0PerPortRXISet = 2; + params->D0Usb2Port1PerPortRXISet = 2; + params->D0Usb2Port2PerPortRXISet = 2; + params->D0Usb2Port3PerPortRXISet = 2; + params->D0Usb2Port4PerPortRXISet = 2; } } diff --git a/src/soc/intel/braswell/Kconfig b/src/soc/intel/braswell/Kconfig index a0c07084b8c..ed5c9728a3e 100644 --- a/src/soc/intel/braswell/Kconfig +++ b/src/soc/intel/braswell/Kconfig @@ -135,4 +135,18 @@ config DISABLE_HPET Enable this to disable the HPET support Solves the Linux MP-BIOS bug timer not connected. +config USE_GOOGLE_FSP + bool + help + Select this to use Google's custom Braswell FSP header/binary + instead of the public release on Github. Only google/cyan + variants require this; all other boards should use the public release. + +config FSP_HEADER_PATH + string + default "$(src)/vendorcode/intel/fsp/fsp1_1/braswell" if USE_GOOGLE_FSP + default "3rdparty/fsp/BraswellFspBinPkg/Include/" + help + Location of FSP header file FspUpdVpd.h + endif diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index a538f7daff6..a7ed4c53884 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -56,7 +56,7 @@ smm-y += tsc_freq.c CPPFLAGS_common += -I$(src)/soc/intel/braswell/ CPPFLAGS_common += -I$(src)/soc/intel/braswell/include -CPPFLAGS_common += -I$(src)/vendorcode/intel/fsp/fsp1_1/braswell +CPPFLAGS_common += -I$(call strip_quotes,$(CONFIG_FSP_HEADER_PATH)) CPPFLAGS_common += -I3rdparty/blobs/mainboard/$(MAINBOARDDIR) diff --git a/src/soc/intel/braswell/chip.c b/src/soc/intel/braswell/chip.c index 4be13cdea3a..900b2f33fde 100644 --- a/src/soc/intel/braswell/chip.c +++ b/src/soc/intel/braswell/chip.c @@ -129,36 +129,26 @@ void soc_silicon_init_params(SILICON_INIT_UPD *params) params->Usb2Port0PerPortTxiSet = config->Usb2Port0PerPortTxiSet; params->Usb2Port0IUsbTxEmphasisEn = config->Usb2Port0IUsbTxEmphasisEn; params->Usb2Port0PerPortTxPeHalf = config->Usb2Port0PerPortTxPeHalf; - if (config->D0Usb2Port0PerPortRXISet != 0) - params->D0Usb2Port0PerPortRXISet = config->D0Usb2Port0PerPortRXISet; params->Usb2Port1PerPortPeTxiSet = config->Usb2Port1PerPortPeTxiSet; params->Usb2Port1PerPortTxiSet = config->Usb2Port1PerPortTxiSet; params->Usb2Port1IUsbTxEmphasisEn = config->Usb2Port1IUsbTxEmphasisEn; params->Usb2Port1PerPortTxPeHalf = config->Usb2Port1PerPortTxPeHalf; - if (config->D0Usb2Port1PerPortRXISet != 0) - params->D0Usb2Port1PerPortRXISet = config->D0Usb2Port1PerPortRXISet; params->Usb2Port2PerPortPeTxiSet = config->Usb2Port2PerPortPeTxiSet; params->Usb2Port2PerPortTxiSet = config->Usb2Port2PerPortTxiSet; params->Usb2Port2IUsbTxEmphasisEn = config->Usb2Port2IUsbTxEmphasisEn; params->Usb2Port2PerPortTxPeHalf = config->Usb2Port2PerPortTxPeHalf; - if (config->D0Usb2Port2PerPortRXISet != 0) - params->D0Usb2Port2PerPortRXISet = config->D0Usb2Port2PerPortRXISet; params->Usb2Port3PerPortPeTxiSet = config->Usb2Port3PerPortPeTxiSet; params->Usb2Port3PerPortTxiSet = config->Usb2Port3PerPortTxiSet; params->Usb2Port3IUsbTxEmphasisEn = config->Usb2Port3IUsbTxEmphasisEn; params->Usb2Port3PerPortTxPeHalf = config->Usb2Port3PerPortTxPeHalf; - if (config->D0Usb2Port3PerPortRXISet != 0) - params->D0Usb2Port3PerPortRXISet = config->D0Usb2Port3PerPortRXISet; params->Usb2Port4PerPortPeTxiSet = config->Usb2Port4PerPortPeTxiSet; params->Usb2Port4PerPortTxiSet = config->Usb2Port4PerPortTxiSet; params->Usb2Port4IUsbTxEmphasisEn = config->Usb2Port4IUsbTxEmphasisEn; params->Usb2Port4PerPortTxPeHalf = config->Usb2Port4PerPortTxPeHalf; - if (config->D0Usb2Port4PerPortRXISet != 0) - params->D0Usb2Port4PerPortRXISet = config->D0Usb2Port4PerPortRXISet; params->Usb3Lane0Ow2tapgen2deemph3p5 = config->Usb3Lane0Ow2tapgen2deemph3p5; @@ -266,9 +256,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *old, fsp_display_upd_value("Usb2Port0PerPortTxPeHalf", 1, old->Usb2Port0PerPortTxPeHalf, new->Usb2Port0PerPortTxPeHalf); - fsp_display_upd_value("D0Usb2Port0PerPortRXISet", 1, - old->D0Usb2Port0PerPortRXISet, - new->D0Usb2Port0PerPortRXISet); fsp_display_upd_value("Usb2Port1PerPortPeTxiSet", 1, old->Usb2Port1PerPortPeTxiSet, new->Usb2Port1PerPortPeTxiSet); @@ -281,9 +268,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *old, fsp_display_upd_value("Usb2Port1PerPortTxPeHalf", 1, old->Usb2Port1PerPortTxPeHalf, new->Usb2Port1PerPortTxPeHalf); - fsp_display_upd_value("D0Usb2Port1PerPortRXISet", 1, - old->D0Usb2Port1PerPortRXISet, - new->D0Usb2Port1PerPortRXISet); fsp_display_upd_value("Usb2Port2PerPortPeTxiSet", 1, old->Usb2Port2PerPortPeTxiSet, new->Usb2Port2PerPortPeTxiSet); @@ -296,9 +280,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *old, fsp_display_upd_value("Usb2Port2PerPortTxPeHalf", 1, old->Usb2Port2PerPortTxPeHalf, new->Usb2Port2PerPortTxPeHalf); - fsp_display_upd_value("D0Usb2Port2PerPortRXISet", 1, - old->D0Usb2Port2PerPortRXISet, - new->D0Usb2Port2PerPortRXISet); fsp_display_upd_value("Usb2Port3PerPortPeTxiSet", 1, old->Usb2Port3PerPortPeTxiSet, new->Usb2Port3PerPortPeTxiSet); @@ -311,9 +292,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *old, fsp_display_upd_value("Usb2Port3PerPortTxPeHalf", 1, old->Usb2Port3PerPortTxPeHalf, new->Usb2Port3PerPortTxPeHalf); - fsp_display_upd_value("D0Usb2Port3PerPortRXISet", 1, - old->D0Usb2Port3PerPortRXISet, - new->D0Usb2Port3PerPortRXISet); fsp_display_upd_value("Usb2Port4PerPortPeTxiSet", 1, old->Usb2Port4PerPortPeTxiSet, new->Usb2Port4PerPortPeTxiSet); @@ -326,9 +304,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *old, fsp_display_upd_value("Usb2Port4PerPortTxPeHalf", 1, old->Usb2Port4PerPortTxPeHalf, new->Usb2Port4PerPortTxPeHalf); - fsp_display_upd_value("D0Usb2Port4PerPortRXISet", 1, - old->D0Usb2Port4PerPortRXISet, - new->D0Usb2Port4PerPortRXISet); fsp_display_upd_value("Usb3Lane0Ow2tapgen2deemph3p5", 1, old->Usb3Lane0Ow2tapgen2deemph3p5, new->Usb3Lane0Ow2tapgen2deemph3p5); diff --git a/src/soc/intel/braswell/chip.h b/src/soc/intel/braswell/chip.h index 4afaf444174..bb06dd595a9 100644 --- a/src/soc/intel/braswell/chip.h +++ b/src/soc/intel/braswell/chip.h @@ -172,11 +172,6 @@ struct soc_intel_braswell_config { UINT8 I2C4Frequency; UINT8 I2C5Frequency; UINT8 I2C6Frequency; - UINT8 D0Usb2Port0PerPortRXISet; /*setting for D0 stepping SOC*/ - UINT8 D0Usb2Port1PerPortRXISet; /*setting for D0 stepping SOC*/ - UINT8 D0Usb2Port2PerPortRXISet; /*setting for D0 stepping SOC*/ - UINT8 D0Usb2Port3PerPortRXISet; /*setting for D0 stepping SOC*/ - UINT8 D0Usb2Port4PerPortRXISet; /*setting for D0 stepping SOC*/ }; extern struct chip_operations soc_intel_braswell_ops; From 61309e39b3c4545f47c9107a0e0ddaedef854505 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Tue, 23 Apr 2019 12:21:17 -0500 Subject: [PATCH 154/588] drivers/fsp 1.1: clean up Kconfig options Now that support has been added for using the public FSP repo for Braswell platform, clean up Kconfig options and set sane defaults when using it. The following changes have been made: - add option to use the 3rdparty/fsp repo for Braswell platform - reorder FSP 1.1 Kconfig entries for improved flow/readability - set the default path for the FSP binary based on use of FSP repo and platform - set the CBFS location for the FSP binary based on platform Change-Id: Ie2f732bf0ac4d4551908caa56360b8bb2869b4c7 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32535 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/drivers/intel/fsp1_1/Kconfig | 40 +++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/drivers/intel/fsp1_1/Kconfig b/src/drivers/intel/fsp1_1/Kconfig index 2575577ba46..a8658ec7e6b 100644 --- a/src/drivers/intel/fsp1_1/Kconfig +++ b/src/drivers/intel/fsp1_1/Kconfig @@ -25,8 +25,14 @@ if PLATFORM_USES_FSP1_1 comment "Intel FSP 1.1" +config FSP_USE_REPO + bool "Use FSP binary from 3rdparty/fsp repo" + select HAVE_FSP_BIN + depends on SOC_INTEL_BRASWELL && !USE_GOOGLE_FSP + default y + config HAVE_FSP_BIN - bool "Should the Intel FSP binary be added to the flash image" + bool "Add Intel FSP binary to flash image" help Select this option to add an Intel FSP binary to the resulting coreboot image. @@ -34,6 +40,25 @@ config HAVE_FSP_BIN Note: Without this binary, coreboot builds relying on the FSP will not boot +config FSP_FILE + string + prompt "Intel FSP binary path and filename" if !FSP_USE_REPO + depends on HAVE_FSP_BIN + default "3rdparty/fsp/BraswellFspBinPkg/FspBin/BSWFSP.fd" if FSP_USE_REPO + default "" + help + The path and filename of the Intel FSP binary for this platform. + +config FSP_LOC + hex "Intel FSP Binary location in CBFS" + default 0xfff6e000 if SOC_INTEL_BRASWELL && USE_GOOGLE_FSP + default 0xfff20000 if SOC_INTEL_BRASWELL + default 0xffee0000 if SOC_INTEL_SKYLAKE + help + The location in CBFS that the FSP is located. This must match the + value that is set in the FSP binary. If the FSP needs to be moved, + rebase the FSP with Intel's BCT (tool). + config CPU_MICROCODE_CBFS_LEN hex "Microcode update region length in bytes" default 0x0 @@ -47,19 +72,6 @@ config CPU_MICROCODE_CBFS_LOC The location (base address) in CBFS that contains the microcode update binary. -config FSP_FILE - string "Intel FSP binary path and filename" - help - The path and filename of the Intel FSP binary for this platform. - -config FSP_LOC - hex "Intel FSP Binary location in CBFS" - default 0xffee0000 - help - The location in CBFS that the FSP is located. This must match the - value that is set in the FSP binary. If the FSP needs to be moved, - rebase the FSP with Intel's BCT (tool). - config DISPLAY_HOBS bool "Display hand-off-blocks (HOBs)" default n From 101098c41a047184e3eceabca2c1baa11141f36e Mon Sep 17 00:00:00 2001 From: T Michael Turney Date: Tue, 1 May 2018 15:59:37 -0700 Subject: [PATCH 155/588] sdm845: Combine BB with QC-Sec for ROM boot TEST=build & run Change-Id: I222a56f1c9b74856a1e1ff8132bab5e041672c5d Signed-off-by: T Michael Turney Reviewed-on: https://review.coreboot.org/c/coreboot/+/25207 Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/soc/qualcomm/ipq40xx/Kconfig | 2 +- src/soc/qualcomm/ipq40xx/mbn_header.h | 2 +- src/soc/qualcomm/ipq806x/Makefile.inc | 4 +- src/soc/qualcomm/ipq806x/mbn_header.h | 2 +- util/{ipqheader => qualcomm}/createxbl.py | 33 ++- util/{ipqheader => qualcomm}/ipqheader.py | 0 util/{ipqheader => qualcomm}/mbn_tools.py | 13 +- util/{ipqheader => qualcomm}/mbncat.py | 0 util/qualcomm/qgpt.py | 234 ++++++++++++++++++++++ 9 files changed, 276 insertions(+), 14 deletions(-) rename util/{ipqheader => qualcomm}/createxbl.py (96%) rename util/{ipqheader => qualcomm}/ipqheader.py (100%) rename util/{ipqheader => qualcomm}/mbn_tools.py (99%) rename util/{ipqheader => qualcomm}/mbncat.py (100%) create mode 100755 util/qualcomm/qgpt.py diff --git a/src/soc/qualcomm/ipq40xx/Kconfig b/src/soc/qualcomm/ipq40xx/Kconfig index 72e05faf22e..90744d5285c 100644 --- a/src/soc/qualcomm/ipq40xx/Kconfig +++ b/src/soc/qualcomm/ipq40xx/Kconfig @@ -47,7 +47,7 @@ config SBL_ELF config SBL_UTIL_PATH depends on USE_BLOBS string "Path for utils to combine SBL_ELF and bootblock" - default "util/ipqheader" + default "util/qualcomm" help Path for utils to combine SBL_ELF and bootblock diff --git a/src/soc/qualcomm/ipq40xx/mbn_header.h b/src/soc/qualcomm/ipq40xx/mbn_header.h index cedcf125845..a48de1c8832 100644 --- a/src/soc/qualcomm/ipq40xx/mbn_header.h +++ b/src/soc/qualcomm/ipq40xx/mbn_header.h @@ -18,7 +18,7 @@ #include -/* QCA firmware blob header gleaned from util/ipqheader/ipqheader.py */ +/* QCA firmware blob header gleaned from util/qualcomm/ipqheader.py */ struct mbn_header { u32 mbn_type; diff --git a/src/soc/qualcomm/ipq806x/Makefile.inc b/src/soc/qualcomm/ipq806x/Makefile.inc index 8a428b2f0d2..1fd134a7b36 100644 --- a/src/soc/qualcomm/ipq806x/Makefile.inc +++ b/src/soc/qualcomm/ipq806x/Makefile.inc @@ -62,14 +62,14 @@ ifeq ($(CONFIG_USE_BLOBS),y) # Add MBN header to allow SBL3 to start coreboot bootblock $(objcbfs)/bootblock.mbn: $(objcbfs)/bootblock.raw.bin @printf " ADD MBN $(subst $(obj)/,,$(@))\n" - ./util/ipqheader/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp + ./util/qualcomm/ipqheader.py $(call loadaddr,bootblock) $< $@.tmp @mv $@.tmp $@ # Create a complete bootblock which will start up the system $(objcbfs)/bootblock.bin: $(call strip_quotes,$(CONFIG_SBL_BLOB)) \ $(objcbfs)/bootblock.mbn @printf " MBNCAT $(subst $(obj)/,,$(@))\n" - @util/ipqheader/mbncat.py -o $@.tmp $^ + @util/qualcomm/mbncat.py -o $@.tmp $^ @mv $@.tmp $@ endif diff --git a/src/soc/qualcomm/ipq806x/mbn_header.h b/src/soc/qualcomm/ipq806x/mbn_header.h index 1e6a32f732d..c7b38d3a812 100644 --- a/src/soc/qualcomm/ipq806x/mbn_header.h +++ b/src/soc/qualcomm/ipq806x/mbn_header.h @@ -18,7 +18,7 @@ #include -/* Qualcomm firmware blob header gleaned from util/ipqheader/ipqheader.py */ +/* Qualcomm firmware blob header gleaned from util/qualcomm/ipqheader.py */ struct mbn_header { u32 mbn_type; diff --git a/util/ipqheader/createxbl.py b/util/qualcomm/createxbl.py similarity index 96% rename from util/ipqheader/createxbl.py rename to util/qualcomm/createxbl.py index 1efd8bac0c0..4a218544c03 100755 --- a/util/ipqheader/createxbl.py +++ b/util/qualcomm/createxbl.py @@ -6,7 +6,7 @@ # GENERAL DESCRIPTION # Concatentates XBL segments into one ELF image # -# Copyright (c) 2016, The Linux Foundation. All rights reserved. +# Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -44,6 +44,7 @@ # # when who what, where, why # -------- --- ------------------------------------------------------ +# 03/26/18 tv Added -e to enable extended MBNV5 support # 09/04/15 et Added -x and -d to embed xbl_sec ELF # 02/11/15 ck Fixed missing elf type check in ZI OOB feature # 11/04/14 ck Updated calls to mbn_tools functions @@ -205,6 +206,11 @@ def main(): else: zi_oob_enabled = True + if options.elf_inp_xbl_sec: + is_ext_mbn_v5 = True + else: + is_ext_mbn_v5 = False + mbn_type = 'elf' header_format = 'reg' @@ -237,7 +243,8 @@ def main(): is_elf2_64_bit, is_elf_xbl_sec_64_bit, is_out_elf_64_bit, - zi_oob_enabled) + zi_oob_enabled, + is_ext_mbn_v5) # Hash the image if user did not explicitly say not to @@ -262,6 +269,7 @@ def main(): target_hash, target_hash_hd, image_header_secflag, + is_ext_mbn_v5, elf_file_name = source_elf) if rv: raise RuntimeError, "Failed to create image header for hash segment" @@ -296,7 +304,8 @@ def merge_elfs(env, is_elf2_64_bit, is_elf_xbl_sec_64_bit, is_out_elf_64_bit, - zi_oob_enabled): + zi_oob_enabled, + is_ext_mbn_v5): [elf_header1, phdr_table1] = \ mbn_tools.preprocess_elf_file(elf_in_file_name1) @@ -654,7 +663,12 @@ def merge_elfs(env, new_phdr.p_paddr = phys_virt_addr new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec) new_phdr.p_memsz = new_phdr.p_filesz - new_phdr.p_flags = 0x5 + if is_ext_mbn_v5 == True: + new_phdr.p_flags = (0x5 | + (mbn_tools.MI_PBT_XBL_SEC_SEGMENT << + mbn_tools.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT)); + else: + new_phdr.p_flags = 0x5 new_phdr.p_align = 0x1000 else: # Converting from 64 to 32 elf requires data size validation @@ -663,18 +677,23 @@ def merge_elfs(env, new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE) new_phdr.p_type = 0x1 # new_phdr.p_offset = segment_offset - new_phdr.p_flags = 0x5 + if is_ext_mbn_v5 == True: + new_phdr.p_flags = (0x5 | + (mbn_tools.MI_PBT_XBL_SEC_SEGMENT << + mbn_tools.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT)); + else: + new_phdr.p_flags = 0x5 new_phdr.p_align = 0x1000 if phys_virt_addr > 0xFFFFFFFF: if zi_oob_enabled == False or curr_phdr.p_filesz != 0: - print "ERROR: File xbl_sec VAddr or PAddr is too large for conversion." + print "ERROR: File xbl_sec VAddr or PAddr is too big for conversion." exit() new_phdr.p_vaddr = phys_virt_addr new_phdr.p_paddr = phys_virt_addr if os.path.getsize(elf_in_file_xbl_sec) > 0xFFFFFFFF: - print "ERROR: File xbl_sec Filesz is too large for conversion." + print "ERROR: File xbl_sec Filesz is too big for conversion." exit() new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec) new_phdr.p_memsz = new_phdr.p_filesz diff --git a/util/ipqheader/ipqheader.py b/util/qualcomm/ipqheader.py similarity index 100% rename from util/ipqheader/ipqheader.py rename to util/qualcomm/ipqheader.py diff --git a/util/ipqheader/mbn_tools.py b/util/qualcomm/mbn_tools.py similarity index 99% rename from util/ipqheader/mbn_tools.py rename to util/qualcomm/mbn_tools.py index c66afda7b55..12dc210cac8 100755 --- a/util/ipqheader/mbn_tools.py +++ b/util/qualcomm/mbn_tools.py @@ -6,7 +6,7 @@ # GENERAL DESCRIPTION # Contains all MBN Utilities for image generation # -# Copyright (c) 2016, The Linux Foundation. All rights reserved. +# Copyright (c) 2016, 2018, The Linux Foundation. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are @@ -41,6 +41,7 @@ # # when who what, where, why # -------- --- --------------------------------------------------------- +# 03/22/18 thiru Added support for extended MBNV5. # 06/06/13 yliong CR 497042: Signed and encrypted image is corrupted. MRC features. # 03/18/13 dhaval Add support for hashing elf segments with SHA256 and # sync up to mpss, adsp mbn-tools @@ -166,6 +167,7 @@ MI_PBT_BOOT_SEGMENT = 0x3 MI_PBT_L4BSP_SEGMENT = 0x4 MI_PBT_SWAPPED_SEGMENT = 0x5 +MI_PBT_XBL_SEC_SEGMENT = 0x5 MI_PBT_SWAP_POOL_SEGMENT = 0x6 MI_PBT_PHDR_SEGMENT = 0x7 @@ -902,6 +904,7 @@ def image_header(env, gen_dict, code_file_name, output_file_name, secure_type, + is_ext_mbn_v5, header_format = 'reg', requires_preamble = False, preamble_file_name = None, @@ -989,6 +992,12 @@ def image_header(env, gen_dict, boot_header.cert_chain_ptr = image_dest + code_size + signature_size boot_header.cert_chain_size = cert_chain_size + if is_ext_mbn_v5 == True: + # If platform image integrity check is enabled + boot_header.flash_parti_ver = 5 # version + boot_header.image_src = 0 # sig_size_qc + boot_header.image_dest_ptr = 0 # cert_chain_size_qc + # If preamble is required, output the preamble file and update the boot_header if requires_preamble is True: boot_header = image_preamble(gen_dict, preamble_file_name, boot_header, num_of_pages) @@ -2051,7 +2060,7 @@ def get_hash_address(elf_file_name): curr_phdr = phdr_table[i] if curr_phdr.p_paddr > last_paddr: # Skip the demand paging segment as it would be outside the physical RAM location - if MI_PBT_SEGMENT_TYPE_VALUE(curr_phdr.p_flags) != MI_PBT_SWAPPED_SEGMENT: + if MI_PBT_SEGMENT_TYPE_VALUE(curr_phdr.p_flags) != MI_PBT_XBL_SEC_SEGMENT: last_paddr = curr_phdr.p_paddr; last_paddr_segment = i; diff --git a/util/ipqheader/mbncat.py b/util/qualcomm/mbncat.py similarity index 100% rename from util/ipqheader/mbncat.py rename to util/qualcomm/mbncat.py diff --git a/util/qualcomm/qgpt.py b/util/qualcomm/qgpt.py new file mode 100755 index 00000000000..51018361e15 --- /dev/null +++ b/util/qualcomm/qgpt.py @@ -0,0 +1,234 @@ +#!/usr/bin/python +#============================================================================ +# +#/** @file qgpt.py +# +# GENERAL DESCRIPTION +# Generates QCom GPT header for wrapping Bootblock +# +# Copyright (c) 2018, The Linux Foundation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# * Neither the name of The Linux Foundation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#**/ +# + +import os +import math +import random +import re +import struct +import sys +import tempfile + +from binascii import crc32 +from optparse import OptionParser +from types import * + + +def UpdateMBR(options, GPTBlobBuffer): + i = 0x1BE + GPTBlobBuffer[i + 0] = 0x00 # not bootable + GPTBlobBuffer[i + 1] = 0x00 # head + GPTBlobBuffer[i + 2] = 0x01 # sector + GPTBlobBuffer[i + 3] = 0x00 # cylinder + GPTBlobBuffer[i + 4] = 0xEE # type + GPTBlobBuffer[i + 5] = 0xFF # head + GPTBlobBuffer[i + 6] = 0xFF # sector + GPTBlobBuffer[i + 7] = 0xFF # cylinder + GPTBlobBuffer[i + 8:i + 8 + 4] = [0x01, 0x00, 0x00, 0x00] + + GPTBlobBuffer[i + 12:i + 16] = [0x00, 0x0f, 0x00, 0x00] + + # magic byte for MBR partitioning - always at this location regardless of + # options.sector + GPTBlobBuffer[510:512] = [0x55, 0xAA] + return i + + +def UpdatePartitionEntry(options, GPTBlobBuffer): + + i = 2 * options.sector_size + # GUID of Boot Block + GPTBlobBuffer[i:i + 16] = [0x2c, 0xba, 0xa0, 0xde, 0xdd, 0xcb, 0x05, 0x48, + 0xb4, 0xf9, 0xf4, 0x28, 0x25, 0x1c, 0x3e, 0x98] + i += 16 + + #This is to set Unique Partition GUID. Below Hex Value is : 00ChezaBootblock00 + GPTBlobBuffer[i:i + 16] = [0x00, 0x43, 0x68, 0x65, 0x7a, 0x61, 0x42, 0x6f, + 0x6f, 0x74, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x00] + i += 16 + + # LBA of BootBlock Start Content + GPTBlobBuffer[i:i + 8] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # End LBA of BootBlock Content + GPTBlobBuffer[i] = options.end_lba & 0xFF + GPTBlobBuffer[i+1] = (options.end_lba>>8) & 0xFF + GPTBlobBuffer[i+2] = (options.end_lba>>16) & 0xFF + GPTBlobBuffer[i+3] = (options.end_lba>>24) & 0xFF + GPTBlobBuffer[i+4] = (options.end_lba>>32) & 0xFF + GPTBlobBuffer[i+5] = (options.end_lba>>40) & 0xFF + GPTBlobBuffer[i+6] = (options.end_lba>>48) & 0xFF + GPTBlobBuffer[i+7] = (options.end_lba>>56) & 0xFF + i += 8 + + # Attributes + GPTBlobBuffer[i:i + 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # Label + GPTBlobBuffer[i:i + 17] = [0x62, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, + 0x62, 0x00, 0x6c, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x6b] + + return i + +def UpdateGPTHeader(options, GPTBlobBuffer): + + i = options.sector_size + # Signature and Revision and HeaderSize i.e. "EFI PART" and 00 00 01 00 + # and 5C 00 00 00 + GPTBlobBuffer[i:i + 16] = [0x45, 0x46, 0x49, 0x20, 0x50, 0x41, 0x52, 0x54, + 0x00, 0x00, 0x01, 0x00, 0x5C, 0x00, 0x00, 0x00] + i += 16 + + # CRC is zeroed out till calculated later + GPTBlobBuffer[i:i + 4] = [0x00, 0x00, 0x00, 0x00] + i += 4 + + # Reserved, set to 0 + GPTBlobBuffer[i:i + 4] = [0x00, 0x00, 0x00, 0x00] + i += 4 + + # Current LBA + GPTBlobBuffer[i:i + 8] = [0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # Backup LBA, No Backup Gpt Used + GPTBlobBuffer[i:i + 8] = [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # First Usuable LBA (qc_sec + bootblock location) + GPTBlobBuffer[i:i + 8] = [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # Last Usuable LBA (qc_sec + bootblock end location) + GPTBlobBuffer[i] = options.end_lba & 0xFF + GPTBlobBuffer[i+1] = (options.end_lba>>8) & 0xFF + GPTBlobBuffer[i+2] = (options.end_lba>>16) & 0xFF + GPTBlobBuffer[i+3] = (options.end_lba>>24) & 0xFF + GPTBlobBuffer[i+4] = (options.end_lba>>32) & 0xFF + GPTBlobBuffer[i+5] = (options.end_lba>>40) & 0xFF + GPTBlobBuffer[i+6] = (options.end_lba>>48) & 0xFF + GPTBlobBuffer[i+7] = (options.end_lba>>56) & 0xFF + i += 8 + + # GUID + GPTBlobBuffer[i:i + 16] = [0x32,0x1B,0x10,0x98,0xE2,0xBB,0xF2,0x4B, + 0xA0,0x6E,0x2B,0xB3,0x3D,0x00,0x0C,0x20] + i += 16 + + # Partition Table Entry LBA + GPTBlobBuffer[i:i + 8] = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] + i += 8 + + # Number of Partition Entries + GPTBlobBuffer[i:i + 4] = [0x01, 0x00, 0x00, 0x00] + i += 4 + + # Size of One Partition Entry + GPTBlobBuffer[i:i + 4] = [0x80, 0x00, 0x00, 0x00] + i += 4 + + # CRC of Partition Entry + + PartEntry = GPTBlobBuffer[options.sector_size*2:options.sector_size*2 + 128] + CalcEntryCRC = crc32(''.join(struct.pack("B", x) for x in PartEntry)) + + GPTBlobBuffer[i] = CalcEntryCRC & 0xFF + GPTBlobBuffer[i+1] = (CalcEntryCRC>>8) & 0xFF + GPTBlobBuffer[i+2] = (CalcEntryCRC>>16) & 0xFF + GPTBlobBuffer[i+3] = (CalcEntryCRC>>24) & 0xFF + i += 4 + + # CRC of Partition Table Header + GPTHeader = GPTBlobBuffer[options.sector_size:options.sector_size + 92] + CalcEntryCRC = crc32(''.join(struct.pack("B", x) for x in GPTHeader)) + i = options.sector_size + 16 + + GPTBlobBuffer[i] = CalcEntryCRC & 0xFF + GPTBlobBuffer[i+1] = (CalcEntryCRC>>8) & 0xFF + GPTBlobBuffer[i+2] = (CalcEntryCRC>>16) & 0xFF + GPTBlobBuffer[i+3] = (CalcEntryCRC>>24) & 0xFF + + return i + + +if __name__ == '__main__': + usage = 'usage: %prog [OPTIONS] INFILE OUTFILE\n\n' + \ + 'Packages IMAGE in a GPT format.' + parser = OptionParser(usage) + parser.add_option('-s', type="int", dest='sector_size', default=4096, + help='Sector size in bytes [Default:4096(4KB)]', + metavar='SIZE') + + (options, args) = parser.parse_args() + if len(args) != 2: + print("Invalid arguments! Exiting...\n") + parser.print_help() + sys.exit(1) + + if options.sector_size != 4096 and options.sector_size != 512: + print("Invalid Sector Size") + sys.exit(1) + + options.inputfile = args[0] + options.outputfile = args[1] + + with open(options.inputfile, 'r+') as fin: + bb_buffer = fin.read() + + # Round up to next sector if bootblock size not evenly divisible + options.end_lba = ((len(bb_buffer) + options.sector_size - 1) / + options.sector_size) + # Add 3 sectors for MBR, GPT header and GPT partition entry + options.end_lba += 3 + # Subtract one because this is last usable LBA, not amount of LBAs + options.end_lba -= 1 + + GPTBlobBuffer = [0] * (options.sector_size*3) #Size of MBR+GPT+PART_ENTRY + + UpdateMBR(options, GPTBlobBuffer) + + UpdatePartitionEntry(options, GPTBlobBuffer) + + UpdateGPTHeader(options, GPTBlobBuffer) + + with open(options.outputfile, 'wb') as fout: + for b in GPTBlobBuffer: + fout.write(struct.pack("B", b)) + fout.write(bb_buffer) From bd0b51c0be1ec2c9a5f02de3c13108c13941e2c2 Mon Sep 17 00:00:00 2001 From: T Michael Turney Date: Thu, 21 Mar 2019 14:20:52 -0700 Subject: [PATCH 156/588] sdm845: Add QCLib to RomStage to perform IP init CB acts as I/O handler for QCLib (e.g. DDR training data) This interface allows bi-directional data flow between CB and QCLib Tested and working interfaces: DDR Training data QCLib serial console output DDR Information (base & size) limits cfg data TEST=build & run Change-Id: I073186674a1a593547d1ee1d15c7cd4fd8ad5bc1 Signed-off-by: T Michael Turney Reviewed-on: https://review.coreboot.org/c/coreboot/+/25208 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/mainboard/google/cheza/chromeos.fmd | 11 ++-- src/mainboard/google/cheza/romstage.c | 4 ++ src/soc/qualcomm/sdm845/Makefile.inc | 5 ++ .../qualcomm/sdm845/include/soc/memlayout.ld | 21 +++++--- src/soc/qualcomm/sdm845/include/soc/mmu.h | 2 - src/soc/qualcomm/sdm845/include/soc/symbols.h | 4 +- src/soc/qualcomm/sdm845/mmu.c | 5 +- src/soc/qualcomm/sdm845/qclib.c | 50 +++++++++++++++++++ src/soc/qualcomm/sdm845/soc.c | 4 +- 9 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 src/soc/qualcomm/sdm845/qclib.c diff --git a/src/mainboard/google/cheza/chromeos.fmd b/src/mainboard/google/cheza/chromeos.fmd index 71e85562d6c..b0d2d99996c 100644 --- a/src/mainboard/google/cheza/chromeos.fmd +++ b/src/mainboard/google/cheza/chromeos.fmd @@ -24,16 +24,15 @@ FLASH@0x0 8M { RO_FRID 0x100 } RO_VPD(PRESERVE) 16K - # TODO(hungte): Remove RO_PRESERVE. - RO_PRESERVE(PRESERVE) { - RO_DDR_TRAINING 8K - RO_FSG - } + RO_DDR_TRAINING(PRESERVE) 8K + RO_LIMITS_CFG(PRESERVE) 4K + RO_FSG(PRESERVE) } RW_VPD(PRESERVE) 32K RW_NVRAM(PRESERVE) 16K - RW_DDR_TRAINING 8K + RW_DDR_TRAINING(PRESERVE) 8K + RW_LIMITS_CFG(PRESERVE) 4K RW_ELOG(PRESERVE) 4K RW_SHARED 4K { SHARED_DATA diff --git a/src/mainboard/google/cheza/romstage.c b/src/mainboard/google/cheza/romstage.c index 7b7da4ce8c2..de737b11599 100644 --- a/src/mainboard/google/cheza/romstage.c +++ b/src/mainboard/google/cheza/romstage.c @@ -15,6 +15,7 @@ #include #include +#include static void prepare_usb(void) { @@ -28,4 +29,7 @@ static void prepare_usb(void) void platform_romstage_main(void) { prepare_usb(); + + /* QCLib: DDR init & train */ + qclib_load_and_run(); } diff --git a/src/soc/qualcomm/sdm845/Makefile.inc b/src/soc/qualcomm/sdm845/Makefile.inc index d099bff7174..78b3568a8b7 100644 --- a/src/soc/qualcomm/sdm845/Makefile.inc +++ b/src/soc/qualcomm/sdm845/Makefile.inc @@ -25,6 +25,10 @@ romstage-y += gpio.c romstage-y += clock.c romstage-$(CONFIG_SDM845_QSPI) += qspi.c romstage-y += usb.c +romstage-y += ../common/qclib.c +romstage-y += qclib.c +romstage-y += ../common/mmu.c +romstage-y += mmu.c ################################################################################ ramstage-y += soc.c @@ -39,6 +43,7 @@ ramstage-y += usb.c ################################################################################ CPPFLAGS_common += -Isrc/soc/qualcomm/sdm845/include +CPPFLAGS_common += -Isrc/soc/qualcomm/common/include $(objcbfs)/bootblock.bin: $(objcbfs)/bootblock.raw.bin @printf "Generating: $(subst $(obj)/,,$(@))\n" diff --git a/src/soc/qualcomm/sdm845/include/soc/memlayout.ld b/src/soc/qualcomm/sdm845/include/soc/memlayout.ld index 7063c6910e3..b1b633317fa 100644 --- a/src/soc/qualcomm/sdm845/include/soc/memlayout.ld +++ b/src/soc/qualcomm/sdm845/include/soc/memlayout.ld @@ -28,11 +28,12 @@ SECTIONS { SSRAM_START(0x14680000) OVERLAP_VERSTAGE_ROMSTAGE(0x14680000, 100K) - DMA_COHERENT(0x14699000, 0x2000) + DMA_COHERENT(0x14699000, 8K) + REGION(qcsdi, 0x146AC000, 44K, 4K) SSRAM_END(0x146C0000) BSRAM_START(0x14800000) - REGION(fw_reserved2, 0x14800000, 0x16000, 4096) + REGION(fw_reserved2, 0x14800000, 0x16000, 0x1000) BOOTBLOCK(0x14816000, 40K) TTB(0x14820000, 56K) VBOOT2_WORK(0x1482E000, 12K) @@ -40,15 +41,19 @@ SECTIONS TIMESTAMP(0x14836000, 1K) PRERAM_CBMEM_CONSOLE(0x14836400, 32K) PRERAM_CBFS_CACHE(0x1483E400, 70K) - REGION(bsram_unused, 0x1484FC00, 0xA2400, 0x100) - REGION(qclib, 0x148F2000, 0x80000, 4096) - REGION(dcb, 0x14972000, 0x4000, 4096) - REGION(pmic, 0x14976000, 0xA000, 4096) + REGION(bsram_unused, 0x1484FC00, 0x9E300, 0x100) + REGION(ddr_information, 0x148EDF00, 256, 256) + REGION(limits_cfg, 0x148EE000, 4K, 4K) + REGION(qclib_serial_log, 0x148EF000, 4K, 4K) + REGION(ddr_training, 0x148F0000, 8K, 4K) + REGION(qclib, 0x148F2000, 512K, 4K) + REGION(dcb, 0x14972000, 16K, 4K) + REGION(pmic, 0x14976000, 40K, 4K) BSRAM_END(0x14980000) DRAM_START(0x80000000) /* Various hardware/software subsystems make use of this area */ - REGION(dram_reserved, 0x85000000, 0x1A800000, 4096) + REGION(dram_reserved, 0x85000000, 0x1A800000, 0x1000) POSTRAM_CBFS_CACHE(0x9F800000, 384K) - RAMSTAGE(0x9F860000, 128K) + RAMSTAGE(0x9F860000, 2M) } diff --git a/src/soc/qualcomm/sdm845/include/soc/mmu.h b/src/soc/qualcomm/sdm845/include/soc/mmu.h index 299700a63fe..c9883bc0bfe 100644 --- a/src/soc/qualcomm/sdm845/include/soc/mmu.h +++ b/src/soc/qualcomm/sdm845/include/soc/mmu.h @@ -16,8 +16,6 @@ #ifndef _SOC_QUALCOMM_SDM845_MMU_H__ #define _SOC_QUALCOMM_SDM845_MMU_H__ -#define DRAMSIZE4GB 0x100000000 - void sdm845_mmu_init(void); #endif // _SOC_QUALCOMM_SDM845_MMU_H_ diff --git a/src/soc/qualcomm/sdm845/include/soc/symbols.h b/src/soc/qualcomm/sdm845/include/soc/symbols.h index 1c14c03d016..e7bf1b2aea8 100644 --- a/src/soc/qualcomm/sdm845/include/soc/symbols.h +++ b/src/soc/qualcomm/sdm845/include/soc/symbols.h @@ -17,10 +17,12 @@ #define _SOC_QUALCOMM_SDM845_SYMBOLS_H_ #include -#include DECLARE_REGION(ssram) DECLARE_REGION(bsram) DECLARE_REGION(dram_reserved) +DECLARE_REGION(dcb); +DECLARE_REGION(pmic); +DECLARE_REGION(limits_cfg); #endif // _SOC_QUALCOMM_SDM845_SYMBOLS_H_ diff --git a/src/soc/qualcomm/sdm845/mmu.c b/src/soc/qualcomm/sdm845/mmu.c index ef6c058ab3c..ec5fa55de28 100644 --- a/src/soc/qualcomm/sdm845/mmu.c +++ b/src/soc/qualcomm/sdm845/mmu.c @@ -17,12 +17,9 @@ #include #include #include +#include #include -#define CACHED_RAM (MA_MEM | MA_S | MA_RW) -#define UNCACHED_RAM (MA_MEM | MA_S | MA_RW | MA_MEM_NC) -#define DEV_MEM (MA_DEV | MA_S | MA_RW) - void sdm845_mmu_init(void) { mmu_init(); diff --git a/src/soc/qualcomm/sdm845/qclib.c b/src/soc/qualcomm/sdm845/qclib.c new file mode 100644 index 00000000000..9c05452c9e7 --- /dev/null +++ b/src/soc/qualcomm/sdm845/qclib.c @@ -0,0 +1,50 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +int qclib_soc_blob_load(void) +{ + size_t size; + ssize_t ssize; + + /* Attempt to load PMICCFG Blob */ + size = cbfs_boot_load_file(CONFIG_CBFS_PREFIX "/pmiccfg", + _pmic, REGION_SIZE(pmic), CBFS_TYPE_RAW); + if (!size) + return -1; + qclib_add_if_table_entry(QCLIB_TE_PMIC_SETTINGS, _pmic, size, 0); + + /* Attempt to load DCB Blob */ + size = cbfs_boot_load_file(CONFIG_CBFS_PREFIX "/dcb", + _dcb, REGION_SIZE(dcb), CBFS_TYPE_RAW); + if (!size) + return -1; + qclib_add_if_table_entry(QCLIB_TE_DCB_SETTINGS, _dcb, size, 0); + + /* Attempt to load Limits Config Blob */ + ssize = fmap_read_area(QCLIB_FR_LIMITS_CFG_DATA, _limits_cfg, + REGION_SIZE(limits_cfg)); + if (ssize < 0) + return -1; + qclib_add_if_table_entry(QCLIB_TE_LIMITS_CFG_DATA, + _limits_cfg, ssize, 0); + + return 0; +} diff --git a/src/soc/qualcomm/sdm845/soc.c b/src/soc/qualcomm/sdm845/soc.c index bc7235f3ed4..ef283c0eae2 100644 --- a/src/soc/qualcomm/sdm845/soc.c +++ b/src/soc/qualcomm/sdm845/soc.c @@ -16,11 +16,13 @@ #include #include #include +#include #include static void soc_read_resources(struct device *dev) { - ram_resource(dev, 0, (uintptr_t)_dram / KiB, DRAMSIZE4GB / KiB); + ram_resource(dev, 0, (uintptr_t)ddr_region->offset / KiB, + ddr_region->size / KiB); reserved_ram_resource(dev, 1, (uintptr_t)_dram_reserved / KiB, REGION_SIZE(dram_reserved) / KiB); } From a88041c04315cd2875cdf71e8070a6c7faa355a3 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Tue, 23 Apr 2019 12:16:33 +0200 Subject: [PATCH 157/588] mainboard/google/cyan/acpi: Serialize _CRS method IASL reports warning 'Control Method should be made Serialized'. Change _CRS method to Serialized. BUG=N/A TEST=Build Google Banon and Google Cyan Change-Id: Iffa097a2100cfa91efa3b617311500b83f839bce Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32331 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier --- src/mainboard/google/cyan/acpi/codec_maxim.asl | 2 +- src/mainboard/google/cyan/acpi/codec_realtek.asl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/cyan/acpi/codec_maxim.asl b/src/mainboard/google/cyan/acpi/codec_maxim.asl index 81bec16ea50..b412551a4ac 100644 --- a/src/mainboard/google/cyan/acpi/codec_maxim.asl +++ b/src/mainboard/google/cyan/acpi/codec_maxim.asl @@ -35,7 +35,7 @@ Scope (\_SB.PCI0.I2C2) } }) - Method(_CRS, 0x0, NotSerialized) + Method(_CRS, 0x0, Serialized) { Name(SBUF,ResourceTemplate () { diff --git a/src/mainboard/google/cyan/acpi/codec_realtek.asl b/src/mainboard/google/cyan/acpi/codec_realtek.asl index 4a1d48de7b9..d697aace3ea 100644 --- a/src/mainboard/google/cyan/acpi/codec_realtek.asl +++ b/src/mainboard/google/cyan/acpi/codec_realtek.asl @@ -26,7 +26,7 @@ Scope (\_SB.PCI0.I2C5) Name (_DDN, AUDIO_CODEC_DDN) Name (_UID, 1) - Method(_CRS, 0x0, NotSerialized) + Method(_CRS, 0x0, Serialized) { Name(SBUF,ResourceTemplate () { From e6bf51fb221db651c271115b32f1308983d20987 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Wed, 1 May 2019 10:48:31 +0200 Subject: [PATCH 158/588] {soc, southbridge} : Correct typo in comment BUG=N/A TEST=N/A Change-Id: I1b207e0b77bac8860ba7501378297c1f3604141c Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32453 Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/soc/intel/braswell/southcluster.c | 2 +- src/southbridge/intel/bd82x6x/pch.c | 2 +- src/southbridge/intel/lynxpoint/pch.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/soc/intel/braswell/southcluster.c b/src/soc/intel/braswell/southcluster.c index 000790d9a63..bf9f689c2a3 100644 --- a/src/soc/intel/braswell/southcluster.c +++ b/src/soc/intel/braswell/southcluster.c @@ -347,7 +347,7 @@ static void sc_init(struct device *dev) * Common code for the south cluster devices. */ -/* Set bit in function disble register to hide this device. */ +/* Set bit in function disable register to hide this device. */ static void sc_disable_devfn(struct device *dev) { void *func_dis = (void *)(PMC_BASE_ADDRESS + FUNC_DIS); diff --git a/src/southbridge/intel/bd82x6x/pch.c b/src/southbridge/intel/bd82x6x/pch.c index 746c11a2e3e..f8540af4514 100644 --- a/src/southbridge/intel/bd82x6x/pch.c +++ b/src/southbridge/intel/bd82x6x/pch.c @@ -144,7 +144,7 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue) } #ifndef __SMM__ -/* Set bit in Function Disble register to hide this device */ +/* Set bit in function disable register to hide this device */ static void pch_hide_devfn(unsigned devfn) { switch (devfn) { diff --git a/src/southbridge/intel/lynxpoint/pch.c b/src/southbridge/intel/lynxpoint/pch.c index 5cf67aa238d..a57bae311db 100644 --- a/src/southbridge/intel/lynxpoint/pch.c +++ b/src/southbridge/intel/lynxpoint/pch.c @@ -100,7 +100,7 @@ static void pch_enable_d3hot(struct device *dev) pci_write_config32(dev, PCH_PCS, reg32); } -/* Set bit in Function Disble register to hide this device */ +/* Set bit in function disable register to hide this device */ void pch_disable_devfn(struct device *dev) { switch (dev->path.pci.devfn) { From 73c312fce591928e3709a733b78ce6826f8e1a2d Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 3 May 2019 16:32:30 -0500 Subject: [PATCH 159/588] src/Kconfig: remove duplicate entry for drivers/fsp1_0/Kconfig The entry for drivers/intel/fsp1_0/Kconfig was added under the chipset menu before addtional FSP versions were added, and the drivers/*/*/Kconfig entry added to support them. This results in the fsp1_0 Kconfig items being duplicated in the Chipset and Generic Drivers menus. Remove the chipset entry since it's no longer needed. Test: select FSP 1.0 mainboard (e.g. intel/minnowmax) in menuconfig, observe FSP 1.0 Kconfig entries listed only under Generic Drivers menu. Signed-off-by: Matt DeVillier Change-Id: If1e78fb9259b1a46d308db829881eb3b3d17cf40 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32565 Reviewed-by: Furquan Shaikh Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/Kconfig | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Kconfig b/src/Kconfig index 90c724ebb52..05875b63274 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -370,8 +370,6 @@ source "src/superio/*/*/Kconfig" comment "Embedded Controllers" source "src/ec/acpi/Kconfig" source "src/ec/*/*/Kconfig" -# FIXME move to vendorcode -source "src/drivers/intel/fsp1_0/Kconfig" source "src/southbridge/intel/common/firmware/Kconfig" source "src/vendorcode/*/Kconfig" From 29a1a0857a637651595dc6109dc24243f353cadf Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 5 May 2019 08:34:55 +0200 Subject: [PATCH 160/588] mb/msi/ms7707: Remove MAINBOARD_PCI_SUBSYSTEM_{DEVICE_ID,VENDOR_ID} References to MAINBOARD_PCI_SUBSYSTEM_{DEVICE_ID,VENDOR_ID} were removed. Change-Id: I70ef22aac165a19663749f76449907482b761316 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32605 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Angel Pons Reviewed-by: Nico Huber --- src/mainboard/msi/ms7707/Kconfig | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/mainboard/msi/ms7707/Kconfig b/src/mainboard/msi/ms7707/Kconfig index 45ff73e57a3..4923bbfdea5 100644 --- a/src/mainboard/msi/ms7707/Kconfig +++ b/src/mainboard/msi/ms7707/Kconfig @@ -22,14 +22,6 @@ config MAINBOARD_PART_NUMBER string default "MS-7707" -config MAINBOARD_PCI_SUBSYSTEM_DEVICE_ID - hex - default 0x7707 - -config MAINBOARD_PCI_SUBSYSTEM_VENDOR_ID - hex - default 0x1462 - config DRAM_RESET_GATE_GPIO int default 60 From 42065f8f94b910972fb5e7f3f1952a908b94ffc1 Mon Sep 17 00:00:00 2001 From: Werner Zeh Date: Thu, 2 May 2019 12:45:21 +0200 Subject: [PATCH 161/588] mb/siemens/mc_apl2: Limit SD-Card speed to DDR50 Due to PCB limitations the SD-Card interface is not able to operate with the highest frequency reliably. The OS driver will switch to the highest mode if a SD-Card is attached which supports this high frequency mode. In order to work around this PCB limitation disable the high frequency modes in the controller capabilities (SDR104 and HS400 mode) and leave SDR50 and DDR50 enabled. Change-Id: Ia5fed5fb70b027de34170b49620927614a00fb7a Signed-off-by: Werner Zeh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32542 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- .../mc_apl1/variants/mc_apl2/mainboard.c | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c index 0c2418ad278..f52091bced5 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c @@ -23,6 +23,11 @@ #include #include #include +#include + +#define SD_CAP_BYP 0x810 +#define SD_CAP_BYP_EN 0x5A +#define SD_CAP_BYP_REG1 0x814 void variant_mainboard_final(void) { @@ -36,6 +41,21 @@ void variant_mainboard_final(void) cmd |= PCI_COMMAND_MASTER; pci_write_config16(dev, PCI_COMMAND, cmd); } + + /* Reduce SD-Card speed to DDR50 because of PCB constraints. */ + dev = pcidev_path_on_root(PCH_DEVFN_SDCARD); + if (dev) { + uint32_t reg; + struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); + if (!res) + return; + + write32(res2mmio(res, SD_CAP_BYP, 0), SD_CAP_BYP_EN); + reg = read32(res2mmio(res, SD_CAP_BYP_REG1, 0)); + /* Disable HS400 and SDR104, keep SDR50 and DDR50 modes. */ + reg &= ~0x20005800; + write32(res2mmio(res, SD_CAP_BYP_REG1, 0), reg); + } } static void wait_for_legacy_dev(void *unused) From 43fc38943da7839d2fe83bf7ca1b9c509c327dc0 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Fri, 26 Apr 2019 14:50:32 +0200 Subject: [PATCH 162/588] mainboard/intel/strago/acpi: Serialize _CRS method IASL reports warning 'Control Method should be made Serialized'. Change _CRS method to Serialized. BUG=N/A TEST=Build Intel Strago Change-Id: I63a7e1caab19360a9a5831458311d5a83fdf52d1 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32468 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/intel/strago/acpi/mainboard.asl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/intel/strago/acpi/mainboard.asl b/src/mainboard/intel/strago/acpi/mainboard.asl index 68ac133eec4..1d5437bbf26 100644 --- a/src/mainboard/intel/strago/acpi/mainboard.asl +++ b/src/mainboard/intel/strago/acpi/mainboard.asl @@ -74,7 +74,7 @@ Scope (\_SB.PCI0.I2C1) Name (_UID, 5) Name (ISTP, 0) /* TouchScreen */ - Method(_CRS, 0x0, NotSerialized) + Method(_CRS, 0x0, Serialized) { Name (BUF0, ResourceTemplate () { @@ -120,7 +120,7 @@ Scope (\_SB.PCI0.I2C5) Name (_DDN, AUDIO_CODEC_DDN) Name (_UID, 1) - Method(_CRS, 0x0, NotSerialized) + Method(_CRS, 0x0, Serialized) { Name(SBUF,ResourceTemplate () { From 85b2ed5438d5d42d00519114e385bf3ae2d56e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 14 Jun 2018 06:57:05 +0300 Subject: [PATCH 163/588] soc/amd/common: Introduce module_dispatch() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This change removes all the separate entrypoint dispatch functions as they all share the same pattern. Furthermore, none of the function definitions under vendorcode binaryPI/AGESA.c file have proper declarations, the ones compiler picks up from AGESA.h are for the internal implementations and with sanely organized headerfiles would not be exposed outside the build of AGESA at all. Change-Id: I0b72badc007565740c93b58743cfd048e8b42775 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31485 Reviewed-by: Nico Huber Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/pi/agesawrapper.c | 55 +++++-- .../amd/pi/00670F00/binaryPI/AGESA.c | 154 ------------------ 2 files changed, 39 insertions(+), 170 deletions(-) diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index 0570b5a3ee2..5f58346625c 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -41,8 +41,34 @@ static void *AcpiAlib; static void *AcpiIvrs; static void *AcpiCrat; +static AGESA_STATUS module_dispatch(AGESA_STRUCT_NAME func, + AMD_CONFIG_PARAMS *StdHeader) +{ + MODULE_ENTRY dispatcher = agesa_get_dispatcher(); + + if (!dispatcher) + return AGESA_UNSUPPORTED; + + StdHeader->Func = func; + return dispatcher(StdHeader); +} + +static AGESA_STATUS amd_dispatch(void *Params) +{ + AMD_CONFIG_PARAMS *StdHeader = Params; + return module_dispatch(StdHeader->Func, StdHeader); +} + +AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams) +{ + AMD_CONFIG_PARAMS *StdHeader = (void *)ApExeParams; + return module_dispatch(AMD_LATE_RUN_AP_TASK, StdHeader); +} + static void *create_struct(AMD_INTERFACE_PARAMS *interface_struct) { + AMD_CONFIG_PARAMS *StdHeader; + /* Should clone entire StdHeader here. */ interface_struct->StdHeader.CalloutPtr = &GetBiosCallout; @@ -57,7 +83,9 @@ static void *create_struct(AMD_INTERFACE_PARAMS *interface_struct) if (!interface_struct->NewStructPtr) /* Avoid NULL pointer usage */ die("No AGESA structure created"); - return interface_struct->NewStructPtr; + StdHeader = interface_struct->NewStructPtr; + StdHeader->Func = interface_struct->AgesaFunctionName; + return StdHeader; } static AGESA_STATUS amd_init_reset(void) @@ -76,7 +104,7 @@ static AGESA_STATUS amd_init_reset(void) SetFchResetParams(&ResetParams->FchInterface); timestamp_add_now(TS_AGESA_INIT_RESET_START); - status = AmdInitReset(ResetParams); + status = amd_dispatch(ResetParams); timestamp_add_now(TS_AGESA_INIT_RESET_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -97,7 +125,7 @@ static AGESA_STATUS amd_init_early(void) OemCustomizeInitEarly(EarlyParams); timestamp_add_now(TS_AGESA_INIT_EARLY_START); - status = AmdInitEarly(EarlyParams); + status = amd_dispatch(EarlyParams); timestamp_add_now(TS_AGESA_INIT_EARLY_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -162,7 +190,7 @@ static AGESA_STATUS amd_init_post(void) ); timestamp_add_now(TS_AGESA_INIT_POST_START); - status = AmdInitPost(PostParams); + status = amd_dispatch(PostParams); timestamp_add_now(TS_AGESA_INIT_POST_DONE); /* @@ -205,7 +233,7 @@ static AGESA_STATUS amd_init_env(void) SetNbEnvParams(&EnvParams->GnbEnvConfiguration); timestamp_add_now(TS_AGESA_INIT_ENV_START); - status = AmdInitEnv(EnvParams); + status = amd_dispatch(EnvParams); timestamp_add_now(TS_AGESA_INIT_ENV_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -256,7 +284,7 @@ static AGESA_STATUS amd_init_mid(void) SetNbMidParams(&MidParams->GnbMidConfiguration); timestamp_add_now(TS_AGESA_INIT_MID_START); - status = AmdInitMid(MidParams); + status = amd_dispatch(MidParams); timestamp_add_now(TS_AGESA_INIT_MID_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -286,7 +314,7 @@ static AGESA_STATUS amd_init_late(void) } timestamp_add_now(TS_AGESA_INIT_LATE_START); - Status = AmdInitLate(LateParams); + Status = amd_dispatch(LateParams); timestamp_add_now(TS_AGESA_INIT_LATE_DONE); DmiTable = LateParams->DmiTable; @@ -309,11 +337,6 @@ static AGESA_STATUS amd_init_late(void) return Status; } -AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams) -{ - return AmdLateRunApTask(ApExeParams); -} - static AGESA_STATUS amd_init_rtb(void) { AGESA_STATUS Status; @@ -325,7 +348,7 @@ static AGESA_STATUS amd_init_rtb(void) AMD_RTB_PARAMS *RtbParams = create_struct(&AmdParamStruct); timestamp_add_now(TS_AGESA_INIT_RTB_START); - Status = AmdInitRtb(RtbParams); + Status = amd_dispatch(RtbParams); timestamp_add_now(TS_AGESA_INIT_RTB_DONE); if (save_s3_info(RtbParams->S3DataBlock.NvStorage, @@ -354,7 +377,7 @@ static AGESA_STATUS amd_init_resume(void) InitResumeParams->S3DataBlock.NvStorageSize = nv_size; timestamp_add_now(TS_AGESA_INIT_RESUME_START); - status = AmdInitResume(InitResumeParams); + status = amd_dispatch(InitResumeParams); timestamp_add_now(TS_AGESA_INIT_RESUME_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -382,7 +405,7 @@ static AGESA_STATUS amd_s3late_restore(void) S3LateParams->S3DataBlock.VolatileStorageSize = vol_size; timestamp_add_now(TS_AGESA_S3_LATE_START); - Status = AmdS3LateRestore(S3LateParams); + Status = amd_dispatch(S3LateParams); timestamp_add_now(TS_AGESA_S3_LATE_DONE); AmdReleaseStruct(&AmdParamStruct); @@ -408,7 +431,7 @@ static AGESA_STATUS amd_s3final_restore(void) S3FinalParams->S3DataBlock.VolatileStorageSize = vol_size; timestamp_add_now(TS_AGESA_S3_FINAL_START); - Status = AmdS3FinalRestore(S3FinalParams); + Status = amd_dispatch(S3FinalParams); timestamp_add_now(TS_AGESA_S3_FINAL_DONE); AmdReleaseStruct(&AmdParamStruct); diff --git a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c index 2efee4eb62e..e17cedcb649 100644 --- a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c +++ b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c @@ -72,157 +72,3 @@ AmdReleaseStruct ( if (!Dispatcher) return AGESA_UNSUPPORTED; return Dispatcher(InterfaceParams); } - -/********************************************************************** - * Interface call: AmdInitReset - **********************************************************************/ -AGESA_STATUS -AmdInitReset ( - IN OUT AMD_RESET_PARAMS *ResetParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - ResetParams->StdHeader.Func = AMD_INIT_RESET; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(ResetParams); -} - -/********************************************************************** - * Interface call: AmdInitEarly - **********************************************************************/ -AGESA_STATUS -AmdInitEarly ( - IN OUT AMD_EARLY_PARAMS *EarlyParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - EarlyParams->StdHeader.Func = AMD_INIT_EARLY; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(EarlyParams); -} - -/********************************************************************** - * Interface call: AmdInitPost - **********************************************************************/ -AGESA_STATUS -AmdInitPost ( - IN OUT AMD_POST_PARAMS *PostParams ///< Amd Cpu init param - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - PostParams->StdHeader.Func = AMD_INIT_POST; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(PostParams); -} - -/********************************************************************** - * Interface call: AmdInitEnv - **********************************************************************/ -AGESA_STATUS -AmdInitEnv ( - IN OUT AMD_ENV_PARAMS *EnvParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - EnvParams->StdHeader.Func = AMD_INIT_ENV; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(EnvParams); -} - -/********************************************************************** - * Interface call: AmdInitMid - **********************************************************************/ -AGESA_STATUS -AmdInitMid ( - IN OUT AMD_MID_PARAMS *MidParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - MidParams->StdHeader.Func = AMD_INIT_MID; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(MidParams); -} - -/********************************************************************** - * Interface call: AmdInitLate - **********************************************************************/ -AGESA_STATUS -AmdInitLate ( - IN OUT AMD_LATE_PARAMS *LateParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - LateParams->StdHeader.Func = AMD_INIT_LATE; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(LateParams); -} - -/********************************************************************** - * Interface call: AmdInitResume - **********************************************************************/ -AGESA_STATUS -AmdInitResume ( - IN AMD_RESUME_PARAMS *ResumeParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - ResumeParams->StdHeader.Func = AMD_INIT_RESUME; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(ResumeParams); -} - -/********************************************************************** - * Interface call: AmdS3LateRestore - **********************************************************************/ -AGESA_STATUS -AmdS3LateRestore ( - IN OUT AMD_S3LATE_PARAMS *S3LateParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - S3LateParams->StdHeader.Func = AMD_S3LATE_RESTORE; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(S3LateParams); -} - -/********************************************************************** - * Interface call: AmdS3FinalRestore - **********************************************************************/ -AGESA_STATUS -AmdS3FinalRestore ( - IN OUT AMD_S3FINAL_PARAMS *S3FinalParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - S3FinalParams->StdHeader.Func = AMD_S3FINAL_RESTORE; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(S3FinalParams); -} - -/********************************************************************** - * Interface call: AmdInitRtb - **********************************************************************/ -AGESA_STATUS -AmdInitRtb ( - IN OUT AMD_RTB_PARAMS *AmdInitRtbParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - AmdInitRtbParams->StdHeader.Func = AMD_INIT_RTB; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(AmdInitRtbParams); -} - -/********************************************************************** - * Interface call: AmdLateRunApTask - **********************************************************************/ -AGESA_STATUS -AmdLateRunApTask ( - IN AP_EXE_PARAMS *AmdApExeParams -) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - AmdApExeParams->StdHeader.Func = AMD_LATE_RUN_AP_TASK; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(AmdApExeParams); -} From 683e77e479d7204bdfaf4d9b468901aafe5225e3 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Mon, 29 Apr 2019 13:29:36 +0200 Subject: [PATCH 164/588] drivers/intel/fsp1_1/cache_as_ram.inc: Reduce max line length to 80 Cosmetic change to reduce line length to 80 max. BUG=NA TEST=Build Portwell PQ7-M107 Change-Id: Ib537592c0a6a3fffc85622e6b74ad5ec8041e7dc Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32509 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/drivers/intel/fsp1_1/cache_as_ram.inc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc index 48fcb8f39f2..fa5c40677b5 100644 --- a/src/drivers/intel/fsp1_1/cache_as_ram.inc +++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc @@ -24,9 +24,8 @@ * performs the final stage of initialization. */ - -#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */ - +/* I/O delay between post codes on failure */ +#define LHLT_DELAY 0x50000 /* * Per FSP1.1 specs, following registers are preserved: * EBX, EDI, ESI, EBP, MM0, MM1 @@ -165,8 +164,8 @@ halt1: * 0x01 - FV signature, "_FVH" not present * 0x02 - FFS GUID not present * 0x03 - FSP INFO Header not found - * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to - * a different location, or does it need to be? + * 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased + * to a different location, or does it need to be? * 0x05 - FSP INFO Header signature "FSPH" not found * 0x06 - FSP Image ID is not the expected ID. */ @@ -181,7 +180,8 @@ halt2: * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid. * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met. * 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed - * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region. + * 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode + * region. * 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked */ movb $0xBB, %ah @@ -213,7 +213,7 @@ CAR_init_params: .long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */ .long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */ .long 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 /* Firmware Location */ - .long CONFIG_ROM_SIZE /* Total Firmware Length */ + .long CONFIG_ROM_SIZE /* Firmware Length */ CAR_init_stack: .long CAR_init_done From 95f8884c955de7a2f46d7a324079f18208093157 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Fri, 26 Apr 2019 14:54:58 -0600 Subject: [PATCH 165/588] soc/intel/common: Add new PAD_CFG macro. Added macro named PAD_CFG_GPI_GPIO_DRIVER_SCI, for pads that need to be configured as GPI, GPIO Driver mode, and SCI interrupt. Also remove PAD_IRQ_CFG_DUAL_ROUTE macro (subsumed by PAD_CFG_GPI_IRQ_WAKE). BUG=none BRANCH=none TEST=Compiles Change-Id: I0332c64e2fa62ce29c772444606adbfdf9c9afc4 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32485 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/include/intelblocks/gpio_defs.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h index 91d8f00a89e..e1ddd4babba 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio_defs.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio_defs.h @@ -391,6 +391,13 @@ PAD_IOSSTATE(TxDRxE)) #if CONFIG(SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT) +/* GPI, GPIO Driver, SCI interrupt */ +#define PAD_CFG_GPI_GPIO_DRIVER_SCI(pad, pull, rst, trig, inv) \ + _PAD_CFG_STRUCT(pad, \ + PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ + PAD_IRQ_CFG(SCI, trig, inv), \ + PAD_PULL(pull) | PAD_CFG1_GPIO_DRIVER | PAD_IOSSTATE(TxDRxE)) + #define PAD_CFG_GPI_DUAL_ROUTE(pad, pull, rst, trig, inv, route1, route2) \ _PAD_CFG_STRUCT(pad, \ PAD_FUNC(GPIO) | PAD_RESET(rst) | PAD_CFG0_TX_DISABLE | \ From 939440c48ba47401679dd65930464649398b78db Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Fri, 26 Apr 2019 15:03:33 -0600 Subject: [PATCH 166/588] soc/intel/cannonlake: Add GPIO dual-route support. Select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT in Kconfig BUG=none BRANCH=none TEST=compiles Change-Id: If5f59ea50c13bd1f279637e281468e6d0312dbab Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32486 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index 6759b7ff993..c06b91eb48a 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -90,6 +90,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_INTEL_COMMON_BLOCK_CHIP_CONFIG select SOC_INTEL_COMMON_BLOCK_CPU select SOC_INTEL_COMMON_BLOCK_CPU_MPINIT + select SOC_INTEL_COMMON_BLOCK_GPIO_DUAL_ROUTE_SUPPORT select SOC_INTEL_COMMON_BLOCK_GSPI_VERSION_2 select SOC_INTEL_COMMON_BLOCK_HDA select SOC_INTEL_COMMON_BLOCK_SA From 3fe7c44d501d64cfcc5cd79fbc02f7071bdfda4b Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Fri, 26 Apr 2019 15:26:15 -0600 Subject: [PATCH 167/588] mainboard/google/hatch: Enable PEN_EJECT_L as wake & notify source. Updated GPP_A8 to be a GPI and SCI source, to support both wake and notifications. BUG=b:128941098 BRANCH=none TEST=Compiles, simulated pen eject with PCH_INT_L signal. Both evtest and waking from s0ix confirm this works. The output of /proc/interrupts confirms the correct interrupt is triggered. Change-Id: I080fb3cbfb3e2f55209ca31824b00ca820d70f78 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32487 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/hatch/variants/baseboard/gpio.c | 4 ++-- src/mainboard/google/hatch/variants/hatch/overridetree.cb | 4 +++- src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/gpio.c b/src/mainboard/google/hatch/variants/baseboard/gpio.c index 198d930abaa..32526cc74b4 100644 --- a/src/mainboard/google/hatch/variants/baseboard/gpio.c +++ b/src/mainboard/google/hatch/variants/baseboard/gpio.c @@ -30,8 +30,8 @@ static const struct pad_config gpio_table[] = { PAD_CFG_GPI_INT(GPP_A6, NONE, PLTRST, LEVEL), /* A7 : PP3300_SOC_A */ PAD_NC(GPP_A7, NONE), - /* A8 : EMR_GARAGE_DET */ - PAD_CFG_GPI_GPIO_DRIVER(GPP_A8, NONE, DEEP), + /* A8 : PEN_GARAGE_DET_L */ + PAD_CFG_GPI_GPIO_DRIVER_SCI(GPP_A8, NONE, DEEP, LEVEL, NONE), /* A9 : ESPI_CLK */ /* A10 : FPMCU_PCH_BOOT1 */ PAD_CFG_GPO(GPP_A10, 0, DEEP), diff --git a/src/mainboard/google/hatch/variants/hatch/overridetree.cb b/src/mainboard/google/hatch/variants/hatch/overridetree.cb index 4b1b8d85f23..42752e68f1c 100644 --- a/src/mainboard/google/hatch/variants/hatch/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch/overridetree.cb @@ -86,7 +86,9 @@ chip soc/intel/cannonlake end chip drivers/generic/gpio_keys register "name" = ""PENH"" - register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_HIGH(GPP_A8)" + register "gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_A8)" + register "key.wake" = "GPE0_DW0_08" + register "key.wakeup_event_action" = "EV_ACT_ASSERTED" register "key.dev_name" = ""EJCT"" register "key.linux_code" = "SW_PEN_INSERTED" register "key.linux_input_type" = "EV_SW" diff --git a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb index c5d5964663f..115a513038e 100644 --- a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb @@ -71,7 +71,9 @@ chip soc/intel/cannonlake end chip drivers/generic/gpio_keys register "name" = ""PENH"" - register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_HIGH(GPP_A8)" + register "gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_A8)" + register "key.wake" = "GPE0_DW0_08" + register "key.wakeup_event_action" = "EV_ACT_ASSERTED" register "key.dev_name" = ""EJCT"" register "key.linux_code" = "SW_PEN_INSERTED" register "key.linux_input_type" = "EV_SW" From b75f493ed7fafb6a933a3f47e1e90803b18fcb65 Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Mon, 29 Apr 2019 09:12:54 +0800 Subject: [PATCH 168/588] mediatek/mt8183: Wait 200us for voltages to settle When we increase voltages, it takes 200us for voltages to stablize. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: I5f32035693b6084dbe763411c612ae5d1f7c9e48 Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32498 Tested-by: build bot (Jenkins) Reviewed-by: You-Cheng Syu Reviewed-by: Julius Werner --- src/soc/mediatek/mt8183/mt6358.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/soc/mediatek/mt8183/mt6358.c b/src/soc/mediatek/mt8183/mt6358.c index 8162e3aaf17..705424337f5 100644 --- a/src/soc/mediatek/mt8183/mt6358.c +++ b/src/soc/mediatek/mt8183/mt6358.c @@ -16,6 +16,7 @@ #include #include #include +#include static struct pmic_setting init_setting[] = { /* [15:0]: TMA_KEY */ @@ -775,13 +776,18 @@ static void mt6358_lp_setting(void) void mt6358_init(void) { + struct stopwatch voltage_settled; + if (pwrap_init()) die("ERROR - Failed to initialize pmic wrap!"); pmic_set_power_hold(true); pmic_wdt_set(); mt6358_init_setting(); + stopwatch_init_usecs_expire(&voltage_settled, 200); wk_sleep_voltage_by_ddr(); wk_power_down_seq(); mt6358_lp_setting(); + while (!stopwatch_expired(&voltage_settled)) + /* wait for voltages to settle */; } From 0dd6b55a7e8cb8fbc8c1c0188d9d4bd91a4e7813 Mon Sep 17 00:00:00 2001 From: Tristan Shieh Date: Fri, 26 Apr 2019 12:32:12 +0800 Subject: [PATCH 169/588] google/kukui: Raise the CPU frequency Run CPU at the highest freqency (1989MHz) to speed up the boot time. BUG=b:80501386 BRANCH=none Test=Boots correctly on Kukui Change-Id: I703ffcb99367f87e6792a72485f5634e0505e5ac Signed-off-by: Tristan Shieh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32466 Reviewed-by: Angel Pons Reviewed-by: Hung-Te Lin Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/mainboard/google/kukui/romstage.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/kukui/romstage.c b/src/mainboard/google/kukui/romstage.c index 81ae9c538dc..baaca43b908 100644 --- a/src/mainboard/google/kukui/romstage.c +++ b/src/mainboard/google/kukui/romstage.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "early_init.h" @@ -28,6 +29,7 @@ void platform_romstage_main(void) mainboard_early_init(); mt6358_init(); + mt_pll_raise_ca53_freq(1989 * MHz); rtc_boot(); mt_mem_init(get_sdram_config()); mtk_mmu_after_dram(); From 72a9091a0efce1835a94f0ba0b10f62c78af70e2 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 24 Mar 2019 17:35:55 +0100 Subject: [PATCH 170/588] sb/intel/bd82x6x: Use common/rcba.h Make use of: * southbridge/intel/common/rcba.h * southbridge/intel/common/pmbase.c * defines in pch.h Get rid of dependency to DEFAULT_RCBA. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to OS, no errors visible in dmesg. Change-Id: I879fce6a5bb80499e1986e618a1422a7aaa3a0c0 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32066 Reviewed-by: HAOUAS Elyes Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/southbridge/intel/bd82x6x/early_usb.c | 32 ++++++++++------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c index 17919af53a3..955737e2a85 100644 --- a/src/southbridge/intel/bd82x6x/early_usb.c +++ b/src/southbridge/intel/bd82x6x/early_usb.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include + #include "pch.h" void early_usb_init(const struct southbridge_usb_port *portmap) @@ -32,46 +35,39 @@ void early_usb_init(const struct southbridge_usb_port *portmap) 0x2000094a, 0x2000035f, 0x20000f53, 0x20000357, 0x20000353 }; int i; - /* Activate PMBAR. */ - pci_write_config32(PCI_DEV(0, 0x1f, 0), PMBASE, DEFAULT_PMBASE | 1); - pci_write_config32(PCI_DEV(0, 0x1f, 0), PMBASE + 4, 0); - /* Enable ACPI BAR */ - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44 /* ACPI_CNTL */, 0x80); /* Unlock registers. */ - outw(inw(DEFAULT_PMBASE | UPRWC) | UPRWC_WR_EN, - DEFAULT_PMBASE | UPRWC); + write_pmbase16(UPRWC, read_pmbase16(UPRWC) | UPRWC_WR_EN); for (i = 0; i < 14; i++) - write32(DEFAULT_RCBABASE + (0x3500 + 4 * i), - currents[portmap[i].current]); + RCBA32(0x3500 + 4 * i) = currents[portmap[i].current]; for (i = 0; i < 10; i++) - write32(DEFAULT_RCBABASE + (0x3538 + 4 * i), 0); + RCBA32(0x3538 + 4 * i) = 0; for (i = 0; i < 8; i++) - write32(DEFAULT_RCBABASE + (0x3560 + 4 * i), rcba_dump[i]); + RCBA32(0x3560 + 4 * i) = rcba_dump[i]; for (i = 0; i < 8; i++) - write32(DEFAULT_RCBABASE + (0x3580 + 4 * i), 0); + RCBA32(0x3580 + 4 * i) = 0; reg32 = 0; for (i = 0; i < 14; i++) if (!portmap[i].enabled) reg32 |= (1 << i); - write32(DEFAULT_RCBABASE + USBPDO, reg32); + RCBA32(USBPDO) = reg32; reg32 = 0; for (i = 0; i < 8; i++) if (portmap[i].enabled && portmap[i].oc_pin >= 0) reg32 |= (1 << (i + 8 * portmap[i].oc_pin)); - write32(DEFAULT_RCBABASE + USBOCM1, reg32); + RCBA32(USBOCM1) = reg32; reg32 = 0; for (i = 8; i < 14; i++) if (portmap[i].enabled && portmap[i].oc_pin >= 4) reg32 |= (1 << (i - 8 + 8 * (portmap[i].oc_pin - 4))); - write32(DEFAULT_RCBABASE + USBOCM2, reg32); + RCBA32(USBOCM2) = reg32; for (i = 0; i < 22; i++) - write32(DEFAULT_RCBABASE + (0x35a8 + 4 * i), 0); + RCBA32(0x35a8 + 4 * i) = 0; - pci_write_config32(PCI_DEV(0, 0x14, 0), 0xe4, 0x00000000); + pci_write_config32(PCH_XHCI_DEV, 0xe4, 0x00000000); /* Relock registers. */ - outw(0, DEFAULT_PMBASE | UPRWC); + write_pmbase16(UPRWC, 0); } From 4998becda3e3e8033a84599158e180217e39d1bc Mon Sep 17 00:00:00 2001 From: Marius Genheimer Date: Tue, 30 Apr 2019 00:04:32 +0200 Subject: [PATCH 171/588] soc/skylake: Add missing PCH IDs Added IDs for: - H170 - Z170 - Q170 - Q150 - B150 Used documents: - 332690-005EN Tested on Gigabyte GA-Z170N-WIFI Change-Id: If20a2b764afa02785a97948893dbc5b5f60aff60 Signed-off-by: Marius Genheimer Reviewed-on: https://review.coreboot.org/c/coreboot/+/32517 Reviewed-by: Patrick Rudolph Reviewed-by: Angel Pons Reviewed-by: Felix Singer Tested-by: build bot (Jenkins) --- src/include/device/pci_ids.h | 5 +++++ src/soc/intel/common/block/lpc/lpc.c | 5 +++++ src/soc/intel/skylake/bootblock/report_platform.c | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index 85bd6c3864c..64539510ce0 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -2689,6 +2689,11 @@ #define PCI_DEVICE_ID_INTEL_SPT_LP_U_BASE 0x9d43 #define PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM 0x9d48 #define PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM 0x9d46 +#define PCI_DEVICE_ID_INTEL_SPT_H_H170 0xa144 +#define PCI_DEVICE_ID_INTEL_SPT_H_Z170 0xa145 +#define PCI_DEVICE_ID_INTEL_SPT_H_Q170 0xa146 +#define PCI_DEVICE_ID_INTEL_SPT_H_Q150 0xa147 +#define PCI_DEVICE_ID_INTEL_SPT_H_B150 0xa148 #define PCI_DEVICE_ID_INTEL_SPT_H_C236 0xa150 #define PCI_DEVICE_ID_INTEL_SPT_H_PREMIUM 0xa14e #define PCI_DEVICE_ID_INTEL_SPT_H_H110 0xa143 diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c index d5f76f3a7b5..43b3522431e 100644 --- a/src/soc/intel/common/block/lpc/lpc.c +++ b/src/soc/intel/common/block/lpc/lpc.c @@ -127,6 +127,11 @@ static const unsigned short pci_device_ids[] = { PCI_DEVICE_ID_INTEL_SPT_H_C236, PCI_DEVICE_ID_INTEL_SPT_H_PREMIUM, PCI_DEVICE_ID_INTEL_SPT_H_H110, + PCI_DEVICE_ID_INTEL_SPT_H_H170, + PCI_DEVICE_ID_INTEL_SPT_H_Z170, + PCI_DEVICE_ID_INTEL_SPT_H_Q170, + PCI_DEVICE_ID_INTEL_SPT_H_Q150, + PCI_DEVICE_ID_INTEL_SPT_H_B150, PCI_DEVICE_ID_INTEL_SPT_H_QM170, PCI_DEVICE_ID_INTEL_SPT_H_HM175, PCI_DEVICE_ID_INTEL_SPT_H_QM175, diff --git a/src/soc/intel/skylake/bootblock/report_platform.c b/src/soc/intel/skylake/bootblock/report_platform.c index f79343508b0..de845c78541 100644 --- a/src/soc/intel/skylake/bootblock/report_platform.c +++ b/src/soc/intel/skylake/bootblock/report_platform.c @@ -71,6 +71,11 @@ static struct { { PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM, "Skylake-Y Premium" }, { PCI_DEVICE_ID_INTEL_SPT_H_PREMIUM, "Skylake PCH-H Premium" }, { PCI_DEVICE_ID_INTEL_SPT_H_H110, "Skylake PCH-H H110" }, + { PCI_DEVICE_ID_INTEL_SPT_H_H170, "Skylake PCH-H H170" }, + { PCI_DEVICE_ID_INTEL_SPT_H_Z170, "Skylake PCH-H Z170" }, + { PCI_DEVICE_ID_INTEL_SPT_H_Q170, "Skylake PCH-H Q170" }, + { PCI_DEVICE_ID_INTEL_SPT_H_Q150, "Skylake PCH-H Q150" }, + { PCI_DEVICE_ID_INTEL_SPT_H_B150, "Skylake PCH-H B150" }, { PCI_DEVICE_ID_INTEL_SPT_H_C236, "Skylake PCH-H C236" }, { PCI_DEVICE_ID_INTEL_SPT_H_QM170, "Skylake PCH-H QM170" }, { PCI_DEVICE_ID_INTEL_SPT_H_HM175, "Skylake PCH-H HM175" }, From 5471be69b9168d3dbceac064522522a97ed1a0db Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Mon, 29 Apr 2019 15:05:08 +0200 Subject: [PATCH 172/588] soc/intel/braswell/Makefile.inc: Remove commented-out line cpu_microcode_bins is commented out. Remove this line. BUG=NA TEST=Portwell PQ7-M107 Change-Id: Ic398d232bea84a765fce940ef876916a873e561f Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32510 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/soc/intel/braswell/Makefile.inc | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index a7ed4c53884..a2b7ee5e678 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -52,8 +52,6 @@ smm-y += smihandler.c smm-y += spi.c smm-y += tsc_freq.c -# cpu_microcode_bins += ??? - CPPFLAGS_common += -I$(src)/soc/intel/braswell/ CPPFLAGS_common += -I$(src)/soc/intel/braswell/include CPPFLAGS_common += -I$(call strip_quotes,$(CONFIG_FSP_HEADER_PATH)) From fb0fa7643eab9d81626c375a1b3b8d11138dd979 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 30 Apr 2019 17:27:40 -0600 Subject: [PATCH 173/588] sb/amd/rs780: Use 32 bit variable to avoid truncation The {read,write}_index functions expect a 32 bit value, as do the bitwise operations. Found-by: Coverity Scan #1229584 Signed-off-by: Jacob Garber Change-Id: Idc2bc46c899d5a4e8b089644dca076a88d97dd7c Reviewed-on: https://review.coreboot.org/c/coreboot/+/32528 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/southbridge/amd/rs780/ht.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/southbridge/amd/rs780/ht.c b/src/southbridge/amd/rs780/ht.c index 94df2337c13..8943fc13007 100644 --- a/src/southbridge/amd/rs780/ht.c +++ b/src/southbridge/amd/rs780/ht.c @@ -24,24 +24,24 @@ void avoid_lpc_dma_deadlock(struct device *nb_dev, struct device *sb_dev) { struct device *cpu_f0; - u8 reg; + u32 reg32; cpu_f0 = pcidev_on_root(0x18, 0); set_nbcfg_enable_bits(cpu_f0, 0x68, 3 << 21, 1 << 21); - reg = nbpcie_p_read_index(sb_dev, 0x10); - reg |= 0x100; /* bit9=1 */ - nbpcie_p_write_index(sb_dev, 0x10, reg); + reg32 = nbpcie_p_read_index(sb_dev, 0x10); + reg32 |= 0x100; /* bit9=1 */ + nbpcie_p_write_index(sb_dev, 0x10, reg32); - reg = nbpcie_p_read_index(nb_dev, 0x10); - reg |= 0x100; /* bit9=1 */ - nbpcie_p_write_index(nb_dev, 0x10, reg); + reg32 = nbpcie_p_read_index(nb_dev, 0x10); + reg32 |= 0x100; /* bit9=1 */ + nbpcie_p_write_index(nb_dev, 0x10, reg32); /* Enable NP protocol over PCIE for memory-mapped writes targeting LPC * Set this bit to avoid a deadlock condition. */ - reg = htiu_read_index(nb_dev, 0x6); - reg |= 0x1000000; /* bit26 */ - htiu_write_index(nb_dev, 0x6, reg); + reg32 = htiu_read_index(nb_dev, 0x6); + reg32 |= 0x1000000; /* bit26 */ + htiu_write_index(nb_dev, 0x6, reg32); } static void pcie_init(struct device *dev) From 32f48a2d56af951186538b6f6bcb136736f11254 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 2 May 2019 21:21:42 +0200 Subject: [PATCH 174/588] mb/google: Remove unused 'include ' Change-Id: Ib96c317391745fa5afea785e3c7441124b3fc252 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32547 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/google/beltino/mainboard.c | 3 +-- src/mainboard/google/link/i915.c | 7 +++---- src/mainboard/google/stout/mainboard.c | 6 +++--- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/mainboard/google/beltino/mainboard.c b/src/mainboard/google/beltino/mainboard.c index e0fd105eb13..7bda2f66943 100644 --- a/src/mainboard/google/beltino/mainboard.c +++ b/src/mainboard/google/beltino/mainboard.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -25,8 +24,8 @@ #include #include #include -#include "onboard.h" +#include "onboard.h" void mainboard_suspend_resume(void) { diff --git a/src/mainboard/google/link/i915.c b/src/mainboard/google/link/i915.c index e09785d8257..12d424cde02 100644 --- a/src/mainboard/google/link/i915.c +++ b/src/mainboard/google/link/i915.c @@ -25,19 +25,18 @@ #include #include #include -#include "onboard.h" -#include "ec.h" #include #include -#include #include #include - #include #include #include #include #include + +#include "ec.h" +#include "onboard.h" #include "i915io.h" enum { diff --git a/src/mainboard/google/stout/mainboard.c b/src/mainboard/google/stout/mainboard.c index 5f51a6b8bc1..05de8cb63d8 100644 --- a/src/mainboard/google/stout/mainboard.c +++ b/src/mainboard/google/stout/mainboard.c @@ -22,14 +22,14 @@ #include #include #include -#include "onboard.h" -#include "ec.h" #include -#include #include #include #include +#include "ec.h" +#include "onboard.h" + void mainboard_suspend_resume(void) { /* Stout EC needs to be put back in ACPI mode */ From 6a4a026e13ae7fa981243498df9db41a53a54096 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 29 Apr 2019 16:03:12 -0500 Subject: [PATCH 175/588] purism/librem_skl: remove 13v3 target, clean up Kconfig Remove the Librem 13v3 as a separate board; instead build a single firmware image for the 13 v2/v3 boards. Clean up Kconfig options: - remove entries for 13v3 board - fold entries into a single line where possible - remove redundant MAINBOARD_VERSION option (will default to 1.0) - remove unused microcode length/location (only needed for FSP CAR) Test: build/boot Librem 13 v2/v3 boards with same image Change-Id: Ic09b8ec5c576f4c4c48ef30ee3f60a4c2c286cd3 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32515 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/purism/librem_skl/Kconfig | 38 ++++---------------- src/mainboard/purism/librem_skl/Kconfig.name | 6 +--- 2 files changed, 7 insertions(+), 37 deletions(-) diff --git a/src/mainboard/purism/librem_skl/Kconfig b/src/mainboard/purism/librem_skl/Kconfig index 965318f5650..2372b9d2800 100644 --- a/src/mainboard/purism/librem_skl/Kconfig +++ b/src/mainboard/purism/librem_skl/Kconfig @@ -19,11 +19,8 @@ config IRQ_SLOT_COUNT config VARIANT_DIR string - default "librem13v2" if BOARD_PURISM_LIBREM13_V2 - default "librem13v2" if BOARD_PURISM_LIBREM13_V3 - default "librem15v3" if BOARD_PURISM_LIBREM15_V3 - default "librem13v2" if BOARD_PURISM_LIBREM13_V4 - default "librem15v3" if BOARD_PURISM_LIBREM15_V4 + default "librem13v2" if BOARD_PURISM_LIBREM13_V2 || BOARD_PURISM_LIBREM13_V4 + default "librem15v3" if BOARD_PURISM_LIBREM15_V3 || BOARD_PURISM_LIBREM15_V4 config MAINBOARD_VENDOR string @@ -31,28 +28,16 @@ config MAINBOARD_VENDOR config MAINBOARD_FAMILY string - default "Librem 13" if BOARD_PURISM_LIBREM13_V2 - default "Librem 13" if BOARD_PURISM_LIBREM13_V3 - default "Librem 15" if BOARD_PURISM_LIBREM15_V3 - default "Librem 13" if BOARD_PURISM_LIBREM13_V4 - default "Librem 15" if BOARD_PURISM_LIBREM15_V4 + default "Librem 13" if BOARD_PURISM_LIBREM13_V2 || BOARD_PURISM_LIBREM13_V4 + default "Librem 15" if BOARD_PURISM_LIBREM15_V3 || BOARD_PURISM_LIBREM15_V4 config MAINBOARD_PART_NUMBER string default "Librem 13 v2" if BOARD_PURISM_LIBREM13_V2 - default "Librem 13 v2" if BOARD_PURISM_LIBREM13_V3 default "Librem 15 v3" if BOARD_PURISM_LIBREM15_V3 default "Librem 13 v4" if BOARD_PURISM_LIBREM13_V4 default "Librem 15 v4" if BOARD_PURISM_LIBREM15_V4 -config MAINBOARD_VERSION - string - default "2.0" if BOARD_PURISM_LIBREM13_V2 - default "3.0" if BOARD_PURISM_LIBREM13_V3 - default "3.0" if BOARD_PURISM_LIBREM15_V3 - default "4.0" if BOARD_PURISM_LIBREM13_V4 - default "4.0" if BOARD_PURISM_LIBREM15_V4 - config MAINBOARD_DIR string default "purism/librem_skl" @@ -67,11 +52,8 @@ config MAX_CPUS config VGA_BIOS_ID string - default "8086,1916" if BOARD_PURISM_LIBREM13_V2 - default "8086,1916" if BOARD_PURISM_LIBREM13_V3 - default "8086,1916" if BOARD_PURISM_LIBREM15_V3 - default "8086,5916" if BOARD_PURISM_LIBREM13_V4 - default "8086,5916" if BOARD_PURISM_LIBREM15_V4 + default "8086,1916" if BOARD_PURISM_LIBREM13_V2 || BOARD_PURISM_LIBREM15_V3 + default "8086,5916" if BOARD_PURISM_LIBREM13_V4 || BOARD_PURISM_LIBREM15_V4 config DIMM_MAX int @@ -81,14 +63,6 @@ config DIMM_SPD_SIZE int default 512 -config CPU_MICROCODE_CBFS_LEN - hex - default 0x18000 - -config CPU_MICROCODE_CBFS_LOC - hex - default 0xFFE115A0 - config CBFS_SIZE hex default 0xe00000 diff --git a/src/mainboard/purism/librem_skl/Kconfig.name b/src/mainboard/purism/librem_skl/Kconfig.name index 5b82de74353..b0dac3e3389 100644 --- a/src/mainboard/purism/librem_skl/Kconfig.name +++ b/src/mainboard/purism/librem_skl/Kconfig.name @@ -1,9 +1,5 @@ config BOARD_PURISM_LIBREM13_V2 - bool "Librem 13 v2" - select BOARD_PURISM_BASEBOARD_LIBREM_SKL - -config BOARD_PURISM_LIBREM13_V3 - bool "Librem 13 v3" + bool "Librem 13 v2/v3" select BOARD_PURISM_BASEBOARD_LIBREM_SKL config BOARD_PURISM_LIBREM15_V3 From 9d3fa7a22985a2ae080a8e36c89107691d15174f Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 1 May 2019 18:44:54 -0700 Subject: [PATCH 176/588] spd_bin: Do not depend CONFIG_DIMM_MAX on CONFIG_GENERIC_SPD_BIN I can't claim that I really understand what this code does, but it looks like there are platforms that use code from lib/spd_bin.c without enabling CONFIG_GENERIC_SPD_BIN. Some functions in that file contain references to CONFIG_DIMM_MAX, so that option probably shouldn't depend on CONFIG_GENERIC_SPD_BIN. Change-Id: I041c52b6bd255e9a9920e5a101165ba5fc5fa6f3 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32548 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Kconfig b/src/Kconfig index 05875b63274..b4898bd456f 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -1153,7 +1153,6 @@ config GENERIC_SPD_BIN config DIMM_MAX int default 4 - depends on GENERIC_SPD_BIN help Total number of memory DIMM slots available on motherboard. It is multiplication of number of channel to number of DIMMs per From 7c712bbb6c969ae7014707bfddedd821035a2171 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 1 May 2019 16:51:20 -0700 Subject: [PATCH 177/588] Fix code that would trip -Wtype-limits This patch fixes up all code that would throw a -Wtype-limits warning. This sometimes involves eliminating unnecessary checks, adding a few odd but harmless casts or just pragma'ing out the warning for a whole file -- I tried to find the path of least resistance. I think the overall benefit of the warning outweighs the occasional weirdness. Change-Id: Iacd37eb1fad388d9db7267ceccb03e6dcf1ad0d2 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32537 Reviewed-by: Paul Menzel Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/console/vtxprintf.c | 8 +++++--- src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c | 9 --------- src/drivers/pc80/rtc/mc146818rtc.c | 3 +++ src/drivers/spi/spi_flash.c | 2 +- src/mainboard/google/foster/pmic.c | 16 ---------------- src/mainboard/google/octopus/romstage.c | 2 +- .../google/octopus/variants/baseboard/memory.c | 2 +- src/mainboard/google/smaug/pmic.c | 16 ---------------- src/soc/intel/broadwell/lpc.c | 2 +- src/soc/qualcomm/ipq40xx/qup.c | 3 +-- src/soc/qualcomm/ipq40xx/spi.c | 4 ++-- src/soc/qualcomm/ipq806x/qup.c | 3 +-- src/soc/qualcomm/ipq806x/spi.c | 4 ++-- src/soc/rockchip/common/spi.c | 6 +++--- src/soc/samsung/exynos5420/spi.c | 2 +- src/southbridge/intel/lynxpoint/lpc.c | 2 +- .../amd/agesa/f12/Proc/GNB/Nb/NbSmuLib.c | 1 - .../amd/agesa/f14/Proc/GNB/Nb/NbSmuLib.c | 1 - .../f15tn/Proc/CPU/Family/0x15/TN/cpuF15TnDmi.c | 2 +- .../Proc/IDS/Family/0x15/TN/IdsF15TnAllService.c | 3 +++ .../f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c | 2 +- .../Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c | 3 +++ .../amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c | 2 +- 23 files changed, 32 insertions(+), 66 deletions(-) diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c index 043a1dae376..f42ed6d0776 100644 --- a/src/console/vtxprintf.c +++ b/src/console/vtxprintf.c @@ -56,8 +56,10 @@ static int number(void (*tx_byte)(unsigned char byte, void *data), int count = 0; #ifdef SUPPORT_64BIT_INTS unsigned long long num = inum; + long long snum = num; #else - unsigned long num = (long)inum; + unsigned long num = (unsigned long)inum; + long snum = (long)num; if (num != inum) { /* Alert user to an incorrect result by printing #^!. */ @@ -76,9 +78,9 @@ static int number(void (*tx_byte)(unsigned char byte, void *data), c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if ((signed long long)num < 0) { + if (snum < 0) { sign = '-'; - num = -num; + num = -snum; size--; } else if (type & PLUS) { sign = '+'; diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c index e26701b0991..cdc98e06dec 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c @@ -45,9 +45,6 @@ static efi_return_status_t mp_get_processor_info(const efi_uintn_t processor_number, efi_processor_information *processor_info_buffer) { - if (cpu_index() < 0) - return FSP_DEVICE_ERROR; - if (processor_info_buffer == NULL) return FSP_INVALID_PARAMETER; @@ -71,9 +68,6 @@ static efi_return_status_t mp_startup_all_aps(const efi_ap_procedure procedure, efi_boolean_t ignored3, efi_uintn_t timeout_usec, void *argument) { - if (cpu_index() < 0) - return FSP_DEVICE_ERROR; - if (procedure == NULL) return FSP_INVALID_PARAMETER; @@ -91,9 +85,6 @@ static efi_return_status_t mp_startup_this_ap(const efi_ap_procedure procedure, efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument) { - if (cpu_index() < 0) - return FSP_DEVICE_ERROR; - if (processor_number > get_cpu_count()) return FSP_NOT_FOUND; diff --git a/src/drivers/pc80/rtc/mc146818rtc.c b/src/drivers/pc80/rtc/mc146818rtc.c index 99079b985e2..6e37cd2f784 100644 --- a/src/drivers/pc80/rtc/mc146818rtc.c +++ b/src/drivers/pc80/rtc/mc146818rtc.c @@ -39,6 +39,9 @@ #define LB_CKS_LOC 0 #endif +/* Don't warn for checking >= LB_CKS_RANGE_START even though it may be 0. */ +#pragma GCC diagnostic ignored "-Wtype-limits" + #include #if (defined(__PRE_RAM__) && \ diff --git a/src/drivers/spi/spi_flash.c b/src/drivers/spi/spi_flash.c index fc831c3e9c4..ae1d2efb22e 100644 --- a/src/drivers/spi/spi_flash.c +++ b/src/drivers/spi/spi_flash.c @@ -339,7 +339,7 @@ int spi_flash_generic_probe(const struct spi_slave *spi, printk(BIOS_INFO, "Manufacturer: %02x\n", *idp); /* search the table for matches in shift and id */ - for (i = 0; i < ARRAY_SIZE(flashes); ++i) + for (i = 0; i < (int)ARRAY_SIZE(flashes); ++i) if (flashes[i].shift == shift && flashes[i].idcode == *idp) { /* we have a match, call probe */ if (flashes[i].probe(spi, idp, flash) == 0) { diff --git a/src/mainboard/google/foster/pmic.c b/src/mainboard/google/foster/pmic.c index e3efd34529a..13e2a4743fd 100644 --- a/src/mainboard/google/foster/pmic.c +++ b/src/mainboard/google/foster/pmic.c @@ -34,10 +34,6 @@ struct max77620_init_reg { u8 delay; }; -static struct max77620_init_reg init_list[] = { - /* TODO */ -}; - static void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int delay) { if (i2c_writeb(bus, MAX77620_I2C_ADDR, reg, val)) { @@ -51,20 +47,8 @@ static void pmic_write_reg(unsigned bus, uint8_t reg, uint8_t val, int delay) } } -static void pmic_slam_defaults(unsigned bus) -{ - int i; - for (i = 0; i < ARRAY_SIZE(init_list); i++) { - struct max77620_init_reg *reg = &init_list[i]; - pmic_write_reg(bus, reg->reg, reg->val, reg->delay); - } -} - void pmic_init(unsigned bus) { - /* Restore PMIC POR defaults, in case kernel changed 'em */ - pmic_slam_defaults(bus); - /* Setup/Enable GPIO5 - VDD_CPU_REG_EN */ pmic_write_reg(bus, MAX77620_GPIO5_REG, 0x09, 1); diff --git a/src/mainboard/google/octopus/romstage.c b/src/mainboard/google/octopus/romstage.c index 9d8b94d0b99..ff0354dc10c 100644 --- a/src/mainboard/google/octopus/romstage.c +++ b/src/mainboard/google/octopus/romstage.c @@ -44,7 +44,7 @@ void mainboard_save_dimm_info(void) if (!CONFIG(DRAM_PART_NUM_ALWAYS_IN_CBI)) { /* Fall back on part numbers encoded in lp4cfg array. */ - if (board_id() < CONFIG_DRAM_PART_IN_CBI_BOARD_ID_MIN) { + if ((int)board_id() < CONFIG_DRAM_PART_IN_CBI_BOARD_ID_MIN) { save_dimm_info_by_sku_config(); return; } diff --git a/src/mainboard/google/octopus/variants/baseboard/memory.c b/src/mainboard/google/octopus/variants/baseboard/memory.c index aec2ba2a4f5..fc7c87dcb20 100644 --- a/src/mainboard/google/octopus/variants/baseboard/memory.c +++ b/src/mainboard/google/octopus/variants/baseboard/memory.c @@ -210,7 +210,7 @@ const struct lpddr4_cfg *__weak variant_lpddr4_config(void) if (!CONFIG(DRAM_PART_NUM_ALWAYS_IN_CBI)) { /* Fall back non cbi memory config. */ - if (board_id() < CONFIG_DRAM_PART_IN_CBI_BOARD_ID_MIN) + if ((int)board_id() < CONFIG_DRAM_PART_IN_CBI_BOARD_ID_MIN) return &non_cbi_lp4cfg; } diff --git a/src/mainboard/google/smaug/pmic.c b/src/mainboard/google/smaug/pmic.c index d9dacb7d08b..9add211ccd5 100644 --- a/src/mainboard/google/smaug/pmic.c +++ b/src/mainboard/google/smaug/pmic.c @@ -36,10 +36,6 @@ struct max77620_init_reg { u8 delay; }; -static struct max77620_init_reg init_list[] = { - /* TODO */ -}; - static void pmic_write_reg(unsigned bus, uint8_t chip, uint8_t reg, uint8_t val, int delay) { @@ -66,20 +62,8 @@ static inline void pmic_write_reg_77621(unsigned bus, uint8_t reg, uint8_t val, pmic_write_reg(bus, MAX77621_CPU_I2C_ADDR, reg, val, delay); } -static void pmic_slam_defaults(unsigned bus) -{ - int i; - for (i = 0; i < ARRAY_SIZE(init_list); i++) { - struct max77620_init_reg *reg = &init_list[i]; - pmic_write_reg_77620(bus, reg->reg, reg->val, reg->delay); - } -} - void pmic_init(unsigned bus) { - /* Restore PMIC POR defaults, in case kernel changed 'em */ - pmic_slam_defaults(bus); - /* MAX77620: Set SD0 to 1.0V - VDD_CORE */ pmic_write_reg_77620(bus, MAX77620_SD0_REG, 0x20, 1); pmic_write_reg_77620(bus, MAX77620_VDVSSD0_REG, 0x20, 1); diff --git a/src/soc/intel/broadwell/lpc.c b/src/soc/intel/broadwell/lpc.c index 8438ab45db5..7679724ecec 100644 --- a/src/soc/intel/broadwell/lpc.c +++ b/src/soc/intel/broadwell/lpc.c @@ -502,7 +502,7 @@ static void pch_lpc_add_mmio_resources(struct device *dev) #define LPC_DEFAULT_IO_RANGE_LOWER 0 #define LPC_DEFAULT_IO_RANGE_UPPER 0x1000 -static inline int pch_io_range_in_default(u16 base, u16 size) +static inline int pch_io_range_in_default(int base, int size) { /* Does it start above the range? */ if (base >= LPC_DEFAULT_IO_RANGE_UPPER) diff --git a/src/soc/qualcomm/ipq40xx/qup.c b/src/soc/qualcomm/ipq40xx/qup.c index 9d1f92d48a1..438bd14757c 100644 --- a/src/soc/qualcomm/ipq40xx/qup.c +++ b/src/soc/qualcomm/ipq40xx/qup.c @@ -478,8 +478,7 @@ qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state) qup_return_t ret = QUP_ERR_UNDEFINED; unsigned curr_state = read32(QUP_ADDR(id, QUP_STATE)); - if ((state >= QUP_STATE_RESET && state <= QUP_STATE_PAUSE) - && (curr_state & QUP_STATE_VALID_MASK)) { + if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) { /* * For PAUSE_STATE to RESET_STATE transition, * two writes of 10[binary]) are required for the diff --git a/src/soc/qualcomm/ipq40xx/spi.c b/src/soc/qualcomm/ipq40xx/spi.c index 109eda9fc09..b68e1cb8640 100644 --- a/src/soc/qualcomm/ipq40xx/spi.c +++ b/src/soc/qualcomm/ipq40xx/spi.c @@ -648,8 +648,8 @@ static int spi_ctrlr_setup(const struct spi_slave *slave) { struct ipq_spi_slave *ds = NULL; int i; - unsigned int bus = slave->bus; - unsigned int cs = slave->cs; + int bus = slave->bus; + int cs = slave->cs; if ((bus < BLSP0_SPI) || (bus > BLSP1_SPI) || ((bus == BLSP0_SPI) && (cs > 2)) diff --git a/src/soc/qualcomm/ipq806x/qup.c b/src/soc/qualcomm/ipq806x/qup.c index 872b264cfa5..3ceb84d8815 100644 --- a/src/soc/qualcomm/ipq806x/qup.c +++ b/src/soc/qualcomm/ipq806x/qup.c @@ -379,8 +379,7 @@ qup_return_t qup_set_state(gsbi_id_t gsbi_id, uint32_t state) qup_return_t ret = QUP_ERR_UNDEFINED; unsigned curr_state = read32(QUP_ADDR(gsbi_id, QUP_STATE)); - if ((state >= QUP_STATE_RESET && state <= QUP_STATE_PAUSE) - && (curr_state & QUP_STATE_VALID_MASK)) { + if (state <= QUP_STATE_PAUSE && (curr_state & QUP_STATE_VALID_MASK)) { /* * For PAUSE_STATE to RESET_STATE transition, * two writes of 10[binary]) are required for the diff --git a/src/soc/qualcomm/ipq806x/spi.c b/src/soc/qualcomm/ipq806x/spi.c index 657734524cc..2657b9c574a 100644 --- a/src/soc/qualcomm/ipq806x/spi.c +++ b/src/soc/qualcomm/ipq806x/spi.c @@ -760,8 +760,8 @@ static int spi_ctrlr_setup(const struct spi_slave *slave) { struct ipq_spi_slave *ds = NULL; int i; - unsigned int bus = slave->bus; - unsigned int cs = slave->cs; + int bus = slave->bus; + int cs = slave->cs; /* * IPQ GSBI (Generic Serial Bus Interface) supports SPI Flash diff --git a/src/soc/rockchip/common/spi.c b/src/soc/rockchip/common/spi.c index 98016c0fc9a..e929419a14d 100644 --- a/src/soc/rockchip/common/spi.c +++ b/src/soc/rockchip/common/spi.c @@ -96,7 +96,7 @@ static void rockchip_spi_set_clk(struct rockchip_spi *regs, unsigned int hz) void rockchip_spi_init(unsigned int bus, unsigned int speed_hz) { - assert(bus >= 0 && bus < ARRAY_SIZE(rockchip_spi_slaves)); + assert(bus < ARRAY_SIZE(rockchip_spi_slaves)); struct rockchip_spi *regs = rockchip_spi_slaves[bus].regs; unsigned int ctrlr0 = 0; @@ -134,13 +134,13 @@ void rockchip_spi_init(unsigned int bus, unsigned int speed_hz) void rockchip_spi_set_sample_delay(unsigned int bus, unsigned int delay_ns) { - assert(bus >= 0 && bus < ARRAY_SIZE(rockchip_spi_slaves)); + assert(bus < ARRAY_SIZE(rockchip_spi_slaves)); struct rockchip_spi *regs = rockchip_spi_slaves[bus].regs; unsigned int rsd; /* Rxd Sample Delay */ rsd = DIV_ROUND_CLOSEST(delay_ns * (SPI_SRCCLK_HZ >> 8), 1*GHz >> 8); - assert(rsd >= 0 && rsd <= 3); + assert(rsd <= 3); clrsetbits_le32(®s->ctrlr0, SPI_RXDSD_MASK << SPI_RXDSD_OFFSET, rsd << SPI_RXDSD_OFFSET); } diff --git a/src/soc/samsung/exynos5420/spi.c b/src/soc/samsung/exynos5420/spi.c index 753a24be194..1903f6b3b90 100644 --- a/src/soc/samsung/exynos5420/spi.c +++ b/src/soc/samsung/exynos5420/spi.c @@ -206,7 +206,7 @@ static void spi_ctrlr_release_bus(const struct spi_slave *slave) static int spi_ctrlr_setup(const struct spi_slave *slave) { - ASSERT(slave->bus >= 0 && slave->bus < 3); + ASSERT(slave->bus < 3); struct exynos_spi_slave *eslave; eslave = to_exynos_spi(slave); diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c index e8cad388d53..951c69c11c5 100644 --- a/src/southbridge/intel/lynxpoint/lpc.c +++ b/src/southbridge/intel/lynxpoint/lpc.c @@ -623,7 +623,7 @@ static void pch_lpc_add_mmio_resources(struct device *dev) #define LPC_DEFAULT_IO_RANGE_LOWER 0 #define LPC_DEFAULT_IO_RANGE_UPPER 0x1000 -static inline int pch_io_range_in_default(u16 base, u16 size) +static inline int pch_io_range_in_default(int base, int size) { /* Does it start above the range? */ if (base >= LPC_DEFAULT_IO_RANGE_UPPER) diff --git a/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/NbSmuLib.c b/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/NbSmuLib.c index 37c9ff19bd1..3bf8de5d71c 100644 --- a/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/NbSmuLib.c +++ b/src/vendorcode/amd/agesa/f12/Proc/GNB/Nb/NbSmuLib.c @@ -527,7 +527,6 @@ NbSmuReadEfuseField ( UINT32 Address; UINT16 Shift; ASSERT (Length <= 32); - ASSERT (Chain <= 0xff); Shift = (Offset - (Offset & ~0x7)); Address = 0xFE000000 | (Chain << 12) | (Offset >> 3); Value = NbSmuReadEfuse (Address, StdHeader); diff --git a/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/NbSmuLib.c b/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/NbSmuLib.c index 76401d435c9..bf1396de556 100644 --- a/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/NbSmuLib.c +++ b/src/vendorcode/amd/agesa/f14/Proc/GNB/Nb/NbSmuLib.c @@ -506,7 +506,6 @@ NbSmuReadEfuseField ( UINT32 Address; UINT16 Shift; ASSERT (Length <= 32); - ASSERT (Chain <= 0xff); Shift = (Offset - (Offset & ~0x7)); Address = 0xFE000000 | (Chain << 12) | (Offset >> 3); Value = NbSmuReadEfuse (Address, StdHeader); diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/cpuF15TnDmi.c b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/cpuF15TnDmi.c index 7b7fa0dd91a..b0f98cf01c8 100644 --- a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/cpuF15TnDmi.c +++ b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/cpuF15TnDmi.c @@ -331,7 +331,7 @@ DmiF15TnGetVoltage ( LibAmdMsrRead ((MSR_PSTATE_0 + NumberBoostStates), &MsrData, StdHeader); MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid); - if ((MaxVid >= 0xF8) && (MaxVid <= 0xFF)) { + if ((MaxVid >= 0xF8)) { Voltage = 0; } else { Voltage = (UINT8) ((155000L - (625 * MaxVid) + 5000) / 10000); diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Family/0x15/TN/IdsF15TnAllService.c b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Family/0x15/TN/IdsF15TnAllService.c index 5e76e9a88ac..a7cb9547dc6 100644 --- a/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Family/0x15/TN/IdsF15TnAllService.c +++ b/src/vendorcode/amd/agesa/f15tn/Proc/IDS/Family/0x15/TN/IdsF15TnAllService.c @@ -62,6 +62,9 @@ CODE_GROUP (G3_DXE) RDATA_GROUP (G3_DXE) +/* Don't warn when checking header-defined ranges that may start at 0. */ +#pragma GCC diagnostic ignored "-Wtype-limits" + #define FILECODE PROC_IDS_FAMILY_0X15_TN_IDSF15TNALLSERVICE_FILECODE /** diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c index 45b1b8f4186..6e8e6f06abd 100644 --- a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbDmi.c @@ -287,7 +287,7 @@ DmiF16KbGetVoltage ( LibAmdMsrRead ((MSR_PSTATE_0 + NumberBoostStates), &MsrData, StdHeader); MaxVid = (UINT8) (((PSTATE_MSR *)&MsrData)->CpuVid); - if ((MaxVid >= 0xF8) && (MaxVid <= 0xFF)) { + if ((MaxVid >= 0xF8)) { Voltage = 0; } else { Voltage = (UINT8) ((155000L - (625 * MaxVid) + 5000) / 10000); diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c index fddf8eb4031..94e32a37438 100644 --- a/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c +++ b/src/vendorcode/amd/agesa/f16kb/Proc/IDS/Family/0x16/KB/IdsF16KbAllService.c @@ -63,6 +63,9 @@ CODE_GROUP (G3_DXE) RDATA_GROUP (G3_DXE) +/* Don't warn when checking header-defined ranges that may start at 0. */ +#pragma GCC diagnostic ignored "-Wtype-limits" + #define FILECODE PROC_IDS_FAMILY_0X16_KB_IDSF16KBALLSERVICE_FILECODE /** diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c index 1302396909d..eba8263e345 100644 --- a/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c +++ b/src/vendorcode/amd/agesa/f16kb/Proc/Mem/Ps/mpmaxfreq.c @@ -136,7 +136,7 @@ MemPGetMaxFreqSupported ( UINT16 MaxFreqSupported; UINT16 *SpeedArray; UINT8 DDR3Voltage; - UINT8 CurrentVoltage; + INT8 CurrentVoltage; DIMM_TYPE DimmType; CPU_LOGICAL_ID LogicalCpuid; UINT8 PackageType; From c4ab50cdde4bfd01ec7509012b105c88bcf4c953 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Wed, 1 May 2019 16:48:44 -0700 Subject: [PATCH 178/588] Makefile.inc: Enable -Wtype-limits This patch enables -Wtype-limits for the whole repository, which disallows checking for a condition that must be always true or always false based on type width (e.g. checking whether an unsigned variable is negative or whether a 32-bit integer is larger than 4G). This helps avoid easy to make and hard to find (because they often only affect error paths) mistakes like size_t size = fmap_read_area(...); if (size < 0) die("If only the compiler could've told me to use ssize_t instead"); Change-Id: I19edabfd092d09dad720e3fc47b44838163bfe25 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32536 Reviewed-by: Paul Menzel Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index a9aaaed783b..9860da1b681 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -401,7 +401,7 @@ endif CFLAGS_common += -pipe -g -nostdinc -std=gnu11 CFLAGS_common += -nostdlib -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes CFLAGS_common += -Wwrite-strings -Wredundant-decls -Wno-trigraphs -CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time +CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time -Wtype-limits CFLAGS_common += -fno-common -ffreestanding -fno-builtin -fomit-frame-pointer CFLAGS_common += -ffunction-sections -fdata-sections -fno-pie ifeq ($(CONFIG_COMPILER_GCC),y) From e09caf6428bbda556df7089a46abcf7dd26bb3a3 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Thu, 2 May 2019 17:58:12 -0600 Subject: [PATCH 179/588] soc/amd/stoneyridge: Move acpi_fill_mcfg to northbridge Relocate the function to the more appropriate file. Change-Id: I92a3e8d0461ae228f6c01567db159e2458de5f6b Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32550 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/lpc.c | 13 ------------- src/soc/amd/stoneyridge/northbridge.c | 12 ++++++++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c index 87da9f12711..9a8c8efdeea 100644 --- a/src/soc/amd/stoneyridge/lpc.c +++ b/src/soc/amd/stoneyridge/lpc.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include @@ -326,18 +325,6 @@ static void lpc_enable_resources(struct device *dev) lpc_enable_childrens_resources(dev); } -unsigned long acpi_fill_mcfg(unsigned long current) -{ - - current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, - CONFIG_MMCONF_BASE_ADDRESS, - 0, - 0, - CONFIG_MMCONF_BUS_NUMBER); - - return current; -} - static struct pci_operations lops_pci = { .set_subsystem = pci_dev_set_subsystem, }; diff --git a/src/soc/amd/stoneyridge/northbridge.c b/src/soc/amd/stoneyridge/northbridge.c index 42963c09415..5985832c81e 100644 --- a/src/soc/amd/stoneyridge/northbridge.c +++ b/src/soc/amd/stoneyridge/northbridge.c @@ -176,6 +176,18 @@ static void northbridge_init(struct device *dev) setup_ioapic((u8 *)IO_APIC2_ADDR, CONFIG_MAX_CPUS+1); } +unsigned long acpi_fill_mcfg(unsigned long current) +{ + + current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, + CONFIG_MMCONF_BASE_ADDRESS, + 0, + 0, + CONFIG_MMCONF_BUS_NUMBER); + + return current; +} + static unsigned long acpi_fill_hest(acpi_hest_t *hest) { void *addr, *current; From 1bc04e3c3edf5b1537b4846dea41a530a1b83016 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Thu, 2 May 2019 18:56:54 -0600 Subject: [PATCH 180/588] soc/amd/stoneyridge: Correct bugs in lpc.c Remove the bridge enable step of accessing D14F0x64. This method for enabling the bridge appears to be last present in the SB700 device. Beginning in the SB800 (and all FCH, SoC devices), the enable is in PMxEC[0]. Since the bridge is enabled in bootblock to allow port 80h, there is no need to maintain it in ramstage. Correct the device used for misc. configuration of the LPC bridge. The #defined value removed is 14.0 but the settings are in 14.3. TEST=Boot Grunt, check console and dmesg for errors and warnings BUG=b:131862871 Change-Id: I078be974dc3c78c94cb7c0832518f21bac029ff2 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32551 Tested-by: build bot (Jenkins) Reviewed-by: Richard Spiegel --- src/soc/amd/stoneyridge/lpc.c | 39 ++++++++++++----------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c index 9a8c8efdeea..a838146c846 100644 --- a/src/soc/amd/stoneyridge/lpc.c +++ b/src/soc/amd/stoneyridge/lpc.c @@ -35,31 +35,22 @@ static void lpc_init(struct device *dev) { u8 byte; - u32 dword; - - /* - * Enable the LPC Controller - * SMBus register 0x64 is not defined in public datasheet. - */ - dword = pci_read_config32(SOC_SMBUS_DEV, 0x64); - dword |= 1 << 20; - pci_write_config32(SOC_SMBUS_DEV, 0x64, dword); /* Initialize isa dma */ isa_dma_init(); /* Enable DMA transaction on the LPC bus */ - byte = pci_read_config8(SOC_SMBUS_DEV, LPC_PCI_CONTROL); + byte = pci_read_config8(dev, LPC_PCI_CONTROL); byte |= LEGACY_DMA_EN; - pci_write_config8(SOC_SMBUS_DEV, LPC_PCI_CONTROL, byte); + pci_write_config8(dev, LPC_PCI_CONTROL, byte); /* Disable the timeout mechanism on LPC */ - byte = pci_read_config8(SOC_SMBUS_DEV, LPC_IO_OR_MEM_DECODE_ENABLE); + byte = pci_read_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE); byte &= ~LPC_SYNC_TIMEOUT_COUNT_ENABLE; - pci_write_config8(SOC_SMBUS_DEV, LPC_IO_OR_MEM_DECODE_ENABLE, byte); + pci_write_config8(dev, LPC_IO_OR_MEM_DECODE_ENABLE, byte); /* Disable LPC MSI Capability */ - byte = pci_read_config8(SOC_SMBUS_DEV, LPC_MISC_CONTROL_BITS); + byte = pci_read_config8(dev, LPC_MISC_CONTROL_BITS); /* BIT 1 is not defined in public datasheet. */ byte &= ~(1 << 1); @@ -69,15 +60,15 @@ static void lpc_init(struct device *dev) * interrupt and visit LPC. */ byte &= ~LPC_NOHOG; - pci_write_config8(SOC_SMBUS_DEV, LPC_MISC_CONTROL_BITS, byte); + pci_write_config8(dev, LPC_MISC_CONTROL_BITS, byte); /* * Enable hand-instance of the pulse generator and SPI * controller prefetch of flash. */ - byte = pci_read_config8(SOC_SMBUS_DEV, LPC_HOST_CONTROL); + byte = pci_read_config8(dev, LPC_HOST_CONTROL); byte |= PREFETCH_EN_SPI_FROM_HOST | T_START_ENH; - pci_write_config8(SOC_SMBUS_DEV, LPC_HOST_CONTROL, byte); + pci_write_config8(dev, LPC_HOST_CONTROL, byte); cmos_check_update_date(); @@ -161,9 +152,8 @@ static void lpc_set_resources(struct device *dev) pci_dev_set_resources(dev); } -static void set_child_resource(struct device *child, - u32 *reg, - u32 *reg_x) +static void set_child_resource(struct device *dev, struct device *child, + u32 *reg, u32 *reg_x) { struct resource *res; u32 base, end; @@ -272,7 +262,7 @@ static void set_child_resource(struct device *child, wideio_index = sb_set_wideio_range(base, res->size); if (wideio_index != WIDEIO_RANGE_ERROR) { /* preserve wide IO related bits. */ - *reg_x = pci_read_config32(SOC_LPC_DEV, + *reg_x = pci_read_config32(dev, LPC_IO_OR_MEM_DECODE_ENABLE); printk(BIOS_DEBUG, @@ -308,11 +298,8 @@ static void lpc_enable_childrens_resources(struct device *dev) for (child = link->children; child; child = child->sibling) { if (child->enabled - && (child->path.type == DEVICE_PATH_PNP)) { - set_child_resource(child, - ®, - ®_x); - } + && (child->path.type == DEVICE_PATH_PNP)) + set_child_resource(dev, child, ®, ®_x); } } pci_write_config32(dev, LPC_IO_PORT_DECODE_ENABLE, reg); From e59ae107c2156bcea84a1e5af7ac18a49dabca1b Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Thu, 2 May 2019 13:57:57 +0200 Subject: [PATCH 181/588] soc/apollolake: Add ramstage hook A hook for romstage is already existing but not for ramstage. It's very useful for debugging as it allows to run code for testing purposes by the mainboard. Also, it allows to run configuration code or configure FSP options, which don't have a devicetree option. Change-Id: I9edc543943c5cbc696fc6c615cb77ef68294c980 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/32543 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/intel/apollolake/chip.c | 9 +++++++ .../intel/apollolake/include/soc/ramstage.h | 26 +++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 src/soc/intel/apollolake/include/soc/ramstage.h diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index c3de4ee8023..279551f9e0f 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -50,6 +50,7 @@ #include #include #include +#include #include "chip.h" @@ -762,6 +763,8 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *silupd) /* Set VTD feature according to devicetree */ silconfig->VtdEnable = cfg->enable_vtd; + + mainboard_silicon_init_params(silconfig); } struct chip_operations soc_intel_apollolake_ops = { @@ -879,4 +882,10 @@ static void spi_flash_init_cb(void *unused) fast_spi_init(); } +__weak +void mainboard_silicon_init_params(FSP_S_CONFIG *silconfig) +{ + printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__); +} + BOOT_STATE_INIT_ENTRY(BS_PRE_DEVICE, BS_ON_ENTRY, spi_flash_init_cb, NULL); diff --git a/src/soc/intel/apollolake/include/soc/ramstage.h b/src/soc/intel/apollolake/include/soc/ramstage.h new file mode 100644 index 00000000000..287f2ff9451 --- /dev/null +++ b/src/soc/intel/apollolake/include/soc/ramstage.h @@ -0,0 +1,26 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * (Written by Andrey Petrov for Intel Corp.) + * Copyright (C) 2019 9elements Agency GmbH + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _SOC_APOLLOLAKE_RAMSTAGE_H_ +#define _SOC_APOLLOLAKE_RAMSTAGE_H_ + +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *silconfig); + +#endif /* _SOC_APOLLOLAKE_RAMSTAGE_H_ */ From 7f1e9dbf3a951599cfa0b2decf0bb6540a666cbd Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Thu, 2 May 2019 15:13:31 +0800 Subject: [PATCH 182/588] soc/intel/cannonlake/acpi: Add board level s0ix call back Add board level s0ix call back. Since some driver doesn't care _ON/_OFF method. Add a control method for s0ix usage. BUG=b:129177593 TEST=NA Signed-off-by: Eric Lai Change-Id: I404f388b19355ae89b36d1fb07f9fb4f97eb3b2d Reviewed-on: https://review.coreboot.org/c/coreboot/+/32539 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh --- src/soc/intel/cannonlake/acpi/lpit.asl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/soc/intel/cannonlake/acpi/lpit.asl b/src/soc/intel/cannonlake/acpi/lpit.asl index 85158069b61..93bce2644ec 100644 --- a/src/soc/intel/cannonlake/acpi/lpit.asl +++ b/src/soc/intel/cannonlake/acpi/lpit.asl @@ -14,6 +14,8 @@ * GNU General Public License for more details. */ +External(\_SB.MS0X, MethodObj) + scope(\_SB) { Device(LPID) { @@ -62,12 +64,20 @@ scope(\_SB) */ If(Arg2 == 5) { \_SB.PCI0.LPCB.EC0.S0IX(1) + /* provide board level s0ix hook */ + If (CondRefOf (\_SB.MS0X)) { + \_SB.MS0X(1) + } } /* * Function 6. */ If(Arg2 == 6) { \_SB.PCI0.LPCB.EC0.S0IX(0) + /* provide board level s0ix hook */ + If (CondRefOf (\_SB.MS0X)) { + \_SB.MS0X(0) + } } } Return(Buffer(One) {0x00}) From 6629b4bbf810e5d2e9323651acf8afb2936cf10b Mon Sep 17 00:00:00 2001 From: Karthikeyan Ramasubramanian Date: Wed, 1 May 2019 10:22:22 -0600 Subject: [PATCH 183/588] soc/intel/apollolake: Reset GPI IS & IE registers at ramstage Reset GPI Interrupt status and enable registers from ramstage instead of bootblock so that it applies to devices in field. BUG=b:130593883 BRANCH=octopus TEST=Ensure that the Interrupt status & enable registers are reset during the boot up when the system is brought out of G3, S5 & S3. Ensure that the system boots fine to ChromeOS. Change-Id: Ib11b580ceb23bd1fe789f549b667a8ced2d859a1 Signed-off-by: Karthikeyan Ramasubramanian Reviewed-on: https://review.coreboot.org/c/coreboot/+/32534 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/soc/intel/apollolake/bootblock/bootblock.c | 9 --------- src/soc/intel/apollolake/chip.c | 6 ++++++ 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/soc/intel/apollolake/bootblock/bootblock.c b/src/soc/intel/apollolake/bootblock/bootblock.c index c791378f133..ac6903a9d21 100644 --- a/src/soc/intel/apollolake/bootblock/bootblock.c +++ b/src/soc/intel/apollolake/bootblock/bootblock.c @@ -122,12 +122,3 @@ void bootblock_soc_early_init(void) paging_enable_for_car("pdpt", "pt"); } } - -void bootblock_soc_init(void) -{ - /* - * Clear the GPI interrupt enable & status registers to avoid any - * interrupt storm during the kernel bootup. - */ - gpi_clear_int_cfg(); -} diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index 279551f9e0f..f6880a7f3f1 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -395,6 +395,12 @@ static void soc_init(void *data) * default policy that doesn't honor boards' requirements. */ itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + /* + * Clear the GPI interrupt status and enable registers. These + * registers do not get reset to default state when booting from S5. + */ + gpi_clear_int_cfg(); + fsp_silicon_init(romstage_handoff_is_resume()); /* Restore GPIO IRQ polarities back to previous settings. */ From 78b58a4996d42191f5dc941f9c14fa07228acca1 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Sat, 28 Jul 2018 16:53:16 -0700 Subject: [PATCH 184/588] drivers/intel/fsp2_0: Fix fsp post-init validation Part of this checks whether tolum_base and cbmem_top are the same - however, cbmem_top hasn't been initialised at the point where this call occurs. Change the ordering to fix that. Signed-off-by: Matthew Garrett Change-Id: Ib89e0513bdc35c3751a9d4c2a2789a2836046789 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32530 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Subrata Banik --- src/drivers/intel/fsp2_0/memory_init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c index 985ee3a07f5..b3afb98c4d2 100644 --- a/src/drivers/intel/fsp2_0/memory_init.c +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -310,8 +310,6 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake, post_code(POST_FSP_MEMORY_EXIT); timestamp_add_now(TS_FSP_MEMORY_INIT_END); - fsp_debug_after_memory_init(status); - /* Handle any errors returned by FspMemoryInit */ fsp_handle_reset(status); if (status != FSP_SUCCESS) { @@ -320,6 +318,13 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake, } do_fsp_post_memory_init(s3wake, fsp_version); + + /* + * fsp_debug_after_memory_init() checks whether the end of the tolum + * region is the same as the top of cbmem, so must be called here + * after cbmem has been initialised in do_fsp_post_memory_init(). + */ + fsp_debug_after_memory_init(status); } /* Load the binary into the memory specified by the info header. */ From a06fa32daf216c6fcd35a1412b2c476031191aec Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 4 May 2019 13:05:58 +0200 Subject: [PATCH 185/588] arch/x86: Remove unused file The file is no longer used by any code. Remove it. Change-Id: I73f06cac11201dc37218d352ab995cf4f012c36a Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32584 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/arch/x86/stages.c | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 src/arch/x86/stages.c diff --git a/src/arch/x86/stages.c b/src/arch/x86/stages.c deleted file mode 100644 index b4d0723e168..00000000000 --- a/src/arch/x86/stages.c +++ /dev/null @@ -1,21 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 coresystems GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -static void skip_romstage(void) -{ - asm volatile ( - "jmp __main\n" - ); -} From b4951c92a1070123e3c56571481dc1a20f09657a Mon Sep 17 00:00:00 2001 From: Bluemax <1403092+BlueMax@users.noreply.github.com> Date: Sun, 7 Apr 2019 00:18:42 +0200 Subject: [PATCH 186/588] Documentation: Add MSI MS-7707 Change-Id: Iba38bda9becba9fcffb51afc4756023659f092ef Signed-off-by: Max Blau Reviewed-on: https://review.coreboot.org/c/coreboot/+/32236 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/mainboard/index.md | 4 + .../mainboard/msi/ms7707/J1-flash-protect.jpg | Bin 0 -> 240521 bytes .../msi/ms7707/JSPI1-Winbond-W25Q32BVSIG.jpg | Bin 0 -> 150406 bytes .../mainboard/msi/ms7707/JSPI1-connected.jpg | Bin 0 -> 83025 bytes Documentation/mainboard/msi/ms7707/JSPI1.png | Bin 0 -> 38818 bytes .../mainboard/msi/ms7707/flashlayout.svg | 34 ++++++ Documentation/mainboard/msi/ms7707/ms7707.md | 112 ++++++++++++++++++ 7 files changed, 150 insertions(+) create mode 100644 Documentation/mainboard/msi/ms7707/J1-flash-protect.jpg create mode 100644 Documentation/mainboard/msi/ms7707/JSPI1-Winbond-W25Q32BVSIG.jpg create mode 100644 Documentation/mainboard/msi/ms7707/JSPI1-connected.jpg create mode 100644 Documentation/mainboard/msi/ms7707/JSPI1.png create mode 100644 Documentation/mainboard/msi/ms7707/flashlayout.svg create mode 100644 Documentation/mainboard/msi/ms7707/ms7707.md diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index 7eaf425e209..9af5c80883b 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -70,6 +70,10 @@ The boards in this section are not real mainboards, but emulators. - [T430 / T530 / X230 / W530 common](lenovo/xx30_series.md) - [T431s](lenovo/t431s.md) +## MSI + +- [MS-7707](msi/ms7707/ms7707.md) + ## SiFive - [SiFive HiFive Unleashed](sifive/hifive-unleashed.md) diff --git a/Documentation/mainboard/msi/ms7707/J1-flash-protect.jpg b/Documentation/mainboard/msi/ms7707/J1-flash-protect.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b649d059a81ee610e56b2dd623a10958bb20c81d GIT binary patch literal 240521 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 literal 0 HcmV?d00001 diff --git a/Documentation/mainboard/msi/ms7707/JSPI1-Winbond-W25Q32BVSIG.jpg b/Documentation/mainboard/msi/ms7707/JSPI1-Winbond-W25Q32BVSIG.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7a0df71dd777b06e4b5025cbbc234ab3c573693f GIT binary patch literal 150406 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

-BCZ%&`klyX<*6t}d!tuv# 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 literal 0 HcmV?d00001 diff --git a/Documentation/mainboard/msi/ms7707/JSPI1-connected.jpg b/Documentation/mainboard/msi/ms7707/JSPI1-connected.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d1eed2760ed53549c0dcc8e7a0e60f216993bdcd GIT binary patch literal 83025 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

ZxRd6}^%=7XaE>Q<5NZy%Sx{$**%VwCPiFvf?TZ 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 E02W%n3IG5A literal 0 HcmV?d00001 diff --git a/Documentation/mainboard/msi/ms7707/JSPI1.png b/Documentation/mainboard/msi/ms7707/JSPI1.png new file mode 100644 index 0000000000000000000000000000000000000000..b1eadc28e6866d23a39a05afd1aa4ab862b7fbdc GIT binary patch literal 38818 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 + + + + + image/svg+xml + + + + + + + + IFD + + BIOS + + + + ME + + + GBE + + 0x000000 + 0x001000 + 0x003000 + 0x200000 + 0x400000 + + + + Flash + diff --git a/Documentation/mainboard/msi/ms7707/ms7707.md b/Documentation/mainboard/msi/ms7707/ms7707.md new file mode 100644 index 00000000000..789431872cc --- /dev/null +++ b/Documentation/mainboard/msi/ms7707/ms7707.md @@ -0,0 +1,112 @@ +# MSI MS-7707 V1.1 + +* MSI MS-7707 V1.1 (Medion OEM Akoya P4385D MSN10014555) +* SandyBridge Intel P67 (BD82x6x) +* Winbond 25Q32BV (4MB) +* Fintek F71808A SuperIO +* Intel 82579V Gigabit +* NEC uPD720200 USB 3.0 Host Controller +* IME 7.0.4.1197 + +## Flash chip (Winbond 25Q32BV) +```eval_rst ++---------------------+--------------------+ +| Type | Value | ++=====================+====================+ +| Size | 4 MiB | ++---------------------+--------------------+ +| BIOS range | 2 MiB | ++---------------------+--------------------+ +| Write protection | Yes (via jumper) | ++---------------------+--------------------+ +| Header | Yes (JSPI1) | ++---------------------+--------------------+ +| Package | SOIC-8 | ++---------------------+--------------------+ +| In circuit flashing | Yes | ++---------------------+--------------------+ +| Internal flashing | Yes | ++---------------------+--------------------+ +| Socketed flash | No | ++---------------------+--------------------+ +| Dual BIOS feature | No | ++---------------------+--------------------+ +| ME removable | Yes | ++---------------------+--------------------+ +``` + +## Installation instructions +* The standard method is to only flash the 2MiB BIOS region. In that case it's +not needed to extract blobs from vendor firmware and internal flashing is +sufficient. +* To flash the whole chip (e.g. to disable ME) blobs are needed to build +coreboot. Blobs can be extracted with util/ifdtool from 4MiB full dump image +(see below). Its recommended to include the VGA BIOS as well (4MiB write only). +Kconfig is prepared already if it gets enabled (path and 8086,0102). +``` +coreboot/3rdparty/blobs/mainboard/msi/ms7707 +├── descriptor.bin +├── gbe.bin +├── me.bin +└── vgabios.bin +``` +* Never write a full 4MiB image if blobs are not included. The generated +coreboot.rom file is always 4MiB but the 2MiB flash command below will only +flash the last 2MiB (BIOS) block. +* The J1-Jumper sets the 'Flash Descriptor Override Strap-Pin' and enables +full 4MiB access for internal flasher (read and write). +* **Write BIOS-range** (2MiB) with J1-Jumper=off (as on picture/default + position): +``` +flashrom -p internal:ich_spi_force=yes --noverify-all --ifd -i bios -w coreboot.rom +``` +* **Read full dump** (4MiB) with J1-jumper=on: +``` +flashrom -p internal -r original.rom +``` +* **Write full dump** (4MiB) with J1-Jumper=on: +``` +flashrom -p internal -w coreboot.rom +``` +* After successful flashing turn main power off, wait some seconds to drain +the capacitors, pull the battery and set the JBAT (clrcmos) jumper for some +seconds. Setting the jumper alone is not enough (the Fintek is VBAT backed). +Put all back in place and restart the board. It might need 1-2 AC power cycles +to reinitialize (running at full fan speed - don't panic). +* External flashing has been tested with RPi2 without main power connected. +3.3V provided by RPi2. Read more about flashing methods [here](https://doc.coreboot.org/flash_tutorial/index.html). +* In case of going back to proprietary BIOS create/save cmos settings as early +as possible (do not leave BIOS on first start without saving settings). +The BIOS might corrupt nvram (not cmos!) and leave the system in a dead state +that needs an external flasher to revive. If stuck, reset the Fintek (see +above) and restart the system several times and/or try setting J1 to +temporarily disable ME. + +![](J1-flash-protect.jpg) + +* The JSPI1 header (5×2 2.0mm pitch pin header) for external flashing is +directly connected to the flash chip. Additional 3.3V to /HOLD and /WP is not +needed (internally re-routed already). + +![](JSPI1-Winbond-W25Q32BVSIG.jpg) + +![](JSPI1-connected.jpg) + +![](JSPI1.png) + +## Flash layout + +* The 4MiB flashrom is divided into 4 sections: + +![][flashlayout] + +## Links + +- [BIOS ROM] +- [Fintek F71808A datasheet] +- [Winbond 25Q32BV datasheet] + +[BIOS ROM]: https://www.medion.com/de/servicebackend/_lightbox/treiber_details.php?did=9744 +[Winbond 25Q32BV datasheet]: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf +[Fintek F71808A datasheet]: https://www.alldatasheet.com/datasheet-pdf/pdf/459069/FINTEK/F71808A.html +[flashlayout]: flashlayout.svg From 0a7543db2d9938fe449d800f0b2e61ffefd7b822 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Tue, 19 Feb 2019 23:49:11 +0100 Subject: [PATCH 187/588] inteltool: Add Sunrise Point-LP Skylake PCH IDs Sunrise Point-LP is used on Skylake and KabyLake platforms, but the PCH IDs differ. This commit adds the PCH IDs for Skylake mobile platforms and renames the Kabylake macros to distinguish them. Used Intel documents: - 332995-001EN (I/O datasheet vol. 1) - 332996-002EN (I/O datasheet vol. 2) Change-Id: Id46224fcc44b06c91cbcd6c74a55c95e1de65ec6 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/31506 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/inteltool/gpio.c | 10 +++++++--- util/inteltool/gpio_groups.c | 10 +++++++--- util/inteltool/inteltool.c | 26 +++++++++++++++++--------- util/inteltool/inteltool.h | 10 +++++++--- util/inteltool/pcr.c | 10 +++++++--- util/inteltool/powermgt.c | 10 +++++++--- util/inteltool/rootcmplx.c | 10 +++++++--- util/inteltool/spi.c | 20 ++++++++++++++------ 8 files changed, 73 insertions(+), 33 deletions(-) diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index 41f4df90c86..c946d5c65f0 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -1028,9 +1028,13 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) case PCI_DEVICE_ID_INTEL_CM236: case PCI_DEVICE_ID_INTEL_APL_LPC: case PCI_DEVICE_ID_INTEL_DNV_LPC: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: diff --git a/util/inteltool/gpio_groups.c b/util/inteltool/gpio_groups.c index 8b328a73831..21e2de93d53 100644 --- a/util/inteltool/gpio_groups.c +++ b/util/inteltool/gpio_groups.c @@ -1778,9 +1778,13 @@ void print_gpio_groups(struct pci_dev *const sb) communities = sunrise_communities; pcr_init(sb); break; - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index e89fd3cf22c..40e76464500 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -224,18 +224,26 @@ static const struct { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BAYTRAIL_LPC, "Bay Trail" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_PRE, "Sunrise Point Desktop Engineering Sample" }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE, - "Sunrise Point-LP U Base" }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM, - "Sunrise Point-LP U Premium" }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM, - "Sunrise Point-LP Y Premium" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE, + "Sunrise Point-LP Engineering Sample" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL, + "Sunrise Point-LP U Base/Skylake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL, + "Sunrise Point-LP Y Premium/Skylake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL, + "Sunrise Point-LP U Premium/Skylake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL, + "Sunrise Point-LP U Base/Kabylake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL, + "Sunrise Point-LP Y Premium/Kabylake" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL, + "Sunrise Point-LP U Premium/Kabylake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE, - "Sunrise Point-LP U iHDCP 2.2 Base" }, + "Sunrise Point-LP U iHDCP 2.2 Base/Kabylake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM, - "Sunrise Point-LP U iHDCP 2.2 Premium" }, + "Sunrise Point-LP U iHDCP 2.2 Premium/Kabylake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM, - "Sunrise Point-LP Y iHDCP 2.2 Premium" }, + "Sunrise Point-LP Y iHDCP 2.2 Premium/Kabylake" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H110, "H110" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_H170, "H170" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_Z170, "Z170" }, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index 25b3a1504ad..6aec3879c2e 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -145,9 +145,13 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_P2SB 0xa120 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_PRE 0xa141 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_SATA 0x9d03 -#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE 0x9d53 -#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM 0x9d58 -#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM 0x9d56 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE 0x9d41 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL 0x9d43 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL 0x9d46 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL 0x9d48 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL 0x9d53 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL 0x9d56 +#define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL 0x9d58 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE 0x9d50 #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM 0x9d4e #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM 0x9d4b diff --git a/util/inteltool/pcr.c b/util/inteltool/pcr.c index a296b19be40..c969620fa03 100644 --- a/util/inteltool/pcr.c +++ b/util/inteltool/pcr.c @@ -79,9 +79,13 @@ void pcr_init(struct pci_dev *const sb) switch (sb->device_id) { case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_PRE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: diff --git a/util/inteltool/powermgt.c b/util/inteltool/powermgt.c index 359180093d6..675e31a1da4 100644 --- a/util/inteltool/powermgt.c +++ b/util/inteltool/powermgt.c @@ -745,9 +745,13 @@ int print_pmbase(struct pci_dev *sb, struct pci_access *pacc) case PCI_DEVICE_ID_INTEL_C224: case PCI_DEVICE_ID_INTEL_C226: case PCI_DEVICE_ID_INTEL_H81: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: diff --git a/util/inteltool/rootcmplx.c b/util/inteltool/rootcmplx.c index ddcd8e3ed3a..70d7cbe3ed3 100644 --- a/util/inteltool/rootcmplx.c +++ b/util/inteltool/rootcmplx.c @@ -112,9 +112,13 @@ int print_rcba(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_C224: case PCI_DEVICE_ID_INTEL_C226: case PCI_DEVICE_ID_INTEL_H81: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: diff --git a/util/inteltool/spi.c b/util/inteltool/spi.c index cb38c555872..da5533deaa6 100644 --- a/util/inteltool/spi.c +++ b/util/inteltool/spi.c @@ -175,9 +175,13 @@ int print_bioscntl(struct pci_dev *sb) case PCI_DEVICE_ID_INTEL_C224: case PCI_DEVICE_ID_INTEL_C226: case PCI_DEVICE_ID_INTEL_H81: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: @@ -309,9 +313,13 @@ int print_spibar(struct pci_dev *sb) { case PCI_DEVICE_ID_INTEL_C224: case PCI_DEVICE_ID_INTEL_C226: case PCI_DEVICE_ID_INTEL_H81: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM: - case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_SKL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_BASE_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_PREM_KBL: + case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_PREM_KBL: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_BASE: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_U_IHDCP_PREM: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_Y_IHDCP_PREM: From 45b824d69433a630147dd690f6b5993bc2d4bb76 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 5 May 2019 17:37:49 +0200 Subject: [PATCH 188/588] src: Remove unused include Change-Id: I2f142cc80692e60eb0f81f57339a247f6ef4a524 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32611 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/apple/macbook21/romstage.c | 1 - src/mainboard/asus/p5gc-mx/romstage.c | 1 - src/mainboard/asus/p5qpl-am/romstage.c | 1 - src/mainboard/getac/p470/romstage.c | 1 - src/mainboard/ibase/mb899/romstage.c | 1 - src/mainboard/intel/dcp847ske/early_southbridge.c | 1 - src/mainboard/kontron/986lcd-m/romstage.c | 1 - src/mainboard/lenovo/t60/romstage.c | 1 - src/mainboard/lenovo/z61t/romstage.c | 1 - src/mainboard/roda/rk886ex/romstage.c | 1 - src/northbridge/intel/haswell/raminit.c | 1 - src/northbridge/intel/i945/early_init.c | 1 - src/northbridge/intel/i945/raminit.c | 1 - src/northbridge/intel/pineview/romstage.c | 1 - src/northbridge/intel/sandybridge/raminit.c | 1 - src/northbridge/intel/sandybridge/raminit_mrc.c | 1 - 16 files changed, 16 deletions(-) diff --git a/src/mainboard/apple/macbook21/romstage.c b/src/mainboard/apple/macbook21/romstage.c index c056ac8fcbf..468cffb7d93 100644 --- a/src/mainboard/apple/macbook21/romstage.c +++ b/src/mainboard/apple/macbook21/romstage.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/asus/p5gc-mx/romstage.c b/src/mainboard/asus/p5gc-mx/romstage.c index beb276c7daf..08379f78a1c 100644 --- a/src/mainboard/asus/p5gc-mx/romstage.c +++ b/src/mainboard/asus/p5gc-mx/romstage.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/asus/p5qpl-am/romstage.c b/src/mainboard/asus/p5qpl-am/romstage.c index 4174981ac2e..bd6bfc6ee7d 100644 --- a/src/mainboard/asus/p5qpl-am/romstage.c +++ b/src/mainboard/asus/p5qpl-am/romstage.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/getac/p470/romstage.c b/src/mainboard/getac/p470/romstage.c index d643b12f8a0..aaa3422c02a 100644 --- a/src/mainboard/getac/p470/romstage.c +++ b/src/mainboard/getac/p470/romstage.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/ibase/mb899/romstage.c b/src/mainboard/ibase/mb899/romstage.c index 7e3b7dba686..9cb1144b80c 100644 --- a/src/mainboard/ibase/mb899/romstage.c +++ b/src/mainboard/ibase/mb899/romstage.c @@ -16,7 +16,6 @@ // __PRE_RAM__ means: use "unsigned" for device, not a struct. #include -#include #include #include #include diff --git a/src/mainboard/intel/dcp847ske/early_southbridge.c b/src/mainboard/intel/dcp847ske/early_southbridge.c index 46f9a94e9e7..778525f320c 100644 --- a/src/mainboard/intel/dcp847ske/early_southbridge.c +++ b/src/mainboard/intel/dcp847ske/early_southbridge.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include diff --git a/src/mainboard/kontron/986lcd-m/romstage.c b/src/mainboard/kontron/986lcd-m/romstage.c index 3d01eb1e0fe..b85bd6883dc 100644 --- a/src/mainboard/kontron/986lcd-m/romstage.c +++ b/src/mainboard/kontron/986lcd-m/romstage.c @@ -16,7 +16,6 @@ /* __PRE_RAM__ means: use "unsigned" for device, not a struct. */ #include -#include #include #include #include diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c index ea207e80a92..0c7c0cfb2d5 100644 --- a/src/mainboard/lenovo/t60/romstage.c +++ b/src/mainboard/lenovo/t60/romstage.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/lenovo/z61t/romstage.c b/src/mainboard/lenovo/z61t/romstage.c index 0d68faca2c6..47a52db39b0 100644 --- a/src/mainboard/lenovo/z61t/romstage.c +++ b/src/mainboard/lenovo/z61t/romstage.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/roda/rk886ex/romstage.c b/src/mainboard/roda/rk886ex/romstage.c index e85da1f4804..2bdad276c1d 100644 --- a/src/mainboard/roda/rk886ex/romstage.c +++ b/src/mainboard/roda/rk886ex/romstage.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index fddada4ba0a..96dc94e7d20 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c index a9de844f150..274296d4827 100644 --- a/src/northbridge/intel/i945/early_init.c +++ b/src/northbridge/intel/i945/early_init.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "i945.h" #include diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index 1e8cf655814..0cf03ae605c 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "raminit.h" #include "i945.h" #include "chip.h" diff --git a/src/northbridge/intel/pineview/romstage.c b/src/northbridge/intel/pineview/romstage.c index bdb685b2526..a3e6c391721 100644 --- a/src/northbridge/intel/pineview/romstage.c +++ b/src/northbridge/intel/pineview/romstage.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index cea3f2cd70d..e60c37875bd 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index a68ae49c7cf..ea3590f78d3 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "raminit.h" #include "pei_data.h" From 1a6b5c23a1f5892c7a461d6a6ef547e2abe524f4 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Thu, 25 Apr 2019 19:11:13 +0800 Subject: [PATCH 189/588] vboot: remove use of GoogleBinaryBlockHeader Remove use of deprecated GoogleBinaryBlockHeader struct, and replace with vb2_gbb_header. BUG=b:124141368, chromium:954774 TEST=make clean && make test-abuild BRANCH=none Change-Id: Iee3bd877cb1791a689efdeabda324f43f7d0c6f2 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32455 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/security/vboot/gbb.c | 13 ++++++++----- src/security/vboot/gbb.h | 2 +- src/security/vboot/vboot_common.c | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/security/vboot/gbb.c b/src/security/vboot/gbb.c index 8f57c798b2c..52930336663 100644 --- a/src/security/vboot/gbb.c +++ b/src/security/vboot/gbb.c @@ -13,17 +13,19 @@ * GNU General Public License for more details. */ +#define NEED_VB20_INTERNALS /* Peeking into vb2_gbb_header */ + #include #include #include -#include #include #include +#include #define GBB_FMAP_REGION_NAME "GBB" /* Copy of GBB header read from boot media. */ -static GoogleBinaryBlockHeader gbb_header; +static struct vb2_gbb_header gbb_header; /* * Read "GBB" region from SPI flash to obtain GBB header and validate @@ -45,13 +47,14 @@ static int gbb_init(void) return 1; if (rdev_readat(&gbb_rdev, &gbb_header, 0, - sizeof(GoogleBinaryBlockHeader)) != - sizeof(GoogleBinaryBlockHeader)) { + sizeof(struct vb2_gbb_header)) != + sizeof(struct vb2_gbb_header)) { printk(BIOS_ERR, "%s: Failure to read GBB header!\n", __func__); return 1; } - if (memcmp(gbb_header.signature, GBB_SIGNATURE, GBB_SIGNATURE_SIZE)) { + if (memcmp(gbb_header.signature, VB2_GBB_SIGNATURE, + VB2_GBB_SIGNATURE_SIZE)) { printk(BIOS_ERR, "%s: Signature check failed!\n", __func__); return 1; } diff --git a/src/security/vboot/gbb.h b/src/security/vboot/gbb.h index 550548d6131..389242a3a2c 100644 --- a/src/security/vboot/gbb.h +++ b/src/security/vboot/gbb.h @@ -18,7 +18,7 @@ #include -/* In order to use GBB_FLAG_* macros from vboot, include gbb_header.h. */ +/* In order to use VB2_GBB_FLAG_* macros from vboot, include vb2_api.h. */ /* * Read flags field from GBB header. diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 3dddc765564..493cb888984 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -18,12 +18,12 @@ #include #include #include -#include #include #include #include #include #include +#include int vboot_named_region_device(const char *name, struct region_device *rdev) { @@ -42,7 +42,7 @@ int vboot_can_enable_udc(void) if (!vboot_developer_mode_enabled()) return 0; /* Enable if GBB flag is set */ - if (gbb_is_flag_set(GBB_FLAG_ENABLE_UDC)) + if (gbb_is_flag_set(VB2_GBB_FLAG_ENABLE_UDC)) return 1; /* Enable if VBNV flag is set */ if (vbnv_udc_enable_flag()) From 8c0acc5515f8a381cf2d33c61951d229d4ef358a Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Fri, 3 May 2019 16:08:07 +0800 Subject: [PATCH 190/588] mb/google/sarien: Fine tune SD card D3 cold timing A13 and A15 need to set low before H12 reset. Change the program sequence for fit HW requirement. BUG=b:131876963 TEST=boot up and check SD card functional Signed-off-by: Eric Lai Change-Id: I2f1752070f24833aaaab75dea8493caf2ed7f157 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32552 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Duncan Laurie --- src/mainboard/google/sarien/variants/sarien/gpio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/mainboard/google/sarien/variants/sarien/gpio.c b/src/mainboard/google/sarien/variants/sarien/gpio.c index 53a937ff39a..ec3b44d4a38 100644 --- a/src/mainboard/google/sarien/variants/sarien/gpio.c +++ b/src/mainboard/google/sarien/variants/sarien/gpio.c @@ -31,9 +31,9 @@ static const struct pad_config gpio_table[] = { /* CLKOUT_LPC1 */ PAD_NC(GPP_A10, NONE), /* PME# */ PAD_NC(GPP_A11, NONE), /* BM_BUSY# */ PAD_NC(GPP_A12, NONE), -/* SUSWARN# */ PAD_CFG_GPO(GPP_A13, 0, DEEP), /* Card reader D3 cold */ + /* ESPI_RESET# */ -/* SUSACK# */ PAD_CFG_GPO(GPP_A15, 0, DEEP), /* Card reader D3 cold */ + /* SD_1P8_SEL */ PAD_NC(GPP_A16, NONE), /* SD_PWR_EN# */ PAD_NC(GPP_A17, NONE), /* ISH_GP0 */ PAD_NC(GPP_A18, NONE), @@ -224,9 +224,12 @@ static const struct pad_config gpio_table[] = { /* Early pad configuration in bootblock */ static const struct pad_config early_gpio_table[] = { -/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 0, DEEP), /* D3 cold RST */ +/* SUSWARN# */ PAD_CFG_GPO(GPP_A13, 0, DEEP), /* Card reader D3 cold */ +/* SUSACK# */ PAD_CFG_GPO(GPP_A15, 0, DEEP), /* Card reader D3 cold */ /* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* SERVOTX_UART */ /* UART2_TXD */ PAD_CFG_NF(GPP_C21, NONE, DEEP, NF1), /* SERVORX_UART */ +/* SSD RESET pin will stay low first */ +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 0, DEEP), /* D3 cold RST */ /* I2C4_SDA */ PAD_CFG_NF(GPP_H8, NONE, DEEP, NF1), /* I2C_SDA_H1 */ /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* DMIC_DATA1 */ PAD_CFG_GPI_APIC(GPP_D18, NONE, PLTRST, @@ -236,9 +239,8 @@ static const struct pad_config early_gpio_table[] = { /* CPU_GP0 */ PAD_CFG_GPI(GPP_E3, NONE, DEEP), /* MEM_INTERLEAVED */ /* SATALED# */ PAD_CFG_GPI(GPP_E8, NONE, DEEP), /* RECOVERY# */ /* DDPD_HPD2 */ PAD_CFG_GPI(GPP_E15, NONE, DEEP), /* H1_FLASH_WP */ -/* SSD RESET need to stay low first */ -/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ /* PWRBTN# */ PAD_CFG_NF(GPD3, UP_20K, DEEP, NF1), /* SIO_PWRBTN# */ +/* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 1, DEEP), /* D3 cold RST */ }; const struct pad_config *variant_gpio_table(size_t *num) From 0c0a9810c7d00524a8bcebacc36496b590de3a79 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Mon, 29 Apr 2019 15:17:06 +0800 Subject: [PATCH 191/588] mb/google/sarien: Turn off camera power when s0ix Turn off camera power when s0ix for power saving. BUG=b:129177593 TEST= measure camera power comsumption is 0mV under s0ix Change-Id: I5a9b7ec1e95cc9931d8d5f2dc1254805c9d0ffed Signed-off-by: Eric Lai Reviewed-on: https://review.coreboot.org/c/coreboot/+/32519 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Duncan Laurie --- src/mainboard/google/sarien/dsdt.asl | 2 ++ .../arcada/include/variant/acpi/mainboard.asl | 28 +++++++++++++++++++ .../sarien/include/variant/acpi/mainboard.asl | 28 +++++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl create mode 100644 src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl diff --git a/src/mainboard/google/sarien/dsdt.asl b/src/mainboard/google/sarien/dsdt.asl index e5b0ccad2e0..58e0704deb3 100644 --- a/src/mainboard/google/sarien/dsdt.asl +++ b/src/mainboard/google/sarien/dsdt.asl @@ -40,6 +40,8 @@ DefinitionBlock( #include #include } + /* Per board variant mainboard hooks. */ + #include } #if CONFIG(CHROMEOS) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl new file mode 100644 index 00000000000..7b252c7f1cc --- /dev/null +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CAM_EN GPP_B11 /* Active low */ + +/* Method called from LPIT prior to enter s0ix state */ +Method (MS0X, 1) +{ + If (Arg0) { + /* Turn off camera power */ + \_SB.PCI0.STXS (CAM_EN) + } Else { + /* Turn on camera power */ + \_SB.PCI0.CTXS (CAM_EN) + } +} diff --git a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl new file mode 100644 index 00000000000..7b252c7f1cc --- /dev/null +++ b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define CAM_EN GPP_B11 /* Active low */ + +/* Method called from LPIT prior to enter s0ix state */ +Method (MS0X, 1) +{ + If (Arg0) { + /* Turn off camera power */ + \_SB.PCI0.STXS (CAM_EN) + } Else { + /* Turn on camera power */ + \_SB.PCI0.CTXS (CAM_EN) + } +} From 0de835d52ee8f44a32f2b483d1e4a1c9a172e4c6 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Mon, 6 May 2019 06:12:33 +0000 Subject: [PATCH 192/588] Update vboot submodule to upstream master Updating from commit id 304aa429: 2019-03-12 10:38:56 -0700 - (futility: updater: Unit test for preserving sections using FMAP flags) to commit id e7edff66: 2019-05-03 07:02:32 -0700 - (vboot: implement DISPLAY_INIT context and SD flag) This brings in 45 new commits. Change-Id: I7493e43bddc553f9724de46130ccb4cb44e18573 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32612 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- 3rdparty/vboot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/vboot b/3rdparty/vboot index 304aa429c1a..e7edff6653e 160000 --- a/3rdparty/vboot +++ b/3rdparty/vboot @@ -1 +1 @@ -Subproject commit 304aa429c1a04cda3ab2ce37b9e31af84405bfca +Subproject commit e7edff6653e16ed915c3ad12234d133d1ef4dcc9 From ba092a9ab6e87fec458d6557d0114147e2713686 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sun, 5 May 2019 13:23:25 +0300 Subject: [PATCH 193/588] mb/apple/macbookair4_2: Correct internal video port selection The MacBook Air 4,2 uses eDP, according to the schematics. Change-Id: Ifc98eab343fd89b8512e92e01fddf34ef8447d5f Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/32606 Reviewed-by: Angel Pons Reviewed-by: Nico Huber Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- src/mainboard/apple/macbookair4_2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/apple/macbookair4_2/Kconfig b/src/mainboard/apple/macbookair4_2/Kconfig index 82f120ab08e..4b2ee8fdc82 100644 --- a/src/mainboard/apple/macbookair4_2/Kconfig +++ b/src/mainboard/apple/macbookair4_2/Kconfig @@ -12,7 +12,7 @@ config BOARD_SPECIFIC_OPTIONS select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_BD82X6X select SYSTEM_TYPE_LAPTOP - select GFX_GMA_INTERNAL_IS_LVDS + select GFX_GMA_INTERNAL_IS_EDP select MAINBOARD_HAS_LIBGFXINIT config MAINBOARD_DIR From 1bc7b6e1350c4ba8eee10a859d10150b15b7b7e9 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 5 May 2019 16:29:41 +0200 Subject: [PATCH 194/588] {gm45,pineview,sandybridge,x4x}: Use {full,system}_reset() function Use already defined system_reset() and full_reset() functions. Change-Id: Ic29fab70cf7f23d49c3eeeb97c984c523f973972 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32608 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/gm45/early_reset.c | 8 +++----- src/northbridge/intel/pineview/raminit.c | 7 +++---- src/northbridge/intel/sandybridge/romstage.c | 7 +++---- src/northbridge/intel/x4x/raminit.c | 5 +---- 4 files changed, 10 insertions(+), 17 deletions(-) diff --git a/src/northbridge/intel/gm45/early_reset.c b/src/northbridge/intel/gm45/early_reset.c index 9f919cfbcd0..3f095a256ff 100644 --- a/src/northbridge/intel/gm45/early_reset.c +++ b/src/northbridge/intel/gm45/early_reset.c @@ -16,8 +16,9 @@ #include #include +#include #include -#include + #include "gm45.h" void gm45_early_reset(void/*const timings_t *const timings*/) @@ -63,8 +64,5 @@ void gm45_early_reset(void/*const timings_t *const timings*/) /* Normally, we would set this after successful raminit. */ MCHBAR32(DCC_MCHBAR) |= (1 << 19); - /* Perform system reset through CF9 interface. */ - outb(0x02, 0xcf9); /* Set system reset bit. */ - outb(0x06, 0xcf9); /* Set CPU reset bit, too. */ - halt(); + system_reset(); } diff --git a/src/northbridge/intel/pineview/raminit.c b/src/northbridge/intel/pineview/raminit.c index 48bca36faa2..144905fb92e 100644 --- a/src/northbridge/intel/pineview/raminit.c +++ b/src/northbridge/intel/pineview/raminit.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -1744,10 +1745,8 @@ static void sdram_checkreset(void) } pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, pmcon2); pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, pmcon3); - if (reset) { - printk(BIOS_DEBUG, "Power cycle reset...\n"); - outb(0xe, 0xcf9); - } + if (reset) + full_reset(); } static void sdram_dradrb(struct sysinfo *s) diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c index 3fab3be85d4..43316a2f223 100644 --- a/src/northbridge/intel/sandybridge/romstage.c +++ b/src/northbridge/intel/sandybridge/romstage.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -47,10 +48,8 @@ void mainboard_romstage_entry(unsigned long bist) { int s3resume = 0; - if (MCHBAR16(SSKPD) == 0xCAFE) { - outb(0x6, 0xcf9); - halt (); - } + if (MCHBAR16(SSKPD) == 0xCAFE) + system_reset(); if (bist == 0) enable_lapic(); diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c index 4d5bdce9ac5..60d3b55531b 100644 --- a/src/northbridge/intel/x4x/raminit.c +++ b/src/northbridge/intel/x4x/raminit.c @@ -22,7 +22,6 @@ #include #include #include -#include #if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) #include /* smbus_read_byte */ #else @@ -624,9 +623,7 @@ static void checkreset_ddr2(int boot_path) reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf0); pci_write_config8(PCI_DEV(0, 0, 0), 0xf0, reg8 | (1 << 2)); - printk(BIOS_DEBUG, "Reset...\n"); - outb(0xe, 0xcf9); - asm ("hlt"); + full_reset(); } pmcon2 |= 0x80; pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, pmcon2); From 66b35bad88807fa18a5ade87283fdb5ffef538f0 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 5 May 2019 16:35:55 +0200 Subject: [PATCH 195/588] mb/lenovo/x60: Use system_reset() Change-Id: I4515d8d14629741f3bf49e9459d7d57c18d321ce Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32609 Tested-by: build bot (Jenkins) Reviewed-by: Alexander Couzens Reviewed-by: Nico Huber --- src/mainboard/lenovo/x60/romstage.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c index 95192f733bf..ea93707ce95 100644 --- a/src/mainboard/lenovo/x60/romstage.c +++ b/src/mainboard/lenovo/x60/romstage.c @@ -19,6 +19,7 @@ #include #include +#include #include #include #include @@ -28,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -198,8 +198,7 @@ void mainboard_romstage_entry(unsigned long bist) if (MCHBAR16(SSKPD) == 0xCAFE) { printk(BIOS_DEBUG, "Soft reset detected, rebooting properly.\n"); - outb(0x6, 0xcf9); - halt(); + system_reset(); } /* Perform some early chipset initialization required From a842d3ee6a191322f47be49f17338073120778b8 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 16:26:25 +0200 Subject: [PATCH 196/588] intel/fsp1_1: Drop unused, weak raminit() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5d155df1d589fc8d7462f46e87275bd6efae0a7f Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32587 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph Reviewed-by: Frans Hendriks Reviewed-by: Michał Żygowski --- src/drivers/intel/fsp1_1/romstage.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index ebb6a6678bf..bfed1213cd6 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -343,13 +343,6 @@ __weak int mrc_cache_stash_data(int type, uint32_t version, return -1; } -/* Transition RAM from off or self-refresh to active */ -__weak void raminit(struct romstage_params *params) -{ - post_code(POST_MEM_PREINIT_PREP_START); - die("ERROR - No RAM initialization specified!\n"); -} - /* Display the memory configuration */ __weak void report_memory_config(void) { From 16895c529c5e44b3c7725ef92f9119ba03397576 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 16:29:17 +0200 Subject: [PATCH 197/588] intel/fsp1_1: Drop `boot_mode` from `pei_data` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was only used locally. Change-Id: Iaaad760e8ceca62655f5448c30846cf11959e8e1 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32588 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Michał Żygowski --- src/drivers/intel/fsp1_1/raminit.c | 5 +++-- src/drivers/intel/fsp1_1/romstage.c | 5 ++--- src/soc/intel/braswell/include/soc/pei_data.h | 3 --- src/soc/intel/skylake/include/soc/pei_data.h | 1 - 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/drivers/intel/fsp1_1/raminit.c b/src/drivers/intel/fsp1_1/raminit.c index 8405c943aa3..4ea1f00897e 100644 --- a/src/drivers/intel/fsp1_1/raminit.c +++ b/src/drivers/intel/fsp1_1/raminit.c @@ -28,6 +28,7 @@ void raminit(struct romstage_params *params) { + const bool s3wake = params->power_state->prev_sleep_state == ACPI_S3; const EFI_GUID bootldr_tolum_guid = FSP_BOOTLOADER_TOLUM_HOB_GUID; EFI_HOB_RESOURCE_DESCRIPTOR *cbmem_root; FSP_INFO_HEADER *fsp_header; @@ -81,7 +82,7 @@ void raminit(struct romstage_params *params) /* Zero fill RT Buffer data and start populating fields. */ memset(&fsp_rt_common_buffer, 0, sizeof(fsp_rt_common_buffer)); pei_ptr = params->pei_data; - if (pei_ptr->boot_mode == ACPI_S3) { + if (s3wake) { fsp_rt_common_buffer.BootMode = BOOT_ON_S3_RESUME; } else if (pei_ptr->saved_data != NULL) { fsp_rt_common_buffer.BootMode = @@ -158,7 +159,7 @@ void raminit(struct romstage_params *params) /* Migrate CAR data */ printk(BIOS_DEBUG, "0x%p: cbmem_top\n", cbmem_top()); - if (pei_ptr->boot_mode != ACPI_S3) { + if (!s3wake) { cbmem_initialize_empty_id_size(CBMEM_ID_FSP_RESERVED_MEMORY, fsp_reserved_bytes); } else if (cbmem_initialize_id_size(CBMEM_ID_FSP_RESERVED_MEMORY, diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index bfed1213cd6..17bd638290e 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -101,7 +101,6 @@ void romstage_common(struct romstage_params *params) timestamp_add_now(TS_BEFORE_INITRAM); pei_data = params->pei_data; - pei_data->boot_mode = params->power_state->prev_sleep_state; s3wake = params->power_state->prev_sleep_state == ACPI_S3; if (CONFIG(ELOG_BOOT_COUNT) && !s3wake) @@ -129,7 +128,7 @@ void romstage_common(struct romstage_params *params) params->pei_data->saved_data = rdev_mmap_full(&rdev); /* Assume boot device is memory mapped. */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); - } else if (params->pei_data->boot_mode == ACPI_S3) { + } else if (s3wake) { /* Waking from S3 and no cache. */ printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n"); @@ -149,7 +148,7 @@ void romstage_common(struct romstage_params *params) if (CONFIG(CACHE_MRC_SETTINGS)) { printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save, pei_data->data_to_save_size); - if ((params->pei_data->boot_mode != ACPI_S3) + if (!s3wake && (params->pei_data->data_to_save_size != 0) && (params->pei_data->data_to_save != NULL)) mrc_cache_stash_data(MRC_TRAINING_DATA, diff --git a/src/soc/intel/braswell/include/soc/pei_data.h b/src/soc/intel/braswell/include/soc/pei_data.h index 50aabed66e8..7ea83ba8dbc 100644 --- a/src/soc/intel/braswell/include/soc/pei_data.h +++ b/src/soc/intel/braswell/include/soc/pei_data.h @@ -44,9 +44,6 @@ struct pei_data { uint8_t spd_ch0_config; uint8_t spd_ch1_config; - /* System state information */ - int boot_mode; - /* Fast boot and S3 resume MRC data */ int saved_data_size; const void *saved_data; diff --git a/src/soc/intel/skylake/include/soc/pei_data.h b/src/soc/intel/skylake/include/soc/pei_data.h index 02e04c6c023..7406a3322e9 100644 --- a/src/soc/intel/skylake/include/soc/pei_data.h +++ b/src/soc/intel/skylake/include/soc/pei_data.h @@ -41,7 +41,6 @@ typedef void ABI_X86(*tx_byte_func)(unsigned char byte); struct pei_data { uint32_t pei_version; - int boot_mode; int ec_present; /* Console output function */ From 99e836c843e6a8536348d5cc9581b5a17512a263 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 7 May 2019 15:35:40 +0000 Subject: [PATCH 198/588] Revert "Makefile.inc: Enable -Wtype-limits" This reverts commit c4ab50cdde4bfd01ec7509012b105c88bcf4c953. Reason for revert: vboot recently was changed so that -Wtype-limits fails, and that was just brought upstream. Since vboot internals are more likely to be used elsewhere while -Wtype-limits is less critical, revert this until vboot is resolved, then bring -Wtype-limits back again. Change-Id: I9cce10462b9e57189513fa49e11fd27ebe35ba51 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32670 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index 9860da1b681..a9aaaed783b 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -401,7 +401,7 @@ endif CFLAGS_common += -pipe -g -nostdinc -std=gnu11 CFLAGS_common += -nostdlib -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes CFLAGS_common += -Wwrite-strings -Wredundant-decls -Wno-trigraphs -CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time -Wtype-limits +CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time CFLAGS_common += -fno-common -ffreestanding -fno-builtin -fomit-frame-pointer CFLAGS_common += -ffunction-sections -fdata-sections -fno-pie ifeq ($(CONFIG_COMPILER_GCC),y) From 66318aad07e6810065bc0668f4a1f34b7cb77687 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 16:59:20 +0200 Subject: [PATCH 199/588] intel/fsp1_1: Move MRC cache pointers into `romstage_params` These are part of a common concept and not SoC specific. Change-Id: I9cb218d7825bd06a138f7f5d9e2b68e86077a3ec Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32589 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph Reviewed-by: Frans Hendriks --- .../intel/fsp1_1/include/fsp/romstage.h | 10 ++++++++ src/drivers/intel/fsp1_1/raminit.c | 12 ++++----- src/drivers/intel/fsp1_1/romstage.c | 25 ++++++++----------- src/soc/intel/braswell/include/soc/pei_data.h | 9 ------- src/soc/intel/skylake/include/soc/pei_data.h | 9 ------- src/soc/intel/skylake/pei_data.c | 9 ------- src/soc/intel/skylake/romstage/romstage.c | 6 +++++ 7 files changed, 32 insertions(+), 48 deletions(-) diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index d608484999f..4e95dadadfc 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -18,6 +18,7 @@ #ifndef _COMMON_ROMSTAGE_H_ #define _COMMON_ROMSTAGE_H_ +#include #include #include #include @@ -32,6 +33,15 @@ struct romstage_params { struct chipset_power_state *power_state; struct pei_data *pei_data; void *chipset_context; + + /* Fast boot and S3 resume MRC data */ + size_t saved_data_size; + const void *saved_data; + bool disable_saved_data; + + /* New save data from MRC */ + size_t data_to_save_size; + const void *data_to_save; }; /* diff --git a/src/drivers/intel/fsp1_1/raminit.c b/src/drivers/intel/fsp1_1/raminit.c index 4ea1f00897e..726cc26a0c3 100644 --- a/src/drivers/intel/fsp1_1/raminit.c +++ b/src/drivers/intel/fsp1_1/raminit.c @@ -47,7 +47,6 @@ void raminit(struct romstage_params *params) u32 *mrc_hob; u32 fsp_reserved_bytes; MEMORY_INIT_UPD *original_params; - struct pei_data *pei_ptr; EFI_STATUS status; VPD_DATA_REGION *vpd_ptr; UPD_DATA_REGION *upd_ptr; @@ -81,10 +80,9 @@ void raminit(struct romstage_params *params) /* Zero fill RT Buffer data and start populating fields. */ memset(&fsp_rt_common_buffer, 0, sizeof(fsp_rt_common_buffer)); - pei_ptr = params->pei_data; if (s3wake) { fsp_rt_common_buffer.BootMode = BOOT_ON_S3_RESUME; - } else if (pei_ptr->saved_data != NULL) { + } else if (params->saved_data != NULL) { fsp_rt_common_buffer.BootMode = BOOT_ASSUMING_NO_CONFIGURATION_CHANGES; } else { @@ -94,7 +92,7 @@ void raminit(struct romstage_params *params) fsp_rt_common_buffer.BootLoaderTolumSize = cbmem_overhead_size(); /* Get any board specific changes */ - fsp_memory_init_params.NvsBufferPtr = (void *)pei_ptr->saved_data; + fsp_memory_init_params.NvsBufferPtr = (void *)params->saved_data; fsp_memory_init_params.RtBufferPtr = &fsp_rt_common_buffer; fsp_memory_init_params.HobListPtr = &hob_list_ptr; @@ -221,7 +219,7 @@ void raminit(struct romstage_params *params) } hob_ptr.Raw = get_next_guid_hob(&mrc_guid, hob_list_ptr); if (hob_ptr.Raw == NULL) { - if (params->pei_data->saved_data == NULL) { + if (params->saved_data == NULL) { printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n"); fsp_verification_failure = 1; } @@ -295,8 +293,8 @@ void raminit(struct romstage_params *params) "Memory Configuration Data Hob not present\n"); else if (!vboot_recovery_mode_enabled()) { /* Do not save MRC data in recovery path */ - pei_ptr->data_to_save = GET_GUID_HOB_DATA(mrc_hob); - pei_ptr->data_to_save_size = ALIGN( + params->data_to_save = GET_GUID_HOB_DATA(mrc_hob); + params->data_to_save_size = ALIGN( ((u32)GET_HOB_LENGTH(mrc_hob)), 16); } } diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 17bd638290e..87fd1a4c01f 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -94,13 +94,11 @@ void romstage_common(struct romstage_params *params) { bool s3wake; struct region_device rdev; - struct pei_data *pei_data; post_code(0x32); timestamp_add_now(TS_BEFORE_INITRAM); - pei_data = params->pei_data; s3wake = params->power_state->prev_sleep_state == ACPI_S3; if (CONFIG(ELOG_BOOT_COUNT) && !s3wake) @@ -111,9 +109,9 @@ void romstage_common(struct romstage_params *params) post_code(0x33); /* Check recovery and MRC cache */ - params->pei_data->saved_data_size = 0; - params->pei_data->saved_data = NULL; - if (!params->pei_data->disable_saved_data) { + params->saved_data_size = 0; + params->saved_data = NULL; + if (!params->disable_saved_data) { if (vboot_recovery_mode_enabled()) { /* Recovery mode does not use MRC cache */ printk(BIOS_DEBUG, @@ -123,9 +121,8 @@ void romstage_common(struct romstage_params *params) params->fsp_version, &rdev))) { /* MRC cache found */ - params->pei_data->saved_data_size = - region_device_sz(&rdev); - params->pei_data->saved_data = rdev_mmap_full(&rdev); + params->saved_data_size = region_device_sz(&rdev); + params->saved_data = rdev_mmap_full(&rdev); /* Assume boot device is memory mapped. */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); } else if (s3wake) { @@ -146,15 +143,15 @@ void romstage_common(struct romstage_params *params) /* Save MRC output */ if (CONFIG(CACHE_MRC_SETTINGS)) { - printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", - pei_data->data_to_save, pei_data->data_to_save_size); + printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n", + params->data_to_save, params->data_to_save_size); if (!s3wake - && (params->pei_data->data_to_save_size != 0) - && (params->pei_data->data_to_save != NULL)) + && (params->data_to_save_size != 0) + && (params->data_to_save != NULL)) mrc_cache_stash_data(MRC_TRAINING_DATA, params->fsp_version, - params->pei_data->data_to_save, - params->pei_data->data_to_save_size); + params->data_to_save, + params->data_to_save_size); } /* Save DIMM information */ diff --git a/src/soc/intel/braswell/include/soc/pei_data.h b/src/soc/intel/braswell/include/soc/pei_data.h index 7ea83ba8dbc..df18dc087aa 100644 --- a/src/soc/intel/braswell/include/soc/pei_data.h +++ b/src/soc/intel/braswell/include/soc/pei_data.h @@ -43,15 +43,6 @@ struct pei_data { void *spd_data_ch1; uint8_t spd_ch0_config; uint8_t spd_ch1_config; - - /* Fast boot and S3 resume MRC data */ - int saved_data_size; - const void *saved_data; - int disable_saved_data; - - /* New save data from MRC */ - int data_to_save_size; - void *data_to_save; }; typedef struct pei_data PEI_DATA; diff --git a/src/soc/intel/skylake/include/soc/pei_data.h b/src/soc/intel/skylake/include/soc/pei_data.h index 7406a3322e9..5ea2190b8e1 100644 --- a/src/soc/intel/skylake/include/soc/pei_data.h +++ b/src/soc/intel/skylake/include/soc/pei_data.h @@ -80,16 +80,7 @@ struct pei_data { uint8_t dqs_map[2][8]; uint16_t RcompResistor[3]; uint16_t RcompTarget[5]; - /* Data read from flash and passed into MRC */ - const void *saved_data; - int saved_data_size; - /* Disable use of saved data (can be set by mainboard) */ - int disable_saved_data; - - /* Data from MRC that should be saved to flash */ - void *data_to_save; - int data_to_save_size; int mem_cfg_id; } __packed; diff --git a/src/soc/intel/skylake/pei_data.c b/src/soc/intel/skylake/pei_data.c index 203a1d8e367..7d314a106fd 100644 --- a/src/soc/intel/skylake/pei_data.c +++ b/src/soc/intel/skylake/pei_data.c @@ -33,16 +33,7 @@ static void ABI_X86 send_to_console(unsigned char b) void soc_fill_pei_data(struct pei_data *pei_data) { - const struct device *dev; - const struct soc_intel_skylake_config *config; - /* Set the parameters for MemoryInit */ - dev = dev_find_slot(0, PCH_DEVFN_LPC); - config = dev->chip_info; - pei_data->pei_version = PEI_VERSION; pei_data->tx_byte = &send_to_console; - - /* Force a full memory train if RMT is enabled */ - pei_data->disable_saved_data = config->Rmt; } diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index 0501b04493c..8ec08c2d0f4 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -46,6 +46,12 @@ void soc_pre_ram_init(struct romstage_params *params) /* Prepare to initialize memory */ soc_fill_pei_data(params->pei_data); + + const struct device *const dev = pcidev_path_on_root(PCH_DEVFN_LPC); + const struct soc_intel_skylake_config *const config = + dev ? dev->chip_info : NULL; + /* Force a full memory train if RMT is enabled */ + params->disable_saved_data = config && config->Rmt; } /* UPD parameters to be initialized before MemoryInit */ From 9b5b9e46b9342500a411514e62032fa3edb565a2 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:06:06 +0200 Subject: [PATCH 200/588] mb/intel/kunimitsu: Refactor to get rid of `pei_data` The SoC specific `struct pei_data` was filled with values that were later only consumed by the mainboard code again. Avoid jumping through this hoop and fill FSP UPDs directly. Change-Id: Ibc013ccea9f83ef29f22fe2da4c0d12096308636 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32590 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- src/mainboard/intel/kunimitsu/Makefile.inc | 3 -- src/mainboard/intel/kunimitsu/pei_data.c | 29 ------------------- src/mainboard/intel/kunimitsu/romstage.c | 30 ++++---------------- src/mainboard/intel/kunimitsu/spd/spd.c | 20 ++++++------- src/mainboard/intel/kunimitsu/spd/spd.h | 2 ++ src/mainboard/intel/kunimitsu/spd/spd_util.c | 2 -- 6 files changed, 17 insertions(+), 69 deletions(-) delete mode 100644 src/mainboard/intel/kunimitsu/pei_data.c diff --git a/src/mainboard/intel/kunimitsu/Makefile.inc b/src/mainboard/intel/kunimitsu/Makefile.inc index dc4b83c0bb5..3330a0aab81 100644 --- a/src/mainboard/intel/kunimitsu/Makefile.inc +++ b/src/mainboard/intel/kunimitsu/Makefile.inc @@ -18,8 +18,6 @@ subdirs-y += spd bootblock-y += bootblock_mainboard.c -romstage-y += pei_data.c - bootblock-$(CONFIG_CHROMEOS) += chromeos.c verstage-$(CONFIG_CHROMEOS) += chromeos.c romstage-$(CONFIG_CHROMEOS) += chromeos.c @@ -28,7 +26,6 @@ ramstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c ramstage-y += mainboard.c -ramstage-y += pei_data.c ramstage-y += ramstage.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c diff --git a/src/mainboard/intel/kunimitsu/pei_data.c b/src/mainboard/intel/kunimitsu/pei_data.c deleted file mode 100644 index bfc40c27485..00000000000 --- a/src/mainboard/intel/kunimitsu/pei_data.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "boardid.h" -#include "spd/spd.h" - -void mainboard_fill_pei_data(struct pei_data *pei_data) -{ - mainboard_fill_dq_map_data(&pei_data->dq_map); - mainboard_fill_dqs_map_data(&pei_data->dqs_map); - mainboard_fill_rcomp_res_data(&pei_data->RcompResistor); - mainboard_fill_rcomp_strength_data(&pei_data->RcompTarget); -} diff --git a/src/mainboard/intel/kunimitsu/romstage.c b/src/mainboard/intel/kunimitsu/romstage.c index 1c6f5a2cd34..f25f88b4dd6 100644 --- a/src/mainboard/intel/kunimitsu/romstage.c +++ b/src/mainboard/intel/kunimitsu/romstage.c @@ -15,20 +15,13 @@ * GNU General Public License for more details. */ -#include #include -#include -#include #include #include "gpio.h" #include "spd/spd.h" void mainboard_romstage_entry(struct romstage_params *params) { - params->pei_data->mem_cfg_id = get_spd_index(); - /* Fill out PEI DATA */ - mainboard_fill_pei_data(params->pei_data); - mainboard_fill_spd_data(params->pei_data); /* Initialize memory */ romstage_common(params); } @@ -36,24 +29,11 @@ void mainboard_romstage_entry(struct romstage_params *params) void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params) { - if (params->pei_data->spd_data[0][0][0] != 0) { - memory_params->MemorySpdPtr00 = - (UINT32)(params->pei_data->spd_data[0][0]); - memory_params->MemorySpdPtr10 = - (UINT32)(params->pei_data->spd_data[1][0]); - } - memcpy(memory_params->DqByteMapCh0, params->pei_data->dq_map[0], - sizeof(params->pei_data->dq_map[0])); - memcpy(memory_params->DqByteMapCh1, params->pei_data->dq_map[1], - sizeof(params->pei_data->dq_map[1])); - memcpy(memory_params->DqsMapCpu2DramCh0, params->pei_data->dqs_map[0], - sizeof(params->pei_data->dqs_map[0])); - memcpy(memory_params->DqsMapCpu2DramCh1, params->pei_data->dqs_map[1], - sizeof(params->pei_data->dqs_map[1])); - memcpy(memory_params->RcompResistor, params->pei_data->RcompResistor, - sizeof(params->pei_data->RcompResistor)); - memcpy(memory_params->RcompTarget, params->pei_data->RcompTarget, - sizeof(params->pei_data->RcompTarget)); + spd_memory_init_params(memory_params); + mainboard_fill_dq_map_data(&memory_params->DqByteMapCh0); + mainboard_fill_dqs_map_data(&memory_params->DqsMapCpu2DramCh0); + mainboard_fill_rcomp_res_data(&memory_params->RcompResistor); + mainboard_fill_rcomp_strength_data(&memory_params->RcompTarget); memory_params->MemorySpdDataLen = SPD_LEN; memory_params->DqPinsInterleaved = FALSE; } diff --git a/src/mainboard/intel/kunimitsu/spd/spd.c b/src/mainboard/intel/kunimitsu/spd/spd.c index 8656d4bc170..bebb544a4d5 100644 --- a/src/mainboard/intel/kunimitsu/spd/spd.c +++ b/src/mainboard/intel/kunimitsu/spd/spd.c @@ -16,8 +16,9 @@ #include #include -#include +#include #include +#include #include #include "spd.h" @@ -73,20 +74,19 @@ static void mainboard_print_spd_info(uint8_t spd[]) } } -/* Copy SPD data for on-board memory */ -void mainboard_fill_spd_data(struct pei_data *pei_data) +/* Fill SPD pointers for on-board memory */ +void spd_memory_init_params(MEMORY_INIT_UPD *memory_params) { uintptr_t spd_data; spd_data = mainboard_get_spd_data(); - memcpy(pei_data->spd_data[0][0], (void *)spd_data, SPD_LEN); - - if (mainboard_has_dual_channel_mem()) - memcpy(pei_data->spd_data[1][0], (void *)spd_data, SPD_LEN); - /* Make sure a valid SPD was found */ - if (pei_data->spd_data[0][0][0] == 0) + if (*(uint8_t *)spd_data == 0) die("Invalid SPD data."); - mainboard_print_spd_info(pei_data->spd_data[0][0]); + memory_params->MemorySpdPtr00 = spd_data; + if (mainboard_has_dual_channel_mem()) + memory_params->MemorySpdPtr10 = spd_data; + + mainboard_print_spd_info((uint8_t *)spd_data); } diff --git a/src/mainboard/intel/kunimitsu/spd/spd.h b/src/mainboard/intel/kunimitsu/spd/spd.h index f53c9ec9fac..22d371f4bc1 100644 --- a/src/mainboard/intel/kunimitsu/spd/spd.h +++ b/src/mainboard/intel/kunimitsu/spd/spd.h @@ -16,6 +16,7 @@ #ifndef MAINBOARD_SPD_H +#include #include #include "../gpio.h" @@ -53,6 +54,7 @@ static inline int get_spd_index(void) { }; return (gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios))); } +void spd_memory_init_params(MEMORY_INIT_UPD *memory_params); void mainboard_fill_dq_map_data(void *dq_map_ptr); void mainboard_fill_dqs_map_data(void *dqs_map_ptr); void mainboard_fill_rcomp_res_data(void *rcomp_ptr); diff --git a/src/mainboard/intel/kunimitsu/spd/spd_util.c b/src/mainboard/intel/kunimitsu/spd/spd_util.c index fc0581cb24d..b173628e291 100644 --- a/src/mainboard/intel/kunimitsu/spd/spd_util.c +++ b/src/mainboard/intel/kunimitsu/spd/spd_util.c @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include "boardid.h" #include "spd.h" From f98f8ebb8cb43f17c8d244f2c4cce2e257355e37 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:06:06 +0200 Subject: [PATCH 201/588] mb/intel/saddlebrook: Refactor to get rid of `pei_data` The SoC specific `struct pei_data` was filled with values that were later only consumed by the mainboard code again. Avoid jumping through this hoop and fill FSP UPDs directly. Change-Id: I399dd89f85ccea43fdf90bd895e71324f4b409cc Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32591 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- src/mainboard/intel/saddlebrook/Makefile.inc | 1 - src/mainboard/intel/saddlebrook/pei_data.c | 27 ------------------- src/mainboard/intel/saddlebrook/romstage.c | 20 +++----------- .../intel/saddlebrook/spd/spd_util.c | 2 -- 4 files changed, 4 insertions(+), 46 deletions(-) delete mode 100644 src/mainboard/intel/saddlebrook/pei_data.c diff --git a/src/mainboard/intel/saddlebrook/Makefile.inc b/src/mainboard/intel/saddlebrook/Makefile.inc index 63889af078c..683462b9de0 100644 --- a/src/mainboard/intel/saddlebrook/Makefile.inc +++ b/src/mainboard/intel/saddlebrook/Makefile.inc @@ -17,6 +17,5 @@ subdirs-y += spd bootblock-y += bootblock.c -romstage-y += pei_data.c ramstage-y += ramstage.c diff --git a/src/mainboard/intel/saddlebrook/pei_data.c b/src/mainboard/intel/saddlebrook/pei_data.c deleted file mode 100644 index ac4ce95723c..00000000000 --- a/src/mainboard/intel/saddlebrook/pei_data.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "spd/spd.h" - -void mainboard_fill_pei_data(struct pei_data *pei_data) -{ - mainboard_fill_dq_map_data(&pei_data->dq_map); - mainboard_fill_dqs_map_data(&pei_data->dqs_map); - mainboard_fill_rcomp_res_data(&pei_data->RcompResistor); - mainboard_fill_rcomp_strength_data(&pei_data->RcompTarget); -} diff --git a/src/mainboard/intel/saddlebrook/romstage.c b/src/mainboard/intel/saddlebrook/romstage.c index d19629cf9ed..48d39db309c 100644 --- a/src/mainboard/intel/saddlebrook/romstage.c +++ b/src/mainboard/intel/saddlebrook/romstage.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include "spd/spd.h" @@ -38,8 +36,6 @@ void car_mainboard_pre_console_init(void) void mainboard_romstage_entry(struct romstage_params *params) { post_code(0x31); - /* Fill out PEI DATA */ - mainboard_fill_pei_data(params->pei_data); romstage_common(params); } @@ -67,18 +63,10 @@ void mainboard_memory_init_params( * should be set in the FSP flash image and should not need to be * changed. */ - memcpy(memory_params->DqByteMapCh0, params->pei_data->dq_map[0], - sizeof(params->pei_data->dq_map[0])); - memcpy(memory_params->DqByteMapCh1, params->pei_data->dq_map[1], - sizeof(params->pei_data->dq_map[1])); - memcpy(memory_params->DqsMapCpu2DramCh0, params->pei_data->dqs_map[0], - sizeof(params->pei_data->dqs_map[0])); - memcpy(memory_params->DqsMapCpu2DramCh1, params->pei_data->dqs_map[1], - sizeof(params->pei_data->dqs_map[1])); - memcpy(memory_params->RcompResistor, params->pei_data->RcompResistor, - sizeof(params->pei_data->RcompResistor)); - memcpy(memory_params->RcompTarget, params->pei_data->RcompTarget, - sizeof(params->pei_data->RcompTarget)); + mainboard_fill_dq_map_data(&memory_params->DqByteMapCh0); + mainboard_fill_dqs_map_data(&memory_params->DqsMapCpu2DramCh0); + mainboard_fill_rcomp_res_data(&memory_params->RcompResistor); + mainboard_fill_rcomp_strength_data(&memory_params->RcompTarget); /* update spd length*/ memory_params->MemorySpdDataLen = blk.len; diff --git a/src/mainboard/intel/saddlebrook/spd/spd_util.c b/src/mainboard/intel/saddlebrook/spd/spd_util.c index 2c26d787d7f..5055d9a3af7 100644 --- a/src/mainboard/intel/saddlebrook/spd/spd_util.c +++ b/src/mainboard/intel/saddlebrook/spd/spd_util.c @@ -15,8 +15,6 @@ #include #include -#include -#include #include "spd.h" void mainboard_fill_dq_map_data(void *dq_map_ptr) From ec562161cd2265c924482835fd2ab32c13ba587e Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:17:40 +0200 Subject: [PATCH 202/588] soc/intel/bsw: Move memory init values into `romstage.h` `chip.h` is usually used as devicetree interface. Change-Id: Ied30927d68927b86758a84ccf3f5fbd8cce632f1 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32592 Reviewed-by: Patrick Georgi Reviewed-by: Matt DeVillier Reviewed-by: Frans Hendriks Tested-by: build bot (Jenkins) --- src/mainboard/google/cyan/romstage.c | 1 - src/mainboard/intel/strago/romstage.c | 1 - src/soc/intel/braswell/chip.h | 3 --- src/soc/intel/braswell/include/soc/romstage.h | 4 ++++ 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mainboard/google/cyan/romstage.c b/src/mainboard/google/cyan/romstage.c index aa20593d5f0..5470b9c4653 100644 --- a/src/mainboard/google/cyan/romstage.c +++ b/src/mainboard/google/cyan/romstage.c @@ -16,7 +16,6 @@ #include #include -#include /* All FSP specific code goes in this block */ void mainboard_romstage_entry(struct romstage_params *rp) diff --git a/src/mainboard/intel/strago/romstage.c b/src/mainboard/intel/strago/romstage.c index 0f3067ea819..ba0ff7b85e7 100644 --- a/src/mainboard/intel/strago/romstage.c +++ b/src/mainboard/intel/strago/romstage.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "onboard.h" #include diff --git a/src/soc/intel/braswell/chip.h b/src/soc/intel/braswell/chip.h index bb06dd595a9..5a00328f4df 100644 --- a/src/soc/intel/braswell/chip.h +++ b/src/soc/intel/braswell/chip.h @@ -32,9 +32,6 @@ #define SVID_CONFIG3 3 #define SVID_PMIC_CONFIG 8 -#define MEM_DDR3 0 -#define MEM_LPDDR3 1 - enum lpe_clk_src { LPE_CLK_SRC_XTAL, LPE_CLK_SRC_PLL, diff --git a/src/soc/intel/braswell/include/soc/romstage.h b/src/soc/intel/braswell/include/soc/romstage.h index 8fa9c8a713c..2512430f754 100644 --- a/src/soc/intel/braswell/include/soc/romstage.h +++ b/src/soc/intel/braswell/include/soc/romstage.h @@ -34,4 +34,8 @@ void set_max_freq(void); void program_base_addresses(void); int chipset_prev_sleep_state(struct chipset_power_state *ps); +/* Values for FSP's PcdMemoryTypeEnable */ +#define MEM_DDR3 0 +#define MEM_LPDDR3 1 + #endif /* _SOC_ROMSTAGE_H_ */ From 85f0b051ba441dead63a4a14f4f20d49581fea0e Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:06:06 +0200 Subject: [PATCH 203/588] mb/google/cyan: Refactor to get rid of `pei_data` The SoC specific `struct pei_data` was filled with values that were later only consumed by the mainboard code again. Avoid jumping through this hoop and fill FSP UPDs directly. The provided solution locates the SPD data in CBFS again to fill SMBIOS tables. This is not perfect. OTOH, this code isn't mainboard specific and doesn't belong here anyway. Change-Id: Ib6103d5b9550846fe17c926631a013ff80b9598f Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32593 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- src/mainboard/google/cyan/romstage.c | 17 ++----- src/mainboard/google/cyan/spd/spd.c | 64 ++++++++++++++---------- src/mainboard/google/cyan/spd/spd_util.h | 3 ++ 3 files changed, 44 insertions(+), 40 deletions(-) diff --git a/src/mainboard/google/cyan/romstage.c b/src/mainboard/google/cyan/romstage.c index 5470b9c4653..c877e420551 100644 --- a/src/mainboard/google/cyan/romstage.c +++ b/src/mainboard/google/cyan/romstage.c @@ -17,13 +17,11 @@ #include #include +#include "spd/spd_util.h" + /* All FSP specific code goes in this block */ void mainboard_romstage_entry(struct romstage_params *rp) { - struct pei_data *ps = rp->pei_data; - - mainboard_fill_spd_data(ps); - /* Call back into chipset code with platform values updated. */ romstage_common(rp); } @@ -31,16 +29,7 @@ void mainboard_romstage_entry(struct romstage_params *rp) void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params) { - /* Update SPD data */ - if (CONFIG(BOARD_GOOGLE_CYAN)) { - memory_params->PcdMemoryTypeEnable = MEM_DDR3; - memory_params->PcdMemorySpdPtr = - (u32)params->pei_data->spd_data_ch0; - } else - memory_params->PcdMemoryTypeEnable = MEM_LPDDR3; - - memory_params->PcdMemChannel0Config = params->pei_data->spd_ch0_config; - memory_params->PcdMemChannel1Config = params->pei_data->spd_ch1_config; + spd_memory_init_params(memory_params); /* Variant-specific memory params */ variant_memory_init_params(memory_params); diff --git a/src/mainboard/google/cyan/spd/spd.c b/src/mainboard/google/cyan/spd/spd.c index af694a43395..7c66e947fc1 100644 --- a/src/mainboard/google/cyan/spd/spd.c +++ b/src/mainboard/google/cyan/spd/spd.c @@ -40,11 +40,24 @@ __weak uint8_t get_ramid(void) return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); } -static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual) +static void *get_spd_pointer(int *dual) { + char *spd_file; + size_t spd_file_len; + int total_spds; int ram_id = 0; int spd_index = 0; + /* Find the SPD data in CBFS. */ + spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, + &spd_file_len); + if (!spd_file) + die("SPD data not found."); + + if (spd_file_len < SPD_PAGE_LEN) + die("Missing SPD data."); + total_spds = spd_file_len / SPD_PAGE_LEN; + ram_id = get_ramid(); printk(BIOS_DEBUG, "ram_id=%d, total_spds: %d\n", ram_id, total_spds); @@ -54,33 +67,20 @@ static void *get_spd_pointer(char *spd_file_content, int total_spds, int *dual) return NULL; } /* Return the serial product data for the RAM */ - return &spd_file_content[SPD_PAGE_LEN * spd_index]; + return &spd_file[SPD_PAGE_LEN * spd_index]; } /* Copy SPD data for on-board memory */ -void mainboard_fill_spd_data(struct pei_data *ps) +void spd_memory_init_params(MEMORY_INIT_UPD *memory_params) { - char *spd_file; - size_t spd_file_len; void *spd_content; int dual_channel = 0; - /* Find the SPD data in CBFS. */ - spd_file = cbfs_boot_map_with_leak("spd.bin", CBFS_TYPE_SPD, - &spd_file_len); - if (!spd_file) - die("SPD data not found."); - - if (spd_file_len < SPD_PAGE_LEN) - die("Missing SPD data."); - /* * Both channels are always present in SPD data. Always use matched * DIMMs so use the same SPD data for each DIMM. */ - spd_content = get_spd_pointer(spd_file, - spd_file_len / SPD_PAGE_LEN, - &dual_channel); + spd_content = get_spd_pointer(&dual_channel); if (CONFIG(DISPLAY_SPD_DATA) && spd_content != NULL) { printk(BIOS_DEBUG, "SPD Data:\n"); hexdump(spd_content, SPD_PAGE_LEN); @@ -94,21 +94,27 @@ void mainboard_fill_spd_data(struct pei_data *ps) * 2=DimmDisabled */ if (spd_content != NULL) { - ps->spd_data_ch0 = spd_content; - ps->spd_ch0_config = 1; + memory_params->PcdMemChannel0Config = 1; printk(BIOS_DEBUG, "Channel 0 DIMM soldered down\n"); if (dual_channel) { printk(BIOS_DEBUG, "Channel 1 DIMM soldered down\n"); - ps->spd_data_ch1 = spd_content; - ps->spd_ch1_config = 1; + memory_params->PcdMemChannel1Config = 1; } else { printk(BIOS_DEBUG, "Channel 1 DIMM not installed\n"); - ps->spd_ch1_config = 2; + memory_params->PcdMemChannel1Config = 2; } } + + /* Update SPD data */ + if (CONFIG(BOARD_GOOGLE_CYAN)) { + memory_params->PcdMemoryTypeEnable = MEM_DDR3; + memory_params->PcdMemorySpdPtr = (uintptr_t)spd_content; + } else { + memory_params->PcdMemoryTypeEnable = MEM_LPDDR3; + } } -static void set_dimm_info(uint8_t *spd, struct dimm_info *dimm) +static void set_dimm_info(const uint8_t *spd, struct dimm_info *dimm) { const int spd_capmb[8] = { 1, 2, 4, 8, 16, 32, 64, 0 }; const int spd_ranks[8] = { 1, 2, 3, 4, -1, -1, -1, -1 }; @@ -171,9 +177,15 @@ static void set_dimm_info(uint8_t *spd, struct dimm_info *dimm) void mainboard_save_dimm_info(struct romstage_params *params) { + const void *spd_content; + int dual_channel; struct dimm_info *dimm; struct memory_info *mem_info; + spd_content = get_spd_pointer(&dual_channel); + if (spd_content == NULL) + return; + /* * Allocate CBMEM area for DIMM information used to populate SMBIOS * table 17 @@ -186,13 +198,13 @@ void mainboard_save_dimm_info(struct romstage_params *params) /* Describe the first channel memory */ dimm = &mem_info->dimm[0]; - set_dimm_info(params->pei_data->spd_data_ch0, dimm); + set_dimm_info(spd_content, dimm); mem_info->dimm_cnt = 1; /* Describe the second channel memory */ - if (params->pei_data->spd_ch1_config == 1) { + if (dual_channel) { dimm = &mem_info->dimm[1]; - set_dimm_info(params->pei_data->spd_data_ch1, dimm); + set_dimm_info(spd_content, dimm); dimm->channel_num = 1; mem_info->dimm_cnt = 2; } diff --git a/src/mainboard/google/cyan/spd/spd_util.h b/src/mainboard/google/cyan/spd/spd_util.h index 11d6eaa16d9..0c5b3265ef2 100644 --- a/src/mainboard/google/cyan/spd/spd_util.h +++ b/src/mainboard/google/cyan/spd/spd_util.h @@ -16,7 +16,10 @@ #ifndef SPD_UTIL_H #define SPD_UTIL_H +#include + uint8_t get_ramid(void); int get_variant_spd_index(int ram_id, int *dual); +void spd_memory_init_params(MEMORY_INIT_UPD *memory_params); #endif /* SPD_UTIL_H */ From feb50f15cc888150c90a5a12e749773cfe401dd5 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:06:06 +0200 Subject: [PATCH 204/588] mb/google/glados: Refactor to get rid of `pei_data` The SoC specific `struct pei_data` was filled with values that were later only consumed by the mainboard code again. Avoid jumping through this hoop and fill FSP UPDs directly. Change-Id: I040f4a55b4f4bad3f6072920e5e2eceded4cb9bb Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32594 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- src/mainboard/google/glados/romstage.c | 52 ++++++------------- src/mainboard/google/glados/spd/spd.c | 25 +++++---- src/mainboard/google/glados/spd/spd_util.h | 21 ++++++++ .../google/glados/variants/asuka/variant.c | 20 +++---- .../baseboard/include/baseboard/variant.h | 3 ++ .../google/glados/variants/caroline/variant.c | 21 ++++---- .../google/glados/variants/cave/variant.c | 20 +++---- .../google/glados/variants/chell/variant.c | 20 +++---- .../google/glados/variants/glados/variant.c | 20 +++---- .../google/glados/variants/lars/variant.c | 23 ++++---- .../google/glados/variants/sentry/variant.c | 23 ++++---- 11 files changed, 132 insertions(+), 116 deletions(-) create mode 100644 src/mainboard/google/glados/spd/spd_util.h diff --git a/src/mainboard/google/glados/romstage.c b/src/mainboard/google/glados/romstage.c index 81f0866dd68..47524c28ba3 100644 --- a/src/mainboard/google/glados/romstage.c +++ b/src/mainboard/google/glados/romstage.c @@ -15,16 +15,16 @@ * GNU General Public License for more details. */ -#include +#include #include #include -#include -#include #include -#include "spd/spd.h" #include #include +#include "spd/spd_util.h" +#include "spd/spd.h" + void mainboard_romstage_entry(struct romstage_params *params) { #ifdef EC_ENABLE_KEYBOARD_BACKLIGHT @@ -32,18 +32,6 @@ void mainboard_romstage_entry(struct romstage_params *params) if (params->power_state->prev_sleep_state != ACPI_S3) google_chromeec_kbbacklight(25); #endif - /* Get SPD index */ - gpio_t spd_gpios[] = { - GPIO_MEM_CONFIG_0, - GPIO_MEM_CONFIG_1, - GPIO_MEM_CONFIG_2, - GPIO_MEM_CONFIG_3, - }; - params->pei_data->mem_cfg_id = - gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); - /* Fill out PEI DATA */ - mainboard_fill_pei_data(params->pei_data); - mainboard_fill_spd_data(params->pei_data); /* Initialize memory */ romstage_common(params); } @@ -51,26 +39,18 @@ void mainboard_romstage_entry(struct romstage_params *params) void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params) { - if (params->pei_data->spd_data[0][0][0] != 0) { - memory_params->MemorySpdPtr00 = - (UINT32)(params->pei_data->spd_data[0][0]); - memory_params->MemorySpdPtr10 = - (UINT32)(params->pei_data->spd_data[1][0]); - } - memcpy(memory_params->DqByteMapCh0, params->pei_data->dq_map[0], - sizeof(params->pei_data->dq_map[0])); - memcpy(memory_params->DqByteMapCh1, params->pei_data->dq_map[1], - sizeof(params->pei_data->dq_map[1])); - memcpy(memory_params->DqsMapCpu2DramCh0, params->pei_data->dqs_map[0], - sizeof(params->pei_data->dqs_map[0])); - memcpy(memory_params->DqsMapCpu2DramCh1, params->pei_data->dqs_map[1], - sizeof(params->pei_data->dqs_map[1])); - memcpy(memory_params->RcompResistor, params->pei_data->RcompResistor, - sizeof(params->pei_data->RcompResistor)); - memcpy(memory_params->RcompTarget, params->pei_data->RcompTarget, - sizeof(params->pei_data->RcompTarget)); + /* Get SPD index */ + const gpio_t spd_gpios[] = { + GPIO_MEM_CONFIG_0, + GPIO_MEM_CONFIG_1, + GPIO_MEM_CONFIG_2, + GPIO_MEM_CONFIG_3, + }; + const int spd_idx = gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); + memory_params->MemorySpdDataLen = SPD_LEN; memory_params->DqPinsInterleaved = FALSE; - if (CONFIG(BOARD_GOOGLE_CAROLINE)) - memory_params->DdrFreqLimit = 1600; + + spd_memory_init_params(memory_params, spd_idx); + variant_memory_init_params(memory_params, spd_idx); } diff --git a/src/mainboard/google/glados/spd/spd.c b/src/mainboard/google/glados/spd/spd.c index 391b7021723..b3cf3f94160 100644 --- a/src/mainboard/google/glados/spd/spd.c +++ b/src/mainboard/google/glados/spd/spd.c @@ -19,10 +19,11 @@ #include #include #include -#include #include #include #include + +#include "spd_util.h" #include "spd.h" static void mainboard_print_spd_info(uint8_t spd[]) @@ -83,13 +84,11 @@ __weak int is_dual_channel(const int spd_index) } /* Copy SPD data for on-board memory */ -void mainboard_fill_spd_data(struct pei_data *pei_data) +void spd_memory_init_params(MEMORY_INIT_UPD *const memory_params, int spd_index) { - char *spd_file; + uint8_t *spd_file; size_t spd_file_len; - int spd_index; - spd_index = pei_data->mem_cfg_id; printk(BIOS_INFO, "SPD index %d\n", spd_index); /* Load SPD data from CBFS */ @@ -108,15 +107,15 @@ void mainboard_fill_spd_data(struct pei_data *pei_data) spd_index = 1; } - /* Assume same memory in both channels */ - spd_index *= SPD_LEN; - memcpy(pei_data->spd_data[0][0], spd_file + spd_index, SPD_LEN); - if (is_dual_channel(spd_index)) - memcpy(pei_data->spd_data[1][0], spd_file + spd_index, SPD_LEN); - + const size_t spd_offset = spd_index * SPD_LEN; /* Make sure a valid SPD was found */ - if (pei_data->spd_data[0][0][0] == 0) + if (spd_file[spd_offset] == 0) die("Invalid SPD data."); - mainboard_print_spd_info(pei_data->spd_data[0][0]); + /* Assume same memory in both channels */ + memory_params->MemorySpdPtr00 = (uintptr_t)spd_file + spd_offset; + if (is_dual_channel(spd_index)) + memory_params->MemorySpdPtr10 = memory_params->MemorySpdPtr00; + + mainboard_print_spd_info(spd_file + spd_offset); } diff --git a/src/mainboard/google/glados/spd/spd_util.h b/src/mainboard/google/glados/spd/spd_util.h new file mode 100644 index 00000000000..90dbd5ff987 --- /dev/null +++ b/src/mainboard/google/glados/spd/spd_util.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SPD_UTIL_H +#define SPD_UTIL_H + +#include + +void spd_memory_init_params(MEMORY_INIT_UPD *, int spd_index); + +#endif /* SPD_UTIL_H */ diff --git a/src/mainboard/google/glados/variants/asuka/variant.c b/src/mainboard/google/glados/variants/asuka/variant.c index 13cfe4fecde..4c778970fe1 100644 --- a/src/mainboard/google/glados/variants/asuka/variant.c +++ b/src/mainboard/google/glados/variants/asuka/variant.c @@ -17,10 +17,10 @@ #include #include #include -#include -#include +#include -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -39,12 +39,14 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Rcomp target */ const u16 RcompTarget[5] = { 100, 40, 40, 23, 40 }; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - memcpy(pei_data->RcompTarget, RcompTarget, - sizeof(RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, RcompTarget, + sizeof(memory_params->RcompTarget)); } int is_dual_channel(const int spd_index) diff --git a/src/mainboard/google/glados/variants/baseboard/include/baseboard/variant.h b/src/mainboard/google/glados/variants/baseboard/include/baseboard/variant.h index bbab7fc1f58..72eef684b8f 100644 --- a/src/mainboard/google/glados/variants/baseboard/include/baseboard/variant.h +++ b/src/mainboard/google/glados/variants/baseboard/include/baseboard/variant.h @@ -15,7 +15,10 @@ #ifndef GLADOS_VARIANT_H #define GLADOS_VARIANT_H +#include + int is_dual_channel(const int spd_index); void mainboard_gpio_smi_sleep(void); +void variant_memory_init_params(MEMORY_INIT_UPD *memory_params, int spd_index); #endif /* GLADOS_VARIANT_H */ diff --git a/src/mainboard/google/glados/variants/caroline/variant.c b/src/mainboard/google/glados/variants/caroline/variant.c index a00eacf0ed2..d61a538d56b 100644 --- a/src/mainboard/google/glados/variants/caroline/variant.c +++ b/src/mainboard/google/glados/variants/caroline/variant.c @@ -15,14 +15,14 @@ */ #include +#include #include #include #include -#include -#include #include -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -41,12 +41,15 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Rcomp target */ const u16 RcompTarget[5] = { 100, 40, 40, 23, 40 }; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - memcpy(pei_data->RcompTarget, RcompTarget, - sizeof(RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, RcompTarget, + sizeof(memory_params->RcompTarget)); + memory_params->DdrFreqLimit = 1600; } void mainboard_gpio_smi_sleep(void) diff --git a/src/mainboard/google/glados/variants/cave/variant.c b/src/mainboard/google/glados/variants/cave/variant.c index 2ce0a9001c4..fc27fb4b615 100644 --- a/src/mainboard/google/glados/variants/cave/variant.c +++ b/src/mainboard/google/glados/variants/cave/variant.c @@ -15,14 +15,14 @@ */ #include +#include #include #include #include -#include -#include #include -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -41,12 +41,14 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Rcomp target */ const u16 RcompTarget[5] = { 100, 40, 40, 23, 40 }; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - memcpy(pei_data->RcompTarget, RcompTarget, - sizeof(RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, RcompTarget, + sizeof(memory_params->RcompTarget)); } void mainboard_gpio_smi_sleep(void) diff --git a/src/mainboard/google/glados/variants/chell/variant.c b/src/mainboard/google/glados/variants/chell/variant.c index da83ed0f7d9..2d1b363caba 100644 --- a/src/mainboard/google/glados/variants/chell/variant.c +++ b/src/mainboard/google/glados/variants/chell/variant.c @@ -15,14 +15,14 @@ */ #include +#include #include #include #include -#include -#include #include -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -41,12 +41,14 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Rcomp target */ const u16 RcompTarget[5] = { 100, 40, 40, 23, 40 }; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - memcpy(pei_data->RcompTarget, RcompTarget, - sizeof(RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, RcompTarget, + sizeof(memory_params->RcompTarget)); } void mainboard_gpio_smi_sleep(void) diff --git a/src/mainboard/google/glados/variants/glados/variant.c b/src/mainboard/google/glados/variants/glados/variant.c index 2ce0a9001c4..fc27fb4b615 100644 --- a/src/mainboard/google/glados/variants/glados/variant.c +++ b/src/mainboard/google/glados/variants/glados/variant.c @@ -15,14 +15,14 @@ */ #include +#include #include #include #include -#include -#include #include -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -41,12 +41,14 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Rcomp target */ const u16 RcompTarget[5] = { 100, 40, 40, 23, 40 }; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - memcpy(pei_data->RcompTarget, RcompTarget, - sizeof(RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, RcompTarget, + sizeof(memory_params->RcompTarget)); } void mainboard_gpio_smi_sleep(void) diff --git a/src/mainboard/google/glados/variants/lars/variant.c b/src/mainboard/google/glados/variants/lars/variant.c index 4fe88ef7c8e..cff00962917 100644 --- a/src/mainboard/google/glados/variants/lars/variant.c +++ b/src/mainboard/google/glados/variants/lars/variant.c @@ -17,8 +17,7 @@ #include #include #include -#include -#include +#include #define K4E6E304EB_MEM_ID 0x5 @@ -29,7 +28,8 @@ #define MEM_SINGLE_CHANB 0xb #define MEM_SINGLE_CHANC 0xc -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -54,17 +54,18 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Default Rcomp Target assignment */ const u16 *targeted_rcomp = RcompTarget; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - /* Override Rcomp Target assignment for specific SKU(s) */ - if (pei_data->mem_cfg_id == K4E6E304EB_MEM_ID) + if (spd_index == K4E6E304EB_MEM_ID) targeted_rcomp = StrengthendRcompTarget; - memcpy(pei_data->RcompTarget, targeted_rcomp, - sizeof(pei_data->RcompTarget)); + memcpy(params->DqByteMapCh0, dq_map, + sizeof(params->DqByteMapCh0) * 2); + memcpy(params->DqsMapCpu2DramCh0, dqs_map, + sizeof(params->DqsMapCpu2DramCh0) * 2); + memcpy(params->RcompResistor, RcompResistor, + sizeof(params->RcompResistor)); + memcpy(params->RcompTarget, targeted_rcomp, + sizeof(params->RcompTarget)); } int is_dual_channel(const int spd_index) diff --git a/src/mainboard/google/glados/variants/sentry/variant.c b/src/mainboard/google/glados/variants/sentry/variant.c index 00f49fecf75..4c7fa23f085 100644 --- a/src/mainboard/google/glados/variants/sentry/variant.c +++ b/src/mainboard/google/glados/variants/sentry/variant.c @@ -17,12 +17,12 @@ #include #include #include -#include -#include +#include #define K4E6E304EE_MEM_ID 0x3 -void mainboard_fill_pei_data(struct pei_data *pei_data) +void variant_memory_init_params( + MEMORY_INIT_UPD *const memory_params, const int spd_index) { /* DQ byte map */ const u8 dq_map[2][12] = { @@ -47,15 +47,16 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) /* Default Rcomp Target assignment */ const u16 *targeted_rcomp = RcompTarget; - memcpy(pei_data->dq_map, dq_map, sizeof(dq_map)); - memcpy(pei_data->dqs_map, dqs_map, sizeof(dqs_map)); - memcpy(pei_data->RcompResistor, RcompResistor, - sizeof(RcompResistor)); - /* Override Rcomp Target assignment for specific SKU(s) */ - if (pei_data->mem_cfg_id == K4E6E304EE_MEM_ID) + if (spd_index == K4E6E304EE_MEM_ID) targeted_rcomp = StrengthendRcompTarget; - memcpy(pei_data->RcompTarget, targeted_rcomp, - sizeof(pei_data->RcompTarget)); + memcpy(memory_params->DqByteMapCh0, dq_map, + sizeof(memory_params->DqByteMapCh0) * 2); + memcpy(memory_params->DqsMapCpu2DramCh0, dqs_map, + sizeof(memory_params->DqsMapCpu2DramCh0) * 2); + memcpy(memory_params->RcompResistor, RcompResistor, + sizeof(memory_params->RcompResistor)); + memcpy(memory_params->RcompTarget, targeted_rcomp, + sizeof(memory_params->RcompTarget)); } From 0ebdf2ac75a6459534d0543d3bc963a96316f920 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 17:06:06 +0200 Subject: [PATCH 205/588] mb/purism/librem_skl: Refactor to get rid of `pei_data` The SoC specific `struct pei_data` was filled with values that were never consumed anywhere again. So just merge the used code into `romstage.c` where it's effectively used. Change-Id: I499b3cfcdd5400ea132749555d433a2d8a9471a3 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32595 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- src/mainboard/purism/librem_skl/Makefile.inc | 3 - src/mainboard/purism/librem_skl/pei_data.c | 65 -------------------- src/mainboard/purism/librem_skl/pei_data.h | 24 -------- src/mainboard/purism/librem_skl/romstage.c | 36 ++++++++++- 4 files changed, 35 insertions(+), 93 deletions(-) delete mode 100644 src/mainboard/purism/librem_skl/pei_data.c delete mode 100644 src/mainboard/purism/librem_skl/pei_data.h diff --git a/src/mainboard/purism/librem_skl/Makefile.inc b/src/mainboard/purism/librem_skl/Makefile.inc index 5a7131f1ba6..35f0f6cbdee 100644 --- a/src/mainboard/purism/librem_skl/Makefile.inc +++ b/src/mainboard/purism/librem_skl/Makefile.inc @@ -13,8 +13,5 @@ ## GNU General Public License for more details. ## -romstage-y += pei_data.c - -ramstage-y += pei_data.c ramstage-y += ramstage.c ramstage-y += hda_verb.c diff --git a/src/mainboard/purism/librem_skl/pei_data.c b/src/mainboard/purism/librem_skl/pei_data.c deleted file mode 100644 index 0be917d3c72..00000000000 --- a/src/mainboard/purism/librem_skl/pei_data.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2015 Google Inc. - * Copyright (C) 2015 Intel Corporation - * Copyright (C) 2017 Purism SPC. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include "pei_data.h" - -void mainboard_fill_dq_map_data(void *dq_map_ptr) -{ - /* DQ byte map */ - const u8 dq_map[2][12] = { - { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, - 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, - { 0x33, 0xCC, 0x00, 0xCC, 0x33, 0xCC, - 0x33, 0x00, 0xFF, 0x00, 0xFF, 0x00 } }; - memcpy(dq_map_ptr, dq_map, sizeof(dq_map)); -} - -void mainboard_fill_dqs_map_data(void *dqs_map_ptr) -{ - /* DQS CPU<>DRAM map */ - const u8 dqs_map[2][8] = { - { 0, 1, 3, 2, 4, 5, 6, 7 }, - { 1, 0, 4, 5, 2, 3, 6, 7 } }; - memcpy(dqs_map_ptr, dqs_map, sizeof(dqs_map)); -} - -void mainboard_fill_rcomp_res_data(void *rcomp_ptr) -{ - /* Rcomp resistor */ - const u16 RcompResistor[3] = { 121, 81, 100 }; - memcpy(rcomp_ptr, RcompResistor, - sizeof(RcompResistor)); -} - -void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr) -{ - /* Rcomp target */ - const u16 RcompTarget[5] = { 100, 40, 20, 20, 26 }; - memcpy(rcomp_strength_ptr, RcompTarget, sizeof(RcompTarget)); -} - -void mainboard_fill_pei_data(struct pei_data *pei_data) -{ - mainboard_fill_dq_map_data(&pei_data->dq_map); - mainboard_fill_dqs_map_data(&pei_data->dqs_map); - mainboard_fill_rcomp_res_data(&pei_data->RcompResistor); - mainboard_fill_rcomp_strength_data(&pei_data->RcompTarget); -} diff --git a/src/mainboard/purism/librem_skl/pei_data.h b/src/mainboard/purism/librem_skl/pei_data.h deleted file mode 100644 index 320d9803d10..00000000000 --- a/src/mainboard/purism/librem_skl/pei_data.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2017 Purism SPC. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _MAINBOARD_PEI_DATA_H_ -#define _MAINBOARD_PEI_DATA_H_ - -void mainboard_fill_dq_map_data(void *dq_map_ptr); -void mainboard_fill_dqs_map_data(void *dqs_map_ptr); -void mainboard_fill_rcomp_res_data(void *rcomp_ptr); -void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr); - -#endif diff --git a/src/mainboard/purism/librem_skl/romstage.c b/src/mainboard/purism/librem_skl/romstage.c index 63d148a98ec..faf4090ae1a 100644 --- a/src/mainboard/purism/librem_skl/romstage.c +++ b/src/mainboard/purism/librem_skl/romstage.c @@ -19,7 +19,41 @@ #include #include #include -#include "pei_data.h" +#include + +static void mainboard_fill_dq_map_data(void *dq_map_ptr) +{ + /* DQ byte map */ + const u8 dq_map[2][12] = { + { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, + 0x0F, 0x00, 0xFF, 0x00, 0xFF, 0x00 }, + { 0x33, 0xCC, 0x00, 0xCC, 0x33, 0xCC, + 0x33, 0x00, 0xFF, 0x00, 0xFF, 0x00 } }; + memcpy(dq_map_ptr, dq_map, sizeof(dq_map)); +} + +static void mainboard_fill_dqs_map_data(void *dqs_map_ptr) +{ + /* DQS CPU<>DRAM map */ + const u8 dqs_map[2][8] = { + { 0, 1, 3, 2, 4, 5, 6, 7 }, + { 1, 0, 4, 5, 2, 3, 6, 7 } }; + memcpy(dqs_map_ptr, dqs_map, sizeof(dqs_map)); +} + +static void mainboard_fill_rcomp_res_data(void *rcomp_ptr) +{ + /* Rcomp resistor */ + const u16 RcompResistor[3] = { 121, 81, 100 }; + memcpy(rcomp_ptr, RcompResistor, sizeof(RcompResistor)); +} + +static void mainboard_fill_rcomp_strength_data(void *rcomp_strength_ptr) +{ + /* Rcomp target */ + const u16 RcompTarget[5] = { 100, 40, 20, 20, 26 }; + memcpy(rcomp_strength_ptr, RcompTarget, sizeof(RcompTarget)); +} void mainboard_memory_init_params(FSPM_UPD *mupd) { From 3c0d23b6ab1ca23c9e54f3554386e7aa2cfec94d Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 4 May 2019 19:19:10 +0200 Subject: [PATCH 206/588] intel/fsp1_1: Drop remnants of `pei_data` `pei_data` was a struct with blob parameters from pre-FSP times. Somehow, it sneaked into upstream FSP1.1 support (probably because early board ports were written for a different blob). When added upstream, its usage was already perverted. It was declared at SoC level but mostly used to pass mainboard data from mainboard code to itself and FSP data from FSP code to itself. Now that no board/ SoC code uses it anymore, we can finally drop it. Change-Id: Ib0bc402703188539cf2254bdc395cca9dd32d863 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32596 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Patrick Rudolph --- .../intel/fsp1_1/include/fsp/romstage.h | 2 - src/drivers/intel/fsp1_1/romstage.c | 4 - src/mainboard/google/eve/spd/spd.c | 1 - src/mainboard/intel/kblrvp/spd/spd_util.c | 2 - src/soc/intel/braswell/include/soc/pei_data.h | 50 ----------- .../intel/braswell/include/soc/pei_wrapper.h | 26 ------ src/soc/intel/braswell/include/soc/romstage.h | 2 - src/soc/intel/skylake/Makefile.inc | 2 - .../skylake/include/fsp11/soc/romstage.h | 2 - src/soc/intel/skylake/include/soc/pei_data.h | 89 ------------------- .../intel/skylake/include/soc/pei_wrapper.h | 27 ------ src/soc/intel/skylake/pei_data.c | 39 -------- src/soc/intel/skylake/romstage/romstage.c | 4 - 13 files changed, 250 deletions(-) delete mode 100644 src/soc/intel/braswell/include/soc/pei_data.h delete mode 100644 src/soc/intel/braswell/include/soc/pei_wrapper.h delete mode 100644 src/soc/intel/skylake/include/soc/pei_data.h delete mode 100644 src/soc/intel/skylake/include/soc/pei_wrapper.h delete mode 100644 src/soc/intel/skylake/pei_data.c diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index 4e95dadadfc..b01f11059c3 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -25,13 +25,11 @@ #include #include #include -#include #include /* chip_power_state */ struct romstage_params { uint32_t fsp_version; struct chipset_power_state *power_state; - struct pei_data *pei_data; void *chipset_context; /* Fast boot and S3 resume MRC data */ diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 87fd1a4c01f..433e16cf130 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -41,9 +41,7 @@ asmlinkage void *romstage_main(FSP_INFO_HEADER *fih) { void *top_of_stack; - struct pei_data pei_data; struct romstage_params params = { - .pei_data = &pei_data, .chipset_context = fih, }; @@ -55,8 +53,6 @@ asmlinkage void *romstage_main(FSP_INFO_HEADER *fih) if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS)) intel_update_microcode_from_cbfs(); - memset(&pei_data, 0, sizeof(pei_data)); - /* Display parameters */ if (!CONFIG(NO_MMCONF_SUPPORT)) printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n", diff --git a/src/mainboard/google/eve/spd/spd.c b/src/mainboard/google/eve/spd/spd.c index 2f365a7b5cd..077bed4bf14 100644 --- a/src/mainboard/google/eve/spd/spd.c +++ b/src/mainboard/google/eve/spd/spd.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/src/mainboard/intel/kblrvp/spd/spd_util.c b/src/mainboard/intel/kblrvp/spd/spd_util.c index 10043843a22..f22dcaa3b7b 100644 --- a/src/mainboard/intel/kblrvp/spd/spd_util.c +++ b/src/mainboard/intel/kblrvp/spd/spd_util.c @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include "../board_id.h" #include "spd.h" diff --git a/src/soc/intel/braswell/include/soc/pei_data.h b/src/soc/intel/braswell/include/soc/pei_data.h deleted file mode 100644 index df18dc087aa..00000000000 --- a/src/soc/intel/braswell/include/soc/pei_data.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * UEFI PEI wrapper - * - * Copyright (C) 2014 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Google Inc. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PEI_DATA_H_ -#define _PEI_DATA_H_ - -#include - -#define PEI_VERSION 22 - -#define ABI_X86 __attribute__((regparm(0))) - -typedef void ABI_X86(*tx_byte_func)(unsigned char byte); - -struct pei_data { - /* Chip settings */ - void *spd_data_ch0; - void *spd_data_ch1; - uint8_t spd_ch0_config; - uint8_t spd_ch1_config; -}; - -typedef struct pei_data PEI_DATA; - -#endif /* _PEI_DATA_H_ */ diff --git a/src/soc/intel/braswell/include/soc/pei_wrapper.h b/src/soc/intel/braswell/include/soc/pei_wrapper.h deleted file mode 100644 index 3222328bef7..00000000000 --- a/src/soc/intel/braswell/include/soc/pei_wrapper.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _SOC_PEI_WRAPPER_H_ -#define _SOC_PEI_WRAPPER_H_ - -#include - -typedef int ABI_X86(*pei_wrapper_entry_t)(struct pei_data *pei_data); - -void broadwell_fill_pei_data(struct pei_data *pei_data); -void mainboard_fill_pei_data(struct pei_data *pei_data); - -#endif diff --git a/src/soc/intel/braswell/include/soc/romstage.h b/src/soc/intel/braswell/include/soc/romstage.h index 2512430f754..633233e6c60 100644 --- a/src/soc/intel/braswell/include/soc/romstage.h +++ b/src/soc/intel/braswell/include/soc/romstage.h @@ -20,14 +20,12 @@ #include #include #include -#include #include void gfx_init(void); void tco_disable(void); void punit_init(void); int early_spi_read_wpsr(u8 *sr); -void mainboard_fill_spd_data(struct pei_data *pei_data); void set_max_freq(void); /* romstage_common.c functions */ diff --git a/src/soc/intel/skylake/Makefile.inc b/src/soc/intel/skylake/Makefile.inc index ee2c928464e..e9f555f13c1 100644 --- a/src/soc/intel/skylake/Makefile.inc +++ b/src/soc/intel/skylake/Makefile.inc @@ -35,7 +35,6 @@ romstage-y += gspi.c romstage-y += i2c.c romstage-y += memmap.c romstage-y += me.c -romstage-y += pei_data.c romstage-y += pmc.c romstage-y += pmutil.c romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c @@ -58,7 +57,6 @@ ramstage-y += lpc.c ramstage-y += me.c ramstage-y += memmap.c ramstage-y += p2sb.c -ramstage-y += pei_data.c ramstage-y += pmc.c ramstage-y += pmutil.c ramstage-$(CONFIG_PLATFORM_USES_FSP2_0) += reset.c diff --git a/src/soc/intel/skylake/include/fsp11/soc/romstage.h b/src/soc/intel/skylake/include/fsp11/soc/romstage.h index 36825f7aeaa..386931043dc 100644 --- a/src/soc/intel/skylake/include/fsp11/soc/romstage.h +++ b/src/soc/intel/skylake/include/fsp11/soc/romstage.h @@ -24,6 +24,4 @@ void intel_early_me_status(void); void enable_smbus(void); int smbus_read_byte(unsigned int device, unsigned int address); -void mainboard_fill_spd_data(struct pei_data *pei_data); - #endif /* _SOC_ROMSTAGE_H_ */ diff --git a/src/soc/intel/skylake/include/soc/pei_data.h b/src/soc/intel/skylake/include/soc/pei_data.h deleted file mode 100644 index 5ea2190b8e1..00000000000 --- a/src/soc/intel/skylake/include/soc/pei_data.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * UEFI PEI wrapper - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Google Inc. nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _PEI_DATA_H_ -#define _PEI_DATA_H_ - -#include - -#define PEI_VERSION 22 - -#define ABI_X86 __attribute__((regparm(0))) - -typedef void ABI_X86(*tx_byte_func)(unsigned char byte); - -struct pei_data { - uint32_t pei_version; - - int ec_present; - - /* Console output function */ - tx_byte_func tx_byte; - - /* - * DIMM SPD data for memory down configurations - * [CHANNEL][SLOT][SPD] - */ - uint8_t spd_data[2][2][512]; - - /* - * LPDDR3 DQ byte map - * [CHANNEL][ITERATION][2] - * - * Maps which PI clocks are used by what LPDDR DQ Bytes (from CPU side) - * DQByteMap[0] - ClkDQByteMap: - * - If clock is per rank, program to [0xFF, 0xFF] - * - If clock is shared by 2 ranks, program to [0xFF, 0] or [0, 0xFF] - * - If clock is shared by 2 ranks but does not go to all bytes, - * Entry[i] defines which DQ bytes Group i services - * DQByteMap[1] - CmdNDQByteMap: [0] is CmdN/CAA and [1] is CmdN/CAB - * DQByteMap[2] - CmdSDQByteMap: [0] is CmdS/CAA and [1] is CmdS/CAB - * DQByteMap[3] - CkeDQByteMap : [0] is CKE /CAA and [1] is CKE /CAB - * For DDR, DQByteMap[3:1] = [0xFF, 0] - * DQByteMap[4] - CtlDQByteMap : Always program to [0xFF, 0] - * since we have 1 CTL / rank - * DQByteMap[5] - CmdVDQByteMap: Always program to [0xFF, 0] - * since we have 1 CA Vref - */ - uint8_t dq_map[2][12]; - - /* - * LPDDR3 Map from CPU DQS pins to SDRAM DQS pins - * [CHANNEL][MAX_BYTES] - */ - uint8_t dqs_map[2][8]; - uint16_t RcompResistor[3]; - uint16_t RcompTarget[5]; - - int mem_cfg_id; -} __packed; - -typedef struct pei_data PEI_DATA; - -#endif /* _PEI_DATA_H_ */ diff --git a/src/soc/intel/skylake/include/soc/pei_wrapper.h b/src/soc/intel/skylake/include/soc/pei_wrapper.h deleted file mode 100644 index d53fe8b7690..00000000000 --- a/src/soc/intel/skylake/include/soc/pei_wrapper.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _SOC_PEI_WRAPPER_H_ -#define _SOC_PEI_WRAPPER_H_ - -#include - -typedef int ABI_X86(*pei_wrapper_entry_t)(struct pei_data *pei_data); - -void soc_fill_pei_data(struct pei_data *pei_data); -void mainboard_fill_pei_data(struct pei_data *pei_data); - -#endif diff --git a/src/soc/intel/skylake/pei_data.c b/src/soc/intel/skylake/pei_data.c deleted file mode 100644 index 7d314a106fd..00000000000 --- a/src/soc/intel/skylake/pei_data.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * Copyright (C) 2015 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "chip.h" - -static void ABI_X86 send_to_console(unsigned char b) -{ - console_tx_byte(b); -} - -void soc_fill_pei_data(struct pei_data *pei_data) -{ - /* Set the parameters for MemoryInit */ - pei_data->pei_version = PEI_VERSION; - pei_data->tx_byte = &send_to_console; -} diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index 8ec08c2d0f4..12239ae13e2 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -44,9 +43,6 @@ void soc_pre_ram_init(struct romstage_params *params) /* Program MCHBAR and DMIBAR */ systemagent_early_init(); - /* Prepare to initialize memory */ - soc_fill_pei_data(params->pei_data); - const struct device *const dev = pcidev_path_on_root(PCH_DEVFN_LPC); const struct soc_intel_skylake_config *const config = dev ? dev->chip_info : NULL; From 30bc9f415d9564de90fc0c6c6a92462ce3ce7c06 Mon Sep 17 00:00:00 2001 From: Jiaxin Yu Date: Tue, 23 Apr 2019 20:45:50 +0800 Subject: [PATCH 207/588] google/kukui: Support sound in boot process Configure and enable GPIO for speaker amp max98357a. BUG=b:117254418 TEST=Build pass and verified on kukui p1 board BRANCH=None Change-Id: I97655702dff402245326d2eff71fae0e336df9f5 Signed-off-by: Jiaxin Yu Reviewed-on: https://review.coreboot.org/c/coreboot/+/32459 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/mainboard/google/kukui/chromeos.c | 2 ++ src/mainboard/google/kukui/gpio.h | 1 + src/mainboard/google/kukui/mainboard.c | 13 +++++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/mainboard/google/kukui/chromeos.c b/src/mainboard/google/kukui/chromeos.c index 44e75e29f0b..35395014d67 100644 --- a/src/mainboard/google/kukui/chromeos.c +++ b/src/mainboard/google/kukui/chromeos.c @@ -27,6 +27,7 @@ void setup_chromeos_gpios(void) gpio_input_pullup(EC_IRQ); gpio_input_pullup(CR50_IRQ); gpio_output(GPIO_RESET, 0); + gpio_output(GPIO_EN_SPK_AMP, 0); } void fill_lb_gpios(struct lb_gpios *gpios) @@ -38,6 +39,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {EC_IN_RW.id, ACTIVE_HIGH, -1, "EC in RW"}, {EC_IRQ.id, ACTIVE_LOW, -1, "EC interrupt"}, {CR50_IRQ.id, ACTIVE_HIGH, -1, "TPM interrupt"}, + {GPIO_EN_SPK_AMP.id, ACTIVE_HIGH, -1, "speaker enable"}, }; lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios)); } diff --git a/src/mainboard/google/kukui/gpio.h b/src/mainboard/google/kukui/gpio.h index 92d238ece23..977acc37392 100644 --- a/src/mainboard/google/kukui/gpio.h +++ b/src/mainboard/google/kukui/gpio.h @@ -23,6 +23,7 @@ #define EC_IN_RW GPIO(PERIPHERAL_EN14) #define CR50_IRQ GPIO(PERIPHERAL_EN3) #define GPIO_RESET GPIO(PERIPHERAL_EN8) +#define GPIO_EN_SPK_AMP GPIO(PERIPHERAL_EN12) void setup_chromeos_gpios(void); diff --git a/src/mainboard/google/kukui/mainboard.c b/src/mainboard/google/kukui/mainboard.c index e1d8f5fb8d7..40b8a49c61a 100644 --- a/src/mainboard/google/kukui/mainboard.c +++ b/src/mainboard/google/kukui/mainboard.c @@ -16,6 +16,7 @@ #include #include #include +#include #include static void configure_emmc(void) @@ -37,10 +38,22 @@ static void configure_usb(void) setup_usb_host(); } +static void configure_audio(void) +{ + /* Audio PWR*/ + mtcmos_audio_power_on(); + + /* SoC I2S */ + gpio_set_mode(GPIO(CAM_RST0), PAD_CAM_RST0_FUNC_I2S2_LRCK); + gpio_set_mode(GPIO(CAM_PDN1), PAD_CAM_PDN1_FUNC_I2S2_BCK); + gpio_set_mode(GPIO(CAM_PDN0), PAD_CAM_PDN0_FUNC_I2S2_MCK); + gpio_set_mode(GPIO(EINT3), PAD_EINT3_FUNC_I2S3_DO); +} static void mainboard_init(struct device *dev) { configure_emmc(); configure_usb(); + configure_audio(); } static void mainboard_enable(struct device *dev) From 551a75923ec7e7bacaf6da79b38eda5c3b3821ad Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 1 May 2019 16:56:36 +0200 Subject: [PATCH 208/588] sb/{ICH7,NM10,PCH}: Use common watchdog_off function Change-Id: I704780b6ae7238560dcb72fc027addc1089e0674 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32533 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: David Guckian --- src/southbridge/intel/bd82x6x/Kconfig | 1 + src/southbridge/intel/bd82x6x/Makefile.inc | 1 - src/southbridge/intel/common/Kconfig | 4 ++ src/southbridge/intel/common/Makefile.inc | 2 + src/southbridge/intel/common/tco.h | 27 +++++++++ .../intel/{bd82x6x => common}/watchdog.c | 29 +++++----- src/southbridge/intel/fsp_rangeley/Kconfig | 1 + .../intel/fsp_rangeley/Makefile.inc | 1 - src/southbridge/intel/fsp_rangeley/watchdog.c | 53 ------------------ src/southbridge/intel/i82801gx/Kconfig | 1 + src/southbridge/intel/i82801gx/Makefile.inc | 2 - src/southbridge/intel/i82801gx/watchdog.c | 50 ----------------- src/southbridge/intel/i82801ix/Kconfig | 1 + src/southbridge/intel/i82801ix/Makefile.inc | 2 - src/southbridge/intel/i82801jx/Kconfig | 1 + src/southbridge/intel/i82801jx/Makefile.inc | 2 - src/southbridge/intel/ibexpeak/Kconfig | 1 + src/southbridge/intel/ibexpeak/Makefile.inc | 1 - src/southbridge/intel/lynxpoint/Kconfig | 1 + src/southbridge/intel/lynxpoint/Makefile.inc | 1 - src/southbridge/intel/lynxpoint/watchdog.c | 56 ------------------- 21 files changed, 56 insertions(+), 182 deletions(-) create mode 100644 src/southbridge/intel/common/tco.h rename src/southbridge/intel/{bd82x6x => common}/watchdog.c (67%) delete mode 100644 src/southbridge/intel/fsp_rangeley/watchdog.c delete mode 100644 src/southbridge/intel/i82801gx/watchdog.c delete mode 100644 src/southbridge/intel/lynxpoint/watchdog.c diff --git a/src/southbridge/intel/bd82x6x/Kconfig b/src/southbridge/intel/bd82x6x/Kconfig index dae3c32c861..fc3e9fcadb6 100644 --- a/src/southbridge/intel/bd82x6x/Kconfig +++ b/src/southbridge/intel/bd82x6x/Kconfig @@ -44,6 +44,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy select HAVE_INTEL_CHIPSET_LOCKDOWN select SOUTHBRIDGE_INTEL_COMMON_SMM select SOUTHBRIDGE_INTEL_COMMON_ACPI_MADT + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG config EHCI_BAR hex diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index a950e5ce5db..023f5d32c27 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -31,7 +31,6 @@ ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c ramstage-y += me_status.c -ramstage-y += watchdog.c ramstage-$(CONFIG_ELOG) += elog.c diff --git a/src/southbridge/intel/common/Kconfig b/src/southbridge/intel/common/Kconfig index 0bda06e10ac..c3bd90dca8b 100644 --- a/src/southbridge/intel/common/Kconfig +++ b/src/southbridge/intel/common/Kconfig @@ -65,6 +65,10 @@ config INTEL_CHIPSET_LOCKDOWN and S3 resume (always done by coreboot). Select this to let coreboot to do this on normal boot path. +config SOUTHBRIDGE_INTEL_COMMON_WATCHDOG + bool + depends on SOUTHBRIDGE_INTEL_COMMON + if SOUTHBRIDGE_INTEL_COMMON_FINALIZE choice diff --git a/src/southbridge/intel/common/Makefile.inc b/src/southbridge/intel/common/Makefile.inc index 1085f6c66a0..4cf6e6f57e8 100644 --- a/src/southbridge/intel/common/Makefile.inc +++ b/src/southbridge/intel/common/Makefile.inc @@ -27,6 +27,8 @@ ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS) += smbus.c romstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_PMCLIB) += pmclib.c +ramstage-$(CONFIG_SOUTHBRIDGE_INTEL_COMMON_WATCHDOG) += watchdog.c + ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_COMMON),y) verstage-y += pmbase.c diff --git a/src/southbridge/intel/common/tco.h b/src/southbridge/intel/common/tco.h new file mode 100644 index 00000000000..9d6f15326ec --- /dev/null +++ b/src/southbridge/intel/common/tco.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (c) 2019 Elyes Haouas + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOUTHBRIDGE_INTEL_COMMON_TCO_H +#define SOUTHBRIDGE_INTEL_COMMON_TCO_H + +#define PMBASE_TCO_OFFSET 0x60 +#define TCO1_STS 0x04 +#define TCO1_TIMEOUT (1 << 3) +#define TCO2_STS 0x06 +#define SECOND_TO_STS (1 << 1) +#define TCO1_CNT 0x08 +#define TCO_TMR_HLT (1 << 11) + +#endif /* SOUTHBRIDGE_INTEL_COMMON_TCO_H */ diff --git a/src/southbridge/intel/bd82x6x/watchdog.c b/src/southbridge/intel/common/watchdog.c similarity index 67% rename from src/southbridge/intel/bd82x6x/watchdog.c rename to src/southbridge/intel/common/watchdog.c index 6373a39e47a..778a7a9f7fd 100644 --- a/src/southbridge/intel/bd82x6x/watchdog.c +++ b/src/southbridge/intel/common/watchdog.c @@ -16,17 +16,16 @@ */ #include -#include #include #include #include +#include #include -#include - +#include #include /* - * Disable PCH watchdog timer + * Disable ICH-NM10-PCH watchdog timer */ void watchdog_off(void) { @@ -36,21 +35,25 @@ void watchdog_off(void) /* Get LPC device. */ dev = pcidev_on_root(0x1f, 0); - /* Disable interrupt. */ value = pci_read_config16(dev, PCI_COMMAND); - value |= PCI_COMMAND_INT_DISABLE; + + if (CONFIG(SOUTHBRIDGE_INTEL_FSP_RANGELEY)) { + /* Enable I/O space. */ + value |= PCI_COMMAND_IO; + } else { + /* Disable interrupt. */ + value |= PCI_COMMAND_INT_DISABLE; + } pci_write_config16(dev, PCI_COMMAND, value); /* Disable the watchdog timer. */ - value = read_pmbase16(TCO1_CNT); + value = read_pmbase16(PMBASE_TCO_OFFSET + TCO1_CNT); value |= TCO_TMR_HLT; - write_pmbase16(TCO1_CNT, value); + write_pmbase16(PMBASE_TCO_OFFSET + TCO1_CNT, value); /* Clear TCO timeout status. */ - write_pmbase16(TCO1_STS, TCO1_TIMEOUT); - write_pmbase16(TCO2_STS, SECOND_TO_STS); - - /* FIXME: Set RCBA GCS Bit5 "No Reboot" ? */ + write_pmbase16(PMBASE_TCO_OFFSET + TCO1_STS, TCO1_TIMEOUT); + write_pmbase16(PMBASE_TCO_OFFSET + TCO2_STS, SECOND_TO_STS); - printk(BIOS_DEBUG, "PCH: watchdog disabled\n"); + printk(BIOS_DEBUG, "ICH-NM10-PCH: watchdog disabled\n"); } diff --git a/src/southbridge/intel/fsp_rangeley/Kconfig b/src/southbridge/intel/fsp_rangeley/Kconfig index c15c48d445d..4526cb3cf5e 100644 --- a/src/southbridge/intel/fsp_rangeley/Kconfig +++ b/src/southbridge/intel/fsp_rangeley/Kconfig @@ -31,6 +31,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy select INTEL_DESCRIPTOR_MODE_CAPABLE select SOUTHBRIDGE_INTEL_COMMON select SOUTHBRIDGE_INTEL_COMMON_SMBUS + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG config EHCI_BAR hex diff --git a/src/southbridge/intel/fsp_rangeley/Makefile.inc b/src/southbridge/intel/fsp_rangeley/Makefile.inc index ac5888ca38a..7fc86012dec 100644 --- a/src/southbridge/intel/fsp_rangeley/Makefile.inc +++ b/src/southbridge/intel/fsp_rangeley/Makefile.inc @@ -19,7 +19,6 @@ ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_FSP_RANGELEY),y) ramstage-y += soc.c ramstage-y += lpc.c ramstage-y += sata.c -ramstage-y += watchdog.c ramstage-y += spi.c ramstage-y += smbus.c ramstage-y += acpi.c diff --git a/src/southbridge/intel/fsp_rangeley/watchdog.c b/src/southbridge/intel/fsp_rangeley/watchdog.c deleted file mode 100644 index f18af8927c9..00000000000 --- a/src/southbridge/intel/fsp_rangeley/watchdog.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2011 Google Inc. - * Copyright (C) 2013 Sage Electronic Engineering, LLC. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include "soc.h" - -void watchdog_off(void) -{ - struct device *dev; - u32 value, abase; - - /* Turn off the watchdog. */ - dev = pcidev_on_root(0x1f, 0); - - /* Enable I/O space. */ - value = pci_read_config16(dev, 0x04); - value |= 1; - pci_write_config16(dev, 0x04, value); - - /* Get TCO base. */ - abase = (pci_read_config32(dev, ABASE) & ~0xf); - - /* Disable the watchdog timer. */ - value = inw(abase + 0x68); - value |= 1 << 11; - outw(value, abase + 0x68); - - /* Clear TCO timeout status. */ - outw(0x0008, abase + 0x64); - outw(0x0002, abase + 0x66); - - printk(BIOS_DEBUG, "TCO Watchdog disabled\n"); -} diff --git a/src/southbridge/intel/i82801gx/Kconfig b/src/southbridge/intel/i82801gx/Kconfig index a7d65c52bb8..2d6e938eba0 100644 --- a/src/southbridge/intel/i82801gx/Kconfig +++ b/src/southbridge/intel/i82801gx/Kconfig @@ -30,6 +30,7 @@ config SOUTHBRIDGE_INTEL_I82801GX select SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ select INTEL_HAS_TOP_SWAP select SOUTHBRIDGE_INTEL_COMMON_SMM + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG if SOUTHBRIDGE_INTEL_I82801GX diff --git a/src/southbridge/intel/i82801gx/Makefile.inc b/src/southbridge/intel/i82801gx/Makefile.inc index b72ca235f5e..32a4bf53332 100644 --- a/src/southbridge/intel/i82801gx/Makefile.inc +++ b/src/southbridge/intel/i82801gx/Makefile.inc @@ -30,8 +30,6 @@ ramstage-y += usb_ehci.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c -ramstage-y += watchdog.c - smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c romstage-y += early_smbus.c diff --git a/src/southbridge/intel/i82801gx/watchdog.c b/src/southbridge/intel/i82801gx/watchdog.c deleted file mode 100644 index 12284b46c16..00000000000 --- a/src/southbridge/intel/i82801gx/watchdog.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -void watchdog_off(void) -{ - struct device *dev; - unsigned long value, base; - - /* Turn off the ICH7 watchdog. */ - dev = pcidev_on_root(0x1f, 0); - - /* Enable I/O space. */ - value = pci_read_config16(dev, 0x04); - value |= (1 << 10); - pci_write_config16(dev, 0x04, value); - - /* Get TCO base. */ - base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60; - - /* Disable the watchdog timer. */ - value = inw(base + 0x08); - value |= 1 << 11; - outw(value, base + 0x08); - - /* Clear TCO timeout status. */ - outw(0x0008, base + 0x04); - outw(0x0002, base + 0x06); - - printk(BIOS_DEBUG, "ICH7 watchdog disabled\n"); -} diff --git a/src/southbridge/intel/i82801ix/Kconfig b/src/southbridge/intel/i82801ix/Kconfig index 44b2cbc0e6d..a2697739a86 100644 --- a/src/southbridge/intel/i82801ix/Kconfig +++ b/src/southbridge/intel/i82801ix/Kconfig @@ -29,6 +29,7 @@ config SOUTHBRIDGE_INTEL_I82801IX select SOUTHBRIDGE_INTEL_COMMON_PMCLIB select INTEL_DESCRIPTOR_MODE_CAPABLE select ACPI_INTEL_HARDWARE_SLEEP_VALUES + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG if SOUTHBRIDGE_INTEL_I82801IX diff --git a/src/southbridge/intel/i82801ix/Makefile.inc b/src/southbridge/intel/i82801ix/Makefile.inc index 3cc7da5eadb..caa493211c9 100644 --- a/src/southbridge/intel/i82801ix/Makefile.inc +++ b/src/southbridge/intel/i82801ix/Makefile.inc @@ -29,8 +29,6 @@ ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c -ramstage-y += ../i82801gx/watchdog.c - ifneq ($(CONFIG_SMM_TSEG),y) ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c ramstage-$(CONFIG_HAVE_SMI_HANDLER) += ../../../cpu/x86/smm/smmrelocate.S diff --git a/src/southbridge/intel/i82801jx/Kconfig b/src/southbridge/intel/i82801jx/Kconfig index be2d2897ba3..b423ecae40a 100644 --- a/src/southbridge/intel/i82801jx/Kconfig +++ b/src/southbridge/intel/i82801jx/Kconfig @@ -33,6 +33,7 @@ config SOUTHBRIDGE_INTEL_I82801JX select ACPI_INTEL_HARDWARE_SLEEP_VALUES select HAVE_POWER_STATE_AFTER_FAILURE select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG if SOUTHBRIDGE_INTEL_I82801JX diff --git a/src/southbridge/intel/i82801jx/Makefile.inc b/src/southbridge/intel/i82801jx/Makefile.inc index c333566e0f6..6626bb5d330 100644 --- a/src/southbridge/intel/i82801jx/Makefile.inc +++ b/src/southbridge/intel/i82801jx/Makefile.inc @@ -29,8 +29,6 @@ ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c -ramstage-y += ../i82801gx/watchdog.c - smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c romstage-y += early_smbus.c diff --git a/src/southbridge/intel/ibexpeak/Kconfig b/src/southbridge/intel/ibexpeak/Kconfig index bb6e22cb739..4763133b80c 100644 --- a/src/southbridge/intel/ibexpeak/Kconfig +++ b/src/southbridge/intel/ibexpeak/Kconfig @@ -40,6 +40,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy select HAVE_INTEL_CHIPSET_LOCKDOWN select HAVE_POWER_STATE_AFTER_FAILURE select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG config EHCI_BAR hex diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index 5c890300a4f..2fb371841af 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -31,7 +31,6 @@ ramstage-y += ../common/pciehp.c ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c ramstage-y += ../bd82x6x/me_status.c -ramstage-y += ../bd82x6x/watchdog.c ramstage-$(CONFIG_ELOG) += ../bd82x6x/elog.c ramstage-y += madt.c diff --git a/src/southbridge/intel/lynxpoint/Kconfig b/src/southbridge/intel/lynxpoint/Kconfig index 5573ec96adc..67e20be11f1 100644 --- a/src/southbridge/intel/lynxpoint/Kconfig +++ b/src/southbridge/intel/lynxpoint/Kconfig @@ -42,6 +42,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy select COMMON_FADT select HAVE_POWER_STATE_AFTER_FAILURE select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE + select SOUTHBRIDGE_INTEL_COMMON_WATCHDOG config INTEL_LYNXPOINT_LP bool diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index 04e0bc9909a..f0bfa5bcc3c 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -37,7 +37,6 @@ endif ramstage-y += rcba.c ramstage-y += me_status.c -ramstage-y += watchdog.c ramstage-y += acpi.c ramstage-$(CONFIG_ELOG) += elog.c diff --git a/src/southbridge/intel/lynxpoint/watchdog.c b/src/southbridge/intel/lynxpoint/watchdog.c deleted file mode 100644 index 545d3d50d56..00000000000 --- a/src/southbridge/intel/lynxpoint/watchdog.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * Copyright (C) 2011 Google Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - - // - // Disable PCH Watchdog timer at SB_RCBA+0x3410 - // - // Mmio32((MmPci32(0, 0, 0x1F, 0, 0xF0) & ~BIT0), 0x3410) |= 0x20; - // -void watchdog_off(void) -{ - struct device *dev; - unsigned long value, base; - - /* Turn off the ICH7 watchdog. */ - dev = pcidev_on_root(0x1f, 0); - - /* Enable I/O space. */ - value = pci_read_config16(dev, 0x04); - value |= (1 << 10); - pci_write_config16(dev, 0x04, value); - - /* Get TCO base. */ - base = (pci_read_config32(dev, 0x40) & 0x0fffe) + 0x60; - - /* Disable the watchdog timer. */ - value = inw(base + 0x08); - value |= 1 << 11; - outw(value, base + 0x08); - - /* Clear TCO timeout status. */ - outw(0x0008, base + 0x04); - outw(0x0002, base + 0x06); - - printk(BIOS_DEBUG, "PCH watchdog disabled\n"); -} From d7d0b04d3a0201bc7b2fed913bb623efe0158f81 Mon Sep 17 00:00:00 2001 From: Maxim Polyakov Date: Mon, 6 May 2019 11:54:21 +0300 Subject: [PATCH 209/588] soc/skl/memmap: calculate mem size even if IGD undefined in devtree The DRAM base memory should be calculated even if IGD isn`t defined in the board device tree Tested on Asrock H110M-DVS Change-Id: I3da51473e6c06da803bd969a4a6dff792c18f962 Signed-off-by: Maxim Polyakov Reviewed-on: https://review.coreboot.org/c/coreboot/+/32614 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/skylake/memmap.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/src/soc/intel/skylake/memmap.c b/src/soc/intel/skylake/memmap.c index fde916a9221..ff7edbc95a5 100644 --- a/src/soc/intel/skylake/memmap.c +++ b/src/soc/intel/skylake/memmap.c @@ -170,13 +170,13 @@ static size_t get_prmrr_size(uintptr_t dram_base, } /* Calculate Intel Traditional Memory size based on GSM, DSM, TSEG and DPR. */ -static size_t calculate_traditional_mem_size(uintptr_t dram_base, - const struct device *dev) +static size_t calculate_traditional_mem_size(uintptr_t dram_base) { + const struct device *igd_dev = pcidev_path_on_root(SA_DEVFN_IGD); uintptr_t traditional_mem_base = dram_base; size_t traditional_mem_size; - if (dev->enabled) { + if (igd_dev && igd_dev->enabled) { /* Read BDSM from Host Bridge */ traditional_mem_base -= sa_get_dsm_size(); @@ -200,9 +200,9 @@ static size_t calculate_traditional_mem_size(uintptr_t dram_base, * Calculate Intel Reserved Memory size based on * PRMRR size, Trace Hub config and PTT selection. */ -static size_t calculate_reserved_mem_size(uintptr_t dram_base, - const struct device *dev) +static size_t calculate_reserved_mem_size(uintptr_t dram_base) { + const struct device *dev = pcidev_path_on_root(SA_DEVFN_ROOT); uintptr_t reserve_mem_base = dram_base; size_t reserve_mem_size; const struct soc_intel_skylake_config *config; @@ -259,20 +259,15 @@ static size_t calculate_reserved_mem_size(uintptr_t dram_base, static uintptr_t calculate_dram_base(size_t *reserved_mem_size) { uintptr_t dram_base; - const struct device *dev; - - dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); - if (!dev) - die("ERROR - IGD device not found!"); /* Read TOLUD from Host Bridge offset */ dram_base = sa_get_tolud_base(); /* Get Intel Traditional Memory Range Size */ - dram_base -= calculate_traditional_mem_size(dram_base, dev); + dram_base -= calculate_traditional_mem_size(dram_base); /* Get Intel Reserved Memory Range Size */ - *reserved_mem_size = calculate_reserved_mem_size(dram_base, dev); + *reserved_mem_size = calculate_reserved_mem_size(dram_base); dram_base -= *reserved_mem_size; From 3ba380797b562bbeb7051abd4641bffcf1cf040c Mon Sep 17 00:00:00 2001 From: Maxim Polyakov Date: Mon, 6 May 2019 12:07:24 +0300 Subject: [PATCH 210/588] soc/intel/skylake: remove PrimaryDisplay check Checking the PrimaryDisplay parameter (added by patch with Change Id Ie3f9362676105e41c69139a094dbb9e8b865689f) isn`t required. The display connected to PEG works even if IGD is primary for output image and at the same time this device is disabled Tested on Asrock H110M-DVS with NVIDIA GTX 1060 GPU Payload: tianocore edk2-stable201811-216-g51be9d0 Change-Id: I5615597881a151bb004676d914fbf40874ac1f68 Signed-off-by: Maxim Polyakov Reviewed-on: https://review.coreboot.org/c/coreboot/+/32615 Reviewed-by: Furquan Shaikh Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/soc/intel/skylake/romstage/romstage_fsp20.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index c166e3a7c18..2f75479339a 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -304,10 +304,6 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, */ m_cfg->InternalGfx = 0; m_cfg->IgdDvmt50PreAlloc = 0; - if (config->PrimaryDisplay == Display_iGFX) - m_cfg->PrimaryDisplay = Display_Auto; - else - m_cfg->PrimaryDisplay = config->PrimaryDisplay; } else { m_cfg->InternalGfx = 1; /* @@ -319,8 +315,8 @@ static void soc_primary_gfx_config_params(FSP_M_CONFIG *m_cfg, * a high resolution panel */ m_cfg->IgdDvmt50PreAlloc = 2; - m_cfg->PrimaryDisplay = config->PrimaryDisplay; } + m_cfg->PrimaryDisplay = config->PrimaryDisplay; } void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) From 1a930584482c1cafb7ed02a9c37fcfe7cb61fb3f Mon Sep 17 00:00:00 2001 From: Dan Elkouby Date: Sun, 1 Apr 2018 19:54:57 +0300 Subject: [PATCH 211/588] sb/intel/bd82x6x: Fix flashconsole after lockdown SMM final locks the SPI BAR, which causes flashconsole to hang. Re-init it like SMM does with CONFIG_SPI_FLASH_SMM. Change-Id: Ib802d7ee32f1fb0a68a84b0280480dcaefa9831f Signed-off-by: Dan Elkouby Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/25660 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/southbridge/intel/bd82x6x/lpc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c index e9e49649f27..f7bb7e4303e 100644 --- a/src/southbridge/intel/bd82x6x/lpc.c +++ b/src/southbridge/intel/bd82x6x/lpc.c @@ -908,6 +908,12 @@ static void lpc_final(struct device *dev) if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) { outb(APM_CNT_FINALIZE, APM_CNT); + if (CONFIG(CONSOLE_SPI_FLASH)) + /* Re-init SPI driver to handle locked BAR. + This prevents flashconsole from hanging. + If other code needs to use SPI during + ramstage, whitelist it here. */ + spi_init(); } } } From ac24d3c3118f0ffbf7f26e0ef867c58dbdcc98e3 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 12 Apr 2019 14:42:17 +0200 Subject: [PATCH 212/588] sconfig: Add SMBIOS type 9 entries Add the new field 'smbios_slot_desc', which takes 2 to 4 arguments. The field is valid for PCI devices and only compiled if SMBIOS table generation is enabled. smbios_slot_desc arguments: 1. slot type 2. slot lenth 3. slot designation (optional) 4. slot data width (optional) Example: device pci 1c.1 on smbios_slot_desc "21" "3" "MINI-PCI-FULL" "8" end # PCIe Port #2 Integrated Wireless LAN Tested on Lenovo T520. Change-Id: If95aae3c322d3da47637613b9a872ba1f7af9080 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32307 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Philipp Deppenwiese --- src/include/device/device.h | 6 + util/sconfig/lex.yy.c_shipped | 261 +++++++++++++++-------------- util/sconfig/main.c | 41 ++++- util/sconfig/sconfig.h | 15 ++ util/sconfig/sconfig.l | 73 ++++---- util/sconfig/sconfig.tab.c_shipped | 163 ++++++++++-------- util/sconfig/sconfig.tab.h_shipped | 27 +-- util/sconfig/sconfig.y | 14 +- 8 files changed, 351 insertions(+), 249 deletions(-) diff --git a/src/include/device/device.h b/src/include/device/device.h index 39a4d567a2a..32cf07282ba 100644 --- a/src/include/device/device.h +++ b/src/include/device/device.h @@ -141,6 +141,12 @@ struct device { #if !DEVTREE_EARLY struct chip_operations *chip_ops; const char *name; +#if CONFIG(GENERATE_SMBIOS_TABLES) + u8 smbios_slot_type; + u8 smbios_slot_data_width; + u8 smbios_slot_length; + const char *smbios_slot_designation; +#endif #endif DEVTREE_CONST void *chip_info; }; diff --git a/util/sconfig/lex.yy.c_shipped b/util/sconfig/lex.yy.c_shipped index b3dff41e585..14ffeff9a2b 100644 --- a/util/sconfig/lex.yy.c_shipped +++ b/util/sconfig/lex.yy.c_shipped @@ -168,7 +168,7 @@ extern FILE *yyin, *yyout; do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ + yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ *yy_cp = (yy_hold_char); \ YY_RESTORE_YY_MORE_OFFSET \ @@ -358,8 +358,8 @@ static void yynoreturn yy_fatal_error (yyconst char* msg ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 37 -#define YY_END_OF_BUFFER 38 +#define YY_NUM_RULES 38 +#define YY_END_OF_BUFFER 39 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -367,24 +367,25 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[145] = +static yyconst flex_int16_t yy_accept[160] = { 0, - 0, 0, 38, 36, 1, 3, 36, 36, 36, 31, - 31, 29, 32, 36, 32, 32, 32, 36, 36, 36, - 36, 36, 36, 36, 36, 36, 36, 36, 1, 3, - 36, 0, 36, 36, 0, 2, 31, 32, 36, 36, - 36, 36, 32, 36, 36, 36, 36, 36, 36, 36, - 24, 36, 36, 36, 36, 7, 36, 36, 36, 36, - 36, 36, 35, 35, 36, 0, 30, 36, 36, 16, - 36, 36, 23, 28, 36, 36, 13, 36, 36, 22, - 36, 36, 8, 10, 12, 36, 20, 36, 21, 36, - 0, 33, 4, 36, 36, 36, 36, 36, 36, 36, - - 36, 19, 36, 36, 34, 34, 36, 36, 36, 36, - 36, 36, 36, 14, 36, 36, 36, 5, 17, 36, - 9, 36, 11, 36, 36, 36, 18, 26, 36, 36, - 36, 36, 36, 6, 36, 36, 36, 36, 36, 25, - 36, 15, 27, 0 + 0, 0, 39, 37, 1, 3, 37, 37, 37, 32, + 32, 30, 33, 37, 33, 33, 33, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 1, 3, + 37, 0, 37, 37, 0, 2, 32, 33, 37, 37, + 37, 37, 33, 37, 37, 37, 37, 37, 37, 37, + 24, 37, 37, 37, 37, 7, 37, 37, 37, 37, + 37, 37, 37, 36, 36, 37, 0, 31, 37, 37, + 16, 37, 37, 23, 28, 37, 37, 13, 37, 37, + 22, 37, 37, 8, 10, 12, 37, 37, 20, 37, + 21, 37, 0, 34, 4, 37, 37, 37, 37, 37, + + 37, 37, 37, 19, 37, 37, 37, 35, 35, 37, + 37, 37, 37, 37, 37, 37, 14, 37, 37, 37, + 37, 5, 17, 37, 9, 37, 11, 37, 37, 37, + 37, 18, 26, 37, 37, 37, 37, 37, 37, 6, + 37, 37, 37, 37, 37, 37, 37, 25, 37, 37, + 15, 37, 27, 37, 37, 37, 37, 29, 0 } ; static yyconst YY_CHAR yy_ec[256] = @@ -427,110 +428,114 @@ static yyconst YY_CHAR yy_meta[39] = 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_uint16_t yy_base[152] = +static yyconst flex_uint16_t yy_base[167] = { 0, - 0, 0, 212, 0, 209, 213, 207, 37, 41, 38, - 172, 0, 44, 194, 54, 78, 60, 186, 181, 45, - 188, 177, 42, 47, 182, 41, 169, 0, 199, 213, - 77, 195, 87, 91, 196, 213, 0, 88, 104, 183, - 172, 161, 93, 168, 163, 173, 164, 171, 171, 165, - 171, 156, 156, 160, 162, 0, 158, 152, 158, 155, - 161, 160, 0, 213, 101, 172, 0, 165, 145, 158, - 148, 155, 0, 0, 150, 150, 0, 148, 138, 0, - 142, 137, 0, 0, 0, 140, 0, 131, 0, 158, - 157, 0, 0, 142, 141, 134, 126, 136, 124, 130, - - 135, 0, 120, 114, 0, 213, 125, 129, 121, 123, - 119, 121, 126, 0, 110, 110, 107, 0, 0, 109, - 0, 93, 104, 98, 84, 84, 0, 0, 89, 77, - 87, 71, 66, 0, 64, 62, 50, 47, 33, 0, - 28, 0, 0, 213, 40, 129, 131, 133, 135, 137, - 139 + 0, 0, 227, 0, 224, 228, 222, 37, 41, 38, + 187, 0, 44, 209, 54, 78, 60, 201, 196, 45, + 203, 192, 42, 47, 197, 62, 184, 0, 214, 228, + 77, 210, 88, 69, 211, 228, 0, 87, 104, 198, + 187, 176, 93, 183, 178, 188, 179, 186, 186, 180, + 186, 171, 171, 175, 177, 0, 173, 167, 173, 177, + 169, 175, 174, 0, 228, 101, 186, 0, 179, 159, + 172, 162, 169, 0, 0, 164, 164, 0, 162, 152, + 0, 156, 151, 0, 0, 0, 154, 153, 0, 144, + 0, 171, 170, 0, 0, 155, 154, 147, 139, 149, + + 137, 143, 148, 0, 133, 136, 126, 0, 228, 137, + 141, 133, 135, 131, 133, 138, 0, 122, 122, 121, + 118, 0, 0, 133, 0, 117, 134, 128, 132, 113, + 113, 0, 0, 120, 112, 110, 121, 94, 95, 0, + 94, 92, 97, 86, 85, 84, 76, 0, 71, 78, + 0, 67, 0, 61, 55, 32, 29, 0, 228, 40, + 129, 131, 133, 135, 137, 139 } ; -static yyconst flex_int16_t yy_def[152] = +static yyconst flex_int16_t yy_def[167] = { 0, - 144, 1, 144, 145, 144, 144, 145, 146, 147, 145, - 10, 145, 10, 145, 10, 10, 10, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 144, 144, - 146, 148, 149, 147, 150, 144, 10, 10, 10, 145, - 145, 145, 10, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 144, 149, 151, 39, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 144, 145, 145, 145, 145, 145, 145, 145, 145, 145, - - 145, 145, 145, 145, 145, 144, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 145, 145, 145, 145, 145, - 145, 145, 145, 0, 144, 144, 144, 144, 144, 144, - 144 + 159, 1, 159, 160, 159, 159, 160, 161, 162, 160, + 10, 160, 10, 160, 10, 10, 10, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 159, 159, + 161, 163, 164, 162, 165, 159, 10, 10, 10, 160, + 160, 160, 10, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 159, 164, 166, 39, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 159, 160, 160, 160, 160, 160, 160, 160, + + 160, 160, 160, 160, 160, 160, 160, 160, 159, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, 0, 159, + 159, 159, 159, 159, 159, 159 } ; -static yyconst flex_uint16_t yy_nxt[252] = +static yyconst flex_uint16_t yy_nxt[267] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 10, 12, 13, 13, 14, 4, 4, 4, 13, 13, 15, 16, 17, 13, 18, 19, 20, 21, 22, 4, 23, 24, 4, 25, 26, 4, 27, 4, 4, 4, 32, 32, - 28, 33, 35, 36, 37, 37, 37, 143, 38, 38, + 28, 33, 35, 36, 37, 37, 37, 158, 38, 38, 38, 38, 38, 49, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 55, 142, 57, 38, 38, 38, 56, - 60, 141, 50, 51, 58, 61, 52, 41, 32, 32, - 140, 63, 139, 42, 38, 38, 38, 46, 66, 66, - 138, 28, 35, 36, 38, 38, 38, 137, 43, 38, - - 38, 38, 66, 66, 136, 90, 44, 135, 134, 45, - 67, 67, 67, 133, 67, 67, 132, 131, 130, 129, - 67, 67, 67, 67, 67, 67, 128, 127, 71, 31, - 31, 34, 34, 32, 32, 65, 65, 35, 35, 66, - 66, 126, 125, 124, 123, 122, 121, 120, 119, 118, - 117, 116, 115, 114, 113, 112, 111, 110, 109, 108, - 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, - 97, 96, 95, 94, 93, 92, 91, 89, 88, 87, - 86, 85, 84, 83, 82, 81, 80, 79, 78, 77, - 76, 75, 74, 73, 72, 70, 69, 68, 36, 64, - - 29, 62, 59, 54, 53, 48, 47, 40, 39, 30, - 29, 144, 3, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144 + 38, 38, 38, 55, 157, 57, 38, 38, 38, 56, + 35, 36, 50, 51, 58, 156, 52, 41, 32, 32, + 155, 64, 154, 42, 38, 38, 38, 46, 60, 67, + 67, 61, 28, 38, 38, 38, 62, 153, 43, 38, + + 38, 38, 67, 67, 152, 92, 44, 151, 150, 45, + 68, 68, 68, 149, 68, 68, 148, 147, 146, 145, + 68, 68, 68, 68, 68, 68, 144, 143, 72, 31, + 31, 34, 34, 32, 32, 66, 66, 35, 35, 67, + 67, 142, 141, 140, 139, 138, 137, 136, 135, 134, + 133, 132, 131, 130, 129, 128, 127, 126, 125, 124, + 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, + 113, 112, 111, 110, 109, 108, 107, 106, 105, 104, + 103, 102, 101, 100, 99, 98, 97, 96, 95, 94, + 93, 91, 90, 89, 88, 87, 86, 85, 84, 83, + + 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, + 71, 70, 69, 36, 65, 29, 63, 59, 54, 53, + 48, 47, 40, 39, 30, 29, 159, 3, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159 } ; -static yyconst flex_int16_t yy_chk[252] = +static yyconst flex_int16_t yy_chk[267] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, - 145, 8, 9, 9, 10, 10, 10, 141, 10, 10, + 160, 8, 9, 9, 10, 10, 10, 157, 10, 10, 13, 13, 13, 20, 10, 10, 10, 10, 10, 10, - 15, 15, 15, 23, 139, 24, 17, 17, 17, 23, - 26, 138, 20, 20, 24, 26, 20, 15, 31, 31, - 137, 31, 136, 15, 16, 16, 16, 17, 33, 33, - 135, 33, 34, 34, 38, 38, 38, 133, 16, 43, - - 43, 43, 65, 65, 132, 65, 16, 131, 130, 16, - 39, 39, 39, 129, 39, 39, 126, 125, 124, 123, - 39, 39, 39, 39, 39, 39, 122, 120, 43, 146, - 146, 147, 147, 148, 148, 149, 149, 150, 150, 151, - 151, 117, 116, 115, 113, 112, 111, 110, 109, 108, - 107, 104, 103, 101, 100, 99, 98, 97, 96, 95, - 94, 91, 90, 88, 86, 82, 81, 79, 78, 76, - 75, 72, 71, 70, 69, 68, 66, 62, 61, 60, - 59, 58, 57, 55, 54, 53, 52, 51, 50, 49, - 48, 47, 46, 45, 44, 42, 41, 40, 35, 32, - - 29, 27, 25, 22, 21, 19, 18, 14, 11, 7, - 5, 3, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144 + 15, 15, 15, 23, 156, 24, 17, 17, 17, 23, + 34, 34, 20, 20, 24, 155, 20, 15, 31, 31, + 154, 31, 152, 15, 16, 16, 16, 17, 26, 33, + 33, 26, 33, 38, 38, 38, 26, 150, 16, 43, + + 43, 43, 66, 66, 149, 66, 16, 147, 146, 16, + 39, 39, 39, 145, 39, 39, 144, 143, 142, 141, + 39, 39, 39, 39, 39, 39, 139, 138, 43, 161, + 161, 162, 162, 163, 163, 164, 164, 165, 165, 166, + 166, 137, 136, 135, 134, 131, 130, 129, 128, 127, + 126, 124, 121, 120, 119, 118, 116, 115, 114, 113, + 112, 111, 110, 107, 106, 105, 103, 102, 101, 100, + 99, 98, 97, 96, 93, 92, 90, 88, 87, 83, + 82, 80, 79, 77, 76, 73, 72, 71, 70, 69, + 67, 63, 62, 61, 60, 59, 58, 57, 55, 54, + + 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, + 42, 41, 40, 35, 32, 29, 27, 25, 22, 21, + 19, 18, 14, 11, 7, 5, 3, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 159, 159, 159, 159, 159, 159 } ; static yy_state_type yy_last_accepting_state; @@ -674,7 +679,7 @@ static int input (void ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -687,7 +692,7 @@ static int input (void ); else \ { \ errno=0; \ - while ( (result = (int) fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + while ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \ { \ if( errno != EINTR) \ { \ @@ -809,13 +814,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 145 ) + if ( yy_current_state >= 160 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 213 ); + while ( yy_base[yy_current_state] != 228 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -955,11 +960,11 @@ YY_RULE_SETUP YY_BREAK case 29: YY_RULE_SETUP -{return(EQUALS);} +{return(SLOT_DESC);} YY_BREAK case 30: YY_RULE_SETUP -{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} +{return(EQUALS);} YY_BREAK case 31: YY_RULE_SETUP @@ -971,12 +976,11 @@ YY_RULE_SETUP YY_BREAK case 33: YY_RULE_SETUP -{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(PCIINT);} +{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} YY_BREAK case 34: -/* rule 34 can match eol */ YY_RULE_SETUP -{yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} +{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(PCIINT);} YY_BREAK case 35: /* rule 35 can match eol */ @@ -984,11 +988,16 @@ YY_RULE_SETUP {yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} YY_BREAK case 36: +/* rule 36 can match eol */ YY_RULE_SETUP -{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);} +{yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} YY_BREAK case 37: YY_RULE_SETUP +{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);} + YY_BREAK +case 38: +YY_RULE_SETUP ECHO; YY_BREAK case YY_STATE_EOF(INITIAL): @@ -1135,7 +1144,7 @@ static int yy_get_next_buffer (void) { char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; char *source = (yytext_ptr); - int number_to_move, i; + yy_size_t number_to_move, i; int ret_val; if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) @@ -1164,7 +1173,7 @@ static int yy_get_next_buffer (void) /* Try to read more data. */ /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1); + number_to_move = (yy_size_t) ((yy_c_buf_p) - (yytext_ptr)) - 1; for ( i = 0; i < number_to_move; ++i ) *(dest++) = *(source++); @@ -1200,7 +1209,7 @@ static int yy_get_next_buffer (void) b->yy_ch_buf = (char *) /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); + yyrealloc((void *) b->yy_ch_buf,(yy_size_t) (b->yy_buf_size + 2) ); } else /* Can't grow it, we don't own it. */ @@ -1246,10 +1255,10 @@ static int yy_get_next_buffer (void) else ret_val = EOB_ACT_CONTINUE_SCAN; - if (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + if ((int) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { /* Extend the array by 50%, plus the number we really need. */ int new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,(yy_size_t) new_size ); if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); } @@ -1283,7 +1292,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 145 ) + if ( yy_current_state >= 160 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; @@ -1311,11 +1320,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 145 ) + if ( yy_current_state >= 160 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (flex_int16_t) yy_c]; - yy_is_jam = (yy_current_state == 144); + yy_is_jam = (yy_current_state == 159); return yy_is_jam ? 0 : yy_current_state; } @@ -1510,12 +1519,12 @@ static void yy_load_buffer_state (void) if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - b->yy_buf_size = (yy_size_t)size; + b->yy_buf_size = size; /* yy_ch_buf has to be 2 characters longer than the size given because * we need to put in 2 end-of-buffer characters. */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); + b->yy_ch_buf = (char *) yyalloc((yy_size_t) (b->yy_buf_size + 2) ); if ( ! b->yy_ch_buf ) YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); @@ -1718,7 +1727,7 @@ YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) if ( ! b ) YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_size = (int) (size - 2); /* "- 2" to take care of EOB's */ b->yy_buf_pos = b->yy_ch_buf = base; b->yy_is_our_buffer = 0; b->yy_input_file = NULL; @@ -1801,7 +1810,7 @@ static void yynoreturn yy_fatal_error (yyconst char* msg ) do \ { \ /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ + yy_size_t yyless_macro_arg = (n); \ YY_LESS_LINENO(yyless_macro_arg);\ yytext[yyleng] = (yy_hold_char); \ (yy_c_buf_p) = yytext + yyless_macro_arg; \ diff --git a/util/sconfig/main.c b/util/sconfig/main.c index 5382f470fd0..c3aa17f1a05 100644 --- a/util/sconfig/main.c +++ b/util/sconfig/main.c @@ -622,6 +622,22 @@ void add_register(struct chip_instance *chip_instance, char *name, char *val) } } +void add_slot_desc(struct bus *bus, char *type, char *length, char *designation, + char *data_width) +{ + struct device *dev = bus->dev; + + if (dev->bustype != PCI && dev->bustype != DOMAIN) { + printf("ERROR: 'slot_type' only allowed for PCI devices\n"); + exit(1); + } + + dev->smbios_slot_type = type; + dev->smbios_slot_length = length; + dev->smbios_slot_data_width = data_width; + dev->smbios_slot_designation = designation; +} + void add_pci_subsystem_ids(struct bus *bus, int vendor, int device, int inherit) { @@ -831,7 +847,30 @@ static void pass1(FILE *fil, struct device *ptr, struct device *next) fprintf(fil, "\t.chip_info = &%s_info_%d,\n", chip_ins->chip->name_underscore, chip_ins->id); if (next) - fprintf(fil, "\t.next=&%s\n", next->name); + fprintf(fil, "\t.next=&%s,\n", next->name); + if (ptr->smbios_slot_type || ptr->smbios_slot_data_width || + ptr->smbios_slot_designation || ptr->smbios_slot_length) { + fprintf(fil, "#if !DEVTREE_EARLY\n"); + fprintf(fil, "#if CONFIG(GENERATE_SMBIOS_TABLES)\n"); + } + /* SMBIOS types start at 1, if zero it hasn't been set */ + if (ptr->smbios_slot_type) + fprintf(fil, "\t.smbios_slot_type = %s,\n", + ptr->smbios_slot_type); + if (ptr->smbios_slot_data_width) + fprintf(fil, "\t.smbios_slot_data_width = %s,\n", + ptr->smbios_slot_data_width); + if (ptr->smbios_slot_designation) + fprintf(fil, "\t.smbios_slot_designation = \"%s\",\n", + ptr->smbios_slot_designation); + if (ptr->smbios_slot_length) + fprintf(fil, "\t.smbios_slot_length = %s,\n", + ptr->smbios_slot_length); + if (ptr->smbios_slot_type || ptr->smbios_slot_data_width || + ptr->smbios_slot_designation || ptr->smbios_slot_length) { + fprintf(fil, "#endif\n"); + fprintf(fil, "#endif\n"); + } fprintf(fil, "};\n"); emit_resources(fil, ptr); diff --git a/util/sconfig/sconfig.h b/util/sconfig/sconfig.h index 389d697a332..e6363dea839 100644 --- a/util/sconfig/sconfig.h +++ b/util/sconfig/sconfig.h @@ -141,6 +141,18 @@ struct device { struct bus *bus; /* Pointer to last bus under this device. */ struct bus *last_bus; + + /* SMBIOS slot type */ + char *smbios_slot_type; + + /* SMBIOS slot data width */ + char *smbios_slot_data_width; + + /* SMBIOS slot description for reference designation */ + char *smbios_slot_designation; + + /* SMBIOS slot length */ + char *smbios_slot_length; }; extern struct bus *root_parent; @@ -158,6 +170,9 @@ void add_pci_subsystem_ids(struct bus *bus, int vendor, int device, void add_ioapic_info(struct bus *bus, int apicid, const char *_srcpin, int irqpin); +void add_slot_desc(struct bus *bus, char *type, char *length, char *designation, + char *data_width); + void yyrestart(FILE *input_file); /* Add chip data to tail of queue. */ diff --git a/util/sconfig/sconfig.l b/util/sconfig/sconfig.l index b21cca54b17..87de6e2763f 100755 --- a/util/sconfig/sconfig.l +++ b/util/sconfig/sconfig.l @@ -21,40 +21,41 @@ int linenum = 0; %} %option nodebug %% -[ \t]+ {} -#.*\n {linenum++;} -\r?\n {linenum++;} -chip {return(CHIP);} -device {return(DEVICE);} -register {return(REGISTER);} -on {yylval.number=1; return(BOOL);} -off {yylval.number=0; return(BOOL);} -hidden {yylval.number=3; return(HIDDEN);} -pci {yylval.number=PCI; return(BUS);} -ioapic {yylval.number=IOAPIC; return(BUS);} -pnp {yylval.number=PNP; return(BUS);} -i2c {yylval.number=I2C; return(BUS);} -lapic {yylval.number=APIC; return(BUS);} -cpu_cluster {yylval.number=CPU_CLUSTER; return(BUS);} -cpu {yylval.number=CPU; return(BUS);} -domain {yylval.number=DOMAIN; return(BUS);} -generic {yylval.number=GENERIC; return(BUS);} -mmio {yylval.number=MMIO; return(BUS);} -spi {yylval.number=SPI; return(BUS);} -usb {yylval.number=USB; return(BUS);} -irq {yylval.number=IRQ; return(RESOURCE);} -drq {yylval.number=DRQ; return(RESOURCE);} -io {yylval.number=IO; return(RESOURCE);} -ioapic_irq {return(IOAPIC_IRQ);} -inherit {return(INHERIT);} -subsystemid {return(SUBSYSTEMID);} -end {return(END);} -= {return(EQUALS);} -0x[0-9a-fA-F.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} -[0-9.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} -[0-9a-fA-F.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} -INT[A-D] {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(PCIINT);} -\"\"[^\"]+\"\" {yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} -\"[^\"]+\" {yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} -[^ \n\t]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);} +[ \t]+ {} +#.*\n {linenum++;} +\r?\n {linenum++;} +chip {return(CHIP);} +device {return(DEVICE);} +register {return(REGISTER);} +on {yylval.number=1; return(BOOL);} +off {yylval.number=0; return(BOOL);} +hidden {yylval.number=3; return(HIDDEN);} +pci {yylval.number=PCI; return(BUS);} +ioapic {yylval.number=IOAPIC; return(BUS);} +pnp {yylval.number=PNP; return(BUS);} +i2c {yylval.number=I2C; return(BUS);} +lapic {yylval.number=APIC; return(BUS);} +cpu_cluster {yylval.number=CPU_CLUSTER; return(BUS);} +cpu {yylval.number=CPU; return(BUS);} +domain {yylval.number=DOMAIN; return(BUS);} +generic {yylval.number=GENERIC; return(BUS);} +mmio {yylval.number=MMIO; return(BUS);} +spi {yylval.number=SPI; return(BUS);} +usb {yylval.number=USB; return(BUS);} +irq {yylval.number=IRQ; return(RESOURCE);} +drq {yylval.number=DRQ; return(RESOURCE);} +io {yylval.number=IO; return(RESOURCE);} +ioapic_irq {return(IOAPIC_IRQ);} +inherit {return(INHERIT);} +subsystemid {return(SUBSYSTEMID);} +end {return(END);} +smbios_slot_desc {return(SLOT_DESC);} += {return(EQUALS);} +0x[0-9a-fA-F.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} +[0-9.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} +[0-9a-fA-F.]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);} +INT[A-D] {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(PCIINT);} +\"\"[^\"]+\"\" {yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} +\"[^\"]+\" {yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);} +[^ \n\t]+ {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);} %% diff --git a/util/sconfig/sconfig.tab.c_shipped b/util/sconfig/sconfig.tab.c_shipped index d59a1b6883f..8e1e57de54b 100644 --- a/util/sconfig/sconfig.tab.c_shipped +++ b/util/sconfig/sconfig.tab.c_shipped @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.0.5. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "3.0.4" +#define YYBISON_VERSION "3.0.5" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -144,17 +144,18 @@ extern int yydebug; DOMAIN = 275, IRQ = 276, DRQ = 277, - IO = 278, - NUMBER = 279, - SUBSYSTEMID = 280, - INHERIT = 281, - IOAPIC_IRQ = 282, - IOAPIC = 283, - PCIINT = 284, - GENERIC = 285, - SPI = 286, - USB = 287, - MMIO = 288 + SLOT_DESC = 278, + IO = 279, + NUMBER = 280, + SUBSYSTEMID = 281, + INHERIT = 282, + IOAPIC_IRQ = 283, + IOAPIC = 284, + PCIINT = 285, + GENERIC = 286, + SPI = 287, + USB = 288, + MMIO = 289 }; #endif @@ -429,21 +430,21 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 40 +#define YYLAST 43 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 34 +#define YYNTOKENS 35 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 14 +#define YYNNTS 15 /* YYNRULES -- Number of rules. */ -#define YYNRULES 24 +#define YYNRULES 28 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 43 +#define YYNSTATES 49 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 288 +#define YYMAXUTOK 289 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -480,7 +481,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33 + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34 }; #if YYDEBUG @@ -488,8 +489,8 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyrline[] = { 0, 36, 36, 36, 38, 38, 38, 38, 40, 40, - 40, 40, 40, 40, 42, 42, 51, 51, 59, 59, - 61, 64, 67, 70, 73 + 40, 40, 40, 40, 40, 42, 42, 51, 51, 59, + 59, 61, 64, 67, 70, 73, 76, 79, 82 }; #endif @@ -500,11 +501,12 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "CHIP", "DEVICE", "REGISTER", "BOOL", "HIDDEN", "BUS", "RESOURCE", "END", "EQUALS", "HEX", "STRING", "PCI", - "PNP", "I2C", "APIC", "CPU_CLUSTER", "CPU", "DOMAIN", "IRQ", "DRQ", "IO", - "NUMBER", "SUBSYSTEMID", "INHERIT", "IOAPIC_IRQ", "IOAPIC", "PCIINT", - "GENERIC", "SPI", "USB", "MMIO", "$accept", "devtree", "$@1", - "chipchildren", "devicechildren", "chip", "@2", "device", "@3", "status", - "resource", "registers", "subsystemid", "ioapic_irq", YY_NULLPTR + "PNP", "I2C", "APIC", "CPU_CLUSTER", "CPU", "DOMAIN", "IRQ", "DRQ", + "SLOT_DESC", "IO", "NUMBER", "SUBSYSTEMID", "INHERIT", "IOAPIC_IRQ", + "IOAPIC", "PCIINT", "GENERIC", "SPI", "USB", "MMIO", "$accept", + "devtree", "$@1", "chipchildren", "devicechildren", "chip", "@2", + "device", "@3", "status", "resource", "registers", "subsystemid", + "ioapic_irq", "smbios_slot_desc", YY_NULLPTR }; #endif @@ -516,14 +518,14 @@ static const yytype_uint16 yytoknum[] = 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288 + 285, 286, 287, 288, 289 }; # endif -#define YYPACT_NINF -10 +#define YYPACT_NINF -12 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-10))) + (!!((Yystate) == (-12))) #define YYTABLE_NINF -1 @@ -534,11 +536,11 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int8 yypact[] = { - -10, 11, 9, -10, 1, -10, -10, -10, 0, 5, - 3, -10, -10, -10, -10, -9, 6, 2, 7, -10, - -10, -10, -10, -10, -3, -5, -10, -1, 4, -10, - -10, -10, -10, -10, 10, 8, -4, 12, 13, 14, - -10, -10, -10 + -12, 11, 9, -12, 1, -12, -12, -12, 0, 5, + 3, -12, -12, -12, -12, -10, 6, 2, 8, -12, + -12, -12, -12, -12, -3, -1, -12, 13, 4, 7, + -12, -12, -12, -12, -12, -12, 16, 15, 10, -11, + 12, 17, -5, 14, -12, 18, -12, -12, -12 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -546,25 +548,25 @@ static const yytype_int8 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 2, 0, 0, 1, 0, 3, 14, 7, 0, 0, - 0, 15, 5, 4, 6, 0, 0, 0, 0, 18, - 19, 16, 21, 13, 0, 0, 17, 0, 0, 9, - 8, 10, 11, 12, 0, 0, 0, 0, 22, 0, - 20, 23, 24 + 2, 0, 0, 1, 0, 3, 15, 7, 0, 0, + 0, 16, 5, 4, 6, 0, 0, 0, 0, 19, + 20, 17, 22, 14, 0, 0, 18, 0, 0, 0, + 9, 8, 10, 11, 12, 13, 0, 0, 0, 0, + 0, 28, 23, 0, 21, 27, 24, 25, 26 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -10, -10, -10, -10, -10, -6, -10, 16, -10, -10, - -10, -10, -10, -10 + -12, -12, -12, -12, -12, -6, -12, 19, -12, -12, + -12, -12, -12, -12, -12 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { -1, 1, 2, 8, 24, 5, 7, 13, 23, 21, - 31, 14, 32, 33 + 32, 14, 33, 34, 35 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -573,46 +575,46 @@ static const yytype_int8 yydefgoto[] = static const yytype_uint8 yytable[] = { 4, 9, 12, 4, 9, 10, 25, 26, 19, 20, - 11, 3, 4, 15, 6, 17, 16, 18, 29, 34, - 22, 37, 27, 35, 28, 39, 0, 0, 36, 0, - 0, 0, 38, 0, 0, 0, 40, 0, 42, 41, - 30 + 11, 3, 4, 15, 6, 17, 16, 18, 30, 43, + 27, 22, 46, 28, 36, 29, 37, 40, 41, 38, + 45, 48, 39, 0, 0, 42, 0, 44, 0, 47, + 0, 0, 0, 31 }; static const yytype_int8 yycheck[] = { 3, 4, 8, 3, 4, 5, 9, 10, 6, 7, - 10, 0, 3, 8, 13, 24, 13, 11, 24, 24, - 13, 11, 25, 24, 27, 29, -1, -1, 24, -1, - -1, -1, 24, -1, -1, -1, 24, -1, 24, 26, - 24 + 10, 0, 3, 8, 13, 25, 13, 11, 24, 30, + 23, 13, 27, 26, 25, 28, 13, 11, 13, 25, + 13, 13, 25, -1, -1, 25, -1, 25, -1, 25, + -1, -1, -1, 24 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 35, 36, 0, 3, 39, 13, 40, 37, 4, - 5, 10, 39, 41, 45, 8, 13, 24, 11, 6, - 7, 43, 13, 42, 38, 9, 10, 25, 27, 39, - 41, 44, 46, 47, 24, 24, 24, 11, 24, 29, - 24, 26, 24 + 0, 36, 37, 0, 3, 40, 13, 41, 38, 4, + 5, 10, 40, 42, 46, 8, 13, 25, 11, 6, + 7, 44, 13, 43, 39, 9, 10, 23, 26, 28, + 40, 42, 45, 47, 48, 49, 25, 13, 25, 25, + 11, 13, 25, 30, 25, 13, 27, 25, 13 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 34, 36, 35, 37, 37, 37, 37, 38, 38, - 38, 38, 38, 38, 40, 39, 42, 41, 43, 43, - 44, 45, 46, 46, 47 + 0, 35, 37, 36, 38, 38, 38, 38, 39, 39, + 39, 39, 39, 39, 39, 41, 40, 43, 42, 44, + 44, 45, 46, 47, 47, 48, 49, 49, 49 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 2, 2, 2, 0, 2, 2, - 2, 2, 2, 0, 0, 5, 0, 7, 1, 1, - 4, 4, 3, 4, 4 + 2, 2, 2, 2, 0, 0, 5, 0, 7, 1, + 1, 4, 4, 3, 4, 4, 5, 4, 3 }; @@ -973,6 +975,7 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, case N: \ yyformat = S; \ break + default: /* Avoid compiler warnings. */ YYCASE_(0, YY_("syntax error")); YYCASE_(1, YY_("syntax error, unexpected %s")); YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); @@ -1294,7 +1297,7 @@ yyreduce: break; - case 14: + case 15: { (yyval.chip_instance) = new_chip_instance((yyvsp[0].string)); @@ -1304,7 +1307,7 @@ yyreduce: break; - case 15: + case 16: { cur_chip_instance = chip_dequeue_tail(); @@ -1312,7 +1315,7 @@ yyreduce: break; - case 16: + case 17: { (yyval.dev) = new_device(cur_parent, cur_chip_instance, (yyvsp[-2].number), (yyvsp[-1].string), (yyvsp[0].number)); @@ -1321,7 +1324,7 @@ yyreduce: break; - case 17: + case 18: { cur_parent = (yyvsp[-2].dev)->parent; @@ -1329,36 +1332,54 @@ yyreduce: break; - case 20: + case 21: { add_resource(cur_parent, (yyvsp[-3].number), strtol((yyvsp[-2].string), NULL, 0), strtol((yyvsp[0].string), NULL, 0)); } break; - case 21: + case 22: { add_register(cur_chip_instance, (yyvsp[-2].string), (yyvsp[0].string)); } break; - case 22: + case 23: { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[-1].string), NULL, 16), strtol((yyvsp[0].string), NULL, 16), 0); } break; - case 23: + case 24: { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[-2].string), NULL, 16), strtol((yyvsp[-1].string), NULL, 16), 1); } break; - case 24: + case 25: { add_ioapic_info(cur_parent, strtol((yyvsp[-2].string), NULL, 16), (yyvsp[-1].string), strtol((yyvsp[0].string), NULL, 16)); } break; + case 26: + + { add_slot_desc(cur_parent, (yyvsp[-3].string), (yyvsp[-2].string), (yyvsp[-1].string), (yyvsp[0].string)); } + + break; + + case 27: + + { add_slot_desc(cur_parent, (yyvsp[-2].string), (yyvsp[-1].string), (yyvsp[0].string), NULL); } + + break; + + case 28: + + { add_slot_desc(cur_parent, (yyvsp[-1].string), (yyvsp[0].string), NULL, NULL); } + + break; + default: break; diff --git a/util/sconfig/sconfig.tab.h_shipped b/util/sconfig/sconfig.tab.h_shipped index cabc4743b87..bcbd644b01d 100644 --- a/util/sconfig/sconfig.tab.h_shipped +++ b/util/sconfig/sconfig.tab.h_shipped @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.0.4. */ +/* A Bison parser, made by GNU Bison 3.0.5. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + Copyright (C) 1984, 1989-1990, 2000-2015, 2018 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -65,17 +65,18 @@ extern int yydebug; DOMAIN = 275, IRQ = 276, DRQ = 277, - IO = 278, - NUMBER = 279, - SUBSYSTEMID = 280, - INHERIT = 281, - IOAPIC_IRQ = 282, - IOAPIC = 283, - PCIINT = 284, - GENERIC = 285, - SPI = 286, - USB = 287, - MMIO = 288 + SLOT_DESC = 278, + IO = 279, + NUMBER = 280, + SUBSYSTEMID = 281, + INHERIT = 282, + IOAPIC_IRQ = 283, + IOAPIC = 284, + PCIINT = 285, + GENERIC = 286, + SPI = 287, + USB = 288, + MMIO = 289 }; #endif diff --git a/util/sconfig/sconfig.y b/util/sconfig/sconfig.y index 3a6e9ab8a3d..0d894a9e35a 100755 --- a/util/sconfig/sconfig.y +++ b/util/sconfig/sconfig.y @@ -31,13 +31,13 @@ static struct chip_instance *cur_chip_instance; int number; } -%token CHIP DEVICE REGISTER BOOL HIDDEN BUS RESOURCE END EQUALS HEX STRING PCI PNP I2C APIC CPU_CLUSTER CPU DOMAIN IRQ DRQ IO NUMBER SUBSYSTEMID INHERIT IOAPIC_IRQ IOAPIC PCIINT GENERIC SPI USB MMIO +%token CHIP DEVICE REGISTER BOOL HIDDEN BUS RESOURCE END EQUALS HEX STRING PCI PNP I2C APIC CPU_CLUSTER CPU DOMAIN IRQ DRQ SLOT_DESC IO NUMBER SUBSYSTEMID INHERIT IOAPIC_IRQ IOAPIC PCIINT GENERIC SPI USB MMIO %% devtree: { cur_parent = root_parent; } chip; chipchildren: chipchildren device | chipchildren chip | chipchildren registers | /* empty */ ; -devicechildren: devicechildren device | devicechildren chip | devicechildren resource | devicechildren subsystemid | devicechildren ioapic_irq | /* empty */ ; +devicechildren: devicechildren device | devicechildren chip | devicechildren resource | devicechildren subsystemid | devicechildren ioapic_irq | devicechildren smbios_slot_desc | /* empty */ ; chip: CHIP STRING /* == path */ { $$ = new_chip_instance($2); @@ -72,4 +72,14 @@ subsystemid: SUBSYSTEMID NUMBER NUMBER INHERIT ioapic_irq: IOAPIC_IRQ NUMBER PCIINT NUMBER { add_ioapic_info(cur_parent, strtol($2, NULL, 16), $3, strtol($4, NULL, 16)); }; + +smbios_slot_desc: SLOT_DESC STRING STRING STRING STRING + { add_slot_desc(cur_parent, $2, $3, $4, $5); }; + +smbios_slot_desc: SLOT_DESC STRING STRING STRING + { add_slot_desc(cur_parent, $2, $3, $4, NULL); }; + +smbios_slot_desc: SLOT_DESC STRING STRING + { add_slot_desc(cur_parent, $2, $3, NULL, NULL); }; + %% From bd7739f3aa64aa5409265397722728ba1ffa78ac Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 24 Apr 2019 09:35:51 +0200 Subject: [PATCH 213/588] device: ignore NONE devices behind bridge Ignore NONE devices in dev_is_active_bridge that are commonly used to indicate hotplug capable ports. Tested on Lenovo T520: The empty ExpressCard Slot is no longer marked as active bridge. Change-Id: I23347270aaab17647023969091ce4bcdd41dd57a Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32441 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Philipp Deppenwiese --- src/device/device_util.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/device/device_util.c b/src/device/device_util.c index 5c4f911b8b3..47df3052e24 100644 --- a/src/device/device_util.c +++ b/src/device/device_util.c @@ -628,7 +628,7 @@ void disable_children(struct bus *bus) /* * Returns true if the device is an enabled bridge that has at least - * one enabled device on its secondary bus. + * one enabled device on its secondary bus that is not of type NONE. */ bool dev_is_active_bridge(struct device *dev) { @@ -643,6 +643,9 @@ bool dev_is_active_bridge(struct device *dev) for (link = dev->link_list; link; link = link->next) { for (child = link->children; child; child = child->sibling) { + if (child->path.type == DEVICE_PATH_NONE) + continue; + if (child->enabled) return 1; } From f5b9369720ac0458be13e723468e27ab987b439e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 12 Apr 2019 15:59:40 +0200 Subject: [PATCH 214/588] smbios: Walk over PCI devicetree to fill type 9 Use the devicetree values for type 9 slots. Tested on Lenovo T520. Change-Id: I1961d8af2d21f755ff52ad58804ea9b31d2a5b9b Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32308 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Philipp Deppenwiese --- src/arch/x86/smbios.c | 51 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 7c87c693e1d..589f4f0e305 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -999,6 +999,56 @@ static int smbios_write_type127(unsigned long *current, int handle) return len; } +/* Generate Type9 entries from devicetree */ +static int smbios_walk_device_tree_type9(struct device *dev, int *handle, + unsigned long *current) +{ + enum misc_slot_usage usage; + enum slot_data_bus_bandwidth bandwidth; + enum misc_slot_type type; + enum misc_slot_length length; + + if (dev->path.type != DEVICE_PATH_PCI) + return 0; + + if (!dev->smbios_slot_type && !dev->smbios_slot_data_width && + !dev->smbios_slot_designation && !dev->smbios_slot_length) + return 0; + + if (dev_is_active_bridge(dev)) + usage = SlotUsageInUse; + else if (dev->enabled) + usage = SlotUsageAvailable; + else + usage = SlotUsageUnknown; + + if (dev->smbios_slot_data_width) + bandwidth = dev->smbios_slot_data_width; + else + bandwidth = SlotDataBusWidthUnknown; + + if (dev->smbios_slot_type) + type = dev->smbios_slot_type; + else + type = SlotTypeUnknown; + + if (dev->smbios_slot_length) + length = dev->smbios_slot_length; + else + length = SlotLengthUnknown; + + return smbios_write_type9(current, handle, + dev->smbios_slot_designation, + type, + bandwidth, + usage, + length, + 1, + 0, + dev->bus->secondary, + dev->path.pci.devfn); +} + static int smbios_walk_device_tree(struct device *tree, int *handle, unsigned long *current) { @@ -1011,6 +1061,7 @@ static int smbios_walk_device_tree(struct device *tree, int *handle, dev_name(dev)); len += dev->ops->get_smbios_data(dev, handle, current); } + len += smbios_walk_device_tree_type9(dev, handle, current); } return len; } From d694f6e21b4a24c70adb55b65f095bc87a9878cd Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Mon, 22 Apr 2019 09:41:14 -0700 Subject: [PATCH 215/588] mb/google/sarien: Add SMBIOS type 9 fields Fill SMBIOS type 9 fields for both sarien and arcada platform. BUG=b:129485789 TEST=Boot up into OS and check with dmidecode -t 9 to we do have entry. Signed-off-by: Lijian Zhao Change-Id: I47a697131b7aeeb64e0c4b4c0556842f1cb1b02e Reviewed-on: https://review.coreboot.org/c/coreboot/+/32389 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Patrick Georgi --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 8 ++++++-- src/mainboard/google/sarien/variants/sarien/devicetree.cb | 8 ++++++-- src/soc/intel/cannonlake/chip.h | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 77bd82a64b6..0cc99704888 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -349,11 +349,15 @@ chip soc/intel/cannonlake device pci 1c.5 off end # PCI Express Port 6 device pci 1c.6 off end # PCI Express Port 7 device pci 1c.7 off end # PCI Express Port 8 - device pci 1d.0 on end # PCI Express Port 9 + device pci 1d.0 on + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "2230" "SlotDataBusWidth1X" + end # PCI Express Port 9 device pci 1d.1 on end # PCI Express Port 10 device pci 1d.2 on end # PCI Express Port 11 device pci 1d.3 off end # PCI Express Port 12 - device pci 1d.4 on end # PCI Express Port 13 (x4) + device pci 1d.4 on + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "2280" "SlotDataBusWidth4X" + end # PCI Express Port 13 (x4) device pci 1e.0 off end # UART #0 device pci 1e.1 off end # UART #1 device pci 1e.2 off end # GSPI #0 diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index e9786f14ebf..3807047e0f4 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -378,11 +378,15 @@ chip soc/intel/cannonlake device pci 1c.5 off end # PCI Express Port 6 device pci 1c.6 off end # PCI Express Port 7 device pci 1c.7 on end # PCI Express Port 8 - device pci 1d.0 on end # PCI Express Port 9 + device pci 1d.0 on + smbios_slot_desc "SlotTypeM2Socket1_SD" "SlotLengthOther" "2230" "SlotDataBusWidth1X" + end # PCI Express Port 9 device pci 1d.1 on end # PCI Express Port 10 device pci 1d.2 off end # PCI Express Port 11 device pci 1d.3 off end # PCI Express Port 12 - device pci 1d.4 on end # PCI Express Port 13 (x4) + device pci 1d.4 on + smbios_slot_desc "SlotTypeM2Socket3" "SlotLengthOther" "2280" "SlotDataBusWidth4X" + end # PCI Express Port 13 (x4) device pci 1e.0 off end # UART #0 device pci 1e.1 off end # UART #1 device pci 1e.2 off end # GSPI #0 diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 40d9f71eedb..b17df4b21ba 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include From 052163236c928de11fa9bf8efbd33c1565fb735d Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 12 Apr 2019 16:14:27 +0200 Subject: [PATCH 216/588] mb/lenovo: Add SMBIOS type 9 for ExpressCard Mark all known PCIe root ports as ExpressCard slot. Tested on Lenovo T520. Change-Id: I43fb481512a54ee054c6fd0189053028fb3c3ec2 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32309 Reviewed-by: Philipp Deppenwiese Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t400/devicetree.cb | 1 + src/mainboard/lenovo/t420/devicetree.cb | 1 + src/mainboard/lenovo/t420s/devicetree.cb | 1 + src/mainboard/lenovo/t430/devicetree.cb | 1 + src/mainboard/lenovo/t430s/devicetree.cb | 1 + src/mainboard/lenovo/t520/variants/t520/devicetree.cb | 4 +++- src/mainboard/lenovo/t520/variants/w520/devicetree.cb | 4 +++- src/mainboard/lenovo/t530/variants/t530/devicetree.cb | 4 +++- src/mainboard/lenovo/t530/variants/w530/devicetree.cb | 1 + src/mainboard/lenovo/x200/devicetree.cb | 1 + src/mainboard/lenovo/x201/devicetree.cb | 4 +++- src/mainboard/lenovo/x220/devicetree.cb | 1 + src/mainboard/lenovo/x230/devicetree.cb | 1 + 13 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/mainboard/lenovo/t400/devicetree.cb b/src/mainboard/lenovo/t400/devicetree.cb index 8e90431d5fe..475c45ebbdb 100644 --- a/src/mainboard/lenovo/t400/devicetree.cb +++ b/src/mainboard/lenovo/t400/devicetree.cb @@ -109,6 +109,7 @@ chip northbridge/intel/gm45 end # PCIe Port #3 device pci 1c.3 on subsystemid 0x17aa 0x20f3 # Expresscard + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #4 device pci 1c.4 off end # PCIe Port #5 device pci 1c.5 off end # PCIe Port #6 diff --git a/src/mainboard/lenovo/t420/devicetree.cb b/src/mainboard/lenovo/t420/devicetree.cb index 47c14ef909c..c4092fe901a 100644 --- a/src/mainboard/lenovo/t420/devicetree.cb +++ b/src/mainboard/lenovo/t420/devicetree.cb @@ -94,6 +94,7 @@ chip northbridge/intel/sandybridge device pci 1c.2 off end # PCIe Port #3 device pci 1c.3 on subsystemid 0x17aa 0x21ce + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #4 ExpressCard device pci 1c.4 on subsystemid 0x17aa 0x21ce diff --git a/src/mainboard/lenovo/t420s/devicetree.cb b/src/mainboard/lenovo/t420s/devicetree.cb index 0f09db8fa93..d1e3f754994 100644 --- a/src/mainboard/lenovo/t420s/devicetree.cb +++ b/src/mainboard/lenovo/t420s/devicetree.cb @@ -93,6 +93,7 @@ chip northbridge/intel/sandybridge device pci 1c.2 off end # PCIe Port #3 device pci 1c.3 on subsystemid 0x17aa 0x21d2 + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #4 ExpressCard device pci 1c.4 off end # PCIe Port #5 device pci 1c.5 off end # PCIe Port #6 Intel Gigabit Ethernet PHY (not PCIe) diff --git a/src/mainboard/lenovo/t430/devicetree.cb b/src/mainboard/lenovo/t430/devicetree.cb index 9e731f9fbdb..2731b69ec0c 100644 --- a/src/mainboard/lenovo/t430/devicetree.cb +++ b/src/mainboard/lenovo/t430/devicetree.cb @@ -88,6 +88,7 @@ chip northbridge/intel/sandybridge end device pci 1c.2 on # PCIe Port #3 subsystemid 0x17aa 0x21f3 + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end device pci 1c.3 off # PCIe Port #4 end diff --git a/src/mainboard/lenovo/t430s/devicetree.cb b/src/mainboard/lenovo/t430s/devicetree.cb index 2ecf05ee43d..21d54acf113 100644 --- a/src/mainboard/lenovo/t430s/devicetree.cb +++ b/src/mainboard/lenovo/t430s/devicetree.cb @@ -99,6 +99,7 @@ chip northbridge/intel/sandybridge end # PCIe Port #2 Integrated Wireless LAN device pci 1c.2 on subsystemid 0x17aa 0x21fb + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #3 ExpressCard device pci 1c.3 off end # PCIe Port #4 device pci 1c.4 off end # PCIe Port #5 diff --git a/src/mainboard/lenovo/t520/variants/t520/devicetree.cb b/src/mainboard/lenovo/t520/variants/t520/devicetree.cb index cf8e7ce1d29..5f1bc608637 100644 --- a/src/mainboard/lenovo/t520/variants/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/variants/t520/devicetree.cb @@ -80,7 +80,9 @@ chip northbridge/intel/sandybridge device pci 1c.0 off end # PCIe Port #1 device pci 1c.1 on end # PCIe Port #2 Integrated Wireless LAN device pci 1c.2 off end # PCIe Port #3 - device pci 1c.3 on end # PCIe Port #4 Express Card + device pci 1c.3 on + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" + end # PCIe Port #4 Express Card device pci 1c.4 on end # PCIe Port #5 MMC/SDXC + IEEE1394 device pci 1c.5 off end # PCIe Port #6 Intel Ethernet PHY device pci 1c.6 off end # PCIe Port #7 USB 3.0 only W520 diff --git a/src/mainboard/lenovo/t520/variants/w520/devicetree.cb b/src/mainboard/lenovo/t520/variants/w520/devicetree.cb index 1770ad9722c..ceca46ea841 100644 --- a/src/mainboard/lenovo/t520/variants/w520/devicetree.cb +++ b/src/mainboard/lenovo/t520/variants/w520/devicetree.cb @@ -80,7 +80,9 @@ chip northbridge/intel/sandybridge device pci 1c.0 off end # PCIe Port #1 device pci 1c.1 on end # PCIe Port #2 Integrated Wireless LAN device pci 1c.2 off end # PCIe Port #3 - device pci 1c.3 on end # PCIe Port #4 Express Card + device pci 1c.3 on + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" + end # PCIe Port #4 Express Card device pci 1c.4 on end # PCIe Port #5 MMC/SDXC + IEEE1394 device pci 1c.5 off end # PCIe Port #6 Intel Ethernet PHY device pci 1c.6 on end # PCIe Port #7 USB 3.0 only W520 diff --git a/src/mainboard/lenovo/t530/variants/t530/devicetree.cb b/src/mainboard/lenovo/t530/variants/t530/devicetree.cb index 1a1e7075f26..335543a8f79 100644 --- a/src/mainboard/lenovo/t530/variants/t530/devicetree.cb +++ b/src/mainboard/lenovo/t530/variants/t530/devicetree.cb @@ -83,7 +83,9 @@ chip northbridge/intel/sandybridge device pci 1b.0 on end # High Definition Audio device pci 1c.0 on end # PCIe Port #1 device pci 1c.1 on end # PCIe Port #2 - device pci 1c.2 on end # PCIe Port #3 (expresscard) + device pci 1c.2 on + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" + end # PCIe Port #3 (expresscard) device pci 1c.3 off end # PCIe Port #4 device pci 1c.4 off end # PCIe Port #5 device pci 1c.5 off end # PCIe Port #6 diff --git a/src/mainboard/lenovo/t530/variants/w530/devicetree.cb b/src/mainboard/lenovo/t530/variants/w530/devicetree.cb index 253096c3165..0a80fa1d8c4 100644 --- a/src/mainboard/lenovo/t530/variants/w530/devicetree.cb +++ b/src/mainboard/lenovo/t530/variants/w530/devicetree.cb @@ -98,6 +98,7 @@ chip northbridge/intel/sandybridge end device pci 1c.2 on # PCIe Port #3 subsystemid 0x17aa 0x21f6 + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end device pci 1c.3 off # PCIe Port #4 end diff --git a/src/mainboard/lenovo/x200/devicetree.cb b/src/mainboard/lenovo/x200/devicetree.cb index d800e4fdfe7..2ed4308cfab 100644 --- a/src/mainboard/lenovo/x200/devicetree.cb +++ b/src/mainboard/lenovo/x200/devicetree.cb @@ -113,6 +113,7 @@ chip northbridge/intel/gm45 end # PCIe Port #3 device pci 1c.3 on subsystemid 0x17aa 0x20f3 # Expresscard + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #4 device pci 1c.4 off end # PCIe Port #5 device pci 1c.5 off end # PCIe Port #6 diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb index fa33aeb4313..6ece08bee64 100644 --- a/src/mainboard/lenovo/x201/devicetree.cb +++ b/src/mainboard/lenovo/x201/devicetree.cb @@ -92,7 +92,9 @@ chip northbridge/intel/nehalem device pci 1c.0 on end # PCIe Port #1 device pci 1c.1 on end # PCIe Port #2 (wwan) - device pci 1c.3 on end # PCIe Port #4 (Expresscard) + device pci 1c.3 on + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" + end # PCIe Port #4 (Expresscard) device pci 1c.4 on end # PCIe Port #5 (wlan) device pci 1d.0 on # USB2 EHCI diff --git a/src/mainboard/lenovo/x220/devicetree.cb b/src/mainboard/lenovo/x220/devicetree.cb index 0ec66f59b8a..360de049435 100644 --- a/src/mainboard/lenovo/x220/devicetree.cb +++ b/src/mainboard/lenovo/x220/devicetree.cb @@ -98,6 +98,7 @@ chip northbridge/intel/sandybridge end # PCIe Port #3 device pci 1c.3 on subsystemid 0x17aa 0x21db + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #4 device pci 1c.4 on subsystemid 0x17aa 0x21db diff --git a/src/mainboard/lenovo/x230/devicetree.cb b/src/mainboard/lenovo/x230/devicetree.cb index 68e2f8ea2c1..4687e9ccc3e 100644 --- a/src/mainboard/lenovo/x230/devicetree.cb +++ b/src/mainboard/lenovo/x230/devicetree.cb @@ -110,6 +110,7 @@ chip northbridge/intel/sandybridge end # PCIe Port #2 device pci 1c.2 on subsystemid 0x17aa 0x21fa + smbios_slot_desc "7" "3" "ExpressCard Slot" "8" end # PCIe Port #3 (expresscard) device pci 1c.3 off end # PCIe Port #4 device pci 1c.4 off end # PCIe Port #5 From 1d3b3c3c0955a652a1b602c5fd86dc6c5890e967 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 4 May 2019 08:12:42 +0200 Subject: [PATCH 217/588] {src,util}: Remove duplicated includes Change-Id: Id09cec6b2aae58b131b208e96fec539d068ff68a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32566 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/northbridge/intel/sandybridge/raminit_common.c | 2 +- util/cbmem/cbmem.c | 1 - util/ectool/ectool.c | 1 - util/romcc/romcc.c | 1 - 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index cbbd2317edb..5347c5c4934 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -23,7 +23,7 @@ #include #include #include -#include + #include "raminit_native.h" #include "raminit_common.h" #include "sandybridge.h" diff --git a/util/cbmem/cbmem.c b/util/cbmem/cbmem.c index ae1d2127fba..52fdc9b81f4 100644 --- a/util/cbmem/cbmem.c +++ b/util/cbmem/cbmem.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/util/ectool/ectool.c b/util/ectool/ectool.c index bc3d46cd529..2af45c30f22 100644 --- a/util/ectool/ectool.c +++ b/util/ectool/ectool.c @@ -22,7 +22,6 @@ #include #endif #include -#include #if defined __NetBSD__ || defined __OpenBSD__ diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 4cb2aadcc92..43be1712135 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include From 2dc00fab7c46369bffdedf3afea2af720e4add80 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 20 Oct 2018 17:10:04 +0200 Subject: [PATCH 218/588] ec/lenovo/h8: Add function to query sense state * Add function to wait for sense registers to become valid. * Add function to retrieve Fn-Key state. Tested on Lenovo T500: * It takes about 700msec for the registers to become valid. Tested on Lenovo T520: * It takes less than 150msec for the registers to become valid. Change-Id: Ie27e2881a256c4efb3def11f05070c446db6e5fc Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/29204 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese Reviewed-by: Nico Huber --- src/ec/lenovo/h8/Makefile.inc | 7 +++++ src/ec/lenovo/h8/h8.h | 5 ++++ src/ec/lenovo/h8/sense.c | 54 +++++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) create mode 100644 src/ec/lenovo/h8/sense.c diff --git a/src/ec/lenovo/h8/Makefile.inc b/src/ec/lenovo/h8/Makefile.inc index ebf6d7d7a4b..bccdd91b7d8 100644 --- a/src/ec/lenovo/h8/Makefile.inc +++ b/src/ec/lenovo/h8/Makefile.inc @@ -1,5 +1,12 @@ ifeq ($(CONFIG_EC_LENOVO_H8),y) +ramstage-y += sense.c +verstage-y += sense.c +romstage-y += sense.c +bootblock-y += sense.c +postcar-y += sense.c +smm-y += sense.c + ifneq ($(filter y,$(CONFIG_H8_BEEP_ON_DEATH) $(CONFIG_H8_FLASH_LEDS_ON_DEATH)),) romstage-y += panic.c ramstage-y += panic.c diff --git a/src/ec/lenovo/h8/h8.h b/src/ec/lenovo/h8/h8.h index a46ba1f5e04..14948c55cec 100644 --- a/src/ec/lenovo/h8/h8.h +++ b/src/ec/lenovo/h8/h8.h @@ -38,6 +38,9 @@ void h8_usb_always_on(void); void h8_mainboard_init_dock (void); +int h8_get_fn_key(void); +int h8_get_sense_ready(void); + void h8_bluetooth_enable(int on); bool h8_bluetooth_nv_enable(void); bool h8_has_bdc(struct device *dev); @@ -135,8 +138,10 @@ void h8_ssdt_generator(struct device *dev); #define H8_EVENT_FN_PRESS 0x39 #define H8_STATUS0 0x46 +#define H8_STATUS0_FN_KEY_DOWN 0x01 #define H8_STATUS1 0x47 #define H8_STATUS2 0x48 +#define H8_STATUS3 0x49 #define H8_EVENT_BAT0 0x4a #define H8_EVENT_BAT0_STATE 0x4b diff --git a/src/ec/lenovo/h8/sense.c b/src/ec/lenovo/h8/sense.c new file mode 100644 index 00000000000..b929d7ede38 --- /dev/null +++ b/src/ec/lenovo/h8/sense.c @@ -0,0 +1,54 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Patrick Rudolph + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +#include "h8.h" + +/** + * Return the EC sense status register state. + * + * Observations showed the sense registers are all zero until the EC populates + * them after some time. Likely the EC sets all bits to it's valid state at + * once, but there's no prove as the firmware isn't available. + * + * Wait for any register having at least one bit set. + * Unlikely that all register will be zero after booting has finished. + * + * @return 1 if the EC provides valid data in sense status registers + */ +int h8_get_sense_ready(void) +{ + static const u8 regs[] = { H8_STATUS0, H8_STATUS1, H8_STATUS2, + H8_STATUS3}; + + for (size_t i = 0; i < ARRAY_SIZE(regs); i++) { + if (ec_read(regs[i])) + return 1; + } + + return 0; +} + +/** + * Return the state of Fn key. + * Only valid if h8_get_sense_ready (see above) returns true. + * + * @return 1 if the key is pressed. + */ +int h8_get_fn_key(void) +{ + return ec_read(H8_STATUS0) & H8_STATUS0_FN_KEY_DOWN; +} From 25212117534f0cb29939a7fc6c1271ca0fa083cd Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 5 May 2019 11:15:25 +0200 Subject: [PATCH 219/588] ec/lenovo/h8: Add VBOOT board support Use Fn-Key as recovery mode switch. Tested using Icb7b263ed86551cc53e1db7babccaca6b3ae2fe6. Change-Id: I2c682431b3f09839db265259205104bd9ef4abfc Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32607 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- src/ec/lenovo/h8/Kconfig | 8 +++++ src/ec/lenovo/h8/Makefile.inc | 6 ++++ src/ec/lenovo/h8/vboot.c | 55 +++++++++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 src/ec/lenovo/h8/vboot.c diff --git a/src/ec/lenovo/h8/Kconfig b/src/ec/lenovo/h8/Kconfig index b109831105c..d8749754280 100644 --- a/src/ec/lenovo/h8/Kconfig +++ b/src/ec/lenovo/h8/Kconfig @@ -32,6 +32,14 @@ config H8_HAS_BAT_TRESHOLDS_IMPL bool default n +config H8_FN_KEY_AS_VBOOT_RECOVERY_SW + bool "Enable Fn-Key as VBOOT recovery switch" + depends on VBOOT + default n + help + If VBOOT is enabled, press Fn-Key at power on to force a recovery mode + boot instead of regular FW_MAIN_x boot. + endif config H8_DOCK_EARLY_INIT diff --git a/src/ec/lenovo/h8/Makefile.inc b/src/ec/lenovo/h8/Makefile.inc index bccdd91b7d8..51c11be625d 100644 --- a/src/ec/lenovo/h8/Makefile.inc +++ b/src/ec/lenovo/h8/Makefile.inc @@ -7,6 +7,12 @@ bootblock-y += sense.c postcar-y += sense.c smm-y += sense.c +ramstage-$(CONFIG_VBOOT) += vboot.c +verstage-$(CONFIG_VBOOT) += vboot.c +romstage-$(CONFIG_VBOOT) += vboot.c +bootblock-$(CONFIG_VBOOT) += vboot.c +postcar-$(CONFIG_VBOOT) += vboot.c + ifneq ($(filter y,$(CONFIG_H8_BEEP_ON_DEATH) $(CONFIG_H8_FLASH_LEDS_ON_DEATH)),) romstage-y += panic.c ramstage-y += panic.c diff --git a/src/ec/lenovo/h8/vboot.c b/src/ec/lenovo/h8/vboot.c new file mode 100644 index 00000000000..3b9f74a117b --- /dev/null +++ b/src/ec/lenovo/h8/vboot.c @@ -0,0 +1,55 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Patrick Rudolph + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +#include "h8.h" + +/** + * HACK: Use Fn-Key as recovery mode switch. + * Wait for sense register ready and read Fn-Key state. + */ +int get_recovery_mode_switch(void) +{ + struct stopwatch sw; + + if (!CONFIG(H8_FN_KEY_AS_VBOOT_RECOVERY_SW)) + return 0; + + /* Tests showed that it takes: + * - 700msec on Lenovo T500 from AC power on + * - less than 150msec on Lenovo T520 from AC power on + */ + stopwatch_init_msecs_expire(&sw, 1000); + while (!stopwatch_expired(&sw) && !h8_get_sense_ready()) + mdelay(1); + + if (!h8_get_sense_ready()) + return 0; + + return h8_get_fn_key(); +} + +/** + * Only used if CONFIG_CHROMEOS is set. + * Always zero as the #WP pin of the flash is tied high. + */ +int get_write_protect_state(void) +{ + return 0; +} From 62bc1cb88ba0103189f6c1c957207c9520986043 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sat, 4 May 2019 14:19:32 +0200 Subject: [PATCH 220/588] mb/lenovo/*: Add support for VBOOT on 8MiB devices Enable VBOOT support on all devices that have a 8 MiB flash, using a single RW_MAIN_A partition, allowing the use of tianocore payload in both RW_MAIN_A and WP_RO. * Add VBNV section to cmos.layout * Add FMAP for VBOOT and regular boot * Select Kconfigs for VBOOT * Enable VBOOT_SLOTS_RW_A by default Also build test VBOOT on Lenovo T420. Tested on Lenovo T520 using Icb7b263ed86551cc53e1db7babccaca6b3ae2fe6. Change-Id: Icb7b263ed86551cc53e1db7babccaca6b3ae2fe6 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32585 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese Reviewed-by: Patrick Georgi --- ...novo_t420_static_option_table_no_mem_fuses | 2 ++ src/mainboard/lenovo/t420/Kconfig | 20 +++++++++++++ src/mainboard/lenovo/t420/board.fmd | 16 ++++++++++ src/mainboard/lenovo/t420/cmos.layout | 3 ++ src/mainboard/lenovo/t420/vboot-rwa.fmd | 29 +++++++++++++++++++ src/mainboard/lenovo/t420s/Kconfig | 20 +++++++++++++ src/mainboard/lenovo/t420s/board.fmd | 16 ++++++++++ src/mainboard/lenovo/t420s/cmos.layout | 3 ++ src/mainboard/lenovo/t420s/vboot-rwa.fmd | 29 +++++++++++++++++++ src/mainboard/lenovo/t520/Kconfig | 20 +++++++++++++ src/mainboard/lenovo/t520/board.fmd | 16 ++++++++++ src/mainboard/lenovo/t520/cmos.layout | 3 ++ src/mainboard/lenovo/t520/vboot-rwa.fmd | 29 +++++++++++++++++++ src/mainboard/lenovo/x220/Kconfig | 19 ++++++++++++ src/mainboard/lenovo/x220/board.fmd | 16 ++++++++++ src/mainboard/lenovo/x220/cmos.layout | 3 ++ src/mainboard/lenovo/x220/vboot-rwa.fmd | 29 +++++++++++++++++++ 17 files changed, 273 insertions(+) create mode 100644 src/mainboard/lenovo/t420/board.fmd create mode 100644 src/mainboard/lenovo/t420/vboot-rwa.fmd create mode 100644 src/mainboard/lenovo/t420s/board.fmd create mode 100644 src/mainboard/lenovo/t420s/vboot-rwa.fmd create mode 100644 src/mainboard/lenovo/t520/board.fmd create mode 100644 src/mainboard/lenovo/t520/vboot-rwa.fmd create mode 100644 src/mainboard/lenovo/x220/board.fmd create mode 100644 src/mainboard/lenovo/x220/vboot-rwa.fmd diff --git a/configs/config.lenovo_t420_static_option_table_no_mem_fuses b/configs/config.lenovo_t420_static_option_table_no_mem_fuses index a268d88b78d..0a3513cfac4 100644 --- a/configs/config.lenovo_t420_static_option_table_no_mem_fuses +++ b/configs/config.lenovo_t420_static_option_table_no_mem_fuses @@ -4,4 +4,6 @@ CONFIG_VENDOR_LENOVO=y CONFIG_BOARD_LENOVO_T420=y CONFIG_NATIVE_RAMINIT_IGNORE_MAX_MEM_FUSES=y CONFIG_NATIVE_RAMINIT_IGNORE_XMP_MAX_DIMMS=y +CONFIG_VBOOT=y +CONFIG_H8_FN_KEY_AS_VBOOT_RECOVERY_SW=y # CONFIG_INTEL_CHIPSET_LOCKDOWN is not set diff --git a/src/mainboard/lenovo/t420/Kconfig b/src/mainboard/lenovo/t420/Kconfig index ce81907ccbc..3d3b56ae22d 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -28,6 +28,26 @@ config BOARD_SPECIFIC_OPTIONS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE +config VBOOT + select VBOOT_VBNV_CMOS + select GBB_FLAG_DISABLE_LID_SHUTDOWN + select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_FWMP + select HAS_RECOVERY_MRC_CACHE + +config VBOOT_SLOTS_RW_A + default y + +config VBOOT_VBNV_OFFSET + hex + default 0x2a + +config FMDFILE + string + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" + config MAINBOARD_DIR string default lenovo/t420 diff --git a/src/mainboard/lenovo/t420/board.fmd b/src/mainboard/lenovo/t420/board.fmd new file mode 100644 index 00000000000..04cf827a87c --- /dev/null +++ b/src/mainboard/lenovo/t420/board.fmd @@ -0,0 +1,16 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_MRC_CACHE@0 0x10000 + SMMSTORE(PRESERVE)@0x10000 0x40000 + + WP_RO@0x50000 0x2a0000 { + FMAP@0x0 0x800 + COREBOOT(CBFS)@0x1000 0x29f000 + } + } +} diff --git a/src/mainboard/lenovo/t420/cmos.layout b/src/mainboard/lenovo/t420/cmos.layout index f55c2037d56..a9f5f5ff471 100644 --- a/src/mainboard/lenovo/t420/cmos.layout +++ b/src/mainboard/lenovo/t420/cmos.layout @@ -81,6 +81,9 @@ entries 440 8 h 0 volume +# VBOOT +448 128 r 0 vbnv + # SandyBridge MRC Scrambler Seed values 896 32 r 0 mrc_scrambler_seed 928 32 r 0 mrc_scrambler_seed_s3 diff --git a/src/mainboard/lenovo/t420/vboot-rwa.fmd b/src/mainboard/lenovo/t420/vboot-rwa.fmd new file mode 100644 index 00000000000..8a4cd3b4776 --- /dev/null +++ b/src/mainboard/lenovo/t420/vboot-rwa.fmd @@ -0,0 +1,29 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_SECTION_A@0x00000 0x180000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x16ffc0 + RW_FWID_A@0x17ffc0 0x40 + } + UNIFIED_MRC_CACHE@0x180000 0x20000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + } + RW_VPD(PRESERVE)@0x1a0000 0x1000 + SMMSTORE(PRESERVE)@0x1a1000 0x40000 + + WP_RO@0x1e1000 0x11f000 { + FMAP@0x0 0x800 + RO_FRID@0x800 0x40 + RO_PADDING@0x840 0x7c0 + RO_VPD(PRESERVE)@0x1000 0x1000 + GBB@0x2000 0x1e000 + COREBOOT(CBFS)@0x20000 0xff000 + } + } +} diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index c5efb556537..1383d4166c2 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -27,6 +27,26 @@ config BOARD_SPECIFIC_OPTIONS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE +config VBOOT + select VBOOT_VBNV_CMOS + select GBB_FLAG_DISABLE_LID_SHUTDOWN + select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_FWMP + select HAS_RECOVERY_MRC_CACHE + +config VBOOT_SLOTS_RW_A + default y + +config VBOOT_VBNV_OFFSET + hex + default 0x2a + +config FMDFILE + string + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" + config MAINBOARD_DIR string default lenovo/t420s diff --git a/src/mainboard/lenovo/t420s/board.fmd b/src/mainboard/lenovo/t420s/board.fmd new file mode 100644 index 00000000000..04cf827a87c --- /dev/null +++ b/src/mainboard/lenovo/t420s/board.fmd @@ -0,0 +1,16 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_MRC_CACHE@0 0x10000 + SMMSTORE(PRESERVE)@0x10000 0x40000 + + WP_RO@0x50000 0x2a0000 { + FMAP@0x0 0x800 + COREBOOT(CBFS)@0x1000 0x29f000 + } + } +} diff --git a/src/mainboard/lenovo/t420s/cmos.layout b/src/mainboard/lenovo/t420s/cmos.layout index 2be55f67c7a..172191a59ae 100644 --- a/src/mainboard/lenovo/t420s/cmos.layout +++ b/src/mainboard/lenovo/t420s/cmos.layout @@ -81,6 +81,9 @@ entries 440 8 h 0 volume +# VBOOT +448 128 r 0 vbnv + # SandyBridge MRC Scrambler Seed values 896 32 r 0 mrc_scrambler_seed 928 32 r 0 mrc_scrambler_seed_s3 diff --git a/src/mainboard/lenovo/t420s/vboot-rwa.fmd b/src/mainboard/lenovo/t420s/vboot-rwa.fmd new file mode 100644 index 00000000000..8a4cd3b4776 --- /dev/null +++ b/src/mainboard/lenovo/t420s/vboot-rwa.fmd @@ -0,0 +1,29 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_SECTION_A@0x00000 0x180000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x16ffc0 + RW_FWID_A@0x17ffc0 0x40 + } + UNIFIED_MRC_CACHE@0x180000 0x20000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + } + RW_VPD(PRESERVE)@0x1a0000 0x1000 + SMMSTORE(PRESERVE)@0x1a1000 0x40000 + + WP_RO@0x1e1000 0x11f000 { + FMAP@0x0 0x800 + RO_FRID@0x800 0x40 + RO_PADDING@0x840 0x7c0 + RO_VPD(PRESERVE)@0x1000 0x1000 + GBB@0x2000 0x1e000 + COREBOOT(CBFS)@0x20000 0xff000 + } + } +} diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index 06f296bc6df..ba17e8092b3 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -27,6 +27,21 @@ config BOARD_LENOVO_BASEBOARD_T520 if BOARD_LENOVO_BASEBOARD_T520 +config VBOOT + select VBOOT_VBNV_CMOS + select GBB_FLAG_DISABLE_LID_SHUTDOWN + select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_FWMP + select HAS_RECOVERY_MRC_CACHE + +config VBOOT_SLOTS_RW_A + default y + +config VBOOT_VBNV_OFFSET + hex + default 0x2a + config VARIANT_DIR string default "t520" if BOARD_LENOVO_T520 @@ -40,6 +55,11 @@ config DEVICETREE string default "variants/$(CONFIG_VARIANT_DIR)/devicetree.cb" +config FMDFILE + string + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" + config MAINBOARD_PART_NUMBER string default "ThinkPad T520" if BOARD_LENOVO_T520 diff --git a/src/mainboard/lenovo/t520/board.fmd b/src/mainboard/lenovo/t520/board.fmd new file mode 100644 index 00000000000..04cf827a87c --- /dev/null +++ b/src/mainboard/lenovo/t520/board.fmd @@ -0,0 +1,16 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_MRC_CACHE@0 0x10000 + SMMSTORE(PRESERVE)@0x10000 0x40000 + + WP_RO@0x50000 0x2a0000 { + FMAP@0x0 0x800 + COREBOOT(CBFS)@0x1000 0x29f000 + } + } +} diff --git a/src/mainboard/lenovo/t520/cmos.layout b/src/mainboard/lenovo/t520/cmos.layout index 1a7943e5a43..ec6ce858ebf 100644 --- a/src/mainboard/lenovo/t520/cmos.layout +++ b/src/mainboard/lenovo/t520/cmos.layout @@ -81,6 +81,9 @@ entries #437 3 r 0 unused 440 8 h 0 volume +# VBOOT +448 128 r 0 vbnv + # SandyBridge MRC Scrambler Seed values 896 32 r 0 mrc_scrambler_seed 928 32 r 0 mrc_scrambler_seed_s3 diff --git a/src/mainboard/lenovo/t520/vboot-rwa.fmd b/src/mainboard/lenovo/t520/vboot-rwa.fmd new file mode 100644 index 00000000000..8a4cd3b4776 --- /dev/null +++ b/src/mainboard/lenovo/t520/vboot-rwa.fmd @@ -0,0 +1,29 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_SECTION_A@0x00000 0x180000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x16ffc0 + RW_FWID_A@0x17ffc0 0x40 + } + UNIFIED_MRC_CACHE@0x180000 0x20000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + } + RW_VPD(PRESERVE)@0x1a0000 0x1000 + SMMSTORE(PRESERVE)@0x1a1000 0x40000 + + WP_RO@0x1e1000 0x11f000 { + FMAP@0x0 0x800 + RO_FRID@0x800 0x40 + RO_PADDING@0x840 0x7c0 + RO_VPD(PRESERVE)@0x1000 0x1000 + GBB@0x2000 0x1e000 + COREBOOT(CBFS)@0x20000 0xff000 + } + } +} diff --git a/src/mainboard/lenovo/x220/Kconfig b/src/mainboard/lenovo/x220/Kconfig index 16f42e850ec..358cf8ec39c 100644 --- a/src/mainboard/lenovo/x220/Kconfig +++ b/src/mainboard/lenovo/x220/Kconfig @@ -26,6 +26,21 @@ config BOARD_SPECIFIC_OPTIONS # Workaround for EC/KBC IRQ1. select SERIRQ_CONTINUOUS_MODE +config VBOOT + select VBOOT_VBNV_CMOS + select GBB_FLAG_DISABLE_LID_SHUTDOWN + select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_FWMP + select HAS_RECOVERY_MRC_CACHE + +config VBOOT_SLOTS_RW_A + default y + +config VBOOT_VBNV_OFFSET + hex + default 0x2a + config MAINBOARD_DIR string default lenovo/x220 @@ -35,6 +50,10 @@ config VARIANT_DIR default "x220" if BOARD_LENOVO_X220 || BOARD_LENOVO_X220I default "x1" if BOARD_LENOVO_X1 +config FMDFILE + string + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" config MAINBOARD_PART_NUMBER string diff --git a/src/mainboard/lenovo/x220/board.fmd b/src/mainboard/lenovo/x220/board.fmd new file mode 100644 index 00000000000..04cf827a87c --- /dev/null +++ b/src/mainboard/lenovo/x220/board.fmd @@ -0,0 +1,16 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_MRC_CACHE@0 0x10000 + SMMSTORE(PRESERVE)@0x10000 0x40000 + + WP_RO@0x50000 0x2a0000 { + FMAP@0x0 0x800 + COREBOOT(CBFS)@0x1000 0x29f000 + } + } +} diff --git a/src/mainboard/lenovo/x220/cmos.layout b/src/mainboard/lenovo/x220/cmos.layout index d4a4ed33718..dc98010ea22 100644 --- a/src/mainboard/lenovo/x220/cmos.layout +++ b/src/mainboard/lenovo/x220/cmos.layout @@ -80,6 +80,9 @@ entries #435 549 r 0 unused 440 8 h 0 volume +# VBOOT +448 128 r 0 vbnv + # SandyBridge MRC Scrambler Seed values 896 32 r 0 mrc_scrambler_seed 928 32 r 0 mrc_scrambler_seed_s3 diff --git a/src/mainboard/lenovo/x220/vboot-rwa.fmd b/src/mainboard/lenovo/x220/vboot-rwa.fmd new file mode 100644 index 00000000000..8a4cd3b4776 --- /dev/null +++ b/src/mainboard/lenovo/x220/vboot-rwa.fmd @@ -0,0 +1,29 @@ +FLASH@0xff800000 0x800000 { + SI_ALL@0x0 0x500000 { + SI_DESC@0x0 0x1000 + SI_GBE@0x1000 0x2000 + SI_ME@0x3000 0x4ed000 + } + SI_BIOS@0x500000 0x300000 { + RW_SECTION_A@0x00000 0x180000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x16ffc0 + RW_FWID_A@0x17ffc0 0x40 + } + UNIFIED_MRC_CACHE@0x180000 0x20000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + } + RW_VPD(PRESERVE)@0x1a0000 0x1000 + SMMSTORE(PRESERVE)@0x1a1000 0x40000 + + WP_RO@0x1e1000 0x11f000 { + FMAP@0x0 0x800 + RO_FRID@0x800 0x40 + RO_PADDING@0x840 0x7c0 + RO_VPD(PRESERVE)@0x1000 0x1000 + GBB@0x2000 0x1e000 + COREBOOT(CBFS)@0x20000 0xff000 + } + } +} From fe80bf2fd1e4f027d68af1c5bc58a8b1344a806d Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 5 May 2019 16:38:04 +0200 Subject: [PATCH 221/588] Documentation: Convert vboot to markdown Convert the HTML document to markdown and place it under security section. Change-Id: I212c6d0c977fd6772371ff6676478d48cc215d6e Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32610 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- Documentation/Intel/index.html | 1 - Documentation/Intel/vboot.html | 402 -------------------------- Documentation/security/index.md | 1 + Documentation/security/vboot/index.md | 324 +++++++++++++++++++++ 4 files changed, 325 insertions(+), 403 deletions(-) delete mode 100644 Documentation/Intel/vboot.html create mode 100644 Documentation/security/vboot/index.md diff --git a/Documentation/Intel/index.html b/Documentation/Intel/index.html index b4daa960a9d..9d8aad05e9d 100644 --- a/Documentation/Intel/index.html +++ b/Documentation/Intel/index.html @@ -29,7 +29,6 @@

x86 coreboot Development

  • SoC support
  • Board support
  • -
  • Verified Boot (vboot) support
  • diff --git a/Documentation/Intel/vboot.html b/Documentation/Intel/vboot.html deleted file mode 100644 index ca49ac2e2d8..00000000000 --- a/Documentation/Intel/vboot.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - vboot - Verified Boot Support - - - -

    vboot - Verified Boot Support

    - -

    -Google's verified boot support consists of: -

    -
      -
    • A root of trust
    • -
    • Special firmware layout
    • -
    • Firmware verification
    • -
    • Firmware measurements
    • -
    • A firmware update mechanism
    • -
    • Specific build flags
    • -
    • Signing the coreboot image
    • -
    - -Google's vboot verifies the firmware and places measurements -within the TPM. - -
    -

    Root of Trust

    -

    -When using vboot, the root-of-trust is basically the read-only portion of the -SPI flash. The following items factor into the trust equation: -

    -
      -
    • The GCC compiler must reliably translate the code into machine code - without inserting any additional code (virus, backdoor, etc.) -
    • -
    • The CPU must reliably execute the reset sequence and instructions as - documented by the CPU manufacturer. -
    • -
    • The SPI flash must provide only the code programmed into it to the CPU - without providing any alternative reset vector or code sequence. -
    • -
    • The SPI flash must honor the write-protect input and protect the - specified portion of the SPI flash from all erase and write accesses. -
    • -
    - -

    -The firmware is typically protected using the write-protect pin on the SPI -flash part and setting some of the write-protect bits in the status register -during manufacturing. The protected area is platform specific and for x86 -platforms is typically 1/4th of the SPI flash -part size. Because this portion of the SPI flash is hardware write protected, -it is not possible to update this portion of the SPI flash in the field, -without altering the system to eliminate the ground connection to the SPI flash -write-protect pin. Without hardware modifications, this portion of the SPI -flash maintains the manufactured state during the system's lifetime. -

    - -
    -

    Firmware Layout

    -

    -Several sections are added to the firmware layout to support vboot: -

    -
      -
    • Read-only section
    • -
    • Google Binary Blob (GBB) area
    • -
    • Read/write section A
    • -
    • Read/write section B
    • -
    -

    -The following sections describe the various portions of the flash layout. -

    - -

    Read-Only Section

    -

    -The read-only section contains a coreboot file system (CBFS) that contains all -of the boot firmware necessary to perform recovery for the system. This -firmware is typically protected using the write-protect pin on the SPI flash -part and setting some of the write-protect bits in the status register during -manufacturing. The protected area is typically 1/4th of the SPI flash part -size and must cover the entire read-only section which consists of: -

    -
      -
    • Vital Product Data (VPD) area
    • -
    • Firmware ID area
    • -
    • Google Binary Blob (GBB) area
    • -
    • coreboot file system containing read-only recovery firmware
    • -
    - -

    Google Binary Blob (GBB) Area

    -

    -The GBB area is part of the read-only section. This area contains a 4096 or -8192 bit public root RSA key that is used to verify the VBLOCK area to obtain -the firmware signing key. -

    - -

    Recovery Firmware

    -

    -The recovery firmware is contained within a coreboot file system and consists -of: -

    -
      -
    • reset vector
    • -
    • bootblock
    • -
    • verstage
    • -
    • romstage
    • -
    • postcar
    • -
    • ramstage
    • -
    • payload
    • -
    • flash map file
    • -
    • config file
    • -
    • processor specific files: -
        -
      • Microcode
      • -
      • fspm.bin
      • -
      • fsps.bin
      • -
      -
    • -
    - -

    -The recovery firmware is written during manufacturing and typically contains -code to write the storage device (eMMC device or hard disk). The recovery -image is usually contained on a socketed device such as a USB flash drive or -an SD card. Depending upon the payload firmware doing the recovery, it may -be possible for the user to interact with the system to specify the recovery -image path. Part of the recovery is also to write the A and B areas of the -SPI flash device to boot the system. -

    - - -

    Read/Write Section

    - -

    -The read/write sections contain an area which contains the firmware signing -key and signature and an area containing a coreboot file system with a subset -of the firmware. The firmware files in FW_MAIN_A and FW_MAIN_B are: -

    -
      -
    • romstage
    • -
    • postcar
    • -
    • ramstage
    • -
    • payload
    • -
    • config file
    • -
    • processor specific files: -
        -
      • Microcode
      • -
      • fspm.bin
      • -
      • fsps.bin
      • -
      -
    • -
    - -

    -The firmware subset enables most issues to be fixed in the field with firmware -updates. The firmware files handle memory and most of silicon initialization. -These files also produce the tables which get passed to the operating system. -

    - -
    -

    Firmware Updates

    -

    -The read/write sections exist in one of three states: -

    -
      -
    • Invalid
    • -
    • Ready to boot
    • -
    • Successfully booted
    • -
    - - - - - -
    -Where is this state information written? -
    CMOS? -
    RW_NVRAM? -
    RW_FWID_* -
    - -

    -Firmware updates are handled by the operating system by writing any read/write -section that is not in the "successfully booted" state. Upon the next reboot, -vboot determines the section to boot. If it finds one in the "ready to boot" -state then it attempts to boot using that section. If the boot fails then -vboot marks the section as invalid and attempts to fall back to a read/write -section in the "successfully booted" state. If vboot is not able to find a -section in the "successfully booted" state then vboot enters recovery mode. -

    - -

    -Only the operating system is able to transition a section from the "ready to -boot" state to the "successfully booted" state. The transition is typically -done after the operating system has been running for a while indicating -that successful boot was possible and the operating system is stable. -

    - -

    -Note that as long as the SPI write protection is in place then the system is -always recoverable. If the flash update fails then the system will continue -to boot using the previous read/write area. The same is true if coreboot -passes control to the payload or the operating system and then the boot fails. -In the worst case, the SPI flash gets totally corrupted in which case vboot -fails the signature checks and enters recovery mode. There are no times where -the SPI flash is exposed and the reset vector or part of the recovery firmware -gets corrupted. -

    - -
    -

    Build Flags

    -

    -The following Kconfig values need to be selected to enable vboot: -

    -
      -
    • COLLECT_TIMESTAMPS
    • -
    • VBOOT
    • -
    - -

    -The starting stage needs to be specified by selecting either -VBOOT_STARTS_IN_BOOTBLOCK or VBOOT_STARTS_IN_ROMSTAGE. -

    - -

    -If vboot starts in bootblock then vboot may be built as a separate stage by -selecting VBOOT_SEPARATE_VERSTAGE. Additionally, if static RAM is too small -to fit both verstage and romstage then selecting VBOOT_RETURN_FROM_VERSTAGE -enables bootblock to reuse the RAM occupied by verstage for romstage. -

    - -

    -Non-volatile flash is needed for vboot operation. This flash area may be in -CMOS, the EC, or in a read/write area of the SPI flash device. Select one of -the following: -

    -
      -
    • VBOOT_VBNV_CMOS
    • -
    • VBOOT_VBNV_EC
    • -
    • VBOOT_VBNV_FLASH
    • -
    -

    -More non-volatile storage features may be found in src/vboot/Kconfig. -

    - -

    -A TPM is also required for vboot operation. TPMs are available in -drivers/i2c/tpm and drivers/pc80/tpm. -

    - -

    -In addition to adding the coreboot files into the read-only region, enabling -vboot causes the build script to add the read/write files into coreboot file -systems in FW_MAIN_A and FW_MAIN_B. -

    - -
    -

    Signing the coreboot Image

    -

    -The following command script is an example of how to sign the coreboot image file. -This script is used on the Intel Galileo board and creates the GBB area and -inserts it into the coreboot image. It also updates the VBLOCK areas with the -firmware signing key and the signature for the FW_MAIN firmware. More details -are available in 3rdparty/vboot/README. -

    - -
    #!/bin/sh
    -#
    -#  The necessary tools were built and installed using the following commands:
    -#
    -#        pushd 3rdparty/vboot
    -#        make
    -#        sudo make install
    -#        popd
    -#
    -#  The keys were made using the following command
    -#
    -#        3rdparty/vboot/scripts/keygeneration/create_new_keys.sh  \
    -#                --4k --4k-root --output $PWD/keys
    -#
    -#
    -#  The "magic" numbers below are derived from the GBB section in
    -#  src/mainboard/intel/galileo/vboot.fmd.
    -#
    -#  GBB Header Size:     0x80
    -#  GBB Offset:      0x611000, 4KiB block number: 1553 (0x611)
    -#  GBB Length:       0x7f000, 4KiB blocks:        127  (0x7f)
    -#  COREBOOT Offset: 0x690000, 4KiB block number: 1680 (0x690)
    -#  COREBOOT Length: 0x170000, 4KiB blocks:        368 (0x170)
    -#
    -#  0x7f000 (GBB Length) = 0x80 + 0x100 + 0x1000 + 0x7ce80 + 0x1000
    -#
    -#  Create the GBB area blob
    -#  Parameters: hwid_size,rootkey_size,bmpfv_size,recoverykey_size
    -#
    -gbb_utility -c 0x100,0x1000,0x7ce80,0x1000 gbb.blob
    -
    -#
    -#  Copy from the start of the flash to the GBB region into the signed flash
    -#  image.
    -#
    -#  1553 * 4096 = 0x611 * 0x1000 = 0x611000, size of area before GBB
    -#
    -dd  conv=fdatasync  ibs=4096  obs=4096  count=1553  \
    -    if=build/coreboot.rom  of=build/coreboot.signed.rom
    -
    -#
    -#  Append the empty GBB area to the coreboot.rom image.
    -#
    -#  1553 * 4096 = 0x611 * 0x1000 = 0x611000, offset to GBB
    -#
    -dd  conv=fdatasync  obs=4096  obs=4096  seek=1553  if=gbb.blob  \
    -    of=build/coreboot.signed.rom
    -
    -#
    -#  Append the rest of the read-only region into the signed flash image.
    -#
    -#  1680 * 4096 = 0x690 * 0x1000 = 0x690000, offset to COREBOOT area
    -#   368 * 4096 = 0x170 * 0x1000 = 0x170000, length of COREBOOT area
    -#
    -dd  conv=fdatasync  ibs=4096  obs=4096  skip=1680  seek=1680  count=368  \
    -    if=build/coreboot.rom  of=build/coreboot.signed.rom
    -
    -#
    -#  Insert the HWID and public root and recovery RSA keys into the GBB area.
    -#
    -gbb_utility                          \
    -   --set --hwid='Galileo'            \
    -   -r $PWD/keys/recovery_key.vbpubk  \
    -   -k $PWD/keys/root_key.vbpubk      \
    -   build/coreboot.signed.rom
    -
    -#
    -#  Sign the read/write firmware areas with the private signing key and update
    -#  the VBLOCK_A and VBLOCK_B regions.
    -#
    -3rdparty/vboot/scripts/image_signing/sign_firmware.sh  \
    -   build/coreboot.signed.rom                           \
    -   $PWD/keys                                           \
    -   build/coreboot.signed.rom
    -
    - -
    -

    Boot Flow

    -

    -The reset vector exist in the read-only area and points to the bootblock entry -point. The only copy of the bootblock exists in the read-only area of the SPI -flash. Verstage may be part of the bootblock or a separate stage. If separate -then the bootblock loads verstage from the read-only area and transfers control -to it. -

    - -

    -Upon first boot, verstage attempts to verify the read/write section A. It gets -the public root key from the GBB area and uses that to verify the VBLOCK area -in read-write section A. If the VBLOCK area is valid then it extracts the -firmware signing key (1024-8192 bits) and uses that to verify the FW_MAIN_A -area of read/write section A. If the verification is successful then verstage -instructs coreboot to use the coreboot file system in read/write section A for -the contents of the remaining boot firmware (romstage, postcar, ramstage and -the payload). -

    - -

    -If verification fails for the read/write area and the other read/write area is -not valid vboot falls back to the read-only area to boot into system recovery. -

    - -
    -

    Chromebook Special Features

    -

    -Google's Chromebooks have some special features: -

    -
      -
    • Developer mode
    • -
    • Write-protect screw
    • -
    - -

    Developer Mode

    -

    -Developer mode allows the user to use coreboot to boot another operating system. -This may be a another (beta) version of Chrome OS, or another flavor of -GNU/Linux. Use of developer mode does not void the system warranty. Upon -entry into developer mode, all locally saved data on the system is lost. -This prevents someone from entering developer mode to subvert the system -security to access files on the local system or cloud. -

    - -

    Write Protect Screw

    -

    -Chromebooks have a write-protect screw which provides the ground to the -write-protect pin of the SPI flash. Google specifically did this to allow -the manufacturing line and advanced developers to re-write the entire SPI flash -part. Once the screw is removed, any firmware may be placed on the device. -However, accessing this screw requires opening the case and voids the system -warranty! -

    - -
    -

    Modified: 2 May 2017

    - - diff --git a/Documentation/security/index.md b/Documentation/security/index.md index 89db42eceec..9ad54866c2a 100644 --- a/Documentation/security/index.md +++ b/Documentation/security/index.md @@ -4,4 +4,5 @@ This section describes documentation about the security architecture of coreboot ## Vendor +- [Verified Boot](vboot/index.md) - [Measured Boot](vboot/measured_boot.md) diff --git a/Documentation/security/vboot/index.md b/Documentation/security/vboot/index.md new file mode 100644 index 00000000000..97420893e57 --- /dev/null +++ b/Documentation/security/vboot/index.md @@ -0,0 +1,324 @@ +# vboot - Verified Boot Support + +Google's verified boot support consists of: + +* A root of trust +* Special firmware layout +* Firmware verification +* Firmware measurements +* A firmware update mechanism +* Specific build flags +* Signing the coreboot image + +Google's vboot verifies the firmware and places measurements within the TPM. + +*** + +## Root of Trust + +When using vboot, the root-of-trust is basically the read-only portion of the +SPI flash. The following items factor into the trust equation: + +* The GCC compiler must reliably translate the code into machine code + without inserting any additional code (virus, backdoor, etc.) +* The CPU must reliably execute the reset sequence and instructions as + documented by the CPU manufacturer. +* The SPI flash must provide only the code programmed into it to the CPU + without providing any alternative reset vector or code sequence. +* The SPI flash must honor the write-protect input and protect the specified + portion of the SPI flash from all erase and write accesses. + +The firmware is typically protected using the write-protect pin on the SPI +flash part and setting some of the write-protect bits in the status register +during manufacturing. The protected area is platform specific and for x86 +platforms is typically 1/4th of the SPI flash part size. +Because this portion of the SPI flash is hardware write protected, it is not +possible to update this portion of the SPI flash in the field, without altering +the system to eliminate the ground connection to the SPI flash write-protect pin. +Without hardware modifications, this portion of the SPI flash maintains the +manufactured state during the system's lifetime. + +*** + +## Firmware Layout + +Several sections are added to the firmware layout to support vboot: + +* Read-only section +* Google Binary Blob (GBB) area +* Read/write section A +* Read/write section B + +The following sections describe the various portions of the flash layout. + +### Read-Only Section + +The read-only section contains a coreboot file system (CBFS) that contains all +of the boot firmware necessary to perform recovery for the system. This firmware +is typically protected using the write-protect pin on the SPI flash part and +setting some of the write-protect bits in the status register during +manufacturing. +The protected area is typically 1/4th of the SPI flash part size and must cover +the entire read-only section which consists of: + +* Vital Product Data (VPD) area +* Firmware ID area +* Google Binary Blob (GBB) area +* coreboot file system containing read-only recovery firmware + +### Google Binary Blob (GBB) Area + +The GBB area is part of the read-only section. This area contains a 4096 or 8192 +bit public root RSA key that is used to verify the *VBLOCK* area to obtain the +firmware signing key. + +### Recovery Firmware + +The recovery firmware is contained within a coreboot file system and consists of: + +* reset vector +* bootblock +* verstage +* romstage +* postcar +* ramstage +* payload +* flash map file +* config file +* processor specific files: + * Microcode + * fspm.bin + * fsps.bin + +The recovery firmware is written during manufacturing and typically contains +code to write the storage device (eMMC device or hard disk). The recovery image +is usually contained on a socketed device such as a USB flash drive or an +SD card. Depending upon the payload firmware doing the recovery, it may be +possible for the user to interact with the system to specify the recovery +image path. Part of the recovery is also to write the A and B areas of the SPI +flash device to boot the system. + +### Read/Write Section + +The read/write sections contain an area which contains the firmware signing +key and signature and an area containing a coreboot file system with a subset +of the firmware. The firmware files in *FW_MAIN_A* and *FW_MAIN_B* are: + +* romstage +* postcar +* ramstage +* payload +* config file +* processor specific files: + * Microcode + * fspm.bin + * fsps.bin + +The firmware subset enables most issues to be fixed in the field with firmware +updates. The firmware files handle memory and most of silicon initialization. +These files also produce the tables which get passed to the operating system. + +*** + +## Firmware Updates + +The read/write sections exist in one of three states: + +* Invalid +* Ready to boot +* Successfully booted + + +Firmware updates are handled by the operating system by writing any read/write +section that is not in the "successfully booted" state. Upon the next reboot, +vboot determines the section to boot. If it finds one in the "ready to boot" +state then it attempts to boot using that section. If the boot fails then +vboot marks the section as invalid and attempts to fall back to a read/write +section in the "successfully booted" state. If vboot is not able to find a +section in the "successfully booted" state then vboot enters recovery mode. + +Only the operating system is able to transition a section from the +"ready to boot" state to the "successfully booted" state. +The transition is typically done after the operating system has been running +for a while indicating that successful boot was possible and the operating +system is stable. + +Note that as long as the SPI write protection is in place then the system +is always recoverable. If the flash update fails then the system will continue +to boot using the previous read/write area. The same is true if coreboot passes +control to the payload or the operating system and then the boot fails. In the +worst case, the SPI flash gets totally corrupted in which case vboot fails the +signature checks and enters recovery mode. There are no times where the SPI +flash is exposed and the reset vector or part of the recovery firmware gets +corrupted. + +*** + +## Build Flags + +The following *Kconfig* values need to be selected to enable vboot: + +* COLLECT_TIMESTAMPS +* VBOOT + +The starting stage needs to be specified by selecting either +VBOOT_STARTS_IN_BOOTBLOCK or VBOOT_STARTS_IN_ROMSTAGE. + +If vboot starts in bootblock then vboot may be built as a separate stage by +selecting `VBOOT_SEPARATE_VERSTAGE`. Additionally, if static RAM is too small +to fit both verstage and romstage then selecting `VBOOT_RETURN_FROM_VERSTAGE` +enables bootblock to reuse the RAM occupied by verstage for romstage. + +Non-volatile flash is needed for vboot operation. This flash area may be in +CMOS, the EC, or in a read/write area of the SPI flash device. +Select one of the following: + +* `VBOOT_VBNV_CMOS` +* `VBOOT_VBNV_EC` +* `VBOOT_VBNV_FLASH` + +More non-volatile storage features may be found in `security/vboot/Kconfig`. + +A TPM is also required for vboot operation. +TPMs are available in `drivers/i2c/tpm` and `drivers/pc80/tpm`. + +In addition to adding the coreboot files into the read-only region, +enabling vboot causes the build script to add the read/write files into +coreboot file systems in *FW_MAIN_A* and *FW_MAIN_B*. + +*** + +## Signing the coreboot Image + +The following command script is an example of how to sign the coreboot image +file. This script is used on the Intel Galileo board and creates the *GBB* area +and inserts it into the coreboot image. It also updates the *VBLOCK* areas with +the firmware signing key and the signature for the *FW_MAIN* firmware. +More details are available in `3rdparty/vboot/README`. + +```bash +#!/bin/sh +# +# The necessary tools were built and installed using the following commands: +# +# pushd 3rdparty/vboot +# make +# sudo make install +# popd +# +# The keys were made using the following command +# +# 3rdparty/vboot/scripts/keygeneration/create_new_keys.sh \ +# --4k --4k-root --output $PWD/keys +# +# +# The "magic" numbers below are derived from the GBB section in +# src/mainboard/intel/galileo/vboot.fmd. +# +# GBB Header Size: 0x80 +# GBB Offset: 0x611000, 4KiB block number: 1553 (0x611) +# GBB Length: 0x7f000, 4KiB blocks: 127 (0x7f) +# COREBOOT Offset: 0x690000, 4KiB block number: 1680 (0x690) +# COREBOOT Length: 0x170000, 4KiB blocks: 368 (0x170) +# +# 0x7f000 (GBB Length) = 0x80 + 0x100 + 0x1000 + 0x7ce80 + 0x1000 +# +# Create the GBB area blob +# Parameters: hwid_size,rootkey_size,bmpfv_size,recoverykey_size +# +gbb_utility -c 0x100,0x1000,0x7ce80,0x1000 gbb.blob + +# +# Copy from the start of the flash to the GBB region into the signed flash +# image. +# +# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, size of area before GBB +# +dd conv=fdatasync ibs=4096 obs=4096 count=1553 \ +if=build/coreboot.rom of=build/coreboot.signed.rom + +# +# Append the empty GBB area to the coreboot.rom image. +# +# 1553 * 4096 = 0x611 * 0x1000 = 0x611000, offset to GBB +# +dd conv=fdatasync obs=4096 obs=4096 seek=1553 if=gbb.blob \ +of=build/coreboot.signed.rom + +# +# Append the rest of the read-only region into the signed flash image. +# +# 1680 * 4096 = 0x690 * 0x1000 = 0x690000, offset to COREBOOT area +# 368 * 4096 = 0x170 * 0x1000 = 0x170000, length of COREBOOT area +# +dd conv=fdatasync ibs=4096 obs=4096 skip=1680 seek=1680 count=368 \ +if=build/coreboot.rom of=build/coreboot.signed.rom + +# +# Insert the HWID and public root and recovery RSA keys into the GBB area. +# +gbb_utility \ +--set --hwid='Galileo' \ +-r $PWD/keys/recovery_key.vbpubk \ +-k $PWD/keys/root_key.vbpubk \ +build/coreboot.signed.rom + +# +# Sign the read/write firmware areas with the private signing key and update +# the VBLOCK_A and VBLOCK_B regions. +# +3rdparty/vboot/scripts/image_signing/sign_firmware.sh \ +build/coreboot.signed.rom \ +$PWD/keys \ + build/coreboot.signed.rom +``` + +*** + +## Boot Flow + +The reset vector exist in the read-only area and points to the bootblock +entry point. The only copy of the bootblock exists in the read-only area +of the SPI flash. Verstage may be part of the bootblock or a separate stage. +If separate then the bootblock loads verstage from the read-only area and +transfers control to it. + +Upon first boot, verstage attempts to verify the read/write section A. +It gets the public root key from the GBB area and uses that to verify the +*VBLOCK* area in read-write section A. If the *VBLOCK* area is valid then it +extracts the firmware signing key (1024-8192 bits) and uses that to verify +the *FW_MAIN_A* area of read/write section A. If the verification is successful +then verstage instructs coreboot to use the coreboot file system in read/write +section A for the contents of the remaining boot firmware (romstage, postcar, +ramstage and the payload). + +If verification fails for the read/write area and the other read/write area is +not valid vboot falls back to the read-only area to boot into system recovery. + +*** + +## Chromebook Special Features + +Google's Chromebooks have some special features: + +* Developer mode +* Write-protect screw + +### Developer Mode + +Developer mode allows the user to use coreboot to boot another operating system. +This may be a another (beta) version of Chrome OS, or another flavor of +GNU/Linux. Use of developer mode does not void the system warranty. Upon entry +into developer mode, all locally saved data on the system is lost. +This prevents someone from entering developer mode to subvert the system +security to access files on the local system or cloud. + +### Write Protect Screw + +Chromebooks have a write-protect screw which provides the ground to the +write-protect pin of the SPI flash. +Google specifically did this to allow the manufacturing line and advanced +developers to re-write the entire SPI flash part. Once the screw is removed, +any firmware may be placed on the device. +However, accessing this screw requires opening the case and voids the +system warranty! From 5de4771360c0e57bd76bc81850298091e0b9bde7 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Wed, 1 May 2019 16:14:42 -0600 Subject: [PATCH 222/588] soc/amd/stoneyridge: Rename AcpiMmio blocks A subsequent patch will move the AcpiMmio support into amd/common. Take this opportunity to rename the blocks in the 0xfed8xxxx region with more consistency. Change-Id: I9a69a6ecfc10f78b4860df05a77a061d2fc8be7d Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32642 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/mainboard/google/kahlee/mainboard.c | 4 +- .../include/baseboard/acpi/audio.asl | 2 +- src/soc/amd/stoneyridge/acpi/gpio_lib.asl | 2 +- src/soc/amd/stoneyridge/acpi/sb_fch.asl | 2 +- src/soc/amd/stoneyridge/gpio.c | 14 +++-- src/soc/amd/stoneyridge/include/soc/iomap.h | 34 +++++++---- src/soc/amd/stoneyridge/sb_util.c | 56 +++++++++---------- src/soc/amd/stoneyridge/sm.c | 4 +- src/soc/amd/stoneyridge/smbus_spd.c | 4 +- src/soc/amd/stoneyridge/southbridge.c | 16 +++--- 10 files changed, 75 insertions(+), 63 deletions(-) diff --git a/src/mainboard/google/kahlee/mainboard.c b/src/mainboard/google/kahlee/mainboard.c index 1bf6c070455..ad979a567fd 100644 --- a/src/mainboard/google/kahlee/mainboard.c +++ b/src/mainboard/google/kahlee/mainboard.c @@ -145,13 +145,13 @@ static void mainboard_init(void *chip_info) pm_write8(PM_PCIB_CFG, pm_read8(PM_PCIB_CFG) | PM_GENINT_DISABLE); /* Set low-power mode for BayHub eMMC bridge's PCIe clock. */ - clrsetbits_le32((uint32_t *)(MISC_MMIO_BASE + GPP_CLK_CNTRL), + clrsetbits_le32((uint32_t *)(ACPIMMIO_MISC_BASE + GPP_CLK_CNTRL), GPP_CLK2_REQ_MAP_MASK, GPP_CLK2_REQ_MAP_CLK_REQ2 << GPP_CLK2_REQ_MAP_SHIFT); /* Same for the WiFi */ - clrsetbits_le32((uint32_t *)(MISC_MMIO_BASE + GPP_CLK_CNTRL), + clrsetbits_le32((uint32_t *)(ACPIMMIO_MISC_BASE + GPP_CLK_CNTRL), GPP_CLK0_REQ_MAP_MASK, GPP_CLK0_REQ_MAP_CLK_REQ0 << GPP_CLK0_REQ_MAP_SHIFT); diff --git a/src/mainboard/google/kahlee/variants/baseboard/include/baseboard/acpi/audio.asl b/src/mainboard/google/kahlee/variants/baseboard/include/baseboard/acpi/audio.asl index 6bb41ae6b34..87890daf36a 100644 --- a/src/mainboard/google/kahlee/variants/baseboard/include/baseboard/acpi/audio.asl +++ b/src/mainboard/google/kahlee/variants/baseboard/include/baseboard/acpi/audio.asl @@ -35,7 +35,7 @@ Device (I2S) Name (RBUF, ResourceTemplate () { // Memory resource is for MISC FCH register set. // It is needed for enabling the clock. - Memory32Fixed(ReadWrite, MISC_MMIO_BASE, 0x100) + Memory32Fixed(ReadWrite, ACPIMMIO_MISC_BASE, 0x100) }) Return (RBUF) diff --git a/src/soc/amd/stoneyridge/acpi/gpio_lib.asl b/src/soc/amd/stoneyridge/acpi/gpio_lib.asl index d18b147d71c..8185c35ac52 100644 --- a/src/soc/amd/stoneyridge/acpi/gpio_lib.asl +++ b/src/soc/amd/stoneyridge/acpi/gpio_lib.asl @@ -19,7 +19,7 @@ Method (GPAD, 0x1) { /* Arg0 - GPIO pin number */ - Return (Add(Multiply(Arg0, 4), GPIO_CONTROL_MMIO_BASE)) + Return (Add(Multiply(Arg0, 4), ACPIMMIO_GPIO0_BASE)) } /* Read pin control dword */ diff --git a/src/soc/amd/stoneyridge/acpi/sb_fch.asl b/src/soc/amd/stoneyridge/acpi/sb_fch.asl index 114401e24b1..4c1196dad64 100644 --- a/src/soc/amd/stoneyridge/acpi/sb_fch.asl +++ b/src/soc/amd/stoneyridge/acpi/sb_fch.asl @@ -144,7 +144,7 @@ Device (MISC) Name (_HID, "AMD0040") Name (_UID, 0x3) Name (_CRS, ResourceTemplate() { - Memory32Fixed(ReadWrite, MISC_MMIO_BASE, 0x100) + Memory32Fixed(ReadWrite, ACPIMMIO_MISC_BASE, 0x100) }) Method (_STA, 0x0, NotSerialized) { diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c index da1ba0bb74e..b747538eaab 100644 --- a/src/soc/amd/stoneyridge/gpio.c +++ b/src/soc/amd/stoneyridge/gpio.c @@ -228,7 +228,7 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) uint8_t mux, index, gpio; int gevent_num; - inter_master = (uint32_t *)(uintptr_t)(GPIO_CONTROL_MMIO_BASE + inter_master = (uint32_t *)(uintptr_t)(ACPIMMIO_GPIO0_BASE + GPIO_MASTER_SWITCH); direction = 0; edge_level = 0; @@ -252,7 +252,7 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) control = gpio_list_ptr[index].control; control_flags = gpio_list_ptr[index].flags; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE); + mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); write8(mux_ptr, mux & AMD_GPIO_MUX_MASK); read8(mux_ptr); /* Flush posted write */ /* special case if pin 2 is assigned to wake */ @@ -316,11 +316,13 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) mem_read_write32(inter_master, GPIO_INTERRUPT_EN, GPIO_INTERRUPT_EN); /* Set all SCI trigger direction (high/low) */ - mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_TRIG), + mem_read_write32((uint32_t *) + (uintptr_t)(ACPIMMIO_SMI_BASE + SMI_SCI_TRIG), direction, mask); /* Set all SCI trigger level (edge/level) */ - mem_read_write32((uint32_t *)(uintptr_t)(APU_SMI_BASE + SMI_SCI_LEVEL), + mem_read_write32((uint32_t *) + (uintptr_t)(ACPIMMIO_SMI_BASE + SMI_SCI_LEVEL), edge_level, mask); } @@ -348,7 +350,7 @@ static void save_i2c_pin_registers(uint8_t gpio, uint32_t *gpio_ptr; uint8_t *mux_ptr; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE); + mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); gpio_ptr = (uint32_t *)gpio_get_address(gpio); save_table->mux_value = read8(mux_ptr); save_table->control_value = read32(gpio_ptr); @@ -360,7 +362,7 @@ static void restore_i2c_pin_registers(uint8_t gpio, uint32_t *gpio_ptr; uint8_t *mux_ptr; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + GPIO_IOMUX_MMIO_BASE); + mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); gpio_ptr = (uint32_t *)gpio_get_address(gpio); write8(mux_ptr, save_table->mux_value); read8(mux_ptr); diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 613dd044f60..e6327dc6db6 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -32,19 +32,29 @@ #endif #define HPET_BASE_ADDRESS 0xfed00000 -/* Register blocks at fixed offsets from FED8_0000h and enabled in PMx04[1] */ +/* AcpiMmio blocks are at fixed offsets from FED8_0000h, enabled in PMx04[1] */ #define AMD_SB_ACPI_MMIO_ADDR 0xfed80000 -#define APU_SMI_BASE 0xfed80200 -#define PM_MMIO_BASE 0xfed80300 -#define BIOSRAM_MMIO_BASE 0xfed80500 -#define ACPI_REG_MMIO_BASE 0xfed80800 -#define ASF_MMIO_BASE 0xfed80900 -#define SMBUS_MMIO_BASE 0xfed80a00 -#define GPIO_IOMUX_MMIO_BASE 0xfed80d00 -#define MISC_MMIO_BASE 0xfed80e00 -#define XHCI_ACPI_PM_MMIO_BASE 0xfed81c00 -#define GPIO_CONTROL_MMIO_BASE 0xfed81500 -#define AOAC_MMIO_BASE 0xfed81e00 +#define ACPIMMIO_SM_PCI_BASE 0xfed80000 +#define ACPIMMIO_SMI_BASE 0xfed80200 +#define ACPIMMIO_PMIO_BASE 0xfed80300 +#define ACPIMMIO_PMIO2_BASE 0xfed80400 +#define ACPIMMIO_BIOSRAM_BASE 0xfed80500 +#define ACPIMMIO_CMOSRAM_BASE 0xfed80600 +#define ACPIMMIO_CMOS_BASE 0xfed80700 +#define ACPIMMIO_ACPI_BASE 0xfed80800 +#define ACPIMMIO_ASF_BASE 0xfed80900 +#define ACPIMMIO_SMBUS_BASE 0xfed80a00 +#define ACPIMMIO_WDT_BASE 0xfed80b00 +#define ACPIMMIO_HPET_BASE 0xfed80c00 +#define ACPIMMIO_IOMUX_BASE 0xfed80d00 +#define ACPIMMIO_MISC_BASE 0xfed80e00 +#define ACPIMMIO_DPVGA_BASE 0xfed81400 +#define ACPIMMIO_GPIO0_BASE 0xfed81500 +#define ACPIMMIO_GPIO1_BASE 0xfed81600 +#define ACPIMMIO_GPIO2_BASE 0xfed81700 +#define ACPIMMIO_XHCIPM_BASE 0xfed81c00 +#define ACPIMMIO_ACDCTMR_BASE 0xfed81d00 +#define ACPIMMIO_AOAC_BASE 0xfed81e00 #define APU_UART0_BASE 0xfedc6000 #define APU_UART1_BASE 0xfedc8000 diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index b60f186ac89..3005f4101f7 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -20,112 +20,112 @@ void pm_write8(u8 reg, u8 value) { - write8((void *)(PM_MMIO_BASE + reg), value); + write8((void *)(ACPIMMIO_PMIO_BASE + reg), value); } u8 pm_read8(u8 reg) { - return read8((void *)(PM_MMIO_BASE + reg)); + return read8((void *)(ACPIMMIO_PMIO_BASE + reg)); } void pm_write16(u8 reg, u16 value) { - write16((void *)(PM_MMIO_BASE + reg), value); + write16((void *)(ACPIMMIO_PMIO_BASE + reg), value); } u16 pm_read16(u8 reg) { - return read16((void *)(PM_MMIO_BASE + reg)); + return read16((void *)(ACPIMMIO_PMIO_BASE + reg)); } void misc_write32(u8 reg, u32 value) { - write32((void *)(MISC_MMIO_BASE + reg), value); + write32((void *)(ACPIMMIO_MISC_BASE + reg), value); } u32 misc_read32(u8 reg) { - return read32((void *)(MISC_MMIO_BASE + reg)); + return read32((void *)(ACPIMMIO_MISC_BASE + reg)); } void pm_write32(u8 reg, u32 value) { - write32((void *)(PM_MMIO_BASE + reg), value); + write32((void *)(ACPIMMIO_PMIO_BASE + reg), value); } u32 pm_read32(u8 reg) { - return read32((void *)(PM_MMIO_BASE + reg)); + return read32((void *)(ACPIMMIO_PMIO_BASE + reg)); } u8 acpi_read8(u8 reg) { - return read8((void *)(ACPI_REG_MMIO_BASE + reg)); + return read8((void *)(ACPIMMIO_ACPI_BASE + reg)); } u16 acpi_read16(u8 reg) { - return read16((void *)(ACPI_REG_MMIO_BASE + reg)); + return read16((void *)(ACPIMMIO_ACPI_BASE + reg)); } u32 acpi_read32(u8 reg) { - return read32((void *)(ACPI_REG_MMIO_BASE + reg)); + return read32((void *)(ACPIMMIO_ACPI_BASE + reg)); } void acpi_write8(u8 reg, u8 value) { - write8((void *)(ACPI_REG_MMIO_BASE + reg), value); + write8((void *)(ACPIMMIO_ACPI_BASE + reg), value); } void acpi_write16(u8 reg, u16 value) { - write16((void *)(ACPI_REG_MMIO_BASE + reg), value); + write16((void *)(ACPIMMIO_ACPI_BASE + reg), value); } void acpi_write32(u8 reg, u32 value) { - write32((void *)(ACPI_REG_MMIO_BASE + reg), value); + write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); } void smi_write32(uint8_t offset, uint32_t value) { - write32((void *)(APU_SMI_BASE + offset), value); + write32((void *)(ACPIMMIO_SMI_BASE + offset), value); } uint32_t smi_read32(uint8_t offset) { - return read32((void *)(APU_SMI_BASE + offset)); + return read32((void *)(ACPIMMIO_SMI_BASE + offset)); } uint16_t smi_read16(uint8_t offset) { - return read16((void *)(APU_SMI_BASE + offset)); + return read16((void *)(ACPIMMIO_SMI_BASE + offset)); } void smi_write16(uint8_t offset, uint16_t value) { - write16((void *)(APU_SMI_BASE + offset), value); + write16((void *)(ACPIMMIO_SMI_BASE + offset), value); } uint8_t smi_read8(uint8_t offset) { - return read8((void *)(APU_SMI_BASE + offset)); + return read8((void *)(ACPIMMIO_SMI_BASE + offset)); } void smi_write8(uint8_t offset, uint8_t value) { - write8((void *)(APU_SMI_BASE + offset), value); + write8((void *)(ACPIMMIO_SMI_BASE + offset), value); } uint8_t biosram_read8(uint8_t offset) { - return read8((void *)(BIOSRAM_MMIO_BASE + offset)); + return read8((void *)(ACPIMMIO_BIOSRAM_BASE + offset)); } void biosram_write8(uint8_t offset, uint8_t value) { - write8((void *)(BIOSRAM_MMIO_BASE + offset), value); + write8((void *)(ACPIMMIO_BIOSRAM_BASE + offset), value); } /* BiosRam may only be accessed a byte at a time */ @@ -174,32 +174,32 @@ uint16_t pm_acpi_pm_evt_blk(void) void xhci_pm_write8(uint8_t reg, uint8_t value) { - write8((void *)(XHCI_ACPI_PM_MMIO_BASE + reg), value); + write8((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); } uint8_t xhci_pm_read8(uint8_t reg) { - return read8((void *)(XHCI_ACPI_PM_MMIO_BASE + reg)); + return read8((void *)(ACPIMMIO_XHCIPM_BASE + reg)); } void xhci_pm_write16(uint8_t reg, uint16_t value) { - write16((void *)(XHCI_ACPI_PM_MMIO_BASE + reg), value); + write16((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); } uint16_t xhci_pm_read16(uint8_t reg) { - return read16((void *)(XHCI_ACPI_PM_MMIO_BASE + reg)); + return read16((void *)(ACPIMMIO_XHCIPM_BASE + reg)); } void xhci_pm_write32(uint8_t reg, uint32_t value) { - write32((void *)(XHCI_ACPI_PM_MMIO_BASE + reg), value); + write32((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); } uint32_t xhci_pm_read32(uint8_t reg) { - return read32((void *)(XHCI_ACPI_PM_MMIO_BASE + reg)); + return read32((void *)(ACPIMMIO_XHCIPM_BASE + reg)); } void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value) diff --git a/src/soc/amd/stoneyridge/sm.c b/src/soc/amd/stoneyridge/sm.c index 9344b2f1805..803e6283202 100644 --- a/src/soc/amd/stoneyridge/sm.c +++ b/src/soc/amd/stoneyridge/sm.c @@ -42,9 +42,9 @@ static u32 get_sm_mmio(struct device *dev) pbus = get_pbus_smbus(dev); res = find_resource(pbus->dev, 0x90); if (res->base == SMB_BASE_ADDR) - return SMBUS_MMIO_BASE; + return ACPIMMIO_SMBUS_BASE; - return ASF_MMIO_BASE; + return ACPIMMIO_ASF_BASE; } static int lsmbus_recv_byte(struct device *dev) diff --git a/src/soc/amd/stoneyridge/smbus_spd.c b/src/soc/amd/stoneyridge/smbus_spd.c index ed73a6e51be..e57ecde5780 100644 --- a/src/soc/amd/stoneyridge/smbus_spd.c +++ b/src/soc/amd/stoneyridge/smbus_spd.c @@ -46,7 +46,7 @@ static int readspd(uint8_t SmbusSlaveAddress, char *buffer, size_t count) dev_addr = (SmbusSlaveAddress >> 1); /* Read the first SPD byte */ - error = do_smbus_read_byte(SMBUS_MMIO_BASE, dev_addr, 0); + error = do_smbus_read_byte(ACPIMMIO_SMBUS_BASE, dev_addr, 0); if (error < 0) { printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n"); return error; @@ -56,7 +56,7 @@ static int readspd(uint8_t SmbusSlaveAddress, char *buffer, size_t count) /* Read the remaining SPD bytes using do_smbus_recv_byte for speed */ for (index = 1 ; index < count ; index++) { - error = do_smbus_recv_byte(SMBUS_MMIO_BASE, dev_addr); + error = do_smbus_recv_byte(ACPIMMIO_SMBUS_BASE, dev_addr); if (error < 0) { printk(BIOS_ERR, "-------------SPD READ ERROR-----------\n"); return error; diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 9c546947e34..4f9e8efe711 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -279,7 +279,7 @@ int sb_set_wideio_range(uint16_t start, uint16_t size) static void power_on_aoac_device(int aoac_device_control_register) { uint8_t byte; - uint8_t *register_pointer = (uint8_t *)(uintptr_t)AOAC_MMIO_BASE + uint8_t *register_pointer = (uint8_t *)(uintptr_t)ACPIMMIO_AOAC_BASE + aoac_device_control_register; /* Power on the UART and AMBA devices */ @@ -291,7 +291,7 @@ static void power_on_aoac_device(int aoac_device_control_register) static bool is_aoac_device_enabled(int aoac_device_status_register) { uint8_t byte; - byte = read8((uint8_t *)(uintptr_t)AOAC_MMIO_BASE + byte = read8((uint8_t *)(uintptr_t)ACPIMMIO_AOAC_BASE + aoac_device_status_register); byte &= (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE); if (byte == (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE)) @@ -393,7 +393,7 @@ static void sb_enable_legacy_io(void) void sb_clk_output_48Mhz(u32 osc) { u32 ctrl; - u32 *misc_clk_cntl_1_ptr = (u32 *)(uintptr_t)(MISC_MMIO_BASE + u32 *misc_clk_cntl_1_ptr = (u32 *)(uintptr_t)(ACPIMMIO_MISC_BASE + MISC_CLK_CNTL1); /* @@ -632,12 +632,12 @@ static void setup_misc(int *reboot) static void fch_smbus_init(void) { pm_write8(SMB_ASF_IO_BASE, SMB_BASE_ADDR >> 8); - smbus_write8(SMBUS_MMIO_BASE, SMBTIMING, SMB_SPEED_400KHZ); + smbus_write8(ACPIMMIO_SMBUS_BASE, SMBTIMING, SMB_SPEED_400KHZ); /* Clear all SMBUS status bits */ - smbus_write8(SMBUS_MMIO_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); - smbus_write8(SMBUS_MMIO_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); - smbus_write8(ASF_MMIO_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); - smbus_write8(ASF_MMIO_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); + smbus_write8(ACPIMMIO_SMBUS_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); + smbus_write8(ACPIMMIO_SMBUS_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); + smbus_write8(ACPIMMIO_ASF_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); + smbus_write8(ACPIMMIO_ASF_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); } /* Before console init */ From 6ac87c4986e8af2fbbe8b3ddc6da868422a28101 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Sun, 5 May 2019 12:17:53 -0600 Subject: [PATCH 223/588] soc/amd/stoneyridge: Rearrange sb_util.c In preparation to move code to a common directory, rearrange some of the functions in sb_util.c. Add various comments. This change should have no functional differences. Change-Id: I1ad55a4a14a27e45459dcaf2fcc7449e29da6d4b Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32643 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth Reviewed-by: Richard Spiegel --- src/soc/amd/stoneyridge/sb_util.c | 205 ++++++++++++++++++------------ 1 file changed, 121 insertions(+), 84 deletions(-) diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 3005f4101f7..b777b1a5c95 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -18,118 +18,82 @@ #include #include -void pm_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_PMIO_BASE + reg), value); -} - -u8 pm_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_PMIO_BASE + reg)); -} +/* smbus pci read/write - access registers at 0xfed80000 - currently unused */ -void pm_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_PMIO_BASE + reg), value); -} - -u16 pm_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_PMIO_BASE + reg)); -} - -void misc_write32(u8 reg, u32 value) -{ - write32((void *)(ACPIMMIO_MISC_BASE + reg), value); -} +/* smi read/write - access registers at 0xfed80200 */ -u32 misc_read32(u8 reg) +uint8_t smi_read8(uint8_t offset) { - return read32((void *)(ACPIMMIO_MISC_BASE + reg)); + return read8((void *)(ACPIMMIO_SMI_BASE + offset)); } -void pm_write32(u8 reg, u32 value) +uint16_t smi_read16(uint8_t offset) { - write32((void *)(ACPIMMIO_PMIO_BASE + reg), value); + return read16((void *)(ACPIMMIO_SMI_BASE + offset)); } -u32 pm_read32(u8 reg) +uint32_t smi_read32(uint8_t offset) { - return read32((void *)(ACPIMMIO_PMIO_BASE + reg)); + return read32((void *)(ACPIMMIO_SMI_BASE + offset)); } -u8 acpi_read8(u8 reg) +void smi_write8(uint8_t offset, uint8_t value) { - return read8((void *)(ACPIMMIO_ACPI_BASE + reg)); + write8((void *)(ACPIMMIO_SMI_BASE + offset), value); } -u16 acpi_read16(u8 reg) +void smi_write16(uint8_t offset, uint16_t value) { - return read16((void *)(ACPIMMIO_ACPI_BASE + reg)); + write16((void *)(ACPIMMIO_SMI_BASE + offset), value); } -u32 acpi_read32(u8 reg) +void smi_write32(uint8_t offset, uint32_t value) { - return read32((void *)(ACPIMMIO_ACPI_BASE + reg)); + write32((void *)(ACPIMMIO_SMI_BASE + offset), value); } -void acpi_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_ACPI_BASE + reg), value); -} +/* pm read/write - access registers at 0xfed80300 */ -void acpi_write16(u8 reg, u16 value) +u8 pm_read8(u8 reg) { - write16((void *)(ACPIMMIO_ACPI_BASE + reg), value); + return read8((void *)(ACPIMMIO_PMIO_BASE + reg)); } -void acpi_write32(u8 reg, u32 value) +u16 pm_read16(u8 reg) { - write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); + return read16((void *)(ACPIMMIO_PMIO_BASE + reg)); } -void smi_write32(uint8_t offset, uint32_t value) +u32 pm_read32(u8 reg) { - write32((void *)(ACPIMMIO_SMI_BASE + offset), value); + return read32((void *)(ACPIMMIO_PMIO_BASE + reg)); } -uint32_t smi_read32(uint8_t offset) +void pm_write8(u8 reg, u8 value) { - return read32((void *)(ACPIMMIO_SMI_BASE + offset)); + write8((void *)(ACPIMMIO_PMIO_BASE + reg), value); } -uint16_t smi_read16(uint8_t offset) +void pm_write16(u8 reg, u16 value) { - return read16((void *)(ACPIMMIO_SMI_BASE + offset)); + write16((void *)(ACPIMMIO_PMIO_BASE + reg), value); } -void smi_write16(uint8_t offset, uint16_t value) +void pm_write32(u8 reg, u32 value) { - write16((void *)(ACPIMMIO_SMI_BASE + offset), value); + write32((void *)(ACPIMMIO_PMIO_BASE + reg), value); } -uint8_t smi_read8(uint8_t offset) -{ - return read8((void *)(ACPIMMIO_SMI_BASE + offset)); -} +/* pm2 read/write - access registers at 0xfed80400 - currently unused */ -void smi_write8(uint8_t offset, uint8_t value) -{ - write8((void *)(ACPIMMIO_SMI_BASE + offset), value); -} +/* biosram read/write - access registers at 0xfed80500 */ uint8_t biosram_read8(uint8_t offset) { return read8((void *)(ACPIMMIO_BIOSRAM_BASE + offset)); } -void biosram_write8(uint8_t offset, uint8_t value) -{ - write8((void *)(ACPIMMIO_BIOSRAM_BASE + offset), value); -} - -/* BiosRam may only be accessed a byte at a time */ -uint16_t biosram_read16(uint8_t offset) +uint16_t biosram_read16(uint8_t offset) /* Must be 1 byte at a time */ { int i; uint16_t value = 0; @@ -144,6 +108,11 @@ uint32_t biosram_read32(uint8_t offset) return value | biosram_read16(offset); } +void biosram_write8(uint8_t offset, uint8_t value) +{ + write8((void *)(ACPIMMIO_BIOSRAM_BASE + offset), value); +} + void biosram_write16(uint8_t offset, uint16_t value) { int i; @@ -162,39 +131,88 @@ void biosram_write32(uint8_t offset, uint32_t value) } } -uint16_t pm_acpi_pm_cnt_blk(void) +/* cmosram read/write - access registers at 0xfed80600 - currently unused */ + +/* cmos read/write - access registers at 0xfed80700 - currently unused */ + +/* acpi read/write - access registers at 0xfed80800 */ + +u8 acpi_read8(u8 reg) { - return pm_read16(PM1_CNT_BLK); + return read8((void *)(ACPIMMIO_ACPI_BASE + reg)); } -uint16_t pm_acpi_pm_evt_blk(void) +u16 acpi_read16(u8 reg) { - return pm_read16(PM_EVT_BLK); + return read16((void *)(ACPIMMIO_ACPI_BASE + reg)); } -void xhci_pm_write8(uint8_t reg, uint8_t value) +u32 acpi_read32(u8 reg) { - write8((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); + return read32((void *)(ACPIMMIO_ACPI_BASE + reg)); } -uint8_t xhci_pm_read8(uint8_t reg) +void acpi_write8(u8 reg, u8 value) { - return read8((void *)(ACPIMMIO_XHCIPM_BASE + reg)); + write8((void *)(ACPIMMIO_ACPI_BASE + reg), value); } -void xhci_pm_write16(uint8_t reg, uint16_t value) +void acpi_write16(u8 reg, u16 value) { - write16((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); + write16((void *)(ACPIMMIO_ACPI_BASE + reg), value); } -uint16_t xhci_pm_read16(uint8_t reg) +void acpi_write32(u8 reg, u32 value) { - return read16((void *)(ACPIMMIO_XHCIPM_BASE + reg)); + write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); } -void xhci_pm_write32(uint8_t reg, uint32_t value) +/* smbus read/write - access registers at 0xfed80a00 and ASF at 0xfed80900 */ + +void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value) { - write32((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); + write8((void *)(mmio + reg), value); +} + +uint8_t smbus_read8(uint32_t mmio, uint8_t reg) +{ + return read8((void *)(mmio + reg)); +} + +/* wdt read/write - access registers at 0xfed80b00 - not currently used */ + +/* hpet read/write - access registers at 0xfed80c00 - not currently used */ + +/* iomux read/write - access registers at 0xfed80d00 - not currently used */ + +/* misc read/write - access registers at 0xfed80e00 */ + +u32 misc_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_MISC_BASE + reg)); +} + +void misc_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + +/* dpvga read/write - access registers at 0xfed81400 - not currently used */ + +/* gpio bk 0 read/write - access registers at 0xfed81500 - not currently used */ +/* gpio bk 1 read/write - access registers at 0xfed81600 - not currently used */ +/* gpio bk 2 read/write - access registers at 0xfed81700 - not currently used */ + +/* xhci_pm read/write - access registers at 0xfed81c00 */ + +uint8_t xhci_pm_read8(uint8_t reg) +{ + return read8((void *)(ACPIMMIO_XHCIPM_BASE + reg)); +} + +uint16_t xhci_pm_read16(uint8_t reg) +{ + return read16((void *)(ACPIMMIO_XHCIPM_BASE + reg)); } uint32_t xhci_pm_read32(uint8_t reg) @@ -202,14 +220,33 @@ uint32_t xhci_pm_read32(uint8_t reg) return read32((void *)(ACPIMMIO_XHCIPM_BASE + reg)); } -void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value) +void xhci_pm_write8(uint8_t reg, uint8_t value) { - write8((void *)(mmio + reg), value); + write8((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); } -uint8_t smbus_read8(uint32_t mmio, uint8_t reg) +void xhci_pm_write16(uint8_t reg, uint16_t value) { - return read8((void *)(mmio + reg)); + write16((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); +} + +void xhci_pm_write32(uint8_t reg, uint32_t value) +{ + write32((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); +} + +/* acdc_tmr read/write - access registers at 0xfed81d00 */ + +/* aoac read/write - access registers at 0xfed81e00 - not currently used */ + +uint16_t pm_acpi_pm_cnt_blk(void) +{ + return pm_read16(PM1_CNT_BLK); +} + +uint16_t pm_acpi_pm_evt_blk(void) +{ + return pm_read16(PM_EVT_BLK); } int acpi_get_sleep_type(void) From 753c225c2c22df0260a97d3eabaaf15aeb0c4bd6 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Sun, 5 May 2019 14:08:59 -0600 Subject: [PATCH 224/588] soc/amd/stoneyridge: Rewrite smbus_read/write, add asf Convert smbus_read8() and smbus_write8() functions to use the same arguments as the other AcpiMmio blocks, and add 16 and 32 bit versions. Add matching functions for the ASF controller. Change-Id: I3b0ecf21f20472245da98ab5e711a54e99dca93a Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32644 Tested-by: build bot (Jenkins) Reviewed-by: Richard Spiegel Reviewed-by: Martin Roth --- .../amd/stoneyridge/include/soc/southbridge.h | 10 ++- src/soc/amd/stoneyridge/sb_util.c | 40 +++++++++- src/soc/amd/stoneyridge/smbus.c | 74 +++++++++++++------ src/soc/amd/stoneyridge/southbridge.c | 10 +-- 4 files changed, 101 insertions(+), 33 deletions(-) diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 9fa93c82451..aed3288ae87 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -525,8 +525,14 @@ void xhci_pm_write16(uint8_t reg, uint16_t value); uint16_t xhci_pm_read16(uint8_t reg); void xhci_pm_write32(uint8_t reg, uint32_t value); uint32_t xhci_pm_read32(uint8_t reg); -void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value); -uint8_t smbus_read8(uint32_t mmio, uint8_t reg); +uint8_t asf_read8(uint8_t offset); +uint16_t asf_read16(uint8_t offset); +void asf_write8(uint8_t offset, uint8_t value); +void asf_write16(uint8_t offset, uint16_t value); +uint8_t smbus_read8(uint8_t offset); +uint16_t smbus_read16(uint8_t offset); +void smbus_write8(uint8_t offset, uint8_t value); +void smbus_write16(uint8_t offset, uint16_t value); void bootblock_fch_early_init(void); void bootblock_fch_init(void); /** diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index b777b1a5c95..4bffdbc5cf9 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -167,16 +167,48 @@ void acpi_write32(u8 reg, u32 value) write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); } +/* asf read/write - access registers at 0xfed80900 - not currently used */ + +u8 asf_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_ASF_BASE + reg)); +} + +u16 asf_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_ASF_BASE + reg)); +} + +void asf_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_ASF_BASE + reg), value); +} + +void asf_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_ASF_BASE + reg), value); +} + /* smbus read/write - access registers at 0xfed80a00 and ASF at 0xfed80900 */ -void smbus_write8(uint32_t mmio, uint8_t reg, uint8_t value) +u8 smbus_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_SMBUS_BASE + reg)); +} + +u16 smbus_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_SMBUS_BASE + reg)); +} + +void smbus_write8(u8 reg, u8 value) { - write8((void *)(mmio + reg), value); + write8((void *)(ACPIMMIO_SMBUS_BASE + reg), value); } -uint8_t smbus_read8(uint32_t mmio, uint8_t reg) +void smbus_write16(u8 reg, u16 value) { - return read8((void *)(mmio + reg)); + write16((void *)(ACPIMMIO_SMBUS_BASE + reg), value); } /* wdt read/write - access registers at 0xfed80b00 - not currently used */ diff --git a/src/soc/amd/stoneyridge/smbus.c b/src/soc/amd/stoneyridge/smbus.c index c4a022a9a96..6285d793b79 100644 --- a/src/soc/amd/stoneyridge/smbus.c +++ b/src/soc/amd/stoneyridge/smbus.c @@ -15,21 +15,51 @@ #include #include +#include #include #include +static u8 controller_read8(u32 base, u8 reg) +{ + switch (base) { + case ACPIMMIO_SMBUS_BASE: + return smbus_read8(reg); + case ACPIMMIO_ASF_BASE: + return asf_read8(reg); + default: + printk(BIOS_ERR, "Error attempting to read SMBus at address 0x%x\n", + base); + } + return 0xff; +} + +static void controller_write8(u32 base, u8 reg, u8 val) +{ + switch (base) { + case ACPIMMIO_SMBUS_BASE: + smbus_write8(reg, val); + break; + case ACPIMMIO_ASF_BASE: + asf_write8(reg, val); + break; + default: + printk(BIOS_ERR, "Error attempting to write SMBus at address 0x%x\n", + base); + } +} + static int smbus_wait_until_ready(u32 mmio) { u32 loops; loops = SMBUS_TIMEOUT; do { u8 val; - val = smbus_read8(mmio, SMBHSTSTAT); + val = controller_read8(mmio, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; if (val == 0) { /* ready now */ return 0; } - smbus_write8(mmio, SMBHSTSTAT, val); + controller_write8(mmio, SMBHSTSTAT, val); } while (--loops); return -2; /* time out */ } @@ -41,12 +71,12 @@ static int smbus_wait_until_done(u32 mmio) do { u8 val; - val = smbus_read8(mmio, SMBHSTSTAT); + val = controller_read8(mmio, SMBHSTSTAT); val &= SMBHST_STAT_VAL_BITS; /* mask off reserved bits */ if (val & SMBHST_STAT_ERROR_BITS) return -5; /* error */ if (val == SMBHST_STAT_NOERROR) { - smbus_write8(mmio, SMBHSTSTAT, val); /* clear sts */ + controller_write8(mmio, SMBHSTSTAT, val); /* clr sts */ return 0; } } while (--loops); @@ -61,19 +91,19 @@ int do_smbus_recv_byte(u32 mmio, u8 device) return -2; /* not ready */ /* set the device I'm talking to */ - smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); + controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); - byte = smbus_read8(mmio, SMBHSTCTRL); + byte = controller_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - smbus_write8(mmio, SMBHSTCTRL, byte); + controller_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ /* read results of transaction */ - byte = smbus_read8(mmio, SMBHSTDAT0); + byte = controller_read8(mmio, SMBHSTDAT0); return byte; } @@ -86,15 +116,15 @@ int do_smbus_send_byte(u32 mmio, u8 device, u8 val) return -2; /* not ready */ /* set the command... */ - smbus_write8(mmio, SMBHSTDAT0, val); + controller_write8(mmio, SMBHSTDAT0, val); /* set the device I'm talking to */ - smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); + controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); - byte = smbus_read8(mmio, SMBHSTCTRL); + byte = controller_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BTE_RW; /* set mode, start */ - smbus_write8(mmio, SMBHSTCTRL, byte); + controller_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) @@ -111,22 +141,22 @@ int do_smbus_read_byte(u32 mmio, u8 device, u8 address) return -2; /* not ready */ /* set the command/address... */ - smbus_write8(mmio, SMBHSTCMD, address & 0xff); + controller_write8(mmio, SMBHSTCMD, address & 0xff); /* set the device I'm talking to */ - smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); + controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 1); - byte = smbus_read8(mmio, SMBHSTCTRL); + byte = controller_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - smbus_write8(mmio, SMBHSTCTRL, byte); + controller_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) return -3; /* timeout or error */ /* read results of transaction */ - byte = smbus_read8(mmio, SMBHSTDAT0); + byte = controller_read8(mmio, SMBHSTDAT0); return byte; } @@ -139,18 +169,18 @@ int do_smbus_write_byte(u32 mmio, u8 device, u8 address, u8 val) return -2; /* not ready */ /* set the command/address... */ - smbus_write8(mmio, SMBHSTCMD, address & 0xff); + controller_write8(mmio, SMBHSTCMD, address & 0xff); /* set the device I'm talking to */ - smbus_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); + controller_write8(mmio, SMBHSTADDR, ((device & 0x7f) << 1) | 0); /* output value */ - smbus_write8(mmio, SMBHSTDAT0, val); + controller_write8(mmio, SMBHSTDAT0, val); - byte = smbus_read8(mmio, SMBHSTCTRL); + byte = controller_read8(mmio, SMBHSTCTRL); byte &= ~SMBHST_CTRL_MODE_BITS; /* Clear [4:2] */ byte |= SMBHST_CTRL_STRT | SMBHST_CTRL_BDT_RW; /* set mode, start */ - smbus_write8(mmio, SMBHSTCTRL, byte); + controller_write8(mmio, SMBHSTCTRL, byte); /* poll for transaction completion */ if (smbus_wait_until_done(mmio) < 0) diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 4f9e8efe711..66894a24b49 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -632,12 +632,12 @@ static void setup_misc(int *reboot) static void fch_smbus_init(void) { pm_write8(SMB_ASF_IO_BASE, SMB_BASE_ADDR >> 8); - smbus_write8(ACPIMMIO_SMBUS_BASE, SMBTIMING, SMB_SPEED_400KHZ); + smbus_write8(SMBTIMING, SMB_SPEED_400KHZ); /* Clear all SMBUS status bits */ - smbus_write8(ACPIMMIO_SMBUS_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); - smbus_write8(ACPIMMIO_SMBUS_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); - smbus_write8(ACPIMMIO_ASF_BASE, SMBHSTSTAT, SMBHST_STAT_CLEAR); - smbus_write8(ACPIMMIO_ASF_BASE, SMBSLVSTAT, SMBSLV_STAT_CLEAR); + smbus_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR); + smbus_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR); + asf_write8(SMBHSTSTAT, SMBHST_STAT_CLEAR); + asf_write8(SMBSLVSTAT, SMBSLV_STAT_CLEAR); } /* Before console init */ From b435d4405dacdc218777aaba349151ae28997741 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Wed, 1 May 2019 21:17:20 -0600 Subject: [PATCH 225/588] soc/amd/stoneyridge: Add aoac_ read/write functions Add 8-bit functions to access the AOAC registers and use them in southbridge.c. At this time, there is no reason to pursue WORD or DWORD access and it's not known if those transaction sizes are supported. Change-Id: I3a8f493625f941fb855c0b8a0eff511a9a5ddfe8 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32645 Tested-by: build bot (Jenkins) Reviewed-by: Richard Spiegel Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/include/soc/southbridge.h | 2 ++ src/soc/amd/stoneyridge/sb_util.c | 10 ++++++++++ src/soc/amd/stoneyridge/southbridge.c | 10 ++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index aed3288ae87..098d24edbbd 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -533,6 +533,8 @@ uint8_t smbus_read8(uint8_t offset); uint16_t smbus_read16(uint8_t offset); void smbus_write8(uint8_t offset, uint8_t value); void smbus_write16(uint8_t offset, uint16_t value); +uint8_t aoac_read8(uint8_t reg); +void aoac_write8(uint8_t reg, uint8_t value); void bootblock_fch_early_init(void); void bootblock_fch_init(void); /** diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 4bffdbc5cf9..530e9cd9463 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -271,6 +271,16 @@ void xhci_pm_write32(uint8_t reg, uint32_t value) /* aoac read/write - access registers at 0xfed81e00 - not currently used */ +u8 aoac_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_AOAC_BASE + reg)); +} + +void aoac_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_AOAC_BASE + reg), value); +} + uint16_t pm_acpi_pm_cnt_blk(void) { return pm_read16(PM1_CNT_BLK); diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 66894a24b49..7dc27c86da0 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -279,20 +279,18 @@ int sb_set_wideio_range(uint16_t start, uint16_t size) static void power_on_aoac_device(int aoac_device_control_register) { uint8_t byte; - uint8_t *register_pointer = (uint8_t *)(uintptr_t)ACPIMMIO_AOAC_BASE - + aoac_device_control_register; /* Power on the UART and AMBA devices */ - byte = read8(register_pointer); + byte = aoac_read8(aoac_device_control_register); byte |= FCH_AOAC_PWR_ON_DEV; - write8(register_pointer, byte); + aoac_write8(aoac_device_control_register, byte); } static bool is_aoac_device_enabled(int aoac_device_status_register) { uint8_t byte; - byte = read8((uint8_t *)(uintptr_t)ACPIMMIO_AOAC_BASE - + aoac_device_status_register); + + byte = aoac_read8(aoac_device_status_register); byte &= (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE); if (byte == (FCH_AOAC_PWR_RST_STATE | FCH_AOAC_RST_CLK_OK_STATE)) return true; From b4b9efcfdd47efe67b13e1cf8cfea2ffe08fb012 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Wed, 1 May 2019 17:33:42 -0600 Subject: [PATCH 226/588] soc/amd/stoneyridge: Finish read/write misc registers Add 16 and 32-bit versions of read / write_misc functions. Find one access of the MISC block still using read8() and write8(), and convert it. Change-Id: I296c521ea7f43210db406013bbe79362545ce6f3 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32646 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- .../amd/stoneyridge/include/soc/southbridge.h | 4 ++++ src/soc/amd/stoneyridge/sb_util.c | 20 +++++++++++++++++++ src/soc/amd/stoneyridge/southbridge.c | 6 ++---- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 098d24edbbd..e5ba2af5ebd 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -503,7 +503,11 @@ u32 acpi_read32(u8 reg); void acpi_write8(u8 reg, u8 value); void acpi_write16(u8 reg, u16 value); void acpi_write32(u8 reg, u32 value); +u8 misc_read8(u8 reg); +u16 misc_read16(u8 reg); u32 misc_read32(u8 reg); +void misc_write8(u8 reg, u8 value); +void misc_write16(u8 reg, u16 value); void misc_write32(u8 reg, u32 value); uint8_t smi_read8(uint8_t offset); uint16_t smi_read16(uint8_t offset); diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 530e9cd9463..5aec4315934 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -219,11 +219,31 @@ void smbus_write16(u8 reg, u16 value) /* misc read/write - access registers at 0xfed80e00 */ +u8 misc_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_MISC_BASE + reg)); +} + +u16 misc_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_MISC_BASE + reg)); +} + u32 misc_read32(u8 reg) { return read32((void *)(ACPIMMIO_MISC_BASE + reg)); } +void misc_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + +void misc_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + void misc_write32(u8 reg, u32 value) { write32((void *)(ACPIMMIO_MISC_BASE + reg), value); diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 7dc27c86da0..b5901782f69 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -391,14 +391,12 @@ static void sb_enable_legacy_io(void) void sb_clk_output_48Mhz(u32 osc) { u32 ctrl; - u32 *misc_clk_cntl_1_ptr = (u32 *)(uintptr_t)(ACPIMMIO_MISC_BASE - + MISC_CLK_CNTL1); /* * Clear the disable for OSCOUT1 (signal typically named XnnM_25M_48M) * or OSCOUT2 (USBCLK/25M_48M_OSC). The frequency defaults to 48MHz. */ - ctrl = read32(misc_clk_cntl_1_ptr); + ctrl = misc_read32(MISC_CLK_CNTL1); switch (osc) { case 1: @@ -410,7 +408,7 @@ void sb_clk_output_48Mhz(u32 osc) default: return; /* do nothing if invalid */ } - write32(misc_clk_cntl_1_ptr, ctrl); + misc_write32(MISC_CLK_CNTL1, ctrl); } static uintptr_t sb_spibase(void) From 976e3e9ae68d64c374e7e2ace2df86173bd5bec8 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Wed, 1 May 2019 17:48:44 -0600 Subject: [PATCH 227/588] soc/amd/stoneyridge: Add iomux read/write functions Add functions to read and write the region in the AcpiMmio block. Convert gpio.c to use them instead of creating pointers. Change-Id: I2a0f44b6ec7261648cf0357b44a6c18dd40d1504 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32647 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/gpio.c | 16 +++------- .../amd/stoneyridge/include/soc/southbridge.h | 6 ++++ src/soc/amd/stoneyridge/sb_util.c | 32 ++++++++++++++++++- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c index b747538eaab..285fedd2387 100644 --- a/src/soc/amd/stoneyridge/gpio.c +++ b/src/soc/amd/stoneyridge/gpio.c @@ -221,7 +221,6 @@ uint16_t gpio_acpi_pin(gpio_t gpio) void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) { - uint8_t *mux_ptr; uint32_t *gpio_ptr, *inter_master; uint32_t control, control_flags, edge_level, direction; uint32_t mask, bit_edge, bit_level; @@ -252,9 +251,8 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) control = gpio_list_ptr[index].control; control_flags = gpio_list_ptr[index].flags; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); - write8(mux_ptr, mux & AMD_GPIO_MUX_MASK); - read8(mux_ptr); /* Flush posted write */ + iomux_write8(gpio, mux & AMD_GPIO_MUX_MASK); + iomux_read8(gpio); /* Flush posted write */ /* special case if pin 2 is assigned to wake */ if ((gpio == 2) && !(mux & AMD_GPIO_MUX_MASK)) route_sci(GPIO_2_EVENT); @@ -348,11 +346,9 @@ static void save_i2c_pin_registers(uint8_t gpio, struct soc_amd_i2c_save *save_table) { uint32_t *gpio_ptr; - uint8_t *mux_ptr; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); gpio_ptr = (uint32_t *)gpio_get_address(gpio); - save_table->mux_value = read8(mux_ptr); + save_table->mux_value = iomux_read8(gpio); save_table->control_value = read32(gpio_ptr); } @@ -360,12 +356,10 @@ static void restore_i2c_pin_registers(uint8_t gpio, struct soc_amd_i2c_save *save_table) { uint32_t *gpio_ptr; - uint8_t *mux_ptr; - mux_ptr = (uint8_t *)(uintptr_t)(gpio + ACPIMMIO_IOMUX_BASE); gpio_ptr = (uint32_t *)gpio_get_address(gpio); - write8(mux_ptr, save_table->mux_value); - read8(mux_ptr); + iomux_write8(gpio, save_table->mux_value); + iomux_read8(gpio); write32(gpio_ptr, save_table->control_value); read32(gpio_ptr); } diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index e5ba2af5ebd..f755c0a0d45 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -529,6 +529,12 @@ void xhci_pm_write16(uint8_t reg, uint16_t value); uint16_t xhci_pm_read16(uint8_t reg); void xhci_pm_write32(uint8_t reg, uint32_t value); uint32_t xhci_pm_read32(uint8_t reg); +u8 iomux_read8(u8 reg); +u16 iomux_read16(u8 reg); +u32 iomux_read32(u8 reg); +void iomux_write8(u8 reg, u8 value); +void iomux_write16(u8 reg, u16 value); +void iomux_write32(u8 reg, u32 value); uint8_t asf_read8(uint8_t offset); uint16_t asf_read16(uint8_t offset); void asf_write8(uint8_t offset, uint8_t value); diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 5aec4315934..41ebb37be2d 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -215,7 +215,37 @@ void smbus_write16(u8 reg, u16 value) /* hpet read/write - access registers at 0xfed80c00 - not currently used */ -/* iomux read/write - access registers at 0xfed80d00 - not currently used */ +/* iomux read/write - access registers at 0xfed80d00 */ + +u8 iomux_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +u16 iomux_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +u32 iomux_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +void iomux_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} + +void iomux_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} + +void iomux_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} /* misc read/write - access registers at 0xfed80e00 */ From 49df54a1dc0596e23e7865e65a45544c947efc9e Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 14 Apr 2019 14:39:34 +0200 Subject: [PATCH 228/588] mb/lenovo/t520: Fix devicetree Disable unused PCI devices. Reduces idle power by around 0.5Watt. Tested on Lenovo T520. Change-Id: I6990dc5810084261b75d2a327b6a103be44fd4cc Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32317 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/mainboard/lenovo/t520/variants/t520/devicetree.cb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mainboard/lenovo/t520/variants/t520/devicetree.cb b/src/mainboard/lenovo/t520/variants/t520/devicetree.cb index 5f1bc608637..eff2d693045 100644 --- a/src/mainboard/lenovo/t520/variants/t520/devicetree.cb +++ b/src/mainboard/lenovo/t520/variants/t520/devicetree.cb @@ -88,6 +88,8 @@ chip northbridge/intel/sandybridge device pci 1c.6 off end # PCIe Port #7 USB 3.0 only W520 device pci 1c.7 off end # PCIe Port #8 device pci 1d.0 on end # USB2 EHCI #1 + device pci 1e.0 off end # PCI-2-PCI bridge + device pci 1f.0 on #LPC bridge chip ec/lenovo/pmh7 device pnp ff.1 on # dummy @@ -167,6 +169,8 @@ chip northbridge/intel/sandybridge device i2c 5f on end end end # SMBus + device pci 1f.5 off end # IDE controller + device pci 1f.6 off end # Thermal controller end end end From b3ddb29c366d043e9988f1865e9f414e716f02f3 Mon Sep 17 00:00:00 2001 From: Mike Hsieh Date: Thu, 2 May 2019 14:43:26 +0800 Subject: [PATCH 229/588] mb/google/sarien/variants/arcada: Update thermal configuration for DPTF Update dptf for arcada DVT1. BUG=b:123924662 TEST=Built and tested on arcada system Signed-off-by: Mike Hsieh Change-Id: Ia8024a69547a569d288e02931190a98676eeaab4 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32538 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- .../arcada/include/variant/acpi/dptf.asl | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/dptf.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/dptf.asl index 6fa06c7d730..4d380713e22 100644 --- a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/dptf.asl +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/dptf.asl @@ -13,14 +13,14 @@ * GNU General Public License for more details. */ -#define DPTF_CPU_PASSIVE 96 -#define DPTF_CPU_CRITICAL 103 +#define DPTF_CPU_PASSIVE 90 +#define DPTF_CPU_CRITICAL 105 /* Skin Sensor for CPU VR temperature monitor */ #define DPTF_TSR0_SENSOR_ID 1 #define DPTF_TSR0_SENSOR_NAME "Skin" -#define DPTF_TSR0_PASSIVE 56 -#define DPTF_TSR0_CRITICAL 108 +#define DPTF_TSR0_PASSIVE 60 +#define DPTF_TSR0_CRITICAL 105 /* Memory Sensor for DDR temperature monitor */ #define DPTF_TSR1_SENSOR_ID 2 @@ -31,24 +31,24 @@ /* M.2 Sensor for Ambient temperature monitor */ #define DPTF_TSR2_SENSOR_ID 3 #define DPTF_TSR2_SENSOR_NAME "Ambient" -#define DPTF_TSR2_PASSIVE 50 -#define DPTF_TSR2_CRITICAL 95 +#define DPTF_TSR2_PASSIVE 37 +#define DPTF_TSR2_CRITICAL 80 #undef DPTF_ENABLE_FAN_CONTROL #undef DPTF_ENABLE_CHARGER Name (DTRT, Package () { /* CPU Throttle Effect on CPU */ - Package () { \_SB.PCI0.TCPU, \_SB.PCI0.TCPU, 100, 10, 0, 0, 0, 0 }, + Package () { \_SB.PCI0.TCPU, \_SB.PCI0.TCPU, 500, 100, 0, 0, 0, 0 }, /* CPU Throttle Effect on Skin (TSR0) */ - Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR0, 100, 600, 0, 0, 0, 0 }, + Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR0, 500, 30, 0, 0, 0, 0 }, /* CPU Throttle Effect on DDR (TSR1) */ - Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR1, 100, 90, 0, 0, 0, 0 }, + Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR1, 100, 50, 2, 0, 0, 0 }, /* CPU Throttle Effect on Ambient (TSR2) */ - Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR2, 100, 600, 0, 0, 0, 0 }, + Package () { \_SB.PCI0.TCPU, \_SB.DPTF.TSR2, 1000, 100, 1, 0, 0, 0 }, }) Name (MPPC, Package () From c7817bc1280fe2e017c2f99dbb3d19c414ee8c63 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Fri, 19 Apr 2019 20:21:43 -0700 Subject: [PATCH 230/588] soc/intel/common/acpi: Remove EC PTS/WAK dynamic loading Use CondRefOf to replace config optios for PTS/WAK acpi method dynamic loading. Then we can move EC PTS and WAK method to be under mainboard. BUG=N/A TEST=Build sarien source code, check build/dsdt.dsl have EC.PTS method included, build whlrvp soure, check build/dsdt.dsl don't have EC.PTS method. Both able to build pass. Signed-off-by: Lijian Zhao Change-Id: I9f4bd7240832caf070e65039e4ba2d8656371da8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32371 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/Kconfig | 1 - src/soc/intel/common/Kconfig | 7 ------- src/soc/intel/common/acpi/platform.asl | 9 --------- 3 files changed, 17 deletions(-) diff --git a/src/mainboard/google/sarien/Kconfig b/src/mainboard/google/sarien/Kconfig index c48a908dc18..e6d1f1f60f3 100644 --- a/src/mainboard/google/sarien/Kconfig +++ b/src/mainboard/google/sarien/Kconfig @@ -16,7 +16,6 @@ config BOARD_GOOGLE_BASEBOARD_SARIEN select MAINBOARD_HAS_CHROMEOS select MAINBOARD_HAS_I2C_TPM_CR50 select MAINBOARD_HAS_TPM2 - select SOC_INTEL_COMMON_ACPI_EC_PTS_WAK select SOC_INTEL_WHISKEYLAKE select SOC_INTEL_COMMON_BLOCK_HDA_VERB select SOC_INTEL_COMMON_BLOCK_SMM_ESPI_DISABLE diff --git a/src/soc/intel/common/Kconfig b/src/soc/intel/common/Kconfig index 318cc25c877..ac2268661f6 100644 --- a/src/soc/intel/common/Kconfig +++ b/src/soc/intel/common/Kconfig @@ -51,13 +51,6 @@ config SOC_INTEL_COMMON_ACPI bool default n -config SOC_INTEL_COMMON_ACPI_EC_PTS_WAK - bool - default n - help - Set this option to have the platform level _PTS/_WAK methods call - methods provided by the Embedded Controller. - config SOC_INTEL_COMMON_NHLT bool default n diff --git a/src/soc/intel/common/acpi/platform.asl b/src/soc/intel/common/acpi/platform.asl index 8b85d440578..9aa2edc6df7 100644 --- a/src/soc/intel/common/acpi/platform.asl +++ b/src/soc/intel/common/acpi/platform.asl @@ -37,10 +37,6 @@ Method (_PTS, 1) { Store (POST_OS_ENTER_PTS, DBG0) -#if CONFIG(SOC_INTEL_COMMON_ACPI_EC_PTS_WAK) - /* Call EC _PTS handler */ - \_SB.PCI0.LPCB.EC0.PTS (Arg0) -#endif If (CondRefOf (\_SB.MPTS)) { \_SB.MPTS (Arg0) @@ -58,10 +54,5 @@ Method (_WAK, 1) \_SB.MWAK (Arg0) } -#if CONFIG(SOC_INTEL_COMMON_ACPI_EC_PTS_WAK) - /* Call EC _WAK handler */ - \_SB.PCI0.LPCB.EC0.WAK (Arg0) -#endif - Return (Package(){0,0}) } From 0a433db22cd4eca1d26cd20ed4e662ad7c928934 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Tue, 7 May 2019 13:42:57 -0700 Subject: [PATCH 231/588] mb/google/sarien: Move EC PTS/WAK function to mainboard Move optional EC PTS and WAK function into mainboard level. Signed-off-by: Lijian Zhao Change-Id: Ie91a8168ae234f4fb4843c8587c77ae2f74aeb81 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32671 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- .../arcada/include/variant/acpi/mainboard.asl | 12 ++++++++++++ .../sarien/include/variant/acpi/mainboard.asl | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl index 7b252c7f1cc..bc036960488 100644 --- a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl @@ -26,3 +26,15 @@ Method (MS0X, 1) \_SB.PCI0.CTXS (CAM_EN) } } + +/* Method called from _PTS prior to enter sleep state */ +Method (MPTS, 1) +{ + \_SB.PCI0.LPCB.EC0.PTS (Arg0) +} + +/* Method called from _WAK prior to wakeup */ +Method (MWAK, 1) +{ + \_SB.PCI0.LPCB.EC0.WAK (Arg0) +} diff --git a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl index 7b252c7f1cc..bc036960488 100644 --- a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl @@ -26,3 +26,15 @@ Method (MS0X, 1) \_SB.PCI0.CTXS (CAM_EN) } } + +/* Method called from _PTS prior to enter sleep state */ +Method (MPTS, 1) +{ + \_SB.PCI0.LPCB.EC0.PTS (Arg0) +} + +/* Method called from _WAK prior to wakeup */ +Method (MWAK, 1) +{ + \_SB.PCI0.LPCB.EC0.WAK (Arg0) +} From 9e8cf3cc869ca70267b43ba4898a9dfa06b5a643 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Tue, 7 May 2019 13:01:53 +0800 Subject: [PATCH 232/588] vboot: remove use of VbInitParams The VbInitParams struct will be deprecated. Remove its use in preparation. Additionally, remove use of the flag VB_INIT_OUT_ENABLE_USB_STORAGE, which is no longer used downstream since vboot_reference CL:347257. BUG=b:124141368, chromium:960226 TEST=make clean && make test-abuild BRANCH=none Change-Id: Ibe02cb6ba639de0d7cbdf79fc4dbf49044c92278 Signed-off-by: Joel Kitching Cq-Depend: chromium:1583943 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32664 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/security/vboot/vboot_common.c | 2 +- src/security/vboot/vboot_common.h | 3 ++- src/security/vboot/vboot_handoff.c | 4 +--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 493cb888984..14f154c4387 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -85,7 +85,7 @@ static int vboot_get_handoff_flag(uint32_t flag) if (vboot_get_handoff_info((void **)&vbho, NULL)) return 0; - return !!(vbho->init_params.out_flags & flag); + return !!(vbho->out_flags & flag); } int vboot_handoff_check_developer_flag(void) diff --git a/src/security/vboot/vboot_common.h b/src/security/vboot/vboot_common.h index 768b29d4fc8..9a02303d12d 100644 --- a/src/security/vboot/vboot_common.h +++ b/src/security/vboot/vboot_common.h @@ -39,7 +39,8 @@ int vboot_check_recovery_request(void); * vboot shared data as well as the flags from VbInit. */ struct vboot_handoff { - VbInitParams init_params; + uint32_t reserved0; /* originally from VbInitParams */ + uint32_t out_flags; uint32_t selected_firmware; char shared_data[VB_SHARED_DATA_MIN_SIZE]; } __packed; diff --git a/src/security/vboot/vboot_handoff.c b/src/security/vboot/vboot_handoff.c index 178877d847f..208663e0292 100644 --- a/src/security/vboot/vboot_handoff.c +++ b/src/security/vboot/vboot_handoff.c @@ -40,7 +40,7 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, { VbSharedDataHeader *vb_sd = (VbSharedDataHeader *)vboot_handoff->shared_data; - uint32_t *oflags = &vboot_handoff->init_params.out_flags; + uint32_t *oflags = &vboot_handoff->out_flags; vb_sd->flags |= VBSD_BOOT_FIRMWARE_VBOOT2; @@ -61,12 +61,10 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, vb_sd->flags |= VBSD_BOOT_REC_SWITCH_ON; *oflags |= VB_INIT_OUT_ENABLE_RECOVERY; *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; } if (vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) { *oflags |= VB_INIT_OUT_ENABLE_DEVELOPER; *oflags |= VB_INIT_OUT_CLEAR_RAM; - *oflags |= VB_INIT_OUT_ENABLE_USB_STORAGE; vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON; vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON; } From 5923d67cfd07a950ffd435aa078167144366f7dc Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Fri, 12 Apr 2019 15:57:43 +0800 Subject: [PATCH 233/588] vboot: communicate display requirements with vb2api_fw_phase1 Input: tell vb2api_fw_phase1 if display unconditionally available Output: vb2api_fw_phase1 may request coreboot to initialize display, if needed based on some internal request Move setting the VBOOT_FLAG_DISPLAY_REQUESTED flag into verstage_main. BUG=b:124141368, b:124192753, chromium:948529 TEST=make clean && make test-abuild BRANCH=none Change-Id: I81c82c46303564b63b8a32e7f80beb9d891a4628 Cq-Depend: chromium:1564232 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32324 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/security/vboot/vboot_handoff.c | 9 +++------ src/security/vboot/vboot_logic.c | 9 +++++++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/security/vboot/vboot_handoff.c b/src/security/vboot/vboot_handoff.c index 208663e0292..fccbdfc0b71 100644 --- a/src/security/vboot/vboot_handoff.c +++ b/src/security/vboot/vboot_handoff.c @@ -68,14 +68,11 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON; vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON; } - /* Inform vboot if the display was requested by vboot kernel phase - or enabled by dev/rec mode. */ + /* TODO(chromium:948529): Remove these two flags after downstream + vboot code longer reads them. */ if (vboot_wants_oprom() || vb2_sd->recovery_reason || - vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) { - vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; + vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) vb_sd->flags |= VBSD_OPROM_LOADED; - } - /* TODO: Remove when depthcharge no longer reads this flag. */ if (CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) vb_sd->flags |= VBSD_OPROM_MATTERS; diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index 2a8e6192892..df34490f985 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -336,6 +336,10 @@ void verstage_main(void) if (CONFIG(VBOOT_LID_SWITCH) && !get_lid_switch()) ctx.flags |= VB2_CONTEXT_NOFAIL_BOOT; + /* Mainboard/SoC always initializes display. */ + if (!CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) + ctx.flags |= VB2_CONTEXT_DISPLAY_INIT; + /* Do early init (set up secdata and NVRAM, load GBB) */ printk(BIOS_INFO, "Phase 1\n"); rv = vb2api_fw_phase1(&ctx); @@ -360,6 +364,11 @@ void verstage_main(void) vboot_reboot(); } + /* Is vboot declaring that display is available? If so, we should mark + it down, so that the mainboard/SoC knows to initialize display. */ + if (ctx.flags & VB2_CONTEXT_DISPLAY_INIT) + vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; + /* Determine which firmware slot to boot (based on NVRAM) */ printk(BIOS_INFO, "Phase 2\n"); rv = vb2api_fw_phase2(&ctx); From 2eb89c8b1479876d37eef37eb4485e23956116e3 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Thu, 25 Apr 2019 17:45:12 +0800 Subject: [PATCH 234/588] vboot: include vb2_sha.h when required Should include vb2_sha.h header when SHA library functions or constants are required. This replaces NEED_VB2_SHA_LIBRARY. BUG=b:124141368, chromium:956474 TEST=make clean && make test-abuild BRANCH=none Change-Id: I9f32174dbf3de05fbe5279cb8017888757abf368 Signed-off-by: Joel Kitching Cq-Depend: chromium:1583820 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32454 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/commonlib/cbfs.c | 1 + src/security/tpm/tspi/tspi.c | 1 + src/security/vboot/antirollback.h | 1 + util/cbfstool/Makefile.inc | 1 - util/cbfstool/cbfs_image.c | 1 + 5 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/commonlib/cbfs.c b/src/commonlib/cbfs.c index 4379099ffe0..a509bc9f61a 100644 --- a/src/commonlib/cbfs.c +++ b/src/commonlib/cbfs.c @@ -18,6 +18,7 @@ #include #include #include +#include #if !defined(ERROR) #define ERROR(x...) printk(BIOS_ERR, "CBFS: " x) diff --git a/src/security/tpm/tspi/tspi.c b/src/security/tpm/tspi/tspi.c index e466eb87aab..4698a4dc8c9 100644 --- a/src/security/tpm/tspi/tspi.c +++ b/src/security/tpm/tspi/tspi.c @@ -22,6 +22,7 @@ #include #if CONFIG(VBOOT) #include +#include #include #endif diff --git a/src/security/vboot/antirollback.h b/src/security/vboot/antirollback.h index 6ea2c13a970..62d2e20f03a 100644 --- a/src/security/vboot/antirollback.h +++ b/src/security/vboot/antirollback.h @@ -37,6 +37,7 @@ #include #include +#include struct vb2_context; enum vb2_pcr_digest; diff --git a/util/cbfstool/Makefile.inc b/util/cbfstool/Makefile.inc index 1787eb14c02..79285207b01 100644 --- a/util/cbfstool/Makefile.inc +++ b/util/cbfstool/Makefile.inc @@ -81,7 +81,6 @@ TOOLCPPFLAGS += -I$(top)/util/cbfstool TOOLCPPFLAGS += -I$(objutil)/cbfstool TOOLCPPFLAGS += -I$(top)/src/commonlib/include TOOLCPPFLAGS += -include $(top)/src/commonlib/include/commonlib/compiler.h -TOOLCPPFLAGS += -DNEED_VB2_SHA_LIBRARY TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/include TOOLCPPFLAGS += -I$(VBOOT_SOURCE)/firmware/2lib/include # UEFI header file support. It's not pretty, but that's what we currently diff --git a/util/cbfstool/cbfs_image.c b/util/cbfstool/cbfs_image.c index 5ff81309f41..5cbe1f185a6 100644 --- a/util/cbfstool/cbfs_image.c +++ b/util/cbfstool/cbfs_image.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "common.h" #include "cbfs_image.h" From 24047fefdac1d5abc1298a0da20340dc3d7eda48 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Thu, 9 May 2019 00:01:45 +0000 Subject: [PATCH 235/588] Change the guard for bootblock_systemagent_early_init to ENV_BOOTBLOCK The definition of bootblock_systemagent_early_init was guarded by !ENV_RAMSTAGE. But it's only called in the bootblock. So guard it with ENV_BOOTBLOCK instead. Change-Id: I143cf72e4a63b176e4772575e7a60a2a611e4ad9 Signed-off-by: Ronald G. Minnich Reviewed-on: https://review.coreboot.org/c/coreboot/+/32697 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Subrata Banik --- src/soc/intel/common/block/systemagent/systemagent_early.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/systemagent/systemagent_early.c b/src/soc/intel/common/block/systemagent/systemagent_early.c index 61f14a935c9..c12c64ab535 100644 --- a/src/soc/intel/common/block/systemagent/systemagent_early.c +++ b/src/soc/intel/common/block/systemagent/systemagent_early.c @@ -24,7 +24,7 @@ #include "systemagent_def.h" -#if !ENV_RAMSTAGE +#if ENV_BOOTBLOCK void bootblock_systemagent_early_init(void) { uint32_t reg; From 643daed6b54970da4d83055649b6abc2a198a840 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 8 May 2019 15:09:29 -0600 Subject: [PATCH 236/588] vendorcode/google/chromeos: Use explicit zero check in ACPI code The ASL 2.0 syntax for "!X" resolves to "LNot(X)" which will evaluate the object as an integer and turn into a boolean. This may not do the right thing if the object is actually a string and it can lead to unexpected behavior. Instead be specific about the object type and check for zero or an empty string depending on what is being returned. This fixes an issue where some VPD keys were causing the search to stop and miss subsequent entries. Change-Id: I1688842964f9c2f81ca31073da9c2d71a8c81767 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32694 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/vendorcode/google/chromeos/acpi/amac.asl | 3 ++- src/vendorcode/google/chromeos/acpi/vpd.asl | 10 +++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/vendorcode/google/chromeos/acpi/amac.asl b/src/vendorcode/google/chromeos/acpi/amac.asl index 51159f51243..c87862f6ffd 100644 --- a/src/vendorcode/google/chromeos/acpi/amac.asl +++ b/src/vendorcode/google/chromeos/acpi/amac.asl @@ -42,6 +42,7 @@ Scope (\_SB) /* Get "dock_passthru" value from RW_VPD */ Local0 = \VPD.VPDF ("RW", "dock_passthru") + Local1 = Zero Switch (ToString (Local0)) { Case ("ethernet_mac0") { @@ -55,7 +56,7 @@ Scope (\_SB) Local1 = \VPD.VPDF ("RO", "dock_mac") } } - If (!Local1) { + If (Local1 == Zero) { Return (Zero) } Printf ("MAC address returned from VPD: %o", Local1) diff --git a/src/vendorcode/google/chromeos/acpi/vpd.asl b/src/vendorcode/google/chromeos/acpi/vpd.asl index 3b262f75a88..8f8b0e571d6 100644 --- a/src/vendorcode/google/chromeos/acpi/vpd.asl +++ b/src/vendorcode/google/chromeos/acpi/vpd.asl @@ -139,7 +139,7 @@ Device (VPD) Local1 <<= 7 Local1 |= Local2 & 0x7f } - If (!Local1) { + If (Local1 == Zero) { Return (Zero) } @@ -162,7 +162,7 @@ Device (VPD) */ Method (VPDS, 0, Serialized) { - Name (VPKV, Package () { Zero, Zero }) + Name (VPKV, Package () { "", "" }) /* Read the VPD type and ensure it is a string */ If (^VPRB () != ^VPES) { @@ -193,14 +193,14 @@ Device (VPD) /* End address of VPD region */ ^VEND = ^VPTR + DerefOf (Local0[1]) - If (!^VPTR || !^VEND) { + If (^VPTR == Zero || ^VEND == Zero) { Printf ("Unable to find VPD region") Return (Zero) } /* Verify VPD info header and save size */ Local0 = VVPD (^VPTR) - If (!Local0) { + If (Local0 == Zero) { Printf ("VPD region %o did not verify", Arg0) Return (Zero) } @@ -213,7 +213,7 @@ Device (VPD) While (Local1 != ToString (Arg1)) { Local2 = VPDS () Local1 = DerefOf (Local2[0]) - If (!Local1) { + If (Local1 == "") { Printf ("VPD KEY %o not found", Arg1) Return (Zero) } From d5d89c8a55ee3a57fb30a7bca346076269266cab Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Tue, 7 May 2019 14:05:33 -0700 Subject: [PATCH 237/588] soc/intel/cannonlake: Fix pcie clock number Cannonlake PCH LP have total 6 pcie clocks and Cannonlake PCH H have total 16 pcie clocks. It is different with pcie root port numbers. BUG=CID 1381814 TEST=Build and boot up fine on sarien platform. Signed-off-by: Lijian Zhao Change-Id: I909b5b584c596e6fe878ffe24d9cabc53c4576ed Reviewed-on: https://review.coreboot.org/c/coreboot/+/32672 Tested-by: build bot (Jenkins) Reviewed-by: John Zhao Reviewed-by: Nico Huber Reviewed-by: Furquan Shaikh Reviewed-by: Subrata Banik --- src/soc/intel/cannonlake/Kconfig | 5 +++++ src/soc/intel/cannonlake/chip.h | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index c06b91eb48a..e524275b8fe 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -183,6 +183,11 @@ config MAX_ROOT_PORTS default 24 if SOC_INTEL_CANNONLAKE_PCH_H default 16 +config MAX_PCIE_CLOCKS + int + default 16 if SOC_INTEL_CANNONLAKE_PCH_H + default 6 + config SMM_TSEG_SIZE hex default 0x800000 diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index b17df4b21ba..f34528a017c 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -168,10 +168,10 @@ struct soc_intel_cannonlake_config { /* PCIe output clocks type to Pcie devices. * 0-23: PCH rootport, 0x70: LAN, 0x80: unspecified but in use, * 0xFF: not used */ - uint8_t PcieClkSrcUsage[CONFIG_MAX_ROOT_PORTS]; + uint8_t PcieClkSrcUsage[CONFIG_MAX_PCIE_CLOCKS]; /* PCIe ClkReq-to-ClkSrc mapping, number of clkreq signal assigned to * clksrc. */ - uint8_t PcieClkSrcClkReq[CONFIG_MAX_ROOT_PORTS]; + uint8_t PcieClkSrcClkReq[CONFIG_MAX_PCIE_CLOCKS]; /* PCIe LTR(Latency Tolerance Reporting) mechanism */ uint8_t PcieRpLtrEnable[CONFIG_MAX_ROOT_PORTS]; /* Enable/Disable HotPlug support for Root Port */ From 4feaf6b7b8745ba5a98b9b9372bb0a53b36b38e8 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 8 May 2019 09:13:34 +0200 Subject: [PATCH 238/588] sb/i82801gx: Remove duplicated 'define PMBASE' Change-Id: If08bea821043bc8e661bf5327f4fe2cef3a65be8 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32677 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/southbridge/intel/i82801gx/i82801gx.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index 3db5d49f3f7..b693b75ccf6 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -89,7 +89,6 @@ int smbus_block_write(unsigned int device, unsigned int cmd, u8 bytes, #define RTC_POWER_FAILED (1 << 1) #define SLEEP_AFTER_POWER_FAIL (1 << 0) -#define PMBASE 0x40 #define ACPI_CNTL 0x44 #define ACPI_EN (1 << 7) #define BIOS_CNTL 0xDC From 1119428693e9a8b071115187e601f94d1d706c23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 27 Mar 2019 10:39:55 +0100 Subject: [PATCH 239/588] soc/intel/braswell/smbus: Enable early SMBus in romstage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable early SMBus support compatible with SPD library using Intel SB common SMBus API. TEST=boot Protectli FW2B with new FSP, MemoryInit should pass without errors Signed-off-by: Michał Żygowski Change-Id: I92a2c5a6d0b38e5658cfdc017041f12717dabdd5 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32062 Tested-by: build bot (Jenkins) Reviewed-by: Frans Hendriks Reviewed-by: Patrick Georgi Reviewed-by: Nico Huber --- src/soc/intel/braswell/Makefile.inc | 1 + src/soc/intel/braswell/smbus.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/soc/intel/braswell/smbus.c diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index a2b7ee5e678..4e90edf15cc 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -14,6 +14,7 @@ romstage-y += iosf.c romstage-y += lpc_init.c romstage-y += memmap.c romstage-y += pmutil.c +romstage-y += smbus.c romstage-y += tsc_freq.c postcar-y += tsc_freq.c diff --git a/src/soc/intel/braswell/smbus.c b/src/soc/intel/braswell/smbus.c new file mode 100644 index 00000000000..7e1b0dfbb03 --- /dev/null +++ b/src/soc/intel/braswell/smbus.c @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Intel Corporation. + * Copyright (C) 2019 3mdeb + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +u8 smbus_read_byte(u32 smbus_dev, u8 addr, u8 offset) +{ + return do_smbus_read_byte(SMBUS_BASE_ADDRESS, addr, offset); +} + +u8 smbus_write_byte(u32 smbus_dev, u8 addr, u8 offset, u8 value) +{ + return do_smbus_write_byte(SMBUS_BASE_ADDRESS, addr, offset, value); +} From 8ed01a0e314990539c956b880560526f7c68177d Mon Sep 17 00:00:00 2001 From: Kevin Chiu Date: Wed, 8 May 2019 16:14:47 +0800 Subject: [PATCH 240/588] mainboard/google/kahlee: Fix Micron MT40A512M16TB-062E:J SPD CRC error Correct Micron MT40A512M16TB-062E:J SPD CRC to 0x5330 to fix post hang in AGESA TestPoint:05 TpProcMemSPDChecking. BUG=b:127394249 BRANCH=master TEST=emerge-grunt coreboot chromeos-bootimage Signed-off-by: Kevin Chiu Change-Id: I8fa49e6e938b3195945b3199438cc53f3e9c92e7 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32678 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- .../variants/baseboard/spd/micron-MT40A512M16TB-062E-J.spd.hex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/kahlee/variants/baseboard/spd/micron-MT40A512M16TB-062E-J.spd.hex b/src/mainboard/google/kahlee/variants/baseboard/spd/micron-MT40A512M16TB-062E-J.spd.hex index d4afea7263d..67640fe849b 100644 --- a/src/mainboard/google/kahlee/variants/baseboard/spd/micron-MT40A512M16TB-062E-J.spd.hex +++ b/src/mainboard/google/kahlee/variants/baseboard/spd/micron-MT40A512M16TB-062E-J.spd.hex @@ -6,7 +6,7 @@ 16 36 0B 35 00 00 16 36 0B 35 16 36 0B 35 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 -00 00 00 00 00 00 9C B5 00 00 00 00 E7 00 60 5B +00 00 00 00 00 00 9C B5 00 00 00 00 E7 00 30 53 0F 01 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 From 32b9a99e1670c638cf6e2db2a6274c3f0ab27c85 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 21 Jan 2019 14:54:31 +0100 Subject: [PATCH 241/588] nb/intel/i945: Use macro instead of magic number Change-Id: I028013bd7511b5b9fc80e5f744fcad584cb25fd3 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31027 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/northbridge/intel/i945/early_init.c | 4 ++-- src/northbridge/intel/i945/raminit.c | 22 +++++++++++----------- src/southbridge/intel/i82801gx/i82801gx.h | 1 + 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c index 274296d4827..84d9c105d6f 100644 --- a/src/northbridge/intel/i945/early_init.c +++ b/src/northbridge/intel/i945/early_init.c @@ -158,10 +158,10 @@ static void i945_setup_bars(void) printk(BIOS_DEBUG, "Setting up static southbridge registers..."); pci_write_config32(PCI_DEV(0, 0x1f, 0), PMBASE, DEFAULT_PMBASE | 1); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44, 0x80); /* ACPI_CNTL: Enable ACPI BAR */ + pci_write_config8(PCI_DEV(0, 0x1f, 0), ACPI_CNTL, ACPI_EN); pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIOBASE, DEFAULT_GPIOBASE | 1); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x4c, 0x10); /* GC: Enable GPIOs */ + pci_write_config8(PCI_DEV(0, 0x1f, 0), GPIO_CNTL, GPIO_EN); setup_pch_gpios(&mainboard_gpio_map); printk(BIOS_DEBUG, " done.\n"); diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index 0cf03ae605c..74407c14ffb 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -247,13 +247,13 @@ static void sdram_detect_errors(struct sys_info *sysinfo) u8 reg8; u8 do_reset = 0; - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2); if (reg8 & ((1<<7)|(1<<2))) { if (reg8 & (1<<2)) { printk(BIOS_DEBUG, "SLP S4# Assertion Width Violation.\n"); /* Write back clears bit 2 */ - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8); do_reset = 1; } @@ -261,14 +261,14 @@ static void sdram_detect_errors(struct sys_info *sysinfo) if (reg8 & (1<<7)) { printk(BIOS_DEBUG, "DRAM initialization was interrupted.\n"); reg8 &= ~(1<<7); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8); do_reset = 1; } /* Set SLP_S3# Assertion Stretch Enable */ - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4); /* GEN_PMCON_3 */ + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3); reg8 |= (1 << 3); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8); if (do_reset) { printk(BIOS_DEBUG, "Reset required.\n"); @@ -277,9 +277,9 @@ static void sdram_detect_errors(struct sys_info *sysinfo) } /* Set DRAM initialization bit in ICH7 */ - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2); reg8 |= (1<<7); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8); /* clear self refresh status if check is disabled or not a resume */ if (!CONFIG(CHECK_SLFRCS_ON_RESUME) @@ -1807,9 +1807,9 @@ static void sdram_program_memory_frequency(struct sys_info *sysinfo) */ goto cache_code; vco_update: - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2); reg8 &= ~(1 << 7); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8); clkcfg &= ~(1 << 10); MCHBAR32(CLKCFG) = clkcfg; @@ -2813,9 +2813,9 @@ void sdram_initialize(int boot_path, const u8 *spd_addresses) sdram_enable_rcomp(); /* Tell ICH7 that we're done */ - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2); + reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2); reg8 &= ~(1 << 7); - pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8); + pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8); printk(BIOS_DEBUG, "RAM initialization finished.\n"); diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index b693b75ccf6..a91ffc500b5 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -94,6 +94,7 @@ int smbus_block_write(unsigned int device, unsigned int cmd, u8 bytes, #define BIOS_CNTL 0xDC #define GPIO_BASE 0x48 /* LPC GPIO Base Address Register */ #define GPIO_CNTL 0x4C /* LPC GPIO Control Register */ +#define GPIO_EN (1 << 4) #define PIRQA_ROUT 0x60 #define PIRQB_ROUT 0x61 From 2de7af0c39c3d65b592c1e83d5511e2ef09a203c Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Wed, 8 May 2019 12:40:19 -0700 Subject: [PATCH 242/588] mb/google/hatch: Fix GBB_HWID for kohaku This change fixes the typo in CB:32161 (mb/google/hatch: Add Kohaku board) that defaults GBB_HWID incorrectly for kohaku using BOARD_GOOGLE_HATCH_WHL. Change-Id: I387879619ac4f79fad422e5f1f047dfe3c7b5b22 Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32690 Reviewed-by: Tim Wawrzynczak Reviewed-by: Paul Fagerburg Reviewed-by: Shelley Chen Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index 07ae7d214ea..09f792128ca 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -64,7 +64,7 @@ config GBB_HWID depends on CHROMEOS default "HATCH TEST 1823" if BOARD_GOOGLE_HATCH default "HATCH_WHL TEST 2374" if BOARD_GOOGLE_HATCH_WHL - default "KOHAKU TEST 1953" if BOARD_GOOGLE_HATCH_WHL + default "KOHAKU TEST 1953" if BOARD_GOOGLE_KOHAKU config MAINBOARD_DIR string From bddfa59f1da418b7c144a4b0eee5e0303aa1183c Mon Sep 17 00:00:00 2001 From: Dtrain Hsu Date: Tue, 7 May 2019 14:35:56 +0800 Subject: [PATCH 243/588] mb/google/hatch: Fine tune Goodix touch screen timing According to Goodix GT7375P datasheet, reduce Goodix touch screen timing. BUG=b:129727745 BRANCH=None TEST=local build and tested with Goodix touch screen worked under coldboot (10 times), warmboot (10 times), S3 (10 times). Change-Id: I4bf081bab5e89d3ce336c6432da5ba71279fa98d Signed-off-by: Dtrain Hsu Reviewed-on: https://review.coreboot.org/c/coreboot/+/32665 Tested-by: build bot (Jenkins) Reviewed-by: Paul Fagerburg Reviewed-by: Shelley Chen --- src/mainboard/google/hatch/variants/hatch/overridetree.cb | 4 ++-- src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/hatch/variants/hatch/overridetree.cb b/src/mainboard/google/hatch/variants/hatch/overridetree.cb index 42752e68f1c..562bb8b229e 100644 --- a/src/mainboard/google/hatch/variants/hatch/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch/overridetree.cb @@ -78,8 +78,8 @@ chip soc/intel/cannonlake register "generic.probed" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D15)" - register "generic.reset_delay_ms" = "30" - register "generic.reset_off_delay_ms" = "3" + register "generic.reset_delay_ms" = "10" + register "generic.reset_off_delay_ms" = "1" register "generic.has_power_resource" = "1" register "hid_desc_reg_offset" = "0x01" device i2c 5d on end diff --git a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb index 115a513038e..eec78807527 100644 --- a/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb +++ b/src/mainboard/google/hatch/variants/hatch_whl/overridetree.cb @@ -63,8 +63,8 @@ chip soc/intel/cannonlake register "generic.probed" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D15)" - register "generic.reset_delay_ms" = "30" - register "generic.reset_off_delay_ms" = "3" + register "generic.reset_delay_ms" = "10" + register "generic.reset_off_delay_ms" = "1" register "generic.has_power_resource" = "1" register "hid_desc_reg_offset" = "0x01" device i2c 5d on end From 1360b9a73f5389efd94f0de36588d71f6f8cd1d1 Mon Sep 17 00:00:00 2001 From: Bonnie Lin Date: Wed, 8 May 2019 18:08:08 +0800 Subject: [PATCH 244/588] mb/google/sarien/variants/arcada: Set tcc offset value Set tcc offset value to 1 degree celsius for Arcada system. BRANCH=None BUG=b:122636962 TEST=Built and tested on Arcada system Signed-off-by: Bonnie Lin Change-Id: I3ca4be2f7b92e29fb133ecc32023526b177d2ac2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32680 Tested-by: build bot (Jenkins) Reviewed-by: Casper Chang Reviewed-by: Lijian Zhao Reviewed-by: Sumeet R Pawnikar --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 0cc99704888..27c61f35635 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -161,7 +161,7 @@ chip soc/intel/cannonlake #| I2C4 | H1 TPM | #+-------------------+---------------------------+ - register "tcc_offset" = "10" + register "tcc_offset" = "1" register "common_soc_config" = "{ .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT, From 9d9ce62ae9bd122e43ab87468de541a822a0ff1f Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 25 Dec 2018 18:12:41 +0100 Subject: [PATCH 245/588] mb/google/nami: Add VBT blobs and include them in cbfs Add vbt files for nami variants and select Kconfig option to utilize them. The default vbt is automatically added by the Kconfig selection and so does not need to be specified in the makefile with the others. Test: boot vayne and akali nami variants, verify display functional and correct vbt loaded. Change-Id: Iaf49bdee7ae82a0a61192327351267f098eb5ab1 Signed-off-by: Arthur Heymans Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/30427 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/google/poppy/Kconfig | 1 + .../google/poppy/variants/nami/Makefile.inc | 3 +++ .../nami/{vbt-akali.bin => akali-data.vbt} | Bin .../google/poppy/variants/nami/data.vbt | Bin 0 -> 4608 bytes .../google/poppy/variants/nami/pantheon-data.vbt | Bin 0 -> 4608 bytes .../google/poppy/variants/nami/vayne-data.vbt | Bin 0 -> 4608 bytes 6 files changed, 4 insertions(+) rename src/mainboard/google/poppy/variants/nami/{vbt-akali.bin => akali-data.vbt} (100%) create mode 100644 src/mainboard/google/poppy/variants/nami/data.vbt create mode 100644 src/mainboard/google/poppy/variants/nami/pantheon-data.vbt create mode 100644 src/mainboard/google/poppy/variants/nami/vayne-data.vbt diff --git a/src/mainboard/google/poppy/Kconfig b/src/mainboard/google/poppy/Kconfig index b7f479f888d..6bc8269aa7c 100644 --- a/src/mainboard/google/poppy/Kconfig +++ b/src/mainboard/google/poppy/Kconfig @@ -10,6 +10,7 @@ config BOARD_GOOGLE_BASEBOARD_POPPY select EC_GOOGLE_CHROMEEC_LPC select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES + select INTEL_GMA_HAVE_VBT if BOARD_GOOGLE_NAMI select INTEL_LPSS_UART_FOR_CONSOLE select MAINBOARD_HAS_CHROMEOS select MAINBOARD_USES_FSP2_0 diff --git a/src/mainboard/google/poppy/variants/nami/Makefile.inc b/src/mainboard/google/poppy/variants/nami/Makefile.inc index dc803578353..0033c60ee71 100644 --- a/src/mainboard/google/poppy/variants/nami/Makefile.inc +++ b/src/mainboard/google/poppy/variants/nami/Makefile.inc @@ -43,3 +43,6 @@ oem.bin-file := $(call strip_quotes,$(CONFIG_OEM_BIN_FILE)) oem.bin-type := raw $(call add_vbt_to_cbfs, vbt-bard.bin, bard-data.vbt) +$(call add_vbt_to_cbfs, vbt-akali.bin, akali-data.vbt) +$(call add_vbt_to_cbfs, vbt-pantheon.bin, pantheon-data.vbt) +$(call add_vbt_to_cbfs, vbt-vayne.bin, vayne-data.vbt) diff --git a/src/mainboard/google/poppy/variants/nami/vbt-akali.bin b/src/mainboard/google/poppy/variants/nami/akali-data.vbt similarity index 100% rename from src/mainboard/google/poppy/variants/nami/vbt-akali.bin rename to src/mainboard/google/poppy/variants/nami/akali-data.vbt diff --git a/src/mainboard/google/poppy/variants/nami/data.vbt b/src/mainboard/google/poppy/variants/nami/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..84063621d0a655cdc7024cf8c0e25004d09183b4 GIT binary patch literal 4608 zcmeHKUu;ul6hF7Of4_TgcY8;m6r4vy=mu=J118KVw`&J0>sY&vIid+2wCG}CV;g4p zj~ZvP1T}q7gNEo5UktvG7@v%h7b6K#c~E?m7ZW6!n27NOxSspn%L**81|tT;Y0r1g zckb!$p7Z@ZT{+k}fVrMs>3B~UI#d81c7?W6JD)mJeYxGq_&|JjXSy%ZgWtnqh=#6S z1Skl?QaPsUvDAUdVkz3+NU&+_9o;ihDz+qx6VFYKj$tN|!ua03#Zqy6c(Pc)+~Br2 zT9^v!JTy`&;EqH4_Y}w5k$`ma#@L4D^&1dlEv@v`V;f1;+hc9*8#gN~*_G()&7{)t zfmGiP?CZy5Di_b?x_Ud)yD-z=*PZH24Rj?HHkU?XbnNi>$TQDQVl>f+t@Ms{9F&KQ ziP7<~W{j6g*l+nvV1IFQS*{Vmi(EG>XNS-Y=klPc{)>cUkq^Mb6;(ir zgkm8^!|}T8c-gPzkI^;fg^pJ+V3`0&c)6krXuq0z6f}`a(K}ueccJ&-^T2G}M>VN!I#E8-?t;XV!i0K%Gp3QrJciO+Z#{6PE@@h`-G z5MLqoc^QO=mk~cg+(NvWI6>S?{3P)(vG)*MHeF?F3W&;rBSW?X)eUboLixC3KknEA zztdzBF-J;{bmIj@3rg<%xyN)q!)3zS2ejFw$la{{TkN~iFpnuhyWVj2Jtb5!%UlC>}7@@G3_(PzGV0_)Ba*ikZ`r6 zZI)O zL_5l}V<#Ubgr@3TRCt{t&w8e7SP$b{O~&c`bU_bi z?RpR>3z3$iwI1$pO>zXqM(|(_SzL_3YzCL;vYx1BQK9`vF_e9q_OV literal 0 HcmV?d00001 diff --git a/src/mainboard/google/poppy/variants/nami/pantheon-data.vbt b/src/mainboard/google/poppy/variants/nami/pantheon-data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..7e4fb0afe5ae87582126da375c018c4b5e1b389f GIT binary patch literal 4608 zcmeGfU2GI(aQ60ozump=Z3!F)))5h|1=_s=6>62e-W7WEO7D85mT1Bi?$E}AmbQ@M zA7`uy32N>^4H}|Nd@=Y!Vtg`2UW_C}pV14D&USo`}Y*b+mQ_Eq>Zr+&FeQH##&nGtH(AHtGCD6+Ba@iSh6e8*PBVD z;{&O_9oW~8$y6?$%XRg3rgveczpp#hnHuOyDr`24#OT$p+w zGA2gH$C@!-Dq+8+GlBiZiQ@R-Vxd`KmXR~ycMAZ52kHzE;94ty-~J-_Rd5^NMsTZO zAQ&p3YCUxW7yt;MT283o+9tQ=>VA0<(y_^TK6To~=5n&2g$k}To*W?>T$(0tp z3*HFlz}I2Z`QtzNBw|&-vY%Y%eGJa~t_a8KtK22=0LcWHE2}=eyPTCZb%BqaSt>B+ zSg_~zSeQHcpZ`y1V0kxO2$U;$@jlg`Uty=B;m#!YKS?#|^3%a!01_)hH$))}NmvPs zAP*VdH~INF`=^}OCPIWdYlGefq7gDaF;C$X0YKv$AU?uym}wJ?y}K(;KPcRQdmyGBZ_uhVQ(t`xJmZv zHyLO1(*-@8wfjM!C`2kps~+yKCbjQLASsR>o(LDlx0P26s9{>OV literal 0 HcmV?d00001 diff --git a/src/mainboard/google/poppy/variants/nami/vayne-data.vbt b/src/mainboard/google/poppy/variants/nami/vayne-data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..7e4fb0afe5ae87582126da375c018c4b5e1b389f GIT binary patch literal 4608 zcmeGfU2GI(aQ60ozump=Z3!F)))5h|1=_s=6>62e-W7WEO7D85mT1Bi?$E}AmbQ@M zA7`uy32N>^4H}|Nd@=Y!Vtg`2UW_C}pV14D&USo`}Y*b+mQ_Eq>Zr+&FeQH##&nGtH(AHtGCD6+Ba@iSh6e8*PBVD z;{&O_9oW~8$y6?$%XRg3rgveczpp#hnHuOyDr`24#OT$p+w zGA2gH$C@!-Dq+8+GlBiZiQ@R-Vxd`KmXR~ycMAZ52kHzE;94ty-~J-_Rd5^NMsTZO zAQ&p3YCUxW7yt;MT283o+9tQ=>VA0<(y_^TK6To~=5n&2g$k}To*W?>T$(0tp z3*HFlz}I2Z`QtzNBw|&-vY%Y%eGJa~t_a8KtK22=0LcWHE2}=eyPTCZb%BqaSt>B+ zSg_~zSeQHcpZ`y1V0kxO2$U;$@jlg`Uty=B;m#!YKS?#|^3%a!01_)hH$))}NmvPs zAP*VdH~INF`=^}OCPIWdYlGefq7gDaF;C$X0YKv$AU?uym}wJ?y}K(;KPcRQdmyGBZ_uhVQ(t`xJmZv zHyLO1(*-@8wfjM!C`2kps~+yKCbjQLASsR>o(LDlx0P26s9{>OV literal 0 HcmV?d00001 From c9f6bd90857d3a7efe08c60f7f5fc19995fb1756 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 9 May 2019 12:40:53 +0200 Subject: [PATCH 246/588] sb/i82801gx: Don't rewrite over BCTRL PCI_MIN_GNT is defined at offset 0x3e in which does not apply to this PCI bridge because it is only defined for "Header type 0 (normal devices)" (line 82). BCTRL registry for D30:F0 is defined at offset 0x3e for i82801gx (see ICH7 Family Datasheet page 355). The write on that register is already done some lines above. So remove wrong register name and the wrong code line. Change-Id: Ib8a0514200f424049503bb8e4bc076ee6ae86ce3 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32699 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/southbridge/intel/i82801gx/pci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/southbridge/intel/i82801gx/pci.c b/src/southbridge/intel/i82801gx/pci.c index c54769fff3d..22c516581f5 100644 --- a/src/southbridge/intel/i82801gx/pci.c +++ b/src/southbridge/intel/i82801gx/pci.c @@ -46,9 +46,6 @@ static void pci_init(struct device *dev) reg8 |= (0x04 << 3); pci_write_config8(dev, SMLT, reg8); - /* Will this improve throughput of bus masters? */ - pci_write_config8(dev, PCI_MIN_GNT, 0x06); - /* Clear errors in status registers */ reg16 = pci_read_config16(dev, PSTS); //reg16 |= 0xf900; From 9646cfe989a096372a717d8ef16ce5096d1b2708 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 9 May 2019 13:24:14 +0200 Subject: [PATCH 247/588] sb/bd82x6x: Don't rewrite over BCTRL PCI_MIN_GNT is defined at offset 0x3e in which does not apply to this PCI bridge because it is only defined for "Header type 0 (normal devices)" (line 82). Some lines obove that code line, the "write" on BCTRL is already done. Change-Id: I8f1b98ba627947ab6652a4ba31d2acb159dd3e32 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32700 Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/southbridge/intel/bd82x6x/pci.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/southbridge/intel/bd82x6x/pci.c b/src/southbridge/intel/bd82x6x/pci.c index c3b82577e1d..2186287df2d 100644 --- a/src/southbridge/intel/bd82x6x/pci.c +++ b/src/southbridge/intel/bd82x6x/pci.c @@ -47,9 +47,6 @@ static void pci_init(struct device *dev) reg8 |= (0x04 << 3); pci_write_config8(dev, SMLT, reg8); - /* Will this improve throughput of bus masters? */ - pci_write_config8(dev, PCI_MIN_GNT, 0x06); - /* Clear errors in status registers */ reg16 = pci_read_config16(dev, PSTS); //reg16 |= 0xf900; From f36fcdf2ab6a9956ac60012404e0edf1d6653fac Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Fri, 19 Apr 2019 17:36:46 -0700 Subject: [PATCH 248/588] mb/google/sarien: Fix s5 touchscreen power leakage Leakage power is observed from TOUCH_SCREEN_PD# (GPP_E7 which is connected to RESET pin of Wacom controller) during S5. To avoid leakage power, GPP_E7 needs to be turned off before S5 entry. BUG=b:129899315 TEST=Measure leakage power in S5 from both Arcada and Sarien Signed-off-by: Lijian Zhao Change-Id: Ie4229477b7149c0a75f4a8c6c7c453a37cc1c78c Reviewed-on: https://review.coreboot.org/c/coreboot/+/32367 Tested-by: build bot (Jenkins) Reviewed-by: Roy Mingi Park Reviewed-by: Duncan Laurie --- .../sarien/variants/arcada/include/variant/acpi/mainboard.asl | 4 ++++ .../sarien/variants/sarien/include/variant/acpi/mainboard.asl | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl index bc036960488..41121d28fe0 100644 --- a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl @@ -14,6 +14,7 @@ */ #define CAM_EN GPP_B11 /* Active low */ +#define TS_PD GPP_E7 /* Method called from LPIT prior to enter s0ix state */ Method (MS0X, 1) @@ -31,6 +32,9 @@ Method (MS0X, 1) Method (MPTS, 1) { \_SB.PCI0.LPCB.EC0.PTS (Arg0) + + /* Clear touch screen pd pin to avoid leakage */ + \_SB.PCI0.CTXS (TS_PD) } /* Method called from _WAK prior to wakeup */ diff --git a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl index bc036960488..41121d28fe0 100644 --- a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl @@ -14,6 +14,7 @@ */ #define CAM_EN GPP_B11 /* Active low */ +#define TS_PD GPP_E7 /* Method called from LPIT prior to enter s0ix state */ Method (MS0X, 1) @@ -31,6 +32,9 @@ Method (MS0X, 1) Method (MPTS, 1) { \_SB.PCI0.LPCB.EC0.PTS (Arg0) + + /* Clear touch screen pd pin to avoid leakage */ + \_SB.PCI0.CTXS (TS_PD) } /* Method called from _WAK prior to wakeup */ From 939bfccb3dbf04a0a2f7e15b82db1fdb469b7a73 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Sun, 5 May 2019 15:39:40 -0600 Subject: [PATCH 249/588] soc/amd/stoneyridge: Add IO access functions for PMx Replace locations in the source that explicitely use the CD6/CD7 index/data pair with utility function calls. Change-Id: I6e7ba472ef2551e363987d18a79408fcd2074de4 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32648 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/enable_usbdebug.c | 5 +-- .../amd/stoneyridge/include/soc/southbridge.h | 6 +++ src/soc/amd/stoneyridge/sb_util.c | 37 +++++++++++++++++++ src/soc/amd/stoneyridge/southbridge.c | 12 ++---- 4 files changed, 48 insertions(+), 12 deletions(-) diff --git a/src/soc/amd/stoneyridge/enable_usbdebug.c b/src/soc/amd/stoneyridge/enable_usbdebug.c index ce84a479295..90bd6e8f336 100644 --- a/src/soc/amd/stoneyridge/enable_usbdebug.c +++ b/src/soc/amd/stoneyridge/enable_usbdebug.c @@ -26,10 +26,7 @@ pci_devfn_t pci_ehci_dbg_dev(unsigned int hcd_idx) { - /* Enable all of the USB controllers */ - outb(PM_USB_ENABLE, PM_INDEX); - outb(PM_USB_ALL_CONTROLLERS, PM_DATA); - + pm_io_write8(PM_USB_ENABLE, PM_USB_ALL_CONTROLLERS); return SOC_EHCI1_DEV; } diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index f755c0a0d45..618a5deff78 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -491,6 +491,12 @@ void sb_tpm_decode(void); void sb_tpm_decode_spi(void); void lpc_wideio_512_window(uint16_t base); void lpc_wideio_16_window(uint16_t base); +uint8_t pm_io_read8(uint8_t reg); +uint16_t pm_io_read16(uint8_t reg); +uint32_t pm_io_read32(uint8_t reg); +void pm_io_write8(uint8_t reg, uint8_t value); +void pm_io_write16(uint8_t reg, uint16_t value); +void pm_io_write32(uint8_t reg, uint32_t value); u8 pm_read8(u8 reg); u16 pm_read16(u8 reg); u32 pm_read32(u8 reg); diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 41ebb37be2d..524efc45ad2 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -18,6 +18,43 @@ #include #include +/* PM registers are accessed a byte at a time via CD6/CD7 */ +uint8_t pm_io_read8(uint8_t reg) +{ + outb(reg, PM_INDEX); + return inb(PM_DATA); +} + +uint16_t pm_io_read16(uint8_t reg) +{ + return (pm_io_read8(reg + sizeof(uint8_t)) << 8) | pm_io_read8(reg); +} + +uint32_t pm_io_read32(uint8_t reg) +{ + return (pm_io_read16(reg + sizeof(uint16_t)) << 16) | pm_io_read16(reg); +} + +void pm_io_write8(uint8_t reg, uint8_t value) +{ + outb(reg, PM_INDEX); + outb(value, PM_DATA); +} + +void pm_io_write16(uint8_t reg, uint16_t value) +{ + pm_io_write8(reg, value & 0xff); + value >>= 8; + pm_io_write8(reg + sizeof(uint8_t), value & 0xff); +} + +void pm_io_write32(uint8_t reg, uint32_t value) +{ + pm_io_write16(reg, value & 0xffff); + value >>= 16; + pm_io_write16(reg + sizeof(uint16_t), value & 0xffff); +} + /* smbus pci read/write - access registers at 0xfed80000 - currently unused */ /* smi read/write - access registers at 0xfed80200 */ diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index b5901782f69..8dfef8b369f 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -329,11 +329,9 @@ void sb_lpc_port80(void) u8 byte; /* Enable LPC controller */ - outb(PM_LPC_GATING, PM_INDEX); - byte = inb(PM_DATA); + byte = pm_io_read8(PM_LPC_GATING); byte |= PM_LPC_ENABLE; - outb(PM_LPC_GATING, PM_INDEX); - outb(byte, PM_DATA); + pm_io_write8(PM_LPC_GATING, byte); /* Enable port 80 LPC decode in pci function 3 configuration space. */ byte = pci_read_config8(SOC_LPC_DEV, LPC_IO_OR_MEM_DEC_EN_HIGH); @@ -367,11 +365,9 @@ void sb_acpi_mmio_decode(void) uint8_t byte; /* Enable ACPI MMIO range 0xfed80000 - 0xfed81fff */ - outb(PM_ISA_CONTROL, PM_INDEX); - byte = inb(PM_DATA); + byte = pm_io_read8(PM_ISA_CONTROL); byte |= MMIO_EN; - outb(PM_ISA_CONTROL, PM_INDEX); - outb(byte, PM_DATA); + pm_io_write8(PM_ISA_CONTROL, byte); } static void sb_enable_cf9_io(void) From ef7d89cabe658e7f2951112c50853328988cea98 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 9 May 2019 13:40:23 -0700 Subject: [PATCH 250/588] vboot: Make vboot_logic_executed() a bit more precise This patch adds another check to vboot_logic_executed() to make sure we only do a runtime check for verstage_should_load() if CONFIG_VBOOT_RETURN_FROM_VERSTAGE is enabled. That's the only case where the stage that's loading the verstage can execute after verification has run (because the verstage will return to it when it's done). In the other case, the stage that loads verstage really just loads it and will never do anything again after hand-off, so it's guaranteed to always execute before verification. This change may allow extra dead-code elimination in some cases. Change-Id: I7019b6f7b0acfbf0a8173914b53364751b08f2cf Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32714 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/security/vboot/vboot_loader.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/security/vboot/vboot_loader.c b/src/security/vboot/vboot_loader.c index 0640ebd173f..3bbb3da99c4 100644 --- a/src/security/vboot/vboot_loader.c +++ b/src/security/vboot/vboot_loader.c @@ -64,9 +64,11 @@ static int vboot_executed CAR_GLOBAL; int vboot_logic_executed(void) { - /* If we are in a stage that would load the verstage or execute the - vboot logic directly, we store the answer in a global. */ - if (verstage_should_load() || verification_should_run()) + /* If we are in the stage that runs verification, or in the stage that + both loads the verstage and is returned to from it afterwards, we + need to check a global to see if verfication has run. */ + if (verification_should_run() || + (verstage_should_load() && CONFIG(VBOOT_RETURN_FROM_VERSTAGE))) return car_get_var(vboot_executed); if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)) { From a73e5a75b1b1ba03e7712d981456974e89a21264 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 9 May 2019 14:12:17 -0700 Subject: [PATCH 251/588] assert.h: Undefine ASSERT macro in case vendorcode headers set it Some edk2 vendorcode headers define an ASSERT macro. They're guarded with an #ifndef ASSERT, but if coreboot's assert.h gets included after that header, we still have a problem. Add code to assert.h to undefine any rogue definitions that may have already been set by vendorcode headers. This is ugly and should only be a stopgap... it would be nice if someone maintaining those vendorcode parts could eventually replace it with a better solution. One option would be to use a "guard header" for every vendorcode header we want to pull into normal coreboot code which would chain-include the vendorcode header and then undefine anything that clashes with coreboot again. Change-Id: Ibf8dc8b2365821e401ce69705df20aa7540aefb2 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32715 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin Reviewed-by: Furquan Shaikh --- src/include/assert.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/assert.h b/src/include/assert.h index 60366352739..4575a29e447 100644 --- a/src/include/assert.h +++ b/src/include/assert.h @@ -19,6 +19,12 @@ #include #include +/* TODO: Fix vendorcode headers to not define macros coreboot uses or to be more + properly isolated. */ +#ifdef ASSERT +#undef ASSERT +#endif + /* GCC and CAR versions */ #define ASSERT(x) { \ if (!(x)) { \ From 998dc17f522af6ef8fc7c85fa1e90fa7873fe7d1 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 9 May 2019 14:16:13 -0700 Subject: [PATCH 252/588] vboot: Turn vboot_logic_executed() into a static inline This patch moves vboot_logic_executed() (and its dependencies) into a header and turns it into a static inline function. The function is used to guard larger amounts of code in several places, so this should allow us to save some more space through compile-time elimination (and also makes it easier to avoid undefined reference issues in some cases). Change-Id: I193f608882cbfe07dc91ee90d02fafbd67a3c324 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32716 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin Reviewed-by: Frans Hendriks --- src/security/vboot/misc.h | 59 ++++++++++++++++++++++++++++--- src/security/vboot/vboot_loader.c | 50 +------------------------- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/src/security/vboot/misc.h b/src/security/vboot/misc.h index b4fae19d74d..23159c8a0d5 100644 --- a/src/security/vboot/misc.h +++ b/src/security/vboot/misc.h @@ -16,6 +16,8 @@ #ifndef __VBOOT_MISC_H__ #define __VBOOT_MISC_H__ +#include +#include #include struct vb2_context; @@ -66,13 +68,62 @@ int vboot_is_slot_selected(void); void vboot_fill_handoff(void); /* - * Source: security/vboot/vboot_loader.c + * Source: security/vboot/bootmode.c */ -int vboot_logic_executed(void); +void vboot_save_recovery_reason_vbnv(void); /* - * Source: security/vboot/bootmode.c + * The stage loading code is compiled and entered from multiple stages. The + * helper functions below attempt to provide more clarity on when certain + * code should be called. They are implemented inline for better compile-time + * code elimination. */ -void vboot_save_recovery_reason_vbnv(void); + +static inline int verification_should_run(void) +{ + if (CONFIG(VBOOT_SEPARATE_VERSTAGE)) + return ENV_VERSTAGE; + else if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE)) + return ENV_ROMSTAGE; + else if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)) + return ENV_BOOTBLOCK; + else + dead_code(); +} + +static inline int verstage_should_load(void) +{ + if (CONFIG(VBOOT_SEPARATE_VERSTAGE)) + return ENV_BOOTBLOCK; + else + return 0; +} + +static inline int vboot_logic_executed(void) +{ + extern int vboot_executed; /* should not be globally accessible */ + + /* If we are in the stage that runs verification, or in the stage that + both loads the verstage and is returned to from it afterwards, we + need to check a global to see if verfication has run. */ + if (verification_should_run() || + (verstage_should_load() && CONFIG(VBOOT_RETURN_FROM_VERSTAGE))) + return car_get_var(vboot_executed); + + if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)) { + /* All other stages are "after the bootblock" */ + return !ENV_BOOTBLOCK; + } else if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE)) { + /* Post-RAM stages are "after the romstage" */ +#ifdef __PRE_RAM__ + return 0; +#else + return 1; +#endif + } else { + dead_code(); + } +} + #endif /* __VBOOT_MISC_H__ */ diff --git a/src/security/vboot/vboot_loader.c b/src/security/vboot/vboot_loader.c index 3bbb3da99c4..13503074250 100644 --- a/src/security/vboot/vboot_loader.c +++ b/src/security/vboot/vboot_loader.c @@ -36,55 +36,7 @@ _Static_assert(!CONFIG(VBOOT_RETURN_FROM_VERSTAGE) || CONFIG(VBOOT_SEPARATE_VERSTAGE), "return from verstage only makes sense for separate verstages"); -/* The stage loading code is compiled and entered from multiple stages. The - * helper functions below attempt to provide more clarity on when certain - * code should be called. */ - -static int verification_should_run(void) -{ - if (CONFIG(VBOOT_SEPARATE_VERSTAGE)) - return ENV_VERSTAGE; - else if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE)) - return ENV_ROMSTAGE; - else if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)) - return ENV_BOOTBLOCK; - else - die("impossible!"); -} - -static int verstage_should_load(void) -{ - if (CONFIG(VBOOT_SEPARATE_VERSTAGE)) - return ENV_BOOTBLOCK; - else - return 0; -} - -static int vboot_executed CAR_GLOBAL; - -int vboot_logic_executed(void) -{ - /* If we are in the stage that runs verification, or in the stage that - both loads the verstage and is returned to from it afterwards, we - need to check a global to see if verfication has run. */ - if (verification_should_run() || - (verstage_should_load() && CONFIG(VBOOT_RETURN_FROM_VERSTAGE))) - return car_get_var(vboot_executed); - - if (CONFIG(VBOOT_STARTS_IN_BOOTBLOCK)) { - /* All other stages are "after the bootblock" */ - return !ENV_BOOTBLOCK; - } else if (CONFIG(VBOOT_STARTS_IN_ROMSTAGE)) { - /* Post-RAM stages are "after the romstage" */ -#ifdef __PRE_RAM__ - return 0; -#else - return 1; -#endif - } else { - die("impossible!"); - } -} +int vboot_executed CAR_GLOBAL; static void vboot_prepare(void) { From 4249348735d18cb2d44506090a675a29b0567e7f Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Thu, 9 May 2019 17:09:25 +0000 Subject: [PATCH 253/588] Define ENV_PAYLOAD_LOADER We've been assuming that ENV_RAMSTAGE is always the payload loader. In order to test out different models, we need a way to mark the "stage we are in" as the payload loader. Define a new rule, ENV_PAYLOAD_LOADER. For now, it is set to ENV_RAMSTAGE. It is not used yet pending approval of this approach. Change-Id: I7d4aa71bad92987374d57ff350b9b0178ee7c12b Signed-off-by: Ronald G. Minnich Reviewed-on: https://review.coreboot.org/c/coreboot/+/32709 Tested-by: build bot (Jenkins) --- src/include/rules.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/include/rules.h b/src/include/rules.h index ea8335fb8ca..ce968f0dd9d 100644 --- a/src/include/rules.h +++ b/src/include/rules.h @@ -257,6 +257,10 @@ #endif +/* ENV_PAYLOAD_LOADER is set when you are in a stage that loads the payload. + * For now, that is the ramstage. */ +#define ENV_PAYLOAD_LOADER ENV_RAMSTAGE + /** * For pre-DRAM stages and post-CAR always build with simple device model, ie. * PCI, PNP and CPU functions operate without use of devicetree. The reason From 1159a163cd36318d27f8f3b71617ad4a5b781efb Mon Sep 17 00:00:00 2001 From: John Zhao Date: Mon, 22 Apr 2019 10:45:51 -0700 Subject: [PATCH 254/588] soc/intel/cnl: Enable VT-d Enable VT-d through fsp upd VtdDisable. Update remapping structure types in numerical order as all remapping structures of type 0 (DRHD) enumerated before remapping structures of type 1 (RMRR), and so forth. BUG=b:130351429 TEST=Booted to kernel and verified the DMAR table contents. Change-Id: I1d20932e417b9d324edd98c8f2195dc228d2e092 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/32432 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Pratikkumar V Prajapati --- src/soc/intel/cannonlake/acpi.c | 15 ++++++++------- src/soc/intel/cannonlake/chip.h | 3 --- src/soc/intel/cannonlake/romstage/fsp_params.c | 5 +++++ src/soc/intel/cannonlake/systemagent.c | 6 +----- 4 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c index 209e7c52d4e..ff9da451c81 100644 --- a/src/soc/intel/cannonlake/acpi.c +++ b/src/soc/intel/cannonlake/acpi.c @@ -304,13 +304,6 @@ static unsigned long soc_fill_dmar(unsigned long current) current += acpi_create_dmar_ds_pci(current, 0, 2, 0); acpi_dmar_drhd_fixup(tmp, current); - - /* Add RMRR entry */ - tmp = current; - current += acpi_create_dmar_rmrr(current, 0, - sa_get_gsm_base(), sa_get_tolud_base() - 1); - current += acpi_create_dmar_ds_pci(current, 0, 2, 0); - acpi_dmar_rmrr_fixup(tmp, current); } struct device *const ipu_dev = dev_find_slot(0, SA_DEVFN_IPU); @@ -344,6 +337,13 @@ static unsigned long soc_fill_dmar(unsigned long current) acpi_dmar_drhd_fixup(tmp, current); } + /* Add RMRR entry */ + const unsigned long tmp = current; + current += acpi_create_dmar_rmrr(current, 0, + sa_get_gsm_base(), sa_get_tolud_base() - 1); + current += acpi_create_dmar_ds_pci(current, 0, 2, 0); + acpi_dmar_rmrr_fixup(tmp, current); + return current; } @@ -361,6 +361,7 @@ unsigned long sa_write_acpi_tables(struct device *dev, unsigned long current, printk(BIOS_DEBUG, "ACPI: * DMAR\n"); acpi_create_dmar(dmar, DMAR_INTR_REMAP, soc_fill_dmar); + current += dmar->header.length; current = acpi_align_current(current); acpi_add_table(rsdp, dmar); diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index f34528a017c..2b2a51f6a0f 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -344,9 +344,6 @@ struct soc_intel_cannonlake_config { /* Enable Pch iSCLK */ uint8_t pch_isclk; - /* Intel VT configuration */ - uint8_t VtdDisable; - /* * Acoustic Noise Mitigation * 0b - Disable diff --git a/src/soc/intel/cannonlake/romstage/fsp_params.c b/src/soc/intel/cannonlake/romstage/fsp_params.c index c71e4b551a5..6e492bb73ae 100644 --- a/src/soc/intel/cannonlake/romstage/fsp_params.c +++ b/src/soc/intel/cannonlake/romstage/fsp_params.c @@ -101,6 +101,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) assert(dev != NULL); const config_t *config = dev->chip_info; FSP_M_CONFIG *m_cfg = &mupd->FspmConfig; + FSP_M_TEST_CONFIG *tconfig = &mupd->FspmTestConfig; soc_memory_init_params(m_cfg, config); @@ -113,6 +114,10 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) /* Set debug probe type */ m_cfg->PlatformDebugConsent = CONFIG_SOC_INTEL_CANNONLAKE_DEBUG_CONSENT; + + /* Configure VT-d */ + tconfig->VtdDisable = 0; + mainboard_memory_init_params(mupd); } diff --git a/src/soc/intel/cannonlake/systemagent.c b/src/soc/intel/cannonlake/systemagent.c index d850b15b345..3f01f14dcf0 100644 --- a/src/soc/intel/cannonlake/systemagent.c +++ b/src/soc/intel/cannonlake/systemagent.c @@ -33,8 +33,6 @@ */ void soc_add_fixed_mmio_resources(struct device *dev, int *index) { - const struct soc_intel_cannonlake_config *const config = dev->chip_info; - static const struct sa_mmio_descriptor soc_fixed_resources[] = { { PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS, CONFIG_SA_PCIEX_LENGTH, "PCIEXBAR" }, @@ -63,10 +61,8 @@ void soc_add_fixed_mmio_resources(struct device *dev, int *index) if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE)) return; - if (!(config && config->VtdDisable)) { - sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, + sa_add_fixed_mmio_resources(dev, index, soc_vtd_resources, ARRAY_SIZE(soc_vtd_resources)); - } } /* From 7bc9036d160c6235d96e1bed49331696d7fa9a09 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 10 May 2019 11:58:37 +0530 Subject: [PATCH 255/588] arch/cpu: Rename mp_get_apic_id() and add_cpu_map_entry() function This patch renames mp_get_apic_id() to cpu_get_apic_id() and add_cpu_map_entry() to cpu_add_map_entry() in order access it outside CONFIG_PARALLEL_MP kconfig scope. Also make below changes - Make cpu_add_map_entry() function available externally to call it from mp_init.c and lapic_cpu_init.c. BRANCH=none BUG=b:79562868 Change-Id: I6a6c85df055bc0b5fc8c850cfa04d50859067088 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32701 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/arch/x86/cpu.c | 29 +++++++++++++++++++++++++++++ src/cpu/x86/mp_init.c | 35 +++++++---------------------------- src/include/cpu/cpu.h | 4 ++++ src/include/cpu/x86/mp.h | 3 --- 4 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/arch/x86/cpu.c b/src/arch/x86/cpu.c index 80d4d0da4ad..f19b389441b 100644 --- a/src/arch/x86/cpu.c +++ b/src/arch/x86/cpu.c @@ -219,6 +219,35 @@ static void set_cpu_ops(struct device *cpu) cpu->ops = driver ? driver->ops : NULL; } +/* Keep track of default apic ids for SMM. */ +static int cpus_default_apic_id[CONFIG_MAX_CPUS]; + +/* + * When CPUID executes with EAX set to 1, additional processor identification + * information is returned to EBX register: + * Default APIC ID: EBX[31-24] - this number is the 8 bit ID that is assigned + * to the local APIC on the processor during power on. + */ +static int initial_lapicid(void) +{ + return cpuid_ebx(1) >> 24; +} + +/* Function to keep track of cpu default apic_id */ +void cpu_add_map_entry(unsigned int index) +{ + cpus_default_apic_id[index] = initial_lapicid(); +} + +/* Returns default APIC id based on logical_cpu number or < 0 on failure. */ +int cpu_get_apic_id(int logical_cpu) +{ + if (logical_cpu >= CONFIG_MAX_CPUS || logical_cpu < 0) + return -1; + + return cpus_default_apic_id[logical_cpu]; +} + void cpu_initialize(unsigned int index) { /* Because we busy wait at the printk spinlock. diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 9d51b3e8b56..8957515540c 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -135,20 +135,8 @@ struct mp_flight_plan { static int global_num_aps; static struct mp_flight_plan mp_info; -struct cpu_map { - struct device *dev; - /* Keep track of default apic ids for SMM. */ - int default_apic_id; -}; - -/* Keep track of APIC and device structure for each CPU. */ -static struct cpu_map cpus[CONFIG_MAX_CPUS]; - -static inline void add_cpu_map_entry(const struct cpu_info *info) -{ - cpus[info->index].dev = info->cpu; - cpus[info->index].default_apic_id = cpuid_ebx(1) >> 24; -} +/* Keep track of device structure for each CPU. */ +static struct device *cpus_dev[CONFIG_MAX_CPUS]; static inline void barrier_wait(atomic_t *b) { @@ -212,9 +200,9 @@ static void asmlinkage ap_init(unsigned int cpu) info = cpu_info(); info->index = cpu; - info->cpu = cpus[cpu].dev; + info->cpu = cpus_dev[cpu]; - add_cpu_map_entry(info); + cpu_add_map_entry(info->index); thread_init_cpu_info_non_bsp(info); /* Fix up APIC id with reality. */ @@ -411,7 +399,7 @@ static int allocate_cpu_devices(struct bus *cpu_bus, struct mp_params *p) continue; } new->name = processor_name; - cpus[i].dev = new; + cpus_dev[i] = new; } return max_cpus; @@ -589,7 +577,7 @@ static void init_bsp(struct bus *cpu_bus) printk(BIOS_CRIT, "BSP index(%d) != 0!\n", info->index); /* Track BSP in cpu_map structures. */ - add_cpu_map_entry(info); + cpu_add_map_entry(info->index); } /* @@ -667,15 +655,6 @@ static void mp_initialize_cpu(void) cpu_initialize(info->index); } -/* Returns APIC id for coreboot CPU number or < 0 on failure. */ -int mp_get_apic_id(int logical_cpu) -{ - if (logical_cpu >= CONFIG_MAX_CPUS || logical_cpu < 0) - return -1; - - return cpus[logical_cpu].default_apic_id; -} - void smm_initiate_relocation_parallel(void) { if ((lapic_read(LAPIC_ICR) & LAPIC_ICR_BUSY)) { @@ -769,7 +748,7 @@ static void adjust_smm_apic_id_map(struct smm_loader_params *smm_params) struct smm_runtime *runtime = smm_params->runtime; for (i = 0; i < CONFIG_MAX_CPUS; i++) - runtime->apic_id_to_cpu[i] = mp_get_apic_id(i); + runtime->apic_id_to_cpu[i] = cpu_get_apic_id(i); } static int install_relocation_handler(int num_cpus, size_t save_state_size) diff --git a/src/include/cpu/cpu.h b/src/include/cpu/cpu.h index 60940f07d11..9a283735d37 100644 --- a/src/include/cpu/cpu.h +++ b/src/include/cpu/cpu.h @@ -5,6 +5,10 @@ #if !defined(__ROMCC__) void cpu_initialize(unsigned int cpu_index); +/* Returns default APIC id based on logical_cpu number or < 0 on failure. */ +int cpu_get_apic_id(int logical_cpu); +/* Function to keep track of cpu default apic_id */ +void cpu_add_map_entry(unsigned int index); struct bus; void initialize_cpus(struct bus *cpu_bus); asmlinkage void secondary_cpu_init(unsigned int cpu_index); diff --git a/src/include/cpu/x86/mp.h b/src/include/cpu/x86/mp.h index 9789910b46f..c04252ec353 100644 --- a/src/include/cpu/x86/mp.h +++ b/src/include/cpu/x86/mp.h @@ -145,9 +145,6 @@ int mp_run_on_all_cpus(void (*func)(void *), void *arg, long expire_us); */ int mp_park_aps(void); -/* Returns APIC id for coreboot CPU number or < 0 on failure. */ -int mp_get_apic_id(int logical_cpu); - /* * SMM helpers to use with initializing CPUs. */ From 7e893a02c0cc04b8fdcfee0b4dc0ff790bfe40c5 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 6 May 2019 14:17:41 +0530 Subject: [PATCH 256/588] Kconfig: Create RAMPAYLOAD kconfig This patch enables coreboot flow to skip ramstage as individual stage to load payload. Instead it is expected to load payload from postcar stage. Change-Id: I839f2d34a93b69ca6bf3de6594e2ad9f66ee7135 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32618 Tested-by: build bot (Jenkins) Reviewed-by: ron minnich --- src/Kconfig | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/Kconfig b/src/Kconfig index b4898bd456f..2c9dc4ab7fb 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -277,6 +277,21 @@ config BOOTSPLASH_FILE The path and filename of the file to use as graphical bootsplash screen. The file format has to be jpg. +config RAMPAYLOAD + bool "Enable coreboot flow without executing ramstage" + default n + depends on ARCH_X86 + help + If this option is enabled, coreboot flow will skip ramstage + loading and execution of ramstage to load payload. + + Instead it is expected to load payload from postcar stage itself. + + In this flow coreboot will perform basic x86 initialization + (DRAM resource allocation), MTRR programming, + Skip PCI enumeration logic and only allocate BAR for fixed devices + (bootable devices, TPM over GSPI). + endmenu menu "Mainboard" From 2d7a52c784efb6be86bac5cb7aa1f8e1bd7088a6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 10 May 2019 17:51:31 +0530 Subject: [PATCH 257/588] lib/timestamp: Make timestamp_sync_cache_to_cbmem() in postcar This patch ensures to have correct timestamp value in postcar. Change-Id: I3ba3a54c20dfcdaf5b87818cc5da9a812f5f2edf Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32726 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/lib/timestamp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/timestamp.c b/src/lib/timestamp.c index b6330fa2585..431bce27033 100644 --- a/src/lib/timestamp.c +++ b/src/lib/timestamp.c @@ -350,6 +350,7 @@ uint32_t get_us_since_boot(void) } ROMSTAGE_CBMEM_INIT_HOOK(timestamp_sync_cache_to_cbmem) +POSTCAR_CBMEM_INIT_HOOK(timestamp_sync_cache_to_cbmem) RAMSTAGE_CBMEM_INIT_HOOK(timestamp_sync_cache_to_cbmem) /* Provide default timestamp implementation using monotonic timer. */ From 2be0b50be5783f173989a7882f3650d2a106f974 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 9 May 2019 13:43:49 +0200 Subject: [PATCH 258/588] boot_device: Constify argument Add const qualifier to first argument. Change-Id: I6655e04401b6a7aa5cafb717ff6f46b80b96646e Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32703 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- src/drivers/spi/boot_device_rw_nommap.c | 2 +- src/include/boot_device.h | 2 +- src/lib/boot_device.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drivers/spi/boot_device_rw_nommap.c b/src/drivers/spi/boot_device_rw_nommap.c index d01d778ca46..cc8fbf7c5d0 100644 --- a/src/drivers/spi/boot_device_rw_nommap.c +++ b/src/drivers/spi/boot_device_rw_nommap.c @@ -109,7 +109,7 @@ const struct spi_flash *boot_device_spi_flash(void) return car_get_var_ptr(&sfg); } -int boot_device_wp_region(struct region_device *rd, +int boot_device_wp_region(const struct region_device *rd, const enum bootdev_prot_type type) { uint32_t ctrlr_pr; diff --git a/src/include/boot_device.h b/src/include/boot_device.h index c882968e589..f392c101482 100644 --- a/src/include/boot_device.h +++ b/src/include/boot_device.h @@ -65,7 +65,7 @@ int boot_device_rw_subregion(const struct region *sub, * by the region device. * Returns 0 on success, < 0 on error. */ -int boot_device_wp_region(struct region_device *rd, +int boot_device_wp_region(const struct region_device *rd, const enum bootdev_prot_type type); /* diff --git a/src/lib/boot_device.c b/src/lib/boot_device.c index 429a6d8710e..e91a97f4616 100644 --- a/src/lib/boot_device.c +++ b/src/lib/boot_device.c @@ -20,7 +20,7 @@ void __weak boot_device_init(void) /* Provide weak do-nothing init. */ } -int __weak boot_device_wp_region(struct region_device *rd, +int __weak boot_device_wp_region(const struct region_device *rd, const enum bootdev_prot_type type) { /* return a failure, make aware WP is not implemented */ From f77eb44433c99a4b3fff5ec67300457a6a52498b Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Fri, 10 May 2019 15:38:29 +0200 Subject: [PATCH 259/588] mb/lenovo/*: Add MAINBOARD_FAMILY The Kconfig MAINBOARD_FAMILY sets the family field of SMBIOS entry 1. Match what vendor firmware does and use the same value as in the version field. Required for fwupd which uses the family field to generate a GUID. Change-Id: I0033c42c5eac6b9d47d0acd16c67467b6d419534 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32727 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Paul Menzel --- src/mainboard/lenovo/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig index a57b4625290..ea1ead13e0b 100644 --- a/src/mainboard/lenovo/Kconfig +++ b/src/mainboard/lenovo/Kconfig @@ -13,4 +13,8 @@ config MAINBOARD_VENDOR string default "LENOVO" +config MAINBOARD_FAMILY + string + default MAINBOARD_PART_NUMBER + endif # VENDOR_LENOVO From a029b3f4a409352c14dcb477b4291cada3275575 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 10 May 2019 16:22:40 +0200 Subject: [PATCH 260/588] 3rdparty/libhwbase: Update to current master Beside some refactorings that don't affect coreboot, this contains bd0ed91 (Makefile: Revise support for generated sources) that fixes an issue with upcoming libgfxinit configuration changes. Change-Id: Ib47aeff8f6426ae27ddbc235a954e3bd60029072 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32735 Reviewed-by: Paul Menzel Reviewed-by: Patrick Georgi Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- 3rdparty/libhwbase | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/libhwbase b/3rdparty/libhwbase index 637f2a4f21e..bd0ed91cb98 160000 --- a/3rdparty/libhwbase +++ b/3rdparty/libhwbase @@ -1 +1 @@ -Subproject commit 637f2a4f21ead8ccc45d5256834eb27ce72088db +Subproject commit bd0ed91cb985a697033edd9fd62d322aa017e791 From 47953d0ae066ad05a62e3dc5ae560e3a6796d035 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 10 May 2019 16:26:07 +0200 Subject: [PATCH 261/588] 3rdparty/libgfxinit: Update for runtime CPU detection Beside one tiny fix for framebuffer scaling, this contains a major refactoring of libgfxinit's configuration infrastructure. With this, we are finally able to detect CPUs at runtime and only have to confi- gure a CPU/GPU generation. Change-Id: Iccf4557453878536f527e4a1902439a1961ab701 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32736 Reviewed-by: Patrick Georgi Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- 3rdparty/libgfxinit | 2 +- src/drivers/intel/gma/Kconfig | 19 ++++++++----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/3rdparty/libgfxinit b/3rdparty/libgfxinit index f70eddafbc2..b3b9fa34bb9 160000 --- a/3rdparty/libgfxinit +++ b/3rdparty/libgfxinit @@ -1 +1 @@ -Subproject commit f70eddafbc2c6045a14e2f8bbb3273ee738fbaf7 +Subproject commit b3b9fa34bb99d33d0fc6a69c64966a71cebd5bd6 diff --git a/src/drivers/intel/gma/Kconfig b/src/drivers/intel/gma/Kconfig index 4f897fab13a..bf7e4b65fef 100644 --- a/src/drivers/intel/gma/Kconfig +++ b/src/drivers/intel/gma/Kconfig @@ -86,22 +86,19 @@ config GFX_GMA_INTERNAL_IS_LVDS if GFX_GMA -config GFX_GMA_CPU +config GFX_GMA_DYN_CPU + def_bool y + help + Activates runtime CPU detection in libgfxinit. + +config GFX_GMA_GENERATION string default "Broxton" if SOC_INTEL_APOLLOLAKE default "Skylake" if SOC_INTEL_SKYLAKE - default "Broadwell" if SOC_INTEL_BROADWELL - default "Haswell" if NORTHBRIDGE_INTEL_HASWELL - default "Ivybridge" if NORTHBRIDGE_INTEL_IVYBRIDGE - default "Sandybridge" if NORTHBRIDGE_INTEL_SANDYBRIDGE - default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM + default "Haswell" if NORTHBRIDGE_INTEL_HASWELL || SOC_INTEL_BROADWELL + default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE default "G45" if NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_X4X -config GFX_GMA_CPU_VARIANT - string - default "ULT" if (SOC_INTEL_SKYLAKE && !SKYLAKE_SOC_PCH_H) || SOC_INTEL_BROADWELL || NORTHBRIDGE_INTEL_HASWELL - default "Normal" - config GFX_GMA_INTERNAL_PORT string default "DP" if GFX_GMA_INTERNAL_IS_EDP From 772a154d39025e5f7f30102cca9f935e9b35cb1c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 10 May 2019 16:48:14 +0200 Subject: [PATCH 262/588] nb/intel/snb: Drop NORTHBRIDGE_INTEL_IVYBRIDGE We keep the support, though. Just now that `libgfxinit` is fixed, we don't need the distinction anymore. Causally, we also don't need CPU_INTEL_MODEL_306AX any more. TEST=Played tint on kontron/ktqm77. Score 606 Change-Id: Id1e33c77f44a66baacba375cbb2aeb71effb7b76 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32737 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/arch/x86/car.ld | 4 +--- src/cpu/intel/Makefile.inc | 1 - src/cpu/intel/model_206ax/Kconfig | 5 +---- src/drivers/intel/gma/Kconfig | 4 ++-- src/mainboard/asrock/b75pro3-m/Kconfig | 2 +- src/mainboard/asus/h61m-cs/Kconfig | 2 +- src/mainboard/asus/p8h61-m_pro/Kconfig | 2 +- src/mainboard/compulab/intense_pc/Kconfig | 2 +- src/mainboard/gigabyte/ga-b75m-d3h/Kconfig | 2 +- src/mainboard/gigabyte/ga-b75m-d3v/Kconfig | 2 +- src/mainboard/google/link/Kconfig | 2 +- src/mainboard/google/parrot/Kconfig | 2 +- src/mainboard/google/stout/Kconfig | 2 +- src/mainboard/hp/2570p/Kconfig | 2 +- src/mainboard/hp/8470p/Kconfig | 2 +- src/mainboard/hp/8770w/Kconfig | 2 +- src/mainboard/hp/folio_9470m/Kconfig | 2 +- src/mainboard/hp/revolve_810_g1/Kconfig | 2 +- src/mainboard/intel/emeraldlake2/Kconfig | 2 +- src/mainboard/kontron/ktqm77/Kconfig | 2 +- src/mainboard/lenovo/s230u/Kconfig | 2 +- src/mainboard/lenovo/t430/Kconfig | 2 +- src/mainboard/lenovo/t430s/Kconfig | 2 +- src/mainboard/lenovo/t530/Kconfig | 2 +- src/mainboard/lenovo/x1_carbon_gen1/Kconfig | 2 +- src/mainboard/lenovo/x230/Kconfig | 2 +- src/mainboard/roda/rv11/Kconfig | 2 +- src/mainboard/sapphire/pureplatinumh61/Kconfig | 2 +- src/northbridge/intel/sandybridge/Kconfig | 11 +---------- src/northbridge/intel/sandybridge/Makefile.inc | 2 +- src/southbridge/intel/common/firmware/Kconfig | 4 ++-- util/autoport/sandybridge.go | 11 +++++------ 32 files changed, 37 insertions(+), 53 deletions(-) diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld index 7b20a14f215..29b3600bbe7 100644 --- a/src/arch/x86/car.ld +++ b/src/arch/x86/car.ld @@ -91,9 +91,7 @@ _car_global_end = .; _car_relocatable_data_end = .; -#if (CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) || \ - CONFIG(NORTHBRIDGE_INTEL_IVYBRIDGE)) && \ - !CONFIG(USE_NATIVE_RAMINIT) +#if CONFIG(NORTHBRIDGE_INTEL_SANDYBRIDGE) && !CONFIG(USE_NATIVE_RAMINIT) . = ABSOLUTE(0xff7e1000); _mrc_pool = .; . += 0x5000; diff --git a/src/cpu/intel/Makefile.inc b/src/cpu/intel/Makefile.inc index 73a8bf8474d..3f897407cf4 100644 --- a/src/cpu/intel/Makefile.inc +++ b/src/cpu/intel/Makefile.inc @@ -12,7 +12,6 @@ subdirs-$(CONFIG_CPU_INTEL_SOCKET_P) += socket_p subdirs-$(CONFIG_CPU_INTEL_SOCKET_MPGA604) += socket_mPGA604 subdirs-$(CONFIG_NORTHBRIDGE_INTEL_NEHALEM) += model_2065x subdirs-$(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE) += model_206ax -subdirs-$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE) += model_206ax subdirs-$(CONFIG_NORTHBRIDGE_INTEL_HASWELL) += haswell subdirs-$(CONFIG_NORTHBRIDGE_INTEL_FSP_RANGELEY) += fsp_model_406dx subdirs-$(CONFIG_CPU_INTEL_SLOT_1) += slot_1 diff --git a/src/cpu/intel/model_206ax/Kconfig b/src/cpu/intel/model_206ax/Kconfig index f045e9aac51..dbb89821215 100644 --- a/src/cpu/intel/model_206ax/Kconfig +++ b/src/cpu/intel/model_206ax/Kconfig @@ -1,10 +1,7 @@ config CPU_INTEL_MODEL_206AX bool -config CPU_INTEL_MODEL_306AX - bool - -if CPU_INTEL_MODEL_206AX || CPU_INTEL_MODEL_306AX +if CPU_INTEL_MODEL_206AX config CPU_SPECIFIC_OPTIONS def_bool y diff --git a/src/drivers/intel/gma/Kconfig b/src/drivers/intel/gma/Kconfig index bf7e4b65fef..59a9e8aa5bc 100644 --- a/src/drivers/intel/gma/Kconfig +++ b/src/drivers/intel/gma/Kconfig @@ -67,7 +67,7 @@ config GFX_GMA def_bool y depends on NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_X4X \ || NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE \ - || NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_HASWELL \ + || NORTHBRIDGE_INTEL_HASWELL \ || SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || SOC_INTEL_APOLLOLAKE depends on MAINBOARD_USE_LIBGFXINIT select RAMSTAGE_LIBHWBASE @@ -96,7 +96,7 @@ config GFX_GMA_GENERATION default "Broxton" if SOC_INTEL_APOLLOLAKE default "Skylake" if SOC_INTEL_SKYLAKE default "Haswell" if NORTHBRIDGE_INTEL_HASWELL || SOC_INTEL_BROADWELL - default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE || NORTHBRIDGE_INTEL_IVYBRIDGE + default "Ironlake" if NORTHBRIDGE_INTEL_NEHALEM || NORTHBRIDGE_INTEL_SANDYBRIDGE default "G45" if NORTHBRIDGE_INTEL_GM45 || NORTHBRIDGE_INTEL_X4X config GFX_GMA_INTERNAL_PORT diff --git a/src/mainboard/asrock/b75pro3-m/Kconfig b/src/mainboard/asrock/b75pro3-m/Kconfig index 8db0eba7634..878eaad0980 100644 --- a/src/mainboard/asrock/b75pro3-m/Kconfig +++ b/src/mainboard/asrock/b75pro3-m/Kconfig @@ -22,7 +22,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select USE_NATIVE_RAMINIT diff --git a/src/mainboard/asus/h61m-cs/Kconfig b/src/mainboard/asus/h61m-cs/Kconfig index 60dafda5c76..69efa9da81b 100644 --- a/src/mainboard/asus/h61m-cs/Kconfig +++ b/src/mainboard/asus/h61m-cs/Kconfig @@ -6,7 +6,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_BD82X6X select USE_NATIVE_RAMINIT diff --git a/src/mainboard/asus/p8h61-m_pro/Kconfig b/src/mainboard/asus/p8h61-m_pro/Kconfig index 93da2cdf58e..14f841e649c 100644 --- a/src/mainboard/asus/p8h61-m_pro/Kconfig +++ b/src/mainboard/asus/p8h61-m_pro/Kconfig @@ -21,7 +21,7 @@ config BOARD_SPECIFIC_OPTIONS select BOARD_ROMSIZE_KB_4096 select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_BD82X6X select USE_NATIVE_RAMINIT diff --git a/src/mainboard/compulab/intense_pc/Kconfig b/src/mainboard/compulab/intense_pc/Kconfig index ff697b922f0..3326b74bf68 100644 --- a/src/mainboard/compulab/intense_pc/Kconfig +++ b/src/mainboard/compulab/intense_pc/Kconfig @@ -7,7 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig index 659f47c5b01..6869bdb3f0d 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig +++ b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig @@ -3,7 +3,7 @@ if BOARD_GIGABYTE_GA_B75M_D3H config BOARD_SPECIFIC_OPTIONS def_bool y select ARCH_X86 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select SUPERIO_ITE_IT8728F diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig index e01d4847ef2..4048f98615a 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig +++ b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig @@ -3,7 +3,7 @@ if BOARD_GIGABYTE_GA_B75M_D3V config BOARD_SPECIFIC_OPTIONS def_bool y select ARCH_X86 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select SUPERIO_ITE_IT8728F diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index fea82f67564..612a1b59871 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -3,7 +3,7 @@ if BOARD_GOOGLE_LINK config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select BOARD_ROMSIZE_KB_8192 select EC_GOOGLE_CHROMEEC diff --git a/src/mainboard/google/parrot/Kconfig b/src/mainboard/google/parrot/Kconfig index 1a31da7b55e..4403d792f76 100644 --- a/src/mainboard/google/parrot/Kconfig +++ b/src/mainboard/google/parrot/Kconfig @@ -3,7 +3,7 @@ if BOARD_GOOGLE_PARROT config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select EC_COMPAL_ENE932 select BOARD_ROMSIZE_KB_8192 diff --git a/src/mainboard/google/stout/Kconfig b/src/mainboard/google/stout/Kconfig index 8b3eb0f0301..7096d937c7e 100644 --- a/src/mainboard/google/stout/Kconfig +++ b/src/mainboard/google/stout/Kconfig @@ -3,7 +3,7 @@ if BOARD_GOOGLE_STOUT config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select EC_QUANTA_IT8518 select BOARD_ROMSIZE_KB_8192 diff --git a/src/mainboard/hp/2570p/Kconfig b/src/mainboard/hp/2570p/Kconfig index ff91e4dafe2..5e33aac2c2b 100644 --- a/src/mainboard/hp/2570p/Kconfig +++ b/src/mainboard/hp/2570p/Kconfig @@ -21,7 +21,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/hp/8470p/Kconfig b/src/mainboard/hp/8470p/Kconfig index f23c02faf37..5b30208b64a 100644 --- a/src/mainboard/hp/8470p/Kconfig +++ b/src/mainboard/hp/8470p/Kconfig @@ -21,7 +21,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/hp/8770w/Kconfig b/src/mainboard/hp/8770w/Kconfig index 6752085574c..41e2ed3c6b5 100644 --- a/src/mainboard/hp/8770w/Kconfig +++ b/src/mainboard/hp/8770w/Kconfig @@ -22,7 +22,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/hp/folio_9470m/Kconfig b/src/mainboard/hp/folio_9470m/Kconfig index 06ca7935736..d9bb68e7e11 100644 --- a/src/mainboard/hp/folio_9470m/Kconfig +++ b/src/mainboard/hp/folio_9470m/Kconfig @@ -7,7 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/hp/revolve_810_g1/Kconfig b/src/mainboard/hp/revolve_810_g1/Kconfig index 475e9783eb5..ce7364ce5e8 100644 --- a/src/mainboard/hp/revolve_810_g1/Kconfig +++ b/src/mainboard/hp/revolve_810_g1/Kconfig @@ -7,7 +7,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_ACPI_RESUME select HAVE_ACPI_TABLES select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/intel/emeraldlake2/Kconfig b/src/mainboard/intel/emeraldlake2/Kconfig index eeb441ce68c..61dd1b0f3d9 100644 --- a/src/mainboard/intel/emeraldlake2/Kconfig +++ b/src/mainboard/intel/emeraldlake2/Kconfig @@ -2,7 +2,7 @@ if BOARD_INTEL_EMERALDLAKE2 config BOARD_SPECIFIC_OPTIONS def_bool y - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select SUPERIO_SMSC_SIO1007 select BOARD_ROMSIZE_KB_8192 diff --git a/src/mainboard/kontron/ktqm77/Kconfig b/src/mainboard/kontron/ktqm77/Kconfig index 043eb019ddc..c215bdf65bb 100644 --- a/src/mainboard/kontron/ktqm77/Kconfig +++ b/src/mainboard/kontron/ktqm77/Kconfig @@ -2,7 +2,7 @@ if BOARD_KONTRON_KTQM77 config BOARD_SPECIFIC_OPTIONS def_bool y - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select SUPERIO_WINBOND_W83627DHG select EC_KONTRON_IT8516E diff --git a/src/mainboard/lenovo/s230u/Kconfig b/src/mainboard/lenovo/s230u/Kconfig index 9200ad5ed91..c7faebb4291 100644 --- a/src/mainboard/lenovo/s230u/Kconfig +++ b/src/mainboard/lenovo/s230u/Kconfig @@ -3,7 +3,7 @@ if BOARD_LENOVO_S230U config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select EC_COMPAL_ENE932 diff --git a/src/mainboard/lenovo/t430/Kconfig b/src/mainboard/lenovo/t430/Kconfig index dbeaadb0c47..7137b5eb730 100644 --- a/src/mainboard/lenovo/t430/Kconfig +++ b/src/mainboard/lenovo/t430/Kconfig @@ -15,7 +15,7 @@ config BOARD_SPECIFIC_OPTIONS select MAINBOARD_HAS_LPC_TPM select MAINBOARD_HAS_TPM1 select INTEL_INT15 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SERIRQ_CONTINUOUS_MODE select SOUTHBRIDGE_INTEL_C216 select SYSTEM_TYPE_LAPTOP diff --git a/src/mainboard/lenovo/t430s/Kconfig b/src/mainboard/lenovo/t430s/Kconfig index bad1837546c..b0a22aafbf8 100644 --- a/src/mainboard/lenovo/t430s/Kconfig +++ b/src/mainboard/lenovo/t430s/Kconfig @@ -3,7 +3,7 @@ if BOARD_LENOVO_T430S || BOARD_LENOVO_T431S config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select EC_LENOVO_PMH7 diff --git a/src/mainboard/lenovo/t530/Kconfig b/src/mainboard/lenovo/t530/Kconfig index b36460d55fd..5b5b7ffa49b 100644 --- a/src/mainboard/lenovo/t530/Kconfig +++ b/src/mainboard/lenovo/t530/Kconfig @@ -1,7 +1,7 @@ config BOARD_LENOVO_BASEBOARD_T530 def_bool n select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select EC_LENOVO_PMH7 diff --git a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig index 520853c800c..a15cadf202c 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/Kconfig +++ b/src/mainboard/lenovo/x1_carbon_gen1/Kconfig @@ -3,7 +3,7 @@ if BOARD_LENOVO_X1_CARBON_GEN1 config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select EC_LENOVO_PMH7 diff --git a/src/mainboard/lenovo/x230/Kconfig b/src/mainboard/lenovo/x230/Kconfig index 5b34b83bcd5..a043efcd70e 100644 --- a/src/mainboard/lenovo/x230/Kconfig +++ b/src/mainboard/lenovo/x230/Kconfig @@ -3,7 +3,7 @@ if BOARD_LENOVO_X230 config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_C216 select EC_LENOVO_PMH7 diff --git a/src/mainboard/roda/rv11/Kconfig b/src/mainboard/roda/rv11/Kconfig index 01fc253eacd..54f04c406ec 100644 --- a/src/mainboard/roda/rv11/Kconfig +++ b/src/mainboard/roda/rv11/Kconfig @@ -3,7 +3,7 @@ if BOARD_RODA_RV11 || BOARD_RODA_RW11 config BOARD_SPECIFIC_OPTIONS def_bool y select SYSTEM_TYPE_LAPTOP - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select SOUTHBRIDGE_INTEL_C216 select BOARD_ROMSIZE_KB_16384 select HAVE_ACPI_TABLES diff --git a/src/mainboard/sapphire/pureplatinumh61/Kconfig b/src/mainboard/sapphire/pureplatinumh61/Kconfig index 13a93c5c27c..6d27b3f1bd2 100644 --- a/src/mainboard/sapphire/pureplatinumh61/Kconfig +++ b/src/mainboard/sapphire/pureplatinumh61/Kconfig @@ -3,7 +3,7 @@ if BOARD_SAPPHIRE_PUREPLATINUMH61 config BOARD_SPECIFIC_OPTIONS def_bool y select ARCH_X86 - select NORTHBRIDGE_INTEL_IVYBRIDGE + select NORTHBRIDGE_INTEL_SANDYBRIDGE select USE_NATIVE_RAMINIT select SOUTHBRIDGE_INTEL_BD82X6X select SUPERIO_FINTEK_F71808A diff --git a/src/northbridge/intel/sandybridge/Kconfig b/src/northbridge/intel/sandybridge/Kconfig index b3827c0d4c4..4f9da000a4e 100644 --- a/src/northbridge/intel/sandybridge/Kconfig +++ b/src/northbridge/intel/sandybridge/Kconfig @@ -23,16 +23,7 @@ config NORTHBRIDGE_INTEL_SANDYBRIDGE select POSTCAR_STAGE select POSTCAR_CONSOLE -config NORTHBRIDGE_INTEL_IVYBRIDGE - bool - select CACHE_MRC_SETTINGS - select CPU_INTEL_MODEL_306AX - select HAVE_DEBUG_RAM_SETUP - select INTEL_GMA_ACPI - select POSTCAR_STAGE - select POSTCAR_CONSOLE - -if NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_SANDYBRIDGE +if NORTHBRIDGE_INTEL_SANDYBRIDGE config VBOOT select VBOOT_STARTS_IN_ROMSTAGE diff --git a/src/northbridge/intel/sandybridge/Makefile.inc b/src/northbridge/intel/sandybridge/Makefile.inc index ecab18a818b..cc4ddaf8611 100644 --- a/src/northbridge/intel/sandybridge/Makefile.inc +++ b/src/northbridge/intel/sandybridge/Makefile.inc @@ -13,7 +13,7 @@ # GNU General Public License for more details. # -ifeq ($(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE)$(CONFIG_NORTHBRIDGE_INTEL_IVYBRIDGE),y) +ifeq ($(CONFIG_NORTHBRIDGE_INTEL_SANDYBRIDGE),y) ramstage-y += ram_calc.c ramstage-y += northbridge.c diff --git a/src/southbridge/intel/common/firmware/Kconfig b/src/southbridge/intel/common/firmware/Kconfig index c0dd43984de..eb63d345208 100644 --- a/src/southbridge/intel/common/firmware/Kconfig +++ b/src/southbridge/intel/common/firmware/Kconfig @@ -61,7 +61,7 @@ config CHECK_ME default n depends on HAVE_ME_BIN && (NORTHBRIDGE_INTEL_NEHALEM || \ NORTHBRIDGE_INTEL_SANDYBRIDGE || \ - NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_HASWELL || \ + NORTHBRIDGE_INTEL_HASWELL || \ SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || \ SOC_INTEL_KABYLAKE || SOC_INTEL_BAYTRAIL || SOC_INTEL_BRASWELL) help @@ -73,7 +73,7 @@ config USE_ME_CLEANER bool "Strip down the Intel ME/TXE firmware" depends on HAVE_ME_BIN && (NORTHBRIDGE_INTEL_NEHALEM || \ NORTHBRIDGE_INTEL_SANDYBRIDGE || \ - NORTHBRIDGE_INTEL_IVYBRIDGE || NORTHBRIDGE_INTEL_HASWELL || \ + NORTHBRIDGE_INTEL_HASWELL || \ SOC_INTEL_BROADWELL || SOC_INTEL_SKYLAKE || \ SOC_INTEL_KABYLAKE || SOC_INTEL_BAYTRAIL || SOC_INTEL_BRASWELL) help diff --git a/util/autoport/sandybridge.go b/util/autoport/sandybridge.go index 997259815bb..170d197af4d 100644 --- a/util/autoport/sandybridge.go +++ b/util/autoport/sandybridge.go @@ -1,7 +1,6 @@ package main type sandybridgemc struct { - variant string } func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) { @@ -106,7 +105,7 @@ func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) { PutPCIDev(addr, "Host bridge") /* FIXME:XX some configs are unsupported. */ - KconfigBool["NORTHBRIDGE_INTEL_"+i.variant+"BRIDGE"] = true + KconfigBool["NORTHBRIDGE_INTEL_SANDYBRIDGE"] = true KconfigBool["USE_NATIVE_RAMINIT"] = true KconfigBool["INTEL_INT15"] = true KconfigBool["HAVE_ACPI_TABLES"] = true @@ -126,10 +125,10 @@ func (i sandybridgemc) Scan(ctx Context, addr PCIDevData) { } func init() { - RegisterPCI(0x8086, 0x0100, sandybridgemc{variant: "SANDY"}) - RegisterPCI(0x8086, 0x0104, sandybridgemc{variant: "SANDY"}) - RegisterPCI(0x8086, 0x0150, sandybridgemc{variant: "IVY"}) - RegisterPCI(0x8086, 0x0154, sandybridgemc{variant: "IVY"}) + RegisterPCI(0x8086, 0x0100, sandybridgemc{}) + RegisterPCI(0x8086, 0x0104, sandybridgemc{}) + RegisterPCI(0x8086, 0x0150, sandybridgemc{}) + RegisterPCI(0x8086, 0x0154, sandybridgemc{}) for _, id := range []uint16{ 0x0102, 0x0106, 0x010a, 0x0112, 0x0116, 0x0122, 0x0126, From a6d401c193c9bb53162df9523f9ba4ebb2a6f1a7 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Mon, 18 Feb 2019 17:20:18 +0100 Subject: [PATCH 263/588] mb/asrock/h81m-hds: Drop now obsolete libgfxinit override CPU type is detected at runtime now. Change-Id: I5e54176e235e43ca28e4baf43dbb9860e7fc3dbd Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/31465 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Tristan Corrick --- src/mainboard/asrock/h81m-hds/Kconfig | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/mainboard/asrock/h81m-hds/Kconfig b/src/mainboard/asrock/h81m-hds/Kconfig index db2768d324b..928a01042e8 100644 --- a/src/mainboard/asrock/h81m-hds/Kconfig +++ b/src/mainboard/asrock/h81m-hds/Kconfig @@ -40,14 +40,6 @@ config CBFS_SIZE hex default 0x200000 -# -# The override of GFX_GMA_CPU_VARIANT should be removed once the patches -# for dynamic CPU detection are merged in libgfxinit. -# -config GFX_GMA_CPU_VARIANT - string - default "Normal" - config MAINBOARD_DIR string default asrock/h81m-hds From 095c931cf12924da9011b47aa64f4a6f11d89f13 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 6 May 2019 19:51:34 +0530 Subject: [PATCH 264/588] src/arch/x86: Use core apic id to get cpu_index() This cpu_index() implementation assumes that cpu_index() function might always getting called from coreboot context (ESP stack pointer will always refer to coreboot). This might not be true in case of proposed PI spec MP_SERVICES_PPI implementation, where FSP context (stack pointer refers to fsp) will request to get cpu_index(), natural alignment logic will use ESP and retrieve struct cpu_info *ci from (stack_top - 8 byte). This is not the place where cpu_index is actually stored by ramstage c_start.S Hence this patch tries to remove those dependencies while retrieving cpu_index(), rather it uses cpuid to fetch lapic id and matches with cpus_default_apic_id[] variable to return correct cpu_index(). BRANCH=none BUG=b:79562868 TEST=Ensures functions can be run on APs without any failure and cpu_index() also provides correct index number. Change-Id: I55023a3e0cf42f0496d45bc6af8ead447f402350 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/26346 Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/arch/x86/cpu.c | 24 ++++++++++++++++++++++++ src/arch/x86/include/arch/cpu.h | 21 ++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/arch/x86/cpu.c b/src/arch/x86/cpu.c index f19b389441b..fb4c7b6cfec 100644 --- a/src/arch/x86/cpu.c +++ b/src/arch/x86/cpu.c @@ -337,3 +337,27 @@ void arch_bootstate_coreboot_exit(void) /* APs are waiting for work. Last thing to do is park them. */ mp_park_aps(); } + +/* + * Previously cpu_index() implementation assumes that cpu_index() + * function will always getting called from coreboot context + * (ESP stack pointer will always refer to coreboot). + * + * But with FSP_USES_MP_SERVICES_PPI implementation in coreboot this + * assumption might not be true, where FSP context (stack pointer refers + * to FSP) will request to get cpu_index(). + * + * Hence new logic to use cpuid to fetch lapic id and matches with + * cpus_default_apic_id[] variable to return correct cpu_index(). + */ +unsigned long cpu_index(void) +{ + int i; + int lapic_id = initial_lapicid(); + + for (i = 0; i < CONFIG_MAX_CPUS; i++) { + if (cpu_get_apic_id(i) == lapic_id) + return i; + } + return -1; +} diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 61b17a6d2a9..481ee9d8e01 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -261,13 +261,6 @@ static inline struct cpu_info *cpu_info(void) ); return ci; } - -static inline unsigned long cpu_index(void) -{ - struct cpu_info *ci; - ci = cpu_info(); - return ci->index; -} #endif #ifndef __ROMCC__ // romcc is segfaulting in some cases @@ -374,4 +367,18 @@ uint32_t cpu_get_feature_flags_ecx(void); */ uint32_t cpu_get_feature_flags_edx(void); +/* + * Previously cpu_index() implementation assumes that cpu_index() + * function will always getting called from coreboot context + * (ESP stack pointer will always refer to coreboot). + * + * But with FSP_USES_MP_SERVICES_PPI implementation in coreboot this + * assumption might not be true, where FSP context (stack pointer refers + * to FSP) will request to get cpu_index(). + * + * Hence new logic to use cpuid to fetch lapic id and matches with + * cpus_default_apic_id[] variable to return correct cpu_index(). + */ +unsigned long cpu_index(void); + #endif /* ARCH_CPU_H */ From e091d0efc40581ce789fdef5f44a327b75adc999 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 10 May 2019 12:35:42 +0530 Subject: [PATCH 265/588] lapic/lapic_cpu_init: Add cpu_add_map_entry() to store default_apic_id This patch ensures start_cpu() function to store default_apic_id using common cpu_add_map_entry() function to make cpu_index() implementation generic. BRANCH=none BUG=b:79562868 Change-Id: Iac4d6e9e6e6f9ba644335b4b70da8689c405f638 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32722 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/cpu/x86/lapic/lapic_cpu_init.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index 3ad1f0a0557..0f73e71331e 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -291,6 +291,7 @@ int start_cpu(struct device *cpu) info = (struct cpu_info *)stack_top; info->index = index; info->cpu = cpu; + cpu_add_map_entry(info->index); thread_init_cpu_info_non_bsp(info); /* Advertise the new stack and index to start_cpu */ @@ -549,6 +550,7 @@ void initialize_cpus(struct bus *cpu_bus) /* Find the device structure for the boot CPU */ info->cpu = alloc_find_dev(cpu_bus, &cpu_path); + cpu_add_map_entry(info->index); // why here? In case some day we can start core1 in amd_sibling_init if (is_smp_boot()) From 9bb0461fbd8cdcceabde0ec266a5207bc40ea9a7 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 8 May 2019 13:40:45 -0600 Subject: [PATCH 266/588] util/ifdtool: Add find_fd null check As the previous comment indicated, this null check is currently superfluous, but adding it in makes Coverity happy, and future-proofs the code in case someone changes the internals of 'find_fcba' later and forgets/doesn't know to update this error check. Found-by: Coverity Scan #1395066 Signed-off-by: Jacob Garber Change-Id: I594cd0098f5b36cef5b3efc4c904710d3ba9b815 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32691 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/ifdtool/ifdtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index a97f352bdf2..6c5e7845691 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -236,7 +236,7 @@ static int get_ifd_version_from_fcba(char *image, int size) int read_freq; const fcba_t *fcba = find_fcba(image, size); const fdbar_t *fdb = find_fd(image, size); - if (!fcba) /* a valid fcba indicates a valid fdb */ + if (!fcba || !fdb) exit(EXIT_FAILURE); chipset = guess_ich_chipset(fdb); From 2be617b58b500214d45c338eda88237730524cac Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 7 May 2019 19:49:37 -0600 Subject: [PATCH 267/588] util/intelvbttool: Free file object on error path Prevents a memory leak. Found-by: Coverity Scan #1396047 Signed-off-by: Jacob Garber Change-Id: I4c72a17351d8afbe23302edfeeba74b17608aef2 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32685 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/intelvbttool/intelvbttool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/util/intelvbttool/intelvbttool.c b/util/intelvbttool/intelvbttool.c index f8e4bda0f4c..715b39ad571 100644 --- a/util/intelvbttool/intelvbttool.c +++ b/util/intelvbttool/intelvbttool.c @@ -1028,8 +1028,10 @@ static int patch_vbios(struct fileobject *fo, if (old_vbt) { if (oh->vbt_offset + vbt_size(old_vbt) == fo->size) { /* Located at the end of file - reduce file size */ - if (fo->size < vbt_size(old_vbt)) + if (fo->size < vbt_size(old_vbt)) { + free_fo(old_vbt); return 1; + } fo = remalloc_fo(fo, fo->size - vbt_size(old_vbt)); if (!fo) { printerr("Failed to allocate memory\n"); From 4fbd22e38d42faf7654cf9ded1f4001652e7fd37 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 8 May 2019 16:28:27 -0600 Subject: [PATCH 268/588] util/intelvbttool: Add error checking for memory allocation It is possible that 'malloc_fo_sub' and 'remalloc_fo' can fail, so add appropriate error checks for those cases. This incidentally fixes a possible memory leak when 'malloc_fo_sub' succeeds but 'remalloc_fo' does not. Found-by: Coverity Scan #1396050 Signed-off-by: Jacob Garber Change-Id: I944b67f5cdcfd7a687e81d8bb01a209c9dc9b0b8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32696 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/intelvbttool/intelvbttool.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/util/intelvbttool/intelvbttool.c b/util/intelvbttool/intelvbttool.c index 715b39ad571..2dfa0023f20 100644 --- a/util/intelvbttool/intelvbttool.c +++ b/util/intelvbttool/intelvbttool.c @@ -788,7 +788,20 @@ static void parse_vbt(const struct fileobject *fo, } /* Duplicate fo as caller is owner and remalloc frees the object */ - *vbt = remalloc_fo(malloc_fo_sub(fo, 0), head->vbt_size); + struct fileobject *dupfo = malloc_fo_sub(fo, 0); + if (!dupfo) { + printerr("malloc failed\n"); + return; + } + + struct fileobject *newfo = remalloc_fo(dupfo, head->vbt_size); + if (!newfo) { + printerr("remalloc failed\n"); + free_fo(dupfo); + return; + } + + *vbt = newfo; } /* Option ROM checksum */ From 9c90609331b33292c7aeacc944cd97fe5a2da056 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Fri, 10 May 2019 15:00:46 +0200 Subject: [PATCH 269/588] soc/intel/braswell: Add tsc_freq.c and pmutil.c in verstage Systems with C_EVIRONMENT_BOOTBLOCK and VBOOT enabled requires functions tsc_freq_mhz(), vbnv_cmos_failed() and vboot_platform_is_resuming() in verstage. Add tsc_freq.c and pmutil.c to verstage. BUG=NA TEST=Booting Embedded Linux on Facebook FBG-1701 + Building Google Banon Change-Id: Ia509eda6bf415aaa63be71013249493aa472289d Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32733 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/intel/braswell/Makefile.inc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index 4e90edf15cc..e2b1fe5295c 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -53,6 +53,9 @@ smm-y += smihandler.c smm-y += spi.c smm-y += tsc_freq.c +verstage-y += pmutil.c +verstage-y += tsc_freq.c + CPPFLAGS_common += -I$(src)/soc/intel/braswell/ CPPFLAGS_common += -I$(src)/soc/intel/braswell/include CPPFLAGS_common += -I$(call strip_quotes,$(CONFIG_FSP_HEADER_PATH)) From 9d6f6459080e6ca1f82fabd7e05ada506c58204d Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 9 May 2019 21:04:52 +0200 Subject: [PATCH 270/588] mainboard: Remove unused include Change-Id: Id05fc39c0c0d0560e34e55f793060d29df82d026 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32676 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks Reviewed-by: Sumeet R Pawnikar --- src/mainboard/google/cheza/mainboard.c | 1 - src/mainboard/google/mistral/bootblock.c | 1 - src/mainboard/google/mistral/mainboard.c | 1 - 3 files changed, 3 deletions(-) diff --git a/src/mainboard/google/cheza/mainboard.c b/src/mainboard/google/cheza/mainboard.c index 42adf56c795..7a19d32e9c6 100644 --- a/src/mainboard/google/cheza/mainboard.c +++ b/src/mainboard/google/cheza/mainboard.c @@ -16,7 +16,6 @@ #include #include #include -#include #include static struct usb_board_data usb1_board_data = { diff --git a/src/mainboard/google/mistral/bootblock.c b/src/mainboard/google/mistral/bootblock.c index 6718d521561..4ef8fec6c34 100644 --- a/src/mainboard/google/mistral/bootblock.c +++ b/src/mainboard/google/mistral/bootblock.c @@ -14,7 +14,6 @@ */ #include -#include void bootblock_mainboard_init(void) { diff --git a/src/mainboard/google/mistral/mainboard.c b/src/mainboard/google/mistral/mainboard.c index 1d62adba5c7..d50758c9e3d 100644 --- a/src/mainboard/google/mistral/mainboard.c +++ b/src/mainboard/google/mistral/mainboard.c @@ -15,7 +15,6 @@ #include #include -#include #include #include From cb6f6a10b3223dce446a1ce8e01cba0357b55b91 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 9 May 2019 21:06:19 +0200 Subject: [PATCH 271/588] soc/intel/braswell: Remove unused include Change-Id: Ied645a583f78bc47c8358240acd639132fd499db Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32711 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks Reviewed-by: Sumeet R Pawnikar --- src/soc/intel/braswell/romstage/romstage.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c index 342b05cf508..22b0df2a8b0 100644 --- a/src/soc/intel/braswell/romstage/romstage.c +++ b/src/soc/intel/braswell/romstage/romstage.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include From 554e55b0f07e7913afad6b374e30661df9db617a Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 8 May 2019 09:32:00 -0600 Subject: [PATCH 272/588] util/kconfig: Use snprintf to avoid buffer overflow 'name' and 'env' are supposed to be file system paths, but could overflow the buffer if configured incorrectly. Let's avoid that entirely. Found-by: Coverity Scan #1362515 Signed-off-by: Jacob Garber Change-Id: I1aef36819d49ebcbde1c51995dc0961c85e74150 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32686 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- util/kconfig/zconf.l | 3 ++- util/kconfig/zconf.lex.c_shipped | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/util/kconfig/zconf.l b/util/kconfig/zconf.l index 0b45c19db9e..f2636d2955d 100644 --- a/util/kconfig/zconf.l +++ b/util/kconfig/zconf.l @@ -273,7 +273,8 @@ FILE *zconf_fopen(const char *name) if (!f && name != NULL && name[0] != '/') { env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), + "%s/%s", env, name); f = fopen(fullname, "r"); } } diff --git a/util/kconfig/zconf.lex.c_shipped b/util/kconfig/zconf.lex.c_shipped index 72e3a5fca28..4133f71dd26 100644 --- a/util/kconfig/zconf.lex.c_shipped +++ b/util/kconfig/zconf.lex.c_shipped @@ -2351,7 +2351,8 @@ FILE *zconf_fopen(const char *name) if (!f && name != NULL && name[0] != '/') { env = getenv(SRCTREE); if (env) { - sprintf(fullname, "%s/%s", env, name); + snprintf(fullname, sizeof(fullname), + "%s/%s", env, name); f = fopen(fullname, "r"); } } From ac6bf7dc1259ae09dfbd123dc6dee1400b26c801 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 10 May 2019 19:17:31 +0200 Subject: [PATCH 273/588] lib/hexdump: Drop redundant isprint() implementation Change-Id: I23e2d89274553cbc75e42f0420a1a84d4cec4340 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32739 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/lib/hexdump.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/lib/hexdump.c b/src/lib/hexdump.c index 2861d6321e9..ca36ddee0e2 100644 --- a/src/lib/hexdump.c +++ b/src/lib/hexdump.c @@ -14,11 +14,7 @@ #include #include - -static int isprint(int c) -{ - return (c >= 32 && c <= 126); -} +#include void hexdump(const void *memory, size_t length) { From f2d173a554b82b731fceeecd00095f6c6433c7ba Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Fri, 10 May 2019 09:12:02 -0600 Subject: [PATCH 274/588] mb/google/sarien: config ISH_GP6 with NF2 A12 is not current set for ISH_GP6 so the ISH_LID_CL#_TAB signal is not making it to the ISH properly. Enable the second native function instead of the first. BRANCH=none BUG=b:131785573 TEST=gpioget on ISH now shows the correct gpio level Change-Id: Ib3a654ae659037263aa9aa29d45b42ca67b7955b Signed-off-by: Jett Rink Reviewed-on: https://review.coreboot.org/c/coreboot/+/32738 Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/variants/arcada/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/sarien/variants/arcada/gpio.c b/src/mainboard/google/sarien/variants/arcada/gpio.c index da954976573..ea0601b55ec 100644 --- a/src/mainboard/google/sarien/variants/arcada/gpio.c +++ b/src/mainboard/google/sarien/variants/arcada/gpio.c @@ -31,7 +31,7 @@ static const struct pad_config gpio_table[] = { /* CLKOUT_LPC1 */ PAD_NC(GPP_A10, NONE), /* PME# */ PAD_NC(GPP_A11, NONE), /* ISH_LID_CL#_TAB */ -/* BM_BUSY# */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF1), +/* ISH_GP6 */ PAD_CFG_NF(GPP_A12, NONE, DEEP, NF2), /* SUSWARN# */ PAD_NC(GPP_A13, NONE), /* ESPI_RESET# */ /* SUSACK# */ PAD_NC(GPP_A15, NONE), From a20e59da157231f0a0e41774af80f6bccde1b280 Mon Sep 17 00:00:00 2001 From: Matt Delco Date: Mon, 22 Apr 2019 13:38:13 -0700 Subject: [PATCH 275/588] libpayload: classify all keyboards Depthcharge uses the keyboard type to help determine whether it can trust the keyboard for security-sensitive confirmations. Currently it trusts anything except usb, but now there's a need to distrust ec-based ps/2 keyboards that are associated with untrusted ECs. To help facilitate this, coreboot needs to report more details about non-usb keyboards, so this change replaces the current instances of unknown with enum values that distinguish uart and gpio from ec-based keyboards. BUG=b:129471321 BRANCH=None TEST=Local compile and flash to systems with trusted and non-trusted ECs. Confirmed that security confirmation can't be performed via keyboard on a system with an untrusted EC but can still be performed on a system with a trusted EC. Change-Id: Iee6295dafadf7cb3da98b62f43b0e184b2b69b1e Signed-off-by: Matt Delco Reviewed-on: https://review.coreboot.org/c/coreboot/+/32717 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- payloads/libpayload/drivers/i8042/keyboard.c | 3 ++- payloads/libpayload/drivers/serial/8250.c | 3 ++- payloads/libpayload/drivers/serial/ipq40xx.c | 1 + payloads/libpayload/drivers/serial/ipq806x.c | 1 + payloads/libpayload/drivers/serial/s5p.c | 3 ++- payloads/libpayload/include/libpayload.h | 3 +++ 6 files changed, 11 insertions(+), 3 deletions(-) diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index 1035bf2791a..42431c36891 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -296,7 +296,8 @@ int keyboard_set_layout(char *country) static struct console_input_driver cons = { .havekey = keyboard_havechar, - .getchar = keyboard_getchar + .getchar = keyboard_getchar, + .input_type = CONSOLE_INPUT_TYPE_EC, }; void keyboard_init(void) diff --git a/payloads/libpayload/drivers/serial/8250.c b/payloads/libpayload/drivers/serial/8250.c index f503bdb1245..9502d4b147e 100644 --- a/payloads/libpayload/drivers/serial/8250.c +++ b/payloads/libpayload/drivers/serial/8250.c @@ -98,7 +98,8 @@ static void serial_hardware_init(int speed, int word_bits, static struct console_input_driver consin = { .havekey = &serial_havechar, - .getchar = &serial_getchar + .getchar = &serial_getchar, + .input_type = CONSOLE_INPUT_TYPE_UART, }; static struct console_output_driver consout = { diff --git a/payloads/libpayload/drivers/serial/ipq40xx.c b/payloads/libpayload/drivers/serial/ipq40xx.c index 52d71b8ac8a..7656ad73e0b 100644 --- a/payloads/libpayload/drivers/serial/ipq40xx.c +++ b/payloads/libpayload/drivers/serial/ipq40xx.c @@ -560,6 +560,7 @@ void serial_console_init(void) consin.havekey = serial_havechar; consin.getchar = serial_getchar; + consin.input_type = CONSOLE_INPUT_TYPE_UART; consout.putchar = serial_putchar; diff --git a/payloads/libpayload/drivers/serial/ipq806x.c b/payloads/libpayload/drivers/serial/ipq806x.c index 912893d7e23..183ada6563f 100644 --- a/payloads/libpayload/drivers/serial/ipq806x.c +++ b/payloads/libpayload/drivers/serial/ipq806x.c @@ -352,6 +352,7 @@ void serial_console_init(void) consin.havekey = serial_havechar; consin.getchar = serial_getchar; + consin.input_type = CONSOLE_INPUT_TYPE_UART; consout.putchar = serial_putchar; diff --git a/payloads/libpayload/drivers/serial/s5p.c b/payloads/libpayload/drivers/serial/s5p.c index 1d23352ec49..6ca5dc4717f 100644 --- a/payloads/libpayload/drivers/serial/s5p.c +++ b/payloads/libpayload/drivers/serial/s5p.c @@ -84,7 +84,8 @@ static struct console_output_driver s5p_serial_output = static struct console_input_driver s5p_serial_input = { .havekey = &serial_havechar, - .getchar = &serial_getchar + .getchar = &serial_getchar, + .input_type = CONSOLE_INPUT_TYPE_UART, }; void serial_init(void) diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 3a84b3b0382..a578d41f288 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -350,6 +350,9 @@ int set_option_from_string(const struct nvram_accessor *nvram, struct cb_cmos_op typedef enum { CONSOLE_INPUT_TYPE_UNKNOWN = 0, CONSOLE_INPUT_TYPE_USB, + CONSOLE_INPUT_TYPE_EC, + CONSOLE_INPUT_TYPE_UART, + CONSOLE_INPUT_TYPE_GPIO, } console_input_type; void console_init(void); From 2cb399625ea04027fd02e6be834738b62d10c7d9 Mon Sep 17 00:00:00 2001 From: Matt Delco Date: Tue, 30 Apr 2019 14:59:43 -0700 Subject: [PATCH 276/588] mainboard: remove "recovery" gpio, selectively add "presence" gpio. The gpio table is only used by depthcharge, and depthcharge rarely has a need for the "recovery" gpio. On a few boards it does use the gpio as a signal for confirming physical presence, so on that boards we'll advertise the board as "presence". All these strings probably should have been #defines to help avoid typos (e.g., the "ec_in_rw" in stout seems questionable since everybody else uses "EC in RW"). Cq-Depend: chromium:1580454 BUG=b:129471321 BRANCH=None TEST=Local compile and flash (with corresponding changes to depthcharge) to 2 systems, one with a "presence" gpio and another without. Confirmed that both systems could enter dev mode. Change-Id: Id6d62d9e48d3e6646cbc1277ea53f0ca95dd849e Signed-off-by: Matt Delco Reviewed-on: https://review.coreboot.org/c/coreboot/+/32718 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Julius Werner --- src/mainboard/google/auron/chromeos.c | 1 - src/mainboard/google/beltino/chromeos.c | 2 +- src/mainboard/google/butterfly/chromeos.c | 3 --- src/mainboard/google/cyan/chromeos.c | 1 - src/mainboard/google/daisy/chromeos.c | 3 --- src/mainboard/google/dragonegg/chromeos.c | 1 - src/mainboard/google/eve/chromeos.c | 1 - src/mainboard/google/fizz/chromeos.c | 1 - src/mainboard/google/foster/chromeos.c | 3 --- src/mainboard/google/gale/chromeos.c | 2 -- src/mainboard/google/glados/chromeos.c | 1 - src/mainboard/google/gru/chromeos.c | 1 - src/mainboard/google/hatch/chromeos.c | 1 - src/mainboard/google/jecht/chromeos.c | 2 +- src/mainboard/google/kahlee/chromeos.c | 1 - src/mainboard/google/kukui/chromeos.c | 1 - src/mainboard/google/link/chromeos.c | 4 ---- src/mainboard/google/nyan/chromeos.c | 1 - src/mainboard/google/nyan_big/chromeos.c | 1 - src/mainboard/google/nyan_blaze/chromeos.c | 1 - src/mainboard/google/oak/chromeos.c | 1 - src/mainboard/google/octopus/chromeos.c | 1 - src/mainboard/google/parrot/chromeos.c | 3 --- src/mainboard/google/peach_pit/chromeos.c | 3 --- src/mainboard/google/poppy/chromeos.c | 1 - src/mainboard/google/rambi/chromeos.c | 1 - src/mainboard/google/reef/chromeos.c | 1 - src/mainboard/google/sarien/chromeos.c | 2 -- src/mainboard/google/slippy/chromeos.c | 1 - src/mainboard/google/smaug/chromeos.c | 1 - src/mainboard/google/storm/chromeos.c | 2 +- src/mainboard/google/stout/chromeos.c | 3 --- src/mainboard/google/veyron/chromeos.c | 2 +- src/mainboard/google/veyron_mickey/chromeos.c | 2 +- src/mainboard/google/veyron_rialto/chromeos.c | 2 +- src/mainboard/intel/baskingridge/chromeos.c | 2 +- src/mainboard/intel/cannonlake_rvp/chromeos.c | 1 - src/mainboard/intel/coffeelake_rvp/chromeos.c | 1 - src/mainboard/intel/emeraldlake2/chromeos.c | 2 +- src/mainboard/intel/glkrvp/chromeos.c | 1 - src/mainboard/intel/icelake_rvp/chromeos.c | 1 - src/mainboard/intel/kblrvp/chromeos.c | 1 - src/mainboard/intel/kunimitsu/chromeos.c | 1 - src/mainboard/intel/strago/chromeos.c | 1 - src/mainboard/intel/wtm2/chromeos.c | 1 - src/mainboard/samsung/lumpy/chromeos.c | 2 +- src/mainboard/samsung/stumpy/chromeos.c | 2 +- 47 files changed, 10 insertions(+), 64 deletions(-) diff --git a/src/mainboard/google/auron/chromeos.c b/src/mainboard/google/auron/chromeos.c index 942e9dd8db7..0147a317fee 100644 --- a/src/mainboard/google/auron/chromeos.c +++ b/src/mainboard/google/auron/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {CROS_WP_GPIO, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/beltino/chromeos.c b/src/mainboard/google/beltino/chromeos.c index 92bb7b445a4..e695ab5f08e 100644 --- a/src/mainboard/google/beltino/chromeos.c +++ b/src/mainboard/google/beltino/chromeos.c @@ -36,7 +36,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_SPI_WP, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, {GPIO_REC_MODE, ACTIVE_LOW, - !get_recovery_mode_switch(), "recovery"}, + !get_recovery_mode_switch(), "presence"}, {-1, ACTIVE_HIGH, 1, "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/butterfly/chromeos.c b/src/mainboard/google/butterfly/chromeos.c index 2301d3eec44..7f72ad24bfa 100644 --- a/src/mainboard/google/butterfly/chromeos.c +++ b/src/mainboard/google/butterfly/chromeos.c @@ -40,9 +40,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) {WP_GPIO, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: virtual GPIO active high */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* lid switch value from EC */ {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, diff --git a/src/mainboard/google/cyan/chromeos.c b/src/mainboard/google/cyan/chromeos.c index 44101e347c8..5d5bc556e54 100644 --- a/src/mainboard/google/cyan/chromeos.c +++ b/src/mainboard/google/cyan/chromeos.c @@ -35,7 +35,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, vboot_recovery_mode_enabled(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/daisy/chromeos.c b/src/mainboard/google/daisy/chromeos.c index 968f1f9d5b0..974cd49f25a 100644 --- a/src/mainboard/google/daisy/chromeos.c +++ b/src/mainboard/google/daisy/chromeos.c @@ -29,9 +29,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) {EXYNOS5_GPD1, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: active low */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* Lid: active high (LID_GPIO) */ {EXYNOS5_GPX3, ACTIVE_HIGH, gpio_get_value(GPIO_X35), "lid"}, diff --git a/src/mainboard/google/dragonegg/chromeos.c b/src/mainboard/google/dragonegg/chromeos.c index 657320cba33..7132b04698e 100644 --- a/src/mainboard/google/dragonegg/chromeos.c +++ b/src/mainboard/google/dragonegg/chromeos.c @@ -28,7 +28,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/eve/chromeos.c b/src/mainboard/google/eve/chromeos.c index 06a4de9d35d..8c276e9ae16 100644 --- a/src/mainboard/google/eve/chromeos.c +++ b/src/mainboard/google/eve/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/fizz/chromeos.c b/src/mainboard/google/fizz/chromeos.c index 3bd5b641c01..31887c59fb3 100644 --- a/src/mainboard/google/fizz/chromeos.c +++ b/src/mainboard/google/fizz/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, 1, "lid"}, /* Lid switch always open */ {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/foster/chromeos.c b/src/mainboard/google/foster/chromeos.c index 591cfd00258..7ce13005096 100644 --- a/src/mainboard/google/foster/chromeos.c +++ b/src/mainboard/google/foster/chromeos.c @@ -28,9 +28,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Write Protect: active low */ {-1, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: active high */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* TODO: Power: active low / high depending on board id */ {GPIO(X5), ACTIVE_LOW, -1, "power"}, diff --git a/src/mainboard/google/gale/chromeos.c b/src/mainboard/google/gale/chromeos.c index 69c3a7a3c74..d0bdbb09400 100644 --- a/src/mainboard/google/gale/chromeos.c +++ b/src/mainboard/google/gale/chromeos.c @@ -68,8 +68,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {PP_SW, ACTIVE_LOW, read_gpio(PP_SW), "presence"}, - {get_rec_sw_gpio_pin(), ACTIVE_LOW, - read_gpio(get_rec_sw_gpio_pin()), "recovery"}, {get_wp_status_gpio_pin(), ACTIVE_LOW, !get_write_protect_state(), "write protect"}, {-1, ACTIVE_LOW, 1, "power"}, diff --git a/src/mainboard/google/glados/chromeos.c b/src/mainboard/google/glados/chromeos.c index f826b55ea8e..b6029dd0f9b 100644 --- a/src/mainboard/google/glados/chromeos.c +++ b/src/mainboard/google/glados/chromeos.c @@ -26,7 +26,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/gru/chromeos.c b/src/mainboard/google/gru/chromeos.c index 53d00fb1887..c92a4923103 100644 --- a/src/mainboard/google/gru/chromeos.c +++ b/src/mainboard/google/gru/chromeos.c @@ -34,7 +34,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO_WP.raw, wp_polarity, get_write_protect_state() ^ !wp_polarity, "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, #if CONFIG(GRU_BASEBOARD_SCARLET) {GPIO_BACKLIGHT.raw, ACTIVE_HIGH, -1, "backlight"}, #endif diff --git a/src/mainboard/google/hatch/chromeos.c b/src/mainboard/google/hatch/chromeos.c index fa54148ee88..4119670ef40 100644 --- a/src/mainboard/google/hatch/chromeos.c +++ b/src/mainboard/google/hatch/chromeos.c @@ -25,7 +25,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/jecht/chromeos.c b/src/mainboard/google/jecht/chromeos.c index b3215a0ec66..2b72cae0363 100644 --- a/src/mainboard/google/jecht/chromeos.c +++ b/src/mainboard/google/jecht/chromeos.c @@ -37,7 +37,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_SPI_WP, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, {GPIO_REC_MODE, ACTIVE_LOW, - !get_recovery_mode_switch(), "recovery"}, + !get_recovery_mode_switch(), "presence"}, {-1, ACTIVE_HIGH, 1, "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/kahlee/chromeos.c b/src/mainboard/google/kahlee/chromeos.c index 3bce66bbd6f..195eb94378f 100644 --- a/src/mainboard/google/kahlee/chromeos.c +++ b/src/mainboard/google/kahlee/chromeos.c @@ -24,7 +24,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {GPIO_EC_IN_RW, ACTIVE_HIGH, gpio_get(GPIO_EC_IN_RW), diff --git a/src/mainboard/google/kukui/chromeos.c b/src/mainboard/google/kukui/chromeos.c index 35395014d67..2cef10e82bb 100644 --- a/src/mainboard/google/kukui/chromeos.c +++ b/src/mainboard/google/kukui/chromeos.c @@ -35,7 +35,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO_WP.id, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {EC_IN_RW.id, ACTIVE_HIGH, -1, "EC in RW"}, {EC_IRQ.id, ACTIVE_LOW, -1, "EC interrupt"}, {CR50_IRQ.id, ACTIVE_HIGH, -1, "TPM interrupt"}, diff --git a/src/mainboard/google/link/chromeos.c b/src/mainboard/google/link/chromeos.c index 5156404ab74..ecd7592823e 100644 --- a/src/mainboard/google/link/chromeos.c +++ b/src/mainboard/google/link/chromeos.c @@ -28,10 +28,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Write Protect: GPIO57 = PCH_SPI_WP_D */ {57, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - /* Recovery: the "switch" comes from the EC */ - /* -1 indicates that this is a pseudo GPIO */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* Lid: the "switch" comes from the EC */ {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, diff --git a/src/mainboard/google/nyan/chromeos.c b/src/mainboard/google/nyan/chromeos.c index ba851c76c3e..e3e09e6dbd3 100644 --- a/src/mainboard/google/nyan/chromeos.c +++ b/src/mainboard/google/nyan/chromeos.c @@ -22,7 +22,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO(R1), ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {GPIO(R4), ACTIVE_HIGH, -1, "lid"}, {GPIO(Q0), ACTIVE_LOW, -1, "power"}, {GPIO(U4), ACTIVE_HIGH, -1, "EC in RW"}, diff --git a/src/mainboard/google/nyan_big/chromeos.c b/src/mainboard/google/nyan_big/chromeos.c index f2979989fad..1fbaac72348 100644 --- a/src/mainboard/google/nyan_big/chromeos.c +++ b/src/mainboard/google/nyan_big/chromeos.c @@ -22,7 +22,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO(R1), ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {GPIO(R4), ACTIVE_HIGH, -1, "lid"}, {GPIO(Q0), ACTIVE_LOW, -1, "power"}, {GPIO(U4), ACTIVE_HIGH, -1, "EC in RW"}, diff --git a/src/mainboard/google/nyan_blaze/chromeos.c b/src/mainboard/google/nyan_blaze/chromeos.c index dbbd91f1ddc..bbb274fb90b 100644 --- a/src/mainboard/google/nyan_blaze/chromeos.c +++ b/src/mainboard/google/nyan_blaze/chromeos.c @@ -22,7 +22,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO(R1), ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {GPIO(R4), ACTIVE_HIGH, -1, "lid"}, {GPIO(Q0), ACTIVE_LOW, -1, "power"}, {GPIO(U4), ACTIVE_HIGH, -1, "EC in RW"}, diff --git a/src/mainboard/google/oak/chromeos.c b/src/mainboard/google/oak/chromeos.c index 4e07236b4c6..b613cc3a85f 100644 --- a/src/mainboard/google/oak/chromeos.c +++ b/src/mainboard/google/oak/chromeos.c @@ -36,7 +36,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {WRITE_PROTECT.id, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {LID.id, ACTIVE_HIGH, -1, "lid"}, {POWER_BUTTON.id, ACTIVE_HIGH, -1, "power"}, {EC_IN_RW.id, ACTIVE_HIGH, -1, "EC in RW"}, diff --git a/src/mainboard/google/octopus/chromeos.c b/src/mainboard/google/octopus/chromeos.c index 5eb39901242..ca9f6fbeb26 100644 --- a/src/mainboard/google/octopus/chromeos.c +++ b/src/mainboard/google/octopus/chromeos.c @@ -25,7 +25,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/parrot/chromeos.c b/src/mainboard/google/parrot/chromeos.c index f17b6a64e1c..095d5049edf 100644 --- a/src/mainboard/google/parrot/chromeos.c +++ b/src/mainboard/google/parrot/chromeos.c @@ -39,9 +39,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Write Protect: GPIO70 active high */ {70, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: Virtual GPIO in the EC (Servo GPIO68 active low) */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* Lid switch GPIO active high (open). */ {15, ACTIVE_HIGH, get_lid_switch(), "lid"}, diff --git a/src/mainboard/google/peach_pit/chromeos.c b/src/mainboard/google/peach_pit/chromeos.c index b2d90d9e903..8bd35bee954 100644 --- a/src/mainboard/google/peach_pit/chromeos.c +++ b/src/mainboard/google/peach_pit/chromeos.c @@ -29,9 +29,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) {EXYNOS5_GPX3, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: active low */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* Lid: active high (LID_GPIO) */ {EXYNOS5_GPX3, ACTIVE_HIGH, gpio_get_value(GPIO_X34), "lid"}, diff --git a/src/mainboard/google/poppy/chromeos.c b/src/mainboard/google/poppy/chromeos.c index 83b8aa05633..3879732135c 100644 --- a/src/mainboard/google/poppy/chromeos.c +++ b/src/mainboard/google/poppy/chromeos.c @@ -28,7 +28,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/rambi/chromeos.c b/src/mainboard/google/rambi/chromeos.c index d47a323a4fc..7880154586a 100644 --- a/src/mainboard/google/rambi/chromeos.c +++ b/src/mainboard/google/rambi/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, vboot_recovery_mode_enabled(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/reef/chromeos.c b/src/mainboard/google/reef/chromeos.c index 7b7f2b8ce0a..4dbbe6d5811 100644 --- a/src/mainboard/google/reef/chromeos.c +++ b/src/mainboard/google/reef/chromeos.c @@ -24,7 +24,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/sarien/chromeos.c b/src/mainboard/google/sarien/chromeos.c index 15670d0d8ed..fafc4692702 100644 --- a/src/mainboard/google/sarien/chromeos.c +++ b/src/mainboard/google/sarien/chromeos.c @@ -36,8 +36,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {GPIO_PCH_WP, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {GPIO_REC_MODE, ACTIVE_LOW, !get_recovery_mode_switch(), - "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/slippy/chromeos.c b/src/mainboard/google/slippy/chromeos.c index 15779ee9657..f52bace2717 100644 --- a/src/mainboard/google/slippy/chromeos.c +++ b/src/mainboard/google/slippy/chromeos.c @@ -25,7 +25,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {58, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/google/smaug/chromeos.c b/src/mainboard/google/smaug/chromeos.c index 567a3ae253d..3d36cd9dc0c 100644 --- a/src/mainboard/google/smaug/chromeos.c +++ b/src/mainboard/google/smaug/chromeos.c @@ -23,7 +23,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) struct lb_gpio chromeos_gpios[] = { {WRITE_PROTECT_L, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {POWER_BUTTON, ACTIVE_LOW, -1, "power"}, {EC_IN_RW, ACTIVE_HIGH, -1, "EC in RW"}, {AP_SYS_RESET_L, ACTIVE_LOW, -1, "reset"}, diff --git a/src/mainboard/google/storm/chromeos.c b/src/mainboard/google/storm/chromeos.c index ccc0b53e026..9587c3c384e 100644 --- a/src/mainboard/google/storm/chromeos.c +++ b/src/mainboard/google/storm/chromeos.c @@ -39,7 +39,7 @@ static int read_gpio(gpio_t gpio_num) void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { - {REC_SW, ACTIVE_LOW, read_gpio(REC_SW), "recovery"}, + {DEV_SW, ACTIVE_LOW, read_gpio(REC_SW), "presence"}, {WP_SW, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, {-1, ACTIVE_LOW, 1, "power"}, diff --git a/src/mainboard/google/stout/chromeos.c b/src/mainboard/google/stout/chromeos.c index 015e0aad322..60c7a09249b 100644 --- a/src/mainboard/google/stout/chromeos.c +++ b/src/mainboard/google/stout/chromeos.c @@ -35,9 +35,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Write Protect: GPIO7 */ {7, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, - /* Recovery: Virtual switch */ - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, - /* Lid Switch: Virtual switch */ {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, diff --git a/src/mainboard/google/veyron/chromeos.c b/src/mainboard/google/veyron/chromeos.c index 357a7fc468f..d27b4dd3d5e 100644 --- a/src/mainboard/google/veyron/chromeos.c +++ b/src/mainboard/google/veyron/chromeos.c @@ -43,7 +43,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_WP.raw, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, {GPIO_RECOVERY.raw, ACTIVE_LOW, - !get_recovery_mode_switch(), "recovery"}, + !get_recovery_mode_switch(), "presence"}, {GPIO_LID.raw, ACTIVE_HIGH, -1, "lid"}, {GPIO_POWER.raw, ACTIVE_LOW, -1, "power"}, {GPIO_ECINRW.raw, ACTIVE_HIGH, -1, "EC in RW"}, diff --git a/src/mainboard/google/veyron_mickey/chromeos.c b/src/mainboard/google/veyron_mickey/chromeos.c index 46a6738b937..c549e70b51e 100644 --- a/src/mainboard/google/veyron_mickey/chromeos.c +++ b/src/mainboard/google/veyron_mickey/chromeos.c @@ -34,7 +34,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {GPIO_WP.raw, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, {GPIO_RECOVERY.raw, ACTIVE_LOW, - !get_recovery_mode_switch(), "recovery"}, + !get_recovery_mode_switch(), "presence"}, {GPIO_RESET.raw, ACTIVE_HIGH, -1, "reset"}, }; lb_add_gpios(gpios, chromeos_gpios, ARRAY_SIZE(chromeos_gpios)); diff --git a/src/mainboard/google/veyron_rialto/chromeos.c b/src/mainboard/google/veyron_rialto/chromeos.c index e86d86305f4..65866f3ceca 100644 --- a/src/mainboard/google/veyron_rialto/chromeos.c +++ b/src/mainboard/google/veyron_rialto/chromeos.c @@ -41,7 +41,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Note for early development, we want to support both servo * and pushkey recovery buttons in firmware boot stages. */ {GPIO_RECOVERY_PUSHKEY.raw, ACTIVE_LOW, - !get_recovery_mode_switch(), "recovery"}, + !get_recovery_mode_switch(), "presence"}, {GPIO_POWER.raw, ACTIVE_LOW, -1, "power"}, {GPIO_RESET.raw, ACTIVE_HIGH, -1, "reset"}, }; diff --git a/src/mainboard/intel/baskingridge/chromeos.c b/src/mainboard/intel/baskingridge/chromeos.c index f1fd3ed84c8..1673622793a 100644 --- a/src/mainboard/intel/baskingridge/chromeos.c +++ b/src/mainboard/intel/baskingridge/chromeos.c @@ -33,7 +33,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {0, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, /* Recovery: GPIO69 - SV_DETECT - J8E3 (silkscreen: J8E2) */ - {69, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, + {69, ACTIVE_HIGH, get_recovery_mode_switch(), "presence"}, /* Hard code the lid switch GPIO to open. */ {-1, ACTIVE_HIGH, 1, "lid"}, diff --git a/src/mainboard/intel/cannonlake_rvp/chromeos.c b/src/mainboard/intel/cannonlake_rvp/chromeos.c index 296a3a51eac..44254bcbcb5 100644 --- a/src/mainboard/intel/cannonlake_rvp/chromeos.c +++ b/src/mainboard/intel/cannonlake_rvp/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/coffeelake_rvp/chromeos.c b/src/mainboard/intel/coffeelake_rvp/chromeos.c index 84f5f27f6af..a581217e17e 100644 --- a/src/mainboard/intel/coffeelake_rvp/chromeos.c +++ b/src/mainboard/intel/coffeelake_rvp/chromeos.c @@ -26,7 +26,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/emeraldlake2/chromeos.c b/src/mainboard/intel/emeraldlake2/chromeos.c index 78610d398d4..219eefb8712 100644 --- a/src/mainboard/intel/emeraldlake2/chromeos.c +++ b/src/mainboard/intel/emeraldlake2/chromeos.c @@ -33,7 +33,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) {48, ACTIVE_LOW, !get_write_protect_state(), "write protect"}, /* Recovery: GPIO22 */ - {22, ACTIVE_LOW, !get_recovery_mode_switch(), "recovery"}, + {22, ACTIVE_LOW, !get_recovery_mode_switch(), "presence"}, /* Hard code the lid switch GPIO to open. */ {-1, ACTIVE_HIGH, 1, "lid"}, diff --git a/src/mainboard/intel/glkrvp/chromeos.c b/src/mainboard/intel/glkrvp/chromeos.c index 07d92e96fe6..4edd4a0ab48 100644 --- a/src/mainboard/intel/glkrvp/chromeos.c +++ b/src/mainboard/intel/glkrvp/chromeos.c @@ -25,7 +25,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/icelake_rvp/chromeos.c b/src/mainboard/intel/icelake_rvp/chromeos.c index 5965d95c320..ce8e5486d8a 100644 --- a/src/mainboard/intel/icelake_rvp/chromeos.c +++ b/src/mainboard/intel/icelake_rvp/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/kblrvp/chromeos.c b/src/mainboard/intel/kblrvp/chromeos.c index 51680742adc..ff93d27f229 100644 --- a/src/mainboard/intel/kblrvp/chromeos.c +++ b/src/mainboard/intel/kblrvp/chromeos.c @@ -31,7 +31,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/kunimitsu/chromeos.c b/src/mainboard/intel/kunimitsu/chromeos.c index f7a9d52ba64..64224889a5b 100644 --- a/src/mainboard/intel/kunimitsu/chromeos.c +++ b/src/mainboard/intel/kunimitsu/chromeos.c @@ -27,7 +27,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/strago/chromeos.c b/src/mainboard/intel/strago/chromeos.c index 03eff1be4e4..df36b38a318 100644 --- a/src/mainboard/intel/strago/chromeos.c +++ b/src/mainboard/intel/strago/chromeos.c @@ -29,7 +29,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, vboot_recovery_mode_enabled(), "recovery"}, {-1, ACTIVE_HIGH, get_lid_switch(), "lid"}, {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/intel/wtm2/chromeos.c b/src/mainboard/intel/wtm2/chromeos.c index 0f5cfbba35e..802221446de 100644 --- a/src/mainboard/intel/wtm2/chromeos.c +++ b/src/mainboard/intel/wtm2/chromeos.c @@ -29,7 +29,6 @@ void fill_lb_gpios(struct lb_gpios *gpios) { struct lb_gpio chromeos_gpios[] = { {-1, ACTIVE_HIGH, get_write_protect_state(), "write protect"}, - {-1, ACTIVE_HIGH, get_recovery_mode_switch(), "recovery"}, {-1, ACTIVE_HIGH, 1, "lid"}, // force open {-1, ACTIVE_HIGH, 0, "power"}, {-1, ACTIVE_HIGH, gfx_get_init_done(), "oprom"}, diff --git a/src/mainboard/samsung/lumpy/chromeos.c b/src/mainboard/samsung/lumpy/chromeos.c index 2d4fb61be89..6760f036113 100644 --- a/src/mainboard/samsung/lumpy/chromeos.c +++ b/src/mainboard/samsung/lumpy/chromeos.c @@ -47,7 +47,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Recovery: GPIO42 = CHP3_REC_MODE# */ {GPIO_REC_MODE, ACTIVE_LOW, !get_recovery_mode_switch(), - "recovery"}, + "presence"}, {100, ACTIVE_HIGH, lid & 1, "lid"}, diff --git a/src/mainboard/samsung/stumpy/chromeos.c b/src/mainboard/samsung/stumpy/chromeos.c index b1ad1371135..9ec4218b01d 100644 --- a/src/mainboard/samsung/stumpy/chromeos.c +++ b/src/mainboard/samsung/stumpy/chromeos.c @@ -43,7 +43,7 @@ void fill_lb_gpios(struct lb_gpios *gpios) /* Recovery: GPIO42 = CHP3_REC_MODE# */ {GPIO_REC_MODE, ACTIVE_LOW, !get_recovery_mode_switch(), - "recovery"}, + "presence"}, /* Hard code the lid switch GPIO to open. */ {100, ACTIVE_HIGH, 1, "lid"}, From 7528f834447de52d1d62e979cd93af0ac30d5f6f Mon Sep 17 00:00:00 2001 From: John Zhao Date: Fri, 10 May 2019 10:51:52 -0700 Subject: [PATCH 277/588] soc/intel: Geminilake Refresh feature request support Add 0x706a8 for GLK Refresh CPU stepping ID. BUG=b:132414963 BRANCH=None TEST=Image built successfully. Signed-off-by: John Zhao Change-Id: I4641d9bd4c82211e7200f617cae9043b0f2f38d1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32744 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/soc/intel/apollolake/cpu.c | 1 + src/soc/intel/common/block/cpu/mp_init.c | 1 + src/soc/intel/common/block/include/intelblocks/mp_init.h | 1 + 3 files changed, 3 insertions(+) diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 11d15e4f13f..651c20e43a9 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -119,6 +119,7 @@ static const struct cpu_device_id cpu_table[] = { { X86_VENDOR_INTEL, CPUID_APOLLOLAKE_E0 }, { X86_VENDOR_INTEL, CPUID_GLK_A0 }, { X86_VENDOR_INTEL, CPUID_GLK_B0 }, + { X86_VENDOR_INTEL, CPUID_GLK_R0 }, { 0, 0 }, }; diff --git a/src/soc/intel/common/block/cpu/mp_init.c b/src/soc/intel/common/block/cpu/mp_init.c index 0a59c56f1f3..e98b5dd6150 100644 --- a/src/soc/intel/common/block/cpu/mp_init.c +++ b/src/soc/intel/common/block/cpu/mp_init.c @@ -70,6 +70,7 @@ static const struct cpu_device_id cpu_table[] = { { X86_VENDOR_INTEL, CPUID_APOLLOLAKE_E0 }, { X86_VENDOR_INTEL, CPUID_GLK_A0 }, { X86_VENDOR_INTEL, CPUID_GLK_B0 }, + { X86_VENDOR_INTEL, CPUID_GLK_R0 }, { X86_VENDOR_INTEL, CPUID_WHISKEYLAKE_V0 }, { X86_VENDOR_INTEL, CPUID_WHISKEYLAKE_W0 }, { X86_VENDOR_INTEL, CPUID_COFFEELAKE_U0 }, diff --git a/src/soc/intel/common/block/include/intelblocks/mp_init.h b/src/soc/intel/common/block/include/intelblocks/mp_init.h index 3c7467da57d..0f37a64345b 100644 --- a/src/soc/intel/common/block/include/intelblocks/mp_init.h +++ b/src/soc/intel/common/block/include/intelblocks/mp_init.h @@ -37,6 +37,7 @@ #define CPUID_APOLLOLAKE_E0 0x506ca #define CPUID_GLK_A0 0x706a0 #define CPUID_GLK_B0 0x706a1 +#define CPUID_GLK_R0 0x706a8 #define CPUID_WHISKEYLAKE_V0 0x806ec #define CPUID_WHISKEYLAKE_W0 0x806eb #define CPUID_COFFEELAKE_D0 0x806ea From a75440739d172bea6eeefc08af2bbdefc528e912 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Thu, 9 May 2019 14:24:02 -0600 Subject: [PATCH 278/588] util/inteltool: Use appropriate channel for printing timings At least one channel must be present, so print an error if there is not. However, we cannot always assume it will be the first channel, so make the appropriate selection when printing the timings. Found-by: Coverity Scan #1370{584,585,588,589,590-596,600} Signed-off-by: Jacob Garber Change-Id: I6b59989242e498474782876302e0850e3e4cf2d3 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32713 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/inteltool/ivy_memory.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/util/inteltool/ivy_memory.c b/util/inteltool/ivy_memory.c index 8ce861127bc..16c1d8920c4 100644 --- a/util/inteltool/ivy_memory.c +++ b/util/inteltool/ivy_memory.c @@ -97,6 +97,11 @@ void ivybridge_dump_timings(const char *dump_spd_file) rankmap[channel] = read_mchbar32(0xc14 + 0x100 * channel) >> 24; } + if ((rankmap[0] == 0) && (rankmap[1] == 0)) { + fputs("Error: no memory channels found\n", stderr); + exit(1); + } + two_channels = rankmap[0] && rankmap[1]; mr0[0] = read_mchbar32(0x0004); @@ -172,49 +177,52 @@ void ivybridge_dump_timings(const char *dump_spd_file) printf(".reg_4004_b30 = { %d, %d },\n", reg_4004_b30[0], reg_4004_b30[1]); + + channel = (rankmap[0] != 0) ? 0 : 1; + if (two_channels && tFAW[0] != tFAW[1]) printf("/* tFAW mismatch: %d, %d */\n", tFAW[0], tFAW[1]); - print_time("tFAW", tFAW[0], tCK); + print_time("tFAW", tFAW[channel], tCK); if (two_channels && tWTR[0] != tWTR[1]) printf("/* tWTR mismatch: %d, %d */\n", tWTR[0], tWTR[1]); - print_time("tWTR", tWTR[0], tCK); + print_time("tWTR", tWTR[channel], tCK); if (two_channels && tCKE[0] != tCKE[1]) printf("/* tCKE mismatch: %d, %d */\n", tCKE[0], tCKE[1]); - print_time("tCKE", tCKE[0], tCK); + print_time("tCKE", tCKE[channel], tCK); if (two_channels && tRTP[0] != tRTP[1]) printf("/* tRTP mismatch: %d, %d */\n", tRTP[0], tRTP[1]); - print_time("tRTP", tRTP[0], tCK); + print_time("tRTP", tRTP[channel], tCK); if (two_channels && tRRD[0] != tRRD[1]) printf("/* tRRD mismatch: %d, %d */\n", tRRD[0], tRRD[1]); - print_time("tRRD", tRRD[0], tCK); + print_time("tRRD", tRRD[channel], tCK); if (two_channels && tRAS[0] != tRAS[1]) printf("/* tRAS mismatch: %d, %d */\n", tRAS[0], tRAS[1]); - print_time("tRAS", tRAS[0], tCK); + print_time("tRAS", tRAS[channel], tCK); if (two_channels && tCWL[0] != tCWL[1]) printf("/* tCWL mismatch: %d, %d */\n", tCWL[0], tCWL[1]); - print_time("tCWL", tCWL[0], tCK); + print_time("tCWL", tCWL[channel], tCK); if (two_channels && tRP[0] != tRP[1]) printf("/* tRP mismatch: %d, %d */\n", tRP[0], tRP[1]); - print_time("tRP", tRP[0], tCK); + print_time("tRP", tRP[channel], tCK); if (two_channels && tRCD[0] != tRCD[1]) printf("/* tRCD mismatch: %d, %d */\n", tRCD[0], tRCD[1]); - print_time("tRCD", tRCD[0], tCK); + print_time("tRCD", tRCD[channel], tCK); if (two_channels && tXPDLL[0] != tXPDLL[1]) printf("/* tXPDLL mismatch: %d, %d */\n", tXPDLL[0], tXPDLL[1]); - print_time("tXPDLL", tXPDLL[0], tCK); + print_time("tXPDLL", tXPDLL[channel], tCK); if (two_channels && tXP[0] != tXP[1]) printf("/* tXP mismatch: %d, %d */\n", tXP[0], tXP[1]); - print_time("tXP", tXP[0], tCK); + print_time("tXP", tXP[channel], tCK); if (two_channels && tAONPD[0] != tAONPD[1]) printf("/* tAONPD mismatch: %d, %d */\n", tAONPD[0], tAONPD[1]); - print_time("tAONPD", tAONPD[0], tCK); + print_time("tAONPD", tAONPD[channel], tCK); reg = read_mchbar32(0x4298); if (reg != read_mchbar32(0x4698) && two_channels) From dbc787d13d461bf0d96002bfc36936de4c64cea7 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Fri, 10 May 2019 17:29:48 -0600 Subject: [PATCH 279/588] libpayload/drivers/i8042: Add fallthrough comment Ctrl-delete does nothing, so it falls through to the default case. Add a comment to make this explicit. Found-by: Coverity Scan #1260878 Signed-off-by: Jacob Garber Change-Id: I4a6f51cb04696b6ebcb554c5667a5bbea58622c1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32750 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- payloads/libpayload/drivers/i8042/keyboard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index 42431c36891..cded6383809 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -258,6 +258,7 @@ int keyboard_getchar(void) /* vulcan nerve pinch */ if ((modifier & KB_MOD_ALT) && reset_handler) reset_handler(); + /* fallthrough */ default: ret = 0; } From ef9e85bbfdb24d228f1e6c37d916025c5d06ea53 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 10 May 2019 19:40:50 +0200 Subject: [PATCH 280/588] mb/t400/acpi: Update ATPR buffer to fit all entries Error spotted using acpica version 20190509 (Change-Id: I6779a20). Change-Id: Ic9cf16a7494667f6dab156c697fb8f8e9966051e Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32743 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Martin Roth --- src/mainboard/lenovo/t400/acpi/graphics.asl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/mainboard/lenovo/t400/acpi/graphics.asl b/src/mainboard/lenovo/t400/acpi/graphics.asl index 818ea93724b..038774fdfd3 100644 --- a/src/mainboard/lenovo/t400/acpi/graphics.asl +++ b/src/mainboard/lenovo/t400/acpi/graphics.asl @@ -63,9 +63,7 @@ Method (ATPX, 2, Serialized) { }) CreateWordField (ATPR, 0x00, SIZE) CreateWordField (ATPR, 0x02, VERS) - CreateDWordField (ATPR, 0x02, MASK) CreateDWordField (ATPR, 0x04, FUNC) - CreateDWordField (ATPR, 0x06, FLAG) /* Version request */ if (LEqual(Arg0, 0x0)) From 2f0bbbfe9f3b3d68d75eabd35280fe8aaa9d8619 Mon Sep 17 00:00:00 2001 From: Martin Roth Date: Sat, 11 May 2019 12:51:44 -0600 Subject: [PATCH 281/588] mb/lenovo/s230u: Rewrite trigger inversion ACPI code The GPIO invert registers are already defined in the PCH code, so just use the 8-bit versions of the registers instead of creating a new GPIO field for the single bits. This allows us to get rid of the Field(GPIO...) code that's causing problems with IASL version 20190509. Signed-off-by: Martin Roth Change-Id: Iac5dfb71b3a2b5a25c05a403cf5f403c7acecaaf Reviewed-on: https://review.coreboot.org/c/coreboot/+/32753 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/mainboard/lenovo/s230u/acpi/gpe.asl | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/mainboard/lenovo/s230u/acpi/gpe.asl b/src/mainboard/lenovo/s230u/acpi/gpe.asl index a69f5629b12..e6f4153aca8 100644 --- a/src/mainboard/lenovo/s230u/acpi/gpe.asl +++ b/src/mainboard/lenovo/s230u/acpi/gpe.asl @@ -16,15 +16,6 @@ Scope (_GPE) { - Field(GPIO, ByteAcc, NoLock, Preserve) - { - Offset(0x2c), // GPIO Invert - , 2, - GV02, 1, - , 1, - GV04, 1, - } - Name (PDET, Zero) Method (PNOT, 2, Serialized) { ShiftLeft (Arg0, Arg1, Local0) @@ -39,10 +30,20 @@ Scope (_GPE) } } + Method (TINV, 2, Serialized) { + ShiftLeft (One, Arg1, Local0) + If (LEqual (Arg0, Zero)) { + Not (Local0, Local0) + And (GIV0, Local0, GIV0) + } Else { + Or (GIV0, Local0, GIV0) + } + } + /* Palm detect sensor 1 */ Method (_L12, 0, NotSerialized) { // Invert trigger - Store(GP02, GV02) + TINV (GP02, 2) PNOT (GP02, 0) } @@ -50,7 +51,7 @@ Scope (_GPE) /* Palm detect sensor 2 */ Method (_L14, 0, NotSerialized) { // Invert trigger - Store(GP04, GV04) + TINV (GP04, 4) PNOT (GP04, 1) } From 60ab1d8c52799d70d1956ce7261d94be439aa63a Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 10 May 2019 21:05:58 +0200 Subject: [PATCH 282/588] src/ec/lenovo/h8/acpi: Serialize Control Method IASL reports warning 'Control Method should be made Serialized'. Change-Id: I034f2c00e912e8f9ef87b9918de1db06fade38b9 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32745 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/ec/lenovo/h8/acpi/battery.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ec/lenovo/h8/acpi/battery.asl b/src/ec/lenovo/h8/acpi/battery.asl index 080f247838a..5f97ed9dc52 100644 --- a/src/ec/lenovo/h8/acpi/battery.asl +++ b/src/ec/lenovo/h8/acpi/battery.asl @@ -160,7 +160,7 @@ Method(BSTA, 4, NotSerialized) Return (Arg1) } -Method(BINF, 2, NotSerialized) +Method(BINF, 2, Serialized) { Acquire(ECLK, 0xffff) ^BPAG(Or(1, Arg1)) /* Battery 0 static information */ From 44105942df5a396c5ff999d7dd8384bfd44784c0 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Thu, 9 May 2019 17:19:23 +0200 Subject: [PATCH 283/588] nb/intel/sandybridge: Update pei_data comments Update outdated comments. Change-Id: I100f71345281a1dc52e99d2395f528d60a9a1f58 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32706 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/samsung/lumpy/romstage.c | 2 -- src/northbridge/intel/sandybridge/pei_data.h | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/mainboard/samsung/lumpy/romstage.c b/src/mainboard/samsung/lumpy/romstage.c index 1080689d4a1..26b9dcc8137 100644 --- a/src/mainboard/samsung/lumpy/romstage.c +++ b/src/mainboard/samsung/lumpy/romstage.c @@ -148,7 +148,6 @@ static const uint8_t *locate_spd(void) die("SPD data not found."); if (spd_file_len < (spd_index + 1) * 256) die("Missing SPD data."); - // leave onboard dimm address at f0, and copy spd data there. return spd_data[spd_index]; } @@ -198,7 +197,6 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) }, }; *pei_data = pei_data_template; - // leave onboard dimm address at f0, and copy spd data there. memcpy(pei_data->spd_data[0], locate_spd(), 256); } diff --git a/src/northbridge/intel/sandybridge/pei_data.h b/src/northbridge/intel/sandybridge/pei_data.h index 0a60707136e..8e98becbe33 100644 --- a/src/northbridge/intel/sandybridge/pei_data.h +++ b/src/northbridge/intel/sandybridge/pei_data.h @@ -105,9 +105,10 @@ struct pei_data uint16_t usb_port_config[16][3]; /* See the usb3 struct above for details */ pch_usb3_controller_settings usb3; - /* SPD data array for onboard RAM. Specify address 0xf0, - * 0xf1, 0xf2, 0xf3 to index one of the 4 slots in - * spd_address for a given "DIMM". + /* SPD data array for onboard RAM. + * spd_data [1..3] are ignored, instead the "dimm_channel{0,1}_disabled" + * flag and the spd_addresses are used to determine which DIMMs should + * use the SPD from spd_data[0]. */ uint8_t spd_data[4][256]; tx_byte_func tx_byte; From 59b4255c63b54739b9a095021508a13eab86c2a1 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 8 May 2019 12:44:15 +0200 Subject: [PATCH 284/588] mb/samsung/lumpy: Move onboard SPD to second channel Move the onboard SPD to second channel as native raminit does and workaround mrc expecations in northbridge code. Required to move pei data to devicetree and to use the same code for mrc and native raminit. Tested on Lenovo T520: Other fields then spd_data[0] are ignored. Change-Id: If1910e82a4bd178c2a6c2991c91e09782122888e Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32682 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/samsung/lumpy/romstage.c | 2 +- src/northbridge/intel/sandybridge/raminit_mrc.c | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/mainboard/samsung/lumpy/romstage.c b/src/mainboard/samsung/lumpy/romstage.c index 26b9dcc8137..a77149d9275 100644 --- a/src/mainboard/samsung/lumpy/romstage.c +++ b/src/mainboard/samsung/lumpy/romstage.c @@ -197,7 +197,7 @@ void mainboard_fill_pei_data(struct pei_data *pei_data) }, }; *pei_data = pei_data_template; - memcpy(pei_data->spd_data[0], locate_spd(), 256); + memcpy(pei_data->spd_data[2], locate_spd(), 256); } const struct southbridge_usb_port mainboard_usb_ports[] = { diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index ea3590f78d3..1c9e0210255 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -288,6 +288,19 @@ void perform_raminit(int s3resume) mainboard_fill_pei_data(&pei_data); post_code(0x3a); + + /* Fix spd_data. MRC only uses spd_data[0] and ignores the other */ + for (size_t i = 1; i < ARRAY_SIZE(pei_data.spd_data); i++) { + if (pei_data.spd_data[i][0] && !pei_data.spd_data[0][0]) { + memcpy(pei_data.spd_data[0], pei_data.spd_data[i], + sizeof(pei_data.spd_data[0])); + } else if (pei_data.spd_data[i][0] && pei_data.spd_data[0][0]) { + if (memcmp(pei_data.spd_data[i], pei_data.spd_data[0], + sizeof(pei_data.spd_data[0])) != 0) + die("Onboard SPDs must match each other"); + } + } + pei_data.boot_mode = s3resume ? 2 : 0; timestamp_add_now(TS_BEFORE_INITRAM); sdram_initialize(&pei_data); From 5709e03613b342f9dc00a659b6474c6ee510fcc3 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 25 Mar 2019 10:12:14 +0100 Subject: [PATCH 285/588] nb/intel/sandybridge: Migrate MRC settings to devicetree * Add more chip register to move PEI data to devicetree.cb. * Set northbridge/southbridge and runtime detectable settings. * Fill in values from devicetree. This change is still a noop as the pei structure is completely overwritten with the exsting mainboard pei structure. The followup commit will migrate to devicetree.cb. Tested on Lenovo T520, boots MRC path with the new devicetree settings. Signed-off-by: Patrick Rudolph Change-Id: Ic6d9f0fd6a2b792ac693d6016ed9ce44945c900c Reviewed-on: https://review.coreboot.org/c/coreboot/+/32069 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/northbridge/intel/sandybridge/chip.h | 66 ++++++++++++ .../intel/sandybridge/raminit_mrc.c | 100 ++++++++++++++++++ 2 files changed, 166 insertions(+) diff --git a/src/northbridge/intel/sandybridge/chip.h b/src/northbridge/intel/sandybridge/chip.h index d002824287e..7dddb8abd0a 100644 --- a/src/northbridge/intel/sandybridge/chip.h +++ b/src/northbridge/intel/sandybridge/chip.h @@ -52,6 +52,72 @@ struct northbridge_intel_sandybridge_config { * Maximum PCI mmio size in MiB. */ u16 pci_mmio_size; + + /* Data for RAM init */ + + /* DIMM SPD address. Use 8bit notation where BIT0 is always zero. */ + u8 spd_addresses[4]; + + /* PEI data for RAM init and early silicon init */ + u8 ts_addresses[4]; + + bool ec_present; + bool ddr3lv_support; + + /* N mode functionality. Leave this setting at 0. + * 0 Auto + * 1 1N + * 2 2N + */ + enum { + DDR_NMODE_AUTO = 0, + DDR_NMODE_1N, + DDR_NMODE_2N, + } nmode; + + /* DDR refresh rate config. JEDEC Standard No.21-C Annex K allows + * for DIMM SPD data to specify whether double-rate is required for + * extended operating temperature range. + * 0 Enable double rate based upon temperature thresholds + * 1 Normal rate + * 2 Always enable double rate + */ + enum { + DDR_REFRESH_RATE_TEMP_THRES = 0, + DDR_REFRESH_REATE_NORMAL, + DDR_REFRESH_RATE_DOUBLE, + } ddr_refresh_rate_config; + + /* + * USB Port Configuration: + * [0] = enable + * [1] = overcurrent pin + * [2] = length + * + * Ports 0-7 can be mapped to OC0-OC3 + * Ports 8-13 can be mapped to OC4-OC7 + * + * Port Length + * MOBILE: + * < 0x050 = Setting 1 (back panel, 1-5in, lowest tx amplitude) + * < 0x140 = Setting 2 (back panel, 5-14in, highest tx amplitude) + * DESKTOP: + * < 0x080 = Setting 1 (front/back panel, <8in, lowest tx amplitude) + * < 0x130 = Setting 2 (back panel, 8-13in, higher tx amplitude) + * < 0x150 = Setting 3 (back panel, 13-15in, highest tx amplitude) + */ + u16 usb_port_config[16][3]; + + struct { + /* 0: Disable, 1: Enable, 2: Auto, 3: Smart Auto */ + u8 mode : 2; + /* 4 bit mask, 1: switchable, 0: not switchable */ + u8 hs_port_switch_mask : 4; + /* 0: No xHCI preOS driver, 1: xHCI preOS driver */ + u8 preboot_support : 1; + /* 0: Disable, 1: Enable */ + u8 xhci_streams : 1; + } usb3; }; #endif /* NORTHBRIDGE_INTEL_SANDYBRIDGE_CHIP_H */ diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index 1c9e0210255..a35d9d814e8 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include "raminit.h" #include "pei_data.h" #include "sandybridge.h" +#include "chip.h" #include #include @@ -275,6 +277,89 @@ struct mrc_var_data { u32 reserved[4]; } __packed; +static void northbridge_fill_pei_data(struct pei_data *pei_data) +{ + pei_data->mchbar = (uintptr_t)DEFAULT_MCHBAR; + pei_data->dmibar = (uintptr_t)DEFAULT_DMIBAR; + pei_data->epbar = DEFAULT_EPBAR; + pei_data->pciexbar = CONFIG_MMCONF_BASE_ADDRESS; + pei_data->hpet_address = CONFIG_HPET_ADDRESS; + pei_data->thermalbase = 0xfed08000; + pei_data->system_type = get_platform_type() == PLATFORM_MOBILE ? 0 : 1; + pei_data->tseg_size = CONFIG_SMM_TSEG_SIZE; + + if ((cpu_get_cpuid() & 0xffff0) == 0x306a0) { + const struct device *dev = pcidev_on_root(1, 0); + pei_data->pcie_init = dev && dev->enabled; + } else { + pei_data->pcie_init = 0; + } +} + +static void southbridge_fill_pei_data(struct pei_data *pei_data) +{ + const struct device *dev = pcidev_on_root(0x19, 0); + + pei_data->smbusbar = SMBUS_IO_BASE; + pei_data->wdbbar = 0x4000000; + pei_data->wdbsize = 0x1000; + pei_data->rcba = (uintptr_t)DEFAULT_RCBABASE; + pei_data->pmbase = DEFAULT_PMBASE; + pei_data->gpiobase = DEFAULT_GPIOBASE; + pei_data->gbe_enable = dev && dev->enabled; +} + +static void devicetree_fill_pei_data(struct pei_data *pei_data) +{ + const struct northbridge_intel_sandybridge_config *cfg; + + const struct device *dev = pcidev_on_root(0, 0); + if (!dev || !dev->chip_info) + return; + + cfg = dev->chip_info; + + switch (cfg->max_mem_clock_mhz) { + /* MRC only supports fixed numbers of frequencies */ + default: + printk(BIOS_WARNING, "RAMINIT: Limiting DDR3 clock to 800 Mhz\n"); + /* fallthrough */ + case 400: + pei_data->max_ddr3_freq = 800; + break; + case 533: + pei_data->max_ddr3_freq = 1066; + break; + case 666: + pei_data->max_ddr3_freq = 1333; + break; + case 800: + pei_data->max_ddr3_freq = 1600; + break; + + } + + memcpy(pei_data->spd_addresses, cfg->spd_addresses, + sizeof(pei_data->spd_addresses)); + + memcpy(pei_data->ts_addresses, cfg->ts_addresses, + sizeof(pei_data->ts_addresses)); + + pei_data->ec_present = cfg->ec_present; + pei_data->ddr3lv_support = cfg->ddr3lv_support; + + pei_data->nmode = cfg->nmode; + pei_data->ddr_refresh_rate_config = cfg->ddr_refresh_rate_config; + + memcpy(pei_data->usb_port_config, cfg->usb_port_config, + sizeof(pei_data->usb_port_config)); + + pei_data->usb3.mode = cfg->usb3.mode; + pei_data->usb3.hs_port_switch_mask = cfg->usb3.hs_port_switch_mask; + pei_data->usb3.preboot_support = cfg->usb3.preboot_support; + pei_data->usb3.xhci_streams = cfg->usb3.xhci_streams; +} + void perform_raminit(int s3resume) { int cbmem_was_initted; @@ -285,10 +370,25 @@ void perform_raminit(int s3resume) if (!mainboard_should_reset_usb(s3resume)) enable_usb_bar(); + memset(&pei_data, 0, sizeof(pei_data)); + pei_data.pei_version = PEI_VERSION, + + northbridge_fill_pei_data(&pei_data); + southbridge_fill_pei_data(&pei_data); + devicetree_fill_pei_data(&pei_data); mainboard_fill_pei_data(&pei_data); post_code(0x3a); + /* Fill after mainboard_fill_pei_data as it might provide spd_data */ + pei_data.dimm_channel0_disabled = + (!pei_data.spd_addresses[0] && !pei_data.spd_data[0][0]) + + (!pei_data.spd_addresses[1] && !pei_data.spd_data[1][0]) * 2; + + pei_data.dimm_channel1_disabled = + (!pei_data.spd_addresses[2] && !pei_data.spd_data[2][0]) + + (!pei_data.spd_addresses[3] && !pei_data.spd_data[3][0]) * 2; + /* Fix spd_data. MRC only uses spd_data[0] and ignores the other */ for (size_t i = 1; i < ARRAY_SIZE(pei_data.spd_data); i++) { if (pei_data.spd_data[i][0] && !pei_data.spd_data[0][0]) { From 9005071c5fb1d75b2a54aa0b3e7af47e25d2de54 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 25 Mar 2019 09:53:23 +0100 Subject: [PATCH 286/588] nb/intel/sandybridge: Move boot_count_increment() Move boot_count_increment() to romstage.c, drop preprocessor code and only increase counter once on regular boot. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to OS, no errors visible in dmesg. Change-Id: I6aa52b75edf19953405b70284c7e7db30f607cd6 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32067 Reviewed-by: HAOUAS Elyes Reviewed-by: Patrick Georgi Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/early_init.c | 18 +----------------- src/northbridge/intel/sandybridge/romstage.c | 4 ++++ 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c index b923065091d..34aec3851b6 100644 --- a/src/northbridge/intel/sandybridge/early_init.c +++ b/src/northbridge/intel/sandybridge/early_init.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include "sandybridge.h" @@ -45,22 +44,7 @@ static void sandybridge_setup_bars(void) pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33); pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33); -#if CONFIG(ELOG_BOOT_COUNT) - /* Increment Boot Counter for non-S3 resume */ - if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) && - ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) != SLP_TYP_S3) - boot_count_increment(); -#endif - - printk(BIOS_DEBUG, " done.\n"); - -#if CONFIG(ELOG_BOOT_COUNT) - /* Increment Boot Counter except when resuming from S3 */ - if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) && - ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3) - return; - boot_count_increment(); -#endif + printk(BIOS_DEBUG, " done\n"); } static void sandybridge_setup_graphics(void) diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c index 43316a2f223..064d042e564 100644 --- a/src/northbridge/intel/sandybridge/romstage.c +++ b/src/northbridge/intel/sandybridge/romstage.c @@ -30,6 +30,7 @@ #include #include #include +#include static void early_pch_reset_pmcon(void) { @@ -79,6 +80,9 @@ void mainboard_romstage_entry(unsigned long bist) s3resume = southbridge_detect_s3_resume(); + if (CONFIG(ELOG_BOOT_COUNT) && !s3resume) + boot_count_increment(); + post_code(0x38); mainboard_early_init(s3resume); From 0c22d2fe46fbc59fa12fec46c21874f422b10e44 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 1 Dec 2018 12:19:52 +0100 Subject: [PATCH 287/588] {bd82x6x,i82801gx,ibexpeak,lynxpoint}: Remove dead code and use macro Use BIOS_CNTL defined macro instead of magic number. Change-Id: I0d2b555ada9c2893af4f85422128f5a8b04e2fc6 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/29990 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/intel/fsp_baytrail/southcluster.c | 3 --- src/southbridge/intel/bd82x6x/lpc.c | 4 +-- src/southbridge/intel/fsp_rangeley/lpc.c | 3 --- src/southbridge/intel/i82801gx/lpc.c | 32 ----------------------- src/southbridge/intel/i82801ix/lpc.c | 32 ----------------------- src/southbridge/intel/i82801jx/lpc.c | 32 ----------------------- src/southbridge/intel/ibexpeak/lpc.c | 4 +-- src/southbridge/intel/lynxpoint/lpc.c | 4 +-- 8 files changed, 6 insertions(+), 108 deletions(-) diff --git a/src/soc/intel/fsp_baytrail/southcluster.c b/src/soc/intel/fsp_baytrail/southcluster.c index 4734e0e023a..c84f4083d43 100644 --- a/src/soc/intel/fsp_baytrail/southcluster.c +++ b/src/soc/intel/fsp_baytrail/southcluster.c @@ -42,9 +42,6 @@ #include "chip.h" #include -#define ENABLE_ACPI_MODE_IN_COREBOOT 0 -#define TEST_SMM_FLASH_LOCKDOWN 0 - typedef struct soc_intel_fsp_baytrail_config config_t; static inline void diff --git a/src/southbridge/intel/bd82x6x/lpc.c b/src/southbridge/intel/bd82x6x/lpc.c index f7bb7e4303e..773750186f0 100644 --- a/src/southbridge/intel/bd82x6x/lpc.c +++ b/src/southbridge/intel/bd82x6x/lpc.c @@ -436,9 +436,9 @@ static void pch_disable_smm_only_flashing(struct device *dev) u8 reg8; printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = pci_read_config8(dev, BIOS_CNTL); reg8 &= ~(1 << 5); - pci_write_config8(dev, 0xdc, reg8); + pci_write_config8(dev, BIOS_CNTL, reg8); } static void pch_fixups(struct device *dev) diff --git a/src/southbridge/intel/fsp_rangeley/lpc.c b/src/southbridge/intel/fsp_rangeley/lpc.c index 4118e5fded0..ba5e04bd3c1 100644 --- a/src/southbridge/intel/fsp_rangeley/lpc.c +++ b/src/southbridge/intel/fsp_rangeley/lpc.c @@ -38,9 +38,6 @@ #define NMI_OFF 0 -#define ENABLE_ACPI_MODE_IN_COREBOOT 0 -#define TEST_SMM_FLASH_LOCKDOWN 0 - typedef struct southbridge_intel_fsp_rangeley_config config_t; static void soc_enable_apic(struct device *dev) diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c index 9a6c9cfefd6..948b6aa7f78 100644 --- a/src/southbridge/intel/i82801gx/lpc.c +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -40,7 +40,6 @@ #define NMI_OFF 0 #define ENABLE_ACPI_MODE_IN_COREBOOT 0 -#define TEST_SMM_FLASH_LOCKDOWN 0 typedef struct southbridge_intel_i82801gx_config config_t; @@ -333,10 +332,6 @@ static void enable_clock_gating(void) #if CONFIG(HAVE_SMI_HANDLER) static void i82801gx_lock_smm(struct device *dev) { -#if TEST_SMM_FLASH_LOCKDOWN - u8 reg8; -#endif - if (!acpi_is_wakeup_s3()) { #if ENABLE_ACPI_MODE_IN_COREBOOT printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n"); @@ -351,33 +346,6 @@ static void i82801gx_lock_smm(struct device *dev) printk(BIOS_DEBUG, "S3 wakeup, enabling ACPI via APMC\n"); outb(APM_CNT_ACPI_ENABLE, APM_CNT); } - -#if TEST_SMM_FLASH_LOCKDOWN - /* Now try this: */ - printk(BIOS_DEBUG, "Locking BIOS to RO... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - reg8 &= ~(1 << 0); /* clear BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - reg8 |= (1 << 1); /* set BLE */ - pci_write_config8(dev, 0xdc, reg8); - printk(BIOS_DEBUG, "ok.\n"); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - - printk(BIOS_DEBUG, "Writing:\n"); - *(volatile u8 *)0xfff00000 = 0x00; - printk(BIOS_DEBUG, "Testing:\n"); - reg8 |= (1 << 0); /* set BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - printk(BIOS_DEBUG, "Done.\n"); -#endif } #endif diff --git a/src/southbridge/intel/i82801ix/lpc.c b/src/southbridge/intel/i82801ix/lpc.c index 4cc1cea02ca..c7de2a14df1 100644 --- a/src/southbridge/intel/i82801ix/lpc.c +++ b/src/southbridge/intel/i82801ix/lpc.c @@ -39,7 +39,6 @@ #define NMI_OFF 0 #define ENABLE_ACPI_MODE_IN_COREBOOT 0 -#define TEST_SMM_FLASH_LOCKDOWN 0 typedef struct southbridge_intel_i82801ix_config config_t; @@ -370,10 +369,6 @@ static void enable_clock_gating(void) #if CONFIG(HAVE_SMI_HANDLER) static void i82801ix_lock_smm(struct device *dev) { -#if TEST_SMM_FLASH_LOCKDOWN - u8 reg8; -#endif - if (!acpi_is_wakeup_s3()) { #if ENABLE_ACPI_MODE_IN_COREBOOT printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n"); @@ -393,33 +388,6 @@ static void i82801ix_lock_smm(struct device *dev) */ if (!CONFIG(PARALLEL_MP)) smm_lock(); - -#if TEST_SMM_FLASH_LOCKDOWN - /* Now try this: */ - printk(BIOS_DEBUG, "Locking BIOS to RO... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - reg8 &= ~(1 << 0); /* clear BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - reg8 |= (1 << 1); /* set BLE */ - pci_write_config8(dev, 0xdc, reg8); - printk(BIOS_DEBUG, "ok.\n"); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - - printk(BIOS_DEBUG, "Writing:\n"); - *(volatile u8 *)0xfff00000 = 0x00; - printk(BIOS_DEBUG, "Testing:\n"); - reg8 |= (1 << 0); /* set BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - printk(BIOS_DEBUG, "Done.\n"); -#endif } #endif diff --git a/src/southbridge/intel/i82801jx/lpc.c b/src/southbridge/intel/i82801jx/lpc.c index abfe6659891..5373ba2022e 100644 --- a/src/southbridge/intel/i82801jx/lpc.c +++ b/src/southbridge/intel/i82801jx/lpc.c @@ -40,7 +40,6 @@ #define NMI_OFF 0 #define ENABLE_ACPI_MODE_IN_COREBOOT 0 -#define TEST_SMM_FLASH_LOCKDOWN 0 typedef struct southbridge_intel_i82801jx_config config_t; @@ -375,10 +374,6 @@ static void enable_clock_gating(void) #if CONFIG(HAVE_SMI_HANDLER) static void i82801jx_lock_smm(struct device *dev) { -#if TEST_SMM_FLASH_LOCKDOWN - u8 reg8; -#endif - if (!acpi_is_wakeup_s3()) { #if ENABLE_ACPI_MODE_IN_COREBOOT printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n"); @@ -393,33 +388,6 @@ static void i82801jx_lock_smm(struct device *dev) printk(BIOS_DEBUG, "S3 wakeup, enabling ACPI via APMC\n"); outb(APM_CNT_ACPI_ENABLE, APM_CNT); } - -#if TEST_SMM_FLASH_LOCKDOWN - /* Now try this: */ - printk(BIOS_DEBUG, "Locking BIOS to RO... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - reg8 &= ~(1 << 0); /* clear BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - reg8 |= (1 << 1); /* set BLE */ - pci_write_config8(dev, 0xdc, reg8); - printk(BIOS_DEBUG, "ok.\n"); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - - printk(BIOS_DEBUG, "Writing:\n"); - *(volatile u8 *)0xfff00000 = 0x00; - printk(BIOS_DEBUG, "Testing:\n"); - reg8 |= (1 << 0); /* set BIOSWE */ - pci_write_config8(dev, 0xdc, reg8); - - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ - printk(BIOS_DEBUG, " BLE: %s; BWE: %s\n", (reg8&2)?"on":"off", - (reg8&1)?"rw":"ro"); - printk(BIOS_DEBUG, "Done.\n"); -#endif } #endif diff --git a/src/southbridge/intel/ibexpeak/lpc.c b/src/southbridge/intel/ibexpeak/lpc.c index f4464f3b4dc..e7162b1e04b 100644 --- a/src/southbridge/intel/ibexpeak/lpc.c +++ b/src/southbridge/intel/ibexpeak/lpc.c @@ -451,9 +451,9 @@ static void pch_disable_smm_only_flashing(struct device *dev) u8 reg8; printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = pci_read_config8(dev, BIOS_CNTL); reg8 &= ~(1 << 5); - pci_write_config8(dev, 0xdc, reg8); + pci_write_config8(dev, BIOS_CNTL, reg8); } static void pch_fixups(struct device *dev) diff --git a/src/southbridge/intel/lynxpoint/lpc.c b/src/southbridge/intel/lynxpoint/lpc.c index 951c69c11c5..b0f57c122bb 100644 --- a/src/southbridge/intel/lynxpoint/lpc.c +++ b/src/southbridge/intel/lynxpoint/lpc.c @@ -510,9 +510,9 @@ static void pch_disable_smm_only_flashing(struct device *dev) u8 reg8; printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... "); - reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */ + reg8 = pci_read_config8(dev, BIOS_CNTL); reg8 &= ~(1 << 5); - pci_write_config8(dev, 0xdc, reg8); + pci_write_config8(dev, BIOS_CNTL, reg8); } static void pch_fixups(struct device *dev) From 8dd518969cf02e37412019e4a6a4a5ce496da8c0 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 12 May 2019 11:27:17 +0200 Subject: [PATCH 288/588] soc/intel/{cannonlake,icelake}: Drop unused cbmem.c file Change-Id: Ib9444f7797289c9b8250cfb16eb1c12dff867ec3 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32756 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Subrata Banik Reviewed-by: Furquan Shaikh --- src/soc/intel/cannonlake/cbmem.c | 22 ---------------------- src/soc/intel/icelake/cbmem.c | 22 ---------------------- 2 files changed, 44 deletions(-) delete mode 100644 src/soc/intel/cannonlake/cbmem.c delete mode 100644 src/soc/intel/icelake/cbmem.c diff --git a/src/soc/intel/cannonlake/cbmem.c b/src/soc/intel/cannonlake/cbmem.c deleted file mode 100644 index 300556a45f5..00000000000 --- a/src/soc/intel/cannonlake/cbmem.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2017 Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include - -void *cbmem_top(void) -{ - /* not implemented yet */ - return (void *) NULL; -} diff --git a/src/soc/intel/icelake/cbmem.c b/src/soc/intel/icelake/cbmem.c deleted file mode 100644 index 4f447773ac9..00000000000 --- a/src/soc/intel/icelake/cbmem.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2018 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include - -void *cbmem_top(void) -{ - /* not implemented yet */ - return (void *) NULL; -} From 11a5b6b577d5e4c2611ac80dd0b7f761b80f942f Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 12 May 2019 09:33:14 +0200 Subject: [PATCH 289/588] i82801gx/bootblock: Use macro instead of magic number Change-Id: I2556c150f53d9580bc3b70ab49b3a2c8477c18ea Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32755 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/southbridge/intel/i82801gx/bootblock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/southbridge/intel/i82801gx/bootblock.c b/src/southbridge/intel/i82801gx/bootblock.c index 426973fc2f3..9d94d0cd257 100644 --- a/src/southbridge/intel/i82801gx/bootblock.c +++ b/src/southbridge/intel/i82801gx/bootblock.c @@ -23,10 +23,10 @@ static void enable_spi_prefetch(void) dev = PCI_DEV(0, 0x1f, 0); - reg8 = pci_read_config8(dev, 0xdc); + reg8 = pci_read_config8(dev, BIOS_CNTL); reg8 &= ~(3 << 2); reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ - pci_write_config8(dev, 0xdc, reg8); + pci_write_config8(dev, BIOS_CNTL, reg8); } static void bootblock_southbridge_init(void) From e429d86655171326db127a5ca9b8b597a291eae2 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 10 May 2019 15:21:40 -0700 Subject: [PATCH 290/588] 3rdparty: Uprev vboot submodule to upstream master This patch uprevs the vboot submodule to the new upstream HEAD commit dac763c782 Make vboot -Wtype-limits compliant Change-Id: I363e218e019b25483bc4c06315ca4e0e34599daf Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32748 Tested-by: build bot (Jenkins) Reviewed-by: Joel Kitching Reviewed-by: Patrick Georgi --- 3rdparty/vboot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/vboot b/3rdparty/vboot index e7edff6653e..dac763c782c 160000 --- a/3rdparty/vboot +++ b/3rdparty/vboot @@ -1 +1 @@ -Subproject commit e7edff6653e16ed915c3ad12234d133d1ef4dcc9 +Subproject commit dac763c782ce05476dec02e855f349d2b6f3a910 From c15e600490fcc0e7da2a4495b233a4f9c62c8cd1 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 10 May 2019 06:56:18 +0200 Subject: [PATCH 291/588] crossgcc: Upgrade acpica to version 20190509 Changes: https://acpica.org/node/170 Change-Id: I6779a20005ffc0d4781bb60de3ba48759ef67d40 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32721 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Paul Menzel --- util/crossgcc/buildgcc | 2 +- ...20190215_iasl.patch => acpica-unix2-20190509_iasl.patch} | 6 +++--- util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum | 1 - util/crossgcc/sum/acpica-unix2-20190509.tar.gz.cksum | 1 + 4 files changed, 5 insertions(+), 5 deletions(-) rename util/crossgcc/patches/{acpica-unix2-20190215_iasl.patch => acpica-unix2-20190509_iasl.patch} (73%) delete mode 100644 util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum create mode 100644 util/crossgcc/sum/acpica-unix2-20190509.tar.gz.cksum diff --git a/util/crossgcc/buildgcc b/util/crossgcc/buildgcc index 0951fb60e43..327027a565d 100755 --- a/util/crossgcc/buildgcc +++ b/util/crossgcc/buildgcc @@ -54,7 +54,7 @@ GCC_VERSION=8.3.0 GCC_AUTOCONF_VERSION=2.69 BINUTILS_VERSION=2.32 GDB_VERSION=8.2.1 -IASL_VERSION=20190215 +IASL_VERSION=20190509 PYTHON_VERSION=3.7.2 EXPAT_VERSION=2.2.6 # CLANG version number diff --git a/util/crossgcc/patches/acpica-unix2-20190215_iasl.patch b/util/crossgcc/patches/acpica-unix2-20190509_iasl.patch similarity index 73% rename from util/crossgcc/patches/acpica-unix2-20190215_iasl.patch rename to util/crossgcc/patches/acpica-unix2-20190509_iasl.patch index c4f605292be..49df22510fd 100644 --- a/util/crossgcc/patches/acpica-unix2-20190215_iasl.patch +++ b/util/crossgcc/patches/acpica-unix2-20190509_iasl.patch @@ -1,6 +1,6 @@ -diff -Naur acpica-unix2-20190215_/source/compiler/asloptions.c acpica-unix2-20190215/source/compiler/asloptions.c > acpica-unix2-20190215_iasl.patch ---- acpica-unix2-20190108_/source/compiler/asloptions.c -+++ acpica-unix2-20190108/source/compiler/asloptions.c +diff -Naur acpica-unix2-20190509_/source/compiler/asloptions.c acpica-unix2-20190509/source/compiler/asloptions.c > acpica-unix2-20190509_iasl.patch +--- acpica-unix2-20190509_/source/compiler/asloptions.c ++++ acpica-unix2-20190509/source/compiler/asloptions.c @@ -126,6 +126,7 @@ if (Gbl_DoSignon) { diff --git a/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum deleted file mode 100644 index 310454d6030..00000000000 --- a/util/crossgcc/sum/acpica-unix2-20190215.tar.gz.cksum +++ /dev/null @@ -1 +0,0 @@ -82d729cb09edc50ee11669651683ca5a5c0f4d5a tarballs/acpica-unix2-20190215.tar.gz diff --git a/util/crossgcc/sum/acpica-unix2-20190509.tar.gz.cksum b/util/crossgcc/sum/acpica-unix2-20190509.tar.gz.cksum new file mode 100644 index 00000000000..2f53d714fbc --- /dev/null +++ b/util/crossgcc/sum/acpica-unix2-20190509.tar.gz.cksum @@ -0,0 +1 @@ +aa4d4f8051800e84a5ed5b71635594aaca749e8d tarballs/acpica-unix2-20190509.tar.gz From 795fda033656982a8aeef0e105bcfbc9a73c8c13 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 10 May 2019 15:23:22 -0700 Subject: [PATCH 292/588] Reland "Makefile.inc: Enable -Wtype-limits"" This reverts commit 99e836c843e6a8536348d5cc9581b5a17512a263. This relands commit c4ab50cdde4bfd01ec7509012b105c88bcf4c953. The issues with -Wtype-limits in the vboot submodule have been resolved now, so we can enable this flag again. Change-Id: I32e8cc88e69072e7ee66cf443b578a9a8ea0ebe2 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32749 Tested-by: build bot (Jenkins) Reviewed-by: Joel Kitching --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index a9aaaed783b..9860da1b681 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -401,7 +401,7 @@ endif CFLAGS_common += -pipe -g -nostdinc -std=gnu11 CFLAGS_common += -nostdlib -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes CFLAGS_common += -Wwrite-strings -Wredundant-decls -Wno-trigraphs -CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time +CFLAGS_common += -Wstrict-aliasing -Wshadow -Wdate-time -Wtype-limits CFLAGS_common += -fno-common -ffreestanding -fno-builtin -fomit-frame-pointer CFLAGS_common += -ffunction-sections -fdata-sections -fno-pie ifeq ($(CONFIG_COMPILER_GCC),y) From 55cb5f8de53366c9df10ed9307cc9088c96191cf Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 13 May 2019 12:49:16 +0530 Subject: [PATCH 293/588] Remove unnecessary ENV_RAMSTAGE guard TEST=Able to build coreboot for CML. Change-Id: Ic0f473e04ffc1de50dee871af52eacf0b328b376 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32764 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/arch/x86/include/arch/acpi.h | 2 -- src/console/post.c | 2 -- src/drivers/uart/uart8250io.c | 2 -- src/drivers/uart/uart8250mem.c | 2 -- src/lib/bootmode.c | 2 -- 5 files changed, 10 deletions(-) diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 79feaad0702..60efdd0d7a7 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -838,14 +838,12 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs, unsigned long (*acpi_fill_ivrs)(acpi_ivrs_t *ivrs_struct, unsigned long current)); -#if ENV_RAMSTAGE && !defined(__SIMPLE_DEVICE__) void acpi_create_hpet(acpi_hpet_t *hpet); unsigned long acpi_write_hpet(struct device *device, unsigned long start, acpi_rsdp_t *rsdp); /* cpu/intel/speedstep/acpi.c */ void generate_cpu_entries(struct device *device); -#endif void acpi_create_mcfg(acpi_mcfg_t *mcfg); diff --git a/src/console/post.c b/src/console/post.c index 236aa8cdaad..b17a819d971 100644 --- a/src/console/post.c +++ b/src/console/post.c @@ -44,7 +44,6 @@ void __weak mainboard_post(uint8_t value) DECLARE_SPIN_LOCK(cmos_post_lock) -#if ENV_RAMSTAGE void cmos_post_log(void) { u8 code = 0; @@ -125,7 +124,6 @@ void post_log_clear(void) post_log_extra(0); } #endif /* CONFIG_CMOS_POST_EXTRA */ -#endif /* ENV_RAMSTAGE */ static void cmos_post_code(u8 value) { diff --git a/src/drivers/uart/uart8250io.c b/src/drivers/uart/uart8250io.c index 62671e2b6f4..614a849f7a4 100644 --- a/src/drivers/uart/uart8250io.c +++ b/src/drivers/uart/uart8250io.c @@ -124,7 +124,6 @@ void uart_tx_flush(int idx) uart8250_tx_flush(uart_platform_base(idx)); } -#if ENV_RAMSTAGE void uart_fill_lb(void *data) { struct lb_serial serial; @@ -138,4 +137,3 @@ void uart_fill_lb(void *data) lb_add_console(LB_TAG_CONSOLE_SERIAL8250, data); } -#endif diff --git a/src/drivers/uart/uart8250mem.c b/src/drivers/uart/uart8250mem.c index c3dff6a72ce..a5aa74a3325 100644 --- a/src/drivers/uart/uart8250mem.c +++ b/src/drivers/uart/uart8250mem.c @@ -147,7 +147,6 @@ void uart_tx_flush(int idx) uart8250_mem_tx_flush(base); } -#if ENV_RAMSTAGE void uart_fill_lb(void *data) { struct lb_serial serial; @@ -166,4 +165,3 @@ void uart_fill_lb(void *data) lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data); } -#endif diff --git a/src/lib/bootmode.c b/src/lib/bootmode.c index 18f6d5dcac4..737dcf93d04 100644 --- a/src/lib/bootmode.c +++ b/src/lib/bootmode.c @@ -17,7 +17,6 @@ #include #include -#if ENV_RAMSTAGE static int gfx_init_done = -1; int gfx_get_init_done(void) @@ -31,7 +30,6 @@ void gfx_set_init_done(int done) { gfx_init_done = done; } -#endif int display_init_required(void) { From 57459dbeacb4759c3352206464b6c19b7add00d5 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 14:11:00 +0200 Subject: [PATCH 294/588] mb/{lenovo/x201,packardbell/ms2290}: Remove superfluous TS init Timestamps are initialized in cpu/intel/car/romstage.c. Change-Id: Ia2b762667be17aa5b482cd585dd6f6198cf50d9e Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32758 Reviewed-by: Nico Huber Reviewed-by: Alexander Couzens Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/x201/romstage.c | 4 ---- src/mainboard/packardbell/ms2290/romstage.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c index 7e895b46f0f..ae154e25b10 100644 --- a/src/mainboard/lenovo/x201/romstage.c +++ b/src/mainboard/lenovo/x201/romstage.c @@ -175,10 +175,6 @@ void mainboard_romstage_entry(unsigned long bist) int s3resume = 0; const u8 spd_addrmap[4] = { 0x50, 0, 0x51, 0 }; - timestamp_init(timestamp_get()); - - timestamp_add_now(TS_START_ROMSTAGE); - if (bist == 0) enable_lapic(); diff --git a/src/mainboard/packardbell/ms2290/romstage.c b/src/mainboard/packardbell/ms2290/romstage.c index 8442dfaee90..efaa9e423d1 100644 --- a/src/mainboard/packardbell/ms2290/romstage.c +++ b/src/mainboard/packardbell/ms2290/romstage.c @@ -168,14 +168,10 @@ void mainboard_romstage_entry(unsigned long bist) int s3resume = 0; const u8 spd_addrmap[4] = { 0x50, 0, 0x52, 0 }; - timestamp_init(timestamp_get()); - /* SERR pin is confused on reset. Clear NMI. */ outb(4, 0x61); outb(0, 0x61); - timestamp_add_now(TS_START_ROMSTAGE); - if (bist == 0) enable_lapic(); From cadc70f7974db25144381b3ea26d4b660233f4dd Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 13:44:22 +0200 Subject: [PATCH 295/588] soc/intel/broadwell: Move GPIO init to a common place This also links the gpio configuration instead of including it as a header. Change-Id: I9309d2b842495f6cff33fdab18aa139a82c1959c Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32759 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Matt DeVillier --- src/mainboard/google/auron/Makefile.inc | 2 ++ src/mainboard/google/auron/romstage.c | 5 ----- .../include/variant/gpio.h => auron_paine/gpio.c} | 7 +------ src/mainboard/google/auron/variants/auron_paine/spd/spd.c | 1 - .../include/variant/gpio.h => auron_yuna/gpio.c} | 7 +------ src/mainboard/google/auron/variants/auron_yuna/spd/spd.c | 1 - .../variants/buddy/{include/variant/gpio.h => gpio.c} | 7 +------ .../variants/gandof/{include/variant/gpio.h => gpio.c} | 7 +------ src/mainboard/google/auron/variants/gandof/spd/spd.c | 1 - .../auron/variants/lulu/{include/variant/gpio.h => gpio.c} | 7 +------ src/mainboard/google/auron/variants/lulu/spd/spd.c | 1 - .../variants/samus/{include/variant/gpio.h => gpio.c} | 7 +------ src/mainboard/google/auron/variants/samus/spd/spd.c | 1 - src/mainboard/google/jecht/Makefile.inc | 2 ++ src/mainboard/google/jecht/romstage.c | 5 ----- .../variants/guado/{include/variant/gpio.h => gpio.c} | 7 +------ .../variants/jecht/{include/variant/gpio.h => gpio.c} | 7 +------ .../variants/rikku/{include/variant/gpio.h => gpio.c} | 7 +------ .../variants/tidus/{include/variant/gpio.h => gpio.c} | 7 +------ src/mainboard/intel/wtm2/Makefile.inc | 2 ++ src/mainboard/intel/wtm2/{gpio.h => gpio.c} | 7 +------ src/mainboard/intel/wtm2/romstage.c | 4 ---- src/mainboard/purism/librem_bdw/Makefile.inc | 1 + src/mainboard/purism/librem_bdw/{gpio.h => gpio.c} | 7 +------ src/mainboard/purism/librem_bdw/romstage.c | 5 ----- src/soc/intel/broadwell/include/soc/gpio.h | 2 ++ src/soc/intel/broadwell/romstage/romstage.c | 4 ++++ 27 files changed, 25 insertions(+), 96 deletions(-) rename src/mainboard/google/auron/variants/{auron_yuna/include/variant/gpio.h => auron_paine/gpio.c} (97%) rename src/mainboard/google/auron/variants/{auron_paine/include/variant/gpio.h => auron_yuna/gpio.c} (97%) rename src/mainboard/google/auron/variants/buddy/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/auron/variants/gandof/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/auron/variants/lulu/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/auron/variants/samus/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/jecht/variants/guado/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/jecht/variants/jecht/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/jecht/variants/rikku/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/google/jecht/variants/tidus/{include/variant/gpio.h => gpio.c} (97%) rename src/mainboard/intel/wtm2/{gpio.h => gpio.c} (97%) rename src/mainboard/purism/librem_bdw/{gpio.h => gpio.c} (96%) diff --git a/src/mainboard/google/auron/Makefile.inc b/src/mainboard/google/auron/Makefile.inc index 170e1686da6..c81aeaf0f6e 100644 --- a/src/mainboard/google/auron/Makefile.inc +++ b/src/mainboard/google/auron/Makefile.inc @@ -32,3 +32,5 @@ subdirs-y += variants/$(VARIANT_DIR) subdirs-y += variants/$(VARIANT_DIR)/spd CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include + +romstage-y += variants/$(VARIANT_DIR)/gpio.c diff --git a/src/mainboard/google/auron/romstage.c b/src/mainboard/google/auron/romstage.c index aea8e211fab..5e1a66ac244 100644 --- a/src/mainboard/google/auron/romstage.c +++ b/src/mainboard/google/auron/romstage.c @@ -17,11 +17,9 @@ #include #include #include -#include #include #include #include -#include #include #include "variant.h" @@ -35,9 +33,6 @@ void mainboard_romstage_entry(struct romstage_params *rp) post_code(0x32); - /* Initialize GPIOs */ - init_gpios(mainboard_gpio_config); - /* Fill out PEI DATA */ memset(&pei_data, 0, sizeof(pei_data)); mainboard_fill_pei_data(&pei_data); diff --git a/src/mainboard/google/auron/variants/auron_yuna/include/variant/gpio.h b/src/mainboard/google/auron/variants/auron_paine/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/auron_yuna/include/variant/gpio.h rename to src/mainboard/google/auron/variants/auron_paine/gpio.c index eca65d14fc6..e8b6c065b18 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/auron_paine/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef AURON_YUNA_GPIO_H -#define AURON_YUNA_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/auron_paine/spd/spd.c b/src/mainboard/google/auron/variants/auron_paine/spd/spd.c index 12c876e61b9..2991d15eff4 100644 --- a/src/mainboard/google/auron/variants/auron_paine/spd/spd.c +++ b/src/mainboard/google/auron/variants/auron_paine/spd/spd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static void mainboard_print_spd_info(uint8_t spd[]) diff --git a/src/mainboard/google/auron/variants/auron_paine/include/variant/gpio.h b/src/mainboard/google/auron/variants/auron_yuna/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/auron_paine/include/variant/gpio.h rename to src/mainboard/google/auron/variants/auron_yuna/gpio.c index 44b930a4419..e8b6c065b18 100644 --- a/src/mainboard/google/auron/variants/auron_paine/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/auron_yuna/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef AURON_PAINE_GPIO_H -#define AURON_PAINE_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/auron_yuna/spd/spd.c b/src/mainboard/google/auron/variants/auron_yuna/spd/spd.c index 12c876e61b9..2991d15eff4 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/spd/spd.c +++ b/src/mainboard/google/auron/variants/auron_yuna/spd/spd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static void mainboard_print_spd_info(uint8_t spd[]) diff --git a/src/mainboard/google/auron/variants/buddy/include/variant/gpio.h b/src/mainboard/google/auron/variants/buddy/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/buddy/include/variant/gpio.h rename to src/mainboard/google/auron/variants/buddy/gpio.c index efa720f60df..fbb682abf97 100644 --- a/src/mainboard/google/auron/variants/buddy/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/buddy/gpio.c @@ -14,12 +14,9 @@ * GNU General Public License for more details. */ -#ifndef BUDDY_GPIO_H -#define BUDDY_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -117,5 +114,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/gandof/include/variant/gpio.h b/src/mainboard/google/auron/variants/gandof/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/gandof/include/variant/gpio.h rename to src/mainboard/google/auron/variants/gandof/gpio.c index 68fe4a01906..3de9a0b9d7a 100644 --- a/src/mainboard/google/auron/variants/gandof/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/gandof/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef GANDOF_GPIO_H -#define GANDOF_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/gandof/spd/spd.c b/src/mainboard/google/auron/variants/gandof/spd/spd.c index 12c876e61b9..2991d15eff4 100644 --- a/src/mainboard/google/auron/variants/gandof/spd/spd.c +++ b/src/mainboard/google/auron/variants/gandof/spd/spd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static void mainboard_print_spd_info(uint8_t spd[]) diff --git a/src/mainboard/google/auron/variants/lulu/include/variant/gpio.h b/src/mainboard/google/auron/variants/lulu/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/lulu/include/variant/gpio.h rename to src/mainboard/google/auron/variants/lulu/gpio.c index 726dcc755e8..a46c4d4e2ac 100644 --- a/src/mainboard/google/auron/variants/lulu/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/lulu/gpio.c @@ -14,12 +14,9 @@ * GNU General Public License for more details. */ -#ifndef LULU_GPIO_H -#define LULU_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -117,5 +114,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/lulu/spd/spd.c b/src/mainboard/google/auron/variants/lulu/spd/spd.c index ac99f5c7bc3..bd76947d688 100644 --- a/src/mainboard/google/auron/variants/lulu/spd/spd.c +++ b/src/mainboard/google/auron/variants/lulu/spd/spd.c @@ -23,7 +23,6 @@ #include #include #include -#include #include static void mainboard_print_spd_info(uint8_t spd[]) diff --git a/src/mainboard/google/auron/variants/samus/include/variant/gpio.h b/src/mainboard/google/auron/variants/samus/gpio.c similarity index 97% rename from src/mainboard/google/auron/variants/samus/include/variant/gpio.h rename to src/mainboard/google/auron/variants/samus/gpio.c index 8362a4dbfbe..72ddcb2259e 100644 --- a/src/mainboard/google/auron/variants/samus/include/variant/gpio.h +++ b/src/mainboard/google/auron/variants/samus/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef SAMUS_GPIO_H -#define SAMUS_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/auron/variants/samus/spd/spd.c b/src/mainboard/google/auron/variants/samus/spd/spd.c index dd632f30d73..ffb90f997d6 100644 --- a/src/mainboard/google/auron/variants/samus/spd/spd.c +++ b/src/mainboard/google/auron/variants/samus/spd/spd.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static void mainboard_print_spd_info(uint8_t spd[]) diff --git a/src/mainboard/google/jecht/Makefile.inc b/src/mainboard/google/jecht/Makefile.inc index 01914bae7d5..39e9b339e87 100644 --- a/src/mainboard/google/jecht/Makefile.inc +++ b/src/mainboard/google/jecht/Makefile.inc @@ -27,3 +27,5 @@ romstage-y += led.c subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include + +romstage-y += variants/$(VARIANT_DIR)/gpio.c diff --git a/src/mainboard/google/jecht/romstage.c b/src/mainboard/google/jecht/romstage.c index 3705feb28a2..de0ed305757 100644 --- a/src/mainboard/google/jecht/romstage.c +++ b/src/mainboard/google/jecht/romstage.c @@ -18,14 +18,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include "onboard.h" @@ -35,9 +33,6 @@ void mainboard_romstage_entry(struct romstage_params *rp) post_code(0x32); - /* Initialize GPIOs */ - init_gpios(mainboard_gpio_config); - /* Fill out PEI DATA */ memset(&pei_data, 0, sizeof(pei_data)); mainboard_fill_pei_data(&pei_data); diff --git a/src/mainboard/google/jecht/variants/guado/include/variant/gpio.h b/src/mainboard/google/jecht/variants/guado/gpio.c similarity index 97% rename from src/mainboard/google/jecht/variants/guado/include/variant/gpio.h rename to src/mainboard/google/jecht/variants/guado/gpio.c index 4c167e3a589..60e769dbd01 100644 --- a/src/mainboard/google/jecht/variants/guado/include/variant/gpio.h +++ b/src/mainboard/google/jecht/variants/guado/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef GUADO_GPIO_H -#define GUADO_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/jecht/variants/jecht/include/variant/gpio.h b/src/mainboard/google/jecht/variants/jecht/gpio.c similarity index 97% rename from src/mainboard/google/jecht/variants/jecht/include/variant/gpio.h rename to src/mainboard/google/jecht/variants/jecht/gpio.c index 94e6516ce70..6a2a64cd7b6 100644 --- a/src/mainboard/google/jecht/variants/jecht/include/variant/gpio.h +++ b/src/mainboard/google/jecht/variants/jecht/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef JECHT_GPIO_H -#define JECHT_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/jecht/variants/rikku/include/variant/gpio.h b/src/mainboard/google/jecht/variants/rikku/gpio.c similarity index 97% rename from src/mainboard/google/jecht/variants/rikku/include/variant/gpio.h rename to src/mainboard/google/jecht/variants/rikku/gpio.c index f58ad24f674..bc065a03a15 100644 --- a/src/mainboard/google/jecht/variants/rikku/include/variant/gpio.h +++ b/src/mainboard/google/jecht/variants/rikku/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef RIKKU_GPIO_H -#define RIKKU_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/google/jecht/variants/tidus/include/variant/gpio.h b/src/mainboard/google/jecht/variants/tidus/gpio.c similarity index 97% rename from src/mainboard/google/jecht/variants/tidus/include/variant/gpio.h rename to src/mainboard/google/jecht/variants/tidus/gpio.c index 846fe816d4f..78aa1776791 100644 --- a/src/mainboard/google/jecht/variants/tidus/include/variant/gpio.h +++ b/src/mainboard/google/jecht/variants/tidus/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef TIDUS_GPIO_H -#define TIDUS_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 0: UNUSED */ PCH_GPIO_UNUSED, /* 1: UNUSED */ PCH_GPIO_UNUSED, /* 2: UNUSED */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_UNUSED, /* 94: UNUSED */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/intel/wtm2/Makefile.inc b/src/mainboard/intel/wtm2/Makefile.inc index 16137462c92..4c944f2773d 100644 --- a/src/mainboard/intel/wtm2/Makefile.inc +++ b/src/mainboard/intel/wtm2/Makefile.inc @@ -13,6 +13,8 @@ ## GNU General Public License for more details. ## +romstage-y += gpio.c + romstage-y += chromeos.c ramstage-y += chromeos.c diff --git a/src/mainboard/intel/wtm2/gpio.h b/src/mainboard/intel/wtm2/gpio.c similarity index 97% rename from src/mainboard/intel/wtm2/gpio.h rename to src/mainboard/intel/wtm2/gpio.c index 9e6f2e64455..c81ad100817 100644 --- a/src/mainboard/intel/wtm2/gpio.h +++ b/src/mainboard/intel/wtm2/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef INTEL_WTM2_GPIO_H -#define INTEL_WTM2_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_NATIVE, /* 0: LPSS_UART1_RXD */ PCH_GPIO_NATIVE, /* 1: LPSS_UART1_TXD */ PCH_GPIO_NATIVE, /* 2: LPSS_UART1_RTS_N_R */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_NATIVE, /* 94: LPSS_UART0_CTS_N */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/intel/wtm2/romstage.c b/src/mainboard/intel/wtm2/romstage.c index 3c9bb363638..de4237d222a 100644 --- a/src/mainboard/intel/wtm2/romstage.c +++ b/src/mainboard/intel/wtm2/romstage.c @@ -21,7 +21,6 @@ #include #include #include -#include "gpio.h" void mainboard_romstage_entry(struct romstage_params *rp) { @@ -29,9 +28,6 @@ void mainboard_romstage_entry(struct romstage_params *rp) post_code(0x32); - /* Initialize GPIOs */ - init_gpios(mainboard_gpio_config); - /* Fill out PEI DATA */ memset(&pei_data, 0, sizeof(pei_data)); mainboard_fill_pei_data(&pei_data); diff --git a/src/mainboard/purism/librem_bdw/Makefile.inc b/src/mainboard/purism/librem_bdw/Makefile.inc index 293e186cec6..16ce37a95f8 100644 --- a/src/mainboard/purism/librem_bdw/Makefile.inc +++ b/src/mainboard/purism/librem_bdw/Makefile.inc @@ -13,5 +13,6 @@ ## GNU General Public License for more details. ## +romstage-y += gpio.c romstage-y += variants/$(VARIANT_DIR)/pei_data.c ramstage-y += variants/$(VARIANT_DIR)/pei_data.c diff --git a/src/mainboard/purism/librem_bdw/gpio.h b/src/mainboard/purism/librem_bdw/gpio.c similarity index 96% rename from src/mainboard/purism/librem_bdw/gpio.h rename to src/mainboard/purism/librem_bdw/gpio.c index 98b09bc45ad..510299659e5 100644 --- a/src/mainboard/purism/librem_bdw/gpio.h +++ b/src/mainboard/purism/librem_bdw/gpio.c @@ -13,12 +13,9 @@ * GNU General Public License for more details. */ -#ifndef MAINBOARD_GPIO_H -#define MAINBOARD_GPIO_H - #include -static const struct gpio_config mainboard_gpio_config[] = { +const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_INPUT, /* 0 */ PCH_GPIO_INPUT, /* 1 */ PCH_GPIO_INPUT, /* 2 */ @@ -116,5 +113,3 @@ static const struct gpio_config mainboard_gpio_config[] = { PCH_GPIO_INPUT, /* 94 */ PCH_GPIO_END }; - -#endif diff --git a/src/mainboard/purism/librem_bdw/romstage.c b/src/mainboard/purism/librem_bdw/romstage.c index 2e0ae85b95b..65912296215 100644 --- a/src/mainboard/purism/librem_bdw/romstage.c +++ b/src/mainboard/purism/librem_bdw/romstage.c @@ -14,19 +14,14 @@ */ #include -#include #include #include #include -#include "gpio.h" void mainboard_romstage_entry(struct romstage_params *rp) { struct pei_data pei_data; - /* Initialize GPIOs */ - init_gpios(mainboard_gpio_config); - /* Fill out PEI DATA */ memset(&pei_data, 0, sizeof(pei_data)); mainboard_fill_pei_data(&pei_data); diff --git a/src/soc/intel/broadwell/include/soc/gpio.h b/src/soc/intel/broadwell/include/soc/gpio.h index 66820b21845..c0ac13497bc 100644 --- a/src/soc/intel/broadwell/include/soc/gpio.h +++ b/src/soc/intel/broadwell/include/soc/gpio.h @@ -193,4 +193,6 @@ int gpio_is_native(int gpio_num); */ unsigned int get_gpios(const int *gpio_num_array); +extern const struct gpio_config mainboard_gpio_config[]; + #endif diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 2531665f1fb..7847829ac6e 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -100,6 +101,9 @@ static void romstage_main(uint64_t tsc, uint32_t bist) /* Set CPU frequency to maximum */ set_max_freq(); + /* Initialize GPIOs */ + init_gpios(mainboard_gpio_config); + /* Call into mainboard. */ mainboard_romstage_entry(&rp); From 325865db5683f32d846cc452504da00ec8d53710 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 15:25:54 +0200 Subject: [PATCH 296/588] soc/intel/broadwell: Don't use a pointer for pei_data To improve the bootflow, the scope of the pei_data needs to be extended. Change-Id: Ic6d91692a7bf9218b81da5bb36b5b26dabac454e Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32762 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Matt DeVillier --- src/mainboard/google/auron/romstage.c | 8 ++------ src/mainboard/google/jecht/romstage.c | 8 ++------ src/mainboard/intel/wtm2/romstage.c | 6 +----- src/mainboard/purism/librem_bdw/romstage.c | 6 +----- src/soc/intel/broadwell/include/soc/romstage.h | 4 ++-- src/soc/intel/broadwell/romstage/romstage.c | 5 ++--- 6 files changed, 10 insertions(+), 27 deletions(-) diff --git a/src/mainboard/google/auron/romstage.c b/src/mainboard/google/auron/romstage.c index 5e1a66ac244..497489911e2 100644 --- a/src/mainboard/google/auron/romstage.c +++ b/src/mainboard/google/auron/romstage.c @@ -29,15 +29,11 @@ __weak void variant_romstage_entry(struct romstage_params *rp) void mainboard_romstage_entry(struct romstage_params *rp) { - struct pei_data pei_data; - post_code(0x32); /* Fill out PEI DATA */ - memset(&pei_data, 0, sizeof(pei_data)); - mainboard_fill_pei_data(&pei_data); - mainboard_fill_spd_data(&pei_data); - rp->pei_data = &pei_data; + mainboard_fill_pei_data(&rp->pei_data); + mainboard_fill_spd_data(&rp->pei_data); /* Call into the real romstage main with this board's attributes. */ romstage_common(rp); diff --git a/src/mainboard/google/jecht/romstage.c b/src/mainboard/google/jecht/romstage.c index de0ed305757..8d1ae8aca2a 100644 --- a/src/mainboard/google/jecht/romstage.c +++ b/src/mainboard/google/jecht/romstage.c @@ -29,15 +29,11 @@ void mainboard_romstage_entry(struct romstage_params *rp) { - struct pei_data pei_data; - post_code(0x32); /* Fill out PEI DATA */ - memset(&pei_data, 0, sizeof(pei_data)); - mainboard_fill_pei_data(&pei_data); - mainboard_fill_spd_data(&pei_data); - rp->pei_data = &pei_data; + mainboard_fill_pei_data(&rp->pei_data); + mainboard_fill_spd_data(&rp->pei_data); /* Call into the real romstage main with this board's attributes. */ romstage_common(rp); diff --git a/src/mainboard/intel/wtm2/romstage.c b/src/mainboard/intel/wtm2/romstage.c index de4237d222a..5b8df275d88 100644 --- a/src/mainboard/intel/wtm2/romstage.c +++ b/src/mainboard/intel/wtm2/romstage.c @@ -24,14 +24,10 @@ void mainboard_romstage_entry(struct romstage_params *rp) { - struct pei_data pei_data; - post_code(0x32); /* Fill out PEI DATA */ - memset(&pei_data, 0, sizeof(pei_data)); - mainboard_fill_pei_data(&pei_data); - rp->pei_data = &pei_data; + mainboard_fill_pei_data(&rp->pei_data); romstage_common(rp); } diff --git a/src/mainboard/purism/librem_bdw/romstage.c b/src/mainboard/purism/librem_bdw/romstage.c index 65912296215..5330d191b49 100644 --- a/src/mainboard/purism/librem_bdw/romstage.c +++ b/src/mainboard/purism/librem_bdw/romstage.c @@ -20,12 +20,8 @@ void mainboard_romstage_entry(struct romstage_params *rp) { - struct pei_data pei_data; - /* Fill out PEI DATA */ - memset(&pei_data, 0, sizeof(pei_data)); - mainboard_fill_pei_data(&pei_data); - rp->pei_data = &pei_data; + mainboard_fill_pei_data(&rp->pei_data); /* Initialize memory */ romstage_common(rp); diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index 31184f9a02f..46f29d62df5 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -18,13 +18,13 @@ #include #include +#include struct chipset_power_state; -struct pei_data; struct romstage_params { unsigned long bist; struct chipset_power_state *power_state; - struct pei_data *pei_data; + struct pei_data pei_data; }; void mainboard_romstage_entry(struct romstage_params *params); diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 7847829ac6e..2a3ac8b8e69 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -68,7 +68,6 @@ static void romstage_main(uint64_t tsc, uint32_t bist) { struct romstage_params rp = { .bist = bist, - .pei_data = NULL, }; post_code(0x30); @@ -125,7 +124,7 @@ void romstage_common(struct romstage_params *params) timestamp_add_now(TS_BEFORE_INITRAM); - params->pei_data->boot_mode = params->power_state->prev_sleep_state; + params->pei_data.boot_mode = params->power_state->prev_sleep_state; #if CONFIG(ELOG_BOOT_COUNT) if (params->power_state->prev_sleep_state != ACPI_S3) @@ -140,7 +139,7 @@ void romstage_common(struct romstage_params *params) ¶ms->power_state->hsio_checksum); /* Initialize RAM */ - raminit(params->pei_data); + raminit(¶ms->pei_data); timestamp_add_now(TS_AFTER_INITRAM); From 97e9e5622df8b2386b2828da2671018232056035 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 13:47:35 +0200 Subject: [PATCH 297/588] soc/intel/broadwell: Clean up the bootflow Call the raminit from a common location instead of from the mainboard specific code. Change-Id: I65d522237a0bb7b2c032536ede10e2cf93c134d8 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32760 Reviewed-by: Nico Huber Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/google/auron/romstage.c | 9 ++-- src/mainboard/google/jecht/romstage.c | 10 ++--- src/mainboard/intel/wtm2/romstage.c | 8 ++-- src/mainboard/purism/librem_bdw/romstage.c | 7 +-- .../intel/broadwell/include/soc/romstage.h | 4 +- src/soc/intel/broadwell/romstage/romstage.c | 45 +++++++++---------- 6 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/mainboard/google/auron/romstage.c b/src/mainboard/google/auron/romstage.c index 497489911e2..568c4c819c3 100644 --- a/src/mainboard/google/auron/romstage.c +++ b/src/mainboard/google/auron/romstage.c @@ -27,17 +27,16 @@ __weak void variant_romstage_entry(struct romstage_params *rp) { } -void mainboard_romstage_entry(struct romstage_params *rp) +void mainboard_pre_raminit(struct romstage_params *rp) { - post_code(0x32); - /* Fill out PEI DATA */ mainboard_fill_pei_data(&rp->pei_data); mainboard_fill_spd_data(&rp->pei_data); - /* Call into the real romstage main with this board's attributes. */ - romstage_common(rp); +} +void mainboard_post_raminit(struct romstage_params *rp) +{ /* Do variant-specific init */ variant_romstage_entry(rp); } diff --git a/src/mainboard/google/jecht/romstage.c b/src/mainboard/google/jecht/romstage.c index 8d1ae8aca2a..86888c82f88 100644 --- a/src/mainboard/google/jecht/romstage.c +++ b/src/mainboard/google/jecht/romstage.c @@ -27,17 +27,15 @@ #include "onboard.h" -void mainboard_romstage_entry(struct romstage_params *rp) +void mainboard_pre_raminit(struct romstage_params *rp) { - post_code(0x32); - /* Fill out PEI DATA */ mainboard_fill_pei_data(&rp->pei_data); mainboard_fill_spd_data(&rp->pei_data); +} - /* Call into the real romstage main with this board's attributes. */ - romstage_common(rp); - +void mainboard_post_raminit(struct romstage_params *rp) +{ if (CONFIG(CHROMEOS)) init_bootmode_straps(); } diff --git a/src/mainboard/intel/wtm2/romstage.c b/src/mainboard/intel/wtm2/romstage.c index 5b8df275d88..f4e336694db 100644 --- a/src/mainboard/intel/wtm2/romstage.c +++ b/src/mainboard/intel/wtm2/romstage.c @@ -22,12 +22,12 @@ #include #include -void mainboard_romstage_entry(struct romstage_params *rp) +void mainboard_pre_raminit(struct romstage_params *rp) { - post_code(0x32); - /* Fill out PEI DATA */ mainboard_fill_pei_data(&rp->pei_data); +} - romstage_common(rp); +void mainboard_post_raminit(struct romstage_params *rp) +{ } diff --git a/src/mainboard/purism/librem_bdw/romstage.c b/src/mainboard/purism/librem_bdw/romstage.c index 5330d191b49..0e1ad885b05 100644 --- a/src/mainboard/purism/librem_bdw/romstage.c +++ b/src/mainboard/purism/librem_bdw/romstage.c @@ -18,11 +18,12 @@ #include #include -void mainboard_romstage_entry(struct romstage_params *rp) +void mainboard_pre_raminit(struct romstage_params *rp) { /* Fill out PEI DATA */ mainboard_fill_pei_data(&rp->pei_data); +} - /* Initialize memory */ - romstage_common(rp); +void mainboard_post_raminit(struct romstage_params *rp) +{ } diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index 46f29d62df5..d65692ae23a 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -27,8 +27,8 @@ struct romstage_params { struct pei_data pei_data; }; -void mainboard_romstage_entry(struct romstage_params *params); -void romstage_common(struct romstage_params *params); +void mainboard_pre_raminit(struct romstage_params *params); +void mainboard_post_raminit(struct romstage_params *params); void raminit(struct pei_data *pei_data); diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 2a3ac8b8e69..acbca14a886 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -103,47 +103,44 @@ static void romstage_main(uint64_t tsc, uint32_t bist) /* Initialize GPIOs */ init_gpios(mainboard_gpio_config); - /* Call into mainboard. */ - mainboard_romstage_entry(&rp); + /* Fill in mainboard pei_date. */ + mainboard_pre_raminit(&rp); - platform_enter_postcar(); -} - -/* This wrapper enables easy transition towards C_ENVIRONMENT_BOOTBLOCK, - * keeping changes in cache_as_ram.S easy to manage. - */ -asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist) -{ - romstage_main(base_timestamp, bist); -} - -/* Entry from the mainboard. */ -void romstage_common(struct romstage_params *params) -{ post_code(0x32); timestamp_add_now(TS_BEFORE_INITRAM); - params->pei_data.boot_mode = params->power_state->prev_sleep_state; + rp.pei_data.boot_mode = rp.power_state->prev_sleep_state; -#if CONFIG(ELOG_BOOT_COUNT) - if (params->power_state->prev_sleep_state != ACPI_S3) + if (CONFIG(ELOG_BOOT_COUNT) + && rp.power_state->prev_sleep_state != ACPI_S3) boot_count_increment(); -#endif /* Print ME state before MRC */ intel_me_status(); /* Save ME HSIO version */ - intel_me_hsio_version(¶ms->power_state->hsio_version, - ¶ms->power_state->hsio_checksum); + intel_me_hsio_version(&rp.power_state->hsio_version, + &rp.power_state->hsio_checksum); /* Initialize RAM */ - raminit(¶ms->pei_data); + raminit(&rp.pei_data); timestamp_add_now(TS_AFTER_INITRAM); - romstage_handoff_init(params->power_state->prev_sleep_state == ACPI_S3); + romstage_handoff_init(rp.power_state->prev_sleep_state == ACPI_S3); + + mainboard_post_raminit(&rp); + + platform_enter_postcar(); +} + +/* This wrapper enables easy transition towards C_ENVIRONMENT_BOOTBLOCK, + * keeping changes in cache_as_ram.S easy to manage. + */ +asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist) +{ + romstage_main(base_timestamp, bist); } void __weak mainboard_pre_console_init(void) {} From d1ad37847da61d243f691590005865df505dc31f Mon Sep 17 00:00:00 2001 From: Gaggery Tsai Date: Wed, 8 May 2019 12:11:21 -0700 Subject: [PATCH 298/588] mb/google/poppy/vr/atlas: Add a W/A for Samsung memory init error This patch adds a workaround for Samsung C-die 2G/4G memory chips. For unknown reasons, some boards with Samsung LP3 memory chips could not pass early CS/CMD training. MRC has to change the granularity from 16 ticks to 8 ticks, which implies bad margin with this memory chip. Another way is to enhance the drive strength for CS. This patch is to enhance the drive strength for CS and CMD. Enhancing the drive strength for CMD could gain margin abaout 3 more ticks. Root cause needs to be further investigated with memory vendor. BUG=b:131177542 BRANCH=None TEST=USE=fw_debug emerge-atlas chromeos-mrc coreboot chromeos-bootimage & check the MRC log to ensure correct Rcomp values are passed to MRC. Tested with board ID #8 and #11. Change-Id: I9ea3ceda8dc8bf781063d3c16c7c2d9b44e5ddd6 Signed-off-by: Gaggery Tsai Reviewed-on: https://review.coreboot.org/c/coreboot/+/32695 Tested-by: build bot (Jenkins) Reviewed-by: Caveh Jalali --- src/mainboard/google/poppy/variants/atlas/memory.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/mainboard/google/poppy/variants/atlas/memory.c b/src/mainboard/google/poppy/variants/atlas/memory.c index 0b34e72830c..022b7333982 100644 --- a/src/mainboard/google/poppy/variants/atlas/memory.c +++ b/src/mainboard/google/poppy/variants/atlas/memory.c @@ -13,8 +13,11 @@ * GNU General Public License for more details. */ +#include #include +#define SAMSUNG_C_DIE_2G 10 +#define SAMSUNG_C_DIE_4G 11 /* DQ byte map */ static const u8 dq_map[][12] = { { 0x0F, 0xF0, 0x00, 0xF0, 0x0F, 0xF0, @@ -34,9 +37,12 @@ static const u16 rcomp_resistor[] = { 200, 81, 162 }; /* Rcomp target */ static const u16 rcomp_target[] = { 100, 40, 40, 23, 40 }; +static const u16 rcomp_target_samsung_c_die[] = { 100, 40, 35, 18, 40 }; void variant_memory_params(struct memory_params *p) { + int spd_index; + p->type = MEMORY_LPDDR3; p->dq_map = dq_map; p->dq_map_size = sizeof(dq_map); @@ -44,6 +50,11 @@ void variant_memory_params(struct memory_params *p) p->dqs_map_size = sizeof(dqs_map); p->rcomp_resistor = rcomp_resistor; p->rcomp_resistor_size = sizeof(rcomp_resistor); - p->rcomp_target = rcomp_target; + spd_index = variant_memory_sku(); + assert(spd_index >= 0); + if (spd_index == SAMSUNG_C_DIE_2G || spd_index == SAMSUNG_C_DIE_4G) + p->rcomp_target = rcomp_target_samsung_c_die; + else + p->rcomp_target = rcomp_target; p->rcomp_target_size = sizeof(rcomp_target); } From cd51d7ced5a4996253c6dfc816ab7ef82533b2da Mon Sep 17 00:00:00 2001 From: Caveh Jalali Date: Mon, 13 May 2019 20:55:06 -0700 Subject: [PATCH 299/588] mb/google/poppy/variant/atlas: Add SPDs for Samsung D-die chips This adds the SPDs for Samsung D-die 16Gbit and 32Gbit LPDDR3-2133 chips. BUG=b:132206809 TEST=boots on atlas with C-die and D-die memory chips localhost ~ # mosys memory spd print all 0 | LPDDR3 | SO-DIMM 1 | LPDDR3 | SO-DIMM 0 | 1-78: Samsung | 00000000 | K4EBE304ED-EGCG 1 | 1-78: Samsung | 00000000 | K4EBE304ED-EGCG 0 | 8192 | 2 | 64 1 | 8192 | 2 | 64 0 | LPDDR3-800, LPDDR3-1066, LPDDR3-1333, LPDDR3-1600, LPDDR3-1866, LPDDR3-2133 1 | LPDDR3-800, LPDDR3-1066, LPDDR3-1333, LPDDR3-1600, LPDDR3-1866, LPDDR3-2133 localhost ~ # Change-Id: I8ba000aeeb77f07d7f18bda86b3c07f5b50478b8 Signed-off-by: Caveh Jalali Reviewed-on: https://review.coreboot.org/c/coreboot/+/32780 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../spd/samsung_dimm_K4E6E304ED-EGCG.spd.hex | 16 ++++++++++++++++ .../spd/samsung_dimm_K4EBE304ED-EGCG.spd.hex | 16 ++++++++++++++++ .../google/poppy/variants/atlas/Makefile.inc | 2 ++ 3 files changed, 34 insertions(+) create mode 100644 src/mainboard/google/poppy/spd/samsung_dimm_K4E6E304ED-EGCG.spd.hex create mode 100644 src/mainboard/google/poppy/spd/samsung_dimm_K4EBE304ED-EGCG.spd.hex diff --git a/src/mainboard/google/poppy/spd/samsung_dimm_K4E6E304ED-EGCG.spd.hex b/src/mainboard/google/poppy/spd/samsung_dimm_K4E6E304ED-EGCG.spd.hex new file mode 100644 index 00000000000..a1dc212a9f4 --- /dev/null +++ b/src/mainboard/google/poppy/spd/samsung_dimm_K4E6E304ED-EGCG.spd.hex @@ -0,0 +1,16 @@ +91 20 F1 03 05 19 05 0B 03 11 01 08 08 00 40 55 +78 78 90 50 90 11 50 E0 90 06 3C 3C 01 90 00 00 +00 00 C2 00 00 00 00 A8 00 08 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 80 CE 00 00 00 00 00 00 00 00 00 +4B 34 45 36 45 33 30 34 45 44 2D 45 47 43 47 20 +20 20 00 00 80 CE 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/google/poppy/spd/samsung_dimm_K4EBE304ED-EGCG.spd.hex b/src/mainboard/google/poppy/spd/samsung_dimm_K4EBE304ED-EGCG.spd.hex new file mode 100644 index 00000000000..e59d8286d51 --- /dev/null +++ b/src/mainboard/google/poppy/spd/samsung_dimm_K4EBE304ED-EGCG.spd.hex @@ -0,0 +1,16 @@ +91 20 F1 03 05 1A 05 0A 03 11 01 08 08 00 40 55 +78 78 90 50 90 11 50 E0 90 06 3C 3C 01 90 00 00 +00 00 C2 00 00 00 00 A8 00 08 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 80 CE 00 00 00 00 00 00 00 00 00 +4B 34 45 42 45 33 30 34 45 44 2D 45 47 43 47 20 +20 20 00 00 80 CE 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/google/poppy/variants/atlas/Makefile.inc b/src/mainboard/google/poppy/variants/atlas/Makefile.inc index 06776ffd4a2..397ef687e91 100644 --- a/src/mainboard/google/poppy/variants/atlas/Makefile.inc +++ b/src/mainboard/google/poppy/variants/atlas/Makefile.inc @@ -12,6 +12,8 @@ SPD_SOURCES += micron_dimm_MT52L256M32D1PF-107 # 0b1001 SPD_SOURCES += samsung_dimm_K4E6E304EC-EGCF # 0b1010 SPD_SOURCES += samsung_dimm_K4EBE304EC-EGCF # 0b1011 SPD_SOURCES += nayna_dimm_NT6CL256T32CM-H1 # 0b1100 +SPD_SOURCES += samsung_dimm_K4E6E304ED-EGCG # 0b1101 +SPD_SOURCES += samsung_dimm_K4EBE304ED-EGCG # 0b1110 bootblock-y += gpio.c From 29150c83df8630a817e81eef593dd93fdb37b09f Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Tue, 23 Apr 2019 16:02:15 -0600 Subject: [PATCH 300/588] soc/amd/stoneyridge: Add ACPI D3Cold support for SD Controller We need to support entering D3Cold from the OS to work around a bug in the SDHC where the data lines get stuck always reading zeros. BUG=b:122749418 TEST=Verified the linux kernel can transition between D3 and D0. Also verified that the device can suspend and resume and continue to have a functioning SD controller after. Change-Id: Ifbf48f20c03a752ce3ff773296b536e92db16a62 Signed-off-by: Raul E Rangel Reviewed-on: https://review.coreboot.org/c/coreboot/+/32433 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/amd/stoneyridge/acpi/sb_pci0_fch.asl | 31 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/soc/amd/stoneyridge/acpi/sb_pci0_fch.asl b/src/soc/amd/stoneyridge/acpi/sb_pci0_fch.asl index 15e4d2f1222..1334df11c46 100644 --- a/src/soc/amd/stoneyridge/acpi/sb_pci0_fch.asl +++ b/src/soc/amd/stoneyridge/acpi/sb_pci0_fch.asl @@ -56,6 +56,16 @@ Device(SBUS) { /* 0:14.7 - SD Controller */ Device(SDCN) { Name(_ADR, 0x00140007) + + Method(_PS0) { + FDDC(24, 0) + } + Method(_PS3) { + FDDC(24, 3) + } + Method(_PSC) { + Return(SDTD) + } } /* end SDCN */ Name(CRES, ResourceTemplate() { @@ -286,8 +296,9 @@ Field( SMIC, ByteAcc, NoLock, Preserve) { offset (0x1e70), /* SD D3 Control */ SDTD, 2, , 1, + SDPD, 1, + , 1, , 1, - , 2, SDRT, 1, SDSC, 1, @@ -433,7 +444,14 @@ Method(FDDC, 2, Serialized) /* todo Case(15) { STD0()} */ /* SATA */ Case(18) { U2D0()} /* EHCI */ Case(23) { U3D0()} /* XHCI */ -/* todo Case(24) { SDD0()} */ /* SD */ + Case(24) { /* SD */ + Store(0x00, SDTD) + Store(One, SDPD) + Store(SDDS, Local0) + while(LNotEqual(Local0,0x7)) { + Store(SDDS, Local0) + } + } } } else { /* put device into D3cold */ @@ -489,7 +507,14 @@ Method(FDDC, 2, Serialized) /* todo Case(15) { STD3()} */ /* SATA */ Case(18) { U2D3()} /* EHCI */ Case(23) { U3D3()} /* XHCI */ -/* todo Case(24) { SDD3()} */ /* SD */ + Case(24) { /* SD */ + Store(Zero, SDPD) + Store(SDDS, Local0) + while(LNotEqual(Local0,0x0)) { + Store(SDDS, Local0) + } + Store(0x03, SDTD) + } } /* Turn off Power */ if(LEqual(I0TD, 3)) { From df85bf79189a0a1a682f5731f2c332acfa28055c Mon Sep 17 00:00:00 2001 From: Alan Green Date: Thu, 2 May 2019 18:50:05 +1000 Subject: [PATCH 301/588] Documentation/lessons/lesson2.md: Add reminder to check username set If username is not set, then the ssh option is not available. This was initially confusing for me. Signed-off-by: Alan Green Change-Id: I731c29a1daa9f8c298710471c7d1fe758b059d08 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32540 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao Reviewed-by: Marshall Dawson Reviewed-by: Mike Banon --- Documentation/lessons/lesson2.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/lessons/lesson2.md b/Documentation/lessons/lesson2.md index d6f800c2901..626e76e74ad 100644 --- a/Documentation/lessons/lesson2.md +++ b/Documentation/lessons/lesson2.md @@ -68,6 +68,10 @@ If you are using SSH keys, select **ssh** from the tabs under "Project coreboot" and run the "clone with commit-msg hook" command that's provided. This should prompt you for your id_rsa passphrase, if you previously set one. +**Note:** if the **ssh** option is not showing, check that you have a username +set. Click the profile picture at the top right and select **User Settings**, +then set your username in the **Profile** section. + If you are using HTTP, instead, select **http** from the tabs under "Project coreboot" and run the command that appears From 9a8c5e7ac0f559898c4d5fcb99a51e4dc472f51f Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Mon, 6 May 2019 17:50:57 +0200 Subject: [PATCH 302/588] util/inteltool: Add Kabylake E3-1200 Support Change-Id: I5c55102d7ce15dbb708e9433500ebd1ed53179ad Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32619 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/inteltool/cpu.c | 318 +++++++++++++++++++++++++++++++++++ util/inteltool/gpio.c | 1 + util/inteltool/gpio_groups.c | 1 + util/inteltool/inteltool.c | 2 + util/inteltool/inteltool.h | 1 + util/inteltool/memory.c | 1 + util/inteltool/pcie.c | 3 + util/inteltool/powermgt.c | 1 + 8 files changed, 328 insertions(+) diff --git a/util/inteltool/cpu.c b/util/inteltool/cpu.c index c40a3bd22bb..ef2df3cd00d 100644 --- a/util/inteltool/cpu.c +++ b/util/inteltool/cpu.c @@ -1529,6 +1529,323 @@ int print_intel_core_msrs(void) { 0x416, "MSR_MC5_ADDR" }, }; +/* + * Intel 64 and IA-32 Architectures Software Developers Manual Conbined Volumes + * Page 4668 + * + * The following two tables are for the Kaby Lake processors + * 06_9EH. + * + */ + + static const msr_entry_t model96ex_global_msrs[] = { + { 0x0000, "IA32_PLATFORM_ID"}, + { 0x0080, "MSR_TRACE_HUB_STH_ACPIBAR_BASE"}, + { 0x00CE, "MSR_PLATFORM_INFO"}, + { 0x0198, "IA32_PERF_STATUS"}, + { 0x01A2, "MSR_TEMPERATURE_TARGET"}, + { 0x01AD, "MSR_TURBO_RATIO_LIMIT"}, + { 0x0284, "IA32_MC4_CTL2"}, + { 0x02F4, "MSR_UNCORE_PRMRR_PHYS_BASE"}, + { 0x02F5, "MSR_UNCORE_PRMRR_PHYS_MASK"}, + { 0x0394, "MSR_UNC_PERF_FIXED_CTRL"}, + { 0x0395, "MSR_UNC_PERF_FIXED_CTR"}, + { 0x060A, "MSR_PKGC3_IRTL"}, + { 0x060B, "MSR_PKGC6_IRTL"}, + { 0x060D, "MSR_PKG_C2_RESIDENCY"}, + { 0x0610, "MSR_PKG_POWER_LIMIT"}, + { 0x0614, "MSR_PKG_POWER_INFO"}, + { 0x0620, "MSR_RING_RATIO_LIMIT"}, + { 0x0638, "MSR_PP0_POWER_LIMIT"}, + { 0x064F, "MSR_CORE_PERF_LIMIT_REASONS"}, + { 0x0652, "MSR_PKG_HDC_CONFIG"}, + { 0x065C, "MSR_PLATFORM_POWER_LIMIT"}, + { 0x06B0, "MSR_GRAPHICS_PERF_LIMIT_REASONS"}, + { 0x06B1, "MSR_RING_PERF_LIMIT_REASONS"}, + { 0x0770, "IA32_PM_ENABLE"}, + { 0x0DB0, "IA32_PKG_HDC_CTL"}, + { 0x03B0, "MSR_UNC_ARB_PERFCTR0"}, + { 0x03B1, "MSR_UNC_ARB_PERFCTR1"}, + { 0x03B2, "MSR_UNC_ARB_PERFEVTSEL0"}, + { 0x03B3, "MSR_UNC_ARB_PERFEVTSEL1"}, + { 0x0700, "MSR_UNC_CBO_0_PERFCTR0"}, + { 0x0701, "MSR_UNC_CBO_0_PERFCTR1"}, + { 0x0706, "MSR_UNC_CBO_0_PERFEVTSEL0"}, + { 0x0707, "MSR_UNC_CBO_0_PERFEVTSEL1"}, + { 0x0710, "MSR_UNC_CBO_1_PERFCTR0"}, + { 0x0711, "MSR_UNC_CBO_1_PERFCTR1"}, + { 0x0716, "MSR_UNC_CBO_1_PERFEVTSEL0"}, + { 0x0717, "MSR_UNC_CBO_1_PERFEVTSEL1"}, + { 0x0720, "MSR_UNC_CBO_2_PERFCTR0"}, + { 0x0721, "MSR_UNC_CBO_2_PERFCTR1"}, + { 0x0726, "MSR_UNC_CBO_2_PERFEVTSEL0"}, + { 0x0727, "MSR_UNC_CBO_2_PERFEVTSEL1"}, + { 0x0730, "MSR_UNC_CBO_3_PERFCTR0"}, + { 0x0731, "MSR_UNC_CBO_3_PERFCTR1"}, + { 0x0736, "MSR_UNC_CBO_3_PERFEVTSEL0"}, + { 0x0737, "MSR_UNC_CBO_3_PERFEVTSEL1"}, + { 0x0E01, "MSR_UNC_PERF_GLOBAL_CTRL"}, + { 0x0E02, "MSR_UNC_PERF_GLOBAL_STATUS"}, + }; + + static const msr_entry_t model96ex_per_core_msrs[] = { + /* Per core MSRs for Sandy Bridge and above */ + { 0x0000, "IA32_P5_MC_ADDR"}, + { 0x0001, "IA32_P5_MC_TYPE"}, + { 0x0006, "IA32_MONITOR_FILTER_SIZE"}, + { 0x0010, "IA32_TIME_STAMP_COUNTER"}, + { 0x001B, "IA32_APIC_BASE"}, + { 0x0034, "MSR_SMI_COUNT"}, + { 0x003A, "IA32_FEATURE_CONTROL"}, + { 0x008B, "IA32_BIOS_SIGN_ID"}, + { 0x00C1, "IA32_PMC0" }, + { 0x00C2, "IA32_PMC1" }, + { 0x00C3, "IA32_PMC2" }, + { 0x00C4, "IA32_PMC3" }, + { 0x00E2, "MSR_PKG_CST_CONFIG_CONTROL" }, + { 0x00E4, "MSR_PMG_IO_CAPTURE_BASE"}, + { 0x00E7, "IA32_MPERF"}, + { 0x00E8, "IA32_APERF"}, + { 0x00FE, "IA32_MTRRCAP"}, + { 0x013C, "MSR_FEATURE_CONFIG"}, + { 0x0174, "IA32_SYSENTER_CS"}, + { 0x0175, "IA32_SYSENTER_ESP"}, + { 0x0176, "IA32_SYSENTER_EIP"}, + { 0x0179, "IA32_MCG_CAP"}, + { 0x017A, "IA32_MCG_STATUS"}, + { 0x0186, "IA32_PERFEVTSEL0"}, + { 0x0187, "IA32_PERFEVTSEL1"}, + { 0x0188, "IA32_PERFEVTSEL2"}, + { 0x0189, "IA32_PERFEVTSEL3"}, + { 0x0199, "IA32_PERF_CTL"}, + { 0x019A, "IA32_CLOCK_MODULATION"}, + { 0x019B, "IA32_THERM_INTERRUPT"}, + { 0x019C, "IA32_THERM_STATUS"}, + { 0x01A0, "IA32_MISC_ENABLE"}, + { 0x01A4, "IA32_MISC_FEATURE_CONTROL"}, + { 0x01A6, "MSR_OFFCORE_RSP_0"}, + { 0x01A7, "MSR_OFFCORE_RSP_1"}, + { 0x01C8, "MSR_LBR_SELECT"}, + { 0x01C9, "MSR_LASTBRANCH_TOS"}, + { 0x01D9, "IA32_DEBUGCTL"}, + { 0x01DD, "MSR_LER_FROM_LIP"}, + { 0x01DE, "MSR_LER_TO_LIP"}, + { 0x01F2, "IA32_SMRR_PHYSBASE"}, + { 0x01F3, "IA32_SMRR_PHYSMASK"}, + { 0x01F4, "MSR_PRMRR_PHYS_BASE"}, + { 0x01F5, "MSR_PRMRR_PHYS_MASK"}, + { 0x01F4, "MSR_PRMRR_PHYS_BASE"}, + { 0x01FB, "MSR_PRMRR_VALID_CONFIG"}, + { 0x01FC, "MSR_POWER_CTL"}, + { 0x0200, "IA32_MTRR_PHYSBASE0"}, + { 0x0201, "IA32_MTRR_PHYSBASE0"}, + { 0x0202, "IA32_MTRR_PHYSBASE1"}, + { 0x0203, "IA32_MTRR_PHYSBASE1"}, + { 0x0204, "IA32_MTRR_PHYSBASE2"}, + { 0x0205, "IA32_MTRR_PHYSBASE2"}, + { 0x0206, "IA32_MTRR_PHYSBASE3"}, + { 0x0207, "IA32_MTRR_PHYSBASE3"}, + { 0x0208, "IA32_MTRR_PHYSBASE4"}, + { 0x0209, "IA32_MTRR_PHYSBASE4"}, + { 0x020A, "IA32_MTRR_PHYSBASE5"}, + { 0x020B, "IA32_MTRR_PHYSBASE5"}, + { 0x020C, "IA32_MTRR_PHYSBASE6"}, + { 0x020D, "IA32_MTRR_PHYSBASE6"}, + { 0x020E, "IA32_MTRR_PHYSBASE7"}, + { 0x020F, "IA32_MTRR_PHYSBASE7"}, + { 0x0210, "IA32_MTRR_PHYSBASE8"}, + { 0x0211, "IA32_MTRR_PHYSBASE8"}, + { 0x0212, "IA32_MTRR_PHYSBASE9"}, + { 0x0213, "IA32_MTRR_PHYSBASE9"}, + { 0x0250, "IA32_MTRR_FIX64K_00000"}, + { 0x0258, "IA32_MTRR_FIX16K_80000"}, + { 0x0259, "IA32_MTRR_FIX16K_A0000"}, + { 0x0268, "IA32_MTRR_FIX4K_C0000"}, + { 0x0269, "IA32_MTRR_FIX4K_C8000"}, + { 0x026A, "IA32_MTRR_FIX4K_D0000"}, + { 0x026B, "IA32_MTRR_FIX4K_D8000"}, + { 0x026C, "IA32_MTRR_FIX4K_E0000"}, + { 0x026D, "IA32_MTRR_FIX4K_E8000"}, + { 0x026E, "IA32_MTRR_FIX4K_F0000"}, + { 0x026F, "IA32_MTRR_FIX4K_F8000"}, + { 0x0277, "IA32_PAT"}, + { 0x0280, "IA32_MC0_CTL2"}, + { 0x0281, "IA32_MC1_CTL2"}, + { 0x0282, "IA32_MC2_CTL2"}, + { 0x0283, "IA32_MC3_CTL2"}, + { 0x02FF, "IA32_MTRR_DEF_TYPE"}, + { 0x0309, "IA32_FIXED_CTR0"}, + { 0x030A, "IA32_FIXED_CTR1"}, + { 0x030B, "IA32_FIXED_CTR2"}, + { 0x0345, "IA32_PERF_CAPABILITIES"}, + { 0x038D, "IA32_FIXED_CTR_CTRL"}, + { 0x038E, "IA32_PERF_GLOBAL_STATUS"}, + { 0x038F, "IA32_PERF_GLOBAL_CTRL"}, + { 0x0390, "IA32_PERF_GLOBAL_STATUS_RESET"}, + { 0x0391, "IA32_PERF_GLOBAL_STATUS_SET"}, + { 0x03F1, "MSR_PEBS_ENABLE"}, + { 0x03F6, "MSR_PEBS_LD_LAT"}, + { 0x03F7, "MSR_PEBS_FRONTEND"}, + { 0x03FC, "MSR_CORE_C3_RESIDENCY"}, + { 0x03FD, "MSR_CORE_C6_RESIDENCY"}, + { 0x03FE, "MSR_CORE_C7_RESIDENCY"}, + { 0x0400, "IA32_MC0_CTL" }, + { 0x0401, "IA32_MC0_STATUS" }, + { 0x0402, "IA32_MC0_ADDR" }, + { 0x0403, "IA32_MC0_MISC" }, + { 0x0404, "IA32_MC1_CTL" }, + { 0x0405, "IA32_MC1_STATUS" }, + { 0x0406, "IA32_MC1_ADDR" }, + { 0x0407, "IA32_MC1_MISC" }, + { 0x0408, "IA32_MC2_CTL" }, + { 0x0409, "IA32_MC2_STATUS" }, + { 0x040a, "IA32_MC2_ADDR" }, + { 0x040c, "IA32_MC3_CTL" }, + { 0x040d, "IA32_MC3_STATUS" }, + { 0x040e, "IA32_MC3_ADDR" }, + { 0x0410, "IA32_MC4_CTL" }, + { 0x0411, "IA32_MC4_STATUS" }, + { 0x0480, "IA32_VMX_BASIC" }, + { 0x0481, "IA32_VMX_PINBASED_CTLS" }, + { 0x0482, "IA32_VMX_PROCBASED_CTLS" }, + { 0x0483, "IA32_VMX_EXIT_CTLS" }, + { 0x0484, "IA32_VMX_ENTRY_CTLS" }, + { 0x0485, "IA32_VMX_MISC" }, + { 0x0486, "IA32_VMX_CR0_FIXED0" }, + { 0x0487, "IA32_VMX_CR0_FIXED1" }, + { 0x0488, "IA32_VMX_CR4_FIXED0" }, + { 0x0489, "IA32_VMX_CR4_FIXED1" }, + { 0x048a, "IA32_VMX_VMCS_ENUM" }, + { 0x048b, "IA32_VMX_PROCBASED_CTLS2" }, + { 0x048c, "IA32_VMX_EPT_VPID_ENUM" }, + { 0x048d, "IA32_VMX_TRUE_PINBASED_CTLS" }, + { 0x048e, "IA32_VMX_TRUE_PROCBASED_CTLS" }, + { 0x048f, "IA32_VMX_TRUE_EXIT_CTLS" }, + { 0x0490, "IA32_VMX_TRUE_ENTRY_CTLS" }, + { 0x04C1, "IA32_A_PMC0"}, + { 0x04C2, "IA32_A_PMC1"}, + { 0x04C3, "IA32_A_PMC2"}, + { 0x04C4, "IA32_A_PMC3"}, + { 0x0500, "IA32_SGX_SVN_STATUS"}, + { 0x0560, "IA32_RTIT_OUTPUT_BASE"}, + { 0x0561, "IA32_RTIT_OUTPUT_MASK_PTRS"}, + { 0x0570, "IA32_RTIT_CTL"}, + { 0x0571, "IA32_RTIT_STATUS"}, + { 0x0572, "IA32_RTIT_CR3_MATCH"}, + { 0x0580, "IA32_RTIT_ADDR0_A"}, + { 0x0581, "IA32_RTIT_ADDR0_B"}, + { 0x0582, "IA32_RTIT_ADDR1_A"}, + { 0x0583, "IA32_RTIT_ADDR1_B"}, + { 0x0600, "IA32_DS_AREA" }, + { 0x064E, "MSR_PPERF"}, + { 0x0653, "MSR_CORE_HDC_RESIDENCY"}, + { 0x0680, "MSR_LASTBRANCH_0_FROM_IP" }, + { 0x0681, "MSR_LASTBRANCH_1_FROM_IP" }, + { 0x0682, "MSR_LASTBRANCH_2_FROM_IP" }, + { 0x0683, "MSR_LASTBRANCH_3_FROM_IP" }, + { 0x0684, "MSR_LASTBRANCH_4_FROM_IP" }, + { 0x0685, "MSR_LASTBRANCH_5_FROM_IP" }, + { 0x0686, "MSR_LASTBRANCH_6_FROM_IP" }, + { 0x0687, "MSR_LASTBRANCH_7_FROM_IP" }, + { 0x0688, "MSR_LASTBRANCH_8_FROM_IP" }, + { 0x0689, "MSR_LASTBRANCH_9_FROM_IP" }, + { 0x068a, "MSR_LASTBRANCH_10_FROM_IP" }, + { 0x068b, "MSR_LASTBRANCH_11_FROM_IP" }, + { 0x068c, "MSR_LASTBRANCH_12_FROM_IP" }, + { 0x068d, "MSR_LASTBRANCH_13_FROM_IP" }, + { 0x068e, "MSR_LASTBRANCH_14_FROM_IP" }, + { 0x068f, "MSR_LASTBRANCH_15_FROM_IP" }, + { 0x0690, "MSR_LASTBRANCH_16_FROM_IP" }, + { 0x0691, "MSR_LASTBRANCH_17_FROM_IP" }, + { 0x0692, "MSR_LASTBRANCH_18_FROM_IP" }, + { 0x0693, "MSR_LASTBRANCH_19_FROM_IP" }, + { 0x0694, "MSR_LASTBRANCH_20_FROM_IP" }, + { 0x0695, "MSR_LASTBRANCH_21_FROM_IP" }, + { 0x0696, "MSR_LASTBRANCH_22_FROM_IP" }, + { 0x0697, "MSR_LASTBRANCH_23_FROM_IP" }, + { 0x0698, "MSR_LASTBRANCH_24_FROM_IP" }, + { 0x0699, "MSR_LASTBRANCH_25_FROM_IP" }, + { 0x069A, "MSR_LASTBRANCH_26_FROM_IP" }, + { 0x069B, "MSR_LASTBRANCH_27_FROM_IP" }, + { 0x069C, "MSR_LASTBRANCH_28_FROM_IP" }, + { 0x069D, "MSR_LASTBRANCH_29_FROM_IP" }, + { 0x069E, "MSR_LASTBRANCH_30_FROM_IP" }, + { 0x069F, "MSR_LASTBRANCH_31_FROM_IP" }, + { 0x06c0, "MSR_LASTBRANCH_0_TO_IP" }, + { 0x06c1, "MSR_LASTBRANCH_1_TO_IP" }, + { 0x06c2, "MSR_LASTBRANCH_2_TO_IP" }, + { 0x06c3, "MSR_LASTBRANCH_3_TO_IP" }, + { 0x06c4, "MSR_LASTBRANCH_4_TO_IP" }, + { 0x06c5, "MSR_LASTBRANCH_5_TO_IP" }, + { 0x06c6, "MSR_LASTBRANCH_6_TO_IP" }, + { 0x06c7, "MSR_LASTBRANCH_7_TO_IP" }, + { 0x06c8, "MSR_LASTBRANCH_8_TO_IP" }, + { 0x06c9, "MSR_LASTBRANCH_9_TO_IP" }, + { 0x06ca, "MSR_LASTBRANCH_10_TO_IP" }, + { 0x06cb, "MSR_LASTBRANCH_11_TO_IP" }, + { 0x06cc, "MSR_LASTBRANCH_12_TO_IP" }, + { 0x06cd, "MSR_LASTBRANCH_13_TO_IP" }, + { 0x06ce, "MSR_LASTBRANCH_14_TO_IP" }, + { 0x06cf, "MSR_LASTBRANCH_15_TO_IP" }, + { 0x06d0, "MSR_LASTBRANCH_16_FROM_IP" }, + { 0x06d1, "MSR_LASTBRANCH_17_FROM_IP" }, + { 0x06d2, "MSR_LASTBRANCH_18_FROM_IP" }, + { 0x06d3, "MSR_LASTBRANCH_19_FROM_IP" }, + { 0x06d4, "MSR_LASTBRANCH_20_FROM_IP" }, + { 0x06d5, "MSR_LASTBRANCH_21_FROM_IP" }, + { 0x06d6, "MSR_LASTBRANCH_22_FROM_IP" }, + { 0x06d7, "MSR_LASTBRANCH_23_FROM_IP" }, + { 0x06d8, "MSR_LASTBRANCH_24_FROM_IP" }, + { 0x06d9, "MSR_LASTBRANCH_25_FROM_IP" }, + { 0x06da, "MSR_LASTBRANCH_26_FROM_IP" }, + { 0x06db, "MSR_LASTBRANCH_27_FROM_IP" }, + { 0x06dc, "MSR_LASTBRANCH_28_FROM_IP" }, + { 0x06dd, "MSR_LASTBRANCH_29_FROM_IP" }, + { 0x06de, "MSR_LASTBRANCH_30_FROM_IP" }, + { 0x06df, "MSR_LASTBRANCH_31_FROM_IP" }, + { 0x06E0, "IA32_TSC_DEADLINE"}, + { 0x0771, "IA32_HWP_CAPABILITIES"}, + { 0x0773, "IA32_HWP_INTERRUPT"}, + { 0x0774, "IA32_HWP_REQUEST"}, + { 0x0777, "IA32_HWP_STATUS"}, + { 0x0D90, "IA32_BNDCFGS"}, + { 0x0DA0, "IA32_XSS"}, + { 0x0DB1, "IA32_PM_CTL1"}, + { 0x0DB2, "IA32_THREAD_STALL"}, + { 0x0DC0, "IA32_LBR_INFO_0"}, + { 0x0DC1, "IA32_LBR_INFO_1"}, + { 0x0DC2, "IA32_LBR_INFO_2"}, + { 0x0DC3, "IA32_LBR_INFO_3"}, + { 0x0DC4, "IA32_LBR_INFO_4"}, + { 0x0DC5, "IA32_LBR_INFO_5"}, + { 0x0DC6, "IA32_LBR_INFO_6"}, + { 0x0DC7, "IA32_LBR_INFO_7"}, + { 0x0DC8, "IA32_LBR_INFO_8"}, + { 0x0DC9, "IA32_LBR_INFO_9"}, + { 0x0DCA, "IA32_LBR_INFO_10"}, + { 0x0DCB, "IA32_LBR_INFO_11"}, + { 0x0DCC, "IA32_LBR_INFO_12"}, + { 0x0DCD, "IA32_LBR_INFO_13"}, + { 0x0DCE, "IA32_LBR_INFO_14"}, + { 0x0DCF, "IA32_LBR_INFO_15"}, + { 0x0DD0, "IA32_LBR_INFO_16"}, + { 0x0DD1, "IA32_LBR_INFO_17"}, + { 0x0DD2, "IA32_LBR_INFO_18"}, + { 0x0DD3, "IA32_LBR_INFO_19"}, + { 0x0DD4, "IA32_LBR_INFO_20"}, + { 0x0DD5, "IA32_LBR_INFO_21"}, + { 0x0DD6, "IA32_LBR_INFO_22"}, + { 0x0DD7, "IA32_LBR_INFO_23"}, + { 0x0DD8, "IA32_LBR_INFO_24"}, + { 0x0DD9, "IA32_LBR_INFO_25"}, + { 0x0DDA, "IA32_LBR_INFO_26"}, + { 0x0DDB, "IA32_LBR_INFO_27"}, + { 0x0DDC, "IA32_LBR_INFO_28"}, + { 0x0DDD, "IA32_LBR_INFO_29"}, + { 0x0DDE, "IA32_LBR_INFO_30"}, + { 0x0DDF, "IA32_LBR_INFO_31"}, + }; + typedef struct { unsigned int model; const msr_entry_t *global_msrs; @@ -1547,6 +1864,7 @@ int print_intel_core_msrs(void) { 0x00f60, modelf6x_global_msrs, ARRAY_SIZE(modelf6x_global_msrs), modelf6x_per_core_msrs, ARRAY_SIZE(modelf6x_per_core_msrs) }, { 0x106c0, model6_atom_global_msrs, ARRAY_SIZE(model6_atom_global_msrs), model6_atom_per_core_msrs, ARRAY_SIZE(model6_atom_per_core_msrs) }, { 0x20650, model20650_global_msrs, ARRAY_SIZE(model20650_global_msrs), model20650_per_core_msrs, ARRAY_SIZE(model20650_per_core_msrs) }, + { 0x906e0, model96ex_global_msrs, ARRAY_SIZE(model96ex_global_msrs), model96ex_per_core_msrs, ARRAY_SIZE(model96ex_per_core_msrs) }, { CPUID_BAYTRAIL, silvermont_global_msrs, ARRAY_SIZE(silvermont_global_msrs), silvermont_per_core_msrs, ARRAY_SIZE(silvermont_per_core_msrs) }, /* Baytrail */ diff --git a/util/inteltool/gpio.c b/util/inteltool/gpio.c index c946d5c65f0..e48a2c51f5f 100644 --- a/util/inteltool/gpio.c +++ b/util/inteltool/gpio.c @@ -1026,6 +1026,7 @@ int print_gpios(struct pci_dev *sb, int show_all, int show_diffs) break; case PCI_DEVICE_ID_INTEL_B150: case PCI_DEVICE_ID_INTEL_CM236: + case PCI_DEVICE_ID_INTEL_C236: case PCI_DEVICE_ID_INTEL_APL_LPC: case PCI_DEVICE_ID_INTEL_DNV_LPC: case PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_PRE: diff --git a/util/inteltool/gpio_groups.c b/util/inteltool/gpio_groups.c index 21e2de93d53..3c0fedbfbf1 100644 --- a/util/inteltool/gpio_groups.c +++ b/util/inteltool/gpio_groups.c @@ -1774,6 +1774,7 @@ void print_gpio_groups(struct pci_dev *const sb) switch (sb->device_id) { case PCI_DEVICE_ID_INTEL_B150: case PCI_DEVICE_ID_INTEL_CM236: + case PCI_DEVICE_ID_INTEL_C236: community_count = ARRAY_SIZE(sunrise_communities); communities = sunrise_communities; pcr_init(sb); diff --git a/util/inteltool/inteltool.c b/util/inteltool/inteltool.c index 40e76464500..7e025107522 100644 --- a/util/inteltool/inteltool.c +++ b/util/inteltool/inteltool.c @@ -135,6 +135,8 @@ static const struct { "7th generation (Kaby Lake family) Core Processor (Mobile)" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q, "7th generation (Kaby Lake family) Core Processor (Mobile)" }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3, + "7th generation (Kaby Lake family) Core Processor Xeon E3-1200" }, /* Southbridges (LPC controllers) */ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371XX, "371AB/EB/MB" }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH10, "ICH10" }, diff --git a/util/inteltool/inteltool.h b/util/inteltool/inteltool.h index 6aec3879c2e..483c93099e0 100644 --- a/util/inteltool/inteltool.h +++ b/util/inteltool/inteltool.h @@ -275,6 +275,7 @@ static inline uint32_t inl(unsigned port) #define PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U 0x5904 /* Kabylake (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y 0x590C /* Kabylake (Mobile) */ #define PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q 0x5914 /* Kabylake (Mobile) */ +#define PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3 0x5918 /* Kabylake Xeon E3 */ /* Intel GPUs */ diff --git a/util/inteltool/memory.c b/util/inteltool/memory.c index f0c756221b4..222ac8afb00 100644 --- a/util/inteltool/memory.c +++ b/util/inteltool/memory.c @@ -225,6 +225,7 @@ int print_mchbar(struct pci_dev *nb, struct pci_access *pacc, const char *dump_s case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q: + case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3: mchbar_phys = pci_read_long(nb, 0x48); mchbar_phys |= ((uint64_t)pci_read_long(nb, 0x4c)) << 32; mchbar_phys &= 0x0000007fffff8000UL; /* 38:15 */ diff --git a/util/inteltool/pcie.c b/util/inteltool/pcie.c index 5b35dbdde91..33644ab9dbe 100644 --- a/util/inteltool/pcie.c +++ b/util/inteltool/pcie.c @@ -270,6 +270,7 @@ int print_epbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q: + case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3: epbar_phys = pci_read_long(nb, 0x40) & 0xfffffffe; epbar_phys |= ((uint64_t)pci_read_long(nb, 0x44)) << 32; break; @@ -395,6 +396,7 @@ int print_dmibar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q: + case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3: dmi_registers = skylake_dmi_registers; size = ARRAY_SIZE(skylake_dmi_registers); dmibar_phys = pci_read_long(nb, 0x68); @@ -504,6 +506,7 @@ int print_pciexbar(struct pci_dev *nb) case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y: case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q: + case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3: pciexbar_reg = pci_read_long(nb, 0x60); pciexbar_reg |= ((uint64_t)pci_read_long(nb, 0x64)) << 32; break; diff --git a/util/inteltool/powermgt.c b/util/inteltool/powermgt.c index 675e31a1da4..8da12d2826e 100644 --- a/util/inteltool/powermgt.c +++ b/util/inteltool/powermgt.c @@ -836,6 +836,7 @@ int print_pmbase(struct pci_dev *sb, struct pci_access *pacc) break; case PCI_DEVICE_ID_INTEL_CM236: + case PCI_DEVICE_ID_INTEL_C236: acpi = pci_get_dev(pacc, sb->domain, sb->bus, sb->dev, 2); if (!acpi) { printf("PMC device not found.\n"); From dcfff3739be63c2d42e16860243d7bec98c7ba44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 31 Dec 2018 10:45:19 +0100 Subject: [PATCH 303/588] src/superio/ite/common: Prepare for ITE IT8786E SuperIO MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce 7bit Slope PWM registers. New ITE SuperIO may have contiguous 7bit values for PWM slope. Add option to enable External Sensor SMBus Host. Update/add registers macros for IT8786E-F which are not backwards compatible. Change-Id: I68fbfe62dfa05d0c166abaefbdc2ab873114b236 Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/30553 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/superio/ite/common/Kconfig | 7 +++++++ src/superio/ite/common/env_ctrl.c | 17 +++++++++++++++-- src/superio/ite/common/env_ctrl.h | 19 +++++++++++++++++++ src/superio/ite/common/env_ctrl_chip.h | 5 +++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/superio/ite/common/Kconfig b/src/superio/ite/common/Kconfig index 6c787417238..55f765004c9 100644 --- a/src/superio/ite/common/Kconfig +++ b/src/superio/ite/common/Kconfig @@ -51,4 +51,11 @@ config SUPERIO_ITE_ENV_CTRL_5FANS bool help ITE FAN controller has 5 independent outputs. + +config SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG + bool + help + Slope PWM registers have no separate BIT6 and are set directly by + 7-bit values instead. + endif diff --git a/src/superio/ite/common/env_ctrl.c b/src/superio/ite/common/env_ctrl.c index 57896e0c017..1b930368455 100644 --- a/src/superio/ite/common/env_ctrl.c +++ b/src/superio/ite/common/env_ctrl.c @@ -4,6 +4,7 @@ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. * Copyright (C) 2016 secunet Security Networks AG * Copyright (C) 2019 Protectli + * Copyright (C) 2019 Libretrend LDA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -165,9 +166,14 @@ static void fan_smartconfig(const u16 base, const u8 fan, pwm_ctrl |= ITE_EC_FAN_CTL_TEMPIN(conf->tmpin); pwm_start = ITE_EC_FAN_CTL_PWM_START_DUTY(conf->pwm_start); - pwm_start |= ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(conf->slope); - pwm_auto = ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(conf->slope); + if (CONFIG(SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG)) { + pwm_auto = conf->slope & 0x7f; + } else { + pwm_start |= ITE_EC_FAN_CTL_PWM_SLOPE_BIT6(conf->slope); + pwm_auto = ITE_EC_FAN_CTL_PWM_SLOPE_LOWER(conf->slope); + } + if (conf->smoothing) pwm_auto |= ITE_EC_FAN_CTL_AUTO_SMOOTHING_EN; @@ -287,6 +293,13 @@ void ite_ec_init(const u16 base, const struct ite_ec_config *const conf) for (i = 0; i < ITE_EC_TMPIN_CNT; ++i) enable_tmpin(base, i + 1, &conf->tmpin[i]); + /* Enable External Sensor SMBus Host if configured */ + if (conf->smbus_en) { + ite_ec_write(base, ITE_EC_INTERFACE_SELECT, + ite_ec_read(base, ITE_EC_INTERFACE_SELECT) | + ITE_EC_INTERFACE_SMB_ENABLE); + } + /* Enable reading of voltage pins */ ite_ec_write(base, ITE_EC_ADC_VOLTAGE_CHANNEL_ENABLE, conf->vin_mask); diff --git a/src/superio/ite/common/env_ctrl.h b/src/superio/ite/common/env_ctrl.h index e29e33f54a3..20e44ad5f11 100644 --- a/src/superio/ite/common/env_ctrl.h +++ b/src/superio/ite/common/env_ctrl.h @@ -4,6 +4,7 @@ * Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. * Copyright (C) 2016 secunet Security Networks AG * Copyright (C) 2019 Protectli + * Copyright (C) 2019 Libretrend LDA * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -50,6 +51,14 @@ #define ITE_EC_FAN_PWM_SMOOTHING_256HZ (1 << 6) #define ITE_EC_FAN_PWM_SMOOTHING_64HZ (2 << 6) #define ITE_EC_FAN_PWM_SMOOTHING_16HZ (3 << 6) +/* ITE IT8786E PWM_SMOOTHING_FREQ */ +#define ITE_EC_FAN_ALT_PWM_SMOOTHING_16HZ (1 << 6) +#define ITE_EC_FAN_ALT_PWM_SMOOTHING_8HZ (2 << 6) +#define ITE_EC_FAN_ALT_PWM_SMOOTHING_4HZ (3 << 6) +#define ITE_EC_FAN_CTL5_SEL(FAN_CTLx) ((((FAN_CTLx)-1) & 3) << 2) +#define ITE_EC_FAN_CTL5_SEL_NONE (3 << 2) +#define ITE_EC_FAN_CTL4_SEL(FAN_CTLx) (((FAN_CTLx)-1) & 3) +#define ITE_EC_FAN_CTL4_SEL_NONE (3 << 0) #define ITE_EC_FAN_TAC_COUNTER_ENABLE 0x0c #define ITE_EC_FAN_TAC_16BIT_ENABLE(x) (1 << ((x)-1)) @@ -68,6 +77,14 @@ : (0x1b + ((x)-1)) \ ) +#define ITE_EC_FAN_TAC_CNTRL 0x0c +#define ITE_EC_TMPIN3_ENHANCED_INT_MODE (1 << 7) +#define ITE_EC_TMPIN2_ENHANCED_INT_MODE (1 << 6) +#define ITE_EC_FAN_TAC5_EN (1 << 5) +#define ITE_EC_FAN_TAC4_EN (1 << 4) +#define ITE_EC_TMPIN1_ENHANCED_INT_MODE (1 << 3) +#define ITE_EC_AMDTSI_ERR_EN (1 << 0) + #define ITE_EC_FAN_MAIN_CTL 0x13 #define ITE_EC_FAN_MAIN_CTL_TAC_EN(x) (1 << ((x)+3)) #define ITE_EC_FAN_MAIN_CTL_COLL_FULL_SPEED (1 << 3) @@ -185,6 +202,8 @@ static const u8 ITE_EC_TEMP_ADJUST[] = { 0x56, 0x57, 0x59 }; /* Common for ITE_EC_FAN_CTL_DELTA_TEMP */ #define ITE_EC_FAN_CTL_DELTA_TEMP_INTRVL(c) ((c) & 0x1f) +#define ITE_EC_FAN_CTL_TARGET_ZONE(x) (0x66 + ((x)-1) * 8) +#define ITE_EC_FAN_CTL_TARGET_ZONE_MASK 0x0f #define ITE_EC_EXTEMP_STATUS 0x88 #define ITE_EC_EXTEMP_STATUS_HOST_BUSY (1 << 0) diff --git a/src/superio/ite/common/env_ctrl_chip.h b/src/superio/ite/common/env_ctrl_chip.h index 923bfa3aeac..f5116e6465f 100644 --- a/src/superio/ite/common/env_ctrl_chip.h +++ b/src/superio/ite/common/env_ctrl_chip.h @@ -101,6 +101,11 @@ struct ite_ec_config { bool tmpin_beep; bool fan_beep; bool vin_beep; + + /* + * Enable SMBus for external thermal sensor. + */ + bool smbus_en; }; /* Some shorthands for device trees */ From 72f6fbb1bc64a68dab121231b186c803e9836ad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 4 Jun 2018 11:16:35 +0300 Subject: [PATCH 304/588] superio/ite: Add IT8786E-I MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Based on IT8786E-I V0.4.1 datasheet with following remark: "Please note that the IT8786E-I V0.4.1 is applicable only to the D version." Signed-off-by: Kyösti Mälkki Signed-off-by: Michał Żygowski Change-Id: I7317da6a72db64f95f9a790ef96ed7a5f93b3aea Reviewed-on: https://review.coreboot.org/c/coreboot/+/30335 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/superio/ite/Makefile.inc | 2 + src/superio/ite/it8786e/Kconfig | 23 +++ src/superio/ite/it8786e/Makefile.inc | 18 +++ src/superio/ite/it8786e/acpi/superio.asl | 171 +++++++++++++++++++++++ src/superio/ite/it8786e/chip.h | 27 ++++ src/superio/ite/it8786e/it8786e.h | 36 +++++ src/superio/ite/it8786e/superio.c | 118 ++++++++++++++++ 7 files changed, 395 insertions(+) create mode 100644 src/superio/ite/it8786e/Kconfig create mode 100644 src/superio/ite/it8786e/Makefile.inc create mode 100644 src/superio/ite/it8786e/acpi/superio.asl create mode 100644 src/superio/ite/it8786e/chip.h create mode 100644 src/superio/ite/it8786e/it8786e.h create mode 100644 src/superio/ite/it8786e/superio.c diff --git a/src/superio/ite/Makefile.inc b/src/superio/ite/Makefile.inc index 551abe9a5dc..8388c7aa386 100644 --- a/src/superio/ite/Makefile.inc +++ b/src/superio/ite/Makefile.inc @@ -2,6 +2,7 @@ ## This file is part of the coreboot project. ## ## Copyright (C) 2009 Ronald G. Minnich +## Copyright (C) 2018 Libretrend LDA ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -31,3 +32,4 @@ subdirs-y += it8721f subdirs-y += it8728f subdirs-y += it8772f subdirs-y += it8783ef +subdirs-y += it8786e diff --git a/src/superio/ite/it8786e/Kconfig b/src/superio/ite/it8786e/Kconfig new file mode 100644 index 00000000000..9d3f258a5a5 --- /dev/null +++ b/src/superio/ite/it8786e/Kconfig @@ -0,0 +1,23 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2016 secunet Security Networks AG +## Copyright (C) 2018 Libretrend LDA +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +config SUPERIO_ITE_IT8786E + bool + select SUPERIO_ITE_COMMON_PRE_RAM + select SUPERIO_ITE_ENV_CTRL + select SUPERIO_ITE_ENV_CTRL_PWM_FREQ2 + select SUPERIO_ITE_ENV_CTRL_8BIT_PWM + select SUPERIO_ITE_ENV_CTRL_7BIT_SLOPE_REG diff --git a/src/superio/ite/it8786e/Makefile.inc b/src/superio/ite/it8786e/Makefile.inc new file mode 100644 index 00000000000..560957ffc51 --- /dev/null +++ b/src/superio/ite/it8786e/Makefile.inc @@ -0,0 +1,18 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2016 secunet Security Networks AG +## Copyright (C) 2018 Libretrend LDA +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +ramstage-$(CONFIG_SUPERIO_ITE_IT8786E) += superio.c diff --git a/src/superio/ite/it8786e/acpi/superio.asl b/src/superio/ite/it8786e/acpi/superio.asl new file mode 100644 index 00000000000..f860da643b3 --- /dev/null +++ b/src/superio/ite/it8786e/acpi/superio.asl @@ -0,0 +1,171 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Christoph Grenz + * Copyright (C) 2013, 2016 secunet Security Networks AG + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * Include this file into a mainboard's DSDT _SB device tree and it will + * expose the IT8786E SuperIO and some of its functionality. + * + * It allows the change of IO ports, IRQs and DMA settings on logical + * devices, disabling and reenabling logical devices. + * + * LDN State + * 0x1 UARTA Implemented, untested + * 0x2 UARTB Implemented, untested + * 0x3 PP Not implemented + * 0x4 EC Not implemented + * 0x5 KBC Implemented, untested + * 0x6 MOUSE Implemented, untested + * 0x7 GPIO Not implemented + * 0x8 UARTC Implemented, untested + * 0x9 UARTD Implemented, untested + * 0xa UARTE Not implemented + * 0xb UARTF Not implemented + * 0xc CIR Not implemented + * + * Controllable through preprocessor defines: + * SUPERIO_DEV Device identifier for this SIO (e.g. SIO0) + * SUPERIO_PNP_BASE I/O address of the first PnP configuration register + * IT8786E_SHOW_UARTA If defined, UARTA will be exposed. + * IT8786E_SHOW_UARTB If defined, UARTB will be exposed. + * IT8786E_SHOW_UARTC If defined, UARTC will be exposed. + * IT8786E_SHOW_UARTD If defined, UARTD will be exposed. + * IT8786E_SHOW_KBC If defined, the KBC will be exposed. + * IT8786E_SHOW_PS2M If defined, PS/2 mouse support will be exposed. + */ + +#undef SUPERIO_CHIP_NAME +#define SUPERIO_CHIP_NAME IT8786E +#include + +#undef PNP_DEFAULT_PSC +#define PNP_DEFAULT_PSC Return (0) /* no power management */ + +#define CONFIGURE_CONTROL CCTL + +Device (SUPERIO_DEV) { + Name (_HID, EisaId("PNP0A05")) + Name (_STR, Unicode("ITE IT8786E Super I/O")) + Name (_UID, SUPERIO_UID(SUPERIO_DEV,)) + + /* Mutex for accesses to the configuration ports */ + Mutex (CRMX, 1) + + /* SuperIO configuration ports */ + OperationRegion (CREG, SystemIO, SUPERIO_PNP_BASE, 0x02) + Field (CREG, ByteAcc, NoLock, Preserve) + { + PNP_ADDR_REG, 8, + PNP_DATA_REG, 8 + } + IndexField (ADDR, DATA, ByteAcc, NoLock, Preserve) + { + Offset (0x02), + CONFIGURE_CONTROL, 8, /* Global configure control */ + + Offset (0x07), + PNP_LOGICAL_DEVICE, 8, /* Logical device selector */ + + Offset (0x30), + PNP_DEVICE_ACTIVE, 1, /* Logical device activation */ + + Offset (0x60), + PNP_IO0_HIGH_BYTE, 8, /* First I/O port base - high byte */ + PNP_IO0_LOW_BYTE, 8, /* First I/O port base - low byte */ + Offset (0x62), + PNP_IO1_HIGH_BYTE, 8, /* Second I/O port base - high byte */ + PNP_IO1_LOW_BYTE, 8, /* Second I/O port base - low byte */ + + Offset (0x70), + PNP_IRQ0, 8, /* First IRQ */ + } + + Method (_CRS) + { + /* Announce the used i/o ports to the OS */ + Return (ResourceTemplate () { + IO (Decode16, SUPERIO_PNP_BASE, SUPERIO_PNP_BASE, + 0x01, 0x02) + }) + } + + #undef PNP_ENTER_MAGIC_1ST + #undef PNP_ENTER_MAGIC_2ND + #undef PNP_ENTER_MAGIC_3RD + #undef PNP_ENTER_MAGIC_4TH + #undef PNP_EXIT_MAGIC_1ST + #define PNP_ENTER_MAGIC_1ST 0x87 + #define PNP_ENTER_MAGIC_2ND 0x01 + #define PNP_ENTER_MAGIC_3RD 0x55 +#if SUPERIO_PNP_BASE == 0x2e + #define PNP_ENTER_MAGIC_4TH 0x55 +#else + #define PNP_ENTER_MAGIC_4TH 0xaa +#endif + #define PNP_EXIT_SPECIAL_REG CONFIGURE_CONTROL + #define PNP_EXIT_SPECIAL_VAL 0x02 + #include + +#ifdef IT8786E_SHOW_UARTA + #undef SUPERIO_UART_LDN + #undef SUPERIO_UART_DDN + #undef SUPERIO_UART_PM_REG + #undef SUPERIO_UART_PM_VAL + #undef SUPERIO_UART_PM_LDN + #define SUPERIO_UART_LDN 1 + #include +#endif + +#ifdef IT8786E_SHOW_UARTB + #undef SUPERIO_UART_LDN + #undef SUPERIO_UART_DDN + #undef SUPERIO_UART_PM_REG + #undef SUPERIO_UART_PM_VAL + #undef SUPERIO_UART_PM_LDN + #define SUPERIO_UART_LDN 2 + #include +#endif + +#ifdef IT8786E_SHOW_KBC + #undef SUPERIO_KBC_LDN + #undef SUPERIO_KBC_PS2M + #undef SUPERIO_KBC_PS2LDN + #define SUPERIO_KBC_LDN 5 +#ifdef IT8786E_SHOW_PS2M + #define SUPERIO_KBC_PS2LDN 6 +#endif + #include +#endif + +#ifdef IT8786E_SHOW_UARTC + #undef SUPERIO_UART_LDN + #undef SUPERIO_UART_DDN + #undef SUPERIO_UART_PM_REG + #undef SUPERIO_UART_PM_VAL + #undef SUPERIO_UART_PM_LDN + #define SUPERIO_UART_LDN 8 + #include +#endif + +#ifdef IT8786E_SHOW_UARTD + #undef SUPERIO_UART_LDN + #undef SUPERIO_UART_DDN + #undef SUPERIO_UART_PM_REG + #undef SUPERIO_UART_PM_VAL + #undef SUPERIO_UART_PM_LDN + #define SUPERIO_UART_LDN 9 + #include +#endif +} diff --git a/src/superio/ite/it8786e/chip.h b/src/superio/ite/it8786e/chip.h new file mode 100644 index 00000000000..4b2e8114756 --- /dev/null +++ b/src/superio/ite/it8786e/chip.h @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2019 Libretrend LDA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SUPERIO_ITE_IT8786E_CHIP_H +#define SUPERIO_ITE_IT8786E_CHIP_H + +#include + +struct superio_ite_it8786e_config { + struct ite_ec_config ec; +}; + +#endif /* SUPERIO_ITE_IT8786E_CHIP_H */ diff --git a/src/superio/ite/it8786e/it8786e.h b/src/superio/ite/it8786e/it8786e.h new file mode 100644 index 00000000000..5f11b636909 --- /dev/null +++ b/src/superio/ite/it8786e/it8786e.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2019 Libretrend LDA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SUPERIO_ITE_IT8786E_H +#define SUPERIO_ITE_IT8786E_H + +#define IT8786E_SP1 0x01 /* COM1 */ +#define IT8786E_SP2 0x02 /* COM2 */ +#define IT8786E_PP 0x03 /* Printer port */ +#define IT8786E_EC 0x04 /* Environment controller */ +#define IT8786E_KBCK 0x05 /* Keyboard */ +#define IT8786E_KBCM 0x06 /* Mouse */ +#define IT8786E_GPIO 0x07 /* GPIO */ +#define IT8786E_SP3 0x08 /* COM3 */ +#define IT8786E_SP4 0x09 /* COM4 */ +#define IT8786E_CIR 0x0a /* Consumer IR */ +#define IT8786E_SP5 0x0b /* COM5 */ +#define IT8786E_SP6 0x0c /* COM6 */ + +#include + +#endif /* SUPERIO_ITE_IT8786E_H */ diff --git a/src/superio/ite/it8786e/superio.c b/src/superio/ite/it8786e/superio.c new file mode 100644 index 00000000000..ac9dc4bc75f --- /dev/null +++ b/src/superio/ite/it8786e/superio.c @@ -0,0 +1,118 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2016 secunet Security Networks AG + * Copyright (C) 2019 Libretrend LDA + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "it8786e.h" +#include "chip.h" + +static void it8786e_init(struct device *const dev) +{ + const struct superio_ite_it8786e_config *conf; + const struct resource *res; + + if (!dev->enabled) + return; + + switch (dev->path.pnp.device) { + case IT8786E_EC: + conf = dev->chip_info; + res = find_resource(dev, PNP_IDX_IO0); + if (!conf || !res) + break; + ite_ec_init(res->base, &conf->ec); + break; + case IT8786E_KBCK: + pc_keyboard_init(NO_AUX_DEVICE); + break; + default: + break; + } +} + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_alt_enable, + .init = it8786e_init, + .ops_pnp_mode = &pnp_conf_mode_870155_aa, +}; + +static struct pnp_info pnp_dev_info[] = { + /* Serial Port 1 */ + { NULL, IT8786E_SP1, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, + /* Serial Port 2 */ + { NULL, IT8786E_SP2, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, + /* Printer Port */ + { NULL, IT8786E_PP, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_DRQ0 | + PNP_MSC0, + 0x0ff8, 0x0ffc, }, + /* Environmental Controller */ + { NULL, IT8786E_EC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0 | + PNP_MSC1 | PNP_MSC2 | PNP_MSC3 | PNP_MSC4 | + PNP_MSC5 | PNP_MSC6 | PNP_MSCA | PNP_MSCB | + PNP_MSCC, + 0x0ff8, 0x0ffc, }, + /* KBC Keyboard */ + { NULL, IT8786E_KBCK, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_MSC0, + 0x0fff, 0x0fff, }, + /* KBC Mouse */ + { NULL, IT8786E_KBCM, PNP_IRQ0 | PNP_MSC0, }, + /* GPIO */ + { NULL, IT8786E_GPIO, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | + PNP_MSC0 | PNP_MSC1 | PNP_MSC2 | PNP_MSC3 | + PNP_MSC4 | PNP_MSC5 | PNP_MSC6 | PNP_MSC7 | + PNP_MSC8 | PNP_MSC9 | PNP_MSCA | PNP_MSCB, + 0x0ffc, 0x0fff, }, + /* Serial Port 3 */ + { NULL, IT8786E_SP3, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, + /* Serial Port 4 */ + { NULL, IT8786E_SP4, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, + /* Consumer Infrared */ + { NULL, IT8786E_CIR, PNP_IO0 | PNP_IRQ0 | PNP_MSC0, 0x0ff8, }, + /* Serial Port 5 */ + { NULL, IT8786E_SP5, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, + /* Serial Port 6 */ + { NULL, IT8786E_SP6, PNP_IO0 | PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | + PNP_MSC2, + 0x0ff8, }, +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), pnp_dev_info); +} + +struct chip_operations superio_ite_it8786e_ops = { + CHIP_NAME("ITE IT8786E Super I/O") + .enable_dev = enable_dev, +}; From 0d4200fef396fb0d1fbf28b4ced475fbf59b5b85 Mon Sep 17 00:00:00 2001 From: Philip Chen Date: Mon, 29 Apr 2019 10:18:24 -0700 Subject: [PATCH 305/588] soc/intel/cannonlake: Support different SPD read type for each slot Also clean up cannonlake_memcfg_init. The major changes include: (1) Add enum 'mem_info_read_type' to spd_info. (2) Add per-dimm-slot spd_info to cnl_mb_cfg. (3) Setup memory config for each slot independently. (4) Squash meminit_memcfg_spd(). BUG=chromium:960581, b:124990009 BRANCH=none TEST=boot hatch, hatch_whl, and kohaku Change-Id: I686a85996858204c20fd05ef24787a0487817c34 Signed-off-by: Philip Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32513 Reviewed-by: Paul Fagerburg Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/romstage.c | 54 +++++++-- .../baseboard/include/baseboard/gpio.h | 7 -- .../baseboard/include/baseboard/variants.h | 3 - .../google/hatch/variants/baseboard/memory.c | 33 +----- .../google/hatch/variants/kohaku/memory.c | 29 +---- src/mainboard/google/sarien/romstage.c | 27 +++-- src/mainboard/intel/coffeelake_rvp/memory.c | 25 +++- src/mainboard/intel/coffeelake_rvp/romstage.c | 10 +- src/soc/intel/cannonlake/cnl_memcfg_init.c | 111 ++++++++++-------- .../cannonlake/include/soc/cnl_memcfg_init.h | 38 +++--- 10 files changed, 177 insertions(+), 160 deletions(-) diff --git a/src/mainboard/google/hatch/romstage.c b/src/mainboard/google/hatch/romstage.c index bdf951b0161..2c630a8ce89 100644 --- a/src/mainboard/google/hatch/romstage.c +++ b/src/mainboard/google/hatch/romstage.c @@ -16,23 +16,63 @@ #include #include #include +#include #include #include #include #include +/* Memory configuration board straps */ +#define GPIO_MEM_CONFIG_0 GPP_F20 +#define GPIO_MEM_CONFIG_1 GPP_F21 +#define GPIO_MEM_CONFIG_2 GPP_F11 +#define GPIO_MEM_CONFIG_3 GPP_F22 + +/* + * GPIO_MEM_CH_SEL is set to 1 for single channel skus + * and 0 for dual channel skus. + */ +#define GPIO_MEM_CH_SEL GPP_F2 + +static int memory_sku(void) +{ + const gpio_t spd_gpios[] = { + GPIO_MEM_CONFIG_0, + GPIO_MEM_CONFIG_1, + GPIO_MEM_CONFIG_2, + GPIO_MEM_CONFIG_3, + }; + + return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); +} + void mainboard_memory_init_params(FSPM_UPD *memupd) { struct cnl_mb_cfg memcfg; - - const struct spd_info spd = { - .spd_by_index = true, - .spd_spec.spd_index = variant_memory_sku(), - }; + int mem_sku; + int is_single_ch_mem; variant_memory_params(&memcfg); - cannonlake_memcfg_init(&memupd->FspmConfig, - &memcfg, &spd); + mem_sku = memory_sku(); + /* + * GPP_F2 is the MEM_CH_SEL gpio, which is set to 1 for single + * channel skus and 0 for dual channel skus. + */ + is_single_ch_mem = gpio_get(GPIO_MEM_CH_SEL); + + /* + * spd[0]-spd[3] map to CH0D0, CH0D1, CH1D0, CH1D1 respectively. + * Dual-DIMM memory is not used in hatch family, so we only + * fill in spd_info for CH0D0 and CH1D0 here. + */ + memcfg.spd[0].read_type = READ_SPD_CBFS; + memcfg.spd[0].spd_spec.spd_index = mem_sku; + if (!is_single_ch_mem) { + memcfg.spd[2].read_type = READ_SPD_CBFS; + memcfg.spd[2].spd_spec.spd_index = mem_sku; + } + + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } void mainboard_get_dram_part_num(const char **part_num, size_t *len) diff --git a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/gpio.h b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/gpio.h index 5d6311ba243..e83732cb62e 100644 --- a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/gpio.h +++ b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/gpio.h @@ -22,13 +22,6 @@ #define GPIO_PCH_WP GPP_C20 -/* Memory configuration board straps */ -#define GPIO_MEM_CONFIG_0 GPP_F20 -#define GPIO_MEM_CONFIG_1 GPP_F21 -#define GPIO_MEM_CONFIG_2 GPP_F11 -#define GPIO_MEM_CONFIG_3 GPP_F22 - - /* EC wake pin is LAN_WAKE# */ #define GPE_EC_WAKE GPE0_LAN_WAK diff --git a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/variants.h b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/variants.h index d41ad536f21..17bd5df63d1 100644 --- a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/variants.h +++ b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/variants.h @@ -31,9 +31,6 @@ const struct pad_config *base_early_gpio_table(size_t *num); const struct pad_config *override_gpio_table(size_t *num); const struct pad_config *override_early_gpio_table(size_t *num); -/* Return memory SKU for the board. */ -int variant_memory_sku(void); - /* Return board specific memory configuration */ void variant_memory_params(struct cnl_mb_cfg *bcfg); diff --git a/src/mainboard/google/hatch/variants/baseboard/memory.c b/src/mainboard/google/hatch/variants/baseboard/memory.c index 580bdc9ab37..bcfc49f20e6 100644 --- a/src/mainboard/google/hatch/variants/baseboard/memory.c +++ b/src/mainboard/google/hatch/variants/baseboard/memory.c @@ -15,16 +15,15 @@ #include #include -#include #include #include static const struct cnl_mb_cfg baseboard_memcfg = { /* Baseboard uses 121, 81 and 100 rcomp resistors */ - .rcomp_resistor = { 121, 81, 100 }, + .rcomp_resistor = {121, 81, 100}, /* Baseboard Rcomp target values */ - .rcomp_targets = { 100, 40, 20, 20, 26 }, + .rcomp_targets = {100, 40, 20, 20, 26}, /* Set CaVref config to 2 */ .vref_ca_config = 2, @@ -36,32 +35,4 @@ static const struct cnl_mb_cfg baseboard_memcfg = { void __weak variant_memory_params(struct cnl_mb_cfg *bcfg) { memcpy(bcfg, &baseboard_memcfg, sizeof(baseboard_memcfg)); - /* - * GPP_F2 is the MEM_CH_SEL gpio, which is set to 1 for single - * channel skus and 0 for dual channel skus. - */ - if (gpio_get(GPP_F2) == 1) { - /* - * Single channel config: for Hatch, Channel 0 is - * always populated. - */ - bcfg->channel_empty[0] = 0; - bcfg->channel_empty[1] = 1; - } else { - /* Dual channel config: both channels populated. */ - bcfg->channel_empty[0] = 0; - bcfg->channel_empty[1] = 0; - } -} - -int __weak variant_memory_sku(void) -{ - const gpio_t spd_gpios[] = { - GPIO_MEM_CONFIG_0, - GPIO_MEM_CONFIG_1, - GPIO_MEM_CONFIG_2, - GPIO_MEM_CONFIG_3, - }; - - return gpio_base2_value(spd_gpios, ARRAY_SIZE(spd_gpios)); } diff --git a/src/mainboard/google/hatch/variants/kohaku/memory.c b/src/mainboard/google/hatch/variants/kohaku/memory.c index 27ae3d8fb26..490124776e1 100644 --- a/src/mainboard/google/hatch/variants/kohaku/memory.c +++ b/src/mainboard/google/hatch/variants/kohaku/memory.c @@ -15,7 +15,6 @@ #include #include -#include #include #include @@ -30,8 +29,8 @@ static const struct cnl_mb_cfg baseboard_memcfg = { * the index = pin number on SoC * the value = pin number on lpddr3 part */ - .dqs_map[DDR_CH0] = { 0, 1, 3, 2, 5, 7, 6, 4 }, - .dqs_map[DDR_CH1] = { 1, 3, 2, 0, 5, 7, 6, 4 }, + .dqs_map[DDR_CH0] = {0, 1, 3, 2, 5, 7, 6, 4}, + .dqs_map[DDR_CH1] = {1, 3, 2, 0, 5, 7, 6, 4}, .dq_map[DDR_CH0] = { {0xf, 0xf0}, @@ -40,7 +39,7 @@ static const struct cnl_mb_cfg baseboard_memcfg = { {0xf, 0x0}, {0xff, 0x0}, {0xff, 0x0} - }, + }, .dq_map[DDR_CH1] = { {0xf, 0xf0}, {0x0, 0xf0}, @@ -48,13 +47,13 @@ static const struct cnl_mb_cfg baseboard_memcfg = { {0xf, 0x0}, {0xff, 0x0}, {0xff, 0x0} - }, + }, /* Kohaku uses 200, 80.6 and 162 rcomp resistors */ - .rcomp_resistor = { 200, 81, 162 }, + .rcomp_resistor = {200, 81, 162}, /* Kohaku Rcomp target values */ - .rcomp_targets = { 100, 40, 40, 23, 40 }, + .rcomp_targets = {100, 40, 40, 23, 40}, /* Set CaVref config to 0 for LPDDR3 */ .vref_ca_config = 0, @@ -66,20 +65,4 @@ static const struct cnl_mb_cfg baseboard_memcfg = { void variant_memory_params(struct cnl_mb_cfg *bcfg) { memcpy(bcfg, &baseboard_memcfg, sizeof(baseboard_memcfg)); - /* - * GPP_F2 is the MEM_CH_SEL gpio, which is set to 1 for single - * channel skus and 0 for dual channel skus. - */ - if (gpio_get(GPP_F2) == 1) { - /* - * Single channel config: for kohaku, Channel 0 is - * always populated. - */ - bcfg->channel_empty[0] = 0; - bcfg->channel_empty[1] = 1; - } else { - /* Dual channel config: both channels populated. */ - bcfg->channel_empty[0] = 0; - bcfg->channel_empty[1] = 0; - } } diff --git a/src/mainboard/google/sarien/romstage.c b/src/mainboard/google/sarien/romstage.c index e83cd4aed45..20eee7f34b8 100644 --- a/src/mainboard/google/sarien/romstage.c +++ b/src/mainboard/google/sarien/romstage.c @@ -18,6 +18,18 @@ #include static const struct cnl_mb_cfg memcfg = { + /* Access memory info through SMBUS. */ + .spd[0] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xa0}, + }, + .spd[1] = {.read_type = NOT_EXISTING}, + .spd[2] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xa4}, + }, + .spd[3] = {.read_type = NOT_EXISTING}, + /* * The dqs_map arrays map the ddr4 pins to the SoC pins * for both channels. @@ -25,16 +37,16 @@ static const struct cnl_mb_cfg memcfg = { * the index = pin number on ddr4 part * the value = pin number on SoC */ - .dqs_map[DDR_CH0] = { 0, 1, 4, 5, 2, 3, 6, 7 }, - .dqs_map[DDR_CH1] = { 0, 1, 4, 5, 2, 3, 6, 7 }, + .dqs_map[DDR_CH0] = {0, 1, 4, 5, 2, 3, 6, 7}, + .dqs_map[DDR_CH1] = {0, 1, 4, 5, 2, 3, 6, 7}, /* Baseboard uses 121, 81 and 100 rcomp resistors */ - .rcomp_resistor = { 121, 81, 100 }, + .rcomp_resistor = {121, 81, 100}, /* * Baseboard Rcomp target values. */ - .rcomp_targets = { 100, 40, 20, 20, 26 }, + .rcomp_targets = {100, 40, 20, 20, 26}, /* Disable Early Command Training */ .ect = 0, @@ -45,12 +57,7 @@ static const struct cnl_mb_cfg memcfg = { void mainboard_memory_init_params(FSPM_UPD *memupd) { - const struct spd_info spd = { - .spd_smbus_address[0] = 0xa0, - .spd_smbus_address[2] = 0xa4 - }; - wilco_ec_romstage_init(); - cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg, &spd); + cannonlake_memcfg_init(&memupd->FspmConfig, &memcfg); } diff --git a/src/mainboard/intel/coffeelake_rvp/memory.c b/src/mainboard/intel/coffeelake_rvp/memory.c index a13000cc13d..b093a20d2c8 100644 --- a/src/mainboard/intel/coffeelake_rvp/memory.c +++ b/src/mainboard/intel/coffeelake_rvp/memory.c @@ -20,6 +20,23 @@ #include static const struct cnl_mb_cfg baseboard_memcfg_cfg = { + /* Access memory info through SMBUS. */ + .spd[0] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xA0} + }, + .spd[1] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xA2} + }, + .spd[2] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xA4} + }, + .spd[3] = { + .read_type = READ_SMBUS, + .spd_spec = {.spd_smbus_address = 0xA6} + }, /* * The dqs_map arrays map the ddr4 pins to the SoC pins * for both channels. @@ -27,16 +44,16 @@ static const struct cnl_mb_cfg baseboard_memcfg_cfg = { * the index = pin number on ddr4 part * the value = pin number on SoC */ - .dqs_map[DDR_CH0] = { 0, 1, 3, 2, 4, 5, 6, 7 }, - .dqs_map[DDR_CH1] = { 1, 0, 4, 5, 2, 3, 6, 7 }, + .dqs_map[DDR_CH0] = {0, 1, 3, 2, 4, 5, 6, 7}, + .dqs_map[DDR_CH1] = {1, 0, 4, 5, 2, 3, 6, 7}, /* Baseboard uses 121, 81 and 100 rcomp resistors */ - .rcomp_resistor = { 121, 81, 100 }, + .rcomp_resistor = {121, 81, 100}, /* * Baseboard Rcomp target values. */ - .rcomp_targets = { 100, 40, 20, 20, 26 }, + .rcomp_targets = {100, 40, 20, 20, 26}, /* Baseboard is an interleaved design */ .dq_pins_interleaved = 1, diff --git a/src/mainboard/intel/coffeelake_rvp/romstage.c b/src/mainboard/intel/coffeelake_rvp/romstage.c index 1ab2d78b5a4..09ef148e362 100644 --- a/src/mainboard/intel/coffeelake_rvp/romstage.c +++ b/src/mainboard/intel/coffeelake_rvp/romstage.c @@ -20,13 +20,5 @@ void mainboard_memory_init_params(FSPM_UPD *memupd) { - const struct spd_info spd = { - .spd_smbus_address[0] = 0xA0, - .spd_smbus_address[1] = 0xA2, - .spd_smbus_address[2] = 0xA4, - .spd_smbus_address[3] = 0xA6, - }; - - cannonlake_memcfg_init(&memupd->FspmConfig, - variant_memcfg_config(), &spd); + cannonlake_memcfg_init(&memupd->FspmConfig, variant_memcfg_config()); } diff --git a/src/soc/intel/cannonlake/cnl_memcfg_init.c b/src/soc/intel/cannonlake/cnl_memcfg_init.c index db001b82aea..4ebd9978ae2 100644 --- a/src/soc/intel/cannonlake/cnl_memcfg_init.c +++ b/src/soc/intel/cannonlake/cnl_memcfg_init.c @@ -20,7 +20,7 @@ #include static void meminit_memcfg(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *board_cfg) + const struct cnl_mb_cfg *board_cfg) { /* * DqByteMapChx expects 12 bytes of data, but the last 6 bytes @@ -29,47 +29,58 @@ static void meminit_memcfg(FSP_M_CONFIG *mem_cfg, */ memset(&mem_cfg->DqByteMapCh0, 0, sizeof(mem_cfg->DqByteMapCh0)); memcpy(&mem_cfg->DqByteMapCh0, &board_cfg->dq_map[DDR_CH0], - sizeof(board_cfg->dq_map[DDR_CH0])); + sizeof(board_cfg->dq_map[DDR_CH0])); memset(&mem_cfg->DqByteMapCh1, 0, sizeof(mem_cfg->DqByteMapCh1)); memcpy(&mem_cfg->DqByteMapCh1, &board_cfg->dq_map[DDR_CH1], - sizeof(board_cfg->dq_map[DDR_CH1])); + sizeof(board_cfg->dq_map[DDR_CH1])); memcpy(&mem_cfg->DqsMapCpu2DramCh0, &board_cfg->dqs_map[DDR_CH0], - sizeof(board_cfg->dqs_map[DDR_CH0])); + sizeof(board_cfg->dqs_map[DDR_CH0])); memcpy(&mem_cfg->DqsMapCpu2DramCh1, &board_cfg->dqs_map[DDR_CH1], - sizeof(board_cfg->dqs_map[DDR_CH1])); + sizeof(board_cfg->dqs_map[DDR_CH1])); memcpy(&mem_cfg->RcompResistor, &board_cfg->rcomp_resistor, - sizeof(mem_cfg->RcompResistor)); + sizeof(mem_cfg->RcompResistor)); /* Early cannonlake requires rcomp targets to be 0 */ memcpy(&mem_cfg->RcompTarget, &board_cfg->rcomp_targets, - sizeof(mem_cfg->RcompTarget)); + sizeof(mem_cfg->RcompTarget)); } -static void meminit_memcfg_spd(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *cnl_cfg, - size_t spd_data_len, uintptr_t spd_data_ptr) +/* + * Initialize default memory settings using spd data contained in a buffer. + */ +static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, uint8_t mem_slot, + size_t spd_data_len, uintptr_t spd_data_ptr) { + static size_t last_set_spd_data_len = 0; + + assert(spd_data_ptr != 0 && spd_data_len != 0); + + if (last_set_spd_data_len != 0 && + last_set_spd_data_len != spd_data_len) + die("spd data length disparity among slots"); + mem_cfg->MemorySpdDataLen = spd_data_len; + last_set_spd_data_len = spd_data_len; - if (cnl_cfg->channel_empty[0] == 0) + switch (mem_slot) { + case 0: mem_cfg->MemorySpdPtr00 = spd_data_ptr; - - if (cnl_cfg->channel_empty[1] == 0) + break; + case 1: + mem_cfg->MemorySpdPtr01 = spd_data_ptr; + break; + case 2: mem_cfg->MemorySpdPtr10 = spd_data_ptr; -} - -/* - * Initialize default memory settings using spd data contained in a buffer. - */ -static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *cnl_cfg, - size_t spd_data_len, uintptr_t spd_data_ptr) -{ - assert(spd_data_ptr && spd_data_len); - meminit_memcfg_spd(mem_cfg, cnl_cfg, spd_data_len, spd_data_ptr); + break; + case 3: + mem_cfg->MemorySpdPtr11 = spd_data_ptr; + break; + default: + die("nonexistent memory slot"); + } } /* @@ -78,13 +89,13 @@ static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, * in spd/Makefile.inc. */ static void meminit_cbfs_spd_index(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *cnl_cfg, - int spd_index) + int spd_index, uint8_t mem_slot) { size_t spd_data_len; uintptr_t spd_data_ptr; struct region_device spd_rdev; + assert(mem_slot < NUM_DIMM_SLOT); printk(BIOS_DEBUG, "SPD INDEX = %d\n", spd_index); if (get_spd_cbfs_rdev(&spd_rdev, spd_index) < 0) die("spd.bin not found or incorrect index\n"); @@ -92,40 +103,42 @@ static void meminit_cbfs_spd_index(FSP_M_CONFIG *mem_cfg, /* Memory leak is ok since we have memory mapped boot media */ assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); spd_data_ptr = (uintptr_t)rdev_mmap_full(&spd_rdev); - meminit_spd_data(mem_cfg, cnl_cfg, spd_data_len, spd_data_ptr); + meminit_spd_data(mem_cfg, mem_slot, spd_data_len, spd_data_ptr); } /* Initialize onboard memory configurations for CannonLake */ void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *cnl_cfg, - const struct spd_info *spd) + const struct cnl_mb_cfg *cnl_cfg) { - bool OnModuleSpd = false; + const struct spd_info *spdi; + /* Early Command Training Enabled */ mem_cfg->ECT = cnl_cfg->ect; mem_cfg->DqPinsInterleaved = cnl_cfg->dq_pins_interleaved; mem_cfg->CaVrefConfig = cnl_cfg->vref_ca_config; - /* Spd pointer will only be used if all smbus slave address of memory - * sockets on the platform is empty */ - for (int i = 0; i < ARRAY_SIZE(mem_cfg->SpdAddressTable); i++) { - if (spd->spd_smbus_address[i] != 0) { - mem_cfg->SpdAddressTable[i] = spd->spd_smbus_address[i]; - OnModuleSpd = true; + for (int i = 0; i < NUM_DIMM_SLOT; i++) { + spdi = &(cnl_cfg->spd[i]); + switch (spdi->read_type) { + case NOT_EXISTING: + break; + case READ_SMBUS: + mem_cfg->SpdAddressTable[i] = + spdi->spd_spec.spd_smbus_address; + break; + case READ_SPD_CBFS: + meminit_cbfs_spd_index(mem_cfg, + spdi->spd_spec.spd_index, i); + break; + case READ_SPD_MEMPTR: + meminit_spd_data(mem_cfg, i, + spdi->spd_spec.spd_data_ptr_info.spd_data_len, + spdi->spd_spec.spd_data_ptr_info.spd_data_ptr); + break; + default: + die("no valid way to read mem info"); } - } - if (!OnModuleSpd) { - if (spd->spd_by_index) { - meminit_cbfs_spd_index(mem_cfg, cnl_cfg, - spd->spd_spec.spd_index); - } else { - meminit_spd_data(mem_cfg, cnl_cfg, - spd->spd_spec.spd_data_ptr_info.spd_data_len, - spd->spd_spec.spd_data_ptr_info.spd_data_ptr); - } + meminit_memcfg(mem_cfg, cnl_cfg); } - - meminit_memcfg(mem_cfg, cnl_cfg); - } diff --git a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h index e602a33f785..d5f6c39f24e 100644 --- a/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h +++ b/src/soc/intel/cannonlake/include/soc/cnl_memcfg_init.h @@ -23,6 +23,9 @@ /* Number of dq bits controlled per dqs */ #define DQ_BITS_PER_DQS 8 +/* Number of memory DIMM slots available on Cannonlake board */ +#define NUM_DIMM_SLOT 4 + /* * Number of memory packages, where a "package" represents a 64-bit solution. */ @@ -40,17 +43,32 @@ struct spd_by_pointer { uintptr_t spd_data_ptr; }; +enum mem_info_read_type { + NOT_EXISTING, /* No memory in this slot */ + READ_SMBUS, /* Read on-module spd by SMBUS. */ + READ_SPD_CBFS, /* Find spd file in CBFS. */ + READ_SPD_MEMPTR /* Find spd data from pointer. */ +}; + struct spd_info { - bool spd_by_index; + enum mem_info_read_type read_type; union spd_data_by { + /* To read on-module spd when read_type is READ_SMBUS. */ + uint8_t spd_smbus_address; + + /* To identify spd file when read_type is READ_SPD_CBFS. */ int spd_index; + + /* To find spd data when read_type is READ_SPD_MEMPTR. */ struct spd_by_pointer spd_data_ptr_info; } spd_spec; - uint8_t spd_smbus_address[4]; }; /* Board-specific memory dq mapping information */ struct cnl_mb_cfg { + /* Parameters required to access SPD for CH0D0/CH0D1/CH1D0/CH1D1. */ + struct spd_info spd[NUM_DIMM_SLOT]; + /* * For each channel, there are 6 sets of DQ byte mappings, * where each set has a package 0 and a package 1 value (package 0 @@ -107,26 +125,12 @@ struct cnl_mb_cfg { /* Early Command Training Enabled */ uint8_t ect; - - /* - * Flags to indicate which channels are populated. We - * currently support single or dual channel configurations. - * Set 1 to indicate that the channel is not populated Set 0 - * to indicate that the channel is populated. For example, - * dual channel memory configuration would have both - * channel_empty[0] = 0 and channel_empty[1] = 0. Note that - * this flag is only used for soldered down DRAM where we get - * SPD data from CBFS. We need the value 0 to default to - * populated in order to support existing boards. - */ - uint8_t channel_empty[2]; }; /* * Initialize default memory configurations for CannonLake. */ void cannonlake_memcfg_init(FSP_M_CONFIG *mem_cfg, - const struct cnl_mb_cfg *cnl_cfg, - const struct spd_info *spd); + const struct cnl_mb_cfg *cnl_cfg); #endif /* _SOC_CANNONLAKE_MEMCFG_INIT_H_ */ From 2968c9d6c7bff8d126aee6fba329ce92bd65c86e Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Wed, 8 May 2019 13:38:29 +0800 Subject: [PATCH 306/588] mb/google/poppy/variants/rammus: Support new onboard Hynix memory Add hynix_dimm_H9CCNNNCLGALAR-NVD for new onboard memory support. BUG=b:130337306 BRANCH=firmware-rammus-11275.B TEST=emerge-rammus coreboot chromeos-ec chromeos-bootimage Flash FW to DUT, and make sure system boots up. Signed-off-by: YanRu Chen Change-Id: Ibd02953d0c6ac62fa4d7751fd8b103b74433aa73 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32674 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../spd/hynix_dimm_H9CCNNNCLGALAR-NVD.spd.hex | 16 ++++++++++++++++ .../google/poppy/variants/rammus/Makefile.inc | 1 + 2 files changed, 17 insertions(+) create mode 100644 src/mainboard/google/poppy/spd/hynix_dimm_H9CCNNNCLGALAR-NVD.spd.hex diff --git a/src/mainboard/google/poppy/spd/hynix_dimm_H9CCNNNCLGALAR-NVD.spd.hex b/src/mainboard/google/poppy/spd/hynix_dimm_H9CCNNNCLGALAR-NVD.spd.hex new file mode 100644 index 00000000000..ada67c96202 --- /dev/null +++ b/src/mainboard/google/poppy/spd/hynix_dimm_H9CCNNNCLGALAR-NVD.spd.hex @@ -0,0 +1,16 @@ +91 20 F1 03 05 1A 05 0A 03 11 01 08 08 00 00 15 +78 78 90 50 90 11 50 E0 90 06 3C 3C 01 90 00 00 +00 00 C2 00 00 00 00 A8 00 88 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 80 AD 01 00 00 00 00 00 00 00 00 +48 39 43 43 4E 4E 4E 43 4C 47 41 4C 41 52 2D 4E +56 44 00 00 80 AD 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/google/poppy/variants/rammus/Makefile.inc b/src/mainboard/google/poppy/variants/rammus/Makefile.inc index 44dd07bcded..0d835cbe88c 100644 --- a/src/mainboard/google/poppy/variants/rammus/Makefile.inc +++ b/src/mainboard/google/poppy/variants/rammus/Makefile.inc @@ -3,6 +3,7 @@ SPD_SOURCES += samsung_dimm_K4E8E324EB-EGCF # 0b0001 SPD_SOURCES += micron_dimm_MT52L256M32D1PF-093 # 0b0010 SPD_SOURCES += samsung_dimm_K4E6E304EC-EGCF # 0b0011 SPD_SOURCES += micron_dimm_MT52L256M32D1PF-107 # 0b0100 +SPD_SOURCES += hynix_dimm_H9CCNNNCLGALAR-NVD # 0b0101 bootblock-y += gpio.c From 111f9a9bcd710c3ee1ac89cf81b603a2de23cc62 Mon Sep 17 00:00:00 2001 From: Puthikorn Voravootivat Date: Mon, 13 May 2019 16:24:15 -0700 Subject: [PATCH 307/588] mb/google/poppy/variants/atlas: Remove B0D4 _PSV Per Intel, the internal thermal protection is working better than putting B0D4 _PSV in dptf. BUG=b:131251533 TEST=Get ~10% better Octane score. Correct TCC and TCC offset in MSR register. Change-Id: If85afdc673687477ec85a47efcb264a7e5d6ae45 Signed-off-by: Puthikorn Voravootivat Reviewed-on: https://review.coreboot.org/c/coreboot/+/32779 Tested-by: build bot (Jenkins) Reviewed-by: Caveh Jalali --- .../google/poppy/variants/atlas/include/variant/acpi/dptf.asl | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/mainboard/google/poppy/variants/atlas/include/variant/acpi/dptf.asl b/src/mainboard/google/poppy/variants/atlas/include/variant/acpi/dptf.asl index 29c1d3f38b5..570fbbbdfa9 100644 --- a/src/mainboard/google/poppy/variants/atlas/include/variant/acpi/dptf.asl +++ b/src/mainboard/google/poppy/variants/atlas/include/variant/acpi/dptf.asl @@ -49,9 +49,6 @@ Name (CHPS, Package () { }) Name (DTRT, Package () { - /* CPU Throttle Effect on CPU */ - Package () { \_SB.PCI0.B0D4, \_SB.PCI0.B0D4, 100, 50, 0, 0, 0, 0 }, - /* CPU Throttle Effect on Ambient */ Package () { \_SB.PCI0.B0D4, \_SB.DPTF.TSR0, 100, 200, 0, 0, 0, 0 }, From caef7f837aee60a405ad8a923e97e4a6ba3aaa9c Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 13 May 2019 20:39:26 +0200 Subject: [PATCH 308/588] mb/packardbell/ms2290/acpi: Serialize Control Method IASL reports remarks 'Control Method should be made Serialized'. Change-Id: I5606c6e435da17f7d4732148f6ddcedb1fde4ab0 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32769 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/packardbell/ms2290/acpi/battery.asl | 2 +- src/mainboard/packardbell/ms2290/acpi/ec.asl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/packardbell/ms2290/acpi/battery.asl b/src/mainboard/packardbell/ms2290/acpi/battery.asl index 716c3a62de7..d341ab44886 100644 --- a/src/mainboard/packardbell/ms2290/acpi/battery.asl +++ b/src/mainboard/packardbell/ms2290/acpi/battery.asl @@ -52,7 +52,7 @@ Method(BSTA, 4, NotSerialized) Return (Arg1) } -Method(BINF, 2, NotSerialized) +Method(BINF, 2, Serialized) { Acquire(ECLK, 0xffff) Store(0, PAGE) diff --git a/src/mainboard/packardbell/ms2290/acpi/ec.asl b/src/mainboard/packardbell/ms2290/acpi/ec.asl index 5fb2498a3e2..4f3e5b6c163 100644 --- a/src/mainboard/packardbell/ms2290/acpi/ec.asl +++ b/src/mainboard/packardbell/ms2290/acpi/ec.asl @@ -101,7 +101,7 @@ Device(EC) BAOE, 128, /* Battery OEM info */ } - Method (_CRS, 0) + Method (_CRS, 0, Serialized) { Name (ECMD, ResourceTemplate() { From 18b51b7315bea0031f05f14dcad82857716d264e Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Fri, 10 May 2019 12:33:08 +0800 Subject: [PATCH 309/588] vboot: rename BOOT_OPROM_NEEDED to BOOT_DISPLAY_REQUEST Verified Boot OPROM code is being refactored. OPROM is being generalized into "display initialization". As such, the NVRAM request flag is being renamed from OPROM_NEEDED to DISPLAY_REQUEST. BUG=b:124141368, b:124192753, chromium:948529 TEST=make clean && make test-abuild BRANCH=none Change-Id: I74374abf7d1deb594c073f7a4a76c9de46092143 Signed-off-by: Joel Kitching Cq-Depend: chromium:1605640 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32720 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Paul Menzel Reviewed-by: Julius Werner --- src/security/vboot/vbnv.c | 4 ++-- src/security/vboot/vbnv_layout.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/security/vboot/vbnv.c b/src/security/vboot/vbnv.c index b99941875c2..78502f74ee7 100644 --- a/src/security/vboot/vbnv.c +++ b/src/security/vboot/vbnv.c @@ -140,11 +140,11 @@ int get_recovery_mode_from_vbnv(void) return vbnv_data(RECOVERY_OFFSET); } -/* Read the BOOT_OPROM_NEEDED flag from VBNV. */ +/* Read the BOOT_DISPLAY_REQUEST flag from VBNV. */ int vboot_wants_oprom(void) { vbnv_setup(); - return (vbnv_data(BOOT_OFFSET) & BOOT_OPROM_NEEDED) ? 1 : 0; + return (vbnv_data(BOOT_OFFSET) & BOOT_DISPLAY_REQUEST) ? 1 : 0; } /* Read the USB Device Controller(UDC) enable flag from VBNV. */ diff --git a/src/security/vboot/vbnv_layout.h b/src/security/vboot/vbnv_layout.h index a9326e4ff46..a3c2490c0d6 100644 --- a/src/security/vboot/vbnv_layout.h +++ b/src/security/vboot/vbnv_layout.h @@ -31,7 +31,7 @@ #define BOOT_OFFSET 1 #define BOOT_DEBUG_RESET_MODE 0x80 #define BOOT_DISABLE_DEV_REQUEST 0x40 -#define BOOT_OPROM_NEEDED 0x20 +#define BOOT_DISPLAY_REQUEST 0x20 #define BOOT_TRY_B_COUNT_MASK 0x0F #define RECOVERY_OFFSET 2 From 807803afa2d10cfd818d7f1585e0279f09fc1e14 Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Fri, 10 May 2019 12:58:53 +0800 Subject: [PATCH 310/588] vboot: remove OPROM-related code As of CL:1605641, vboot2 code should be used for setting and checking display init state. Remove all vboot1 OPROM-related code, and use the vboot2 display init code which has already been added in previous commits. coreboot should not be reading vboot NVRAM flags directly. Remove the function vboot_wants_oprom(), and instead rely on display_init_required(), which uses the VBOOT_WD_FLAG_DISPLAY_INIT value stored in vboot_working_data.flags, initialized during verstage. Note that this means in the case of CONFIG_VBOOT=y, the return value of display_init_required() can only be trusted after verstage has been executed. This should not be a problem assuming that all display initialization occurs in ramstage. BUG=b:124141368, b:124192753, chromium:948529 TEST=Build locally TEST=make clean && make test-abuild BRANCH=none Change-Id: Ic8f9dc5a3c7f1546a8fed82bde02be4d04568f8d Signed-off-by: Joel Kitching Cq-Depend: chromium:1605641, chromium:1605525 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32723 Reviewed-by: Furquan Shaikh Reviewed-by: Paul Menzel Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/device/pci_device.c | 3 --- src/security/vboot/vbnv.c | 7 ------- src/security/vboot/vbnv.h | 1 - src/security/vboot/vboot_handoff.c | 7 ------- src/soc/intel/broadwell/igd.c | 2 +- 5 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/device/pci_device.c b/src/device/pci_device.c index b5453c7e76b..31c35dc02ea 100644 --- a/src/device/pci_device.c +++ b/src/device/pci_device.c @@ -780,9 +780,6 @@ static int should_run_oprom(struct device *dev) */ should_run = display_init_required(); - if (!should_run && CONFIG(VBOOT)) - should_run = vboot_wants_oprom(); - if (!should_run) printk(BIOS_DEBUG, "Not running VGA Option ROM\n"); return should_run; diff --git a/src/security/vboot/vbnv.c b/src/security/vboot/vbnv.c index 78502f74ee7..0c4f33bc119 100644 --- a/src/security/vboot/vbnv.c +++ b/src/security/vboot/vbnv.c @@ -140,13 +140,6 @@ int get_recovery_mode_from_vbnv(void) return vbnv_data(RECOVERY_OFFSET); } -/* Read the BOOT_DISPLAY_REQUEST flag from VBNV. */ -int vboot_wants_oprom(void) -{ - vbnv_setup(); - return (vbnv_data(BOOT_OFFSET) & BOOT_DISPLAY_REQUEST) ? 1 : 0; -} - /* Read the USB Device Controller(UDC) enable flag from VBNV. */ int vbnv_udc_enable_flag(void) { diff --git a/src/security/vboot/vbnv.h b/src/security/vboot/vbnv.h index c8e689fa04c..a2f0b4c9781 100644 --- a/src/security/vboot/vbnv.h +++ b/src/security/vboot/vbnv.h @@ -25,7 +25,6 @@ int verify_vbnv(uint8_t *vbnv_copy); void regen_vbnv_crc(uint8_t *vbnv_copy); int get_recovery_mode_from_vbnv(void); void set_recovery_mode_into_vbnv(int recovery_reason); -int vboot_wants_oprom(void); /* Read the USB Device Controller(UDC) enable flag from VBNV. */ int vbnv_udc_enable_flag(void); diff --git a/src/security/vboot/vboot_handoff.c b/src/security/vboot/vboot_handoff.c index fccbdfc0b71..8a6b3d61e88 100644 --- a/src/security/vboot/vboot_handoff.c +++ b/src/security/vboot/vboot_handoff.c @@ -68,13 +68,6 @@ static void fill_vboot_handoff(struct vboot_handoff *vboot_handoff, vb_sd->flags |= VBSD_BOOT_DEV_SWITCH_ON; vb_sd->flags |= VBSD_LF_DEV_SWITCH_ON; } - /* TODO(chromium:948529): Remove these two flags after downstream - vboot code longer reads them. */ - if (vboot_wants_oprom() || vb2_sd->recovery_reason || - vb2_sd->flags & VB2_SD_FLAG_DEV_MODE_ENABLED) - vb_sd->flags |= VBSD_OPROM_LOADED; - if (CONFIG(VBOOT_MUST_REQUEST_DISPLAY)) - vb_sd->flags |= VBSD_OPROM_MATTERS; /* In vboot1, VBSD_FWB_TRIED is * set only if B is booted as explicitly requested. Therefore, if B is diff --git a/src/soc/intel/broadwell/igd.c b/src/soc/intel/broadwell/igd.c index 319549df1e6..b9b42810fcb 100644 --- a/src/soc/intel/broadwell/igd.c +++ b/src/soc/intel/broadwell/igd.c @@ -513,7 +513,7 @@ static void igd_init(struct device *dev) /* Wait for any configured pre-graphics delay */ if (!acpi_is_wakeup_s3()) { #if CONFIG(CHROMEOS) - if (display_init_required() || vboot_wants_oprom()) + if (display_init_required()) mdelay(CONFIG_PRE_GRAPHICS_DELAY); #else mdelay(CONFIG_PRE_GRAPHICS_DELAY); From 724c66c88fa219087f4d6a0ccce1ba1d6f93c93b Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Mon, 13 May 2019 17:04:00 -0600 Subject: [PATCH 311/588] libpayload: ahci: Prevent memory leaks when failing on init Free several resources when AHCI initialization fails. Note that it is only safe to free resources when the command engine has stopped, since otherwise they may still be used for DMA. Found-by: Coverity CID 1260719, 1260727, 1261090, 1261098 Signed-off-by: Jacob Garber Change-Id: I6826d79338b26ff9696ab6ac9eb4c59f734687d8 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32778 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Nico Huber --- payloads/libpayload/drivers/storage/ahci.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/payloads/libpayload/drivers/storage/ahci.c b/payloads/libpayload/drivers/storage/ahci.c index 40e1008cf45..f74adafd752 100644 --- a/payloads/libpayload/drivers/storage/ahci.c +++ b/payloads/libpayload/drivers/storage/ahci.c @@ -108,6 +108,9 @@ static int ahci_dev_init(hba_ctrl_t *const ctrl, const int ncs = HBA_CAPS_DECODE_NCS(ctrl->caps); + if (ahci_cmdengine_stop(port)) + return 1; + /* Allocate command list, one command table and received FIS. */ cmd_t *const cmdlist = memalign(1024, ncs * sizeof(cmd_t)); cmdtable_t *const cmdtable = memalign(128, sizeof(cmdtable_t)); @@ -121,12 +124,10 @@ static int ahci_dev_init(hba_ctrl_t *const ctrl, memset((void *)rcvd_fis, '\0', sizeof(*rcvd_fis)); /* Set command list base and received FIS base. */ - if (ahci_cmdengine_stop(port)) - return 1; port->cmdlist_base = virt_to_phys(cmdlist); port->frameinfo_base = virt_to_phys(rcvd_fis); if (ahci_cmdengine_start(port)) - return 1; + goto _cleanup_ret; /* Put port into active state. */ port->cmd_stat |= HBA_PxCMD_ICC_ACTIVE; @@ -178,6 +179,8 @@ static int ahci_dev_init(hba_ctrl_t *const ctrl, /* Clean up (not reached for initialized devices). */ if (dev) free(dev); + /* Only free if stopping succeeds, since otherwise the controller may + still use the resources for DMA. */ if (!ahci_cmdengine_stop(port)) { port->cmdlist_base = 0; port->frameinfo_base = 0; From 56f768774a25320d738febf99c335abdb6eeafbe Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 14:01:13 +0200 Subject: [PATCH 312/588] soc/intel/broadwell: Use the common cpu/intel/car romstage entry The only functional difference is the use of stack guards. Change-Id: I95645271e0d93a97f544a1cc4e9a4320738e6a20 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32761 Tested-by: build bot (Jenkins) Reviewed-by: Matt DeVillier Reviewed-by: Nico Huber --- src/soc/intel/broadwell/romstage/Makefile.inc | 1 + src/soc/intel/broadwell/romstage/romstage.c | 23 ++++--------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc index 2d562d98efc..cc0a05124fe 100644 --- a/src/soc/intel/broadwell/romstage/Makefile.inc +++ b/src/soc/intel/broadwell/romstage/Makefile.inc @@ -1,5 +1,6 @@ cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S +romstage-y += ../../../../cpu/intel/car/romstage.c romstage-y += cpu.c romstage-y += pch.c romstage-y += power_state.c diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index acbca14a886..25c47c62c2d 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,7 @@ /* platform_enter_postcar() determines the stack to use after * cache-as-ram is torn down as well as the MTRR settings to use, * and continues execution in postcar stage. */ -static void platform_enter_postcar(void) +void platform_enter_postcar(void) { struct postcar_frame pcf; uintptr_t top_of_ram; @@ -63,8 +64,8 @@ static void platform_enter_postcar(void) run_postcar_phase(&pcf); } -/* Entry from cache-as-ram.inc. */ -static void romstage_main(uint64_t tsc, uint32_t bist) +/* Entry from cpu/intel/car/romstage.c. */ +void mainboard_romstage_entry(unsigned long bist) { struct romstage_params rp = { .bist = bist, @@ -72,12 +73,6 @@ static void romstage_main(uint64_t tsc, uint32_t bist) post_code(0x30); - /* Save initial timestamp from bootblock. */ - timestamp_init(tsc); - - /* Save romstage begin */ - timestamp_add_now(TS_START_ROMSTAGE); - /* System Agent Early Initialization */ systemagent_early_init(); @@ -131,16 +126,6 @@ static void romstage_main(uint64_t tsc, uint32_t bist) romstage_handoff_init(rp.power_state->prev_sleep_state == ACPI_S3); mainboard_post_raminit(&rp); - - platform_enter_postcar(); -} - -/* This wrapper enables easy transition towards C_ENVIRONMENT_BOOTBLOCK, - * keeping changes in cache_as_ram.S easy to manage. - */ -asmlinkage void bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist) -{ - romstage_main(base_timestamp, bist); } void __weak mainboard_pre_console_init(void) {} From 5bb15f1a4d18bafaf51b17fd9ea6d861f2b9ebd2 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 22 Dec 2018 16:02:25 +0100 Subject: [PATCH 313/588] soc/intel/broadwell: Use C_ENVIRONMENT_BOOTBLOCK This puts the cache-as-ram init in the bootblock. Before setting up cache as ram the microcode updates are applied. This removes the possibility for a normal/fallback setup although implementing this should be quite easy. Setting up LPC in the bootblock to output console on SuperIOs is not done in this patch, therefore BOOTBLOCK_CONSOLE is not yet selected. Change-Id: I44eb6d380dea5b82e3f009a46381a0f611bb7935 Signed-off-by: Arthur Heymans Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/30383 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/soc/intel/broadwell/Kconfig | 21 +++---- src/soc/intel/broadwell/Makefile.inc | 8 +++ src/soc/intel/broadwell/bootblock/cpu.c | 63 ++----------------- src/soc/intel/broadwell/bootblock/pch.c | 3 +- .../intel/broadwell/bootblock/systemagent.c | 3 +- src/soc/intel/broadwell/romstage/Makefile.inc | 2 - src/soc/intel/broadwell/romstage/romstage.c | 4 +- 7 files changed, 26 insertions(+), 78 deletions(-) diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 83ccf7b9d81..9dd2f4f4144 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -44,6 +44,8 @@ config CPU_SPECIFIC_OPTIONS select HAVE_POWER_STATE_AFTER_FAILURE select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE select NO_FIXED_XIP_ROM_SIZE + select C_ENVIRONMENT_BOOTBLOCK + select NO_BOOTBLOCK_CONSOLE config PCIEXP_ASPM bool @@ -69,18 +71,6 @@ config VBOOT select VBOOT_MUST_REQUEST_DISPLAY select VBOOT_STARTS_IN_ROMSTAGE -config BOOTBLOCK_CPU_INIT - string - default "soc/intel/broadwell/bootblock/cpu.c" - -config BOOTBLOCK_NORTHBRIDGE_INIT - string - default "soc/intel/broadwell/bootblock/systemagent.c" - -config BOOTBLOCK_SOUTHBRIDGE_INIT - string - default "soc/intel/broadwell/bootblock/pch.c" - config MMCONF_BASE_ADDRESS hex default 0xf0000000 @@ -123,6 +113,13 @@ config DCACHE_RAM_MRC_VAR_SIZE help The amount of cache-as-ram region required by the reference code. +config DCACHE_BSP_STACK_SIZE + hex + default 0x2000 + help + The amount of anticipated stack usage in CAR by bootblock and + other stages. + config HAVE_MRC bool "Add a Memory Reference Code binary" help diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc index 1caf67adf4d..eab8b37ba26 100644 --- a/src/soc/intel/broadwell/Makefile.inc +++ b/src/soc/intel/broadwell/Makefile.inc @@ -9,6 +9,13 @@ subdirs-y += ../../../cpu/intel/microcode subdirs-y += ../../../cpu/intel/turbo subdirs-y += ../../../cpu/intel/common +bootblock-y += bootblock/cpu.c +bootblock-y += bootblock/pch.c +bootblock-y += bootblock/systemagent.c +bootblock-y += ../../../cpu/intel/car/bootblock.c +bootblock-y += ../../../cpu/intel/car/non-evict/cache_as_ram.S +bootblock-y += ../../../cpu/x86/early_reset.S + ramstage-y += acpi.c ramstage-y += adsp.c ramstage-y += chip.c @@ -58,6 +65,7 @@ ramstage-y += stage_cache.c romstage-y += stage_cache.c postcar-y += stage_cache.c ramstage-y += systemagent.c +bootblock-y += tsc_freq.c ramstage-y += tsc_freq.c romstage-y += tsc_freq.c smm-y += tsc_freq.c diff --git a/src/soc/intel/broadwell/bootblock/cpu.c b/src/soc/intel/broadwell/bootblock/cpu.c index 2f1ac51981f..f3c35f3441f 100644 --- a/src/soc/intel/broadwell/bootblock/cpu.c +++ b/src/soc/intel/broadwell/bootblock/cpu.c @@ -19,47 +19,10 @@ #include #include #include -#include #include #include - -static void set_var_mtrr(unsigned int reg, unsigned int base, unsigned int size, - unsigned int type) -{ - /* Bit Bit 32-35 of MTRRphysMask should be set to 1 */ - msr_t basem, maskm; - basem.lo = base | type; - basem.hi = 0; - wrmsr(MTRR_PHYS_BASE(reg), basem); - maskm.lo = ~(size - 1) | MTRR_PHYS_MASK_VALID; - maskm.hi = (1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1; - wrmsr(MTRR_PHYS_MASK(reg), maskm); -} - -static void enable_rom_caching(void) -{ - msr_t msr; - - disable_cache(); - set_var_mtrr(1, CACHE_ROM_BASE, CACHE_ROM_SIZE, MTRR_TYPE_WRPROT); - enable_cache(); - - /* Enable Variable MTRRs */ - msr.hi = 0x00000000; - msr.lo = 0x00000800; - wrmsr(MTRR_DEF_TYPE_MSR, msr); -} - -static void bootblock_mdelay(int ms) -{ - u32 target = ms * 24 * 1000; - msr_t current; - msr_t start = rdmsr(MSR_COUNTER_24_MHZ); - - do { - current = rdmsr(MSR_COUNTER_24_MHZ); - } while ((current.lo - start.lo) < target); -} +#include +#include static void set_flex_ratio_to_tdp_nominal(void) { @@ -102,7 +65,7 @@ static void set_flex_ratio_to_tdp_nominal(void) RCBA32_OR(SOFT_RESET_CTRL, 1); /* Delay before reset to avoid potential TPM lockout */ - bootblock_mdelay(30); + mdelay(30); /* Issue warm reset, will be "CPU only" due to soft reset data */ outb(0x0, 0xcf9); @@ -110,26 +73,8 @@ static void set_flex_ratio_to_tdp_nominal(void) halt(); } -static void check_for_clean_reset(void) -{ - msr_t msr; - msr = rdmsr(MTRR_DEF_TYPE_MSR); - - /* Use the MTRR default type MSR as a proxy for detecting INIT#. - * Reset the system if any known bits are set in that MSR. That is - * an indication of the CPU not being properly reset. */ - if (msr.lo & (MTRR_DEF_TYPE_EN | MTRR_DEF_TYPE_FIX_EN)) { - outb(0x0, 0xcf9); - outb(0x6, 0xcf9); - halt(); - } -} - -static void bootblock_cpu_init(void) +void bootblock_early_cpu_init(void) { /* Set flex ratio and reset if needed */ set_flex_ratio_to_tdp_nominal(); - check_for_clean_reset(); - enable_rom_caching(); - intel_update_microcode_from_cbfs(); } diff --git a/src/soc/intel/broadwell/bootblock/pch.c b/src/soc/intel/broadwell/bootblock/pch.c index dc7f42a6253..1301610947a 100644 --- a/src/soc/intel/broadwell/bootblock/pch.c +++ b/src/soc/intel/broadwell/bootblock/pch.c @@ -19,6 +19,7 @@ #include #include #include +#include /* * Enable Prefetching and Caching. @@ -66,7 +67,7 @@ static void set_spi_speed(void) SPIBAR8(SPIBAR_SSFC + 2) = ssfc; } -static void bootblock_southbridge_init(void) +void bootblock_early_southbridge_init(void) { map_rcba(); enable_spi_prefetch(); diff --git a/src/soc/intel/broadwell/bootblock/systemagent.c b/src/soc/intel/broadwell/bootblock/systemagent.c index e618636eb29..7aaed789ac4 100644 --- a/src/soc/intel/broadwell/bootblock/systemagent.c +++ b/src/soc/intel/broadwell/bootblock/systemagent.c @@ -16,8 +16,9 @@ #include #include #include +#include -static void bootblock_northbridge_init(void) +void bootblock_early_northbridge_init(void) { uint32_t reg; diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc index cc0a05124fe..ea17d67061e 100644 --- a/src/soc/intel/broadwell/romstage/Makefile.inc +++ b/src/soc/intel/broadwell/romstage/Makefile.inc @@ -1,5 +1,3 @@ -cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S - romstage-y += ../../../../cpu/intel/car/romstage.c romstage-y += cpu.c romstage-y += pch.c diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 25c47c62c2d..54434a31536 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -67,9 +67,7 @@ void platform_enter_postcar(void) /* Entry from cpu/intel/car/romstage.c. */ void mainboard_romstage_entry(unsigned long bist) { - struct romstage_params rp = { - .bist = bist, - }; + struct romstage_params rp = { 0 }; post_code(0x30); From 4d56a0625516ba436903d59d9c0a4a13827d89be Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 22 Dec 2018 16:11:52 +0100 Subject: [PATCH 314/588] nb/intel/broadwell: Add an option for where verstage starts Previously broadwell used a romcc bootblock and starting verstage in romstage was madatory but with C_ENVIRONMENT_BOOTBLOCK it is also possible to have a separate verstage. This selects using a separate verstage by default but still keeps the option around to use verstage in romstage. With a separate verstage the romstage becomes an RW stage. The mrc.bin however is only added to the RO COREBOOT fmap region as it requires to be run at a specific offset. This means that coreboot will have to jump from a RW region to the RO region for that binary and back to that RW region after that binary is done initializing the memory. Change-Id: I900233cadb3c76da329fb98f93917570e633365f Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30384 Reviewed-by: Nico Huber Reviewed-by: Matt DeVillier Tested-by: build bot (Jenkins) --- src/mainboard/google/auron/Makefile.inc | 1 + src/mainboard/google/jecht/Makefile.inc | 1 + src/mainboard/intel/wtm2/Makefile.inc | 1 + src/soc/intel/broadwell/Kconfig | 25 +++++++++++++++++++++- src/soc/intel/broadwell/Makefile.inc | 2 ++ src/soc/intel/broadwell/romstage/raminit.c | 7 +++++- 6 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/auron/Makefile.inc b/src/mainboard/google/auron/Makefile.inc index c81aeaf0f6e..d2b6d0eb9a6 100644 --- a/src/mainboard/google/auron/Makefile.inc +++ b/src/mainboard/google/auron/Makefile.inc @@ -17,6 +17,7 @@ ramstage-$(CONFIG_EC_GOOGLE_CHROMEEC) += ec.c romstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c +bootblock-$(CONFIG_CHROMEOS) += chromeos.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c diff --git a/src/mainboard/google/jecht/Makefile.inc b/src/mainboard/google/jecht/Makefile.inc index 39e9b339e87..28a284e759c 100644 --- a/src/mainboard/google/jecht/Makefile.inc +++ b/src/mainboard/google/jecht/Makefile.inc @@ -16,6 +16,7 @@ subdirs-y += spd romstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_CHROMEOS) += chromeos.c +verstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-y += lan.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c led.c diff --git a/src/mainboard/intel/wtm2/Makefile.inc b/src/mainboard/intel/wtm2/Makefile.inc index 4c944f2773d..c4afb98cc5b 100644 --- a/src/mainboard/intel/wtm2/Makefile.inc +++ b/src/mainboard/intel/wtm2/Makefile.inc @@ -15,6 +15,7 @@ romstage-y += gpio.c +verstage-y += chromeos.c romstage-y += chromeos.c ramstage-y += chromeos.c diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 9dd2f4f4144..b685391af93 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -67,9 +67,25 @@ config PCIEXP_L1_SUB_STATE bool default y +config BROADWELL_VBOOT_IN_BOOTBLOCK + depends on VBOOT + bool "Start verstage in bootblock" + default y + select VBOOT_STARTS_IN_BOOTBLOCK + select VBOOT_SEPARATE_VERSTAGE + help + Broadwell can either start verstage in a separate stage + right after the bootblock has run or it can start it + after romstage for compatibility reasons. + Broadwell however uses a mrc.bin to initialse memory which + needs to be located at a fixed offset. Therefore even with + a separate verstage starting after the bootblock that same + binary is used meaning a jump is made from RW to the RO region + and back to the RW region after the binary is done. + config VBOOT select VBOOT_MUST_REQUEST_DISPLAY - select VBOOT_STARTS_IN_ROMSTAGE + select VBOOT_STARTS_IN_ROMSTAGE if !BROADWELL_VBOOT_IN_BOOTBLOCK config MMCONF_BASE_ADDRESS hex @@ -141,6 +157,13 @@ config MRC_BIN_ADDRESS hex default 0xfffa0000 +# The UEFI System Agent binary needs to be at a fixed offset in the flash +# and can therefore only reside in the COREBOOT fmap region +config RO_REGION_ONLY + string + depends on VBOOT + default "mrc.bin" + endif # HAVE_MRC config PRE_GRAPHICS_DELAY diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc index eab8b37ba26..40017eb3ec1 100644 --- a/src/soc/intel/broadwell/Makefile.inc +++ b/src/soc/intel/broadwell/Makefile.inc @@ -49,6 +49,7 @@ romstage-y += pei_data.c ramstage-y += pmutil.c romstage-y += pmutil.c smm-y += pmutil.c +verstage-y += pmutil.c ramstage-y += ramstage.c ramstage-$(CONFIG_HAVE_REFCODE_BLOB) += refcode.c ramstage-y += sata.c @@ -70,6 +71,7 @@ ramstage-y += tsc_freq.c romstage-y += tsc_freq.c smm-y += tsc_freq.c postcar-y += tsc_freq.c +verstage-y += tsc_freq.c bootblock-$(CONFIG_USBDEBUG) += usb_debug.c romstage-$(CONFIG_USBDEBUG) += usb_debug.c ramstage-$(CONFIG_USBDEBUG) += usb_debug.c diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c index 8d43907f8aa..fc8b7c6984a 100644 --- a/src/soc/intel/broadwell/romstage/raminit.c +++ b/src/soc/intel/broadwell/romstage/raminit.c @@ -45,6 +45,8 @@ void raminit(struct pei_data *pei_data) struct memory_info *mem_info; pei_wrapper_entry_t entry; int ret; + struct cbfsf f; + uint32_t type = CBFS_TYPE_MRC; broadwell_fill_pei_data(pei_data); @@ -77,7 +79,10 @@ void raminit(struct pei_data *pei_data) } /* Determine if mrc.bin is in the cbfs. */ - entry = cbfs_boot_map_with_leak("mrc.bin", CBFS_TYPE_MRC, NULL); + if (cbfs_locate_file_in_region(&f, "COREBOOT", "mrc.bin", &type) < 0) + die("mrc.bin not found!"); + /* We don't care about leaking the mapping */ + entry = (pei_wrapper_entry_t)rdev_mmap_full(&f.data); if (entry == NULL) { printk(BIOS_DEBUG, "Couldn't find mrc.bin\n"); return; From e43972474c0eebc478722f7c371a8c68318f24cf Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 22 Dec 2018 16:59:44 +0100 Subject: [PATCH 315/588] soc/intel/broadwell: Enable LPC/SIO setup in bootblock This allows for serial console during the bootblock and enables bootblock console by default. Change-Id: I7746e4f819486d6142c96bc4c7480076fbfdfbde Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30385 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Matt DeVillier --- src/mainboard/google/jecht/Makefile.inc | 4 +- src/mainboard/google/jecht/bootblock.c | 31 ++++++++++++ src/mainboard/google/jecht/romstage.c | 12 ----- src/soc/intel/broadwell/Kconfig | 1 - src/soc/intel/broadwell/bootblock/pch.c | 49 +++++++++++++++++++ .../intel/broadwell/include/soc/romstage.h | 1 - src/soc/intel/broadwell/romstage/pch.c | 41 ---------------- src/soc/intel/broadwell/romstage/romstage.c | 9 ---- 8 files changed, 83 insertions(+), 65 deletions(-) create mode 100644 src/mainboard/google/jecht/bootblock.c diff --git a/src/mainboard/google/jecht/Makefile.inc b/src/mainboard/google/jecht/Makefile.inc index 28a284e759c..116792fab7b 100644 --- a/src/mainboard/google/jecht/Makefile.inc +++ b/src/mainboard/google/jecht/Makefile.inc @@ -24,7 +24,9 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c led.c romstage-y += variants/$(VARIANT_DIR)/pei_data.c ramstage-y += variants/$(VARIANT_DIR)/pei_data.c -romstage-y += led.c +bootblock-y += led.c + +bootblock-y += bootblock.c subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include diff --git a/src/mainboard/google/jecht/bootblock.c b/src/mainboard/google/jecht/bootblock.c new file mode 100644 index 00000000000..43725cd7472 --- /dev/null +++ b/src/mainboard/google/jecht/bootblock.c @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2010 coresystems GmbH + * Copyright (C) 2014 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "onboard.h" + +void bootblock_mainboard_early_init(void) +{ + /* Early SuperIO setup */ + it8772f_ac_resume_southbridge(IT8772F_SUPERIO_DEV); + ite_kill_watchdog(IT8772F_GPIO_DEV); + ite_enable_serial(IT8772F_SERIAL_DEV, CONFIG_TTYS0_BASE); + + /* Turn On Power LED */ + set_power_led(LED_ON); +} diff --git a/src/mainboard/google/jecht/romstage.c b/src/mainboard/google/jecht/romstage.c index 86888c82f88..4fc2ba0c93b 100644 --- a/src/mainboard/google/jecht/romstage.c +++ b/src/mainboard/google/jecht/romstage.c @@ -39,15 +39,3 @@ void mainboard_post_raminit(struct romstage_params *rp) if (CONFIG(CHROMEOS)) init_bootmode_straps(); } - -void mainboard_pre_console_init(void) -{ - /* Early SuperIO setup */ - it8772f_ac_resume_southbridge(IT8772F_SUPERIO_DEV); - ite_kill_watchdog(IT8772F_GPIO_DEV); - ite_enable_serial(IT8772F_SERIAL_DEV, CONFIG_TTYS0_BASE); - - /* Turn On Power LED */ - set_power_led(LED_ON); - -} diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index b685391af93..d81ab8ac951 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -45,7 +45,6 @@ config CPU_SPECIFIC_OPTIONS select HAVE_POWER_STATE_PREVIOUS_AFTER_FAILURE select NO_FIXED_XIP_ROM_SIZE select C_ENVIRONMENT_BOOTBLOCK - select NO_BOOTBLOCK_CONSOLE config PCIEXP_ASPM bool diff --git a/src/soc/intel/broadwell/bootblock/pch.c b/src/soc/intel/broadwell/bootblock/pch.c index 1301610947a..590961b3617 100644 --- a/src/soc/intel/broadwell/bootblock/pch.c +++ b/src/soc/intel/broadwell/bootblock/pch.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include /* @@ -67,10 +70,56 @@ static void set_spi_speed(void) SPIBAR8(SPIBAR_SSFC + 2) = ssfc; } +const struct reg_script pch_early_init_script[] = { + /* Setup southbridge BARs */ + REG_PCI_WRITE32(RCBA, RCBA_BASE_ADDRESS | 1), + REG_PCI_WRITE32(PMBASE, ACPI_BASE_ADDRESS | 1), + REG_PCI_WRITE8(ACPI_CNTL, ACPI_EN), + REG_PCI_WRITE32(GPIO_BASE, GPIO_BASE_ADDRESS | 1), + REG_PCI_WRITE8(GPIO_CNTL, GPIO_EN), + + /* Set COM1/COM2 decode range */ + REG_PCI_WRITE16(LPC_IO_DEC, 0x0010), + /* Enable legacy decode ranges */ + REG_PCI_WRITE16(LPC_EN, CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | + COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN), + + /* Enable IOAPIC */ + REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + OIC, 0x0100), + /* Read back for posted write */ + REG_MMIO_READ16(RCBA_BASE_ADDRESS + OIC), + + /* Set HPET address and enable it */ + REG_MMIO_RMW32(RCBA_BASE_ADDRESS + HPTC, ~3, (1 << 7)), + /* Read back for posted write */ + REG_MMIO_READ32(RCBA_BASE_ADDRESS + HPTC), + /* Enable HPET to start counter */ + REG_MMIO_OR32(HPET_BASE_ADDRESS + 0x10, (1 << 0)), + + /* Disable reset */ + REG_MMIO_OR32(RCBA_BASE_ADDRESS + GCS, (1 << 5)), + /* TCO timer halt */ + REG_IO_OR16(ACPI_BASE_ADDRESS + TCO1_CNT, TCO_TMR_HLT), + + /* Enable upper 128 bytes of CMOS */ + REG_MMIO_OR32(RCBA_BASE_ADDRESS + RC, (1 << 2)), + + /* Disable unused device (always) */ + REG_MMIO_OR32(RCBA_BASE_ADDRESS + FD, PCH_DISABLE_ALWAYS), + + REG_SCRIPT_END +}; + +static void pch_early_lpc(void) +{ + reg_script_run_on_dev(PCH_DEV_LPC, pch_early_init_script); +} + void bootblock_early_southbridge_init(void) { map_rcba(); enable_spi_prefetch(); enable_port80_on_lpc(); set_spi_speed(); + pch_early_lpc(); } diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index d65692ae23a..ece3cd8c5a1 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -50,5 +50,4 @@ int smbus_read_byte(unsigned int device, unsigned int address); int early_spi_read(u32 offset, u32 size, u8 *buffer); int early_spi_read_wpsr(u8 *sr); -void mainboard_pre_console_init(void); #endif diff --git a/src/soc/intel/broadwell/romstage/pch.c b/src/soc/intel/broadwell/romstage/pch.c index ecdadb7f9bf..ef97a1e3fa2 100644 --- a/src/soc/intel/broadwell/romstage/pch.c +++ b/src/soc/intel/broadwell/romstage/pch.c @@ -27,46 +27,6 @@ #include #include -const struct reg_script pch_early_init_script[] = { - /* Setup southbridge BARs */ - REG_PCI_WRITE32(RCBA, RCBA_BASE_ADDRESS | 1), - REG_PCI_WRITE32(PMBASE, ACPI_BASE_ADDRESS | 1), - REG_PCI_WRITE8(ACPI_CNTL, ACPI_EN), - REG_PCI_WRITE32(GPIO_BASE, GPIO_BASE_ADDRESS | 1), - REG_PCI_WRITE8(GPIO_CNTL, GPIO_EN), - - /* Set COM1/COM2 decode range */ - REG_PCI_WRITE16(LPC_IO_DEC, 0x0010), - /* Enable legacy decode ranges */ - REG_PCI_WRITE16(LPC_EN, CNF1_LPC_EN | CNF2_LPC_EN | GAMEL_LPC_EN | - COMA_LPC_EN | KBC_LPC_EN | MC_LPC_EN), - - /* Enable IOAPIC */ - REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + OIC, 0x0100), - /* Read back for posted write */ - REG_MMIO_READ16(RCBA_BASE_ADDRESS + OIC), - - /* Set HPET address and enable it */ - REG_MMIO_RMW32(RCBA_BASE_ADDRESS + HPTC, ~3, (1 << 7)), - /* Read back for posted write */ - REG_MMIO_READ32(RCBA_BASE_ADDRESS + HPTC), - /* Enable HPET to start counter */ - REG_MMIO_OR32(HPET_BASE_ADDRESS + 0x10, (1 << 0)), - - /* Disable reset */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + GCS, (1 << 5)), - /* TCO timer halt */ - REG_IO_OR16(ACPI_BASE_ADDRESS + TCO1_CNT, TCO_TMR_HLT), - - /* Enable upper 128 bytes of CMOS */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + RC, (1 << 2)), - - /* Disable unused device (always) */ - REG_MMIO_OR32(RCBA_BASE_ADDRESS + FD, PCH_DISABLE_ALWAYS), - - REG_SCRIPT_END -}; - const struct reg_script pch_interrupt_init_script[] = { /* * GFX INTA -> PIRQA (MSI) @@ -132,7 +92,6 @@ static void pch_enable_lpc(void) void pch_early_init(void) { - reg_script_run_on_dev(PCH_DEV_LPC, pch_early_init_script); reg_script_run_on_dev(PCH_DEV_LPC, pch_interrupt_init_script); pch_enable_lpc(); diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 54434a31536..f8571678d86 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -77,13 +77,6 @@ void mainboard_romstage_entry(unsigned long bist) /* PCH Early Initialization */ pch_early_init(); - /* Call into mainboard pre console init. Needed to enable serial port - on IT8772 */ - mainboard_pre_console_init(); - - /* Start console drivers */ - console_init(); - /* Get power state */ rp.power_state = fill_power_state(); @@ -125,5 +118,3 @@ void mainboard_romstage_entry(unsigned long bist) mainboard_post_raminit(&rp); } - -void __weak mainboard_pre_console_init(void) {} From caae2690325256036ed371646c0ce5d2115aed29 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 12 May 2019 12:44:00 +0200 Subject: [PATCH 316/588] soc/intel/broadwell/romstage: Clean up unused bist variable Checking BIST is done in the bootblock. Change-Id: I3ea2eb6a37c038f7348f0abd2056eee5c07bdb9d Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32757 Reviewed-by: Matt DeVillier Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/soc/intel/broadwell/include/soc/romstage.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index ece3cd8c5a1..ac8265fb4cb 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -22,7 +22,6 @@ struct chipset_power_state; struct romstage_params { - unsigned long bist; struct chipset_power_state *power_state; struct pei_data pei_data; }; From 65209de411b4f87d7ebf9a3d82e91324a841f3be Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:57:01 +0200 Subject: [PATCH 317/588] autoport: Remove unneeded include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7cb4b47e2fd893274303bb20dc7fa895830b4493 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32787 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- util/autoport/bd82x6x.go | 1 - 1 file changed, 1 deletion(-) diff --git a/util/autoport/bd82x6x.go b/util/autoport/bd82x6x.go index a97ff1d9613..e93704ec4a3 100644 --- a/util/autoport/bd82x6x.go +++ b/util/autoport/bd82x6x.go @@ -302,7 +302,6 @@ func (b bd82x6x) Scan(ctx Context, addr PCIDevData) { #include #include #include -#include #include #include #include From 5bc493a8a2f53e834ac5be98725acf7601c70dbc Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:56:32 +0200 Subject: [PATCH 318/588] src/southbridge: Remove unneeded include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: If358e221021466f0058bfc84a322750b34a36d5f Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32786 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/southbridge/intel/bd82x6x/early_usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/southbridge/intel/bd82x6x/early_usb.c b/src/southbridge/intel/bd82x6x/early_usb.c index 955737e2a85..e5d5625cab9 100644 --- a/src/southbridge/intel/bd82x6x/early_usb.c +++ b/src/southbridge/intel/bd82x6x/early_usb.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include From 45b79be9c06ccc925eeb3c11e821413478b903b5 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:55:56 +0200 Subject: [PATCH 319/588] src/soc: Remove unneeded include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I5a7b53a07fe6fd6121067dcec004e81eb284edbb Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32785 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/amd/stoneyridge/enable_usbdebug.c | 1 - src/soc/amd/stoneyridge/southbridge.c | 1 - 2 files changed, 2 deletions(-) diff --git a/src/soc/amd/stoneyridge/enable_usbdebug.c b/src/soc/amd/stoneyridge/enable_usbdebug.c index 90bd6e8f336..19b95508478 100644 --- a/src/soc/amd/stoneyridge/enable_usbdebug.c +++ b/src/soc/amd/stoneyridge/enable_usbdebug.c @@ -17,7 +17,6 @@ #define __SIMPLE_DEVICE__ #include -#include #include #include #include diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index 8dfef8b369f..b6c40b63d34 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -15,7 +15,6 @@ #include -#include #include #include #include From 274dabd7a04b18bc2f2378bb9faa7416dfd0ab83 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:55:17 +0200 Subject: [PATCH 320/588] src/northbridge: Remove unneeded include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I52ace93ae6f802723823955ac349ed54dc064aaa Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32784 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/northbridge/intel/gm45/early_reset.c | 1 - src/northbridge/intel/gm45/romstage.c | 1 - src/northbridge/intel/haswell/raminit.c | 1 - src/northbridge/intel/i945/raminit.c | 1 - src/northbridge/intel/pineview/raminit.c | 1 - src/northbridge/intel/pineview/romstage.c | 1 - src/northbridge/intel/sandybridge/raminit.c | 1 - src/northbridge/intel/sandybridge/raminit_mrc.c | 1 - src/northbridge/intel/sandybridge/romstage.c | 1 - src/northbridge/intel/x4x/raminit.c | 1 - 10 files changed, 10 deletions(-) diff --git a/src/northbridge/intel/gm45/early_reset.c b/src/northbridge/intel/gm45/early_reset.c index 3f095a256ff..b5aa8044bef 100644 --- a/src/northbridge/intel/gm45/early_reset.c +++ b/src/northbridge/intel/gm45/early_reset.c @@ -15,7 +15,6 @@ */ #include -#include #include #include diff --git a/src/northbridge/intel/gm45/romstage.c b/src/northbridge/intel/gm45/romstage.c index 15d3c3a344d..38f2d5f68f1 100644 --- a/src/northbridge/intel/gm45/romstage.c +++ b/src/northbridge/intel/gm45/romstage.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 96dc94e7d20..050dbd1ae61 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/northbridge/intel/i945/raminit.c b/src/northbridge/intel/i945/raminit.c index 74407c14ffb..797ea1229d2 100644 --- a/src/northbridge/intel/i945/raminit.c +++ b/src/northbridge/intel/i945/raminit.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/pineview/raminit.c b/src/northbridge/intel/pineview/raminit.c index 144905fb92e..282765efcc6 100644 --- a/src/northbridge/intel/pineview/raminit.c +++ b/src/northbridge/intel/pineview/raminit.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/northbridge/intel/pineview/romstage.c b/src/northbridge/intel/pineview/romstage.c index a3e6c391721..41fb0f6720d 100644 --- a/src/northbridge/intel/pineview/romstage.c +++ b/src/northbridge/intel/pineview/romstage.c @@ -17,7 +17,6 @@ * so this one is named with prefix mainboard. */ -#include #include #include #include diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index e60c37875bd..2ebeaf0dca5 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index a35d9d814e8..f032b8aefc0 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/northbridge/intel/sandybridge/romstage.c b/src/northbridge/intel/sandybridge/romstage.c index 064d042e564..76b30883887 100644 --- a/src/northbridge/intel/sandybridge/romstage.c +++ b/src/northbridge/intel/sandybridge/romstage.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c index 60d3b55531b..7fed1efe266 100644 --- a/src/northbridge/intel/x4x/raminit.c +++ b/src/northbridge/intel/x4x/raminit.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include From 8b7a16145254deff4ba5191463707d6981017357 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:54:30 +0200 Subject: [PATCH 321/588] src/mainboard: Remove unneeded include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I73c557d6ef009fb2cac35fdea500dee76f525330 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32783 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/mainboard/apple/macbook21/romstage.c | 1 - src/mainboard/asus/p5gc-mx/romstage.c | 1 - src/mainboard/asus/p5qpl-am/romstage.c | 1 - src/mainboard/ibase/mb899/romstage.c | 1 - src/mainboard/intel/baskingridge/chromeos.c | 1 - src/mainboard/intel/dcp847ske/early_southbridge.c | 1 - src/mainboard/intel/emeraldlake2/chromeos.c | 1 - src/mainboard/kontron/986lcd-m/romstage.c | 1 - src/mainboard/lenovo/x60/romstage.c | 1 - src/mainboard/lenovo/z61t/romstage.c | 1 - 10 files changed, 10 deletions(-) diff --git a/src/mainboard/apple/macbook21/romstage.c b/src/mainboard/apple/macbook21/romstage.c index 468cffb7d93..1c84c8432b4 100644 --- a/src/mainboard/apple/macbook21/romstage.c +++ b/src/mainboard/apple/macbook21/romstage.c @@ -18,7 +18,6 @@ /* __PRE_RAM__ means: use "unsigned" for device, not a struct. */ #include -#include #include #include #include diff --git a/src/mainboard/asus/p5gc-mx/romstage.c b/src/mainboard/asus/p5gc-mx/romstage.c index 08379f78a1c..b076b9d7fb7 100644 --- a/src/mainboard/asus/p5gc-mx/romstage.c +++ b/src/mainboard/asus/p5gc-mx/romstage.c @@ -18,7 +18,6 @@ // __PRE_RAM__ means: use "unsigned" for device, not a struct. #include -#include #include #include #include diff --git a/src/mainboard/asus/p5qpl-am/romstage.c b/src/mainboard/asus/p5qpl-am/romstage.c index bd6bfc6ee7d..7d028434d67 100644 --- a/src/mainboard/asus/p5qpl-am/romstage.c +++ b/src/mainboard/asus/p5qpl-am/romstage.c @@ -15,7 +15,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/mainboard/ibase/mb899/romstage.c b/src/mainboard/ibase/mb899/romstage.c index 9cb1144b80c..c98556c30f6 100644 --- a/src/mainboard/ibase/mb899/romstage.c +++ b/src/mainboard/ibase/mb899/romstage.c @@ -16,7 +16,6 @@ // __PRE_RAM__ means: use "unsigned" for device, not a struct. #include -#include #include #include #include diff --git a/src/mainboard/intel/baskingridge/chromeos.c b/src/mainboard/intel/baskingridge/chromeos.c index 1673622793a..6561927d3b8 100644 --- a/src/mainboard/intel/baskingridge/chromeos.c +++ b/src/mainboard/intel/baskingridge/chromeos.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/intel/dcp847ske/early_southbridge.c b/src/mainboard/intel/dcp847ske/early_southbridge.c index 778525f320c..705ace9bc60 100644 --- a/src/mainboard/intel/dcp847ske/early_southbridge.c +++ b/src/mainboard/intel/dcp847ske/early_southbridge.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include diff --git a/src/mainboard/intel/emeraldlake2/chromeos.c b/src/mainboard/intel/emeraldlake2/chromeos.c index 219eefb8712..699141fc0ff 100644 --- a/src/mainboard/intel/emeraldlake2/chromeos.c +++ b/src/mainboard/intel/emeraldlake2/chromeos.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include diff --git a/src/mainboard/kontron/986lcd-m/romstage.c b/src/mainboard/kontron/986lcd-m/romstage.c index b85bd6883dc..85a82c5acbd 100644 --- a/src/mainboard/kontron/986lcd-m/romstage.c +++ b/src/mainboard/kontron/986lcd-m/romstage.c @@ -16,7 +16,6 @@ /* __PRE_RAM__ means: use "unsigned" for device, not a struct. */ #include -#include #include #include #include diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c index ea93707ce95..b66ef668717 100644 --- a/src/mainboard/lenovo/x60/romstage.c +++ b/src/mainboard/lenovo/x60/romstage.c @@ -18,7 +18,6 @@ // __PRE_RAM__ means: use "unsigned" for device, not a struct. #include -#include #include #include #include diff --git a/src/mainboard/lenovo/z61t/romstage.c b/src/mainboard/lenovo/z61t/romstage.c index 47a52db39b0..502eac39d56 100644 --- a/src/mainboard/lenovo/z61t/romstage.c +++ b/src/mainboard/lenovo/z61t/romstage.c @@ -18,7 +18,6 @@ // __PRE_RAM__ means: use "unsigned" for device, not a struct. #include -#include #include #include #include From 7aeeb4839023867d9a6c56854fb2e8a2143bf788 Mon Sep 17 00:00:00 2001 From: Alex James Date: Thu, 9 May 2019 10:40:46 -0500 Subject: [PATCH 322/588] util/lint/check-style: Don't hardcode clang-format path Signed-off-by: Alex James Change-Id: I688cb60c98370bf74aa8554bab43594ff84c4e24 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32707 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/lint/check-style | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/lint/check-style b/util/lint/check-style index 1ac51b4d1a7..2237ed62956 100755 --- a/util/lint/check-style +++ b/util/lint/check-style @@ -15,7 +15,7 @@ ################################################################## # SETTINGS # set path to clang-format binary -CLANG_FORMAT="/usr/bin/clang-format" +CLANG_FORMAT="$(command -v clang-format)" # remove any older patches from previous commits. Set to true or false. # DELETE_OLD_PATCHES=false From dce10f8f92c4e771cf54544679fcbe10f094afdf Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Sat, 6 Apr 2019 16:10:36 -0600 Subject: [PATCH 323/588] payloads/coreinfo: Remove unused variable The 'last' variable is unused, and has been for the entire history of this file. Found-by: Clang Static Analyzer Signed-off-by: Jacob Garber Change-Id: Ic86a6d8d2b47585f901f1e48ae88735534c834ba Reviewed-on: https://review.coreboot.org/c/coreboot/+/32796 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Martin Roth --- payloads/coreinfo/pci_module.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/payloads/coreinfo/pci_module.c b/payloads/coreinfo/pci_module.c index ff042af65d8..3060161fe03 100644 --- a/payloads/coreinfo/pci_module.c +++ b/payloads/coreinfo/pci_module.c @@ -103,15 +103,10 @@ static void show_config_space(WINDOW *win, int row, int col, int index) static int pci_module_redraw(WINDOW *win) { unsigned int bus, slot, func; - int i, last; + int i; print_module_title(win, "PCI Device List"); - last = menu_first + MENU_VISIBLE; - - if (last > devices_index) - last = devices_index; - for (i = 0; i < MENU_VISIBLE; i++) { int item = menu_first + i; From 48b6be81a5753779f036818a62dd9d61c6abc9c0 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 15 May 2019 20:08:55 +0530 Subject: [PATCH 324/588] Remove remaining unnecessary ENV_RAMSTAGE guard TEST=Able to build coreboot for CML. Change-Id: I8a6a97d59277ebfc498c83bb039436ed7c89d2cd Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32802 Tested-by: build bot (Jenkins) Reviewed-by: ron minnich --- src/drivers/intel/fsp2_0/include/fsp/info_header.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/drivers/intel/fsp2_0/include/fsp/info_header.h b/src/drivers/intel/fsp2_0/include/fsp/info_header.h index e0659243ba4..3e86b29c8dd 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/info_header.h +++ b/src/drivers/intel/fsp2_0/include/fsp/info_header.h @@ -44,7 +44,6 @@ struct fsp_header { enum cb_err fsp_identify(struct fsp_header *hdr, const void *fsp_blob); -#if ENV_RAMSTAGE /* * This is a FSP_INFO_HEADER that came from fsps.bin blob. It contains * both SiliconInit and Notify APIs. When SiliconInit is loaded the @@ -52,6 +51,5 @@ enum cb_err fsp_identify(struct fsp_header *hdr, const void *fsp_blob); * header parsing again. */ extern struct fsp_header fsps_hdr; -#endif #endif /* _FSP2_0_INFO_HEADER_H_ */ From 6644a75b0e9fec0ba104e5249f238520b6e3f7f6 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 15 May 2019 20:12:27 +0530 Subject: [PATCH 325/588] drivers/elog: Rename ramstage_elog_add_boot_count() to elog_add_boot_count() This patch removes ramstage_ prefix from ramstage_elog_add_boot_count() function. Change-Id: Ia75b2dc959ace7dc26dc974c5f4b5cb6c5a25617 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32803 Tested-by: build bot (Jenkins) Reviewed-by: ron minnich --- src/drivers/elog/elog.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drivers/elog/elog.c b/src/drivers/elog/elog.c index 85b79983a57..e41b55bba5f 100644 --- a/src/drivers/elog/elog.c +++ b/src/drivers/elog/elog.c @@ -797,7 +797,7 @@ static bool elog_do_add_boot_count(void) #endif } -static void ramstage_elog_add_boot_count(void) +static void elog_add_boot_count(void) { if (elog_do_add_boot_count()) { elog_add_event_dword(ELOG_TYPE_BOOT, boot_count_read()); @@ -860,7 +860,7 @@ int elog_init(void) es->full_threshold, es->shrink_size); if (ENV_RAMSTAGE) - ramstage_elog_add_boot_count(); + elog_add_boot_count(); return 0; } From e1909eea5c4dcf2f67c63d13c2bb74e10d2ba8a2 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 14 May 2019 16:14:57 -0600 Subject: [PATCH 326/588] soc/intel/skylake: Correct GPIO pointer assignment We need to store the acpi_gpio struct, not save its address. Found-by: Clang Static Analyzer Signed-off-by: Jacob Garber Change-Id: I41c8bf10ce72bec736da97ccc33f9ada49804dc1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32797 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- src/soc/intel/skylake/sd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/skylake/sd.c b/src/soc/intel/skylake/sd.c index 12c6abe4fd7..571d3e7b44c 100644 --- a/src/soc/intel/skylake/sd.c +++ b/src/soc/intel/skylake/sd.c @@ -35,7 +35,7 @@ int sd_fill_soc_gpio_info(struct acpi_gpio* gpio, struct device *dev) gpio->pin_count = 1; gpio->pins[0] = config->sdcard_cd_gpio_default; } else - gpio = &config->sdcard_cd_gpio; + *gpio = config->sdcard_cd_gpio; return 0; } From 69486cac74a0e9578c90366feae8abebce5ff834 Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Thu, 2 May 2019 12:03:45 -0600 Subject: [PATCH 327/588] soc/amd/common: Create AcpiMmio functionality from stoneyridge Move the stoneyridge AcpiMmio code into soc/amd/common. The SB800 southbridge introduced the MMIO hardware blocks at 0xfed80000 commonly known as AcpiMmio. Implementations beginning with Mullins enable decode in PMx04. Older designs use PMx24 and allow for configuring the base address. Future work may support the older version. Comparing the documentation for AMD's RRGs and BKDGs, it is evident that the block locations have not been reassigned across products. In some cases, address locations are deprecated and new ones consumed, e.g. the early GPIO blocks were simpler at offset 0x100 and the newer GPIO banks are now at 0x1500, 0x1600, and 0x1700. Note: Do not infer the definitions within the hardware blocks are consistent across family/model products. BUG=b:131682806 Change-Id: I083b6339cd29e72289e63c9331a815c46d71600d Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32649 Reviewed-by: Richard Spiegel Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- src/mainboard/google/kahlee/mainboard.c | 1 + src/soc/amd/common/block/acpi/halt.c | 1 + src/soc/amd/common/block/acpimmio/Kconfig | 6 + .../amd/common/block/acpimmio/Makefile.inc | 6 + src/soc/amd/common/block/acpimmio/mmio_util.c | 379 ++++++++++++++++++ .../common/block/include/amdblocks/acpimmio.h | 101 +++++ .../block/include/amdblocks/acpimmio_map.h | 67 ++++ src/soc/amd/stoneyridge/Kconfig | 1 + src/soc/amd/stoneyridge/acpi.c | 1 + src/soc/amd/stoneyridge/gpio.c | 4 +- src/soc/amd/stoneyridge/include/soc/iomap.h | 29 +- .../amd/stoneyridge/include/soc/southbridge.h | 59 --- src/soc/amd/stoneyridge/lpc.c | 1 + src/soc/amd/stoneyridge/pmutil.c | 1 + src/soc/amd/stoneyridge/ramtop.c | 3 +- src/soc/amd/stoneyridge/reset.c | 1 + src/soc/amd/stoneyridge/sb_util.c | 351 +--------------- src/soc/amd/stoneyridge/smbus.c | 1 + src/soc/amd/stoneyridge/smi.c | 1 + src/soc/amd/stoneyridge/smi_util.c | 1 + src/soc/amd/stoneyridge/smihandler.c | 1 + src/soc/amd/stoneyridge/southbridge.c | 13 +- src/soc/amd/stoneyridge/usb.c | 2 +- 23 files changed, 582 insertions(+), 449 deletions(-) create mode 100644 src/soc/amd/common/block/acpimmio/Kconfig create mode 100644 src/soc/amd/common/block/acpimmio/Makefile.inc create mode 100644 src/soc/amd/common/block/acpimmio/mmio_util.c create mode 100644 src/soc/amd/common/block/include/amdblocks/acpimmio.h create mode 100644 src/soc/amd/common/block/include/amdblocks/acpimmio_map.h diff --git a/src/mainboard/google/kahlee/mainboard.c b/src/mainboard/google/kahlee/mainboard.c index ad979a567fd..cfd56376337 100644 --- a/src/mainboard/google/kahlee/mainboard.c +++ b/src/mainboard/google/kahlee/mainboard.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/amd/common/block/acpi/halt.c b/src/soc/amd/common/block/acpi/halt.c index 8f36efb0425..200b3c12f55 100644 --- a/src/soc/amd/common/block/acpi/halt.c +++ b/src/soc/amd/common/block/acpi/halt.c @@ -15,6 +15,7 @@ #include #include +#include #include void poweroff(void) diff --git a/src/soc/amd/common/block/acpimmio/Kconfig b/src/soc/amd/common/block/acpimmio/Kconfig new file mode 100644 index 00000000000..f14cc0c2270 --- /dev/null +++ b/src/soc/amd/common/block/acpimmio/Kconfig @@ -0,0 +1,6 @@ +config SOC_AMD_COMMON_BLOCK_ACPIMMIO + bool + default n + help + Select this option to enable hardware blocks in the AcpiMmio + address space (0xfed8xxxx). diff --git a/src/soc/amd/common/block/acpimmio/Makefile.inc b/src/soc/amd/common/block/acpimmio/Makefile.inc new file mode 100644 index 00000000000..9517b10b8a5 --- /dev/null +++ b/src/soc/amd/common/block/acpimmio/Makefile.inc @@ -0,0 +1,6 @@ +bootblock-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c +verstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c +romstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c +postcar-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c +ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c +smm-$(CONFIG_SOC_AMD_COMMON_BLOCK_ACPIMMIO) += mmio_util.c diff --git a/src/soc/amd/common/block/acpimmio/mmio_util.c b/src/soc/amd/common/block/acpimmio/mmio_util.c new file mode 100644 index 00000000000..7d4c4c5df14 --- /dev/null +++ b/src/soc/amd/common/block/acpimmio/mmio_util.c @@ -0,0 +1,379 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2017 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +void enable_acpimmio_decode(void) +{ + uint32_t dw; + + dw = pm_io_read32(ACPIMMIO_DECODE_REGISTER); + dw |= ACPIMMIO_DECODE_EN; + pm_io_write32(ACPIMMIO_DECODE_REGISTER, dw); +} + +/* PM registers are accessed a byte at a time via CD6/CD7 */ +uint8_t pm_io_read8(uint8_t reg) +{ + outb(reg, PM_INDEX); + return inb(PM_DATA); +} + +uint16_t pm_io_read16(uint8_t reg) +{ + return (pm_io_read8(reg + sizeof(uint8_t)) << 8) | pm_io_read8(reg); +} + +uint32_t pm_io_read32(uint8_t reg) +{ + return (pm_io_read16(reg + sizeof(uint16_t)) << 16) | pm_io_read16(reg); +} + +void pm_io_write8(uint8_t reg, uint8_t value) +{ + outb(reg, PM_INDEX); + outb(value, PM_DATA); +} + +void pm_io_write16(uint8_t reg, uint16_t value) +{ + pm_io_write8(reg, value & 0xff); + value >>= 8; + pm_io_write8(reg + sizeof(uint8_t), value & 0xff); +} + +void pm_io_write32(uint8_t reg, uint32_t value) +{ + pm_io_write16(reg, value & 0xffff); + value >>= 16; + pm_io_write16(reg + sizeof(uint16_t), value & 0xffff); +} + +/* smbus pci read/write - access registers at 0xfed80000 - currently unused */ + +/* smi read/write - access registers at 0xfed80200 */ + +uint8_t smi_read8(uint8_t offset) +{ + return read8((void *)(ACPIMMIO_SMI_BASE + offset)); +} + +uint16_t smi_read16(uint8_t offset) +{ + return read16((void *)(ACPIMMIO_SMI_BASE + offset)); +} + +uint32_t smi_read32(uint8_t offset) +{ + return read32((void *)(ACPIMMIO_SMI_BASE + offset)); +} + +void smi_write8(uint8_t offset, uint8_t value) +{ + write8((void *)(ACPIMMIO_SMI_BASE + offset), value); +} + +void smi_write16(uint8_t offset, uint16_t value) +{ + write16((void *)(ACPIMMIO_SMI_BASE + offset), value); +} + +void smi_write32(uint8_t offset, uint32_t value) +{ + write32((void *)(ACPIMMIO_SMI_BASE + offset), value); +} + +/* pm read/write - access registers at 0xfed80300 */ + +u8 pm_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_PMIO_BASE + reg)); +} + +u16 pm_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_PMIO_BASE + reg)); +} + +u32 pm_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_PMIO_BASE + reg)); +} + +void pm_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_PMIO_BASE + reg), value); +} + +void pm_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_PMIO_BASE + reg), value); +} + +void pm_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_PMIO_BASE + reg), value); +} + +/* pm2 read/write - access registers at 0xfed80400 - currently unused */ + +/* biosram read/write - access registers at 0xfed80500 */ + +uint8_t biosram_read8(uint8_t offset) +{ + return read8((void *)(ACPIMMIO_BIOSRAM_BASE + offset)); +} + +uint16_t biosram_read16(uint8_t offset) /* Must be 1 byte at a time */ +{ + int i; + uint16_t value = 0; + for (i = sizeof(value) - 1 ; i >= 0 ; i--) + value = (value << 8) | biosram_read8(offset + i); + return value; +} + +uint32_t biosram_read32(uint8_t offset) +{ + uint32_t value = biosram_read16(offset + sizeof(uint16_t)) << 16; + return value | biosram_read16(offset); +} + +void biosram_write8(uint8_t offset, uint8_t value) +{ + write8((void *)(ACPIMMIO_BIOSRAM_BASE + offset), value); +} + +void biosram_write16(uint8_t offset, uint16_t value) +{ + int i; + for (i = 0 ; i < sizeof(value) ; i++) { + biosram_write8(offset + i, value & 0xff); + value >>= 8; + } +} + +void biosram_write32(uint8_t offset, uint32_t value) +{ + int i; + for (i = 0 ; i < sizeof(value) ; i++) { + biosram_write8(offset + i, value & 0xff); + value >>= 8; + } +} + +/* cmosram read/write - access registers at 0xfed80600 - currently unused */ + +/* cmos read/write - access registers at 0xfed80700 - currently unused */ + +/* acpi read/write - access registers at 0xfed80800 */ + +u8 acpi_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_ACPI_BASE + reg)); +} + +u16 acpi_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_ACPI_BASE + reg)); +} + +u32 acpi_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_ACPI_BASE + reg)); +} + +void acpi_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_ACPI_BASE + reg), value); +} + +void acpi_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_ACPI_BASE + reg), value); +} + +void acpi_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); +} + +/* asf read/write - access registers at 0xfed80900 - not currently used */ + +u8 asf_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_ASF_BASE + reg)); +} + +u16 asf_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_ASF_BASE + reg)); +} + +void asf_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_ASF_BASE + reg), value); +} + +void asf_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_ASF_BASE + reg), value); +} + +/* smbus read/write - access registers at 0xfed80a00 and ASF at 0xfed80900 */ + +u8 smbus_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_SMBUS_BASE + reg)); +} + +u16 smbus_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_SMBUS_BASE + reg)); +} + +void smbus_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_SMBUS_BASE + reg), value); +} + +void smbus_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_SMBUS_BASE + reg), value); +} + +/* wdt read/write - access registers at 0xfed80b00 - not currently used */ + +/* hpet read/write - access registers at 0xfed80c00 - not currently used */ + +/* iomux read/write - access registers at 0xfed80d00 */ + +u8 iomux_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +u16 iomux_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +u32 iomux_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_IOMUX_BASE + reg)); +} + +void iomux_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} + +void iomux_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} + +void iomux_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_IOMUX_BASE + reg), value); +} + +/* misc read/write - access registers at 0xfed80e00 */ + +u8 misc_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_MISC_BASE + reg)); +} + +u16 misc_read16(u8 reg) +{ + return read16((void *)(ACPIMMIO_MISC_BASE + reg)); +} + +u32 misc_read32(u8 reg) +{ + return read32((void *)(ACPIMMIO_MISC_BASE + reg)); +} + +void misc_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + +void misc_write16(u8 reg, u16 value) +{ + write16((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + +void misc_write32(u8 reg, u32 value) +{ + write32((void *)(ACPIMMIO_MISC_BASE + reg), value); +} + +/* dpvga read/write - access registers at 0xfed81400 - not currently used */ + +/* gpio bk 0 read/write - access registers at 0xfed81500 - not currently used */ +/* gpio bk 1 read/write - access registers at 0xfed81600 - not currently used */ +/* gpio bk 2 read/write - access registers at 0xfed81700 - not currently used */ + +/* xhci_pm read/write - access registers at 0xfed81c00 */ + +uint8_t xhci_pm_read8(uint8_t reg) +{ + return read8((void *)(ACPIMMIO_XHCIPM_BASE + reg)); +} + +uint16_t xhci_pm_read16(uint8_t reg) +{ + return read16((void *)(ACPIMMIO_XHCIPM_BASE + reg)); +} + +uint32_t xhci_pm_read32(uint8_t reg) +{ + return read32((void *)(ACPIMMIO_XHCIPM_BASE + reg)); +} + +void xhci_pm_write8(uint8_t reg, uint8_t value) +{ + write8((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); +} + +void xhci_pm_write16(uint8_t reg, uint16_t value) +{ + write16((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); +} + +void xhci_pm_write32(uint8_t reg, uint32_t value) +{ + write32((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); +} + +/* acdc_tmr read/write - access registers at 0xfed81d00 */ + +/* aoac read/write - access registers at 0xfed81e00 - not currently used */ + +u8 aoac_read8(u8 reg) +{ + return read8((void *)(ACPIMMIO_AOAC_BASE + reg)); +} + +void aoac_write8(u8 reg, u8 value) +{ + write8((void *)(ACPIMMIO_AOAC_BASE + reg), value); +} diff --git a/src/soc/amd/common/block/include/amdblocks/acpimmio.h b/src/soc/amd/common/block/include/amdblocks/acpimmio.h new file mode 100644 index 00000000000..e1cf7cbdc23 --- /dev/null +++ b/src/soc/amd/common/block/include/amdblocks/acpimmio.h @@ -0,0 +1,101 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Advanced Micro Devices, Inc. + * Copyright (C) 2014 Alexandru Gagniuc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __AMDBLOCKS_ACPIMMIO_H__ +#define __AMDBLOCKS_ACPIMMIO_H__ + +void enable_acpimmio_decode(void); +uint8_t pm_io_read8(uint8_t reg); +uint16_t pm_io_read16(uint8_t reg); +uint32_t pm_io_read32(uint8_t reg); +void pm_io_write8(uint8_t reg, uint8_t value); +void pm_io_write16(uint8_t reg, uint16_t value); +void pm_io_write32(uint8_t reg, uint32_t value); +uint8_t smi_read8(uint8_t offset); +uint16_t smi_read16(uint8_t offset); +uint32_t smi_read32(uint8_t offset); +void smi_write8(uint8_t offset, uint8_t value); +void smi_write16(uint8_t offset, uint16_t value); +void smi_write32(uint8_t offset, uint32_t value); +uint8_t pm_read8(uint8_t reg); +uint16_t pm_read16(uint8_t reg); +uint32_t pm_read32(uint8_t reg); +void pm_write8(uint8_t reg, uint8_t value); +void pm_write16(uint8_t reg, uint16_t value); +void pm_write32(uint8_t reg, uint32_t value); +uint8_t pm2_read8(uint8_t reg); +uint16_t pm2_read16(uint8_t reg); +uint32_t pm2_read32(uint8_t reg); +void pm2_write8(uint8_t reg, uint8_t value); +void pm2_write16(uint8_t reg, uint16_t value); +void pm2_write32(uint8_t reg, uint32_t value); +uint8_t biosram_read8(uint8_t offset); +void biosram_write8(uint8_t offset, uint8_t value); +uint16_t biosram_read16(uint8_t offset); +uint32_t biosram_read32(uint8_t offset); +void biosram_write16(uint8_t offset, uint16_t value); +void biosram_write32(uint8_t offset, uint32_t value); +uint8_t acpi_read8(uint8_t reg); +uint16_t acpi_read16(uint8_t reg); +uint32_t acpi_read32(uint8_t reg); +void acpi_write8(uint8_t reg, uint8_t value); +void acpi_write16(uint8_t reg, uint16_t value); +void acpi_write32(uint8_t reg, uint32_t value); +uint8_t asf_read8(uint8_t reg); +uint16_t asf_read16(uint8_t reg); +uint32_t asf_read32(uint8_t reg); +void asf_write8(uint8_t reg, uint8_t value); +void asf_write16(uint8_t reg, uint16_t value); +void asf_write32(uint8_t reg, uint32_t value); +uint8_t smbus_read8(uint8_t reg); +uint16_t smbus_read16(uint8_t reg); +void smbus_write8(uint8_t reg, uint8_t value); +void smbus_write16(uint8_t reg, uint16_t value); +uint8_t wdt_read8(uint8_t reg); +uint16_t wdt_read16(uint8_t reg); +uint32_t wdt_read32(uint8_t reg); +void wdt_write8(uint8_t reg, uint8_t value); +void wdt_write16(uint8_t reg, uint16_t value); +void wdt_write32(uint8_t reg, uint32_t value); +uint8_t hpet_read8(uint8_t reg); +uint16_t hpet_read16(uint8_t reg); +uint32_t hpet_read32(uint8_t reg); +void hpet_write8(uint8_t reg, uint8_t value); +void hpet_write16(uint8_t reg, uint16_t value); +void hpet_write32(uint8_t reg, uint32_t value); +uint8_t iomux_read8(uint8_t reg); +uint16_t iomux_read16(uint8_t reg); +uint32_t iomux_read32(uint8_t reg); +void iomux_write8(uint8_t reg, uint8_t value); +void iomux_write16(uint8_t reg, uint16_t value); +void iomux_write32(uint8_t reg, uint32_t value); +uint8_t misc_read8(uint8_t reg); +uint16_t misc_read16(uint8_t reg); +uint32_t misc_read32(uint8_t reg); +void misc_write8(uint8_t reg, uint8_t value); +void misc_write16(uint8_t reg, uint16_t value); +void misc_write32(uint8_t reg, uint32_t value); +uint8_t xhci_pm_read8(uint8_t reg); +uint16_t xhci_pm_read16(uint8_t reg); +uint32_t xhci_pm_read32(uint8_t reg); +void xhci_pm_write8(uint8_t reg, uint8_t value); +void xhci_pm_write16(uint8_t reg, uint16_t value); +void xhci_pm_write32(uint8_t reg, uint32_t value); +uint8_t aoac_read8(uint8_t reg); +void aoac_write8(uint8_t reg, uint8_t value); + +#endif /* __AMDBLOCKS_ACPIMMIO_H__ */ diff --git a/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h b/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h new file mode 100644 index 00000000000..755af52d4f2 --- /dev/null +++ b/src/soc/amd/common/block/include/amdblocks/acpimmio_map.h @@ -0,0 +1,67 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Advanced Micro Devices, Inc. + * Copyright (C) 2014 Alexandru Gagniuc + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __AMDBLOCKS_ACPIMMIO_MAP_H__ +#define __AMDBLOCKS_ACPIMMIO_MAP_H__ + +/* IO index/data for accessing PMIO prior to enabling MMIO decode */ +#define PM_INDEX 0xcd6 +#define PM_DATA 0xcd7 + +/* TODO: In the event this is ported backward far enough, earlier devices + * enable the decode in PMx24 instead. All discrete FCHs and the Kabini + * SoC fall into this category. Kabini's successor, Mullins, uses this + * newer method. + */ +#define ACPIMMIO_DECODE_REGISTER 0x4 +#define ACPIMMIO_DECODE_EN BIT(0) + +/* MMIO register blocks are at fixed offsets from 0xfed80000 and are enabled + * in PMx24[1] (older implementations) and PMx04[1] (newer implementations). + * PM registers are also accessible via IO CD6/CD7. + * + * All products do not support all blocks below, however AMD has avoided + * redefining addresses and consumes new ranges as necessary. + * + * Definitions within each block are not guaranteed to remain consistent + * across family/model products. + */ + +#define AMD_SB_ACPI_MMIO_ADDR 0xfed80000 +#define ACPIMMIO_SM_PCI_BASE 0xfed80000 +#define ACPIMMIO_SMI_BASE 0xfed80200 +#define ACPIMMIO_PMIO_BASE 0xfed80300 +#define ACPIMMIO_PMIO2_BASE 0xfed80400 +#define ACPIMMIO_BIOSRAM_BASE 0xfed80500 +#define ACPIMMIO_CMOSRAM_BASE 0xfed80600 +#define ACPIMMIO_CMOS_BASE 0xfed80700 +#define ACPIMMIO_ACPI_BASE 0xfed80800 +#define ACPIMMIO_ASF_BASE 0xfed80900 +#define ACPIMMIO_SMBUS_BASE 0xfed80a00 +#define ACPIMMIO_WDT_BASE 0xfed80b00 +#define ACPIMMIO_HPET_BASE 0xfed80c00 +#define ACPIMMIO_IOMUX_BASE 0xfed80d00 +#define ACPIMMIO_MISC_BASE 0xfed80e00 +#define ACPIMMIO_DPVGA_BASE 0xfed81400 +#define ACPIMMIO_GPIO0_BASE 0xfed81500 +#define ACPIMMIO_GPIO1_BASE 0xfed81600 +#define ACPIMMIO_GPIO2_BASE 0xfed81700 +#define ACPIMMIO_XHCIPM_BASE 0xfed81c00 +#define ACPIMMIO_ACDCTMR_BASE 0xfed81d00 +#define ACPIMMIO_AOAC_BASE 0xfed81e00 + +#endif /* __AMDBLOCKS_ACPIMMIO_MAP_H__ */ diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig index 29ab149df9a..d4e1feb2515 100644 --- a/src/soc/amd/stoneyridge/Kconfig +++ b/src/soc/amd/stoneyridge/Kconfig @@ -46,6 +46,7 @@ config CPU_SPECIFIC_OPTIONS select SOC_AMD_PI select SOC_AMD_COMMON select SOC_AMD_COMMON_BLOCK + select SOC_AMD_COMMON_BLOCK_ACPIMMIO select SOC_AMD_COMMON_BLOCK_PCI select SOC_AMD_COMMON_BLOCK_PI select SOC_AMD_COMMON_BLOCK_PSP diff --git a/src/soc/amd/stoneyridge/acpi.c b/src/soc/amd/stoneyridge/acpi.c index 227fb701362..4f11ea227a5 100644 --- a/src/soc/amd/stoneyridge/acpi.c +++ b/src/soc/amd/stoneyridge/acpi.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c index 285fedd2387..01ced0880b2 100644 --- a/src/soc/amd/stoneyridge/gpio.c +++ b/src/soc/amd/stoneyridge/gpio.c @@ -16,13 +16,15 @@ */ #include +#include #include #include #include +#include #include #include -#include #include +#include "chip.h" static const struct soc_amd_event gpio_event_table[] = { { GPIO_1, GEVENT_19 }, diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index e6327dc6db6..77620431196 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -22,6 +22,9 @@ #define SPI_BASE_ADDRESS 0xfec10000 #define IO_APIC2_ADDR 0xfec20000 +/* AcpiMmio blocks are at fixed offsets from FED8_0000h, enabled in PMx04[1] */ +#include + /* I2C fixed address */ #define I2C_BASE_ADDRESS 0xfedc2000 #define I2C_DEVICE_SIZE 0x00001000 @@ -32,30 +35,6 @@ #endif #define HPET_BASE_ADDRESS 0xfed00000 -/* AcpiMmio blocks are at fixed offsets from FED8_0000h, enabled in PMx04[1] */ -#define AMD_SB_ACPI_MMIO_ADDR 0xfed80000 -#define ACPIMMIO_SM_PCI_BASE 0xfed80000 -#define ACPIMMIO_SMI_BASE 0xfed80200 -#define ACPIMMIO_PMIO_BASE 0xfed80300 -#define ACPIMMIO_PMIO2_BASE 0xfed80400 -#define ACPIMMIO_BIOSRAM_BASE 0xfed80500 -#define ACPIMMIO_CMOSRAM_BASE 0xfed80600 -#define ACPIMMIO_CMOS_BASE 0xfed80700 -#define ACPIMMIO_ACPI_BASE 0xfed80800 -#define ACPIMMIO_ASF_BASE 0xfed80900 -#define ACPIMMIO_SMBUS_BASE 0xfed80a00 -#define ACPIMMIO_WDT_BASE 0xfed80b00 -#define ACPIMMIO_HPET_BASE 0xfed80c00 -#define ACPIMMIO_IOMUX_BASE 0xfed80d00 -#define ACPIMMIO_MISC_BASE 0xfed80e00 -#define ACPIMMIO_DPVGA_BASE 0xfed81400 -#define ACPIMMIO_GPIO0_BASE 0xfed81500 -#define ACPIMMIO_GPIO1_BASE 0xfed81600 -#define ACPIMMIO_GPIO2_BASE 0xfed81700 -#define ACPIMMIO_XHCIPM_BASE 0xfed81c00 -#define ACPIMMIO_ACDCTMR_BASE 0xfed81d00 -#define ACPIMMIO_AOAC_BASE 0xfed81e00 - #define APU_UART0_BASE 0xfedc6000 #define APU_UART1_BASE 0xfedc8000 @@ -78,8 +57,6 @@ #define PM2_DATA 0xcd1 #define BIOSRAM_INDEX 0xcd4 #define BIOSRAM_DATA 0xcd5 -#define PM_INDEX 0xcd6 -#define PM_DATA 0xcd7 #define AB_INDX 0xcd8 #define AB_DATA (AB_INDX+4) #define SYS_RESET 0xcf9 diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h index 618a5deff78..6734efb04d1 100644 --- a/src/soc/amd/stoneyridge/include/soc/southbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h @@ -483,7 +483,6 @@ void southbridge_final(void *chip_info); void southbridge_init(void *chip_info); void sb_lpc_port80(void); void sb_lpc_decode(void); -void sb_acpi_mmio_decode(void); void sb_pci_port80(void); void sb_read_mode(u32 mode); void sb_set_spi100(u16 norm, u16 fast, u16 alt, u16 tpm); @@ -491,66 +490,8 @@ void sb_tpm_decode(void); void sb_tpm_decode_spi(void); void lpc_wideio_512_window(uint16_t base); void lpc_wideio_16_window(uint16_t base); -uint8_t pm_io_read8(uint8_t reg); -uint16_t pm_io_read16(uint8_t reg); -uint32_t pm_io_read32(uint8_t reg); -void pm_io_write8(uint8_t reg, uint8_t value); -void pm_io_write16(uint8_t reg, uint16_t value); -void pm_io_write32(uint8_t reg, uint32_t value); -u8 pm_read8(u8 reg); -u16 pm_read16(u8 reg); -u32 pm_read32(u8 reg); -void pm_write8(u8 reg, u8 value); -void pm_write16(u8 reg, u16 value); -void pm_write32(u8 reg, u32 value); -u8 acpi_read8(u8 reg); -u16 acpi_read16(u8 reg); -u32 acpi_read32(u8 reg); -void acpi_write8(u8 reg, u8 value); -void acpi_write16(u8 reg, u16 value); -void acpi_write32(u8 reg, u32 value); -u8 misc_read8(u8 reg); -u16 misc_read16(u8 reg); -u32 misc_read32(u8 reg); -void misc_write8(u8 reg, u8 value); -void misc_write16(u8 reg, u16 value); -void misc_write32(u8 reg, u32 value); -uint8_t smi_read8(uint8_t offset); -uint16_t smi_read16(uint8_t offset); -uint32_t smi_read32(uint8_t offset); -void smi_write8(uint8_t offset, uint8_t value); -void smi_write16(uint8_t offset, uint16_t value); -void smi_write32(uint8_t offset, uint32_t value); -uint8_t biosram_read8(uint8_t offset); -void biosram_write8(uint8_t offset, uint8_t value); -uint16_t biosram_read16(uint8_t offset); -void biosram_write16(uint8_t offset, uint16_t value); -uint32_t biosram_read32(uint8_t offset); -void biosram_write32(uint8_t offset, uint32_t value); uint16_t pm_acpi_pm_cnt_blk(void); uint16_t pm_acpi_pm_evt_blk(void); -void xhci_pm_write8(uint8_t reg, uint8_t value); -uint8_t xhci_pm_read8(uint8_t reg); -void xhci_pm_write16(uint8_t reg, uint16_t value); -uint16_t xhci_pm_read16(uint8_t reg); -void xhci_pm_write32(uint8_t reg, uint32_t value); -uint32_t xhci_pm_read32(uint8_t reg); -u8 iomux_read8(u8 reg); -u16 iomux_read16(u8 reg); -u32 iomux_read32(u8 reg); -void iomux_write8(u8 reg, u8 value); -void iomux_write16(u8 reg, u16 value); -void iomux_write32(u8 reg, u32 value); -uint8_t asf_read8(uint8_t offset); -uint16_t asf_read16(uint8_t offset); -void asf_write8(uint8_t offset, uint8_t value); -void asf_write16(uint8_t offset, uint16_t value); -uint8_t smbus_read8(uint8_t offset); -uint16_t smbus_read16(uint8_t offset); -void smbus_write8(uint8_t offset, uint8_t value); -void smbus_write16(uint8_t offset, uint16_t value); -uint8_t aoac_read8(uint8_t reg); -void aoac_write8(uint8_t reg, uint8_t value); void bootblock_fch_early_init(void); void bootblock_fch_init(void); /** diff --git a/src/soc/amd/stoneyridge/lpc.c b/src/soc/amd/stoneyridge/lpc.c index a838146c846..3ace1fdce65 100644 --- a/src/soc/amd/stoneyridge/lpc.c +++ b/src/soc/amd/stoneyridge/lpc.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include diff --git a/src/soc/amd/stoneyridge/pmutil.c b/src/soc/amd/stoneyridge/pmutil.c index bfb5f424efc..7367251193b 100644 --- a/src/soc/amd/stoneyridge/pmutil.c +++ b/src/soc/amd/stoneyridge/pmutil.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include diff --git a/src/soc/amd/stoneyridge/ramtop.c b/src/soc/amd/stoneyridge/ramtop.c index f43fcf37ec4..7c855bb1e18 100644 --- a/src/soc/amd/stoneyridge/ramtop.c +++ b/src/soc/amd/stoneyridge/ramtop.c @@ -25,7 +25,8 @@ #include #include #include -#include +#include +#include void backup_top_of_low_cacheable(uintptr_t ramtop) { diff --git a/src/soc/amd/stoneyridge/reset.c b/src/soc/amd/stoneyridge/reset.c index 34aa576a095..ec5ee910d9d 100644 --- a/src/soc/amd/stoneyridge/reset.c +++ b/src/soc/amd/stoneyridge/reset.c @@ -20,6 +20,7 @@ #include #include #include +#include #include void set_warm_reset_flag(void) diff --git a/src/soc/amd/stoneyridge/sb_util.c b/src/soc/amd/stoneyridge/sb_util.c index 524efc45ad2..11bf73a7231 100644 --- a/src/soc/amd/stoneyridge/sb_util.c +++ b/src/soc/amd/stoneyridge/sb_util.c @@ -16,358 +16,9 @@ #include #include #include +#include #include -/* PM registers are accessed a byte at a time via CD6/CD7 */ -uint8_t pm_io_read8(uint8_t reg) -{ - outb(reg, PM_INDEX); - return inb(PM_DATA); -} - -uint16_t pm_io_read16(uint8_t reg) -{ - return (pm_io_read8(reg + sizeof(uint8_t)) << 8) | pm_io_read8(reg); -} - -uint32_t pm_io_read32(uint8_t reg) -{ - return (pm_io_read16(reg + sizeof(uint16_t)) << 16) | pm_io_read16(reg); -} - -void pm_io_write8(uint8_t reg, uint8_t value) -{ - outb(reg, PM_INDEX); - outb(value, PM_DATA); -} - -void pm_io_write16(uint8_t reg, uint16_t value) -{ - pm_io_write8(reg, value & 0xff); - value >>= 8; - pm_io_write8(reg + sizeof(uint8_t), value & 0xff); -} - -void pm_io_write32(uint8_t reg, uint32_t value) -{ - pm_io_write16(reg, value & 0xffff); - value >>= 16; - pm_io_write16(reg + sizeof(uint16_t), value & 0xffff); -} - -/* smbus pci read/write - access registers at 0xfed80000 - currently unused */ - -/* smi read/write - access registers at 0xfed80200 */ - -uint8_t smi_read8(uint8_t offset) -{ - return read8((void *)(ACPIMMIO_SMI_BASE + offset)); -} - -uint16_t smi_read16(uint8_t offset) -{ - return read16((void *)(ACPIMMIO_SMI_BASE + offset)); -} - -uint32_t smi_read32(uint8_t offset) -{ - return read32((void *)(ACPIMMIO_SMI_BASE + offset)); -} - -void smi_write8(uint8_t offset, uint8_t value) -{ - write8((void *)(ACPIMMIO_SMI_BASE + offset), value); -} - -void smi_write16(uint8_t offset, uint16_t value) -{ - write16((void *)(ACPIMMIO_SMI_BASE + offset), value); -} - -void smi_write32(uint8_t offset, uint32_t value) -{ - write32((void *)(ACPIMMIO_SMI_BASE + offset), value); -} - -/* pm read/write - access registers at 0xfed80300 */ - -u8 pm_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_PMIO_BASE + reg)); -} - -u16 pm_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_PMIO_BASE + reg)); -} - -u32 pm_read32(u8 reg) -{ - return read32((void *)(ACPIMMIO_PMIO_BASE + reg)); -} - -void pm_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_PMIO_BASE + reg), value); -} - -void pm_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_PMIO_BASE + reg), value); -} - -void pm_write32(u8 reg, u32 value) -{ - write32((void *)(ACPIMMIO_PMIO_BASE + reg), value); -} - -/* pm2 read/write - access registers at 0xfed80400 - currently unused */ - -/* biosram read/write - access registers at 0xfed80500 */ - -uint8_t biosram_read8(uint8_t offset) -{ - return read8((void *)(ACPIMMIO_BIOSRAM_BASE + offset)); -} - -uint16_t biosram_read16(uint8_t offset) /* Must be 1 byte at a time */ -{ - int i; - uint16_t value = 0; - for (i = sizeof(value) - 1 ; i >= 0 ; i--) - value = (value << 8) | biosram_read8(offset + i); - return value; -} - -uint32_t biosram_read32(uint8_t offset) -{ - uint32_t value = biosram_read16(offset + sizeof(uint16_t)) << 16; - return value | biosram_read16(offset); -} - -void biosram_write8(uint8_t offset, uint8_t value) -{ - write8((void *)(ACPIMMIO_BIOSRAM_BASE + offset), value); -} - -void biosram_write16(uint8_t offset, uint16_t value) -{ - int i; - for (i = 0 ; i < sizeof(value) ; i++) { - biosram_write8(offset + i, value & 0xff); - value >>= 8; - } -} - -void biosram_write32(uint8_t offset, uint32_t value) -{ - int i; - for (i = 0 ; i < sizeof(value) ; i++) { - biosram_write8(offset + i, value & 0xff); - value >>= 8; - } -} - -/* cmosram read/write - access registers at 0xfed80600 - currently unused */ - -/* cmos read/write - access registers at 0xfed80700 - currently unused */ - -/* acpi read/write - access registers at 0xfed80800 */ - -u8 acpi_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_ACPI_BASE + reg)); -} - -u16 acpi_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_ACPI_BASE + reg)); -} - -u32 acpi_read32(u8 reg) -{ - return read32((void *)(ACPIMMIO_ACPI_BASE + reg)); -} - -void acpi_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_ACPI_BASE + reg), value); -} - -void acpi_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_ACPI_BASE + reg), value); -} - -void acpi_write32(u8 reg, u32 value) -{ - write32((void *)(ACPIMMIO_ACPI_BASE + reg), value); -} - -/* asf read/write - access registers at 0xfed80900 - not currently used */ - -u8 asf_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_ASF_BASE + reg)); -} - -u16 asf_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_ASF_BASE + reg)); -} - -void asf_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_ASF_BASE + reg), value); -} - -void asf_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_ASF_BASE + reg), value); -} - -/* smbus read/write - access registers at 0xfed80a00 and ASF at 0xfed80900 */ - -u8 smbus_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_SMBUS_BASE + reg)); -} - -u16 smbus_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_SMBUS_BASE + reg)); -} - -void smbus_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_SMBUS_BASE + reg), value); -} - -void smbus_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_SMBUS_BASE + reg), value); -} - -/* wdt read/write - access registers at 0xfed80b00 - not currently used */ - -/* hpet read/write - access registers at 0xfed80c00 - not currently used */ - -/* iomux read/write - access registers at 0xfed80d00 */ - -u8 iomux_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_IOMUX_BASE + reg)); -} - -u16 iomux_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_IOMUX_BASE + reg)); -} - -u32 iomux_read32(u8 reg) -{ - return read32((void *)(ACPIMMIO_IOMUX_BASE + reg)); -} - -void iomux_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_IOMUX_BASE + reg), value); -} - -void iomux_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_IOMUX_BASE + reg), value); -} - -void iomux_write32(u8 reg, u32 value) -{ - write32((void *)(ACPIMMIO_IOMUX_BASE + reg), value); -} - -/* misc read/write - access registers at 0xfed80e00 */ - -u8 misc_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_MISC_BASE + reg)); -} - -u16 misc_read16(u8 reg) -{ - return read16((void *)(ACPIMMIO_MISC_BASE + reg)); -} - -u32 misc_read32(u8 reg) -{ - return read32((void *)(ACPIMMIO_MISC_BASE + reg)); -} - -void misc_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_MISC_BASE + reg), value); -} - -void misc_write16(u8 reg, u16 value) -{ - write16((void *)(ACPIMMIO_MISC_BASE + reg), value); -} - -void misc_write32(u8 reg, u32 value) -{ - write32((void *)(ACPIMMIO_MISC_BASE + reg), value); -} - -/* dpvga read/write - access registers at 0xfed81400 - not currently used */ - -/* gpio bk 0 read/write - access registers at 0xfed81500 - not currently used */ -/* gpio bk 1 read/write - access registers at 0xfed81600 - not currently used */ -/* gpio bk 2 read/write - access registers at 0xfed81700 - not currently used */ - -/* xhci_pm read/write - access registers at 0xfed81c00 */ - -uint8_t xhci_pm_read8(uint8_t reg) -{ - return read8((void *)(ACPIMMIO_XHCIPM_BASE + reg)); -} - -uint16_t xhci_pm_read16(uint8_t reg) -{ - return read16((void *)(ACPIMMIO_XHCIPM_BASE + reg)); -} - -uint32_t xhci_pm_read32(uint8_t reg) -{ - return read32((void *)(ACPIMMIO_XHCIPM_BASE + reg)); -} - -void xhci_pm_write8(uint8_t reg, uint8_t value) -{ - write8((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); -} - -void xhci_pm_write16(uint8_t reg, uint16_t value) -{ - write16((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); -} - -void xhci_pm_write32(uint8_t reg, uint32_t value) -{ - write32((void *)(ACPIMMIO_XHCIPM_BASE + reg), value); -} - -/* acdc_tmr read/write - access registers at 0xfed81d00 */ - -/* aoac read/write - access registers at 0xfed81e00 - not currently used */ - -u8 aoac_read8(u8 reg) -{ - return read8((void *)(ACPIMMIO_AOAC_BASE + reg)); -} - -void aoac_write8(u8 reg, u8 value) -{ - write8((void *)(ACPIMMIO_AOAC_BASE + reg), value); -} - uint16_t pm_acpi_pm_cnt_blk(void) { return pm_read16(PM1_CNT_BLK); diff --git a/src/soc/amd/stoneyridge/smbus.c b/src/soc/amd/stoneyridge/smbus.c index 6285d793b79..df7a86edc7e 100644 --- a/src/soc/amd/stoneyridge/smbus.c +++ b/src/soc/amd/stoneyridge/smbus.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/src/soc/amd/stoneyridge/smi.c b/src/soc/amd/stoneyridge/smi.c index 5ddc0dda624..4a0d833c7bb 100644 --- a/src/soc/amd/stoneyridge/smi.c +++ b/src/soc/amd/stoneyridge/smi.c @@ -19,6 +19,7 @@ */ #include +#include #include #include diff --git a/src/soc/amd/stoneyridge/smi_util.c b/src/soc/amd/stoneyridge/smi_util.c index 91b86e284e6..8759e2acb1f 100644 --- a/src/soc/amd/stoneyridge/smi_util.c +++ b/src/soc/amd/stoneyridge/smi_util.c @@ -21,6 +21,7 @@ #include #include #include +#include void configure_smi(uint8_t smi_num, uint8_t mode) { diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c index c3f4b675dc3..c3aed578ffc 100644 --- a/src/soc/amd/stoneyridge/smihandler.c +++ b/src/soc/amd/stoneyridge/smihandler.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* bits in smm_io_trap */ diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index b6c40b63d34..bf8787c1fca 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -359,16 +360,6 @@ void sb_lpc_decode(void) pci_write_config32(SOC_LPC_DEV, LPC_IO_PORT_DECODE_ENABLE, tmp); } -void sb_acpi_mmio_decode(void) -{ - uint8_t byte; - - /* Enable ACPI MMIO range 0xfed80000 - 0xfed81fff */ - byte = pm_io_read8(PM_ISA_CONTROL); - byte |= MMIO_EN; - pm_io_write8(PM_ISA_CONTROL, byte); -} - static void sb_enable_cf9_io(void) { uint32_t reg = pm_read32(PM_DECODE_EN); @@ -642,7 +633,7 @@ void bootblock_fch_early_init(void) sb_lpc_early_setup(); sb_spibase(); sb_disable_4dw_burst(); /* Must be disabled on CZ(ST) */ - sb_acpi_mmio_decode(); + enable_acpimmio_decode(); fch_smbus_init(); sb_enable_cf9_io(); setup_spread_spectrum(&reboot); diff --git a/src/soc/amd/stoneyridge/usb.c b/src/soc/amd/stoneyridge/usb.c index f2fa3ba267b..00f82375e83 100644 --- a/src/soc/amd/stoneyridge/usb.c +++ b/src/soc/amd/stoneyridge/usb.c @@ -22,7 +22,7 @@ #include #include #include - +#include static void set_usb_over_current(struct device *dev) { From f42344a38963cba10604901a6934c7842db42c4d Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Thu, 2 May 2019 12:53:00 -0600 Subject: [PATCH 328/588] soc/amd/stoneyridge: Move I2C bus clear out of gpio.c Relocate the I2C bus reset code from gpio.c to i2c.c. When it first went in, gpio.c was a natural location due to the nature of the algorithm. This is preparation for moving most of gpio.c to common code. Change-Id: I3b2d8e1b54e7c5929220d763bd99fe01b0636aaa Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32650 Reviewed-by: Martin Roth Reviewed-by: Richard Spiegel Tested-by: build bot (Jenkins) --- src/soc/amd/stoneyridge/chip.h | 2 +- src/soc/amd/stoneyridge/gpio.c | 97 --------------------- src/soc/amd/stoneyridge/i2c.c | 99 ++++++++++++++++++++++ src/soc/amd/stoneyridge/include/soc/gpio.h | 26 ------ src/soc/amd/stoneyridge/include/soc/i2c.h | 49 +++++++++++ 5 files changed, 149 insertions(+), 124 deletions(-) create mode 100644 src/soc/amd/stoneyridge/include/soc/i2c.h diff --git a/src/soc/amd/stoneyridge/chip.h b/src/soc/amd/stoneyridge/chip.h index 92223d19626..d1a7d301997 100644 --- a/src/soc/amd/stoneyridge/chip.h +++ b/src/soc/amd/stoneyridge/chip.h @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #define MAX_NODES 1 diff --git a/src/soc/amd/stoneyridge/gpio.c b/src/soc/amd/stoneyridge/gpio.c index 01ced0880b2..7c9680582ce 100644 --- a/src/soc/amd/stoneyridge/gpio.c +++ b/src/soc/amd/stoneyridge/gpio.c @@ -18,11 +18,9 @@ #include #include #include -#include #include #include #include -#include #include #include "chip.h" @@ -326,101 +324,6 @@ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size) edge_level, mask); } -/* - * I2C pins are open drain with external pull up, so in order to bit bang them - * all, SCL pins must become GPIO inputs with no pull, then they need to be - * toggled between input-no-pull and output-low. This table is for the initial - * conversion of all SCL pins to input with no pull. - */ -static const struct soc_amd_gpio i2c_2_gpi[] = { - PAD_GPI(I2C0_SCL_PIN, PULL_NONE), - PAD_GPI(I2C1_SCL_PIN, PULL_NONE), - PAD_GPI(I2C2_SCL_PIN, PULL_NONE), - PAD_GPI(I2C3_SCL_PIN, PULL_NONE), -}; -#define saved_pins_count ARRAY_SIZE(i2c_2_gpi) - -/* - * To program I2C pins without destroying their programming, the registers - * that will be changed need to be saved first. - */ -static void save_i2c_pin_registers(uint8_t gpio, - struct soc_amd_i2c_save *save_table) -{ - uint32_t *gpio_ptr; - - gpio_ptr = (uint32_t *)gpio_get_address(gpio); - save_table->mux_value = iomux_read8(gpio); - save_table->control_value = read32(gpio_ptr); -} - -static void restore_i2c_pin_registers(uint8_t gpio, - struct soc_amd_i2c_save *save_table) -{ - uint32_t *gpio_ptr; - - gpio_ptr = (uint32_t *)gpio_get_address(gpio); - iomux_write8(gpio, save_table->mux_value); - iomux_read8(gpio); - write32(gpio_ptr, save_table->control_value); - read32(gpio_ptr); -} - -/* Slaves to be reset are controlled by devicetree register i2c_scl_reset */ -void sb_reset_i2c_slaves(void) -{ - const struct soc_amd_stoneyridge_config *cfg; - const struct device *dev = pcidev_path_on_root(GNB_DEVFN); - struct soc_amd_i2c_save save_table[saved_pins_count]; - uint8_t i, j, control; - - if (!dev || !dev->chip_info) - return; - cfg = dev->chip_info; - control = cfg->i2c_scl_reset & GPIO_I2C_MASK; - if (control == 0) - return; - - /* Save and reprogram I2C SCL pins */ - for (i = 0; i < saved_pins_count; i++) - save_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]); - sb_program_gpios(i2c_2_gpi, saved_pins_count); - - /* - * Toggle SCL back and forth 9 times under 100KHz. A single read is - * needed after the writes to force the posted write to complete. - */ - for (j = 0; j < 9; j++) { - if (control & GPIO_I2C0_SCL) - write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_LOW); - if (control & GPIO_I2C1_SCL) - write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_LOW); - if (control & GPIO_I2C2_SCL) - write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_LOW); - if (control & GPIO_I2C3_SCL) - write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_LOW); - - read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */ - udelay(4); /* 4usec gets 85KHz for 1 pin, 70KHz for 4 pins */ - - if (control & GPIO_I2C0_SCL) - write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_HIGH); - if (control & GPIO_I2C1_SCL) - write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_HIGH); - if (control & GPIO_I2C2_SCL) - write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_HIGH); - if (control & GPIO_I2C3_SCL) - write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_HIGH); - - read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */ - udelay(4); - } - - /* Restore I2C pins. */ - for (i = 0; i < saved_pins_count; i++) - restore_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]); -} - int gpio_interrupt_status(gpio_t gpio) { uintptr_t gpio_address = gpio_get_address(gpio); diff --git a/src/soc/amd/stoneyridge/i2c.c b/src/soc/amd/stoneyridge/i2c.c index e99f3509ff1..c3e5539e197 100644 --- a/src/soc/amd/stoneyridge/i2c.c +++ b/src/soc/amd/stoneyridge/i2c.c @@ -13,12 +13,16 @@ * GNU General Public License for more details. */ +#include #include #include +#include #include +#include #include #include #include +#include #include "chip.h" #define I2C_BUS_ADDRESS(x) (I2C_BASE_ADDRESS + I2C_DEVICE_SIZE * (x)) @@ -140,3 +144,98 @@ struct device_operations stoneyridge_i2c_mmio_ops = { .acpi_name = i2c_acpi_name, .acpi_fill_ssdt_generator = dw_i2c_acpi_fill_ssdt, }; + +/* + * I2C pins are open drain with external pull up, so in order to bit bang them + * all, SCL pins must become GPIO inputs with no pull, then they need to be + * toggled between input-no-pull and output-low. This table is for the initial + * conversion of all SCL pins to input with no pull. + */ +static const struct soc_amd_gpio i2c_2_gpi[] = { + PAD_GPI(I2C0_SCL_PIN, PULL_NONE), + PAD_GPI(I2C1_SCL_PIN, PULL_NONE), + PAD_GPI(I2C2_SCL_PIN, PULL_NONE), + PAD_GPI(I2C3_SCL_PIN, PULL_NONE), +}; +#define saved_pins_count ARRAY_SIZE(i2c_2_gpi) + +/* + * To program I2C pins without destroying their programming, the registers + * that will be changed need to be saved first. + */ +static void save_i2c_pin_registers(uint8_t gpio, + struct soc_amd_i2c_save *save_table) +{ + uint32_t *gpio_ptr; + + gpio_ptr = (uint32_t *)gpio_get_address(gpio); + save_table->mux_value = iomux_read8(gpio); + save_table->control_value = read32(gpio_ptr); +} + +static void restore_i2c_pin_registers(uint8_t gpio, + struct soc_amd_i2c_save *save_table) +{ + uint32_t *gpio_ptr; + + gpio_ptr = (uint32_t *)gpio_get_address(gpio); + iomux_write8(gpio, save_table->mux_value); + iomux_read8(gpio); + write32(gpio_ptr, save_table->control_value); + read32(gpio_ptr); +} + +/* Slaves to be reset are controlled by devicetree register i2c_scl_reset */ +void sb_reset_i2c_slaves(void) +{ + const struct soc_amd_stoneyridge_config *cfg; + const struct device *dev = pcidev_path_on_root(GNB_DEVFN); + struct soc_amd_i2c_save save_table[saved_pins_count]; + uint8_t i, j, control; + + if (!dev || !dev->chip_info) + return; + cfg = dev->chip_info; + control = cfg->i2c_scl_reset & GPIO_I2C_MASK; + if (control == 0) + return; + + /* Save and reprogram I2C SCL pins */ + for (i = 0; i < saved_pins_count; i++) + save_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]); + sb_program_gpios(i2c_2_gpi, saved_pins_count); + + /* + * Toggle SCL back and forth 9 times under 100KHz. A single read is + * needed after the writes to force the posted write to complete. + */ + for (j = 0; j < 9; j++) { + if (control & GPIO_I2C0_SCL) + write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_LOW); + if (control & GPIO_I2C1_SCL) + write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_LOW); + if (control & GPIO_I2C2_SCL) + write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_LOW); + if (control & GPIO_I2C3_SCL) + write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_LOW); + + read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */ + udelay(4); /* 4usec gets 85KHz for 1 pin, 70KHz for 4 pins */ + + if (control & GPIO_I2C0_SCL) + write32((uint32_t *)GPIO_I2C0_ADDRESS, GPIO_SCL_HIGH); + if (control & GPIO_I2C1_SCL) + write32((uint32_t *)GPIO_I2C1_ADDRESS, GPIO_SCL_HIGH); + if (control & GPIO_I2C2_SCL) + write32((uint32_t *)GPIO_I2C2_ADDRESS, GPIO_SCL_HIGH); + if (control & GPIO_I2C3_SCL) + write32((uint32_t *)GPIO_I2C3_ADDRESS, GPIO_SCL_HIGH); + + read32((uint32_t *)GPIO_I2C3_ADDRESS); /* Flush posted write */ + udelay(4); + } + + /* Restore I2C pins. */ + for (i = 0; i < saved_pins_count; i++) + restore_i2c_pin_registers(i2c_2_gpi[i].gpio, &save_table[i]); +} diff --git a/src/soc/amd/stoneyridge/include/soc/gpio.h b/src/soc/amd/stoneyridge/include/soc/gpio.h index fe8240fb11a..26d0336d0a6 100644 --- a/src/soc/amd/stoneyridge/include/soc/gpio.h +++ b/src/soc/amd/stoneyridge/include/soc/gpio.h @@ -36,21 +36,10 @@ struct soc_amd_event { uint8_t event; }; -struct soc_amd_i2c_save { - uint32_t control_value; - uint8_t mux_value; -}; - #define GPIO_MASTER_SWITCH 0xFC #define GPIO_MASK_STS_EN BIT(28) #define GPIO_INTERRUPT_EN BIT(30) -#define GPIO_I2C0_SCL BIT(0) -#define GPIO_I2C1_SCL BIT(1) -#define GPIO_I2C2_SCL BIT(2) -#define GPIO_I2C3_SCL BIT(3) -#define GPIO_I2C_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) - #define GPIO_TOTAL_PINS 149 #define GPIO_PIN_IN (1 << 0) /* for byte access */ #define GPIO_PIN_OUT (1 << 6) /* for byte access */ @@ -186,15 +175,6 @@ struct soc_amd_i2c_save { #define GPIO_147 147 #define GPIO_148 148 -#define I2C0_SCL_PIN GPIO_145 -#define I2C1_SCL_PIN GPIO_147 -#define I2C2_SCL_PIN GPIO_113 -#define I2C3_SCL_PIN GPIO_19 - -#define GPIO_I2C0_ADDRESS GPIO_BANK2_CONTROL(I2C0_SCL_PIN) -#define GPIO_I2C1_ADDRESS GPIO_BANK2_CONTROL(I2C1_SCL_PIN) -#define GPIO_I2C2_ADDRESS GPIO_BANK1_CONTROL(I2C2_SCL_PIN) -#define GPIO_I2C3_ADDRESS GPIO_BANK0_CONTROL(I2C3_SCL_PIN) #define GPIO_SCL_HIGH 0 #define GPIO_SCL_LOW GPIO_OUTPUT_ENABLE @@ -373,11 +353,6 @@ struct soc_amd_i2c_save { #define GPIO_148_IOMUX_I2C1_SDA 0 #define GPIO_148_IOMUX_GPIOxx 1 -#define I2C0_SCL_PIN_IOMUX_GPIOxx GPIO_145_IOMUX_GPIOxx -#define I2C1_SCL_PIN_IOMUX_GPIOxx GPIO_147_IOMUX_GPIOxx -#define I2C2_SCL_PIN_IOMUX_GPIOxx GPIO_113_IOMUX_GPIOxx -#define I2C3_SCL_PIN_IOMUX_GPIOxx GPIO_19_IOMUX_GPIOxx - enum { GEVENT_0, GEVENT_1, @@ -599,7 +574,6 @@ uintptr_t gpio_get_address(gpio_t gpio_num); * @return none */ void sb_program_gpios(const struct soc_amd_gpio *gpio_list_ptr, size_t size); -void sb_reset_i2c_slaves(void); /* Return the interrupt status and clear if set. */ int gpio_interrupt_status(gpio_t gpio); diff --git a/src/soc/amd/stoneyridge/include/soc/i2c.h b/src/soc/amd/stoneyridge/include/soc/i2c.h new file mode 100644 index 00000000000..62575d0fb84 --- /dev/null +++ b/src/soc/amd/stoneyridge/include/soc/i2c.h @@ -0,0 +1,49 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Advanced Micro Devices, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __STONEYRIDGE_I2C_H__ +#define __STONEYRIDGE_I2C_H__ + +#include + +struct soc_amd_i2c_save { + uint32_t control_value; + uint8_t mux_value; +}; + +#define GPIO_I2C0_SCL BIT(0) +#define GPIO_I2C1_SCL BIT(1) +#define GPIO_I2C2_SCL BIT(2) +#define GPIO_I2C3_SCL BIT(3) +#define GPIO_I2C_MASK (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#define I2C0_SCL_PIN GPIO_145 +#define I2C1_SCL_PIN GPIO_147 +#define I2C2_SCL_PIN GPIO_113 +#define I2C3_SCL_PIN GPIO_19 + +#define GPIO_I2C0_ADDRESS GPIO_BANK2_CONTROL(I2C0_SCL_PIN) +#define GPIO_I2C1_ADDRESS GPIO_BANK2_CONTROL(I2C1_SCL_PIN) +#define GPIO_I2C2_ADDRESS GPIO_BANK1_CONTROL(I2C2_SCL_PIN) +#define GPIO_I2C3_ADDRESS GPIO_BANK0_CONTROL(I2C3_SCL_PIN) + +#define I2C0_SCL_PIN_IOMUX_GPIOxx GPIO_145_IOMUX_GPIOxx +#define I2C1_SCL_PIN_IOMUX_GPIOxx GPIO_147_IOMUX_GPIOxx +#define I2C2_SCL_PIN_IOMUX_GPIOxx GPIO_113_IOMUX_GPIOxx +#define I2C3_SCL_PIN_IOMUX_GPIOxx GPIO_19_IOMUX_GPIOxx + +void sb_reset_i2c_slaves(void); + +#endif /* __STONEYRIDGE_I2C_H__ */ From ce2c1cb742b17623978f3d9a9e414552189bc819 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Wed, 15 May 2019 13:40:05 -0600 Subject: [PATCH 329/588] mb/google/sarien: leave gpio pads unlocks during fsp The FSP will lock down the configuration of GPP_A12, which makes the configuration of the GPIO pin on warm reset not work correctly. This is only needed for the Arcada variant since it is the only variant that uses ISH. BRANCH=sarien BUG=b:132719369 TEST=ISH_GP6 now works on warm resets on arcarda Change-Id: Icb3bae2c48eee053189f1a878f5975c6afe51c71 Signed-off-by: Jett Rink Reviewed-on: https://review.coreboot.org/c/coreboot/+/32831 Reviewed-by: Furquan Shaikh Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index 27c61f35635..b6377ba55dd 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -26,6 +26,7 @@ chip soc/intel/cannonlake register "PchPmSlpS4MinAssert" = "4" # 4s register "PchPmSlpSusMinAssert" = "4" # 4s register "PchPmSlpAMinAssert" = "4" # 2s + register "PchUnlockGpioPads" = "1" register "speed_shift_enable" = "1" register "psys_pmax" = "140" From 2e8188aa13b84f607fd3a1e95fb7b63b26ff1d89 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Wed, 15 May 2019 09:57:49 -0600 Subject: [PATCH 330/588] Documentation/lessons: Tidy up lesson 2 - The link to create an account is now "Sign in" and not "Register" - Use monospace formatting for terminal commands and file names - Properly escape less-than and greater-than - Correct the 'make lint' example command - Reformat example commit messages - Add formatting for website links - Other whitespace fixes Signed-off-by: Jacob Garber Change-Id: I9931bef8c30387d1c08b59973d6de9b5c0419814 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32804 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Lijian Zhao Reviewed-by: Patrick Rudolph Reviewed-by: Stefan Reinauer --- Documentation/lessons/lesson2.md | 96 +++++++++++++++++--------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/Documentation/lessons/lesson2.md b/Documentation/lessons/lesson2.md index 626e76e74ad..ae70c70cbc2 100644 --- a/Documentation/lessons/lesson2.md +++ b/Documentation/lessons/lesson2.md @@ -5,10 +5,10 @@ If you already have an account, skip to Part 2. Otherwise, go to in your preferred web browser. -Select **Register** in the upper right corner. +Select **Sign in** in the upper right corner. Select the appropriate sign-in. For example, if you have a Google account, -select **Google OAuth2** (gerrit-oauth-provider plugin)".**Note:** Your +select **Google OAuth2** (gerrit-oauth-provider plugin). **Note:** Your username for the account will be the username of the account you used to sign-in with. (ex. your Google username). @@ -17,7 +17,7 @@ sign-in with. (ex. your Google username). If you prefer to use an HTTP password instead, skip to Part 2b. For the most up-to-date instructions on how to set up SSH keys with Gerrit go to - + and follow the instructions there. Then, skip to Part 3. Additionally, that section of the Web site provides explanation on starting @@ -35,13 +35,13 @@ doing so could overwrite an existing key. In the upper right corner, select your name and click on **Settings**. Select **SSH Public Keys** on the left-hand side. -In a terminal, run "ssh-keygen" and confirm the default path ".ssh/id_rsa". +In a terminal, run `ssh-keygen` and confirm the default path `.ssh/id_rsa`. Make a passphrase -- remember this phrase. It will be needed whenever you use this RSA Public Key. **Note:** You might want to use a short password, or forego the password altogether as you will be using it very often. -Open "id_rsa.pub", copy all contents and paste into the textbox under +Open `id_rsa.pub`, copy all contents and paste into the textbox under "Add SSH Public Key" in the https://review.coreboot.org webpage. ## Part 2b: Setting up an HTTP Password @@ -51,7 +51,7 @@ after you select your name and click on **Settings** on the left-hand side, rath than selecting **SSH Public Keys**, select **HTTP Password**. Click **Generate Password**. This should fill the "Password" box with a password. Copy -the password, and add the following to your $HOME/.netrc file: +the password, and add the following to your `$HOME/.netrc` file: machine review.coreboot.org login YourUserNameHere password YourPasswordHere @@ -61,7 +61,7 @@ just generated. ## Part 3: Clone coreboot and configure it for submitting patches On Gerrit, click on the **Browse** tab in the upper left corner and select -**Repositories**. From the listing, select the "coreboot" repo. You may have +**Repositories**. From the listing, select the "coreboot" repo. You may have to click the next page arrow at the bottom a few times to find it. If you are using SSH keys, select **ssh** from the tabs under "Project @@ -73,7 +73,7 @@ set. Click the profile picture at the top right and select **User Settings**, then set your username in the **Profile** section. If you are using HTTP, instead, select **http** from the tabs under "Project coreboot" -and run the command that appears +and run the command that appears. Now is a good time to configure your global git identity, if you haven't already. @@ -91,13 +91,13 @@ and other configurations. An easy first commit to make is fixing existing checkpatch errors and warnings in the source files. To see errors that are already present, build the files in -the repository by running 'make lint' in the coreboot directory. Alternatively, -if you want to run 'make lint' on a specific directory, run: +the repository by running `make lint` in the coreboot directory. Alternatively, +if you want to run `make lint` on a specific directory, run: - for file in $(git ls-files | grep src/amd/quadcore); do \ + for file in $(git ls-files | grep ); do \ util/lint/checkpatch.pl --file $file --terse; done -where is the filepath of the directory (ex. src/cpu/amd/car). +where `filepath` is the filepath of the directory (ex. `src/cpu/amd/car`). Any changes made to files under the src directory are made locally, and can be submitted for review. @@ -120,7 +120,7 @@ To commit the change, run git commit -s **Note:** The -s adds a signed-off-by line by the committer. Your commit should be -signed off with your name and email (i.e. **Your Name** ****, based on +signed off with your name and email (i.e. **Your Name** **\**, based on what you set with git config earlier). Running git commit first checks for any errors and warnings using lint. If @@ -134,65 +134,73 @@ The first line of your commit message is your commit summary. This is a brief one-line description of what you changed in the files using the template below: -`: Short description` -*ex. cpu/amd/pi/00630F01: Fix checkpatch warnings and errors* + : Short description + +For example, + + cpu/amd/pi/00630F01: Fix checkpatch warnings and errors **Note:** It is good practice to use present tense in your descriptions and do not punctuate your summary. Then hit Enter. The next paragraph should be a more in-depth explanation of the changes you've made to the files. Again, it is good practice to use present -tense. -*ex. Fix space prohibited between function name and open parenthesis, -line over 80 characters, unnecessary braces for single statement blocks, -space required before open brace errors and warnings.* +tense. Ex. + + Fix space prohibited between function name and open parenthesis, + line over 80 characters, unnecessary braces for single statement blocks, + space required before open brace errors and warnings. When you have finished writing your commit message, save and exit the text editor. You have finished committing your change. If, after submitting your -commit, you wish to make changes to it, running "git commit --amend" allows +commit, you wish to make changes to it, running `git commit --amend` allows you to take back your commit and amend it. -When you are done with your commit, run 'git push' to push your commit to +When you are done with your commit, run `git push` to push your commit to coreboot.org. **Note:** To submit as a draft, use -'git push origin HEAD:refs/drafts/master' Submitting as a draft means that +`git push origin HEAD:refs/drafts/master`. Submitting as a draft means that your commit will be on coreboot.org, but is only visible to those you add as reviewers. This has been a quick primer on how to submit a change to Gerrit for review -using git. You may wish to review the [Gerrit code review workflow +using git. You may wish to review the [Gerrit code review workflow documentation](https://gerrit-review.googlesource.com/Documentation/intro-user.html#code-review), especially if you plan to work on multiple changes at the same time. ## Part 4b: Using git cola to stage and submit a commit If git cola is not installed on your machine, see -https://git-cola.github.io/downloads.html for download instructions. + for download instructions. -After making some edits to src files, rather than run "git add," run -'git cola' from the command line. You should see all of the files +After making some edits to src files, rather than run `git add`, run +`git cola` from the command line. You should see all of the files edited under "Modified". In the textbox labeled "Commit summary" provide a brief one-line description of what you changed in the files according to the template below: -`: Short description` -*ex. cpu/amd/pi/00630F01: Fix checkpatch warnings and errors* + : Short description + +For example, + + cpu/amd/pi/00630F01: Fix checkpatch warnings and errors **Note:** It is good practice to use present tense in your descriptions and do not punctuate your short description. In the larger text box labeled 'Extended description...' provide a more in-depth explanation of the changes you've made to the files. Again, it -is good practice to use present tense. -*ex. Fix space prohibited between function name and open parenthesis, -line over 80 characters, unnecessary braces for single statement blocks, -space required before open brace errors and warnings.* +is good practice to use present tense. Ex. + + Fix space prohibited between function name and open parenthesis, + line over 80 characters, unnecessary braces for single statement blocks, + space required before open brace errors and warnings. Then press Enter two times to move the cursor to below your description. To the left of the text boxes, there is an icon with an downward arrow. Press the arrow and select "Sign Off." Make sure that you are signing off -with your name and email (i.e. **Your Name** ****, based on what +with your name and email (i.e. **Your Name** **\**, based on what you set with git config earlier). Now, review each of your changes and mark either individual changes or @@ -218,30 +226,30 @@ Note: Be sure to add any other changes that haven't already been explained in the extended description. When ready, select 'Commit' again. Once all errors have been satisfied -and the commit succeeds, move to the command line and run 'git push'. -**Note:** To submit as a draft, use 'git push origin HEAD:refs/drafts/master' +and the commit succeeds, move to the command line and run `git push`. +**Note:** To submit as a draft, use `git push origin HEAD:refs/drafts/master`. Submitting as a draft means that your commit will be on coreboot.org, but is only visible to those you add as reviewers. ## Part 5: Getting your commit reviewed -Your commits can now be seen on review.coreboot.org if you select “Your” -and click on “Changes” and can be reviewed by others. Your code will +Your commits can now be seen on review.coreboot.org if you select "Your" +and click on "Changes" and can be reviewed by others. Your code will first be reviewed by build bot (Jenkins), which will either give you a warning or verify a successful build; if so, your commit will receive a +1. Other -users may also give your commit +1. For a commit to be merged, it needs -to receive a +2.**Note:** A +1 and a +1 does not make a +2. Only certain users +users may also give your commit +1. For a commit to be merged, it needs +to receive a +2. **Note:** A +1 and a +1 does not make a +2. Only certain users can give a +2. ## Part 6 (optional): bash-git-prompt To help make it easier to understand the state of the git repository -without running 'git status' or 'git log', there is a way to make the +without running `git status` or `git log`, there is a way to make the command line show the status of the repository at every point. This is through bash-git-prompt. Instructions for installing this are found at: -https://github.com/magicmonty/bash-git-prompt +. **Note:** Feel free to search for different versions of git prompt, as this one is specific to bash. @@ -254,7 +262,7 @@ Run the following two commands in the command line: **Note:** cd will change your directory to your home directory, so the git clone command will be run there. -Finally, open the ~/.bashrc file and append the following two lines: +Finally, open the `~/.bashrc` file and append the following two lines: GIT_PROMPT_ONLY_IN_REPO=1 source ~/.bash-git-prompt/gitprompt.sh @@ -264,7 +272,7 @@ its state. There also are additional configurations that you can change depending on your preferences. If you wish to do so, look at the "All configs for .bashrc" section -on https://github.com/magicmonty/bash-git-prompt. Listed in that section are +on . Listed in that section are various lines that you can copy, uncomment and add to your .bashrc file to change the configurations. Example configurations include avoid fetching remote status, and supporting versions of Git older than 1.7.10. @@ -277,7 +285,7 @@ Suppose you would like to update a commit that has already been pushed to the remote repository. If the commit you wish to update is the most recent commit you have made, after making your desired changes, stage the files (either using git add or in git cola), and amend the commit. To do so, -if you are using the command line, run "git commit --amend." If you are +if you are using the command line, run `git commit --amend`. If you are using git cola, click on the gear icon located on the upper left side under **Commit** and select **Amend Last Commit** in the drop down menu. Then, stage the files you have changed, commit the changes, and run git push to push the From bc674765a93bc5c9bf2c20ce2444389dccc754e1 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 14 May 2019 11:21:41 -0600 Subject: [PATCH 331/588] {arch,cpu}/x86, drivers/intel: Restore cpu_index error handling Previously cpu_index() always succeeded, but since commit 095c931 (src/arch/x86: Use core apic id to get cpu_index()) it is now possible for it to indicate an error by returning -1. This commit adds error handling for all calls to cpu_index(), and restores several checks that were removed in commit 7c712bb (Fix code that would trip -Wtype-limits) but are now needed. Signed-off-by: Jacob Garber Change-Id: I5436eed4cb5675f916924eb9670db04592a8b927 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32795 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/arch/x86/cpu.c | 2 +- src/arch/x86/exception.c | 2 +- src/arch/x86/include/arch/cpu.h | 2 +- src/cpu/x86/mp_init.c | 15 ++++++++++++++- src/cpu/x86/pae/pgtbl.c | 4 ++-- src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c | 9 +++++++++ 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/cpu.c b/src/arch/x86/cpu.c index fb4c7b6cfec..e6c94355033 100644 --- a/src/arch/x86/cpu.c +++ b/src/arch/x86/cpu.c @@ -350,7 +350,7 @@ void arch_bootstate_coreboot_exit(void) * Hence new logic to use cpuid to fetch lapic id and matches with * cpus_default_apic_id[] variable to return correct cpu_index(). */ -unsigned long cpu_index(void) +int cpu_index(void) { int i; int lapic_id = initial_lapicid(); diff --git a/src/arch/x86/exception.c b/src/arch/x86/exception.c index b00777a4553..b88f4a7553e 100644 --- a/src/arch/x86/exception.c +++ b/src/arch/x86/exception.c @@ -502,7 +502,7 @@ void x86_exception(struct eregs *info) } #else /* !CONFIG_GDB_STUB */ #define MDUMP_SIZE 0x80 - unsigned int logical_processor = 0; + int logical_processor = 0; #if ENV_RAMSTAGE logical_processor = cpu_index(); diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 481ee9d8e01..078ea1748b0 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -379,6 +379,6 @@ uint32_t cpu_get_feature_flags_edx(void); * Hence new logic to use cpuid to fetch lapic id and matches with * cpus_default_apic_id[] variable to return correct cpu_index(). */ -unsigned long cpu_index(void); +int cpu_index(void); #endif /* ARCH_CPU_H */ diff --git a/src/cpu/x86/mp_init.c b/src/cpu/x86/mp_init.c index 8957515540c..b7b8fe2afaf 100644 --- a/src/cpu/x86/mp_init.c +++ b/src/cpu/x86/mp_init.c @@ -870,13 +870,20 @@ static int run_ap_work(struct mp_callback *val, long expire_us) int i; int cpus_accepted; struct stopwatch sw; - int cur_cpu = cpu_index(); + int cur_cpu; if (!CONFIG(PARALLEL_MP_AP_WORK)) { printk(BIOS_ERR, "APs already parked. PARALLEL_MP_AP_WORK not selected.\n"); return -1; } + cur_cpu = cpu_index(); + + if (cur_cpu < 0) { + printk(BIOS_ERR, "Invalid CPU index.\n"); + return -1; + } + /* Signal to all the APs to run the func. */ for (i = 0; i < ARRAY_SIZE(ap_callbacks); i++) { if (cur_cpu == i) @@ -918,6 +925,12 @@ static void ap_wait_for_instruction(void) return; cur_cpu = cpu_index(); + + if (cur_cpu < 0) { + printk(BIOS_ERR, "Invalid CPU index.\n"); + return; + } + per_cpu_slot = &ap_callbacks[cur_cpu]; while (1) { diff --git a/src/cpu/x86/pae/pgtbl.c b/src/cpu/x86/pae/pgtbl.c index 062ee402f12..9c921342f10 100644 --- a/src/cpu/x86/pae/pgtbl.c +++ b/src/cpu/x86/pae/pgtbl.c @@ -116,12 +116,12 @@ void *map_2M_page(unsigned long page) static struct pg_table pgtbl[CONFIG_MAX_CPUS] __attribute__((aligned(4096))); static unsigned long mapped_window[CONFIG_MAX_CPUS]; - unsigned long index; + int index; unsigned long window; void *result; int i; index = cpu_index(); - if (index >= CONFIG_MAX_CPUS) + if (index < 0) return MAPPING_ERROR; window = page >> 10; if (window != mapped_window[index]) { diff --git a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c index cdc98e06dec..e26701b0991 100644 --- a/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c +++ b/src/drivers/intel/fsp2_0/ppi/mp_service_ppi.c @@ -45,6 +45,9 @@ static efi_return_status_t mp_get_processor_info(const efi_uintn_t processor_number, efi_processor_information *processor_info_buffer) { + if (cpu_index() < 0) + return FSP_DEVICE_ERROR; + if (processor_info_buffer == NULL) return FSP_INVALID_PARAMETER; @@ -68,6 +71,9 @@ static efi_return_status_t mp_startup_all_aps(const efi_ap_procedure procedure, efi_boolean_t ignored3, efi_uintn_t timeout_usec, void *argument) { + if (cpu_index() < 0) + return FSP_DEVICE_ERROR; + if (procedure == NULL) return FSP_INVALID_PARAMETER; @@ -85,6 +91,9 @@ static efi_return_status_t mp_startup_this_ap(const efi_ap_procedure procedure, efi_uintn_t processor_number, efi_uintn_t timeout_usec, void *argument) { + if (cpu_index() < 0) + return FSP_DEVICE_ERROR; + if (processor_number > get_cpu_count()) return FSP_NOT_FOUND; From d8cd2e9c37377eae5cf42e1778aeb7682d2256ac Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Thu, 4 Apr 2019 18:07:52 +0200 Subject: [PATCH 332/588] libpayload: make log2 and clz work on signed values internally Needed to make libpayload build clean with -Wconversion. BUG=b:111443775 BRANCH=none TEST=make junit.xml shows fewer warnings with -Wconversion enabled Change-Id: Ie193e39854d2231b6d09a2b0deeeef2873e900ab Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32184 Tested-by: build bot (Jenkins) Reviewed-by: Jacob Garber Reviewed-by: Stefan Reinauer --- payloads/libpayload/include/libpayload.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index a578d41f288..57a3afc6b1d 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -434,9 +434,12 @@ void hexdump(const void *memory, size_t length); void fatal(const char *msg) __attribute__((noreturn)); /* Count Leading Zeroes: clz(0) == 32, clz(0xf) == 28, clz(1 << 31) == 0 */ -static inline int clz(u32 x) { return x ? __builtin_clz(x) : sizeof(x) * 8; } +static inline int clz(u32 x) +{ + return x ? __builtin_clz(x) : (int)sizeof(x) * 8; +} /* Integer binary logarithm (rounding down): log2(0) == -1, log2(5) == 2 */ -static inline int log2(u32 x) { return sizeof(x) * 8 - clz(x) - 1; } +static inline int log2(u32 x) { return (int)sizeof(x) * 8 - clz(x) - 1; } /* Find First Set: __ffs(0xf) == 0, __ffs(0) == -1, __ffs(1 << 31) == 31 */ static inline int __ffs(u32 x) { return log2(x & (u32)(-(s32)x)); } /** @} */ From f295d8f113142d72b55cc9a14d33a6de4e6a4dbc Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Wed, 15 May 2019 21:33:05 +0200 Subject: [PATCH 333/588] mb/ocp/monolake: replace IS_ENABLED(CONFIG_*) with CONFIG() That's how we do it these days. Change-Id: I6bf6460440d0f2e6973734ba8894a4be981d03c5 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32812 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/mainboard/ocp/monolake/mainboard.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/ocp/monolake/mainboard.c b/src/mainboard/ocp/monolake/mainboard.c index d457859d443..bbfeeafb3b8 100644 --- a/src/mainboard/ocp/monolake/mainboard.c +++ b/src/mainboard/ocp/monolake/mainboard.c @@ -23,7 +23,7 @@ #define BMC_KCS_BASE 0xca2 #define INTERFACE_IS_IO 0x1 -#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) +#if CONFIG(GENERATE_SMBIOS_TABLES) static int mainboard_smbios_data(struct device *dev, int *handle, unsigned long *current) { @@ -50,7 +50,7 @@ static int mainboard_smbios_data(struct device *dev, int *handle, */ static void mainboard_enable(struct device *dev) { -#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLES) +#if CONFIG(GENERATE_SMBIOS_TABLES) dev->ops->get_smbios_data = mainboard_smbios_data; #endif From d9391837198d838d55ecf853ca70a675f9ca36aa Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Wed, 15 May 2019 21:33:42 +0200 Subject: [PATCH 334/588] soc/qualcomm/common: replace IS_ENABLED(CONFIG_*) with CONFIG() That's how we do it these days. Change-Id: I1c088d23dff709bcdcb21310059e6a2aab84c0be Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32813 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/soc/qualcomm/common/qclib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/soc/qualcomm/common/qclib.c b/src/soc/qualcomm/common/qclib.c index 1fd79b57b5a..73c525001e3 100644 --- a/src/soc/qualcomm/common/qclib.c +++ b/src/soc/qualcomm/common/qclib.c @@ -129,7 +129,7 @@ void qclib_load_and_run(void) memset(ddr_region, 0, sizeof(struct region)); /* output area, QCLib copies console log buffer out */ - if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) + if (CONFIG(CONSOLE_CBMEM)) qclib_add_if_table_entry(QCLIB_TE_QCLIB_LOG_BUFFER, _qclib_serial_log, REGION_SIZE(qclib_serial_log), 0); @@ -152,11 +152,11 @@ void qclib_load_and_run(void) } /* Enable QCLib serial output, based on Kconfig */ - if (IS_ENABLED(CONFIG_CONSOLE_SERIAL)) + if (CONFIG(CONSOLE_SERIAL)) qclib_cb_if_table.global_attributes = QCLIB_GA_ENABLE_UART_LOGGING; - if (IS_ENABLED(CONFIG_QC_SDI_ENABLE)) { + if (CONFIG(QC_SDI_ENABLE)) { struct prog qcsdi = PROG_INIT(PROG_REFCODE, CONFIG_CBFS_PREFIX "/qcsdi"); From 25b35d317eef9ef5d73bbecc502fdac13a478bf6 Mon Sep 17 00:00:00 2001 From: Alex James Date: Wed, 15 May 2019 20:15:47 -0500 Subject: [PATCH 335/588] mb/gigabyte/ga-b75m-d3{h,v}: Various cleanups - Enable LPC TPM support in Kconfig and add pc80/tpm to devicetree - Enable VBT support in Kconfig and add VBT files extracted from vendor firmware - Remove IGPU VBIOS entries from Kconfig - Remove unused PS2 definitions in superio.asl - Add PWRB ACPI device entry to mainboard.asl - Remove duplicate chipset register initialization from mainboard.c - Move ITE Super I/O configuration to mainboard_config_superio in romstage.c Signed-off-by: Alex James Change-Id: I2d11c55dc809b920bccf55f5f745d9f29b18bbb6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32752 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/gigabyte/ga-b75m-d3h/Kconfig | 9 +--- .../gigabyte/ga-b75m-d3h/acpi/mainboard.asl | 2 +- .../gigabyte/ga-b75m-d3h/acpi/platform.asl | 5 +-- .../gigabyte/ga-b75m-d3h/acpi/superio.asl | 19 -------- .../gigabyte/ga-b75m-d3h/board_info.txt | 2 +- src/mainboard/gigabyte/ga-b75m-d3h/data.vbt | Bin 0 -> 3902 bytes .../gigabyte/ga-b75m-d3h/devicetree.cb | 7 ++- src/mainboard/gigabyte/ga-b75m-d3h/dsdt.asl | 2 + .../gigabyte/ga-b75m-d3h/mainboard.c | 42 +----------------- src/mainboard/gigabyte/ga-b75m-d3h/romstage.c | 25 +++++------ src/mainboard/gigabyte/ga-b75m-d3v/Kconfig | 10 +---- .../gigabyte/ga-b75m-d3v/acpi/mainboard.asl | 23 ++++++++++ .../gigabyte/ga-b75m-d3v/acpi/platform.asl | 4 +- .../gigabyte/ga-b75m-d3v/acpi/superio.asl | 4 -- .../gigabyte/ga-b75m-d3v/board_info.txt | 4 +- src/mainboard/gigabyte/ga-b75m-d3v/data.vbt | Bin 0 -> 3902 bytes .../gigabyte/ga-b75m-d3v/devicetree.cb | 10 +++-- src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl | 2 + .../gigabyte/ga-b75m-d3v/mainboard.c | 42 +----------------- src/mainboard/gigabyte/ga-b75m-d3v/romstage.c | 27 ++++++----- 20 files changed, 77 insertions(+), 162 deletions(-) create mode 100644 src/mainboard/gigabyte/ga-b75m-d3h/data.vbt create mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl create mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/data.vbt diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig index 6869bdb3f0d..af884f62fb0 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig +++ b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig @@ -12,6 +12,7 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_OPTION_TABLE select HAVE_CMOS_DEFAULT select HAVE_ACPI_RESUME + select INTEL_GMA_HAVE_VBT select INTEL_INT15 select SERIRQ_CONTINUOUS_MODE select MAINBOARD_HAS_LIBGFXINIT @@ -37,12 +38,4 @@ config MAX_CPUS int default 8 -config VGA_BIOS_ID - string - default "8086,0162" - -config VGA_BIOS_FILE - string - default "pci8086,0162.rom" - endif # BOARD_GIGABYTE_GA_B75M_D3H diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/mainboard.asl b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/mainboard.asl index 34de86f9761..a1c79896d7e 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/mainboard.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/mainboard.asl @@ -18,6 +18,6 @@ Scope (\_SB) { Device (PWRB) { - Name (_HID, EisaId("PNP0C0C")) + Name (_HID, EisaId ("PNP0C0C")) } } diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/platform.asl b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/platform.asl index 06031646b9a..10856d33948 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/platform.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/platform.asl @@ -17,14 +17,13 @@ * entering a sleep state. The sleep state number is passed in Arg0 */ -Method(_PTS,1) +Method (_PTS, 1) { - } /* The _WAK method is called on system wakeup */ Method(_WAK,1) { - Return(Package(){0,0}) + Return (Package () {0, 0}) } diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/superio.asl b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/superio.asl index 78bf687938f..e69de29bb2d 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/acpi/superio.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3h/acpi/superio.asl @@ -1,19 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 The ChromiumOS Authors. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* mainboard configuration */ - -#define SIO_EC_ENABLE_PS2K // Enable PS/2 Keyboard -#define SIO_ENABLE_PS2M // Enable PS/2 Mouse diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/board_info.txt b/src/mainboard/gigabyte/ga-b75m-d3h/board_info.txt index 7ee7f956d8e..c4fb591c0be 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/board_info.txt +++ b/src/mainboard/gigabyte/ga-b75m-d3h/board_info.txt @@ -1,5 +1,5 @@ Category: desktop -Board URL: http://www.gigabyte.com/products/product-page.aspx?pid=4150#sp +Board URL: https://www.gigabyte.com/products/product-page.aspx?pid=4150#ov ROM package: SOIC-8 ROM protocol: SPI ROM socketed: n diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/data.vbt b/src/mainboard/gigabyte/ga-b75m-d3h/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..ccbf6eed7f940d3e2de666eed4af9c9184e63c4b GIT binary patch literal 3902 zcmdT{Z){Ul6hE);_22D#tb3c#)v=r*fo|;2YngLdroMLFTu0fuwKSC&>7eCLGR7!> z0*Sbyi(pJhH3kvUG@2;x6XBDIe&CZ?j4=x_#27yi;s-;B;R7*|AoaXI9fT=+F%t2< z{O-B;^xWUO_uO;teO;T5q%b)W>5Qc#?a_hcrqpO62MRn_Ge`B(5{Zo_w?)IL@U}>N zw0{$R1}kAj&E4w&IpFG~Q1I!V*wn%NWMI4nlM_?9quUF6a=Y@KvBPEy6a6s^@7R%_ z%oipO=5v@#zYs=^R$`GudnR)@a%k`Ne4!ULF0#g8SI5RK#9**9w6Qa!1Vf0*Gre8G z-rz=wMF;vvHz#88a4I%Bf}`UYjU~g$PaY0=xV4Hwmut}Uv0BCl>8n5YH z)FkQn`}?H0oCU8}c&`q01A4LDFyN5d04iM34L&ywTsjH;fE?O112h@FG!2N~q3LM_ zSbdk?r3$N!zmt#3KxhOd)YaY7+owjNgG0md#CR&5+4@rP_-n7v`r%FqXt5ke)e265 z1RsE7ybVt9J+MJ2!>Xd`cxF&_oCjLWDlTAR$56O2`qW2#!N=r(!FDQ+HL7Gi9wI!7IS27AT%G_2*2z`zGx$ z6=q70DRrfVs#0+};cn$SA5B%D66hK4JD#BsIH?*{@XGS?Y%9 zd2}`V1SlRK_u}~!nu|0^GaFEwFK3@#t;xkwq}KfgHhbaW28$!BjRzU3`bD{{fmjE_ zbRzJszF8xTwg6O4tZ)POp?xd-Zf}R0x4>d{vnSpN|? z{6@#wS5-bJ|I1%iZlW0A^<;KwX`>fqb_GCuFtIH$F_oVjnb@1R*jY6Mxdu?fuuk!v z>^8`JN-LZh14UJ)>kLiP`OYI($NcNm%$cfY=y_Gyej%i)m#P|H0J>**!)mS1Ce@>^J-lW@U#i#u8Oc($~4 zSu2%FV>euJ7fX0`wbzwhV~lFDq6zrOsR#b@H7)M~|Bf5KaLeDg+4pX|?UqHxRx<2k z@(5!YhOaWY#MoJemzaE+v7Z>)JaWB_H~V zjUrnoVqBD87TInQPl<9_WOE`ei1Ia&-4IchCRZXd?uCy$S<(+(nu--aywXuB zXZ=m8g665z)IB4V-1=@7omN&6=qr||FFZvIt=cF6Vz8I=J4h_sXD!6T*_QIc*z6i5 z@&2ks1|B?Gn>=ZSL1|Uzv$HwHH)dRm+8lTaM~&eh#-z?584Px`u!`$`C?{~0A}amb zDBTZyiSm)=P;~a_@$m56wDlH!`+M5eO#8jP;GsrmpwB4B@_EssLbeEXS+BQN8)eJ^ zyjn}NcvJmv%r@)?$FO%jWaftF>8tjU)RhNH+Y|8SAUQJz47Nam{_D1Jr{Nd=PiOFc AjQ{`u literal 0 HcmV?d00001 diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/devicetree.cb b/src/mainboard/gigabyte/ga-b75m-d3h/devicetree.cb index 7a3568aba3a..ceb92793653 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/devicetree.cb +++ b/src/mainboard/gigabyte/ga-b75m-d3h/devicetree.cb @@ -21,16 +21,15 @@ chip northbridge/intel/sandybridge device domain 0 on subsystemid 0x1458 0x5000 inherit - device pci 00.0 on # host bridge + device pci 00.0 on # Host bridge subsystemid 0x1458 0x5000 end device pci 01.0 on end # PCIe Bridge for discrete graphics - device pci 02.0 on # vga controller + device pci 02.0 on # Integrated VGA controller subsystemid 0x1458 0xd000 end chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH - # GPI routing register "alt_gp_smi_en" = "0x0000" register "gen1_dec" = "0x003c0a01" @@ -109,7 +108,7 @@ chip northbridge/intel/sandybridge end chip drivers/pc80/tpm - device pnp 0c31.0 on end + device pnp 0c31.0 on end end end device pci 1f.2 on # SATA Controller 1 diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/dsdt.asl b/src/mainboard/gigabyte/ga-b75m-d3h/dsdt.asl index 67054cc28d6..c00ee30e6b4 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/dsdt.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3h/dsdt.asl @@ -24,7 +24,9 @@ DefinitionBlock( #include // Some generic macros + #include "acpi/mainboard.asl" #include "acpi/platform.asl" + #include "acpi/thermal.asl" #include /* global NVS and variables. */ #include diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/mainboard.c b/src/mainboard/gigabyte/ga-b75m-d3h/mainboard.c index 4e8d9f579f9..cc267579143 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/mainboard.c +++ b/src/mainboard/gigabyte/ga-b75m-d3h/mainboard.c @@ -19,54 +19,16 @@ #include #include -static void mainboard_init(struct device *dev) -{ - RCBA32(0x38c8) = 0x00002005; - RCBA32(0x38c4) = 0x00802005; - RCBA32(0x2240) = 0x00330e71; - RCBA32(0x2244) = 0x003f0eb1; - RCBA32(0x2248) = 0x002102cd; - RCBA32(0x224c) = 0x00f60000; - RCBA32(0x2250) = 0x00020000; - RCBA32(0x2254) = 0x00e3004c; - RCBA32(0x2258) = 0x00e20bef; - RCBA32(0x2260) = 0x003304ed; - RCBA32(0x2278) = 0x001107c1; - RCBA32(0x227c) = 0x001d07e9; - RCBA32(0x2280) = 0x00e20000; - RCBA32(0x2284) = 0x00ee0000; - RCBA32(0x2288) = 0x005b05d3; - RCBA32(0x2318) = 0x04b8ff2e; - RCBA32(0x231c) = 0x03930f2e; - RCBA32(0x3808) = 0x005044a3; - RCBA32(0x3810) = 0x52410000; - RCBA32(0x3814) = 0x0000008a; - RCBA32(0x3818) = 0x00000006; - RCBA32(0x381c) = 0x0000072e; - RCBA32(0x3820) = 0x0000000a; - RCBA32(0x3824) = 0x00000123; - RCBA32(0x3828) = 0x00000009; - RCBA32(0x382c) = 0x00000001; - RCBA32(0x3834) = 0x0000061a; - RCBA32(0x3838) = 0x00000003; - RCBA32(0x383c) = 0x00000a76; - RCBA32(0x3840) = 0x00000004; - RCBA32(0x3844) = 0x0000e5e4; - RCBA32(0x3848) = 0x0000000e; -} - // mainboard_enable is executed as first thing after // enumerate_buses(). static void mainboard_enable(struct device *dev) { - dev->ops->init = mainboard_init; - install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_NONE, GMA_INT15_PANEL_FIT_DEFAULT, - GMA_INT15_BOOT_DISPLAY_CRT, 0); + GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); } struct chip_operations mainboard_ops = { - .enable_dev = mainboard_enable, + .enable_dev = mainboard_enable }; diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c b/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c index aa5f4840a3a..49647850cd8 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c +++ b/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c @@ -25,12 +25,6 @@ #define SIO_GPIO PNP_DEV(SUPERIO_BASE, IT8728F_GPIO) #define SERIAL_DEV PNP_DEV(SUPERIO_BASE, 0x01) -void mainboard_rcba_config(void) -{ - /* Enable HECI */ - RCBA32(FD2) &= ~0x2; -} - void pch_enable_lpc(void) { pci_write_config16(PCH_LPC_DEV, LPC_EN, KBC_LPC_EN | @@ -40,7 +34,10 @@ void pch_enable_lpc(void) pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10); pci_write_config32(PCH_LPC_DEV, ETR3, 0x10000); +} +void mainboard_config_superio(void) +{ /* Initialize SuperIO */ ite_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); @@ -87,18 +84,20 @@ const struct southbridge_usb_port mainboard_usb_ports[] = { { 1, 5, 6 }, }; -void mainboard_get_spd(spd_raw_data *spd, bool id_only) +void mainboard_early_init(int s3resume) { - read_spd (&spd[0], 0x50, id_only); - read_spd (&spd[1], 0x51, id_only); - read_spd (&spd[2], 0x52, id_only); - read_spd (&spd[3], 0x53, id_only); } -void mainboard_early_init(int s3resume) +void mainboard_get_spd(spd_raw_data *spd, bool id_only) { + read_spd(&spd[0], 0x50, id_only); + read_spd(&spd[1], 0x51, id_only); + read_spd(&spd[2], 0x52, id_only); + read_spd(&spd[3], 0x53, id_only); } -void mainboard_config_superio(void) +void mainboard_rcba_config(void) { + /* Enable HECI */ + RCBA32(FD2) &= ~0x2; } diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig index 4048f98615a..d86c742b372 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig +++ b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig @@ -12,9 +12,11 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_OPTION_TABLE select HAVE_CMOS_DEFAULT select HAVE_ACPI_RESUME + select INTEL_GMA_HAVE_VBT select INTEL_INT15 select SERIRQ_CONTINUOUS_MODE select MAINBOARD_HAS_LIBGFXINIT + select MAINBOARD_HAS_LPC_TPM config DRAM_RESET_GATE_GPIO int @@ -36,12 +38,4 @@ config MAX_CPUS int default 8 -config VGA_BIOS_ID - string - default "8086,0102" - -config VGA_BIOS_FILE - string - default "pci8086,0102.rom" - endif # BOARD_GIGABYTE_GA_B75M_D3V diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl new file mode 100644 index 00000000000..a1c79896d7e --- /dev/null +++ b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl @@ -0,0 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Google Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Scope (\_SB) +{ + Device (PWRB) + { + Name (_HID, EisaId ("PNP0C0C")) + } +} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl index d8d33208f89..10856d33948 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl @@ -17,7 +17,7 @@ * entering a sleep state. The sleep state number is passed in Arg0 */ -Method(_PTS,1) +Method (_PTS, 1) { } @@ -25,5 +25,5 @@ Method(_PTS,1) Method(_WAK,1) { - Return(Package(){0,0}) + Return (Package () {0, 0}) } diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl index 4c50b6c689b..e69de29bb2d 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl @@ -1,4 +0,0 @@ -/* mainboard configuration */ - -#define SIO_EC_ENABLE_PS2K // Enable PS/2 Keyboard -#define SIO_ENABLE_PS2M // Enable PS/2 Mouse diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt b/src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt index ede1945aec8..5535d9af60c 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt +++ b/src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt @@ -1,7 +1,7 @@ Category: desktop -Board URL: http://www.gigabyte.com/products/product-page.aspx?pid=4151#ov +Board URL: https://www.gigabyte.com/products/product-page.aspx?pid=4151#ov ROM package: SOIC-8 ROM protocol: SPI ROM socketed: n Flashrom support: y -Release date: 2012 +Release year: 2012 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/data.vbt b/src/mainboard/gigabyte/ga-b75m-d3v/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..ccbf6eed7f940d3e2de666eed4af9c9184e63c4b GIT binary patch literal 3902 zcmdT{Z){Ul6hE);_22D#tb3c#)v=r*fo|;2YngLdroMLFTu0fuwKSC&>7eCLGR7!> z0*Sbyi(pJhH3kvUG@2;x6XBDIe&CZ?j4=x_#27yi;s-;B;R7*|AoaXI9fT=+F%t2< z{O-B;^xWUO_uO;teO;T5q%b)W>5Qc#?a_hcrqpO62MRn_Ge`B(5{Zo_w?)IL@U}>N zw0{$R1}kAj&E4w&IpFG~Q1I!V*wn%NWMI4nlM_?9quUF6a=Y@KvBPEy6a6s^@7R%_ z%oipO=5v@#zYs=^R$`GudnR)@a%k`Ne4!ULF0#g8SI5RK#9**9w6Qa!1Vf0*Gre8G z-rz=wMF;vvHz#88a4I%Bf}`UYjU~g$PaY0=xV4Hwmut}Uv0BCl>8n5YH z)FkQn`}?H0oCU8}c&`q01A4LDFyN5d04iM34L&ywTsjH;fE?O112h@FG!2N~q3LM_ zSbdk?r3$N!zmt#3KxhOd)YaY7+owjNgG0md#CR&5+4@rP_-n7v`r%FqXt5ke)e265 z1RsE7ybVt9J+MJ2!>Xd`cxF&_oCjLWDlTAR$56O2`qW2#!N=r(!FDQ+HL7Gi9wI!7IS27AT%G_2*2z`zGx$ z6=q70DRrfVs#0+};cn$SA5B%D66hK4JD#BsIH?*{@XGS?Y%9 zd2}`V1SlRK_u}~!nu|0^GaFEwFK3@#t;xkwq}KfgHhbaW28$!BjRzU3`bD{{fmjE_ zbRzJszF8xTwg6O4tZ)POp?xd-Zf}R0x4>d{vnSpN|? z{6@#wS5-bJ|I1%iZlW0A^<;KwX`>fqb_GCuFtIH$F_oVjnb@1R*jY6Mxdu?fuuk!v z>^8`JN-LZh14UJ)>kLiP`OYI($NcNm%$cfY=y_Gyej%i)m#P|H0J>**!)mS1Ce@>^J-lW@U#i#u8Oc($~4 zSu2%FV>euJ7fX0`wbzwhV~lFDq6zrOsR#b@H7)M~|Bf5KaLeDg+4pX|?UqHxRx<2k z@(5!YhOaWY#MoJemzaE+v7Z>)JaWB_H~V zjUrnoVqBD87TInQPl<9_WOE`ei1Ia&-4IchCRZXd?uCy$S<(+(nu--aywXuB zXZ=m8g665z)IB4V-1=@7omN&6=qr||FFZvIt=cF6Vz8I=J4h_sXD!6T*_QIc*z6i5 z@&2ks1|B?Gn>=ZSL1|Uzv$HwHH)dRm+8lTaM~&eh#-z?584Px`u!`$`C?{~0A}amb zDBTZyiSm)=P;~a_@$m56wDlH!`+M5eO#8jP;GsrmpwB4B@_EssLbeEXS+BQN8)eJ^ zyjn}NcvJmv%r@)?$FO%jWaftF>8tjU)RhNH+Y|8SAUQJz47Nam{_D1Jr{Nd=PiOFc AjQ{`u literal 0 HcmV?d00001 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb b/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb index a00e2ee0c5d..ceb92793653 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb +++ b/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb @@ -1,4 +1,5 @@ chip northbridge/intel/sandybridge + # IGD Displays register "gfx.ndid" = "3" register "gfx.did" = "{ 0x80000100, 0x80000240, 0x80000410 }" @@ -20,16 +21,15 @@ chip northbridge/intel/sandybridge device domain 0 on subsystemid 0x1458 0x5000 inherit - device pci 00.0 on # host bridge + device pci 00.0 on # Host bridge subsystemid 0x1458 0x5000 end device pci 01.0 on end # PCIe Bridge for discrete graphics - device pci 02.0 on # vga controller + device pci 02.0 on # Integrated VGA controller subsystemid 0x1458 0xd000 end chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH - # GPI routing register "alt_gp_smi_en" = "0x0000" register "gen1_dec" = "0x003c0a01" @@ -106,6 +106,10 @@ chip northbridge/intel/sandybridge device pnp 2e.7 off end # GPIO device pnp 2e.a off end # IR end + + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end end device pci 1f.2 on # SATA Controller 1 subsystemid 0x1458 0xb005 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl b/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl index 67054cc28d6..c00ee30e6b4 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl +++ b/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl @@ -24,7 +24,9 @@ DefinitionBlock( #include // Some generic macros + #include "acpi/mainboard.asl" #include "acpi/platform.asl" + #include "acpi/thermal.asl" #include /* global NVS and variables. */ #include diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c b/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c index 4e8d9f579f9..cc267579143 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c +++ b/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c @@ -19,54 +19,16 @@ #include #include -static void mainboard_init(struct device *dev) -{ - RCBA32(0x38c8) = 0x00002005; - RCBA32(0x38c4) = 0x00802005; - RCBA32(0x2240) = 0x00330e71; - RCBA32(0x2244) = 0x003f0eb1; - RCBA32(0x2248) = 0x002102cd; - RCBA32(0x224c) = 0x00f60000; - RCBA32(0x2250) = 0x00020000; - RCBA32(0x2254) = 0x00e3004c; - RCBA32(0x2258) = 0x00e20bef; - RCBA32(0x2260) = 0x003304ed; - RCBA32(0x2278) = 0x001107c1; - RCBA32(0x227c) = 0x001d07e9; - RCBA32(0x2280) = 0x00e20000; - RCBA32(0x2284) = 0x00ee0000; - RCBA32(0x2288) = 0x005b05d3; - RCBA32(0x2318) = 0x04b8ff2e; - RCBA32(0x231c) = 0x03930f2e; - RCBA32(0x3808) = 0x005044a3; - RCBA32(0x3810) = 0x52410000; - RCBA32(0x3814) = 0x0000008a; - RCBA32(0x3818) = 0x00000006; - RCBA32(0x381c) = 0x0000072e; - RCBA32(0x3820) = 0x0000000a; - RCBA32(0x3824) = 0x00000123; - RCBA32(0x3828) = 0x00000009; - RCBA32(0x382c) = 0x00000001; - RCBA32(0x3834) = 0x0000061a; - RCBA32(0x3838) = 0x00000003; - RCBA32(0x383c) = 0x00000a76; - RCBA32(0x3840) = 0x00000004; - RCBA32(0x3844) = 0x0000e5e4; - RCBA32(0x3848) = 0x0000000e; -} - // mainboard_enable is executed as first thing after // enumerate_buses(). static void mainboard_enable(struct device *dev) { - dev->ops->init = mainboard_init; - install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_NONE, GMA_INT15_PANEL_FIT_DEFAULT, - GMA_INT15_BOOT_DISPLAY_CRT, 0); + GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); } struct chip_operations mainboard_ops = { - .enable_dev = mainboard_enable, + .enable_dev = mainboard_enable }; diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c b/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c index 035e20e2a9b..eb88d366aeb 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c +++ b/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c @@ -25,12 +25,6 @@ #define SIO_GPIO PNP_DEV(SUPERIO_BASE, IT8728F_GPIO) #define SERIAL_DEV PNP_DEV(SUPERIO_BASE, 0x01) -void mainboard_rcba_config(void) -{ - /* Enable HECI */ - RCBA32(FD2) &= ~0x2; -} - void pch_enable_lpc(void) { pci_write_config16(PCH_LPC_DEV, LPC_EN, KBC_LPC_EN | @@ -40,7 +34,10 @@ void pch_enable_lpc(void) pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10); pci_write_config32(PCH_LPC_DEV, ETR3, 0x10000); +} +void mainboard_config_superio(void) +{ /* Initialize SuperIO */ ite_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); @@ -87,19 +84,21 @@ const struct southbridge_usb_port mainboard_usb_ports[] = { { 1, 5, 6 }, }; -/* FIXME: This board only has two DIMM slots! */ -void mainboard_get_spd(spd_raw_data *spd, bool id_only) +void mainboard_early_init(int s3resume) { - read_spd (&spd[0], 0x50, id_only); - read_spd (&spd[1], 0x51, id_only); - read_spd (&spd[2], 0x52, id_only); - read_spd (&spd[3], 0x53, id_only); } -void mainboard_early_init(int s3resume) +/* FIXME: This board only has two DIMM slots! */ +void mainboard_get_spd(spd_raw_data *spd, bool id_only) { + read_spd(&spd[0], 0x50, id_only); + read_spd(&spd[1], 0x51, id_only); + read_spd(&spd[2], 0x52, id_only); + read_spd(&spd[3], 0x53, id_only); } -void mainboard_config_superio(void) +void mainboard_rcba_config(void) { + /* Enable HECI */ + RCBA32(FD2) &= ~0x2; } From bf7435087eee94a6cbd5f50d816fea9168395090 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 25 Mar 2019 17:05:20 +0100 Subject: [PATCH 336/588] sb/intel/sandybridge/early_pch: Make DMI init more readable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a few comments and use known register values. Based on the "2nd Generation Intel® Core™ Processor Family Mobile" datasheet and the existing serialice trace. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to GNU/Linux. Change-Id: I404515b77a22324f55581f117d79630be4ba64dd Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32071 Reviewed-by: Patrick Georgi Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- .../intel/sandybridge/sandybridge.h | 15 +- src/southbridge/intel/bd82x6x/early_pch.c | 206 ++++++++++++------ src/southbridge/intel/bd82x6x/pch.h | 2 + 3 files changed, 150 insertions(+), 73 deletions(-) diff --git a/src/northbridge/intel/sandybridge/sandybridge.h b/src/northbridge/intel/sandybridge/sandybridge.h index 92cb888a418..77f2ead74ee 100644 --- a/src/northbridge/intel/sandybridge/sandybridge.h +++ b/src/northbridge/intel/sandybridge/sandybridge.h @@ -175,12 +175,23 @@ enum platform_type { #define DMIPVCCCTL 0x00c /* 16bit */ #define DMIVC0RCAP 0x010 /* 32bit */ -#define DMIVC0RCTL0 0x014 /* 32bit */ +#define DMIVC0RCTL 0x014 /* 32bit */ #define DMIVC0RSTS 0x01a /* 16bit */ +#define VC0NP 0x2 #define DMIVC1RCAP 0x01c /* 32bit */ #define DMIVC1RCTL 0x020 /* 32bit */ #define DMIVC1RSTS 0x026 /* 16bit */ +#define VC1NP 0x2 + +#define DMIVCPRCTL 0x02c /* 32bit */ + +#define DMIVCPRSTS 0x032 /* 16bit */ +#define VCPNP 0x2 + +#define DMIVCMRCTL 0x0038 /* 32 bit */ +#define DMIVCMRSTS 0x003e /* 16 bit */ +#define VCMNP 0x2 #define DMILE1D 0x050 /* 32bit */ #define DMILE1A 0x058 /* 64bit */ @@ -190,7 +201,7 @@ enum platform_type { #define DMILCAP 0x084 /* 32bit */ #define DMILCTL 0x088 /* 16bit */ #define DMILSTS 0x08a /* 16bit */ - +#define TXTRN (1 << 11) #define DMICTL1 0x0f0 /* 32bit */ #define DMICTL2 0x0fc /* 32bit */ diff --git a/src/southbridge/intel/bd82x6x/early_pch.c b/src/southbridge/intel/bd82x6x/early_pch.c index a50a1596689..76ca2027763 100644 --- a/src/southbridge/intel/bd82x6x/early_pch.c +++ b/src/southbridge/intel/bd82x6x/early_pch.c @@ -20,6 +20,7 @@ #include #include #include +#include /* For DMI bar. */ #include @@ -68,36 +69,29 @@ write_iobp(u32 address, u32 val) read8(DEFAULT_RCBA + IOBPS); // call wait_iobp() instead here? } - static void init_dmi (void) { + volatile u32 tmp; int i; - write32 (DEFAULT_DMIBAR + 0x0914, - read32 (DEFAULT_DMIBAR + 0x0914) | 0x80000000); - write32 (DEFAULT_DMIBAR + 0x0934, - read32 (DEFAULT_DMIBAR + 0x0934) | 0x80000000); - for (i = 0; i < 4; i++) - { - write32 (DEFAULT_DMIBAR + 0x0a00 + (i << 4), - read32 (DEFAULT_DMIBAR + 0x0a00 + (i << 4)) & 0xf3ffffff); - write32 (DEFAULT_DMIBAR + 0x0a04 + (i << 4), - read32 (DEFAULT_DMIBAR + 0x0a04 + (i << 4)) | 0x800); + DMIBAR32(0x0914) |= 0x80000000; + DMIBAR32(0x0934) |= 0x80000000; + + for (i = 0; i < 4; i++) { + DMIBAR32(0x0a00 + (i << 4)) &= 0xf3ffffff; + DMIBAR32(0x0a04 + (i << 4)) |= 0x800; } - write32 (DEFAULT_DMIBAR + 0x0c30, (read32 (DEFAULT_DMIBAR + 0x0c30) - & 0xfffffff) | 0x40000000); - for (i = 0; i < 2; i++) - { - write32 (DEFAULT_DMIBAR + 0x0904 + (i << 5), - read32 (DEFAULT_DMIBAR + 0x0904 + (i << 5)) & 0xfe3fffff); - write32 (DEFAULT_DMIBAR + 0x090c + (i << 5), - read32 (DEFAULT_DMIBAR + 0x090c + (i << 5)) & 0xfff1ffff); + DMIBAR32(0x0c30) = (DMIBAR32(0x0c30) & 0xfffffff) | 0x40000000; + + for (i = 0; i < 2; i++) { + DMIBAR32(0x0904 + (i << 5)) &= 0xfe3fffff; + DMIBAR32(0x090c + (i << 5)) &= 0xfff1ffff; } - write32 (DEFAULT_DMIBAR + 0x090c, - read32 (DEFAULT_DMIBAR + 0x090c) & 0xfe1fffff); - write32 (DEFAULT_DMIBAR + 0x092c, - read32 (DEFAULT_DMIBAR + 0x092c) & 0xfe1fffff); + + DMIBAR32(0x090c) &= 0xfe1fffff; + DMIBAR32(0x092c) &= 0xfe1fffff; + read32 (DEFAULT_DMIBAR + 0x0904); // !!! = 0x7a1842ec write32 (DEFAULT_DMIBAR + 0x0904, 0x7a1842ec); read32 (DEFAULT_DMIBAR + 0x090c); // !!! = 0x00000208 @@ -226,33 +220,54 @@ init_dmi (void) write32 (DEFAULT_DMIBAR + 0x0934, 0x98200280); read32 (DEFAULT_DMIBAR + 0x022c); // !!! = 0x00c26460 write32 (DEFAULT_DMIBAR + 0x022c, 0x00c2403c); - read8 (DEFAULT_RCBA + 0x21a4); // !!! = 0x42 - - read32 (DEFAULT_RCBA + 0x21a4); // !!! = 0x00012c42 - read32 (DEFAULT_RCBA + 0x2340); // !!! = 0x0013001b - write32 (DEFAULT_RCBA + 0x2340, 0x003a001b); - read8 (DEFAULT_RCBA + 0x21b0); // !!! = 0x01 - write8 (DEFAULT_RCBA + 0x21b0, 0x02); - read32 (DEFAULT_DMIBAR + 0x0084); // !!! = 0x0041ac41 - write32 (DEFAULT_DMIBAR + 0x0084, 0x0041ac42); - read8 (DEFAULT_DMIBAR + 0x0088); // !!! = 0x00 - write8 (DEFAULT_DMIBAR + 0x0088, 0x20); - read16 (DEFAULT_DMIBAR + 0x008a); // !!! = 0x0041 - read8 (DEFAULT_DMIBAR + 0x0088); // !!! = 0x00 - write8 (DEFAULT_DMIBAR + 0x0088, 0x20); - read16 (DEFAULT_DMIBAR + 0x008a); // !!! = 0x0042 - read16 (DEFAULT_DMIBAR + 0x008a); // !!! = 0x0042 - - read32 (DEFAULT_DMIBAR + 0x0014); // !!! = 0x8000007f - write32 (DEFAULT_DMIBAR + 0x0014, 0x80000019); - read32 (DEFAULT_DMIBAR + 0x0020); // !!! = 0x01000000 - write32 (DEFAULT_DMIBAR + 0x0020, 0x81000022); - read32 (DEFAULT_DMIBAR + 0x002c); // !!! = 0x02000000 - write32 (DEFAULT_DMIBAR + 0x002c, 0x82000044); - read32 (DEFAULT_DMIBAR + 0x0038); // !!! = 0x07000080 - write32 (DEFAULT_DMIBAR + 0x0038, 0x87000080); - read8 (DEFAULT_DMIBAR + 0x0004); // !!! = 0x00 - write8 (DEFAULT_DMIBAR + 0x0004, 0x01); + + /* Link Capabilities Register */ + RCBA32(0x21a4) = (RCBA32(0x21a4) & ~0x3fc00) | + (3 << 10) | // L0s and L1 entry supported + (2 << 12) | // L0s 128 ns to less than 256 ns + (2 << 15); // L1 2 us to less than 4 us + + RCBA32(0x2340) = (RCBA32(0x2340) & ~0xff0000) | (0x3a << 16); + RCBA8(0x21b0) = (RCBA8(0x21b0) & ~0xf) | 2; + + /* Write once settings. */ + DMIBAR32(DMILCAP) = (DMIBAR32(DMILCAP) & ~0x3f00f) | + (2 << 0) | // 5GT/s + (2 << 12) | // L0s 128 ns to less than 256 ns + (2 << 15); // L1 2 us to less than 4 us + + DMIBAR8(DMILCTL) |= 0x20; // Retrain link + while (DMIBAR16(DMILSTS) & TXTRN) + ; + + DMIBAR8(DMILCTL) |= 0x20; // Retrain link + while (DMIBAR16(DMILSTS) & TXTRN) + ; + + const u8 w = (DMIBAR16(DMILSTS) >> 4) & 0x1f; + const u16 t = (DMIBAR16(DMILSTS) & 0xf) * 2500; + + printk(BIOS_DEBUG, "DMI: Running at X%x @ %dMT/s\n", w, t); + /* + * Virtual Channel resources must match settings in RCBA! + * + * Channel Vp and Vm are documented in + * "Desktop 4th Generation Intel Core Processor Family, Desktop Intel + * Pentium Processor Family, and Desktop Intel Celeron Processor Family + * Vol. 2" + */ + + /* Channel 0: Enable, Set ID to 0, map TC0 and TC3 and TC4 to VC0. */ + DMIBAR32(DMIVC0RCTL) = (1 << 31) | (0 << 24) | (0x0c << 1) | 1; + /* Channel 1: Enable, Set ID to 1, map TC1 and TC5 to VC1. */ + DMIBAR32(DMIVC1RCTL) = (1 << 31) | (1 << 24) | (0x11 << 1); + /* Channel p: Enable, Set ID to 2, map TC2 and TC6 to VCp */ + DMIBAR32(DMIVCPRCTL) = (1 << 31) | (2 << 24) | (0x22 << 1); + /* Channel m: Enable, Set ID to 0, map TC7 to VCm */ + DMIBAR32(DMIVCMRCTL) = (1 << 31) | (7 << 24) | (0x40 << 1); + + /* Set Extended VC Count (EVCC) to 1 as Channel 1 is active. */ + DMIBAR8(DMIPVCCAP1) |= 1; read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x01200654 write32 (DEFAULT_RCBA + 0x0050, 0x01200654); @@ -261,27 +276,76 @@ init_dmi (void) read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x012a0654 read8 (DEFAULT_RCBA + 0x1114); // !!! = 0x00 write8 (DEFAULT_RCBA + 0x1114, 0x05); - read32 (DEFAULT_RCBA + 0x2014); // !!! = 0x80000011 - write32 (DEFAULT_RCBA + 0x2014, 0x80000019); - read32 (DEFAULT_RCBA + 0x2020); // !!! = 0x00000000 - write32 (DEFAULT_RCBA + 0x2020, 0x81000022); - read32 (DEFAULT_RCBA + 0x2020); // !!! = 0x81000022 - read32 (DEFAULT_RCBA + 0x2030); // !!! = 0x00000000 - write32 (DEFAULT_RCBA + 0x2030, 0x82000044); - read32 (DEFAULT_RCBA + 0x2030); // !!! = 0x82000044 - read32 (DEFAULT_RCBA + 0x2040); // !!! = 0x00000000 - write32 (DEFAULT_RCBA + 0x2040, 0x87000080); - read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x012a0654 - write32 (DEFAULT_RCBA + 0x0050, 0x812a0654); - read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x812a0654 - read16 (DEFAULT_RCBA + 0x201a); // !!! = 0x0000 - read16 (DEFAULT_RCBA + 0x2026); // !!! = 0x0000 - read16 (DEFAULT_RCBA + 0x2036); // !!! = 0x0000 - read16 (DEFAULT_RCBA + 0x2046); // !!! = 0x0000 - read16 (DEFAULT_DMIBAR + 0x001a); // !!! = 0x0000 - read16 (DEFAULT_DMIBAR + 0x0026); // !!! = 0x0000 - read16 (DEFAULT_DMIBAR + 0x0032); // !!! = 0x0000 - read16 (DEFAULT_DMIBAR + 0x003e); // !!! = 0x0000 + + /* + * Virtual Channel resources must match settings in DMIBAR! + * + * Some of the following settings are taken from + * "Intel Core i5-600, i3-500 Desktop Processor Series and Intel + * Pentium Desktop Processor 6000 Series Vol. 2" datasheet and + * serialice traces. + */ + + /* Virtual Channel 0 Resource Control Register. + * Enable channel. + * Set Virtual Channel Identifier. + * Map TC0 and TC3 and TC4 to VC0. + */ + + RCBA32(0x2014) = (1 << 31) | (0 << 24) | (0x0c << 1) | 1; + + /* Virtual Channel 1 Resource Control Register. + * Enable channel. + * Set Virtual Channel Identifier. + * Map TC1 and TC5 to VC1. + */ + RCBA32(0x2020) = (1 << 31) | (1 << 24) | (0x11 << 1); + /* Read back register */ + tmp = RCBA32(0x2020); + + /* Virtual Channel private Resource Control Register. + * Enable channel. + * Set Virtual Channel Identifier. + * Map TC2 and TC6 to VCp. + */ + RCBA32(0x2030) = (1 << 31) | (2 << 24) | (0x22 << 1); + /* Read back register */ + tmp = RCBA32(0x2030); + + /* Virtual Channel ME Resource Control Register. + * Enable channel. + * Set Virtual Channel Identifier. + * Map TC7 to VCm. + */ + RCBA32(0x2040) = (1 << 31) | (7 << 24) | (0x40 << 1); + + /* Lock Virtual Channel Resource control register. */ + RCBA32(0x0050) |= 0x80000000; + /* Read back register */ + tmp = RCBA32(0x0050); + + /* Wait for virtual channels negotiation pending */ + while (RCBA16(0x201a) & VCNEGPND) + ; + while (RCBA16(0x2026) & VCNEGPND) + ; + while (RCBA16(0x2036) & VCNEGPND) + ; + while (RCBA16(0x2046) & VCNEGPND) + ; + + /* + * BIOS Requirement: Check if DMI VC Negotiation was successful. + * Wait for virtual channels negotiation pending. + */ + while (DMIBAR16(DMIVC0RSTS) & VC0NP) + ; + while (DMIBAR16(DMIVC1RSTS) & VC1NP) + ; + while (DMIBAR16(DMIVCPRSTS) & VCPNP) + ; + while (DMIBAR16(DMIVCMRSTS) & VCMNP) + ; } void diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h index 21b603108a7..fb8238ad4f9 100644 --- a/src/southbridge/intel/bd82x6x/pch.h +++ b/src/southbridge/intel/bd82x6x/pch.h @@ -310,6 +310,8 @@ early_usb_init (const struct southbridge_usb_port *portmap); #define IOTR2 0x1e90 /* 64bit */ #define IOTR3 0x1e98 /* 64bit */ +#define VCNEGPND 2 + #define TCTL 0x3000 /* 8bit */ #define NOINT 0 From a1e9eefa402a9ec3a008e9d0d4b3041274b8d0b7 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 25 Mar 2019 11:47:36 +0100 Subject: [PATCH 337/588] sb/intel/bd82x6x/early_pch: Make use of RCBA and DMIBAR marcros Use RCBA and DMIBAR macros to get rid of DEFAULT_RCBA and DEFAULT_DMIBAR. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to OS, no errors visible in dmesg. Change-Id: Ic9be2240ea10b17c8cc289007dccadbb9e3f69ab Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32072 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/southbridge/intel/bd82x6x/early_pch.c | 326 +++++++++++----------- 1 file changed, 164 insertions(+), 162 deletions(-) diff --git a/src/southbridge/intel/bd82x6x/early_pch.c b/src/southbridge/intel/bd82x6x/early_pch.c index 76ca2027763..76f1447e8ad 100644 --- a/src/southbridge/intel/bd82x6x/early_pch.c +++ b/src/southbridge/intel/bd82x6x/early_pch.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* For DMI bar. */ @@ -32,41 +33,41 @@ static void wait_iobp(void) { - while (read8(DEFAULT_RCBA + IOBPS) & 1) + while (RCBA8(IOBPS) & 1) ; // implement timeout? } static u32 read_iobp(u32 address) { + volatile u32 tmp; u32 ret; - write32(DEFAULT_RCBA + IOBPIRI, address); - write16(DEFAULT_RCBA + IOBPS, (read16(DEFAULT_RCBA + IOBPS) - & 0x1ff) | 0x600); + RCBA32(IOBPIRI) = address; + RCBA16(IOBPS) = (RCBA16(IOBPS) & 0x1ff) | 0x600; wait_iobp(); - ret = read32(DEFAULT_RCBA + IOBPD); + ret = RCBA32(IOBPD); wait_iobp(); - read8(DEFAULT_RCBA + IOBPS); // call wait_iobp() instead here? + tmp = RCBA8(IOBPS); // call wait_iobp() instead here? return ret; } static void write_iobp(u32 address, u32 val) { + volatile u32 tmp; /* this function was probably pch_iobp_update with the andvalue * being 0. So either the IOBP read can be removed or this function * and the pch_iobp_update function in ramstage could be merged */ read_iobp(address); - write16(DEFAULT_RCBA + IOBPS, (read16(DEFAULT_RCBA + IOBPS) - & 0x1ff) | 0x600); + RCBA16(IOBPS) = (RCBA16(IOBPS) & 0x1ff) | 0x600; wait_iobp(); - write32(DEFAULT_RCBA + IOBPD, val); + RCBA32(IOBPD) = val; wait_iobp(); - write16(DEFAULT_RCBA + IOBPS, - (read16(DEFAULT_RCBA + IOBPS) & 0x1ff) | 0x600); - read8(DEFAULT_RCBA + IOBPS); // call wait_iobp() instead here? + RCBA16(IOBPS) = (RCBA16(IOBPS) & 0x1ff) | 0x600; + + tmp = RCBA8(IOBPS); // call wait_iobp() instead here? } static void @@ -92,134 +93,134 @@ init_dmi (void) DMIBAR32(0x090c) &= 0xfe1fffff; DMIBAR32(0x092c) &= 0xfe1fffff; - read32 (DEFAULT_DMIBAR + 0x0904); // !!! = 0x7a1842ec - write32 (DEFAULT_DMIBAR + 0x0904, 0x7a1842ec); - read32 (DEFAULT_DMIBAR + 0x090c); // !!! = 0x00000208 - write32 (DEFAULT_DMIBAR + 0x090c, 0x00000128); - read32 (DEFAULT_DMIBAR + 0x0924); // !!! = 0x7a1842ec - write32 (DEFAULT_DMIBAR + 0x0924, 0x7a1842ec); - read32 (DEFAULT_DMIBAR + 0x092c); // !!! = 0x00000208 - write32 (DEFAULT_DMIBAR + 0x092c, 0x00000128); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x46139008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x46139008); - read32 (DEFAULT_DMIBAR + 0x0c04); // !!! = 0x2e680008 - write32 (DEFAULT_DMIBAR + 0x0c04, 0x2e680008); - read32 (DEFAULT_DMIBAR + 0x0904); // !!! = 0x7a1842ec - write32 (DEFAULT_DMIBAR + 0x0904, 0x3a1842ec); - read32 (DEFAULT_DMIBAR + 0x0924); // !!! = 0x7a1842ec - write32 (DEFAULT_DMIBAR + 0x0924, 0x3a1842ec); - read32 (DEFAULT_DMIBAR + 0x0910); // !!! = 0x00006300 - write32 (DEFAULT_DMIBAR + 0x0910, 0x00004300); - read32 (DEFAULT_DMIBAR + 0x0930); // !!! = 0x00006300 - write32 (DEFAULT_DMIBAR + 0x0930, 0x00004300); - read32 (DEFAULT_DMIBAR + 0x0a00); // !!! = 0x03042010 - write32 (DEFAULT_DMIBAR + 0x0a00, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a10); // !!! = 0x03042010 - write32 (DEFAULT_DMIBAR + 0x0a10, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a20); // !!! = 0x03042010 - write32 (DEFAULT_DMIBAR + 0x0a20, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a30); // !!! = 0x03042010 - write32 (DEFAULT_DMIBAR + 0x0a30, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0c00); // !!! = 0x29700c08 - write32 (DEFAULT_DMIBAR + 0x0c00, 0x29700c08); - read32 (DEFAULT_DMIBAR + 0x0a04); // !!! = 0x0c0708f0 - write32 (DEFAULT_DMIBAR + 0x0a04, 0x0c0718f0); - read32 (DEFAULT_DMIBAR + 0x0a14); // !!! = 0x0c0708f0 - write32 (DEFAULT_DMIBAR + 0x0a14, 0x0c0718f0); - read32 (DEFAULT_DMIBAR + 0x0a24); // !!! = 0x0c0708f0 - write32 (DEFAULT_DMIBAR + 0x0a24, 0x0c0718f0); - read32 (DEFAULT_DMIBAR + 0x0a34); // !!! = 0x0c0708f0 - write32 (DEFAULT_DMIBAR + 0x0a34, 0x0c0718f0); - read32 (DEFAULT_DMIBAR + 0x0900); // !!! = 0x50000000 - write32 (DEFAULT_DMIBAR + 0x0900, 0x50000000); - read32 (DEFAULT_DMIBAR + 0x0920); // !!! = 0x50000000 - write32 (DEFAULT_DMIBAR + 0x0920, 0x50000000); - read32 (DEFAULT_DMIBAR + 0x0908); // !!! = 0x51ffffff - write32 (DEFAULT_DMIBAR + 0x0908, 0x51ffffff); - read32 (DEFAULT_DMIBAR + 0x0928); // !!! = 0x51ffffff - write32 (DEFAULT_DMIBAR + 0x0928, 0x51ffffff); - read32 (DEFAULT_DMIBAR + 0x0a00); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a00, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a10); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a10, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a20); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a20, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a30); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a30, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x46139008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x46139008); - read32 (DEFAULT_DMIBAR + 0x0904); // !!! = 0x3a1842ec - write32 (DEFAULT_DMIBAR + 0x0904, 0x3a1846ec); - read32 (DEFAULT_DMIBAR + 0x0924); // !!! = 0x3a1842ec - write32 (DEFAULT_DMIBAR + 0x0924, 0x3a1846ec); - read32 (DEFAULT_DMIBAR + 0x0a00); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a00, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a10); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a10, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a20); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a20, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0a30); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a30, 0x03042018); - read32 (DEFAULT_DMIBAR + 0x0908); // !!! = 0x51ffffff - write32 (DEFAULT_DMIBAR + 0x0908, 0x51ffffff); - read32 (DEFAULT_DMIBAR + 0x0928); // !!! = 0x51ffffff - write32 (DEFAULT_DMIBAR + 0x0928, 0x51ffffff); - read32 (DEFAULT_DMIBAR + 0x0c00); // !!! = 0x29700c08 - write32 (DEFAULT_DMIBAR + 0x0c00, 0x29700c08); - read32 (DEFAULT_DMIBAR + 0x0c0c); // !!! = 0x16063400 - write32 (DEFAULT_DMIBAR + 0x0c0c, 0x00063400); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x46339008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x46139008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x46339008); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x46339008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x45339008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x46339008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x45339008); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x45339008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x453b9008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x45339008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x453b9008); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x453b9008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x45bb9008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x453b9008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x45bb9008); - read32 (DEFAULT_DMIBAR + 0x0700); // !!! = 0x45bb9008 - write32 (DEFAULT_DMIBAR + 0x0700, 0x45fb9008); - read32 (DEFAULT_DMIBAR + 0x0720); // !!! = 0x45bb9008 - write32 (DEFAULT_DMIBAR + 0x0720, 0x45fb9008); - read32 (DEFAULT_DMIBAR + 0x0914); // !!! = 0x9021a080 - write32 (DEFAULT_DMIBAR + 0x0914, 0x9021a280); - read32 (DEFAULT_DMIBAR + 0x0934); // !!! = 0x9021a080 - write32 (DEFAULT_DMIBAR + 0x0934, 0x9021a280); - read32 (DEFAULT_DMIBAR + 0x0914); // !!! = 0x9021a280 - write32 (DEFAULT_DMIBAR + 0x0914, 0x9821a280); - read32 (DEFAULT_DMIBAR + 0x0934); // !!! = 0x9021a280 - write32 (DEFAULT_DMIBAR + 0x0934, 0x9821a280); - read32 (DEFAULT_DMIBAR + 0x0a00); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a00, 0x03242018); - read32 (DEFAULT_DMIBAR + 0x0a10); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a10, 0x03242018); - read32 (DEFAULT_DMIBAR + 0x0a20); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a20, 0x03242018); - read32 (DEFAULT_DMIBAR + 0x0a30); // !!! = 0x03042018 - write32 (DEFAULT_DMIBAR + 0x0a30, 0x03242018); - read32 (DEFAULT_DMIBAR + 0x0258); // !!! = 0x40000600 - write32 (DEFAULT_DMIBAR + 0x0258, 0x60000600); - read32 (DEFAULT_DMIBAR + 0x0904); // !!! = 0x3a1846ec - write32 (DEFAULT_DMIBAR + 0x0904, 0x2a1846ec); - read32 (DEFAULT_DMIBAR + 0x0914); // !!! = 0x9821a280 - write32 (DEFAULT_DMIBAR + 0x0914, 0x98200280); - read32 (DEFAULT_DMIBAR + 0x0924); // !!! = 0x3a1846ec - write32 (DEFAULT_DMIBAR + 0x0924, 0x2a1846ec); - read32 (DEFAULT_DMIBAR + 0x0934); // !!! = 0x9821a280 - write32 (DEFAULT_DMIBAR + 0x0934, 0x98200280); - read32 (DEFAULT_DMIBAR + 0x022c); // !!! = 0x00c26460 - write32 (DEFAULT_DMIBAR + 0x022c, 0x00c2403c); + tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904) = 0x7a1842ec; + tmp = DMIBAR32(0x090c); // !!! = 0x00000208 + DMIBAR32(0x090c) = 0x00000128; + tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924) = 0x7a1842ec; + tmp = DMIBAR32(0x092c); // !!! = 0x00000208 + DMIBAR32(0x092c) = 0x00000128; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46139008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46139008; + tmp = DMIBAR32(0x0c04); // !!! = 0x2e680008 + DMIBAR32(0x0c04) = 0x2e680008; + tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904) = 0x3a1842ec; + tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924) = 0x3a1842ec; + tmp = DMIBAR32(0x0910); // !!! = 0x00006300 + DMIBAR32(0x0910) = 0x00004300; + tmp = DMIBAR32(0x0930); // !!! = 0x00006300 + DMIBAR32(0x0930) = 0x00004300; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042010 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042010 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042010 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042010 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00) = 0x29700c08; + tmp = DMIBAR32(0x0a04); // !!! = 0x0c0708f0 + DMIBAR32(0x0a04) = 0x0c0718f0; + tmp = DMIBAR32(0x0a14); // !!! = 0x0c0708f0 + DMIBAR32(0x0a14) = 0x0c0718f0; + tmp = DMIBAR32(0x0a24); // !!! = 0x0c0708f0 + DMIBAR32(0x0a24) = 0x0c0718f0; + tmp = DMIBAR32(0x0a34); // !!! = 0x0c0708f0 + DMIBAR32(0x0a34) = 0x0c0718f0; + tmp = DMIBAR32(0x0900); // !!! = 0x50000000 + DMIBAR32(0x0900) = 0x50000000; + tmp = DMIBAR32(0x0920); // !!! = 0x50000000 + DMIBAR32(0x0920) = 0x50000000; + tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908) = 0x51ffffff; + tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928) = 0x51ffffff; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46139008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46139008; + tmp = DMIBAR32(0x0904); // !!! = 0x3a1842ec + DMIBAR32(0x0904) = 0x3a1846ec; + tmp = DMIBAR32(0x0924); // !!! = 0x3a1842ec + DMIBAR32(0x0924) = 0x3a1846ec; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908) = 0x51ffffff; + tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928) = 0x51ffffff; + tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00) = 0x29700c08; + tmp = DMIBAR32(0x0c0c); // !!! = 0x16063400 + DMIBAR32(0x0c0c) = 0x00063400; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46339008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46339008; + tmp = DMIBAR32(0x0700); // !!! = 0x46339008 + DMIBAR32(0x0700) = 0x45339008; + tmp = DMIBAR32(0x0720); // !!! = 0x46339008 + DMIBAR32(0x0720) = 0x45339008; + tmp = DMIBAR32(0x0700); // !!! = 0x45339008 + DMIBAR32(0x0700) = 0x453b9008; + tmp = DMIBAR32(0x0720); // !!! = 0x45339008 + DMIBAR32(0x0720) = 0x453b9008; + tmp = DMIBAR32(0x0700); // !!! = 0x453b9008 + DMIBAR32(0x0700) = 0x45bb9008; + tmp = DMIBAR32(0x0720); // !!! = 0x453b9008 + DMIBAR32(0x0720) = 0x45bb9008; + tmp = DMIBAR32(0x0700); // !!! = 0x45bb9008 + DMIBAR32(0x0700) = 0x45fb9008; + tmp = DMIBAR32(0x0720); // !!! = 0x45bb9008 + DMIBAR32(0x0720) = 0x45fb9008; + tmp = DMIBAR32(0x0914); // !!! = 0x9021a080 + DMIBAR32(0x0914) = 0x9021a280; + tmp = DMIBAR32(0x0934); // !!! = 0x9021a080 + DMIBAR32(0x0934) = 0x9021a280; + tmp = DMIBAR32(0x0914); // !!! = 0x9021a280 + DMIBAR32(0x0914) = 0x9821a280; + tmp = DMIBAR32(0x0934); // !!! = 0x9021a280 + DMIBAR32(0x0934) = 0x9821a280; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03242018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03242018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03242018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03242018; + tmp = DMIBAR32(0x0258); // !!! = 0x40000600 + DMIBAR32(0x0258) = 0x60000600; + tmp = DMIBAR32(0x0904); // !!! = 0x3a1846ec + DMIBAR32(0x0904) = 0x2a1846ec; + tmp = DMIBAR32(0x0914); // !!! = 0x9821a280 + DMIBAR32(0x0914) = 0x98200280; + tmp = DMIBAR32(0x0924); // !!! = 0x3a1846ec + DMIBAR32(0x0924) = 0x2a1846ec; + tmp = DMIBAR32(0x0934); // !!! = 0x9821a280 + DMIBAR32(0x0934) = 0x98200280; + tmp = DMIBAR32(0x022c); // !!! = 0x00c26460 + DMIBAR32(0x022c) = 0x00c2403c; /* Link Capabilities Register */ RCBA32(0x21a4) = (RCBA32(0x21a4) & ~0x3fc00) | @@ -269,13 +270,13 @@ init_dmi (void) /* Set Extended VC Count (EVCC) to 1 as Channel 1 is active. */ DMIBAR8(DMIPVCCAP1) |= 1; - read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x01200654 - write32 (DEFAULT_RCBA + 0x0050, 0x01200654); - read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x01200654 - write32 (DEFAULT_RCBA + 0x0050, 0x012a0654); - read32 (DEFAULT_RCBA + 0x0050); // !!! = 0x012a0654 - read8 (DEFAULT_RCBA + 0x1114); // !!! = 0x00 - write8 (DEFAULT_RCBA + 0x1114, 0x05); + tmp = RCBA32(0x0050); // !!! = 0x01200654 + RCBA32(0x0050) = 0x01200654; + tmp = RCBA32(0x0050); // !!! = 0x01200654 + RCBA32(0x0050) = 0x012a0654; + tmp = RCBA32(0x0050); // !!! = 0x012a0654 + tmp = RCBA8(0x1114); // !!! = 0x00 + RCBA8(0x1114) = 0x05; /* * Virtual Channel resources must match settings in DMIBAR! @@ -351,24 +352,25 @@ init_dmi (void) void early_pch_init_native (void) { + volatile u32 tmp; pci_write_config8 (SOUTHBRIDGE, 0xa6, pci_read_config8 (SOUTHBRIDGE, 0xa6) | 2); - write32 (DEFAULT_RCBA + 0x2088, 0x00109000); - read32 (DEFAULT_RCBA + 0x20ac); // !!! = 0x00000000 - write32 (DEFAULT_RCBA + 0x20ac, 0x40000000); - write32 (DEFAULT_RCBA + 0x100c, 0x01110000); - write8 (DEFAULT_RCBA + 0x2340, 0x1b); - read32 (DEFAULT_RCBA + 0x2314); // !!! = 0x0a080000 - write32 (DEFAULT_RCBA + 0x2314, 0x0a280000); - read32 (DEFAULT_RCBA + 0x2310); // !!! = 0xc809605b - write32 (DEFAULT_RCBA + 0x2310, 0xa809605b); - write32 (DEFAULT_RCBA + 0x2324, 0x00854c74); - read8 (DEFAULT_RCBA + 0x0400); // !!! = 0x00 - read32 (DEFAULT_RCBA + 0x2310); // !!! = 0xa809605b - write32 (DEFAULT_RCBA + 0x2310, 0xa809605b); - read32 (DEFAULT_RCBA + 0x2310); // !!! = 0xa809605b - write32 (DEFAULT_RCBA + 0x2310, 0xa809605b); + RCBA32(0x2088) = 0x00109000; + tmp = RCBA32(0x20ac); // !!! = 0x00000000 + RCBA32(0x20ac) = 0x40000000; + RCBA32(0x100c) = 0x01110000; + RCBA8(0x2340) = 0x1b; + tmp = RCBA32(0x2314); // !!! = 0x0a080000 + RCBA32(0x2314) = 0x0a280000; + tmp = RCBA32(0x2310); // !!! = 0xc809605b + RCBA32(0x2310) = 0xa809605b; + RCBA32(0x2324) = 0x00854c74; + tmp = RCBA8(0x0400); // !!! = 0x00 + tmp = RCBA32(0x2310); // !!! = 0xa809605b + RCBA32(0x2310) = 0xa809605b; + tmp = RCBA32(0x2310); // !!! = 0xa809605b + RCBA32(0x2310) = 0xa809605b; write_iobp(0xea007f62, 0x00590133); write_iobp(0xec007f62, 0x00590133); From 6aca7e6bec07c583de18752aa7a8639b64e9bd93 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 26 Mar 2019 18:22:36 +0100 Subject: [PATCH 338/588] nb/intel/sandybridge: Move DMI init code Move the DMI initialization code to northbridge folder. Leave southbridge specific settings in bd82x6x folder and call it from northbridge code. Tested on Lenovo T520 (Intel Sandy Bridge). Still boots to OS, no errors visible in dmesg. Change-Id: Ib0b47391f3309f9ab0c3a3a8d525f38f8cca73c0 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32073 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- .../intel/sandybridge/Makefile.inc | 1 + src/northbridge/intel/sandybridge/early_dmi.c | 226 ++++++++++++++++++ src/northbridge/intel/sandybridge/raminit.c | 1 + .../intel/sandybridge/sandybridge.h | 1 + src/southbridge/intel/bd82x6x/early_pch.c | 209 +--------------- src/southbridge/intel/bd82x6x/pch.h | 2 + 6 files changed, 236 insertions(+), 204 deletions(-) create mode 100644 src/northbridge/intel/sandybridge/early_dmi.c diff --git a/src/northbridge/intel/sandybridge/Makefile.inc b/src/northbridge/intel/sandybridge/Makefile.inc index cc4ddaf8611..ba55466026b 100644 --- a/src/northbridge/intel/sandybridge/Makefile.inc +++ b/src/northbridge/intel/sandybridge/Makefile.inc @@ -29,6 +29,7 @@ romstage-y += common.c smm-$(CONFIG_HAVE_SMI_HANDLER) += common.c ifeq ($(CONFIG_USE_NATIVE_RAMINIT),y) +romstage-y += early_dmi.c romstage-y += raminit.c romstage-y += raminit_common.c romstage-y += raminit_sandy.c diff --git a/src/northbridge/intel/sandybridge/early_dmi.c b/src/northbridge/intel/sandybridge/early_dmi.c new file mode 100644 index 00000000000..db49040dc18 --- /dev/null +++ b/src/northbridge/intel/sandybridge/early_dmi.c @@ -0,0 +1,226 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Vladimir Serbinenko + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +void early_init_dmi(void) +{ + volatile u32 tmp; + int i; + + DMIBAR32(0x0914) |= 0x80000000; + DMIBAR32(0x0934) |= 0x80000000; + + for (i = 0; i < 4; i++) { + DMIBAR32(0x0a00 + (i << 4)) &= 0xf3ffffff; + DMIBAR32(0x0a04 + (i << 4)) |= 0x800; + } + DMIBAR32(0x0c30) = (DMIBAR32(0x0c30) & 0xfffffff) | 0x40000000; + + for (i = 0; i < 2; i++) { + DMIBAR32(0x0904 + (i << 5)) &= 0xfe3fffff; + DMIBAR32(0x090c + (i << 5)) &= 0xfff1ffff; + } + + DMIBAR32(0x090c) &= 0xfe1fffff; + DMIBAR32(0x092c) &= 0xfe1fffff; + + tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904) = 0x7a1842ec; + tmp = DMIBAR32(0x090c); // !!! = 0x00000208 + DMIBAR32(0x090c) = 0x00000128; + tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924) = 0x7a1842ec; + tmp = DMIBAR32(0x092c); // !!! = 0x00000208 + DMIBAR32(0x092c) = 0x00000128; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46139008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46139008; + tmp = DMIBAR32(0x0c04); // !!! = 0x2e680008 + DMIBAR32(0x0c04) = 0x2e680008; + tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904) = 0x3a1842ec; + tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924) = 0x3a1842ec; + tmp = DMIBAR32(0x0910); // !!! = 0x00006300 + DMIBAR32(0x0910) = 0x00004300; + tmp = DMIBAR32(0x0930); // !!! = 0x00006300 + DMIBAR32(0x0930) = 0x00004300; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042010 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042010 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042010 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042010 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00) = 0x29700c08; + tmp = DMIBAR32(0x0a04); // !!! = 0x0c0708f0 + DMIBAR32(0x0a04) = 0x0c0718f0; + tmp = DMIBAR32(0x0a14); // !!! = 0x0c0708f0 + DMIBAR32(0x0a14) = 0x0c0718f0; + tmp = DMIBAR32(0x0a24); // !!! = 0x0c0708f0 + DMIBAR32(0x0a24) = 0x0c0718f0; + tmp = DMIBAR32(0x0a34); // !!! = 0x0c0708f0 + DMIBAR32(0x0a34) = 0x0c0718f0; + tmp = DMIBAR32(0x0900); // !!! = 0x50000000 + DMIBAR32(0x0900) = 0x50000000; + tmp = DMIBAR32(0x0920); // !!! = 0x50000000 + DMIBAR32(0x0920) = 0x50000000; + tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908) = 0x51ffffff; + tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928) = 0x51ffffff; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46139008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46139008; + tmp = DMIBAR32(0x0904); // !!! = 0x3a1842ec + DMIBAR32(0x0904) = 0x3a1846ec; + tmp = DMIBAR32(0x0924); // !!! = 0x3a1842ec + DMIBAR32(0x0924) = 0x3a1846ec; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03042018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03042018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03042018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03042018; + tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908) = 0x51ffffff; + tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928) = 0x51ffffff; + tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00) = 0x29700c08; + tmp = DMIBAR32(0x0c0c); // !!! = 0x16063400 + DMIBAR32(0x0c0c) = 0x00063400; + tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700) = 0x46339008; + tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720) = 0x46339008; + tmp = DMIBAR32(0x0700); // !!! = 0x46339008 + DMIBAR32(0x0700) = 0x45339008; + tmp = DMIBAR32(0x0720); // !!! = 0x46339008 + DMIBAR32(0x0720) = 0x45339008; + tmp = DMIBAR32(0x0700); // !!! = 0x45339008 + DMIBAR32(0x0700) = 0x453b9008; + tmp = DMIBAR32(0x0720); // !!! = 0x45339008 + DMIBAR32(0x0720) = 0x453b9008; + tmp = DMIBAR32(0x0700); // !!! = 0x453b9008 + DMIBAR32(0x0700) = 0x45bb9008; + tmp = DMIBAR32(0x0720); // !!! = 0x453b9008 + DMIBAR32(0x0720) = 0x45bb9008; + tmp = DMIBAR32(0x0700); // !!! = 0x45bb9008 + DMIBAR32(0x0700) = 0x45fb9008; + tmp = DMIBAR32(0x0720); // !!! = 0x45bb9008 + DMIBAR32(0x0720) = 0x45fb9008; + tmp = DMIBAR32(0x0914); // !!! = 0x9021a080 + DMIBAR32(0x0914) = 0x9021a280; + tmp = DMIBAR32(0x0934); // !!! = 0x9021a080 + DMIBAR32(0x0934) = 0x9021a280; + tmp = DMIBAR32(0x0914); // !!! = 0x9021a280 + DMIBAR32(0x0914) = 0x9821a280; + tmp = DMIBAR32(0x0934); // !!! = 0x9021a280 + DMIBAR32(0x0934) = 0x9821a280; + tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00) = 0x03242018; + tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10) = 0x03242018; + tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20) = 0x03242018; + tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30) = 0x03242018; + tmp = DMIBAR32(0x0258); // !!! = 0x40000600 + DMIBAR32(0x0258) = 0x60000600; + tmp = DMIBAR32(0x0904); // !!! = 0x3a1846ec + DMIBAR32(0x0904) = 0x2a1846ec; + tmp = DMIBAR32(0x0914); // !!! = 0x9821a280 + DMIBAR32(0x0914) = 0x98200280; + tmp = DMIBAR32(0x0924); // !!! = 0x3a1846ec + DMIBAR32(0x0924) = 0x2a1846ec; + tmp = DMIBAR32(0x0934); // !!! = 0x9821a280 + DMIBAR32(0x0934) = 0x98200280; + tmp = DMIBAR32(0x022c); // !!! = 0x00c26460 + DMIBAR32(0x022c) = 0x00c2403c; + + early_pch_init_native_dmi_pre(); + + /* Write once settings. */ + DMIBAR32(DMILCAP) = (DMIBAR32(DMILCAP) & ~0x3f00f) | + (2 << 0) | // 5GT/s + (2 << 12) | // L0s 128 ns to less than 256 ns + (2 << 15); // L1 2 us to less than 4 us + + DMIBAR8(DMILCTL) |= 0x20; // Retrain link + while (DMIBAR16(DMILSTS) & TXTRN) + ; + + DMIBAR8(DMILCTL) |= 0x20; // Retrain link + while (DMIBAR16(DMILSTS) & TXTRN) + ; + + const u8 w = (DMIBAR16(DMILSTS) >> 4) & 0x1f; + const u16 t = (DMIBAR16(DMILSTS) & 0xf) * 2500; + + printk(BIOS_DEBUG, "DMI: Running at X%x @ %dMT/s\n", w, t); + /* + * Virtual Channel resources must match settings in RCBA! + * + * Channel Vp and Vm are documented in + * "Desktop 4th Generation Intel Core Processor Family, Desktop Intel + * Pentium Processor Family, and Desktop Intel Celeron Processor Family + * Vol. 2" + */ + + /* Channel 0: Enable, Set ID to 0, map TC0 and TC3 and TC4 to VC0. */ + DMIBAR32(DMIVC0RCTL) = (1 << 31) | (0 << 24) | (0x0c << 1) | 1; + /* Channel 1: Enable, Set ID to 1, map TC1 and TC5 to VC1. */ + DMIBAR32(DMIVC1RCTL) = (1 << 31) | (1 << 24) | (0x11 << 1); + /* Channel p: Enable, Set ID to 2, map TC2 and TC6 to VCp */ + DMIBAR32(DMIVCPRCTL) = (1 << 31) | (2 << 24) | (0x22 << 1); + /* Channel m: Enable, Set ID to 0, map TC7 to VCm */ + DMIBAR32(DMIVCMRCTL) = (1 << 31) | (7 << 24) | (0x40 << 1); + + /* Set Extended VC Count (EVCC) to 1 as Channel 1 is active. */ + DMIBAR8(DMIPVCCAP1) |= 1; + + early_pch_init_native_dmi_post(); + + /* + * BIOS Requirement: Check if DMI VC Negotiation was successful. + * Wait for virtual channels negotiation pending. + */ + while (DMIBAR16(DMIVC0RSTS) & VC0NP) + ; + while (DMIBAR16(DMIVC1RSTS) & VC1NP) + ; + while (DMIBAR16(DMIVCPRSTS) & VCPNP) + ; + while (DMIBAR16(DMIVCMRSTS) & VCMNP) + ; +} diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index 2ebeaf0dca5..f67d61f9739 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -315,6 +315,7 @@ static void init_dram_ddr3(int min_tck, int s3resume) } early_pch_init_native(); + early_init_dmi(); early_thermal_init(); /* try to find timings in MRC cache */ diff --git a/src/northbridge/intel/sandybridge/sandybridge.h b/src/northbridge/intel/sandybridge/sandybridge.h index 77f2ead74ee..77165f69316 100644 --- a/src/northbridge/intel/sandybridge/sandybridge.h +++ b/src/northbridge/intel/sandybridge/sandybridge.h @@ -220,6 +220,7 @@ void sandybridge_early_initialization(void); void sandybridge_init_iommu(void); void sandybridge_late_initialization(void); void northbridge_romstage_finalize(int s3resume); +void early_init_dmi(void); #endif /* !__SMM__ */ diff --git a/src/southbridge/intel/bd82x6x/early_pch.c b/src/southbridge/intel/bd82x6x/early_pch.c index 76f1447e8ad..e74c3043f04 100644 --- a/src/southbridge/intel/bd82x6x/early_pch.c +++ b/src/southbridge/intel/bd82x6x/early_pch.c @@ -70,158 +70,8 @@ write_iobp(u32 address, u32 val) tmp = RCBA8(IOBPS); // call wait_iobp() instead here? } -static void -init_dmi (void) +void early_pch_init_native_dmi_pre(void) { - volatile u32 tmp; - int i; - - DMIBAR32(0x0914) |= 0x80000000; - DMIBAR32(0x0934) |= 0x80000000; - - for (i = 0; i < 4; i++) { - DMIBAR32(0x0a00 + (i << 4)) &= 0xf3ffffff; - DMIBAR32(0x0a04 + (i << 4)) |= 0x800; - } - DMIBAR32(0x0c30) = (DMIBAR32(0x0c30) & 0xfffffff) | 0x40000000; - - for (i = 0; i < 2; i++) { - DMIBAR32(0x0904 + (i << 5)) &= 0xfe3fffff; - DMIBAR32(0x090c + (i << 5)) &= 0xfff1ffff; - } - - DMIBAR32(0x090c) &= 0xfe1fffff; - DMIBAR32(0x092c) &= 0xfe1fffff; - - tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec - DMIBAR32(0x0904) = 0x7a1842ec; - tmp = DMIBAR32(0x090c); // !!! = 0x00000208 - DMIBAR32(0x090c) = 0x00000128; - tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec - DMIBAR32(0x0924) = 0x7a1842ec; - tmp = DMIBAR32(0x092c); // !!! = 0x00000208 - DMIBAR32(0x092c) = 0x00000128; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 - DMIBAR32(0x0700) = 0x46139008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 - DMIBAR32(0x0720) = 0x46139008; - tmp = DMIBAR32(0x0c04); // !!! = 0x2e680008 - DMIBAR32(0x0c04) = 0x2e680008; - tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec - DMIBAR32(0x0904) = 0x3a1842ec; - tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec - DMIBAR32(0x0924) = 0x3a1842ec; - tmp = DMIBAR32(0x0910); // !!! = 0x00006300 - DMIBAR32(0x0910) = 0x00004300; - tmp = DMIBAR32(0x0930); // !!! = 0x00006300 - DMIBAR32(0x0930) = 0x00004300; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042010 - DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042010 - DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042010 - DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042010 - DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 - DMIBAR32(0x0c00) = 0x29700c08; - tmp = DMIBAR32(0x0a04); // !!! = 0x0c0708f0 - DMIBAR32(0x0a04) = 0x0c0718f0; - tmp = DMIBAR32(0x0a14); // !!! = 0x0c0708f0 - DMIBAR32(0x0a14) = 0x0c0718f0; - tmp = DMIBAR32(0x0a24); // !!! = 0x0c0708f0 - DMIBAR32(0x0a24) = 0x0c0718f0; - tmp = DMIBAR32(0x0a34); // !!! = 0x0c0708f0 - DMIBAR32(0x0a34) = 0x0c0718f0; - tmp = DMIBAR32(0x0900); // !!! = 0x50000000 - DMIBAR32(0x0900) = 0x50000000; - tmp = DMIBAR32(0x0920); // !!! = 0x50000000 - DMIBAR32(0x0920) = 0x50000000; - tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff - DMIBAR32(0x0908) = 0x51ffffff; - tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff - DMIBAR32(0x0928) = 0x51ffffff; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 - DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 - DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 - DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 - DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 - DMIBAR32(0x0700) = 0x46139008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 - DMIBAR32(0x0720) = 0x46139008; - tmp = DMIBAR32(0x0904); // !!! = 0x3a1842ec - DMIBAR32(0x0904) = 0x3a1846ec; - tmp = DMIBAR32(0x0924); // !!! = 0x3a1842ec - DMIBAR32(0x0924) = 0x3a1846ec; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 - DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 - DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 - DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 - DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff - DMIBAR32(0x0908) = 0x51ffffff; - tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff - DMIBAR32(0x0928) = 0x51ffffff; - tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 - DMIBAR32(0x0c00) = 0x29700c08; - tmp = DMIBAR32(0x0c0c); // !!! = 0x16063400 - DMIBAR32(0x0c0c) = 0x00063400; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 - DMIBAR32(0x0700) = 0x46339008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 - DMIBAR32(0x0720) = 0x46339008; - tmp = DMIBAR32(0x0700); // !!! = 0x46339008 - DMIBAR32(0x0700) = 0x45339008; - tmp = DMIBAR32(0x0720); // !!! = 0x46339008 - DMIBAR32(0x0720) = 0x45339008; - tmp = DMIBAR32(0x0700); // !!! = 0x45339008 - DMIBAR32(0x0700) = 0x453b9008; - tmp = DMIBAR32(0x0720); // !!! = 0x45339008 - DMIBAR32(0x0720) = 0x453b9008; - tmp = DMIBAR32(0x0700); // !!! = 0x453b9008 - DMIBAR32(0x0700) = 0x45bb9008; - tmp = DMIBAR32(0x0720); // !!! = 0x453b9008 - DMIBAR32(0x0720) = 0x45bb9008; - tmp = DMIBAR32(0x0700); // !!! = 0x45bb9008 - DMIBAR32(0x0700) = 0x45fb9008; - tmp = DMIBAR32(0x0720); // !!! = 0x45bb9008 - DMIBAR32(0x0720) = 0x45fb9008; - tmp = DMIBAR32(0x0914); // !!! = 0x9021a080 - DMIBAR32(0x0914) = 0x9021a280; - tmp = DMIBAR32(0x0934); // !!! = 0x9021a080 - DMIBAR32(0x0934) = 0x9021a280; - tmp = DMIBAR32(0x0914); // !!! = 0x9021a280 - DMIBAR32(0x0914) = 0x9821a280; - tmp = DMIBAR32(0x0934); // !!! = 0x9021a280 - DMIBAR32(0x0934) = 0x9821a280; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 - DMIBAR32(0x0a00) = 0x03242018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 - DMIBAR32(0x0a10) = 0x03242018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 - DMIBAR32(0x0a20) = 0x03242018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 - DMIBAR32(0x0a30) = 0x03242018; - tmp = DMIBAR32(0x0258); // !!! = 0x40000600 - DMIBAR32(0x0258) = 0x60000600; - tmp = DMIBAR32(0x0904); // !!! = 0x3a1846ec - DMIBAR32(0x0904) = 0x2a1846ec; - tmp = DMIBAR32(0x0914); // !!! = 0x9821a280 - DMIBAR32(0x0914) = 0x98200280; - tmp = DMIBAR32(0x0924); // !!! = 0x3a1846ec - DMIBAR32(0x0924) = 0x2a1846ec; - tmp = DMIBAR32(0x0934); // !!! = 0x9821a280 - DMIBAR32(0x0934) = 0x98200280; - tmp = DMIBAR32(0x022c); // !!! = 0x00c26460 - DMIBAR32(0x022c) = 0x00c2403c; - /* Link Capabilities Register */ RCBA32(0x21a4) = (RCBA32(0x21a4) & ~0x3fc00) | (3 << 10) | // L0s and L1 entry supported @@ -230,45 +80,11 @@ init_dmi (void) RCBA32(0x2340) = (RCBA32(0x2340) & ~0xff0000) | (0x3a << 16); RCBA8(0x21b0) = (RCBA8(0x21b0) & ~0xf) | 2; +} - /* Write once settings. */ - DMIBAR32(DMILCAP) = (DMIBAR32(DMILCAP) & ~0x3f00f) | - (2 << 0) | // 5GT/s - (2 << 12) | // L0s 128 ns to less than 256 ns - (2 << 15); // L1 2 us to less than 4 us - - DMIBAR8(DMILCTL) |= 0x20; // Retrain link - while (DMIBAR16(DMILSTS) & TXTRN) - ; - - DMIBAR8(DMILCTL) |= 0x20; // Retrain link - while (DMIBAR16(DMILSTS) & TXTRN) - ; - - const u8 w = (DMIBAR16(DMILSTS) >> 4) & 0x1f; - const u16 t = (DMIBAR16(DMILSTS) & 0xf) * 2500; - - printk(BIOS_DEBUG, "DMI: Running at X%x @ %dMT/s\n", w, t); - /* - * Virtual Channel resources must match settings in RCBA! - * - * Channel Vp and Vm are documented in - * "Desktop 4th Generation Intel Core Processor Family, Desktop Intel - * Pentium Processor Family, and Desktop Intel Celeron Processor Family - * Vol. 2" - */ - - /* Channel 0: Enable, Set ID to 0, map TC0 and TC3 and TC4 to VC0. */ - DMIBAR32(DMIVC0RCTL) = (1 << 31) | (0 << 24) | (0x0c << 1) | 1; - /* Channel 1: Enable, Set ID to 1, map TC1 and TC5 to VC1. */ - DMIBAR32(DMIVC1RCTL) = (1 << 31) | (1 << 24) | (0x11 << 1); - /* Channel p: Enable, Set ID to 2, map TC2 and TC6 to VCp */ - DMIBAR32(DMIVCPRCTL) = (1 << 31) | (2 << 24) | (0x22 << 1); - /* Channel m: Enable, Set ID to 0, map TC7 to VCm */ - DMIBAR32(DMIVCMRCTL) = (1 << 31) | (7 << 24) | (0x40 << 1); - - /* Set Extended VC Count (EVCC) to 1 as Channel 1 is active. */ - DMIBAR8(DMIPVCCAP1) |= 1; +void early_pch_init_native_dmi_post(void) +{ + volatile u32 tmp; tmp = RCBA32(0x0050); // !!! = 0x01200654 RCBA32(0x0050) = 0x01200654; @@ -334,19 +150,6 @@ init_dmi (void) ; while (RCBA16(0x2046) & VCNEGPND) ; - - /* - * BIOS Requirement: Check if DMI VC Negotiation was successful. - * Wait for virtual channels negotiation pending. - */ - while (DMIBAR16(DMIVC0RSTS) & VC0NP) - ; - while (DMIBAR16(DMIVC1RSTS) & VC1NP) - ; - while (DMIBAR16(DMIVCPRSTS) & VCPNP) - ; - while (DMIBAR16(DMIVCMRSTS) & VCMNP) - ; } void @@ -433,8 +236,6 @@ early_pch_init_native (void) write_iobp(0xec0007b2, 0x04514b5e); write_iobp(0xec00078c, 0x40000200); write_iobp(0xec000780, 0x02000020); - - init_dmi(); } static void pch_enable_bars(void) diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h index fb8238ad4f9..faa6822bf22 100644 --- a/src/southbridge/intel/bd82x6x/pch.h +++ b/src/southbridge/intel/bd82x6x/pch.h @@ -77,6 +77,8 @@ void southbridge_rcba_config(void); void mainboard_rcba_config(void); void early_pch_init_native(void); void early_pch_init(void); +void early_pch_init_native_dmi_pre(void); +void early_pch_init_native_dmi_post(void); struct southbridge_usb_port { From 997207d9a663a74a5b1ed4499fd7b1ce83494d78 Mon Sep 17 00:00:00 2001 From: Alan Green Date: Thu, 16 May 2019 08:52:12 +1000 Subject: [PATCH 339/588] src/include/assert.h: add noreturn attribute to dead_code() Clang does not recognize dead_code() as termination of execution. It gives this message: error: control reaches end of non-void function [-Werror,-Wreturn-type] This change adds an __attribute__((noreturn)) to ensure that clang recognises that this function will terminate execution. This change is more general solution to the problem that was addressed in the specific at https://review.coreboot.org/c/coreboot/+/32798 Signed-off-by: Alan Green Change-Id: I5ba7189559aa01545d5bbe893bced400a3aaabbb Reviewed-on: https://review.coreboot.org/c/coreboot/+/32833 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/include/assert.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/include/assert.h b/src/include/assert.h index 4575a29e447..e0db0bc05c8 100644 --- a/src/include/assert.h +++ b/src/include/assert.h @@ -56,7 +56,8 @@ * bootmode.c:42: undefined reference to `dead_code_assertion_failed_at_line_42' */ #define __dead_code(line) do { \ - extern void dead_code_assertion_failed_at_line_##line(void); \ + extern void dead_code_assertion_failed_at_line_##line(void) \ + __attribute__((noreturn)); \ dead_code_assertion_failed_at_line_##line(); \ } while (0) #define _dead_code(line) __dead_code(line) From f85f2f87465a50ff9572f4e3039c01105494f60a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 15 May 2019 19:06:58 +0200 Subject: [PATCH 340/588] soc/qualcomm/sdm845: Fix broken Kconfig This fixes the following changes, which made qualcomm Kconfig appear on all platforms: bd0b51c0be1ec2c9a5f02de3c13108c13941e2c2 7a3e46d767890f502b09771e19decc5033e27079 Use proper Kconfig logic. Change-Id: I0195fd186ac39dd4258fe0781dd6d3d1b1d1679f Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32805 Reviewed-by: Patrick Georgi Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/soc/qualcomm/common/Kconfig | 10 ++++++++++ src/soc/qualcomm/sdm845/Kconfig | 1 + 2 files changed, 11 insertions(+) diff --git a/src/soc/qualcomm/common/Kconfig b/src/soc/qualcomm/common/Kconfig index f3d12629fb2..8a1f6d62fd7 100644 --- a/src/soc/qualcomm/common/Kconfig +++ b/src/soc/qualcomm/common/Kconfig @@ -1,5 +1,15 @@ +config SOC_QUALCOMM_COMMON + bool + default n + help + Selected by platforms that use the common code. + +if SOC_QUALCOMM_COMMON + config QC_SDI_ENABLE bool default n prompt "Debug Build: enable SDI" + +endif diff --git a/src/soc/qualcomm/sdm845/Kconfig b/src/soc/qualcomm/sdm845/Kconfig index ffb95cb4cda..f6268c95bab 100644 --- a/src/soc/qualcomm/sdm845/Kconfig +++ b/src/soc/qualcomm/sdm845/Kconfig @@ -10,6 +10,7 @@ config SOC_QUALCOMM_SDM845 select GENERIC_UDELAY select HAVE_MONOTONIC_TIMER select ARM64_USE_ARCH_TIMER + select SOC_QUALCOMM_COMMON if SOC_QUALCOMM_SDM845 From 9beb52a17ca2dd574e1bfd734b9af88bf57db328 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 17 May 2019 12:06:37 -0600 Subject: [PATCH 341/588] mb/google/sarien: Set serial number in SMBIOS Set the system serial number from the VPD key "serial_number" and the mainboard serial number from the VPD key "mlb_serial_number". BUG=b:132970635 TEST=check serial number is set in SMBIOS based on VPD, and if there is no VPD key found then it is empty. Change-Id: Ia8f1486dcb1edc968b8eb1e6d989b10c05913aca Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32851 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: Furquan Shaikh --- src/mainboard/google/sarien/ramstage.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/mainboard/google/sarien/ramstage.c b/src/mainboard/google/sarien/ramstage.c index d8d1c9dbe37..1d220461cf5 100644 --- a/src/mainboard/google/sarien/ramstage.c +++ b/src/mainboard/google/sarien/ramstage.c @@ -14,6 +14,7 @@ */ #include +#include #include #include #include @@ -21,6 +22,26 @@ #include #if CONFIG(GENERATE_SMBIOS_TABLES) +#define VPD_KEY_SYSTEM_SERIAL "serial_number" +#define VPD_KEY_MAINBOARD_SERIAL "mlb_serial_number" +#define VPD_SERIAL_LEN 64 + +const char *smbios_system_serial_number(void) +{ + static char serial[VPD_SERIAL_LEN]; + if (vpd_gets(VPD_KEY_SYSTEM_SERIAL, serial, VPD_SERIAL_LEN, VPD_RO)) + return serial; + return ""; +} + +const char *smbios_mainboard_serial_number(void) +{ + static char serial[VPD_SERIAL_LEN]; + if (vpd_gets(VPD_KEY_MAINBOARD_SERIAL, serial, VPD_SERIAL_LEN, VPD_RO)) + return serial; + return ""; +} + /* mainboard silk screen shows DIMM-A and DIMM-B */ void smbios_fill_dimm_locator(const struct dimm_info *dimm, struct smbios_type17 *t) From 46340d076a8205946c841dd637db7fd4ebd31b15 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Fri, 17 May 2019 14:57:31 -0600 Subject: [PATCH 342/588] soc/intel: Fill DIMM serial number from SPD Fill the DIMM serial number field for SMBIOS from the saved SPD data that is returned by FSP. BUG=b:132970635 TEST=This was tested on sarien to ensure that SMBIOS type 17 filled the serial number from the DIMM: Handle 0x000B, DMI type 17, 40 bytes Memory Device Locator: DIMM-A Serial Number: 41164beb Change-Id: I85438bd1d581095ea3482dcf077a7f3389f1cd47 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32853 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/soc/intel/apollolake/meminit_util_apl.c | 1 + src/soc/intel/apollolake/meminit_util_glk.c | 1 + src/soc/intel/cannonlake/romstage/romstage.c | 1 + src/soc/intel/common/smbios.c | 5 ++++- src/soc/intel/common/smbios.h | 5 ++++- src/soc/intel/icelake/romstage/romstage.c | 1 + src/soc/intel/skylake/romstage/romstage_fsp20.c | 1 + 7 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/apollolake/meminit_util_apl.c b/src/soc/intel/apollolake/meminit_util_apl.c index a11c5d8031f..b272a99efed 100644 --- a/src/soc/intel/apollolake/meminit_util_apl.c +++ b/src/soc/intel/apollolake/meminit_util_apl.c @@ -90,6 +90,7 @@ void save_lpddr4_dimm_info_part_num(const char *dram_part_num) src_dimm->DimmId, dram_part_num, strlen(dram_part_num), + NULL, /* SPD not available */ memory_info_hob->DataWidth); index++; } diff --git a/src/soc/intel/apollolake/meminit_util_glk.c b/src/soc/intel/apollolake/meminit_util_glk.c index 9bfdf0b8a51..29dcd56767c 100644 --- a/src/soc/intel/apollolake/meminit_util_glk.c +++ b/src/soc/intel/apollolake/meminit_util_glk.c @@ -96,6 +96,7 @@ void save_lpddr4_dimm_info_part_num(const char *dram_part_num) src_dimm->DimmId, dram_part_num, strlen(dram_part_num), + src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL, memory_info_hob->DataWidth); index++; } diff --git a/src/soc/intel/cannonlake/romstage/romstage.c b/src/soc/intel/cannonlake/romstage/romstage.c index 661c98a466c..98d4c006a86 100644 --- a/src/soc/intel/cannonlake/romstage/romstage.c +++ b/src/soc/intel/cannonlake/romstage/romstage.c @@ -111,6 +111,7 @@ static void save_dimm_info(void) src_dimm->DimmId, dram_part_num, dram_part_num_len, + src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL, memory_info_hob->DataWidth); index++; } diff --git a/src/soc/intel/common/smbios.c b/src/soc/intel/common/smbios.c index 0b1be8817eb..d89e9d58271 100644 --- a/src/soc/intel/common/smbios.c +++ b/src/soc/intel/common/smbios.c @@ -22,7 +22,7 @@ void dimm_info_fill(struct dimm_info *dimm, u32 dimm_capacity, u8 ddr_type, u32 frequency, u8 rank_per_dimm, u8 channel_id, u8 dimm_id, const char *module_part_num, size_t module_part_number_size, - u16 data_width) + const u8 *module_serial_num, u16 data_width) { dimm->dimm_size = dimm_capacity; dimm->ddr_type = ddr_type; @@ -34,6 +34,9 @@ void dimm_info_fill(struct dimm_info *dimm, u32 dimm_capacity, u8 ddr_type, module_part_num, min(sizeof(dimm->module_part_number), module_part_number_size)); + if (module_serial_num) + memcpy(dimm->serial, module_serial_num, + DIMM_INFO_SERIAL_SIZE); switch (data_width) { case 8: dimm->bus_width = MEMORY_BUS_WIDTH_8; diff --git a/src/soc/intel/common/smbios.h b/src/soc/intel/common/smbios.h index 33b5d0df04f..5824f5d6654 100644 --- a/src/soc/intel/common/smbios.h +++ b/src/soc/intel/common/smbios.h @@ -19,10 +19,13 @@ #include #include +/* Offset info DIMM_INFO SpdSave for start of serial number */ +#define SPD_SAVE_OFFSET_SERIAL 5 + /* Fill the SMBIOS memory information from FSP MEM_INFO_DATA_HOB in CBMEM.*/ void dimm_info_fill(struct dimm_info *dimm, u32 dimm_capacity, u8 ddr_type, u32 frequency, u8 rank_per_dimm, u8 channel_id, u8 dimm_id, const char *module_part_num, size_t module_part_number_size, - u16 data_width); + const u8 *module_serial_num, u16 data_width); #endif /* _COMMON_SMBIOS_H_ */ diff --git a/src/soc/intel/icelake/romstage/romstage.c b/src/soc/intel/icelake/romstage/romstage.c index 1a0c4ffaee6..179d99cff67 100644 --- a/src/soc/intel/icelake/romstage/romstage.c +++ b/src/soc/intel/icelake/romstage/romstage.c @@ -96,6 +96,7 @@ static void save_dimm_info(void) src_dimm->DimmId, (const char *)src_dimm->ModulePartNum, sizeof(src_dimm->ModulePartNum), + src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL, memory_info_hob->DataWidth); index++; } diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index 2f75479339a..96937d651d9 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -126,6 +126,7 @@ static void save_dimm_info(void) src_dimm->DimmId, (const char *)src_dimm->ModulePartNum, sizeof(src_dimm->ModulePartNum), + src_dimm->SpdSave + SPD_SAVE_OFFSET_SERIAL, memory_info_hob->DataWidth); index++; } From 6eaa78144cb7c5b60d3d3d8467b1a0a23ef0db70 Mon Sep 17 00:00:00 2001 From: Lijian Zhao Date: Thu, 16 May 2019 07:32:42 -0700 Subject: [PATCH 343/588] SMBIOS: Fix SPD manufacture ID decoder According to JEP106 from JEDEC, fix manufacture ID of Crucial, Super Talnet and Micron. Signed-off-by: Lijian Zhao Change-Id: I10a268a7f3bde405b95bd3a16d5d121be623c7ed Reviewed-on: https://review.coreboot.org/c/coreboot/+/32837 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Duncan Laurie Reviewed-by: Patrick Rudolph --- src/arch/x86/smbios.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 589f4f0e305..90cd674198d 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -140,7 +140,7 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, struct smbios_type17 *t) { switch (mod_id) { - case 0x2c80: + case 0x9b85: t->manufacturer = smbios_add_string(t->eos, "Crucial"); break; @@ -172,9 +172,9 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, t->manufacturer = smbios_add_string(t->eos, "Hynix/Hyundai"); break; - case 0xb502: + case 0x3486: t->manufacturer = smbios_add_string(t->eos, - "SuperTalent"); + "Super Talent"); break; case 0xcd04: t->manufacturer = smbios_add_string(t->eos, @@ -188,7 +188,7 @@ void smbios_fill_dimm_manufacturer_from_id(uint16_t mod_id, t->manufacturer = smbios_add_string(t->eos, "Elpida"); break; - case 0xff2c: + case 0x2c80: t->manufacturer = smbios_add_string(t->eos, "Micron"); break; From aa2157430f96c658b9629bf69d507f1f161078a7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 16 May 2019 14:51:51 -0600 Subject: [PATCH 344/588] vendorcode/google/chromeos: Correct VPD field for MAC passthrough The VPD field name is dock_passthrough, not dock_passthru. Fix it. (I assume there is no length limit) BUG=b:132689337 TEST=check that the feature can now be controlled by the associated enterprise policy Change-Id: Icc2b070313fde74447279cd6ccaa4e3eb6d119ee Signed-off-by: Simon Glass Reviewed-on: https://review.coreboot.org/c/coreboot/+/32839 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/vendorcode/google/chromeos/acpi/amac.asl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/vendorcode/google/chromeos/acpi/amac.asl b/src/vendorcode/google/chromeos/acpi/amac.asl index c87862f6ffd..5a091ddfaac 100644 --- a/src/vendorcode/google/chromeos/acpi/amac.asl +++ b/src/vendorcode/google/chromeos/acpi/amac.asl @@ -16,16 +16,17 @@ /* * The Realtek r8152 driver in the Linux kernel supports a MAC address - * passthru feature which can result in the dock ethernet port using the - * same MAC address that is assigned to the internal NIC. This is done - * by calling an ACPI method at \_SB.AMAC() which returns a formatted - * string (as a buffer) containing the MAC address for the dock to use. + * dock pass-through feature which can result in the dock ethernet port + * using the same MAC address that is assigned to the internal NIC. This + * is done by calling an ACPI method at \_SB.AMAC() which returns a + * formatted string (as a buffer) containing the MAC address for the + * dock to use. * * The Linux kernel implementation can be found at * drivers/net/usb/r8152.c:vendor_mac_passthru_addr_read() * * For Chrome OS, the policy which controls where the dock MAC address - * comes from is written into RW_VPD property "dock_passthru": + * comes from is written into RW_VPD property "dock_passthrough": * * "dock_mac" or empty: Use MAC address from RO_VPD value "dock_mac" * "ethernet_mac0": Use MAC address from RO_VPD value "ethernet_mac0" @@ -39,8 +40,8 @@ Scope (\_SB) /* Format expected by the Linux kernel r8152 driver */ Name (MACA, "_AUXMAC_#XXXXXXXXXXXX#") - /* Get "dock_passthru" value from RW_VPD */ - Local0 = \VPD.VPDF ("RW", "dock_passthru") + /* Get "dock_passthrough" value from RW_VPD */ + Local0 = \VPD.VPDF ("RW", "dock_passthrough") Local1 = Zero Switch (ToString (Local0)) From ef179ab07b73ebe5b7dd33b260402d39daec678b Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Sat, 18 May 2019 13:47:39 -0700 Subject: [PATCH 345/588] timestamp: Update TIMESTAMP_CACHE_IN_BSS to include ENV_POSTCAR With CB:32726 ("lib/timestamp: Make timestamp_sync_cache_to_cbmem() in postcar") timestamps are synced from cache to cbmem in postcar as well. For postcar, the cache lives in BSS just like ramstage. This change updates TIMESTAMP_CACHE_IN_BSS to include both ramstage and postcar and uses this instead of ENV_RAMSTAGE to check for cache location. Ideally, it would be good to get rid of timestamp cache in postcar and ramstage completely since early cbmem init is enabled by default in coreboot and it is guaranteed that cbmem is recovered before timestamps are added in ramstage or postcar. This change is being pushed in as a temporary fix while I make the changes to remove timestamp cache from romstage and postcar completely. BUG=b:132939309 Change-Id: I2d82a96aba954df77c9386b7bd2e2ec0973881be Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/32881 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Subrata Banik --- src/lib/timestamp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/timestamp.c b/src/lib/timestamp.c index 431bce27033..38d02128451 100644 --- a/src/lib/timestamp.c +++ b/src/lib/timestamp.c @@ -47,12 +47,15 @@ DECLARE_OPTIONAL_REGION(timestamp); #define USE_TIMESTAMP_REGION 0 #endif -/* The cache location will sit in BSS when in ramstage. */ -#define TIMESTAMP_CACHE_IN_BSS ENV_RAMSTAGE +/* The cache location will sit in BSS when in ramstage/postcar. */ +#define TIMESTAMP_CACHE_IN_BSS (ENV_RAMSTAGE || ENV_POSTCAR) #define HAS_CBMEM (ENV_ROMSTAGE || ENV_RAMSTAGE || ENV_POSTCAR) -/* Storage of cache entries during ramstage prior to cbmem coming online. */ +/* + * Storage of cache entries during ramstage/postcar prior to cbmem coming + * online. + */ static struct timestamp_cache timestamp_cache; enum { @@ -220,7 +223,7 @@ void timestamp_init(uint64_t base) /* Timestamps could have already been recovered. * In those circumstances honor the cache which sits in BSS * as it has already been initialized. */ - if (ENV_RAMSTAGE && + if (TIMESTAMP_CACHE_IN_BSS && ts_cache->cache_state != TIMESTAMP_CACHE_UNINITIALIZED) return; From fc46ad8a8b99fbfaf5f2e9112abbb26221c1aeff Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 19 May 2019 11:49:27 +0200 Subject: [PATCH 346/588] src/Kconfig: Move DRAM section to src/lib/Kconfig These Kconfigs are mostly used in src/lib/. Change-Id: I7aa5436c6ff5fef53fde2081e902d793f3581c1e Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32882 Reviewed-by: Nico Huber Reviewed-by: Furquan Shaikh Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/Kconfig | 25 ------------------------- src/lib/Kconfig | 25 +++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Kconfig b/src/Kconfig index 2c9dc4ab7fb..d30aa99f06f 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -1158,31 +1158,6 @@ config GENERIC_GPIO_LIB implies configurability usually found on SoCs, particularly the ability to control internal pull resistors. -config GENERIC_SPD_BIN - bool - help - If enabled, add support for adding spd.hex files in cbfs as spd.bin - and locating it runtime to load SPD. Additionally provide provision to - fetch SPD over SMBus. - -config DIMM_MAX - int - default 4 - help - Total number of memory DIMM slots available on motherboard. - It is multiplication of number of channel to number of DIMMs per - channel - -config DIMM_SPD_SIZE - int - default 256 - help - Total SPD size that will be used for DIMM. - Ex: DDR3 256, DDR4 512. - -config SPD_READ_BY_WORD - bool - config BOOTBLOCK_CUSTOM # To be selected by arch, SoC or mainboard if it does not want use the normal # src/lib/bootblock.c#main() C entry point. diff --git a/src/lib/Kconfig b/src/lib/Kconfig index 2f10c1ccdf7..cb1e4a5cc8f 100644 --- a/src/lib/Kconfig +++ b/src/lib/Kconfig @@ -30,6 +30,31 @@ config FLATTENED_DEVICE_TREE Selected by features that require to parse and manipulate a flattened devicetree in ramstage. +config GENERIC_SPD_BIN + bool + help + If enabled, add support for adding spd.hex files in cbfs as spd.bin + and locating it runtime to load SPD. Additionally provide provision to + fetch SPD over SMBus. + +config DIMM_MAX + int + default 4 + help + Total number of memory DIMM slots available on motherboard. + It is multiplication of number of channel to number of DIMMs per + channel + +config DIMM_SPD_SIZE + int + default 256 + help + Total SPD size that will be used for DIMM. + Ex: DDR3 256, DDR4 512. + +config SPD_READ_BY_WORD + bool + if RAMSTAGE_LIBHWBASE config HWBASE_DYNAMIC_MMIO From 7576bd7f4299a3af220a7ba3d6c4928812c2982b Mon Sep 17 00:00:00 2001 From: Joel Kitching Date: Fri, 17 May 2019 14:26:01 +0800 Subject: [PATCH 347/588] vboot: save whether developer mode is enabled Save whether or not vboot has selected developer mode as a flag in vboot_working_data. Other coreboot code may access this flag without needing to consult vboot_handoff (which is in the process of being deprecated). BUG=b:124141368, b:124192753 TEST=make clean && make test-abuild BRANCH=none Change-Id: Ieb6ac4937c943aea78ddc762595a05387d2b8114 Signed-off-by: Joel Kitching Reviewed-on: https://review.coreboot.org/c/coreboot/+/32843 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Julius Werner --- src/security/vboot/bootmode.c | 6 ++---- src/security/vboot/misc.h | 2 ++ src/security/vboot/vboot_common.c | 5 ----- src/security/vboot/vboot_common.h | 1 - src/security/vboot/vboot_logic.c | 7 +++++-- 5 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/security/vboot/bootmode.c b/src/security/vboot/bootmode.c index e6e53b6f334..68749f008ba 100644 --- a/src/security/vboot/bootmode.c +++ b/src/security/vboot/bootmode.c @@ -164,10 +164,8 @@ int vboot_recovery_mode_memory_retrain(void) int vboot_developer_mode_enabled(void) { - if (cbmem_possibly_online() && vboot_handoff_check_developer_flag()) - return 1; - - return 0; + return cbmem_possibly_online() && + vboot_get_working_data()->flags & VBOOT_WD_FLAG_DEVELOPER_MODE; } #if CONFIG(VBOOT_NO_BOARD_SUPPORT) diff --git a/src/security/vboot/misc.h b/src/security/vboot/misc.h index 23159c8a0d5..acb6dbbd025 100644 --- a/src/security/vboot/misc.h +++ b/src/security/vboot/misc.h @@ -47,6 +47,8 @@ struct vboot_working_data { */ /* vboot requests display initialization from coreboot. */ #define VBOOT_WD_FLAG_DISPLAY_INIT (1 << 0) +/* vboot has selected developer mode. */ +#define VBOOT_WD_FLAG_DEVELOPER_MODE (1 << 1) /* * Source: security/vboot/common.c diff --git a/src/security/vboot/vboot_common.c b/src/security/vboot/vboot_common.c index 14f154c4387..ff8e6c896ce 100644 --- a/src/security/vboot/vboot_common.c +++ b/src/security/vboot/vboot_common.c @@ -88,11 +88,6 @@ static int vboot_get_handoff_flag(uint32_t flag) return !!(vbho->out_flags & flag); } -int vboot_handoff_check_developer_flag(void) -{ - return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_DEVELOPER); -} - int vboot_handoff_check_recovery_flag(void) { return vboot_get_handoff_flag(VB_INIT_OUT_ENABLE_RECOVERY); diff --git a/src/security/vboot/vboot_common.h b/src/security/vboot/vboot_common.h index 9a02303d12d..a785a8ba346 100644 --- a/src/security/vboot/vboot_common.h +++ b/src/security/vboot/vboot_common.h @@ -62,7 +62,6 @@ int vboot_get_handoff_info(void **addr, uint32_t *size); * Returns value read for other fields */ int vboot_handoff_check_recovery_flag(void); -int vboot_handoff_check_developer_flag(void); int vboot_handoff_get_recovery_reason(void); /* ============================ VBOOT REBOOT ============================== */ diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index df34490f985..00347c3f583 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -364,10 +364,13 @@ void verstage_main(void) vboot_reboot(); } - /* Is vboot declaring that display is available? If so, we should mark - it down, so that the mainboard/SoC knows to initialize display. */ + /* Jot down some information from vboot which may be required later on + in coreboot boot flow. */ if (ctx.flags & VB2_CONTEXT_DISPLAY_INIT) + /* Mainboard/SoC should initialize display. */ vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; + if (ctx.flags & VB2_CONTEXT_DEVELOPER_MODE) + vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DEVELOPER_MODE; /* Determine which firmware slot to boot (based on NVRAM) */ printk(BIOS_INFO, "Phase 2\n"); From c1b77c13911f0fb5db85bb1d6633e26334a9da71 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Thu, 16 May 2019 14:46:12 +0200 Subject: [PATCH 348/588] security/vboot/vboot_crtm.h: Remove ENV_ for vboot_measure_cbfs_hook() vboot_measure_cbfs_hook() is included when CONFIG_VBOOT_MEASURED_BOOT is enabled, but this function is defined as 0 in vboot_crtm.h using ENV_ Remove ENV_ for vboot_measure_cbfs_hook() function definition. This function is added to bootblock stage also. BUG=NA TEST=Build Google Banon and Google Cyan Change-Id: Ic62c18db09c119dfb85340a6b7f36bfd148aaa45 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32532 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Furquan Shaikh Reviewed-by: Julius Werner --- src/security/vboot/Makefile.inc | 1 + src/security/vboot/vboot_crtm.h | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/security/vboot/Makefile.inc b/src/security/vboot/Makefile.inc index 6d2096ddb0a..9ce724ed54d 100644 --- a/src/security/vboot/Makefile.inc +++ b/src/security/vboot/Makefile.inc @@ -70,6 +70,7 @@ ramstage-y += vboot_common.c postcar-y += vboot_common.c ifeq ($(CONFIG_VBOOT_MEASURED_BOOT),y) +bootblock-y += vboot_crtm.c verstage-y += vboot_crtm.c romstage-y += vboot_crtm.c ramstage-y += vboot_crtm.c diff --git a/src/security/vboot/vboot_crtm.h b/src/security/vboot/vboot_crtm.h index e675edbf03b..64cb4f2b40c 100644 --- a/src/security/vboot/vboot_crtm.h +++ b/src/security/vboot/vboot_crtm.h @@ -46,8 +46,7 @@ */ uint32_t vboot_init_crtm(void); -#if (CONFIG(VBOOT_MEASURED_BOOT) && \ -!ENV_BOOTBLOCK && !ENV_DECOMPRESSOR && !ENV_SMM) +#if CONFIG(VBOOT_MEASURED_BOOT) /* * Measures cbfs data via hook (cbfs) * fh is the cbfs file handle to measure From 232113e7cdc08c4dad7c7914af937717e9c1b144 Mon Sep 17 00:00:00 2001 From: Jamie Chen Date: Tue, 14 May 2019 17:18:52 +0800 Subject: [PATCH 349/588] mb/google/octopus: Override emmc DLL values for Casta New emmc DLL values for Casta BUG=b:122307918 TEST=Boot to OS on 12 systems Change-Id: Ie51885fb9628fa093ecc38f4a3f3157f751ca9ab Signed-off-by: Jamie Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32799 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Karthik Ramasubramanian --- .../octopus/variants/casta/overridetree.cb | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/mainboard/google/octopus/variants/casta/overridetree.cb b/src/mainboard/google/octopus/variants/casta/overridetree.cb index dc9c9118af6..091b3027f44 100644 --- a/src/mainboard/google/octopus/variants/casta/overridetree.cb +++ b/src/mainboard/google/octopus/variants/casta/overridetree.cb @@ -1,4 +1,45 @@ chip soc/intel/apollolake + # EMMC Tx CMD Delay + # Refer to EDS-Vol2-16.32. + # [14:8] steps of delay for DDR mode, each 125ps. + # [6:0] steps of delay for SDR mode, each 125ps. + register "emmc_tx_cmd_cntl" = "0x00000505" + + # EMMC TX DATA Delay 1 + # Refer to EDS-Vol2-16.33. + # [14:8] steps of delay for HS400, each 125ps. + # [6:0] steps of delay for SDR104/HS200, each 125ps. + register "emmc_tx_data_cntl1" = "0x00000c0d" + + # EMMC TX DATA Delay 2 + # Refer to EDS-Vol2-16.34. + # [30:24] steps of delay for SDR50, each 125ps. + # [22:16] steps of delay for DDR50, each 125ps. + # [14:8] steps of delay for SDR25/HS50, each 125ps. + # [6:0] steps of delay for SDR12, each 125ps. + register "emmc_tx_data_cntl2" = "0x1c2a2a2a" + + # EMMC RX CMD/DATA Delay 1 + # Refer to EDS-Vol2-16.35. + # [30:24] steps of delay for SDR50, each 125ps. + # [22:16] steps of delay for DDR50, each 125ps. + # [14:8] steps of delay for SDR25/HS50, each 125ps. + # [6:0] steps of delay for SDR12, each 125ps. + register "emmc_rx_cmd_data_cntl1" = "0x00181b1b" + + # EMMC RX CMD/DATA Delay 2 + # Refer to EDS-Vol2-16.37. + # [17:16] stands for Rx Clock before Output Buffer + # [14:8] steps of delay for Auto Tuning Mode, each 125ps. + # [6:0] steps of delay for HS200, each 125ps. + register "emmc_rx_cmd_data_cntl2" = "0x0001000f" + + # EMMC Rx Strobe Delay + # Refer to EDS-Vol2-16.36. + # [14:8] Rx Strobe Delay DLL 1(HS400 Mode), each 125ps. + # [6:0] Rx Strobe Delay DLL 2(HS400 Mode), each 125ps. + register "emmc_rx_strobe_cntl" = "0x00000a0a" + # Override USB2 PER PORT register (PORT 4) register "usb2eye[4]" = "{ .Usb20OverrideEn = 1, From 20989630c417b1f0228f4c8eb6af7d715f5bdbcc Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Thu, 16 May 2019 11:46:22 +0200 Subject: [PATCH 350/588] soc/intel/braswell/pmutil.c: Use GEN_PMCON1 for RTC status cbmem_find is not available in every stage. Remove usage of cbmem_find() and use GEN_PMCON1 always. BUG=NA TEST=Booting Embedded Linux on Facebook FBG-1701 Change-Id: Id97d57864b3e241e8f046d9b1caebdce199a46b1 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32724 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/soc/intel/braswell/pmutil.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/soc/intel/braswell/pmutil.c b/src/soc/intel/braswell/pmutil.c index 271eefed08c..4bc621b80e1 100644 --- a/src/soc/intel/braswell/pmutil.c +++ b/src/soc/intel/braswell/pmutil.c @@ -16,9 +16,9 @@ #include #include +#include #include #include -#include #include #include #include @@ -364,15 +364,14 @@ int rtc_failure(void) { uint32_t gen_pmcon1; int rtc_fail; - struct chipset_power_state *ps = cbmem_find(CBMEM_ID_POWER_STATE); - if (ps != NULL) - gen_pmcon1 = ps->gen_pmcon1; - else - gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1)); + /* not usable in ramstage as GEN_PMCON1 gets reset */ + if (ENV_RAMSTAGE) + dead_code(); - rtc_fail = !!(gen_pmcon1 & RPS); + gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1)); + rtc_fail = !!(gen_pmcon1 & RPS); if (rtc_fail) printk(BIOS_DEBUG, "RTC failure.\n"); From 811a51ac6757b30392385009579f5eddbd9540ab Mon Sep 17 00:00:00 2001 From: Krishna Prasad Bhat Date: Tue, 14 May 2019 14:42:10 +0530 Subject: [PATCH 351/588] mb/google/hatch: Change SD_CD# reset config to PLTRST The system should boot fine to OS on pressing power button before the system enters G3. However, on hatch, we observe that the system waits for few seconds at "Starting kernel" and then resets, with SD card tray inserted and SD_CD# pad reset config set to DEEP. Hence configuring SD_CD# pad reset config to PLTRST. BUG=b:129933011 TEST=Built and verified on hatch. Change-Id: Ic4466b96332f095ff39b28d98607e95fc3d12d6a Signed-off-by: Krishna Prasad Bhat Reviewed-on: https://review.coreboot.org/c/coreboot/+/32782 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Paul Fagerburg Reviewed-by: Tim Wawrzynczak Reviewed-by: Furquan Shaikh --- src/mainboard/google/hatch/variants/baseboard/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/gpio.c b/src/mainboard/google/hatch/variants/baseboard/gpio.c index 32526cc74b4..0b6607595d1 100644 --- a/src/mainboard/google/hatch/variants/baseboard/gpio.c +++ b/src/mainboard/google/hatch/variants/baseboard/gpio.c @@ -339,7 +339,7 @@ static const struct pad_config gpio_table[] = { /* G4 : SD_DATA3 */ PAD_CFG_NF(GPP_G4, NONE, DEEP, NF1), /* G5 : SD_CD# */ - PAD_CFG_NF(GPP_G5, NONE, DEEP, NF1), + PAD_CFG_NF(GPP_G5, NONE, PLTRST, NF1), /* G6 : SD_CLK */ PAD_CFG_NF(GPP_G6, NONE, DEEP, NF1), /* G7 : SD_WP => NC */ From 2e585a12a247e7993c45aa887b9f4c22e63ccbed Mon Sep 17 00:00:00 2001 From: Paul Menzel Date: Mon, 16 Jul 2018 08:39:22 +0200 Subject: [PATCH 352/588] sb/amd/cimx/sb800: Get rid of power button device in coreboot Apply commit d7b88dcb (mb/google/x86-boards: Get rid of power button device in coreboot) to AMD Brazos boards [1]: > As per the ACPI specification, there are two types of power button > devices: > 1. Fixed hardware power button > 2. Generic hardware power button > > Fixed hardware power button is added by the OSPM if POWER_BUTTON flag > is not set in FADT by the BIOS. This device has its programming model > in PM1x_EVT_BLK. All ACPI compliant OSes are expected to add this > power button device by default if the power button FADT flag is not > set. > > On the other hand, generic hardware power button can be used by > platforms if fixed register space cannot be used for the power button > device. In order to support this, power button device object with HID > PNP0C0C is expected to be added to ACPI tables. Additionally, > POWER_BUTTON flag should be set to indicate the presence of control > method for power button. [..] > This change gets rid of the generic hardware power button from all > google mainboards and relies completely on the fixed hardware power > button. The same problem exists with the AMD Hudson devices in coreboot. For AMD Hudson (2) and Yangtze based devices this was removed in commit 44f2fab8 (AMD hudson and yangtze boards: Let mainboard declare power button) [2]. Two devices are detected. $ dmesg | grep Button [ 0.209213] input: Power Button as /devices/LNXSYSTM:00/LNXSYBUS:00/PNP0C0C:00/input/input0 [ 0.209254] ACPI: Power Button [PWRB] [ 0.209332] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input1 [ 0.209349] ACPI: Power Button [PWRF] $ sudo evtest No device specified, trying to scan all of /dev/input/event* Available devices: /dev/input/event0: Power Button /dev/input/event1: Power Button [..] [1]: https://review.coreboot.org/5546 [2]: https://review.coreboot.org/27272 Change-Id: I0cbecb72f7e1bf3d051d3b7656c6af4d6f43b497 Signed-off-by: Paul Menzel Reviewed-on: https://review.coreboot.org/c/coreboot/+/27496 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Stefan Reinauer --- src/mainboard/amd/inagua/acpi/gpe.asl | 9 --------- src/mainboard/amd/persimmon/acpi/gpe.asl | 9 --------- src/mainboard/amd/south_station/acpi/gpe.asl | 9 --------- src/mainboard/amd/union_station/acpi/gpe.asl | 9 --------- src/mainboard/asrock/e350m1/acpi/gpe.asl | 9 --------- src/mainboard/elmex/pcm205400/acpi/gpe.asl | 9 --------- src/mainboard/gizmosphere/gizmo/acpi/gpe.asl | 9 --------- src/mainboard/jetway/nf81-t56n-lf/acpi/gpe.asl | 9 --------- src/mainboard/pcengines/apu1/acpi/gpe.asl | 9 --------- src/southbridge/amd/cimx/sb800/acpi/fch.asl | 9 --------- 10 files changed, 90 deletions(-) diff --git a/src/mainboard/amd/inagua/acpi/gpe.asl b/src/mainboard/amd/inagua/acpi/gpe.asl index 30e6fdcb3c0..3cf38c035a9 100644 --- a/src/mainboard/amd/inagua/acpi/gpe.asl +++ b/src/mainboard/amd/inagua/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/amd/persimmon/acpi/gpe.asl b/src/mainboard/amd/persimmon/acpi/gpe.asl index 30e6fdcb3c0..3cf38c035a9 100644 --- a/src/mainboard/amd/persimmon/acpi/gpe.asl +++ b/src/mainboard/amd/persimmon/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/amd/south_station/acpi/gpe.asl b/src/mainboard/amd/south_station/acpi/gpe.asl index 2f227587122..e7a320eda52 100644 --- a/src/mainboard/amd/south_station/acpi/gpe.asl +++ b/src/mainboard/amd/south_station/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/amd/union_station/acpi/gpe.asl b/src/mainboard/amd/union_station/acpi/gpe.asl index 2f227587122..e7a320eda52 100644 --- a/src/mainboard/amd/union_station/acpi/gpe.asl +++ b/src/mainboard/amd/union_station/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/asrock/e350m1/acpi/gpe.asl b/src/mainboard/asrock/e350m1/acpi/gpe.asl index 0ba8899a607..7994ae31a52 100644 --- a/src/mainboard/asrock/e350m1/acpi/gpe.asl +++ b/src/mainboard/asrock/e350m1/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/elmex/pcm205400/acpi/gpe.asl b/src/mainboard/elmex/pcm205400/acpi/gpe.asl index 30e6fdcb3c0..3cf38c035a9 100644 --- a/src/mainboard/elmex/pcm205400/acpi/gpe.asl +++ b/src/mainboard/elmex/pcm205400/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/gizmosphere/gizmo/acpi/gpe.asl b/src/mainboard/gizmosphere/gizmo/acpi/gpe.asl index 0b9250d5747..e520724101e 100644 --- a/src/mainboard/gizmosphere/gizmo/acpi/gpe.asl +++ b/src/mainboard/gizmosphere/gizmo/acpi/gpe.asl @@ -16,12 +16,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -43,7 +37,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -64,14 +57,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/jetway/nf81-t56n-lf/acpi/gpe.asl b/src/mainboard/jetway/nf81-t56n-lf/acpi/gpe.asl index 30e6fdcb3c0..3cf38c035a9 100644 --- a/src/mainboard/jetway/nf81-t56n-lf/acpi/gpe.asl +++ b/src/mainboard/jetway/nf81-t56n-lf/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/mainboard/pcengines/apu1/acpi/gpe.asl b/src/mainboard/pcengines/apu1/acpi/gpe.asl index 30e6fdcb3c0..3cf38c035a9 100644 --- a/src/mainboard/pcengines/apu1/acpi/gpe.asl +++ b/src/mainboard/pcengines/apu1/acpi/gpe.asl @@ -15,12 +15,6 @@ Scope(\_GPE) { /* Start Scope GPE */ - /* General event 3 */ - Method(_L03) { - /* DBGO("\\_GPE\\_L00\n") */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ - } - /* Legacy PM event */ Method(_L08) { /* DBGO("\\_GPE\\_L08\n") */ @@ -42,7 +36,6 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.UOH5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UOH6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.UEH1, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* ExtEvent0 SCI event */ @@ -63,14 +56,12 @@ Scope(\_GPE) { /* Start Scope GPE */ Notify(\_SB.PCI0.PBR5, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR6, 0x02) /* NOTIFY_DEVICE_WAKE */ Notify(\_SB.PCI0.PBR7, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } /* Azalia SCI event */ Method(_L1B) { /* DBGO("\\_GPE\\_L1B\n") */ Notify(\_SB.PCI0.AZHD, 0x02) /* NOTIFY_DEVICE_WAKE */ - Notify(\_SB.PWRB, 0x02) /* NOTIFY_DEVICE_WAKE */ } } /* End Scope GPE */ diff --git a/src/southbridge/amd/cimx/sb800/acpi/fch.asl b/src/southbridge/amd/cimx/sb800/acpi/fch.asl index 2dc3438c08d..b837b4cfc95 100644 --- a/src/southbridge/amd/cimx/sb800/acpi/fch.asl +++ b/src/southbridge/amd/cimx/sb800/acpi/fch.asl @@ -354,12 +354,3 @@ Scope(\){ PWDA, 1, } } - -Scope(\_SB) { - Device(PWRB) { /* Start Power button device */ - Name(_HID, EISAID("PNP0C0C")) - Name(_UID, 0xAA) - Name(_PRW, Package () {3, 0x04}) /* wake from S1-S4 */ - Name(_STA, 0x0B) /* sata is invisible */ - } -} /* End Scope(_SB) */ From 1eeb94ff4acf09959794a2ac1d92e685633aab18 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Fri, 17 May 2019 07:36:47 -0600 Subject: [PATCH 353/588] util/scripts: update references to cross-repo-cherrypick It appears that the rebase.sh script was renamed to cross-repo-cherrypick and changed directories. Update comments to reflect that change. Change-Id: I863df48378feb48c9b195b1778dcaf1972a4f105 Signed-off-by: Jett Rink Reviewed-on: https://review.coreboot.org/c/coreboot/+/32849 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/scripts/cross-repo-cherrypick | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/util/scripts/cross-repo-cherrypick b/util/scripts/cross-repo-cherrypick index 38d4f46fe76..42b05b51318 100755 --- a/util/scripts/cross-repo-cherrypick +++ b/util/scripts/cross-repo-cherrypick @@ -1,6 +1,6 @@ #!/bin/sh -# rebase.sh - rebase helper script +# cross-repo-cherrypick - rebase helper script # # Copyright 2015, 2017 Google Inc. # @@ -22,8 +22,8 @@ BRANCH="origin/master" # git remote add ... # git checkout -b upstreaming # git cherry-pick ... -# git rebase -i --exec util/gitconfig/rebase.sh master -# Alternatively, you can run util/gitconfig/rebase.sh after every +# git rebase -i --exec util/scripts/cross-repo-cherrypick master +# Alternatively, you can run util/scripts/cross-repo-cherrypick after every # individual cherry-pick. # use $0 --cros to add a stub BUG/BRANCH/TEST block From cc8665eacc389318191aa6fe1b04b29580cc84ae Mon Sep 17 00:00:00 2001 From: Keith Short Date: Tue, 14 May 2019 13:38:56 -0600 Subject: [PATCH 354/588] console: Add new function die_with_post_code() Add a new helper function die_with_post_code() that generates a post code and an error string prior to halting the CPU. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: I87551d60b253dc13ff76f7898c1f112f573a00a2 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32838 Reviewed-by: Martin Roth Reviewed-by: Aaron Durbin Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/console/die.c | 7 +++++++ src/include/console/console.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/console/die.c b/src/console/die.c index 769e65134f6..513d1c4097a 100644 --- a/src/console/die.c +++ b/src/console/die.c @@ -36,4 +36,11 @@ void __noreturn die(const char *msg) die_notify(); halt(); } + +/* Report a fatal error with a post code */ +void __noreturn die_with_post_code(uint8_t value, const char *msg) +{ + post_code(value); + die(msg); +} #endif diff --git a/src/include/console/console.h b/src/include/console/console.h index ed10807c9a4..082ba29be84 100644 --- a/src/include/console/console.h +++ b/src/include/console/console.h @@ -43,6 +43,7 @@ void post_log_clear(void); /* this function is weak and can be overridden by a mainboard function. */ void mainboard_post(u8 value); void __noreturn die(const char *msg); +void __noreturn die_with_post_code(uint8_t value, const char *msg); /* * This function is weak and can be overridden to provide additional From bd96a8430046601dfa2ffbd31636dfd49a41e2ca Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 18 May 2019 06:57:07 +0200 Subject: [PATCH 355/588] util: Fix typo on plural form of index Change-Id: Idc165f8eafacf3130a29b701bc3610c1a67f69d5 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32855 Tested-by: build bot (Jenkins) Reviewed-by: Jacob Garber --- util/romcc/romcc.c | 34 ++++++++++++++++---------------- util/romcc/tests/linux_test5.c | 6 +++--- util/romcc/tests/raminit_test6.c | 6 +++--- util/romcc/tests/raminit_test7.c | 6 +++--- util/romcc/tests/simple_test46.c | 4 ++-- util/romcc/tests/simple_test54.c | 6 +++--- util/x86/x86_page_tables.go | 8 ++++---- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 43be1712135..c6507dcad9f 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -14111,9 +14111,9 @@ static void compute_closure_variables(struct compile_state *state, struct block *block; struct triple *old_result, *first, *ins; size_t count, idx; - unsigned long used_indicies; + unsigned long used_indices; int i, max_index; -#define MAX_INDICIES (sizeof(used_indicies)*CHAR_BIT) +#define MAX_INDICES (sizeof(used_indices)*CHAR_BIT) #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1)) struct { unsigned id; @@ -14183,7 +14183,7 @@ static void compute_closure_variables(struct compile_state *state, * * To gurantee that stability I lookup the variables * to see where they have been used before and - * I build my final list with the assigned indicies. + * I build my final list with the assigned indices. */ vars = 0; if (enclose_triple(old_result)) { @@ -14202,8 +14202,8 @@ static void compute_closure_variables(struct compile_state *state, ordered_triple_set(&vars, set->member); } - /* Lookup the current indicies of the live varialbe */ - used_indicies = 0; + /* Lookup the current indices of the live varialbe */ + used_indices = 0; max_index = -1; for(set = vars; set ; set = set->next) { struct triple *ins; @@ -14214,14 +14214,14 @@ static void compute_closure_variables(struct compile_state *state, if (index < 0) { continue; } - if (index >= MAX_INDICIES) { + if (index >= MAX_INDICES) { internal_error(state, ins, "index unexpectedly large"); } - if (used_indicies & (1 << index)) { + if (used_indices & (1 << index)) { internal_error(state, ins, "index previously used?"); } - /* Remember which indicies have been used */ - used_indicies |= (1 << index); + /* Remember which indices have been used */ + used_indices |= (1 << index); if (index > max_index) { max_index = index; } @@ -14239,31 +14239,31 @@ static void compute_closure_variables(struct compile_state *state, continue; } /* Find the lowest unused index value */ - for(index = 0; index < MAX_INDICIES; index++) { - if (!(used_indicies & ((uint64_t)1 << index))) { + for(index = 0; index < MAX_INDICES; index++) { + if (!(used_indices & ((uint64_t)1 << index))) { break; } } - if (index == MAX_INDICIES) { - internal_error(state, ins, "no free indicies?"); + if (index == MAX_INDICES) { + internal_error(state, ins, "no free indices?"); } info[ID_BITS(ins->id)].index = index; - /* Remember which indicies have been used */ - used_indicies |= (1 << index); + /* Remember which indices have been used */ + used_indices |= (1 << index); if (index > max_index) { max_index = index; } } /* Build the return list of variables with positions matching - * their indicies. + * their indices. */ *enclose = 0; last_var = enclose; for(i = 0; i <= max_index; i++) { struct triple *var; var = 0; - if (used_indicies & (1 << i)) { + if (used_indices & (1 << i)) { for(set = vars; set; set = set->next) { int index; index = info[ID_BITS(set->member->id)].index; diff --git a/util/romcc/tests/linux_test5.c b/util/romcc/tests/linux_test5.c index cf0df46d548..e94d5d71e72 100644 --- a/util/romcc/tests/linux_test5.c +++ b/util/romcc/tests/linux_test5.c @@ -156,7 +156,7 @@ static const struct mem_param *spd_set_memclk(void) unsigned device; uint32_t value; - static const int latency_indicies[] = { 26, 23, 9 }; + static const int latency_indices[] = { 26, 23, 9 }; static const unsigned char min_cycle_times[] = { [NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */ [NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */ @@ -224,7 +224,7 @@ static const struct mem_param *spd_set_memclk(void) continue; } debug('D'); - value = smbus_read_byte(device, latency_indicies[index]); + value = smbus_read_byte(device, latency_indices[index]); if (value < 0) continue; debug('E'); @@ -310,7 +310,7 @@ static const struct mem_param *spd_set_memclk(void) } /* Read the min_cycle_time for this latency */ - value = smbus_read_byte(device, latency_indicies[index]); + value = smbus_read_byte(device, latency_indices[index]); /* All is good if the selected clock speed * is what I need or slower. diff --git a/util/romcc/tests/raminit_test6.c b/util/romcc/tests/raminit_test6.c index e99e355e33d..8048dcee896 100644 --- a/util/romcc/tests/raminit_test6.c +++ b/util/romcc/tests/raminit_test6.c @@ -1621,7 +1621,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) unsigned min_cycle_time, min_latency; int i; uint32_t value; - static const int latency_indicies[] = { 26, 23, 9 }; + static const int latency_indices[] = { 26, 23, 9 }; static const unsigned char min_cycle_times[] = { [0 ] = 0x50, [1 ] = 0x60, @@ -1651,7 +1651,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) (!(latencies & (1 << latency)))) { continue; } - value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); + value = spd_read_byte(ctrl->channel0[i], latency_indices[index]); if (value < 0) { continue; } @@ -1701,7 +1701,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) } - value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); + value = spd_read_byte(ctrl->channel0[i], latency_indices[index]); if (value <= min_cycle_time) { diff --git a/util/romcc/tests/raminit_test7.c b/util/romcc/tests/raminit_test7.c index 184e912ffff..c768e86a3cf 100644 --- a/util/romcc/tests/raminit_test7.c +++ b/util/romcc/tests/raminit_test7.c @@ -1626,7 +1626,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) unsigned min_cycle_time, min_latency; int i; uint32_t value; - static const int latency_indicies[] = { 26, 23, 9 }; + static const int latency_indices[] = { 26, 23, 9 }; static const unsigned char min_cycle_times[] = { [0 ] = 0x50, [1 ] = 0x60, @@ -1656,7 +1656,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) (!(latencies & (1 << latency)))) { continue; } - value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); + value = spd_read_byte(ctrl->channel0[i], latency_indices[index]); if (value < 0) { continue; } @@ -1706,7 +1706,7 @@ static const struct mem_param *spd_set_memclk(const struct mem_controller *ctrl) } - value = spd_read_byte(ctrl->channel0[i], latency_indicies[index]); + value = spd_read_byte(ctrl->channel0[i], latency_indices[index]); if (value <= min_cycle_time) { diff --git a/util/romcc/tests/simple_test46.c b/util/romcc/tests/simple_test46.c index 0b831254a11..2d3764e4582 100644 --- a/util/romcc/tests/simple_test46.c +++ b/util/romcc/tests/simple_test46.c @@ -1,6 +1,6 @@ static void spd_set_memclk(void) { - static const int indicies[] = { 26, 23, 9 }; + static const int indices[] = { 26, 23, 9 }; int new_cycle_time, new_latency; int index; unsigned min_cycle_time, min_latency; @@ -15,7 +15,7 @@ static void spd_set_memclk(void) for(index = 0; index < 3; index++) { unsigned long loops; unsigned long address; - address = indicies[index]; + address = indices[index]; loops = 1000000; do { } while(--loops); diff --git a/util/romcc/tests/simple_test54.c b/util/romcc/tests/simple_test54.c index 37dce795c5d..b7dee66bcfe 100644 --- a/util/romcc/tests/simple_test54.c +++ b/util/romcc/tests/simple_test54.c @@ -569,7 +569,7 @@ static const struct mem_param *spd_set_memclk(void) unsigned device; uint32_t value; - static const int latency_indicies[] = { 26, 23, 9 }; + static const int latency_indices[] = { 26, 23, 9 }; static const unsigned char min_cycle_times[] = { [NBCAP_MEMCLK_200MHZ] = 0x50, /* 5ns */ [NBCAP_MEMCLK_166MHZ] = 0x60, /* 6ns */ @@ -637,7 +637,7 @@ static const struct mem_param *spd_set_memclk(void) continue; } debug('D'); - value = smbus_read_byte(device, latency_indicies[index]); + value = smbus_read_byte(device, latency_indices[index]); if (value < 0) continue; debug('E'); @@ -723,7 +723,7 @@ static const struct mem_param *spd_set_memclk(void) } /* Read the min_cycle_time for this latency */ - value = smbus_read_byte(device, latency_indicies[index]); + value = smbus_read_byte(device, latency_indices[index]); /* All is good if the selected clock speed * is what I need or slower. diff --git a/util/x86/x86_page_tables.go b/util/x86/x86_page_tables.go index 2dc0ed36ff4..e477b54c5e4 100644 --- a/util/x86/x86_page_tables.go +++ b/util/x86/x86_page_tables.go @@ -223,7 +223,7 @@ func (cw *cWriter) WritePageEntry(data interface{}) error { return nil } -// This map represents what the IA32_PAT MSR should be at runtime. The indicies +// This map represents what the IA32_PAT MSR should be at runtime. The indices // are what the linux kernel uses. Reserved entries are not used. // 0 WB : _PAGE_CACHE_MODE_WB // 1 WC : _PAGE_CACHE_MODE_WC @@ -523,11 +523,11 @@ func newAddrSpace(mergeFunc addrRangeMerge, metatdataBaseAddr uint64) *addressSp return as } -func (as *addressSpace) deleteEntries(indicies []int) { +func (as *addressSpace) deleteEntries(indices []int) { // deletions need to be processed in reverse order so as not // delete the wrong entries - sort.Sort(sort.Reverse(sort.IntSlice(indicies))) - for _, i := range indicies { + sort.Sort(sort.Reverse(sort.IntSlice(indices))) + for _, i := range indices { as.ranges = append(as.ranges[:i], as.ranges[i+1:]...) } } From 686b539949d9a07d3b6522c075ccae3f15a6121a Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 18 May 2019 13:36:03 +0200 Subject: [PATCH 356/588] i945: Add device identification D2:F1 Add device identification D2:F1 for desktop version. (see Intel 945G/945GZ/945GC/945P/945PL Express Chipset Family datasheet page 192) Change-Id: Ie060644d635a7031ee6f55420d63751192481091 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32877 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/northbridge/intel/i945/gma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c index 9c4f410d027..1d20533a481 100644 --- a/src/northbridge/intel/i945/gma.c +++ b/src/northbridge/intel/i945/gma.c @@ -858,6 +858,7 @@ static const unsigned short i945_gma_func0_ids[] = { }; static const unsigned short i945_gma_func1_ids[] = { + 0x2776, /* Desktop 82945G/GZ/GC */ 0x27a6, /* Mobile 945GM/GMS/GME Express Integrated Graphics Controller */ 0 }; From 8ef6732b94148a39f8203cb3b4cf3388dc103199 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 10 May 2019 11:49:24 -0600 Subject: [PATCH 357/588] ec/google/wilco: Add support for KB_ERR_CODE to Wilco EC Adds support for the KB_ERR_CODE command on the Wilco EC. This command is used to drive diagnostic LEDs on the platform after a failed boot. This change also adds the Wilco EC mailbox command support to bootblock and verstage so that those stages can use the KB_ERR_CODE command. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: I96d17baf57694e4e01c676d80c606f67054cd0c3 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32776 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/ec/google/wilco/Makefile.inc | 3 ++- src/ec/google/wilco/commands.c | 6 ++++++ src/ec/google/wilco/commands.h | 21 +++++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/src/ec/google/wilco/Makefile.inc b/src/ec/google/wilco/Makefile.inc index 3a7790c097a..f17869ecbcc 100644 --- a/src/ec/google/wilco/Makefile.inc +++ b/src/ec/google/wilco/Makefile.inc @@ -1,6 +1,7 @@ ifeq ($(CONFIG_EC_GOOGLE_WILCO),y) -bootblock-y += bootblock.c +bootblock-y += bootblock.c commands.c mailbox.c +verstage-y += commands.c mailbox.c romstage-y += commands.c mailbox.c romstage.c boardid.c ramstage-y += chip.c commands.c mailbox.c boardid.c smm-y += commands.c mailbox.c smihandler.c boardid.c diff --git a/src/ec/google/wilco/commands.c b/src/ec/google/wilco/commands.c index d0d572d569e..a97a28eccea 100644 --- a/src/ec/google/wilco/commands.c +++ b/src/ec/google/wilco/commands.c @@ -181,3 +181,9 @@ int wilco_ec_signed_fw(void) CONFIG_EC_BASE_ACPI_DATA); return !!ec_read(EC_RAM_SIGNED_FW); } + +int wilco_ec_err_code(enum ec_err_code err_code) +{ + return wilco_ec_mailbox(WILCO_EC_MSG_DEFAULT, KB_ERR_CODE, + &err_code, 1, NULL, 0); +} diff --git a/src/ec/google/wilco/commands.h b/src/ec/google/wilco/commands.h index 3077eee5787..fafb7fd8ba6 100644 --- a/src/ec/google/wilco/commands.h +++ b/src/ec/google/wilco/commands.h @@ -50,6 +50,8 @@ enum { KB_SLP_EN = 0x64, /* Inform the EC about BIOS boot progress */ KB_BIOS_PROGRESS = 0xc2, + /* Inform the EC that a fatal error occurred */ + KB_ERR_CODE = 0x7b, }; enum ec_ram_addr { @@ -86,6 +88,12 @@ enum ec_camera { CAMERA_OFF }; +enum ec_err_code { + DLED_MEMORY = 0x03, + DLED_PANEL = 0x10, + DLED_ROM = 0x19, +}; + /** * wilco_ec_radio_control() - Control wireless radios. * @ec_radio: Wireless radio type. @@ -310,4 +318,17 @@ enum ec_acpi_wake_events { */ int wilco_ec_signed_fw(void); +/** + * wilco_ec_err_code + * + * Send an error code to the EC to indicate a failed boot. The EC flashes the + * platform LED amber and white to provide user indication of the failure type. + * + * @err_code: Error code to send to the EC + * + * Returns 0 if EC command was successful + * Returns -1 if EC command failed + */ +int wilco_ec_err_code(enum ec_err_code err_code); + #endif /* EC_GOOGLE_WILCO_COMMANDS_H */ From abdc9bc8c8605f2865b7a9cc956cbcc4402c1c43 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Tue, 14 May 2019 17:31:19 +0530 Subject: [PATCH 358/588] soc/intel/common/block/gpio: Add gpio_pm_configure() function This patch adds new function to perform gpio power management programming as per EDS. BUG=b:130764684 TEST=Able to build and boot from fixed media on ICL and CML. Change-Id: I816a70ad92595f013740a235a9799912ad51665e Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32788 Tested-by: build bot (Jenkins) Reviewed-by: Paul Fagerburg Reviewed-by: Tim Wawrzynczak Reviewed-by: Furquan Shaikh --- src/soc/intel/common/block/gpio/gpio.c | 18 +++++++++++++++++ .../common/block/include/intelblocks/gpio.h | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index 3a0594cba1f..d37601ce3b7 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -609,3 +609,21 @@ void gpi_clear_int_cfg(void) } } } + +/* The function performs GPIO Power Management programming. */ +void gpio_pm_configure(const uint8_t *misccfg_pm_values, size_t num) +{ + int i; + size_t gpio_communities; + uint8_t misccfg_pm_mask = MISCCFG_ENABLE_GPIO_PM_CONFIG; + const struct pad_community *comm; + + comm = soc_gpio_get_community(&gpio_communities); + if (gpio_communities != num) + die("Incorrect GPIO community count!\n"); + + /* Program GPIO_MISCCFG */ + for (i = 0; i < num; i++, comm++) + pcr_rmw8(comm->port, GPIO_MISCCFG, + misccfg_pm_mask, misccfg_pm_values[i]); +} diff --git a/src/soc/intel/common/block/include/intelblocks/gpio.h b/src/soc/intel/common/block/include/intelblocks/gpio.h index 417929329f5..a2cccc7cd2e 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpio.h +++ b/src/soc/intel/common/block/include/intelblocks/gpio.h @@ -23,6 +23,23 @@ #ifndef __ACPI__ #include +/* GPIO community IOSF sideband clock gating */ +#define MISCCFG_GPSIDEDPCGEN (1 << 5) +/* GPIO community RCOMP clock gating */ +#define MISCCFG_GPRCOMPCDLCGEN (1 << 4) +/* GPIO community RTC clock gating */ +#define MISCCFG_GPRTCDLCGEN (1 << 3) +/* GFX controller clock gating */ +#define MISCCFG_GSXSLCGEN (1 << 2) +/* GPIO community partition clock gating */ +#define MISCCFG_GPDPCGEN (1 << 1) +/* GPIO community local clock gating */ +#define MISCCFG_GPDLCGEN (1 << 0) +/* Enable GPIO community power management configuration */ +#define MISCCFG_ENABLE_GPIO_PM_CONFIG (MISCCFG_GPSIDEDPCGEN | \ + MISCCFG_GPRCOMPCDLCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN \ + | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN) + /* * GPIO numbers may not be contiguous and instead will have a different * starting pin number for each pad group. @@ -215,5 +232,8 @@ uint32_t soc_gpio_pad_config_fixup(const struct pad_config *cfg, */ void gpi_clear_int_cfg(void); +/* The function performs GPIO Power Management programming. */ +void gpio_pm_configure(const uint8_t *misccfg_pm_values, size_t num); + #endif #endif /* _SOC_INTELBLOCKS_GPIO_H_ */ From dd5fa024260bf6fd19c077d640c34e27b742115b Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 15 May 2019 21:04:37 +0530 Subject: [PATCH 359/588] soc/intel/icelake: Make use of gpio_pm_configure() Provide option in chip.h to set dynamic local clock gating setting. BUG=b:130764684 TEST=Able to build and boot ICL. Change-Id: Ic30a490aadb8cc9c05a19a05533ab0196c69b7f1 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32789 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/icelake/chip.c | 23 +++++++++++++++++++ src/soc/intel/icelake/chip.h | 20 ++++++++++++++++ src/soc/intel/icelake/gpio.c | 21 ++++++++++++----- .../intel/icelake/include/soc/gpio_soc_defs.h | 8 +++++++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/src/soc/intel/icelake/chip.c b/src/soc/intel/icelake/chip.c index 11d14de0842..2616db17684 100644 --- a/src/soc/intel/icelake/chip.c +++ b/src/soc/intel/icelake/chip.c @@ -103,6 +103,27 @@ const char *soc_acpi_name(const struct device *dev) } #endif +/* SoC rotine to fill GPIO PM mask and value for GPIO_MISCCFG register */ +static void soc_fill_gpio_pm_configuration(void) +{ + uint8_t value[TOTAL_GPIO_COMM]; + const struct device *dev; + dev = pcidev_on_root(SA_DEV_SLOT_ROOT, 0); + if (!dev || !dev->chip_info) + return; + + const config_t *config = dev->chip_info; + + if (config->gpio_override_pm) + memcpy(value, config->gpio_pm, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + else + memset(value, MISCCFG_ENABLE_GPIO_PM_CONFIG, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + + gpio_pm_configure(value, TOTAL_GPIO_COMM); +} + void soc_init_pre_device(void *chip_info) { /* Snapshot the current GPIO IRQ polarities. FSP is setting a @@ -117,6 +138,8 @@ void soc_init_pre_device(void *chip_info) /* Restore GPIO IRQ polarities back to previous settings. */ itss_restore_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); + + soc_fill_gpio_pm_configuration(); } static void pci_domain_set_resources(struct device *dev) diff --git a/src/soc/intel/icelake/chip.h b/src/soc/intel/icelake/chip.h index 3e2b78acd68..77611262a3f 100644 --- a/src/soc/intel/icelake/chip.h +++ b/src/soc/intel/icelake/chip.h @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -263,6 +264,25 @@ struct soc_intel_icelake_config { FORCE_ENABLE, FORCE_DISABLE, } CnviBtAudioOffload; + + /* + * Override GPIO PM configuration: + * 0: Use FSP default GPIO PM program, + * 1: coreboot to override GPIO PM program + */ + uint8_t gpio_override_pm; + + /* + * GPIO PM configuration: 0 to disable, 1 to enable power gating + * Bit 6-7: Reserved + * Bit 5: MISCCFG_GPSIDEDPCGEN + * Bit 4: MISCCFG_GPRCOMPCDLCGEN + * Bit 3: MISCCFG_GPRTCDLCGEN + * Bit 2: MISCCFG_GSXLCGEN + * Bit 1: MISCCFG_GPDPCGEN + * Bit 0: MISCCFG_GPDLCGEN + */ + uint8_t gpio_pm[TOTAL_GPIO_COMM]; }; typedef struct soc_intel_icelake_config config_t; diff --git a/src/soc/intel/icelake/gpio.c b/src/soc/intel/icelake/gpio.c index b1c46abe29d..96c5c838ada 100644 --- a/src/soc/intel/icelake/gpio.c +++ b/src/soc/intel/icelake/gpio.c @@ -76,8 +76,9 @@ static const struct pad_group icl_community5_groups[] = { INTEL_GPP_BASE(GPP_C0, GPP_S0, GPP_S7, 320), /* GPP_S */ }; -static const struct pad_community icl_communities[] = { - { /* GPP G, B, A */ +static const struct pad_community icl_communities[TOTAL_GPIO_COMM] = { + /* GPP G, B, A */ + [COMM_0] = { .port = PID_GPIOCOM0, .first_pad = GPP_G0, .last_pad = GPP_A23, @@ -95,7 +96,9 @@ static const struct pad_community icl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map_com0), .groups = icl_community0_groups, .num_groups = ARRAY_SIZE(icl_community0_groups), - }, { /* GPP H, D, F */ + }, + /* GPP H, D, F */ + [COMM_1] = { .port = PID_GPIOCOM1, .first_pad = GPP_H0, .last_pad = GPP_F19, @@ -113,7 +116,9 @@ static const struct pad_community icl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = icl_community1_groups, .num_groups = ARRAY_SIZE(icl_community1_groups), - }, { /* GPD */ + }, + /* GPD */ + [COMM_2] = { .port = PID_GPIOCOM2, .first_pad = GPD0, .last_pad = GPD11, @@ -131,7 +136,9 @@ static const struct pad_community icl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = icl_community2_groups, .num_groups = ARRAY_SIZE(icl_community2_groups), - }, { /* GPP C, E */ + }, + /* GPP C, E */ + [COMM_3] = { .port = PID_GPIOCOM4, .first_pad = GPP_C0, .last_pad = GPP_E23, @@ -149,7 +156,9 @@ static const struct pad_community icl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = icl_community4_groups, .num_groups = ARRAY_SIZE(icl_community4_groups), - }, { /* GPP R, S */ + }, + /* GPP R, S */ + [COMM_4] = { .port = PID_GPIOCOM5, .first_pad = GPP_R0, .last_pad = GPP_S7, diff --git a/src/soc/intel/icelake/include/soc/gpio_soc_defs.h b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h index 5a27a15bd6d..887e378e073 100644 --- a/src/soc/intel/icelake/include/soc/gpio_soc_defs.h +++ b/src/soc/intel/icelake/include/soc/gpio_soc_defs.h @@ -281,4 +281,12 @@ #define NUM_GPIO_COM5_PADS (GPP_S7 - GPP_R0 + 1) #define TOTAL_PADS 205 + +#define COMM_0 0 +#define COMM_1 1 +#define COMM_2 2 +#define COMM_3 3 +#define COMM_4 4 +#define TOTAL_GPIO_COMM 5 + #endif From 76a8f9e29f3cb6aa2e971957eec7fc05abaf50b8 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Wed, 15 May 2019 21:23:18 +0530 Subject: [PATCH 360/588] soc/intel/cannonlake: Make use of gpio_pm_configure() Provide option in chip.h to set dynamic local clock gating setting. BUG=b:130764684 TEST=Able to build and boot CML. Change-Id: Iec60076398b745e11d5025e4d7a5c35374d918a4 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32790 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/cannonlake/chip.c | 23 +++++++++++++++++++ src/soc/intel/cannonlake/chip.h | 19 +++++++++++++++ src/soc/intel/cannonlake/gpio.c | 21 ++++++++++++----- src/soc/intel/cannonlake/gpio_cnp_h.c | 19 +++++++++++---- .../cannonlake/include/soc/gpio_soc_defs.h | 8 +++++++ .../include/soc/gpio_soc_defs_cnp_h.h | 7 ++++++ 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c index 1bd34c34e01..faddbd5a243 100644 --- a/src/soc/intel/cannonlake/chip.c +++ b/src/soc/intel/cannonlake/chip.c @@ -166,6 +166,27 @@ void cnl_configure_pads(const struct pad_config *cfg, size_t num_pads) gpio_configure_pads(cfg, num_pads); } +/* SoC rotine to fill GPIO PM mask and value for GPIO_MISCCFG register */ +static void soc_fill_gpio_pm_configuration(void) +{ + uint8_t value[TOTAL_GPIO_COMM]; + const struct device *dev; + dev = pcidev_on_root(SA_DEV_SLOT_ROOT, 0); + if (!dev || !dev->chip_info) + return; + + const config_t *config = dev->chip_info; + + if (config->gpio_override_pm) + memcpy(value, config->gpio_pm, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + else + memset(value, MISCCFG_ENABLE_GPIO_PM_CONFIG, sizeof(uint8_t) * + TOTAL_GPIO_COMM); + + gpio_pm_configure(value, TOTAL_GPIO_COMM); +} + void soc_init_pre_device(void *chip_info) { /* Perform silicon specific init. */ @@ -176,6 +197,8 @@ void soc_init_pre_device(void *chip_info) /* TODO(furquan): Get rid of this workaround once FSP is fixed. */ cnl_configure_pads(NULL, 0); + + soc_fill_gpio_pm_configuration(); } static void pci_domain_set_resources(struct device *dev) diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h index 2b2a51f6a0f..0d51c1ca5c0 100644 --- a/src/soc/intel/cannonlake/chip.h +++ b/src/soc/intel/cannonlake/chip.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -402,6 +403,24 @@ struct soc_intel_cannonlake_config { /* Enable GBE wakeup */ uint8_t LanWakeFromDeepSx; uint8_t WolEnableOverride; + + /* + * Override GPIO PM configuration: + * 0: Use FSP default GPIO PM program, + * 1: coreboot to override GPIO PM program + */ + uint8_t gpio_override_pm; + /* + * GPIO PM configuration: 0 to disable, 1 to enable power gating + * Bit 6-7: Reserved + * Bit 5: MISCCFG_GPSIDEDPCGEN + * Bit 4: MISCCFG_GPRCOMPCDLCGEN + * Bit 3: MISCCFG_GPRTCDLCGEN + * Bit 2: MISCCFG_GSXLCGEN + * Bit 1: MISCCFG_GPDPCGEN + * Bit 0: MISCCFG_GPDLCGEN + */ + uint8_t gpio_pm[TOTAL_GPIO_COMM]; }; typedef struct soc_intel_cannonlake_config config_t; diff --git a/src/soc/intel/cannonlake/gpio.c b/src/soc/intel/cannonlake/gpio.c index dd514643d73..4036fdc073e 100644 --- a/src/soc/intel/cannonlake/gpio.c +++ b/src/soc/intel/cannonlake/gpio.c @@ -77,8 +77,9 @@ static const struct pad_group cnl_community4_groups[] = { INTEL_GPP(GPP_C0, GPIO_RSVD_22, GPIO_RSVD_27), /* HVMOS */ }; -static const struct pad_community cnl_communities[] = { - { /* GPP A, B, G, SPI */ +static const struct pad_community cnl_communities[TOTAL_GPIO_COMM] = { + /* GPP A, B, G, SPI */ + [COMM_0] = { .port = PID_GPIOCOM0, .first_pad = GPP_A0, .last_pad = GPIO_RSVD_11, @@ -96,7 +97,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map_com0), .groups = cnl_community0_groups, .num_groups = ARRAY_SIZE(cnl_community0_groups), - }, { /* GPP D, F, H, VGPIO */ + }, + /* GPP D, F, H, VGPIO */ + [COMM_1] = { .port = PID_GPIOCOM1, .first_pad = GPP_D0, .last_pad = vSD3_CD_B, @@ -114,7 +117,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community1_groups, .num_groups = ARRAY_SIZE(cnl_community1_groups), - }, { /* GPD */ + }, + /* GPD */ + [COMM_2] = { .port = PID_GPIOCOM2, .first_pad = GPD0, .last_pad = GPD11, @@ -132,7 +137,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community2_groups, .num_groups = ARRAY_SIZE(cnl_community2_groups), - }, { /* AZA, CPU */ + }, + /* AZA, CPU */ + [COMM_3] = { .port = PID_GPIOCOM3, .first_pad = HDA_BCLK, .last_pad = GPIO_RSVD_38, @@ -150,7 +157,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community3_groups, .num_groups = ARRAY_SIZE(cnl_community3_groups), - }, { /* GPP C, E, JTAG, HVMOS */ + }, + /* GPP C, E, JTAG, HVMOS */ + [COMM_4] = { .port = PID_GPIOCOM4, .first_pad = GPP_C0, .last_pad = GPIO_RSVD_27, diff --git a/src/soc/intel/cannonlake/gpio_cnp_h.c b/src/soc/intel/cannonlake/gpio_cnp_h.c index 102444a9f81..dd9f4336452 100644 --- a/src/soc/intel/cannonlake/gpio_cnp_h.c +++ b/src/soc/intel/cannonlake/gpio_cnp_h.c @@ -80,7 +80,8 @@ static const struct pad_group cnl_community4_groups[] = { }; static const struct pad_community cnl_communities[] = { - { /* GPP A, B */ + /* GPP A, B */ + [COMM_0] = { .port = PID_GPIOCOM0, .first_pad = GPP_A0, .last_pad = GPIO_RSVD_2, @@ -98,7 +99,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map_com0), .groups = cnl_community0_groups, .num_groups = ARRAY_SIZE(cnl_community0_groups), - }, { /* GPP C, D, G */ + }, + /* GPP C, D, G */ + [COMM_1] = { .port = PID_GPIOCOM1, .first_pad = GPP_C0, .last_pad = vSSP2_RXD, @@ -116,7 +119,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community1_groups, .num_groups = ARRAY_SIZE(cnl_community1_groups), - }, { /* GPD */ + }, + /* GPD */ + [COMM_2] = { .port = PID_GPIOCOM2, .first_pad = GPD0, .last_pad = GPD11, @@ -134,7 +139,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community2_groups, .num_groups = ARRAY_SIZE(cnl_community2_groups), - }, { /* GPP K, H, E, F */ + }, + /* GPP K, H, E, F */ + [COMM_3] = { .port = PID_GPIOCOM3, .first_pad = GPP_K0, .last_pad = GPIO_RSVD_19, @@ -152,7 +159,9 @@ static const struct pad_community cnl_communities[] = { .num_reset_vals = ARRAY_SIZE(rst_map), .groups = cnl_community3_groups, .num_groups = ARRAY_SIZE(cnl_community3_groups), - }, { /* GPP I, J */ + }, + /* GPP I, J */ + [COMM_4] = { .port = PID_GPIOCOM4, .first_pad = GPIO_RSVD_20, .last_pad = GPP_J11, diff --git a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h index 59901440d91..698bd2a5c7e 100644 --- a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h +++ b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs.h @@ -355,4 +355,12 @@ #define TOTAL_PADS 275 #define SD_PWR_EN_PIN GPP_A17 + +#define COMM_0 0 +#define COMM_1 1 +#define COMM_2 2 +#define COMM_3 3 +#define COMM_4 4 +#define TOTAL_GPIO_COMM 5 + #endif diff --git a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs_cnp_h.h b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs_cnp_h.h index 1788e789895..5176ac734a4 100644 --- a/src/soc/intel/cannonlake/include/soc/gpio_soc_defs_cnp_h.h +++ b/src/soc/intel/cannonlake/include/soc/gpio_soc_defs_cnp_h.h @@ -399,4 +399,11 @@ #define TOTAL_PADS (GPD11 + 1) +#define COMM_0 0 +#define COMM_1 1 +#define COMM_2 2 +#define COMM_3 3 +#define COMM_4 4 +#define TOTAL_GPIO_COMM 5 + #endif From 97ae7430a80c00b3f53465727880d74d7ebfe7aa Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 17 May 2019 14:39:36 +0530 Subject: [PATCH 361/588] mb/google/dragonegg: Override FSP default GPIO PM configuration GPIO_COMM_0/2/3/4: Enable gpio community all PM configuration. GPIO_COMM_1: Disable RCOMP clock gating due to GPP_D16 IRQ mapped for H1 TPM. BUG=b:130764684 TEST=H1 TPM interrupt working find and able to boot from fixed boot media Change-Id: I1f83f938f201c6574367960b1027555767cf6f3d Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32847 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../google/dragonegg/variants/baseboard/devicetree.cb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/mainboard/google/dragonegg/variants/baseboard/devicetree.cb b/src/mainboard/google/dragonegg/variants/baseboard/devicetree.cb index 257ad1dd15d..f8209242806 100644 --- a/src/mainboard/google/dragonegg/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/dragonegg/variants/baseboard/devicetree.cb @@ -167,6 +167,16 @@ chip soc/intel/icelake }, }" + # GPIO PM programming + register "gpio_override_pm" = "1" + + # GPIO community PM configuration + register "gpio_pm[COMM_0]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_1]" = "MISCCFG_GPSIDEDPCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN" + register "gpio_pm[COMM_2]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_3]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_4]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + device domain 0 on device pci 00.0 on end # Host Bridge device pci 02.0 on end # Integrated Graphics Device From 0c89ed93d758d3abd82f19abf12fa66c16610a57 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 17 May 2019 14:50:48 +0530 Subject: [PATCH 362/588] mb/google/{arcada, hatch, sarien}: Override FSP default GPIO PM configuration sarien/arcada: GPIO_COMM_0/2/3/4: Enable gpio community all PM configuration GPIO_COMM_1: Disable RCOMP clock gating due to GPP_D18 IRQ mapped for H1 TPM. hatch: GPIO_COMM_0/1/2/3: Enable gpio community all PM configuration GPIO_COMM_4: Disable RCOMP clock gating due to GPP_C21 IRQ mapped for H1 TPM. BUG=b:130764684 TEST=H1 TPM interrupt working find and able to boot from fixed boot media Change-Id: Ia4d5483847a4d243b9038119d4bb5990591cc754 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32848 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- .../google/hatch/variants/baseboard/devicetree.cb | 10 ++++++++++ .../google/sarien/variants/arcada/devicetree.cb | 10 ++++++++++ .../google/sarien/variants/sarien/devicetree.cb | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb index 09e004e84c6..9d10cac41b6 100644 --- a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb @@ -89,6 +89,16 @@ chip soc/intel/cannonlake register "PchHdaAudioLinkSsp1" = "1" register "PchHdaAudioLinkDmic0" = "1" + # GPIO PM programming + register "gpio_override_pm" = "1" + + # GPIO community PM configuration + register "gpio_pm[COMM_0]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_1]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_2]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_3]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_4]" = "MISCCFG_GPSIDEDPCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN" + device cpu_cluster 0 on device lapic 0 on end end diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index b6377ba55dd..d3848a24b08 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -201,6 +201,16 @@ chip soc/intel/cannonlake register "PcieClkSrcUsage[4]" = "12" register "PcieClkSrcClkReq[4]" = "4" + # GPIO PM programming + register "gpio_override_pm" = "1" + + # GPIO community PM configuration + register "gpio_pm[COMM_0]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_1]" = "MISCCFG_GPSIDEDPCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN" + register "gpio_pm[COMM_2]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_3]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_4]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + device cpu_cluster 0 on device lapic 0 on end end diff --git a/src/mainboard/google/sarien/variants/sarien/devicetree.cb b/src/mainboard/google/sarien/variants/sarien/devicetree.cb index 3807047e0f4..c96423c93dd 100644 --- a/src/mainboard/google/sarien/variants/sarien/devicetree.cb +++ b/src/mainboard/google/sarien/variants/sarien/devicetree.cb @@ -205,6 +205,16 @@ chip soc/intel/cannonlake register "PcieClkSrcUsage[2]" = "12" register "PcieClkSrcClkReq[2]" = "2" + # GPIO PM programming + register "gpio_override_pm" = "1" + + # GPIO community PM configuration + register "gpio_pm[COMM_0]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_1]" = "MISCCFG_GPSIDEDPCGEN | MISCCFG_GPRTCDLCGEN | MISCCFG_GSXSLCGEN | MISCCFG_GPDPCGEN | MISCCFG_GPDLCGEN" + register "gpio_pm[COMM_2]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_3]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + register "gpio_pm[COMM_4]" = "MISCCFG_ENABLE_GPIO_PM_CONFIG" + device cpu_cluster 0 on device lapic 0 on end end From cf041d8c8375d07434908a8bd1028d4bd0d54070 Mon Sep 17 00:00:00 2001 From: Mike Banon Date: Tue, 28 Aug 2018 00:44:59 +0300 Subject: [PATCH 363/588] src/vendorcode/amd/agesa/f16kb: Update microcode to version 0x7000110 2018-02-09 This microcode update for CPU ID 0x700F01 improves system stability: in particular, fixes Xen hardware virtualization freezes. Also it attempts to patch some Spectre-related security vulnerabilities. This new microcode has been tested by multiple coreboot community members and found working perfectly. Old version: 0x700010B [2013-07-09] replaced by New version: 0x7000110 [2018-02-09] Change-Id: Iebe6e54d922378a8a1feb97f37b08ac50c8234b2 Signed-off-by: Mike Banon Reviewed-on: https://review.coreboot.org/c/coreboot/+/28370 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- .../0x16/KB/F16KbId7001MicrocodePatch.c | 3899 ++--------------- 1 file changed, 437 insertions(+), 3462 deletions(-) diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbId7001MicrocodePatch.c b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbId7001MicrocodePatch.c index 61876b8db58..a0a20eb3e99 100644 --- a/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbId7001MicrocodePatch.c +++ b/src/vendorcode/amd/agesa/f16kb/Proc/CPU/Family/0x16/KB/F16KbId7001MicrocodePatch.c @@ -4,16 +4,16 @@ * * AMD F16Kb Microcode patch. * - * F16Kb Microcode Patch rev 0700010B for 7001 or equivalent. + * F16Kb Microcode Patch rev 07000110 for 7001 or equivalent. * * @xrefitem bom "File Content Label" "Release Content" * @e project: AGESA * @e sub-project: CPU/Family/0x16/KB - * @e \$Revision: 267923 $ @e \$Date: 2013-07-15 16:49:48 -0400 (Mon, 15 Jul 2013) $ + * @e \$Revision: 334098 $ @e \$Date: 2018-02-09 14:21:15 -0400 (Fri, 09 Feb 2018) $ */ /***************************************************************************** * - * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. + * Copyright (c) 2008 - 2018, Advanced Micro Devices, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -64,3468 +64,443 @@ RDATA_GROUP (G3_DXE) */ -// Encrypt Patch code 0700010B for 7001 and equivalent +// Encrypt Patch code 07000110 for 7001 and equivalent CONST UINT8 ROMDATA CpuF16KbId7001MicrocodePatch [IDS_PAD_4K] = { - 0x13, - 0x20, - 0x09, - 0x07, - 0x0b, - 0x01, - 0x00, - 0x07, - 0x03, - 0x80, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x70, - 0x00, - 0x00, - 0x00, - 0xaa, - 0xaa, - 0xaa, - 0x1c, - 0x8a, - 0x19, - 0x02, - 0x24, - 0xb6, - 0x41, - 0xb0, - 0x60, - 0x6a, - 0x6e, - 0xc3, - 0xdb, - 0xae, - 0xd9, - 0xa3, - 0x9e, - 0x4c, - 0x89, - 0xd2, - 0xe6, - 0xb8, - 0xb1, - 0x81, - 0x30, - 0xbd, - 0x57, - 0x94, - 0x81, - 0xa3, - 0xbc, - 0x81, - 0x95, - 0x47, - 0xb5, - 0x93, - 0x5f, - 0x8a, - 0xf6, - 0x82, - 0xcd, - 0x0e, - 0x4d, - 0xd3, - 0x26, - 0xd8, - 0xa8, - 0x35, - 0xb7, - 0x64, - 0xba, - 0x32, - 0x33, - 0x09, - 0xfd, - 0x93, - 0xc6, - 0x49, - 0x19, - 0xe3, - 0x53, - 0xc1, - 0xb5, - 0xcc, - 0x2f, - 0xf3, - 0x52, - 0xaa, - 0xe3, - 0x9c, - 0x79, - 0x52, - 0x10, - 0x5f, - 0xff, - 0x90, - 0x29, - 0x0b, - 0xf1, - 0x7f, - 0xfa, - 0x0c, - 0x10, - 0x75, - 0x84, - 0x74, - 0x81, - 0x8b, - 0x63, - 0xb3, - 0x71, - 0x20, - 0x25, - 0xc8, - 0x16, - 0x6d, - 0xc2, - 0xcc, - 0xf7, - 0x78, - 0x30, - 0xb6, - 0x2d, - 0x81, - 0x2b, - 0xdd, - 0xc4, - 0x6b, - 0xab, - 0x31, - 0x90, - 0xa8, - 0x6d, - 0xd7, - 0x6c, - 0xae, - 0x66, - 0xe5, - 0xdf, - 0xd6, - 0x65, - 0xd4, - 0x95, - 0xe5, - 0x68, - 0xae, - 0x26, - 0xa5, - 0x48, - 0xe6, - 0xf5, - 0xf3, - 0x22, - 0x67, - 0xb9, - 0x4d, - 0x22, - 0x38, - 0x32, - 0x51, - 0x4b, - 0x8a, - 0x6b, - 0xc1, - 0x9c, - 0xd2, - 0xc3, - 0x91, - 0xb5, - 0x43, - 0xe9, - 0xcc, - 0x73, - 0x49, - 0x07, - 0x7c, - 0x7d, - 0xe8, - 0xc8, - 0x5e, - 0x56, - 0x7a, - 0x22, - 0x80, - 0xcc, - 0xbd, - 0x21, - 0x1b, - 0x32, - 0x0d, - 0xd4, - 0x92, - 0x62, - 0x37, - 0xaf, - 0xf6, - 0x18, - 0xfa, - 0x9f, - 0x9f, - 0x12, - 0x6b, - 0x4b, - 0x4f, - 0x1d, - 0x5a, - 0xca, - 0x3c, - 0x7d, - 0x7d, - 0x38, - 0x66, - 0x00, - 0x90, - 0xc5, - 0x7e, - 0x44, - 0xf3, - 0xa8, - 0x65, - 0xc3, - 0x1b, - 0x41, - 0x1d, - 0xef, - 0xb3, - 0xd4, - 0x43, - 0xb5, - 0x02, - 0x1a, - 0x0d, - 0x08, - 0x44, - 0xa5, - 0x57, - 0xa7, - 0x65, - 0x90, - 0xdc, - 0xdc, - 0x1e, - 0xdf, - 0x45, - 0x5f, - 0x88, - 0xdc, - 0x7c, - 0xd6, - 0x09, - 0x57, - 0x01, - 0x33, - 0xfc, - 0x47, - 0xad, - 0xa0, - 0x49, - 0x0c, - 0x55, - 0xc4, - 0xfd, - 0xf1, - 0x68, - 0xd2, - 0x67, - 0x0c, - 0xf1, - 0x92, - 0xa4, - 0x9b, - 0x50, - 0x34, - 0x5d, - 0xea, - 0x58, - 0x5b, - 0x2a, - 0x58, - 0x44, - 0x53, - 0xdf, - 0x59, - 0xbc, - 0x14, - 0xe3, - 0x7f, - 0xd6, - 0x4a, - 0xd6, - 0x98, - 0x59, - 0x8c, - 0xbb, - 0xce, - 0xe6, - 0x86, - 0xdb, - 0x66, - 0xbd, - 0xeb, - 0x51, - 0xf1, - 0xce, - 0x80, - 0x0f, - 0xd9, - 0x83, - 0x86, - 0x17, - 0xed, - 0x78, - 0x3e, - 0x5d, - 0xac, - 0xd1, - 0x13, - 0xfa, - 0x01, - 0x58, - 0x35, - 0xe9, - 0x66, - 0x16, - 0x5d, - 0xa8, - 0x70, - 0x08, - 0x0e, - 0xa3, - 0xab, - 0x3b, - 0xd1, - 0x75, - 0xbf, - 0x2f, - 0xb2, - 0x9a, - 0x7c, - 0xd8, - 0x84, - 0x66, - 0x1a, - 0x07, - 0x00, - 0xe0, - 0x04, - 0xbf, - 0x0e, - 0x04, - 0xaa, - 0x0e, - 0x91, - 0x6f, - 0xb4, - 0xb8, - 0xff, - 0xfa, - 0xad, - 0xb0, - 0xd8, - 0x41, - 0x65, - 0xf5, - 0xd5, - 0x0d, - 0x12, - 0x15, - 0xbf, - 0x40, - 0x5b, - 0xed, - 0xeb, - 0x81, - 0x2a, - 0x1f, - 0x48, - 0x00, - 0x5b, - 0xf7, - 0x08, - 0x35, - 0x86, - 0x8d, - 0xe4, - 0x15, - 0x52, - 0x40, - 0x1b, - 0x88, - 0x5a, - 0x8f, - 0xd0, - 0x4f, - 0xb5, - 0xbc, - 0xdb, - 0x45, - 0x30, - 0xc5, - 0x89, - 0x32, - 0x98, - 0xf9, - 0xa7, - 0x18, - 0x27, - 0xf1, - 0x0b, - 0xc7, - 0x6d, - 0xeb, - 0x7f, - 0x39, - 0xd2, - 0x25, - 0x99, - 0x6d, - 0x3a, - 0x1b, - 0x24, - 0xa4, - 0xc5, - 0x7c, - 0xdf, - 0x33, - 0x3d, - 0x7c, - 0x43, - 0x40, - 0x5b, - 0x8d, - 0xd1, - 0xec, - 0x0c, - 0xca, - 0x76, - 0xd9, - 0x1a, - 0x32, - 0xee, - 0x45, - 0xee, - 0xb6, - 0x30, - 0x21, - 0xf8, - 0x66, - 0xb5, - 0xbf, - 0xfb, - 0x66, - 0x13, - 0x9c, - 0xf0, - 0xcf, - 0xae, - 0xca, - 0x54, - 0xbc, - 0xf1, - 0xce, - 0x76, - 0x57, - 0x8d, - 0xf5, - 0xee, - 0x02, - 0x14, - 0xc0, - 0x62, - 0x3f, - 0xa1, - 0xad, - 0x9d, - 0xbb, - 0x83, - 0x3d, - 0x8f, - 0xf2, - 0xe9, - 0x41, - 0x42, - 0xca, - 0x04, - 0xf9, - 0xf7, - 0x4f, - 0xf7, - 0xc6, - 0x77, - 0xf0, - 0x0e, - 0x8c, - 0xea, - 0xb6, - 0x6c, - 0x47, - 0xae, - 0xd1, - 0x1b, - 0x2c, - 0x89, - 0xbf, - 0x4b, - 0x61, - 0xdc, - 0x2d, - 0x06, - 0x6d, - 0x79, - 0x5c, - 0x5e, - 0x82, - 0xc0, - 0x4f, - 0x54, - 0x5d, - 0x68, - 0x55, - 0x5b, - 0x1c, - 0x75, - 0xb6, - 0xcc, - 0x4b, - 0xb6, - 0x3e, - 0x2b, - 0xec, - 0x30, - 0xa7, - 0x6f, - 0x43, - 0xbb, - 0xe7, - 0x52, - 0xbe, - 0xc5, - 0xeb, - 0xc8, - 0x2b, - 0xb9, - 0x40, - 0x7d, - 0x5a, - 0xf8, - 0x4c, - 0x8e, - 0x84, - 0x64, - 0xb9, - 0x32, - 0x38, - 0x3d, - 0xf8, - 0x4e, - 0xe5, - 0x82, - 0x87, - 0xbe, - 0x69, - 0x3a, - 0x66, - 0xd0, - 0x3c, - 0x1e, - 0x40, - 0x14, - 0xc0, - 0x71, - 0x12, - 0x8b, - 0xee, - 0x1f, - 0x2b, - 0x5f, - 0xe9, - 0x80, - 0x1e, - 0x10, - 0x48, - 0x1e, - 0xcb, - 0xba, - 0x10, - 0x22, - 0x45, - 0x67, - 0xf3, - 0xbd, - 0x3f, - 0x97, - 0x86, - 0x7d, - 0x3f, - 0x01, - 0x00, - 0x00, - 0x00, - 0x0b, - 0x01, - 0x00, - 0x07, - 0xe2, - 0x13, - 0xe7, - 0x13, - 0x93, - 0x07, - 0x66, - 0x04, - 0x60, - 0x04, - 0xd7, - 0x19, - 0x04, - 0x07, - 0xda, - 0x09, - 0x4f, - 0x15, - 0x2e, - 0x07, - 0xe3, - 0x16, - 0xf0, - 0x0c, - 0xf0, - 0x0c, - 0xf0, - 0x0c, - 0xf0, - 0x0c, - 0xf0, - 0x0c, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x6f, - 0xd7, - 0x3a, - 0x00, - 0xc0, - 0x9f, - 0xdb, - 0xeb, - 0xff, - 0x57, - 0x7f, - 0x29, - 0xa0, - 0x9f, - 0xc9, - 0xe7, - 0x52, - 0xa0, - 0x06, - 0x00, - 0x67, - 0xd9, - 0x3a, - 0x00, - 0xc0, - 0x9f, - 0xdb, - 0xeb, - 0xc0, - 0xff, - 0xff, - 0x28, - 0xe0, - 0x1f, - 0xe0, - 0xac, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x67, - 0xd9, - 0x3a, - 0x00, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x17, - 0xac, - 0x06, - 0x00, - 0x9d, - 0xf1, - 0xef, - 0x2b, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x16, - 0xac, - 0x06, - 0x00, - 0xf9, - 0xff, - 0xff, - 0x2d, - 0xe1, - 0x9f, - 0xaf, - 0xfe, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x6b, - 0xb8, - 0x06, - 0x00, - 0xf5, - 0xff, - 0xff, - 0x28, - 0xe1, - 0x9f, - 0xaf, - 0xfe, - 0x90, - 0xff, - 0xff, - 0x29, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xdf, - 0xff, - 0xff, - 0x2e, - 0xe0, - 0x1f, - 0xab, - 0xfa, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x9d, - 0x4b, - 0xe1, - 0x50, - 0xa0, - 0x06, - 0x00, - 0xd6, - 0xff, - 0xff, - 0x00, - 0xe1, - 0xcf, - 0x43, - 0xd7, - 0x70, - 0x5c, - 0x39, - 0x00, - 0xc0, - 0x1f, - 0xd0, - 0xeb, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xa3, - 0xdb, - 0x38, - 0x00, - 0xc1, - 0xdf, - 0xd9, - 0xeb, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xd7, - 0xb8, - 0x06, - 0x00, - 0x00, - 0xff, - 0xff, - 0x3c, - 0xe1, - 0x5f, - 0xeb, - 0xfe, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xdd, - 0x7f, - 0x2c, - 0xe0, - 0x0f, - 0x6b, - 0xff, - 0x4b, - 0xd8, - 0x38, - 0x00, - 0xa0, - 0x1f, - 0xc0, - 0xe7, - 0x91, - 0xbb, - 0x06, - 0x00, - 0x2b, - 0xce, - 0x38, - 0x00, - 0xc0, - 0x1f, - 0xd0, - 0xeb, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x90, - 0xbb, - 0x06, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x29, - 0xe1, - 0x4f, - 0x2a, - 0xca, - 0xff, - 0x81, - 0x7f, - 0x2d, - 0xe1, - 0x4f, - 0x2b, - 0xca, - 0xfa, - 0xb8, - 0x06, - 0x00, - 0xfb, - 0xff, - 0xff, - 0x2d, - 0xe1, - 0xdf, - 0xab, - 0xfe, - 0x23, - 0xd3, - 0x38, - 0x00, - 0xc1, - 0x1d, - 0x00, - 0xf9, - 0x19, - 0xa1, - 0x06, - 0x00, - 0x78, - 0xff, - 0xff, - 0x29, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xfb, - 0xff, - 0xff, - 0x2b, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xe6, - 0x5c, - 0x02, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x19, - 0x19, - 0xfe, - 0x00, - 0xe1, - 0xcf, - 0x03, - 0xd7, - 0xfd, - 0xef, - 0xff, - 0x00, - 0xe1, - 0x98, - 0x8b, - 0xfe, - 0x4d, - 0xa0, - 0x06, - 0x00, - 0x6f, - 0xfa, - 0xff, - 0x2d, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0x19, - 0x19, - 0xfe, - 0x00, - 0xe1, - 0xd7, - 0xc3, - 0xd6, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x5b, - 0x8b, - 0xfe, - 0x6f, - 0xfa, - 0xff, - 0x2e, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0x4b, - 0xa0, - 0x06, - 0x00, - 0xff, - 0xf9, - 0x78, - 0x00, - 0xc1, - 0x9f, - 0xdb, - 0xeb, - 0xfd, - 0xff, - 0x38, - 0x00, - 0xc1, - 0x9f, - 0xdb, - 0xeb, - 0xd7, - 0xb8, - 0x06, - 0x00, - 0xef, - 0x5f, - 0x3f, - 0x00, - 0xa0, - 0x9f, - 0xc9, - 0xe7, - 0x67, - 0xfa, - 0xff, - 0x2f, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0x4a, - 0xa0, - 0x06, - 0x00, - 0xff, - 0xcd, - 0x78, - 0x00, - 0xa0, - 0xdf, - 0xcb, - 0xe7, - 0xff, - 0xcd, - 0x7f, - 0x2a, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x76, - 0x5e, - 0x39, - 0x00, - 0xc0, - 0x1f, - 0xd0, - 0xeb, - 0xf5, - 0xff, - 0xff, - 0x2e, - 0xe1, - 0x1f, - 0xe0, - 0xac, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xdd, - 0x7f, - 0x2f, - 0xe0, - 0xdf, - 0xab, - 0xff, - 0x76, - 0x5e, - 0x39, - 0x00, - 0xa0, - 0x1f, - 0xc0, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x30, - 0x5e, - 0x39, - 0x00, - 0xc0, - 0x1f, - 0xd0, - 0xeb, - 0xdf, - 0xff, - 0xff, - 0x2f, - 0xe0, - 0xdf, - 0xab, - 0xfa, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xee, - 0xff, - 0xff, - 0x00, - 0xe1, - 0xdd, - 0x0b, - 0xf9, - 0xf7, - 0xff, - 0xff, - 0x2f, - 0xe1, - 0x0f, - 0x20, - 0xcb, - 0x93, - 0xbf, - 0x06, - 0x00, - 0x6f, - 0xfa, - 0xff, - 0x2e, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0xdf, - 0x78, - 0x00, - 0xa1, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xd1, - 0x7f, - 0x28, - 0xe0, - 0x1f, - 0x6b, - 0xf1, - 0x67, - 0xd1, - 0x3a, - 0x00, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0x33, - 0xa1, - 0x06, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x32, - 0xa1, - 0x06, - 0x00, - 0xf8, - 0xff, - 0xff, - 0x00, - 0xe1, - 0x9d, - 0x0b, - 0xf9, - 0xfe, - 0xff, - 0xff, - 0x00, - 0xe1, - 0xcf, - 0x43, - 0xd7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x2b, - 0xce, - 0x38, - 0x00, - 0xa0, - 0x1f, - 0xc0, - 0xe7, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x94, - 0x5b, - 0x02, - 0x00, - 0x57, - 0xdc, - 0x38, - 0x00, - 0xc0, - 0xdf, - 0xdb, - 0xeb, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x98, - 0x5b, - 0x06, - 0x00, - 0xfe, - 0xef, - 0xff, - 0x00, - 0xe1, - 0x98, - 0x8b, - 0xfe, - 0x47, - 0xff, - 0xff, - 0x2d, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0x2b, - 0xb2, - 0x06, - 0x00, - 0x41, - 0x19, - 0xfe, - 0x00, - 0xe1, - 0xd7, - 0xc3, - 0xd6, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xff, - 0x7f, - 0x3f, - 0xe1, - 0x17, - 0xe0, - 0xca, - 0xff, - 0xf9, - 0x7f, - 0x3c, - 0xe1, - 0x17, - 0xe0, - 0xca, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7a, - 0x2c, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xf7, - 0xdf, - 0x3a, - 0x2c, - 0xc0, - 0x9f, - 0xdb, - 0xeb, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xff, - 0xff, - 0x00, - 0xe1, - 0xdd, - 0x0b, - 0xf9, - 0xfe, - 0xff, - 0xff, - 0x2d, - 0xe1, - 0x4b, - 0x6b, - 0xcb, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x5b, - 0x7f, - 0x00, - 0xa0, - 0x9f, - 0xc9, - 0xe7, - 0xe7, - 0xff, - 0xff, - 0x26, - 0xe0, - 0x9f, - 0xe9, - 0xff, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xf4, - 0xff, - 0xff, - 0x00, - 0xe1, - 0xd7, - 0xc3, - 0xd6, - 0x77, - 0x5e, - 0x3f, - 0x00, - 0xa0, - 0x9f, - 0xc9, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xff, - 0xbf, - 0x2d, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0x0f, - 0xff, - 0xfe, - 0xff, - 0xff, - 0xff, - 0xcf, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0xdb, - 0x7f, - 0x2d, - 0xe0, - 0xdf, - 0x6b, - 0xf1, - 0xcc, - 0xff, - 0xff, - 0x2b, - 0xe0, - 0x1f, - 0xe0, - 0xac, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xe0, - 0xff, - 0xff, - 0x28, - 0xe1, - 0x1f, - 0xe0, - 0xac, - 0xff, - 0xd7, - 0x7f, - 0x2d, - 0xe0, - 0x5f, - 0xab, - 0xff, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xf7, - 0xdb, - 0x3a, - 0x2c, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0xd1, - 0x7a, - 0x2c, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x00, - 0x00, - 0xfe, - 0x2b, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0x00, - 0x00, - 0xfe, - 0x2d, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0x45, - 0x9d, - 0x06, - 0x00, - 0x00, - 0x00, - 0xbf, - 0x2a, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0x00, - 0x80, - 0xff, - 0x7f, - 0x80, - 0x3e, - 0xce, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x9f, - 0xbf, - 0x2a, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0x5d, - 0xff, - 0xff, - 0xff, - 0xff, - 0xcf, - 0xbf, - 0x45, - 0x3d, - 0x06, - 0x00, - 0xb0, - 0xff, - 0xff, - 0x2b, - 0xe0, - 0x1f, - 0xe0, - 0xe7, - 0xc0, - 0xff, - 0xff, - 0x2a, - 0xe0, - 0x1f, - 0xe0, - 0xac, - 0x45, - 0x3d, - 0x06, - 0x00, - 0x67, - 0xfa, - 0xff, - 0x2f, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0xd5, - 0x78, - 0x00, - 0xc0, - 0xdf, - 0xdb, - 0xeb, - 0xff, - 0xbf, - 0x07, - 0x00, - 0x5f, - 0x5e, - 0x3f, - 0x00, - 0xc0, - 0x9f, - 0xda, - 0xeb, - 0xdf, - 0xfb, - 0xff, - 0x2c, - 0xe1, - 0x1f, - 0xe0, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xf7, - 0xdf, - 0x3a, - 0x2c, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0xd1, - 0x7a, - 0x2c, - 0xa0, - 0x9f, - 0xcb, - 0xe7, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xf7, - 0x5f, - 0x3f, - 0x00, - 0xc0, - 0x9f, - 0xda, - 0xeb, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0x43, - 0x5a, - 0x06, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0x81, - 0x7f, - 0x00, - 0xe1, - 0x1f, - 0xc0, - 0xbf, - 0xff, - 0xbf, - 0x07, - 0x00, - 0xc6, - 0x9c, - 0xc0, - 0x30, - 0x51, - 0x9c, - 0x16, - 0x99, - 0xb1, - 0x07, - 0xa3, - 0x18, - 0xeb, - 0x9c, - 0xf3, - 0x3e, - 0x48, - 0xcf, - 0x1f, - 0xc7, - 0xba, - 0x80, - 0xa7, - 0x9c, - 0x01, - 0x99, - 0xe3, - 0xd8, - 0xa3, - 0xb5, - 0xef, - 0xca, - 0x0e, - 0x43, - 0x9c, - 0xc4, - 0x4c, - 0xa5, - 0x9d, - 0xa0, - 0x33, - 0x4e, - 0xdd, - 0xdf, - 0x14, - 0x59, - 0x8d, - 0x04, - 0xfc, - 0x03, - 0x71, - 0xc7, - 0xd2, - 0x99, - 0xb6, - 0x9d, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, + 0x18, 0x20, 0x09, 0x02, 0x10, 0x01, 0x00, 0x07, + 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x70, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, + 0x8d, 0xf8, 0xbc, 0xa3, 0x4b, 0xbd, 0x3d, 0x48, + 0xdf, 0x1a, 0xc9, 0xae, 0x9f, 0x15, 0xac, 0x70, + 0xbb, 0xa6, 0x17, 0x65, 0xed, 0x9c, 0xd1, 0xba, + 0x03, 0x77, 0x30, 0x74, 0x56, 0x31, 0x78, 0x9c, + 0xcd, 0xe5, 0x2c, 0xac, 0x05, 0xc5, 0xa4, 0x7e, + 0x03, 0x17, 0x55, 0xc2, 0x19, 0x65, 0x4d, 0x55, + 0x30, 0xde, 0xad, 0x51, 0x79, 0x99, 0xd5, 0x29, + 0xbf, 0x74, 0x24, 0xc6, 0xbb, 0x98, 0xd2, 0x1d, + 0x15, 0x37, 0xd1, 0x5b, 0xb7, 0xef, 0x76, 0xba, + 0x8a, 0xff, 0xa8, 0x01, 0x38, 0xe6, 0x6a, 0x4c, + 0x6e, 0x78, 0x36, 0x21, 0x60, 0xa4, 0xca, 0x6d, + 0xeb, 0xaf, 0xfe, 0x13, 0x3b, 0x20, 0x2b, 0x96, + 0x9d, 0x79, 0xde, 0x59, 0xf0, 0xa1, 0x24, 0x8b, + 0xb1, 0x2f, 0x9d, 0x38, 0x55, 0xfb, 0x0d, 0x2d, + 0x6a, 0xec, 0xf8, 0xcc, 0xf9, 0x1a, 0xda, 0xb9, + 0xe1, 0xca, 0x33, 0x28, 0xcd, 0x2a, 0x4f, 0x54, + 0x95, 0x4f, 0x94, 0x23, 0x2f, 0xc1, 0x5e, 0xbd, + 0xf0, 0xd3, 0xfb, 0x0f, 0x82, 0xf2, 0x00, 0xa3, + 0xe8, 0x60, 0xf1, 0x84, 0x05, 0x2c, 0xc3, 0xdd, + 0x70, 0xa1, 0xbc, 0x74, 0xbb, 0xf6, 0xde, 0x06, + 0x20, 0xd3, 0x56, 0x26, 0x67, 0x39, 0x8a, 0xee, + 0xdf, 0xc8, 0x6b, 0xc9, 0xf5, 0x3b, 0x28, 0x23, + 0x85, 0x10, 0xd7, 0x49, 0x0a, 0x58, 0x6f, 0xca, + 0x94, 0x88, 0xb3, 0xd0, 0x34, 0x24, 0x47, 0x78, + 0xce, 0x4c, 0xc3, 0xf1, 0xc2, 0x15, 0x24, 0x25, + 0xe7, 0xff, 0x9a, 0x66, 0x21, 0xad, 0x91, 0x25, + 0x8b, 0xc6, 0x68, 0xac, 0x3c, 0x68, 0xb3, 0xc5, + 0x45, 0xa0, 0x97, 0xb4, 0x9b, 0xdc, 0x73, 0xec, + 0x29, 0x67, 0x73, 0x38, 0x80, 0x85, 0x03, 0xd1, + 0x4a, 0xe3, 0x48, 0x93, 0x9d, 0x3c, 0x11, 0xac, + 0xc0, 0x35, 0xfa, 0xac, 0x1d, 0x68, 0x86, 0xee, + 0xab, 0x70, 0xa8, 0xe7, 0xb3, 0x87, 0xcb, 0x9f, + 0x5b, 0x2a, 0x58, 0x44, 0x53, 0xdf, 0x59, 0xbc, + 0x14, 0xe3, 0x7f, 0xd6, 0x4a, 0xd6, 0x98, 0x59, + 0x8c, 0xbb, 0xce, 0xe6, 0x86, 0xdb, 0x66, 0xbd, + 0xeb, 0x51, 0xf1, 0xce, 0x80, 0x0f, 0xd9, 0x83, + 0x86, 0x17, 0xed, 0x78, 0x3e, 0x5d, 0xac, 0xd1, + 0x13, 0xfa, 0x01, 0x58, 0x35, 0xe9, 0x66, 0x16, + 0x5d, 0xa8, 0x70, 0x08, 0x0e, 0xa3, 0xab, 0x3b, + 0xd1, 0x75, 0xbf, 0x2f, 0xb2, 0x9a, 0x7c, 0xd8, + 0x84, 0x66, 0x1a, 0x07, 0x00, 0xe0, 0x04, 0xbf, + 0x0e, 0x04, 0xaa, 0x0e, 0x91, 0x6f, 0xb4, 0xb8, + 0xff, 0xfa, 0xad, 0xb0, 0xd8, 0x41, 0x65, 0xf5, + 0xd5, 0x0d, 0x12, 0x15, 0xbf, 0x40, 0x5b, 0xed, + 0xeb, 0x81, 0x2a, 0x1f, 0x48, 0x00, 0x5b, 0xf7, + 0x08, 0x35, 0x86, 0x8d, 0xe4, 0x15, 0x52, 0x40, + 0x1b, 0x88, 0x5a, 0x8f, 0xd0, 0x4f, 0xb5, 0xbc, + 0xdb, 0x45, 0x30, 0xc5, 0x89, 0x32, 0x98, 0xf9, + 0xa7, 0x18, 0x27, 0xf1, 0x0b, 0xc7, 0x6d, 0xeb, + 0x7f, 0x39, 0xd2, 0x25, 0x99, 0x6d, 0x3a, 0x1b, + 0x24, 0xa4, 0xc5, 0x7c, 0xdf, 0x33, 0x3d, 0x7c, + 0x43, 0x40, 0x5b, 0x8d, 0xd1, 0xec, 0x0c, 0xca, + 0x76, 0xd9, 0x1a, 0x32, 0xee, 0x45, 0xee, 0xb6, + 0x30, 0x21, 0xf8, 0x66, 0xb5, 0xbf, 0xfb, 0x66, + 0x13, 0x9c, 0xf0, 0xcf, 0xae, 0xca, 0x54, 0xbc, + 0xf1, 0xce, 0x76, 0x57, 0x8d, 0xf5, 0xee, 0x02, + 0x14, 0xc0, 0x62, 0x3f, 0xa1, 0xad, 0x9d, 0xbb, + 0x83, 0x3d, 0x8f, 0xf2, 0xe9, 0x41, 0x42, 0xca, + 0x04, 0xf9, 0xf7, 0x4f, 0xf7, 0xc6, 0x77, 0xf0, + 0x0e, 0x8c, 0xea, 0xb6, 0x6c, 0x47, 0xae, 0xd1, + 0x1b, 0x2c, 0x89, 0xbf, 0x4b, 0x61, 0xdc, 0x2d, + 0x06, 0x6d, 0x79, 0x5c, 0x5e, 0x82, 0xc0, 0x4f, + 0x54, 0x5d, 0x68, 0x55, 0x5b, 0x1c, 0x75, 0xb6, + 0xcc, 0x4b, 0xb6, 0x3e, 0x2b, 0xec, 0x30, 0xa7, + 0x62, 0xc1, 0xdd, 0xd4, 0x52, 0xd8, 0x81, 0xe9, + 0xbb, 0xd6, 0x60, 0xc8, 0x51, 0xdb, 0x56, 0xa1, + 0x90, 0x42, 0xbe, 0xd3, 0xe3, 0xb5, 0x38, 0x38, + 0xad, 0x41, 0x34, 0x2f, 0xf5, 0xdc, 0x13, 0x97, + 0x88, 0x24, 0xa2, 0x81, 0xc0, 0x4a, 0x65, 0x51, + 0x36, 0x52, 0x81, 0x96, 0x13, 0x55, 0x7a, 0x07, + 0x8d, 0x6a, 0xb5, 0xcb, 0xf1, 0x93, 0xf1, 0x2f, + 0x7a, 0x00, 0x3c, 0xa9, 0xc4, 0xfb, 0x77, 0xf9, + 0x01, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x07, + 0xe2, 0x13, 0xe7, 0x13, 0x93, 0x07, 0x66, 0x04, + 0x60, 0x04, 0xd7, 0x19, 0x04, 0x07, 0xda, 0x09, + 0x4f, 0x15, 0x20, 0x07, 0xe3, 0x16, 0xd6, 0x06, + 0x27, 0x0d, 0x56, 0x06, 0xf4, 0x10, 0x34, 0x1a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6f, 0xd7, 0x3a, 0x00, 0xc0, 0x9f, 0xdb, 0xeb, + 0xff, 0x57, 0x7f, 0x29, 0xa0, 0x9f, 0xc9, 0xe7, + 0x52, 0xa0, 0x06, 0x00, 0x67, 0xd9, 0x3a, 0x00, + 0xc0, 0x9f, 0xdb, 0xeb, 0xc0, 0xff, 0xff, 0x28, + 0xe0, 0x1f, 0xe0, 0xac, 0xff, 0xbf, 0x07, 0x00, + 0x67, 0xd9, 0x3a, 0x00, 0xa0, 0x9f, 0xcb, 0xe7, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x17, 0xac, 0x06, 0x00, 0x9d, 0xf1, 0xef, 0x2b, + 0xe1, 0x1f, 0xe0, 0xe7, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0x16, 0xac, 0x06, 0x00, + 0xf9, 0xff, 0xff, 0x2d, 0xe1, 0x9f, 0xaf, 0xfe, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x6b, 0xb8, 0x06, 0x00, 0xf5, 0xff, 0xff, 0x28, + 0xe1, 0x9f, 0xaf, 0xfe, 0x90, 0xff, 0xff, 0x29, + 0xe1, 0x1f, 0xe0, 0xe7, 0xff, 0xbf, 0x07, 0x00, + 0xdf, 0xff, 0xff, 0x2e, 0xe0, 0x1f, 0xab, 0xfa, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x9d, 0x4b, 0xe1, + 0x50, 0xa0, 0x06, 0x00, 0xd6, 0xff, 0xff, 0x00, + 0xe1, 0xcf, 0x43, 0xd7, 0x70, 0x5c, 0x39, 0x00, + 0xc0, 0x1f, 0xd0, 0xeb, 0xff, 0xbf, 0x07, 0x00, + 0xa3, 0xdb, 0x38, 0x00, 0xc1, 0xdf, 0xd9, 0xeb, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xd7, 0xb8, 0x06, 0x00, 0x00, 0xff, 0xff, 0x3c, + 0xe1, 0x5f, 0xeb, 0xfe, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xdd, 0x7f, 0x2c, 0xe0, 0x0f, 0x6b, 0xff, + 0x4b, 0xd8, 0x38, 0x00, 0xa0, 0x1f, 0xc0, 0xe7, + 0x91, 0xbb, 0x06, 0x00, 0x2b, 0xce, 0x38, 0x00, + 0xc0, 0x1f, 0xd0, 0xeb, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0x90, 0xbb, 0x06, 0x00, + 0xff, 0x81, 0x7f, 0x29, 0xe1, 0x4f, 0x2a, 0xca, + 0xff, 0x81, 0x7f, 0x2d, 0xe1, 0x4f, 0x2b, 0xca, + 0xfa, 0xb8, 0x06, 0x00, 0xfb, 0xff, 0xff, 0x2d, + 0xe1, 0xdf, 0xab, 0xfe, 0x23, 0xd3, 0x38, 0x00, + 0xc1, 0x1d, 0x00, 0xf9, 0x19, 0xa1, 0x06, 0x00, + 0x78, 0xff, 0xff, 0x29, 0xe1, 0x1f, 0xe0, 0xe7, + 0xfb, 0xff, 0xff, 0x2b, 0xe1, 0x1f, 0xe0, 0xe7, + 0xe6, 0x5c, 0x02, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0x19, 0x19, 0xfe, 0x00, 0xe1, 0xcf, 0x03, 0xd7, + 0xfd, 0xef, 0xff, 0x00, 0xe1, 0x98, 0x8b, 0xfe, + 0x4d, 0xa0, 0x06, 0x00, 0x6f, 0xfa, 0xff, 0x2d, + 0xe1, 0x1f, 0xe0, 0xe7, 0x19, 0x19, 0xfe, 0x00, + 0xe1, 0xd7, 0xc3, 0xd6, 0xff, 0xbf, 0x07, 0x00, + 0xad, 0xff, 0xff, 0x00, 0xe1, 0xd7, 0xc3, 0xd6, + 0xf2, 0xff, 0xff, 0x00, 0xe1, 0x1b, 0x8b, 0xfe, + 0x18, 0xa0, 0x06, 0x00, 0x62, 0x18, 0xfe, 0x00, + 0xe1, 0xd7, 0xc3, 0xd6, 0xfe, 0xff, 0xff, 0x2f, + 0xe1, 0x1f, 0xeb, 0xfb, 0xff, 0xbf, 0x07, 0x00, + 0xef, 0x5f, 0x3f, 0x00, 0xa0, 0x9f, 0xc9, 0xe7, + 0x67, 0xfa, 0xff, 0x2f, 0xe1, 0x1f, 0xe0, 0xe7, + 0x4a, 0xa0, 0x06, 0x00, 0xff, 0xcd, 0x78, 0x00, + 0xa0, 0xdf, 0xcb, 0xe7, 0xff, 0xcd, 0x7f, 0x2a, + 0xe0, 0x1f, 0xe0, 0xe7, 0xff, 0xbf, 0x07, 0x00, + 0xfc, 0xff, 0xff, 0x2f, 0xe1, 0x1f, 0xe0, 0xe7, + 0xff, 0x81, 0x7f, 0x27, 0xe1, 0x1f, 0xe0, 0xe7, + 0x3a, 0x20, 0x06, 0x00, 0xf4, 0x5c, 0x39, 0x00, + 0xc0, 0x1f, 0xd0, 0xeb, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0x26, 0x40, 0x06, 0x00, + 0xfc, 0xff, 0xff, 0x2f, 0xe1, 0x1f, 0xe0, 0xe7, + 0xff, 0x81, 0x7f, 0x27, 0xe1, 0x1f, 0xe0, 0xe7, + 0x3a, 0x20, 0x06, 0x00, 0xf4, 0x52, 0x39, 0x00, + 0xc0, 0x1f, 0xd0, 0xeb, 0xff, 0xfe, 0xff, 0x2f, + 0xe1, 0x5f, 0x6a, 0xf1, 0x21, 0x40, 0x06, 0x00, + 0x1f, 0xff, 0xff, 0x2e, 0xe1, 0x1f, 0xe0, 0xe7, + 0xf5, 0x5f, 0x3f, 0xae, 0xc1, 0x5f, 0xda, 0xeb, + 0x1d, 0xa0, 0x06, 0x00, 0x00, 0xff, 0xff, 0x80, + 0xe1, 0xdb, 0x8b, 0xfe, 0xa4, 0x0e, 0xfe, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xff, 0xbf, 0x07, 0x00, + 0x9b, 0x80, 0x38, 0x00, 0x81, 0x1b, 0x80, 0xff, + 0xc8, 0x11, 0xfe, 0x00, 0xe1, 0xd7, 0xc3, 0xd6, + 0x93, 0x5f, 0x06, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0x47, 0xff, 0xff, 0x2d, 0xe1, 0x1f, 0xe0, 0xe7, + 0x2c, 0x19, 0xfe, 0x00, 0xe1, 0xd7, 0xc3, 0xd6, + 0x03, 0x24, 0x06, 0x00, 0xb6, 0xff, 0xff, 0x00, + 0xe1, 0x98, 0x8f, 0xfe, 0xb7, 0xff, 0xff, 0x00, + 0xe1, 0xd7, 0xc3, 0xd6, 0xca, 0x45, 0x06, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0x76, 0x5e, 0x39, 0x00, 0xc0, 0x1f, 0xd0, 0xeb, + 0xf5, 0xff, 0xff, 0x2e, 0xe1, 0x1f, 0xe0, 0xac, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0xdd, 0x7f, 0x2f, + 0xe0, 0xdf, 0xab, 0xff, 0x76, 0x5e, 0x39, 0x00, + 0xa0, 0x1f, 0xc0, 0xe7, 0xff, 0xbf, 0x07, 0x00, + 0x30, 0x5e, 0x39, 0x00, 0xc0, 0x1f, 0xd0, 0xeb, + 0xdf, 0xff, 0xff, 0x2f, 0xe0, 0xdf, 0xab, 0xfa, + 0xff, 0xbf, 0x07, 0x00, 0xee, 0xff, 0xff, 0x00, + 0xe1, 0xdd, 0x0b, 0xf9, 0xf7, 0xff, 0xff, 0x2f, + 0xe1, 0x0f, 0x20, 0xcb, 0x93, 0xbf, 0x06, 0x00, + 0x6f, 0xfa, 0xff, 0x2e, 0xe1, 0x1f, 0xe0, 0xe7, + 0xff, 0xdf, 0x78, 0x00, 0xa1, 0x9f, 0xcb, 0xe7, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0xd1, 0x7f, 0x28, + 0xe0, 0x1f, 0x6b, 0xf1, 0x67, 0xd1, 0x3a, 0x00, + 0xa0, 0x9f, 0xcb, 0xe7, 0x33, 0xa1, 0x06, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x32, 0xa1, 0x06, 0x00, 0xf8, 0xff, 0xff, 0x00, + 0xe1, 0x9d, 0x0b, 0xf9, 0xfe, 0xff, 0xff, 0x00, + 0xe1, 0xcf, 0x43, 0xd7, 0xff, 0xbf, 0x07, 0x00, + 0x2b, 0xce, 0x38, 0x00, 0xa0, 0x1f, 0xc0, 0xe7, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x94, 0x5b, 0x02, 0x00, 0x57, 0xdc, 0x38, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0x98, 0x5b, 0x06, 0x00, + 0xfe, 0xef, 0xff, 0x00, 0xe1, 0x98, 0x8b, 0xfe, + 0x47, 0xff, 0xff, 0x2d, 0xe1, 0x1f, 0xe0, 0xe7, + 0x2b, 0xb2, 0x06, 0x00, 0x41, 0x19, 0xfe, 0x00, + 0xe1, 0xd7, 0xc3, 0xd6, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xff, 0x7f, 0x3f, 0xe1, 0x17, 0xe0, 0xca, + 0xff, 0xf9, 0x7f, 0x3c, 0xe1, 0x17, 0xe0, 0xca, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7a, 0x2c, + 0xa0, 0x9f, 0xcb, 0xe7, 0xf7, 0xdf, 0x3a, 0x2c, + 0xc0, 0x9f, 0xdb, 0xeb, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xff, 0xff, 0x00, 0xe1, 0xdd, 0x0b, 0xf9, + 0xfe, 0xff, 0xff, 0x2d, 0xe1, 0x4b, 0x6b, 0xcb, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x5b, 0x7f, 0x00, + 0xa0, 0x9f, 0xc9, 0xe7, 0xe7, 0xff, 0xff, 0x26, + 0xe0, 0x9f, 0xe9, 0xff, 0xff, 0xbf, 0x07, 0x00, + 0xf4, 0xff, 0xff, 0x00, 0xe1, 0xd7, 0xc3, 0xd6, + 0x77, 0x5e, 0x3f, 0x00, 0xa0, 0x9f, 0xc9, 0xe7, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0xff, 0xbf, 0x2d, + 0xe0, 0x1f, 0xe0, 0xe7, 0x0f, 0xff, 0xfe, 0xff, + 0xff, 0xff, 0xcf, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xdb, 0x7f, 0x2d, 0xe0, 0xdf, 0x6b, 0xf1, + 0xcc, 0xff, 0xff, 0x2b, 0xe0, 0x1f, 0xe0, 0xac, + 0xff, 0xbf, 0x07, 0x00, 0xe0, 0xff, 0xff, 0x28, + 0xe1, 0x1f, 0xe0, 0xac, 0xff, 0xd7, 0x7f, 0x2d, + 0xe0, 0x5f, 0xab, 0xff, 0xff, 0xbf, 0x07, 0x00, + 0xf7, 0xdb, 0x3a, 0x2c, 0xa0, 0x9f, 0xcb, 0xe7, + 0xff, 0xd1, 0x7a, 0x2c, 0xa0, 0x9f, 0xcb, 0xe7, + 0xff, 0xbf, 0x07, 0x00, 0x00, 0x00, 0xfe, 0x2b, + 0xe0, 0x1f, 0xe0, 0xe7, 0x00, 0x00, 0xfe, 0x2d, + 0xe0, 0x1f, 0xe0, 0xe7, 0x45, 0x9d, 0x06, 0x00, + 0x00, 0x00, 0xbf, 0x2a, 0xe0, 0x1f, 0xe0, 0xe7, + 0x00, 0x80, 0xff, 0x7f, 0x80, 0x3e, 0xce, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x9f, 0xbf, 0x2a, + 0xe0, 0x1f, 0xe0, 0xe7, 0xff, 0x5d, 0xff, 0xff, + 0xff, 0xff, 0xcf, 0xbf, 0x45, 0x3d, 0x06, 0x00, + 0xb0, 0xff, 0xff, 0x2b, 0xe0, 0x1f, 0xe0, 0xe7, + 0xc0, 0xff, 0xff, 0x2a, 0xe0, 0x1f, 0xe0, 0xac, + 0x45, 0x3d, 0x06, 0x00, 0x67, 0xfa, 0xff, 0x2f, + 0xe1, 0x1f, 0xe0, 0xe7, 0xff, 0xd5, 0x78, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xff, 0xbf, 0x07, 0x00, + 0x5f, 0x5e, 0x3f, 0x00, 0xc0, 0x9f, 0xda, 0xeb, + 0xdf, 0xfb, 0xff, 0x2c, 0xe1, 0x1f, 0xe0, 0xe7, + 0xff, 0xbf, 0x07, 0x00, 0xf7, 0xdf, 0x3a, 0x2c, + 0xa0, 0x9f, 0xcb, 0xe7, 0xff, 0xd1, 0x7a, 0x2c, + 0xa0, 0x9f, 0xcb, 0xe7, 0xff, 0xbf, 0x07, 0x00, + 0xf7, 0x5f, 0x3f, 0x00, 0xc0, 0x9f, 0xda, 0xeb, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x43, 0x5a, 0x06, 0x00, 0xcf, 0x53, 0x39, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xfe, 0xff, 0xff, 0x27, + 0xe1, 0xdf, 0xe9, 0xfa, 0xff, 0xbf, 0x07, 0x00, + 0x89, 0xff, 0xff, 0xc0, 0xe1, 0x5b, 0x8a, 0xfe, + 0xf2, 0xff, 0xff, 0x00, 0xe1, 0xd7, 0x83, 0xd6, + 0xff, 0xbf, 0x07, 0x00, 0xe9, 0xff, 0xff, 0x00, + 0xe1, 0x5d, 0x0a, 0xf9, 0xf3, 0xff, 0xff, 0x00, + 0xe1, 0xcf, 0x03, 0xd7, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xff, 0xbf, 0x29, 0xe0, 0x5f, 0x6a, 0xf1, + 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xcf, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xfe, 0xff, 0xff, 0x27, + 0xe1, 0xdf, 0xa9, 0xff, 0xcb, 0x5b, 0x39, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xff, 0xbf, 0x07, 0x00, + 0xcf, 0x53, 0x39, 0x00, 0xa0, 0xdf, 0xcb, 0xe7, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x03, 0x00, 0xcb, 0x59, 0x39, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xff, 0xdb, 0x7f, 0x00, + 0xe0, 0x1d, 0x8b, 0xfe, 0xff, 0xbf, 0x03, 0x00, + 0xf8, 0xff, 0xff, 0x00, 0xe1, 0xcf, 0x03, 0xd7, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1b, 0x8b, 0xfe, + 0xff, 0xbf, 0x07, 0x00, 0xf9, 0xff, 0xff, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xdf, 0xff, 0xff, 0x2d, + 0xe0, 0x5f, 0xab, 0xfa, 0xff, 0xbf, 0x07, 0x00, + 0xdf, 0xff, 0xff, 0x2c, 0xe0, 0x1f, 0xab, 0xfa, + 0xff, 0xd9, 0x7f, 0x00, 0xe1, 0x5b, 0x8b, 0xfe, + 0xff, 0xbf, 0x07, 0x00, 0xfb, 0xff, 0xff, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xfe, 0xff, 0xff, 0xac, + 0xe1, 0x1b, 0xeb, 0xff, 0xff, 0xbf, 0x07, 0x00, + 0xdf, 0xff, 0xff, 0x2c, 0xe0, 0x1f, 0xeb, 0xfa, + 0x00, 0x00, 0xfe, 0x2c, 0xe0, 0x17, 0xeb, 0xca, + 0xff, 0xbf, 0x07, 0x00, 0xcb, 0x59, 0x39, 0x00, + 0xa0, 0xdf, 0xcb, 0xe7, 0xfd, 0xff, 0xff, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xff, 0xbf, 0x07, 0x00, + 0xe9, 0xff, 0xff, 0x2d, 0xe1, 0x1f, 0xe0, 0xac, + 0xff, 0xdb, 0x7f, 0x29, 0xe0, 0x5f, 0xaa, 0xff, + 0x35, 0xa0, 0x06, 0x00, 0xcf, 0x53, 0x39, 0x00, + 0xa0, 0xdf, 0xcb, 0xe7, 0xff, 0xdb, 0x7f, 0x29, + 0xe0, 0x5f, 0x6a, 0xf1, 0x2b, 0xa0, 0x06, 0x00, + 0xfe, 0xff, 0xff, 0x2f, 0xe1, 0xdd, 0xab, 0xfe, + 0x7e, 0x11, 0xfe, 0x00, 0xe1, 0xcf, 0x43, 0xd7, + 0x3a, 0x40, 0x06, 0x00, 0xfe, 0xff, 0xff, 0x27, + 0xe1, 0xdd, 0xe9, 0xfa, 0xcf, 0x59, 0x39, 0x00, + 0xc0, 0xdf, 0xdb, 0xeb, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0xff, 0xbf, 0x2c, 0xe0, 0x0f, 0x6b, 0xdf, + 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xcf, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xcf, 0x59, 0x39, 0x00, + 0xa0, 0xdf, 0xcb, 0xe7, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0x2a, 0xa0, 0x06, 0x00, + 0xfe, 0xff, 0xff, 0x2f, 0xe1, 0xdd, 0xab, 0xfe, + 0x82, 0x11, 0xfe, 0x00, 0xe1, 0xcf, 0x43, 0xd7, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0xfe, 0xff, 0x2f, + 0xe1, 0x9f, 0x6b, 0xf1, 0xf4, 0x5e, 0x39, 0x00, + 0xa0, 0x1f, 0xc0, 0xe7, 0xfd, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0x9b, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x03, 0x00, 0xf4, 0x5c, 0x39, 0x00, + 0xa0, 0x1f, 0xc0, 0xe7, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xfd, 0xbf, 0x07, 0x00, + 0xfc, 0xff, 0xff, 0x2f, 0xe1, 0x1f, 0xe0, 0xe7, + 0xe3, 0xff, 0xff, 0x27, 0xe1, 0xdf, 0xe9, 0xfa, + 0x2a, 0x20, 0x06, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xc5, 0x43, 0x06, 0x00, + 0xf4, 0x5e, 0x39, 0x00, 0xa0, 0x1f, 0xc0, 0xe7, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0x9b, + 0xff, 0xbf, 0x03, 0x00, 0xf4, 0x52, 0x39, 0x00, + 0xa0, 0x1f, 0xc0, 0xe7, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xfd, 0xbf, 0x07, 0x00, + 0xfc, 0xff, 0xff, 0x2f, 0xe1, 0x1f, 0xe0, 0xe7, + 0xe3, 0xff, 0xff, 0x27, 0xe1, 0xdf, 0xe9, 0xfa, + 0x2a, 0x20, 0x06, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xd5, 0x52, 0x06, 0x00, + 0xfd, 0x5f, 0x3f, 0x2e, 0xc0, 0x5f, 0xda, 0xeb, + 0xfe, 0xff, 0xff, 0x00, 0xe0, 0xdb, 0xcb, 0xff, + 0xff, 0xbf, 0x07, 0x00, 0xec, 0x0e, 0xfe, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xf7, 0xff, 0xff, 0x2e, + 0xe1, 0x9d, 0xab, 0xfe, 0x1d, 0xa0, 0x06, 0x00, + 0x13, 0xff, 0xff, 0x2a, 0xe1, 0x1f, 0xe0, 0xe7, + 0x05, 0x0f, 0xfe, 0x00, 0xe1, 0xcf, 0x43, 0xd7, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x5b, 0x8b, 0xfe, 0x6f, 0xfa, 0xff, 0x2e, + 0xe1, 0x1f, 0xe0, 0xe7, 0x4b, 0xa0, 0x06, 0x00, + 0xff, 0xf9, 0x78, 0x00, 0xc1, 0x9f, 0xdb, 0xeb, + 0xfd, 0xff, 0x38, 0x00, 0xc1, 0x9f, 0xdb, 0xeb, + 0xd7, 0xb8, 0x06, 0x00, 0xee, 0xff, 0xff, 0x00, + 0xe1, 0xda, 0x8b, 0xfe, 0xff, 0xef, 0xff, 0x3c, + 0xe1, 0x17, 0xe0, 0xca, 0xc8, 0x58, 0x06, 0x00, + 0x9b, 0x80, 0x38, 0x00, 0xc1, 0x1d, 0xc0, 0xf3, + 0xff, 0x81, 0x7f, 0x00, 0xe0, 0x0c, 0x0b, 0xf9, + 0xff, 0xbf, 0x07, 0x00, 0x15, 0x12, 0xfe, 0x00, + 0xe1, 0xd7, 0x83, 0xd6, 0xff, 0xff, 0xff, 0x00, + 0xe1, 0xcf, 0x43, 0xd7, 0x93, 0x5f, 0x06, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xc3, 0x21, 0x06, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0x9b, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xfd, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0x93, 0x5f, 0x06, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0x81, 0x7f, 0x00, 0xe1, 0x1f, 0xc0, 0xbf, + 0xff, 0xbf, 0x07, 0x00, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0x81, 0x7f, 0x00, + 0xe1, 0x1f, 0xc0, 0xbf, 0xff, 0xbf, 0x07, 0x00, + 0x18, 0xa0, 0xba, 0x3a, 0x3f, 0x95, 0x1c, 0x69, + 0x42, 0xac, 0xed, 0xda, 0x47, 0xb4, 0xfd, 0xc8, + 0x19, 0xf5, 0x85, 0x69, 0x6a, 0x82, 0x3b, 0xce, + 0x6e, 0x7d, 0x01, 0x4e, 0x1e, 0x5b, 0x92, 0x6c, + 0xed, 0x73, 0x65, 0xe1, 0xdf, 0xfb, 0x8e, 0x8b, + 0x5d, 0x35, 0x65, 0x6f, 0xe8, 0x1a, 0xdf, 0xc7, + 0xeb, 0xd3, 0xd6, 0x0c, 0xee, 0xfe, 0x34, 0x1f, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 }; /*---------------------------------------------------------------------------------------- From 334e8360efb03644488ce4ac8a9a9e75ef6fa6c0 Mon Sep 17 00:00:00 2001 From: Mike Banon Date: Thu, 23 Aug 2018 00:50:08 +0300 Subject: [PATCH 364/588] src/vendorcode/amd/agesa/f15tn: Update microcode to version 0x600111F 2018-03-05 This microcode update for CPU IDs 0x610F01/0x610F31 improves system stability: in particular, fixes Xen hardware virtualization freezes. Also it attempts to patch some Spectre-related security vulnerabilities. This new microcode has been tested by multiple coreboot community members and found working perfectly. Old version: 0x600110F [2012-01-11] replaced by New version: 0x600111F [2018-03-05] Change-Id: Ied5da0ff85abb63c2db2eeafd051b8e00916d961 Signed-off-by: Mike Banon Reviewed-on: https://review.coreboot.org/c/coreboot/+/28273 Reviewed-by: Martin Roth Reviewed-by: Tested-by: build bot (Jenkins) --- .../f15tn/Config/OptionFamily15hInstall.h | 4 +- .../0x15/TN/F15TnMicrocodePatch0600110F_Enc.c | 2673 ----------------- .../0x15/TN/F15TnMicrocodePatch0600111F_Enc.c | 405 +++ .../Proc/CPU/Family/0x15/TN/Makefile.inc | 2 +- 4 files changed, 408 insertions(+), 2676 deletions(-) delete mode 100644 src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600110F_Enc.c create mode 100644 src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600111F_Enc.c diff --git a/src/vendorcode/amd/agesa/f15tn/Config/OptionFamily15hInstall.h b/src/vendorcode/amd/agesa/f15tn/Config/OptionFamily15hInstall.h index f0d91940186..bd00756c436 100644 --- a/src/vendorcode/amd/agesa/f15tn/Config/OptionFamily15hInstall.h +++ b/src/vendorcode/amd/agesa/f15tn/Config/OptionFamily15hInstall.h @@ -808,9 +808,9 @@ extern F_IS_NB_PSTATE_ENABLED F15IsNbPstateEnabled; #define F15_TN_UCODE_0E #if AGESA_ENTRY_INIT_EARLY == TRUE - extern CONST UINT8 ROMDATA CpuF15TnMicrocodePatch0600110F_Enc []; + extern CONST UINT8 ROMDATA CpuF15TnMicrocodePatch0600111F_Enc []; #undef F15_TN_UCODE_10F - #define F15_TN_UCODE_10F CpuF15TnMicrocodePatch0600110F_Enc, + #define F15_TN_UCODE_10F CpuF15TnMicrocodePatch0600111F_Enc, #endif diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600110F_Enc.c b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600110F_Enc.c deleted file mode 100644 index 80e60f6313e..00000000000 --- a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600110F_Enc.c +++ /dev/null @@ -1,2673 +0,0 @@ -/* $NoKeywords:$ */ -/** - * @file - * - * AMD F15Tn Microcode patch. - * - * F15Tn Microcode Patch rev 0600110F for 6101 or equivalent. - * - * @xrefitem bom "File Content Label" "Release Content" - * @e project: AGESA - * @e sub-project: CPU/Family/0x15/TN - * @e \$Revision: 64060 $ @e \$Date: 2012-01-15 21:36:26 -0600 (Sun, 15 Jan 2012) $ - */ -/***************************************************************************** - * - * Copyright (c) 2008 - 2012, Advanced Micro Devices, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Advanced Micro Devices, Inc. nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ - - - -/*---------------------------------------------------------------------------------------- - * M O D U L E S U S E D - *---------------------------------------------------------------------------------------- - */ -#include "AGESA.h" -#include "Ids.h" -#include "cpuRegisters.h" -#include "cpuEarlyInit.h" -CODE_GROUP (G3_DXE) -RDATA_GROUP (G3_DXE) - -/*---------------------------------------------------------------------------------------- - * D E F I N I T I O N S A N D M A C R O S - *---------------------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------------------- - * T Y P E D E F S A N D S T R U C T U R E S - *---------------------------------------------------------------------------------------- - */ - - -// Encrypt Patch code 0600110F for 6101 and equivalent - -CONST UINT8 ROMDATA CpuF15TnMicrocodePatch0600110F_Enc [IDS_PAD_4K] = -{ - 0x12, - 0x20, - 0x11, - 0x01, - 0x0f, - 0x11, - 0x00, - 0x06, - 0x02, - 0x80, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x01, - 0x61, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0x00, - 0xd4, - 0x3d, - 0x97, - 0xf0, - 0xd2, - 0x1a, - 0xcf, - 0x44, - 0x1d, - 0x45, - 0x82, - 0x13, - 0xec, - 0xcd, - 0x52, - 0x24, - 0x2d, - 0x26, - 0x73, - 0x9f, - 0x0e, - 0x38, - 0x80, - 0x5b, - 0x02, - 0x6a, - 0xd3, - 0x80, - 0x97, - 0xc0, - 0xe8, - 0x08, - 0xaf, - 0x52, - 0x2e, - 0xe4, - 0x54, - 0xa6, - 0xb3, - 0xb3, - 0x9b, - 0x21, - 0xb9, - 0xe1, - 0xa8, - 0xa4, - 0xed, - 0x9a, - 0x76, - 0xf7, - 0x62, - 0x13, - 0x3b, - 0xf8, - 0x21, - 0xc4, - 0xf3, - 0xff, - 0xb5, - 0x20, - 0xbd, - 0x8c, - 0x3a, - 0x4b, - 0x7e, - 0x44, - 0x88, - 0x9e, - 0x21, - 0xf3, - 0x32, - 0xad, - 0x96, - 0xf9, - 0x1d, - 0xe4, - 0xce, - 0xdd, - 0xb7, - 0x58, - 0x6c, - 0x3c, - 0x78, - 0x00, - 0x9f, - 0x9f, - 0x76, - 0x6e, - 0x92, - 0x80, - 0xb9, - 0x6a, - 0xcf, - 0x66, - 0x2b, - 0x7e, - 0x1d, - 0xbf, - 0x2d, - 0xca, - 0xde, - 0x58, - 0x1b, - 0xc6, - 0xb8, - 0x5e, - 0x82, - 0xc3, - 0xdf, - 0x8b, - 0xd8, - 0xdb, - 0xca, - 0x43, - 0xf2, - 0x75, - 0x40, - 0xb6, - 0xbf, - 0xdb, - 0x5f, - 0xb8, - 0xd2, - 0xdd, - 0x81, - 0xeb, - 0xa6, - 0x7f, - 0x01, - 0xbc, - 0x37, - 0x07, - 0x4e, - 0x73, - 0x13, - 0xcf, - 0x08, - 0xb9, - 0xd6, - 0xda, - 0xe6, - 0x10, - 0xd7, - 0x2c, - 0xfe, - 0x49, - 0x3e, - 0x4b, - 0xa0, - 0xfa, - 0xc1, - 0x81, - 0xe9, - 0xdb, - 0x70, - 0xfd, - 0x46, - 0xc4, - 0x44, - 0x4c, - 0x14, - 0xc2, - 0x1a, - 0x46, - 0xa5, - 0x2c, - 0xb3, - 0x04, - 0x15, - 0xda, - 0x53, - 0x74, - 0x41, - 0x61, - 0xcc, - 0xda, - 0x40, - 0x53, - 0x03, - 0x4a, - 0x51, - 0xc2, - 0x4f, - 0x81, - 0x34, - 0x89, - 0x4f, - 0x7c, - 0x7e, - 0xa0, - 0x50, - 0x7a, - 0xc8, - 0xf3, - 0xd0, - 0xfc, - 0x7f, - 0xda, - 0xa8, - 0x61, - 0x6c, - 0x46, - 0xb3, - 0xc9, - 0x05, - 0x0b, - 0x9f, - 0x5e, - 0xb1, - 0x43, - 0x9d, - 0xc0, - 0x3a, - 0xbe, - 0x6e, - 0x05, - 0x30, - 0x3d, - 0xf1, - 0xee, - 0x0e, - 0xcf, - 0x63, - 0x40, - 0xe9, - 0xd3, - 0x27, - 0x2c, - 0x0a, - 0x48, - 0xe8, - 0xae, - 0xc0, - 0x38, - 0xae, - 0x3b, - 0x41, - 0x21, - 0x5a, - 0xa2, - 0xc0, - 0x20, - 0x77, - 0x18, - 0x9b, - 0x7f, - 0xdd, - 0x95, - 0x4b, - 0x8b, - 0x83, - 0x2c, - 0xfb, - 0x49, - 0xd8, - 0x25, - 0xf2, - 0x21, - 0x6e, - 0x54, - 0xe5, - 0x01, - 0x22, - 0xd5, - 0xf8, - 0x99, - 0x1f, - 0x83, - 0x69, - 0x52, - 0xa1, - 0x9a, - 0x67, - 0x73, - 0x55, - 0xa2, - 0x98, - 0x82, - 0x8c, - 0xff, - 0xed, - 0x9c, - 0x0a, - 0x07, - 0x33, - 0x6f, - 0x16, - 0x39, - 0x79, - 0xcc, - 0xe3, - 0x5a, - 0xa0, - 0x2d, - 0xa6, - 0xdf, - 0x2e, - 0x4b, - 0xab, - 0x6c, - 0x6f, - 0xd4, - 0x6e, - 0x70, - 0x9b, - 0x9a, - 0xf3, - 0xb3, - 0x52, - 0xb8, - 0x05, - 0x53, - 0xba, - 0x79, - 0x08, - 0x6a, - 0xb1, - 0x5e, - 0xf7, - 0x85, - 0xc1, - 0xfc, - 0xd8, - 0xb5, - 0x3d, - 0xbb, - 0xb9, - 0x3d, - 0xa3, - 0x98, - 0x13, - 0x61, - 0xed, - 0x1e, - 0xc0, - 0x45, - 0x6c, - 0x98, - 0xfc, - 0x87, - 0x2c, - 0xb8, - 0x99, - 0x97, - 0xb8, - 0xc7, - 0x5f, - 0x2e, - 0x6d, - 0x28, - 0x79, - 0xaf, - 0x0b, - 0xf9, - 0x84, - 0x7e, - 0x34, - 0xd8, - 0x86, - 0x61, - 0x22, - 0xdb, - 0xf4, - 0xef, - 0x58, - 0x0d, - 0x4e, - 0xcf, - 0x02, - 0x8a, - 0xf8, - 0x17, - 0xab, - 0x7d, - 0x79, - 0x98, - 0x38, - 0x35, - 0x59, - 0xdf, - 0x03, - 0xff, - 0xed, - 0xc7, - 0x1f, - 0x25, - 0xe3, - 0x26, - 0x05, - 0xde, - 0x7f, - 0xbb, - 0xe4, - 0xff, - 0xbf, - 0x6d, - 0xc6, - 0xc2, - 0x2e, - 0x02, - 0x45, - 0x85, - 0x5f, - 0x43, - 0xdb, - 0xb8, - 0xd2, - 0x13, - 0xd7, - 0x52, - 0xde, - 0x53, - 0x49, - 0xda, - 0x7f, - 0x0b, - 0xb8, - 0x76, - 0x70, - 0xf9, - 0xfe, - 0xf0, - 0x27, - 0xb7, - 0xc9, - 0xd4, - 0x83, - 0x6d, - 0x80, - 0xaa, - 0x34, - 0x46, - 0xf5, - 0xe3, - 0x1f, - 0xd7, - 0x0f, - 0xf2, - 0xee, - 0x5a, - 0xb2, - 0xcd, - 0x08, - 0x47, - 0xe6, - 0xf7, - 0x99, - 0xd1, - 0x05, - 0x55, - 0x0f, - 0x5f, - 0x1d, - 0xab, - 0xd6, - 0xb3, - 0x32, - 0xaf, - 0xa1, - 0x57, - 0x4d, - 0x32, - 0x00, - 0x4f, - 0xf6, - 0x6f, - 0x6e, - 0x79, - 0x8a, - 0x7c, - 0xc2, - 0xef, - 0x7e, - 0xcd, - 0x83, - 0xac, - 0x85, - 0x0e, - 0x53, - 0x2c, - 0xd9, - 0x92, - 0xf5, - 0x55, - 0xf6, - 0xc9, - 0x41, - 0xed, - 0xf5, - 0x4e, - 0x41, - 0xea, - 0x97, - 0xca, - 0x3b, - 0x14, - 0xca, - 0x0d, - 0x4e, - 0xb9, - 0x5f, - 0x54, - 0x23, - 0xf1, - 0xdc, - 0x8b, - 0xa4, - 0xc1, - 0x52, - 0xe2, - 0x7a, - 0x8f, - 0xdf, - 0x3f, - 0x93, - 0xa1, - 0x84, - 0x5c, - 0xca, - 0x6a, - 0x3a, - 0x42, - 0x95, - 0x2e, - 0x71, - 0xf6, - 0xa2, - 0x88, - 0x56, - 0x32, - 0xe8, - 0x98, - 0x2a, - 0xb8, - 0xf0, - 0x65, - 0x95, - 0x01, - 0xb8, - 0xc8, - 0x23, - 0xe9, - 0x30, - 0x52, - 0x94, - 0xeb, - 0xfa, - 0x9f, - 0x67, - 0x53, - 0xf0, - 0x63, - 0x10, - 0x70, - 0x1b, - 0x01, - 0x71, - 0x21, - 0xb3, - 0x27, - 0x4e, - 0x37, - 0x04, - 0xdc, - 0x74, - 0x6f, - 0xf3, - 0x08, - 0x00, - 0x72, - 0x21, - 0x96, - 0xe5, - 0xc6, - 0x75, - 0xa8, - 0x14, - 0x6f, - 0xcf, - 0xd8, - 0x86, - 0xe3, - 0xb7, - 0xf3, - 0x8c, - 0xe4, - 0x71, - 0x03, - 0x60, - 0xd4, - 0x53, - 0xff, - 0x5a, - 0x07, - 0xc4, - 0xe5, - 0x6b, - 0xf4, - 0x8d, - 0x80, - 0x55, - 0x78, - 0x4f, - 0xf5, - 0x55, - 0x04, - 0x2e, - 0x61, - 0x05, - 0x46, - 0x51, - 0x56, - 0xf8, - 0x0a, - 0xf5, - 0x6e, - 0x08, - 0x85, - 0xfd, - 0x01, - 0x9a, - 0x90, - 0x5a, - 0xed, - 0x0e, - 0x44, - 0x49, - 0xff, - 0x48, - 0xbe, - 0x5b, - 0xc4, - 0xea, - 0xbb, - 0x38, - 0xa9, - 0x04, - 0xf3, - 0x6c, - 0x6b, - 0x41, - 0x85, - 0x59, - 0x18, - 0x38, - 0xd5, - 0x52, - 0x18, - 0x1d, - 0xdd, - 0xab, - 0x28, - 0xd9, - 0x05, - 0xfe, - 0xd9, - 0xc6, - 0xa9, - 0x25, - 0xf4, - 0xb5, - 0xcb, - 0x9c, - 0x1d, - 0xe8, - 0x6f, - 0x21, - 0xd3, - 0x5b, - 0x88, - 0x44, - 0x2c, - 0x10, - 0xaf, - 0x43, - 0xcc, - 0xe8, - 0x10, - 0x9d, - 0xc1, - 0xb2, - 0x14, - 0xae, - 0xa3, - 0x1d, - 0x05, - 0x97, - 0xca, - 0x45, - 0xef, - 0x5c, - 0x57, - 0x60, - 0x49, - 0x75, - 0x7d, - 0x80, - 0xd2, - 0x9e, - 0x44, - 0xf0, - 0xed, - 0x7e, - 0x32, - 0x3a, - 0x12, - 0xc6, - 0xff, - 0x07, - 0x0d, - 0xbf, - 0xcf, - 0x42, - 0xe5, - 0xde, - 0x44, - 0x19, - 0x70, - 0x22, - 0x76, - 0x6b, - 0x30, - 0x6f, - 0x8d, - 0x69, - 0x75, - 0x5d, - 0xc4, - 0x7e, - 0xf7, - 0x99, - 0xe1, - 0x37, - 0x84, - 0xee, - 0x97, - 0x5c, - 0x83, - 0xdf, - 0xd0, - 0xe9, - 0x1c, - 0xb0, - 0x9f, - 0x13, - 0x81, - 0x51, - 0x51, - 0xaf, - 0x61, - 0xb4, - 0x35, - 0x1f, - 0xe2, - 0x54, - 0xe9, - 0x68, - 0x75, - 0x3c, - 0xcc, - 0x51, - 0x9c, - 0x75, - 0x27, - 0x66, - 0xe7, - 0x95, - 0x7d, - 0x91, - 0xd8, - 0xf0, - 0xff, - 0x47, - 0xc6, - 0x51, - 0xb3, - 0xef, - 0x03, - 0xaf, - 0x61, - 0x59, - 0x95, - 0x43, - 0x14, - 0xce, - 0xdf, - 0x48, - 0xc8, - 0xea, - 0xbc, - 0x13, - 0x98, - 0xb9, - 0xcc, - 0x63, - 0x41, - 0x7f, - 0x9a, - 0xe0, - 0x41, - 0xd7, - 0xb7, - 0x7b, - 0x80, - 0xb5, - 0x3e, - 0x95, - 0xdc, - 0xc4, - 0x76, - 0xae, - 0x64, - 0x64, - 0x02, - 0x52, - 0xab, - 0x70, - 0x42, - 0x04, - 0x34, - 0xd4, - 0x74, - 0x7d, - 0xfd, - 0x88, - 0x0f, - 0x49, - 0x51, - 0x80, - 0x86, - 0x90, - 0xc1, - 0x55, - 0x12, - 0x62, - 0xfc, - 0xc0, - 0x1f, - 0x2b, - 0x79, - 0xbb, - 0xca, - 0x5e, - 0xa1, - 0x81, - 0xcf, - 0x2b, - 0x3b, - 0x10, - 0xd8, - 0x69, - 0x67, - 0xa8, - 0xc5, - 0xa2, - 0xfe, - 0xa4, - 0x71, - 0xcb, - 0x65, - 0x28, - 0xbe, - 0x8d, - 0x0c, - 0x00, - 0x6a, - 0xb0, - 0x99, - 0x4e, - 0x57, - 0xac, - 0x62, - 0x95, - 0x98, - 0xb7, - 0xaf, - 0x81, - 0xec, - 0xe7, - 0xe3, - 0x02, - 0x5e, - 0xc2, - 0x8b, - 0x2a, - 0x68, - 0x22, - 0xb7, - 0x4a, - 0x9c, - 0x6a, - 0x0d, - 0x75, - 0xbc, - 0xee, - 0xa6, - 0x01, - 0x6f, - 0xf7, - 0x4d, - 0x66, - 0x42, - 0x13, - 0xc2, - 0xe4, - 0xcb, - 0xe4, - 0x12, - 0xa3, - 0x94, - 0x9b, - 0x0a, - 0xfc, - 0x72, - 0xc4, - 0xbc, - 0xc0, - 0x8d, - 0x68, - 0x73, - 0x99, - 0xf2, - 0xd8, - 0x15, - 0x10, - 0x93, - 0x1e, - 0x3b, - 0x16, - 0x34, - 0x7b, - 0x48, - 0x15, - 0x1b, - 0x72, - 0x8c, - 0x3a, - 0xa7, - 0x14, - 0x73, - 0xee, - 0x44, - 0x9a, - 0x8a, - 0xa5, - 0x1d, - 0xec, - 0x10, - 0x5d, - 0xf8, - 0x58, - 0x5e, - 0x01, - 0xfe, - 0x05, - 0x23, - 0x39, - 0xc5, - 0xa5, - 0x60, - 0x9b, - 0xb7, - 0x11, - 0x5c, - 0x13, - 0x3d, - 0xd1, - 0xef, - 0x62, - 0x0e, - 0xbf, - 0x0a, - 0x9f, - 0xdd, - 0x1f, - 0x50, - 0x5f, - 0xb7, - 0xc8, - 0x48, - 0xd1, - 0xc5, - 0xd1, - 0xa8, - 0x97, - 0x03, - 0x27, - 0x34, - 0x63, - 0x8a, - 0xa9, - 0x14, - 0x00, - 0xdb, - 0xf7, - 0xbc, - 0xce, - 0x26, - 0xcd, - 0xea, - 0x30, - 0xdf, - 0x42, - 0xf8, - 0x04, - 0x85, - 0x1d, - 0xc3, - 0xfc, - 0xbf, - 0x68, - 0xb0, - 0x28, - 0xc6, - 0x72, - 0xba, - 0x3d, - 0x72, - 0x9e, - 0x8b, - 0x15, - 0x3f, - 0xa1, - 0x4b, - 0x0b, - 0xd3, - 0x14, - 0x51, - 0x75, - 0x5c, - 0x1f, - 0xa2, - 0x04, - 0x68, - 0xf0, - 0x76, - 0xb2, - 0x5d, - 0x05, - 0x60, - 0x4f, - 0x8b, - 0xa2, - 0x2a, - 0x0d, - 0x56, - 0x39, - 0x66, - 0x6d, - 0x1c, - 0xf3, - 0x86, - 0x86, - 0xc9, - 0xfd, - 0xdb, - 0x8c, - 0xe6, - 0xd1, - 0xb0, - 0xb3, - 0x66, - 0x0f, - 0xdf, - 0xbc, - 0x5c, - 0x0b, - 0x24, - 0x63, - 0x1e, - 0xe8, - 0x69, - 0x8b, - 0xf8, - 0x43, - 0x45, - 0x17, - 0x48, - 0x3a, - 0xe7, - 0xcd, - 0xb6, - 0x18, - 0xfe, - 0x39, - 0x01, - 0x27, - 0x98, - 0xf9, - 0xd1, - 0xcf, - 0xfb, - 0xc1, - 0x96, - 0x0b, - 0x0c, - 0x57, - 0x03, - 0x70, - 0x4b, - 0x51, - 0x81, - 0x28, - 0x40, - 0x8b, - 0xa6, - 0xcb, - 0xf7, - 0xd7, - 0x7e, - 0xb8, - 0x81, - 0x70, - 0xef, - 0xfb, - 0xc4, - 0x1c, - 0x8c, - 0x74, - 0x35, - 0xb5, - 0x85, - 0xbc, - 0xa4, - 0xbe, - 0xba, - 0x80, - 0x1e, - 0x2f, - 0x72, - 0xfb, - 0xe1, - 0x27, - 0xe1, - 0x3c, - 0xf6, - 0x99, - 0x8a, - 0xd8, - 0xe6, - 0xed, - 0x32, - 0x93, - 0x78, - 0x12, - 0xa9, - 0xd6, - 0x52, - 0x55, - 0xfa, - 0x6e, - 0xf9, - 0x3c, - 0xf1, - 0x6c, - 0x93, - 0x2e, - 0x82, - 0x70, - 0x9f, - 0x5c, - 0x8b, - 0x88, - 0x63, - 0x6e, - 0xc1, - 0xd0, - 0xec, - 0xe9, - 0x39, - 0x0b, - 0x42, - 0xb8, - 0xe9, - 0xaa, - 0xcd, - 0xfc, - 0x70, - 0xfa, - 0xb9, - 0x42, - 0xdd, - 0x58, - 0x32, - 0x5f, - 0x3c, - 0xaa, - 0xf3, - 0x24, - 0x64, - 0x61, - 0xc9, - 0x19, - 0xf7, - 0x8b, - 0x20, - 0xf6, - 0x78, - 0xfc, - 0xb1, - 0x51, - 0xa6, - 0x95, - 0x2c, - 0x2f, - 0x58, - 0x4e, - 0xab, - 0x08, - 0x58, - 0x9b, - 0xad, - 0x2c, - 0x30, - 0x13, - 0x66, - 0xcf, - 0xf2, - 0x5e, - 0x17, - 0x3f, - 0x60, - 0x78, - 0x07, - 0xa5, - 0x32, - 0xf3, - 0x0b, - 0xb7, - 0xab, - 0x9a, - 0x73, - 0x3e, - 0x0c, - 0xbe, - 0x3a, - 0x1a, - 0x95, - 0x77, - 0xe8, - 0xdf, - 0x78, - 0xc0, - 0xb5, - 0x43, - 0x26, - 0x35, - 0xd1, - 0x41, - 0x2b, - 0x81, - 0x31, - 0xd2, - 0x22, - 0xb4, - 0x8d, - 0xf7, - 0x51, - 0xd5, - 0xc5, - 0x06, - 0x17, - 0x7c, - 0x03, - 0xa3, - 0x97, - 0xb1, - 0xc2, - 0x86, - 0x7c, - 0xb4, - 0x98, - 0xca, - 0x88, - 0x6f, - 0x09, - 0x70, - 0xb9, - 0xb6, - 0x35, - 0x08, - 0xdc, - 0xc5, - 0x65, - 0xd3, - 0xf6, - 0x87, - 0x34, - 0xad, - 0xd9, - 0x4f, - 0x76, - 0x0a, - 0xc4, - 0xbb, - 0xfc, - 0x11, - 0xe3, - 0x31, - 0x2a, - 0x05, - 0x85, - 0x93, - 0xca, - 0xc3, - 0xfe, - 0x8c, - 0xe3, - 0x83, - 0xd3, - 0x88, - 0x2d, - 0x85, - 0xb1, - 0x33, - 0x04, - 0x7f, - 0x9e, - 0xdb, - 0x2b, - 0xc8, - 0xc9, - 0xbd, - 0x79, - 0xcd, - 0x9f, - 0xff, - 0xe7, - 0xee, - 0x9f, - 0x68, - 0xc6, - 0x7b, - 0x10, - 0x9a, - 0x7b, - 0x70, - 0x84, - 0x7b, - 0xdf, - 0x35, - 0xc1, - 0xf6, - 0x9f, - 0x9f, - 0x2b, - 0x59, - 0x69, - 0xb6, - 0xca, - 0x16, - 0xbd, - 0x7a, - 0x20, - 0xdf, - 0x1e, - 0xd4, - 0x6a, - 0x8c, - 0x23, - 0x44, - 0xfb, - 0x68, - 0x24, - 0xcf, - 0xf6, - 0x2f, - 0x20, - 0x1f, - 0xcf, - 0x32, - 0xdd, - 0x80, - 0xef, - 0x12, - 0x21, - 0x05, - 0xe7, - 0x4d, - 0xc9, - 0xd2, - 0x91, - 0x05, - 0x10, - 0xa9, - 0xfe, - 0x6f, - 0x49, - 0x6f, - 0x78, - 0x69, - 0x07, - 0xc9, - 0x60, - 0xae, - 0x14, - 0xa4, - 0x5c, - 0x3b, - 0xf5, - 0xd7, - 0x3d, - 0xe3, - 0x1a, - 0x88, - 0xb3, - 0x64, - 0x39, - 0x10, - 0x92, - 0xd2, - 0x8b, - 0x50, - 0x14, - 0x60, - 0x58, - 0x3e, - 0x59, - 0x32, - 0xbe, - 0x4c, - 0x91, - 0x72, - 0x0d, - 0x1c, - 0xde, - 0x97, - 0xd8, - 0xb3, - 0xc9, - 0x96, - 0x76, - 0xcb, - 0x7f, - 0x00, - 0x79, - 0x97, - 0x93, - 0x6e, - 0xa9, - 0x86, - 0x6e, - 0x47, - 0x62, - 0x49, - 0x66, - 0xd3, - 0xf0, - 0x00, - 0x41, - 0x25, - 0x01, - 0x82, - 0x99, - 0xfb, - 0x26, - 0x42, - 0x4c, - 0xa3, - 0xff, - 0x18, - 0x2e, - 0x8a, - 0x6a, - 0xda, - 0x68, - 0xa9, - 0x57, - 0x52, - 0x04, - 0x2f, - 0xd7, - 0xda, - 0x8a, - 0xdb, - 0xbf, - 0xf3, - 0x3b, - 0x3c, - 0xfc, - 0xa5, - 0xc1, - 0xf7, - 0xb7, - 0x7e, - 0x94, - 0x64, - 0x3c, - 0x36, - 0x00, - 0xc3, - 0x85, - 0xa2, - 0xfb, - 0x19, - 0xe6, - 0xc7, - 0x2f, - 0x7d, - 0xa4, - 0xf5, - 0x09, - 0x73, - 0x32, - 0x11, - 0x2c, - 0x1e, - 0xf2, - 0xf5, - 0x59, - 0xd5, - 0x15, - 0xbc, - 0x1d, - 0xe2, - 0x7b, - 0x2c, - 0xc7, - 0x48, - 0x4a, - 0x08, - 0xf3, - 0x1f, - 0x64, - 0xa6, - 0x44, - 0x55, - 0xf8, - 0xa8, - 0x4b, - 0x6f, - 0x3a, - 0x6f, - 0x94, - 0xcd, - 0xb1, - 0xf5, - 0x36, - 0xd7, - 0x6f, - 0x96, - 0x21, - 0xf6, - 0xdd, - 0x60, - 0xf9, - 0x6e, - 0x38, - 0x74, - 0xd7, - 0xf5, - 0x78, - 0xa9, - 0x64, - 0x39, - 0x4d, - 0xbf, - 0x79, - 0xaf, - 0xaf, - 0x34, - 0xbd, - 0x36, - 0x65, - 0x9f, - 0xe1, - 0xec, - 0xaf, - 0x29, - 0x3a, - 0x90, - 0x0c, - 0xdd, - 0xcd, - 0x98, - 0x05, - 0x39, - 0xca, - 0x95, - 0x5e, - 0x27, - 0x76, - 0xc6, - 0x95, - 0xc6, - 0x0b, - 0x01, - 0x0c, - 0xd0, - 0xfe, - 0x97, - 0xee, - 0x9c, - 0x39, - 0xc7, - 0x39, - 0xeb, - 0x38, - 0x04, - 0xc2, - 0x7f, - 0x8d, - 0x65, - 0x6c, - 0x27, - 0x7b, - 0xe3, - 0x52, - 0xd6, - 0x24, - 0x58, - 0x13, - 0xdc, - 0x0b, - 0xaa, - 0xe9, - 0xf5, - 0x96, - 0xbe, - 0x5c, - 0xc1, - 0x56, - 0xd2, - 0x82, - 0xa6, - 0x27, - 0xe8, - 0x4f, - 0xd8, - 0xc9, - 0x65, - 0x57, - 0x88, - 0xf5, - 0x5c, - 0xb4, - 0xca, - 0x3d, - 0x53, - 0x18, - 0x46, - 0x31, - 0xcc, - 0xba, - 0x2d, - 0x49, - 0x9e, - 0x34, - 0x29, - 0x56, - 0x68, - 0xad, - 0x07, - 0x0d, - 0x96, - 0xaa, - 0x44, - 0x15, - 0x54, - 0x5c, - 0x9b, - 0x96, - 0x83, - 0x70, - 0x5c, - 0x0f, - 0xbf, - 0x42, - 0x44, - 0x96, - 0xc3, - 0x86, - 0xdb, - 0x5b, - 0x88, - 0xd5, - 0xd7, - 0x19, - 0x80, - 0x5d, - 0x7f, - 0x65, - 0x24, - 0xda, - 0x49, - 0x43, - 0x9f, - 0xcb, - 0xdf, - 0x40, - 0xce, - 0x44, - 0x68, - 0xa9, - 0xf4, - 0x10, - 0x42, - 0xd7, - 0x75, - 0x60, - 0x60, - 0xd7, - 0xf4, - 0x24, - 0xa6, - 0x62, - 0x1e, - 0x16, - 0xa0, - 0xce, - 0x25, - 0x67, - 0x5d, - 0xd9, - 0xa7, - 0xcb, - 0x1b, - 0xb8, - 0x81, - 0x0a, - 0x9e, - 0xde, - 0xa4, - 0xe0, - 0x8b, - 0x26, - 0xd3, - 0x1f, - 0x9d, - 0x75, - 0x44, - 0xce, - 0x16, - 0xde, - 0xdd, - 0xa2, - 0xcb, - 0x5f, - 0xe5, - 0xad, - 0xe2, - 0x73, - 0xce, - 0xa4, - 0x9a, - 0x75, - 0x7e, - 0x5f, - 0xb3, - 0x4b, - 0x89, - 0x84, - 0x10, - 0x14, - 0x11, - 0xfa, - 0x61, - 0xdb, - 0x12, - 0x32, - 0x5d, - 0xd1, - 0x05, - 0x5e, - 0xbd, - 0x81, - 0x15, - 0x59, - 0xda, - 0xc9, - 0xb7, - 0x86, - 0xfd, - 0xdb, - 0xab, - 0xaa, - 0xed, - 0xf8, - 0xf0, - 0x7a, - 0x98, - 0x6b, - 0x00, - 0x4a, - 0xee, - 0x9b, - 0xa9, - 0xef, - 0xcb, - 0x73, - 0xc8, - 0x4b, - 0x9a, - 0xc1, - 0x1d, - 0xda, - 0xd7, - 0x02, - 0x0b, - 0x53, - 0xbb, - 0x16, - 0xdb, - 0x99, - 0xac, - 0xc5, - 0x24, - 0x30, - 0xec, - 0x62, - 0x22, - 0x3e, - 0xfd, - 0xa8, - 0x70, - 0x9d, - 0x90, - 0x83, - 0xa6, - 0x5c, - 0xaf, - 0x39, - 0x7e, - 0x04, - 0x7a, - 0x08, - 0x14, - 0xe4, - 0xd0, - 0x83, - 0xf3, - 0xe3, - 0x4c, - 0x07, - 0x2a, - 0xfd, - 0xc0, - 0xf9, - 0x4c, - 0x9d, - 0x2e, - 0x67, - 0xfd, - 0x39, - 0xbc, - 0xad, - 0x65, - 0x84, - 0xbc, - 0xd8, - 0x72, - 0x7a, - 0x8e, - 0x1b, - 0x72, - 0x33, - 0x7d, - 0x92, - 0x15, - 0x44, - 0xd0, - 0x03, - 0x56, - 0x80, - 0xee, - 0x2c, - 0x89, - 0x4a, - 0x0a, - 0x53, - 0xc8, - 0xeb, - 0x2a, - 0xb5, - 0x38, - 0xae, - 0x69, - 0x75, - 0x08, - 0x1d, - 0x07, - 0xa7, - 0xe7, - 0x3c, - 0xf0, - 0x22, - 0x02, - 0x7f, - 0x42, - 0xbf, - 0x00, - 0x86, - 0xef, - 0xc6, - 0x7b, - 0xff, - 0xd0, - 0x32, - 0x01, - 0xb0, - 0x9f, - 0xae, - 0x49, - 0x8f, - 0x4b, - 0x2b, - 0xa6, - 0x5f, - 0x11, - 0x1d, - 0xc8, - 0xd5, - 0x1c, - 0x49, - 0x41, - 0x09, - 0x55, - 0x61, - 0xb1, - 0xcf, - 0xf8, - 0x7b, - 0x5d, - 0x37, - 0xd7, - 0x3d, - 0xc9, - 0x6d, - 0xf0, - 0x7f, - 0x0f, - 0x40, - 0xf7, - 0xce, - 0xa9, - 0x45, - 0x25, - 0x89, - 0xe2, - 0x36, - 0x2e, - 0xe9, - 0x16, - 0x17, - 0xcb, - 0x86, - 0xea, - 0x6f, - 0x29, - 0xd9, - 0xbe, - 0xe3, - 0x5d, - 0x6f, - 0xa3, - 0xbd, - 0x94, - 0xfd, - 0x55, - 0x23, - 0x46, - 0x40, - 0xfc, - 0xa5, - 0xf4, - 0x0f, - 0xa2, - 0x63, - 0x2b, - 0x49, - 0x88, - 0x69, - 0xfb, - 0xac, - 0x4b, - 0xa4, - 0x06, - 0x8b, - 0x34, - 0xd6, - 0x57, - 0x71, - 0xf9, - 0x7a, - 0xa2, - 0xde, - 0x93, - 0xc4, - 0x20, - 0xb0, - 0x35, - 0xea, - 0x70, - 0x9f, - 0xdf, - 0x30, - 0x6e, - 0xbb, - 0x7e, - 0x6c, - 0x46, - 0x90, - 0x1c, - 0x0b, - 0xea, - 0x44, - 0x4b, - 0xdd, - 0xbd, - 0x89, - 0x0f, - 0x02, - 0x5a, - 0xaa, - 0x5a, - 0x2c, - 0x57, - 0xc3, - 0xf3, - 0xfc, - 0xf5, - 0xc2, - 0x89, - 0xb1, - 0x08, - 0x79, - 0x3c, - 0x8b, - 0xbe, - 0xc1, - 0xd5, - 0x53, - 0x62, - 0x52, - 0xc2, - 0xc9, - 0xba, - 0xa2, - 0xb8, - 0x02, - 0xc6, - 0xbd, - 0x51, - 0xda, - 0xf9, - 0xf7, - 0x8d, - 0x66, - 0xd0, - 0x10, - 0xb0, - 0xdf, - 0x52, - 0xd8, - 0x5c, - 0x2e, - 0x60, - 0x24, - 0xd7, - 0x2e, - 0x9b, - 0xc2, - 0x54, - 0xd3, - 0x6c, - 0x5d, - 0xb5, - 0x63, - 0xa9, - 0xf3, - 0x33, - 0x47, - 0xa0, - 0x46, - 0x7c, - 0x5b, - 0xd2, - 0xc2, - 0x2d, - 0xb0, - 0xa5, - 0x05, - 0x4b, - 0xf9, - 0xf3, - 0x11, - 0x8a, - 0x5b, - 0x71, - 0xcb, - 0x95, - 0x49, - 0x2f, - 0xfc, - 0xbc, - 0x2a, - 0x55, - 0xff, - 0xce, - 0x00, - 0x39, - 0x5f, - 0x43, - 0xf5, - 0x99, - 0x40, - 0xe3, - 0x3c, - 0x65, - 0x6c, - 0xcb, - 0x44, - 0x6f, - 0xb3, - 0x8f, - 0xdc, - 0xad, - 0x95, - 0x7a, - 0xa2, - 0x0a, - 0x76, - 0x21, - 0xf4, - 0x69, - 0x75, - 0x86, - 0xa7, - 0xff, - 0x30, - 0x4e, - 0x58, - 0x5f, - 0xe6, - 0xc1, - 0x2c, - 0x4f, - 0xa6, - 0xf7, - 0x6d, - 0x01, - 0xe0, - 0xc1, - 0x13, - 0xd1, - 0x49, - 0x66, - 0x32, - 0x4e, - 0x6c, - 0x6d, - 0x17, - 0xde, - 0xd9, - 0x05, - 0xf0, - 0x0e, - 0x4e, - 0x06, - 0x22, - 0xa2, - 0xa4, - 0x2c, - 0x74, - 0x6b, - 0x18, - 0x46, - 0x18, - 0x7b, - 0xab, - 0x95, - 0xfa, - 0xe4, - 0x56, - 0xdf, - 0x5d, - 0xc5, - 0x4d, - 0x5c, - 0x20, - 0xa0, - 0x42, - 0x80, - 0x86, - 0xd8, - 0x60, - 0x8f, - 0x17, - 0x6b, - 0xf9, - 0x33, - 0xa8, - 0xaf, - 0x7a, - 0x43, - 0x75, - 0x33, - 0x8e, - 0xc5, - 0x32, - 0x69, - 0xe7, - 0xd0, - 0xe5, - 0xc5, - 0xa4, - 0xf0, - 0xa5, - 0x10, - 0xc7, - 0xd1, - 0xff, - 0x52, - 0xa0, - 0xb8, - 0x05, - 0x7d, - 0x5f, - 0xf2, - 0x7e, - 0x85, - 0x59, - 0x95, - 0xf7, - 0x8b, - 0x26, - 0x68, - 0x69, - 0x93, - 0x1a, - 0x58, - 0x89, - 0x2e, - 0x79, - 0x99, - 0xdb, - 0x93, - 0x59, - 0x45, - 0xdc, - 0xda, - 0x8b, - 0xba, - 0xf3, - 0xe8, - 0x81, - 0xe2, - 0x43, - 0x65, - 0x68, - 0x36, - 0x6d, - 0x2c, - 0x69, - 0x0a, - 0xee, - 0x16, - 0xe0, - 0x94, - 0xfc, - 0xee, - 0x6b, - 0x52, - 0x9b, - 0xd0, - 0x2e, - 0x5e, - 0x9e, - 0x0a, - 0x83, - 0x74, - 0xab, - 0xa2, - 0xab, - 0xfd, - 0xb8, - 0x8e, - 0x18, - 0xf7, - 0x78, - 0x84, - 0xef, - 0xfc, - 0x0d, - 0xac, - 0x26, - 0x15, - 0x8b, - 0xd0, - 0x5e, - 0x95, - 0x26, - 0x33, - 0x2d, - 0x82, - 0x78, - 0xc8, - 0x00, - 0x07, - 0x21, - 0x94, - 0x19, - 0x25, - 0xd9, - 0x6c, - 0x47, - 0xae, - 0xa4, - 0xd5, - 0x7d, - 0x27, - 0xde, - 0xec, - 0xf1, - 0x59, - 0xb7, - 0x9a, - 0x02, - 0x57, - 0x91, - 0x54, - 0x06, - 0x89, - 0xb4, - 0xb5, - 0x12, - 0xea, - 0x95, - 0x89, - 0x10, - 0xad, - 0x7a, - 0xa0, - 0x05, - 0x33, - 0xaf, - 0xf4, - 0x7d, - 0x45, - 0x88, - 0xe9, - 0xc6, - 0xe8, - 0x2a, - 0x36, - 0x3f, - 0x44, - 0xd1, - 0x74, - 0x71, - 0x32, - 0x9b, - 0xe5, - 0x35, - 0x55, - 0xc8, - 0xb7, - 0x0c, - 0xc5, - 0xf0, - 0x7b, - 0x29, - 0x45, - 0xb8, - 0xc7, - 0x14, - 0xa2, - 0x1e, - 0x9a, - 0x3f, - 0xe5, - 0x94, - 0xf8, - 0xe6, - 0x70, - 0x62, - 0xaf, - 0x0e, - 0xd7, - 0xf8, - 0x05, - 0x61, - 0x65, - 0x48, - 0xfd, - 0xee, - 0x3e, - 0x55, - 0xff, - 0x14, - 0x59, - 0x18, - 0x0f, - 0x2f, - 0x20, - 0x52, - 0x20, - 0xde, - 0x15, - 0xcf, - 0x23, - 0x10, - 0xa2, - 0x1c, - 0x4c, - 0x84, - 0x81, - 0x21, - 0xb0, - 0x6b, - 0x25, - 0xa8, - 0x3e, - 0xc6, - 0xa4, - 0xc2, - 0x0a, - 0x46, - 0x52, - 0x4f, - 0x72, - 0x56, - 0x06, - 0xec, - 0x76, - 0xda, - 0x7e, - 0x09, - 0x45, - 0x05, - 0x9b, - 0xdb, - 0x31, - 0x90, - 0x63, - 0xdf, - 0x98, - 0x47, - 0x4a, - 0x9e, - 0x28, - 0x3d, - 0x0d, - 0x64, - 0xfb, - 0x44, - 0xc5, - 0xfb, - 0xe2, - 0x56, - 0xe9, - 0x08, - 0x98, - 0x79, - 0x2f, - 0xaf, - 0x15, - 0xb5, - 0xea, - 0x7e, - 0x61, - 0x89, - 0x16, - 0x5e, - 0x9c, - 0x6e, - 0xca, - 0x90, - 0x90, - 0x4a, - 0x5f, - 0x14, - 0x83, - 0x67, - 0x47, - 0x44, - 0xae, - 0x0a, - 0x83, - 0xc4, - 0x95, - 0xf6, - 0x88, - 0xc2, - 0xfb, - 0xa3, - 0x9b, - 0x7a, - 0xf9, - 0x32, - 0x80, - 0x94, - 0xf4, - 0x16, - 0x5a, - 0xd4, - 0xef, - 0x39, - 0xe8, - 0x86, - 0xe1, - 0xcd, - 0x6a, - 0x7e, - 0xca, - 0x33, - 0xa1, - 0xd4, - 0xcb, - 0xe9, - 0x5a, - 0xca, - 0xc6, - 0xb0, - 0xd9, - 0x68, - 0x27, - 0x8c, - 0x93, - 0x47, - 0x3e, - 0x4f, - 0xc0, - 0xa8, - 0x86, - 0x68, - 0x4b, - 0x1a, - 0xf5, - 0x93, - 0xdd, - 0x16, - 0xed, - 0x8e, - 0x27, - 0x66, - 0x4d, - 0x59, - 0xf0, - 0x27, - 0x1b, - 0x37, - 0xa0, - 0x25, - 0x9a, - 0x62, - 0xb4, - 0x6f, - 0xbd, - 0x83, - 0x28, - 0x0b, - 0x26, - 0xa9, - 0x07, - 0xac, - 0xb5, - 0x91, - 0x93, - 0x91, -}; - -/*---------------------------------------------------------------------------------------- - * P R O T O T Y P E S O F L O C A L F U N C T I O N S - *---------------------------------------------------------------------------------------- - */ - -/*---------------------------------------------------------------------------------------- - * E X P O R T E D F U N C T I O N S - *---------------------------------------------------------------------------------------- - */ diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600111F_Enc.c b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600111F_Enc.c new file mode 100644 index 00000000000..71fb1df0a8a --- /dev/null +++ b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/F15TnMicrocodePatch0600111F_Enc.c @@ -0,0 +1,405 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * AMD F15Tn Microcode patch. + * + * F15Tn Microcode Patch rev 0600111F for 6101/6131 or equivalent. + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: CPU/Family/0x15/TN + * @e \$Revision: 334098 $ @e \$Date: 2018-03-05 14:21:15 -0600 (Mon, 05 Mar 2018) $ + */ +/***************************************************************************** + * + * Copyright (c) 2008 - 2018, Advanced Micro Devices, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Advanced Micro Devices, Inc. nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + ***************************************************************************/ + + + +/*---------------------------------------------------------------------------------------- + * M O D U L E S U S E D + *---------------------------------------------------------------------------------------- + */ +#include "AGESA.h" +#include "Ids.h" +#include "cpuRegisters.h" +#include "cpuEarlyInit.h" +CODE_GROUP (G3_DXE) +RDATA_GROUP (G3_DXE) + +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + + +// Encrypt Patch code 0600111F for 6101/6131 and equivalent + +CONST UINT8 ROMDATA CpuF15TnMicrocodePatch0600111F_Enc [IDS_PAD_4K] = +{ + 0x18, 0x20, 0x05, 0x03, 0x1f, 0x11, 0x00, 0x06, + 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0xb7, 0x58, 0x1c, 0xca, 0xa2, 0xf2, 0x52, + 0x72, 0xa4, 0xe1, 0x1b, 0x37, 0xe0, 0x9f, 0xb3, + 0x58, 0xf4, 0x76, 0x85, 0x1a, 0x83, 0x4a, 0x89, + 0x78, 0x82, 0x4e, 0xf3, 0xa1, 0x6a, 0xb7, 0x56, + 0x93, 0xcb, 0xfa, 0x4c, 0x03, 0x6b, 0xec, 0xb5, + 0x4f, 0xc0, 0x7d, 0x46, 0x0e, 0x04, 0x96, 0xec, + 0xab, 0xc3, 0x74, 0x0c, 0x4b, 0x1c, 0x19, 0x1f, + 0x62, 0x89, 0x66, 0xe4, 0x63, 0x1f, 0x9f, 0x0b, + 0xd6, 0x35, 0x08, 0xd3, 0xa3, 0xee, 0xbd, 0xf6, + 0x6d, 0x98, 0x95, 0x28, 0x75, 0x18, 0xce, 0x98, + 0x6e, 0xf6, 0x5c, 0x71, 0xf5, 0xf0, 0xeb, 0x06, + 0x59, 0xf1, 0x40, 0x8e, 0x84, 0xfe, 0xf0, 0x49, + 0x23, 0x4b, 0xb4, 0x6f, 0x38, 0xa4, 0xd8, 0x09, + 0x9e, 0xbe, 0x63, 0x9b, 0x20, 0xf3, 0xf7, 0xc7, + 0x2c, 0x71, 0xfe, 0x6a, 0xd3, 0x98, 0xe0, 0x74, + 0xea, 0x8e, 0xd8, 0x3c, 0x42, 0x7b, 0x03, 0x2d, + 0x02, 0x28, 0xb0, 0x99, 0x0f, 0x16, 0x54, 0x31, + 0x08, 0x27, 0x27, 0xb7, 0x7c, 0x31, 0x95, 0x1b, + 0x20, 0xfc, 0x47, 0x3b, 0xc6, 0x20, 0x8e, 0xd0, + 0xe7, 0x97, 0x43, 0xb6, 0x83, 0x74, 0x12, 0x01, + 0x43, 0x70, 0xc5, 0x71, 0x37, 0xf9, 0x13, 0xa2, + 0x7c, 0x4f, 0x7c, 0xf1, 0x8f, 0xec, 0x8a, 0xeb, + 0xb6, 0x04, 0x33, 0x99, 0xdc, 0xa5, 0x32, 0x9e, + 0x5c, 0xad, 0x7b, 0xbe, 0x1b, 0x8d, 0x0d, 0x79, + 0xbd, 0x51, 0x1f, 0xc2, 0x8d, 0x50, 0x2f, 0xbf, + 0x8f, 0x66, 0xa6, 0x22, 0x65, 0x73, 0xc6, 0xe5, + 0xf5, 0x66, 0x48, 0xf5, 0x75, 0x1c, 0x73, 0xec, + 0x4f, 0xc6, 0xa9, 0x59, 0x80, 0xa7, 0x52, 0xe5, + 0x51, 0xbc, 0x27, 0x2f, 0x1b, 0x6e, 0x7f, 0xc7, + 0xf6, 0x0a, 0x17, 0x51, 0xb5, 0x27, 0x44, 0xf9, + 0x5c, 0x0d, 0xb7, 0x10, 0xfb, 0x52, 0x1a, 0x21, + 0x03, 0x93, 0xaf, 0x60, 0xe2, 0xc7, 0x18, 0xa9, + 0xf2, 0xe9, 0x93, 0x42, 0xd2, 0x3c, 0xdb, 0xdb, + 0xcf, 0x0d, 0xbe, 0x03, 0x72, 0x52, 0xb7, 0x3d, + 0x0f, 0xda, 0x7a, 0x57, 0xbe, 0x15, 0x54, 0x3f, + 0xfd, 0x26, 0xd9, 0x55, 0xc1, 0xeb, 0xa4, 0x12, + 0x73, 0xe3, 0xf0, 0x45, 0x71, 0x9a, 0xdb, 0x47, + 0x3b, 0x64, 0xee, 0x6c, 0xfe, 0x05, 0x54, 0xee, + 0x1c, 0x6b, 0xf5, 0x44, 0x6d, 0xd0, 0x6b, 0x39, + 0x1c, 0x87, 0xe7, 0x99, 0x69, 0x84, 0xff, 0x32, + 0xe7, 0xbf, 0x54, 0x68, 0xa1, 0x01, 0xf0, 0x38, + 0x3d, 0x94, 0x39, 0x07, 0xfd, 0x87, 0x1b, 0x87, + 0x36, 0x15, 0xed, 0x54, 0x0e, 0x58, 0xb2, 0xac, + 0x73, 0x7c, 0xe9, 0x6e, 0xcb, 0xea, 0x32, 0xd3, + 0x2b, 0x97, 0x1d, 0x6d, 0x40, 0x75, 0xe1, 0x6f, + 0xa5, 0x4d, 0xd7, 0xdc, 0x64, 0xba, 0x52, 0x02, + 0xc5, 0x71, 0xe6, 0x55, 0xc0, 0xc6, 0xe3, 0x3f, + 0x51, 0x8f, 0x02, 0xa8, 0x25, 0x8e, 0x82, 0x0e, + 0x32, 0xf8, 0x66, 0x85, 0x26, 0xba, 0x66, 0x80, + 0x2b, 0x9f, 0x8a, 0xb7, 0xb3, 0x61, 0x8e, 0xa3, + 0xa5, 0x43, 0xa0, 0x0a, 0x67, 0x57, 0xb4, 0x3a, + 0x3f, 0x87, 0x60, 0x11, 0xec, 0xe6, 0xbb, 0x85, + 0x56, 0x27, 0x46, 0x68, 0x73, 0xd6, 0xc0, 0x87, + 0xd3, 0xde, 0x51, 0xec, 0x21, 0x68, 0x0a, 0x91, + 0xa5, 0x91, 0x11, 0x76, 0xc8, 0x0e, 0x8a, 0xc0, + 0xa0, 0x7a, 0xb4, 0x82, 0xbf, 0x83, 0x18, 0xa0, + 0xd5, 0xe2, 0x28, 0xc5, 0x86, 0x9f, 0x18, 0x33, + 0xaa, 0x58, 0x40, 0x14, 0x55, 0x81, 0xb1, 0x4c, + 0xce, 0x09, 0xc4, 0x4d, 0x01, 0x7d, 0x15, 0x8b, + 0xba, 0xfd, 0x05, 0xa2, 0x43, 0xb4, 0xad, 0x33, + 0xdc, 0x0b, 0x59, 0x2b, 0x9b, 0xb2, 0x71, 0xaa, + 0x4c, 0x26, 0x33, 0x60, 0x4d, 0xb3, 0x53, 0x71, + 0xdb, 0xf7, 0x21, 0xbc, 0x4b, 0x13, 0xf8, 0x37, + 0xf5, 0x94, 0xb7, 0x46, 0x10, 0x9d, 0x58, 0x7b, + 0xb0, 0x4f, 0xd7, 0x56, 0x75, 0x6c, 0x23, 0x5a, + 0x68, 0x68, 0xa2, 0x53, 0x7f, 0x1f, 0x38, 0x6f, + 0x69, 0x3f, 0x95, 0x3e, 0x7b, 0x59, 0x23, 0x04, + 0xab, 0xa0, 0xd4, 0xa6, 0x7a, 0xfa, 0x94, 0xbb, + 0x94, 0x71, 0x83, 0xa9, 0xc3, 0xf1, 0x21, 0x69, + 0x01, 0xf0, 0x65, 0x57, 0x75, 0x28, 0xc2, 0xa9, + 0x75, 0x3c, 0x4f, 0xd8, 0xd3, 0xc6, 0xb6, 0xd7, + 0x26, 0xce, 0x0c, 0xb8, 0x64, 0x11, 0x59, 0x2c, + 0x7f, 0x81, 0x6e, 0xf9, 0x7e, 0xa3, 0x32, 0x24, + 0x42, 0xdb, 0xe0, 0x5e, 0x09, 0xda, 0x32, 0xf5, + 0xa1, 0x49, 0x0c, 0x0f, 0xd4, 0x4b, 0xe2, 0x30, + 0xc6, 0xa9, 0x77, 0xb0, 0x06, 0xaa, 0x71, 0x3b, + 0x8e, 0x57, 0xcb, 0x78, 0xcb, 0x16, 0x52, 0x31, + 0x7d, 0xc7, 0x6c, 0x9d, 0x63, 0xa7, 0x4c, 0x2b, + 0xab, 0x6f, 0xf8, 0xdc, 0x03, 0x85, 0x8e, 0x24, + 0x5a, 0xf6, 0x4c, 0xf7, 0x63, 0x34, 0x3c, 0xbc, + 0xff, 0x2b, 0xc7, 0xfc, 0x3c, 0xa0, 0x8a, 0xb4, + 0x8a, 0x8c, 0x52, 0x53, 0xa2, 0x8f, 0xf3, 0xdc, + 0x19, 0x74, 0x83, 0x96, 0x70, 0x9e, 0x9a, 0x47, + 0x5d, 0xc7, 0x93, 0xd4, 0x74, 0x0b, 0xed, 0xdc, + 0x4f, 0x25, 0xa2, 0xe0, 0x4c, 0x8c, 0x1c, 0x7f, + 0x90, 0xd6, 0xa4, 0x92, 0xde, 0x63, 0xd7, 0x93, + 0x96, 0x2e, 0xbb, 0x62, 0x9b, 0x64, 0x16, 0x7d, + 0x44, 0x1b, 0xd0, 0xd0, 0xe7, 0xa3, 0x37, 0x53, + 0xb0, 0xd5, 0x08, 0xe5, 0x35, 0x8c, 0x5b, 0x7a, + 0xbb, 0xcb, 0x70, 0xe2, 0x38, 0x96, 0xc1, 0x5c, + 0x94, 0xd5, 0xc4, 0x51, 0x59, 0x3a, 0x7f, 0x3c, + 0xf9, 0x50, 0x52, 0x9b, 0x8e, 0x6c, 0x3a, 0x46, + 0x9e, 0xf5, 0xbc, 0x17, 0xd5, 0x12, 0x11, 0xcd, + 0xe8, 0xd0, 0xd6, 0x5b, 0xbc, 0xd1, 0x8f, 0x66, + 0x62, 0xa6, 0x35, 0xcb, 0x19, 0x24, 0x14, 0xb6, + 0x87, 0xf5, 0x3d, 0x53, 0xe7, 0xf3, 0x4a, 0xbf, + 0xd1, 0x57, 0xad, 0x0f, 0x78, 0x8b, 0x95, 0x1f, + 0x2d, 0x80, 0x89, 0xc8, 0x78, 0xa7, 0x65, 0x3d, + 0x9d, 0x39, 0x7c, 0x68, 0x0e, 0x39, 0xfe, 0x8e, + 0xcb, 0x26, 0xc0, 0x61, 0x40, 0x18, 0x67, 0x29, + 0x72, 0xa8, 0xfe, 0x26, 0x54, 0x15, 0x19, 0x3d, + 0xb2, 0x39, 0x67, 0x73, 0xc2, 0x9d, 0x5e, 0x5e, + 0x0d, 0x59, 0x6a, 0x2f, 0x99, 0xb2, 0x92, 0x13, + 0xd1, 0xc4, 0xf3, 0x21, 0x08, 0x93, 0xc1, 0x87, + 0x15, 0xac, 0x9b, 0xfb, 0x85, 0xda, 0xea, 0x92, + 0xaf, 0xa1, 0x33, 0x0b, 0x31, 0x46, 0xa9, 0x51, + 0xe9, 0xe8, 0xda, 0x48, 0x8d, 0xe9, 0xf2, 0x12, + 0xbf, 0x80, 0x00, 0x49, 0x57, 0x49, 0xb2, 0x7d, + 0x8b, 0x08, 0x7e, 0x0d, 0xb9, 0x67, 0xd2, 0x0c, + 0x52, 0x18, 0x6f, 0xa2, 0xbb, 0x5b, 0x69, 0x79, + 0xb4, 0x4a, 0x75, 0x17, 0x60, 0x19, 0xce, 0xbf, + 0xce, 0x78, 0xb2, 0x09, 0x53, 0x9d, 0x58, 0x37, + 0x7b, 0x2b, 0x29, 0x92, 0x9b, 0x2d, 0x56, 0x1a, + 0x11, 0xa4, 0x30, 0xae, 0xf2, 0xae, 0x54, 0x75, + 0x1b, 0xb8, 0xb0, 0xbb, 0x2f, 0x78, 0xfc, 0xc5, + 0xa9, 0x79, 0x98, 0x4c, 0xb4, 0x2f, 0x30, 0xe8, + 0xce, 0xaf, 0x6e, 0x67, 0x22, 0x24, 0x66, 0x72, + 0xb6, 0xc3, 0xf4, 0x6c, 0x72, 0x2f, 0x1d, 0xa6, + 0x48, 0x25, 0xba, 0x8d, 0x3c, 0x13, 0x76, 0x1d, + 0x3d, 0xb7, 0xd5, 0xbf, 0x0b, 0x8b, 0x71, 0x71, + 0x05, 0x7b, 0x95, 0xa3, 0x6b, 0x9f, 0x99, 0xb6, + 0xfd, 0x68, 0x73, 0x56, 0xbb, 0x65, 0x6e, 0xbc, + 0x4f, 0xa3, 0x79, 0x32, 0xc9, 0xc7, 0xb4, 0x09, + 0xd3, 0x35, 0x3b, 0x5c, 0x74, 0x54, 0x6d, 0xd0, + 0x5d, 0x0f, 0xb4, 0xb0, 0x1d, 0x96, 0xef, 0xf6, + 0x95, 0xe2, 0x12, 0xd8, 0xb0, 0x7b, 0xd7, 0xf9, + 0x6c, 0x9d, 0xc4, 0x8b, 0xe6, 0xb1, 0xc2, 0x41, + 0x4b, 0xbd, 0xd5, 0x3d, 0xcb, 0xc1, 0x02, 0x49, + 0xd1, 0x05, 0x70, 0x58, 0x95, 0x42, 0x24, 0xc7, + 0x0a, 0xa7, 0x1c, 0x3f, 0x12, 0x6d, 0x36, 0x14, + 0xc6, 0xdf, 0x6b, 0x88, 0x3e, 0x69, 0x7f, 0xa1, + 0xcf, 0x27, 0xa6, 0x7f, 0x30, 0xdb, 0xef, 0x1d, + 0xdd, 0x71, 0xe9, 0xc3, 0x50, 0x34, 0xf1, 0x15, + 0xf9, 0xa1, 0x7d, 0x64, 0x51, 0x94, 0xf7, 0x70, + 0xc6, 0x28, 0xa4, 0x23, 0xbf, 0x03, 0xd9, 0x90, + 0x6e, 0x2b, 0x22, 0x02, 0x95, 0xc2, 0x1f, 0xbf, + 0x33, 0x57, 0x54, 0x6e, 0x00, 0x3b, 0xce, 0xf2, + 0x74, 0x33, 0x6d, 0x1b, 0x6e, 0x84, 0x51, 0xc0, + 0xef, 0xa7, 0x4d, 0xa9, 0x49, 0x3a, 0x2a, 0x11, + 0x45, 0xbd, 0xbf, 0xac, 0xa1, 0xed, 0x03, 0x4f, + 0x0b, 0x36, 0xda, 0x73, 0x51, 0xec, 0x48, 0xa4, + 0xa0, 0x9a, 0x5e, 0xa3, 0x57, 0x96, 0xf4, 0xe9, + 0x2f, 0x52, 0xa1, 0x49, 0x3f, 0xe1, 0x3e, 0xe3, + 0x2e, 0x67, 0x77, 0x96, 0xe5, 0xbd, 0x63, 0x55, + 0x88, 0xdf, 0x69, 0xc6, 0x44, 0xf8, 0xb8, 0xa4, + 0x92, 0x9d, 0x15, 0x00, 0xe8, 0xdb, 0xf0, 0xd0, + 0x64, 0x31, 0xfb, 0x36, 0x4f, 0x50, 0x18, 0x8c, + 0xe1, 0x48, 0x3f, 0xbe, 0x3d, 0xaa, 0xae, 0x4c, + 0x34, 0xb7, 0xb1, 0x44, 0x0f, 0x2e, 0xa3, 0xa6, + 0xd7, 0xe3, 0x71, 0xe3, 0x9c, 0xe1, 0xc9, 0x2a, + 0xbd, 0x65, 0x94, 0x01, 0xbf, 0x29, 0x1b, 0x77, + 0x02, 0x47, 0xef, 0x7f, 0x41, 0xc7, 0x81, 0xa3, + 0xbf, 0x27, 0x2c, 0x85, 0x72, 0x10, 0x65, 0x40, + 0x53, 0x36, 0x0d, 0x40, 0x82, 0x78, 0x9c, 0x1f, + 0xa9, 0x03, 0x74, 0x3f, 0xd6, 0xbc, 0x16, 0xdc, + 0x78, 0x54, 0x72, 0x5d, 0x5c, 0xe5, 0x0d, 0xa5, + 0x56, 0x4f, 0x62, 0xa3, 0x83, 0x9f, 0x3b, 0xd6, + 0xa6, 0xc6, 0x63, 0x7f, 0xdc, 0x09, 0x21, 0x08, + 0x88, 0xfb, 0x34, 0xad, 0xcb, 0x7e, 0x67, 0x8d, + 0x68, 0xf2, 0x87, 0xdf, 0xb7, 0xb8, 0xe6, 0xe8, + 0xe5, 0x9c, 0x1e, 0xa5, 0xb4, 0x44, 0x27, 0x73, + 0x41, 0x5e, 0x12, 0x7a, 0x0c, 0x98, 0x3f, 0xc4, + 0x95, 0x77, 0x9f, 0x24, 0x89, 0x0a, 0xc8, 0xa4, + 0x7d, 0xfd, 0xa5, 0xbb, 0x3a, 0x87, 0x67, 0x43, + 0x75, 0x3f, 0x52, 0x75, 0x78, 0x4c, 0x13, 0xe1, + 0x7b, 0xad, 0x2c, 0x47, 0xa3, 0x15, 0x79, 0xbf, + 0x8e, 0x03, 0x51, 0xf4, 0xe7, 0x7d, 0x35, 0x16, + 0x03, 0x0c, 0x31, 0xf2, 0x87, 0x2b, 0x89, 0xb9, + 0xa2, 0x8a, 0xe8, 0xc2, 0x8b, 0x59, 0xde, 0xee, + 0x50, 0x17, 0x41, 0x56, 0xf9, 0x2f, 0x32, 0xcd, + 0x92, 0xfc, 0x1d, 0x14, 0xed, 0xe0, 0x6f, 0x2c, + 0xd5, 0x7c, 0xac, 0x7e, 0x6a, 0xbf, 0x8b, 0x48, + 0x94, 0xbb, 0x13, 0x2d, 0x49, 0x3e, 0xf1, 0x83, + 0x98, 0x8d, 0xb6, 0x30, 0x24, 0xcd, 0xaa, 0xd3, + 0x4a, 0xe1, 0xdd, 0xfd, 0x50, 0xdd, 0x63, 0x0f, + 0x70, 0xd6, 0x9e, 0x71, 0xe5, 0xa9, 0x8b, 0x40, + 0x62, 0x73, 0x8b, 0x81, 0xb6, 0x3c, 0x17, 0x9c, + 0x56, 0xc0, 0xd3, 0x75, 0x1a, 0x86, 0xa8, 0x13, + 0x75, 0xa0, 0xac, 0x56, 0xc8, 0x7f, 0xe2, 0x32, + 0xcb, 0x20, 0xe7, 0x98, 0xb7, 0x48, 0x83, 0xae, + 0x9b, 0x70, 0xc0, 0x50, 0xed, 0xa4, 0x8c, 0xc4, + 0x25, 0xae, 0x6a, 0xdf, 0x1a, 0xcd, 0x48, 0x06, + 0x80, 0x78, 0xed, 0xa4, 0xcc, 0x51, 0x8b, 0x40, + 0xa4, 0x05, 0xd3, 0xe6, 0x43, 0x5a, 0x77, 0x98, + 0x0e, 0xc6, 0x96, 0xdd, 0x72, 0x2c, 0x83, 0x43, + 0x0d, 0x09, 0x76, 0x79, 0xf9, 0xe7, 0xcb, 0xdd, + 0x48, 0xf3, 0x2e, 0xf8, 0x7c, 0xa2, 0xdd, 0xcc, + 0xe6, 0x97, 0x50, 0x9e, 0x73, 0x3d, 0x5f, 0x66, + 0xae, 0xeb, 0x05, 0x5c, 0xc9, 0xae, 0xc1, 0x89, + 0x23, 0x31, 0x1e, 0xfd, 0x89, 0xca, 0x7e, 0x87, + 0x16, 0xca, 0xff, 0x8d, 0x40, 0xb6, 0x1c, 0xad, + 0xd2, 0x0c, 0xa4, 0xcd, 0x26, 0x89, 0x22, 0x75, + 0x4d, 0xb3, 0x85, 0xf4, 0xc1, 0xaf, 0x7d, 0x0f, + 0x06, 0x40, 0x48, 0x2b, 0xba, 0x21, 0x5d, 0x41, + 0xfb, 0x38, 0xae, 0x6a, 0x6e, 0x1d, 0x83, 0xfb, + 0xb3, 0x50, 0x32, 0xf7, 0xb8, 0x2f, 0x3f, 0xcc, + 0x15, 0x9c, 0x04, 0x52, 0x0b, 0x07, 0xec, 0x56, + 0x13, 0x38, 0x9f, 0x7f, 0x89, 0xe3, 0xff, 0x13, + 0xe1, 0xbf, 0x32, 0x94, 0xa8, 0x2c, 0x0c, 0xb1, + 0x8d, 0xb9, 0x66, 0xa6, 0x43, 0xab, 0x2a, 0xd7, + 0xd0, 0xcd, 0x15, 0xf3, 0x92, 0xd0, 0x37, 0xa9, + 0x7e, 0x88, 0xd6, 0x5e, 0x9d, 0x09, 0xe0, 0x0d, + 0x22, 0x30, 0x1a, 0x38, 0xfe, 0xd8, 0x4a, 0x9a, + 0x19, 0x30, 0x85, 0x49, 0x3c, 0x3a, 0x20, 0x8b, + 0xcb, 0x83, 0x3f, 0x6b, 0xa4, 0x6c, 0x03, 0x35, + 0xd5, 0x3c, 0x7d, 0x36, 0x90, 0xb0, 0x2b, 0xf5, + 0x74, 0x3a, 0xc9, 0x2f, 0xdb, 0x30, 0x1c, 0x6d, + 0x12, 0x54, 0x95, 0x99, 0x91, 0xbd, 0x25, 0x40, + 0xd2, 0x08, 0x76, 0x9e, 0x1b, 0x17, 0x3c, 0xaf, + 0x61, 0x91, 0x17, 0x09, 0x0c, 0x28, 0x47, 0x58, + 0x07, 0xed, 0xac, 0x77, 0x00, 0xf7, 0x1d, 0x30, + 0xd7, 0xab, 0x47, 0xe3, 0x93, 0x88, 0xe9, 0xb6, + 0x35, 0x52, 0xe5, 0x97, 0x13, 0x4b, 0xb6, 0x60, + 0x67, 0x9c, 0xbf, 0xbd, 0x22, 0x8f, 0x12, 0xec, + 0x42, 0x9c, 0xc2, 0x40, 0x51, 0xa4, 0xd5, 0x04, + 0x8b, 0xfc, 0x0f, 0xf0, 0x52, 0xe5, 0x07, 0x0c, + 0xd5, 0xc9, 0x83, 0xc4, 0x60, 0x01, 0xd0, 0x2e, + 0x84, 0x90, 0xd7, 0xd2, 0x18, 0x87, 0xce, 0x6e, + 0x54, 0xbe, 0xbf, 0x8a, 0x51, 0xa8, 0x86, 0x6b, + 0xeb, 0x09, 0xc8, 0xd1, 0xcc, 0xa9, 0x5e, 0x36, + 0xd5, 0x36, 0xff, 0xb1, 0xf4, 0x00, 0x90, 0xf7, + 0xb4, 0x8b, 0x88, 0x83, 0xba, 0x5d, 0x01, 0x5c, + 0x25, 0x74, 0x4b, 0xb8, 0x93, 0x28, 0xa1, 0xe2, + 0x68, 0xa5, 0x9d, 0xe6, 0x40, 0xc3, 0xf1, 0x7e, + 0x29, 0x30, 0x18, 0xb3, 0x54, 0xa3, 0x43, 0x80, + 0xba, 0xa7, 0x92, 0x74, 0xb2, 0xd1, 0x76, 0xac, + 0xbd, 0x39, 0x0f, 0x09, 0x2a, 0xf5, 0xa2, 0x5a, + 0x41, 0x9f, 0x82, 0xa2, 0xef, 0x70, 0x6c, 0x62, + 0x85, 0xee, 0x2e, 0xc0, 0x10, 0x80, 0xc7, 0x2c, + 0x9a, 0x4a, 0xc3, 0xf2, 0x73, 0x8d, 0x69, 0xf5, + 0xfb, 0x2f, 0x35, 0x2d, 0xe9, 0xa8, 0x8c, 0x6b, + 0xa4, 0x0c, 0x8b, 0xa8, 0x96, 0xea, 0x66, 0xfc, + 0xeb, 0x9d, 0xe5, 0xb4, 0x31, 0xf9, 0xf1, 0x05, + 0x67, 0x2e, 0x97, 0x04, 0x00, 0xa7, 0x6c, 0xa3, + 0x41, 0x76, 0x76, 0x0b, 0x5f, 0xd3, 0x5e, 0xc9, + 0xf4, 0xac, 0x6f, 0x19, 0x68, 0x5b, 0xdb, 0x08, + 0x13, 0x2b, 0x1b, 0x5a, 0x05, 0xd8, 0x43, 0xc4, + 0x34, 0x7f, 0x13, 0x06, 0x4d, 0x49, 0x95, 0xb1, + 0xa3, 0xa2, 0x1a, 0x58, 0xf6, 0x84, 0x19, 0x1c, + 0x5a, 0x89, 0x62, 0xe0, 0xf3, 0xd6, 0x00, 0x03, + 0x79, 0xca, 0xc8, 0x4a, 0x30, 0xeb, 0x3f, 0xaf, + 0x29, 0x47, 0x1f, 0xa1, 0xef, 0x57, 0x98, 0x25, + 0xc9, 0xa0, 0xe9, 0x8b, 0xc2, 0x69, 0xf9, 0xa1, + 0x4f, 0x89, 0x2a, 0x70, 0xdf, 0x17, 0xf6, 0xfe, + 0xd2, 0xb6, 0xcb, 0x5e, 0x7c, 0xad, 0x9c, 0x9c, + 0xc3, 0x07, 0x0c, 0x70, 0x8d, 0xe0, 0xd4, 0x31, + 0x56, 0xfb, 0xb1, 0xa3, 0x1b, 0x90, 0x63, 0x9e, + 0x1e, 0x16, 0x5b, 0xd6, 0x33, 0xb7, 0x7e, 0xd3, + 0xd8, 0xf0, 0x62, 0x79, 0xce, 0xca, 0x50, 0x43, + 0x40, 0xc2, 0x41, 0xc6, 0xcd, 0x16, 0xa6, 0xc1, + 0x12, 0x0b, 0x28, 0xa1, 0x9a, 0xc2, 0xda, 0xfd, + 0x3f, 0x3a, 0xb9, 0xfe, 0xbc, 0x13, 0x3c, 0x75, + 0xc8, 0x36, 0x87, 0x29, 0xfe, 0x29, 0xb6, 0xf9, + 0x50, 0x17, 0xa8, 0xc8, 0x9c, 0x88, 0x6d, 0x44, + 0xfa, 0xa0, 0xeb, 0xa9, 0xdf, 0x50, 0x13, 0x15, + 0x70, 0xa1, 0x0b, 0x63, 0xed, 0x33, 0x97, 0x71, + 0xb6, 0xd1, 0xc3, 0xf0, 0x59, 0xf5, 0x18, 0xd3, + 0xb8, 0x79, 0xaa, 0x97, 0x42, 0x3f, 0x62, 0x66, + 0xf7, 0x04, 0x3d, 0x0f, 0x05, 0x5a, 0xbc, 0x08, + 0x0d, 0xec, 0x6c, 0x99, 0x30, 0x22, 0x16, 0x3d, + 0x93, 0x35, 0xee, 0x06, 0x0e, 0x17, 0x70, 0xb2, + 0x97, 0x88, 0x79, 0x91, 0x1b, 0x47, 0xb7, 0xdd, + 0x5c, 0x68, 0x0c, 0x50, 0xf2, 0x09, 0xe2, 0xaa, + 0x37, 0xc7, 0x9b, 0x47, 0xf7, 0x1b, 0x74, 0x46, + 0x95, 0x49, 0x5b, 0xf3, 0x50, 0x34, 0xfa, 0xf7, + 0x99, 0x27, 0x96, 0x5b, 0x7b, 0xd8, 0x3e, 0x3a, + 0x4a, 0xc2, 0x9a, 0x85, 0x07, 0x94, 0xc6, 0xdf, + 0x92, 0x40, 0x3c, 0xe2, 0x3b, 0x4c, 0x39, 0xe7, + 0x41, 0x8a, 0x4c, 0x95, 0x07, 0x0b, 0x26, 0x0e, + 0x45, 0x07, 0x73, 0xaf, 0x1f, 0x53, 0xe8, 0xc2, + 0x1e, 0x98, 0xb9, 0xd1, 0x34, 0xa7, 0xbe, 0x73, + 0xa7, 0x61, 0xcb, 0x1e, 0x42, 0xed, 0xe1, 0x20, + 0xfd, 0x2c, 0x85, 0x0f, 0x18, 0x21, 0xf6, 0x06, + 0xf3, 0x6d, 0x84, 0xff, 0xa4, 0xaa, 0x6b, 0xdd, + 0xbe, 0x55, 0x29, 0x8e, 0x4d, 0x81, 0xc1, 0x30, + 0x05, 0xf5, 0x1d, 0x69, 0x56, 0xa7, 0x0d, 0x72, + 0x10, 0xd0, 0x68, 0x27, 0x96, 0xda, 0x2e, 0xc0, + 0xd6, 0x6f, 0xc5, 0x41, 0xe7, 0xf6, 0xed, 0xc4, + 0xd9, 0xf3, 0x56, 0x40, 0x0b, 0xdb, 0x55, 0xda, + 0x5f, 0x95, 0x30, 0x53, 0x3c, 0xe5, 0xfd, 0x9f, + 0x69, 0xa1, 0x82, 0xa2, 0x2f, 0x07, 0x88, 0xf3, + 0x4a, 0xbc, 0xe7, 0xe0, 0xa3, 0x6f, 0xc6, 0x1e, + 0x56, 0x0c, 0xff, 0xe7, 0x8f, 0xf0, 0xa8, 0xf2, + 0x41, 0x34, 0x19, 0x7f, 0x5c, 0x4a, 0xd1, 0x30, + 0xc3, 0xfb, 0x24, 0xdf, 0x0c, 0xd8, 0x30, 0x54, + 0x1d, 0xad, 0xa3, 0x45, 0x9e, 0xae, 0x97, 0xc2, + 0x9f, 0xf7, 0x7b, 0x4d, 0x66, 0x8f, 0xcc, 0x86, + 0x29, 0x8d, 0xc5, 0x87, 0x61, 0x16, 0x97, 0x19, + 0x6f, 0xf7, 0x63, 0x37, 0xb1, 0x6e, 0x19, 0x04, + 0x20, 0x6f, 0x31, 0x09, 0x24, 0xf3, 0x61, 0x42, + 0x2b, 0x92, 0x44, 0x91, 0x42, 0x7f, 0xe3, 0x0d, + 0xba, 0xfb, 0x7f, 0x33, 0x88, 0xe8, 0x71, 0x25, + 0xf2, 0xbb, 0xd5, 0x25, 0x58, 0xd3, 0x2e, 0x38, + 0x4f, 0x57, 0x70, 0x32, 0xa5, 0x59, 0xe4, 0x02, + 0xbb, 0x33, 0x75, 0x35, 0xb5, 0xe1, 0x0d, 0xcd, + 0x46, 0x0f, 0x6d, 0x86, 0xd3, 0x8f, 0x1e, 0xe5, + 0xa5, 0x8b, 0x9a, 0xa7, 0x4c, 0x0b, 0xca, 0x9a, + 0x64, 0x6e, 0x2f, 0xab, 0x9f, 0x21, 0xd6, 0x8d, + 0x6b, 0x29, 0x6a, 0x78, 0xa8, 0x4c, 0x15, 0x3d, + 0x8c, 0x3b, 0xac, 0xc6, 0x70, 0xeb, 0x41, 0xbe, + 0x41, 0x74, 0x9b, 0xe5, 0x87, 0xa3, 0x1c, 0xbe, + 0x47, 0x6e, 0x2d, 0x92, 0xbe, 0x80, 0xb4, 0x92, + 0xcc, 0x9e, 0x0b, 0x05, 0x75, 0xab, 0x9b, 0x76, + 0xd1, 0xde, 0x22, 0x32, 0x78, 0x69, 0xfb, 0x1b, + 0xe8, 0x4d, 0x49, 0x97, 0x23, 0xeb, 0x51, 0x38, + 0x9a, 0x22, 0xa7, 0xc0, 0xcf, 0x25, 0x3a, 0x4e, + 0x50, 0x0d, 0xff, 0x8e, 0xb5, 0x91, 0xd3, 0x85, + 0x54, 0xe9, 0x1f, 0x70, 0xea, 0x64, 0x6a, 0x77, + 0xbe, 0xd2, 0x15, 0xce, 0x9c, 0xb0, 0x70, 0x61, + 0x8b, 0x58, 0xdb, 0x9f, 0x0a, 0xe4, 0x80, 0xb3, + 0x21, 0x44, 0x0b, 0xea, 0x43, 0xab, 0x0d, 0xf0, + 0x7e, 0xbc, 0xd5, 0xde, 0x29, 0x12, 0xcd, 0xde, + 0xd9, 0xf3, 0xf3, 0x0e, 0xf4, 0xb8, 0x3d, 0xd7, + 0x4e, 0x24, 0xcf, 0x9b, 0x4b, 0xad, 0x96, 0x1e, + 0xca, 0x6d, 0x3f, 0x9c, 0xe4, 0xb8, 0x8b, 0xf5, + 0x3a, 0x43, 0xb0, 0xce, 0x16, 0x27, 0x87, 0xe3, + 0x1b, 0x54, 0xd0, 0xed, 0x3c, 0xe2, 0xb0, 0x1f, + 0x24, 0xa3, 0x6d, 0x31, 0x00, 0x7d, 0x58, 0x69, + 0xc9, 0xc6, 0x50, 0xc8, 0x87, 0xac, 0x45, 0x54, + 0x66, 0x06, 0x7f, 0xc3, 0x51, 0xb8, 0xdf, 0x51 +}; + +/*---------------------------------------------------------------------------------------- + * P R O T O T Y P E S O F L O C A L F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * E X P O R T E D F U N C T I O N S + *---------------------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/Makefile.inc b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/Makefile.inc index 7d52cb6dae7..e4b04247b26 100644 --- a/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/Makefile.inc +++ b/src/vendorcode/amd/agesa/f15tn/Proc/CPU/Family/0x15/TN/Makefile.inc @@ -4,7 +4,7 @@ libagesa-y += F15TnEquivalenceTable.c libagesa-y += F15TnInitEarlyTable.c libagesa-y += F15TnIoCstate.c libagesa-y += F15TnLogicalIdTables.c -libagesa-y += F15TnMicrocodePatch0600110F_Enc.c +libagesa-y += F15TnMicrocodePatch0600111F_Enc.c libagesa-y += F15TnMicrocodePatchTables.c libagesa-y += F15TnMsrTables.c libagesa-y += F15TnPciTables.c From ddbf2c4af05b5cbd889d6a55e67734c8a041bc66 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Wed, 15 May 2019 08:42:20 -0600 Subject: [PATCH 365/588] soc/intel/cannonlake: Configure SPI CS parameters in FSP UPD. When FSP UPD parameters are configured, also configure the GSPI CS lines appropriately. GSPI driver assumes CS0 is the CS signal to use. BUG=b:130329260 BRANCH=None TEST=Boot Kohaku, TPM communcation still functional. Change-Id: Ic816395b7d198a52c704e6cabcb56889150b741c Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32791 Reviewed-by: Patrick Georgi Reviewed-by: Paul Fagerburg Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/fsp_params.c | 43 +++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/soc/intel/cannonlake/fsp_params.c b/src/soc/intel/cannonlake/fsp_params.c index cc01d10fe81..dd9388296d7 100644 --- a/src/soc/intel/cannonlake/fsp_params.c +++ b/src/soc/intel/cannonlake/fsp_params.c @@ -119,6 +119,28 @@ static void ignore_gbe_ltr(void) write8(pmcbase + LTR_IGN, reg8); } +static void configure_gspi_cs(int idx, const config_t *config, + uint8_t *polarity, uint8_t *enable, + uint8_t *defaultcs) +{ + struct spi_cfg cfg; + + /* If speed_mhz is set, infer that the port should be configured */ + if (config->common_soc_config.gspi[idx].speed_mhz != 0) { + if (gspi_get_soc_spi_cfg(idx, &cfg) == 0) { + if (cfg.cs_polarity == SPI_POLARITY_LOW) + *polarity = 0; + else + *polarity = 1; + + if (defaultcs != NULL) + *defaultcs = 0; + if (enable != NULL) + *enable = 1; + } + } +} + /* UPD parameters to be initialized before SiliconInit */ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) { @@ -357,6 +379,27 @@ void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd) /* Unlock all GPIO pads */ tconfig->PchUnlockGpioPads = config->PchUnlockGpioPads; + + /* + * GSPI Chip Select parameters + * The GSPI driver assumes that CS0 is the used chip-select line, + * therefore only CS0 is configured below. + */ +#if CONFIG(SOC_INTEL_COMETLAKE) + configure_gspi_cs(0, config, ¶ms->SerialIoSpi0CsPolarity[0], + ¶ms->SerialIoSpi0CsEnable[0], + ¶ms->SerialIoSpiDefaultCsOutput[0]); + configure_gspi_cs(1, config, ¶ms->SerialIoSpi1CsPolarity[0], + ¶ms->SerialIoSpi1CsEnable[0], + ¶ms->SerialIoSpiDefaultCsOutput[1]); + configure_gspi_cs(2, config, ¶ms->SerialIoSpi2CsPolarity[0], + ¶ms->SerialIoSpi2CsEnable[0], + ¶ms->SerialIoSpiDefaultCsOutput[2]); +#else + for (i = 0; i < CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX; i++) + configure_gspi_cs(i, config, + ¶ms->SerialIoSpiCsPolarity[0], NULL, NULL); +#endif } /* Mainboard GPIO Configuration */ From 365cb144c8622faff5043cbca8ff80751998556c Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sun, 19 May 2019 23:31:48 +0200 Subject: [PATCH 366/588] src/drivers/intel/fsp2_0: Fix logical 'and' of equal expressions Probably a copy/paste issue. Change-Id: I0334bc1f5d145df5af0a307cf8e7c23cc0605f76 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32886 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/drivers/intel/fsp2_0/hand_off_block.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/drivers/intel/fsp2_0/hand_off_block.c b/src/drivers/intel/fsp2_0/hand_off_block.c index 5efd59058c5..c5c78cabf0a 100644 --- a/src/drivers/intel/fsp2_0/hand_off_block.c +++ b/src/drivers/intel/fsp2_0/hand_off_block.c @@ -237,9 +237,9 @@ static void display_fsp_version_info_hob(const void *hob, size_t size) /* Don't show ingredient name and version if its all 0xFF */ if (fvi[index].Version.MajorVersion == 0xFF && - fvi[index].Version.MajorVersion == 0xFF && - fvi[index].Version.MajorVersion == 0xFF && - fvi[index].Version.MajorVersion == 0xFF && + fvi[index].Version.MinorVersion == 0xFF && + fvi[index].Version.Revision == 0xFF && + fvi[index].Version.BuildNumber == 0xFF && fvi[index].VersionStringIndex == 0) { str_ptr = (char *)((uintptr_t)str_ptr + cnt + sizeof(uint8_t)); From 86fa2792b98cabd0b8604342a44e099d8ade5a77 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 19 May 2019 14:41:28 +0200 Subject: [PATCH 367/588] mb/lenovo/t400: Add VBT file All variants (t400, r400, t500, w500) use the same OPROM for the IGD. Change-Id: I1b9db7b29b22809542f80f60a5e2eb3283fe1c02 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32884 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Patrick Rudolph --- src/mainboard/lenovo/t400/Kconfig | 1 + src/mainboard/lenovo/t400/data.vbt | Bin 0 -> 3863 bytes 2 files changed, 1 insertion(+) create mode 100644 src/mainboard/lenovo/t400/data.vbt diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig index 9f9405162cf..16f16803761 100644 --- a/src/mainboard/lenovo/t400/Kconfig +++ b/src/mainboard/lenovo/t400/Kconfig @@ -25,6 +25,7 @@ config BOARD_SPECIFIC_OPTIONS select DRIVERS_LENOVO_HYBRID_GRAPHICS select MAINBOARD_HAS_LIBGFXINIT select MAINBOARD_USES_IFD_GBE_REGION + select INTEL_GMA_HAVE_VBT config MAINBOARD_DIR string diff --git a/src/mainboard/lenovo/t400/data.vbt b/src/mainboard/lenovo/t400/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..e9bfaaf65126d9ef41fcc3be62f6b9505f213828 GIT binary patch literal 3863 zcmcImZ)_Ar6o31FZ*KQ`w-kCU1*Sk?i?nP@sX$8H_A0iufwq*UK@;xaPDBc=r4UFo zU8D&liq`mrAi;hi5kizNe)5AgF@c0=)I>0f(r*Mb;e&|@#B_Z#yVp`%Xo)bFncv$t z@BQY@%$u28-qp}aQ}tUqn_sG@Vab96MFqcLJH0eCZ{4=DvA(l@XG81O)XVf^SOB+U z<97kFf?#S@8`f`VJ}{8$u{+9BnF9lR_he{Ws+rdB-ks~o^=AfhS-PzYhhjV?X*jgE zCrh^++P^E;zmYO$w5C-xm1}D#b*k4?Icut&Du>A%o#!{!Y%odV-h+KTnWJsJ{R1>} zAWIv&npe~Q-2UFfIojCSxNMzCrbnIEqs%*w$dbwbyU)2WD*q6j)AaYoI<0l$`OHxhAat+Vk%KVQ|2o# zDlvJpT%aTpqA7^zQYJzq4xL^3FhH4*fO1iXrEzH8+?Lm)lN8EI5R$|N zDlm-;KTa_a0a&oCP?W<$^TMO>*&0X~s$2?AbxrO1jdgBA5 zK2!qZZ(wMAMm$78hzS(VXp5mnwjm>nuuonOm*lJPKy{!(OF|RY-B@4KbvUeBa1!eo zte3EUtrNJ0^(U;iu>OhlZ>$g@K(MN(gnxVy(g1ow0vS;)lpu~M;?E8BjUg5yf+5PK zh-`P75Sd?Vh)G1&PZ3%F#D2-RTlnDtLjX?*F~L#r%7Skw zPl!d5j`)FiPc#s335FO)ye-ILA>tk3522Ln2Std7eu&%;k^3QXKSb__$o;r}Q2d$V zh=MBJWQY@SFz&O9aIQi8o*ob4WbwX_(Lq9mOFgV|LwZ6Pgb3@4!#{_@jxaRv*LKZIJq@+M{)yuNK(8pd}9@YPqOA4TldE{sP zf2HUZC}X#=u&ueGYHe+GMLlEgV;Uytyme8MC^i$Ne?sB{yIrOlOznsCYzFb!4CrhI zMgm&c>gjb}3~d3ngJ?=HE@fj85ca7%;EGxS1@E#G`pin?q5F3ZgT#j*juG?47Ic=- zvJNihJE|UC^hdj37w#BRVa|vs$RQ_^J*F!$Ih}Dyx6>s~ zlUEyX%aT8$3}Mfi@{#Y`hn6~Rr}I65fmRpb^meA61x08l@rxx$XXfS%VUiRzLADs& zdRXBkPliJzomFtU9URx`n-}me{&dZevG$S`ZujZDrs)OO*>$qz$!$Qm}SL z?V!R|AFu4%L1CC**eI!NFHl!(LoqzSUoi{|6oTJX-1gwNT9}kdkj1r=Ai_cBinrI~ zd1v3{AA)o(V&9KgQ9|YuJ4LMRgzO~tDPny>$OU5GAl4m1{vvi+)LI)Qo1*r+^~N$ta}EzZ`dnM3;!aeO#4mK zI&P9vrv0U9eQS~%rme)Rq8KTQ*;`{)CPr3`$n0YC*wrjSgKnwtP2>R>A;uAvf|cMP zVxhi&J>m`1u|;t`y_9JH7UQagE6Fa#kjb5iNt(hmQa~}sN~!G?PB5|O7K?$4FFh`% zsZ2AZ#b;G6CoRY`)jeW%voo!GYD@zm(-EaaX0yYX=CDrF6Po2I-w%U5J9B56eh^rm z^Rs5KTVw8fccBDE+JHC?UB#D~Wq~xzFD4A_NoMy} Date: Sun, 16 Sep 2018 18:55:28 +0200 Subject: [PATCH 368/588] mb/lenovo/r500: Add mainboard Tested: - Ethernet NIC - Wifi RFKill - USB - LVDS, VGA with libgfxinit - Booting with dock attached (COM1) - Keyboard, trackpoint - SeaBIOS 1.12 - S3 resume - Tested in descriptor mode, with vendor FD and ME - Add VBT to ACPI OPregion Untested: - SATA (likely works) - Trackpad (my cable is broken, likely works) - Displayport (likely works) - Descriptorless mode - DVD drive - Extra battery - model with ATI GPU Does not work: - Dock hotplug - Quad core CPU (hangs during AP init, probably needs hardware mod) - Hotplugging the expresscard slot (works with 'echo 1 | sudo tee /sys/bus/pci/rescan') TODO: - proper dock support - documentation note: This board was hard to flash, I had to desolder the flash. TESTED: on a R500 with an Intel iGPU, SeaBIOS 1.12, Debian 9, Linux 4.9 from USB Change-Id: I9e129b2e916acdf2b8534fa9d8d2cfc8f64f5815 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/28644 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/lenovo/t400/Kconfig | 21 ++- src/mainboard/lenovo/t400/Kconfig.name | 3 + src/mainboard/lenovo/t400/Makefile.inc | 3 +- src/mainboard/lenovo/t400/devicetree.cb | 36 +---- src/mainboard/lenovo/t400/dsdt.asl | 1 + src/mainboard/lenovo/t400/romstage.c | 16 ++- .../lenovo/t400/variants/r500/Makefile.inc | 1 + .../lenovo/t400/variants/r500/data.vbt | Bin 0 -> 4125 bytes .../lenovo/t400/variants/r500/gpio.c | 131 ++++++++++++++++++ .../lenovo/t400/variants/r500/overridetree.cb | 45 ++++++ .../lenovo/t400/variants/t400/Makefile.inc | 1 + .../lenovo/t400/{ => variants/t400}/data.vbt | Bin .../lenovo/t400/{ => variants/t400}/gpio.c | 0 .../lenovo/t400/variants/t400/overridetree.cb | 43 ++++++ 14 files changed, 261 insertions(+), 40 deletions(-) create mode 100644 src/mainboard/lenovo/t400/variants/r500/Makefile.inc create mode 100644 src/mainboard/lenovo/t400/variants/r500/data.vbt create mode 100644 src/mainboard/lenovo/t400/variants/r500/gpio.c create mode 100644 src/mainboard/lenovo/t400/variants/r500/overridetree.cb create mode 100644 src/mainboard/lenovo/t400/variants/t400/Makefile.inc rename src/mainboard/lenovo/t400/{ => variants/t400}/data.vbt (100%) rename src/mainboard/lenovo/t400/{ => variants/t400}/gpio.c (100%) create mode 100644 src/mainboard/lenovo/t400/variants/t400/overridetree.cb diff --git a/src/mainboard/lenovo/t400/Kconfig b/src/mainboard/lenovo/t400/Kconfig index 16f16803761..2bd67c28bc0 100644 --- a/src/mainboard/lenovo/t400/Kconfig +++ b/src/mainboard/lenovo/t400/Kconfig @@ -1,5 +1,5 @@ if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 || BOARD_LENOVO_R400 \ - || BOARD_LENOVO_W500 + || BOARD_LENOVO_W500 || BOARD_LENOVO_R500 config BOARD_SPECIFIC_OPTIONS def_bool y @@ -11,7 +11,8 @@ config BOARD_SPECIFIC_OPTIONS select EC_LENOVO_H8 select H8_HAS_BAT_TRESHOLDS_IMPL select H8_DOCK_EARLY_INIT - select BOARD_ROMSIZE_KB_8192 + select BOARD_ROMSIZE_KB_8192 if !BOARD_LENOVO_R500 + select BOARD_ROMSIZE_KB_4096 if BOARD_LENOVO_R500 select DRIVERS_GENERIC_IOAPIC select HAVE_MP_TABLE select HAVE_ACPI_TABLES @@ -24,20 +25,31 @@ config BOARD_SPECIFIC_OPTIONS select SUPERIO_NSC_PC87384 select DRIVERS_LENOVO_HYBRID_GRAPHICS select MAINBOARD_HAS_LIBGFXINIT - select MAINBOARD_USES_IFD_GBE_REGION + select MAINBOARD_USES_IFD_GBE_REGION if !BOARD_LENOVO_R500 select INTEL_GMA_HAVE_VBT config MAINBOARD_DIR string default lenovo/t400 +config VARIANT_DIR + string + default "t400" if BOARD_LENOVO_T400 || BOARD_LENOVO_T500 \ + || BOARD_LENOVO_R400 || BOARD_LENOVO_W500 + default "r500" if BOARD_LENOVO_R500 + config MAINBOARD_PART_NUMBER string default "ThinkPad T400" if BOARD_LENOVO_T400 default "ThinkPad T500" if BOARD_LENOVO_T500 default "ThinkPad R400" if BOARD_LENOVO_R400 + default "ThinkPad R500" if BOARD_LENOVO_R500 default "ThinkPad W500" if BOARD_LENOVO_W500 +config OVERRIDE_DEVICETREE + string + default "variants/$(CONFIG_VARIANT_DIR)/overridetree.cb" + config USBDEBUG_HCD_INDEX int default 2 @@ -54,4 +66,7 @@ config ONBOARD_VGA_IS_PRIMARY bool default y +config INTEL_GMA_VBT_FILE + default "src/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/data.vbt" + endif # BOARD_LENOVO_T400 diff --git a/src/mainboard/lenovo/t400/Kconfig.name b/src/mainboard/lenovo/t400/Kconfig.name index d459ce9236f..a259ddece46 100644 --- a/src/mainboard/lenovo/t400/Kconfig.name +++ b/src/mainboard/lenovo/t400/Kconfig.name @@ -7,5 +7,8 @@ config BOARD_LENOVO_T500 config BOARD_LENOVO_R400 bool "ThinkPad R400" +config BOARD_LENOVO_R500 + bool "ThinkPad R500" + config BOARD_LENOVO_W500 bool "ThinkPad W500" diff --git a/src/mainboard/lenovo/t400/Makefile.inc b/src/mainboard/lenovo/t400/Makefile.inc index 7721e0345fd..d0ee1537f43 100644 --- a/src/mainboard/lenovo/t400/Makefile.inc +++ b/src/mainboard/lenovo/t400/Makefile.inc @@ -13,9 +13,10 @@ ## GNU General Public License for more details. ## -romstage-y += gpio.c romstage-y += dock.c +subdirs-y += variants/$(VARIANT_DIR)/ + ramstage-y += dock.c ramstage-y += cstates.c ramstage-y += blc.c diff --git a/src/mainboard/lenovo/t400/devicetree.cb b/src/mainboard/lenovo/t400/devicetree.cb index 475c45ebbdb..b4c2ea89b1e 100644 --- a/src/mainboard/lenovo/t400/devicetree.cb +++ b/src/mainboard/lenovo/t400/devicetree.cb @@ -211,46 +211,12 @@ chip northbridge/intel/gm45 io 0x60 = 0x1620 end end - - chip drivers/lenovo/hybrid_graphics - device pnp ff.f on end # dummy - - register "detect_gpio" = "21" - - register "has_panel_hybrid_gpio" = "1" - register "panel_hybrid_gpio" = "22" - register "panel_integrated_lvl" = "0" - - register "has_backlight_gpio" = "1" - register "backlight_gpio" = "19" - register "backlight_integrated_lvl" = "0" - - register "has_dgpu_power_gpio" = "1" - register "dgpu_power_gpio" = "49" - register "dgpu_power_off_lvl" = "0" - - register "has_thinker1" = "0" - end end device pci 1f.2 on # SATA/IDE 1 subsystemid 0x17aa 0x20f8 ioapic_irq 2 INTB 0x11 end - device pci 1f.3 on # SMBus - subsystemid 0x17aa 0x20f9 - ioapic_irq 2 INTC 0x12 - # eeprom, 8 virtual devices, same chip - chip drivers/i2c/at24rf08c - device i2c 54 on end - device i2c 55 on end - device i2c 56 on end - device i2c 57 on end - device i2c 5c on end - device i2c 5d on end - device i2c 5e on end - device i2c 5f on end - end - end + device pci 1f.3 on end # SMBus device pci 1f.5 off end # SATA/IDE 2 device pci 1f.6 off end # Thermal end diff --git a/src/mainboard/lenovo/t400/dsdt.asl b/src/mainboard/lenovo/t400/dsdt.asl index 75f4bce0c54..6aafec69c48 100644 --- a/src/mainboard/lenovo/t400/dsdt.asl +++ b/src/mainboard/lenovo/t400/dsdt.asl @@ -18,6 +18,7 @@ #define BRIGHTNESS_UP \_SB.PCI0.GFX0.INCB #define BRIGHTNESS_DOWN \_SB.PCI0.GFX0.DECB #define ACPI_VIDEO_DEVICE \_SB.PCI0.GFX0 +#define EC_LENOVO_H8_ME_WORKAROUND 1 #include DefinitionBlock( diff --git a/src/mainboard/lenovo/t400/romstage.c b/src/mainboard/lenovo/t400/romstage.c index 6b03ad0ad82..43d6088788a 100644 --- a/src/mainboard/lenovo/t400/romstage.c +++ b/src/mainboard/lenovo/t400/romstage.c @@ -75,7 +75,21 @@ void mb_pre_raminit_setup(sysinfo_t *sysinfo) else dock_info(); - hybrid_graphics_init(sysinfo); + if (CONFIG(BOARD_LENOVO_R500)) { + int use_integrated = get_gpio(21); + printk(BIOS_DEBUG, "R500 variant found with an %s GPU\n", + use_integrated ? "integrated" : "discrete"); + if (use_integrated) { + sysinfo->enable_igd = 1; + sysinfo->enable_peg = 0; + } else { + sysinfo->enable_igd = 0; + sysinfo->enable_peg = 1; + } + } else { + hybrid_graphics_init(sysinfo); + } + } void mb_post_raminit_setup(void) diff --git a/src/mainboard/lenovo/t400/variants/r500/Makefile.inc b/src/mainboard/lenovo/t400/variants/r500/Makefile.inc new file mode 100644 index 00000000000..3dae61e8a80 --- /dev/null +++ b/src/mainboard/lenovo/t400/variants/r500/Makefile.inc @@ -0,0 +1 @@ +romstage-y += gpio.c diff --git a/src/mainboard/lenovo/t400/variants/r500/data.vbt b/src/mainboard/lenovo/t400/variants/r500/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..799b9b687eff8bfe5c8ff610e13ce952ee8b3354 GIT binary patch literal 4125 zcmd5;Z)_Ar6o32wZg2N)Z#n4oC}oPoZo$H~Km~G!ZLeaB4YW|mMNGItFF>qN+oF(= zbd@G(6g}mGXb3q?NE8$03!nTzO-#TT4Tc0IiZ<~BQDTURevp{1Z)W$d)D~JIB+li{ z@9mp;zj-tBX66=eYw0GL=8fI$Pc)OD^nwiwj11OOOH2EvEjwD9yPJ2kbZp8zN#25a z@LO#BSAbrQ(_;;fu4roCHm?fxJi9YLu$E9~>`fY0E?cpZ5W8Wyy=r-*ZLcAuv2pDxdu>CbuD0$S?CfB&I@y}S1e5i3(iklL=tY6W2-lg$2s{$-@Oua9h|eFn+q{9u0I z`F!s(U8Q4<3Lz2sISCXFxXN(?t)eW3IhEH$fs-U%ig1cFS9)BEitELg6p!;d$D>OP z4`Bnkx0QpF${G-+hG3Ba9qT(wc61T~-R~g6m0Zx5*%bhv#NY@=Ee@>+t)>*hmrbOs z-9dS<9Rv(jtOC1nWz*`lX{V)iecOhP&duH1vQItjzWCCSkra%7h>@`wu?V>+N8qYb z4TGWuMUjUy;%c}dUW7G@4Sh-yj-tGeayk@(b0HHhpj<_{fdXL_RFnitHOf+yRVeFF z+EKQn!{r z37+Sj_dJlYd`TM(Y_3w20$UKA=Q&D$$)-4g=JI2lH-B95JR%?q({NIPuQ~Er(VOpK zD=v@hea|!r&_+EP^mGEuX z_bdi6M!>*`*5K7EXviiB$kqk z;=3woA8)VcRp6JvE*3wXX`?-YNm9`Uy_MiJ!^3v+<$x$@FM$(XU^{mI9G|87gXIUu zx>652*%Kv8+d9YIdA8AUMoX5Y1x>?(zjj*FutZlMuk5B_uD~vA)MUCBXsfiK5^mwI z5(*pv|926$-TytpO=u}(apr#xS>9QAN%@0&dCvb+qw|`nSV`bvkoCgLv3!A1L*1Jo ze4|>PYQ`h#{D{>aF}Fw5e8f5)F;7R-Pa@W}hBH!F0tMz=QUW{<8uqg(Ij=101EPPcy6%|CV3)2;fbxh|@`2*P>P=W-f@SwJ~dJ%-kJQmlQ>MKfCmW5uhbx%J6yk7H9z)h*GQ;Y(y-? z^R9&50vTIigmR0h1)v%?KS&6AzXwdtbWFk|reciXQK=%9nNg zCc8gwa2RQ<#FW0n>}FEnV0;YpfN~E*Hm}ap~Q_m$mZfrj^`g+cuY3g~V$CX_f z8om5xzjq&|px6njZIdNznQ0aX1$Mt;X!kO^!^;ZAT&mi!NpLeElUN8-R?SuJKD)`8 zX{Fs_|JjF-X(A@6z+S=I^J&@@pUgBRpXlr$!eT1r6P}i7nP$i*#-!ahCf#Sk2WIwr z_bc5yQekU$hI+FTECBm6fmv`bCsm10rFehgi taq1n!M4wO4miB#1SN)N>`0h_r{sH7tZjAr{ literal 0 HcmV?d00001 diff --git a/src/mainboard/lenovo/t400/variants/r500/gpio.c b/src/mainboard/lenovo/t400/variants/r500/gpio.c new file mode 100644 index 00000000000..a1cc4586dae --- /dev/null +++ b/src/mainboard/lenovo/t400/variants/r500/gpio.c @@ -0,0 +1,131 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +static const struct pch_gpio_set1 pch_gpio_set1_mode = { + .gpio1 = GPIO_MODE_GPIO, + .gpio2 = GPIO_MODE_GPIO, + .gpio3 = GPIO_MODE_GPIO, + .gpio4 = GPIO_MODE_GPIO, + .gpio5 = GPIO_MODE_GPIO, + .gpio6 = GPIO_MODE_GPIO, + .gpio7 = GPIO_MODE_GPIO, + .gpio8 = GPIO_MODE_GPIO, + .gpio9 = GPIO_MODE_GPIO, + .gpio12 = GPIO_MODE_GPIO, + .gpio13 = GPIO_MODE_GPIO, + .gpio17 = GPIO_MODE_GPIO, + .gpio18 = GPIO_MODE_GPIO, + .gpio19 = GPIO_MODE_GPIO, + .gpio20 = GPIO_MODE_GPIO, + .gpio21 = GPIO_MODE_GPIO, + .gpio22 = GPIO_MODE_GPIO, + .gpio24 = GPIO_MODE_GPIO, + .gpio27 = GPIO_MODE_GPIO, + .gpio28 = GPIO_MODE_GPIO, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_direction = { + .gpio1 = GPIO_DIR_INPUT, + .gpio2 = GPIO_DIR_INPUT, + .gpio3 = GPIO_DIR_INPUT, + .gpio4 = GPIO_DIR_INPUT, + .gpio5 = GPIO_DIR_INPUT, + .gpio6 = GPIO_DIR_INPUT, + .gpio7 = GPIO_DIR_INPUT, + .gpio8 = GPIO_DIR_INPUT, + .gpio9 = GPIO_DIR_OUTPUT, + .gpio12 = GPIO_DIR_OUTPUT, + .gpio13 = GPIO_DIR_INPUT, + .gpio17 = GPIO_DIR_INPUT, + .gpio18 = GPIO_DIR_OUTPUT, + .gpio19 = GPIO_DIR_INPUT, + .gpio20 = GPIO_DIR_OUTPUT, + .gpio21 = GPIO_DIR_INPUT, + .gpio22 = GPIO_DIR_INPUT, + .gpio24 = GPIO_DIR_OUTPUT, + .gpio27 = GPIO_DIR_OUTPUT, + .gpio28 = GPIO_DIR_OUTPUT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_level = { + .gpio9 = GPIO_LEVEL_HIGH, + .gpio12 = GPIO_LEVEL_LOW, + .gpio18 = GPIO_LEVEL_HIGH, + .gpio20 = GPIO_LEVEL_HIGH, + .gpio24 = GPIO_LEVEL_HIGH, + .gpio27 = GPIO_LEVEL_LOW, + .gpio28 = GPIO_LEVEL_LOW, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_invert = { + .gpio1 = GPIO_INVERT, + .gpio8 = GPIO_INVERT, +}; + +static const struct pch_gpio_set1 pch_gpio_set1_blink = { +}; + +static const struct pch_gpio_set2 pch_gpio_set2_mode = { + .gpio33 = GPIO_MODE_GPIO, + .gpio34 = GPIO_MODE_GPIO, + .gpio36 = GPIO_MODE_GPIO, + .gpio37 = GPIO_MODE_GPIO, + .gpio38 = GPIO_MODE_GPIO, + .gpio39 = GPIO_MODE_GPIO, + .gpio41 = GPIO_MODE_GPIO, + .gpio42 = GPIO_MODE_GPIO, + .gpio48 = GPIO_MODE_GPIO, + .gpio49 = GPIO_MODE_GPIO, + .gpio56 = GPIO_MODE_GPIO, + .gpio57 = GPIO_MODE_GPIO, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_direction = { + .gpio33 = GPIO_DIR_OUTPUT, + .gpio34 = GPIO_DIR_OUTPUT, + .gpio36 = GPIO_DIR_INPUT, + .gpio37 = GPIO_DIR_INPUT, + .gpio38 = GPIO_DIR_INPUT, + .gpio39 = GPIO_DIR_INPUT, + .gpio41 = GPIO_DIR_OUTPUT, + .gpio42 = GPIO_DIR_OUTPUT, + .gpio48 = GPIO_DIR_INPUT, + .gpio49 = GPIO_DIR_OUTPUT, + .gpio56 = GPIO_DIR_INPUT, + .gpio57 = GPIO_DIR_INPUT, +}; + +static const struct pch_gpio_set2 pch_gpio_set2_level = { + .gpio33 = GPIO_LEVEL_HIGH, + .gpio34 = GPIO_LEVEL_LOW, + .gpio41 = GPIO_LEVEL_HIGH, + .gpio42 = GPIO_LEVEL_HIGH, + .gpio49 = GPIO_LEVEL_HIGH, +}; + +const struct pch_gpio_map mainboard_gpio_map = { + .set1 = { + .mode = &pch_gpio_set1_mode, + .direction = &pch_gpio_set1_direction, + .level = &pch_gpio_set1_level, + .blink = &pch_gpio_set1_blink, + .invert = &pch_gpio_set1_invert, + }, + .set2 = { + .mode = &pch_gpio_set2_mode, + .direction = &pch_gpio_set2_direction, + .level = &pch_gpio_set2_level, + }, +}; diff --git a/src/mainboard/lenovo/t400/variants/r500/overridetree.cb b/src/mainboard/lenovo/t400/variants/r500/overridetree.cb new file mode 100644 index 00000000000..65b9387f594 --- /dev/null +++ b/src/mainboard/lenovo/t400/variants/r500/overridetree.cb @@ -0,0 +1,45 @@ +chip northbridge/intel/gm45 + device domain 0 on + device pci 03.0 off end + chip southbridge/intel/i82801ix + register "sata_clock_request" = "1" + # Enable PCIe ports 1,2,4,5,6 as slots (Mini * PCIe). + register "pcie_slot_implemented" = "0x3b" + # Set power limits to 10 * 10^0 watts. + # Maybe we should set less for Mini PCIe. + register "pcie_power_limits" = "{ { 41, 0 }, { 41, 0 }, { 0, 0 }, { 41, 0 }, { 41, 0 }, { 41, 0 } }" + register "pcie_hotplug_map" = "{ 0, 0, 0, 0, 0, 1, 0, 0 }" + device pci 19.0 off end # LAN + device pci 1c.2 off end # PCIe Port #3 + device pci 1c.4 on # PCIe Port #5 + subsystemid 0x17aa 0x20f3 + end + device pci 1c.5 on # PCIe Port #6 + subsystemid 0x17aa 0x20f3 # Ethernet NIC + end + device pci 1f.0 on # LPC bridge + subsystemid 0x17aa 0x20f5 + chip ec/lenovo/h8 + register "config1" = "0x05" + register "config3" = "0x40" + register "event6_enable" = "0x87" + register "event7_enable" = "0x09" + register "event8_enable" = "0x5b" + register "eventa_enable" = "0x83" + register "eventb_enable" = "0x00" + end + end + device pci 1f.3 on # SMBus + subsystemid 0x17aa 0x20f9 + ioapic_irq 2 INTC 0x12 + # eeprom, 4 virtual devices, same chip + chip drivers/i2c/at24rf08c + device i2c 54 on end + device i2c 55 on end + device i2c 56 on end + device i2c 57 on end + end + end + end + end +end diff --git a/src/mainboard/lenovo/t400/variants/t400/Makefile.inc b/src/mainboard/lenovo/t400/variants/t400/Makefile.inc new file mode 100644 index 00000000000..3dae61e8a80 --- /dev/null +++ b/src/mainboard/lenovo/t400/variants/t400/Makefile.inc @@ -0,0 +1 @@ +romstage-y += gpio.c diff --git a/src/mainboard/lenovo/t400/data.vbt b/src/mainboard/lenovo/t400/variants/t400/data.vbt similarity index 100% rename from src/mainboard/lenovo/t400/data.vbt rename to src/mainboard/lenovo/t400/variants/t400/data.vbt diff --git a/src/mainboard/lenovo/t400/gpio.c b/src/mainboard/lenovo/t400/variants/t400/gpio.c similarity index 100% rename from src/mainboard/lenovo/t400/gpio.c rename to src/mainboard/lenovo/t400/variants/t400/gpio.c diff --git a/src/mainboard/lenovo/t400/variants/t400/overridetree.cb b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb new file mode 100644 index 00000000000..64cb6db03fe --- /dev/null +++ b/src/mainboard/lenovo/t400/variants/t400/overridetree.cb @@ -0,0 +1,43 @@ +chip northbridge/intel/gm45 + device domain 0 on + chip southbridge/intel/i82801ix + device pci 1f.0 on # LPC bridge + subsystemid 0x17aa 0x20f5 + chip drivers/lenovo/hybrid_graphics + device pnp ff.f on end # dummy + + register "detect_gpio" = "21" + + register "has_panel_hybrid_gpio" = "1" + register "panel_hybrid_gpio" = "22" + register "panel_integrated_lvl" = "0" + + register "has_backlight_gpio" = "1" + register "backlight_gpio" = "19" + register "backlight_integrated_lvl" = "0" + + register "has_dgpu_power_gpio" = "1" + register "dgpu_power_gpio" = "49" + register "dgpu_power_off_lvl" = "0" + + register "has_thinker1" = "0" + end + end + device pci 1f.3 on # SMBus + subsystemid 0x17aa 0x20f9 + ioapic_irq 2 INTC 0x12 + # eeprom, 8 virtual devices, same chip + chip drivers/i2c/at24rf08c + device i2c 54 on end + device i2c 55 on end + device i2c 56 on end + device i2c 57 on end + device i2c 5c on end + device i2c 5d on end + device i2c 5e on end + device i2c 5f on end + end + end + end + end +end From 7f8a57e96ae8a0ad41bc6024c9fa5a0c14282f15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 28 Jun 2018 16:58:52 +0300 Subject: [PATCH 369/588] soc/amd/common: Refactor AmdCreateStruct() use MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit AmdCreateStruct() and AmdReleaseStruct() are equally bad when it comes to lack of correct function declarations for definitions found in vendorcode binaryPI/AGESA.c. Replace these with calls that go through the common module_dispatch() functions. Change-Id: I611bcbe2a71fb65c8eb759a9dc74cbd9cb74136e Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31486 Reviewed-by: Richard Spiegel Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/pi/agesawrapper.c | 143 +++++++++--------- .../amd/pi/00670F00/binaryPI/AGESA.c | 27 ---- 2 files changed, 70 insertions(+), 100 deletions(-) diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index 5f58346625c..da6de00568c 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -65,41 +65,60 @@ AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams) return module_dispatch(AMD_LATE_RUN_AP_TASK, StdHeader); } -static void *create_struct(AMD_INTERFACE_PARAMS *interface_struct) +static void *amd_create_struct(AMD_INTERFACE_PARAMS *aip, + AGESA_STRUCT_NAME func, void *buf, size_t len) { AMD_CONFIG_PARAMS *StdHeader; + AGESA_STATUS status; /* Should clone entire StdHeader here. */ - interface_struct->StdHeader.CalloutPtr = &GetBiosCallout; + memset(aip, 0, sizeof(*aip)); + aip->StdHeader.CalloutPtr = &GetBiosCallout; + + /* If we provide the buffer, API expects it to have + StdHeader already filled. */ + if (buf != NULL && len >= sizeof(*StdHeader)) { + memcpy(buf, &aip->StdHeader, sizeof(*StdHeader)); + aip->AllocationMethod = ByHost; + aip->NewStructPtr = buf; + aip->NewStructSize = len; + } else { + if (ENV_ROMSTAGE) + aip->AllocationMethod = PreMemHeap; + if (ENV_RAMSTAGE) + aip->AllocationMethod = PostMemDram; + } - AGESA_STATUS status = AmdCreateStruct(interface_struct); + aip->AgesaFunctionName = func; + status = module_dispatch(AMD_CREATE_STRUCT, &aip->StdHeader); if (status != AGESA_SUCCESS) { printk(BIOS_ERR, "Error: AmdCreateStruct() for 0x%x returned 0x%x. " "Proper system initialization may not be possible.\n", - interface_struct->AgesaFunctionName, status); + aip->AgesaFunctionName, status); } - if (!interface_struct->NewStructPtr) /* Avoid NULL pointer usage */ + if (!aip->NewStructPtr) die("No AGESA structure created"); - StdHeader = interface_struct->NewStructPtr; - StdHeader->Func = interface_struct->AgesaFunctionName; + StdHeader = aip->NewStructPtr; + StdHeader->Func = aip->AgesaFunctionName; return StdHeader; } +static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip) +{ + return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader); +} + static AGESA_STATUS amd_init_reset(void) { AGESA_STATUS status; AMD_RESET_PARAMS _ResetParams; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_RESET, - .AllocationMethod = ByHost, - .NewStructSize = sizeof(AMD_RESET_PARAMS), - .NewStructPtr = &_ResetParams, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; - AMD_RESET_PARAMS *ResetParams = create_struct(&AmdParamStruct); + AMD_RESET_PARAMS *ResetParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_RESET, &_ResetParams, sizeof(AMD_RESET_PARAMS)); SetFchResetParams(&ResetParams->FchInterface); @@ -107,19 +126,17 @@ static AGESA_STATUS amd_init_reset(void) status = amd_dispatch(ResetParams); timestamp_add_now(TS_AGESA_INIT_RESET_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } static AGESA_STATUS amd_init_early(void) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_EARLY, - .AllocationMethod = PreMemHeap, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; - AMD_EARLY_PARAMS *EarlyParams = create_struct(&AmdParamStruct); + AMD_EARLY_PARAMS *EarlyParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_EARLY, NULL, 0); soc_customize_init_early(EarlyParams); OemCustomizeInitEarly(EarlyParams); @@ -128,7 +145,7 @@ static AGESA_STATUS amd_init_early(void) status = amd_dispatch(EarlyParams); timestamp_add_now(TS_AGESA_INIT_EARLY_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } @@ -169,12 +186,10 @@ static void print_init_post_settings(AMD_POST_PARAMS *parms) static AGESA_STATUS amd_init_post(void) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_POST, - .AllocationMethod = PreMemHeap, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; - AMD_POST_PARAMS *PostParams = create_struct(&AmdParamStruct); + AMD_POST_PARAMS *PostParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_POST, NULL, 0); PostParams->MemConfig.UmaMode = CONFIG(GFXUMA) ? UMA_AUTO : UMA_NONE; PostParams->MemConfig.UmaSize = 0; @@ -214,7 +229,7 @@ static AGESA_STATUS amd_init_post(void) print_init_post_settings(PostParams); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } @@ -222,12 +237,10 @@ static AGESA_STATUS amd_init_post(void) static AGESA_STATUS amd_init_env(void) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_ENV, - .AllocationMethod = PostMemDram, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; - AMD_ENV_PARAMS *EnvParams = create_struct(&AmdParamStruct); + AMD_ENV_PARAMS *EnvParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_ENV, NULL, 0); SetFchEnvParams(&EnvParams->FchInterface); SetNbEnvParams(&EnvParams->GnbEnvConfiguration); @@ -236,7 +249,7 @@ static AGESA_STATUS amd_init_env(void) status = amd_dispatch(EnvParams); timestamp_add_now(TS_AGESA_INIT_ENV_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } @@ -270,15 +283,13 @@ void *agesawrapper_getlateinitptr(int pick) static AGESA_STATUS amd_init_mid(void) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_MID, - .AllocationMethod = PostMemDram, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; /* Enable MMIO on AMD CPU Address Map Controller */ amd_initcpuio(); - AMD_MID_PARAMS *MidParams = create_struct(&AmdParamStruct); + AMD_MID_PARAMS *MidParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_MID, NULL, 0); SetFchMidParams(&MidParams->FchInterface); SetNbMidParams(&MidParams->GnbMidConfiguration); @@ -287,7 +298,7 @@ static AGESA_STATUS amd_init_mid(void) status = amd_dispatch(MidParams); timestamp_add_now(TS_AGESA_INIT_MID_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } @@ -295,16 +306,14 @@ static AGESA_STATUS amd_init_mid(void) static AGESA_STATUS amd_init_late(void) { AGESA_STATUS Status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_LATE, - .AllocationMethod = PostMemDram, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; /* * NOTE: if not call amdcreatestruct, the initializer * (AmdInitLateInitializer) would not be called. */ - AMD_LATE_PARAMS *LateParams = create_struct(&AmdParamStruct); + AMD_LATE_PARAMS *LateParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_LATE, NULL, 0); const struct device *dev = pcidev_path_on_root(IOMMU_DEVFN); if (dev && dev->enabled) { @@ -333,19 +342,17 @@ static AGESA_STATUS amd_init_late(void) AcpiSlit, AcpiWheaMce, AcpiWheaCmc, AcpiAlib, AcpiIvrs, __func__); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return Status; } static AGESA_STATUS amd_init_rtb(void) { AGESA_STATUS Status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_RTB, - .AllocationMethod = PostMemDram, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; - AMD_RTB_PARAMS *RtbParams = create_struct(&AmdParamStruct); + AMD_RTB_PARAMS *RtbParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_RTB, NULL, 0); timestamp_add_now(TS_AGESA_INIT_RTB_START); Status = amd_dispatch(RtbParams); @@ -357,7 +364,7 @@ static AGESA_STATUS amd_init_rtb(void) RtbParams->S3DataBlock.VolatileStorageSize)) printk(BIOS_ERR, "S3 data not saved, resuming impossible\n"); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return Status; } @@ -365,13 +372,11 @@ static AGESA_STATUS amd_init_rtb(void) static AGESA_STATUS amd_init_resume(void) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_INIT_RESUME, - .AllocationMethod = PreMemHeap, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; size_t nv_size; - AMD_RESUME_PARAMS *InitResumeParams = create_struct(&AmdParamStruct); + AMD_RESUME_PARAMS *InitResumeParams = amd_create_struct(&AmdParamStruct, + AMD_INIT_RESUME, NULL, 0); get_s3nv_info(&InitResumeParams->S3DataBlock.NvStorage, &nv_size); InitResumeParams->S3DataBlock.NvStorageSize = nv_size; @@ -380,7 +385,7 @@ static AGESA_STATUS amd_init_resume(void) status = amd_dispatch(InitResumeParams); timestamp_add_now(TS_AGESA_INIT_RESUME_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return status; } @@ -389,17 +394,13 @@ static AGESA_STATUS amd_s3late_restore(void) { AGESA_STATUS Status; AMD_S3LATE_PARAMS _S3LateParams; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_S3LATE_RESTORE, - .AllocationMethod = ByHost, - .NewStructSize = sizeof(AMD_S3LATE_PARAMS), - .NewStructPtr = &_S3LateParams, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; size_t vol_size; amd_initcpuio(); - AMD_S3LATE_PARAMS *S3LateParams = create_struct(&AmdParamStruct); + AMD_S3LATE_PARAMS *S3LateParams = amd_create_struct(&AmdParamStruct, + AMD_S3LATE_RESTORE, &_S3LateParams, sizeof(AMD_S3LATE_PARAMS)); get_s3vol_info(&S3LateParams->S3DataBlock.VolatileStorage, &vol_size); S3LateParams->S3DataBlock.VolatileStorageSize = vol_size; @@ -408,7 +409,7 @@ static AGESA_STATUS amd_s3late_restore(void) Status = amd_dispatch(S3LateParams); timestamp_add_now(TS_AGESA_S3_LATE_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return Status; } @@ -417,15 +418,11 @@ static AGESA_STATUS amd_s3final_restore(void) { AGESA_STATUS Status; AMD_S3FINAL_PARAMS _S3FinalParams; - AMD_INTERFACE_PARAMS AmdParamStruct = { - .AgesaFunctionName = AMD_S3FINAL_RESTORE, - .AllocationMethod = ByHost, - .NewStructSize = sizeof(AMD_S3FINAL_PARAMS), - .NewStructPtr = &_S3FinalParams, - }; + AMD_INTERFACE_PARAMS AmdParamStruct; size_t vol_size; - AMD_S3FINAL_PARAMS *S3FinalParams = create_struct(&AmdParamStruct); + AMD_S3FINAL_PARAMS *S3FinalParams = amd_create_struct(&AmdParamStruct, + AMD_S3FINAL_RESTORE, &_S3FinalParams, sizeof(AMD_S3FINAL_PARAMS)); get_s3vol_info(&S3FinalParams->S3DataBlock.VolatileStorage, &vol_size); S3FinalParams->S3DataBlock.VolatileStorageSize = vol_size; @@ -434,7 +431,7 @@ static AGESA_STATUS amd_s3final_restore(void) Status = amd_dispatch(S3FinalParams); timestamp_add_now(TS_AGESA_S3_FINAL_DONE); - AmdReleaseStruct(&AmdParamStruct); + amd_release_struct(&AmdParamStruct); return Status; } diff --git a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c index e17cedcb649..da89ce8e6d2 100644 --- a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c +++ b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c @@ -45,30 +45,3 @@ CONST UINT32 ImageSignature = IMAGE_SIGNATURE; CONST UINT32 ModuleSignature = MODULE_SIGNATURE; CONST CHAR8 ModuleIdentifier[8] = AGESA_ID; -/********************************************************************** - * Interface call: AmdCreateStruct - **********************************************************************/ -AGESA_STATUS -AmdCreateStruct ( - IN OUT AMD_INTERFACE_PARAMS *InterfaceParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - InterfaceParams->StdHeader.Func = AMD_CREATE_STRUCT; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(InterfaceParams); -} - -/********************************************************************** - * Interface call: AmdReleaseStruct - **********************************************************************/ -AGESA_STATUS -AmdReleaseStruct ( - IN OUT AMD_INTERFACE_PARAMS *InterfaceParams - ) -{ - MODULE_ENTRY Dispatcher = agesa_get_dispatcher(); - InterfaceParams->StdHeader.Func = AMD_RELEASE_STRUCT; - if (!Dispatcher) return AGESA_UNSUPPORTED; - return Dispatcher(InterfaceParams); -} From 1dda496a7419664279ec5cb4490b3a4598187a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 14 Jun 2018 09:38:44 +0300 Subject: [PATCH 370/588] binaryPI/00670F000: Remove AGESA.c file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Id48de8b2f6feb6c29d745140c872215faa32eb37 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31487 Reviewed-by: Richard Spiegel Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- .../amd/pi/00670F00/binaryPI/AGESA.c | 47 ------------------- 1 file changed, 47 deletions(-) delete mode 100644 src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c diff --git a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c b/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c deleted file mode 100644 index da89ce8e6d2..00000000000 --- a/src/vendorcode/amd/pi/00670F00/binaryPI/AGESA.c +++ /dev/null @@ -1,47 +0,0 @@ -/* $NoKeywords:$ */ -/** - * @file - * - * Agesa structures and definitions - * - * Contains AMD AGESA core interface - * - * @xrefitem bom "File Content Label" "Release Content" - * @e project: AGESA - * @e sub-project: Include - * @e \$Revision: 85818 $ @e \$Date: 2013-01-11 17:04:21 -0600 (Fri, 11 Jan 2013) $ - */ -/***************************************************************************** - * - * Copyright (c) 2008 - 2013, Advanced Micro Devices, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of Advanced Micro Devices, Inc. nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - ***************************************************************************/ -#include - -CONST UINT32 ImageSignature = IMAGE_SIGNATURE; -CONST UINT32 ModuleSignature = MODULE_SIGNATURE; -CONST CHAR8 ModuleIdentifier[8] = AGESA_ID; - From 40a85f85c68902f8e16f3088bd94ab5ab83e7749 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Fri, 17 May 2019 14:55:04 -0600 Subject: [PATCH 371/588] util/romcc: Use 64 bit integers when shifting 'used_indices' is 64 bits wide, so use a fixed-width type to make that clear. As such, 'index' can have a value of up to 63, so use a 64 bit integer when doing the shifts to prevent overflow. Found-by: Coverity Scan CID 1287090 Signed-off-by: Jacob Garber Change-Id: Ibd089df6be60c8ea46da11e5e83cd58b2e2c54d6 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32854 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- util/romcc/romcc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index c6507dcad9f..97cc2191e7e 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -14111,7 +14111,7 @@ static void compute_closure_variables(struct compile_state *state, struct block *block; struct triple *old_result, *first, *ins; size_t count, idx; - unsigned long used_indices; + uint64_t used_indices; int i, max_index; #define MAX_INDICES (sizeof(used_indices)*CHAR_BIT) #define ID_BITS(X) ((X) & (TRIPLE_FLAG_LOCAL -1)) @@ -14217,11 +14217,11 @@ static void compute_closure_variables(struct compile_state *state, if (index >= MAX_INDICES) { internal_error(state, ins, "index unexpectedly large"); } - if (used_indices & (1 << index)) { + if (used_indices & ((uint64_t)1 << index)) { internal_error(state, ins, "index previously used?"); } /* Remember which indices have been used */ - used_indices |= (1 << index); + used_indices |= ((uint64_t)1 << index); if (index > max_index) { max_index = index; } @@ -14249,7 +14249,7 @@ static void compute_closure_variables(struct compile_state *state, } info[ID_BITS(ins->id)].index = index; /* Remember which indices have been used */ - used_indices |= (1 << index); + used_indices |= ((uint64_t)1 << index); if (index > max_index) { max_index = index; } @@ -14263,7 +14263,7 @@ static void compute_closure_variables(struct compile_state *state, for(i = 0; i <= max_index; i++) { struct triple *var; var = 0; - if (used_indices & (1 << i)) { + if (used_indices & ((uint64_t)1 << i)) { for(set = vars; set; set = set->next) { int index; index = info[ID_BITS(set->member->id)].index; From b79d2dee2b2f294aac97dad849909d7bfb892c76 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Thu, 16 May 2019 22:00:27 -0600 Subject: [PATCH 372/588] util/romcc: Free variable after it is used Free 'arg_type' after it is used to prevent a memory leak. Found-by: Coverity Scan CID 1129114 Signed-off-by: Jacob Garber Change-Id: I5e8661547bb7623463ed23fc45269049ffb8c50e Reviewed-on: https://review.coreboot.org/c/coreboot/+/32841 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 97cc2191e7e..bf0510a49f0 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -11236,6 +11236,7 @@ static struct triple *relational_expr(struct compile_state *state) arg_type = arithmetic_result(state, left, right); sign = is_signed(arg_type); + xfree(arg_type); op = -1; switch(tok) { case TOK_LESS: op = sign? OP_SLESS : OP_ULESS; break; From ae8301fddbb5c8456b738bbeab94b98ae3eb06b6 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Fri, 17 May 2019 12:51:47 -0600 Subject: [PATCH 373/588] util/romcc: Fix parsing of empty string literal The corner case of an empty string literal was causing romcc to segfault. This checks if the literal is empty, and if so allocates a size one buffer for the terminating null character. A test case for this is added to ensure it doesn't happen again. Found-by: Coverity CID 1129099 Signed-off-by: Jacob Garber Change-Id: I067160a3b9998184f44e4878ef6269f372fe68bb Reviewed-on: https://review.coreboot.org/c/coreboot/+/32852 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 9 +++++++++ util/romcc/tests/simple_test87.c | 4 ++++ 2 files changed, 13 insertions(+) create mode 100644 util/romcc/tests/simple_test87.c diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index bf0510a49f0..b9ec835f6f5 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -10782,6 +10782,15 @@ static struct triple *string_constant(struct compile_state *state) } while(str < end); type->elements = ptr - buf; } while(peek(state) == TOK_LIT_STRING); + + /* buf contains the allocated buffer for the string constant. However, + if buf is NULL, then the string constant is empty, but we still + need to allocate one byte for the null character. */ + if (buf == NULL) { + buf = xmalloc(1, "string_constant"); + ptr = buf; + } + *ptr = '\0'; type->elements += 1; def = triple(state, OP_BLOBCONST, type, 0, 0); diff --git a/util/romcc/tests/simple_test87.c b/util/romcc/tests/simple_test87.c new file mode 100644 index 00000000000..6a1148c46aa --- /dev/null +++ b/util/romcc/tests/simple_test87.c @@ -0,0 +1,4 @@ +static void main(void) +{ + char *x = ""; +} From b7f27abb3bc4ef83e4250c9ac3480ca5fd7ec7cb Mon Sep 17 00:00:00 2001 From: Kane Chen Date: Thu, 16 May 2019 18:52:36 +0800 Subject: [PATCH 374/588] mb/google/kohaku: Set ACPI_GPIO_IRQ_EDGE_BOTH for headset INT Currently, GPP_H0 gpio input rout is set to GPI_INT. So, ACPI_GPIO_IRQ is required for GPP_H0 in devicetree This change also aligns hatch's setting. BUG=b:131742713 TEST=headset is working Change-Id: Ie1264641bc4dfa5f98b6dab2d6f2133a6f9cbdb8 Signed-off-by: Kane Chen Reviewed-on: https://review.coreboot.org/c/coreboot/+/32845 Tested-by: build bot (Jenkins) Reviewed-by: Ben Kao Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg Reviewed-by: Tim Wawrzynczak --- src/mainboard/google/hatch/variants/kohaku/overridetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb index 9546420e351..69875bdde29 100644 --- a/src/mainboard/google/hatch/variants/kohaku/overridetree.cb +++ b/src/mainboard/google/hatch/variants/kohaku/overridetree.cb @@ -90,7 +90,7 @@ chip soc/intel/cannonlake chip drivers/i2c/da7219 # TODO: these settings were copied from another board # with the same chip. verify the settings - register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_H0_IRQ)" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_H0)" register "btn_cfg" = "50" register "mic_det_thr" = "500" register "jack_ins_deb" = "20" From a172228b7a66454a34b331fff10d6d0bb03ab634 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 07:46:18 +0200 Subject: [PATCH 375/588] src/arch/arm64: Remove variable set but not used Change-Id: I4fe5771dd1ebf3d2a981dab08e98f1c018d14133 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32888 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- src/arch/arm64/boot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/arch/arm64/boot.c b/src/arch/arm64/boot.c index d17a20d6286..7fbc525a18b 100644 --- a/src/arch/arm64/boot.c +++ b/src/arch/arm64/boot.c @@ -38,7 +38,6 @@ static void run_payload(struct prog *prog) void arch_prog_run(struct prog *prog) { void (*doit)(void *); - void *arg; if (ENV_RAMSTAGE && prog_type(prog) == PROG_PAYLOAD) { run_payload(prog); @@ -46,7 +45,6 @@ void arch_prog_run(struct prog *prog) } doit = prog_entry(prog); - arg = prog_entry_arg(prog); doit(prog_entry_arg(prog)); } From b19de28c9889675125183f350e2a35f60e142562 Mon Sep 17 00:00:00 2001 From: Kevin Chiu Date: Thu, 16 May 2019 11:16:18 +0800 Subject: [PATCH 376/588] mb/google/octopus: Create Garg variant This commit creates a garg variant for Octopus. The initial settings override the baseboard was copied from variant bobba. BUG=b:132668378 BRANCH=master TEST=emerge-octopus coreboot Change-Id: I9a36bc5dc3d2b891b1bce86015aa264894d1434b Signed-off-by: Kevin Chiu Reviewed-on: https://review.coreboot.org/c/coreboot/+/32835 Tested-by: build bot (Jenkins) Reviewed-by: Sheng-Liang Pan Reviewed-by: Justin TerAvest --- src/mainboard/google/octopus/Kconfig | 3 + src/mainboard/google/octopus/Kconfig.name | 6 + .../google/octopus/variants/garg/Makefile.inc | 3 + .../google/octopus/variants/garg/gpio.c | 37 ++++ .../garg/include/variant/acpi/dptf.asl | 16 ++ .../variants/garg/include/variant/ec.h | 24 +++ .../variants/garg/include/variant/gpio.h | 21 ++ .../octopus/variants/garg/overridetree.cb | 180 ++++++++++++++++++ 8 files changed, 290 insertions(+) create mode 100644 src/mainboard/google/octopus/variants/garg/Makefile.inc create mode 100644 src/mainboard/google/octopus/variants/garg/gpio.c create mode 100644 src/mainboard/google/octopus/variants/garg/include/variant/acpi/dptf.asl create mode 100644 src/mainboard/google/octopus/variants/garg/include/variant/ec.h create mode 100644 src/mainboard/google/octopus/variants/garg/include/variant/gpio.h create mode 100644 src/mainboard/google/octopus/variants/garg/overridetree.cb diff --git a/src/mainboard/google/octopus/Kconfig b/src/mainboard/google/octopus/Kconfig index 9c0a2f771ef..48753ed4b16 100644 --- a/src/mainboard/google/octopus/Kconfig +++ b/src/mainboard/google/octopus/Kconfig @@ -59,6 +59,7 @@ config VARIANT_DIR default "casta" if BOARD_GOOGLE_CASTA default "bloog" if BOARD_GOOGLE_BLOOG default "octopus" if BOARD_GOOGLE_OCTOPUS + default "garg" if BOARD_GOOGLE_GARG config DEVICETREE string @@ -79,6 +80,7 @@ config MAINBOARD_PART_NUMBER default "Casta" if BOARD_GOOGLE_CASTA default "Bloog" if BOARD_GOOGLE_BLOOG default "Octopus" if BOARD_GOOGLE_OCTOPUS + default "Garg" if BOARD_GOOGLE_GARG config MAINBOARD_FAMILY string @@ -96,6 +98,7 @@ config GBB_HWID default "CASTA TEST 8105" if BOARD_GOOGLE_CASTA default "BLOOG TEST 2509" if BOARD_GOOGLE_BLOOG default "OCTOPUS TEST 6859" if BOARD_GOOGLE_OCTOPUS + default "GARG TEST 1337" if BOARD_GOOGLE_GARG config MAX_CPUS int diff --git a/src/mainboard/google/octopus/Kconfig.name b/src/mainboard/google/octopus/Kconfig.name index e5684e0268a..b192134fb46 100644 --- a/src/mainboard/google/octopus/Kconfig.name +++ b/src/mainboard/google/octopus/Kconfig.name @@ -52,3 +52,9 @@ config BOARD_GOOGLE_BLOOG select BASEBOARD_OCTOPUS_LAPTOP select BOARD_GOOGLE_BASEBOARD_OCTOPUS select NHLT_DA7219 if INCLUDE_NHLT_BLOBS + +config BOARD_GOOGLE_GARG + bool "-> Garg" + select BASEBOARD_OCTOPUS_LAPTOP + select BOARD_GOOGLE_BASEBOARD_OCTOPUS + select NHLT_DA7219 if INCLUDE_NHLT_BLOBS diff --git a/src/mainboard/google/octopus/variants/garg/Makefile.inc b/src/mainboard/google/octopus/variants/garg/Makefile.inc new file mode 100644 index 00000000000..9fb63f5f433 --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/Makefile.inc @@ -0,0 +1,3 @@ +bootblock-y += gpio.c + +ramstage-y += gpio.c diff --git a/src/mainboard/google/octopus/variants/garg/gpio.c b/src/mainboard/google/octopus/variants/garg/gpio.c new file mode 100644 index 00000000000..a4362409b52 --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/gpio.c @@ -0,0 +1,37 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +static const struct pad_config default_override_table[] = { + PAD_NC(GPIO_104, UP_20K), + + /* EN_PP3300_TOUCHSCREEN */ + PAD_CFG_GPO_IOSSTATE_IOSTERM(GPIO_146, 0, DEEP, NONE, Tx0RxDCRx0, + DISPUPD), + + PAD_NC(GPIO_213, DN_20K), +}; + +const struct pad_config *variant_override_gpio_table(size_t *num) +{ + *num = ARRAY_SIZE(default_override_table); + + return default_override_table; +} diff --git a/src/mainboard/google/octopus/variants/garg/include/variant/acpi/dptf.asl b/src/mainboard/google/octopus/variants/garg/include/variant/acpi/dptf.asl new file mode 100644 index 00000000000..4f6497ab2d4 --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/include/variant/acpi/dptf.asl @@ -0,0 +1,16 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include diff --git a/src/mainboard/google/octopus/variants/garg/include/variant/ec.h b/src/mainboard/google/octopus/variants/garg/include/variant/ec.h new file mode 100644 index 00000000000..feb6c716555 --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/include/variant/ec.h @@ -0,0 +1,24 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_EC_H +#define MAINBOARD_EC_H + +#include + +/* Enable EC backed Keyboard Backlight in ACPI */ +#define EC_ENABLE_KEYBOARD_BACKLIGHT + +#endif diff --git a/src/mainboard/google/octopus/variants/garg/include/variant/gpio.h b/src/mainboard/google/octopus/variants/garg/include/variant/gpio.h new file mode 100644 index 00000000000..750b0d4cccf --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/include/variant/gpio.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_GPIO_H +#define MAINBOARD_GPIO_H + +#include + +#endif /* MAINBOARD_GPIO_H */ diff --git a/src/mainboard/google/octopus/variants/garg/overridetree.cb b/src/mainboard/google/octopus/variants/garg/overridetree.cb new file mode 100644 index 00000000000..0230a29a894 --- /dev/null +++ b/src/mainboard/google/octopus/variants/garg/overridetree.cb @@ -0,0 +1,180 @@ +chip soc/intel/apollolake + + # EMMC Tx CMD Delay + # Refer to EDS-Vol2-16.32. + # [14:8] steps of delay for DDR mode, each 125ps. + # [6:0] steps of delay for SDR mode, each 125ps. + register "emmc_tx_cmd_cntl" = "0x505" + + # EMMC TX DATA Delay 1 + # Refer to EDS-Vol2-16.33. + # [14:8] steps of delay for HS400, each 125ps. + # [6:0] steps of delay for SDR104/HS200, each 125ps. + register "emmc_tx_data_cntl1" = "0x0a0b" + + # EMMC TX DATA Delay 2 + # Refer to EDS-Vol2-16.34. + # [30:24] steps of delay for SDR50, each 125ps. + # [22:16] steps of delay for DDR50, each 125ps. + # [14:8] steps of delay for SDR25/HS50, each 125ps. + # [6:0] steps of delay for SDR12, each 125ps. + register "emmc_tx_data_cntl2" = "0x1c272828" + + # EMMC RX CMD/DATA Delay 1 + # Refer to EDS-Vol2-16.35. + # [30:24] steps of delay for SDR50, each 125ps. + # [22:16] steps of delay for DDR50, each 125ps. + # [14:8] steps of delay for SDR25/HS50, each 125ps. + # [6:0] steps of delay for SDR12, each 125ps. + register "emmc_rx_cmd_data_cntl1" = "0x00181b1a" + + # EMMC RX CMD/DATA Delay 2 + # Refer to EDS-Vol2-16.37. + # [17:16] stands for Rx Clock before Output Buffer + # [14:8] steps of delay for Auto Tuning Mode, each 125ps. + # [6:0] steps of delay for HS200, each 125ps. + register "emmc_rx_cmd_data_cntl2" = "0x10021" + + # EMMC Rx Strobe Delay + # Refer to EDS-Vol2-16.36. + # [14:8] Rx Strobe Delay DLL 1(HS400 Mode), each 125ps. + # [6:0] Rx Strobe Delay DLL 2(HS400 Mode), each 125ps. + register "emmc_rx_strobe_cntl" = "0x0a0a" + + # Intel Common SoC Config + #+-------------------+---------------------------+ + #| Field | Value | + #+-------------------+---------------------------+ + #| GSPI0 | cr50 TPM. Early init is | + #| | required to set up a BAR | + #| | for TPM communication | + #| | before memory is up | + #| I2C0 | Digitizer | + #| I2C5 | Audio | + #| I2C6 | Trackpad | + #| I2C7 | Touchscreen | + #+-------------------+---------------------------+ + + register "tcc_offset" = "10" + + register "common_soc_config" = "{ + .gspi[0] = { + .speed_mhz = 1, + .early_init = 1, + }, + .i2c[0] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 88, + .fall_time_ns = 16, + }, + .i2c[5] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 104, + .fall_time_ns = 52, + }, + .i2c[6] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 66, + .fall_time_ns = 90, + .data_hold_time_ns = 350, + }, + .i2c[7] = { + .speed = I2C_SPEED_FAST, + .rise_time_ns = 44, + .fall_time_ns = 90, + }, + }" + + device domain 0 on + device pci 16.0 on + chip drivers/i2c/hid + register "generic.hid" = ""WCOM50C1"" + register "generic.desc" = ""WCOM Digitizer"" + register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_139_IRQ)" + register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_140)" + register "generic.reset_delay_ms" = "20" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x1" + device i2c 0x9 on end + end + chip drivers/generic/gpio_keys + register "name" = ""PENH"" + register "gpio" = "ACPI_GPIO_INPUT_ACTIVE_LOW(GPIO_145)" + register "key.dev_name" = ""EJCT"" + register "key.linux_code" = "SW_PEN_INSERTED" + register "key.linux_input_type" = "EV_SW" + register "key.label" = ""pen_eject"" + register "key.wake" = "GPE0_DW2_04" + register "key.wakeup_event_action" = "EV_ACT_DEASSERTED" + device generic 0 on end + end + end # - I2C 0 + device pci 17.1 on + chip drivers/i2c/da7219 + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPIO_137_IRQ)" + register "btn_cfg" = "50" + register "mic_det_thr" = "500" + register "jack_ins_deb" = "20" + register "jack_det_rate" = ""32ms_64ms"" + register "jack_rem_deb" = "1" + register "a_d_btn_thr" = "0xa" + register "d_b_btn_thr" = "0x16" + register "b_c_btn_thr" = "0x21" + register "c_mic_btn_thr" = "0x3e" + register "btn_avg" = "4" + register "adc_1bit_rpt" = "1" + register "micbias_lvl" = "2600" + register "mic_amp_in_sel" = ""diff"" + device i2c 1a on end + end + end # - I2C 5 + device pci 17.2 on + chip drivers/i2c/generic + register "hid" = ""ELAN0000"" + register "desc" = ""ELAN Touchpad"" + register "irq" = "ACPI_IRQ_WAKE_EDGE_LOW(GPIO_135_IRQ)" + register "wake" = "GPE0_DW3_27" + register "probed" = "1" + device i2c 15 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""PNP0C50"" + register "generic.desc" = ""Synaptics Touchpad"" + register "generic.irq" = "ACPI_IRQ_WAKE_EDGE_LOW(GPIO_135_IRQ)" + register "generic.wake" = "GPE0_DW3_27" + register "generic.probed" = "1" + register "hid_desc_reg_offset" = "0x20" + device i2c 0x2c on end + end + end # - I2C 6 + device pci 17.3 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_212_IRQ)" + register "probed" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_105)" + register "reset_delay_ms" = "20" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_146)" + register "enable_delay_ms" = "1" + register "has_power_resource" = "1" + device i2c 10 on end + end + chip drivers/i2c/generic + register "hid" = ""RAYD0001"" + register "desc" = ""Raydium Touchscreen"" + register "irq" = "ACPI_IRQ_EDGE_LOW(GPIO_212_IRQ)" + register "probed" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_105)" + register "reset_delay_ms" = "1" + register "enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPIO_146)" + register "enable_delay_ms" = "50" + register "has_power_resource" = "1" + device i2c 39 on end + end + end # - I2C 7 + end + + # Disable compliance mode + register "DisableComplianceMode" = "1" +end From b461865577ed57b4512c75e0becf44b6b7ed0922 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 20 May 2019 16:28:49 +0200 Subject: [PATCH 377/588] Documentation: Add Rotundu Add information about flash and programming header. Change-Id: If34016e20dd580f92695bef5b67dd0c282b0b421 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32894 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- Documentation/mainboard/index.md | 1 + .../mainboard/opencellular/rotundu.md | 76 ++++++++++++++++++ .../mainboard/opencellular/rotundu_flash.jpg | Bin 0 -> 94737 bytes .../opencellular/rotundu_header2.jpg | Bin 0 -> 56605 bytes .../mainboard/opencellular/rotundu_j16.png | Bin 0 -> 20835 bytes 5 files changed, 77 insertions(+) create mode 100644 Documentation/mainboard/opencellular/rotundu.md create mode 100644 Documentation/mainboard/opencellular/rotundu_flash.jpg create mode 100644 Documentation/mainboard/opencellular/rotundu_header2.jpg create mode 100644 Documentation/mainboard/opencellular/rotundu_j16.png diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index 9af5c80883b..fb637c423b5 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -44,6 +44,7 @@ The boards in this section are not real mainboards, but emulators. ## Open Cellular - [Elgon](opencellular/elgon.md) +- [Rotundu](opencellular/rotundu.md) ## HP diff --git a/Documentation/mainboard/opencellular/rotundu.md b/Documentation/mainboard/opencellular/rotundu.md new file mode 100644 index 00000000000..8773e960a3b --- /dev/null +++ b/Documentation/mainboard/opencellular/rotundu.md @@ -0,0 +1,76 @@ +# Rutundu + +This page describes how to run coreboot on the [Rotundu] compute board +from [OpenCellular]. + +## TODO + +* Configure UART +* EC interface + +## Flashing coreboot + +```eval_rst ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Model | W25Q128 | ++---------------------+------------+ +| Size | 16 MiB | ++---------------------+------------+ +| In circuit flashing | yes | ++---------------------+------------+ +| Package | SOIC-8 | ++---------------------+------------+ +| Write protection | No | ++---------------------+------------+ +| Dual BIOS feature | No | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +``` + +### Internal programming + +The SPI flash can be accessed using [flashrom]. + +### External programming + +The GBCv1 board does have a pinheader to flash the SOIC-8 in circuit. +Directly connecting a Pomona test-clip on the flash is also possible. + +**Closeup view of SOIC-8 flash IC** + +![][rotundu_flash] + +[rotundu_flash]: rotundu_flash.jpg + +**SPI header** + +![][rotundu_header2] + +[rotundu_header2]: rotundu_header2.jpg + +**SPI header pinout** + +Dediprog compatible pinout. + +![][rotundu_j16] + +[rotundu_j16]: rotundu_j16.png + +## Technology + +```eval_rst ++------------------+--------------------------------------------------+ +| SoC | Intel Baytrail | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel ME | ++------------------+--------------------------------------------------+ +``` + +[Rotundu]: https://github.com/Telecominfraproject/OpenCellular +[OpenCellular]: https://code.fb.com/connectivity/introducing-opencellular-an-open-source-wireless-access-platform/ +[flashrom]: https://flashrom.org/Flashrom diff --git a/Documentation/mainboard/opencellular/rotundu_flash.jpg b/Documentation/mainboard/opencellular/rotundu_flash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f14617c17aa4bb36c10923a185c1eea1ba50ed3a GIT binary patch literal 94737 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

    Ree0YKDJeS2lFE-Pv5_cP}goVB#| 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 qgj}v7qv-txpqDlh$p z%S+uh0CCM2U<4hEZ!4PRxXEfo)CueWI7E$b{$v!D5K%wSU)1J_W8lQyBGmm@*euMJ4n zh78YGw6I(sUqF9#K~g0s*az-VdhV_J5zyzh+ z)rOI~eX&R=HosH_{*)hyT8c+5H#?plP@epomcGhx5h-?l^s)Zg2eLMxw5653hbMDf z|HSNQAj0avv>#{HY zdCn&DhSdbg1-8b1RmMr~q{EDsYg_KhQM_Vs+Y#D1opod=Gg{uy8cn0L34Jk9UKq;e zs_Eh5n3$MQU@rlhfxaPWWJ*Qc3*Oe~m9#+-P}GN_YVPQMujP!)SX^@f$7Z6uT7DGWMX$Qb#a8r*l-f`dP;l zSKVnfUBYgY%%AlS6|Tg8oYCxVFR|}iynF?k8%k?=t|XoWOmcOsNKAB`2|1k{1=9X} ze8zw8GFjyPPy|>REDFq7>V!}|?XS|DRTYtQ%&j}q83qgbqK* z((VLn1WU&p70TkCZXOd3dO2THp*JHJW7BR{4{08jw@U@vV`oZHKaejPak%T`dV)i! z`MqAp1!>Yr)E*C)0@Xcv02tJX)Fu@K6y)K>nyBNN3u81Jy{54!WgClb4x2SRQ^M9{ zh0;~@7kiiUwXz}+7$(%@T+iujuNnqP)weuSh9I$#|?F1JCWNxO1kw<9rT@j?Q&)LO~lpQ8z5 zh+%$Df3d7nZW%?X*#4QSoH()DXhU;|9JgL}hr54U{>fbH2W|{$=Z4 z5UA3pFt$c}$#%7j#Y4jh*HX%tM0ymx2>yyh3Lh8&A#2A)|>S)Ys z%S|hBnWl*&Exn3-iB@=yIhGutC?{AijP@;{t7&dyXQe>S{lSf6-jk;3{azzfuHP)H&3eB`mBCJRWpJ>FOVaU

    za{NZHJo+ueM!{7z`N`_! zb&(nfC53l>jqV-Mm4yh0O=|3A6y}=vVU`uqfbWuOGQOTzyot&FU}GFrE1!%#cvwkF zO|5DNPBz2j^>ZFxX1_miW{M6m73zqmvt z6?1eorD9YDpgB(uC~9Rqq>*mTbSQHEWw+T}JHJ4Ps*^veYAKbno@VYi5r~MG;sdio zlP0iPVo^CPOFl!QQz*(bRPkM&Ry-&hp}&cLxrw;kP`>o|Vu&*HgdHY*KB1Hy9fq9T zMid6taW}?3KZFapRu&ZoBSgf*9m<%1o5%>pXcYs(5`5Q}3`>FD>Exxt6{uIb=jP|f zg)wwSF@Io1y{`qc7GiYEBV((c1lYE)6n7Ik9OtiY^6%FO;B!4{ik)D#G^ z98U(k_#&h^8@05OR!tRnEI9{(aEzz8l2IopCBw0B&17LM0G99x_%o%NQ^#}yuV8Xk zbsWKfYzCOHFY*+OfNofkkYA7zQr${Te{_3Nxt);JN{zTiaU7Urut*5NG?LVY(_HBi zf3UT==IGZLv!BZR4RH#`#JK30Ct}PjKF^11n|o-{`d@)R_k8HD z?k$%ke50p(Ye#db4V9G}QV+jj-2xJ)(%itK5a-32yLRx6R zGMov3UZ#bVM3Zr~;iWqia;mB@)A>qX+{DUg0F@Z-cMP%G;84!B^m>0Ea%wco9{JwJ z(Yx__Edo(^SAq}v(usy;aYArR03wX#r0Zjh zt-r{_xRC3Rd-v6}Eb3%J!(^!mR#dhz2+{w5(4DR6)$~HfRL^`?SCo7?HpW@s|3HY+ zR&))jx*8#r8GiIrdQC3gHT9Zjz6%0dg?D=COVbXf6ofK2OeLx)xJdPBWoe`aFD-+O zLXEn0LvvGBY-+W#08aek=tVeW1#VFaL=yy+2)RALunejsdBPyj2FlPNQiFU|JzL~M z?e@Wio?1qE{wo9`ng)D-Ee5w)Yc&z=^ z!dGGQ#-)t5j7f=*5C8c{TO?rRH=VomC6kP3FrEu5D7360ez(8rH6Hd_*}6#(+aY45dWC@XpcX_l1W+7()T}>oNO+ zDX@Co`~;MqFDo*;l8pQ+%SU?P&19*g#y+}Z+x@wH$@AJSKK(uEVNwvGa^A+t^NHyt zyuYMI@Vr`;>603cA2p=*Ub1dSy|5QPEK+&`N|nDSYHLA=i~zQp81-y^Ok8YJ+hh3!nIf!aHU`aT_M=pls z)xlEWKUoc}>?P7wTwv(i$jr-Kk#gFb4NK1k&EDMKY*d~-PmJexj0>`lUrq`tGF1xl zp3^&(WA=JzMpsiAO$?N2?7RugbaCivKk^aHF+s( zs;E(WYH~z3))_;+fL@+QNQ)_Dol>VxXO$3V*{EJTFA>X;Dr%dSdh$X6<=LfiM*~4C7abwU^ldt^y%$Q}(TuEk#m%-iY z^Qs2uj$hsnGXJZ?#^PHjBY6S=o({$+#wel*Dh!zV8(0P+CZ$vXibzBTvqMtn=am^8 ziLU1t2^rFGU{);_n7+%_#wtcq1}`$mf3W<$UL|3JKiyV4Nmn7Q=a zhWJXF)!G@K)8(_LrLSsYC5scG5{zdoAI(@r#HgcDXvuItEK4a%8Gy>}Qd8^0r}MnXf-wwm)}CmUtK^OHx77kePHXM-~D z*=0!;b2q-+*;?AQl2ipaT7UQFpRT6Ku*Hih7^{91GWL32?bMq%n$~sBj2BwB8U-qAYURWTM6h0DO`FJV7S*u*og^PufCnPBt3>pJaWz3P!G^jT zpe5!>=8cD$t=wNHPD*K{6a38?UpyB*$I>Y79-VTWCfjc`r;GxEMW@@^8!gtVRw_;0 z?2qKthcYxRQn4syVdf_MTKSTP5iKY%Sj8|@F!4r5WQxS8)hQ%Rk*MDd5mNz929})Y zqfzy#=QveEn1Jhqlf%Y+>vjFv7eUi3`-U@8^Wlt^M!~5GOTXJ%yCa^%<0Dzhjo<2- zQw@n#f%A{9_ngsQT-kq(JQh22?{gXiIuhUK((E-VCly3T#hX>u?t(V_#;JAXNR`tU zau8lb1b9o`xv^P3_T+AvVOe+z_~2{?8Yv$4Zy~?le`&Jstp|aKm}mx5!-qfHo+Zzx zRN2zF3-k5qn4VXWl6=$Ebn&J)*Oec^D4om$YvdJ=W+0EQu4tyuo*bNCxFFd`V*zq^027iM=n{4cQ3#a19Y?Yn5x&ik9*&q7)tuPYns?-{16s^y7845 zbIfi`nx6TcE?DsS7Dk_n#mTzc8Ka$F1)RLsX)F1tJ8F$<7i1O%HhEh?xvaQ5m2Ub+ zN9`NO&mgVOu2pO7t(B)FngzEEPDUrp=0Hp%e0wuvs}iFRD~qYPud_GkIew%8fu^yl zBIIB(0>n`}2U!l>#4WE<$|LbRckbxiJ(&l6;uA{l*5efI4SHS$K`NP@D$tSLfc+gou_{}6T zb5)C>0N=EOQu=h)cQeqp{ZD96dqJ+Xsj_7}FwqL%{Y`bf+``0bxl& z6s*-ra}wEt9)`hG`kAQ|i^kEg1$Y_OL<$T_VwY0??15_Qb%Jg*N0NG0h3=f2ftf}c|7$G71925xPh{~A>X zZE;y0J7=_kvOdhO9*wQ_t<@O+s?RLyjHl>Qx`{4pK^E|CykQtUA@Vj`<7$}7wVZf8 zn=?o%ZlljG&$_a-4~kRf%G^V{tMYGuj<;v^MMsZw3S;O#>!A(X5+4{c0b8xEs3!EP4fH9^G1+g8}_{AqIUE3TZzw+rn@$kc9_FSK^c3hOT>Cy z)1;ODfF*;zAIH(;M)}G~mNxdMKt7%+G?uMNfk)R%ucO`bBVb@<;Pa_e(m1)UA*MS7 z-e$uP>jey@t3yr=7~Z5zH%)wpWkjM+-Pr2IVzi_$onZg&>O;8 zf6r+N&Ahg^lI{E($o|DBD>5x0ed0mZJ9B};8#U%bl7K38ik55(bq0?t4IjI){@qAX z_N=p@FT0f2c(f7qH(QS4lO&>9S&EkZljtYv`7?+NNR8xBvT=k_GQoa7Rg+?h`crO$yTl;Q9kaCOnEtuFtdcb+^ZYO9`5wiDgU7_cqF}=&XBYi|L&?g)DMrObEh3If zBk>;RM0^j8!hC>j9j~sg#$D*0F#v|Sgsa7&xw+IqATD!nj%x|@ovltEa0bJrQ>s`% z_Pp2DsWK#s%5Vi9(;!uyMgE!ub6E_(@))+a?t#rKC#mj7uHUnu$-)H2uwM>YaThBp z0V!Ryo+OUuu9vq@O zd3&(&^YN1#YN@@WO0L9X+i;67Z4Kr9zESDP25Q{dK0yyhK8Kv8cjJ{qW|_efZ#0=q z5TXG=Osrb#P8(&E)9Cm8>Sw9Hf6VC#X`krLu@wJ@9TRRytrlYR7w11-PoR&e=v%>! zgC_%MA?_O_LQbBCR={zE_Vpg$k+iII-<7oN|Iq(ERsC@I_=5hpzGjXqu1{EcPw3e( z=R#L}-Y&dfX`js-uGy3Pvwn>*zpnJf9A4i-|m;qTmz9k`gCs+KRFh%r4) zzID@gLQvYCO~U3tzo+||lr(-TQqg~0D=BbD^c6j{E0a)#WI!uFT$O+SrihkL(6+^g z%GF&AjZI2aJkj_}`?sa&IP+{4V#pKIvq*{hK4E+pIr04Pu1U&w6$%Hx4oQEuZOFz zuwth)R)@Aey2VMY5bKj&dO4UkrA2*dnKU;#S%o2{rOa$d`8eW2JvnbQ-8@b+i$I}* zQuq}OqVa?KYe;rgK)P{KsY7tv;J6648M$R+X`orDe?4D@ zO{P4~RhWjB;blbx2fqIvV0M3uor)DO@0WEx>}avCvf}e~#6Tt^dV$N^kaoG|r1%eR zu7Rh9ts=3((cI_|WYG^sotNG2ygIhSntJ{pAh(Z)|4@$!?;OQh9MjZZ-HC)Cj2x zOZWZ3R5r#G44xn3ngkA<6YW3o3hY{gq#dv72I5l9$>XvJ!pPlo#ilKPgoh93r_Yuh zu<>c%ScJXOGf?l25Z?;<`c!`emgGikB-f`C4B_#^l&=`FzC?`v)-%~GX!8a#d}7j1 z%5x7!GmO+rNduI;lsd)zos1#^_9-gRa3#ND9r7W5a9A`2=j%mr+Ax-zZp$nl`P;U) zbdgr&YvN?lUB`w?kI2Cxm(G4C3ItltTCVUfpG&s%vlx6V{ma^@P|XE@)qIWaImxmu;wepMYP|*{XL^iwZ zzqP3GGbt)}S8Tj#e71ZrD*}}nT-}y;#U&xz!n?~eI>xg4=AuVFXEfrxg(tbS(YnVV z3&c2i>(=Ez;{L2*KQGo!$sQ&ShPctUF~7}wR0hCFqxBF3siuO zSoNELG>e8j^=@k#j+36l_s141z^{^GE{lFE&7!L&?mHUKEjQw!Be1NIjO3hif)mwx- zaer*d&yoI2Pr1_);gI#-F3wJbTLhifrl+y98iaXc$wQh}JPwZEKi#37l2#9&hFt~M zi37@o$_YqM3Q>I%qr@{52r_j!^f|9G3G6JwAev)Tf|e=LAVEC)P&vj=6;8(5>_qTz$qrSlmNylBwO~ znFT@`84y7KI#4V&6>8m{>w0d7|KWN^E5ErzgO>h*9)1&L| z25zksrWhxG8HSrwS#l0m;h^RM5CzanmYwRMlEnIdQ*<>Ca{>ztzm1F%kdmizV7ClL zR8W-Dogd*pc{1gGir}6S>M#>lCN*s_Lr%@-9Tuem*lIz=?mI&qRIMR^UbmNn1v+ig{>L~C5?Y* zRoLAf?fe5IQM9+$YPf{n8%VLm`35+dKKRo*uok%M)0k%_Wh!usyN|ApNCbIl9?=-N z{fE3X>@AwIQhZy~8EE|i?rM?K9abZA4AohM>@*LHjNXx@k(~x8D;>BJcI^sTC&fE6 zL0cRqK{j{Fxjj->Z_LiI^)0U99N@LUL%Ew{+vQ3OU*Br6Ik zfNM47d+FTgzEPAp*$C#0tk29IT2^ZQb|TIX;oDpLxr&WA<)yy@82pLi5@6ohA8aEiB*+=dUFc< zY0GyxRxURFxDBXH5^tnG@u;C^#=v@OQQwBG;3_@<qXYZW64sbLL3$>TGQNGUkD~;J~8=;RT7$UaZ~FLbv-T zHtJT(^7YzdT&RH0{GV+64HMUv?Job|JIvwc)3v8~rbkV*NWximeuVqsK;)2>X&y|K z03c2&$_g{q2j(-^SbE5 z^--M>r&S&OWb64-p}Vte45K?3ZBop;vv_+ZXxH;5 zV&7KgnyBkC2PLz=FcEQ-{ry~n^+zC0k+9Z|yNkobT$jVg?KavV+Rf|oq9gws0S4=e zQ^Y`r+Nn~s2a|tvmxtmY{v2lB2F{?(c+q6zN4Q|8rbc2)`P4p_4+%>NB-NEpmN+fq z)E_`S!$9)PC0gmf?aJr3j}N*U!_t-vePFl z=%>0}V{>Bvj*glsZ^w)1l9B9)Tevcwfu*_?E9hPTzq>y0qs%?fY{$#gW4lp;;uqgH zMjkY$^3^uL_Kr*sNf=5BE+d%hw=z@lkMI>f!UqBQ^PRN>f7RO2lQN62Vp>GdknH-! zMFW}=wXXhb8`I46-P*E!w!@U<<-X@M0p9lZH;U>7G=!Zzr*A#O+azLW9{_M>u4u7W z3PLS>x(@>H+CL0+3IFJ*%u?b_NhcPcdcO4P`|UV>mp6F4%}sp3Z1`;?rwrCBGDRkeJ+uu_0R+?CiCr03aH*5L+?e^=R3lE7U7kfbEtAxdnK zmGCJ-YUY#h0l%{YP-nB>(-^#LZ1jXS`P!FK%_Mr+)|?eu<-*g-i!<-#6t#!%R9Trm zyP0!=l&$U{^cDLL11l-c;^eF-l@Qf3<+2*Lw1%Gk(|0oB*k^uP$8+}XE)Q>67F>8UziWMx>Pp!dOMzK-C!V5c@47x2M>1~J1e1gtLO>_& zgNB1Eyv{F&h)GC`h1;lO@-O63EosJTDWnh|@^VnK`jIK_Y}1eTHo2%HSW^%)cjvv> zn7nsyQ++n<=w^O}YcG6hUXH*ami9MDcD_Dm<72ROJ$;Ec{ z@xmPALiPk*bDC=mw5x$>n5QwWg%;I!L`l2G^kH4ko1|%RK4~{V7tlWd{a;>POw;po z)$YrxVzkZIk|Zm)%i#@|#eG_jY3v8PtCb~D0UOMfHZvZtrz|oD`uiAQ@;`unfcSaw z=mX07j;E)`+)3+4F^6^*U25pOZ=_iE!SPphWt8HyV3qQ+G4i9=l8f^!Dbm_YgvLf@ z!p|dpzb$}3py_`L9|y@1>5t?NyOBJjyiVfQ4&3}aFs%YVko;_eFu!efoxA_0_}16^ zrt4Yeh?k;Du+bDcdn0k@+rAKBDnGFW30f~m*k$XYGBnFzHeMJ$O7nNLp$f+)BHC-+ zAT#{?%~POJ{X+IShDbzH`ZZ+DJKba(O{&+XgC2A$R1TdW%$LH$mubfxZ)l5{_9eqVQv;LYf}gf!VPxy zY)Drj)8EE5;@^;c%3CRBIvgjo^J>k78ME()lM9;umgD{CB^d?9DJ{oJP_&r2aUzDZ zw^jSf97fmcr{zPdLftYgJ59g$l96atq+6!y$ItDmieMzth9 zTRvZ2=2|z=G}Jbt(L}wp!IVSrq}NwKjiebIB!-a;kMQ}-jCs#e_n%n2EiHV@`2vJb z1xo}m8U%8^`-K)s>wdj>Tuf2X?YU>maGDlG$+5RHD1U7I+sEOy0c zB%~oaB=W++lNp`bRszMkHNG;~ZdW{bcSaFGD@f|<KEJU;zc>#LWXNVY)YR7l|dD!_EO+CGL^YD&1~jf1T? zv$7$snH|eiW@F@7s)gb^!C<-D`4dl^BV&0;+1v5l>tPa3;Zqmn%hMx&MFr!cu6Sy& zm)9>2wFL(l>GVs;^_@?!3$283-OcAl9$@W^A+FT4&7N)IrjnQBB8rDV{Rtkd9Z;H1Yf* zUklIhV*nbkE0<{NZ02DZJn%R2ptr9H_qDZ!yy~&uiV{Xoq6YuR*8;$k! z;ddpqB|F04pwk)58W+>zj7lv(I!a9$oaMfW%bj}(+-XFkU(GaLZ)Fy^sB;*a`Qd%3 z^Uz?d#_H0#qK-XurG3i00%PWVknLmK_mXJaUqQsD>xMyhK2vn@Qg@{t#~g%SC?SZ2S( zZmgWCb(!wd-ABHA7W|3)R{q<`c9va1<(2$53ZwM~rVX#b=wsEU=ln5movf(J6|VxD zfF!kAE?j9;Crfo=;_UK#&vg++*xTPAEx-!(TX_^4lZ3`aphQfA`iVJC-|B|$r^mso zm8R}XsZYqOqIcnZ_h@5G6E!Xfjf1C83hgX=g36o1=VzXkPG@(aY%#^^I2vHkESPAH z!@&}{M6Do5y0I**kP?TZAwOS~fnRlSTk4#fW>x#On)|wy&$>??JN_*a??!v&oY=o< zZc}Jt@u#7oA)E*6;&F`m=ivbzqG>6spq72dp>Uh2`OKle* z{SDU{ub?7bwM0iID$BoAhV)Ae;YC~V;X6*PTO}<(jxl2A`FK1FfBOE$y8Z(I+wv0& z=o@zzrR`YGc1mc@3(T|k^Nh4`)!{LJqnSm{rinaopYg@v3yk*>@{!o zh-gYs1a!@_6(i6 zM5~HPv#Rlf0`J;fZO-h>J?fu){sCA!;sX*~jzb(%@)TU+z~8m|Ro7caD>oKf3%t>$ zToQ}Ibk&5ZfU(zkUHJUT7U_)Tx9Ntb1=o!$S8XR4+q+`I^15%A}diTxGFd`W-a zsn$)UB#uzA)1m;@Dx)bO5D0!NPpjv&k|=5Bcjxasq_TU`c`l{#<;sa`^YJqDb*{h- z=?uBSmRe7QhDpXasjfTtELzuE%u)C~b^__%>|V+xyw zX=QM+WkSF7&UVSfCNYDsT71+>-+DG2{&3|w#g03QAC{Qb?cu!kh zzfX{US~S_CWHo|msx;SxQsjl?x{RmYit*f9=KruPCO@t!dHHSmW>xGxpc)=VN;Df~ z+lg=76gt0Grm^9;v9z0ADH!SZ$|V0c@tGrhUY0N*SwNZNklOyJJV-A5$O)}2MN7w4 z_lw4(wHb}_?f4{@r?HXCi4A*H17mh)S!r}W4oy{JA@4k7HX&<`obxcLruQ-7D>QzDiZ`iMt8SjfIny)1yS&^X zQFY;38yP7LY!@)C_IupuwGa@f1--1KA+xN?$m`*C*}uLvR8?C~0eQmM?TvrB`INXp zw)`0WE#7QNZ2ZH3D@jRMTyXKotd%}@G-XvhV{(g6L#+L;I;6IC_<6bW@v{0AWm+t4 zlzb)C$@?Aswm;&F=z3)vITn*GeACp-RHM9V7!n!7*cA9e$?DVq!GnVuclpaloz;`# zG0!05=SOepTAl<>foN0Arj8)TC76ds5yhFl=r0OVR+LA)2a=bgZp}_1h|xRAjCq#G z4}h)ZBxfY)Km5$)kwO~pOu|2?4i2&N?zp;GxV>|k+~Hd2L#wK zsTnaLITRn!qN?&z2>t=4pjYwBD^AKU^Qn7!r|Q0J3$T&e6js`FAfqQ3&$=(eh94=N zsw4GdSVplQuRE{d~o8TWqFWv)Fjx1sS0CRkK-)IUoM$9|eRwwZkW~KnR z4&yG1K;7Qut@&+q)P^j;K-IW0qiYTOKCP`}tI0e6jbF7@iEpJs_u4D;*~)ySdrs03 zI>(Ufom^lE&rhd^5T}SB^SW-souzg@1{FYhWAqzs@%wt7#p7eiBh&34g#?#Ci1XM6 zJmywrTP?pXD#GOkyhL2aVrM8;AYFb?E&OV$PuF86wJ1;h?`dwf^t>nwD=$xM zir~Ox7`PePH|t0oXw<`WdF}tZ7xQx_2cKKqTAu-q3N;SL+eGg@eC{-nGU z-YP9vRE-1K?yUB+O>2MOJD>FT~h%hPcEIRK(=_OmGBq&hJV!hEqQgd_L$K zTXs9I4>fd?cc%ItAt{!Zht6C)JY1STd@6G#uSBd8Exx*w@~8IF565xxnF1!FIA$t< z>IFIufNsAs*>qq10*KTCqDp1*wmH%BgXPpE-_70$2i3W8;u{r5-w41FulhNP!j*M)LK79UhKks*X_hP&lT;~seGlE?p zc<&a%jN#i&?|01Ci*nC1zFe3vuyc|qu^75z_A9+ILL=r?s%2MY{xRgc6Ub;*qPmM6JM1mWl2xlFTFRQ`DS+-BYg}QD->wnk(`AFTTgo0<3*dgRLf&Xzflo=R zAhRb6!e8A+gHny1P4uNxujj6D#ZCG6X+v^HuJ$BLBVew+Sc~^!X*P4h2#HK~@^DVvr8h0d25snYJs61W>ms)i<@_o5rglG_ z@Hva|LVX-%H!NJ$^qXUZG#N4Eh=N;XAE1CVPGPASnTmO;Tdbj^v-#T7K~cEPOl|4k zol|uCZFYaoDrn+MNZ{sHhz->|a&0U}h=gAJuKHGV=qN>v&; z9-=?5K}MsU#)MSG!V-LOhz`NxUYBB~!sXnF1FH*Ys_O}iD=nzM?}m0jVFXemJA?O4 zJogbmqHtYYTnjneRBW6DVr@<5A{!o(H>z0pR6*}{jA zr0VE>+eWmFKVLe=Iq$K@yY8|I^D)&;J_eR=bB4ZYF#s z07d@}glBTA4hu&rTOR#{9wBqGV%PelO9JD4y@pM3JFTrV8|tAk?K)OA0Rgdp6i`$+ zo}-$~CA1?;zQ9MCw8iUYMI2#rLq>72eUsbfozb1g!1n7!)tYAbgDysGVbn!{B zE_QU3O{uA#Qa=2YayJyoeo-L%|sbN%(M787N!*gAOD!jjBtEpdw(HkX1eVAUTEu~KcDF8|64R}i4Xvc3C z2#=6ACy7O6mX@B9E%Mg9=iX^C0kE(z@UXD|-*F=tSWFB!EOIsqR!R|gb`DV$Q|$jq zxxb%B5{7~5Vm%;$O89+US-~2M`8&BCMet?=_*C zkXT6_*F5Q=8KVwG!(p-crx`TG@*hK$DpP}RLZm3F*r~f?>-_PELoUz`dx(*7NQY+X zdHax(@+ftdapLGe3UABKyjlyrNcK;eb zmyx~`p(-$&7K^nk-?7|tTh+$R&<{klP8vBPQ>IOtLK-OEWXRLY*{EV!sAW zU11)S4VaDt0)!R3ogb&rRDJdQ(8HS8^?Yw&u$*?KdnHsESBPz&%oIf5* zHi?E_hjb%LmY%V%_+^ekKrV{kx(c&@<)PE3o#%hX(P(bCjK|{Qk11~R7&VhsB?Hs1 z=W_e!?^P}u0*6*2`)@3i=LqwC39hc)A2onu3zhCf(w+X<{|dIy8DlxSvU+ef_wFUi z#d0(RQ)LT9Tr0(m(p3-viRE4%oFwng=d_N)Gh~+L`MOubnN&MOC4E=Wsdb|(W;~J$q?Vf3beJoL&Yl@&m~gKqPUZ_S0M4U;P42duVrO_ z-UnvCel6^~$WA<#1|}|;c=W$`<9MP z!K4}<)%45Z+iY4K9-{#J4H|VDH>FFZNYVsadEe*H!e&1Z)QK8AB)J{UqiOLXSW>O0 z2YTdt{sG+nI%*MB%NkcG21L=>6-a^U*0x{c>d+*Xz%wA7ej&%*v0ejJS~D6Tel?(9(Kj4I5KIIJ`C{?(#W;voArzty&_akqlg-{4=Mcu2CL8bHU7BIsN-E&m=AB~zCkF3-pJmf=E)XwEP zma3v1h%Nj+?+M{f4@24A@{D(dh?xk-AWmV6#5*kx%9{bkti~}=o{H@>9CxF)vw?Vd zjDg}Y;zC+;UkNJ?e`P7vW3vT>Egw}e*>^RtRxli^{{F~^LZ}v+GpRQ)8k@dsI7sI$ z*DUJ@qU-5mrgfNe*+doTs7?RSk=3IhdLU!8_9Mj7qdsmU!lJIi(1;xPEuGgdzv@Tl zN00#JvX(NHMVro!E&O85;rE~$z>!%eH!wXi8up#4C1FH7Hc#pYF;)S+hT?RGUT@Tl z9|>cg=l6kULP8^MUCTe`&Vh`ECL1O%eS=-ZbWk>rKd@><2L`I5>5hYtUU4BCm-Rp5y#ltINSnoH@$T*cJUo=S>pW8K ze+jSkO68G(`s*=nI|K*RRhV%D=DaH()HmCw_{|RjsFeFp;psswkVQvfn?EB$W z1o#iI{~7Xs@NUBt7+7p@shIQy*E?j(b&)P+>?ANXBs!&OGx06bbU8x$1^m8mGl9y*7OiU~){N}%*1!YOosazITVXBu~F@F~s zY@Ryo0+hfcdX=({)D=Hv#gaX_zxGQj71cV|hyxE(ktMa7t%#yJcy5Q(xfj;w9+=9c zO9HgP1wdk#gL4+sKN#a>VyZdhGc$d=eV?gSlDw7o9hMV#QME-^cB2bI#ww5#QhTtdSQAEJF<$ z0t~Y%vt1sfrY>nga`W8I(W<-P+!h7%SL7aSDE=xpQ(2wk2{&e)h*<=??nS;76G(AU{M*9I!fh+>%NZrQ1LS zddffNb?7v=)_X}>9ULw6f_O!@=m;aFoZ(4%Ueisl_MGWEYwL6n z1B1Pvm^->OoVA=%BN=sY!6t< zf*2^o4yd~S0UR%ofpM!y9dgOw;(vfJGMf1JyE$}@MpU~PHKPAD)Zp1djoT7fP0Z$N z?{ZJyYwUHZMxw{8yoHQWPG!fCUg5Z)D9ckmpkBIm(k4k8ZsBI&W+6q{fh@%7m96rS zsa-(%mv!aZHcaj>!e_4wRXJR_VoQxb$hxDmg#mmXbaPU1nJJdE)2{MriPDiOV>ITB zTJ3Z(Vw&Ww*Pa{0xr#^*4_TFs(P%liTV2!D6EbvHueSFTDJz*=C=A5-ibQ3MX9sol zsrpT#{{Wxl58jheDOqiac?{5PbvG(ZE6wD{z@;!B)RoeQ-egXYYCcFwT*4+6{f82x z9P_$=x~VTw&=Hkz@f3;PdOincsHfBjtuOnhIz-`go#ZW<0&9?}sLay_`*fz^BViGQ5d+nYiujQtuSk;LYy?3G%U9k?aS`l8h0d!`rx;c^%vW`>B6N49qaDI zV&XdV!o@e2zUQE_^ef!24y7nNaBN?JQEemnGQA7jw)W5NBlh_Z7NeH^HzF}_FHP%} z>Ah@GUB?_OUxQ;p>v3aVCRu2D8%p-WQ&Yr+C5F%3UvHd<#l_2|I8?_k6*9Cgw=J)b z%OZZO3l=Xb8Cb{*?ean)lPc^e5dmW|M zMkqo2+z550g1marEdGz5^rx9YYkKkW!6_YI@&y4eYsG`|A5t>wW z;6!5jJ&SIoN*jbpD=XlQb}nqi@#p~%WfQQ>u5%7$FBp&gWKz=xEWDLlJSEo=Md)fr zE{$-aC+KKY*!r=QdKS}xd^N(@(T;sZ)TMY4BrYvcUE6A9eKDs;#lAY0;%2CeGBqv1 zi4SZgpSiHeelVv)({pJ#tqy1!#MUOUHG$0&SenQ5HD967)+MR>A1~-@1LQS{tPNmC zX#};`1V~(a9=O$YE-WeJ78c?xGQXFF5+k=#{mqH^Tl;_g(8}~ZI}}R=MRr-4XG6ef zi%_iSERKns!&2-!7u2d2LuS3OM2PUU;Am;RZoFk)g(z8Z5p6`o-w~S=@VDo)Z{mPd!b=#6^8aO$Ka-?Z3BXSele=6spFN zD@=1CR|dNxl}4(^LX6q|Fo_~QMxRhe=N*{+miL8J+bLOh45aaUK92@ zl)e#ugd-Egh>|1ZtoZsGZ&a^NCRmyjlD`Tg_s3?&_mw)D>!|D4ekG~T67z}7t%hZd z7^0beg;j?t-iIF z;TZHEZT+|8y69%1q0mvLxH!nN$HpwEsNm_`)g28kC+I*?o|=<~$p%Yj9`r=Nx;=QB z{R`6zV{8^4{3J`zL6&IQ*yYs5(S1#rJy&|iT69bSggy^85qOksn2l_KzyU5!Uqgi~6fY&#oT^CN5VBSJ)X z>aoq%zE8wgepzKoBl**G^D15NOpz~q7rA1JRO?|*Q*EM6P1CVnrITWEgB$%vT^Q(S z&ZQb-Rl{5=YRj_hb~I*;r5Op*$W&vN$^QV^t((wd;Zx1F)l)-?Mt#o6p^+J@Um}-m zBbAbGxt6xggb}oiT@_5xbY(Wn@;OI0!$-v0a`ZCn|u`5`b#MTGMe22(u11`y`*QN+!;MlL5{%7F6QKzou$mKH*KQ{jWiB`o* z$4n`}NSC?(*g)EQiS2YK#|@k2bR)2ZyW^fb$XjHtP`>?XYL!|Pc-I9-TNf#U7`}@~ zqPWy`TzZruy5U-1do47^Mf$uVPMy!@Xs$S&4>lFx$fx;X7cB|Ncd*xGdXM=w6Zmwa)LU(x z>{|@5=6|rZDA69PAK^-Tu~#-9aQ01fHjwMk+I!%XhPTlDi2V}9XQQ#1ylI7sVRcRS z*s>FP;cYlGKidew4l>m%si~S2wi;o5Se$y5nVodP=4AIC38!MkI1HHZ z%}o(GdgAc0%>MvfTp4cIRQ~`Il^!T2X=2tY^)JDQ#lm?s#%=cUlq&3c?qun?;VUAj z%H50WRI}3-liHG+h;;%8dr2+i_sNgL0h* zyK>%QMAnmWIyGN%UmjG zA^QvHHAOdQ`jl8^uDC1dgGDzpCxeUXQ9a6P&Qy4#LaOU>M9s4jQmQ5FZ9VWdQ92@$lhm$yBb=lCMP9p~fqfq3&rCcY zk%?^e!sm+%<6fJObw5mGPAs}D{{SX_x*Jcs9Lon4-0oV;y=o@d{782bJSnc^eG9-= z)4n$wshcv?rejgBVI|!0U1Rtc(eH)RGU1wqAg*|@@S`g}B`jERdZMp#z4sJ*ll<*Yv@eQzuFr$>8CiAWk{VV>QP#Q{tA56O)DmvB;3757^UmEm6@}iq^dNrzU5I-=hc+HrdnAV6JOk|hG(KB zF7FkEUWT}-GPNy)yVSYY4y9qbs7k#tgRerp>_Vd1)1f%V$-9t!nOAcpWa-rueGX%o z<~21n!c%N&v@*Zc_?0!GlBkT92_ZOh64^N29}XscBq((rHatk>iQ!wUl}j^GD6_?K z%L&W6-OWoL3lHKFy~OmxnHQO98sR~DV9|2UjUFVKM`T%H_}zl*BGb6y^;?yTFS$~y za&&fy{L5FNo;qQ%y}F6k+M7AS_>&gWs`F&cZOP<9aA?ic&mL_}itni>v(_XW?`89;TSM8|+f$sBtKwMdA|G-#eOFvI zv4=HT@h9IwRX&Ewy=-h@>Nv(0>d4NSo6vdHA7YOR;X>u`{0j)VXf{DL%srZpok!U+ zrLds=$!%w%J~qs@y3~}X@{S8fA}%XTcBolagI)e(z^mK^C!Q7=qTitfWa{ZQ#WNhxYm4@1JQ zgx9Mj4QyPe_>&>{$C{KyB~~Yy)3!4ykR2mt{A0Y4#e)cQ)+r`8@Qj~o}_JrmJA zGghGnyEvo4DQirxiC8(4ai`_}cOAIfg_6*;>N|;HpjK9UN=&M>^AXg#id*9RyO$`nhVd9aehlN}o=TDRHJ}Z>(gWv;8fwLLnBT2xW)Y52}9yWaw z2lEG|!WG1Ls*7=>lAb8|6pX0vIo zH$Q-cO!`GhjMLm$sIGUpc$y9+@c4{{Rw`0c#|344O3KQ^E=MDW{@j>I)-r(c6~@jQ z;B69ua_soZsk|yFXV(~waYr!RWXpSw3VxFG{tYo!pp^n9Dmdihu3OdkF?O5TnNowC z#9^UC$~sXh=Ii~K%0Y9n9vyjk>xLd99vsy`#3)(AsasmUqXXh-`h#u;3B1)A{E!bw zA2Dz4U4TQuLR9&0hs%LHQ##DeS-KOajZ;J5c9^~kh*PSUf<}YXrNFNqWj!4WikaF# zx-r~Ru9MpW?z?v^G@C&msxWxkyO)Wnc!NAya?gt8sd|?wTbcWf70y3#(&`X02{#QI ziqz;{nBcv~Bzd^C^~G`28Q~)t!s`;CjrroS0$l``E#DaK7OqKua|$^#DuET|Gmhfa z-gV5eb6e38tGbMxApmYI5x~OWOsaSmcA*5qOyNO0*R(1aJZov}m`jjhrraFFE0O;I zZWb5lCR0{-n|NvCLTG#rCw?%qKlZ3^aOC_-sG-Z$td!DCPRM22;`5SG9W%463Ay8y z%xOt9lD2kErxwhijgu}Ob&*k0)5U+WnpWIgAGb6}H5y%1+-yWVtl^bi&ZX{Xb6gww zkC?feougGuLYrkH&=IhN?Ou}d^Tb^7$E?>D4A73MEoij{sO*P#M8$i!s{Rl1qu`|1 z4S(7chK8e{;mzonOPk`q5YlE4jWU-iLthcMf(WOWEQKvm z^}R5L22WEHmcF32A+`IPEe4(-qO5rRXnAFixcgzL>V3lOcuTasw=1b;n4m2};8Z*0 zHFLN)?Me!Lr%45cewbx(zLD1*N13N0t~=qI)aq6~9q?zXY(OG06O!8;#w(p7(=?jR zUm7Yoy-(p`u{Utt-B0L({-pkSjhIJp5o$Xuf~(v+7?jJv=u%7-1TOm#5-CgyEi$7?o#Ho1zeY(ayA7+)lFx=s_H61fS$euOu)n(6Gi5#al~^b% zl{y3(r5jGAlIqc0$`K986-(XX(Fw5fXf@jz`3>$VfcYP(Q~|*;eFFW%K-K;WL+gW- z;GcPNzF*ja@QPwsDRdzLgiKXmm4jTw>*HP;BRZ8UF~Dsk3z#E$-IlDyKrYd2__%Pr%6y327@Xy#$t*OTU01}C?xAiRD zcSZiEQl4WsUsGZbv-2+V=3LJaKaDKsIz39m)=}+0GKvj;?CfKbMJ@AuGUri6B$)U{{Y&Ja_X+;<4E5NW8W4g zhX;&L5V9XqW2uh#R=> z8qVS5UvhyQODDBT!M8VLo=0#KFys7QH-_f$lP-FXG*?hPSrD07zeG)$OSIvFwJ@1W zs+&tFI`w^AeU`!_ZgKPr!T;rL}l7Swu%qWD50wH!b!^TmJMGSy>IKWc_ zpVvkhZWdm)dgSgk`MaJ(cqoN9{{UsO#P-IR?lhZUj7ys%q7^v|5S28H#Bl3_5tT;{ zxV{9+ro~)T+X)4jfiC7KluNuyL&O?k3)J#(o!Yn(W?T%x4+t;QmNl+Y0xJiH@*tah zY+UYFALT1Dz98DTCfA4LS80KJ@9crdzO;%0_9PB z9!S8}FL06pmR%wc$phRexawCES>17x`r~kUFyUcr!i}4NzohHhCNT;#a0e9O4cQH5 zTCoD%m0*RX9rttS8Iz(K;Tw%bU^FH)OdyHRe?` z@bK_Z+^r7cH11YuC)PC14xrtF>Q<1564lz1A{vsv`3LFv0*o=EEX`LD<{>WS`9bo7 z6Xp}NrQAs71#nmFiWjmpz#jorbuJc6vx8G`;{dfoUZAiC0{K7s9=QbTgQq~k^(y=X zl#LjFCB3JeRIcv3nCLl1q*_dq&IQUi$hI07E`7!mMsi@SoacWEa36EKU=5@Vm*qAB z@pn4?CPk?M+20p?j~#KCtU+!f_lay~(UIGu5T?IA&s$H-)Uy@TyuZP_K00brhH!P(#VHr__q$ZzIuz_qd7cgU%Bx8Oh z+yHV}3{zOhGoR+3FgbyGg}P;8Rw3M|Lk{OzFH0QLsgvTMN@b-)mx=Csl@j9%=B5}4 z+)1g}ikOL#Jrdk8z|?E0jloTv6~O>p9ms6Po1H|rJ#d~p5zQEL{ zO;CD_f+ysf#4s|D;Ita9m|_0_?o8Gz;d8+#mgRtfoQYpMWDkqq5Y?ge61i-rS&1AT z2C*@Yph}%D^%myU<{3s8TZ%5C*g@O>07UvAYGr1V%_X|0sT9$Oa8j}eDx3@${-@RZ zp3-~C^ux+a`ys2F?}F|IIQ%wZ$Nd@HdX;goLkQ`JuOc8|l_``KOR&a_lPqfD&Fvr& zS%4vS{sa#zeq%LLBj#-$a||UFw~3rCjFRAJKTzA+&H0Q{@L7e|Z{Y(C;(f(g2Z&YL zAl4R=^DbQKZYAOAE?O5WC|67vUw`ntUGoMJDy%l?m6A070O240Xun^i#s2_=fB5Ey^h^8VQw>JFL5)M|SJ9V^$Awz)6{QF2fAS}z z`ks&KRgd#2>H6W{7t}1B!(`mx9gr$DW)PTlF?3ZWgVcJbdLfZ7Wf4t=phCBdOL1#! z8o3qsF>m{V86!YlVp_uI1eESE2wL7InG}zX4_!nLynISv`V|o;bHsh7fT&3fuLL7Y zp!ZYD3j3*$V{z#7sc5$pdYNsQi&T8f^$LAW zL}P|io`h$V?*kEI-wXv)Dygw>tf?FPOqI(jxtC0$VMYDK%p1fne5@(l)bkaRi*nRV zuNA2%V430v5CtVPokfXto~Nf_6*CZ!jXld&rPCH~QpIP|07U*F1Sk$AW;wnxtLk9z zh*pz>;(0&deiN6|4lm+DUjw+2M^c5$kMbL(hnTn;Qsq{j;lWagR_ZUy>7 zj7GB^P3wf#OU<5hGLPj-7JkW`n`2S9*N94H-%w&0#PsmPa~g&*^oUmm5H~O&24xZu z!cLfQ8Dg~d!BYk%Ft$~&ZfFUfaP8tUfJ>Hj7>(H#5}s;aoD)1hDvFrGKk!}rIF2~( zcNmP^H2aKHC|BHTA%htV+Nt)kBwq>_)S!(*!hsZ2r`!ph{Y7&LC#3s}H62`b@tZ}& z8X^X&oJD$pDvuFqJWCqq?kFX!$pQ}#8AWi3Ta9UfoaljBM8^`wIG$r<2vo_l46MA= z?0A$`BMcIpSC#pfb_Fvlu?KmFG&`Nl1Rv~bkc{ek zUXWcHhiO8Ro-ubogT`ivSCXdH2+fS~PxUWmS)(hYq$W-Qd)yjhxMn{S65IGMd^|y^RfrLSJWzN_WYJN7^u0tyQ_N7Yf(%&<;cpW}-2?SLC~!3$ za?ZJ96lqXolxX4j+3*uz0o?xp4+MA1WCPN5$mU#IXV#}jlh=3XuR_%YN4)Vx$UyvKq(hE4t@ zf5tKXS=Y=icOAw&C0aWp;^3O#!xRjwbt@3aN&;-^D+4`2=hnt|!Gw-az5wBH%qEOM zn1Q&h?<1m9FlsuL5ov^IMBGZ0F!wESG^Si)b|BF=6BH4I&B2kp?sOJVjxfwf0|r?D zUzv+E@hlqAxG_y{4afSw?=@EB!#jfILw^eR9v<(hcn<37EGt3Hd}!a|WiRIVnfSb0 zdBn8@Wn$jtUjmJcO2v};O0()=V5xc@D>9EWzAE`Y9-*1p0VwJa$u2bUO?pIFGUb@p zeM31YO>1=lK3~o1)&Tz3d06rvl79XX9ycy!FL2pIMotfF{)^lD}NIS zas9vUe-b*3ivpOp##)eJimRElGvYI3-wfPEOh{`yTJ-|U+DO%LE5tacQp(vy4kuQd5kp#N;Dl2W*+%tuKWuXHFRCO<7I<5z< z9ZrLAJ4)f)cZ1_iUtAKN5~Ar3w8TY=gb9sQ8gXdqUMxnqiLCG`2C5&qWrrZtc;c(X zLI@ebTzk|2W-BD7*C!;n{XgzrCE5s~aOhyDMH9Gx@z4E49KZ7`j@YQj@hpZcs8uXh ztK4846;WSXRQ}aE@0~nz;gsSP{{X^m^`F5B)l9CsmMh+7!Dn^piSP?^rqEvS-nU^q* z^5Un|Z^ArSj9QtWWy{Kq!ZFZ|UrsK(@QSe7@+fc*nRh7x_lX%lPxX(oulqGAMib2U zVVE(yl;inLN4>rw4~=kl^qSHzvh4Lp*#r8<;@-xVCdG*m$Z<7Ia-3sSp{)k=vl z9+lJ%z5%r4J_6vSobNJ=0*yg+ae=SI%O;_t%?_p$Jmwh2xlAyLj-p_ja>Ei}C-L*O z!^FsRsmFg3eIXEir4;8pFqH0U!oclA_ZKAkOMUH)k4X<&}$r zw-<5zTw~$1dD5j~Y?h3>DmL6;Sm!X@=v+ik) zc$mZ?P>G!JR;j7EqFFK5F3$WMBxF?o0E>ezZ=zP>&|KWw)AAZfi+*9LNaTX-N3^{P zprgdH)VKQH(o$5b(X? zVZsC*l98qE6PqW6%2K+-OjtVg7Sj5{u@t;FKGL3LJj!{O&HfYl;X9R6C*<;gl#=7m zl(BJadm;Gyklhv&x{8>)4>Tg?SCr~xWAf{O+MP19iAZ3OO{q>{-Xdam7_3VY^)MUv z6=5f$Tf{QVApUWYMZ)@tQmeX{IwWG@H{j);-7sdHCJgZ^N%n{JtLkq0@wm)rTUvSQ z9Y*z@ii7F|W0s!rei-!riEf|<7_sm5nj(HC%987ElLX4U_#FxQkweD>UM_LJoruI@ z^OZ7)Zu-ZEqEnjgV^0STmx3KLV*WTj1{Oq&9XRov;8n;x?Id|r{w_))Xa1)Ajs=$ z>JFip-akA8EWJXkfj-0it>(e3Nxdq zg&3<6mQKf+YJnp#?@Vqj%xT8*z6`)luWU!!&cvfu?ro6+d~X%SDhAn7hy2Z1Lol%e zOeKUH-Nk?P7tL1%hjV7vQ8^7qp<^sD43Gj{fyYr>6VnqMYjb?g#_MWfF7eN{yBW~aZ{>z+F%}`sO1e&8B1hB z0Yut&8)}NhcDc7xc=5bXgEbE-^2JQW;%vBoej!xHh8n^58Zj0YN^7~16=FFkMc7~N zVgCTOQ5xWh8m(Ngi?eeBI+=SDG~pGD&m*i<9|}EECSc62-zbubDtD6UcUqJa`ePsG z_@3jxn)s=SpWLj$q6-@~M6K|xJC8OM8mU}A13EarhfrLlyYGsqX%+?MUS(D$<5kbh z>@im`ro~)r&DjlTJ2fU zD*lLbdV`ON=c!n}4d<2O%Eum{$8%F3m>u=Q9Ksc=jvP3T70F6*T&jaEcg4ZFLyIiJ zH?*zS0+>KMh8a|Fz+ow7^1cki>1J>33$fIBS^ogH^T#ysu4qz2P}2VZ$<=DZH9KQH zM%b)7?ksD4%_*24Mwlmx#3@`aOzy6yLeO(F3cFzgaq9kYJm1{FDT{@{)oxtKJsGok zKalMQ0sOe#{8z&b{JWjp+b@vBZswbqZm}w=S2uCw;=M;PM5S^ol{RRL=8A*`ZfyL-g@ z$EAx`u>r`aNdd6jqu`2X_MmmYOu;QT3jKvdGCHXK1Wq=kQ~)3gk47PA`$`qQO~D`g zrO%?b5(@iDU_$tbwNU;O?o-15015nDJbiHST;4b!MU>p`F@NY0eW_sAP~hgVGw~SV zsDmk&33ttYqx47v9{BEbiiem1c7{nzC9JT--XVoSF2gG9Dn7oka>nJ(s%JQlgEai7 z^d%pXU}MY*tq4XHtkVPozH(d)dw@>GgX0p;w*q&4K?U&r${T*5*?*~K;OuoQ@)IUi zY+c(L_Dfb~6}SmT(M=H*LHdfkzf*AjrXmcw$#He^-?%bd(e=jE-^qRfLSurV_cKUb zN=Jw|sKrgc)uXXdYoA zBXH(cMmsS9P*m7PA@0un zt}8w-z<@2++^u9>ResI`%nVrMj}O7byNd$N@OzK0NW2l?jJ(eHW|`hc*^FGFl350d zVzkAK;kW}>%KfK>3@+oDM$+Z{4S3-F(A7Q9;ELA<8=7Mt3@EU@LIekoOtPoa7p6-? zvUCyPu_b6K8n_I;)zm`zc!h*+IOKq7f=S@+0ike>f~bNn?8yvgX+&5$j-`^b`I$vd zd`g4Cdl3SSH$PIutqFc{9|w!Xc-J?;osgEoUx{&@&ZXZAXB}K4z6S;+cy-5L3|9e# z%%pIIDmu6IHD_@+Zegmp>X_&H%-d@mds%^S5O{L@QHM}{2&}&1!|pi0i2nd4xpp1Y zz-VSGWMGY-)KjY=?Tv7$Q9VzhP+$0zss18OzlhcdO^`vwF#z4orDR+&qWj#$Oui$V z$J8tT0K!|-^&J&sxNq@88=$WV_Cxq(vtvHyC<`dcubV3n+%$y1*(*FeKNb=A(NPr< z!|@=^&-IMFSDe=p<0fS;1!4>!XA>r8ONu=uCgaj>bP3s5F)!1IIMiiJO5(#8kd*Vx z0G$lVGJEU(rN`pG$XWqwpnyO<%(5=W#45|_@f?E&H9x2PPOSyXWv{%-Hh*Bxqs%}m zUdSd~2RYf|S{hhlS%uu8L1@GKWogjfbsU?_=gfqo?=w|Rr855j>fl8$P{k_Sss1rn zwhx4_fx}%+qGB0Q!v#FnIH>9ynuPC_fCoj#eDy06saDERn3bz>)Y&j4(djcGEr%lS zfG?HKrdU9ng~40~V7nLMY!a9$shvv3RmN3DC~?wI63|wwCh5=DnJVuvuLJWawLd@MDw1MHx`Km!p4B zcov9@nmd=XWT(S$&Zg*tP7hHCyE7{iqX|_Bc}upQ3nrpBWDy8WX)g4N6kP9w2?cF9 zB5{kqIYEvM%CX^9rS|wxsEHV%-Ui2MSsk~Sjm%esJFR-hxQ_0{7V`C05Q#v z$u{wPMtc{zNB;nnRIc0HKm7@zypF)$Vh(Qi1h{+u0GaRpXSex^QTVX{ClLuvi9g;y z&Uf|y00;u2f#DtSo5VMs2BP2m)$lmP#*=R|Qoj+$x>PQN^&K!5OU$lb;*~Qu5fu$W zPOF9=5NuE?Dm1~~rY@!GIK*vVBtcId!YRo;QsRwq_@j;fAM#v`zbE-W_B~CU1Q(_i zL9*~%F&HVQa`V!%JW2{B*09T#*MFI-kN*G}eInX{x3o&z17G9}VUedKy6~txv>0-N zuC-zmypSAy&r#G5twUD`WMNI7WoCb*f1kpIvb=n5wGFeA`#qywL@ik1RinT88F5@V zd8bgvU1|RSilTa=O-eWi@F1;9xDpbaa4e+mOBSMfQ0iB>NIb4BmBF6VsPd7kE51L% zS08f`(%Y!Ac4j(*3^;;~lHm%x z>OQzI?)h)s<0s(Nf6DMji{Q@%?$c+fONALc@nIJWJSlk<7cDWw739SBg0wT#*@{wX z$HbKdnN6crAytU#JNW+qlt0-Y=zo#b;HeEWF#8tn#EWTNi|6c^VV2Rc ztA*EiIvgc{YjVg1-PZ>i7@=Yrvyl~iYZVXmT6 z59tVvgb(;c{mnAq({kec2=en*VjJODhWYE7`OFk7S$Lap^uvWSre}6Lm7$kS2sYdM zEL3hPVZPAtod)AfGfY6(fx5(G3s4RSz(E~AYckNUWi(+?jZ(MeK9&%ekBa?C8wU$EV{lfGq1o!T*vy0NMA&i8^%`)TIEs9tc4r? zOZo*UL?Wyz@e|W?0iM3)O>A(Yy+OB_KPcsHl9FA{z6DF(klMb;P+6V`p9}bHDe*7< z7nC4(5Cu2DDKyWnQx^+^wELN3XbD37$|5Ot5k=1xGM;5w&&dm*EhQVlqIaW6(DyrV zV%^uNtfh~HcTE_Bh~WOfQbAIctjY^aCsF43-TImS7%%?-Zl&*DVxD4_U`n+#+|l<3 z?16fXy3WsLA6A;3QP>KXYT13ks+Z&1W{HNfaCg|Gnw znh|mtTPSK#Hd7j9iEFK@j$N{v*NjEB8j4}uDCQa^i-BhcuQG=b_yJ3G!!Iy{FLQ6g z3jYA#sQ&oJq%jMSruKeg#L8GVFEa>++XzR{VG_JEs_GYhvG{Djm$7?RbbQ`3dqB`W4wOb+z)S8sP@)KPC?No; za@DD6!#m<&{{Se1AE*5j@eJGPd@VLT!ZBQM%4GzJ5r*kA7YnpMQQiWora>P}{KXb4 z(puP=Qg_r$lpmR4MI#Vz5H|g6f|f+g=>%e2n{@!1(zxl6!+wzXNp` zruw2R)Na^)1=$6<;J{kLLPZz`ZWvQ{EFfit>EKp!t7Hg87peG+#pD$mwaOcHkU;9* zr5mAl77)=MGSyzmkb9c<#?3|17tt zj8`no`F4hf(2oJCi2m$_C@I!>OlnrUEOcaHL$zTDMcEIH(5xB~QUe0>KRx;$1i5WO*aL zLbz?XmTq_M2&`*RcQ&;j?nW$GVAqJ; zsb?FDJiVpJP<%l)y&$s2_3Ar3O0R?*3JFg>IJj3L{W7VI_nAnyh`_~O-xD$|?161v zOoaC>w0}qZse^?~?~RZwUlX}sE{-%fxCgrU+A{36MZ}m!_LQNF!(DUPEvzNDK9R$+ z)lV#2U^#q7+en7AR4&5i8d&bGR4zW<$MMGo=EPAuROq@??rj}YAM1v(73OJ{{He5K zjTUxHbCcXCJm+l8_wHj1e-VH6Lv@xF7J=dm%KrdxZQ+U7Thc{IxJ3`@0Pr{Gf;8?7 zF_XEPmzLBpsk!W{FVWtc#RSxLlROL?UEUhtA)K(ry=XQre9g)W4 z8G0LtL!0@M<{7UhFjo(J2TYOMK)RTMtt_SE2`>R|H$3YWG_b`?1V&K?Y-p803_LK0 z85lZvw>mQb4vAjAViL!oj~SGylsM6y$V+0PqxMY`s-A{Phe#J2on$33+Mo(Gd^jgj zGTf)Nbjzq{123uNMvoH3hWT&h1>qitj54fY88-iwire;cj8+qX%iudhJyEvYcxRa(=&Sqh-Re|62{y_%q?_fB$Q)Z2#|H9`hi^0huUKaF0;AUE~PcK)W%w38ke)oC>R+Y zV9}OzBbx*F8t5Cu=VYxjdS=1*6DCLMXK<_Gm+2=i)gF~R3V9r>S0zp5!n&-%Dp^zo zR$}plI$$2@TIf5LYRI^i=y4p(uA-P@GJ}b^ejbR_GRz zw{qU1xnIoEVK03W^<${3^j@jB+YOobC|JNTq{>{8Z1TfZ8P^wxyc^`I5nLPF6JGfD?tV3H0 z&)lNwMqsU1;xkmaBQSXoe;73|O#30p-LVU!1!qMFTfx+7rxo1t%cqM2rDg;H<_X+P zsv6s4a|R6!^(=~wT|i!DDC`zTa;ie?S?Vz36*U=fHO6MP=Jk-ax|mRo^#@EliyK65 zq9p6?#BATW?)|t1nX=-hwXjlys42LciJF>~xXqY08KDZ1)+?SD>Zno1=wvIk>d@`I!ik+EY72=m)8$H%CgD78#zR@ywA}Hvf+kZ zKC)M~Y`TSC_(nT&OT?(Ur6i%1iE@T?C-zV%Bq=>d=|biJ5LQ?TzqypsLjtm2q9k54 zULfJ+#!x(4q8KrcGc{H{MYyzg0*Qo+H5ADJLKTu?_>GTqaS-r}WU7Sl4PUv9*wb7U zcZ@<5q#-WWWLk!wg$EBwaK$+6?0`~Mpi~b+4lV=g;EEMj=YvJeki4vge_+y_3WR1D zvwLz(v^GaXq zg}dfwiw<8h+Zvvt<5sf_URRm1?g~6y0Vamg1yrD>MNGI6XpGKy=-F^YgLj`4|!0t8YtSlJ}xl(+~{+fwp!Y@f(I<)WWkediI)1 zv-kf0033(6t<7CeZ1K%Yfof}f!bVvK2Z1I4bge{2D&zdYJVu)C>#KBMAA42AV)ULn z0q{_!tChiT9Ez~*t*<9qj~R??WZ!Z?4lbCwbO&td?8h{*LfGp(;1>IkP+e@=MMJ+0 zY%y@doRCp%e6?IoF#C}J{{S2eP=q*?IYI`RtN{Th+%JWaFz5__&yRHyS$oIKzr|)T zfA?cdU}eAc%$!!p9m6p*S)Ms~W?2&XB>fI9Uk!4sX8R6huAzM>@>k-hbaZ;7q!AH# zZfY_?U5Jw8eg4$zT=mZn-tx8a+MGZ6g`DU9&No~+zS%a}mLV}>_XE`Q9KsLd7IlYh zyz5_4@e4`?hg6E-Qu2U5GOB8QVVEx9!u&|2fqc#wP`OJFzT=*`{eQDC^&MU~z*M!Z z4&V!efLf8!L+{Q-DzvG<(a0!c@gM&HdFTHC-)&;R;Wpg8%c8dzvTTr;AZd;y(8Mj1 z1cBwuDAGbU0X)-;IOXQSB>9xts(7kf#yI2VF;+Oc7bI1LtT9ARRFR7S@QxmjxzmnY zEO3sMBS*NjsE~8{qb>=z@Zd45_9>!e8GfX1nQk-O6rAI69i|{ zcSiL804~d2tv{*OtjX0KA(EE^2DDO6k!@g0jcm|N>5*mj&}r-RLj79MbU&um;HIU1 z_3%y2KJs7Au<3P;2=i;(PS$Dh7e!{%UYFU0FomFMIbj%MV|=*h{W^ie)AKM&6@iX6 z?)~;l;EoJ(+r;~Ceo^Td4<<*QzP~lcc!S(hYu1k<44_5?vM!R#X1eZu!>%zxgyp)H z5Q1Q(ZEV96P&RSc0}Yk?l#&fR0qUYU;Jz5K^Zx)g`zR^m-9Hvj6E1x3W|O-2Yy6=X z`axQmC<8?v3n&)*A@k0E=c(g;G)vxby#b|rSF9(cMchE@4gUaw11}(tAR^|z2;i=3 ze&akSt`Z>+s--A@TRgriwJwW8w9nlnAmqo;mQrMf7^ALOB$5d+{{RW$34t-%Ar&kN zN*&I1a=`DvsqNV=;`nPd$eOgX*R2-@pZM5r572CR~0H9V# zwyW8(p3QE~8E~(Te6y&2C|eUKMp{KEq>Em>D$x4$j^?NPMairuws_H7su|y5*0oy~8j0+sD;+?ib`d zT795ZS*EsQGO!34eE{xMZy6iqU;+@)&0;t4eG0g^ zw5~4s(zl|G$iDgzzV+z6bO7Fl7odIs-+&lm{vZGX7vPQf!imqI``1AK!~h@>0RaI3 z0s{a80RaF2000000RRypF%Td@FhEgpVgK3y2mu2D0Y4D+Etyj!nz8)&IExbco{tCA zpTaff2iq~8yq<@0EZMUU+w5Co&DOx92y-qjhzpAg2sh*hzWCVuEIBI^%B{9&#ONDCX6~VcSS9hoUSj4jb+qwrx!)_hIPI|dB_!{D{;^My8 zv$PJ8{Xq|jFo#k|@jNb~YQ4FsCJl3A#icF4yqc`E^H(ZBOzaPdd%(?VC9K=4=T_kec3^MszT+axIEd=o zU7e3@4ztKN0KY&$zg*w;&#|scH>nR-+YjWY0xaGq?Iy5gym&qxOIg0g*Qn-w{4F+2 zxi#BiGUuB($?seJzwCd0T)8LyLbZ%6Kb9TaY#+n=zNGc!t&e}&}iFy7~e;ezbuZ-_+_Bpk4JREfZn*(AT`E>M?LSK9Iv}5W|Uybm` zjPxhKcE>&2lDl8?=wL_i?bcm))Ska4Pq@#73kNrRN;qxKF1Rkb@YVpp z4W8b=i+u_GLVR*??+w2tja^Q-Aa4?)Zr$;J$zhg0%-;%1 z9wK<}+l8_?%F#KUJHyG3vu|L9=zckH}7AsbX9% z(&icR8#hNJ2oVEwkbUqcugd%Fvp!q=zsPdOh4fh4=Yn7{+`PwwmII5C@Da%()*00O zLd#W%fr)WFezS6S`ET-b#OA~8@?uU&J3YsMUZi6-1V!cmz+Pf+7BWz8<%!(>p(M#j zxf}e1S{KG09`BwDrd+O@6B^d!3ldktT+YD>UE2+XPhYFE)bowVNaL9iflRT^$0vb0 z{{YLf81U-}HI2zGA~f1C9nW2lndjwyP9GRgw@uyL_aIntg!3-@cZtec((atUN7k z^WY9r84k96f7sOSc(yN)Ym)YZW$gyYo{7MbIDDSMi7GZt{{XRIhgJ@+_5cP(0yuWh zc9HvQ#h53NjkUjGd-4H$rnB2=6N!5_9fPh9!n#eb~b3{(b)dIL!Kb=Vl?RI}h@~t>jy` zCA`0f&H_M$a?exIe>Z}e*8o^P@%{Mo;rPLfe0aa>K$yc(4~~hpdRwNSh${Y}DH+j!aM(-`js-tc|w5{y}))zt|*kHFiNKo<7GYDZ^={;2{xTrF=`#lCA%N}vAMncKo2JL zS)Fj*y!%Zc2qR3>7Doy6UHD~|*ml!LDQe^!o{Kf2X$FZMNHNMem)2hkgb0HeSG=$a!(m>>H*^kbA;>3%7$XF~Ev40a}C8o?7KI||% zN0S-CKCO!h->?L}C8ocjzb+2=7pTsGCzM}dKV#s2^nCS*Tr zI4~Y3Kb#!AFX?~-^PAY#tec>?y>hI|h=06$T&bDivy_JT?Hf^BjABgfRJ9?nm?W&;5su?6Xuzju&SSV7#-U7qZ6WW#i%gN)M5b z!r`oEsdKo_l7XxuY48JBMAMhcepSmu*=`_R%Krc*21=kC6K!6n{E@4!1Rc$maN+C= z3mzJ?B@TbQ3}izj6C>355*Tm#j=JH8Q{?cM^8Uf?{{UD0NB*b!Wl+Qj#iC^C0F2a&FBJnK0sLc9&OFGZ{er23o<*uVw%x5Mn$c0LJ zBU#8rcSRq0K`DXNBv^`6<)rwU?8*#~nVh3Yhj0%ErAecH@@X2X&+LAM-)yGRkf*^3 z!deet_~tqRCXY7`BbG|;1Aj59DULGI@+-xPrMrU4J;Ao|2$3j>aK~e=BHY`LQmBi} z+LfCx?wwp1QIf@uHOcoY6#_fraQTS0dgT2_=;3w26^eC~)2Eq0{voP6V!wQw2W)}y zKg|hk3V8&B;~&X@q{81YCFCX9TS57VL9|8ON>_-xAZx$0I|;TBd}4)EL!aVuxm_8J z#g}8LVnkX>gSh*6KAq3ehNs-e#Tj%2kWKW=g;g74Q3nJ0r{g0Drv0VVa|u#GHR>GRE(TZOtg~ zFo{ZpL?*8=@Rp#rIf79UTI_BnMgkNM$8y1lyzG}Pew=qM=yf?+JCDR*(~!sj2<|jT zA|-65t4b$wiG4u@LaC@@Q%Pfh`AL|bKwQ>Am3%>Xr^(b1@NL2qUvyPRmLs`M6tFlIg&nzql=`+P1}IH}eK8?qWGcP!}la zKGMP{5J;ge$nh~Uu6~rL6#PDe^kb@di1mTH>LG-3+Z0lw16|6qnPf`wpAg`<#*tF; zGK(rw^_f!Bkg$cc!-?hv4c^vre9dsh#TyKlfx+v$ne&EHdsR5BlJ#uPh4P)k*;U(v!X{o&>12!LOs|BG?pqAxi2-u<0Z~_rm{8GuOBy6dyr`udOswdv zAe+y(tMNEUeAc1@3${UJ@(&S5B)7SQO_RCZ!t7${h*T29tf){^6(m-uqEUc+$C|I) zwB>@^7OqzHu(1r-Wl?{UTwC7WiT-CW8r*Y<+$oN}*p0AmdX!6ucq%&%V&`DiP8BM+ zZlZ5uxHd!%44Sxd8dR_?$zqW#AmxiyhIy=oJl&EVzoo&S0uSyHM_8&XRK8mJT(i;FKV6+)Uqr(Y+WbS0%;)+E*1^oS^`zo}9d|!= zepwg%`ILS?qT%xu-Q(%BoAiG)ZbyT-8)JA1t65phs&xsaGXCVV=>!4->4y?DMg{Zt znA8}&>pnGxPC?WySLKF*q&%FkL7c*{_?V3!5q*=-@;#8tElZ)|3DU4jO3_|r*15s5 zfv4tORWAOE7Z{tM1)3G;m7avFXq;E+TT8d<1_#~+U-toVD!eso{6GSrLz`UwC6C&- zXs#e$H&clu<+orSP4exR+RBR4hz{z->(CJxnsJ;$jxMKDI zoFU6L0?@fm4WJ{`_z07!Kv;rmgBFSHxJfTV&*7aw4_ALy-HM_+bA4@iX+Naa><td6$;QPA69^N=cA} zu0j=eEL_Aic}$1^%Fmf+iQ}ljgoXN>oO`f2?!;iEtrPbxA#DTkEF@*#(0PQO z=LO*lmC^QL3Oq2>`==Rp3w_2gQ!MdOrhn9fP#hdl2;UtC!R(s&M}yMLw8riMmNV5o zQvKxuyUUAtfl<36**jh()VhIK!$JnbvDb_HpcRp7UEl=Zi5eLW_=&O2Y*}t7s+mw# zX-mh%>B$#VyoF;EnxL@&h814;e{46vvK}CEh_2M&mS-RAekJkZIfdUIyO%Me2P-Z} z6#SWU1QYcC0OWbqP@uWEKxk#D1*(9&1?=HZY84-Cyp3If974=t3{%<5TQ=OuRxjWlD7)M)TPXgaOg zrBk(@YU6eUf81eMGWm&9+}Zh@Lk*Sn63k$Dny2$PlG^_OFT4RR*r=CmlX63bnwoYh z_lN|gygu;;*oaY}EN|Ldz(*R{vf!<~Yy)ou+CF9RMH)*D4-9NSk{DBR#w`0Ehy2^zHnw+!jS$MY0ml zC5=GxEodBUqRtF3N(DE@TWn^jGv+xjOr{H$0FivE9nsUM*9Ti3p(g9Zz2zseC{`$( zM``YGAui%HG;Csm>(p^Tk0adH!<)zu~`J<`)dMH+td${3%0i!LjC6z?w&lwMUfY9b9r? zT&J^`VJqC*4=Sl+q0qtr9ACt)Lz1?;vyj&u(+I%Qds<_ss{oF z(gq1Z434R0{0fGkL_Iorhrmcqp2&b%Wc9!fCtOCtkO9l6LS7;eM#t#jhd<9aLfhhX zMl5vLREu2Tmf}>J0#gpiB3MJrcs-15u-1oxmHW%YLCk7wAHzABc5!1%TpJFSrxr zkACrhcu0w;0bF+m!i24Yw96T8ndI&Qp5oUmoPv1}?lFv#yobMu+j00Z+!}g@4Z%qe zx&_fYuLE|n-~mARLUpE1QSB?a$xkHZO_xEj4filUHatYEXVc0yIICGy%0=ZqV9N0h zVJus|AOIY39-{UDD4ZeO=lkW^b8q5UtlC%@;eOpudxE`W+vh+o)5pvit>_;Q)YKZj zd4`y!vS5k9TSIlD+flyPrfclC# zc5Cdjc?T}tg<+*REJ`iZA9IUTDfGxKcuV+>5kj8&C%8wH7>`L9Kv+)gh8Y)S542lu zQ`tNCmd_|SNzA0rsa79Ax^i;`IVqKso(OTMh?cUTW|iUQE%PzN2%*7j0A4p1SWqk6 zadCdfsbRH@q6?G=g84wkZ2nc@9$<-DBtxFzdlG|FO^kIWFFZn`r6cB2m6UDM6w>f`gj5m_0OmKQl#IC0BD~T* z-NubSOL`NgN?19B72{A*rnWiYDd@YZ{^7QrB))FfbG?4$UKcvc!*#fTj&0`ass^N1QIO|P^I%ItBGyjA&_kdaN-*zSyb6pQmt_woe-%m3`@-9 zC>2N-+c9O;@=CVbxURF$xpMXmU$f{|P9J@po~36W0gZH}VY@nleY+3D3XbAw>!)v1 zh^aT8P(41ngnOC2+y&IocKNK!#Kg1|5`r$H={`-oA*L~=rjuvXMjiLFIB zf~CT!&MlX24^VikC0Yc_TtyqADveaPqv9+tnP$S0$sWXb<^i^X*pS(F;xiG8_(-^L z+wmM5RR~K})Nl=qws^odv*{Tww7^PQ%=%$$(g|AtvKn2BGvtyi~FrUEeUX zi#Fy18>coB4{Rq9tY|My0W6*CavrEp;p=pxU_7gD6v|3-yW$f#j4WM~^5E zK>f=cHSsWW%(8HI2H>tWw=d6gz7C^l-YO{zrpLwGKFlgMG&G~2)&~j&H38YRjX;_&J3Tkj4AK{!6m*N~EyByT8OUw#-?Nu5nP(nkNzkZ_QwIeC#hylr1Nk1YNPVS5{j=X&{oRx+n_nwkT6l$^m#y@Md2&4!$5 z9-*dG5;a<&ilv*>pj`w}q5x@Q#9mLjZ(I)eV8sOiuPkPEX`K0pb8yr~1PAbfHC4u_ zz?(P|nHQ4@B3?l|u)Q;%p$)9Ops6K*7(&4cwT**jMXY(0=r6fac)GJzuJ#03V z0vX~BppW}NqZ7^KK#nZsl>te)NiD9f*I}r{LxvU@j)tZ4U0S`lLLxZJF4lD}UFF2i zAnyejn!OdZdx~v6kRs=%B`;reb?O-qIl7MV;us!Lb!+h~jRld;+}ETWvjPR$a#RKf zG0<{Dw%ppWr7dFP;sQg*mL#Jpg38z#@LGv*s2Pg!?j??hzF?K-YHuDtfj9*NCM>FbX_JZ7}w1 z5UCno*WP+E2A`N2{c!&Pq_9~ox|VR43tbR?CJ?Yo_i*!&>Y_{Q%fNl-0AOy&xDI!b z>LoDU$~uHNnRB_^N(xD+l)&aEPbbnwhlF7UgWbn?frpHkD&|>gw}uLo@Y5|UG`n2* zn{+w20TP#Ac;+Ko1n?tTx#|Lvf*iR205hM^>i4oWz*6__SmVILH~9Vp6r+KM0>On< z_a}H%0m55EZU$(s8i<=y3^NKNk?wG)=!I?08^l5TOT96+##xmUYNyIr(=Ugqh(b3) z4VQxQK~p!yG9n6nGcCvl zTEDn(4BKs79^iDs4JG-2jA2p3m-8$WmlK{Cmy_lebdD`5GOJ%`?QBZwJOQX3+%44! z;kiy=08y|eTpFBxEVyM|Y`u=L!HPbDHY7TFiWJtWrMRam+Y8)UuK@(jj#=B>6)Iv} zaoD?sN3r9~z;YG$g?5UVgj*ZxACOT1qqbg3QdYz?sOsgMN(wz}09{Nay&5){VkTbx z7@>D|;ZS~PcjwK;+)g%9Rzc^MRF-}J0Gfl5d=tulI|S)DW@&W!f5bwTZx%nPX>DJZ z_=>h^=HW?UyoKIk(@JzO;D6swlz zJbs}S7Ba=p7YbQ$Ihg_2CZ1ylgr1c)EQx%IgB)MPu>SxMIEPu<4E@0?Twf*M!3M~a zxwmiFU{kDrd%wiUFOL;qz7v&-MJ}wjA9$3jn!ptsP)UUM4-w;7>(K$Oi#ZH2n4d?8 z?CvE&sJWJ6%KT9N7zJ+66HGNMQRd~sbFzw;8h#Kg4US=k(Yxu3q5Js1Fe2cnc?;?B z9hY&Wq2~9GGWPuPMGlb7u`Mf-6I3fDunDX6zw-r3et+{2ykCFwJTK1x)qa2T0xP!O zY6#>10G{HG2mJR1)8v`>gc`Em^GzKO_{r(eSy35BOy5^@*A0dTsY#3~@_NomSn^5? zILcqN2Q0Xj;@*y80OT?l)N~Gfz!rDRYJ7DO3gqrk0vr~2kKsY=ziCuNqK8OIABkin zY`WRK5RveRoV1>joe6yh!7MonBi^8;F1W}ni%ar7BnzQj>9{S4%y=tfhCc`md> z$DZIE5d?9og0`R*o@xw@YUn@GS|g%^c!gaG6)VAY{9OQtkmp!h~E>J z2Lf2rzM!h=3GFCG)F3yoS+0@f%7TT(AaTq_1VRMUks1AyP@g5ONSB#AE}TAB~DzJ0`AZd8wjihaqbv{X1*a;+!WhpxE$U028#!!4#|f! z8oy&3%K%{#fl1$g+~uxe zmYl~Dr8WkiaCNfO_R=E+ZShhe=cn?^-gC@G?x%A_M~asg-6;5v1lxXNkzTk@r*1fvz>jxlY)tFJQ{@=F7ubvuU}1?ciT%ACX_Lp($u zT10Yck1?q7_WnwlcW==lrv zFYeR#7&o+t^X^iuxdu5~C06WZ2z!>~G+`8_LMp2y`!VOUk1DwutTZsO@IMk~LN;fnDrYN{GXnGF<^~qnUXl(a0dPh;D6m>f%H8!$0N3s? z1anMuH>l50J5UgXd5Mu^wdg7w(7WOZQzr66pbk2gjtm+K=S-l7P!gN6m^P@`NrebR z7NEH0@c;(mD#0(rQMkGx7OWD!=GG66LIC$0F+Lz3_Bh!9Y?n|AKGMLyiBSTKQ>f?l zh{I)K>4a^ATJjx(W$2JgVRzyRNZHJ=AEYrsaTefuAO@g{KGR@57eahai^Kz)L`PkI;tCxgusYqIAwh0?eGY=|Rzsu2I}%{e zNQy0S7U|qDucuz4%+UIE7UkSB$eH+ul&;~Ma`$#Q$J5ddKz8_wsIK-XfvhF7H$kq+ zh^HL}2@$u1Vr^IkWyMjrxWj^)gCJ}w?%=U}@f%tu;vv-J3r673BL4uyDk_IO)WEwy zi%*q&!8$g(F;$Ncp=iEe%xmf`#gaxlC$&A9hvsW3X1xit%maRS@ zFw6tg-QNV*8aD)w}(q6K03fK8C>hK@!h-tMDA>6pY0B*4O zl(NEwbeC;a9hLynKsk2&BFGtfoJ^-1oksAts8_dXcGMNNL*QV*I4Ow5ZpS6U_#$VL zRiBS>s)XuT{L`b<6-yn$l5vE2mvD#+-yc9K@0o7Wj+dXfa1x^hQ6q%`6jU8w3tnF0 zAPe|QYc0$av-2s<@h-q#_>K9+PJR7ux*vD4>Hv=ESA4L{IaO}a}@}JGv+nI*B@!{&Y&Q(k{czoJReJ^=)G7& zs-WrSC^rCkqH@A=eL8`W<{+lh%j!C&Rf{)e;7uvwJeaP@Lz$Zm+&PH6WDpK01xqeU zhQXztp||G9#W5+ezR0<60`SDFj!U?J4Gpp+znr$QmH-~5p^a5}xv0lm0pyJ+tFrWg zwHDwClo6;QyI>kvPGcLY?b8OVe$Z*EM#xzL+A3@z^f6ZoHb$AWs3UL~{h_~TSJ*tm z!23qF5D%CRB*r?KJV6;*hcT|3#A!UjZUiC2sk!N)Zj zp==+jD;Z@$RO)HJr3Di2=w%&4X)I6ng1GpVI)z4=$8m3#edW^;i9_QeoNwVfncOgi zt*on+l`eRw6&5&7S;U|VLuuh6fCox45omdaP#SX*Ebd*AfC_0EcxpY+S(6uF40FRQ zAZ_#_xK#56s2xEI*!Ye@UP@Ttm!Rj-V7%P!Vh4mtF3W7F*I+D0_m>6ZeNzKx3O?e{ zTWr7{pj2-!h=swY#2~b}JWC;tbrsp^>M5%jG$dkNIVq&0BBrE>ilCNcWubBk9}#NN zxZB8vUTeb=19-O(Sci<+x54&@6^~1@c3Tc3pfoIw`q5SG{zT;ZWVqgEQs;3t3PI%( zz?@v+WAvV2S#ah$soYGtwUGYW)ZoUjUwF-b;x70u-S6a=WOL|#f<^+c@cEZh%1y=G zT8WUfg%wwjvm?azN>hnTMk!SgtB^FFVNKTY0chBrM>G`Jj9tDXQRGX9EjXvR;qWjP zK2-#d$t58K)l>}UAiO|QEUzP}K(2QLf>j&I76S0>#&r&5Lkpd8H&7!8de5oEsNUR4 zl|m1Rakf-m`hcB46+5bz0mE?tLDJ)BwADgtn?*0~}ym0x25^b#yK)ZlTusNeO86DtE`BW)8>Dcj$QfI$Ya)Tu;bc zD(<^Pq)PW2Ej42Kfm_u!;thnLZ<638ZuJ=1#I;i$*qp%v!{ew-2PN4kI)c7xCt6Dg z`Y!3vgpumhp_7m*7d~Nh?FdxP?E%rW#2(oy%a#tnCEu!Ku*r3I5N?NocK{Jc^ z$725g(vJjIg1Bjtx@o3``%ddHcRw&$)aoz18)?Y)HX0Nu-gXvP@=Gg-33lAAi@2=b zW5Ha`7V2!Is~7}@MOBFP2dJA2<_c<~?o`mIV0nq9=w$^tiUGPJVe>7|P&WKP7nmy} zQPdKvShY=j%G8)w8_Z}2a=_)g;pAeG4|&A6adFrAikUba)lFAx)ElP>X$j3FEyu_) zE?Zt_41lU&s^0O8Fpl_PcTV~X z3%5^f7H1?7Q=a0w?gfz}lDw)@8dA@RNH!u|zQj5{pLi12YOLkV08*xCl$$K^DmZjs zUdcv0)TZEPXKbh1NOJKO8qKbFmV|vpNX9NlU|hU1Q^NtiGF{qiO^o#pn^rt}W;P11 zC7$j|^#Y|7{l!YcHJj8nExNNHFcv^4tfcp{py}rMjl1Sc(L0%O5O~Pzv96{DLAfdn zIrkK)jzA*Dr4A+0P})G|11L9)wW(xreXzQxPoMzcs1)oC%lVYKY&fil3)8~D1q<;I znNQ~{5j7YOGMY`e@IW3!6)p}})U1J+L9028WY9M~IQ+~Gi$p1Y%r~=ut`PMusQbnp zU9D{XfJUiO#lHO6%l;rf93UDxiXjmS^JX zDw+kADH4LG87XnwMb^QCVc>z2U^b>yrvxI?XxQ5jnQ+yy_sk>Xp?VqzzGf~P67gJYgvtu4Rr!F>chWscUb|k+RoO3M1+mER|`p%`xPU z)2JmrmkVOVdz?*UHEJdpS5vEpv^$k>s9e`P#niE=kke$`@3>?;6A=nZ;wE`QzA17_ zR}I`;`63DjkV`e;Zlf$Aue0c!BJ&bx%5}i+e5A01aH2Hipcc#NTpUmdB95a{(f>RssvE*g*xduN_N7N{Y#+xPruZ9wzibWO2xVrmMJk(jk(BQBeaB(p)KIxQl|N z2PYm8{Z6B{qf2alThwVvp@qT27UD$_8yK#uS$=27(uldW&6d(Bmo77rmqZ4bqNOP? zjmkopMJ8J)tB4BIS+a!ejn!;atS}oc_?k(f;wW3sa1RKPu9)h@#Wp28kD?w)Se&4R z-t!WM`iDC@`Z7*Y?g~*M4O&)+7@+uOkn&WG6+M5c`G3mG$mL_g>*6d@EnfbD`GP9) zGB;A=OtP-DSBSC1YAaExK##I39%fSJ-{(+pCrl%FNLB9E0*w`pML*nbiAXhZ#fPgR zOt)3k#y~c*>5rK6lC8+DDpp@I(!9NW3V=a8kaEd;V->2tAfqsq9#BdKuDrpQ(-Pt> zC9dm<%wjiT1gE%($dMIr7$K0oo4T^)nj7%SZjx{VND}e(DSw$|L~89I`JAs3%ZXJs zyvu*yZd}-RWf-m%1W#sm5|f8A>9TDy5@mR}S%(gilBs-*(Q9LtG$JD9>h4n9hQq|d z-gHc%b}te$JTV@8z@&ePYCnH5Zeo;l^2=E{p5S3F=6B)}pq3NY2i?lGO0bE{K#Wwe z2Y2kZ`}$*ygRj%MNO3H*Ml(7Gwir;Vrg1G}%o5j~`QjE;3y)ADul>wbRgmljq2zb>l?bTB7u?xvV&H3Sx5ma2G{vb1P*ahV~)W+;a8Ekw;q5z??q2_pD5^)`6 zrLyYUn-~%@0`?>+>5awN;kC+`C3q0I%~dYv*7S;%NF* zU6ivJmN6A7n(jGQnaey(0$)g;`;L7AsfrH89;46F%|vDM33juPN}%&EG4y(ZEadOF z3VEu6(r`h#x~L^=cAVb%_(aeZ^H#;FM{b5(Sx0fSo?MuoGxWPWwyG22$IBiMMscH%(BUAam|H~Z<)HkP)Vn4Kk64= z1+z|nnPojg+zP=f#t)gVqY&;84&%`B zp$Szecez|yaqf<-{lv=@Ys8}!+SsT;1S{rR@EhhZ;2bF3#1~^If;q&e#&kU#OIk?w zIzbQ@L)UQF3)-zVHV?Em2csTp{$dXg%%H=*d?UET{!%4nmn^o0w>)as_Vo;;&V-0$Mg^)OZ2ekFm}7IhA{({6d~tPx_{&Ux~P7QHc2Z>bF#>OutJWncD5E@6Z>RHVNmK`~pvnQLB1C>CFLYE=D z$aoKku7}J7bx{>=aH;AX+uXoajB+*pAQNbvOEn7s->br-U420TX?Tsf(&y$=>lY7b zsG?S*q3~W%SN<+iwpB4*UYJ5?fPmNlm3o_aGKZAoXuK7u7HaTQ{wH9|Ok`=Eh%T&MeEIvw8%h8bWJX$LcH~8!pWVX`P;mCZM#bUxQHM`xk)g86oG@8uQofiQ;w!Yhlv%S&3i25E zA*DsT08D@aed63TWkeNi<%CcNL(~bSd^g0x!+EihGP$V5J|SkW62QcYSf-c~(kYP? zsMzeK%#Wx`1KIQ!OnI^{#PRHy^)?2T$1}||$Lbd%6d1QIo?uZpjM>Ot$1es6UQaRL zIFxoSpN4klxj+FhNKpeqxN70baQw>2qO5n^DvI<3ZI_-UUq3|ll#c%Z@N8_uxRLmE zMFLgT`JILiL36%(@lY@PoWZ5Qt#K<&@Xp0bly1_96Lf5X~|=p`@X!+0*+aO5>^Qaz9mb7yJo-Y16w&I>=W`TEm*I2 z5a@+=LndB0%R$>`%YNP6le*^Wi7fxB~CVXWI?bB zl*(sQm_A{XaN&i^d-!7CfdbAVLtOPZrQd{OM|{DeQo%5&r;z{^&oGVspqWJwLrR+{ z2gENWdY&t<-|8=p3U{)#=`Bi&Fc3$W*+c&T!LqKg`@kGybVgMtN-qBZh-ib%7JPrB z0(>+T4B_r-m=$?~)o~wgq8=8dda@O<1+GKy8d$=*y5H0w0B?))6)9JW!n&GsL;TIr zUR3@fL%RDTqjpMZ)7B}rh)P*U@<8~*9N6bUT|gARHsv%=v@vS@AKbtfRd>|7Q&9^l ztNlwMJg$Ah*jC4!ujz(CY@MtWzGJ5J#21z@7U7>n?j9vewAH1@h?ZX&3mI+4pL3Ry zmg|VvjYBKUK$ciD+!Br}%tfcMjBiO}5xTdTNjGRp(Uu%@m?$PVB0)Qrs}5j!oUT}$ zY^o*Hu;i}%Obfk;ekE*7yN8I~Q>egs8DjZ!Idz^1&i5)N1;HV$m^@rnyMbLr`4L6X zo;!m}*Ql*FK`^%w+_d<^%oNNU3gTVV09yfvncFZ3#b6yni2Xbm*z*xi9T z5Vd}K`#?)~u?G>81bmx0@G7rk)8cu(qkMY0=?LYbap&c(3v1DJNt z3S&SMW2|98k>;hHz`P=^vjQotmu*CBPzKIkGZs4%+Qg@1AxO0<+B<>0BB5syl@<4a z5rS0&dPO;c=3dLnm&E6vbCy%grsmE;671u|Y@{28iAur%E^ZYAYOWaxa6vhIN;dTa zlv+|>O*}B@ZAx2B%ULa|T$mPIBVgNeQ;2;T%6qtKokNy3Z6-(^E>WQ2{-N0)^fOjX z5FDQ4Lz6FK<_5HJ73~nbT}_UZDFW9KO=M_%9KbGKGcp47+VZ(U0M#w{mndDuakrGK znZ*jrzDb1vaBN5ltU|FZl*N`W7&YOEmA4--k5R*YQdFt2d*)88xzv0A0CLIfS>X`2 zg8pfL%(B9u-zMdWY@sy#%lU^Qq5lAx7H>5F08x4po1G93GP`Mq4{@M}5JDOUHd2eh z%xGdW<}1SvAg!XIT$3@+5!5!)^!q|kl!`F2Mb}YMggS2$_9?MV)N)&POKE3;^cu*$ z$7S3T@eZVUNk#!=HgKad(&JrmDCCUa)dT{jUx}tt>1QExD1q?=Hf9Q4m)!fxwzGiF zT7iS-ApOl{)E5-Bnl6%2HWqD<4n}C>C|l4hA56UZv4*@>ip1hp6zIeA7($jVQmIn? zP`RP#k18dkx{TnqwgLoBk}&we_6vdv5O_TO;ouj~$q*ij>l)FFNqO2&%zI@ip%yC2 z1Bsp*>NN*N1zuCR6^wZ1Mo=_Csh0`8#(xqzm_h^7eMfT=&P34-zAa*e+u`OO;Y9>J0=upV!bwf8!@BBYOnM+>wWjhW z*FerjS$^a~JQ8Z`AQj?6k|3`rmL52Y7uEU}UZLX-P}TncGvJdQP@2bR*~?TjnyAvF z8B#W=xDgH`Oy(oKiG=Qfb#SEvzzY@ml`^R+x%iqi0gK{TfN0OcDL2!^T}T}0sDYh4 z+)akL)KLKBA5ySb@=Fd`VEL4k(rWxM8r`gZBW58n_qg0mgEfB;H@valV zj~5WRMf%Oy_FM-*ACj!2FnDvWE&)K=ti|v6LSD7WIatM1^(`_jmGrxob1qz@n;sTW zrC2sS!L|v9jWVdP+sN&9NlNJKRW-aR`Zl2kE@a0t`-@~DRit>RF^Gl2=LUTWvnpyH z3?aNcbsUNEG3{4mu+l^-@=O>DvmnD`F6jD!ufvk8asW9P!n%V;L>5`ZTSkDvCCl?K z7+oo+g~G-Pj&F&AI(=Zvix$PNsJdmtJinMB7CM$%@|THc`XCUb4@PZFl*PO;^EKz{ zvTFxJ-eB%cPi~=pl(&1002SUP+A6JO6f}jnV~txyj_2paqfIzU*aIMzo#yJOp`^yHtAn$;3;d%Zb zfpODP;bd8qC4I|r^}bPVKMxF9J-9Uc{{S+hnH8hQ_CyI0yDqN2?Bq^tw+}MB!Cg*L z)aVf5C_~Y|q8zSG7>sAhvCSSGyDNx`O5CJ{V`Y9|u$|cJaH=+uQ?07i+X0gPC12$C zDX0O@64nCWwaQ1OCr`xY$WMBIf>@|*+F=Hz748&OK)YL&+_XO0%T+KnqL@hsNI5l- zXz9~{GX5DsLELg?{{SQu2#>P!jPUGqxlT#eP5{W1_?(lFj}dQshdTr`MQ#$ytjEL@ z?6So}h?>3?v9NCvfKzZ_JflE8O(uox>L8H)rI*CHNlzriLXy_P3B)Ui7s^p9l;dVF zDgu5;juR!O$ycOsLZLLPC9H78m5&|?02N`R5qb88uyfqH=a{67Jeq(|OEBI~0vfV4 z*fOQhlkRdu?z@7M2N0CC?ku@*P?tP`vIu;c_KnxdjaybdpM(C>lhR+L&XE+tS6)bh zz?J5u5^OP+adKPnmlg=CtPOA${<1Y@qE!b6$vi^m1pXl~(w;s2r9?}bWr+poi2!c0 zY^Em0Uk&R82IYwqx}(Vofey9^MquICo6S;mB4MFDhgblBMh+%m~#>77Uc-#3Cy~g|e{6456(& z#fYpSM5X-$xUVr!5M-@yGe^WQhDEu|G+jO?p%(!{@f1R*P;yzafo!!7SehN)GEpwI zlm$l+87>ac(+CS^GW>X6ssee(nM5o}!ygQy1ycS8mxv0q`Ha)Rs7C2Hb6^Un3Oe&E zU=h2v1<^YRIWSKV@v%dv&=!&Vg9k1*{X~jbA53&88nFP{?|*q27aBg|2lA*EtRsoa zx&Ee$psN$p5V1h$JaGs>?msYY?f(D{8l#dPVP*q#;v&y42uK%VxYq9cLLs18Fh}h5 z3aEyhyJ5M9f!CN&mfTP@1vT8a5wqeRCTkP25u#gVZXIeMFlYf;>g$Ekq(%;6}|I6A7~pNS8SyK#)r~ ze9J>FTJ3_$7k1}i1<@m`7S5DvUi=nbfRsZC_z(90KB|4SqkQEyEkAKs%%JIV;S0m$42qF{q&^VH&HOS5WYQl|1js z1SwDpo|7Uow=+wg^2v9QR+Sm330yN`67Vi498Osmx!mR?9D<7gG~h&1S%Ki38<&I- zUlM>)O#V?09bZ`f+|(2| zVu56Av_aGms@OG;5FxM>PruP#qG}g)7tz+?Npgx~zyVXGKkf`_ zXBp^y$A)ecvH)|(H2X@B2?Vp-7)PE8C0)ylWFM$gMIVqrgU(AEaXu6ML8(TSRv6l9 z#NYQ2SEZx!M0n;RuIuj(>@OvJ-%)%nvIFlls_m?P%#A?!j|Vp){K4HzltR=~eA@}L zy;iVgO<4d@Zwd>E?Rufvc8@->a#d~~S!RWPKju^odA%gi=9AOX%TAJpN3Y|HW8I{#T3ig>6|f)t@;BggVbE&0=dMh`^!3Y^d}_2yhX{F z!$dLw2@?2CVK6=9I=Lf3ica7?)sQ$LQ`}u_yJzBHKq|-_zl&d(z)dc;E+Ge~d@&Ly zH7IldCDRH&Ec9T7epOPFnNV%MJC_}cPRNOLj|@urPxGKBweDpVpiclSdgWEurJY zJBtC+u_ZOqHC$Uq{o(?r!J)tp3$GI8io{f7;SpLhID))6AQI(3p@MP86CFLUhQvt4 z4tB!kY!S(QMF?RrAn9dWtc<7@1SfzZ6i|sXpHOI06|Ns1r#R=jj3~=PfY=mlUq_$m zEmQ7oY^JU?0KLRLoBCAl861}J09rt>`9v9_6nSmL3}Dl*qR?Lx!Su@dIrIpK{Q?hD zFNlI2yOajM5hL>{x`zpqE1iO)-3Xkh|ZOjg%6(Ku(w%#L{ zr**J140Eo<%Qmg>_u?S-#VXX@w>E3Q-6Jn#j<2^M1EnvFfX1vh#uV! zgQ)WW3Shevxl;BV+;p2Tj}Wh=z*GX+!`Td)YU<}XYV2%O>JKfN;V4+5ZXAE8F+dk& z4o8vnX$+X)V%~f(T%TybsL-*Uh7*AC5rZ(4o+Y#5480fJ6y4Og(Mx|&5puw2za2ts zNCBbDxG*>7zJVTNaONtInC(6?JGTgbILJ-HH->9~qfwk4PY8y$N}|pnGbu~u8+V`3 z-F@Oy;2zg=*|0@cab1ut1G5)$t_#b55s451+qe5jt3`c7$N@)Vv*Ii7?;fS;m)D2|vxnh~6&j~exoBfC z&LHi}xyu&RWfcrA45L2rgTZwY1jL$dG_>NJj8+h{*#Ta1yF}97xA8U69LC_P?k!rv z{6IL|K2x)N+y>jaAuv;1c9`v^sEU`35en`qfW|Q5^7cD9G<7_Qb;hjai|~y zrv|2rM5o zg~eZ8KcZX8TLzrRA^}vYZc1}QiLd%YS9-+#;CQFPK?=TV-<6M&b7ymk^(wJ9s74`& z06r;zy+G!=Uzx`t^C`>+N;PWYg`JF{IUCr3qIh31672%h!W|Hyp+VI$r9j$wn4F4l17U5v#clC4{T8Pv zYDyI}66k#Y00;rT-{T6YwU%929O={o6}3E_e^C(}kQVn8UUL>GTFV#4DJi@>sTHOW zdatxvEeL#b0QwHl&LJ(T)CLM++DBtb&`2Q>L^1)b?>40|6^;)`wO0Nebf)^T#0Cn@m}RICTM;eXtS_uLggIf=I|T*a`?CAVT2 z%pTxAv;$n%b7KMepWI43E?)dhx(d5+{{Rz=k7!&Q32~mjfU?+|JDo#rmA4RCux?r4 zi4x8uYvNm16Q5iTShAsX-OS>v++?!{(Fnq%@<0@+Q(#0BiGgj^l`pI`UZa7v$aM~q z%M*lGVkVncN2x^N0V}o$4oLJJOk3rJe7DWQz*M$nC)d*{zYxk@7Z)O7Eu<3ZVzP1l z{{RRtbuIm7!)rT!AX@WacUvvA3Xc%(co(rgqY?qrh%vr?hV&kR!{%_ONBlIR@w$SO zJW}w2C!U~|o8qOc zb;B`=Jd%!QiB#hUU9T|;1A&xlhcqTYT1gpol)ed;vp^~KsY;GGKOElg6z z6@*%HDulXSk8+bJK4LX5oJ*&l@Plh-LGS6;{{RfAHg@acT#H^`Fn26q-3997+C%6? zy@c=S+%i6AR~dT{yn@wmUqHgxP6Xj3Oji(xas4t12{^Aup1fC^5(86X*9V+{trJ*$W2NJnfUo(kQE-q9Tmpg^LxRf#O z3nRcP9?mWzKvU~b`cpWUWltywP!*YSws%laxl4gXmau{+Q?zj?q?IU3)LTA)T3l!= zB3^fpQY=j?h{%M#Bw=RF3mc# zknM-Rst(T&Z!rtN;~kWc>N3ndA)&qV{mdouOW7M~@v+(a{{SQuyxBLafvSiPo0jP- z@i*h3aq!NVId)4sA$7obi$c7XFS+vcUnK~<2(ng|{^yRT-v^b^R+y!7N-eAhSL=;*n*PiDm1Xfq#4Ky4RaAKyq9)o$0 z*wA(U2oS;GD@n=`QBL9)yPxVIna3J&64y2&taxCib@X)$d?dP;G%SDsyCY?y4N`L! z!x@)8K8Gep3xe#t*m{>TqgfKRF6Rx8q*ZCmaf@DV8o#3Cf>Svm&Ou@dZTA-eN2hRH zd6iPL$M?fs+#fGDFqCrqOg%#F?kz?-Q94{KB2@+jl7JzV` z4@?t@xUD=gDx4R=^spKh2b#DM7L{bDjF;xVjzmHo*AQ3`2hCJD5Zf_DA7o zYzvOfl{OGWs$yz6RTN6bI3FT-SJBH%2JHAXf_nlK4OxRy-FBBFbtU|o$Q1vE6i5CR3}voN{<3TP0lKc zEO8MZMg_MrWf=u~X_i;7_CSis+>eZVw;p2Z61?i5ClK5=K+F|EuyXj40hLKce9m^i#1N%7WHVIT&8jK77-FQ{2;3&;m^5v_q&0qsOQ@JB?##na*eH))k` zhEYLiI`tLQw+q9}Hdf$OF!KgnEM-s7~!P{L6V~ zFiIsA*T~1NUlSO7q7oOV64W#JvfR4P3CyXg&1?9XA4n*g z0HvM~1L0#m%Ab!i!UNp=MED9r2}Gc-3&IAuxEn!m)yk+NGm?V6T&UQv9%8!TmmYVB zT|;%gql`k;yh5O}#=%6h@*m;@RpZdi;Bto&=?PDn%w@6W1J)7tr~>X6-fG?=f{QUL zGGDNQSxTMlX$tK^r#Opnv~voWf;73MHyB~f3xloE3RP&s6b?8a`pOkD(ZsOX`Vl)v z%1VnxXA^sjR;lEa`3YO9;v<3d@fOHZ?@4{nwQS^R0R51F3E$!nLnK#-D#R^sk(?W? zG67zd4xt5AzSsr|i0jOwd|7uru?v@TW9*cJw!xGT4m2-~jn}EjxUpF|Jj{gNIdCCD z?Y5nNMO_hBNR~6rIe`@^)k=9ltNX<0DCq;yg=NQb6IQM95#A=>GLRocR8vmxm?7G$ zJR%|vaV_5pxEoA#6Nz<)FLmanR-DLf15L~K8UT>bTRCSX7CvIdv)x$(MR)L&qi+{q zxLYm0?CP0tJb_LkHL!QeS`E!iBa(`Aag1Z5Ufy9`kjI}g;{?EQ5<@IDFz=gRc>CEL z`}vI{khY?}tUf9w70LY~T9&B%N<8d!&MGx|K&`3G{z%j$YK1S_J2gBcmN1quEvRYd zfnz8M_?0C~zY#0F%S-F>billD2Od1j7Wtf`b*LRF5SMGUDKEfszG4Gz4f`S>TZqww zLwe!AdCu)75`XMP52t810NA-DJfE1LG9u=O9}^)w-PZ_)a6nU2m?BR#sk7)ixoGza zr1uo=b^#|<&vNbAu2l0#yyPJF8kJ53=VAychADe2cW~|pKE;mgWzMwsEb9uvzGE6S#bl2fnw^vn60kn8ikf1$d$!JdzQ<- z=LD^hU(SCJ-Y+TnjbR9M6(8{-*5RG*>Ld~rODZOOvq5ML6{JnTomoN{Rz6`{8~i2^ z##utvZU7lw-yBL2c*XM-sag42fxFI&Ugh0DGj&qktwM@-_^ISlt+zQmQ;$DV~q^b%)Zc87;aPbguc}V;r z6z{1~V7f`vl#^Z1wdf^29=(XPuMjUB%O06uay70XcARO`3Nd`3#<5=cfEK9P2S>xK zUjF4X18W)l&J0B(nkJ|Q3ycU>j2{y{#a|_5z)@*>GAi5n5a{dDK(qk6DgY@F^({xJ zQ&`)$$&;z}N z2!zj=u<)0$%a^qbq!kt%%2116f7CSn{{Wdw1=IS1TH9>3qd-GTgQ1ox^QpYzrAXuN z00kbaD;dFBD)^{2tAtRSDZC+Y2jEAD3^Wg*Luz40>e)p^LtRvAJd2jI^$vj0ZN;@1 z5zPjV@RZ>-JSw>ufWYJeQk!%bjet_>tp`f+5!nTfP9xSlL|ZD!cHR%_EgU0jNc(%v zL_DpO9vG3|#=&Cg!vWQjhd7P9Rr_SRN1IMi)C%nNaeJE$=HM(Lt|+~I%nCaLmscwA zE*=3t%Po-ZUkql58?rygDLFDakg7O_KL9>15{0~Lt6$j*vekHDLK5AT=4as#n5#-%uSL%yyFjhL{{V5u3onXlzlLAD2sF+j zFBSrx7o-%tH{P*Vi-K}&c9`Mev7tG#B9#*#s>-wI*cP5*3Ud>}tq$da0djC|M2$Is zUl6XT*@4UUMO$48hW=I+d2;FHx57SQ#RN+`=Bg~?s+9Jx)CCx!_aRl-2EeYuV;ayB z%%c$Y*MuWvE{R6MXfZ-{i1~s=(U)pCxs3LUhE%Ndi{Y|95 z!|@0!!vb4N-{do=aM$8k?-2%=(UyCK28S}N3!AZVHzLO4p?Iy}qhvqyjb zv(EXS^SsaVu6M0>T;g(OnESr>z4x`h*XR0P6YySE4Cl_{J18h9I1=I_@+c^%2o#iC zHn%asGY+>taf5#_b*02aP;QWa(i(H3z%$rZ;wlgn6y|5hzqcH+gzdnSSYIS$M6s4I z2=5Ux(H&k}p`biLkq~+P(P46H#@S`?=;mgBiVF&R1nnOuYkD9w(4%wP_q~mfG_`_c zIvTxbYUK6gx`F~Xc$GG8pkX@!hX40#Z~UzR+2Eb8@6ghJ2mUvTv^(7cdzR9&bNB2G&opiuR9-arR#NusyDj{+D`VwFeLEVnrvM3#<9REjA6f( zf*vxh{mQ_~S1godf~*ZaMMXoyzI}VXb~WXhkdRO(AGxqwQcKIL%d4yXlam~+X1B|; z)l@sna;0KTvzfY)qAT!}U^1WWkHNt(r=yLR#>3PP2ng6?YENdJ^WLYUa+;1VBR`CW zhQ{`~J&4$NvVzWZtf;?ax=5pbZ6rT##y~`burJ8p|LtQ=lb=bv5H=aD675@+CL=#4 zCe+y;GO7LyfBN<|9-bUiR8mqO_^n6W7G&&(ecF>1#$Pr^L(+ zs#a3*@Wj{D@O;Iiv?v#fHTYF&ssv7dqRy5GKT)k+K?xMQqgjajK|f*2>~f7 zbg5|&${p58;T*is=2vbsNb!(Gv#)y2t#>H>twOKMK{xHa#~l8zy)jGecQxO+e6_{{SDql#zjrZP*3^DgW`~ zhkTAkqtnR2!9khb_N0MItU(Al|ES6D+z3wX78KLvu86!9X7w8FTchi+9QFdpc!|y^ zIDx__S~=B$fq~IV(=o>0vI6s|DwP-pr7D%wwYAT8OTJ}fuuJd$%J8$@n{OqnHdcwX z?IgEX&Q~g~s!f)PV^-PO*%{52fwD;pyPj8!d=tIPz{NFM=dk~6Wnn?be7xi->>!!n zzN#abL=T)&dq;<=$4H(6ZNB@>b)G?$*@W(lbtk!99JrP^CotvEQ79=XDV)}x#xiRp z@|n-n*?ufkjj7+MyXygNh28F~%=TpEwyKe`@*_7lx6_LY7&xS++nIse`8w^a!xGN< z@wO>MMNUp`r*4xO{HOO|r8gij5LLTBk@Gh=aHshs0|!U+VtWuQ{jJ|U*wxk5*-D(& z3#B5m^z`(ay1L<7$f|TN9ywn$m|gnuTt)+AT$Z!aR#sM3QepFun%_R=$x}anUTQffMD^^MO5GPaFv^GP zFhBcQM?Z3YJFDd`{1o?VN9d-Fjg2lWTc+V?R82ab)w8686**Z?_m|e^n%zUEDwIBc zBy4JG;_CJB^HZp`Sz%l~ySPA%X}KH3E0*et8V;uP`{O_RJXWL;+dHA~PK26vBY_w{ z;v*P$_z&N^Ta%SRVAdU6oy@U+9(qzASFBde974)X^W=#~00FJd>7I^@tE&oFX}gUl z6j*o^%NM)NtNF!E-|Tm1Mc%!eRM$E?SV`bAe=HV8v9jD9b&rJ22aH{rF)SO*2o^Bb z1IhexD-Fxb%fFrUmB#%2Zwm+tvdd7iYNLSZWbo4;f5Kuag^h};D%S|a9QoRsn)`%= zKO>(@#xWu? zvc3jK#3>wViIS^YNuMDWW;j)4e!16%hmMXuKAqjDT5Zt}Zs2&cyD-jU4)Nra@bFh) zwIhGy^Hden%a<>=#!I~o`x6b6g{Y~i6#``gZ>~?8f9ETO-65jauXlCs@%Psk69geL zvQ;lku!C63r4>ve_RR51f_^CXsvo7>6DlfHk4EQ{2Sh}ojZQ~p8px3x8hQ_IL^7Yq zvL_nW>3%1r0@~U1`yzGTcfpTZ!8+r0JfPP88s>7j-d7?a92f;ae6%KUC86#xgWg2;+(89 zhcaxMjTMn+ybJlJ)Akh%!QRkYyi)B})P}~!a*d9;xm2*K4|eKz7Z(;@gPHSr=^T~>Ix2yAy`HDD}mX-sl!gAu`w`FBzQKS>te32n5l$?KYb5kmT z%|N-yg%`xQO2@ZW&2CpV4HIL?TdHDR#@H**?(g4K7#<%luCGrG)@9z(=+rYdwn!fz zbPyb^ZEgF@&!0bkj!!`m8W%?lLWWALgsd!$fB>1jy?sv{OEKQ3KVe$@7XdMG=T{uk zvZU3;#W&zEcb2O}L@b`qpfFHTRg22YKXAXfvL7YR(QUu8_2-o%WOVoUCwyObOYuK8 ztSI9$%MCg1+u zC1lRVTng8_hzNXgczUhceLR%Dk|SLqtw@(p+ng?9G1925A$UH`E1X< zv(>$>XYk$hw>k@NhQbD^;H*vnJov0K6DCwQChct zwCQx+Kb=Q=aoj959VTodLW)mU@#hqM#grfYE-@S|4ljMkxPsgzsn$r4a zFz~@&oq-Yh2_c(3{IIuMBIGI6A60QD(X_52z~2kJ8$3R+f~y6Oe-j-4^Q(XMa&Wu< zuU_p|dCBQ1E@XGcR$;7nZD)h3q?D_Olj8PxvWgQ%K#=|^zaTDEh+MU*&ygIZ(Ww-Ub&^N-ZDl^;YxUZ*xevVOZ(!}9kBgqx)L=s48sex@GKiKns0DddR~tev076( zI2jhK9&hg*PnAG&RNP_Nh8q1){!z{D?xAlO1uAIQ*T%4Fb8qfBpYZUcseIRqijy!Q zlgZ7cFvtme?JC8^)O#>(TN}i0#U$OUw`&a~n%~AzD*h2lzSn|QVn*_16LYK>$`(ZI zovPKbvN=+2Nse-H^481@eh`bHqjR4S-NM4^=F0F|N$d4WkKshQk9U8Djm%ON)JToTl(uqewR494^8?H%{;>yt8DxIZ&#aL7SNL!Bh;ypd>K|enyw;E!NP`e$YdR}23zB0ZyeM-OS$59 z-51X>EwCNFY(4SEhwpY$$}ybuFu;S_W0^uR5TRW~jq;4j+8c?{=#;MdZoFNEgVZa% zUkj1PFZH&8i{AO>iMG&%&*RExKIwZmo0#{i_m}PXgNL!TalE4Pk?Xz|zq=ana5&d# z*U`=h-})tTJYsExMMQw5n$Rngiu+7#R{erZ;I{Kgc4H`cuX=}~^K)7#3k4cxe9D3E zUG|gX)ng+YJ<>oBcVB}Y0V5(T?2MalGSdkK9X)<}^Uw?lz;7>*5X#fRJmnrY$!0<^D zYB%q(U4idB8lgE;2haXQObmgT`Qg6LmR4mwKN`!<5#k`!bZA}f9Lv>#$FNv>-4uXa zU9CO(Y+zP7)=3GyqTuRlu($ET z6Rsfdo9i>u&Bp;50a$>9@^fycPB2$ji0n;?5xENXogN;lzL17SnO$e?G?KB8zTY-j`#IT=@`&ZNX_XNf7gwl!nO*{o!mhT*IjhA;W z=f%;-*qbM6IJ+JvoT0Lr#djxAvbNm&a5nFqZ7;+vOrU1|f{IEP3q)x`bUMMx=TeC& z3ldTD0kmwf62b+#f!0gIs7B7C`*M8=dh!r>zc+0vh?vrCw`%4>eB>j zbt_*#&n%ONf8%Ln^A)LsV9+{)hnoq-KTo-jU|#nLoT(qNZ((274Q&~YSMxjSU#UeG zDQl+I`lIw9MdKS6PN@c`gmFE5UqkMjS?B1kxiE#dKzbmP$A~w2k639C%aW<_!9>I?^DtLSNp~v@$`SYZ~WUQ|Fh?GZ7WL40O@CQA)U+@ zv$tmjH2{JSr=`YpF3M`__U{{E&Ln>n?ZZEx(6!EmNC2|JuL zGKvZF-fejK;4wa>JBCM14a4R6rj~T#p&*KcM7NJ`yS~b?@XbWWjJ=ZKY=Z?#fu^fC zW&Gd$xLZcc#X8)N(&AN~d=Uyrwmd6MvF4Z2*^TVr3x1nMFK&Jk*q1|$c;;N~1#DFn z4fOPi-)Bjxpfof{?r#>m=aq{78EbKiI=gMY_CSNC3Vwe654AQ4(y-*D`6xN3gCBS2 zY>v&|R2hhcm<&`H3m^Pe*c`7r@{vFJ*RO64XVGkqQA)T{k~;fl%dFa5)x~VH5i!IX zo*!N~E(U~~^#a{rs{I=8`eM%S^JrffCJz1gQqcqK5TwMD7q76;@Ev+DT=zvq`eOH}&gwcRwU%R?kweeNbDqzN{Z4759Kn zt*Qo>Bf>?*mI;8258md!FZ*H^b{tQJr^!Pfd79wvPKgpMu% z%yjuiCtELX@1xfN%LJ0;;K1EtRTjSS@da8;g{izQP4cmbBF+9sU1(;L6#=u2&S*o$ zTEc+A^h!@j$;ujz7O0pw{FRoGsUl)xODiiFuRwkp5D?J)5f1QCXMcbHj;-6tj6H|> zWHdk%!;Q}NoMm0+*&L+!AcTDfdAWL%3yBAyR0?%p*2&`NG#hv%BqT_(pHox6Z>S-O zEpxp%2B+37_DAN*i*p(e`+#H`wFF%64j5aqxZ0&q{_#dpBS3kK>M8vDn`ic0~@kn`_MNP+!t6X{_0*Ik+yfnb7_7GR@3pq6slNVs-#`5Azs25voy`H!KkLqQznz#&z#$x) zfCgm`nLmI3NT;i(hmDOb!8Dey#IiAx-zmk?=mUk4#u_ZFth7Tdn)BJL`182(RGiGLH zM&%L@qg2<}oK&|&fb2dLD8KB9rt>Z?W+COaSe|v>&2qcyLmP`@(MkbaG7tYxlp-{* zxATn(50BQF{3hD`QoqaOM;i-@w#raOCmTqHCB(bheivm}Og(+^mfJuq~(ZQ~QnIbjX1w zx1aU|nL1*1P%hd2Xya2Nhw(w!XtVhg*W%I=_T9UB7suOqu#@d6v5?1{fSsvtQ~>M& z){R|9D7n-`nL(aXaf;BBKkGD7^Zk20yIl&|?Mcl%nA_D6%Vb4fPfqGimitYNbV6B7 zt2gQ5#&_5k9d7GI5x~zn0RvH~wjc*&61m)K%XUE6V6#~k7dl^i2JeS&%4fTwU%v%bxZ}lkH2{pme$ffe($d}@aED0prM(3=3ZGqpXZ6Vx z;M%qK1W)BpLGbYfs0e`YTS)e$<#zTQ@a=E<-H{|cJJ#Q&4dk>WCu(=VTrzOD*#$cH zXm?QPg0Zc^kHX0x{C#oc+8#*6YrW_r^d!PX7Rjk<%~pDZPeK0q`vmMP78cB0ae0b` zWCpzt4v20yr%c|JgfM7Z7@k0fEv1H%j23>lsOp+sXk;Qm=FF zuRlaXT$9)8Ng$r^bbvuCyuZ`h#_Rhhb1ZF*y5Gxyd6wyk@t~xq=hQfHCUk_jj->gj zBjEkKR`V!mSh#(xjbQn0O_ciqw3QbjLam03@!bY;f+NwPuPbuadgj@rk#5yaJihO(MZa&U(K5uvrV zo(cRHCt>r&%>zpdAH3KM%5axyW$L)wE_P;2VTEeu14+Dc?SWYk>HdH4LL^pFQp;TP zmJE{;kQt>AH zr;3!s3wZ#p^yb99#8~0FaL)JcP)(^&j#pP3FMdzl$G3l|MMT5m#vM+R<+=0r&P{fD zdQi?F;kRSVkxl*vsC~m399mOT!wP^svu4BXS2i|mQn8G!Fc^UcfT~Em4J2nFCLtZl zA08zy-k&O*YBKU2xuJs{rsFT`rh59+6B!fSuU$}4QI)}dyTJxFyPOXh?@R>#Zk;y# zM;jwSpd5iVzrHT<<_+q_$!;eM79}Tq6%F>MD8Smm9<30k(&)qqsu)U30e?m&Vk%EQ zOA_oqUxlwvy@?nU_W*f?9B-)Y$2+l05}GJ!EyjdTab8{ipAMTKheg z%k=oe+{B+&IiFahxSbovGO4{=AI>5HkQfc~9!kr^M1t++=u2?vip82TfFlCxtC$f$ z_~egXrpp8%vI8b3+z-N2-hOj^*_`{0Ytz-S8j5U+fJ6-ar?s(S%FWTjB>-sCz`;#; zB2Yz;%Y(}I_hxaktcVEuOuappHh|H{x(>41qTl^sAVm;aAfQvoz6Z2;Hh`;y4B11k z{@(CuySon=yKK&ZcIiTn=W+*&N|^`_jXcU9xR>c~ZDTVmQ}plTibwj-+^SYke&paZ zsdatn=pWKwtFBA+u^{)Dh;I2edn%M!>ua_QOp{6VRTxEy$)}De({r}|#Mkw9tWF$B z{BepF7j|n?#NU1&{LuW)ys;B_NIMQfd#YdAmh z7QU%)cfaLy)2eDfY4R>6 zD@k&8Ck-~3s3PO8Pti<9Ia(V8i%rMUY)vnE&d+}gXPM|lya7R`mX3D<-IGDlqncYe zcHJ8L4k|bI+9*zu7Pmpuc@O$JiqYVYG`Y@56;k7iv6=s!v3cQ!bdSW^CMpQvu!QhxYl`wpH!_`_iLJno$9a6s|$ zUPv(Ny8wlvR~q?>@VoC6r^=txVB%8v487kwV1pSB_~>=c{|u;btuS(jM24g2b+jaM z((qvI?Z4C_JU`~tl8%frA6wm0fdvU01}A`WW;S`YjQ4}*W|qy?dWd$NGaK^e$W~BM z<+WM9z0?`TQf6LaI>tQff{>9-6_NpEhjDkqE&%@;wcJZ1oQCE6a z)Kjl6K=Gi$z}2;%50rU&xSqDP9QwM2&|Bujz- zq+yWzvjqv*T&}J%0J3FDJm-aUOqWDo8~r9>@52VfYavRGttdx<7N(Z`z>HB16XZfg z3U*WF?cLp%TT|aKq~ohpp0r8zMTEwxpe2x z;$~3KftK18s@Sy$R%l6yf(SD0Q)ep^PI6!SU>1*ZfGpSTigPb7UhH39fUQ~c1M1%B zmw8V)P2wrm#>ayN+4uKp`t_%{PWRe^H?3_sxs!|3vGMWmljGo!8X_;ISK{n|MrLL0 z1A=`o{3$$VUIt1wHJ1b!wEJ5Nn=)7A(rD((jElehTxwFu?-p8`xf;QcR0J`ow(ZQ+ z=YiZW!otsaw=oXX$g-Pm)^k!{eELopqp;H&F|Cjn$s5jRtR;0sD zhtjh<$@@wo!h|in_Gx5nisZnr##cvw`23KW1EydRTj^I_-K}x8_KZA^Y8|P6oOf#d zKyGpHlRz%_^}%pPSRzE{WCuQ`s1_O3zh*S@Jt0~eN#?4%lX&6qF-L^kMcg-sh?laLETX-l(sze#)G?&_QmTo z>HjXaWR{+trI{0?{&~3(uHY&l(6@$@%-=R+55@Pipn0)7#g*m4M?X{h812Xtl{&XA_(AMl zVl**0iJa89$jCmNMorBG%g>cLLSsb<7g+R4n8d{7Zx6zx6FCAvfzr?@W--<`{62ve zxloe(37yca3o$O<;HiIL0U5ttFpW%N$>(2GeD*s@e2otKi#)u%EA_5HICobY6TMIE z7vCjm+;y-bCD5}t-JPBJB0IfSKG?^SD14LjQt*RFAfao>;I50yf!&q0b&1Z~QG~j> zGz;e?LdkVNofv0YfU#Jkkd1- z4yNW94W^J}?}B^Q5kk7z)+?2g0-w@(<#A@fbyY5AxBE3Gg>BvE&N4{er0`>-(cN#7 zUEiw@RYhr4G5B_5N<f)pyM!LJvS4p|w)Z3}B*dOKwtQToWkyeiM_Xkg&ucpEuLX&tR4Hbq6zjHu? z=je5I)T87PYZ){+)+6+YOeK7}VKP40_W7Pvk!FMRewowvB!5B+W~B$YRo2f}>SuO` zY)0I?N3n0P#x-|9{y&@*9QLk+ksvedkq)LwPtWN-jlbN@sqaq_g0#UDbNH0r6DhjN zQ!0n?X3MzHl*PjxR^}thXiMR0pK@zoghvt&{_!^Z;Nc#EeGvD<6BepaOoZPXx5a~6 z1Q6VrLk#xoWR)kDUl~F%{9*>*Xi){OyiT+(#*^czvi=`6^&>UG$+){;-9qT}C%5{#{ z#yTA@|F+hSa-s}f8a=BrC1QJF$HHQR7+=EuS_zn_rk!5DRtY;${pKSPFfgDOmcXWh zfk4Cht|9t|uZpK^P7-OlO-%2pevif;nwjo{z-FBoE>=>UdV+H|HcVpaKJ^sn9V~BI zCKBOC{E*T^1o%(WC}h9VequJMZ}Ao9w#V_dIZIR|-_;?k#5Ny$ZMT_nV?@C@@GpN? z`>xptz57$Gih~7IS||S`0skkk^Dofy4?p}T!vSf4=-5i{P=)bizUbYxUub|qF+|13 zmr9o#!b!F=#M){h#w%5peoe0FPPVz~Bz5+FTJADX_njmap%*V8f=#DC`Y!gxE~?{_ zmpc2O(O+Hl=W7X{BIGVkh|`o<5V?|STQjMoUjTVDF$M+6VnxTxt4zGW}uYG!| z>TACFF5Zbz+j&I|G!PMOj0W_Rn#`ejVU4Sk(dU{CpX-5R$6K**e!*|SkJ6@Su06=G zw$hYccCNBlok1iJRmx`2_iijkY^AQRf%$~4%ABi_3IeVYTVHSB>l4ow#{y;3ay3wK zK8_!&o>Nua9E}~R%%>~2NH%bEP#*0|h_yW}G4SAI;?5;8z|1#G0FxN4J!d&J0+OY9>tJpwg6xg9gH%6+e z4R)_HwX|f9${BlAYlg~t;;IX3AxxWx#xOS^aBP46T#JuUueK{R82KL4y!nXO=(>L9 zR7=L9)wX38Vk0}|sb-B+!q_V*$<|BB8)=((TrRYxz+62@*8gJLfw(gz znVDN`<@2j!v;9M#`W?1SwI;G}-}(+YP19tPp>tYlWD}`L8^n+A6cr8CLf{5|xST5@ zW%mgP-o`O&IGir{sZ^Q}xnJ&Mu{0jaf4Cuv1DS7?`P4fbn=;(U=?2_s2U)vizVNs) zk3*pD8=YaAouOI%z4?&s7Ei0?+et#nkO^LhHo~y{hDucWCFg4jhxO+#KJ_HAo@}$z zu4GBE#~P2`Q&;bs196P3^|_SvSs+om!+u2>yJ0+=_Q4O>s<_<-dYj){hnns@^{RWb zuEcNNY)z#wfly{l&~Wq+=vHQsm$shn4*^+qVanos(wTCeRq%}APd%AW@wwEmU%wjm ze%wXJ#6;a&%LqG|G%Y4t=QDGF;Zv(H`!k*6F zQNJ>LvsmZE0y4~`fY}l3`Is|Jo!37EqgRrFloHR{8vZo{Pq?p!LP-e%8R?0+kFO)^ z^q=G_tNCLx!8^2aKf<48=NQ0fI*-RRk9WcZj~KLO)nAoAz}Im)7Ab$Wt+|cPd+;KiyejDJQ}LoA=@CAtmioQ-}KKn2EnI&yRhR`O`tM7Im)X z*I^Ax=HYE-O*1D73&KaY6|&<~HVy^h$7aQb{ac%l$nGKFt=x0*C!g{Y@$XlevuE4` zrnBbe&=Mo}tvszB@jLu>@tS#uZ{DQ6#Ujtwg@K9W0NjDRZkIeqn`11I=2ifue!WNX z05l9M)8S1^`360WYcx!Hx0HFB?!{Dl!E+pPekxAGalpujXX-0bd7 zRle!U_*2tyg$Q7C8Gu;iPlV~|12Z$J$)7kPV-+OD9;^)|u$p;oih%bt^DMJrc+Ne7 zjYWu}>2mneX>Zq^Uy<0-64-}e4*@4xiA`khoId2RqzEQAby5MvrQxh}GnJZMAw;>k zBKHX)gJB1ZN#(jfWpmT06c;@1d+I2fOAL%)C6F$|Rt@LfY(388$miFwV@D3%H z*_BOTgBwm1s-@eRliNpT0sL4B9Bsc(?B`s$0n~y23?L9KVglAtBsxMmgbUTGG1FwA zTw62sN?4Mb8fY!0o3Fq>WIDUGqhn*g*;gv9bS4`TIr}RlW9DO&`iK*0Q>+@8ug+Io z2uj4CF6yh)?pLZGNCRD*_BAz?S7(knA_D%E*8L`!`}GPj?+6Ph)n~5kSRC++njyV_ zAXUV}!X-<4<9o+!yu=g0C+mY{iRqacb7s;9s4PvN5!}a*ZpElr*zg<<0P?P0FoN4sTTsl5y#^o~Wa!LsbT3zE>DvD1=mPC7Nt5k3A>ID8emPs`}PVjigH`R>|Ev3S8 zcf2w9+vcm3WGLi99Xd9K3)F%9{PX9nbM8ivFN6#ZQ~2G_323CX`{G~z{P`1<4GfZ! zl5AW_Et}2XeX@nH=k-cR0PCUQm)7VHH)U)l(Gu8p5cU%R8k)q2yQ!{RmQ$G`0T0$X z)iuyQ3P)UuBCDLWU9%j}5Ylv0C4&4+rG^^po^n!*gDAQAyqvy9FYXRb;Y$=IHMn{w zR0a^_2vmx`LCbxP{hSOdCKYuiS}Nbf!I4MjA{MQc-}TyxXsBDbvCY?rZUXvkxP@xi z1?A*;?3p(mZ`~?!b%w7qGw&@&!J9hBywBqGLme=NGF7EFAU<0W4$QIRQV)Cch0@SK zO-pc9m-!GcC0Ne;GP!eY$nvAP7J1)F{N0*ZdEip>ovt)hKd-&DGRbBCxm4Khhf%M| z5QCph6=p|35PKfGO4g*0pHZW<4I7!Th0${j^+$srW5dEAYZUF93q}D`?t!7n^=qg1 zBi;;lw_^+@x}7zp;9?*u>new78K^`%+sMf^sT+96l%pWEiiLeL1$1HJ;*AbG3Haw_ zy$Q`17Kr!#rekcfEFXR}5kd(`Yf~9!P_Ty0BvBp@eG;K||HT7vXLW0hH4TcKJ6>v3 zl;h1#{RGQN2WfT^q^`U=Ki@HQDEEVj(%%+<$W<5Dg)yykM?^(SgDR(TIcD8>mu{Zg zn1El7VqryE6YwyJ?XKt95#iIBa1=!WOM-lT6$!(24-rE8i8EqMt;)w6t3Q{6uJPa> z5o!SlR$uQ23JMc`{D^O|e~Q`v&Dr;VV(i@*aV&3P*~Y~WnbO4Ylq=~ArFC^X{vYrt zqNa=Rf1so5BfSC^Y>h{o3$xDYZ!mII2vVGJb#;f~yOS7#&WU1bvhms}{?DksZF=af z>Z<|$Ws8Ht^IwtbOOS!OOJk5hZ>&M97lvpV6X;_=8uce?A+%t3 zGu-%{2Q1GrSl#{VSUb(atB^9mF;5{^i+;{0|1-v2tuvB(gBnbNW;*)H57#g;46i_0 z$1T}EsJwYwPp_X3I7HzCoEP-+{_D4!iGKX(llwX$A?ei~l>Xsa)VBvD*kJ;ZwbO^| ztTy@`#-5&V{WvO~@uX8Tz+1(9zIx@GcDxd5A4-Q)tLHxqCN*+JY8?j;kDE89H@3BY_l>x}>l8$!hpTLH7tj4F=GbkD%i-u#l&MN{Qz$l_)$z^@ zn1lJBm)GKE-xz{AGB9zl+irXWJIW(rH-XvNS9xORG%iY$3aa+s#jDzjo3ACIT;|9I5zx*dtdK3O13GE$EZ?jnHTguu zW=mlWW;6>PEW7nrhSdS}JrZ5FkeQ0^(#;g6l$43NaA=a*jg!+cFrf4k$Gz11LM9oJ zmU7l`pD;R>Kc3vu5*GB}(Pw#iP*k8zgZKAiyDYtfEuk9ot^yDE)(H|j85q&85 z94TaFE>7}+U0k?U&u@K2f(5X`3dc2|iQVUKv0v@fr++byQd24Y7K%f6AM_M~X$NWn zJBtCdDf4Z3!kNh0?p$-~1JQzv?Ke0=7&w)!#vK?RK_>!XFFbFL@kz{J9*Y;nw| zy_vMNX8VMt_*QExjm8SpvhU*ir+#sssj5~y;rRKPS#XJkYEW&r8@DK`D3FYN|HM8u zxD&T<*b#!p%?*>4fxfvo=FK4wAhg;@7{tTG`^sgmJA@tE=aNMl(=QTuJw%(CvMv^cBE`F}BBB6;G+~$XMGnv(XP~)75z)uw6ioPbm9X zqX0R!m^L4#F5DW)r}^|^CFawhD{$_P`Ov1YCQATu{Cu!KLC?Y|ksGfgl(UiXnOLIc zc9}u{8VaalX-1L~0d2hhFKx`L+e7HE^>S_e*QJkYc5p47$);ki2I)>MR*LKBWgjSa z2wYXCv%#(hBvw6t=#qTgq6Q>0=889 zXcp6tX5HuXF~@Dz!n?IER)`UE6;i}e!%0df@t_+k8CW;1;e90ZiUs~qC=~a;2HKZG z{BBw#2#gHck|_@e;T)U}2$HHV9-5eFsIuTR?pEQo{*fs|`~0=!9ryjk_vv2P2is@+ zEfGk!SN9y*IiJgU=aqUuvyYT@2n!<+xksB0+xOZt9N+pqL|o%svy|R>KV?|E4wHGG z{GjW`GRkA!R*r;qzWQb$4Sf4aj+!_R>Op zmXr~Bm$yVtH+{Ulo!z`Al$n`BpK@V}Osd=(qrubY=w*=qGU;PrZd>MhB*3%j(I|pF zHF)KC_(6dt=ybYh6(itpE6SOl(+Srg8ogp4`YPBt=IVF664=YNb`p%{J+b;^iY+V* z6Lj1Aif@tgBUy3a;}ERpR5sAQBy2RS9~~j^*Kviat#9!r+y)ZM*Jn_@?Z*_)d2(bvE%KbYL<`1xG@ZGPj>b;iw$RMA%%?}E1Pic8*HufzAnwQ$U%NJCPoU@CxLp`0ek+Z( z1vE4)$1dxSSKd`DK(VweVZ42p{q=V!>9l)u!p(>h%_}S(=Z7?MU!T6!p5bHP&M(#; zdJ@lrpDpXF+pc|Pvo_R^-Zea+wW$g4gR(SJC5L&> zik1^^JZZsDvTjHBdRyF+p$99pCTT_%CazdUj_2vt!r5guQ{fuF0j*#(Ew4S)Z z+S%ul<4P=l+%g!0pd&3_*xfCA9aJAPLG~_MBnXTRKLJ@lw)HWoR%ip)AMhNmy(-ND zYM1mLP`flJT8)$F2xRo8I3XMupxKkbP7@3Eu%GorcDf*X7-&wX%P`IlU&8*2qkt7S z3OdfmCsRPPqSf9LAP(c=61X5VWc--m;M;n37p8+;!@b7t%o<*+soYv-Kn$x{{GwVL z#?W-1sZf(WDpC;Z%q4t`oFKKYfj@5zGzD$+f<8(R$P$1}=wWS@xU6h8*wZRZMgr&O zwHFr`9|^hC;64!Z_4Q2E8bw4#YVYfQ2Hi7rm3OKBIt7x20CtsjrhN3-sa*jb3;LT( z&0-oUQLM%^43j|*(Z}e7Cc}_zkMYs#$w=7se-gFXnm3uVR2bn%Kd1$g?3r8@)3OQ) zr6A)V;1u^LDO0J&9=cy05gQF8>45e|;DOo$f(b^OrKDVTGA#8Tlv9!bP;EUM&N4kPlax;>K3uYf5{erNz}xr#F_cbs~A=&MR;k|;FI zjIRkw|1{kkfE~=pc?Rhzr1C{n^#Di(}aIupzihM+16}heOHxdc{#i5 z`Qbvc{j3f!V3YCM_<)>96H83i%WK%Ct9)_W+$kOnt>2&B_2S1svY~z~ykF)?vvtOL z9;U-KCt`Q8ofXsvY%wr@MAKz+^VMq_sez&Z&-k>*c|SMYb>zDtb&~niydS0Xp2grb z-;dGj3Ukwg1^X@5X0A-)2f7wkl{vHI{2PyAen3)?-#?&l{_C44*jt%7SF&HI{%@L% z4afNDLrMPuoznNU{&el2E+1|7`*WZ;AGiGQHFR^@o`T}5{*`$y&Q+ijOW+7l&Nvhg zG^{?>2s%#}i}FfgO-)vdqzS({H+EQLl+Gw4qz%N6*(RqTBz@@C0=Ck(H&iKF7r?Df zaQ}WdpOef|M+lI83*f5__+Ht-Kux{_)a3gvO7&!R54$2jlV~)P>AL`cM-KUNlt5LU z{ZCbX01D#Y<(1C1YE;V7f{wfg$W z0>C7veX=w2@%zUB(0e>wq`?n#U0`)}HEy)pQ~Dl(r0&5%^tx&(ebC+z|7v37=(t+S zri|BrW=6)%<#k@QxP|-8C*+N=10G-SeFg}Dc6f1fAIr_^AXMvSo4n(CPv`W^2(bmN zGPkrKeC3Q3LclWk3kac|nk8J|s%-PZxJ%eIC+Wx=D6dXtHXeQ?05ZehzX@;jKP!q= z>9G(K=gL1{wGjp1iGj3G$}fY8P*i4Sroc=G7*M5~=z$+UMWU!0v^}?R$K$lP2HPb_ zYFX*J3mC2tzBVu)Yyt=10uKld{y8{^XJlmX`Qc*#7Ek6TL~gg=nY9xMe1dFZU8Zt| znE`Esht{}%@h0Gb;TfGmnWn|Md=#_GkqO-4^Ay+TNsd)MzDQ(82h!nbk>AZsZbi5A z)fD>zVZfjfWH8j8YE8GgFjNIX9mDpTgHC0?4W6*s&P4CVy{#34uVVv}o1-+1@OOY5 z9>VsnFYM3}FT0Zv-$iZ1l*!ihre-LW$c3MqtBu{x#w>Cikt9qe+w2j`mkXMg(Gf(Xqg^LQACXKl zMQ#1TM+-&hWAa@)vsT%Dvf0rIbe{ECNbN%=?cLcvV=irqzV+CCzC@0fcy-dU13Zlm z*5$I!+lv-ORkz5*fzr8_^NaEqzdj#Mr@4<`d(;uaeycvH7w1+vLtj$Dl}&LY=D+}a zA)XFYvBIY_-sSyAwHtB5UAv3(I1>XdBm`QZhZ>!adpS+?Q{HP;es|nmM#mvdTwvl< z%>>gt1L=&O%G7xadhddnA>f>g%;s!PX0T{wd&zS9($)|=sY+Q0XLO@2=(udBE$Ta4OmaOhpp`PWdm_lb$19w&dJB95j1C3(@uUy!-+uZy zf+tY^+fNTxJn;12pJ|n3pKqZ|YZ@5H+Z;6VHy_x{KKt`YkN5V%U0gCxPo14pyfG!- zJ=-NlxevdE@=!-d-jK!>>?QD9^Hq5TY{q-@&B{&OkG4h{>+=o!ZvTP|9x2#XO0@Y| zmXlSNmq!H!eL%w!%3bMgTV7c)6n)3Fbq-Q zb|oB>kWjo~5`~F({Oe#v=MK(MOr~N8w_e9Bk`PSuspE=~#3J>)p&Dz-7d$mkyPZq# zkneKrJhrz$v~t&TLR~o&tCHK-&R&v zEgY|wyQNgi;WhFKH{g5Bkgts3fqIiUI+=jA)rBDn*_jF!}(2mI(AQ2JcFDZZB~}X?+Rmg z1@-9{g_`8dSXj>66OeZc3jvaHsTnP=EJv;^g_uI(q7(`a4+Uak73pbnlyBYAU^4xl z_mYkw{}t%<`jyD3cQo%^6bsr}ZshIk(j}!B%)c|x<$Y9C^o)#5i776Ie%kf&s*{N9 zhcvaC6%`j36jVB0ZH!177!j)`m)BZDH@&+*8XYw$eoBarh{(Yvurof{kq8XjfGs{M z)c7+K=9x*j`UcCS1e^}vO3DqwJkeGO@fTPm?%X>ZeT(O)ys^E#O-OWmphh+G4{}#AH9kJDsh(mpI}-uB~m~fOY1N*uM2U zS9R6?EG-4G2#W16&%@(xE?(+5iUqS!DwgcS$B(HGJ8SlJG6Y94P_{$F6i`oPdi$AT zi;JBzI!#PAqNAe=!^3wXGnYDVm@foKk6*lx}GjTVwc{2rS8%$iTc>A$M52Rw>^1OKussy+y@$M z3NJ6GW8&;(fbjr^_P;7Q)1aoVD2_jhNEIbou?UpnLI{h16-Xpun_`538!-`q0J4g* z1PO}?L^BA3vSk{Om}sgU*+KvTAt)*+pvV?6vIayDWnW}pBGL=>gX45M_RE=h@6FtI z?zzAB&i}o+=fLg{mrFOLd8r|zJT~0AcyT;FiQb$!3BFMr*apd}$cAIAX7HfE5x0nk z6KCaPU%cq1O+I7lPj^0+sy&vDU&zRG^9y_9#at$ahqw9*a!En6bP6S?p)xkk+xT-? z1i{U14}hO|gwiLG#N7Z}>#-~XfnY!;E8l2sm3(<@3c!j|FC3^nUC>s2m8osk|Y%*S4DjQmuTp4U}WS*OR=P@-upQ=fvp#=pWX?F(nwY5*Q<%_012IFzK*alyx z=)M*KF(*6w)dLE)EF_~#w*iIf76xW{?`uCRx=FyzqI`ooSRFg7Rg>mu{T!Rrn^7lI z5c2%&Y|^sSvgvfPu$gB%jZa{A7^4QBM=cF)5>PHq;gb6sF@Dqcg>${WsPH%Ba?9Hp zB_-jmkkxg024*jE&Ov|>bk%isVl6C!xclL@EiGVIVX-5JL)pHiiRj^BP9%~3N=%H} ztn$ulmcr*NEB!itx9PY$r%_z!^&mbmx8j$9u~Hj*7K>F>LY;O*CJprVrWY5J!9hw$ zSXioNZ0v0FXa^sxaln?!tiv0`E@Zj^26J}m{cWwbGybj=?#QdLlLSI{fChJCC+Mw` zV*`r_n;4h8gPTTp0bCviH=04lyRD;GeGePDK01|~=W zK9a*fZ@KV9Xh9&htb79NwzSYkF1awd_3>i=wm`SeF=u6{7!}?xb6W-c3{Cw(b|p6^ zW^W@8V@rN);tT*$#ULHlU*_ez3h=hJ5%ka0+@-m^OS%m#cva}i^8DGS(Z<`ANbFaB zhLMq&XVo#F+|B{G4c?I3_5Sn=j+z^l;abouTJ!E*R+Xas`-Pw#8z+rZ|39tkod%0Y~|C&;ZJF$3DZu|H0O6VTUoE#d!@ z_P@6ODgg$)4_&*-D(v|w34%h=ip7xC8Rb!u7IkVwagFTc`27ac^?2*Yi67bWoaNZGZOc}A3I^t;J$W_ zeA9V-XU&XEI~A3cw;8{Mh2aUQ1ScJJ)7_>8FJ)Ghis*#?s1=H|z za}$4F7GK$lx4mLaEgG|wR>ANAxij67;y&hUd&nxT$_ELd<6Ix6Q>W8Y5E(r^X(M{N z!0~#q1Bbf=3+u+U2BPr!ecC@9TB{k2L8HA1@b2XBL)ksp` z+}|}fKRmysP*SaVLj@bIit}4$p$@z_4 Date: Fri, 3 May 2019 20:07:56 +0530 Subject: [PATCH 378/588] soc/intel/skylake: Remove redundant mca_configure() in ramstage This patch removes redundant mca_configure() function call from ramstage to clear machine check exception. First time it's getting called from soc_core_init() function inside cpu.c file. TEST=Build and boot SKL/KBL/AML platform without any machine-check exception. Change-Id: I7e54fd07816c6317588ab6db06365937c4300ccd Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32553 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Nick Vaccaro --- src/soc/intel/skylake/finalize.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index 5d7e1e00341..34738f28f15 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -142,9 +141,6 @@ static void soc_finalize(void *unused) pch_finalize_script(dev); - printk(BIOS_DEBUG, "Clearing MCA.\n"); - mp_run_on_all_cpus(mca_configure, NULL, 17 * USECS_PER_SEC); - soc_lockdown(dev); printk(BIOS_DEBUG, "Finalizing SMM.\n"); From f91344cd07a4e9a4c2e183f00431b4fee05daf33 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Mon, 6 May 2019 19:23:26 +0530 Subject: [PATCH 379/588] soc/intel: Remove unused pointer argument in mca_configure() Change-Id: Iad3982d9db07a1f17ac39e87ff9c37956e40c258 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32616 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: David Guckian Reviewed-by: Paul Menzel --- src/soc/intel/apollolake/cpu.c | 2 +- src/soc/intel/cannonlake/cpu.c | 2 +- src/soc/intel/common/block/cpu/cpulib.c | 2 +- src/soc/intel/common/block/include/intelblocks/cpulib.h | 2 +- src/soc/intel/denverton_ns/cpu.c | 2 +- src/soc/intel/icelake/cpu.c | 2 +- src/soc/intel/skylake/cpu.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/soc/intel/apollolake/cpu.c b/src/soc/intel/apollolake/cpu.c index 651c20e43a9..aad0f6b5225 100644 --- a/src/soc/intel/apollolake/cpu.c +++ b/src/soc/intel/apollolake/cpu.c @@ -76,7 +76,7 @@ void soc_core_init(struct device *cpu) scope. For now every CPU clears every bank. */ if (CONFIG(SOC_INTEL_COMMON_BLOCK_SGX) || acpi_get_sleep_type() == ACPI_S5) - mca_configure(NULL); + mca_configure(); /* Set core MSRs */ reg_script_run(core_msr_script); diff --git a/src/soc/intel/cannonlake/cpu.c b/src/soc/intel/cannonlake/cpu.c index 8552424749b..d98e2f54865 100644 --- a/src/soc/intel/cannonlake/cpu.c +++ b/src/soc/intel/cannonlake/cpu.c @@ -413,7 +413,7 @@ void soc_core_init(struct device *cpu) /* TODO(adurbin): This should only be done on a cold boot. Also, some * of these banks are core vs package scope. For now every CPU clears * every bank. */ - mca_configure(NULL); + mca_configure(); /* Enable the local CPU apics */ enable_lapic_tpr(); diff --git a/src/soc/intel/common/block/cpu/cpulib.c b/src/soc/intel/common/block/cpu/cpulib.c index a7f89baafde..75e71120e04 100644 --- a/src/soc/intel/common/block/cpu/cpulib.c +++ b/src/soc/intel/common/block/cpu/cpulib.c @@ -300,7 +300,7 @@ uint32_t cpu_get_max_turbo_ratio(void) return msr.lo & 0xff; } -void mca_configure(void *unused) +void mca_configure(void) { msr_t msr; int i; diff --git a/src/soc/intel/common/block/include/intelblocks/cpulib.h b/src/soc/intel/common/block/include/intelblocks/cpulib.h index 70ad2536075..8630fd1eb59 100644 --- a/src/soc/intel/common/block/include/intelblocks/cpulib.h +++ b/src/soc/intel/common/block/include/intelblocks/cpulib.h @@ -159,6 +159,6 @@ uint32_t cpu_get_power_max(void); uint32_t cpu_get_max_turbo_ratio(void); /* Configure Machine Check Architecture support */ -void mca_configure(void *unused); +void mca_configure(void); #endif /* SOC_INTEL_COMMON_BLOCK_CPULIB_H */ diff --git a/src/soc/intel/denverton_ns/cpu.c b/src/soc/intel/denverton_ns/cpu.c index ce6df68f9fa..2a631718c02 100644 --- a/src/soc/intel/denverton_ns/cpu.c +++ b/src/soc/intel/denverton_ns/cpu.c @@ -58,7 +58,7 @@ static void dnv_configure_mca(void) /* TODO(adurbin): This should only be done on a cold boot. Also, some of these banks are core vs package scope. For now every CPU clears every bank. */ - mca_configure(NULL); + mca_configure(); } static void denverton_core_init(struct device *cpu) diff --git a/src/soc/intel/icelake/cpu.c b/src/soc/intel/icelake/cpu.c index b1776a09a46..527b989e1a2 100644 --- a/src/soc/intel/icelake/cpu.c +++ b/src/soc/intel/icelake/cpu.c @@ -192,7 +192,7 @@ void soc_core_init(struct device *cpu) /* TODO(adurbin): This should only be done on a cold boot. Also, some * of these banks are core vs package scope. For now every CPU clears * every bank. */ - mca_configure(NULL); + mca_configure(); /* Enable the local CPU apics */ enable_lapic_tpr(); diff --git a/src/soc/intel/skylake/cpu.c b/src/soc/intel/skylake/cpu.c index 52b0e194e6e..a63809bd7e2 100644 --- a/src/soc/intel/skylake/cpu.c +++ b/src/soc/intel/skylake/cpu.c @@ -428,7 +428,7 @@ void soc_core_init(struct device *cpu) /* TODO(adurbin): This should only be done on a cold boot. Also, some * of these banks are core vs package scope. For now every CPU clears * every bank. */ - mca_configure(NULL); + mca_configure(); /* Enable the local CPU apics */ enable_lapic_tpr(); From be291e8abf173e4f12e6d9e5532fdf1acbcb9a67 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sun, 6 Jan 2019 07:35:11 +0100 Subject: [PATCH 380/588] soc/intel/fsp1.1: Implement postcar stage This moves FSP1.1 to use postcar stage to tear down CAR. On platforms with USE_GENERIC_FSP_CAR_INC the FSP header is found during the postcar stage so there is no need to push to save it in CAR global variables. On FSP1.1 platforms with an open source CAR implementation (Skylake, even though it still runs the FSP-T), the soc/intel/common/blocks/cpu/car/exit_car.S code tears down CAR. This also uses common functions to set up the MTRR to use after CAR is torn down. Test: build/boot on google/celes (BSW) and google/chell (SKL) Change-Id: I2330993842aae9c1365230f0c6bd8a2449dc73a5 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30686 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- src/drivers/intel/fsp1_1/Kconfig | 2 + src/drivers/intel/fsp1_1/Makefile.inc | 8 +- src/drivers/intel/fsp1_1/after_raminit.S | 170 ------------------ src/drivers/intel/fsp1_1/cache_as_ram.inc | 6 - src/drivers/intel/fsp1_1/car.c | 128 +++++++++---- src/drivers/intel/fsp1_1/exit_car.S | 27 +++ src/drivers/intel/fsp1_1/include/fsp/car.h | 8 +- .../intel/fsp1_1/include/fsp/romstage.h | 2 +- src/drivers/intel/fsp1_1/include/fsp/util.h | 4 + src/drivers/intel/fsp1_1/romstage.c | 20 +-- src/drivers/intel/fsp1_1/stack.c | 161 ----------------- src/drivers/intel/fsp1_1/temp_ram_exit.c | 44 +++++ src/soc/intel/braswell/Makefile.inc | 2 + src/soc/intel/quark/include/soc/romstage.h | 2 +- .../intel/quark/romstage/car_stage_entry.S | 6 - src/soc/intel/quark/romstage/fsp2_0.c | 3 +- src/soc/intel/skylake/romstage/car_stage.S | 5 +- 17 files changed, 188 insertions(+), 410 deletions(-) delete mode 100644 src/drivers/intel/fsp1_1/after_raminit.S create mode 100644 src/drivers/intel/fsp1_1/exit_car.S delete mode 100644 src/drivers/intel/fsp1_1/stack.c create mode 100644 src/drivers/intel/fsp1_1/temp_ram_exit.c diff --git a/src/drivers/intel/fsp1_1/Kconfig b/src/drivers/intel/fsp1_1/Kconfig index a8658ec7e6b..da9e1888e9c 100644 --- a/src/drivers/intel/fsp1_1/Kconfig +++ b/src/drivers/intel/fsp1_1/Kconfig @@ -18,6 +18,8 @@ config PLATFORM_USES_FSP1_1 bool select UEFI_2_4_BINDING select INTEL_GMA_ADD_VBT if RUN_FSP_GOP + select POSTCAR_STAGE + select POSTCAR_CONSOLE help Does the code require the Intel Firmware Support Package? diff --git a/src/drivers/intel/fsp1_1/Makefile.inc b/src/drivers/intel/fsp1_1/Makefile.inc index 953d1e4ffed..93f3b59d4b3 100644 --- a/src/drivers/intel/fsp1_1/Makefile.inc +++ b/src/drivers/intel/fsp1_1/Makefile.inc @@ -28,7 +28,6 @@ romstage-y += fsp_util.c romstage-y += hob.c romstage-y += raminit.c romstage-y += romstage.c -romstage-y += stack.c romstage-y += stage_cache.c romstage-$(CONFIG_MMA) += mma_core.c @@ -45,6 +44,13 @@ CPPFLAGS_common += -Isrc/drivers/intel/fsp1_1/include cpu_incs-$(CONFIG_USE_GENERIC_FSP_CAR_INC) += $(src)/drivers/intel/fsp1_1/cache_as_ram.inc +postcar-y += stage_cache.c +ifneq ($(CONFIG_SKIP_FSP_CAR),y) +postcar-y += temp_ram_exit.c +postcar-y += exit_car.S +endif +postcar-y += fsp_util.c + # Add the FSP binary to the cbfs image ifeq ($(CONFIG_HAVE_FSP_BIN),y) cbfs-files-y += fsp.bin diff --git a/src/drivers/intel/fsp1_1/after_raminit.S b/src/drivers/intel/fsp1_1/after_raminit.S deleted file mode 100644 index 3f2a7ae02f2..00000000000 --- a/src/drivers/intel/fsp1_1/after_raminit.S +++ /dev/null @@ -1,170 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2000,2007 Ronald G. Minnich - * Copyright (C) 2007-2008 coresystems GmbH - * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC. - * Copyright (C) 2015 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -/* - * This is the common entry point after DRAM has been initialized. - */ - /* - * eax: New stack address - */ - - /* Switch to the stack in RAM */ - movl %eax, %esp - -#if CONFIG(SKIP_FSP_CAR) - - /* chipset_teardown_car() is expected to disable cache-as-ram. */ - call chipset_teardown_car - -#else -.extern fih_car - - post_code(POST_FSP_TEMP_RAM_EXIT) - - /* Calculate TempRamExit entry into FSP */ - movl fih_car, %ebp - mov 0x40(%ebp), %eax - add 0x1c(%ebp), %eax - - /* Build the call frame */ - pushl $0 - - /* Call TempRamExit */ - call *%eax - add $4, %esp - cmp $0, %eax - jz 1f - /* - * Failures for post code BC - failed in TempRamExit - * - * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully. - * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid. - * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met. - * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed. - */ - movb $0xBC, %ah - jmp .Lhlt -1: -#endif - /* Display the MTRRs */ - call display_mtrrs - - /* - * The stack contents are initialized in src/soc/intel/common/stack.c - * to be the following: - * - * * - * * - * * - * +36: MTRR mask 1 63:32 - * +32: MTRR mask 1 31:0 - * +28: MTRR base 1 63:32 - * +24: MTRR base 1 31:0 - * +20: MTRR mask 0 63:32 - * +16: MTRR mask 0 31:0 - * +12: MTRR base 0 63:32 - * +8: MTRR base 0 31:0 - * +4: Number of MTRRs to setup (described above) - * +0: Number of variable MTRRs to clear - */ - -#if CONFIG(SOC_SETS_MSRS) - push %esp - call soc_set_mtrrs - - /* eax: new top_of_stack with setup_stack_and_mtrrs data removed */ - movl %eax, %esp -#else - /* Clear all of the variable MTRRs. */ - popl %ebx - movl $MTRR_PHYS_BASE(0), %ecx - clr %eax - clr %edx - -1: - testl %ebx, %ebx - jz 1f - wrmsr /* Write MTRR base. */ - inc %ecx - wrmsr /* Write MTRR mask. */ - inc %ecx - dec %ebx - jmp 1b - -1: - /* Get number of MTRRs. */ - popl %ebx - movl $MTRR_PHYS_BASE(0), %ecx -2: - testl %ebx, %ebx - jz 2f - - /* Low 32 bits of MTRR base. */ - popl %eax - /* Upper 32 bits of MTRR base. */ - popl %edx - /* Write MTRR base. */ - wrmsr - inc %ecx - /* Low 32 bits of MTRR mask. */ - popl %eax - /* Upper 32 bits of MTRR mask. */ - popl %edx - /* Write MTRR mask. */ - wrmsr - inc %ecx - - dec %ebx - jmp 2b -2: -#endif /* CONFIG_SOC_SETS_MSRS */ - - post_code(0x39) - - /* And enable cache again after setting MTRRs. */ - movl %cr0, %eax - andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax - movl %eax, %cr0 - - post_code(0x3a) - -#if CONFIG(SOC_SETS_MSRS) - call soc_enable_mtrrs -#else - /* Enable MTRR. */ - movl $MTRR_DEF_TYPE_MSR, %ecx - rdmsr - orl $MTRR_DEF_TYPE_EN, %eax - wrmsr -#endif /* CONFIG_SOC_SETS_MSRS */ - - post_code(0x3b) - - /* Invalidate the cache again. */ - invd - - post_code(0x3c) - -__main: - post_code(POST_PREPARE_RAMSTAGE) - cld /* Clear direction flag. */ - call after_cache_as_ram diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc index fa5c40677b5..f50641e3aec 100644 --- a/src/drivers/intel/fsp1_1/cache_as_ram.inc +++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc @@ -147,12 +147,6 @@ before_romstage: /* Call cache_as_ram_main(struct cache_as_ram_params *) */ call cache_as_ram_main -/* One will never return from cache_as_ram_main() in verstage so there's - * no such thing as after RAM init. */ -#if !ENV_VERSTAGE -#include "after_raminit.S" -#endif - movb $0x69, %ah jmp .Lhlt diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 3a41e404687..34b2518c385 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -18,35 +18,96 @@ #include #include #include +#include #include #include -FSP_INFO_HEADER *fih_car CAR_GLOBAL; +#define ROMSTAGE_RAM_STACK_SIZE 0x5000 -/* Save FSP_INFO_HEADER for TempRamExit() call in assembly. */ -static inline void set_fih_car(FSP_INFO_HEADER *fih) +/* platform_enter_postcar() determines the stack to use after + * cache-as-ram is torn down as well as the MTRR settings to use, + * and continues execution in postcar stage. */ +static void platform_enter_postcar(void) { - /* This variable is written in the raw form because it's only - * ever accessed in code that that has the cache-as-ram enabled. The - * assembly routine which tears down cache-as-ram utilizes this - * variable for determining where to find FSP. */ - fih_car = fih; + struct postcar_frame pcf; + size_t alignment; + uint32_t aligned_ram; + + if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE)) + die("Unable to initialize postcar frame.\n"); + /* Cache the ROM as WP just below 4GiB. */ + postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE, + MTRR_TYPE_WRPROT); + + /* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */ + postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK); + + /* + * +-------------------------+ Top of RAM (aligned) + * | System Management Mode | + * | code and data | Length: CONFIG_TSEG_SIZE + * | (TSEG) | + * +-------------------------+ SMM base (aligned) + * | | + * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE + * | | + * +-------------------------+ top_of_ram (aligned) + * | | + * | CBMEM Root | + * | | + * +-------------------------+ + * | | + * | FSP Reserved Memory | + * | | + * +-------------------------+ + * | | + * | Various CBMEM Entries | + * | | + * +-------------------------+ top_of_stack (8 byte aligned) + * | | + * | stack (CBMEM Entry) | + * | | + * +-------------------------+ + */ + + alignment = mmap_region_granularity(); + aligned_ram = ALIGN_DOWN(romstage_ram_stack_bottom(), alignment); + postcar_frame_add_mtrr(&pcf, aligned_ram, alignment, MTRR_TYPE_WRBACK); + + if (CONFIG(HAVE_SMI_HANDLER)) { + void *smm_base; + size_t smm_size; + + /* + * Cache the TSEG region at the top of ram. This region is not + * restricted to SMM mode until SMM has been relocated. By + * setting the region to cacheable it provides faster access + * when relocating the SMM handler as well as using the TSEG + * region for other purposes. + */ + smm_region(&smm_base, &smm_size); + postcar_frame_add_mtrr(&pcf, (uintptr_t)smm_base, alignment, + MTRR_TYPE_WRBACK); + } + + run_postcar_phase(&pcf); } -asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) +/* This is the romstage C entry for platforms without + CONFIG_C_ENVIRONMENT_BOOTBLOCK */ +asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params) { int i; const int num_guards = 4; const u32 stack_guard = 0xdeadbeef; u32 *stack_base; - void *ram_stack; u32 size; /* Size of unallocated CAR. */ size = _car_region_end - _car_relocatable_data_end; size = ALIGN_DOWN(size, 16); - stack_base = (u32 *) (_car_region_end - size); + stack_base = (u32 *)(_car_region_end - size); for (i = 0; i < num_guards; i++) stack_base[i] = stack_guard; @@ -66,23 +127,20 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) display_mtrrs(); - if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE || - car_params->bootloader_car_end != - (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)) { + if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE + || car_params->bootloader_car_end != (CONFIG_DCACHE_RAM_BASE + + CONFIG_DCACHE_RAM_SIZE)) { printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n", - CONFIG_DCACHE_RAM_BASE, - CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE, - (long)car_params->bootloader_car_start, - (long)car_params->bootloader_car_end); + CONFIG_DCACHE_RAM_BASE, + CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE, + (long)car_params->bootloader_car_start, + (long)car_params->bootloader_car_end); } car_soc_post_console_init(); car_mainboard_post_console_init(); - set_fih_car(car_params->fih); - - /* Return new stack value in RAM back to assembly stub. */ - ram_stack = cache_as_ram_stage_main(car_params->fih); + cache_as_ram_stage_main(car_params->fih); /* Check the stack. */ for (i = 0; i < num_guards; i++) { @@ -91,11 +149,13 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n"); } - return ram_stack; + /* we don't return here */ + platform_enter_postcar(); } -/* Entry point taken when romstage is called after a separate verstage. */ -asmlinkage void *romstage_c_entry(void) +/* This is the romstage C entry for platforms with + CONFIG_C_ENVIRONMENT_BOOTBLOCK */ +asmlinkage void romstage_c_entry(void) { /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram * is still enabled. We can directly access work buffer here. */ @@ -107,24 +167,16 @@ asmlinkage void *romstage_c_entry(void) if (prog_locate(&fsp)) { fih = NULL; printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp)); - } else + } else { /* This leaks a mapping which this code assumes is benign as * the flash is memory mapped CPU's address space. */ fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); + } - set_fih_car(fih); - - /* Return new stack value in RAM back to assembly stub. */ - return cache_as_ram_stage_main(fih); -} - -asmlinkage void after_cache_as_ram(void *chipset_context) -{ - timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_END); - printk(BIOS_DEBUG, "FspTempRamExit returned successfully\n"); - display_mtrrs(); + cache_as_ram_stage_main(fih); - after_cache_as_ram_stage(); + /* we don't return here */ + platform_enter_postcar(); } void __weak car_mainboard_pre_console_init(void) diff --git a/src/drivers/intel/fsp1_1/exit_car.S b/src/drivers/intel/fsp1_1/exit_car.S new file mode 100644 index 00000000000..4b2822a8878 --- /dev/null +++ b/src/drivers/intel/fsp1_1/exit_car.S @@ -0,0 +1,27 @@ +/* + * This file is part of the coreboot project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + + +.text +.global chipset_teardown_car +chipset_teardown_car: + + pop %ebx + /* Move the stack pointer to real ram */ + movl post_car_stack_top, %esp + /* Align the stack 16 bytes */ + andl $0xfffffff0, %esp + + call chipset_teardown_car_main + + jmp *%ebx diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h index 5214d73b296..0ae687a9d74 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/car.h +++ b/src/drivers/intel/fsp1_1/include/fsp/car.h @@ -30,14 +30,12 @@ struct cache_as_ram_params { }; /* Entry points from the cache-as-ram assembly code. */ -asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params); -asmlinkage void after_cache_as_ram(void *chipset_context); -asmlinkage void *romstage_c_entry(void); +asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params); +asmlinkage void romstage_c_entry(void); /* Per stage calls from the above two functions. The void * return from * cache_as_ram_stage_main() is the stack pointer to use in RAM after * exiting cache-as-ram mode. */ -void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih); -void after_cache_as_ram_stage(void); +void cache_as_ram_stage_main(FSP_INFO_HEADER *fih); /* Mainboard and SoC initialization prior to console. */ void car_mainboard_pre_console_init(void); diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index b01f11059c3..de379508870 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -87,7 +87,7 @@ void mainboard_add_dimm_info(struct romstage_params *params, void raminit(struct romstage_params *params); void report_memory_config(void); void romstage_common(struct romstage_params *params); -asmlinkage void *romstage_main(FSP_INFO_HEADER *fih); +asmlinkage void romstage_main(FSP_INFO_HEADER *fih); /* Initialize memory margin analysis settings. */ void setup_mma(MEMORY_INIT_UPD *memory_upd); void *setup_stack_and_mtrrs(void); diff --git a/src/drivers/intel/fsp1_1/include/fsp/util.h b/src/drivers/intel/fsp1_1/include/fsp/util.h index 0ad7a4117a7..45b8eda2435 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/util.h +++ b/src/drivers/intel/fsp1_1/include/fsp/util.h @@ -17,6 +17,8 @@ #ifndef FSP1_1_UTIL_H #define FSP1_1_UTIL_H +#include +#include #include /* Current users expect to get the SoC's FSP definitions by including util.h. */ #include @@ -107,4 +109,6 @@ void *get_first_guid_hob(const EFI_GUID *guid); __attribute__((cdecl)) size_t fsp_write_line(uint8_t *buffer, size_t number_of_bytes); +asmlinkage void chipset_teardown_car_main(void); + #endif /* FSP1_1_UTIL_H */ diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 433e16cf130..40c598877f2 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -38,9 +38,8 @@ #include #include -asmlinkage void *romstage_main(FSP_INFO_HEADER *fih) +asmlinkage void romstage_main(FSP_INFO_HEADER *fih) { - void *top_of_stack; struct romstage_params params = { .chipset_context = fih, }; @@ -72,17 +71,11 @@ asmlinkage void *romstage_main(FSP_INFO_HEADER *fih) mainboard_romstage_entry(¶ms); soc_after_ram_init(¶ms); post_code(0x38); - - top_of_stack = setup_stack_and_mtrrs(); - - printk(BIOS_DEBUG, "Calling FspTempRamExit API\n"); - timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START); - return top_of_stack; } -void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih) +void cache_as_ram_stage_main(FSP_INFO_HEADER *fih) { - return romstage_main(fih); + romstage_main(fih); } /* Entry from the mainboard. */ @@ -161,13 +154,6 @@ void romstage_common(struct romstage_params *params) full_reset(); } -void after_cache_as_ram_stage(void) -{ - /* Load the ramstage. */ - run_ramstage(); - die("ERROR - Failed to load ramstage!"); -} - /* Initialize the power state */ __weak struct chipset_power_state *fill_power_state(void) { diff --git a/src/drivers/intel/fsp1_1/stack.c b/src/drivers/intel/fsp1_1/stack.c deleted file mode 100644 index 88ff36a8473..00000000000 --- a/src/drivers/intel/fsp1_1/stack.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2013 Google Inc. - * Copyright (C) 2015-2016 Intel Corp. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * setup_stack_and_mtrrs() determines the stack to use after - * cache-as-ram is torn down as well as the MTRR settings to use. - */ -void *setup_stack_and_mtrrs(void) -{ - size_t alignment; - uint32_t aligned_ram; - uint32_t mtrr_mask_upper; - uint32_t max_mtrrs; - uint32_t num_mtrrs; - uint32_t *slot; - - /* Display the MTRRs */ - display_mtrrs(); - - /* Top of stack needs to be aligned to a 8-byte boundary. */ - slot = (void *)romstage_ram_stack_top(); - num_mtrrs = 0; - max_mtrrs = get_var_mtrr_count(); - - /* - * The upper bits of the MTRR mask need to set according to the number - * of physical address bits. - */ - mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1; - alignment = mmap_region_granularity(); - aligned_ram = ALIGN_DOWN(romstage_ram_stack_bottom(), alignment); - - /* - * The order for each MTRR is value then base with upper 32-bits of - * each value coming before the lower 32-bits. The reasoning for - * this ordering is to create a stack layout like the following: - * - * +36: MTRR mask 1 63:32 - * +32: MTRR mask 1 31:0 - * +28: MTRR base 1 63:32 - * +24: MTRR base 1 31:0 - * +20: MTRR mask 0 63:32 - * +16: MTRR mask 0 31:0 - * +12: MTRR base 0 63:32 - * +8: MTRR base 0 31:0 - * +4: Number of MTRRs to setup (described above) - * +0: Number of variable MTRRs to clear - */ - - /* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */ - slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push32(slot, ~(CACHE_TMP_RAMTOP - 1) - | MTRR_PHYS_MASK_VALID); - slot = stack_push32(slot, 0); /* upper base */ - slot = stack_push32(slot, 0 | MTRR_TYPE_WRBACK); - num_mtrrs++; - - /* - * +-------------------------+ Top of RAM (aligned) - * | System Management Mode | - * | code and data | Length: CONFIG_TSEG_SIZE - * | (TSEG) | - * +-------------------------+ SMM base (aligned) - * | | - * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE - * | | - * +-------------------------+ top_of_ram (aligned) - * | | - * | CBMEM Root | - * | | - * +-------------------------+ - * | | - * | FSP Reserved Memory | - * | | - * +-------------------------+ - * | | - * | Various CBMEM Entries | - * | | - * +-------------------------+ top_of_stack (8 byte aligned) - * | | - * | stack (CBMEM Entry) | - * | | - * +-------------------------+ - */ - - /* - * Cache the stack and the other CBMEM entries as well as part or all - * of the FSP reserved memory region. - */ - slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID); - slot = stack_push32(slot, 0); /* upper base */ - slot = stack_push32(slot, aligned_ram | MTRR_TYPE_WRBACK); - num_mtrrs++; - -#if CONFIG(HAVE_SMI_HANDLER) - void *smm_base; - size_t smm_size; - uint32_t tseg_base; - - /* - * Cache the TSEG region at the top of ram. This region is not - * restricted to SMM mode until SMM has been relocated. By setting - * the region to cacheable it provides faster access when relocating - * the SMM handler as well as using the TSEG region for other purposes. - */ - smm_region(&smm_base, &smm_size); - tseg_base = (uint32_t)smm_base; - slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID); - slot = stack_push32(slot, 0); /* upper base */ - slot = stack_push32(slot, tseg_base | MTRR_TYPE_WRBACK); - num_mtrrs++; -#endif - - /* Cache the ROM as WP just below 4GiB. */ - slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) - | MTRR_PHYS_MASK_VALID); - slot = stack_push32(slot, 0); /* upper base */ - slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT); - num_mtrrs++; - - /* Validate the MTRR usage */ - if (num_mtrrs > max_mtrrs) { - printk(BIOS_ERR, "MTRRs: max = %d, used = %d, available=%d", - max_mtrrs, num_mtrrs, max_mtrrs - num_mtrrs); - die("ERROR - MTRR use count incorrect!\n"); - } - - /* - * Save the number of MTRRs to setup and clear. Return the stack - * location pointing to the number of MTRRs. - */ - slot = stack_push32(slot, num_mtrrs); - slot = stack_push32(slot, max_mtrrs); - return slot; -} diff --git a/src/drivers/intel/fsp1_1/temp_ram_exit.c b/src/drivers/intel/fsp1_1/temp_ram_exit.c new file mode 100644 index 00000000000..c1535e0bc0a --- /dev/null +++ b/src/drivers/intel/fsp1_1/temp_ram_exit.c @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include + +asmlinkage void chipset_teardown_car_main(void) +{ + FSP_INFO_HEADER *fih; + uint32_t status; + FSP_TEMP_RAM_EXIT temp_ram_exit; + struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); + + if (prog_locate(&fsp)) { + die("Unable to locate fsp.bin\n"); + } else { + /* This leaks a mapping which this code assumes is benign as + * the flash is memory mapped CPU's address space. */ + + /* FIXME: the implementation of find_fsp is utter garbage + as it casts error values to FSP_INFO_HEADER pointers. + Checking for return values can only be done sanely once + that is fixed. */ + fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); + } + + temp_ram_exit = (FSP_TEMP_RAM_EXIT)(fih->TempRamExitEntryOffset + + fih->ImageBase); + printk(BIOS_DEBUG, "Calling TempRamExit: %p\n", temp_ram_exit); + status = temp_ram_exit(NULL); + + if (status != FSP_SUCCESS) { + printk(BIOS_CRIT, "TempRamExit returned 0x%08x\n", status); + die("TempRamExit returned an error!\n"); + } +} diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index e2b1fe5295c..6b466c66f88 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -17,6 +17,8 @@ romstage-y += pmutil.c romstage-y += smbus.c romstage-y += tsc_freq.c +postcar-y += memmap.c +postcar-y += iosf.c postcar-y += tsc_freq.c ramstage-y += acpi.c diff --git a/src/soc/intel/quark/include/soc/romstage.h b/src/soc/intel/quark/include/soc/romstage.h index fb8a844815d..c7de080146d 100644 --- a/src/soc/intel/quark/include/soc/romstage.h +++ b/src/soc/intel/quark/include/soc/romstage.h @@ -25,7 +25,7 @@ #include #include -asmlinkage void *car_stage_c_entry(void); +asmlinkage void car_stage_c_entry(void); void clear_smi_and_wake_events(void); void disable_rom_shadow(void); void *locate_rmu_file(size_t *rmu_file_len); diff --git a/src/soc/intel/quark/romstage/car_stage_entry.S b/src/soc/intel/quark/romstage/car_stage_entry.S index d51587143b9..c9847eaac70 100644 --- a/src/soc/intel/quark/romstage/car_stage_entry.S +++ b/src/soc/intel/quark/romstage/car_stage_entry.S @@ -29,12 +29,6 @@ car_stage_entry: /* Enter the C code */ call car_stage_c_entry -#if CONFIG(PLATFORM_USES_FSP1_1) -#if !ENV_VERSTAGE -#include "src/drivers/intel/fsp1_1/after_raminit.S" -#endif -#endif - /* The code should never reach this point */ movb $0x69, %ah jmp .Lhlt diff --git a/src/soc/intel/quark/romstage/fsp2_0.c b/src/soc/intel/quark/romstage/fsp2_0.c index 31e130a3985..2ec16c9f341 100644 --- a/src/soc/intel/quark/romstage/fsp2_0.c +++ b/src/soc/intel/quark/romstage/fsp2_0.c @@ -26,7 +26,7 @@ #include #include -asmlinkage void *car_stage_c_entry(void) +asmlinkage void car_stage_c_entry(void) { struct postcar_frame pcf; bool s3wake; @@ -83,7 +83,6 @@ asmlinkage void *car_stage_c_entry(void) postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRTHROUGH); run_postcar_phase(&pcf); - return NULL; } static struct chipset_power_state power_state CAR_GLOBAL; diff --git a/src/soc/intel/skylake/romstage/car_stage.S b/src/soc/intel/skylake/romstage/car_stage.S index ee04f0272d3..d8b45cb2588 100644 --- a/src/soc/intel/skylake/romstage/car_stage.S +++ b/src/soc/intel/skylake/romstage/car_stage.S @@ -13,6 +13,8 @@ * GNU General Public License for more details. */ +#include + /* I/O delay between post codes on failure */ #define LHLT_DELAY 0x50000 @@ -20,9 +22,8 @@ .global car_stage_entry car_stage_entry: call romstage_c_entry - #include "src/drivers/intel/fsp1_1/after_raminit.S" - + /* we don't return here */ movb $0x69, %ah jmp .Lhlt From b6ee05692dce5df945b8363d361398ab2192d960 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Tue, 21 May 2019 16:55:14 +0800 Subject: [PATCH 381/588] vboot: determine display init before recovery check Display is required by recovery mode. Determine display init before recovery check. BUG=b:133197727,b:133175864 TEST=enter recovery mode, checked the display shows up Signed-off-by: Eric Lai Change-Id: Id6ac611f51241373bca3e2b394a94dcd52d3fde7 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32906 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Duncan Laurie --- src/security/vboot/vboot_logic.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index 00347c3f583..d4ad32736b3 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -344,6 +344,14 @@ void verstage_main(void) printk(BIOS_INFO, "Phase 1\n"); rv = vb2api_fw_phase1(&ctx); + /* Jot down some information from vboot which may be required later on + in coreboot boot flow. */ + if (ctx.flags & VB2_CONTEXT_DISPLAY_INIT) + /* Mainboard/SoC should initialize display. */ + vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; + if (ctx.flags & VB2_CONTEXT_DEVELOPER_MODE) + vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DEVELOPER_MODE; + if (rv) { /* * If vb2api_fw_phase1 fails, check for return value. @@ -364,14 +372,6 @@ void verstage_main(void) vboot_reboot(); } - /* Jot down some information from vboot which may be required later on - in coreboot boot flow. */ - if (ctx.flags & VB2_CONTEXT_DISPLAY_INIT) - /* Mainboard/SoC should initialize display. */ - vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DISPLAY_INIT; - if (ctx.flags & VB2_CONTEXT_DEVELOPER_MODE) - vboot_get_working_data()->flags |= VBOOT_WD_FLAG_DEVELOPER_MODE; - /* Determine which firmware slot to boot (based on NVRAM) */ printk(BIOS_INFO, "Phase 2\n"); rv = vb2api_fw_phase2(&ctx); From 9b0d8e7a1fd18a53579d0332204d2be57ec0474b Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Mon, 20 May 2019 16:35:33 -0600 Subject: [PATCH 382/588] util/romcc: Prevent out-of-bounds read If 'class > LAST_REGC', then there will be an out-of-bounds read when accessing 'regcm_bound'. Prevent this by skipping to the next iteration of the loop. Note that this should not generally happen anyway, since 'result' represents a bitset for the indices of 'regcm_bound', and so iterations where 'class > LAST_REGC' should already be skipped by the previous continue statement (since those bits of 'result' should all be zero). Found-by: Covericy CID 1129122 Signed-off-by: Jacob Garber Change-Id: Id5f5adb0a292763251054aeecf2a5b87a11297b1 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32902 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Paul Menzel --- util/romcc/romcc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index b9ec835f6f5..329cfd2433a 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -22160,6 +22160,7 @@ static unsigned arch_regcm_normalize(struct compile_state *state, unsigned regcm } if (class > LAST_REGC) { result &= ~mask; + continue; } for(class2 = 0; class2 <= LAST_REGC; class2++) { if ((regcm_bound[class2].first >= regcm_bound[class].first) && From 8ef2a45bb9139a160d2562938680a73edb10e8ae Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 18 May 2019 15:51:39 -0500 Subject: [PATCH 383/588] soc/{baytrail/braswell/broadwell}: fix flashconsole on platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enabling flashconsole on these platforms fails to build due to spi.c not being compiled in prior to ramstage. Include in early stages (bootblock/romstage/postcar) as needed to enable flashconsole support. Early inclusion of monotonic_timer.c is needed for Broadwell as well. Change-Id: Idae0578ca92939246021bb85e34b0dcbd41df3b5 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32878 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/baytrail/Makefile.inc | 2 ++ src/soc/intel/braswell/Makefile.inc | 2 ++ src/soc/intel/broadwell/Makefile.inc | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/src/soc/intel/baytrail/Makefile.inc b/src/soc/intel/baytrail/Makefile.inc index 0d4bac51406..6e6eb9cc44c 100644 --- a/src/soc/intel/baytrail/Makefile.inc +++ b/src/soc/intel/baytrail/Makefile.inc @@ -16,6 +16,8 @@ ramstage-y += tsc_freq.c romstage-y += tsc_freq.c postcar-y += tsc_freq.c smm-y += tsc_freq.c +romstage-y += spi.c +postcar-y += spi.c ramstage-y += spi.c smm-y += spi.c ramstage-y += chip.c diff --git a/src/soc/intel/braswell/Makefile.inc b/src/soc/intel/braswell/Makefile.inc index 6b466c66f88..e479a3c5e55 100644 --- a/src/soc/intel/braswell/Makefile.inc +++ b/src/soc/intel/braswell/Makefile.inc @@ -15,10 +15,12 @@ romstage-y += lpc_init.c romstage-y += memmap.c romstage-y += pmutil.c romstage-y += smbus.c +romstage-y += spi.c romstage-y += tsc_freq.c postcar-y += memmap.c postcar-y += iosf.c +postcar-y += spi.c postcar-y += tsc_freq.c ramstage-y += acpi.c diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc index 40017eb3ec1..a79fa464a9e 100644 --- a/src/soc/intel/broadwell/Makefile.inc +++ b/src/soc/intel/broadwell/Makefile.inc @@ -39,6 +39,9 @@ ramstage-y += memmap.c romstage-y += memmap.c postcar-y += memmap.c ramstage-y += minihd.c +bootblock-y += monotonic_timer.c +romstage-y += monotonic_timer.c +postcar-y += monotonic_timer.c ramstage-y += monotonic_timer.c smm-y += monotonic_timer.c ramstage-y += pch.c @@ -60,6 +63,9 @@ romstage-y += smbus_common.c ramstage-y += smi.c smm-y += smihandler.c ramstage-y += smmrelocate.c +bootblock-y += spi.c +romstage-y += spi.c +postcar-y += spi.c ramstage-y += spi.c smm-$(CONFIG_SPI_FLASH_SMM) += spi.c ramstage-y += stage_cache.c From 1caa3143d6decbb1cbb0c64cdb5a22bb46ae0053 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 18 May 2019 15:56:14 -0500 Subject: [PATCH 384/588] soc/fsp_baytrail: fix flashconsole on platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Include spi.c in romstage. Since FSP 1.0 can't use NO_CAR_GLOBAL_MIGRATION, adjust global variables in spi.c to use CAR_GLOBAL. Adapted from early versions of CB:21107 Change-Id: I3487fb8ac317ce920bf1c3ef9d89590051932378 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/32879 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/fsp_baytrail/Makefile.inc | 1 + src/soc/intel/fsp_baytrail/spi.c | 82 +++++++++++++------------ 2 files changed, 44 insertions(+), 39 deletions(-) diff --git a/src/soc/intel/fsp_baytrail/Makefile.inc b/src/soc/intel/fsp_baytrail/Makefile.inc index 5ed635d9431..ca2b353b0f3 100644 --- a/src/soc/intel/fsp_baytrail/Makefile.inc +++ b/src/soc/intel/fsp_baytrail/Makefile.inc @@ -35,6 +35,7 @@ romstage-y += tsc_freq.c postcar-y += tsc_freq.c smm-$(CONFIG_HAVE_SMI_HANDLER) += tsc_freq.c ramstage-y += spi.c +romstage-y += spi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += spi.c ramstage-y += chip.c ramstage-y += iosf.c diff --git a/src/soc/intel/fsp_baytrail/spi.c b/src/soc/intel/fsp_baytrail/spi.c index 979ee573bbc..9375d195474 100644 --- a/src/soc/intel/fsp_baytrail/spi.c +++ b/src/soc/intel/fsp_baytrail/spi.c @@ -15,7 +15,7 @@ */ /* This file is derived from the flashrom project. */ - +#include #include #include #include @@ -33,7 +33,7 @@ typedef struct spi_slave ich_spi_slave; -static int ichspi_lock = 0; +static int g_ichspi_lock CAR_GLOBAL = 0; typedef struct ich9_spi_regs { uint32_t bfpr; @@ -81,7 +81,7 @@ typedef struct ich_spi_controller { uint16_t *control; } ich_spi_controller; -static ich_spi_controller cntlr; +static ich_spi_controller g_cntlr CAR_GLOBAL; enum { SPIS_SCIP = 0x0001, @@ -239,18 +239,19 @@ static ich9_spi_regs *spi_regs(void) void spi_init(void) { + ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); ich9_spi_regs *ich9_spi = spi_regs(); - ichspi_lock = readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (uint8_t *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (uint16_t *)ich9_spi->ssfc; - cntlr.preop = &ich9_spi->preop; + car_set_var(g_ichspi_lock, readw_(&ich9_spi->hsfs) & HSFS_FLOCKDN); + cntlr->opmenu = ich9_spi->opmenu; + cntlr->menubytes = sizeof(ich9_spi->opmenu); + cntlr->optype = &ich9_spi->optype; + cntlr->addr = &ich9_spi->faddr; + cntlr->data = (uint8_t *)ich9_spi->fdata; + cntlr->databytes = sizeof(ich9_spi->fdata); + cntlr->status = &ich9_spi->ssfs; + cntlr->control = (uint16_t *)ich9_spi->ssfc; + cntlr->preop = &ich9_spi->preop; } typedef struct spi_transaction { @@ -311,17 +312,18 @@ static void spi_setup_type(spi_transaction *trans) static int spi_setup_opcode(spi_transaction *trans) { + ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); uint16_t optypes; - uint8_t opmenu[cntlr.menubytes]; + uint8_t opmenu[cntlr->menubytes]; trans->opcode = trans->out[0]; spi_use_out(trans, 1); - if (!ichspi_lock) { + if (!car_get_var(g_ichspi_lock)) { /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); + writeb_(trans->opcode, cntlr->opmenu); + optypes = readw_(cntlr->optype); optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); + writew_(optypes, cntlr->optype); return 0; } else { /* The lock is on. See if what we need is on the menu. */ @@ -332,20 +334,20 @@ static int spi_setup_opcode(spi_transaction *trans) if (trans->opcode == SPI_OPCODE_WREN) return 0; - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < cntlr.menubytes; + read_reg(cntlr->opmenu, opmenu, sizeof(opmenu)); + for (opcode_index = 0; opcode_index < cntlr->menubytes; opcode_index++) { if (opmenu[opcode_index] == trans->opcode) break; } - if (opcode_index == cntlr.menubytes) { + if (opcode_index == cntlr->menubytes) { printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", trans->opcode); return -1; } - optypes = readw_(cntlr.optype); + optypes = readw_(cntlr->optype); optype = (optypes >> (opcode_index * 2)) & 0x3; if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && @@ -391,14 +393,15 @@ static int spi_setup_offset(spi_transaction *trans) */ static int ich_status_poll(uint16_t bitmask, int wait_til_set) { + ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); int timeout = 40000; /* This will result in 400 ms */ uint16_t status = 0; while (timeout--) { - status = readw_(cntlr.status); + status = readw_(cntlr->status); if (wait_til_set ^ ((status & bitmask) == 0)) { if (wait_til_set) - writew_((status & bitmask), cntlr.status); + writew_((status & bitmask), cntlr->status); return status; } udelay(10); @@ -412,6 +415,7 @@ static int ich_status_poll(uint16_t bitmask, int wait_til_set) static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, void *din, size_t bytesin) { + ich_spi_controller *cntlr = car_get_var_ptr(&g_cntlr); uint16_t control; int16_t opcode_index; int with_address; @@ -437,7 +441,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, if (ich_status_poll(SPIS_SCIP, 0) == -1) return -1; - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); + writew_(SPIS_CDS | SPIS_FCERR, cntlr->status); spi_setup_type(&trans); if ((opcode_index = spi_setup_opcode(&trans)) < 0) @@ -445,13 +449,13 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, if ((with_address = spi_setup_offset(&trans)) < 0) return -1; - if (!ichspi_lock && trans.opcode == SPI_OPCODE_WREN) { + if (!car_get_var(g_ichspi_lock) && trans.opcode == SPI_OPCODE_WREN) { /* * Treat Write Enable as Atomic Pre-Op if possible * in order to prevent the Management Engine from * issuing a transaction between WREN and DATA. */ - writew_(trans.opcode, cntlr.preop); + writew_(trans.opcode, cntlr->preop); return 0; } @@ -459,13 +463,13 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, control = SPIC_SCGO | ((opcode_index & 0x07) << 4); /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) + if (readw_(cntlr->preop)) control |= SPIC_ACS; if (!trans.bytesout && !trans.bytesin) { /* SPI addresses are 24 bit only */ if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + writel_(trans.offset & 0x00FFFFFF, cntlr->addr); /* * This is a 'no data' command (like Write Enable), its @@ -473,7 +477,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, * spi_setup_opcode() above. Tell the chip to send the * command. */ - writew_(control, cntlr.control); + writew_(control, cntlr->control); /* wait for the result */ status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); @@ -495,7 +499,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, * and followed by other SPI commands, and this sequence is controlled * by the SPI chip driver. */ - if (trans.bytesout > cntlr.databytes) { + if (trans.bytesout > cntlr->databytes) { printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" " spi_crop_chunk()?\n"); return -1; @@ -509,28 +513,28 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, uint32_t data_length; /* SPI addresses are 24 bit only */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + writel_(trans.offset & 0x00FFFFFF, cntlr->addr); if (trans.bytesout) - data_length = min(trans.bytesout, cntlr.databytes); + data_length = min(trans.bytesout, cntlr->databytes); else - data_length = min(trans.bytesin, cntlr.databytes); + data_length = min(trans.bytesin, cntlr->databytes); /* Program data into FDATA0 to N */ if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); + write_reg(trans.out, cntlr->data, data_length); spi_use_out(&trans, data_length); if (with_address) trans.offset += data_length; } /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); + control &= ~((cntlr->databytes - 1) << 8); control |= SPIC_DS; control |= (data_length - 1) << 8; /* write it */ - writew_(control, cntlr.control); + writew_(control, cntlr->control); /* Wait for Cycle Done Status or Flash Cycle Error. */ status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); @@ -543,7 +547,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, } if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); + read_reg(cntlr->data, trans.in, data_length); spi_use_in(&trans, data_length); if (with_address) trans.offset += data_length; @@ -552,7 +556,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, spi_xfer_exit: /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); + writew_(0, cntlr->preop); return 0; } From fa6233daeb2bfb8b75bea9032c0839e2d5bcf60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 28 Jun 2018 16:55:29 +0300 Subject: [PATCH 385/588] soc/amd/common: Identify AGESA call pattern MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The entry to AGESA always follows pattern: amd_create_struct() amd_dispatch() amd_release_struct() Separate the create/release_struct calls from the more relevant entry point details. Change-Id: I1037c9daef3365c8672a198ac60f47fc79ffaea1 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31488 Reviewed-by: Richard Spiegel Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/amd/common/block/pi/agesawrapper.c | 138 +++++++-------------- 1 file changed, 46 insertions(+), 92 deletions(-) diff --git a/src/soc/amd/common/block/pi/agesawrapper.c b/src/soc/amd/common/block/pi/agesawrapper.c index da6de00568c..a39e29ff481 100644 --- a/src/soc/amd/common/block/pi/agesawrapper.c +++ b/src/soc/amd/common/block/pi/agesawrapper.c @@ -65,10 +65,9 @@ AGESA_STATUS amd_late_run_ap_task(AP_EXE_PARAMS *ApExeParams) return module_dispatch(AMD_LATE_RUN_AP_TASK, StdHeader); } -static void *amd_create_struct(AMD_INTERFACE_PARAMS *aip, +static AGESA_STATUS amd_create_struct(AMD_INTERFACE_PARAMS *aip, AGESA_STRUCT_NAME func, void *buf, size_t len) { - AMD_CONFIG_PARAMS *StdHeader; AGESA_STATUS status; /* Should clone entire StdHeader here. */ @@ -77,8 +76,8 @@ static void *amd_create_struct(AMD_INTERFACE_PARAMS *aip, /* If we provide the buffer, API expects it to have StdHeader already filled. */ - if (buf != NULL && len >= sizeof(*StdHeader)) { - memcpy(buf, &aip->StdHeader, sizeof(*StdHeader)); + if (buf != NULL && len >= sizeof(aip->StdHeader)) { + memcpy(buf, &aip->StdHeader, sizeof(aip->StdHeader)); aip->AllocationMethod = ByHost; aip->NewStructPtr = buf; aip->NewStructSize = len; @@ -101,9 +100,7 @@ static void *amd_create_struct(AMD_INTERFACE_PARAMS *aip, if (!aip->NewStructPtr) die("No AGESA structure created"); - StdHeader = aip->NewStructPtr; - StdHeader->Func = aip->AgesaFunctionName; - return StdHeader; + return status; } static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip) @@ -111,14 +108,9 @@ static AGESA_STATUS amd_release_struct(AMD_INTERFACE_PARAMS *aip) return module_dispatch(AMD_RELEASE_STRUCT, &aip->StdHeader); } -static AGESA_STATUS amd_init_reset(void) +static AGESA_STATUS amd_init_reset(AMD_RESET_PARAMS *ResetParams) { AGESA_STATUS status; - AMD_RESET_PARAMS _ResetParams; - AMD_INTERFACE_PARAMS AmdParamStruct; - - AMD_RESET_PARAMS *ResetParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_RESET, &_ResetParams, sizeof(AMD_RESET_PARAMS)); SetFchResetParams(&ResetParams->FchInterface); @@ -126,17 +118,12 @@ static AGESA_STATUS amd_init_reset(void) status = amd_dispatch(ResetParams); timestamp_add_now(TS_AGESA_INIT_RESET_DONE); - amd_release_struct(&AmdParamStruct); return status; } -static AGESA_STATUS amd_init_early(void) +static AGESA_STATUS amd_init_early(AMD_EARLY_PARAMS *EarlyParams) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct; - - AMD_EARLY_PARAMS *EarlyParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_EARLY, NULL, 0); soc_customize_init_early(EarlyParams); OemCustomizeInitEarly(EarlyParams); @@ -145,8 +132,6 @@ static AGESA_STATUS amd_init_early(void) status = amd_dispatch(EarlyParams); timestamp_add_now(TS_AGESA_INIT_EARLY_DONE); - amd_release_struct(&AmdParamStruct); - return status; } @@ -183,13 +168,9 @@ static void print_init_post_settings(AMD_POST_PARAMS *parms) uma_size / MiB, uma_start); } -static AGESA_STATUS amd_init_post(void) +static AGESA_STATUS amd_init_post(AMD_POST_PARAMS *PostParams) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct; - - AMD_POST_PARAMS *PostParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_POST, NULL, 0); PostParams->MemConfig.UmaMode = CONFIG(GFXUMA) ? UMA_AUTO : UMA_NONE; PostParams->MemConfig.UmaSize = 0; @@ -229,18 +210,12 @@ static AGESA_STATUS amd_init_post(void) print_init_post_settings(PostParams); - amd_release_struct(&AmdParamStruct); - return status; } -static AGESA_STATUS amd_init_env(void) +static AGESA_STATUS amd_init_env(AMD_ENV_PARAMS *EnvParams) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct; - - AMD_ENV_PARAMS *EnvParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_ENV, NULL, 0); SetFchEnvParams(&EnvParams->FchInterface); SetNbEnvParams(&EnvParams->GnbEnvConfiguration); @@ -249,8 +224,6 @@ static AGESA_STATUS amd_init_env(void) status = amd_dispatch(EnvParams); timestamp_add_now(TS_AGESA_INIT_ENV_DONE); - amd_release_struct(&AmdParamStruct); - return status; } @@ -280,17 +253,13 @@ void *agesawrapper_getlateinitptr(int pick) } } -static AGESA_STATUS amd_init_mid(void) +static AGESA_STATUS amd_init_mid(AMD_MID_PARAMS *MidParams) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct; /* Enable MMIO on AMD CPU Address Map Controller */ amd_initcpuio(); - AMD_MID_PARAMS *MidParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_MID, NULL, 0); - SetFchMidParams(&MidParams->FchInterface); SetNbMidParams(&MidParams->GnbMidConfiguration); @@ -298,22 +267,12 @@ static AGESA_STATUS amd_init_mid(void) status = amd_dispatch(MidParams); timestamp_add_now(TS_AGESA_INIT_MID_DONE); - amd_release_struct(&AmdParamStruct); - return status; } -static AGESA_STATUS amd_init_late(void) +static AGESA_STATUS amd_init_late(AMD_LATE_PARAMS *LateParams) { AGESA_STATUS Status; - AMD_INTERFACE_PARAMS AmdParamStruct; - - /* - * NOTE: if not call amdcreatestruct, the initializer - * (AmdInitLateInitializer) would not be called. - */ - AMD_LATE_PARAMS *LateParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_LATE, NULL, 0); const struct device *dev = pcidev_path_on_root(IOMMU_DEVFN); if (dev && dev->enabled) { @@ -342,17 +301,12 @@ static AGESA_STATUS amd_init_late(void) AcpiSlit, AcpiWheaMce, AcpiWheaCmc, AcpiAlib, AcpiIvrs, __func__); - amd_release_struct(&AmdParamStruct); return Status; } -static AGESA_STATUS amd_init_rtb(void) +static AGESA_STATUS amd_init_rtb(AMD_RTB_PARAMS *RtbParams) { AGESA_STATUS Status; - AMD_INTERFACE_PARAMS AmdParamStruct; - - AMD_RTB_PARAMS *RtbParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_RTB, NULL, 0); timestamp_add_now(TS_AGESA_INIT_RTB_START); Status = amd_dispatch(RtbParams); @@ -364,20 +318,14 @@ static AGESA_STATUS amd_init_rtb(void) RtbParams->S3DataBlock.VolatileStorageSize)) printk(BIOS_ERR, "S3 data not saved, resuming impossible\n"); - amd_release_struct(&AmdParamStruct); - return Status; } -static AGESA_STATUS amd_init_resume(void) +static AGESA_STATUS amd_init_resume(AMD_RESUME_PARAMS *InitResumeParams) { AGESA_STATUS status; - AMD_INTERFACE_PARAMS AmdParamStruct; size_t nv_size; - AMD_RESUME_PARAMS *InitResumeParams = amd_create_struct(&AmdParamStruct, - AMD_INIT_RESUME, NULL, 0); - get_s3nv_info(&InitResumeParams->S3DataBlock.NvStorage, &nv_size); InitResumeParams->S3DataBlock.NvStorageSize = nv_size; @@ -385,23 +333,16 @@ static AGESA_STATUS amd_init_resume(void) status = amd_dispatch(InitResumeParams); timestamp_add_now(TS_AGESA_INIT_RESUME_DONE); - amd_release_struct(&AmdParamStruct); - return status; } -static AGESA_STATUS amd_s3late_restore(void) +static AGESA_STATUS amd_s3late_restore(AMD_S3LATE_PARAMS *S3LateParams) { AGESA_STATUS Status; - AMD_S3LATE_PARAMS _S3LateParams; - AMD_INTERFACE_PARAMS AmdParamStruct; size_t vol_size; amd_initcpuio(); - AMD_S3LATE_PARAMS *S3LateParams = amd_create_struct(&AmdParamStruct, - AMD_S3LATE_RESTORE, &_S3LateParams, sizeof(AMD_S3LATE_PARAMS)); - get_s3vol_info(&S3LateParams->S3DataBlock.VolatileStorage, &vol_size); S3LateParams->S3DataBlock.VolatileStorageSize = vol_size; @@ -409,21 +350,14 @@ static AGESA_STATUS amd_s3late_restore(void) Status = amd_dispatch(S3LateParams); timestamp_add_now(TS_AGESA_S3_LATE_DONE); - amd_release_struct(&AmdParamStruct); - return Status; } -static AGESA_STATUS amd_s3final_restore(void) +static AGESA_STATUS amd_s3final_restore(AMD_S3FINAL_PARAMS *S3FinalParams) { AGESA_STATUS Status; - AMD_S3FINAL_PARAMS _S3FinalParams; - AMD_INTERFACE_PARAMS AmdParamStruct; size_t vol_size; - AMD_S3FINAL_PARAMS *S3FinalParams = amd_create_struct(&AmdParamStruct, - AMD_S3FINAL_RESTORE, &_S3FinalParams, sizeof(AMD_S3FINAL_PARAMS)); - get_s3vol_info(&S3FinalParams->S3DataBlock.VolatileStorage, &vol_size); S3FinalParams->S3DataBlock.VolatileStorageSize = vol_size; @@ -431,22 +365,22 @@ static AGESA_STATUS amd_s3final_restore(void) Status = amd_dispatch(S3FinalParams); timestamp_add_now(TS_AGESA_S3_FINAL_DONE); - amd_release_struct(&AmdParamStruct); - return Status; } static AGESA_STATUS romstage_dispatch(AMD_CONFIG_PARAMS *StdHeader) { + void *Params = StdHeader; + switch (StdHeader->Func) { case AMD_INIT_RESET: - return amd_init_reset(); + return amd_init_reset(Params); case AMD_INIT_EARLY: - return amd_init_early(); + return amd_init_early(Params); case AMD_INIT_POST: - return amd_init_post(); + return amd_init_post(Params); case AMD_INIT_RESUME: - return amd_init_resume(); + return amd_init_resume(Params); default: return AGESA_UNSUPPORTED; } @@ -454,22 +388,25 @@ static AGESA_STATUS romstage_dispatch(AMD_CONFIG_PARAMS *StdHeader) static AGESA_STATUS ramstage_dispatch(AMD_CONFIG_PARAMS *StdHeader) { + void *Params = StdHeader; + switch (StdHeader->Func) { case AMD_INIT_ENV: - return amd_init_env(); + return amd_init_env(Params); case AMD_INIT_MID: - return amd_init_mid(); + return amd_init_mid(Params); case AMD_INIT_LATE: - return amd_init_late(); + return amd_init_late(Params); case AMD_INIT_RTB: - return amd_init_rtb(); + return amd_init_rtb(Params); case AMD_S3LATE_RESTORE: - return amd_s3late_restore(); + return amd_s3late_restore(Params); case AMD_S3FINAL_RESTORE: - return amd_s3final_restore(); + return amd_s3final_restore(Params); default: return AGESA_UNSUPPORTED; } + } AGESA_STATUS agesa_execute_state(AGESA_STRUCT_NAME func) @@ -477,7 +414,23 @@ AGESA_STATUS agesa_execute_state(AGESA_STRUCT_NAME func) AGESA_STATUS status = AGESA_UNSUPPORTED; AMD_CONFIG_PARAMS template = {}; AMD_CONFIG_PARAMS *StdHeader = &template; + AMD_INTERFACE_PARAMS AmdParamStruct; + AMD_INTERFACE_PARAMS *aip = &AmdParamStruct; + union { + AMD_RESET_PARAMS ResetParams; + AMD_S3LATE_PARAMS S3LateParams; + AMD_S3FINAL_PARAMS S3FinalParams; + } sp; + + if ((func == AMD_INIT_RESET) || (func == AMD_S3LATE_RESTORE) || + (func == AMD_S3FINAL_RESTORE)) { + memset(&sp, 0, sizeof(sp)); + amd_create_struct(aip, func, &sp, sizeof(sp)); + } else { + amd_create_struct(aip, func, NULL, 0); + } + StdHeader = aip->NewStructPtr; StdHeader->Func = func; if (ENV_ROMSTAGE) @@ -485,5 +438,6 @@ AGESA_STATUS agesa_execute_state(AGESA_STRUCT_NAME func) if (ENV_RAMSTAGE) status = ramstage_dispatch(StdHeader); + amd_release_struct(aip); return status; } From d93531bcc8a216d9bc82a7f13444833943a270d7 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 30 Apr 2019 12:52:29 -0600 Subject: [PATCH 386/588] soc/intel/cannonlake: Dump ME f/w version and status information At the end of device enable, print the ME f/w version number. Before resume or loading payload, dump the ME's Host Firmware Status registers. BUG=b:131437724 BRANCH=none TEST=Prints seemingly sane values on WHL and CML devices. Change-Id: Ibeb3a2a85cd84c9baa45f90f20a3dcf69f7d5646 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32527 Reviewed-by: Paul Fagerburg Reviewed-by: Furquan Shaikh Reviewed-by: Subrata Banik Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/Makefile.inc | 1 + src/soc/intel/cannonlake/finalize.c | 3 + src/soc/intel/cannonlake/include/soc/me.h | 21 ++ src/soc/intel/cannonlake/me.c | 299 ++++++++++++++++++++++ 4 files changed, 324 insertions(+) create mode 100644 src/soc/intel/cannonlake/include/soc/me.h create mode 100644 src/soc/intel/cannonlake/me.c diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc index 7ad0c7c82c4..13289448b6a 100644 --- a/src/soc/intel/cannonlake/Makefile.inc +++ b/src/soc/intel/cannonlake/Makefile.inc @@ -43,6 +43,7 @@ ramstage-y += gspi.c ramstage-y += i2c.c ramstage-y += lockdown.c ramstage-y += lpc.c +ramstage-y += me.c ramstage-y += memmap.c ramstage-y += nhlt.c ramstage-y += p2sb.c diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c index 4dfd15bc4a6..eb4c5c2c9d4 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -94,6 +95,8 @@ static void soc_finalize(void *unused) { printk(BIOS_DEBUG, "Finalizing chipset.\n"); + dump_me_status(); + pch_finalize(); printk(BIOS_DEBUG, "Finalizing SMM.\n"); diff --git a/src/soc/intel/cannonlake/include/soc/me.h b/src/soc/intel/cannonlake/include/soc/me.h new file mode 100644 index 00000000000..1d782c153c8 --- /dev/null +++ b/src/soc/intel/cannonlake/include/soc/me.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _CANNONLAKE_ME_H_ +#define _CANNONLAKE_ME_H_ + +void dump_me_status(void); + +#endif /* _CANNONLAKE_ME_H_ */ diff --git a/src/soc/intel/cannonlake/me.c b/src/soc/intel/cannonlake/me.c new file mode 100644 index 00000000000..3fedc6374e8 --- /dev/null +++ b/src/soc/intel/cannonlake/me.c @@ -0,0 +1,299 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Google LLC. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Miscellaneous constants */ +enum { + MKHI_GEN_GROUP_ID = 0xFF, + MKHI_GET_FW_VERSION = 0x02, + ME_OPMODE_NORMAL = 0x00, + ME_WSTATE_NORMAL = 0x05, +}; + +/* HFSTS register offsets in PCI config space */ +enum { + PCI_ME_HFSTS1 = 0x40, + PCI_ME_HFSTS2 = 0x48, + PCI_ME_HFSTS3 = 0x60, + PCI_ME_HFSTS4 = 0x64, + PCI_ME_HFSTS5 = 0x68, + PCI_ME_HFSTS6 = 0x6C, +}; + +/* Host Firmware Status Register 1 */ +union hfsts1 { + uint32_t raw; + struct { + uint32_t working_state : 4; + uint32_t mfg_mode : 1; + uint32_t fpt_bad : 1; + uint32_t operation_state : 3; + uint32_t fw_init_complete : 1; + uint32_t ft_bup_ld_flr : 1; + uint32_t fw_upd_in_progress : 1; + uint32_t error_code : 4; + uint32_t operation_mode : 4; + uint32_t reset_count : 4; + uint32_t boot_options : 1; + uint32_t rsvd0 : 1; + uint32_t bist_state : 1; + uint32_t bist_reset_req : 1; + uint32_t power_source : 2; + uint32_t reserved1 : 1; + uint32_t d0i3_support_valid : 1; + } __packed fields; +}; + +/* Host Firmware Status Register 2 */ +union hfsts2 { + uint32_t raw; + struct { + uint32_t nftp_load_failure : 1; + uint32_t icc_prog_status : 2; + uint32_t invoke_mebx : 1; + uint32_t cpu_replaced : 1; + uint32_t rsvd0 : 1; + uint32_t mfs_failure : 1; + uint32_t warm_reset_rqst : 1; + uint32_t cpu_replaced_valid : 1; + uint32_t low_power_state : 1; + uint32_t me_power_gate : 1; + uint32_t ipu_needed : 1; + uint32_t forced_safe_boot : 1; + uint32_t rsvd1 : 2; + uint32_t listener_change : 1; + uint32_t status_data : 8; + uint32_t current_pmevent : 4; + uint32_t phase : 4; + } __packed fields; +}; + +/* Host Firmware Status Register 3 */ +union hfsts3 { + uint32_t raw; +}; + +/* Host Firmware Status Register 4 */ +union hfsts4 { + uint32_t raw; + struct { + uint32_t rsvd0 : 9; + uint32_t enforcement_flow : 1; + uint32_t sx_resume_type : 1; + uint32_t rsvd1 : 1; + uint32_t tpms_disconnected : 1; + uint32_t rvsd2 : 1; + uint32_t fwsts_valid : 1; + uint32_t boot_guard_self_test : 1; + uint32_t rsvd3 : 16; + } __packed fields; +}; + +/* Host Firmware Status Register 5 */ +union hfsts5 { + uint32_t raw; + struct { + uint32_t acm_active : 1; + uint32_t valid : 1; + uint32_t result_code_source : 1; + uint32_t error_status_code : 5; + uint32_t acm_done_sts : 1; + uint32_t timeout_count : 7; + uint32_t scrtm_indicator : 1; + uint32_t inc_boot_guard_acm : 4; + uint32_t inc_key_manifest : 4; + uint32_t inc_boot_policy : 4; + uint32_t rsvd0 : 2; + uint32_t start_enforcement : 1; + } __packed fields; +}; + +/* Host Firmware Status Register 6 */ +union hfsts6 { + uint32_t raw; + struct { + uint32_t force_boot_guard_acm : 1; + uint32_t cpu_debug_disable : 1; + uint32_t bsp_init_disable : 1; + uint32_t protect_bios_env : 1; + uint32_t rsvd0 : 2; + uint32_t error_enforce_policy : 2; + uint32_t measured_boot : 1; + uint32_t verified_boot : 1; + uint32_t boot_guard_acmsvn : 4; + uint32_t kmsvn : 4; + uint32_t bpmsvn : 4; + uint32_t key_manifest_id : 4; + uint32_t boot_policy_status : 1; + uint32_t error : 1; + uint32_t boot_guard_disable : 1; + uint32_t fpf_disable : 1; + uint32_t fpf_soc_lock : 1; + uint32_t txt_support : 1; + } __packed fields; +}; + +static uint32_t me_read_config32(int offset) +{ + return pci_read_config32(PCH_DEV_CSE, offset); +} + +/* + * From reading the documentation, this should work for both WHL and CML + * platforms. Also, calling this function from dump_me_status() does not + * work, as the ME does not respond and the command times out. + */ +static void print_me_version(void *unused) +{ + struct mkhi_hdr { + uint8_t group_id; + uint8_t command :7; + uint8_t is_resp :1; + uint8_t rsvd; + uint8_t result; + } __packed; + + struct version { + uint16_t minor; + uint16_t major; + uint16_t build; + uint16_t hotfix; + } __packed; + + struct fw_ver_resp { + struct mkhi_hdr hdr; + struct version code; + struct version rec; + struct version fitc; + } __packed; + + union hfsts1 hfsts1; + const struct mkhi_hdr fw_ver_msg = { + .group_id = MKHI_GEN_GROUP_ID, + .command = MKHI_GET_FW_VERSION, + }; + struct fw_ver_resp resp; + size_t resp_size = sizeof(resp); + + /* Ignore if UART debugging is disabled */ + if (!CONFIG(CONSOLE_SERIAL)) + return; + + hfsts1.raw = me_read_config32(PCI_ME_HFSTS1); + + /* + * Prerequisites: + * 1) HFSTS1 Current Working State is Normal + * 2) HFSTS1 Current Operation Mode is Normal + * 3) It's after DRAM INIT DONE message (taken care of by calling it + * during ramstage + */ + if ((hfsts1.fields.working_state != ME_WSTATE_NORMAL) || + (hfsts1.fields.operation_mode != ME_OPMODE_NORMAL)) + goto fail; + + heci_reset(); + + if (!heci_send(&fw_ver_msg, sizeof(fw_ver_msg), BIOS_HOST_ADDR, + HECI_MKHI_ADDR)) + goto fail; + + if (!heci_receive(&resp, &resp_size)) + goto fail; + + if (resp.hdr.result) + goto fail; + + printk(BIOS_DEBUG, "ME: Version: %d.%d.%d.%d\n", resp.code.major, + resp.code.minor, resp.code.hotfix, resp.code.build); + return; + +fail: + printk(BIOS_DEBUG, "ME: Version: Unavailable\n"); +} +BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_version, NULL); + +void dump_me_status(void) +{ + union hfsts1 hfsts1; + union hfsts2 hfsts2; + union hfsts3 hfsts3; + union hfsts4 hfsts4; + union hfsts5 hfsts5; + union hfsts6 hfsts6; + + hfsts1.raw = me_read_config32(PCI_ME_HFSTS1); + hfsts2.raw = me_read_config32(PCI_ME_HFSTS2); + hfsts3.raw = me_read_config32(PCI_ME_HFSTS3); + hfsts4.raw = me_read_config32(PCI_ME_HFSTS4); + hfsts5.raw = me_read_config32(PCI_ME_HFSTS5); + hfsts6.raw = me_read_config32(PCI_ME_HFSTS6); + + printk(BIOS_DEBUG, "ME: HFSTS1 : 0x%08X\n", + hfsts1.raw); + printk(BIOS_DEBUG, "ME: HFSTS2 : 0x%08X\n", + hfsts2.raw); + printk(BIOS_DEBUG, "ME: HFSTS3 : 0x%08X\n", + hfsts3.raw); + printk(BIOS_DEBUG, "ME: HFSTS4 : 0x%08X\n", + hfsts4.raw); + printk(BIOS_DEBUG, "ME: HFSTS5 : 0x%08X\n", + hfsts5.raw); + printk(BIOS_DEBUG, "ME: HFSTS6 : 0x%08X\n", + hfsts6.raw); + + printk(BIOS_DEBUG, "ME: Manufacturing Mode : %s\n", + hfsts1.fields.mfg_mode ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: FW Partition Table : %s\n", + hfsts1.fields.fpt_bad ? "BAD" : "OK"); + printk(BIOS_DEBUG, "ME: Bringup Loader Failure : %s\n", + hfsts1.fields.ft_bup_ld_flr ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Firmware Init Complete : %s\n", + hfsts1.fields.fw_init_complete ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Boot Options Present : %s\n", + hfsts1.fields.boot_options ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Update In Progress : %s\n", + hfsts1.fields.fw_upd_in_progress ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: D0i3 Support : %s\n", + hfsts1.fields.d0i3_support_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Low Power State Enabled : %s\n", + hfsts2.fields.low_power_state ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replaced : %s\n", + hfsts2.fields.cpu_replaced ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: CPU Replacement Valid : %s\n", + hfsts2.fields.cpu_replaced_valid ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: Current Working State : %u\n", + hfsts1.fields.working_state); + printk(BIOS_DEBUG, "ME: Current Operation State : %u\n", + hfsts1.fields.operation_state); + printk(BIOS_DEBUG, "ME: Current Operation Mode : %u\n", + hfsts1.fields.operation_mode); + printk(BIOS_DEBUG, "ME: Error Code : %u\n", + hfsts1.fields.error_code); + printk(BIOS_DEBUG, "ME: CPU Debug Disabled : %s\n", + hfsts6.fields.cpu_debug_disable ? "YES" : "NO"); + printk(BIOS_DEBUG, "ME: TXT Support : %s\n", + hfsts6.fields.txt_support ? "YES" : "NO"); +} From fa40e822700f78489a3cd8be65365a9e7249eecf Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 22:26:08 +0200 Subject: [PATCH 387/588] util/sconfig: Move 'static' at beginning of declaration When using -Werror=old-style-declaration, gcc reports an error: "'static' is not at beginning of declaration" Tested on 945G-M4 board. Change-Id: I7216a4fab2d5878066c871166e6a481d1f201a9d Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32900 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Paul Menzel --- util/sconfig/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/sconfig/main.c b/util/sconfig/main.c index c3aa17f1a05..548063fd883 100644 --- a/util/sconfig/main.c +++ b/util/sconfig/main.c @@ -701,7 +701,7 @@ static void pass0(FILE *fil, struct device *ptr, struct device *next) return; } - fprintf(fil, "DEVTREE_CONST static struct device %s;\n", ptr->name); + fprintf(fil, "static DEVTREE_CONST struct device %s;\n", ptr->name); if (ptr->res) fprintf(fil, "DEVTREE_CONST struct resource %s_res[];\n", ptr->name); From 402fe20e3e10f0f2aa1329eb60970e56bf92986e Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Tue, 12 Feb 2019 22:22:42 +0100 Subject: [PATCH 388/588] mb/up/squared: Add mainboard Works: - bootblock, romstage, ramstage - Serial console UART0, UART1 - SPI flash console - iGPU init with libgfxinit - LAN1, LAN2 - USB2, USB3 - HDMI, DisplayPort - eMMC - flashing with flashrom externally WIP: - Documentation - VGA For some reason Seabios can not find the CBFS region and therefore it can't load seavgabios, but generally it is working as soon as Linux is booted. - ACPI Works not: - Devices needs proper configuration - Seabios can't find CBFS region Untested: - GPIO pin header - 60 pin EXHAT - Camera interface - MIPI-CSI2 2-lane (2MP) - MIPI-CSI2 4-lane (8MP) - SATA3 - USB3 OTG - embedded DisplayPort - M.2 slot - mini PCIe - flashing with flashrom internally using Linux Change-Id: Ia913534ec176fc600fcd4ce3af335ebe682b0ed4 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/31378 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/mainboard/index.md | 4 + Documentation/mainboard/up/squared/bottom.jpg | Bin 0 -> 38689 bytes Documentation/mainboard/up/squared/index.md | 99 +++ Documentation/mainboard/up/squared/top.jpg | Bin 0 -> 33925 bytes src/mainboard/up/Kconfig | 16 + src/mainboard/up/Kconfig.name | 2 + src/mainboard/up/squared/Kconfig | 88 ++ src/mainboard/up/squared/Kconfig.name | 2 + src/mainboard/up/squared/Makefile.inc | 7 + src/mainboard/up/squared/acpi_tables.c | 0 src/mainboard/up/squared/board_info.txt | 7 + src/mainboard/up/squared/bootblock.c | 22 + src/mainboard/up/squared/data.vbt | Bin 0 -> 6154 bytes src/mainboard/up/squared/devicetree.cb | 50 ++ src/mainboard/up/squared/dsdt.asl | 43 + src/mainboard/up/squared/gma-mainboard.ads | 32 + src/mainboard/up/squared/gpio.h | 773 ++++++++++++++++++ src/mainboard/up/squared/ramstage.c | 432 ++++++++++ src/mainboard/up/squared/romstage.c | 96 +++ src/mainboard/up/squared/upsquared.fmd | 21 + src/mainboard/up/squared/vboot-ro.fmd | 35 + src/mainboard/up/squared/vboot-roa.fmd | 40 + src/mainboard/up/squared/vboot-roab.fmd | 45 + 23 files changed, 1814 insertions(+) create mode 100644 Documentation/mainboard/up/squared/bottom.jpg create mode 100644 Documentation/mainboard/up/squared/index.md create mode 100644 Documentation/mainboard/up/squared/top.jpg create mode 100644 src/mainboard/up/Kconfig create mode 100644 src/mainboard/up/Kconfig.name create mode 100644 src/mainboard/up/squared/Kconfig create mode 100644 src/mainboard/up/squared/Kconfig.name create mode 100644 src/mainboard/up/squared/Makefile.inc create mode 100644 src/mainboard/up/squared/acpi_tables.c create mode 100644 src/mainboard/up/squared/board_info.txt create mode 100644 src/mainboard/up/squared/bootblock.c create mode 100644 src/mainboard/up/squared/data.vbt create mode 100644 src/mainboard/up/squared/devicetree.cb create mode 100644 src/mainboard/up/squared/dsdt.asl create mode 100644 src/mainboard/up/squared/gma-mainboard.ads create mode 100644 src/mainboard/up/squared/gpio.h create mode 100644 src/mainboard/up/squared/ramstage.c create mode 100644 src/mainboard/up/squared/romstage.c create mode 100644 src/mainboard/up/squared/upsquared.fmd create mode 100644 src/mainboard/up/squared/vboot-ro.fmd create mode 100644 src/mainboard/up/squared/vboot-roa.fmd create mode 100644 src/mainboard/up/squared/vboot-roab.fmd diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index fb637c423b5..eced74966e9 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -82,3 +82,7 @@ The boards in this section are not real mainboards, but emulators. ## Supermicro - [X10SLM+-F](supermicro/x10slm-f.md) + +## UP + +- [Squared](up/squared/index.md) diff --git a/Documentation/mainboard/up/squared/bottom.jpg b/Documentation/mainboard/up/squared/bottom.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f9aa85db50a25d26594360c1c0f7ef44c6cc6907 GIT binary patch literal 38689 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" +./util/scripts/config --set-str IFD_BIN_PATH "" +make olddefconfig +``` + +### Flashing + +[overview_top]: top.jpg +[overview_bottom]: bottom.jpg diff --git a/Documentation/mainboard/up/squared/top.jpg b/Documentation/mainboard/up/squared/top.jpg new file mode 100644 index 0000000000000000000000000000000000000000..71adf459b733337d5ff6652ab415ddd2e4efff25 GIT binary patch literal 33925 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 literal 0 HcmV?d00001 diff --git a/src/mainboard/up/Kconfig b/src/mainboard/up/Kconfig new file mode 100644 index 00000000000..04e290c0ae7 --- /dev/null +++ b/src/mainboard/up/Kconfig @@ -0,0 +1,16 @@ +if VENDOR_UP + +choice + prompt "Mainboard model" + +source "src/mainboard/up/*/Kconfig.name" + +endchoice + +source "src/mainboard/up/*/Kconfig" + +config MAINBOARD_VENDOR + string + default "UP" + +endif diff --git a/src/mainboard/up/Kconfig.name b/src/mainboard/up/Kconfig.name new file mode 100644 index 00000000000..ef694d30f97 --- /dev/null +++ b/src/mainboard/up/Kconfig.name @@ -0,0 +1,2 @@ +config VENDOR_UP + bool "UP" diff --git a/src/mainboard/up/squared/Kconfig b/src/mainboard/up/squared/Kconfig new file mode 100644 index 00000000000..fd03b7a2ae5 --- /dev/null +++ b/src/mainboard/up/squared/Kconfig @@ -0,0 +1,88 @@ +if BOARD_UP_SQUARED + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select USE_BLOBS + select ADD_FSP_BINARIES + select FSP_USE_REPO + select HAVE_ACPI_TABLES + select HAVE_ACPI_RESUME + select INTEL_GMA_HAVE_VBT + select INTEL_LPSS_UART_FOR_CONSOLE + select SOC_INTEL_APOLLOLAKE + select BOARD_ROMSIZE_KB_16384 + select ONBOARD_VGA_IS_PRIMARY + select MAINBOARD_HAS_LIBGFXINIT + +config VBOOT + select VBOOT_NO_BOARD_SUPPORT + select GBB_FLAG_DISABLE_LID_SHUTDOWN + select GBB_FLAG_DISABLE_EC_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_PD_SOFTWARE_SYNC + select GBB_FLAG_DISABLE_FWMP + +config GBB_HWID + string + depends on VBOOT + default "UPSQUARED" + +config MAINBOARD_DIR + string + default "up/squared" + +config MAINBOARD_VENDOR + string + default "Up" + +config MAINBOARD_PART_NUMBER + string + default "Squared" + +config FMDFILE + string + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/upsquared.fmd" if !VBOOT + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-ro.fmd" if !VBOOT_SLOTS_RW_A + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-roa.fmd" if VBOOT_SLOTS_RW_A && !VBOOT_SLOTS_RW_AB + default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-roab.fmd" if VBOOT_SLOTS_RW_AB + +config SUBSYSTEM_VENDOR_ID + hex + default 0x8086 + +config SUBSYSTEM_DEVICE_ID + hex + default 0x7270 + +config VGA_BIOS_ID + string + default "8086,5a85" + +config PXE_ROM_ID + string + default "10ec,8168" + +config MAX_CPUS + int + default 2 + +config UART_FOR_CONSOLE + int + default 0 + +config IFWI_FMAP_NAME + string + default "IFWI" + +config POST_IO + bool + default n + +config POST_DEVICE + bool + default n + +config CONSOLE_POST + bool + default y + +endif diff --git a/src/mainboard/up/squared/Kconfig.name b/src/mainboard/up/squared/Kconfig.name new file mode 100644 index 00000000000..4d6a59bb7c6 --- /dev/null +++ b/src/mainboard/up/squared/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_UP_SQUARED + bool "Squared" diff --git a/src/mainboard/up/squared/Makefile.inc b/src/mainboard/up/squared/Makefile.inc new file mode 100644 index 00000000000..af2508e8cf6 --- /dev/null +++ b/src/mainboard/up/squared/Makefile.inc @@ -0,0 +1,7 @@ +bootblock-y += bootblock.c + +romstage-y += romstage.c + +ramstage-y += ramstage.c + +ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads diff --git a/src/mainboard/up/squared/acpi_tables.c b/src/mainboard/up/squared/acpi_tables.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/mainboard/up/squared/board_info.txt b/src/mainboard/up/squared/board_info.txt new file mode 100644 index 00000000000..851af32a781 --- /dev/null +++ b/src/mainboard/up/squared/board_info.txt @@ -0,0 +1,7 @@ +Vendor name: Up +Board name: Squared +Category: mini +ROM protocol: SPI +ROM socketed: n +Flashrom support: n +Release year: 2017 diff --git a/src/mainboard/up/squared/bootblock.c b/src/mainboard/up/squared/bootblock.c new file mode 100644 index 00000000000..e35e8b8e7f2 --- /dev/null +++ b/src/mainboard/up/squared/bootblock.c @@ -0,0 +1,22 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +void bootblock_mainboard_init(void) +{ + lpc_configure_pads(); +} diff --git a/src/mainboard/up/squared/data.vbt b/src/mainboard/up/squared/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..a8b5550108122e4967cbade00c0bd227e15a1328 GIT binary patch literal 6154 zcmeHLZ)_Ar6o0$h`!~CLy>3y;QOoehaxKtq3mm0ZyVonF2Q9s8ORdqQ*K&t67Fyb( zMZ~VLBuxzFKBz%Mw8j_>erck9GDiHMk`SdeQNt%o&;*GjBx3XfaK72y_S$0810jm^ zUEa={nYX`r^XARW+gsIA)l91z8(Nzic2J9ApaRMH37sHZw68zjcgSBKywHUZ)l{|p{77n)0X8p6Et45j2zK`z?CpGVPe1hq z3uq~hv(CUZOs2u^-ku^F=<1@4Os9`F#{1&EPsd|LGGRa`!I{AUa5l(12^?H21#AGP z1{oS?C;(&tXgHu%%oy6Jc!1x?@z|a31bfb8KScrI1uQ)HKC4=k0blL`j|VOyHpMoF z+3o=kN6`|CH25}(TF$GM78X2qdC*i-%TT43w%cW5Sye2iW2IVWYfbN&F4O6iIpu$< zCEy&cK8x_yv^n4y0k}C8cDwRmtKfrvfrsaXGFXvu3Y;zqYg`_91UZ6y+D70zx@zm!dAT*OXjOq ztDa1{qFCjP(701ia+(FQNy+5hE=k$24fnF(tQg8Q=CTuG@GV(@0U%kp$t+T&$)GeE z7QG2}ui53OnADkF{+m5sb~r5kl^=5u7;{|VhO_^h(rlm2T~8*nESg(qq32%qKyEF3 z@6r==;sK8{y2A8C-mSGPdjfA(o&y(N_&nI~fROOgu7+9&O!F}Iaj+blYEjKpF`8;o zGYYG~2Nd5jnpozbVbz6=HlP$T`Ds9ZBl^5JaNmrM6BYp!yaK{QgtilRx;gWiJMls zm57@>?v@LAo6b*gdY0Qrbez2so;|I+WRzDp507zXVpn2ipO5t%nKSFE?XaUGqbB6sULXLk>F!D1*z!hf*6_~EgJqxuE zjzvJ#)Sm1q8(63yNdq=-S_lI);`L~rX$V}xb`uEi7Y|HCy!l$|v6Ky5!fqgF_R%zK zsIAo0j?q$0JDEbTn;DSQVoS%9yO+0|h(MlNld#r;c`{+#ooGrret51ZF%tFWX)3kW z0#`F5fjKOCQg@^?3txpk(lfde5enH`0El2q7%LeAbZR3gOI@e zXn3;BhzAzrb4N8_uIKD8Tc@?IORa?fnFazLV)ps>MS%uU9kQbyPZoR2w1Iu8pbd33 z;kI!5zIfM;_Pz1{L4{3fCark^?AuOZPJZIfJwKX7{482~9~`YgvqG4u?}RYKU@i9= zTo8&z0fwjOt`OH7r-13=4StN=1O}3^r)IhxZ +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x02, // DSDT revision: ACPI v2.0 and up + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 // OEM revision +) +{ + /* global NVS and variables */ + #include + + /* CPU */ + #include + + Scope (\_SB) { + Device (PCI0) + { + #include + #include + #include + } + } + + /* Chipset specific sleep states */ + #include +} diff --git a/src/mainboard/up/squared/gma-mainboard.ads b/src/mainboard/up/squared/gma-mainboard.ads new file mode 100644 index 00000000000..6865970e167 --- /dev/null +++ b/src/mainboard/up/squared/gma-mainboard.ads @@ -0,0 +1,32 @@ +-- +-- This file is part of the coreboot project. +-- +-- This program is free software; you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation; either version 2 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- + +with HW.GFX.GMA; +with HW.GFX.GMA.Display_Probing; + +use HW.GFX.GMA; +use HW.GFX.GMA.Display_Probing; + +private package GMA.Mainboard is + + ports : constant Port_List := + (DP1, + DP2, + DP3, + HDMI1, + HDMI2, + HDMI3, + others => Disabled); + +end GMA.Mainboard; diff --git a/src/mainboard/up/squared/gpio.h b/src/mainboard/up/squared/gpio.h new file mode 100644 index 00000000000..b4ac4e9b6d2 --- /dev/null +++ b/src/mainboard/up/squared/gpio.h @@ -0,0 +1,773 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Felix Singer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#include + +#ifndef GPIO_H +#define GPIO_H + +static const struct pad_config gpio_table[] = { + // ******************************** + // ******* GPIO Group North ******* + // ******************************** + // *GPIO + _PAD_CFG_STRUCT(GPIO_0, 0x04000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_1, 0x04000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_2, 0x04000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_3, 0x04000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_4, 0x04000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_5, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_6, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_7, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_8, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_9, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_10, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_11, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_12, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_13, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_14, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_15, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_16, 0x40880102, 0x00024000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_17, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_18, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_19, 0x44000201, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_20, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_21, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_22, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_23, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_24, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_25, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_26, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_27, 0x44000201, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_28, 0x44000102, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_29, 0x44000102, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_30, 0x44000102, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_31, 0x44000102, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_32, 0x44000102, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_33, 0x44000102, 0x00000000), + + // PWM0 + _PAD_CFG_STRUCT(GPIO_34, 0x44000400, 0x00001000), + + // PWM1 + _PAD_CFG_STRUCT(GPIO_35, 0x44000400, 0x00001000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_36, 0x44000201, 0x00000000), + + // PWM3 + _PAD_CFG_STRUCT(GPIO_37, 0x04000400, 0x00001000), + + // LPSS_UART0_RXD + _PAD_CFG_STRUCT(GPIO_38, 0x44000402, 0x00023100), + + // LPSS_UART0_TXD + _PAD_CFG_STRUCT(GPIO_39, 0x44000400, 0x00003100), + + // LPSS_UART0_RTS_N + _PAD_CFG_STRUCT(GPIO_40, 0x44000400, 0x00003100), + + // LPSS_UART0_CTS_N + _PAD_CFG_STRUCT(GPIO_41, 0x44000402, 0x00023100), + + // LPSS_UART1_RXD + _PAD_CFG_STRUCT(GPIO_42, 0x44000402, 0x00023100), + + // LPSS_UART1_TXD + _PAD_CFG_STRUCT(GPIO_43, 0x44000400, 0x0001f100), + + // LPSS_UART1_RTS_N + _PAD_CFG_STRUCT(GPIO_44, 0x44000400, 0x00003100), + + // LPSS_UART1_CTS_N + _PAD_CFG_STRUCT(GPIO_45, 0x44000402, 0x0001c100), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_46, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_47, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_48, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_49, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_62, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_63, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_64, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_65, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_66, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_67, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_68, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_69, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_70, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_71, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_72, 0x44000200, 0x00001000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_73, 0x44000200, 0x00001000), + + // *JTAG_TCK + _PAD_CFG_STRUCT(TCK, 0x44000400, 0x00c3d000), + + // *JTAG_TRST_N + _PAD_CFG_STRUCT(TRST_B, 0x44000400, 0x00c3d000), + + // *JTAG_TMS + _PAD_CFG_STRUCT(TMS, 0x44000400, 0x00c3f000), + + // *JTAG_TDI + _PAD_CFG_STRUCT(TDI, 0x44000400, 0x00c3f000), + + // *JTAG_PMODE + _PAD_CFG_STRUCT(CX_PMODE, 0x44000400, 0x00c3c000), + + // *JTAG_PREQ_N + _PAD_CFG_STRUCT(CX_PREQ_B, 0x44000402, 0x00c3f000), + + // *JTAGX + _PAD_CFG_STRUCT(JTAGX, 0x44000402, 0x00c3f000), + + // *JTAG_PRDY_N + _PAD_CFG_STRUCT(CX_PRDY_B, 0x44000402, 0x0043f000), + + // *JTAG_TDO + _PAD_CFG_STRUCT(TDO, 0x44000400, 0x0043f000), + + // GPIO + _PAD_CFG_STRUCT(CNV_BRI_DT, 0x44000201, 0x0003d000), + + // GPIO + _PAD_CFG_STRUCT(CNV_BRI_RSP, 0x44000201, 0x00002400), + + // GPIO + _PAD_CFG_STRUCT(CNV_RGI_DT, 0x44000201, 0x00000000), + + // RESERVED +// _PAD_CFG_STRUCT(CNV_RGI_RSP, 0xffffffff, 0xffffffff), + + // GPIO + _PAD_CFG_STRUCT(SVID0_ALERT_B, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(SVID0_DATA, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(SVID0_CLK, 0x44000100, 0x00000000), + + + // ************************************ + // ******* GPIO Group NorthWest ******* + // ************************************ + // *DDI0_DDC_SDA + _PAD_CFG_STRUCT(GPIO_187, 0x44000400, 0x0001f000), + + // *DDI0_DDC_SCL + _PAD_CFG_STRUCT(GPIO_188, 0x44000400, 0x0001f000), + + // *DDI1_DDC_SDA + _PAD_CFG_STRUCT(GPIO_189, 0x44000400, 0x00002c00), + + // *DDI1_DDC_SCL + _PAD_CFG_STRUCT(GPIO_190, 0x44000400, 0x00002c00), + + // GPIO + _PAD_CFG_STRUCT(GPIO_191, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_192, 0x44000100, 0x00000000), + + // *PNL0_VDDEN + _PAD_CFG_STRUCT(GPIO_193, 0x44000400, 0x00005000), + + // *PNL0_BKLTEN + _PAD_CFG_STRUCT(GPIO_194, 0x44000400, 0x00005000), + + // *PNL0_BKLTCTL + _PAD_CFG_STRUCT(GPIO_195, 0x44000400, 0x00005000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_196, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_197, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_198, 0x44000100, 0x00000000), + + // DDI1_HPD + _PAD_CFG_STRUCT(GPIO_199, 0x44000800, 0x00003000), + + // DDI0_HPD + _PAD_CFG_STRUCT(GPIO_200, 0x44000802, 0x00003000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_201, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_202, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_203, 0x44000102, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_204, 0x44000102, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMC_SPI_FS0, 0x44000102, 0x00000000), + + // DDI2_HPD + _PAD_CFG_STRUCT(PMC_SPI_FS1, 0x44000802, 0x00003000), + + // GPIO + _PAD_CFG_STRUCT(PMC_SPI_FS2, 0x44000102, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMC_SPI_RXD, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMC_SPI_TXD, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMC_SPI_CLK, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMIC_PWRGOOD, 0x44000203, 0x00002400), + + // GPIO + _PAD_CFG_STRUCT(PMIC_RESET_B, 0x44000102, 0x0003c000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_213, 0x44000201, 0x00003000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_214, 0x44000102, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_215, 0x44000100, 0x00000000), + + // *THERMTRIP_N + _PAD_CFG_STRUCT(PMIC_THERMTRIP_B, 0x44000400, 0x00003000), + + // GPIO + _PAD_CFG_STRUCT(PMIC_STDBY, 0x44000201, 0x00001000), + + // *PROCHOT_N + _PAD_CFG_STRUCT(PROCHOT_B, 0x44000402, 0x00023000), + + // RESERVED +// _PAD_CFG_STRUCT(PMIC_I2C_SCL, 0xffffffff, 0xffffffff), + + // RESERVED +// _PAD_CFG_STRUCT(PMIC_I2C_SDA, 0xffffffff, 0xffffffff), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_74, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_75, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_76, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_77, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_78, 0x44000100, 0x00000000), + + // AVS_DMIC_CLK_A1 + _PAD_CFG_STRUCT(GPIO_79, 0x44000400, 0x0003d000), + + // AVS_DMIC_CLK_B1 + _PAD_CFG_STRUCT(GPIO_80, 0x44000400, 0x0003d000), + + // AVS_DMIC_DATA_1 + _PAD_CFG_STRUCT(GPIO_81, 0x44000400, 0x00025200), + + // AVS_DMIC_CLK_AB2 + _PAD_CFG_STRUCT(GPIO_82, 0x44000400, 0x0003d000), + + // AVS_DMIC_DATA_2 + _PAD_CFG_STRUCT(GPIO_83, 0x44000400, 0x00025200), + + // AVS_I2S2_MCLK + _PAD_CFG_STRUCT(GPIO_84, 0x44000400, 0x00001000), + + // AVS_I2S2_BCLK + _PAD_CFG_STRUCT(GPIO_85, 0x44000400, 0x0001d200), + + // AVS_I2S2_WS_SYNC + _PAD_CFG_STRUCT(GPIO_86, 0x44000402, 0x0001d200), + + // AVS_I2S2_SDI + _PAD_CFG_STRUCT(GPIO_87, 0x44000402, 0x0001f200), + + // AVS_I2S2_SDO + _PAD_CFG_STRUCT(GPIO_88, 0x44000400, 0x0001c200), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_89, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_90, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_91, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_92, 0x44000100, 0x00000000), + + // *FST_SPI_CS0_N + _PAD_CFG_STRUCT(GPIO_97, 0x44000402, 0x0003fc00), + + // GPIO + _PAD_CFG_STRUCT(GPIO_98, 0x44000100, 0x00000000), + + // *FST_SPI_MOSI_IO0 + _PAD_CFG_STRUCT(GPIO_99, 0x44000400, 0x0003fc00), + + // *FST_SPI_MISO_IO1 + _PAD_CFG_STRUCT(GPIO_100, 0x44000402, 0x0003fc00), + + // GPIO + _PAD_CFG_STRUCT(GPIO_101, 0x44000100, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_102, 0x44000100, 0x00000000), + + // *FST_SPI_CLK + _PAD_CFG_STRUCT(GPIO_103, 0x44000400, 0x0003fc00), + + // *n/a + _PAD_CFG_STRUCT(FST_SPI_CLK_FB, 0x44000400, 0x0003c000), + + // SIO_SPI_0_CLK + _PAD_CFG_STRUCT(GPIO_104, 0x44000400, 0x0001d200), + + // SIO_SPI_0_FS0 + _PAD_CFG_STRUCT(GPIO_105, 0x44000400, 0x0001f200), + + // SIO_SPI_0_FS1 + _PAD_CFG_STRUCT(GPIO_106, 0x44000400, 0x0001f200), + + // SIO_SPI_0_RXD + _PAD_CFG_STRUCT(GPIO_109, 0x44000402, 0x0001f200), + + // SIO_SPI_0_TXD + _PAD_CFG_STRUCT(GPIO_110, 0x44000400, 0x0001f200), + + // SIO_SPI_1_CLK + _PAD_CFG_STRUCT(GPIO_111, 0x44000400, 0x00001000), + + // SIO_SPI_1_FS0 + _PAD_CFG_STRUCT(GPIO_112, 0x44000400, 0x00001000), + + // SIO_SPI_1_FS1 + _PAD_CFG_STRUCT(GPIO_113, 0x44000400, 0x00001000), + + // SIO_SPI_1_RXD + _PAD_CFG_STRUCT(GPIO_116, 0x44000402, 0x0001d000), + + // SIO_SPI_1_TXD + _PAD_CFG_STRUCT(GPIO_117, 0x44000400, 0x00001000), + + // SIO_SPI_2_CLK + _PAD_CFG_STRUCT(GPIO_118, 0x44000400, 0x00001000), + + // SIO_SPI_2_FS0 + _PAD_CFG_STRUCT(GPIO_119, 0x44000400, 0x00001000), + + // SIO_SPI_2_FS1 + _PAD_CFG_STRUCT(GPIO_120, 0x44000400, 0x00001000), + + // SIO_SPI_2_FS2 + _PAD_CFG_STRUCT(GPIO_121, 0x44000400, 0x00001000), + + // SIO_SPI_2_RXD + _PAD_CFG_STRUCT(GPIO_122, 0x44000400, 0x00001000), + + // SIO_SPI_2_TXD + _PAD_CFG_STRUCT(GPIO_123, 0x44000400, 0x00001000), + + + // ******************************* + // ******* GPIO Group West ******* + // ******************************* + // LPSS_I2C0_SDA + _PAD_CFG_STRUCT(GPIO_124, 0x44000402, 0x00012700), + + // LPSS_I2C0_SCL + _PAD_CFG_STRUCT(GPIO_125, 0x44000402, 0x00012700), + + // LPSS_I2C1_SDA + _PAD_CFG_STRUCT(GPIO_126, 0x44000402, 0x00012700), + + // LPSS_I2C1_SCL + _PAD_CFG_STRUCT(GPIO_127, 0x44000402, 0x00012700), + + // LPSS_I2C2_SDA + _PAD_CFG_STRUCT(GPIO_128, 0x44000402, 0x00012700), + + // LPSS_I2C2_SCL + _PAD_CFG_STRUCT(GPIO_129, 0x44000402, 0x00012700), + + // LPSS_I2C3_SDA + _PAD_CFG_STRUCT(GPIO_130, 0x44000402, 0x00012700), + + // LPSS_I2C3_SCL + _PAD_CFG_STRUCT(GPIO_131, 0x44000402, 0x00012700), + + // LPSS_I2C4_SDA + _PAD_CFG_STRUCT(GPIO_132, 0x44000402, 0x00012700), + + // LPSS_I2C4_SCL + _PAD_CFG_STRUCT(GPIO_133, 0x44000402, 0x00012700), + + // LPSS_I2C5_SDA + _PAD_CFG_STRUCT(GPIO_134, 0x44000402, 0x0001f200), + + // LPSS_I2C5_SCL + _PAD_CFG_STRUCT(GPIO_135, 0x44000402, 0x0001f200), + + // LPSS_I2C6_SDA + _PAD_CFG_STRUCT(GPIO_136, 0x44000402, 0x0001f200), + + // LPSS_I2C6_SCL + _PAD_CFG_STRUCT(GPIO_137, 0x44000402, 0x0001f200), + + // LPSS_I2C7_SDA + _PAD_CFG_STRUCT(GPIO_138, 0x44000402, 0x00006700), + + // LPSS_I2C7_SCL + _PAD_CFG_STRUCT(GPIO_139, 0x44000402, 0x00006700), + + // AVS_I2S6_BCLK + _PAD_CFG_STRUCT(GPIO_146, 0x44000800, 0x0003d000), + + // AVS_I2S6_WS_SYNC + _PAD_CFG_STRUCT(GPIO_147, 0x44000800, 0x0003d000), + + // AVS_I2S6_SDI + _PAD_CFG_STRUCT(GPIO_148, 0x44000802, 0x0003d000), + + // AVS_I2S6_SDO + _PAD_CFG_STRUCT(GPIO_149, 0x44000800, 0x0003d000), + + // AVS_I2S5_BCLK + _PAD_CFG_STRUCT(GPIO_150, 0x44000800, 0x0001d200), + + // AVS_I2S5_WS_SYNC + _PAD_CFG_STRUCT(GPIO_151, 0x44000800, 0x0001d200), + + // AVS_I2S5_SDI + _PAD_CFG_STRUCT(GPIO_152, 0x44000802, 0x0001d200), + + // AVS_I2S5_SDO + _PAD_CFG_STRUCT(GPIO_153, 0x44000800, 0x0001c200), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_154, 0x44000102, 0x00000000), + + // SPKR + _PAD_CFG_STRUCT(GPIO_155, 0x44000800, 0x0003d000), + + // *PCIE_CLKREQ0_N + _PAD_CFG_STRUCT(GPIO_209, 0x44000400, 0x00001000), + + // *PCIE_CLKREQ1_N + _PAD_CFG_STRUCT(GPIO_210, 0x44000400, 0x00001000), + + // *PCIE_CLKREQ2_N + _PAD_CFG_STRUCT(GPIO_211, 0x44000400, 0x00001000), + + // *PCIE_CLKREQ3_N + _PAD_CFG_STRUCT(GPIO_212, 0x44000400, 0x00001000), + + // *OSC_CLK_OUT_0 + _PAD_CFG_STRUCT(OSC_CLK_OUT_0, 0x44000400, 0x00001000), + + // *OSC_CLK_OUT_1 + _PAD_CFG_STRUCT(OSC_CLK_OUT_1, 0x44000400, 0x00001000), + + // *OSC_CLK_OUT_2 + _PAD_CFG_STRUCT(OSC_CLK_OUT_2, 0x44000400, 0x00001000), + + // *OSC_CLK_OUT_3 + _PAD_CFG_STRUCT(OSC_CLK_OUT_3, 0x44000400, 0x00001000), + + // GPIO + _PAD_CFG_STRUCT(OSC_CLK_OUT_4, 0x44000100, 0x00000000), + + // *GPIO + _PAD_CFG_STRUCT(PMU_AC_PRESENT, 0x44000102, 0x00000000), + + // GPIO + _PAD_CFG_STRUCT(PMU_BATLOW_B, 0x44000102, 0x00000000), + + // *PMU_PLTRST_N + _PAD_CFG_STRUCT(PMU_PLTRST_B, 0x44000400, 0x0003c000), + + // *PMU_PWRBTN_N + _PAD_CFG_STRUCT(PMU_PWRBTN_B, 0x44000402, 0x0003f000), + + // *PMU_RSTBTN_N + _PAD_CFG_STRUCT(PMU_RESETBUTTON_B, 0x44000402, 0x0003c000), + + // *PMU_SLP_S0_N + _PAD_CFG_STRUCT(PMU_SLP_S0_B, 0x44000400, 0x0003c000), + + // *PMU_SLP_S3_N + _PAD_CFG_STRUCT(PMU_SLP_S3_B, 0x44000400, 0x0003c000), + + // *PMU_SLP_S4_N + _PAD_CFG_STRUCT(PMU_SLP_S4_B, 0x44000400, 0x0003c000), + + // *PMU_SUSCLK + _PAD_CFG_STRUCT(PMU_SUSCLK, 0x44000400, 0x0003c000), + + // *GPIO + _PAD_CFG_STRUCT(PMU_WAKE_B, 0x44000201, 0x0003f000), + + // *SUS_STAT_B + _PAD_CFG_STRUCT(SUS_STAT_B, 0x44000400, 0x0003c000), + + // GPIO + _PAD_CFG_STRUCT(SUSPWRDNACK, 0x44000102, 0x00000000), + + + // ************************************ + // ******* GPIO Group SouthWest ******* + // ************************************ + // PCIE_WAKE0_N + _PAD_CFG_STRUCT(GPIO_205, 0x44000402, 0x00000000), + + // PCIE_WAKE1_N + _PAD_CFG_STRUCT(GPIO_206, 0x44000402, 0x00000000), + + // PCIE_WAKE2_N + _PAD_CFG_STRUCT(GPIO_207, 0x44000402, 0x00000000), + + // PCIE_WAKE3_N + _PAD_CFG_STRUCT(GPIO_208, 0x44000402, 0x00000000), + + // *EMMC_CLK + _PAD_CFG_STRUCT(GPIO_156, 0x44000402, 0x00005000), + + // *EMMC_D0 + _PAD_CFG_STRUCT(GPIO_157, 0x44000402, 0x00023000), + + // *EMMC_D1 + _PAD_CFG_STRUCT(GPIO_158, 0x44000402, 0x00023000), + + // *EMMC_D2 + _PAD_CFG_STRUCT(GPIO_159, 0x44000402, 0x00023000), + + // *EMMC_D3 + _PAD_CFG_STRUCT(GPIO_160, 0x44000402, 0x00023000), + + // *EMMC_D4 + _PAD_CFG_STRUCT(GPIO_161, 0x44000402, 0x00023000), + + // *EMMC_D5 + _PAD_CFG_STRUCT(GPIO_162, 0x44000402, 0x00023000), + + // *EMMC_D6 + _PAD_CFG_STRUCT(GPIO_163, 0x44000402, 0x00023000), + + // *EMMC_D7 + _PAD_CFG_STRUCT(GPIO_164, 0x44000402, 0x00023000), + + // *EMMC_CMD + _PAD_CFG_STRUCT(GPIO_165, 0x44000402, 0x00023000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_166, 0x44000300, 0x00001000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_167, 0x44000102, 0x00023000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_168, 0x44000100, 0x00023000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_169, 0x44000200, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_170, 0x44000201, 0x00003000), + + // *GPIO + _PAD_CFG_STRUCT(GPIO_171, 0x44000201, 0x00003000), + + // SDCARD_CLK + _PAD_CFG_STRUCT(GPIO_172, 0x44000400, 0x00021100), + + // n/a + _PAD_CFG_STRUCT(GPIO_179, 0x44000400, 0x00001000), + + // SDCARD_D0 + _PAD_CFG_STRUCT(GPIO_173, 0x44000402, 0x00023100), + + // SDCARD_D1 + _PAD_CFG_STRUCT(GPIO_174, 0x44000402, 0x00023000), + + // SDCARD_D2 + _PAD_CFG_STRUCT(GPIO_175, 0x44000402, 0x00023000), + + // SDCARD_D3 + _PAD_CFG_STRUCT(GPIO_176, 0x44000402, 0x00023000), + + // SDCARD_CD_B + _PAD_CFG_STRUCT(GPIO_177, 0x44000402, 0x00003000), + + // SDCARD_CMD + _PAD_CFG_STRUCT(GPIO_178, 0x44000402, 0x00023100), + + // SDCARD_LVL_WP + _PAD_CFG_STRUCT(GPIO_186, 0x44000402, 0x00003000), + + // *EMMC_RCLK + _PAD_CFG_STRUCT(GPIO_182, 0x44000400, 0x0001d000), + + // GPIO + _PAD_CFG_STRUCT(GPIO_183, 0x44000200, 0x00001000), + + // SMB_ALERT_N + _PAD_CFG_STRUCT(SMB_ALERTB, 0x44000402, 0x0003f000), + + // SMB_CLK + _PAD_CFG_STRUCT(SMB_CLK, 0x44000402, 0x0003f000), + + // SMB_DATA + _PAD_CFG_STRUCT(SMB_DATA, 0x44000402, 0x0003f000), + + // LPC_ILB_SERIRQ + _PAD_CFG_STRUCT(LPC_ILB_SERIRQ, 0x44000402, 0x0003f000), + + // LPC_CLKOUT0 + _PAD_CFG_STRUCT(LPC_CLKOUT0, 0x44000400, 0x00020100), + + // LPC_CLKOUT1 + _PAD_CFG_STRUCT(LPC_CLKOUT1, 0x44000400, 0x00020100), + + // LPC_AD0 + _PAD_CFG_STRUCT(LPC_AD0, 0x44000402, 0x00023100), + + // LPC_AD1 + _PAD_CFG_STRUCT(LPC_AD1, 0x44000402, 0x00023100), + + // LPC_AD2 + _PAD_CFG_STRUCT(LPC_AD2, 0x44000402, 0x00023100), + + // LPC_AD3 + _PAD_CFG_STRUCT(LPC_AD3, 0x44000402, 0x00023100), + + // LPC_CLKRUNB + _PAD_CFG_STRUCT(LPC_CLKRUNB, 0x44000400, 0x00023100), + + // LPC_FRAMEB + _PAD_CFG_STRUCT(LPC_FRAMEB, 0x44000400, 0x00023100), +}; + +#endif diff --git a/src/mainboard/up/squared/ramstage.c b/src/mainboard/up/squared/ramstage.c new file mode 100644 index 00000000000..e9fcfb2da34 --- /dev/null +++ b/src/mainboard/up/squared/ramstage.c @@ -0,0 +1,432 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Felix Singer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +void mainboard_silicon_init_params(FSP_S_CONFIG *silconfig) +{ + printk(BIOS_DEBUG, "MAINBOARD: %s/%s called\n", __FILE__, __func__); + + silconfig->C1e = 0x1; // 0x0 + silconfig->PkgCStateLimit = 0xFE; // 0x2 + silconfig->CStateAutoDemotion = 0x3; // 0x0 + silconfig->CStateUnDemotion = 0x3; // 0x0 + silconfig->PkgCStateDemotion = 0x1; // 0x0 + silconfig->PkgCStateUnDemotion = 0x1; // 0x0 + silconfig->IpuEn = 0x0; // 0x1 + silconfig->Pme = 0x1; // 0x0 + silconfig->HdAudioIoBufferOwnership = 0x3; // 0x0 + silconfig->DspEndpointDmic = 0x0; // 0x1 + silconfig->DspEndpointBluetooth = 0x0; // 0x1 + silconfig->DspEndpointI2sSkp = 0x1; // 0x0 + silconfig->DspEndpointI2sHp = 0x1; // 0x0 + silconfig->HDAudioPwrGate = 0x1; // 0x0 + silconfig->HDAudioClkGate = 0x1; // 0x0 + silconfig->DspFeatureMask = 0x2A; // 0x0 + silconfig->HpetBdfValid = 0x1; // 0x0 + silconfig->HpetDeviceNumber = 0xF; // 0x1f + silconfig->IoApicBdfValid = 0x1; // 0x0 + silconfig->IoApicDeviceNumber = 0x1F; // 0xf + silconfig->IshEnable = 0x0; // 0x1 + silconfig->SpiEiss = 0x0; // 0x1 + silconfig->LPSS_S0ixEnable = 0x1; // 0x0 + silconfig->SdcardEnabled = 0x0; // 0x1 + silconfig->eMMCHostMaxSpeed = 0x2; // 0x0 + silconfig->Usb30Mode = 0x1; // 0x0 + silconfig->VtdEnable = 0x1; // 0x0 + silconfig->MonitorMwaitEnable = 0x0; // 0x1 + silconfig->HdAudioDspUaaCompliance = 0x1; // 0x0 + silconfig->InitS3Cpu = 0x1; // 0x0 + + silconfig->PortUsb20PerPortTxPeHalf[0] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[0] = 0x7; + silconfig->PortUsb20PerPortTxiSet[0] = 0x0; + silconfig->PortUsb20HsSkewSel[0] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[0] = 0x3; + silconfig->PortUsb20PerPortRXISet[0] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[0] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[1] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[1] = 0x6; + silconfig->PortUsb20PerPortTxiSet[1] = 0x0; + silconfig->PortUsb20HsSkewSel[1] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[1] = 0x3; + silconfig->PortUsb20PerPortRXISet[1] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[1] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[2] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[2] = 0x6; + silconfig->PortUsb20PerPortTxiSet[2] = 0x0; + silconfig->PortUsb20HsSkewSel[2] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[2] = 0x3; + silconfig->PortUsb20PerPortRXISet[2] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[2] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[3] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[3] = 0x6; + silconfig->PortUsb20PerPortTxiSet[3] = 0x0; + silconfig->PortUsb20HsSkewSel[3] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[3] = 0x3; + silconfig->PortUsb20PerPortRXISet[3] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[3] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[4] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[4] = 0x7; + silconfig->PortUsb20PerPortTxiSet[4] = 0x0; + silconfig->PortUsb20HsSkewSel[4] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[4] = 0x3; + silconfig->PortUsb20PerPortRXISet[4] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[4] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[5] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[5] = 0x7; + silconfig->PortUsb20PerPortTxiSet[5] = 0x0; + silconfig->PortUsb20HsSkewSel[5] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[5] = 0x3; + silconfig->PortUsb20PerPortRXISet[5] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[5] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[6] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[6] = 0x7; + silconfig->PortUsb20PerPortTxiSet[6] = 0x0; + silconfig->PortUsb20HsSkewSel[6] = 0x0; + silconfig->PortUsb20IUsbTxEmphasisEn[6] = 0x3; + silconfig->PortUsb20PerPortRXISet[6] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[6] = 0x0; + + silconfig->PortUsb20PerPortTxPeHalf[7] = 0x0; + silconfig->PortUsb20PerPortPeTxiSet[7] = 0x1; + silconfig->PortUsb20PerPortTxiSet[7] = 0x3; + silconfig->PortUsb20HsSkewSel[7] = 0x1; + silconfig->PortUsb20IUsbTxEmphasisEn[7] = 0x1; + silconfig->PortUsb20PerPortRXISet[7] = 0x0; + silconfig->PortUsb20HsNpreDrvSel[7] = 0x3; + + + silconfig->WriteProtectionEnable[0] = 0x1; + silconfig->ReadProtectionEnable[0] = 0x1; + silconfig->ProtectedRangeLimit[0] = 0xFFF; + silconfig->ProtectedRangeBase[0] = 0x0; + + silconfig->IPC[0] = 0xFFFFEEF8; + silconfig->IPC[1] = 0xFFFFFFFF; + silconfig->IPC[2] = 0xFFFFFFFF; + silconfig->IPC[3] = 0xFFFFFFFF; + + silconfig->SataPortsDisableDynamicPg[0] = 0x0; + silconfig->SataPortsEnable[0] = 0x1; + silconfig->SataPortsDevSlp[0] = 0x0; + silconfig->SataPortsHotPlug[0] = 0x0; + silconfig->SataPortsInterlockSw[0] = 0x1; + silconfig->SataPortsExternal[0] = 0x0; + silconfig->SataPortsSpinUp[0] = 0x0; + silconfig->SataPortsSolidStateDrive[0] = 0x0; + silconfig->SataPortsEnableDitoConfig[0] = 0x0; + silconfig->SataPortsDmVal[0] = 0xF; + silconfig->SataPortsDitoVal[0] = 0x271; + + silconfig->SataPortsDisableDynamicPg[1] = 0x0; + silconfig->SataPortsEnable[1] = 0x1; + silconfig->SataPortsDevSlp[1] = 0x0; + silconfig->SataPortsHotPlug[1] = 0x0; + silconfig->SataPortsInterlockSw[1] = 0x1; + silconfig->SataPortsExternal[1] = 0x0; + silconfig->SataPortsSpinUp[1] = 0x0; + silconfig->SataPortsSolidStateDrive[1] = 0x0; + silconfig->SataPortsEnableDitoConfig[1] = 0x0; + silconfig->SataPortsDmVal[1] = 0xF; + silconfig->SataPortsDitoVal[1] = 0x271; + + + silconfig->PcieRootPortEn[0] = 0x1; + silconfig->PcieRpHide[0] = 0x0; + silconfig->PcieRpSlotImplemented[0] = 0x1; + silconfig->PcieRpHotPlug[0] = 0x0; + silconfig->PcieRpPmSci[0] = 0x1; + silconfig->PcieRpExtSync[0] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[0] = 0x0; + silconfig->PcieRpAcsEnabled[0] = 0x1; + silconfig->PcieRpClkReqSupported[0] = 0x1; + silconfig->PcieRpClkReqNumber[0] = 0x2; + silconfig->PcieRpClkReqDetect[0] = 0x0; + silconfig->AdvancedErrorReporting[0] = 0x0; + silconfig->PmeInterrupt[0] = 0x0; + silconfig->UnsupportedRequestReport[0] = 0x0; + silconfig->FatalErrorReport[0] = 0x0; + silconfig->NoFatalErrorReport[0] = 0x0; + silconfig->CorrectableErrorReport[0] = 0x0; + silconfig->SystemErrorOnFatalError[0] = 0x0; + silconfig->SystemErrorOnNonFatalError[0] = 0x0; + silconfig->SystemErrorOnCorrectableError[0] = 0x0; + silconfig->PcieRpSpeed[0] = 0x0; + silconfig->PhysicalSlotNumber[0] = 0x0; + silconfig->PcieRpCompletionTimeout[0] = 0x0; + silconfig->PtmEnable[0] = 0x0; + silconfig->PcieRpAspm[0] = 0x4; + silconfig->PcieRpL1Substates[0] = 0x3; + silconfig->PcieRpLtrEnable[0] = 0x1; + silconfig->PcieRpLtrConfigLock[0] = 0x0; + silconfig->PcieRpSelectableDeemphasis[0] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[0] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[0] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[0] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[0] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[0] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[0] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[0] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[0] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[0] = 0x3C; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[0] = 0x2; + + silconfig->PcieRootPortEn[1] = 0x1; + silconfig->PcieRpHide[1] = 0x0; + silconfig->PcieRpSlotImplemented[1] = 0x1; + silconfig->PcieRpHotPlug[1] = 0x0; + silconfig->PcieRpPmSci[1] = 0x1; + silconfig->PcieRpExtSync[1] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[1] = 0x0; + silconfig->PcieRpAcsEnabled[1] = 0x1; + silconfig->PcieRpClkReqSupported[1] = 0x1; + silconfig->PcieRpClkReqNumber[1] = 0x3; + silconfig->PcieRpClkReqDetect[1] = 0x0; + silconfig->AdvancedErrorReporting[1] = 0x0; + silconfig->PmeInterrupt[1] = 0x0; + silconfig->UnsupportedRequestReport[1] = 0x0; + silconfig->FatalErrorReport[1] = 0x0; + silconfig->NoFatalErrorReport[1] = 0x0; + silconfig->CorrectableErrorReport[1] = 0x0; + silconfig->SystemErrorOnFatalError[1] = 0x0; + silconfig->SystemErrorOnNonFatalError[1] = 0x0; + silconfig->SystemErrorOnCorrectableError[1] = 0x0; + silconfig->PcieRpSpeed[1] = 0x0; + silconfig->PhysicalSlotNumber[1] = 0x1; + silconfig->PcieRpCompletionTimeout[1] = 0x0; + silconfig->PtmEnable[1] = 0x0; + silconfig->PcieRpAspm[1] = 0x4; + silconfig->PcieRpL1Substates[1] = 0x3; + silconfig->PcieRpLtrEnable[1] = 0x1; + silconfig->PcieRpLtrConfigLock[1] = 0x0; + silconfig->PcieRpSelectableDeemphasis[1] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[1] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[1] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[1] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[1] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[1] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[1] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[1] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[1] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[1] = 0x3C; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[1] = 0x2; + + silconfig->PcieRootPortEn[2] = 0x1; + silconfig->PcieRpHide[2] = 0x0; + silconfig->PcieRpSlotImplemented[2] = 0x1; + silconfig->PcieRpHotPlug[2] = 0x0; + silconfig->PcieRpPmSci[2] = 0x1; + silconfig->PcieRpExtSync[2] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[2] = 0x0; + silconfig->PcieRpAcsEnabled[2] = 0x1; + silconfig->PcieRpClkReqSupported[2] = 0x1; + silconfig->PcieRpClkReqNumber[2] = 0x0; + silconfig->PcieRpClkReqDetect[2] = 0x0; + silconfig->AdvancedErrorReporting[2] = 0x0; + silconfig->PmeInterrupt[2] = 0x0; + silconfig->UnsupportedRequestReport[2] = 0x0; + silconfig->FatalErrorReport[2] = 0x0; + silconfig->NoFatalErrorReport[2] = 0x0; + silconfig->CorrectableErrorReport[2] = 0x0; + silconfig->SystemErrorOnFatalError[2] = 0x0; + silconfig->SystemErrorOnNonFatalError[2] = 0x0; + silconfig->SystemErrorOnCorrectableError[2] = 0x0; + silconfig->PcieRpSpeed[2] = 0x0; + silconfig->PhysicalSlotNumber[2] = 0x2; + silconfig->PcieRpCompletionTimeout[2] = 0x0; + silconfig->PtmEnable[2] = 0x0; + silconfig->PcieRpAspm[2] = 0x4; + silconfig->PcieRpL1Substates[2] = 0x3; + silconfig->PcieRpLtrEnable[2] = 0x1; + silconfig->PcieRpLtrConfigLock[2] = 0x0; + silconfig->PcieRpSelectableDeemphasis[2] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[2] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[2] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[2] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[2] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[2] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[2] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[2] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[2] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[2] = 0x0; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[2] = 0x2; + + silconfig->PcieRootPortEn[3] = 0x1; + silconfig->PcieRpHide[3] = 0x0; + silconfig->PcieRpSlotImplemented[3] = 0x1; + silconfig->PcieRpHotPlug[3] = 0x0; + silconfig->PcieRpPmSci[3] = 0x1; + silconfig->PcieRpExtSync[3] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[3] = 0x0; + silconfig->PcieRpAcsEnabled[3] = 0x1; + silconfig->PcieRpClkReqSupported[3] = 0x1; + silconfig->PcieRpClkReqNumber[3] = 0x1; + silconfig->PcieRpClkReqDetect[3] = 0x0; + silconfig->AdvancedErrorReporting[3] = 0x0; + silconfig->PmeInterrupt[3] = 0x0; + silconfig->UnsupportedRequestReport[3] = 0x0; + silconfig->FatalErrorReport[3] = 0x0; + silconfig->NoFatalErrorReport[3] = 0x0; + silconfig->CorrectableErrorReport[3] = 0x0; + silconfig->SystemErrorOnFatalError[3] = 0x0; + silconfig->SystemErrorOnNonFatalError[3] = 0x0; + silconfig->SystemErrorOnCorrectableError[3] = 0x0; + silconfig->PcieRpSpeed[3] = 0x0; + silconfig->PhysicalSlotNumber[3] = 0x3; + silconfig->PcieRpCompletionTimeout[3] = 0x0; + silconfig->PtmEnable[3] = 0x0; + silconfig->PcieRpAspm[3] = 0x4; + silconfig->PcieRpL1Substates[3] = 0x3; + silconfig->PcieRpLtrEnable[3] = 0x1; + silconfig->PcieRpLtrConfigLock[3] = 0x0; + silconfig->PcieRpSelectableDeemphasis[3] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[3] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[3] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[3] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[3] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[3] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[3] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[3] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[3] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[3] = 0x3C; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[3] = 0x2; + + silconfig->PcieRootPortEn[4] = 0x1; + silconfig->PcieRpHide[4] = 0x0; + silconfig->PcieRpSlotImplemented[4] = 0x1; + silconfig->PcieRpHotPlug[4] = 0x0; + silconfig->PcieRpPmSci[4] = 0x1; + silconfig->PcieRpExtSync[4] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[4] = 0x0; + silconfig->PcieRpAcsEnabled[4] = 0x1; + silconfig->PcieRpClkReqSupported[4] = 0x1; + silconfig->PcieRpClkReqNumber[4] = 0x2; + silconfig->PcieRpClkReqDetect[4] = 0x0; + silconfig->AdvancedErrorReporting[4] = 0x0; + silconfig->PmeInterrupt[4] = 0x0; + silconfig->UnsupportedRequestReport[4] = 0x0; + silconfig->FatalErrorReport[4] = 0x0; + silconfig->NoFatalErrorReport[4] = 0x0; + silconfig->CorrectableErrorReport[4] = 0x0; + silconfig->SystemErrorOnFatalError[4] = 0x0; + silconfig->SystemErrorOnNonFatalError[4] = 0x0; + silconfig->SystemErrorOnCorrectableError[4] = 0x0; + silconfig->PcieRpSpeed[4] = 0x0; + silconfig->PhysicalSlotNumber[4] = 0x4; + silconfig->PcieRpCompletionTimeout[4] = 0x0; + silconfig->PtmEnable[4] = 0x0; + silconfig->PcieRpAspm[4] = 0x4; + silconfig->PcieRpL1Substates[4] = 0x3; + silconfig->PcieRpLtrEnable[4] = 0x1; + silconfig->PcieRpLtrConfigLock[4] = 0x0; + silconfig->PcieRpSelectableDeemphasis[4] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[4] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[4] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[4] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[4] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[4] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[4] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[4] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[4] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[4] = 0x3C; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[4] = 0x2; + + silconfig->PcieRootPortEn[5] = 0x1; + silconfig->PcieRpHide[5] = 0x0; + silconfig->PcieRpSlotImplemented[5] = 0x1; + silconfig->PcieRpHotPlug[5] = 0x0; + silconfig->PcieRpPmSci[5] = 0x1; + silconfig->PcieRpExtSync[5] = 0x1; + silconfig->PcieRpTransmitterHalfSwing[5] = 0x0; + silconfig->PcieRpAcsEnabled[5] = 0x1; + silconfig->PcieRpClkReqSupported[5] = 0x1; + silconfig->PcieRpClkReqNumber[5] = 0x3; + silconfig->PcieRpClkReqDetect[5] = 0x0; + silconfig->AdvancedErrorReporting[5] = 0x0; + silconfig->PmeInterrupt[5] = 0x0; + silconfig->UnsupportedRequestReport[5] = 0x0; + silconfig->FatalErrorReport[5] = 0x0; + silconfig->NoFatalErrorReport[5] = 0x0; + silconfig->CorrectableErrorReport[5] = 0x0; + silconfig->SystemErrorOnFatalError[5] = 0x0; + silconfig->SystemErrorOnNonFatalError[5] = 0x0; + silconfig->SystemErrorOnCorrectableError[5] = 0x0; + silconfig->PcieRpSpeed[5] = 0x0; + silconfig->PhysicalSlotNumber[5] = 0x5; + silconfig->PcieRpCompletionTimeout[5] = 0x0; + silconfig->PtmEnable[5] = 0x0; + silconfig->PcieRpAspm[5] = 0x4; + silconfig->PcieRpL1Substates[5] = 0x3; + silconfig->PcieRpLtrEnable[5] = 0x1; + silconfig->PcieRpLtrConfigLock[5] = 0x0; + silconfig->PcieRpSelectableDeemphasis[5] = 0x1; + silconfig->PcieRpNonSnoopLatencyOverrideValue[5] = 0x3C; + silconfig->PcieRpNonSnoopLatencyOverrideMultiplier[5] = 0x2; + silconfig->PcieRpSlotPowerLimitScale[5] = 0x0; + silconfig->PcieRpSlotPowerLimitValue[5] = 0x0; + silconfig->PcieRpLtrMaxNonSnoopLatency[5] = 0x1003; + silconfig->PcieRpNonSnoopLatencyOverrideMode[5] = 0x2; + silconfig->PcieRpLtrMaxSnoopLatency[5] = 0x1003; + silconfig->PcieRpSnoopLatencyOverrideMode[5] = 0x2; + silconfig->PcieRpSnoopLatencyOverrideValue[5] = 0x3C; + silconfig->PcieRpSnoopLatencyOverrideMultiplier[5] = 0x2; + + + silconfig->SsicRate[0] = 0x1; + silconfig->SsicPortEnable[0] = 0x0; + silconfig->SsicRate[1] = 0x1; + silconfig->SsicPortEnable[1] = 0x0; + + silconfig->PortUsb30Enable[0] = 0x1; + silconfig->PortUs30bOverCurrentPin[0] = 0x0; + silconfig->PortUsb30Enable[1] = 0x1; + silconfig->PortUs30bOverCurrentPin[1] = 0x1; + silconfig->PortUsb30Enable[2] = 0x1; + silconfig->PortUs30bOverCurrentPin[2] = 0x1; + silconfig->PortUsb30Enable[3] = 0x1; + silconfig->PortUs30bOverCurrentPin[3] = 0x1; + silconfig->PortUsb30Enable[4] = 0x1; + silconfig->PortUs30bOverCurrentPin[4] = 0x1; + silconfig->PortUsb30Enable[5] = 0x1; + silconfig->PortUs30bOverCurrentPin[5] = 0x1; + + silconfig->PortUsb20Enable[0] = 0x1; + silconfig->PortUs20bOverCurrentPin[0] = 0x0; + silconfig->PortUsb20Enable[1] = 0x1; + silconfig->PortUs20bOverCurrentPin[1] = 0x1; + silconfig->PortUsb20Enable[2] = 0x1; + silconfig->PortUs20bOverCurrentPin[2] = 0x1; + silconfig->PortUsb20Enable[3] = 0x1; + silconfig->PortUs20bOverCurrentPin[3] = 0x1; + silconfig->PortUsb20Enable[4] = 0x1; + silconfig->PortUs20bOverCurrentPin[4] = 0x1; + silconfig->PortUsb20Enable[5] = 0x1; + silconfig->PortUs20bOverCurrentPin[5] = 0x1; + silconfig->PortUsb20Enable[6] = 0x1; + silconfig->PortUs20bOverCurrentPin[6] = 0x2; + silconfig->PortUsb20Enable[7] = 0x1; + silconfig->PortUs20bOverCurrentPin[7] = 0x2; +} diff --git a/src/mainboard/up/squared/romstage.c b/src/mainboard/up/squared/romstage.c new file mode 100644 index 00000000000..2cfaa0064aa --- /dev/null +++ b/src/mainboard/up/squared/romstage.c @@ -0,0 +1,96 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2019 Felix Singer + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include "gpio.h" + +static const uint8_t ch0_bit_swizzling[] = { + 0x0D, 0x0A, 0x08, 0x0B, 0x0C, 0x0F, 0x0E, 0x09, + 0x06, 0x00, 0x03, 0x04, 0x07, 0x01, 0x05, 0x02, + 0x1C, 0x1A, 0x19, 0x1B, 0x1D, 0x1F, 0x1E, 0x18, + 0x10, 0x17, 0x15, 0x16, 0x14, 0x12, 0x13, 0x11 +}; + +static const uint8_t ch1_bit_swizzling[] = { + 0x00, 0x07, 0x04, 0x05, 0x06, 0x02, 0x03, 0x01, + 0x08, 0x0F, 0x0D, 0x0B, 0x0A, 0x09, 0x0E, 0x0C, + 0x17, 0x11, 0x13, 0x12, 0x14, 0x15, 0x16, 0x10, + 0x1C, 0x1A, 0x1D, 0x1F, 0x18, 0x19, 0x1E, 0x1B +}; + +static const uint8_t ch2_bit_swizzling[] = { + 0x0D, 0x08, 0x0B, 0x0E, 0x0C, 0x0F, 0x09, 0x0A, + 0x04, 0x07, 0x01, 0x06, 0x02, 0x03, 0x00, 0x05, + 0x18, 0x19, 0x1C, 0x1A, 0x1D, 0x1E, 0x1F, 0x1B, + 0x11, 0x13, 0x15, 0x10, 0x16, 0x12, 0x17, 0x14 +}; + +static const uint8_t ch3_bit_swizzling[] = { + 0x00, 0x05, 0x04, 0x07, 0x03, 0x02, 0x06, 0x01, + 0x0A, 0x0B, 0x08, 0x09, 0x0C, 0x0E, 0x0D, 0x0F, + 0x12, 0x16, 0x14, 0x13, 0x17, 0x11, 0x15, 0x10, + 0x19, 0x1F, 0x1D, 0x1B, 0x1E, 0x18, 0x1C, 0x1A +}; + + +void mainboard_memory_init_params(FSPM_UPD *memupd) +{ + printk(BIOS_DEBUG, "MAINBOARD: %s/%s called\n", __FILE__, __func__); + + gpio_configure_pads(gpio_table, ARRAY_SIZE(gpio_table)); + + memupd->FspmConfig.Package = 0x1; // 0x0 + memupd->FspmConfig.Profile = 0xB; // 0x19 + memupd->FspmConfig.MemoryDown = 0x1; // 0x0 + memupd->FspmConfig.DDR3LPageSize = 0x0; // 0x1 + memupd->FspmConfig.DIMM0SPDAddress = 0x0; // 0xa0 + memupd->FspmConfig.DIMM1SPDAddress = 0x0; // 0xa4 + memupd->FspmConfig.RmtCheckRun = 0x3; // 0x0 + memupd->FspmConfig.RmtMarginCheckScaleHighThreshold = 0xC8; // 0x0 + memupd->FspmConfig.EnhancePort8xhDecoding = 0x0; // 0x1 + memupd->FspmConfig.NpkEn = 0x0; // 0x3 + memupd->FspmConfig.PrimaryVideoAdaptor = 0x2; // 0x0 + + memupd->FspmConfig.Ch0_RankEnable = 0x1; // 0x0 + memupd->FspmConfig.Ch0_DeviceWidth = 0x1; // 0x0 + memupd->FspmConfig.Ch0_DramDensity = 0x2; // 0x0 + memupd->FspmConfig.Ch0_Option = 0x3; // 0x0 + memupd->FspmConfig.Ch1_RankEnable = 0x1; // 0x0 + memupd->FspmConfig.Ch1_DeviceWidth = 0x1; // 0x0 + memupd->FspmConfig.Ch1_DramDensity = 0x2; // 0x0 + memupd->FspmConfig.Ch1_Option = 0x3; // 0x0 + memupd->FspmConfig.Ch2_RankEnable = 0x1; // 0x0 + memupd->FspmConfig.Ch2_DeviceWidth = 0x1; // 0x0 + memupd->FspmConfig.Ch2_DramDensity = 0x2; // 0x0 + memupd->FspmConfig.Ch2_Option = 0x3; // 0x0 + memupd->FspmConfig.Ch3_RankEnable = 0x1; // 0x0 + memupd->FspmConfig.Ch3_DeviceWidth = 0x1; // 0x0 + memupd->FspmConfig.Ch3_DramDensity = 0x2; // 0x0 + memupd->FspmConfig.Ch3_Option = 0x3; // 0x0 + memupd->FspmConfig.StartTimerTickerOfPfetAssert = 0x4E20; // 0x0 + + memcpy(memupd->FspmConfig.Ch0_Bit_swizzling, &ch0_bit_swizzling, + sizeof(ch0_bit_swizzling)); + memcpy(memupd->FspmConfig.Ch1_Bit_swizzling, &ch1_bit_swizzling, + sizeof(ch1_bit_swizzling)); + memcpy(memupd->FspmConfig.Ch2_Bit_swizzling, &ch2_bit_swizzling, + sizeof(ch2_bit_swizzling)); + memcpy(memupd->FspmConfig.Ch3_Bit_swizzling, &ch3_bit_swizzling, + sizeof(ch3_bit_swizzling)); +} diff --git a/src/mainboard/up/squared/upsquared.fmd b/src/mainboard/up/squared/upsquared.fmd new file mode 100644 index 00000000000..4ea1375e108 --- /dev/null +++ b/src/mainboard/up/squared/upsquared.fmd @@ -0,0 +1,21 @@ +FLASH 16M { + SI_DESC@0x0 0x1000 + SI_BIOS@0x1000 0xefe000 { + IFWI@0x0 0x2ff000 + OBB@0x2ff000 0xbff000 { + FMAP@0x0 0x800 + UNIFIED_MRC_CACHE@0x800 0x21000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + RW_VAR_MRC_CACHE@0x20000 0x1000 + } + CONSOLE@0x21800 0x20000 + COREBOOT(CBFS)@0x41800 0xb7d800 + BIOS_UNUSABLE@0xbbf000 0x40000 + } + } + SI_DEVICEEXT@0xeff000 0x101000 { + DEVICE_EXTENSION@0x0 0x100000 + UNUSED_HOLE@0x100000 0x1000 + } +} diff --git a/src/mainboard/up/squared/vboot-ro.fmd b/src/mainboard/up/squared/vboot-ro.fmd new file mode 100644 index 00000000000..72f92fe964d --- /dev/null +++ b/src/mainboard/up/squared/vboot-ro.fmd @@ -0,0 +1,35 @@ +FLASH 16M { + SI_DESC@0x0 0x1000 + SI_BIOS@0x1000 0xefe000 { + WP_RO@0x0 0xe91000 { + IFWI@0x0 0x2ff000 + FMAP@0x2ff000 0x800 + RO_VPD(PRESERVE)@0x2ff800 0x4000 + RO_SECTION@0x303800 0xb8d800 { + RO_FRID@0x0 0x40 + RO_FRID_PAD@0x40 0x7c0 + GBB@0x800 0x40000 + COREBOOT(CBFS)@0x40800 0xb4d000 + } + } + MISC_RW@0xe91000 0x2d000 { + UNIFIED_MRC_CACHE@0x0 0x21000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + RW_VAR_MRC_CACHE@0x20000 0x1000 + } + RW_SHARED@0x21000 0x4000 { + SHARED_DATA@0x0 0x2000 + VBLOCK_DEV@0x2000 0x2000 + } + RW_VPD(PRESERVE)@0x25000 0x2000 + RW_NVRAM(PRESERVE)@0x27000 0x5000 + FPF_STATUS@0x2c000 0x1000 + } + BIOS_UNUSABLE@0xebe000 0x40000 + } + SI_DEVICEEXT@0xeff000 0x101000 { + DEVICE_EXTENSION@0x0 0x100000 + UNUSED_HOLE@0x100000 0x1000 + } +} diff --git a/src/mainboard/up/squared/vboot-roa.fmd b/src/mainboard/up/squared/vboot-roa.fmd new file mode 100644 index 00000000000..330ce037576 --- /dev/null +++ b/src/mainboard/up/squared/vboot-roa.fmd @@ -0,0 +1,40 @@ +FLASH 16M { + SI_DESC@0x0 0x1000 + SI_BIOS@0x1000 0xefe000 { + WP_RO@0x0 0x502000 { + IFWI@0x0 0x2ff000 + FMAP@0x2ff000 0x800 + RO_VPD(PRESERVE)@0x2ff800 0x4000 + RO_SECTION@0x303800 0x1fe800 { + RO_FRID@0x0 0x40 + RO_FRID_PAD@0x40 0x7c0 + GBB@0x800 0x40000 + COREBOOT(CBFS)@0x40800 0x1be000 + } + } + MISC_RW@0x502000 0x2d000 { + UNIFIED_MRC_CACHE@0x0 0x21000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + RW_VAR_MRC_CACHE@0x20000 0x1000 + } + RW_SHARED@0x21000 0x4000 { + SHARED_DATA@0x0 0x2000 + VBLOCK_DEV@0x2000 0x2000 + } + RW_VPD(PRESERVE)@0x25000 0x2000 + RW_NVRAM(PRESERVE)@0x27000 0x5000 + FPF_STATUS@0x2c000 0x1000 + } + RW_SECTION_A@0x52f000 0x98f000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x97efc0 + RW_FWID_A@0x98efc0 0x40 + } + BIOS_UNUSABLE@0xebe000 0x40000 + } + SI_DEVICEEXT@0xeff000 0x101000 { + DEVICE_EXTENSION@0x0 0x100000 + UNUSED_HOLE@0x100000 0x1000 + } +} diff --git a/src/mainboard/up/squared/vboot-roab.fmd b/src/mainboard/up/squared/vboot-roab.fmd new file mode 100644 index 00000000000..4ddcbc0c2ec --- /dev/null +++ b/src/mainboard/up/squared/vboot-roab.fmd @@ -0,0 +1,45 @@ +FLASH 16M { + SI_DESC@0x0 0x1000 + SI_BIOS@0x1000 0xefe000 { + WP_RO@0x0 0x503000 { + IFWI@0x0 0x2ff000 + FMAP@0x2ff000 0x800 + RO_VPD(PRESERVE)@0x2ff800 0x4000 + RO_SECTION@0x303800 0x1ff800 { + RO_FRID@0x0 0x40 + RO_FRID_PAD@0x40 0x7c0 + GBB@0x800 0x40000 + COREBOOT(CBFS)@0x40800 0x1bf000 + } + } + MISC_RW@0x503000 0x2d000 { + UNIFIED_MRC_CACHE@0x0 0x21000 { + RECOVERY_MRC_CACHE@0x0 0x10000 + RW_MRC_CACHE@0x10000 0x10000 + RW_VAR_MRC_CACHE@0x20000 0x1000 + } + RW_SHARED@0x21000 0x4000 { + SHARED_DATA@0x0 0x2000 + VBLOCK_DEV@0x2000 0x2000 + } + RW_VPD(PRESERVE)@0x25000 0x2000 + RW_NVRAM(PRESERVE)@0x27000 0x5000 + FPF_STATUS@0x2c000 0x1000 + } + RW_SECTION_A@0x530000 0x4c7000 { + VBLOCK_A@0x0 0x10000 + FW_MAIN_A(CBFS)@0x10000 0x4b6fc0 + RW_FWID_A@0x4c6fc0 0x40 + } + RW_SECTION_B@0x9f7000 0x4c7000 { + VBLOCK_B@0x0 0x10000 + FW_MAIN_B(CBFS)@0x10000 0x4b6fc0 + RW_FWID_B@0x4c6fc0 0x40 + } + BIOS_UNUSABLE@0xebe000 0x40000 + } + SI_DEVICEEXT@0xeff000 0x101000 { + DEVICE_EXTENSION@0x0 0x100000 + UNUSED_HOLE@0x100000 0x1000 + } +} From ba44a27f7fcc50677e2b0789f61fce2df8f6d620 Mon Sep 17 00:00:00 2001 From: Jett Rink Date: Tue, 21 May 2019 13:48:04 -0600 Subject: [PATCH 389/588] post: during post_code, only call elog when enabled Now that we call post_code in other stages other than RAMSTAGE, we need to guard the elog calls with the appropriate condition in order to compile correctly. Change-Id: I766c276f28d46492fb05e0e3be71853e21f4e8e0 Signed-off-by: Jett Rink Reviewed-on: https://review.coreboot.org/c/coreboot/+/32914 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/console/post.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/console/post.c b/src/console/post.c index b17a819d971..0719e5e7df8 100644 --- a/src/console/post.c +++ b/src/console/post.c @@ -81,7 +81,7 @@ void cmos_post_log(void) default: printk(BIOS_WARNING, "POST: Unexpected post code " "in previous boot: 0x%02x\n", code); -#if CONFIG(ELOG) +#if CONFIG(ELOG) && (ENV_RAMSTAGE || CONFIG(ELOG_PRERAM)) elog_add_event_word(ELOG_TYPE_LAST_POST_CODE, code); #if CONFIG(CMOS_POST_EXTRA) if (extra) From 7006458777483291abfca790beb48f201ba74c37 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Mon, 6 May 2019 16:12:57 -0600 Subject: [PATCH 390/588] post_code: add post code for failure to load next stage Add a new post code, POST_INVALID_ROM, used when coreboot fails to locate or validate a resource that is stored in ROM. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: Ie6de6590595d8fcdc57ad156237fffa03d5ead38 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32770 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin Reviewed-by: Duncan Laurie --- Documentation/POSTCODES | 1 + src/arch/x86/postcar_loader.c | 9 ++++++--- src/include/console/post_codes.h | 7 +++++++ src/lib/prog_loaders.c | 10 ++++++---- src/security/vboot/vboot_logic.c | 6 ++++-- 5 files changed, 24 insertions(+), 9 deletions(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 5d337b629dd..2340fac0492 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -16,6 +16,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0x66 Devices have been enumerated 0x88 Devices have been configured 0x89 Devices have been enabled +0xe0 Boot media (e.g. SPI ROM) is corrupt 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/arch/x86/postcar_loader.c b/src/arch/x86/postcar_loader.c index d62487ef882..e5d0ceab4de 100644 --- a/src/arch/x86/postcar_loader.c +++ b/src/arch/x86/postcar_loader.c @@ -141,13 +141,16 @@ static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf) }; if (prog_locate(prog)) - die("Failed to locate after CAR program.\n"); + die_with_post_code(POST_INVALID_ROM, + "Failed to locate after CAR program.\n"); if (rmodule_stage_load(&rsl)) - die("Failed to load after CAR program.\n"); + die_with_post_code(POST_INVALID_ROM, + "Failed to load after CAR program.\n"); /* Set the stack pointer within parameters of the program loaded. */ if (rsl.params == NULL) - die("No parameters found in after CAR program.\n"); + die_with_post_code(POST_INVALID_ROM, + "No parameters found in after CAR program.\n"); finalize_load(rsl.params, pcf->stack); diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index f482ae9e476..775f78d6039 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -318,6 +318,13 @@ */ #define POST_JUMPING_TO_PAYLOAD 0xf3 +/** + * \brief Invalid or corrupt ROM + * + * Set if firmware failed to find or validate a resource that is stored in ROM. + */ +#define POST_INVALID_ROM 0xe0 + /** * \brief TPM failure * diff --git a/src/lib/prog_loaders.c b/src/lib/prog_loaders.c index 3b77712550a..a21663fc0fb 100644 --- a/src/lib/prog_loaders.c +++ b/src/lib/prog_loaders.c @@ -69,7 +69,8 @@ void run_romstage(void) fail: if (CONFIG(BOOTBLOCK_CONSOLE)) - die("Couldn't load romstage.\n"); + die_with_post_code(POST_INVALID_ROM, + "Couldn't load romstage.\n"); halt(); } @@ -162,7 +163,7 @@ void run_ramstage(void) prog_run(&ramstage); fail: - die("Ramstage was not loaded!\n"); + die_with_post_code(POST_INVALID_ROM, "Ramstage was not loaded!\n"); } #ifdef __RAMSTAGE__ // gc-sections should take care of this @@ -195,13 +196,14 @@ void payload_load(void) break; } /* else fall-through */ default: - die("Unsupported payload type.\n"); + die_with_post_code(POST_INVALID_ROM, + "Unsupported payload type.\n"); break; } out: if (prog_entry(payload) == NULL) - die("Payload not loaded.\n"); + die_with_post_code(POST_INVALID_ROM, "Payload not loaded.\n"); } void payload_run(void) diff --git a/src/security/vboot/vboot_logic.c b/src/security/vboot/vboot_logic.c index d4ad32736b3..626310010c8 100644 --- a/src/security/vboot/vboot_logic.c +++ b/src/security/vboot/vboot_logic.c @@ -320,7 +320,8 @@ void verstage_main(void) if (CONFIG(VBOOT_MEASURED_BOOT) && !(ctx.flags & VB2_CONTEXT_S3_RESUME)) { if (vboot_init_crtm() != VB2_SUCCESS) - die("Initializing measured boot mode failed!"); + die_with_post_code(POST_INVALID_ROM, + "Initializing measured boot mode failed!"); } if (get_recovery_mode_switch()) { @@ -395,7 +396,8 @@ void verstage_main(void) printk(BIOS_INFO, "Phase 4\n"); rv = locate_firmware(&ctx, &fw_main); if (rv) - die("Failed to read FMAP to locate firmware"); + die_with_post_code(POST_INVALID_ROM, + "Failed to read FMAP to locate firmware"); rv = hash_body(&ctx, &fw_main); save_if_needed(&ctx); From 1835bf0fd4b77ab3eae1fb085be1667d13ed3144 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Thu, 16 May 2019 11:46:27 -0600 Subject: [PATCH 391/588] post_code: add post code for critical CBFS failures Add a new post code POST_INVALID_CBFS, used when coreboot fails to locate or validate a resource that is stored in CBFS. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: If1c8b92889040f9acd6250f847db02626809a987 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32771 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/POSTCODES | 1 + src/include/console/post_codes.h | 7 +++++++ src/soc/intel/quark/romstage/fsp2_0.c | 3 ++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 2340fac0492..162e863fede 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -17,6 +17,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0x88 Devices have been configured 0x89 Devices have been enabled 0xe0 Boot media (e.g. SPI ROM) is corrupt +0xe1 Resource stored within CBFS is corrupt 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index 775f78d6039..7bd1ee0798d 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -325,6 +325,13 @@ */ #define POST_INVALID_ROM 0xe0 +/** + * \brief Invalid or corrupt CBFS + * + * Set if firmware failed to find or validate a resource that is stored in CBFS. + */ +#define POST_INVALID_CBFS 0xe1 + /** * \brief TPM failure * diff --git a/src/soc/intel/quark/romstage/fsp2_0.c b/src/soc/intel/quark/romstage/fsp2_0.c index 2ec16c9f341..e4abcc034ad 100644 --- a/src/soc/intel/quark/romstage/fsp2_0.c +++ b/src/soc/intel/quark/romstage/fsp2_0.c @@ -116,7 +116,8 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *fspm_upd, uint32_t version) /* Locate the RMU data file in flash */ rmu_data = locate_rmu_file(&rmu_data_len); if (!rmu_data) - die("Microcode file (rmu.bin) not found."); + die_with_post_code(POST_INVALID_CBFS, + "Microcode file (rmu.bin) not found."); /* Locate the configuration data from devicetree.cb */ dev = pcidev_path_on_root(LPC_DEV_FUNC); From bb41aba0d8c3c3cbfee44b0f7267e78fb7d012ee Mon Sep 17 00:00:00 2001 From: Keith Short Date: Thu, 16 May 2019 14:07:43 -0600 Subject: [PATCH 392/588] post_code: add post code for invalid vendor binary Add a new post code POST_INVALID_VENDOR_BINARY, used when coreboot fails to locate or validate a vendor supplied binary. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: Ib1e359d4e8772c37922b1b779135e58c73bff6b4 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32772 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- Documentation/POSTCODES | 1 + src/drivers/intel/fsp1_1/raminit.c | 14 ++++++++------ src/drivers/intel/fsp2_0/memory_init.c | 6 ++++-- src/drivers/intel/fsp2_0/silicon_init.c | 3 ++- src/include/console/post_codes.h | 8 ++++++++ src/northbridge/intel/haswell/raminit.c | 3 ++- src/northbridge/intel/sandybridge/raminit_mrc.c | 3 ++- src/soc/intel/fsp_baytrail/romstage/romstage.c | 3 ++- src/soc/intel/fsp_broadwell_de/romstage/romstage.c | 3 ++- 9 files changed, 31 insertions(+), 13 deletions(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 162e863fede..855940f433a 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -18,6 +18,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0x89 Devices have been enabled 0xe0 Boot media (e.g. SPI ROM) is corrupt 0xe1 Resource stored within CBFS is corrupt +0xe2 Vendor binary (e.g. FSP) generated a fatal error 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/drivers/intel/fsp1_1/raminit.c b/src/drivers/intel/fsp1_1/raminit.c index 726cc26a0c3..fc6f8480892 100644 --- a/src/drivers/intel/fsp1_1/raminit.c +++ b/src/drivers/intel/fsp1_1/raminit.c @@ -195,9 +195,6 @@ void raminit(struct romstage_params *params) } #if CONFIG(DISPLAY_HOBS) - if (hob_list_ptr == NULL) - die("ERROR - HOB pointer is NULL!\n"); - /* * Verify that FSP is generating the required HOBs: * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0 @@ -244,7 +241,10 @@ void raminit(struct romstage_params *params) "ERROR - Missing one or more required FSP HOBs!\n"); /* Display the HOBs */ - print_hob_type_structure(0, hob_list_ptr); + if (hob_list_ptr != NULL) + print_hob_type_structure(0, hob_list_ptr); + else + printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n"); #endif /* Get the address of the CBMEM region for the FSP reserved memory */ @@ -274,14 +274,16 @@ void raminit(struct romstage_params *params) printk(BIOS_DEBUG, "0x%08x: Chipset reserved bytes reported by FSP\n", (unsigned int)delta_bytes); - die("Please verify the chipset reserved size\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Please verify the chipset reserved size\n"); } #endif } /* Verify the FSP 1.1 HOB interface */ if (fsp_verification_failure) - die("ERROR - coreboot's requirements not met by FSP binary!\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "ERROR - coreboot's requirements not met by FSP binary!\n"); /* Display the memory configuration */ report_memory_config(); diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c index b3afb98c4d2..449b57d03eb 100644 --- a/src/drivers/intel/fsp2_0/memory_init.c +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -277,7 +277,8 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake, upd = (FSPM_UPD *)(hdr->cfg_region_offset + hdr->image_base); if (upd->FspUpdHeader.Signature != FSPM_UPD_SIGNATURE) - die("Invalid FSPM signature!\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Invalid FSPM signature!\n"); /* Copy the default values from the UPD area */ memcpy(&fspm_upd, upd, sizeof(fspm_upd)); @@ -290,7 +291,8 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake, /* Fill common settings on behalf of chipset. */ if (fsp_fill_common_arch_params(arch_upd, s3wake, fsp_version, memmap) != CB_SUCCESS) - die("FSPM_ARCH_UPD not found!\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "FSPM_ARCH_UPD not found!\n"); /* Give SoC and mainboard a chance to update the UPD */ platform_fsp_memory_init_params_cb(&fspm_upd, fsp_version); diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index 402b05d55e0..b0a697d8cbc 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -33,7 +33,8 @@ static void do_silicon_init(struct fsp_header *hdr) supd = (FSPS_UPD *) (hdr->cfg_region_offset + hdr->image_base); if (supd->FspUpdHeader.Signature != FSPS_UPD_SIGNATURE) - die("Invalid FSPS signature\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Invalid FSPS signature\n"); upd = xmalloc(sizeof(FSPS_UPD)); diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index 7bd1ee0798d..478c811b4d2 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -332,6 +332,14 @@ */ #define POST_INVALID_CBFS 0xe1 +/** + * \brief Vendor binary error + * + * Set if firmware failed to find or validate a vendor binary, or the binary + * generated a fatal error. + */ +#define POST_INVALID_VENDOR_BINARY 0xe2 + /** * \brief TPM failure * diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index 050dbd1ae61..c24bb67db7c 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -166,7 +166,8 @@ void sdram_initialize(struct pei_data *pei_data) default: printk(BIOS_ERR, "MRC returned %x.\n", rv); } - die("Nonzero MRC return value.\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Nonzero MRC return value.\n"); } } else { die("UEFI PEI System Agent not found.\n"); diff --git a/src/northbridge/intel/sandybridge/raminit_mrc.c b/src/northbridge/intel/sandybridge/raminit_mrc.c index f032b8aefc0..e88d3565937 100644 --- a/src/northbridge/intel/sandybridge/raminit_mrc.c +++ b/src/northbridge/intel/sandybridge/raminit_mrc.c @@ -235,7 +235,8 @@ void sdram_initialize(struct pei_data *pei_data) default: printk(BIOS_ERR, "MRC returned %x.\n", rv); } - die("Nonzero MRC return value.\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Nonzero MRC return value.\n"); } } else { die("UEFI PEI System Agent not found.\n"); diff --git a/src/soc/intel/fsp_baytrail/romstage/romstage.c b/src/soc/intel/fsp_baytrail/romstage/romstage.c index c46b09ef97c..030b5dfeed9 100644 --- a/src/soc/intel/fsp_baytrail/romstage/romstage.c +++ b/src/soc/intel/fsp_baytrail/romstage/romstage.c @@ -208,7 +208,8 @@ void main(FSP_INFO_HEADER *fsp_info_header) post_code(0x48); printk(BIOS_DEBUG, "Starting the Intel FSP (early_init)\n"); fsp_early_init(fsp_info_header); - die("Uh Oh! fsp_early_init should not return here.\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Uh Oh! fsp_early_init should not return here.\n"); } /******************************************************************************* diff --git a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c index a75dabd2256..121cb25d615 100644 --- a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c +++ b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c @@ -84,7 +84,8 @@ void *asmlinkage main(FSP_INFO_HEADER *fsp_info_header) post_code(0x48); printk(BIOS_DEBUG, "Starting the Intel FSP (early_init)\n"); fsp_early_init(fsp_info_header); - die("Uh Oh! fsp_early_init should not return here.\n"); + die_with_post_code(POST_INVALID_VENDOR_BINARY, + "Uh Oh! fsp_early_init should not return here.\n"); } /******************************************************************************* From 24302633a558e545efcc84178136bd1879f6d8ee Mon Sep 17 00:00:00 2001 From: Keith Short Date: Thu, 16 May 2019 14:08:31 -0600 Subject: [PATCH 393/588] post_code: add post code for memory error Add a new post code POST_RAM_FAILURE, used when the Intel FSP code fails to initialize RAM. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: Ibafefa0fc0b1c525f923929cc91731fbcc1e7533 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32773 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/POSTCODES | 1 + src/drivers/intel/fsp1_1/raminit.c | 3 ++- src/drivers/intel/fsp2_0/memory_init.c | 3 ++- src/include/console/post_codes.h | 8 ++++++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 855940f433a..2a8285b27f3 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -19,6 +19,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0xe0 Boot media (e.g. SPI ROM) is corrupt 0xe1 Resource stored within CBFS is corrupt 0xe2 Vendor binary (e.g. FSP) generated a fatal error +0xe3 RAM could not be initialized 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/drivers/intel/fsp1_1/raminit.c b/src/drivers/intel/fsp1_1/raminit.c index fc6f8480892..eff011aa622 100644 --- a/src/drivers/intel/fsp1_1/raminit.c +++ b/src/drivers/intel/fsp1_1/raminit.c @@ -130,7 +130,8 @@ void raminit(struct romstage_params *params) printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status); if (status != EFI_SUCCESS) - die("ERROR - FspMemoryInit failed to initialize memory!\n"); + die_with_post_code(POST_RAM_FAILURE, + "ERROR - FspMemoryInit failed to initialize memory!\n"); /* Locate the FSP reserved memory area */ fsp_reserved_bytes = 0; diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c index 449b57d03eb..60e3310a4da 100644 --- a/src/drivers/intel/fsp2_0/memory_init.c +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -316,7 +316,8 @@ static void do_fsp_memory_init(struct fsp_header *hdr, bool s3wake, fsp_handle_reset(status); if (status != FSP_SUCCESS) { printk(BIOS_CRIT, "FspMemoryInit returned 0x%08x\n", status); - die("FspMemoryInit returned an error!\n"); + die_with_post_code(POST_RAM_FAILURE, + "FspMemoryInit returned an error!\n"); } do_fsp_post_memory_init(s3wake, fsp_version); diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index 478c811b4d2..07927ec957d 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -340,6 +340,14 @@ */ #define POST_INVALID_VENDOR_BINARY 0xe2 +/** + * \brief RAM failure + * + * Set if RAM could not be initialized. This includes RAM is missing, + * unsupported RAM configuration, or RAM failure. + */ +#define POST_RAM_FAILURE 0xe3 + /** * \brief TPM failure * From 15588b03b36aa875e2a2a31cc649a2d9dff7581e Mon Sep 17 00:00:00 2001 From: Keith Short Date: Thu, 9 May 2019 11:40:34 -0600 Subject: [PATCH 394/588] post_code: add post code for hardware initialization failure Add a new post code POST_HW_INIT_FAILURE, used when coreboot fails to detect or initialize a required hardware component. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: I73820d24b3e1c269d9d446a78ef4f97e167e3552 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32774 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/POSTCODES | 1 + src/console/Makefile.inc | 1 + src/include/console/post_codes.h | 7 +++++++ src/soc/intel/apollolake/memmap.c | 3 ++- src/soc/intel/cannonlake/bootblock/pch.c | 3 ++- src/soc/intel/cannonlake/memmap.c | 3 ++- src/soc/intel/common/block/graphics/graphics.c | 6 ++++-- src/soc/intel/common/block/p2sb/p2sb.c | 12 ++++++++---- src/soc/intel/common/block/pmc/pmc.c | 3 ++- src/soc/intel/fsp_baytrail/southcluster.c | 2 +- src/soc/intel/icelake/memmap.c | 3 ++- src/soc/intel/quark/i2c.c | 3 ++- 12 files changed, 34 insertions(+), 13 deletions(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index 2a8285b27f3..a9d392a9b08 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -20,6 +20,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0xe1 Resource stored within CBFS is corrupt 0xe2 Vendor binary (e.g. FSP) generated a fatal error 0xe3 RAM could not be initialized +0xe4 Critical hardware component could not initialize 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/console/Makefile.inc b/src/console/Makefile.inc index d5795d79296..4f0c2ef6139 100644 --- a/src/console/Makefile.inc +++ b/src/console/Makefile.inc @@ -9,6 +9,7 @@ endif smm-$(CONFIG_DEBUG_SMI) += init.c console.c vtxprintf.c printk.c smm-$(CONFIG_SMM_TSEG) += die.c +smm-$(CONFIG_SMM_TSEG) += post.c verstage-y += init.c verstage-y += printk.c diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index 07927ec957d..ae277d82e22 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -348,6 +348,13 @@ */ #define POST_RAM_FAILURE 0xe3 +/** + * \brief Hardware initialization failure + * + * Set when a required hardware component was not found or is unsupported. + */ +#define POST_HW_INIT_FAILURE 0xe4 + /** * \brief TPM failure * diff --git a/src/soc/intel/apollolake/memmap.c b/src/soc/intel/apollolake/memmap.c index 4f91b8aea52..6058e348958 100644 --- a/src/soc/intel/apollolake/memmap.c +++ b/src/soc/intel/apollolake/memmap.c @@ -40,7 +40,8 @@ void *cbmem_top(void) config = dev->chip_info; if (!config) - die("Failed to get chip_info\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "Failed to get chip_info\n"); /* FSP allocates 2x PRMRR Size Memory for alignment */ if (config->sgx_enable) diff --git a/src/soc/intel/cannonlake/bootblock/pch.c b/src/soc/intel/cannonlake/bootblock/pch.c index 1c7fd7f082f..c43d6d8bd12 100644 --- a/src/soc/intel/cannonlake/bootblock/pch.c +++ b/src/soc/intel/cannonlake/bootblock/pch.c @@ -120,7 +120,8 @@ static void soc_config_acpibase(void) pmc_base_reg = get_pmc_reg_base(); if (!pmc_base_reg) - die("Invalid PMC base address\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "Invalid PMC base address\n"); pmc_reg_value = pcr_read32(PID_PSF3, pmc_base_reg + PCR_PSFX_TO_SHDW_BAR4); diff --git a/src/soc/intel/cannonlake/memmap.c b/src/soc/intel/cannonlake/memmap.c index 3512e2c4b4e..3cae54fadb5 100644 --- a/src/soc/intel/cannonlake/memmap.c +++ b/src/soc/intel/cannonlake/memmap.c @@ -221,7 +221,8 @@ static uintptr_t calculate_dram_base(size_t *reserved_mem_size) dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); if (!dev) - die("ERROR - IGD device not found!"); + die_with_post_code(POST_HW_INIT_FAILURE, + "ERROR - IGD device not found!"); /* Read TOLUD from Host Bridge offset */ dram_base = sa_get_tolud_base(); diff --git a/src/soc/intel/common/block/graphics/graphics.c b/src/soc/intel/common/block/graphics/graphics.c index 5d3b4a15cf9..4cea21b075c 100644 --- a/src/soc/intel/common/block/graphics/graphics.c +++ b/src/soc/intel/common/block/graphics/graphics.c @@ -58,7 +58,8 @@ uintptr_t graphics_get_memory_base(void) */ uintptr_t memory_base = graphics_get_bar(PCI_BASE_ADDRESS_2); if (!memory_base) - die("GMADR is not programmed!"); + die_with_post_code(POST_HW_INIT_FAILURE, + "GMADR is not programmed!"); return memory_base; } @@ -74,7 +75,8 @@ static uintptr_t graphics_get_gtt_base(void) if (!gtt_base) { gtt_base = graphics_get_bar(PCI_BASE_ADDRESS_0); if (!gtt_base) - die("GTTMMADR is not programmed!"); + die_with_post_code(POST_HW_INIT_FAILURE, + "GTTMMADR is not programmed!"); } return gtt_base; } diff --git a/src/soc/intel/common/block/p2sb/p2sb.c b/src/soc/intel/common/block/p2sb/p2sb.c index 1d7c091a694..24cde1b6c98 100644 --- a/src/soc/intel/common/block/p2sb/p2sb.c +++ b/src/soc/intel/common/block/p2sb/p2sb.c @@ -36,7 +36,8 @@ static pci_devfn_t p2sb_get_device(void) pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn)); if (dev == PCI_DEV_INVALID) - die("PCH_DEV_P2SB not found!\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "PCH_DEV_P2SB not found!\n"); return dev; } @@ -45,7 +46,8 @@ static struct device *p2sb_get_device(void) { struct device *dev = PCH_DEV_P2SB; if (!dev) - die("PCH_DEV_P2SB not found!\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "PCH_DEV_P2SB not found!\n"); return dev; } @@ -99,7 +101,8 @@ void p2sb_unhide(void) if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) != PCI_VENDOR_ID_INTEL) - die("Unable to unhide PCH_DEV_P2SB device !\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "Unable to unhide PCH_DEV_P2SB device !\n"); } void p2sb_hide(void) @@ -108,7 +111,8 @@ void p2sb_hide(void) if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) != 0xFFFF) - die("Unable to hide PCH_DEV_P2SB device !\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "Unable to hide PCH_DEV_P2SB device !\n"); } static void p2sb_configure_endpoints(int epmask_id, uint32_t mask) diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c index 43543a1cc50..eaaf1252eac 100644 --- a/src/soc/intel/common/block/pmc/pmc.c +++ b/src/soc/intel/common/block/pmc/pmc.c @@ -91,7 +91,8 @@ static void pch_pmc_read_resources(struct device *dev) struct pmc_resource_config *config = &pmc_cfg; if (pmc_soc_get_resources(config) < 0) - die("Unable to get PMC controller resource information!"); + die_with_post_code(POST_HW_INIT_FAILURE, + "Unable to get PMC controller resource information!"); /* Get the normal PCI resources of this device. */ pci_dev_read_resources(dev); diff --git a/src/soc/intel/fsp_baytrail/southcluster.c b/src/soc/intel/fsp_baytrail/southcluster.c index c84f4083d43..356b855f3be 100644 --- a/src/soc/intel/fsp_baytrail/southcluster.c +++ b/src/soc/intel/fsp_baytrail/southcluster.c @@ -98,7 +98,7 @@ static void sc_enable_ioapic(struct device *dev) reg32 = *ioapic_data; printk(BIOS_DEBUG, "Southbridge APIC ID = %x\n", (reg32 >> 24) & 0x0f); if (reg32 != (1 << 25)) - die("APIC Error\n"); + die_with_post_code(POST_HW_INIT_FAILURE, "APIC Error\n"); printk(BIOS_SPEW, "Dumping IOAPIC registers\n"); for (i=0; i<3; i++) { diff --git a/src/soc/intel/icelake/memmap.c b/src/soc/intel/icelake/memmap.c index 7d6e4e65924..f4467084ea9 100644 --- a/src/soc/intel/icelake/memmap.c +++ b/src/soc/intel/icelake/memmap.c @@ -220,7 +220,8 @@ static uintptr_t calculate_dram_base(size_t *reserved_mem_size) dev = dev_find_slot(0, PCI_DEVFN(SA_DEV_SLOT_IGD, 0)); if (!dev) - die("ERROR - IGD device not found!"); + die_with_post_code(POST_HW_INIT_FAILURE, + "ERROR - IGD device not found!"); /* Read TOLUD from Host Bridge offset */ dram_base = sa_get_tolud_base(); diff --git a/src/soc/intel/quark/i2c.c b/src/soc/intel/quark/i2c.c index 595c818593b..bb1a26437fb 100644 --- a/src/soc/intel/quark/i2c.c +++ b/src/soc/intel/quark/i2c.c @@ -38,7 +38,8 @@ static void i2c_disable(I2C_REGS *regs) while (status & IC_ENABLE_CONTROLLER) { udelay(1); if (--timeout == 0) - die("ERROR - I2C failed to disable!\n"); + die_with_post_code(POST_HW_INIT_FAILURE, + "ERROR - I2C failed to disable!\n"); status = regs->ic_enable_status; } From c58e3bd90a96bf01859d1c0af83926b1e17edff5 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 10 May 2019 11:14:31 -0600 Subject: [PATCH 395/588] post_code: add post code for video initialization failure Add a new post code POST_VIDEO_FAILURE used when the Intel FSP silicon initialization returns an error when graphics was also initialized. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms Change-Id: Ibc7f7defbed34038f445949010a37c8e368aae20 Signed-off-by: Keith Short Reviewed-on: https://review.coreboot.org/c/coreboot/+/32775 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/POSTCODES | 1 + src/drivers/intel/fsp2_0/silicon_init.c | 14 +++++++++++++- src/include/console/post_codes.h | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Documentation/POSTCODES b/Documentation/POSTCODES index a9d392a9b08..0e67dd173cc 100644 --- a/Documentation/POSTCODES +++ b/Documentation/POSTCODES @@ -21,6 +21,7 @@ This is an (incomplete) list of POST codes emitted by coreboot v4. 0xe2 Vendor binary (e.g. FSP) generated a fatal error 0xe3 RAM could not be initialized 0xe4 Critical hardware component could not initialize +0xe5 Video subsystem failed to initialize 0xf8 Entry into elf boot 0xf3 Jumping to payload diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index b0a697d8cbc..e9c29db40e6 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -29,6 +30,7 @@ static void do_silicon_init(struct fsp_header *hdr) FSPS_UPD *upd, *supd; fsp_silicon_init_fn silicon_init; uint32_t status; + uint8_t postcode; supd = (FSPS_UPD *) (hdr->cfg_region_offset + hdr->image_base); @@ -59,8 +61,18 @@ static void do_silicon_init(struct fsp_header *hdr) /* Handle any errors returned by FspSiliconInit */ fsp_handle_reset(status); if (status != FSP_SUCCESS) { + if (vbt_get()) { + /* Attempted to initialize graphics. Assume failure + * is related to a video failure. + */ + postcode = POST_VIDEO_FAILURE; + } else { + /* Other silicon initialization failed */ + postcode = POST_HW_INIT_FAILURE; + } printk(BIOS_SPEW, "FspSiliconInit returned 0x%08x\n", status); - die("FspSiliconINit returned an error!\n"); + die_with_post_code(postcode, + "FspSiliconINit returned an error!\n"); } } diff --git a/src/include/console/post_codes.h b/src/include/console/post_codes.h index ae277d82e22..c1917adafff 100644 --- a/src/include/console/post_codes.h +++ b/src/include/console/post_codes.h @@ -355,6 +355,13 @@ */ #define POST_HW_INIT_FAILURE 0xe4 +/** + * \brief Video failure + * + * Video subsystem failed to initialize. + */ +#define POST_VIDEO_FAILURE 0xe5 + /** * \brief TPM failure * From f41afde6c2bbab86072b6a8cc23f91cdcd772a59 Mon Sep 17 00:00:00 2001 From: Keith Short Date: Fri, 10 May 2019 11:52:55 -0600 Subject: [PATCH 396/588] ec/google/wilco: set diagnostic LEDs on boot failure On Wilco devices, if any of the coreboot stages fails with a fatal error, set the diagnostic LEDs with the Wilco EC. The last saved post code is used to determine the error code sent to the EC. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms TEST=Remove DIMM module, confirm diagnostic LED pattern for memory failure (2 amber, 4 white). TEST=Forced a fatal error in both bootblock and verstage to confirm diagnostic LEDs during these stages. This works on cold-boots only. Bug b:132622888 tracks the mailbox failures on warm boots. Change-Id: If865ab8203f89e499130f4677fec166b40d80174 Signed-off-by: Keith Short Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32777 Tested-by: build bot (Jenkins) Reviewed-by: Jett Rink Reviewed-by: Duncan Laurie Reviewed-by: Furquan Shaikh --- src/ec/google/wilco/commands.c | 43 +++++++++++++++++++++++++++++++--- src/ec/google/wilco/commands.h | 14 +++++------ 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/ec/google/wilco/commands.c b/src/ec/google/wilco/commands.c index a97a28eccea..9d4170f5390 100644 --- a/src/ec/google/wilco/commands.c +++ b/src/ec/google/wilco/commands.c @@ -182,8 +182,45 @@ int wilco_ec_signed_fw(void) return !!ec_read(EC_RAM_SIGNED_FW); } -int wilco_ec_err_code(enum ec_err_code err_code) +struct err_code_entry { + uint8_t post_code; + enum ec_err_code ec_err; +}; + +/* + * Any post codes not listed in the post_code_err_map[] use default. + */ +static const enum ec_err_code default_ec_err = DLED_ROM; +static const struct err_code_entry post_code_err_map[] = { + { .post_code = POST_RAM_FAILURE, .ec_err = DLED_MEMORY, }, + { .post_code = POST_VIDEO_FAILURE, .ec_err = DLED_PANEL, }, +}; + +/* Records the most recent post code during boot */ +static uint8_t wilco_ec_saved_post_code; + +void wilco_ec_save_post_code(uint8_t post_code) +{ + wilco_ec_saved_post_code = post_code; +} + +/* Send error code to the EC based on last saved post code */ +void die_notify(void) { - return wilco_ec_mailbox(WILCO_EC_MSG_DEFAULT, KB_ERR_CODE, - &err_code, 1, NULL, 0); + size_t i; + enum ec_err_code err_code = default_ec_err; + + for (i = 0; i < ARRAY_SIZE(post_code_err_map); i++) { + if (post_code_err_map[i].post_code == + wilco_ec_saved_post_code) { + err_code = post_code_err_map[i].ec_err; + break; + } + } + + printk(BIOS_EMERG, "Fatal error: post_code 0x%02x, EC err 0x%02x\n", + wilco_ec_saved_post_code, err_code); + + wilco_ec_mailbox(WILCO_EC_MSG_DEFAULT, KB_ERR_CODE, + &err_code, 1, NULL, 0); } diff --git a/src/ec/google/wilco/commands.h b/src/ec/google/wilco/commands.h index fafb7fd8ba6..9b7f2e5d074 100644 --- a/src/ec/google/wilco/commands.h +++ b/src/ec/google/wilco/commands.h @@ -319,16 +319,14 @@ enum ec_acpi_wake_events { int wilco_ec_signed_fw(void); /** - * wilco_ec_err_code + * wilco_ec_save_post_code * - * Send an error code to the EC to indicate a failed boot. The EC flashes the - * platform LED amber and white to provide user indication of the failure type. + * Save this post code as the most recent progress step. If the boot fails + * and calls die_notify() this post code will be used to send an error code + * to the EC indicating the failure. * - * @err_code: Error code to send to the EC - * - * Returns 0 if EC command was successful - * Returns -1 if EC command failed + * @post_code: Post code to save */ -int wilco_ec_err_code(enum ec_err_code err_code); +void wilco_ec_save_post_code(uint8_t post_code); #endif /* EC_GOOGLE_WILCO_COMMANDS_H */ From 239b13ce38e9f7edd86193a5edddb403cdac437d Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Wed, 22 May 2019 10:14:26 -0700 Subject: [PATCH 397/588] mb/google/sarien: Send post code to the EC Use the mainboard post code hook to inform the wilco EC driver of the latest boot stage. BUG=b:124401932 BRANCH=sarien TEST=build coreboot for sarien and arcada platforms TEST=Remove DIMM module, confirm diagnostic LED pattern for memory failure (2 amber, 4 white). Change-Id: If5bf69365d8be3bdbd433f305c85848206ded7b0 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32937 Reviewed-by: Jett Rink Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/mainboard/google/sarien/ramstage.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/mainboard/google/sarien/ramstage.c b/src/mainboard/google/sarien/ramstage.c index 1d220461cf5..e246419373a 100644 --- a/src/mainboard/google/sarien/ramstage.c +++ b/src/mainboard/google/sarien/ramstage.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -69,6 +70,11 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) cnl_configure_pads(gpio_table, num_gpios); } +void mainboard_post(uint8_t value) +{ + wilco_ec_save_post_code(value); +} + static void mainboard_enable(struct device *dev) { dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator; From 84b8f90bba65c56c4122d0a214608ef4e882861c Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 20 May 2019 10:05:18 +0200 Subject: [PATCH 398/588] mb/asus/p8h61-m_pro: Add small fixes * Add VBT * Configure OnBoard NIC * Add documentation Change-Id: Iad739b4e1dacb41f5f63247150951df7013bbf0c Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32890 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Angel Pons --- Documentation/mainboard/asus/p8h61-m_pro.jpg | Bin 0 -> 69452 bytes Documentation/mainboard/asus/p8h61-m_pro.md | 103 +++++++++++++++++++ Documentation/mainboard/index.md | 1 + src/mainboard/asus/p8h61-m_pro/Kconfig | 3 + src/mainboard/asus/p8h61-m_pro/data.vbt | Bin 0 -> 3902 bytes src/mainboard/asus/p8h61-m_pro/devicetree.cb | 8 +- 6 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 Documentation/mainboard/asus/p8h61-m_pro.jpg create mode 100644 Documentation/mainboard/asus/p8h61-m_pro.md create mode 100644 src/mainboard/asus/p8h61-m_pro/data.vbt diff --git a/Documentation/mainboard/asus/p8h61-m_pro.jpg b/Documentation/mainboard/asus/p8h61-m_pro.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f3d60071b555971d91f9f4007aa995fbc1a40670 GIT binary patch literal 69452 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 literal 0 HcmV?d00001 diff --git a/Documentation/mainboard/asus/p8h61-m_pro.md b/Documentation/mainboard/asus/p8h61-m_pro.md new file mode 100644 index 00000000000..169678efcd5 --- /dev/null +++ b/Documentation/mainboard/asus/p8h61-m_pro.md @@ -0,0 +1,103 @@ +# ASUS P8H61-M Pro + +This page describes how to run coreboot on the [ASUS P8H61-M Pro]. + +## Flashing coreboot + +```eval_rst ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | yes | ++---------------------+------------+ +| Model | W25Q32BV | ++---------------------+------------+ +| Size | 4 MiB | ++---------------------+------------+ +| Package | DIP-8 | ++---------------------+------------+ +| Write protection | no | ++---------------------+------------+ +| Dual BIOS feature | no | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +``` + +The flash IC is located right next to one of the SATA ports: +![](p8h61-m_pro.jpg) + +### Internal programming + +The main SPI flash can be accessed using [flashrom]. By default, only +the BIOS region of the flash is writable. If you wish to change any +other region (Management Engine or flash descriptor), then an external +programmer is required. + +The following command may be used to flash coreboot: + +``` +$ sudo flashrom --noverify-all --ifd -i bios -p internal -w coreboot.rom +``` + +The use of `--noverify-all` is required since the Management Engine +region is not readable even by the host. + +## Known issues + +- There is no automatic, OS-independent fan control. This is because + the super I/O hardware monitor can only obtain valid CPU temperature + readings from the PECI agent, whose complete initialisation is not + publicly documented. The `coretemp` driver can still be used for + accurate CPU temperature readings. + +- me_cleaner breaks LPC bus and attached components! +- PS/2 mouse doesn't work + +## Untested + +- parallel port +- EHCI debug +- S/PDIF audio + +## Working + +- PS/2 keyboard +- PCIe graphics +- USB +- Gigabit Ethernet +- Integrated graphics +- SATA +- Serial port +- hardware monitor (see [Known issues](#known-issues) for caveats) +- front panel audio +- Native raminit (2 x 2GB, DDR3-1333) +- Native graphics init (libgfxinit) +- Wake-on-LAN +- TPM on TPM-header + +## Technology + +```eval_rst ++------------------+--------------------------------------------------+ +| Northbridge | :doc:`../../northbridge/intel/sandybridge/index` | ++------------------+--------------------------------------------------+ +| Southbridge | bd82x6x | ++------------------+--------------------------------------------------+ +| CPU | model_206ax | ++------------------+--------------------------------------------------+ +| Super I/O | Nuvoton NCT6776 | ++------------------+--------------------------------------------------+ +| EC | None | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +``` + +## Extra resources + +- [Flash chip datasheet][W25Q32BV] + +[ASUS P8H61-M Pro]: https://www.asus.com/Motherboards/P8H61M_Pro/ +[W25Q32BV]: https://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf +[flashrom]: https://flashrom.org/Flashrom diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index eced74966e9..1494e062444 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -6,6 +6,7 @@ This section contains documentation about coreboot on specific mainboards. - [F2A85-M](asus/f2a85-m.md) - [P8H61-M LX](asus/p8h61-m_lx.md) +- [P8H61-M Pro](asus/p8h61-m_pro.md) ## ASRock diff --git a/src/mainboard/asus/p8h61-m_pro/Kconfig b/src/mainboard/asus/p8h61-m_pro/Kconfig index 14f841e649c..e8a6f6404a2 100644 --- a/src/mainboard/asus/p8h61-m_pro/Kconfig +++ b/src/mainboard/asus/p8h61-m_pro/Kconfig @@ -31,6 +31,9 @@ config BOARD_SPECIFIC_OPTIONS select HAVE_CMOS_DEFAULT select DRIVERS_ASMEDIA_ASPM_BLACKLIST select MAINBOARD_HAS_LPC_TPM + select REALTEK_8168_RESET + select RT8168_SET_LED_MODE + select INTEL_GMA_HAVE_VBT config MAINBOARD_DIR string diff --git a/src/mainboard/asus/p8h61-m_pro/data.vbt b/src/mainboard/asus/p8h61-m_pro/data.vbt new file mode 100644 index 0000000000000000000000000000000000000000..114a840660fcd06b44a58fbac5428b549c909c34 GIT binary patch literal 3902 zcmdT{U1%It6h5;v`*&w1*-T=)S<`S+OS?()Gueg^Le$yKCT7!Zc9Y#MYZ1FiciR-w zG~NEtf;CeOwjz{Oq}EzxQIy)J(kDS5`XoU`LJ<-1p%fpa6zM||EVb*oGm{@0X$Q4f z@9^Do?wNDHz4y#HcV;(aB59f$iFCv=k+$eSYHK=?%!3NgR4dr8Zjo3bwKEz{hj&Ke ziToRB)`BrpBl9$0mw<^Lq*%u_Km7ll?Io-nFYR zRVa=hD&%P@^IVuRTA4%+@14rik;D5Y3dLT^xX_z+cC~NmqO?=(=nQp))Xq+dw|cv} zdbf1RBs$Qa*p`gN!|7OJgeJylG?ogdQUlu}@#krBEHM;|#L@#%nHXE?-#>G#xOdOw zAsXy&rXf{T+YCZu$+Uleai*Pyr>5u_^EpVz3I_|tBZYjsOc=ox-Xm}va89T`p>f_n zLXgv_6q!*I9a(7|o2Oy?|FV@mJ|aJm`v^OpU*W%u5~ zCyb3)QnaLDw9!>6Za3VkeCvlw#q%^~I#>F}c)q)K)qy-B?uqxr0;-!&tYx zr*BR&ShoXIPF8t=d*8VOes{J(^&8+d&$z{3{a2;eI5})n)+|4KMKZE)acbQM;0l-n zci*D%e)(VCS+f;SSl%dR4=Wp^sdH5T@xkQIcpjxrd?UI_=C_r%bUTJx@VnW9P+4f zB_sP#bFtS5fK(rZdbopEJ(M^K<~5Hm1oLX;mbCz5dGZ@rz>{#neVaQ~`*><>U-nw1 z($Edxd-W2%w$A6ttv6>i+OY)v7}SG*`7_OL1OJwne&$ua@{;eo^p01N2w6jDA5lgK z$rAc9QA&iIBlHSUt`hPSp$<{06G@{;qoR@#Nlv7%iON}#d??a+QTb6MKZ}$|N`pi; zN;EDhFG^%mqNgRLERl;6U67RP61gc+MOHS*q+OapXuDr=3XdZpvI7g+_I-WIYQ%MzUlay0{cOad@e{RL%t& zHI-VYQe*e5Q1TkP(A{=+5$w~;Gnbx1h88vp02!Pm;~gZGopUzw;aqchVRUZ2ntXTd z5(5t+(*00LtU*qP+MLf Date: Tue, 21 May 2019 17:22:49 +0200 Subject: [PATCH 399/588] src/mainboard/google: Adopt Mainboards to changed Type41 Func Required for automatic onboard device detection in the next patch. Change-Id: I3087de779faf8d006510c460b5372b22ae54b887 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32909 Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- src/arch/x86/smbios.c | 4 ++-- src/include/smbios.h | 2 +- .../google/auron/variants/auron_paine/variant.c | 3 ++- src/mainboard/google/auron/variants/auron_yuna/variant.c | 3 ++- src/mainboard/google/auron/variants/buddy/variant.c | 3 ++- src/mainboard/google/auron/variants/gandof/variant.c | 3 ++- src/mainboard/google/auron/variants/lulu/variant.c | 6 ++++-- src/mainboard/google/butterfly/mainboard.c | 3 ++- src/mainboard/google/link/mainboard.c | 9 ++++++--- src/mainboard/google/parrot/mainboard.c | 6 ++++-- src/mainboard/google/rambi/mainboard.c | 6 ++++-- src/mainboard/google/slippy/mainboard.c | 9 ++++++--- 12 files changed, 37 insertions(+), 20 deletions(-) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 90cd674198d..310a870da66 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -962,7 +962,7 @@ int smbios_write_type38(unsigned long *current, int *handle, int smbios_write_type41(unsigned long *current, int *handle, const char *name, u8 instance, u16 segment, - u8 bus, u8 device, u8 function) + u8 bus, u8 device, u8 function, u8 device_type) { struct smbios_type41 *t = (struct smbios_type41 *)*current; int len = sizeof(struct smbios_type41); @@ -972,7 +972,7 @@ int smbios_write_type41(unsigned long *current, int *handle, t->handle = *handle; t->length = len - 2; t->reference_designation = smbios_add_string(t->eos, name); - t->device_type = SMBIOS_DEVICE_TYPE_OTHER; + t->device_type = device_type; t->device_status = 1; t->device_type_instance = instance; t->segment_group_number = segment; diff --git a/src/include/smbios.h b/src/include/smbios.h index afe77d6ad9f..017e90e7420 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -44,7 +44,7 @@ int smbios_write_type38(unsigned long *current, int *handle, const u8 irq); int smbios_write_type41(unsigned long *current, int *handle, const char *name, u8 instance, u16 segment, - u8 bus, u8 device, u8 function); + u8 bus, u8 device, u8 function, u8 device_type); const char *smbios_system_manufacturer(void); const char *smbios_system_product_name(void); diff --git a/src/mainboard/google/auron/variants/auron_paine/variant.c b/src/mainboard/google/auron/variants/auron_paine/variant.c index 62d4f522f71..84e26db1b7c 100644 --- a/src/mainboard/google/auron/variants/auron_paine/variant.c +++ b/src/mainboard/google/auron/variants/auron_paine/variant.c @@ -26,7 +26,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/auron/variants/auron_yuna/variant.c b/src/mainboard/google/auron/variants/auron_yuna/variant.c index 62d4f522f71..84e26db1b7c 100644 --- a/src/mainboard/google/auron/variants/auron_yuna/variant.c +++ b/src/mainboard/google/auron/variants/auron_yuna/variant.c @@ -26,7 +26,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/auron/variants/buddy/variant.c b/src/mainboard/google/auron/variants/buddy/variant.c index 9f8188fe43e..dcda04dbb6e 100644 --- a/src/mainboard/google/auron/variants/buddy/variant.c +++ b/src/mainboard/google/auron/variants/buddy/variant.c @@ -35,7 +35,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TOUCHSCREEN_I2C_BUS, /* segment */ BOARD_TOUCHSCREEN_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/auron/variants/gandof/variant.c b/src/mainboard/google/auron/variants/gandof/variant.c index cd7a66332d0..29b298839fd 100644 --- a/src/mainboard/google/auron/variants/gandof/variant.c +++ b/src/mainboard/google/auron/variants/gandof/variant.c @@ -29,7 +29,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/auron/variants/lulu/variant.c b/src/mainboard/google/auron/variants/lulu/variant.c index 97302b84865..a76cc858c3e 100644 --- a/src/mainboard/google/auron/variants/lulu/variant.c +++ b/src/mainboard/google/auron/variants/lulu/variant.c @@ -29,7 +29,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ len += smbios_write_type41( current, handle, @@ -38,7 +39,8 @@ int variant_smbios_data(struct device *dev, int *handle, unsigned long *current) BOARD_TOUCHSCREEN_I2C_BUS, /* segment */ BOARD_TOUCHSCREEN_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/butterfly/mainboard.c b/src/mainboard/google/butterfly/mainboard.c index 9cc13c94732..c298689639e 100644 --- a/src/mainboard/google/butterfly/mainboard.c +++ b/src/mainboard/google/butterfly/mainboard.c @@ -264,7 +264,8 @@ static int butterfly_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/link/mainboard.c b/src/mainboard/google/link/mainboard.c index 410866d0feb..37d1a672cda 100644 --- a/src/mainboard/google/link/mainboard.c +++ b/src/mainboard/google/link/mainboard.c @@ -170,7 +170,8 @@ static int link_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_LIGHTSENSOR_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ len += smbios_write_type41( current, handle, @@ -179,7 +180,8 @@ static int link_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ len += smbios_write_type41( current, handle, @@ -188,7 +190,8 @@ static int link_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_TOUCHSCREEN_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } diff --git a/src/mainboard/google/parrot/mainboard.c b/src/mainboard/google/parrot/mainboard.c index 52e4af3ea77..8c3ad6352e3 100644 --- a/src/mainboard/google/parrot/mainboard.c +++ b/src/mainboard/google/parrot/mainboard.c @@ -57,7 +57,8 @@ static int parrot_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ } else { len += smbios_write_type41( current, handle, @@ -66,7 +67,8 @@ static int parrot_onboard_smbios_data(struct device *dev, int *handle, 0, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ } return len; diff --git a/src/mainboard/google/rambi/mainboard.c b/src/mainboard/google/rambi/mainboard.c index 15faac9bf81..d3f6164cd38 100644 --- a/src/mainboard/google/rambi/mainboard.c +++ b/src/mainboard/google/rambi/mainboard.c @@ -142,7 +142,8 @@ static int mainboard_smbios_data(struct device *dev, int *handle, BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ #endif #ifdef BOARD_TOUCHSCREEN_NAME len += smbios_write_type41( @@ -152,7 +153,8 @@ static int mainboard_smbios_data(struct device *dev, int *handle, BOARD_TOUCHSCREEN_I2C_BUS, /* segment */ BOARD_TOUCHSCREEN_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ #endif return len; } diff --git a/src/mainboard/google/slippy/mainboard.c b/src/mainboard/google/slippy/mainboard.c index 4bbc1d6907a..b98fc8a3809 100644 --- a/src/mainboard/google/slippy/mainboard.c +++ b/src/mainboard/google/slippy/mainboard.c @@ -54,7 +54,8 @@ static int mainboard_smbios_data(struct device *dev, int *handle, BOARD_LIGHTSENSOR_I2C_BUS, /* segment */ BOARD_LIGHTSENSOR_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ len += smbios_write_type41( current, handle, @@ -63,7 +64,8 @@ static int mainboard_smbios_data(struct device *dev, int *handle, BOARD_TRACKPAD_I2C_BUS, /* segment */ BOARD_TRACKPAD_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ len += smbios_write_type41( current, handle, @@ -72,7 +74,8 @@ static int mainboard_smbios_data(struct device *dev, int *handle, BOARD_TOUCHSCREEN_I2C_BUS, /* segment */ BOARD_TOUCHSCREEN_I2C_ADDR, /* bus */ 0, /* device */ - 0); /* function */ + 0, /* function */ + SMBIOS_DEVICE_TYPE_OTHER); /* device type */ return len; } From e8e92d60c4e2a17542a98bdfb3a533060d26a281 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 7 May 2019 17:29:21 -0700 Subject: [PATCH 400/588] endian.h: Add be32dec/be32enc family of functions Libpayload has a family of functions that can "encode" or "decode" an endian-specific integer onto a byte stream pointer. These allow writing more pretty code than a raw be32_to_cpu/cpu_to_be32 with pointer casts in many (de-)serialization scenarios, so let's add them to coreboot as well. Change-Id: I049c5665484da12b3cf977a529310b0bde177d2d Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32856 Reviewed-by: Aaron Durbin Tested-by: build bot (Jenkins) --- src/include/endian.h | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/include/endian.h b/src/include/endian.h index 08636f3da61..8dc18542ae0 100644 --- a/src/include/endian.h +++ b/src/include/endian.h @@ -85,6 +85,32 @@ #define setbits_8(addr, set) setbits_8(addr, 0, set) #ifndef __ROMCC__ +/* be16dec/be32dec/be64dec/le16dec/le32dec/le64dec family of functions. */ +#define DEFINE_ENDIAN_DEC(endian, width) \ + static inline uint##width##_t endian##width##dec(const void *p) \ + { \ + return endian##width##_to_cpu(*(uint##width##_t *)p); \ + } +DEFINE_ENDIAN_DEC(be, 16) +DEFINE_ENDIAN_DEC(be, 32) +DEFINE_ENDIAN_DEC(be, 64) +DEFINE_ENDIAN_DEC(le, 16) +DEFINE_ENDIAN_DEC(le, 32) +DEFINE_ENDIAN_DEC(le, 64) + +/* be16enc/be32enc/be64enc/le16enc/le32enc/le64enc family of functions. */ +#define DEFINE_ENDIAN_ENC(endian, width) \ + static inline void endian##width##enc(void *p, uint##width##_t u) \ + { \ + *(uint##width##_t *)p = cpu_to_##endian##width(u); \ + } +DEFINE_ENDIAN_ENC(be, 16) +DEFINE_ENDIAN_ENC(be, 32) +DEFINE_ENDIAN_ENC(be, 64) +DEFINE_ENDIAN_ENC(le, 16) +DEFINE_ENDIAN_ENC(le, 32) +DEFINE_ENDIAN_ENC(le, 64) + /* * Portable (API) endian support that can be used in code that is shared * with userspace (man 3 endian) tools. From 2b6da7f326bf84a8eab3684edf5e5814e9c23385 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Thu, 16 May 2019 16:22:18 -0700 Subject: [PATCH 401/588] commonlib/stdlib.h: Remove printf() from coreboot coreboot should not have a definition of printf() anywhere -- it's too easy to accidentally sneak it into code otherwise. Where that is needed in code shared with userspace utilities, we should instead use printk() and define a shim for that for the userspace side. Change-Id: Iaa459df7122c88beb56695eee7c252d90bbde861 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32857 Reviewed-by: Patrick Georgi Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/commonlib/include/commonlib/stdlib.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commonlib/include/commonlib/stdlib.h b/src/commonlib/include/commonlib/stdlib.h index 1a05eebd55d..4a3671c7ab8 100644 --- a/src/commonlib/include/commonlib/stdlib.h +++ b/src/commonlib/include/commonlib/stdlib.h @@ -38,11 +38,11 @@ #if CONFIG(COREBOOT_BUILD) #include #include -#define printf(...) printk(BIOS_ERR, __VA_ARGS__) #define HALT(x) halt() #else #include -#define HALT(x) +#define printk(level, ...) printf(__VA_ARGS__) +#define HALT(x) abort() #endif static inline void *xmalloc_work(size_t size, const char *file, @@ -50,7 +50,7 @@ static inline void *xmalloc_work(size_t size, const char *file, { void *ret = malloc(size); if (!ret && size) { - printf("%s/%s/line %d: Failed to malloc %zu bytes\n", + printk(BIOS_ERR, "%s/%s/line %d: Failed to malloc %zu bytes\n", file, func, line, size); while (1) HALT(1); From 66c77c2dc9b16d3b3522697ea04009aad1c8ba79 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 13 May 2019 17:45:27 -0700 Subject: [PATCH 402/588] console: Move poor-man's atoi() into string.h vtxprintf.c seems to have been written before string.h was as fleshed out as it is today -- this patch removes some custom implementation of stuff we now have globally. It also makes the skip_atoi() function globally available, because I need it somewhere else, and while we maybe don't want a huge fully-featured string parsing library in coreboot, being able to parse an integer is occasionally useful. Change-Id: Iecb2b970aecfc768540d2bf8b3023445f54853a4 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32858 Tested-by: build bot (Jenkins) Reviewed-by: Alex Thiessen --- src/console/vtxprintf.c | 22 ++++------------------ src/include/string.h | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c index f42ed6d0776..c429ac79e22 100644 --- a/src/console/vtxprintf.c +++ b/src/console/vtxprintf.c @@ -24,20 +24,6 @@ #define SUPPORT_64BIT_INTS #endif -/* haha, don't need ctype.c */ -#define isdigit(c) ((c) >= '0' && (c) <= '9') -#define is_digit isdigit -#define isxdigit(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F')) - -static int skip_atoi(const char **s) -{ - int i = 0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - #define ZEROPAD 1 /* pad with zero */ #define SIGN 2 /* unsigned/signed long */ #define PLUS 4 /* show plus */ @@ -175,8 +161,8 @@ int vtxprintf(void (*tx_byte)(unsigned char byte, void *data), /* get field width */ field_width = -1; - if (is_digit(*fmt)) { - field_width = skip_atoi(&fmt); + if (isdigit(*fmt)) { + field_width = skip_atoi((char **)&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ @@ -191,8 +177,8 @@ int vtxprintf(void (*tx_byte)(unsigned char byte, void *data), precision = -1; if (*fmt == '.') { ++fmt; - if (is_digit(*fmt)) { - precision = skip_atoi(&fmt); + if (isdigit(*fmt)) { + precision = skip_atoi((char **)&fmt); } else if (*fmt == '*') { ++fmt; /* it's the next argument */ diff --git a/src/include/string.h b/src/include/string.h index 4a2f5e9ee66..c56a760a047 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -178,4 +178,19 @@ static inline int tolower(int c) c -= 'A'-'a'; return c; } + +/* + * Parses an unsigned integer and moves the input pointer forward to the first + * character that's not a valid digit. s and *s must not be NULL. Result + * undefined if it overruns the return type size. + */ +static inline unsigned int skip_atoi(char **s) +{ + unsigned int i = 0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + #endif /* STRING_H */ From b3f852fba3cfd4ebde8cd7a34df069ba4cebe7a1 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 16:58:24 -0700 Subject: [PATCH 403/588] fit: Add "board-skuX" (without -rev) to allowed compatible strings In some cases we may have boards that need to differentiate SKUs but don't really want to differentiate revisions (at least for some SKUs). Let's add a compatible string match that includes only the SKU but not the revision so that kernel DTSes don't have to specify every possible revision if they want to match this. This patch was adapted from depthcharge's http://crosreview.com/1512004 Change-Id: Ib88862424b350a213761f5662fe170a1f8fccc7f Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32859 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/fit.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/fit.c b/src/lib/fit.c index a8bca47bdc6..3aad806f2e4 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -63,6 +63,14 @@ static void fit_add_default_compat_strings(void) fit_add_compat_string(compat_string); } + if (sku_id() != UNDEFINED_STRAPPING_ID) { + snprintf(compat_string, sizeof(compat_string), "%s,%s-sku%u", + CONFIG_MAINBOARD_VENDOR, CONFIG_MAINBOARD_PART_NUMBER, + sku_id()); + + fit_add_compat_string(compat_string); + } + if (board_id() != UNDEFINED_STRAPPING_ID) { snprintf(compat_string, sizeof(compat_string), "%s,%s-rev%u", CONFIG_MAINBOARD_VENDOR, CONFIG_MAINBOARD_PART_NUMBER, From a5ea3a271bbaa10f03115ffe3f473a07ca95c5ab Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 7 May 2019 17:38:12 -0700 Subject: [PATCH 404/588] device_tree: Use be32dec/be32enc where appropriate This patch rewrites some of the device tree code to use the new be32dec/be32enc helpers where they can make the code cleaner. Change-Id: I437bbd6645a556ae9a0cfe6ea14638098e4c3606 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32860 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/device_tree.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 79561a69b84..8dbc510c10b 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -56,7 +56,7 @@ int fdt_next_property(const void *blob, uint32_t offset, int fdt_node_name(const void *blob, uint32_t offset, const char **name) { uint8_t *ptr = ((uint8_t *)blob) + offset; - if (be32toh(*(uint32_t *)ptr) != FDT_TOKEN_BEGIN_NODE) + if (be32dec(ptr) != FDT_TOKEN_BEGIN_NODE) return 0; ptr += 4; @@ -358,14 +358,14 @@ static void dt_flatten_prop(struct device_tree_property *prop, uint8_t *dstruct = (uint8_t *)*struct_start; uint8_t *dstrings = (uint8_t *)*strings_start; - *((uint32_t *)dstruct) = htobe32(FDT_TOKEN_PROPERTY); + be32enc(dstruct, FDT_TOKEN_PROPERTY); dstruct += sizeof(uint32_t); - *((uint32_t *)dstruct) = htobe32(prop->prop.size); + be32enc(dstruct, prop->prop.size); dstruct += sizeof(uint32_t); uint32_t name_offset = (uintptr_t)dstrings - (uintptr_t)strings_base; - *((uint32_t *)dstruct) = htobe32(name_offset); + be32enc(dstruct, name_offset); dstruct += sizeof(uint32_t); strcpy((char *)dstrings, prop->prop.name); @@ -385,7 +385,7 @@ static void dt_flatten_node(const struct device_tree_node *node, uint8_t *dstruct = (uint8_t *)*struct_start; uint8_t *dstrings = (uint8_t *)*strings_start; - *((uint32_t *)dstruct) = htobe32(FDT_TOKEN_BEGIN_NODE); + be32enc(dstruct, FDT_TOKEN_BEGIN_NODE); dstruct += sizeof(uint32_t); strcpy((char *)dstruct, node->name); @@ -401,7 +401,7 @@ static void dt_flatten_node(const struct device_tree_node *node, dt_flatten_node(child, (void **)&dstruct, strings_base, (void **)&dstrings); - *((uint32_t *)dstruct) = htobe32(FDT_TOKEN_END_NODE); + be32enc(dstruct, FDT_TOKEN_END_NODE); dstruct += sizeof(uint32_t); *struct_start = dstruct; @@ -489,9 +489,9 @@ void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp, struct device_tree_property *prop; list_for_each(prop, node->properties, list_node) { if (addrcp && !strcmp("#address-cells", prop->prop.name)) - *addrcp = be32toh(*(u32 *)prop->prop.data); + *addrcp = be32dec(prop->prop.data); if (sizecp && !strcmp("#size-cells", prop->prop.name)) - *sizecp = be32toh(*(u32 *)prop->prop.data); + *sizecp = be32dec(prop->prop.data); } } From e0b9aea7be96f1d724a6c794dd617122125f1ba6 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Mon, 28 Jan 2019 18:14:13 +0100 Subject: [PATCH 405/588] lib/bootblock: Sanitize CMOS after bootblock_*_early_init() CMOS isn't used that early, but the chipset initialization may be required to access it. In one instance, Intel Apollo Lake, the sanitize_cmos() function seems to hang if called before bootblock_soc_early_init(). The missing step is fast_spi_early_init(). But even without, one might expect sanitize_cmos() to return eventually (it didn't within about 20min). Change-Id: I6e1a029e4be7e109be43a3dad944bd7e05ea1f02 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/31349 Tested-by: build bot (Jenkins) Reviewed-by: Alex Thiessen --- src/lib/bootblock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/bootblock.c b/src/lib/bootblock.c index 43674effc7a..c28a67aceb5 100644 --- a/src/lib/bootblock.c +++ b/src/lib/bootblock.c @@ -42,12 +42,12 @@ asmlinkage void bootblock_main_with_timestamp(uint64_t base_timestamp, timestamps[i].entry_stamp); } - sanitize_cmos(); - cmos_post_init(); - bootblock_soc_early_init(); bootblock_mainboard_early_init(); + sanitize_cmos(); + cmos_post_init(); + if (CONFIG(BOOTBLOCK_CONSOLE)) { console_init(); exception_init(); From dedf66ecdf79edece1039fe8bd019a0a544cfccb Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 12:35:48 +0200 Subject: [PATCH 406/588] cpu/amd/quadcore: Remove variable set but not used Change-Id: I73f35ea80976ab445c797c4800b1e2fd24d34fdf Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32893 Reviewed-by: Marshall Dawson Tested-by: build bot (Jenkins) --- src/cpu/amd/quadcore/quadcore.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpu/amd/quadcore/quadcore.c b/src/cpu/amd/quadcore/quadcore.c index ad4a7ead6d1..125876badff 100644 --- a/src/cpu/amd/quadcore/quadcore.c +++ b/src/cpu/amd/quadcore/quadcore.c @@ -95,13 +95,13 @@ void real_start_other_core(uint32_t nodeid, uint32_t cores) */ /* Wait for the first core of each compute unit to start... */ - uint32_t timeout; for (i = 1; i < cores + 1; i++) { if (!(i & 0x1)) { uint32_t ap_apicid = get_boot_apic_id(nodeid, i); - timeout = wait_cpu_state(ap_apicid, - F10_APSTATE_ASLEEP, F10_APSTATE_ASLEEP); + /* Timeout */ + wait_cpu_state(ap_apicid, F10_APSTATE_ASLEEP, + F10_APSTATE_ASLEEP); } } From 3d23890c65e4a0c08bc346e8c3c2b4161440b4c6 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 21 May 2019 21:35:02 +0200 Subject: [PATCH 407/588] soc/intel/denverton_ns: Remove variable set but not used Change-Id: Ic04231525c1aaaf3afc8c11cddc409b1f5b46743 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32913 Reviewed-by: Patrick Georgi Reviewed-by: David Guckian Tested-by: build bot (Jenkins) --- src/soc/intel/denverton_ns/cpu.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/soc/intel/denverton_ns/cpu.c b/src/soc/intel/denverton_ns/cpu.c index 2a631718c02..fc1024afa7f 100644 --- a/src/soc/intel/denverton_ns/cpu.c +++ b/src/soc/intel/denverton_ns/cpu.c @@ -38,7 +38,6 @@ static struct smm_relocation_attrs relo_attrs; static void dnv_configure_mca(void) { msr_t msr; - int num_banks; struct cpuid_result cpuid_regs; /* Check feature flag in CPUID.(EAX=1):EDX[7]==1 MCE @@ -48,7 +47,6 @@ static void dnv_configure_mca(void) return; msr = rdmsr(IA32_MCG_CAP); - num_banks = msr.lo & IA32_MCG_CAP_COUNT_MASK; if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) { /* Enable all error logging */ msr.lo = msr.hi = 0xffffffff; From ce83f3103c9b7d0e6daa6b95544d880660d0b6e9 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 18:31:38 +0200 Subject: [PATCH 408/588] nb/intel/haswell: Remove variable set but not used Change-Id: I4e7f74f67f03131fae205a93dae3d61eca9cc0c7 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32895 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/northbridge/intel/haswell/raminit.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c index c24bb67db7c..9beb23cc8ed 100644 --- a/src/northbridge/intel/haswell/raminit.c +++ b/src/northbridge/intel/haswell/raminit.c @@ -186,7 +186,7 @@ void sdram_initialize(struct pei_data *pei_data) void setup_sdram_meminfo(struct pei_data *pei_data) { - u32 addr_decoder_common, addr_decode_ch[2]; + u32 addr_decode_ch[2]; struct memory_info* mem_info; struct dimm_info *dimm; int ddr_frequency; @@ -199,7 +199,8 @@ void setup_sdram_meminfo(struct pei_data *pei_data) die("Failed to add memory info to CBMEM.\n"); memset(mem_info, 0, sizeof(struct memory_info)); - addr_decoder_common = MCHBAR32(0x5000); + /* FIXME: Do we need to read MCHBAR32(0x5000) ? */ + MCHBAR32(0x5000); addr_decode_ch[0] = MCHBAR32(0x5004); addr_decode_ch[1] = MCHBAR32(0x5008); From 0c89c1c05e514c8c6ddc5a844f84a2b422f1bd56 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 18:39:27 +0200 Subject: [PATCH 409/588] nb/intel/x4x/early_init.c: Remove variable set but not used Change-Id: I8d0ab8bdc506592ef1d731e557b2397481aed725 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32896 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/northbridge/intel/x4x/early_init.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/northbridge/intel/x4x/early_init.c b/src/northbridge/intel/x4x/early_init.c index d019ffd7f50..a58f2ba6e9d 100644 --- a/src/northbridge/intel/x4x/early_init.c +++ b/src/northbridge/intel/x4x/early_init.c @@ -150,7 +150,6 @@ static void init_egress(void) static void init_dmi(void) { u32 reg32; - u16 reg16; /* Assume IGD present */ @@ -224,9 +223,11 @@ static void init_dmi(void) /* ASPM on DMI link */ RCBA16(0x1a8) &= ~0x3; - reg16 = RCBA16(0x1a8); + /* FIXME: Do we need to read RCBA16(0x1a8)? */ + RCBA16(0x1a8); RCBA32(0x2010) = (RCBA32(0x2010) & ~(0x3 << 10)) | (1 << 10); - reg32 = RCBA32(0x2010); + /* FIXME: Do we need to read RCBA32(0x2010)? */ + RCBA32(0x2010); /* Set up VC1 max time */ RCBA32(0x1c) = (RCBA32(0x1c) & ~0x7f0000) | 0x120000; @@ -240,7 +241,8 @@ static void init_dmi(void) DMIBAR16(0x210) = (DMIBAR16(0x210) & ~(0xff7)) | 0x101; DMIBAR32(0x88) &= ~0x3; DMIBAR32(0x88) |= 0x3; - reg16 = DMIBAR16(0x88); + /* FIXME: Do we need to read RCBA16(0x88)? */ + DMIBAR16(0x88); } static void x4x_prepare_resume(int s3resume) From f00d37342c7fcabd9760ac69976227752e5c96f1 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 18:52:58 +0200 Subject: [PATCH 410/588] nb/intel/pineview/early_init.c: Remove variable set but not used Change-Id: If9ca551794a52e47a3649b126c3f061a68c494e4 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32897 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/northbridge/intel/pineview/early_init.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/northbridge/intel/pineview/early_init.c b/src/northbridge/intel/pineview/early_init.c index a0d53052550..509ab4ee0cc 100644 --- a/src/northbridge/intel/pineview/early_init.c +++ b/src/northbridge/intel/pineview/early_init.c @@ -119,9 +119,7 @@ static void early_graphics_setup(void) static void early_misc_setup(void) { - u32 reg32; - - reg32 = MCHBAR32(0x30); + MCHBAR32(0x30); MCHBAR32(0x30) = 0x21800; DMIBAR32(0x2c) = 0x86000040; pci_write_config32(PCI_DEV(0, 0x1e, 0), 0x18, 0x00020200); @@ -129,9 +127,9 @@ static void early_misc_setup(void) early_graphics_setup(); - reg32 = MCHBAR32(0x40); + MCHBAR32(0x40); MCHBAR32(0x40) = 0x0; - reg32 = MCHBAR32(0x40); + MCHBAR32(0x40); MCHBAR32(0x40) = 0x8; pci_write_config8(LPC, 0x8, 0x1d); From 83339ab3ebcf1e0b8e4cbcd44c13d93049e161b6 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 18:59:28 +0200 Subject: [PATCH 411/588] soc/intel/fsp_broadwell_de/romstage: Remove variable set but not used Change-Id: I3e304b9b19978c4100ef3486088d809c2a7fe1d7 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32898 Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/soc/intel/fsp_broadwell_de/romstage/romstage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c index 121cb25d615..38cd9476c59 100644 --- a/src/soc/intel/fsp_broadwell_de/romstage/romstage.c +++ b/src/soc/intel/fsp_broadwell_de/romstage/romstage.c @@ -94,7 +94,6 @@ void *asmlinkage main(FSP_INFO_HEADER *fsp_info_header) */ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) { - int cbmem_was_initted; void *cbmem_hob_ptr; post_code(0x4a); @@ -113,7 +112,7 @@ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) late_mainboard_romstage_entry(); post_code(0x4d); - cbmem_was_initted = !cbmem_recovery(0); + cbmem_recovery(0); /* Save the HOB pointer in CBMEM to be used in ramstage*/ cbmem_hob_ptr = cbmem_add(CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr)); From 0e0c7a3dd8f93b50d4ff494639b5e2ff45ffaeaa Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Mon, 20 May 2019 19:04:09 +0200 Subject: [PATCH 412/588] soc/intel/fsp_baytrail/romstage: Remove variable set but not used Change-Id: Ic04cb7c51862bea4d01f853ee2c88cc03c414e35 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32899 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/soc/intel/fsp_baytrail/romstage/romstage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/soc/intel/fsp_baytrail/romstage/romstage.c b/src/soc/intel/fsp_baytrail/romstage/romstage.c index 030b5dfeed9..52f4dc9d63e 100644 --- a/src/soc/intel/fsp_baytrail/romstage/romstage.c +++ b/src/soc/intel/fsp_baytrail/romstage/romstage.c @@ -218,7 +218,6 @@ void main(FSP_INFO_HEADER *fsp_info_header) */ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) { - int cbmem_was_initted; void *cbmem_hob_ptr; uint32_t prev_sleep_state; @@ -245,7 +244,7 @@ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) late_mainboard_romstage_entry(); post_code(0x4c); - cbmem_was_initted = !cbmem_recovery(prev_sleep_state == ACPI_S3); + cbmem_recovery(prev_sleep_state == ACPI_S3); /* Save the HOB pointer in CBMEM to be used in ramstage*/ cbmem_hob_ptr = cbmem_add(CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr)); From 7687617d0020b0a234d8d299a9d31ec363512436 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Wed, 8 May 2019 13:29:03 +0300 Subject: [PATCH 413/588] util/autoport: Mention i2c-i801 module in readme.md SMBus adapter will not appear if i2c-i801 module is not loaded. Added it to the readme. Change-Id: I3de0e02f13178d78b8cc02a74a745ad66e929070 Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/32681 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- util/autoport/readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/util/autoport/readme.md b/util/autoport/readme.md index 4683d8dd10e..cfa8c36a386 100644 --- a/util/autoport/readme.md +++ b/util/autoport/readme.md @@ -120,6 +120,7 @@ on the vendor firmware with just one module in channel 0, slot 0, and check the the EEPROM has. Under Linux, you can use these commands to see what is on SMBus: $ sudo modprobe i2c-dev + $ sudo modprobe i2c-i801 $ sudo i2cdetect -l i2c-0 i2c i915 gmbus ssc I2C adapter i2c-1 i2c i915 gmbus vga I2C adapter From 55fffa29c236f054c6b40fb971f7974f2dbd705d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Sun, 10 Jun 2018 05:18:50 +0300 Subject: [PATCH 414/588] AGESA binaryPI: Sync STRUCT_NAME definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While not implemented, copying the definitions from later AGESA/AMD.h to older helps us avoid lots of preprocessor directives. Change-Id: I34edc1ca23e9c063c4286273c53249ff0a953798 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31510 Reviewed-by: Marshall Dawson Tested-by: build bot (Jenkins) --- src/drivers/amd/agesa/eventlog.c | 3 ++- src/vendorcode/amd/agesa/f12/AMD.h | 5 ++++- src/vendorcode/amd/agesa/f14/AMD.h | 5 ++++- src/vendorcode/amd/agesa/f15tn/AMD.h | 5 ++++- src/vendorcode/amd/agesa/f16kb/AMD.h | 4 +++- src/vendorcode/amd/pi/00630F01/AMD.h | 2 ++ src/vendorcode/amd/pi/00660F01/AMD.h | 9 +++++++++ src/vendorcode/amd/pi/00730F01/AMD.h | 3 +++ 8 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c index 6cfcde520b7..23e31ba7d31 100644 --- a/src/drivers/amd/agesa/eventlog.c +++ b/src/drivers/amd/agesa/eventlog.c @@ -29,8 +29,9 @@ static const char undefined[] = "undefined"; static const char *AgesaFunctionNameStr[] = { "AmdInitRecovery", "AmdCreateStruct", "AmdInitEarly", "AmdInitEnv", "AmdInitLate", "AmdInitMid", "AmdInitPost", "AmdInitReset", "AmdInitResume", "AmdReleaseStruct", - "AmdS3LateRestore","AmdS3Save", "AmdGetApicId", "AmdGetPciAddress", "AmdIdentifyCore", + "AmdS3LateRestore", "AmdS3Save", "AmdGetApicId", "AmdGetPciAddress", "AmdIdentifyCore", "AmdReadEventLog", "AmdGetAvailableExeCacheSize", "AmdLateRunApTask", "AmdIdentifyDimm", + "Amd2dDataEye", "AmdS3FinalRestore", "AmdInitRtb" }; /* heapManager.h */ diff --git a/src/vendorcode/amd/agesa/f12/AMD.h b/src/vendorcode/amd/agesa/f12/AMD.h index 179c3f5da0b..31c0b347a0b 100644 --- a/src/vendorcode/amd/agesa/f12/AMD.h +++ b/src/vendorcode/amd/agesa/f12/AMD.h @@ -148,7 +148,10 @@ typedef enum { AMD_READ_EVENT_LOG, ///< AmdReadEventLog general service handle AMD_GET_EXECACHE_SIZE, ///< AmdGetAvailableExeCacheSize general service handle AMD_LATE_RUN_AP_TASK, ///< AmdLateRunApTask entry point handle - AMD_IDENTIFY_DIMMS ///< AmdIdentifyDimm general service handle + AMD_IDENTIFY_DIMMS, ///< AmdIdentifyDimm general service handle + AMD_GET_2D_DATA_EYE, ///< AmdGet2DDataEye general service handle + AMD_S3FINAL_RESTORE, ///< AmdS3FinalRestore entry point handle + AMD_INIT_RTB ///< AmdInitRtb entry point handle } AGESA_STRUCT_NAME; /* ResetType constant values */ diff --git a/src/vendorcode/amd/agesa/f14/AMD.h b/src/vendorcode/amd/agesa/f14/AMD.h index 9d443beb1ee..c1cfaa1f32c 100644 --- a/src/vendorcode/amd/agesa/f14/AMD.h +++ b/src/vendorcode/amd/agesa/f14/AMD.h @@ -147,7 +147,10 @@ typedef enum { AMD_READ_EVENT_LOG, ///< AmdReadEventLog general service handle AMD_GET_EXECACHE_SIZE, ///< AmdGetAvailableExeCacheSize general service handle AMD_LATE_RUN_AP_TASK, ///< AmdLateRunApTask entry point handle - AMD_IDENTIFY_DIMMS ///< AmdIdentifyDimm general service handle + AMD_IDENTIFY_DIMMS, ///< AmdIdentifyDimm general service handle + AMD_GET_2D_DATA_EYE, ///< AmdGet2DDataEye general service handle + AMD_S3FINAL_RESTORE, ///< AmdS3FinalRestore entry point handle + AMD_INIT_RTB ///< AmdInitRtb entry point handle } AGESA_STRUCT_NAME; /* ResetType constant values */ diff --git a/src/vendorcode/amd/agesa/f15tn/AMD.h b/src/vendorcode/amd/agesa/f15tn/AMD.h index 31d38db5563..27326ecef8d 100644 --- a/src/vendorcode/amd/agesa/f15tn/AMD.h +++ b/src/vendorcode/amd/agesa/f15tn/AMD.h @@ -144,7 +144,10 @@ typedef enum { AMD_READ_EVENT_LOG, ///< AmdReadEventLog general service handle AMD_GET_EXECACHE_SIZE, ///< AmdGetAvailableExeCacheSize general service handle AMD_LATE_RUN_AP_TASK, ///< AmdLateRunApTask entry point handle - AMD_IDENTIFY_DIMMS ///< AmdIdentifyDimm general service handle + AMD_IDENTIFY_DIMMS, ///< AmdIdentifyDimm general service handle + AMD_GET_2D_DATA_EYE, ///< AmdGet2DDataEye general service handle + AMD_S3FINAL_RESTORE, ///< AmdS3FinalRestore entry point handle + AMD_INIT_RTB ///< AmdInitRtb entry point handle } AGESA_STRUCT_NAME; /* ResetType constant values */ diff --git a/src/vendorcode/amd/agesa/f16kb/AMD.h b/src/vendorcode/amd/agesa/f16kb/AMD.h index bfce993bce0..83d538f3e21 100644 --- a/src/vendorcode/amd/agesa/f16kb/AMD.h +++ b/src/vendorcode/amd/agesa/f16kb/AMD.h @@ -143,7 +143,9 @@ typedef enum { AMD_GET_EXECACHE_SIZE, ///< AmdGetAvailableExeCacheSize general service handle AMD_LATE_RUN_AP_TASK, ///< AmdLateRunApTask entry point handle AMD_IDENTIFY_DIMMS, ///< AmdIdentifyDimm general service handle - AMD_GET_2D_DATA_EYE ///< AmdGet2DDataEye general service handle + AMD_GET_2D_DATA_EYE, ///< AmdGet2DDataEye general service handle + AMD_S3FINAL_RESTORE, ///< AmdS3FinalRestore entry point handle + AMD_INIT_RTB ///< AmdInitRtb entry point handle } AGESA_STRUCT_NAME; /* ResetType constant values */ diff --git a/src/vendorcode/amd/pi/00630F01/AMD.h b/src/vendorcode/amd/pi/00630F01/AMD.h index 68f7c328185..f70b1285080 100644 --- a/src/vendorcode/amd/pi/00630F01/AMD.h +++ b/src/vendorcode/amd/pi/00630F01/AMD.h @@ -149,6 +149,8 @@ typedef enum { AMD_IDENTIFY_DIMMS = 0x00033000, ///< AmdIdentifyDimm general service handle AMD_GET_2D_DATA_EYE = 0x00034000, ///< AmdGet2DDataEye general service handle AMD_S3FINAL_RESTORE = 0x00035000, ///< AmdS3FinalRestore entry point handle + AMD_INIT_RTB = 0x00036000, /* reserved */ + AMD_HEAP_ALLOCATE_BUFFER = 0x00038000, AMD_HEAP_DEALLOCATE_BUFFER = 0x00039000, FCH_INIT_RESET = 0x00040000, diff --git a/src/vendorcode/amd/pi/00660F01/AMD.h b/src/vendorcode/amd/pi/00660F01/AMD.h index aa68204e8d2..54abf80af07 100644 --- a/src/vendorcode/amd/pi/00660F01/AMD.h +++ b/src/vendorcode/amd/pi/00660F01/AMD.h @@ -126,6 +126,11 @@ typedef enum ACCESS_WIDTH { AccessS3SaveWidth64, ///< Save 64 bits data. } ACCESS_WIDTH; +/* When AMD rolled out CarrizoPI, they made a bad choice of removing + * an entry from the middle of the enumeration list. + */ +#define AMD_S3_SAVE_REMOVED + /// AGESA struct name typedef enum { // AGESA BASIC FUNCTIONS @@ -140,6 +145,10 @@ typedef enum { AMD_INIT_RESUME = 0x00029000, ///< AmdInitResume entry point handle AMD_RELEASE_STRUCT = 0x0002A000, ///< AmdReleaseStruct handle AMD_S3LATE_RESTORE = 0x0002B000, ///< AmdS3LateRestore entry point handle +#if 0 + /* This was removed, shifting everything else up.*/ + AMD_S3_SAVE = 0x0002C000, +#endif AMD_GET_APIC_ID = 0x0002C000, ///< AmdGetApicId entry point handle AMD_GET_PCI_ADDRESS = 0x0002D000, ///< AmdGetPciAddress entry point handle AMD_IDENTIFY_CORE = 0x0002E000, ///< AmdIdentifyCore general service handle diff --git a/src/vendorcode/amd/pi/00730F01/AMD.h b/src/vendorcode/amd/pi/00730F01/AMD.h index 1b6fdb26e8b..13fc29afebb 100644 --- a/src/vendorcode/amd/pi/00730F01/AMD.h +++ b/src/vendorcode/amd/pi/00730F01/AMD.h @@ -148,6 +148,9 @@ typedef enum { AMD_LATE_RUN_AP_TASK = 0x00032000, ///< AmdLateRunApTask entry point handle AMD_IDENTIFY_DIMMS = 0x00033000, ///< AmdIdentifyDimm general service handle AMD_GET_2D_DATA_EYE = 0x00034000, ///< AmdGet2DDataEye general service handle + AMD_S3FINAL_RESTORE = 0x00035000, /* reserved */ + AMD_INIT_RTB = 0x00036000, /* reserved */ + AMD_HEAP_ALLOCATE_BUFFER = 0x00038000, AMD_HEAP_DEALLOCATE_BUFFER = 0x00039000, FCH_INIT_RESET = 0x00040000, From b4222a65adcbacdb056fea88abd300c897eabfc2 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 21 May 2019 13:41:50 -0600 Subject: [PATCH 415/588] util/romcc: Add extra NULL checks for member In each of these cases it is possible that 'member' is NULL at the beginning, which will skip the earlier while loops entirely and cause a NULL dereference later on. Add extra error checks to prevent this. Change-Id: Ib5873c0830b71397ef661976d387fc6ce33c5cd1 Signed-off-by: Jacob Garber Found-by: Coverity CID 1129147, 1129152, 1129153, 1129154 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32916 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 329cfd2433a..571a29f94b5 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -6228,6 +6228,8 @@ static size_t field_offset(struct compile_state *state, size += size_of(state, member->left); member = member->right; } + if (member == NULL) + internal_error(state, 0, "Member is NULL"); size += needed_padding(state, member, size); } else if ((type->type & TYPE_MASK) == TYPE_UNION) { @@ -6350,10 +6352,12 @@ static size_t index_offset(struct compile_state *state, i++; member = member->right; } - size += needed_padding(state, member, size); + if (member == NULL) + internal_error(state, 0, "Member is NULL"); if (i != index) { internal_error(state, 0, "Missing member index: %u", index); } + size += needed_padding(state, member, size); } else if ((type->type & TYPE_MASK) == TYPE_JOIN) { ulong_t i; @@ -6402,6 +6406,8 @@ static size_t index_reg_offset(struct compile_state *state, i++; member = member->right; } + if (member == NULL) + internal_error(state, 0, "Member is NULL"); if (i != index) { internal_error(state, 0, "Missing member index: %u", index); } @@ -6640,6 +6646,8 @@ static struct type *reg_type( offset += size; member = member->right; } + if (member == NULL) + internal_error(state, 0, "Member is NULL"); offset += reg_needed_padding(state, member, offset); member = reg_type(state, member, reg_offset - offset); break; From 4b688ab3fe6a8db4985a6e6cdad5def661f4066a Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 21 May 2019 18:55:34 -0600 Subject: [PATCH 416/588] util/romcc: Add null check for filename It is possible that 'filename' is still null in this if statement, so we add an extra check to prevent a null dereference in strcmp. Change-Id: Iaba95b63a4d552051e0c56445522de7274dfd0b3 Signed-off-by: Jacob Garber Found-by: Coverity CID 1395330 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32922 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 571a29f94b5..285b0237f46 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -1989,7 +1989,7 @@ static struct occurrence *new_occurrence(struct compile_state *state) (last->line == line) && (last->function == function) && ((last->filename == filename) || - (strcmp(last->filename, filename) == 0))) + (filename != NULL && strcmp(last->filename, filename) == 0))) { get_occurrence(last); return last; From 9742ae1d11dab3357835fab7d7e3577dde4e0480 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Thu, 16 May 2019 22:27:45 -0600 Subject: [PATCH 417/588] util/romcc: Fix memory leak The 'new_type' function already allocates memory, so it is only necessary to clone the existing type if this function is not called. Change-Id: I47065204c5f4b6bab022bd7ccf19838c3ce1f86e Signed-off-by: Jacob Garber Found-by: Coverity Scan CID 1129106 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32921 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index 285b0237f46..d60a9a7f831 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -12601,7 +12601,9 @@ static struct type *struct_declarator( } type = new_type(TYPE_BITFIELD, type, 0); type->elements = value->u.cval; - } + } else + type = clone_type(0, type); + return type; } @@ -12656,7 +12658,6 @@ static struct type *struct_or_union_specifier( done = 0; eat(state, TOK_COMMA); } - type = clone_type(0, type); type->field_ident = fident; if (*next) { *next = new_type(type_join, *next, type); From 298afb3140fa8f092b356ec89d8be2f5a36b530f Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 21 May 2019 14:42:24 -0600 Subject: [PATCH 418/588] util/romcc: Add extra null pointer check It is possible that 'lnode->val' is set to 0 on a previous iteration of the loop, so check that it is non-null here before dereferencing it. Change-Id: I9827dd5623eaf11240df605a8b50ff9e27a5fce0 Signed-off-by: Jacob Garber Found-by: Coverity CID 1129149 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32917 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- util/romcc/romcc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/util/romcc/romcc.c b/util/romcc/romcc.c index d60a9a7f831..2a158e5fe09 100644 --- a/util/romcc/romcc.c +++ b/util/romcc/romcc.c @@ -20944,7 +20944,8 @@ static void scc_visit_phi(struct compile_state *state, struct scc_state *scc, } } /* meet(const, const) = const or lattice low */ - else if (!constants_equal(state, lnode->val, tmp->val)) { + else if (lnode->val != 0 && + !constants_equal(state, lnode->val, tmp->val)) { lnode->val = 0; } From c72dc05acc12c65614079bd0de25809b80456141 Mon Sep 17 00:00:00 2001 From: Evan Green Date: Tue, 21 May 2019 15:39:00 -0700 Subject: [PATCH 419/588] mb/google/hatch/variants: Fix DPTF sensor IDs There are indeed two temperature sensors hooked up to the EC, but they are indexed as 0 and 1, not 1 and 2. BUG=b:132999028 TEST=Boot hatch with hardened EC, observe no more index overflows Change-Id: Ia7f503bc1dc941635db52fce40f217bf34da6d2b Signed-off-by: Evan Green Reviewed-on: https://review.coreboot.org/c/coreboot/+/32920 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Paul Menzel --- .../hatch/variants/baseboard/include/baseboard/acpi/dptf.asl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/acpi/dptf.asl b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/acpi/dptf.asl index 1384ccfeb70..ff7db493341 100644 --- a/src/mainboard/google/hatch/variants/baseboard/include/baseboard/acpi/dptf.asl +++ b/src/mainboard/google/hatch/variants/baseboard/include/baseboard/acpi/dptf.asl @@ -21,7 +21,7 @@ #define DPTF_CPU_ACTIVE_AC3 80 #define DPTF_CPU_ACTIVE_AC4 75 -#define DPTF_TSR0_SENSOR_ID 1 +#define DPTF_TSR0_SENSOR_ID 0 #define DPTF_TSR0_SENSOR_NAME "Thermal Sensor 1" #define DPTF_TSR0_PASSIVE 65 #define DPTF_TSR0_CRITICAL 75 @@ -31,7 +31,7 @@ #define DPTF_TSR0_ACTIVE_AC3 42 #define DPTF_TSR0_ACTIVE_AC4 39 -#define DPTF_TSR1_SENSOR_ID 2 +#define DPTF_TSR1_SENSOR_ID 1 #define DPTF_TSR1_SENSOR_NAME "Thermal Sensor 2" #define DPTF_TSR1_PASSIVE 65 #define DPTF_TSR1_CRITICAL 75 From b7fe7a1a8e033706f39c0fded5901f0f1dce7cfb Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Thu, 8 Mar 2018 16:32:43 -0800 Subject: [PATCH 420/588] intel/common/block/scs: Add ability to send early CMD0, CMD1 In order to improve boot time with emmc, add ability to send CMD0 and CMD1 early in romstage. This way, by the time system boots to payload, we are ready to continue with emmc setup and we don't need to send CMD0 in payload again, and wait for card to reset and be ready. BUG=b:78106689 TESTS = Boot to OS Force early_mmc_wake_hw() to return error, recover in payload Force an error in payload, make sure system can recover/boot Change-Id: I3488b077bf5100a1e0f2c879fb1436105607d25e Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/25068 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/commonlib/include/commonlib/cbmem_id.h | 2 + .../block/include/intelblocks/early_mmc.h | 80 +++++++++ src/soc/intel/common/block/scs/Kconfig | 10 ++ src/soc/intel/common/block/scs/Makefile.inc | 1 + src/soc/intel/common/block/scs/early_mmc.c | 166 ++++++++++++++++++ 5 files changed, 259 insertions(+) create mode 100644 src/soc/intel/common/block/include/intelblocks/early_mmc.h create mode 100644 src/soc/intel/common/block/scs/early_mmc.c diff --git a/src/commonlib/include/commonlib/cbmem_id.h b/src/commonlib/include/commonlib/cbmem_id.h index af79a590755..535ba3394c1 100644 --- a/src/commonlib/include/commonlib/cbmem_id.h +++ b/src/commonlib/include/commonlib/cbmem_id.h @@ -39,6 +39,7 @@ #define CBMEM_ID_IMD_SMALL 0x53a11439 #define CBMEM_ID_MEMINFO 0x494D454D #define CBMEM_ID_MMA_DATA 0x4D4D4144 +#define CBMEM_ID_MMC_STATUS 0x4d4d4353 #define CBMEM_ID_MPTABLE 0x534d5054 #define CBMEM_ID_MRCDATA 0x4d524344 #define CBMEM_ID_VAR_MRCDATA 0x4d524345 @@ -100,6 +101,7 @@ { CBMEM_ID_IMD_SMALL, "IMD SMALL " }, \ { CBMEM_ID_MEMINFO, "MEM INFO " }, \ { CBMEM_ID_MMA_DATA, "MMA DATA " }, \ + { CBMEM_ID_MMC_STATUS, "MMC STATUS " }, \ { CBMEM_ID_MPTABLE, "SMP TABLE " }, \ { CBMEM_ID_MRCDATA, "MRC DATA " }, \ { CBMEM_ID_VAR_MRCDATA, "VARMRC DATA" }, \ diff --git a/src/soc/intel/common/block/include/intelblocks/early_mmc.h b/src/soc/intel/common/block/include/intelblocks/early_mmc.h new file mode 100644 index 00000000000..69be40cf27a --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/early_mmc.h @@ -0,0 +1,80 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SOC_INTEL_COMMON_BLOCK_EARLY_MMC_H +#define SOC_INTEL_COMMON_BLOCK_EARLY_MMC_H + +#include + +/* + * Following should be defined in soc/iomap.h + * PRERAM_MMC_BASE_ADDRESS - Provide an address to setup emmc controller's + PCI BAR. + */ + +/* + * Structure for the following delay registers + * emmc_tx_data_cntl1: Tx Delay Control 1 (Tx_DATA_dly_1)-Offset 824h + * emmc_tx_data_cntl2: Tx Delay Control 2 (Tx_DATA_dly_2)-Offset 828h + * emmc_rx_cmd_data_cntl1: Rx CMD Data Delay Control 1 + * (Rx_CMD_Data_dly_1)-Offset 82Ch + * emmc_rx_cmd_data_cntl2: Rx CMD Data Path Delay Control 2 + * (Rx_CMD_Data_dly_2)-Offset 834h + * emmc_rx_strobe_cntl: Rx Strobe Delay Control + * (Rx_Strobe_Ctrl_Path)-Offset 830h + * emmc_tx_cmd_cntl: Tx CMD Delay Control (Tx_CMD_dly)-Offset 820h + */ +struct mmc_dll_params { + uint32_t emmc_tx_data_cntl1; + uint32_t emmc_tx_data_cntl2; + uint32_t emmc_rx_cmd_data_cntl1; + uint32_t emmc_rx_cmd_data_cntl2; + uint32_t emmc_rx_strobe_cntl; + uint32_t emmc_tx_cmd_cntl; +}; + +/* + * SOC specific API to get mmc min max frequencies. + * returns 0, if able to get f_min, f_max; otherwise returns -1 + */ +int soc_get_mmc_frequencies(uint32_t *f_min, uint32_t *f_max); +/* + * SOC specific API to configure mmc gpios. + * returns 0, if able to configure gpios; otherwise returns -1 + */ +int soc_configure_mmc_gpios(void); +/* + * SOC specific API to get mmc delay register settings. + * returns 0, if able to get register settings; otherwise returns -1 + */ +int soc_get_mmc_dll(struct mmc_dll_params *params); + +#if IS_ENABLED(CONFIG_SOC_INTEL_COMMON_EARLY_MMC_WAKE) +/* + * Initializes sdhci / mmc controller and sends CMD0, CMD1 to emmc card. + * In case of success: It returns 0 and adds cbmem entry CBMEM_ID_MMC_STATUS + * and sets it to 1. Payload can start by sending CMD1, there is no need to + * send CMD0 and wait for the card to be ready. + * In case of failure: It returns -1 and doesn't add cbmem entry. Payload + * should do complete initialization starting with CMD0. + */ +int early_mmc_wake_hw(void); +#else +static inline int early_mmc_wake_hw(void) +{ + return -1; +} +#endif /* CONFIG_SOC_INTEL_COMMON_EARLY_MMC_WAKE */ +#endif /* SOC_INTEL_COMMON_BLOCK_EARLY_MMC_H */ diff --git a/src/soc/intel/common/block/scs/Kconfig b/src/soc/intel/common/block/scs/Kconfig index 0a402137bcc..06ad8e4fa8e 100644 --- a/src/soc/intel/common/block/scs/Kconfig +++ b/src/soc/intel/common/block/scs/Kconfig @@ -2,3 +2,13 @@ config SOC_INTEL_COMMON_BLOCK_SCS bool help Intel Processor common storage and communication subsystem support + +config SOC_INTEL_COMMON_EARLY_MMC_WAKE + bool + default n + select COMMONLIB_STORAGE + select COMMONLIB_STORAGE_MMC + select SDHCI_CONTROLLER + help + Send CMD1 early in romstage to improve boot time. It requires emmc + DLL tuning parameters to be added to devicetree.cb diff --git a/src/soc/intel/common/block/scs/Makefile.inc b/src/soc/intel/common/block/scs/Makefile.inc index 1c2a6c6692f..1160802d032 100644 --- a/src/soc/intel/common/block/scs/Makefile.inc +++ b/src/soc/intel/common/block/scs/Makefile.inc @@ -1 +1,2 @@ ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SCS) += sd.c +romstage-$(CONFIG_SOC_INTEL_COMMON_EARLY_MMC_WAKE) += early_mmc.c diff --git a/src/soc/intel/common/block/scs/early_mmc.c b/src/soc/intel/common/block/scs/early_mmc.c new file mode 100644 index 00000000000..4b15bb48bb3 --- /dev/null +++ b/src/soc/intel/common/block/scs/early_mmc.c @@ -0,0 +1,166 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Intel Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EMMC_TX_CMD_CNTL_OFFSET 0x820 +#define EMMC_TX_DATA_CNTL1_OFFSET 0x824 +#define EMMC_TX_DATA_CNTL2_OFFSET 0x828 +#define EMMC_RX_CMD_DATA_CNTL1_OFFSET 0x82C +#define EMMC_RX_STROBE_CNTL_OFFSET 0x830 +#define EMMC_RX_CMD_DATA_CNTL2_OFFSET 0x834 + +void soc_sd_mmc_controller_quirks(struct sd_mmc_ctrlr *ctrlr) +{ + uint32_t f_min, f_max; + + if (soc_get_mmc_frequencies(&f_min, &f_max) < 0) { + printk(BIOS_ERR, + "MMC early init: failed to get mmc frequencies\n"); + return; + } + + ctrlr->f_min = f_min; + ctrlr->f_max = f_max; +} + +static void enable_mmc_controller_bar(void) +{ + pci_write_config32(PCH_DEV_EMMC, PCI_BASE_ADDRESS_0, + PRERAM_MMC_BASE_ADDRESS); + pci_write_config32(PCH_DEV_EMMC, PCI_COMMAND, + PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); +} + +static void disable_mmc_controller_bar(void) +{ + pci_write_config32(PCH_DEV_EMMC, PCI_BASE_ADDRESS_0, 0); + pci_write_config32(PCH_DEV_EMMC, PCI_COMMAND, + ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY)); +} + +static int set_mmc_dll(void *ioaddr) +{ + struct mmc_dll_params dll_params; + + if (soc_get_mmc_dll(&dll_params) < 0) { + printk(BIOS_ERR, + "MMC early init: failed to get mmc DLL parameters\n"); + return -1; + } + + write32(ioaddr + EMMC_TX_DATA_CNTL1_OFFSET, + dll_params.emmc_tx_data_cntl1); + write32(ioaddr + EMMC_TX_DATA_CNTL2_OFFSET, + dll_params.emmc_tx_data_cntl2); + write32(ioaddr + EMMC_RX_CMD_DATA_CNTL1_OFFSET, + dll_params.emmc_rx_cmd_data_cntl1); + write32(ioaddr + EMMC_RX_CMD_DATA_CNTL2_OFFSET, + dll_params.emmc_rx_cmd_data_cntl2); + write32(ioaddr + EMMC_RX_STROBE_CNTL_OFFSET, + dll_params.emmc_rx_strobe_cntl); + write32(ioaddr + EMMC_TX_CMD_CNTL_OFFSET, + dll_params.emmc_tx_cmd_cntl); + + return 0; +} + +static void set_early_mmc_wake_status(int32_t status) +{ + int32_t *ms_cbmem; + + ms_cbmem = cbmem_add(CBMEM_ID_MMC_STATUS, sizeof(int)); + + if (ms_cbmem == NULL) { + printk(BIOS_ERR, + "%s: Failed to add early mmc wake status to cbmem!\n", + __func__); + return; + } + + *ms_cbmem = status; +} + +int early_mmc_wake_hw(void) +{ + struct storage_media media; + struct sd_mmc_ctrlr *mmc_ctrlr; + struct sdhci_ctrlr *sdhci_ctrlr; + int err; + + if (acpi_is_wakeup_s3()) + return -1; + + /* Configure mmc gpios */ + if (soc_configure_mmc_gpios() < 0) { + printk(BIOS_ERR, + "%s: MMC early init: failed to configure mmc gpios\n", + __func__); + return -1; + } + /* Setup pci bar */ + enable_mmc_controller_bar(); + + /* Initialize sdhci */ + mmc_ctrlr = new_pci_sdhci_controller(PCH_DEV_EMMC); + if (mmc_ctrlr == NULL) + goto out_err; + + sdhci_ctrlr = container_of(mmc_ctrlr, struct sdhci_ctrlr, sd_mmc_ctrlr); + + /* set emmc DLL tuning parameters */ + if (set_mmc_dll(sdhci_ctrlr->ioaddr) < 0) + goto out_err; + + memset(&media, 0, sizeof(media)); + media.ctrlr = mmc_ctrlr; + SET_BUS_WIDTH(mmc_ctrlr, 1); + /* + * Set clock to 1 so that the driver can choose minimum frequency + * possible + */ + SET_CLOCK(mmc_ctrlr, 1); + + /* Reset emmc, send CMD0 */ + if (sd_mmc_go_idle(&media)) + goto out_err; + + /* Send CMD1 */ + err = mmc_send_op_cond(&media); + if (err != 0 && err != CARD_IN_PROGRESS) + goto out_err; + + disable_mmc_controller_bar(); + + set_early_mmc_wake_status(1); + return 0; + +out_err: + + disable_mmc_controller_bar(); + return -1; +} From ddf2bc5081e0eafc33af40a06f4217c5c851fa3f Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Fri, 30 Mar 2018 16:03:32 -0700 Subject: [PATCH 421/588] coreboot_tables: pass the early_mmc_wake_hw status to payload Pass the return value from early_mmc_wake_hw() to the payload so that payload can skip sending CMD0 and resetting the card in case of success or in case of a failure in firmware, payload can recover by sending CMD0 and resetting the card. BUG=b:78106689 TEST=Boot to OS Change-Id: Ia4c57d05433c3966118c3642913d7017958cce55 Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/25464 Reviewed-by: Lijian Zhao Tested-by: build bot (Jenkins) --- payloads/libpayload/include/coreboot_tables.h | 15 +++++++++++++++ payloads/libpayload/include/sysinfo.h | 1 + payloads/libpayload/libc/coreboot.c | 10 ++++++++++ .../include/commonlib/coreboot_tables.h | 15 +++++++++++++++ src/lib/coreboot_table.c | 19 +++++++++++++++++++ 5 files changed, 60 insertions(+) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 92e3f26180c..705e3486661 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -287,6 +287,21 @@ struct cb_macs { struct mac_address mac_addrs[0]; }; +#define CB_TAG_MMC_INFO 0x0034 +struct cb_mmc_info { + uint32_t tag; + uint32_t size; + /* + * Passes the early mmc status to payload to indicate if firmware + * successfully sent CMD0, CMD1 to the card or not. In case of + * success, the payload can skip the first step of the initialization + * sequence which is to send CMD0, and instead start by sending CMD1 + * as described in Jedec Standard JESD83-B1 section 6.4.3. + * passes 1 on success + */ + int32_t early_cmd1_status; +}; + #define CB_TAG_SERIALNO 0x002a #define CB_MAX_SERIALNO_LENGTH 32 diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index 7e6e74809dd..72059adb91d 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -129,6 +129,7 @@ struct sysinfo_t { uint64_t mtc_start; uint32_t mtc_size; void *chromeos_vpd; + int mmc_early_wake_status; }; extern struct sysinfo_t lib_sysinfo; diff --git a/payloads/libpayload/libc/coreboot.c b/payloads/libpayload/libc/coreboot.c index 3982e47ec26..26a3a48c232 100644 --- a/payloads/libpayload/libc/coreboot.c +++ b/payloads/libpayload/libc/coreboot.c @@ -102,6 +102,13 @@ static void cb_parse_vbnv(unsigned char *ptr, struct sysinfo_t *info) info->vbnv_size = vbnv->range_size; } +static void cb_parse_mmc_info(unsigned char *ptr, struct sysinfo_t *info) +{ + struct cb_mmc_info *mmc_info = (struct cb_mmc_info *)ptr; + + info->mmc_early_wake_status = mmc_info->early_cmd1_status; +} + static void cb_parse_gpios(unsigned char *ptr, struct sysinfo_t *info) { int i; @@ -399,6 +406,9 @@ int cb_parse_header(void *addr, int len, struct sysinfo_t *info) case CB_TAG_SPI_FLASH: cb_parse_spi_flash(ptr, info); break; + case CB_TAG_MMC_INFO: + cb_parse_mmc_info(ptr, info); + break; case CB_TAG_MTC: cb_parse_mtc(ptr, info); break; diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 198ad27b876..99ab21c7247 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -385,6 +385,21 @@ struct mac_address { uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */ }; +#define LB_TAG_MMC_INFO 0x0034 +struct lb_mmc_info { + uint32_t tag; + uint32_t size; + /* + * Passes the early mmc status to payload to indicate if firmware + * successfully sent CMD0, CMD1 to the card or not. In case of + * success, the payload can skip the first step of the initialization + * sequence which is to send CMD0, and instead start by sending CMD1 + * as described in Jedec Standard JESD83-B1 section 6.4.3. + * passes 1 on success + */ + int32_t early_cmd1_status; +}; + struct lb_macs { uint32_t tag; uint32_t size; diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 6e44f5d3d55..14cd0302026 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -321,6 +321,22 @@ static void lb_sku_id(struct lb_header *header) printk(BIOS_INFO, "SKU ID: %d\n", sid); } +static void lb_mmc_info(struct lb_header *header) +{ + struct lb_mmc_info *rec; + int32_t *ms_cbmem; + + ms_cbmem = cbmem_find(CBMEM_ID_MMC_STATUS); + if (!ms_cbmem) + return; + + rec = (struct lb_mmc_info *)lb_new_record(header); + + rec->tag = LB_TAG_MMC_INFO; + rec->size = sizeof(*rec); + rec->early_cmd1_status = *ms_cbmem; +} + static void add_cbmem_pointers(struct lb_header *header) { /* @@ -559,6 +575,9 @@ static uintptr_t write_coreboot_table(uintptr_t rom_table_end) lb_ram_code(head); lb_sku_id(head); + /* Pass mmc early init status */ + lb_mmc_info(head); + /* Add SPI flash description if available */ if (CONFIG(BOOT_DEVICE_SPI_FLASH)) lb_spi_flash(head); From 2803346b27aafb0fec2e6c949e2ab9994c754604 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Thu, 23 May 2019 12:14:38 +0200 Subject: [PATCH 422/588] Renumber cbtable tag MMC_INFO We got another tag in the meantime, so resolve the conflict. Change-Id: I64cb5e02a9bed3d8746b75e451c13a1598341ba1 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32954 Reviewed-by: Arthur Heymans Reviewed-by: Angel Pons Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- payloads/libpayload/include/coreboot_tables.h | 2 +- src/commonlib/include/commonlib/coreboot_tables.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/payloads/libpayload/include/coreboot_tables.h b/payloads/libpayload/include/coreboot_tables.h index 705e3486661..8e5cec04bf4 100644 --- a/payloads/libpayload/include/coreboot_tables.h +++ b/payloads/libpayload/include/coreboot_tables.h @@ -287,7 +287,7 @@ struct cb_macs { struct mac_address mac_addrs[0]; }; -#define CB_TAG_MMC_INFO 0x0034 +#define CB_TAG_MMC_INFO 0x0035 struct cb_mmc_info { uint32_t tag; uint32_t size; diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 99ab21c7247..bbc8608266f 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -385,7 +385,7 @@ struct mac_address { uint8_t pad[2]; /* Pad it to 8 bytes to keep it simple. */ }; -#define LB_TAG_MMC_INFO 0x0034 +#define LB_TAG_MMC_INFO 0x0035 struct lb_mmc_info { uint32_t tag; uint32_t size; From 3d84038d57d606945403b3a1e4759dff359a7a7d Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Fri, 17 May 2019 19:37:16 +0200 Subject: [PATCH 423/588] soc/intel/skylake: Add PCI Id for Kabylake DT Change-Id: I496b3a91f765d4fa137c32c9ee1e244803fc25d8 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32850 Reviewed-by: Lijian Zhao Tested-by: build bot (Jenkins) --- src/include/device/pci_ids.h | 1 + src/soc/intel/common/block/systemagent/systemagent.c | 1 + src/soc/intel/skylake/bootblock/report_platform.c | 1 + 3 files changed, 3 insertions(+) diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index 64539510ce0..553deafc8b7 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -3081,6 +3081,7 @@ #define PCI_DEVICE_ID_INTEL_KBL_ID_Y 0x590c #define PCI_DEVICE_ID_INTEL_KBL_ID_H 0x5910 #define PCI_DEVICE_ID_INTEL_KBL_U_R 0x5914 +#define PCI_DEVICE_ID_INTEL_KBL_ID_DT_2 0x5918 #define PCI_DEVICE_ID_INTEL_KBL_ID_DT 0x591f #define PCI_DEVICE_ID_INTEL_CNL_ID_U 0x5A04 #define PCI_DEVICE_ID_INTEL_CNL_ID_Y 0x5A02 diff --git a/src/soc/intel/common/block/systemagent/systemagent.c b/src/soc/intel/common/block/systemagent/systemagent.c index 0f91156566e..281a7f76559 100644 --- a/src/soc/intel/common/block/systemagent/systemagent.c +++ b/src/soc/intel/common/block/systemagent/systemagent.c @@ -351,6 +351,7 @@ static const unsigned short systemagent_ids[] = { PCI_DEVICE_ID_INTEL_KBL_ID_H, PCI_DEVICE_ID_INTEL_KBL_U_R, PCI_DEVICE_ID_INTEL_KBL_ID_DT, + PCI_DEVICE_ID_INTEL_KBL_ID_DT_2, PCI_DEVICE_ID_INTEL_CFL_ID_U, PCI_DEVICE_ID_INTEL_CFL_ID_H, PCI_DEVICE_ID_INTEL_CFL_ID_S, diff --git a/src/soc/intel/skylake/bootblock/report_platform.c b/src/soc/intel/skylake/bootblock/report_platform.c index de845c78541..1e81809b4f5 100644 --- a/src/soc/intel/skylake/bootblock/report_platform.c +++ b/src/soc/intel/skylake/bootblock/report_platform.c @@ -59,6 +59,7 @@ static struct { { PCI_DEVICE_ID_INTEL_KBL_ID_H, "Kabylake-H" }, { PCI_DEVICE_ID_INTEL_KBL_ID_S, "Kabylake-S" }, { PCI_DEVICE_ID_INTEL_KBL_ID_DT, "Kabylake DT" }, + { PCI_DEVICE_ID_INTEL_KBL_ID_DT_2, "Kabylake DT 2" }, }; static struct { From 2e1fea408d8c7287497f0846715ee933fa9449f0 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Mon, 26 Nov 2018 10:33:00 +0100 Subject: [PATCH 424/588] superio: Add ASpeed AST2400 Add support for ASpeed AST2400. This device uses write twice 0xA5 to enter config mode. BUG = N/A TEST = ASRock D1521D4U Change-Id: I58fce31f0a2483e61e9d31f38ab5a059b8cf4f83 Signed-off-by: Frans Hendriks Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/23135 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/include/superio/conf_mode.h | 3 + src/superio/Makefile.inc | 2 + src/superio/aspeed/Makefile.inc | 24 ++++++++ src/superio/aspeed/ast2400/Kconfig | 21 +++++++ src/superio/aspeed/ast2400/Makefile.inc | 18 ++++++ src/superio/aspeed/ast2400/ast2400.h | 31 ++++++++++ src/superio/aspeed/ast2400/superio.c | 74 ++++++++++++++++++++++++ src/superio/aspeed/common/Kconfig | 22 +++++++ src/superio/aspeed/common/aspeed.h | 30 ++++++++++ src/superio/aspeed/common/early_serial.c | 70 ++++++++++++++++++++++ src/superio/common/conf_mode.c | 12 ++++ 11 files changed, 307 insertions(+) create mode 100644 src/superio/aspeed/Makefile.inc create mode 100644 src/superio/aspeed/ast2400/Kconfig create mode 100644 src/superio/aspeed/ast2400/Makefile.inc create mode 100644 src/superio/aspeed/ast2400/ast2400.h create mode 100644 src/superio/aspeed/ast2400/superio.c create mode 100644 src/superio/aspeed/common/Kconfig create mode 100644 src/superio/aspeed/common/aspeed.h create mode 100644 src/superio/aspeed/common/early_serial.c diff --git a/src/include/superio/conf_mode.h b/src/include/superio/conf_mode.h index ecc365df7e5..8e753ea43be 100644 --- a/src/include/superio/conf_mode.h +++ b/src/include/superio/conf_mode.h @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2013 Nico Huber + * Copyright (C) 2017-2018 Eltan B.V. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,6 +26,7 @@ void pnp_enter_conf_mode_6767(struct device *dev); void pnp_enter_conf_mode_7777(struct device *dev); void pnp_enter_conf_mode_8787(struct device *dev); void pnp_enter_conf_mode_a0a0(struct device *dev); +void pnp_enter_conf_mode_a5a5(struct device *dev); void pnp_exit_conf_mode_aa(struct device *dev); void pnp_enter_conf_mode_870155aa(struct device *dev); void pnp_exit_conf_mode_0202(struct device *dev); @@ -34,6 +36,7 @@ extern const struct pnp_mode_ops pnp_conf_mode_6767_aa; extern const struct pnp_mode_ops pnp_conf_mode_7777_aa; extern const struct pnp_mode_ops pnp_conf_mode_8787_aa; extern const struct pnp_mode_ops pnp_conf_mode_a0a0_aa; +extern const struct pnp_mode_ops pnp_conf_mode_a5a5_aa; extern const struct pnp_mode_ops pnp_conf_mode_870155_aa; #endif /* DEVICE_PNP_CONF_MODE_H */ diff --git a/src/superio/Makefile.inc b/src/superio/Makefile.inc index 5fc0ecdd7ef..ca96343858d 100644 --- a/src/superio/Makefile.inc +++ b/src/superio/Makefile.inc @@ -2,6 +2,7 @@ ## This file is part of the coreboot project. ## ## Copyright (C) 2009 Ronald G. Minnich +## Copyright (C) 2018 Eltan B.V. ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by @@ -13,6 +14,7 @@ ## GNU General Public License for more details. ## +subdirs-y += aspeed subdirs-y += fintek subdirs-y += intel subdirs-y += ite diff --git a/src/superio/aspeed/Makefile.inc b/src/superio/aspeed/Makefile.inc new file mode 100644 index 00000000000..6d0cc263e9a --- /dev/null +++ b/src/superio/aspeed/Makefile.inc @@ -0,0 +1,24 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2009 Ronald G. Minnich +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +## include generic fintek pre-ram stage driver +romstage-$(CONFIG_SUPERIO_ASPEED_COMMON_PRE_RAM) += common/early_serial.c +bootblock-$(CONFIG_SUPERIO_ASPEED_COMMON_PRE_RAM) += common/early_serial.c + +subdirs-y += ast2400 +subdirs-y += common + +CPPFLAGS_common += -Isrc/superio/aspeed diff --git a/src/superio/aspeed/ast2400/Kconfig b/src/superio/aspeed/ast2400/Kconfig new file mode 100644 index 00000000000..1ced5afdc28 --- /dev/null +++ b/src/superio/aspeed/ast2400/Kconfig @@ -0,0 +1,21 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2009 Ronald G. Minnich +## Copyright (C) 2014 Edward O'Callaghan +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +config SUPERIO_ASPEED_AST2400 + bool + default n + select SUPERIO_ASPEED_COMMON_PRE_RAM diff --git a/src/superio/aspeed/ast2400/Makefile.inc b/src/superio/aspeed/ast2400/Makefile.inc new file mode 100644 index 00000000000..a6f8b2003a3 --- /dev/null +++ b/src/superio/aspeed/ast2400/Makefile.inc @@ -0,0 +1,18 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2008 Corey Osgood +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +ramstage-$(CONFIG_SUPERIO_ASPEED_AST2400) += superio.c diff --git a/src/superio/aspeed/ast2400/ast2400.h b/src/superio/aspeed/ast2400/ast2400.h new file mode 100644 index 00000000000..aa9b0a98996 --- /dev/null +++ b/src/superio/aspeed/ast2400/ast2400.h @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Edward O'Callaghan + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SUPERIO_ASPEED_AST2400_H +#define SUPERIO_ASPEED_AST2400_H + +#define AST2400_SUART1 0x2 /* Com1 */ +#define AST2400_SUART2 0x3 /* Com2 */ +#define AST2400_SWAK 0x4 /* System Wake-Up control */ +#define AST2400_KBC 0x5 /* Keyboard controller */ +#define AST2400_GPIO 0x7 /* GPIO */ +#define AST2400_SUART3 0xB /* Com3 */ +#define AST2400_SUART4 0xC /* Com4 */ +#define AST2400_ILPC2AHB 0xD /* LPC 2 AHB */ +#define AST2400_MAILBOX 0xE /* Mailbox */ + +#endif /* SUPERIO_ASPEED_AST2400_H */ diff --git a/src/superio/aspeed/ast2400/superio.c b/src/superio/aspeed/ast2400/superio.c new file mode 100644 index 00000000000..dcb14fa6688 --- /dev/null +++ b/src/superio/aspeed/ast2400/superio.c @@ -0,0 +1,74 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Corey Osgood + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "ast2400.h" + +static void ast2400_init(struct device *dev) +{ + if (!dev->enabled) + return; + + switch (dev->path.pnp.device) { + case AST2400_KBC: + pc_keyboard_init(NO_AUX_DEVICE); + break; + } +} + +static struct device_operations ops = { + .read_resources = pnp_read_resources, + .set_resources = pnp_set_resources, + .enable_resources = pnp_enable_resources, + .enable = pnp_enable, + .init = ast2400_init, + .ops_pnp_mode = &pnp_conf_mode_a5a5_aa, +}; + +static struct pnp_info pnp_dev_info[] = { + { NULL, AST2400_SUART1, PNP_IO0 | PNP_IRQ0 | PNP_MSC0, 0xfff8, }, + { NULL, AST2400_SUART2, PNP_IO0 | PNP_IRQ0 | PNP_MSC0, 0xfff8, }, + { NULL, AST2400_SWAK, PNP_IO0 | PNP_IO1 | PNP_IO2 | PNP_IO3 + | PNP_IRQ0, 0xfff8, 0xfff8, 0xfff8, 0xfff8, }, + { NULL, AST2400_KBC, PNP_IO0 | PNP_IO1 | PNP_IRQ0 | PNP_IRQ1 + | PNP_MSC0, 0xffff, 0xffff, }, + { NULL, AST2400_GPIO, PNP_IRQ0, }, // GPIO LDN has no IO Region + { NULL, AST2400_SUART3, PNP_IO0 | PNP_IRQ0 | PNP_MSC0, 0xfff8, }, + { NULL, AST2400_SUART4, PNP_IO0 | PNP_IRQ0 | PNP_MSC0, 0xfff8, }, + { NULL, AST2400_ILPC2AHB, PNP_IRQ0 | PNP_MSC0 | PNP_MSC1 | PNP_MSC2 + | PNP_MSC3 | PNP_MSC4 | PNP_MSC5 | PNP_MSC6 | PNP_MSC7 + | PNP_MSC8 | PNP_MSC9 | PNP_MSCA | PNP_MSCB | PNP_MSCC + | PNP_MSCD | PNP_MSCE, }, + { NULL, AST2400_MAILBOX, PNP_IO0 | PNP_IRQ0, 0xfffe, }, +}; + +static void enable_dev(struct device *dev) +{ + pnp_enable_devices(dev, &ops, ARRAY_SIZE(pnp_dev_info), + pnp_dev_info); +} + +struct chip_operations superio_aspeed_ast2400_ops = { + CHIP_NAME("ASpeed AST2400 Super I/O") + .enable_dev = enable_dev, +}; diff --git a/src/superio/aspeed/common/Kconfig b/src/superio/aspeed/common/Kconfig new file mode 100644 index 00000000000..3f0dabb8534 --- /dev/null +++ b/src/superio/aspeed/common/Kconfig @@ -0,0 +1,22 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2009 Ronald G. Minnich +## Copyright (C) 2014 Edward O'Callaghan +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +# Generic Aspeed preram driver - Just enough UART initialisation code for +# preram phase. +config SUPERIO_ASPEED_COMMON_PRE_RAM + bool + default n diff --git a/src/superio/aspeed/common/aspeed.h b/src/superio/aspeed/common/aspeed.h new file mode 100644 index 00000000000..d3774eab3ee --- /dev/null +++ b/src/superio/aspeed/common/aspeed.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Edward O'Callaghan + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef SUPERIO_ASPEED_COMMON_ROMSTAGE_H +#define SUPERIO_ASPEED_COMMON_ROMSTAGE_H + +#include +#include +#include + +void aspeed_enable_serial(pnp_devfn_t dev, uint16_t iobase); + +void pnp_enter_conf_state(pnp_devfn_t dev); +void pnp_exit_conf_state(pnp_devfn_t dev); + +#endif /* SUPERIO_ASPEED_COMMON_ROMSTAGE_H */ diff --git a/src/superio/aspeed/common/early_serial.c b/src/superio/aspeed/common/early_serial.c new file mode 100644 index 00000000000..7ac9474bcca --- /dev/null +++ b/src/superio/aspeed/common/early_serial.c @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Edward O'Callaghan + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* + * A generic pre-ram driver for Aspeed variant Super I/O chips. + * + * The following is derived directly from the vendor Aspeed's data-sheets: + * + * To toggle between `configuration mode` and `normal operation mode` as to + * manipulation the various LDN's in Aspeed Super I/O's we are required to + * pass magic numbers `passwords keys`. + * + * ASPEED_ENTRY_KEY := enable configuration : 0xA5 (twice!) + * ASPEED_EXIT_KEY := disable configuration : 0xAA + * + * To modify a LDN's configuration register, we use the index port to select + * the index of the LDN and then writing to the data port to alter the + * parameters. A default index, data port pair is 0x4E, 0x4F respectively, a + * user modified pair is 0x2E, 0x2F respectively. + * + */ + +#include +#include +#include +#include +#include "aspeed.h" + +#define ASPEED_ENTRY_KEY 0xA5 +#define ASPEED_EXIT_KEY 0xAA + +/* Enable configuration: pass entry key '0xA5' into index port dev. */ +void pnp_enter_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(ASPEED_ENTRY_KEY, port); + outb(ASPEED_ENTRY_KEY, port); +} + +/* Disable configuration: pass exit key '0xAA' into index port dev. */ +void pnp_exit_conf_state(pnp_devfn_t dev) +{ + u16 port = dev >> 8; + outb(ASPEED_EXIT_KEY, port); +} + +/* Bring up early serial debugging output before the RAM is initialized. */ +void aspeed_enable_serial(pnp_devfn_t dev, u16 iobase) +{ + pnp_enter_conf_state(dev); + pnp_set_logical_device(dev); + pnp_set_enable(dev, 0); + pnp_set_iobase(dev, PNP_IDX_IO0, iobase); + pnp_set_enable(dev, 1); + pnp_exit_conf_state(dev); +} diff --git a/src/superio/common/conf_mode.c b/src/superio/common/conf_mode.c index dec630bfa4c..8ba1cddba96 100644 --- a/src/superio/common/conf_mode.c +++ b/src/superio/common/conf_mode.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2013 Nico Huber + * Copyright (C) 2017-2018 Eltan B.V. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -48,6 +49,12 @@ void pnp_enter_conf_mode_a0a0(struct device *dev) outb(0xa0, dev->path.pnp.port); } +void pnp_enter_conf_mode_a5a5(struct device *dev) +{ + outb(0xa5, dev->path.pnp.port); + outb(0xa5, dev->path.pnp.port); +} + void pnp_exit_conf_mode_aa(struct device *dev) { outb(0xaa, dev->path.pnp.port); @@ -96,6 +103,11 @@ const struct pnp_mode_ops pnp_conf_mode_a0a0_aa = { .exit_conf_mode = pnp_exit_conf_mode_aa, }; +const struct pnp_mode_ops pnp_conf_mode_a5a5_aa = { + .enter_conf_mode = pnp_enter_conf_mode_a5a5, + .exit_conf_mode = pnp_exit_conf_mode_aa, +}; + const struct pnp_mode_ops pnp_conf_mode_870155_aa = { .enter_conf_mode = pnp_enter_conf_mode_870155aa, .exit_conf_mode = pnp_exit_conf_mode_0202, From fa82e0db64f67fa7adb84bb423b23887a3dfed98 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 21:34:04 +0200 Subject: [PATCH 425/588] nb/amd/pi/00660F01: Remove variable set but not used Change-Id: I14c69b324de795ba6dead7932b3267887130a6df Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32946 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/northbridge/amd/pi/00660F01/northbridge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/northbridge/amd/pi/00660F01/northbridge.c b/src/northbridge/amd/pi/00660F01/northbridge.c index 43df7259fca..41641ee65f4 100644 --- a/src/northbridge/amd/pi/00660F01/northbridge.c +++ b/src/northbridge/amd/pi/00660F01/northbridge.c @@ -678,7 +678,6 @@ static void domain_set_resources(struct device *dev) struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info mem_hole; - u32 reset_memhole = 1; #endif pci_tolm = 0xffffffffUL; @@ -708,7 +707,6 @@ static void domain_set_resources(struct device *dev) /* Use hole_basek as mmio_basek, and we don't need to reset hole anymore */ if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) { mmio_basek = mem_hole.hole_startk; - reset_memhole = 0; } #endif From 7a5d4e2b4a5acbdad42c36cb4c33aab3b95af385 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 21:40:10 +0200 Subject: [PATCH 426/588] nb/amd/amdmct/mct/mctecc_d.c: Remove variable set but not used Change-Id: I309cf83a1fec16b796c72c1803d27e1b7932940f Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32947 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/northbridge/amd/amdmct/mct/mctecc_d.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct/mctecc_d.c b/src/northbridge/amd/amdmct/mct/mctecc_d.c index 7be63533a95..8eb7bf54b75 100644 --- a/src/northbridge/amd/amdmct/mct/mctecc_d.c +++ b/src/northbridge/amd/amdmct/mct/mctecc_d.c @@ -80,7 +80,6 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) u16 OB_ECCRedir; u32 LDramECC; u32 OF_ScrubCTL; - u16 OB_ChipKill; u8 MemClrECC; u32 dev; @@ -96,7 +95,7 @@ u8 ECCInit_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA) OB_ECCRedir = mctGet_NVbits(NV_ECCRedir); /* ECC Redirection */ - OB_ChipKill = mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */ + mctGet_NVbits(NV_ChipKill); /* ECC Chip-kill mode */ OF_ScrubCTL = 0; /* Scrub CTL for Dcache, L2, and dram */ nvbits = mctGet_NVbits(NV_DCBKScrub); From f0a576595a12d0d3ba8dd0fc003027dd35d7a522 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 23:24:46 +0200 Subject: [PATCH 427/588] nb/amd/amdmct/mct/mctpro_d.c: Remove variable set but not used Change-Id: Ic2f2788142329e2e4d04b531805a32d4dcaa293c Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32949 Reviewed-by: Marshall Dawson Tested-by: build bot (Jenkins) --- src/northbridge/amd/amdmct/mct/mctpro_d.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct/mctpro_d.c b/src/northbridge/amd/amdmct/mct/mctpro_d.c index 0acb6f4ff49..83937330f84 100644 --- a/src/northbridge/amd/amdmct/mct/mctpro_d.c +++ b/src/northbridge/amd/amdmct/mct/mctpro_d.c @@ -280,7 +280,6 @@ void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct) u32 Speed; u32 ch, ch_start, ch_end; u32 index_reg; - u32 index; u32 dev; u32 val; @@ -297,7 +296,7 @@ void mct_BeforeDramInit_D(struct DCTStatStruc *pDCTstat, u32 dct) ch_end = dct+1; } dev = pDCTstat->dev_dct; - index = 0x0D00E001; + for (ch = ch_start; ch < ch_end; ch++) { index_reg = 0x98 + 0x100 * ch; val = Get_NB32_index(dev, index_reg, 0x0D00E001); From 502008d5dc4467fc03e8a2edd7a50b340a4c5529 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 23:33:11 +0200 Subject: [PATCH 428/588] nb/northbridge/intel/x4x/acpi.c: Remove variable set but not used Change-Id: I715adbe3d90d0f5195b54c274fb7843945d3e6be Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32950 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/northbridge/intel/x4x/acpi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/northbridge/intel/x4x/acpi.c b/src/northbridge/intel/x4x/acpi.c index fb04fd8582b..a91d227c7af 100644 --- a/src/northbridge/intel/x4x/acpi.c +++ b/src/northbridge/intel/x4x/acpi.c @@ -25,11 +25,9 @@ unsigned long acpi_fill_mcfg(unsigned long current) { - struct device *dev; u32 pciexbar = 0; u32 length = 0; - dev = pcidev_on_root(0, 0); if (!decode_pciebar(&pciexbar, &length)) return current; From 3dbfb2bef9cdb97ac6e34a4268cc4a26e6483013 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 20:11:49 +0200 Subject: [PATCH 429/588] nb/amd/amdmct/mct/mctdqs_d.c: Remove variable set but not used Change-Id: I45f32ea1ebf59a20d475dfad2d9d0980dec6918b Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32940 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/northbridge/amd/amdmct/mct/mctdqs_d.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct/mctdqs_d.c b/src/northbridge/amd/amdmct/mct/mctdqs_d.c index e2dd56fc1a5..36ee3ab3324 100644 --- a/src/northbridge/amd/amdmct/mct/mctdqs_d.c +++ b/src/northbridge/amd/amdmct/mct/mctdqs_d.c @@ -1192,8 +1192,6 @@ void mct_Write1LTestPattern_D(struct MCTStatStruc *pMCTstat, void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat, u32 addr) { - u32 value; - /* BIOS issues the remaining (Ntrain - 2) reads after checking that * F2x11C[PrefDramTrainMode] is cleared. These reads must be to * consecutive cache lines (i.e., 64 bytes apart) and must not cross @@ -1205,5 +1203,5 @@ void mct_Read1LTestPattern_D(struct MCTStatStruc *pMCTstat, SetUpperFSbase(addr); /* 1st move causes read fill (to exclusive or shared)*/ - value = read32_fs(addr << 8); + read32_fs(addr << 8); } From 35f9507b08aa8e062b0a1f87eb25b45694378503 Mon Sep 17 00:00:00 2001 From: Duncan Laurie Date: Thu, 23 May 2019 14:48:29 -0700 Subject: [PATCH 430/588] ec/google/wilco: Fix radio control command This command is working as written, but it is not actually correct as to what the format of the command should be. Fix this and add define the other radios. There is no change in the command send to the EC. Change-Id: Ia551b08561b673d27bec2f900d97b746699b30c4 Signed-off-by: Duncan Laurie Reviewed-on: https://review.coreboot.org/c/coreboot/+/32973 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao Reviewed-by: EricR Lai --- src/ec/google/wilco/commands.c | 2 +- src/ec/google/wilco/commands.h | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ec/google/wilco/commands.c b/src/ec/google/wilco/commands.c index 9d4170f5390..626f9ddc2c0 100644 --- a/src/ec/google/wilco/commands.c +++ b/src/ec/google/wilco/commands.c @@ -159,7 +159,7 @@ void wilco_ec_power_off(enum ec_power_off_reason reason) int wilco_ec_radio_control(enum ec_radio radio, uint8_t state) { - uint8_t radio_control[3] = { 0, radio, state }; + uint8_t radio_control[3] = { radio, RADIO_WRITE, state }; return wilco_ec_mailbox(WILCO_EC_MSG_DEFAULT, KB_RADIO_CONTROL, radio_control, ARRAY_SIZE(radio_control), diff --git a/src/ec/google/wilco/commands.h b/src/ec/google/wilco/commands.h index 9b7f2e5d074..9a185805af9 100644 --- a/src/ec/google/wilco/commands.h +++ b/src/ec/google/wilco/commands.h @@ -80,7 +80,15 @@ enum ec_audio_mute { }; enum ec_radio { - RADIO_WIFI = 0x02, + RADIO_WIFI = 0, + RADIO_WWAN, + RADIO_BT, +}; + +enum ec_radio_action { + RADIO_READ = 1, + RADIO_WRITE, + RADIO_TOGGLE, }; enum ec_camera { From c6918f99d73541246f5a7d6d0f5723c674737fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Mon, 11 Jun 2018 08:52:22 +0300 Subject: [PATCH 431/588] AGESA: Move heap_status_name() implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Place it within class libagesa to avoid including AGESA internal header heapManager.h in coreboot proper build CPPFLAGS. Change-Id: Iae86d6631d7a6ba6ea2588a53b292b435dfd7861 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31511 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/drivers/amd/agesa/eventlog.c | 16 ------------- src/drivers/amd/agesa/state_machine.c | 2 ++ src/northbridge/amd/agesa/state_machine.h | 1 - src/vendorcode/amd/agesa/common/Makefile.inc | 1 + src/vendorcode/amd/agesa/common/debug_util.c | 24 ++++++++++++++++++++ src/vendorcode/amd/agesa/common/debug_util.h | 8 +++++++ src/vendorcode/amd/agesa/f12/Makefile.inc | 1 - src/vendorcode/amd/agesa/f14/Makefile.inc | 2 -- src/vendorcode/amd/agesa/f15tn/Makefile.inc | 2 -- src/vendorcode/amd/agesa/f16kb/Makefile.inc | 2 -- src/vendorcode/amd/pi/Lib/debug_util.c | 24 ++++++++++++++++++++ src/vendorcode/amd/pi/Lib/debug_util.h | 8 +++++++ 12 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 src/vendorcode/amd/agesa/common/debug_util.c create mode 100644 src/vendorcode/amd/agesa/common/debug_util.h create mode 100644 src/vendorcode/amd/pi/Lib/debug_util.c create mode 100644 src/vendorcode/amd/pi/Lib/debug_util.h diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c index 23e31ba7d31..df3759cf350 100644 --- a/src/drivers/amd/agesa/eventlog.c +++ b/src/drivers/amd/agesa/eventlog.c @@ -21,8 +21,6 @@ #include #include -#include - static const char undefined[] = "undefined"; /* Match order of enum AGESA_STRUCT_NAME. */ @@ -34,11 +32,6 @@ static const char *AgesaFunctionNameStr[] = { "Amd2dDataEye", "AmdS3FinalRestore", "AmdInitRtb" }; -/* heapManager.h */ -static const char *HeapStatusStr[] = { - "DoNotExistYet", "LocalCache", "TempMem", "SystemMem", "DoNotExistAnymore","S3Resume" -}; - /* This function has to match with enumeration of AGESA_STRUCT_NAME defined * inside AMD.h header file. Unfortunately those are different across * different vendorcode subtrees. @@ -64,15 +57,6 @@ const char *agesa_struct_name(int state) return AgesaFunctionNameStr[index]; } -const char *heap_status_name(int status) -{ - if ((status < HEAP_DO_NOT_EXIST_YET) || (status > HEAP_S3_RESUME)) - return undefined; - - int index = status - HEAP_DO_NOT_EXIST_YET; - return HeapStatusStr[index]; -} - /* * Possible AGESA_STATUS values: * diff --git a/src/drivers/amd/agesa/state_machine.c b/src/drivers/amd/agesa/state_machine.c index dfd64c3d522..90bf038f711 100644 --- a/src/drivers/amd/agesa/state_machine.c +++ b/src/drivers/amd/agesa/state_machine.c @@ -25,6 +25,8 @@ #include #include #include + +#include #include #if CONFIG(CPU_AMD_AGESA_OPENSOURCE) diff --git a/src/northbridge/amd/agesa/state_machine.h b/src/northbridge/amd/agesa/state_machine.h index 93625fce124..d05ae478d5c 100644 --- a/src/northbridge/amd/agesa/state_machine.h +++ b/src/northbridge/amd/agesa/state_machine.h @@ -24,7 +24,6 @@ /* eventlog */ const char *agesa_struct_name(int state); -const char *heap_status_name(int status); void agesawrapper_trace(AGESA_STATUS ret, AMD_CONFIG_PARAMS *StdHeader, const char *func); AGESA_STATUS agesawrapper_amdreadeventlog(UINT8 HeapStatus); diff --git a/src/vendorcode/amd/agesa/common/Makefile.inc b/src/vendorcode/amd/agesa/common/Makefile.inc index 78dd4fc9880..247969477cc 100644 --- a/src/vendorcode/amd/agesa/common/Makefile.inc +++ b/src/vendorcode/amd/agesa/common/Makefile.inc @@ -30,6 +30,7 @@ romstage-y += agesa-entry.c ramstage-y += agesa-entry.c +libagesa-y += debug_util.c libagesa-y += amdlib.c # Do not optimise performance-critical low-level IO for size with -Os, diff --git a/src/vendorcode/amd/agesa/common/debug_util.c b/src/vendorcode/amd/agesa/common/debug_util.c new file mode 100644 index 00000000000..29d0841904a --- /dev/null +++ b/src/vendorcode/amd/agesa/common/debug_util.c @@ -0,0 +1,24 @@ + +#include +#include +#include + +#include "debug_util.h" + +static const char undefined[] = "undefined"; + +static const char *HeapStatusStr[] = { + "DoNotExistYet", "LocalCache", "TempMem", "SystemMem", "DoNotExistAnymore","S3Resume" +}; + +/* This function has to match with enumeration of XXXX defined + * inside heapManager.h header file. + */ +const char *heap_status_name(UINT8 HeapStatus) +{ + if ((HeapStatus < HEAP_DO_NOT_EXIST_YET) || (HeapStatus > HEAP_S3_RESUME)) + return undefined; + + int index = HeapStatus - HEAP_DO_NOT_EXIST_YET; + return HeapStatusStr[index]; +} diff --git a/src/vendorcode/amd/agesa/common/debug_util.h b/src/vendorcode/amd/agesa/common/debug_util.h new file mode 100644 index 00000000000..a8d9a33c501 --- /dev/null +++ b/src/vendorcode/amd/agesa/common/debug_util.h @@ -0,0 +1,8 @@ +#ifndef __AGESA_DEBUG_UTIL_H__ +#define __AGESA_DEBUG_UTIL_H__ + +#include "AMD.h" + +const char *heap_status_name(UINT8 HeapStatus); + +#endif diff --git a/src/vendorcode/amd/agesa/f12/Makefile.inc b/src/vendorcode/amd/agesa/f12/Makefile.inc index f925ccb5f0f..dbea9c368ca 100644 --- a/src/vendorcode/amd/agesa/f12/Makefile.inc +++ b/src/vendorcode/amd/agesa/f12/Makefile.inc @@ -46,7 +46,6 @@ CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno # These are invalid, coreboot proper should not require # use of AGESA internal header files. CPPFLAGS_x86_ANY = -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU # heapManager.h CPPFLAGS_x86_32 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) CPPFLAGS_x86_64 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) diff --git a/src/vendorcode/amd/agesa/f14/Makefile.inc b/src/vendorcode/amd/agesa/f14/Makefile.inc index ad2d2dc63dc..bf1051c9aae 100644 --- a/src/vendorcode/amd/agesa/f14/Makefile.inc +++ b/src/vendorcode/amd/agesa/f14/Makefile.inc @@ -46,8 +46,6 @@ CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno # These are invalid, coreboot proper should not require # use of AGESA internal header files. CPPFLAGS_x86_ANY = -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU # heapManager.h -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU/Family CPPFLAGS_x86_32 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) CPPFLAGS_x86_64 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) diff --git a/src/vendorcode/amd/agesa/f15tn/Makefile.inc b/src/vendorcode/amd/agesa/f15tn/Makefile.inc index 57350d95711..1c5dc18d857 100644 --- a/src/vendorcode/amd/agesa/f15tn/Makefile.inc +++ b/src/vendorcode/amd/agesa/f15tn/Makefile.inc @@ -46,8 +46,6 @@ CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno # These are invalid, coreboot proper should not require # use of AGESA internal header files. CPPFLAGS_x86_ANY = -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU # heapManager.h -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU/Family CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/Fch # FchPlatform.h CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/Fch/Common # FchCommonCfg.h diff --git a/src/vendorcode/amd/agesa/f16kb/Makefile.inc b/src/vendorcode/amd/agesa/f16kb/Makefile.inc index 3115c4d996e..c423cf2bab5 100644 --- a/src/vendorcode/amd/agesa/f16kb/Makefile.inc +++ b/src/vendorcode/amd/agesa/f16kb/Makefile.inc @@ -46,8 +46,6 @@ CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno # These are invalid, coreboot proper should not require # use of AGESA internal header files. CPPFLAGS_x86_ANY = -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU # heapManager.h -CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/CPU/Family CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/Fch # FchPlatform.h CPPFLAGS_x86_ANY += -I$(AGESA_ROOT)/Proc/Fch/Common # FchCommonCfg.h diff --git a/src/vendorcode/amd/pi/Lib/debug_util.c b/src/vendorcode/amd/pi/Lib/debug_util.c new file mode 100644 index 00000000000..29d0841904a --- /dev/null +++ b/src/vendorcode/amd/pi/Lib/debug_util.c @@ -0,0 +1,24 @@ + +#include +#include +#include + +#include "debug_util.h" + +static const char undefined[] = "undefined"; + +static const char *HeapStatusStr[] = { + "DoNotExistYet", "LocalCache", "TempMem", "SystemMem", "DoNotExistAnymore","S3Resume" +}; + +/* This function has to match with enumeration of XXXX defined + * inside heapManager.h header file. + */ +const char *heap_status_name(UINT8 HeapStatus) +{ + if ((HeapStatus < HEAP_DO_NOT_EXIST_YET) || (HeapStatus > HEAP_S3_RESUME)) + return undefined; + + int index = HeapStatus - HEAP_DO_NOT_EXIST_YET; + return HeapStatusStr[index]; +} diff --git a/src/vendorcode/amd/pi/Lib/debug_util.h b/src/vendorcode/amd/pi/Lib/debug_util.h new file mode 100644 index 00000000000..a8d9a33c501 --- /dev/null +++ b/src/vendorcode/amd/pi/Lib/debug_util.h @@ -0,0 +1,8 @@ +#ifndef __AGESA_DEBUG_UTIL_H__ +#define __AGESA_DEBUG_UTIL_H__ + +#include "AMD.h" + +const char *heap_status_name(UINT8 HeapStatus); + +#endif From ec85e2f55df026e2097fa5e56ec3605ab0762256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 14 Feb 2019 10:50:03 +0200 Subject: [PATCH 432/588] AGESA f12 f14 vendorcode: Clean up extra CFLAGS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extra variable is no longer required here. Change-Id: I2a6839ee0349e3019de3b2a91f9e7bb1c435603d Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31512 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/vendorcode/amd/agesa/f12/Makefile.inc | 8 ++------ src/vendorcode/amd/agesa/f14/Makefile.inc | 8 ++------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/vendorcode/amd/agesa/f12/Makefile.inc b/src/vendorcode/amd/agesa/f12/Makefile.inc index dbea9c368ca..9bc3c2600e6 100644 --- a/src/vendorcode/amd/agesa/f12/Makefile.inc +++ b/src/vendorcode/amd/agesa/f12/Makefile.inc @@ -43,12 +43,8 @@ BUILDOPTS_INCLUDES = -I$(AGESA_ROOT)/Config $(AGESA_INC) $(AGESA_AUTOINCLUDES) CFLAGS_x86_32 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno-strict-aliasing CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno-strict-aliasing -# These are invalid, coreboot proper should not require -# use of AGESA internal header files. -CPPFLAGS_x86_ANY = - -CPPFLAGS_x86_32 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) -CPPFLAGS_x86_64 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) +CPPFLAGS_x86_32 += $(AGESA_INC) +CPPFLAGS_x86_64 += $(AGESA_INC) ####################################################################### diff --git a/src/vendorcode/amd/agesa/f14/Makefile.inc b/src/vendorcode/amd/agesa/f14/Makefile.inc index bf1051c9aae..da79a39f8f8 100644 --- a/src/vendorcode/amd/agesa/f14/Makefile.inc +++ b/src/vendorcode/amd/agesa/f14/Makefile.inc @@ -43,12 +43,8 @@ BUILDOPTS_INCLUDES = -I$(AGESA_ROOT)/Config $(AGESA_INC) $(AGESA_AUTOINCLUDES) CFLAGS_x86_32 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno-strict-aliasing CFLAGS_x86_64 += -march=k8-sse3 -mtune=k8-sse3 -fno-zero-initialized-in-bss -fno-strict-aliasing -# These are invalid, coreboot proper should not require -# use of AGESA internal header files. -CPPFLAGS_x86_ANY = - -CPPFLAGS_x86_32 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) -CPPFLAGS_x86_64 += $(AGESA_INC) $(CPPFLAGS_x86_ANY) +CPPFLAGS_x86_32 += $(AGESA_INC) +CPPFLAGS_x86_64 += $(AGESA_INC) ####################################################################### From d1d4f937ec7ecf8032911fbce2ff899b14199384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Sun, 24 Sep 2017 08:21:00 +0300 Subject: [PATCH 433/588] AGESA: Move debug helper to eventlog file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2d74f934936e250886526b9c8482f500628a1158 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31513 Reviewed-by: Marshall Dawson Tested-by: build bot (Jenkins) --- src/drivers/amd/agesa/eventlog.c | 26 ++++++++++++++- src/drivers/amd/agesa/state_machine.c | 40 ++--------------------- src/northbridge/amd/agesa/state_machine.h | 12 ++++++- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c index df3759cf350..03cb64a8ce0 100644 --- a/src/drivers/amd/agesa/eventlog.c +++ b/src/drivers/amd/agesa/eventlog.c @@ -1,6 +1,8 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2016 Kyösti Mälkki + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -18,6 +20,7 @@ #include #include #include +#include #include #include @@ -40,7 +43,7 @@ static const char *AgesaFunctionNameStr[] = { * under vendorcode/ tree. */ -const char *agesa_struct_name(int state) +static const char *agesa_struct_name(AGESA_STRUCT_NAME state) { #if CONFIG(CPU_AMD_AGESA_OPENSOURCE) if ((state < AMD_INIT_RECOVERY) || (state > AMD_IDENTIFY_DIMMS)) @@ -57,6 +60,27 @@ const char *agesa_struct_name(int state) return AgesaFunctionNameStr[index]; } +void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func) +{ + task->apic_id = (u8) (cpuid_ebx(1) >> 24); + task->func = func; + task->function_name = agesa_struct_name(func); + + printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n", + task->apic_id, task->function_name, task->func); +} + +void agesa_state_on_exit(struct agesa_state *task, + AMD_CONFIG_PARAMS *StdHeader) +{ + printk(BIOS_DEBUG, "APIC %02d: Heap in %s (%d) at 0x%08x\n", + task->apic_id, heap_status_name(StdHeader->HeapStatus), + StdHeader->HeapStatus, (u32)StdHeader->HeapBasePtr); + + printk(BIOS_DEBUG, "APIC %02d: ** Exit %s [%08x]\n", + task->apic_id, task->function_name, task->func); +} + /* * Possible AGESA_STATUS values: * diff --git a/src/drivers/amd/agesa/state_machine.c b/src/drivers/amd/agesa/state_machine.c index 90bf038f711..03c658287d5 100644 --- a/src/drivers/amd/agesa/state_machine.c +++ b/src/drivers/amd/agesa/state_machine.c @@ -26,7 +26,6 @@ #include #include -#include #include #if CONFIG(CPU_AMD_AGESA_OPENSOURCE) @@ -231,38 +230,6 @@ static AGESA_STATUS ramstage_dispatch(struct sysinfo *cb, return status; } -/* DEBUG trace helper */ - -struct agesa_state -{ - u8 apic_id; - - AGESA_STRUCT_NAME func; - const char *function_name; -}; - -static void state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func, - const char *struct_name) -{ - task->apic_id = (u8) (cpuid_ebx(1) >> 24); - task->func = func; - task->function_name = struct_name; - - printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n", - task->apic_id, task->function_name, task->func); -} - -static void state_on_exit(struct agesa_state *task, - AMD_CONFIG_PARAMS *StdHeader) -{ - printk(BIOS_DEBUG, "APIC %02d: Heap in %s (%d) at 0x%08x\n", - task->apic_id, heap_status_name(StdHeader->HeapStatus), - StdHeader->HeapStatus, (u32)StdHeader->HeapBasePtr); - - printk(BIOS_DEBUG, "APIC %02d: ** Exit %s [%08x]\n", - task->apic_id, task->function_name, task->func); -} - int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func) { AMD_INTERFACE_PARAMS aip; @@ -272,13 +239,12 @@ int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func) } agesa_params; void *buf = NULL; size_t len = 0; - const char *state_name = agesa_struct_name(func); AGESA_STATUS status, final; struct agesa_state task; memset(&task, 0, sizeof(task)); - state_on_entry(&task, func, state_name); + agesa_state_on_entry(&task, func); aip.StdHeader = cb->StdHeader; @@ -302,13 +268,13 @@ int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func) if (ENV_RAMSTAGE) final = ramstage_dispatch(cb, func, StdHeader); - agesawrapper_trace(final, StdHeader, state_name); + agesawrapper_trace(final, StdHeader, task.function_name); ASSERT(final < AGESA_FATAL); status = amd_release_struct(&aip); ASSERT(status == AGESA_SUCCESS); - state_on_exit(&task, &aip.StdHeader); + agesa_state_on_exit(&task, &aip.StdHeader); return (final < AGESA_FATAL) ? 0 : -1; } diff --git a/src/northbridge/amd/agesa/state_machine.h b/src/northbridge/amd/agesa/state_machine.h index d05ae478d5c..74c3f61e0d4 100644 --- a/src/northbridge/amd/agesa/state_machine.h +++ b/src/northbridge/amd/agesa/state_machine.h @@ -23,7 +23,6 @@ #define HAS_LEGACY_WRAPPER CONFIG(BINARYPI_LEGACY_WRAPPER) /* eventlog */ -const char *agesa_struct_name(int state); void agesawrapper_trace(AGESA_STATUS ret, AMD_CONFIG_PARAMS *StdHeader, const char *func); AGESA_STATUS agesawrapper_amdreadeventlog(UINT8 HeapStatus); @@ -54,6 +53,17 @@ void board_BeforeAgesa(struct sysinfo *cb); void platform_once(struct sysinfo *cb); void agesa_set_interface(struct sysinfo *cb); + +struct agesa_state { + u8 apic_id; + + AGESA_STRUCT_NAME func; + const char *function_name; +}; + +void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func); +void agesa_state_on_exit(struct agesa_state *task, + AMD_CONFIG_PARAMS *StdHeader); int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func); /* AGESA dispatchers */ From e20d6095aee0c73e758199dfa214366104fc9a85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Sun, 10 Jun 2018 08:20:56 +0300 Subject: [PATCH 434/588] AGESA binaryPI: Redo entrypoints namelist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stop assuming the list is complete with no gaps, and use a lookup-table to match AGESA_STRUCT_NAME types of the entrypoints we use with names. Change-Id: Ibef4690d8aa76ff5b47c879f5ceb9d8fc4c4c4cd Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31514 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/drivers/amd/agesa/eventlog.c | 94 +++++++++++++++++++++----------- 1 file changed, 62 insertions(+), 32 deletions(-) diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c index 03cb64a8ce0..152011ed344 100644 --- a/src/drivers/amd/agesa/eventlog.c +++ b/src/drivers/amd/agesa/eventlog.c @@ -1,7 +1,7 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2016 Kyösti Mälkki + * Copyright (C) 2016-2019 Kyösti Mälkki * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,45 +26,75 @@ static const char undefined[] = "undefined"; -/* Match order of enum AGESA_STRUCT_NAME. */ -static const char *AgesaFunctionNameStr[] = { - "AmdInitRecovery", "AmdCreateStruct", "AmdInitEarly", "AmdInitEnv", "AmdInitLate", - "AmdInitMid", "AmdInitPost", "AmdInitReset", "AmdInitResume", "AmdReleaseStruct", - "AmdS3LateRestore", "AmdS3Save", "AmdGetApicId", "AmdGetPciAddress", "AmdIdentifyCore", - "AmdReadEventLog", "AmdGetAvailableExeCacheSize", "AmdLateRunApTask", "AmdIdentifyDimm", - "Amd2dDataEye", "AmdS3FinalRestore", "AmdInitRtb" -}; - -/* This function has to match with enumeration of AGESA_STRUCT_NAME defined - * inside AMD.h header file. Unfortunately those are different across - * different vendorcode subtrees. - * - * TBD: Fix said header or move this function together with the strings above - * under vendorcode/ tree. - */ - -static const char *agesa_struct_name(AGESA_STRUCT_NAME state) +struct agesa_mapping { -#if CONFIG(CPU_AMD_AGESA_OPENSOURCE) - if ((state < AMD_INIT_RECOVERY) || (state > AMD_IDENTIFY_DIMMS)) - return undefined; - - int index = state - AMD_INIT_RECOVERY; -#else - state >>= 12; - if ((state < AMD_INIT_RECOVERY >> 12) || (state > AMD_IDENTIFY_DIMMS >> 12)) - return undefined; + AGESA_STRUCT_NAME func; + const char *name; +}; - int index = state - (AMD_INIT_RECOVERY >> 12); +static const struct agesa_mapping entrypoint[] = { + { + .func = AMD_INIT_RESET, + .name = "AmdInitReset", + }, + { + .func = AMD_INIT_EARLY, + .name = "AmdInitEarly", + }, + { + .func = AMD_INIT_POST, + .name = "AmdInitPost", + }, + { + .func = AMD_INIT_RESUME, + .name = "AmdInitResume", + }, + { + .func = AMD_INIT_ENV, + .name = "AmdInitEnv", + }, + { + .func = AMD_INIT_MID, + .name = "AmdInitMid", + }, + { + .func = AMD_INIT_LATE, + .name = "AmdInitLate", + }, + { + .func = AMD_S3LATE_RESTORE, + .name = "AmdS3LateRestore", + }, +#if !defined(AMD_S3_SAVE_REMOVED) + { + .func = AMD_S3_SAVE, + .name = "AmdS3Save", + }, #endif - return AgesaFunctionNameStr[index]; -} + { + .func = AMD_S3FINAL_RESTORE, + .name = "AmdS3FinalRestore", + }, + { + .func = AMD_INIT_RTB, + .name = "AmdInitRtb", + }, +}; void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func) { + int i; + task->apic_id = (u8) (cpuid_ebx(1) >> 24); task->func = func; - task->function_name = agesa_struct_name(func); + task->function_name = undefined; + + for (i = 0; i < ARRAY_SIZE(entrypoint); i++) { + if (task->func == entrypoint[i].func) { + task->function_name = entrypoint[i].name; + break; + } + } printk(BIOS_DEBUG, "\nAPIC %02d: ** Enter %s [%08x]\n", task->apic_id, task->function_name, task->func); From 43f6d9d7160be96460f77993465de1570568c569 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ky=C3=B6sti=20M=C3=A4lkki?= Date: Thu, 14 Mar 2019 14:59:31 +0200 Subject: [PATCH 435/588] AGESA binaryPI: Add AGESA entry timestamps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The call to timestamp_rescale_table() had to be moved before TS_AGESA_INIT_{POST/RESUME}_DONE to have that timestamp appear without rescaling. Change-Id: I71e09d3bc4c8657979d447b90fb6ac7cae959479 Signed-off-by: Kyösti Mälkki Reviewed-on: https://review.coreboot.org/c/coreboot/+/31515 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/drivers/amd/agesa/eventlog.c | 27 +++++++++++++++++++++++ src/drivers/amd/agesa/romstage.c | 2 -- src/drivers/amd/agesa/state_machine.c | 20 ++++++++++++++++- src/northbridge/amd/agesa/state_machine.h | 2 ++ src/vendorcode/amd/Kconfig | 9 ++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/drivers/amd/agesa/eventlog.c b/src/drivers/amd/agesa/eventlog.c index 152011ed344..887da308d4e 100644 --- a/src/drivers/amd/agesa/eventlog.c +++ b/src/drivers/amd/agesa/eventlog.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -30,54 +31,78 @@ struct agesa_mapping { AGESA_STRUCT_NAME func; const char *name; + uint32_t entry_id; + uint32_t exit_id; }; static const struct agesa_mapping entrypoint[] = { { .func = AMD_INIT_RESET, .name = "AmdInitReset", + .entry_id = TS_AGESA_INIT_RESET_START, + .exit_id = TS_AGESA_INIT_RESET_DONE, }, { .func = AMD_INIT_EARLY, .name = "AmdInitEarly", + .entry_id = TS_AGESA_INIT_EARLY_START, + .exit_id = TS_AGESA_INIT_EARLY_DONE, }, { .func = AMD_INIT_POST, .name = "AmdInitPost", + .entry_id = TS_AGESA_INIT_POST_START, + .exit_id = TS_AGESA_INIT_POST_DONE, }, { .func = AMD_INIT_RESUME, .name = "AmdInitResume", + .entry_id = TS_AGESA_INIT_RESUME_START, + .exit_id = TS_AGESA_INIT_RESUME_DONE, }, { .func = AMD_INIT_ENV, .name = "AmdInitEnv", + .entry_id = TS_AGESA_INIT_ENV_START, + .exit_id = TS_AGESA_INIT_ENV_DONE, }, { .func = AMD_INIT_MID, .name = "AmdInitMid", + .entry_id = TS_AGESA_INIT_MID_START, + .exit_id = TS_AGESA_INIT_MID_DONE, }, { .func = AMD_INIT_LATE, .name = "AmdInitLate", + .entry_id = TS_AGESA_INIT_LATE_START, + .exit_id = TS_AGESA_INIT_LATE_DONE, }, { .func = AMD_S3LATE_RESTORE, .name = "AmdS3LateRestore", + .entry_id = TS_AGESA_S3_LATE_START, + .exit_id = TS_AGESA_S3_LATE_DONE, }, #if !defined(AMD_S3_SAVE_REMOVED) { .func = AMD_S3_SAVE, .name = "AmdS3Save", + .entry_id = TS_AGESA_INIT_RTB_START, + .exit_id = TS_AGESA_INIT_RTB_DONE, }, #endif { .func = AMD_S3FINAL_RESTORE, .name = "AmdS3FinalRestore", + .entry_id = TS_AGESA_S3_FINAL_START, + .exit_id = TS_AGESA_S3_FINAL_DONE, }, { .func = AMD_INIT_RTB, .name = "AmdInitRtb", + .entry_id = TS_AGESA_INIT_RTB_START, + .exit_id = TS_AGESA_INIT_RTB_DONE, }, }; @@ -92,6 +117,8 @@ void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func) for (i = 0; i < ARRAY_SIZE(entrypoint); i++) { if (task->func == entrypoint[i].func) { task->function_name = entrypoint[i].name; + task->ts_entry_id = entrypoint[i].entry_id; + task->ts_exit_id = entrypoint[i].exit_id; break; } } diff --git a/src/drivers/amd/agesa/romstage.c b/src/drivers/amd/agesa/romstage.c index d5b20b76f93..adf6e0d0e32 100644 --- a/src/drivers/amd/agesa/romstage.c +++ b/src/drivers/amd/agesa/romstage.c @@ -90,8 +90,6 @@ void *asmlinkage romstage_main(unsigned long bist) else agesa_execute_state(cb, AMD_INIT_RESUME); - /* FIXME: Detect if TSC frequency changed during raminit? */ - timestamp_rescale_table(1, 4); timestamp_add_now(TS_AFTER_INITRAM); /* Work around AGESA setting all memory as WB on normal diff --git a/src/drivers/amd/agesa/state_machine.c b/src/drivers/amd/agesa/state_machine.c index 03c658287d5..c8529c5e048 100644 --- a/src/drivers/amd/agesa/state_machine.c +++ b/src/drivers/amd/agesa/state_machine.c @@ -20,7 +20,9 @@ #include #include #include -#include +#include +#include + #include #include #include @@ -147,6 +149,11 @@ static AGESA_STATUS romstage_dispatch(struct sysinfo *cb, platform_BeforeInitPost(cb, param); board_BeforeInitPost(cb, param); status = module_dispatch(func, StdHeader); + + /* FIXME: Detect if TSC frequency really + * changed during raminit? */ + timestamp_rescale_table(1, 4); + platform_AfterInitPost(cb, param); break; } @@ -156,6 +163,11 @@ static AGESA_STATUS romstage_dispatch(struct sysinfo *cb, AMD_RESUME_PARAMS *param = (void *)StdHeader; platform_BeforeInitResume(cb, param); status = module_dispatch(func, StdHeader); + + /* FIXME: Detect if TSC frequency really + * changed during raminit? */ + timestamp_rescale_table(1, 4); + platform_AfterInitResume(cb, param); break; } @@ -262,12 +274,18 @@ int agesa_execute_state(struct sysinfo *cb, AGESA_STRUCT_NAME func) AMD_CONFIG_PARAMS *StdHeader = aip.NewStructPtr; ASSERT(StdHeader->Func == func); + if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_entry_id) + timestamp_add_now(task.ts_entry_id); + if (ENV_ROMSTAGE) final = romstage_dispatch(cb, func, StdHeader); if (ENV_RAMSTAGE) final = ramstage_dispatch(cb, func, StdHeader); + if (CONFIG(AGESA_EXTRA_TIMESTAMPS) && task.ts_exit_id) + timestamp_add_now(task.ts_exit_id); + agesawrapper_trace(final, StdHeader, task.function_name); ASSERT(final < AGESA_FATAL); diff --git a/src/northbridge/amd/agesa/state_machine.h b/src/northbridge/amd/agesa/state_machine.h index 74c3f61e0d4..7d9fe9c5efe 100644 --- a/src/northbridge/amd/agesa/state_machine.h +++ b/src/northbridge/amd/agesa/state_machine.h @@ -59,6 +59,8 @@ struct agesa_state { AGESA_STRUCT_NAME func; const char *function_name; + uint32_t ts_entry_id; + uint32_t ts_exit_id; }; void agesa_state_on_entry(struct agesa_state *task, AGESA_STRUCT_NAME func); diff --git a/src/vendorcode/amd/Kconfig b/src/vendorcode/amd/Kconfig index 3fe0c822405..44b3940fa7a 100644 --- a/src/vendorcode/amd/Kconfig +++ b/src/vendorcode/amd/Kconfig @@ -47,6 +47,15 @@ if CPU_AMD_AGESA_BINARY_PI source src/vendorcode/amd/pi/Kconfig endif +config AGESA_EXTRA_TIMESTAMPS + bool "Add instrumentation for AGESA calls" + default n + depends on !BINARYPI_LEGACY_WRAPPER + depends on DRIVERS_AMD_PI + help + Insert additional timestamps around each entrypoint into + AGESA vendorcode. + endmenu endif From a6f9ee39065ecd6ec24f5f09616bddef17e894d6 Mon Sep 17 00:00:00 2001 From: Peter Lemenkov Date: Wed, 10 Oct 2018 14:28:44 +0200 Subject: [PATCH 436/588] mb/lenovo: Unify thermal threshold handling Unify thermal handling across Lenovo boards (except g505, which is different). Namely, do the following: * Move thermal levels from acpi_tables to thermal.h (and create if necessary). * Don't use board-specific ifdef guards. * Set thermal levels using dedicated acpi_update_thermal_table function as almost all Lenovo boards do. * Update list of authors in comments. Merge all author's entries. * Minor whitespace and formatting. This makes diff -ruw between the Lenovo boards smaller. Change-Id: If569f67c932b7fbf14893b890a5588df4994daeb Signed-off-by: Peter Lemenkov Reviewed-on: https://review.coreboot.org/c/coreboot/+/29659 Reviewed-by: Patrick Rudolph Reviewed-by: Philipp Deppenwiese Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/l520/acpi_tables.c | 1 - src/mainboard/lenovo/l520/thermal.h | 17 ++++++----- src/mainboard/lenovo/s230u/acpi_tables.c | 10 +++++-- src/mainboard/lenovo/s230u/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/t400/acpi_tables.c | 11 +++++-- src/mainboard/lenovo/t400/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/t420/thermal.h | 16 ++++++---- src/mainboard/lenovo/t420s/thermal.h | 24 ++++++++------- src/mainboard/lenovo/t430/thermal.h | 16 ++++++---- src/mainboard/lenovo/t430s/thermal.h | 16 ++++++---- src/mainboard/lenovo/t520/acpi_tables.c | 1 - src/mainboard/lenovo/t520/thermal.h | 24 ++++++++------- src/mainboard/lenovo/t530/acpi_tables.c | 1 - src/mainboard/lenovo/t530/thermal.h | 24 ++++++++------- src/mainboard/lenovo/t60/acpi_tables.c | 11 +++++-- src/mainboard/lenovo/t60/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/x131e/thermal.h | 22 +++++++------- src/mainboard/lenovo/x1_carbon_gen1/thermal.h | 24 ++++++++------- src/mainboard/lenovo/x200/acpi_tables.c | 11 +++++-- src/mainboard/lenovo/x200/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/x201/acpi_tables.c | 11 +++++-- src/mainboard/lenovo/x201/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/x220/thermal.h | 24 ++++++++------- src/mainboard/lenovo/x230/thermal.h | 24 ++++++++------- src/mainboard/lenovo/x60/acpi_tables.c | 11 +++++-- src/mainboard/lenovo/x60/thermal.h | 30 +++++++++++++++++++ src/mainboard/lenovo/z61t/acpi_tables.c | 8 +++++ src/mainboard/lenovo/z61t/thermal.h | 30 +++++++++++++++++++ 28 files changed, 402 insertions(+), 115 deletions(-) create mode 100644 src/mainboard/lenovo/s230u/thermal.h create mode 100644 src/mainboard/lenovo/t400/thermal.h create mode 100644 src/mainboard/lenovo/t60/thermal.h create mode 100644 src/mainboard/lenovo/x200/thermal.h create mode 100644 src/mainboard/lenovo/x201/thermal.h create mode 100644 src/mainboard/lenovo/x60/thermal.h create mode 100644 src/mainboard/lenovo/z61t/thermal.h diff --git a/src/mainboard/lenovo/l520/acpi_tables.c b/src/mainboard/lenovo/l520/acpi_tables.c index b86186404c7..31f41e75611 100644 --- a/src/mainboard/lenovo/l520/acpi_tables.c +++ b/src/mainboard/lenovo/l520/acpi_tables.c @@ -35,7 +35,6 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->s5u0 = 0; gnvs->s5u1 = 0; - // the lid is open by default. gnvs->lids = 1; diff --git a/src/mainboard/lenovo/l520/thermal.h b/src/mainboard/lenovo/l520/thermal.h index a2007ffedaf..72953fd2c2e 100644 --- a/src/mainboard/lenovo/l520/thermal.h +++ b/src/mainboard/lenovo/l520/thermal.h @@ -2,7 +2,10 @@ * This file is part of the coreboot project. * * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -15,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef L520_THERMAL_H -#define L520_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif /* L520_THERMAL_H */ +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/s230u/acpi_tables.c b/src/mainboard/lenovo/s230u/acpi_tables.c index 21fce85f5a1..8d6d93f1c36 100644 --- a/src/mainboard/lenovo/s230u/acpi_tables.c +++ b/src/mainboard/lenovo/s230u/acpi_tables.c @@ -14,6 +14,13 @@ */ #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -28,6 +35,5 @@ void acpi_create_gnvs(global_nvs_t *gnvs) /* The LID is open by default */ gnvs->lids = 1; - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } diff --git a/src/mainboard/lenovo/s230u/thermal.h b/src/mainboard/lenovo/s230u/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/s230u/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t400/acpi_tables.c b/src/mainboard/lenovo/t400/acpi_tables.c index 301ca50735d..8fb9056c518 100644 --- a/src/mainboard/lenovo/t400/acpi_tables.c +++ b/src/mainboard/lenovo/t400/acpi_tables.c @@ -21,6 +21,13 @@ #include #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -32,9 +39,7 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->cmap = 0x01; gnvs->cmbp = 0x01; - /* Set thermal levels */ - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } unsigned long acpi_fill_madt(unsigned long current) diff --git a/src/mainboard/lenovo/t400/thermal.h b/src/mainboard/lenovo/t400/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/t400/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t420/thermal.h b/src/mainboard/lenovo/t420/thermal.h index 6ca5b2a672c..72953fd2c2e 100644 --- a/src/mainboard/lenovo/t420/thermal.h +++ b/src/mainboard/lenovo/t420/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,8 +18,8 @@ * GNU General Public License for more details. */ -#ifndef T420_THERMAL_H -#define T420_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H /* Temperature which OS will shutdown at */ #define CRITICAL_TEMPERATURE 100 @@ -23,4 +27,4 @@ /* Temperature which OS will throttle CPU */ #define PASSIVE_TEMPERATURE 90 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t420s/thermal.h b/src/mainboard/lenovo/t420s/thermal.h index c7803e5c7a4..72953fd2c2e 100644 --- a/src/mainboard/lenovo/t420s/thermal.h +++ b/src/mainboard/lenovo/t420s/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef T420S_THERMAL_H -#define T420S_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t430/thermal.h b/src/mainboard/lenovo/t430/thermal.h index e3e49f594e6..edfe3bc7ce1 100644 --- a/src/mainboard/lenovo/t430/thermal.h +++ b/src/mainboard/lenovo/t430/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,8 +18,8 @@ * GNU General Public License for more details. */ -#ifndef _LENOVO_T430_THERMAL_H -#define _LENOVO_T430_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H /* Config TDP Sensor ID */ #define CTDP_SENSOR_ID 0 /* PECI */ @@ -37,4 +41,4 @@ /* Tj_max value for calculating PECI CPU temperature */ #define MAX_TEMPERATURE 105 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t430s/thermal.h b/src/mainboard/lenovo/t430s/thermal.h index 1d55584ce95..72953fd2c2e 100644 --- a/src/mainboard/lenovo/t430s/thermal.h +++ b/src/mainboard/lenovo/t430s/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,8 +18,8 @@ * GNU General Public License for more details. */ -#ifndef T430S_THERMAL_H -#define T430S_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H /* Temperature which OS will shutdown at */ #define CRITICAL_TEMPERATURE 100 @@ -23,4 +27,4 @@ /* Temperature which OS will throttle CPU */ #define PASSIVE_TEMPERATURE 90 -#endif /* T430S_THERMAL_H */ +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t520/acpi_tables.c b/src/mainboard/lenovo/t520/acpi_tables.c index a3b0894bcc4..279674d0021 100644 --- a/src/mainboard/lenovo/t520/acpi_tables.c +++ b/src/mainboard/lenovo/t520/acpi_tables.c @@ -32,7 +32,6 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->s5u0 = 0; gnvs->s5u1 = 0; - // the lid is open by default. gnvs->lids = 1; diff --git a/src/mainboard/lenovo/t520/thermal.h b/src/mainboard/lenovo/t520/thermal.h index 60721bf244a..72953fd2c2e 100644 --- a/src/mainboard/lenovo/t520/thermal.h +++ b/src/mainboard/lenovo/t520/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef T520_THERMAL_H -#define T520_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif /* T520_THERMAL_H */ +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t530/acpi_tables.c b/src/mainboard/lenovo/t530/acpi_tables.c index a3b0894bcc4..279674d0021 100644 --- a/src/mainboard/lenovo/t530/acpi_tables.c +++ b/src/mainboard/lenovo/t530/acpi_tables.c @@ -32,7 +32,6 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->s5u0 = 0; gnvs->s5u1 = 0; - // the lid is open by default. gnvs->lids = 1; diff --git a/src/mainboard/lenovo/t530/thermal.h b/src/mainboard/lenovo/t530/thermal.h index 0b24ea81860..72953fd2c2e 100644 --- a/src/mainboard/lenovo/t530/thermal.h +++ b/src/mainboard/lenovo/t530/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef T530_THERMAL_H -#define T530_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif /* T530_THERMAL_H */ +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/t60/acpi_tables.c b/src/mainboard/lenovo/t60/acpi_tables.c index 183b7fe2990..bd10a0e3fb6 100644 --- a/src/mainboard/lenovo/t60/acpi_tables.c +++ b/src/mainboard/lenovo/t60/acpi_tables.c @@ -16,6 +16,13 @@ #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -23,7 +30,5 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->cmap = 0x01; gnvs->cmbp = 0x01; - /* Set thermal levels */ - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } diff --git a/src/mainboard/lenovo/t60/thermal.h b/src/mainboard/lenovo/t60/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/t60/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x131e/thermal.h b/src/mainboard/lenovo/x131e/thermal.h index ff928699aea..72953fd2c2e 100644 --- a/src/mainboard/lenovo/x131e/thermal.h +++ b/src/mainboard/lenovo/x131e/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,15 +18,13 @@ * GNU General Public License for more details. */ -#ifndef X131E_THERMAL_H -#define X131E_THERMAL_H - -/* Active Thermal and fans are controlled by the EC. */ +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H /* Temperature which OS will shutdown at */ -#define CRITICAL_TEMPERATURE 100 +#define CRITICAL_TEMPERATURE 100 /* Temperature which OS will throttle CPU */ -#define PASSIVE_TEMPERATURE 90 +#define PASSIVE_TEMPERATURE 90 -#endif /* X131E_THERMAL_H */ +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x1_carbon_gen1/thermal.h b/src/mainboard/lenovo/x1_carbon_gen1/thermal.h index 199c27e637f..72953fd2c2e 100644 --- a/src/mainboard/lenovo/x1_carbon_gen1/thermal.h +++ b/src/mainboard/lenovo/x1_carbon_gen1/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef X230_THERMAL_H -#define X230_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x200/acpi_tables.c b/src/mainboard/lenovo/x200/acpi_tables.c index 301ca50735d..8fb9056c518 100644 --- a/src/mainboard/lenovo/x200/acpi_tables.c +++ b/src/mainboard/lenovo/x200/acpi_tables.c @@ -21,6 +21,13 @@ #include #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -32,9 +39,7 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->cmap = 0x01; gnvs->cmbp = 0x01; - /* Set thermal levels */ - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } unsigned long acpi_fill_madt(unsigned long current) diff --git a/src/mainboard/lenovo/x200/thermal.h b/src/mainboard/lenovo/x200/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/x200/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x201/acpi_tables.c b/src/mainboard/lenovo/x201/acpi_tables.c index e412503c882..82991b267ba 100644 --- a/src/mainboard/lenovo/x201/acpi_tables.c +++ b/src/mainboard/lenovo/x201/acpi_tables.c @@ -17,10 +17,15 @@ #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t * gnvs) { - /* Set thermal levels */ - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } diff --git a/src/mainboard/lenovo/x201/thermal.h b/src/mainboard/lenovo/x201/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/x201/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x220/thermal.h b/src/mainboard/lenovo/x220/thermal.h index 82df3030939..72953fd2c2e 100644 --- a/src/mainboard/lenovo/x220/thermal.h +++ b/src/mainboard/lenovo/x220/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef X220_THERMAL_H -#define X220_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x230/thermal.h b/src/mainboard/lenovo/x230/thermal.h index 199c27e637f..72953fd2c2e 100644 --- a/src/mainboard/lenovo/x230/thermal.h +++ b/src/mainboard/lenovo/x230/thermal.h @@ -1,12 +1,16 @@ /* * This file is part of the coreboot project. * + * Copyright (C) 2008-2009 coresystems GmbH * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -14,13 +18,13 @@ * GNU General Public License for more details. */ -#ifndef X230_THERMAL_H -#define X230_THERMAL_H +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 -#endif +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/x60/acpi_tables.c b/src/mainboard/lenovo/x60/acpi_tables.c index 183b7fe2990..bd10a0e3fb6 100644 --- a/src/mainboard/lenovo/x60/acpi_tables.c +++ b/src/mainboard/lenovo/x60/acpi_tables.c @@ -16,6 +16,13 @@ #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -23,7 +30,5 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->cmap = 0x01; gnvs->cmbp = 0x01; - /* Set thermal levels */ - gnvs->tcrt = 100; - gnvs->tpsv = 90; + acpi_update_thermal_table(gnvs); } diff --git a/src/mainboard/lenovo/x60/thermal.h b/src/mainboard/lenovo/x60/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/x60/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ diff --git a/src/mainboard/lenovo/z61t/acpi_tables.c b/src/mainboard/lenovo/z61t/acpi_tables.c index 3e9a81042e9..bd10a0e3fb6 100644 --- a/src/mainboard/lenovo/z61t/acpi_tables.c +++ b/src/mainboard/lenovo/z61t/acpi_tables.c @@ -16,6 +16,13 @@ #include #include +#include "thermal.h" + +static void acpi_update_thermal_table(global_nvs_t *gnvs) +{ + gnvs->tcrt = CRITICAL_TEMPERATURE; + gnvs->tpsv = PASSIVE_TEMPERATURE; +} void acpi_create_gnvs(global_nvs_t *gnvs) { @@ -23,4 +30,5 @@ void acpi_create_gnvs(global_nvs_t *gnvs) gnvs->cmap = 0x01; gnvs->cmbp = 0x01; + acpi_update_thermal_table(gnvs); } diff --git a/src/mainboard/lenovo/z61t/thermal.h b/src/mainboard/lenovo/z61t/thermal.h new file mode 100644 index 00000000000..72953fd2c2e --- /dev/null +++ b/src/mainboard/lenovo/z61t/thermal.h @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2008-2009 coresystems GmbH + * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. + * Copyright (C) 2014 Vladimir Serbinenko + * Copyright (C) 2016 Patrick Rudolph + * Copyright (C) 2017 James Ye + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_THERMAL_H +#define MAINBOARD_THERMAL_H + +/* Temperature which OS will shutdown at */ +#define CRITICAL_TEMPERATURE 100 + +/* Temperature which OS will throttle CPU */ +#define PASSIVE_TEMPERATURE 90 + +#endif /* MAINBOARD_THERMAL_H */ From c752c500fbcc055e8cdfb30a2e523e8a9349b79f Mon Sep 17 00:00:00 2001 From: Iru Cai Date: Wed, 16 Jan 2019 18:31:08 +0800 Subject: [PATCH 437/588] Documentation: Add HP EliteBook 8760w Also add the HP EliteBook document from wiki. Change-Id: I189db9c279705af53d82af66d0c2e8afb6f84d73 Signed-off-by: Iru Cai Reviewed-on: https://review.coreboot.org/c/coreboot/+/30950 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- Documentation/mainboard/hp/8760w.md | 82 +++++++++++++ Documentation/mainboard/hp/8760w_flash.jpg | Bin 0 -> 55849 bytes .../mainboard/hp/elitebook_series.md | 111 ++++++++++++++++++ Documentation/mainboard/index.md | 5 + 4 files changed, 198 insertions(+) create mode 100644 Documentation/mainboard/hp/8760w.md create mode 100644 Documentation/mainboard/hp/8760w_flash.jpg create mode 100644 Documentation/mainboard/hp/elitebook_series.md diff --git a/Documentation/mainboard/hp/8760w.md b/Documentation/mainboard/hp/8760w.md new file mode 100644 index 00000000000..714745aa043 --- /dev/null +++ b/Documentation/mainboard/hp/8760w.md @@ -0,0 +1,82 @@ +# HP EliteBook 8760w + +This page describes how to run coreboot on the [HP EliteBook 8760w]. + +## Flashing coreboot + +```eval_rst ++---------------------+------------+ +| Type | Value | ++=====================+============+ +| Socketed flash | no | ++---------------------+------------+ +| Model | W25Q64.V | ++---------------------+------------+ +| Size | 8 MiB | ++---------------------+------------+ +| Package | SOIC-8 | ++---------------------+------------+ +| Write protection | no | ++---------------------+------------+ +| Dual BIOS feature | no | ++---------------------+------------+ +| In circuit flashing | yes | ++---------------------+------------+ +| Internal flashing | yes | ++---------------------+------------+ +``` + +## Required proprietary blobs + +- Intel Firmware Descriptor, ME and GbE firmware +- EC: please read [EliteBook Series](elitebook_series) + +## Flashing instructions + +HP EliteBook 8760w has an 8MB SOIC-8 flash chip on the bottom of the +mainboard. You just need to remove the service cover, and use an SOIC-8 +clip to read and flash the chip. + +![8760w_chip_location](8760w_flash.jpg) + +## Untested + +- dock: serial port, parallel port, ... +- TPM +- S3 suspend/resume +- Gigabit Ethernet + +## Working + +- i7-2630QM, 0+4G+8G+0 +- i7-3720QM, 8G+8G+8G+8G +- Arch Linux boot from SeaBIOS payload +- EHCI debug: the port is at the right side, next to the charging port +- SATA +- eSATA +- USB2 and USB3 +- keyboard, touchpad, trackpad +- WLAN +- WWAN +- EC ACPI +- Using `me_cleaner` + +## Technology + +```eval_rst ++------------------+--------------------------------------------------+ +| Northbridge | :doc:`../../northbridge/intel/sandybridge/index` | ++------------------+--------------------------------------------------+ +| Southbridge | bd82x6x | ++------------------+--------------------------------------------------+ +| CPU | model_206ax | ++------------------+--------------------------------------------------+ +| Super I/O | SMSC LPC47n217 | ++------------------+--------------------------------------------------+ +| EC | SMSC KBC1126 | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +``` + +[HP EliteBook 8760w]: https://support.hp.com/us-en/product/hp-elitebook-8760w-mobile-workstation/5071180 diff --git a/Documentation/mainboard/hp/8760w_flash.jpg b/Documentation/mainboard/hp/8760w_flash.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d9bbac6788a3982c01dbda568b58ab8eade72726 GIT binary patch literal 55849 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 S4p@m(ZL^Y?8&Pb3)c@I&H9x2T literal 0 HcmV?d00001 diff --git a/Documentation/mainboard/hp/elitebook_series.md b/Documentation/mainboard/hp/elitebook_series.md new file mode 100644 index 00000000000..6668928008f --- /dev/null +++ b/Documentation/mainboard/hp/elitebook_series.md @@ -0,0 +1,111 @@ +# HP EliteBook series + +This document is about HP EliteBook series laptops up to Ivy Bridge era +which use SMSC KBC1126 as embedded controller. + +## EC + +SMSC KBC1098/KBC1126 has been used in HP EliteBooks for many generations. +They use similar EC firmware that will load other code and data from the +SPI flash chip, so we need to put some firmware blobs to the coreboot image. + +The following document takes EliteBook 2760p as an example. + +First, you need to extract the blobs needed by EC firmware using util/kbc1126. +You can extract them from your backup firmware image, or firmware update +provided by HP with [unar] as follows: + +```bash +wget https://ftp.hp.com/pub/softpaq/sp79501-80000/sp79710.exe +unar sp79710.exe +${COREBOOT_DIR}/util/kbc1126/kbc1126_ec_dump sp79710/Rompaq/68SOU.BIN +mv 68SOU.BIN.fw1 ${COREBOOT_DIR}/2760p-fw1.bin +mv 68SOU.BIN.fw2 ${COREBOOT_DIR}/2760p-fw2.bin +``` + +When you config coreboot, select: + +```text +Chipset ---> + [*] Add firmware images for KBC1126 EC + (2760p-fw1.bin) KBC1126 firmware #1 path and filename + (2760p-fw2.bin) KBC1126 filename #2 path and filename +``` + +## Super I/O + +EliteBook 8000 series laptops have SMSC LPC47n217 Super I/O to provide +a serial port and a parallel port, you can debug the laptop via this +serial port. + +## porting + +To port coreboot to an HP EliteBook laptop, you need to do the following: + +- select Kconfig option `EC_HP_KBC1126` +- select Kconfig option `SUPERIO_SMSC_LPC47N217` if there is LPC47n217 Super I/O +- initialize EC and Super I/O in romstage +- add EC and Super I/O support to devicetree.cb + +To get the related values for EC in devicetree.cb, you need to extract the EFI +module EcThermalInit from the vendor UEFI firmware with [UEFITool]. Usually, +`ec_data_port`, `ec_cmd_port` and `ec_ctrl_reg` has the following values: + +- For xx60 series: 0x60, 0x64, 0xca +- For xx70 series: 0x62, 0x66, 0x81 + +You can use [radare2] and the following [r2pipe] Python script to find +these values from the EcThermalInit EFI module: + +```python +#!/usr/bin/env python + +# install radare2 and use `pip3 install --user r2pipe` to install r2pipe + +import r2pipe +import sys + +if len(sys.argv) < 2: + fn = "ecthermalinit.efi" +else: + fn = sys.argv[1] + +r2 = r2pipe.open(fn) +r2.cmd("aa") +entryf = r2.cmdj("pdfj") + +for insn in entryf["ops"]: + if "lea r8" in insn["opcode"]: + _callback = insn["ptr"] + break + +r2.cmd("af @ {}".format(_callback)) +callbackf_insns = r2.cmdj("pdfj @ {}".format(_callback))["ops"] + +def find_port(addr): + ops = r2.cmdj("pdfj @ {}".format(addr))["ops"] + for insn in ops: + if "lea r8d" in insn["opcode"]: + return insn["ptr"] + +ctrl_reg_found = False + +for i in range(0, len(callbackf_insns)): + if not ctrl_reg_found and "mov cl" in callbackf_insns[i]["opcode"]: + ctrl_reg_found = True + ctrl_reg = callbackf_insns[i]["ptr"] + print("ec_ctrl_reg = 0x%02x" % ctrl_reg) + cmd_port = find_port(callbackf_insns[i+1]["jump"]) + data_port = find_port(callbackf_insns[i+3]["jump"]) + print("ec_cmd_port = 0x%02x\nec_data_port = 0x%02x" % (cmd_port, data_port)) + + if "mov bl" in callbackf_insns[i]["opcode"]: + ctrl_value = callbackf_insns[i]["ptr"] + print("ec_fan_ctrl_value = 0x%02x" % ctrl_value) +``` + + +[unar]: https://theunarchiver.com/command-line +[UEFITool]: https://github.com/LongSoft/UEFITool +[radare2]: https://radare.org/ +[r2pipe]: https://github.com/radare/radare2-r2pipe diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index 1494e062444..7e0dab2f4c3 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -51,6 +51,11 @@ The boards in this section are not real mainboards, but emulators. - [Compaq 8200 Elite SFF](hp/compaq_8200_sff.md) +### EliteBook series + +- [EliteBook common](hp/elitebook_series.md) +- [EliteBook 8760w](hp/8760w.md) + ## Lenovo - [Mainboard codenames](lenovo/codenames.md) From 99e578e3c1697028957f25efc7c14d1cb4d405dc Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 15 Jan 2019 20:14:33 +0100 Subject: [PATCH 438/588] nb/intel/pineview: Move to C_ENVIRONMENT_BOOTBLOCK This adds a file i82801gx/bootblock_gcc.c since other targets that don't yet C_ENVIRONMENT_BOOTBLOCK still use the romcc compiled bootblock.c. Tested on Foxconn D41S. Change-Id: I7e74838b0d5e9c192082084cfd9821996f0e4c50 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30939 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/cpu/intel/socket_FCBGA559/Kconfig | 7 +++ src/cpu/intel/socket_FCBGA559/Makefile.inc | 4 +- src/mainboard/foxconn/d41s/Makefile.inc | 2 + .../foxconn/d41s/{romstage.c => early_init.c} | 3 +- src/mainboard/intel/d510mo/Makefile.inc | 2 + .../intel/d510mo/{romstage.c => early_init.c} | 3 +- src/northbridge/intel/pineview/Kconfig | 1 + src/northbridge/intel/pineview/Makefile.inc | 2 + src/northbridge/intel/pineview/bootblock.c | 6 ++- src/northbridge/intel/pineview/pineview.h | 1 - src/northbridge/intel/pineview/romstage.c | 8 ---- src/southbridge/intel/i82801gx/Makefile.inc | 2 + .../intel/i82801gx/bootblock_gcc.c | 44 +++++++++++++++++++ 13 files changed, 71 insertions(+), 14 deletions(-) rename src/mainboard/foxconn/d41s/{romstage.c => early_init.c} (95%) rename src/mainboard/intel/d510mo/{romstage.c => early_init.c} (95%) create mode 100644 src/southbridge/intel/i82801gx/bootblock_gcc.c diff --git a/src/cpu/intel/socket_FCBGA559/Kconfig b/src/cpu/intel/socket_FCBGA559/Kconfig index b1b310d3cc9..d3af4ca3cc4 100644 --- a/src/cpu/intel/socket_FCBGA559/Kconfig +++ b/src/cpu/intel/socket_FCBGA559/Kconfig @@ -21,4 +21,11 @@ config DCACHE_RAM_SIZE hex default 0x4000 +config DCACHE_BSP_STACK_SIZE + hex + default 0x2000 + help + The amount of anticipated stack usage in CAR by bootblock and + other stages. + endif diff --git a/src/cpu/intel/socket_FCBGA559/Makefile.inc b/src/cpu/intel/socket_FCBGA559/Makefile.inc index 868f6e56085..c95e135bb5f 100644 --- a/src/cpu/intel/socket_FCBGA559/Makefile.inc +++ b/src/cpu/intel/socket_FCBGA559/Makefile.inc @@ -8,7 +8,9 @@ subdirs-y += ../microcode subdirs-y += ../hyperthreading subdirs-y += ../speedstep -cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S +bootblock-y += ../car/bootblock.c +bootblock-y += ../car/non-evict/cache_as_ram.S + postcar-y += ../car/non-evict/exit_car.S romstage-y += ../car/romstage.c diff --git a/src/mainboard/foxconn/d41s/Makefile.inc b/src/mainboard/foxconn/d41s/Makefile.inc index f3d7e76263f..057b5bfcd33 100644 --- a/src/mainboard/foxconn/d41s/Makefile.inc +++ b/src/mainboard/foxconn/d41s/Makefile.inc @@ -1,2 +1,4 @@ +romstage-y += early_init.c +bootblock-y += early_init.c ramstage-y += cstates.c romstage-y += gpio.c diff --git a/src/mainboard/foxconn/d41s/romstage.c b/src/mainboard/foxconn/d41s/early_init.c similarity index 95% rename from src/mainboard/foxconn/d41s/romstage.c rename to src/mainboard/foxconn/d41s/early_init.c index cdd12dc3ac5..6568d96139c 100644 --- a/src/mainboard/foxconn/d41s/romstage.c +++ b/src/mainboard/foxconn/d41s/early_init.c @@ -15,6 +15,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -23,7 +24,7 @@ #define SERIAL_DEV PNP_DEV(0x2e, IT8721F_SP1) -void mb_enable_lpc(void) +void bootblock_mainboard_early_init(void) { /* Disable Serial IRQ */ pci_write_config8(PCI_DEV(0, 0x1f, 0), SERIRQ_CNTL, 0xd0); diff --git a/src/mainboard/intel/d510mo/Makefile.inc b/src/mainboard/intel/d510mo/Makefile.inc index f3d7e76263f..f87689b8a1d 100644 --- a/src/mainboard/intel/d510mo/Makefile.inc +++ b/src/mainboard/intel/d510mo/Makefile.inc @@ -1,2 +1,4 @@ +bootblock-y += early_init.c +romstage-y += early_init.c ramstage-y += cstates.c romstage-y += gpio.c diff --git a/src/mainboard/intel/d510mo/romstage.c b/src/mainboard/intel/d510mo/early_init.c similarity index 95% rename from src/mainboard/intel/d510mo/romstage.c rename to src/mainboard/intel/d510mo/early_init.c index 024c3e10fe4..2719e87fe63 100644 --- a/src/mainboard/intel/d510mo/romstage.c +++ b/src/mainboard/intel/d510mo/early_init.c @@ -14,6 +14,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -23,7 +24,7 @@ #define SERIAL_DEV PNP_DEV(0x4e, W83627THG_SP1) #define SUPERIO_DEV PNP_DEV(0x4e, 0) -void mb_enable_lpc(void) +void bootblock_mainboard_early_init(void) { /* Disable Serial IRQ */ pci_write_config8(PCI_DEV(0, 0x1f, 0), SERIRQ_CNTL, 0x00); diff --git a/src/northbridge/intel/pineview/Kconfig b/src/northbridge/intel/pineview/Kconfig index 1878cc4f38d..2b4f502c617 100644 --- a/src/northbridge/intel/pineview/Kconfig +++ b/src/northbridge/intel/pineview/Kconfig @@ -33,6 +33,7 @@ config NORTHBRIDGE_SPECIFIC_OPTIONS # dummy select SMM_TSEG select PARALLEL_MP select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM + select C_ENVIRONMENT_BOOTBLOCK config BOOTBLOCK_NORTHBRIDGE_INIT string diff --git a/src/northbridge/intel/pineview/Makefile.inc b/src/northbridge/intel/pineview/Makefile.inc index 90a9f483739..c72fe3ee57e 100644 --- a/src/northbridge/intel/pineview/Makefile.inc +++ b/src/northbridge/intel/pineview/Makefile.inc @@ -16,6 +16,8 @@ ifeq ($(CONFIG_NORTHBRIDGE_INTEL_PINEVIEW),y) +bootblock-y += bootblock.c + ramstage-y += ram_calc.c ramstage-y += northbridge.c ramstage-y += gma.c diff --git a/src/northbridge/intel/pineview/bootblock.c b/src/northbridge/intel/pineview/bootblock.c index bd76fb933c3..bd510b00eef 100644 --- a/src/northbridge/intel/pineview/bootblock.c +++ b/src/northbridge/intel/pineview/bootblock.c @@ -12,11 +12,13 @@ */ #include -#define PCIEXBAR 0x60 +#include +#include "pineview.h" + #define MMCONF_256_BUSSES 16 #define ENABLE 1 -static void bootblock_northbridge_init(void) +void bootblock_early_northbridge_init(void) { pci_io_write_config32(PCI_DEV(0,0,0), PCIEXBAR, CONFIG_MMCONF_BASE_ADDRESS | MMCONF_256_BUSSES | ENABLE); diff --git a/src/northbridge/intel/pineview/pineview.h b/src/northbridge/intel/pineview/pineview.h index 65d21cfb8d1..f53ff17aa3d 100644 --- a/src/northbridge/intel/pineview/pineview.h +++ b/src/northbridge/intel/pineview/pineview.h @@ -236,7 +236,6 @@ u32 decode_igd_gtt_size(const u32 gsm); u8 decode_pciebar(u32 *const base, u32 *const len); /* Mainboard romstage callback functions */ -void mb_enable_lpc(void); void get_mb_spd_addrmap(u8 *spd_addr_map); void mb_pirq_setup(void); /* optional */ diff --git a/src/northbridge/intel/pineview/romstage.c b/src/northbridge/intel/pineview/romstage.c index 41fb0f6720d..8d7de451494 100644 --- a/src/northbridge/intel/pineview/romstage.c +++ b/src/northbridge/intel/pineview/romstage.c @@ -57,20 +57,12 @@ void mainboard_romstage_entry(unsigned long bist) if (bist == 0) enable_lapic(); - /* Disable watchdog timer */ - RCBA32(GCS) = RCBA32(GCS) | 0x20; - /* Enable GPIOs */ pci_write_config32(LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1); pci_write_config8(LPC_DEV, GPIO_CNTL, 0x10); setup_pch_gpios(&mainboard_gpio_map); - mb_enable_lpc(); // nm10_enable_lpc - - /* Initialize console device(s) */ - console_init(); - /* Halt if there was a built in self test failure */ report_bist_failure(bist); diff --git a/src/southbridge/intel/i82801gx/Makefile.inc b/src/southbridge/intel/i82801gx/Makefile.inc index 32a4bf53332..6e7f9bf945d 100644 --- a/src/southbridge/intel/i82801gx/Makefile.inc +++ b/src/southbridge/intel/i82801gx/Makefile.inc @@ -15,6 +15,8 @@ ifeq ($(CONFIG_SOUTHBRIDGE_INTEL_I82801GX),y) +bootblock-y += bootblock_gcc.c + ramstage-y += i82801gx.c ramstage-y += ac97.c ramstage-y += azalia.c diff --git a/src/southbridge/intel/i82801gx/bootblock_gcc.c b/src/southbridge/intel/i82801gx/bootblock_gcc.c new file mode 100644 index 00000000000..996788888a2 --- /dev/null +++ b/src/southbridge/intel/i82801gx/bootblock_gcc.c @@ -0,0 +1,44 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Sven Schnelle + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "i82801gx.h" + +static void enable_spi_prefetch(void) +{ + u8 reg8; + pci_devfn_t dev = PCI_DEV(0, 0x1f, 0); + + reg8 = pci_read_config8(dev, BIOS_CNTL); + reg8 &= ~(3 << 2); + reg8 |= (2 << 2); /* Prefetching and Caching Enabled */ + pci_write_config8(dev, BIOS_CNTL, reg8); +} + +void bootblock_early_southbridge_init(void) +{ + enable_spi_prefetch(); + + /* Enable RCBA */ + pci_devfn_t lpc_dev = PCI_DEV(0, 0x1f, 0); + pci_write_config32(lpc_dev, RCBA, (uintptr_t)DEFAULT_RCBA | 1); + + /* Enable upper 128bytes of CMOS */ + RCBA32(0x3400) = (1 << 2); + + /* Disable watchdog timer */ + RCBA32(GCS) = RCBA32(GCS) | 0x20; +} From d3872fcad91a97a8c0582381d1cc9745ccee5494 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Fri, 24 May 2019 17:54:29 +0200 Subject: [PATCH 439/588] superio/fintek/f71863fg: Remove variable set but not used Change-Id: I993055d237b2bd607822485d34d5508c74a7744c Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32990 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/superio/fintek/f71863fg/superio.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/superio/fintek/f71863fg/superio.c b/src/superio/fintek/f71863fg/superio.c index 634888b2177..a5cd632e490 100644 --- a/src/superio/fintek/f71863fg/superio.c +++ b/src/superio/fintek/f71863fg/superio.c @@ -23,15 +23,13 @@ static void f71863fg_init(struct device *dev) { - struct resource *res0; - if (!dev->enabled) return; switch (dev->path.pnp.device) { /* TODO: Might potentially need code for HWM or FDC etc. */ case F71863FG_KBC: - res0 = find_resource(dev, PNP_IDX_IO0); + find_resource(dev, PNP_IDX_IO0); pc_keyboard_init(NO_AUX_DEVICE); break; } From 82882288c9732aae9ba4baf7ff2916a886499ba2 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 19:06:43 +0200 Subject: [PATCH 440/588] nb/intel/pineview: Use MTRR as a proxy for proper reset On reset this platform can sometimes hang. This also fixes pineview mainboards not building due to the symbol 'check_mtrr' lacking. Change-Id: I61fe77113004ea664522bda549240a33e3742a98 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33010 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: HAOUAS Elyes --- src/northbridge/intel/pineview/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/northbridge/intel/pineview/Makefile.inc b/src/northbridge/intel/pineview/Makefile.inc index c72fe3ee57e..2d166138b66 100644 --- a/src/northbridge/intel/pineview/Makefile.inc +++ b/src/northbridge/intel/pineview/Makefile.inc @@ -16,6 +16,7 @@ ifeq ($(CONFIG_NORTHBRIDGE_INTEL_PINEVIEW),y) +bootblock-y += ../../../cpu/x86/early_reset.S bootblock-y += bootblock.c ramstage-y += ram_calc.c From 7ae606f57f0b3d450ae748141b0e2367041b27d3 Mon Sep 17 00:00:00 2001 From: Paul Menzel Date: Wed, 22 May 2019 19:19:15 +0200 Subject: [PATCH 441/588] libpayload: Reset PS/2 keyboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Loading a libpayload based payload like coreinfo or FILO from SeaBIOS or GRUB pressing keys does not give the expected results. For example, pressing F1 gives the character 24 translated to scan code 6a. ESC for example 43 (111) in coreinfo loaded from SeaBIOS on QEMU Q35. The problem is not reproducible using the payload directly, that means without SeaBIOS or GRUB. The problem seems to be, that those have already initialized the PS/2 controller and AT keyboard. Comparing it with coreboot’s PS/2 keyboard code, the keyboard needs to be reset. That seems to fix the issue, when the keyboard was initialized before. TEST=Build coreboot for QEMU Q35 with SeaBIOS, and coreinfo as secondary payload. Run qemu-system-i386 -M q35 -L /dev/shm -bios build/coreboot.rom -serial stdio press 3 to select the coreinfo payload, and verify that the keys F1 and F2 are working. Same with coreinfo loaded from GRUB on the ASRock E350M1. Change-Id: I2732292ac316d4bc0029ecb5c95fa7d1e7d68947 Signed-off-by: Paul Menzel Reviewed-on: https://review.coreboot.org/c/coreboot/+/32951 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- payloads/libpayload/drivers/i8042/i8042.h | 1 + payloads/libpayload/drivers/i8042/keyboard.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/payloads/libpayload/drivers/i8042/i8042.h b/payloads/libpayload/drivers/i8042/i8042.h index 643167ef409..e864ac92638 100644 --- a/payloads/libpayload/drivers/i8042/i8042.h +++ b/payloads/libpayload/drivers/i8042/i8042.h @@ -63,6 +63,7 @@ #define I8042_KBCMD_EN 0xf4 #define I8042_KBCMD_DEFAULT_DIS 0xf5 #define I8042_KBCMD_SET_DEFAULT 0xf6 +#define I8042_KBCMD_ACK 0xfa #define I8042_KBCMD_RESEND 0xfe #define I8042_KBCMD_RESET 0xff diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index cded6383809..fea9e718ddf 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -317,6 +317,13 @@ void keyboard_init(void) /* Enable first PS/2 port */ i8042_cmd(I8042_CMD_EN_KB); + /* Reset keyboard and self test (keyboard side) */ + ret = keyboard_cmd(I8042_KBCMD_RESET); + if (ret != I8042_KBCMD_ACK) { + printf("ERROR: Keyboard reset failed ACK: 0x%x\n", ret); + return; + } + /* Set scancode set 1 */ ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE); if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) From 1f925b15ae65ae4789b2ae1dd2ef8b4bbdc4e9f1 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 23 May 2019 14:37:40 +0200 Subject: [PATCH 442/588] drivers/intel/fsp1.1: Remove stale comment on bootflow This list is incorrect and not up to date. The FSP1.1 romstage bootflow is unnecessarily clumsy and instead of trying to update this comment effort is better spend making the bootflow more streamlined. Change-Id: If1e4c462acd0748f072f33e6397a7b43f3bfc834 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32959 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Frans Hendriks --- .../intel/fsp1_1/include/fsp/romstage.h | 35 ------------------- 1 file changed, 35 deletions(-) diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index de379508870..6ddafd858b0 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -42,41 +42,6 @@ struct romstage_params { const void *data_to_save; }; -/* - * FSP Boot Flow: - * 1. src/cpu/x86/16bit/reset.inc - * 2. src/cpu/x86/16bit/entry.inc - * 3. other modules - * 4. src/drivers/intel/fsp1_1/cache_as_ram.inc - * 5. src/drivers/intel/fsp1_1/fsp_util.c/find_fsp - * 6. FSP binary/TempRamInit - * 7. src/drivers/intel/fsp1_1/cache_as_ram.inc - return - * 8. src/soc/intel/common/romstage.c/romstage_main - * 9 src/soc/.../romstage/.../soc_pre_console_init - * 10 src/console/console.c/console_init - * 11 src/soc/.../romstage/.../soc_romstage_init - * 12. src/mainboard/.../romstage.c/mainboard_romstage_entry - * 13. src/soc/intel/common/romstage.c/romstage_common - * 14 src/soc/.../romstage/.../soc_pre_raminit - * 15. FSP binary/MemoryInit - * 16. src/soc/intel/common/romstage.c/romstage_common - return - * 17. src/mainboard/.../romstage.c/mainboard_romstage_entry - return - * 18. src/soc/intel/common/romstage.c/romstage_main - return - * 19. src/soc/intel/common/stack.c/setup_stack_and_mtrrs - * 20. src/drivers/intel/fsp1_1/cache_as_ram.inc - return, cleanup - * after call to romstage_main - * 21. FSP binary/TempRamExit - * 22. src/soc/intel/common/romstage.c/romstage_after_car - * 23. FSP binary/SiliconInit - * 24. src/soc/intel/common/romstage.c/romstage_after_car - return - * 25. src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify_boot_state_callback - * 26. src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify - * 27. FSP binary/FspNotify - * 28. src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify_boot_state_callback - * 29. src/drivers/intel/fsp1_1/fsp_util.c/fsp_notify - * 30. FSP binary/FspNotify - */ - void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params); void mainboard_romstage_entry(struct romstage_params *params); From 16d635c82c7de67c440ef17b3e5efdc36d17bb4a Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 23 May 2019 14:43:13 +0200 Subject: [PATCH 443/588] drivers/intel/fsp1.1: Remove unused function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This function is unused since POSTCAR_STAGE is used. (be291e8 soc/intel/fsp1.1: Implement postcar stage) Change-Id: Ia9ff5236295a0e1c4f7634d27cf0ae1d87029678 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32960 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Kyösti Mälkki Reviewed-by: Frans Hendriks --- src/drivers/intel/fsp1_1/include/fsp/romstage.h | 1 - src/drivers/intel/fsp1_1/romstage.c | 7 ------- 2 files changed, 8 deletions(-) diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index 6ddafd858b0..7efbb1085ca 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -55,7 +55,6 @@ void romstage_common(struct romstage_params *params); asmlinkage void romstage_main(FSP_INFO_HEADER *fih); /* Initialize memory margin analysis settings. */ void setup_mma(MEMORY_INIT_UPD *memory_upd); -void *setup_stack_and_mtrrs(void); void soc_after_ram_init(struct romstage_params *params); void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, MEMORY_INIT_UPD *new); diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 40c598877f2..85badced896 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -326,13 +326,6 @@ __weak void report_memory_config(void) { } -/* Choose top of stack and setup MTRRs */ -__weak void *setup_stack_and_mtrrs(void) -{ - die("ERROR - Must specify top of stack!\n"); - return NULL; -} - /* SOC initialization after RAM is enabled */ __weak void soc_after_ram_init(struct romstage_params *params) { From 608d73e4c50334e00e7543572eeb356d7b3325f5 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 9 Jan 2019 21:19:48 +0100 Subject: [PATCH 444/588] src/drivers/intel/fsp1_0: Move PLATFORM_USES_FSP1_0 drivers/intel/fsp1_0/Kconfig is a better location than cpu/x86/Kconfig. Change-Id: Ic1c86c26a66c33760484bb6a86e9763c148a7c96 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30791 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/cpu/x86/Kconfig | 7 ------- src/drivers/intel/fsp1_0/Kconfig | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig index 232fe63f32f..608afd7a28c 100644 --- a/src/cpu/x86/Kconfig +++ b/src/cpu/x86/Kconfig @@ -151,13 +151,6 @@ config X86_AMD_FIXED_MTRRS This option informs the MTRR code to use the RdMem and WrMem fields in the fixed MTRR MSRs. -config PLATFORM_USES_FSP1_0 - bool - default n - help - Selected for Intel processors/platform combinations that use the - Intel Firmware Support Package (FSP) 1.0 for initialization. - config MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING def_bool n help diff --git a/src/drivers/intel/fsp1_0/Kconfig b/src/drivers/intel/fsp1_0/Kconfig index 4ce528fb77d..361dd5ea851 100644 --- a/src/drivers/intel/fsp1_0/Kconfig +++ b/src/drivers/intel/fsp1_0/Kconfig @@ -13,6 +13,13 @@ ## GNU General Public License for more details. ## +config PLATFORM_USES_FSP1_0 + bool + default n + help + Selected for Intel processors/platform combinations that use the + Intel Firmware Support Package (FSP) 1.0 for initialization. + if PLATFORM_USES_FSP1_0 comment "Intel FSP" From 548f33a9f4a7675c42822516c285bdf2c8bb64de Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 15 May 2018 16:34:50 +0200 Subject: [PATCH 445/588] sb/intel/ibexpeak: Use common Intel SMM code TODO in followup patch: Some not mainboard specific things should be moved out of mainboard_smi_apmc. Change-Id: Ifc2d8f7755ace598e66b162d071d472093e4656e Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/26296 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/mainboard/lenovo/x201/smihandler.c | 2 +- src/mainboard/packardbell/ms2290/smihandler.c | 2 +- src/southbridge/intel/ibexpeak/Kconfig | 1 + src/southbridge/intel/ibexpeak/Makefile.inc | 1 - src/southbridge/intel/ibexpeak/pch.h | 1 - src/southbridge/intel/ibexpeak/smi.c | 347 --------- src/southbridge/intel/ibexpeak/smihandler.c | 696 +----------------- 7 files changed, 17 insertions(+), 1033 deletions(-) delete mode 100644 src/southbridge/intel/ibexpeak/smi.c diff --git a/src/mainboard/lenovo/x201/smihandler.c b/src/mainboard/lenovo/x201/smihandler.c index e733b3b5fe8..fc6a0e96701 100644 --- a/src/mainboard/lenovo/x201/smihandler.c +++ b/src/mainboard/lenovo/x201/smihandler.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/mainboard/packardbell/ms2290/smihandler.c b/src/mainboard/packardbell/ms2290/smihandler.c index ff13543cde0..83562be9211 100644 --- a/src/mainboard/packardbell/ms2290/smihandler.c +++ b/src/mainboard/packardbell/ms2290/smihandler.c @@ -18,9 +18,9 @@ #include #include #include -#include #include #include +#include #include #include #include diff --git a/src/southbridge/intel/ibexpeak/Kconfig b/src/southbridge/intel/ibexpeak/Kconfig index 4763133b80c..85c89799e08 100644 --- a/src/southbridge/intel/ibexpeak/Kconfig +++ b/src/southbridge/intel/ibexpeak/Kconfig @@ -32,6 +32,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy select SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ select SOUTHBRIDGE_INTEL_COMMON_SMBUS select SOUTHBRIDGE_INTEL_COMMON_SPI + select SOUTHBRIDGE_INTEL_COMMON_SMM select HAVE_USBDEBUG_OPTIONS select COMMON_FADT select ACPI_SATA_GENERATOR diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index 2fb371841af..24eac22b9fd 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -35,7 +35,6 @@ ramstage-y += ../bd82x6x/me_status.c ramstage-$(CONFIG_ELOG) += ../bd82x6x/elog.c ramstage-y += madt.c -ramstage-y += smi.c smm-y += smihandler.c me.c ../bd82x6x/me_8.x.c ../bd82x6x/pch.c romstage-y += ../bd82x6x/early_usb.c early_smbus.c ../bd82x6x/early_me.c ../bd82x6x/me_status.c ../common/gpio.c early_thermal.c diff --git a/src/southbridge/intel/ibexpeak/pch.h b/src/southbridge/intel/ibexpeak/pch.h index 9b2dd8ac8e1..90e7102ed25 100644 --- a/src/southbridge/intel/ibexpeak/pch.h +++ b/src/southbridge/intel/ibexpeak/pch.h @@ -61,7 +61,6 @@ int pch_silicon_revision(void); int pch_silicon_type(void); int pch_silicon_supported(int type, int rev); void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); -void gpi_route_interrupt(u8 gpi, u8 mode); #if CONFIG(ELOG) void pch_log_state(void); #endif diff --git a/src/southbridge/intel/ibexpeak/smi.c b/src/southbridge/intel/ibexpeak/smi.c deleted file mode 100644 index 4c9f2ac26d4..00000000000 --- a/src/southbridge/intel/ibexpeak/smi.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2008-2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#define __SIMPLE_DEVICE__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "pch.h" - -/* While we read PMBASE dynamically in case it changed, let's - * initialize it with a sane value - */ -static u16 pmbase = DEFAULT_PMBASE; - -/** - * @brief read and clear PM1_STS - * @return PM1_STS register - */ -static u16 reset_pm1_status(void) -{ - u16 reg16; - - reg16 = inw(pmbase + PM1_STS); - /* set status bits are cleared by writing 1 to them */ - outw(reg16, pmbase + PM1_STS); - - return reg16; -} - -static void dump_pm1_status(u16 pm1_sts) -{ - printk(BIOS_DEBUG, "PM1_STS: "); - if (pm1_sts & (1 << 15)) printk(BIOS_DEBUG, "WAK "); - if (pm1_sts & (1 << 14)) printk(BIOS_DEBUG, "PCIEXPWAK "); - if (pm1_sts & (1 << 11)) printk(BIOS_DEBUG, "PRBTNOR "); - if (pm1_sts & (1 << 10)) printk(BIOS_DEBUG, "RTC "); - if (pm1_sts & (1 << 8)) printk(BIOS_DEBUG, "PWRBTN "); - if (pm1_sts & (1 << 5)) printk(BIOS_DEBUG, "GBL "); - if (pm1_sts & (1 << 4)) printk(BIOS_DEBUG, "BM "); - if (pm1_sts & (1 << 0)) printk(BIOS_DEBUG, "TMROF "); - printk(BIOS_DEBUG, "\n"); -} - -/** - * @brief read and clear SMI_STS - * @return SMI_STS register - */ -static u32 reset_smi_status(void) -{ - u32 reg32; - - reg32 = inl(pmbase + SMI_STS); - /* set status bits are cleared by writing 1 to them */ - outl(reg32, pmbase + SMI_STS); - - return reg32; -} - -static void dump_smi_status(u32 smi_sts) -{ - printk(BIOS_DEBUG, "SMI_STS: "); - if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI "); - if (smi_sts & (1 << 25)) printk(BIOS_DEBUG, "EL_SMI "); - if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR "); - if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI "); - if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 "); - if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 "); - if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI "); - if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI "); - if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC "); - if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO "); - if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON "); - if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI "); - if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI "); - if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 "); - if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 "); - if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR "); - if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM "); - if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI "); - if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB "); - if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS "); - printk(BIOS_DEBUG, "\n"); -} - - -/** - * @brief read and clear GPE0_STS - * @return GPE0_STS register - */ -static u32 reset_gpe0_status(void) -{ - u32 reg32; - - reg32 = inl(pmbase + GPE0_STS); - /* set status bits are cleared by writing 1 to them */ - outl(reg32, pmbase + GPE0_STS); - - return reg32; -} - -static void dump_gpe0_status(u32 gpe0_sts) -{ - int i; - printk(BIOS_DEBUG, "GPE0_STS: "); - for (i=31; i>= 16; i--) { - if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16)); - } - if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 "); - if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 "); - if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 "); - if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME "); - if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "EL_SCI/BATLOW "); - if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP "); - if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI "); - if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK "); - if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI "); - if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 "); - if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 "); - if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 "); - if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "HOT_PLUG "); - if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM "); - printk(BIOS_DEBUG, "\n"); -} - - -/** - * @brief read and clear ALT_GP_SMI_STS - * @return ALT_GP_SMI_STS register - */ -static u16 reset_alt_gp_smi_status(void) -{ - u16 reg16; - - reg16 = inl(pmbase + ALT_GP_SMI_STS); - /* set status bits are cleared by writing 1 to them */ - outl(reg16, pmbase + ALT_GP_SMI_STS); - - return reg16; -} - -static void dump_alt_gp_smi_status(u16 alt_gp_smi_sts) -{ - int i; - printk(BIOS_DEBUG, "ALT_GP_SMI_STS: "); - for (i=15; i>= 0; i--) { - if (alt_gp_smi_sts & (1 << i)) printk(BIOS_DEBUG, "GPI%d ", i); - } - printk(BIOS_DEBUG, "\n"); -} - - - -/** - * @brief read and clear TCOx_STS - * @return TCOx_STS registers - */ -static u32 reset_tco_status(void) -{ - u32 tcobase = pmbase + 0x60; - u32 reg32; - - reg32 = inl(tcobase + 0x04); - /* set status bits are cleared by writing 1 to them */ - outl(reg32 & ~(1 << 18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS - if (reg32 & (1 << 18)) - outl(reg32 & (1 << 18), tcobase + 0x04); // clear BOOT_STS - - return reg32; -} - - -static void dump_tco_status(u32 tco_sts) -{ - printk(BIOS_DEBUG, "TCO_STS: "); - if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV "); - if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT "); - if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO "); - if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET "); - if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR "); - if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI "); - if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI "); - if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR "); - if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY "); - if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT "); - if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT "); - if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO "); - if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI "); - printk(BIOS_DEBUG, "\n"); -} - - - -/** - * @brief Set the EOS bit - */ -static void smi_set_eos(void) -{ - u8 reg8; - - reg8 = inb(pmbase + SMI_EN); - reg8 |= EOS; - outb(reg8, pmbase + SMI_EN); -} - -void southbridge_smm_init(void) -{ - u32 smi_en; - u16 pm1_en; - u32 gpe0_en; - -#if CONFIG(ELOG) - /* Log events from chipset before clearing */ - pch_log_state(); -#endif - - printk(BIOS_DEBUG, "Initializing southbridge SMI..."); - - pmbase = pci_read_config32(PCI_DEV(0, 0x1f, 0), - PMBASE) & 0xff80; - - printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", pmbase); - - smi_en = inl(pmbase + SMI_EN); - if (smi_en & APMC_EN) { - printk(BIOS_INFO, "SMI# handler already enabled?\n"); - return; - } - - printk(BIOS_DEBUG, "\n"); - dump_smi_status(reset_smi_status()); - dump_pm1_status(reset_pm1_status()); - dump_gpe0_status(reset_gpe0_status()); - dump_alt_gp_smi_status(reset_alt_gp_smi_status()); - dump_tco_status(reset_tco_status()); - - /* Disable GPE0 PME_B0 */ - gpe0_en = inl(pmbase + GPE0_EN); - gpe0_en &= ~PME_B0_EN; - outl(gpe0_en, pmbase + GPE0_EN); - - pm1_en = 0; - pm1_en |= PWRBTN_EN; - pm1_en |= GBL_EN; - outw(pm1_en, pmbase + PM1_EN); - - /* Enable SMI generation: - * - on TCO events - * - on APMC writes (io 0xb2) - * - on writes to SLP_EN (sleep states) - * - on writes to GBL_RLS (bios commands) - * No SMIs: - * - on microcontroller writes (io 0x62/0x66) - */ - - smi_en = 0; /* reset SMI enables */ - -#if 0 - smi_en |= LEGACY_USB2_EN | LEGACY_USB_EN; -#endif - smi_en |= TCO_EN; - smi_en |= APMC_EN; -#if DEBUG_PERIODIC_SMIS - /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using - * periodic SMIs. - */ - smi_en |= PERIODIC_EN; -#endif - smi_en |= SLP_SMI_EN; -#if 0 - smi_en |= BIOS_EN; -#endif - - /* The following need to be on for SMIs to happen */ - smi_en |= EOS | GBL_SMI_EN; - - outl(smi_en, pmbase + SMI_EN); -} - -void southbridge_trigger_smi(void) -{ - /** - * There are several methods of raising a controlled SMI# via - * software, among them: - * - Writes to io 0xb2 (APMC) - * - Writes to the Local Apic ICR with Delivery mode SMI. - * - * Using the local apic is a bit more tricky. According to - * AMD Family 11 Processor BKDG no destination shorthand must be - * used. - * The whole SMM initialization is quite a bit hardware specific, so - * I'm not too worried about the better of the methods at the moment - */ - - /* raise an SMI interrupt */ - printk(BIOS_SPEW, " ... raise SMI#\n"); - outb(0x00, 0xb2); -} - -void southbridge_clear_smi_status(void) -{ - /* Clear SMI status */ - reset_smi_status(); - - /* Clear PM1 status */ - reset_pm1_status(); - - /* Set EOS bit so other SMIs can occur. */ - smi_set_eos(); -} - -void smm_setup_structures(void *gnvs, void *tcg, void *smi1) -{ - /* - * Issue SMI to set the gnvs pointer in SMM. - * tcg and smi1 are unused. - * - * EAX = APM_CNT_GNVS_UPDATE - * EBX = gnvs pointer - * EDX = APM_CNT - */ - asm volatile ( - "outb %%al, %%dx\n\t" - : /* ignore result */ - : "a" (APM_CNT_GNVS_UPDATE), - "b" ((u32)gnvs), - "d" (APM_CNT) - ); -} diff --git a/src/southbridge/intel/ibexpeak/smihandler.c b/src/southbridge/intel/ibexpeak/smihandler.c index fabe1c41ba7..dbc412c072d 100644 --- a/src/southbridge/intel/ibexpeak/smihandler.c +++ b/src/southbridge/intel/ibexpeak/smihandler.c @@ -35,13 +35,7 @@ */ #include #include - -/* While we read PMBASE dynamically in case it changed, let's - * initialize it with a sane value - */ -static u16 pmbase = DEFAULT_PMBASE; - -static u8 smm_initialized = 0; +#include /* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located * by coreboot. @@ -52,193 +46,6 @@ global_nvs_t *smm_get_gnvs(void) return gnvs; } -static void alt_gpi_mask(u16 clr, u16 set) -{ - u16 alt_gp = inw(pmbase + ALT_GP_SMI_EN); - alt_gp &= ~clr; - alt_gp |= set; - outw(alt_gp, pmbase + ALT_GP_SMI_EN); -} - -static void gpe0_mask(u32 clr, u32 set) -{ - u32 gpe0 = inl(pmbase + GPE0_EN); - gpe0 &= ~clr; - gpe0 |= set; - outl(gpe0, pmbase + GPE0_EN); -} - -void gpi_route_interrupt(u8 gpi, u8 mode) -{ - u32 gpi_rout; - if (gpi >= 16) - return; - - alt_gpi_mask(1 << gpi, 0); - gpe0_mask(1 << (gpi+16), 0); - - gpi_rout = pci_read_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT); - gpi_rout &= ~(3 << (2 * gpi)); - gpi_rout |= ((mode & 3) << (2 * gpi)); - pci_write_config32(PCI_DEV(0, 0x1f, 0), GPIO_ROUT, gpi_rout); - - if (mode == GPI_IS_SCI) - gpe0_mask(0, 1 << (gpi+16)); - else if (mode == GPI_IS_SMI) - alt_gpi_mask(0, 1 << gpi); -} - -/** - * @brief read and clear PM1_STS - * @return PM1_STS register - */ -static u16 reset_pm1_status(void) -{ - u16 reg16; - - reg16 = inw(pmbase + PM1_STS); - /* set status bits are cleared by writing 1 to them */ - outw(reg16, pmbase + PM1_STS); - - return reg16; -} - -static void dump_pm1_status(u16 pm1_sts) -{ - printk(BIOS_SPEW, "PM1_STS: "); - if (pm1_sts & (1 << 15)) printk(BIOS_SPEW, "WAK "); - if (pm1_sts & (1 << 14)) printk(BIOS_SPEW, "PCIEXPWAK "); - if (pm1_sts & (1 << 11)) printk(BIOS_SPEW, "PRBTNOR "); - if (pm1_sts & (1 << 10)) printk(BIOS_SPEW, "RTC "); - if (pm1_sts & (1 << 8)) printk(BIOS_SPEW, "PWRBTN "); - if (pm1_sts & (1 << 5)) printk(BIOS_SPEW, "GBL "); - if (pm1_sts & (1 << 4)) printk(BIOS_SPEW, "BM "); - if (pm1_sts & (1 << 0)) printk(BIOS_SPEW, "TMROF "); - printk(BIOS_SPEW, "\n"); - int reg16 = inw(pmbase + PM1_EN); - printk(BIOS_SPEW, "PM1_EN: %x\n", reg16); -} - -/** - * @brief read and clear SMI_STS - * @return SMI_STS register - */ -static u32 reset_smi_status(void) -{ - u32 reg32; - - reg32 = inl(pmbase + SMI_STS); - /* set status bits are cleared by writing 1 to them */ - outl(reg32, pmbase + SMI_STS); - - return reg32; -} - -static void dump_smi_status(u32 smi_sts) -{ - printk(BIOS_DEBUG, "SMI_STS: "); - if (smi_sts & (1 << 26)) printk(BIOS_DEBUG, "SPI "); - if (smi_sts & (1 << 21)) printk(BIOS_DEBUG, "MONITOR "); - if (smi_sts & (1 << 20)) printk(BIOS_DEBUG, "PCI_EXP_SMI "); - if (smi_sts & (1 << 18)) printk(BIOS_DEBUG, "INTEL_USB2 "); - if (smi_sts & (1 << 17)) printk(BIOS_DEBUG, "LEGACY_USB2 "); - if (smi_sts & (1 << 16)) printk(BIOS_DEBUG, "SMBUS_SMI "); - if (smi_sts & (1 << 15)) printk(BIOS_DEBUG, "SERIRQ_SMI "); - if (smi_sts & (1 << 14)) printk(BIOS_DEBUG, "PERIODIC "); - if (smi_sts & (1 << 13)) printk(BIOS_DEBUG, "TCO "); - if (smi_sts & (1 << 12)) printk(BIOS_DEBUG, "DEVMON "); - if (smi_sts & (1 << 11)) printk(BIOS_DEBUG, "MCSMI "); - if (smi_sts & (1 << 10)) printk(BIOS_DEBUG, "GPI "); - if (smi_sts & (1 << 9)) printk(BIOS_DEBUG, "GPE0 "); - if (smi_sts & (1 << 8)) printk(BIOS_DEBUG, "PM1 "); - if (smi_sts & (1 << 6)) printk(BIOS_DEBUG, "SWSMI_TMR "); - if (smi_sts & (1 << 5)) printk(BIOS_DEBUG, "APM "); - if (smi_sts & (1 << 4)) printk(BIOS_DEBUG, "SLP_SMI "); - if (smi_sts & (1 << 3)) printk(BIOS_DEBUG, "LEGACY_USB "); - if (smi_sts & (1 << 2)) printk(BIOS_DEBUG, "BIOS "); - printk(BIOS_DEBUG, "\n"); -} - - -/** - * @brief read and clear GPE0_STS - * @return GPE0_STS register - */ -static u32 reset_gpe0_status(void) -{ - u32 reg32; - - reg32 = inl(pmbase + GPE0_STS); - /* set status bits are cleared by writing 1 to them */ - outl(reg32, pmbase + GPE0_STS); - - return reg32; -} - -static void dump_gpe0_status(u32 gpe0_sts) -{ - int i; - printk(BIOS_DEBUG, "GPE0_STS: "); - for (i=31; i>= 16; i--) { - if (gpe0_sts & (1 << i)) printk(BIOS_DEBUG, "GPIO%d ", (i-16)); - } - if (gpe0_sts & (1 << 14)) printk(BIOS_DEBUG, "USB4 "); - if (gpe0_sts & (1 << 13)) printk(BIOS_DEBUG, "PME_B0 "); - if (gpe0_sts & (1 << 12)) printk(BIOS_DEBUG, "USB3 "); - if (gpe0_sts & (1 << 11)) printk(BIOS_DEBUG, "PME "); - if (gpe0_sts & (1 << 10)) printk(BIOS_DEBUG, "BATLOW "); - if (gpe0_sts & (1 << 9)) printk(BIOS_DEBUG, "PCI_EXP "); - if (gpe0_sts & (1 << 8)) printk(BIOS_DEBUG, "RI "); - if (gpe0_sts & (1 << 7)) printk(BIOS_DEBUG, "SMB_WAK "); - if (gpe0_sts & (1 << 6)) printk(BIOS_DEBUG, "TCO_SCI "); - if (gpe0_sts & (1 << 5)) printk(BIOS_DEBUG, "AC97 "); - if (gpe0_sts & (1 << 4)) printk(BIOS_DEBUG, "USB2 "); - if (gpe0_sts & (1 << 3)) printk(BIOS_DEBUG, "USB1 "); - if (gpe0_sts & (1 << 2)) printk(BIOS_DEBUG, "SWGPE "); - if (gpe0_sts & (1 << 1)) printk(BIOS_DEBUG, "HOTPLUG "); - if (gpe0_sts & (1 << 0)) printk(BIOS_DEBUG, "THRM "); - printk(BIOS_DEBUG, "\n"); -} - - -/** - * @brief read and clear TCOx_STS - * @return TCOx_STS registers - */ -static u32 reset_tco_status(void) -{ - u32 tcobase = pmbase + 0x60; - u32 reg32; - - reg32 = inl(tcobase + 0x04); - /* set status bits are cleared by writing 1 to them */ - outl(reg32 & ~(1 << 18), tcobase + 0x04); // Don't clear BOOT_STS before SECOND_TO_STS - if (reg32 & (1 << 18)) - outl(reg32 & (1 << 18), tcobase + 0x04); // clear BOOT_STS - - return reg32; -} - - -static void dump_tco_status(u32 tco_sts) -{ - printk(BIOS_DEBUG, "TCO_STS: "); - if (tco_sts & (1 << 20)) printk(BIOS_DEBUG, "SMLINK_SLV "); - if (tco_sts & (1 << 18)) printk(BIOS_DEBUG, "BOOT "); - if (tco_sts & (1 << 17)) printk(BIOS_DEBUG, "SECOND_TO "); - if (tco_sts & (1 << 16)) printk(BIOS_DEBUG, "INTRD_DET "); - if (tco_sts & (1 << 12)) printk(BIOS_DEBUG, "DMISERR "); - if (tco_sts & (1 << 10)) printk(BIOS_DEBUG, "DMISMI "); - if (tco_sts & (1 << 9)) printk(BIOS_DEBUG, "DMISCI "); - if (tco_sts & (1 << 8)) printk(BIOS_DEBUG, "BIOSWR "); - if (tco_sts & (1 << 7)) printk(BIOS_DEBUG, "NEWCENTURY "); - if (tco_sts & (1 << 3)) printk(BIOS_DEBUG, "TIMEOUT "); - if (tco_sts & (1 << 2)) printk(BIOS_DEBUG, "TCO_INT "); - if (tco_sts & (1 << 1)) printk(BIOS_DEBUG, "SW_TCO "); - if (tco_sts & (1 << 0)) printk(BIOS_DEBUG, "NMI2SMI "); - printk(BIOS_DEBUG, "\n"); -} - int southbridge_io_trap_handler(int smif) { switch (smif) { @@ -256,53 +63,6 @@ int southbridge_io_trap_handler(int smif) return 0; } -/** - * @brief Set the EOS bit - */ -void southbridge_smi_set_eos(void) -{ - u8 reg8; - - reg8 = inb(pmbase + SMI_EN); - reg8 |= EOS; - outb(reg8, pmbase + SMI_EN); -} - -static void busmaster_disable_on_bus(int bus) -{ - int slot, func; - unsigned int val; - unsigned char hdr; - - for (slot = 0; slot < 0x20; slot++) { - for (func = 0; func < 8; func++) { - u32 reg32; - pci_devfn_t dev = PCI_DEV(bus, slot, func); - - val = pci_read_config32(dev, PCI_VENDOR_ID); - - if (val == 0xffffffff || val == 0x00000000 || - val == 0x0000ffff || val == 0xffff0000) - continue; - - /* Disable Bus Mastering for this one device */ - reg32 = pci_read_config32(dev, PCI_COMMAND); - reg32 &= ~PCI_COMMAND_MASTER; - pci_write_config32(dev, PCI_COMMAND, reg32); - - /* If this is a bridge, then follow it. */ - hdr = pci_read_config8(dev, PCI_HEADER_TYPE); - hdr &= 0x7f; - if (hdr == PCI_HEADER_TYPE_BRIDGE || - hdr == PCI_HEADER_TYPE_CARDBUS) { - unsigned int buses; - buses = pci_read_config32(dev, PCI_PRIMARY_BUS); - busmaster_disable_on_bus((buses >> 8) & 0xff); - } - } - } -} - static void southbridge_gate_memory_reset_real(int offset, u16 use, u16 io, u16 lvl) { @@ -334,7 +94,7 @@ static void southbridge_gate_memory_reset_real(int offset, * Intel reference designs all use GPIO 60 but it is * not a requirement and boards could use a different pin. */ -static void southbridge_gate_memory_reset(void) +void southbridge_gate_memory_reset(void) { u16 gpiobase; @@ -354,377 +114,7 @@ static void southbridge_gate_memory_reset(void) gpiobase + GP_LVL); } -static void xhci_sleep(u8 slp_typ) -{ - u32 reg32, xhci_bar; - u16 reg16; - - switch (slp_typ) { - case ACPI_S3: - case ACPI_S4: - reg16 = pci_read_config16(PCH_XHCI_DEV, 0x74); - reg16 &= ~0x03UL; - pci_write_config32(PCH_XHCI_DEV, 0x74, reg16); - - reg32 = pci_read_config32(PCH_XHCI_DEV, PCI_COMMAND); - reg32 |= (PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - pci_write_config32(PCH_XHCI_DEV, PCI_COMMAND, reg32); - - xhci_bar = pci_read_config32(PCH_XHCI_DEV, - PCI_BASE_ADDRESS_0) & ~0xFUL; - - if ((xhci_bar + 0x4C0) & 1) - pch_iobp_update(0xEC000082, ~0UL, (3 << 2)); - if ((xhci_bar + 0x4D0) & 1) - pch_iobp_update(0xEC000182, ~0UL, (3 << 2)); - if ((xhci_bar + 0x4E0) & 1) - pch_iobp_update(0xEC000282, ~0UL, (3 << 2)); - if ((xhci_bar + 0x4F0) & 1) - pch_iobp_update(0xEC000382, ~0UL, (3 << 2)); - - reg32 = pci_read_config32(PCH_XHCI_DEV, PCI_COMMAND); - reg32 &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); - pci_write_config32(PCH_XHCI_DEV, PCI_COMMAND, reg32); - - reg16 = pci_read_config16(PCH_XHCI_DEV, 0x74); - reg16 |= 0x03; - pci_write_config16(PCH_XHCI_DEV, 0x74, reg16); - break; - - case ACPI_S5: - reg16 = pci_read_config16(PCH_XHCI_DEV, 0x74); - reg16 |= ((1 << 8) | 0x03); - pci_write_config16(PCH_XHCI_DEV, 0x74, reg16); - break; - } -} - -static void southbridge_smi_sleep(void) -{ - u8 reg8; - u32 reg32; - u8 slp_typ; - u8 s5pwr = CONFIG_MAINBOARD_POWER_FAILURE_STATE; - - // save and recover RTC port values - u8 tmp70, tmp72; - tmp70 = inb(0x70); - tmp72 = inb(0x72); - get_option(&s5pwr, "power_on_after_fail"); - outb(tmp70, 0x70); - outb(tmp72, 0x72); - - /* First, disable further SMIs */ - reg8 = inb(pmbase + SMI_EN); - reg8 &= ~SLP_SMI_EN; - outb(reg8, pmbase + SMI_EN); - - /* Figure out SLP_TYP */ - reg32 = inl(pmbase + PM1_CNT); - printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32); - slp_typ = acpi_sleep_from_pm1(reg32); - - if (smm_get_gnvs()->xhci) - xhci_sleep(slp_typ); - - /* Do any mainboard sleep handling */ - mainboard_smi_sleep(slp_typ); - -#if CONFIG(ELOG_GSMI) - /* Log S3, S4, and S5 entry */ - if (slp_typ >= ACPI_S3) - elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ); -#endif - - /* Next, do the deed. - */ - - switch (slp_typ) { - case ACPI_S0: printk(BIOS_DEBUG, "SMI#: Entering S0 (On)\n"); break; - case ACPI_S1: printk(BIOS_DEBUG, "SMI#: Entering S1 (Assert STPCLK#)\n"); break; - case ACPI_S3: - printk(BIOS_DEBUG, "SMI#: Entering S3 (Suspend-To-RAM)\n"); - - /* Gate memory reset */ - southbridge_gate_memory_reset(); - - /* Invalidate the cache before going to S3 */ - wbinvd(); - break; - case ACPI_S4: printk(BIOS_DEBUG, "SMI#: Entering S4 (Suspend-To-Disk)\n"); break; - case ACPI_S5: - printk(BIOS_DEBUG, "SMI#: Entering S5 (Soft Power off)\n"); - - outl(0, pmbase + GPE0_EN); - - /* Always set the flag in case CMOS was changed on runtime. For - * "KEEP", switch to "OFF" - KEEP is software emulated - */ - reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3); - if (s5pwr == MAINBOARD_POWER_ON) { - reg8 &= ~1; - } else { - reg8 |= 1; - } - pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8); - - /* also iterates over all bridges on bus 0 */ - busmaster_disable_on_bus(0); - break; - default: printk(BIOS_DEBUG, "SMI#: ERROR: SLP_TYP reserved\n"); break; - } - - /* Write back to the SLP register to cause the originally intended - * event again. We need to set BIT13 (SLP_EN) though to make the - * sleep happen. - */ - outl(reg32 | SLP_EN, pmbase + PM1_CNT); - - /* Make sure to stop executing code here for S3/S4/S5 */ - if (slp_typ >= ACPI_S3) - halt(); - - /* In most sleep states, the code flow of this function ends at - * the line above. However, if we entered sleep state S1 and wake - * up again, we will continue to execute code in this function. - */ - reg32 = inl(pmbase + PM1_CNT); - if (reg32 & SCI_EN) { - /* The OS is not an ACPI OS, so we set the state to S0 */ - reg32 &= ~(SLP_EN | SLP_TYP); - outl(reg32, pmbase + PM1_CNT); - } -} - -/* - * Look for Synchronous IO SMI and use save state from that - * core in case we are not running on the same core that - * initiated the IO transaction. - */ -static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd) -{ - em64t101_smm_state_save_area_t *state; - int node; - - /* Check all nodes looking for the one that issued the IO */ - for (node = 0; node < CONFIG_MAX_CPUS; node++) { - state = smm_get_save_state(node); - - /* Check for Synchronous IO (bit0 == 1) */ - if (!(state->io_misc_info & (1 << 0))) - continue; - - /* Make sure it was a write (bit4 == 0) */ - if (state->io_misc_info & (1 << 4)) - continue; - - /* Check for APMC IO port */ - if (((state->io_misc_info >> 16) & 0xff) != APM_CNT) - continue; - - /* Check AX against the requested command */ - if ((state->rax & 0xff) != cmd) - continue; - - return state; - } - - return NULL; -} - -#if CONFIG(ELOG_GSMI) -static void southbridge_smi_gsmi(void) -{ - u32 *ret, *param; - u8 sub_command; - em64t101_smm_state_save_area_t *io_smi = - smi_apmc_find_state_save(APM_CNT_ELOG_GSMI); - - if (!io_smi) - return; - - /* Command and return value in EAX */ - ret = (u32*)&io_smi->rax; - sub_command = (u8)(*ret >> 8); - - /* Parameter buffer in EBX */ - param = (u32*)&io_smi->rbx; - - /* drivers/elog/gsmi.c */ - *ret = gsmi_exec(sub_command, param); -} -#endif - -static void southbridge_smi_apmc(void) -{ - u32 pmctrl; - u8 reg8; - em64t101_smm_state_save_area_t *state; - - /* Emulate B2 register as the FADT / Linux expects it */ - - reg8 = inb(APM_CNT); - switch (reg8) { - case APM_CNT_CST_CONTROL: - /* Calling this function seems to cause - * some kind of race condition in Linux - * and causes a kernel oops - */ - printk(BIOS_DEBUG, "C-state control\n"); - break; - case APM_CNT_PST_CONTROL: - /* Calling this function seems to cause - * some kind of race condition in Linux - * and causes a kernel oops - */ - printk(BIOS_DEBUG, "P-state control\n"); - break; - case APM_CNT_ACPI_DISABLE: - pmctrl = inl(pmbase + PM1_CNT); - pmctrl &= ~SCI_EN; - outl(pmctrl, pmbase + PM1_CNT); - printk(BIOS_DEBUG, "SMI#: ACPI disabled.\n"); - break; - case APM_CNT_ACPI_ENABLE: - pmctrl = inl(pmbase + PM1_CNT); - pmctrl |= SCI_EN; - outl(pmctrl, pmbase + PM1_CNT); - printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n"); - break; - case APM_CNT_GNVS_UPDATE: - if (smm_initialized) { - printk(BIOS_DEBUG, "SMI#: SMM structures already initialized!\n"); - return; - } - state = smi_apmc_find_state_save(reg8); - if (state) { - /* EBX in the state save contains the GNVS pointer */ - gnvs = (global_nvs_t *)((u32)state->rbx); - smm_initialized = 1; - printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); - } - break; -#if CONFIG(ELOG_GSMI) - case APM_CNT_ELOG_GSMI: - southbridge_smi_gsmi(); - break; -#endif - } - - mainboard_smi_apmc(reg8); -} - -static void southbridge_smi_pm1(void) -{ - u16 pm1_sts; - - pm1_sts = reset_pm1_status(); - dump_pm1_status(pm1_sts); - - /* While OSPM is not active, poweroff immediately - * on a power button event. - */ - if (pm1_sts & PWRBTN_STS) { - // power button pressed - u32 reg32; - reg32 = (7 << 10) | (1 << 13); -#if CONFIG(ELOG_GSMI) - elog_add_event(ELOG_TYPE_POWER_BUTTON); -#endif - outl(reg32, pmbase + PM1_CNT); - } -} - -static void southbridge_smi_gpe0(void) -{ - u32 gpe0_sts; - - gpe0_sts = reset_gpe0_status(); - dump_gpe0_status(gpe0_sts); -} - -static void southbridge_smi_gpi(void) -{ - u16 reg16; - reg16 = inw(pmbase + ALT_GP_SMI_STS); - outw(reg16, pmbase + ALT_GP_SMI_STS); - - reg16 &= inw(pmbase + ALT_GP_SMI_EN); - - mainboard_smi_gpi(reg16); - - if (reg16) - printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16); - - outw(reg16, pmbase + ALT_GP_SMI_STS); -} - -static void southbridge_smi_mc(void) -{ - u32 reg32; - - reg32 = inl(pmbase + SMI_EN); - - /* Are periodic SMIs enabled? */ - if ((reg32 & MCSMI_EN) == 0) - return; - - printk(BIOS_DEBUG, "Microcontroller SMI.\n"); -} - - - -static void southbridge_smi_tco(void) -{ - u32 tco_sts; - - tco_sts = reset_tco_status(); - - /* Any TCO event? */ - if (!tco_sts) - return; - - if (tco_sts & (1 << 8)) { // BIOSWR - u8 bios_cntl; - - bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc); - - if (bios_cntl & 1) { - /* BWE is RW, so the SMI was caused by a - * write to BWE, not by a write to the BIOS - */ - - /* This is the place where we notice someone - * is trying to tinker with the BIOS. We are - * trying to be nice and just ignore it. A more - * resolute answer would be to power down the - * box. - */ - printk(BIOS_DEBUG, "Switching back to RO\n"); - pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc, (bios_cntl & ~1)); - } /* No else for now? */ - } else if (tco_sts & (1 << 3)) { /* TIMEOUT */ - /* Handle TCO timeout */ - printk(BIOS_DEBUG, "TCO Timeout.\n"); - } else { - dump_tco_status(tco_sts); - } -} - -static void southbridge_smi_periodic(void) -{ - u32 reg32; - - reg32 = inl(pmbase + SMI_EN); - - /* Are periodic SMIs enabled? */ - if ((reg32 & PERIODIC_EN) == 0) - return; - - printk(BIOS_DEBUG, "Periodic SMI.\n"); -} - -static void southbridge_smi_monitor(void) +void southbridge_smi_monitor(void) { #define IOTRAP(x) (trap_sts & (1 << x)) u32 trap_sts, trap_cycle; @@ -778,76 +168,18 @@ static void southbridge_smi_monitor(void) #undef IOTRAP } -typedef void (*smi_handler_t)(void); - -static smi_handler_t southbridge_smi[32] = { - NULL, // [0] reserved - NULL, // [1] reserved - NULL, // [2] BIOS_STS - NULL, // [3] LEGACY_USB_STS - southbridge_smi_sleep, // [4] SLP_SMI_STS - southbridge_smi_apmc, // [5] APM_STS - NULL, // [6] SWSMI_TMR_STS - NULL, // [7] reserved - southbridge_smi_pm1, // [8] PM1_STS - southbridge_smi_gpe0, // [9] GPE0_STS - southbridge_smi_gpi, // [10] GPI_STS - southbridge_smi_mc, // [11] MCSMI_STS - NULL, // [12] DEVMON_STS - southbridge_smi_tco, // [13] TCO_STS - southbridge_smi_periodic, // [14] PERIODIC_STS - NULL, // [15] SERIRQ_SMI_STS - NULL, // [16] SMBUS_SMI_STS - NULL, // [17] LEGACY_USB2_STS - NULL, // [18] INTEL_USB2_STS - NULL, // [19] reserved - NULL, // [20] PCI_EXP_SMI_STS - southbridge_smi_monitor, // [21] MONITOR_STS - NULL, // [22] reserved - NULL, // [23] reserved - NULL, // [24] reserved - NULL, // [25] EL_SMI_STS - NULL, // [26] SPI_STS - NULL, // [27] reserved - NULL, // [28] reserved - NULL, // [29] reserved - NULL, // [30] reserved - NULL // [31] reserved -}; - -/** - * @brief Interrupt handler for SMI# - * @param node - * @param state_save - */ -void southbridge_smi_handler(void) +void southbridge_update_gnvs(u8 apm_cnt, int *smm_done) { - int i, dump = 0; - u32 smi_sts; - - /* Update global variable pmbase */ - pmbase = lpc_get_pmbase(); - - /* We need to clear the SMI status registers, or we won't see what's - * happening in the following calls. - */ - smi_sts = reset_smi_status(); - - /* Call SMI sub handler for each of the status bits */ - for (i = 0; i < 31; i++) { - if (smi_sts & (1 << i)) { - if (southbridge_smi[i]) { - southbridge_smi[i](); - } else { - printk(BIOS_DEBUG, "SMI_STS[%d] occurred, but no " - "handler available.\n", i); - dump = 1; - } - } - } - - if (dump) { - dump_smi_status(smi_sts); + em64t101_smm_state_save_area_t *state = + smi_apmc_find_state_save(apm_cnt); + if (state) { + /* EBX in the state save contains the GNVS pointer */ + gnvs = (global_nvs_t *)((u32)state->rbx); + *smm_done = 1; + printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs); } +} +void southbridge_finalize_all(void) +{ } From b66ee5507c4c2395868a5cd350dc8a7eb46542fd Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 15 May 2018 16:35:45 +0200 Subject: [PATCH 446/588] cpu/intel/model_2065x: Use parallel MP init TESTED on Thinkpad X201 with a i7 CPU M620 CPU (hyperthread dual core). Boots ~28ms faster. Change-Id: I56b352f9d76ee58f5c82cd431a4e0fa206f848a0 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/26297 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/cpu/intel/model_2065x/Kconfig | 1 + src/cpu/intel/model_2065x/model_2065x.h | 1 + src/cpu/intel/model_2065x/model_2065x_init.c | 153 +++++++++---------- src/northbridge/intel/nehalem/northbridge.c | 2 +- 4 files changed, 73 insertions(+), 84 deletions(-) diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig index ba2b7de74d8..707713c6973 100644 --- a/src/cpu/intel/model_2065x/Kconfig +++ b/src/cpu/intel/model_2065x/Kconfig @@ -20,6 +20,7 @@ config CPU_SPECIFIC_OPTIONS select TSC_SYNC_MFENCE select CPU_INTEL_COMMON select NO_FIXED_XIP_ROM_SIZE + select PARALLEL_MP config BOOTBLOCK_CPU_INIT string diff --git a/src/cpu/intel/model_2065x/model_2065x.h b/src/cpu/intel/model_2065x/model_2065x.h index 1e6a3119100..904e794219f 100644 --- a/src/cpu/intel/model_2065x/model_2065x.h +++ b/src/cpu/intel/model_2065x/model_2065x.h @@ -20,6 +20,7 @@ /* Nehalem bus clock is fixed at 133MHz */ #define NEHALEM_BCLK 133 +#define CORE_THREAD_COUNT_MSR 0x35 #define MSR_FEATURE_CONFIG 0x13c #define MSR_FLEX_RATIO 0x194 #define FLEX_RATIO_LOCK (1 << 20) diff --git a/src/cpu/intel/model_2065x/model_2065x_init.c b/src/cpu/intel/model_2065x/model_2065x_init.c index f08a058a57e..d8de7c055f1 100644 --- a/src/cpu/intel/model_2065x/model_2065x_init.c +++ b/src/cpu/intel/model_2065x/model_2065x_init.c @@ -15,6 +15,7 @@ * GNU General Public License for more details. */ +#include #include #include #include @@ -22,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -109,29 +111,6 @@ static acpi_cstate_t cstate_map[] = { { 0 } }; -int cpu_get_apic_id_map(int *apic_id_map) -{ - int i; - struct cpuid_result result; - unsigned int threads_per_package, threads_per_core; - - /* Logical processors (threads) per core */ - result = cpuid_ext(0xb, 0); - threads_per_core = result.ebx & 0xffff; - - /* Logical processors (threads) per package */ - result = cpuid_ext(0xb, 1); - threads_per_package = result.ebx & 0xffff; - - for (i = 0; i < threads_per_package && i < CONFIG_MAX_CPUS; ++i) { - apic_id_map[i] = (i % threads_per_core) - + ((i / threads_per_core) << 2); - } - - return threads_per_package; -} - - int cpu_config_tdp_levels(void) { msr_t platform_info; @@ -250,58 +229,6 @@ static void configure_mca(void) wrmsr(IA32_MC0_STATUS + (i * 4), msr); } -/* - * Initialize any extra cores/threads in this package. - */ -static void intel_cores_init(struct device *cpu) -{ - struct cpuid_result result; - unsigned int threads_per_package, threads_per_core, i; - - /* Logical processors (threads) per core */ - result = cpuid_ext(0xb, 0); - threads_per_core = result.ebx & 0xffff; - - /* Logical processors (threads) per package */ - result = cpuid_ext(0xb, 1); - threads_per_package = result.ebx & 0xffff; - - /* Only initialize extra cores from BSP */ - if (cpu->path.apic.apic_id) - return; - - printk(BIOS_DEBUG, "CPU: %u has %u cores, %u threads per core\n", - cpu->path.apic.apic_id, threads_per_package/threads_per_core, - threads_per_core); - - for (i = 1; i < threads_per_package; ++i) { - struct device_path cpu_path; - struct device *new; - - /* Build the CPU device path */ - cpu_path.type = DEVICE_PATH_APIC; - cpu_path.apic.apic_id = - cpu->path.apic.apic_id + (i % threads_per_core) - + ((i / threads_per_core) << 2); - - /* Allocate the new CPU device structure */ - new = alloc_dev(cpu->bus, &cpu_path); - if (!new) - continue; - - printk(BIOS_DEBUG, "CPU: %u has core %u\n", - cpu->path.apic.apic_id, - new->path.apic.apic_id); - - /* Start the new CPU */ - if (is_smp_boot() && !start_cpu(new)) { - /* Record the error in cpu? */ - printk(BIOS_ERR, "CPU %u would not start!\n", - new->path.apic.apic_id); - } - } -} - static void model_2065x_init(struct device *cpu) { char processor_name[49]; @@ -309,8 +236,6 @@ static void model_2065x_init(struct device *cpu) /* Turn on caching if we haven't already */ x86_enable_cache(); - intel_update_microcode_from_cbfs(); - /* Clear out pending MCEs */ configure_mca(); @@ -320,10 +245,6 @@ static void model_2065x_init(struct device *cpu) printk(BIOS_INFO, "CPU:lapic=%ld, boot_cpu=%d\n", lapicid(), boot_cpu()); - /* Setup MTRRs based on physical address size */ - x86_setup_mtrrs_with_detect(); - x86_mtrr_check(); - /* Setup Page Attribute Tables (PAT) */ // TODO set up PAT @@ -348,9 +269,75 @@ static void model_2065x_init(struct device *cpu) /* Enable Turbo */ enable_turbo(); +} - /* Start up extra cores */ - intel_cores_init(cpu); +/* MP initialization support. */ +static const void *microcode_patch; + +static void pre_mp_init(void) +{ + /* Setup MTRRs based on physical address size. */ + x86_setup_mtrrs_with_detect(); + x86_mtrr_check(); +} + +static int get_cpu_count(void) +{ + msr_t msr; + int num_threads; + int num_cores; + + msr = rdmsr(CORE_THREAD_COUNT_MSR); + num_threads = (msr.lo >> 0) & 0xffff; + num_cores = (msr.lo >> 16) & 0xffff; + printk(BIOS_DEBUG, "CPU has %u cores, %u threads enabled.\n", + num_cores, num_threads); + + return num_threads; +} + +static void get_microcode_info(const void **microcode, int *parallel) +{ + microcode_patch = intel_microcode_find(); + *microcode = microcode_patch; + *parallel = 1; +} + +static void per_cpu_smm_trigger(void) +{ + /* Relocate the SMM handler. */ + smm_relocate(); + + /* After SMM relocation a 2nd microcode load is required. */ + intel_microcode_load_unlocked(microcode_patch); +} + +static void post_mp_init(void) +{ + /* Now that all APs have been relocated as well as the BSP let SMIs + * start flowing. */ + southbridge_smm_init(); + + /* Lock down the SMRAM space. */ + smm_lock(); +} + + +static const struct mp_ops mp_ops = { + .pre_mp_init = pre_mp_init, + .get_cpu_count = get_cpu_count, + .get_smm_info = smm_info, + .get_microcode_info = get_microcode_info, + .pre_mp_smm_init = smm_initialize, + .per_cpu_smm_trigger = per_cpu_smm_trigger, + .relocation_handler = smm_relocation_handler, + .post_mp_init = post_mp_init, +}; + +void bsp_init_and_start_aps(struct bus *cpu_bus) +{ + if (mp_init_with_smm(cpu_bus, &mp_ops)) + printk(BIOS_ERR, "MP initialization failure.\n"); } static struct device_operations cpu_dev_ops = { diff --git a/src/northbridge/intel/nehalem/northbridge.c b/src/northbridge/intel/nehalem/northbridge.c index a9032bafea2..233b0bbd00f 100644 --- a/src/northbridge/intel/nehalem/northbridge.c +++ b/src/northbridge/intel/nehalem/northbridge.c @@ -311,7 +311,7 @@ static const struct pci_driver mc_driver_44 __pci_driver = { static void cpu_bus_init(struct device *dev) { - initialize_cpus(dev->link_list); + bsp_init_and_start_aps(dev->link_list); } static struct device_operations cpu_bus_ops = { From 97c7c6bbb6c9dd2ef4f917c3c4c16a8ff0de5d9f Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 15 May 2018 16:45:21 +0200 Subject: [PATCH 447/588] cpu/intel/model_2065x: Put stage cache in TSEG TSEG is not accessible in ring 0 after it is locked in ramstage, in contrast with cbmem which remains accessible. Assuming SMM does not touch the cache this is a good region to cache stages. Change-Id: I89cbfb6ece62f554ac676fe686115e841d2c1e40 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/26298 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/cpu/intel/model_2065x/Kconfig | 5 ++++ src/cpu/intel/model_2065x/Makefile.inc | 4 +++ src/cpu/intel/model_2065x/model_2065x.h | 18 +++++++++++++ src/cpu/intel/model_2065x/stage_cache.c | 30 +++++++++++++++++++++ src/northbridge/intel/nehalem/northbridge.c | 7 ----- src/northbridge/intel/nehalem/ram_calc.c | 6 +++++ 6 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 src/cpu/intel/model_2065x/stage_cache.c diff --git a/src/cpu/intel/model_2065x/Kconfig b/src/cpu/intel/model_2065x/Kconfig index 707713c6973..d8c016867cb 100644 --- a/src/cpu/intel/model_2065x/Kconfig +++ b/src/cpu/intel/model_2065x/Kconfig @@ -21,6 +21,7 @@ config CPU_SPECIFIC_OPTIONS select CPU_INTEL_COMMON select NO_FIXED_XIP_ROM_SIZE select PARALLEL_MP + select CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM config BOOTBLOCK_CPU_INIT string @@ -30,4 +31,8 @@ config SMM_TSEG_SIZE hex default 0x800000 +config SMM_RESERVED_SIZE + hex + default 0x100000 + endif diff --git a/src/cpu/intel/model_2065x/Makefile.inc b/src/cpu/intel/model_2065x/Makefile.inc index 043141ac188..39246c07082 100644 --- a/src/cpu/intel/model_2065x/Makefile.inc +++ b/src/cpu/intel/model_2065x/Makefile.inc @@ -19,6 +19,10 @@ ramstage-y += acpi.c smm-$(CONFIG_HAVE_SMI_HANDLER) += finalize.c +romstage-y += stage_cache.c +ramstage-y += stage_cache.c +postcar-y += stage_cache.c + cpu_microcode_bins += 3rdparty/blobs/cpu/intel/model_2065x/microcode.bin cpu_incs-y += $(src)/cpu/intel/car/non-evict/cache_as_ram.S diff --git a/src/cpu/intel/model_2065x/model_2065x.h b/src/cpu/intel/model_2065x/model_2065x.h index 904e794219f..e7ba2a771b4 100644 --- a/src/cpu/intel/model_2065x/model_2065x.h +++ b/src/cpu/intel/model_2065x/model_2065x.h @@ -80,4 +80,22 @@ void set_power_limits(u8 power_limit_1_time); int cpu_config_tdp_levels(void); #endif +/* + * Region of SMM space is reserved for multipurpose use. It falls below + * the IED region and above the SMM handler. + */ +#define RESERVED_SMM_SIZE CONFIG_SMM_RESERVED_SIZE +#define RESERVED_SMM_OFFSET (CONFIG_SMM_TSEG_SIZE - RESERVED_SMM_SIZE) + +/* Sanity check config options. */ +#if (CONFIG_SMM_TSEG_SIZE <= RESERVED_SMM_SIZE) +# error "CONFIG_SMM_TSEG_SIZE <= RESERVED_SMM_SIZE" +#endif +#if (CONFIG_SMM_TSEG_SIZE < 0x800000) +# error "CONFIG_SMM_TSEG_SIZE must at least be 8MiB" +#endif +#if ((CONFIG_SMM_TSEG_SIZE & (CONFIG_SMM_TSEG_SIZE - 1)) != 0) +# error "CONFIG_SMM_TSEG_SIZE is not a power of 2" +#endif + #endif diff --git a/src/cpu/intel/model_2065x/stage_cache.c b/src/cpu/intel/model_2065x/stage_cache.c new file mode 100644 index 00000000000..ab8ac979c16 --- /dev/null +++ b/src/cpu/intel/model_2065x/stage_cache.c @@ -0,0 +1,30 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google, Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "model_2065x.h" + +void stage_cache_external_region(void **base, size_t *size) +{ + /* + * The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET. + * The top of RAM is defined to be the TSEG base address. + */ + *size = RESERVED_SMM_SIZE; + *base = (void *)((uintptr_t)northbridge_get_tseg_base() + + RESERVED_SMM_OFFSET); +} diff --git a/src/northbridge/intel/nehalem/northbridge.c b/src/northbridge/intel/nehalem/northbridge.c index 233b0bbd00f..485cb27f459 100644 --- a/src/northbridge/intel/nehalem/northbridge.c +++ b/src/northbridge/intel/nehalem/northbridge.c @@ -171,13 +171,6 @@ static void mc_read_resources(struct device *dev) add_fixed_resources(dev, 10); } -u32 northbridge_get_tseg_base(void) -{ - struct device *dev = pcidev_on_root(0, 0); - - return pci_read_config32(dev, TSEG) & ~1; -} - u32 northbridge_get_tseg_size(void) { return CONFIG_SMM_TSEG_SIZE; diff --git a/src/northbridge/intel/nehalem/ram_calc.c b/src/northbridge/intel/nehalem/ram_calc.c index 163f21ce3cd..ca821da2dcd 100644 --- a/src/northbridge/intel/nehalem/ram_calc.c +++ b/src/northbridge/intel/nehalem/ram_calc.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "nehalem.h" static uintptr_t smm_region_start(void) @@ -32,6 +33,11 @@ static uintptr_t smm_region_start(void) return tom; } +u32 northbridge_get_tseg_base(void) +{ + return (u32)smm_region_start & ~1; +} + void *cbmem_top(void) { return (void *) smm_region_start(); From 81e9b8ee67fe4f395e999200333a5214d1bf3789 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 3 Dec 2018 11:51:17 +0100 Subject: [PATCH 448/588] sb/intel/common/smi.c: Remove unused functions Since all targets using sb/intel/common and cpu/intel/smm/gen1 are now using PARALLEL_MP, some code is not used anymore. Change-Id: Ibdc2bb0f1412366b945813efbc1b6451d27f376f Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30019 Reviewed-by: Paul Menzel Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/cpu/intel/smm/gen1/smi.h | 3 - src/cpu/intel/smm/gen1/smmrelocate.c | 169 --------------------------- src/southbridge/intel/common/smi.c | 32 ----- 3 files changed, 204 deletions(-) diff --git a/src/cpu/intel/smm/gen1/smi.h b/src/cpu/intel/smm/gen1/smi.h index 6d08bb36844..05c507c09c2 100644 --- a/src/cpu/intel/smm/gen1/smi.h +++ b/src/cpu/intel/smm/gen1/smi.h @@ -17,11 +17,8 @@ void bsp_init_and_start_aps(struct bus *cpu_bus); /* These helpers are for performing SMM relocation. */ void southbridge_smm_init(void); -void southbridge_trigger_smi(void); -void southbridge_clear_smi_status(void); u32 northbridge_get_tseg_base(void); u32 northbridge_get_tseg_size(void); -int cpu_get_apic_id_map(int *apic_id_map); void northbridge_write_smram(u8 smram); bool cpu_has_alternative_smrr(void); diff --git a/src/cpu/intel/smm/gen1/smmrelocate.c b/src/cpu/intel/smm/gen1/smmrelocate.c index cc2a8952ca7..f3192bcd554 100644 --- a/src/cpu/intel/smm/gen1/smmrelocate.c +++ b/src/cpu/intel/smm/gen1/smmrelocate.c @@ -100,60 +100,6 @@ static void write_smrr(struct smm_relocation_params *relo_params) } } -/* The relocation work is actually performed in SMM context, but the code - * resides in the ramstage module. This occurs by trampolining from the default - * SMRAM entry point to here. */ -static void asmlinkage cpu_smm_do_relocation(void *arg) -{ - em64t101_smm_state_save_area_t *save_state; - msr_t mtrr_cap; - struct smm_relocation_params *relo_params; - const struct smm_module_params *p; - const struct smm_runtime *runtime; - int cpu; - - p = arg; - runtime = p->runtime; - relo_params = p->arg; - cpu = p->cpu; - - if (cpu >= CONFIG_MAX_CPUS) { - printk(BIOS_CRIT, - "Invalid CPU number assigned in SMM stub: %d\n", cpu); - return; - } - - printk(BIOS_DEBUG, "In relocation handler: cpu %d\n", cpu); - - /* All threads need to set IEDBASE and SMBASE in the save state area. - * Since one thread runs at a time during the relocation the save state - * is the same for all cpus. */ - save_state = (void *)(runtime->smbase + SMM_DEFAULT_SIZE - - runtime->save_state_size); - - /* The relocated handler runs with all CPUs concurrently. Therefore - * stagger the entry points adjusting SMBASE downwards by save state - * size * CPU num. */ - save_state->smbase = relo_params->smram_base - - cpu * runtime->save_state_size; - if (CONFIG_IED_REGION_SIZE != 0) { - save_state->iedbase = relo_params->ied_base; - - printk(BIOS_DEBUG, "New SMBASE=0x%08x IEDBASE=0x%08x @ %p\n", - save_state->smbase, save_state->iedbase, save_state); - } else { - printk(BIOS_DEBUG, "New SMBASE=0x%08x @ %p\n", - save_state->smbase, save_state); - } - - /* Write SMRR MSRs based on indicated support. */ - mtrr_cap = rdmsr(MTRR_CAP_MSR); - if (mtrr_cap.lo & SMRR_SUPPORTED && relo_params->smrr_mask.lo != 0) - write_smrr(relo_params); - - southbridge_clear_smi_status(); -} - static void fill_in_relocation_params(struct smm_relocation_params *params) { /* All range registers are aligned to 4KiB */ @@ -202,33 +148,6 @@ static void fill_in_relocation_params(struct smm_relocation_params *params) } } -static int install_relocation_handler(int *apic_id_map, int num_cpus, - struct smm_relocation_params *relo_params) -{ - /* The default SMM entry happens serially at the default location. - * Therefore, there is only 1 concurrent save state area. Set the - * stack size to the save state size, and call into the - * do_relocation handler. */ - int save_state_size = sizeof(em64t101_smm_state_save_area_t); - struct smm_loader_params smm_params = { - .per_cpu_stack_size = save_state_size, - .num_concurrent_stacks = num_cpus, - .per_cpu_save_state_size = save_state_size, - .num_concurrent_save_states = 1, - .handler = &cpu_smm_do_relocation, - .handler_arg = (void *)relo_params, - }; - - default_smm_area = backup_default_smm_area(); - - if (smm_setup_relocation_handler(&smm_params)) - return -1; - int i; - for (i = 0; i < num_cpus; i++) - smm_params.runtime->apic_id_to_cpu[i] = apic_id_map[i]; - return 0; -} - static void setup_ied_area(struct smm_relocation_params *params) { char *ied_base; @@ -248,94 +167,6 @@ static void setup_ied_area(struct smm_relocation_params *params) memset(ied_base + (1 << 20), 0, (32 << 10)); } -static int install_permanent_handler(int *apic_id_map, int num_cpus, - struct smm_relocation_params *relo_params) -{ - /* There are num_cpus concurrent stacks and num_cpus concurrent save - * state areas. Lastly, set the stack size to the save state size. */ - int save_state_size = sizeof(em64t101_smm_state_save_area_t); - struct smm_loader_params smm_params = { - .per_cpu_stack_size = save_state_size, - .num_concurrent_stacks = num_cpus, - .per_cpu_save_state_size = save_state_size, - .num_concurrent_save_states = num_cpus, - }; - - printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n", - relo_params->smram_base); - if (smm_load_module((void *)relo_params->smram_base, - relo_params->smram_size, &smm_params)) - return -1; - int i; - for (i = 0; i < num_cpus; i++) - smm_params.runtime->apic_id_to_cpu[i] = apic_id_map[i]; - return 0; -} - -static int cpu_smm_setup(void) -{ - int num_cpus; - int apic_id_map[CONFIG_MAX_CPUS]; - - printk(BIOS_DEBUG, "Setting up SMI for CPU\n"); - - fill_in_relocation_params(&smm_reloc_params); - - /* enable the SMM memory window */ - northbridge_write_smram(D_OPEN | G_SMRAME | C_BASE_SEG); - - if (CONFIG_IED_REGION_SIZE != 0) - setup_ied_area(&smm_reloc_params); - - num_cpus = cpu_get_apic_id_map(apic_id_map); - if (num_cpus > CONFIG_MAX_CPUS) { - printk(BIOS_CRIT, - "Error: Hardware CPUs (%d) > MAX_CPUS (%d)\n", - num_cpus, CONFIG_MAX_CPUS); - } - - if (install_relocation_handler(apic_id_map, num_cpus, - &smm_reloc_params)) { - printk(BIOS_CRIT, "SMM Relocation handler install failed.\n"); - return -1; - } - - if (install_permanent_handler(apic_id_map, num_cpus, - &smm_reloc_params)) { - printk(BIOS_CRIT, "SMM Permanent handler install failed.\n"); - return -1; - } - - /* Ensure the SMM handlers hit DRAM before performing first SMI. */ - /* TODO(adurbin): Is this really needed? */ - wbinvd(); - - /* close the SMM memory window and enable normal SMM */ - northbridge_write_smram(G_SMRAME | C_BASE_SEG); - - return 0; -} - -void smm_init(void) -{ - /* Return early if CPU SMM setup failed. */ - if (cpu_smm_setup()) - return; - - southbridge_smm_init(); - - /* Initiate first SMI to kick off SMM-context relocation. Note: this - * SMI being triggered here queues up an SMI in the APs which are in - * wait-for-SIPI state. Once an AP gets an SIPI it will service the SMI - * at the SMM_DEFAULT_BASE before jumping to startup vector. */ - southbridge_trigger_smi(); - - printk(BIOS_DEBUG, "Relocation complete.\n"); - - /* Lock down the SMRAM space. */ - smm_lock(); -} - void smm_init_completion(void) { restore_default_smm_area(default_smm_area); diff --git a/src/southbridge/intel/common/smi.c b/src/southbridge/intel/common/smi.c index 036ac22adc4..398c6804e02 100644 --- a/src/southbridge/intel/common/smi.c +++ b/src/southbridge/intel/common/smi.c @@ -104,38 +104,6 @@ void southbridge_smm_init(void) write_pmbase32(SMI_EN, smi_en); } -void southbridge_trigger_smi(void) -{ - /** - * There are several methods of raising a controlled SMI# via - * software, among them: - * - Writes to io 0xb2 (APMC) - * - Writes to the Local Apic ICR with Delivery mode SMI. - * - * Using the local apic is a bit more tricky. According to - * AMD Family 11 Processor BKDG no destination shorthand must be - * used. - * The whole SMM initialization is quite a bit hardware specific, so - * I'm not too worried about the better of the methods at the moment - */ - - /* raise an SMI interrupt */ - printk(BIOS_SPEW, " ... raise SMI#\n"); - outb(0x00, 0xb2); -} - -void southbridge_clear_smi_status(void) -{ - /* Clear SMI status */ - reset_smi_status(); - - /* Clear PM1 status */ - reset_pm1_status(); - - /* Set EOS bit so other SMIs can occur. */ - smi_set_eos(); -} - void smm_setup_structures(void *gnvs, void *tcg, void *smi1) { /* From d8f56a9b2999a3216aea7e219566af8d62bd53e1 Mon Sep 17 00:00:00 2001 From: Casper Chang Date: Fri, 24 May 2019 22:03:35 +0800 Subject: [PATCH 449/588] mb/google/sarien: Modify arcada touchscreen reset delay Modify reset delay to 20ms of touchscreen to address i2c hid driver rebind failed issue after auto update of touchscreen firmware BUG=b:132211627 TEST=Touchscreen works after auto update and no re-bind driver failed issue Signed-off-by: Casper Chang Change-Id: If17afbd160a2c97beb69d0cb50e4a7dc654775f5 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32988 Tested-by: build bot (Jenkins) Reviewed-by: Nick Crews Reviewed-by: Duncan Laurie --- src/mainboard/google/sarien/variants/arcada/devicetree.cb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/google/sarien/variants/arcada/devicetree.cb b/src/mainboard/google/sarien/variants/arcada/devicetree.cb index d3848a24b08..767df1f7959 100644 --- a/src/mainboard/google/sarien/variants/arcada/devicetree.cb +++ b/src/mainboard/google/sarien/variants/arcada/devicetree.cb @@ -315,7 +315,7 @@ chip soc/intel/cannonlake register "generic.irq" = "ACPI_IRQ_LEVEL_LOW(GPP_C23_IRQ)" register "generic.probed" = "1" register "generic.reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_E7)" - register "generic.reset_delay_ms" = "10" + register "generic.reset_delay_ms" = "20" register "generic.enable_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_HIGH(GPP_B21)" register "generic.enable_delay_ms" = "55" register "generic.has_power_resource" = "1" From 07db5fcec10b825d7d3660c492abb66f2e802405 Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Thu, 23 May 2019 15:42:34 +0200 Subject: [PATCH 450/588] src/include/device/pci_ids.h: Add Kabylake C236 Device Change-Id: Ib11981543575311a32896df385d44cf30aa9387f Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32964 Reviewed-by: Philipp Deppenwiese Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/include/device/pci_ids.h | 1 + src/soc/intel/common/block/lpc/lpc.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index 553deafc8b7..3c48e685dea 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -2694,6 +2694,7 @@ #define PCI_DEVICE_ID_INTEL_SPT_H_Q170 0xa146 #define PCI_DEVICE_ID_INTEL_SPT_H_Q150 0xa147 #define PCI_DEVICE_ID_INTEL_SPT_H_B150 0xa148 +#define PCI_DEVICE_ID_INTEL_KBP_H_C236 0xa149 #define PCI_DEVICE_ID_INTEL_SPT_H_C236 0xa150 #define PCI_DEVICE_ID_INTEL_SPT_H_PREMIUM 0xa14e #define PCI_DEVICE_ID_INTEL_SPT_H_H110 0xa143 diff --git a/src/soc/intel/common/block/lpc/lpc.c b/src/soc/intel/common/block/lpc/lpc.c index 43b3522431e..86547a443fc 100644 --- a/src/soc/intel/common/block/lpc/lpc.c +++ b/src/soc/intel/common/block/lpc/lpc.c @@ -125,6 +125,7 @@ static const unsigned short pci_device_ids[] = { PCI_DEVICE_ID_INTEL_SPT_LP_U_PREMIUM, PCI_DEVICE_ID_INTEL_SPT_LP_Y_PREMIUM, PCI_DEVICE_ID_INTEL_SPT_H_C236, + PCI_DEVICE_ID_INTEL_KBP_H_C236, PCI_DEVICE_ID_INTEL_SPT_H_PREMIUM, PCI_DEVICE_ID_INTEL_SPT_H_H110, PCI_DEVICE_ID_INTEL_SPT_H_H170, From 3b4d0e060cd4d3384cba18404c0c309cf94f508e Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Fri, 24 May 2019 15:17:06 +0200 Subject: [PATCH 451/588] src/cpu/x86/lapic/lapic.c: Add missing newline Added missing new line to Info Output. Change-Id: Ic4cd63f231de918fad7cd34724651bf8eb1c8e62 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32987 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans Reviewed-by: Angel Pons --- src/cpu/x86/lapic/lapic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/x86/lapic/lapic.c b/src/cpu/x86/lapic/lapic.c index 8cd3092b247..755fbe220d7 100644 --- a/src/cpu/x86/lapic/lapic.c +++ b/src/cpu/x86/lapic/lapic.c @@ -24,7 +24,7 @@ void do_lapic_init(void) * see the Intel mp1.4 spec, page A-3 */ - printk(BIOS_INFO, "Setting up local APIC..."); + printk(BIOS_INFO, "Setting up local APIC...\n"); /* Enable the local APIC */ enable_lapic(); From 9e5b06297d8f5d86d33ced80f371d52ef4c12334 Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Tue, 21 May 2019 17:37:58 +0200 Subject: [PATCH 452/588] src/arch/x86: Add automatic type41 entry creation SMBIOS Type41 Entries will be automatically created. Type 41 entries define attributes of the onboard devices. Change-Id: Idcb3532a5c05666d6613af4f303df85f4f1f6e97 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32910 Reviewed-by: Philipp Deppenwiese Reviewed-by: Patrick Rudolph Tested-by: build bot (Jenkins) --- src/arch/x86/smbios.c | 71 ++++++++++++++++++++++++++++++++++++ src/include/device/pci_ids.h | 2 + src/include/smbios.h | 2 + 3 files changed, 75 insertions(+) diff --git a/src/arch/x86/smbios.c b/src/arch/x86/smbios.c index 310a870da66..bf627f280fd 100644 --- a/src/arch/x86/smbios.c +++ b/src/arch/x86/smbios.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #if CONFIG(CHROMEOS) #include #endif @@ -50,6 +53,41 @@ static u8 smbios_checksum(u8 *p, u32 length) return -ret; } +/* Get the device type 41 from the dev struct */ +static u8 smbios_get_device_type_from_dev(struct device *dev) +{ + u16 pci_basesubclass = (dev->class >> 8) & 0xFFFF; + + switch (pci_basesubclass) { + case PCI_CLASS_NOT_DEFINED: + return SMBIOS_DEVICE_TYPE_OTHER; + case PCI_CLASS_DISPLAY_VGA: + case PCI_CLASS_DISPLAY_XGA: + case PCI_CLASS_DISPLAY_3D: + case PCI_CLASS_DISPLAY_OTHER: + return SMBIOS_DEVICE_TYPE_VIDEO; + case PCI_CLASS_STORAGE_SCSI: + return SMBIOS_DEVICE_TYPE_SCSI; + case PCI_CLASS_NETWORK_ETHERNET: + return SMBIOS_DEVICE_TYPE_ETHERNET; + case PCI_CLASS_NETWORK_TOKEN_RING: + return SMBIOS_DEVICE_TYPE_TOKEN_RING; + case PCI_CLASS_MULTIMEDIA_VIDEO: + case PCI_CLASS_MULTIMEDIA_AUDIO: + case PCI_CLASS_MULTIMEDIA_PHONE: + case PCI_CLASS_MULTIMEDIA_OTHER: + return SMBIOS_DEVICE_TYPE_SOUND; + case PCI_CLASS_STORAGE_ATA: + return SMBIOS_DEVICE_TYPE_PATA; + case PCI_CLASS_STORAGE_SATA: + return SMBIOS_DEVICE_TYPE_SATA; + case PCI_CLASS_STORAGE_SAS: + return SMBIOS_DEVICE_TYPE_SAS; + default: + return SMBIOS_DEVICE_TYPE_UNKNOWN; + } +} + int smbios_add_string(u8 *start, const char *str) { @@ -999,6 +1037,38 @@ static int smbios_write_type127(unsigned long *current, int handle) return len; } +/* Generate Type41 entries from devicetree */ +static int smbios_walk_device_tree_type41(struct device *dev, int *handle, + unsigned long *current) +{ + static u8 type41_inst_cnt[SMBIOS_DEVICE_TYPE_COUNT + 1] = {}; + + if (dev->path.type != DEVICE_PATH_PCI) + return 0; + if (!dev->on_mainboard) + return 0; + + u8 device_type = smbios_get_device_type_from_dev(dev); + + if (device_type == SMBIOS_DEVICE_TYPE_OTHER || + device_type == SMBIOS_DEVICE_TYPE_UNKNOWN) + return 0; + + if (device_type > SMBIOS_DEVICE_TYPE_COUNT) + return 0; + + const char *name = get_pci_subclass_name(dev); + + return smbios_write_type41(current, handle, + name, // name + type41_inst_cnt[device_type]++, // inst + 0, // segment + dev->bus->secondary, //bus + PCI_SLOT(dev->path.pci.devfn), // device + PCI_FUNC(dev->path.pci.devfn), // func + device_type); +} + /* Generate Type9 entries from devicetree */ static int smbios_walk_device_tree_type9(struct device *dev, int *handle, unsigned long *current) @@ -1062,6 +1132,7 @@ static int smbios_walk_device_tree(struct device *tree, int *handle, len += dev->ops->get_smbios_data(dev, handle, current); } len += smbios_walk_device_tree_type9(dev, handle, current); + len += smbios_walk_device_tree_type41(dev, handle, current); } return len; } diff --git a/src/include/device/pci_ids.h b/src/include/device/pci_ids.h index 3c48e685dea..a35e134dc99 100644 --- a/src/include/device/pci_ids.h +++ b/src/include/device/pci_ids.h @@ -18,7 +18,9 @@ #define PCI_CLASS_STORAGE_FLOPPY 0x0102 #define PCI_CLASS_STORAGE_IPI 0x0103 #define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_ATA 0x0105 #define PCI_CLASS_STORAGE_SATA 0x0106 +#define PCI_CLASS_STORAGE_SAS 0x0107 #define PCI_CLASS_STORAGE_OTHER 0x0180 #define PCI_BASE_CLASS_NETWORK 0x02 diff --git a/src/include/smbios.h b/src/include/smbios.h index 017e90e7420..0bba0a7f9e4 100644 --- a/src/include/smbios.h +++ b/src/include/smbios.h @@ -756,6 +756,8 @@ typedef enum { SMBIOS_DEVICE_TYPE_SAS, } smbios_onboard_device_type; +#define SMBIOS_DEVICE_TYPE_COUNT 10 + struct smbios_type41 { u8 type; u8 length; From 63cba976b19fb5bc3b52f8448240bece9bafb28e Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Thu, 23 May 2019 15:31:40 +0800 Subject: [PATCH 453/588] mb/google/sarien: Fix SSD power leakage in S5 Turn off SSD power in S5. BUG=b:133389422 TEST=measure H13 is low in S5 Signed-off-by: Eric Lai Change-Id: I40b5381cac33b0eac962a7730ee5c57e60e6d375 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32952 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- .../variants/arcada/include/variant/acpi/mainboard.asl | 8 ++++++++ .../variants/sarien/include/variant/acpi/mainboard.asl | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl index 41121d28fe0..6eba2bcb21d 100644 --- a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl @@ -15,6 +15,8 @@ #define CAM_EN GPP_B11 /* Active low */ #define TS_PD GPP_E7 +#define SSD_EN GPP_H13 +#define SSD_RST GPP_H12 /* Method called from LPIT prior to enter s0ix state */ Method (MS0X, 1) @@ -35,6 +37,12 @@ Method (MPTS, 1) /* Clear touch screen pd pin to avoid leakage */ \_SB.PCI0.CTXS (TS_PD) + + /* Clear SSD EN adn RST pin to avoid leakage */ + If (Arg0 == 5) { + \_SB.PCI0.CTXS (SSD_EN) + \_SB.PCI0.CTXS (SSD_RST) + } } /* Method called from _WAK prior to wakeup */ diff --git a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl index 41121d28fe0..6eba2bcb21d 100644 --- a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl @@ -15,6 +15,8 @@ #define CAM_EN GPP_B11 /* Active low */ #define TS_PD GPP_E7 +#define SSD_EN GPP_H13 +#define SSD_RST GPP_H12 /* Method called from LPIT prior to enter s0ix state */ Method (MS0X, 1) @@ -35,6 +37,12 @@ Method (MPTS, 1) /* Clear touch screen pd pin to avoid leakage */ \_SB.PCI0.CTXS (TS_PD) + + /* Clear SSD EN adn RST pin to avoid leakage */ + If (Arg0 == 5) { + \_SB.PCI0.CTXS (SSD_EN) + \_SB.PCI0.CTXS (SSD_RST) + } } /* Method called from _WAK prior to wakeup */ From 48b2adae1c3ba0c23630f912fd7f7c87f0a7528c Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Tue, 28 May 2019 13:49:44 +0800 Subject: [PATCH 454/588] mb/google/sarien: Modify SSD power sequence Due to we turn off SSD power in S5. CB:32952 Based on M2 spec we have to turn on SSD power before RST assert. BUG=b:133389422 TEST=verify warm boot and cold boot are boot successfully. Signed-off-by: Eric Lai Change-Id: I5b78bab4be675bbb8795361bcfa5af52cb54bb1e Reviewed-on: https://review.coreboot.org/c/coreboot/+/33029 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/mainboard/google/sarien/variants/arcada/gpio.c | 2 +- src/mainboard/google/sarien/variants/sarien/gpio.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/gpio.c b/src/mainboard/google/sarien/variants/arcada/gpio.c index ea0601b55ec..ff0240c991a 100644 --- a/src/mainboard/google/sarien/variants/arcada/gpio.c +++ b/src/mainboard/google/sarien/variants/arcada/gpio.c @@ -211,7 +211,6 @@ static const struct pad_config gpio_table[] = { /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* I2C5_SDA */ PAD_NC(GPP_H10, NONE), /* ISH_I2C2_SDA */ /* I2C5_SCL */ PAD_NC(GPP_H11, NONE), /* ISH_I2C2_SCL */ -/* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* M2_SKT2_CFG2 */ PAD_NC(GPP_H14, NONE), /* M2_SKT2_CFG3 */ PAD_CFG_GPO(GPP_H15, 1, DEEP), /* BT_RADIO_DIS# */ /* DDPF_CTRLCLK */ PAD_NC(GPP_H16, NONE), @@ -239,6 +238,7 @@ static const struct pad_config gpio_table[] = { /* Early pad configuration in bootblock */ static const struct pad_config early_gpio_table[] = { +/* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* SSD RESET pin will stay low first */ /* M2_SKT2_CFG0 */ PAD_CFG_GPO(GPP_H12, 0, DEEP), /* D3 cold RST */ /* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* SERVOTX_UART */ diff --git a/src/mainboard/google/sarien/variants/sarien/gpio.c b/src/mainboard/google/sarien/variants/sarien/gpio.c index ec3b44d4a38..78db12e8a1e 100644 --- a/src/mainboard/google/sarien/variants/sarien/gpio.c +++ b/src/mainboard/google/sarien/variants/sarien/gpio.c @@ -197,7 +197,6 @@ static const struct pad_config gpio_table[] = { /* I2C4_SCL */ PAD_CFG_NF(GPP_H9, NONE, DEEP, NF1), /* I2C_SCL_H1 */ /* I2C5_SDA */ PAD_NC(GPP_H10, NONE), /* I2C5_SCL */ PAD_NC(GPP_H11, NONE), -/* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* M2_SKT2_CFG2 */ PAD_NC(GPP_H14, NONE), /* M2_SKT2_CFG3 */ PAD_CFG_GPO(GPP_H15, 1, DEEP), /* BT_RADIO_DIS# */ /* DDPF_CTRLCLK */ PAD_NC(GPP_H16, NONE), @@ -224,6 +223,7 @@ static const struct pad_config gpio_table[] = { /* Early pad configuration in bootblock */ static const struct pad_config early_gpio_table[] = { +/* M2_SKT2_CFG1 */ PAD_CFG_GPO(GPP_H13, 1, DEEP), /* M.2 SSD D3 cold */ /* SUSWARN# */ PAD_CFG_GPO(GPP_A13, 0, DEEP), /* Card reader D3 cold */ /* SUSACK# */ PAD_CFG_GPO(GPP_A15, 0, DEEP), /* Card reader D3 cold */ /* UART2_RXD */ PAD_CFG_NF(GPP_C20, NONE, DEEP, NF1), /* SERVOTX_UART */ From 9637856b533ee6eaa7cd3e1c1b2ec4d816f58dff Mon Sep 17 00:00:00 2001 From: Bora Guvendik Date: Fri, 24 May 2019 14:41:31 -0700 Subject: [PATCH 455/588] soc/intel/cannonlake: Dump ME status info before notify EndOfFirmware Dumping ME status displays wrong information if we disable Heci1 because it is called after fsp notifies EndOfFirmware and disables Heci1. This patch moves the ME status dump before fsp notify EndOfFirmware. TEST=Boot to OS, check ME dump information Change-Id: Ifd8b18a41c502c4ecfb84698a7669028394589fd Signed-off-by: Bora Guvendik Reviewed-on: https://review.coreboot.org/c/coreboot/+/32991 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Furquan Shaikh Reviewed-by: Tim Wawrzynczak --- src/soc/intel/cannonlake/finalize.c | 3 --- src/soc/intel/cannonlake/include/soc/me.h | 2 +- src/soc/intel/cannonlake/me.c | 5 ++++- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c index eb4c5c2c9d4..4dfd15bc4a6 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -95,8 +94,6 @@ static void soc_finalize(void *unused) { printk(BIOS_DEBUG, "Finalizing chipset.\n"); - dump_me_status(); - pch_finalize(); printk(BIOS_DEBUG, "Finalizing SMM.\n"); diff --git a/src/soc/intel/cannonlake/include/soc/me.h b/src/soc/intel/cannonlake/include/soc/me.h index 1d782c153c8..5b411d36210 100644 --- a/src/soc/intel/cannonlake/include/soc/me.h +++ b/src/soc/intel/cannonlake/include/soc/me.h @@ -16,6 +16,6 @@ #ifndef _CANNONLAKE_ME_H_ #define _CANNONLAKE_ME_H_ -void dump_me_status(void); +void dump_me_status(void *unused); #endif /* _CANNONLAKE_ME_H_ */ diff --git a/src/soc/intel/cannonlake/me.c b/src/soc/intel/cannonlake/me.c index 3fedc6374e8..c9748b73438 100644 --- a/src/soc/intel/cannonlake/me.c +++ b/src/soc/intel/cannonlake/me.c @@ -235,7 +235,7 @@ static void print_me_version(void *unused) } BOOT_STATE_INIT_ENTRY(BS_DEV_ENABLE, BS_ON_EXIT, print_me_version, NULL); -void dump_me_status(void) +void dump_me_status(void *unused) { union hfsts1 hfsts1; union hfsts2 hfsts2; @@ -297,3 +297,6 @@ void dump_me_status(void) printk(BIOS_DEBUG, "ME: TXT Support : %s\n", hfsts6.fields.txt_support ? "YES" : "NO"); } + +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_ENTRY, dump_me_status, NULL); +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME_CHECK, BS_ON_EXIT, dump_me_status, NULL); From 1470c7367b8fca24c86c8912aa65e969e63ff521 Mon Sep 17 00:00:00 2001 From: Alan Green Date: Wed, 22 May 2019 11:12:44 +1000 Subject: [PATCH 456/588] util/xcompile/xcompile: apply -march to clang as well as gcc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For x64 and x86_32 configurations, apply the -march flag to both GCC and Clang flags. This solves the problem of Clang-compiled coreboot failing due to Clang emitting SSE instructions for code that is executed while SSE is not enabled. This patch takes functionality targeted for GCC configurations and moves it down a few lines, modifying CFLAGS instead of GCC_CFLAGS in order that it applies to both GCC and Clang. This is an alternate patch to CB:32887. Signed-off-by: Alan Green Change-Id: I6a6a6136b01a64d46f730ed19ebbeaadaf2183df Reviewed-on: https://review.coreboot.org/c/coreboot/+/32923 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki --- util/xcompile/xcompile | 51 +++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 4a29cdd647e..40356d93d9e 100755 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -227,6 +227,29 @@ GCC_CC_${TARCH}:=${GCC} GCC_CFLAGS_${TARCH}:=${CFLAGS_GCC} GCC_COMPILER_RT_${TARCH}:=${CC_RT_GCC} GCC_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_GCC} + +# Clang +CLANG_CC_${TARCH}:=${CLANG} +CLANG_CFLAGS_${TARCH}:=${CFLAGS_CLANG} +CLANG_CFLAGS_${TARCH}+=-Qunused-arguments -m${TWIDTH} +# tone down clang compiler warnings +CLANG_CFLAGS_${TARCH}+=-Wno-unused-variable -Wno-unused-function -Wno-tautological-compare +CLANG_CFLAGS_${TARCH}+=-Wno-shift-overflow -Wno-address-of-packed-member -Wno-initializer-overrides +CLANG_COMPILER_RT_${TARCH}:=${CC_RT_CLANG} +CLANG_COMPILER_RT_FLAGS_${TARCH}:=${CC_RT_EXTRA_CLANG} + +# GCC/Clang Common +ifeq (\$(CONFIG_COMPILER_GCC)\$(CONFIG_LP_COMPILER_GCC),y) + CC_${TARCH}:=\$(GCC_CC_${TARCH}) + CFLAGS_${TARCH}:=\$(GCC_CFLAGS_${TARCH}) + COMPILER_RT_${TARCH}:=\$(GCC_COMPILER_RT_${TARCH}) + COMPILER_RT_FLAGS_${TARCH}:=\$(GCC_COMPILER_RT_FLAGS_${TARCH}) +else + CC_${TARCH}:=\$(CLANG_CC_${TARCH}) + CFLAGS_${TARCH}:=\$(CLANG_CFLAGS_${TARCH}) + COMPILER_RT_${TARCH}:=\$(CLANG_COMPILER_RT_${TARCH}) + COMPILER_RT_FLAGS_${TARCH}:=\$(CLANG_COMPILER_RT_FLAGS_${TARCH}) +endif EOF # Generally the x86 should build for i686 -- no sse/mmx @@ -238,7 +261,7 @@ EOF # to use i586 instead. if [ "${TARCH}" = "x86_64" ]; then cat < Date: Wed, 29 May 2019 13:59:14 +0530 Subject: [PATCH 457/588] drivers/intel/fsp2_0: Fix typo mistake Change-Id: I90f595d7d789429c8717261c6edb6c756f6c0e1f Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/33056 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: Aamir Bohra --- src/drivers/intel/fsp2_0/silicon_init.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index e9c29db40e6..302bc0f3ade 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -72,7 +72,7 @@ static void do_silicon_init(struct fsp_header *hdr) } printk(BIOS_SPEW, "FspSiliconInit returned 0x%08x\n", status); die_with_post_code(postcode, - "FspSiliconINit returned an error!\n"); + "FspSiliconInit returned an error!\n"); } } From 23fbd052b90be2e9a6c3858bb9b314069e70ea6d Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 28 May 2019 17:38:17 +0200 Subject: [PATCH 458/588] nb/intel/nehalem: Call smm_region_start() function This also removes the unnecessary mask. TEST: X201 Boots again. Change-Id: Ia637bd01cd7dc1aecd1a87a739d5243c70419553 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33046 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Nico Huber --- src/northbridge/intel/nehalem/ram_calc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/nehalem/ram_calc.c b/src/northbridge/intel/nehalem/ram_calc.c index ca821da2dcd..e32190f519d 100644 --- a/src/northbridge/intel/nehalem/ram_calc.c +++ b/src/northbridge/intel/nehalem/ram_calc.c @@ -35,7 +35,7 @@ static uintptr_t smm_region_start(void) u32 northbridge_get_tseg_base(void) { - return (u32)smm_region_start & ~1; + return (u32)smm_region_start(); } void *cbmem_top(void) From b80d1324d3e86c0b8c72fd7cd09df07794931059 Mon Sep 17 00:00:00 2001 From: Ivy Jian Date: Mon, 27 May 2019 11:19:44 +0800 Subject: [PATCH 459/588] mb/google/poppy/variants/nami: Disable FPMCU for non-fingerprint variants Even fingerprint device probe failed on non-fingerpint boards,the CRFP driver still register the device that cause the GPE#1 as wake source every time. Override devicetree for non-fingerpirnt variants to avoid unexpected wake event(GPE#1). BUG=b:129650040 BRANCH=firmware-nami-10775.108.B TEST=Boots to OS and check no GPE#1 wake event from eventlog when S0ix exit. Signed-off-by: Ivy Jian Change-Id: I6fa96e04a34e296889414b96a8c604fc61b8a236 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33017 Reviewed-by: EricR Lai Reviewed-by: John Su Tested-by: build bot (Jenkins) --- src/mainboard/google/poppy/variants/nami/mainboard.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/poppy/variants/nami/mainboard.c b/src/mainboard/google/poppy/variants/nami/mainboard.c index dff62c217cc..cc87136520a 100644 --- a/src/mainboard/google/poppy/variants/nami/mainboard.c +++ b/src/mainboard/google/poppy/variants/nami/mainboard.c @@ -238,6 +238,7 @@ void variant_devtree_update(void) struct device *root = SA_DEV_ROOT; config_t *cfg = root->chip_info; uint8_t pl2_id = PL2_ID_DEFAULT; + struct device *spi_fpmcu = PCH_DEV_GSPI1; switch (sku_id) { case SKU_0_SONA: @@ -260,6 +261,7 @@ void variant_devtree_update(void) case SKU_3_PANTHEON: case SKU_4_PANTHEON: cfg->usb2_ports[5].enable = 0; + spi_fpmcu->enabled = 0; break; case SKU_0_BARD: case SKU_1_BARD: From c30e59051fcbda4fba8a2c36c6b04110ee1caacd Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Thu, 23 May 2019 14:34:58 -0600 Subject: [PATCH 460/588] arch/x86: Do not add properties to null DP packages It doesn't make sense to add a property to a non-existent Device Property package. However, some of these functions will proceed anyway and allocate a new Device Property package, add the property to that, and then immediately leak the new package. This changes all the acpi_dp_add_* functions to ignore a null package. Change-Id: I664dcdbaa6b1b8a3aeb9a0126d622e2ffb736efd Signed-off-by: Jacob Garber Found-by: Coverity CID 135745{6,7}, 138029{2-6} Reviewed-on: https://review.coreboot.org/c/coreboot/+/32971 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/arch/x86/acpi_device.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/arch/x86/acpi_device.c b/src/arch/x86/acpi_device.c index 5d8777f37f1..57fbc89064a 100644 --- a/src/arch/x86/acpi_device.c +++ b/src/arch/x86/acpi_device.c @@ -740,6 +740,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp, const struct acpi_dp *prop; size_t i, properties_added = 0; + if (!dp || !property_list) + return 0; + for (i = 0; i < property_count; i++) { prop = &property_list[i]; @@ -775,6 +778,9 @@ size_t acpi_dp_add_property_list(struct acpi_dp *dp, struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, uint64_t value) { + if (!dp) + return NULL; + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_INTEGER, name); if (new) @@ -786,6 +792,9 @@ struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name, struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, const char *string) { + if (!dp) + return NULL; + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_STRING, name); if (new) @@ -797,6 +806,9 @@ struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name, struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name, const char *reference) { + if (!dp) + return NULL; + struct acpi_dp *new = acpi_dp_new(dp, ACPI_DP_TYPE_REFERENCE, name); if (new) @@ -810,7 +822,7 @@ struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name, { struct acpi_dp *new; - if (!child || child->type != ACPI_DP_TYPE_TABLE) + if (!dp || !child || child->type != ACPI_DP_TYPE_TABLE) return NULL; new = acpi_dp_new(dp, ACPI_DP_TYPE_CHILD, name); @@ -826,7 +838,7 @@ struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array) { struct acpi_dp *new; - if (!array || array->type != ACPI_DP_TYPE_TABLE) + if (!dp || !array || array->type != ACPI_DP_TYPE_TABLE) return NULL; new = acpi_dp_new(dp, ACPI_DP_TYPE_ARRAY, array->name); @@ -842,7 +854,7 @@ struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name, struct acpi_dp *dp_array; int i; - if (len <= 0) + if (!dp || len <= 0) return NULL; dp_array = acpi_dp_new_table(name); @@ -862,6 +874,9 @@ struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name, const char *ref, int index, int pin, int active_low) { + if (!dp) + return NULL; + struct acpi_dp *gpio = acpi_dp_new_table(name); if (!gpio) From 702f83897730739af21d10649759589ae9a22203 Mon Sep 17 00:00:00 2001 From: Eric Lai Date: Tue, 28 May 2019 23:49:32 +0800 Subject: [PATCH 461/588] mb/google/sarien: Send post code to the EC Use the mainboard post code hook to inform the wilco EC driver of the every stage. BUG=b:124401932,b:133466714,b:133600566 BRANCH=sarien TEST=Remove DIMM module, confirm diagnostic LED pattern for memory failure (2 amber, 4 white). Signed-off-by: Eric Lai Signed-off-by: Duncan Laurie Change-Id: Ic71e4a6e62b63ca2fd189957c4d6f49b61b934de Reviewed-on: https://review.coreboot.org/c/coreboot/+/33047 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie Reviewed-by: Frank Wu Reviewed-by: Furquan Shaikh --- src/mainboard/google/sarien/Makefile.inc | 5 +++++ src/mainboard/google/sarien/ec.c | 23 +++++++++++++++++++++++ src/mainboard/google/sarien/ramstage.c | 6 ------ 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 src/mainboard/google/sarien/ec.c diff --git a/src/mainboard/google/sarien/Makefile.inc b/src/mainboard/google/sarien/Makefile.inc index 6fd23cefcda..7c37bc9901d 100644 --- a/src/mainboard/google/sarien/Makefile.inc +++ b/src/mainboard/google/sarien/Makefile.inc @@ -29,5 +29,10 @@ verstage-$(CONFIG_CHROMEOS) += chromeos.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_HDA_VERB) += hda_verb.c +bootblock-$(CONFIG_EC_GOOGLE_WILCO) += ec.c +ramstage-$(CONFIG_EC_GOOGLE_WILCO) += ec.c +romstage-$(CONFIG_EC_GOOGLE_WILCO) += ec.c +verstage-$(CONFIG_EC_GOOGLE_WILCO) += ec.c + subdirs-y += variants/$(VARIANT_DIR) CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include diff --git a/src/mainboard/google/sarien/ec.c b/src/mainboard/google/sarien/ec.c new file mode 100644 index 00000000000..fd8e84fbc81 --- /dev/null +++ b/src/mainboard/google/sarien/ec.c @@ -0,0 +1,23 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +void mainboard_post(uint8_t value) +{ + wilco_ec_save_post_code(value); +} diff --git a/src/mainboard/google/sarien/ramstage.c b/src/mainboard/google/sarien/ramstage.c index e246419373a..1d220461cf5 100644 --- a/src/mainboard/google/sarien/ramstage.c +++ b/src/mainboard/google/sarien/ramstage.c @@ -15,7 +15,6 @@ #include #include -#include #include #include #include @@ -70,11 +69,6 @@ void mainboard_silicon_init_params(FSP_S_CONFIG *params) cnl_configure_pads(gpio_table, num_gpios); } -void mainboard_post(uint8_t value) -{ - wilco_ec_save_post_code(value); -} - static void mainboard_enable(struct device *dev) { dev->ops->acpi_inject_dsdt_generator = chromeos_dsdt_generator; From edbcd057e6e8a991c8473a0da05081452db2f8f5 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 20 May 2019 09:21:43 +0200 Subject: [PATCH 462/588] Documentation: Warn about ME cleaner on Sandy Bridge Document known issues with 'disabled' ME. Change-Id: I364f3ed49341523c781eb2f3b41e866f33632a7e Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32889 Reviewed-by: Felix Held Tested-by: build bot (Jenkins) --- .../northbridge/intel/sandybridge/index.md | 1 + .../intel/sandybridge/me_cleaner.md | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 Documentation/northbridge/intel/sandybridge/me_cleaner.md diff --git a/Documentation/northbridge/intel/sandybridge/index.md b/Documentation/northbridge/intel/sandybridge/index.md index dcb090aad69..c1d4b9948d2 100644 --- a/Documentation/northbridge/intel/sandybridge/index.md +++ b/Documentation/northbridge/intel/sandybridge/index.md @@ -6,3 +6,4 @@ This section contains documentation about coreboot on specific Intel "Sandy Brid - [Native Ram Initialization](nri.md) - [RAM initialization feature matrix](nri_features.md) +- [ME Cleaner](me_cleaner.md) diff --git a/Documentation/northbridge/intel/sandybridge/me_cleaner.md b/Documentation/northbridge/intel/sandybridge/me_cleaner.md new file mode 100644 index 00000000000..1086e7e0919 --- /dev/null +++ b/Documentation/northbridge/intel/sandybridge/me_cleaner.md @@ -0,0 +1,20 @@ +# ME Cleaner +It's possible to 'clean' the ME partition within the flash medium as part +of the build process. While cleaning as much code as possible is removed +from the ME firmware partition. In this state the ME errors out and doesn't +operate any more. + +**Using a 'cleaned' ME partition may lead to issues and its use should be +carefully evaulated.** + +## Observations with 'cleaned' ME + +* Instable LPC bus + * SuperIO is malfunctioning + * TPM is malfunctioning + * Random system shutdowns on high bus activity + +## Filing bug reports + +Always test with unmodified IFD and ME section before reporting bugs to the +coreboot project. From 1bffc4bda3b66ba2c91163ec396c54e51d2f056b Mon Sep 17 00:00:00 2001 From: Alex James Date: Wed, 15 May 2019 20:42:27 -0500 Subject: [PATCH 463/588] mb/gigabyte/ga-b75m-d3{h,v}: Switch to variant setup The Gigabyte GA-B75M-D3H/D3V mainboard trees share a lot of duplicate code, and can serve as a base for porting other Gigabyte 7 series motherboards. Switch the Gigabyte GA-B75M-D3H/D3V mainboard trees to a variant setup, defining ga-b75m-d3v as a variant of ga-b75m-d3h. Signed-off-by: Alex James Change-Id: Ia175207a2568aefe1aa9bd8d4d990de6a26f1657 Reviewed-on: https://review.coreboot.org/c/coreboot/+/32708 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/mainboard/gigabyte/ga-b75m-d3h/Kconfig | 17 ++- .../gigabyte/ga-b75m-d3h/Kconfig.name | 3 + .../gigabyte/ga-b75m-d3h/Makefile.inc | 9 +- src/mainboard/gigabyte/ga-b75m-d3h/hda_verb.c | 4 +- src/mainboard/gigabyte/ga-b75m-d3h/romstage.c | 1 + .../ga-b75m-d3h}/gma-mainboard.ads | 0 .../{ => variants/ga-b75m-d3h}/gpio.c | 0 .../ga-b75m-d3h/include/variant/hda_verb.h} | 15 +-- .../variants}/ga-b75m-d3v/board_info.txt | 0 .../variants}/ga-b75m-d3v/gma-mainboard.ads | 0 .../variants}/ga-b75m-d3v/gpio.c | 0 .../ga-b75m-d3v/include/variant/hda_verb.h} | 7 +- src/mainboard/gigabyte/ga-b75m-d3v/Kconfig | 41 ------ .../gigabyte/ga-b75m-d3v/Kconfig.name | 2 - .../gigabyte/ga-b75m-d3v/Makefile.inc | 17 --- .../gigabyte/ga-b75m-d3v/acpi/ec.asl | 0 .../gigabyte/ga-b75m-d3v/acpi/mainboard.asl | 23 ---- .../gigabyte/ga-b75m-d3v/acpi/platform.asl | 29 ---- .../gigabyte/ga-b75m-d3v/acpi/superio.asl | 0 .../gigabyte/ga-b75m-d3v/acpi/thermal.asl | 63 --------- .../gigabyte/ga-b75m-d3v/acpi_tables.c | 39 ------ .../gigabyte/ga-b75m-d3v/cmos.default | 6 - .../gigabyte/ga-b75m-d3v/cmos.layout | 107 --------------- src/mainboard/gigabyte/ga-b75m-d3v/data.vbt | Bin 3902 -> 0 bytes .../gigabyte/ga-b75m-d3v/devicetree.cb | 124 ------------------ src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl | 43 ------ .../gigabyte/ga-b75m-d3v/mainboard.c | 34 ----- src/mainboard/gigabyte/ga-b75m-d3v/romstage.c | 104 --------------- 28 files changed, 34 insertions(+), 654 deletions(-) rename src/mainboard/gigabyte/ga-b75m-d3h/{ => variants/ga-b75m-d3h}/gma-mainboard.ads (100%) rename src/mainboard/gigabyte/ga-b75m-d3h/{ => variants/ga-b75m-d3h}/gpio.c (100%) rename src/mainboard/gigabyte/{ga-b75m-d3v/thermal.h => ga-b75m-d3h/variants/ga-b75m-d3h/include/variant/hda_verb.h} (61%) rename src/mainboard/gigabyte/{ => ga-b75m-d3h/variants}/ga-b75m-d3v/board_info.txt (100%) rename src/mainboard/gigabyte/{ => ga-b75m-d3h/variants}/ga-b75m-d3v/gma-mainboard.ads (100%) rename src/mainboard/gigabyte/{ => ga-b75m-d3h/variants}/ga-b75m-d3v/gpio.c (100%) rename src/mainboard/gigabyte/{ga-b75m-d3v/hda_verb.c => ga-b75m-d3h/variants/ga-b75m-d3v/include/variant/hda_verb.h} (93%) delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/Kconfig delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/Kconfig.name delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/Makefile.inc delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/ec.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi/thermal.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/acpi_tables.c delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/cmos.default delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/cmos.layout delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/data.vbt delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c delete mode 100644 src/mainboard/gigabyte/ga-b75m-d3v/romstage.c diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig index af884f62fb0..ceb2dbc85f5 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig +++ b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig @@ -1,4 +1,4 @@ -if BOARD_GIGABYTE_GA_B75M_D3H +if BOARD_GIGABYTE_GA_B75M_D3H || BOARD_GIGABYTE_GA_B75M_D3V config BOARD_SPECIFIC_OPTIONS def_bool y @@ -30,12 +30,23 @@ config MAINBOARD_DIR string default gigabyte/ga-b75m-d3h +config VARIANT_DIR + string + default "ga-b75m-d3h" if BOARD_GIGABYTE_GA_B75M_D3H + default "ga-b75m-d3v" if BOARD_GIGABYTE_GA_B75M_D3V + config MAINBOARD_PART_NUMBER string - default "GA-B75M-D3H" + default "GA-B75M-D3H" if BOARD_GIGABYTE_GA_B75M_D3H + default "GA-B75M-D3V" if BOARD_GIGABYTE_GA_B75M_D3V config MAX_CPUS int default 8 -endif # BOARD_GIGABYTE_GA_B75M_D3H +# Override the default variant behavior, since the data.vbt is the same +config INTEL_GMA_VBT_FILE + string + default "src/mainboard/$(MAINBOARDDIR)/data.vbt" + +endif # BOARD_GIGABYTE_GA_B75M* diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig.name b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig.name index 571f6d1647f..f8fbe54215f 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig.name +++ b/src/mainboard/gigabyte/ga-b75m-d3h/Kconfig.name @@ -1,2 +1,5 @@ config BOARD_GIGABYTE_GA_B75M_D3H bool "GA-B75M-D3H" + +config BOARD_GIGABYTE_GA_B75M_D3V + bool "GA-B75M-D3V" diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/Makefile.inc b/src/mainboard/gigabyte/ga-b75m-d3h/Makefile.inc index 63976c4b793..07fc277c287 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/Makefile.inc +++ b/src/mainboard/gigabyte/ga-b75m-d3h/Makefile.inc @@ -13,5 +13,10 @@ ## GNU General Public License for more details. ## -romstage-y += gpio.c -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads +romstage-y += variants/$(VARIANT_DIR)/gpio.c + +ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += variants/$(VARIANT_DIR)/gma-mainboard.ads + +subdirs-y += variants/$(VARIANT_DIR) + +CPPFLAGS_common += -I$(src)/mainboard/$(MAINBOARDDIR)/variants/$(VARIANT_DIR)/include diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/hda_verb.c b/src/mainboard/gigabyte/ga-b75m-d3h/hda_verb.c index 23cd570fb21..34610f09ee7 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/hda_verb.c +++ b/src/mainboard/gigabyte/ga-b75m-d3h/hda_verb.c @@ -13,9 +13,7 @@ #include -const u32 cim_verb_data[] = { - /* FIXME: Add configuration for sound */ -}; +#include const u32 pc_beep_verbs[] = {}; diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c b/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c index 49647850cd8..67bcbcb8c94 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c +++ b/src/mainboard/gigabyte/ga-b75m-d3h/romstage.c @@ -88,6 +88,7 @@ void mainboard_early_init(int s3resume) { } +/* FIXME: The GA-B75M-D3V only has two DIMM slots! */ void mainboard_get_spd(spd_raw_data *spd, bool id_only) { read_spd(&spd[0], 0x50, id_only); diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/gma-mainboard.ads b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/gma-mainboard.ads similarity index 100% rename from src/mainboard/gigabyte/ga-b75m-d3h/gma-mainboard.ads rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/gma-mainboard.ads diff --git a/src/mainboard/gigabyte/ga-b75m-d3h/gpio.c b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/gpio.c similarity index 100% rename from src/mainboard/gigabyte/ga-b75m-d3h/gpio.c rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/gpio.c diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/thermal.h b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/include/variant/hda_verb.h similarity index 61% rename from src/mainboard/gigabyte/ga-b75m-d3v/thermal.h rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/include/variant/hda_verb.h index 9db69104a03..53e7c65ddbf 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/thermal.h +++ b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3h/include/variant/hda_verb.h @@ -1,9 +1,6 @@ /* * This file is part of the coreboot project. * - * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. - * Copyright (C) 2014 Vladimir Serbinenko - * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. @@ -14,13 +11,11 @@ * GNU General Public License for more details. */ -#ifndef GAB75MD3H_THERMAL_H -#define GAB75MD3H_THERMAL_H - - /* Temperature which OS will shutdown at */ - #define CRITICAL_TEMPERATURE 100 +#ifndef GA_B75M_D3H_HDA_VERB_H +#define GA_B75M_D3H_HDA_VERB_H - /* Temperature which OS will throttle CPU */ - #define PASSIVE_TEMPERATURE 90 +const u32 cim_verb_data[] = { + /* FIXME: Add configuration for sound */ +}; #endif diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/board_info.txt similarity index 100% rename from src/mainboard/gigabyte/ga-b75m-d3v/board_info.txt rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/board_info.txt diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/gma-mainboard.ads b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/gma-mainboard.ads similarity index 100% rename from src/mainboard/gigabyte/ga-b75m-d3v/gma-mainboard.ads rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/gma-mainboard.ads diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/gpio.c b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/gpio.c similarity index 100% rename from src/mainboard/gigabyte/ga-b75m-d3v/gpio.c rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/gpio.c diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/hda_verb.c b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/include/variant/hda_verb.h similarity index 93% rename from src/mainboard/gigabyte/ga-b75m-d3v/hda_verb.c rename to src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/include/variant/hda_verb.h index 3ae6b5d01e9..c84c80df7b8 100644 --- a/src/mainboard/gigabyte/ga-b75m-d3v/hda_verb.c +++ b/src/mainboard/gigabyte/ga-b75m-d3h/variants/ga-b75m-d3v/include/variant/hda_verb.h @@ -11,7 +11,8 @@ * GNU General Public License for more details. */ -#include +#ifndef GA_B75M_D3V_HDA_VERB_H +#define GA_B75M_D3V_HDA_VERB_H const u32 cim_verb_data[] = { /* coreboot specific header */ @@ -36,6 +37,4 @@ const u32 cim_verb_data[] = { AZALIA_PIN_CFG(0, 0x1f, 0x411111f0) }; -const u32 pc_beep_verbs[] = {}; - -AZALIA_ARRAY_SIZES; +#endif diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig deleted file mode 100644 index d86c742b372..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig +++ /dev/null @@ -1,41 +0,0 @@ -if BOARD_GIGABYTE_GA_B75M_D3V - -config BOARD_SPECIFIC_OPTIONS - def_bool y - select ARCH_X86 - select NORTHBRIDGE_INTEL_SANDYBRIDGE - select USE_NATIVE_RAMINIT - select SOUTHBRIDGE_INTEL_C216 - select SUPERIO_ITE_IT8728F - select BOARD_ROMSIZE_KB_8192 - select HAVE_ACPI_TABLES - select HAVE_OPTION_TABLE - select HAVE_CMOS_DEFAULT - select HAVE_ACPI_RESUME - select INTEL_GMA_HAVE_VBT - select INTEL_INT15 - select SERIRQ_CONTINUOUS_MODE - select MAINBOARD_HAS_LIBGFXINIT - select MAINBOARD_HAS_LPC_TPM - -config DRAM_RESET_GATE_GPIO - int - default 25 - -config USBDEBUG_HCD_INDEX - int - default 2 - -config MAINBOARD_DIR - string - default gigabyte/ga-b75m-d3v - -config MAINBOARD_PART_NUMBER - string - default "GA-B75M-D3V" - -config MAX_CPUS - int - default 8 - -endif # BOARD_GIGABYTE_GA_B75M_D3V diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig.name b/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig.name deleted file mode 100644 index 92f5744f2d7..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/Kconfig.name +++ /dev/null @@ -1,2 +0,0 @@ -config BOARD_GIGABYTE_GA_B75M_D3V - bool "GA-B75M-D3V" diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/Makefile.inc b/src/mainboard/gigabyte/ga-b75m-d3v/Makefile.inc deleted file mode 100644 index 63976c4b793..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/Makefile.inc +++ /dev/null @@ -1,17 +0,0 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2011 The ChromiumOS Authors. All rights reserved. -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; version 2 of the License. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## - -romstage-y += gpio.c -ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/ec.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/ec.asl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl deleted file mode 100644 index a1c79896d7e..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/mainboard.asl +++ /dev/null @@ -1,23 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 Google Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -Scope (\_SB) -{ - Device (PWRB) - { - Name (_HID, EisaId ("PNP0C0C")) - } -} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl deleted file mode 100644 index 10856d33948..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/platform.asl +++ /dev/null @@ -1,29 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 The Chromium OS Authors. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -/* The _PTS method (Prepare To Sleep) is called before the OS is - * entering a sleep state. The sleep state number is passed in Arg0 - */ - -Method (_PTS, 1) -{ -} - -/* The _WAK method is called on system wakeup */ - -Method(_WAK,1) -{ - Return (Package () {0, 0}) -} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/superio.asl deleted file mode 100644 index e69de29bb2d..00000000000 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/thermal.asl b/src/mainboard/gigabyte/ga-b75m-d3v/acpi/thermal.asl deleted file mode 100644 index ca561a50394..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi/thermal.asl +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2011 The Chromium OS Authors. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -// Thermal Zone - -External (\PPKG, MethodObj) - -Scope (\_TZ) -{ - ThermalZone (THRM) - { - Name (_TC1, 0x02) - Name (_TC2, 0x03) - - // Thermal zone polling frequency: 10 seconds - Name (_TZP, 100) - - // Thermal sampling period for passive cooling: 10 seconds - Name (_TSP, 100) - - // Convert from Degrees C to 1/10 Kelvin for ACPI - Method (CTOK, 1) - { - // 10th of Degrees C - Multiply (Arg0, 10, Local0) - - // Convert to Kelvin - Add (Local0, 2732, Local0) - - Return (Local0) - } - - // Threshold for OS to shutdown - Method (_CRT, 0, Serialized) - { - Return (CTOK (\TCRT)) - } - - // Threshold for passive cooling - Method (_PSV, 0, Serialized) - { - Return (CTOK (\TPSV)) - } - - // Processors used for passive cooling - Method (_PSL, 0, Serialized) - { - Return (\PPKG ()) - } - } -} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/acpi_tables.c b/src/mainboard/gigabyte/ga-b75m-d3v/acpi_tables.c deleted file mode 100644 index 5c09059173b..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/acpi_tables.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2009 coresystems GmbH - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "thermal.h" - -static void acpi_update_thermal_table(global_nvs_t *gnvs) -{ - gnvs->tcrt = CRITICAL_TEMPERATURE; - gnvs->tpsv = PASSIVE_TEMPERATURE; -} - -void acpi_create_gnvs(global_nvs_t *gnvs) -{ - memset((void *)gnvs, 0, sizeof(*gnvs)); - - /* Disable USB ports in S3 by default */ - gnvs->s3u0 = 0; - gnvs->s3u1 = 0; - - /* Disable USB ports in S5 by default */ - gnvs->s5u0 = 0; - gnvs->s5u1 = 0; - - acpi_update_thermal_table(gnvs); -} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/cmos.default b/src/mainboard/gigabyte/ga-b75m-d3v/cmos.default deleted file mode 100644 index 6f3cec735e8..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/cmos.default +++ /dev/null @@ -1,6 +0,0 @@ -boot_option=Fallback -debug_level=Debug -power_on_after_fail=Enable -nmi=Enable -sata_mode=AHCI -gfx_uma_size=32M diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/cmos.layout b/src/mainboard/gigabyte/ga-b75m-d3v/cmos.layout deleted file mode 100644 index 095e3833e15..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/cmos.layout +++ /dev/null @@ -1,107 +0,0 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2007-2008 coresystems GmbH -## Copyright (C) 2014 Vladimir Serbinenko -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; version 2 of the License. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -## GNU General Public License for more details. -## - -# ----------------------------------------------------------------- -entries - -# ----------------------------------------------------------------- -# Status Register A -# ----------------------------------------------------------------- -# Status Register B -# ----------------------------------------------------------------- -# Status Register C -#96 4 r 0 status_c_rsvd -#100 1 r 0 uf_flag -#101 1 r 0 af_flag -#102 1 r 0 pf_flag -#103 1 r 0 irqf_flag -# ----------------------------------------------------------------- -# Status Register D -#104 7 r 0 status_d_rsvd -#111 1 r 0 valid_cmos_ram -# ----------------------------------------------------------------- -# Diagnostic Status Register -#112 8 r 0 diag_rsvd1 - -# ----------------------------------------------------------------- -0 120 r 0 reserved_memory -#120 264 r 0 unused - -# ----------------------------------------------------------------- -# RTC_BOOT_BYTE (coreboot hardcoded) -384 1 e 4 boot_option -388 4 h 0 reboot_counter -#390 2 r 0 unused? - -# ----------------------------------------------------------------- -# coreboot config options: console -#392 3 r 0 unused -395 4 e 6 debug_level -#399 1 r 0 unused - -# coreboot config options: southbridge -408 1 e 1 nmi -409 2 e 7 power_on_after_fail - -#411 10 r 0 unused -421 1 e 9 sata_mode -#422 2 r 0 unused - -# coreboot config options: cpu -#425 7 r 0 unused - -# coreboot config options: northbridge -432 3 e 11 gfx_uma_size -#435 549 r 0 unused - -# coreboot config options: check sums -984 16 h 0 check_sum - -# ----------------------------------------------------------------- - -enumerations - -#ID value text -1 0 Disable -1 1 Enable -4 0 Fallback -4 1 Normal -6 0 Emergency -6 1 Alert -6 2 Critical -6 3 Error -6 4 Warning -6 5 Notice -6 6 Info -6 7 Debug -6 8 Spew -7 0 Disable -7 1 Enable -7 2 Keep -9 0 AHCI -9 1 IDE -11 0 32M -11 1 64M -11 2 96M -11 3 128M -11 4 160M -11 5 192M -11 6 224M - -# ----------------------------------------------------------------- -checksums - -checksum 392 439 984 diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/data.vbt b/src/mainboard/gigabyte/ga-b75m-d3v/data.vbt deleted file mode 100644 index ccbf6eed7f940d3e2de666eed4af9c9184e63c4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3902 zcmdT{Z){Ul6hE);_22D#tb3c#)v=r*fo|;2YngLdroMLFTu0fuwKSC&>7eCLGR7!> z0*Sbyi(pJhH3kvUG@2;x6XBDIe&CZ?j4=x_#27yi;s-;B;R7*|AoaXI9fT=+F%t2< z{O-B;^xWUO_uO;teO;T5q%b)W>5Qc#?a_hcrqpO62MRn_Ge`B(5{Zo_w?)IL@U}>N zw0{$R1}kAj&E4w&IpFG~Q1I!V*wn%NWMI4nlM_?9quUF6a=Y@KvBPEy6a6s^@7R%_ z%oipO=5v@#zYs=^R$`GudnR)@a%k`Ne4!ULF0#g8SI5RK#9**9w6Qa!1Vf0*Gre8G z-rz=wMF;vvHz#88a4I%Bf}`UYjU~g$PaY0=xV4Hwmut}Uv0BCl>8n5YH z)FkQn`}?H0oCU8}c&`q01A4LDFyN5d04iM34L&ywTsjH;fE?O112h@FG!2N~q3LM_ zSbdk?r3$N!zmt#3KxhOd)YaY7+owjNgG0md#CR&5+4@rP_-n7v`r%FqXt5ke)e265 z1RsE7ybVt9J+MJ2!>Xd`cxF&_oCjLWDlTAR$56O2`qW2#!N=r(!FDQ+HL7Gi9wI!7IS27AT%G_2*2z`zGx$ z6=q70DRrfVs#0+};cn$SA5B%D66hK4JD#BsIH?*{@XGS?Y%9 zd2}`V1SlRK_u}~!nu|0^GaFEwFK3@#t;xkwq}KfgHhbaW28$!BjRzU3`bD{{fmjE_ zbRzJszF8xTwg6O4tZ)POp?xd-Zf}R0x4>d{vnSpN|? z{6@#wS5-bJ|I1%iZlW0A^<;KwX`>fqb_GCuFtIH$F_oVjnb@1R*jY6Mxdu?fuuk!v z>^8`JN-LZh14UJ)>kLiP`OYI($NcNm%$cfY=y_Gyej%i)m#P|H0J>**!)mS1Ce@>^J-lW@U#i#u8Oc($~4 zSu2%FV>euJ7fX0`wbzwhV~lFDq6zrOsR#b@H7)M~|Bf5KaLeDg+4pX|?UqHxRx<2k z@(5!YhOaWY#MoJemzaE+v7Z>)JaWB_H~V zjUrnoVqBD87TInQPl<9_WOE`ei1Ia&-4IchCRZXd?uCy$S<(+(nu--aywXuB zXZ=m8g665z)IB4V-1=@7omN&6=qr||FFZvIt=cF6Vz8I=J4h_sXD!6T*_QIc*z6i5 z@&2ks1|B?Gn>=ZSL1|Uzv$HwHH)dRm+8lTaM~&eh#-z?584Px`u!`$`C?{~0A}amb zDBTZyiSm)=P;~a_@$m56wDlH!`+M5eO#8jP;GsrmpwB4B@_EssLbeEXS+BQN8)eJ^ zyjn}NcvJmv%r@)?$FO%jWaftF>8tjU)RhNH+Y|8SAUQJz47Nam{_D1Jr{Nd=PiOFc AjQ{`u diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb b/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb deleted file mode 100644 index ceb92793653..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/devicetree.cb +++ /dev/null @@ -1,124 +0,0 @@ -chip northbridge/intel/sandybridge - # IGD Displays - register "gfx.ndid" = "3" - register "gfx.did" = "{ 0x80000100, 0x80000240, 0x80000410 }" - - device cpu_cluster 0 on - chip cpu/intel/model_206ax - register "c1_acpower" = "1" - register "c2_acpower" = "3" - register "c3_acpower" = "5" - register "c1_battery" = "1" - register "c2_battery" = "3" - register "c3_battery" = "5" - # Magic APIC ID to locate this chip - device lapic 0x0 on end - device lapic 0xacac off end - end - end - - register "pci_mmio_size" = "2048" - - device domain 0 on - subsystemid 0x1458 0x5000 inherit - device pci 00.0 on # Host bridge - subsystemid 0x1458 0x5000 - end - device pci 01.0 on end # PCIe Bridge for discrete graphics - device pci 02.0 on # Integrated VGA controller - subsystemid 0x1458 0xd000 - end - - chip southbridge/intel/bd82x6x # Intel Series 7 Panther Point PCH - # GPI routing - register "alt_gp_smi_en" = "0x0000" - register "gen1_dec" = "0x003c0a01" - - # Set max SATA speed to 6.0 Gb/s - register "sata_port_map" = "0x3f" - register "sata_interface_speed_support" = "0x3" - - register "pcie_port_coalesce" = "0" - register "p_cnt_throttling_supported" = "0" - register "docking_supported" = "0" - register "c2_latency" = "0x0065" - - device pci 14.0 on # USB 3.0 Controller - subsystemid 0x1458 0x5007 - end - device pci 16.0 on end # Management Engine Interface 1 - device pci 16.1 off end # Management Engine Interface 2 - device pci 16.2 off end # Management Engine IDE-R - device pci 16.3 off end # Management Engine KT - device pci 19.0 off end # Intel Gigabit Ethernet - device pci 1a.0 on # USB2 EHCI #2 - subsystemid 0x1458 0x5006 - end - device pci 1b.0 on # High Definition Audio - subsystemid 0x1458 0xa002 - end - device pci 1c.0 on end # PCIe Port #1 - device pci 1c.1 off end # PCIe Port #2 - device pci 1c.2 off end # PCIe Port #3 - device pci 1c.3 off end # PCIe Port #4 - device pci 1c.4 on # PCIe Port #5 - device pci 00.0 on # PCI 10ec:8168 - subsystemid 0x1458 0xe000 - end - end - device pci 1c.5 off end # PCIe Port #6 - device pci 1c.6 off end # PCIe Port #7 - device pci 1c.7 off end # PCIe Port #8 - device pci 1d.0 on # USB2 EHCI #1 - subsystemid 0x1458 0x5006 - end - device pci 1e.0 on end # PCI bridge - device pci 1f.0 on # ISA/LPC bridge - subsystemid 0x1458 0x5001 - chip superio/ite/it8728f - device pnp 2e.0 off end # FDC - device pnp 2e.1 on # Serial Port 1 - io 0x60 = 0x3f8 - irq 0x70 = 4 - end - device pnp 2e.2 on - io 0x60 = 0x2f8 - irq 0x70 = 3 - end - device pnp 2e.3 on - io 0x60 = 0x378 - irq 0x70 = 7 - drq 0x74 = 4 - end - device pnp 2e.4 on # EC - io 0x60 = 0xa30 - irq 0x70 = 9 - io 0x62 = 0xa20 - end - device pnp 2e.5 on # Keyboard - io 0x60 = 0x60 - irq 0x70 = 1 - io 0x62 = 0x64 - end - device pnp 2e.6 on # Mouse - irq 0x70 = 12 - end - device pnp 2e.7 off end # GPIO - device pnp 2e.a off end # IR - end - - chip drivers/pc80/tpm - device pnp 0c31.0 on end - end - end - device pci 1f.2 on # SATA Controller 1 - subsystemid 0x1458 0xb005 - end - device pci 1f.3 on # SMBus - subsystemid 0x1458 0x5001 - end - device pci 1f.4 off end - device pci 1f.5 off end # SATA Controller 2 - end - end -end diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl b/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl deleted file mode 100644 index c00ee30e6b4..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/dsdt.asl +++ /dev/null @@ -1,43 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -DefinitionBlock( - "dsdt.aml", - "DSDT", - 0x02, // DSDT revision: ACPI v2.0 and up - OEM_ID, - ACPI_TABLE_CREATOR, - 0x20141018 // OEM revision -) -{ - #include - - // Some generic macros - #include "acpi/mainboard.asl" - #include "acpi/platform.asl" - #include "acpi/thermal.asl" - #include - /* global NVS and variables. */ - #include - #include - - Scope (\_SB) { - Device (PCI0) - { - #include - #include - #include - } - } -} diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c b/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c deleted file mode 100644 index cc267579143..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/mainboard.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2007-2009 coresystems GmbH - * Copyright (C) 2011-2012 Google Inc. - * Copyright (C) 2014 Vladimir Serbinenko - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include - -// mainboard_enable is executed as first thing after -// enumerate_buses(). - -static void mainboard_enable(struct device *dev) -{ - install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_NONE, - GMA_INT15_PANEL_FIT_DEFAULT, - GMA_INT15_BOOT_DISPLAY_DEFAULT, 0); -} - -struct chip_operations mainboard_ops = { - .enable_dev = mainboard_enable -}; diff --git a/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c b/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c deleted file mode 100644 index eb88d366aeb..00000000000 --- a/src/mainboard/gigabyte/ga-b75m-d3v/romstage.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Damien Zammit - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -#define SUPERIO_BASE 0x2e -#define SUPERIO_DEV PNP_DEV(SUPERIO_BASE, 0) -#define SIO_GPIO PNP_DEV(SUPERIO_BASE, IT8728F_GPIO) -#define SERIAL_DEV PNP_DEV(SUPERIO_BASE, 0x01) - -void pch_enable_lpc(void) -{ - pci_write_config16(PCH_LPC_DEV, LPC_EN, KBC_LPC_EN | - CNF1_LPC_EN | CNF2_LPC_EN | COMA_LPC_EN); - - pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, 0x3c0a01); - pci_write_config16(PCH_LPC_DEV, LPC_IO_DEC, 0x10); - - pci_write_config32(PCH_LPC_DEV, ETR3, 0x10000); -} - -void mainboard_config_superio(void) -{ - /* Initialize SuperIO */ - ite_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); - - ite_reg_write(SIO_GPIO, 0xEF, 0x7E); // magic SIO disable reboot - - /* FIXME: These values could be configured in ramstage */ - ite_reg_write(SIO_GPIO, 0x25, 0x40); // gpio pin function -> gp16 - ite_reg_write(SIO_GPIO, 0x27, 0x10); // gpio pin function -> gp34 - ite_reg_write(SIO_GPIO, 0x2c, 0x80); // smbus isolation on parallel port - ite_reg_write(SIO_GPIO, 0x62, 0x0a); // simple iobase 0xa00 - ite_reg_write(SIO_GPIO, 0x72, 0x20); // watchdog timeout clear! - ite_reg_write(SIO_GPIO, 0x73, 0x00); // watchdog timeout clear! - ite_reg_write(SIO_GPIO, 0xcb, 0x00); // simple io set4 direction -> in - ite_reg_write(SIO_GPIO, 0xe9, 0x27); // bus select disable - ite_reg_write(SIO_GPIO, 0xf0, 0x10); // ? - ite_reg_write(SIO_GPIO, 0xf1, 0x42); // ? - ite_reg_write(SIO_GPIO, 0xf6, 0x1c); // hwmon alert beep -> gp36(pin12) - - /* EC SIO settings */ - ite_reg_write(IT8728F_EC, 0xf1, 0xc0); - ite_reg_write(IT8728F_EC, 0xf6, 0xf0); - ite_reg_write(IT8728F_EC, 0xf9, 0x48); - ite_reg_write(IT8728F_EC, 0x60, 0x0a); - ite_reg_write(IT8728F_EC, 0x61, 0x30); - ite_reg_write(IT8728F_EC, 0x62, 0x0a); - ite_reg_write(IT8728F_EC, 0x63, 0x20); - ite_reg_write(IT8728F_EC, 0x30, 0x01); -} - -const struct southbridge_usb_port mainboard_usb_ports[] = { - { 1, 5, 0 }, - { 1, 5, 0 }, - { 1, 5, 1 }, - { 1, 5, 1 }, - { 1, 5, 2 }, - { 1, 5, 2 }, - { 1, 5, 3 }, - { 1, 5, 3 }, - { 1, 5, 4 }, - { 1, 5, 4 }, - { 1, 5, 6 }, - { 1, 5, 5 }, - { 1, 5, 5 }, - { 1, 5, 6 }, -}; - -void mainboard_early_init(int s3resume) -{ -} - -/* FIXME: This board only has two DIMM slots! */ -void mainboard_get_spd(spd_raw_data *spd, bool id_only) -{ - read_spd(&spd[0], 0x50, id_only); - read_spd(&spd[1], 0x51, id_only); - read_spd(&spd[2], 0x52, id_only); - read_spd(&spd[3], 0x53, id_only); -} - -void mainboard_rcba_config(void) -{ - /* Enable HECI */ - RCBA32(FD2) &= ~0x2; -} From 87c4f11c64713c8a90d7a6ffe997da891c9758d4 Mon Sep 17 00:00:00 2001 From: Tobias Diedrich Date: Thu, 7 Dec 2017 22:40:20 +0100 Subject: [PATCH 464/588] intel/sandybridge: Make timC training more robust. When using native raminit with https://review.coreboot.org/#/c/22683/ I've found that timC training usually fails unless the ram is overspecced (i.e. DDR3L-1600 rated for 1.35V works most of the time with native raminit as DDR3-1333 @1.5V). Looking at the training data I've found that during timC training it is reading register values in the 0-4000 range and checking for runs of 0, but with the failing training the values don't go all the way down to 0. The solution for me has been to do a thresholing pre-pass, after which both the DDR3-1333 @1.5V and the DDR3L-1600 @1.35V work fine for me. Tested: - Intel NUC DCP847SKE - RAM slots with 2x4GB Kingston KVR1333D3S9/4G (DDR3-1333 1.5V), boots fine with native raminit @1.5V - RAM slots with 2x4GB Kingston KVR16LS11/4G (DDR3L-1600 1.35V), boots fine with native raminit @1.35V - Casual use with these settings - Tested on Lenovo T520 with Crucial HyperX DDR3-1833. - Memtest86+ stable. Change-Id: I9986616e86560c4980ccd8e3e549af53caa15c71 Signed-off-by: Tobias Diedrich Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/22776 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- .../intel/sandybridge/raminit_common.c | 39 ++++++++++++++++--- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index 5347c5c4934..53f28c6cd66 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -1524,6 +1524,24 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank) wait_428c(channel); } +static void timC_threshold_process(int *data, const int count) +{ + int min = data[0]; + int max = min; + int i; + for (i = 1; i < count; i++) { + if (min > data[i]) + min = data[i]; + if (max < data[i]) + max = data[i]; + } + int threshold = min/2 + max/2; + for (i = 0; i < count; i++) + data[i] = data[i] > threshold; + printram("threshold=%d min=%d max=%d\n", + threshold, min, max); +} + static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank) { int timC; @@ -1554,14 +1572,25 @@ static int discover_timC(ramctr_timing *ctrl, int channel, int slotrank) } } FOR_ALL_LANES { - struct run rn = - get_longest_zero_run(statistics[lane], MAX_TIMC + 1); - ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle; - if (rn.all) { + struct run rn = get_longest_zero_run( + statistics[lane], ARRAY_SIZE(statistics[lane])); + if (rn.all || rn.length < 8) { printk(BIOS_EMERG, "timC discovery failed: %d, %d, %d\n", channel, slotrank, lane); - return MAKE_ERR; + /* With command training not happend yet, the lane can + * be erroneous. Take the avarage as reference and try + * again to find a run. + */ + timC_threshold_process(statistics[lane], + ARRAY_SIZE(statistics[lane])); + rn = get_longest_zero_run(statistics[lane], + ARRAY_SIZE(statistics[lane])); + if (rn.all || rn.length < 8) { + printk(BIOS_EMERG, "timC recovery failed\n"); + return MAKE_ERR; + } } + ctrl->timings[channel][slotrank].lanes[lane].timC = rn.middle; printram("timC: %d, %d, %d: 0x%02x-0x%02x-0x%02x\n", channel, slotrank, lane, rn.start, rn.middle, rn.end); } From 6d6945b807469675f872124f33250d2e5c0f14b8 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 29 Dec 2018 14:00:46 +0100 Subject: [PATCH 465/588] soc/intel/apollolake: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms using this code have NO_CAR_GLOBAL_MIGRATION. Change-Id: I0f393385aa94f18c2e05af3b5a54999575323d18 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30510 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/apollolake/meminit.c | 7 +++---- src/soc/intel/apollolake/mmap_boot.c | 29 +++++++++------------------- src/soc/intel/apollolake/romstage.c | 7 +++---- 3 files changed, 15 insertions(+), 28 deletions(-) diff --git a/src/soc/intel/apollolake/meminit.c b/src/soc/intel/apollolake/meminit.c index 038fa9fb2b5..219b6610424 100644 --- a/src/soc/intel/apollolake/meminit.c +++ b/src/soc/intel/apollolake/meminit.c @@ -12,7 +12,6 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ -#include #include #include #include @@ -21,11 +20,11 @@ #include #include -static size_t memory_size_mib CAR_GLOBAL; +static size_t memory_size_mib; size_t memory_in_system_in_mib(void) { - return car_get_var(memory_size_mib); + return memory_size_mib; } static void accumulate_channel_memory(int density, int dual_rank) @@ -61,7 +60,7 @@ static void accumulate_channel_memory(int density, int dual_rank) sz *= GiB / MiB; - car_set_var(memory_size_mib, car_get_var(memory_size_mib) + sz); + memory_size_mib += sz; } size_t iohole_in_mib(void) diff --git a/src/soc/intel/apollolake/mmap_boot.c b/src/soc/intel/apollolake/mmap_boot.c index 1c3077ed91b..614b6031c4d 100644 --- a/src/soc/intel/apollolake/mmap_boot.c +++ b/src/soc/intel/apollolake/mmap_boot.c @@ -16,7 +16,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -57,17 +56,17 @@ * */ -static size_t bios_size CAR_GLOBAL; +static size_t bios_size; -static struct mem_region_device shadow_dev CAR_GLOBAL; -static struct xlate_region_device real_dev CAR_GLOBAL; +static struct mem_region_device shadow_dev; +static struct xlate_region_device real_dev; static void bios_mmap_init(void) { size_t size, start, bios_mapped_size; uintptr_t base; - size = car_get_var(bios_size); + size = bios_size; /* If bios_size is initialized, then bail out. */ if (size != 0) @@ -83,34 +82,25 @@ static void bios_mmap_init(void) */ bios_mapped_size = size - 256 * KiB; - struct mem_region_device *shadow_dev_ptr; - struct xlate_region_device *real_dev_ptr; - shadow_dev_ptr = car_get_var_ptr(&shadow_dev); - real_dev_ptr = car_get_var_ptr(&real_dev); - - mem_region_device_ro_init(shadow_dev_ptr, (void *)base, + mem_region_device_ro_init(&shadow_dev, (void *)base, bios_mapped_size); - xlate_region_device_ro_init(real_dev_ptr, &shadow_dev_ptr->rdev, + xlate_region_device_ro_init(&real_dev, &shadow_dev.rdev, start, bios_mapped_size, CONFIG_ROM_SIZE); - car_set_var(bios_size, size); + bios_size = size; } const struct region_device *boot_device_ro(void) { bios_mmap_init(); - struct xlate_region_device *real_dev_ptr; - real_dev_ptr = car_get_var_ptr(&real_dev); - - return &real_dev_ptr->rdev; + return &real_dev.rdev; } static int iafw_boot_region_properties(struct cbfs_props *props) { - struct xlate_region_device *real_dev_ptr; struct region *real_dev_reg; struct region regn; @@ -123,8 +113,7 @@ static int iafw_boot_region_properties(struct cbfs_props *props) /* Check that we are within the memory mapped area. It's too easy to forget the SRAM mapping when crafting an FMAP file. */ - real_dev_ptr = car_get_var_ptr(&real_dev); - real_dev_reg = &real_dev_ptr->sub_region; + real_dev_reg = &real_dev.sub_region; if (region_is_subregion(real_dev_reg, ®n)) { printk(BIOS_DEBUG, "CBFS @ %zx size %zx\n", props->offset, props->size); diff --git a/src/soc/intel/apollolake/romstage.c b/src/soc/intel/apollolake/romstage.c index c976ac2d6f0..5bf501dcfa6 100644 --- a/src/soc/intel/apollolake/romstage.c +++ b/src/soc/intel/apollolake/romstage.c @@ -17,7 +17,6 @@ */ #include -#include #include #include #include @@ -57,7 +56,7 @@ static const uint8_t hob_variable_guid[16] = { 0x8d, 0xe6, 0xc0, 0x44, 0x64, 0x1d, 0xe9, 0x42, }; -static uint32_t fsp_version CAR_GLOBAL; +static uint32_t fsp_version; /* High Performance Event Timer Configuration */ #define P2SB_HPTC 0x60 @@ -236,7 +235,7 @@ asmlinkage void car_stage_entry(void) &var_size); if (new_var_data) mrc_cache_stash_data(MRC_VARIABLE_DATA, - car_get_var(fsp_version), new_var_data, + fsp_version, new_var_data, var_size); else printk(BIOS_ERR, "Failed to determine variable data\n"); @@ -410,7 +409,7 @@ void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version) mupd->FspmConfig.VariableNvsBufferPtr = rdev_mmap_full(&rdev); } - car_set_var(fsp_version, version); + fsp_version = version; } From 8a1b94ccbeca88b8fba96329477e99ea8535c244 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 09:47:01 +0200 Subject: [PATCH 466/588] Clean up unused arch/early_variables.h header MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ib863e23863ba6d7504b6c4d32de2f1fea4e57fec Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32996 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/drivers/intel/fsp1_1/car.c | 2 +- src/drivers/intel/fsp1_1/hob.c | 1 - src/drivers/intel/fsp1_1/romstage.c | 1 - src/mainboard/packardbell/ms2290/romstage.c | 1 - src/soc/intel/broadwell/romstage/romstage.c | 1 - src/soc/intel/broadwell/romstage/uart.c | 1 - src/soc/intel/common/block/fast_spi/fast_spi_flash.c | 1 - src/soc/intel/common/block/scs/early_mmc.c | 1 - src/soc/intel/skylake/romstage/romstage.c | 1 - src/soc/intel/skylake/romstage/romstage_fsp20.c | 1 - 10 files changed, 1 insertion(+), 10 deletions(-) diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 34b2518c385..a1ee7b141ac 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include diff --git a/src/drivers/intel/fsp1_1/hob.c b/src/drivers/intel/fsp1_1/hob.c index ee1a6a328e8..0a123cff789 100644 --- a/src/drivers/intel/fsp1_1/hob.c +++ b/src/drivers/intel/fsp1_1/hob.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 85badced896..45ca87aac8d 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/src/mainboard/packardbell/ms2290/romstage.c b/src/mainboard/packardbell/ms2290/romstage.c index efaa9e423d1..0ab55448582 100644 --- a/src/mainboard/packardbell/ms2290/romstage.c +++ b/src/mainboard/packardbell/ms2290/romstage.c @@ -31,7 +31,6 @@ #include #include -#include "arch/early_variables.h" #include #include diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index f8571678d86..9bca716447b 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/src/soc/intel/broadwell/romstage/uart.c b/src/soc/intel/broadwell/romstage/uart.c index 58450dd8348..a1a29b65fdd 100644 --- a/src/soc/intel/broadwell/romstage/uart.c +++ b/src/soc/intel/broadwell/romstage/uart.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c index 97e231ca3fa..0a4344272e1 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi_flash.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi_flash.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/common/block/scs/early_mmc.c b/src/soc/intel/common/block/scs/early_mmc.c index 4b15bb48bb3..8f47ec7d9e9 100644 --- a/src/soc/intel/common/block/scs/early_mmc.c +++ b/src/soc/intel/common/block/scs/early_mmc.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/intel/skylake/romstage/romstage.c b/src/soc/intel/skylake/romstage/romstage.c index 12239ae13e2..29c4774dc12 100644 --- a/src/soc/intel/skylake/romstage/romstage.c +++ b/src/soc/intel/skylake/romstage/romstage.c @@ -15,7 +15,6 @@ */ #include -#include #include #include #include diff --git a/src/soc/intel/skylake/romstage/romstage_fsp20.c b/src/soc/intel/skylake/romstage/romstage_fsp20.c index 96937d651d9..04c369beb8a 100644 --- a/src/soc/intel/skylake/romstage/romstage_fsp20.c +++ b/src/soc/intel/skylake/romstage/romstage_fsp20.c @@ -14,7 +14,6 @@ */ #include -#include #include #include #include From 00295aa8a6824bc2a0a2f9ff7eb8f649287bd97b Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 09:52:07 +0200 Subject: [PATCH 467/588] soc/intel/braswell: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that this soc supports NO_CAR_GLOBAL_MIGRATION CAR_GLOBAL and car_get/set_x are not needed anymore. Change-Id: Ia7fa97135a4b376ac0bd8b30093a77614cc2cf55 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32997 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/braswell/romstage/romstage.c | 41 ++++++++++------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c index 22b0df2a8b0..8dfc291d1ea 100644 --- a/src/soc/intel/braswell/romstage/romstage.c +++ b/src/soc/intel/braswell/romstage/romstage.c @@ -17,7 +17,6 @@ #include #include -#include #include #include #include @@ -105,48 +104,44 @@ static void soc_rtc_init(void) cmos_init(rtc_failed); } -static struct chipset_power_state power_state CAR_GLOBAL; +static struct chipset_power_state power_state; static void migrate_power_state(int is_recovery) { struct chipset_power_state *ps_cbmem; - struct chipset_power_state *ps_car; - ps_car = car_get_var_ptr(&power_state); ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem)); if (ps_cbmem == NULL) { printk(BIOS_DEBUG, "Not adding power state to cbmem!\n"); return; } - memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem)); + memcpy(ps_cbmem, &power_state, sizeof(*ps_cbmem)); } ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state); struct chipset_power_state *fill_power_state(void) { - struct chipset_power_state *ps = car_get_var_ptr(&power_state); - - ps->pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); - ps->pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN); - ps->pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); - ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS); - ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN); - ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS); - ps->prsts = read32((void *)(PMC_BASE_ADDRESS + PRSTS)); - ps->gen_pmcon1 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON1)); - ps->gen_pmcon2 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON2)); - - ps->prev_sleep_state = chipset_prev_sleep_state(ps); + power_state.pm1_sts = inw(ACPI_BASE_ADDRESS + PM1_STS); + power_state.pm1_en = inw(ACPI_BASE_ADDRESS + PM1_EN); + power_state.pm1_cnt = inl(ACPI_BASE_ADDRESS + PM1_CNT); + power_state.gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS); + power_state.gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN); + power_state.tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS); + power_state.prsts = read32((void *)(PMC_BASE_ADDRESS + PRSTS)); + power_state.gen_pmcon1 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON1)); + power_state.gen_pmcon2 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON2)); + + power_state.prev_sleep_state = chipset_prev_sleep_state(&power_state); printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n", - ps->pm1_sts, ps->pm1_en, ps->pm1_cnt); + power_state.pm1_sts, power_state.pm1_en, power_state.pm1_cnt); printk(BIOS_DEBUG, "gpe0_sts: %08x gpe0_en: %08x tco_sts: %08x\n", - ps->gpe0_sts, ps->gpe0_en, ps->tco_sts); + power_state.gpe0_sts, power_state.gpe0_en, power_state.tco_sts); printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n", - ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2); - printk(BIOS_DEBUG, "prev_sleep_state %d\n", ps->prev_sleep_state); - return ps; + power_state.prsts, power_state.gen_pmcon1, power_state.gen_pmcon2); + printk(BIOS_DEBUG, "prev_sleep_state %d\n", power_state.prev_sleep_state); + return &power_state; } /* Return 0, 3, or 5 to indicate the previous sleep state. */ From 6e11908128ec83c6237f3285bc7e2cfbc6f6d0f7 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 27 May 2019 17:21:54 +0200 Subject: [PATCH 468/588] intel/quark/storage_test.h: Drop external variable declaration These are only used where they are initially declared. Change-Id: I0a81a945b771b6c29a170c479b9e72c98e8f3c5a Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33022 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- src/soc/intel/quark/include/soc/storage_test.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/soc/intel/quark/include/soc/storage_test.h b/src/soc/intel/quark/include/soc/storage_test.h index 62c9e792368..1c93f1cdf0e 100644 --- a/src/soc/intel/quark/include/soc/storage_test.h +++ b/src/soc/intel/quark/include/soc/storage_test.h @@ -48,9 +48,4 @@ struct log_entry { #define LOG_ENTRIES 256 -extern struct log_entry log[LOG_ENTRIES]; -extern uint8_t log_index; -extern int log_full; -extern long log_start_time; - #endif /* __STORAGE_TEST_H__ */ From 84e22e37e89e3384782c40379cc7f2b18faa2099 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 09:57:27 +0200 Subject: [PATCH 469/588] soc/intel/quark: Don't use CAR_GLOBAL This soc has NO_CAR_GLOBAL_MIGRATION and does not require CAR_GLOBAL and car_get/set_x. Change-Id: I4e2c1c5766e3bcdd4763b42fb925074f7ccd7002 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32998 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/soc/intel/quark/romstage/fsp2_0.c | 15 +++++++-------- src/soc/intel/quark/romstage/romstage.c | 1 - src/soc/intel/quark/storage_test.c | 15 +++++++-------- 3 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/soc/intel/quark/romstage/fsp2_0.c b/src/soc/intel/quark/romstage/fsp2_0.c index e4abcc034ad..5ebbacbd2a7 100644 --- a/src/soc/intel/quark/romstage/fsp2_0.c +++ b/src/soc/intel/quark/romstage/fsp2_0.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. */ -#include +#include #include #include #include "../chip.h" @@ -85,20 +85,19 @@ asmlinkage void car_stage_c_entry(void) run_postcar_phase(&pcf); } -static struct chipset_power_state power_state CAR_GLOBAL; +static struct chipset_power_state power_state; struct chipset_power_state *get_power_state(void) { - return (struct chipset_power_state *)car_get_var_ptr(&power_state); + return &power_state; } int fill_power_state(void) { - struct chipset_power_state *ps = get_power_state(); - - ps->prev_sleep_state = 0; - printk(BIOS_SPEW, "prev_sleep_state %d\n", ps->prev_sleep_state); - return ps->prev_sleep_state; + power_state.prev_sleep_state = 0; + printk(BIOS_SPEW, "prev_sleep_state %d\n", + power_state.prev_sleep_state); + return power_state.prev_sleep_state; } void platform_fsp_memory_init_params_cb(FSPM_UPD *fspm_upd, uint32_t version) diff --git a/src/soc/intel/quark/romstage/romstage.c b/src/soc/intel/quark/romstage/romstage.c index f2a280effb4..4ac580eb287 100644 --- a/src/soc/intel/quark/romstage/romstage.c +++ b/src/soc/intel/quark/romstage/romstage.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include diff --git a/src/soc/intel/quark/storage_test.c b/src/soc/intel/quark/storage_test.c index bdf86b1f129..653466a6d93 100644 --- a/src/soc/intel/quark/storage_test.c +++ b/src/soc/intel/quark/storage_test.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -29,13 +28,13 @@ #include #if CONFIG(STORAGE_LOG) -struct log_entry log[LOG_ENTRIES] CAR_GLOBAL; -uint8_t log_index CAR_GLOBAL; -int log_full CAR_GLOBAL; -long log_start_time CAR_GLOBAL; +struct log_entry log[LOG_ENTRIES]; +uint8_t log_index; +int log_full; +long log_start_time; #endif -static uint8_t drivers_storage[256] CAR_GLOBAL; +static uint8_t drivers_storage[256]; #define STORAGE_DEBUG BIOS_DEBUG #define LOG_DEBUG (CONFIG(STORAGE_LOG) ? STORAGE_DEBUG : BIOS_NEVER) @@ -175,7 +174,7 @@ void storage_test(uint32_t bar, int full_initialization) /* Get the structure addresses */ media = NULL; if (ENV_ROMSTAGE) - media = car_get_var_ptr(drivers_storage); + media = (struct storage_media *)drivers_storage; else media = cbmem_find(CBMEM_ID_STORAGE_DATA); sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7); @@ -255,7 +254,7 @@ static void copy_storage_structures(int is_recovery) sdhci_ctrlr = (void *)(((uintptr_t)(media + 1) + 0x7) & ~7); /* Migrate the data into CBMEM */ - memcpy(media, car_get_var_ptr(drivers_storage), size); + memcpy(media, drivers_storage, size); media->ctrlr = &sdhci_ctrlr->sd_mmc_ctrlr; } From 9456d60f6597cea314be09be7cd053a631a31948 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 10:22:09 +0200 Subject: [PATCH 470/588] soc/intel/common/gspi: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms using this code have NO_CAR_GLOBAL_MIGRATION. Change-Id: I5dfbc718fd82f0511b0049383e4e93c6f15ee932 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32999 Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/gspi/gspi.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/soc/intel/common/block/gspi/gspi.c b/src/soc/intel/common/block/gspi/gspi.c index 81eb7eedec2..7fd7d0f9ae9 100644 --- a/src/soc/intel/common/block/gspi/gspi.c +++ b/src/soc/intel/common/block/gspi/gspi.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -262,15 +261,13 @@ static uint32_t gspi_get_bus_clk_mhz(unsigned int gspi_bus) return cfg[gspi_bus].speed_mhz; } -static uintptr_t gspi_base[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX] CAR_GLOBAL; +static uintptr_t gspi_base[CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX]; static uintptr_t gspi_get_bus_base_addr(unsigned int gspi_bus) { - uintptr_t *base = car_get_var_ptr(gspi_base); + if (!gspi_base[gspi_bus]) + gspi_base[gspi_bus] = gspi_calc_base_addr(gspi_bus); - if (!base[gspi_bus]) - base[gspi_bus] = gspi_calc_base_addr(gspi_bus); - - return base[gspi_bus]; + return gspi_base[gspi_bus]; } /* Parameters for GSPI controller operation. */ From 4a402feebf6d8754a8ca8d2207607efd93ef8fe4 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 10:24:16 +0200 Subject: [PATCH 471/588] drivers/emulation/qemu_debugcon: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This platform uses NO_CAR_GLOBAL_MIGRATION. Change-Id: Idc9434e5a1a8bc5ed76a9f80c9a7cfba2fd474c0 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33000 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/drivers/emulation/qemu/qemu_debugcon.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/drivers/emulation/qemu/qemu_debugcon.c b/src/drivers/emulation/qemu/qemu_debugcon.c index 3807524c5cb..b040bd83882 100644 --- a/src/drivers/emulation/qemu/qemu_debugcon.c +++ b/src/drivers/emulation/qemu/qemu_debugcon.c @@ -17,14 +17,13 @@ #include #include #include -#include -static int qemu_debugcon_detected CAR_GLOBAL; +static int qemu_debugcon_detected; void qemu_debugcon_init(void) { int detected = (inb(CONFIG_CONSOLE_QEMU_DEBUGCON_PORT) == 0xe9); - car_set_var(qemu_debugcon_detected, detected); + qemu_debugcon_detected = detected; printk(BIOS_INFO, "QEMU debugcon %s [port 0x%x]\n", detected ? "detected" : "not found", CONFIG_CONSOLE_QEMU_DEBUGCON_PORT); @@ -32,6 +31,6 @@ void qemu_debugcon_init(void) void qemu_debugcon_tx_byte(unsigned char data) { - if (car_get_var(qemu_debugcon_detected) != 0) + if (qemu_debugcon_detected != 0) outb(data, CONFIG_CONSOLE_QEMU_DEBUGCON_PORT); } From 3d6ccd0489cfc973ba6a9a47b3e5567cd3a40acb Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 27 May 2019 17:25:23 +0200 Subject: [PATCH 472/588] soc/intel/common/cse: Declare g_cse statically Change-Id: I91b6ce3b52d987e2fc0f79e550fda2891502bfe8 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33023 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/intel/common/block/cse/cse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index 302e6dec05e..e4fc6e4ff1a 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -69,7 +69,7 @@ #define MEI_HDR_CSE_ADDR (((1 << 8) - 1) << MEI_HDR_CSE_ADDR_START) -struct cse_device { +static struct cse_device { uintptr_t sec_bar; } g_cse CAR_GLOBAL; From a5eed800f3fa84ab100f7b612361c641515ee412 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 10:28:11 +0200 Subject: [PATCH 473/588] soc/intel/common/cse: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms using this code have NO_CAR_GLOBAL_MIGRATION. Change-Id: If952ad8129e1fa6e45858cb77ec99c9fec55c4a6 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33001 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/common/block/cse/cse.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/soc/intel/common/block/cse/cse.c b/src/soc/intel/common/block/cse/cse.c index e4fc6e4ff1a..7bd46ceba93 100644 --- a/src/soc/intel/common/block/cse/cse.c +++ b/src/soc/intel/common/block/cse/cse.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -71,7 +70,7 @@ static struct cse_device { uintptr_t sec_bar; -} g_cse CAR_GLOBAL; +} g_cse; /* * Initialize the device with provided temporary BAR. If BAR is 0 use a @@ -80,7 +79,6 @@ static struct cse_device { */ void heci_init(uintptr_t tempbar) { - struct cse_device *cse = car_get_var_ptr(&g_cse); #if defined(__SIMPLE_DEVICE__) pci_devfn_t dev = PCH_DEV_CSE; #else @@ -89,7 +87,7 @@ void heci_init(uintptr_t tempbar) u8 pcireg; /* Assume it is already initialized, nothing else to do */ - if (cse->sec_bar) + if (g_cse.sec_bar) return; /* Use default pre-ram bar */ @@ -111,7 +109,7 @@ void heci_init(uintptr_t tempbar) pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; pci_write_config8(dev, PCI_COMMAND, pcireg); - cse->sec_bar = tempbar; + g_cse.sec_bar = tempbar; } /* Get HECI BAR 0 from PCI configuration space */ @@ -130,20 +128,18 @@ static uint32_t get_cse_bar(void) static uint32_t read_bar(uint32_t offset) { - struct cse_device *cse = car_get_var_ptr(&g_cse); /* Reach PCI config space to get BAR in case CAR global not available */ - if (!cse->sec_bar) - cse->sec_bar = get_cse_bar(); - return read32((void *)(cse->sec_bar + offset)); + if (!g_cse.sec_bar) + g_cse.sec_bar = get_cse_bar(); + return read32((void *)(g_cse.sec_bar + offset)); } static void write_bar(uint32_t offset, uint32_t val) { - struct cse_device *cse = car_get_var_ptr(&g_cse); /* Reach PCI config space to get BAR in case CAR global not available */ - if (!cse->sec_bar) - cse->sec_bar = get_cse_bar(); - return write32((void *)(cse->sec_bar + offset), val); + if (!g_cse.sec_bar) + g_cse.sec_bar = get_cse_bar(); + return write32((void *)(g_cse.sec_bar + offset), val); } static uint32_t read_cse_csr(void) From ea6dd747e8a49cfba8add8e59bc3900bc9b598df Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 10:32:31 +0200 Subject: [PATCH 474/588] soc/intel/common/pmc: Don't use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms using this code use NO_CAR_GLOBAL_MIGRATION. Change-Id: I426dee60521045db4711cd253432c65223a64b93 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33002 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/soc/intel/common/block/pmc/pmclib.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c index f58d36246e0..564aacb55e1 100644 --- a/src/soc/intel/common/block/pmc/pmclib.c +++ b/src/soc/intel/common/block/pmc/pmclib.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -27,7 +26,7 @@ #include #include -static struct chipset_power_state power_state CAR_GLOBAL; +static struct chipset_power_state power_state; struct chipset_power_state *pmc_get_power_state(void) { @@ -38,7 +37,7 @@ struct chipset_power_state *pmc_get_power_state(void) /* cbmem is online but ptr is not populated yet */ if (ptr == NULL && !(ENV_RAMSTAGE || ENV_POSTCAR)) - return car_get_var_ptr(&power_state); + return &power_state; return ptr; } @@ -46,16 +45,14 @@ struct chipset_power_state *pmc_get_power_state(void) static void migrate_power_state(int is_recovery) { struct chipset_power_state *ps_cbmem; - struct chipset_power_state *ps_car; - ps_car = car_get_var_ptr(&power_state); ps_cbmem = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*ps_cbmem)); if (ps_cbmem == NULL) { printk(BIOS_DEBUG, "Not adding power state to cbmem!\n"); return; } - memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem)); + memcpy(ps_cbmem, &power_state, sizeof(*ps_cbmem)); } ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state) From 75c20157ab927aa1e453f710bab96618d556bb20 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Sat, 25 May 2019 10:37:26 +0200 Subject: [PATCH 475/588] drivers/intel/fsp2_0: Dont' use CAR_GLOBAL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All platforms using this code have NO_CAR_GLOBAL_MIGRATION. Change-Id: Ic50b16916261abb8c63b8fe571819af5c830ff8d Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33003 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/drivers/intel/fsp2_0/hand_off_block.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/drivers/intel/fsp2_0/hand_off_block.c b/src/drivers/intel/fsp2_0/hand_off_block.c index c5c78cabf0a..95b80200029 100644 --- a/src/drivers/intel/fsp2_0/hand_off_block.c +++ b/src/drivers/intel/fsp2_0/hand_off_block.c @@ -10,7 +10,6 @@ * (at your option) any later version. */ -#include #include #include #include @@ -100,7 +99,7 @@ struct hob_resource *fsp_hob_header_to_resource(const struct hob_header *hob) * Utilities for locating and identifying HOBs */ -static void *fsp_hob_list_ptr CAR_GLOBAL; +static void *fsp_hob_list_ptr; static void save_hob_list(int is_recovery) { @@ -122,14 +121,14 @@ const void *fsp_get_hob_list(void) uint32_t *list_loc; if (ENV_ROMSTAGE) - return (void *)car_get_var(fsp_hob_list_ptr); + return fsp_hob_list_ptr; list_loc = cbmem_find(CBMEM_ID_FSP_RUNTIME); return (list_loc) ? (void *)(uintptr_t)(*list_loc) : NULL; } void *fsp_get_hob_list_ptr(void) { - return car_get_var_ptr(&fsp_hob_list_ptr); + return &fsp_hob_list_ptr; } static const From 3d90d3bfce7b3e2a885bb4722ecb3a5c127e2882 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Sat, 25 May 2019 17:38:53 +0300 Subject: [PATCH 476/588] util/autoport: Add info about rank 1 mirroring inteltool can't detect whether address mapping is normal or mirrored, which in turn may be cause RAM initialization to fail when using spd.bin generated by inteltool. Mention this in readme as it may help someone. Change-Id: I8d24e4d9332bdcf484987581dd6941e2bf9c4f87 Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/32683 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- util/autoport/readme.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/util/autoport/readme.md b/util/autoport/readme.md index cfa8c36a386..fa349b906f2 100644 --- a/util/autoport/readme.md +++ b/util/autoport/readme.md @@ -268,6 +268,12 @@ If several slots are soldered there are two ways to handle them: not forget to copy the data on all the array elements that need it. * If they use different data, use several files. +If memory initialization is not working, in particular write training (timB) +on DIMM's second rank fails, try enbling rank 1 mirroring, which can't be +detected by inteltool. It is described by SPD field "Address Mapping from Edge +Connector to DRAM", byte `63` (`0x3f`). Bit 0 describes Rank 1 Mapping, +0 = standard, 1 = mirrored; set it to 1. Bits 1-7 are reserved. + ### `board_info.txt` `board_info.txt` is a text file used in the board status page to list all From 64fb5aa9c3e50a49d2ecc153ff8c597e203475bc Mon Sep 17 00:00:00 2001 From: John Zhao Date: Thu, 23 May 2019 16:22:21 -0700 Subject: [PATCH 477/588] soc/intel/common: Set GSPI clock value to prevent division by zero Clang Static Analyzer version 8.0.0 detects the division by zero if gspi_clk_mhz is initialized to 0. gspi_clk_mhz is referred to speed_mhz in devicetree. Set gspi_clk_mhz to 1 if it is detected as 0 in order to prevent the division by zero in DIV_ROUND_UP operation. Then the value of (ref_clk_mhz - 1) will be fed into GSPI's Serial Clock Rate value. TEST=Built and boot up to kernel. Change-Id: I6a09474bff114c57d7a9c4c232bb636ff287e4d5 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/32974 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/soc/intel/common/block/gspi/gspi.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/gspi/gspi.c b/src/soc/intel/common/block/gspi/gspi.c index 7fd7d0f9ae9..17532bf6db7 100644 --- a/src/soc/intel/common/block/gspi/gspi.c +++ b/src/soc/intel/common/block/gspi/gspi.c @@ -434,9 +434,11 @@ static uint32_t gspi_get_clk_div(unsigned int gspi_bus) { const uint32_t ref_clk_mhz = CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_CLOCK_MHZ; - const uint32_t gspi_clk_mhz = gspi_get_bus_clk_mhz(gspi_bus); + uint32_t gspi_clk_mhz = gspi_get_bus_clk_mhz(gspi_bus); + + if (!gspi_clk_mhz) + gspi_clk_mhz = 1; - assert(gspi_clk_mhz != 0); assert(ref_clk_mhz != 0); return (DIV_ROUND_UP(ref_clk_mhz, gspi_clk_mhz) - 1) & SSCR0_SCR_MASK; } From 2bb432ece634af05aade44ea55755ae3e6637acf Mon Sep 17 00:00:00 2001 From: John Zhao Date: Tue, 21 May 2019 19:32:51 -0700 Subject: [PATCH 478/588] soc/intel/common: Check bios_size and window_size after MIN operation Clang Static Analyzer version 8.0.0 detects that log2_ceil(bios_size) and log2_ceil(window_size) are garbage or undefined if the value of bios_size and window_size is zero. Check bios_size and window_size after MIN operation to prevent error. TEST=Built and boot up to kernel. Change-Id: Ifc3f3da52d129ef5d6063a46b045603a236be759 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/32924 Tested-by: build bot (Jenkins) Reviewed-by: Duncan Laurie --- src/soc/intel/common/block/fast_spi/fast_spi.c | 5 ++--- src/soc/intel/common/block/lpc/lpc_lib.c | 3 +++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/soc/intel/common/block/fast_spi/fast_spi.c b/src/soc/intel/common/block/fast_spi/fast_spi.c index 455b13ccb76..58e7db75a10 100644 --- a/src/soc/intel/common/block/fast_spi/fast_spi.c +++ b/src/soc/intel/common/block/fast_spi/fast_spi.c @@ -236,14 +236,13 @@ void fast_spi_cache_bios_region(void) /* Only the IFD BIOS region is memory mapped (at top of 4G) */ fast_spi_get_bios_region(&bios_size); - if (!bios_size) - return; - /* LOCAL APIC default address is 0xFEE0000, bios_size over 16MB will * cause memory type conflict when setting memory type to write * protection, so limit the cached bios region to be no more than 16MB. * */ bios_size = MIN(bios_size, 16 * MiB); + if (!bios_size) + return; /* Round to power of two */ alignment = 1UL << (log2_ceil(bios_size)); diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c index b3836377363..c67c43532ca 100644 --- a/src/soc/intel/common/block/lpc/lpc_lib.c +++ b/src/soc/intel/common/block/lpc/lpc_lib.c @@ -80,6 +80,9 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) /* Each IO range register can only open a 256-byte window. */ window_size = MIN(size, LPC_LGIR_MAX_WINDOW_SIZE); + if (!window_size) + return; + /* Window size must be a power of two for the AMASK to work. */ alignment = 1UL << (log2_ceil(window_size)); window_size = ALIGN_UP(window_size, alignment); From 6336ee6df936e7e67a7e3cdc8185214ae9cb668a Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Wed, 8 May 2019 18:58:55 +0200 Subject: [PATCH 479/588] sb/intel/*: Delete early_spi The file and all of it's functions are unused. Drop the dead code. Change-Id: Iaddd7a688d431d40f38293939e084d19b286aed4 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/32688 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes Reviewed-by: David Guckian Reviewed-by: Arthur Heymans --- src/soc/intel/baytrail/include/soc/romstage.h | 1 - src/soc/intel/baytrail/romstage/Makefile.inc | 1 - src/soc/intel/baytrail/romstage/early_spi.c | 60 -------- src/soc/intel/braswell/include/soc/romstage.h | 1 - src/soc/intel/braswell/romstage/Makefile.inc | 1 - src/soc/intel/braswell/romstage/early_spi.c | 63 -------- .../intel/broadwell/include/soc/romstage.h | 3 - src/soc/intel/broadwell/romstage/Makefile.inc | 1 - src/soc/intel/broadwell/romstage/spi.c | 143 ------------------ src/southbridge/intel/bd82x6x/Makefile.inc | 1 - src/southbridge/intel/bd82x6x/early_spi.c | 108 ------------- src/southbridge/intel/bd82x6x/pch.h | 1 - .../intel/fsp_rangeley/Makefile.inc | 2 +- .../intel/fsp_rangeley/early_spi.c | 108 ------------- src/southbridge/intel/fsp_rangeley/soc.h | 1 - src/southbridge/intel/ibexpeak/Makefile.inc | 2 - src/southbridge/intel/ibexpeak/pch.h | 1 - src/southbridge/intel/lynxpoint/Makefile.inc | 2 +- src/southbridge/intel/lynxpoint/early_spi.c | 108 ------------- src/southbridge/intel/lynxpoint/pch.h | 1 - 20 files changed, 2 insertions(+), 607 deletions(-) delete mode 100644 src/soc/intel/baytrail/romstage/early_spi.c delete mode 100644 src/soc/intel/braswell/romstage/early_spi.c delete mode 100644 src/soc/intel/broadwell/romstage/spi.c delete mode 100644 src/southbridge/intel/bd82x6x/early_spi.c delete mode 100644 src/southbridge/intel/fsp_rangeley/early_spi.c delete mode 100644 src/southbridge/intel/lynxpoint/early_spi.c diff --git a/src/soc/intel/baytrail/include/soc/romstage.h b/src/soc/intel/baytrail/include/soc/romstage.h index 3e8b6a27ef8..fffce7e317d 100644 --- a/src/soc/intel/baytrail/include/soc/romstage.h +++ b/src/soc/intel/baytrail/include/soc/romstage.h @@ -37,7 +37,6 @@ void gfx_init(void); void tco_disable(void); void punit_init(void); void set_max_freq(void); -int early_spi_read_wpsr(u8 *sr); #if CONFIG(ENABLE_BUILTIN_COM1) void byt_config_com1_and_enable(void); diff --git a/src/soc/intel/baytrail/romstage/Makefile.inc b/src/soc/intel/baytrail/romstage/Makefile.inc index f1a3463d201..d43a6fb6e34 100644 --- a/src/soc/intel/baytrail/romstage/Makefile.inc +++ b/src/soc/intel/baytrail/romstage/Makefile.inc @@ -5,4 +5,3 @@ romstage-y += raminit.c romstage-$(CONFIG_ENABLE_BUILTIN_COM1) += uart.c romstage-y += gfx.c romstage-y += pmc.c -romstage-y += early_spi.c diff --git a/src/soc/intel/baytrail/romstage/early_spi.c b/src/soc/intel/baytrail/romstage/early_spi.c deleted file mode 100644 index 72e9b2cdae1..00000000000 --- a/src/soc/intel/baytrail/romstage/early_spi.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -#include -#include -#include - -#define SPI_CYCLE_DELAY 10 /* 10us */ -#define SPI_CYCLE_TIMEOUT 400000 / SPI_CYCLE_DELAY /* 400ms */ - -#define SPI8(x) *((volatile u8 *)(SPI_BASE_ADDRESS + x)) -#define SPI16(x) *((volatile u16 *)(SPI_BASE_ADDRESS + x)) -#define SPI32(x) *((volatile u32 *)(SPI_BASE_ADDRESS + x)) - -/* Minimal set of commands to read wpsr from SPI. Don't use this code outside - * romstage -- it trashes the opmenu table. - * Returns 0 on success, < 0 on failure. */ -int early_spi_read_wpsr(u8 *sr) -{ - int timeout = SPI_CYCLE_TIMEOUT; - - /* No address associated with rdsr */ - SPI8(OPTYPE) = 0x0; - /* Setup opcode[0] = read wpsr */ - SPI8(OPMENU0) = 0x5; - - /* Start transaction */ - SPI16(SSFC) = DATA_CYCLE | SPI_CYCLE_GO; - - /* Wait for error / complete status */ - while (timeout--) { - u16 status = SPI16(SSFS); - if (status & FLASH_CYCLE_ERROR) { - printk(BIOS_ERR, "SPI rdsr failed\n"); - return -1; - } else if (status & CYCLE_DONE_STATUS) - break; - - udelay(SPI_CYCLE_DELAY); - } - - *sr = SPI32(FDATA0) & 0xff; - return 0; -} diff --git a/src/soc/intel/braswell/include/soc/romstage.h b/src/soc/intel/braswell/include/soc/romstage.h index 633233e6c60..4ecbd2c1f95 100644 --- a/src/soc/intel/braswell/include/soc/romstage.h +++ b/src/soc/intel/braswell/include/soc/romstage.h @@ -25,7 +25,6 @@ void gfx_init(void); void tco_disable(void); void punit_init(void); -int early_spi_read_wpsr(u8 *sr); void set_max_freq(void); /* romstage_common.c functions */ diff --git a/src/soc/intel/braswell/romstage/Makefile.inc b/src/soc/intel/braswell/romstage/Makefile.inc index c3ed415dcc9..15de8220412 100644 --- a/src/soc/intel/braswell/romstage/Makefile.inc +++ b/src/soc/intel/braswell/romstage/Makefile.inc @@ -1,3 +1,2 @@ -romstage-y += early_spi.c romstage-y += pmc.c romstage-y += romstage.c diff --git a/src/soc/intel/braswell/romstage/early_spi.c b/src/soc/intel/braswell/romstage/early_spi.c deleted file mode 100644 index 0ca5ef521fa..00000000000 --- a/src/soc/intel/braswell/romstage/early_spi.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. All rights reserved. - * Copyright (C) 2015 Intel Corp. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -#include -#include -#include - -#define SPI_CYCLE_DELAY 10 /* 10us */ -#define SPI_CYCLE_TIMEOUT (400000 / SPI_CYCLE_DELAY) /* 400ms */ - -#define SPI8(x) (*((volatile u8 *)(SPI_BASE_ADDRESS + (x)))) -#define SPI16(x) (*((volatile u16 *)(SPI_BASE_ADDRESS + (x)))) -#define SPI32(x) (*((volatile u32 *)(SPI_BASE_ADDRESS + (x)))) - -/* - * Minimal set of commands to read wpsr from SPI. Don't use this code outside - * romstage -- it trashes the opmenu table. - * Returns 0 on success, < 0 on failure. - */ -int early_spi_read_wpsr(u8 *sr) -{ - int timeout = SPI_CYCLE_TIMEOUT; - - /* No address associated with rdsr */ - SPI8(OPTYPE) = 0x0; - /* Setup opcode[0] = read wpsr */ - SPI8(OPMENU0) = 0x5; - - /* Start transaction */ - SPI16(SSFC) = DATA_CYCLE | SPI_CYCLE_GO; - - /* Wait for error / complete status */ - while (timeout--) { - u16 status = SPI16(SSFS); - if (status & FLASH_CYCLE_ERROR) { - printk(BIOS_ERR, "SPI rdsr failed\n"); - return -1; - } else if (status & CYCLE_DONE_STATUS) - break; - - udelay(SPI_CYCLE_DELAY); - } - - *sr = SPI32(FDATA0) & 0xff; - return 0; -} diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index ac8265fb4cb..cd37cf6316b 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -46,7 +46,4 @@ void intel_early_me_status(void); void enable_smbus(void); int smbus_read_byte(unsigned int device, unsigned int address); -int early_spi_read(u32 offset, u32 size, u8 *buffer); -int early_spi_read_wpsr(u8 *sr); - #endif diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc index ea17d67061e..a53cd95cd52 100644 --- a/src/soc/intel/broadwell/romstage/Makefile.inc +++ b/src/soc/intel/broadwell/romstage/Makefile.inc @@ -6,6 +6,5 @@ romstage-y += raminit.c romstage-y += report_platform.c romstage-y += romstage.c romstage-y += smbus.c -romstage-y += spi.c romstage-y += systemagent.c romstage-$(CONFIG_DRIVERS_UART_8250MEM) += uart.c diff --git a/src/soc/intel/broadwell/romstage/spi.c b/src/soc/intel/broadwell/romstage/spi.c deleted file mode 100644 index cb0509d104d..00000000000 --- a/src/soc/intel/broadwell/romstage/spi.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include - -#define SPI_DELAY 10 /* 10us */ -#define SPI_RETRY 200000 /* 2s */ - -static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) -{ - u32 *ptr32 = (u32 *)buffer; - u32 i; - - /* Clear status bits */ - SPIBAR16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR | - SPIBAR_HSFS_FDONE; - - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - printk(BIOS_ERR, "SPI ERROR: transaction in progress\n"); - return -1; - } - - /* Set flash address */ - SPIBAR32(SPIBAR_FADDR) = offset; - - /* Setup read transaction */ - SPIBAR16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) | - SPIBAR_HSFC_CYCLE_READ; - - /* Start transaction */ - SPIBAR16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO; - - /* Wait for completion */ - for (i = 0; i < SPI_RETRY; i++) { - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - /* Cycle in progress, wait 1ms */ - udelay(SPI_DELAY); - continue; - } - - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { - printk(BIOS_ERR, "SPI ERROR: Access Error\n"); - return -1; - - } - - if (SPIBAR16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { - printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n"); - return -1; - } - break; - } - - if (i >= SPI_RETRY) { - printk(BIOS_ERR, "SPI ERROR: Timeout\n"); - return -1; - } - - /* Read the data */ - for (i = 0; i < size; i += sizeof(u32)) { - if (size-i >= 4) { - /* reading >= dword */ - *ptr32++ = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32))); - } else { - /* reading < dword */ - u8 j, *ptr8 = (u8 *)ptr32; - u32 temp = SPIBAR32(SPIBAR_FDATA(i/sizeof(u32))); - for (j = 0; j < (size-i); j++) { - *ptr8++ = temp & 0xff; - temp >>= 8; - } - } - } - - return size; -} - -int early_spi_read(u32 offset, u32 size, u8 *buffer) -{ - u32 current = 0; - - while (size > 0) { - u8 count = (size < 64) ? size : 64; - if (early_spi_read_block(offset + current, count, - buffer + current) < 0) - return -1; - size -= count; - current += count; - } - - return 0; -} - -/* - * Minimal set of commands to read WPSR from SPI. - * Don't use this code outside romstage -- it trashes the opmenu table. - * Returns 0 on success, < 0 on failure. - */ -int early_spi_read_wpsr(u8 *sr) -{ - int retry; - - /* No address associated with rdsr */ - SPIBAR8(SPIBAR_OPTYPE) = 0x0; - /* Setup opcode[0] = read wpsr */ - SPIBAR8(SPIBAR_OPMENU_LOWER) = 0x5; - - /* Start transaction */ - SPIBAR16(SPIBAR_SSFC) = SPIBAR_SSFC_DATA | SPIBAR_SSFC_GO; - - /* Wait for error / complete status */ - for (retry = SPI_RETRY; retry; retry--) { - u16 status = SPIBAR16(SPIBAR_SSFS); - if (status & SPIBAR_SSFS_ERROR) { - printk(BIOS_ERR, "SPI rdsr failed\n"); - return -1; - } else if (status & SPIBAR_SSFS_DONE) { - break; - } - - udelay(SPI_DELAY); - } - - *sr = SPIBAR32(SPIBAR_FDATA(0)) & 0xff; - return 0; -} diff --git a/src/southbridge/intel/bd82x6x/Makefile.inc b/src/southbridge/intel/bd82x6x/Makefile.inc index 023f5d32c27..b6023b00b37 100644 --- a/src/southbridge/intel/bd82x6x/Makefile.inc +++ b/src/southbridge/intel/bd82x6x/Makefile.inc @@ -37,7 +37,6 @@ ramstage-$(CONFIG_ELOG) += elog.c smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me.c me_8.x.c pch.c romstage-y += early_smbus.c me_status.c -romstage-y += early_spi.c romstage-y += early_rcba.c romstage-y += early_pch.c diff --git a/src/southbridge/intel/bd82x6x/early_spi.c b/src/southbridge/intel/bd82x6x/early_spi.c deleted file mode 100644 index 3034930a06e..00000000000 --- a/src/southbridge/intel/bd82x6x/early_spi.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "pch.h" - -#define SPI_DELAY 10 /* 10us */ -#define SPI_RETRY 200000 /* 2s */ - -static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) -{ - u32 *ptr32 = (u32*)buffer; - u32 i; - - /* Clear status bits */ - RCBA16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR | - SPIBAR_HSFS_FDONE; - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - printk(BIOS_ERR, "SPI ERROR: transaction in progress\n"); - return -1; - } - - /* Set flash address */ - RCBA32(SPIBAR_FADDR) = offset; - - /* Setup read transaction */ - RCBA16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) | - SPIBAR_HSFC_CYCLE_READ; - - /* Start transactinon */ - RCBA16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO; - - /* Wait for completion */ - for (i = 0; i < SPI_RETRY; i++) { - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - /* Cycle in progress, wait 1ms */ - udelay(SPI_DELAY); - continue; - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { - printk(BIOS_ERR, "SPI ERROR: Access Error\n"); - return -1; - - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { - printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n"); - return -1; - } - break; - } - - if (i >= SPI_RETRY) { - printk(BIOS_ERR, "SPI ERROR: Timeout\n"); - return -1; - } - - /* Read the data */ - for (i = 0; i < size; i+=sizeof(u32)) { - if (size-i >= 4) { - /* reading >= dword */ - *ptr32++ = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - } else { - /* reading < dword */ - u8 j, *ptr8 = (u8*)ptr32; - u32 temp = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - for (j = 0; j < (size-i); j++) { - *ptr8++ = temp & 0xff; - temp >>= 8; - } - } - } - - return size; -} - -int early_spi_read(u32 offset, u32 size, u8 *buffer) -{ - u32 current = 0; - - while (size > 0) { - u8 count = (size < 64) ? size : 64; - if (early_spi_read_block(offset + current, count, - buffer + current) < 0) - return -1; - size -= count; - current += count; - } - - return 0; -} diff --git a/src/southbridge/intel/bd82x6x/pch.h b/src/southbridge/intel/bd82x6x/pch.h index faa6822bf22..4369b5c162f 100644 --- a/src/southbridge/intel/bd82x6x/pch.h +++ b/src/southbridge/intel/bd82x6x/pch.h @@ -70,7 +70,6 @@ void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue); void enable_smbus(void); void enable_usb_bar(void); int smbus_read_byte(unsigned device, unsigned address); -int early_spi_read(u32 offset, u32 size, u8 *buffer); void early_thermal_init(void); void southbridge_configure_default_intmap(void); void southbridge_rcba_config(void); diff --git a/src/southbridge/intel/fsp_rangeley/Makefile.inc b/src/southbridge/intel/fsp_rangeley/Makefile.inc index 7fc86012dec..67a51af15a6 100644 --- a/src/southbridge/intel/fsp_rangeley/Makefile.inc +++ b/src/southbridge/intel/fsp_rangeley/Makefile.inc @@ -23,7 +23,7 @@ ramstage-y += spi.c ramstage-y += smbus.c ramstage-y += acpi.c -romstage-y += early_usb.c early_smbus.c gpio.c early_spi.c early_init.c +romstage-y += early_usb.c early_smbus.c gpio.c early_init.c romstage-y += romstage.c bootblock-$(CONFIG_USBDEBUG) += usb_debug.c diff --git a/src/southbridge/intel/fsp_rangeley/early_spi.c b/src/southbridge/intel/fsp_rangeley/early_spi.c deleted file mode 100644 index 7b20cdb9a79..00000000000 --- a/src/southbridge/intel/fsp_rangeley/early_spi.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "soc.h" - -#define SPI_DELAY 10 /* 10us */ -#define SPI_RETRY 200000 /* 2s */ - -static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) -{ - u32 *ptr32 = (u32*)buffer; - u32 i; - - /* Clear status bits */ - RCBA16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR | - SPIBAR_HSFS_FDONE; - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - printk(BIOS_ERR, "SPI ERROR: transaction in progress\n"); - return -1; - } - - /* Set flash address */ - RCBA32(SPIBAR_FADDR) = offset; - - /* Setup read transaction */ - RCBA16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) | - SPIBAR_HSFC_CYCLE_READ; - - /* Start transaction */ - RCBA16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO; - - /* Wait for completion */ - for (i = 0; i < SPI_RETRY; i++) { - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - /* Cycle in progress, wait 1ms */ - udelay(SPI_DELAY); - continue; - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { - printk(BIOS_ERR, "SPI ERROR: Access Error\n"); - return -1; - - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { - printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n"); - return -1; - } - break; - } - - if (i >= SPI_RETRY) { - printk(BIOS_ERR, "SPI ERROR: Timeout\n"); - return -1; - } - - /* Read the data */ - for (i = 0; i < size; i+=sizeof(u32)) { - if (size-i >= 4) { - /* reading >= dword */ - *ptr32++ = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - } else { - /* reading < dword */ - u8 j, *ptr8 = (u8*)ptr32; - u32 temp = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - for (j = 0; j < (size-i); j++) { - *ptr8++ = temp & 0xff; - temp >>= 8; - } - } - } - - return size; -} - -int early_spi_read(u32 offset, u32 size, u8 *buffer) -{ - u32 current = 0; - - while (size > 0) { - u8 count = (size < 64) ? size : 64; - if (early_spi_read_block(offset + current, count, - buffer + current) < 0) - return -1; - size -= count; - current += count; - } - - return 0; -} diff --git a/src/southbridge/intel/fsp_rangeley/soc.h b/src/southbridge/intel/fsp_rangeley/soc.h index 4c5e835c7f8..aceb425ab71 100644 --- a/src/southbridge/intel/fsp_rangeley/soc.h +++ b/src/southbridge/intel/fsp_rangeley/soc.h @@ -68,7 +68,6 @@ void soc_log_state(void); void enable_smbus(void); void enable_usb_bar(void); int smbus_read_byte(unsigned device, unsigned address); -int early_spi_read(u32 offset, u32 size, u8 *buffer); void rangeley_sb_early_initialization(void); #endif #endif diff --git a/src/southbridge/intel/ibexpeak/Makefile.inc b/src/southbridge/intel/ibexpeak/Makefile.inc index 24eac22b9fd..fccb3a86565 100644 --- a/src/southbridge/intel/ibexpeak/Makefile.inc +++ b/src/southbridge/intel/ibexpeak/Makefile.inc @@ -39,7 +39,5 @@ smm-y += smihandler.c me.c ../bd82x6x/me_8.x.c ../bd82x6x/pch.c romstage-y += ../bd82x6x/early_usb.c early_smbus.c ../bd82x6x/early_me.c ../bd82x6x/me_status.c ../common/gpio.c early_thermal.c romstage-y += ../bd82x6x/early_rcba.c -romstage-$(CONFIG_SOUTHBRIDGE_INTEL_BD82X6X) += ../bd82x6x/early_spi.c -romstage-$(CONFIG_SOUTHBRIDGE_INTEL_C216) += ../bd82x6x/early_spi.c endif diff --git a/src/southbridge/intel/ibexpeak/pch.h b/src/southbridge/intel/ibexpeak/pch.h index 90e7102ed25..04cc21d4754 100644 --- a/src/southbridge/intel/ibexpeak/pch.h +++ b/src/southbridge/intel/ibexpeak/pch.h @@ -71,7 +71,6 @@ int smbus_read_byte(unsigned device, unsigned address); int smbus_write_byte(unsigned device, unsigned address, u8 data); int smbus_block_read(unsigned device, unsigned cmd, u8 bytes, u8 *buf); int smbus_block_write(unsigned device, unsigned cmd, u8 bytes, const u8 *buf); -int early_spi_read(u32 offset, u32 size, u8 *buffer); void early_thermal_init(void); void southbridge_configure_default_intmap(void); #endif diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc index f0bfa5bcc3c..3e3ef35e2d9 100644 --- a/src/southbridge/intel/lynxpoint/Makefile.inc +++ b/src/southbridge/intel/lynxpoint/Makefile.inc @@ -47,7 +47,7 @@ smm-$(CONFIG_HAVE_SMI_HANDLER) += pmutil.c usb_ehci.c usb_xhci.c bootblock-y += early_pch.c romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c -romstage-y += early_spi.c rcba.c pmutil.c +romstage-y += rcba.c pmutil.c ifeq ($(CONFIG_INTEL_LYNXPOINT_LP),y) romstage-y += lp_gpio.c diff --git a/src/southbridge/intel/lynxpoint/early_spi.c b/src/southbridge/intel/lynxpoint/early_spi.c deleted file mode 100644 index 3034930a06e..00000000000 --- a/src/southbridge/intel/lynxpoint/early_spi.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. All rights reserved. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; version 2 of - * the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include "pch.h" - -#define SPI_DELAY 10 /* 10us */ -#define SPI_RETRY 200000 /* 2s */ - -static int early_spi_read_block(u32 offset, u8 size, u8 *buffer) -{ - u32 *ptr32 = (u32*)buffer; - u32 i; - - /* Clear status bits */ - RCBA16(SPIBAR_HSFS) |= SPIBAR_HSFS_AEL | SPIBAR_HSFS_FCERR | - SPIBAR_HSFS_FDONE; - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - printk(BIOS_ERR, "SPI ERROR: transaction in progress\n"); - return -1; - } - - /* Set flash address */ - RCBA32(SPIBAR_FADDR) = offset; - - /* Setup read transaction */ - RCBA16(SPIBAR_HSFC) = SPIBAR_HSFC_BYTE_COUNT(size) | - SPIBAR_HSFC_CYCLE_READ; - - /* Start transactinon */ - RCBA16(SPIBAR_HSFC) |= SPIBAR_HSFC_GO; - - /* Wait for completion */ - for (i = 0; i < SPI_RETRY; i++) { - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_SCIP) { - /* Cycle in progress, wait 1ms */ - udelay(SPI_DELAY); - continue; - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_AEL) { - printk(BIOS_ERR, "SPI ERROR: Access Error\n"); - return -1; - - } - - if (RCBA16(SPIBAR_HSFS) & SPIBAR_HSFS_FCERR) { - printk(BIOS_ERR, "SPI ERROR: Flash Cycle Error\n"); - return -1; - } - break; - } - - if (i >= SPI_RETRY) { - printk(BIOS_ERR, "SPI ERROR: Timeout\n"); - return -1; - } - - /* Read the data */ - for (i = 0; i < size; i+=sizeof(u32)) { - if (size-i >= 4) { - /* reading >= dword */ - *ptr32++ = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - } else { - /* reading < dword */ - u8 j, *ptr8 = (u8*)ptr32; - u32 temp = RCBA32(SPIBAR_FDATA(i/sizeof(u32))); - for (j = 0; j < (size-i); j++) { - *ptr8++ = temp & 0xff; - temp >>= 8; - } - } - } - - return size; -} - -int early_spi_read(u32 offset, u32 size, u8 *buffer) -{ - u32 current = 0; - - while (size > 0) { - u8 count = (size < 64) ? size : 64; - if (early_spi_read_block(offset + current, count, - buffer + current) < 0) - return -1; - size -= count; - current += count; - } - - return 0; -} diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h index 97d0aa33b3c..93c2bc5703e 100644 --- a/src/southbridge/intel/lynxpoint/pch.h +++ b/src/southbridge/intel/lynxpoint/pch.h @@ -195,7 +195,6 @@ void southbridge_smm_enable_smi(void); void enable_smbus(void); void enable_usb_bar(void); int smbus_read_byte(unsigned device, unsigned address); -int early_spi_read(u32 offset, u32 size, u8 *buffer); int early_pch_init(const void *gpio_map, const struct rcba_config_instruction *rcba_config); void pch_enable_lpc(void); From 57448845ff549f9aa75c3d49c9b292accb5dbc99 Mon Sep 17 00:00:00 2001 From: John Zhao Date: Mon, 20 May 2019 16:10:16 -0700 Subject: [PATCH 480/588] soc/intel/apollolake: Fix value stored to gnvs is never read Clang Static Analyzer found version 8.0.0 gnvs is allocated, but it is never used. Change sizeof(*gnvs) to sizeof(global_nvs_t) while adding ACPI GNVS to CBMEM. TEST=Built and boot up to kernel. Change-Id: Ie9421af4a556d1d88183aa938ee2a124a10ab727 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/32903 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- src/soc/intel/apollolake/chip.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/soc/intel/apollolake/chip.c b/src/soc/intel/apollolake/chip.c index f6880a7f3f1..e9030dc2df6 100644 --- a/src/soc/intel/apollolake/chip.c +++ b/src/soc/intel/apollolake/chip.c @@ -389,8 +389,6 @@ static void set_sci_irq(void) static void soc_init(void *data) { - struct global_nvs_t *gnvs; - /* Snapshot the current GPIO IRQ polarities. FSP is setting a * default policy that doesn't honor boards' requirements. */ itss_snapshot_irq_polarities(GPIO_IRQ_START, GPIO_IRQ_END); @@ -418,7 +416,7 @@ static void soc_init(void *data) p2sb_unhide(); /* Allocate ACPI NVS in CBMEM */ - gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(*gnvs)); + cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof(struct global_nvs_t)); /* Set RAPL MSR for Package power limits*/ set_power_limits(); From 342d3180d7134be92db03190205849d514ac33a8 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 24 May 2019 13:03:43 +0200 Subject: [PATCH 481/588] Makefile.inc: Extend version string for timeless builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With the version string "TIMELESS", binaries are slightly smaller than for a regular build. This may lead to false positive build tests if the space is limited (e.g. bootblock). So let's make the string a little longer. Change-Id: I3bbf6f71d5bcd74728a3fe39734312690901d0ec Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32986 Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- Makefile.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.inc b/Makefile.inc index 9860da1b681..d4f7597e82d 100644 --- a/Makefile.inc +++ b/Makefile.inc @@ -31,7 +31,7 @@ CONFIG_OVERRIDE_DEVICETREE:=$(call strip_quotes, $(CONFIG_OVERRIDE_DEVICETREE)) # misleadingly named, this is the coreboot version ifeq ($(KERNELVERSION),) ifeq ($(BUILD_TIMELESS),1) -KERNELVERSION := TIMELESS +KERNELVERSION := -TIMELESS--LESSTIME- else KERNELVERSION := $(strip $(if $(GIT),\ $(shell git describe --dirty --always || git describe),\ From 348a44ecae1eb67e9b4e062926e7028012b21ca2 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 27 May 2019 02:19:17 -0500 Subject: [PATCH 482/588] mb/google/{misc}: set default SMBIOS manufacturer Legacy Google mainboards (pre-Skylake) shipped with the SMBIOS manufacturer set to GOOGLE, which many Linux drivers rely on for application of DMI quirks. Set it as the default to avoid having to do so for each board's config Change-Id: I61b0217f3535852d7d6e24a1ac78075c20c0825a Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/33027 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- src/mainboard/google/auron/Kconfig | 4 ++++ src/mainboard/google/beltino/Kconfig | 4 ++++ src/mainboard/google/butterfly/Kconfig | 4 ++++ src/mainboard/google/cyan/Kconfig | 4 ++++ src/mainboard/google/jecht/Kconfig | 4 ++++ src/mainboard/google/link/Kconfig | 5 +++++ src/mainboard/google/parrot/Kconfig | 4 ++++ src/mainboard/google/rambi/Kconfig | 4 ++++ src/mainboard/google/slippy/Kconfig | 3 +++ src/mainboard/google/stout/Kconfig | 4 ++++ 10 files changed, 40 insertions(+) diff --git a/src/mainboard/google/auron/Kconfig b/src/mainboard/google/auron/Kconfig index 3f350e8dd2a..69b086fefea 100644 --- a/src/mainboard/google/auron/Kconfig +++ b/src/mainboard/google/auron/Kconfig @@ -72,4 +72,8 @@ config VGA_BIOS_FILE string default "pci8086,0406.rom" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif diff --git a/src/mainboard/google/beltino/Kconfig b/src/mainboard/google/beltino/Kconfig index 872d49ddeec..df5da9df20d 100644 --- a/src/mainboard/google/beltino/Kconfig +++ b/src/mainboard/google/beltino/Kconfig @@ -59,4 +59,8 @@ config VGA_BIOS_FILE string default "pci8086,0406.rom" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_BASEBOARD_BELTINO diff --git a/src/mainboard/google/butterfly/Kconfig b/src/mainboard/google/butterfly/Kconfig index 24797be46c7..76bcc3d3b09 100644 --- a/src/mainboard/google/butterfly/Kconfig +++ b/src/mainboard/google/butterfly/Kconfig @@ -44,4 +44,8 @@ config MAINBOARD_VENDOR string default "Hewlett-Packard" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_BUTTERFLY diff --git a/src/mainboard/google/cyan/Kconfig b/src/mainboard/google/cyan/Kconfig index aac14c06c30..bf0cd095f7a 100644 --- a/src/mainboard/google/cyan/Kconfig +++ b/src/mainboard/google/cyan/Kconfig @@ -112,4 +112,8 @@ config CBFS_SIZE hex default 0x200000 +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_BASEBOARD_CYAN diff --git a/src/mainboard/google/jecht/Kconfig b/src/mainboard/google/jecht/Kconfig index 15ed05b04be..5ffc1bc435a 100644 --- a/src/mainboard/google/jecht/Kconfig +++ b/src/mainboard/google/jecht/Kconfig @@ -53,4 +53,8 @@ config VGA_BIOS_FILE string default "pci8086,0406.rom" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index 612a1b59871..3628f1d8a54 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -45,4 +45,9 @@ config GBB_HWID string depends on CHROMEOS default "X86 LINK TEST 6638" + +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_LINK diff --git a/src/mainboard/google/parrot/Kconfig b/src/mainboard/google/parrot/Kconfig index 4403d792f76..daf605d436e 100644 --- a/src/mainboard/google/parrot/Kconfig +++ b/src/mainboard/google/parrot/Kconfig @@ -41,4 +41,8 @@ config VGA_BIOS_FILE string default "pci8086,0106.rom" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_PARROT diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index 6d0c0dfce06..c47b3d79090 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -94,4 +94,8 @@ config VGA_BIOS_FILE string default "pci8086,0f31.rom" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_BASEBOARD_RAMBI diff --git a/src/mainboard/google/slippy/Kconfig b/src/mainboard/google/slippy/Kconfig index ecc8aff5ba6..242876da86b 100644 --- a/src/mainboard/google/slippy/Kconfig +++ b/src/mainboard/google/slippy/Kconfig @@ -71,5 +71,8 @@ config VGA_BIOS_FILE config INTEL_GMA_VBT_FILE default "src/mainboard/$(MAINBOARDDIR)/data.vbt" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" endif # BOARD_GOOGLE_BASEBOARD_SLIPPY diff --git a/src/mainboard/google/stout/Kconfig b/src/mainboard/google/stout/Kconfig index 7096d937c7e..dfe687b0ff6 100644 --- a/src/mainboard/google/stout/Kconfig +++ b/src/mainboard/google/stout/Kconfig @@ -43,4 +43,8 @@ config VGA_BIOS_ID string default "8086,0156" +config MAINBOARD_SMBIOS_MANUFACTURER + string + default "GOOGLE" + endif # BOARD_GOOGLE_STOUT From 924463d1a58075c208b008e13d8b0ec2f2b8731a Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sun, 26 May 2019 16:25:24 -0500 Subject: [PATCH 483/588] google/clapper: fix up devicetree When clapper was upstreamed, the devicetree was pulled from the wrong firmware branch, leading to some incorrect settings and touchpad, touchscreen, and audio not working. Correct devicetree settings using Chromium branch firmware-clapper-5216.199.B Test: build/boot google/clapper, verify touchpad/touchscreen/audio functional under Linux (GalliumOS 3.0/kernel 4.16.18). Change-Id: Iacfce575a054b1f484149f36d0aa83d20d034d8a Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/33025 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans --- .../rambi/variants/clapper/devicetree.cb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/mainboard/google/rambi/variants/clapper/devicetree.cb b/src/mainboard/google/rambi/variants/clapper/devicetree.cb index 1e50e53c770..c010af1e73c 100644 --- a/src/mainboard/google/rambi/variants/clapper/devicetree.cb +++ b/src/mainboard/google/rambi/variants/clapper/devicetree.cb @@ -32,16 +32,25 @@ chip soc/intel/baytrail register "sdcard_cap_high" = "0x0" # Enable devices in ACPI mode + register "lpe_acpi_mode" = "1" + register "lpss_acpi_mode" = "1" register "scc_acpi_mode" = "1" # Enable PIPEA as DP_C register "gpu_pipea_port_select" = "2" # DP_C - register "gpu_pipea_power_cycle_delay" = "5" # 400ms - register "gpu_pipea_power_on_delay" = "2000" # 200ms - register "gpu_pipea_light_on_delay" = "10" # 1ms + register "gpu_pipea_power_cycle_delay" = "6" # 600ms + register "gpu_pipea_power_on_delay" = "5000" # 500ms + register "gpu_pipea_light_on_delay" = "70" # 7ms register "gpu_pipea_power_off_delay" = "500" # 50ms register "gpu_pipea_light_off_delay" = "2000" # 200ms + # VR PS2 control + register "vnn_ps2_enable" = "1" + register "vcc_ps2_enable" = "1" + + # Disable SLP_X stretching after SUS power well fail. + register "disable_slp_x_stretch_sus_fail" = "1" + device cpu_cluster 0 on device lapic 0 on end end @@ -59,11 +68,11 @@ chip soc/intel/baytrail device pci 18.2 on end # I2C2 device pci 18.3 off end # I2C3 device pci 18.4 off end # I2C4 - device pci 18.5 off end # I2C5 + device pci 18.5 on end # I2C5 device pci 18.6 on end # I2C6 device pci 18.7 off end # I2C7 device pci 1a.0 off end # TXE - device pci 1b.0 off end # HDA + device pci 1b.0 on end # HDA device pci 1c.0 on end # PCIE_PORT1 device pci 1c.1 on end # PCIE_PORT2 device pci 1c.2 off end # PCIE_PORT3 From bdcb4d37506f04e205f11ff45fd0925cf2a5cbc1 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Mon, 27 May 2019 17:10:24 -0600 Subject: [PATCH 484/588] drivers/generic/max98357a: Add extra error handling It is possible that acpi_device_scope() and acpi_device_name() can return NULL to indicate an error, so add error handling to check their return values. Change-Id: I4c7ab0c592845d9d5f142e078fc2b505a99ecd12 Signed-off-by: Jacob Garber Found-by: Coverity CID 1362592 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33028 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/drivers/generic/max98357a/max98357a.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/drivers/generic/max98357a/max98357a.c b/src/drivers/generic/max98357a/max98357a.c index 1408dacca61..838491dc84e 100644 --- a/src/drivers/generic/max98357a/max98357a.c +++ b/src/drivers/generic/max98357a/max98357a.c @@ -36,9 +36,14 @@ static void max98357a_fill_ssdt(struct device *dev) if (!dev->enabled || !config) return; + const char *scope = acpi_device_scope(dev); + const char *name = acpi_device_name(dev); + if (!scope || !name) + return; + /* Device */ - acpigen_write_scope(acpi_device_scope(dev)); - acpigen_write_device(acpi_device_name(dev)); + acpigen_write_scope(scope); + acpigen_write_device(name); acpigen_write_name_string("_HID", MAX98357A_ACPI_HID); acpigen_write_name_integer("_UID", 0); acpigen_write_name_string("_DDN", dev->chip_ops->name); From 5b922726e1220585cbae4e0392817dcca3a2b11f Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 28 May 2019 11:47:49 -0600 Subject: [PATCH 485/588] cpu/x86/mtrr: Assert that MSR arrays are fully initialized The initialization logic for the fixed_msrs and msr_index arrays depends on the contents of the fixed MTRR descriptor. However, Coverity is unable to check these values and believes (incorrectly) that the arrays may not be entirely initialized. An assert was added in commit b28025a434 to ensure that one of the loops is entered, but it is simplest to just check that msr_num has iterated over the entire array after the loops are over. This also acts as a sanity check that the values in the MTRR descriptor were hardcoded correctly. Change-Id: Ia573792f74aa6ea5e659c1e2253f112184fbb0a5 Signed-off-by: Jacob Garber Found-by: Coverity CID 1370582 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33048 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/cpu/x86/mtrr/mtrr.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index d87c3d43d30..60eee319cee 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -331,7 +331,6 @@ static void commit_fixed_mtrrs(void) desc = &fixed_mtrr_desc[i]; num_ranges = (desc->end - desc->begin) / desc->step; - ASSERT(num_ranges > 0); for (j = 0; j < num_ranges; j += RANGES_PER_FIXED_MTRR) { msr_index[msr_num] = desc->msr_index_base + (j / RANGES_PER_FIXED_MTRR); @@ -355,6 +354,9 @@ static void commit_fixed_mtrrs(void) } } + /* Ensure that both arrays were fully initialized */ + ASSERT(msr_num == NUM_FIXED_MTRRS) + for (i = 0; i < ARRAY_SIZE(fixed_msrs); i++) printk(BIOS_DEBUG, "MTRR: Fixed MSR 0x%lx 0x%08x%08x\n", msr_index[i], fixed_msrs[i].hi, fixed_msrs[i].lo); From 3f4a987beefc8cb66ba3f9fff5405cdad8933fd6 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Thu, 23 May 2019 12:31:24 +0200 Subject: [PATCH 486/588] commonlib: renumber CB_TAG_TCPA_LOG It conflicts with VBOOT_WORKBUF but unlike VBOOT_WORKBUF no user can be identified in the coreboot tree for TCPA_LOG, so renumber this. Change-Id: Ib8a850c0ccbcacdf7d288316b54eb82fce874a82 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32955 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/commonlib/include/commonlib/coreboot_tables.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index bbc8608266f..0873dcc2eb4 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -310,7 +310,7 @@ void lb_ramoops(struct lb_header *header); #define LB_TAG_CBMEM_CONSOLE 0x0017 #define LB_TAG_MRC_CACHE 0x0018 #define LB_TAG_ACPI_GNVS 0x0024 -#define LB_TAG_TCPA_LOG 0x0034 +#define LB_TAG_TCPA_LOG 0x0036 #define LB_TAG_WIFI_CALIBRATION 0x0027 #define LB_TAG_VPD 0x002c struct lb_cbmem_ref { From 68999a8b869be132f1c8c242d9a6167896920be3 Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Thu, 23 May 2019 12:44:00 +0200 Subject: [PATCH 487/588] commonlib: fix typo LB_TAB_* (instead of LB_TAG_*) Also adapt all users of these symbols Change-Id: Ibf924a283d438de49a93ce661b0d9ca1a81cd6d1 Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/32956 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/commonlib/include/commonlib/coreboot_tables.h | 6 +++--- src/lib/coreboot_table.c | 4 ++-- src/mainboard/google/daisy/mainboard.c | 2 +- src/mainboard/google/gale/mainboard.c | 2 +- src/mainboard/google/nyan/mainboard.c | 2 +- src/mainboard/google/nyan_big/mainboard.c | 2 +- src/mainboard/google/nyan_blaze/mainboard.c | 2 +- src/mainboard/google/peach_pit/mainboard.c | 2 +- src/mainboard/google/storm/mainboard.c | 2 +- src/mainboard/google/urara/mainboard.c | 2 +- src/mainboard/google/veyron/mainboard.c | 2 +- src/mainboard/google/veyron_mickey/mainboard.c | 2 +- src/mainboard/google/veyron_rialto/mainboard.c | 2 +- 13 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/commonlib/include/commonlib/coreboot_tables.h b/src/commonlib/include/commonlib/coreboot_tables.h index 0873dcc2eb4..277b7467fba 100644 --- a/src/commonlib/include/commonlib/coreboot_tables.h +++ b/src/commonlib/include/commonlib/coreboot_tables.h @@ -291,9 +291,9 @@ struct lb_gpios { }; #define LB_TAG_VBNV 0x0019 -#define LB_TAB_VBOOT_HANDOFF 0x0020 -#define LB_TAB_VBOOT_WORKBUF 0x0034 -#define LB_TAB_DMA 0x0022 +#define LB_TAG_VBOOT_HANDOFF 0x0020 +#define LB_TAG_VBOOT_WORKBUF 0x0034 +#define LB_TAG_DMA 0x0022 #define LB_TAG_RAM_OOPS 0x0023 #define LB_TAG_MTC 0x002b struct lb_range { diff --git a/src/lib/coreboot_table.c b/src/lib/coreboot_table.c index 14cd0302026..df756983d0a 100644 --- a/src/lib/coreboot_table.c +++ b/src/lib/coreboot_table.c @@ -219,7 +219,7 @@ static void lb_vboot_handoff(struct lb_header *header) return; vbho = (struct lb_range *)lb_new_record(header); - vbho->tag = LB_TAB_VBOOT_HANDOFF; + vbho->tag = LB_TAG_VBOOT_HANDOFF; vbho->size = sizeof(*vbho); vbho->range_start = (intptr_t)addr; vbho->range_size = size; @@ -231,7 +231,7 @@ static void lb_vboot_workbuf(struct lb_header *header) struct vboot_working_data *wd = vboot_get_working_data(); vbwb = (struct lb_range *)lb_new_record(header); - vbwb->tag = LB_TAB_VBOOT_WORKBUF; + vbwb->tag = LB_TAG_VBOOT_WORKBUF; vbwb->size = sizeof(*vbwb); vbwb->range_start = (uintptr_t)wd + wd->buffer_offset; vbwb->range_size = wd->buffer_size; diff --git a/src/mainboard/google/daisy/mainboard.c b/src/mainboard/google/daisy/mainboard.c index e812189923c..46939b70e9d 100644 --- a/src/mainboard/google/daisy/mainboard.c +++ b/src/mainboard/google/daisy/mainboard.c @@ -350,7 +350,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/gale/mainboard.c b/src/mainboard/google/gale/mainboard.c index c8ab88a7fa9..8025374efa1 100644 --- a/src/mainboard/google/gale/mainboard.c +++ b/src/mainboard/google/gale/mainboard.c @@ -74,7 +74,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/nyan/mainboard.c b/src/mainboard/google/nyan/mainboard.c index b1cf19e2584..807cec3f3f4 100644 --- a/src/mainboard/google/nyan/mainboard.c +++ b/src/mainboard/google/nyan/mainboard.c @@ -259,7 +259,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/nyan_big/mainboard.c b/src/mainboard/google/nyan_big/mainboard.c index c0769f1b00f..c8bb8136d46 100644 --- a/src/mainboard/google/nyan_big/mainboard.c +++ b/src/mainboard/google/nyan_big/mainboard.c @@ -257,7 +257,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/nyan_blaze/mainboard.c b/src/mainboard/google/nyan_blaze/mainboard.c index a296092a192..97d05762783 100644 --- a/src/mainboard/google/nyan_blaze/mainboard.c +++ b/src/mainboard/google/nyan_blaze/mainboard.c @@ -257,7 +257,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/peach_pit/mainboard.c b/src/mainboard/google/peach_pit/mainboard.c index 0441e529897..ecd2260511d 100644 --- a/src/mainboard/google/peach_pit/mainboard.c +++ b/src/mainboard/google/peach_pit/mainboard.c @@ -485,7 +485,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/storm/mainboard.c b/src/mainboard/google/storm/mainboard.c index fdff5ab0f45..783e6ad7a13 100644 --- a/src/mainboard/google/storm/mainboard.c +++ b/src/mainboard/google/storm/mainboard.c @@ -119,7 +119,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/urara/mainboard.c b/src/mainboard/google/urara/mainboard.c index 3eaad3451e5..7bf8b908a39 100644 --- a/src/mainboard/google/urara/mainboard.c +++ b/src/mainboard/google/urara/mainboard.c @@ -43,7 +43,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/veyron/mainboard.c b/src/mainboard/google/veyron/mainboard.c index d8ac310643c..5243dc9290b 100644 --- a/src/mainboard/google/veyron/mainboard.c +++ b/src/mainboard/google/veyron/mainboard.c @@ -123,7 +123,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/veyron_mickey/mainboard.c b/src/mainboard/google/veyron_mickey/mainboard.c index bb239732b5b..9024b6c66a9 100644 --- a/src/mainboard/google/veyron_mickey/mainboard.c +++ b/src/mainboard/google/veyron_mickey/mainboard.c @@ -101,7 +101,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); diff --git a/src/mainboard/google/veyron_rialto/mainboard.c b/src/mainboard/google/veyron_rialto/mainboard.c index 074e6a4e995..6259955669c 100644 --- a/src/mainboard/google/veyron_rialto/mainboard.c +++ b/src/mainboard/google/veyron_rialto/mainboard.c @@ -107,7 +107,7 @@ void lb_board(struct lb_header *header) struct lb_range *dma; dma = (struct lb_range *)lb_new_record(header); - dma->tag = LB_TAB_DMA; + dma->tag = LB_TAG_DMA; dma->size = sizeof(*dma); dma->range_start = (uintptr_t)_dma_coherent; dma->range_size = REGION_SIZE(dma_coherent); From e955fa33f6f994158a8bb2454505354ffed9ec9d Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Tue, 14 May 2019 12:52:54 +0200 Subject: [PATCH 488/588] src/drivers/xgi: Move coreboot related includes to xgi_coreboot.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia18c77876121594a272a07d56acfaa863d0ccb25 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/29307 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Kyösti Mälkki --- src/drivers/xgi/common/vb_init.c | 2 +- src/drivers/xgi/common/vb_setmode.c | 2 +- src/drivers/xgi/common/vb_util.c | 3 ++- src/drivers/xgi/common/xgi_coreboot.h | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/drivers/xgi/common/vb_init.c b/src/drivers/xgi/common/vb_init.c index a20c0683d48..b9191abe3d9 100644 --- a/src/drivers/xgi/common/vb_init.c +++ b/src/drivers/xgi/common/vb_init.c @@ -17,7 +17,7 @@ * GNU General Public License for more details. */ -#include +/* coreboot related includes come indirectly from xgi_coreboot.h */ #include "xgi_coreboot.h" #include "vstruct.h" diff --git a/src/drivers/xgi/common/vb_setmode.c b/src/drivers/xgi/common/vb_setmode.c index 162d00cfcf8..64412566a1b 100644 --- a/src/drivers/xgi/common/vb_setmode.c +++ b/src/drivers/xgi/common/vb_setmode.c @@ -14,7 +14,7 @@ * GNU General Public License for more details. */ -#include +/* coreboot related includes come indirectly from xgi_coreboot.h */ #include "xgi_coreboot.h" #include "vstruct.h" diff --git a/src/drivers/xgi/common/vb_util.c b/src/drivers/xgi/common/vb_util.c index f71ad5680a6..248b8af5f87 100644 --- a/src/drivers/xgi/common/vb_util.c +++ b/src/drivers/xgi/common/vb_util.c @@ -14,8 +14,9 @@ * GNU General Public License for more details. */ -#include "xgi_coreboot.h" +/* coreboot related includes come indirectly from xgi_coreboot.h */ +#include "xgi_coreboot.h" #include "vgatypes.h" #include "vb_util.h" diff --git a/src/drivers/xgi/common/xgi_coreboot.h b/src/drivers/xgi/common/xgi_coreboot.h index 41952d6925d..5e593eb1c21 100644 --- a/src/drivers/xgi/common/xgi_coreboot.h +++ b/src/drivers/xgi/common/xgi_coreboot.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include From 1ac5ecbfd1acf79f3bea288ef644c28ba54cc685 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Thu, 23 May 2019 09:38:21 +0200 Subject: [PATCH 489/588] soc/intel/braswell/acpi/globalnvs.asl: Remove redundant use of Offset ASL compiler reports twice warning 'unnecessary/redundant use of Offfset operator'. Remove redundant offsets. BUG=N/A TEST=Facebook FBG-1701 booting Embedded Linux Change-Id: I16705b9392b17c50d3988012406e03de393cbcd2 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32953 Tested-by: build bot (Jenkins) Reviewed-by: HAOUAS Elyes --- src/soc/intel/braswell/acpi/globalnvs.asl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/soc/intel/braswell/acpi/globalnvs.asl b/src/soc/intel/braswell/acpi/globalnvs.asl index c0b0b8d3d85..9bd9afc924b 100644 --- a/src/soc/intel/braswell/acpi/globalnvs.asl +++ b/src/soc/intel/braswell/acpi/globalnvs.asl @@ -31,7 +31,6 @@ OperationRegion (GNVS, SystemMemory, NVSA, 0x2000) Field (GNVS, ByteAcc, NoLock, Preserve) { /* Miscellaneous */ - Offset (0x00), OSYS, 16, /* 0x00 - Operating System */ SMIF, 8, /* 0x02 - SMI function */ PRM0, 8, /* 0x03 - SMI function parameter */ @@ -55,7 +54,6 @@ Field (GNVS, ByteAcc, NoLock, Preserve) CID1, 16, /* 0x1e - Wifi Domain Type */ /* Device Config */ - Offset (0x20), S5U0, 8, /* 0x20 - Enable USB0 in S5 */ S5U1, 8, /* 0x21 - Enable USB1 in S5 */ S3U0, 8, /* 0x22 - Enable USB0 in S3 */ From 73ac12196c61c8d0c21a54dfa87b858662d6859a Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 23 May 2019 14:41:19 +0200 Subject: [PATCH 490/588] drivers/intel/fsp1.1: Simplify bootflow and clean up MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This gets rid of the boilerplate back and forward calls between the SOC/FSP-driver code and mainboard code. Change-Id: I5d4a10d1da6b3ac5e65efd7f82607b56b80e08d4 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32961 Reviewed-by: Patrick Georgi Reviewed-by: Frans Hendriks Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- .../intel/fsp1_1/include/fsp/romstage.h | 4 +- src/drivers/intel/fsp1_1/romstage.c | 91 +++++++++---------- src/mainboard/google/cyan/romstage.c | 7 -- src/mainboard/google/glados/romstage.c | 4 +- src/mainboard/intel/kunimitsu/romstage.c | 6 -- src/mainboard/intel/saddlebrook/romstage.c | 6 -- src/mainboard/intel/strago/romstage.c | 2 - 7 files changed, 45 insertions(+), 75 deletions(-) diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h index 7efbb1085ca..2caceebfa08 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h +++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h @@ -44,15 +44,13 @@ struct romstage_params { void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params); -void mainboard_romstage_entry(struct romstage_params *params); +void mainboard_pre_raminit(struct romstage_params *params); void mainboard_save_dimm_info(struct romstage_params *params); void mainboard_add_dimm_info(struct romstage_params *params, struct memory_info *mem_info, int channel, int dimm, int index); void raminit(struct romstage_params *params); void report_memory_config(void); -void romstage_common(struct romstage_params *params); -asmlinkage void romstage_main(FSP_INFO_HEADER *fih); /* Initialize memory margin analysis settings. */ void setup_mma(MEMORY_INIT_UPD *memory_upd); void soc_after_ram_init(struct romstage_params *params); diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c index 45ca87aac8d..d86d3ab4842 100644 --- a/src/drivers/intel/fsp1_1/romstage.c +++ b/src/drivers/intel/fsp1_1/romstage.c @@ -37,48 +37,7 @@ #include #include -asmlinkage void romstage_main(FSP_INFO_HEADER *fih) -{ - struct romstage_params params = { - .chipset_context = fih, - }; - - post_code(0x30); - - timestamp_add_now(TS_START_ROMSTAGE); - - /* Load microcode before RAM init */ - if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS)) - intel_update_microcode_from_cbfs(); - - /* Display parameters */ - if (!CONFIG(NO_MMCONF_SUPPORT)) - printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n", - CONFIG_MMCONF_BASE_ADDRESS); - printk(BIOS_INFO, "Using FSP 1.1\n"); - - /* Display FSP banner */ - print_fsp_info(fih); - - /* Stash FSP version. */ - params.fsp_version = fsp_version(fih); - - /* Get power state */ - params.power_state = fill_power_state(); - - /* Call into mainboard. */ - mainboard_romstage_entry(¶ms); - soc_after_ram_init(¶ms); - post_code(0x38); -} - -void cache_as_ram_stage_main(FSP_INFO_HEADER *fih) -{ - romstage_main(fih); -} - -/* Entry from the mainboard. */ -void romstage_common(struct romstage_params *params) +static void raminit_common(struct romstage_params *params) { bool s3wake; struct region_device rdev; @@ -153,6 +112,47 @@ void romstage_common(struct romstage_params *params) full_reset(); } +void cache_as_ram_stage_main(FSP_INFO_HEADER *fih) +{ + struct romstage_params params = { + .chipset_context = fih, + }; + + post_code(0x30); + + timestamp_add_now(TS_START_ROMSTAGE); + + /* Load microcode before RAM init */ + if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS)) + intel_update_microcode_from_cbfs(); + + /* Display parameters */ + if (!CONFIG(NO_MMCONF_SUPPORT)) + printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n", + CONFIG_MMCONF_BASE_ADDRESS); + printk(BIOS_INFO, "Using FSP 1.1\n"); + + /* Display FSP banner */ + print_fsp_info(fih); + + /* Stash FSP version. */ + params.fsp_version = fsp_version(fih); + + /* Get power state */ + params.power_state = fill_power_state(); + + /* Board initialization before and after RAM is enabled */ + mainboard_pre_raminit(¶ms); + + post_code(0x31); + + /* Initialize memory */ + raminit_common(¶ms); + + soc_after_ram_init(¶ms); + post_code(0x38); +} + /* Initialize the power state */ __weak struct chipset_power_state *fill_power_state(void) { @@ -160,13 +160,8 @@ __weak struct chipset_power_state *fill_power_state(void) } /* Board initialization before and after RAM is enabled */ -__weak void mainboard_romstage_entry( - struct romstage_params *params) +__weak void mainboard_pre_raminit(struct romstage_params *params) { - post_code(0x31); - - /* Initialize memory */ - romstage_common(params); } /* Save the DIMM information for SMBIOS table 17 */ diff --git a/src/mainboard/google/cyan/romstage.c b/src/mainboard/google/cyan/romstage.c index c877e420551..dea73e9eeed 100644 --- a/src/mainboard/google/cyan/romstage.c +++ b/src/mainboard/google/cyan/romstage.c @@ -19,13 +19,6 @@ #include "spd/spd_util.h" -/* All FSP specific code goes in this block */ -void mainboard_romstage_entry(struct romstage_params *rp) -{ - /* Call back into chipset code with platform values updated. */ - romstage_common(rp); -} - void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params) { diff --git a/src/mainboard/google/glados/romstage.c b/src/mainboard/google/glados/romstage.c index 47524c28ba3..f2daa38d003 100644 --- a/src/mainboard/google/glados/romstage.c +++ b/src/mainboard/google/glados/romstage.c @@ -25,15 +25,13 @@ #include "spd/spd_util.h" #include "spd/spd.h" -void mainboard_romstage_entry(struct romstage_params *params) +void mainboard_pre_raminit(struct romstage_params *params) { #ifdef EC_ENABLE_KEYBOARD_BACKLIGHT /* Turn on keyboard backlight to indicate we are booting */ if (params->power_state->prev_sleep_state != ACPI_S3) google_chromeec_kbbacklight(25); #endif - /* Initialize memory */ - romstage_common(params); } void mainboard_memory_init_params(struct romstage_params *params, diff --git a/src/mainboard/intel/kunimitsu/romstage.c b/src/mainboard/intel/kunimitsu/romstage.c index f25f88b4dd6..f900ca319bc 100644 --- a/src/mainboard/intel/kunimitsu/romstage.c +++ b/src/mainboard/intel/kunimitsu/romstage.c @@ -20,12 +20,6 @@ #include "gpio.h" #include "spd/spd.h" -void mainboard_romstage_entry(struct romstage_params *params) -{ - /* Initialize memory */ - romstage_common(params); -} - void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params) { diff --git a/src/mainboard/intel/saddlebrook/romstage.c b/src/mainboard/intel/saddlebrook/romstage.c index 48d39db309c..82b85fd700f 100644 --- a/src/mainboard/intel/saddlebrook/romstage.c +++ b/src/mainboard/intel/saddlebrook/romstage.c @@ -33,12 +33,6 @@ void car_mainboard_pre_console_init(void) nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); } -void mainboard_romstage_entry(struct romstage_params *params) -{ - post_code(0x31); - romstage_common(params); -} - void mainboard_memory_init_params( struct romstage_params *params, MEMORY_INIT_UPD *memory_params) diff --git a/src/mainboard/intel/strago/romstage.c b/src/mainboard/intel/strago/romstage.c index ba0ff7b85e7..1dc7ba32fc1 100644 --- a/src/mainboard/intel/strago/romstage.c +++ b/src/mainboard/intel/strago/romstage.c @@ -14,8 +14,6 @@ * GNU General Public License for more details. */ -#include -#include #include #include "onboard.h" #include From 56e2d7d21aeffb75af34606bc034ee4fed560775 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 23 May 2019 15:07:49 +0200 Subject: [PATCH 491/588] soc/intel/skylake: Use common cpu/intel/car romstage code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting up the console and entering postcar can be done in a common place. Change-Id: I8a8db0fcb4f0fbbb121a8195a8a8b6644c28db07 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32962 Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/drivers/intel/fsp1_1/car.c | 14 +++---- src/drivers/intel/fsp1_1/include/fsp/car.h | 1 - src/soc/intel/skylake/romstage/Makefile.inc | 2 +- src/soc/intel/skylake/romstage/car_stage.S | 41 --------------------- 4 files changed, 6 insertions(+), 52 deletions(-) delete mode 100644 src/soc/intel/skylake/romstage/car_stage.S diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index a1ee7b141ac..82dc320e0e7 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -27,7 +28,7 @@ /* platform_enter_postcar() determines the stack to use after * cache-as-ram is torn down as well as the MTRR settings to use, * and continues execution in postcar stage. */ -static void platform_enter_postcar(void) +void platform_enter_postcar(void) { struct postcar_frame pcf; size_t alignment; @@ -153,17 +154,15 @@ asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params) platform_enter_postcar(); } -/* This is the romstage C entry for platforms with - CONFIG_C_ENVIRONMENT_BOOTBLOCK */ -asmlinkage void romstage_c_entry(void) +/* This is the entry for platforms with CONFIG_C_ENVIRONMENT_BOOTBLOCK + called from cpu/intel/car/romstage.c */ +void mainboard_romstage_entry(unsigned long bist) { /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram * is still enabled. We can directly access work buffer here. */ FSP_INFO_HEADER *fih; struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); - console_init(); - if (prog_locate(&fsp)) { fih = NULL; printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp)); @@ -174,9 +173,6 @@ asmlinkage void romstage_c_entry(void) } cache_as_ram_stage_main(fih); - - /* we don't return here */ - platform_enter_postcar(); } void __weak car_mainboard_pre_console_init(void) diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h index 0ae687a9d74..c05139231c8 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/car.h +++ b/src/drivers/intel/fsp1_1/include/fsp/car.h @@ -31,7 +31,6 @@ struct cache_as_ram_params { /* Entry points from the cache-as-ram assembly code. */ asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params); -asmlinkage void romstage_c_entry(void); /* Per stage calls from the above two functions. The void * return from * cache_as_ram_stage_main() is the stack pointer to use in RAM after * exiting cache-as-ram mode. */ diff --git a/src/soc/intel/skylake/romstage/Makefile.inc b/src/soc/intel/skylake/romstage/Makefile.inc index 8bfbfea66ab..e929ebaf177 100644 --- a/src/soc/intel/skylake/romstage/Makefile.inc +++ b/src/soc/intel/skylake/romstage/Makefile.inc @@ -1,4 +1,4 @@ -romstage-$(CONFIG_PLATFORM_USES_FSP1_1) += car_stage.S +romstage-$(CONFIG_PLATFORM_USES_FSP1_1) += ../../../../cpu/intel/car/romstage.c romstage-$(CONFIG_PLATFORM_USES_FSP1_1) += romstage.c romstage-$(CONFIG_PLATFORM_USES_FSP2_0) += romstage_fsp20.c romstage-y += systemagent.c diff --git a/src/soc/intel/skylake/romstage/car_stage.S b/src/soc/intel/skylake/romstage/car_stage.S deleted file mode 100644 index d8b45cb2588..00000000000 --- a/src/soc/intel/skylake/romstage/car_stage.S +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2015 Google Inc - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include - -/* I/O delay between post codes on failure */ -#define LHLT_DELAY 0x50000 - -.text -.global car_stage_entry -car_stage_entry: - call romstage_c_entry - - /* we don't return here */ - movb $0x69, %ah - jmp .Lhlt - -.Lhlt: - xchg %al, %ah -#if CONFIG(POST_IO) - outb %al, $CONFIG_POST_IO_PORT -#else - post_code(POST_DEAD_CODE) -#endif - movl $LHLT_DELAY, %ecx -.Lhlt_Delay: - outb %al, $0xED - loop .Lhlt_Delay - jmp .Lhlt From 23cb12b0404bbcb451140592b9502751a0ff719f Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 25 Jul 2017 19:36:25 +0200 Subject: [PATCH 492/588] payloads/external/iPXE: Add more Kconfig options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two new options: * Disable the prompt "Press Ctrl+B for the iPXE command line..." Add a boolean that disables the initial 2 second timeout. * Include a script that is executed instead of showing a shell. Allows to add a script that will be included into the iPXE ROM. Tested on Lenovo T500 and PC Engines apu2. Change-Id: Ie1083d8571d9d1f1c7c71659fb6ff0de2eecad0e Signed-off-by: Patrick Rudolph Signed-off-by: Michał Żygowski Reviewed-on: https://review.coreboot.org/c/coreboot/+/20782 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- payloads/external/Makefile.inc | 9 +++++++-- payloads/external/iPXE/Kconfig | 26 ++++++++++++++++++++++++++ payloads/external/iPXE/Makefile | 21 ++++++++++++++++++++- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/payloads/external/Makefile.inc b/payloads/external/Makefile.inc index 5edbb81b187..9c34efabeb0 100644 --- a/payloads/external/Makefile.inc +++ b/payloads/external/Makefile.inc @@ -229,7 +229,9 @@ endif ifeq ($(CONFIG_BUILD_IPXE),y) PXE_ROM_FILE:=payloads/external/iPXE/ipxe/ipxe.rom endif - +ifeq ($(CONFIG_PXE_ADD_SCRIPT),y) +PXE_CONFIG_SCRIPT:=$(abspath $(patsubst "%",%,$(CONFIG_PXE_SCRIPT))) +endif ifeq ($(CONFIG_CONSOLE_SERIAL)$(CONFIG_DRIVERS_UART_8250IO),yy) IPXE_UART=COM$(call int-add,$(CONFIG_UART_FOR_CONSOLE) 1) endif @@ -244,7 +246,7 @@ cbfs-files-$(CONFIG_PXE_ROM)$(CONFIG_BUILD_IPXE) += pci$(CONFIG_PXE_ROM_ID).rom pci$(CONFIG_PXE_ROM_ID).rom-file := $(PXE_ROM_FILE) pci$(CONFIG_PXE_ROM_ID).rom-type := raw -payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG) +payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG) $(PXE_CONFIG_SCRIPT) $(MAKE) -C payloads/external/iPXE all \ CROSS_COMPILE="$(CROSS_COMPILE_$(ARCH-ramstage-y))" \ PXE_ROM_PCI_ID=$(PXE_ROM_PCI_ID) \ @@ -253,6 +255,9 @@ payloads/external/iPXE/ipxe/ipxe.rom ipxe: $(DOTCONFIG) CONSOLE_SERIAL=$(IPXE_SERIAL_CONSOLE) \ IPXE_UART=$(IPXE_UART) \ CONFIG_TTYS0_BAUD=$(CONFIG_TTYS0_BAUD) \ + CONFIG_SCRIPT=$(PXE_CONFIG_SCRIPT) \ + CONFIG_HAS_SCRIPT=$(CONFIG_PXE_ADD_SCRIPT) \ + CONFIG_PXE_NO_PROMT=$(CONFIG_PXE_NO_PROMT) \ MFLAGS= MAKEFLAGS= # LinuxBoot diff --git a/payloads/external/iPXE/Kconfig b/payloads/external/iPXE/Kconfig index f99182c908b..7cb0d1e2497 100644 --- a/payloads/external/iPXE/Kconfig +++ b/payloads/external/iPXE/Kconfig @@ -87,5 +87,31 @@ config PXE_SERIAL_CONSOLE Unselect to let only SeaBIOS handle printing output. +config PXE_NO_PROMT + bool "Do not show prompt to boot from PXE" + default n + depends on BUILD_IPXE + help + Don't wait for the user to press Ctrl-B. + The PXE still can be run as it shows up in SeaBIOS's payload list. + +config PXE_ADD_SCRIPT + bool "Embed an iPXE script for automated provisioning" + depends on BUILD_IPXE + default n + help + Enable to embed a script that is run instead of an iPXE shell. + +config PXE_SCRIPT + string "Embedded iPXE script path and filename" + depends on PXE_ADD_SCRIPT + default "" + help + Path to a script that is embedded into the iPXE binary. + Example: startup.ipxe + + Uses the ipxe script instead showing the prompt: + "Press Ctrl-B to start iPXE..." + endmenu endif diff --git a/payloads/external/iPXE/Makefile b/payloads/external/iPXE/Makefile index 3a0585fc787..0c071fa13bb 100644 --- a/payloads/external/iPXE/Makefile +++ b/payloads/external/iPXE/Makefile @@ -54,15 +54,34 @@ ifeq ($(CONSOLE_SERIAL),yy) sed 's|#define\s*COMCONSOLE.*|#define COMCONSOLE $(IPXE_UART)|' "$(project_dir)/src/config/serial.h" > "$(project_dir)/src/config/serial.h.tmp" sed 's|#define\s*COMSPEED.*|#define COMSPEED $(CONFIG_TTYS0_BAUD)|' "$(project_dir)/src/config/serial.h.tmp" > "$(project_dir)/src/config/serial.h" endif +ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),) + cp "$(project_dir)/src/config/general.h" "$(project_dir)/src/config/general.h.cb" +endif +ifeq ($(CONFIG_HAS_SCRIPT),y) + sed 's|//#define\s*IMAGE_SCRIPT.*|#define IMAGE_SCRIPT|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp" + mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h" +endif +ifeq ($(CONFIG_PXE_NO_PROMT),y) + sed 's|#define\s*BANNER_TIMEOUT.*|#define BANNER_TIMEOUT 0|' "$(project_dir)/src/config/general.h" > "$(project_dir)/src/config/general.h.tmp" + mv "$(project_dir)/src/config/general.h.tmp" "$(project_dir)/src/config/general.h" +endif -build: config +build: config $(CONFIG_SCRIPT) +ifeq ($(CONFIG_HAS_SCRIPT),y) + echo " MAKE $(project_name) $(TAG-y) EMBED=$(CONFIG_SCRIPT)" + $(MAKE) -C $(project_dir)/src bin/$(PXE_ROM_PCI_ID).rom EMBED=$(CONFIG_SCRIPT) +else echo " MAKE $(project_name) $(TAG-y)" $(MAKE) -C $(project_dir)/src bin/$(PXE_ROM_PCI_ID).rom +endif cp $(project_dir)/src/bin/$(PXE_ROM_PCI_ID).rom $(project_dir)/ipxe.rom ifeq ($(CONSOLE_SERIAL),yy) cp "$(project_dir)/src/config/console.h.cb" "$(project_dir)/src/config/console.h" cp "$(project_dir)/src/config/serial.h.cb" "$(project_dir)/src/config/serial.h" endif +ifneq ($(filter y,$(CONFIG_HAS_SCRIPT) $(CONFIG_PXE_NO_PROMT)),) + cp "$(project_dir)/src/config/general.h.cb" "$(project_dir)/src/config/general.h" +endif clean: test -d $(project_dir) && $(MAKE) -C $(project_dir)/src veryclean || exit 0 From a998e280163b84c0786cb8d4b7f216a36b262d6a Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Thu, 23 May 2019 16:14:59 +0200 Subject: [PATCH 493/588] src/soc/intel/skylake/chip.h: Add smbios.h for Type9 Entries In order to add the smbios_slot_desc for the SMBIOS Type9 entries into the devicetree, and not use numbers but strings like "SlotTypePciExpressGen3X4", smbios.h needs to be included in the static.c. Change-Id: Iace547868b4ce8eb7d3624baf1abd1187c1e5f51 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/32965 Reviewed-by: Philipp Deppenwiese Tested-by: build bot (Jenkins) --- src/soc/intel/skylake/chip.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 57d51e76b24..a537165dd9b 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -34,6 +34,7 @@ #include #include #include +#include #define MAX_PEG_PORTS 3 From 543be8d367468253096311fe9198bb8cc66ad5b4 Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Sun, 26 May 2019 01:14:13 +0200 Subject: [PATCH 494/588] payloads/external/Linuxboot: Fix Makefile when not using bash Adding "SHELL := /bin/bash" to the Makefile makes sure, that we use the bash shell which is needed here. Tested with oh-my-zsh. Change-Id: I71495e15b8f1a495af7d8ab21cc5235feb595e01 Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/33014 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- payloads/external/LinuxBoot/targets/linux.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/payloads/external/LinuxBoot/targets/linux.mk b/payloads/external/LinuxBoot/targets/linux.mk index 5632a0b9231..e32ad1e21be 100644 --- a/payloads/external/LinuxBoot/targets/linux.mk +++ b/payloads/external/LinuxBoot/targets/linux.mk @@ -12,6 +12,7 @@ ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## +SHELL := /bin/bash ARCH-$(CONFIG_LINUXBOOT_X86_64)=x86_64 ARCH-$(CONFIG_LINUXBOOT_X86)=x86 From 62c0b61bed96df60967d2980d9ee4e4b3f0461b0 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 5 Feb 2019 21:10:01 +0100 Subject: [PATCH 495/588] soc/intel/denverton_ns: Don't use CONFIG_CBFS_SIZE CONFIG_CBFS_SIZE is only meaningful to generate the default fmap layout and ought not to be used in the code directly. Change-Id: Iae72a9fb02d62d7548d34689f5eb371f34cd3d81 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/31249 Reviewed-by: Angel Pons Reviewed-by: David Guckian Reviewed-by: Paul Menzel Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/soc/intel/denverton_ns/bootblock/bootblock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/denverton_ns/bootblock/bootblock.c b/src/soc/intel/denverton_ns/bootblock/bootblock.c index f16ee20620f..57e3a2e49bf 100644 --- a/src/soc/intel/denverton_ns/bootblock/bootblock.c +++ b/src/soc/intel/denverton_ns/bootblock/bootblock.c @@ -37,8 +37,8 @@ const FSPT_UPD temp_ram_init_params = { .MicrocodeRegionLength = (UINT32)CONFIG_CPU_MICROCODE_CBFS_LEN, .CodeRegionBase = - (UINT32)(0x100000000ULL - CONFIG_CBFS_SIZE), - .CodeRegionLength = (UINT32)CONFIG_CBFS_SIZE, + (UINT32)(0x100000000ULL - CONFIG_ROM_SIZE), + .CodeRegionLength = (UINT32)CONFIG_ROM_SIZE, .Reserved1 = {0}, }, .FsptConfig = { From b12ece98b09dd88634d93bcb41ca5c4cb9d86364 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:01:02 +0200 Subject: [PATCH 496/588] src/{include,arch,cpu,lib}: Add missing 'include ' is supposed to provide and . So when is included, and/or is removed. Change-Id: I57aead27806e307b9827fc7ee2cd663f12ee6e5e Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/31892 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/arch/x86/include/arch/acpi.h | 2 +- src/cpu/allwinner/a10/twi.c | 7 ++++--- src/cpu/amd/family_10h-family_15h/init_cpus.c | 2 ++ src/cpu/amd/family_10h-family_15h/powernow_acpi.c | 2 +- src/include/types.h | 2 ++ src/lib/lzmadecode.c | 2 +- 6 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/arch/x86/include/arch/acpi.h b/src/arch/x86/include/arch/acpi.h index 60efdd0d7a7..dbf46a9b1b0 100644 --- a/src/arch/x86/include/arch/acpi.h +++ b/src/arch/x86/include/arch/acpi.h @@ -56,11 +56,11 @@ #define OEM_ID "COREv4" /* Must be exactly 6 bytes long! */ #if !defined(__ASSEMBLER__) && !defined(__ACPI__) && !defined(__ROMCC__) -#include #include #include #include #include +#include #define RSDP_SIG "RSD PTR " /* RSDT pointer signature */ #define ASLC "CORE" /* Must be exactly 4 bytes long! */ diff --git a/src/cpu/allwinner/a10/twi.c b/src/cpu/allwinner/a10/twi.c index 6e7f9e214a5..01ee5a5c6fa 100644 --- a/src/cpu/allwinner/a10/twi.c +++ b/src/cpu/allwinner/a10/twi.c @@ -20,12 +20,13 @@ * Largely based on the uboot-sunxi code. */ -#include "memmap.h" -#include "twi.h" - #include #include #include +#include + +#include "memmap.h" +#include "twi.h" #define TWI_BASE(n) (A1X_TWI0_BASE + 0x400 * (n)) diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c index 719d62fbcc0..310706ba953 100644 --- a/src/cpu/amd/family_10h-family_15h/init_cpus.c +++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c @@ -17,6 +17,8 @@ #include #include #include +#include + #include "init_cpus.h" #if CONFIG(HAVE_OPTION_TABLE) diff --git a/src/cpu/amd/family_10h-family_15h/powernow_acpi.c b/src/cpu/amd/family_10h-family_15h/powernow_acpi.c index d024069e303..e648b717508 100644 --- a/src/cpu/amd/family_10h-family_15h/powernow_acpi.c +++ b/src/cpu/amd/family_10h-family_15h/powernow_acpi.c @@ -16,7 +16,6 @@ */ #include -#include #include #include #include @@ -30,6 +29,7 @@ #include #include #include +#include static inline uint8_t is_fam15h(void) { diff --git a/src/include/types.h b/src/include/types.h index b76c95b5bb2..d6fdc085884 100644 --- a/src/include/types.h +++ b/src/include/types.h @@ -15,6 +15,8 @@ #ifndef __TYPES_H #define __TYPES_H + +/* types.h is supposed to provide stdint and stddef defined in here: */ #include #include diff --git a/src/lib/lzmadecode.c b/src/lib/lzmadecode.c index 0a5d0386380..c45e1317081 100644 --- a/src/lib/lzmadecode.c +++ b/src/lib/lzmadecode.c @@ -20,7 +20,7 @@ */ #include "lzmadecode.h" -#include +#include #define kNumTopBits 24 #define kTopValue ((UInt32)1 << kNumTopBits) From bd1683da29d5688f97fcc43bef3e0df74e4196f9 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:05:37 +0200 Subject: [PATCH 497/588] src/{device,drivers}: Add missing 'include ' is supposed to provide and . So when is included, and/or is removed. Change-Id: I3395715f9e2b03175089186ab2e57d9e508fc87c Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32806 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/device/dram/ddr2.c | 1 + src/device/dram/ddr3.c | 1 + src/drivers/generic/bayhub/bh720.h | 2 ++ src/drivers/intel/fsp2_0/graphics.c | 1 + src/drivers/intel/fsp2_0/include/fsp/util.h | 1 + src/drivers/intel/fsp2_0/memory_init.c | 1 + src/drivers/intel/fsp2_0/silicon_init.c | 1 + src/drivers/intel/fsp2_0/temp_ram_exit.c | 1 + src/drivers/intel/fsp2_0/util.c | 1 + src/drivers/net/atl1e.c | 1 + src/drivers/net/r8168.c | 2 ++ src/drivers/pc80/rtc/mc146818rtc.c | 2 +- src/drivers/xpowers/axp209/axp209.c | 7 ++++--- 13 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/device/dram/ddr2.c b/src/device/dram/ddr2.c index 53106f23f9b..60588b880bb 100644 --- a/src/device/dram/ddr2.c +++ b/src/device/dram/ddr2.c @@ -26,6 +26,7 @@ #include #include #include +#include /*============================================================================== * = DDR2 SPD decoding helpers diff --git a/src/device/dram/ddr3.c b/src/device/dram/ddr3.c index e545b4d0365..3272dac6d72 100644 --- a/src/device/dram/ddr3.c +++ b/src/device/dram/ddr3.c @@ -27,6 +27,7 @@ #include #include #include +#include /*============================================================================== * = DDR3 SPD decoding helpers diff --git a/src/drivers/generic/bayhub/bh720.h b/src/drivers/generic/bayhub/bh720.h index 3183bf1a845..ecea513bfb3 100644 --- a/src/drivers/generic/bayhub/bh720.h +++ b/src/drivers/generic/bayhub/bh720.h @@ -15,6 +15,8 @@ * GNU General Public License for more details. */ +#include + enum { BH720_PROTECT = 0xd0, BH720_PROTECT_LOCK_OFF = 0, diff --git a/src/drivers/intel/fsp2_0/graphics.c b/src/drivers/intel/fsp2_0/graphics.c index e0c63d25702..55dc6dfddca 100644 --- a/src/drivers/intel/fsp2_0/graphics.c +++ b/src/drivers/intel/fsp2_0/graphics.c @@ -13,6 +13,7 @@ #include #include #include +#include enum pixel_format { pixel_rgbx_8bpc = 0, diff --git a/src/drivers/intel/fsp2_0/include/fsp/util.h b/src/drivers/intel/fsp2_0/include/fsp/util.h index 231162ed17b..ef7ecd163f9 100644 --- a/src/drivers/intel/fsp2_0/include/fsp/util.h +++ b/src/drivers/intel/fsp2_0/include/fsp/util.h @@ -19,6 +19,7 @@ #include #include #include +#include struct hob_header { uint16_t type; diff --git a/src/drivers/intel/fsp2_0/memory_init.c b/src/drivers/intel/fsp2_0/memory_init.c index 60e3310a4da..f248a58c774 100644 --- a/src/drivers/intel/fsp2_0/memory_init.c +++ b/src/drivers/intel/fsp2_0/memory_init.c @@ -32,6 +32,7 @@ #include #include #include +#include /* TPM MRC hash functionality depends on vboot starting before memory init. */ _Static_assert(!CONFIG(FSP2_0_USES_TPM_MRC_HASH) || diff --git a/src/drivers/intel/fsp2_0/silicon_init.c b/src/drivers/intel/fsp2_0/silicon_init.c index 302bc0f3ade..e72e4ac163e 100644 --- a/src/drivers/intel/fsp2_0/silicon_init.c +++ b/src/drivers/intel/fsp2_0/silicon_init.c @@ -22,6 +22,7 @@ #include #include #include +#include struct fsp_header fsps_hdr; diff --git a/src/drivers/intel/fsp2_0/temp_ram_exit.c b/src/drivers/intel/fsp2_0/temp_ram_exit.c index ced3584fd05..075e923f843 100644 --- a/src/drivers/intel/fsp2_0/temp_ram_exit.c +++ b/src/drivers/intel/fsp2_0/temp_ram_exit.c @@ -15,6 +15,7 @@ #include #include #include +#include void fsp_temp_ram_exit(void) { diff --git a/src/drivers/intel/fsp2_0/util.c b/src/drivers/intel/fsp2_0/util.c index 19b8127ac5c..f670e6facd2 100644 --- a/src/drivers/intel/fsp2_0/util.c +++ b/src/drivers/intel/fsp2_0/util.c @@ -16,6 +16,7 @@ #include #include #include +#include static bool looks_like_fsp_header(const uint8_t *raw_hdr) { diff --git a/src/drivers/net/atl1e.c b/src/drivers/net/atl1e.c index f6f04a1035b..097b768b12d 100644 --- a/src/drivers/net/atl1e.c +++ b/src/drivers/net/atl1e.c @@ -26,6 +26,7 @@ #include #include #include +#include #define REG_SPI_FLASH_CTRL 0x200 #define SPI_FLASH_CTRL_EN_VPD 0x2000 diff --git a/src/drivers/net/r8168.c b/src/drivers/net/r8168.c index 3200163ab37..31887789003 100644 --- a/src/drivers/net/r8168.c +++ b/src/drivers/net/r8168.c @@ -33,6 +33,8 @@ #include #include #include +#include + #include "chip.h" #define NIC_TIMEOUT 1000 diff --git a/src/drivers/pc80/rtc/mc146818rtc.c b/src/drivers/pc80/rtc/mc146818rtc.c index 6e37cd2f784..e0869a93371 100644 --- a/src/drivers/pc80/rtc/mc146818rtc.c +++ b/src/drivers/pc80/rtc/mc146818rtc.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -29,6 +28,7 @@ #include #include #include +#include /* There's no way around this include guard. option_table.h is autogenerated */ #if CONFIG(USE_OPTION_TABLE) diff --git a/src/drivers/xpowers/axp209/axp209.c b/src/drivers/xpowers/axp209/axp209.c index da575ccffd5..93e864dff72 100644 --- a/src/drivers/xpowers/axp209/axp209.c +++ b/src/drivers/xpowers/axp209/axp209.c @@ -8,12 +8,13 @@ * Subject to the GNU GPL v2, or (at your option) any later version. */ -#include "axp209.h" -#include "chip.h" - #include #include #include +#include + +#include "axp209.h" +#include "chip.h" /* Hide these definitions from the rest of the source, so keep them here */ enum registers { From 5fd93e05820d742fac5dbc1b371b464a88bb9043 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:07:30 +0200 Subject: [PATCH 498/588] src/{ec,vendorcode}: Add missing 'include is supposed to provide and . So when is included, and/or is removed. Change-Id: I1eb4163fb36a47b584f1fc9dd3c012e2930e9866 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32807 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/ec/lenovo/h8/h8.c | 1 + src/ec/lenovo/h8/wwan.c | 1 + src/ec/lenovo/pmh7/pmh7.c | 1 + src/vendorcode/siemens/hwilib/hwilib.c | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ec/lenovo/h8/h8.c b/src/ec/lenovo/h8/h8.c index de4f2c29b2d..f707014c315 100644 --- a/src/ec/lenovo/h8/h8.c +++ b/src/ec/lenovo/h8/h8.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "h8.h" #include "chip.h" diff --git a/src/ec/lenovo/h8/wwan.c b/src/ec/lenovo/h8/wwan.c index cf3c8f7cf0b..e79cb613320 100644 --- a/src/ec/lenovo/h8/wwan.c +++ b/src/ec/lenovo/h8/wwan.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "h8.h" #include "chip.h" diff --git a/src/ec/lenovo/pmh7/pmh7.c b/src/ec/lenovo/pmh7/pmh7.c index 986abb5d813..ef505cd164d 100644 --- a/src/ec/lenovo/pmh7/pmh7.c +++ b/src/ec/lenovo/pmh7/pmh7.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "pmh7.h" #include "chip.h" diff --git a/src/vendorcode/siemens/hwilib/hwilib.c b/src/vendorcode/siemens/hwilib/hwilib.c index 1213dce4ede..a4d87addff8 100644 --- a/src/vendorcode/siemens/hwilib/hwilib.c +++ b/src/vendorcode/siemens/hwilib/hwilib.c @@ -18,8 +18,9 @@ #include #include #include -#include "hwilib.h" +#include +#include "hwilib.h" #define MAX_BLOCK_NUM 4 #define LEN_HIB 0x1fd From 51401c30509d189d07a8a94958bdecdfd8b7667d Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:09:30 +0200 Subject: [PATCH 499/588] src/northbridge: Add missing 'include ' is supposed to provide and . When is included, and/or is removed. Change-Id: Iad5367bed844b866b2ad87639eee29a16d9a99ed Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32808 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/northbridge/amd/amdfam10/link_control.c | 1 + src/northbridge/amd/amdfam10/misc_control.c | 1 + src/northbridge/amd/amdfam10/northbridge.c | 1 + src/northbridge/amd/amdht/h3finit.c | 1 + src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 2 ++ src/northbridge/amd/amdmct/mct_ddr3/s3utils.c | 2 ++ src/northbridge/amd/amdmct/wrappers/mcti_d.c | 1 + src/northbridge/intel/gm45/gma.c | 1 + src/northbridge/intel/haswell/gma.c | 1 + src/northbridge/intel/i945/early_init.c | 5 +++-- src/northbridge/intel/i945/gma.c | 1 + src/northbridge/intel/nehalem/gma.c | 1 + src/northbridge/intel/nehalem/raminit.c | 10 +++++----- src/northbridge/intel/pineview/early_init.c | 2 +- src/northbridge/intel/pineview/gma.c | 7 ++++--- src/northbridge/intel/sandybridge/early_init.c | 3 ++- src/northbridge/intel/sandybridge/gma.c | 1 + src/northbridge/intel/sandybridge/raminit.c | 1 + src/northbridge/intel/x4x/gma.c | 1 + src/northbridge/intel/x4x/raminit.c | 1 + 20 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/northbridge/amd/amdfam10/link_control.c b/src/northbridge/amd/amdfam10/link_control.c index 871a4366c27..384772374be 100644 --- a/src/northbridge/amd/amdfam10/link_control.c +++ b/src/northbridge/amd/amdfam10/link_control.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "amdfam10.h" diff --git a/src/northbridge/amd/amdfam10/misc_control.c b/src/northbridge/amd/amdfam10/misc_control.c index bbaec538871..b0a1ab679a5 100644 --- a/src/northbridge/amd/amdfam10/misc_control.c +++ b/src/northbridge/amd/amdfam10/misc_control.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "amdfam10.h" diff --git a/src/northbridge/amd/amdfam10/northbridge.c b/src/northbridge/amd/amdfam10/northbridge.c index 1d071c18772..a681961be2f 100644 --- a/src/northbridge/amd/amdfam10/northbridge.c +++ b/src/northbridge/amd/amdfam10/northbridge.c @@ -34,6 +34,7 @@ #include #include #include +#include #if CONFIG(LOGICAL_CPUS) #include diff --git a/src/northbridge/amd/amdht/h3finit.c b/src/northbridge/amd/amdht/h3finit.c index 8c33ad81569..cda0a28cef8 100644 --- a/src/northbridge/amd/amdht/h3finit.c +++ b/src/northbridge/amd/amdht/h3finit.c @@ -36,6 +36,7 @@ #include #include #include +#include /*---------------------------------------------------------------------------- * DEFINITIONS AND MACROS diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 74e52345359..42e91b6130c 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -43,7 +43,9 @@ #include #include #include +#include #include + #include "s3utils.h" #include "mct_d_gcc.h" #include "mct_d.h" diff --git a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c index a78a7520524..d991002f5b7 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/s3utils.c @@ -30,6 +30,8 @@ #include #include #include +#include + #include "mct_d.h" #include "mct_d_gcc.h" diff --git a/src/northbridge/amd/amdmct/wrappers/mcti_d.c b/src/northbridge/amd/amdmct/wrappers/mcti_d.c index 7aaf016d294..b8042fe46da 100644 --- a/src/northbridge/amd/amdmct/wrappers/mcti_d.c +++ b/src/northbridge/amd/amdmct/wrappers/mcti_d.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "mcti.h" diff --git a/src/northbridge/intel/gm45/gma.c b/src/northbridge/intel/gm45/gma.c index 3549b492343..a2de7f0fb06 100644 --- a/src/northbridge/intel/gm45/gma.c +++ b/src/northbridge/intel/gm45/gma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "drivers/intel/gma/i915_reg.h" #include "chip.h" diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c index 1b2430f8498..607fab76028 100644 --- a/src/northbridge/intel/haswell/gma.c +++ b/src/northbridge/intel/haswell/gma.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "chip.h" #include "haswell.h" diff --git a/src/northbridge/intel/i945/early_init.c b/src/northbridge/intel/i945/early_init.c index 84d9c105d6f..f9167dfc97b 100644 --- a/src/northbridge/intel/i945/early_init.c +++ b/src/northbridge/intel/i945/early_init.c @@ -13,7 +13,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -22,9 +21,11 @@ #include #include #include -#include "i945.h" #include #include +#include + +#include "i945.h" int i945_silicon_revision(void) { diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c index 1d20533a481..54ff47cc646 100644 --- a/src/northbridge/intel/i945/gma.c +++ b/src/northbridge/intel/i945/gma.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "i945.h" #include "chip.h" diff --git a/src/northbridge/intel/nehalem/gma.c b/src/northbridge/intel/nehalem/gma.c index 8c0117f531d..087d37e5aa5 100644 --- a/src/northbridge/intel/nehalem/gma.c +++ b/src/northbridge/intel/nehalem/gma.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "chip.h" #include "nehalem.h" diff --git a/src/northbridge/intel/nehalem/raminit.c b/src/northbridge/intel/nehalem/raminit.c index 5b6077f5eae..15d6abb67be 100644 --- a/src/northbridge/intel/nehalem/raminit.c +++ b/src/northbridge/intel/nehalem/raminit.c @@ -30,18 +30,18 @@ #include #include #include -#include "raminit.h" -#include "chip.h" #include #include #include #include #include - -#include "nehalem.h" - #include #include +#include + +#include "chip.h" +#include "nehalem.h" +#include "raminit.h" #define NORTHBRIDGE PCI_DEV(0, 0, 0) #define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0) diff --git a/src/northbridge/intel/pineview/early_init.c b/src/northbridge/intel/pineview/early_init.c index 509ab4ee0cc..be6a5e27d66 100644 --- a/src/northbridge/intel/pineview/early_init.c +++ b/src/northbridge/intel/pineview/early_init.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -24,6 +23,7 @@ #include #include #include +#include #define LPC PCI_DEV(0, 0x1f, 0) #define D0F0 PCI_DEV(0, 0, 0) diff --git a/src/northbridge/intel/pineview/gma.c b/src/northbridge/intel/pineview/gma.c index 019f7648f0b..dd6cb325969 100644 --- a/src/northbridge/intel/pineview/gma.c +++ b/src/northbridge/intel/pineview/gma.c @@ -23,10 +23,7 @@ #include #include #include - #include -#include "chip.h" -#include "pineview.h" #include #include #include @@ -34,6 +31,10 @@ #include #include #include +#include + +#include "chip.h" +#include "pineview.h" #define GTTSIZE (512*1024) diff --git a/src/northbridge/intel/sandybridge/early_init.c b/src/northbridge/intel/sandybridge/early_init.c index 34aec3851b6..fd3d34f2dee 100644 --- a/src/northbridge/intel/sandybridge/early_init.c +++ b/src/northbridge/intel/sandybridge/early_init.c @@ -14,7 +14,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -22,6 +21,8 @@ #include #include #include +#include + #include "sandybridge.h" static void sandybridge_setup_bars(void) diff --git a/src/northbridge/intel/sandybridge/gma.c b/src/northbridge/intel/sandybridge/gma.c index cb6782e9b77..1005288fee6 100644 --- a/src/northbridge/intel/sandybridge/gma.c +++ b/src/northbridge/intel/sandybridge/gma.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "chip.h" #include "sandybridge.h" diff --git a/src/northbridge/intel/sandybridge/raminit.c b/src/northbridge/intel/sandybridge/raminit.c index f67d61f9739..c13ae37fbc4 100644 --- a/src/northbridge/intel/sandybridge/raminit.c +++ b/src/northbridge/intel/sandybridge/raminit.c @@ -30,6 +30,7 @@ #include #include #include +#include #include "raminit_native.h" #include "raminit_common.h" diff --git a/src/northbridge/intel/x4x/gma.c b/src/northbridge/intel/x4x/gma.c index c4e8bf1cdd4..61731fee3ed 100644 --- a/src/northbridge/intel/x4x/gma.c +++ b/src/northbridge/intel/x4x/gma.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "chip.h" #include "drivers/intel/gma/i915_reg.h" diff --git a/src/northbridge/intel/x4x/raminit.c b/src/northbridge/intel/x4x/raminit.c index 7fed1efe266..bd6536ab6fa 100644 --- a/src/northbridge/intel/x4x/raminit.c +++ b/src/northbridge/intel/x4x/raminit.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "iomap.h" #include "x4x.h" From ab89edbccf6e614213bbd88f5dbd5c8bf9a5d4c6 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:10:44 +0200 Subject: [PATCH 500/588] src/southbridge: Add missing 'include ' is supposed to provide and . When is included, and/or is removed. Change-Id: I4d8628e4ce3c7f80da2590b4cad618b290e0d513 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32809 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/southbridge/amd/pi/hudson/hudson.c | 4 ++-- src/southbridge/amd/pi/hudson/lpc.c | 2 ++ src/southbridge/amd/sb700/ide.c | 2 ++ src/southbridge/amd/sb700/sata.c | 2 ++ src/southbridge/amd/sb700/usb.c | 2 ++ src/southbridge/intel/bd82x6x/sata.c | 4 +++- src/southbridge/intel/common/smbus.c | 2 ++ src/southbridge/intel/i82801ix/sata.c | 4 +++- src/southbridge/intel/i82801jx/sata.c | 4 +++- src/southbridge/intel/ibexpeak/sata.c | 4 +++- 10 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/southbridge/amd/pi/hudson/hudson.c b/src/southbridge/amd/pi/hudson/hudson.c index e1ea2ce4b33..a331c572620 100644 --- a/src/southbridge/amd/pi/hudson/hudson.c +++ b/src/southbridge/amd/pi/hudson/hudson.c @@ -14,16 +14,16 @@ */ #include - #include #include #include - #include #include #include #include #include +#include + #include "hudson.h" #include "smbus.h" #include "smi.h" diff --git a/src/southbridge/amd/pi/hudson/lpc.c b/src/southbridge/amd/pi/hudson/lpc.c index abb92f29d21..5354a278226 100644 --- a/src/southbridge/amd/pi/hudson/lpc.c +++ b/src/southbridge/amd/pi/hudson/lpc.c @@ -27,6 +27,8 @@ #include #include #include +#include + #include "hudson.h" #include "pci_devs.h" diff --git a/src/southbridge/amd/sb700/ide.c b/src/southbridge/amd/sb700/ide.c index 673464318c0..0b11db3c865 100644 --- a/src/southbridge/amd/sb700/ide.c +++ b/src/southbridge/amd/sb700/ide.c @@ -19,6 +19,8 @@ #include #include #include +#include + #include "sb700.h" static void ide_init(struct device *dev) diff --git a/src/southbridge/amd/sb700/sata.c b/src/southbridge/amd/sb700/sata.c index 39aef639d2a..292a7f2c9e1 100644 --- a/src/southbridge/amd/sb700/sata.c +++ b/src/southbridge/amd/sb700/sata.c @@ -23,6 +23,8 @@ #include #include #include +#include + #include "sb700.h" static int sata_drive_detect(int portnum, uint16_t iobar) diff --git a/src/southbridge/amd/sb700/usb.c b/src/southbridge/amd/sb700/usb.c index da653112d74..4109e88cc3d 100644 --- a/src/southbridge/amd/sb700/usb.c +++ b/src/southbridge/amd/sb700/usb.c @@ -21,6 +21,8 @@ #include #include #include +#include + #include "sb700.h" static struct pci_operations lops_pci = { diff --git a/src/southbridge/intel/bd82x6x/sata.c b/src/southbridge/intel/bd82x6x/sata.c index 91c87bf26e8..6a39873e7b1 100644 --- a/src/southbridge/intel/bd82x6x/sata.c +++ b/src/southbridge/intel/bd82x6x/sata.c @@ -20,9 +20,11 @@ #include #include #include -#include "pch.h" #include #include +#include + +#include "pch.h" typedef struct southbridge_intel_bd82x6x_config config_t; diff --git a/src/southbridge/intel/common/smbus.c b/src/southbridge/intel/common/smbus.c index 4b08c48f270..af1eb602a00 100644 --- a/src/southbridge/intel/common/smbus.c +++ b/src/southbridge/intel/common/smbus.c @@ -19,6 +19,8 @@ #include #include #include +#include + #include "smbus.h" diff --git a/src/southbridge/intel/i82801ix/sata.c b/src/southbridge/intel/i82801ix/sata.c index 6155c150060..49d2d36b85c 100644 --- a/src/southbridge/intel/i82801ix/sata.c +++ b/src/southbridge/intel/i82801ix/sata.c @@ -22,8 +22,10 @@ #include #include #include -#include "i82801ix.h" #include +#include + +#include "i82801ix.h" typedef struct southbridge_intel_i82801ix_config config_t; diff --git a/src/southbridge/intel/i82801jx/sata.c b/src/southbridge/intel/i82801jx/sata.c index 8de2d7427d4..ddaa7838681 100644 --- a/src/southbridge/intel/i82801jx/sata.c +++ b/src/southbridge/intel/i82801jx/sata.c @@ -22,8 +22,10 @@ #include #include #include -#include "i82801jx.h" #include +#include + +#include "i82801jx.h" typedef struct southbridge_intel_i82801jx_config config_t; diff --git a/src/southbridge/intel/ibexpeak/sata.c b/src/southbridge/intel/ibexpeak/sata.c index 112445bb652..e03f8b58845 100644 --- a/src/southbridge/intel/ibexpeak/sata.c +++ b/src/southbridge/intel/ibexpeak/sata.c @@ -21,9 +21,11 @@ #include #include #include -#include "pch.h" #include #include +#include + +#include "pch.h" typedef struct southbridge_intel_ibexpeak_config config_t; From 27d02d8286aff64115ae593a189c38fdaf3ce769 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:11:39 +0200 Subject: [PATCH 501/588] src/soc: Add missing 'include ' is supposed to provide and . When is included, and/or is removed. Change-Id: I2db0a647bc657a3626cb5e78f23e9198e290261a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32810 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/soc/amd/common/block/include/amdblocks/psp.h | 2 +- src/soc/amd/stoneyridge/include/soc/northbridge.h | 1 + src/soc/amd/stoneyridge/southbridge.c | 2 +- src/soc/intel/apollolake/graphics.c | 1 + src/soc/intel/baytrail/gfx.c | 1 + src/soc/intel/broadwell/igd.c | 1 + src/soc/intel/cannonlake/graphics.c | 1 + src/soc/intel/icelake/graphics.c | 1 + src/soc/intel/skylake/graphics.c | 1 + src/soc/mediatek/common/pll.c | 1 + src/soc/mediatek/mt8173/ddp.c | 1 + src/soc/mediatek/mt8173/pll.c | 3 +-- src/soc/mediatek/mt8173/rtc.c | 1 + src/soc/nvidia/tegra210/dsi.c | 8 +++++--- src/soc/nvidia/tegra210/include/soc/dma.h | 1 + src/soc/nvidia/tegra210/mipi-phy.c | 3 +-- src/soc/nvidia/tegra210/spi.c | 3 +-- src/soc/qualcomm/ipq806x/include/soc/clock.h | 1 + src/soc/rockchip/common/gpio.c | 1 + src/soc/rockchip/rk3399/include/soc/mipi.h | 1 + src/soc/rockchip/rk3399/mipi.c | 2 +- 21 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/soc/amd/common/block/include/amdblocks/psp.h b/src/soc/amd/common/block/include/amdblocks/psp.h index 25a564b457b..512b0b8c040 100644 --- a/src/soc/amd/common/block/include/amdblocks/psp.h +++ b/src/soc/amd/common/block/include/amdblocks/psp.h @@ -18,7 +18,7 @@ #include #include -#include +#include /* Extra, Special Purpose Registers in the PSP PCI Config Space */ diff --git a/src/soc/amd/stoneyridge/include/soc/northbridge.h b/src/soc/amd/stoneyridge/include/soc/northbridge.h index 563dae09e11..60a6ea22bbe 100644 --- a/src/soc/amd/stoneyridge/include/soc/northbridge.h +++ b/src/soc/amd/stoneyridge/include/soc/northbridge.h @@ -18,6 +18,7 @@ #define __PI_STONEYRIDGE_NORTHBRIDGE_H__ #include +#include /* D0F0 - Root Complex */ diff --git a/src/soc/amd/stoneyridge/southbridge.c b/src/soc/amd/stoneyridge/southbridge.c index bf8787c1fca..84db3dd76c5 100644 --- a/src/soc/amd/stoneyridge/southbridge.c +++ b/src/soc/amd/stoneyridge/southbridge.c @@ -14,7 +14,6 @@ */ #include - #include #include #include @@ -36,6 +35,7 @@ #include #include #include +#include /* * Table of devices that need their AOAC registers enabled and waited diff --git a/src/soc/intel/apollolake/graphics.c b/src/soc/intel/apollolake/graphics.c index 51661d0cfc0..f5136ec103b 100644 --- a/src/soc/intel/apollolake/graphics.c +++ b/src/soc/intel/apollolake/graphics.c @@ -26,6 +26,7 @@ #include #include #include +#include uintptr_t fsp_soc_get_igd_bar(void) { diff --git a/src/soc/intel/baytrail/gfx.c b/src/soc/intel/baytrail/gfx.c index d2cb589db8f..2048c138246 100644 --- a/src/soc/intel/baytrail/gfx.c +++ b/src/soc/intel/baytrail/gfx.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "chip.h" diff --git a/src/soc/intel/broadwell/igd.c b/src/soc/intel/broadwell/igd.c index b9b42810fcb..9107b23eb90 100644 --- a/src/soc/intel/broadwell/igd.c +++ b/src/soc/intel/broadwell/igd.c @@ -36,6 +36,7 @@ #include #include #include +#include #define GT_RETRY 1000 enum { diff --git a/src/soc/intel/cannonlake/graphics.c b/src/soc/intel/cannonlake/graphics.c index a89dcb31fb6..2acfecc5b08 100644 --- a/src/soc/intel/cannonlake/graphics.c +++ b/src/soc/intel/cannonlake/graphics.c @@ -23,6 +23,7 @@ #include #include #include +#include uintptr_t fsp_soc_get_igd_bar(void) { diff --git a/src/soc/intel/icelake/graphics.c b/src/soc/intel/icelake/graphics.c index 35fe8b62364..0fbddf06e9d 100644 --- a/src/soc/intel/icelake/graphics.c +++ b/src/soc/intel/icelake/graphics.c @@ -23,6 +23,7 @@ #include #include #include +#include uintptr_t fsp_soc_get_igd_bar(void) { diff --git a/src/soc/intel/skylake/graphics.c b/src/soc/intel/skylake/graphics.c index 07ee67ab88a..f563c113024 100644 --- a/src/soc/intel/skylake/graphics.c +++ b/src/soc/intel/skylake/graphics.c @@ -25,6 +25,7 @@ #include #include #include +#include uintptr_t fsp_soc_get_igd_bar(void) { diff --git a/src/soc/mediatek/common/pll.c b/src/soc/mediatek/common/pll.c index 0968d2f59fa..a63fe8927b8 100644 --- a/src/soc/mediatek/common/pll.c +++ b/src/soc/mediatek/common/pll.c @@ -16,6 +16,7 @@ #include #include #include +#include #define GENMASK(h, l) (BIT(h + 1) - BIT(l)) diff --git a/src/soc/mediatek/mt8173/ddp.c b/src/soc/mediatek/mt8173/ddp.c index 0b78c3ea64e..f8896d391aa 100644 --- a/src/soc/mediatek/mt8173/ddp.c +++ b/src/soc/mediatek/mt8173/ddp.c @@ -19,6 +19,7 @@ #include #include #include +#include #define RDMA_FIFO_PSEUDO_SIZE(bytes) (((bytes) / 16) << 16) #define RDMA_OUTPUT_VALID_FIFO_THRESHOLD(bytes) ((bytes) / 16) diff --git a/src/soc/mediatek/mt8173/pll.c b/src/soc/mediatek/mt8173/pll.c index 7eb12b12820..e1c1bff6d53 100644 --- a/src/soc/mediatek/mt8173/pll.c +++ b/src/soc/mediatek/mt8173/pll.c @@ -16,11 +16,10 @@ #include #include #include -#include - #include #include #include +#include enum mux_id { TOP_AXI_SEL, diff --git a/src/soc/mediatek/mt8173/rtc.c b/src/soc/mediatek/mt8173/rtc.c index 79e5732c2f8..9ad4caa89c8 100644 --- a/src/soc/mediatek/mt8173/rtc.c +++ b/src/soc/mediatek/mt8173/rtc.c @@ -18,6 +18,7 @@ #include #include #include +#include #define RTC_GPIO_USER_MASK ((1 << 13) - (1 << 8)) diff --git a/src/soc/nvidia/tegra210/dsi.c b/src/soc/nvidia/tegra210/dsi.c index 76054f01561..ae20d44d16d 100644 --- a/src/soc/nvidia/tegra210/dsi.c +++ b/src/soc/nvidia/tegra210/dsi.c @@ -12,9 +12,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ + +#include #include #include -#include #include #include #include @@ -24,14 +25,15 @@ #include #include #include -#include "chip.h" #include #include #include #include #include +#include + +#include "chip.h" #include "jdi_25x18_display/panel-jdi-lpm102a188a.h" -#include struct tegra_mipi_device mipi_device_data[NUM_DSI]; diff --git a/src/soc/nvidia/tegra210/include/soc/dma.h b/src/soc/nvidia/tegra210/include/soc/dma.h index 1093479d5ff..3cb94ce8d33 100644 --- a/src/soc/nvidia/tegra210/include/soc/dma.h +++ b/src/soc/nvidia/tegra210/include/soc/dma.h @@ -19,6 +19,7 @@ #include #include +#include /* * The DMA engine operates on 4 bytes at a time, so make sure any data diff --git a/src/soc/nvidia/tegra210/mipi-phy.c b/src/soc/nvidia/tegra210/mipi-phy.c index 4e6bdf0242d..4e56730d3b2 100644 --- a/src/soc/nvidia/tegra210/mipi-phy.c +++ b/src/soc/nvidia/tegra210/mipi-phy.c @@ -13,9 +13,7 @@ * GNU General Public License for more details. */ -#include #include - #include #include #include @@ -25,6 +23,7 @@ #include #include #include +#include int mipi_dphy_set_timing(struct tegra_dsi *dsi) { diff --git a/src/soc/nvidia/tegra210/spi.c b/src/soc/nvidia/tegra210/spi.c index edb052df6bd..9310e0cc093 100644 --- a/src/soc/nvidia/tegra210/spi.c +++ b/src/soc/nvidia/tegra210/spi.c @@ -26,9 +26,8 @@ #include #include #include -#include -#include #include +#include #if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI # define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "TEGRA_SPI: " x) diff --git a/src/soc/qualcomm/ipq806x/include/soc/clock.h b/src/soc/qualcomm/ipq806x/include/soc/clock.h index 482deadfe7d..7ecc1eee168 100644 --- a/src/soc/qualcomm/ipq806x/include/soc/clock.h +++ b/src/soc/qualcomm/ipq806x/include/soc/clock.h @@ -34,6 +34,7 @@ #define __IPQ860X_CLOCK_H_ #include +#include /* UART clock @ 7.3728 MHz */ #define UART_DM_CLK_RX_TX_BIT_RATE 0xCC diff --git a/src/soc/rockchip/common/gpio.c b/src/soc/rockchip/common/gpio.c index fa0990b10b3..3d7e1614e04 100644 --- a/src/soc/rockchip/common/gpio.c +++ b/src/soc/rockchip/common/gpio.c @@ -20,6 +20,7 @@ #include #include #include +#include static void gpio_set_dir(gpio_t gpio, enum gpio_dir dir) { diff --git a/src/soc/rockchip/rk3399/include/soc/mipi.h b/src/soc/rockchip/rk3399/include/soc/mipi.h index f304d8fcd0f..43ab7b914f8 100644 --- a/src/soc/rockchip/rk3399/include/soc/mipi.h +++ b/src/soc/rockchip/rk3399/include/soc/mipi.h @@ -17,6 +17,7 @@ #define __RK_MIPI_H #include +#include struct rk_mipi_regs { u32 dsi_version; diff --git a/src/soc/rockchip/rk3399/mipi.c b/src/soc/rockchip/rk3399/mipi.c index cc16563c435..1f3f02cbee2 100644 --- a/src/soc/rockchip/rk3399/mipi.c +++ b/src/soc/rockchip/rk3399/mipi.c @@ -20,13 +20,13 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include static struct rk_mipi_dsi rk_mipi[2] = { From e39db681dfd7c4127f1ac0e360e0930e72ef3ee3 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 15 May 2019 21:12:31 +0200 Subject: [PATCH 502/588] src/mainboard: Add missing 'include ' is supposed to provide and . So when is included, and/or is removed. Change-Id: I3b1a395cfe8b710fb6b468e68f4c92e063794568 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32811 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/mainboard/asus/kcma-d8/romstage.c | 2 +- src/mainboard/asus/kgpe-d16/romstage.c | 2 +- src/mainboard/cubietech/cubieboard/romstage.c | 2 +- src/mainboard/lenovo/t430s/variants/t430s/romstage.c | 1 + src/mainboard/siemens/mc_apl1/mainboard.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl1/mainboard.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl1/ptn3460.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl3/mainboard.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl4/ptn3460.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl5/mainboard.c | 1 + src/mainboard/siemens/mc_apl1/variants/mc_apl5/ptn3460.c | 1 + src/mainboard/siemens/mc_tcu3/ptn3460.c | 1 + 13 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/mainboard/asus/kcma-d8/romstage.c b/src/mainboard/asus/kcma-d8/romstage.c index 5d43a542729..6c40627823b 100644 --- a/src/mainboard/asus/kcma-d8/romstage.c +++ b/src/mainboard/asus/kcma-d8/romstage.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include "cpu/amd/quadcore/quadcore.c" diff --git a/src/mainboard/asus/kgpe-d16/romstage.c b/src/mainboard/asus/kgpe-d16/romstage.c index f7d30bda98b..d017b0616a8 100644 --- a/src/mainboard/asus/kgpe-d16/romstage.c +++ b/src/mainboard/asus/kgpe-d16/romstage.c @@ -17,7 +17,6 @@ * GNU General Public License for more details. */ -#include #include #include #include @@ -45,6 +44,7 @@ #include #include #include +#include #include "cpu/amd/quadcore/quadcore.c" diff --git a/src/mainboard/cubietech/cubieboard/romstage.c b/src/mainboard/cubietech/cubieboard/romstage.c index 21fa9b535fb..bfb5e029d6d 100644 --- a/src/mainboard/cubietech/cubieboard/romstage.c +++ b/src/mainboard/cubietech/cubieboard/romstage.c @@ -31,7 +31,7 @@ #include #include #include - +#include #define GPB_TWI0_FUNC 2 #define GPB_TWI0_PINS ((1 << 0) | (1 << 1)) diff --git a/src/mainboard/lenovo/t430s/variants/t430s/romstage.c b/src/mainboard/lenovo/t430s/variants/t430s/romstage.c index e461681f190..5bc7b809614 100644 --- a/src/mainboard/lenovo/t430s/variants/t430s/romstage.c +++ b/src/mainboard/lenovo/t430s/variants/t430s/romstage.c @@ -22,6 +22,7 @@ #include #include #include +#include const struct southbridge_usb_port mainboard_usb_ports[] = { { 1, 0, 0 }, /* P0:, OC 0 */ diff --git a/src/mainboard/siemens/mc_apl1/mainboard.c b/src/mainboard/siemens/mc_apl1/mainboard.c index b39b6817f6e..c931e1008a1 100644 --- a/src/mainboard/siemens/mc_apl1/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/mainboard.c @@ -28,6 +28,7 @@ #include #include #include +#include #define MAX_PATH_DEPTH 12 #define MAX_NUM_MAPPINGS 10 diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl1/mainboard.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl1/mainboard.c index 6d22fd98268..df6fc21bdec 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl1/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl1/mainboard.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #define TX_DWORD3 0xa8c diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl1/ptn3460.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl1/ptn3460.c index 060a35c0a8e..c0770f31247 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl1/ptn3460.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl1/ptn3460.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /** diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c index f52091bced5..7890ee02113 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl2/mainboard.c @@ -24,6 +24,7 @@ #include #include #include +#include #define SD_CAP_BYP 0x810 #define SD_CAP_BYP_EN 0x5A diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl3/mainboard.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl3/mainboard.c index 3e2e7f09102..6a883c6a264 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl3/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl3/mainboard.c @@ -28,6 +28,7 @@ #include #include #include +#include #define TX_DWORD3 0xa8c diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl4/ptn3460.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl4/ptn3460.c index 73d901935ae..47763ae5d88 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl4/ptn3460.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl4/ptn3460.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /* diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl5/mainboard.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl5/mainboard.c index 9462497aa6e..e1b56bda131 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl5/mainboard.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl5/mainboard.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #define TX_DWORD3 0xa8c diff --git a/src/mainboard/siemens/mc_apl1/variants/mc_apl5/ptn3460.c b/src/mainboard/siemens/mc_apl1/variants/mc_apl5/ptn3460.c index 060a35c0a8e..c0770f31247 100644 --- a/src/mainboard/siemens/mc_apl1/variants/mc_apl5/ptn3460.c +++ b/src/mainboard/siemens/mc_apl1/variants/mc_apl5/ptn3460.c @@ -16,6 +16,7 @@ #include #include #include +#include #include /** diff --git a/src/mainboard/siemens/mc_tcu3/ptn3460.c b/src/mainboard/siemens/mc_tcu3/ptn3460.c index 9acc60a3452..414baeb089b 100644 --- a/src/mainboard/siemens/mc_tcu3/ptn3460.c +++ b/src/mainboard/siemens/mc_tcu3/ptn3460.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "soc/i2c.h" #include "ptn3460.h" From a95a6bf646aee936d841f458812f2ced3a29e6f7 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Tue, 16 Jan 2018 18:59:54 +0100 Subject: [PATCH 503/588] libpayload/drivers/i8402/kbd: Fix qemu Reset keyboard controller to fix qemu make scan codes. Change-Id: I5f8ad2d4be4b9e89d9af3a62726259e77f0403c1 Signed-off-by: Patrick Rudolph Reviewed-on: https://review.coreboot.org/c/coreboot/+/23584 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- payloads/libpayload/drivers/i8042/keyboard.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index fea9e718ddf..12255fb7f81 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -333,6 +333,14 @@ void keyboard_init(void) if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) return; + /* + * Set default parameters. + * Fix for broken QEMU ps/2 make scancodes. + */ + ret = keyboard_cmd(0xf6); + if (!ret) + return; + /* Enable scanning */ ret = keyboard_cmd(I8042_KBCMD_EN); if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) From 9b5e8c171868f3c559eb0f51a5b6f20cf5d0b7f9 Mon Sep 17 00:00:00 2001 From: Damien Zammit Date: Sat, 2 Sep 2017 18:28:29 +1000 Subject: [PATCH 504/588] xcompile: Remove --rtlib switch from clang CFLAGS Fix the following error from clang invoking gcc linker with wrong arg: i386-elf-gcc: error: unrecognized command line option '--rtlib=libgcc'; did you mean '-static-libgcc'? clang-4.0: error: linker (via gcc) command failed with exit code 1 Just remove --rtlib switch from CFLAGS relating to clang Change-Id: Ife7ef6b6b47a04598fc67b40751bc59eed93b4af Signed-off-by: Damien Zammit Reviewed-on: https://review.coreboot.org/c/coreboot/+/21354 Tested-by: build bot (Jenkins) Reviewed-by: Martin Roth --- util/xcompile/xcompile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/xcompile/xcompile b/util/xcompile/xcompile index 40356d93d9e..7ab1cb7af83 100755 --- a/util/xcompile/xcompile +++ b/util/xcompile/xcompile @@ -453,7 +453,7 @@ test_architecture() { # but that's more of a clang limitation. Let's be optimistic # that this will change in the future. CLANG="${clang_prefix}clang" - CFLAGS_CLANG="-target ${clang_arch}-${TABI} --rtlib=${CLANG_RUNTIME} $CFLAGS_CLANG -ccc-gcc-name ${GCC}" + CFLAGS_CLANG="-target ${clang_arch}-${TABI} $CFLAGS_CLANG -ccc-gcc-name ${GCC}" fi } From 2b99a01e0d28ae3c755480e12beb130e8b1550ac Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Wed, 29 May 2019 22:52:23 +0200 Subject: [PATCH 505/588] soc/rockchip/rk3288: Disable bootblock console Bootblock space is tight on this SoC and recent changes increased it ever so slightly to make this a problem. Since the bootblock is well-tested, we can get by without console. Change-Id: I7496a3e313b2c6ee6fb3c4671eac64376d84e0dc Signed-off-by: Patrick Georgi Reviewed-on: https://review.coreboot.org/c/coreboot/+/33068 Reviewed-by: Angel Pons Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/soc/rockchip/rk3288/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/soc/rockchip/rk3288/Kconfig b/src/soc/rockchip/rk3288/Kconfig index 38d87524b77..f845f07514f 100644 --- a/src/soc/rockchip/rk3288/Kconfig +++ b/src/soc/rockchip/rk3288/Kconfig @@ -30,6 +30,7 @@ config SOC_ROCKCHIP_RK3288 select MAINBOARD_HAS_NATIVE_VGA_INIT select MAINBOARD_FORCE_NATIVE_VGA_INIT select HAVE_LINEAR_FRAMEBUFFER + select NO_BOOTBLOCK_CONSOLE if SOC_ROCKCHIP_RK3288 From 10490b98e2c8b7b0c6c275b6b809d48697f6ee2f Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 21 Mar 2019 23:17:06 +0100 Subject: [PATCH 506/588] mb/roda/rk9: Document flash header Change-Id: I5bd131635340ffa0c6b8979fc8e263fc5f09fdc5 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32025 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- Documentation/mainboard/index.md | 4 ++++ .../mainboard/roda/rk9/flash_header.md | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 Documentation/mainboard/roda/rk9/flash_header.md diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index 7e0dab2f4c3..fb4f5022aac 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -81,6 +81,10 @@ The boards in this section are not real mainboards, but emulators. - [MS-7707](msi/ms7707/ms7707.md) +## Roda + +- [RK9 Flash Header](roda/rk9/flash_header.md) + ## SiFive - [SiFive HiFive Unleashed](sifive/hifive-unleashed.md) diff --git a/Documentation/mainboard/roda/rk9/flash_header.md b/Documentation/mainboard/roda/rk9/flash_header.md new file mode 100644 index 00000000000..c2978cbe682 --- /dev/null +++ b/Documentation/mainboard/roda/rk9/flash_header.md @@ -0,0 +1,23 @@ +Roda RK9 Flash Header +===================== + +There is a 5x2 pin, 1.27mm pitch header *J1* south of the BIOS flash. It +follows the pinout of the Dediprog adaptor board: + + +------+ + | 1 2 | 1: HOLD 2 2: CS 2 + | 3 4 | 3: CS 1 4: VCC + | 5 6 | 5: MISO 6: HOLD 1 + | 7 8 | 7: 8: CLK + | 9 10 | 9: GND 10: MOSI + +------+ + +Pins 3 to 10 directly map to the regular SPI flash pinout. + +There is also a *JP17* around. Ideally, it should be closed during +programming (isolates the SPI bus from the southbridge): + + +---+ + | 1 | 1: SF100-I/O3 + | 2 | 2: GND + +---+ From d64f8899728edfb645dde10a1f6f1fb46df13a15 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 30 May 2019 11:48:02 +0200 Subject: [PATCH 507/588] mb/lenovo/*20*: Remove default FMAP These boards don't need a default FMAP. Moreover, having a default FMAP disables automatic integration of optional regions like `CONSOLE`. Also, these files contain an error: `COREBOOT` isn't placed at the top of the image. Resulting in default builds without a reset vector ;) Change-Id: If6331e19955034c02828e88902a5934c34d3e784 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33110 Reviewed-by: Patrick Rudolph Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t420/Kconfig | 1 - src/mainboard/lenovo/t420/board.fmd | 16 ---------------- src/mainboard/lenovo/t420s/Kconfig | 1 - src/mainboard/lenovo/t420s/board.fmd | 16 ---------------- src/mainboard/lenovo/t520/Kconfig | 1 - src/mainboard/lenovo/t520/board.fmd | 16 ---------------- src/mainboard/lenovo/x220/Kconfig | 1 - src/mainboard/lenovo/x220/board.fmd | 16 ---------------- 8 files changed, 68 deletions(-) delete mode 100644 src/mainboard/lenovo/t420/board.fmd delete mode 100644 src/mainboard/lenovo/t420s/board.fmd delete mode 100644 src/mainboard/lenovo/t520/board.fmd delete mode 100644 src/mainboard/lenovo/x220/board.fmd diff --git a/src/mainboard/lenovo/t420/Kconfig b/src/mainboard/lenovo/t420/Kconfig index 3d3b56ae22d..02bcc4f4a49 100644 --- a/src/mainboard/lenovo/t420/Kconfig +++ b/src/mainboard/lenovo/t420/Kconfig @@ -46,7 +46,6 @@ config VBOOT_VBNV_OFFSET config FMDFILE string default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT - default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" config MAINBOARD_DIR string diff --git a/src/mainboard/lenovo/t420/board.fmd b/src/mainboard/lenovo/t420/board.fmd deleted file mode 100644 index 04cf827a87c..00000000000 --- a/src/mainboard/lenovo/t420/board.fmd +++ /dev/null @@ -1,16 +0,0 @@ -FLASH@0xff800000 0x800000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME@0x3000 0x4ed000 - } - SI_BIOS@0x500000 0x300000 { - RW_MRC_CACHE@0 0x10000 - SMMSTORE(PRESERVE)@0x10000 0x40000 - - WP_RO@0x50000 0x2a0000 { - FMAP@0x0 0x800 - COREBOOT(CBFS)@0x1000 0x29f000 - } - } -} diff --git a/src/mainboard/lenovo/t420s/Kconfig b/src/mainboard/lenovo/t420s/Kconfig index 1383d4166c2..60735b049db 100644 --- a/src/mainboard/lenovo/t420s/Kconfig +++ b/src/mainboard/lenovo/t420s/Kconfig @@ -45,7 +45,6 @@ config VBOOT_VBNV_OFFSET config FMDFILE string default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT - default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" config MAINBOARD_DIR string diff --git a/src/mainboard/lenovo/t420s/board.fmd b/src/mainboard/lenovo/t420s/board.fmd deleted file mode 100644 index 04cf827a87c..00000000000 --- a/src/mainboard/lenovo/t420s/board.fmd +++ /dev/null @@ -1,16 +0,0 @@ -FLASH@0xff800000 0x800000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME@0x3000 0x4ed000 - } - SI_BIOS@0x500000 0x300000 { - RW_MRC_CACHE@0 0x10000 - SMMSTORE(PRESERVE)@0x10000 0x40000 - - WP_RO@0x50000 0x2a0000 { - FMAP@0x0 0x800 - COREBOOT(CBFS)@0x1000 0x29f000 - } - } -} diff --git a/src/mainboard/lenovo/t520/Kconfig b/src/mainboard/lenovo/t520/Kconfig index ba17e8092b3..e847f8e39de 100644 --- a/src/mainboard/lenovo/t520/Kconfig +++ b/src/mainboard/lenovo/t520/Kconfig @@ -58,7 +58,6 @@ config DEVICETREE config FMDFILE string default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT - default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" config MAINBOARD_PART_NUMBER string diff --git a/src/mainboard/lenovo/t520/board.fmd b/src/mainboard/lenovo/t520/board.fmd deleted file mode 100644 index 04cf827a87c..00000000000 --- a/src/mainboard/lenovo/t520/board.fmd +++ /dev/null @@ -1,16 +0,0 @@ -FLASH@0xff800000 0x800000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME@0x3000 0x4ed000 - } - SI_BIOS@0x500000 0x300000 { - RW_MRC_CACHE@0 0x10000 - SMMSTORE(PRESERVE)@0x10000 0x40000 - - WP_RO@0x50000 0x2a0000 { - FMAP@0x0 0x800 - COREBOOT(CBFS)@0x1000 0x29f000 - } - } -} diff --git a/src/mainboard/lenovo/x220/Kconfig b/src/mainboard/lenovo/x220/Kconfig index 358cf8ec39c..c80c2520b26 100644 --- a/src/mainboard/lenovo/x220/Kconfig +++ b/src/mainboard/lenovo/x220/Kconfig @@ -53,7 +53,6 @@ config VARIANT_DIR config FMDFILE string default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/vboot-rwa.fmd" if VBOOT - default "src/mainboard/$(CONFIG_MAINBOARD_DIR)/board.fmd" config MAINBOARD_PART_NUMBER string diff --git a/src/mainboard/lenovo/x220/board.fmd b/src/mainboard/lenovo/x220/board.fmd deleted file mode 100644 index 04cf827a87c..00000000000 --- a/src/mainboard/lenovo/x220/board.fmd +++ /dev/null @@ -1,16 +0,0 @@ -FLASH@0xff800000 0x800000 { - SI_ALL@0x0 0x500000 { - SI_DESC@0x0 0x1000 - SI_GBE@0x1000 0x2000 - SI_ME@0x3000 0x4ed000 - } - SI_BIOS@0x500000 0x300000 { - RW_MRC_CACHE@0 0x10000 - SMMSTORE(PRESERVE)@0x10000 0x40000 - - WP_RO@0x50000 0x2a0000 { - FMAP@0x0 0x800 - COREBOOT(CBFS)@0x1000 0x29f000 - } - } -} From 695da71e615e9c946df64b79795a8d73228fb629 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Thu, 30 May 2019 09:56:35 +0530 Subject: [PATCH 508/588] src/vendorcode/amd/pi: Fix CONFIG() check issue in rules.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes problem of adding CONFIG() check inside rules.h. Change-Id: Ifb6842d0efef3521642c5c399fdf2876f71b167a Signed-off-by: Subrata Banik Signed-off-by: Ronald G. Minnich Reviewed-on: https://review.coreboot.org/c/coreboot/+/33105 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki --- src/vendorcode/amd/pi/00670F00/Makefile.inc | 2 +- src/vendorcode/amd/pi/Makefile.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vendorcode/amd/pi/00670F00/Makefile.inc b/src/vendorcode/amd/pi/00670F00/Makefile.inc index 0e6f2afd1c2..790955a1d0d 100644 --- a/src/vendorcode/amd/pi/00670F00/Makefile.inc +++ b/src/vendorcode/amd/pi/00670F00/Makefile.inc @@ -77,8 +77,8 @@ $(call src-to-obj,libagesa,$1): $(agesa_src_path)/$(notdir $1) $(obj)/config.h $ @printf " CC $$(subst $(obj)/,,$$(@))\n" $(CC_libagesa) -c -MMD $(CFLAGS_libagesa) $(AGESA_CFLAGS) \ $(AGESA_INC) \ - -include $(src)/include/rules.h \ -include $(src)/include/kconfig.h \ + -include $(src)/include/rules.h \ -include $(src)/commonlib/include/commonlib/compiler.h \ -o $$@ \ $(agesa_src_path)/$(notdir $1) diff --git a/src/vendorcode/amd/pi/Makefile.inc b/src/vendorcode/amd/pi/Makefile.inc index 4c8db6ab503..4e8787bed22 100644 --- a/src/vendorcode/amd/pi/Makefile.inc +++ b/src/vendorcode/amd/pi/Makefile.inc @@ -100,8 +100,8 @@ $(call src-to-obj,libagesa,$1): $(agesa_src_path)/$(notdir $1) $(obj)/config.h $ @printf " CC $$(subst $(obj)/,,$$(@))\n" $(CC_libagesa) -c -MMD $(CFLAGS_libagesa) $(AGESA_CFLAGS) \ $(AGESA_INC) \ - -include $(src)/include/rules.h \ -include $(src)/include/kconfig.h \ + -include $(src)/include/rules.h \ -include $(src)/commonlib/include/commonlib/compiler.h \ -o $$@ \ $(agesa_src_path)/$(notdir $1) From a1d0928b0014def7481bd5ed4ede739a3aac42ba Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Wed, 29 May 2019 15:48:10 -0700 Subject: [PATCH 509/588] soc/intel/common/block/gpio: Fix the mask for gpio_pm_configure gpio_pm_configure clears out all the bits related to PM configuration in MISCCFG register and sets only the bits requested by mainboard. The mask as it is set currently results in preserving all PM bits instead of clearing them. This change updates the mask to ensure that the PM bits are cleared before setting the ones requested by mainboard. Change-Id: I5b8c04952775dc1e94fa229328be2f3c1102a468 Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/33099 Tested-by: build bot (Jenkins) Reviewed-by: Subrata Banik Reviewed-by: Paul Fagerburg Reviewed-by: Tim Wawrzynczak --- src/soc/intel/common/block/gpio/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/gpio/gpio.c b/src/soc/intel/common/block/gpio/gpio.c index d37601ce3b7..7ebf05a2209 100644 --- a/src/soc/intel/common/block/gpio/gpio.c +++ b/src/soc/intel/common/block/gpio/gpio.c @@ -615,7 +615,7 @@ void gpio_pm_configure(const uint8_t *misccfg_pm_values, size_t num) { int i; size_t gpio_communities; - uint8_t misccfg_pm_mask = MISCCFG_ENABLE_GPIO_PM_CONFIG; + const uint8_t misccfg_pm_mask = ~MISCCFG_ENABLE_GPIO_PM_CONFIG; const struct pad_community *comm; comm = soc_gpio_get_community(&gpio_communities); From 7fa3d5673c5d9837d55b6de69419a6871eee8438 Mon Sep 17 00:00:00 2001 From: Paul Fagerburg Date: Tue, 21 May 2019 14:54:26 -0600 Subject: [PATCH 510/588] mb/google/hatch: Create kindred variant Create the Kindred variant of Hatch by taking a copy of the Hatch files as placeholders. Kindred-specific changes will happen in future CLs. BUG=b:133181366 BRANCH=NONE TEST=util/abuild/abuild -p none -t google/hatch -x -a make sure the build includes GOOGLE_KINDRED Change-Id: I09ad3da0505d599fc3797d7fa24b4dc170dcd18b Signed-off-by: Paul Fagerburg Reviewed-on: https://review.coreboot.org/c/coreboot/+/32936 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/hatch/Kconfig | 3 + src/mainboard/google/hatch/Kconfig.name | 6 + .../hatch/variants/kindred/Makefile.inc | 20 +++ .../kindred/include/variant/acpi/dptf.asl | 16 ++ .../variants/kindred/include/variant/ec.h | 21 +++ .../variants/kindred/include/variant/gpio.h | 21 +++ .../hatch/variants/kindred/overridetree.cb | 158 ++++++++++++++++++ 7 files changed, 245 insertions(+) create mode 100644 src/mainboard/google/hatch/variants/kindred/Makefile.inc create mode 100644 src/mainboard/google/hatch/variants/kindred/include/variant/acpi/dptf.asl create mode 100644 src/mainboard/google/hatch/variants/kindred/include/variant/ec.h create mode 100644 src/mainboard/google/hatch/variants/kindred/include/variant/gpio.h create mode 100644 src/mainboard/google/hatch/variants/kindred/overridetree.cb diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index 09f792128ca..e3927c0c251 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -65,6 +65,7 @@ config GBB_HWID default "HATCH TEST 1823" if BOARD_GOOGLE_HATCH default "HATCH_WHL TEST 2374" if BOARD_GOOGLE_HATCH_WHL default "KOHAKU TEST 1953" if BOARD_GOOGLE_KOHAKU + default "KINDRED TEST 2636" if BOARD_GOOGLE_KINDRED config MAINBOARD_DIR string @@ -79,6 +80,7 @@ config MAINBOARD_PART_NUMBER default "Hatch" if BOARD_GOOGLE_HATCH default "Hatch_whl" if BOARD_GOOGLE_HATCH_WHL default "Kohaku" if BOARD_GOOGLE_KOHAKU + default "Kindred" if BOARD_GOOGLE_KINDRED config MAINBOARD_VENDOR string @@ -101,6 +103,7 @@ config VARIANT_DIR default "hatch" if BOARD_GOOGLE_HATCH default "hatch_whl" if BOARD_GOOGLE_HATCH_WHL default "kohaku" if BOARD_GOOGLE_KOHAKU + default "kindred" if BOARD_GOOGLE_KINDRED config VBOOT select HAS_RECOVERY_MRC_CACHE diff --git a/src/mainboard/google/hatch/Kconfig.name b/src/mainboard/google/hatch/Kconfig.name index eb8e61274a8..43fd4bed9b0 100644 --- a/src/mainboard/google/hatch/Kconfig.name +++ b/src/mainboard/google/hatch/Kconfig.name @@ -17,3 +17,9 @@ config BOARD_GOOGLE_KOHAKU select BOARD_GOOGLE_BASEBOARD_HATCH select BOARD_ROMSIZE_KB_16384 select SOC_INTEL_COMETLAKE + +config BOARD_GOOGLE_KINDRED + bool "-> Kindred" + select BOARD_GOOGLE_BASEBOARD_HATCH + select BOARD_ROMSIZE_KB_16384 + select SOC_INTEL_COMETLAKE diff --git a/src/mainboard/google/hatch/variants/kindred/Makefile.inc b/src/mainboard/google/hatch/variants/kindred/Makefile.inc new file mode 100644 index 00000000000..8173ca4389a --- /dev/null +++ b/src/mainboard/google/hatch/variants/kindred/Makefile.inc @@ -0,0 +1,20 @@ +## This file is part of the coreboot project. +## +## Copyright 2019 Google LLC +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +SPD_SOURCES = 4G_2400 # 0b000 +SPD_SOURCES += empty_ddr4 # 0b001 +SPD_SOURCES += 8G_2400 # 0b010 +SPD_SOURCES += 8G_2666 # 0b011 +SPD_SOURCES += 16G_2400 # 0b100 +SPD_SOURCES += 16G_2666 # 0b101 diff --git a/src/mainboard/google/hatch/variants/kindred/include/variant/acpi/dptf.asl b/src/mainboard/google/hatch/variants/kindred/include/variant/acpi/dptf.asl new file mode 100644 index 00000000000..f1f09438fae --- /dev/null +++ b/src/mainboard/google/hatch/variants/kindred/include/variant/acpi/dptf.asl @@ -0,0 +1,16 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include diff --git a/src/mainboard/google/hatch/variants/kindred/include/variant/ec.h b/src/mainboard/google/hatch/variants/kindred/include/variant/ec.h new file mode 100644 index 00000000000..768987d2258 --- /dev/null +++ b/src/mainboard/google/hatch/variants/kindred/include/variant/ec.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef VARIANT_EC_H +#define VARIANT_EC_H + +#include + +#endif diff --git a/src/mainboard/google/hatch/variants/kindred/include/variant/gpio.h b/src/mainboard/google/hatch/variants/kindred/include/variant/gpio.h new file mode 100644 index 00000000000..d99e2bbd65e --- /dev/null +++ b/src/mainboard/google/hatch/variants/kindred/include/variant/gpio.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#endif diff --git a/src/mainboard/google/hatch/variants/kindred/overridetree.cb b/src/mainboard/google/hatch/variants/kindred/overridetree.cb new file mode 100644 index 00000000000..562bb8b229e --- /dev/null +++ b/src/mainboard/google/hatch/variants/kindred/overridetree.cb @@ -0,0 +1,158 @@ +chip soc/intel/cannonlake + + register "SerialIoDevMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoPci, + [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoPci, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoPci, + [PchSerialIoIndexSPI0] = PchSerialIoPci, + [PchSerialIoIndexSPI1] = PchSerialIoPci, + [PchSerialIoIndexSPI2] = PchSerialIoDisabled, + [PchSerialIoIndexUART0] = PchSerialIoSkipInit, + [PchSerialIoIndexUART1] = PchSerialIoDisabled, + [PchSerialIoIndexUART2] = PchSerialIoDisabled, + }" + + # Intel Common SoC Config + #+-------------------+---------------------------+ + #| Field | Value | + #+-------------------+---------------------------+ + #| GSPI0 | cr50 TPM. Early init is | + #| | required to set up a BAR | + #| | for TPM communication | + #| | before memory is up | + #| GSPI1 | FP MCU | + #| I2C0 | Touchpad | + #| I2C1 | Touch screen | + #| I2C4 | Audio | + #+-------------------+---------------------------+ + register "common_soc_config" = "{ + .gspi[0] = { + .speed_mhz = 1, + .early_init = 1, + }, + .i2c[0] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[1] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + }, + }" + + # GPIO for SD card detect + register "sdcard_cd_gpio" = "vSD3_CD_B" + + device domain 0 on + device pci 15.0 on + chip drivers/i2c/generic + register "hid" = ""ELAN0000"" + register "desc" = ""ELAN Touchpad"" + register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_D21_IRQ)" + register "wake" = "GPE0_DW0_21" + device i2c 15 on end + end + end # I2C #0 + device pci 15.1 on + chip drivers/i2c/generic + register "hid" = ""ELAN0001"" + register "desc" = ""ELAN Touchscreen"" + register "irq" = "ACPI_IRQ_EDGE_LOW(GPP_D16_IRQ)" + register "probed" = "1" + register "reset_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D15)" + register "reset_delay_ms" = "100" + register "reset_off_delay_ms" = "5" + register "has_power_resource" = "1" + register "stop_gpio" = "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_C4)" + register "stop_off_delay_ms" = "5" + device i2c 49 on end + end + chip drivers/i2c/hid + register "generic.hid" = ""GDIX0000"" + register "generic.desc" = ""Goodix Touchscreen"" + register "generic.irq" = "ACPI_IRQ_EDGE_LOW(GPP_D16_IRQ)" + register "generic.probed" = "1" + register "generic.reset_gpio" = + "ACPI_GPIO_OUTPUT_ACTIVE_LOW(GPP_D15)" + register "generic.reset_delay_ms" = "10" + register "generic.reset_off_delay_ms" = "1" + register "generic.has_power_resource" = "1" + register "hid_desc_reg_offset" = "0x01" + device i2c 5d on end + end + chip drivers/generic/gpio_keys + register "name" = ""PENH"" + register "gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_A8)" + register "key.wake" = "GPE0_DW0_08" + register "key.wakeup_event_action" = "EV_ACT_ASSERTED" + register "key.dev_name" = ""EJCT"" + register "key.linux_code" = "SW_PEN_INSERTED" + register "key.linux_input_type" = "EV_SW" + register "key.label" = ""pen_eject"" + device generic 0 on end + end + end # I2C #1 + device pci 15.2 off end # I2C #2 + device pci 15.3 on + chip drivers/i2c/sx9310 + register "desc" = ""SAR Proximity Sensor"" + register "irq_gpio" = "ACPI_GPIO_IRQ_LEVEL_LOW(GPP_A0)" + register "speed" = "I2C_SPEED_FAST" + register "uid" = "1" + register "reg_prox_ctrl0" = "0x10" + register "reg_prox_ctrl1" = "0x00" + register "reg_prox_ctrl2" = "0x84" + register "reg_prox_ctrl3" = "0x0e" + register "reg_prox_ctrl4" = "0x07" + register "reg_prox_ctrl5" = "0xc6" + register "reg_prox_ctrl6" = "0x20" + register "reg_prox_ctrl7" = "0x0d" + register "reg_prox_ctrl8" = "0x8d" + register "reg_prox_ctrl9" = "0x43" + register "reg_prox_ctrl10" = "0x1f" + register "reg_prox_ctrl11" = "0x00" + register "reg_prox_ctrl12" = "0x00" + register "reg_prox_ctrl13" = "0x00" + register "reg_prox_ctrl14" = "0x00" + register "reg_prox_ctrl15" = "0x00" + register "reg_prox_ctrl16" = "0x00" + register "reg_prox_ctrl17" = "0x00" + register "reg_prox_ctrl18" = "0x00" + register "reg_prox_ctrl19" = "0x00" + register "reg_sar_ctrl0" = "0x50" + register "reg_sar_ctrl1" = "0x8a" + register "reg_sar_ctrl2" = "0x3c" + device i2c 28 on end + end + end # I2C #3 + device pci 19.0 on + chip drivers/i2c/generic + register "hid" = ""10EC5682"" + register "name" = ""RT58"" + register "desc" = ""Realtek RT5682"" + register "irq_gpio" = "ACPI_GPIO_IRQ_EDGE_BOTH(GPP_H0)" + register "property_count" = "1" + # Set the jd_src to RT5668_JD1 for jack detection + register "property_list[0].type" = "ACPI_DP_TYPE_INTEGER" + register "property_list[0].name" = ""realtek,jd-src"" + register "property_list[0].integer" = "1" + device i2c 1a on end + end + end #I2C #4 + device pci 1e.3 on + chip drivers/spi/acpi + register "name" = ""CRFP"" + register "hid" = "ACPI_DT_NAMESPACE_HID" + register "uid" = "1" + register "compat_string" = ""google,cros-ec-spi"" + register "irq" = "ACPI_IRQ_LEVEL_LOW(GPP_A23_IRQ)" + device spi 1 on end + end # FPMCU + end # GSPI #1 + end + +end From a66c9b8bf4e4db0a108f90c21084ecc25aa87e72 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 20 May 2019 14:53:47 -0700 Subject: [PATCH 511/588] string.h: Move common string functions into .c file There's no clear reason why most of coreboot's basic string functions are static inline. These functions don't particularly benefit from inlining (at least not notably more than other functions). This patch moves them to string.c to be more consistent with our usual coding practices. Leaving the ctype functions as static inline because they actually seem small and collapsible enough that inlining seems reasonable. Also clarified the situation of strdup() and strconcat() a bit more, optimized strrchr() to be single-pass, fixed a bug with using strchr() to find '\0' and got rid of unnecessary register keywords. Change-Id: I88166ba9876e94dfa3cfc06969c78a9e1bc6fc36 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32901 Tested-by: build bot (Jenkins) Reviewed-by: Alex Thiessen --- src/include/string.h | 119 +++++-------------------------------------- src/lib/Makefile.inc | 9 +++- src/lib/string.c | 109 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 131 insertions(+), 106 deletions(-) diff --git a/src/include/string.h b/src/include/string.h index c56a760a047..d164f32b83c 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -25,33 +25,13 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args); #endif char *strdup(const char *s); char *strconcat(const char *s1, const char *s2); - -// simple string functions - -static inline size_t strnlen(const char *src, size_t max) -{ - size_t i = 0; - while ((*src++) && (i < max)) - i++; - return i; -} - -static inline size_t strlen(const char *src) -{ - size_t i = 0; - while (*src++) - i++; - return i; -} - -static inline char *strchr(const char *s, int c) -{ - for (; *s; s++) { - if (*s == c) - return (char *) s; - } - return 0; -} +size_t strnlen(const char *src, size_t max); +size_t strlen(const char *src); +char *strchr(const char *s, int c); +char *strncpy(char *to, const char *from, int count); +char *strcpy(char *dst, const char *src); +int strcmp(const char *s1, const char *s2); +int strncmp(const char *s1, const char *s2, int maxlen); /** * Find a character in a string. @@ -61,71 +41,14 @@ static inline char *strchr(const char *s, int c) * @return A pointer to the last occurrence of the character in the * string, or NULL if the character was not encountered within the string. */ -static inline char *strrchr(const char *s, int c) -{ - char *p = (char *)s + strlen(s); - - for (; p >= s; p--) { - if (*p == c) - return p; - } - - return NULL; -} - -static inline char *strncpy(char *to, const char *from, int count) -{ - register char *ret = to; - register char data; - - while (count > 0) { - count--; - data = *from++; - *to++ = data; - if (data == '\0') - break; - } - - while (count > 0) { - count--; - *to++ = '\0'; - } - return ret; -} - -static inline char *strcpy(char *dst, const char *src) -{ - char *ptr = dst; - - while (*src) - *dst++ = *src++; - *dst = '\0'; +char *strrchr(const char *s, int c); - return ptr; -} - -static inline int strcmp(const char *s1, const char *s2) -{ - int r; - - while ((r = (*s1 - *s2)) == 0 && *s1) { - s1++; - s2++; - } - return r; -} - -static inline int strncmp(const char *s1, const char *s2, int maxlen) -{ - int i; - - for (i = 0; i < maxlen; i++) { - if ((s1[i] != s2[i]) || (s1[i] == '\0')) - return s1[i] - s2[i]; - } - - return 0; -} +/* + * Parses an unsigned integer and moves the input pointer forward to the first + * character that's not a valid digit. s and *s must not be NULL. Result + * undefined if it overruns the return type size. + */ +unsigned int skip_atoi(char **s); static inline int isspace(int c) { @@ -179,18 +102,4 @@ static inline int tolower(int c) return c; } -/* - * Parses an unsigned integer and moves the input pointer forward to the first - * character that's not a valid digit. s and *s must not be NULL. Result - * undefined if it overruns the return type size. - */ -static inline unsigned int skip_atoi(char **s) -{ - unsigned int i = 0; - - while (isdigit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - #endif /* STRING_H */ diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 1350152a404..913675bac87 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -118,7 +118,6 @@ ramstage-y += bootmem.c ramstage-y += fmap.c ramstage-y += memchr.c ramstage-y += memcmp.c -ramstage-y += string.c ramstage-y += malloc.c smm-$(CONFIG_SMM_TSEG) += malloc.c ramstage-y += dimm_info_util.c @@ -244,6 +243,14 @@ postcar-y += reset.c ramstage-y += reset.c smm-y += reset.c +decompressor-y += string.c +bootblock-y += string.c +verstage-y += string.c +romstage-y += string.c +postcar-y += string.c +ramstage-y += string.c +smm-y += string.c + postcar-y += bootmode.c postcar-y += boot_device.c postcar-y += cbfs.c diff --git a/src/lib/string.c b/src/lib/string.c index 2e71489ff60..a19f0178520 100644 --- a/src/lib/string.c +++ b/src/lib/string.c @@ -1,9 +1,14 @@ +#include +#include #include #include #include char *strdup(const char *s) { + if (!ENV_RAMSTAGE) + dead_code(); /* This can't be used without malloc(). */ + size_t sz = strlen(s) + 1; char *d = malloc(sz); if (d) @@ -13,6 +18,9 @@ char *strdup(const char *s) char *strconcat(const char *s1, const char *s2) { + if (!ENV_RAMSTAGE) + dead_code(); /* This can't be used without malloc(). */ + size_t sz_1 = strlen(s1); size_t sz_2 = strlen(s2); char *d = malloc(sz_1 + sz_2 + 1); @@ -22,3 +30,104 @@ char *strconcat(const char *s1, const char *s2) } return d; } + +size_t strnlen(const char *src, size_t max) +{ + size_t i = 0; + while ((*src++) && (i < max)) + i++; + return i; +} + +size_t strlen(const char *src) +{ + size_t i = 0; + while (*src++) + i++; + return i; +} + +char *strchr(const char *s, int c) +{ + do { + if (*s == c) + return (char *)s; + } while (*s++); + + return NULL; +} + +char *strrchr(const char *s, int c) +{ + char *p = NULL; + + do { + if (*s == c) + p = (char *)s; + } while (*s++); + + return p; +} + +char *strncpy(char *to, const char *from, int count) +{ + char *ret = to; + char data; + + while (count > 0) { + count--; + data = *from++; + *to++ = data; + if (data == '\0') + break; + } + + while (count > 0) { + count--; + *to++ = '\0'; + } + return ret; +} + +char *strcpy(char *dst, const char *src) +{ + char *ptr = dst; + + while (*src) + *dst++ = *src++; + *dst = '\0'; + + return ptr; +} + +int strcmp(const char *s1, const char *s2) +{ + int r; + + while ((r = (*s1 - *s2)) == 0 && *s1) { + s1++; + s2++; + } + return r; +} + +int strncmp(const char *s1, const char *s2, int maxlen) +{ + int i; + + for (i = 0; i < maxlen; i++) { + if ((s1[i] != s2[i]) || (s1[i] == '\0')) + return s1[i] - s2[i]; + } + + return 0; +} + +unsigned int skip_atoi(char **s) +{ + unsigned int i = 0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} From cdc459e66a3c6b68bae2515120445a10483df7f4 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 21 May 2019 14:00:53 -0600 Subject: [PATCH 512/588] mb/google/hatch: Create helios variant Created helios (hatch variant). Currenly copied from kohaku. Helios- specific changes will come later. BUG=b:133182138 BRANCH=none TEST=none Change-Id: I9d151621a1c42e6f3cadb288f7ea476828c059b5 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32919 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg --- .../google/hatch/variants/helios/Makefile.inc | 20 ++++++++ .../helios/include/variant/acpi/dptf.asl | 16 +++++++ .../variants/helios/include/variant/ec.h | 21 +++++++++ .../variants/helios/include/variant/gpio.h | 21 +++++++++ .../hatch/variants/helios/overridetree.cb | 46 +++++++++++++++++++ 5 files changed, 124 insertions(+) create mode 100644 src/mainboard/google/hatch/variants/helios/Makefile.inc create mode 100644 src/mainboard/google/hatch/variants/helios/include/variant/acpi/dptf.asl create mode 100644 src/mainboard/google/hatch/variants/helios/include/variant/ec.h create mode 100644 src/mainboard/google/hatch/variants/helios/include/variant/gpio.h create mode 100644 src/mainboard/google/hatch/variants/helios/overridetree.cb diff --git a/src/mainboard/google/hatch/variants/helios/Makefile.inc b/src/mainboard/google/hatch/variants/helios/Makefile.inc new file mode 100644 index 00000000000..cf6ee5ac97d --- /dev/null +++ b/src/mainboard/google/hatch/variants/helios/Makefile.inc @@ -0,0 +1,20 @@ +## This file is part of the coreboot project. +## +## Copyright 2019 Google LLC +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +SPD_SOURCES = 4G_2400 # 0b000 +SPD_SOURCES += empty_ddr4 # 0b001 +SPD_SOURCES += 8G_2400 # 0b010 +SPD_SOURCES += 8G_2666 # 0b011 +SPD_SOURCES += 16G_2400 # 0b100 +SPD_SOURCES += 16G_2666 # 0b101 diff --git a/src/mainboard/google/hatch/variants/helios/include/variant/acpi/dptf.asl b/src/mainboard/google/hatch/variants/helios/include/variant/acpi/dptf.asl new file mode 100644 index 00000000000..f1f09438fae --- /dev/null +++ b/src/mainboard/google/hatch/variants/helios/include/variant/acpi/dptf.asl @@ -0,0 +1,16 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include diff --git a/src/mainboard/google/hatch/variants/helios/include/variant/ec.h b/src/mainboard/google/hatch/variants/helios/include/variant/ec.h new file mode 100644 index 00000000000..768987d2258 --- /dev/null +++ b/src/mainboard/google/hatch/variants/helios/include/variant/ec.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef VARIANT_EC_H +#define VARIANT_EC_H + +#include + +#endif diff --git a/src/mainboard/google/hatch/variants/helios/include/variant/gpio.h b/src/mainboard/google/hatch/variants/helios/include/variant/gpio.h new file mode 100644 index 00000000000..d99e2bbd65e --- /dev/null +++ b/src/mainboard/google/hatch/variants/helios/include/variant/gpio.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2019 Google LLC + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#ifndef VARIANT_GPIO_H +#define VARIANT_GPIO_H + +#include + +#endif diff --git a/src/mainboard/google/hatch/variants/helios/overridetree.cb b/src/mainboard/google/hatch/variants/helios/overridetree.cb new file mode 100644 index 00000000000..84f0e29afaf --- /dev/null +++ b/src/mainboard/google/hatch/variants/helios/overridetree.cb @@ -0,0 +1,46 @@ +chip soc/intel/cannonlake + register "SerialIoDevMode" = "{ + [PchSerialIoIndexI2C0] = PchSerialIoPci, + [PchSerialIoIndexI2C1] = PchSerialIoPci, + [PchSerialIoIndexI2C2] = PchSerialIoPci, + [PchSerialIoIndexI2C3] = PchSerialIoPci, + [PchSerialIoIndexI2C4] = PchSerialIoPci, + [PchSerialIoIndexI2C5] = PchSerialIoPci, + [PchSerialIoIndexSPI0] = PchSerialIoPci, + [PchSerialIoIndexSPI1] = PchSerialIoPci, + [PchSerialIoIndexSPI2] = PchSerialIoDisabled, + [PchSerialIoIndexUART0] = PchSerialIoSkipInit, + [PchSerialIoIndexUART1] = PchSerialIoDisabled, + [PchSerialIoIndexUART2] = PchSerialIoDisabled, + }" + + # Intel Common SoC Config + #+-------------------+---------------------------+ + #| Field | Value | + #+-------------------+---------------------------+ + #| I2C0 | Trackpad | + #| I2C1 | Touchscreen | + #| I2C2 | Digitizer | + #| I2C4 | Audio | + #+-------------------+---------------------------+ + register "common_soc_config" = "{ + .i2c[0] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[1] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[2] = { + .speed = I2C_SPEED_FAST, + }, + .i2c[4] = { + .speed = I2C_SPEED_FAST, + }, + .gspi[0] = { + .speed_mhz = 1, + .early_init = 1, + }, + }" + + device domain 0 on end +end From f3510cbe36717f217a7ccde2b1f5994694ddce99 Mon Sep 17 00:00:00 2001 From: Tim Wawrzynczak Date: Tue, 21 May 2019 11:03:01 -0600 Subject: [PATCH 513/588] mainboard/google/hatch: Add Helios support Add Helios as a variant of Hatch. BUG=b:133182138 BRANCH=None TEST=util/abuild/abuild -p none -t google/hatch -x -a attempts to build a Helios target. Change-Id: I64ba06932eb0ee32405f7b14a94971a64c8fce71 Signed-off-by: Tim Wawrzynczak Reviewed-on: https://review.coreboot.org/c/coreboot/+/32918 Reviewed-by: Shelley Chen Reviewed-by: Furquan Shaikh Reviewed-by: Paul Fagerburg Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/Kconfig | 9 ++++++--- src/mainboard/google/hatch/Kconfig.name | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/mainboard/google/hatch/Kconfig b/src/mainboard/google/hatch/Kconfig index e3927c0c251..80451299f67 100644 --- a/src/mainboard/google/hatch/Kconfig +++ b/src/mainboard/google/hatch/Kconfig @@ -64,8 +64,9 @@ config GBB_HWID depends on CHROMEOS default "HATCH TEST 1823" if BOARD_GOOGLE_HATCH default "HATCH_WHL TEST 2374" if BOARD_GOOGLE_HATCH_WHL - default "KOHAKU TEST 1953" if BOARD_GOOGLE_KOHAKU + default "HELIOS TEST 0878" if BOARD_GOOGLE_HELIOS default "KINDRED TEST 2636" if BOARD_GOOGLE_KINDRED + default "KOHAKU TEST 1953" if BOARD_GOOGLE_KOHAKU config MAINBOARD_DIR string @@ -79,8 +80,9 @@ config MAINBOARD_PART_NUMBER string default "Hatch" if BOARD_GOOGLE_HATCH default "Hatch_whl" if BOARD_GOOGLE_HATCH_WHL - default "Kohaku" if BOARD_GOOGLE_KOHAKU + default "Helios" if BOARD_GOOGLE_HELIOS default "Kindred" if BOARD_GOOGLE_KINDRED + default "Kohaku" if BOARD_GOOGLE_KOHAKU config MAINBOARD_VENDOR string @@ -102,8 +104,9 @@ config VARIANT_DIR string default "hatch" if BOARD_GOOGLE_HATCH default "hatch_whl" if BOARD_GOOGLE_HATCH_WHL - default "kohaku" if BOARD_GOOGLE_KOHAKU + default "helios" if BOARD_GOOGLE_HELIOS default "kindred" if BOARD_GOOGLE_KINDRED + default "kohaku" if BOARD_GOOGLE_KOHAKU config VBOOT select HAS_RECOVERY_MRC_CACHE diff --git a/src/mainboard/google/hatch/Kconfig.name b/src/mainboard/google/hatch/Kconfig.name index 43fd4bed9b0..9a257259ad4 100644 --- a/src/mainboard/google/hatch/Kconfig.name +++ b/src/mainboard/google/hatch/Kconfig.name @@ -23,3 +23,9 @@ config BOARD_GOOGLE_KINDRED select BOARD_GOOGLE_BASEBOARD_HATCH select BOARD_ROMSIZE_KB_16384 select SOC_INTEL_COMETLAKE + +config BOARD_GOOGLE_HELIOS + bool "-> Helios" + select BOARD_GOOGLE_BASEBOARD_HATCH + select BOARD_ROMSIZE_KB_16384 + select SOC_INTEL_COMETLAKE From 2761847f904ce695fc8e47929f65bf6da64bcb6d Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Thu, 30 May 2019 18:28:59 +0530 Subject: [PATCH 514/588] Makefile.inc: Remove unnecessary CONFIG dependency This patch removes unnecessary kconfig depencies as below 1. CONFIG_ARCH_RAMSTAGE_X86_32 2. CONFIG_RELOCATABLE_RAMSTAGE Include required files as is without specify kconfig option. Change-Id: Ic9d1a95e80178775dd78e756f97f6da13a24dc95 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/33113 Tested-by: build bot (Jenkins) Reviewed-by: ron minnich --- src/arch/x86/Makefile.inc | 4 ++-- src/lib/Makefile.inc | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/arch/x86/Makefile.inc b/src/arch/x86/Makefile.inc index 6e4ee76c55f..7e518d8c93e 100644 --- a/src/arch/x86/Makefile.inc +++ b/src/arch/x86/Makefile.inc @@ -193,7 +193,7 @@ verstage-$(CONFIG_VBOOT_SEPARATE_VERSTAGE) += gdt_init.S verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c verstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S -verstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c +verstage-y += cpu_common.c verstage-y += memset.c verstage-y += memcpy.c verstage-y += memmove.c @@ -230,7 +230,7 @@ romstage-y += boot.c romstage-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += gdt_init.S romstage-y += cbmem.c romstage-y += cbfs_and_run.c -romstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c +romstage-y += cpu_common.c romstage-$(CONFIG_EARLY_EBDA_INIT) += ebda.c romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += exception.c romstage-$(CONFIG_IDT_IN_EVERY_STAGE) += idt.S diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 913675bac87..1b8ad19b679 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -104,7 +104,7 @@ bootblock-$(CONFIG_ARCH_BOOTBLOCK_X86_32) += gcc.c verstage-$(CONFIG_ARCH_VERSTAGE_X86_32) += gcc.c romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c -smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c +smm-y += gcc.c endif romstage-$(CONFIG_GENERIC_UDELAY) += timer.c @@ -279,7 +279,7 @@ verstage-y += program.ld ifeq ($(CONFIG_RELOCATABLE_MODULES),y) ramstage-y += rmodule.c -romstage-$(CONFIG_RELOCATABLE_RAMSTAGE) += rmodule.c +romstage-y += rmodule.c RMODULE_LDFLAGS := -z defs -Bsymbolic From c82acf59311abbb7e27add8d452282d57ed988aa Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Fri, 22 Mar 2019 15:19:05 +0530 Subject: [PATCH 515/588] qualcomm/qcs405: enable SPI bus 4 for TPM Change-Id: Ic282daf10dad42bc4513cc55f15ce80a4bd316a5 Signed-off-by: Patrick Georgi Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/30934 Tested-by: build bot (Jenkins) --- src/mainboard/google/mistral/Makefile.inc | 1 + src/mainboard/google/mistral/verstage.c | 31 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/mainboard/google/mistral/verstage.c diff --git a/src/mainboard/google/mistral/Makefile.inc b/src/mainboard/google/mistral/Makefile.inc index 2cb963123bb..ca191d147e0 100644 --- a/src/mainboard/google/mistral/Makefile.inc +++ b/src/mainboard/google/mistral/Makefile.inc @@ -7,6 +7,7 @@ bootblock-y += bootblock.c verstage-y += memlayout.ld verstage-y += chromeos.c verstage-y += reset.c +verstage-y += verstage.c romstage-y += memlayout.ld romstage-y += chromeos.c diff --git a/src/mainboard/google/mistral/verstage.c b/src/mainboard/google/mistral/verstage.c new file mode 100644 index 00000000000..a34e4fa361f --- /dev/null +++ b/src/mainboard/google/mistral/verstage.c @@ -0,0 +1,31 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2016 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include + +void verstage_mainboard_init(void) +{ + struct spi_slave spi; + + printk(BIOS_ERR, "Trying to initialize TPM SPI bus\n"); + if (spi_setup_slave(CONFIG_DRIVER_TPM_SPI_BUS, + CONFIG_DRIVER_TPM_SPI_CHIP, &spi)) { + printk(BIOS_ERR, "Failed to setup TPM SPI slave\n"); + } +} From a2c219a91d41463bf8830b321ee461806f9698da Mon Sep 17 00:00:00 2001 From: Nitheesh Sekar Date: Fri, 22 Mar 2019 15:10:43 +0530 Subject: [PATCH 516/588] qcs405: Enable SPI-NOR Enable support for Gigadevice spi-nor flash. Change-Id: I340eb3bf77b25fe3502d4b29ef4bf7c06b282c02 Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/29968 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/mainboard/google/mistral/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/mistral/Kconfig b/src/mainboard/google/mistral/Kconfig index d1ab9c4f112..a2ba7cc24a5 100644 --- a/src/mainboard/google/mistral/Kconfig +++ b/src/mainboard/google/mistral/Kconfig @@ -10,6 +10,8 @@ config BOARD_SPECIFIC_OPTIONS select COMMON_CBFS_SPI_WRAPPER select SOC_QUALCOMM_QCS405 select SPI_FLASH + select SPI_FLASH_GIGADEVICE + select SPI_FLASH_WINBOND select MAINBOARD_HAS_CHROMEOS config VBOOT From a82f991122b199bcdaf51eb93dcdcd81825de2bf Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Sat, 29 Dec 2018 21:43:11 -0600 Subject: [PATCH 517/588] google/buddy: fix Windows ACPI error with WLAN Buddy's WLAN ACPI code was equivalent to, but formatted differently from the other auron variants. Since only differnce is root port used, have buddy use common WLAN ACPI and use preprocessor guards to set the root port correctly. Test: build/boot Buddy, verify Windows 10 boots without ACPI BIOS ERROR. Change-Id: I78d994f2bb3981d4d10cb534cd6e0ae673f73527 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/30523 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/mainboard/google/auron/acpi/mainboard.asl | 9 +++++-- .../google/auron/variants/buddy/devicetree.cb | 4 ++-- .../buddy/include/variant/acpi/mainboard.asl | 24 ------------------- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/src/mainboard/google/auron/acpi/mainboard.asl b/src/mainboard/google/auron/acpi/mainboard.asl index a07ce3e7bea..cd6a8305646 100644 --- a/src/mainboard/google/auron/acpi/mainboard.asl +++ b/src/mainboard/google/auron/acpi/mainboard.asl @@ -16,8 +16,14 @@ #include -#if !CONFIG(BOARD_GOOGLE_BUDDY) +/* + * WLAN on Buddy connected to RP4, becomes RP2 after coalesce + */ +#if CONFIG(BOARD_GOOGLE_BUDDY) +Scope (\_SB.PCI0.RP02) +#else Scope (\_SB.PCI0.RP01) +#endif { Device (WLAN) { @@ -35,7 +41,6 @@ Scope (\_SB.PCI0.RP01) } } } -#endif #include diff --git a/src/mainboard/google/auron/variants/buddy/devicetree.cb b/src/mainboard/google/auron/variants/buddy/devicetree.cb index e6627949b57..f75da84eee8 100644 --- a/src/mainboard/google/auron/variants/buddy/devicetree.cb +++ b/src/mainboard/google/auron/variants/buddy/devicetree.cb @@ -90,8 +90,8 @@ chip soc/intel/broadwell device pci 1b.0 off end # High Definition Audio device pci 1c.0 off end # PCIe Port #1 device pci 1c.1 off end # PCIe Port #2 - device pci 1c.2 on end # PCIe Port #3 - device pci 1c.3 on end # PCIe Port #4 + device pci 1c.2 on end # PCIe Port #3 - LAN (becomes RP1) + device pci 1c.3 on end # PCIe Port #4 - WLAN (becomes RP2) device pci 1c.4 on end # PCIe Port #5 device pci 1c.5 off end # PCIe Port #6 device pci 1d.0 on end # USB2 EHCI diff --git a/src/mainboard/google/auron/variants/buddy/include/variant/acpi/mainboard.asl b/src/mainboard/google/auron/variants/buddy/include/variant/acpi/mainboard.asl index 788fbdc61ec..e9fd212e8dc 100644 --- a/src/mainboard/google/auron/variants/buddy/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/auron/variants/buddy/include/variant/acpi/mainboard.asl @@ -117,27 +117,3 @@ Scope (\_SB.PCI0.RP01) } } } - -/* - * WLAN connected to Root Port 4, becomes Root Port 2 after coalesce - */ -Scope (\_SB.PCI0.RP02) -{ - Device (WLAN) - { - Name (_ADR, 0x00000000) - - /* GPIO10 is WLAN_WAKE_L_Q */ - Name (GPIO, BOARD_WLAN_WAKE_GPIO) - - Name (_PRW, Package() { GPIO, 3 }) - - Method (_DSW, 3, NotSerialized) - { - If (LEqual (Arg0, 1)) { - // Enable GPIO as wake source - \_SB.PCI0.LPCB.GPIO.GWAK (^GPIO) - } - } - } -} From 0da3a8a91bdfa97f658286717c9e6af0fcd69fe6 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Mon, 27 May 2019 02:09:24 -0500 Subject: [PATCH 518/588] soc/intel/baytrail: set default VBIOS filename and PCI ID All Baytrail boards have the same GPU PCI ID, so set it here to avoid having to set it in each board's config. Move the VGA_BIOS_FILE config from google/rambi into soc/baytrail since it likewise applies to all Baytrail boards. Change-Id: Id1e0580b55e3590d868cb839987f06c49bb07cf5 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/33026 Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/mainboard/google/rambi/Kconfig | 4 ---- src/soc/intel/baytrail/Kconfig | 10 ++++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/mainboard/google/rambi/Kconfig b/src/mainboard/google/rambi/Kconfig index c47b3d79090..56d44bcea0a 100644 --- a/src/mainboard/google/rambi/Kconfig +++ b/src/mainboard/google/rambi/Kconfig @@ -90,10 +90,6 @@ config EC_GOOGLE_CHROMEEC_BOARDNAME string default "" -config VGA_BIOS_FILE - string - default "pci8086,0f31.rom" - config MAINBOARD_SMBIOS_MANUFACTURER string default "GOOGLE" diff --git a/src/soc/intel/baytrail/Kconfig b/src/soc/intel/baytrail/Kconfig index 03ad31d41fa..43c2906f151 100644 --- a/src/soc/intel/baytrail/Kconfig +++ b/src/soc/intel/baytrail/Kconfig @@ -168,4 +168,14 @@ config REFCODE_BLOB_FILE endif # HAVE_REFCODE_BLOB +config VGA_BIOS_ID + string + depends on VGA_BIOS + default "8086,0f31" + +config VGA_BIOS_FILE + string + depends on VGA_BIOS + default "pci8086,0f31.rom" + endif From bfd23ce87bddafe5a1ff17d016cd88f6e746385b Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 30 May 2019 14:00:29 +0200 Subject: [PATCH 519/588] soc/intel/common/mmc: Replace IS_ENABLED() with CONFIG() Change-Id: I99d51176f6d7d6a98a3a3c82aa8e8eee73344496 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33111 Reviewed-by: Subrata Banik Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/include/intelblocks/early_mmc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/include/intelblocks/early_mmc.h b/src/soc/intel/common/block/include/intelblocks/early_mmc.h index 69be40cf27a..39aaf58fcf0 100644 --- a/src/soc/intel/common/block/include/intelblocks/early_mmc.h +++ b/src/soc/intel/common/block/include/intelblocks/early_mmc.h @@ -61,7 +61,7 @@ int soc_configure_mmc_gpios(void); */ int soc_get_mmc_dll(struct mmc_dll_params *params); -#if IS_ENABLED(CONFIG_SOC_INTEL_COMMON_EARLY_MMC_WAKE) +#if CONFIG(SOC_INTEL_COMMON_EARLY_MMC_WAKE) /* * Initializes sdhci / mmc controller and sends CMD0, CMD1 to emmc card. * In case of success: It returns 0 and adds cbmem entry CBMEM_ID_MMC_STATUS From d1b99d2bbf11ece1e724eb57dfe5a01a950715ca Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 30 May 2019 15:11:42 +0200 Subject: [PATCH 520/588] nb/intel/snb: Don't run VGA oprom when libgfxinit is enabled This was likely an oversight when libgfxinit got its own Kconfig symbols. Change-Id: I647551719b332b5b734720ae4ee0619bbfcbed8c Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33126 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/gma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/northbridge/intel/sandybridge/gma.c b/src/northbridge/intel/sandybridge/gma.c index 1005288fee6..19df8d4cc8e 100644 --- a/src/northbridge/intel/sandybridge/gma.c +++ b/src/northbridge/intel/sandybridge/gma.c @@ -626,7 +626,7 @@ static void gma_func0_init(struct device *dev) /* Init graphics power management */ gma_pm_init_pre_vbios(dev); - if (!CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) + if (!CONFIG(MAINBOARD_USE_LIBGFXINIT)) /* PCI Init, will run VBIOS */ pci_dev_init(dev); From ec93be5208e1bfece4165858d0d9e2b13e185ea3 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 30 May 2019 15:13:31 +0200 Subject: [PATCH 521/588] nb/intel/haswell/gma: Drop NGI remnant The native graphics init option was replaced with libgfxinit. Change-Id: I62569b70186b7b068effdadc4b39b3c09ddb7188 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33127 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/northbridge/intel/haswell/gma.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/northbridge/intel/haswell/gma.c b/src/northbridge/intel/haswell/gma.c index 607fab76028..ca446e25a7c 100644 --- a/src/northbridge/intel/haswell/gma.c +++ b/src/northbridge/intel/haswell/gma.c @@ -236,14 +236,6 @@ static void power_well_enable(void) { gtt_write(HSW_PWR_WELL_CTL1, HSW_PWR_WELL_ENABLE); gtt_poll(HSW_PWR_WELL_CTL1, HSW_PWR_WELL_STATE, HSW_PWR_WELL_STATE); - - /* In the native graphics case, we've got about 20 ms. - * after we power up the AUX channel until we can talk to it. - * So get that going right now. We can't turn on the panel, yet, just VDD. - */ - if (CONFIG(MAINBOARD_DO_NATIVE_VGA_INIT)) { - gtt_write(PCH_PP_CONTROL, PCH_PP_UNLOCK| EDP_FORCE_VDD | PANEL_POWER_RESET); - } } static void gma_pm_init_pre_vbios(struct device *dev) From 2e6c3c8936e4d5afcbd39226bc6b18a42119afee Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Thu, 30 May 2019 15:21:40 +0200 Subject: [PATCH 522/588] mb/google/link: Remove Link's own native graphics init The code was already orphaned since its hook-up was removed with a6be58fece (nb/intel/sandybridge: Remove the C native graphic init). Change-Id: Ia554c457e2f3a2dc42965ac5cded0be8e82311fb Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33128 Tested-by: build bot (Jenkins) Reviewed-by: Arthur Heymans Reviewed-by: Julius Werner --- src/mainboard/google/link/Kconfig | 2 - src/mainboard/google/link/Makefile.inc | 3 - src/mainboard/google/link/i915.c | 374 ------------------------- src/mainboard/google/link/i915io.c | 355 ----------------------- src/mainboard/google/link/i915io.h | 82 ------ src/mainboard/google/link/intel_dp.c | 166 ----------- 6 files changed, 982 deletions(-) delete mode 100644 src/mainboard/google/link/i915.c delete mode 100644 src/mainboard/google/link/i915io.c delete mode 100644 src/mainboard/google/link/i915io.h delete mode 100644 src/mainboard/google/link/intel_dp.c diff --git a/src/mainboard/google/link/Kconfig b/src/mainboard/google/link/Kconfig index 3628f1d8a54..6d62f64e3e7 100644 --- a/src/mainboard/google/link/Kconfig +++ b/src/mainboard/google/link/Kconfig @@ -14,8 +14,6 @@ config BOARD_SPECIFIC_OPTIONS select MAINBOARD_HAS_LPC_TPM select MAINBOARD_HAS_TPM1 select SERIRQ_CONTINUOUS_MODE - select MAINBOARD_HAS_NATIVE_VGA_INIT - select HAVE_LINEAR_FRAMEBUFFER if MAINBOARD_DO_NATIVE_VGA_INIT select MAINBOARD_HAS_LIBGFXINIT select HAVE_IFD_BIN select HAVE_ME_BIN diff --git a/src/mainboard/google/link/Makefile.inc b/src/mainboard/google/link/Makefile.inc index 281ce32442f..89bb3650233 100644 --- a/src/mainboard/google/link/Makefile.inc +++ b/src/mainboard/google/link/Makefile.inc @@ -17,9 +17,6 @@ ramstage-y += ec.c romstage-y += chromeos.c ramstage-y += chromeos.c -ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += i915.c -ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += i915io.c -ramstage-$(CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT) += intel_dp.c ramstage-$(CONFIG_MAINBOARD_USE_LIBGFXINIT) += gma-mainboard.ads smm-$(CONFIG_HAVE_SMI_HANDLER) += mainboard_smi.c diff --git a/src/mainboard/google/link/i915.c b/src/mainboard/google/link/i915.c deleted file mode 100644 index 12d424cde02..00000000000 --- a/src/mainboard/google/link/i915.c +++ /dev/null @@ -1,374 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ec.h" -#include "onboard.h" -#include "i915io.h" - -enum { - vmsg = 1, vio = 2, vspin = 4, -}; - -static int verbose = 0; - -static unsigned int *mmio; -static unsigned int graphics; -static unsigned short addrport; -static unsigned short dataport; -static unsigned int physbase; -static u32 htotal, hblank, hsync, vtotal, vblank, vsync; - -const u32 link_edid_data[] = { - 0xffffff00, 0x00ffffff, 0x0379e430, 0x00000000, - 0x04011500, 0x96121ba5, 0xa2d54f02, 0x26935259, - 0x00545017, 0x01010000, 0x01010101, 0x01010101, - 0x01010101, 0x6f6d0101, 0xa4a0a000, 0x20306031, - 0xb510003a, 0x19000010, 0x00000000, 0x00000000, - 0x00000000, 0x00000000, 0x00000000, 0x4c00fe00, - 0x69442047, 0x616c7073, 0x20200a79, 0xfe000000, - 0x31504c00, 0x45513932, 0x50532d31, 0x24003141, -}; - -#define READ32(addr) io_i915_READ32(addr) -#define WRITE32(val, addr) io_i915_WRITE32(val, addr) - -static char *regname(unsigned long addr) -{ - static char name[16]; - snprintf(name, sizeof(name), "0x%lx", addr); - return name; -} - -unsigned long io_i915_READ32(unsigned long addr) -{ - unsigned long val; - outl(addr, addrport); - val = inl(dataport); - if (verbose & vio) - printk(BIOS_SPEW, "%s: Got %08lx\n", regname(addr), val); - return val; -} - -void io_i915_WRITE32(unsigned long val, unsigned long addr) -{ - if (verbose & vio) - printk(BIOS_SPEW, "%s: outl %08lx\n", regname(addr), val); - outl(addr, addrport); - outl(val, dataport); -} - - -/* - 2560 - 4 words per - 4 *p - 10240 - 4k bytes per page - 4096/p - 2.50 - 1700 lines - 1700 * p - 4250.00 - PTEs -*/ -static void -setgtt(int start, int end, unsigned long base, int inc) -{ - int i; - - for(i = start; i < end; i++){ - u32 word = base + i*inc; - WRITE32(word|1,(i*4)|1); - } -} - -static unsigned long tickspermicrosecond = 1795; -static unsigned long long globalstart; - -static unsigned long -microseconds(unsigned long long start, unsigned long long end) -{ - unsigned long ret; - ret = ((end - start)/tickspermicrosecond); - return ret; -} - -static unsigned long globalmicroseconds(void) -{ - return microseconds(globalstart, rdtscll()); -} - -extern struct iodef iodefs[]; -extern int niodefs; - -static int i915_init_done = 0; - -/* fill the palette. This runs when the P opcode is hit. */ -/* and, yes, it's needed for even 32 bits per pixel */ -static void palette(void) -{ - int i; - unsigned long color = 0; - - for(i = 0; i < 256; i++, color += 0x010101){ - io_i915_WRITE32(color, _LGC_PALETTE_A + (i << 2)); - } -} - -static unsigned long times[4096]; - -static int run(int index) -{ - int i, prev = 0; - struct iodef *id, *lastidread = NULL; - unsigned long u, t; - if (index >= niodefs) - return index; - /* state machine! */ - for(i = index, id = &iodefs[i]; id->op; i++, id++){ - switch (id->op) { - case M: - if (verbose & vmsg) printk(BIOS_SPEW, "%ld: %s\n", - globalmicroseconds(), id->msg); - break; - case P: - palette(); - break; - case R: - u = READ32(id->addr); - if (verbose & vio) - printk(BIOS_SPEW, "\texpect %08lx\n", id->data); - /* we're looking for something. */ - if (lastidread->addr == id->addr){ - /* they're going to be polling. - * just do it 1000 times - */ - for (t = 0; t < 1000 && id->data != u; t++){ - u = READ32(id->addr); - } - if (verbose & vspin) printk(BIOS_SPEW, - "%s: # loops %ld got %08lx want %08lx\n", - regname(id->addr), - t, u, id->data); - } - lastidread = id; - break; - case W: - WRITE32(id->data, id->addr); - if (id->addr == PCH_PP_CONTROL){ - if (verbose & vio) - printk(BIOS_SPEW, "PCH_PP_CONTROL\n"); - switch (id->data & 0xf) { - case 8: break; - case 7: break; - default: udelay(100000); - if (verbose & vio) - printk(BIOS_SPEW, "U %d\n", 100000); - } - } - break; - case V: - if (id->count < 8){ - prev = verbose; - verbose = id->count; - } else { - verbose = prev; - } - printk(BIOS_SPEW, "Change verbosity to %d\n", verbose); - break; - case I: - printk(BIOS_SPEW, "run: return %d\n", i+1); - return i+1; - break; - default: - printk(BIOS_SPEW, "BAD TABLE, opcode %d @ %d\n", id->op, i); - return -1; - } - if (id->udelay) - udelay(id->udelay); - if (i < ARRAY_SIZE(times)) - times[i] = globalmicroseconds(); - } - printk(BIOS_SPEW, "run: return %d\n", i); - return i+1; -} - -int i915lightup_sandy(const struct i915_gpu_controller_info *info, - u32 pphysbase, u16 piobase, u8 *pmmio, u32 pgfx) -{ - static struct edid edid; - const struct edid_mode *mode; - int edid_ok; - - int index; - u32 auxin[16], auxout[16]; - mmio = (void *)pmmio; - addrport = piobase; - dataport = addrport + 4; - physbase = pphysbase; - graphics = pgfx; - printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p" - "addrport %04x physbase %08x\n", - (void *)graphics, mmio, addrport, physbase); - globalstart = rdtscll(); - - - edid_ok = decode_edid((unsigned char *)&link_edid_data, - sizeof(link_edid_data), &edid); - mode = &edid.mode; - printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok); - edid.framebuffer_bits_per_pixel = 32; - - htotal = (mode->ha - 1) | ((mode->ha + mode->hbl - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal); - - hblank = (mode->ha - 1) | ((mode->ha + mode->hbl - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank); - - hsync = (mode->ha + mode->hso - 1) | - ((mode->ha + mode->hso + mode->hspw - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync); - - vtotal = (mode->va - 1) | ((mode->va + mode->vbl - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal); - - vblank = (mode->va - 1) | ((mode->va + mode->vbl - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank); - - vsync = (mode->va + mode->vso - 1) | - ((mode->va + mode->vso + mode->vspw - 1) << 16); - printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync); - - printk(BIOS_SPEW, "Table has %d elements\n", niodefs); - - index = run(0); - printk(BIOS_SPEW, "Run returns %d\n", index); - auxout[0] = 1 << 31 /* dp */|0x1 << 28/*R*/|DP_DPCD_REV << 8|0xe; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 14); - auxout[0] = 0 << 31 /* i2c */|1 << 30|0x0 << 28/*W*/|0x0 << 8|0x0; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0); - index = run(index); - printk(BIOS_SPEW, "Run returns %d\n", index); - auxout[0] = 0 << 31 /* i2c */|0 << 30|0x0 << 28/*W*/|0x0 << 8|0x0; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0); - index = run(index); - printk(BIOS_SPEW, "Run returns %d\n", index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_SET_POWER << 8|0x0; - auxout[1] = 0x01000000; - /* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE */ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_LINK_BW_SET << 8|0x8; - auxout[1] = 0x0a840000; - /*(DP_LINK_BW_2_7 &0xa)|0x0000840a*/ - auxout[2] = 0x00000000; - auxout[3] = 0x01000000; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 13, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_TRAINING_PATTERN_SET << 8|0x0; - auxout[1] = 0x21000000; - /* DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE | - * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000021*/ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_TRAINING_LANE0_SET << 8|0x3; - auxout[1] = 0x00000000; - /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x1 << 28/*R*/|DP_LANE0_1_STATUS << 8|0x5; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_TRAINING_PATTERN_SET << 8|0x0; - auxout[1] = 0x22000000; - /* DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE | - * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000022*/ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_TRAINING_LANE0_SET << 8|0x3; - auxout[1] = 0x00000000; - /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x1 << 28/*R*/|DP_LANE0_1_STATUS << 8|0x5; - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5); - index = run(index); - auxout[0] = 1 << 31 /* dp */|0x0 << 28/*W*/|DP_TRAINING_PATTERN_SET << 8|0x0; - auxout[1] = 0x00000000; - /* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE | - * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/ - intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); - index = run(index); - - if (index != niodefs) - printk(BIOS_ERR, "Left over IO work in i915_lightup" - " -- this is likely a table error. " - "Only %d of %d were done.\n", index, niodefs); - printk(BIOS_SPEW, "DONE startup\n"); - verbose = 0; - /* GTT is the Global Translation Table for the graphics pipeline. - * It is used to translate graphics addresses to physical - * memory addresses. As in the CPU, GTTs map 4K pages. - * There are 32 bits per pixel, or 4 bytes, - * which means 1024 pixels per page. - * There are 4250 GTTs on Link: - * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page. - * The setgtt function adds a further bit of flexibility: - * it allows you to set a range (the first two parameters) to point - * to a physical address (third parameter);the physical address is - * incremented by a count (fourth parameter) for each GTT in the - * range. - * Why do it this way? For ultrafast startup, - * we can point all the GTT entries to point to one page, - * and set that page to 0s: - * memset(physbase, 0, 4096); - * setgtt(0, 4250, physbase, 0); - * this takes about 2 ms, and is a win because zeroing - * the page takes a up to 200 ms. We will be exploiting this - * trick in a later rev of this code. - * This call sets the GTT to point to a linear range of pages - * starting at physbase. - */ - setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096); - printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n", - (void *)graphics, FRAME_BUFFER_BYTES); - memset((void *)graphics, 0, FRAME_BUFFER_BYTES); - printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds()); - set_vbe_mode_info_valid(&edid, (uintptr_t)graphics); - i915_init_done = 1; - return i915_init_done; -} diff --git a/src/mainboard/google/link/i915io.c b/src/mainboard/google/link/i915io.c deleted file mode 100644 index 5ebb42d4e70..00000000000 --- a/src/mainboard/google/link/i915io.c +++ /dev/null @@ -1,355 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include -#include "i915io.h" - -struct iodef iodefs[] = { - {V, 0}, - {W, 1, "", PCH_GMBUS0, 0x00000000, 0}, - {R, 1, "", PP_ON_DELAYS, ( /* T2 */ 0x0 << 16) | ( /* T5 */ 0x0 << 0) | 0x00000000, 0}, - {R, 1, "", PP_OFF_DELAYS, ( /* T3 */ 0x0 << 16) | ( /* Tx */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", PP_ON_DELAYS, ( /* T2 */ 0x190 << 16) | ( /* T5 */ 0x7d0 << 0) | 0x019007d0, 0}, - {W, 1, "", PP_OFF_DELAYS, ( /* T3 */ 0x15e << 16) | ( /* Tx */ 0x7d0 << 0) | 0x015e07d0, 0}, - {M, 1, "[drm:intel_detect_pch], Found PatherPoint PCH", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:i915_load_modeset_init], failed to find VBIOS tables", 0x0, 0xcf8e64, 0}, - {R, 50, "", FORCEWAKE_MT_ACK, 0x00000001, 10}, - {W, 1, "", FORCEWAKE_MT, 0x00010001, 0}, - {R, 1, "", FORCEWAKE_MT, 0x00010001, 0}, - {R, 1, "", FORCEWAKE_MT_ACK, 0x00000001, 0}, - {R, 1, "", 0x13805c, 0x40000000, 0}, - {R, 1, "", 0xa180, 0x84100020, 0}, - {W, 1, "", FORCEWAKE_MT, 0x00010000, 0}, - {R, 1, "", 0x120000, 0x00000000, 0}, - {M, 1, "[drm:intel_init_display], Using MT version of forcewake", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:intel_modeset_init], 3 display pipes available.", 0x0, 0xcf8e64, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {W, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {R, 1, "", _PIPEBCONF, 0x00000000, 0}, - {W, 1, "", _PIPEBCONF, 0x00000000, 0}, - {R, 1, "", 0x72008, 0x00000000, 0}, - {W, 1, "", 0x72008, 0x00000000, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {W, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {R, 1, "", _PIPEBCONF, 0x00000000, 0}, - {W, 1, "", _PIPEBCONF, 0x00000000, 0}, - {R, 1, "", 0x72008, 0x00000000, 0}, - {W, 1, "", 0x72008, 0x00000000, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {W, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {R, 1, "", _PIPEBCONF, 0x00000000, 0}, - {W, 1, "", _PIPEBCONF, 0x00000000, 0}, - {R, 1, "", 0x72008, 0x00000000, 0}, - {W, 1, "", 0x72008, 0x00000000, 300}, - {W, 1, "", CPU_VGACNTRL, 0x80000000, 0}, - {R, 1, "", CPU_VGACNTRL, 0x80000000, 0}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 0}, - {R, 1, "", PCH_PP_ON_DELAYS, PANEL_PORT_SELECT_DPA | ( /* PANEL_POWER_UP_DELAY */ 0x7d0 << 16) | ( /* PANEL_LIGHT_ON_DELAY */ 0x7d0 << 0) | 0x47d007d0, 0}, - {R, 1, "", PCH_PP_OFF_DELAYS, ( /* PANEL_POWER_DOWN_DELAY */ 0x1f4 << 16) | ( /* PANEL_LIGHT_OFF_DELAY */ 0x7d0 << 0) | 0x01f407d0, 0}, - {R, 1, "", PCH_PP_DIVISOR, 0x00186906, 0}, - {M, 1, "[drm:intel_dp_init], cur t1_t3 2000 t8 2000 t9 2000 t10 500t11_t12 6000", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_init], vbt t1_t3 0 t8 0 t9 0 t10 0 t11_t12 0", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_init], panel power up delay 200,power down" "delay 50, power cycle delay 600", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_init], backlight on delay 200, off delay 200", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_on], Turn eDP VDD on", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_CONTROL, 0x00000000, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {M, 1, "[drm:ironlake_wait_panel_power_cycle], Wait for panel power cycle", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_wait_panel_status], R PCH_PP_CONTROL:00000000", 0x0, 0xcf8e64, 0}, - {R, 2, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, 0x00000000, 0}, - {W, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_on], R PCH_PP_CONTROL:abcd0008", 0x0, 0xcf8e64, 0}, - {R, 2, "", PCH_PP_STATUS, 0x00000000, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_on], eDP was not running", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {M, 1, "[drm:intel_dp_i2c_init], i2c_init DPDDC-A", 0x0, 0x00000000, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {I,}, - {M, 1, "[drm:ironlake_edp_panel_vdd_off], Turn eDP VDD off 1", 0x0, 0x00000000, 0}, - {R, 1, "", BLC_PWM_CPU_CTL, 0x000010ce, 0}, - {M, 1, "[drm:intel_panel_get_backlight], get backlight PWM = 4302", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_aux_ch], dp_aux_ch timeout status 0x5145003f", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_i2c_aux_ch], aux_ch failed -110", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_init_pch_refclk], has_panel 1 has_lvds 0 " "has_pch_edp 0has_cpu_edp 1 has_ck505 0", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_DREF_CONTROL, 0x00000000, 0}, - {M, 1, "[drm:ironlake_init_pch_refclk], Using SSC on panel", 0x0, 0xcf8e64, 0}, - {W, 1, "", PCH_DREF_CONTROL, DREF_SSC_SOURCE_ENABLE | DREF_NONSPREAD_SOURCE_ENABLE | DREF_SSC1_ENABLE | 0x00001402, 0}, - {R, 1, "", PCH_DREF_CONTROL, DREF_SSC_SOURCE_ENABLE | DREF_NONSPREAD_SOURCE_ENABLE | DREF_SSC1_ENABLE | 0x00001402, 200}, - {M, 1, "[drm:ironlake_init_pch_refclk], Using SSC on eDP", 0x0, 0xcf8e64, 0}, - {W, 1, "", PCH_DREF_CONTROL, DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD | DREF_SSC_SOURCE_ENABLE | DREF_NONSPREAD_SOURCE_ENABLE | DREF_SSC1_ENABLE | 0x00005402, 0}, - {R, 1, "", PCH_DREF_CONTROL, DREF_CPU_SOURCE_OUTPUT_DOWNSPREAD | DREF_SSC_SOURCE_ENABLE | DREF_NONSPREAD_SOURCE_ENABLE | DREF_SSC1_ENABLE | 0x00005402, 200}, - {W, 1, "", ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE | 0x10000000, 0}, - {W, 1, "", WM3_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM2_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM1_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", 0x9404, 0x00002000, 0}, - {W, 1, "", ILK_DSPCLK_GATE_D, ILK_VRHUNIT_CLOCK_GATE_DISABLE | 0x10000000, 0}, - {W, 1, "", IVB_CHICKEN3, 0x00000024, 0}, - {W, 1, "", GEN7_COMMON_SLICE_CHICKEN1, 0x04000400, 0}, - {W, 1, "", 0xb01c, 0x3c4fff8c, 0}, - {W, 1, "", GEN7_L3_CHICKEN_MODE_REGISTER, 0x20000000, 0}, - {R, 1, "", GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0x00000000, 0}, - {W, 1, "", GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, 0x00000800, 0}, - {R, 1, "", _DSPACNTR, ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | 0x00000000, 0}, - {W, 1, "", _DSPACNTR, ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ | 0x00004000, 0}, - {R, 1, "", _DSPAADDR, 0x00000000, 0}, - {W, 1, "", _DSPAADDR, 0x00000000, 0}, - {R, 1, "", _DSPASIZE + 0xc, 0x00000000, 0}, - {W, 1, "", _DSPASIZE + 0xc, 0x00000000, 0}, - {R, 1, "", _DSPBCNTR, 0x00000000, 0}, - {W, 1, "", _DSPBCNTR, 0x00004000, 0}, - {R, 1, "", _DSPBADDR, 0x00000000, 0}, - {W, 1, "", _DSPBADDR, 0x00000000, 0}, - {R, 1, "", _DSPBSURF, 0x00000000, 0}, - {W, 1, "", _DSPBSURF, 0x00000000, 0}, - {R, 1, "", _DVSACNTR, 0x00000000, 0}, - {W, 1, "", _DVSACNTR, DVS_TRICKLE_FEED_DISABLE | 0x00004000, 0}, - {R, 1, "", _DVSALINOFF, 0x00000000, 0}, - {W, 1, "", _DVSALINOFF, 0x00000000, 0}, - {R, 1, "", _DVSASURF, 0x00000000, 0}, - {W, 1, "", _DVSASURF, 0x00000000, 0}, - {W, 1, "", SOUTH_DSPCLK_GATE_D, PCH_DPLSUNIT_CLOCK_GATE_DISABLE | 0x20000000, 0}, - {R, 1, "", SOUTH_CHICKEN2, 0x00000000, 0}, - {W, 1, "", SOUTH_CHICKEN2, DPLS_EDP_PPS_FIX_DIS | 0x00000001, 0}, - {W, 1, "", _TRANSA_CHICKEN2, 0x80000000, 0}, - {W, 1, "", _TRANSB_CHICKEN2, TRANS_CHICKEN2_TIMING_OVERRIDE | 0x80000000, 0}, - {M, 1, "[drm:drm_edid_to_eld], ELD:no CEA Extension found", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_helper_probe_single_connector_modes], " "[CONNECTOR:6:eDP-1]probed modes :", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_mode_debug_printmodeline],Modeline 0:\"2560x1700\" " "60 285250 2560 2608 2640 2720 1700 1703 1713 17490x48 0xa", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_setup_crtcs], ", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_enable_connectors], connector 6 enabled? yes", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_setup_crtcs], picking CRTCs for 8192x8192 config", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_setup_crtcs], desired mode 2560x1700 set on crtc 3", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_helper_probe_single_connector_modes], [CONNECTOR:6:eDP-1]", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_detect], DPCD:110a8441000001c0", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_on], Turn eDP VDD on", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_detect], DPCD:110a8441000001c0", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_enable_connectors], connector 6 enabled? yes", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_get_load_detect_pipe], [CONNECTOR:6:eDP-1],[ENCODER:7:TMDS-7]", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_mode_fixup], Display port link bw 0a lane count 4clock 270000", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_crtc_helper_set_mode], [CRTC:3]", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {I,}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_off], Turn eDP VDD off 1", 0x0, 0xcf8e64, 0}, - {R, 2, "", PCH_DP_D, 0x00000004, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_8 | PIPECONF_DITHER_TYPE_SP | 0x00000000, 0}, - {W, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_TYPE_SP | 0x00000040, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_TYPE_SP | 0x00000040, 0}, - {M, 1, "[drm:ironlake_crtc_mode_set], Mode for pipe 0:", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_mode_debug_printmodeline],Modeline 0:\"2560x1700\" " "60 285250 2560 2608 2640 2720 1700 1703 1713 1749 0x48 0xa", 0x0, 0xcf8e64, 0}, - {W, 1, "", _TRANSA_DATA_M1, 0x00000000, 0}, - {W, 1, "", _TRANSA_DATA_N1, 0x00000000, 0}, - {W, 1, "", _TRANSA_DP_LINK_M1, 0x00000000, 0}, - {W, 1, "", _TRANSA_DP_LINK_N1, 0x00000000, 0}, - {W, 1, "", _PCH_FPA1, 0x00020e08, 0}, - {W, 1, "", _VSYNCSHIFT_A, 0x00000000, 0}, - {W, 1, "", _HTOTAL_A, 0x0a9f09ff, 0}, - {W, 1, "", _HBLANK_A, 0x0a9f09ff, 0}, - {W, 1, "", _HSYNC_A, 0x0a4f0a2f, 0}, - {W, 1, "", _VTOTAL_A, 0x06d406a3, 0}, - {W, 1, "", _VBLANK_A, 0x06d406a3, 0}, - {W, 1, "", _VSYNC_A, 0x06b006a6, 0}, - {W, 1, "", _PIPEASRC, 0x09ff06a3, 0}, - {W, 1, "", _PIPEA_DATA_M1, 0x7e4e58a4, 0}, - {W, 1, "", _PIPEA_DATA_N1, 0x0083d600, 0}, - {W, 1, "", _PIPEA_LINK_M1, 0x00045a42, 0}, - {W, 1, "", _PIPEA_LINK_N1, 0x00041eb0, 0}, - {M, 1, "[drm:ironlake_set_pll_edp], eDP PLL enable for clock 270000", 0x0, 0xcf8e64, 0}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 0}, - {W, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 0}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 500}, - {W, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x00000050, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x00000050, 0}, - {R, 1, "", _PIPEASTAT, 0x00000000, 0}, - {W, 1, "", _PIPEASTAT, PIPE_VBLANK_INTERRUPT_STATUS | 0x00000002, 0}, - {R, 4562, "", _PIPEASTAT, 0x00000000, 0}, - {M, 1, "[drm:intel_wait_for_vblank], vblank wait timed out", 0x0, 0xcf8e64, 0}, - {W, 1, "", _DSPACNTR, DISPPLANE_GAMMA_ENABLE | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | 0x40000000, 0}, - {R, 2, "", _DSPACNTR, DISPPLANE_GAMMA_ENABLE | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | 0x40000000, 0}, - {W, 1, "", _DSPACNTR, DISPPLANE_GAMMA_ENABLE | (DISPPLANE_BGRX888 & 0x18000000) | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ | 0x58004000, 0}, - {M, 1, "[drm:ironlake_update_plane], Writing base 00000000 00000000 0 0 10240", 0x0, 0xcf8e64, 0}, - {W, 1, "", _DSPASTRIDE, 0x00002800, 0}, - {W, 1, "", _DSPASIZE + 0xc, 0x00000000, 0}, - {W, 1, "", _DSPACNTR + 0x24, 0x00000000, 0}, - {W, 1, "", _DSPAADDR, 0x00000000, 0}, - {R, 1, "", _DSPACNTR, DISPPLANE_GAMMA_ENABLE | (DISPPLANE_BGRX888 & 0x18000000) | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ | 0x58004000, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {R, 1, "", WM0_PIPEA_ILK, 0x00783818, 0}, - {W, 1, "", WM0_PIPEA_ILK, 0x00183806, 0}, - {M, 1, "[drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 24,cursor:6", 0x0, 0xcf8e64, 0}, - {W, 1, "", WM3_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM2_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM1_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 1:display plane 38, fbc lines 3,cursor 6", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM1_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x4 << 24) | ( /* WMx_LP_FBC */ 0x3 << 20) | ( /* WMx_LP_SR */ 0x26 << 8) | ( /* WMx_LP_CURSOR */ 0x6 << 0) | 0x84302606, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 2:display plane 145, " "fbc lines 3,cursor 6", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM2_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x10 << 24) | ( /* WMx_LP_FBC */ 0x3 << 20) | ( /* WMx_LP_SR */ 0x91 << 8) | ( /* WMx_LP_CURSOR */ 0x6 << 0) | 0x90309106, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 3:display plane " "288, fbc lines 4,cursor 10", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM3_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x20 << 24) | ( /* WMx_LP_FBC */ 0x4 << 20) | ( /* WMx_LP_SR */ 0x120 << 8) | ( /* WMx_LP_CURSOR */ 0xa << 0) | 0xa041200a, 0}, - {M, 1, "[drm:drm_crtc_helper_set_mode], [ENCODER:7:TMDS-7]set [MODE:0:2560x1700]", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_edp_pll_on], ", 0x0, 0xcf8e64, 0}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000001c, 0}, - {W, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000401c, 0}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000401c, 200}, - {R, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_SYNC_VS_HIGH | DP_SYNC_HS_HIGH | DP_DETECTED | 0x0000401c, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {R, 1, "", WM0_PIPEA_ILK, 0x00183806, 0}, - {W, 1, "", WM0_PIPEA_ILK, 0x00183806, 0}, - {M, 1, "[drm:sandybridge_update_wm], FIFO watermarks For pipe A - plane 24,cursor:6", 0x0, 0xcf8e64, 0}, - {W, 1, "", WM3_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM2_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {W, 1, "", WM1_LP_ILK, ( /* WMx_LP_LATENCY */ 0x0 << 24) | ( /* WMx_LP_FBC */ 0x0 << 20) | ( /* WMx_LP_SR */ 0x0 << 8) | ( /* WMx_LP_CURSOR */ 0x0 << 0) | 0x00000000, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 1:display plane 38, fbc lines 3,cursor 6", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM1_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x4 << 24) | ( /* WMx_LP_FBC */ 0x3 << 20) |( /* WMx_LP_SR */ 0x26 << 8) | ( /* WMx_LP_CURSOR */ 0x6 << 0) | 0x84302606, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 2:display plane 145, " "fbc lines 3,cursor 6", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM2_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x10 << 24) | ( /* WMx_LP_FBC */ 0x3 << 20) |( /* WMx_LP_SR */ 0x91 << 8) | ( /* WMx_LP_CURSOR */ 0x6 << 0) | 0x90309106, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {M, 1, "[drm:ironlake_check_srwm], watermark 3:display plane 288, " "fbc lines 4,cursor 10", 0x0, 0xcf8e64, 0}, - {R, 1, "", 0x145d10, 0x2010040c, 0}, - {W, 1, "", WM3_LP_ILK, WMx_LP_SR_EN | ( /* WMx_LP_LATENCY */ 0x20 << 24) | ( /* WMx_LP_FBC */ 0x4 << 20) |( /* WMx_LP_SR */ 0x120 << 8) | ( /* WMx_LP_CURSOR */ 0xa << 0) | 0xa041200a, 0}, - {R, 1, "", _FDI_TXA_CTL, 0x00040000, 0}, - {W, 1, "", _FDI_TXA_CTL, 0x00040000, 0}, - {R, 1, "", _FDI_TXA_CTL, 0x00040000, 0}, - {R, 1, "", _FDI_RXA_CTL, 0x00000040, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x00000050, 0}, - {W, 1, "", _FDI_RXA_CTL, 0x00020040, 0}, - {R, 1, "", _FDI_RXA_CTL, 0x00020040, 100}, - {R, 1, "", SOUTH_CHICKEN1, 0x00000000, 0}, - {W, 2, "", SOUTH_CHICKEN1, 0x00000000, 0}, - {R, 1, "", SOUTH_CHICKEN1, 0x00000000, 0}, - {R, 1, "", _FDI_TXA_CTL, 0x00040000, 0}, - {W, 1, "", _FDI_TXA_CTL, 0x00040000, 0}, - {R, 1, "", _FDI_RXA_CTL, 0x00020040, 0}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x00000050, 0}, - {W, 1, "", _FDI_RXA_CTL, 0x00020040, 0}, - {R, 1, "", _FDI_RXA_CTL, 0x00020040, 100}, - {P, 1, "Set Palette"}, - {R, 1, "", _PIPEACONF, ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x00000050, 0}, - {W, 1, "", _PIPEACONF, PIPECONF_ENABLE | ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP | 0x80000050, 0}, - {R, 1, "", _PIPEASTAT, 0x00000000, 0}, - {W, 1, "", _PIPEASTAT, PIPE_VBLANK_INTERRUPT_STATUS | 0x00000002, 0}, - {R, 4533, "", _PIPEASTAT, 0x00000000, 0}, - {M, 1, "[drm:intel_wait_for_vblank], vblank wait timed out", 0x0, 0xcf8e64, 0}, - {R, 1, "", _PIPEACONF, PIPECONF_ENABLE | PIPECONF_DOUBLE_WIDE | ( /* PIPECONF_FRAME_START_DELAY_MASK */ 0x0 << 27) | PIPECONF_BPP_6 | PIPECONF_DITHER_EN | PIPECONF_DITHER_TYPE_SP |0xc0000050, 0}, - {R, 1, "", _DSPACNTR, DISPPLANE_GAMMA_ENABLE | (DISPPLANE_BGRX888 & 0x18000000) | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ | 0x58004000, 0}, - {W, 1, "", _DSPACNTR, DISPLAY_PLANE_ENABLE | DISPPLANE_GAMMA_ENABLE | (DISPPLANE_BGRX888 & 0x18000000) | ( /* DISPPLANE_SEL_PIPE(0=A,1=B) */ 0x0 << 24) | DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ | 0xd8004000, 0}, - {R, 1, "", _DSPAADDR, 0x00000000, 0}, - {W, 1, "", _DSPAADDR, 0x00000000, 0}, - {R, 1, "", _DSPASIZE + 0xc, 0x00000000, 0}, - {W, 1, "", _DSPASIZE + 0xc, 0x00000000, 0}, - {R, 1, "", _PIPEASTAT, 0x00000000, 0}, - {W, 1, "", _PIPEASTAT, PIPE_VBLANK_INTERRUPT_STATUS | 0x00000002, 0}, - {R, 4392, "", _PIPEASTAT, 0x00000000, 0}, - {M, 1, "[drm:intel_wait_for_vblank], vblank wait timed out", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_on], Turn eDP VDD on", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {M, 1, "[drm:ironlake_edp_panel_on], Turn eDP power on", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_STATUS, 0x00000000, 0}, - {M, 1, "[drm:ironlake_wait_panel_power_cycle], Wait for panel power cycle", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_wait_panel_status], R PCH_PP_CONTROL:abcd0008", 0x0, 0xcf8e64, 0}, - {R, 2, "", PCH_PP_STATUS, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | 0xabcd0008, 0}, - {W, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd000b, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd000b, 0}, - {M, 1, "[drm:ironlake_wait_panel_on], Wait for panel power on", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:ironlake_wait_panel_status], R PCH_PP_CONTROL:abcd000b", 0x0, 0xcf8e64, 0}, - {R, 4, "", PCH_PP_STATUS, /*undocbit3 | undocbit1 | */ 0x0000000a, 0}, - {R, 16983, "", PCH_PP_STATUS, PP_ON | PP_SEQUENCE_POWER_UP | /*undocbit3 | undocbit1 | */ 0x9000000a, 0}, - {R, 17839, "", PCH_PP_STATUS, PP_ON | PP_SEQUENCE_POWER_UP | /*undocbit3 | undocbit0 | */ 0x90000009, 0}, - {R, 1, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {M, 1, "[drm:ironlake_edp_panel_vdd_off], Turn eDP VDD off 1", 0x0, 0xcf8e64, 0}, - {R, 2, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_FORCE_VDD | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd000b, 0}, - {W, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd0003, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd0003, 0}, - {M, 1, "[drm:ironlake_panel_vdd_off_sync], R PCH_PP_CONTROL:abcd0003", 0x0, 0xcf8e64, 0}, - {R, 1, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_2_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x8e1c4104, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_2_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x8e1c4104, 0}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_2_CPT | (DP_PRE_EMPHASIS_9_5 & 0xc00000) | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x8cdc4104, 0}, - {M, 1, "[drm:intel_dp_link_down], ", 0x0, 0xcf8e64, 0}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x8e1c0004, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x8e1c0004, 100}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_IDLE_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x8e1c0204, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_IDLE_CPT | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x8e1c0204, 0}, - {W, 1, "", DP_A, DP_LINK_TRAIN_PAT_1 | (DP_LINK_TRAIN_OFF_CPT & 0x300) | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x0e1c0304, 0}, - {R, 2, "", DP_A, DP_LINK_TRAIN_PAT_1 | (DP_LINK_TRAIN_OFF_CPT & 0x300) | DP_PRE_EMPHASIS_0 | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_DETECTED | 0x0e1c0304, 0}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {I,}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4004, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4004, 0}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {I,}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {I,}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /*undocbit3 | */ 0x80000008, 0}, - {I,}, - {M, 1, "[drm:intel_dp_start_link_train], clock recovery OK", 0x0, 0x00000000, 0}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_2_CPT | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4104, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_2_CPT | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4104, 0}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /* undocbit3 | */ 0x80000008, 0}, - {I,}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /* undocbit3 | */ 0x80000008, 0}, - {I,}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /* undocbit3 | */ 0x80000008, 0}, - {I,}, - {W, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | (DP_LINK_TRAIN_OFF_CPT & 0x300) | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4304, 0}, - {R, 1, "", DP_A, DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | (DP_LINK_TRAIN_OFF_CPT & 0x300) | (DP_PORT_WIDTH_4 & 0x180000) | DP_ENHANCED_FRAMING | DP_PLL_FREQ_270MHZ | DP_PLL_ENABLE | DP_DETECTED | 0x891c4304, 0}, - {R, 2, "", PCH_PP_STATUS, PP_ON | /* undocbit3 | */ 0x80000008, 0}, - {I,}, - {M, 1, "[drm:ironlake_edp_backlight_on], ", 0x0, 0x00000000, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd0003, 0}, - {W, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_BLC_ENABLE | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd0007, 0}, - {R, 1, "", PCH_PP_CONTROL, (PCH_PP_UNLOCK & 0xabcd0000) | EDP_BLC_ENABLE | PANEL_POWER_RESET | PANEL_POWER_ON | 0xabcd0007, 0}, - {R, 1, "", _PIPEADSL, 0x00000633, 500}, - {R, 1, "", _PIPEADSL, 0x00000652, 0}, - {R, 1, "", _PIPEASTAT, 0x00000000, 0}, - {W, 1, "", _PIPEASTAT, PIPE_VBLANK_INTERRUPT_STATUS | 0x00000002, 0}, - {R, 5085, "", _PIPEASTAT, 0x00000000, 0}, - {M, 1, "[drm:intel_wait_for_vblank], vblank wait timed out", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:intel_dp_mode_fixup], Display port link bw 0a lane count 4clock 270000", 0x0, 0xcf8e64, 0}, - {M, 1, "[drm:drm_crtc_helper_set_mode], [CRTC:3]", 0x0, 0xcf8e64, 0}, - {I,}, -}; - -int niodefs = ARRAY_SIZE(iodefs); diff --git a/src/mainboard/google/link/i915io.h b/src/mainboard/google/link/i915io.h deleted file mode 100644 index c7663d4db08..00000000000 --- a/src/mainboard/google/link/i915io.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2012 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include -#include - -/* things that are, strangely, not defined anywhere? */ -#define PCH_PP_UNLOCK 0xabcd0000 -#define WMx_LP_SR_EN (1 << 31) - -/* Google Link-specific defines */ -/* how many 4096-byte pages do we need for the framebuffer? - * There are 32 bits per pixel, or 4 bytes, - * which means 1024 pixels per page. - * HencetThere are 4250 GTTs on Link: - * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page. - */ -#define FRAME_BUFFER_PAGES ((2560*1700)/1024) -#define FRAME_BUFFER_BYTES (FRAME_BUFFER_PAGES*4096) - -/* One-letter commands for code not meant to be ready for humans. - * The code was generated by a set of programs/scripts. - * M print out a kernel message - * R read a register. We do these mainly to ensure that if hardware wanted - * the register read, it was read; also, in debug, we can see what was expected - * and what was found. This has proven *very* useful to get this debugged. - * The udelay, if non-zero, will make sure there is a - * udelay() call with the value. - * The count is from the kernel and tells us how many times this read was done. - * Also useful for debugging and the state - * machine uses the info to drive a poll. - * W Write a register - * V set verbosity. It's a bit mask. - * 0 -> nothing - * 1 -> print kernel messages - * 2 -> print IO ops - * 4 -> print the number of times we spin on a register in a poll - * 8 -> restore whatever the previous verbosity level was - * (only one deep stack) - * - * Again, this is not really meant for human consumption. There is not a poll - * operator as such because, sometimes, there is a read/write/read where the - * second read is a poll, and this chipset is so touchy I'm reluctant to move - * things around and/or delete too many reads. - */ -#define M 1 -#define R 2 -#define W 4 -#define V 8 -#define I 16 -#define P 32 - -struct iodef { - unsigned char op; - unsigned int count; - const char *msg; - unsigned long addr; - unsigned long data; - unsigned long udelay; -}; - -/* i915.c */ -unsigned long io_i915_READ32(unsigned long addr); -void io_i915_WRITE32(unsigned long val, unsigned long addr); - -/* intel_dp.c */ -u32 pack_aux(u32 *src, int src_bytes); -void unpack_aux(u32 src, u32 *dst, int dst_bytes); -int intel_dp_aux_ch(u32 ch_ctl, u32 ch_data, u32 *send, int send_bytes, - u32 *recv, int recv_size); diff --git a/src/mainboard/google/link/intel_dp.c b/src/mainboard/google/link/intel_dp.c deleted file mode 100644 index f74743aab12..00000000000 --- a/src/mainboard/google/link/intel_dp.c +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright 2013 Google Inc. - * Copyright © 2008 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Keith Packard - * - */ - -#include -#include -#include -#include "i915io.h" - -u32 -pack_aux(u32 *src32, int src_bytes) -{ - u8 *src = (u8 *)src32; - int i; - u32 v = 0; - - if (src_bytes > 4) - src_bytes = 4; - for (i = 0; i < src_bytes; i++) - v |= ((u32) src[i]) << ((3-i) * 8); - return v; -} - -void -unpack_aux(u32 src, u32 *dst32, int dst_bytes) -{ - u8 *dst = (u8 *)dst32; - - int i; - if (dst_bytes > 4) - dst_bytes = 4; - for (i = 0; i < dst_bytes; i++) - dst[i] = src >> ((3-i) * 8); -} - -int -intel_dp_aux_ch(u32 ch_ctl, u32 ch_data, u32 *send, int send_bytes, - u32 *recv, int recv_size) -{ - int i; - int recv_bytes; - u32 status; - u32 aux_clock_divider; - int try, precharge = 5; - - /* The clock divider is based off the hrawclk, - * and would like to run at 2MHz. So, take the - * hrawclk value and divide by 2 and use that - * - * Note that PCH attached eDP panels should use a 125MHz input - * clock divider. - */ - /* 200 on link */ - aux_clock_divider = 200; /* SNB & IVB eDP input clock at 400Mhz */ - - /* Try to wait for any previous AUX channel activity */ - for (try = 0; try < 3; try++) { - status = io_i915_READ32(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - udelay(1000); - } - - if (try == 3) { - printk(BIOS_SPEW, "[000000.0] [drm:%s], ", __func__); - printk(BIOS_SPEW, "dp_aux_ch not started status 0x%08lx\n", - io_i915_READ32(ch_ctl)); - return -1; - } - - /* Must try at least 3 times according to DP spec */ - for (try = 0; try < 5; try++) { - /* Load the send data into the aux channel data registers */ - for (i = 0; i < send_bytes; i += 4) - io_i915_WRITE32(send[i], ch_data + i); - - /* Send the command and wait for it to complete */ - io_i915_WRITE32( - DP_AUX_CH_CTL_SEND_BUSY | - DP_AUX_CH_CTL_TIME_OUT_400us | - (send_bytes << DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT) | - (precharge << DP_AUX_CH_CTL_PRECHARGE_2US_SHIFT) | - (aux_clock_divider << DP_AUX_CH_CTL_BIT_CLOCK_2X_SHIFT) | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR, ch_ctl); - for (;;) { - status = io_i915_READ32(ch_ctl); - if ((status & DP_AUX_CH_CTL_SEND_BUSY) == 0) - break; - udelay(100); - } - - /* Clear done status and any errors */ - io_i915_WRITE32( - status | - DP_AUX_CH_CTL_DONE | - DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR, ch_ctl); - - if (status & (DP_AUX_CH_CTL_TIME_OUT_ERROR | - DP_AUX_CH_CTL_RECEIVE_ERROR)) - continue; - if (status & DP_AUX_CH_CTL_DONE) - break; - } - - if ((status & DP_AUX_CH_CTL_DONE) == 0) { - printk(BIOS_SPEW, "[000000.0] [drm:%s], ", __func__); - printk(BIOS_SPEW, "dp_aux_ch not done status 0x%08x\n", status); - return -1; - } - - /* Check for timeout or receive error. - * Timeouts occur when the sink is not connected - */ - if (status & DP_AUX_CH_CTL_RECEIVE_ERROR) { - printk(BIOS_SPEW, "[000000.0] [drm:%s], ", __func__); - printk(BIOS_SPEW, "dp_aux_ch receive error status 0x%08x\n", status); - return -1; - } - - /* Timeouts occur when the device isn't connected, so they're - * "normal" -- don't fill the kernel log with these */ - if (status & DP_AUX_CH_CTL_TIME_OUT_ERROR) { - printk(BIOS_SPEW, "[000000.0] [drm:%s], ", __func__); - printk(BIOS_SPEW, "dp_aux_ch timeout status 0x%08x\n", status); - return -1; - } - - /* Unload any bytes sent back from the other side */ - recv_bytes = ((status & DP_AUX_CH_CTL_MESSAGE_SIZE_MASK) >> - DP_AUX_CH_CTL_MESSAGE_SIZE_SHIFT); - if (recv_bytes > recv_size) - recv_bytes = recv_size; - - for (i = 0; i < recv_bytes; i += 4) - unpack_aux(io_i915_READ32(ch_data + i), - recv + i, recv_bytes - i); - - return recv_bytes; -} From 60a0a3d629d91f8909e5209753baf8f4b6bcc1f5 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Thu, 30 May 2019 04:16:18 +0300 Subject: [PATCH 523/588] ec/lenovo/h8: Fix method name in ACPI code Fix a typo. Change-Id: I2ab624eccd9bad36908df7fd739828e9ed8a4f62 Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/33100 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/ec/lenovo/h8/acpi/lid.asl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ec/lenovo/h8/acpi/lid.asl b/src/ec/lenovo/h8/acpi/lid.asl index a8e17cb7856..c9142f5ff9e 100644 --- a/src/ec/lenovo/h8/acpi/lid.asl +++ b/src/ec/lenovo/h8/acpi/lid.asl @@ -28,7 +28,7 @@ Device(LID) { Name(_HID, "PNP0C0D") - Method(_LId, 0, NotSerialized) + Method(_LID, 0, NotSerialized) { return (LIDS) } From d44d4f0f4eca026f81a3b2a21518d7524235f144 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Tue, 28 May 2019 09:47:38 +0200 Subject: [PATCH 524/588] mb/lenovo/*: Remove useless smihandler code This code to handle the brightness from SMM is copied from the Lenovo Thinkpad X60 code, but does not work on later generation. The PCI device it tries to address does not even exist on those devices. Change-Id: Ia959eb5b747846048396e66d4c926c96c27f3878 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33138 Reviewed-by: Patrick Rudolph Reviewed-by: Nico Huber Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t420s/smihandler.c | 30 ------------------------- src/mainboard/lenovo/t430s/smihandler.c | 30 ------------------------- src/mainboard/lenovo/t520/smihandler.c | 30 ------------------------- src/mainboard/lenovo/t530/smihandler.c | 30 ------------------------- src/mainboard/lenovo/x220/smihandler.c | 30 ------------------------- 5 files changed, 150 deletions(-) diff --git a/src/mainboard/lenovo/t420s/smihandler.c b/src/mainboard/lenovo/t420s/smihandler.c index be4228dc90a..2713725b360 100644 --- a/src/mainboard/lenovo/t420s/smihandler.c +++ b/src/mainboard/lenovo/t420s/smihandler.c @@ -27,23 +27,6 @@ #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 -static void mainboard_smi_brightness_up(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); -} - -static void mainboard_smi_brightness_down(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, - (value - 0x10) & 0xf0); -} - static void mainboard_smi_handle_ec_sci(void) { u8 status = inb(EC_SC); @@ -54,19 +37,6 @@ static void mainboard_smi_handle_ec_sci(void) event = ec_query(); printk(BIOS_DEBUG, "EC event %02x\n", event); - - switch (event) { - case 0x14: - /* brightness up */ - mainboard_smi_brightness_up(); - break; - case 0x15: - /* brightness down */ - mainboard_smi_brightness_down(); - break; - default: - break; - } } void mainboard_smi_gpi(u32 gpi_sts) diff --git a/src/mainboard/lenovo/t430s/smihandler.c b/src/mainboard/lenovo/t430s/smihandler.c index 876d81c0d74..2810e5ae91c 100644 --- a/src/mainboard/lenovo/t430s/smihandler.c +++ b/src/mainboard/lenovo/t430s/smihandler.c @@ -27,23 +27,6 @@ #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 -static void mainboard_smi_brightness_up(void) -{ - u8 value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4); - - if (value < 0xf0) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); -} - -static void mainboard_smi_brightness_down(void) -{ - u8 value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4); - - if (value > 0x10) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, - (value - 0x10) & 0xf0); -} - static void mainboard_smi_handle_ec_sci(void) { u8 status = inb(EC_SC); @@ -54,19 +37,6 @@ static void mainboard_smi_handle_ec_sci(void) event = ec_query(); printk(BIOS_DEBUG, "EC event %02x\n", event); - - switch (event) { - case 0x14: - /* brightness up */ - mainboard_smi_brightness_up(); - break; - case 0x15: - /* brightness down */ - mainboard_smi_brightness_down(); - break; - default: - break; - } } void mainboard_smi_gpi(u32 gpi_sts) diff --git a/src/mainboard/lenovo/t520/smihandler.c b/src/mainboard/lenovo/t520/smihandler.c index 88ce5046fc3..46ad664c3cb 100644 --- a/src/mainboard/lenovo/t520/smihandler.c +++ b/src/mainboard/lenovo/t520/smihandler.c @@ -27,23 +27,6 @@ #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 -static void mainboard_smi_brightness_up(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); -} - -static void mainboard_smi_brightness_down(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, - (value - 0x10) & 0xf0); -} - static void mainboard_smi_handle_ec_sci(void) { u8 status = inb(EC_SC); @@ -54,19 +37,6 @@ static void mainboard_smi_handle_ec_sci(void) event = ec_query(); printk(BIOS_DEBUG, "EC event %02x\n", event); - - switch (event) { - case 0x14: - /* brightness up */ - mainboard_smi_brightness_up(); - break; - case 0x15: - /* brightness down */ - mainboard_smi_brightness_down(); - break; - default: - break; - } } void mainboard_smi_gpi(u32 gpi_sts) diff --git a/src/mainboard/lenovo/t530/smihandler.c b/src/mainboard/lenovo/t530/smihandler.c index bf0f81fc572..46ad664c3cb 100644 --- a/src/mainboard/lenovo/t530/smihandler.c +++ b/src/mainboard/lenovo/t530/smihandler.c @@ -27,23 +27,6 @@ #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 -static void mainboard_smi_brightness_up(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); -} - -static void mainboard_smi_brightness_down(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, - (value - 0x10) & 0xf0); -} - static void mainboard_smi_handle_ec_sci(void) { u8 status = inb(EC_SC); @@ -54,19 +37,6 @@ static void mainboard_smi_handle_ec_sci(void) event = ec_query(); printk(BIOS_DEBUG, "EC event %02x\n", event); - - switch (event) { - case 0x14: - /* brightness up */ - mainboard_smi_brightness_up(); - break; - case 0x15: - /* brightness down */ - mainboard_smi_brightness_down(); - break; - default: - break; - } } void mainboard_smi_gpi(u32 gpi_sts) diff --git a/src/mainboard/lenovo/x220/smihandler.c b/src/mainboard/lenovo/x220/smihandler.c index bf0f81fc572..46ad664c3cb 100644 --- a/src/mainboard/lenovo/x220/smihandler.c +++ b/src/mainboard/lenovo/x220/smihandler.c @@ -27,23 +27,6 @@ #define GPE_EC_SCI 1 #define GPE_EC_WAKE 13 -static void mainboard_smi_brightness_up(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) < 0xf0) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, (value + 0x10) | 0xf); -} - -static void mainboard_smi_brightness_down(void) -{ - u8 value; - - if ((value = pci_read_config8(PCI_DEV(0, 2, 1), 0xf4)) > 0x10) - pci_write_config8(PCI_DEV(0, 2, 1), 0xf4, - (value - 0x10) & 0xf0); -} - static void mainboard_smi_handle_ec_sci(void) { u8 status = inb(EC_SC); @@ -54,19 +37,6 @@ static void mainboard_smi_handle_ec_sci(void) event = ec_query(); printk(BIOS_DEBUG, "EC event %02x\n", event); - - switch (event) { - case 0x14: - /* brightness up */ - mainboard_smi_brightness_up(); - break; - case 0x15: - /* brightness down */ - mainboard_smi_brightness_down(); - break; - default: - break; - } } void mainboard_smi_gpi(u32 gpi_sts) From 38b7445ad240f7504b95e3e0c63122418e3ff159 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Fri, 31 May 2019 14:43:19 -0600 Subject: [PATCH 525/588] mb/google/poppy/variants/nami: Add fallthrough comment This fallthrough is intentional (see commit 2257a35862 - Perform PL2 setting for syndra), so add a comment to make that explicit. Change-Id: I57fe1e08f59aed12544cd2a71f1e0464f432f03b Signed-off-by: Jacob Garber Found-by: Coverity CID 1397063 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33156 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/mainboard/google/poppy/variants/nami/mainboard.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mainboard/google/poppy/variants/nami/mainboard.c b/src/mainboard/google/poppy/variants/nami/mainboard.c index cc87136520a..23870175b7f 100644 --- a/src/mainboard/google/poppy/variants/nami/mainboard.c +++ b/src/mainboard/google/poppy/variants/nami/mainboard.c @@ -252,6 +252,7 @@ void variant_devtree_update(void) case SKU_6_SYNDRA: case SKU_7_SYNDRA: pl2_id = PL2_ID_SONA_SYNDRA; + /* fallthrough */ case SKU_0_VAYNE: case SKU_1_VAYNE: case SKU_2_VAYNE: From 7da638c20e4c56bc103be23216862e265b3ca8b1 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Thu, 30 May 2019 16:11:41 -0600 Subject: [PATCH 526/588] mb/sifive/hifive-unleashed: Check for errors in fixup_fdt It is possible that cbfs_boot_map_with_leak() and malloc() could fail, so detect those conditions and print error messages if they do. Change-Id: I34951da0b73028c4c89446cb1779a72422997325 Signed-off-by: Jacob Garber Found-by: Coverity CID 1399147 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33134 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph Reviewed-by: Xiang Wang --- src/mainboard/sifive/hifive-unleashed/fixup_fdt.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/mainboard/sifive/hifive-unleashed/fixup_fdt.c b/src/mainboard/sifive/hifive-unleashed/fixup_fdt.c index ea58e02b2e2..8ac6ff1208f 100644 --- a/src/mainboard/sifive/hifive-unleashed/fixup_fdt.c +++ b/src/mainboard/sifive/hifive-unleashed/fixup_fdt.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -86,6 +87,11 @@ static void fixup_fdt(void *unused) /* load flat dt from cbfs */ fdt_rom = cbfs_boot_map_with_leak("fallback/DTB", CBFS_TYPE_RAW, NULL); + if (fdt_rom == NULL) { + printk(BIOS_ERR, "Unable to load fallback/DTB from CBFS\n"); + return; + } + /* Expand DT into a tree */ tree = fdt_unflatten(fdt_rom); @@ -95,6 +101,12 @@ static void fixup_fdt(void *unused) /* convert the tree to a flat dt */ void *dt = malloc(dt_flat_size(tree)); + + if (dt == NULL) { + printk(BIOS_ERR, "Unable to allocate memory for flat device tree\n"); + return; + } + dt_flatten(tree, dt); /* update HLS */ From f7f90f7c3f35f03efe037c4e079420e88a317610 Mon Sep 17 00:00:00 2001 From: Jacob Garber Date: Tue, 28 May 2019 15:37:37 -0600 Subject: [PATCH 527/588] drivers/intel/fsp1_1: Exit cleanly if FSP not found Instead of dereferencing a null pointer, print a nice message and exit cleanly if the FSP isn't found in the CBFS. Change-Id: I761e7febc7cec5bd2ef3af214bc51777ee5c313d Signed-off-by: Jacob Garber Found-by: Coverity CID 1401467, 1401717 Reviewed-on: https://review.coreboot.org/c/coreboot/+/33049 Reviewed-by: Furquan Shaikh Tested-by: build bot (Jenkins) --- src/drivers/intel/fsp1_1/car.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 82dc320e0e7..41a02f33b95 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -160,17 +160,14 @@ void mainboard_romstage_entry(unsigned long bist) { /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram * is still enabled. We can directly access work buffer here. */ - FSP_INFO_HEADER *fih; struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); - if (prog_locate(&fsp)) { - fih = NULL; - printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp)); - } else { - /* This leaks a mapping which this code assumes is benign as - * the flash is memory mapped CPU's address space. */ - fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); - } + if (prog_locate(&fsp)) + die_with_post_code(POST_INVALID_CBFS, "Unable to locate fsp.bin"); + + /* This leaks a mapping which this code assumes is benign as + * the flash is memory mapped CPU's address space. */ + FSP_INFO_HEADER *fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); cache_as_ram_stage_main(fih); } From 6681f05373c2ec07168e279026962d7a63539e93 Mon Sep 17 00:00:00 2001 From: Nitheesh Sekar Date: Fri, 14 Sep 2018 19:07:36 +0530 Subject: [PATCH 528/588] qcs405: util/qualcomm: Add T32 debug scripts Add T32 scripts that allow debug of any coreboot stage on qcs405. Change-Id: I4e792a2806e5ebd3b4075c7bb69c43587920deae Signed-off-by: Sricharan R Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/29951 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- util/qualcomm/scripts/cmm/clear_bss.cmm | 16 ++ util/qualcomm/scripts/cmm/debug_cb_405.cmm | 165 ++++++++++++++++++ util/qualcomm/scripts/cmm/debug_cb_common.cmm | 18 +- .../scripts/cmm/pbl32_to_bootblock64_jump.cmm | 15 ++ 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100755 util/qualcomm/scripts/cmm/clear_bss.cmm create mode 100644 util/qualcomm/scripts/cmm/debug_cb_405.cmm create mode 100644 util/qualcomm/scripts/cmm/pbl32_to_bootblock64_jump.cmm diff --git a/util/qualcomm/scripts/cmm/clear_bss.cmm b/util/qualcomm/scripts/cmm/clear_bss.cmm new file mode 100755 index 00000000000..16eaac71d8c --- /dev/null +++ b/util/qualcomm/scripts/cmm/clear_bss.cmm @@ -0,0 +1,16 @@ +d.a 0x80000000 mov x0,#0x8c +d.a 0x80000004 lsl x0, x0, #0x14 +d.a 0x80000008 mov x1,#0x18 +d.a 0x8000000c lsl x1,x1, #0x10 +d.a 0x80000010 mov x2,#0x0 +d.a 0x80000014 mov x3,#0x80 +d.a 0x80000018 lsl x3, x3, #0x18 +d.a 0x8000001c add x3, x3, #0x14 +d.a 0x80000020 str x2,[x0] +d.a 0x80000024 sub x1, x1, #0x8 +d.a 0x80000028 add x0, x0, #0x8 +d.a 0x8000002c cmp x1,0x0 +d.a 0x80000030 b.ne 0x20 +d.a 0x80000034 b 0x34 +r.s pc 0x80000000 +go diff --git a/util/qualcomm/scripts/cmm/debug_cb_405.cmm b/util/qualcomm/scripts/cmm/debug_cb_405.cmm new file mode 100644 index 00000000000..166d2aa3085 --- /dev/null +++ b/util/qualcomm/scripts/cmm/debug_cb_405.cmm @@ -0,0 +1,165 @@ +;============================================================================ +;## +;## This file is part of the coreboot project. +;## +;## Copyright (C) 2018, The Linux Foundation. All rights reserved. +;## +;## This program is free software; you can redistribute it and/or modify +;## it under the terms of the GNU General Public License version 2 and +;## only version 2 as published by the Free Software Foundation. +;## +;## This program is distributed in the hope that it will be useful, +;## but WITHOUT ANY WARRANTY; without even the implied warranty of +;## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;## GNU General Public License for more details. +;## +;============================================================================ +; Name: +; debug_cb_405.cmm +; +; Description: +; Debug coreboot 405 front-end +;============================================================================ + +;============================================================================ +; CMM script variables +;============================================================================ + +LOCAL &TargetPkg + +GLOBAL &BBEntryAddr // Bootblock Entry +GLOBAL &BBExitAddr // Bootblock Exit to Xbl-Sec +GLOBAL &VEREntryAddr // Verstage Entry +GLOBAL &ROMEntryAddr // Romstage Entry +GLOBAL &QCLEntryAddr // QCLstage Entry +GLOBAL &RAMEntryAddr // Ramstage Entry +GLOBAL &BL31EntryAddr // BL31 Entry +GLOBAL &DCEntryAddr // Depthcharge Entry +GLOBAL &KernelEntryAddr // Kernel Entry + +GLOBAL &PreRamConsoleAddr +GLOBAL &RamConsoleAddr +GLOBAL &PreRamCbfsCache +GLOBAL &VBoot2Work +GLOBAL &Stack +GLOBAL &Ttb +GLOBAL &Timestamp +GLOBAL &CbmemTop +GLOBAL &PostRamCbfsCache + +GLOBAL &CBTablePtr + +GLOBAL &debug + +;============================================================================ + +;--------------------------------------------------- +; Entry point +;--------------------------------------------------- +ENTRY &ImageName + + // Later these can be parameterized + &TargetPkg="Qcs405Pkg" + + // These settings come from .../src/soc/qualcomm/qcs405/include/soc/memlayout.ld + &BBEntryAddr=0x8c2f000 + &VEREntryAddr=0x8C00000 + &ROMEntryAddr=0x8C00000 + &QCLEntryAddr=0x1485AC00 + &RAMEntryAddr=0x9F860000 + &BL31EntryAddr=0x06820000 + &DCEntryAddr=0xf1104800 + &KernelEntryAddr=0x90080000 + + &PreRamConsoleAddr=0x8C4F400 + &VBoot2Work=0x8C47000 + &Stack=0x8C4B000 + &Ttb=0x8C39000 + &Timestamp=0x8C4F000 + &PreRamCbfsCache=0x8C57400 + &CbmemTop=0x280000000 + &PostRamCbfsCache=0x9F800000 + // End of memlayout.ld settings + + // Common commands irrespective of &Mode + PATH + &CwDir=os.pwd() + PATH + &CwDir + + // position at top of coreboot tree + // find depth count for source loading + cd ..\..\..\.. + &srcpath=os.pwd() + + b.sel PROGRAM onchip + ;sys.u + + b.d /all + + ;go &BBEntryAddr + ;wait !run() + +;--------------------------------------------------- +; Setup area and log +;--------------------------------------------------- + area.clear + area.reset + area.create CB_Logs 1000. 8192. + area.select CB_Logs + + ;winclear + ;b.d /all + + if FILE.EXIST("C:\TEMP\WIN.CMM") + do C:\TEMP\WIN.CMM + + area.view CB_Logs + + PRINT %String "Source Path: &srcpath" + + symbol.sourcepath.setbasedir &srcpath\src + + PRINT "pbl32_to_bootblock64 jump" + do pbl32_to_bootblock64_jump.cmm + do clear_bss.cmm + WAIT 5s + b + + // Make parsing simple, upper-case parameters + &Imagename=STRING.UPR("&Imagename") + IF (STR.CP("&ImageName","DEBUG,*")) + ( + &debug="DEBUG" + ) + ELSE + ( + &debug="" + ) + &Imagename=STR.CUT("&ImageName",6) + IF "&debug"=="" + ( + PRINT "SPI_RAM LOAD" + &ImageName=STRING.UPR("&ImageName") + IF "&ImageName"=="" + ( + &ImageName="RAM,BB" //for RAM load Bootblock only and jump till DC + ) + PRINT "&ImageName" + ) + ELSE + ( + if (STR.CP("&debug","DEBUG")) + ( + PRINT "DEBUG" + &ImageName=STRING.UPR("&ImageName") + IF "&ImageName"=="" + ( + &ImageName="RAM,ALL" //for RAM loading all the images + ) + PRINT "&ImageName" + ) + ) + + DO debug_cb_common.cmm &TargetPkg &srcpath &xblsrcpath &ImageName + + enddo diff --git a/util/qualcomm/scripts/cmm/debug_cb_common.cmm b/util/qualcomm/scripts/cmm/debug_cb_common.cmm index bdb0097cd3b..5959ee11e6a 100644 --- a/util/qualcomm/scripts/cmm/debug_cb_common.cmm +++ b/util/qualcomm/scripts/cmm/debug_cb_common.cmm @@ -104,6 +104,10 @@ ENTRY &TargetPkg &srcpath &xblsrcpath &ImageName if &BBStage ( + IF "&debug"=="" + ( + d.load.binary build/coreboot.rom 0xA0000000 + ) &imgpath="build\cbfs\fallback\bootblock.elf" if (&RAMLoad) d.load.elf &imgpath /strippart "coreboot" /sourcepath &srcpath @@ -114,9 +118,17 @@ ENTRY &TargetPkg &srcpath &xblsrcpath &ImageName ;b.s run_romstage /o ;d.set &PreRamConsoleAddr++0x8000 0 d.dump &PreRamConsoleAddr /spotlight - print %String "Now the control is in BootBlock, press enter after debugging to go to next stage" - print %String "Press enter to go to next stage" - enter + IF (STR.CP("&debug","DEBUG")) + ( + print %String "Now the control is in BootBlock, press enter after debugging to go to next stage" + print %String "Press enter to go to next stage" + enter + ) + ELSE + ( + go + enddo + ) ) go &VEREntryAddr diff --git a/util/qualcomm/scripts/cmm/pbl32_to_bootblock64_jump.cmm b/util/qualcomm/scripts/cmm/pbl32_to_bootblock64_jump.cmm new file mode 100644 index 00000000000..bebf85d1c4a --- /dev/null +++ b/util/qualcomm/scripts/cmm/pbl32_to_bootblock64_jump.cmm @@ -0,0 +1,15 @@ +PER.Set.simple SPR:0x36100 %Long 00c5183C +D.S AZSD:0x8600034 %LE %Long 0x8600000 +D.S AZSD:0x8600000 %LE %Long 0x1400000 +d.a 0x8600004 ldr r0,0x8600034 +d.a 0x8600008 mcr p15,0x0,r0,c12,c0,1 +d.a 0x860000c dsb +d.a 0x8600010 isb +d.a 0x8600014 mrc p15,0x0,r1,c12,c0,2 +d.a 0x8600018 orr r1,r1,0x3 +d.a 0x860001c mcr p15,0x0,r1,c12,c0,2 +d.a 0x8600020 isb +d.a 0x8600024 wfi +r.s pc 0x8600004 +go +b From c345570acce55a2cb13a65bf06c4e1d8069f7b36 Mon Sep 17 00:00:00 2001 From: Hung-Te Lin Date: Mon, 27 May 2019 11:02:00 +0800 Subject: [PATCH 529/588] src/driver/vpd: Update lib_vpd from upstream Update lib_vpd.c (only containing vpd_decode.c) to latest version from https://chromium.googlesource.com/chromiumos/platform/vpd The called module (vpd.c) has been also corrected for new lib_vpd types and constants. BUG=chromium:967209 TEST=select VPD config on kukui; make; boots on at least kukui boards. Change-Id: I3928e9c43cb87caf93fb44ee10434ce80f0a188a Signed-off-by: Hung-Te Lin Reviewed-on: https://review.coreboot.org/c/coreboot/+/33016 Tested-by: build bot (Jenkins) Reviewed-by: Joel Kitching --- src/drivers/vpd/Makefile.inc | 4 +- src/drivers/vpd/lib_vpd.c | 113 ------------------ src/drivers/vpd/lib_vpd.h | 226 ----------------------------------- src/drivers/vpd/vpd.c | 41 ++++--- src/drivers/vpd/vpd_decode.c | 92 ++++++++++++++ src/drivers/vpd/vpd_decode.h | 68 +++++++++++ 6 files changed, 184 insertions(+), 360 deletions(-) delete mode 100644 src/drivers/vpd/lib_vpd.c delete mode 100644 src/drivers/vpd/lib_vpd.h create mode 100644 src/drivers/vpd/vpd_decode.c create mode 100644 src/drivers/vpd/vpd_decode.h diff --git a/src/drivers/vpd/Makefile.inc b/src/drivers/vpd/Makefile.inc index 91c069d6c89..17019b599b1 100644 --- a/src/drivers/vpd/Makefile.inc +++ b/src/drivers/vpd/Makefile.inc @@ -1,2 +1,2 @@ -romstage-$(CONFIG_VPD) += lib_vpd.c -ramstage-$(CONFIG_VPD) += vpd.c lib_vpd.c +romstage-$(CONFIG_VPD) += vpd_decode.c +ramstage-$(CONFIG_VPD) += vpd.c vpd_decode.c diff --git a/src/drivers/vpd/lib_vpd.c b/src/drivers/vpd/lib_vpd.c deleted file mode 100644 index 0744a712abb..00000000000 --- a/src/drivers/vpd/lib_vpd.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2014 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. - * - */ -#include -#include "lib_vpd.h" - -/* Given an encoded string, this functions decodes the length field which varies - * from 1 byte to many bytes. - * - * The in points the actual byte going to be decoded. The *length returns - * the decoded length field. The number of consumed bytes will be stroed in - * decoded_len. - * - * Returns VPD_FAIL if more bit is 1, but actually reaches the end of string. - */ -int decodeLen(const int32_t max_len, - const uint8_t *in, - int32_t *length, - int32_t *decoded_len) -{ - uint8_t more; - int i = 0; - - assert(length); - assert(decoded_len); - - *length = 0; - do { - if (i >= max_len) - return VPD_FAIL; - - more = in[i] & 0x80; - *length <<= 7; - *length |= in[i] & 0x7f; - ++i; - } while (more); - - *decoded_len = i; - - return VPD_OK; -} - -/* Given the encoded string, this function invokes callback with extracted - * (key, value). The *consumed will be plused the number of bytes consumed in - * this function. - * - * The input_buf points to the first byte of the input buffer. - * - * The *consumed starts from 0, which is actually the next byte to be decoded. - * It can be non-zero to be used in multiple calls. - * - * If one entry is successfully decoded, sends it to callback and returns the - * result. - */ -int decodeVpdString(const int32_t max_len, - const uint8_t *input_buf, - int32_t *consumed, - VpdDecodeCallback callback, - void *callback_arg) -{ - int type; - int32_t key_len, value_len; - int32_t decoded_len; - const uint8_t *key, *value; - - /* type */ - if (*consumed >= max_len) - return VPD_FAIL; - - type = input_buf[*consumed]; - switch (type) { - case VPD_TYPE_INFO: - case VPD_TYPE_STRING: - (*consumed)++; - /* key */ - if (VPD_OK != decodeLen(max_len - *consumed, - &input_buf[*consumed], &key_len, - &decoded_len) || - *consumed + decoded_len >= max_len) { - return VPD_FAIL; - } - - *consumed += decoded_len; - key = &input_buf[*consumed]; - *consumed += key_len; - - /* value */ - if (VPD_OK != decodeLen(max_len - *consumed, - &input_buf[*consumed], - &value_len, &decoded_len) || - *consumed + decoded_len > max_len) { - return VPD_FAIL; - } - *consumed += decoded_len; - value = &input_buf[*consumed]; - *consumed += value_len; - - if (type == VPD_TYPE_STRING) - return callback(key, key_len, value, value_len, - callback_arg); - - return VPD_OK; - - default: - return VPD_FAIL; - break; - } - - return VPD_OK; -} diff --git a/src/drivers/vpd/lib_vpd.h b/src/drivers/vpd/lib_vpd.h deleted file mode 100644 index 156d27939ff..00000000000 --- a/src/drivers/vpd/lib_vpd.h +++ /dev/null @@ -1,226 +0,0 @@ -/* - * Copyright (c) 2013 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. - * - */ - -#ifndef __LIB_VPD__ -#define __LIB_VPD__ - -#include - -enum { - VPD_OK = 0, - VPD_FAIL, -}; - -enum { - VPD_TYPE_TERMINATOR = 0, - VPD_TYPE_STRING, - VPD_TYPE_INFO = 0xfe, - VPD_TYPE_IMPLICIT_TERMINATOR = 0xff, -}; - -enum { - VPD_AS_LONG_AS = -1, -}; - -enum { /* export_type */ - VPD_EXPORT_KEY_VALUE = 1, - VPD_EXPORT_VALUE, - VPD_EXPORT_AS_PARAMETER, -}; - -/* Callback for decodeVpdString to invoke. */ -typedef int VpdDecodeCallback(const uint8_t *key, int32_t key_len, - const uint8_t *value, int32_t value_len, - void *arg); - -/* Container data types */ -struct StringPair { - uint8_t *key; - uint8_t *value; - int pad_len; - int filter_out; /* TRUE means not exported. */ - struct StringPair *next; -}; - -struct PairContainer { - struct StringPair *first; -}; - - -/*********************************************************************** - * Encode and decode VPD entries - ***********************************************************************/ - -/* Encodes the len into multiple bytes with the following format. - * - * 7 6 ............ 0 - * +----+------------------+ - * |More| Length | ... - * +----+------------------+ - * - * The encode_buf points to the actual position we are going to store. - * encoded_len will return the exact bytes we encoded in this function. - * Returns fail if the buffer is not long enough. - */ -int encodeLen( - const int32_t len, - uint8_t *encode_buf, - const int32_t max_len, - int32_t *encoded_len); - -/* Given an encoded string, this functions decodes the length field which varies - * from 1 byte to many bytes. - * - * The in points the actual byte going to be decoded. The *length returns - * the decoded length field. The number of consumed bytes will be stroed in - * decoded_len. - * - * Returns VPD_FAIL if more bit is 1, but actually reaches the end of string. - */ -int decodeLen( - const int32_t max_len, - const uint8_t *in, - int32_t *length, - int32_t *decoded_len); - - -/* Encodes the terminator. - * When calling, the output_buf should point to the start of buffer while - * *generated_len should contain how many bytes exist in buffer now. - * After return, *generated_len would be plused the number of bytes generated - * in this function. - */ -int encodeVpdTerminator( - const int max_buffer_len, - uint8_t *output_buf, - int *generated_len); - -/* Encodes the given type/key/value pair into buffer. - * - * The pad_value_len is used to control the output value length. - * When pad_value_len > 0, the value is outputted into fixed length (pad \0 - * if the value is shorter). Truncated if too long. - * pad_value_len == VPD_NO_LIMIT, output the value as long as possible. - * This is useful when we want to fix the structure layout at beginning. - * - * The encoded string will be stored in output_buf. If it is longer than - * max_buffer_len, this function returns fail. If the buffer is long enough, - * the generated_len will be updated. - * - * When calling, the output_buf should point to the start of buffer while - * *generated_len should contain how many bytes exist in buffer now. - * After return, *generated_len would be plused the number of bytes generated - * in this function. - * - * The initial value of *generated_len can be non-zero, so that this value - * can be used between multiple calls to encodeVpd2Pair(). - */ -int encodeVpdString( - const uint8_t *key, - const uint8_t *value, - const int pad_value_len, - const int max_buffer_len, - uint8_t *output_buf, - int *generated_len); - - -/* Given the encoded string, this function invokes callback with extracted - * (key, value). The *consumed will be plused the number of bytes consumed in - * this function. - * - * The input_buf points to the first byte of the input buffer. - * - * The *consumed starts from 0, which is actually the next byte to be decoded. - * It can be non-zero to be used in multiple calls. - * - * If one entry is successfully decoded, sends it to callback and returns the - * result. - */ -int decodeVpdString( - const int32_t max_len, - const uint8_t *input_buf, - int32_t *consumed, - VpdDecodeCallback callback, - void *callback_arg); - -/*********************************************************************** - * Container helpers - ***********************************************************************/ -void initContainer(struct PairContainer *container); - -struct StringPair *findString(struct PairContainer *container, - const uint8_t *key, - struct StringPair ***prev_next); - -/* If key is already existed in container, its value will be replaced. - * If not existed, creates new entry in container. - */ -void setString(struct PairContainer *container, - const uint8_t *key, - const uint8_t *value, - const int pad_len); - -/* merge all entries in src into dst. If key is duplicate, overwrite it. - */ -void mergeContainer(struct PairContainer *dst, - const struct PairContainer *src); - -/* subtract src from dst. -*/ -int subtractContainer(struct PairContainer *dst, - const struct PairContainer *src); - -/* Given a container, encode its all entries into the buffer. - */ -int encodeContainer(const struct PairContainer *container, - const int max_buf_len, - uint8_t *buf, - int *generated); - -/* Given a VPD blob, decode its entries and push into container. - */ -int decodeToContainer(struct PairContainer *container, - const int32_t max_len, - const uint8_t *input_buf, - int32_t *consumed); - -/* Set filter for exporting functions. - * If filter is NULL, resets the filter so that everything can be exported. - */ -int setContainerFilter(struct PairContainer *container, - const uint8_t *filter); - -/* - * Remove a key. - * Returns VPD_OK if deleted successfully. Otherwise, VPD_FAIL. - */ -int deleteKey(struct PairContainer *container, - const uint8_t *key); - -/* - * Returns number of pairs in container. - */ -int lenOfContainer(const struct PairContainer *container); - -/* - * Export the container content with human-readable text. - * - * The buf points to the first byte of buffer and *generated contains the number - * of bytes already existed in buffer. - * - * Afterward, the *generated will be plused on exact bytes this function has - * generated. - */ -int exportContainer(const int export_type, - const struct PairContainer *container, - const int max_buf_len, - uint8_t *buf, - int *generated); - -void destroyContainer(struct PairContainer *container); - -#endif /* __LIB_VPD__ */ diff --git a/src/drivers/vpd/vpd.c b/src/drivers/vpd/vpd.c index e620b58b31d..c6dd339f619 100644 --- a/src/drivers/vpd/vpd.c +++ b/src/drivers/vpd/vpd.c @@ -12,7 +12,7 @@ #include #include "vpd.h" -#include "lib_vpd.h" +#include "vpd_decode.h" #include "vpd_tables.h" /* Currently we only support Google VPD 2.0, which has a fixed offset. */ @@ -160,27 +160,27 @@ static void cbmem_add_cros_vpd(int is_recovery) } } -static int vpd_gets_callback(const uint8_t *key, int32_t key_len, - const uint8_t *value, int32_t value_len, - void *arg) +static int vpd_gets_callback(const uint8_t *key, uint32_t key_len, + const uint8_t *value, uint32_t value_len, + void *arg) { struct vpd_gets_arg *result = (struct vpd_gets_arg *)arg; if (key_len != result->key_len || memcmp(key, result->key, key_len) != 0) - /* Returns VPD_OK to continue parsing. */ - return VPD_OK; + /* Returns VPD_DECODE_OK to continue parsing. */ + return VPD_DECODE_OK; result->matched = 1; result->value = value; result->value_len = value_len; - /* Returns VPD_FAIL to stop parsing. */ - return VPD_FAIL; + /* Returns VPD_DECODE_FAIL to stop parsing. */ + return VPD_DECODE_FAIL; } const void *vpd_find(const char *key, int *size, enum vpd_region region) { struct vpd_gets_arg arg = {0}; - int consumed = 0; + uint32_t consumed = 0; const struct vpd_cbmem *vpd; vpd = cbmem_find(CBMEM_ID_VPD); @@ -190,18 +190,21 @@ const void *vpd_find(const char *key, int *size, enum vpd_region region) arg.key = (const uint8_t *)key; arg.key_len = strlen(key); - if (region == VPD_ANY || region == VPD_RO) - while (VPD_OK == decodeVpdString(vpd->ro_size, vpd->blob, - &consumed, vpd_gets_callback, &arg)) { - /* Iterate until found or no more entries. */ + if (region == VPD_ANY || region == VPD_RO) { + while (vpd_decode_string( + vpd->ro_size, vpd->blob, &consumed, + vpd_gets_callback, &arg) == VPD_DECODE_OK) { + /* Iterate until found or no more entries. */ } - - if (!arg.matched && region != VPD_RO) - while (VPD_OK == decodeVpdString(vpd->rw_size, - vpd->blob + vpd->ro_size, &consumed, - vpd_gets_callback, &arg)) { - /* Iterate until found or no more entries. */ + } + if (!arg.matched && region != VPD_RO) { + while (vpd_decode_string( + vpd->rw_size, vpd->blob + vpd->ro_size, + &consumed, vpd_gets_callback, + &arg) == VPD_DECODE_OK) { + /* Iterate until found or no more entries. */ } + } if (!arg.matched) return NULL; diff --git a/src/drivers/vpd/vpd_decode.c b/src/drivers/vpd/vpd_decode.c new file mode 100644 index 00000000000..0eab704ca80 --- /dev/null +++ b/src/drivers/vpd/vpd_decode.c @@ -0,0 +1,92 @@ +/* + * Copyright 2014 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. + * + * This is a copy from upstream: + * https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/lib/vpd_decode.c + */ +#include "vpd_decode.h" + +int vpd_decode_len( + const u32 max_len, const u8 *in, u32 *length, u32 *decoded_len) +{ + u8 more; + int i = 0; + + if (!length || !decoded_len) + return VPD_DECODE_FAIL; + + *length = 0; + do { + if (i >= max_len) + return VPD_DECODE_FAIL; + + more = in[i] & 0x80; + *length <<= 7; + *length |= in[i] & 0x7f; + ++i; + } while (more); + + *decoded_len = i; + return VPD_DECODE_OK; +} + +int vpd_decode_string( + const u32 max_len, const u8 *input_buf, u32 *consumed, + vpd_decode_callback callback, void *callback_arg) +{ + int type; + int res; + u32 key_len; + u32 value_len; + u32 decoded_len; + const u8 *key; + const u8 *value; + + /* type */ + if (*consumed >= max_len) + return VPD_DECODE_FAIL; + + type = input_buf[*consumed]; + + switch (type) { + case VPD_TYPE_INFO: + case VPD_TYPE_STRING: + (*consumed)++; + + /* key */ + res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed], + &key_len, &decoded_len); + /* key name cannot be empty, and must be followed by value. */ + if (res != VPD_DECODE_OK || key_len < 1 || + *consumed + decoded_len + key_len >= max_len) + return VPD_DECODE_FAIL; + + *consumed += decoded_len; + key = &input_buf[*consumed]; + *consumed += key_len; + + /* value */ + res = vpd_decode_len(max_len - *consumed, &input_buf[*consumed], + &value_len, &decoded_len); + /* value can be empty (value_len = 0). */ + if (res != VPD_DECODE_OK || + *consumed + decoded_len + value_len > max_len) + return VPD_DECODE_FAIL; + + *consumed += decoded_len; + value = &input_buf[*consumed]; + *consumed += value_len; + + if (type == VPD_TYPE_STRING) + return callback(key, key_len, value, value_len, + callback_arg); + break; + + default: + return VPD_DECODE_FAIL; + } + + return VPD_DECODE_OK; +} diff --git a/src/drivers/vpd/vpd_decode.h b/src/drivers/vpd/vpd_decode.h new file mode 100644 index 00000000000..99ca7efa81a --- /dev/null +++ b/src/drivers/vpd/vpd_decode.h @@ -0,0 +1,68 @@ +/* + * Copyright 2019 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. + * + * This is a copy from upstream: + * https://chromium.googlesource.com/chromiumos/platform/vpd/+/master/include/lib/vpd_decode.h + */ + +#ifndef __VPD_DECODE_H +#define __VPD_DECODE_H + +#include + +enum { + VPD_DECODE_OK = 0, + VPD_DECODE_FAIL = 1, +}; + +enum { + VPD_TYPE_TERMINATOR = 0, + VPD_TYPE_STRING, + VPD_TYPE_INFO = 0xfe, + VPD_TYPE_IMPLICIT_TERMINATOR = 0xff, +}; + +/* Callback for vpd_decode_string to invoke. */ +typedef int vpd_decode_callback( + const u8 *key, u32 key_len, const u8 *value, u32 value_len, + void *arg); + +/* + * vpd_decode_len + * + * Given an encoded string, this function extracts the length of content + * (either key or value). The *consumed will contain the number of bytes + * consumed. + * + * The input_buf points to the first byte of the input buffer. + * + * The *consumed starts from 0, which is actually the next byte to be decoded. + * It can be non-zero to be used in multiple calls. + * + * Returns VPD_DECODE_OK on success, otherwise VPD_DECODE_FAIL. + */ +int vpd_decode_len( + const u32 max_len, const u8 *in, u32 *length, u32 *decoded_len); + +/* + * vpd_decode_string + * + * Given the encoded string, this function invokes callback with extracted + * (key, value). The *consumed will be plused the number of bytes consumed in + * this function. + * + * The input_buf points to the first byte of the input buffer. + * + * The *consumed starts from 0, which is actually the next byte to be decoded. + * It can be non-zero to be used in multiple calls. + * + * If one entry is successfully decoded, sends it to callback and returns the + * result. + */ +int vpd_decode_string( + const u32 max_len, const u8 *input_buf, u32 *consumed, + vpd_decode_callback callback, void *callback_arg); + +#endif /* __VPD_DECODE_H */ From 51dc5ea735cd175a6d38d59d8b3b3eadee027e6c Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 23:26:07 +0200 Subject: [PATCH 530/588] soc/intel/common/lpss: Drop now unused lpss_clk_read() Change-Id: I7def72e820ee1a4fa47c34b26dab9e0886ba74e6 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33094 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/soc/intel/common/block/include/intelblocks/lpss.h | 3 --- src/soc/intel/common/block/lpss/lpss.c | 9 --------- 2 files changed, 12 deletions(-) diff --git a/src/soc/intel/common/block/include/intelblocks/lpss.h b/src/soc/intel/common/block/include/intelblocks/lpss.h index ca5568996f5..eb38f13a71e 100644 --- a/src/soc/intel/common/block/include/intelblocks/lpss.h +++ b/src/soc/intel/common/block/include/intelblocks/lpss.h @@ -30,7 +30,4 @@ void lpss_clk_update(uintptr_t base, uint32_t clk_m_val, uint32_t clk_n_val); /* Check if controller is in reset. */ bool lpss_is_controller_in_reset(uintptr_t base); -/* Read LPSS CLK register */ -uint32_t lpss_clk_read(uintptr_t base); - #endif /* SOC_INTEL_COMMON_BLOCK_LPSS_H */ diff --git a/src/soc/intel/common/block/lpss/lpss.c b/src/soc/intel/common/block/lpss/lpss.c index 1168871d097..6b6d17b1061 100644 --- a/src/soc/intel/common/block/lpss/lpss.c +++ b/src/soc/intel/common/block/lpss/lpss.c @@ -69,12 +69,3 @@ void lpss_clk_update(uintptr_t base, uint32_t clk_m_val, uint32_t clk_n_val) write32(addr, clk_sel); } - -uint32_t lpss_clk_read(uintptr_t base) -{ - uint8_t *addr = (void *)base; - - addr += LPSS_CLOCK_CTL_REG; - - return read32(addr); -} From 8bbad6c8186037e67da9f1465078b5952c0c0899 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 23:18:26 +0200 Subject: [PATCH 531/588] soc/intel/common/uart: Drop dead call to soc_uart_set_legacy_mode() The only path that leads here is guarded by both !DRIVERS_UART_ 8250MEM_32 and INTEL_LPSS_UART_FOR_CONSOLE but the latter selects the former. Change-Id: I6e0765b028572950991c45b45b2051f4f176a94a Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33095 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/soc/intel/common/block/include/intelblocks/uart.h | 6 ------ src/soc/intel/common/block/uart/uart.c | 4 ---- 2 files changed, 10 deletions(-) diff --git a/src/soc/intel/common/block/include/intelblocks/uart.h b/src/soc/intel/common/block/include/intelblocks/uart.h index ad2ddf4b280..55f259db7cf 100644 --- a/src/soc/intel/common/block/include/intelblocks/uart.h +++ b/src/soc/intel/common/block/include/intelblocks/uart.h @@ -91,10 +91,4 @@ struct device *uart_get_device(void); */ struct device *soc_uart_console_to_device(int uart_console); -/* - * Set UART to legacy mode - * Put UART in byte access mode for 16550 compatibility - */ -void soc_uart_set_legacy_mode(void); - #endif /* SOC_INTEL_COMMON_BLOCK_UART_H */ diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index a8e5792a860..35c2c6cafb0 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -139,10 +139,6 @@ void uart_bootblock_init(void) uart_common_init(uart_get_device(), UART_BASE(CONFIG_UART_FOR_CONSOLE)); - if (!CONFIG(DRIVERS_UART_8250MEM_32)) - /* Put UART in byte access mode for 16550 compatibility */ - soc_uart_set_legacy_mode(); - /* Configure the 2 pads per UART. */ uart_configure_gpio_pads(); } From ce8eebd3b7642e3d675616fb8d3d068cb58d66ef Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 18:33:35 +0200 Subject: [PATCH 532/588] soc/intel/common/uart: Only return valid UART base We only configure the base address for the console UART, the other addresses are never assigned to the hardware. It seems better to return 0 for them instead of a spurious value. Change-Id: I3fa5c99958b56ca5b0b603917c086bdddb677fa2 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33096 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/soc/intel/common/block/uart/uart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 35c2c6cafb0..47774b6e96b 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -46,8 +46,9 @@ static void uart_lpss_init(uintptr_t baseaddr) #if CONFIG(DRIVERS_UART_8250MEM) uintptr_t uart_platform_base(int idx) { - /* return Base address for UART console index */ - return UART_BASE_0_ADDR(idx); + if (idx == CONFIG_UART_FOR_CONSOLE) + return UART_BASE_0_ADDR(CONFIG_UART_FOR_CONSOLE); + return 0; } #endif From 62ddc491cf8c8c6412177d2866bec89c6f4906dc Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 18:39:31 +0200 Subject: [PATCH 533/588] soc/intel/common/uart: Correctly guard uart_platform_base() We should only provide this implementation when the Intel LPSS UART is used. Otherwise, no other UART could be used for the console with these SoCs. Change-Id: Iebd89edb3f21d4a68587fd02659b4d529f3f4bbe Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33097 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao --- src/soc/intel/common/block/uart/uart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 47774b6e96b..84ba1ee0f22 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -43,7 +43,7 @@ static void uart_lpss_init(uintptr_t baseaddr) CONFIG_SOC_INTEL_COMMON_LPSS_UART_CLK_N_VAL); } -#if CONFIG(DRIVERS_UART_8250MEM) +#if CONFIG(INTEL_LPSS_UART_FOR_CONSOLE) uintptr_t uart_platform_base(int idx) { if (idx == CONFIG_UART_FOR_CONSOLE) From 2deb5fb3b07e07ee3d0d142723e2a25f5982d417 Mon Sep 17 00:00:00 2001 From: John Zhao Date: Wed, 29 May 2019 18:12:01 -0700 Subject: [PATCH 534/588] src/device: Prevent attack on null pointer dereference Clang Static Analyzer version 8.0.0 detects access to field dev results in a dereference of a null pointer which is loaded from variable bus. Add sanity check for pointer bus to prevent null pointer dereference. TEST=Built and boot up to kernel. Change-Id: I084906c33065eaa834f50c545efcfab620658ec9 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/33101 Tested-by: build bot (Jenkins) Reviewed-by: Lijian Zhao --- src/device/device.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/device/device.c b/src/device/device.c index 1b4255bffe7..17cd8f4ab82 100644 --- a/src/device/device.c +++ b/src/device/device.c @@ -340,6 +340,9 @@ static void compute_resources(struct bus *bus, struct resource *bridge, resource_t base; base = round(bridge->base, bridge->align); + if (!bus) + return; + printk(BIOS_SPEW, "%s %s: base: %llx size: %llx align: %d gran: %d" " limit: %llx\n", dev_path(bus->dev), resource2str(bridge), base, bridge->size, bridge->align, @@ -484,6 +487,9 @@ static void allocate_resources(struct bus *bus, struct resource *bridge, resource_t base; base = bridge->base; + if (!bus) + return; + printk(BIOS_SPEW, "%s %s: base:%llx size:%llx align:%d gran:%d " "limit:%llx\n", dev_path(bus->dev), resource2str(bridge), From 10ed868d1999e4bd69efd8b86093bd953b8f8827 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 23:13:47 +0200 Subject: [PATCH 535/588] soc/intel/{skl,cnl,icl}: Drop soc_uart_set_legacy_mode() This is never called: The only calling path is guarded by both !DRIVERS_UART_8250MEM_32 and INTEL_LPSS_UART_FOR_CONSOLE but the latter selects the former. If somebody figures out how this is supposed to be used, we can easily revive the implementation. Change-Id: I96e304bdee4eadb52725027d0d662ef75f3d4307 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33093 Reviewed-by: Lance Zhao Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/uart.c | 15 --------------- src/soc/intel/icelake/uart.c | 15 --------------- src/soc/intel/skylake/uart.c | 15 --------------- 3 files changed, 45 deletions(-) diff --git a/src/soc/intel/cannonlake/uart.c b/src/soc/intel/cannonlake/uart.c index 2bd906adf89..7174a9a58f8 100644 --- a/src/soc/intel/cannonlake/uart.c +++ b/src/soc/intel/cannonlake/uart.c @@ -24,10 +24,6 @@ #include #include -/* Serial IO UART controller legacy mode */ -#define PCR_SERIAL_IO_GPPRVRW7 0x618 -#define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) - const struct uart_gpio_pad_config uart_gpio_pads[] = { { .console_index = 0, @@ -54,17 +50,6 @@ const struct uart_gpio_pad_config uart_gpio_pads[] = { const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); -void soc_uart_set_legacy_mode(void) -{ - pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, - PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); - /* - * Dummy read after setting any of GPPRVRW7. - * Required for UART 16550 8-bit Legacy mode to become active - */ - lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); -} - struct device *soc_uart_console_to_device(int uart_console) { /* diff --git a/src/soc/intel/icelake/uart.c b/src/soc/intel/icelake/uart.c index 2bd906adf89..7174a9a58f8 100644 --- a/src/soc/intel/icelake/uart.c +++ b/src/soc/intel/icelake/uart.c @@ -24,10 +24,6 @@ #include #include -/* Serial IO UART controller legacy mode */ -#define PCR_SERIAL_IO_GPPRVRW7 0x618 -#define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) - const struct uart_gpio_pad_config uart_gpio_pads[] = { { .console_index = 0, @@ -54,17 +50,6 @@ const struct uart_gpio_pad_config uart_gpio_pads[] = { const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); -void soc_uart_set_legacy_mode(void) -{ - pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, - PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); - /* - * Dummy read after setting any of GPPRVRW7. - * Required for UART 16550 8-bit Legacy mode to become active - */ - lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); -} - struct device *soc_uart_console_to_device(int uart_console) { /* diff --git a/src/soc/intel/skylake/uart.c b/src/soc/intel/skylake/uart.c index 1b2a7428df8..8b7c99eae52 100644 --- a/src/soc/intel/skylake/uart.c +++ b/src/soc/intel/skylake/uart.c @@ -24,10 +24,6 @@ #include #include -/* Serial IO UART controller legacy mode */ -#define PCR_SERIAL_IO_GPPRVRW7 0x618 -#define PCR_SIO_PCH_LEGACY_UART(idx) (1 << (idx)) - /* UART pad configuration. Support RXD and TXD for now. */ const struct uart_gpio_pad_config uart_gpio_pads[] = { { @@ -55,17 +51,6 @@ const struct uart_gpio_pad_config uart_gpio_pads[] = { const int uart_max_index = ARRAY_SIZE(uart_gpio_pads); -void soc_uart_set_legacy_mode(void) -{ - pcr_write32(PID_SERIALIO, PCR_SERIAL_IO_GPPRVRW7, - PCR_SIO_PCH_LEGACY_UART(CONFIG_UART_FOR_CONSOLE)); - /* - * Dummy read after setting any of GPPRVRW7. - * Required for UART 16550 8-bit Legacy mode to become active - */ - lpss_clk_read(UART_BASE(CONFIG_UART_FOR_CONSOLE)); -} - struct device *soc_uart_console_to_device(int uart_console) { /* From fa1f7216ce2105aab79ee91cb3f8c8e879ded341 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 15:40:54 +0200 Subject: [PATCH 536/588] nb/intel/sandybridge: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iaac05f73d2ba892d3ec7ee2ac0c16a98f2fce5bc Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32926 Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/northbridge/intel/sandybridge/early_dmi.c | 129 +++++++++--------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/src/northbridge/intel/sandybridge/early_dmi.c b/src/northbridge/intel/sandybridge/early_dmi.c index db49040dc18..6d41a2da96e 100644 --- a/src/northbridge/intel/sandybridge/early_dmi.c +++ b/src/northbridge/intel/sandybridge/early_dmi.c @@ -19,7 +19,6 @@ void early_init_dmi(void) { - volatile u32 tmp; int i; DMIBAR32(0x0914) |= 0x80000000; @@ -39,133 +38,133 @@ void early_init_dmi(void) DMIBAR32(0x090c) &= 0xfe1fffff; DMIBAR32(0x092c) &= 0xfe1fffff; - tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904); // !!! = 0x7a1842ec DMIBAR32(0x0904) = 0x7a1842ec; - tmp = DMIBAR32(0x090c); // !!! = 0x00000208 + DMIBAR32(0x090c); // !!! = 0x00000208 DMIBAR32(0x090c) = 0x00000128; - tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924); // !!! = 0x7a1842ec DMIBAR32(0x0924) = 0x7a1842ec; - tmp = DMIBAR32(0x092c); // !!! = 0x00000208 + DMIBAR32(0x092c); // !!! = 0x00000208 DMIBAR32(0x092c) = 0x00000128; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700); // !!! = 0x46139008 DMIBAR32(0x0700) = 0x46139008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720); // !!! = 0x46139008 DMIBAR32(0x0720) = 0x46139008; - tmp = DMIBAR32(0x0c04); // !!! = 0x2e680008 + DMIBAR32(0x0c04); // !!! = 0x2e680008 DMIBAR32(0x0c04) = 0x2e680008; - tmp = DMIBAR32(0x0904); // !!! = 0x7a1842ec + DMIBAR32(0x0904); // !!! = 0x7a1842ec DMIBAR32(0x0904) = 0x3a1842ec; - tmp = DMIBAR32(0x0924); // !!! = 0x7a1842ec + DMIBAR32(0x0924); // !!! = 0x7a1842ec DMIBAR32(0x0924) = 0x3a1842ec; - tmp = DMIBAR32(0x0910); // !!! = 0x00006300 + DMIBAR32(0x0910); // !!! = 0x00006300 DMIBAR32(0x0910) = 0x00004300; - tmp = DMIBAR32(0x0930); // !!! = 0x00006300 + DMIBAR32(0x0930); // !!! = 0x00006300 DMIBAR32(0x0930) = 0x00004300; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042010 + DMIBAR32(0x0a00); // !!! = 0x03042010 DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042010 + DMIBAR32(0x0a10); // !!! = 0x03042010 DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042010 + DMIBAR32(0x0a20); // !!! = 0x03042010 DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042010 + DMIBAR32(0x0a30); // !!! = 0x03042010 DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00); // !!! = 0x29700c08 DMIBAR32(0x0c00) = 0x29700c08; - tmp = DMIBAR32(0x0a04); // !!! = 0x0c0708f0 + DMIBAR32(0x0a04); // !!! = 0x0c0708f0 DMIBAR32(0x0a04) = 0x0c0718f0; - tmp = DMIBAR32(0x0a14); // !!! = 0x0c0708f0 + DMIBAR32(0x0a14); // !!! = 0x0c0708f0 DMIBAR32(0x0a14) = 0x0c0718f0; - tmp = DMIBAR32(0x0a24); // !!! = 0x0c0708f0 + DMIBAR32(0x0a24); // !!! = 0x0c0708f0 DMIBAR32(0x0a24) = 0x0c0718f0; - tmp = DMIBAR32(0x0a34); // !!! = 0x0c0708f0 + DMIBAR32(0x0a34); // !!! = 0x0c0708f0 DMIBAR32(0x0a34) = 0x0c0718f0; - tmp = DMIBAR32(0x0900); // !!! = 0x50000000 + DMIBAR32(0x0900); // !!! = 0x50000000 DMIBAR32(0x0900) = 0x50000000; - tmp = DMIBAR32(0x0920); // !!! = 0x50000000 + DMIBAR32(0x0920); // !!! = 0x50000000 DMIBAR32(0x0920) = 0x50000000; - tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908); // !!! = 0x51ffffff DMIBAR32(0x0908) = 0x51ffffff; - tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928); // !!! = 0x51ffffff DMIBAR32(0x0928) = 0x51ffffff; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00); // !!! = 0x03042018 DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10); // !!! = 0x03042018 DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20); // !!! = 0x03042018 DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30); // !!! = 0x03042018 DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700); // !!! = 0x46139008 DMIBAR32(0x0700) = 0x46139008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720); // !!! = 0x46139008 DMIBAR32(0x0720) = 0x46139008; - tmp = DMIBAR32(0x0904); // !!! = 0x3a1842ec + DMIBAR32(0x0904); // !!! = 0x3a1842ec DMIBAR32(0x0904) = 0x3a1846ec; - tmp = DMIBAR32(0x0924); // !!! = 0x3a1842ec + DMIBAR32(0x0924); // !!! = 0x3a1842ec DMIBAR32(0x0924) = 0x3a1846ec; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00); // !!! = 0x03042018 DMIBAR32(0x0a00) = 0x03042018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10); // !!! = 0x03042018 DMIBAR32(0x0a10) = 0x03042018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20); // !!! = 0x03042018 DMIBAR32(0x0a20) = 0x03042018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30); // !!! = 0x03042018 DMIBAR32(0x0a30) = 0x03042018; - tmp = DMIBAR32(0x0908); // !!! = 0x51ffffff + DMIBAR32(0x0908); // !!! = 0x51ffffff DMIBAR32(0x0908) = 0x51ffffff; - tmp = DMIBAR32(0x0928); // !!! = 0x51ffffff + DMIBAR32(0x0928); // !!! = 0x51ffffff DMIBAR32(0x0928) = 0x51ffffff; - tmp = DMIBAR32(0x0c00); // !!! = 0x29700c08 + DMIBAR32(0x0c00); // !!! = 0x29700c08 DMIBAR32(0x0c00) = 0x29700c08; - tmp = DMIBAR32(0x0c0c); // !!! = 0x16063400 + DMIBAR32(0x0c0c); // !!! = 0x16063400 DMIBAR32(0x0c0c) = 0x00063400; - tmp = DMIBAR32(0x0700); // !!! = 0x46139008 + DMIBAR32(0x0700); // !!! = 0x46139008 DMIBAR32(0x0700) = 0x46339008; - tmp = DMIBAR32(0x0720); // !!! = 0x46139008 + DMIBAR32(0x0720); // !!! = 0x46139008 DMIBAR32(0x0720) = 0x46339008; - tmp = DMIBAR32(0x0700); // !!! = 0x46339008 + DMIBAR32(0x0700); // !!! = 0x46339008 DMIBAR32(0x0700) = 0x45339008; - tmp = DMIBAR32(0x0720); // !!! = 0x46339008 + DMIBAR32(0x0720); // !!! = 0x46339008 DMIBAR32(0x0720) = 0x45339008; - tmp = DMIBAR32(0x0700); // !!! = 0x45339008 + DMIBAR32(0x0700); // !!! = 0x45339008 DMIBAR32(0x0700) = 0x453b9008; - tmp = DMIBAR32(0x0720); // !!! = 0x45339008 + DMIBAR32(0x0720); // !!! = 0x45339008 DMIBAR32(0x0720) = 0x453b9008; - tmp = DMIBAR32(0x0700); // !!! = 0x453b9008 + DMIBAR32(0x0700); // !!! = 0x453b9008 DMIBAR32(0x0700) = 0x45bb9008; - tmp = DMIBAR32(0x0720); // !!! = 0x453b9008 + DMIBAR32(0x0720); // !!! = 0x453b9008 DMIBAR32(0x0720) = 0x45bb9008; - tmp = DMIBAR32(0x0700); // !!! = 0x45bb9008 + DMIBAR32(0x0700); // !!! = 0x45bb9008 DMIBAR32(0x0700) = 0x45fb9008; - tmp = DMIBAR32(0x0720); // !!! = 0x45bb9008 + DMIBAR32(0x0720); // !!! = 0x45bb9008 DMIBAR32(0x0720) = 0x45fb9008; - tmp = DMIBAR32(0x0914); // !!! = 0x9021a080 + DMIBAR32(0x0914); // !!! = 0x9021a080 DMIBAR32(0x0914) = 0x9021a280; - tmp = DMIBAR32(0x0934); // !!! = 0x9021a080 + DMIBAR32(0x0934); // !!! = 0x9021a080 DMIBAR32(0x0934) = 0x9021a280; - tmp = DMIBAR32(0x0914); // !!! = 0x9021a280 + DMIBAR32(0x0914); // !!! = 0x9021a280 DMIBAR32(0x0914) = 0x9821a280; - tmp = DMIBAR32(0x0934); // !!! = 0x9021a280 + DMIBAR32(0x0934); // !!! = 0x9021a280 DMIBAR32(0x0934) = 0x9821a280; - tmp = DMIBAR32(0x0a00); // !!! = 0x03042018 + DMIBAR32(0x0a00); // !!! = 0x03042018 DMIBAR32(0x0a00) = 0x03242018; - tmp = DMIBAR32(0x0a10); // !!! = 0x03042018 + DMIBAR32(0x0a10); // !!! = 0x03042018 DMIBAR32(0x0a10) = 0x03242018; - tmp = DMIBAR32(0x0a20); // !!! = 0x03042018 + DMIBAR32(0x0a20); // !!! = 0x03042018 DMIBAR32(0x0a20) = 0x03242018; - tmp = DMIBAR32(0x0a30); // !!! = 0x03042018 + DMIBAR32(0x0a30); // !!! = 0x03042018 DMIBAR32(0x0a30) = 0x03242018; - tmp = DMIBAR32(0x0258); // !!! = 0x40000600 + DMIBAR32(0x0258); // !!! = 0x40000600 DMIBAR32(0x0258) = 0x60000600; - tmp = DMIBAR32(0x0904); // !!! = 0x3a1846ec + DMIBAR32(0x0904); // !!! = 0x3a1846ec DMIBAR32(0x0904) = 0x2a1846ec; - tmp = DMIBAR32(0x0914); // !!! = 0x9821a280 + DMIBAR32(0x0914); // !!! = 0x9821a280 DMIBAR32(0x0914) = 0x98200280; - tmp = DMIBAR32(0x0924); // !!! = 0x3a1846ec + DMIBAR32(0x0924); // !!! = 0x3a1846ec DMIBAR32(0x0924) = 0x2a1846ec; - tmp = DMIBAR32(0x0934); // !!! = 0x9821a280 + DMIBAR32(0x0934); // !!! = 0x9821a280 DMIBAR32(0x0934) = 0x98200280; - tmp = DMIBAR32(0x022c); // !!! = 0x00c26460 + DMIBAR32(0x022c); // !!! = 0x00c26460 DMIBAR32(0x022c) = 0x00c2403c; early_pch_init_native_dmi_pre(); From 9c8895fd889b01fe71bb296e2566b96a9542b303 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 19:57:43 +0200 Subject: [PATCH 537/588] nb/intel/sandybridge: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I75f5d821e018932d3f10d84b7ebed362777fb17d Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32938 Reviewed-by: Patrick Georgi Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- .../intel/sandybridge/raminit_common.c | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/northbridge/intel/sandybridge/raminit_common.c b/src/northbridge/intel/sandybridge/raminit_common.c index 53f28c6cd66..4974173ef12 100644 --- a/src/northbridge/intel/sandybridge/raminit_common.c +++ b/src/northbridge/intel/sandybridge/raminit_common.c @@ -1452,9 +1452,8 @@ static void test_timC(ramctr_timing * ctrl, int channel, int slotrank) int lane; FOR_ALL_LANES { - volatile u32 tmp; MCHBAR32(0x4340 + 0x400 * channel + 4 * lane) = 0; - tmp = MCHBAR32(0x4140 + 0x400 * channel + 4 * lane); + MCHBAR32(0x4140 + 0x400 * channel + 4 * lane); } wait_428c(channel); @@ -2026,9 +2025,8 @@ int write_training(ramctr_timing * ctrl) MCHBAR32_OR(0x5030, 8); FOR_ALL_POPULATED_CHANNELS { - volatile u32 tmp; MCHBAR32_AND(0x4020 + 0x400 * channel, ~0x00200000); - tmp = MCHBAR32(0x428c + 0x400 * channel); + MCHBAR32(0x428c + 0x400 * channel); wait_428c(channel); /* DRAM command ZQCS */ @@ -2373,9 +2371,8 @@ static int discover_edges_real(ramctr_timing *ctrl, int channel, int slotrank, program_timings(ctrl, channel); FOR_ALL_LANES { - volatile u32 tmp; MCHBAR32(0x4340 + 0x400 * channel + 4 * lane) = 0; - tmp = MCHBAR32(0x400 * channel + 4 * lane + 0x4140); + MCHBAR32(0x400 * channel + 4 * lane + 0x4140); } wait_428c(channel); @@ -2454,8 +2451,7 @@ int discover_edges(ramctr_timing *ctrl) fill_pattern0(ctrl, channel, 0, 0); MCHBAR32(0x4288 + (channel << 10)) = 0; FOR_ALL_LANES { - volatile u32 tmp; - tmp = MCHBAR32(0x400 * channel + lane * 4 + 0x4140); + MCHBAR32(0x400 * channel + lane * 4 + 0x4140); } FOR_ALL_POPULATED_RANKS FOR_ALL_LANES { @@ -2655,10 +2651,9 @@ static int discover_edges_write_real(ramctr_timing *ctrl, int channel, program_timings(ctrl, channel); FOR_ALL_LANES { - volatile u32 tmp; MCHBAR32(0x4340 + 0x400 * channel + 4 * lane) = 0; - tmp = MCHBAR32(0x400 * channel + + MCHBAR32(0x400 * channel + 4 * lane + 0x4140); } wait_428c(channel); @@ -2703,8 +2698,7 @@ static int discover_edges_write_real(ramctr_timing *ctrl, int channel, wait_428c(channel); FOR_ALL_LANES { - volatile u32 tmp; - tmp = MCHBAR32(0x4340 + + MCHBAR32(0x4340 + 0x400 * channel + lane * 4); } From 19cb6c9980f86bb602c988f48dbf20413f2c27bf Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 20:26:02 +0200 Subject: [PATCH 538/588] sb/intel/fsp_rangeley: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia2bc9bb0f0ece5ae3a57662b54f3e7e78ce00b19 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32942 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Kyösti Mälkki --- src/southbridge/intel/fsp_rangeley/romstage.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/southbridge/intel/fsp_rangeley/romstage.c b/src/southbridge/intel/fsp_rangeley/romstage.c index 19e470e3098..2c2427eed1c 100644 --- a/src/southbridge/intel/fsp_rangeley/romstage.c +++ b/src/southbridge/intel/fsp_rangeley/romstage.c @@ -90,7 +90,6 @@ void main(FSP_INFO_HEADER *fsp_info_header) * Memory is setup and the stack is set by the FSP. */ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) { - int cbmem_was_initted; void *cbmem_hob_ptr; timestamp_add_now(TS_AFTER_INITRAM); @@ -113,7 +112,7 @@ void romstage_main_continue(EFI_STATUS status, void *hob_list_ptr) { /* Decode E0000 and F0000 segment to DRAM */ sideband_write(B_UNIT, BMISC, sideband_read(B_UNIT, BMISC) | (1 << 1) | (1 << 0)); - cbmem_was_initted = !cbmem_recovery(0); + cbmem_recovery(0); /* Save the HOB pointer in CBMEM to be used in ramstage*/ cbmem_hob_ptr = cbmem_add(CBMEM_ID_HOB_POINTER, sizeof(*hob_list_ptr)); From 1a7623bc1a76126c90c77ca27f27f2cba5ccae05 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 21:05:24 +0200 Subject: [PATCH 539/588] drivers/aspeed/ast2050: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Iedda92edf8c4eb7be037dcc0faa6fe8aa0c0754c Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32945 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons Reviewed-by: Kyösti Mälkki --- src/drivers/aspeed/ast2050/ast2050.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/drivers/aspeed/ast2050/ast2050.c b/src/drivers/aspeed/ast2050/ast2050.c index 631372d4289..21af5c7c80d 100644 --- a/src/drivers/aspeed/ast2050/ast2050.c +++ b/src/drivers/aspeed/ast2050/ast2050.c @@ -37,13 +37,12 @@ static void aspeed_ast2050_set_resources(struct device *dev) static void aspeed_ast2050_init(struct device *dev) { - u8 ret; struct drm_device drm_dev; drm_dev.pdev = dev; printk(BIOS_INFO, "ASpeed AST2050: initializing video device\n"); - ret = ast_driver_load(&drm_dev, 0); + ast_driver_load(&drm_dev, 0); /* Unlock extended configuration registers */ outb(0x80, 0x3d4); outb(0xa8, 0x3d5); From 156936b7711457157078ced41ea87529cb65aa2e Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Thu, 23 May 2019 23:16:11 +0200 Subject: [PATCH 540/588] nb/amd/amdmct/mct_ddr3/mct_d.c: Remove variable set but not used Change-Id: Icd9c0541d9006f4ebddcefff9d2355056af0c5c4 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32972 Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/northbridge/amd/amdmct/mct_ddr3/mct_d.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c index 42e91b6130c..5be456695eb 100644 --- a/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c +++ b/src/northbridge/amd/amdmct/mct_ddr3/mct_d.c @@ -3810,7 +3810,7 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, { u8 Node; u32 NextBase, BottomIO; - u8 _MemHoleRemap, DramHoleBase, DramHoleOffset; + u8 _MemHoleRemap, DramHoleBase; u32 HoleSize, DramSelBaseAddr; u32 val; @@ -3869,7 +3869,6 @@ static void HTMemMapInit_D(struct MCTStatStruc *pMCTstat, if ((DramSelBaseAddr > 0) && (DramSelBaseAddr < BottomIO)) base = DramSelBaseAddr; val = ((base + HoleSize) >> (24-8)) & 0xFF; - DramHoleOffset = val; val <<= 8; /* shl 16, rol 24 */ val |= DramHoleBase << 24; val |= 1 << DramHoleValid; From 4be1f8a2f6be29e7a9983d068c2356b7728f91d5 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 25 May 2019 19:38:03 +0200 Subject: [PATCH 541/588] sb/nvidia/mcp55: Remove variable set but not used Change-Id: Ic8f6c264aedbdab0eacb6a99a32cc90336e08d84 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/33011 Reviewed-by: Arthur Heymans Tested-by: build bot (Jenkins) --- src/southbridge/nvidia/mcp55/lpc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/southbridge/nvidia/mcp55/lpc.c b/src/southbridge/nvidia/mcp55/lpc.c index 1aef631ee6d..6416dd37b0b 100644 --- a/src/southbridge/nvidia/mcp55/lpc.c +++ b/src/southbridge/nvidia/mcp55/lpc.c @@ -100,10 +100,9 @@ static void lpc_init(struct device *dev) get_option(&on, "slow_cpu"); if (on) { u16 pm10_bar; - u32 dword; pm10_bar = (pci_read_config16(dev, 0x60) & 0xff00); outl(((on << 1) + 0x10), (pm10_bar + 0x10)); - dword = inl(pm10_bar + 0x10); + inl(pm10_bar + 0x10); on = 8 - on; printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n", (on * 12) + (on >> 1), (on & 1) * 5); From 99f1d5033591a28bf6b6a142adc24b285abc7870 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 25 May 2019 11:47:56 +0200 Subject: [PATCH 542/588] cpu/amd/family_10h-family_15h: Remove variable set but not used Change-Id: Ifc63ec5b588f8edcec5eda343ec9694332845045 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/33006 Reviewed-by: Angel Pons Reviewed-by: Marshall Dawson Tested-by: build bot (Jenkins) --- src/cpu/amd/family_10h-family_15h/init_cpus.c | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/src/cpu/amd/family_10h-family_15h/init_cpus.c b/src/cpu/amd/family_10h-family_15h/init_cpus.c index 310706ba953..d6a4725e2ef 100644 --- a/src/cpu/amd/family_10h-family_15h/init_cpus.c +++ b/src/cpu/amd/family_10h-family_15h/init_cpus.c @@ -986,7 +986,6 @@ void cpuSetAMDMSR(uint8_t node_id) uint8_t nvram; u32 platform; uint64_t revision; - uint8_t enable_c_states; uint8_t enable_cpb; printk(BIOS_DEBUG, "cpuSetAMDMSR "); @@ -1062,21 +1061,16 @@ void cpuSetAMDMSR(uint8_t node_id) } if (revision & (AMD_DR_Ex | AMD_FAM15_ALL)) { - enable_c_states = 0; if (CONFIG(HAVE_ACPI_TABLES)) - if (get_option(&nvram, "cpu_c_states") == CB_SUCCESS) - enable_c_states = !!nvram; - - if (enable_c_states) { - /* Set up the C-state base address */ - msr_t c_state_addr_msr; - c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS); - c_state_addr_msr.lo = ACPI_CPU_P_LVL2; /* CstateAddr = ACPI_CPU_P_LVL2 */ - wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr); - } + if ((get_option(&nvram, "cpu_c_states") == CB_SUCCESS) && + (nvram)) { + /* Set up the C-state base address */ + msr_t c_state_addr_msr; + c_state_addr_msr = rdmsr(MSR_CSTATE_ADDRESS); + c_state_addr_msr.lo = ACPI_CPU_P_LVL2; + wrmsr(MSR_CSTATE_ADDRESS, c_state_addr_msr); + } } -#else - enable_c_states = 0; #endif if (revision & AMD_FAM15_ALL) { From 95794693cb0270b63b9f209567313c2e052cce02 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 25 May 2019 13:34:51 +0200 Subject: [PATCH 543/588] sb/nvidia/ck804: Remove variable set but not used Change-Id: Ia8586e229e04fa11696a846653a3a54909ca7c1a Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/33007 Tested-by: build bot (Jenkins) Reviewed-by: Angel Pons --- src/southbridge/nvidia/ck804/ck804.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/southbridge/nvidia/ck804/ck804.c b/src/southbridge/nvidia/ck804/ck804.c index 59796e1add3..02d70a694da 100644 --- a/src/southbridge/nvidia/ck804/ck804.c +++ b/src/southbridge/nvidia/ck804/ck804.c @@ -58,9 +58,6 @@ static void ck804_enable(struct device *dev) u32 reg_old, reg; u8 byte; - struct southbridge_nvidia_ck804_config *conf; - conf = dev->chip_info; - if (dev->device == 0x0000) { vendorid = pci_read_config32(dev, PCI_VENDOR_ID); deviceid = (vendorid >> 16) & 0xffff; From 6b7171b32c59fd8aa4aea79f88e59a376ef00064 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Sat, 25 May 2019 20:21:18 +0200 Subject: [PATCH 544/588] nb/amd/pi/00630F01/northbridge.c: Remove variable set but not used Change-Id: Id5e762880ddfcb65872a50e8ffe10d86b3719b5d Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/33012 Tested-by: build bot (Jenkins) Reviewed-by: Marshall Dawson --- src/northbridge/amd/pi/00630F01/northbridge.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/northbridge/amd/pi/00630F01/northbridge.c b/src/northbridge/amd/pi/00630F01/northbridge.c index eca2f0c73d5..309a762840b 100644 --- a/src/northbridge/amd/pi/00630F01/northbridge.c +++ b/src/northbridge/amd/pi/00630F01/northbridge.c @@ -463,11 +463,9 @@ static unsigned long agesa_write_acpi_tables(struct device *device, acpi_header_t *ssdt; acpi_header_t *alib; acpi_header_t *ivrs; - acpi_hest_t *hest; /* HEST */ current = ALIGN(current, 8); - hest = (acpi_hest_t *)current; acpi_write_hest((void *)current, acpi_fill_hest); acpi_add_table(rsdp, (void *)current); current += ((acpi_header_t *)current)->length; @@ -680,7 +678,6 @@ static void domain_set_resources(struct device *dev) struct bus *link; #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info mem_hole; - u32 reset_memhole = 1; #endif pci_tolm = 0xffffffffUL; @@ -711,7 +708,6 @@ static void domain_set_resources(struct device *dev) // Use hole_basek as mmio_basek, and we don't need to reset hole anymore if ((mem_hole.node_id != -1) && (mmio_basek > mem_hole.hole_startk)) { mmio_basek = mem_hole.hole_startk; - reset_memhole = 0; } #endif From c6d503fb8198c4e2df3cabfa9a1c3fa142e7d7e4 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 29 May 2019 12:44:04 +0200 Subject: [PATCH 545/588] sb//nvidia/mcp55/mcp55.c: Remove variable set but not used Change-Id: I40cae58a7a7c9c3c20367541853001510a59e42b Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/33061 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/southbridge/nvidia/mcp55/mcp55.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/southbridge/nvidia/mcp55/mcp55.c b/src/southbridge/nvidia/mcp55/mcp55.c index f93ec92a701..bd49d9be5f3 100644 --- a/src/southbridge/nvidia/mcp55/mcp55.c +++ b/src/southbridge/nvidia/mcp55/mcp55.c @@ -59,8 +59,6 @@ void mcp55_enable(struct device *dev) u32 reg_old, reg; u8 byte; unsigned deviceid, vendorid, devfn; - struct southbridge_nvidia_mcp55_config *conf; - conf = dev->chip_info; int i; if (dev->device == 0x0000) { From 920bab553ef51ae33d2a87a1e1ff951149624d2c Mon Sep 17 00:00:00 2001 From: Marshall Dawson Date: Tue, 21 May 2019 17:56:34 -0600 Subject: [PATCH 546/588] soc/amd/stoneyridge: Fix alignment in iomap.h Change-Id: I79e8bc425d5db45abaeb655f86773f3bb1b2f8c4 Signed-off-by: Marshall Dawson Reviewed-on: https://review.coreboot.org/c/coreboot/+/32933 Tested-by: build bot (Jenkins) Reviewed-by: Furquan Shaikh --- src/soc/amd/stoneyridge/include/soc/iomap.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h index 77620431196..1caef3362fc 100644 --- a/src/soc/amd/stoneyridge/include/soc/iomap.h +++ b/src/soc/amd/stoneyridge/include/soc/iomap.h @@ -26,9 +26,9 @@ #include /* I2C fixed address */ -#define I2C_BASE_ADDRESS 0xfedc2000 -#define I2C_DEVICE_SIZE 0x00001000 -#define I2C_DEVICE_COUNT 4 +#define I2C_BASE_ADDRESS 0xfedc2000 +#define I2C_DEVICE_SIZE 0x00001000 +#define I2C_DEVICE_COUNT 4 #if CONFIG(HPET_ADDRESS_OVERRIDE) #error HPET address override is not allowed and must be fixed at 0xfed00000 From 4b55935173d2267635486d13016c7148f1e2955d Mon Sep 17 00:00:00 2001 From: Christian Walter Date: Tue, 28 May 2019 13:36:07 +0200 Subject: [PATCH 547/588] src/soc/intel/common/block/sgx: Add missing new lines Added missing new lines to Debug Output. Change-Id: I30f208a60661451bc0794c705113e8d19a68b0eb Signed-off-by: Christian Walter Reviewed-on: https://review.coreboot.org/c/coreboot/+/33035 Reviewed-by: Philipp Deppenwiese Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/sgx/sgx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/soc/intel/common/block/sgx/sgx.c b/src/soc/intel/common/block/sgx/sgx.c index 2d4cc53aa71..60714d9ce28 100644 --- a/src/soc/intel/common/block/sgx/sgx.c +++ b/src/soc/intel/common/block/sgx/sgx.c @@ -100,8 +100,8 @@ void prmrr_core_configure(void) return; } - printk(BIOS_INFO, "SGX: prmrr_base = 0x%llx", prmrr_base.data64); - printk(BIOS_INFO, "SGX: prmrr_mask = 0x%llx", prmrr_mask.data64); + printk(BIOS_INFO, "SGX: prmrr_base = 0x%llx\n", prmrr_base.data64); + printk(BIOS_INFO, "SGX: prmrr_mask = 0x%llx\n", prmrr_mask.data64); /* Program core PRMRR MSRs. * - Set cache writeback mem attrib in PRMRR base MSR From 10ed374d7d6555992a7434370130d813bfa3ad89 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Wed, 29 May 2019 14:57:06 +0200 Subject: [PATCH 548/588] sb/intel/i82801ix: Select SOUTHBRIDGE_INTEL_COMMON_SPI This allows to use the CONFIG_CONSOLE_SPI_FLASH. Change-Id: I563c69ce6337d46380f889f42633e858ac207916 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33064 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/southbridge/intel/i82801ix/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/src/southbridge/intel/i82801ix/Kconfig b/src/southbridge/intel/i82801ix/Kconfig index a2697739a86..5edb8a1426d 100644 --- a/src/southbridge/intel/i82801ix/Kconfig +++ b/src/southbridge/intel/i82801ix/Kconfig @@ -18,6 +18,7 @@ config SOUTHBRIDGE_INTEL_I82801IX bool select SOUTHBRIDGE_INTEL_COMMON select SOUTHBRIDGE_INTEL_COMMON_SMBUS + select SOUTHBRIDGE_INTEL_COMMON_SPI if !BOARD_EMULATION_QEMU_X86_Q35 select SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ select IOAPIC select HAVE_USBDEBUG From 9995418166bc4074de2a99aa50e74f8a88196c39 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Wed, 29 May 2019 23:33:06 +0200 Subject: [PATCH 549/588] soc/intel: Replace UART_BASE() and friends with a Kconfig Re-add the Kconfig CONSOLE_UART_BASE_ADDRESS. It was lost by accident on APL at least. It is used outside of soc/intel/ scope, e.g. to con- figure SeaBIOS. As we only ever configure a single UART for the coreboot console, we don't need different addresses for each possible UART. Which saves us a lot of code. Change-Id: I28e1d98aa37a6acb57b98b8882fc4fa131d5d309 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/33098 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Rudolph --- src/soc/intel/apollolake/Kconfig | 5 +++++ src/soc/intel/apollolake/include/soc/iomap.h | 8 -------- src/soc/intel/cannonlake/Kconfig | 5 +++++ src/soc/intel/cannonlake/include/soc/iomap.h | 8 -------- src/soc/intel/common/acpi/acpi_debug.asl | 2 +- src/soc/intel/common/block/uart/uart.c | 9 ++++----- src/soc/intel/icelake/Kconfig | 5 +++++ src/soc/intel/icelake/include/soc/iomap.h | 8 -------- src/soc/intel/skylake/Kconfig | 5 +++++ src/soc/intel/skylake/include/soc/iomap.h | 7 ------- 10 files changed, 25 insertions(+), 37 deletions(-) diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 217d1eab24f..1f819eab063 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -361,6 +361,11 @@ config CPU_BCLK_MHZ int default 100 +config CONSOLE_UART_BASE_ADDRESS + hex + default 0xddffc000 + depends on INTEL_LPSS_UART_FOR_CONSOLE + config APL_SKIP_SET_POWER_LIMITS bool default n diff --git a/src/soc/intel/apollolake/include/soc/iomap.h b/src/soc/intel/apollolake/include/soc/iomap.h index 8e2986d8b70..4b823652844 100644 --- a/src/soc/intel/apollolake/include/soc/iomap.h +++ b/src/soc/intel/apollolake/include/soc/iomap.h @@ -58,12 +58,4 @@ #define EARLY_I2C_BASE_ADDRESS 0xfe020000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) -#define UART_BASE_SIZE 0x1000 - -#define UART_BASE_0_ADDRESS 0xddffc000 -/* UART BARs are 4KB in size */ -#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_BASE_SIZE * (x))) -#define UART_BASE(x) UART_BASE_0_ADDR(x) - #endif /* _SOC_APOLLOLAKE_IOMAP_H_ */ diff --git a/src/soc/intel/cannonlake/Kconfig b/src/soc/intel/cannonlake/Kconfig index e524275b8fe..76906b25480 100644 --- a/src/soc/intel/cannonlake/Kconfig +++ b/src/soc/intel/cannonlake/Kconfig @@ -223,6 +223,11 @@ config SOC_INTEL_I2C_DEV_MAX default 4 if SOC_INTEL_CANNONLAKE_PCH_H default 6 +config CONSOLE_UART_BASE_ADDRESS + hex + default 0xfe032000 + depends on INTEL_LPSS_UART_FOR_CONSOLE + # Clock divider parameters for 115200 baud rate config SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL hex diff --git a/src/soc/intel/cannonlake/include/soc/iomap.h b/src/soc/intel/cannonlake/include/soc/iomap.h index 100bd11356f..1ebaf3f7b68 100644 --- a/src/soc/intel/cannonlake/include/soc/iomap.h +++ b/src/soc/intel/cannonlake/include/soc/iomap.h @@ -29,14 +29,6 @@ #define PCH_TRACE_HUB_BASE_ADDRESS 0xfc800000 #define PCH_TRACE_HUB_BASE_SIZE 0x00800000 -#define UART_BASE_SIZE 0x1000 - -#define UART_BASE_0_ADDRESS 0xfe032000 -/* Both UART BAR 0 and 1 are 4KB in size */ -#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_BASE_SIZE * (x))) -#define UART_BASE(x) UART_BASE_0_ADDR(x) - #define EARLY_I2C_BASE_ADDRESS 0xfe040000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) diff --git a/src/soc/intel/common/acpi/acpi_debug.asl b/src/soc/intel/common/acpi/acpi_debug.asl index 6c52bbfd775..0c0be154e6d 100644 --- a/src/soc/intel/common/acpi/acpi_debug.asl +++ b/src/soc/intel/common/acpi/acpi_debug.asl @@ -59,7 +59,7 @@ Method (APRT, 1, Serialized) #if CONFIG(DRIVERS_UART_8250MEM_32) OperationRegion (UBAR, SystemMemory, - UART_BASE_0_ADDR(CONFIG_UART_FOR_CONSOLE), 24) + CONFIG_CONSOLE_UART_BASE_ADDRESS, 24) Field (UBAR, AnyAcc, NoLock, Preserve) { TDR, 8, /* Transmit Data Register BAR + 0x000 */ diff --git a/src/soc/intel/common/block/uart/uart.c b/src/soc/intel/common/block/uart/uart.c index 84ba1ee0f22..9d820ffd7ef 100644 --- a/src/soc/intel/common/block/uart/uart.c +++ b/src/soc/intel/common/block/uart/uart.c @@ -47,7 +47,7 @@ static void uart_lpss_init(uintptr_t baseaddr) uintptr_t uart_platform_base(int idx) { if (idx == CONFIG_UART_FOR_CONSOLE) - return UART_BASE_0_ADDR(CONFIG_UART_FOR_CONSOLE); + return CONFIG_CONSOLE_UART_BASE_ADDRESS; return 0; } #endif @@ -137,8 +137,7 @@ static void uart_configure_gpio_pads(void) void uart_bootblock_init(void) { /* Program UART BAR0, command, reset and clock register */ - uart_common_init(uart_get_device(), - UART_BASE(CONFIG_UART_FOR_CONSOLE)); + uart_common_init(uart_get_device(), CONFIG_CONSOLE_UART_BASE_ADDRESS); /* Configure the 2 pads per UART. */ uart_configure_gpio_pads(); @@ -155,8 +154,8 @@ static void uart_read_resources(struct device *dev) uart_is_debug_controller(dev)) { struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0); /* Need to set the base and size for the resource allocator. */ - res->base = UART_BASE(CONFIG_UART_FOR_CONSOLE); - res->size = UART_BASE_SIZE; + res->base = CONFIG_CONSOLE_UART_BASE_ADDRESS; + res->size = 0x1000; res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; } diff --git a/src/soc/intel/icelake/Kconfig b/src/soc/intel/icelake/Kconfig index a4b46baab5c..052e37dadbb 100644 --- a/src/soc/intel/icelake/Kconfig +++ b/src/soc/intel/icelake/Kconfig @@ -138,6 +138,11 @@ config SOC_INTEL_UART_DEV_MAX int default 3 +config CONSOLE_UART_BASE_ADDRESS + hex + default 0xfe032000 + depends on INTEL_LPSS_UART_FOR_CONSOLE + # Clock divider parameters for 115200 baud rate config SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL hex diff --git a/src/soc/intel/icelake/include/soc/iomap.h b/src/soc/intel/icelake/include/soc/iomap.h index 7c42b577301..218b8bfa60b 100644 --- a/src/soc/intel/icelake/include/soc/iomap.h +++ b/src/soc/intel/icelake/include/soc/iomap.h @@ -28,14 +28,6 @@ #define PCH_TRACE_HUB_BASE_ADDRESS 0xfc800000 #define PCH_TRACE_HUB_BASE_SIZE 0x00800000 -#define UART_BASE_SIZE 0x1000 - -#define UART_BASE_0_ADDRESS 0xfe032000 -/* Both UART BAR 0 and 1 are 4KB in size */ -#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_BASE_SIZE * (x))) -#define UART_BASE(x) UART_BASE_0_ADDR(x) - #define EARLY_I2C_BASE_ADDRESS 0xfe040000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) diff --git a/src/soc/intel/skylake/Kconfig b/src/soc/intel/skylake/Kconfig index fcfe2b65910..626b5f80f08 100644 --- a/src/soc/intel/skylake/Kconfig +++ b/src/soc/intel/skylake/Kconfig @@ -289,6 +289,11 @@ config CPU_BCLK_MHZ int default 100 +config CONSOLE_UART_BASE_ADDRESS + hex + default 0xfe030000 + depends on INTEL_LPSS_UART_FOR_CONSOLE + # Clock divider parameters for 115200 baud rate config SOC_INTEL_COMMON_LPSS_UART_CLK_M_VAL hex diff --git a/src/soc/intel/skylake/include/soc/iomap.h b/src/soc/intel/skylake/include/soc/iomap.h index 628a272a546..c73d766953a 100644 --- a/src/soc/intel/skylake/include/soc/iomap.h +++ b/src/soc/intel/skylake/include/soc/iomap.h @@ -25,13 +25,6 @@ #define PCH_PRESERVED_BASE_ADDRESS 0xfc800000 #define PCH_PRESERVED_BASE_SIZE 0x02000000 -#define UART_BASE_SIZE 0x1000 -#define UART_BASE_0_ADDRESS 0xfe030000 -/* Both UART BAR 0 and 1 are 4KB in size */ -#define UART_BASE_0_ADDR(x) (UART_BASE_0_ADDRESS + (2 * \ - UART_BASE_SIZE * (x))) -#define UART_BASE(x) UART_BASE_0_ADDR(x) - #define EARLY_I2C_BASE_ADDRESS 0xfe040000 #define EARLY_I2C_BASE(x) (EARLY_I2C_BASE_ADDRESS + (0x1000 * (x))) From 317cbd6f02e5f49bbc64dd0de0082c313c77c6b1 Mon Sep 17 00:00:00 2001 From: John Zhao Date: Fri, 31 May 2019 10:44:46 -0700 Subject: [PATCH 550/588] src/soc/intel: Avoid NULL pointer dereference Coverity detects pointer mem_info as NULL_RETURNS. Add sanity check for mem_info to prevent NULL pointer dereference. BUG=CID 1401394 TEST=Built and boot up to kernel. Change-Id: I9d78ab38b8b2dd3734e0143acfd88d9093f16ce6 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/33152 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- src/soc/intel/broadwell/romstage/raminit.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c index fc8b7c6984a..c13761df3a4 100644 --- a/src/soc/intel/broadwell/romstage/raminit.c +++ b/src/soc/intel/broadwell/romstage/raminit.c @@ -122,6 +122,12 @@ void raminit(struct pei_data *pei_data) printk(BIOS_DEBUG, "create cbmem for dimm information\n"); mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info)); + + if (!mem_info) { + printk(BIOS_ERR, "Error! Failed to add mem_info to cbmem\n"); + return; + } + memset(mem_info, 0, sizeof(*mem_info)); /* Translate pei_memory_info struct data into memory_info struct */ mem_info->dimm_cnt = pei_data->meminfo.dimm_cnt; From 8a2056cac4995dbb69b7e2f2b2a0ca0c5657d5ad Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Fri, 24 May 2019 12:14:52 +0200 Subject: [PATCH 551/588] mainboard/intel/saddlebrook: Remove unused functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setting up the SIO serial console is done in the bootblock. Change-Id: Ideaf8f3dc0ee067e96d3fb5046071551c6d45329 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32985 Reviewed-by: Christian Walter Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/mainboard/intel/saddlebrook/romstage.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/mainboard/intel/saddlebrook/romstage.c b/src/mainboard/intel/saddlebrook/romstage.c index 82b85fd700f..45f39d46e27 100644 --- a/src/mainboard/intel/saddlebrook/romstage.c +++ b/src/mainboard/intel/saddlebrook/romstage.c @@ -23,15 +23,7 @@ #include #include "spd/spd.h" #include -#include -#include -#define SERIAL_DEV PNP_DEV(0x2e, NCT6776_SP1) - -void car_mainboard_pre_console_init(void) -{ - nuvoton_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); -} void mainboard_memory_init_params( struct romstage_params *params, From ef1ab4d6d47c87d976c8186d5d8651853e3c92a9 Mon Sep 17 00:00:00 2001 From: Subrata Banik Date: Fri, 31 May 2019 16:09:56 +0530 Subject: [PATCH 552/588] arch/riscv/Kconfig: Make correct default value for CONFIG_ARCH_RISCV_M Change-Id: Ib9329904060cab48d527de1b1ccdab5b6fe71b99 Signed-off-by: Subrata Banik Reviewed-on: https://review.coreboot.org/c/coreboot/+/33144 Reviewed-by: Martin Roth Tested-by: build bot (Jenkins) --- src/arch/riscv/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/arch/riscv/Kconfig b/src/arch/riscv/Kconfig index 9d325af7594..25a398068a0 100644 --- a/src/arch/riscv/Kconfig +++ b/src/arch/riscv/Kconfig @@ -24,8 +24,8 @@ config ARCH_RISCV_M # one implementation that will not have it due # to security concerns. bool - default n if ARCH_RISCV_M_DISABLED - default y + default y if ARCH_RISCV && !ARCH_RISCV_M_DISABLED + default n config ARCH_RISCV_S # S (supervisor) mode is for kernels. It is optional. From b2709ae0aed724278dfaa3d0af1d68e8fe18cbb1 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Thu, 30 May 2019 17:24:12 -0700 Subject: [PATCH 553/588] soc/intel/cannonlake: Do not read SPD again if index hasn't changed With the recent refactoring of memory configuration in CB:32513 ("soc/intel/cannonlake: Support different SPD read type for each slot"), meminit_cbfs_spd_index ends up reading SPD from CBFS for each slot. However, for mainboards that use the same SPD index for each slot this is unneccessary. This change adds a check to see if spd_data_ptr is not NULL and current spd index is the same as the last call to decide if SPD read from CBFS should be skipped. TEST=Verified that SPD gets read only once on hatch. Change-Id: I91963b55cea534c92207b2cd9f0caa96df8f222b Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/33137 Reviewed-by: Paul Menzel Reviewed-by: Aaron Durbin Reviewed-by: Tim Wawrzynczak Reviewed-by: Philip Chen Tested-by: build bot (Jenkins) --- src/soc/intel/cannonlake/cnl_memcfg_init.c | 31 +++++++++++++++------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/soc/intel/cannonlake/cnl_memcfg_init.c b/src/soc/intel/cannonlake/cnl_memcfg_init.c index 4ebd9978ae2..d3e5e837fde 100644 --- a/src/soc/intel/cannonlake/cnl_memcfg_init.c +++ b/src/soc/intel/cannonlake/cnl_memcfg_init.c @@ -91,18 +91,29 @@ static void meminit_spd_data(FSP_M_CONFIG *mem_cfg, uint8_t mem_slot, static void meminit_cbfs_spd_index(FSP_M_CONFIG *mem_cfg, int spd_index, uint8_t mem_slot) { - size_t spd_data_len; - uintptr_t spd_data_ptr; - struct region_device spd_rdev; + static size_t spd_data_len; + static uintptr_t spd_data_ptr; + static int last_spd_index; assert(mem_slot < NUM_DIMM_SLOT); - printk(BIOS_DEBUG, "SPD INDEX = %d\n", spd_index); - if (get_spd_cbfs_rdev(&spd_rdev, spd_index) < 0) - die("spd.bin not found or incorrect index\n"); - spd_data_len = region_device_sz(&spd_rdev); - /* Memory leak is ok since we have memory mapped boot media */ - assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); - spd_data_ptr = (uintptr_t)rdev_mmap_full(&spd_rdev); + + if ((spd_data_ptr == 0) || (last_spd_index != spd_index)) { + struct region_device spd_rdev; + + printk(BIOS_DEBUG, "SPD INDEX = %d\n", spd_index); + + if (get_spd_cbfs_rdev(&spd_rdev, spd_index) < 0) + die("spd.bin not found or incorrect index\n"); + + spd_data_len = region_device_sz(&spd_rdev); + + /* Memory leak is ok since we have memory mapped boot media */ + assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED)); + + spd_data_ptr = (uintptr_t)rdev_mmap_full(&spd_rdev); + last_spd_index = spd_index; + } + meminit_spd_data(mem_cfg, mem_slot, spd_data_len, spd_data_ptr); } From 3cae9afbf91d7b164a033968350f8f60b84301b9 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Fri, 5 Apr 2019 10:00:18 +0200 Subject: [PATCH 554/588] vendorcode/eltan: Add vendor code for measured and verified boot This patch contains the general files for the vendorcode/eltan that has been uploaded recently: - Add eltan directory to vendorcode. - Add documentation about the support in the vendorcode directories. - Add the Makefile.inc and Kconfig for the vendorcode/eltan and vendorcode/eltan/security. BUG=N/A TEST=Created verified binary and verify logging on Portwell PQ-M107 Change-Id: Ic1d5a21d40b6a31886777e8e9fe7b28c860f1a80 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/30218 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- Documentation/vendorcode/eltan/index.md | 8 +++++ Documentation/vendorcode/eltan/security.md | 39 ++++++++++++++++++++++ src/vendorcode/Makefile.inc | 1 + src/vendorcode/eltan/Kconfig | 17 ++++++++++ src/vendorcode/eltan/Makefile.inc | 16 +++++++++ src/vendorcode/eltan/security/Kconfig | 16 +++++++++ src/vendorcode/eltan/security/Makefile.inc | 30 +++++++++++++++++ 7 files changed, 127 insertions(+) create mode 100644 Documentation/vendorcode/eltan/index.md create mode 100644 Documentation/vendorcode/eltan/security.md create mode 100644 src/vendorcode/eltan/Kconfig create mode 100644 src/vendorcode/eltan/Makefile.inc create mode 100644 src/vendorcode/eltan/security/Kconfig create mode 100644 src/vendorcode/eltan/security/Makefile.inc diff --git a/Documentation/vendorcode/eltan/index.md b/Documentation/vendorcode/eltan/index.md new file mode 100644 index 00000000000..4484798a23c --- /dev/null +++ b/Documentation/vendorcode/eltan/index.md @@ -0,0 +1,8 @@ +# Eltan vendorcode-specific documentation + +This section contains documentation about coreboot on Eltan specific +vendorcode. + +## Sections + +- [Security](security.md) diff --git a/Documentation/vendorcode/eltan/security.md b/Documentation/vendorcode/eltan/security.md new file mode 100644 index 00000000000..04537df23ca --- /dev/null +++ b/Documentation/vendorcode/eltan/security.md @@ -0,0 +1,39 @@ +# Eltan Security + +## Security +This code enables measured boot and verified boot support. +Verified boot is available in coreboot, but based on ChromeOS. This vendorcode +uses a small encryption library and leave much more space in flash for the +payload. + +## Hashing Library +The library suppports SHA-1, SHA-256 and SHA-512. The required routines of +`3rdparty/vboot/firmware/2lib` are used. + +## Measured boot +measured boot support will use TPM2 device if available. The items specified +in `mb_log_list[]` will be measured. + +## Verified boot +verified boot support will use TPM2 device if available. The items specified +in the next table will be verified: +* `bootblock_verify_list[]` +* `verify_item_t romstage_verify_list[]` +* `ram_stage_additional_list[]` +* `ramstage_verify_list[]` +* `payload_verify_list[]` +* `oprom_verify_list[]` + +## Enabling support + +* Measured boot can be enabled using **CONFIG_MBOOT** +* Create mb_log_list table with list of item to measure +* Create tables bootblock_verify_list[], verify_item_t romstage_verify_list[], + ram_stage_additional_list[], ramstage_verify_list[], payload_verify_list[], + oprom_verify_list[] +* Verified boot can be enabled using **CONFIG_VERIFIED_BOOT** +* Added Kconfig values for verbose console output + +## Debugging + +You can enable verbose console output in *menuconfig*. diff --git a/src/vendorcode/Makefile.inc b/src/vendorcode/Makefile.inc index 522d4150e4f..8ccb0d0ee7a 100644 --- a/src/vendorcode/Makefile.inc +++ b/src/vendorcode/Makefile.inc @@ -3,3 +3,4 @@ subdirs-y += google subdirs-y += intel subdirs-y += siemens subdirs-y += cavium +subdirs-y += eltan diff --git a/src/vendorcode/eltan/Kconfig b/src/vendorcode/eltan/Kconfig new file mode 100644 index 00000000000..731dd2cea3a --- /dev/null +++ b/src/vendorcode/eltan/Kconfig @@ -0,0 +1,17 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2014-2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +source src/vendorcode/eltan/security/mboot/Kconfig +source src/vendorcode/eltan/security/verified_boot/Kconfig diff --git a/src/vendorcode/eltan/Makefile.inc b/src/vendorcode/eltan/Makefile.inc new file mode 100644 index 00000000000..1f6a4065cfb --- /dev/null +++ b/src/vendorcode/eltan/Makefile.inc @@ -0,0 +1,16 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2018 Eltan B.V. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +subdirs-y += security diff --git a/src/vendorcode/eltan/security/Kconfig b/src/vendorcode/eltan/security/Kconfig new file mode 100644 index 00000000000..2af58080da0 --- /dev/null +++ b/src/vendorcode/eltan/security/Kconfig @@ -0,0 +1,16 @@ +## This file is part of the coreboot project. +## +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +source src/vendorcode/eltan/security/mboot/Kconfig +source src/vendorcode/eltan/security/verified_boot/Kconfig diff --git a/src/vendorcode/eltan/security/Makefile.inc b/src/vendorcode/eltan/security/Makefile.inc new file mode 100644 index 00000000000..26b324ba586 --- /dev/null +++ b/src/vendorcode/eltan/security/Makefile.inc @@ -0,0 +1,30 @@ +## This file is part of the coreboot project. +## +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +subdirs-y += lib +subdirs-y += verified_boot +subdirs-y += mboot + +ifeq ($(CONFIG_MBOOT), y) +CPPFLAGS_common += -I$(src)/vendorcode/eltan/security/mboot +CPPFLAGS_common += -I$(src)/vendorcode/eltan/security/include +endif + +ifeq ($(CONFIG_VERIFIED_BOOT), y) +CPPFLAGS_common += -I$(src)/vendorcode/eltan/security/verified_boot +endif + +ifeq ($(CONFIG_TPM2),y) +CPPFLAGS_common += -I$(src)/security/include +endif From a99ed13e3397bc536012120aab8cadb827913863 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Mon, 3 Jun 2019 19:02:31 -0700 Subject: [PATCH 555/588] libpayload/i8042/keyboard: Fix return value check for keyboard_cmd CB:32951 ("libpayload: Reset PS/2 keyboard") added a call to reset keyboard and check the return value of keyboard_cmd() to compare against I8042_KBCMD_ACK. However, keyboard_cmd() already checks for ACK and returns 1 or 0 based on whether ACK is received. This change fixes the check introduced by CB:32951 to compare against 0 just like the other checks for keyboard_cmd(). Additionally, it adds error messages for all failed commands in keyboard_init() to make the prints consistent in case of failure. BUG=b:134366527 TEST=Verified that logs do not contain "ERROR: Keyboard reset failed" anymore. Change-Id: Idcadaae12e0a44e404a1d98c6deb633d97058203 Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/33185 Tested-by: build bot (Jenkins) Reviewed-by: Frank Wu Reviewed-by: Paul Menzel --- payloads/libpayload/drivers/i8042/keyboard.c | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/payloads/libpayload/drivers/i8042/keyboard.c b/payloads/libpayload/drivers/i8042/keyboard.c index 12255fb7f81..240385ce6dc 100644 --- a/payloads/libpayload/drivers/i8042/keyboard.c +++ b/payloads/libpayload/drivers/i8042/keyboard.c @@ -172,7 +172,7 @@ static unsigned char keyboard_cmd(unsigned char cmd) { i8042_write_data(cmd); - return i8042_wait_read_ps2() == 0xfa; + return i8042_wait_read_ps2() == I8042_KBCMD_ACK; } int keyboard_havechar(void) @@ -319,32 +319,40 @@ void keyboard_init(void) /* Reset keyboard and self test (keyboard side) */ ret = keyboard_cmd(I8042_KBCMD_RESET); - if (ret != I8042_KBCMD_ACK) { - printf("ERROR: Keyboard reset failed ACK: 0x%x\n", ret); + if (!ret) { + printf("ERROR: Keyboard reset failed!\n"); return; } /* Set scancode set 1 */ ret = keyboard_cmd(I8042_KBCMD_SET_SCANCODE); - if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) + if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) { + printf("ERROR: Keyboard set scancode failed!\n"); return; + } ret = keyboard_cmd(I8042_SCANCODE_SET_1); - if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) + if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) { + printf("ERROR: Keyboard scancode set#1 failed!\n"); return; + } /* * Set default parameters. * Fix for broken QEMU ps/2 make scancodes. */ ret = keyboard_cmd(0xf6); - if (!ret) + if (!ret) { + printf("ERROR: Keyboard set default params failed!\n"); return; + } /* Enable scanning */ ret = keyboard_cmd(I8042_KBCMD_EN); - if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) + if (!ret && !CONFIG(LP_PC_KEYBOARD_IGNORE_INIT_FAILURE)) { + printf("ERROR: Keyboard enable scanning failed!\n"); return; + } console_add_input_driver(&cons); } From fca7c4d614eeee1b040cfeba37599b32d0ad55f1 Mon Sep 17 00:00:00 2001 From: Furquan Shaikh Date: Sat, 1 Jun 2019 14:44:56 -0700 Subject: [PATCH 556/588] mb/google/hatch: Enable LTR for PCIe ports Enable LTR for NVMe and WiFi PCIe ports so that they can use ASPM L1.2 BUG=b:134195632 TEST=Verified L1 substate with lspci on hatch: Before: L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2- ASPM_L1.1+ After: L1SubCtl1: PCI-PM_L1.2+ PCI-PM_L1.1+ ASPM_L1.2+ ASPM_L1.1+ Change-Id: I7fce60897b78dde12747ac7fb857c988d16118ab Signed-off-by: Furquan Shaikh Reviewed-on: https://review.coreboot.org/c/coreboot/+/33161 Reviewed-by: Patrick Georgi Reviewed-by: Paul Menzel Reviewed-by: Paul Fagerburg Tested-by: build bot (Jenkins) --- src/mainboard/google/hatch/variants/baseboard/devicetree.cb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb index 9d10cac41b6..1123d537341 100644 --- a/src/mainboard/google/hatch/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/hatch/variants/baseboard/devicetree.cb @@ -72,6 +72,7 @@ chip soc/intel/cannonlake # Enable Root port 9(x4) for NVMe. register "PcieRpEnable[8]" = "1" + register "PcieRpLtrEnable[8]" = "1" # RP 9 uses CLK SRC 1 register "PcieClkSrcUsage[1]" = "8" # ClkReq-to-ClkSrc mapping for CLK SRC 1 @@ -79,6 +80,7 @@ chip soc/intel/cannonlake # PCIe port 14 for M.2 E-key WLAN register "PcieRpEnable[13]" = "1" + register "PcieRpLtrEnable[13]" = "1" # RP 14 uses CLK SRC 3 register "PcieClkSrcUsage[3]" = "13" register "PcieClkSrcClkReq[3]" = "3" From 9636a106d43453976addb39253cf70bc65ea1224 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 17:36:43 -0700 Subject: [PATCH 557/588] device_tree: Switch allocations to xzalloc() The FIT code is already using xzalloc() everywhere, and that's the only real consumer of device tree code right now. Chances are if you're trying to unflatten an FDT and it doesn't fit into the heap you're pretty much screwed anyway, so all the OOM handling feels a bit unnecessary (and some functions will just silently fail because they don't have a return value, which is bad). Let's just switch this all to die on failed allocations. Change-Id: I738f24d550a776653b2becd3d4f7d4d2cb3cc048 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32861 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/device_tree.c | 55 ++++++++----------------------------------- src/lib/fit.c | 2 +- 2 files changed, 11 insertions(+), 46 deletions(-) diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 8dbc510c10b..bb40eee2316 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -153,24 +154,6 @@ int fdt_skip_node(const void *blob, uint32_t start_offset) /* * Functions to turn a flattened tree into an unflattened one. */ -static struct device_tree_node *alloc_node(void) -{ - struct device_tree_node *buf = malloc(sizeof(struct device_tree_node)); - if (!buf) - return NULL; - memset(buf, 0, sizeof(*buf)); - return buf; -} - -static struct device_tree_property *alloc_prop(void) -{ - struct device_tree_property *buf = - malloc(sizeof(struct device_tree_property)); - if (!buf) - return NULL; - memset(buf, 0, sizeof(*buf)); - return buf; -} static int fdt_unflatten_node(const void *blob, uint32_t start_offset, struct device_tree_node **new_node) @@ -185,18 +168,14 @@ static int fdt_unflatten_node(const void *blob, uint32_t start_offset, return 0; offset += size; - struct device_tree_node *node = alloc_node(); + struct device_tree_node *node = xzalloc(sizeof(*node)); *new_node = node; - if (!node) - return 0; node->name = name; struct fdt_property fprop; last = &node->properties; while ((size = fdt_next_property(blob, offset, &fprop))) { - struct device_tree_property *prop = alloc_prop(); - if (!prop) - return 0; + struct device_tree_property *prop = xzalloc(sizeof(*prop)); prop->prop = fprop; list_insert_after(&prop->list_node, last); @@ -227,10 +206,7 @@ static int fdt_unflatten_map_entry(const void *blob, uint32_t offset, if (!size) return 0; - struct device_tree_reserve_map_entry *entry = malloc(sizeof(*entry)); - if (!entry) - return 0; - memset(entry, 0, sizeof(*entry)); + struct device_tree_reserve_map_entry *entry = xzalloc(sizeof(*entry)); *new = entry; entry->start = start; entry->size = size; @@ -240,11 +216,8 @@ static int fdt_unflatten_map_entry(const void *blob, uint32_t offset, struct device_tree *fdt_unflatten(const void *blob) { - struct device_tree *tree = malloc(sizeof(*tree)); + struct device_tree *tree = xzalloc(sizeof(*tree)); const struct fdt_header *header = (const struct fdt_header *)blob; - if (!tree) - return NULL; - memset(tree, 0, sizeof(*tree)); tree->header = header; uint32_t struct_offset = be32toh(header->structure_offset); @@ -534,7 +507,7 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, if (!create) return NULL; - found = alloc_node(); + found = malloc(sizeof(*found)); if (!found) return NULL; found->name = strdup(*path); @@ -804,9 +777,7 @@ void dt_add_bin_prop(struct device_tree_node *node, const char *name, } } - prop = alloc_prop(); - if (!prop) - return; + prop = xzalloc(sizeof(*prop)); list_insert_after(&prop->list_node, &node->properties); prop->prop.name = name; prop->prop.data = data; @@ -878,9 +849,7 @@ void dt_add_string_prop(struct device_tree_node *node, const char *name, */ void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val) { - u32 *val_ptr = malloc(sizeof(val)); - if (!val_ptr) - return; + u32 *val_ptr = xmalloc(sizeof(val)); *val_ptr = htobe32(val); dt_add_bin_prop(node, name, val_ptr, sizeof(*val_ptr)); } @@ -894,9 +863,7 @@ void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val) */ void dt_add_u64_prop(struct device_tree_node *node, const char *name, u64 val) { - u64 *val_ptr = malloc(sizeof(val)); - if (!val_ptr) - return; + u64 *val_ptr = xmalloc(sizeof(val)); *val_ptr = htobe64(val); dt_add_bin_prop(node, name, val_ptr, sizeof(*val_ptr)); } @@ -916,9 +883,7 @@ void dt_add_reg_prop(struct device_tree_node *node, u64 *addrs, u64 *sizes, { int i; size_t length = (addr_cells + size_cells) * sizeof(u32) * count; - u8 *data = malloc(length); - if (!data) - return; + u8 *data = xmalloc(length); u8 *cur = data; for (i = 0; i < count; i++) { diff --git a/src/lib/fit.c b/src/lib/fit.c index 3aad806f2e4..d15641db9a7 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -27,7 +27,7 @@ #include #include #include -#include +#include static struct list_node image_nodes; static struct list_node config_nodes; From 73eaec81689662cf5c1cd6ac5de1152e19b0c14d Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 17:58:07 -0700 Subject: [PATCH 558/588] device_tree: Add version checks This patch adds a few more sanity checks to the FDT header parsing to make sure that our code can support the version that is passed in. This patch was adapted from depthcharge's http://crosreview.com/1536384 Change-Id: I06c112f540213c8db7c2455c2e8a4e8e4f337b78 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32862 Reviewed-by: Hung-Te Lin Reviewed-by: Paul Menzel Tested-by: build bot (Jenkins) --- src/include/device_tree.h | 3 ++- src/lib/device_tree.c | 18 ++++++++++++++++++ src/lib/fit.c | 8 +++----- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/include/device_tree.h b/src/include/device_tree.h index 14be8322c69..96902b893b7 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -33,7 +33,7 @@ struct fdt_header { uint32_t reserve_map_offset; uint32_t version; - uint32_t last_compatible_version; + uint32_t last_comp_version; uint32_t boot_cpuid_phys; @@ -42,6 +42,7 @@ struct fdt_header { }; #define FDT_HEADER_MAGIC 0xd00dfeed +#define FDT_SUPPORTED_VERSION 17 #define FDT_TOKEN_BEGIN_NODE 1 #define FDT_TOKEN_END_NODE 2 #define FDT_TOKEN_PROPERTY 3 diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index bb40eee2316..7a3128efcf7 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -220,6 +220,24 @@ struct device_tree *fdt_unflatten(const void *blob) const struct fdt_header *header = (const struct fdt_header *)blob; tree->header = header; + uint32_t magic = be32toh(header->magic); + uint32_t version = be32toh(header->version); + uint32_t last_comp_version = be32toh(header->last_comp_version); + + if (magic != FDT_HEADER_MAGIC) { + printk(BIOS_DEBUG, "Invalid device tree magic %#.8x!\n", magic); + return NULL; + } + if (last_comp_version > FDT_SUPPORTED_VERSION) { + printk(BIOS_DEBUG, "Unsupported device tree version %u(>=%u)\n", + version, last_comp_version); + return NULL; + } + if (version > FDT_SUPPORTED_VERSION) + printk(BIOS_DEBUG, + "NOTE: FDT version %u too new, should add support!\n", + version); + uint32_t struct_offset = be32toh(header->structure_offset); uint32_t strings_offset = be32toh(header->strings_offset); uint32_t reserve_offset = be32toh(header->reserve_map_offset); diff --git a/src/lib/fit.c b/src/lib/fit.c index d15641db9a7..c98ba2f8020 100644 --- a/src/lib/fit.c +++ b/src/lib/fit.c @@ -423,19 +423,17 @@ static void fit_update_compat(const void *fdt_blob, struct fit_config_node *fit_load(void *fit) { - struct fdt_header *header = (struct fdt_header *)fit; struct fit_image_node *image; struct fit_config_node *config; struct compat_string_entry *compat_node; printk(BIOS_DEBUG, "FIT: Loading FIT from %p\n", fit); - if (be32toh(header->magic) != FDT_HEADER_MAGIC) { - printk(BIOS_ERR, "FIT: Bad header magic value 0x%08x.\n", - be32toh(header->magic)); + struct device_tree *tree = fdt_unflatten(fit); + if (!tree) { + printk(BIOS_ERR, "ERROR: Failed to unflatten FIT image!\n"); return NULL; } - struct device_tree *tree = fdt_unflatten(fit); const char *default_config_name = NULL; struct fit_config_node *default_config = NULL; From 6702b68a7966d584e310bf7a99f4a1dc57f2f56f Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 18:13:53 -0700 Subject: [PATCH 559/588] device_tree: Add phandle caching and lookups This patch caches phandles when unflattening the device tree, so we don't have to look up the phandle property again every time we're trying to find the phandle of a node. This is especially important when supporting phandle lookups, which are also added. In addition we keep track of the highest phandle in the whole tree, which will be important for applying overlays later. With this, dt_get_phandle(node) becomes obsolete because the phandle is already available as a member variable in the node. This patch was adapted from depthcharge's http://crosreview.com/1536385 Change-Id: I9cbd67d1d13e57c25d068b3db18bb75c709d7ebe Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32863 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/include/device_tree.h | 8 +++-- src/lib/device_tree.c | 59 ++++++++++++++++++++++--------------- src/soc/cavium/cn81xx/soc.c | 2 +- 3 files changed, 42 insertions(+), 27 deletions(-) diff --git a/src/include/device_tree.h b/src/include/device_tree.h index 96902b893b7..8280dad077c 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -47,6 +47,7 @@ struct fdt_header { #define FDT_TOKEN_END_NODE 2 #define FDT_TOKEN_PROPERTY 3 #define FDT_TOKEN_END 9 +#define FDT_PHANDLE_ILLEGAL 0xdeadbeef struct fdt_property { @@ -71,6 +72,8 @@ struct device_tree_property struct device_tree_node { const char *name; + uint32_t phandle; + // List of struct device_tree_property-s. struct list_node properties; // List of struct device_tree_nodes. @@ -91,6 +94,7 @@ struct device_tree { const void *header; uint32_t header_size; + uint32_t max_phandle; struct list_node reserve_map; @@ -136,6 +140,8 @@ void dt_read_cell_props(const struct device_tree_node *node, u32 *addrcp, // represented as an array of strings. struct device_tree_node *dt_find_node(struct device_tree_node *parent, const char **path, u32 *addrcp, u32 *sizecp, int create); +struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, + uint32_t phandle); // Look up or create a node relative to a parent node, through its path // represented as a string of '/' separated node names. struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, const char *path, @@ -150,8 +156,6 @@ struct device_tree_node *dt_find_next_compat_child(struct device_tree_node *pare // Look up a node relative to a parent node, through its property value. struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, const char *name, void *data, size_t size); -// Return the phandle -uint32_t dt_get_phandle(const struct device_tree_node *node); // Write src into *dest as a 'length'-byte big-endian integer. void dt_write_int(u8 *dest, u64 src, size_t length); // Delete a property diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 7a3128efcf7..44eca4e2a8e 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -66,6 +66,12 @@ int fdt_node_name(const void *blob, uint32_t offset, const char **name) return ALIGN_UP(strlen((char *)ptr) + 1, sizeof(uint32_t)) + 4; } +static int dt_prop_is_phandle(struct device_tree_property *prop) +{ + return !(strcmp("phandle", prop->prop.name) && + strcmp("linux,phandle", prop->prop.name)); +} + /* @@ -156,6 +162,7 @@ int fdt_skip_node(const void *blob, uint32_t start_offset) */ static int fdt_unflatten_node(const void *blob, uint32_t start_offset, + struct device_tree *tree, struct device_tree_node **new_node) { struct list_node *last; @@ -178,6 +185,12 @@ static int fdt_unflatten_node(const void *blob, uint32_t start_offset, struct device_tree_property *prop = xzalloc(sizeof(*prop)); prop->prop = fprop; + if (dt_prop_is_phandle(prop)) { + node->phandle = be32dec(prop->prop.data); + if (node->phandle > tree->max_phandle) + tree->max_phandle = node->phandle; + } + list_insert_after(&prop->list_node, last); last = &prop->list_node; @@ -186,7 +199,7 @@ static int fdt_unflatten_node(const void *blob, uint32_t start_offset, struct device_tree_node *child; last = &node->children; - while ((size = fdt_unflatten_node(blob, offset, &child))) { + while ((size = fdt_unflatten_node(blob, offset, tree, &child))) { list_insert_after(&child->list_node, last); last = &child->list_node; @@ -260,7 +273,7 @@ struct device_tree *fdt_unflatten(const void *blob) offset += size; } - fdt_unflatten_node(blob, struct_offset, &tree->root); + fdt_unflatten_node(blob, struct_offset, tree, &tree->root); return tree; } @@ -590,6 +603,26 @@ struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, return node; } +struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, + uint32_t phandle) +{ + if (!root) + return NULL; + + if (root->phandle == phandle) + return root; + + struct device_tree_node *node; + struct device_tree_node *result; + list_for_each(node, root->children, list_node) { + result = dt_find_node_by_phandle(node, phandle); + if (result) + return result; + } + + return NULL; +} + /* * Check if given node is compatible. * @@ -719,28 +752,6 @@ struct device_tree_node *dt_find_prop_value(struct device_tree_node *parent, return NULL; } -/** - * Find the phandle of a node. - * - * @param node Pointer to node containing the phandle - * @return Zero on error, the phandle on success - */ -uint32_t dt_get_phandle(const struct device_tree_node *node) -{ - const uint32_t *phandle; - size_t len; - - dt_find_bin_prop(node, "phandle", (const void **)&phandle, &len); - if (phandle != NULL && len == sizeof(*phandle)) - return be32_to_cpu(*phandle); - - dt_find_bin_prop(node, "linux,phandle", (const void **)&phandle, &len); - if (phandle != NULL && len == sizeof(*phandle)) - return be32_to_cpu(*phandle); - - return 0; -} - /* * Write an arbitrary sized big-endian integer into a pointer. * diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c index 98166b056f7..05007493df4 100644 --- a/src/soc/cavium/cn81xx/soc.c +++ b/src/soc/cavium/cn81xx/soc.c @@ -234,7 +234,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, continue; } /* Store the phandle */ - phandle = dt_get_phandle(dt_node); + phandle = dt_node->phandle; printk(BIOS_INFO, "%s: Removing node %s\n", __func__, path); list_remove(&dt_node->list_node); From f36d53c6539ec9e221a5005f00a56960f791a81f Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 18:23:34 -0700 Subject: [PATCH 560/588] device_tree: Drop sub-node path lookup from dt_find_node_by_path() Besides looking up a node with an absolute path dt_find_node_by_path() currently also supports finding a sub-node of a non-root node. All callers of the function pass the root node though, so it seems there is no real need for this functionality. Also it is planned to support DT path names with aliases, which would become messy in combination with the lookup from a sub-node. Change the interface of dt_find_node_by_path() to receive the DT tree object instead of a parent node and adapt all callers accordingly. This patch was adapted from depthcharge's http://crosreview.com/1252769 Change-Id: Iff56be4da2461ae73a7301dcaa315758d2a8c999 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32864 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/include/device_tree.h | 6 +++--- src/lib/device_tree.c | 12 ++++++------ src/soc/cavium/cn81xx/soc.c | 10 +++++----- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/include/device_tree.h b/src/include/device_tree.h index 8280dad077c..6eaeacd6f02 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -142,10 +142,10 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, const cha u32 *addrcp, u32 *sizecp, int create); struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, uint32_t phandle); -// Look up or create a node relative to a parent node, through its path +// Look up or create a node in the tree, through its path // represented as a string of '/' separated node names. -struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, const char *path, - u32 *addrcp, u32 *sizecp, int create); +struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, + const char *path, u32 *addrcp, u32 *sizecp, int create); // Look up a node relative to a parent node, through its compatible string. struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible); // Look up the next child of a parent node, through its compatible string. It diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 44eca4e2a8e..3e1dd3580c2 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -552,9 +552,9 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, } /* - * Find a node from a string device tree path, relative to a parent node. + * Find a node in the tree from a string device tree path. * - * @param parent The node from which to start the relative path lookup. + * @param tree The device tree to search. * @param path A string representing a path in the device tree, with * nodes separated by '/'. Example: "soc/firmware/coreboot" * @param addrcp Pointer that will be updated with any #address-cells @@ -567,7 +567,7 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, * It is the caller responsibility to provide the correct path string, namely * not starting or ending with a '/', and not having "//" anywhere in it. */ -struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, +struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, const char *path, u32 *addrcp, u32 *sizecp, int create) { @@ -595,7 +595,7 @@ struct device_tree_node *dt_find_node_by_path(struct device_tree_node *parent, if (!next_slash) { path_array[i] = NULL; - node = dt_find_node(parent, path_array, + node = dt_find_node(tree->root, path_array, addrcp, sizecp, create); } @@ -965,7 +965,7 @@ int dt_set_bin_prop_by_path(struct device_tree *tree, const char *path, *prop_name++ = '\0'; /* Separate path from the property name. */ - dt_node = dt_find_node_by_path(tree->root, path_copy, NULL, + dt_node = dt_find_node_by_path(tree, path_copy, NULL, NULL, create); if (!dt_node) { @@ -995,7 +995,7 @@ struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree) struct device_tree_node *reserved; u32 addr = 0, size = 0; - reserved = dt_find_node_by_path(tree->root, "reserved-memory", &addr, + reserved = dt_find_node_by_path(tree, "reserved-memory", &addr, &size, 1); if (!reserved) return NULL; diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c index 05007493df4..20542e5fa2d 100644 --- a/src/soc/cavium/cn81xx/soc.c +++ b/src/soc/cavium/cn81xx/soc.c @@ -185,7 +185,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, size_t i; /* Set the sclk clock rate. */ - dt_node = dt_find_node_by_path(tree->root, "soc@0/sclk", NULL, NULL, 0); + dt_node = dt_find_node_by_path(tree, "soc@0/sclk", NULL, NULL, 0); if (dt_node) { const u32 freq = thunderx_get_io_clock(); printk(BIOS_INFO, "%s: Set SCLK to %u Hz\n", __func__, freq); @@ -195,7 +195,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, __func__); /* Set refclkuaa clock rate. */ - dt_node = dt_find_node_by_path(tree->root, "soc@0/refclkuaa", NULL, + dt_node = dt_find_node_by_path(tree, "soc@0/refclkuaa", NULL, NULL, 0); if (dt_node) { const u32 freq = uart_platform_refclk(); @@ -212,7 +212,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, const uint64_t addr = UAAx_PF_BAR0(i); /* Remove the node */ snprintf(path, sizeof(path), "soc@0/serial@%llx", addr); - dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0); + dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node || uart_is_enabled(i)) { printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path); continue; @@ -228,7 +228,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, const uint64_t addr = PEM_PEMX_PF_BAR0(i); /* Remove the node */ snprintf(path, sizeof(path), "soc@0/pci@%llx", addr); - dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0); + dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node || bdk_pcie_is_running(0, i)) { printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path); continue; @@ -240,7 +240,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, /* Remove phandle to non existing nodes */ snprintf(path, sizeof(path), "soc@0/smmu0@%llx", SMMU_PF_BAR0); - dt_node = dt_find_node_by_path(tree->root, path, NULL, NULL, 0); + dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node) { printk(BIOS_ERR, "%s: SMMU entry not found\n", __func__); From fbec63d15f761e01c934078570acbef779e707ba Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 3 May 2019 18:29:28 -0700 Subject: [PATCH 561/588] device_tree: Have absolute paths start with '/' Currently DT paths are *not* expected to start with '/'. This is not what the spec says (see Devicetree Specification v0.2, 2.2.3 Path Names) and also not what is done by Linux. Change dt_find_node_by_path() to expect paths to start with '/' and add a leading '/' to all DT path strings. Besides the compatibility with the spec this change is also needed to support aliases in the future. This patch was adapted from depthcharge's http://crosreview.com/1252770 Change-Id: Ibdf59ccbb4ead38c6193b630642fd1f1e847dd89 Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32865 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/device_tree.c | 8 ++++---- src/soc/cavium/cn81xx/soc.c | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 3e1dd3580c2..e26021e9ee2 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -556,7 +556,7 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, * * @param tree The device tree to search. * @param path A string representing a path in the device tree, with - * nodes separated by '/'. Example: "soc/firmware/coreboot" + * nodes separated by '/'. Example: "/firmware/coreboot" * @param addrcp Pointer that will be updated with any #address-cells * value found in the path. May be NULL to ignore. * @param sizecp Pointer that will be updated with any #size-cells @@ -565,13 +565,13 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, * @return The found/created node, or NULL. * * It is the caller responsibility to provide the correct path string, namely - * not starting or ending with a '/', and not having "//" anywhere in it. + * starting with a '/', not ending in a '/' and not having "//" anywhere in it. */ struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, const char *path, u32 *addrcp, u32 *sizecp, int create) { - char *dup_path = strdup(path); + char *dup_path = strdup(&path[1]); /* remove leading '/' */ /* Hopefully enough depth for any node. */ const char *path_array[15]; int i; @@ -995,7 +995,7 @@ struct device_tree_node *dt_init_reserved_memory_node(struct device_tree *tree) struct device_tree_node *reserved; u32 addr = 0, size = 0; - reserved = dt_find_node_by_path(tree, "reserved-memory", &addr, + reserved = dt_find_node_by_path(tree, "/reserved-memory", &addr, &size, 1); if (!reserved) return NULL; diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c index 20542e5fa2d..efe7d6d2043 100644 --- a/src/soc/cavium/cn81xx/soc.c +++ b/src/soc/cavium/cn81xx/soc.c @@ -185,7 +185,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, size_t i; /* Set the sclk clock rate. */ - dt_node = dt_find_node_by_path(tree, "soc@0/sclk", NULL, NULL, 0); + dt_node = dt_find_node_by_path(tree, "/soc@0/sclk", NULL, NULL, 0); if (dt_node) { const u32 freq = thunderx_get_io_clock(); printk(BIOS_INFO, "%s: Set SCLK to %u Hz\n", __func__, freq); @@ -195,7 +195,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, __func__); /* Set refclkuaa clock rate. */ - dt_node = dt_find_node_by_path(tree, "soc@0/refclkuaa", NULL, + dt_node = dt_find_node_by_path(tree, "/soc@0/refclkuaa", NULL, NULL, 0); if (dt_node) { const u32 freq = uart_platform_refclk(); @@ -211,7 +211,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, char path[32]; const uint64_t addr = UAAx_PF_BAR0(i); /* Remove the node */ - snprintf(path, sizeof(path), "soc@0/serial@%llx", addr); + snprintf(path, sizeof(path), "/soc@0/serial@%llx", addr); dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node || uart_is_enabled(i)) { printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path); @@ -227,7 +227,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, u32 phandle = 0; const uint64_t addr = PEM_PEMX_PF_BAR0(i); /* Remove the node */ - snprintf(path, sizeof(path), "soc@0/pci@%llx", addr); + snprintf(path, sizeof(path), "/soc@0/pci@%llx", addr); dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node || bdk_pcie_is_running(0, i)) { printk(BIOS_INFO, "%s: ignoring %s\n", __func__, path); @@ -239,7 +239,7 @@ static int dt_platform_fixup(struct device_tree_fixup *fixup, list_remove(&dt_node->list_node); /* Remove phandle to non existing nodes */ - snprintf(path, sizeof(path), "soc@0/smmu0@%llx", SMMU_PF_BAR0); + snprintf(path, sizeof(path), "/soc@0/smmu0@%llx", SMMU_PF_BAR0); dt_node = dt_find_node_by_path(tree, path, NULL, NULL, 0); if (!dt_node) { printk(BIOS_ERR, "%s: SMMU entry not found\n", From 6d5695fac53f52e1f389f420b5428e92de5b8c9c Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 6 May 2019 19:23:28 -0700 Subject: [PATCH 562/588] device_tree: Add support for aliases This patch adds support to lookup nodes via the "/aliases" mechanism in device trees. This may be required for overlay support (don't quite remember tbh) and is also just a generally useful feature. It was adapted from depthcharge's http://crosreview.com/1249703 and http://crosreview.com/1542702. Change-Id: I1289ab2f02c4877a2d0111040384827e2b48a34a Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32866 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/include/device_tree.h | 3 ++ src/lib/device_tree.c | 86 +++++++++++++++++++++++++++++++++------ 2 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/include/device_tree.h b/src/include/device_tree.h index 6eaeacd6f02..e3723c86ac9 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -146,6 +146,9 @@ struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, // represented as a string of '/' separated node names. struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, const char *path, u32 *addrcp, u32 *sizecp, int create); +// Look up a node through an alias. +struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree, + const char *alias); // Look up a node relative to a parent node, through its compatible string. struct device_tree_node *dt_find_compat(struct device_tree_node *parent, const char *compatible); // Look up the next child of a parent node, through its compatible string. It diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index e26021e9ee2..bbcd7c06f6c 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -564,27 +564,65 @@ struct device_tree_node *dt_find_node(struct device_tree_node *parent, * @param create 1: Create node(s) if not found. 0: Return NULL instead. * @return The found/created node, or NULL. * - * It is the caller responsibility to provide the correct path string, namely - * starting with a '/', not ending in a '/' and not having "//" anywhere in it. - */ + * It is the caller responsibility to provide a path string that doesn't end + * with a '/' and doesn't contain any "//". If the path does not start with a + * '/', the first segment is interpreted as an alias. */ struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, const char *path, u32 *addrcp, u32 *sizecp, int create) { - char *dup_path = strdup(&path[1]); /* remove leading '/' */ + char *sub_path; + char *duped_str; + struct device_tree_node *parent; + char *next_slash; /* Hopefully enough depth for any node. */ const char *path_array[15]; int i; - char *next_slash; struct device_tree_node *node = NULL; - if (!dup_path) - return NULL; + if (path[0] == '/') { // regular path + if (path[1] == '\0') { // special case: "/" is root node + dt_read_cell_props(tree->root, addrcp, sizecp); + return tree->root; + } - next_slash = dup_path; - path_array[0] = dup_path; - for (i = 1; i < (ARRAY_SIZE(path_array) - 1); i++) { + sub_path = duped_str = strdup(&path[1]); + if (!sub_path) + return NULL; + + parent = tree->root; + } else { // alias + char *alias; + + alias = duped_str = strdup(path); + if (!alias) + return NULL; + + sub_path = strchr(alias, '/'); + if (sub_path) + *sub_path = '\0'; + + parent = dt_find_node_by_alias(tree, alias); + if (!parent) { + printk(BIOS_DEBUG, + "Could not find node '%s', alias '%s' does not exist\n", + path, alias); + free(duped_str); + return NULL; + } + + if (!sub_path) { + // it's just the alias, no sub-path + free(duped_str); + return parent; + } + sub_path++; + } + + next_slash = sub_path; + path_array[0] = sub_path; + for (i = 1; i < (ARRAY_SIZE(path_array) - 1); i++) { next_slash = strchr(next_slash, '/'); if (!next_slash) break; @@ -595,14 +633,38 @@ struct device_tree_node *dt_find_node_by_path(struct device_tree *tree, if (!next_slash) { path_array[i] = NULL; - node = dt_find_node(tree->root, path_array, + node = dt_find_node(parent, path_array, addrcp, sizecp, create); } - free(dup_path); + free(duped_str); return node; } +/* + * Find a node from an alias + * + * @param tree The device tree. + * @param alias The alias name. + * @return The found node, or NULL. + */ +struct device_tree_node *dt_find_node_by_alias(struct device_tree *tree, + const char *alias) +{ + struct device_tree_node *node; + const char *alias_path; + + node = dt_find_node_by_path(tree, "/aliases", NULL, NULL, 0); + if (!node) + return NULL; + + alias_path = dt_find_string_prop(node, alias); + if (!alias_path) + return NULL; + + return dt_find_node_by_path(tree, alias_path, NULL, NULL, 0); +} + struct device_tree_node *dt_find_node_by_phandle(struct device_tree_node *root, uint32_t phandle) { From 0d74653bd46a360466cf5050ea0c102fc11cdc2d Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 6 May 2019 19:35:56 -0700 Subject: [PATCH 563/588] device_tree: Match debug output format to dtc -O dts output This patch updates the device tree dumping functions (not compiled by default but available for debugging) to output properties and nodes in a format similar to .dts files that is very close to what dtc outputs when you decompile a .dtb with it. This makes it easier to match device tree dumps from coreboot with device tree dumps generated by other device tree tooling. This patch was adapted from depthcharge's http://crosreview.com/1536386 Change-Id: Ib40e50d906aff05473a70c4fc9b124d63232558c Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32867 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/lib/device_tree.c | 49 +++++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index bbcd7c06f6c..3c4bd244628 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -80,21 +80,36 @@ static int dt_prop_is_phandle(struct device_tree_property *prop) static void print_indent(int depth) { - while (depth--) - printk(BIOS_DEBUG, " "); + printk(BIOS_DEBUG, "%*s", depth * 8, ""); } static void print_property(const struct fdt_property *prop, int depth) { + int is_string = prop->size > 0 && + ((char *)prop->data)[prop->size - 1] == '\0'; + + if (is_string) + for (const char *c = prop->data; *c != '\0'; c++) + if (!isprint(*c)) + is_string = 0; + print_indent(depth); - printk(BIOS_DEBUG, "prop \"%s\" (%d bytes).\n", prop->name, prop->size); - print_indent(depth + 1); - for (int i = 0; i < MIN(25, prop->size); i++) { - printk(BIOS_DEBUG, "%02x ", ((uint8_t *)prop->data)[i]); + if (is_string) { + printk(BIOS_DEBUG, "%s = \"%s\";\n", + prop->name, (const char *)prop->data); + } else { + printk(BIOS_DEBUG, "%s = < ", prop->name); + for (int i = 0; i < MIN(128, prop->size); i += 4) { + uint32_t val = 0; + for (int j = 0; j < MIN(4, prop->size - i); j++) + val |= ((uint8_t *)prop->data)[i + j] << + (24 - j * 8); + printk(BIOS_DEBUG, "%#.2x ", val); + } + if (prop->size > 128) + printk(BIOS_DEBUG, "..."); + printk(BIOS_DEBUG, ">;\n"); } - if (prop->size > 25) - printk(BIOS_DEBUG, "..."); - printk(BIOS_DEBUG, "\n"); } static int print_flat_node(const void *blob, uint32_t start_offset, int depth) @@ -109,7 +124,7 @@ static int print_flat_node(const void *blob, uint32_t start_offset, int depth) offset += size; print_indent(depth); - printk(BIOS_DEBUG, "name = %s\n", name); + printk(BIOS_DEBUG, "%s {\n", name); struct fdt_property prop; while ((size = fdt_next_property(blob, offset, &prop))) { @@ -118,9 +133,14 @@ static int print_flat_node(const void *blob, uint32_t start_offset, int depth) offset += size; } + printk(BIOS_DEBUG, "\n"); // empty line between props and nodes + while ((size = print_flat_node(blob, offset, depth + 1))) offset += size; + print_indent(depth); + printk(BIOS_DEBUG, "}\n"); + return offset - start_offset + sizeof(uint32_t); } @@ -458,15 +478,22 @@ void dt_flatten(const struct device_tree *tree, void *start_dest) static void print_node(const struct device_tree_node *node, int depth) { print_indent(depth); - printk(BIOS_DEBUG, "name = %s\n", node->name); + if (depth == 0) // root node has no name, print a starting slash + printk(BIOS_DEBUG, "/"); + printk(BIOS_DEBUG, "%s {\n", node->name); struct device_tree_property *prop; list_for_each(prop, node->properties, list_node) print_property(&prop->prop, depth + 1); + printk(BIOS_DEBUG, "\n"); // empty line between props and nodes + struct device_tree_node *child; list_for_each(child, node->children, list_node) print_node(child, depth + 1); + + print_indent(depth); + printk(BIOS_DEBUG, "};\n"); } void dt_print_node(const struct device_tree_node *node) From 0e9116f0a12c0a2a8142978458d3266e5e9aacdc Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Mon, 13 May 2019 17:30:31 -0700 Subject: [PATCH 564/588] device_tree: Make FDT property data non-const FDT property data should not be const -- sometimes we need to update it, for example when fixing up phandles in an overlay. On the other hand it's occasionally desirable to put a string constant in there without having to strdup() it all the time... let's just live with the tiny implicit assumption that the data we'd want to modify (phandle references, mostly) will never be added from string constants, and put a cast in dt_add_string_prop(). Change-Id: Ifac103fcff0520cc427ab9a2aa141c65e12507ac Signed-off-by: Julius Werner Reviewed-on: https://review.coreboot.org/c/coreboot/+/32868 Reviewed-by: Hung-Te Lin Tested-by: build bot (Jenkins) --- src/include/device_tree.h | 4 ++-- src/lib/device_tree.c | 4 ++-- src/soc/cavium/cn81xx/soc.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/include/device_tree.h b/src/include/device_tree.h index e3723c86ac9..d9d9613f968 100644 --- a/src/include/device_tree.h +++ b/src/include/device_tree.h @@ -52,7 +52,7 @@ struct fdt_header { struct fdt_property { const char *name; - const void *data; + void *data; uint32_t size; }; @@ -165,7 +165,7 @@ void dt_write_int(u8 *dest, u64 src, size_t length); void dt_delete_prop(struct device_tree_node *node, const char *name); // Add different kinds of properties to a node, or update existing ones. void dt_add_bin_prop(struct device_tree_node *node, const char *name, - const void *data, size_t size); + void *data, size_t size); void dt_add_string_prop(struct device_tree_node *node, const char *name, const char *str); void dt_add_u32_prop(struct device_tree_node *node, const char *name, u32 val); diff --git a/src/lib/device_tree.c b/src/lib/device_tree.c index 3c4bd244628..a5021ca8fd5 100644 --- a/src/lib/device_tree.c +++ b/src/lib/device_tree.c @@ -883,7 +883,7 @@ void dt_delete_prop(struct device_tree_node *node, const char *name) * @param size The size of data in bytes. */ void dt_add_bin_prop(struct device_tree_node *node, const char *name, - const void *data, size_t size) + void *data, size_t size) { struct device_tree_property *prop; @@ -955,7 +955,7 @@ void dt_find_bin_prop(const struct device_tree_node *node, const char *name, void dt_add_string_prop(struct device_tree_node *node, const char *name, const char *str) { - dt_add_bin_prop(node, name, str, strlen(str) + 1); + dt_add_bin_prop(node, name, (char *)str, strlen(str) + 1); } /* diff --git a/src/soc/cavium/cn81xx/soc.c b/src/soc/cavium/cn81xx/soc.c index efe7d6d2043..f1e11d335b4 100644 --- a/src/soc/cavium/cn81xx/soc.c +++ b/src/soc/cavium/cn81xx/soc.c @@ -149,7 +149,7 @@ static void dt_platform_fixup_mac(struct device_tree_node *node) if (*localmac) return; if (used_mac < num_free_mac_addresses) { - const u64 genmac = next_free_mac_address + used_mac; + u64 genmac = next_free_mac_address + used_mac; dt_add_bin_prop(node, name, &genmac, 6); used_mac++; return; From 59b6542bbc5aa7215aa68eca098c047924e5e118 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 23 May 2019 15:24:30 +0200 Subject: [PATCH 565/588] soc/intel/braswell: Use common cpu/intel/car code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The code in cpu/intel/car/romstage.c Does most of the things like setting up timestamps, stack guards, entering postcar. A functional difference is that the FSP header is searched for twice instead of passed from the CAR entry to the C code. When using C_ENVIRONMENT_BOOTBLOCK this needs to be done anyway (or a special linker symbol kept across multiple stages is needed, which is likely not worth the speedup). Change-Id: I0f03e5a808f00157fdd807b104417a54e4bde7b2 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/32963 Tested-by: build bot (Jenkins) Reviewed-by: Kyösti Mälkki --- src/drivers/intel/fsp1_1/cache_as_ram.inc | 46 ++++++------ src/drivers/intel/fsp1_1/car.c | 75 ++++---------------- src/drivers/intel/fsp1_1/include/fsp/car.h | 11 --- src/soc/intel/braswell/romstage/Makefile.inc | 1 + 4 files changed, 36 insertions(+), 97 deletions(-) diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc index f50641e3aec..493dbc8d04c 100644 --- a/src/drivers/intel/fsp1_1/cache_as_ram.inc +++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc @@ -31,11 +31,11 @@ * EBX, EDI, ESI, EBP, MM0, MM1 * * Shift values to release MM2. - * mm0 -> edi: BIST value + * mm0 -> ebx: BIST value * mm1 -> mm0: low 32-bits of TSC value * mm2 -> mm1: high 32-bits of TSC value */ - movd %mm0, %edi + movd %mm0, %ebx movd %mm1, %eax movd %eax, %mm0 movd %mm2, %eax @@ -79,8 +79,8 @@ find_fsp_ret: /* * BIST value is zero * eax: TempRamInitApi address + * ebx: BIST value * ebp: FSP_INFO_HEADER address - * edi: BIST value * esi: Not used * mm0: low 32-bits of TSC value * mm1: high 32-bits of TSC value @@ -90,13 +90,12 @@ find_fsp_ret: jmp *%eax CAR_init_done: - addl $4, %esp /* * ebp: FSP_INFO_HEADER address + * ebx: BIST value * ecx: Temp RAM base * edx: Temp RAM top - * edi: BIST value * mm0: low 32-bits of TSC value * mm1: high 32-bits of TSC value */ @@ -109,43 +108,42 @@ CAR_init_done: /* * ebp: FSP_INFO_HEADER address + * ebx: BIST value * ecx: Temp RAM base * edx: Temp RAM top - * edi: BIST value * esp: Top of stack in temp RAM * mm0: low 32-bits of TSC value * mm1: high 32-bits of TSC value */ - /* Create cache_as_ram_params on stack */ - pushl %edx /* bootloader CAR end */ - pushl %ecx /* bootloader CAR begin */ - pushl %ebp /* FSP_INFO_HEADER */ - pushl %edi /* bist */ - movd %mm1, %eax - pushl %eax /* tsc[63:32] */ - movd %mm0, %eax - pushl %eax /* tsc[31:0] */ - pushl %esp /* pointer to cache_as_ram_params */ - - /* Save FSP_INFO_HEADER location in ebx */ - mov %ebp, %ebx - /* coreboot assumes stack/heap region will be zero */ cld movl %ecx, %edi neg %ecx - /* Only clear up to current stack value. */ - add %esp, %ecx + /* Clear up to Temp Ram top. */ + add %edx, %ecx shrl $2, %ecx xorl %eax, %eax rep stosl + /* Need to align stack to 16 bytes at call instruction. Account for + the pushes below. */ + andl $0xfffffff0, %esp + subl $4, %esp + + /* Push BIST and initial timestamp on the stack */ + pushl %ebx /* bist */ + movd %mm1, %eax + pushl %eax /* tsc[63:32] */ + movd %mm0, %eax + pushl %eax /* tsc[31:0] */ + before_romstage: post_code(0x2A) - /* Call cache_as_ram_main(struct cache_as_ram_params *) */ - call cache_as_ram_main + /* Call bootblock_c_entry_bist(uint64_t base_timestamp, uint32_t bist) + in cpu/intel/car/romstage.c */ + call bootblock_c_entry_bist movb $0x69, %ah jmp .Lhlt diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 41a02f33b95..10f9524650a 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -94,74 +94,25 @@ void platform_enter_postcar(void) run_postcar_phase(&pcf); } -/* This is the romstage C entry for platforms without - CONFIG_C_ENVIRONMENT_BOOTBLOCK */ -asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params) -{ - int i; - const int num_guards = 4; - const u32 stack_guard = 0xdeadbeef; - u32 *stack_base; - u32 size; - - /* Size of unallocated CAR. */ - size = _car_region_end - _car_relocatable_data_end; - size = ALIGN_DOWN(size, 16); - - stack_base = (u32 *)(_car_region_end - size); - - for (i = 0; i < num_guards; i++) - stack_base[i] = stack_guard; - - /* Initialize timestamp book keeping only once. */ - timestamp_init(car_params->tsc); - - /* Call into pre-console init code then initialize console. */ - car_soc_pre_console_init(); - car_mainboard_pre_console_init(); - console_init(); - - printk(BIOS_DEBUG, "FSP TempRamInit successful\n"); - - printk(BIOS_SPEW, "bist: 0x%08x\n", car_params->bist); - printk(BIOS_SPEW, "tsc: 0x%016llx\n", car_params->tsc); - - display_mtrrs(); - - if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE - || car_params->bootloader_car_end != (CONFIG_DCACHE_RAM_BASE - + CONFIG_DCACHE_RAM_SIZE)) { - printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n", - CONFIG_DCACHE_RAM_BASE, - CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE, - (long)car_params->bootloader_car_start, - (long)car_params->bootloader_car_end); - } - - car_soc_post_console_init(); - car_mainboard_post_console_init(); - - cache_as_ram_stage_main(car_params->fih); - - /* Check the stack. */ - for (i = 0; i < num_guards; i++) { - if (stack_base[i] == stack_guard) - continue; - printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n"); - } - - /* we don't return here */ - platform_enter_postcar(); -} - -/* This is the entry for platforms with CONFIG_C_ENVIRONMENT_BOOTBLOCK - called from cpu/intel/car/romstage.c */ +/* This is the romstage entry called from cpu/intel/car/romstage.c */ void mainboard_romstage_entry(unsigned long bist) { /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram * is still enabled. We can directly access work buffer here. */ struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin"); + if (!CONFIG(C_ENVIRONMENT_BOOTBLOCK)) { + /* Call into pre-console init code then initialize console. */ + car_soc_pre_console_init(); + car_mainboard_pre_console_init(); + console_init(); + + display_mtrrs(); + + car_soc_post_console_init(); + car_mainboard_post_console_init(); + } + if (prog_locate(&fsp)) die_with_post_code(POST_INVALID_CBFS, "Unable to locate fsp.bin"); diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h index c05139231c8..8d7a6836722 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/car.h +++ b/src/drivers/intel/fsp1_1/include/fsp/car.h @@ -20,17 +20,6 @@ #include #include -/* cache-as-ram support for FSP 1.1. */ -struct cache_as_ram_params { - uint64_t tsc; - uint32_t bist; - FSP_INFO_HEADER *fih; - uintptr_t bootloader_car_start; - uintptr_t bootloader_car_end; -}; - -/* Entry points from the cache-as-ram assembly code. */ -asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params); /* Per stage calls from the above two functions. The void * return from * cache_as_ram_stage_main() is the stack pointer to use in RAM after * exiting cache-as-ram mode. */ diff --git a/src/soc/intel/braswell/romstage/Makefile.inc b/src/soc/intel/braswell/romstage/Makefile.inc index 15de8220412..3d3e407a293 100644 --- a/src/soc/intel/braswell/romstage/Makefile.inc +++ b/src/soc/intel/braswell/romstage/Makefile.inc @@ -1,2 +1,3 @@ +romstage-y += ../../../../cpu/intel/car/romstage.c romstage-y += pmc.c romstage-y += romstage.c From ad5467d202408cafadd12aef6eea48b92b792a18 Mon Sep 17 00:00:00 2001 From: Felix Singer Date: Thu, 2 May 2019 14:40:48 +0200 Subject: [PATCH 566/588] drivers/fsp20: Fix spelling in help text Change-Id: Iab8d20a385bde31b29fa7766a87753fcc2d759b8 Signed-off-by: Felix Singer Reviewed-on: https://review.coreboot.org/c/coreboot/+/32544 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/drivers/intel/fsp2_0/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drivers/intel/fsp2_0/Kconfig b/src/drivers/intel/fsp2_0/Kconfig index 7fe81e51a0e..3fb39d50762 100644 --- a/src/drivers/intel/fsp2_0/Kconfig +++ b/src/drivers/intel/fsp2_0/Kconfig @@ -27,7 +27,7 @@ config PLATFORM_USES_FSP2_1 select FSP_PEIM_TO_PEIM_INTERFACE help Include FSP 2.1 wrappers and functionality. - Features added into FSP 2.1 specification that impacts corerboot are: + Features added into FSP 2.1 specification that impacts coreboot are: 1. Remove FSP stack switch and use the same stack with boot firmware 2. FSP should support external PPI interface pulled in via FSP_PEIM_TO_PEIM_INTERFACE From 086149eb32808f2003e2951ce679b3c7728c3846 Mon Sep 17 00:00:00 2001 From: Evgeny Zinoviev Date: Fri, 31 May 2019 16:25:04 +0300 Subject: [PATCH 567/588] mb/apple/macbookair4_2: Fix DRAM_RESET_GATE_GPIO It's GPIO28 according to schematics. Change-Id: I55be1ed178c818a17766e22cb2fd010412b8fe02 Signed-off-by: Evgeny Zinoviev Reviewed-on: https://review.coreboot.org/c/coreboot/+/33149 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber Reviewed-by: Felix Held --- src/mainboard/apple/macbookair4_2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mainboard/apple/macbookair4_2/Kconfig b/src/mainboard/apple/macbookair4_2/Kconfig index 4b2ee8fdc82..df8ecfd79d5 100644 --- a/src/mainboard/apple/macbookair4_2/Kconfig +++ b/src/mainboard/apple/macbookair4_2/Kconfig @@ -33,7 +33,7 @@ config VGA_BIOS_ID config DRAM_RESET_GATE_GPIO int - default 60 + default 28 config MAX_CPUS int From ec017590e54f5941f53cf33d8ebce6d311313a46 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 6 Apr 2019 16:09:46 +0200 Subject: [PATCH 568/588] util/lint: Make usage of IS_ENABLED() an error As long as we keep the IS_ENABLED() definition in libpayload for compatibility, we should check that IS_ENABLED() usage doesn't sneak back in. Also remove all other IS_ENABLED() checks. Change-Id: Id30ffa0089cec6c24fc3dbbb10a1be35f63b3d89 Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32229 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner Reviewed-by: Patrick Georgi --- util/lint/checkpatch.pl | 10 ------- util/lint/kconfig_lint | 55 +++++++++-------------------------- util/lint/kconfig_lint_README | 8 ++--- 3 files changed, 16 insertions(+), 57 deletions(-) diff --git a/util/lint/checkpatch.pl b/util/lint/checkpatch.pl index 265b04cef26..1affdb7b337 100755 --- a/util/lint/checkpatch.pl +++ b/util/lint/checkpatch.pl @@ -6184,16 +6184,6 @@ sub process { } } -# check for #if defined CONFIG_ || defined CONFIG__MODULE - if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(CONFIG_[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) { - my $config = $1; - if (WARN("PREFER_IS_ENABLED", - "Prefer IS_ENABLED() to CONFIG_ || CONFIG__MODULE\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] = "\+#if IS_ENABLED($config)"; - } - } - # check for case / default statements not preceded by break/fallthrough/switch if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) { my $has_break = 0; diff --git a/util/lint/kconfig_lint b/util/lint/kconfig_lint index 502a61878bc..47f04941f28 100755 --- a/util/lint/kconfig_lint +++ b/util/lint/kconfig_lint @@ -93,7 +93,7 @@ sub Main { check_used_symbols(); check_for_ifdef(); check_for_def(); - check_is_enabled(); + check_config_macro(); check_selected_symbols(); # Run checks based on the data that was found @@ -213,27 +213,6 @@ sub check_for_ifdef { } } } - - my @collected_is_enabled; - if ($dont_use_git_grep) { - @collected_is_enabled = - `grep -Irn -- "\\ Date: Wed, 22 May 2019 21:44:48 +0200 Subject: [PATCH 569/588] nb/intel/x4x/rcven.c: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I13d6593e283f0a9e6603e19ccfda116f3b145e52 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32948 Reviewed-by: Felix Held Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/northbridge/intel/x4x/rcven.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/northbridge/intel/x4x/rcven.c b/src/northbridge/intel/x4x/rcven.c index 7c49838d138..36a6ebd259c 100644 --- a/src/northbridge/intel/x4x/rcven.c +++ b/src/northbridge/intel/x4x/rcven.c @@ -41,7 +41,6 @@ static inline void barrier(void) static u8 sampledqs(u32 addr, u8 lane, u8 channel) { - volatile u32 strobe; u32 sample_offset = 0x400 * channel + 0x561 + lane * 4; /* Reset the DQS probe */ @@ -50,7 +49,8 @@ static u8 sampledqs(u32 addr, u8 lane, u8 channel) MCHBAR8(RESET_CNTL(channel)) |= 0x2; udelay(2); barrier(); - strobe = read32((u32 *)addr); + /* Read strobe */ + read32((u32 *)addr); barrier(); return (MCHBAR8(sample_offset) >> 6) & 1; } From 12f0e42cb4e66f0ebe198b051be31b68d876d2e5 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 6 Apr 2019 16:16:36 +0200 Subject: [PATCH 570/588] kconfig: Drop IS_ENABLED() macro We keep its definition in libpayload, though, to maintain compatibility with existing payload code. For now. Change-Id: I8fc0d0136ba2316ef393c5c17f2b3ac3a9c6328d Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/c/coreboot/+/32230 Tested-by: build bot (Jenkins) Reviewed-by: Julius Werner --- Documentation/getting_started/kconfig.md | 2 -- src/include/kconfig.h | 1 - 2 files changed, 3 deletions(-) diff --git a/Documentation/getting_started/kconfig.md b/Documentation/getting_started/kconfig.md index 249fd4600e9..852ca08bf94 100644 --- a/Documentation/getting_started/kconfig.md +++ b/Documentation/getting_started/kconfig.md @@ -1165,8 +1165,6 @@ saved .config file. As always, a 'select' statement overrides any specified - coreboot has added the glob operator '*' for the 'source' keyword. - coreboot’s Kconfig always defines variables except for strings. In other Kconfig implementations, bools set to false/0/no are not defined. -- IS_ENABLED() is ‘false’ for undefined variables and ‘0’ variables. In Linux - (where the macro comes from) it’s ‘true’ as soon as the variable is defined. - coreboot’s version of Kconfig adds the KCONFIG_STRICT environment variable to error out if there are any issues in the Kconfig files. In the Linux kernel, Kconfig will generate a warning, but will still output an updated .config or diff --git a/src/include/kconfig.h b/src/include/kconfig.h index 0478548d598..50ef3022935 100644 --- a/src/include/kconfig.h +++ b/src/include/kconfig.h @@ -17,7 +17,6 @@ #define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0, 0) #define ___config_enabled(__ignored, val, ...) val -#define IS_ENABLED(option) config_enabled(option) /* deprecated */ #define CONFIG(option) config_enabled(CONFIG_##option) #endif From 1b05479a7fc1605e1d9735575300bd09b55e6a5d Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Fri, 22 Mar 2019 12:38:20 +0530 Subject: [PATCH 571/588] libpayload: Add UART for qcs405 TEST=build Change-Id: I43164cf9eacc844af1d048f7b6ebbda96fc9d202 Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Sricharan R Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/29957 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- payloads/libpayload/Kconfig | 5 + payloads/libpayload/configs/config.mistral | 2 + payloads/libpayload/drivers/Makefile.inc | 1 + payloads/libpayload/drivers/serial/qcs405.c | 555 ++++++++++++++++++++ 4 files changed, 563 insertions(+) create mode 100644 payloads/libpayload/drivers/serial/qcs405.c diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index 5dce89ae6f2..97b970b0f14 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -258,6 +258,11 @@ config IPQ40XX_SERIAL_CONSOLE depends on SERIAL_CONSOLE default n +config QCS405_SERIAL_CONSOLE + bool "QCS405 SOC compatible serial port driver" + depends on SERIAL_CONSOLE + default n + config PL011_SERIAL_CONSOLE bool "PL011 compatible serial port driver" depends on 8250_SERIAL_CONSOLE diff --git a/payloads/libpayload/configs/config.mistral b/payloads/libpayload/configs/config.mistral index 5f60392fdb4..e305fb67000 100644 --- a/payloads/libpayload/configs/config.mistral +++ b/payloads/libpayload/configs/config.mistral @@ -1,3 +1,5 @@ CONFIG_LP_CHROMEOS=y CONFIG_LP_ARCH_ARM64=y CONFIG_LP_TIMER_ARM64_ARCH=y +CONFIG_LP_SERIAL_CONSOLE=y +CONFIG_LP_QCS405_SERIAL_CONSOLE=y diff --git a/payloads/libpayload/drivers/Makefile.inc b/payloads/libpayload/drivers/Makefile.inc index 40e587c2237..b4e75943f39 100644 --- a/payloads/libpayload/drivers/Makefile.inc +++ b/payloads/libpayload/drivers/Makefile.inc @@ -37,6 +37,7 @@ libc-$(CONFIG_LP_8250_SERIAL_CONSOLE) += serial/8250.c serial/serial.c libc-$(CONFIG_LP_S5P_SERIAL_CONSOLE) += serial/s5p.c serial/serial.c libc-$(CONFIG_LP_IPQ806X_SERIAL_CONSOLE) += serial/ipq806x.c serial/serial.c libc-$(CONFIG_LP_IPQ40XX_SERIAL_CONSOLE) += serial/ipq40xx.c serial/serial.c +libc-$(CONFIG_LP_QCS405_SERIAL_CONSOLE) += serial/qcs405.c serial/serial.c libc-$(CONFIG_LP_PC_KEYBOARD) += i8042/keyboard.c libc-$(CONFIG_LP_PC_MOUSE) += i8042/mouse.c libc-$(CONFIG_LP_PC_I8042) += i8042/i8042.c diff --git a/payloads/libpayload/drivers/serial/qcs405.c b/payloads/libpayload/drivers/serial/qcs405.c new file mode 100644 index 00000000000..9f02e172634 --- /dev/null +++ b/payloads/libpayload/drivers/serial/qcs405.c @@ -0,0 +1,555 @@ +/* + * Copyright (c) 2010-2012, 2014, 2016, 2019, The Linux Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#define UART_DM_CLK_RX_TX_BIT_RATE 0xFF + +enum MSM_BOOT_UART_DM_PARITY_MODE { + MSM_BOOT_UART_DM_NO_PARITY, + MSM_BOOT_UART_DM_ODD_PARITY, + MSM_BOOT_UART_DM_EVEN_PARITY, + MSM_BOOT_UART_DM_SPACE_PARITY +}; + +/* UART Stop Bit Length */ +enum MSM_BOOT_UART_DM_STOP_BIT_LEN { + MSM_BOOT_UART_DM_SBL_9_16, + MSM_BOOT_UART_DM_SBL_1, + MSM_BOOT_UART_DM_SBL_1_9_16, + MSM_BOOT_UART_DM_SBL_2 +}; + +/* UART Bits per Char */ +enum MSM_BOOT_UART_DM_BITS_PER_CHAR { + MSM_BOOT_UART_DM_5_BPS, + MSM_BOOT_UART_DM_6_BPS, + MSM_BOOT_UART_DM_7_BPS, + MSM_BOOT_UART_DM_8_BPS +}; + +/* 8-N-1 Configuration */ +#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \ + (MSM_BOOT_UART_DM_SBL_1 << 2) | \ + (MSM_BOOT_UART_DM_8_BPS << 4)) + +/* UART_DM Registers */ + +/* UART Operational Mode Register */ +#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00) +#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04) +#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8) +#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7) + +#define PERIPH_BLK_BLSP 1 + +/* UART Clock Selection Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0) +#else +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08) +#endif + +/* UART DM TX FIFO Registers - 4 */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x))) +#else +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x))) +#endif + +/* UART Command Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8) +#else +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10) +#endif +#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0) +#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1) +#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2) +#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3) + +/* UART Channel Command */ +#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4) +#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4) << 11) +#define MSM_BOOT_UART_DM_CR_CH_CMD(x) \ + (MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x)) +#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0) +#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1) +#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2) +#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3) +#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4) +#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5) +#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6) +#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7) +#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8) +#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9) +#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C) +#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D) +#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E) +#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10) +#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11) +#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12) +#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13) +#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14) + +/*UART General Command */ +#define MSM_UART_DM_CR_GENERAL_CMD(x) ((x) << 8) + +#define MSM_BOOT_UART_DM_GCMD_NULL MSM_UART_DM_CR_GENERAL_CMD(0) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_UART_DM_CR_GENERAL_CMD(1) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_UART_DM_CR_GENERAL_CMD(2) +#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_UART_DM_CR_GENERAL_CMD(3) +#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_UART_DM_CR_GENERAL_CMD(4) +#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_UART_DM_CR_GENERAL_CMD(5) +#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_UART_DM_CR_GENERAL_CMD(6) + +/* UART Interrupt Mask Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0) +#else +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14) +#endif + +#define MSM_BOOT_UART_DM_TXLEV (1 << 0) +#define MSM_BOOT_UART_DM_RXHUNT (1 << 1) +#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2) +#define MSM_BOOT_UART_DM_RXSTALE (1 << 3) +#define MSM_BOOT_UART_DM_RXLEV (1 << 4) +#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5) +#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6) +#define MSM_BOOT_UART_DM_TX_READY (1 << 7) +#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8) +#define MSM_BOOT_UART_DM_TX_DONE (1 << 9) +#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10) +#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11) +#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12) + +#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \ + MSM_BOOT_UART_DM_TXLEV | \ + MSM_BOOT_UART_DM_RXSTALE) + +/* UART Interrupt Programming Register */ +#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18) +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */ + +/* UART Transmit/Receive FIFO Watermark Register */ +#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C) +/* Interrupt is generated when FIFO level is less than or equal to this value */ +#define MSM_BOOT_UART_DM_TFW_VALUE 0 + +#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20) +/*Interrupt generated when no of words in RX FIFO is greater than this value */ +#define MSM_BOOT_UART_DM_RFW_VALUE 0 + +/* UART Hunt Character Register */ +#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24) + +/* Used for RX transfer initialization */ +#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34) + +/* Default DMRX value - any value bigger than FIFO size would be fine */ +#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220 + +/* Register to enable IRDA function */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8) +#else +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38) +#endif + +/* UART Data Mover Enable Register */ +#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C) + +/* Number of characters for Transmission */ +#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040) + +/* UART RX FIFO Base Address */ +#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44) + +/* UART Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4) +#else +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008) +#endif +#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0) +#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1) +#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2) +#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3) +#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4) +#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5) +#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6) +#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7) +#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8) + +/* UART Receive FIFO Registers - 4 in numbers */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x))) +#else +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x))) +#endif + +/* UART Masked Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC) +#else +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10) +#endif + +/* UART Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4) +#else +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14) +#endif + +/* Number of characters received since the end of last RX transfer */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC) +#else +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38) +#endif + +/* UART TX FIFO Status Register */ +#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C) +#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6) +#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31) +#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9) +#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13) + +/* UART RX FIFO Status Register */ +#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50) +#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6) +#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31) +#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9) +#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13) + +/* Macros for Common Errors */ +#define MSM_BOOT_UART_DM_E_FAILURE 1 +#define MSM_BOOT_UART_DM_E_TIMEOUT 2 +#define MSM_BOOT_UART_DM_E_INVAL 3 +#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4 +#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5 + +#define UART1_DM_BASE ((void *)0x078af000) +#define UART2_DM_BASE ((void *)0x078b1000) + +enum { + BLSP1_UART1, + BLSP1_UART2, +}; + +#define FIFO_DATA_SIZE 4 + +struct uart_params_t { + void *uart_dm_base; + unsigned int blsp_uart; +}; + +static struct console_input_driver consin = { + .havekey = serial_havechar, + .getchar = serial_getchar, +}; + +static struct console_output_driver consout = { + .putchar = serial_putchar, +}; + +static struct uart_params_t uart_board_param = {}; + +/** + * msm_boot_uart_dm_init_rx_transfer - Init Rx transfer + * @uart_dm_base: UART controller base address + */ +static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base) +{ + /* Reset receiver */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CMD_RESET_RX); + + /* Enable receiver */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CR_RX_ENABLE); + write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base), + MSM_BOOT_UART_DM_DMRX_DEF_VALUE); + + /* Clear stale event */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CMD_RES_STALE_INT); + + /* Enable stale event */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT); + + return 0; +} + +static unsigned int msm_boot_uart_dm_init(void *uart_dm_base); + +static int valid_data = 0; + +static unsigned int word = 0; + +/** + * msm_boot_uart_dm_read - reads a word from the RX FIFO. + * @data: location where the read data is stored + * @count: no of valid data in the FIFO + * + * Reads a word from the RX FIFO. If no data is available + * returns %MSM_BOOT_UART_DM_E_RX_NOT_READY. + */ +static unsigned int +msm_boot_uart_dm_read(unsigned int *data, int *count) +{ + static int total_rx_data = 0; + static int rx_data_read = 0; + void *base; + uint32_t status_reg; + + base = uart_board_param.uart_dm_base; + + if (data == NULL) + return MSM_BOOT_UART_DM_E_INVAL; + + status_reg = read32(MSM_BOOT_UART_DM_MISR(base)); + + /* Check for DM_RXSTALE for RX transfer to finish */ + while (!(status_reg & MSM_BOOT_UART_DM_RXSTALE)) { + status_reg = read32(MSM_BOOT_UART_DM_MISR(base)); + return MSM_BOOT_UART_DM_E_RX_NOT_READY; + } + + /* Check for Overrun error. We'll just reset Error Status */ + if (read32(MSM_BOOT_UART_DM_SR(base)) & + MSM_BOOT_UART_DM_SR_UART_OVERRUN) { + write32(MSM_BOOT_UART_DM_CR(base), + MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT); + total_rx_data = rx_data_read = 0; + msm_boot_uart_dm_init(base); + return MSM_BOOT_UART_DM_E_RX_NOT_READY; + } + + /* Read UART_DM_RX_TOTAL_SNAP for actual number of bytes received */ + if (total_rx_data == 0) + total_rx_data = read32(MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base)); + + /* Data available in FIFO; read a word. */ + *data = read32(MSM_BOOT_UART_DM_RF(base, 0)); + + /* increment the total count of chars we've read so far */ + rx_data_read += FIFO_DATA_SIZE; + + /* actual count of valid data in word */ + *count = ((total_rx_data < rx_data_read) ? + (FIFO_DATA_SIZE - (rx_data_read - total_rx_data)) : + FIFO_DATA_SIZE); + + /* If there are still data left in FIFO we'll read them before + * initializing RX Transfer again + */ + if (rx_data_read < total_rx_data) + return 0; + + msm_boot_uart_dm_init_rx_transfer(base); + total_rx_data = rx_data_read = 0; + + return 0; +} + +void serial_putchar(unsigned int data) +{ + int num_of_chars = 1; + void *base = uart_board_param.uart_dm_base; + + if (data == '\n') { + num_of_chars++; + data = (data << 8) | '\r'; + } + + /* Wait until transmit FIFO is empty. */ + while (!(read32(MSM_BOOT_UART_DM_SR(base)) & + MSM_BOOT_UART_DM_SR_TXEMT)) + udelay(1); + /* + * TX FIFO is ready to accept new character(s). First write number of + * characters to be transmitted. + */ + write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars); + + /* And now write the character(s) */ + write32(MSM_BOOT_UART_DM_TF(base, 0), data); +} + +/* + * msm_boot_uart_dm_reset - resets UART controller + * @base: UART controller base address + */ +static unsigned int msm_boot_uart_dm_reset(void *base) +{ + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX); + write32(MSM_BOOT_UART_DM_CR(base), + MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT); + + return 0; +} + +/* + * msm_boot_uart_dm_init - initilaizes UART controller + * @uart_dm_base: UART controller base address + */ +unsigned int msm_boot_uart_dm_init(void *uart_dm_base) +{ + /* Configure UART mode registers MR1 and MR2 */ + /* Hardware flow control isn't supported */ + write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0); + + /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */ + write32(MSM_BOOT_UART_DM_MR2(uart_dm_base), + MSM_BOOT_UART_DM_8_N_1_MODE); + + /* Configure Interrupt Mask register IMR */ + write32(MSM_BOOT_UART_DM_IMR(uart_dm_base), + MSM_BOOT_UART_DM_IMR_ENABLED); + + /* + * Configure Tx and Rx watermarks configuration registers + * TX watermark value is set to 0 - interrupt is generated when + * FIFO level is less than or equal to 0 + */ + write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base), + MSM_BOOT_UART_DM_TFW_VALUE); + + /* RX watermark value */ + write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base), + MSM_BOOT_UART_DM_RFW_VALUE); + + /* Configure Interrupt Programming Register */ + /* Set initial Stale timeout value */ + write32(MSM_BOOT_UART_DM_IPR(uart_dm_base), + MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB); + + /* Configure IRDA if required */ + /* Disabling IRDA mode */ + write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0); + + /* Configure hunt character value in HCR register */ + /* Keep it in reset state */ + write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0); + + /* + * Configure Rx FIFO base address + * Both TX/RX shares same SRAM and default is half-n-half. + * Sticking with default value now. + * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries). + * We have found RAM_ADDR_WIDTH = 0x7f + */ + + /* Issue soft reset command */ + msm_boot_uart_dm_reset(uart_dm_base); + + /* Enable/Disable Rx/Tx DM interfaces */ + /* Data Mover not currently utilized. */ + write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0); + + /* Enable transmitter */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CR_TX_ENABLE); + + /* Initialize Receive Path */ + msm_boot_uart_dm_init_rx_transfer(uart_dm_base); + + return 0; +} + +/** + * serial_havechar - checks if data available for reading + * + * Returns 1 if data available, 0 otherwise + */ +int serial_havechar(void) +{ + /* Return if data is already read */ + if (valid_data) + return 1; + + /* Read data from the FIFO */ + if (msm_boot_uart_dm_read(&word, &valid_data) != 0) + return 0; + + return 1; +} + +/** + * qcs405_serial_getc - reads a character + * + * Returns the character read from serial port. + */ +int serial_getchar(void) +{ + uint8_t byte; + + while (!serial_havechar()) + ; /* wait for incoming data */ + + byte = (uint8_t)(word & 0xff); + word = word >> 8; + valid_data--; + + return byte; +} + +/* For simplicity sake let's rely on coreboot initalizing the UART. */ +void serial_console_init(void) +{ + struct cb_serial *sc_ptr = lib_sysinfo.serial; + + if (!sc_ptr) + return; + + uart_board_param.uart_dm_base = (void *)(uintptr_t)sc_ptr->baseaddr; + + /* TODO: We should rely on coreboot init. */ + msm_boot_uart_dm_init(uart_board_param.uart_dm_base); + + console_add_output_driver(&consout); + console_add_input_driver(&consin); +} From 37e957f3349c461371e15cd3d6f754514506ce47 Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Fri, 22 Mar 2019 15:26:02 +0530 Subject: [PATCH 572/588] qcs405: Add UART support Add support for UART driver in coreboot. TEST=build & run Change-Id: Id9626c68eadead8b8ec5ffbc08cab7b0ec36478f Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Sricharan R Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/29964 Reviewed-by: Stefan Reinauer Tested-by: build bot (Jenkins) --- src/soc/qualcomm/qcs405/Kconfig | 1 + src/soc/qualcomm/qcs405/Makefile.inc | 4 + src/soc/qualcomm/qcs405/include/soc/blsp.h | 60 ++++ src/soc/qualcomm/qcs405/include/soc/cdp.h | 144 ++++++++++ src/soc/qualcomm/qcs405/include/soc/iomap.h | 156 ++++++++++ src/soc/qualcomm/qcs405/include/soc/uart.h | 273 ++++++++++++++++++ src/soc/qualcomm/qcs405/uart.c | 303 ++++++++++++++++++++ 7 files changed, 941 insertions(+) create mode 100644 src/soc/qualcomm/qcs405/include/soc/blsp.h create mode 100644 src/soc/qualcomm/qcs405/include/soc/cdp.h create mode 100644 src/soc/qualcomm/qcs405/include/soc/iomap.h create mode 100644 src/soc/qualcomm/qcs405/include/soc/uart.h create mode 100644 src/soc/qualcomm/qcs405/uart.c diff --git a/src/soc/qualcomm/qcs405/Kconfig b/src/soc/qualcomm/qcs405/Kconfig index 3e8c1ba5be7..6bbdd3bf34a 100644 --- a/src/soc/qualcomm/qcs405/Kconfig +++ b/src/soc/qualcomm/qcs405/Kconfig @@ -11,6 +11,7 @@ config SOC_QUALCOMM_QCS405 select GENERIC_UDELAY select HAVE_MONOTONIC_TIMER select ARM64_USE_ARCH_TIMER + select HAVE_UART_SPECIAL if SOC_QUALCOMM_QCS405 diff --git a/src/soc/qualcomm/qcs405/Makefile.inc b/src/soc/qualcomm/qcs405/Makefile.inc index 4df5246e3c4..c64e5bcf580 100644 --- a/src/soc/qualcomm/qcs405/Makefile.inc +++ b/src/soc/qualcomm/qcs405/Makefile.inc @@ -8,12 +8,14 @@ bootblock-y += spi.c bootblock-y += mmu.c bootblock-y += gpio.c bootblock-y += clock.c +bootblock-$(CONFIG_DRIVERS_UART) += uart.c ################################################################################ verstage-y += timer.c verstage-y += spi.c verstage-y += gpio.c verstage-y += clock.c +verstage-$(CONFIG_DRIVERS_UART) += uart.c ################################################################################ romstage-y += timer.c @@ -22,6 +24,7 @@ romstage-y += cbmem.c romstage-y += gpio.c romstage-y += clock.c romstage-y += usb.c +romstage-$(CONFIG_DRIVERS_UART) += uart.c ################################################################################ ramstage-y += soc.c @@ -31,6 +34,7 @@ ramstage-y += cbmem.c ramstage-y += gpio.c ramstage-y += clock.c ramstage-y += usb.c +ramstage-$(CONFIG_DRIVERS_UART) += uart.c ################################################################################ diff --git a/src/soc/qualcomm/qcs405/include/soc/blsp.h b/src/soc/qualcomm/qcs405/include/soc/blsp.h new file mode 100644 index 00000000000..6e55d7dd379 --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/blsp.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef __BLSP_H_ +#define __BLSP_H_ + +typedef enum { + BLSP_QUP_ID_0, + BLSP_QUP_ID_1, + BLSP_QUP_ID_2, + BLSP_QUP_ID_3, +} blsp_qup_id_t; + +typedef enum { + BLSP_SUCCESS = 0, + BLSP_ID_ERROR, + BLSP_ERROR, + BLSP_UNSUPPORTED +} blsp_return_t; + +typedef enum { + BLSP_PROTO_I2C_UIM = 1, + BLSP_PROTO_I2C_ONLY, + BLSP_PROTO_SPI_ONLY, + BLSP_PROTO_UART_FLOW_CTL, + BLSP_PROTO_UIM, + BLSP_PROTO_I2C_UART, +} blsp_protocol_t; + +blsp_return_t blsp_i2c_init(blsp_qup_id_t id); +int blsp_i2c_init_board(blsp_qup_id_t id); + +#endif diff --git a/src/soc/qualcomm/qcs405/include/soc/cdp.h b/src/soc/qualcomm/qcs405/include/soc/cdp.h new file mode 100644 index 00000000000..8e33f4b9600 --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/cdp.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#ifndef _QCS405_CDP_H_ +#define _QCS405_CDP_H_ + +#include + +unsigned int smem_get_board_machtype(void); + +typedef enum { + PHY_INTERFACE_MODE_MII, + PHY_INTERFACE_MODE_GMII, + PHY_INTERFACE_MODE_SGMII, + PHY_INTERFACE_MODE_QSGMII, + PHY_INTERFACE_MODE_TBI, + PHY_INTERFACE_MODE_RMII, + PHY_INTERFACE_MODE_RGMII, + PHY_INTERFACE_MODE_RGMII_ID, + PHY_INTERFACE_MODE_RGMII_RXID, + PHY_INTERFACE_MODE_RGMII_TXID, + PHY_INTERFACE_MODE_RTBI, + PHY_INTERFACE_MODE_XGMII, + PHY_INTERFACE_MODE_NONE /* Must be last */ +} phy_interface_t; + +typedef struct { + gpio_t gpio; + unsigned int func; + unsigned int dir; + unsigned int pull; + unsigned int drvstr; + unsigned int enable; +} gpio_func_data_t; + +typedef struct { + unsigned int m_value; + unsigned int n_value; + unsigned int d_value; +} uart_clk_mnd_t; + +/* SPI Mode */ + +typedef enum { + NOR_SPI_MODE_0, + NOR_SPI_MODE_1, + NOR_SPI_MODE_2, + NOR_SPI_MODE_3, +} spi_mode; + +/* SPI Chip selects */ + +typedef enum { + SPI_CS_0, + SPI_CS_1, + SPI_CS_2, + SPI_CS_3, +} spi_cs; + +/* Flash Types */ + +typedef enum { + ONLY_NAND, + ONLY_NOR, + NAND_NOR, + NOR_MMC, +} flash_desc; + +#define NO_OF_DBG_UART_GPIOS 2 + +#define SPI_NOR_FLASH_VENDOR_MICRON 0x1 +#define SPI_NOR_FLASH_VENDOR_SPANSION 0x2 + +/* SPI parameters */ + +typedef struct { + spi_mode mode; + spi_cs chip_select; + int vendor; +} spinorflash_params_t; + +typedef struct { + unsigned int count; + uint8_t addr[7]; +} ipq_gmac_phy_addr_t; + +typedef struct { + unsigned int base; + int unit; + unsigned int is_macsec; + unsigned int mac_pwr0; + unsigned int mac_pwr1; + unsigned int mac_conn_to_phy; + phy_interface_t phy; + ipq_gmac_phy_addr_t phy_addr; +} ipq_gmac_board_cfg_t; + +#define IPQ_GMAC_NMACS 4 + +enum gale_board_id { + BOARD_ID_GALE_PROTO = 0, + BOARD_ID_GALE_EVT = 1, + BOARD_ID_GALE_EVT2_0 = 2, + BOARD_ID_GALE_EVT2_1 = 6, + BOARD_ID_GALE_EVT3 = 5, +}; + +/* Board specific parameters */ +typedef struct { +} __packed board_ipq40xx_params_t; + +extern board_ipq40xx_params_t *gboard_param; + +unsigned int get_board_index(unsigned int machid); +void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count); + +#endif diff --git a/src/soc/qualcomm/qcs405/include/soc/iomap.h b/src/soc/qualcomm/qcs405/include/soc/iomap.h new file mode 100644 index 00000000000..2ed3e10f76a --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/iomap.h @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012 - 2013, 2015, 2019 The Linux Foundation. + * All rights reserved. + * + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __SOC_QUALCOMM_QCS405_IOMAP_H_ +#define __SOC_QUALCOMM_QCS405_IOMAP_H_ + +#include +#include +#include + +/* Typecast to allow integers being passed as address + This needs to be included because vendor code is not compliant with our + macros for read/write. Hence, special macros for readl_i and writel_i are + included to do this in one place for all occurrences in vendor code + */ +#define readl_i(a) read32((const void *)(a)) +#define writel_i(v, a) write32((void *)a, v) +#define clrsetbits_le32_i(addr, clear, set) \ + clrsetbits_le32(((void *)(addr)), (clear), (set)) + +#define GCC_CLK_CTL_REG ((void *)0x01800000u) +#define MSM_CLK_CTL_BASE GCC_CLK_CTL_REG +#define GCC_CLK_BRANCH_ENA (GCC_CLK_CTL_REG + 0x6000) +#define IMEM_AXI (1 << 17) +#define SYS_NOC_APSS_AHB (1 << 16) +#define BIMC_AXI_M0 (1 << 15) +#define APSS_AHB (1 << 14) +#define APSS_AXI (1 << 13) +#define MPM_AHB (1 << 12) +#define GMEM_SYS_NOC_AXI (1 << 11) +#define BLSP1_AHB (1 << 10) +#define BLSP1_SLEEP (1 << 9) +#define PRNG_AHB (1 << 8) +#define BOOT_ROM_AHB (1 << 7) +#define MSG_RAM_AHB (1 << 6) +#define TLMM_AHB (1 << 5) +#define TLMM (1 << 4) +#define SPMI_PCNOC_AHB (1 << 3) +#define CRYPTO (1 << 2) +#define CRYPTO_AXI (1 << 1) +#define CRYPTO_AHB (1 << 0) + +#define GCC_BLSP1_QUP1_I2C_APPS_CBCR (MSM_CLK_CTL_BASE + 0x2008) +#define GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR (MSM_CLK_CTL_BASE + 0x200c) +#define GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR (MSM_CLK_CTL_BASE + 0x2010) +#define GCC_BLSP1_QUP2_I2C_APPS_CBCR (MSM_CLK_CTL_BASE + 0x3010) +#define GCC_BLSP1_QUP2_I2C_APPS_CMD_RCGR (MSM_CLK_CTL_BASE + 0x3000) +#define GCC_BLSP1_QUP2_I2C_APPS_CFG_RCGR (MSM_CLK_CTL_BASE + 0x3004) + +#define GCNT_GLOBAL_CTRL_BASE ((void *)0x004a0000u) +#define GCNT_CNTCR (GCNT_GLOBAL_CTRL_BASE + 0x1000) +#define GCNT_GLB_CNTCV_LO (GCNT_GLOBAL_CTRL_BASE + 0x1008) +#define GCNT_GLB_CNTCV_HI (GCNT_GLOBAL_CTRL_BASE + 0x100c) +#define GCNT_CNTCV_LO (GCNT_GLOBAL_CTRL_BASE + 0x2000) +#define GCNT_CNTCV_HI (GCNT_GLOBAL_CTRL_BASE + 0x2004) + +#define GCNT_PSHOLD ((void *)0x004AB000u) + +/* RPM interface constants */ +#define RPM_INT ((void *)0x63020) +#define RPM_INT_ACK ((void *)0x63060) +#define RPM_SIGNAL_COOKIE ((void *)0x47C20) +#define RPM_SIGNAL_ENTRY ((void *)0x47C24) +#define RPM_FW_MAGIC_NUM 0x4D505242 + +#define TLMM_BASE_ADDR ((void *)0x01000000) +#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + 0x1000 * (x)) +#define GPIO_IN_OUT_ADDR(x) (GPIO_CONFIG_ADDR(x) + 4) + +/* Yes, this is not a typo... host2 is actually mapped before host1. */ +#define USB_HOST2_XHCI_BASE 0x10000000 +#define USB_HOST2_DWC3_BASE 0x1000C100 +#define USB_HOST2_PHY_BASE 0x100F8800 +#define USB_HOST1_XHCI_BASE 0x11000000 +#define USB_HOST1_DWC3_BASE 0x1100C100 +#define USB_HOST1_PHY_BASE 0x110F8800 + +#define UART1_DM_BASE ((void *)0x078af000) +#define UART2_DM_BASE ((void *)0x078B1000) + +enum { + BLSP1_UART1, + BLSP1_UART2, +}; + +#define GCC_BLSP1_UART_BCR_BASE (GCC_CLK_CTL_REG + 0x2038) +#define GCC_BLSP1_UART_BCR(x) (GCC_BLSP1_UART_BCR_BASE + (x) * 0xff0) +#define GCC_BLSP1_UART_APPS_CBCR(x) (GCC_BLSP1_UART_BCR(x) + 4) +#define GCC_BLSP1_UART_APPS_CMD_RCGR(x) (GCC_BLSP1_UART_APPS_CBCR(x) + 8) +#define GCC_BLSP1_UART_APPS_CFG_RCGR(x) (GCC_BLSP1_UART_APPS_CMD_RCGR(x) + 4) +#define GCC_BLSP1_UART_APPS_M(x) (GCC_BLSP1_UART_APPS_CFG_RCGR(x) + 4) +#define GCC_BLSP1_UART_APPS_N(x) (GCC_BLSP1_UART_APPS_M(x) + 4) +#define GCC_BLSP1_UART_APPS_D(x) (GCC_BLSP1_UART_APPS_N(x) + 4) +#define GCC_BLSP1_UART_MISC(x) (GCC_BLSP1_UART_APPS_D(x) + 4) + +#define BLSP1_QUP0_BASE ((void *)0x078B5000) +#define BLSP1_QUP1_BASE ((void *)0x078B6000) +#define BLSP1_QUP2_BASE ((void *)0x078B7000) +#define BLSP1_QUP3_BASE ((void *)0x078B8000) + +#define TCSR_BOOT_MISC_DETECT ((void *)0x0193D100) +#define TCSR_RESET_DEBUG_SW_ENTRY ((void *)0x01940000) + +static inline void *blsp_qup_base(blsp_qup_id_t id) +{ + switch (id) { + case BLSP_QUP_ID_0: return BLSP1_QUP0_BASE; + case BLSP_QUP_ID_1: return BLSP1_QUP1_BASE; + case BLSP_QUP_ID_2: return BLSP1_QUP2_BASE; + case BLSP_QUP_ID_3: return BLSP1_QUP3_BASE; + } + return NULL; +} + +#define BLSP_MINI_CORE_SHIFT 8 +#define BLSP_MINI_CORE_I2C (0x2u << BLSP_MINI_CORE_SHIFT) +#define BLSP_MINI_CORE_MASK (0xfu << BLSP_MINI_CORE_SHIFT) + +#define ETIMEDOUT -10 +#define EINVAL -11 +#define EIO -12 + +#endif diff --git a/src/soc/qualcomm/qcs405/include/soc/uart.h b/src/soc/qualcomm/qcs405/include/soc/uart.h new file mode 100644 index 00000000000..5c8a361c7b3 --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/uart.h @@ -0,0 +1,273 @@ +/* + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved.* + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __UART_DM_H__ +#define __UART_DM_H__ + +#define PERIPH_BLK_BLSP 1 + +#define MSM_BOOT_UART_DM_EXTR_BITS(value, start_pos, end_pos) \ + ((value << (32 - end_pos)) >> (32 - (end_pos - start_pos))) + +extern void __udelay(unsigned long usec); + + +enum MSM_BOOT_UART_DM_PARITY_MODE { + MSM_BOOT_UART_DM_NO_PARITY, + MSM_BOOT_UART_DM_ODD_PARITY, + MSM_BOOT_UART_DM_EVEN_PARITY, + MSM_BOOT_UART_DM_SPACE_PARITY +}; + +/* UART Stop Bit Length */ +enum MSM_BOOT_UART_DM_STOP_BIT_LEN { + MSM_BOOT_UART_DM_SBL_9_16, + MSM_BOOT_UART_DM_SBL_1, + MSM_BOOT_UART_DM_SBL_1_9_16, + MSM_BOOT_UART_DM_SBL_2 +}; + +/* UART Bits per Char */ +enum MSM_BOOT_UART_DM_BITS_PER_CHAR { + MSM_BOOT_UART_DM_5_BPS, + MSM_BOOT_UART_DM_6_BPS, + MSM_BOOT_UART_DM_7_BPS, + MSM_BOOT_UART_DM_8_BPS +}; + +/* 8-N-1 Configuration */ +#define MSM_BOOT_UART_DM_8_N_1_MODE (MSM_BOOT_UART_DM_NO_PARITY | \ + (MSM_BOOT_UART_DM_SBL_1 << 2) | \ + (MSM_BOOT_UART_DM_8_BPS << 4)) + +/* UART_DM Registers */ + +/* UART Operational Mode Register */ +#define MSM_BOOT_UART_DM_MR1(base) ((base) + 0x00) +#define MSM_BOOT_UART_DM_MR2(base) ((base) + 0x04) +#define MSM_BOOT_UART_DM_RXBRK_ZERO_CHAR_OFF (1 << 8) +#define MSM_BOOT_UART_DM_LOOPBACK (1 << 7) + +/* UART Clock Selection Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0xA0) +#else +#define MSM_BOOT_UART_DM_CSR(base) ((base) + 0x08) +#endif + +/* UART DM TX FIFO Registers - 4 */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x100+(4*(x))) +#else +#define MSM_BOOT_UART_DM_TF(base, x) ((base) + 0x70+(4*(x))) +#endif + +/* UART Command Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0xA8) +#else +#define MSM_BOOT_UART_DM_CR(base) ((base) + 0x10) +#endif +#define MSM_BOOT_UART_DM_CR_RX_ENABLE (1 << 0) +#define MSM_BOOT_UART_DM_CR_RX_DISABLE (1 << 1) +#define MSM_BOOT_UART_DM_CR_TX_ENABLE (1 << 2) +#define MSM_BOOT_UART_DM_CR_TX_DISABLE (1 << 3) + +/* UART Channel Command */ +#define MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) ((x & 0x0f) << 4) +#define MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x) ((x >> 4) << 11) +#define MSM_BOOT_UART_DM_CR_CH_CMD(x) \ + (MSM_BOOT_UART_DM_CR_CH_CMD_LSB(x) | MSM_BOOT_UART_DM_CR_CH_CMD_MSB(x)) +#define MSM_BOOT_UART_DM_CMD_NULL MSM_BOOT_UART_DM_CR_CH_CMD(0) +#define MSM_BOOT_UART_DM_CMD_RESET_RX MSM_BOOT_UART_DM_CR_CH_CMD(1) +#define MSM_BOOT_UART_DM_CMD_RESET_TX MSM_BOOT_UART_DM_CR_CH_CMD(2) +#define MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT MSM_BOOT_UART_DM_CR_CH_CMD(3) +#define MSM_BOOT_UART_DM_CMD_RES_BRK_CHG_INT MSM_BOOT_UART_DM_CR_CH_CMD(4) +#define MSM_BOOT_UART_DM_CMD_START_BRK MSM_BOOT_UART_DM_CR_CH_CMD(5) +#define MSM_BOOT_UART_DM_CMD_STOP_BRK MSM_BOOT_UART_DM_CR_CH_CMD(6) +#define MSM_BOOT_UART_DM_CMD_RES_CTS_N MSM_BOOT_UART_DM_CR_CH_CMD(7) +#define MSM_BOOT_UART_DM_CMD_RES_STALE_INT MSM_BOOT_UART_DM_CR_CH_CMD(8) +#define MSM_BOOT_UART_DM_CMD_PACKET_MODE MSM_BOOT_UART_DM_CR_CH_CMD(9) +#define MSM_BOOT_UART_DM_CMD_MODE_RESET MSM_BOOT_UART_DM_CR_CH_CMD(C) +#define MSM_BOOT_UART_DM_CMD_SET_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(D) +#define MSM_BOOT_UART_DM_CMD_RES_RFR_N MSM_BOOT_UART_DM_CR_CH_CMD(E) +#define MSM_BOOT_UART_DM_CMD_RES_TX_ERR MSM_BOOT_UART_DM_CR_CH_CMD(10) +#define MSM_BOOT_UART_DM_CMD_CLR_TX_DONE MSM_BOOT_UART_DM_CR_CH_CMD(11) +#define MSM_BOOT_UART_DM_CMD_RES_BRKSTRT_INT MSM_BOOT_UART_DM_CR_CH_CMD(12) +#define MSM_BOOT_UART_DM_CMD_RES_BRKEND_INT MSM_BOOT_UART_DM_CR_CH_CMD(13) +#define MSM_BOOT_UART_DM_CMD_RES_PER_FRM_INT MSM_BOOT_UART_DM_CR_CH_CMD(14) + +/*UART General Command */ +#define MSM_BOOT_UART_DM_CR_GENERAL_CMD(x) ((x) << 8) + +#define MSM_BOOT_UART_DM_GCMD_NULL MSM_BOOT_UART_DM_CR_GENERAL_CMD(0) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_EN MSM_BOOT_UART_DM_CR_GENERAL_CMD(1) +#define MSM_BOOT_UART_DM_GCMD_CR_PROT_DIS MSM_BOOT_UART_DM_CR_GENERAL_CMD(2) +#define MSM_BOOT_UART_DM_GCMD_RES_TX_RDY_INT MSM_BOOT_UART_DM_CR_GENERAL_CMD(3) +#define MSM_BOOT_UART_DM_GCMD_SW_FORCE_STALE MSM_BOOT_UART_DM_CR_GENERAL_CMD(4) +#define MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(5) +#define MSM_BOOT_UART_DM_GCMD_DIS_STALE_EVT MSM_BOOT_UART_DM_CR_GENERAL_CMD(6) + +/* UART Interrupt Mask Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0xB0) +#else +#define MSM_BOOT_UART_DM_IMR(base) ((base) + 0x14) +#endif + +#define MSM_BOOT_UART_DM_TXLEV (1 << 0) +#define MSM_BOOT_UART_DM_RXHUNT (1 << 1) +#define MSM_BOOT_UART_DM_RXBRK_CHNG (1 << 2) +#define MSM_BOOT_UART_DM_RXSTALE (1 << 3) +#define MSM_BOOT_UART_DM_RXLEV (1 << 4) +#define MSM_BOOT_UART_DM_DELTA_CTS (1 << 5) +#define MSM_BOOT_UART_DM_CURRENT_CTS (1 << 6) +#define MSM_BOOT_UART_DM_TX_READY (1 << 7) +#define MSM_BOOT_UART_DM_TX_ERROR (1 << 8) +#define MSM_BOOT_UART_DM_TX_DONE (1 << 9) +#define MSM_BOOT_UART_DM_RXBREAK_START (1 << 10) +#define MSM_BOOT_UART_DM_RXBREAK_END (1 << 11) +#define MSM_BOOT_UART_DM_PAR_FRAME_ERR_IRQ (1 << 12) + +#define MSM_BOOT_UART_DM_IMR_ENABLED (MSM_BOOT_UART_DM_TX_READY | \ + MSM_BOOT_UART_DM_TXLEV | \ + MSM_BOOT_UART_DM_RXSTALE) + +/* UART Interrupt Programming Register */ +#define MSM_BOOT_UART_DM_IPR(base) ((base) + 0x18) +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB 0x0f +#define MSM_BOOT_UART_DM_STALE_TIMEOUT_MSB 0 /* Not used currently */ + +/* UART Transmit/Receive FIFO Watermark Register */ +#define MSM_BOOT_UART_DM_TFWR(base) ((base) + 0x1C) +/* Interrupt is generated when FIFO level is less than or equal to this value */ +#define MSM_BOOT_UART_DM_TFW_VALUE 0 + +#define MSM_BOOT_UART_DM_RFWR(base) ((base) + 0x20) +/*Interrupt generated when no of words in RX FIFO is greater than this value */ +#define MSM_BOOT_UART_DM_RFW_VALUE 0 + +/* UART Hunt Character Register */ +#define MSM_BOOT_UART_DM_HCR(base) ((base) + 0x24) + +/* Used for RX transfer initialization */ +#define MSM_BOOT_UART_DM_DMRX(base) ((base) + 0x34) + +/* Default DMRX value - any value bigger than FIFO size would be fine */ +#define MSM_BOOT_UART_DM_DMRX_DEF_VALUE 0x220 + +/* Register to enable IRDA function */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0xB8) +#else +#define MSM_BOOT_UART_DM_IRDA(base) ((base) + 0x38) +#endif + +/* UART Data Mover Enable Register */ +#define MSM_BOOT_UART_DM_DMEN(base) ((base) + 0x3C) + +/* Number of characters for Transmission */ +#define MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base) ((base) + 0x040) + +/* UART RX FIFO Base Address */ +#define MSM_BOOT_UART_DM_BADR(base) ((base) + 0x44) + +/* UART Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x0A4) +#else +#define MSM_BOOT_UART_DM_SR(base) ((base) + 0x008) +#endif +#define MSM_BOOT_UART_DM_SR_RXRDY (1 << 0) +#define MSM_BOOT_UART_DM_SR_RXFULL (1 << 1) +#define MSM_BOOT_UART_DM_SR_TXRDY (1 << 2) +#define MSM_BOOT_UART_DM_SR_TXEMT (1 << 3) +#define MSM_BOOT_UART_DM_SR_UART_OVERRUN (1 << 4) +#define MSM_BOOT_UART_DM_SR_PAR_FRAME_ERR (1 << 5) +#define MSM_BOOT_UART_DM_RX_BREAK (1 << 6) +#define MSM_BOOT_UART_DM_HUNT_CHAR (1 << 7) +#define MSM_BOOT_UART_DM_RX_BRK_START_LAST (1 << 8) + +/* UART Receive FIFO Registers - 4 in numbers */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x140 + (4*(x))) +#else +#define MSM_BOOT_UART_DM_RF(base, x) ((base) + 0x70 + (4*(x))) +#endif + +/* UART Masked Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0xAC) +#else +#define MSM_BOOT_UART_DM_MISR(base) ((base) + 0x10) +#endif + +/* UART Interrupt Status Register */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0xB4) +#else +#define MSM_BOOT_UART_DM_ISR(base) ((base) + 0x14) +#endif + +/* Number of characters received since the end of last RX transfer */ +#if PERIPH_BLK_BLSP +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0xBC) +#else +#define MSM_BOOT_UART_DM_RX_TOTAL_SNAP(base) ((base) + 0x38) +#endif + +/* UART TX FIFO Status Register */ +#define MSM_BOOT_UART_DM_TXFS(base) ((base) + 0x4C) +#define MSM_BOOT_UART_DM_TXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6) +#define MSM_BOOT_UART_DM_TXFS_STATE_MSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31) +#define MSM_BOOT_UART_DM_TXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9) +#define MSM_BOOT_UART_DM_TXFS_ASYNC_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13) + +/* UART RX FIFO Status Register */ +#define MSM_BOOT_UART_DM_RXFS(base) ((base) + 0x50) +#define MSM_BOOT_UART_DM_RXFS_STATE_LSB(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 0, 6) +#define MSM_BOOT_UART_DM_RXFS_STATE_MSB(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 14, 31) +#define MSM_BOOT_UART_DM_RXFS_BUF_STATE(x) MSM_BOOT_UART_DM_EXTR_BITS(x, 7, 9) +#define MSM_BOOT_UART_DM_RXFS_ASYNC_STATE(x) \ + MSM_BOOT_UART_DM_EXTR_BITS(x, 10, 13) + +/* Macros for Common Errors */ +#define MSM_BOOT_UART_DM_E_SUCCESS 0 +#define MSM_BOOT_UART_DM_E_FAILURE 1 +#define MSM_BOOT_UART_DM_E_TIMEOUT 2 +#define MSM_BOOT_UART_DM_E_INVAL 3 +#define MSM_BOOT_UART_DM_E_MALLOC_FAIL 4 +#define MSM_BOOT_UART_DM_E_RX_NOT_READY 5 + +void qcs405_uart_init(void); + +#endif /* __UART_DM_H__ */ diff --git a/src/soc/qualcomm/qcs405/uart.c b/src/soc/qualcomm/qcs405/uart.c new file mode 100644 index 00000000000..4a4331220ac --- /dev/null +++ b/src/soc/qualcomm/qcs405/uart.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Source : APQ8064 LK boot + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define FIFO_DATA_SIZE 4 + +typedef struct { + void *uart_dm_base; + unsigned int blsp_uart; + gpio_func_data_t dbg_uart_gpio[NO_OF_DBG_UART_GPIOS]; +} uart_params_t; + +void ipq_configure_gpio(const gpio_func_data_t *gpio, unsigned int count) +{ + int i; + + for (i = 0; i < count; i++) { + gpio_configure(gpio->gpio, gpio->func, + gpio->pull, gpio->drvstr, gpio->enable); + gpio++; + } +} + +static const uart_params_t uart_board_param = { + .uart_dm_base = UART2_DM_BASE, + .blsp_uart = BLSP1_UART2, + .dbg_uart_gpio = { + { + .gpio = GPIO(17), + .func = 1, + .dir = GPIO_OUTPUT, + .pull = GPIO_PULL_UP, + .enable = GPIO_OUTPUT + }, + { + .gpio = GPIO(18), + .func = 1, + .dir = GPIO_INPUT, + .pull = GPIO_NO_PULL, + .enable = GPIO_INPUT + }, + }, +}; + +/** + * @brief msm_boot_uart_dm_init_rx_transfer - Init Rx transfer + * @param uart_dm_base: UART controller base address + */ +static unsigned int msm_boot_uart_dm_init_rx_transfer(void *uart_dm_base) +{ + /* Reset receiver */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CMD_RESET_RX); + + /* Enable receiver */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CR_RX_ENABLE); + write32(MSM_BOOT_UART_DM_DMRX(uart_dm_base), + MSM_BOOT_UART_DM_DMRX_DEF_VALUE); + + /* Clear stale event */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CMD_RES_STALE_INT); + + /* Enable stale event */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_GCMD_ENA_STALE_EVT); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +#if CONFIG(DRIVERS_UART) +static unsigned int msm_boot_uart_dm_init(void *uart_dm_base); + +/* Received data is valid or not */ +static int valid_data = 0; + +/* Received data */ +static unsigned int word = 0; + + +void uart_tx_byte(int idx, unsigned char data) +{ + int num_of_chars = 1; + void *base = uart_board_param.uart_dm_base; + + /* Wait until transmit FIFO is empty. */ + while (!(read32(MSM_BOOT_UART_DM_SR(base)) & + MSM_BOOT_UART_DM_SR_TXEMT)) + udelay(1); + /* + * TX FIFO is ready to accept new character(s). First write number of + * characters to be transmitted. + */ + write32(MSM_BOOT_UART_DM_NO_CHARS_FOR_TX(base), num_of_chars); + + /* And now write the character(s) */ + write32(MSM_BOOT_UART_DM_TF(base, 0), data); +} +#endif /* CONFIG_SERIAL_UART */ + +/** + * @brief msm_boot_uart_dm_reset - resets UART controller + * @param base: UART controller base address + */ +static unsigned int msm_boot_uart_dm_reset(void *base) +{ + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_RX); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RESET_TX); + write32(MSM_BOOT_UART_DM_CR(base), + MSM_BOOT_UART_DM_CMD_RESET_ERR_STAT); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_TX_ERR); + write32(MSM_BOOT_UART_DM_CR(base), MSM_BOOT_UART_DM_CMD_RES_STALE_INT); + + return MSM_BOOT_UART_DM_E_SUCCESS; +} + +/** + * @brief msm_boot_uart_dm_init - initilaizes UART controller + * @param uart_dm_base: UART controller base address + */ +unsigned int msm_boot_uart_dm_init(void *uart_dm_base) +{ + /* Configure UART mode registers MR1 and MR2 */ + /* Hardware flow control isn't supported */ + write32(MSM_BOOT_UART_DM_MR1(uart_dm_base), 0x0); + + /* 8-N-1 configuration: 8 data bits - No parity - 1 stop bit */ + write32(MSM_BOOT_UART_DM_MR2(uart_dm_base), + MSM_BOOT_UART_DM_8_N_1_MODE); + + /* Configure Interrupt Mask register IMR */ + write32(MSM_BOOT_UART_DM_IMR(uart_dm_base), + MSM_BOOT_UART_DM_IMR_ENABLED); + + /* + * Configure Tx and Rx watermarks configuration registers + * TX watermark value is set to 0 - interrupt is generated when + * FIFO level is less than or equal to 0 + */ + write32(MSM_BOOT_UART_DM_TFWR(uart_dm_base), + MSM_BOOT_UART_DM_TFW_VALUE); + + /* RX watermark value */ + write32(MSM_BOOT_UART_DM_RFWR(uart_dm_base), + MSM_BOOT_UART_DM_RFW_VALUE); + + /* Configure Interrupt Programming Register */ + /* Set initial Stale timeout value */ + write32(MSM_BOOT_UART_DM_IPR(uart_dm_base), + MSM_BOOT_UART_DM_STALE_TIMEOUT_LSB); + + /* Configure IRDA if required */ + /* Disabling IRDA mode */ + write32(MSM_BOOT_UART_DM_IRDA(uart_dm_base), 0x0); + + /* Configure hunt character value in HCR register */ + /* Keep it in reset state */ + write32(MSM_BOOT_UART_DM_HCR(uart_dm_base), 0x0); + + /* + * Configure Rx FIFO base address + * Both TX/RX shares same SRAM and default is half-n-half. + * Sticking with default value now. + * As such RAM size is (2^RAM_ADDR_WIDTH, 32-bit entries). + * We have found RAM_ADDR_WIDTH = 0x7f + */ + + /* Issue soft reset command */ + msm_boot_uart_dm_reset(uart_dm_base); + + /* Enable/Disable Rx/Tx DM interfaces */ + /* Data Mover not currently utilized. */ + write32(MSM_BOOT_UART_DM_DMEN(uart_dm_base), 0x0); + + /* Enable transmitter */ + write32(MSM_BOOT_UART_DM_CR(uart_dm_base), + MSM_BOOT_UART_DM_CR_TX_ENABLE); + + /* Initialize Receive Path */ + msm_boot_uart_dm_init_rx_transfer(uart_dm_base); + + return 0; +} + +/** + * @brief qcs405_uart_init - initializes UART + * + * Initializes clocks, GPIO and UART controller. + */ +void uart_init(int idx) +{ + /* Note int idx isn't used in this driver. */ + void *dm_base; + + dm_base = uart_board_param.uart_dm_base; + + if (read32(MSM_BOOT_UART_DM_CSR(dm_base)) == 0xFF) + return; /* UART must have been already initialized. */ + + clock_configure_uart(1843200); + clock_enable_uart(); + + ipq_configure_gpio(uart_board_param.dbg_uart_gpio, + NO_OF_DBG_UART_GPIOS); + + write32(MSM_BOOT_UART_DM_CSR(dm_base), 0xFF); + + /* Initialize UART_DM */ + msm_boot_uart_dm_init(dm_base); +} + +/* for the benefit of non-console uart init */ +void qcs405_uart_init(void) +{ + uart_init(0); +} + +/** + * @brief uart_tx_flush - transmits a string of data + * @param idx: string to transmit + */ +void uart_tx_flush(int idx) +{ + void *base = uart_board_param.uart_dm_base; + + while (!(read32(MSM_BOOT_UART_DM_SR(base)) & + MSM_BOOT_UART_DM_SR_TXEMT)) + ; +} + +#if CONFIG(DRIVERS_UART) +/** + * qcs405_serial_getc - reads a character + * + * Returns the character read from serial port. + */ +uint8_t uart_rx_byte(int idx) +{ + uint8_t byte; + + byte = (uint8_t)(word & 0xff); + word = word >> 8; + valid_data--; + + return byte; +} +#endif + +#ifndef __PRE_RAM__ +void uart_fill_lb(void *data) +{ + struct lb_serial serial; + + serial.type = LB_SERIAL_TYPE_MEMORY_MAPPED; + serial.baseaddr = (uint64_t)UART2_DM_BASE; + serial.baud = get_uart_baudrate(); + serial.regwidth = 1; + + lb_add_serial(&serial, data); + lb_add_console(LB_TAG_CONSOLE_SERIAL8250MEM, data); +} +#endif From 13539d2f9d671099764f12e45b8e6d4e41c8e4af Mon Sep 17 00:00:00 2001 From: Prudhvi Yarlagadda Date: Thu, 14 Mar 2019 11:01:12 +0530 Subject: [PATCH 573/588] qcs405: Add SPI driver support Add SPI driver support in coreboot. Change-Id: I813ba0b5cc8344c463c3e41ff6db80bc0d8ebd96 Signed-off-by: Prudhvi Yarlagadda Signed-off-by: Nitheesh Sekar Reviewed-on: https://review.coreboot.org/c/coreboot/+/32058 Reviewed-by: Patrick Georgi Tested-by: build bot (Jenkins) --- src/soc/qualcomm/qcs405/Kconfig | 9 + src/soc/qualcomm/qcs405/include/soc/qup.h | 232 +++++++ src/soc/qualcomm/qcs405/include/soc/spi.h | 210 ++++++ src/soc/qualcomm/qcs405/spi.c | 768 +++++++++++++++++++++- 4 files changed, 1202 insertions(+), 17 deletions(-) create mode 100644 src/soc/qualcomm/qcs405/include/soc/qup.h create mode 100644 src/soc/qualcomm/qcs405/include/soc/spi.h diff --git a/src/soc/qualcomm/qcs405/Kconfig b/src/soc/qualcomm/qcs405/Kconfig index 6bbdd3bf34a..aa867c2f25e 100644 --- a/src/soc/qualcomm/qcs405/Kconfig +++ b/src/soc/qualcomm/qcs405/Kconfig @@ -19,4 +19,13 @@ config VBOOT select VBOOT_SEPARATE_VERSTAGE select VBOOT_RETURN_FROM_VERSTAGE select VBOOT_STARTS_IN_BOOTBLOCK + +config QCS405_BLSP_SPI + bool + default y + prompt "Build Flash Using SPI-NOR" + +config BOOT_DEVICE_SPI_FLASH_BUS + int + default 5 endif diff --git a/src/soc/qualcomm/qcs405/include/soc/qup.h b/src/soc/qualcomm/qcs405/include/soc/qup.h new file mode 100644 index 00000000000..f8f9c759725 --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/qup.h @@ -0,0 +1,232 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 - 2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __QUP_H__ +#define __QUP_H__ + + +/* QUP block registers */ +#define QUP_CONFIG 0x000 +#define QUP_STATE 0x004 +#define QUP_IO_MODES 0x008 +#define QUP_SW_RESET 0x00C +#define QUP_TRANSFER_CANCEL 0x014 +#define QUP_OPERATIONAL 0x018 +#define QUP_ERROR_FLAGS 0x01C +#define QUP_ERROR_FLAGS_EN 0x020 +#define QUP_TEST_CTRL 0x024 +#define QUP_OPERATIONAL_MASK 0x028 +#define QUP_HW_VERSION 0x030 +#define QUP_MX_OUTPUT_COUNT 0x100 +#define QUP_MX_OUTPUT_CNT_CURRENT 0x104 +#define QUP_OUTPUT_DEBUG 0x108 +#define QUP_OUTPUT_FIFO_WORD_CNT 0x10C +#define QUP_OUTPUT_FIFO 0x110 +#define QUP_OUTPUT_FIFO_SIZE 64 /* bytes */ +#define QUP_MX_WRITE_COUNT 0x150 +#define QUP_MX_WRITE_CNT_CURRENT 0x154 +#define QUP_MX_INPUT_COUNT 0x200 +#define QUP_MX_INPUT_CNT_CURRENT 0x204 +#define QUP_MX_READ_COUNT 0x208 +#define QUP_MX_READ_CNT_CURRENT 0x20C +#define QUP_INPUT_DEBUG 0x210 +#define QUP_INPUT_FIFO_WORD_CNT 0x214 +#define QUP_INPUT_FIFO 0x218 +#define QUP_INPUT_FIFO_SIZE 64 /* bytes */ +#define QUP_I2C_MASTER_CLK_CTL 0x400 +#define QUP_I2C_MASTER_STATUS 0x404 +#define QUP_I2C_MASTER_CONFIG 0x408 +#define QUP_I2C_MASTER_BUS_CLEAR 0x40C +#define QUP_I2C_MASTER_LOCAL_ID 0x410 +#define QUP_I2C_MASTER_COMMAND 0x414 + +#define OUTPUT_FIFO_FULL (1<<6) +#define INPUT_FIFO_NOT_EMPTY (1<<5) +#define OUTPUT_FIFO_NOT_EMPTY (1<<4) +#define MAX_OUTPUT_DONE_FLAG (1<<10) +#define MAX_INPUT_DONE_FLAG (1<<11) +#define INPUT_SERVICE_FLAG (1<<9) +#define OUTPUT_SERVICE_FLAG (1<<8) +#define QUP_UNPACK_EN (1<<14) +#define QUP_PACK_EN (1<<15) +#define QUP_OUTPUT_BIT_SHIFT_EN (1<<16) + +#define QUP_MODE_MASK (0x03) +#define QUP_OUTPUT_MODE_SHFT (10) +#define QUP_INPUT_MODE_SHFT (12) + +#define QUP_FS_DIVIDER_MASK (0xFF) + +#define QUP_APP_CLK_ON_EN (1 << 12) +#define QUP_CORE_CLK_ON_EN (1 << 13) +#define QUP_MINI_CORE_PROTO_SHFT (8) +#define QUP_MINI_CORE_PROTO_MASK (0x0F) + +/* Mini-core states */ +#define QUP_STATE_RESET 0x0 +#define QUP_STATE_RUN 0x1 +#define QUP_STATE_PAUSE 0x3 +#define QUP_STATE_VALID (1<<2) +#define QUP_STATE_MASK 0x3 +#define QUP_STATE_VALID_MASK (1<<2) + +/* Tags for output FIFO */ +#define QUP_I2C_1CLK_NOOP_SEQ 0x1 /*MSB 8-bit NOP, LSB 8-bits 1 clk.*/ +#define QUP_I2C_START_SEQ (0x1 << 8) +#define QUP_I2C_DATA_SEQ (0x2 << 8) +#define QUP_I2C_STOP_SEQ (0x3 << 8) +#define QUP_I2C_RECV_SEQ (0x4 << 8) + +/* Tags for input FIFO */ +#define QUP_I2C_MIDATA_SEQ (0x5 << 8) +#define QUP_I2C_MISTOP_SEQ (0x6 << 8) +#define QUP_I2C_MINACK_SEQ (0x7 << 8) + +#define QUP_I2C_ADDR(x) ((x & 0xFF) << 1) +#define QUP_I2C_DATA(x) (x & 0xFF) +#define QUP_I2C_MI_TAG(x) (x & 0xFF00) +#define QUP_I2C_SLAVE_READ (0x1) + +/*Bit vals for I2C_MASTER_CLK_CTL register */ +#define QUP_HS_DIVIDER_SHFT (8) +#define QUP_DIVIDER_MIN_VAL (0x3) + +/* Bit masks for I2C_MASTER_STATUS register */ +#define QUP_I2C_INVALID_READ_SEQ (1 << 25) +#define QUP_I2C_INVALID_READ_ADDR (1 << 24) +#define QUP_I2C_INVALID_TAG (1 << 23) +#define QUP_I2C_FAILED_MASK (0x3 << 6) +#define QUP_I2C_INVALID_WRITE (1 << 5) +#define QUP_I2C_ARB_LOST (1 << 4) +#define QUP_I2C_PACKET_NACK (1 << 3) +#define QUP_I2C_BUS_ERROR (1 << 2) + +typedef enum { + QUP_SUCCESS = 0, + QUP_ERR_BAD_PARAM, + QUP_ERR_STATE_SET, + QUP_ERR_TIMEOUT, + QUP_ERR_UNSUPPORTED, + QUP_ERR_I2C_FAILED, + QUP_ERR_I2C_ARB_LOST, + QUP_ERR_I2C_BUS_ERROR, + QUP_ERR_I2C_INVALID_SLAVE_ADDR, + QUP_ERR_XFER_FAIL, + QUP_ERR_I2C_NACK, + QUP_ERR_I2C_INVALID_WRITE, + QUP_ERR_I2C_INVALID_TAG, + QUP_ERR_UNDEFINED, +} qup_return_t; + +typedef enum { + QUP_MINICORE_SPI = 1, + QUP_MINICORE_I2C_MASTER, + QUP_MINICORE_I2C_SLAVE +} qup_protocol_t; + +typedef enum { + QUP_MODE_FIFO = 0, + QUP_MODE_BLOCK, + QUP_MODE_DATAMOVER, +} qup_mode_t; + +typedef struct { + qup_protocol_t protocol; + unsigned int clk_frequency; + unsigned int src_frequency; + qup_mode_t mode; + unsigned int initialized; +} qup_config_t; + +typedef struct { + qup_protocol_t protocol; + union { + struct { + uint8_t addr; + uint8_t *data; + unsigned int data_len; + } iic; + struct { + void *in; + void *out; + unsigned int size; + } spi; + } p; +} qup_data_t; + +/* + * Initialize BLSP QUP block for FIFO I2C transfers. + * id[IN]: BLSP for which QUP is to be initialized. + * config_ptr[IN]: configurations parameters for the QUP. + * + * return: QUP_SUCCESS, if initialization succeeds. + */ +qup_return_t qup_init(blsp_qup_id_t id, const qup_config_t *config_ptr); + +/* + * Set QUP state to run, pause, reset. + * id[IN]: BLSP block for which QUP state is to be set. + * state[IN]: New state to transition to. + * + * return: QUP_SUCCESS, if state transition succeeds. + */ +qup_return_t qup_set_state(blsp_qup_id_t id, uint32_t state); + +/* + * Reset the status bits set during an i2c transfer. + * id[IN]: BLSP block for which i2c status bits are to be cleared. + * + * return: QUP_SUCCESS, if status bits are cleared successfully. + */ +qup_return_t qup_reset_i2c_master_status(blsp_qup_id_t id); + +/* + * Send data to the peripheral on the bus. + * id[IN]: BLSP block for which data is to be sent. + * p_tx_obj[IN]: Data to be sent to the slave on the bus. + * stop_seq[IN]: When set to non-zero QUP engine sends i2c stop sequnce. + * + * return: QUP_SUCCESS, when data is sent successfully to the peripheral. + */ +qup_return_t qup_send_data(blsp_qup_id_t id, qup_data_t *p_tx_obj, + uint8_t stop_seq); + +/* + * Receive data from peripheral on the bus. + * id[IN]: BLSP block from which data is to be received. + * p_tx_obj[IN]: length of data to be received, slave address. + * [OUT]: buffer filled with data from slave. + * + * return: QUP_SUCCESS, when data is received successfully. + */ +qup_return_t qup_recv_data(blsp_qup_id_t id, qup_data_t *p_tx_obj); + +#endif //__QUP_H__ diff --git a/src/soc/qualcomm/qcs405/include/soc/spi.h b/src/soc/qualcomm/qcs405/include/soc/spi.h new file mode 100644 index 00000000000..12f7fd97c7c --- /dev/null +++ b/src/soc/qualcomm/qcs405/include/soc/spi.h @@ -0,0 +1,210 @@ +/* + * Register definitions for the IPQ BLSP SPI Controller + * + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _QCS405_SPI_H_ +#define _QCS405_SPI_H_ + +#include +#include +#include + +#define BLSP0_QUP_REG_BASE ((void *)0x78b5000u) +#define BLSP4_QUP_REG_BASE ((void *)0x78b9000u) +#define BLSP5_QUP_REG_BASE ((void *)0x7af5000u) + +#define BLSP0_SPI_CONFIG_REG (BLSP0_QUP_REG_BASE + 0x00000300) +#define BLSP4_SPI_CONFIG_REG (BLSP4_QUP_REG_BASE + 0x00000300) +#define BLSP5_SPI_CONFIG_REG (BLSP5_QUP_REG_BASE + 0x00000300) + +#define BLSP0_SPI_IO_CONTROL_REG (BLSP0_QUP_REG_BASE + 0x00000304) +#define BLSP4_SPI_IO_CONTROL_REG (BLSP4_QUP_REG_BASE + 0x00000304) +#define BLSP5_SPI_IO_CONTROL_REG (BLSP5_QUP_REG_BASE + 0x00000304) + +#define BLSP0_SPI_ERROR_FLAGS_REG (BLSP0_QUP_REG_BASE + 0x00000308) +#define BLSP4_SPI_ERROR_FLAGS_REG (BLSP4_QUP_REG_BASE + 0x00000308) +#define BLSP5_SPI_ERROR_FLAGS_REG (BLSP5_QUP_REG_BASE + 0x00000308) + +#define BLSP0_SPI_DEASSERT_WAIT_REG (BLSP0_QUP_REG_BASE + 0x00000310) +#define BLSP4_SPI_DEASSERT_WAIT_REG (BLSP4_QUP_REG_BASE + 0x00000310) +#define BLSP5_SPI_DEASSERT_WAIT_REG (BLSP5_QUP_REG_BASE + 0x00000310) +#define BLSP0_SPI_ERROR_FLAGS_EN_REG (BLSP0_QUP_REG_BASE + 0x0000030c) +#define BLSP4_SPI_ERROR_FLAGS_EN_REG (BLSP4_QUP_REG_BASE + 0x0000030c) +#define BLSP5_SPI_ERROR_FLAGS_EN_REG (BLSP5_QUP_REG_BASE + 0x0000030c) + +#define BLSP0_QUP_CONFIG_REG (BLSP0_QUP_REG_BASE + 0x00000000) +#define BLSP4_QUP_CONFIG_REG (BLSP4_QUP_REG_BASE + 0x00000000) +#define BLSP5_QUP_CONFIG_REG (BLSP5_QUP_REG_BASE + 0x00000000) + +#define BLSP0_QUP_ERROR_FLAGS_REG (BLSP0_QUP_REG_BASE + 0x0000001c) +#define BLSP4_QUP_ERROR_FLAGS_REG (BLSP4_QUP_REG_BASE + 0x0000001c) +#define BLSP5_QUP_ERROR_FLAGS_REG (BLSP5_QUP_REG_BASE + 0x0000001c) + +#define BLSP0_QUP_ERROR_FLAGS_EN_REG (BLSP0_QUP_REG_BASE + 0x00000020) +#define BLSP4_QUP_ERROR_FLAGS_EN_REG (BLSP4_QUP_REG_BASE + 0x00000020) +#define BLSP5_QUP_ERROR_FLAGS_EN_REG (BLSP5_QUP_REG_BASE + 0x00000020) + +#define BLSP0_QUP_OPERATIONAL_MASK (BLSP0_QUP_REG_BASE + 0x00000028) +#define BLSP4_QUP_OPERATIONAL_MASK (BLSP4_QUP_REG_BASE + 0x00000028) +#define BLSP5_QUP_OPERATIONAL_MASK (BLSP5_QUP_REG_BASE + 0x00000028) + +#define BLSP0_QUP_OPERATIONAL_REG (BLSP0_QUP_REG_BASE + 0x00000018) +#define BLSP4_QUP_OPERATIONAL_REG (BLSP4_QUP_REG_BASE + 0x00000018) +#define BLSP5_QUP_OPERATIONAL_REG (BLSP5_QUP_REG_BASE + 0x00000018) + +#define BLSP0_QUP_IO_MODES_REG (BLSP0_QUP_REG_BASE + 0x00000008) +#define BLSP4_QUP_IO_MODES_REG (BLSP4_QUP_REG_BASE + 0x00000008) +#define BLSP5_QUP_IO_MODES_REG (BLSP5_QUP_REG_BASE + 0x00000008) + +#define BLSP0_QUP_STATE_REG (BLSP0_QUP_REG_BASE + 0x00000004) +#define BLSP4_QUP_STATE_REG (BLSP4_QUP_REG_BASE + 0x00000004) +#define BLSP5_QUP_STATE_REG (BLSP5_QUP_REG_BASE + 0x00000004) + +#define BLSP0_QUP_INPUT_FIFOc_REG(c) \ + (BLSP0_QUP_REG_BASE + 0x00000218 + 4 * (c)) +#define BLSP4_QUP_INPUT_FIFOc_REG(c) \ + (BLSP4_QUP_REG_BASE + 0x00000218 + 4 * (c)) +#define BLSP5_QUP_INPUT_FIFOc_REG(c) \ + (BLSP5_QUP_REG_BASE + 0x00000218 + 4 * (c)) + +#define BLSP0_QUP_OUTPUT_FIFOc_REG(c) \ + (BLSP0_QUP_REG_BASE + 0x00000110 + 4 * (c)) +#define BLSP4_QUP_OUTPUT_FIFOc_REG(c) \ + (BLSP4_QUP_REG_BASE + 0x00000110 + 4 * (c)) +#define BLSP5_QUP_OUTPUT_FIFOc_REG(c) \ + (BLSP5_QUP_REG_BASE + 0x00000110 + 4 * (c)) + +#define BLSP0_QUP_MX_INPUT_COUNT_REG (BLSP0_QUP_REG_BASE + 0x00000200) +#define BLSP4_QUP_MX_INPUT_COUNT_REG (BLSP4_QUP_REG_BASE + 0x00000200) +#define BLSP5_QUP_MX_INPUT_COUNT_REG (BLSP5_QUP_REG_BASE + 0x00000200) + +#define BLSP0_QUP_MX_OUTPUT_COUNT_REG (BLSP0_QUP_REG_BASE + 0x00000100) +#define BLSP4_QUP_MX_OUTPUT_COUNT_REG (BLSP4_QUP_REG_BASE + 0x00000100) +#define BLSP5_QUP_MX_OUTPUT_COUNT_REG (BLSP5_QUP_REG_BASE + 0x00000100) + +#define BLSP0_QUP_SW_RESET_REG (BLSP0_QUP_REG_BASE + 0x0000000c) +#define BLSP4_QUP_SW_RESET_REG (BLSP4_QUP_REG_BASE + 0x0000000c) +#define BLSP5_QUP_SW_RESET_REG (BLSP5_QUP_REG_BASE + 0x0000000c) + +#define QUP_CONFIG_MINI_CORE_MSK (0x0F << 8) +#define QUP_CONFIG_MINI_CORE_SPI (1 << 8) +#define QUP_CONF_INPUT_MSK (1 << 7) +#define QUP_CONF_INPUT_ENA (0 << 7) +#define QUP_CONF_NO_INPUT (1 << 7) +#define QUP_CONF_OUTPUT_MSK (1 << 6) +#define QUP_CONF_OUTPUT_ENA (0 << 6) +#define QUP_CONF_NO_OUTPUT (1 << 6) +#define QUP_CONF_N_MASK 0x1F +#define QUP_CONF_N_SPI_8_BIT_WORD 0x07 + +#define SPI_CONFIG_INPUT_FIRST (1 << 9) +#define SPI_CONFIG_INPUT_FIRST_BACK (0 << 9) +#define SPI_CONFIG_LOOP_BACK_MSK (1 << 8) +#define SPI_CONFIG_NO_LOOP_BACK (0 << 8) +#define SPI_CONFIG_NO_SLAVE_OPER_MSK (1 << 5) +#define SPI_CONFIG_NO_SLAVE_OPER (0 << 5) + +#define SPI_IO_CTRL_CLK_ALWAYS_ON (0 << 9) +#define SPI_IO_CTRL_MX_CS_MODE (1 << 8) +#define SPI_IO_CTRL_NO_TRI_STATE (1 << 0) +#define SPI_IO_CTRL_FORCE_CS_MSK (1 << 11) +#define SPI_IO_CTRL_FORCE_CS_EN (1 << 11) +#define SPI_IO_CTRL_FORCE_CS_DIS (0 << 11) +#define SPI_IO_CTRL_CLOCK_IDLE_HIGH (1 << 10) + +#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_MSK (1 << 16) +#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN (1 << 16) +#define QUP_IO_MODES_INPUT_MODE_MSK (0x03 << 12) +#define QUP_IO_MODES_INPUT_BLOCK_MODE (0x01 << 12) +#define QUP_IO_MODES_OUTPUT_MODE_MSK (0x03 << 10) +#define QUP_IO_MODES_OUTPUT_BLOCK_MODE (0x01 << 10) + +#define SPI_INPUT_BLOCK_SIZE 4 +#define SPI_OUTPUT_BLOCK_SIZE 4 + +#define MAX_COUNT_SIZE 0xffff + +#define SPI_CORE_RESET 0 +#define SPI_CORE_RUNNING 1 +#define SPI_MODE0 0 +#define SPI_MODE1 1 +#define SPI_MODE2 2 +#define SPI_MODE3 3 +#define BLSP0_SPI 0 +#define BLSP4_SPI 4 +#define BLSP5_SPI 5 + +struct blsp_spi { + void *spi_config; + void *io_control; + void *error_flags; + void *error_flags_en; + void *qup_config; + void *qup_error_flags; + void *qup_error_flags_en; + void *qup_operational; + void *qup_io_modes; + void *qup_state; + void *qup_input_fifo; + void *qup_output_fifo; + void *qup_mx_input_count; + void *qup_mx_output_count; + void *qup_sw_reset; + void *qup_ns_reg; + void *qup_md_reg; + void *qup_op_mask; + void *qup_deassert_wait; +}; + + +#define SUCCESS 0 + +#define DUMMY_DATA_VAL 0 +#define TIMEOUT_CNT 100 + +#define ETIMEDOUT -10 +#define EINVAL -11 +#define EIO -12 + +/* MX_INPUT_COUNT and MX_OUTPUT_COUNT are 16-bits. Zero has a special meaning + * (count function disabled) and does not hold significance in the count. */ +#define MAX_PACKET_COUNT ((64 * KiB) - 1) + + +struct qcs_spi_slave { + struct spi_slave slave; + const struct blsp_spi *regs; + unsigned int mode; + unsigned int initialized; + unsigned long freq; + int allocated; +}; + +#endif diff --git a/src/soc/qualcomm/qcs405/spi.c b/src/soc/qualcomm/qcs405/spi.c index c04b15d3c82..13b9daef9db 100644 --- a/src/soc/qualcomm/qcs405/spi.c +++ b/src/soc/qualcomm/qcs405/spi.c @@ -1,49 +1,783 @@ /* - * This file is part of the coreboot project. + * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. * - * Copyright (C) 2018, The Linux Foundation. All rights reserved. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 and - * only version 2 as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include + +static const struct blsp_spi spi_reg[] = { + /* BLSP0 registers for SPI interface */ + { + BLSP0_SPI_CONFIG_REG, + BLSP0_SPI_IO_CONTROL_REG, + BLSP0_SPI_ERROR_FLAGS_REG, + BLSP0_SPI_ERROR_FLAGS_EN_REG, + BLSP0_QUP_CONFIG_REG, + BLSP0_QUP_ERROR_FLAGS_REG, + BLSP0_QUP_ERROR_FLAGS_EN_REG, + BLSP0_QUP_OPERATIONAL_REG, + BLSP0_QUP_IO_MODES_REG, + BLSP0_QUP_STATE_REG, + BLSP0_QUP_INPUT_FIFOc_REG(0), + BLSP0_QUP_OUTPUT_FIFOc_REG(0), + BLSP0_QUP_MX_INPUT_COUNT_REG, + BLSP0_QUP_MX_OUTPUT_COUNT_REG, + BLSP0_QUP_SW_RESET_REG, + 0, + 0, + BLSP0_QUP_OPERATIONAL_MASK, + BLSP0_SPI_DEASSERT_WAIT_REG, + }, + {0}, {0}, {0}, + /* BLSP4 registers for SPI interface */ + { + BLSP4_SPI_CONFIG_REG, + BLSP4_SPI_IO_CONTROL_REG, + BLSP4_SPI_ERROR_FLAGS_REG, + BLSP4_SPI_ERROR_FLAGS_EN_REG, + BLSP4_QUP_CONFIG_REG, + BLSP4_QUP_ERROR_FLAGS_REG, + BLSP4_QUP_ERROR_FLAGS_EN_REG, + BLSP4_QUP_OPERATIONAL_REG, + BLSP4_QUP_IO_MODES_REG, + BLSP4_QUP_STATE_REG, + BLSP4_QUP_INPUT_FIFOc_REG(0), + BLSP4_QUP_OUTPUT_FIFOc_REG(0), + BLSP4_QUP_MX_INPUT_COUNT_REG, + BLSP4_QUP_MX_OUTPUT_COUNT_REG, + BLSP4_QUP_SW_RESET_REG, + 0, + 0, + BLSP4_QUP_OPERATIONAL_MASK, + BLSP4_SPI_DEASSERT_WAIT_REG, + }, + /* BLSP5 registers for SPI interface */ + { + BLSP5_SPI_CONFIG_REG, + BLSP5_SPI_IO_CONTROL_REG, + BLSP5_SPI_ERROR_FLAGS_REG, + BLSP5_SPI_ERROR_FLAGS_EN_REG, + BLSP5_QUP_CONFIG_REG, + BLSP5_QUP_ERROR_FLAGS_REG, + BLSP5_QUP_ERROR_FLAGS_EN_REG, + BLSP5_QUP_OPERATIONAL_REG, + BLSP5_QUP_IO_MODES_REG, + BLSP5_QUP_STATE_REG, + BLSP5_QUP_INPUT_FIFOc_REG(0), + BLSP5_QUP_OUTPUT_FIFOc_REG(0), + BLSP5_QUP_MX_INPUT_COUNT_REG, + BLSP5_QUP_MX_OUTPUT_COUNT_REG, + BLSP5_QUP_SW_RESET_REG, + 0, + 0, + BLSP5_QUP_OPERATIONAL_MASK, + BLSP5_SPI_DEASSERT_WAIT_REG, + }, +}; + +static int check_bit_state(void *reg_addr, int mask, + int val, int us_delay) +{ + unsigned int count = TIMEOUT_CNT; + + while ((read32(reg_addr) & mask) != val) { + count--; + if (count == 0) + return -ETIMEDOUT; + udelay(us_delay); + } + + return SUCCESS; +} + +/* + * Check whether QUPn State is valid + */ +static int check_qup_state_valid(struct qcs_spi_slave *ds) +{ + return check_bit_state(ds->regs->qup_state, QUP_STATE_VALID_MASK, + QUP_STATE_VALID, 1); +} + +/* + * Configure QUPn Core state + */ +static int config_spi_state(struct qcs_spi_slave *ds, unsigned int state) +{ + uint32_t val; + int ret = SUCCESS; + + ret = check_qup_state_valid(ds); + if (ret != SUCCESS) + return ret; + + switch (state) { + case QUP_STATE_RUN: + /* Set the state to RUN */ + val = ((read32(ds->regs->qup_state) & ~QUP_STATE_MASK) + | QUP_STATE_RUN); + write32(ds->regs->qup_state, val); + ret = check_qup_state_valid(ds); + break; + case QUP_STATE_RESET: + /* Set the state to RESET */ + val = ((read32(ds->regs->qup_state) & ~QUP_STATE_MASK) + | QUP_STATE_RESET); + write32(ds->regs->qup_state, val); + ret = check_qup_state_valid(ds); + break; + default: + printk(BIOS_ERR, "unsupported QUP SPI state : %d\n", state); + ret = -EINVAL; + break; + } + + return ret; +} + +/* + * Set QUPn SPI Mode + */ +static void spi_set_mode(struct qcs_spi_slave *ds, unsigned int mode) +{ + unsigned int clk_idle_state; + unsigned int input_first_mode; + uint32_t val; + + switch (mode) { + case SPI_MODE0: + clk_idle_state = 0; + input_first_mode = SPI_CONFIG_INPUT_FIRST; + break; + case SPI_MODE1: + clk_idle_state = 0; + input_first_mode = 0; + break; + case SPI_MODE2: + clk_idle_state = 1; + input_first_mode = SPI_CONFIG_INPUT_FIRST; + break; + case SPI_MODE3: + clk_idle_state = 1; + input_first_mode = 0; + break; + default: + printk(BIOS_ERR, "unsupported spi mode : %d\n", mode); + return; + } + + val = read32(ds->regs->spi_config); + val |= input_first_mode; + write32(ds->regs->spi_config, val); + val = read32(ds->regs->io_control); + + if (clk_idle_state) + val |= SPI_IO_CTRL_CLOCK_IDLE_HIGH; + else + val &= ~SPI_IO_CTRL_CLOCK_IDLE_HIGH; + + write32(ds->regs->io_control, val); +} + +/* + * Reset entire QUP and all mini cores + */ +static void spi_reset(struct qcs_spi_slave *ds) +{ + write32(ds->regs->qup_sw_reset, 0x1); + udelay(5); + check_qup_state_valid(ds); +} + +static struct qcs_spi_slave spi_slave_pool[3]; + +static struct qcs_spi_slave *to_qcs_spi(const struct spi_slave *slave) +{ + struct qcs_spi_slave *ds; + size_t i; + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + ds = spi_slave_pool + i; + + if (!ds->allocated) + continue; + + if ((ds->slave.bus == slave->bus) && + (ds->slave.cs == slave->cs)) + return ds; + } + + return NULL; +} + +static void write_force_cs(const struct spi_slave *slave, int assert) +{ + struct qcs_spi_slave *ds = to_qcs_spi(slave); + if (assert) + clrsetbits_le32(ds->regs->io_control, + SPI_IO_CTRL_FORCE_CS_MSK, SPI_IO_CTRL_FORCE_CS_EN); + else + clrsetbits_le32(ds->regs->io_control, + SPI_IO_CTRL_FORCE_CS_MSK, SPI_IO_CTRL_FORCE_CS_DIS); +} + +/* + * BLSP QUPn SPI Hardware Initialisation + */ +static int spi_hw_init(struct qcs_spi_slave *ds) +{ + int ret; + + ds->initialized = 0; + + /* QUPn module configuration */ + spi_reset(ds); + + /* Set the QUPn state */ + ret = config_spi_state(ds, QUP_STATE_RESET); + if (ret) + return ret; + + /* + * Configure Mini core to SPI core with Input Output enabled, + * SPI master, N = 8 bits + */ + clrsetbits_le32(ds->regs->qup_config, QUP_CONFIG_MINI_CORE_MSK | + QUP_CONF_INPUT_MSK | + QUP_CONF_OUTPUT_MSK | + QUP_CONF_N_MASK, + QUP_CONFIG_MINI_CORE_SPI | + QUP_CONF_INPUT_ENA | + QUP_CONF_OUTPUT_ENA | + QUP_CONF_N_SPI_8_BIT_WORD); + + /* + * Configure Input first SPI protocol, + * SPI master mode and no loopback + */ + clrsetbits_le32(ds->regs->spi_config, SPI_CONFIG_LOOP_BACK_MSK | + SPI_CONFIG_NO_SLAVE_OPER_MSK, + SPI_CONFIG_NO_LOOP_BACK | + SPI_CONFIG_NO_SLAVE_OPER); + + /* + * Configure SPI IO Control Register + * CLK_ALWAYS_ON = 0 + * MX_CS_MODE = 0 + * NO_TRI_STATE = 1 + */ + write32(ds->regs->io_control, SPI_IO_CTRL_CLK_ALWAYS_ON | + SPI_IO_CTRL_NO_TRI_STATE | SPI_IO_CTRL_MX_CS_MODE); + + /* + * Configure SPI IO Modes. + * OUTPUT_BIT_SHIFT_EN = 1 + * INPUT_MODE = Block Mode + * OUTPUT MODE = Block Mode + */ + clrsetbits_le32(ds->regs->qup_io_modes, + QUP_IO_MODES_OUTPUT_BIT_SHIFT_MSK | + QUP_IO_MODES_INPUT_MODE_MSK | + QUP_IO_MODES_OUTPUT_MODE_MSK, + QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN | + QUP_IO_MODES_INPUT_BLOCK_MODE | + QUP_IO_MODES_OUTPUT_BLOCK_MODE); + + spi_set_mode(ds, ds->mode); + + /* Disable Error mask */ + write32(ds->regs->error_flags_en, 0); + write32(ds->regs->qup_error_flags_en, 0); + write32(ds->regs->qup_deassert_wait, 0); + + ds->initialized = 1; + + return SUCCESS; +} static int spi_ctrlr_claim_bus(const struct spi_slave *slave) { - return 0; + struct qcs_spi_slave *ds = to_qcs_spi(slave); + unsigned int ret; + + ret = spi_hw_init(ds); + if (ret) + return -EIO; + switch (slave->bus) { + case 4: + gpio_configure + (GPIO(37), 2, GPIO_PULL_DOWN, GPIO_6MA, GPIO_INPUT); // MOSI + gpio_configure + (GPIO(38), 2, GPIO_PULL_DOWN, GPIO_6MA, GPIO_OUTPUT); // MISO + gpio_configure + (GPIO(117), 2, GPIO_NO_PULL, GPIO_6MA, GPIO_OUTPUT); // CS + gpio_configure + (GPIO(118), 2, GPIO_PULL_DOWN, GPIO_6MA, GPIO_OUTPUT);// CLK + break; + case 5: + gpio_configure + (GPIO(26), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); // MOSI + gpio_configure + (GPIO(27), 3, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); // MISO + gpio_configure + (GPIO(28), 4, GPIO_PULL_UP, GPIO_16MA, GPIO_INPUT); // CS + gpio_configure + (GPIO(29), 4, GPIO_NO_PULL, GPIO_16MA, GPIO_INPUT); // CLK + break; + default: + printk(BIOS_ERR, "SPI error: unsupported bus %d " + "(Supported buses 0, 1, 2, 3, 4, 5)\n", slave->bus); + break; + } + write_force_cs(slave, 1); + + return SUCCESS; } static void spi_ctrlr_release_bus(const struct spi_slave *slave) { + struct qcs_spi_slave *ds = to_qcs_spi(slave); + /* Reset the SPI hardware */ + write_force_cs(slave, 0); + spi_reset(ds); + ds->initialized = 0; } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t bytes_out, void *din, size_t bytes_in) +/* + * Function to write data to OUTPUT FIFO + */ +static void spi_write_byte(struct qcs_spi_slave *ds, unsigned char data) +{ + /* Wait for space in the FIFO */ + while ((read32(ds->regs->qup_operational) & OUTPUT_FIFO_FULL)) + udelay(1); + + /* Write the byte of data */ + write32(ds->regs->qup_output_fifo, data); +} + +/* + * Function to read data from Input FIFO + */ +static unsigned char spi_read_byte(struct qcs_spi_slave *ds) +{ + /* Wait for Data in FIFO */ + while (!(read32(ds->regs->qup_operational) & INPUT_FIFO_NOT_EMPTY)) + udelay(1); + + /* Read a byte of data */ + return read32(ds->regs->qup_input_fifo) & 0xff; +} + +/* + * Function to check wheather Input or Output FIFO + * has data to be serviced + */ +static int check_fifo_status(void *reg_addr) +{ + unsigned int count = TIMEOUT_CNT; + unsigned int status_flag; + unsigned int val; + + do { + val = read32(reg_addr); + count--; + if (count == 0) + return -ETIMEDOUT; + status_flag = ((val & OUTPUT_SERVICE_FLAG) | + (val & INPUT_SERVICE_FLAG)); + } while (!status_flag); + + return SUCCESS; +} + +/* + * Function to configure Input and Output enable/disable + */ +static void enable_io_config(struct qcs_spi_slave *ds, + uint32_t write_cnt, uint32_t read_cnt) +{ + + if (write_cnt) { + clrsetbits_le32(ds->regs->qup_config, + QUP_CONF_OUTPUT_MSK, QUP_CONF_OUTPUT_ENA); + } else { + clrsetbits_le32(ds->regs->qup_config, + QUP_CONF_OUTPUT_MSK, QUP_CONF_NO_OUTPUT); + } + + if (read_cnt) { + clrsetbits_le32(ds->regs->qup_config, + QUP_CONF_INPUT_MSK, QUP_CONF_INPUT_ENA); + } else { + clrsetbits_le32(ds->regs->qup_config, + QUP_CONF_INPUT_MSK, QUP_CONF_NO_INPUT); + } +} + +/* + * Function to read bytes number of data from the Input FIFO + */ +static int __blsp_spi_read(struct qcs_spi_slave *ds, u8 *data_buffer, + unsigned int bytes) +{ + uint32_t val; + unsigned int i; + unsigned int fifo_count; + int ret = SUCCESS; + int state_config; + struct stopwatch sw; + + /* Configure no of bytes to read */ + state_config = config_spi_state(ds, QUP_STATE_RESET); + if (state_config) + return state_config; + + /* Configure input and output enable */ + enable_io_config(ds, 0, bytes); + + write32(ds->regs->qup_mx_input_count, bytes); + + state_config = config_spi_state(ds, QUP_STATE_RUN); + if (state_config) + return state_config; + + while (bytes) { + ret = check_fifo_status(ds->regs->qup_operational); + if (ret != SUCCESS) + goto out; + + val = read32(ds->regs->qup_operational); + if (val & INPUT_SERVICE_FLAG) { + /* + * acknowledge to hw that software will + * read input data + */ + val &= INPUT_SERVICE_FLAG; + write32(ds->regs->qup_operational, val); + + fifo_count = ((bytes > SPI_INPUT_BLOCK_SIZE) ? + SPI_INPUT_BLOCK_SIZE : bytes); + + for (i = 0; i < fifo_count; i++) { + *data_buffer = spi_read_byte(ds); + data_buffer++; + bytes--; + } + } + } + + stopwatch_init_msecs_expire(&sw, 10); + + do { + val = read32(ds->regs->qup_operational); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "SPI FIFO read timeout\n"); + ret = -ETIMEDOUT; + goto out; + } + } while (!(val & MAX_INPUT_DONE_FLAG)); + +out: + /* + * Put the SPI Core back in the Reset State + * to end the transfer + */ + (void)config_spi_state(ds, QUP_STATE_RESET); + return ret; +} + +static int blsp_spi_read(struct qcs_spi_slave *ds, u8 *data_buffer, + unsigned int bytes) { + int length, ret; + + while (bytes) { + length = (bytes < MAX_COUNT_SIZE) ? bytes : MAX_COUNT_SIZE; + + ret = __blsp_spi_read(ds, data_buffer, length); + if (ret != SUCCESS) + return ret; + + data_buffer += length; + bytes -= length; + } + return 0; } +/* + * Function to write data to the Output FIFO + */ +static int __blsp_spi_write(struct qcs_spi_slave *ds, const u8 *cmd_buffer, + unsigned int bytes) +{ + uint32_t val; + unsigned int i; + unsigned int write_len = bytes; + unsigned int read_len = bytes; + unsigned int fifo_count; + int ret = SUCCESS; + int state_config; + struct stopwatch sw; + + state_config = config_spi_state(ds, QUP_STATE_RESET); + if (state_config) + return state_config; + + /* Configure input and output enable */ + enable_io_config(ds, write_len, read_len); + /* No of bytes to be written in Output FIFO */ + write32(ds->regs->qup_mx_output_count, bytes); + write32(ds->regs->qup_mx_input_count, bytes); + state_config = config_spi_state(ds, QUP_STATE_RUN); + + if (state_config) + return state_config; + + /* + * read_len considered to ensure that we read the dummy data for the + * write we performed. This is needed to ensure with WR-RD transaction + * to get the actual data on the subsequent read cycle that happens + */ + while (write_len || read_len) { + ret = check_fifo_status(ds->regs->qup_operational); + if (ret != SUCCESS) + goto out; + + val = read32(ds->regs->qup_operational); + if (val & OUTPUT_SERVICE_FLAG) { + /* + * acknowledge to hw that software will write + * expected output data + */ + val &= OUTPUT_SERVICE_FLAG; + write32(ds->regs->qup_operational, val); + + if (write_len > SPI_OUTPUT_BLOCK_SIZE) + fifo_count = SPI_OUTPUT_BLOCK_SIZE; + else + fifo_count = write_len; + + for (i = 0; i < fifo_count; i++) { + /* Write actual data to output FIFO */ + spi_write_byte(ds, *cmd_buffer); + cmd_buffer++; + write_len--; + } + } + + if (val & INPUT_SERVICE_FLAG) { + /* + * acknowledge to hw that software + * will read input data + */ + val &= INPUT_SERVICE_FLAG; + write32(ds->regs->qup_operational, val); + + if (read_len > SPI_INPUT_BLOCK_SIZE) + fifo_count = SPI_INPUT_BLOCK_SIZE; + else + fifo_count = read_len; + + for (i = 0; i < fifo_count; i++) { + /* Read dummy data for the data written */ + (void)spi_read_byte(ds); + + /* Decrement the read count after reading the + * dummy data from the device. This is to make + * sure we read dummy data before we write the + * data to fifo + */ + read_len--; + } + } + } + + stopwatch_init_msecs_expire(&sw, 10); + + do { + val = read32(ds->regs->qup_operational); + if (stopwatch_expired(&sw)) { + printk(BIOS_ERR, "SPI FIFO write timeout\n"); + ret = -ETIMEDOUT; + goto out; + } + + } while (!(val & MAX_OUTPUT_DONE_FLAG)); + +out: + /* + * Put the SPI Core back in the Reset State + * to end the transfer + */ + (void)config_spi_state(ds, QUP_STATE_RESET); + + return ret; +} + +static int blsp_spi_write(struct qcs_spi_slave *ds, u8 *cmd_buffer, + unsigned int bytes) +{ + int length, ret; + + while (bytes) { + length = (bytes < MAX_COUNT_SIZE) ? bytes : MAX_COUNT_SIZE; + + ret = __blsp_spi_write(ds, cmd_buffer, length); + if (ret != SUCCESS) { + printk(BIOS_ERR, "SPI:DBG write not success\n"); + return ret; + } + + cmd_buffer += length; + bytes -= length; + } + + return 0; +} + +/* + * This function is invoked with either tx_buf or rx_buf. + * Calling this function with both null does a chip select change. + */ +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t out_bytes, void *din, size_t in_bytes) +{ + struct qcs_spi_slave *ds = to_qcs_spi(slave); + u8 *txp = (u8 *)dout; + u8 *rxp = (u8 *)din; + int ret; + + ret = config_spi_state(ds, QUP_STATE_RESET); + if (ret != SUCCESS) + return ret; + + if (dout != NULL) { + ret = blsp_spi_write(ds, txp, (unsigned int) out_bytes); + if (ret != SUCCESS) + goto out; + } + + if (din != NULL) { + ret = blsp_spi_read(ds, rxp, in_bytes); + if (ret != SUCCESS) + goto out; + } + +out: + /* + * Put the SPI Core back in the Reset State + * to end the transfer + */ + (void)config_spi_state(ds, QUP_STATE_RESET); + + return ret; +} + +static int spi_ctrlr_setup(const struct spi_slave *slave) +{ + struct qcs_spi_slave *ds = NULL; + int i; + unsigned int bus = slave->bus; + unsigned int cs = slave->cs; + int qup = 0; + int blsp = 2; + + if (((bus != BLSP4_SPI) && (bus != BLSP5_SPI)) || cs != 0) { + printk(BIOS_ERR, + "SPI error: unsupported bus %d or cs %d\n", bus, cs); + return -1; + } + + for (i = 0; i < ARRAY_SIZE(spi_slave_pool); i++) { + if (spi_slave_pool[i].allocated) + continue; + ds = spi_slave_pool + i; + ds->slave.bus = bus; + ds->slave.cs = cs; + ds->regs = &spi_reg[bus]; + ds->mode = SPI_MODE0; + ds->freq = 50000000; + + if (bus == BLSP4_SPI) { + ds->freq = 1000000; + qup = 4; + blsp = 1; + } + + clock_configure_spi(blsp, qup, ds->freq); + clock_enable_spi(blsp, qup); + + ds->allocated = 1; + + return 0; + } + + printk(BIOS_ERR, "SPI error: all %d pools busy\n", i); + return -1; +} + +static int xfer_vectors(const struct spi_slave *slave, + struct spi_op vectors[], size_t count) +{ + return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); +} + static const struct spi_ctrlr spi_ctrlr = { + .setup = spi_ctrlr_setup, .claim_bus = spi_ctrlr_claim_bus, .release_bus = spi_ctrlr_release_bus, .xfer = spi_ctrlr_xfer, - .max_xfer_size = 65535, + .xfer_vector = xfer_vectors, + .max_xfer_size = MAX_PACKET_COUNT, }; const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { { .ctrlr = &spi_ctrlr, - .bus_start = 0, - .bus_end = 0, + .bus_start = BLSP5_SPI, + .bus_end = BLSP5_SPI, + }, + { + .ctrlr = &spi_ctrlr, + .bus_start = BLSP4_SPI, + .bus_end = BLSP4_SPI, }, }; From 06cfb21e243ec74660e4886cef2f2e9c6c755d9e Mon Sep 17 00:00:00 2001 From: Roy Mingi Park Date: Mon, 3 Jun 2019 16:11:25 -0700 Subject: [PATCH 574/588] mb/google/sarien: Fix SSD's power off sequence before going to S5 BUG=b:133389422 TEST=check SSD's power off sequence to meet PCIE requirement. SSD's reset should be cleared before clearing SSD's power EN Pin. Change-Id: Ia106b805deafb8a442b56bcce91b51135cb32988 Signed-off-by: Roy Mingi Park Reviewed-on: https://review.coreboot.org/c/coreboot/+/33182 Reviewed-by: EricR Lai Reviewed-by: Duncan Laurie Tested-by: build bot (Jenkins) --- .../sarien/variants/arcada/include/variant/acpi/mainboard.asl | 3 ++- .../sarien/variants/sarien/include/variant/acpi/mainboard.asl | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl index 6eba2bcb21d..4b05ba8e908 100644 --- a/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/arcada/include/variant/acpi/mainboard.asl @@ -40,8 +40,9 @@ Method (MPTS, 1) /* Clear SSD EN adn RST pin to avoid leakage */ If (Arg0 == 5) { - \_SB.PCI0.CTXS (SSD_EN) \_SB.PCI0.CTXS (SSD_RST) + Sleep(1) + \_SB.PCI0.CTXS (SSD_EN) } } diff --git a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl index 6eba2bcb21d..4b05ba8e908 100644 --- a/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl +++ b/src/mainboard/google/sarien/variants/sarien/include/variant/acpi/mainboard.asl @@ -40,8 +40,9 @@ Method (MPTS, 1) /* Clear SSD EN adn RST pin to avoid leakage */ If (Arg0 == 5) { - \_SB.PCI0.CTXS (SSD_EN) \_SB.PCI0.CTXS (SSD_RST) + Sleep(1) + \_SB.PCI0.CTXS (SSD_EN) } } From fbf380abac431b3b93ea180ee928b6b8f8dd8182 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Thu, 10 Jan 2019 22:56:15 +0100 Subject: [PATCH 575/588] mb/*/devicetree.cb: Remove unavailable PCIe ports Some variants only support 4 PCIe ports so there is no need to have those unavailable ports in the devicetree. Change-Id: I154cae358fb7f862fc0c8eaa620474b37b5e6484 Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/30821 Reviewed-by: Felix Held Reviewed-by: Angel Pons Tested-by: build bot (Jenkins) --- src/mainboard/asrock/g41c-gs/variants/g41c-gs-r2/devicetree.cb | 2 -- src/mainboard/asrock/g41c-gs/variants/g41m-gs/devicetree.cb | 2 -- src/mainboard/asrock/g41c-gs/variants/g41m-s3/devicetree.cb | 2 -- src/mainboard/asrock/g41c-gs/variants/g41m-vs3-r2/devicetree.cb | 2 -- src/mainboard/asus/p5gc-mx/devicetree.cb | 2 -- src/mainboard/foxconn/g41s-k/devicetree.cb | 2 -- src/mainboard/gigabyte/ga-g41m-es2l/devicetree.cb | 2 -- src/mainboard/intel/d945gclf/devicetree.cb | 2 -- src/mainboard/intel/dg41wv/devicetree.cb | 2 -- src/mainboard/lenovo/thinkcentre_a58/devicetree.cb | 2 -- 10 files changed, 20 deletions(-) diff --git a/src/mainboard/asrock/g41c-gs/variants/g41c-gs-r2/devicetree.cb b/src/mainboard/asrock/g41c-gs/variants/g41c-gs-r2/devicetree.cb index 833ea00ad72..156fe3fd649 100644 --- a/src/mainboard/asrock/g41c-gs/variants/g41c-gs-r2/devicetree.cb +++ b/src/mainboard/asrock/g41c-gs/variants/g41c-gs-r2/devicetree.cb @@ -62,8 +62,6 @@ chip northbridge/intel/x4x # Northbridge device pci 1c.1 on end # PCIe 2 device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x1849 0x27c8 end diff --git a/src/mainboard/asrock/g41c-gs/variants/g41m-gs/devicetree.cb b/src/mainboard/asrock/g41c-gs/variants/g41m-gs/devicetree.cb index 63bcbc8d395..ba2f00d1ec8 100644 --- a/src/mainboard/asrock/g41c-gs/variants/g41m-gs/devicetree.cb +++ b/src/mainboard/asrock/g41c-gs/variants/g41m-gs/devicetree.cb @@ -57,8 +57,6 @@ chip northbridge/intel/x4x # Northbridge device pci 1c.1 on end # PCIe 2 device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x1849 0x27c8 end diff --git a/src/mainboard/asrock/g41c-gs/variants/g41m-s3/devicetree.cb b/src/mainboard/asrock/g41c-gs/variants/g41m-s3/devicetree.cb index 971eebd7c08..45a20142f4e 100644 --- a/src/mainboard/asrock/g41c-gs/variants/g41m-s3/devicetree.cb +++ b/src/mainboard/asrock/g41c-gs/variants/g41m-s3/devicetree.cb @@ -59,8 +59,6 @@ chip northbridge/intel/x4x # Northbridge end device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x1849 0x27c8 end diff --git a/src/mainboard/asrock/g41c-gs/variants/g41m-vs3-r2/devicetree.cb b/src/mainboard/asrock/g41c-gs/variants/g41m-vs3-r2/devicetree.cb index 4c910c5f766..b458115134c 100644 --- a/src/mainboard/asrock/g41c-gs/variants/g41m-vs3-r2/devicetree.cb +++ b/src/mainboard/asrock/g41c-gs/variants/g41m-vs3-r2/devicetree.cb @@ -56,8 +56,6 @@ chip northbridge/intel/x4x # Northbridge device pci 1c.1 on end # PCIe 2 (ethernet) device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x1849 0x27c8 end diff --git a/src/mainboard/asus/p5gc-mx/devicetree.cb b/src/mainboard/asus/p5gc-mx/devicetree.cb index 642f1ee0097..2f7d2781d73 100644 --- a/src/mainboard/asus/p5gc-mx/devicetree.cb +++ b/src/mainboard/asus/p5gc-mx/devicetree.cb @@ -64,8 +64,6 @@ chip northbridge/intel/i945 device pci 1c.1 on end # PCIe device pci 1c.2 off end # PCIe port 3 device pci 1c.3 off end # PCIe port 4 - device pci 1c.4 off end # PCIe port 5 - device pci 1c.5 off end # PCIe port 6 device pci 1d.0 on # USB UHCI ioapic_irq 2 INTA 0x10 end diff --git a/src/mainboard/foxconn/g41s-k/devicetree.cb b/src/mainboard/foxconn/g41s-k/devicetree.cb index bf940b46aad..ca952ba7c6e 100644 --- a/src/mainboard/foxconn/g41s-k/devicetree.cb +++ b/src/mainboard/foxconn/g41s-k/devicetree.cb @@ -57,8 +57,6 @@ chip northbridge/intel/x4x # Northbridge end device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on end # USB device pci 1d.1 on end # USB device pci 1d.2 on end # USB diff --git a/src/mainboard/gigabyte/ga-g41m-es2l/devicetree.cb b/src/mainboard/gigabyte/ga-g41m-es2l/devicetree.cb index 05edb278d97..8b47c4f21f9 100644 --- a/src/mainboard/gigabyte/ga-g41m-es2l/devicetree.cb +++ b/src/mainboard/gigabyte/ga-g41m-es2l/devicetree.cb @@ -63,8 +63,6 @@ chip northbridge/intel/x4x # Northbridge end device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x1458 0x5004 end diff --git a/src/mainboard/intel/d945gclf/devicetree.cb b/src/mainboard/intel/d945gclf/devicetree.cb index 90c517fb90e..716654c6eb6 100644 --- a/src/mainboard/intel/d945gclf/devicetree.cb +++ b/src/mainboard/intel/d945gclf/devicetree.cb @@ -59,8 +59,6 @@ chip northbridge/intel/i945 device pci 1c.1 off end # PCIe port 2 device pci 1c.2 on end # PCIe port 3 device pci 1c.3 on end # PCIe port 4 - device pci 1c.4 off end # PCIe port 5 - device pci 1c.5 off end # PCIe port 6 device pci 1d.0 on end # USB UHCI device pci 1d.1 on end # USB UHCI device pci 1d.2 on end # USB UHCI diff --git a/src/mainboard/intel/dg41wv/devicetree.cb b/src/mainboard/intel/dg41wv/devicetree.cb index d96ad9541c9..be28763a004 100644 --- a/src/mainboard/intel/dg41wv/devicetree.cb +++ b/src/mainboard/intel/dg41wv/devicetree.cb @@ -77,8 +77,6 @@ chip northbridge/intel/x4x # Northbridge end device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on # USB subsystemid 0x8086 0x5756 end diff --git a/src/mainboard/lenovo/thinkcentre_a58/devicetree.cb b/src/mainboard/lenovo/thinkcentre_a58/devicetree.cb index f3f56cec1fb..cc3ef49f25a 100644 --- a/src/mainboard/lenovo/thinkcentre_a58/devicetree.cb +++ b/src/mainboard/lenovo/thinkcentre_a58/devicetree.cb @@ -55,8 +55,6 @@ chip northbridge/intel/x4x # Northbridge end device pci 1c.2 off end # PCIe 3 device pci 1c.3 off end # PCIe 4 - device pci 1c.4 off end # PCIe 5 - device pci 1c.5 off end # PCIe 6 device pci 1d.0 on end # USB device pci 1d.1 on end # USB device pci 1d.2 on end # USB From 742df5ad34c0ad4d2bae2373ace6440c4cb6b792 Mon Sep 17 00:00:00 2001 From: Arthur Heymans Date: Mon, 3 Jun 2019 16:24:41 +0200 Subject: [PATCH 576/588] sb/intel/i82801gx: Include chip.h directly Change-Id: I3d743e90444292be687999ab4f50aa89d514fbad Signed-off-by: Arthur Heymans Reviewed-on: https://review.coreboot.org/c/coreboot/+/33171 Reviewed-by: Felix Held Reviewed-by: Angel Pons Reviewed-by: HAOUAS Elyes Tested-by: build bot (Jenkins) --- src/mainboard/lenovo/t60/mainboard.c | 1 + src/mainboard/lenovo/x60/mainboard.c | 1 + src/mainboard/lenovo/z61t/mainboard.c | 1 + src/southbridge/intel/i82801gx/i82801gx.h | 1 - src/southbridge/intel/i82801gx/ide.c | 1 + src/southbridge/intel/i82801gx/lpc.c | 1 + src/southbridge/intel/i82801gx/pcie.c | 1 + src/southbridge/intel/i82801gx/sata.c | 1 + 8 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mainboard/lenovo/t60/mainboard.c b/src/mainboard/lenovo/t60/mainboard.c index 2d998fbaa2b..b78d862d417 100644 --- a/src/mainboard/lenovo/t60/mainboard.c +++ b/src/mainboard/lenovo/t60/mainboard.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/src/mainboard/lenovo/x60/mainboard.c b/src/mainboard/lenovo/x60/mainboard.c index 274a15113a8..964e9c0b529 100644 --- a/src/mainboard/lenovo/x60/mainboard.c +++ b/src/mainboard/lenovo/x60/mainboard.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "dock.h" #include #include diff --git a/src/mainboard/lenovo/z61t/mainboard.c b/src/mainboard/lenovo/z61t/mainboard.c index 886b4fb4035..5f599465a14 100644 --- a/src/mainboard/lenovo/z61t/mainboard.c +++ b/src/mainboard/lenovo/z61t/mainboard.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/src/southbridge/intel/i82801gx/i82801gx.h b/src/southbridge/intel/i82801gx/i82801gx.h index a91ffc500b5..e44fcf51231 100644 --- a/src/southbridge/intel/i82801gx/i82801gx.h +++ b/src/southbridge/intel/i82801gx/i82801gx.h @@ -36,7 +36,6 @@ #if !defined(__ASSEMBLER__) #if !defined(__PRE_RAM__) -#include "chip.h" #if !defined(__SIMPLE_DEVICE__) void i82801gx_enable(struct device *dev); #endif diff --git a/src/southbridge/intel/i82801gx/ide.c b/src/southbridge/intel/i82801gx/ide.c index a36237228c6..672ee432fd7 100644 --- a/src/southbridge/intel/i82801gx/ide.c +++ b/src/southbridge/intel/i82801gx/ide.c @@ -19,6 +19,7 @@ #include #include #include +#include "chip.h" #include "i82801gx.h" typedef struct southbridge_intel_i82801gx_config config_t; diff --git a/src/southbridge/intel/i82801gx/lpc.c b/src/southbridge/intel/i82801gx/lpc.c index 948b6aa7f78..846a70997be 100644 --- a/src/southbridge/intel/i82801gx/lpc.c +++ b/src/southbridge/intel/i82801gx/lpc.c @@ -34,6 +34,7 @@ #include #include +#include "chip.h" #include "i82801gx.h" #include "nvs.h" diff --git a/src/southbridge/intel/i82801gx/pcie.c b/src/southbridge/intel/i82801gx/pcie.c index 3e5dbc3e872..0946a9aadf3 100644 --- a/src/southbridge/intel/i82801gx/pcie.c +++ b/src/southbridge/intel/i82801gx/pcie.c @@ -19,6 +19,7 @@ #include #include #include +#include "chip.h" #include "i82801gx.h" /* Low Power variant has 6 root ports. */ diff --git a/src/southbridge/intel/i82801gx/sata.c b/src/southbridge/intel/i82801gx/sata.c index 8514b6d3bf3..b657513dcf3 100644 --- a/src/southbridge/intel/i82801gx/sata.c +++ b/src/southbridge/intel/i82801gx/sata.c @@ -20,6 +20,7 @@ #include #include #include +#include "chip.h" #include "i82801gx.h" #include "sata.h" From 2ba303e49d03b3e0a77a6b2adde07e38a3aa5c1a Mon Sep 17 00:00:00 2001 From: John Zhao Date: Tue, 28 May 2019 16:48:14 -0700 Subject: [PATCH 577/588] src/arch/x86: Prevent attack on null pointer dereference Clang Static Analyzer version 8.0.0 detects null pointer argument in call to memory copy function. Add sanity check for pointer header to prevent null pointer dereference. TEST=Built and boot up to kernel. Change-Id: I7027b7cae3009a5481048bfa0536a6cbd9bef683 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/33051 Tested-by: build bot (Jenkins) Reviewed-by: Lance Zhao Reviewed-by: Felix Held --- src/arch/x86/acpi.c | 53 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/src/arch/x86/acpi.c b/src/arch/x86/acpi.c index d1dcd036527..bf9813cbfe2 100644 --- a/src/arch/x86/acpi.c +++ b/src/arch/x86/acpi.c @@ -218,6 +218,9 @@ void acpi_create_madt(acpi_madt_t *madt) memset((void *)madt, 0, sizeof(acpi_madt_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "APIC", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -248,6 +251,9 @@ void acpi_create_mcfg(acpi_mcfg_t *mcfg) memset((void *)mcfg, 0, sizeof(acpi_mcfg_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "MCFG", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -302,6 +308,9 @@ static void acpi_create_tcpa(acpi_tcpa_t *tcpa) if (!lasa) return; + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "TCPA", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -361,6 +370,9 @@ static void acpi_create_tpm2(acpi_tpm2_t *tpm2) if (!lasa) tpm2_log_len = 0; + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "TPM2", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -481,6 +493,9 @@ void acpi_create_srat(acpi_srat_t *srat, memset((void *)srat, 0, sizeof(acpi_srat_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "SRAT", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -508,6 +523,9 @@ void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, memset((void *)dmar, 0, sizeof(acpi_dmar_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "DMAR", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -669,6 +687,9 @@ void acpi_create_slit(acpi_slit_t *slit, memset((void *)slit, 0, sizeof(acpi_slit_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "SLIT", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -694,6 +715,9 @@ void acpi_create_hpet(acpi_hpet_t *hpet) memset((void *)hpet, 0, sizeof(acpi_hpet_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "HPET", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -728,6 +752,9 @@ void acpi_create_vfct(struct device *device, memset((void *)vfct, 0, sizeof(struct acpi_vfct)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "VFCT", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -754,6 +781,9 @@ void acpi_create_ivrs(acpi_ivrs_t *ivrs, memset((void *)ivrs, 0, sizeof(acpi_ivrs_t)); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "IVRS", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -807,6 +837,10 @@ void acpi_create_dbg2(acpi_dbg2_header_t *dbg2, current = (uintptr_t)dbg2; memset(dbg2, 0, sizeof(acpi_dbg2_header_t)); header = &(dbg2->header); + + if (!header) + return; + header->revision = get_acpi_table_revision(DBG2); memcpy(header->signature, "DBG2", 4); memcpy(header->oem_id, OEM_ID, 6); @@ -926,6 +960,9 @@ static void acpi_write_rsdt(acpi_rsdt_t *rsdt, char *oem_id, char *oem_table_id) { acpi_header_t *header = &(rsdt->header); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "RSDT", 4); memcpy(header->oem_id, oem_id, 6); @@ -946,6 +983,9 @@ static void acpi_write_xsdt(acpi_xsdt_t *xsdt, char *oem_id, char *oem_table_id) { acpi_header_t *header = &(xsdt->header); + if (!header) + return; + /* Fill out header fields. */ memcpy(header->signature, "XSDT", 4); memcpy(header->oem_id, oem_id, 6); @@ -1046,7 +1086,8 @@ unsigned long acpi_create_hest_error_source(acpi_hest_t *hest, memcpy(pos, data, data_len); len += data_len; - header->length += len; + if (header) + header->length += len; return len; } @@ -1059,6 +1100,9 @@ void acpi_write_hest(acpi_hest_t *hest, memset(hest, 0, sizeof(acpi_hest_t)); + if (!header) + return; + memcpy(header->signature, "HEST", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); @@ -1080,6 +1124,9 @@ void acpi_write_bert(acpi_bert_t *bert, uintptr_t region, size_t length) memset(bert, 0, sizeof(acpi_bert_t)); + if (!header) + return; + memcpy(header->signature, "BERT", 4); memcpy(header->oem_id, OEM_ID, 6); memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); @@ -1101,6 +1148,10 @@ void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) acpi_header_t *header = &(fadt->header); memset((void *) fadt, 0, sizeof(acpi_fadt_t)); + + if (!header) + return; + memcpy(header->signature, "FACP", 4); header->length = sizeof(acpi_fadt_t); header->revision = get_acpi_table_revision(FADT); From c53665ce55ba4f5a670caf382213d984a2991900 Mon Sep 17 00:00:00 2001 From: Elyes HAOUAS Date: Wed, 22 May 2019 20:06:30 +0200 Subject: [PATCH 578/588] nb/intel/x4x: Remove variable set but not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I142ae6f7806b3f57b98a158e8f26592aed8fa452 Signed-off-by: Elyes HAOUAS Reviewed-on: https://review.coreboot.org/c/coreboot/+/32939 Reviewed-by: Felix Held Reviewed-by: Kyösti Mälkki Tested-by: build bot (Jenkins) --- src/northbridge/intel/x4x/raminit_ddr23.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/northbridge/intel/x4x/raminit_ddr23.c b/src/northbridge/intel/x4x/raminit_ddr23.c index f1726231081..422b0ffa163 100644 --- a/src/northbridge/intel/x4x/raminit_ddr23.c +++ b/src/northbridge/intel/x4x/raminit_ddr23.c @@ -1317,7 +1317,6 @@ static u32 mirror_shift_bit(const u32 data, u8 bit) void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val) { u32 addr = test_address(ch, r); - volatile u32 rubbish; u8 data8 = cmd; u32 data32; @@ -1337,7 +1336,7 @@ void send_jedec_cmd(const struct sysinfo *s, u8 r, u8 ch, u8 cmd, u32 val) } data32 <<= 3; - rubbish = read32((void *)((data32 | addr))); + read32((void *)((data32 | addr))); udelay(10); MCHBAR8_AND_OR(0x271, ~0x3e, NORMALOP_CMD); MCHBAR8_AND_OR(0x671, ~0x3e, NORMALOP_CMD); From d3a73280cc8e01a28cbdb1a4d086e4dda7b35f0c Mon Sep 17 00:00:00 2001 From: John Zhao Date: Fri, 31 May 2019 09:58:49 -0700 Subject: [PATCH 579/588] src/drivers/intel: Avoid NULL pointer dereference Coverity detects pointer fih as FORWARD_NULL. Add sanity check for fih to prevent NULL pointer dereference. BUG=CID 1401717 TEST=Built and boot up to kernel. Change-Id: Ia6853e5302c87d9ffe52b942f067be56f6e77406 Signed-off-by: John Zhao Reviewed-on: https://review.coreboot.org/c/coreboot/+/33150 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held Reviewed-by: Christian Walter --- src/drivers/intel/fsp1_1/car.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c index 10f9524650a..dd17664036d 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -120,6 +120,9 @@ void mainboard_romstage_entry(unsigned long bist) * the flash is memory mapped CPU's address space. */ FSP_INFO_HEADER *fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); + if (!fih) + die("Invalid FSP header\n"); + cache_as_ram_stage_main(fih); } From d622507450464db5ee6cff7de03f9649a299018b Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Tue, 21 May 2019 11:04:50 +0200 Subject: [PATCH 580/588] lib/Makefile.inc: Add hexdump.c to postcar stage hexdump() is not available in postcar stage. Add hexdump() functionality to postcar stage. BUG=NA TEST=Booting Embedded Linux on Facebook FBG-1701 Change-Id: Ibdce911065c01b0a1aa81dc248557257d0e420b0 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/32908 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks --- src/lib/Makefile.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc index 1b8ad19b679..16d5c649b21 100644 --- a/src/lib/Makefile.inc +++ b/src/lib/Makefile.inc @@ -166,6 +166,7 @@ postcar-y += imd.c postcar-y += romstage_handoff.c bootblock-y += hexdump.c +postcar-y += hexdump.c ramstage-y += hexdump.c romstage-y += hexdump.c verstage-y += hexdump.c From 43b6e2ed7108859297512a6d4194335fb8237d1b Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Tue, 4 Jun 2019 13:53:05 +0200 Subject: [PATCH 581/588] mainboard/facebook/fbg1701: Do initial mainboard commit Initial support for Facebook FBG-1701 system. coreboot implementation based on Intel Strago mainboard. Configure 'Onboard memory manufacturer' which must match HW. BUG=N/A TEST=booting SeaBIOS and Linux 4.15+ kernel on Facebook FBG-1701 Change-Id: I28ac78a630ee705b1e546031f024bfe7f952ab39 Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/30414 Tested-by: build bot (Jenkins) Reviewed-by: David Hendricks Reviewed-by: Patrick Rudolph --- Documentation/mainboard/facebook/fbg1701.md | 83 ++++++ Documentation/mainboard/index.md | 4 + src/mainboard/facebook/fbg1701/Kconfig | 105 +++++++ src/mainboard/facebook/fbg1701/Kconfig.name | 2 + src/mainboard/facebook/fbg1701/Makefile.inc | 34 +++ src/mainboard/facebook/fbg1701/acpi/ec.asl | 14 + .../facebook/fbg1701/acpi/mainboard.asl | 45 +++ .../facebook/fbg1701/acpi/sleepstates.asl | 20 ++ .../facebook/fbg1701/acpi/superio.asl | 47 ++++ src/mainboard/facebook/fbg1701/acpi_tables.c | 54 ++++ src/mainboard/facebook/fbg1701/board_info.txt | 6 + src/mainboard/facebook/fbg1701/cmos.layout | 121 +++++++++ src/mainboard/facebook/fbg1701/com_init.c | 29 ++ src/mainboard/facebook/fbg1701/devicetree.cb | 131 +++++++++ src/mainboard/facebook/fbg1701/dsdt.asl | 48 ++++ src/mainboard/facebook/fbg1701/fadt.c | 48 ++++ src/mainboard/facebook/fbg1701/gpio.c | 253 +++++++++++++++++ src/mainboard/facebook/fbg1701/hda_verb.c | 78 ++++++ src/mainboard/facebook/fbg1701/irqroute.c | 18 ++ src/mainboard/facebook/fbg1701/irqroute.h | 70 +++++ src/mainboard/facebook/fbg1701/logo.c | 47 ++++ src/mainboard/facebook/fbg1701/mainboard.c | 52 ++++ src/mainboard/facebook/fbg1701/mainboard.h | 21 ++ src/mainboard/facebook/fbg1701/onboard.h | 36 +++ src/mainboard/facebook/fbg1701/ramstage.c | 32 +++ src/mainboard/facebook/fbg1701/romstage.c | 51 ++++ .../spd/MICRON_MT41K512M16HA-125A.spd.hex | 257 ++++++++++++++++++ .../spd/SAMSUNG_K4B8G1646D-MYKO.spd.hex | 254 +++++++++++++++++ src/mainboard/facebook/fbg1701/w25q64.c | 78 ++++++ 29 files changed, 2038 insertions(+) create mode 100644 Documentation/mainboard/facebook/fbg1701.md create mode 100644 src/mainboard/facebook/fbg1701/Kconfig create mode 100644 src/mainboard/facebook/fbg1701/Kconfig.name create mode 100644 src/mainboard/facebook/fbg1701/Makefile.inc create mode 100644 src/mainboard/facebook/fbg1701/acpi/ec.asl create mode 100644 src/mainboard/facebook/fbg1701/acpi/mainboard.asl create mode 100644 src/mainboard/facebook/fbg1701/acpi/sleepstates.asl create mode 100644 src/mainboard/facebook/fbg1701/acpi/superio.asl create mode 100644 src/mainboard/facebook/fbg1701/acpi_tables.c create mode 100644 src/mainboard/facebook/fbg1701/board_info.txt create mode 100644 src/mainboard/facebook/fbg1701/cmos.layout create mode 100644 src/mainboard/facebook/fbg1701/com_init.c create mode 100644 src/mainboard/facebook/fbg1701/devicetree.cb create mode 100644 src/mainboard/facebook/fbg1701/dsdt.asl create mode 100644 src/mainboard/facebook/fbg1701/fadt.c create mode 100644 src/mainboard/facebook/fbg1701/gpio.c create mode 100644 src/mainboard/facebook/fbg1701/hda_verb.c create mode 100644 src/mainboard/facebook/fbg1701/irqroute.c create mode 100644 src/mainboard/facebook/fbg1701/irqroute.h create mode 100644 src/mainboard/facebook/fbg1701/logo.c create mode 100644 src/mainboard/facebook/fbg1701/mainboard.c create mode 100644 src/mainboard/facebook/fbg1701/mainboard.h create mode 100644 src/mainboard/facebook/fbg1701/onboard.h create mode 100644 src/mainboard/facebook/fbg1701/ramstage.c create mode 100644 src/mainboard/facebook/fbg1701/romstage.c create mode 100644 src/mainboard/facebook/fbg1701/spd/MICRON_MT41K512M16HA-125A.spd.hex create mode 100644 src/mainboard/facebook/fbg1701/spd/SAMSUNG_K4B8G1646D-MYKO.spd.hex create mode 100644 src/mainboard/facebook/fbg1701/w25q64.c diff --git a/Documentation/mainboard/facebook/fbg1701.md b/Documentation/mainboard/facebook/fbg1701.md new file mode 100644 index 00000000000..89e8a6abbca --- /dev/null +++ b/Documentation/mainboard/facebook/fbg1701.md @@ -0,0 +1,83 @@ +# Facebook FBG-1701 + +This page describes how to run coreboot on the Facebook FBG1701. + +FBG1701 are assembled with different onboard memory modules: + Rev 1.0 Onboard Samsung K4B8G1646D-MYKO memory + Rev 1.1 and 1.2 Onboard Micron MT41K512M16HA-125A memory + +Use make menuconfig to configure `onboard memory manufacturer` in Mainboard +menu. + +## Required blobs + +This board currently requires: +fsp blob 3rdparty/fsp/BraswellFspBinPkg/FspBin/BSWFSP.fd +Microcode Intel Braswell cpuid 1046C4 version 410 + (Used pre-build binary retrieved from Intel site) + +## Flashing coreboot + +### Internal programming + +The main SPI flash can be accessed using [flashrom]. + +### External programming + +The system has an internal flash chip which is a 8 MiB soldered SOIC-8 chip. +This chip is located to the top middle side of the board. It's located +between SoC and Q7 connector. Use clip (or solder wires) to program +the chip. +Specifically, it's a Winbond W25Q64FW (1.8V), whose datasheet can be found +[here][W25Q64FW]. + +The system has an external flash chip which is a 8 MiB soldered SOIC-8 chip. +This chip is located in the middle of carrier board close to the flex cable +connection. +Specifically, it's a Winbond W25Q64FV (3.3V), whose datasheet can be found +[here][W25Q64FV]. + +## Known issues + +- None + +## Untested + +- hardware monitor +- SDIO +- Full Embedded Controller support + +## Working + +- USB +- Gigabit Ethernet +- integrated graphics +- flashrom +- external graphics +- PCIe +- eMMC +- SATA +- serial port +- SMBus +- HDA +- initialization with FSP MR2 +- SeaBIOS payload +- Embedded Linux (Ubuntu 4.15+) + +## Technology + +```eval_rst ++------------------+--------------------------------------------------+ +| SoC | Intel Atom Processor N3710 | ++------------------+--------------------------------------------------+ +| CPU | Intel Braswell (N3710) | ++------------------+--------------------------------------------------+ +| Super I/O, EC | ITE8256 | ++------------------+--------------------------------------------------+ +| Coprocessor | Intel Management Engine | ++------------------+--------------------------------------------------+ +``` + +[W25Q64FW]: https://www.winbond.com/resource-files/w25q64fw%20revn%2005182017%20sfdp.pdf +[W25Q64FV]: https://www.winbond.com/resource-files/w25q64fv%20revs%2007182017.pdf +[flashrom]: https://flashrom.org/Flashrom diff --git a/Documentation/mainboard/index.md b/Documentation/mainboard/index.md index fb4f5022aac..f63ef763fb0 100644 --- a/Documentation/mainboard/index.md +++ b/Documentation/mainboard/index.md @@ -30,6 +30,10 @@ The boards in this section are not real mainboards, but emulators. - [IceLake RVP](intel/icelake_rvp.md) - [KBLRVP11](intel/kblrvp11.md) +## Facebook + +- [FBG-1701](facebook/fbg1701.md) + ## Foxconn - [D41S](foxconn/d41s.md) diff --git a/src/mainboard/facebook/fbg1701/Kconfig b/src/mainboard/facebook/fbg1701/Kconfig new file mode 100644 index 00000000000..3f451945b45 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/Kconfig @@ -0,0 +1,105 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2018-2019 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +if BOARD_FACEBOOK_FBG1701 + +config BOARD_SPECIFIC_OPTIONS + def_bool y + select BOARD_ROMSIZE_KB_8192 + select HAVE_ACPI_TABLES + select HAVE_OPTION_TABLE + select MAINBOARD_HAS_LPC_TPM + select MAINBOARD_HAS_TPM2 + select SOC_INTEL_BRASWELL + select PCIEXP_L1_SUB_STATE + select HAVE_FSP_BIN + select CACHE_MRC_SETTINGS + select DISABLE_HPET + select GENERIC_SPD_BIN + +choice + prompt "Onboard memory manufacturer" + default ONBOARD_MICRON_MEM + +config ONBOARD_SAMSUNG_MEM + bool "Samsung" + help + Samsung K4B8G1646D memory + +config ONBOARD_MICRON_MEM + bool "Micron" + help + Micron MT41K512M16HA memory +endchoice + +config MAINBOARD_DIR + string + default facebook/fbg1701 + +config MAINBOARD_PART_NUMBER + string + default "FBG-1701" + +config CBFS_SIZE + hex + default 0x00800000 + +config CPU_MICROCODE_CBFS_LEN + hex + default 0x10C00 + help + This should be updated when the microcode patch changes. + +config CPU_MICROCODE_CBFS_LOC + hex + default 0xFFFE9400 + +config MRC_SETTINGS_CACHE_SIZE + hex + default 0x08000 + +config FSP_LOC + hex + default 0xfff9c000 + +config FSP1_1_DISPLAY_LOGO + bool + default n + +config BOOTBLOCK_LOC + hex + default 0xFFFF0000 + +config BOOTBLOCK_SIZE + hex + default 0x10000 + +config SPI_FLASH_INCLUDE_ALL_DRIVERS + bool + default n + +config SPI_FLASH_WINBOND + bool + default y + +config TPM_INIT + bool "TPM Setup in RAMSTAGE" + default n + +config C_ENV_BOOTBLOCK_SIZE + hex "C Bootblock Size" + default 0x4000 + +endif # BOARD_FACEBOOK_FBG1701 diff --git a/src/mainboard/facebook/fbg1701/Kconfig.name b/src/mainboard/facebook/fbg1701/Kconfig.name new file mode 100644 index 00000000000..1ead7d587fd --- /dev/null +++ b/src/mainboard/facebook/fbg1701/Kconfig.name @@ -0,0 +1,2 @@ +config BOARD_FACEBOOK_FBG1701 + bool "fbg1701" diff --git a/src/mainboard/facebook/fbg1701/Makefile.inc b/src/mainboard/facebook/fbg1701/Makefile.inc new file mode 100644 index 00000000000..07309c564c7 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/Makefile.inc @@ -0,0 +1,34 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2013 Google Inc. +## Copyright (C) 2015 Intel Corp. +## Copyright (C) 2018-2019 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +bootblock-$(CONFIG_C_ENVIRONMENT_BOOTBLOCK) += com_init.c + +ramstage-y += gpio.c +ramstage-y += hda_verb.c +ramstage-y += irqroute.c +ramstage-$(CONFIG_FSP1_1_DISPLAY_LOGO) += logo.c +ramstage-y += ramstage.c +ramstage-y += w25q64.c + +cbfs-files-$(CONFIG_FSP1_1_DISPLAY_LOGO) += logo.bmp +logo.bmp-file := $(call strip_quotes,$(CONFIG_FSP1_1_LOGO_FILE_NAME)) +logo.bmp-type := raw +logo.bmp-compression := LZMA + +# Order of names in SPD_SOURCES is important! +SPD_SOURCES = SAMSUNG_K4B8G1646D-MYKO +SPD_SOURCES += MICRON_MT41K512M16HA-125A diff --git a/src/mainboard/facebook/fbg1701/acpi/ec.asl b/src/mainboard/facebook/fbg1701/acpi/ec.asl new file mode 100644 index 00000000000..3c9d818baed --- /dev/null +++ b/src/mainboard/facebook/fbg1701/acpi/ec.asl @@ -0,0 +1,14 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ diff --git a/src/mainboard/facebook/fbg1701/acpi/mainboard.asl b/src/mainboard/facebook/fbg1701/acpi/mainboard.asl new file mode 100644 index 00000000000..9575748446e --- /dev/null +++ b/src/mainboard/facebook/fbg1701/acpi/mainboard.asl @@ -0,0 +1,45 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "onboard.h" + +Scope (\_SB) +{ + Device (PWRB) + { + Name (_HID, EisaId ("PNP0C0C")) + Name (_UID, 1) + } +} + +/* + * Onboard CPLD + */ +Scope (\_SB.PCI0.LPCB) +{ + Device (CPLD) /* Onboard CPLD */ + { + Name(_HID, EISAID("PNP0C01")) + Name(_CRS, ResourceTemplate() + { + /* Reserve 0x280 to 0x2BF for the CPLD */ + FixedIO (0x0280, 0x40) + IRQNoFlags () {7} + }) + } +} diff --git a/src/mainboard/facebook/fbg1701/acpi/sleepstates.asl b/src/mainboard/facebook/fbg1701/acpi/sleepstates.asl new file mode 100644 index 00000000000..428fda2a015 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/acpi/sleepstates.asl @@ -0,0 +1,20 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of + * the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +Name(\_S0, Package(){0x0,0x0,0x0,0x0}) +Name(\_S4, Package(){0x6,0x6,0x0,0x0}) +Name(\_S5, Package(){0x7,0x7,0x0,0x0}) diff --git a/src/mainboard/facebook/fbg1701/acpi/superio.asl b/src/mainboard/facebook/fbg1701/acpi/superio.asl new file mode 100644 index 00000000000..468c95c531e --- /dev/null +++ b/src/mainboard/facebook/fbg1701/acpi/superio.asl @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2011 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +/* mainboard configuration */ +#include "onboard.h" + +Device (COM1) { + Name (_HID, EISAID ("PNP0501")) + Name (_UID, 1) + Name (_ADR, 0) + + Method (_STA, 0, NotSerialized) + { + Return (0x0F) + } + + Name (_CRS, ResourceTemplate () + { + FixedIO (0x03F8, 0x08) + FixedIO (0x6E, 0x02) + IRQNoFlags () {4} + }) + + Name (_PRS, ResourceTemplate () + { + StartDependentFn (0, 0) { + FixedIO (0x03F8, 0x08) + FixedIO (0x6E, 0x02) + IRQNoFlags () {4} + } + EndDependentFn () + }) +} diff --git a/src/mainboard/facebook/fbg1701/acpi_tables.c b/src/mainboard/facebook/fbg1701/acpi_tables.c new file mode 100644 index 00000000000..15c955afc2e --- /dev/null +++ b/src/mainboard/facebook/fbg1701/acpi_tables.c @@ -0,0 +1,54 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2012 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include + +void acpi_create_gnvs(global_nvs_t *gnvs) +{ + acpi_init_gnvs(gnvs); + + /* Enable USB ports in S3 */ + gnvs->s3u0 = 1; + gnvs->s3u1 = 1; + + /* Disable USB ports in S5 */ + gnvs->s5u0 = 0; + gnvs->s5u1 = 0; + + /* Disable DPTF */ + gnvs->dpte = 0; + + /* PMIC is configured in I2C1, hide it for the OS */ + gnvs->dev.lpss_en[LPSS_NVS_I2C2] = 0; +} + +unsigned long acpi_fill_madt(unsigned long current) +{ + /* Local APICs */ + current = acpi_create_madt_lapics(current); + + /* IOAPIC */ + current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, + 2, IO_APIC_ADDR, 0); + + current = acpi_madt_irq_overrides(current); + + return current; +} diff --git a/src/mainboard/facebook/fbg1701/board_info.txt b/src/mainboard/facebook/fbg1701/board_info.txt new file mode 100644 index 00000000000..41d91fd2bea --- /dev/null +++ b/src/mainboard/facebook/fbg1701/board_info.txt @@ -0,0 +1,6 @@ +Vendor name: Facebook +Board name: FBG-1701 +Category: sbc +ROM protocol: SPI +ROM socketed: n +Flashrom support: y diff --git a/src/mainboard/facebook/fbg1701/cmos.layout b/src/mainboard/facebook/fbg1701/cmos.layout new file mode 100644 index 00000000000..c293c5f9895 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/cmos.layout @@ -0,0 +1,121 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007-2008 coresystems GmbH +## Copyright (C) 2015 Intel Corp. +## Copyright (C) 2018 Eltan B.V. +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +# ----------------------------------------------------------------- +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +# ----------------------------------------------------------------- +# Status Register A +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +# ----------------------------------------------------------------- +# Status Register B +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +# ----------------------------------------------------------------- +# Status Register C +#96 4 r 0 status_c_rsvd +#100 1 r 0 uf_flag +#101 1 r 0 af_flag +#102 1 r 0 pf_flag +#103 1 r 0 irqf_flag +# ----------------------------------------------------------------- +# Status Register D +#104 7 r 0 status_d_rsvd +#111 1 r 0 valid_cmos_ram +# ----------------------------------------------------------------- +# Diagnostic Status Register +#112 8 r 0 diag_rsvd1 + +# ----------------------------------------------------------------- +0 120 r 0 reserved_memory +#120 264 r 0 unused + +# ----------------------------------------------------------------- +# RTC_BOOT_BYTE (coreboot hardcoded) +# reboot_counter reserved for core, not used by platform. +384 1 e 4 boot_option +388 4 h 0 reboot_counter +#390 2 r 0 unused + +# ----------------------------------------------------------------- +# coreboot config options: console +#392 3 r 0 unused +395 4 e 6 debug_level +#399 1 r 0 unused + +# coreboot config options: cpu +#400 1 e 2 unused +#401 7 r 0 unused + +# coreboot config options: southbridge +408 1 e 1 nmi +409 2 e 7 power_on_after_fail +#411 5 r 0 unused + +# coreboot config options: bootloader +#416 568 r 0 unused + +# coreboot config options: check sums +984 16 h 0 check_sum +#1000 24 r 0 amd_reserved + +# ----------------------------------------------------------------- + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +6 0 Emergency +6 1 Alert +6 2 Critical +6 3 Error +6 4 Warning +6 5 Notice +6 6 Info +6 7 Debug +6 8 Spew +7 0 Disable +7 1 Enable +7 2 Keep +# ----------------------------------------------------------------- +checksums + +checksum 392 415 984 diff --git a/src/mainboard/facebook/fbg1701/com_init.c b/src/mainboard/facebook/fbg1701/com_init.c new file mode 100644 index 00000000000..f19aba311c7 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/com_init.c @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include "onboard.h" + +#define SERIAL_DEV PNP_DEV(ITE8528_CMD_PORT, 1) /* ITE8528 UART1 */ + +void bootblock_mainboard_early_init(void) +{ + /* Enable the serial port inside the EC */ + pnp_set_logical_device(SERIAL_DEV); + pnp_set_enable(SERIAL_DEV, 1); +} diff --git a/src/mainboard/facebook/fbg1701/devicetree.cb b/src/mainboard/facebook/fbg1701/devicetree.cb new file mode 100644 index 00000000000..3c82a034b4d --- /dev/null +++ b/src/mainboard/facebook/fbg1701/devicetree.cb @@ -0,0 +1,131 @@ +chip soc/intel/braswell + + ############################################################ + # Set the parameters for MemoryInit + ############################################################ + + register "PcdMrcInitTsegSize" = "8" # SMM Region size in MiB + + register "PcdMrcInitMmioSize" = "0x0800" + register "PcdMrcInitSpdAddr1" = "0xa0" + register "PcdMrcInitSpdAddr2" = "0xa2" + register "PcdIgdDvmt50PreAlloc" = "1" + register "PcdApertureSize" = "2" + register "PcdGttSize" = "1" + register "PcdDvfsEnable" = "0" + register "PcdCaMirrorEn" = "1" + + ############################################################ + # Set the parameters for SiliconInit + ############################################################ + + register "PcdSdcardMode" = "PCH_DISABLED" + register "PcdEnableHsuart0" = "0" + register "PcdEnableHsuart1" = "0" + register "PcdEnableAzalia" = "1" + register "PcdEnableXhci" = "1" + register "PcdEnableLpe" = "0" + register "PcdEnableDma0" = "0" + register "PcdEnableDma1" = "0" + register "PcdEnableI2C0" = "0" + register "PcdEnableI2C1" = "0" + register "PcdEnableI2C2" = "0" + register "PcdEnableI2C3" = "0" + register "PcdEnableI2C4" = "0" + register "PcdEnableI2C5" = "0" + register "PcdEnableI2C6" = "0" + register "PunitPwrConfigDisable" = "0" # Enable SVID + register "ChvSvidConfig" = "1" + register "PcdEmmcMode" = "PCH_PCI_MODE" + register "PcdUsb3ClkSsc" = "1" + register "PcdDispClkSsc" = "1" + register "PcdSataClkSsc" = "1" + register "PcdEnableSata" = "0" # Disable SATA + register "Usb2Port0PerPortPeTxiSet" = "7" + register "Usb2Port0PerPortTxiSet" = "5" + register "Usb2Port0IUsbTxEmphasisEn" = "2" + register "Usb2Port0PerPortTxPeHalf" = "1" + register "Usb2Port1PerPortPeTxiSet" = "7" + register "Usb2Port1PerPortTxiSet" = "3" + register "Usb2Port1IUsbTxEmphasisEn" = "2" + register "Usb2Port1PerPortTxPeHalf" = "1" + register "Usb2Port2PerPortPeTxiSet" = "7" + register "Usb2Port2PerPortTxiSet" = "3" + register "Usb2Port2IUsbTxEmphasisEn" = "2" + register "Usb2Port2PerPortTxPeHalf" = "1" + register "Usb2Port3PerPortPeTxiSet" = "7" + register "Usb2Port3PerPortTxiSet" = "3" + register "Usb2Port3IUsbTxEmphasisEn" = "2" + register "Usb2Port3PerPortTxPeHalf" = "1" + register "Usb2Port4PerPortPeTxiSet" = "7" + register "Usb2Port4PerPortTxiSet" = "3" + register "Usb2Port4IUsbTxEmphasisEn" = "2" + register "Usb2Port4PerPortTxPeHalf" = "1" + register "Usb3Lane0Ow2tapgen2deemph3p5" = "0x3a" + register "Usb3Lane1Ow2tapgen2deemph3p5" = "0x64" + register "Usb3Lane2Ow2tapgen2deemph3p5" = "0x64" + register "Usb3Lane3Ow2tapgen2deemph3p5" = "0x3a" + register "PcdSataInterfaceSpeed" = "3" + register "PcdPchSsicEnable" = "1" + register "PcdRtcLock" = "0" # Disable RTC access locking to NVRAM + register "PMIC_I2CBus" = "0" + register "ISPEnable" = "0" # Disable IUNIT + register "ISPPciDevConfig" = "3" + register "PcdSdDetectChk" = "0" # Disable SD card detect + register "DptfDisable" = "1" + + # LPE audio codec settings + register "lpe_codec_clk_src" = "LPE_CLK_SRC_XTAL" # 19.2MHz clock + + # Enable devices in PCI mode + register "lpss_acpi_mode" = "0" + register "emmc_acpi_mode" = "0" + register "sd_acpi_mode" = "0" + register "lpe_acpi_mode" = "0" + + # Disable SLP_X stretching after SUS power well fail. + register "disable_slp_x_stretch_sus_fail" = "1" + + # Allow PCIe devices to wake system from suspend + register "pcie_wake_enable" = "1" + + # CPLD requires continuous mode + register "serirq_mode" = "SERIRQ_CONTINUOUS" + + device cpu_cluster 0 on + device lapic 0 on end + end + + device domain 0 on + device pci 00.0 on end # 8086 2280 - SoC router + device pci 02.0 on end # 8086 22B1 - GFX + device pci 0b.0 off end # 8086 22DC - PUNIT/DPTF + device pci 10.0 on end # 8086 2294 - MMC Port + device pci 12.0 on end # 8086 0F16 - SD Port + device pci 13.0 off end # 8086 22a3 - SATA Port + device pci 14.0 on end # 8086 22b5 - USB XHCI - Only 1 USB controller at a time + device pci 18.0 off end # 8086 22c0 - SIO - DMA + device pci 18.1 off end # 8086 22c1 - I2C Port 1 + device pci 18.2 off end # 8086 22c2 - I2C Port 2 + device pci 18.3 off end # 8086 22c3 - I2C Port 3 + device pci 18.4 off end # 8086 22c4 - I2C Port 4 + device pci 18.5 off end # 8086 22c5 - I2C Port 5 + device pci 18.6 off end # 8086 22c6 - I2C Port 6 + device pci 18.7 off end # 8086 22c7 - I2C Port 7 + device pci 1a.0 on end # 8086 2298 - Trusted Execution Engine + device pci 1b.0 on end # 8086 2284 - HD Audio + device pci 1c.0 on end # 8086 0000 - PCIe Root Port 1 + device pci 1c.1 off end # 8086 0000 - PCIe Root Port 2 + device pci 1c.2 off end # 8086 0000 - PCIe Root Port 3 + device pci 1c.3 on end # 8086 0000 - PCIe Root Port 4 + device pci 1e.0 off end # 8086 2286 - SIO - DMA + device pci 1e.3 off end # 8086 228a - HSUART 1 + device pci 1e.4 off end # 8086 228c - HSUART 2 + device pci 1f.0 on # 8086 229c - LPC bridge + chip drivers/pc80/tpm + device pnp 0c31.0 on end + end + end # LPC Bridge + device pci 1f.3 on end # 8086 2292 - SMBus 0 + end +end diff --git a/src/mainboard/facebook/fbg1701/dsdt.asl b/src/mainboard/facebook/fbg1701/dsdt.asl new file mode 100644 index 00000000000..4eea7b93f49 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/dsdt.asl @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 Google Inc. + * Copyright (C) 2015-2018 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +DefinitionBlock( + "dsdt.aml", + "DSDT", + 0x02, /* DSDT revision: ACPI v2.0 and up */ + OEM_ID, + ACPI_TABLE_CREATOR, + 0x20110725 /* OEM revision */ +) +{ + /* Some generic macros */ + #include + + /* global NVS and variables */ + #include + + #include + + Scope (\_SB) { + Device (PCI0) + { + #include + } + } + + /* Chipset specific sleep states */ + #include "acpi/sleepstates.asl" + #include "acpi/mainboard.asl" +} diff --git a/src/mainboard/facebook/fbg1701/fadt.c b/src/mainboard/facebook/fbg1701/fadt.c new file mode 100644 index 00000000000..73adfad94c9 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/fadt.c @@ -0,0 +1,48 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +void acpi_create_fadt(acpi_fadt_t *fadt, acpi_facs_t *facs, void *dsdt) +{ + acpi_header_t *header = &(fadt->header); + + memset((void *) fadt, 0, sizeof(acpi_fadt_t)); + memcpy(header->signature, "FACP", 4); + header->length = sizeof(acpi_fadt_t); + header->revision = 3; + memcpy(header->oem_id, OEM_ID, 6); + memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); + memcpy(header->asl_compiler_id, ASLC, 4); + header->asl_compiler_revision = 1; + + fadt->firmware_ctrl = (unsigned long) facs; + fadt->dsdt = (unsigned long) dsdt; + fadt->preferred_pm_profile = PM_MOBILE; + + fadt->x_firmware_ctl_l = (unsigned long)facs; + fadt->x_firmware_ctl_h = 0; + fadt->x_dsdt_l = (unsigned long)dsdt; + fadt->x_dsdt_h = 0; + + acpi_fill_in_fadt(fadt); + + fadt->iapc_boot_arch &= ~ACPI_FADT_8042; + + header->checksum = + acpi_checksum((void *) fadt, header->length); +} diff --git a/src/mainboard/facebook/fbg1701/gpio.c b/src/mainboard/facebook/fbg1701/gpio.c new file mode 100644 index 00000000000..5a73ca91485 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/gpio.c @@ -0,0 +1,253 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +/* South East Community */ +static const struct soc_gpio_map gpse_gpio_map[] = { + Native_M1,/* 00 MF_PLT_CLK0 */ + GPIO_NC, /* 01 PWM1 */ + GPIO_INPUT_NO_PULL, /* 02 MF_PLT_CLK1, RAMID2 */ + GPIO_NC, /* 03 MF_PLT_CLK4 */ + GPIO_NC, /* 04 MF_PLT_CLK3 */ + GPIO_NC, /* PWM0 05 */ + GPIO_NC, /* 06 MF_PLT_CLK5 */ + GPIO_NC, /* 07 MF_PLT_CLK2 */ + GPIO_NC, /* 15 SDMMC2_D3_CD_B */ + Native_M1, /* 16 SDMMC1_CLK */ + NATIVE_PU20K(1), /* 17 SDMMC1_D0 */ + GPIO_NC, /* 18 SDMMC2_D1 */ + GPIO_NC, /* 19 SDMMC2_CLK */ + NATIVE_PU20K(1),/* 20 SDMMC1_D2 */ + GPIO_NC, /* 21 SDMMC2_D2 */ + GPIO_NC, /* 22 SDMMC2_CMD */ + NATIVE_PU20K(1), /* 23 SDMMC1_CMD */ + NATIVE_PU20K(1), /* 24 SDMMC1_D1 */ + GPIO_NC, /* 25 SDMMC2_D0 */ + NATIVE_PU20K(1), /* 26 SDMMC1_D3_CD_B */ + NATIVE_PU20K(1), /* 30 SDMMC3_D1 */ + Native_M1, /* 31 SDMMC3_CLK */ + NATIVE_PU20K(1), /* 32 SDMMC3_D3 */ + NATIVE_PU20K(1), /* 33 SDMMC3_D2 */ + NATIVE_PU20K(1), /* 34 SDMMC3_CMD */ + NATIVE_PU20K(1), /* 35 SDMMC3_D0 */ + NATIVE_PU20K(1), /* 45 MF_LPC_AD2 */ + NATIVE_PU20K(1), /* 46 LPC_CLKRUNB */ + NATIVE_PU20K(1), /* 47 MF_LPC_AD0 */ + Native_M1, /* 48 LPC_FRAMEB */ + Native_M1, /* 49 MF_LPC_CLKOUT1 */ + NATIVE_PU20K(1), /* 50 MF_LPC_AD3 */ + Native_M1, /* 51 MF_LPC_CLKOUT0 */ + NATIVE_PU20K(1), /* 52 MF_LPC_AD1 */ + Native_M1,/* SPI1_MISO */ + Native_M1, /* 61 SPI1_CS0_B */ + Native_M1, /* SPI1_CLK */ + NATIVE_PU20K(1), /* 63 MMC1_D6 */ + Native_M1, /* 62 SPI1_MOSI */ + NATIVE_PU20K(1), /* 65 MMC1_D5 */ + GPIO_NC, /* 66 SPI1_CS1_B */ + NATIVE_PU20K(1), /* 67 MMC1_D4_SD_WE */ + NATIVE_PU20K(1), /* 68 MMC1_D7 */ + GPIO_NC, /* 69 MMC1_RCLK */ + Native_M1, /* 75 GPO USB_OC1_B */ + Native_M1, /* 76 PMU_RESETBUTTON_B */ + GPIO_NC, /* 77 GPIO_ALERT */ + Native_M1, /* 78 SDMMC3_PWR_EN_B */ + Native_M1, /* 79 GPI ILB_SERIRQ */ + Native_M1, /* 80 USB_OC0_B */ + NATIVE_INT_PU20K(1, L1), /* 81 SDMMC3_CD_B */ + Native_M1, /* 82 SPKR */ + Native_M1, /* 83 SUSPWRDNACK */ + SPARE_PIN, /* 84 spare pin */ + Native_M1, /* 85 SDMMC3_1P8_EN */ + GPIO_END +}; + +/* South West Community */ +static const struct soc_gpio_map gpsw_gpio_map[] = { + NATIVE_PU20K(1), /* 00 FST_SPI_D2 */ + NATIVE_PU20K(1), /* 01 FST_SPI_D0 */ + NATIVE_PU20K(1), /* 02 FST_SPI_CLK */ + NATIVE_PU20K(1), /* 03 FST_SPI_D3 */ + NATIVE_PU20K(1), /* 04 FST_SPI_CS1_B */ + NATIVE_PU20K(1), /* 05 FST_SPI_D1 */ + NATIVE_PU20K(1), /* 06 FST_SPI_CS0_B */ + GPIO_NC, /* 07 FST_SPI_CS2_B NC */ + GPIO_NC, /* 15 UART1_RTS_B */ + GPIO_NC, /* 16 UART1_RXD */ + GPIO_NC, /* 17 UART2_RXD */ + GPIO_NC, /* 18 UART1_CTS_B */ + GPIO_NC, /* 19 UART2_RTS_B */ + GPIO_NC, /* 20 UART1_TXD */ + GPIO_NC, /* 21 UART2_TXD */ + GPIO_NC, /* 22 UART2_CTS_B */ + Native_M2, /* 30 MF_HDA_CLK */ + Native_M2, /* 31 MF_HDA_RSTB */ + Native_M2, /* 32 MF_HDA_SDI0 */ + Native_M2, /* 33 MF_HDA_SDO */ + GPIO_NC, /* 34 MF_HDA_DOCKRSTB */ + Native_M2, /* 35 MF_HDA_SYNC */ + GPIO_NC, /* 36 MF_HDA_SDI1 */ + GPIO_NC, /* 37 MF_HDA_DOCKENB */ + GPIO_NC, /* 45 I2C5_SDA */ + GPIO_NC, /* 46 I2C4_SDA */ + GPIO_INPUT_NO_PULL, /* 47 I2C6_SDA SD_WP_1P8*/ + GPIO_NC, /* 48 I2C5_SCL */ + GPIO_NC, /* 49 I2C_NFC_SDA */ + GPIO_NC, /* 50 I2C4_SCL */ + GPIO_NC, /* 51 I2C6_SCL */ + GPIO_NC, /* 52 I2C_NFC_SCL */ + GPIO_NC, /* 60 I2C1_SDA */ + NATIVE_PU1K_CSEN_INVTX(1), /* 61 I2C0_SDA */ + GPIO_NC, /* 62 I2C2_SDA */ + GPIO_NC, /* 63 I2C1_SCL */ + GPIO_NC, /* 64 I2C3_SDA */ + NATIVE_PU1K_CSEN_INVTX(1), /* 65 I2C0_SCL */ + GPIO_NC, /* 66 I2C2_SCL */ + GPIO_NC, /* 67 I2C3_SCL */ + GPIO_NC, /* 75 SATA_GP0 */ + GPIO_NC, /* 76 GPI SATA_GP1 */ + Native_M1, /* 77 SATA_LEDN */ + GPIO_NC, /* 78 SATA_GP2 */ + Native_M1, /* 79 MF_SMB_ALERT_N */ + GPIO_INPUT_NO_PULL, /* 80 SATA_GP3, MMC1_RST */ + Native_M1, /* 81 MF_SMB_CLK */ + Native_M1, /* 82 MF_SMB_DATA */ + Native_M1, /* 90 PCIE_CLKREQ0B */ + Native_M1, /* 91 PCIE_CLKREQ1B */ + GPIO_NC, /* 92 GP_SSP_2_CLK */ + Native_M1, /* 93 PCIE_CLKREQ2B */ + GPIO_NC, /* 94 GP_SSP_2_RXD */ + Native_M1, /* 93 PCIE_CLKREQ3B */ + GPIO_NC, /* 96 GP_SSP_2_FS */ + GPIO_NC, /* 97 GP_SSP_2_TXD */ + GPIO_END +}; + +/* North Community */ +static const struct soc_gpio_map gpn_gpio_map[] = { + GPI(trig_edge_low, L8, NA, non_maskable, en_edge_rx_data, + UNMASK_WAKE, SCI), /* 00 GPIO_DFX0 SMC_EXTSMI_N */ + GPIO_NC, /* 01 GPIO_DFX3 */ + GPIO_NC, /* 02 GPIO_DFX7 */ + GPI(trig_edge_low, L8, NA, non_maskable, en_edge_rx_data, + UNMASK_WAKE, SCI), /* 03 GPIO_DFX1 PM_THRM_N */ + GPI(trig_edge_low, L8, NA, non_maskable, en_edge_rx_data, + UNMASK_WAKE, SCI), /* 04 GPIO_DFX5 LID_N */ + GPIO_NC, /* 05 GPIO_DFX4 */ + GPIO_NC, /* 06 GPIO_DFX8 */ + GPIO_NC, /* 07 GPIO_DFX2 */ + GPI(trig_edge_low, L8, NA, non_maskable, en_edge_rx_data, + UNMASK_WAKE, SCI), /* 08 GPIO_DFX6 WAKE1_N */ + GPI(trig_edge_low, L8, NA, non_maskable, en_edge_rx_data, + UNMASK_WAKE, SCI), /* 15 GPIO_SUS0 */ + GPIO_NC, /* 16 SEC_GPIO_SUS10 */ + GPI(trig_edge_low, L0, P_1K_H, non_maskable, NA, NA, NA), + /* 17 GPIO_SUS3 */ + GPI(trig_edge_low, L1, P_1K_H, non_maskable, NA, UNMASK_WAKE, NA), + /* 18 GPIO_SUS7 */ + GPI(trig_edge_low, L3, P_1K_H, non_maskable, NA, UNMASK_WAKE, NA), + /* 19 GPIO_SUS1 */ + GPIO_NC, /* 20 GPIO_SUS5 */ + GPIO_NC, /* 21 SEC_GPIO_SUS11 */ + GPIO_NC, /* 22 GPIO_SUS4 */ + GPIO_NC, /* 23 SEC_GPIO_SUS8 */ + Native_M6, /* 24 GPIO_SUS2 */ + GPIO_INPUT_PU_5K,/* 25 GPIO_SUS6 */ + Native_M1, /* 26 CX_PREQ_B */ + GPIO_NC, /* 27 SEC_GPIO_SUS9 */ + Native_M1, /* 30 TRST_B */ + Native_M1, /* 31 TCK */ + GPIO_SKIP, /* 32 PROCHOT_B */ + GPIO_SKIP, /* 33 SVID0_DATA */ + Native_M1, /* 34 TMS */ + GPIO_NC, /* 35 CX_PRDY_B_2 */ + GPIO_NC, /* 36 TDO_2 */ + Native_M1, /* 37 CX_PRDY_B */ + GPIO_SKIP, /* 38 SVID0_ALERT_B */ + Native_M1, /* 39 TDO */ + GPIO_SKIP, /* 40 SVID0_CLK */ + Native_M1, /* 41 TDI */ + GPIO_NC, /* 45 GP_CAMERASB05 */ + GPIO_NC, /* 46 GP_CAMERASB02 */ + Native_M2, /* 47 GP_CAMERASB08 */ + GPIO_NC, /* 48 GP_CAMERASB00 */ + GPIO_NC, /* 49 GP_CAMERASBO6 */ + Native_M2, /* 50 GP_CAMERASB10 */ + GPIO_NC, /* 51 GP_CAMERASB03 */ + Native_M2, /* 52 GP_CAMERASB09 */ + GPIO_NC, /* 53 GP_CAMERASB01 */ + GPIO_NC, /* 54 GP_CAMERASB07 */ + Native_M2, /* 55 GP_CAMERASB11 */ + GPIO_NC, /* 56 GP_CAMERASB04 */ + GPIO_NC, /* 60 PANEL0_BKLTEN */ + Native_M1, /* 61 HV_DDI0_HPD */ + GPIO_NC, /* 62 HV_DDI2_DDC_SDA */ + GPIO_NC, /* 63 PANEL1_BKLTCTL */ + Native_M1, /* 64 HV_DDI1_HPD */ + Native_M1, /* 65 PANEL0_BKLTCTL */ + NATIVE_PU20K(1), /* 66 HV_DDI0_DDC_SDA */ + GPIO_NC, /* 67 HV_DDI2_DDC_SCL */ + NATIVE_TX_RX_EN, /* 68 HV_DDI2_HPD */ + GPIO_NC, /* 69 PANEL1_VDDEN */ + GPIO_NC, /* 70 PANEL1_BKLTEN */ + NATIVE_PU20K(1), /* 71 HV_DDI0_DDC_SCL */ + GPIO_NC, /* 72 PANEL0_VDDEN */ + GPIO_END +}; + +/* East Community */ +static const struct soc_gpio_map gpe_gpio_map[] = { + Native_M1, /* 00 PMU_SLP_S3_B */ + GPIO_NC, /* 01 PMU_BATLOW_B */ + Native_M1, /* 02 SUS_STAT_B */ + Native_M1, /* 03 PMU_SLP_S0IX_B */ + Native_M1, /* 04 PMU_AC_PRESENT */ + Native_M1, /* 05 PMU_PLTRST_B */ + Native_M1, /* 06 PMU_SUSCLK */ + GPIO_NC, /* 07 PMU_SLP_LAN_B */ + Native_M1, /* 08 PMU_PWRBTN_B */ + Native_M1, /* 09 PMU_SLP_S4_B */ + NATIVE_FUNC(M1, P_1K_H, NA), /* 10 PMU_WAKE_B */ + GPIO_NC, /* 11 PMU_WAKE_LAN_B */ + GPIO_NC, /* 15 MF_GPIO_3 */ + GPIO_NC, /* 16 MF_GPIO_7 */ + GPIO_NC, /* 17 MF_I2C1_SCL */ + GPIO_NC, /* 18 MF_GPIO_1 */ + GPIO_NC, /* 19 MF_GPIO_5 */ + GPIO_NC, /* 20 MF_GPIO_9 */ + GPIO_NC, /* 21 MF_GPIO_0 */ + GPIO_INPUT_PU_20K, /* 22 MF_GPIO_4 */ + GPIO_NC, /* 23 MF_GPIO_8 */ + GPIO_NC, /* 24 MF_GPIO_2 */ + GPIO_NC, /* 25 MF_GPIO_6 */ + GPIO_NC, /* 26 MF_I2C1_SDA */ + GPIO_END +}; + +static struct soc_gpio_config gpio_config = { + /* BSW */ + .north = gpn_gpio_map, + .southeast = gpse_gpio_map, + .southwest = gpsw_gpio_map, + .east = gpe_gpio_map +}; + +struct soc_gpio_config *mainboard_get_gpios(void) +{ + return &gpio_config; +} diff --git a/src/mainboard/facebook/fbg1701/hda_verb.c b/src/mainboard/facebook/fbg1701/hda_verb.c new file mode 100644 index 00000000000..344443f09ae --- /dev/null +++ b/src/mainboard/facebook/fbg1701/hda_verb.c @@ -0,0 +1,78 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include + +const u32 cim_verb_data[] = { + /* coreboot specific header */ + 0x10EC0298, /* Codec Vendor - Device ID: Realtek ALC298 */ + 0x152D1165, /* Subsystem ID Quanta */ + 0x0000000C, /* Number of jacks */ + + /* HDA Codec Subsystem ID Verb Table */ + AZALIA_SUBVENDOR(0x0, 0x152D1165), + + /* Pin Widget Verb Table */ + + /* Widget node 1 (NID 0x01) */ + 0x0017FF00, + 0x0017FF00, + 0x0017FF00, + 0x0017FF00, + + /* Pin Complex (NID 0x12) DMIC */ + AZALIA_PIN_CFG(0x0, 0x12, 0x90A60130), + + /* Pin Complex (NID 0x13) DMIC */ + AZALIA_PIN_CFG(0x0, 0x13, 0x411111F0), + + /* Pin Complex (NID 0x14) SPEAKER-OUT (Port-D) */ + AZALIA_PIN_CFG(0x0, 0x14, 0x90180110), + + /* Pin Complex (NID 0x17) I2S-OUT */ + AZALIA_PIN_CFG(0x0, 0x17, 0x01011120), + + /* Pin Complex (NID 0x18) MIC1 (Port-B) */ + AZALIA_PIN_CFG(0x0, 0x18, 0x41111F0), + + /* Pin Complex (NID 0x19) I2S-IN */ + AZALIA_PIN_CFG(0x0, 0x19, 0x90870140), + + /* Pin Complex (NID 0x1A) LINE1 (Port-C) */ + AZALIA_PIN_CFG(0x0, 0x1A, 0x411111F0), + + /* Pin Complex (NID 0x1D) PC-BEEP */ + AZALIA_PIN_CFG(0x0, 0x1D, 0x40400001), + + /* Pin Complex (NID 0x1E) SPDIF-OUT */ + AZALIA_PIN_CFG(0x0, 0x1E, 0x411111F0), + + /* Pin Complex (NID 0x1F) SPDIF-IN */ + AZALIA_PIN_CFG(0x0, 0x1F, 0x411111F0), + + /* Pin Complex (NID 0x21) HP-OUT (Port-A) */ + AZALIA_PIN_CFG(0x0, 0x21, 0x411111F0), + + /* POST I2S bypass output SRC */ + 0x0205002D, + 0x0204C020, + 0x0205002D, + 0x0204C020, + +}; + +const u32 pc_beep_verbs[0] = {}; + +AZALIA_ARRAY_SIZES; diff --git a/src/mainboard/facebook/fbg1701/irqroute.c b/src/mainboard/facebook/fbg1701/irqroute.c new file mode 100644 index 00000000000..a4ff6bf2b2e --- /dev/null +++ b/src/mainboard/facebook/fbg1701/irqroute.c @@ -0,0 +1,18 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "irqroute.h" + +DEFINE_IRQ_ROUTES; diff --git a/src/mainboard/facebook/fbg1701/irqroute.h b/src/mainboard/facebook/fbg1701/irqroute.h new file mode 100644 index 00000000000..6b7cb4169e8 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/irqroute.h @@ -0,0 +1,70 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/* + * IR02h GFX INT(A) - PIRQ A + * IR0Bh PUNIT INT(A) - PIRQ F + * IR10h EMMC INT(ABCD) - PIRQ DEFG + * IR11h SDIO INT(A) - PIRQ B + * IR12h SD INT(A) - PIRQ C + * IR13h SATA INT(A) - PIRQ D + * IR14h XHCI INT(A) - PIRQ E + * IR15h LP Audio INT(A) - PIRQ F + * IR17h MMC INT(A) - PIRQ F + * IR18h SIO INT(ABCD) - PIRQ BADC + * IR1Ah TXE INT(A) - PIRQ F + * IR1Bh HD Audio INT(A) - PIRQ G + * IR1Ch PCIe INT(ABCD) - PIRQ EFGH + * IR1Dh EHCI INT(A) - PIRQ D + * IR1Eh SIO INT(ABCD) - PIRQ BDEF + * IR1Fh LPC INT(ABCD) - PIRQ HGBC +*/ +#define PCI_DEV_PIRQ_ROUTES \ + PCI_DEV_PIRQ_ROUTE(GFX_DEV, A, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(PUNIT_DEV, F, F, F, F), \ + PCI_DEV_PIRQ_ROUTE(MMC_DEV, D, E, F, G), \ + PCI_DEV_PIRQ_ROUTE(SD_DEV, C, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SATA_DEV, D, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(XHCI_DEV, E, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(LPE_DEV, F, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(SIO1_DEV, B, A, D, C), \ + PCI_DEV_PIRQ_ROUTE(TXE_DEV, F, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(HDA_DEV, G, A, A, A), \ + PCI_DEV_PIRQ_ROUTE(PCIE_DEV, E, F, G, H), \ + PCI_DEV_PIRQ_ROUTE(SIO2_DEV, B, D, E, F), \ + PCI_DEV_PIRQ_ROUTE(PCU_DEV, H, G, B, C) + +/* + * Route each PIRQ[A-H] to a PIC IRQ[0-15] + * Reserved: 0, 1, 2, 8, 13 + * PS2 keyboard: 12 + * ACPI/SCI: 9 + * Floppy: 6 + */ +#define PIRQ_PIC_ROUTES \ + PIRQ_PIC(A, 11), \ + PIRQ_PIC(B, 5), \ + PIRQ_PIC(C, 5), \ + PIRQ_PIC(D, 11), \ + PIRQ_PIC(E, 11), \ + PIRQ_PIC(F, 5), \ + PIRQ_PIC(G, 11), \ + PIRQ_PIC(H, 11) diff --git a/src/mainboard/facebook/fbg1701/logo.c b/src/mainboard/facebook/fbg1701/logo.c new file mode 100644 index 00000000000..678d2e29233 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/logo.c @@ -0,0 +1,47 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2017 Patrick Rudolph + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include "mainboard.h" + +static char logo_data[1 * MiB]; +static size_t logo_data_sz = 0; + +void *load_logo(size_t *logo_size) +{ + const char *filename = "logo.bmp"; + + if (logo_data_sz != 0) { + if (logo_size) + *logo_size = logo_data_sz; + return (void *)logo_data; + } + + logo_data_sz = cbfs_boot_load_file(filename, logo_data, + sizeof(logo_data), CBFS_TYPE_RAW); + if (logo_data_sz == 0) + return NULL; + + if (logo_size) + *logo_size = logo_data_sz; + + printk(BIOS_DEBUG, "Found a Logo of %zu bytes after decompression\n", + logo_data_sz); + + return (void *)logo_data; +} diff --git a/src/mainboard/facebook/fbg1701/mainboard.c b/src/mainboard/facebook/fbg1701/mainboard.c new file mode 100644 index 00000000000..ff2564d67a7 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/mainboard.c @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007-2009 coresystems GmbH + * Copyright (C) 2011 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "onboard.h" +#include "mainboard.h" + +/* + * Declare the resources we are using + */ +static void mainboard_reserve_resources(struct device *dev) +{ + unsigned int idx = 0; + struct resource *res; + + /* + * CPLD: Reserve the IRQ here all others are within the default LPC + * range 0 to 1000h + */ + res = new_resource(dev, idx++); + res->base = 0x7; + res->size = 0x1; + res->flags = IORESOURCE_IRQ | IORESOURCE_ASSIGNED | IORESOURCE_FIXED; +} + +/* + * mainboard_enable is executed as first thing after + * enumerate_buses(). + */ +static void mainboard_enable(struct device *dev) +{ + mainboard_reserve_resources(dev); +} + +struct chip_operations mainboard_ops = { + .enable_dev = mainboard_enable, +}; diff --git a/src/mainboard/facebook/fbg1701/mainboard.h b/src/mainboard/facebook/fbg1701/mainboard.h new file mode 100644 index 00000000000..e161da03965 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/mainboard.h @@ -0,0 +1,21 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef MAINBOARD_H +#define MAINBOARD_H + +void *load_logo(size_t *logo_size); + +#endif diff --git a/src/mainboard/facebook/fbg1701/onboard.h b/src/mainboard/facebook/fbg1701/onboard.h new file mode 100644 index 00000000000..d1fd0509a6b --- /dev/null +++ b/src/mainboard/facebook/fbg1701/onboard.h @@ -0,0 +1,36 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef ONBOARD_H +#define ONBOARD_H + +/* SD CARD gpio */ +#define SDCARD_CD 81 /* Not used */ + +#define ITE8528_CMD_PORT 0x6E +#define ITE8528_DATA_PORT 0x6F + +/* CPLD definitions */ +#define CPLD_PCB_VERSION_PORT 0x283 +#define CPLD_PCB_VERSION_MASK 0xF0 +#define CPLD_PCB_VERSION_BIT 4 + +#define CPLD_RESET_PORT 0x287 +#define CPLD_CMD_RESET_DSI_BRIDGE_ACTIVE 0x20 +#define CPLD_CMD_RESET_DSI_BRIDGE_INACTIVE 0x00 + +#endif diff --git a/src/mainboard/facebook/fbg1701/ramstage.c b/src/mainboard/facebook/fbg1701/ramstage.c new file mode 100644 index 00000000000..91dfe3b2cf8 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/ramstage.c @@ -0,0 +1,32 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include "mainboard.h" + +void mainboard_silicon_init_params(SILICON_INIT_UPD *params) +{ + if (CONFIG(FSP1_1_DISPLAY_LOGO)) { + size_t logo_len; + void *logo = NULL; + + logo = load_logo(&logo_len); + + if (logo) { + params->PcdLogoPtr = (u32)logo; + params->PcdLogoSize = logo_len; + } + } +} diff --git a/src/mainboard/facebook/fbg1701/romstage.c b/src/mainboard/facebook/fbg1701/romstage.c new file mode 100644 index 00000000000..e2e37d6387b --- /dev/null +++ b/src/mainboard/facebook/fbg1701/romstage.c @@ -0,0 +1,51 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018-2019 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void mainboard_memory_init_params(struct romstage_params *params, + MEMORY_INIT_UPD *memory_params) +{ + struct region_device spd_rdev; + u8 spd_index = 0; + + if (CONFIG(ONBOARD_MICRON_MEM)) + spd_index = 1; + if (get_spd_cbfs_rdev(&spd_rdev, spd_index) < 0) + die("spd.bin not found\n"); + + memory_params->PcdMemoryTypeEnable = MEM_DDR3; + memory_params->PcdMemorySpdPtr = (uintptr_t)rdev_mmap_full(&spd_rdev); + memory_params->PcdMemChannel0Config = 1; /* Memory down */ + memory_params->PcdMemChannel1Config = 2; /* Disabled */ +} + +void mainboard_after_memory_init(void) +{ + printk(BIOS_DEBUG, "%s/%s called\n", __FILE__, __func__); + + /* Disable the Braswell UART hardware for COM1. */ + pci_write_config32(PCI_DEV(0, LPC_DEV, 0), UART_CONT, 0); +} diff --git a/src/mainboard/facebook/fbg1701/spd/MICRON_MT41K512M16HA-125A.spd.hex b/src/mainboard/facebook/fbg1701/spd/MICRON_MT41K512M16HA-125A.spd.hex new file mode 100644 index 00000000000..f18cbc2a87f --- /dev/null +++ b/src/mainboard/facebook/fbg1701/spd/MICRON_MT41K512M16HA-125A.spd.hex @@ -0,0 +1,257 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2019 Eltan B.V. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +# +# 8 Gb DDR3 (1600 MHz 11-11-11) Micron MT41K512M16HA-125:A +# +# SINGLE DIE +# + +# 512MBx16 64Mx16x8 ( 8 bank, 16 Rows, 10 Col, 2 KB page size ) +# 5-6-7-8-9-10-11 +# DDR3L-1600 +# tCk 1.25ns +# tRCD 13.75ns +# tRP 13.75ns +# tRAS 35ns +# tRC 48.75ns +# CL-tRCD-tRP 11-11-11 + +# 0 Number of SPD Bytes used / Total SPD Size / CRC Coverage +# bits[3:0]: 3 = 384 SPD Bytes Used +# bits[6:4]: 1 = 256 SPD Bytes Total +# bit7 : 0 = CRC covers bytes 0 ~ 128 +23 + +# 1 SPD Revision +# 0x10 = Revision 1.0 +10 + +# 2 Key Byte / DRAM Device Type +# bits[7:0]: 0x0c = DDR3 SDRAM +0B + +# 3 Key Byte / Module Type +# bits[3:0]: 3 = SODIMM +# bits[6:4]: 0 = Not hybrid +# bits[7]: 0 = Not hybrid +03 + +# 4 SDRAM CHIP Density and Banks +# bits[3:0]: 5 = 8 Gigabits Total SDRAM capacity per chip +# bits[6:4]: 0 = 3 (8 banks) +# bits[7]: reserverd +05 + +# 5 SDRAM Addressing +# bits[2:0]: 1 = 10 Column Address Bits +# bits[5:3]: 4 = 16 Row Address Bits +# bits[7:6]: 0 = reserved +21 + +# 6 Module Nominal Voltage +# bits[0]: 0 = 1.5V operable +# bits[1]: 1 = 1.35V operable +# bits[2]: 0 = NOT 1.25V operable +# bits[7:3]: reserved +02 + +# 7 Module Organization +# bits[2:0]: 010b = 16 bits SDRAM device +# bits[5:3]: 000b = 1 ranks +# bits[7:6]: reserved +02 + +# 8 Module Memory Bus width +# bits[2:0]: 3 = 64 bits pirmary bus width +# bits[4:3]: 0 = 0 bits bus witdth extension +# bits[7:5]: reserved +03 + +# 9 Fine Timebase (FTB) dividend / divisor +# bits[3:0]: 1 = Divisor +# bits[7:4]: 1 = Dividend +11 + +# 10 Medium Timebase (MTB) dividend +# bits[7:0]: 0 = 1 (timebase 0.125ns) +01 + +# 11 Medium Timebase (MTB) divisor +# bits[7:0]: 8 (timebase 0.125ns) +08 + +# 12 SDRAM Minimum cycle time (tCKmin) +# 0xA tCK = 1.25ns (DDR3-1600 (800 MHz clock)) +0A + +# 13 Reserved +00 + +# 14 CAS Latencies supported, Least Significate Byte +# Support 5,6,7,8,9,10,11 +FE + +# 15 CAS Latencies supported, Most Significate Byte +# No supporting CL 12-18 +00 + +# 16 Minimum CAS Latency Time (tAAmin) +# 0x69 tAA = 13.125ns (offset = 00) DDR3-1600K downbin +69 + +# 17 Minimum Write Recovery Time (tWRmin) +# 0x78 tWR = 15 ns +78 + +# 18 Minimum RAS to CAS Delay Time (tRCDmin) +# 0x69 tRCD = 13.125ns (offset 00) DDR3-1600K downbin +69 + +# 19 Minimum Row Active to Row Active Delay Time (tRRDmin) +# 0x3C tRRD = 7.5ns DDR3-1600, 2KB +3C + +# 20 Minimum Row Precharge Delay Time (tRPmin) +# 0x69 tRP = 13.125ns (offset 00) DDR3-1600K downbin +69 + +# 21 Upper Nibble for tRAS and tRC +# 3:0 : 1 higher tRAS = 35ns +# 7:0 : 1 higher tRC = 48.125ns +11 + +# 22 Minimum Active to Precharge Delay Time (tRASmin), Least Significant byte +# lower 0x118 : tRAS = 35ns DDR3-1600 +18 + +# 23 Minimum Active to Precharge Delay Time (tRCmin), Most Significant byte +# lower 0x181 : tRC = 48.125ns (offset 00) DDR3-1600K downbin +81 + +# 24 Minimum Refresh Recovery Delay time (tRFCmin), Least Significant byte +# lower 0xAF0 : tRFC = 350ns 8 Gb +F0 + +# 25 Minimum Refresh Recovery Delay time (tRFCmin), Most Significant byte +# higher 0xAF0 : tRFC = 350ns 8 Gb +0A + +# 26 tWTRmin +# 0x3C : tWTR = 7.5 ns (DDR3) +3C + +# 27 tRTPmin +# 0x3C : tRTP = 7.5 ns (DDR3) +3C + +# 28 Upper Nibble for tFAW +# Bit [3:0] : 1 = higher 0x140 tFAW = 40ns +01 + +# 29 tFAWmin Lower +# lower 0x140 : tFAW = 40ns +40 + +# 30 SDRAM Optional Features +# byte [0] : 1 = RZQ/6 is support +# byte [1] : 1 = RZQ/7 is supported +# byte [7] : 1 = DLL-Off Mode support +83 + +# 31 Thermal options +# byte [0] : 1 = 0 - 95C +# byte [2] : 1 = Auto Self Refresh (ASR) is supported +# byte [7] : 1 = Partial Array Self Refres (PASR) is supported +85 + +# 32 Module Thermal support +# byte [0] : 0 = Thermal sensor accuracy undefined +# byte [7] : 0 = No thermal sensor +00 + +# 33 SDRAM device type +# byte [1:0] : 00b = Signal Loading not specified +# byte [6:4] : 000b = Die count not specified +# byte [7] : 1 = Non-Standard Device +80 + +# 34 Fine tCKmin +# 0x00 tCK = 1.25ns (DDR3-1600 (800 MHz clock)) +00 + +# 35 Fine tAAmin +# 0x00 tAA = 13.125ns (tAAmin offset = 00) DDR3-1600K downbin +00 + +# 36 Fine tRCDmin +# 0x00 tRCD = 13.125ns DDR3-1600K downbin +00 + +# 37 Fine tRPmin +# 0x00 tRP = 13.125ns (offset 00) DDR3-1600K downbin +00 + +# 38 Fine tRCmin +# 0x00 tRC = 48.125ns (offset 00) DDR3-1600K downbin +00 + +# 39-59 reserved, general section +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 + +# 60-116 Module specific section +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 + +# 117-118 Module Manufacturer +80 2C + +# 119 Module Manufacturing Location +01 + +# 120-121 Module Manufacturing Date +13 0A + +# 122-125 Module Serial number +00 00 00 00 + +# 126-127 SPD CRC +00 00 + +# 128-145 Module Part number +4D 54 34 31 4B 35 31 32 4D 31 36 48 41 2D 31 32 +35 00 + +# 145-146 Module revision code +00 00 + +# 148-149 DRAM Manufacturer ID code +80 2C + +# 150-175 Manufacturer Specific Data +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 + +# 176-255 Open for Customer Use + +# 176 - 255 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/facebook/fbg1701/spd/SAMSUNG_K4B8G1646D-MYKO.spd.hex b/src/mainboard/facebook/fbg1701/spd/SAMSUNG_K4B8G1646D-MYKO.spd.hex new file mode 100644 index 00000000000..64faf1e163d --- /dev/null +++ b/src/mainboard/facebook/fbg1701/spd/SAMSUNG_K4B8G1646D-MYKO.spd.hex @@ -0,0 +1,254 @@ +# +# This file is part of the coreboot project. +# +# Copyright (C) 2018-2019 Eltan B.V. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# + +# +# 8 Gb DDR3 (1600 MHz 11-11-11) Samsung K4B8G1646D-MYK0 +# +# DUAL DIE +# +# 512Mb x16 ( 8 bank, 16 Rows, 10 Col, 2 KB page size ) +# 5-6-7-8-9-10-11 +# DDR3L-1600 +# tCk 1.25ns +# tRCD 13.75ns +# tRP 13.75ns +# tRAS 35ns +# tRC 48.75ns +# CL-tRCD-tRP 11-11-11 + +# 0 Number of SPD Bytes used / Total SPD Size / CRC Coverage +# bits[3:0]: 3 = 384 SPD Bytes Used +# bits[6:4]: 1 = 256 SPD Bytes Total +# bit7 : 0 = CRC covers bytes 0 ~ 128 +23 + +# 1 SPD Revision +# 0x10 = Revision 1.0 +10 + +# 2 Key Byte / DRAM Device Type +# bits[7:0]: 0x0c = DDR3 SDRAM +0B + +# 3 Key Byte / Module Type +# bits[3:0]: 3 = SODIMM +# bits[6:4]: 0 = Not hybrid +# bits[7]: 0 = Not hybrid +03 + +# 4 SDRAM CHIP Density and Banks +# bits[3:0]: 4 = 4 Gigabits Total SDRAM capacity per chip +# bits[6:4]: 0 = 3 (8 banks) +# bits[7]: reserverd +04 + +# 5 SDRAM Addressing +# bits[2:0]: 1 = 10 Column Address Bits +# bits[5:3]: 100b = 16 Row Address Bits +# bits[7:6]: 0 = reserved +21 + +# 6 Module Nominal Voltage +# bits[0]: 0 = 1.5V operable +# bits[1]: 1 = 1.35V operable +# bits[2]: 0 = NOT 1.25V operable +# bits[7:3]: reserved +02 + +# 7 Module Organization +# bits[2:0]: 010b = 16 bits SDRAM device +# bits[5:3]: 001b = 2 ranks +# bits[7:6]: reserved +0A + +# 8 Module Memory Bus width +# bits[2:0]: 3 = 64 bits pirmary bus width +# bits[4:3]: 0 = 0 bits bus witdth extension +# bits[7:5]: reserved +03 + +# 9 Fine Timebase (FTB) dividend / divisor +# bits[3:0]: 1 = Divisor +# bits[7:4]: 1 = Dividend +11 + +# 10 Medium Timebase (MTB) dividend +# bits[7:0]: 0 = 1 (timebase 0.125ns) +01 + +# 11 Medium Timebase (MTB) divisor +# bits[7:0]: 8 (timebase 0.125ns) +08 + +# 12 SDRAM Minimum cycle time (tCKmin) +# 0xA tCK = 1.25ns (DDR3-1600 (800 MHz clock)) +0A + +# 13 Reserved +00 + +# 14 CAS Latencies supported, Least Significate Byte +# Support 5,6,7,8,9,10,11 +FE + +# 15 CAS Latencies supported, Most Significate Byte +# Not supporting CL 12-18 +00 + +# 16 Minimum CAS Latency Time (tAAmin) +# 0x69 tAA = 13.125ns (offset = 00) DDR3-1600K downbin +69 + +# 17 Minimum Write Recovery Time (tWRmin) +# 0x78 tWR = 15 ns +78 + +# 18 Minimum RAS to CAS Delay Time (tRCDmin) +# 0x69 tRCD = 13.125ns (offset 00) DDR3-1600K downbin +69 + +# 19 Minimum Row Active to Row Active Delay Time (tRRDmin) +# 48 tRRD = 6.0ns DDR3-1600, 1KB +30 + +# 20 Minimum Row Precharge Delay Time (tRPmin) +# 0x69 tRP = 13.125ns (offset 00) DDR3-1600K downbin +69 + +# 21 Upper Nibble for tRAS and tRC +# 3:0 : 1 higher tRAS = 35ns +# 7:0 : 1 higher tRC = 48.125ns +11 + +# 22 Minimum Active to Precharge Delay Time (tRASmin), Least Significant byte +# lower 0x118 : tRAS = 35ns DDR3-1600 +18 + +# 23 Minimum Active to Precharge Delay Time (tRCmin), Most Significant byte +# lower 0x181 : tRC = 48.125ns (offset 00) DDR3-1600K downbin +81 + +# 24 Minimum Refresh Recovery Delay time (tRFCmin), Least Significant byte +# lower 0x680 : tRFC = 208ns 4 Gb +80 + +# 25 Minimum Refresh Recovery Delay time (tRFCmin), Most Significant byte +# higher 0x680 : tRFC = 208ns 4 Gb +06 + +# 26 tWTRmin +# 0x3C : tWTR = 7.5 ns (DDR3) +3C + +# 27 tRTPmin +# 0x3C : tRTP = 7.5 ns (DDR3) +3C + +# 28 Upper Nibble for tFAW +# Bit [3:0] : 1 = higher 0x140 tFAW = 40ns DDR3-1600K, 2 KB page size +01 + +# 29 tFAWmin Lower +# lower 0x140 : tFAW = 40ns DDR3-1600K, 2 KB page size +40 + +# 30 SDRAM Optional Features +# byte [0] : 1 = RZQ/6 is support +# byte [1] : 1 = RZQ/7 is supported +# byte [7] : 1 = DLL-Off Mode support +83 + +# 31 Thermal options +# byte [2]: 1 = Auto Self Refresh (ASR) is supported +04 + +# 32 Module Thermal support +# byte [0] : 0 = Thermal sensor accuracy undefined +# byte [7] : 0 = No thermal sensor +00 + +# 33 SDRAM device type +# byte [1:0] : 01b = multi load stack +# byte [6:4] : 100b = 8 die +# byte [7] : 0 = Standard Device +41 + +# 34 Fine tCKmin +# 0x00 tCK = 1.25ns (DDR3-1600 (800 MHz clock)) +00 + +# 35 Fine tAAmin +# 0x00 tAA = 13.125ns (tAAmin offset = 00) DDR3-1600K downbin +00 + +# 36 Fine tRCDmin +# 0x00 tRCD = 13.125ns DDR3-1600K downbin +00 + +# 37 Fine tRPmin +# 0x00 tRP = 13.125ns (offset 00) DDR3-1600K downbin +00 + +# 38 Fine tRCmin +# 0x00 tRC = 48.125ns (offset 00) DDR3-1600K downbin +00 + +# 39-59 reserved, general section +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 + +# 60-116 Module specific section +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 + +# 117-118 Module Manufacturer +80 CE + +# 119 Module Manufacturing Location +01 + +# 120-121 Module Manufacturing Date +12 1B + +# 122-125 Module Serial number +00 00 00 00 + +# 126-127 SPD CRC +00 00 + +# 128-145 Module Part number +4B 34 42 38 47 31 36 34 36 44 2D 4D 59 4B 30 20 +20 20 + +# 145-146 Module revision code +00 00 + +# 148-149 DRAM Manufacturer ID code +80 CE + +# 150-175 Manufacturer Specific Data +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 + +# 176-255 Open for Customer Use + +# 176 - 255 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diff --git a/src/mainboard/facebook/fbg1701/w25q64.c b/src/mainboard/facebook/fbg1701/w25q64.c new file mode 100644 index 00000000000..bc908f04b34 --- /dev/null +++ b/src/mainboard/facebook/fbg1701/w25q64.c @@ -0,0 +1,78 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corp. + * Copyright (C) 2018 Eltan B.V. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include + +/* + * SPI lockdown configuration + */ +#define SPI_OPMENU_0 CMD_W25_WRSR /* Write Status Register */ +#define SPI_OPTYPE_0 SPI_OPTYPE_WR_NOADDR /* Write, no address */ + +#define SPI_OPMENU_1 CMD_W25_PP /* BYPR: Byte Program */ +#define SPI_OPTYPE_1 SPI_OPTYPE_WR_ADDR /* Write, address required */ + +#define SPI_OPMENU_2 CMD_W25_READ /* Read Data */ +#define SPI_OPTYPE_2 SPI_OPTYPE_RD_ADDR /* Read, address required */ + +#define SPI_OPMENU_3 CMD_W25_RDSR /* Read Status Register */ +#define SPI_OPTYPE_3 SPI_OPTYPE_RD_NOADDR /* Read, no address */ + +#define SPI_OPMENU_4 CMD_W25_SE /* Sector Erase */ +#define SPI_OPTYPE_4 SPI_OPTYPE_WR_ADDR /* Write, address required */ + +#define SPI_OPMENU_5 CMD_W25_RDID /* Read ID */ +#define SPI_OPTYPE_5 SPI_OPTYPE_RD_NOADDR /* Read, no address */ + +#define SPI_OPMENU_6 CMD_W25_BE /* BE: Block Erase */ +#define SPI_OPTYPE_6 SPI_OPTYPE_WR_ADDR /* Write, address required */ + +#define SPI_OPMENU_7 CMD_W25_FAST_READ /* FAST: Fast Read */ +#define SPI_OPTYPE_7 SPI_OPTYPE_RD_ADDR /* Read, address required */ + +#define SPI_OPPREFIX CMD_W25_WREN /* WREN only to be inline */ + /* with flashrom */ + +#define SPI_OPTYPE ((SPI_OPTYPE_7 << 14) | (SPI_OPTYPE_6 << 12) | \ + (SPI_OPTYPE_5 << 10) | (SPI_OPTYPE_4 << 8) | \ + (SPI_OPTYPE_3 << 6) | (SPI_OPTYPE_2 << 4) | \ + (SPI_OPTYPE_1 << 2) | (SPI_OPTYPE_0 << 0)) + +#define SPI_OPMENU_UPPER ((SPI_OPMENU_7 << 24) | (SPI_OPMENU_6 << 16) | \ + (SPI_OPMENU_5 << 8) | (SPI_OPMENU_4 << 0)) + +#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \ + (SPI_OPMENU_1 << 8) | (SPI_OPMENU_0 << 0)) + +#define SPI_VSCC (WG_64_BYTE | EO(0x20) | BES_4_KB) + +static const struct spi_config spi_config = { + .preop = CMD_W25_WREN, + .optype = SPI_OPTYPE, + .opmenu = { SPI_OPMENU_LOWER, SPI_OPMENU_UPPER }, + .lvscc = SPI_VSCC, + .uvscc = SPI_VSCC, +}; + +int mainboard_get_spi_config(struct spi_config *cfg) +{ + memcpy(cfg, &spi_config, sizeof(*cfg)); + + return 0; +} From 1583fcd13fe436e815977f96086412adabcb7dd7 Mon Sep 17 00:00:00 2001 From: Frans Hendriks Date: Wed, 5 Jun 2019 10:18:23 +0200 Subject: [PATCH 582/588] MAINTAINERS: Add maintainer to Facebook FBG1701 Add maintainers to the new mainboard port. Change-Id: I620ea424cc26fa0218a74052863ea30700789e1b Signed-off-by: Frans Hendriks Reviewed-on: https://review.coreboot.org/c/coreboot/+/33224 Tested-by: build bot (Jenkins) Reviewed-by: Philipp Deppenwiese --- MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 04f784f8899..f1ae0769373 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -382,6 +382,12 @@ M: Tristan Corrick S: Maintained F: src/mainboard/supermicro/x10slm-f/ +FACEBOOK FBG1701 MAINBOARD +M: Frans Hendriks +M: Wim Vervoorn +S: Maintained +F: src/mainboard/facebook/fbg1701/ + AMD FAMILY10H & FAMILY15H (NON-AGESA) CPUS & NORTHBRIDGE M: Timothy Pearson S: Supported From dab15ca91ec0f613a3766af791b1c46cd04e61b0 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Tue, 28 May 2019 18:44:44 +0200 Subject: [PATCH 583/588] src/lib/bootmem.c,selfboot.c: permanently reserve memory for payload Signed-off-by: Krystian Hebel --- payloads/Kconfig | 16 ++++++++++++++++ src/lib/bootmem.c | 22 ++++++++++++++++++++++ src/lib/selfboot.c | 14 ++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/payloads/Kconfig b/payloads/Kconfig index d0f8a440800..28312e69ace 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -151,4 +151,20 @@ config TINT_SECONDARY_PAYLOAD source "payloads/external/*/Kconfig.secondary" endmenu # "Secondary Payloads" + +menu "Reserve RAM for payload" + +config CUSTOM_RAM_RES_ADDR + hex "Base address for reserved memory" + default 0 + help + If a payload needs some preallocated memory this field specifies + starting address of reserved memory region. + +config CUSTOM_RAM_RES_SIZE + hex "Size of reserved memory" + default 0 + help + Size (in bytes) of reserved memory region. +endmenu endmenu diff --git a/src/lib/bootmem.c b/src/lib/bootmem.c index 01ad3e841bf..02727d74123 100644 --- a/src/lib/bootmem.c +++ b/src/lib/bootmem.c @@ -96,6 +96,28 @@ static void bootmem_init(void) bootmem_arch_add_ranges(); bootmem_platform_add_ranges(); + + if (CONFIG_CUSTOM_RAM_RES_SIZE != 0) { + const struct range_entry *r; + size_t start = CONFIG_CUSTOM_RAM_RES_ADDR; + size_t end = CONFIG_CUSTOM_RAM_RES_ADDR + CONFIG_CUSTOM_RAM_RES_SIZE; + memranges_each_entry(r, bm) { + /* All further bootmem entries are beyond this range. */ + if (end <= range_entry_base(r)) + break; + + if (start >= range_entry_base(r) && end <= range_entry_end(r)) { + if (range_entry_tag(r) == BM_MEM_RAM) { + bootmem_add_range(CONFIG_CUSTOM_RAM_RES_ADDR, + CONFIG_CUSTOM_RAM_RES_SIZE, BM_MEM_RESERVED); + return; + } + } + } + printk(BIOS_ERR, "ERROR: Tried to reserve memory %lx - %lx," + " but it is not RAM\n", start, end); + die("Check CUSTOM_RAM_RES_ADDR and CUSTOM_RAM_RES_ADDR\n"); + } } void bootmem_add_range(uint64_t start, uint64_t size, diff --git a/src/lib/selfboot.c b/src/lib/selfboot.c index a0bb711f8a1..0d6ae54f91d 100644 --- a/src/lib/selfboot.c +++ b/src/lib/selfboot.c @@ -46,6 +46,17 @@ static void cbfs_decode_payload_segment(struct cbfs_payload_segment *segment, segment->mem_len = read_be32(&src->mem_len); } +static int payload_target_custom_reserved_ram(uint64_t start, uint64_t size) +{ + if (start >= CONFIG_CUSTOM_RAM_RES_ADDR && + (start + size) <= (CONFIG_CUSTOM_RAM_RES_ADDR + CONFIG_CUSTOM_RAM_RES_SIZE)) { + printk(BIOS_DEBUG, "Payload being loaded in reserved memory.\n"); + return 1; + } + + return 0; +} + static int segment_targets_type(void *dest, unsigned long memsz, enum bootmem_type dest_type) { @@ -56,6 +67,9 @@ static int segment_targets_type(void *dest, unsigned long memsz, if (payload_arch_usable_ram_quirk(d, memsz)) return 1; + if (payload_target_custom_reserved_ram(d, memsz)) + return 1; + printk(BIOS_ERR, "SELF segment doesn't target RAM: 0x%p, %lu bytes\n", dest, memsz); bootmem_dump_ranges(); return 0; From 25860553fb34df6563cea8525e352febfe0b5fb1 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Wed, 15 May 2019 16:19:05 +0200 Subject: [PATCH 584/588] libpayload: x86_64 support 32-bit code can still be run with i386_do_exec() - it is run in true protected mode, not compatibility mode. Exceptions were tested with #DE, #GP and #DB. Apparently BSS is not cleared by SeaBIOS, it needs to be cleared manually. This operation can take some time, depending mostly on stack/heap size. Signed-off-by: Krystian Hebel --- payloads/libpayload/Kconfig | 26 +- payloads/libpayload/Makefile | 2 + payloads/libpayload/Makefile.inc | 3 +- payloads/libpayload/arch/x86/Kconfig | 2 +- payloads/libpayload/arch/x86/Makefile.inc | 21 +- payloads/libpayload/arch/x86/exception.c | 95 ++++-- .../libpayload/arch/x86/exception_asm64.S | 317 +++++++++++++++++ payloads/libpayload/arch/x86/exec64.S | 134 ++++++++ payloads/libpayload/arch/x86/head.S | 322 ++++++++++++++++++ ...ayload.ldscript => libpayload.ldscript.in} | 6 + payloads/libpayload/arch/x86/rom_media.c | 8 +- payloads/libpayload/arch/x86/virtual.c | 4 +- payloads/libpayload/bin/lpas | 9 +- payloads/libpayload/bin/lpgcc | 9 +- .../libpayload/drivers/storage/ahci_common.c | 4 +- payloads/libpayload/drivers/timer/Kconfig | 6 +- payloads/libpayload/include/sysinfo.h | 2 +- .../libpayload/include/x86/arch/exception.h | 70 ++-- payloads/libpayload/include/x86/arch/io.h | 4 +- payloads/libpayload/include/x86/arch/rdtsc.h | 6 + .../libpayload/include/x86/arch/virtual.h | 8 +- payloads/libpayload/libc/time.c | 2 +- payloads/libpayload/libcbfs/cbfs_core.c | 2 +- 23 files changed, 966 insertions(+), 96 deletions(-) create mode 100644 payloads/libpayload/arch/x86/exception_asm64.S create mode 100644 payloads/libpayload/arch/x86/exec64.S rename payloads/libpayload/arch/x86/{libpayload.ldscript => libpayload.ldscript.in} (94%) diff --git a/payloads/libpayload/Kconfig b/payloads/libpayload/Kconfig index 97b970b0f14..03c5e52ee4a 100644 --- a/payloads/libpayload/Kconfig +++ b/payloads/libpayload/Kconfig @@ -109,6 +109,11 @@ config ARCH_X86 help Support the x86 architecture +config ARCH_X86_64 + bool "x86_64" + help + Support the x86_64 architecture + config ARCH_ARM64 bool "ARM64" help @@ -123,7 +128,7 @@ endchoice config MULTIBOOT bool "Multiboot header support" - depends on ARCH_X86 + depends on ARCH_X86 || ARCH_X86_64 default y if !CHROMEOS config HEAP_SIZE @@ -149,6 +154,7 @@ config BASE_ADDRESS default 0x80100000 if ARCH_ARM64 default 0x00000000 if ARCH_MIPS default 0x00100000 if ARCH_X86 + default 0x21000000 if ARCH_X86_64 help This is the base address for the payload. @@ -241,7 +247,7 @@ config SERIAL_CONSOLE config 8250_SERIAL_CONSOLE bool "8250-compatible serial port driver (including IO and MMIO)" depends on SERIAL_CONSOLE - default y if ARCH_X86 + default y if ARCH_X86 || ARCH_X86_64 config S5P_SERIAL_CONSOLE bool "Exynos SOC, S5P compatible serial port driver" @@ -271,7 +277,7 @@ config PL011_SERIAL_CONSOLE config SERIAL_IOBASE ## This default is currently not used on non-x86 systems. hex "Default I/O base for the serial port (default 0x3f8)" - depends on SERIAL_CONSOLE && ARCH_X86 + depends on SERIAL_CONSOLE && (ARCH_X86 || ARCH_X86_64) default 0x3f8 config SERIAL_SET_SPEED @@ -304,12 +310,12 @@ config VIDEO_CONSOLE config VGA_VIDEO_CONSOLE bool "VGA video console driver" - depends on ARCH_X86 && VIDEO_CONSOLE + depends on (ARCH_X86 || ARCH_X86_64) && VIDEO_CONSOLE default y if !CHROMEOS config GEODELX_VIDEO_CONSOLE bool "Geode LX video console driver" - depends on ARCH_X86 && VIDEO_CONSOLE + depends on (ARCH_X86 || ARCH_X86_64) && VIDEO_CONSOLE default n config COREBOOT_VIDEO_CONSOLE @@ -339,14 +345,14 @@ config PC_I8042 config PC_MOUSE bool "Allow input from a PC mouse" default n if CHROMEOS - default y if ARCH_X86 # uses IO + default y if ARCH_X86 || ARCH_X86_64 # uses IO default n help PS/2 mouse driver on top of PC_I8042. config PC_KEYBOARD bool "Allow input from a PC keyboard" - default y if ARCH_X86 # uses IO + default y if ARCH_X86 || ARCH_X86_64 # uses IO default n config PC_KEYBOARD_IGNORE_INIT_FAILURE @@ -369,12 +375,12 @@ menu "Drivers" config PCI bool "Support for PCI devices" - depends on ARCH_X86 # for now + depends on ARCH_X86 || ARCH_X86_64 # for now default y config NVRAM bool "Support for reading/writing NVRAM bytes" - depends on ARCH_X86 # for now + depends on ARCH_X86 || ARCH_X86_64 # for now default y config MOUSE_CURSOR @@ -406,7 +412,7 @@ config RTC_PORT_EXTENDED_VIA config SPEAKER bool "Support for PC speaker" - depends on ARCH_X86 + depends on ARCH_X86 || ARCH_X86_64 default y if !CHROMEOS source "drivers/timer/Kconfig" diff --git a/payloads/libpayload/Makefile b/payloads/libpayload/Makefile index 1a0acf1781b..891b0c41357 100644 --- a/payloads/libpayload/Makefile +++ b/payloads/libpayload/Makefile @@ -97,6 +97,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_MIPS) := mips ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 +ARCHDIR-$(CONFIG_LP_ARCH_X86_64) := x86 ARCH-y := $(ARCHDIR-y) @@ -105,6 +106,7 @@ ARCH-y := $(ARCHDIR-y) ARCH-$(CONFIG_LP_ARCH_ARM) := arm ARCH-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCH-$(CONFIG_LP_ARCH_X86) := x86_32 +ARCH-$(CONFIG_LP_ARCH_X86_64) := x86_64 ARCH-$(CONFIG_LP_ARCH_MIPS) := mips # Three cases where we don't need fully populated $(obj) lists: diff --git a/payloads/libpayload/Makefile.inc b/payloads/libpayload/Makefile.inc index 7787762b43c..9f4de391116 100644 --- a/payloads/libpayload/Makefile.inc +++ b/payloads/libpayload/Makefile.inc @@ -35,6 +35,7 @@ ARCHDIR-$(CONFIG_LP_ARCH_ARM) := arm ARCHDIR-$(CONFIG_LP_ARCH_ARM64) := arm64 ARCHDIR-$(CONFIG_LP_ARCH_MIPS) := mips ARCHDIR-$(CONFIG_LP_ARCH_X86) := x86 +ARCHDIR-$(CONFIG_LP_ARCH_X86_64) := x86 DESTDIR ?= install real-target: lib @@ -93,7 +94,7 @@ $(obj)/head.o: $(obj)/arch/$(ARCHDIR-y)/head.head.o.o printf " CP $(subst $(CURDIR)/,,$(@))\n" cp $^ $@ -install: real-target +install: real-target arch/$(ARCHDIR-y)/libpayload.ldscript printf " INSTALL $(DESTDIR)/libpayload/lib\n" install -m 755 -d $(DESTDIR)/libpayload/lib for lib in $(library-targets); do \ diff --git a/payloads/libpayload/arch/x86/Kconfig b/payloads/libpayload/arch/x86/Kconfig index 129ff5f6821..4e6415f881a 100644 --- a/payloads/libpayload/arch/x86/Kconfig +++ b/payloads/libpayload/arch/x86/Kconfig @@ -27,7 +27,7 @@ ## SUCH DAMAGE. ## -if ARCH_X86 +if ARCH_X86 || ARCH_X86_64 config ARCH_SPECIFIC_OPTIONS # dummy def_bool y diff --git a/payloads/libpayload/arch/x86/Makefile.inc b/payloads/libpayload/arch/x86/Makefile.inc index 0cc477399af..8b63fb77f26 100644 --- a/payloads/libpayload/arch/x86/Makefile.inc +++ b/payloads/libpayload/arch/x86/Makefile.inc @@ -27,16 +27,29 @@ ## SUCH DAMAGE. ## + +ifeq ($(CONFIG_LP_ARCH_X86_64),y) +# x64 needs at least 16-byte aligned stack (PSB=4) +CFLAGS += -mpreferred-stack-boundary=4 -mno-red-zone +else CFLAGS += -mpreferred-stack-boundary=2 +endif head.o-y += head.S + libc-y += main.c sysinfo.c libc-y += timer.c coreboot.c util.S -libc-y += exec.S virtual.c +libc-y += virtual.c libc-y += selfboot.c -libc-y += exception_asm.S exception.c +libc-y += exception.c libc-y += delay.c +ifeq ($(CONFIG_LP_ARCH_X86_64),y) +libc-y += exec64.S exception_asm64.S +else +libc-y += exec.S exception_asm.S +endif + # Will fall back to default_memXXX() in libc/memory.c if GPL not allowed. libc-$(CONFIG_LP_GPL) += string.c @@ -48,3 +61,7 @@ libcbfs-$(CONFIG_LP_CBFS) += rom_media.c libc-$(CONFIG_LP_MULTIBOOT) += multiboot.c libc-$(CONFIG_LP_ENABLE_APIC) += apic.c + +arch/$(ARCHDIR-y)/libpayload.ldscript: $(obj)/libpayload-config.h FORCE + gcc -E -x c -Iinclude -I$(obj) arch/$(ARCHDIR-y)/libpayload.ldscript.in | grep -v "^#" > arch/$(ARCHDIR-y)/libpayload.ldscript +FORCE: diff --git a/payloads/libpayload/arch/x86/exception.c b/payloads/libpayload/arch/x86/exception.c index 13ff58ccbe4..2bac4aefa95 100644 --- a/payloads/libpayload/arch/x86/exception.c +++ b/payloads/libpayload/arch/x86/exception.c @@ -35,7 +35,7 @@ #define IF_FLAG (1 << 9) -u32 exception_stack[0x400] __attribute__((aligned(8))); +size_t exception_stack[0x400] __attribute__((aligned(8))); static interrupt_handler handlers[256]; @@ -61,9 +61,9 @@ static const char *names[EXC_COUNT] = { [EXC_SX] = "Security", }; -static void print_segment_error_code(u32 code) +static void print_segment_error_code(size_t code) { - printf("%#x - descriptor %#x in the ", code, (code >> 3) & 0x1FFF); + printf("%#zx - descriptor %#zx in the ", code, (code >> 3) & 0x1FFF); if (code & (0x1 << 1)) { printf("IDT"); } else { @@ -78,9 +78,9 @@ static void print_segment_error_code(u32 code) printf(", internal to the CPU"); } -static void print_page_fault_error_code(u32 code) +static void print_page_fault_error_code(size_t code) { - printf("%#x -", code); + printf("%#zx -", code); if (code & (0x1 << 0)) printf(" page protection"); else @@ -99,22 +99,22 @@ static void print_page_fault_error_code(u32 code) printf(", instruction fetch"); } -static void print_raw_error_code(u32 code) +static void print_raw_error_code(size_t code) { - printf("%#x", code); + printf("%#zx", code); } static void dump_stack(uintptr_t addr, size_t bytes) { int i, j; - const int line = 8; - uint32_t *ptr = (uint32_t *)(addr & ~(line * sizeof(*ptr) - 1)); + const int line = 32 / sizeof(size_t); + size_t *ptr = (size_t *)(addr & ~(line * sizeof(*ptr) - 1)); printf("Dumping stack:\n"); for (i = bytes / sizeof(*ptr); i >= 0; i -= line) { printf("%p: ", ptr + i); for (j = i; j < i + line; j++) - printf("%08x ", *(ptr + j)); + printf("%0*zx ", (int)(2*sizeof(size_t)), *(ptr + j)); printf("\n"); } } @@ -144,28 +144,55 @@ static void dump_exception_state(void) break; } printf("\n"); - printf("EIP: 0x%08x\n", exception_state->regs.eip); - printf("CS: 0x%04x\n", exception_state->regs.cs); - printf("EFLAGS: 0x%08x\n", exception_state->regs.eflags); - printf("EAX: 0x%08x\n", exception_state->regs.eax); - printf("ECX: 0x%08x\n", exception_state->regs.ecx); - printf("EDX: 0x%08x\n", exception_state->regs.edx); - printf("EBX: 0x%08x\n", exception_state->regs.ebx); - printf("ESP: 0x%08x\n", exception_state->regs.esp); - printf("EBP: 0x%08x\n", exception_state->regs.ebp); - printf("ESI: 0x%08x\n", exception_state->regs.esi); - printf("EDI: 0x%08x\n", exception_state->regs.edi); - printf("DS: 0x%04x\n", exception_state->regs.ds); - printf("ES: 0x%04x\n", exception_state->regs.es); - printf("SS: 0x%04x\n", exception_state->regs.ss); - printf("FS: 0x%04x\n", exception_state->regs.fs); - printf("GS: 0x%04x\n", exception_state->regs.gs); +#if CONFIG(LP_ARCH_X86_64) + printf("RIP: 0x%016zx\n", exception_state->regs.rip); + printf("CS: 0x%04zx\n", exception_state->regs.cs); + printf("RFLAGS: 0x%016zx\n", exception_state->regs.rflags); + printf("RAX: 0x%016zx\n", exception_state->regs.rax); + printf("RCX: 0x%016zx\n", exception_state->regs.rcx); + printf("RDX: 0x%016zx\n", exception_state->regs.rdx); + printf("RBX: 0x%016zx\n", exception_state->regs.rbx); + printf("RSP: 0x%016zx\n", exception_state->regs.rsp); + printf("RBP: 0x%016zx\n", exception_state->regs.rbp); + printf("RSI: 0x%016zx\n", exception_state->regs.rsi); + printf("RDI: 0x%016zx\n", exception_state->regs.rdi); + printf("R8: 0x%016zx\n", exception_state->regs.r8); + printf("R9: 0x%016zx\n", exception_state->regs.r9); + printf("R10: 0x%016zx\n", exception_state->regs.r10); + printf("R11: 0x%016zx\n", exception_state->regs.r11); + printf("R12: 0x%016zx\n", exception_state->regs.r12); + printf("R13: 0x%016zx\n", exception_state->regs.r13); + printf("R14: 0x%016zx\n", exception_state->regs.r14); + printf("R15: 0x%016zx\n", exception_state->regs.r15); + printf("DS: 0x%04zx\n", exception_state->regs.ds); + printf("ES: 0x%04zx\n", exception_state->regs.es); + printf("SS: 0x%04zx\n", exception_state->regs.ss); + printf("FS: 0x%04zx\n", exception_state->regs.fs); + printf("GS: 0x%04zx\n", exception_state->regs.gs); +#else + printf("EIP: 0x%08zx\n", exception_state->regs.eip); + printf("CS: 0x%04zx\n", exception_state->regs.cs); + printf("EFLAGS: 0x%08zx\n", exception_state->regs.eflags); + printf("EAX: 0x%08zx\n", exception_state->regs.eax); + printf("ECX: 0x%08zx\n", exception_state->regs.ecx); + printf("EDX: 0x%08zx\n", exception_state->regs.edx); + printf("EBX: 0x%08zx\n", exception_state->regs.ebx); + printf("ESP: 0x%08zx\n", exception_state->regs.esp); + printf("EBP: 0x%08zx\n", exception_state->regs.ebp); + printf("ESI: 0x%08zx\n", exception_state->regs.esi); + printf("EDI: 0x%08zx\n", exception_state->regs.edi); + printf("DS: 0x%04zx\n", exception_state->regs.ds); + printf("ES: 0x%04zx\n", exception_state->regs.es); + printf("SS: 0x%04zx\n", exception_state->regs.ss); + printf("FS: 0x%04zx\n", exception_state->regs.fs); + printf("GS: 0x%04zx\n", exception_state->regs.gs); +#endif } void exception_dispatch(void) { die_if(exception_state->vector >= ARRAY_SIZE(handlers), - "Invalid vector %u\n", exception_state->vector); + "Invalid vector %zu\n", exception_state->vector); u8 vec = exception_state->vector; @@ -185,7 +212,11 @@ void exception_dispatch(void) vec); dump_exception_state(); +#if CONFIG(LP_ARCH_X86_64) + dump_stack(exception_state->regs.rsp, 1024); +#else dump_stack(exception_state->regs.esp, 512); +#endif /* We don't call apic_eoi because we don't want to ack the interrupt and allow another interrupt to wake the processor. */ halt(); @@ -207,14 +238,14 @@ void set_interrupt_handler(u8 vector, interrupt_handler handler) handlers[vector] = handler; } -static uint32_t eflags(void) +static size_t flags(void) { - uint32_t eflags; + size_t flags; asm volatile( "pushf\n\t" "pop %0\n\t" - : "=rm" (eflags)); - return eflags; + : "=rm" (flags)); + return flags; } void enable_interrupts(void) @@ -234,5 +265,5 @@ void disable_interrupts(void) int interrupts_enabled(void) { - return !!(eflags() & IF_FLAG); + return !!(flags() & IF_FLAG); } diff --git a/payloads/libpayload/arch/x86/exception_asm64.S b/payloads/libpayload/arch/x86/exception_asm64.S new file mode 100644 index 00000000000..a14742870a3 --- /dev/null +++ b/payloads/libpayload/arch/x86/exception_asm64.S @@ -0,0 +1,317 @@ +/* + * This file is part of the libpayload project. + * + * Copyright 2013 Google Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + .align 16 + .global exception_stack_end +exception_stack_end: + .quad 0 + .global exception_state +exception_state: + .quad 0 + +/* Some temporary variables which are used while saving exception state. */ +vector: + .quad 0 +error_code: + .quad 0 +old_rsp: + .quad 0 +old_rax: + .quad 0 +old_rdx: + .quad 0 + + .align 16 + +.code64 + +/* + * Each exception vector has a small stub associated with it which sets aside + * the error code, if any, records which vector we entered from, and calls + * the common exception entry point. Some exceptions have error codes and some + * don't, so we have a macro for each type. + */ + + .macro stub num +exception_stub_\num: + movq $0, error_code + movq $\num, vector + jmp exception_common + .endm + + .macro stub_err num +exception_stub_\num: + popq error_code + movq $\num, vector + jmp exception_common + .endm + + .altmacro + .macro user_defined_stubs from, to + stub \from + .if \to-\from + user_defined_stubs %(from+1),\to + .endif + .endm + + stub 0 + stub 1 + stub 2 + stub 3 + stub 4 + stub 5 + stub 6 + stub 7 + stub_err 8 + stub 9 + stub_err 10 + stub_err 11 + stub_err 12 + stub_err 13 + stub_err 14 + stub 15 + stub 16 + stub_err 17 + stub 18 + stub 19 + stub 20 + stub 21 + stub 22 + stub 23 + stub 24 + stub 25 + stub 26 + stub 27 + stub 28 + stub 29 + stub_err 30 + stub 31 + /* Split the macro so we avoid a stack overflow. */ + user_defined_stubs 32, 63 + user_defined_stubs 64, 127 + user_defined_stubs 128, 191 + user_defined_stubs 192, 255 + +exception_common: + /* + * Save off the stack pointer and old eax value and install the + * exception stack. eax points to the old stack which has the + * exception ip, cs, and flags. + */ + movq %rax, old_rax + movq 24(%rsp), %rax + movq %rax, old_rsp + movq %rdx, old_rdx + movq %rsp, %rax + movq exception_stack_end, %rsp + + /* + * Push values onto the top of the exception stack to form an + * exception state structure. + */ + pushq vector + pushq error_code + mov %gs, %rdx + pushq %rdx + mov %fs, %rdx + pushq %rdx + mov %es, %rdx + pushq %rdx + mov %ds, %rdx + pushq %rdx + mov %ss, %rdx + pushq %rdx + pushq 8(%rax) + pushq 16(%rax) + pushq (%rax) + pushq %r15 + pushq %r14 + pushq %r13 + pushq %r12 + pushq %r11 + pushq %r10 + pushq %r9 + pushq %r8 + pushq %rdi + pushq %rsi + pushq %rbp + pushq old_rsp + pushq %rbx + pushq old_rdx + pushq %rcx + pushq old_rax + + /* + * Call the C exception handler. It will find the exception state + * using the exception_state global pointer. Not + * passing parameters means we don't have to worry about what ABI + * is being used. + */ + movq %rsp, exception_state + call exception_dispatch + + /* + * Restore state from the exception state structure, including any + * changes that might have been made. + */ + popq old_rax + popq %rcx + popq old_rdx + popq %rbx + popq old_rsp + + movq old_rsp, %rax + andq $~(0xf), %rax + subq $40, %rax + + popq %rbp + popq %rsi + popq %rdi + popq %r8 + popq %r9 + popq %r10 + popq %r11 + popq %r12 + popq %r13 + popq %r14 + popq %r15 + popq (%rax) + popq 16(%rax) + popq 8(%rax) + popq %rdx + mov %rdx, %ss + popq %rdx + mov %rdx, %ds + popq %rdx + mov %rdx, %es + popq %rdx + mov %rdx, %fs + popq %rdx + mov %rdx, %gs + + movq %rax, %rsp + movq old_rax, %rax + movq old_rdx, %rdx + + /* Return from the exception. */ + iretq + + /* + * Record the target and construct the actual entry at init time. This + * is necessary because the linker doesn't want to construct the entry + * for us. + */ + .macro interrupt_gate target + .quad \target + .quad \target + .endm + + .altmacro + .macro user_defined_gates from, to + interrupt_gate exception_stub_\from + .if \to-\from + user_defined_gates %(from+1),\to + .endif + .endm + + .align 8 + .global idt +idt: + interrupt_gate exception_stub_0 + interrupt_gate exception_stub_1 + interrupt_gate exception_stub_2 + interrupt_gate exception_stub_3 + interrupt_gate exception_stub_4 + interrupt_gate exception_stub_5 + interrupt_gate exception_stub_6 + interrupt_gate exception_stub_7 + interrupt_gate exception_stub_8 + interrupt_gate exception_stub_9 + interrupt_gate exception_stub_10 + interrupt_gate exception_stub_11 + interrupt_gate exception_stub_12 + interrupt_gate exception_stub_13 + interrupt_gate exception_stub_14 + interrupt_gate exception_stub_15 + interrupt_gate exception_stub_16 + interrupt_gate exception_stub_17 + interrupt_gate exception_stub_18 + interrupt_gate exception_stub_19 + interrupt_gate exception_stub_20 + interrupt_gate exception_stub_21 + interrupt_gate exception_stub_22 + interrupt_gate exception_stub_23 + interrupt_gate exception_stub_24 + interrupt_gate exception_stub_25 + interrupt_gate exception_stub_26 + interrupt_gate exception_stub_27 + interrupt_gate exception_stub_28 + interrupt_gate exception_stub_29 + interrupt_gate exception_stub_30 + interrupt_gate exception_stub_31 + user_defined_gates 32, 63 + user_defined_gates 64, 127 + user_defined_gates 128, 191 + user_defined_gates 192, 255 +idt_end: + +/* IDT pointer for use with lidt */ +idt_ptr: + .word idt_end - idt - 1 + .quad idt + + .global exception_init_asm +exception_init_asm: + /* + * Loop over the entries which start out as two copies of the target + * address. We can turn them into real interrupt gates by selectively + * replacing certain bit fields. + */ + movq $idt, %rax + movq $0x00008e0000180000, %rcx +1: + movq (%rax), %rdi + movq %rdi, %rsi + movq %rdi, %rdx + andl $0xffff0000, %esi + shlq $32, %rsi + andq $0x0000ffff, %rdx + orq %rdx, %rsi + orq %rcx, %rsi + movq %rsi, (%rax) + shrq $32, %rdi + movq %rdi, 8(%rax) + addq $16, %rax + cmpq $idt_end, %rax + jne 1b + + /* Install the IDT. */ + lidt idt_ptr + + ret diff --git a/payloads/libpayload/arch/x86/exec64.S b/payloads/libpayload/arch/x86/exec64.S new file mode 100644 index 00000000000..48c418f7b7d --- /dev/null +++ b/payloads/libpayload/arch/x86/exec64.S @@ -0,0 +1,134 @@ +/* + * This file is part of the libpayload project. + * + * Copyright (C) 2008 Advanced Micro Devices, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* calling syntax: i386_do_exec(long addr, int argc, char **argv, int *ret) */ + +/* This implements the payload API detailed here: + * https://www.coreboot.org/Payload_API + */ + +.align 4 +.text + +.code64 +.global i386_do_exec + .type i386_do_exec,@function + +i386_do_exec: + pushq %rbx + pushq %rbp + pushq %rdx + pushq %rcx + + movq $0x08, %rcx + call SetCodeSelector + +.code32 + pushl %ebp + movl %esp, %ebp + + /* Save the remaining callee preserved registers */ + pushl %ebx + pushl %esi + pushl %edi + + /* Disable paging */ + movl %cr0, %eax + andl $0x7FFFFFFF, %eax + movl %eax, %cr0 + + /* Disable long mode */ + movl $0xC0000080, %ecx + rdmsr + btrl $8, %eax + wrmsr + + /* Push argc and argv on to the stack. + * + * We need to put a dummy value inbetween, as argc should be at offset + * 0x10, according to the payload API. + */ + pushl %esi /* argc */ + pushl $0 + pushl 12(%ebp) /* argv, saved on stack */ + + /* Push a "magic" number on the stack - the other payload will use this + * as a clue that the argc and argv values on the stack are sane. + */ + pushl $0x12345678 + + /* Jump to the code */ + call *%edi + /* %eax has the return value */ + + /* Skip over the argc/argv stuff still on the stack. + * Don't assume %ebp is sane, here. Restore it from the stack. + */ + addl $0x10, %esp + + /* Restore the saved registers */ + popl %edi + popl %esi + popl %ebx + popl %ebp + + /* Get pointer to return value and save the return value in it. */ + movl (%esp), %ecx + movl %eax, (%ecx) + + /* Use long jump to switch to 64-bit code segment */ + ljmp $0x18, $1f +.code64 +1: + popq %rcx + popq %rdx + popq %rbp + popq %rbx + + ret + +SetCodeSelector: + # pop the return address from stack + pop %rbx + + # save rsp because we need to push it after ss + mov %rsp, %rdx + + # use iret to jump to a 32-bit offset in a new code segment + # iret will pop cs:rip, flags, then ss:rsp + mov %ss, %ax # need to push ss.. + push %rax # push ss instuction not valid in x64 mode, + # so use ax + push %rdx # the rsp to load + pushfq # push rflags + push %rcx # cx is code segment selector from caller + push %rbx # push the IP for the next instruction + + # the iretq will behave like ret, with the new cs/ss value loaded + iretq diff --git a/payloads/libpayload/arch/x86/head.S b/payloads/libpayload/arch/x86/head.S index 0575dbe8cc4..04a4ad4f0f5 100644 --- a/payloads/libpayload/arch/x86/head.S +++ b/payloads/libpayload/arch/x86/head.S @@ -61,6 +61,7 @@ mb_header: #define CB_ARGV 0x08 #define CB_ARGC 0x10 +#if !CONFIG(LP_ARCH_X86_64) /* * This function saves off the previous stack and switches us to our * own execution environment. @@ -142,3 +143,324 @@ _leave: /* Return to the original context. */ ret + + +#else +/* + * This function saves off the previous stack and switches us to our + * own execution environment. + */ +_init: + /* No interrupts, please. */ + cli + cld + + /* Store EAX and EBX */ + movl %eax, loader_eax + movl %ebx, loader_ebx + + /* Copy argv[] and argc as demanded by the Payload API, + * see https://www.coreboot.org/Payload_API and exec.S. + */ + cmpl $CB_MAGIC_VALUE, CB_MAGIC(%esp) + jne 1f + + movl CB_ARGV(%esp), %eax + movl %eax, main_argv + movl $0, (main_argv+4) + + movl CB_ARGC(%esp), %eax + movl %eax, main_argc +1: + /* Store current stack pointer and set up new stack. */ + movl %esp, %ebx + movl $_stack, %esp + andl $0xfffffff0, %esp + + pushl $0 /* keep stack aligned for x64 calls (SysV ABI) */ + pushl $0 + pushl $0 + pushl %ebx + + /* Enable special x86 functions if present. */ + pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + + movl $0, %eax + cpuid + /* Test if CPUID(eax=1) is available. */ + test %eax, %eax + je cpuid_done + + /* Get CPU features. */ + movl $1, %eax + cpuid + +cpuid_fpu: + /* Test if x87 FPU is present */ + test $1, %edx + je cpuid_sse + + fninit + movl %cr0, %eax + andl $0xFFFFFFFB, %eax /* clear EM */ + orl $0x00000022, %eax /* set MP, NE */ + movl %eax, %cr0 + +cpuid_sse: + /* Test if SSE is available */ + test $0x02000000, %edx + je cpuid_done + + movl %cr4, %eax + orl $0x00000600, %eax /* set OSFXSR, OSXMMEXCPT */ + movl %eax, %cr4 + +cpuid_done: + popl %edx + popl %ecx + popl %ebx + popl %eax + + /* Prepare GDT for 64-bit operation */ + lgdt %cs:gdtptr + ljmp $0x08, $1f +1: + movl $0x10, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + + call _gen_long_mode_pgtbl32 + + /* Load identity mapped page tables */ + movl $(_pagetables), %eax + movl %eax, %cr3 + + /* Enable PAE */ + movl %cr4, %eax + btsl $5, %eax + movl %eax, %cr4 + + /* Enable long mode */ + movl $0xC0000080, %ecx /* 0xC0000080 = IA32_EFER */ + rdmsr + btsl $8, %eax + wrmsr + + /* Enable paging */ + movl %cr0, %eax + btsl $31, %eax + movl %eax, %cr0 + + /* Use long jump to switch to 64-bit code segment */ + ljmp $0x18, $1f +.code64 +1: + + /* Clear bss */ + movq $_edata, %rdi + addq $7, %rdi + andq $(~7), %rdi + movq %rsp, %rcx + subq %rdi, %rcx + shrq $3, %rcx + xorq %rax, %rax + rep stosq + + /* Let's rock. */ + call start_main + + /* %eax has the return value - pass it on unmolested */ +_leave: + /* Just in case */ + cli + + /* Ensure cache is clean. */ + invd + + push %rax + + /* Set 32-bit code segment and ss */ + mov $0x08, %rcx + call SetCodeSelector + +.code32 + /* Running in 32-bit compatibility mode */ + + /* Use flat 32-bit data segment. */ + movl $0x10, %eax + movl %eax, %ds + movl %eax, %es + movl %eax, %ss + movl %eax, %fs + movl %eax, %gs + + /* Disable paging */ + movl %cr0, %eax + andl $0x7FFFFFFF, %eax + movl %eax, %cr0 + + /* Disable long mode */ + movl $0xC0000080, %ecx + rdmsr + btrl $8, %eax + wrmsr + + /* Disable PAE */ + movl %cr4, %eax + andl $(~0x20), %eax + movl %eax, %cr4 + + popl %eax + addl $4, %esp /* we pushed %rax, but poped %eax */ + + /* Restore old stack. */ + popl %esp + + /* Return to the original context. */ + ret + + .align 4 +.globl gdtptr +gdtptr: + .word gdt_end - gdt -1 /* compute the table limit */ + .long gdt /* we know the offset */ + + .align 4 +gdt: + /* selgdt 0, unused */ + .word 0x0000, 0x0000 /* dummy */ + .byte 0x00, 0x00, 0x00, 0x00 + + /* selgdt 0x08, flat code segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes + for limit */ + + /* selgdt 0x10,flat data segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00 + + /* selgdt 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 + +gdt_end: + + +/* Page table attributes: WB, Supervisor, Present, Writeable */ +#define PAGE_ATTRIBUTES 0x003 + +/* + * Creates identity mapped page entries. + * Identity maps 0 - 4GiB using arbitraty page size. + * Use offset: + * 12 for 4 KiB pages + * 12 + 9 for 2 MiB pages + * 12 + 9 + 9 for 1 GiB pages + * + * edi: The destination (in _pagetables) + * Clobers: esi, edi, ebx + */ +.code32 +.macro gen_page_entries32 offset + xorl %esi, %esi + xorl %ebx, %ebx +1: + movl $(PAGE_ATTRIBUTES | (1 << 7)), 0x00(%edi) + orl %esi, 0x00(%edi) + movl %ebx, 0x04(%edi) + addl $(1 << (\offset)), %esi + addl $8, %edi + cmpl %ebx, %esi + ja 1b +.endm + +_gen_long_mode_pgtbl32: + + /* Setup long mode: identity map 0-4GiB */ + + movl $(_pagetables), %ecx + xorl %eax, %eax + + /* Generate one PM4LE entry - point to PDPE */ + leal (0x1000)(%ecx), %edi + movl %edi, (%ecx) + orl $(PAGE_ATTRIBUTES), (%ecx) + movl %eax, 4(%ecx) + + /* Read CPUID(eax=0x80000001) EDX BIT26 */ + movl $0x80000001, %eax + cpuid + btsl $26, %edx + jc paging_1g_pages +paging_2m_pages: + + /* With 2 MiB hugepages we need 6 pages of 4096 byte */ + + movl $(PAGE_ATTRIBUTES), %ebx + + /* edi points to PDPE table, point esi to PDE tables */ + movl %edi, %esi + addl $0x1000, %esi + + movl $4, %eax + /* Point to the to be generated PDE tables */ +1: + mov %ebx, 0x0(%edi) + or %esi, 0x0(%edi) + movl $0, 0x4(%edi) + add $0x1000, %esi + add $8, %edi + dec %eax + jnz 1b + + /* point edi to PDE tables */ + movl $(_pagetables), %ecx + leal (0x2000)(%ecx), %edi + + /* Fill the PDE tables : Generate 4 * 512 PDE entries */ + gen_page_entries32 (12 + 9) + + ret + +paging_1g_pages: + /* With 1 GiB hugepages we need 2 pages of 4096 byte */ + + /* edi points to PDPE table already */ + + /* Fill the PDPE table : Generate 4 PDPE entries */ + gen_page_entries32 (12 + 9 + 9) + + ret + +.code64 +SetCodeSelector: + # pop the return address from stack + pop %rbx + + # save rsp because we need to push it after ss + mov %rsp, %rdx + + # use iret to jump to a 32-bit offset in a new code segment + # iret will pop cs:rip, flags, then ss:rsp + mov %ss, %ax # need to push ss.. + push %rax # push ss instuction not valid in x64 mode, + # so use ax + push %rdx # the rsp to load + pushfq # push rflags + push %rcx # cx is code segment selector from caller + push %rbx # push the IP for the next instruction + + # the iretq will behave like ret, with the new cs/ss value loaded + iretq + +.align 4096 +_pagetables: + .fill 4096 * 6 +#endif diff --git a/payloads/libpayload/arch/x86/libpayload.ldscript b/payloads/libpayload/arch/x86/libpayload.ldscript.in similarity index 94% rename from payloads/libpayload/arch/x86/libpayload.ldscript rename to payloads/libpayload/arch/x86/libpayload.ldscript.in index bcb2165a2fc..00696838746 100644 --- a/payloads/libpayload/arch/x86/libpayload.ldscript +++ b/payloads/libpayload/arch/x86/libpayload.ldscript.in @@ -27,8 +27,14 @@ * SUCH DAMAGE. */ +#include +#if CONFIG(LP_ARCH_X86_64) +OUTPUT_FORMAT(elf64-x86-64) +OUTPUT_ARCH(i386:x86-64) +#else OUTPUT_FORMAT(elf32-i386) OUTPUT_ARCH(i386) +#endif ENTRY(_entry) diff --git a/payloads/libpayload/arch/x86/rom_media.c b/payloads/libpayload/arch/x86/rom_media.c index d9c27fa8b42..99b65e74c79 100644 --- a/payloads/libpayload/arch/x86/rom_media.c +++ b/payloads/libpayload/arch/x86/rom_media.c @@ -51,10 +51,10 @@ static void *x86_rom_map(struct cbfs_media *media, size_t offset, size_t count) // mapped location. To workaround that, we handle >0xf0000000 as real // memory pointer. - if ((uint32_t)offset > (uint32_t)0xf0000000) + if ((size_t)offset > (size_t)0xf0000000) ptr = (void*)offset; else - ptr = (void*)(0 - (uint32_t)media->context + offset); + ptr = (void*)(size_t)(0x100000000ULL - (size_t)media->context + offset); return ptr; } @@ -80,7 +80,7 @@ int init_x86rom_cbfs_media(struct cbfs_media *media) { // 0xfffffffc, and the pointer is still a memory-mapped address. // Since the CBFS core always use ROM offset, we need to figure out // header->romsize even before media is initialized. - struct cbfs_header *header = (struct cbfs_header*) + struct cbfs_header *header = (struct cbfs_header*)(size_t) *(uint32_t*)(0xfffffffc); if (CBFS_HEADER_MAGIC != ntohl(header->magic)) { #if CONFIG(LP_ROM_SIZE) @@ -91,7 +91,7 @@ int init_x86rom_cbfs_media(struct cbfs_media *media) { #endif } else { uint32_t romsize = ntohl(header->romsize); - media->context = (void*)romsize; + media->context = (void*)(size_t)romsize; #if CONFIG(LP_ROM_SIZE) if (CONFIG_LP_ROM_SIZE != romsize) printk(BIOS_INFO, "Warning: rom size unmatch (%d/%d)\n", diff --git a/payloads/libpayload/arch/x86/virtual.c b/payloads/libpayload/arch/x86/virtual.c index 59768dbd66b..5fb3151ced7 100644 --- a/payloads/libpayload/arch/x86/virtual.c +++ b/payloads/libpayload/arch/x86/virtual.c @@ -28,9 +28,9 @@ */ #include +#include -unsigned long virtual_offset = 0; - +uintptr_t virtual_offset = 0; int getpagesize(void) { diff --git a/payloads/libpayload/bin/lpas b/payloads/libpayload/bin/lpas index a82570ceb05..dd56de52022 100755 --- a/payloads/libpayload/bin/lpas +++ b/payloads/libpayload/bin/lpas @@ -64,13 +64,6 @@ CMDLINE= while [ $# -gt 0 ]; do case $1 in - --32) - shift - continue - ;; - --64) - error "Invalid option --64 - only 32 bit architectures are supported" - ;; -debug-wrapper) DEBUGME=1 shift @@ -84,7 +77,7 @@ while [ $# -gt 0 ]; do shift done -_ASFLAGS="--32 -I$_INCDIR" +_ASFLAGS="-I$_INCDIR" if [ $DEBUGME -eq 1 ]; then echo "$DEFAULT_AS $_ASFLAGS $CMDLINE" diff --git a/payloads/libpayload/bin/lpgcc b/payloads/libpayload/bin/lpgcc index b3ef342ff28..8a2d139787a 100755 --- a/payloads/libpayload/bin/lpgcc +++ b/payloads/libpayload/bin/lpgcc @@ -92,6 +92,12 @@ if [ "$CONFIG_LP_ARCH_X86" = "y" ]; then _ARCHEXTRA="-m32 " _ARCH=x86 fi +if [ "$CONFIG_LP_ARCH_X86_64" = "y" ]; then + _ARCHINCDIR=$_INCDIR/x86 + _ARCHLIBDIR=$_LIBDIR/x86 + _ARCHEXTRA="-m64 " + _ARCH=x86_64 +fi if [ -f $_LIBDIR/libpayload.ldscript ]; then _LDDIR=$_LIBDIR @@ -120,9 +126,6 @@ while [ $# -gt 0 ]; do shift continue ;; - -m64) - error "Invalid option --64 - only 32 bit architectures are supported" - ;; -c) DOLINK=0 ;; diff --git a/payloads/libpayload/drivers/storage/ahci_common.c b/payloads/libpayload/drivers/storage/ahci_common.c index ef9d43d3068..20e6dfdf89b 100644 --- a/payloads/libpayload/drivers/storage/ahci_common.c +++ b/payloads/libpayload/drivers/storage/ahci_common.c @@ -69,7 +69,7 @@ static u8 *ahci_prdbuf_init(ahci_dev_t *const dev, u8 *const user_buf, const size_t len, const int out) { - if ((u32)user_buf & 1) { + if ((size_t)user_buf & 1) { printf("ahci: Odd buffer pointer (%p).\n", user_buf); if (dev->buf) /* orphaned buffer */ free(dev->buf - *(dev->buf - 1)); @@ -79,7 +79,7 @@ static u8 *ahci_prdbuf_init(ahci_dev_t *const dev, dev->user_buf = user_buf; dev->write_back = !out; dev->buflen = len; - if ((u32)dev->buf & 1) { + if ((size_t)dev->buf & 1) { dev->buf[0] = 1; dev->buf += 1; } else { diff --git a/payloads/libpayload/drivers/timer/Kconfig b/payloads/libpayload/drivers/timer/Kconfig index 5a61dfab51b..ba4976f7ccd 100644 --- a/payloads/libpayload/drivers/timer/Kconfig +++ b/payloads/libpayload/drivers/timer/Kconfig @@ -12,12 +12,12 @@ choice prompt "Timer driver" - default TIMER_NONE if !ARCH_X86 - default TIMER_RDTSC if ARCH_X86 + default TIMER_NONE if !(ARCH_X86 || ARCH_X86_64) + default TIMER_RDTSC if ARCH_X86 || ARCH_X86_64 config TIMER_RDTSC bool "x86 rdtsc" - depends on ARCH_X86 + depends on ARCH_X86 || ARCH_X86_64 config TIMER_NONE bool "None" diff --git a/payloads/libpayload/include/sysinfo.h b/payloads/libpayload/include/sysinfo.h index 72059adb91d..03df76de598 100644 --- a/payloads/libpayload/include/sysinfo.h +++ b/payloads/libpayload/include/sysinfo.h @@ -100,7 +100,7 @@ struct sysinfo_t { void *vboot_workbuf; uint32_t vboot_workbuf_size; -#if CONFIG(LP_ARCH_X86) +#if CONFIG(LP_ARCH_X86) || CONFIG(LP_ARCH_X86_64) int x86_rom_var_mtrr_index; #endif diff --git a/payloads/libpayload/include/x86/arch/exception.h b/payloads/libpayload/include/x86/arch/exception.h index a6c2afcf0d7..9fede2d0c05 100644 --- a/payloads/libpayload/include/x86/arch/exception.h +++ b/payloads/libpayload/include/x86/arch/exception.h @@ -31,6 +31,7 @@ #define _ARCH_EXCEPTION_H #include +#include void exception_init_asm(void); void exception_dispatch(void); @@ -42,31 +43,60 @@ int interrupts_enabled(void); struct exception_state { /* Careful: x86/gdb.c currently relies on the size and order of regs. */ +#if CONFIG(LP_ARCH_X86_64) struct { - u32 eax; - u32 ecx; - u32 edx; - u32 ebx; - u32 esp; - u32 ebp; - u32 esi; - u32 edi; - u32 eip; - u32 eflags; - u32 cs; - u32 ss; - u32 ds; - u32 es; - u32 fs; - u32 gs; + size_t rax; + size_t rcx; + size_t rdx; + size_t rbx; + size_t rsp; + size_t rbp; + size_t rsi; + size_t rdi; + size_t r8; + size_t r9; + size_t r10; + size_t r11; + size_t r12; + size_t r13; + size_t r14; + size_t r15; + size_t rip; + size_t rflags; + size_t cs; + size_t ss; + size_t ds; + size_t es; + size_t fs; + size_t gs; } regs; - u32 error_code; - u32 vector; +#else + struct { + size_t eax; + size_t ecx; + size_t edx; + size_t ebx; + size_t esp; + size_t ebp; + size_t esi; + size_t edi; + size_t eip; + size_t eflags; + size_t cs; + size_t ss; + size_t ds; + size_t es; + size_t fs; + size_t gs; + } regs; +#endif + size_t error_code; + size_t vector; } __packed; extern struct exception_state *exception_state; -extern u32 exception_stack[]; -extern u32 *exception_stack_end; +extern uintptr_t exception_stack[]; +extern uintptr_t *exception_stack_end; enum { EXC_DE = 0, /* Divide by zero */ diff --git a/payloads/libpayload/include/x86/arch/io.h b/payloads/libpayload/include/x86/arch/io.h index c417ce0c667..7482eaaddf0 100644 --- a/payloads/libpayload/include/x86/arch/io.h +++ b/payloads/libpayload/include/x86/arch/io.h @@ -82,7 +82,7 @@ static inline __attribute__((always_inline)) void write32(volatile void *addr, u static inline unsigned int inl(int port) { unsigned long val; - __asm__ __volatile__("inl %w1, %0" : "=a"(val) : "Nd"(port)); + __asm__ __volatile__("inl %w1, %k0" : "=a"(val) : "Nd"(port)); return val; } @@ -102,7 +102,7 @@ static inline unsigned char inb(int port) static inline void outl(unsigned int val, int port) { - __asm__ __volatile__("outl %0, %w1" : : "a"(val), "Nd"(port)); + __asm__ __volatile__("outl %k0, %w1" : : "a"(val), "Nd"(port)); } static inline void outw(unsigned short val, int port) diff --git a/payloads/libpayload/include/x86/arch/rdtsc.h b/payloads/libpayload/include/x86/arch/rdtsc.h index ef23e0e247c..041c55386d4 100644 --- a/payloads/libpayload/include/x86/arch/rdtsc.h +++ b/payloads/libpayload/include/x86/arch/rdtsc.h @@ -34,9 +34,15 @@ static u64 rdtsc(void) { +#if CONFIG(LP_ARCH_X86_64) + u32 low, high; + __asm__ __volatile__ ("rdtsc" : "=a" (low), "=d" (high)); + return ((u64)high << 32) | low; +#else u64 val; __asm__ __volatile__ ("rdtsc" : "=A" (val)); return val; +#endif } #endif diff --git a/payloads/libpayload/include/x86/arch/virtual.h b/payloads/libpayload/include/x86/arch/virtual.h index 328c3aa34ef..779bd59fcb4 100644 --- a/payloads/libpayload/include/x86/arch/virtual.h +++ b/payloads/libpayload/include/x86/arch/virtual.h @@ -30,10 +30,12 @@ #ifndef _ARCH_VIRTUAL_H #define _ARCH_VIRTUAL_H -extern unsigned long virtual_offset; +#include -#define virt_to_phys(virt) ((unsigned long) (virt) + virtual_offset) -#define phys_to_virt(phys) ((void *) ((unsigned long) (phys) - virtual_offset)) +extern uintptr_t virtual_offset; + +#define virt_to_phys(virt) ((size_t) (virt) + virtual_offset) +#define phys_to_virt(phys) ((void *) ((size_t) (phys) - virtual_offset)) #define virt_to_bus(addr) virt_to_phys(addr) #define bus_to_virt(addr) phys_to_virt(addr) diff --git a/payloads/libpayload/libc/time.c b/payloads/libpayload/libc/time.c index 75834486b5b..50a1a6deb72 100644 --- a/payloads/libpayload/libc/time.c +++ b/payloads/libpayload/libc/time.c @@ -34,7 +34,7 @@ #include #include -#if CONFIG(LP_ARCH_X86) && CONFIG(LP_NVRAM) +#if (CONFIG(LP_ARCH_X86) || CONFIG(LP_ARCH_X86_64)) && CONFIG(LP_NVRAM) #include #endif diff --git a/payloads/libpayload/libcbfs/cbfs_core.c b/payloads/libpayload/libcbfs/cbfs_core.c index e94e1e76baf..1343fca99cb 100644 --- a/payloads/libpayload/libcbfs/cbfs_core.c +++ b/payloads/libpayload/libcbfs/cbfs_core.c @@ -119,7 +119,7 @@ static int get_cbfs_range(uint32_t *offset, uint32_t *cbfs_end, // Logical offset (for source media) of first file. *offset = ntohl(header->offset); *cbfs_end = ntohl(header->romsize); -#if CONFIG(LP_ARCH_X86) +#if CONFIG(LP_ARCH_X86) || CONFIG(LP_ARCH_X86_64) // resolve actual length of ROM used for CBFS components // the bootblock size was not taken into account *cbfs_end -= ntohl(header->bootblocksize); From 37b0f6d17c7219340acb584b1fef979b6e131339 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Wed, 15 May 2019 16:21:25 +0200 Subject: [PATCH 585/588] libpayload/configs/defconfig-tinycurses-64: test config for x86_64 Signed-off-by: Krystian Hebel --- payloads/libpayload/configs/defconfig-tinycurses-64 | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 payloads/libpayload/configs/defconfig-tinycurses-64 diff --git a/payloads/libpayload/configs/defconfig-tinycurses-64 b/payloads/libpayload/configs/defconfig-tinycurses-64 new file mode 100644 index 00000000000..c447c917d55 --- /dev/null +++ b/payloads/libpayload/configs/defconfig-tinycurses-64 @@ -0,0 +1,11 @@ +CONFIG_LP_ARCH_X86_64=y +# CONFIG_LP_MULTIBOOT is not set +CONFIG_LP_TINYCURSES=y +CONFIG_LP_COREBOOT_VIDEO_CONSOLE=y +CONFIG_LP_USB=y +CONFIG_LP_USB_UHCI=y +CONFIG_LP_USB_OHCI=y +CONFIG_LP_USB_EHCI=y +CONFIG_LP_USB_XHCI=y +CONFIG_LP_HEAP_SIZE=536870912 +CONFIG_LP_STACK_SIZE=8388608 From 4e77e7e9cd2dcab6c2f0df679899f2f5b2d83a2f Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 24 May 2019 17:51:54 +0200 Subject: [PATCH 586/588] payloads/bareflank: initial commit All include/* files were obtained from Bareflank commit ba613e2c687f Signed-off-by: Krystian Hebel --- payloads/Kconfig | 7 + payloads/Makefile.inc | 9 + payloads/bareflank/Kconfig | 17 + payloads/bareflank/Makefile | 144 + payloads/bareflank/common.c | 521 ++++ payloads/bareflank/entry.c | 205 ++ payloads/bareflank/include/bfaffinity.h | 61 + payloads/bareflank/include/bfarch.h | 49 + payloads/bareflank/include/bfbenchmark.h | 114 + payloads/bareflank/include/bfbitmanip.h | 274 ++ payloads/bareflank/include/bfbuffer.h | 309 ++ payloads/bareflank/include/bfcallonce.h | 56 + payloads/bareflank/include/bfconstants.h | 277 ++ payloads/bareflank/include/bfdebug.h | 1137 ++++++++ .../bareflank/include/bfdebugringinterface.h | 163 ++ payloads/bareflank/include/bfdelegate.h | 282 ++ .../bareflank/include/bfdriverinterface.h | 116 + payloads/bareflank/include/bfdwarf.h | 96 + payloads/bareflank/include/bfehframelist.h | 68 + payloads/bareflank/include/bfelf_loader.h | 2531 +++++++++++++++++ .../include/bfelf_loader_reloc_aarch64.h | 263 ++ .../include/bfelf_loader_reloc_x64.h | 93 + payloads/bareflank/include/bferrorcodes.h | 174 ++ payloads/bareflank/include/bfexception.h | 144 + payloads/bareflank/include/bfexports.h | 37 + payloads/bareflank/include/bffile.h | 345 +++ payloads/bareflank/include/bfgsl.h | 282 ++ payloads/bareflank/include/bfjson.h | 113 + payloads/bareflank/include/bfmanager.h | 198 ++ payloads/bareflank/include/bfmemory.h | 75 + payloads/bareflank/include/bfobject.h | 57 + payloads/bareflank/include/bfplatform.h | 177 ++ payloads/bareflank/include/bfshuffle.h | 49 + payloads/bareflank/include/bfstd.h | 118 + payloads/bareflank/include/bfstring.h | 142 + payloads/bareflank/include/bfsupport.h | 196 ++ payloads/bareflank/include/bfthreadcontext.h | 115 + payloads/bareflank/include/bftypes.h | 138 + payloads/bareflank/include/bfupperlower.h | 146 + payloads/bareflank/include/bfvcpuid.h | 64 + payloads/bareflank/include/bfvector.h | 140 + payloads/bareflank/include/common.h | 176 ++ payloads/bareflank/platform.c | 86 + payloads/external/Makefile.inc | 12 + 44 files changed, 9776 insertions(+) create mode 100644 payloads/bareflank/Kconfig create mode 100644 payloads/bareflank/Makefile create mode 100755 payloads/bareflank/common.c create mode 100644 payloads/bareflank/entry.c create mode 100644 payloads/bareflank/include/bfaffinity.h create mode 100644 payloads/bareflank/include/bfarch.h create mode 100644 payloads/bareflank/include/bfbenchmark.h create mode 100644 payloads/bareflank/include/bfbitmanip.h create mode 100644 payloads/bareflank/include/bfbuffer.h create mode 100644 payloads/bareflank/include/bfcallonce.h create mode 100755 payloads/bareflank/include/bfconstants.h create mode 100644 payloads/bareflank/include/bfdebug.h create mode 100644 payloads/bareflank/include/bfdebugringinterface.h create mode 100644 payloads/bareflank/include/bfdelegate.h create mode 100644 payloads/bareflank/include/bfdriverinterface.h create mode 100644 payloads/bareflank/include/bfdwarf.h create mode 100644 payloads/bareflank/include/bfehframelist.h create mode 100644 payloads/bareflank/include/bfelf_loader.h create mode 100644 payloads/bareflank/include/bfelf_loader_reloc_aarch64.h create mode 100644 payloads/bareflank/include/bfelf_loader_reloc_x64.h create mode 100644 payloads/bareflank/include/bferrorcodes.h create mode 100755 payloads/bareflank/include/bfexception.h create mode 100644 payloads/bareflank/include/bfexports.h create mode 100644 payloads/bareflank/include/bffile.h create mode 100644 payloads/bareflank/include/bfgsl.h create mode 100644 payloads/bareflank/include/bfjson.h create mode 100644 payloads/bareflank/include/bfmanager.h create mode 100644 payloads/bareflank/include/bfmemory.h create mode 100644 payloads/bareflank/include/bfobject.h create mode 100755 payloads/bareflank/include/bfplatform.h create mode 100644 payloads/bareflank/include/bfshuffle.h create mode 100644 payloads/bareflank/include/bfstd.h create mode 100644 payloads/bareflank/include/bfstring.h create mode 100755 payloads/bareflank/include/bfsupport.h create mode 100644 payloads/bareflank/include/bfthreadcontext.h create mode 100644 payloads/bareflank/include/bftypes.h create mode 100644 payloads/bareflank/include/bfupperlower.h create mode 100644 payloads/bareflank/include/bfvcpuid.h create mode 100644 payloads/bareflank/include/bfvector.h create mode 100644 payloads/bareflank/include/common.h create mode 100755 payloads/bareflank/platform.c diff --git a/payloads/Kconfig b/payloads/Kconfig index 28312e69ace..d339cfeb34b 100644 --- a/payloads/Kconfig +++ b/payloads/Kconfig @@ -124,6 +124,13 @@ config COREINFO_SECONDARY_PAYLOAD coreinfo can be loaded as a secondary payload under SeaBIOS, GRUB, or any other payload that can load additional payloads. +config BAREFLANK_SECONDARY_PAYLOAD + bool "Load Bareflank as a secondary payload" + default n + depends on ARCH_X86 + help + Bareflank can be loaded before primary payload. + config MEMTEST_SECONDARY_PAYLOAD bool "Load Memtest86+ as a secondary payload" default n diff --git a/payloads/Makefile.inc b/payloads/Makefile.inc index 83d3910ce06..3f77fe432e8 100644 --- a/payloads/Makefile.inc +++ b/payloads/Makefile.inc @@ -13,6 +13,11 @@ ## GNU General Public License for more details. ## +cbfs-files-$(CONFIG_BAREFLANK_SECONDARY_PAYLOAD) += $(CONFIG_CBFS_PREFIX)/payload +$(CONFIG_CBFS_PREFIX)/payload-file := payloads/bareflank/build/bareflank.elf +$(CONFIG_CBFS_PREFIX)/payload-type := payload +$(CONFIG_CBFS_PREFIX)/payload-compression := $(CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG) + cbfs-files-$(CONFIG_COREINFO_SECONDARY_PAYLOAD) += img/coreinfo img/coreinfo-file := payloads/coreinfo/build/coreinfo.elf img/coreinfo-type := payload @@ -24,6 +29,7 @@ img/nvramcui-type := payload img/nvramcui-compression := $(CBFS_SECONDARY_PAYLOAD_COMPRESS_FLAG) PAYLOADS_LIST=\ +payloads/bareflank \ payloads/coreinfo \ payloads/nvramcui \ payloads/libpayload \ @@ -38,6 +44,9 @@ payloads/external/GRUB2 \ payloads/external/LinuxBoot \ payloads/external/Yabits \ +payloads/bareflank/build/bareflank.elf bareflank: + $(MAKE) -C payloads/bareflank defaultbuild CONFIG_CBFS_PREFIX=$(CONFIG_CBFS_PREFIX) + payloads/coreinfo/build/coreinfo.elf coreinfo: $(MAKE) -C payloads/coreinfo defaultbuild diff --git a/payloads/bareflank/Kconfig b/payloads/bareflank/Kconfig new file mode 100644 index 00000000000..8cee21381db --- /dev/null +++ b/payloads/bareflank/Kconfig @@ -0,0 +1,17 @@ +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +# +# For a description of the syntax of this configuration file, +# see http://lxr.linux.no/source/Documentation/kbuild/kconfig-language.txt. +# + +mainmenu "Bareflank Configuration" diff --git a/payloads/bareflank/Makefile b/payloads/bareflank/Makefile new file mode 100644 index 00000000000..c19fcb79dd6 --- /dev/null +++ b/payloads/bareflank/Makefile @@ -0,0 +1,144 @@ +## +## This file is part of the coreinfo project. +## +## Copyright (C) 2008 Advanced Micro Devices, Inc. +## Copyright (C) 2008 Uwe Hermann +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; version 2 of the License. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## + +src := $(CURDIR) +srctree := $(src) +srck := $(src)/../../util/kconfig +coreinfo_obj := $(src)/build +objk := $(src)/build/util/kconfig + +ifeq ($(filter %clean,$(MAKECMDGOALS)),) +export KERNELVERSION := 0.1.0 +export KCONFIG_AUTOHEADER := $(coreinfo_obj)/config.h +export KCONFIG_AUTOCONFIG := $(coreinfo_obj)/auto.conf +export KCONFIG_DEPENDENCIES := $(coreinfo_obj)/auto.conf.cmd +export KCONFIG_SPLITCONFIG := $(coreinfo_obj)/config +export KCONFIG_TRISTATE := $(coreinfo_obj)/tristate.conf +export KCONFIG_CONFIG := $(CURDIR)/.config +export KCONFIG_NEGATIVES := 1 +export Kconfig := Kconfig + +export V := $(V) + +CONFIG_SHELL := sh +KBUILD_DEFCONFIG := configs/defconfig +UNAME_RELEASE := $(shell uname -r) +HAVE_DOTCONFIG := $(wildcard .config) +MAKEFLAGS += -rR --no-print-directory + +# Make is silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +.SILENT: +endif + +HOSTCC ?= gcc +HOSTCXX ?= g++ +HOSTCFLAGS := -I$(srck) -I$(objk) +HOSTCXXFLAGS := -I$(srck) -I$(objk) + +LIBPAYLOAD_PATH := $(realpath ../libpayload) +LIBPAYLOAD_OBJ := $(coreinfo_obj)/libpayload +HAVE_LIBPAYLOAD := $(wildcard $(LIBPAYLOAD_OBJ)/lib/libpayload.a) +LIBPAYLOAD_CONFIG ?= configs/defconfig-tinycurses-64 +OBJCOPY ?= objcopy + +INCLUDES = -I$(coreinfo_obj) -include $(LIBPAYLOAD_OBJ)/include/kconfig.h -I$(src)/../../src/commonlib/include -I$(src)/include -I$(src) +OBJECTS = common.o entry.o platform.o +OBJS = $(patsubst %,$(coreinfo_obj)/%,$(OBJECTS)) +TARGET = $(coreinfo_obj)/bareflank.elf + +all: real-all + +# in addition to the dependency below, create the file if it doesn't exist +# to silence warnings about a file that would be generated anyway. +$(if $(wildcard .xcompile),,$(eval $(shell ../../util/xcompile/xcompile $(XGCCPATH) > .xcompile || rm -f .xcompile))) +.xcompile: ../../util/xcompile/xcompile + $< $(XGCCPATH) > $@.tmp + \mv -f $@.tmp $@ 2> /dev/null || rm -f $@.tmp $@ + +CONFIG_COMPILER_GCC := y +ARCH-y := x86_64 + +include .xcompile + +CC := $(CC_$(ARCH-y)) +AS := $(AS_$(ARCH-y)) +OBJCOPY := $(OBJCOPY_$(ARCH-y)) + +LPCC := CC="$(CC)" $(LIBPAYLOAD_OBJ)/bin/lpgcc +LPAS := AS="$(AS)" $(LIBPAYLOAD_OBJ)/bin/lpas + +CFLAGS += -Wall -Werror -Os -fno-builtin $(CFLAGS_$(ARCH-y)) $(INCLUDES) + +ifneq ($(strip $(HAVE_DOTCONFIG)),) +include $(src)/.config +real-all: $(TARGET) + +$(TARGET): $(src)/.config $(coreinfo_obj)/config.h $(OBJS) libpayload + printf " LPCC $(subst $(CURDIR)/,,$(@)) (LINK)\n" + $(LPCC) -o $@ $(OBJS) + $(OBJCOPY) --only-keep-debug $@ $(TARGET).debug + $(OBJCOPY) --strip-debug $@ + $(OBJCOPY) --add-gnu-debuglink=$(TARGET).debug $@ + +$(coreinfo_obj)/%.S.o: $(src)/%.S libpayload + printf " LPAS $(subst $(CURDIR)/,,$(@))\n" + $(LPAS) -o $@ $< + +$(coreinfo_obj)/%.o: $(src)/%.c libpayload + printf " LPCC $(subst $(CURDIR)/,,$(@))\n" + $(LPCC) $(CFLAGS) -c -o $@ $< -DCONFIG_CBFS_PREFIX=\"$(CONFIG_CBFS_PREFIX)\" + +else +real-all: config +endif + +defaultbuild: + $(MAKE) olddefconfig + $(MAKE) all + +ifneq ($(strip $(HAVE_LIBPAYLOAD)),) +libpayload: + printf "Found Libpayload $(LIBPAYLOAD_OBJ).\n" +else +LPOPTS=obj="$(CURDIR)/lpbuild" DOTCONFIG="$(CURDIR)/lp.config" +libpayload: + printf "Building libpayload @ $(LIBPAYLOAD_PATH).\n" + $(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) distclean coreinfo_obj=$(coreinfo_obj)/libptmp + $(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) defconfig KBUILD_DEFCONFIG=$(LIBPAYLOAD_CONFIG) + $(MAKE) -C $(LIBPAYLOAD_PATH) $(LPOPTS) install DESTDIR=$(coreinfo_obj) +endif + +$(coreinfo_obj)/config.h: + $(MAKE) oldconfig + +$(shell mkdir -p $(coreinfo_obj) $(objk)/lxdialog $(KCONFIG_SPLITCONFIG)) + +include $(srck)/Makefile + +.PHONY: $(PHONY) prepare + +else + +clean: + rm -rf build/*.elf build/*.o .xcompile + +distclean: clean + rm -rf build lpbuild + rm -f .config* lp.config* + +.PHONY: clean distclean +endif diff --git a/payloads/bareflank/common.c b/payloads/bareflank/common.c new file mode 100755 index 00000000000..2e1d55ab6bb --- /dev/null +++ b/payloads/bareflank/common.c @@ -0,0 +1,521 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +/* -------------------------------------------------------------------------- */ +/* Global */ +/* -------------------------------------------------------------------------- */ + +int64_t g_num_modules = 0; +struct bfelf_binary_t g_modules[MAX_NUM_MODULES]; + +_start_t _start_func = 0; +struct crt_info_t g_info; +struct bfelf_loader_t g_loader; + +int64_t g_num_cpus_started = 0; +int64_t g_vmm_status = VMM_UNLOADED; + +void *g_tls = 0; +void *g_stack = 0; + +uint64_t g_tls_size = 0; +uint64_t g_stack_size = 0; +uint64_t g_stack_top = 0; + +void *g_rsdp = 0; + +/* -------------------------------------------------------------------------- */ +/* Helpers */ +/* -------------------------------------------------------------------------- */ + +int64_t +private_setup_stack(void) +{ + g_stack_size = STACK_SIZE * 2; + + g_stack = platform_alloc_rw(g_stack_size); + if (g_stack == 0) { + return BF_ERROR_OUT_OF_MEMORY; + } + + g_stack_top = (uint64_t)g_stack + g_stack_size; + g_stack_top = (g_stack_top & ~(STACK_SIZE - 1)) - 1; + + platform_memset(g_stack, 0, g_stack_size); + return BF_SUCCESS; +} + +int64_t +private_setup_tls(void) +{ + g_tls_size = THREAD_LOCAL_STORAGE_SIZE * (uint64_t)platform_num_cpus(); + + g_tls = platform_alloc_rw(g_tls_size); + if (g_tls == 0) { + return BF_ERROR_OUT_OF_MEMORY; + } + + platform_memset(g_tls, 0, g_tls_size); + return BF_SUCCESS; +} + +int64_t +private_setup_rsdp(void) +{ + g_rsdp = platform_get_rsdp(); + return BF_SUCCESS; +} + +int64_t +private_add_raw_md_to_memory_manager(uint64_t virt, uint64_t type) +{ + int64_t ret = 0; + struct memory_descriptor md = {0, 0, 0}; + + md.virt = virt; + md.phys = (uint64_t)platform_virt_to_phys((void *)md.virt); + md.type = type; + + ret = platform_call_vmm_on_core( + 0, BF_REQUEST_ADD_MDL, (uintptr_t)&md, 0); + + if (ret != MEMORY_MANAGER_SUCCESS) { + return ret; + } + + return BF_SUCCESS; +} + +int64_t +private_add_md_to_memory_manager(struct bfelf_binary_t *module) +{ + bfelf64_word s = 0; + + for (s = 0; s < bfelf_file_get_num_load_instrs(&module->ef); s++) { + + int64_t ret = 0; + + uint64_t exec_s = 0; + uint64_t exec_e = 0; + const struct bfelf_load_instr *instr = 0; + + ret = bfelf_file_get_load_instr(&module->ef, s, &instr); + bfignored(ret); + + exec_s = (uint64_t)module->exec + instr->mem_offset; + exec_e = (uint64_t)module->exec + instr->mem_offset + instr->memsz; + exec_s &= ~(BAREFLANK_PAGE_SIZE - 1); + exec_e &= ~(BAREFLANK_PAGE_SIZE - 1); + + for (; exec_s <= exec_e; exec_s += BAREFLANK_PAGE_SIZE) { + if ((instr->perm & bfpf_x) != 0) { + ret = private_add_raw_md_to_memory_manager( + exec_s, MEMORY_TYPE_R | MEMORY_TYPE_E); + } + else { + ret = private_add_raw_md_to_memory_manager( + exec_s, MEMORY_TYPE_R | MEMORY_TYPE_W); + } + + if (ret != MEMORY_MANAGER_SUCCESS) { + return ret; + } + } + } + + return BF_SUCCESS; +} + +int64_t +private_add_tss_mdl(void) +{ + uint64_t i = 0; + + for (i = 0; i < g_tls_size; i += BAREFLANK_PAGE_SIZE) { + + int64_t ret = private_add_raw_md_to_memory_manager( + (uint64_t)g_tls + i, MEMORY_TYPE_R | MEMORY_TYPE_W); + + if (ret != BF_SUCCESS) { + return ret; + } + } + + return BF_SUCCESS; +} + +int64_t +private_add_modules_mdl(void) +{ + int64_t i = 0; + + for (i = 0; i < g_num_modules; i++) { + int64_t ret = private_add_md_to_memory_manager(&g_modules[i]); + if (ret != BF_SUCCESS) { + return ret; + } + } + + return BF_SUCCESS; +} + +/* -------------------------------------------------------------------------- */ +/* Implementation */ +/* -------------------------------------------------------------------------- */ + +int64_t +common_vmm_status(void) +{ return g_vmm_status; } + +void +common_reset(void) +{ + int64_t i; + + for (i = 0; i < g_num_modules; i++) { + if (g_modules[i].exec != 0) { + platform_free_rwe(g_modules[i].exec, g_modules[i].exec_size); + } + } + + platform_memset(&g_modules, 0, sizeof(g_modules)); + platform_memset(&g_loader, 0, sizeof(struct bfelf_loader_t)); + platform_memset(&g_info, 0, sizeof(struct crt_info_t)); + platform_memset(&g_loader, 0, sizeof(struct bfelf_loader_t)); + + _start_func = 0; + + g_num_modules = 0; + g_num_cpus_started = 0; + g_vmm_status = VMM_UNLOADED; + + if (g_tls != 0) { + platform_free_rw(g_tls, g_tls_size); + } + + if (g_stack != 0) { + platform_free_rw(g_stack, g_stack_size); + } + + g_tls = 0; + g_stack = 0; + g_stack_top = 0; + + g_rsdp = 0; +} + +int64_t +common_init(void) +{ + int64_t ret = platform_init(); + if (ret != BF_SUCCESS) { + return ret; + } + + common_reset(); + + return BF_SUCCESS; +} + +int64_t +common_fini(void) +{ + if (common_vmm_status() == VMM_RUNNING) { + if (common_stop_vmm() != BF_SUCCESS) { + BFALERT("common_fini: failed to stop vmm\n"); + } + } + + if (common_vmm_status() == VMM_LOADED) { + if (common_unload_vmm() != BF_SUCCESS) { + BFALERT("common_fini: failed to unload vmm\n"); + } + } + + if (common_vmm_status() == VMM_CORRUPT) { + return BF_ERROR_VMM_CORRUPTED; + } + + if (g_num_modules > 0) { + common_reset(); + } + + return BF_SUCCESS; +} + +int64_t +common_add_module(const char *file, uint64_t fsize) +{ + if (file == 0 || fsize == 0) { + return BF_ERROR_INVALID_ARG; + } + + switch (common_vmm_status()) { + case VMM_CORRUPT: + return BF_ERROR_VMM_CORRUPTED; + case VMM_LOADED: + return BF_ERROR_VMM_INVALID_STATE; + case VMM_RUNNING: + return BF_ERROR_VMM_INVALID_STATE; + default: + break; + } + + if (g_num_modules >= MAX_NUM_MODULES) { + return BF_ERROR_MAX_MODULES_REACHED; + } + + g_modules[g_num_modules].file = file; + g_modules[g_num_modules].file_size = fsize; + + g_num_modules++; + return BF_SUCCESS; +} + +int64_t +common_load_vmm(void) +{ + int64_t ret = 0; + int64_t ignore_ret = 0; + + switch (common_vmm_status()) { + case VMM_CORRUPT: + return BF_ERROR_VMM_CORRUPTED; + case VMM_LOADED: + return BF_SUCCESS; + case VMM_RUNNING: + return BF_ERROR_VMM_INVALID_STATE; + default: + break; + } + + if (g_num_modules == 0) { + return BF_ERROR_NO_MODULES_ADDED; + } + + ret = private_setup_stack(); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = private_setup_tls(); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = private_setup_rsdp(); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = bfelf_load(g_modules, (uint64_t)g_num_modules,(void **)&_start_func, &g_info, &g_loader); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = platform_call_vmm_on_core(0, BF_REQUEST_INIT, 0, 0); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = platform_call_vmm_on_core(0, BF_REQUEST_SET_RSDP, (uint64_t)g_rsdp, 0); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = private_add_modules_mdl(); + if (ret != BF_SUCCESS) { + goto failure; + } + + ret = private_add_tss_mdl(); + if (ret != BF_SUCCESS) { + goto failure; + } + + g_vmm_status = VMM_LOADED; + return BF_SUCCESS; + +failure: + + ignore_ret = common_unload_vmm(); + bfignored(ignore_ret); + + return ret; +} + +int64_t +common_unload_vmm(void) +{ + int64_t ret = 0; + + switch (common_vmm_status()) { + case VMM_CORRUPT: + return BF_ERROR_VMM_CORRUPTED; + case VMM_RUNNING: + return BF_ERROR_VMM_INVALID_STATE; + case VMM_UNLOADED: + goto unloaded; + default: + break; + } + + ret = platform_call_vmm_on_core(0, BF_REQUEST_FINI, 0, 0); + if (ret != BF_SUCCESS) { + goto corrupted; + } + +unloaded: + + common_reset(); + + g_vmm_status = VMM_UNLOADED; + return BF_SUCCESS; + +corrupted: + + g_vmm_status = VMM_CORRUPT; + return ret; +} + +int64_t +common_start_vmm(void) +{ + int64_t ret = 0; + int64_t cpuid = 0; + int64_t ignore_ret = 0; + + switch (common_vmm_status()) { + case VMM_CORRUPT: + return BF_ERROR_VMM_CORRUPTED; + case VMM_RUNNING: + return BF_SUCCESS; + case VMM_UNLOADED: + return BF_ERROR_VMM_INVALID_STATE; + default: + break; + } + + for (cpuid = 0, g_num_cpus_started = 0; cpuid < platform_num_cpus(); cpuid++) { + ret = platform_call_vmm_on_core( + (uint64_t)cpuid, BF_REQUEST_VMM_INIT, (uint64_t)cpuid, 0); + + if (ret != BF_SUCCESS) { + goto failure; + } + + g_num_cpus_started++; + } + + g_vmm_status = VMM_RUNNING; + return BF_SUCCESS; + +failure: + + ignore_ret = common_stop_vmm(); + bfignored(ignore_ret); + + return ret; +} + +int64_t +common_stop_vmm(void) +{ + int64_t ret = 0; + int64_t cpuid = 0; + + switch (common_vmm_status()) { + case VMM_CORRUPT: + return BF_ERROR_VMM_CORRUPTED; + case VMM_UNLOADED: + return BF_ERROR_VMM_INVALID_STATE; + default: + break; + } + + for (cpuid = g_num_cpus_started - 1; cpuid >= 0 ; cpuid--) { + ret = platform_call_vmm_on_core( + (uint64_t)cpuid, BF_REQUEST_VMM_FINI, (uint64_t)cpuid, 0); + + if (ret != BFELF_SUCCESS) { + goto corrupted; + } + + g_num_cpus_started--; + } + + g_vmm_status = VMM_LOADED; + return BF_SUCCESS; + +corrupted: + + g_vmm_status = VMM_CORRUPT; + return ret; +} + +int64_t +common_dump_vmm(struct debug_ring_resources_t **drr, uint64_t vcpuid) +{ + int64_t ret = 0; + + if (drr == 0) { + return BF_ERROR_INVALID_ARG; + } + + if (common_vmm_status() == VMM_UNLOADED) { + return BF_ERROR_VMM_INVALID_STATE; + } + + ret = platform_call_vmm_on_core( + 0, BF_REQUEST_GET_DRR, (uint64_t)vcpuid, (uint64_t)drr); + + if (ret != BFELF_SUCCESS) { + return ret; + } + + return BF_SUCCESS; +} + +typedef struct thread_context_t tc_t; + +int64_t +common_call_vmm( + uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2) +{ + int64_t ignored_ret = 0; + tc_t *tc = (tc_t *)(g_stack_top - sizeof(tc_t)); + + ignored_ret = bfelf_set_integer_args(&g_info, request, arg1, arg2, 0); + bfignored(ignored_ret); + + tc->cpuid = cpuid; + tc->tlsptr = (uint64_t *)((uint64_t)g_tls + (THREAD_LOCAL_STORAGE_SIZE * (uint64_t)cpuid)); + + return _start_func((void *)(g_stack_top - sizeof(tc_t) - 1), &g_info); +} diff --git a/payloads/bareflank/entry.c b/payloads/bareflank/entry.c new file mode 100644 index 00000000000..fc24858d0b3 --- /dev/null +++ b/payloads/bareflank/entry.c @@ -0,0 +1,205 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include // TODO: read file from CBFS? +#include + +#include +#include +#include +#include + +#include +#include +#include + +extern void i386_do_exec(void* addr, int argc, char **argv, int *ret); + +/* -------------------------------------------------------------------------- */ +/* Global */ +/* -------------------------------------------------------------------------- */ + +uint64_t g_vcpuid = 0; + +struct pmodule_t { + const char *data; + uint64_t size; +}; + +uint64_t g_num_pmodules = 0; +struct pmodule_t pmodules[MAX_NUM_MODULES] = {{0}}; + +/* -------------------------------------------------------------------------- */ +/* Misc Device */ +/* -------------------------------------------------------------------------- */ + +static int64_t +ioctl_add_module(const char *file, uint64_t len) +{ + char *buf; + int64_t ret; + + if (g_num_pmodules >= MAX_NUM_MODULES) { + BFALERT("IOCTL_ADD_MODULE: too many modules have been loaded\n"); + return BF_IOCTL_FAILURE; + } + + buf = platform_alloc_rw(len); + if (buf == NULL) { + BFALERT("IOCTL_ADD_MODULE: failed to allocate memory for the module\n"); + return BF_IOCTL_FAILURE; + } + + platform_memcpy(buf, file, len); + + ret = common_add_module(buf, len); + if (ret != BF_SUCCESS) { + BFALERT("IOCTL_ADD_MODULE: common_add_module failed: %p - %s\n", (void *)ret, ec_to_str(ret)); + goto failed; + } + + pmodules[g_num_pmodules].data = buf; + pmodules[g_num_pmodules].size = len; + + g_num_pmodules++; + + return BF_IOCTL_SUCCESS; + +failed: + + platform_free_rw(buf, len); + + BFALERT("IOCTL_ADD_MODULE: failed\n"); + return BF_IOCTL_FAILURE; +} + +static long +ioctl_load_vmm(void) +{ + int64_t ret; + + ret = common_load_vmm(); + if (ret != BF_SUCCESS) { + BFALERT("IOCTL_LOAD_VMM: common_load_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); + goto failure; + } + + return BF_IOCTL_SUCCESS; + +failure: + + BFDEBUG("IOCTL_LOAD_VMM: failed\n"); + return BF_IOCTL_FAILURE; +} + +static long +ioctl_start_vmm(void) +{ + int64_t ret; + + ret = common_start_vmm(); + if (ret != BF_SUCCESS) { + BFALERT("IOCTL_START_VMM: common_start_vmm failed: %p - %s\n", (void *)ret, ec_to_str(ret)); + goto failure; + } + + return BF_IOCTL_SUCCESS; + +failure: + + BFDEBUG("IOCTL_START_VMM: failed\n"); + return BF_IOCTL_FAILURE; +} + +static void cbfs_run_payload(struct cbfs_payload *pay) +{ + struct cbfs_payload_segment *seg = &pay->segments; + for (;;) { + void *src = (void*)pay + ntohl(seg->offset); + void *dest = (void*)ntohll(seg->load_addr); + u32 src_len = ntohl(seg->len); + u32 dest_len = ntohl(seg->mem_len); + switch (seg->type) { + case PAYLOAD_SEGMENT_BSS: + printf("BSS segment %d@%p\n", dest_len, dest); + memset(dest, 0, dest_len); + break; + case PAYLOAD_SEGMENT_ENTRY: { + printf("Calling addr %p\n", dest); + i386_do_exec(dest, 0, NULL, NULL); + return; + } + default: + printf("Segment %x %d@%p -> %d@%p\n", seg->type, src_len, src, + dest_len, dest); + if (seg->compression == ntohl(CBFS_COMPRESS_NONE)) { + if (src_len > dest_len) + src_len = dest_len; + memcpy(dest, src, src_len); + } else if (CONFIG_LP_LZMA + && seg->compression == ntohl(CBFS_COMPRESS_LZMA)) { + int ret = ulzman(src, src_len, dest, dest_len); + if (ret < 0) + return; + src_len = ret; + } else { + printf("No support for compression type %x\n", seg->compression); + return; + } + if (dest_len > src_len) + memset(dest + src_len, 0, dest_len - src_len); + break; + } + seg++; + } +} + +/* -------------------------------------------------------------------------- */ +/* Entry / Exit */ +/* -------------------------------------------------------------------------- */ + +int main(void) +{ + void *payload = NULL; + + printf("\n"); + printf(" ___ __ _ _ \n"); + printf(" | _ ) __ _ _ _ ___ / _| |__ _ _ _ | |__\n"); + printf(" | _ \\/ _` | '_/ -_) _| / _` | ' \\| / /\n"); + printf(" |___/\\__,_|_| \\___|_| |_\\__,_|_||_|_\\_\\\n"); + printf("\n"); + printf(" Please give us a star on: https://github.com/Bareflank/hypervisor\n"); + printf("\n"); + + if (common_init() != BF_SUCCESS) { + return -1; + } + + ioctl_add_module((char *)vmm, vmm_len); + ioctl_load_vmm(); + ioctl_start_vmm(); + + payload = cbfs_load_payload(CBFS_DEFAULT_MEDIA, CONFIG_CBFS_PREFIX "/realpayload"); + + cbfs_run_payload(payload); + + printf("Should not get here...\n"); + + return 0; +} diff --git a/payloads/bareflank/include/bfaffinity.h b/payloads/bareflank/include/bfaffinity.h new file mode 100644 index 00000000000..1fb98f38e51 --- /dev/null +++ b/payloads/bareflank/include/bfaffinity.h @@ -0,0 +1,61 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfbuffer.h +/// +/// + +#ifdef WIN64 + +#include + +inline int +set_affinity(uint64_t core) +{ + if (SetProcessAffinityMask(GetCurrentProcess(), 1ULL << core) == 0) { + return -1; + } + + return 0; +} + +#else + +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#include + +inline int +set_affinity(uint64_t core) +{ + cpu_set_t mask; + + CPU_ZERO(&mask); + CPU_SET(core, &mask); + + if (sched_setaffinity(0, sizeof(mask), &mask) != 0) { + return -1; + } + + return 0; +} + +#endif diff --git a/payloads/bareflank/include/bfarch.h b/payloads/bareflank/include/bfarch.h new file mode 100644 index 00000000000..17c6ea47e3a --- /dev/null +++ b/payloads/bareflank/include/bfarch.h @@ -0,0 +1,49 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2017 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFARCH_H +#define BFARCH_H + +#ifndef BF_ARCH + +#if defined(_MSC_VER) +# if defined(_M_X64) +# define BF_ARCH "intel_x64" +# define BF_X64 +# define BF_INTEL_X64 +# else +# error "bfarch.h: unsupported architecture" +# endif +#elif defined(__GNUC__) || defined(__clang__) +# if defined(__x86_64__) +# define BF_ARCH "intel_x64" +# define BF_X64 +# define BF_INTEL_X64 +# elif defined(__aarch64__) +# define BF_ARCH "aarch64" +# define BF_AARCH64 +# else +# error "bfarch.h: unsupported architecture" +# endif +#else +# error "bfarch.h: unsupported compiler" +#endif + +#endif +#endif diff --git a/payloads/bareflank/include/bfbenchmark.h b/payloads/bareflank/include/bfbenchmark.h new file mode 100644 index 00000000000..6d78980accb --- /dev/null +++ b/payloads/bareflank/include/bfbenchmark.h @@ -0,0 +1,114 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULLAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef BFBENCHMARK_H +#define BFBENCHMARK_H + +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC system_header +#endif + +#include +#include + +#include + +template +uint64_t benchmark(T func) +{ + auto s = std::chrono::high_resolution_clock::now(); + func(); + auto e = std::chrono::high_resolution_clock::now(); + + return static_cast((e - s).count()); +} + +size_t g_page_allocs = 0; +size_t g_nonpage_allocs = 0; + +inline void * +custom_new(std::size_t size) +{ + if ((size & 0xFFF) == 0) { + g_page_allocs += size; + } + else { + g_nonpage_allocs += size; + } + + return malloc(size); +} + +inline void +custom_delete(void *ptr, std::size_t size) +{ + bfignored(size); + free(ptr); +} + +void * +operator new[](std::size_t size) +{ return custom_new(size); } + +void * +operator new (std::size_t size) +{ return custom_new(size); } + +void * +operator new (std::size_t count, const std::nothrow_t &) +{ return custom_new(count); } + +void * +operator new[](std::size_t count, const std::nothrow_t &) +{ return custom_new(count); } + +void +operator delete (void *ptr, std::size_t size) throw() +{ custom_delete(ptr, size); } + +void +operator delete (void *ptr) throw() +{ operator delete (ptr, static_cast(0)); } + +void +operator delete[](void *ptr, std::size_t size) throw() +{ custom_delete(ptr, size); } + +void +operator delete[](void *ptr) throw() +{ operator delete[](ptr, static_cast(0)); } + +inline void +print_memory_stats() +{ + auto page_allocs = g_page_allocs; + auto nonpage_allocs = g_nonpage_allocs; + + bfdebug_nhex(0, "bytes allocated", page_allocs + nonpage_allocs); + bfdebug_subnhex(0, "page aligned bytes allocated", page_allocs); + bfdebug_subnhex(0, "non-page aligned bytes allocated", nonpage_allocs); +} + +inline void +clear_memory_stats() +{ + g_page_allocs = 0; + g_nonpage_allocs = 0; +} + +#endif diff --git a/payloads/bareflank/include/bfbitmanip.h b/payloads/bareflank/include/bfbitmanip.h new file mode 100644 index 00000000000..528ddbb9ec3 --- /dev/null +++ b/payloads/bareflank/include/bfbitmanip.h @@ -0,0 +1,274 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULLAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfbitmanip.h +/// + +#ifndef BFBITMANIP_H +#define BFBITMANIP_H + +#include + +#include +#include + +/// Set Bit +/// +/// Sets a bit given the bit position and an integer. +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be set +/// @param b bit position +/// @return t with bit set at position b +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +set_bit(T t, B b) noexcept +{ + return t | (0x1ULL << b); +} + +/// Set Bit +/// +/// Sets a bit given the bit position and an integer. +/// +/// @expects +/// @ensures +/// +/// @param view view whose bit is to be set +/// @param b bit position +/// @return t with bit set at position b +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +set_bit(gsl::span &view, B b) +{ + auto byte_view = gsl::as_writeable_bytes(view); + byte_view.at(b >> 3) |= gsl::narrow_cast((1 << (b & 7))); +} + +/// Clear Bit +/// +/// Clears a bit given the bit position and an integer. +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be cleared +/// @param b bit position +/// @return t with bit cleared at position b +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +clear_bit(T t, B b) noexcept +{ + return t & ~(0x1ULL << b); +} + +/// Clear Bit +/// +/// Clears a bit given the bit position and an integer. +/// +/// @expects +/// @ensures +/// +/// @param view view whose bit is to be cleared +/// @param b bit position +/// @return t with bit cleared at position b +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +clear_bit(gsl::span &view, B b) +{ + auto byte_view = gsl::as_writeable_bytes(view); + byte_view.at(b >> 3) &= gsl::narrow_cast(~(1 << (b & 7))); +} + +/// Get Bit +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be gotten +/// @param b bit position +/// @return value of bit b for integer t +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +get_bit(T t, B b) noexcept +{ + return (t & (0x1ULL << b)) >> b; +} + +/// Get Bit +/// +/// @expects +/// @ensures +/// +/// @param view view whose bit is to be gotten +/// @param b bit position +/// @return value of bit b for integer t +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +get_bit(const gsl::span &view, B b) +{ + auto byte_view = gsl::as_writeable_bytes(view); + return byte_view.at(b >> 3) & gsl::narrow_cast((1 << (b & 7))); +} + +/// Is Bit Set +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be tested +/// @param b bit position +/// @return true if bit b in t is set, false otherwise +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +is_bit_set(T t, B b) noexcept +{ + return static_cast(get_bit(t, b)) != static_cast(0); +} + +/// Is Bit Cleared +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be tested +/// @param b bit position +/// @return true if bit b in t is cleared, false otherwise +/// +template < + typename T, + typename B, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +is_bit_cleared(T t, B b) noexcept +{ + return static_cast(get_bit(t, b)) == static_cast(0); +} + +/// Number of Bits Set +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bit is to be tested +/// @return the number of bits set in t +/// +template < + typename T, + typename = std::enable_if::value> + > +auto +num_bits_set(T t) noexcept +{ + std::bitset<64> b{t}; + return b.count(); +} + +/// Get Bits +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bits are to be gotten +/// @param m the bit mask +/// @return t & m +/// +template < + typename T, + typename M, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +get_bits(T t, M m) noexcept +{ + return t & m; +} + +/// Set Bits +/// +/// @expects +/// @ensures +/// +/// @param t integer whose bits are to be set +/// @param m the bit mask +/// @param v the bits to set +/// @return t with bits set to v masked by m +/// +template < + typename T, + typename M, + typename V, + typename = std::enable_if::value>, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +constexpr auto +set_bits(T t, M m, V v) noexcept +{ + return (t & ~m) | (v & m); +} + +#endif diff --git a/payloads/bareflank/include/bfbuffer.h b/payloads/bareflank/include/bfbuffer.h new file mode 100644 index 00000000000..7ca1c0a5944 --- /dev/null +++ b/payloads/bareflank/include/bfbuffer.h @@ -0,0 +1,309 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfbuffer.h +/// + +#ifndef BFBUFFER_H +#define BFBUFFER_H + +#include +#include + +namespace bfn +{ + +/// Buffer +/// +/// Simple character buffer class that stores both a buffer and its size. +/// This class is a hybrid between std::array, and std::unique_ptr. It's +/// dynamic, doesn't have support for iterators or random memory access, +/// and cannot be copied. +/// +class buffer +{ +public: + + using size_type = std::size_t; ///< Size type of buffer + using data_type = char; ///< Data type of buffer + + /// Default Constructor + /// + /// @expects none + /// @ensures none + /// + buffer() = default; + + /// Allocate Buffer Constructor + /// + /// @expects none + /// @ensures none + /// + /// @param size the size of the buffer to allocate + /// + /// @throws std::bad_alloc if this constructor is unable to allocate memory for the buffer + /// + buffer(size_type size) : + m_size(size), + m_data(std::make_unique(m_size)) + { + expects(size != 0); + } + + /// Pre-Allocated Buffer Constructor + /// + /// @note Takes ownership of data, and frees the provided buffer when the + /// buffer goes out of scope + /// + /// @expects none + /// @ensures none + /// + /// @param data a pointer to the buffer to store. + /// @param size the size of the provided buffer + /// + buffer(void *data, size_type size) : + m_size(size), + m_data(static_cast(data)) + { + expects(size != 0 || data == nullptr); + expects(data != nullptr || size == 0); + } + + /// Initializer List Constructor + /// + /// @expects none + /// @ensures none + /// + /// @param list initial list to create the buffer + /// + /// @throws std::bad_alloc if this constructor is unable to allocate memory for the buffer + /// + buffer(std::initializer_list list) : + m_size(list.size()), + m_data(std::make_unique(list.size())) + { + auto _i = 0LL; + auto _span = span(); + + for (const auto &elem : list) { + _span[_i++] = elem; + } + } + + /// Default Destructor + /// + /// @expects none + /// @ensures none + /// + ~buffer() = default; + + /// Get Data + /// + /// @expects none + /// @ensures none + /// + /// @return returns a pointer to the buffer + /// + data_type *get() noexcept + { return m_data.get(); } + + /// Get Data + /// + /// @expects none + /// @ensures none + /// + /// @return returns a pointer to the buffer + /// + data_type *data() noexcept + { return m_data.get(); } + + /// Get Data + /// + /// @expects none + /// @ensures none + /// + /// @return returns a pointer to the buffer + /// + const data_type *data() const noexcept + { return m_data.get(); } + + /// Is Empty + /// + /// @expects none + /// @ensures none + /// + /// @return returns true if size() == 0, false otherwise + /// + bool empty() const noexcept + { return m_size == 0; } + + /// Valid + /// + /// @return returns true if the buffer is valid, false otherwise + /// + operator bool() const noexcept + { return m_data.operator bool(); } + + /// Size + /// + /// @expects none + /// @ensures none + /// + /// @return returns the size of the buffer + /// + size_type size() const noexcept + { return m_size; } + + /// Release + /// + /// @expects none + /// @ensures none + /// + void + release() noexcept + { + m_size = 0; + m_data.release(); + } + + /// Swap + /// + /// @expects none + /// @ensures none + /// + /// @param other the other buffer to swap with + /// + void + swap(buffer &other) noexcept + { + std::swap(m_size, other.m_size); + std::swap(m_data, other.m_data); + } + + /// Span + /// + /// @expects none + /// @ensures none + /// + /// @return returns a gsl::span that can be used to access the buffer. + /// + gsl::span + span() const + { return gsl::make_span(m_data.get(), gsl::narrow_cast(m_size)); } + + /// Resize + /// + /// Resize the buffer. If count is smaller than the original size, the + /// data is truncated. If count is larger than the original size, the + /// remaining data is undefined. + /// + /// @expects none + /// @ensures none + /// + /// @param count the number of bytes to resize the buffer to + /// + /// @throws std::bad_alloc if this method is unable to allocate memory for the buffer + /// + void + resize(size_type count) + { + auto new_data = std::make_unique(count); + memcpy(new_data.get(), m_data.get(), std::min(m_size, count)); + + m_size = count; + m_data = std::move(new_data); + } + +private: + + size_type m_size{0}; + std::unique_ptr m_data; + +public: + + /// @cond + + buffer(buffer &&) noexcept = default; + buffer &operator=(buffer &&) noexcept = default; + + buffer(const buffer &) = delete; + buffer &operator=(const buffer &) = delete; + + /// @endcond +}; + +/// Swap +/// +/// @expects none +/// @ensures none +/// +/// @param lhs buffer to swap +/// @param rhs buffer to swap +/// +inline void +swap(buffer &lhs, buffer &rhs) noexcept +{ lhs.swap(rhs); } + +/// Equals +/// +/// @expects none +/// @ensures none +/// +/// @param lhs buffer to compare +/// @param rhs buffer to compare +/// @return true if ==, false otherwise +/// +inline bool +operator==(const buffer &lhs, const buffer &rhs) noexcept +{ + if (lhs.size() != rhs.size()) { + return false; + } + + return memcmp(lhs.data(), rhs.data(), lhs.size()) == 0; +} + +/// Not Equals +/// +/// @expects none +/// @ensures none +/// +/// @param lhs buffer to compare +/// @param rhs buffer to compare +/// @return true if !=, false otherwise +/// +inline bool +operator!=(const buffer &lhs, const buffer &rhs) noexcept +{ return !(lhs == rhs); } + +/// Default Out Stream Operator +/// +/// @expects none +/// @ensures none +/// +/// @param os the out stream object +/// @return os +/// +inline std::ostream & +operator<<(std::ostream &os, const buffer &) +{ return os; } + +} + +#endif diff --git a/payloads/bareflank/include/bfcallonce.h b/payloads/bareflank/include/bfcallonce.h new file mode 100644 index 00000000000..05a7776bb39 --- /dev/null +++ b/payloads/bareflank/include/bfcallonce.h @@ -0,0 +1,56 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULLAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef BFCALLONCE +#define BFCALLONCE + +/// @cond + +#include + +// TODO +// +// This code is only needed because there seems to be a bug with GCC that +// causes a system error when --coverage is enabled. The following was written +// to have the same names and implementation as std::call_once so that at +// some point this code can easily be removed. +// +namespace bfn +{ + +struct once_flag { + bool m_value{false}; + mutable std::mutex m_mutex{}; +}; + +template +void call_once(once_flag &flag, FUNC func) +{ + std::lock_guard lock(flag.m_mutex); + + if (!flag.m_value) { + func(); + flag.m_value = true; + } +} + +} + +/// @endcond + +#endif diff --git a/payloads/bareflank/include/bfconstants.h b/payloads/bareflank/include/bfconstants.h new file mode 100755 index 00000000000..f3334e21176 --- /dev/null +++ b/payloads/bareflank/include/bfconstants.h @@ -0,0 +1,277 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFCONSTANTS_H +#define BFCONSTANTS_H + +#include +#include + +/* + * Max Physical Address + * + * Defines the maximum physical address the system can access. This can be + * used by CR3 and EPT to define the memory map used by the VMM. Note that + * if this value is too large, its possible additional memory would be needed + * by the VMM to setup CR3 or EPT depending on the granulairty used. + * + * Note: defined in bytes + */ +#ifndef MAX_PHYS_ADDR +#define MAX_PHYS_ADDR 0x1000000000 +#endif + +/* + * Bareflank Page Size + * + * Defines the page size that is supported by the VMM. For now, this is + * set to a value that is likely supported by most hardware. + * + * Note: defined in bytes + */ +#ifndef BAREFLANK_PAGE_SIZE +#define BAREFLANK_PAGE_SIZE (0x1000ULL) +#endif + +/* + * Page Pool K + * + * Defines the size of the initial page pool used by the VMM. If more memory + * is needed by the VMM initially, this value may be increased. Note that + * increasing "K" by 1 will double the amount of memory. + */ +#ifndef PAGE_POOL_K +#define PAGE_POOL_K (15ULL) +#endif + +/* +* Huge Pool K +* +* Defines the size of the initial huge pool used by the VMM. If more memory +* is needed by the VMM initially, this value may be increased. Note that +* increasing "K" by 1 will double the amount of memory. +*/ + +#ifndef HUGE_POOL_K +#define HUGE_POOL_K (15ULL) +#endif +/* +* Memory Map Pool K +* +* Defines the size of the initial mem map pool used by the VMM. If more memory +* is needed by the VMM for mapping, this value may be increased. Note that +* increasing "K" by 1 will double the amount of memory. +*/ +#ifndef MEM_MAP_POOL_K +#define MEM_MAP_POOL_K (15ULL) +#endif + +/* + * Memory Map Pool Start + * + * This defines the starting location of the virtual memory that is used + * for memory mapping. Note that on some systems, this might need to be + * changed to prevent collisions. + * + * Note: defined in bytes (defaults to 2MB) + */ +#ifndef MEM_MAP_POOL_START +#define MEM_MAP_POOL_START 0x200000ULL +#endif + +/* + * Max Supported Modules + * + * The maximum number of modules supported by the VMM. If you VMM has a large + * number of dynamic libraries to load, this value might need to be increased + */ +#ifndef MAX_NUM_MODULES +#define MAX_NUM_MODULES (75LL) +#endif + +/* + * Debug Ring Size + * + * Defines the size of the debug ring. Note that the memory manager is used to + * allocate memory for the debug ring, so if you need more than one ring, + * which is supported, make sure the memory manager has enough memory in + * the huge pool to support your needs. + * + * Note: Must be defined using a bit shift as this prevents the debug ring from + * allocating memory that generates fragmentation in the memory manager + * + * Note: defined in bytes + */ +#define DEBUG_RING_SIZE (1 << 15ULL) + +/* + * Stack Size + * + * Each entry function is guarded with a custom stack to prevent stack + * overflows from corrupting the kernel, as well as providing a larger stack + * that's common in userspace code, but not in the kernel. If stack corruption + * is occuring, this function likely needs to be increased. Note one stack + * frame is allocated per CPU, so only increase this if needed. + * + * Note: Must be defined using a bit shift as we will mask to get the + * bottom of the stack if needed. + * + * Note: This is hard coded in the thread_context.asm as there is no way to + * use this include in NASM. If you change this, you must change the + * value in that file as well. + * + * Note: defined in bytes + */ +#ifndef STACK_SIZE +#define STACK_SIZE (1ULL << 15ULL) +#endif + +/* + * Thread Local Storage (TLS) Size + * + * Bareflank don't support threads, but it does support Multi-Core, and + * we need a way to store CPU specific information. Certain libc++ + * operations (for example, std::uncaught_exceptions) need to use this CPU + * specific storage so that the cores are not interfering with each other. + * So as far as the code is concerned, TLS is being used, even if a "thread" + * in the traditional sense isn't. + * + * Note: Defined in bytes + */ +#ifndef THREAD_LOCAL_STORAGE_SIZE +#define THREAD_LOCAL_STORAGE_SIZE (0x1000ULL) +#endif + +/* + * Default Serial COM Port + * + * On x64, possible values include (but not limited to): + * - 0x03F8U // COM1 + * - 0x02F8U // COM2 + * - 0x03E8U // COM3 + * - 0x02E8U // COM4 + * - 0xE000U + * - 0xE010U + * + * On aarch64, the value is the serial peripheral's physical base address. + * + * Note: See bfvmm/serial/serial_ns16550a.h + */ +#ifndef DEFAULT_COM_PORT +#if defined(BF_AARCH64) +# define DEFAULT_COM_PORT 0x09000000 +#else +# define DEFAULT_COM_PORT 0x03F8U +# define DEFAULT_COM_DRIVER serial_ns16550a +#endif +#endif + +/* + * Serial Port Driver + * + * Possible values include: + * - serial_ns16550a + * - serial_pl011 + * + * On x64, this should always be serial_ns16550a. + */ +#ifndef DEFAULT_COM_DRIVER +#if defined(BF_AARCH64) +# define DEFAULT_COM_DRIVER serial_pl011 +#else +# define DEFAULT_COM_DRIVER serial_ns16550a +#endif +#endif + +/* + * Serial port memory length (aarch64 only) + * + * This is the length of the memory region occupied by the memory-mapped + * serial port. + */ +#if !defined(DEFAULT_COM_LENGTH) && defined(BF_AARCH64) +#define DEFAULT_COM_LENGTH 0x1000 +#endif + +/* + * Default Serial Baud Rate + * + * Note: See bfvmm/serial/serial_ns16550a.h + */ +#ifndef DEFAULT_BAUD_RATE +#define DEFAULT_BAUD_RATE baud_rate_115200 +#endif + +/* + * Default serial baud rate divisor, integer part (for PL011) + * + * Note: See bfvmm/serial/serial_pl011.h + */ +#ifndef DEFAULT_BAUD_RATE_INT +#define DEFAULT_BAUD_RATE_INT 0x4 +#endif + +/* + * Default serial baud rate divisor, fractional part (for PL011) + * + * Note: See bfvmm/serial/serial_pl011.h + */ +#ifndef DEFAULT_BAUD_RATE_FRAC +#define DEFAULT_BAUD_RATE_FRAC 0x0 +#endif + +/* + * Default Serial Data Bits + * + * Note: See bfvmm/serial/serial_ns16550a.h + */ +#ifndef DEFAULT_DATA_BITS +#define DEFAULT_DATA_BITS char_length_8 +#endif + +/* + * Default Serial Stop Bits + * + * Note: See bfvmm/serial/serial_ns16550a.h + */ +#ifndef DEFAULT_STOP_BITS +#define DEFAULT_STOP_BITS stop_bits_1 +#endif + +/* + * Default Serial Parity Bits + * + * Note: See bfvmm/serial/serial_ns16550a.h + */ +#ifndef DEFAULT_PARITY_BITS +#define DEFAULT_PARITY_BITS parity_none +#endif + +/* + * Debug Level + * + * Defines how noisy Bareflank is. This defaults to 0 which only prints status + * information. Raise this level to include additional verbosity. Note that + * as you increase this level, performance will degrade. + */ +#ifndef DEBUG_LEVEL +#define DEBUG_LEVEL 0 +#endif + +#endif diff --git a/payloads/bareflank/include/bfdebug.h b/payloads/bareflank/include/bfdebug.h new file mode 100644 index 00000000000..03cf53b2214 --- /dev/null +++ b/payloads/bareflank/include/bfdebug.h @@ -0,0 +1,1137 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFDEBUG_H +#define BFDEBUG_H + +#include + +/** @cond */ + +/* -------------------------------------------------------------------------- */ +/* C++ Debugging */ +/* -------------------------------------------------------------------------- */ + +#ifdef __cplusplus + +#include +#include + +#include + +#ifdef _MSC_VER +#define bfcolor_black "" +#define bfcolor_red "" +#define bfcolor_green "" +#define bfcolor_yellow "" +#define bfcolor_blue "" +#define bfcolor_magenta "" +#define bfcolor_cyan "" +#define bfcolor_end "" +#else +#define bfcolor_black "\033[1;30m" +#define bfcolor_red "\033[1;31m" +#define bfcolor_green "\033[1;32m" +#define bfcolor_yellow "\033[1;33m" +#define bfcolor_blue "\033[1;34m" +#define bfcolor_magenta "\033[1;35m" +#define bfcolor_cyan "\033[1;36m" +#define bfcolor_end "\033[0m" +#endif + +#define bfcolor_debug bfcolor_green +#define bfcolor_alert bfcolor_yellow +#define bfcolor_error bfcolor_red + +using cstr_t = const char *; + +#ifdef UNIX +#define __BFFUNC__ static_cast(__PRETTY_FUNCTION__) +#else +#define __BFFUNC__ static_cast(__FUNCTION__) +#endif + +#ifdef VMM +extern "C" uint64_t thread_context_cpuid(void); +extern "C" uint64_t write_str(const std::string &str); +#else +#include +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4312) +#endif + +template < + typename T, + typename = std::enable_if_t < + std::is_pointer::value || + std::is_integral::value + > + > +const void * +view_as_pointer(const T val) +{ return reinterpret_cast(val); } + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +extern "C" uint64_t +unsafe_write_cstr(const char *cstr, size_t len); + +/* ---------------------------------------------------------------------------*/ +/* Low Level Debugging */ +/* ---------------------------------------------------------------------------*/ + +inline char * +bfitoa(size_t value, char *str, size_t base) +{ + const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + int i = 0, j = 0; + size_t remainder; + + do { + remainder = value % base; + str[i++] = digits[remainder]; + value = value / base; + } + while (value != 0); + + str[i] = '\0'; + + for (j = 0, i--; j < i; j++, i--) { + char c = str[j]; + str[j] = str[i]; + str[i] = c; + } + + return str; +} + +#define CALLED() \ + { \ + const auto *str_text = "\033[1;32mDEBUG\033[0m: function called = "; \ + const auto *str_func = __BFFUNC__; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(str_func, strlen(str_func)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define WARNING(a) \ + { \ + const auto *str_text = "\033[1;33mWARNING\033[0m: " a " = "; \ + const auto *str_func = __BFFUNC__; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(str_func, strlen(str_func)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define UNHANDLED() \ + { \ + const auto *str_text = "\033[1;33mWARNING\033[0m: unsupported function called = "; \ + const auto *str_func = __BFFUNC__; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(str_func, strlen(str_func)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define ARG_UNSUPPORTED(a) \ + { \ + const auto *str_text = "\033[1;33mWARNING\033[0m: " a " not supported for function called = "; \ + const auto *str_func = __BFFUNC__; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(str_func, strlen(str_func)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + + +#define DEBUG_STR(a,b) \ + { \ + const auto *str_text = "\033[1;32mDEBUG\033[0m: " a " = "; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(b, strlen(b)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define DEBUG_DEC(a,b) \ + { \ + char numstr[64]; \ + bfitoa(b, numstr, 10); \ + const auto *str_text = "\033[1;32mDEBUG\033[0m: " a " = "; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(numstr, strlen(numstr)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define DEBUG_HEX(a,b) \ + { \ + char numstr[64]; \ + bfitoa(b, numstr, 16); \ + const auto *str_text = "\033[1;32mDEBUG\033[0m: " a " = "; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(numstr, strlen(numstr)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +#define DEBUG_LINE() \ + { \ + char numstr[64]; \ + bfitoa(__LINE__, numstr, 10); \ + const auto *str_text = "\033[1;32mDEBUG\033[0m: "; \ + const auto *str_func = __BFFUNC__; \ + const auto *str_next = " = "; \ + const auto *str_endl = "\n"; \ + unsafe_write_cstr(str_text, strlen(str_text)); \ + unsafe_write_cstr(str_func, strlen(str_func)); \ + unsafe_write_cstr(str_next, strlen(str_next)); \ + unsafe_write_cstr(numstr, strlen(numstr)); \ + unsafe_write_cstr(str_endl, strlen(str_endl)); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Helpers (Private) */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_core(gsl::not_null msg) +{ + *msg += bfcolor_cyan; + *msg += "["; + *msg += bfcolor_yellow; +#ifdef VMM + *msg += std::to_string(thread_context_cpuid()); +#else + *msg += '0'; +#endif + *msg += bfcolor_cyan; + *msg += "] "; + *msg += bfcolor_end; +} + +inline void +__bfdebug_type(gsl::not_null msg, cstr_t color, cstr_t type) +{ + *msg += color; + *msg += type; + *msg += bfcolor_end; + *msg += ": "; +} + +inline void +__bfdebug_jtfy(gsl::not_null msg, uint64_t width, cstr_t title, cstr_t indent) +{ + if (title != nullptr) { + auto len = width - strlen(title); + + if (indent != nullptr) { + len -= strlen(indent); + *msg += indent; + } + + *msg += title; + *msg += std::string(len, ' '); + } + else { + *msg += std::string(width, ' '); + } +} + +template +void __bfdebug_transaction(F func) +{ + std::string msg; + msg.reserve(0x1000); + func(&msg); + +#ifdef VMM + write_str(msg); +#else + std::cout << msg; +#endif +} + +template +void __bfdebug_add_line(std::string *msg, F func) +{ + if (msg == nullptr) { + __bfdebug_transaction([&](std::string * tmsg) { + func(tmsg); + }); + } + else { + std::string ln; + ln.reserve(0x1000); + + func(&ln); + + if (msg->size() + ln.size() > msg->capacity()) { + msg->reserve(msg->capacity() + 0x1000); + } + + *msg += ln; + } +} + +#define bfdebug_transaction(level,func) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_transaction(func); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Get Macro Magic */ +/* ---------------------------------------------------------------------------*/ + +/* + * This is a cleaned up version of the following: + * https://stackoverflow.com/questions/11761703/overloading-macro-on-number-of-arguments + * + * This is needed because some of the debug macros only take a single argument, + * which means __VA_ARGS__ gets mad because it's not used. For macros with more + * than one arg, this is not needed. Also, if this becomes needed for other + * things in the future, we should move this to it's own header + * + * The bug fix for MSVC comes from the following: + * https://stackoverflow.com/questions/5134523/msvc-doesnt-expand-va-args-correctly + */ + +#define __BUGFX(x) x + +#define __NARG2(...) __BUGFX(__NARG1(__VA_ARGS__,__RSEQN())) +#define __NARG1(...) __BUGFX(__ARGSN(__VA_ARGS__)) +#define __ARGSN(_1,_2,_3,_4,_5,_6,_7,_8,_9,_10,N,...) N +#define __RSEQN() 10,9,8,7,6,5,4,3,2,1,0 + +#define __FUNC2(name,n) name ## n +#define __FUNC1(name,n) __FUNC2(name,n) +#define GET_MACRO(func,...) __FUNC1(func,__BUGFX(__NARG2(__VA_ARGS__))) (__VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Info */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_info_core(cstr_t color, cstr_t type, cstr_t title, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + + if (title != nullptr) { + *msg += std::string(title); + } + + *msg += '\n'; +} + +inline void +__bfdebug_info(cstr_t color, cstr_t type, cstr_t title, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_info_core(color, type, title, ln); + }); +} + +#define bfdebug_info(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_info(bfcolor_debug, "DEBUG", __VA_ARGS__); \ + } + +#define bfalert_info(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_info(bfcolor_alert, "ALERT", __VA_ARGS__); \ + } + +#define bferror_info(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_info(bfcolor_error, "ERROR", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Line Break */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_lnbr_core(cstr_t color, cstr_t type, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + + *msg += '\n'; +} + +inline void +__bfdebug_lnbr(cstr_t color, cstr_t type, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_lnbr_core(color, type, ln); + }); +} + +#define bfdebug_lnbr1(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_debug, "DEBUG"); \ + } + +#define bfalert_lnbr1(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_alert, "ALERT"); \ + } + +#define bferror_lnbr1(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_error, "ERROR"); \ + } + +#define bfdebug_lnbr2(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_debug, "DEBUG", msg); \ + } + +#define bfalert_lnbr2(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_alert, "ALERT", msg); \ + } + +#define bferror_lnbr2(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_lnbr(bfcolor_error, "ERROR", msg); \ + } + +#define bfdebug_lnbr(...) GET_MACRO(bfdebug_lnbr, __VA_ARGS__) +#define bfalert_lnbr(...) GET_MACRO(bfalert_lnbr, __VA_ARGS__) +#define bferror_lnbr(...) GET_MACRO(bferror_lnbr, __VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Horizontal Line Break1 */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_brk1_core(cstr_t color, cstr_t type, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + + *msg += "======================================================================"; + *msg += '\n'; +} + +inline void +__bfdebug_brk1(cstr_t color, cstr_t type, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_brk1_core(color, type, ln); + }); +} + +#define bfdebug_brk11(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_debug, "DEBUG"); \ + } + +#define bfalert_brk11(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_alert, "ALERT"); \ + } + +#define bferror_brk11(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_error, "ERROR"); \ + } + +#define bfdebug_brk12(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_debug, "DEBUG", msg); \ + } + +#define bfalert_brk12(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_alert, "ALERT", msg); \ + } + +#define bferror_brk12(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk1(bfcolor_error, "ERROR", msg); \ + } + +#define bfdebug_brk1(...) GET_MACRO(bfdebug_brk1, __VA_ARGS__) +#define bfalert_brk1(...) GET_MACRO(bfalert_brk1, __VA_ARGS__) +#define bferror_brk1(...) GET_MACRO(bferror_brk1, __VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Horizontal Line Break2 */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_brk2_core(cstr_t color, cstr_t type, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + + *msg += "----------------------------------------------------------------------"; + *msg += '\n'; +} + +inline void +__bfdebug_brk2(cstr_t color, cstr_t type, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_brk2_core(color, type, ln); + }); +} + +#define bfdebug_brk21(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_debug, "DEBUG"); \ + } + +#define bfalert_brk21(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_alert, "ALERT"); \ + } + +#define bferror_brk21(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_error, "ERROR"); \ + } + +#define bfdebug_brk22(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_debug, "DEBUG", msg); \ + } + +#define bfalert_brk22(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_alert, "ALERT", msg); \ + } + +#define bferror_brk22(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk2(bfcolor_error, "ERROR", msg); \ + } + +#define bfdebug_brk2(...) GET_MACRO(bfdebug_brk2, __VA_ARGS__) +#define bfalert_brk2(...) GET_MACRO(bfalert_brk2, __VA_ARGS__) +#define bferror_brk2(...) GET_MACRO(bferror_brk2, __VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Horizontal Line Break3 */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_brk3_core(cstr_t color, cstr_t type, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + + *msg += "......................................................................"; + *msg += '\n'; +} + +inline void +__bfdebug_brk3(cstr_t color, cstr_t type, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_brk3_core(color, type, ln); + }); +} + +#define bfdebug_brk31(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_debug, "DEBUG"); \ + } + +#define bfalert_brk31(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_alert, "ALERT"); \ + } + +#define bferror_brk31(level) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_error, "ERROR"); \ + } + +#define bfdebug_brk32(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_debug, "DEBUG", msg); \ + } + +#define bfalert_brk32(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_alert, "ALERT", msg); \ + } + +#define bferror_brk32(level,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_brk3(bfcolor_error, "ERROR", msg); \ + } + +#define bfdebug_brk3(...) GET_MACRO(bfdebug_brk3, __VA_ARGS__) +#define bfalert_brk3(...) GET_MACRO(bfalert_brk3, __VA_ARGS__) +#define bferror_brk3(...) GET_MACRO(bferror_brk3, __VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Hex Number */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_nhex_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, uint64_t nhex, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 52, title, indent); + + *msg += bfn::to_string(nhex, 16); + *msg += '\n'; +} + +inline void +__bfdebug_nhex( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, uint64_t nhex, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_nhex_core(color, type, indent, title, nhex, ln); + }); +} + +inline void +__bfdebug_nhex( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, void *nhex, std::string *msg = nullptr) +{ __bfdebug_nhex(color, type, indent, title, reinterpret_cast(nhex), msg); } + +#define bfdebug_nhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_nhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_nhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subnhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subnhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subnhex(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_nhex(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Decimal Number */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_ndec_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, uint64_t ndec, gsl::not_null msg) +{ + auto str = bfn::to_string(ndec, 10); + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 70 - str.length(), title, indent); + + *msg += str; + *msg += '\n'; +} + +inline void +__bfdebug_ndec( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, uint64_t ndec, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_ndec_core(color, type, indent, title, ndec, ln); + }); +} + +#define bfdebug_ndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_ndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_ndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subndec(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_ndec(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Boolean */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_bool_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, bool val, gsl::not_null msg) +{ + auto str = val ? "true" : "false"; + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 70 - strlen(str), title, indent); + + *msg += str; + *msg += '\n'; +} + +inline void +__bfdebug_bool( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, bool val, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_bool_core(color, type, indent, title, val, ln); + }); +} + +#define bfdebug_bool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_bool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_bool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subbool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subbool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subbool(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_bool(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Text */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_text_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, cstr_t text, gsl::not_null msg) +{ + auto str = text == nullptr ? std::string{} : std::string{text}; + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 70 - str.length(), title, indent); + + *msg += str; + *msg += '\n'; +} + +inline void +__bfdebug_text( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, cstr_t text, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_text_core(color, type, indent, title, text, ln); + }); +} + +#define bfdebug_text(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_text(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_text(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subtext(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subtext(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subtext(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_text(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Pass */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_pass_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 66, title, indent); + + *msg += bfcolor_green "pass" bfcolor_end; + *msg += '\n'; +} + +inline void +__bfdebug_pass( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_pass_core(color, type, indent, title, ln); + }); +} + +#define bfdebug_pass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_pass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_pass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subpass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subpass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subpass(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_pass(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Fail */ +/* ---------------------------------------------------------------------------*/ + +inline void +__bfdebug_fail_core( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, gsl::not_null msg) +{ + __bfdebug_core(msg); + __bfdebug_type(msg, color, type); + __bfdebug_jtfy(msg, 66, title, indent); + + *msg += bfcolor_red "fail <----" bfcolor_end; + *msg += '\n'; +} + +inline void +__bfdebug_fail( + cstr_t color, cstr_t type, cstr_t indent, cstr_t title, std::string *msg = nullptr) +{ + __bfdebug_add_line(msg, [&](std::string * ln) { + __bfdebug_fail_core(color, type, indent, title, ln); + }); +} + +#define bfdebug_fail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_debug, "DEBUG", nullptr, __VA_ARGS__); \ + } + +#define bfalert_fail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_alert, "ALERT", nullptr, __VA_ARGS__); \ + } + +#define bferror_fail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_error, "ERROR", nullptr, __VA_ARGS__); \ + } + +#define bfdebug_subfail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_debug, "DEBUG", " - ", __VA_ARGS__); \ + } + +#define bfalert_subfail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_alert, "ALERT", " - ", __VA_ARGS__); \ + } + +#define bferror_subfail(level, ...) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + __bfdebug_fail(bfcolor_error, "ERROR", " - ", __VA_ARGS__); \ + } + +/* ---------------------------------------------------------------------------*/ +/* Test */ +/* ---------------------------------------------------------------------------*/ + +#define bfdebug_test3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfdebug_pass(level,title); \ + } \ + else { \ + bfdebug_fail(level,title); \ + } \ + } + +#define bfdebug_subtest3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfdebug_subpass(level,title); \ + } \ + else { \ + bfdebug_subfail(level,title); \ + } \ + } + +#define bfalert_test3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfalert_pass(level,title); \ + } \ + else { \ + bfalert_fail(level,title); \ + } \ + } + +#define bfalert_subtest3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfalert_subpass(level,title); \ + } \ + else { \ + bfalert_subfail(level,title); \ + } \ + } + +#define bferror_test3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bferror_pass(level,title); \ + } \ + else { \ + bferror_fail(level,title); \ + } \ + } + +#define bferror_subtest3(level,title,val) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bferror_subpass(level,title); \ + } \ + else { \ + bferror_subfail(level,title); \ + } \ + } + +#define bfdebug_test4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfdebug_pass(level,title,msg); \ + } \ + else { \ + bfdebug_fail(level,title,msg); \ + } \ + } + +#define bfdebug_subtest4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfdebug_subpass(level,title,msg); \ + } \ + else { \ + bfdebug_subfail(level,title,msg); \ + } \ + } + +#define bfalert_test4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfalert_pass(level,title,msg); \ + } \ + else { \ + bfalert_fail(level,title,msg); \ + } \ + } + +#define bfalert_subtest4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bfalert_subpass(level,title,msg); \ + } \ + else { \ + bfalert_subfail(level,title,msg); \ + } \ + } + +#define bferror_test4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bferror_pass(level,title,msg); \ + } \ + else { \ + bferror_fail(level,title,msg); \ + } \ + } + +#define bferror_subtest4(level,title,val,msg) \ + if (GSL_UNLIKELY(level <= DEBUG_LEVEL)) { \ + if ((val)) { \ + bferror_subpass(level,title,msg); \ + } \ + else { \ + bferror_subfail(level,title,msg); \ + } \ + } + +#define bfdebug_test(...) GET_MACRO(bfdebug_test, __VA_ARGS__) +#define bfdebug_subtest(...) GET_MACRO(bfdebug_subtest, __VA_ARGS__) +#define bfalert_test(...) GET_MACRO(bfalert_test, __VA_ARGS__) +#define bfalert_subtest(...) GET_MACRO(bfalert_subtest, __VA_ARGS__) +#define bferror_test(...) GET_MACRO(bferror_test, __VA_ARGS__) +#define bferror_subtest(...) GET_MACRO(bferror_subtest, __VA_ARGS__) + +/* ---------------------------------------------------------------------------*/ +/* Line / Field */ +/* ---------------------------------------------------------------------------*/ + +#define bfline bfdebug_ndec(0, "line", __LINE__); +#define __bffield1(a,b) bfdebug_ndec(0, "[" #b "] " #a, a); +#define __bffield2(a,b) __bffield1(a,b); +#define bffield(a) __bffield2(a,__LINE__) +#define __bffield_hex1(a,b) bfdebug_nhex(0, "[" #b "] " #a, a); +#define __bffield_hex2(a,b) __bffield_hex1(a,b); +#define bffield_hex(a) __bffield_hex2(a,__LINE__) + +#endif + +/* -------------------------------------------------------------------------- */ +/* C Debugging */ +/* -------------------------------------------------------------------------- */ + +#ifndef KERNEL +#ifdef __cplusplus +#include +#else +#include +#endif +#define BFDEBUG(...) printf("[BAREFLANK DEBUG]: " __VA_ARGS__) +#define BFALERT(...) printf("[BAREFLANK ALERT]: " __VA_ARGS__) +#define BFERROR(...) printf("[BAREFLANK ERROR]: " __VA_ARGS__) +#endif + +/* -------------------------------------------------------------------------- */ +/* Linux Debugging */ +/* -------------------------------------------------------------------------- */ + +#ifdef KERNEL +#ifdef __linux__ +#include +#define BFDEBUG(...) printk(KERN_INFO "[BAREFLANK DEBUG]: " __VA_ARGS__) +#define BFALERT(...) printk(KERN_INFO "[BAREFLANK ALERT]: " __VA_ARGS__) +#define BFERROR(...) printk(KERN_ALERT "[BAREFLANK ERROR]: " __VA_ARGS__) +#endif +#endif + +/* -------------------------------------------------------------------------- */ +/* Windows Debugging */ +/* -------------------------------------------------------------------------- */ + +#ifdef KERNEL +#ifdef _WIN32 +#include +#define BFDEBUG(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[BAREFLANK DEBUG]: " __VA_ARGS__) +#define BFALERT(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "[BAREFLANK ALERT]: " __VA_ARGS__) +#define BFERROR(...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "[BAREFLANK ERROR]: " __VA_ARGS__) +#endif +#endif + +/* -------------------------------------------------------------------------- */ +/* EFI Debugging */ +/* -------------------------------------------------------------------------- */ + +#ifdef KERNEL +#ifdef EFI +#include "efi.h" +#include "efilib.h" +#define BFDEBUG(...) Print(L"[BAREFLANK DEBUG]: " __VA_ARGS__) +#define BFALERT(...) Print(L"[BAREFLANK ALERT]: " __VA_ARGS__) +#define BFERROR(...) Print(L"[BAREFLANK ERROR]: " __VA_ARGS__) +#endif +#endif + + +/** @endcond */ + +#endif diff --git a/payloads/bareflank/include/bfdebugringinterface.h b/payloads/bareflank/include/bfdebugringinterface.h new file mode 100644 index 00000000000..6aedf3b8f58 --- /dev/null +++ b/payloads/bareflank/include/bfdebugringinterface.h @@ -0,0 +1,163 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfdebug.h + */ + +#ifndef BFDEBUGRINGINTERFACE_H +#define BFDEBUGRINGINTERFACE_H + +#include +#include +#include +#include + +#pragma pack(push, 1) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Get Debug Ring Resource Typedef + * + * @expects none + * @ensures none + * + * This is used by the driver entry to as the function signature for + * getting it's internal debug ring + */ +typedef struct debug_ring_resources_t *(*get_drr_t)(uint64_t vcpuid); + +/** + * @struct debug_ring_resources_t + * + * Debug Ring Resources + * + * Each driver entry needs to allocate some memory for the debug ring, and + * then cast this structure over the allocated memory to access the bits used + * by the ring. + * + * Prior to providing this structure to the debug ring, the memory should be + * cleared, and the len of the buffer should be set to the total length of + * memory allocated minus the size of debug_ring_resources_t. + * + * @code + * + * int len = PAGE_SIZE * 100; + * struct debug_ring_resources_t *drr = valloc(len); + * + * memset(drr, 0, len); + * drr->len = len - sizeof(debug_ring_resources_t); + * + * + * + * int ret; + * char read_buf[len] + * + * ret = debug_ring_read(drr, read_buf, len); + * if(ret < 0) + * + * + * @endcode + * + * Note there are many different designs for cicular buffers, but all of the + * designs have to face the same problem. How to detect when the buffer is + * full vs when it is empty. This design uses two counters the grow + * forever. The current position in the buffer is then pos % len. If the + * counters are 64bit, it would take a life time for the counters to + * overflow. + * + * @var debug_ring_resources_t::epos + * the end position in the circular buffer + * @var debug_ring_resources_t::spos + * the start position in the circular buffer + * @var debug_ring_resources_t::tag1 + * used to identify the debug ring from a memory dump + * @var debug_ring_resources_t::buf + * the circular buffer that stores the debug strings. + * @var debug_ring_resources_t::tag2 + * used to identify the debug ring from a memory dump + */ +struct debug_ring_resources_t { + uint64_t epos; + uint64_t spos; + + uint64_t tag1; + char buf[DEBUG_RING_SIZE]; + uint64_t tag2; +}; + +/** + * Debug Ring Read + * + * Reads strings that have been written to the debug ring. Although you can + * provide any buffer size you want, it's advised to provide a buffer that + * is the same size as the buffer that was originally allocated. + * + * @expects none + * @ensures none + * + * @param drr the debug_ring_resource that was used to create the + * debug ring + * @param str the buffer to read the string into. should be the same size + * as drr in bytes + * @param len the length of the str buffer in bytes + * @return the number of bytes read from the debug ring, 0 + * on error + */ +static inline uint64_t +debug_ring_read(struct debug_ring_resources_t *drr, char *str, uint64_t len) +{ + uint64_t i; + uint64_t spos; + uint64_t count; + uint64_t content; + + if (drr == 0 || str == 0 || len == 0) { + return 0; + } + + if (drr->spos > drr->epos) { + return 0; + } + + spos = drr->spos % DEBUG_RING_SIZE; + content = drr->epos - drr->spos; + + for (i = 0, count = 0; i < content && i < len - 1; i++) { + if (drr->buf[spos] != '\0') { + str[count++] = drr->buf[spos]; + } + + spos = ((spos + 1) % DEBUG_RING_SIZE); + } + + str[i] = '\0'; + return count; +} + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif diff --git a/payloads/bareflank/include/bfdelegate.h b/payloads/bareflank/include/bfdelegate.h new file mode 100644 index 00000000000..7e661f82678 --- /dev/null +++ b/payloads/bareflank/include/bfdelegate.h @@ -0,0 +1,282 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULLAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfdelegate.h +/// + +#ifndef BFDELEGATE_H +#define BFDELEGATE_H + +#include + +// ----------------------------------------------------------------------------- +// Delegate Definition +// ----------------------------------------------------------------------------- + +template < + typename T, + typename = std::enable_if::value> + > +class delegate; + +// ----------------------------------------------------------------------------- +// Delegate Partial Specialization +// ----------------------------------------------------------------------------- + +/// Delegate +/// +/// This delegate class provides the ability to register a call back function +/// that originates from: +/// - A free function +/// - A member function +/// - A lambda function (including capture lists) +/// +/// It should be noted that this class attempts to provide the most effcient +/// implementation without the need for malloc / free, or inheritance, at +/// the expense of a very specific syntax requirement. +/// +template < + typename RET, + typename ...PARAMS + > +class delegate +{ + using stub_t = RET(*)(void *, PARAMS...); ///< Stub function type + +public: + + /// Default Constructor + /// + /// Creates a nullptr delegate. Note that attempts to execute a nullptr + /// delegate will result in a crash as we do not perform a check for + /// null + /// + delegate() noexcept = default; + + /// Default Destructor + /// + ~delegate() noexcept = default; + + /// Is Valid + /// + /// @return true if valid, false otherwise + /// + constexpr bool is_valid() const noexcept + { return m_stub != nullptr; } + + /// Is Valid + /// + /// @return true if valid, false otherwise + /// + constexpr explicit operator bool() const noexcept + { return is_valid(); } + + /// Create (Member Function Pointer) + /// + /// Example usage: + /// @code + /// test_class t; + /// auto d = delegate::create(&t); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @param obj a pointer to the class who's member function will + /// be executed. + /// @return resulting delegate + /// + template < + typename T, + RET(T::*FUNC)(PARAMS...), + typename = std::enable_if::value> + > + constexpr static delegate create(T &obj) noexcept + { return delegate(std::addressof(obj), member_stub); } + + /// Create (Member Function Pointer Class Pointer) + /// + /// Example usage: + /// @code + /// test_class t; + /// auto d = delegate::create(&t); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @param obj a pointer to the class who's member function will + /// be executed. + /// @return resulting delegate + /// + template < + typename T, + RET(T::*FUNC)(PARAMS...), + typename = std::enable_if::value> + > + constexpr static delegate create(T *obj) noexcept + { return delegate(obj, member_stub); } + + /// Create (Member Function Unique Pointer) + /// + /// Example usage: + /// @code + /// auto t = make_unique(); + /// auto d = delegate::create(t); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @param obj a pointer to the class who's member function will + /// be executed. + /// @return resulting delegate + /// + template < + typename T, + RET(T::*FUNC)(PARAMS...), + typename = std::enable_if::value> + > + constexpr static delegate create(const std::unique_ptr &obj) noexcept + { return delegate(obj.get(), member_stub); } + + /// Create (Const Member Function Pointer) + /// + /// Example usage: + /// @code + /// test_class t; + /// auto d = delegate::create(&t); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @note this function has to have _const appended to it's name because + /// MSVC doesn't understand the template overload and fails to + /// compile. + /// + /// @param obj a pointer to the class who's member function will + /// be executed. + /// @return resulting delegate + /// + template < + typename T, + RET(T::*FUNC)(PARAMS...) const, + typename = std::enable_if::value> + > + constexpr static delegate create_const(const T &obj) noexcept + { return delegate(const_cast(std::addressof(obj)), const_member_stub); } + + /// Create (Function Pointer) + /// + /// Example usage: + /// @code + /// auto d = delegate::create<&foo>(); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @return resulting delegate + /// + template + constexpr static delegate create() noexcept + { return delegate(nullptr, function_stub); } + + /// Create (Lambda Pointer) + /// + /// Example usage: + /// @code + /// test_class t; + /// auto d = delegate::create([](int val) -> int { return val; }); + /// std::cout << "d: " << d(1) << '\n'; + /// @endcode + /// + /// @param ptr a pointer to the lambda function that will + /// be executed. + /// @return resulting delegate + /// + template + constexpr static delegate create(const LAMBDA &ptr) noexcept + { return delegate(reinterpret_cast(const_cast(std::addressof(ptr))), lambda_stub); } + + /// Operator () + /// + /// @param params the parameters to pass to the delegate function. + /// @return the result of executing the delegate function + /// + constexpr RET operator()(PARAMS... params) const + { return (*m_stub)(m_obj, std::forward(params)...); } + +private: + + /// @cond + + // Note: + // + // The only public constructor is the default constructor. To create a + // delegate, use the delegate::create function. + // + + constexpr explicit delegate(void *obj, stub_t stub) noexcept : + m_obj(obj), + m_stub(stub) + { } + + /// @endcond + +private: + + /// @cond + + template < + typename T, + RET(T::*FUNC)(PARAMS...), + typename = std::enable_if::value> + > + constexpr static RET member_stub(void *obj, PARAMS... params) + { return (static_cast(obj)->*FUNC)(std::forward(params)...); } + + template < + typename T, + RET(T::*FUNC)(PARAMS...) const, + typename = std::enable_if::value> + > + constexpr static RET const_member_stub(void *obj, PARAMS... params) + { return (static_cast(obj)->*FUNC)(std::forward(params)...); } + + template + constexpr static RET function_stub(void *, PARAMS... params) + { return (FUNC)(std::forward(params)...); } + + template + constexpr static RET lambda_stub(void *ptr, PARAMS... params) + { return (static_cast(ptr)->operator())(std::forward(params)...); } + + /// @endcond + +private: + + void *m_obj{nullptr}; ///< Object containing member function + stub_t m_stub{nullptr}; ///< Stub that executes the delegate function + +public: + + /// @cond + + delegate(const delegate &other) noexcept = default; + delegate &operator=(const delegate &other) noexcept = default; + + delegate(delegate &&other) noexcept = default; + delegate &operator=(delegate &&other) noexcept = default; + + /// @endcond +}; + +#endif diff --git a/payloads/bareflank/include/bfdriverinterface.h b/payloads/bareflank/include/bfdriverinterface.h new file mode 100644 index 00000000000..af07deb8ee7 --- /dev/null +++ b/payloads/bareflank/include/bfdriverinterface.h @@ -0,0 +1,116 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFDRIVERINTERFACE_H +#define BFDRIVERINTERFACE_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* -------------------------------------------------------------------------- */ +/* Common */ +/* -------------------------------------------------------------------------- */ + +#define VMM_UNLOADED 10 +#define VMM_LOADED 11 +#define VMM_RUNNING 12 +#define VMM_CORRUPT 100 + +#ifndef BAREFLANK_NAME +#define BAREFLANK_NAME "bareflank" +#endif + +#ifndef BAREFLANK_MAJOR +#define BAREFLANK_MAJOR 150 +#endif + +#ifndef BAREFLANK_DEVICETYPE +#define BAREFLANK_DEVICETYPE 0xF00D +#endif + +#define IOCTL_ADD_MODULE_LENGTH_CMD 0x801 +#define IOCTL_ADD_MODULE_CMD 0x802 +#define IOCTL_LOAD_VMM_CMD 0x803 +#define IOCTL_UNLOAD_VMM_CMD 0x804 +#define IOCTL_START_VMM_CMD 0x805 +#define IOCTL_STOP_VMM_CMD 0x806 +#define IOCTL_DUMP_VMM_CMD 0x807 +#define IOCTL_VMM_STATUS_CMD 0x808 +#define IOCTL_SET_VCPUID_CMD 0x80A + +/* -------------------------------------------------------------------------- */ +/* Linux Interfaces */ +/* -------------------------------------------------------------------------- */ + +#ifdef __linux__ + +#define IOCTL_ADD_MODULE_LENGTH _IOW(BAREFLANK_MAJOR, IOCTL_ADD_MODULE_LENGTH_CMD, uint64_t *) +#define IOCTL_ADD_MODULE _IOW(BAREFLANK_MAJOR, IOCTL_ADD_MODULE_CMD, char *) +#define IOCTL_LOAD_VMM _IO(BAREFLANK_MAJOR, IOCTL_LOAD_VMM_CMD) +#define IOCTL_UNLOAD_VMM _IO(BAREFLANK_MAJOR, IOCTL_UNLOAD_VMM_CMD) +#define IOCTL_START_VMM _IO(BAREFLANK_MAJOR, IOCTL_START_VMM_CMD) +#define IOCTL_STOP_VMM _IO(BAREFLANK_MAJOR, IOCTL_STOP_VMM_CMD) +#define IOCTL_DUMP_VMM _IOR(BAREFLANK_MAJOR, IOCTL_DUMP_VMM_CMD, struct debug_ring_resources_t *) +#define IOCTL_VMM_STATUS _IOR(BAREFLANK_MAJOR, IOCTL_VMM_STATUS_CMD, int64_t *) +#define IOCTL_SET_VCPUID _IOW(BAREFLANK_MAJOR, IOCTL_SET_VCPUID_CMD, uint64_t *) + +#endif + +/* -------------------------------------------------------------------------- */ +/* Windows Interfaces */ +/* -------------------------------------------------------------------------- */ + +#if defined(_WIN32) || defined(__CYGWIN__) + +#include + +DEFINE_GUID( + GUID_DEVINTERFACE_bareflank, + 0x1d9c9218, + 0x3c88, + 0x4b81, + 0x8e, + 0x81, + 0xb4, + 0x62, + 0x2a, + 0x4d, + 0xcb, + 0x44); + +#define IOCTL_ADD_MODULE CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_ADD_MODULE_CMD, METHOD_IN_DIRECT, FILE_WRITE_DATA) +#define IOCTL_LOAD_VMM CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_LOAD_VMM_CMD, METHOD_BUFFERED, 0) +#define IOCTL_UNLOAD_VMM CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_UNLOAD_VMM_CMD, METHOD_BUFFERED, 0) +#define IOCTL_START_VMM CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_START_VMM_CMD, METHOD_BUFFERED, 0) +#define IOCTL_STOP_VMM CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_STOP_VMM_CMD, METHOD_BUFFERED, 0) +#define IOCTL_DUMP_VMM CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_DUMP_VMM_CMD, METHOD_OUT_DIRECT, FILE_READ_DATA) +#define IOCTL_VMM_STATUS CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_VMM_STATUS_CMD, METHOD_BUFFERED, FILE_READ_DATA) +#define IOCTL_SET_VCPUID CTL_CODE(BAREFLANK_DEVICETYPE, IOCTL_SET_VCPUID_CMD, METHOD_IN_DIRECT, FILE_WRITE_DATA) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/include/bfdwarf.h b/payloads/bareflank/include/bfdwarf.h new file mode 100644 index 00000000000..b13bc99b7bd --- /dev/null +++ b/payloads/bareflank/include/bfdwarf.h @@ -0,0 +1,96 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfdwarf.h + */ + +#ifndef BFDWARF_H +#define BFDWARF_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @struct dwarf_sections_t + * + * Struct to hold pointers to all the used DWARF sections + * + * @var dwarf_sections_t::debug_info_addr + * the virtual address of ".debug_info" after relocation + * @var dwarf_sections_t::debug_info_size + * the size of ".debug_info" + * @var dwarf_sections_t::debug_abbrev_addr + * the virtual address of ".debug_abbrev" after relocation + * @var dwarf_sections_t::debug_abbrev_size + * the size of ".debug_abbrev" + * @var dwarf_sections_t::debug_line_addr + * the virtual address of ".debug_line" after relocation + * @var dwarf_sections_t::debug_line_size + * the size of ".debug_line" + * @var dwarf_sections_t::debug_str_addr + * the virtual address of ".debug_str" after relocation + * @var dwarf_sections_t::debug_str_size + * the size of ".debug_str" + * @var dwarf_sections_t::debug_ranges_addr + * the virtual address of ".debug_ranges" after relocation + * @var dwarf_sections_t::debug_ranges_size + * the size of ".debug_ranges" + */ +struct dwarf_sections_t { + void *debug_info_addr; + uint64_t debug_info_size; + + void *debug_abbrev_addr; + uint64_t debug_abbrev_size; + + void *debug_line_addr; + uint64_t debug_line_size; + + void *debug_str_addr; + uint64_t debug_str_size; + + void *debug_ranges_addr; + uint64_t debug_ranges_size; +}; + +/** + * Get DWARF sections + * + * @expects none + * @ensures ret != nullptr + * + * Returns a list containing pointers to the found DWARF sections. These + * sections are used to map instruction pointers to function names in the + * unwinder. + * + * @return dwarf_sections_t pointer + */ +struct dwarf_sections_t * +get_dwarf_sections() noexcept; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/include/bfehframelist.h b/payloads/bareflank/include/bfehframelist.h new file mode 100644 index 00000000000..5d9be204303 --- /dev/null +++ b/payloads/bareflank/include/bfehframelist.h @@ -0,0 +1,68 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfehframelist.h + */ + +#ifndef BFEHFRAMELIST_H +#define BFEHFRAMELIST_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @struct eh_frame_t + * + * Defines a ".eh_frame" section. + * + * @var eh_frame_t::addr + * the starting address of the the .eh_frame section + * @var eh_frame_t::size + * the size of the .eh_frame section + */ +struct eh_frame_t { + void *addr; + uint64_t size; +}; + +/** + * Get EH Framework List + * + * @expects none + * @ensures ret != nullptr + * + * Returns a list of ".eh_frame" sections, containing their start address, + * and size. This is used by the unwind library to find stack frames. The + * list should have one .eh_frame section for each module that is loaded. + * + * @return eh_frame list (of size MAX_NUM_MODULES) + */ +struct eh_frame_t * +get_eh_frame_list() noexcept; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/include/bfelf_loader.h b/payloads/bareflank/include/bfelf_loader.h new file mode 100644 index 00000000000..7e0113fe540 --- /dev/null +++ b/payloads/bareflank/include/bfelf_loader.h @@ -0,0 +1,2531 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfelf_loader.h + */ + +#ifndef BFELF_LOADER_H +#define BFELF_LOADER_H + +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(push, 1) + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Defines */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +#ifndef BFELF_MAX_NEEDED +#define BFELF_MAX_NEEDED (25) +#endif + +#ifndef BFELF_MAX_SEGMENTS +#define BFELF_MAX_SEGMENTS (4) +#endif + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Data Types */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * Data Representation + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 2 + */ + +/* @cond */ + +#ifndef __cplusplus +typedef uint64_t bfelf64_addr; +typedef uint64_t bfelf64_off; +typedef uint16_t bfelf64_half; +typedef uint32_t bfelf64_word; +typedef int32_t bfelf64_sword; +typedef uint64_t bfelf64_xword; +typedef int64_t bfelf64_sxword; +#else +using bfelf64_addr = uint64_t; +using bfelf64_off = uint64_t; +using bfelf64_half = uint16_t; +using bfelf64_word = uint32_t; +using bfelf64_sword = int32_t; +using bfelf64_xword = uint64_t; +using bfelf64_sxword = int64_t; +#endif + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Error Codes */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline int64_t +private_error(const char *header, const char *msg, const char *func, int line, int64_t code) +{ + BFALERT("%s [%d] %s: %s\n", func, line, header, msg); + return code; +} + +#define bfinvalid_argument(a) \ + private_error("invalid argument", a, __func__, __LINE__, BFELF_ERROR_INVALID_ARG); + +#define bfinvalid_file(a) \ + private_error("invalid file", a, __func__, __LINE__, BFELF_ERROR_INVALID_FILE); + +#define bfinvalid_index(a) \ + private_error("invalid index", a, __func__, __LINE__, BFELF_ERROR_INVALID_INDEX); + +#define bfinvalid_signature(a) \ + private_error("invalid signature", a, __func__, __LINE__, BFELF_ERROR_INVALID_SIGNATURE); + +#define bfunsupported_file(a) \ + private_error("unsupported elf file", a, __func__, __LINE__, BFELF_ERROR_UNSUPPORTED_FILE); + +#define bfloader_full(a) \ + private_error("loader full", a, __func__, __LINE__, BFELF_ERROR_LOADER_FULL); + +#define bfno_such_symbol(a) \ + private_error("no such symbol", a, __func__, __LINE__, BFELF_ERROR_NO_SUCH_SYMBOL); + +#define bfunsupported_rel(a) \ + private_error("unsupported relocation", a, __func__, __LINE__, BFELF_ERROR_UNSUPPORTED_RELA); + +#define bfout_of_memory(a) \ + private_error("out of memory", a, __func__, __LINE__, BFELF_ERROR_OUT_OF_MEMORY); + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Helpers */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline int64_t +private_strcmp(const char *s1, const char *s2) +{ + while ((*s1 != 0) && (*s1 == *s2)) { + s1++, s2++; + } + + return *s1 == *s2 ? BFELF_SUCCESS : BFELF_ERROR_MISMATCH; +} + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF File Definition */ +/* ---------------------------------------------------------------------------------------------- */ + +struct bfelf_dyn; +struct bfelf_sym; +struct bfelf_rela; +struct bfelf_shdr; +struct bfelf_phdr; +struct bfelf_ehdr; + +/** + * @struct bfelf_load_instr + * + * ELF Load Segment + * + * The load instructions that each segment provides is missing some helpful + * info. This structure provides the info that is needed, in a cleaned up + * format. + * + * Note that there are two different char * buffers that you need to know about + * when loading a segment. There is the char * for the ELF file, and the char * + * for the memory that the ELF file is being loaded into. The ELF file does + * not equal memory. The best example is the BSS section, which is empty in the + * ELF file. Also, the RE vs RW sections are usually aligned. To use this + * information use the following steps: + * - get the total size of memory + * - allocate RW memory for the total size + * - get the number of load instructions + * - loop through each load instruction and copy the file char * to the mem + * char * using the file/mem offset/size. + * - map memory using the virt_addr and mem_size + * + * @var bfelf_load_instr::perm + * defines the permissions (read/write/execute) for this segment + * @var bfelf_load_instr::mem_offset + * defines the segment offset in memory + * @var bfelf_load_instr::file_offset + * defines the segment offset in the ELF file + * @var bfelf_load_instr::memsz + * defines the segment size in memory + * @var bfelf_load_instr::filesz + * defines the segment size in the ELF file + * @var bfelf_load_instr::virt_addr + * defines the assumed virtual address of the segment if PIC == false + */ +struct bfelf_load_instr { + bfelf64_word perm; + bfelf64_off mem_offset; + bfelf64_off file_offset; + bfelf64_xword memsz; + bfelf64_xword filesz; + bfelf64_addr virt_addr; +}; + +/* + * ELF File + * + * The following is used by this API to store information about the ELF file + * being used. + * + * @cond + */ +struct bfelf_file_t { + uint64_t filesz; + const char *file; + + char *exec_addr; + char *exec_virt; + + bfelf64_off entry; + + bfelf64_xword num_load_instr; + struct bfelf_load_instr load_instr[BFELF_MAX_SEGMENTS]; + + bfelf64_xword num_loadable_segments; + const struct bfelf_phdr *loadable_segments[BFELF_MAX_SEGMENTS]; + + bfelf64_addr start_addr; + bfelf64_xword total_memsz; + + bfelf64_xword num_needed; + bfelf64_xword needed[BFELF_MAX_NEEDED]; + + const struct bfelf_ehdr *ehdr; + const struct bfelf_phdr *phdrtab; + const struct bfelf_shdr *shdrtab; + + bfelf64_addr dynoff; + + const char *strtab; + const char *strtab_offset; + const char *shstrtab; + + bfelf64_word nbucket; + bfelf64_word nchain; + const bfelf64_word *bucket; + const bfelf64_word *chain; + const bfelf64_word *hash; + + bfelf64_xword dynnum; + const struct bfelf_dyn *dyntab; + + bfelf64_xword symnum; + const struct bfelf_sym *symtab; + + bfelf64_xword relanum_dyn; + const struct bfelf_rela *relatab_dyn; + + bfelf64_xword relanum_plt; + const struct bfelf_rela *relatab_plt; + + bfelf64_addr init; + bfelf64_addr fini; + + bfelf64_addr init_array; + bfelf64_xword init_arraysz; + + bfelf64_addr fini_array; + bfelf64_xword fini_arraysz; + + bfelf64_addr eh_frame; + bfelf64_xword eh_framesz; + + bfelf64_xword flags_1; + bfelf64_xword stack_flags; + + bfelf64_addr relaro_vaddr; + bfelf64_xword relaro_memsz; + + bfelf64_word added; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF File Header */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * e_ident indexes + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 3 + * + * @cond + */ +#define bfei_mag0 bfscast(bfelf64_sword, 0) +#define bfei_mag1 bfscast(bfelf64_sword, 1) +#define bfei_mag2 bfscast(bfelf64_sword, 2) +#define bfei_mag3 bfscast(bfelf64_sword, 3) +#define bfei_class bfscast(bfelf64_sword, 4) +#define bfei_data bfscast(bfelf64_sword, 5) +#define bfei_version bfscast(bfelf64_sword, 6) +#define bfei_osabi bfscast(bfelf64_sword, 7) +#define bfei_abiversion bfscast(bfelf64_sword, 8) +#define bfei_pad bfscast(bfelf64_sword, 9) +#define bfei_nident bfscast(bfelf64_sword, 16) + +/* @endcond */ + +/* + * ELF Class Types + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 5 + * + * @cond + */ +#define bfelfclass32 bfscast(unsigned char, 1) +#define bfelfclass64 bfscast(unsigned char, 2) + +/* @endcond */ + +/* + * ELF Data Types + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 5 + * + * @cond + */ +#define bfelfdata2lsb bfscast(unsigned char, 1) +#define bfelfdata2msb bfscast(unsigned char, 2) + +/* @endcond */ + +/* + * ELF Version + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 4 + * + * @cond + */ +#define bfev_current bfscast(unsigned char, 1) + +/* @endcond */ + +/* + * ELF OS / ABI Types + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 5 + * + * @cond + */ +#define bfelfosabi_sysv bfscast(unsigned char, 0) +#define bfelfosabi_hpux bfscast(unsigned char, 1) +#define bfelfosabi_standalone bfscast(unsigned char, 255) + +/* @endcond */ + +/* + * ELF Types + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 5 + * + * @cond + */ +#define bfet_none bfscast(bfelf64_half, 0) +#define bfet_rel bfscast(bfelf64_half, 1) +#define bfet_exec bfscast(bfelf64_half, 2) +#define bfet_dyn bfscast(bfelf64_half, 3) +#define bfet_core bfscast(bfelf64_half, 4) +#define bfet_loos bfscast(bfelf64_half, 0xFE00) +#define bfet_hios bfscast(bfelf64_half, 0xFEFF) +#define bfet_loproc bfscast(bfelf64_half, 0xFF00) +#define bfet_hiproc bfscast(bfelf64_half, 0xFFFF) + +/* @endcond */ + +/* + * ELF Machine Codes + * + * The following is defined in the Linux kernel sources: + * linux/include/uapi/linux/elf-em.h + * + * @cond + */ +#define bfem_none bfscast(bfelf64_half, 0) +#define bfem_m32 bfscast(bfelf64_half, 1) +#define bfem_sparc bfscast(bfelf64_half, 2) +#define bfem_386 bfscast(bfelf64_half, 3) +#define bfem_68k bfscast(bfelf64_half, 4) +#define bfem_88k bfscast(bfelf64_half, 5) +#define bfem_486 bfscast(bfelf64_half, 6) +#define bfem_860 bfscast(bfelf64_half, 7) +#define bfem_mips bfscast(bfelf64_half, 8) +#define bfem_mips_rs3_le bfscast(bfelf64_half, 10) +#define bfem_mips_rs4_be bfscast(bfelf64_half, 11) +#define bfem_parisc bfscast(bfelf64_half, 15) +#define bfem_sparc32plus bfscast(bfelf64_half, 18) +#define bfem_ppc bfscast(bfelf64_half, 20) +#define bfem_ppc64 bfscast(bfelf64_half, 21) +#define bfem_spu bfscast(bfelf64_half, 23) +#define bfem_arm bfscast(bfelf64_half, 40) +#define bfem_sh bfscast(bfelf64_half, 42) +#define bfem_sparcv9 bfscast(bfelf64_half, 43) +#define bfem_h8_300 bfscast(bfelf64_half, 46) +#define bfem_ia_64 bfscast(bfelf64_half, 50) +#define bfem_x86_64 bfscast(bfelf64_half, 62) +#define bfem_s390 bfscast(bfelf64_half, 22) +#define bfem_cris bfscast(bfelf64_half, 76) +#define bfem_v850 bfscast(bfelf64_half, 87) +#define bfem_m32r bfscast(bfelf64_half, 88) +#define bfem_mn10300 bfscast(bfelf64_half, 89) +#define bfem_openrisc bfscast(bfelf64_half, 92) +#define bfem_blackfin bfscast(bfelf64_half, 106) +#define bfem_altera_nios2 bfscast(bfelf64_half, 113) +#define bfem_ti_c6000 bfscast(bfelf64_half, 140) +#define bfem_aarch64 bfscast(bfelf64_half, 183) +#define bfem_frv bfscast(bfelf64_half, 0x5441) +#define bfem_avr32 bfscast(bfelf64_half, 0x18AD) +#define bfem_alpha bfscast(bfelf64_half, 0x9026) +#define bfem_cygnus_v850 bfscast(bfelf64_half, 0x9080) +#define bfem_cygnus_m32r bfscast(bfelf64_half, 0x9041) +#define bfem_s390_old bfscast(bfelf64_half, 0xA390) +#define bfem_cygnus_mn10300 bfscast(bfelf64_half, 0xBEEF) + +/* @endcond */ + +/* + * ELF File Header + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 3 + * + * The file header is located at the beginning of the file, and is used to + * locate the other parts of the file. + * + * @cond + */ +struct bfelf_ehdr { + unsigned char e_ident[bfei_nident]; + bfelf64_half e_type; + bfelf64_half e_machine; + bfelf64_word e_version; + bfelf64_addr e_entry; + bfelf64_off e_phoff; + bfelf64_off e_shoff; + bfelf64_word e_flags; + bfelf64_half e_ehsize; + bfelf64_half e_phentsize; + bfelf64_half e_phnum; + bfelf64_half e_shentsize; + bfelf64_half e_shnum; + bfelf64_half e_shstrndx; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Section Header Table */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Section Type + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 7 + * + * @cond + */ +#define bfsht_null bfscast(bfelf64_word, 0) +#define bfsht_progbits bfscast(bfelf64_word, 1) +#define bfsht_symtab bfscast(bfelf64_word, 2) +#define bfsht_strtab bfscast(bfelf64_word, 3) +#define bfsht_rela bfscast(bfelf64_word, 4) +#define bfsht_hash bfscast(bfelf64_word, 5) +#define bfsht_dynamic bfscast(bfelf64_word, 6) +#define bfsht_note bfscast(bfelf64_word, 7) +#define bfsht_nobits bfscast(bfelf64_word, 8) +#define bfsht_rel bfscast(bfelf64_word, 9) +#define bfsht_shlib bfscast(bfelf64_word, 10) +#define bfsht_dynsym bfscast(bfelf64_word, 11) +#define bfsht_init_array bfscast(bfelf64_word, 14) +#define bfsht_fini_array bfscast(bfelf64_word, 15) +#define bfsht_loos bfscast(bfelf64_word, 0x60000000) +#define bfsht_hios bfscast(bfelf64_word, 0x6FFFFFFF) +#define bfsht_loproc bfscast(bfelf64_word, 0x70000000) +#define bfsht_x86_64_unwind bfscast(bfelf64_word, 0x70000001) +#define bfsht_hiproc bfscast(bfelf64_word, 0x7FFFFFFF) + +/* @endcond */ + +/* + * ELF Section Attributes + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 8 + * + * @cond + */ +#define bfshf_write bfscast(bfelf64_xword, 0x1) +#define bfshf_alloc bfscast(bfelf64_xword, 0x2) +#define bfshf_execinstr bfscast(bfelf64_xword, 0x4) +#define bfshf_maskos bfscast(bfelf64_xword, 0x0F000000) +#define bfshf_maskproc bfscast(bfelf64_xword, 0xF0000000) +#define bfshf_undocumneted bfscast(bfelf64_xword, 0x00000060) + +#define bfshf_a (bfshf_alloc) +#define bfshf_wa (bfshf_write | bfshf_alloc) +#define bfshf_ai (bfshf_alloc | bfshf_write | bfshf_undocumneted) + +/* @endcond */ + +/* + * ELF Section Header Entry + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 6 + * + * Sections contain all the information in an ELF file, except for the ELF + * header, program header table, and section header table. Sections are + * identified by an index into the section header table. + * + * @cond + */ +struct bfelf_shdr { + bfelf64_word sh_name; + bfelf64_word sh_type; + bfelf64_xword sh_flags; + bfelf64_addr sh_addr; + bfelf64_off sh_offset; + bfelf64_xword sh_size; + bfelf64_word sh_link; + bfelf64_word sh_info; + bfelf64_xword sh_addralign; + bfelf64_xword sh_entsize; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Dynamic Section */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Dynamic Table Entry Tags + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 14 + * + * @cond + */ +#define bfdt_null bfscast(bfelf64_xword, 0) +#define bfdt_needed bfscast(bfelf64_xword, 1) +#define bfdt_pltrelsz bfscast(bfelf64_xword, 2) +#define bfdt_pltgot bfscast(bfelf64_xword, 3) +#define bfdt_hash bfscast(bfelf64_xword, 4) +#define bfdt_strtab bfscast(bfelf64_xword, 5) +#define bfdt_symtab bfscast(bfelf64_xword, 6) +#define bfdt_rela bfscast(bfelf64_xword, 7) +#define bfdt_relasz bfscast(bfelf64_xword, 8) +#define bfdt_relaent bfscast(bfelf64_xword, 9) +#define bfdt_strsz bfscast(bfelf64_xword, 10) +#define bfdt_syment bfscast(bfelf64_xword, 11) +#define bfdt_init bfscast(bfelf64_xword, 12) +#define bfdt_fini bfscast(bfelf64_xword, 13) +#define bfdt_soname bfscast(bfelf64_xword, 14) +#define bfdt_rpath bfscast(bfelf64_xword, 15) +#define bfdt_symbolic bfscast(bfelf64_xword, 16) +#define bfdt_rel bfscast(bfelf64_xword, 17) +#define bfdt_relsz bfscast(bfelf64_xword, 18) +#define bfdt_relent bfscast(bfelf64_xword, 19) +#define bfdt_pltrel bfscast(bfelf64_xword, 20) +#define bfdt_debug bfscast(bfelf64_xword, 21) +#define bfdt_textrel bfscast(bfelf64_xword, 22) +#define bfdt_jmprel bfscast(bfelf64_xword, 23) +#define bfdt_bind_now bfscast(bfelf64_xword, 24) +#define bfdt_init_array bfscast(bfelf64_xword, 25) +#define bfdt_fini_array bfscast(bfelf64_xword, 26) +#define bfdt_init_arraysz bfscast(bfelf64_xword, 27) +#define bfdt_fini_arraysz bfscast(bfelf64_xword, 28) +#define bfdt_loos bfscast(bfelf64_xword, 0x60000000) +#define bfdt_relacount bfscast(bfelf64_xword, 0x6ffffff9) +#define bfdt_relcount bfscast(bfelf64_xword, 0x6ffffffa) +#define bfdt_flags_1 bfscast(bfelf64_xword, 0x6ffffffb) +#define bfdt_hios bfscast(bfelf64_xword, 0x6FFFFFFF) +#define bfdt_loproc bfscast(bfelf64_xword, 0x70000000) +#define bfdt_hiproc bfscast(bfelf64_xword, 0x7FFFFFFF) + +#define bfdf_1_now bfscast(bfelf64_xword, 0x00000001) +#define bfdf_1_global bfscast(bfelf64_xword, 0x00000002) +#define bfdf_1_group bfscast(bfelf64_xword, 0x00000004) +#define bfdf_1_nodelete bfscast(bfelf64_xword, 0x00000008) +#define bfdf_1_loadfltr bfscast(bfelf64_xword, 0x00000010) +#define bfdf_1_initfirst bfscast(bfelf64_xword, 0x00000020) +#define bfdf_1_noopen bfscast(bfelf64_xword, 0x00000040) +#define bfdf_1_origin bfscast(bfelf64_xword, 0x00000080) +#define bfdf_1_direct bfscast(bfelf64_xword, 0x00000100) +#define bfdf_1_trans bfscast(bfelf64_xword, 0x00000200) +#define bfdf_1_interpose bfscast(bfelf64_xword, 0x00000400) +#define bfdf_1_nodeflib bfscast(bfelf64_xword, 0x00000800) +#define bfdf_1_nodump bfscast(bfelf64_xword, 0x00001000) +#define bfdf_1_confalt bfscast(bfelf64_xword, 0x00002000) +#define bfdf_1_endfiltee bfscast(bfelf64_xword, 0x00004000) +#define bfdf_1_dispreldne bfscast(bfelf64_xword, 0x00008000) +#define bfdf_1_disprelpnd bfscast(bfelf64_xword, 0x00010000) +#define bfdf_1_nodirect bfscast(bfelf64_xword, 0x00020000) +#define bfdf_1_ignmuldef bfscast(bfelf64_xword, 0x00040000) +#define bfdf_1_noksyms bfscast(bfelf64_xword, 0x00080000) +#define bfdf_1_nohdr bfscast(bfelf64_xword, 0x00100000) +#define bfdf_1_edited bfscast(bfelf64_xword, 0x00200000) +#define bfdf_1_noreloc bfscast(bfelf64_xword, 0x00400000) +#define bfdf_1_symintpose bfscast(bfelf64_xword, 0x00800000) +#define bfdf_1_globaudit bfscast(bfelf64_xword, 0x01000000) +#define bfdf_1_singleton bfscast(bfelf64_xword, 0x02000000) +#define bfdf_1_pie bfscast(bfelf64_xword, 0x08000000) + +/* @endcond */ + +/* + * ELF Dynamic Table + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 14 + * + * NOTE: The spec actually uses a union, but the use of a union goes against + * the C++ Core Guidelines, and Windows seems to get really mad. There really + * is not need for a union since the type size if the same. For this reason, + * we simply use d_val and cast when needed. + * + * @cond + */ +struct bfelf_dyn { + bfelf64_sxword d_tag; + bfelf64_xword d_val; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Symbol Table */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Symbol Bindings + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 10 + * + * @cond + */ +#define bfstb_local bfscast(unsigned char, 0) +#define bfstb_global bfscast(unsigned char, 1) +#define bfstb_weak bfscast(unsigned char, 2) +#define bfstb_loos bfscast(unsigned char, 10) +#define bfstb_hios bfscast(unsigned char, 12) +#define bfstb_loproc bfscast(unsigned char, 13) +#define bfstb_hiproc bfscast(unsigned char, 15) + +/* @endcond */ + +/* + * ELF Symbol Types + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 10 + * + * @cond + */ +#define bfstt_notype bfscast(unsigned char, 0) +#define bfstt_object bfscast(unsigned char, 1) +#define bfstt_func bfscast(unsigned char, 2) +#define bfstt_section bfscast(unsigned char, 3) +#define bfstt_file bfscast(unsigned char, 4) +#define bfstt_loos bfscast(unsigned char, 10) +#define bfstt_hios bfscast(unsigned char, 12) +#define bfstt_loproc bfscast(unsigned char, 13) +#define bfstt_hiproc bfscast(unsigned char, 15) + +/* @endcond */ + +/* + * ELF Symbol Info Algorithms + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 11 + * + * @cond + */ +#define BFELF_SYM_BIND(x) ((x) >> 4) +#define BFELF_SYM_TYPE(x) ((x)&0xF) + +/* @endcond */ + +/* + * ELF Undefined Symbol Index + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 9 + * + * @cond + */ +#define STN_UNDEF 0 + +/* @endcond */ + +/* + * ELF Symbol + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 9 + * + * @cond + */ +struct bfelf_sym { + bfelf64_word st_name; + unsigned char st_info; + unsigned char st_other; + bfelf64_half st_shndx; + bfelf64_addr st_value; + bfelf64_xword st_size; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Relocations */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Relocation + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 11 + * + * @cond + */ +struct bfelf_rel { + bfelf64_addr r_offset; + bfelf64_xword r_info; +}; + +/* @endcond */ + +/* + * ELF Relocation Addend + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 11 + * + * @cond + */ +struct bfelf_rela { + bfelf64_addr r_offset; + bfelf64_xword r_info; + bfelf64_sxword r_addend; +}; + +/* @endcond */ + +/* + * ELF Relocation Info Algorithms + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 11 + * + * @cond + */ +#define BFELF_REL_SYM(i) ((i) >> 32) +#define BFELF_REL_TYPE(i) ((i)&0xFFFFFFFFL) + +/* @endcond */ + + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Program Header */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Section Attributes + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 12 + * + * @cond + */ +#define bfpt_null bfscast(bfelf64_word, 0) +#define bfpt_load bfscast(bfelf64_word, 1) +#define bfpt_dynamic bfscast(bfelf64_word, 2) +#define bfpt_interp bfscast(bfelf64_word, 3) +#define bfpt_note bfscast(bfelf64_word, 4) +#define bfpt_shlib bfscast(bfelf64_word, 5) +#define bfpt_phdr bfscast(bfelf64_word, 6) +#define bfpt_loos bfscast(bfelf64_word, 0x60000000) +#define bfpt_gnu_eh_frame bfscast(bfelf64_word, 0x6474e550) +#define bfpt_gnu_stack bfscast(bfelf64_word, 0x6474e551) +#define bfpt_gnu_relro bfscast(bfelf64_word, 0x6474e552) +#define bfpt_hios bfscast(bfelf64_word, 0x6FFFFFFF) +#define bfpt_loproc bfscast(bfelf64_word, 0x70000000) +#define bfpt_hiproc bfscast(bfelf64_word, 0x7FFFFFFF) + +/* @endcond */ + +/* + * ELF Section Attributes + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 13 + * + * @cond + */ +#define bfpf_x bfscast(bfelf64_xword, 0x1) +#define bfpf_w bfscast(bfelf64_xword, 0x2) +#define bfpf_r bfscast(bfelf64_xword, 0x4) +#define bfpf_maskos bfscast(bfelf64_xword, 0x00FF0000) +#define bfpf_maskproc bfscast(bfelf64_xword, 0xFF000000) + +/* @endcond */ + +/* + * ELF Program Header Entry + * + * The following is defined in the ELF 64bit file format specification: + * http://www.uclibc.org/docs/elf-64-gen.pdf, page 12 + * + * In executable and shared object files, sections are grouped into segments for + * loading. The program header table contains a list of entries describing + * each segment. This information is needed when using the ELF loader to + * load each segment into memory allocated by the user. For more information + * on how to do this, please see the unit tests. + * + * @cond + */ +struct bfelf_phdr { + bfelf64_word p_type; + bfelf64_word p_flags; + bfelf64_off p_offset; + bfelf64_addr p_vaddr; + bfelf64_addr p_paddr; + bfelf64_xword p_filesz; + bfelf64_xword p_memsz; + bfelf64_xword p_align; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Loader Definition */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * ELF Loader + * + * The following structure is used to create an ELF loader, which groups up + * all of the ELF files used by a single program, mainly needed for global + * symbol searching. + * + * @cond + */ +struct bfelf_loader_t { + bfelf64_word num; + bfelf64_word relocated; + struct bfelf_file_t *efs[MAX_NUM_MODULES]; +}; + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Symbol Table Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline unsigned long +private_hash(const char *name) +{ + unsigned long h = 0; + + while (*name != 0) { + char c = *name++; + unsigned long g; + unsigned char uc = bfscast(unsigned char, c); + + if (c >= 0) { + h = (h << 4) + uc; + } + else { + h = (h << 4) - uc; + } + + if ((g = (h & 0xf0000000)) != 0) { + h ^= g >> 24; + } + + h &= 0x0fffffff; + } + + return h; +} + +static inline int64_t +private_get_sym_by_hash( + struct bfelf_file_t *ef, const char *name, const struct bfelf_sym **sym) +{ + bfelf64_word i = 0; + unsigned long x = private_hash(name); + + i = ef->bucket[x % ef->nbucket]; + while (i > STN_UNDEF && i < ef->nchain) { + int64_t ret = 0; + const char *str = nullptr; + + *sym = &(ef->symtab[i]); + str = &(ef->strtab[(*sym)->st_name]); + + ret = private_strcmp(name, str); + if (ret == BFELF_ERROR_MISMATCH) { + i = ef->chain[i]; + continue; + } + + return BFELF_SUCCESS; + } + + return BFELF_ERROR_NO_SUCH_SYMBOL; +} + +static inline int64_t +private_get_sym_by_name( + struct bfelf_file_t *ef, const char *name, const struct bfelf_sym **sym) +{ + bfelf64_word i = 0; + + if (ef->hash != nullptr) { + return private_get_sym_by_hash(ef, name, sym); + } + + for (i = 0; i < ef->symnum; i++) { + int64_t ret = 0; + const char *str = nullptr; + + *sym = &(ef->symtab[i]); + str = &(ef->strtab[(*sym)->st_name]); + + ret = private_strcmp(name, str); + if (ret == BFELF_ERROR_MISMATCH) { + continue; + } + + return BFELF_SUCCESS; + } + + return BFELF_ERROR_NO_SUCH_SYMBOL; +} + +static inline int64_t +private_get_sym_global( + const struct bfelf_loader_t *loader, const char *name, + struct bfelf_file_t **ef_found, const struct bfelf_sym **sym) +{ + int64_t ret = 0; + bfelf64_word i = 0; + struct bfelf_file_t *ef_ignore = *ef_found; + const struct bfelf_sym *found_sym = nullptr; + + *sym = nullptr; + *ef_found = nullptr; + + for (i = 0; i < loader->num; i++) { + if (loader->efs[i] == ef_ignore) { + continue; + } + + ret = private_get_sym_by_name(loader->efs[i], name, &found_sym); + if (ret == BFELF_ERROR_NO_SUCH_SYMBOL) { + continue; + } + + if (found_sym->st_value == 0) { + continue; + } + + *sym = found_sym; + *ef_found = loader->efs[i]; + + if (BFELF_SYM_BIND(found_sym->st_info) == bfstb_weak) { + continue; + } + + return BFELF_SUCCESS; + } + + if (*sym != nullptr) { + return BFELF_SUCCESS; + } + + return bfno_such_symbol(name); +} + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Relocations Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/* + * Forward declarations required by relocator + * + * @cond + */ + +static inline int64_t +private_get_sym_global( + const struct bfelf_loader_t *loader, const char *name, + struct bfelf_file_t **ef_found, const struct bfelf_sym **sym); + +/* @endcond */ + +/* + * Relocation definitions and relocators + * + * @cond + */ + +#if defined(BF_AARCH64) +# include +#elif defined(BF_X64) +# include +#else +# error "Unsupported architecture" +#endif + +/* @endcond */ + +/* @cond */ + +static inline int64_t +private_relocate_symbols(struct bfelf_loader_t *loader, struct bfelf_file_t *ef) +{ + int64_t ret = 0; + bfelf64_word i = 0; + + for (i = 0; i < ef->relanum_dyn; i++) { + const struct bfelf_rela *rela = &(ef->relatab_dyn[i]); + + ret = private_relocate_symbol(loader, ef, rela); + if (ret != BFELF_SUCCESS) { + return ret; + } + } + + for (i = 0; i < ef->relanum_plt; i++) { + const struct bfelf_rela *rela = &(ef->relatab_plt[i]); + + ret = private_relocate_symbol(loader, ef, rela); + if (ret != BFELF_SUCCESS) { + return ret; + } + } + + return BFELF_SUCCESS; +} + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF File Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline int64_t +private_check_signature(struct bfelf_file_t *ef) +{ + if (ef->ehdr->e_ident[bfei_mag0] != 0x7F) { + return bfinvalid_signature("magic #0 has unexpected value"); + } + + if (ef->ehdr->e_ident[bfei_mag1] != 'E') { + return bfinvalid_signature("magic #1 has unexpected value"); + } + + if (ef->ehdr->e_ident[bfei_mag2] != 'L') { + return bfinvalid_signature("magic #2 has unexpected value"); + } + + if (ef->ehdr->e_ident[bfei_mag3] != 'F') { + return bfinvalid_signature("magic #3 has unexpected value"); + } + + return BFELF_SUCCESS; +} + +static inline int64_t +private_check_support(struct bfelf_file_t *ef) +{ + if (ef->ehdr->e_ident[bfei_class] != bfelfclass64) { + return bfunsupported_file("file is not 64bit"); + } + + if (ef->ehdr->e_ident[bfei_data] != bfelfdata2lsb) { + return bfunsupported_file("file is not little endian"); + } + + if (ef->ehdr->e_ident[bfei_version] != bfev_current) { + return bfunsupported_file("unsupported version"); + } + + if (ef->ehdr->e_ident[bfei_osabi] != bfelfosabi_sysv) { + return bfunsupported_file("file does not use the system v abi"); + } + + if (ef->ehdr->e_ident[bfei_abiversion] != 0) { + return bfunsupported_file("unsupported abi version"); + } + + if (ef->ehdr->e_type != bfet_dyn && ef->ehdr->e_type != bfet_exec) { + return bfunsupported_file("file must be an executable or shared library"); + } + +#ifdef BF_AARCH64 + if (ef->ehdr->e_machine != bfem_aarch64) { + return bfunsupported_file("file must be compiled for aarch64"); + } +#endif + +#ifdef BF_X64 + if (ef->ehdr->e_machine != bfem_x86_64) { + return bfunsupported_file("file must be compiled for x86_64"); + } +#endif + + if (ef->ehdr->e_version != bfev_current) { + return bfunsupported_file("unsupported version"); + } + + if (ef->ehdr->e_flags != 0) { + return bfunsupported_file("unsupported flags"); + } + + return BFELF_SUCCESS; +} + +static inline void +private_process_segments(struct bfelf_file_t *ef) +{ + bfelf64_xword i = 0; + + for (i = 0; i < ef->ehdr->e_phnum; i++) { + const struct bfelf_phdr *phdr = &(ef->phdrtab[i]); + + switch (phdr->p_type) { + case bfpt_load: + + if (ef->num_loadable_segments < BFELF_MAX_SEGMENTS) { + ef->total_memsz = phdr->p_vaddr + phdr->p_memsz; + ef->loadable_segments[ef->num_loadable_segments++] = phdr; + } + + break; + + case bfpt_dynamic: + ef->dynoff = phdr->p_offset; + ef->dynnum = phdr->p_filesz / sizeof(struct bfelf_dyn); + break; + + case bfpt_gnu_stack: + ef->stack_flags = phdr->p_flags; + break; + + case bfpt_gnu_relro: + ef->relaro_vaddr = phdr->p_vaddr; + ef->relaro_memsz = phdr->p_memsz; + break; + } + } + + if (ef->num_loadable_segments > 0) { + ef->start_addr = ef->loadable_segments[0]->p_vaddr; + ef->total_memsz -= ef->start_addr; + } + + for (i = 0; i < ef->num_loadable_segments; i++) { + const struct bfelf_phdr *phdr = ef->loadable_segments[i]; + + ef->load_instr[i].perm = phdr->p_flags; + ef->load_instr[i].mem_offset = phdr->p_vaddr - ef->start_addr; + ef->load_instr[i].file_offset = phdr->p_offset; + ef->load_instr[i].memsz = phdr->p_memsz; + ef->load_instr[i].filesz = phdr->p_filesz; + ef->load_instr[i].virt_addr = phdr->p_vaddr; + + ef->num_load_instr++; + } +} + +static inline void +private_process_dynamic_section(struct bfelf_file_t *ef) +{ + bfelf64_xword i = 0; + + if (ef->dynnum == 0 || ef->dynoff == 0) { + return; + } + + ef->num_needed = 0; + ef->dyntab = bfrcast(const struct bfelf_dyn *, ef->file + ef->dynoff); + + for (i = 0; i < ef->dynnum; i++) { + const struct bfelf_dyn *dyn = &(ef->dyntab[i]); + + switch (dyn->d_tag) { + case bfdt_null: + return; + + case bfdt_needed: + + if (ef->num_needed < BFELF_MAX_NEEDED) { + ef->needed[ef->num_needed++] = dyn->d_val; + } + + break; + + case bfdt_pltrelsz: + ef->relanum_plt = dyn->d_val / sizeof(struct bfelf_rela); + break; + + case bfdt_hash: + ef->hash = bfrcast(bfelf64_word *, dyn->d_val); + break; + + case bfdt_strtab: + ef->strtab_offset = bfrcast(char *, dyn->d_val); + break; + + case bfdt_symtab: + ef->symtab = bfrcast(struct bfelf_sym *, dyn->d_val); + break; + + case bfdt_rela: + ef->relatab_dyn = bfrcast(struct bfelf_rela *, dyn->d_val); + break; + + case bfdt_relasz: + ef->relanum_dyn = dyn->d_val / sizeof(struct bfelf_rela); + break; + + case bfdt_init: + ef->init = dyn->d_val; + break; + + case bfdt_fini: + ef->fini = dyn->d_val; + break; + + case bfdt_jmprel: + ef->relatab_plt = bfrcast(struct bfelf_rela *, dyn->d_val); + break; + + case bfdt_init_array: + ef->init_array = dyn->d_val; + break; + + case bfdt_fini_array: + ef->fini_array = dyn->d_val; + break; + + case bfdt_init_arraysz: + ef->init_arraysz = dyn->d_val; + break; + + case bfdt_fini_arraysz: + ef->fini_arraysz = dyn->d_val; + break; + + case bfdt_flags_1: + ef->flags_1 = dyn->d_val; + break; + + default: + break; + } + } +} + +/* @endcond */ + +/** + * Initialize an ELF file + * + * This function initializes an ELF file structure given the file's contents + * in memory. The resulting structure will be used by all of the other + * functions. + * + * @expects file != nullptr + * @expects filesz != nullptr + * @expects ef != nullptr + * @ensures + * + * @param file a character buffer containing the contents of the ELF file to + * be loaded. + * @param filesz the size of the character buffer + * @param ef the ELF file structure to initialize. + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_init(const char *file, uint64_t filesz, struct bfelf_file_t *ef) +{ + int64_t ret = 0; + bfelf64_word i = 0; + + if (file == nullptr) { + return bfinvalid_argument("file == nullptr"); + } + + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (filesz < sizeof(struct bfelf_ehdr)) { + return bfinvalid_argument("filesz invalid"); + } + + ef->file = file; + ef->filesz = filesz; + + ef->ehdr = bfrcast(const struct bfelf_ehdr *, file); + ef->phdrtab = bfrcast(const struct bfelf_phdr *, file + ef->ehdr->e_phoff); + ef->shdrtab = bfrcast(const struct bfelf_shdr *, file + ef->ehdr->e_shoff); + + ret = private_check_signature(ef); + if (ret != BFELF_SUCCESS) { + return ret; + } + + ret = private_check_support(ef); + if (ret != BFELF_SUCCESS) { + return ret; + } + + private_process_segments(ef); + private_process_dynamic_section(ef); + + ef->entry = ef->ehdr->e_entry; + ef->shstrtab = bfrcast(const char *, file + ef->shdrtab[ef->ehdr->e_shstrndx].sh_offset); + + /* + * ld from binutils 2.27 only has rela.dyn, while ld.gold and ld.lld both + * have rela.dyn and rela.plt. ld from binutils 2.27 also uses + * .init_array / .fini_array instead of .ctors / .dtors, while ld.gold and + * ld.lld still use the old .ctors / .dtors, which do not seems to show + * up in the .dynamic section, so we need to manually search for them. + * Since you will likely only have one or the other, if we see the old + * .ctors / .dtors, we treat it like .init_array / .fini_array for now + * which keeps things simple. Also, ld from binutils 2.27 marks .eh_frame + * with bfsht_x86_64_unwind, while ld.gold and ld.lld both mark .eh_frame + * with bfsht_progbits, also requiring a manual string search. + * + * Note that the file provided in this function is assumed to be deleted + * after this function is called, and thus, we have to search for these + * sections now because the file will not be available later. + */ + + for (i = 0; i < ef->ehdr->e_shnum; i++) { + const struct bfelf_shdr *shdr = &(ef->shdrtab[i]); + const char *name = &ef->shstrtab[shdr->sh_name]; + + if (private_strcmp(name, ".eh_frame") == BFELF_SUCCESS) { + ef->eh_frame = shdr->sh_addr; + ef->eh_framesz = shdr->sh_size; + continue; + } + + if (private_strcmp(name, ".ctors") == BFELF_SUCCESS) { + ef->init_array = shdr->sh_addr; + ef->init_arraysz = shdr->sh_size; + continue; + } + + if (private_strcmp(name, ".dtors") == BFELF_SUCCESS) { + ef->fini_array = shdr->sh_addr; + ef->fini_arraysz = shdr->sh_size; + continue; + } + } + + /* + * The string table is located in both ELF file provided here, as well as + * in the exec provided to bfelf_loader_add. By the time bfelf_loader_add + * is called, we assume that the file provided to this function has been + * deleted, but up to this point, the user is free to use some of the + * functions (like bfelf_file_get_needed), and for these we need a valid + * string table, so we store the location of the string table relative + * to the provided file, and then overwrite this when the user adds the + * ELF file to the loader, in which case we reference the string table + * relative to the provided exec. + */ + ef->strtab = bfcadd(const char *, ef->strtab_offset, bfrcast(bfelf64_addr, file)); + + return BFELF_SUCCESS; +} + +/** + * Get number of load instructions + * + * Once an ELF file has been initialized, the next step is to load all of the + * program segments into memory, relocate them, and then execute the entry + * point. To assist this operation, this function returns the total number of + * load instructions. + * + * @expects ef != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file + * @return number of load instructions on success, negative on error + */ +static inline int64_t +bfelf_file_get_num_load_instrs(const struct bfelf_file_t *ef) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + return bfscast(int64_t, ef->num_load_instr); +} + +/** + * Get load instructions + * + * Once you know how many load instructions there are, you can use this + * function to get each instruction structure. + * + * @expects ef != nullptr + * @expects index < bfelf_file_get_num_load_instrs() + * @expects instr != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file + * @param index the index of the instructions to get + * @param instr where to store the load instructions + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_get_load_instr( + const struct bfelf_file_t *ef, uint64_t index, const struct bfelf_load_instr **instr) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (instr == nullptr) { + return bfinvalid_argument("phdr == nullptr"); + } + + if (index >= ef->num_load_instr) { + return bfinvalid_index("index >= number of load instructions"); + } + + *instr = &(ef->load_instr[index]); + return BFELF_SUCCESS; +} + +/** + * Get Info + * + * Once an ELF loader has had all of it's ELF files initialized and added, + * use the relocate ELF loader to setup the ELF files such that they can + * be executed. Once this is done, this function can be used to get the + * C runtime information for bootstrapping a binary / module. + * + * @expects ef != nullptr + * @expects info != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the info structure for + * @param info the info structure to store the results. + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_get_section_info( + const struct bfelf_file_t *ef, struct section_info_t *info) +{ + bfelf64_word i = 0; + + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (info == nullptr) { + return bfinvalid_argument("info == nullptr"); + } + + if (ef->added == 0) { + return bfinvalid_argument("ef must be added to a loader first"); + } + + for (i = 0; i < sizeof(struct section_info_t); i++) { + bfrcast(char *, info)[i] = 0; + } + + if (ef->init != 0) { + info->init_addr = ef->init + ef->exec_virt; + } + + if (ef->fini != 0) { + info->fini_addr = ef->fini + ef->exec_virt; + } + + if (ef->init_array != 0) { + info->init_array_addr = ef->init_array + ef->exec_virt; + info->init_array_size = ef->init_arraysz; + } + + if (ef->fini_array != 0) { + info->fini_array_addr = ef->fini_array + ef->exec_virt; + info->fini_array_size = ef->fini_arraysz; + } + + if (ef->eh_frame != 0) { + info->eh_frame_addr = ef->eh_frame + ef->exec_virt; + info->eh_frame_size = ef->eh_framesz; + } + + return BFELF_SUCCESS; +} + +/** + * Get Entry Point + * + * Returns the entry point of the ELF file. + * + * @expects ef != nullptr + * @expects addr != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the entry location from + * @param addr the resulting address of the entry point + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_get_entry(const struct bfelf_file_t *ef, void **addr) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (addr == nullptr) { + return bfinvalid_argument("addr == nullptr"); + } + + if (ef->added == 0) { + return bfinvalid_argument("ef must be added to a loader first"); + } + + *addr = bfrcast(void *, ef->entry + ef->exec_virt); + return BFELF_SUCCESS; +} + +/** + * Get Stack Permissions + * + * Returns the ELF file's stack permissions. + * + * @expects ef != nullptr + * @expects perm != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the stack permission info from + * @param perm the resulting permissions + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_get_stack_perm(const struct bfelf_file_t *ef, bfelf64_xword *perm) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (perm == nullptr) { + return bfinvalid_argument("perm == nullptr"); + } + + *perm = ef->stack_flags; + return BFELF_SUCCESS; +} + +/** + * Get Relocation Read-Only Info + * + * Returns the ELF file's RELRO information for + * re-mapping previously writable memory to read-only + * + * @expects ef != nullptr + * @expects addr != nullptr + * @expects size != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the relro info from + * @param addr the resulting address + * @param size the resulting size + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_file_get_relro( + const struct bfelf_file_t *ef, bfelf64_addr *addr, bfelf64_xword *size) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (addr == nullptr) { + return bfinvalid_argument("addr == nullptr"); + } + + if (size == nullptr) { + return bfinvalid_argument("size == nullptr"); + } + + if (ef->added == 0) { + return bfinvalid_argument("ef must be added to a loader first"); + } + + *addr = ef->relaro_vaddr + bfrcast(bfelf64_addr, ef->exec_virt); + *size = ef->relaro_memsz; + return BFELF_SUCCESS; +} + +/** + * Get Number of Needed Libraries + * + * Returns the number of DT_NEEDED entries in the ELF + * file + * + * @expects ef != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the number of needed files from + * @return number of needed entries on success, negative on error + */ +static inline int64_t +bfelf_file_get_num_needed(const struct bfelf_file_t *ef) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + return bfscast(int64_t, ef->num_needed); +} + +/** + * Get Needed Library + * + * Returns the name of a shared library that is needed by this + * ELF file + * + * @expects ef != nullptr + * @expects index < bfelf_file_get_num_needed() + * @expects needed != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the needed filename from + * @param index the shared library name to get + * @param needed the resulting needed library + * @return number of needed entries on success, negative on error + */ +static inline int64_t +bfelf_file_get_needed( + const struct bfelf_file_t *ef, uint64_t index, const char **needed) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (needed == nullptr) { + return bfinvalid_argument("needed == nullptr"); + } + + if (index >= ef->num_needed) { + return bfinvalid_index("index >= number of needed"); + } + + *needed = &(ef->strtab[ef->needed[index]]); + return BFELF_SUCCESS; +} + +/** + * Get Total Memory Size + * + * Returns the total number of bytes needed in memory for this ELF file + * when loading the ELF file + * + * @expects ef != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the total size from + * @return number of needed entries on success, negative on error + */ +static inline int64_t +bfelf_file_get_total_size(const struct bfelf_file_t *ef) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + return bfscast(int64_t, ef->total_memsz); +} + +/** + * Get PIC/PIE + * + * Returns 1 if this ELF file was compiled using PIC / PIE, or + * 0 otherwise + * + * @expects ef != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param ef the ELF file to get the pic/pie info from + * @return 1 if compiled with PIC/PIE, 0 otherwise + */ +static inline int64_t +bfelf_file_get_pic_pie(const struct bfelf_file_t *ef) +{ + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + return ef->start_addr == 0 ? 1 : 0; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Loader Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/** + * Add ELF file to an ELF loader + * + * Once an ELF loader has been initialized, use this function to add an + * ELF file to the ELF loader + * + * @expects loader != nullptr + * @expects ef != nullptr + * @expects exec_addr != nullptr + * @expects exec_virt != nullptr + * @ensures + * + * @param loader the ELF loader + * @param ef the ELF file to add + * @param exec_addr the address in memory where this ELF file was loaded. + * @param exec_virt the address in memory where this ELF file will be run. + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_loader_add( + struct bfelf_loader_t *loader, struct bfelf_file_t *ef, char *exec_addr, char *exec_virt) +{ + bfelf64_addr start; + + if (loader == nullptr) { + return bfinvalid_argument("loader == nullptr"); + } + + if (ef == nullptr) { + return bfinvalid_argument("ef == nullptr"); + } + + if (exec_addr == nullptr) { + return bfinvalid_argument("exec_addr == nullptr"); + } + + if (loader->num >= MAX_NUM_MODULES) { + return bfloader_full("increase MAX_NUM_MODULES"); + } + + if (ef->added++ != 0) { + return bfinvalid_argument("ef already added"); + } + + ef->exec_addr = exec_addr; + + if (ef->start_addr == 0) { + ef->exec_virt = exec_virt; + } + + start = bfrcast(bfelf64_addr, ef->exec_addr - ef->start_addr); + + ef->hash = bfcadd(const bfelf64_word *, ef->hash, start); + ef->strtab = bfcadd(const char *, ef->strtab_offset, start); + ef->symtab = bfcadd(const struct bfelf_sym *, ef->symtab, start); + ef->relatab_dyn = bfcadd(const struct bfelf_rela *, ef->relatab_dyn, start); + ef->relatab_plt = bfcadd(const struct bfelf_rela *, ef->relatab_plt, start); + + ef->nbucket = ef->hash[0]; + ef->nchain = ef->hash[1]; + ef->bucket = &(ef->hash[2]); + ef->chain = &(ef->hash[2 + ef->nbucket]); + + /* + * Sadly, the only way to determine the total size of the dynamic symbol + * table is to assume that the dynamic string table is always after the + * dynamic symbol table. :( + */ + ef->symnum = (bfrcast(bfelf64_addr, ef->strtab) - bfrcast(bfelf64_addr, ef->symtab)) / + sizeof(struct bfelf_sym); + + loader->efs[loader->num++] = ef; + return BFELF_SUCCESS; +} + +/** + * Relocate ELF Loader + * + * Relocates all of the ELF files that have been added to the ELF loader. + * Once all of the ELF files have been relocated, it's safe to resolve + * symbols for execution. + * + * @expects loader != nullptr + * @ensures + * + * @param loader the ELF loader + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_loader_relocate(struct bfelf_loader_t *loader) +{ + bfelf64_word i = 0; + + if (loader == nullptr) { + return bfinvalid_argument("loader == nullptr"); + } + + if (loader->relocated == 1) { + return BFELF_SUCCESS; + } + + for (i = 0; i < loader->num; i++) { + int64_t ret = private_relocate_symbols(loader, loader->efs[i]); + if (ret != BFELF_SUCCESS) { + return ret; + } + } + + loader->relocated = 1; + return BFELF_SUCCESS; +} + +/** + * Resolve Symbol + * + * Once an ELF loader has had all of it's ELF files initialized and added, + * use the relocate ELF loader to setup the ELF files such that they can + * be executed. If the ELF file is relocated into memory that is accessible + * via the ELF loader, the resolve symbol function can be used to get the + * address of a specific symbol so that it can be executed. + * + * @expects loader != nullptr + * @expects loader != name + * @expects loader != addr + * @ensures + * + * @param loader the ELF loader + * @param name the name of the symbol to resolve + * @param addr the resulting address if the symbol is successfully resolved + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_loader_resolve_symbol( + const struct bfelf_loader_t *loader, const char *name, void **addr) +{ + int64_t ret = 0; + + struct bfelf_file_t *found_ef = nullptr; + const struct bfelf_sym *found_sym = nullptr; + + if (loader == nullptr) { + return bfinvalid_argument("loader == nullptr"); + } + + if (name == nullptr) { + return bfinvalid_argument("name == nullptr"); + } + + if (addr == nullptr) { + return bfinvalid_argument("addr == nullptr"); + } + + ret = private_get_sym_global(loader, name, &found_ef, &found_sym); + if (ret != BFELF_SUCCESS) { + return ret; + } + + *addr = found_ef->exec_virt + found_sym->st_value; + return BFELF_SUCCESS; +} + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Loading APIs */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +struct bfelf_binary_t { + char *exec; + const char *file; + uint64_t exec_size; + uint64_t file_size; + struct bfelf_file_t ef; +}; + +static inline int64_t +private_load_binary(struct bfelf_binary_t *binary) +{ + int64_t i = 0; + int64_t ret = 0; + int64_t num_segments = 0; + + /* + * Note: + * + * This function expects that binary->file and binary->file_size have + * already been filled in before executing this function. It will + * allocate the exec, and then copy each program segment in the provided + * file into the exec + */ + + if (binary->ef.file == nullptr) { + ret = bfelf_file_init(binary->file, binary->file_size, &binary->ef); + if (ret != BF_SUCCESS) { + return ret; + } + } + + num_segments = bfelf_file_get_num_load_instrs(&binary->ef); + binary->exec_size = bfscast(uint64_t, bfelf_file_get_total_size(&binary->ef)); + + /* + * TODO: + * + * Currently we allocate RWE memory instead of W^E. This code is used in + * two different places, the hypervisor and guest applications. In both + * cases this memory is changed to W^E by either the hypervisor's memory + * manager, or by a set of hypercalls. The only time the memory is actually + * used as RWE is during the initialization of the hypervisor, and not it's + * normal operation. + * + * Since this has to be cross platform, most operating systems support some + * form of RWE so this is what we use today. The risk for attack is limited + * to the initialization of the hypervisor which in most cases will be + * performed by a root-of-trust, so the attack surface is low. Still, + * someday it would be nice to find an mprotect like function for all + * operating systems such that memory can be allocated RW, and changed + * to RE as needed. If this functionality is found, the code here will have + * to be changed to support this. + */ + + binary->exec = bfscast(char *, platform_alloc_rwe(binary->exec_size)); + if (binary->exec == nullptr) { + return bfout_of_memory("unable to allocate exec RWE memory"); + } + + platform_memset(binary->exec, 0, binary->exec_size); + + for (i = 0; i < num_segments; i++) { + const struct bfelf_load_instr *instr = nullptr; + + const char *src = nullptr; + char *dst = nullptr; + + ret = bfelf_file_get_load_instr(&binary->ef, bfscast(uint64_t, i), &instr); + bfignored(ret); + + if (instr != nullptr) { + dst = bfadd(char *, binary->exec, instr->mem_offset); + src = bfcadd(const char *, binary->file, instr->file_offset); + + platform_memcpy(dst, src, instr->filesz); + } + } + + return BF_SUCCESS; +} + +static inline int64_t +private_relocate_binaries( + struct bfelf_binary_t *binaries, uint64_t num_binaries, struct bfelf_loader_t *loader) +{ + uint64_t i = 0; + int64_t ret = 0; + + for (i = 0; i < num_binaries; i++) { + ret = bfelf_loader_add(loader, &binaries[i].ef, binaries[i].exec, binaries[i].exec); + bfignored(ret); + } + + ret = bfelf_loader_relocate(loader); + if (ret != BFELF_SUCCESS) { + return ret; + } + + return BF_SUCCESS; +} + +static inline int64_t +private_crt_info( + struct bfelf_binary_t *binaries, uint64_t num_binaries, struct crt_info_t *crt_info) +{ + uint64_t i = 0; + + for (i = 0; i < num_binaries; i++) { + + int64_t ret = 0; + struct section_info_t section_info; + + ret = bfelf_file_get_section_info(&binaries[i].ef, §ion_info); + bfignored(ret); + + crt_info->info[crt_info->info_num++] = section_info; + } + + return BF_SUCCESS; +} + +/* @endcond */ + +/** + * Load + * + * Takes an array of ELF binaries and loads them. The resulting output is an + * entry point that can be executed. The CRT info and the ELF loader are also + * provided as a result. + * + * @note This function gets the entry point of the last binary provided. + * For this reason, the main executable should ALWAYS be last in the list + * of ELF binaries provided + * + * @note It is assumed that file and file_size are already provided for each + * ELF binary. This function will loop through each binary, and use this + * information to actually load everything into ELF file specific + * structures. + * + * @expects binaries != null + * @expects num_binaries != 0 && num_binaries < MAX_NUM_MODULES + * @expects entry != null + * @expects crt_info != null + * @expects loader != null + * @ensures none + * + * @param binaries the list of ELF binaries to load + * @param num_binaries the number of binaries provided + * @param entry the resulting entry point + * @param crt_info the resulting CRT info + * @param loader the resulting ELF loader + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_load( + struct bfelf_binary_t *binaries, uint64_t num_binaries, void **entry, + struct crt_info_t *crt_info, struct bfelf_loader_t *loader) +{ + uint64_t i = 0; + int64_t ret = 0; + + if (binaries == nullptr) { + return bfinvalid_argument("binaries == nullptr"); + } + + if (num_binaries == 0 || num_binaries >= MAX_NUM_MODULES) { + return bfinvalid_argument("num_binaries == 0 || num_binaries >= MAX_NUM_MODULES"); + } + + if (entry == nullptr) { + return bfinvalid_argument("entry == nullptr"); + } + + if (crt_info == nullptr) { + return bfinvalid_argument("crt_info == nullptr"); + } + + if (loader == nullptr) { + return bfinvalid_argument("loader == nullptr"); + } + + for (i = 0; i < num_binaries; i++) { + ret = private_load_binary(&binaries[i]); + if (ret != BF_SUCCESS) { + return ret; + } + } + + ret = private_relocate_binaries(binaries, num_binaries, loader); + if (ret != BF_SUCCESS) { + return ret; + } + + ret = private_crt_info(binaries, num_binaries, crt_info); + bfignored(ret); + + ret = bfelf_file_get_entry(&binaries[num_binaries - 1].ef, entry); + bfignored(ret); + + return BF_SUCCESS; +} + +/** + * Set Args + * + * Tells the CRT info to use the standard main(arc, argv) function, and sets + * the values of these. This information will be passed to the resulting + * entry point + * + * @expects crt_info != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param crt_info the CRT info to fill where the args will be stored + * @param argc the total number of args + * @param argv the args + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_set_args(struct crt_info_t *crt_info, int argc, const char **argv) +{ + if (crt_info == nullptr) { + return bfinvalid_argument("crt_info == nullptr"); + } + + crt_info->argc = argc; + crt_info->argv = argv; + crt_info->arg_type = 0; + + return BF_SUCCESS; +} + +/** + * Set Integer Args + * + * There are two different types of main functions supported: the standard + * main(arc, argv) and then another form that uses 64bit integers in the + * form int64_t bfmain(int64_t, int64_t, int64_t, int64_t). This function tells + * the CRT info to use the integer version, and sets the values of these. + * This information will be passed to the resulting entry point + * + * @expects crt_info != nullptr + * @ensures returns BFELF_SUCCESS if params == valid + * + * @param crt_info the CRT info to fill where the args will be stored + * @param request the request id + * @param arg1 integer arg #1 + * @param arg2 integer arg #2 + * @param arg3 integer arg #3 + * @return BFELF_SUCCESS on success, negative on error + */ +static inline int64_t +bfelf_set_integer_args( + struct crt_info_t *crt_info, uintptr_t request, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3) +{ + if (crt_info == nullptr) { + return bfinvalid_argument("crt_info == nullptr"); + } + + crt_info->request = request; + crt_info->arg1 = arg1; + crt_info->arg2 = arg2; + crt_info->arg3 = arg3; + crt_info->arg_type = 1; + + return BF_SUCCESS; +} + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +#include +#include +#include + +#include +#include +#include +#include + +/* @cond */ + +inline auto +private_read_binary( + gsl::not_null f, const std::string &filename, bfelf_binary_t &binary) +{ + auto buffer = f->read_binary(filename); + + binary.file = buffer.get(); + binary.file_size = buffer.size(); + + return buffer; +} + +inline auto +private_get_needed_list(const bfelf_file_t &ef) +{ + int64_t ret = 0; + std::vector list; + + for (auto i = 0LL; i < bfelf_file_get_num_needed(&ef); i++) { + const char *needed = nullptr; + + ret = bfelf_file_get_needed(&ef, static_cast(i), &needed); + bfignored(ret); + + list.emplace_back(needed); + } + + return list; +} + +/* @endcond */ + +/** + * Read Binary and Get Needed List + * + * This function takes a filename, and a list of paths to locate the + * provide file. If the ELF binary is located, the function then parses + * the ELF file and returns the list of binaries that are needed (i.e. + * have to be linked to this ELF binary to resolve needed symbols). If + * the binary cannot be located, an exception is thrown. + * + * @expects none + * @ensures none + * + * @param f the file object to read the located filename + * @param filename the name of the ELF binary to get the needed list from + * @param paths a list of paths to locate the ELF binary from + * @param buffer the buffer to read the ELF binary into + * @param binary the binary object + * @return list of needed binaries or throws + */ +inline auto +bfelf_read_binary_and_get_needed_list( + gsl::not_null f, const std::string &filename, + const std::vector &paths, bfn::buffer &buffer, bfelf_binary_t &binary) +{ + buffer = private_read_binary(f, filename, binary); + + auto ret = bfelf_file_init(buffer.data(), buffer.size(), &binary.ef); + if (ret != BFELF_SUCCESS) { + throw std::runtime_error("bfelf_file_init failed: " + std::to_string(ret)); + } + + auto list = f->find_files(private_get_needed_list(binary.ef), paths); + return list; +} + +/** + * Binaries Info + * + * Provides a C++ wrapper for all of the ELF structures that are needed to + * load an ELF binary. + */ +class binaries_info +{ +public: + + using index_type = std::size_t; ///< Index type + using info_type = crt_info_t; ///< CRT info type + using entry_type = void *; ///< Entry point address type + using loader_type = bfelf_loader_t; ///< ELF loader type + + /** + * Constructor + * + * Loads the file provided, and searches the needed list to identify + * any other files that are needed for symbol resolution. + * + * @expects none + * @ensures none + * + * @param f the file object to read the located filename + * @param filename the name of the ELF binary to load + * @param paths a list of paths to locate the ELF binary from + * @param load if true, loads the binaries + */ + binaries_info( + gsl::not_null f, const std::string &filename, const std::vector &paths, bool load = true) + { + bfn::buffer data; + bfelf_binary_t binary = {}; + + auto filenames = bfelf_read_binary_and_get_needed_list(f, filename, paths, data, binary); + + this->init_binaries(f, filenames); + this->push_binary(std::move(data), std::move(binary)); + + auto ___ = gsl::on_failure([&] { + this->unload_binaries(); + }); + + if (load) { + this->load_binaries(); + } + } + + /** + * Constructor + * + * Loads all of the files provided. This does not search the needed list + * and instead expects that the list of binaries provided is complete. + * + * @expects none + * @ensures none + * + * @param f the file object to read the located filename + * @param filenames the list of files to load + * @param load if true, loads the binaries + */ + binaries_info( + gsl::not_null f, const std::vector &filenames, bool load = true) + { + this->init_binaries(f, filenames); + + auto ___ = gsl::on_failure([&] { + this->unload_binaries(); + }); + + if (load) { + this->load_binaries(); + } + } + + /** + * Default Destructor + */ + ~binaries_info() + { this->unload_binaries(); } + + /** + * Set Args + * + * Sets the argc and argv for this binary. + * + * @expects none + * @ensures none + * + * @param argc the number of arguments to pass to this binary + * @param argv the arguments to pass to this binary + */ + void + set_args(int argc, const char **argv) + { + auto ret = bfelf_set_args(&m_info, argc, argv); + bfignored(ret); + } + + /** + * Get Main ELF Binary + * + * Returns the main ELF binary (i.e. does not return the shared libraries + * needed by the main binary) + * + * @expects none + * @ensures none + * + * @return main binary + */ + auto & + ef() + { return m_binaries.back().ef; } + + /** + * Get Specific ELF Binary + * + * Returns a specific ELF binary given an index + * + * @expects index is valid + * @ensures none + * + * @param index of the ELF binary to get + * @return main binary + */ + auto & + ef(index_type index) + { return m_binaries.at(index).ef; } + + /** + * Get A Specific Binary + * + * @expects none + * @ensures none + * + * @param index of the specific binary to get + * @return returns a specific binary + */ + auto & + at(index_type index) + { return m_binaries.at(index); } + + /** + * Get The First Binary + * + * @expects none + * @ensures none + * + * @return returns the first binary + */ + auto & + front() + { return m_binaries.front(); } + + /** + * Get The Last Binary + * + * @expects none + * @ensures none + * + * @return returns the last binary + */ + auto & + back() + { return m_binaries.back(); } + + /** + * Get Binaries + * + * @expects none + * @ensures none + * + * @return returns the Binaries + */ + auto & + binaries() + { return m_binaries; } + + /** + * Get CRT Info + * + * @expects none + * @ensures none + * + * @return returns CRT info + */ + const auto & + info() const + { return m_info; } + + /** + * Get Entry Point Address + * + * @expects none + * @ensures none + * + * @return returns entry point address + */ + auto + entry() const + { return m_entry; } + + /** + * Get ELF Loader + * + * @expects none + * @ensures none + * + * @return returns the ELF loader + */ + auto & + loader() + { return m_loader; } + +private: + + void + push_binary(bfn::buffer &&data, bfelf_binary_t &&binary) + { + m_datas.push_back(std::move(data)); + m_binaries.push_back(std::move(binary)); + } + + void + init_binaries(gsl::not_null f, const std::vector &filenames) + { + expects(!filenames.empty()); + + for (const auto &filename : filenames) { + bfelf_binary_t binary = {}; + this->push_binary(private_read_binary(f, filename, binary), std::move(binary)); + } + } + + void + load_binaries() + { + auto ret = bfelf_load(m_binaries.data(), m_binaries.size(), &m_entry, &m_info, &m_loader); + if (ret != BF_SUCCESS) { + throw std::runtime_error("bfelf_load failed: " + bfn::to_string(ret, 16)); + } + } + + void + unload_binaries() + { + for (const auto &binary : m_binaries) { + platform_free_rwe(binary.exec, binary.exec_size); + } + } + + info_type m_info{}; + entry_type m_entry{}; + loader_type m_loader{}; + + std::vector m_binaries; + std::vector m_datas; + +public: + + /** @cond */ + + binaries_info(binaries_info &&) noexcept = default; + binaries_info &operator=(binaries_info &&) noexcept = default; + + binaries_info(const binaries_info &) = delete; + binaries_info &operator=(const binaries_info &) = delete; + + /** @endcond */ +}; + +#endif + +#pragma pack(pop) +#endif diff --git a/payloads/bareflank/include/bfelf_loader_reloc_aarch64.h b/payloads/bareflank/include/bfelf_loader_reloc_aarch64.h new file mode 100644 index 00000000000..80155de61cb --- /dev/null +++ b/payloads/bareflank/include/bfelf_loader_reloc_aarch64.h @@ -0,0 +1,263 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2017 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfelf_loader_reloc_aarch64.h + */ + +/* + * AArch64 Relocations + * + * The following is defined in the "ELF for the ARM 64-bit architecture" + * specification: + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0056b/IHI0056B_aaelf64.pdf + * + * @cond + */ + +/* ---------------------------------------------------------------------------------------------- */ +/* Miscellaneous relocations */ +/* ---------------------------------------------------------------------------------------------- */ +#define BFR_AARCH64_NONE bfscast(bfelf64_xword, 0) + +/* ---------------------------------------------------------------------------------------------- */ +/* Static data relocations */ +/* ---------------------------------------------------------------------------------------------- */ +/* Data relocations */ +#define BFR_AARCH64_ABS64 bfscast(bfelf64_xword, 257) +#define BFR_AARCH64_ABS32 bfscast(bfelf64_xword, 258) +#define BFR_AARCH64_ABS16 bfscast(bfelf64_xword, 259) +#define BFR_AARCH64_PREL64 bfscast(bfelf64_xword, 260) +#define BFR_AARCH64_PREL32 bfscast(bfelf64_xword, 261) +#define BFR_AARCH64_PREL16 bfscast(bfelf64_xword, 262) + +/* ---------------------------------------------------------------------------------------------- */ +/* Static AArch64 relocations */ +/* ---------------------------------------------------------------------------------------------- */ +/* Group relocations to create an unsigned data value or address inline */ +#define BFR_AARCH64_MOVW_UABS_G0 bfscast(bfelf64_xword, 263) +#define BFR_AARCH64_MOVW_UABS_G0_NC bfscast(bfelf64_xword, 264) +#define BFR_AARCH64_MOVW_UABS_G1 bfscast(bfelf64_xword, 265) +#define BFR_AARCH64_MOVW_UABS_G1_NC bfscast(bfelf64_xword, 266) +#define BFR_AARCH64_MOVW_UABS_G2 bfscast(bfelf64_xword, 267) +#define BFR_AARCH64_MOVW_UABS_G2_NC bfscast(bfelf64_xword, 268) +#define BFR_AARCH64_MOVW_UABS_G3 bfscast(bfelf64_xword, 269) + +/* Group relocations to create a signed data or offset value inline */ +#define BFR_AARCH64_MOVW_SABS_G0 bfscast(bfelf64_xword, 270) +#define BFR_AARCH64_MOVW_SABS_G1 bfscast(bfelf64_xword, 271) +#define BFR_AARCH64_MOVW_SABS_G2 bfscast(bfelf64_xword, 272) + +/* Relocations to generate PC-relative addresses */ +#define BFR_AARCH64_LD_PREL_LO19 bfscast(bfelf64_xword, 273) +#define BFR_AARCH64_ADR_PREL_LO21 bfscast(bfelf64_xword, 274) +#define BFR_AARCH64_ADR_PREL_PG_HI21 bfscast(bfelf64_xword, 275) +#define BFR_AARCH64_ADR_PREL_PG_HI21_NC bfscast(bfelf64_xword, 276) +#define BFR_AARCH64_ADD_ABS_LO12_NC bfscast(bfelf64_xword, 277) +#define BFR_AARCH64_LDST8_ABS_LO12_NC bfscast(bfelf64_xword, 278) +#define BFR_AARCH64_LDST16_ABS_LO12_NC bfscast(bfelf64_xword, 284) +#define BFR_AARCH64_LDST32_ABS_LO12_NC bfscast(bfelf64_xword, 285) +#define BFR_AARCH64_LDST64_ABS_LO12_NC bfscast(bfelf64_xword, 286) +#define BFR_AARCH64_LDST128_ABS_LO12_NC bfscast(bfelf64_xword, 299) + +/* Relocations for control-flow instructions */ +#define BFR_AARCH64_TSTBR14 bfscast(bfelf64_xword, 279) +#define BFR_AARCH64_CONDBR19 bfscast(bfelf64_xword, 280) +#define BFR_AARCH64_JUMP26 bfscast(bfelf64_xword, 282) +#define BFR_AARCH64_CALL26 bfscast(bfelf64_xword, 283) + +/* Group relocations to create a PC-relative offset inline */ +#define BFR_AARCH64_MOVW_PREL_G0 bfscast(bfelf64_xword, 287) +#define BFR_AARCH64_MOVW_PREL_G0_NC bfscast(bfelf64_xword, 288) +#define BFR_AARCH64_MOVW_PREL_G1 bfscast(bfelf64_xword, 289) +#define BFR_AARCH64_MOVW_PREL_G1_NC bfscast(bfelf64_xword, 290) +#define BFR_AARCH64_MOVW_PREL_G2 bfscast(bfelf64_xword, 291) +#define BFR_AARCH64_MOVW_PREL_G2_NC bfscast(bfelf64_xword, 292) +#define BFR_AARCH64_MOVW_PREL_G3 bfscast(bfelf64_xword, 293) + +/* Group relocations to create a GOT-relative offset inline */ +#define BFR_AARCH64_MOVW_GOTOFF_G0 bfscast(bfelf64_xword, 300) +#define BFR_AARCH64_MOVW_GOTOFF_G0_NC bfscast(bfelf64_xword, 301) +#define BFR_AARCH64_MOVW_GOTOFF_G1 bfscast(bfelf64_xword, 302) +#define BFR_AARCH64_MOVW_GOTOFF_G1_NC bfscast(bfelf64_xword, 303) +#define BFR_AARCH64_MOVW_GOTOFF_G2 bfscast(bfelf64_xword, 304) +#define BFR_AARCH64_MOVW_GOTOFF_G2_NC bfscast(bfelf64_xword, 305) +#define BFR_AARCH64_MOVW_GOTOFF_G3 bfscast(bfelf64_xword, 306) + +/* GOT-relative data relocations */ +#define BFR_AARCH64_GOTREL64 bfscast(bfelf64_xword, 307) +#define BFR_AARCH64_GOTREL32 bfscast(bfelf64_xword, 308) + +/* GOT-relative instruction relocations */ +#define BFR_AARCH64_GOT_LD_PREL19 bfscast(bfelf64_xword, 309) +#define BFR_AARCH64_LD64_GOTOFF_LO15 bfscast(bfelf64_xword, 310) +#define BFR_AARCH64_ADR_GOT_PAGE bfscast(bfelf64_xword, 311) +#define BFR_AARCH64_LD64_GOT_LO12_NC bfscast(bfelf64_xword, 312) +#define BFR_AARCH64_LD64_GOTPAGE_LO15 bfscast(bfelf64_xword, 313) + +/* ---------------------------------------------------------------------------------------------- */ +/* Relocations for thread-local storage */ +/* ---------------------------------------------------------------------------------------------- */ +/* General dynamic TLS relocations */ +#define BFR_AARCH64_TLSGD_ADR_PREL21 bfscast(bfelf64_xword, 512) +#define BFR_AARCH64_TLSGD_ADR_PAGE21 bfscast(bfelf64_xword, 513) +#define BFR_AARCH64_TLSGD_ADD_LO12_NC bfscast(bfelf64_xword, 514) +#define BFR_AARCH64_TLSGD_MOVW_G1 bfscast(bfelf64_xword, 515) +#define BFR_AARCH64_TLSGD_MOVW_G0_NC bfscast(bfelf64_xword, 516) + +/* Local dynamic TLS relocations */ +#define BFR_AARCH64_TLSLD_ADR_PREL21 bfscast(bfelf64_xword, 517) +#define BFR_AARCH64_TLSLD_ADR_PAGE21 bfscast(bfelf64_xword, 518) +#define BFR_AARCH64_TLSLD_ADD_LO12_NC bfscast(bfelf64_xword, 519) +#define BFR_AARCH64_TLSLD_MOVW_G1 bfscast(bfelf64_xword, 520) +#define BFR_AARCH64_TLSLD_MOVW_G0_NC bfscast(bfelf64_xword, 521) +#define BFR_AARCH64_TLSLD_LD_PREL19 bfscast(bfelf64_xword, 522) +#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G2 bfscast(bfelf64_xword, 523) +#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G1 bfscast(bfelf64_xword, 524) +#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G1_NC bfscast(bfelf64_xword, 525) +#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G0 bfscast(bfelf64_xword, 526) +#define BFR_AARCH64_TLSLD_MOVW_DTPREL_G0_NC bfscast(bfelf64_xword, 527) +#define BFR_AARCH64_TLSLD_ADD_DTPREL_HI12 bfscast(bfelf64_xword, 528) +#define BFR_AARCH64_TLSLD_ADD_DTPREL_LO12 bfscast(bfelf64_xword, 529) +#define BFR_AARCH64_TLSLD_ADD_DTPREL_LO12_NC bfscast(bfelf64_xword, 530) +#define BFR_AARCH64_TLSLD_LDST8_DTPREL_LO12 bfscast(bfelf64_xword, 531) +#define BFR_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC bfscast(bfelf64_xword, 532) +#define BFR_AARCH64_TLSLD_LDST16_DTPREL_LO12 bfscast(bfelf64_xword, 533) +#define BFR_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC bfscast(bfelf64_xword, 534) +#define BFR_AARCH64_TLSLD_LDST32_DTPREL_LO12 bfscast(bfelf64_xword, 535) +#define BFR_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC bfscast(bfelf64_xword, 536) +#define BFR_AARCH64_TLSLD_LDST64_DTPREL_LO12 bfscast(bfelf64_xword, 537) +#define BFR_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC bfscast(bfelf64_xword, 538) +#define BFR_AARCH64_TLSLD_LDST128_DTPREL_LO12 bfscast(bfelf64_xword, 572) +#define BFR_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC bfscast(bfelf64_xword, 573) + +/* Initial exec TLS relocations */ +#define BFR_AARCH64_TLSIE_MOVW_GOTTPREP_G1 bfscast(bfelf64_xword, 539) +#define BFR_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC bfscast(bfelf64_xword, 540) +#define BFR_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 bfscast(bfelf64_xword, 541) +#define BFR_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC bfscast(bfelf64_xword, 542) +#define BFR_AARCH64_TLSIE_LD_GOTTPREL_PREL19 bfscast(bfelf64_xword, 543) + +/* Local exec TLS relocations */ +#define BFR_AARCH64_TLSLE_MOVW_TPREL_G2 bfscast(bfelf64_xword, 544) +#define BFR_AARCH64_TLSLE_MOVW_TPREL_G1 bfscast(bfelf64_xword, 545) +#define BFR_AARCH64_TLSLE_MOVW_TPREL_G1_NC bfscast(bfelf64_xword, 546) +#define BFR_AARCH64_TLSLE_MOVW_TPREL_G0 bfscast(bfelf64_xword, 547) +#define BFR_AARCH64_TLSLE_MOVW_TPREL_G0_NC bfscast(bfelf64_xword, 548) +#define BFR_AARCH64_TLSLE_ADD_TPREL_HI12 bfscast(bfelf64_xword, 549) +#define BFR_AARCH64_TLSLE_ADD_TPREL_LO12 bfscast(bfelf64_xword, 550) +#define BFR_AARCH64_TLSLE_ADD_TPREL_LO12_NC bfscast(bfelf64_xword, 551) +#define BFR_AARCH64_TLSLE_LDST8_TPREL_LO12 bfscast(bfelf64_xword, 552) +#define BFR_AARCH64_TLSLE_LDST8_TPREL_LO12_NC bfscast(bfelf64_xword, 553) +#define BFR_AARCH64_TLSLE_LDST16_TPREL_LO12 bfscast(bfelf64_xword, 554) +#define BFR_AARCH64_TLSLE_LDST16_TPREL_LO12_NC bfscast(bfelf64_xword, 555) +#define BFR_AARCH64_TLSLE_LDST32_TPREL_LO12 bfscast(bfelf64_xword, 556) +#define BFR_AARCH64_TLSLE_LDST32_TPREL_LO12_NC bfscast(bfelf64_xword, 557) +#define BFR_AARCH64_TLSLE_LDST64_TPREL_LO12 bfscast(bfelf64_xword, 558) +#define BFR_AARCH64_TLSLE_LDST64_TPREL_LO12_NC bfscast(bfelf64_xword, 559) +#define BFR_AARCH64_TLSLE_LDST128_TPREL_LO12 bfscast(bfelf64_xword, 570) +#define BFR_AARCH64_TLSLE_LDST128_TPREL_LO12_NC bfscast(bfelf64_xword, 571) + +/* TLS descriptor relocations */ +#define BFR_AARCH64_TLSDESC_LD_PREL19 bfscast(bfelf64_xword, 560) +#define BFR_AARCH64_TLSDESC_ADR_PREL21 bfscast(bfelf64_xword, 561) +#define BFR_AARCH64_TLSDESC_ADR_PAGE21 bfscast(bfelf64_xword, 562) +#define BFR_AARCH64_TLSDESC_LD64_LO12 bfscast(bfelf64_xword, 563) +#define BFR_AARCH64_TLSDESC_ADD_LO12 bfscast(bfelf64_xword, 564) +#define BFR_AARCH64_TLSDESC_OFF_G1 bfscast(bfelf64_xword, 656) +#define BFR_AARCH64_TLSDESC_OFF_G0_NC bfscast(bfelf64_xword, 566) +#define BFR_AARCH64_TLSDESC_LDR bfscast(bfelf64_xword, 567) +#define BFR_AARCH64_TLSDESC_ADD bfscast(bfelf64_xword, 568) +#define BFR_AARCH64_TLSDESC_CALL bfscast(bfelf64_xword, 569) + +/* ---------------------------------------------------------------------------------------------- */ +/* Dynamic relocations */ +/* ---------------------------------------------------------------------------------------------- */ +#define BFR_AARCH64_COPY bfscast(bfelf64_xword, 1024) +#define BFR_AARCH64_GLOB_DAT bfscast(bfelf64_xword, 1025) +#define BFR_AARCH64_JUMP_SLOT bfscast(bfelf64_xword, 1026) +#define BFR_AARCH64_RELATIVE bfscast(bfelf64_xword, 1027) +#define BFR_AARCH64_TLS_DTPREL64 bfscast(bfelf64_xword, 1028) +#define BFR_AARCH64_TLS_DTPMOD64 bfscast(bfelf64_xword, 1029) +#define BFR_AARCH64_TLS_TPREL64 bfscast(bfelf64_xword, 1030) +#define BFR_AARCH64_TLSDESC bfscast(bfelf64_xword, 1031) +#define BFR_AARCH64_IRELATIVE bfscast(bfelf64_xword, 1032) + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Relocations Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline int64_t +private_relocate_symbol( + struct bfelf_loader_t *loader, struct bfelf_file_t *ef, const struct bfelf_rela *rela) +{ + const char *str = nullptr; + const struct bfelf_sym *found_sym = nullptr; + struct bfelf_file_t *found_ef = ef; + bfelf64_addr *ptr = bfrcast(bfelf64_addr *, ef->exec_addr + rela->r_offset - ef->start_addr); + + if (BFELF_REL_TYPE(rela->r_info) == BFR_AARCH64_RELATIVE) { + *ptr = bfrcast(bfelf64_addr, ef->exec_virt + rela->r_addend); + return BFELF_SUCCESS; + } + + found_sym = &(ef->symtab[BFELF_REL_SYM(rela->r_info)]); + + if (BFELF_SYM_BIND(found_sym->st_info) == bfstb_weak) { + found_ef = nullptr; + } + + if (found_sym->st_value == 0 || found_ef == nullptr) { + int64_t ret; + + str = &(ef->strtab[found_sym->st_name]); + ret = private_get_sym_global(loader, str, &found_ef, &found_sym); + + if (ret != BFELF_SUCCESS) { + return ret; + } + } + + switch (BFELF_REL_TYPE(rela->r_info)) { + case BFR_AARCH64_GLOB_DAT: + case BFR_AARCH64_JUMP_SLOT: + case BFR_AARCH64_ABS64: + *ptr = bfrcast(bfelf64_addr, found_ef->exec_virt + found_sym->st_value); + break; + + case BFR_AARCH64_ABS32: + *(uint32_t *) ptr = bfrcast(uint32_t, found_ef->exec_virt + found_sym->st_value); + break; + + case BFR_AARCH64_ABS16: + *(uint16_t *) ptr = bfrcast(uint16_t, found_ef->exec_virt + found_sym->st_value); + break; + + default: + return bfunsupported_rel(str); + } + + return BFELF_SUCCESS; +} + +/* @endcond */ diff --git a/payloads/bareflank/include/bfelf_loader_reloc_x64.h b/payloads/bareflank/include/bfelf_loader_reloc_x64.h new file mode 100644 index 00000000000..5127762ff76 --- /dev/null +++ b/payloads/bareflank/include/bfelf_loader_reloc_x64.h @@ -0,0 +1,93 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2017 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfelf_loader_reloc_x64.h + */ + +/* + * System V ABI 64bit Relocations + * + * The following is defined in the ELF 64bit file format specification: + * http://www.x86-64.org/documentation/abi.pdf, page 71 + * + * @cond + */ +#define BFR_X86_64_64 bfscast(bfelf64_xword, 1) +#define BFR_X86_64_GLOB_DAT bfscast(bfelf64_xword, 6) +#define BFR_X86_64_JUMP_SLOT bfscast(bfelf64_xword, 7) +#define BFR_X86_64_RELATIVE bfscast(bfelf64_xword, 8) + +/* @endcond */ + +/* ---------------------------------------------------------------------------------------------- */ +/* ELF Relocations Implementation */ +/* ---------------------------------------------------------------------------------------------- */ + +/* @cond */ + +static inline int64_t +private_relocate_symbol( + struct bfelf_loader_t *loader, struct bfelf_file_t *ef, const struct bfelf_rela *rela) +{ + const char *str = nullptr; + const struct bfelf_sym *found_sym = nullptr; + struct bfelf_file_t *found_ef = ef; + bfelf64_addr *ptr = bfrcast(bfelf64_addr *, ef->exec_addr + rela->r_offset - ef->start_addr); + + if (BFELF_REL_TYPE(rela->r_info) == BFR_X86_64_RELATIVE) { + *ptr = bfrcast(bfelf64_addr, ef->exec_virt + rela->r_addend); + return BFELF_SUCCESS; + } + + found_sym = &(ef->symtab[BFELF_REL_SYM(rela->r_info)]); + + if (BFELF_SYM_BIND(found_sym->st_info) == bfstb_weak) { + found_ef = nullptr; + } + + if (found_sym->st_value == 0 || found_ef == nullptr) { + int64_t ret = 0; + str = &(ef->strtab[found_sym->st_name]); + + ret = private_get_sym_global(loader, str, &found_ef, &found_sym); + if (ret != BFELF_SUCCESS) { + return ret; + } + } + + *ptr = bfrcast(bfelf64_addr, found_ef->exec_virt + found_sym->st_value); + + switch (BFELF_REL_TYPE(rela->r_info)) { + case BFR_X86_64_64: + *ptr += bfscast(bfelf64_addr, rela->r_addend); + break; + + case BFR_X86_64_GLOB_DAT: + case BFR_X86_64_JUMP_SLOT: + break; + + default: + return bfunsupported_rel(str); + } + + return BFELF_SUCCESS; +} + +/* @endcond */ diff --git a/payloads/bareflank/include/bferrorcodes.h b/payloads/bareflank/include/bferrorcodes.h new file mode 100644 index 00000000000..647a13a1d6b --- /dev/null +++ b/payloads/bareflank/include/bferrorcodes.h @@ -0,0 +1,174 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFERROR_CODES_H +#define BFERROR_CODES_H + +#include + +/* -------------------------------------------------------------------------- */ +/* Success */ +/* -------------------------------------------------------------------------- */ + +#define SUCCESS 0 + +/* -------------------------------------------------------------------------- */ +/* Entry Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define ENTRY_SUCCESS bfscast(int64_t, SUCCESS) +#define ENTRY_ERROR_STACK_OVERFLOW bfscast(int64_t, 0x8000000000000010) +#define ENTRY_ERROR_VMM_INIT_FAILED bfscast(int64_t, 0x8000000000000020) +#define ENTRY_ERROR_VMM_START_FAILED bfscast(int64_t, 0x8000000000000030) +#define ENTRY_ERROR_VMM_STOP_FAILED bfscast(int64_t, 0x8000000000000040) +#define ENTRY_ERROR_UNKNOWN bfscast(int64_t, 0x8000000000000050) + +/* -------------------------------------------------------------------------- */ +/* C Runtime Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define CRT_SUCCESS bfscast(int64_t, SUCCESS) +#define CRT_FAILURE bfscast(int64_t, 0x8000000000000100) + +/* -------------------------------------------------------------------------- */ +/* Unwinder Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define REGISTER_EH_FRAME_SUCCESS bfscast(int64_t, SUCCESS) +#define REGISTER_EH_FRAME_FAILURE bfscast(int64_t, 0x8000000000001000) + +/* -------------------------------------------------------------------------- */ +/* Debug Ring Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define GET_DRR_SUCCESS bfscast(int64_t, SUCCESS) +#define GET_DRR_FAILURE bfscast(int64_t, 0x8000000000010000) + +/* -------------------------------------------------------------------------- */ +/* ELF Loader Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define BFELF_SUCCESS bfscast(int64_t, SUCCESS) +#define BFELF_ERROR_INVALID_ARG bfscast(int64_t, 0x8000000000100000) +#define BFELF_ERROR_INVALID_FILE bfscast(int64_t, 0x8000000000200000) +#define BFELF_ERROR_INVALID_INDEX bfscast(int64_t, 0x8000000000300000) +#define BFELF_ERROR_INVALID_SIGNATURE bfscast(int64_t, 0x8000000000500000) +#define BFELF_ERROR_UNSUPPORTED_FILE bfscast(int64_t, 0x8000000000600000) +#define BFELF_ERROR_INVALID_SEGMENT bfscast(int64_t, 0x8000000000700000) +#define BFELF_ERROR_INVALID_SECTION bfscast(int64_t, 0x8000000000800000) +#define BFELF_ERROR_LOADER_FULL bfscast(int64_t, 0x8000000000900000) +#define BFELF_ERROR_NO_SUCH_SYMBOL bfscast(int64_t, 0x8000000000A00000) +#define BFELF_ERROR_MISMATCH bfscast(int64_t, 0x8000000000B00000) +#define BFELF_ERROR_UNSUPPORTED_RELA bfscast(int64_t, 0x8000000000C00000) +#define BFELF_ERROR_OUT_OF_ORDER bfscast(int64_t, 0x8000000000D00000) +#define BFELF_ERROR_OUT_OF_MEMORY bfscast(int64_t, 0x8000000000E00000) + +/* -------------------------------------------------------------------------- */ +/* Memory Manager Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define MEMORY_MANAGER_SUCCESS bfscast(int64_t, SUCCESS) +#define MEMORY_MANAGER_FAILURE bfscast(int64_t, 0x8000000001000000) + +/* -------------------------------------------------------------------------- */ +/* Common Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define BF_SUCCESS bfscast(int64_t, SUCCESS) +#define BF_ERROR_INVALID_ARG bfscast(int64_t, 0x8000000010000000) +#define BF_ERROR_INVALID_INDEX bfscast(int64_t, 0x8000000020000000) +#define BF_ERROR_NO_MODULES_ADDED bfscast(int64_t, 0x8000000030000000) +#define BF_ERROR_MAX_MODULES_REACHED bfscast(int64_t, 0x8000000040000000) +#define BF_ERROR_VMM_INVALID_STATE bfscast(int64_t, 0x8000000050000000) +#define BF_ERROR_FAILED_TO_ADD_FILE bfscast(int64_t, 0x8000000060000000) +#define BF_ERROR_FAILED_TO_DUMP_DR bfscast(int64_t, 0x8000000070000000) +#define BF_ERROR_OUT_OF_MEMORY bfscast(int64_t, 0x8000000080000000) +#define BF_ERROR_VMM_CORRUPTED bfscast(int64_t, 0x8000000090000000) +#define BF_ERROR_UNKNOWN bfscast(int64_t, 0x80000000A0000000) + +/* -------------------------------------------------------------------------- */ +/* IOCTL Error Codes */ +/* -------------------------------------------------------------------------- */ + +#define BF_IOCTL_SUCCESS bfscast(int64_t, SUCCESS) +#define BF_IOCTL_FAILURE bfscast(int64_t, -1) + +/* -------------------------------------------------------------------------- */ +/* Bad Alloc */ +/* -------------------------------------------------------------------------- */ + +#define BF_BAD_ALLOC bfscast(int64_t, 0x8000000100000000) + +/* -------------------------------------------------------------------------- */ +/* VMCall */ +/* -------------------------------------------------------------------------- */ + +#define BF_VMCALL_SUCCESS bfscast(int64_t, SUCCESS) +#define BF_VMCALL_FAILURE bfscast(int64_t, 0x8000001000000000) + +/* -------------------------------------------------------------------------- */ +/* Stringify Error Codes */ +/* -------------------------------------------------------------------------- */ + +static inline const char * +ec_to_str(int64_t value) +{ + switch (value) { + case SUCCESS: return "SUCCESS"; + case ENTRY_ERROR_STACK_OVERFLOW: return "ENTRY_ERROR_STACK_OVERFLOW"; + case ENTRY_ERROR_VMM_INIT_FAILED: return "ENTRY_ERROR_VMM_INIT_FAILED"; + case ENTRY_ERROR_VMM_START_FAILED: return "ENTRY_ERROR_VMM_START_FAILED"; + case ENTRY_ERROR_VMM_STOP_FAILED: return "ENTRY_ERROR_VMM_STOP_FAILED"; + case ENTRY_ERROR_UNKNOWN: return "ENTRY_ERROR_UNKNOWN"; + case CRT_FAILURE: return "CRT_FAILURE"; + case REGISTER_EH_FRAME_FAILURE: return "REGISTER_EH_FRAME_FAILURE"; + case GET_DRR_FAILURE: return "GET_DRR_FAILURE"; + case MEMORY_MANAGER_FAILURE: return "MEMORY_MANAGER_FAILURE"; + case BFELF_ERROR_INVALID_ARG: return "BFELF_ERROR_INVALID_ARG"; + case BFELF_ERROR_INVALID_FILE: return "BFELF_ERROR_INVALID_FILE"; + case BFELF_ERROR_INVALID_INDEX: return "BFELF_ERROR_INVALID_INDEX"; + case BFELF_ERROR_INVALID_SIGNATURE: return "BFELF_ERROR_INVALID_SIGNATURE"; + case BFELF_ERROR_UNSUPPORTED_FILE: return "BFELF_ERROR_UNSUPPORTED_FILE"; + case BFELF_ERROR_INVALID_SEGMENT: return "BFELF_ERROR_INVALID_SEGMENT"; + case BFELF_ERROR_INVALID_SECTION: return "BFELF_ERROR_INVALID_SECTION"; + case BFELF_ERROR_LOADER_FULL: return "BFELF_ERROR_LOADER_FULL"; + case BFELF_ERROR_NO_SUCH_SYMBOL: return "BFELF_ERROR_NO_SUCH_SYMBOL"; + case BFELF_ERROR_MISMATCH: return "BFELF_ERROR_MISMATCH"; + case BFELF_ERROR_UNSUPPORTED_RELA: return "BFELF_ERROR_UNSUPPORTED_RELA"; + case BFELF_ERROR_OUT_OF_ORDER: return "BFELF_ERROR_OUT_OF_ORDER"; + case BFELF_ERROR_OUT_OF_MEMORY: return "BFELF_ERROR_OUT_OF_MEMORY"; + case BF_ERROR_INVALID_ARG: return "BF_ERROR_INVALID_ARG"; + case BF_ERROR_INVALID_INDEX: return "BF_ERROR_INVALID_INDEX"; + case BF_ERROR_NO_MODULES_ADDED: return "BF_ERROR_NO_MODULES_ADDED"; + case BF_ERROR_MAX_MODULES_REACHED: return "BF_ERROR_MAX_MODULES_REACHED"; + case BF_ERROR_VMM_INVALID_STATE: return "BF_ERROR_VMM_INVALID_STATE"; + case BF_ERROR_FAILED_TO_ADD_FILE: return "BF_ERROR_FAILED_TO_ADD_FILE"; + case BF_ERROR_FAILED_TO_DUMP_DR: return "BF_ERROR_FAILED_TO_DUMP_DR"; + case BF_ERROR_OUT_OF_MEMORY: return "BF_ERROR_OUT_OF_MEMORY"; + case BF_ERROR_VMM_CORRUPTED: return "BF_ERROR_VMM_CORRUPTED"; + case BF_ERROR_UNKNOWN: return "BF_ERROR_UNKNOWN"; + case BF_BAD_ALLOC: return "BF_BAD_ALLOC"; + case BF_IOCTL_FAILURE: return "BF_IOCTL_FAILURE"; + + default: + return "UNDEFINED_ERROR_CODE"; + } +} + +#endif diff --git a/payloads/bareflank/include/bfexception.h b/payloads/bareflank/include/bfexception.h new file mode 100755 index 00000000000..0e7f12794fc --- /dev/null +++ b/payloads/bareflank/include/bfexception.h @@ -0,0 +1,144 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfexception.h +/// + +#ifndef BFEXCEPTION_H +#define BFEXCEPTION_H + +#include +#include + +#include +#include +#include + +/// Guard Exceptions +/// +/// Catches all exceptions and prints the exception that occurred. The point of +/// this function is to prevent any exception from bubbling beyond this point. +/// +/// @expects +/// @ensures +/// +/// @param error_code an error code to return if an exception occurs +/// @param func the function to run that is guarded +/// @param error_func the function to run when an exception occurs +/// @return error_code on failure, SUCCESS on success +/// +template < + typename FUNC, + typename ERROR_FUNC, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +int64_t +guard_exceptions(int64_t error_code, FUNC func, ERROR_FUNC error_func) +{ + try { + func(); + return SUCCESS; + } + catch (std::bad_alloc &) { + error_func(); + return BF_BAD_ALLOC; + } + catch (std::exception &e) { + bfdebug_transaction(0, [&](std::string * msg) { + bferror_lnbr(0, msg); + bferror_brk1(0, msg); + bferror_info(0, typeid(e).name(), msg); + bferror_brk1(0, msg); + bferror_info(0, e.what(), msg); + }); + } + catch (...) { + bfdebug_transaction(0, [&](std::string * msg) { + bferror_lnbr(0, msg); + bferror_brk1(0, msg); + bferror_info(0, "unknown exception", msg); + bferror_brk1(0, msg); + }); + } + + error_func(); + return error_code; +} + +/// Guard Exceptions +/// +/// Catches all exceptions and prints the exception that occurred. The point of +/// this function is to prevent any exception from bubbling beyond this point. +/// +/// @expects +/// @ensures +/// +/// @param error_code an error code to return if an exception occurs +/// @param func the function to run that is guarded +/// @return error_code on failure, SUCCESS on success +/// +template < + typename FUNC, + typename = std::enable_if::value> + > +int64_t +guard_exceptions(int64_t error_code, FUNC && func) +{ return guard_exceptions(error_code, std::forward(func), [] {}); } + +/// Guard Exceptions +/// +/// Catches all exceptions and prints the exception that occurred. The point of +/// this function is to prevent any exception from bubbling beyond this point. +/// +/// @expects +/// @ensures +/// +/// @param func the function to run that is guarded +/// +template < + typename FUNC, + typename = std::enable_if::value> + > +void +guard_exceptions(FUNC && func) +{ guard_exceptions(0L, std::forward(func), [] {}); } + +/// Guard Exceptions +/// +/// Catches all exceptions and prints the exception that occurred. The point of +/// this function is to prevent any exception from bubbling beyond this point. +/// +/// @expects +/// @ensures +/// +/// @param func the function to run that is guarded +/// @param error_func the function to run when an exception occurs +/// +template < + typename FUNC, + typename ERROR_FUNC, + typename = std::enable_if::value>, + typename = std::enable_if::value> + > +void +guard_exceptions(FUNC && func, ERROR_FUNC && error_func) +{ guard_exceptions(0L, std::forward(func), std::forward(error_func)); } + +#endif diff --git a/payloads/bareflank/include/bfexports.h b/payloads/bareflank/include/bfexports.h new file mode 100644 index 00000000000..1cc48ccce0f --- /dev/null +++ b/payloads/bareflank/include/bfexports.h @@ -0,0 +1,37 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFEXPORTS_H +#define BFEXPORTS_H + +#if defined(_WIN32) || defined(__CYGWIN__) +#define IMPORT_SYM __declspec(dllimport) +#define EXPORT_SYM __declspec(dllexport) +#else +#define IMPORT_SYM +#define EXPORT_SYM __attribute__ ((visibility ("default"))) +#endif + +#if defined(_WIN32) || defined(__CYGWIN__) +#define WEAK_SYM +#else +#define WEAK_SYM __attribute__((weak)) +#endif + +#endif diff --git a/payloads/bareflank/include/bffile.h b/payloads/bareflank/include/bffile.h new file mode 100644 index 00000000000..57a9e0939de --- /dev/null +++ b/payloads/bareflank/include/bffile.h @@ -0,0 +1,345 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bffile.h +/// + +#ifndef BFFILE_H +#define BFFILE_H + +#include + +#include +#include +#include + +#include +#include +#include +#include + +/// File +/// +/// This class is responsible for working with a file. Specifically, this +/// class wraps calls to ifstream and fstream to simplify their interface +/// as well as provide an implementation for the rest of the Bareflank +/// Manager, such that testing is easier. +/// +class file +{ +public: + + using text_data = std::string; ///< File format for text data + using binary_data = bfn::buffer; ///< File format for binary data + using filename_type = std::string; ///< File name type + using extension_type = std::string; ///< Extension name type + using path_list_type = std::vector; ///< Find files path type + using filesize_type = std::size_t; ///< File size type + + /// File Constructor + /// + /// @expects none + /// @ensures none + /// + /// Creates a file class that can be used to working with files. + /// + file() noexcept = default; + + /// File Destructor + /// + /// @expects none + /// @ensures none + /// + VIRTUAL ~file() noexcept = default; + + /// Read + /// + /// Reads the entire contents of a file, in text form + /// + /// @expects filename.empty() == false + /// @ensures none + /// + /// @param filename name of the file to read. + /// @return the contents of filename + /// + /// optimization notes: + /// - http://insanecoding.blogspot.it/2011/11/how-to-read-in-file-in-c.html + /// - since std::string has to initialize the backing array, reading in + /// a binary will always be faster. Thus, use read_binary if possible + /// + VIRTUAL text_data + read_text(const filename_type &filename) const + { + expects(!filename.empty()); + + std::fstream handle(filename, std::ios_base::in | std::ios_base::binary); + if (handle) { + + handle.seekg(0, std::ios::end); + auto size = handle.tellg(); + + if (size <= 0) { + return text_data{}; + } + + handle.seekg(0, std::ios::beg); + text_data buffer(static_cast(size), 0); + + handle.read(&buffer.front(), size); + return buffer; + } + + throw std::runtime_error("invalid filename: " + filename); + } + + /// Read + /// + /// Reads the entire contents of a file, in binary form + /// + /// @expects filename.empty() == false + /// @ensures none + /// + /// @param filename name of the file to read. + /// @return the contents of filename + /// + /// optimization notes: + /// - http://insanecoding.blogspot.it/2011/11/how-to-read-in-file-in-c.html + /// + VIRTUAL binary_data + read_binary(const filename_type &filename) const + { + expects(!filename.empty()); + + std::fstream handle(filename, std::ios_base::in | std::ios_base::binary); + if (handle) { + + handle.seekg(0, std::ios::end); + auto size = handle.tellg(); + + if (size <= 0) { + return binary_data{}; + } + + handle.seekg(0, std::ios::beg); + binary_data buffer(static_cast(size)); + + handle.read(buffer.data(), size); + return buffer; + } + + throw std::runtime_error("invalid filename: " + filename); + } + + /// Write + /// + /// Writes text data to the file provided + /// + /// @expects filename.empty() == false + /// @expects buffer.empty() == false + /// @ensures none + /// + /// @param filename name of the file to write to. + /// @param buffer data to write + /// + VIRTUAL void + write_text(const filename_type &filename, const text_data &buffer) const + { + expects(!filename.empty()); + + std::fstream handle(filename, std::ios_base::out | std::ios_base::binary); + if (handle) { + handle.write(buffer.data(), static_cast(buffer.size())); + return; + } + + throw std::runtime_error("invalid filename: " + filename); + } + + /// Write + /// + /// Writes binary data to the file provided + /// + /// @expects filename.empty() == false + /// @expects buffer.empty() == false + /// @ensures none + /// + /// @param filename name of the file to write to. + /// @param buffer data to write + /// + VIRTUAL void + write_binary(const filename_type &filename, const binary_data &buffer) const + { + expects(!filename.empty()); + + std::fstream handle(filename, std::ios_base::out | std::ios_base::binary); + if (handle) { + handle.write(buffer.data(), static_cast(buffer.size())); + return; + } + + throw std::runtime_error("invalid filename: " + filename); + } + + /// Get File Extension + /// + /// @expects none + /// @ensures none + /// + /// @param filename the file name to extract the extension + /// @return the filename's extension + /// + VIRTUAL extension_type + extension(const filename_type &filename) const + { + if (filename.empty()) { + return {}; + } + + auto index = filename.find_last_of('.'); + + if (index != filename_type::npos) { + return filename.substr(index); + } + + return {}; + } + + /// File Exists + /// + /// @expects none + /// @ensures none + /// + /// @param filename the file name to check + /// @return true if the file exists, false otherwise + /// + VIRTUAL bool + exists(const filename_type &filename) const + { + std::ifstream handle{filename}; + return handle.good(); + } + + /// File Size + /// + /// @expects filename.empty() == false + /// @ensures none + /// + /// @param filename to get the size of + /// @return size of filename + /// + VIRTUAL filesize_type + size(const filename_type &filename) const + { + expects(!filename.empty()); + + std::fstream handle(filename, std::ios_base::in | std::ios_base::binary); + if (handle) { + handle.seekg(0, std::ios::end); + return static_cast(handle.tellg()); + } + + throw std::runtime_error("invalid filename: " + filename); + } + + /// Find Files + /// + /// Loops through all of the provided files and file paths and + /// returns a list of each filename combined with the path and the filename + /// that was first found. If a filename cannot be found, an exception is + /// thrown. + /// + /// @note we use the '/' separator on both Windows and POSIX. The reason + /// is both support '/' for the versions we support. + /// + /// @expects files.empty() == false + /// @expects paths.empty() == false + /// @ensures ret: path_list_type.size() == files.size() + /// + /// @param files list of files to locate in the list of provided paths + /// @param paths list of paths to search for the provided list of files + /// @return pull paths for each file located, throws otherwise + /// + VIRTUAL path_list_type + find_files(const path_list_type &files, const path_list_type &paths) const + { + expects(!paths.empty()); + path_list_type results; + + for (const auto &filename : files) { + auto found = false; + + for (auto path : paths) { + path += '/'; + path += filename; + + if (exists(path)) { + results.push_back(path); + + found = true; + break; + } + } + + if (!found) { + throw std::runtime_error("unable to locate file: " + filename); + } + } + + return results; + } + + /// Get Home Directory + /// + /// @expects none + /// @expects none + /// + /// @return returns home directory + /// + VIRTUAL std::string + home() const + { + char *home; + + home = std::getenv("HOME"); + if (home != nullptr) { + return {home}; + } + + home = std::getenv("HOMEPATH"); + if (home != nullptr) { + return {home}; + } + + throw std::runtime_error("HOME or HOMEPATH not set"); + } + +public: + + /// @cond + + file(file &&) noexcept = default; + file &operator=(file &&) noexcept = default; + + file(const file &) = default; + file &operator=(const file &) = default; + + /// @endcond +}; + +#endif diff --git a/payloads/bareflank/include/bfgsl.h b/payloads/bareflank/include/bfgsl.h new file mode 100644 index 00000000000..4e8ee400ee2 --- /dev/null +++ b/payloads/bareflank/include/bfgsl.h @@ -0,0 +1,282 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfgsl.h +/// + +#ifndef BFGSL_H +#define BFGSL_H + +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC system_header +#endif + +#include + +/// @cond + +#define concat1(a,b) a ## b +#define concat2(a,b) concat1(a,b) +#define ___ concat2(dont_care, __COUNTER__) + +/// @endcond + +#ifndef NEED_GSL_LITE + +#include + +namespace gsl +{ + +/// @cond + +#define expects(cond) Expects(cond) +#define ensures(cond) Ensures(cond) + +template +class final_act_success +{ +public: + explicit final_act_success(F f) noexcept : f_(std::move(f)), invoke_(true) {} + + final_act_success(final_act_success &&other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_) + { + other.invoke_ = false; + } + + final_act_success(const final_act_success &) = delete; + final_act_success &operator=(const final_act_success &) = delete; + + ~final_act_success() noexcept + { + if (std::uncaught_exception()) { + return; + } + + if (invoke_) { f_(); } + } + +private: + F f_; + bool invoke_; +}; + +template +class final_act_failure +{ +public: + explicit final_act_failure(F f) noexcept : f_(std::move(f)), invoke_(true) {} + + final_act_failure(final_act_failure &&other) noexcept : f_(std::move(other.f_)), invoke_(other.invoke_) + { + other.invoke_ = false; + } + + final_act_failure(const final_act_failure &) = delete; + final_act_failure &operator=(const final_act_failure &) = delete; + + ~final_act_failure() noexcept + { + if (!std::uncaught_exception()) { + return; + } + + if (invoke_) { f_(); } + } + +private: + F f_; + bool invoke_; +}; + +template +inline final_act_success on_success(const F &f) noexcept +{ + return final_act_success(f); +} + +template +inline final_act_success on_success(F &&f) noexcept +{ + return final_act_success(std::forward(f)); +} + +template +inline final_act_failure on_failure(const F &f) noexcept +{ + return final_act_failure(f); +} + +template +inline final_act_failure on_failure(F &&f) noexcept +{ + return final_act_failure(std::forward(f)); +} + +/// @endcond + +/// Memset +/// +/// Same as std::memset, but for spans +/// +/// @param dst The span to memset +/// @param val The value to set the span to +/// @return Returns dst +/// +template +auto memset(span dst, T val) +{ + expects(dst.size() > 0); + + return std::memset( + dst.data(), + static_cast(val), + static_cast(dst.size()) + ); +} + +} + +#else + +#ifdef NEED_STD_LITE +#include +#endif + +/// @cond + +#if defined(__clang__) || defined(__GNUC__) +#define gsl_likely(x) __builtin_expect(!!(x), 1) +#define gsl_unlikely(x) __builtin_expect(!!(x), 0) +#else +#define gsl_likely(x) (x) +#define gsl_unlikely(x) (x) +#endif + +#ifndef GSL_ABORT +#define GSL_ABORT abort +#endif + +#define expects(cond) \ + if (gsl_unlikely(!(cond))) { \ + GSL_ABORT(); \ + } +#define ensures(cond) \ + if (gsl_unlikely(!(cond))) { \ + GSL_ABORT(); \ + } + +/// @endcond + +namespace gsl +{ + +/// Narrow Cast +/// +/// A rename of static_cast to indicate a narrow (e.g. 64bit to 32bit) +/// +/// @param u the value to narrow +/// @return static_cast(u) +/// +template +inline constexpr T +narrow_cast(U &&u) noexcept +{ + return static_cast(std::forward(u)); +} + +/// At +/// +/// Returns a reference to an element in an array given an index. Unlike +/// the [] operator, if the indexis out-of-bounds, an exception is thrown, +/// or std::terminate() is called. +/// +/// @param arr the array +/// @param index the index of the element to retrieve. +/// @return a reference to +/// +template +constexpr T & +at(T(&arr)[N], I index) +{ + expects(index >= 0 && index < narrow_cast(N)); + return arr[static_cast(index)]; +} + +/// At +/// +/// Returns a reference to an element in an array given an index. Unlike +/// the [] operator, if the indexis out-of-bounds, an exception is thrown, +/// or std::terminate() is called. +/// +/// @param arr the array +/// @param index the index of the element to retrieve. +/// @return a reference to +/// +template +const constexpr T & +at(const T(&arr)[N], I index) +{ + expects(index >= 0 && index < narrow_cast(N)); + return arr[static_cast(index)]; +} + +/// At +/// +/// Returns a reference to an element in an array given an index. Unlike +/// the [] operator, if the indexis out-of-bounds, an exception is thrown, +/// or std::terminate() is called. +/// +/// @param arr the array +/// @param N the size of the array +/// @param index the index of the element to retrieve. +/// @return a reference to +/// +template +constexpr T & +at(T *arr, size_t N, I index) +{ + expects(index >= 0 && index < narrow_cast(N)); + return arr[static_cast(index)]; +} + +/// At +/// +/// Returns a reference to an element in an array given an index. Unlike +/// the [] operator, if the indexis out-of-bounds, an exception is thrown, +/// or std::terminate() is called. +/// +/// @param arr the array +/// @param N the size of the array +/// @param index the index of the element to retrieve. +/// @return a reference to +/// +template +const constexpr T & +at(const T *arr, size_t N, I index) +{ + expects(index >= 0 && index < narrow_cast(N)); + return arr[static_cast(index)]; +} + +} + +#endif + +#endif diff --git a/payloads/bareflank/include/bfjson.h b/payloads/bareflank/include/bfjson.h new file mode 100644 index 00000000000..62e4a9a393d --- /dev/null +++ b/payloads/bareflank/include/bfjson.h @@ -0,0 +1,113 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULLAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfjson.h +/// + +#ifndef BFJSON_H +#define BFJSON_H + +#include + +#include +using json = nlohmann::json; ///< Simply namespace + +/// JSON Hex or Dec +/// +/// Converts a JSON object's field to T. The field name can either be "" +/// or "_hex". If "_hex" is added to the field name, the value is +/// interpreted as a hex string, other wise it's interpreted as a dec number. +/// +/// @expects none +/// @ensures none +/// +/// @param obj the json object +/// @param field the field name +/// @return returns the converted number or throws +/// +template < + typename T, + typename J, + typename = std::enable_if::value> + > +auto +json_hex_or_dec(const J &obj, const std::string &field) +{ + auto val_hex = obj.value(field + "_hex", json(nullptr)); + + if (val_hex.is_string()) { + return gsl::narrow_cast(std::stoull(val_hex.template get(), 0, 16)); + } + + auto val_dec = obj.at(field); + + if (val_dec.is_number()) { + return gsl::narrow_cast(val_dec.template get()); + } + + throw std::runtime_error("json is neither a hex or dec"); +} + +/// JSON Hex or Dec Array +/// +/// Converts a JSON object's field to [T]. The field name can either be +/// "" or "_hex". If "_hex" is added to the field name, each value +/// is interpreted as a hex string, other wise they are interpreted as a dec +/// number. +/// +/// @expects none +/// @ensures none +/// +/// @param obj the json object +/// @param field the field name +/// @return returns std::vector with the converted numbers or throws +/// +template < + typename T, + typename J, + typename = std::enable_if::value> + > +auto +json_hex_or_dec_array(const J &obj, const std::string &field) +{ + std::vector result; + auto array_hex = obj.value(field + "_hex", json(nullptr)); + + if (array_hex.is_array()) { + for (auto val : array_hex) { + result.push_back(gsl::narrow_cast(std::stoull(val.template get(), 0, 16))); + } + + return result; + } + + auto array_dec = obj.at(field); + + if (array_dec.is_array()) { + for (auto val : array_dec) { + result.push_back(gsl::narrow_cast(val.template get())); + } + + return result; + } + + throw std::runtime_error("json is neither a hex or dec"); +} + +#endif diff --git a/payloads/bareflank/include/bfmanager.h b/payloads/bareflank/include/bfmanager.h new file mode 100644 index 00000000000..3e4f5a0716d --- /dev/null +++ b/payloads/bareflank/include/bfmanager.h @@ -0,0 +1,198 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef BFMANAGER_H +#define BFMANAGER_H + +#include +#include +#include + +#include +#include + +/// Manager +/// +/// A generic class for creating, destroying, running and stopping T given a +/// T_factory to actually instantiate T, and a tid to identify which T to +/// interact with. +/// +template +class bfmanager +{ +public: + + /// Destructor + /// + /// @expects none + /// @ensures none + /// + ~bfmanager() = default; + + /// Get Singleton Instance + /// + /// @expects none + /// @ensures ret != nullptr + /// + /// @return a singleton instance of bfmanager + /// + static bfmanager *instance() noexcept + { + static bfmanager self; + return &self; + } + + /// Create T + /// + /// Creates T. Note that the T is actually created by the + /// T factory's make_t function. + /// + /// @expects none + /// @ensures none + /// + /// @param id the t to initialize + /// @param obj object that can be passed around as needed + /// by extensions of Bareflank + /// + void create(tid id, bfobject *obj = nullptr) + { + auto ___ = gsl::on_failure([&] { + std::lock_guard guard(m_mutex); + m_ts.erase(id); + }); + + if (auto &&t = add_t(id, obj)) { + t->init(obj); + } + } + + /// Destroy T + /// + /// Deletes T. + /// + /// @param id the t to destroy + /// @param obj object that can be passed around as needed + /// by extensions of Bareflank + /// + void destroy(tid id, bfobject *obj = nullptr) + { + auto ___ = gsl::finally([&] { + std::lock_guard guard(m_mutex); + m_ts.erase(id); + }); + + if (auto &&t = get_t(id)) { + t->fini(obj); + } + } + + /// Run T + /// + /// Executes T. + /// + /// @expects t exists + /// @ensures none + /// + /// @param id the t to run + /// @param obj object that can be passed around as needed + /// by extensions of Bareflank + /// + void run(tid id, bfobject *obj = nullptr) + { + if (auto &&t = get_t(id)) { + t->run(obj); + } + } + + /// Halt T + /// + /// Halts T. + /// + /// @expects none + /// @ensures none + /// + /// @param id the t to halt + /// @param obj object that can be passed around as needed + /// by extensions of Bareflank + /// + void hlt(tid id, bfobject *obj = nullptr) + { + if (auto &&t = get_t(id)) { + t->hlt(obj); + } + } + + /// Set Factory + /// + /// Should only be used by unit tests + /// + /// @expects none + /// @ensures none + /// + /// @param factory the new factory to use + /// + void set_factory(std::unique_ptr factory) + { m_T_factory = std::move(factory); } + +private: + + bfmanager() noexcept : + m_T_factory(std::make_unique()) + { } + + std::unique_ptr &add_t(tid id, bfobject *obj) + { + if (auto &&t = get_t(id)) { + return t; + } + + if (auto t = m_T_factory->make(id, obj)) { + std::lock_guard guard(m_mutex); + return m_ts[id] = std::move(t); + } + + throw std::runtime_error("make returned a nullptr"); + } + + std::unique_ptr &get_t(tid id) + { + std::lock_guard guard(m_mutex); + return m_ts[id]; + } + +private: + + std::unique_ptr m_T_factory; + std::map> m_ts; + + mutable std::mutex m_mutex; + +public: + + /// @cond + + bfmanager(bfmanager &&) noexcept = delete; + bfmanager &operator=(bfmanager &&) noexcept = delete; + + bfmanager(const bfmanager &) = delete; + bfmanager &operator=(const bfmanager &) = delete; + + /// @endcond +}; + +#endif diff --git a/payloads/bareflank/include/bfmemory.h b/payloads/bareflank/include/bfmemory.h new file mode 100644 index 00000000000..49d39029a03 --- /dev/null +++ b/payloads/bareflank/include/bfmemory.h @@ -0,0 +1,75 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfmemory.h + */ + +#ifndef BFMEMORY_H +#define BFMEMORY_H + +#include +#include +#include + +#pragma pack(push, 1) + +#ifdef __cplusplus +extern "C" { +#endif + +/* @cond */ + +#define MEMORY_TYPE_R 0x1U +#define MEMORY_TYPE_W 0x2U +#define MEMORY_TYPE_E 0x4U + +/* @endcond */ + +/** + * @struct memory_descriptor + * + * Memory Descriptor + * + * A memory descriptor provides information about a block of memory. + * Typically, each page of memory that the VMM uses will have a memory + * descriptor associated with it. The VMM will use this information to create + * its resources, as well as generate page tables as needed. + * + * @var memory_descriptor::phys + * the starting physical address of the block of memory + * @var memory_descriptor::virt + * the starting virtual address of the block of memory + * @var memory_descriptor::type + * the type of memory block. This is likely architecture specific as + * this holds information about access rights, etc... + */ +struct memory_descriptor { + uint64_t phys; + uint64_t virt; + uint64_t type; +}; + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif diff --git a/payloads/bareflank/include/bfobject.h b/payloads/bareflank/include/bfobject.h new file mode 100644 index 00000000000..295c5fe25ab --- /dev/null +++ b/payloads/bareflank/include/bfobject.h @@ -0,0 +1,57 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfobject.h +/// + +#ifndef BFOBJECT_H +#define BFOBJECT_H + +/// User Data +/// +/// This defines the base class used for passing around subclasses. +/// This is mainly used so that dynamic_cast can be used if desired +/// for casting and deletion. +/// +class bfobject +{ +public: + + /// Default Constructor + /// + bfobject() = default; + + /// Default Destructor + /// + virtual ~bfobject() = default; + +public: + + /// @cond + + bfobject(bfobject &&) noexcept = delete; + bfobject &operator=(bfobject &&) noexcept = delete; + + bfobject(const bfobject &) = delete; + bfobject &operator=(const bfobject &) = delete; + + /// @endcond +}; + +#endif diff --git a/payloads/bareflank/include/bfplatform.h b/payloads/bareflank/include/bfplatform.h new file mode 100755 index 00000000000..657622734f1 --- /dev/null +++ b/payloads/bareflank/include/bfplatform.h @@ -0,0 +1,177 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfplatform.h + */ + +#ifndef BFPLATFORM_H +#define BFPLATFORM_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Initalize Platform Logic + * + * @expects none + * @ensures none + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t platform_init(void); + +/** + * Allocate Memory + * + * @expects none + * @ensures none + * + * @note: If this function is used in userspace, it must be assumed that free() + * can be used to free this memory. In the kernel, it can be assumed that + * platform_free_rw is used instead, which provides the length field. + * + * @param len the size of memory to allocate in bytes. + * @return returns the address of the newly allocated memory + */ +void *platform_alloc_rw(uint64_t len); + +/** + * Allocate Executable Memory + * + * @expects none + * @ensures none + * + * @note: memory allocated from this function must be 4k aligned. If this + * function is used in userspace, it must be assumed that free() can be + * used to free this memory. In the kernel, it can be assumed that + * platform_free_rwe is used instead, which provides the length field. + * + * @param len the size of memory to allocate in bytes. + * @return returns the address of the newly allocated, executable memory + */ +void *platform_alloc_rwe(uint64_t len); + +/** + * Free Memory + * + * @expects none + * @ensures none + * + * @param addr the address of memory allocated using platform_alloc_rw + * @param len the size of the memory allocated using platform_alloc_rw + */ +void platform_free_rw(const void *addr, uint64_t len); + +/** + * Free Executable Memory + * + * @expects none + * @ensures none + * + * @param addr the address of memory allocated using platform_alloc_rwe + * @param len the size of the memory allocated using platform_alloc_rwe + */ +void platform_free_rwe(const void *addr, uint64_t len); + +/** + * Convert Virtual Address to Physical Address + * + * @expects none + * @ensures none + * + * @param virt the virtual address to convert + * @return the physical address associated with the provided virtual address + */ +void *platform_virt_to_phys(void *virt); + +/** + * Memset + * + * @expects none + * @ensures none + * + * @param ptr a pointer to the memory to set + * @param value the value to set each byte to + * @param num the number of bytes to set + */ +void *platform_memset(void *ptr, char value, uint64_t num); + +/** + * Memcpy + * + * @expects none + * @ensures none + * + * @param dst a pointer to the memory to copy to + * @param src a pointer to the memory to copy from + * @param num the number of bytes to copy + */ +void *platform_memcpy(void *dst, const void *src, uint64_t num); + +/** + * Get Number of CPUs + * + * @expects none + * @ensures none + * + * @return returns the total number of CPUs available. + */ +int64_t platform_num_cpus(void); + +/** + * Call VMM on Core + * + * Executes the VMM. The VMM has a single entry point, with a switch statement + * that executes the provided "request". When this occurs, arg1 and arg2 are + * provided to the requested function. Note that the first arg takes a cpuid, + * which is the core number want to execute the VMM on. If a -1 is provided, + * the currently executing core will be used. + * + * @param cpuid the core id this code is to be execute on + * @param request the requested function in the VMM to execute + * @param arg1 arg #1 + * @param arg2 arg #2 + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t platform_call_vmm_on_core( + uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2); + +/** + * Get RSDP + * + * Returns the address of the Root System Description Pointer for ACPI. + * If ACPI is not supported, return 0. + * + * @expects none + * @ensures none + * + * @return returns the RSDP or 0 if ACPI is not supported + */ +void *platform_get_rsdp(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/include/bfshuffle.h b/payloads/bareflank/include/bfshuffle.h new file mode 100644 index 00000000000..bda3fc27971 --- /dev/null +++ b/payloads/bareflank/include/bfshuffle.h @@ -0,0 +1,49 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfshuffle.h +/// + +#ifndef BFSHUFFLE_H +#define BFSHUFFLE_H + +#include +#include +#include + +namespace bfn +{ + +/// Shuffle Vector +/// +/// @expects none +/// @ensures none +/// +/// @param list the vector to shuffle +/// +template void +shuffle(std::vector &list) +{ + std::random_device rd; + std::shuffle(list.begin(), list.end(), std::mt19937{rd()}); +} + +} + +#endif diff --git a/payloads/bareflank/include/bfstd.h b/payloads/bareflank/include/bfstd.h new file mode 100644 index 00000000000..eea919d3188 --- /dev/null +++ b/payloads/bareflank/include/bfstd.h @@ -0,0 +1,118 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfstd.h +/// + +#ifndef BFSTD_H +#define BFSTD_H + +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC system_header +#endif + +#include +#include + +// Note: +// +// This file exists for code that cannot include libc++ +// + +namespace std +{ +/// Remove Reference +/// +/// Returns T regardless of lvalue / rvalue type +/// +template struct remove_reference { + typedef T type; ///< Type T +}; + +/// Remove Reference +/// +/// Returns T regardless of lvalue / rvalue type +/// +template struct remove_reference { + typedef T type; ///< Type T +}; + +/// Remove Reference +/// +/// Returns T regardless of lvalue / rvalue type +/// +template struct remove_reference < T && > { + typedef T type; ///< Type T +}; + +/// Forward +/// +/// Preserves lvalue / rvalue reference +/// +/// @param t the object to be forwarded +/// @return static_cast(t) +/// +template +constexpr T && +forward(typename std::remove_reference::type &t) noexcept +{ + return static_cast < T && >(t); +} + +/// Forward +/// +/// Preserves lvalue / rvalue reference +/// +/// @param t the object to be forwarded +/// @return static_cast(t) +/// +template +constexpr T && +forward(typename std::remove_reference::type &&t) noexcept +{ + return static_cast < T && >(t); +} + +/// Move +/// +/// Produces a rvalue reference +/// +/// @param t the object to be moved +/// @return static_cast::type&&>(t) +/// +template +constexpr typename std::remove_reference::type && +move(T &&t) noexcept +{ + return static_cast < typename std::remove_reference::type && >(t); +} + +/// Terminate +/// +/// A C++ wrapper around C's abort(). +/// +[[noreturn]] inline void +terminate() noexcept +{ + printf("FATAL ERROR: std::terminate() called!!!\n"); + abort(); +} +} + +#endif diff --git a/payloads/bareflank/include/bfstring.h b/payloads/bareflank/include/bfstring.h new file mode 100644 index 00000000000..4212fcdcd1e --- /dev/null +++ b/payloads/bareflank/include/bfstring.h @@ -0,0 +1,142 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfstring.h +/// + +#ifndef BFSTRING_H +#define BFSTRING_H + +#include +#include +#include +#include +#include + +/// std::string literal +/// +/// @param str string to convert to std::string +/// @param len len of str +/// @return std::string(str, len) +/// +inline auto operator""_s(const char *str, std::size_t len) +{ + return std::string(str, len); +} + +namespace bfn +{ + +/// Convert to String (with base) +/// +/// Same thing as std::to_string, but adds the ability to state the base for +/// conversion. +/// +/// @expects none +/// @ensures none +/// +/// @param val the value to convert +/// @param base the base for conversion. +/// @return string version of val converted to the provided base +/// +template < + typename T, + typename = std::enable_if::value> + > +std::string +to_string(const T val, const int base) +{ + // TODO: + // + // C++17 has a new set of functions that called to_chars which gets rid + // of the allocation. We should use this in the VMM when compiled with + // our cross compiler. When not compiled with our cross compiler, we + // should use this code to emulate it so that we do not need C++17 on all + // systems. This optimization would reduce the debugging code to just + // page allocations as needed which is ideal + // + + std::stringstream stream; + + switch (base) { + case 16: + stream << std::setfill('0') << std::setw(18) << std::internal; + break; + + default: + break; + }; + + stream << std::setbase(base) << std::showbase << val; + return stream.str(); +} + +/// Split String +/// +/// Splits a string into a string vector based on a provided +/// delimiter +/// +/// @expects none +/// @ensures none +/// +/// @param str the string to split +/// @param delimiter the delimiter to split the string with +/// @return std::vector version of str, split using delimiter +/// +inline std::vector +split(const std::string &str, char delimiter) +{ + std::istringstream ss{str}; + std::vector result; + + while (!ss.eof()) { + std::string field; + std::getline(ss, field, delimiter); + + result.push_back(field); + } + + return result; +} + +/// Split String +/// +/// Splits a string into a string vector based on a provided +/// delimiter +/// +/// @expects none +/// @ensures none +/// +/// @param str the string to split +/// @param delimiter the delimiter to split the string with +/// @return std::vector version of str, split using delimiter +/// +inline std::vector +split(const char *str, char delimiter) +{ + if (str == nullptr) { + return {}; + } + + return split(std::string(str), delimiter); +} + +} + +#endif diff --git a/payloads/bareflank/include/bfsupport.h b/payloads/bareflank/include/bfsupport.h new file mode 100755 index 00000000000..496e114ed31 --- /dev/null +++ b/payloads/bareflank/include/bfsupport.h @@ -0,0 +1,196 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfsupport.h + */ + +#ifndef BFSUPPORT_H +#define BFSUPPORT_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @struct section_info_t + * + * Provides information about the ELF file that is used to init/fini the + * file. + * + * @var section_info_t::init_addr + * the virtual address of ".init" after relocation + * @var section_info_t::fini_addr + * the virtual address of ".fini" after relocation + * @var section_info_t::init_array_addr + * the virtual address of ".init_array" after relocation + * @var section_info_t::init_array_size + * the size of ".init_array" + * @var section_info_t::fini_array_addr + * the virtual address of ".fini_array" after relocation + * @var section_info_t::fini_array_size + * the size of ".fini_array" + * @var section_info_t::eh_frame_addr + * the virtual address of ".eh_frame" after relocation + * @var section_info_t::eh_frame_size + * the size of ".eh_frame" + * @var section_info_t::debug_info_addr + * the virtual address of ".debug_info" after relocation + * @var section_info_t::debug_info_size + * the size of ".debug_info" + * @var section_info_t::debug_abbrev_addr + * the virtual address of ".debug_abbrev" after relocation + * @var section_info_t::debug_abbrev_size + * the size of ".debug_abbrev" + * @var section_info_t::debug_line_addr + * the virtual address of ".debug_line" after relocation + * @var section_info_t::debug_line_size + * the size of ".debug_line" + * @var section_info_t::debug_str_addr + * the virtual address of ".debug_str" after relocation + * @var section_info_t::debug_str_size + * the size of ".debug_str" + * @var section_info_t::debug_ranges_addr + * the virtual address of ".debug_ranges" after relocation + * @var section_info_t::debug_ranges_size + * the size of ".debug_ranges" + */ +struct section_info_t { + void *init_addr; + void *fini_addr; + + void *init_array_addr; + uint64_t init_array_size; + + void *fini_array_addr; + uint64_t fini_array_size; + + void *eh_frame_addr; + uint64_t eh_frame_size; + + void *debug_info_addr; + uint64_t debug_info_size; + + void *debug_abbrev_addr; + uint64_t debug_abbrev_size; + + void *debug_line_addr; + uint64_t debug_line_size; + + void *debug_str_addr; + uint64_t debug_str_size; + + void *debug_ranges_addr; + uint64_t debug_ranges_size; +}; + +/** + * @struct crt_info_t + * + * Provides information for executing an application including section + * information, the program break and arguments. + * + * @var crt_info_t::arg_type + * 0 = argc/argv, 1 == arg#, undefined otherwise + * @var crt_info_t::argc + * the number of arguments + * @var crt_info_t::argv + * the arguments +* @var crt_info_t::request + * - + * @var crt_info_t::arg1 + * integer argument #1 + * @var crt_info_t::arg2 + * integer argument #2 + * @var crt_info_t::arg3 + * integer argument #3 + * @var crt_info_t::info_num + * the number of modules + * @var crt_info_t::info + * the section info for each module + * @var crt_info_t::func + * (optional) function to call + * @var crt_info_t::vcpuid + * (optional) vcpuid the executable is running on + * @var crt_info_t::program_break + * (optional) the executable's program break + */ +struct crt_info_t { + + int arg_type; + + int argc; + const char **argv; + + uintptr_t request; + uintptr_t arg1; + uintptr_t arg2; + uintptr_t arg3; + + int info_num; + struct section_info_t info[MAX_NUM_MODULES]; + + uintptr_t func; + uintptr_t vcpuid; + uintptr_t program_break; +}; + +/** + * Request IDs + * + * The following defines the different types of requests that can be made + * when calling bfmain instead of main. Note that these are simply the + * currently defined requests, users can add to this as needed. + * + * @cond + */ + +#define BF_REQUEST_INIT 0 +#define BF_REQUEST_FINI 1 +#define BF_REQUEST_VMM_INIT 2 +#define BF_REQUEST_VMM_FINI 3 +#define BF_REQUEST_ADD_MDL 4 +#define BF_REQUEST_GET_DRR 5 +#define BF_REQUEST_SET_RSDP 6 +#define BF_REQUEST_END 0xFFFF + +/* @endcond */ + +/** + * Start + * + * Defines the function signature for the _start function + */ +#ifdef __cplusplus +using _start_t = int64_t (*)(char *stack, const struct crt_info_t *); +#else +typedef int64_t (*_start_t)(char *stack, const struct crt_info_t *); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/include/bfthreadcontext.h b/payloads/bareflank/include/bfthreadcontext.h new file mode 100644 index 00000000000..3fa562e92bd --- /dev/null +++ b/payloads/bareflank/include/bfthreadcontext.h @@ -0,0 +1,115 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file bfthreadcontext.h + */ + +#ifndef BFTHREADCONTEXT +#define BFTHREADCONTEXT + +#include +#include + +#pragma pack(push, 1) + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Return CPUID + * + * @return returns the CPUID for the currently executing thread + */ +uint64_t thread_context_cpuid(void); + +/** + * Return TLS data + * + * @return returns the TLS data for the currently executing thread + */ +uint64_t *thread_context_tlsptr(void); + +/** + * @struct thread_context_t + * + * Thread Context + * + * On the top of every stack pointer sits one of these structures, which is + * used to identify thread specific information. For more information on + * how this works, please see the following post: + * + * https://github.com/Bareflank/hypervisor/issues/213 + * + * Note: If this struct changes, assembly code in the misc module will + * likely have to change as well since we don't have a clean way to bridge + * between C and NASM + * + * @var thread_context_t::cpuid + * the cpuid of the thread + * @var thread_context_t::tlsptr + * the TLS pointer of the thread + * @var thread_context_t::reserved1 + * reserved + * @var thread_context_t::reserved2 + * reserved + */ +struct thread_context_t { + uint64_t cpuid; + uint64_t *tlsptr; + uint64_t reserved1; + uint64_t reserved2; +}; + +/** + * Setup Stack + * + * The following function sets up the stack to match the algorithm defined + * in the following issue: + * + * https://github.com/Bareflank/hypervisor/issues/213 + * + * @param stack the stack pointer + * @return the stack pointer (in interger form) + */ +static inline uint64_t +setup_stack(void *stack) +{ + struct thread_context_t *tc; + uint64_t stack_int = bfrcast(uint64_t, stack); + + uint64_t stack_top = stack_int + (STACK_SIZE * 2); + stack_top = (stack_top & ~(STACK_SIZE - 1)) - 1; + stack_int = stack_top - sizeof(struct thread_context_t) - 1; + + tc = bfrcast(struct thread_context_t *, stack_top - sizeof(struct thread_context_t)); + tc->cpuid = thread_context_cpuid(); + tc->tlsptr = thread_context_tlsptr(); + + return stack_int; +} + +#ifdef __cplusplus +} +#endif + +#pragma pack(pop) + +#endif diff --git a/payloads/bareflank/include/bftypes.h b/payloads/bareflank/include/bftypes.h new file mode 100644 index 00000000000..13d0671b8c0 --- /dev/null +++ b/payloads/bareflank/include/bftypes.h @@ -0,0 +1,138 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BFTYPES_H +#define BFTYPES_H + +/* -------------------------------------------------------------------------- */ +/* Helper Macros */ +/* -------------------------------------------------------------------------- */ + +#ifdef __cplusplus +#define bfscast(a, b) (static_cast(b)) +#else +#define bfscast(a, b) ((a)(b)) +#endif + +#ifdef __cplusplus +#define bfrcast(a, b) (reinterpret_cast(b)) +#else +#define bfrcast(a, b) ((a)(b)) +#endif + +#ifdef __cplusplus +#define bfadd(a, b, c) (reinterpret_cast(reinterpret_cast(b) + (c))) +#else +#define bfadd(a, b, c) ((a)((char *)(b) + (c))) +#endif + +#ifdef __cplusplus +#define bfcadd(a, b, c) (reinterpret_cast(reinterpret_cast(b) + (c))) +#else +#define bfcadd(a, b, c) ((a)((const char *)(b) + (c))) +#endif + +#define bfignored(a) (void)a + +/* -------------------------------------------------------------------------- */ +/* Stringify */ +/* -------------------------------------------------------------------------- */ + +#define bfstringify(a) __bfstringify(a) +#define __bfstringify(a) #a + +/* -------------------------------------------------------------------------- */ +/* NULL */ +/* -------------------------------------------------------------------------- */ + +#if !defined(__cplusplus) && !defined(nullptr) +#define nullptr 0 +#endif + +/* -------------------------------------------------------------------------- */ +/* Debug */ +/* -------------------------------------------------------------------------- */ + +#ifdef NDEBUG +#define ndebug 1 +#else +#define ndebug 0 +#endif + +/* -------------------------------------------------------------------------- */ +/* Testing */ +/* -------------------------------------------------------------------------- */ + +#ifdef ENABLE_BUILD_TEST +#define VIRTUAL virtual +#else +#define VIRTUAL +#endif + +/* -------------------------------------------------------------------------- */ +/* Userspace */ +/* -------------------------------------------------------------------------- */ + +#if !defined(KERNEL) && !defined(_WIN32) +#if defined(__cplusplus) && __has_include("cstdint") +#include +#else +#include +#endif +#endif + +/* -------------------------------------------------------------------------- */ +/* Linux Types */ +/* -------------------------------------------------------------------------- */ + +#if defined(KERNEL) && defined(__linux__) +#include +#define PRId64 "lld" +#endif + +/* -------------------------------------------------------------------------- */ +/* Windows Types */ +/* -------------------------------------------------------------------------- */ + +#if defined(_WIN32) +#include +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef INT32 int32_t; +typedef INT64 int64_t; +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; +typedef UINT32 uint32_t; +typedef UINT64 uint64_t; +typedef UINT_PTR uintptr_t; +typedef INT_PTR intptr_t; +#define PRId64 "lld" +#endif + +/* -------------------------------------------------------------------------- */ +/* EFI Types */ +/* -------------------------------------------------------------------------- */ + +#if defined(KERNEL) && defined(EFI) +#include "efi.h" +#include "efilib.h" +#define PRId64 "lld" +#endif + +#endif diff --git a/payloads/bareflank/include/bfupperlower.h b/payloads/bareflank/include/bfupperlower.h new file mode 100644 index 00000000000..dd7161bd565 --- /dev/null +++ b/payloads/bareflank/include/bfupperlower.h @@ -0,0 +1,146 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfupperlower.h +/// + +#ifndef BFUPPERLOWER_H +#define BFUPPERLOWER_H + +#include +#include + +namespace bfn +{ + +/// Lower +/// +/// @param val the pointer to mask +/// @return the lower 12 bits of val +/// +template < + typename T, + typename = std::enable_if::value> + > +auto +lower(T val) noexcept +{ + return static_cast(static_cast(val) & (0xFFFULL)); +} + +/// Lower +/// +/// @param val the pointer to mask +/// @return the lower 12 bits of val +/// +template +auto +lower(T *val) noexcept +{ + return reinterpret_cast(reinterpret_cast(val) & (0xFFFULL)); +} + +/// Lower +/// +/// @param val the pointer to mask +/// @param from the number of bits to mask +/// @return the lower "from" bits of val +/// +template < + typename T, + typename = std::enable_if::value> + > +auto +lower(T val, uintptr_t from) noexcept +{ + return static_cast(static_cast(val) & ((0x1ULL << from) - 1)); +} + +/// Lower +/// +/// @param val the pointer to mask +/// @param from the number of bits to mask +/// @return the lower "from" bits of val +/// +template +auto +lower(T *val, uintptr_t from) noexcept +{ + return reinterpret_cast(reinterpret_cast(val) & ((0x1ULL << from) - 1)); +} + +/// Upper +/// +/// @param val the pointer to mask +/// @return the upper 12 bits of val +/// +template < + typename T, + typename = std::enable_if::value> + > +auto +upper(T val) noexcept +{ + return static_cast(static_cast(val) & ~(0xFFFULL)); +} + +/// Upper +/// +/// @param val the pointer to mask +/// @return the upper 12 bits of val +/// +template +auto +upper(T *val) noexcept +{ + return reinterpret_cast(reinterpret_cast(val) & ~(0xFFFULL)); +} + +/// Upper +/// +/// @param val the pointer to mask +/// @param from the number of bits to mask +/// @return the upper "from" bits of val +/// +template < + typename T, + typename = std::enable_if::value> + > +auto +upper(T val, uintptr_t from) noexcept +{ + return static_cast(static_cast(val) & ~((0x1ULL << from) - 1)); +} + +/// Upper +/// +/// @param val the pointer to mask +/// @param from the number of bits to mask +/// @return the upper "from" bits of val +/// +template +auto +upper(T *val, uintptr_t from) noexcept +{ + return reinterpret_cast(reinterpret_cast(val) & ~((0x1ULL << from) - 1)); +} + +} + +#endif diff --git a/payloads/bareflank/include/bfvcpuid.h b/payloads/bareflank/include/bfvcpuid.h new file mode 100644 index 00000000000..23e7f8cf89b --- /dev/null +++ b/payloads/bareflank/include/bfvcpuid.h @@ -0,0 +1,64 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#ifndef BFVCPUID_H +#define BFVCPUID_H + +#include + +// *INDENT-OFF* + +namespace vcpuid +{ + using type = uint64_t; + + constexpr const auto reserved = 0x8000000000000000UL; + + constexpr const auto invalid = 0xFFFFFFFFFFFFFFFFUL; + constexpr const auto current = 0xFFFFFFFFFFFFFFF0UL; + + constexpr const auto guest_mask = 0xFFFFFFFFFFFF0000UL; + constexpr const auto guest_from = 16; + + /// Is Bootstrap vCPU + /// + /// @expects none + /// @ensures none + /// + /// @param id the id to check + /// @return true if this vCPU is the bootstrap vCPU, false otherwise + /// + constexpr inline bool is_bootstrap_vcpu(type id) + { return id == 0; } + + /// Is Host VM vCPU + /// + /// @expects none + /// @ensures none + /// + /// @param id the id to check + /// @return true if this vCPU belongs to the host VM, false otherwise + /// + constexpr inline bool is_hvm_vcpu(type id) + { return (id & (vcpuid::guest_mask & ~vcpuid::reserved)) == 0; } + +} + +// *INDENT-ON* + +#endif diff --git a/payloads/bareflank/include/bfvector.h b/payloads/bareflank/include/bfvector.h new file mode 100644 index 00000000000..7e76f28828f --- /dev/null +++ b/payloads/bareflank/include/bfvector.h @@ -0,0 +1,140 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +/// +/// @file bfvector.h +/// + +#ifndef BFVECTOR +#define BFVECTOR + +#include +#include + +namespace bfn +{ + +/// Find +/// +/// Get the iterator from the provided vector, given an index. +/// +/// @expects index >= 0 +/// @expects index < v.size() +/// @ensures ret != v.end() +/// +/// @param v std::vector to get iterator from +/// @param index the iterator to locate +/// @return returns the iterator at pos == index, or throws gsl::fail_fast +/// +template < + typename T, + typename A + > +auto +find(std::vector &v, const std::ptrdiff_t index) +{ + // [[ensures ret: ret != v.end()]] + expects(index >= 0 && index < gsl::narrow_cast(v.size())); + + return v.begin() + index; +} + +/// Find (const) +/// +/// Get the iterator from the provided vector, given an index. +/// +/// @expects index >= 0 +/// @expects index < v.size() +/// @ensures ret != v.end() +/// +/// @param v std::vector to get iterator from +/// @param index the iterator to locate +/// @return returns the iterator at pos == index, or throws gsl::fail_fast +/// +template < + typename T, + typename A + > +auto +cfind(const std::vector &v, const std::ptrdiff_t index) +{ + // [[ensures ret: ret != v.end()]] + expects(index >= 0 && index < gsl::narrow_cast(v.size())); + + return v.cbegin() + index; +} + +/// Remove +/// +/// Removes an element from the provided vector. This function uses +/// std::vector::erase, and thus, all iterators are invalidated after this +/// function call is made. +/// +/// @expects index >= 0 +/// @expects index < v.size() +/// @ensures +/// +/// @param v std::vector to get iterator from +/// @param index the iterator to locate +/// +template < + typename T, + typename A, + typename I, + typename = std::enable_if::value> + > +void +remove(std::vector &v, const I index) +{ + v.erase(cfind(v, index)); +} + +/// Take +/// +/// Takes an element from the provided vector. This function uses +/// std::vector::erase, and thus, all iterators are invalidated after this +/// function call is made. +/// +/// @expects index >= 0 +/// @expects index < v.size() +/// @ensures +/// +/// @param v std::vector to get iterator from +/// @param index the iterator to locate +/// @return returns the element that was removed +/// +template < + typename T, + typename A, + typename I, + typename = std::enable_if::value> + > +auto +take(std::vector &v, const I index) +{ + const auto iter = cfind(v, index); + auto val = *iter; + + v.erase(iter); + + return val; +} + +} + +#endif diff --git a/payloads/bareflank/include/common.h b/payloads/bareflank/include/common.h new file mode 100644 index 00000000000..f0d314ec60b --- /dev/null +++ b/payloads/bareflank/include/common.h @@ -0,0 +1,176 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef COMMON_H +#define COMMON_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * VMM Status + * + * @return returns the current status of the VMM. + */ +int64_t +common_vmm_status(void); + +/** + * Reset + * + * This function should not be called directly. Instead, use common_unload. + * This is only exposed publically for unit testing. + */ +void +common_reset(void); + +/** + * Initialize Driver Entry + * + * This code should be run as part of the driver entry's init code. This + * sets up some resources that are needed throughout the lifetime of the + * driver entry. + */ +int64_t +common_init(void); + +/** + * Finalize Driver Entry + * + * This code should be run as part of the driver entry's fini code. This + * cleans up some resources that were needed throughout the lifetime of the + * driver entry. + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_fini(void); + +/** + * Add Module + * + * Add's a module into memory to be executed once start_vmm is run. This + * function uses the platform functions to allocate memory for the executable. + * The file that is provided should not be removed until after stop_vmm is + * run. Removing the file from memory could cause a crash, as the start_vmm + * function uses the file that is being added to search for symbols that are + * needed, as well as the stop_vmm function. Once stop_vmm is run, it's safe + * to remove the files. Also, this function cannot be run if the vmm has + * already been started. + * + * @param file the file to add to memory + * @param fsize the size of the file in bytes + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_add_module(const char *file, uint64_t fsize); + +/** + * Load VMM + * + * This function loads the vmm (assuming that the modules that were + * loaded are actually a vmm). Once a VMM is loaded, it is placed in memory, + * and all of the modules are properly reloacted such that, code within each + * module is now capable of executing. + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_load_vmm(void); + +/** + * Unload VMM + * + * This function unloads the vmm. Once the VMM is unloaded, all of the symbols + * for the VMM are removed from memory, and are no longer accessible. The VMM + * cannot be unloaded unless the VMM is already loaded, but is not running. + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_unload_vmm(void); + +/** + * Start VMM + * + * This function starts the vmm. Before the VMM can be started, it must first + * be loaded. + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_start_vmm(void); + +/** + * Stop VMM + * + * This function stops the vmm. Before a VMM can be stopped, it must first be + * loaded, and running. + * + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_stop_vmm(void); + +/** + * Dump VMM + * + * This grabs the conents of the debug ring, and dumps the contents to the + * driver entry's console. This is one of a couple of ways to get feedback + * from the VMM. Note that the VMM must at least be loaded for this function + * to work as it has to do a symbol lookup + * + * @param drr a pointer to the drr provided by the user + * @param vcpuid indicates which drr to get as each vcpu has its own drr + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_dump_vmm(struct debug_ring_resources_t **drr, uint64_t vcpuid); + +/** + * Call VMM + * + * Executes the VMM. The VMM has a single entry point, with a switch statement + * that executes the provided "request". When this occurs, arg1 and arg2 are + * provided to the requested function. Note that the first arg takes a cpuid, + * which is the core number you are currently executing on. This is needed + * because this function needs to set up the proper stack before executing + * the VMM, and it needs to know which core you are on to use the proper stack + * which in turn also executes with the proper TLS region. + * + * @param cpuid the core id this code is currently being executed on + * @param request the requested function in the VMM to execute + * @param arg1 arg #1 + * @param arg2 arg #2 + * @return BF_SUCCESS on success, negative error code on failure + */ +int64_t +common_call_vmm(uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/payloads/bareflank/platform.c b/payloads/bareflank/platform.c new file mode 100755 index 00000000000..27197fe55a9 --- /dev/null +++ b/payloads/bareflank/platform.c @@ -0,0 +1,86 @@ +/* + * Bareflank Hypervisor + * Copyright (C) 2015 Assured Information Security, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +#include +#include +#include + + +int platform_info_should_fail = 0; + +int64_t +platform_init(void) +{ return BF_SUCCESS; } + +void * +platform_alloc_rw(uint64_t len) +{ + return memalign(BAREFLANK_PAGE_SIZE, len); +} + +void * +platform_alloc_rwe(uint64_t len) +{ + return memalign(BAREFLANK_PAGE_SIZE, len); +} + +void +platform_free_rw(const void *addr, uint64_t len) +{ + bfignored(len); + free((void *)addr); +} + +void +platform_free_rwe(const void *addr, uint64_t len) +{ + bfignored(len); + free((void *)addr); +} + +void * +platform_virt_to_phys(void *virt) +{ return virt; } + +void * +platform_memset(void *ptr, char value, uint64_t num) +{ return memset(ptr, value, num); } + +void * +platform_memcpy(void *dst, const void *src, uint64_t num) +{ return memcpy(dst, src, num); } + +int64_t +platform_num_cpus(void) +{ return 1; } + +int64_t +platform_call_vmm_on_core( + uint64_t cpuid, uint64_t request, uintptr_t arg1, uintptr_t arg2) +{ + return common_call_vmm(cpuid, request, arg1, arg2); +} + +void * +platform_get_rsdp(void) +{ return 0; } diff --git a/payloads/external/Makefile.inc b/payloads/external/Makefile.inc index 9c34efabeb0..902454e731a 100644 --- a/payloads/external/Makefile.inc +++ b/payloads/external/Makefile.inc @@ -47,6 +47,17 @@ ifneq ($(strip $(call strip_quotes,$(CONFIG_PAYLOAD_OPTIONS))),) ADDITIONAL_PAYLOAD_CONFIG+=$(strip $(call strip_quotes,$(CONFIG_PAYLOAD_OPTIONS))) endif +ifeq ($(CONFIG_BAREFLANK_SECONDARY_PAYLOAD),y) +cbfs-files-y += $(CONFIG_CBFS_PREFIX)/realpayload +$(CONFIG_CBFS_PREFIX)/realpayload-file := $(CONFIG_PAYLOAD_FILE) +ifeq ($(CONFIG_PAYLOAD_IS_FLAT_BINARY),y) +$(CONFIG_CBFS_PREFIX)/realpayload-type := flat-binary +else +$(CONFIG_CBFS_PREFIX)/realpayload-type := payload +endif +$(CONFIG_CBFS_PREFIX)/realpayload-compression := $(CBFS_PAYLOAD_COMPRESS_FLAG) +$(CONFIG_CBFS_PREFIX)/realpayload-options := $(ADDITIONAL_PAYLOAD_CONFIG) +else cbfs-files-y += $(CONFIG_CBFS_PREFIX)/payload $(CONFIG_CBFS_PREFIX)/payload-file := $(CONFIG_PAYLOAD_FILE) ifeq ($(CONFIG_PAYLOAD_IS_FLAT_BINARY),y) @@ -56,6 +67,7 @@ $(CONFIG_CBFS_PREFIX)/payload-type := payload endif $(CONFIG_CBFS_PREFIX)/payload-compression := $(CBFS_PAYLOAD_COMPRESS_FLAG) $(CONFIG_CBFS_PREFIX)/payload-options := $(ADDITIONAL_PAYLOAD_CONFIG) +endif cbfs-files-$(CONFIG_INCLUDE_CONFIG_FILE) += payload_config payload_config-file := $(PAYLOAD_CONFIG) From 6ce3d95786e36b53d6bb47a296e9410ddc1d9155 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Wed, 15 May 2019 16:34:46 +0200 Subject: [PATCH 587/588] mmax.config: config file for building 64-bit test image Signed-off-by: Krystian Hebel --- mmax.config | 762 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 762 insertions(+) create mode 100644 mmax.config diff --git a/mmax.config b/mmax.config new file mode 100644 index 00000000000..cde9d01b503 --- /dev/null +++ b/mmax.config @@ -0,0 +1,762 @@ +# +# Automatically generated file; DO NOT EDIT. +# coreboot configuration +# + +# +# General setup +# +CONFIG_COREBOOT_BUILD=y +CONFIG_LOCALVERSION="" +CONFIG_CBFS_PREFIX="fallback" +CONFIG_COMPILER_GCC=y +# CONFIG_COMPILER_LLVM_CLANG is not set +# CONFIG_ANY_TOOLCHAIN is not set +# CONFIG_CCACHE is not set +# CONFIG_FMD_GENPARSER is not set +# CONFIG_UTIL_GENPARSER is not set +# CONFIG_USE_OPTION_TABLE is not set +CONFIG_COMPRESS_RAMSTAGE=y +CONFIG_INCLUDE_CONFIG_FILE=y +CONFIG_COLLECT_TIMESTAMPS=y +# CONFIG_TIMESTAMPS_ON_CONSOLE is not set +# CONFIG_USE_BLOBS is not set +# CONFIG_COVERAGE is not set +# CONFIG_UBSAN is not set +CONFIG_NO_RELOCATABLE_RAMSTAGE=y +# CONFIG_RELOCATABLE_RAMSTAGE is not set +# CONFIG_UPDATE_IMAGE is not set +# CONFIG_BOOTSPLASH_IMAGE is not set +# CONFIG_RAMPAYLOAD is not set + +# +# Mainboard +# + +# +# Important: Run 'make distclean' before switching boards +# +# CONFIG_VENDOR_ADI is not set +# CONFIG_VENDOR_ADLINK is not set +# CONFIG_VENDOR_ADVANSUS is not set +# CONFIG_VENDOR_AMD is not set +# CONFIG_VENDOR_AOPEN is not set +# CONFIG_VENDOR_APPLE is not set +# CONFIG_VENDOR_ASROCK is not set +# CONFIG_VENDOR_ASUS is not set +# CONFIG_VENDOR_AVALUE is not set +# CONFIG_VENDOR_BAP is not set +# CONFIG_VENDOR_BIOSTAR is not set +# CONFIG_VENDOR_CAVIUM is not set +# CONFIG_VENDOR_COMPULAB is not set +# CONFIG_VENDOR_CUBIETECH is not set +# CONFIG_VENDOR_ELMEX is not set +# CONFIG_VENDOR_EMULATION is not set +# CONFIG_VENDOR_ESD is not set +# CONFIG_VENDOR_FACEBOOK is not set +# CONFIG_VENDOR_FOXCONN is not set +# CONFIG_VENDOR_GETAC is not set +# CONFIG_VENDOR_GIGABYTE is not set +# CONFIG_VENDOR_GIZMOSPHERE is not set +# CONFIG_VENDOR_GOOGLE is not set +# CONFIG_VENDOR_HP is not set +# CONFIG_VENDOR_IBASE is not set +# CONFIG_VENDOR_IEI is not set +CONFIG_VENDOR_INTEL=y +# CONFIG_VENDOR_JETWAY is not set +# CONFIG_VENDOR_KONTRON is not set +# CONFIG_VENDOR_LENOVO is not set +# CONFIG_VENDOR_LIPPERT is not set +# CONFIG_VENDOR_MSI is not set +# CONFIG_VENDOR_OCP is not set +# CONFIG_VENDOR_OPENCELLULAR is not set +# CONFIG_VENDOR_PACKARDBELL is not set +# CONFIG_VENDOR_PCENGINES is not set +# CONFIG_VENDOR_PURISM is not set +# CONFIG_VENDOR_RODA is not set +# CONFIG_VENDOR_SAMSUNG is not set +# CONFIG_VENDOR_SAPPHIRE is not set +# CONFIG_VENDOR_SCALEWAY is not set +# CONFIG_VENDOR_SIEMENS is not set +# CONFIG_VENDOR_SIFIVE is not set +# CONFIG_VENDOR_SUPERMICRO is not set +# CONFIG_VENDOR_TI is not set +# CONFIG_VENDOR_TYAN is not set +# CONFIG_VENDOR_VIA is not set +CONFIG_BOARD_SPECIFIC_OPTIONS=y +CONFIG_MAINBOARD_DIR="intel/minnowmax" +CONFIG_MAINBOARD_PART_NUMBER="Minnow Max" +CONFIG_MAX_CPUS=16 +CONFIG_FSP_FILE="3rdparty/blobs/mainboard/$(MAINBOARDDIR)/fsp.fd" +CONFIG_CBFS_SIZE=0x00600000 +CONFIG_ENABLE_FSP_FAST_BOOT=y +CONFIG_VIRTUAL_ROM_SIZE=0x800000 +CONFIG_UART_FOR_CONSOLE=0 +CONFIG_PAYLOAD_CONFIGFILE="" +CONFIG_MAINBOARD_VENDOR="Intel" +CONFIG_VGA_BIOS_ID="8086,0f31" +# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set +CONFIG_DIMM_SPD_SIZE=256 +CONFIG_VGA_BIOS=y +CONFIG_MAINBOARD_SERIAL_NUMBER="123456789" +CONFIG_VGA_BIOS_FILE="3rdparty/blobs/mainboard/$(MAINBOARDDIR)/vga.dat" +CONFIG_C_ENV_BOOTBLOCK_SIZE=0x10000 +CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Intel" +CONFIG_DEVICETREE="devicetree.cb" +CONFIG_PRERAM_CBMEM_CONSOLE_SIZE=0xc00 +CONFIG_POST_IO=y +CONFIG_DCACHE_RAM_BASE=0xfef00000 +CONFIG_DCACHE_RAM_SIZE=0x4000 +CONFIG_MAX_REBOOT_CNT=3 +CONFIG_OVERRIDE_DEVICETREE="" +CONFIG_BOOT_DEVICE_SPI_FLASH_BUS=0 +CONFIG_FMDFILE="" +CONFIG_MMCONF_BASE_ADDRESS=0xe0000000 +CONFIG_HAVE_INTEL_FIRMWARE=y +# CONFIG_POST_DEVICE is not set +CONFIG_DRIVERS_UART_8250IO=y +# CONFIG_VBOOT is not set +CONFIG_DIMM_MAX=4 +CONFIG_TTYS0_LCS=3 +# CONFIG_BOARD_INTEL_APOLLOLAKE_RVP1 is not set +# CONFIG_BOARD_INTEL_APOLLOLAKE_RVP2 is not set +# CONFIG_BOARD_INTEL_BASKING_RIDGE is not set +# CONFIG_BOARD_INTEL_BAKERSPORT_FSP is not set +# CONFIG_BOARD_INTEL_BAYLEYBAY_FSP is not set +# CONFIG_BOARD_INTEL_CAMELBACKMOUNTAIN_FSP is not set +# CONFIG_BOARD_INTEL_CANNONLAKE_RVPU is not set +# CONFIG_BOARD_INTEL_CANNONLAKE_RVPY is not set + +# +# Coffeelake RVP +# +# CONFIG_BOARD_INTEL_COFFEELAKE_RVPU is not set +# CONFIG_BOARD_INTEL_COFFEELAKE_RVP11 is not set +# CONFIG_BOARD_INTEL_WHISKEYLAKE_RVP is not set +# CONFIG_BOARD_INTEL_COFFEELAKE_RVP8 is not set +# CONFIG_BOARD_INTEL_COMETLAKE_RVP is not set +# CONFIG_BOARD_INTEL_D510MO is not set +# CONFIG_BOARD_INTEL_D945GCLF is not set +# CONFIG_BOARD_INTEL_DCP847SKE is not set +# CONFIG_BOARD_INTEL_DG41WV is not set +# CONFIG_BOARD_INTEL_DG43GT is not set +# CONFIG_BOARD_INTEL_EMERALDLAKE2 is not set +# CONFIG_BOARD_INTEL_GALILEO is not set +# CONFIG_BOARD_INTEL_GLKRVP is not set +# CONFIG_BOARD_INTEL_HARCUVAR is not set +# CONFIG_BOARD_INTEL_ICELAKE_RVPU is not set +# CONFIG_BOARD_INTEL_ICELAKE_RVPY is not set +# CONFIG_BOARD_INTEL_KBLRVP3 is not set +# CONFIG_BOARD_INTEL_KBLRVP7 is not set +# CONFIG_BOARD_INTEL_KBLRVP8 is not set +# CONFIG_BOARD_INTEL_KBLRVP11 is not set +# CONFIG_BOARD_INTEL_KUNIMITSU is not set +# CONFIG_BOARD_INTEL_LEAFHILL is not set +# CONFIG_BOARD_INTEL_LITTLEPLAINS is not set +# CONFIG_BOARD_INTEL_MINNOW3 is not set +CONFIG_BOARD_INTEL_MINNOWMAX=y +# CONFIG_BOARD_INTEL_MOHONPEAK is not set +# CONFIG_BOARD_INTEL_SKLSDLBRK is not set +# CONFIG_BOARD_INTEL_STRAGO is not set +# CONFIG_BOARD_INTEL_WTM2 is not set +CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="Minnow Max" +# CONFIG_BOARD_INTEL_BASEBOARD_GLKRVP is not set +CONFIG_IFD_BIN_PATH="3rdparty/blobs/mainboard/$(MAINBOARDDIR)/descriptor.bin" +CONFIG_ME_BIN_PATH="3rdparty/blobs/mainboard/$(MAINBOARDDIR)/txe.bin" +CONFIG_HAVE_IFD_BIN=y +CONFIG_CPU_ADDR_BITS=36 +CONFIG_DEFAULT_CONSOLE_LOGLEVEL=7 +CONFIG_FSP_LOC=0xfffc0000 +CONFIG_MAINBOARD_VERSION="1.0" +# CONFIG_DRIVERS_PS2_KEYBOARD is not set +# CONFIG_PCIEXP_L1_SUB_STATE is not set +CONFIG_SMBIOS_ENCLOSURE_TYPE=0x03 +CONFIG_HEAP_SIZE=0x4000 +CONFIG_BOARD_ROMSIZE_KB_8192=y +# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_2048 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set +CONFIG_COREBOOT_ROMSIZE_KB_8192=y +# CONFIG_COREBOOT_ROMSIZE_KB_10240 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_32768 is not set +# CONFIG_COREBOOT_ROMSIZE_KB_65536 is not set +CONFIG_COREBOOT_ROMSIZE_KB=8192 +CONFIG_ROM_SIZE=0x800000 +# CONFIG_SYSTEM_TYPE_LAPTOP is not set +# CONFIG_SYSTEM_TYPE_TABLET is not set +# CONFIG_SYSTEM_TYPE_DETACHABLE is not set +# CONFIG_SYSTEM_TYPE_CONVERTIBLE is not set +# CONFIG_CBFS_AUTOGEN_ATTRIBUTES is not set + +# +# Chipset +# + +# +# SoC +# +CONFIG_CPU_SPECIFIC_OPTIONS=y +CONFIG_SMM_TSEG_SIZE=0x800000 +CONFIG_SMM_RESERVED_SIZE=0x100000 +CONFIG_SMM_MODULE_STACK_SIZE=0x400 +CONFIG_ACPI_CPU_STRING="\\_PR.CP%02d" +# CONFIG_SOC_CAVIUM_CN81XX is not set +CONFIG_ARCH_ARMV8_EXTENSION=0 +CONFIG_STACK_SIZE=0x1000 +# CONFIG_SOC_CAVIUM_COMMON is not set +CONFIG_BOOTBLOCK_CPU_INIT="soc/intel/fsp_baytrail/bootblock/bootblock.c" +# CONFIG_SOC_INTEL_GLK is not set +CONFIG_X86_TOP4G_BOOTMEDIA_MAP=y +CONFIG_ROMSTAGE_ADDR=0x2000000 +CONFIG_VERSTAGE_ADDR=0x2000000 +CONFIG_FSP_HEADER_PATH="" +CONFIG_SPI_FLASH_INCLUDE_ALL_DRIVERS=y +CONFIG_ENABLE_BUILTIN_COM1=y +# CONFIG_PCIEXP_ASPM is not set +# CONFIG_PCIEXP_COMMON_CLOCK is not set +# CONFIG_PCIEXP_CLK_PM is not set +CONFIG_TTYS0_BASE=0x3f8 +# CONFIG_SOC_INTEL_COMMON_CANNONLAKE_BASE is not set +# CONFIG_SOC_INTEL_COFFEELAKE is not set +# CONFIG_SOC_INTEL_WHISKEYLAKE is not set +# CONFIG_SOC_INTEL_COMETLAKE is not set +# CONFIG_SOC_INTEL_CANNONLAKE_PCH_H is not set +CONFIG_SOC_INTEL_FSP_BAYTRAIL=y +# CONFIG_SOC_INTEL_FSP_BAYTRAIL_MD is not set +CONFIG_CPU_MICROCODE_HEADER_FILES="3rdparty/blobs/mainboard/$(MAINBOARDDIR)/M0130673324.h 3rdparty/blobs/mainboard/$(MAINBOARDDIR)/M0130679901.h" +CONFIG_BAYTRAIL_FSP_SPECIFIC_OPTIONS=y +CONFIG_CONSOLE_CBMEM=y +CONFIG_FSP_SRC_PATH="" +CONFIG_UART_PCI_ADDR=0x0 +# CONFIG_SOC_INTEL_KABYLAKE is not set +# CONFIG_SOC_MEDIATEK_MT8173 is not set +# CONFIG_SOC_MEDIATEK_MT8183 is not set +# CONFIG_SOC_NVIDIA_TEGRA124 is not set +# CONFIG_SOC_NVIDIA_TEGRA210 is not set +# CONFIG_QC_SDI_ENABLE is not set +# CONFIG_SOC_QC_IPQ40XX is not set +# CONFIG_SOC_QC_IPQ806X is not set +# CONFIG_SOC_QUALCOMM_QCS405 is not set +# CONFIG_SOC_QUALCOMM_SDM845 is not set +# CONFIG_SOC_ROCKCHIP_RK3288 is not set +# CONFIG_SOC_ROCKCHIP_RK3399 is not set +# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set +# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set +# CONFIG_SOC_UCB_RISCV is not set + +# +# CPU +# +# CONFIG_CPU_ALLWINNER_A10 is not set +CONFIG_XIP_ROM_SIZE=0x10000 +CONFIG_NUM_IPI_STARTS=2 +# CONFIG_CPU_AMD_AGESA is not set +CONFIG_ENABLE_MRC_CACHE=y +# CONFIG_CPU_AMD_PI is not set +# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set +CONFIG_SSE2=y +# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set +# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set +# CONFIG_CPU_TI_AM335X is not set +# CONFIG_PARALLEL_CPU_INIT is not set +CONFIG_PARALLEL_MP=y +# CONFIG_PARALLEL_MP_AP_WORK is not set +# CONFIG_UDELAY_IO is not set +# CONFIG_UDELAY_LAPIC is not set +CONFIG_UDELAY_TSC=y +CONFIG_TSC_CONSTANT_RATE=y +CONFIG_TSC_MONOTONIC_TIMER=y +# CONFIG_UDELAY_TIMER2 is not set +# CONFIG_TSC_SYNC_LFENCE is not set +CONFIG_TSC_SYNC_MFENCE=y +# CONFIG_NO_FIXED_XIP_ROM_SIZE is not set +CONFIG_LOGICAL_CPUS=y +CONFIG_SMM_TSEG=y +CONFIG_SMM_MODULE_HEAP_SIZE=0x4000 +CONFIG_SMM_STUB_STACK_SIZE=0x400 +# CONFIG_SMM_LAPIC_REMAP_MITIGATION is not set +# CONFIG_SERIALIZED_SMM_INITIALIZATION is not set +# CONFIG_X86_AMD_FIXED_MTRRS is not set +CONFIG_PLATFORM_USES_FSP1_0=y +# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set +# CONFIG_SOC_SETS_MSRS is not set +CONFIG_CACHE_AS_RAM=y +# CONFIG_NO_CAR_GLOBAL_MIGRATION is not set +CONFIG_SMP=y +CONFIG_SSE=y +CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y +CONFIG_USES_MICROCODE_HEADER_FILES=y +CONFIG_MICROCODE_BLOB_NOT_HOOKED_UP=y +# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_BINS is not set +CONFIG_CPU_MICROCODE_CBFS_EXTERNAL_HEADER=y +# CONFIG_CPU_MICROCODE_CBFS_NONE is not set + +# +# Northbridge +# +# CONFIG_NORTHBRIDGE_AMD_AGESA is not set +# CONFIG_NORTHBRIDGE_AMD_PI is not set +CONFIG_MAX_PIRQ_LINKS=4 + +# +# Southbridge +# +# CONFIG_AMD_SB_CIMX is not set +# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set +# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON is not set +CONFIG_SOUTHBRIDGE_INTEL_COMMON_RESET=y +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_GPIO is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMBUS is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SPI is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_PIRQ_ACPI_GEN is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_RCBA_PIRQ is not set +# CONFIG_HAVE_INTEL_CHIPSET_LOCKDOWN is not set +# CONFIG_SOUTHBRIDGE_INTEL_COMMON_SMM is not set +CONFIG_INTEL_DESCRIPTOR_MODE_CAPABLE=y +CONFIG_INTEL_DESCRIPTOR_MODE_REQUIRED=y + +# +# Super I/O +# +# CONFIG_SUPERIO_NUVOTON_NCT6776_COM_A is not set + +# +# Embedded Controllers +# +# CONFIG_EC_GOOGLE_WILCO is not set +CONFIG_EC_BASE_ACPI_DATA=0x930 +CONFIG_EC_BASE_ACPI_COMMAND=0x934 +CONFIG_EC_BASE_HOST_DATA=0x940 +CONFIG_EC_BASE_HOST_COMMAND=0x944 +CONFIG_EC_BASE_PACKET=0x950 +CONFIG_SEABIOS_PS2_TIMEOUT=0 + +# +# Intel Firmware +# +CONFIG_HAVE_ME_BIN=y +# CONFIG_MAINBOARD_USES_IFD_GBE_REGION is not set +# CONFIG_MAINBOARD_USES_IFD_EC_REGION is not set +# CONFIG_DO_NOT_TOUCH_DESCRIPTOR_REGION is not set +# CONFIG_LOCK_MANAGEMENT_ENGINE is not set +CONFIG_UNLOCK_FLASH_REGIONS=y +# CONFIG_CAVIUM_BDK is not set +# CONFIG_MAINBOARD_HAS_CHROMEOS is not set +# CONFIG_GOOGLE_SMBIOS_MAINBOARD_VERSION is not set +CONFIG_FSP_VENDORCODE_HEADER_PATH="fsp1_0/baytrail" +# CONFIG_UEFI_2_4_BINDING is not set +# CONFIG_UDK_2015_BINDING is not set +# CONFIG_UDK_2017_BINDING is not set +CONFIG_UDK_2013_VERSION=2013 +CONFIG_UDK_2015_VERSION=2015 +CONFIG_UDK_2017_VERSION=2017 +CONFIG_UDK_VERSION=2013 +# CONFIG_USE_SIEMENS_HWILIB is not set +# CONFIG_ARCH_ARM is not set +# CONFIG_ARCH_BOOTBLOCK_ARM is not set +# CONFIG_ARCH_VERSTAGE_ARM is not set +# CONFIG_ARCH_ROMSTAGE_ARM is not set +# CONFIG_ARCH_RAMSTAGE_ARM is not set +# CONFIG_ARCH_BOOTBLOCK_ARMV4 is not set +# CONFIG_ARCH_VERSTAGE_ARMV4 is not set +# CONFIG_ARCH_ROMSTAGE_ARMV4 is not set +# CONFIG_ARCH_RAMSTAGE_ARMV4 is not set +# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set +# CONFIG_ARCH_VERSTAGE_ARMV7 is not set +# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set +# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set +# CONFIG_ARCH_BOOTBLOCK_ARMV7_M is not set +# CONFIG_ARCH_VERSTAGE_ARMV7_M is not set +# CONFIG_ARCH_BOOTBLOCK_ARMV7_R is not set +# CONFIG_ARCH_VERSTAGE_ARMV7_R is not set +# CONFIG_ARCH_ROMSTAGE_ARMV7_R is not set +# CONFIG_ARCH_RAMSTAGE_ARMV7_R is not set +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_ARM64 is not set +# CONFIG_ARCH_BOOTBLOCK_ARM64 is not set +# CONFIG_ARCH_VERSTAGE_ARM64 is not set +# CONFIG_ARCH_ROMSTAGE_ARM64 is not set +# CONFIG_ARCH_RAMSTAGE_ARM64 is not set +# CONFIG_ARCH_BOOTBLOCK_ARMV8_64 is not set +# CONFIG_ARCH_VERSTAGE_ARMV8_64 is not set +# CONFIG_ARCH_ROMSTAGE_ARMV8_64 is not set +# CONFIG_ARCH_RAMSTAGE_ARMV8_64 is not set +# CONFIG_ARM64_USE_ARCH_TIMER is not set +# CONFIG_ARM64_A53_ERRATUM_843419 is not set +# CONFIG_ARCH_MIPS is not set +# CONFIG_ARCH_BOOTBLOCK_MIPS is not set +# CONFIG_ARCH_VERSTAGE_MIPS is not set +# CONFIG_ARCH_ROMSTAGE_MIPS is not set +# CONFIG_ARCH_RAMSTAGE_MIPS is not set +# CONFIG_ARCH_PPC64 is not set +# CONFIG_ARCH_BOOTBLOCK_PPC64 is not set +# CONFIG_ARCH_VERSTAGE_PPC64 is not set +# CONFIG_ARCH_ROMSTAGE_PPC64 is not set +# CONFIG_ARCH_RAMSTAGE_PPC64 is not set +# CONFIG_ARCH_RISCV is not set +CONFIG_ARCH_RISCV_M=y +# CONFIG_ARCH_RISCV_S is not set +# CONFIG_ARCH_RISCV_U is not set +# CONFIG_ARCH_RISCV_RV64 is not set +# CONFIG_ARCH_RISCV_RV32 is not set +# CONFIG_ARCH_RISCV_PMP is not set +# CONFIG_ARCH_BOOTBLOCK_RISCV is not set +# CONFIG_ARCH_VERSTAGE_RISCV is not set +# CONFIG_ARCH_ROMSTAGE_RISCV is not set +# CONFIG_ARCH_RAMSTAGE_RISCV is not set +# CONFIG_RISCV_USE_ARCH_TIMER is not set +CONFIG_ARCH_X86=y +CONFIG_ARCH_BOOTBLOCK_X86_32=y +CONFIG_ARCH_VERSTAGE_X86_32=y +CONFIG_ARCH_ROMSTAGE_X86_32=y +# CONFIG_ARCH_POSTCAR_X86_32 is not set +CONFIG_ARCH_RAMSTAGE_X86_32=y +# CONFIG_ARCH_BOOTBLOCK_X86_64 is not set +# CONFIG_ARCH_VERSTAGE_X86_64 is not set +# CONFIG_ARCH_ROMSTAGE_X86_64 is not set +# CONFIG_ARCH_POSTCAR_X86_64 is not set +# CONFIG_ARCH_RAMSTAGE_X86_64 is not set +# CONFIG_USE_MARCH_586 is not set +# CONFIG_AP_IN_SIPI_WAIT is not set +# CONFIG_SIPI_VECTOR_IN_ROM is not set +CONFIG_RAMBASE=0xe00000 +CONFIG_RAMTOP=0x1000000 +# CONFIG_CBMEM_TOP_BACKUP is not set +# CONFIG_EARLY_EBDA_INIT is not set +CONFIG_PC80_SYSTEM=y +# CONFIG_BOOTBLOCK_DEBUG_SPINLOOP is not set +# CONFIG_BOOTBLOCK_SAVE_BIST_AND_TIMESTAMP is not set +# CONFIG_HAVE_CMOS_DEFAULT is not set +CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y +# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set +# CONFIG_HPET_ADDRESS_OVERRIDE is not set +CONFIG_HPET_ADDRESS=0xfed00000 +CONFIG_ID_SECTION_OFFSET=0x80 +# CONFIG_POSTCAR_STAGE is not set +# CONFIG_VERSTAGE_DEBUG_SPINLOOP is not set +# CONFIG_ROMSTAGE_DEBUG_SPINLOOP is not set +CONFIG_BOOTBLOCK_SIMPLE=y +# CONFIG_BOOTBLOCK_NORMAL is not set +CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c" +CONFIG_ACPI_HAVE_PCAT_8259=y +# CONFIG_COLLECT_TIMESTAMPS_NO_TSC is not set +CONFIG_COLLECT_TIMESTAMPS_TSC=y +# CONFIG_PAGING_IN_CACHE_AS_RAM is not set +# CONFIG_IDT_IN_EVERY_STAGE is not set +CONFIG_HAVE_CF9_RESET=y + +# +# Devices +# +# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT is not set +# CONFIG_MAINBOARD_HAS_LIBGFXINIT is not set +# CONFIG_VGA_ROM_RUN is not set +CONFIG_NO_GFX_INIT=y +# CONFIG_MULTIPLE_VGA_ADAPTERS is not set +# CONFIG_SMBUS_HAS_AUX_CHANNELS is not set +CONFIG_PCI=y +# CONFIG_NO_MMCONF_SUPPORT is not set +CONFIG_MMCONF_SUPPORT=y +# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set +CONFIG_PCIX_PLUGIN_SUPPORT=y +CONFIG_CARDBUS_PLUGIN_SUPPORT=y +# CONFIG_AZALIA_PLUGIN_SUPPORT is not set +CONFIG_PCIEXP_PLUGIN_SUPPORT=y +# CONFIG_EARLY_PCI_BRIDGE is not set +CONFIG_SUBSYSTEM_VENDOR_ID=0x0000 +CONFIG_SUBSYSTEM_DEVICE_ID=0x0000 +# CONFIG_VGA_BIOS_DGPU is not set +# CONFIG_SOFTWARE_I2C is not set + +# +# Generic Drivers +# +# CONFIG_DRIVERS_AS3722_RTC is not set +# CONFIG_GIC is not set +# CONFIG_IPMI_KCS is not set +# CONFIG_DRIVERS_LENOVO_WACOM is not set +# CONFIG_RT8168_GET_MAC_FROM_VPD is not set +# CONFIG_RT8168_SET_LED_MODE is not set +# CONFIG_SMMSTORE_IN_CBFS is not set +CONFIG_SPI_FLASH=y +CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP=y +# CONFIG_BOOT_DEVICE_SPI_FLASH_RW_NOMMAP_EARLY is not set +# CONFIG_SPI_FLASH_NO_FAST_READ is not set +CONFIG_SPI_FLASH_ADESTO=y +CONFIG_SPI_FLASH_AMIC=y +CONFIG_SPI_FLASH_ATMEL=y +CONFIG_SPI_FLASH_EON=y +CONFIG_SPI_FLASH_GIGADEVICE=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_SST=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_FAST_READ_DUAL_OUTPUT_3B is not set +# CONFIG_SPI_FLASH_HAS_VOLATILE_GROUP is not set +CONFIG_HAVE_SPI_CONSOLE_SUPPORT=y +CONFIG_DRIVERS_UART=y +# CONFIG_DRIVERS_UART_8250IO_SKIP_INIT is not set +# CONFIG_NO_UART_ON_SUPERIO is not set +# CONFIG_UART_OVERRIDE_INPUT_CLOCK_DIVIDER is not set +# CONFIG_UART_OVERRIDE_REFCLK is not set +# CONFIG_DRIVERS_UART_8250MEM is not set +# CONFIG_DRIVERS_UART_8250MEM_32 is not set +# CONFIG_HAVE_UART_SPECIAL is not set +# CONFIG_DRIVERS_UART_OXPCIE is not set +# CONFIG_DRIVERS_UART_PL011 is not set +# CONFIG_UART_USE_REFCLK_AS_INPUT_CLOCK is not set +# CONFIG_HAVE_USBDEBUG is not set +# CONFIG_HAVE_USBDEBUG_OPTIONS is not set +# CONFIG_VPD is not set +# CONFIG_DRIVERS_AMD_PI is not set +# CONFIG_SMBIOS_PROVIDED_BY_MOBO is not set +# CONFIG_DRIVERS_I2C_MAX98373 is not set +# CONFIG_DRIVERS_I2C_MAX98927 is not set +# CONFIG_DRIVERS_I2C_PCA9538 is not set +# CONFIG_DRIVERS_I2C_PCF8523 is not set +# CONFIG_DRIVERS_I2C_RT5663 is not set +# CONFIG_DRIVERS_I2C_RTD2132 is not set +# CONFIG_DRIVERS_I2C_RX6110SA is not set +# CONFIG_DRIVERS_I2C_SX9310 is not set +# CONFIG_MAINBOARD_HAS_I2C_TPM_ATMEL is not set +# CONFIG_MAINBOARD_HAS_I2C_TPM_CR50 is not set +# CONFIG_MAINBOARD_HAS_I2C_TPM_GENERIC is not set + +# +# Intel FSP +# +CONFIG_HAVE_FSP_BIN=y +CONFIG_MRC_CACHE_FMAP=y +CONFIG_USE_GENERIC_FSP_CAR_INC=y +CONFIG_FSP_USES_UPD=y +# CONFIG_PLATFORM_USES_FSP2_0 is not set +# CONFIG_PLATFORM_USES_FSP2_1 is not set +# CONFIG_INTEL_DDI is not set +# CONFIG_INTEL_EDID is not set +# CONFIG_INTEL_INT15 is not set +# CONFIG_INTEL_GMA_ACPI is not set +# CONFIG_INTEL_GMA_SSC_ALTERNATE_REF is not set +# CONFIG_INTEL_GMA_SWSMISCI is not set +# CONFIG_DRIVER_INTEL_I210 is not set +# CONFIG_DRIVERS_INTEL_MIPI_CAMERA is not set +CONFIG_DRIVERS_INTEL_WIFI=y +# CONFIG_USE_SAR is not set +# CONFIG_DRIVERS_LENOVO_HYBRID_GRAPHICS is not set +# CONFIG_DRIVER_MAXIM_MAX77686 is not set +# CONFIG_DRIVER_PARADE_PS8625 is not set +# CONFIG_DRIVER_PARADE_PS8640 is not set +CONFIG_DRIVERS_MC146818=y +# CONFIG_LPC_TPM is not set +# CONFIG_MAINBOARD_HAS_LPC_TPM is not set +# CONFIG_DRIVERS_RICOH_RCE822 is not set +# CONFIG_DRIVER_SIEMENS_NC_FPGA is not set +# CONFIG_NC_FPGA_NOTIFY_CB_READY is not set +# CONFIG_DRIVERS_SIL_3114 is not set +# CONFIG_MAINBOARD_HAS_SPI_TPM_CR50 is not set +# CONFIG_DRIVER_TI_TPS65090 is not set +# CONFIG_DRIVERS_TI_TPS65913 is not set +# CONFIG_DRIVERS_TI_TPS65913_RTC is not set +# CONFIG_DRIVERS_USB_ACPI is not set +# CONFIG_DRIVER_XPOWERS_AXP209 is not set +# CONFIG_COMMONLIB_STORAGE is not set + +# +# Security +# + +# +# Verified Boot (vboot) +# + +# +# Trusted Platform Module +# +CONFIG_USER_NO_TPM=y +# CONFIG_ACPI_SATA_GENERATOR is not set +CONFIG_ACPI_INTEL_HARDWARE_SLEEP_VALUES=y +# CONFIG_ACPI_AMD_HARDWARE_SLEEP_VALUES is not set +# CONFIG_BOOT_DEVICE_NOT_SPI_FLASH is not set +CONFIG_BOOT_DEVICE_SPI_FLASH=y +CONFIG_BOOT_DEVICE_MEMORY_MAPPED=y +# CONFIG_BOOT_DEVICE_SUPPORTS_WRITES is not set +# CONFIG_RTC is not set + +# +# Console +# +CONFIG_SQUELCH_EARLY_SMP=y +CONFIG_CONSOLE_SERIAL=y + +# +# I/O mapped, 8250-compatible +# + +# +# Serial port base address = 0x3f8 +# +# CONFIG_CONSOLE_SERIAL_921600 is not set +# CONFIG_CONSOLE_SERIAL_460800 is not set +# CONFIG_CONSOLE_SERIAL_230400 is not set +CONFIG_CONSOLE_SERIAL_115200=y +# CONFIG_CONSOLE_SERIAL_57600 is not set +# CONFIG_CONSOLE_SERIAL_38400 is not set +# CONFIG_CONSOLE_SERIAL_19200 is not set +# CONFIG_CONSOLE_SERIAL_9600 is not set +CONFIG_TTYS0_BAUD=115200 +# CONFIG_SPKMODEM is not set +# CONFIG_CONSOLE_NE2K is not set +CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x20000 +# CONFIG_CONSOLE_SPI_FLASH is not set +# CONFIG_SPI_CONSOLE is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8 is not set +CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7=y +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set +# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set +# CONFIG_NO_POST is not set +# CONFIG_CMOS_POST is not set +# CONFIG_CONSOLE_POST is not set +CONFIG_POST_IO_PORT=0x80 +# CONFIG_NO_EARLY_BOOTBLOCK_POSTCODES is not set +CONFIG_HWBASE_DEBUG_CB=y +# CONFIG_HAVE_ACPI_RESUME is not set +# CONFIG_ACPI_HUGE_LOWMEM_BACKUP is not set +# CONFIG_HAVE_ROMSTAGE_CONSOLE_SPINLOCK is not set +# CONFIG_HAVE_ROMSTAGE_NVRAM_CBFS_SPINLOCK is not set +# CONFIG_HAVE_ROMSTAGE_MICROCODE_CBFS_SPINLOCK is not set +CONFIG_HAVE_MONOTONIC_TIMER=y +# CONFIG_GENERIC_UDELAY is not set +# CONFIG_TIMER_QUEUE is not set +CONFIG_HAVE_OPTION_TABLE=y +# CONFIG_PIRQ_ROUTE is not set +CONFIG_HAVE_SMI_HANDLER=y +# CONFIG_PCI_IO_CFG_EXT is not set +# CONFIG_IOAPIC is not set +# CONFIG_USE_WATCHDOG_ON_BOOT is not set +# CONFIG_GFXUMA is not set +CONFIG_HAVE_ACPI_TABLES=y +# CONFIG_COMMON_FADT is not set +# CONFIG_ACPI_NHLT is not set + +# +# System tables +# +# CONFIG_GENERATE_MP_TABLE is not set +# CONFIG_GENERATE_PIRQ_TABLE is not set +CONFIG_GENERATE_SMBIOS_TABLES=y + +# +# Payload +# +# CONFIG_PAYLOAD_NONE is not set +# CONFIG_PAYLOAD_ELF is not set +# CONFIG_PAYLOAD_BAYOU is not set +# CONFIG_PAYLOAD_FILO is not set +# CONFIG_PAYLOAD_GRUB2 is not set +# CONFIG_PAYLOAD_LINUXBOOT is not set +CONFIG_PAYLOAD_SEABIOS=y +# CONFIG_PAYLOAD_UBOOT is not set +# CONFIG_PAYLOAD_YABITS is not set +# CONFIG_PAYLOAD_LINUX is not set +# CONFIG_PAYLOAD_TIANOCORE is not set +CONFIG_PAYLOAD_FILE="payloads/external/SeaBIOS/seabios/out/bios.bin.elf" +CONFIG_SEABIOS_STABLE=y +# CONFIG_SEABIOS_MASTER is not set +# CONFIG_SEABIOS_REVISION is not set +# CONFIG_SEABIOS_THREAD_OPTIONROMS is not set +CONFIG_SEABIOS_BOOTORDER_FILE="" +CONFIG_SEABIOS_ADD_SERCON_PORT_FILE=y +CONFIG_SEABIOS_SERCON_PORT_ADDR=0x3f8 +CONFIG_SEABIOS_DEBUG_LEVEL=-1 + +# +# Using default SeaBIOS log level +# +CONFIG_PAYLOAD_OPTIONS="" +CONFIG_PXE=y + +# +# PXE Options +# +# CONFIG_PXE_ROM is not set +CONFIG_BUILD_IPXE=y +CONFIG_IPXE_STABLE=y +# CONFIG_IPXE_MASTER is not set +CONFIG_PXE_ROM_ID="8086,1539" +CONFIG_PXE_SERIAL_CONSOLE=y +CONFIG_COMPRESSED_PAYLOAD_LZMA=y +# CONFIG_COMPRESSED_PAYLOAD_LZ4 is not set +# CONFIG_PAYLOAD_IS_FLAT_BINARY is not set +CONFIG_COMPRESS_SECONDARY_PAYLOAD=y + +# +# Secondary Payloads +# +CONFIG_COREINFO_SECONDARY_PAYLOAD=y +CONFIG_BAREFLANK_SECONDARY_PAYLOAD=y +CONFIG_MEMTEST_SECONDARY_PAYLOAD=y +# CONFIG_NVRAMCUI_SECONDARY_PAYLOAD is not set +# CONFIG_TINT_SECONDARY_PAYLOAD is not set +CONFIG_MEMTEST_STABLE=y +# CONFIG_MEMTEST_MASTER is not set +# CONFIG_MEMTEST_REVISION is not set + +# +# Reserve RAM for payload +# +CONFIG_CUSTOM_RAM_RES_ADDR=0x21000000 +CONFIG_CUSTOM_RAM_RES_SIZE=0x20920000 + +# +# Debugging +# + +# +# CPU Debug Settings +# +# CONFIG_DEBUG_SMM_RELOCATION is not set + +# +# General Debug Settings +# +# CONFIG_GDB_STUB is not set +# CONFIG_FATAL_ASSERTS is not set +# CONFIG_DEBUG_CBFS is not set +# CONFIG_HAVE_DEBUG_RAM_SETUP is not set +# CONFIG_HAVE_DEBUG_SMBUS is not set +# CONFIG_DEBUG_SMI is not set +# CONFIG_DEBUG_MALLOC is not set +# CONFIG_DEBUG_ACPI is not set +# CONFIG_DEBUG_CONSOLE_INIT is not set +# CONFIG_DEBUG_SPI_FLASH is not set +# CONFIG_TRACE is not set +# CONFIG_DEBUG_BOOT_STATE is not set +# CONFIG_DEBUG_ADA_CODE is not set +CONFIG_HAVE_EM100_SUPPORT=y +# CONFIG_EM100 is not set +CONFIG_NO_EDID_FILL_FB=y +# CONFIG_ENABLE_APIC_EXT_ID is not set +CONFIG_WARNINGS_ARE_ERRORS=y +# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set +# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set +# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set +# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set +# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set +CONFIG_REG_SCRIPT=y +# CONFIG_NO_XIP_EARLY_STAGES is not set +# CONFIG_EARLY_CBMEM_LIST is not set +CONFIG_RELOCATABLE_MODULES=y +CONFIG_NO_STAGE_CACHE=y +CONFIG_BOOTBLOCK_CUSTOM=y From ee1d9360519468657ce93a31d5c6a750219b0866 Mon Sep 17 00:00:00 2001 From: Krystian Hebel Date: Fri, 7 Jun 2019 15:39:42 +0200 Subject: [PATCH 588/588] libpayload: x86_64 support for APIC code Signed-off-by: Krystian Hebel --- payloads/libpayload/arch/x86/apic.c | 5 +++-- payloads/libpayload/configs/defconfig-tinycurses-64 | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/payloads/libpayload/arch/x86/apic.c b/payloads/libpayload/arch/x86/apic.c index db81ea1163b..d8db6052f7e 100644 --- a/payloads/libpayload/arch/x86/apic.c +++ b/payloads/libpayload/arch/x86/apic.c @@ -87,12 +87,12 @@ int apic_initialized(void) static inline uint32_t apic_read32(uint32_t offset) { - return read32((void *)(apic_bar + offset)); + return read32((void *)(size_t)(apic_bar + offset)); } static inline void apic_write32(uint32_t offset, uint32_t value) { - write32((void *)(apic_bar + offset), value); + write32((void *)(size_t)(apic_bar + offset), value); } uint8_t apic_id(void) @@ -204,6 +204,7 @@ static void apic_reset_all_lvts(void) { uint8_t max = apic_max_lvt_entries(); for (int i = 0; i <= max; ++i) { + if (i == 3) continue; // FIXME: LVT LINT0 Register (FEE0 0350H), hack for SeaBIOS uint32_t offset = APIC_LVT_TIMER + APIC_LVT_SIZE * i; apic_write32(offset, APIC_MASKED_BIT); } diff --git a/payloads/libpayload/configs/defconfig-tinycurses-64 b/payloads/libpayload/configs/defconfig-tinycurses-64 index c447c917d55..52f79bc000a 100644 --- a/payloads/libpayload/configs/defconfig-tinycurses-64 +++ b/payloads/libpayload/configs/defconfig-tinycurses-64 @@ -1,4 +1,5 @@ CONFIG_LP_ARCH_X86_64=y +CONFIG_LP_ENABLE_APIC=y # CONFIG_LP_MULTIBOOT is not set CONFIG_LP_TINYCURSES=y CONFIG_LP_COREBOOT_VIDEO_CONSOLE=y