summaryrefslogtreecommitdiff
path: root/src/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel')
-rw-r--r--src/soc/intel/snowridge/Kconfig259
-rw-r--r--src/soc/intel/snowridge/Makefile.mk62
-rw-r--r--src/soc/intel/snowridge/acpi.c481
-rw-r--r--src/soc/intel/snowridge/acpi/southcluster.asl45
-rw-r--r--src/soc/intel/snowridge/acpi/uncore.asl36
-rw-r--r--src/soc/intel/snowridge/bootblock/bootblock.c55
-rw-r--r--src/soc/intel/snowridge/bootblock/bootblock.h10
-rw-r--r--src/soc/intel/snowridge/bootblock/early_uart_init.c55
-rw-r--r--src/soc/intel/snowridge/chip.c432
-rw-r--r--src/soc/intel/snowridge/chip.h41
-rw-r--r--src/soc/intel/snowridge/chipset.cb214
-rw-r--r--src/soc/intel/snowridge/common/fsp_hob.c49
-rw-r--r--src/soc/intel/snowridge/common/fsp_hob.h20
-rw-r--r--src/soc/intel/snowridge/common/gpio.c314
-rw-r--r--src/soc/intel/snowridge/common/hob_display.c312
-rw-r--r--src/soc/intel/snowridge/common/kti_cache.c145
-rw-r--r--src/soc/intel/snowridge/common/kti_cache.h10
-rw-r--r--src/soc/intel/snowridge/common/pmclib.c103
-rw-r--r--src/soc/intel/snowridge/common/reset.c10
-rw-r--r--src/soc/intel/snowridge/common/spi.c8
-rw-r--r--src/soc/intel/snowridge/common/systemagent_early.c32
-rw-r--r--src/soc/intel/snowridge/common/uart8250mem.c30
-rw-r--r--src/soc/intel/snowridge/common/uart8250mem.h16
-rw-r--r--src/soc/intel/snowridge/common/upd_display.c133
-rw-r--r--src/soc/intel/snowridge/cpu.c103
-rw-r--r--src/soc/intel/snowridge/dlb.c21
-rw-r--r--src/soc/intel/snowridge/finalize.c19
-rw-r--r--src/soc/intel/snowridge/heci.c36
-rw-r--r--src/soc/intel/snowridge/include/soc/acpi.h12
-rw-r--r--src/soc/intel/snowridge/include/soc/cpu.h10
-rw-r--r--src/soc/intel/snowridge/include/soc/gpio.h62
-rw-r--r--src/soc/intel/snowridge/include/soc/gpio_defs.h179
-rw-r--r--src/soc/intel/snowridge/include/soc/gpio_snr.h192
-rw-r--r--src/soc/intel/snowridge/include/soc/iomap.h24
-rw-r--r--src/soc/intel/snowridge/include/soc/irq.h14
-rw-r--r--src/soc/intel/snowridge/include/soc/itss.h11
-rw-r--r--src/soc/intel/snowridge/include/soc/lpc.h6
-rw-r--r--src/soc/intel/snowridge/include/soc/msr.h19
-rw-r--r--src/soc/intel/snowridge/include/soc/nvs.h8
-rw-r--r--src/soc/intel/snowridge/include/soc/p2sb.h16
-rw-r--r--src/soc/intel/snowridge/include/soc/pci_devs.h81
-rw-r--r--src/soc/intel/snowridge/include/soc/pcr_gpmr.h19
-rw-r--r--src/soc/intel/snowridge/include/soc/pcr_ids.h22
-rw-r--r--src/soc/intel/snowridge/include/soc/pm.h128
-rw-r--r--src/soc/intel/snowridge/include/soc/pmc.h41
-rw-r--r--src/soc/intel/snowridge/include/soc/sata.h14
-rw-r--r--src/soc/intel/snowridge/include/soc/smbus.h8
-rw-r--r--src/soc/intel/snowridge/include/soc/soc_chip.h8
-rw-r--r--src/soc/intel/snowridge/include/soc/systemagent.h23
-rw-r--r--src/soc/intel/snowridge/itss.c82
-rw-r--r--src/soc/intel/snowridge/lockdown.c33
-rw-r--r--src/soc/intel/snowridge/lpc.c74
-rw-r--r--src/soc/intel/snowridge/nis.c29
-rw-r--r--src/soc/intel/snowridge/pcie_rp.c192
-rw-r--r--src/soc/intel/snowridge/qat.c27
-rw-r--r--src/soc/intel/snowridge/ramstage.h15
-rw-r--r--src/soc/intel/snowridge/romstage/gpio_snr.c200
-rw-r--r--src/soc/intel/snowridge/romstage/romstage.c186
-rw-r--r--src/soc/intel/snowridge/sata.c51
-rw-r--r--src/soc/intel/snowridge/smihandler.c25
-rw-r--r--src/soc/intel/snowridge/sriov.c110
-rw-r--r--src/soc/intel/snowridge/systemagent.c102
62 files changed, 5074 insertions, 0 deletions
diff --git a/src/soc/intel/snowridge/Kconfig b/src/soc/intel/snowridge/Kconfig
new file mode 100644
index 0000000000..ad77f9a1ea
--- /dev/null
+++ b/src/soc/intel/snowridge/Kconfig
@@ -0,0 +1,259 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+config SOC_INTEL_SNOWRIDGE
+ bool
+ help
+ Intel Snow Ridge SoC support
+
+ select BOOT_DEVICE_SUPPORTS_WRITES
+
+ ## Arch
+ select ARCH_X86
+
+ ## CPU
+ select SSE
+ select SUPPORT_CPU_UCODE_IN_CBFS
+ select MICROCODE_BLOB_NOT_IN_BLOB_REPO
+ select CPU_INTEL_COMMON
+ select CPU_INTEL_FIRMWARE_INTERFACE_TABLE
+ select PARALLEL_MP
+ select PARALLEL_MP_AP_WORK
+ select UDELAY_TSC
+ select TSC_MONOTONIC_TIMER
+ select TSC_SYNC_MFENCE
+ select HAVE_SMI_HANDLER
+
+ ## ACPI
+ select ACPI_INTEL_HARDWARE_SLEEP_VALUES
+
+ ## Device
+ select USE_DDR4
+
+ ## Drivers
+ select CACHE_MRC_SETTINGS
+ select UART_OVERRIDE_REFCLK
+
+ ## FSP 2.0
+ select PLATFORM_USES_FSP2_0
+ select FSP_CAR
+ select FSP_USES_CB_STACK
+ select FSP_M_XIP
+ select FSP_T_XIP
+ select SOC_INTEL_COMMON_FSP_RESET
+
+ ## SoC
+ select SOC_INTEL_COMMON
+ select SOC_INTEL_COMMON_BASECODE
+ select SOC_INTEL_COMMON_BLOCK
+ select SOC_INTEL_COMMON_BLOCK_ACPI
+ 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_CPU_SMMRELOCATE
+ select USE_INTEL_FSP_MP_INIT
+ select SOC_INTEL_COMMON_BLOCK_FAST_SPI
+ select SOC_INTEL_COMMON_BLOCK_GPIO
+ select SOC_INTEL_COMMON_BLOCK_GPIO_ITSS_POL_CFG
+ select SOC_INTEL_COMMON_BLOCK_GPMR
+ select USE_SOC_GPMR_DEFS
+ select SOC_INTEL_COMMON_BLOCK_IMC
+ select SOC_INTEL_COMMON_BLOCK_IRQ
+ select SOC_INTEL_COMMON_BLOCK_ITSS
+ select SOC_INTEL_COMMON_BLOCK_LPC
+ select SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR
+ select SOC_INTEL_COMMON_BLOCK_MEMINIT
+ select SOC_INTEL_COMMON_BLOCK_P2SB
+ select SOC_INTEL_COMMON_BLOCK_PCR
+ select SOC_INTEL_COMMON_BLOCK_PMC
+ select SOC_INTEL_COMMON_BLOCK_RTC
+ select SOC_INTEL_MEM_MAPPED_PM_CONFIGURATION
+ select PMC_GLOBAL_RESET_ENABLE_LOCK
+ select SOC_INTEL_COMMON_BLOCK_SMBUS
+ select SOC_INTEL_COMMON_BLOCK_TCO
+ select SOC_INTEL_COMMON_BLOCK_TCO_ENABLE_THROUGH_SMBUS
+ select SOC_INTEL_COMMON_BLOCK_SA_SERVER
+ select SOC_INTEL_COMMON_BLOCK_SMM
+ select SOC_INTEL_COMMON_BLOCK_SMM_IO_TRAP
+ select SOC_INTEL_COMMON_BLOCK_SMM_ESPI_DISABLE
+ select SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE
+ select SOC_INTEL_COMMON_BLOCK_SPI
+ select SOC_INTEL_COMMON_BLOCK_TIMER
+ select SOC_INTEL_COMMON_BLOCK_XHCI
+ select SOC_INTEL_COMMON_IBL_BASE # Select this one to add intelpch to including path.
+ select SOC_INTEL_COMMON_PCH_LOCKDOWN
+ select SOC_INTEL_COMMON_RESET
+
+ ## Southbridge
+ select INTEL_DESCRIPTOR_MODE_CAPABLE
+
+ ## Vendorcode
+ select UDK_202005_BINDING
+
+if SOC_INTEL_SNOWRIDGE
+
+config CHIPSET_DEVICETREE
+ default "soc/intel/snowridge/chipset.cb"
+
+config MAX_CPUS
+ default 16
+
+config HEAP_SIZE
+ default 0x100000
+
+config PRERAM_CBFS_CACHE_SIZE
+ default 0x0
+
+config C_ENV_BOOTBLOCK_SIZE
+ default 0x8000
+
+# CAR memory layout on Snow Ridge hardware:
+# CAR base address - 0xfe800000
+# CAR size - 0x7ff00 (512KB - 0x100)
+# FSP:
+# FSP reserved base - 0xfe800000
+# FSP reserved size - 0x40000
+# remaining:
+# DCACHE base - 0xfe840000
+# DCACHE size - 0x3ff00
+
+config DCACHE_RAM_BASE
+ default 0xfe840000
+
+config DCACHE_RAM_SIZE
+ default 0x3ff00 if FSP_CAR
+
+config DCACHE_BSP_STACK_SIZE
+ default 0x1C400
+ help
+ The amount of anticipated stack usage in CAR by bootblock and other stages.
+ In the case of FSP_USES_CB_STACK, the default value will be sum of FSP-M
+ stack requirement (112KiB) and CB romstage stack requirement (~1KiB).
+
+config CPU_INTEL_NUM_FIT_ENTRIES
+ default 24
+ help
+ Number of microcode files.
+
+config ECAM_MMCONF_BASE_ADDRESS
+ default 0x80000000
+
+config ECAM_MMCONF_BUS_NUMBER
+ default 256
+
+config ALWAYS_ALLOW_ABOVE_4G_ALLOCATION
+ default y
+
+config MAX_SOCKET
+ int
+ default 1
+
+config FSP_HEADER_PATH
+ default "src/vendorcode/intel/fsp/fsp2_0/snowridge" if !FSP_USE_REPO
+
+config FSP_TEMP_RAM_SIZE
+ default 0x20000
+ help
+ The amount of anticipated heap usage in CAR by FSP. Refer to platform FSP
+ integration guide document to know the exact FSP requirement for heap setup.
+
+config FSP_T_LOCATION
+ hex "Intel FSP-T (temp ram init) binary location"
+ depends on ADD_FSP_BINARIES && FSP_CAR
+ default 0xffe20000
+ help
+ The memory location of the Intel FSP-T binary for this platform.
+
+config FSP_M_ADDR
+ hex "Intel FSP-M (memory init) binary location"
+ depends on ADD_FSP_BINARIES
+ default 0xffe27000
+ help
+ The memory location of the Intel FSP-M binary for this platform.
+
+config FSP_S_ADDR
+ hex "Intel FSP-S (silicon init) binary location"
+ depends on ADD_FSP_BINARIES
+ default 0xffdb5000
+ help
+ The memory location of the Intel FSP-S binary for this platform.
+
+config DIMMS_PER_CHANNEL
+ default 2
+
+config DATA_BUS_WIDTH
+ default 128
+
+config MRC_CHANNEL_WIDTH
+ default 64
+
+## Private settings
+config KTI_CACHE_IN_FMAP
+ bool
+ default y
+ help
+ Save KTI cache data to flash and load it on following boots.
+
+if KTI_CACHE_IN_FMAP
+
+config KTI_CACHE_FMAP_NAME
+ string
+ default "RW_KTI_CACHE"
+
+config KTI_CACHE_SIZE
+ hex
+ default 0x1000
+ help
+ Size should be aligned to sector size.
+
+endif # KTI_CACHE_IN_FMAP
+
+config HSUART_DEV
+ hex
+ default 0x1a
+
+choice
+ prompt "UART mode selection"
+ default HIGH_SPEED_UART
+
+config LEGACY_UART
+ bool "Enable legacy UART"
+ select DRIVERS_UART_8250IO
+
+config HIGH_SPEED_UART
+ bool "Enable High-Speed UART"
+ select DRIVERS_UART_8250MEM
+endchoice
+
+config CONSOLE_UART_BASE_ADDRESS
+ hex "Temporary MMIO Base Address for HSUART"
+ default 0xfe032000
+ depends on HIGH_SPEED_UART
+ help
+ This option allows you to select temporary MMIO Base Address for HSUART.
+ It should be selected from 8M temporary MMIO address space starting at
+ 0xfe000000. It will be used until coreboot resource allocation overwrite it
+ with new allocated value.
+
+config PCR_BASE_ADDRESS
+ hex
+ default 0xfd000000
+ help
+ This option allows you to select MMIO Base Address of sideband bus.
+
+config IED_REGION_SIZE
+ hex
+ default 0x400000
+
+config SMM_RESERVED_SIZE
+ hex
+ default 0x200000
+
+config CPU_BCLK_MHZ
+ int
+ default 100
+
+config ENABLE_VTD
+ bool "Enable Intel Virtualization Technology"
+ default y
+
+endif # SOC_INTEL_SNOWRIDGE
diff --git a/src/soc/intel/snowridge/Makefile.mk b/src/soc/intel/snowridge/Makefile.mk
new file mode 100644
index 0000000000..07f39231f0
--- /dev/null
+++ b/src/soc/intel/snowridge/Makefile.mk
@@ -0,0 +1,62 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+ifeq ($(CONFIG_SOC_INTEL_SNOWRIDGE),y)
+
+subdirs-y += ../../../cpu/intel/microcode
+subdirs-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += ../../../cpu/intel/turbo
+
+all-$(CONFIG_HIGH_SPEED_UART) += common/uart8250mem.c
+all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += common/gpio.c
+all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += common/pmclib.c
+all-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SPI) += common/spi.c
+
+bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += bootblock/bootblock.c
+bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU) += bootblock/early_uart_init.c
+
+romstage-y += ../../../cpu/intel/car/romstage.c
+romstage-y += common/fsp_hob.c
+romstage-y += common/kti_cache.c
+romstage-y += romstage/gpio_snr.c
+romstage-y += romstage/romstage.c
+romstage-$(CONFIG_DISPLAY_HOBS) += common/hob_display.c
+romstage-$(CONFIG_DISPLAY_UPD_DATA) += common/upd_display.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += common/reset.c
+romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SA_SERVER) += common/systemagent_early.c
+
+ramstage-y += common/fsp_hob.c
+ramstage-y += common/kti_cache.c
+ramstage-y += chip.c
+ramstage-y += finalize.c
+ramstage-$(CONFIG_DISPLAY_HOBS) += common/hob_display.c
+ramstage-$(CONFIG_DISPLAY_UPD_DATA) += common/upd_display.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_RESET) += common/reset.c
+ramstage-$(CONFIG_PCI) += dlb.c
+ramstage-$(CONFIG_PCI) += heci.c
+ramstage-$(CONFIG_PCI) += lpc.c
+ramstage-$(CONFIG_PCI) += nis.c
+ramstage-$(CONFIG_PCI) += pcie_rp.c
+ramstage-$(CONFIG_PCI) += qat.c
+ramstage-$(CONFIG_PCI) += sata.c
+ramstage-$(CONFIG_PCI) += sriov.c
+ramstage-$(CONFIG_PCI) += systemagent.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ACPI) += acpi.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_CPU_MPINIT) += cpu.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_ITSS) += itss.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_SA_SERVER) += common/systemagent_early.c
+ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c
+
+smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += smihandler.c
+smm-$(CONFIG_HIGH_SPEED_UART) += common/uart8250mem.c
+smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_GPIO) += common/gpio.c
+smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_PMC) += common/pmclib.c
+smm-$(CONFIG_SPI_FLASH_SMM) += common/spi.c
+
+CPPFLAGS_common += -I$(src)/soc/intel/snowridge/include/
+
+## Set FSP binary blobs memory location
+
+$(call strip_quotes,$(CONFIG_FSP_T_CBFS))-position := $(CONFIG_FSP_T_LOCATION) --xip
+$(call strip_quotes,$(CONFIG_FSP_M_CBFS))-position := $(CONFIG_FSP_M_ADDR) --xip
+$(call strip_quotes,$(CONFIG_FSP_S_CBFS))-position := $(CONFIG_FSP_S_ADDR) --xip
+
+endif ## CONFIG_SOC_INTEL_SNOWRIDGE
diff --git a/src/soc/intel/snowridge/acpi.c b/src/soc/intel/snowridge/acpi.c
new file mode 100644
index 0000000000..552f7ba816
--- /dev/null
+++ b/src/soc/intel/snowridge/acpi.c
@@ -0,0 +1,481 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi.h>
+#include <acpi/acpi_device.h>
+#include <acpi/acpigen.h>
+#include <acpi/acpigen_pci.h>
+#include <arch/hpet.h>
+#include <arch/ioapic.h>
+#include <assert.h>
+#include <cbmem.h>
+#include <commonlib/bsd/helpers.h>
+#include <console/console.h>
+#include <device/mmio.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pci_type.h>
+#include <intelblocks/acpi.h>
+#include <intelblocks/lpc_lib.h>
+#include <intelblocks/p2sb.h>
+#include <intelblocks/systemagent_server.h>
+#include <soc/acpi.h>
+#include <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/itss.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/systemagent.h>
+#include <southbridge/intel/common/acpi_pirq_gen.h>
+#include <static.h>
+#include <string.h>
+
+uint32_t soc_read_sci_irq_select(void)
+{
+ return read32p(PCH_PWRM_BASE_ADDRESS + ACTL);
+}
+
+int soc_madt_sci_irq_polarity(int sci)
+{
+ if (sci >= 20)
+ return MP_IRQ_POLARITY_LOW;
+
+ return MP_IRQ_POLARITY_HIGH;
+}
+
+void soc_fill_fadt(acpi_fadt_t *fadt)
+{
+ /**
+ * The default field value is 0 if it's not set when calling this function.
+ */
+
+ fadt->pm2_cnt_blk = ACPI_BASE_ADDRESS + PM2_CNT;
+ fadt->pm_tmr_blk = ACPI_BASE_ADDRESS + PM1_TMR;
+ fadt->pm2_cnt_len = 1;
+ fadt->pm_tmr_len = 4;
+
+ fadt->duty_offset = 1;
+ fadt->duty_width = 0;
+
+ fill_fadt_extended_pm_io(fadt);
+}
+
+void soc_power_states_generation(int core_id, int cores_per_package)
+{
+ generate_p_state_entries(core_id, cores_per_package);
+}
+
+static void acpigen_write_pci_prt(const struct device *dev)
+{
+ unsigned int map_count = 0;
+ struct slot_pin_irq_map *pin_irq_map =
+ calloc(MAX_SLOTS * PCI_INT_MAX, sizeof(struct slot_pin_irq_map));
+ if (!pin_irq_map)
+ return;
+
+ struct device *child = NULL;
+ while ((child = dev_bus_each_child(dev->downstream, child))) {
+ if (!is_enabled_pci(child))
+ continue;
+
+ enum pci_pin pin = pci_read_config8(child, PCI_INTERRUPT_PIN);
+ if (pin < PCI_INT_A || pin > PCI_INT_D)
+ continue;
+
+ pin_irq_map[map_count].slot = PCI_SLOT(child->path.pci.devfn);
+ pin_irq_map[map_count].pin = pin;
+
+ /* `pic_pirq` is actually `enum pirq` type. */
+ pin_irq_map[map_count].pic_pirq = itss_soc_get_dev_pirq(child);
+ if (pin_irq_map[map_count].pic_pirq == PIRQ_INVALID)
+ continue;
+
+ /* PIRQA-H is hardwired to IRQ16-23. */
+ pin_irq_map[map_count].apic_gsi =
+ PCH_IRQ16 + pirq_idx(pin_irq_map[map_count].pic_pirq);
+
+ printk(BIOS_SPEW, "%s, slot_pin_irq_map[%2d]: {0x%2x, %s, PIRQ%c, IRQ%d}\n",
+ dev_path(child), map_count, pin_irq_map[map_count].slot,
+ pin_to_str(pin_irq_map[map_count].pin),
+ (unsigned int)pirq_idx(pin_irq_map[map_count].pic_pirq) + 'A',
+ pin_irq_map[map_count].apic_gsi);
+
+ map_count++;
+ }
+
+ size_t pirq_routes;
+ const uint8_t *legacy_pirq_routing = lpc_get_pic_pirq_routing(&pirq_routes);
+ struct pic_pirq_map pirq_map = {.type = PIRQ_GSI};
+ for (size_t i = 0; i < PIRQ_COUNT && i < pirq_routes; i++)
+ pirq_map.gsi[i] = legacy_pirq_routing[i];
+
+ intel_write_pci_PRT(acpi_device_path(dev), pin_irq_map, map_count, &pirq_map);
+ free(pin_irq_map);
+}
+
+void domain_fill_ssdt(const struct device *dev)
+{
+ const char *acpi_scope = acpi_device_scope(dev);
+ const char *acpi_name = acpi_device_name(dev);
+ printk(BIOS_DEBUG, "%s ACPI scope: '%s', name: '%s'\n", __func__, acpi_scope,
+ acpi_name);
+
+ /**
+ * PCH domain is defined in uncore.asl.
+ *
+ * Generating accelerator domains dynamically since they are SKU-dependent.
+ */
+ if (!is_domain0(dev)) {
+ /**
+ * Device (PCIx)
+ * {
+ * Method (_STA) { Return (status) }
+ * Name (_HID, EISAID ("PNP0A08")) // PCI Express Bus
+ * Name (_CID, EISAID ("PNP0A03")) // PCI Bus
+ * Name (_UID, "PCIx")
+ * Name (_PXM, 0)
+ * Method (_OSC, 4) { Return (\_SB.DOSC (Arg0, Arg1, Arg2, Arg3)) }
+ * }
+ */
+ acpigen_write_scope(acpi_scope);
+ acpigen_write_device(acpi_name);
+
+ acpigen_write_STA(dev->enabled ? ACPI_STATUS_DEVICE_ALL_ON :
+ ACPI_STATUS_DEVICE_ALL_OFF);
+
+ acpigen_write_name("_HID");
+ acpigen_emit_eisaid("PNP0A08");
+
+ acpigen_write_name("_CID");
+ acpigen_emit_eisaid("PNP0A03");
+
+ acpigen_write_name("_UID");
+ acpigen_write_string(acpi_name);
+
+ acpigen_write_name("_PXM");
+ acpigen_write_integer(0);
+
+ acpigen_write_method("_OSC", 4);
+ acpigen_write_return_namestr("\\_SB.DOSC");
+ acpigen_emit_byte(ARG0_OP);
+ acpigen_emit_byte(ARG1_OP);
+ acpigen_emit_byte(ARG2_OP);
+ acpigen_emit_byte(ARG3_OP);
+ acpigen_write_method_end();
+
+ acpigen_write_device_end();
+ acpigen_write_scope_end();
+ }
+
+ pci_domain_fill_ssdt(dev);
+
+ acpigen_write_pci_prt(dev);
+}
+
+void pcie_rp_fill_ssdt(const struct device *dev)
+{
+ const char *acpi_scope = acpi_device_scope(dev);
+ const char *acpi_name = acpi_device_name(dev);
+ printk(BIOS_DEBUG, "%s ACPI scope: '%s', name: '%s'\n", __func__, acpi_scope,
+ acpi_name);
+
+ acpigen_write_scope(acpi_scope);
+ acpigen_write_device(acpi_name);
+ acpigen_write_STA(dev->enabled ? ACPI_STATUS_DEVICE_ALL_ON :
+ ACPI_STATUS_DEVICE_ALL_OFF);
+ acpigen_write_ADR_pci_device(dev);
+ acpigen_write_device_end();
+ acpigen_write_scope_end();
+
+ acpigen_write_pci_prt(dev);
+}
+
+unsigned long acpi_create_srat_lapics(unsigned long current)
+{
+ for (struct device *cpu = DEV_PTR(cpu_bus)->downstream->children; cpu != NULL;
+ cpu = cpu->next) {
+ if (!is_enabled_cpu(cpu))
+ continue;
+
+ printk(BIOS_DEBUG,
+ "SRAT: APIC ID = 0x%02x, package ID = 0x%02x, node ID = 0x%02x, core ID = 0x%02x, thread ID = 0x%02x\n",
+ cpu->path.apic.apic_id, cpu->path.apic.package_id,
+ cpu->path.apic.node_id, cpu->path.apic.core_id,
+ cpu->path.apic.thread_id);
+ current += acpi_create_srat_lapic((acpi_srat_lapic_t *)current,
+ cpu->path.apic.node_id,
+ cpu->path.apic.apic_id);
+ }
+
+ return current;
+}
+
+static unsigned long acpi_fill_srat(unsigned long current)
+{
+ const uint32_t low_mem_end = sa_server_get_tolud();
+ const uint64_t hi_mem_end = sa_server_get_touud(), mem_4G = 4ull * GiB;
+
+ current = acpi_create_srat_lapics(current);
+
+ current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, 0, low_mem_end >> 10,
+ ACPI_SRAT_MEMORY_ENABLED);
+
+ if (hi_mem_end > mem_4G)
+ current += acpi_create_srat_mem((acpi_srat_mem_t *)current, 0, mem_4G >> 10,
+ (hi_mem_end - mem_4G) >> 10,
+ ACPI_SRAT_MEMORY_ENABLED);
+
+ return current;
+}
+
+static unsigned long acpi_create_drhd(unsigned long current, struct device *dev)
+{
+ unsigned long tmp = current;
+ const struct device *dev_domain = dev_get_domain(dev);
+ if (!dev_domain->enabled)
+ return current;
+
+ /**
+ * Bit 0 of VTBAR is read-write and it indicates whether VT-d base address is enabled.
+ */
+ uint32_t vtd_base = pci_read_config32(dev, VTBAR);
+ if (!(vtd_base & VTD_CHIPSET_BASE_ADDRESS_ENABLE))
+ return current;
+
+ vtd_base = ALIGN_DOWN(vtd_base, 4 * KiB);
+
+ const uint32_t pcie_seg = dev->upstream->segment_group;
+ if (is_dev_on_domain0(dev)) {
+ printk(BIOS_DEBUG,
+ "[DMA Remapping Hardware Unit Definition] Flags: 0x%x, PCI Segment: 0x%x, Register Base Address: 0x%x\n",
+ DRHD_INCLUDE_PCI_ALL, pcie_seg, vtd_base);
+ current += acpi_create_dmar_drhd_4k(current, DRHD_INCLUDE_PCI_ALL, pcie_seg,
+ vtd_base);
+
+ union p2sb_bdf ioapic_bdf = p2sb_get_ioapic_bdf();
+ printk(BIOS_DEBUG, "[IOAPIC] PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n",
+ ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn);
+ current += acpi_create_dmar_ds_ioapic_from_hw(
+ current, IO_APIC_ADDR, ioapic_bdf.bus, ioapic_bdf.dev, ioapic_bdf.fn);
+
+ uint16_t num_hpets = (read32p(HPET_BASE_ADDRESS) >> HPET_NUM_TIM_CAP_SHIFT) &
+ HPET_NUM_TIM_CAP_MASK;
+ if (num_hpets && num_hpets != HPET_NUM_TIM_CAP_MASK) {
+ if (read32p(HPET_BASE_ADDRESS + HPET_TMR0_CNF_CAP) &
+ HPET_TIMER_FSB_EN_CNF_MASK) {
+ union p2sb_bdf hpet_bdf = p2sb_get_hpet_bdf();
+ printk(BIOS_DEBUG,
+ "[MSI_CAPABLE_HPET] Enumeration ID: 0x%x, PCI Bus: 0x%x, PCI Path: 0x%x, 0x%x\n",
+ 0, hpet_bdf.bus, hpet_bdf.dev, hpet_bdf.fn);
+ current += acpi_create_dmar_ds_msi_hpet(
+ current, 0, hpet_bdf.bus, hpet_bdf.dev, hpet_bdf.fn);
+ }
+ }
+ } else {
+ printk(BIOS_DEBUG,
+ "[DMA Remapping Hardware Unit Definition] Flags: 0x%x, PCI Segment: 0x%x, Register Base Address: 0x%x\n",
+ 0, pcie_seg, vtd_base);
+ current += acpi_create_dmar_drhd_4k(current, 0, pcie_seg, vtd_base);
+
+ if (dev == DEV_PTR(dlb_sa)) {
+ if (DEV_PTR(dlb)) {
+ printk(BIOS_DEBUG, "[PCI Endpoint Device] %s\n",
+ dev_path(DEV_PTR(dlb)));
+ current += acpi_create_dmar_ds_pci(
+ current, PCI_DEV2BUS(PCI_BDF(DEV_PTR(dlb))),
+ PCI_SLOT(DEV_PTR(dlb)->path.pci.devfn),
+ PCI_FUNC(DEV_PTR(dlb)->path.pci.devfn));
+ }
+ } else {
+ struct device *pci_bridge = NULL;
+ while ((pci_bridge = dev_bus_each_child(dev_get_domain(dev)->downstream,
+ pci_bridge))) {
+ if (pci_bridge->vendor != PCI_VID_INTEL)
+ continue;
+
+ switch (pci_bridge->device) {
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPA:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPB:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPC:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPD:
+ case PCI_DID_INTEL_SNR_VRP4_NIS:
+ case PCI_DID_INTEL_SNR_VRP5_QAT_1_8:
+ printk(BIOS_DEBUG, "[PCI Sub-hierarchy] %s\n",
+ dev_path(pci_bridge));
+ current += acpi_create_dmar_ds_pci_br(
+ current, dev->upstream->secondary,
+ PCI_SLOT(pci_bridge->path.pci.devfn),
+ PCI_FUNC(pci_bridge->path.pci.devfn));
+ break;
+ default:
+ continue;
+ }
+ }
+ }
+ }
+
+ if (current != tmp)
+ acpi_dmar_drhd_fixup(tmp, current);
+
+ return current;
+}
+
+static unsigned long acpi_create_rmrr(unsigned long current)
+{
+ const uint32_t MEM_BLK_COUNT = 0x140, MEM_BLK_SIZE = 32;
+ uint32_t size = ALIGN_UP(MEM_BLK_COUNT * MEM_BLK_SIZE, 0x1000);
+ const struct cbmem_entry *entry;
+ void *ptr;
+ unsigned long tmp = current;
+ struct device *dev = PCH_DEV_XHCI;
+
+ entry = cbmem_entry_find(CBMEM_ID_STORAGE_DATA);
+ if (!entry) {
+ ptr = cbmem_add(CBMEM_ID_STORAGE_DATA, size);
+ if (!ptr) {
+ printk(BIOS_ERR, "Failed to allocate reserved memory in cbmem!\n");
+ return current;
+ }
+
+ memset(ptr, 0, size);
+ } else {
+ ptr = cbmem_entry_start(entry);
+ size = cbmem_entry_size(entry);
+ }
+
+ printk(BIOS_DEBUG,
+ "[Reserved Memory Region Reporting] PCI Segment: 0x%x, Base: %p, Limit: %p\n",
+ dev->upstream->segment_group, ptr, ptr + size - 1);
+ current += acpi_create_dmar_rmrr(current, dev->upstream->segment_group, (uintptr_t)ptr,
+ (uintptr_t)(ptr + size - 1));
+
+ printk(BIOS_DEBUG, "[PCI Endpoint Device] %s\n", dev_path(dev));
+ current += acpi_create_dmar_ds_pci(current, PCI_DEV2BUS(PCI_BDF(dev)),
+ PCI_SLOT(dev->path.pci.devfn),
+ PCI_FUNC(dev->path.pci.devfn));
+
+ if (current != tmp)
+ acpi_dmar_rmrr_fixup(tmp, current);
+
+ return current;
+}
+
+static unsigned long acpi_create_atsr(unsigned long current, struct device *dev)
+{
+ unsigned long tmp = current;
+
+ /**
+ * Bit 0 of VTBAR is read-write and it indicates whether VT-d base address is enabled.
+ */
+ uint32_t vtd_base = pci_read_config32(dev, VTBAR);
+ if (!(vtd_base & VTD_CHIPSET_BASE_ADDRESS_ENABLE))
+ return current;
+
+ vtd_base = ALIGN_DOWN(vtd_base, 4 * KiB);
+
+ uint64_t vtd_ext_cap = read64p(vtd_base + VTD_ECAP);
+ if (!(vtd_ext_cap & DEVICE_TLB))
+ return current;
+
+ printk(BIOS_DEBUG, "Domain 1 VT-d BAR: 0x%x, Extended Capability: 0x%llx\n", vtd_base,
+ vtd_ext_cap);
+
+ bool first = true;
+ struct device *cpu_pcie_rp = NULL;
+ while ((cpu_pcie_rp =
+ dev_bus_each_child(dev_get_domain(dev)->downstream, cpu_pcie_rp))) {
+ if (cpu_pcie_rp->vendor != PCI_VID_INTEL)
+ continue;
+
+ switch (cpu_pcie_rp->device) {
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPA:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPB:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPC:
+ case PCI_DID_INTEL_SNR_CPU_PCIE_RPD:
+ break;
+ default:
+ continue;
+ }
+
+ if (first) {
+ const uint32_t pcie_seg = dev->upstream->segment_group;
+ printk(BIOS_DEBUG,
+ "[Root Port ATS Capability] Flags: 0x%x, PCI Segment: 0x%x\n", 0,
+ pcie_seg);
+ current += acpi_create_dmar_atsr(current, 0, pcie_seg);
+ first = false;
+ }
+
+ printk(BIOS_DEBUG, "[PCI Sub-hierarchy] %s\n", dev_path(cpu_pcie_rp));
+ current += acpi_create_dmar_ds_pci_br(current,
+ PCI_DEV2BUS(PCI_BDF(cpu_pcie_rp)),
+ PCI_SLOT(cpu_pcie_rp->path.pci.devfn),
+ PCI_FUNC(cpu_pcie_rp->path.pci.devfn));
+ }
+
+ if (tmp != current)
+ acpi_dmar_atsr_fixup(tmp, current);
+
+ return current;
+}
+
+static unsigned long acpi_fill_dmar(unsigned long current)
+{
+ assert(DEV_PTR(pch_sa));
+
+ /**
+ * Domain 0 hosts all PCH peripherals, and DRHD entry for this domain should be at last,
+ * thus we search from `DEV_PTR(pch_sa)` here.
+ */
+ struct device *dev = DEV_PTR(pch_sa);
+ while ((dev = dev_find_device(PCI_VID_INTEL, PCI_DID_INTEL_SNR_ID, dev)) != NULL)
+ current = acpi_create_drhd(current, dev);
+
+ current = acpi_create_drhd(current, DEV_PTR(pch_sa));
+
+ current = acpi_create_rmrr(current);
+
+ /* Only CPU PCIe root ports support address translation services (ATS). */
+ assert(DEV_PTR(cpu_sa));
+ current = acpi_create_atsr(current, DEV_PTR(cpu_sa));
+
+ return current;
+}
+
+unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
+ struct acpi_rsdp *rsdp)
+{
+ acpi_srat_t *srat;
+ acpi_dmar_t *dmar;
+
+ /**
+ * Write only when calling from system agent in domain 0.
+ */
+ if (!sa_server_is_on_pch_domain(dev))
+ return current;
+
+ /* SRAT */
+ printk(BIOS_DEBUG, "ACPI: * SRAT at 0x%08lx\n", current);
+ srat = (acpi_srat_t *)current;
+ acpi_create_srat(srat, acpi_fill_srat);
+ acpi_add_table(rsdp, srat);
+ current += srat->header.length;
+ current = acpi_align_current(current);
+
+ printk(BIOS_DEBUG, "ACPI: * DMAR at 0x%08lx\n", current);
+ dmar = (acpi_dmar_t *)current;
+ acpi_create_dmar(dmar, DMAR_INTR_REMAP, acpi_fill_dmar);
+ acpi_add_table(rsdp, dmar);
+ current += dmar->header.length;
+
+ return current;
+}
+
+/**
+ * To use ACPI in common block, this function should be defined.
+ */
+const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
+{
+ *entries = 0;
+ return NULL;
+}
diff --git a/src/soc/intel/snowridge/acpi/southcluster.asl b/src/soc/intel/snowridge/acpi/southcluster.asl
new file mode 100644
index 0000000000..e2df596c05
--- /dev/null
+++ b/src/soc/intel/snowridge/acpi/southcluster.asl
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/ioapic.h>
+#include <cpu/x86/lapic_def.h>
+#include <soc/iomap.h>
+
+Scope (\_SB.PCI0)
+{
+ /* PCH Reserved resources. */
+ Device (PCHR)
+ {
+ Name (_HID, EisaId ("PNP0C02"))
+ Name (_CRS, ResourceTemplate ()
+ {
+ Memory32Fixed (ReadWrite, RESERVED_BASE_ADDRESS, RESERVED_BASE_SIZE)
+ })
+ }
+
+ Device (APIC)
+ {
+ Name (_HID, EisaId ("PNP0003"))
+ Name (_CRS, ResourceTemplate ()
+ {
+ /* IO APIC */
+ Memory32Fixed (ReadOnly, IO_APIC_ADDR, 0x00100000)
+ /* Local APIC */
+ Memory32Fixed (ReadOnly, LAPIC_DEFAULT_BASE, 0x00100000)
+ })
+ }
+
+ #include <soc/intel/common/block/acpi/acpi/lpc.asl>
+
+ Device (PMC)
+ {
+ Name (_HID, EISAID ("PNP0C02"))
+ Name (_DDN, "PCH PMC")
+ Name (_UID, "PMC")
+
+ Name (_CRS, ResourceTemplate
+ {
+ IO (Decode16, ACPI_BASE_ADDRESS, ACPI_BASE_ADDRESS, 0x1, 0x80)
+ Memory32Fixed (ReadOnly, PCH_PWRM_BASE_ADDRESS, 0x10000)
+ })
+ }
+}
diff --git a/src/soc/intel/snowridge/acpi/uncore.asl b/src/soc/intel/snowridge/acpi/uncore.asl
new file mode 100644
index 0000000000..5d06926d81
--- /dev/null
+++ b/src/soc/intel/snowridge/acpi/uncore.asl
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/itss.h>
+#include <intelblocks/pcr.h>
+#include <soc/pcr_ids.h>
+
+#define PCI_HOST_BRIDGE_OSC_UUID "33db4d5b-1ff7-401c-9657-7441c03dd766"
+
+Scope (\_SB)
+{
+ Method (DOSC, 4)
+ {
+ If (Arg0 != ToUUID (PCI_HOST_BRIDGE_OSC_UUID))
+ {
+ CreateDWordField (Arg3, 0, DW1)
+ DW1 |= 4 // Unrecognized UUID
+ }
+ Return (Arg3)
+ }
+
+ Device (PCI0)
+ {
+ Method (_STA)
+ {
+ Return (0xf)
+ }
+ Name (_HID, EISAID ("PNP0A08")) // PCI Express Bus
+ Name (_CID, EISAID ("PNP0A03")) // PCI Bus
+ Name (_UID, "PCI0")
+ Name (_PXM, 0)
+ Method (_OSC, 4)
+ {
+ Return (\_SB.DOSC (Arg0, Arg1, Arg2, Arg3))
+ }
+ }
+}
diff --git a/src/soc/intel/snowridge/bootblock/bootblock.c b/src/soc/intel/snowridge/bootblock/bootblock.c
new file mode 100644
index 0000000000..8e6c0def99
--- /dev/null
+++ b/src/soc/intel/snowridge/bootblock/bootblock.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootblock_common.h>
+#include <console/console.h>
+#include <fsp/util.h>
+#include <intelblocks/fast_spi.h>
+#include <intelblocks/tco.h>
+#include <soc/iomap.h>
+
+#include <FsptUpd.h>
+
+#include "bootblock.h"
+
+const FSPT_UPD temp_ram_init_params = {
+ .FspUpdHeader = {
+ .Signature = 0x545F445055434F53ULL,
+ .Revision = 1,
+ .Reserved = {0},
+ },
+ .FsptCoreUpd = {
+ .MicrocodeRegionBase = 0,
+ .MicrocodeRegionLength = 0,
+ .CodeRegionBase = 0xffe00000,
+ .CodeRegionLength = 0x200000,
+ .Reserved1 = {0},
+ },
+ .ReservedTempRamInitUpd = {0},
+ .UnusedUpdSpace0 = {0},
+ .UpdTerminator = 0x55AA,
+};
+
+asmlinkage void bootblock_c_entry(uint64_t base_timestamp)
+{
+ bootblock_main_with_basetime(base_timestamp);
+}
+
+void bootblock_soc_early_init(void)
+{
+ if (CONFIG(DRIVERS_UART))
+ early_uart_init();
+}
+
+void bootblock_soc_init(void)
+{
+ if (CONFIG(BOOTBLOCK_CONSOLE))
+ printk(BIOS_DEBUG, "FSP TempRamInit successful...\n");
+
+ if (CONFIG(FSP_CAR))
+ report_fspt_output();
+
+ tco_configure();
+ tco_reset_status();
+
+ fast_spi_early_init(SPI_BASE_ADDRESS);
+}
diff --git a/src/soc/intel/snowridge/bootblock/bootblock.h b/src/soc/intel/snowridge/bootblock/bootblock.h
new file mode 100644
index 0000000000..2cc732085a
--- /dev/null
+++ b/src/soc/intel/snowridge/bootblock/bootblock.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_BOOTBLOCK_H_
+#define _SOC_SNOWRIDGE_BOOTBLOCK_H_
+
+void early_uart_init(void);
+
+void early_tco_init(void);
+
+#endif // _SOC_SNOWRIDGE_BOOTBLOCK_H_
diff --git a/src/soc/intel/snowridge/bootblock/early_uart_init.c b/src/soc/intel/snowridge/bootblock/early_uart_init.c
new file mode 100644
index 0000000000..9f56ceba01
--- /dev/null
+++ b/src/soc/intel/snowridge/bootblock/early_uart_init.c
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <soc/pci_devs.h>
+#include <stdint.h>
+
+#include "../common/uart8250mem.h"
+#include "bootblock.h"
+
+static void pci_early_hsuart_device_enable(uint8_t func, uint16_t io_base)
+{
+ register uint16_t cmd_stat_reg;
+
+ pci_or_config32(PCH_DEV_UART(func), UART_IOBA, io_base);
+
+ /**
+ * Enable memory/io space and allow to initiate a transaction as a master.
+ */
+ cmd_stat_reg = pci_read_config16(PCH_DEV_UART(func), PCI_COMMAND);
+ cmd_stat_reg |= PCI_COMMAND_MASTER | PCI_COMMAND_IO;
+
+#if CONFIG_CONSOLE_UART_BASE_ADDRESS != 0
+ /* Decode MMIO at MEMBA (BAR1). */
+ pci_write_config32(PCH_DEV_UART(func), UART_MEMBA,
+ CONFIG_CONSOLE_UART_BASE_ADDRESS + SIZE_OF_HSUART_RES * func);
+ cmd_stat_reg |= PCI_COMMAND_MEMORY;
+#endif
+
+ pci_write_config16(PCH_DEV_UART(func), PCI_COMMAND, cmd_stat_reg);
+
+#if CONFIG_TTYS0_BAUD > 115200
+#if CONFIG_CONSOLE_UART_BASE_ADDRESS && CONFIG(ECAM_MMCONF_SUPPORT)
+#define UCMR_OFFSET 0x34
+ /**
+ * Change UART baseclock to 24 x 1.8432MHz -> 44.2368MHz, use
+ * `HIGH_SPEED_CLK_MULT` (24) times faster base clock.
+ */
+ write32p(CONFIG_CONSOLE_UART_BASE_ADDRESS + UCMR_OFFSET,
+ read32p(CONFIG_CONSOLE_UART_BASE_ADDRESS + UCMR_OFFSET) * HIGH_SPEED_CLK_MULT);
+#else
+#error MMIO access is required for baudrates above 115200.
+#endif
+#endif
+}
+
+void early_uart_init(void)
+{
+ static const uint16_t legacy_uart_io_port_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
+ register int i;
+
+ for (i = SNOWRIDGE_UARTS_TO_INIT - 1; i >= 0; --i) {
+ pci_early_hsuart_device_enable(i, legacy_uart_io_port_tab[i]);
+ }
+}
diff --git a/src/soc/intel/snowridge/chip.c b/src/soc/intel/snowridge/chip.c
new file mode 100644
index 0000000000..f08161e7e8
--- /dev/null
+++ b/src/soc/intel/snowridge/chip.c
@@ -0,0 +1,432 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <acpi/acpi.h>
+#include <cbfs.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <device/resource.h>
+#include <fsp/api.h>
+#include <intelblocks/acpi.h>
+#include <intelblocks/irq.h>
+#include <ramstage.h>
+#include <soc/acpi.h>
+#include <soc/pci_devs.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "chip.h"
+#include "common/fsp_hob.h"
+
+static void soc_silicon_init_params(FSPS_UPD *supd)
+{
+ const struct microcode *microcode_file;
+ size_t microcode_len;
+
+ microcode_file = cbfs_map("cpu_microcode_blob.bin", &microcode_len);
+ if (microcode_file && (microcode_len != 0)) {
+ supd->FspsConfig.PcdCpuMicrocodePatchBase = (UINT32)microcode_file;
+ supd->FspsConfig.PcdCpuMicrocodePatchSize = (UINT32)microcode_len;
+ }
+}
+
+/* UPD parameters to be initialized before SiliconInit */
+void platform_fsp_silicon_init_params_cb(FSPS_UPD *supd)
+{
+ soc_silicon_init_params(supd);
+ mainboard_silicon_init_params(supd);
+}
+
+static void chip_domain_resource_table_init(config_t *chip_info)
+{
+ memset(&chip_info->domain, 0, sizeof(chip_info->domain));
+ /**
+ * Valid resource range meets base <= limit.
+ */
+ for (int i = 0; i < MAX_DOMAIN; i++) {
+ chip_info->domain[i].bus_base = UINT8_MAX;
+ chip_info->domain[i].io_base = UINT16_MAX;
+ chip_info->domain[i].mem32_base = UINT32_MAX;
+ chip_info->domain[i].mem64_base = UINT64_MAX;
+ }
+}
+
+static void chip_domain_resource_table_load(config_t *chip_info)
+{
+ const BL_IIO_UDS *hob = fsp_hob_get_iio_uds_data();
+ if (!hob)
+ die("FSP HOB IIO UDS DATA not found!\n");
+
+ /**
+ * Assert for `numofIIO` and `BL_MAX_LOGIC_IIO_STACK` so the following loop effects.
+ */
+ assert(hob->PlatformData.numofIIO == 1);
+ assert(BL_MAX_LOGIC_IIO_STACK);
+
+ const BL_STACK_RES *stack_res = hob->PlatformData.IIO_resource[0].StackRes;
+ for (int i = 0; i < BL_MAX_LOGIC_IIO_STACK; i++) {
+ struct snr_domain *domain = &chip_info->domain[i];
+ domain->personality = stack_res[i].Personality;
+
+ /**
+ * SNR FSP uses specific enumerations for different type of stacks, see
+ * vendorcode/intel/fsp/fsp2_0/snowridge/FspmUpd.h.
+ */
+ if (stack_res[i].Personality >= BL_TYPE_DISABLED)
+ continue;
+
+ if (stack_res[i].BusBase > stack_res[i].BusLimit)
+ die("Incorrect bus base 0x%02x and limit 0x%02x for domain %d",
+ stack_res[i].BusBase, stack_res[i].BusLimit, i);
+
+ domain->bus_base = stack_res[i].BusBase;
+ domain->bus_limit = stack_res[i].BusLimit;
+
+ /**
+ * Stack with `BL_TYPE_RESERVED` personality has valid bus range but no IO and MMIO resources.
+ */
+ if (stack_res[i].Personality == BL_TYPE_RESERVED)
+ continue;
+
+ domain->enabled = true;
+
+ /**
+ * Only non-zero resource base is valid.
+ */
+ if (stack_res[i].PciResourceIoBase) {
+ if (stack_res[i].PciResourceIoBase > stack_res[i].PciResourceIoLimit)
+ die("Incorrect IO base 0x%04x and limit 0x%04x for domain %d",
+ stack_res[i].PciResourceIoBase,
+ stack_res[i].PciResourceIoLimit, i);
+
+ domain->io_base = stack_res[i].PciResourceIoBase;
+ domain->io_limit = stack_res[i].PciResourceIoLimit;
+ }
+
+ if (stack_res[i].PciResourceMem32Base) {
+ if (stack_res[i].PciResourceMem32Base >
+ stack_res[i].PciResourceMem32Limit)
+ die("Incorrect Mem32 base 0x%08x and limit 0x%08x for domain %d",
+ stack_res[i].PciResourceMem32Base,
+ stack_res[i].PciResourceMem32Limit, i);
+
+ domain->mem32_base = stack_res[i].PciResourceMem32Base;
+ domain->mem32_limit = stack_res[i].PciResourceMem32Limit;
+ }
+
+ if (stack_res[i].PciResourceMem64Base) {
+ if (stack_res[i].PciResourceMem64Base >
+ stack_res[i].PciResourceMem64Limit)
+ die("Incorrect Mem64 base 0x%16llx and limit 0x%16llx for domain %d",
+ stack_res[i].PciResourceMem64Base,
+ stack_res[i].PciResourceMem64Limit, i);
+
+ domain->mem64_base = stack_res[i].PciResourceMem64Base;
+ domain->mem64_limit = stack_res[i].PciResourceMem64Limit;
+ }
+ }
+}
+
+static void chip_cfg_domain_resource_table_split(config_t *chip_info, int base_domain_index,
+ int addtional_domain_index)
+{
+ assert(base_domain_index < MAX_DOMAIN);
+ assert(addtional_domain_index < MAX_DOMAIN);
+
+ struct snr_domain *base_domain = &chip_info->domain[base_domain_index];
+ struct snr_domain *addtional_domain = &chip_info->domain[addtional_domain_index];
+ memcpy(addtional_domain, base_domain, sizeof(*addtional_domain));
+
+ /**
+ * Base + (Limit - Base) / 2 to avoid overflow.
+ */
+ if (base_domain->bus_base < base_domain->bus_limit) {
+ base_domain->bus_limit = base_domain->bus_base +
+ (base_domain->bus_limit - base_domain->bus_base) / 2;
+ addtional_domain->bus_base = base_domain->bus_limit + 1;
+ }
+
+ if (base_domain->io_base < base_domain->io_limit) {
+ base_domain->io_limit = base_domain->io_base +
+ (base_domain->io_limit - base_domain->io_base) / 2;
+ addtional_domain->io_base = base_domain->io_limit + 1;
+ }
+
+ if (base_domain->mem32_base < base_domain->mem32_limit) {
+ base_domain->mem32_limit =
+ base_domain->mem32_base +
+ (base_domain->mem32_limit - base_domain->mem32_base) / 2;
+ addtional_domain->mem32_base = base_domain->mem32_limit + 1;
+ }
+
+ if (base_domain->mem64_base < base_domain->mem64_limit) {
+ base_domain->mem64_limit =
+ base_domain->mem64_base +
+ (base_domain->mem64_limit - base_domain->mem64_base) / 2;
+ addtional_domain->mem64_base = base_domain->mem64_limit + 1;
+ }
+}
+
+static void chip_domain_resource_table_handle_multi_root(config_t *chip_info)
+{
+ /**
+ * Split domains that have more than 1 root bus.
+ */
+ int addtional_domain = BL_MAX_LOGIC_IIO_STACK;
+ chip_cfg_domain_resource_table_split(chip_info, 7,
+ addtional_domain++); /**< Domain 8 (Ubox1). */
+
+ if (chip_info->domain[2].enabled)
+ chip_cfg_domain_resource_table_split(
+ chip_info, 2,
+ addtional_domain++); /**< Domain 2 (S2) has an extra root bus for Intel DLB. */
+}
+
+static void chip_domain_resource_table_dump(config_t *chip_info)
+{
+ printk(BIOS_DEBUG,
+ "---------------------------------------------------------------------------------------------------------------------\n"
+ "| Domain | Enabled | Bus Base/Limit | IO Base/Limit | Mem32 Base/Limit | Mem64 Base/Limit |\n"
+ "---------------------------------------------------------------------------------------------------------------------\n");
+ for (int i = 0; i < MAX_DOMAIN; i++) {
+ struct snr_domain *domain = &chip_info->domain[i];
+ printk(BIOS_DEBUG,
+ "| %2u | %c(0x%02x) | 0x%02x/0x%02x | 0x%04x/0x%04x | 0x%08x/0x%08x | 0x%016llx/0x%016llx |\n",
+ i, domain->enabled ? 'Y' : 'N', domain->personality, domain->bus_base,
+ domain->bus_limit, domain->io_base, domain->io_limit, domain->mem32_base,
+ domain->mem32_limit, domain->mem64_base, domain->mem64_limit);
+ }
+ printk(BIOS_DEBUG,
+ "---------------------------------------------------------------------------------------------------------------------\n");
+}
+
+static void chip_domain_resource_table_fill(config_t *chip_info)
+{
+ chip_domain_resource_table_init(chip_info);
+ chip_domain_resource_table_load(chip_info);
+ chip_domain_resource_table_handle_multi_root(chip_info);
+ chip_domain_resource_table_dump(chip_info);
+}
+
+static void devicetree_domain_definition_update(config_t *chip_info)
+{
+ struct device *dev = NULL;
+ int domain;
+
+ /**
+ * Check static domain id agaginst dynamic and fill domain device.
+ */
+ while ((dev = dev_find_path(dev, DEVICE_PATH_DOMAIN)) != NULL) {
+ domain = dev_get_domain_id(dev);
+ if (domain >= MAX_DOMAIN)
+ die("Incorrect domain[%d] in devicetree\n", domain);
+
+ chip_info->domain[domain].dev = dev;
+
+ printk(BIOS_SPEW, "%s -> domain[%d] defined in devicetree\n", dev_path(dev),
+ domain);
+ }
+
+ if (!chip_info->domain[0].dev)
+ die("Please add domain 0 to device tree!\n");
+
+ for (domain = 0; domain < MAX_DOMAIN; domain++) {
+ if (!chip_info->domain[domain].enabled) {
+ if (chip_info->domain[domain].dev &&
+ chip_info->domain[domain].dev->enabled) {
+ printk(BIOS_WARNING,
+ "Domain[%d] is disabled, reserved or not existed but defined in device tree!\n",
+ domain);
+ dev_set_enabled(chip_info->domain[domain].dev, false);
+ }
+ continue;
+ }
+
+ if (!chip_info->domain[domain].dev)
+ die("Domain[%d] is enabled but not defined in device tree!\n", domain);
+
+ dev = chip_info->domain[domain].dev;
+
+ printk(BIOS_SPEW, "Domain[%d] is enabled, updating PCI root bus to 0x%02x\n",
+ domain, chip_info->domain[domain].bus_base);
+
+ /* Use same bus number for secondary and subordinate before PCI enumeration. */
+ dev->downstream->secondary = dev->downstream->subordinate =
+ chip_info->domain[domain].bus_base;
+ dev->downstream->max_subordinate = chip_info->domain[domain].bus_limit;
+ }
+}
+
+static void soc_init_pre_device(void *chip_info)
+{
+ fsp_silicon_init();
+
+ chip_domain_resource_table_fill((config_t *)chip_info);
+
+ devicetree_domain_definition_update((config_t *)chip_info);
+}
+
+static void domain_read_resources(struct device *dev)
+{
+ struct resource *res;
+ uint8_t index = 0;
+ const uint8_t domain = dev->path.domain.domain_id;
+ const config_t *chip_info = dev->chip_info;
+
+ printk(BIOS_DEBUG, "Reading resources for %s\n", dev_path(dev));
+
+ /**
+ * Allocate IO resource.
+ */
+ if (chip_info->domain[domain].io_limit >= chip_info->domain[domain].io_base) {
+ res = new_resource(dev, index++);
+ if (!res)
+ die("Allocate resource for %s failed!\n", dev_path(dev));
+
+ res->base = chip_info->domain[domain].io_base;
+ res->limit = chip_info->domain[domain].io_limit;
+ res->size = res->limit - res->base + 1;
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED;
+ printk(BIOS_SPEW, "IO Base/Limit: 0x%04llx/0x%04llx\n", res->base, res->limit);
+ }
+
+ /**
+ * Allocate Mem32 resource.
+ */
+ if (chip_info->domain[domain].mem32_limit >= chip_info->domain[domain].mem32_base) {
+ res = new_resource(dev, index++);
+ if (!res)
+ die("Allocate resource for %s failed!\n", dev_path(dev));
+
+ res->base = chip_info->domain[domain].mem32_base;
+ res->limit = chip_info->domain[domain].mem32_limit;
+ res->size = res->limit - res->base + 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED;
+ printk(BIOS_SPEW, "Mem32 Base/Limit: 0x%08llx/0x%08llx\n", res->base,
+ res->limit);
+ }
+
+ /**
+ * Allocate Mem64 resource.
+ */
+ if (chip_info->domain[domain].mem64_limit >= chip_info->domain[domain].mem64_base) {
+ res = new_resource(dev, index++);
+ if (!res)
+ die("Allocate resource for %s failed!\n", dev_path(dev));
+
+ res->base = chip_info->domain[domain].mem64_base;
+ res->limit = chip_info->domain[domain].mem64_limit;
+ res->size = res->limit - res->base + 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_PCI64 |
+ IORESOURCE_ABOVE_4G;
+ printk(BIOS_SPEW, "Mem64 Base/Limit: 0x%016llx/0x%016llx\n", res->base,
+ res->size);
+ }
+
+ printk(BIOS_DEBUG, "Reading resources for %s done\n", dev_path(dev));
+}
+
+static void domain_set_resources(struct device *dev)
+{
+ printk(BIOS_DEBUG, "Setting resources for %s\n", dev_path(dev));
+
+ pci_domain_set_resources(dev);
+
+ printk(BIOS_DEBUG, "Setting resources for %s done\n", dev_path(dev));
+}
+
+static void domain_scan_bus(struct device *dev)
+{
+ printk(BIOS_DEBUG, "Scanning %s\n", dev_path(dev));
+
+ pci_host_bridge_scan_bus(dev);
+
+ printk(BIOS_DEBUG, "Scanning %s done\n", dev_path(dev));
+}
+
+const char *soc_acpi_name(const struct device *dev)
+{
+ if (dev->path.type == DEVICE_PATH_DOMAIN)
+ switch (dev_get_domain_id(dev)) {
+ case 0:
+ return "PCI0";
+ case 1:
+ return "PCI1";
+ case 2:
+ return "PCI2";
+ case 3:
+ return "PCI3";
+ case 4:
+ return "PCI4";
+ case 5:
+ return "PCI5";
+ case 6:
+ return "PCI6";
+ case 7:
+ return "PCI7";
+ case 8:
+ return "PCI8";
+ case 9:
+ return "PCI9";
+ default:
+ return NULL;
+ }
+
+ return NULL;
+}
+
+static struct device_operations pci_domain_ops = {
+ .read_resources = domain_read_resources,
+ .set_resources = domain_set_resources,
+ .scan_bus = domain_scan_bus,
+ .acpi_fill_ssdt = domain_fill_ssdt,
+ .acpi_name = soc_acpi_name,
+};
+
+static struct device_operations cpu_bus_ops = {
+ .read_resources = noop_read_resources,
+ .set_resources = noop_set_resources,
+ .acpi_fill_ssdt = generate_cpu_entries,
+};
+
+static void southcluster_enable_dev(struct device *dev)
+{
+ if (!dev->enabled) {
+ printk(BIOS_DEBUG, "Disable %s\n", dev_path(dev));
+ /**
+ * Mark the device as hidden so that coreboot won't complain about leftover static
+ * device.
+ */
+ dev->hidden = true;
+ pci_and_config16(dev, PCI_COMMAND,
+ ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER));
+ } else {
+ printk(BIOS_DEBUG, "Enable %s\n", dev_path(dev));
+ pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_SERR);
+ }
+}
+
+static void soc_enable_dev(struct device *dev)
+{
+ if (dev->path.type == DEVICE_PATH_DOMAIN) {
+ printk(BIOS_SPEW, "Set domain operation for %s\n", dev_path(dev));
+ dev->ops = &pci_domain_ops;
+ } else if (dev->path.type == DEVICE_PATH_CPU_CLUSTER) {
+ printk(BIOS_SPEW, "Set CPU cluster operation for %s\n", dev_path(dev));
+ dev->ops = &cpu_bus_ops;
+ } else if (dev->path.type == DEVICE_PATH_PCI) {
+ /**
+ * For a static PCH device, if it's enabled, set the SERR bits, otherwise
+ * disable the ability of issuing and responding to IO and memory requests.
+ */
+ if (is_dev_on_domain0(dev) && is_pci(dev) && is_pch_slot(dev->path.pci.devfn))
+ southcluster_enable_dev(dev);
+ }
+}
+
+struct chip_operations soc_intel_snowridge_ops = {
+ .name = "Intel Snowridge",
+ .init = &soc_init_pre_device,
+ .enable_dev = &soc_enable_dev,
+};
diff --git a/src/soc/intel/snowridge/chip.h b/src/soc/intel/snowridge/chip.h
new file mode 100644
index 0000000000..27d792a7be
--- /dev/null
+++ b/src/soc/intel/snowridge/chip.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_CHIP_H_
+#define _SOC_SNOWRIDGE_CHIP_H_
+
+#include <fsp/soc_binding.h>
+#include <intelblocks/cfg.h>
+#include <stdint.h>
+
+/**
+ * @brief Total number of domains. SNR needs two additional domains to handle
+ * additional root bus in stack 2 (Intel Dynamic Load Balancer) and 7 (UBox1).
+ */
+#define MAX_DOMAIN (BL_MAX_SOCKET * BL_MAX_LOGIC_IIO_STACK + 2)
+
+struct snr_domain {
+ uint8_t enabled;
+ uint8_t personality;
+ uint8_t bus_base;
+ uint8_t bus_limit;
+ uint16_t io_base;
+ uint16_t io_limit;
+ uint32_t mem32_base;
+ uint32_t mem32_limit;
+ uint64_t mem64_base;
+ uint64_t mem64_limit;
+ struct device *dev;
+};
+
+struct soc_intel_snowridge_config {
+ struct soc_intel_common_config common_soc_config;
+
+ uint32_t tcc_offset; /**< Needed by `common/block/cpulib.c`. */
+ uint8_t eist_enable;
+
+ struct snr_domain domain[MAX_DOMAIN];
+};
+
+typedef struct soc_intel_snowridge_config config_t;
+
+#endif // _SOC_SNOWRIDGE_CHIP_H_
diff --git a/src/soc/intel/snowridge/chipset.cb b/src/soc/intel/snowridge/chipset.cb
new file mode 100644
index 0000000000..7632b33eac
--- /dev/null
+++ b/src/soc/intel/snowridge/chipset.cb
@@ -0,0 +1,214 @@
+## SPDX-License-Identifier: GPL-2.0-only
+
+chip soc/intel/snowridge
+
+ register "common_soc_config" = "{
+ .chipset_lockdown = CHIPSET_LOCKDOWN_COREBOOT,
+ }"
+
+ # Enable Enhanced Intel SpeedStep
+ register "eist_enable" = "1"
+
+ device cpu_cluster 0 alias cpu_bus on end
+
+ device domain 0 on # S0 personality: 0x01 (UBOX_IIO)
+ #
+ # S0 hosts all the PCH peripherals and some of the CPU Complex peripherals.
+ #
+ device pci 00.0 alias pch_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S0
+ device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S0
+ device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S0
+ device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S0
+ device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S0
+ #
+ # Not found
+ # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S0
+ #
+ device pci 01.0 on end # 0x0b00 - DMA Channel 0
+ device pci 01.1 on end # 0x0b00 - DMA Channel 1
+ device pci 01.2 on end # 0x0b00 - DMA Channel 2
+ device pci 01.3 on end # 0x0b00 - DMA Channel 3
+ device pci 01.4 on end # 0x0b00 - DMA Channel 4
+ device pci 01.5 on end # 0x0b00 - DMA Channel 5
+ device pci 01.6 on end # 0x0b00 - DMA Channel 6
+ device pci 01.7 on end # 0x0b00 - DMA Channel 7
+ device pci 02.0 on end # 0x09a6 - PECI Out-Of-Band Management Services Module (OOBMSM)
+ device pci 02.1 on end # 0x09a7 - PECI OOB-MSM - Discovery
+ device pci 02.2 hidden end # 0x09a8 - Reserved
+ device pci 02.4 on end # 0x3456 - CPU Complex Intel Trace Hub
+ #
+ # QAT v.17 is SKU dependent, let coreboot autodetect it.
+ # device pci 06.0 on end # 0x18da - Intel QAT v1.7
+ #
+ device pci 07.0 on end # 0x18b3 - SATA Controller 0
+ #
+ # Let coreboot autodetect when something is plugged in.
+ # device pci 09.0 on end # 0x18a4 - PCH PCIe Cluster 0, Root Port 0
+ # device pci 0a.0 on end # 0x18a5 - PCH PCIe Cluster 0, Root Port 1
+ # device pci 0b.0 on end # 0x18a6 - PCH PCIe Cluster 0, Root Port 2
+ # device pci 0c.0 on end # 0x18a7 - PCH PCIe Cluster 0, Root Port 3
+ #
+ device pci 0e.0 on end # 0x18f3 - SATA Controller 2
+ device pci 0f.0 on end # 0x18ac - Host (DMA) SMBus
+ #
+ # Let coreboot autodetect when something is plugged in.
+ # device pci 14.0 on end # 0x18ad - PCH PCIe Cluster 2, Root Port 8
+ # device pci 15.0 on end # 0x18ae - PCH PCIe Cluster 2, Root Port 9
+ # device pci 16.0 on end # 0x18af - PCH PCIe Cluster 2, Root Port 10
+ # device pci 17.0 on end # 0x18a2 - PCH PCIe Cluster 2, Root Port 11
+ #
+ device pci 18.0 on end # 0x18d3 - Intel ME - HECI 1
+ device pci 18.1 hidden end # 0x18d4 - Reserved
+ device pci 18.2 hidden end # 0x18ea - Reserved
+ device pci 18.3 hidden end # 0x18d5 - Reserved
+ device pci 18.4 hidden end # 0x18d6 - Reserved
+ device pci 18.6 hidden end # 0x18d7 - Reserved
+ device pci 1a.0 on end # 0x18d8 - HSUART 0
+ device pci 1a.1 on end # 0x18d8 - HSUART 1
+ device pci 1a.2 on end # 0x18d8 - HSUART 2
+ device pci 1a.3 hidden end # 0x18d9 - Reserved
+ #
+ # Not found
+ # device pci 1a.4 on end # 0x18ec - Reserved
+ # device pci 1b.0 on end # 0x18e5 - Reserved
+ # device pci 1b.1 on end # 0x18e6 - Reserved
+ # device pci 1b.2 on end # 0x18e7 - Reserved
+ # device pci 1b.3 on end # 0x18e8 - Reserved
+ # device pci 1b.4 on end # 0x18e9 - Reserved
+ # device pci 1b.6 on end # 0x18eb - Reserved
+ #
+ device pci 1c.0 on end # 0x18db - eMMC Controller
+ device pci 1d.0 on end # 0x0998 - Satellite IEH - PCH
+ device pci 1e.0 on end # 0x18d0 - USB Controller
+ #
+ # Not found
+ # device pci 1e.2 on end # 0x18e3 - PCM/SRAM
+ #
+ device pci 1f.0 on end # 0x18dc - LPC/eSPI Controller
+ device pci 1f.1 on end # 0x18dd - PH Bridge Control - P2SB
+ device pci 1f.2 hidden end # 0x18de - PCH PMC
+ device pci 1f.4 on end # 0x18df - Legacy SMBus
+ device pci 1f.5 on end # 0x18e0 - SPI Controller
+ device pci 1f.7 on end # 0x18e1 - PCH Intel Trace Hub
+ end # D0 S0
+ device domain 1 on # S1 personality: 0x01 (UBOX_IIO)
+ #
+ # S1 hosts the CPU Complex PCIe Root Ports
+ #
+ device pci 00.0 alias cpu_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S1
+ device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S1
+ device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S1
+ device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S1
+ device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S1
+ #
+ # Not found
+ # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S1
+ #
+ # Let coreboot autodetect when something is plugged in.
+ # device pci 04.0 on end # 0x334a - CPU PCIe Root Port - A link widths: x16, x8, x4, x2, x1
+ # device pci 05.0 on end # 0x334b - CPU PCIe Root Port - B link widths: x4, x2, x1
+ # device pci 06.0 on end # 0x334c - CPU PCIe Root Port - C link widths: x8, x4, x2, x1
+ # device pci 07.0 on end # 0x334d - CPU PCIe Root Port - D link widths: x4, x2, x1
+ #
+ end # D1 S1
+ device domain 2 on # S2 personality: 0x05 (NAC)
+ device pci 00.0 alias dlb_sa on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S2
+ device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S2
+ device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S2
+ device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S2
+ device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S2
+ #
+ # Not found
+ # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S2
+ #
+ end # D2 S2
+ device domain 3 on # S3 personality: 0x05 (NAC)
+ #
+ # S3 hosts the VRP to the Network Interface and Scheduler (NIS)
+ #
+ device pci 00.0 on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S3
+ device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S3
+ device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S3
+ device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S3
+ device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S3
+ #
+ # Not found
+ # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S3
+ #
+ device pci 04.0 alias nis_vrp on # 0x18d1 - VRP to Network Interface and Scheduler (NIS)
+ #
+ # NIS devices are SKU dependent, let coreboot autodetect them.
+ #
+ end
+ end # D3 S3
+ device domain 4 on # S4 personality: 0x05 (NAC)
+ #
+ # S4 hosts the Intel QAT v1.8 accelerator and the iRC-NAC
+ #
+ device pci 00.0 on end # 0x09a2 - Mesh2IIO MMAP/Intel VT-d - Bus S4
+ device pci 00.1 on end # 0x09a4 - Mesh2IIO PMU/PMON - Bus S4
+ device pci 00.2 on end # 0x09a3 - Mesh2IIO RAS - Bus S4
+ device pci 00.3 on end # 0x09a5 - Mesh2IIO DFx - Bus S4
+ device pci 00.4 on end # 0x0998 - Satellite IEH - Bus S4
+ #
+ # Not found
+ # device pci 00.5 off end # 0x28c0 - VMD2 - Bus S4
+ #
+ device pci 05.0 alias qat_1_8_vrp on # 0x18da - VRP for Intel QAT v1.8 accelerator
+ device pci 00.0 on end # 0x18a0 - Intel QAT v1.8 accelerator
+ end
+ device pci 06.0 on end # 0x18e2 - NAC Intelligent Reset Controller (iRC)
+ end # D4 S4
+ device domain 5 off # Personality: 0x12 (None)
+ end # D5 S5
+ device domain 6 off # Personality: 0x08 (Reserved)
+ end # D6 S6
+ device domain 7 on # Personality: 0x00 (Ubox) U0
+ #
+ # U0 is the second-highest bus number assigned to the device
+ # U0 hosts the Ubox, Serial Presence Detect (SPD) SMBus,
+ # Virtual Pin Port (VPP) SMBus, the Memory Controller, and DDRIO
+ #
+ device pci 00.0 on end # 0x3460 - Ubox - Noncoherent Events (NCEVENTS)
+ device pci 00.1 on end # 0x3451 - Ubox - Register Access Control Unit (RACU)
+ device pci 00.2 on end # 0x3452 - Ubox - Noncoherent Decode (NCDECS)
+ device pci 00.3 on end # 0x0998 - Ubox - Global I/O Error Handler (Global IEH)
+ device pci 00.5 on end # 0x3455 - Ubox - Error Handling
+ device pci 0b.0 on end # 0x3448 - Ubox - SPD0 SMBus
+ device pci 0b.1 on end # 0x3449 - Ubox - SPD1 SMBus. Note: SoC does not pin out it.
+ device pci 0b.2 hidden end # 0x344b - Ubox - Reserved
+ device pci 0c.0 on end # 0x344a - Ubox - IMC
+ device pci 1a.0 on end # 0x2880 - Ubox - DDRIO
+ end # D7 U0
+ device domain 8 on # U1 - additional root bus 0xFF for domain/stack 7
+ #
+ # U1 is the highest bus number assigned to the device
+ # U1 hosts the Cache and Home Agent (CHA) and Power Control Unit (PCU)
+ #
+ device pci 00.0 on end # 0x344c - CHA0_GRP1 - Mesh Credit Configuration
+ device pci 00.1 on end # 0x344c - CHA1_GRP1 - Mesh Credit Configuration
+ device pci 00.2 on end # 0x344c - CHA2_GRP1 - Mesh Credit Configuration
+ device pci 00.3 on end # 0x344c - CHA3_GRP1 - Mesh Credit Configuration
+ device pci 00.4 on end # 0x344c - CHA4_GRP1 - Mesh Credit Configuration
+ device pci 00.5 on end # 0x344c - CHA5_GRP1 - Mesh Credit Configuration
+ device pci 0a.0 on end # 0x344d - CHA0_GRP0 - IMC Channel Mapping
+ device pci 0a.1 on end # 0x344d - CHA1_GRP0 - IMC Channel Mapping
+ device pci 0a.2 on end # 0x344d - CHA2_GRP0 - IMC Channel Mapping
+ device pci 0a.3 on end # 0x344d - CHA3_GRP0 - IMC Channel Mapping
+ device pci 0a.4 on end # 0x344d - CHA4_GRP0 - IMC Channel Mapping
+ device pci 0a.5 on end # 0x344d - CHA5_GRP0 - IMC Channel Mapping
+ device pci 1d.0 on end # 0x344f - CHAALL0 - Multicast DRAM Rules
+ device pci 1d.1 on end # 0x3457 - CHAALL1 - Multicast MMIO Rules
+ device pci 1e.0 on end # 0x3458 - Power Control Unit (PCU)
+ device pci 1e.1 on end # 0x3459 - PCU
+ device pci 1e.2 on end # 0x345a - PCU
+ device pci 1e.3 on end # 0x345b - PCU
+ device pci 1e.4 on end # 0x345c - PCU
+ device pci 1e.5 on end # 0x345d - PCU
+ device pci 1e.6 on end # 0x345e - PCU
+ device pci 1e.7 on end # 0x345f - PCU
+ end # D8 U1
+ device domain 9 on # Additional root bus 0xE7 for domain/stack 2
+ device pci 0.0 alias dlb on end # 0x270b - Intel DLB 1.0
+ end
+end #chip
diff --git a/src/soc/intel/snowridge/common/fsp_hob.c b/src/soc/intel/snowridge/common/fsp_hob.c
new file mode 100644
index 0000000000..426e6c3cf9
--- /dev/null
+++ b/src/soc/intel/snowridge/common/fsp_hob.c
@@ -0,0 +1,49 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <fsp/util.h>
+
+#include "fsp_hob.h"
+
+const guid_t fsp_hob_fia_override_status_guid = {
+ .b = {0xc1, 0x94, 0x8d, 0x61, 0xde, 0x0e, 0xe3, 0x4e, 0x98, 0x4F, 0xB2, 0x07, 0x6B,
+ 0x05, 0x50, 0xFB}
+};
+
+const guid_t fsp_hob_iio_uds_data_guid = {
+ .b = {0xbd, 0x74, 0x6b, 0x83, 0xf3, 0xc2, 0x28, 0x4d, 0xa3, 0xb8, 0x91, 0x33, 0x10,
+ 0x52, 0x52, 0x9b}
+};
+
+const guid_t fsp_hob_kti_cache_guid = {
+ .b = {0xd6, 0xd3, 0x45, 0xac, 0x6e, 0xa3, 0xa6, 0x43, 0xad, 0x17, 0x0a, 0x45, 0xbb,
+ 0x47, 0xbe, 0xd6}
+};
+
+const guid_t fsp_hob_smbios_memory_info_guid = {
+ .b = {0x8c, 0x10, 0xa1, 0x01, 0xee, 0x9d, 0x84, 0x49, 0x88, 0xc3, 0xee, 0xe8, 0xc4,
+ 0x9e, 0xfb, 0x89}
+};
+
+static const void *fsp_hob_get(const guid_t *guid, size_t *hob_size)
+{
+ return fsp_find_extension_hob_by_guid(guid->b, hob_size);
+}
+
+const BL_IIO_UDS *fsp_hob_get_iio_uds_data(void)
+{
+ size_t unused;
+
+ return fsp_hob_get(&fsp_hob_iio_uds_data_guid, &unused);
+}
+
+const void *fsp_hob_get_kti_cache(size_t *hob_size)
+{
+ return fsp_hob_get(&fsp_hob_kti_cache_guid, hob_size);
+}
+
+const FSP_SMBIOS_MEMORY_INFO *fsp_hob_get_memory_info(void)
+{
+ size_t unused;
+
+ return fsp_hob_get(&fsp_hob_smbios_memory_info_guid, &unused);
+}
diff --git a/src/soc/intel/snowridge/common/fsp_hob.h b/src/soc/intel/snowridge/common/fsp_hob.h
new file mode 100644
index 0000000000..e5c96bdd27
--- /dev/null
+++ b/src/soc/intel/snowridge/common/fsp_hob.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_FSP_HOB_H_
+#define _SOC_SNOWRIDGE_FSP_HOB_H_
+
+#include <fsp/soc_binding.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <uuid.h>
+
+extern const guid_t fsp_hob_fia_override_status_guid;
+extern const guid_t fsp_hob_iio_uds_data_guid;
+extern const guid_t fsp_hob_kti_cache_guid;
+extern const guid_t fsp_hob_smbios_memory_info_guid;
+
+const BL_IIO_UDS *fsp_hob_get_iio_uds_data(void);
+const void *fsp_hob_get_kti_cache(size_t *hob_size);
+const FSP_SMBIOS_MEMORY_INFO *fsp_hob_get_memory_info(void);
+
+#endif // _SOC_SNOWRIDGE_FSP_HOB_H_
diff --git a/src/soc/intel/snowridge/common/gpio.c b/src/soc/intel/snowridge/common/gpio.c
new file mode 100644
index 0000000000..8bf5edf50e
--- /dev/null
+++ b/src/soc/intel/snowridge/common/gpio.c
@@ -0,0 +1,314 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/gpio.h>
+#include <soc/gpio_snr.h>
+#include <soc/pcr_ids.h>
+
+static const struct pad_group snr_community_west2_groups[] = {
+ INTEL_GPP(GPIO_WEST2_0, GPIO_WEST2_0, GPIO_WEST2_23),
+};
+
+static const struct pad_group snr_community_west3_groups[] = {
+ INTEL_GPP(GPIO_WEST3_0, GPIO_WEST3_0, GPIO_WEST3_23),
+};
+
+static const struct pad_group snr_community_west01_groups[] = {
+ INTEL_GPP(GPIO_WEST01_0, GPIO_WEST01_0, GPIO_WEST01_22),
+};
+
+static const struct pad_group snr_community_west5_groups[] = {
+ INTEL_GPP(GPIO_WEST5_0, GPIO_WEST5_0, GPIO_WEST5_18),
+};
+
+static const struct pad_group snr_community_westb_groups[] = {
+ INTEL_GPP(GPIO_WESTB_0, GPIO_WESTB_0, GPIO_WESTB_11),
+};
+
+static const struct pad_group snr_community_westd_peci_groups[] = {
+ INTEL_GPP(GPIO_WESTD_PECI_0, GPIO_WESTD_PECI_0, GPIO_WESTD_PECI_0),
+};
+
+static const struct pad_group snr_community_east2_groups[] = {
+ INTEL_GPP(GPIO_EAST2_0, GPIO_EAST2_0, GPIO_EAST2_23),
+};
+
+static const struct pad_group snr_community_east3_groups[] = {
+ INTEL_GPP(GPIO_EAST3_0, GPIO_EAST3_0, GPIO_EAST3_9),
+};
+
+static const struct pad_group snr_community_east0_groups[] = {
+ INTEL_GPP(GPIO_EAST0_0, GPIO_EAST0_0, GPIO_EAST0_22),
+};
+
+static const struct pad_group snr_community_emmc_groups[] = {
+ INTEL_GPP(GPIO_EMMC_0, GPIO_EMMC_0, GPIO_EMMC_10),
+};
+
+static const struct pad_community snr_gpio_communities[] = {
+ {
+ .name = "GPIO_WEST2",
+ .acpi_path = "\\_SB.GPO0",
+ .num_gpi_regs = GPIO_WEST2_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WEST2_0,
+ .last_pad = GPIO_WEST2_23,
+ .pad_own_reg_0 = GPIO_WEST2_PAD_OWN,
+ .host_own_reg_0 = GPIO_WEST2_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WEST2_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WEST2_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WEST2_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WEST2_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WEST2_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WEST2_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WEST2_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WEST2_NMI_EN,
+ .pad_cfg_base = GPIO_WEST2_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WEST2_PADCFGLOCK,
+ .gpi_status_offset = 0,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_west2_groups,
+ .num_groups = ARRAY_SIZE(snr_community_west2_groups),
+ },
+ {
+ .name = "GPIO_WEST3",
+ .acpi_path = "\\_SB.GPO1",
+ .num_gpi_regs = GPIO_WEST3_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WEST3_0,
+ .last_pad = GPIO_WEST3_23,
+ .pad_own_reg_0 = GPIO_WEST3_PAD_OWN,
+ .host_own_reg_0 = GPIO_WEST3_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WEST3_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WEST3_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WEST3_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WEST3_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WEST3_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WEST3_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WEST3_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WEST3_NMI_EN,
+ .pad_cfg_base = GPIO_WEST3_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WEST3_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_west3_groups,
+ .num_groups = ARRAY_SIZE(snr_community_west3_groups),
+ },
+ {
+ .name = "GPIO_WEST01",
+ .acpi_path = "\\_SB.GPO2",
+ .num_gpi_regs = GPIO_WEST01_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WEST01_0,
+ .last_pad = GPIO_WEST01_22,
+ .pad_own_reg_0 = GPIO_WEST01_PAD_OWN,
+ .host_own_reg_0 = GPIO_WEST01_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WEST01_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WEST01_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WEST01_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WEST01_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WEST01_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WEST01_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WEST01_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WEST01_NMI_EN,
+ .pad_cfg_base = GPIO_WEST01_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WEST01_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_west01_groups,
+ .num_groups = ARRAY_SIZE(snr_community_west01_groups),
+ },
+ {
+ .name = "GPIO_WEST5",
+ .acpi_path = "\\_SB.GPO3",
+ .num_gpi_regs = GPIO_WEST5_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WEST5_0,
+ .last_pad = GPIO_WEST5_18,
+ .pad_own_reg_0 = GPIO_WEST5_PAD_OWN,
+ .host_own_reg_0 = GPIO_WEST5_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WEST5_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WEST5_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WEST5_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WEST5_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WEST5_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WEST5_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WEST5_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WEST5_NMI_EN,
+ .pad_cfg_base = GPIO_WEST5_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WEST5_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_west5_groups,
+ .num_groups = ARRAY_SIZE(snr_community_west5_groups),
+ },
+ {
+ .name = "GPIO_WESTB",
+ .acpi_path = "\\_SB.GPO4",
+ .num_gpi_regs = GPIO_WESTB_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WESTB_0,
+ .last_pad = GPIO_WESTB_11,
+ .pad_own_reg_0 = GPIO_WESTB_PAD_OWN,
+ .host_own_reg_0 = GPIO_WESTB_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WESTB_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WESTB_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WESTB_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WESTB_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WESTB_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WESTB_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WESTB_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WESTB_NMI_EN,
+ .pad_cfg_base = GPIO_WESTB_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WESTB_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_westb_groups,
+ .num_groups = ARRAY_SIZE(snr_community_westb_groups),
+ },
+ {
+ .name = "GPIO_WESTD_PECI",
+ .acpi_path = "\\_SB.GPO5",
+ .num_gpi_regs = GPIO_WESTD_PECI_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_WESTD_PECI_0,
+ .last_pad = GPIO_WESTD_PECI_0,
+ .pad_own_reg_0 = GPIO_WESTD_PECI_PAD_OWN,
+ .host_own_reg_0 = GPIO_WESTD_PECI_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_WESTD_PECI_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_WESTD_PECI_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_WESTD_PECI_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_WESTD_PECI_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_WESTD_PECI_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_WESTD_PECI_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_WESTD_PECI_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_WESTD_PECI_NMI_EN,
+ .pad_cfg_base = GPIO_WESTD_PECI_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_WESTD_PECI_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS +
+ GPIO_WESTB_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM1,
+ .groups = snr_community_westd_peci_groups,
+ .num_groups = ARRAY_SIZE(snr_community_westd_peci_groups),
+ },
+ {
+ .name = "GPIO_EAST2",
+ .acpi_path = "\\_SB.GPO11",
+ .num_gpi_regs = GPIO_EAST2_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_EAST2_0,
+ .last_pad = GPIO_EAST2_23,
+ .pad_own_reg_0 = GPIO_EAST2_PAD_OWN,
+ .host_own_reg_0 = GPIO_EAST2_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_EAST2_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_EAST2_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_EAST2_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_EAST2_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_EAST2_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_EAST2_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_EAST2_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_EAST2_NMI_EN,
+ .pad_cfg_base = GPIO_EAST2_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_EAST2_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS +
+ GPIO_WESTB_GPI_STATUS_REGS +
+ GPIO_WESTD_PECI_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM0,
+ .groups = snr_community_east2_groups,
+ .num_groups = ARRAY_SIZE(snr_community_east2_groups),
+ },
+ {
+ .name = "GPIO_EAST3",
+ .acpi_path = "\\_SB.GPO12",
+ .num_gpi_regs = GPIO_EAST3_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_EAST3_0,
+ .last_pad = GPIO_EAST3_9,
+ .pad_own_reg_0 = GPIO_EAST3_PAD_OWN,
+ .host_own_reg_0 = GPIO_EAST3_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_EAST3_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_EAST3_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_EAST3_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_EAST3_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_EAST3_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_EAST3_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_EAST3_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_EAST3_NMI_EN,
+ .pad_cfg_base = GPIO_EAST3_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_EAST3_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS +
+ GPIO_WESTB_GPI_STATUS_REGS +
+ GPIO_WESTD_PECI_GPI_STATUS_REGS +
+ GPIO_EAST2_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM0,
+ .groups = snr_community_east3_groups,
+ .num_groups = ARRAY_SIZE(snr_community_east3_groups),
+ },
+ {
+ .name = "GPIO_EAST0",
+ .acpi_path = "\\_SB.GPO13",
+ .num_gpi_regs = GPIO_EAST0_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_EAST0_0,
+ .last_pad = GPIO_EAST0_22,
+ .pad_own_reg_0 = GPIO_EAST0_PAD_OWN,
+ .host_own_reg_0 = GPIO_EAST0_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_EAST0_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_EAST0_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_EAST0_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_EAST0_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_EAST0_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_EAST0_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_EAST0_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_EAST0_NMI_EN,
+ .pad_cfg_base = GPIO_EAST0_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_EAST0_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS +
+ GPIO_WESTB_GPI_STATUS_REGS +
+ GPIO_WESTD_PECI_GPI_STATUS_REGS +
+ GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM0,
+ .groups = snr_community_east0_groups,
+ .num_groups = ARRAY_SIZE(snr_community_east0_groups),
+ },
+ {
+ .name = "GPIO_EMMC",
+ .acpi_path = "\\_SB.GPO14",
+ .num_gpi_regs = GPIO_EMMC_GPI_STATUS_REGS,
+ .max_pads_per_group = GPIO_MAX_NUM_PER_GROUP,
+ .first_pad = GPIO_EMMC_0,
+ .last_pad = GPIO_EMMC_10,
+ .pad_own_reg_0 = GPIO_EMMC_PAD_OWN,
+ .host_own_reg_0 = GPIO_EMMC_HOSTSW_OWN,
+ .gpi_int_sts_reg_0 = GPIO_EMMC_GPI_IS,
+ .gpi_int_en_reg_0 = GPIO_EMMC_GPI_IE,
+ .gpi_smi_sts_reg_0 = GPIO_EMMC_SMI_STS,
+ .gpi_smi_en_reg_0 = GPIO_EMMC_SMI_EN,
+ .gpi_gpe_sts_reg_0 = GPIO_EMMC_GPI_GPE_STS,
+ .gpi_gpe_en_reg_0 = GPIO_EMMC_GPI_GPE_EN,
+ .gpi_nmi_sts_reg_0 = GPIO_EMMC_NMI_STS,
+ .gpi_nmi_en_reg_0 = GPIO_EMMC_NMI_EN,
+ .pad_cfg_base = GPIO_EMMC_PADCFG_OFFSET,
+ .pad_cfg_lock_offset = GPIO_EMMC_PADCFGLOCK,
+ .gpi_status_offset = GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS +
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS +
+ GPIO_WESTB_GPI_STATUS_REGS +
+ GPIO_WESTD_PECI_GPI_STATUS_REGS +
+ GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS +
+ GPIO_EAST0_GPI_STATUS_REGS,
+ .port = PID_GPIOCOM0,
+ .groups = snr_community_emmc_groups,
+ .num_groups = ARRAY_SIZE(snr_community_emmc_groups),
+ }
+};
+
+const struct pad_community *soc_gpio_get_community(size_t *num_communities)
+{
+ *num_communities = ARRAY_SIZE(snr_gpio_communities);
+ return snr_gpio_communities;
+}
diff --git a/src/soc/intel/snowridge/common/hob_display.c b/src/soc/intel/snowridge/common/hob_display.c
new file mode 100644
index 0000000000..eaed9c674b
--- /dev/null
+++ b/src/soc/intel/snowridge/common/hob_display.c
@@ -0,0 +1,312 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <fsp/debug.h>
+#include <fsp/soc_binding.h>
+#include <fsp/util.h>
+#include <lib.h>
+#include <uuid.h>
+
+#include "fsp_hob.h"
+
+struct guid_name_map {
+ const guid_t *guid;
+ const char *name;
+};
+
+static const struct guid_name_map guid_names[] = {
+ {&fsp_hob_fia_override_status_guid, "FSP_HOB_FIA_OVERRIDE_STATUS_GUID"},
+ {&fsp_hob_iio_uds_data_guid, "FSP_HOB_IIO_UDS_DATA_GUID" },
+ {&fsp_hob_kti_cache_guid, "FSP_HOB_KTI_HOST_NVRAM_DATA_GUID"},
+ {&fsp_hob_smbios_memory_info_guid, "FSP_HOB_SMBIOS_MEMORY_INFO_GUID" },
+};
+
+const char *soc_get_guid_name(const uint8_t *guid)
+{
+ size_t index;
+
+ /* Compare the GUID values in this module */
+ for (index = 0; index < ARRAY_SIZE(guid_names); index++)
+ if (fsp_guid_compare(guid, guid_names[index].guid->b))
+ return guid_names[index].name;
+
+ return NULL;
+}
+
+static void soc_display_fsp_iio_uds_data_hob(const BL_IIO_UDS *hob)
+{
+ if (!hob) {
+ return;
+ }
+
+ printk(BIOS_DEBUG, "IIO UDS\n");
+ printk(BIOS_DEBUG, "\t Platform Data\n");
+ printk(BIOS_DEBUG, "\t\t PlatGlobalIoBase: 0x%x\n", hob->PlatformData.PlatGlobalIoBase);
+ printk(BIOS_DEBUG, "\t\t PlatGlobalIoLimit: 0x%x\n",
+ hob->PlatformData.PlatGlobalIoLimit);
+ printk(BIOS_DEBUG, "\t\t PlatGlobalMmio32Base: 0x%x\n",
+ hob->PlatformData.PlatGlobalMmio32Base);
+ printk(BIOS_DEBUG, "\t\t PlatGlobalMmio32Limit: 0x%x\n",
+ hob->PlatformData.PlatGlobalMmio32Limit);
+ printk(BIOS_DEBUG, "\t\t PlatGlobalMmio64Base: 0x%llx\n",
+ hob->PlatformData.PlatGlobalMmio64Base);
+ printk(BIOS_DEBUG, "\t\t PlatGlobalMmio64Limit: 0x%llx\n",
+ hob->PlatformData.PlatGlobalMmio64Limit);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ const BL_QPI_CPU_DATA *cpu_qpi_info = &hob->PlatformData.CpuQpiInfo[socket];
+ printk(BIOS_DEBUG, "\t\t CpuQpiInfo[%d]\n", socket);
+ printk(BIOS_DEBUG, "\t\t\t Valid: 0x%x\n", cpu_qpi_info->Valid);
+ for (int bar = 0; bar < BL_TYPE_MAX_MMIO_BAR; bar++) {
+ printk(BIOS_DEBUG, "\t\t\t MmioBar[%d]: 0x%x\n", bar,
+ cpu_qpi_info->MmioBar[bar]);
+ }
+ printk(BIOS_DEBUG, "\t\t\t PcieSegment: 0x%x\n", cpu_qpi_info->PcieSegment);
+ printk(BIOS_DEBUG, "\t\t\t SegMmcfgBase: 0x%llx\n",
+ cpu_qpi_info->SegMmcfgBase.Data);
+ printk(BIOS_DEBUG, "\t\t\t stackPresentBitmap: 0x%x\n",
+ cpu_qpi_info->stackPresentBitmap);
+ printk(BIOS_DEBUG, "\t\t\t M2PciePresentBitmap: 0x%x\n",
+ cpu_qpi_info->M2PciePresentBitmap);
+ printk(BIOS_DEBUG, "\t\t\t TotM3Kti: 0x%x\n", cpu_qpi_info->TotM3Kti);
+ printk(BIOS_DEBUG, "\t\t\t TotCha: 0x%x\n", cpu_qpi_info->TotCha);
+ for (int cha = 0; cha < BL_MAX_CHA_MAP; cha++) {
+ printk(BIOS_DEBUG, "\t\t\t ChaList[%d]: 0x%x\n", cha,
+ cpu_qpi_info->ChaList[cha]);
+ }
+ printk(BIOS_DEBUG, "\t\t\t SocId: 0x%x\n", cpu_qpi_info->SocId);
+ for (int peer = 0; peer < BL_MAX_FW_KTI_PORTS; peer++) {
+ const BL_QPI_PEER_DATA *peer_info = &cpu_qpi_info->PeerInfo[peer];
+ printk(BIOS_DEBUG, "\t\t\t PeerInfo[%d]\n", peer);
+ printk(BIOS_DEBUG, "\t\t\t\t Valid: 0x%x\n", peer_info->Valid);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerSocId: 0x%x\n", peer_info->PeerSocId);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerSocType: 0x%x\n",
+ peer_info->PeerSocType);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerPort: 0x%x\n", peer_info->PeerPort);
+ }
+ }
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ const BL_QPI_IIO_DATA *iio_qpi_info = &hob->PlatformData.IioQpiInfo[socket];
+ printk(BIOS_DEBUG, "\t\t IioQpiInfo[%d]\n", socket);
+ printk(BIOS_DEBUG, "\t\t\t SocId: 0x%x\n", iio_qpi_info->SocId);
+ for (int peer = 0; peer < BL_MAX_SOCKET; peer++) {
+ const BL_QPI_PEER_DATA *peer_info = &iio_qpi_info->PeerInfo[peer];
+ printk(BIOS_DEBUG, "\t\t\t PeerInfo[%d]\n", peer);
+ printk(BIOS_DEBUG, "\t\t\t\t Valid: 0x%x\n", peer_info->Valid);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerSocId: 0x%x\n", peer_info->PeerSocId);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerSocType: 0x%x\n",
+ peer_info->PeerSocType);
+ printk(BIOS_DEBUG, "\t\t\t\t PeerPort: 0x%x\n", peer_info->PeerPort);
+ }
+ }
+ printk(BIOS_DEBUG, "\t\t MemTsegSize: 0x%x\n", hob->PlatformData.MemTsegSize);
+ printk(BIOS_DEBUG, "\t\t MemIedSize: 0x%x\n", hob->PlatformData.MemIedSize);
+ printk(BIOS_DEBUG, "\t\t PciExpressBase: 0x%llx\n", hob->PlatformData.PciExpressBase);
+ printk(BIOS_DEBUG, "\t\t PciExpressSize: 0x%x\n", hob->PlatformData.PciExpressSize);
+ printk(BIOS_DEBUG, "\t\t MemTolm: 0x%x\n", hob->PlatformData.MemTolm);
+ for (uint8_t socket = 0; socket < hob->PlatformData.numofIIO; socket++) {
+ const BL_IIO_RESOURCE_INSTANCE *iio_res =
+ &hob->PlatformData.IIO_resource[socket];
+ printk(BIOS_DEBUG, "\t\t IIO_resource[%d]\n", socket);
+ printk(BIOS_DEBUG, "\t\t\t Valid: 0x%x\n", iio_res->Valid);
+ printk(BIOS_DEBUG, "\t\t\t SocketID: 0x%x\n", iio_res->SocketID);
+ printk(BIOS_DEBUG, "\t\t\t BusBase: 0x%x\n", iio_res->BusBase);
+ printk(BIOS_DEBUG, "\t\t\t BusLimit: 0x%x\n", iio_res->BusLimit);
+ printk(BIOS_DEBUG, "\t\t\t PciResourceIoBase: 0x%x\n",
+ iio_res->PciResourceIoBase);
+ printk(BIOS_DEBUG, "\t\t\t PciResourceIoLimit: 0x%x\n",
+ iio_res->PciResourceIoLimit);
+ printk(BIOS_DEBUG, "\t\t\t IoApicBase: 0x%x\n", iio_res->IoApicBase);
+ printk(BIOS_DEBUG, "\t\t\t IoApicLimit: 0x%x\n", iio_res->IoApicLimit);
+ printk(BIOS_DEBUG, "\t\t\t Mmio32Base: 0x%x\n", iio_res->Mmio32Base);
+ printk(BIOS_DEBUG, "\t\t\t Mmio32Limit: 0x%x\n", iio_res->Mmio32Limit);
+ printk(BIOS_DEBUG, "\t\t\t Mmio64Base: 0x%llx\n", iio_res->Mmio64Base);
+ printk(BIOS_DEBUG, "\t\t\t Mmio64Limit: 0x%llx\n", iio_res->Mmio64Limit);
+ for (int stack = 0; stack < BL_MAX_LOGIC_IIO_STACK; stack++) {
+ const BL_STACK_RES *stack_res = &iio_res->StackRes[stack];
+ printk(BIOS_DEBUG, "\t\t\t StackRes[%d]\n", stack);
+ printk(BIOS_DEBUG, "\t\t\t\t Personality: 0x%x\n",
+ stack_res->Personality);
+ printk(BIOS_DEBUG, "\t\t\t\t BusBase: 0x%x\n", stack_res->BusBase);
+ printk(BIOS_DEBUG, "\t\t\t\t BusLimit: 0x%x\n", stack_res->BusLimit);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceIoBase: 0x%x\n",
+ stack_res->PciResourceIoBase);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceIoLimit: 0x%x\n",
+ stack_res->PciResourceIoLimit);
+ printk(BIOS_DEBUG, "\t\t\t\t IoApicBase: 0x%x\n",
+ stack_res->IoApicBase);
+ printk(BIOS_DEBUG, "\t\t\t\t IoApicLimit: 0x%x\n",
+ stack_res->IoApicLimit);
+ printk(BIOS_DEBUG, "\t\t\t\t Mmio32Base: 0x%x\n",
+ stack_res->Mmio32Base);
+ printk(BIOS_DEBUG, "\t\t\t\t Mmio32Limit: 0x%x\n",
+ stack_res->Mmio32Limit);
+ printk(BIOS_DEBUG, "\t\t\t\t Mmio64Base: 0x%llx\n",
+ stack_res->Mmio64Base);
+ printk(BIOS_DEBUG, "\t\t\t\t Mmio64Limit: 0x%llx\n",
+ stack_res->Mmio64Limit);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem32Base: 0x%x\n",
+ stack_res->PciResourceMem32Base);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem32Limit: 0x%x\n",
+ stack_res->PciResourceMem32Limit);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem64Base: 0x%llx\n",
+ stack_res->PciResourceMem64Base);
+ printk(BIOS_DEBUG, "\t\t\t\t PciResourceMem64Limit: 0x%llx\n",
+ stack_res->PciResourceMem64Limit);
+ printk(BIOS_DEBUG, "\t\t\t\t VtdBarAddress: 0x%x\n",
+ stack_res->VtdBarAddress);
+ printk(BIOS_DEBUG, "\t\t\t\t Mmio32MinSize: 0x%x\n",
+ stack_res->Mmio32MinSize);
+ }
+ printk(BIOS_DEBUG, "\t\t\t RcBaseAddress: 0x%x\n", iio_res->RcBaseAddress);
+ printk(BIOS_DEBUG, "\t\t\t PcieInfo\n");
+ for (int port = 0; port < BL_NUMBER_PORTS_PER_SOCKET; port++) {
+ const BL_IIO_PORT_INFO *port_info = &iio_res->PcieInfo.PortInfo[port];
+ printk(BIOS_DEBUG, "\t\t\t\t PortInfo[%d]\n", port);
+ printk(BIOS_DEBUG, "\t\t\t\t\t Device: 0x%x, Function: 0x%x\n",
+ port_info->Device, port_info->Function);
+ }
+ printk(BIOS_DEBUG, "\t\t\t DmaDeviceCount: 0x%x\n", iio_res->DmaDeviceCount);
+ }
+ printk(BIOS_DEBUG, "\t\t numofIIO: 0x%x\n", hob->PlatformData.numofIIO);
+ printk(BIOS_DEBUG, "\t\t MaxBusNumber: 0x%x\n", hob->PlatformData.MaxBusNumber);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ printk(BIOS_DEBUG, "\t\t packageBspApicID[%d]: 0x%x\n", socket,
+ hob->PlatformData.packageBspApicID[socket]);
+ }
+ printk(BIOS_DEBUG, "\t\t EVMode: 0x%x\n", hob->PlatformData.EVMode);
+ printk(BIOS_DEBUG, "\t\t Pci64BitResourceAllocation: %d\n",
+ hob->PlatformData.Pci64BitResourceAllocation);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ printk(BIOS_DEBUG, "\t\t SkuPersonality[%d]: 0x%x\n", socket,
+ hob->PlatformData.SkuPersonality[socket]);
+ }
+ for (int iio = 0; iio < BL_MaxIIO; iio++) {
+ for (int iio_stack = 0; iio_stack < BL_MAX_IIO_STACK; iio_stack++) {
+ printk(BIOS_DEBUG, "\t\t VMDStackEnable[%d][%d]: 0x%x\n", iio,
+ iio_stack, hob->PlatformData.VMDStackEnable[iio][iio_stack]);
+ }
+ }
+ printk(BIOS_DEBUG, "\t\t IoGranularity: 0x%x\n", hob->PlatformData.IoGranularity);
+ printk(BIOS_DEBUG, "\t\t MmiolGranularity: 0x%x\n", hob->PlatformData.MmiolGranularity);
+ printk(BIOS_DEBUG, "\t\t MmiohGranularity: 0x%llx\n",
+ hob->PlatformData.MmiohGranularity.Data);
+ printk(BIOS_DEBUG, "\t\t RemoteRequestThreshold: 0x%x\n",
+ hob->PlatformData.RemoteRequestThreshold);
+ printk(BIOS_DEBUG, "\t\t UboxMmioSize: 0x%x\n", hob->PlatformData.UboxMmioSize);
+ printk(BIOS_DEBUG, "\t\t MaxAddressBits: 0x%x\n", hob->PlatformData.MaxAddressBits);
+
+ printk(BIOS_DEBUG, "\t System Status\n");
+ printk(BIOS_DEBUG, "\t\t CurrentUpiiLinkSpeed: 0x%x\n",
+ hob->SystemStatus.CurrentUpiiLinkSpeed);
+ printk(BIOS_DEBUG, "\t\t CurrentUpiLinkFrequency: 0x%x\n",
+ hob->SystemStatus.CurrentUpiLinkFrequency);
+ printk(BIOS_DEBUG, "\t\t OutKtiCpuSktHotPlugEn: 0x%x\n",
+ hob->SystemStatus.OutKtiCpuSktHotPlugEn);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++)
+ printk(BIOS_DEBUG, "\t\t OutKtiPerLinkL1En: 0x%x\n",
+ hob->SystemStatus.OutKtiPerLinkL1En[socket]);
+ printk(BIOS_DEBUG, "\t\t IsocEnable: 0x%x\n", hob->SystemStatus.IsocEnable);
+ printk(BIOS_DEBUG, "\t\t meRequestedSize: 0x%x\n", hob->SystemStatus.meRequestedSize);
+ printk(BIOS_DEBUG, "\t\t ieRequestedSize: 0x%x\n", hob->SystemStatus.ieRequestedSize);
+ printk(BIOS_DEBUG, "\t\t DmiVc1: 0x%x\n", hob->SystemStatus.DmiVc1);
+ printk(BIOS_DEBUG, "\t\t DmiVcm: 0x%x\n", hob->SystemStatus.DmiVcm);
+ printk(BIOS_DEBUG, "\t\t CpuPCPSInfo: 0x%x\n", hob->SystemStatus.CpuPCPSInfo);
+ printk(BIOS_DEBUG, "\t\t cpuSubType: 0x%x\n", hob->SystemStatus.cpuSubType);
+ printk(BIOS_DEBUG, "\t\t SystemRasType: 0x%x\n", hob->SystemStatus.SystemRasType);
+ printk(BIOS_DEBUG, "\t\t numCpus: 0x%x\n", hob->SystemStatus.numCpus);
+ printk(BIOS_DEBUG, "\t\t tolmLimit: 0x%x\n", hob->SystemStatus.tolmLimit);
+ printk(BIOS_DEBUG, "\t\t tohmLimit: 0x%x\n", hob->SystemStatus.tohmLimit);
+ printk(BIOS_DEBUG, "\t\t RcVersion\n");
+ printk(BIOS_DEBUG, "\t\t\t Major: 0x%x\n", hob->SystemStatus.RcVersion.Major);
+ printk(BIOS_DEBUG, "\t\t\t Minor: 0x%x\n", hob->SystemStatus.RcVersion.Minor);
+ printk(BIOS_DEBUG, "\t\t\t Revision: 0x%x\n", hob->SystemStatus.RcVersion.Revision);
+ printk(BIOS_DEBUG, "\t\t\t BuildNumber: 0x%x\n",
+ hob->SystemStatus.RcVersion.BuildNumber);
+ printk(BIOS_DEBUG, "\t\t MsrTraceEnable: 0x%x\n", hob->SystemStatus.MsrTraceEnable);
+ printk(BIOS_DEBUG, "\t\t DdrXoverMode: 0x%x\n", hob->SystemStatus.DdrXoverMode);
+ printk(BIOS_DEBUG, "\t\t bootMode: 0x%x\n", hob->SystemStatus.bootMode);
+ printk(BIOS_DEBUG, "\t\t OutClusterOnDieEn: 0x%x\n",
+ hob->SystemStatus.OutClusterOnDieEn);
+ printk(BIOS_DEBUG, "\t\t OutSncEn: 0x%x\n", hob->SystemStatus.OutSncEn);
+ printk(BIOS_DEBUG, "\t\t OutNumOfCluster: 0x%x\n", hob->SystemStatus.OutNumOfCluster);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ for (int imc = 0; imc < BL_MAX_IMC; imc++) {
+ printk(BIOS_DEBUG, "\t\t imcEnabled[%d][%d]: 0x%x\n", socket, imc,
+ hob->SystemStatus.imcEnabled[socket][imc]);
+ }
+ }
+ printk(BIOS_DEBUG, "\t\t LlcSizeReg: 0x%x\n", hob->SystemStatus.LlcSizeReg);
+ for (int socket = 0; socket < BL_MAX_SOCKET; socket++) {
+ for (int ch = 0; ch < BL_MAX_CH; ch++) {
+ printk(BIOS_DEBUG, "\t\t chEnabled[%d][%d]: 0x%x\n", socket, ch,
+ hob->SystemStatus.chEnabled[socket][ch]);
+ }
+ }
+ for (int node = 0; node < BL_MC_MAX_NODE; node++) {
+ printk(BIOS_DEBUG, "\t\t memNode[%d]: 0x%x\n", node,
+ hob->SystemStatus.memNode[node]);
+ }
+ printk(BIOS_DEBUG, "\t\t IoDcMode: 0x%x\n", hob->SystemStatus.IoDcMode);
+ printk(BIOS_DEBUG, "\t\t DfxRstCplBitsEn: 0x%x\n", hob->SystemStatus.DfxRstCplBitsEn);
+}
+
+static void soc_display_fsp_fia_override_status(const BL_FIA_OVERRIDE_STATUS_HOB *hob)
+{
+ if (!hob)
+ return;
+ printk(BIOS_DEBUG, "FIA Override Status\n");
+ printk(BIOS_DEBUG, "\t FiaMuxConfigGetStatus: 0x%08x\n", hob->FiaMuxConfigGetStatus);
+ printk(BIOS_DEBUG, "\t FiaMuxConfigSetStatus: 0x%08x\n", hob->FiaMuxConfigSetStatus);
+ printk(BIOS_DEBUG, "\t FiaMuxConfigSetRequired: 0x%08x\n",
+ hob->FiaMuxConfigSetRequired);
+}
+
+static void soc_display_fsp_smbios_memory_info(const FSP_SMBIOS_MEMORY_INFO *hob)
+{
+ if (!hob)
+ return;
+
+ printk(BIOS_DEBUG, "SMBIOS Memory Info\n");
+ printk(BIOS_DEBUG, "\t Revision: 0x%x\n", hob->Revision);
+ printk(BIOS_DEBUG, "\t DataWidth: 0x%x\n", hob->DataWidth);
+ printk(BIOS_DEBUG, "\t MemoryType: 0x%x\n", hob->MemoryType);
+ printk(BIOS_DEBUG, "\t MemoryFrequencyInMHz: 0x%x\n", hob->MemoryFrequencyInMHz);
+ printk(BIOS_DEBUG, "\t ErrorCorrectionType: 0x%x\n", hob->ErrorCorrectionType);
+ printk(BIOS_DEBUG, "\t ChannelCount: 0x%x\n", hob->ChannelCount);
+ for (uint8_t channel = 0; channel < hob->ChannelCount; channel++) {
+ const CHANNEL_INFO *channel_info = &hob->ChannelInfo[channel];
+ printk(BIOS_DEBUG, "\t ChannelInfo[%d]\n", channel);
+ printk(BIOS_DEBUG, "\t\t ChannelId: 0x%x\n", channel_info->ChannelId);
+ printk(BIOS_DEBUG, "\t\t DimmCount: 0x%x\n", channel_info->DimmCount);
+ for (uint8_t dimm = 0; dimm < channel_info->DimmCount; dimm++) {
+ const DIMM_INFO *dimm_info = &channel_info->DimmInfo[dimm];
+ printk(BIOS_DEBUG, "\t\t\t DimmInfo[%d]\n", dimm);
+ printk(BIOS_DEBUG, "\t\t\t\t DimmId: 0x%x\n", dimm_info->DimmId);
+ printk(BIOS_DEBUG, "\t\t\t\t SizeInMb: 0x%x\n", dimm_info->SizeInMb);
+ printk(BIOS_DEBUG, "\t\t\t\t MfgId: 0x%x\n", dimm_info->MfgId);
+ printk(BIOS_DEBUG, "\t\t\t\t ModulePartNum: %s\n",
+ dimm_info->ModulePartNum);
+ }
+ }
+}
+
+void soc_display_hob(const struct hob_header *hob)
+{
+ uint8_t *guid;
+
+ if (hob->type != HOB_TYPE_GUID_EXTENSION)
+ return;
+
+ guid = (uint8_t *)fsp_hob_header_to_resource(hob);
+ if (fsp_guid_compare(guid, fsp_hob_iio_uds_data_guid.b))
+ soc_display_fsp_iio_uds_data_hob(
+ (const BL_IIO_UDS *)(guid + sizeof(fsp_hob_iio_uds_data_guid)));
+ else if (fsp_guid_compare(guid, fsp_hob_fia_override_status_guid.b))
+ soc_display_fsp_fia_override_status(
+ (const BL_FIA_OVERRIDE_STATUS_HOB
+ *)(guid + sizeof(fsp_hob_fia_override_status_guid)));
+ else if (fsp_guid_compare(guid, fsp_hob_smbios_memory_info_guid.b))
+ soc_display_fsp_smbios_memory_info(
+ (const FSP_SMBIOS_MEMORY_INFO
+ *)(guid + sizeof(fsp_hob_smbios_memory_info_guid)));
+}
diff --git a/src/soc/intel/snowridge/common/kti_cache.c b/src/soc/intel/snowridge/common/kti_cache.c
new file mode 100644
index 0000000000..f3d72b638d
--- /dev/null
+++ b/src/soc/intel/snowridge/common/kti_cache.c
@@ -0,0 +1,145 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <boot_device.h>
+#include <bootstate.h>
+#include <commonlib/bsd/ipchksum.h>
+#include <stdlib.h>
+#include <commonlib/region.h>
+#include <console/console.h>
+#include <fmap.h>
+#include <lib.h>
+#include <spi-generic.h>
+#include <spi_flash.h>
+#include <string.h>
+
+#include "fsp_hob.h"
+#include "kti_cache.h"
+
+struct kti_metadata {
+ uint16_t data_size;
+ uint16_t data_checksum;
+} __packed;
+
+void *kti_cache_load(size_t *size)
+{
+ struct region region;
+ struct region_device read_rdev;
+ struct kti_metadata md;
+ void *data;
+ uint16_t checksum;
+
+ if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, &region) != 0) {
+ printk(BIOS_ERR, "Region %s doesn't exist!\n", CONFIG_KTI_CACHE_FMAP_NAME);
+ return NULL;
+ }
+
+ if (boot_device_ro_subregion(&region, &read_rdev) < 0)
+ return NULL;
+
+ if (rdev_readat(&read_rdev, &md, 0, sizeof(struct kti_metadata)) < 0) {
+ printk(BIOS_ERR, "Couldn't read KTI metadata\n");
+ return NULL;
+ }
+
+ if (md.data_size == 0xFFFF) {
+ printk(BIOS_INFO, "KTI cache not found!\n");
+ return NULL;
+ }
+
+ data = rdev_mmap(&read_rdev, sizeof(struct kti_metadata), md.data_size);
+ if (data == NULL) {
+ printk(BIOS_ERR, "Map KTI cache failed.\n");
+ return NULL;
+ }
+
+ checksum = ipchksum(data, md.data_size);
+ rdev_munmap(&read_rdev, data);
+ if (checksum != md.data_checksum) {
+ printk(BIOS_ERR, "KTI cache checksum mismatch: %x vs %x\n", md.data_checksum,
+ checksum);
+ return NULL;
+ }
+
+ if (size)
+ *size = md.data_size;
+
+ return data;
+}
+
+static void kti_cache_protect(void)
+{
+ struct region region;
+
+ if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, &region) < 0) {
+ return;
+ }
+
+ if (spi_flash_ctrlr_protect_region(boot_device_spi_flash(), &region, WRITE_PROTECT) <
+ 0) {
+ printk(BIOS_ERR, "Set Flash Protected Range for %s failed.\n",
+ CONFIG_KTI_CACHE_FMAP_NAME);
+ return;
+ }
+
+ printk(BIOS_INFO, "Enable Flash Protected Range on %s.\n", CONFIG_KTI_CACHE_FMAP_NAME);
+}
+
+static void kti_cache_save(void *unused)
+{
+ size_t kti_data_size;
+ const void *kti_data;
+ struct kti_metadata *md;
+ struct region region;
+ struct region_device write_rdev;
+
+ printk(BIOS_INFO, "Save KTI starts...\n");
+
+ kti_data = fsp_hob_get_kti_cache(&kti_data_size);
+ if (!kti_data) {
+ printk(BIOS_WARNING, "Couldn't find KTI cache hob!\n");
+ return;
+ }
+
+ hexdump(kti_data, kti_data_size);
+
+ md = malloc(sizeof(struct kti_metadata) + kti_data_size);
+ if (md == NULL) {
+ printk(BIOS_ERR, "Allocate KTI metadata failed!\n");
+ return;
+ }
+
+ memset(md, 0, sizeof(struct kti_metadata));
+ md->data_size = kti_data_size;
+ md->data_checksum = ipchksum(kti_data, kti_data_size);
+ memcpy(md + 1, kti_data, kti_data_size);
+
+ if (fmap_locate_area(CONFIG_KTI_CACHE_FMAP_NAME, &region) != 0)
+ goto ret;
+
+ if (boot_device_rw_subregion(&region, &write_rdev) < 0)
+ goto ret;
+
+ if (rdev_eraseat(&write_rdev, 0, region_device_sz(&write_rdev)) < 0) {
+ printk(BIOS_ERR, "Erase stale KTI cache failed.\n");
+ goto ret;
+ }
+
+ if (rdev_writeat(&write_rdev, md, 0, sizeof(struct kti_metadata) + kti_data_size) < 0) {
+ printk(BIOS_ERR, "Write KTI cache failed.\n");
+ goto ret;
+ }
+
+ kti_cache_protect();
+
+ printk(BIOS_INFO, "Save KTI ends.\n");
+
+ret:
+ free(md);
+}
+
+/**
+ * Ensures kti data is stored into SPI after PCI enumeration is done during
+ * BS_DEV_ENUMERATE-BS_ON_EXIT and lock down SPI protected ranges during
+ * BS_DEV_RESOURCES-BS_ON_EXIT.
+ */
+BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_EXIT, kti_cache_save, NULL);
diff --git a/src/soc/intel/snowridge/common/kti_cache.h b/src/soc/intel/snowridge/common/kti_cache.h
new file mode 100644
index 0000000000..0c8d923e33
--- /dev/null
+++ b/src/soc/intel/snowridge/common/kti_cache.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_KTI_CACHE_H_
+#define _SOC_SNOWRIDGE_KTI_CACHE_H_
+
+#include <stddef.h>
+
+void *kti_cache_load(size_t *size);
+
+#endif // _SOC_SNOWRIDGE_KTI_CACHE_H_
diff --git a/src/soc/intel/snowridge/common/pmclib.c b/src/soc/intel/snowridge/common/pmclib.c
new file mode 100644
index 0000000000..ae995ca67c
--- /dev/null
+++ b/src/soc/intel/snowridge/common/pmclib.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/mmio.h>
+#include <intelblocks/pmclib.h>
+#include <soc/iomap.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+
+const char *const *soc_smi_sts_array(size_t *a)
+{
+ static const char *const smi_sts_bits[] = {
+ [BIOS_STS_BIT] = "BIOS",
+ [LEGACY_USB_STS_BIT] = "LEGACY_USB",
+ [SMI_ON_SLP_EN_STS_BIT] = "SLP_SMI",
+ [APM_STS_BIT] = "APM",
+ [SWSMI_TMR_STS_BIT] = "SWSMI_TMR",
+ [PM1_STS_BIT] = "PM1",
+ [GPE0_STS_BIT] = "GPE0",
+ [GPIO_STS_BIT] = "GPI",
+ [MCSMI_STS_BIT] = "MCSMI",
+ [DEVMON_STS_BIT] = "DEVMON",
+ [TCO_STS_BIT] = "TCO",
+ [PERIODIC_STS_BIT] = "PERIODIC",
+ [SERIRQ_SMI_STS_BIT] = "SERIRQ_SMI",
+ [SMBUS_SMI_STS_BIT] = "SMBUS_SMI",
+ [PCI_EXP_SMI_STS_BIT] = "PCI_EXP_SMI",
+ [MONITOR_STS_BIT] = "MONITOR",
+ [SPI_SMI_STS_BIT] = "SPI",
+ [GPIO_UNLOCK_SMI_STS_BIT] = "GPIO_UNLOCK",
+ [ESPI_SMI_STS_BIT] = "ESPI_SMI",
+ };
+
+ *a = ARRAY_SIZE(smi_sts_bits);
+ return smi_sts_bits;
+}
+
+const char *const *soc_tco_sts_array(size_t *a)
+{
+ static const char *const tco_sts_bits[] = {
+ [0] = "NMI2SMI",
+ [1] = "SW_TCO",
+ [2] = "TCO_INT",
+ [3] = "TIMEOUT",
+ [7] = "NEWCENTURY",
+ [8] = "BIOSWR",
+ [9] = "DMISCI",
+ [10] = "DMISMI",
+ [12] = "DMISERR",
+ [13] = "SLVSEL",
+ [16] = "INTRD_DET",
+ [17] = "SECOND_TO",
+ [18] = "BOOT",
+ [20] = "SMLINK_SLV"
+ };
+
+ *a = ARRAY_SIZE(tco_sts_bits);
+ return tco_sts_bits;
+}
+
+const char *const *soc_std_gpe_sts_array(size_t *a)
+{
+ static const char *const gpe_sts_bits[] = {
+ [1] = "HOTPLUG",
+ [2] = "SWGPE",
+ [6] = "TCO_SCI",
+ [7] = "SMB_WAK",
+ [9] = "PCI_EXP",
+ [10] = "BATLOW",
+ [11] = "PME",
+ [12] = "ME",
+ [13] = "PME_B0",
+ [14] = "eSPI",
+ [15] = "GPIO Tier-2",
+ [16] = "LAN_WAKE",
+ [18] = "WADT"
+ };
+
+ *a = ARRAY_SIZE(gpe_sts_bits);
+ return gpe_sts_bits;
+}
+
+void pmc_soc_set_afterg3_en(bool on)
+{
+ uintptr_t pmc_bar = soc_read_pmc_base();
+ uint8_t reg8 = read32p(pmc_bar + GEN_PMCON_A);
+
+ if (on)
+ reg8 &= ~SLEEP_AFTER_POWER_FAIL;
+ else
+ reg8 |= SLEEP_AFTER_POWER_FAIL;
+
+ write32p(pmc_bar + GEN_PMCON_A, reg8);
+}
+
+uintptr_t soc_read_pmc_base(void)
+{
+ return PCH_PWRM_BASE_ADDRESS;
+}
+
+uint32_t *soc_pmc_etr_addr(void)
+{
+ return (uint32_t *)(soc_read_pmc_base() + ETR);
+}
diff --git a/src/soc/intel/snowridge/common/reset.c b/src/soc/intel/snowridge/common/reset.c
new file mode 100644
index 0000000000..dc2c5642e0
--- /dev/null
+++ b/src/soc/intel/snowridge/common/reset.c
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cf9_reset.h>
+#include <console/console.h>
+#include <soc/intel/common/reset.h>
+
+void do_global_reset(void)
+{
+ do_full_reset();
+}
diff --git a/src/soc/intel/snowridge/common/spi.c b/src/soc/intel/snowridge/common/spi.c
new file mode 100644
index 0000000000..7fbb9115b8
--- /dev/null
+++ b/src/soc/intel/snowridge/common/spi.c
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/spi.h>
+
+int spi_soc_devfn_to_bus(unsigned int devfn)
+{
+ return -1;
+}
diff --git a/src/soc/intel/snowridge/common/systemagent_early.c b/src/soc/intel/snowridge/common/systemagent_early.c
new file mode 100644
index 0000000000..56bddad500
--- /dev/null
+++ b/src/soc/intel/snowridge/common/systemagent_early.c
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/systemagent_server.h>
+#include <soc/systemagent.h>
+
+uint32_t sa_server_soc_reg_to_pci_offset(enum sa_server_reg reg)
+{
+ switch (reg) {
+ case MMCFG_BASE_REG:
+ return PCIE_MMCFG_BASE;
+ case MMCFG_LIMIT_REG:
+ return PCIE_MMCFG_LIMIT;
+ case TSEG_BASE_REG:
+ return TSEG;
+ case TSEG_LIMIT_REG:
+ return TSEG_LIMIT;
+ case TOCM_REG:
+ return TOCM;
+ case TOUUD_REG:
+ return TOUUD;
+ case TOLUD_REG:
+ return TOLUD;
+ case MMIO_L_REG:
+ return MMIOL;
+ case VT_BAR_REG:
+ return VTBAR;
+ case DPR_REG:
+ return DPR;
+ default:
+ return 0;
+ }
+}
diff --git a/src/soc/intel/snowridge/common/uart8250mem.c b/src/soc/intel/snowridge/common/uart8250mem.c
new file mode 100644
index 0000000000..51d0604ac8
--- /dev/null
+++ b/src/soc/intel/snowridge/common/uart8250mem.c
@@ -0,0 +1,30 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/uart.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <soc/pci_devs.h>
+
+#include "uart8250mem.h"
+
+uintptr_t uart_platform_base(unsigned int idx)
+{
+ uint32_t reg32 = pci_read_config32(PCH_DEV_UART(idx), UART_MEMBA);
+
+ reg32 &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
+
+ return reg32;
+}
+
+unsigned int uart_platform_refclk(void)
+{
+ unsigned int ret = 115200 * 16;
+
+ /**
+ * Base uart clock is HIGH_SPEED_CLK_MULT (24) * 1.8432Mhz if using baudrates > 115200.
+ */
+ if (CONFIG_TTYS0_BAUD > 115200)
+ ret *= HIGH_SPEED_CLK_MULT;
+
+ return ret;
+}
diff --git a/src/soc/intel/snowridge/common/uart8250mem.h b/src/soc/intel/snowridge/common/uart8250mem.h
new file mode 100644
index 0000000000..2c5b6fb516
--- /dev/null
+++ b/src/soc/intel/snowridge/common/uart8250mem.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_UART_H_
+#define _SOC_SNOWRIDGE_UART_H_
+
+#define UART_IOBA 0x10
+#define UART_MEMBA 0x14
+
+#if CONFIG_CONSOLE_UART_BASE_ADDRESS != 0
+#define SIZE_OF_HSUART_RES 256
+#endif
+
+#define SNOWRIDGE_UARTS_TO_INIT 3
+#define HIGH_SPEED_CLK_MULT 24
+
+#endif /* _SOC_SNOWRIDGE_UART_H_ */
diff --git a/src/soc/intel/snowridge/common/upd_display.c b/src/soc/intel/snowridge/common/upd_display.c
new file mode 100644
index 0000000000..3c7f44bcef
--- /dev/null
+++ b/src/soc/intel/snowridge/common/upd_display.c
@@ -0,0 +1,133 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <fsp/debug.h>
+#include <lib.h>
+
+#define DISPLAY_UPD(field) \
+ fsp_display_upd_value(#field, sizeof(old->field), old->field, new->field)
+
+void soc_display_fspm_upd_params(const FSPM_UPD *fspm_old_upd, const FSPM_UPD *fspm_new_upd)
+{
+ const FSP_M_CONFIG *old = &fspm_old_upd->FspmConfig;
+ const FSP_M_CONFIG *new = &fspm_new_upd->FspmConfig;
+
+ printk(BIOS_SPEW, "UPD values for FspMemoryInit:\n");
+
+ DISPLAY_UPD(PcdEnableBiosSsaRMT);
+ DISPLAY_UPD(PcdEnableBiosSsaRMTonFCB);
+ DISPLAY_UPD(PcdBiosSsaPerBitMargining);
+ DISPLAY_UPD(PcdBiosSsaDisplayTables);
+ DISPLAY_UPD(PcdBiosSsaPerDisplayPlots);
+ DISPLAY_UPD(PcdBiosSsaLoopCount);
+ DISPLAY_UPD(PcdBiosSsaBacksideMargining);
+ DISPLAY_UPD(PcdBiosSsaEarlyReadIdMargining);
+ DISPLAY_UPD(PcdBiosSsaStepSizeOverride);
+ DISPLAY_UPD(PcdBiosSsaRxDqs);
+ DISPLAY_UPD(PcdBiosSsaRxVref);
+ DISPLAY_UPD(PcdBiosSsaTxDq);
+ DISPLAY_UPD(PcdBiosSsaTxVref);
+ DISPLAY_UPD(PcdBiosSsaCmdAll);
+ DISPLAY_UPD(PcdBiosSsaCmdVref);
+ DISPLAY_UPD(PcdBiosSsaCtlAll);
+ DISPLAY_UPD(PcdBiosSsaEridDelay);
+ DISPLAY_UPD(PcdBiosSsaEridVref);
+ DISPLAY_UPD(PcdBiosSsaDebugMessages);
+ DISPLAY_UPD(PcdEccSupport);
+ DISPLAY_UPD(PcdFastBoot);
+ DISPLAY_UPD(PcdMemTest);
+ DISPLAY_UPD(PcdMemTurnaroundOpt);
+ DISPLAY_UPD(PcdDdrFreq);
+ DISPLAY_UPD(PcdCommandTiming);
+ DISPLAY_UPD(PcdCustomRefreshRate);
+ DISPLAY_UPD(PcdTsegSize);
+ DISPLAY_UPD(PcdHsuartDevice);
+ DISPLAY_UPD(PcdHeciCommunication);
+ DISPLAY_UPD(PcdVtdSupport);
+ DISPLAY_UPD(PcdPchUsb3Port);
+ DISPLAY_UPD(PcdPchUsb2Port);
+ DISPLAY_UPD(PcdPchUsb3PortOc);
+ DISPLAY_UPD(PcdPchUsb2PortOc);
+ DISPLAY_UPD(PcdUsb2PeTxiSet);
+ DISPLAY_UPD(PcdUsb2TxiSet);
+ DISPLAY_UPD(PcdUsb2PreDeEmp);
+ DISPLAY_UPD(PcdUsb2PreEmpHalfBit);
+ DISPLAY_UPD(PcdIIOPciePortBifurcation);
+ DISPLAY_UPD(PcdIIoPcieRLinkDeEmphasis);
+ DISPLAY_UPD(PcdIIoPciePort1ADeEmphasis);
+ DISPLAY_UPD(PcdIIoPciePort1BDeEmphasis);
+ DISPLAY_UPD(PcdIIoPciePort1CDeEmphasis);
+ DISPLAY_UPD(PcdIIoPciePort1DDeEmphasis);
+ DISPLAY_UPD(PcdIIoPcieLinkSpeedRLink);
+ DISPLAY_UPD(PcdIIoPciePort1ALinkSpeed);
+ DISPLAY_UPD(PcdIIoPciePort1BLinkSpeed);
+ DISPLAY_UPD(PcdIIoPciePort1CLinkSpeed);
+ DISPLAY_UPD(PcdIIoPciePort1DLinkSpeed);
+ DISPLAY_UPD(PcdIIoPcieRLinkAspm);
+ DISPLAY_UPD(PcdIIoPciePort1AAspm);
+ DISPLAY_UPD(PcdIIoPciePort1BAspm);
+ DISPLAY_UPD(PcdIIoPciePort1CAspm);
+ DISPLAY_UPD(PcdIIoPciePort1DAspm);
+ DISPLAY_UPD(PcdBifurcationPcie0);
+ DISPLAY_UPD(PcdBifurcationPcie2);
+ DISPLAY_UPD(PcdMemoryThermalThrottling);
+ DISPLAY_UPD(PcdFiaMuxOverride);
+ DISPLAY_UPD(FiaMuxCfgInvalidate);
+ DISPLAY_UPD(PcdPchTraceHubMode);
+ DISPLAY_UPD(PcdPchTraceHubMemReg0Size);
+ DISPLAY_UPD(PcdPchTraceHubMemReg1Size);
+ DISPLAY_UPD(PcdFiaLaneConfigPtr);
+ DISPLAY_UPD(PcdKtiBufferPtr);
+ DISPLAY_UPD(PcdMemSpdPtr);
+
+ hexdump(fspm_new_upd, sizeof(*fspm_new_upd));
+}
+
+void soc_display_fsps_upd_params(const FSPS_UPD *fsps_old_upd, const FSPS_UPD *fsps_new_upd)
+{
+ const FSP_S_CONFIG *old = &fsps_old_upd->FspsConfig;
+ const FSP_S_CONFIG *new = &fsps_new_upd->FspsConfig;
+
+ printk(BIOS_SPEW, "UPD values for FspSiliconInit:\n");
+
+ DISPLAY_UPD(PcdCpuMicrocodePatchBase);
+ DISPLAY_UPD(PcdCpuMicrocodePatchSize);
+ DISPLAY_UPD(PcdEnableSATA);
+ DISPLAY_UPD(PcdEmmc);
+ DISPLAY_UPD(PcdEmmcHS400Support);
+ DISPLAY_UPD(PcdPcieRootPort0LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort1LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort2LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort3LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort8LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort9LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort10LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort11LinkSpeed);
+ DISPLAY_UPD(PcdPcieRootPort0Aspm);
+ DISPLAY_UPD(PcdPcieRootPort1Aspm);
+ DISPLAY_UPD(PcdPcieRootPort2Aspm);
+ DISPLAY_UPD(PcdPcieRootPort3Aspm);
+ DISPLAY_UPD(PcdPcieRootPort8Aspm);
+ DISPLAY_UPD(PcdPcieRootPort9Aspm);
+ DISPLAY_UPD(PcdPcieRootPort10Aspm);
+ DISPLAY_UPD(PcdPcieRootPort11Aspm);
+ DISPLAY_UPD(PcdPcieRootPort0ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort1ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort2ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort3ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort8ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort9ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort10ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort11ConnectionType);
+ DISPLAY_UPD(PcdPcieRootPort0HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort1HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort2HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort3HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort8HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort9HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort10HotPlug);
+ DISPLAY_UPD(PcdPcieRootPort11HotPlug);
+ DISPLAY_UPD(PcdEMMCDLLConfigPtr);
+
+ hexdump(fsps_new_upd, sizeof(*fsps_new_upd));
+}
diff --git a/src/soc/intel/snowridge/cpu.c b/src/soc/intel/snowridge/cpu.c
new file mode 100644
index 0000000000..29050aa9ab
--- /dev/null
+++ b/src/soc/intel/snowridge/cpu.c
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cpu/intel/common/common.h>
+#include <cpu/intel/smm_reloc.h>
+#include <cpu/intel/turbo.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
+#include <cpu/x86/smm.h>
+#include <device/device.h>
+#include <intelblocks/cpulib.h>
+#include <intelblocks/mp_init.h>
+#include <intelblocks/msr.h>
+#include <soc/msr.h>
+#include <soc/soc_chip.h>
+#include <static.h>
+
+static void configure_misc(void)
+{
+ msr_t msr;
+ config_t *conf = config_of_soc();
+
+ msr = rdmsr(IA32_MISC_ENABLE);
+ msr.lo |= FAST_STRINGS_ENABLE_BIT;
+ msr.lo |= (1 << 3); /**< Enable TM1, TM2 and EMTTM. */
+ wrmsr(IA32_MISC_ENABLE, msr);
+
+ cpu_set_eist(conf->eist_enable);
+
+ msr.lo = 0;
+ msr.hi = 0;
+ wrmsr(IA32_THERM_INTERRUPT, msr);
+
+ msr.lo = 1 << 4;
+ msr.hi = 0;
+ wrmsr(IA32_PACKAGE_THERM_INTERRUPT, msr);
+
+ msr = rdmsr(MSR_POWER_CTL);
+ msr.lo |= (1 << 0); /**< Enable bi-directional PROCHOT as an input. */
+ msr.lo |= (1 << 23); /**< Lock it. */
+ wrmsr(MSR_POWER_CTL, msr);
+}
+
+void soc_core_init(struct device *dev)
+{
+ /**
+ * This should only be done on a cold boot. Also, some these banks are core
+ * vs package scope.
+ */
+ mca_configure();
+
+ enable_lapic_tpr();
+
+ configure_misc();
+
+ configure_dca_cap();
+
+ set_energy_perf_bias(ENERGY_POLICY_NORMAL);
+
+ enable_turbo();
+}
+
+static void post_mp_init(void)
+{
+ cpu_set_max_ratio();
+
+ /**
+ * Now that all APs have been relocated as well as the BSP, let SMI start flowing.
+ */
+ global_smi_enable();
+}
+
+static const struct mp_ops mp_ops = {
+ /**
+ * Skip Pre MP init MTRR programming as MTRRs are mirrored from BSP that are set prior
+ * to ramstage. Real MTRRs programming are being done after resource allocation.
+ */
+
+ .get_cpu_count = get_cpu_count,
+#if CONFIG(HAVE_SMI_HANDLER)
+ .get_smm_info = smm_info,
+#endif
+ .get_microcode_info = get_microcode_info,
+ .pre_mp_smm_init = smm_initialize,
+ .per_cpu_smm_trigger = smm_relocate,
+ .relocation_handler = smm_relocation_handler,
+ .post_mp_init = post_mp_init,
+};
+
+void mp_init_cpus(struct bus *cpu_bus)
+{
+ if (mp_init_with_smm(cpu_bus, &mp_ops))
+ die_with_post_code(POSTCODE_HW_INIT_FAILURE, "mp_init_with_smm failed!\n");
+
+ configure_tcc_thermal_target();
+}
+
+bool cpu_soc_is_in_untrusted_mode(void)
+{
+ msr_t msr;
+
+ msr = rdmsr(MSR_BIOS_DONE);
+ return !!(msr.lo & ENABLE_IA_UNTRUSTED);
+}
diff --git a/src/soc/intel/snowridge/dlb.c b/src/soc/intel/snowridge/dlb.c
new file mode 100644
index 0000000000..6e25c4064a
--- /dev/null
+++ b/src/soc/intel/snowridge/dlb.c
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "ramstage.h"
+
+static struct device_operations snr_dlb_ops = {
+ .read_resources = pciexp_pf_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .final = pci_dev_request_bus_master,
+ .ops_pci = &pci_dev_ops_pci,
+};
+
+static const struct pci_driver snr_dlb_driver __pci_driver = {
+ .ops = &snr_dlb_ops,
+ .vendor = PCI_VID_INTEL,
+ .device = PCI_DID_INTEL_SNR_DLB
+};
diff --git a/src/soc/intel/snowridge/finalize.c b/src/soc/intel/snowridge/finalize.c
new file mode 100644
index 0000000000..476b2c1f3d
--- /dev/null
+++ b/src/soc/intel/snowridge/finalize.c
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <bootstate.h>
+#include <commonlib/console/post_codes.h>
+#include <console/console.h>
+#include <cpu/x86/smm.h>
+
+static void soc_finalize(void *unused)
+{
+ printk(BIOS_DEBUG, "Finalizing chipset.\n");
+
+ apm_control(APM_CNT_FINALIZE);
+
+ /* Indicate finalize step with post code */
+ post_code(POSTCODE_OS_BOOT);
+}
+
+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);
+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);
diff --git a/src/soc/intel/snowridge/heci.c b/src/soc/intel/snowridge/heci.c
new file mode 100644
index 0000000000..3bc9d5f21f
--- /dev/null
+++ b/src/soc/intel/snowridge/heci.c
@@ -0,0 +1,36 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <device/resource.h>
+
+static void heci_read_resources(struct device *dev)
+{
+ struct resource *res = NULL;
+
+ pci_dev_read_resources(dev);
+
+ /**
+ * Clear `IORESOURCE_PCI64` since we want this device to remain under 4G as it is used
+ * by FSP Notify.
+ */
+ res = find_resource(dev, PCI_BASE_ADDRESS_0);
+ res->limit = 0xffffffff;
+ res->flags &= ~IORESOURCE_PCI64;
+}
+
+static struct device_operations snr_heci_ops = {
+ .read_resources = heci_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .ops_pci = &pci_dev_ops_pci,
+};
+
+static const struct pci_driver snr_heci_driver __pci_driver = {
+ .ops = &snr_heci_ops,
+ .vendor = PCI_VID_INTEL,
+ .device = PCI_DID_INTEL_SNR_HECI1,
+};
diff --git a/src/soc/intel/snowridge/include/soc/acpi.h b/src/soc/intel/snowridge/include/soc/acpi.h
new file mode 100644
index 0000000000..9bb36c3b82
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/acpi.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_ACPI_H_
+#define _SOC_SNOWRIDGE_ACPI_H_
+
+#include <acpi/acpi.h>
+#include <device/device.h>
+
+void domain_fill_ssdt(const struct device *dev);
+void pcie_rp_fill_ssdt(const struct device *dev);
+
+#endif // _SOC_SNOWRIDGE_ACPI_H_
diff --git a/src/soc/intel/snowridge/include/soc/cpu.h b/src/soc/intel/snowridge/include/soc/cpu.h
new file mode 100644
index 0000000000..eaf0a01770
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/cpu.h
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_CPU_H_
+#define _SOC_SNOWRIDGE_CPU_H_
+
+/**
+ * @brief Required by `src/soc/intel/common/block`.
+ */
+
+#endif // _SOC_SNOWRIDGE_CPU_H_
diff --git a/src/soc/intel/snowridge/include/soc/gpio.h b/src/soc/intel/snowridge/include/soc/gpio.h
new file mode 100644
index 0000000000..1166aed4fd
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/gpio.h
@@ -0,0 +1,62 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_GPIO_H_
+#define _SOC_SNOWRIDGE_GPIO_H_
+
+#include "gpio_defs.h"
+
+#define GPIO_MAX_NUM_PER_GROUP 32
+
+#define GPIO_WEST2_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WEST2_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_WEST3_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WEST3_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_WEST01_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WEST01_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_WEST5_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WEST5_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_WESTB_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WESTB_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_WESTD_PECI_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_WESTD_PECI_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_EAST2_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_EAST2_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_EAST3_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_EAST3_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_EAST0_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_EAST0_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_EMMC_GPI_STATUS_REGS \
+ (ALIGN_UP(GPIO_EMMC_PAD_NUM, GPIO_MAX_NUM_PER_GROUP) / GPIO_MAX_NUM_PER_GROUP)
+
+#define GPIO_MISCCFG 0x10 /**< Miscellaneous Configuration. */
+#define GPIO_NUM_PAD_CFG_REGS 4 /**< DW0, DW1 and DW2 but 16-bytes aligned. */
+
+#define NUM_GPI_STATUS_REGS \
+ (GPIO_WEST2_GPI_STATUS_REGS + GPIO_WEST3_GPI_STATUS_REGS + \
+ GPIO_WEST01_GPI_STATUS_REGS + GPIO_WEST5_GPI_STATUS_REGS + \
+ GPIO_WESTB_GPI_STATUS_REGS + GPIO_WESTD_PECI_GPI_STATUS_REGS + \
+ GPIO_EAST2_GPI_STATUS_REGS + GPIO_EAST3_GPI_STATUS_REGS + \
+ GPIO_EAST0_GPI_STATUS_REGS + GPIO_EMMC_GPI_STATUS_REGS)
+
+/**
+ * @brief SNR doesn't support dynamic GPIO PM hence GPIO community MISCCFG register doesn't
+ * have PM bits.
+ */
+#define MISCCFG_GPIO_PM_CONFIG_BITS 0
+
+/**
+ * @note Actually `intelblocks/gpio.h` has already included this file, but to support those
+ * file that include this file directly, we need include `intelblocks/gpio.h` recursively.
+ */
+#include <intelblocks/gpio.h>
+
+#endif // _SOC_SNOWRIDGE_GPIO_H_
diff --git a/src/soc/intel/snowridge/include/soc/gpio_defs.h b/src/soc/intel/snowridge/include/soc/gpio_defs.h
new file mode 100644
index 0000000000..8f21c22a11
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/gpio_defs.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_GPIO_DEFS_H_
+#define _SOC_SNOWRIDGE_GPIO_DEFS_H_
+
+enum gpio_pad_own_t {
+ GPIO_PAD_OWN_HOST = 0x00,
+ GPIO_PAD_OWN_ME = 0x03
+};
+
+/**
+ * The following sets of macros are used when defining pad_community in
+ * src/soc/intel/snowridge/common/gpio.c.
+ */
+
+#define GPIO_WEST2_PAD_OWN 0x0020
+#define GPIO_WEST2_HOSTSW_OWN 0x0120
+#define GPIO_WEST2_GPI_IS 0x0200
+#define GPIO_WEST2_GPI_IE 0x0230
+#define GPIO_WEST2_GPI_GPE_STS 0x0260
+#define GPIO_WEST2_GPI_GPE_EN 0x0290
+#define GPIO_WEST2_SMI_STS 0x02c0
+#define GPIO_WEST2_SMI_EN 0x02f0
+#define GPIO_WEST2_NMI_STS 0x0320
+#define GPIO_WEST2_NMI_EN 0x0350
+#define GPIO_WEST2_PADCFGLOCK 0x00c0
+#define GPIO_WEST2_PADCFGLOCKTX 0x00c4
+#define GPIO_WEST2_PAD_NUM 24
+
+#define GPIO_WEST3_PAD_OWN 0x002c
+#define GPIO_WEST3_HOSTSW_OWN 0x0124
+#define GPIO_WEST3_GPI_IS 0x0204
+#define GPIO_WEST3_GPI_IE 0x0234
+#define GPIO_WEST3_GPI_GPE_STS 0x0264
+#define GPIO_WEST3_GPI_GPE_EN 0x0294
+#define GPIO_WEST3_SMI_STS 0x02c4
+#define GPIO_WEST3_SMI_EN 0x02f4
+#define GPIO_WEST3_NMI_STS 0x0324
+#define GPIO_WEST3_NMI_EN 0x0354
+#define GPIO_WEST3_PADCFGLOCK 0x00c8
+#define GPIO_WEST3_PADCFGLOCKTX 0x00cc
+#define GPIO_WEST3_PAD_NUM 16
+
+#define GPIO_WEST01_PAD_OWN 0x0038
+#define GPIO_WEST01_HOSTSW_OWN 0x0128
+#define GPIO_WEST01_GPI_IS 0x0208
+#define GPIO_WEST01_GPI_IE 0x0238
+#define GPIO_WEST01_GPI_GPE_STS 0x0268
+#define GPIO_WEST01_GPI_GPE_EN 0x0298
+#define GPIO_WEST01_SMI_STS 0x02c8
+#define GPIO_WEST01_SMI_EN 0x02f8
+#define GPIO_WEST01_NMI_STS 0x0328
+#define GPIO_WEST01_NMI_EN 0x0358
+#define GPIO_WEST01_PADCFGLOCK 0x00d0
+#define GPIO_WEST01_PADCFGLOCKTX 0x00d4
+#define GPIO_WEST01_PAD_NUM 23
+
+#define GPIO_WEST5_PAD_OWN 0x0044
+#define GPIO_WEST5_HOSTSW_OWN 0x012c
+#define GPIO_WEST5_GPI_IS 0x020c
+#define GPIO_WEST5_GPI_IE 0x023c
+#define GPIO_WEST5_GPI_GPE_STS 0x026c
+#define GPIO_WEST5_GPI_GPE_EN 0x029c
+#define GPIO_WEST5_SMI_STS 0x02cc
+#define GPIO_WEST5_SMI_EN 0x02fc
+#define GPIO_WEST5_NMI_STS 0x032c
+#define GPIO_WEST5_NMI_EN 0x035c
+#define GPIO_WEST5_PADCFGLOCK 0x00d8
+#define GPIO_WEST5_PADCFGLOCKTX 0x00dc
+#define GPIO_WEST5_PAD_NUM 13
+
+#define GPIO_WESTB_PAD_OWN 0x0060 /**< Reserved. */
+#define GPIO_WESTB_HOSTSW_OWN 0x013c
+#define GPIO_WESTB_GPI_IS 0x021c
+#define GPIO_WESTB_GPI_IE 0x024c
+#define GPIO_WESTB_GPI_GPE_STS 0x027c
+#define GPIO_WESTB_GPI_GPE_EN 0x02ac
+#define GPIO_WESTB_SMI_STS 0x02dc
+#define GPIO_WESTB_SMI_EN 0x030c
+#define GPIO_WESTB_NMI_STS 0x033c
+#define GPIO_WESTB_NMI_EN 0x036c
+#define GPIO_WESTB_PADCFGLOCK 0x00f8
+#define GPIO_WESTB_PADCFGLOCKTX 0x00fc
+#define GPIO_WESTB_PAD_NUM 4
+
+#define GPIO_WESTD_PECI_PAD_OWN 0x0074
+#define GPIO_WESTD_PECI_HOSTSW_OWN 0x0144
+#define GPIO_WESTD_PECI_GPI_IS 0x0224
+#define GPIO_WESTD_PECI_GPI_IE 0x0254
+#define GPIO_WESTD_PECI_GPI_GPE_STS 0x0284
+#define GPIO_WESTD_PECI_GPI_GPE_EN 0x02b4
+#define GPIO_WESTD_PECI_SMI_STS 0x02e4
+#define GPIO_WESTD_PECI_SMI_EN 0x0314
+#define GPIO_WESTD_PECI_NMI_STS 0x0344
+#define GPIO_WESTD_PECI_NMI_EN 0x0374
+#define GPIO_WESTD_PECI_PADCFGLOCK 0x0108
+#define GPIO_WESTD_PECI_PADCFGLOCKTX 0x010c
+#define GPIO_WESTD_PECI_PAD_NUM 1
+
+#define GPIO_EAST2_PAD_OWN 0x0020
+#define GPIO_EAST2_HOSTSW_OWN 0x0120
+#define GPIO_EAST2_GPI_IS 0x0200
+#define GPIO_EAST2_GPI_IE 0x0230
+#define GPIO_EAST2_GPI_GPE_STS 0x0260
+#define GPIO_EAST2_GPI_GPE_EN 0x0290
+#define GPIO_EAST2_SMI_STS 0x02c0
+#define GPIO_EAST2_SMI_EN 0x02f0
+#define GPIO_EAST2_NMI_STS 0x0320
+#define GPIO_EAST2_NMI_EN 0x0350
+#define GPIO_EAST2_PADCFGLOCK 0x00c0
+#define GPIO_EAST2_PADCFGLOCKTX 0x00c4
+#define GPIO_EAST2_PAD_NUM 23
+
+#define GPIO_EAST3_PAD_OWN 0x002c
+#define GPIO_EAST3_HOSTSW_OWN 0x0124
+#define GPIO_EAST3_GPI_IS 0x0204
+#define GPIO_EAST3_GPI_IE 0x0234
+#define GPIO_EAST3_GPI_GPE_STS 0x0264
+#define GPIO_EAST3_GPI_GPE_EN 0x0294
+#define GPIO_EAST3_SMI_STS 0x02c4
+#define GPIO_EAST3_SMI_EN 0x02f4
+#define GPIO_EAST3_NMI_STS 0x0324
+#define GPIO_EAST3_NMI_EN 0x0354
+#define GPIO_EAST3_PADCFGLOCK 0x00c8
+#define GPIO_EAST3_PADCFGLOCKTX 0x00cc
+#define GPIO_EAST3_PAD_NUM 10
+
+#define GPIO_EAST0_PAD_OWN 0x0034 /**< Reserved. */
+#define GPIO_EAST0_HOSTSW_OWN 0x0128
+#define GPIO_EAST0_GPI_IS 0x0208
+#define GPIO_EAST0_GPI_IE 0x0238
+#define GPIO_EAST0_GPI_GPE_STS 0x0268
+#define GPIO_EAST0_GPI_GPE_EN 0x0298
+#define GPIO_EAST0_SMI_STS 0x02c8
+#define GPIO_EAST0_SMI_EN 0x02f8
+#define GPIO_EAST0_NMI_STS 0x0328
+#define GPIO_EAST0_NMI_EN 0x0358
+#define GPIO_EAST0_PADCFGLOCK 0x00d0
+#define GPIO_EAST0_PADCFGLOCKTX 0x00d4
+#define GPIO_EAST0_PAD_NUM 8
+
+#define GPIO_EMMC_PAD_OWN 0x0040
+#define GPIO_EMMC_HOSTSW_OWN 0x012c
+#define GPIO_EMMC_GPI_IS 0x020c
+#define GPIO_EMMC_GPI_IE 0x023c
+#define GPIO_EMMC_GPI_GPE_STS 0x026c
+#define GPIO_EMMC_GPI_GPE_EN 0x029c
+#define GPIO_EMMC_SMI_STS 0x02cc
+#define GPIO_EMMC_SMI_EN 0x02fc
+#define GPIO_EMMC_NMI_STS 0x032c
+#define GPIO_EMMC_NMI_EN 0x035c
+#define GPIO_EMMC_PADCFGLOCK 0x00d8
+#define GPIO_EMMC_PADCFGLOCKTX 0x00dc
+#define GPIO_EMMC_PAD_NUM 11
+
+/**
+ * @brief GPIO west community.
+ */
+#define GPIO_WEST2_PADCFG_OFFSET 0x800
+#define GPIO_WEST3_PADCFG_OFFSET 0x980
+#define GPIO_WEST01_PADCFG_OFFSET 0xb00
+#define GPIO_WEST5_PADCFG_OFFSET 0xc70
+#define GPIO_WESTB_PADCFG_OFFSET 0xf00 /**< Reserved. */
+#define GPIO_WESTD_PECI_PADCFG_OFFSET 0x1100
+
+/**
+ * @brief GPIO east community.
+ */
+#define GPIO_EAST2_PADCFG_OFFSET 0x800
+#define GPIO_EAST3_PADCFG_OFFSET 0x980
+#define GPIO_EAST0_PADCFG_OFFSET 0xa30 /**< Reserved. */
+#define GPIO_EMMC_PADCFG_OFFSET 0xba0
+
+#define TOTAL_PADS \
+ (GPIO_WEST2_PAD_NUM + GPIO_WEST3_PAD_NUM + GPIO_WEST01_PAD_NUM + GPIO_WEST5_PAD_NUM + \
+ GPIO_WESTB_PAD_NUM + GPIO_WESTD_PECI_PAD_NUM + GPIO_EAST2_PAD_NUM + \
+ GPIO_EAST3_PAD_NUM + GPIO_EAST0_PAD_NUM + GPIO_EMMC_PAD_NUM)
+
+#endif // _SOC_SNOWRIDGE_GPIO_DEFS_H_
diff --git a/src/soc/intel/snowridge/include/soc/gpio_snr.h b/src/soc/intel/snowridge/include/soc/gpio_snr.h
new file mode 100644
index 0000000000..d986b1af2e
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/gpio_snr.h
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_GPIO_SNR_H_
+#define _SOC_SNOWRIDGE_GPIO_SNR_H_
+
+#include <intelblocks/gpio.h>
+
+enum snr_pad_host_sw_owner_t { GPIO_HOSTSW_OWN_DEFAULT, GPIO_HOSTSW_OWN_ACPI, GPIO_HOSTSW_OWN_DRIVER };
+
+struct snr_pad_config {
+ struct pad_config cfg;
+ uint32_t pad_config_mask[GPIO_NUM_PAD_CFG_REGS];
+ enum snr_pad_host_sw_owner_t hostsw_own;
+};
+
+/**
+ * @note Intel common block uses the fourth bits in DW1 to indicate GPIO host software ownership.
+ */
+#define SNR_PAD_CFG_STRUCT1(__pad, __config0, __mask0, __config1, __mask1, __hostsw_own) \
+ { \
+ .cfg = _PAD_CFG_STRUCT(__pad, __config0, __config1), \
+ .pad_config_mask[0] = __mask0, .pad_config_mask[1] = __mask1 | BIT(4), \
+ .hostsw_own = __hostsw_own, \
+ }
+
+#define SNR_PAD_CFG_STRUCT0(__pad, __config0, __mask0, __hostsw_own) \
+ SNR_PAD_CFG_STRUCT1(__pad, __config0, __mask0, 0, 0, __hostsw_own)
+
+/**
+ * @brief GPIO pad format:
+ * 31 24 16 8 0
+ * ---------------------------------------------------
+ * | | Community Index | Group Index | Pad Number |
+ * ---------------------------------------------------
+ */
+
+#define SNR_GPIO_DEF(COMMUNITY, PAD) ((uint32_t)(((COMMUNITY & 0xff) << 16) | (PAD & 0xff)))
+#define SNR_GPIO_COMMUNITY(GPIO_PAD) ((GPIO_PAD >> 16) & 0xff)
+#define SNR_GPIO_PAD(GPIO_PAD) (GPIO_PAD & 0xff)
+
+enum {
+ GPIO_COMM_WEST2 = 0,
+ GPIO_COMM_WEST3,
+ GPIO_COMM_WEST01,
+ GPIO_COMM_WEST5,
+ GPIO_COMM_WESTB,
+ GPIO_COMM_WESTD_PECI,
+ GPIO_COMM_EAST2,
+ GPIO_COMM_EAST3,
+ GPIO_COMM_EAST0,
+ GPIO_COMM_EMMC
+};
+
+#define GPIO_WEST2_0 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x0) /**< GBE_SDP_TIMESYNC0. */
+#define GPIO_WEST2_1 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x1) /**< GBE_SDP_TIMESYNC1. */
+#define GPIO_WEST2_2 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x2) /**< GBE_SDP_TIMESYNC2. */
+#define GPIO_WEST2_3 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x3) /**< GBE_SDP_TIMESYNC3. */
+#define GPIO_WEST2_4 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x4) /**< GBE0_I2C_CLK. */
+#define GPIO_WEST2_5 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x5) /**< GBE0_I2C_DATA. */
+#define GPIO_WEST2_6 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x6) /**< GBE1_I2C_CLK. */
+#define GPIO_WEST2_7 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x7) /**< GBE1_I2C_DATA. */
+#define GPIO_WEST2_8 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x8) /**< GBE2_I2C_CLK. */
+#define GPIO_WEST2_9 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x9) /**< GBE2_I2C_DATA. */
+#define GPIO_WEST2_10 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xa) /**< GBE3_I2C_CLK. */
+#define GPIO_WEST2_11 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xb) /**< GBE3_I2C_DATA. */
+#define GPIO_WEST2_12 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xc) /**< GBE0_LED0. */
+#define GPIO_WEST2_13 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xd) /**< GBE0_LED1. */
+#define GPIO_WEST2_14 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xe) /**< GBE0_LED2. */
+#define GPIO_WEST2_15 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0xf) /**< GBE1_LED0. */
+#define GPIO_WEST2_16 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x10) /**< GBE1_LED1. */
+#define GPIO_WEST2_17 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x11) /**< GBE1_LED2. */
+#define GPIO_WEST2_18 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x12) /**< GBE2_LED0. */
+#define GPIO_WEST2_19 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x13) /**< GBE2_LED1. */
+#define GPIO_WEST2_20 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x14) /**< GBE2_LED2. */
+#define GPIO_WEST2_21 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x15) /**< GBE3_LED0. */
+#define GPIO_WEST2_22 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x16) /**< GBE3_LED1. */
+#define GPIO_WEST2_23 SNR_GPIO_DEF(GPIO_COMM_WEST2, 0x17) /**< GBE3_LED2. */
+#define GPIO_WEST3_0 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x0) /**< NCSI_RXD0. */
+#define GPIO_WEST3_1 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x1) /**< NCSI_CLK_IN. */
+#define GPIO_WEST3_2 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x2) /**< NCSI_RXD1. */
+#define GPIO_WEST3_3 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x3) /**< NCSI_CRS_DV. */
+#define GPIO_WEST3_4 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x4) /**< NCSI_ARB_IN. */
+#define GPIO_WEST3_5 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x5) /**< NCSI_TX_EN. */
+#define GPIO_WEST3_6 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x6) /**< NCSI_TXD0. */
+#define GPIO_WEST3_7 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x7) /**< NCSI_TXD1. */
+#define GPIO_WEST3_8 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x8) /**< NCSI_ARB_OUT. */
+#define GPIO_WEST3_9 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x9) /**< GBE_SMB_CLK. */
+#define GPIO_WEST3_10 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0xa) /**< GBE_SMB_DATA. */
+#define GPIO_WEST3_11 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0xb) /**< GBE_SMB_ALRT_N. */
+#define GPIO_WEST3_20 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x14) /**< UART0_RXD. */
+#define GPIO_WEST3_21 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x15) /**< UART0_TXD. */
+#define GPIO_WEST3_22 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x16) /**< UART1_RXD. */
+#define GPIO_WEST3_23 SNR_GPIO_DEF(GPIO_COMM_WEST3, 0x17) /**< UART1_TXD. */
+#define GPIO_WEST01_0 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x0) /**< CPU_GP_0. */
+#define GPIO_WEST01_1 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x1) /**< CPU_GP_1. */
+#define GPIO_WEST01_2 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x2) /**< CPU_GP_2. */
+#define GPIO_WEST01_3 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x3) /**< CPU_GP_3. */
+#define GPIO_WEST01_4 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x4) /**< FAN_PWM_0. */
+#define GPIO_WEST01_5 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x5) /**< FAN_PWM_1. */
+#define GPIO_WEST01_6 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x6) /**< FAN_PWM_2. */
+#define GPIO_WEST01_7 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x7) /**< FAN_PWM_3. */
+#define GPIO_WEST01_8 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x8) /**< FAN_TACH_0. */
+#define GPIO_WEST01_9 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x9) /**< FAN_TACH_1. */
+#define GPIO_WEST01_10 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xa) /**< FAN_TACH_2. */
+#define GPIO_WEST01_11 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xb) /**< FAN_TACH_3. */
+#define GPIO_WEST01_12 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xc) /**< ME_SMB0_CLK. */
+#define GPIO_WEST01_13 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xd) /**< ME_SMB0_DATA. */
+#define GPIO_WEST01_14 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xe) /**< ME_SMB0_ALRT_N. */
+#define GPIO_WEST01_15 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0xf) /**< ME_SMB1_CLK. */
+#define GPIO_WEST01_16 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x10) /**< ME_SMB1_DATA. */
+#define GPIO_WEST01_17 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x11) /**< ME_SMB1_ALRT_N. */
+#define GPIO_WEST01_18 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x12) /**< ME_SMB2_CLK. */
+#define GPIO_WEST01_19 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x13) /**< ME_SMB2_DATA. */
+#define GPIO_WEST01_20 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x14) /**< ME_SMB2_ALRT_N. */
+#define GPIO_WEST01_21 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x15) /**< GBE_MNG_I2C_CLK. */
+#define GPIO_WEST01_22 SNR_GPIO_DEF(GPIO_COMM_WEST01, 0x16) /**< GBE_MNG_I2C_DATA. */
+#define GPIO_WEST5_0 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x0) /**< IE_UART_RXD. */
+#define GPIO_WEST5_1 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x1) /**< IE_UART_TXD. */
+#define GPIO_WEST5_2 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x2) /**< VPP_SMB_CLK. */
+#define GPIO_WEST5_3 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x3) /**< VPP_SMB_DATA. */
+#define GPIO_WEST5_4 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x4) /**< VPP_SMB_ALRT_N. */
+#define GPIO_WEST5_5 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x5) /**< PCIE_CLKREQ0_N. */
+#define GPIO_WEST5_6 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x6) /**< PCIE_CLKREQ1_N. */
+#define GPIO_WEST5_7 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x7) /**< PCIE_CLKREQ2_N. */
+#define GPIO_WEST5_8 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x8) /**< PCIE_CLKREQ3_N. */
+#define GPIO_WEST5_15 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0xf) /**< FLEX_CLK_SE0. */
+#define GPIO_WEST5_16 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x10) /**< FLEX_CLK_SE1. */
+#define GPIO_WEST5_17 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x11) /**< FLEX_CLK1_50. */
+#define GPIO_WEST5_18 SNR_GPIO_DEF(GPIO_COMM_WEST5, 0x12) /**< FLEX_CLK2_50. */
+#define GPIO_WESTB_0 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x0) /**< Reserved. */
+#define GPIO_WESTB_8 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x8) /**< DBG_SPARE0. */
+#define GPIO_WESTB_9 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0x9) /**< DBG_SPARE1. */
+#define GPIO_WESTB_10 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0xa) /**< DBG_SPARE2. */
+#define GPIO_WESTB_11 SNR_GPIO_DEF(GPIO_COMM_WESTB, 0xb) /**< DBG_SPARE3. */
+#define GPIO_WESTD_PECI_0 SNR_GPIO_DEF(GPIO_COMM_WESTD_PECI, 0x0) /**< PECI_PCH. For P5900. */
+#define GPIO_EAST2_0 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x0) /**< USB_OC0_N. */
+#define GPIO_EAST2_1 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x1) /**< GPIO_0. */
+#define GPIO_EAST2_2 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x2) /**< GPIO_1. */
+#define GPIO_EAST2_3 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x3) /**< GPIO_2. */
+#define GPIO_EAST2_4 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x4) /**< GPIO_3. */
+#define GPIO_EAST2_5 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x5) /**< GPIO_4. */
+#define GPIO_EAST2_6 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x6) /**< GPIO_5. */
+#define GPIO_EAST2_7 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x7) /**< GPIO_6. */
+#define GPIO_EAST2_8 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x8) /**< GPIO_7. */
+#define GPIO_EAST2_9 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x9) /**< GPIO_8. */
+#define GPIO_EAST2_10 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xa) /**< GPIO_9. */
+#define GPIO_EAST2_11 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xb) /**< GPIO_10. */
+#define GPIO_EAST2_12 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xc) /**< GPIO_11. */
+#define GPIO_EAST2_13 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xd) /**< GPIO_12. */
+#define GPIO_EAST2_14 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xe) /**< PECI_SMB_DATA. */
+#define GPIO_EAST2_15 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0xf) /**< SATA0_LED_N. */
+#define GPIO_EAST2_17 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x11) /**< SATA_PDETECT0. */
+#define GPIO_EAST2_18 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x12) /**< SATA_PDETECT1. */
+#define GPIO_EAST2_19 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x13) /**< SATA0_SDOUT. */
+#define GPIO_EAST2_20 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x14) /**< SATA1_SDOUT. */
+#define GPIO_EAST2_21 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x15) /**< SATA2_LED_N. */
+#define GPIO_EAST2_22 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x16) /**< SATA_PDETECT2. */
+#define GPIO_EAST2_23 SNR_GPIO_DEF(GPIO_COMM_EAST2, 0x17) /**< SATA2_SDOUT. */
+#define GPIO_EAST3_0 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x0) /**< ESPI_IO0. For P5900. */
+#define GPIO_EAST3_1 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x1) /**< ESPI_IO1. */
+#define GPIO_EAST3_2 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x2) /**< ESPI_IO2. */
+#define GPIO_EAST3_3 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x3) /**< ESPI_IO3. */
+#define GPIO_EAST3_4 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x4) /**< ESPI_CLK. */
+#define GPIO_EAST3_5 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x5) /**< ESPI_RST_N. */
+#define GPIO_EAST3_6 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x6) /**< ESPI_CS0_N. */
+#define GPIO_EAST3_7 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x7) /**< ESPI_ALRT0_N. */
+#define GPIO_EAST3_8 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x8) /**< ESPI_CS1_N. */
+#define GPIO_EAST3_9 SNR_GPIO_DEF(GPIO_COMM_EAST3, 0x9) /**< ESPI_ALRT1_N. */
+#define GPIO_EAST0_0 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x0) /**< Reserved. */
+#define GPIO_EAST0_10 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xa) /**< ADR_COMPLETE. */
+#define GPIO_EAST0_11 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xb) /**< ADR_TRIGGER_N. */
+#define GPIO_EAST0_13 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0xd) /**< PMU_SLP_S3_N. */
+#define GPIO_EAST0_18 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x12) /**< SUS_STAT_N. Not documented. */
+#define GPIO_EAST0_19 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x13) /**< PMU_I2C_CLK. */
+#define GPIO_EAST0_20 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x14) /**< PMU_I2C_DATA. */
+#define GPIO_EAST0_21 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x15) /**< PECI_SMB_CLK. */
+#define GPIO_EAST0_22 SNR_GPIO_DEF(GPIO_COMM_EAST0, 0x16) /**< PECI_SMB_ALRT_N. */
+#define GPIO_EMMC_0 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x0) /**< EMMC_CMD. */
+#define GPIO_EMMC_1 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x1) /**< EMMC_STROBE. */
+#define GPIO_EMMC_2 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x2) /**< EMMC_CLK. */
+#define GPIO_EMMC_3 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x3) /**< EMMC_D0. */
+#define GPIO_EMMC_4 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x4) /**< EMMC_D1. */
+#define GPIO_EMMC_5 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x5) /**< EMMC_D2. */
+#define GPIO_EMMC_6 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x6) /**< EMMC_D3. */
+#define GPIO_EMMC_7 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x7) /**< EMMC_D4. */
+#define GPIO_EMMC_8 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x8) /**< EMMC_D5. */
+#define GPIO_EMMC_9 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0x9) /**< EMMC_D6. */
+#define GPIO_EMMC_10 SNR_GPIO_DEF(GPIO_COMM_EMMC, 0xa) /**< EMMC_D7. */
+
+void gpio_configure_snr_pads(struct snr_pad_config *gpio, size_t num);
+
+#endif // _SOC_SNOWRIDGE_GPIO_SNR_H_
diff --git a/src/soc/intel/snowridge/include/soc/iomap.h b/src/soc/intel/snowridge/include/soc/iomap.h
new file mode 100644
index 0000000000..11a06aceab
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/iomap.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_IOMAP_H_
+#define _SOC_SNOWRIDGE_IOMAP_H_
+
+#define TCO_BASE_ADDRESS 0x400
+
+/**
+ * @brief PMC PciCfgSpace is not PCI compliant. Intel FSP will hide the PMC controller to avoid
+ * external software or OS from corrupting the BAR addresses. Intel® FSP will program the PMC
+ * controller I/O and MMIO BARs with the following addresses. Use these addresses in the
+ * bootloader code instead of reading from the PMC controller. This process takes place during
+ * Intel FSP-S, @sa SnowRidge FSP Integration Guide.
+ */
+#define ACPI_BASE_ADDRESS 0x00000500
+#define PCH_PWRM_BASE_ADDRESS 0xfe000000
+
+#define SPI_BASE_ADDRESS 0xfe010000
+#define SPI_BASE_SIZE 0x00001000
+
+#define RESERVED_BASE_ADDRESS 0xfc000000 /**< PCH reserved. */
+#define RESERVED_BASE_SIZE 0x02c00000
+
+#endif // _SOC_SNOWRIDGE_IOMAP_H_
diff --git a/src/soc/intel/snowridge/include/soc/irq.h b/src/soc/intel/snowridge/include/soc/irq.h
new file mode 100644
index 0000000000..18d9f89e83
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/irq.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef _SOC_SNOWRIDGE_IRQ_H_
+#define _SOC_SNOWRIDGE_IRQ_H_
+
+#define PCH_IRQ10 10
+#define PCH_IRQ11 11
+#define PCH_IRQ16 16
+
+#define PCH_REDIR_ETR 120
+
+#define PCH_IOAPIC_ID 8
+
+#endif // _SOC_SNOWRIDGE_IRQ_H_
diff --git a/src/soc/intel/snowridge/include/soc/itss.h b/src/soc/intel/snowridge/include/soc/itss.h
new file mode 100644
index 0000000000..916c2510ad
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/itss.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_ITSS_H_
+#define _SOC_SNOWRIDGE_ITSS_H_
+
+#include <device/device.h>
+#include <southbridge/intel/common/acpi_pirq_gen.h>
+
+enum pirq itss_soc_get_dev_pirq(struct device *dev);
+
+#endif // _SOC_SNOWRIDGE_ITSS_H_
diff --git a/src/soc/intel/snowridge/include/soc/lpc.h b/src/soc/intel/snowridge/include/soc/lpc.h
new file mode 100644
index 0000000000..bea9a035a0
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/lpc.h
@@ -0,0 +1,6 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_LPC_H_
+#define _SOC_SNOWRIDGE_LPC_H_
+
+#endif // _SOC_SNOWRIDGE_LPC_H_
diff --git a/src/soc/intel/snowridge/include/soc/msr.h b/src/soc/intel/snowridge/include/soc/msr.h
new file mode 100644
index 0000000000..b45050b794
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/msr.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_MSR_H_
+#define _SOC_SNOWRIDGE_MSR_H_
+
+#include <intelblocks/msr.h>
+
+/**
+ * @brief Force serialized SMM relocation by hardcoding `SMM_CPU_SVRSTR` feature as not supported.
+ */
+#ifdef SMM_CPU_SVRSTR_MASK
+#undef SMM_CPU_SVRSTR_MASK
+#endif
+#define SMM_CPU_SVRSTR_MASK 0
+
+#define MSR_BIOS_DONE 0x151
+#define ENABLE_IA_UNTRUSTED BIT(0)
+
+#endif // _SOC_SNOWRIDGE_MSR_H_
diff --git a/src/soc/intel/snowridge/include/soc/nvs.h b/src/soc/intel/snowridge/include/soc/nvs.h
new file mode 100644
index 0000000000..7b0950386e
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/nvs.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_NVS_H_
+#define _SOC_SNOWRIDGE_NVS_H_
+
+#include <intelblocks/nvs.h>
+
+#endif // _SOC_SNOWRIDGE_NVS_H_
diff --git a/src/soc/intel/snowridge/include/soc/p2sb.h b/src/soc/intel/snowridge/include/soc/p2sb.h
new file mode 100644
index 0000000000..e70a3aaf04
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/p2sb.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_P2SB_H_
+#define _SOC_SNOWRIDGE_P2SB_H_
+
+#include <commonlib/bsd/helpers.h>
+
+#define PCH_P2SB_EPMASK0 0x220
+
+#define P2SB_BAR CONFIG_PCR_BASE_ADDRESS
+#define P2SB_SIZE (16 * MiB)
+
+#define HPTC_OFFSET 0x60
+#define HPTC_ADDR_ENABLE_BIT BIT(7)
+
+#endif /* _SOC_SNOWRIDGE_P2SB_H_ */
diff --git a/src/soc/intel/snowridge/include/soc/pci_devs.h b/src/soc/intel/snowridge/include/soc/pci_devs.h
new file mode 100644
index 0000000000..ca50bf8eb1
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/pci_devs.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_PCI_DEVS_H_
+#define _SOC_SNOWRIDGE_PCI_DEVS_H_
+
+#include <device/pci_def.h>
+
+#if defined(__SIMPLE_DEVICE__)
+#include <device/pci_type.h>
+#define _SA_DEV(slot, func) PCI_DEV(0x00, slot, func)
+#define _PCH_DEV(slot, func) PCI_DEV(0x00, slot, func)
+#define _UBOX0_DEV(slot, func) PCI_DEV(0xFE, slot, func)
+#define _UBOX1_DEV(slot, func) PCI_DEV(0xFF, slot, func)
+#else
+#include <device/device.h>
+#define _SA_DEV(slot, func) pcidev_path_on_bus(0, PCI_DEVFN(slot, func))
+#define _PCH_DEV(slot, func) pcidev_path_on_bus(0, PCI_DEVFN(slot, func))
+#define _UBOX0_DEV(slot, func) pcidev_path_on_bus(0xFE, PCI_DEVFN(slot, func))
+#define _UBOX1_DEV(slot, func) pcidev_path_on_bus(0xFF, PCI_DEVFN(slot, func))
+#endif
+
+/* Stack S0. */
+#define SA_DEV_ROOT _SA_DEV(0x00, 0)
+#define PCH_DEVFN_QAT_1_7 PCI_DEVFN(0x06, 0)
+#define PCH_DEVFN_PCIE_RP0 PCI_DEVFN(0x09, 0)
+#define PCH_DEVFN_PCIE_RP1 PCI_DEVFN(0x0a, 0)
+#define PCH_DEVFN_PCIE_RP2 PCI_DEVFN(0x0b, 0)
+#define PCH_DEVFN_PCIE_RP3 PCI_DEVFN(0x0c, 0)
+#define PCH_DEVFN_PCIE_RP8 PCI_DEVFN(0x14, 0)
+#define PCH_DEVFN_PCIE_RP9 PCI_DEVFN(0x15, 0)
+#define PCH_DEVFN_PCIE_RP10 PCI_DEVFN(0x16, 0)
+#define PCH_DEVFN_PCIE_RP11 PCI_DEVFN(0x17, 0)
+#define PCH_DEV_UART(func) _PCH_DEV(0x1a, func)
+
+#define MIN_PCH_SLOT PCI_SLOT(PCH_DEVFN_QAT_1_7)
+
+/**
+ * @note To use common block xhci, `PCH_DEVFN_XHCI` need to be defined as `PCI_DEV` not
+ * `PCI_DEVFN`. Actually they are same for this SoC.
+ */
+#define PCH_DEVFN_XHCI PCI_DEV(0x0, 0x1e, 0)
+#define PCH_DEV_XHCI _PCH_DEV(0x1e, 0)
+
+#define PCH_DEVFN_LPC PCI_DEVFN(0x1f, 0)
+#define PCH_DEV_LPC _PCH_DEV(0x1f, 0)
+#define PCH_DEVFN_P2SB PCI_DEVFN(0x1f, 1)
+#define PCH_DEV_P2SB _PCH_DEV(0x1f, 1)
+#define PCH_DEVFN_PMC PCI_DEVFN(0x1f, 2)
+#define PCH_DEVFN_SMBUS PCI_DEVFN(0x1f, 4)
+#define PCH_DEV_SMBUS _PCH_DEV(0x1f, 4)
+#define PCH_DEVFN_SPI PCI_DEVFN(0x1f, 5)
+#define PCH_DEV_SPI _PCH_DEV(0x1f, 5)
+
+/* Stack S1. */
+#define CPU_DEVFN_PCIE_RPA PCI_DEVFN(0x04, 0)
+#define CPU_DEVFN_PCIE_RPB PCI_DEVFN(0x05, 0)
+#define CPU_DEVFN_PCIE_RPC PCI_DEVFN(0x06, 0)
+#define CPU_DEVFN_PCIE_RPD PCI_DEVFN(0x07, 0)
+
+/* Stack S2. */
+#define DLB_DEVFN PCI_DEVFN(0x00, 0)
+
+/* Stack S3. */
+#define NIS_DEVFN PCI_DEVFN(0x04, 0)
+
+/* Stack S4. */
+#define QAT_1_8_DEVFN PCI_DEVFN(0x05, 0)
+
+/* Stack U0. */
+#define UBOX_DEV_RACU _UBOX0_DEV(0x00, 1)
+#define UBOX_DEV_NCDECS _UBOX0_DEV(0x00, 2)
+
+/* Stack U1. */
+#define CHAALL_DEV(func) _UBOX1_DEV(0x1d, func)
+
+/**
+ * Before calling FspMemoryInit(), the bus number for UBox 0 is 0x1E.
+ */
+#define IMC_SPD_DEV PCI_DEV(0x1e, 0x0b, 0)
+
+#endif // _SOC_SNOWRIDGE_PCI_DEVS_H_
diff --git a/src/soc/intel/snowridge/include/soc/pcr_gpmr.h b/src/soc/intel/snowridge/include/soc/pcr_gpmr.h
new file mode 100644
index 0000000000..c2879271c6
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/pcr_gpmr.h
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_GPMR_H_
+#define _SOC_SNOWRIDGE_GPMR_H_
+
+#define GPMR_LPCLGIR1 0xe30
+#define GPMR_DMICTL 0xefc
+#define GPMR_DMICTL_SRLOCK BIT(31)
+
+#define GPMR_LPCGMR 0xe40
+#define GPMR_GCS 0xe4c
+#define GPMR_GCS_BILD BIT(0)
+
+#define GPMR_LPCIOD 0xe70
+#define GPMR_LPCIOE 0xe74
+#define GPMR_TCOBASE 0xe78
+#define GPMR_TCOEN BIT(1)
+
+#endif // _SOC_SNOWRIDGE_GPMR_H_
diff --git a/src/soc/intel/snowridge/include/soc/pcr_ids.h b/src/soc/intel/snowridge/include/soc/pcr_ids.h
new file mode 100644
index 0000000000..94f1f17b11
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/pcr_ids.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_PCR_IDS_H_
+#define _SOC_SNOWRIDGE_PCR_IDS_H_
+
+#define PID_PCIE2_P0 0x71
+#define PID_PSTH 0x89
+#define PID_ESPISPI 0x93
+#define PID_USB2 0xA7
+#define PID_PCIE0_P0 0xB4
+#define PID_MODPHY1 0xBA
+#define PID_MODPHY2 0xBB
+#define PID_GPIOCOM1 0xC2 /**< GPIO Community West. */
+#define PID_GPIOCOM0 0xC5 /**< GPIO Community East. */
+#define PID_CC 0xCC
+#define PID_SMB 0xCF
+#define PID_ITSS 0xD0
+#define PID_LPC 0xD2
+#define PID_RTC 0xD1
+#define PID_DMI 0x4D
+
+#endif // _SOC_SNOWRIDGE_PCR_IDS_H_
diff --git a/src/soc/intel/snowridge/include/soc/pm.h b/src/soc/intel/snowridge/include/soc/pm.h
new file mode 100644
index 0000000000..fe5c292c0d
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/pm.h
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_PM_H_
+#define _SOC_SNOWRIDGE_PM_H_
+
+#include <acpi/acpi.h>
+#include <intelpch/gpe.h>
+#include <stdint.h>
+#include <soc/iomap.h>
+#include <soc/pmc.h>
+
+#define PM1_STS 0x00
+#define WAK_STS BIT(15)
+#define PWRBTN_STS BIT(8)
+#define PM1_EN 0x02
+#define PWRBTN_EN BIT(8)
+#define GBL_EN BIT(5)
+#define PM1_CNT 0x04
+#define SCI_EN BIT(0)
+#define PM1_TMR 0x08
+#define SMI_EN 0x30
+#define XHCI_SMI_EN BIT(31)
+#define ME_SMI_EN BIT(30)
+#define ESPI_SMI_EN BIT(28)
+#define GPIO_UNLOCK_SMI_EN BIT(27)
+#define SDX_SMI_EN BIT(25)
+#define THERM_SMI_EN BIT(18)
+#define LEGACY_USB2_EN BIT(17)
+#define PERIODIC_EN BIT(14)
+#define TCO_SMI_EN BIT(13)
+#define MCSMI_EN BIT(11)
+#define BIOS_RLS BIT(7)
+#define SWSMI_TMR_EN BIT(6)
+#define APMC_EN BIT(5)
+#define SLP_SMI_EN BIT(4)
+#define LEGACY_USB_EN BIT(3)
+#define BIOS_EN BIT(2)
+#define EOS BIT(1)
+#define GBL_SMI_EN BIT(0)
+#define SMI_STS 0x34
+#define SMI_STS_BITS 32
+#define XHCI_SMI_STS_BIT 31
+#define ME_SMI_STS_BIT 30
+#define ESPI_SMI_STS_BIT 28
+#define GPIO_UNLOCK_SMI_STS_BIT 27
+#define SPI_SMI_STS_BIT 26
+#define SCC_SMI_STS_BIT 25
+#define INTERNAL_TT_STS_BIT 22
+#define MONITOR_STS_BIT 21
+#define PCI_EXP_SMI_STS_BIT 20
+#define RTC_UIP_SMI_STS_BIT 19
+#define THERMAL_SMI_STS_BIT 18
+#define LEGACY_USB2_STS_BIT 17
+#define SMBUS_SMI_STS_BIT 16
+#define SERIRQ_SMI_STS_BIT 15
+#define PERIODIC_STS_BIT 14
+#define TCO_STS_BIT 13
+#define DEVMON_STS_BIT 12
+#define MCSMI_STS_BIT 11
+#define GPIO_STS_BIT 10
+#define GPE0_STS_BIT 9
+#define PM1_STS_BIT 8
+#define SWSMI_TMR_STS_BIT 6
+#define APM_STS_BIT 5
+#define SMI_ON_SLP_EN_STS_BIT 4
+#define LEGACY_USB_STS_BIT 3
+#define BIOS_STS_BIT 2
+#define PM2_CNT 0x50
+
+#define GPE0_REG_MAX 4
+#define GPE0_STS(x) (0x60 + ((x) * 4))
+#define GPE_31_0 0 /**< 0x60 = GPE[31:0]. */
+#define GPE_63_32 1 /**< 0x64 = GPE[63:32]. */
+#define GPE_95_64 2 /**< 0x68 = GPE[95:64]. */
+#define GPE_STD 3 /**< 0x6c = Standard GPE. */
+
+#define GPE0_EN(x) (0x70 + ((x) * 4))
+#define WADT_EN BIT(18)
+#define USB_CON_DSX_EN BIT(17)
+#define LANWAKE_EN BIT(16)
+#define GPIO_T2_EN BIT(15)
+#define ESPI_EN BIT(14)
+#define PME_B0_EN BIT(13)
+#define ME_SCI_EN BIT(12)
+#define PME_EN BIT(11)
+#define BATLOW_EN BIT(10)
+#define PCI_EXP_EN BIT(9)
+#define TCOSCI_EN BIT(6)
+#define THERM_EN BIT(4)
+#define SWGPE_EN BIT(2)
+#define HOT_PLUG_EN BIT(1)
+
+/**
+ * @brief Enable SMI generation:
+ * - on APMC writes (io 0xb2)
+ * - on writes to SLP_EN (sleep states)
+ * - on writes to GBL_RLS (bios commands)
+ * - on eSPI events (does nothing on LPC systems)
+ * No SMIs:
+ * - on TCO events, unless enabled in common code
+ * - on microcontroller writes (io 0x62/0x66)
+ */
+#define ENABLE_SMI_PARAMS (APMC_EN | SLP_SMI_EN | GBL_SMI_EN | ESPI_SMI_EN | EOS)
+
+#define PSS_RATIO_STEP 2
+#define PSS_MAX_ENTRIES 8
+#define PSS_LATENCY_TRANSITION 10
+#define PSS_LATENCY_BUSMASTER 10
+
+struct chipset_power_state {
+ uint16_t pm1_sts;
+ uint16_t pm1_en;
+ uint32_t pm1_cnt;
+ uint32_t gpe0_sts[4];
+ uint32_t gpe0_en[4];
+
+ uint32_t prev_sleep_state;
+} __packed;
+
+/**
+ * @brief Return base address of Power Management Controller memory mapped registers, definition
+ * is not needed.
+ *
+ * @return uint8_t*
+ */
+uint8_t *pmc_mmio_regs(void);
+
+#endif // _SOC_SNOWRIDGE_PM_H_
diff --git a/src/soc/intel/snowridge/include/soc/pmc.h b/src/soc/intel/snowridge/include/soc/pmc.h
new file mode 100644
index 0000000000..01873d3d93
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/pmc.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_PMC_H_
+#define _SOC_SNOWRIDGE_PMC_H_
+
+#define GEN_PMCON_A 0x1020
+#define GBL_RST_STS BIT(24)
+#define MS4V BIT(18)
+#define SUS_PWR_FLR BIT(16)
+#define PWR_FLR BIT(14)
+#define PER_SMI_SEL_MASK (3 << 1)
+#define SMI_RATE_64S (0 << 1)
+#define SMI_RATE_32S BIT(1)
+#define SMI_RATE_16S (2 << 1)
+#define SMI_RATE_8S (3 << 1)
+#define SLEEP_AFTER_POWER_FAIL BIT(0)
+#define GEN_PMCON_B 0x1024
+#define SLP_STR_POL_LOCK BIT(18)
+#define ACPI_BASE_LOCK BIT(17)
+#define SMI_LOCK BIT(4)
+#define ETR 0x1048
+#define CF9_LOCK BIT(31)
+#define CF9_GLB_RST BIT(20)
+#define PRSTS 0x1810
+#define PMSYNC_TPR_CFG 0x18C4
+#define PCH2CPU_TPR_CFG_LOCK BIT(31)
+#define GPIO_GPE_CFG 0x1920
+#define GPE0_DWX_MASK 0xf
+#define GPE0_DW_SHIFT(x) (4 * (x))
+#define ACTL 0x1BD8
+#define SCI_IRQ_SEL (7 << 0)
+#define SCI_IRQ_ADJUST 0
+#define SCIS_IRQ9 0
+#define SCIS_IRQ10 1
+#define SCIS_IRQ11 2
+#define SCIS_IRQ20 4
+#define SCIS_IRQ21 5
+#define SCIS_IRQ22 6
+#define SCIS_IRQ23 7
+
+#endif // _SOC_SNOWRIDGE_PMC_H_
diff --git a/src/soc/intel/snowridge/include/soc/sata.h b/src/soc/intel/snowridge/include/soc/sata.h
new file mode 100644
index 0000000000..b52cffe389
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/sata.h
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_SATA_H_
+#define _SOC_SNOWRIDGE_SATA_H_
+
+#define SATA_ABAR 0x24
+#define SATA_MAP 0x90
+#define SATA_MAP_AHCI (0 << 6)
+#define SATA_MAP_RAID (1 << 6)
+
+#define SATA_GHC 0x04
+#define SATA_GHC_AE BIT(31)
+
+#endif // _SOC_SNOWRIDGE_SATA_H_
diff --git a/src/soc/intel/snowridge/include/soc/smbus.h b/src/soc/intel/snowridge/include/soc/smbus.h
new file mode 100644
index 0000000000..20b7897843
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/smbus.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_SMBUS_H_
+#define _SOC_SNOWRIDGE_SMBUS_H_
+
+#include <intelpch/smbus.h>
+
+#endif // _SOC_SNOWRIDGE_SMBUS_H_
diff --git a/src/soc/intel/snowridge/include/soc/soc_chip.h b/src/soc/intel/snowridge/include/soc/soc_chip.h
new file mode 100644
index 0000000000..713291c9b4
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/soc_chip.h
@@ -0,0 +1,8 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_SOC_CHIP_H_
+#define _SOC_SNOWRIDGE_SOC_CHIP_H_
+
+#include "../../chip.h"
+
+#endif // _SOC_SNOWRIDGE_SOC_CHIP_H_
diff --git a/src/soc/intel/snowridge/include/soc/systemagent.h b/src/soc/intel/snowridge/include/soc/systemagent.h
new file mode 100644
index 0000000000..532f71773e
--- /dev/null
+++ b/src/soc/intel/snowridge/include/soc/systemagent.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_SYSTEMAGENT_H_
+#define _SOC_SNOWRIDGE_SYSTEMAGENT_H_
+
+#define PCIE_MMCFG_BASE 0x90
+#define PCIE_MMCFG_LIMIT 0x98
+#define TSEG 0xA8
+#define TSEG_LIMIT 0xAC
+#define TOCM 0xC0
+#define TOUUD 0xC8
+#define TOLUD 0xD0
+#define MMIOL 0xD8
+
+#define VTBAR 0x180
+#define VTD_CHIPSET_BASE_ADDRESS_ENABLE BIT(0)
+
+#define DPR 0x290
+
+#define VTD_ECAP 0x10
+#define DEVICE_TLB BIT(2)
+
+#endif // _SOC_SNOWRIDGE_SYSTEMAGENT_H_
diff --git a/src/soc/intel/snowridge/itss.c b/src/soc/intel/snowridge/itss.c
new file mode 100644
index 0000000000..07f5b1d788
--- /dev/null
+++ b/src/soc/intel/snowridge/itss.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ops.h>
+#include <device/pci_type.h>
+#include <intelblocks/itss.h>
+#include <soc/itss.h>
+#include <soc/pci_devs.h>
+#include <static.h>
+
+#include "ramstage.h"
+
+uint32_t itss_soc_get_on_chip_dev_pir(struct device *dev)
+{
+ /* Check if device is on chip. */
+ if (dev->upstream->dev->path.type != DEVICE_PATH_DOMAIN)
+ return 0;
+
+ if (!is_pci(dev))
+ return 0;
+
+ const unsigned int devfn = dev->path.pci.devfn;
+ switch (dev_get_domain_id(dev)) {
+ case 0:
+ return PCI_ITSS_PIR(PCI_SLOT(devfn));
+ case 3:
+ if (devfn == NIS_DEVFN)
+ return PCI_ITSS_PIR(25);
+ break;
+ case 4:
+ if (devfn == QAT_1_8_DEVFN)
+ return PCI_ITSS_PIR(5);
+ break;
+ }
+
+ printk(BIOS_WARNING, "Unknown PIR for %s\n", dev_path(dev));
+ return 0;
+}
+
+enum pirq itss_soc_get_dev_pirq(struct device *dev)
+{
+ enum pci_pin dev_pin = pci_read_config8(dev, PCI_INTERRUPT_PIN);
+ if (dev_pin < PCI_INT_A || dev_pin > PCI_INT_D)
+ return PIRQ_INVALID;
+
+ struct device *bridge;
+ enum pci_pin swizzle_pin;
+ if (is_dev_on_domain0(dev)) {
+ /**
+ * Get the pin asserting from bridge to root.
+ * This function only applies for devices in domain 0.
+ */
+ swizzle_pin = get_pci_irq_pins(dev, &bridge);
+ if (swizzle_pin < PCI_INT_A || swizzle_pin > PCI_INT_D)
+ return PIRQ_INVALID;
+
+ /* Device attached to PCH PCIe Root Port need further swizzle. */
+ if (is_pci_bridge(bridge) && bridge != dev)
+ swizzle_pin = pciexp_get_rp_irq_pin(bridge, swizzle_pin);
+ } else if (dev->upstream->dev == DEV_PTR(nis_vrp)) {
+ bridge = DEV_PTR(nis_vrp);
+ swizzle_pin = (dev_pin - 1 + PCI_SLOT(dev->path.pci.devfn)) % 4 + 1;
+ } else if (dev->upstream->dev == DEV_PTR(qat_1_8_vrp)) {
+ bridge = DEV_PTR(qat_1_8_vrp);
+ swizzle_pin = (dev_pin - 1 + PCI_SLOT(dev->path.pci.devfn)) % 4 + 1;
+ } else {
+ bridge = dev;
+ swizzle_pin = dev_pin;
+ }
+
+ if (bridge != dev) {
+ /**
+ * We can't print `dev` path and `bridge` path in a single `printk()` due to
+ * restriction of `dev_path()`.
+ */
+ printk(BIOS_DEBUG, "%s %s swizzled to ", dev_path(dev), pin_to_str(dev_pin));
+ printk(BIOS_DEBUG, "%s %s.\n", dev_path(bridge), pin_to_str(swizzle_pin));
+ }
+
+ return itss_get_on_chip_dev_pirq(bridge, swizzle_pin);
+}
diff --git a/src/soc/intel/snowridge/lockdown.c b/src/soc/intel/snowridge/lockdown.c
new file mode 100644
index 0000000000..b74b74ca4b
--- /dev/null
+++ b/src/soc/intel/snowridge/lockdown.c
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/pci_ops.h>
+#include <intelblocks/cfg.h>
+#include <intelblocks/pmclib.h>
+#include <intelpch/lockdown.h>
+#include <soc/pci_devs.h>
+#include <soc/pm.h>
+#include <soc/pmc.h>
+
+#define SMM_FEATURE_CONTROL 0x8c
+#define SMM_CODE_CHK_EN (1 << 2)
+#define SMM_FEATURE_CONTROL_LOCK (1 << 0)
+
+static void pmc_lockdown_cfg(int chipset_lockdown)
+{
+ pmc_or_mmio32(PMSYNC_TPR_CFG, PCH2CPU_TPR_CFG_LOCK);
+ pmc_or_mmio32(GEN_PMCON_B, SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
+
+ pmc_global_reset_disable_and_lock();
+
+ assert(chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT);
+
+ pmc_or_mmio32(GEN_PMCON_B, SMI_LOCK);
+}
+
+void soc_lockdown_config(int chipset_lockdown)
+{
+ pmc_lockdown_cfg(chipset_lockdown);
+
+ pci_or_config32(UBOX_DEV_RACU, SMM_FEATURE_CONTROL,
+ SMM_CODE_CHK_EN | SMM_FEATURE_CONTROL_LOCK);
+}
diff --git a/src/soc/intel/snowridge/lpc.c b/src/soc/intel/snowridge/lpc.c
new file mode 100644
index 0000000000..128b7487d9
--- /dev/null
+++ b/src/soc/intel/snowridge/lpc.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/ioapic.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <intelblocks/itss.h>
+#include <intelblocks/lpc_lib.h>
+#include <intelblocks/pcr.h>
+#include <soc/iomap.h>
+#include <soc/irq.h>
+#include <soc/itss.h>
+#include <soc/pcr_ids.h>
+#include <static.h>
+
+static void soc_pch_pirq_init(void)
+{
+ for (uint32_t reg = PCR_ITSS_PIRQA_ROUT; reg <= PCR_ITSS_PIRQH_ROUT; reg++)
+ printk(BIOS_SPEW, "PIRQ Routing Control %c at 0x%04x: 0x%02x\n",
+ reg - PCR_ITSS_PIRQA_ROUT + 'A', reg, pcr_read8(PID_ITSS, reg));
+
+ for (uint32_t reg = 0; reg < 32; reg++)
+ printk(BIOS_SPEW, "PCI Interrupt Route %d at 0x%04x: 0x%02x\n", reg,
+ PCI_ITSS_PIR(reg), pcr_read16(PID_ITSS, PCI_ITSS_PIR(reg)));
+
+ /* The PIRQA-H registers are programmable thus legacy PIC mode is supported. */
+ size_t num;
+ const uint8_t *pch_interrupt_routing = lpc_get_pic_pirq_routing(&num);
+ itss_irq_init(pch_interrupt_routing);
+
+ for (struct device *dev = all_devices; dev; dev = dev->next) {
+ if (!is_enabled_pci(dev))
+ continue;
+
+ enum pirq pirq = itss_soc_get_dev_pirq(dev);
+ if (pirq == PIRQ_INVALID)
+ continue;
+
+ uint8_t pirq_value = pcr_read8(PID_ITSS, PCR_ITSS_PIRQA_ROUT + pirq_idx(pirq));
+ if (pirq_value & 0x80)
+ pci_write_config8(dev, PCI_INTERRUPT_LINE, PCH_IRQ16 + pirq_idx(pirq));
+ else
+ pci_write_config8(dev, PCI_INTERRUPT_LINE, pirq_value & 0x0f);
+
+ printk(BIOS_DEBUG, "%s is using %s, line 0x%2x\n", dev_path(dev),
+ pin_to_str(pci_read_config8(dev, PCI_INTERRUPT_PIN)),
+ pci_read_config8(dev, PCI_INTERRUPT_LINE));
+ }
+}
+
+void lpc_soc_init(struct device *dev)
+{
+ lpc_set_serirq_mode(CONFIG(SERIRQ_CONTINUOUS_MODE) ? SERIRQ_CONTINUOUS : SERIRQ_QUIET);
+
+ ioapic_set_max_vectors(IO_APIC_ADDR, PCH_REDIR_ETR);
+
+ setup_ioapic(IO_APIC_ADDR, PCH_IOAPIC_ID);
+ ioapic_set_boot_config(IO_APIC_ADDR, true);
+
+ soc_pch_pirq_init();
+}
+
+void pch_lpc_soc_fill_io_resources(struct device *dev)
+{
+ struct resource *res;
+
+ res = new_resource(dev, PCI_BASE_ADDRESS_4); /**< Use the register offset in PMC. */
+ res->base = ACPI_BASE_ADDRESS;
+ res->size = 0x80; /**< 128 bytes I/O config space */
+ res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+ printk(BIOS_DEBUG, "Adding ACPI IO config space BAR at base 0x%08llx, size 0x%08llx\n",
+ res->base, res->size);
+}
diff --git a/src/soc/intel/snowridge/nis.c b/src/soc/intel/snowridge/nis.c
new file mode 100644
index 0000000000..d716c3c983
--- /dev/null
+++ b/src/soc/intel/snowridge/nis.c
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "ramstage.h"
+
+static struct device_operations snr_nis_ops = {
+ .read_resources = pciexp_pf_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .final = pci_dev_request_bus_master,
+ .ops_pci = &pci_dev_ops_pci,
+};
+
+static const unsigned short snr_nis_ids[] = {
+ PCI_DID_INTEL_SNR_NIS1890,
+ PCI_DID_INTEL_SNR_NIS1891,
+ PCI_DID_INTEL_SNR_NIS1892,
+ PCI_DID_INTEL_SNR_NIS1895,
+ 0
+};
+
+static const struct pci_driver snr_nis_driver __pci_driver = {
+ .ops = &snr_nis_ops,
+ .vendor = PCI_VID_INTEL,
+ .devices = snr_nis_ids
+};
diff --git a/src/soc/intel/snowridge/pcie_rp.c b/src/soc/intel/snowridge/pcie_rp.c
new file mode 100644
index 0000000000..bf391c5308
--- /dev/null
+++ b/src/soc/intel/snowridge/pcie_rp.c
@@ -0,0 +1,192 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <commonlib/bsd/compiler.h>
+#include <console/console.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <device/pciexp.h>
+#include <soc/acpi.h>
+#include <soc/pci_devs.h>
+
+#include "ramstage.h"
+
+#define INTXSWZCTL 0xf8
+
+enum pci_pin pciexp_get_rp_irq_pin(struct device *bridge, enum pci_pin pin)
+{
+ /* Swizzle according to INTXSWZCTL register. */
+ enum pci_pin reg_swizzle_pin = pin;
+ uint8_t int_swx_ctl = pci_read_config8(bridge, INTXSWZCTL) & 0x07;
+ switch (int_swx_ctl) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ reg_swizzle_pin = (reg_swizzle_pin - 1 + int_swx_ctl) % 4 + 1;
+ break;
+ case 4:
+ reg_swizzle_pin = PCI_INT_A;
+ break;
+ default:
+ reg_swizzle_pin = PCI_INT_NONE;
+ break;
+ }
+
+ printk(BIOS_DEBUG, "Root Port %s %s swizzled to %s (INTXSWZCTL).\n", dev_path(bridge),
+ pin_to_str(pin), pin_to_str(reg_swizzle_pin));
+ if (reg_swizzle_pin < PCI_INT_A || reg_swizzle_pin > PCI_INT_D)
+ return reg_swizzle_pin;
+
+ /* Swizzle between PCIe Root Ports. */
+ enum pci_pin hardwired_swizzle_pin = reg_swizzle_pin;
+ switch (bridge->device) {
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP3:
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP11:
+ hardwired_swizzle_pin += 1;
+ __fallthrough;
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP2:
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP10:
+ hardwired_swizzle_pin += 1;
+ __fallthrough;
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP1:
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP9:
+ hardwired_swizzle_pin += 1;
+ __fallthrough;
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP0:
+ case PCI_DID_INTEL_SNR_PCH_PCIE_RP8:
+ hardwired_swizzle_pin = (hardwired_swizzle_pin - 1) % 4 + 1;
+ printk(BIOS_DEBUG, "Root Port %s %s swizzled to %s (Hard-wired).\n",
+ dev_path(bridge), pin_to_str(reg_swizzle_pin),
+ pin_to_str(hardwired_swizzle_pin));
+ __fallthrough;
+ default:
+ return hardwired_swizzle_pin;
+ }
+}
+
+static bool pcie_rp_is_vrp(struct device *dev)
+{
+ switch (dev_get_domain_id(dev)) {
+ case 0:
+ switch (dev->path.pci.devfn) {
+ case PCH_DEVFN_QAT_1_7:
+ return true;
+ default:
+ break;
+ }
+ break;
+ case 3:
+ if (dev->path.pci.devfn == NIS_DEVFN)
+ return true;
+ break;
+ case 4:
+ if (dev->path.pci.devfn == QAT_1_8_DEVFN)
+ return true;
+ break;
+ default:
+ break;
+ }
+
+ return false;
+}
+
+static void pcie_rp_scan_bridge(struct device *dev)
+{
+ if (pcie_rp_is_vrp(dev))
+ return pciexp_scan_bridge(dev);
+ else if (CONFIG(PCIEXP_HOTPLUG) && pciexp_dev_is_slot_hot_plug_cap(dev))
+ return pciexp_hotplug_scan_bridge(dev);
+ else
+ return pciexp_scan_bridge(dev);
+}
+
+static const char *pcie_rp_acpi_name(const struct device *dev)
+{
+ switch (dev_get_domain_id(dev)) {
+ case 0:
+ switch (dev->path.pci.devfn) {
+ case PCH_DEVFN_QAT_1_7:
+ return "VRP6";
+ case PCH_DEVFN_PCIE_RP0:
+ return "RP00";
+ case PCH_DEVFN_PCIE_RP1:
+ return "RP01";
+ case PCH_DEVFN_PCIE_RP2:
+ return "RP02";
+ case PCH_DEVFN_PCIE_RP3:
+ return "RP03";
+ case PCH_DEVFN_PCIE_RP8:
+ return "RP08";
+ case PCH_DEVFN_PCIE_RP9:
+ return "RP09";
+ case PCH_DEVFN_PCIE_RP10:
+ return "RP10";
+ case PCH_DEVFN_PCIE_RP11:
+ return "RP11";
+ default:
+ break;
+ }
+ break;
+ case 1:
+ switch (dev->path.pci.devfn) {
+ case CPU_DEVFN_PCIE_RPA:
+ return "RPA";
+ case CPU_DEVFN_PCIE_RPB:
+ return "RPB";
+ case CPU_DEVFN_PCIE_RPC:
+ return "RPC";
+ case CPU_DEVFN_PCIE_RPD:
+ return "RPD";
+ default:
+ break;
+ }
+ break;
+ case 3:
+ if (dev->path.pci.devfn == NIS_DEVFN)
+ return "VRP4";
+ break;
+ case 4:
+ if (dev->path.pci.devfn == QAT_1_8_DEVFN)
+ return "VRP5";
+ break;
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+static struct device_operations snr_pcie_rp_ops = {
+ .read_resources = pci_bus_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_bus_enable_resources,
+ .scan_bus = pcie_rp_scan_bridge,
+ .acpi_fill_ssdt = pcie_rp_fill_ssdt,
+ .acpi_name = pcie_rp_acpi_name,
+};
+
+static const unsigned short snr_pcie_rp_ids[] = {
+ PCI_DID_INTEL_SNR_VRP0_QAT_1_7,
+ PCI_DID_INTEL_SNR_VRP5_QAT_1_8,
+ PCI_DID_INTEL_SNR_VRP4_NIS,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP0,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP1,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP2,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP3,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP8,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP9,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP10,
+ PCI_DID_INTEL_SNR_PCH_PCIE_RP11,
+ PCI_DID_INTEL_SNR_CPU_PCIE_RPA,
+ PCI_DID_INTEL_SNR_CPU_PCIE_RPB,
+ PCI_DID_INTEL_SNR_CPU_PCIE_RPC,
+ PCI_DID_INTEL_SNR_CPU_PCIE_RPD,
+ 0
+};
+
+static const struct pci_driver snr_pcie_rp_driver __pci_driver = {
+ .ops = &snr_pcie_rp_ops,
+ .vendor = PCI_VID_INTEL,
+ .devices = snr_pcie_rp_ids
+};
diff --git a/src/soc/intel/snowridge/qat.c b/src/soc/intel/snowridge/qat.c
new file mode 100644
index 0000000000..5a35c31493
--- /dev/null
+++ b/src/soc/intel/snowridge/qat.c
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+
+#include "ramstage.h"
+
+static struct device_operations snr_qat_ops = {
+ .read_resources = pciexp_pf_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .final = pci_dev_request_bus_master,
+ .ops_pci = &pci_dev_ops_pci,
+};
+
+static const unsigned short snr_qat_ids[] = {
+ PCI_DID_INTEL_SNR_QAT_1_7,
+ PCI_DID_INTEL_SNR_QAT_1_8,
+ 0
+};
+
+static const struct pci_driver snr_qat_driver __pci_driver = {
+ .ops = &snr_qat_ops,
+ .vendor = PCI_VID_INTEL,
+ .devices = snr_qat_ids
+};
diff --git a/src/soc/intel/snowridge/ramstage.h b/src/soc/intel/snowridge/ramstage.h
new file mode 100644
index 0000000000..bcbc2f834b
--- /dev/null
+++ b/src/soc/intel/snowridge/ramstage.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef _SOC_SNOWRIDGE_RAMSTAGE_H_
+#define _SOC_SNOWRIDGE_RAMSTAGE_H_
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <southbridge/intel/common/acpi_pirq_gen.h>
+
+void pciexp_pf_read_resources(struct device *dev);
+void pciexp_vf_read_resources(struct device *dev);
+
+enum pci_pin pciexp_get_rp_irq_pin(struct device *bridge, enum pci_pin pin);
+
+#endif // _SOC_SNOWRIDGE_RAMSTAGE_H_
diff --git a/src/soc/intel/snowridge/romstage/gpio_snr.c b/src/soc/intel/snowridge/romstage/gpio_snr.c
new file mode 100644
index 0000000000..99d994861c
--- /dev/null
+++ b/src/soc/intel/snowridge/romstage/gpio_snr.c
@@ -0,0 +1,200 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <intelblocks/gpio.h>
+#include <intelblocks/pcr.h>
+#include <soc/gpio_snr.h>
+#include <soc/pci_devs.h>
+
+#define SNR_GPIO_GROUP(GPIO_PAD) (SNR_GPIO_PAD(GPIO_PAD) / GPIO_MAX_NUM_PER_GROUP)
+#define SNR_GPIO_WITHIN_GROUP(GPIO_PAD) (SNR_GPIO_PAD(GPIO_PAD) % GPIO_MAX_NUM_PER_GROUP)
+
+static void gpio_unlock_snr_pad_group(const struct pad_community *comm,
+ const size_t group_index, const uint32_t bit_mask)
+{
+ struct pcr_sbi_msg msg = {
+ .pid = comm->port,
+ .offset = comm->pad_cfg_lock_offset + group_index * 2 * sizeof(uint32_t),
+ .opcode = GPIO_LOCK_UNLOCK,
+ .is_posted = false,
+ .fast_byte_enable = 0xf,
+ .bar = 0,
+ .fid = 0,
+ };
+ uint32_t data;
+ uint8_t response;
+ int status;
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG,
+ "Unlock GPIO community %s, group %zu at offset 0x%04x with mask 0x%08x\n",
+ comm->name, group_index, msg.offset, bit_mask);
+
+ data = pcr_read32(msg.pid, msg.offset) & (~bit_mask);
+ status = pcr_execute_sideband_msg(PCH_DEV_P2SB, &msg, &data, &response);
+ if (status || response)
+ die("Failed to unlock GPIO PAD, response = %d\n", response);
+
+ msg.offset += sizeof(uint32_t);
+ data = pcr_read32(msg.pid, msg.offset) & (~bit_mask);
+ status = pcr_execute_sideband_msg(PCH_DEV_P2SB, &msg, &data, &response);
+ if (status || response)
+ die("Failed to unlock GPIO PAD Tx state, response = %d\n", response);
+}
+
+static uint8_t gpio_get_snr_pad_own(gpio_t pad)
+{
+ size_t num_communities;
+ const struct pad_community *comm =
+ soc_gpio_get_community(&num_communities) + SNR_GPIO_COMMUNITY(pad);
+ uint16_t pad_own_offset = comm->pad_own_reg_0;
+ uint32_t pad_own;
+
+ /**
+ * 4 bits for each pad.
+ */
+ pad_own_offset += (pad - comm->first_pad) / 8 * sizeof(uint32_t);
+ pad_own = pcr_read32(comm->port, pad_own_offset);
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG,
+ "Pad 0x%08x ownership at 0x%04x value = 0x%08x, mask = 0x%08x\n", pad,
+ pad_own_offset, pad_own, 0x03 << ((pad - comm->first_pad) % 8 * 4));
+
+ return (pad_own >> ((pad - comm->first_pad) % 8 * sizeof(uint32_t))) & 0x03;
+}
+
+static uint8_t gpio_get_snr_pad_hostsw_own(gpio_t pad)
+{
+ size_t num_communities;
+ const struct pad_community *comm =
+ soc_gpio_get_community(&num_communities) + SNR_GPIO_COMMUNITY(pad);
+ uint32_t host_sw_own;
+
+ host_sw_own = pcr_read32(comm->port, comm->host_own_reg_0 + SNR_GPIO_GROUP(pad));
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG,
+ "Pad 0x%08x host software ownership at 0x%04x value = 0x%08x, mask = 0x%08x\n",
+ pad, comm->host_own_reg_0 + SNR_GPIO_GROUP(pad), host_sw_own,
+ 0x01 << SNR_GPIO_WITHIN_GROUP(pad));
+
+ return (host_sw_own >> SNR_GPIO_WITHIN_GROUP(pad)) & 0x01;
+}
+
+static void gpio_clear_snr_pad_group_interrupt_status(const struct pad_community *comm,
+ const size_t group_index,
+ const uint32_t bit_mask)
+{
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG,
+ "Clear GPIO community %s, group %zu interrupt status with mask 0x%08x\n",
+ comm->name, group_index, bit_mask);
+
+ const uint16_t offset = group_index * sizeof(uint32_t);
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG, "GPI interrupt status at offset 0x%04x\n",
+ comm->gpi_int_sts_reg_0 + offset);
+ pcr_write32(comm->port, comm->gpi_int_sts_reg_0 + offset, bit_mask);
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG, "GPI GPE status at offset 0x%04x\n",
+ comm->gpi_gpe_sts_reg_0 + offset);
+ pcr_write32(comm->port, comm->gpi_gpe_sts_reg_0 + offset, bit_mask);
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG, "SMI status at offset 0x%04x\n",
+ comm->gpi_smi_sts_reg_0 + offset);
+ pcr_write32(comm->port, comm->gpi_smi_sts_reg_0 + offset, bit_mask);
+
+ if (CONFIG(DEBUG_GPIO))
+ printk(BIOS_DEBUG, "NMI status at offset 0x%04x\n",
+ comm->gpi_nmi_sts_reg_0 + offset);
+ pcr_write32(comm->port, comm->gpi_nmi_sts_reg_0 + offset, bit_mask);
+}
+
+void gpio_configure_snr_pads(struct snr_pad_config *gpio, size_t num)
+{
+ size_t i, j, num_communities, comm_index, group_index;
+ const struct pad_community *comm = soc_gpio_get_community(&num_communities);
+ uint16_t config_offset;
+ uint32_t bit_mask, pad_conf;
+
+ if (!gpio || num == 0)
+ return;
+
+ /**
+ * Unlock pad configuration and pad tx configuration at group level.
+ */
+ for (i = 0; i < num; i++) {
+ comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad);
+ if (comm_index >= num_communities) {
+ printk(BIOS_WARNING, "Invalid GPIO community index %zu\n", comm_index);
+ continue;
+ }
+
+ group_index = SNR_GPIO_GROUP(gpio[i].cfg.pad);
+ if (group_index >= comm->num_groups) {
+ printk(BIOS_WARNING, "Invalid GPIO group index %zu\n", group_index);
+ continue;
+ }
+
+ bit_mask = 1 << (SNR_GPIO_PAD(gpio[i].cfg.pad) % GPIO_MAX_NUM_PER_GROUP);
+
+ gpio_unlock_snr_pad_group(&comm[comm_index], group_index, bit_mask);
+ }
+
+ /**
+ * @note Common block GPIO code doesn't support leaving some bits as default value, thus we
+ * should read the original value and set concerned bits before calling common code.
+ */
+ for (i = 0; i < num; i++) {
+ if (gpio_get_snr_pad_own(gpio[i].cfg.pad) != GPIO_PAD_OWN_HOST) {
+ printk(BIOS_ERR, "GPIO pad 0x%08x is not owned by host\n",
+ gpio[i].cfg.pad);
+ continue;
+ }
+
+ comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad);
+ config_offset = comm[comm_index].pad_cfg_base +
+ (gpio[i].cfg.pad - comm[comm_index].first_pad) *
+ GPIO_NUM_PAD_CFG_REGS * sizeof(uint32_t);
+ for (j = 0; j < GPIO_NUM_PAD_CFG_REGS; j++) {
+ pad_conf = pcr_read32(comm[comm_index].port,
+ config_offset + j * sizeof(uint32_t));
+ pad_conf &= ~gpio[i].pad_config_mask[j];
+ gpio[i].cfg.pad_config[j] =
+ (gpio[i].cfg.pad_config[j] & gpio[i].pad_config_mask[j]) |
+ pad_conf;
+ }
+
+ /**
+ * Set the fourth bit for host software ownership.
+ */
+ switch (gpio[i].hostsw_own) {
+ case GPIO_HOSTSW_OWN_ACPI:
+ gpio[i].cfg.pad_config[1] |= PAD_CFG_OWN_GPIO(ACPI);
+ break;
+ case GPIO_HOSTSW_OWN_DRIVER:
+ gpio[i].cfg.pad_config[1] |= PAD_CFG_OWN_GPIO(DRIVER);
+ break;
+ default:
+ gpio[i].cfg.pad_config[1] |=
+ gpio_get_snr_pad_hostsw_own(gpio[i].cfg.pad) << 4;
+ break;
+ }
+
+ gpio_configure_pads(&gpio[i].cfg, 1);
+ }
+
+ /**
+ * Clear pad interrupt status at group level.
+ */
+ for (i = 0; i < num; i++) {
+ comm_index = SNR_GPIO_COMMUNITY(gpio[i].cfg.pad);
+ group_index = SNR_GPIO_GROUP(gpio[i].cfg.pad);
+ bit_mask = 1 << (SNR_GPIO_PAD(gpio[i].cfg.pad) % GPIO_MAX_NUM_PER_GROUP);
+ gpio_clear_snr_pad_group_interrupt_status(&comm[comm_index], group_index,
+ bit_mask);
+ }
+}
diff --git a/src/soc/intel/snowridge/romstage/romstage.c b/src/soc/intel/snowridge/romstage/romstage.c
new file mode 100644
index 0000000000..d615da6e92
--- /dev/null
+++ b/src/soc/intel/snowridge/romstage/romstage.c
@@ -0,0 +1,186 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/romstage.h>
+#include <cbmem.h>
+#include <console/console.h>
+#include <device/dram/common.h>
+#include <device/dram/ddr4.h>
+#include <device/pci_def.h>
+#include <device/pci_ops.h>
+#include <fsp/api.h>
+#include <fsp/soc_binding.h>
+#include <fsp/util.h>
+#include <intelblocks/imc.h>
+#include <intelblocks/meminit.h>
+#include <intelblocks/p2sblib.h>
+#include <intelblocks/rtc.h>
+#include <lib.h>
+#include <romstage.h>
+#include <soc/intel/common/smbios.h>
+#include <soc/pci_devs.h>
+#include <spd.h>
+#include <spd_bin.h>
+#include <string.h>
+
+#include "../common/fsp_hob.h"
+#include "../common/kti_cache.h"
+
+#define SPD_DIMM_ADDR(ch, dimm) ((ch) * CONFIG_DIMMS_PER_CHANNEL + (dimm))
+
+static void fsp_kti_cache_fill(FSPM_UPD *mupd)
+{
+ void *data;
+ size_t kti_size;
+
+ mupd->FspmConfig.PcdKtiBufferPtr = 0;
+
+ data = kti_cache_load(&kti_size);
+ if (data == NULL)
+ return;
+
+ mupd->FspmConfig.PcdKtiBufferPtr = (uint32_t)data;
+
+ printk(BIOS_SPEW, "KTI cache found, size %zx bytes\n", kti_size);
+ hexdump(data, kti_size);
+}
+
+static struct mem_channel_data mem_channel_data;
+
+static void fsp_mem_spd_fill(FSPM_UPD *mupd)
+{
+ const struct soc_mem_cfg soc_mem_cfg = {
+ .num_phys_channels = MRC_CHANNELS,
+ .phys_to_mrc_map = {0, 1},
+ };
+ const struct mem_spd spd_info = {
+ .topo = MEM_TOPO_DIMM_MODULE,
+ .smbus[0] = {.addr_dimm[0] = SPD_DIMM_ADDR(0, 0),
+ .addr_dimm[1] = SPD_DIMM_ADDR(0, 1)},
+ .smbus[1] = {.addr_dimm[0] = SPD_DIMM_ADDR(1, 0),
+ .addr_dimm[1] = SPD_DIMM_ADDR(1, 1)},
+ };
+
+ imc_spd_smbus_init(IMC_SPD_DEV);
+
+ mem_populate_channel_data(mupd, &soc_mem_cfg, &spd_info, false, &mem_channel_data);
+
+ printk(BIOS_SPEW, "SPD block length: 0x%zx\n", mem_channel_data.spd_len);
+
+ mupd->FspmConfig.PcdMemSpdPtr = (uintptr_t)mem_channel_data.spd[0][0];
+ printk(BIOS_SPEW, "PcdMemSpdPtr: 0x%08x\n", mupd->FspmConfig.PcdMemSpdPtr);
+
+ mupd->FspmConfig.PcdDdrFreq = 0;
+}
+
+static void soc_memory_init_params(FSPM_UPD *mupd)
+{
+ fsp_kti_cache_fill(mupd);
+ fsp_mem_spd_fill(mupd);
+
+ mupd->FspmConfig.PcdVtdSupport = CONFIG(ENABLE_VTD);
+
+ mupd->FspmConfig.PcdFiaMuxOverride = 1;
+ mupd->FspmConfig.FiaMuxCfgInvalidate = 0;
+}
+
+void platform_fsp_memory_init_params_cb(FSPM_UPD *mupd, uint32_t version)
+{
+ soc_memory_init_params(mupd);
+
+ mainboard_memory_init_params(mupd);
+}
+
+static uint8_t spd_ddr_type_to_smbios_memory_type(uint16_t spd_type)
+{
+ switch (spd_type) {
+ case SPD_MEMORY_TYPE_DDR4_SDRAM:
+ case SPD_MEMORY_TYPE_DDR4E_SDRAM:
+ return MEMORY_TYPE_DDR4;
+ case SPD_MEMORY_TYPE_LPDDR4_SDRAM:
+ return MEMORY_TYPE_LPDDR4;
+ default:
+ return MEMORY_TYPE_UNKNOWN;
+ }
+}
+
+static void smbios_memory_info_save(void)
+{
+ const FSP_SMBIOS_MEMORY_INFO *fsp_smbios_memory_info = fsp_hob_get_memory_info();
+ if (!fsp_smbios_memory_info) {
+ printk(BIOS_WARNING, "Couldn't find SMBIOS memory info hob!\n");
+ return;
+ }
+
+ struct memory_info *mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
+ if (!mem_info) {
+ printk(BIOS_ERR, "Add memory info to cbmem failed!\n");
+ return;
+ }
+
+ memset(mem_info, 0, sizeof(*mem_info));
+
+ assert(fsp_smbios_memory_info->ChannelCount <=
+ ARRAY_SIZE(fsp_smbios_memory_info->ChannelInfo));
+
+ uint8_t dimm_cnt = 0;
+ for (uint8_t channel = 0; channel < fsp_smbios_memory_info->ChannelCount &&
+ channel < ARRAY_SIZE(fsp_smbios_memory_info->ChannelInfo) &&
+ dimm_cnt < ARRAY_SIZE(mem_info->dimm);
+ channel++) {
+ const CHANNEL_INFO *channel_info =
+ &fsp_smbios_memory_info->ChannelInfo[channel];
+
+ assert(channel_info->DimmCount <= ARRAY_SIZE(channel_info->DimmInfo));
+
+ for (uint8_t dimm = 0; dimm < channel_info->DimmCount &&
+ dimm < ARRAY_SIZE(channel_info->DimmInfo) &&
+ dimm_cnt < ARRAY_SIZE(mem_info->dimm);
+ dimm++) {
+ const DIMM_INFO *fsp_dimm_info = &channel_info->DimmInfo[dimm];
+ struct dimm_info *dimm_info = &mem_info->dimm[dimm_cnt];
+
+ struct dimm_attr_ddr4_st dimm_attr;
+ enum spd_status status = spd_decode_ddr4(
+ &dimm_attr, (uint8_t *)mem_channel_data.spd[channel][dimm]);
+
+ printk(BIOS_INFO, "MemoryType from fsp hob: 0x%02x\n",
+ fsp_smbios_memory_info->MemoryType);
+
+ /* Populate the DIMM information */
+ dimm_info_fill(dimm_info, fsp_dimm_info->SizeInMb,
+ spd_ddr_type_to_smbios_memory_type(
+ fsp_smbios_memory_info->MemoryType),
+ fsp_smbios_memory_info->MemoryFrequencyInMHz,
+ status == SPD_STATUS_OK ? dimm_attr.ranks : 0,
+ channel_info->ChannelId, fsp_dimm_info->DimmId,
+ (const char *)fsp_dimm_info->ModulePartNum,
+ sizeof(fsp_dimm_info->ModulePartNum),
+ status == SPD_STATUS_OK ? dimm_attr.serial_number : NULL,
+ fsp_smbios_memory_info->DataWidth,
+ status == SPD_STATUS_OK ? dimm_attr.vdd_voltage : 1200,
+ fsp_smbios_memory_info->ErrorCorrectionType,
+ fsp_dimm_info->MfgId,
+ status == SPD_STATUS_OK ? dimm_attr.dimm_type : 0, 0, 0);
+
+ dimm_cnt++;
+ }
+ }
+
+ mem_info->dimm_cnt = dimm_cnt;
+ printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
+}
+
+/**
+ * @brief Intel SoCs place this function in `src/soc`.
+ */
+void mainboard_romstage_entry(void)
+{
+ p2sb_dev_enable_bar(PCH_DEV_P2SB, CONFIG_PCR_BASE_ADDRESS);
+ mainboard_config_gpios();
+
+ fsp_memory_init(false);
+
+ rtc_init();
+
+ smbios_memory_info_save();
+}
diff --git a/src/soc/intel/snowridge/sata.c b/src/soc/intel/snowridge/sata.c
new file mode 100644
index 0000000000..bdd881d996
--- /dev/null
+++ b/src/soc/intel/snowridge/sata.c
@@ -0,0 +1,51 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <console/console.h>
+#include <device/device.h>
+#include <device/mmio.h>
+#include <device/pci.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <soc/sata.h>
+
+static void sata_init(struct device *dev)
+{
+ uint32_t reg32, abar;
+
+ printk(BIOS_DEBUG, "Set SATA controller in AHCI mode.\n");
+
+ uint16_t reg16 = pci_read_config16(dev, SATA_MAP);
+ reg16 &= ~(3 << 6);
+ reg16 |= SATA_MAP_AHCI;
+ pci_write_config16(dev, SATA_MAP, reg16);
+
+ /* Initialize AHCI memory-mapped space */
+ abar = pci_read_config32(dev, SATA_ABAR);
+
+ /* Enable AHCI Mode */
+ reg32 = read32p(abar + SATA_GHC);
+ reg32 |= SATA_GHC_AE;
+ write32p(abar + SATA_GHC, reg32);
+}
+
+static struct device_operations snr_sata_ops = {
+ .read_resources = pci_dev_read_resources,
+ .set_resources = pci_dev_set_resources,
+ .enable_resources = pci_dev_enable_resources,
+ .init = sata_init,
+ .final = pci_dev_request_bus_master,
+ .ops_pci = &pci_dev_ops_pci,
+};
+
+static const unsigned short snr_sata_ids[] = {
+ PCI_DID_INTEL_SNR_SATA0,
+ PCI_DID_INTEL_SNR_SATA2,
+ 0,
+};
+
+static const struct pci_driver snr_sata_driver __pci_driver = {
+ .ops = &snr_sata_ops,
+ .vendor = PCI_VID_INTEL,
+ .devices = snr_sata_ids,
+};
diff --git a/src/soc/intel/snowridge/smihandler.c b/src/soc/intel/snowridge/smihandler.c
new file mode 100644
index 0000000000..96efa64090
--- /dev/null
+++ b/src/soc/intel/snowridge/smihandler.c
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <intelblocks/fast_spi.h>
+#include <intelblocks/smihandler.h>
+#include <soc/pm.h>
+
+void smihandler_soc_at_finalize(void)
+{
+ fast_spi_enable_wp();
+}
+
+const smi_handler_t southbridge_smi[SMI_STS_BITS] = {
+ [SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,
+ [APM_STS_BIT] = smihandler_southbridge_apmc,
+ [PM1_STS_BIT] = smihandler_southbridge_pm1,
+ [GPE0_STS_BIT] = smihandler_southbridge_gpe0,
+ [GPIO_STS_BIT] = smihandler_southbridge_gpi,
+ [ESPI_SMI_STS_BIT] = smihandler_southbridge_espi,
+ [MCSMI_STS_BIT] = smihandler_southbridge_mc,
+#if CONFIG(SOC_INTEL_COMMON_BLOCK_SMM_TCO_ENABLE)
+ [TCO_STS_BIT] = smihandler_southbridge_tco,
+#endif
+ [PERIODIC_STS_BIT] = smihandler_southbridge_periodic,
+ [MONITOR_STS_BIT] = smihandler_southbridge_monitor
+};
diff --git a/src/soc/intel/snowridge/sriov.c b/src/soc/intel/snowridge/sriov.c
new file mode 100644
index 0000000000..61f9c7c8b7
--- /dev/null
+++ b/src/soc/intel/snowridge/sriov.c
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <commonlib/bsd/helpers.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pci_def.h>
+#include <device/pciexp.h>
+#include <device/resource.h>
+#include <lib.h>
+
+#include "ramstage.h"
+
+void pciexp_vf_read_resources(struct device *dev)
+{
+ uint32_t sriov_cap_offset, supported_page_size, system_page_size;
+ uint16_t num_vfs, index;
+ int align;
+ struct resource *resource;
+
+ sriov_cap_offset = pciexp_find_extended_cap(dev, PCIE_EXT_CAP_SRIOV_ID, 0);
+ if (sriov_cap_offset == 0) {
+ printk(BIOS_DEBUG, "No SRIOV capability for %s!\n", dev_path(dev));
+ return;
+ }
+
+ printk(BIOS_DEBUG, "%s SRIOV capability found at offset 0x%x\n", dev_path(dev),
+ sriov_cap_offset);
+
+ supported_page_size = pci_read_config32(
+ dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SUPPORTED_PAGE_SIZE);
+ if (supported_page_size == 0) {
+ printk(BIOS_DEBUG, "No supported page size for %s!\n", dev_path(dev));
+ return;
+ }
+
+ system_page_size =
+ pci_read_config32(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_SYSTEM_PAGE_SIZE);
+ if ((system_page_size & supported_page_size) == 0) {
+ printk(BIOS_ERR, "Unsupportted system page size 0x%08x for %s!\n",
+ system_page_size, dev_path(dev));
+ return;
+ }
+
+ if (popcnt(system_page_size) != 1) {
+ printk(BIOS_ERR, "More than 1 bit is set in system page size for %s!\n",
+ dev_path(dev));
+ return;
+ }
+
+ num_vfs = pci_read_config16(dev, sriov_cap_offset + PCIE_EXT_CAP_SRIOV_TOTAL_VFS);
+
+ /**
+ * If bit `n` is set, the VFs are required to support a page size of 2 ^ (n + 12).
+ */
+ align = __ffs(system_page_size) + 12;
+
+ for (index = PCIE_EXT_CAP_SRIOV_VF_BAR0; index <= PCIE_EXT_CAP_SRIOV_VF_BAR5;
+ index += 4) {
+ resource = pci_get_resource(dev, sriov_cap_offset + index);
+ if (resource->flags == 0)
+ continue;
+
+ printk(BIOS_DEBUG, "%s SRIOV BAR at offset 0x%x\n", dev_path(dev),
+ sriov_cap_offset + index);
+
+ /**
+ * Section 9.3.3.13 of PCIe Base Specification 6.2.
+ */
+ resource->align = MAX(resource->align, align);
+ resource->gran = MAX(resource->gran, align);
+ resource->size = 1 << resource->gran;
+
+ resource->size *= num_vfs;
+
+ /**
+ * Allocate above 4G to avoid exhausting MMIO32 space.
+ */
+ if (resource->size >= 16 * MiB)
+ resource->flags |= IORESOURCE_ABOVE_4G;
+
+ printk(BIOS_DEBUG, "%s SRIOV BAR size 0x%llx, flags 0x%lx\n", dev_path(dev),
+ resource->size, resource->flags);
+
+ if (resource->flags & IORESOURCE_PCI64)
+ index += 4;
+ }
+}
+
+void pciexp_pf_read_resources(struct device *dev)
+{
+ uint16_t index;
+ struct resource *resource;
+
+ printk(BIOS_SPEW, "Reading resource: %s idx %02x\n", dev_path(dev), PCI_BASE_ADDRESS_0);
+
+ for (index = PCI_BASE_ADDRESS_0; index < PCI_BASE_ADDRESS_0 + (6 << 2);) {
+ resource = pci_get_resource(dev, index);
+ /**
+ * Allocate above 4G to avoid exhausting MMIO32 space.
+ */
+ if (resource->size >= 16 * MiB)
+ resource->flags |= IORESOURCE_ABOVE_4G;
+
+ index += (resource->flags & IORESOURCE_PCI64) ? 8 : 4;
+ }
+
+ pciexp_vf_read_resources(dev);
+
+ compact_resources(dev);
+}
diff --git a/src/soc/intel/snowridge/systemagent.c b/src/soc/intel/snowridge/systemagent.c
new file mode 100644
index 0000000000..2663dc0168
--- /dev/null
+++ b/src/soc/intel/snowridge/systemagent.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <arch/hpet.h>
+#include <arch/ioapic.h>
+#include <commonlib/bsd/helpers.h>
+#include <cpu/x86/lapic_def.h>
+#include <device/pci_ops.h>
+#include <intelblocks/systemagent_server.h>
+#include <soc/iomap.h>
+#include <soc/systemagent.h>
+#include <security/intel/txt/txt_register.h>
+
+static bool get_vtd_bar(struct device *dev, uint64_t *base, uint64_t *size)
+{
+ struct sa_server_mem_map_descriptor vtd_bar_descriptor = {
+ .reg_offset = VTBAR,
+ .is_64_bit = true,
+ .alignment = 4 * KiB, /* Bit(0) is VT-d enable bit. */
+ };
+
+ if (!(pci_read_config32(dev, VTBAR) & VTD_CHIPSET_BASE_ADDRESS_ENABLE))
+ return false;
+
+ *base = sa_server_read_map_entry(PCI_BDF(dev), &vtd_bar_descriptor);
+ *size = 4 * KiB;
+ return true;
+}
+
+static bool get_pcie_mmcfg_bar(struct device *dev, uint64_t *base, uint64_t *size)
+{
+ /* The PCIe MMCFG limit in registers is not correct thus using the configuration value here. */
+ *base = CONFIG_ECAM_MMCONF_BASE_ADDRESS;
+ *size = CONFIG_ECAM_MMCONF_LENGTH;
+ return true;
+}
+
+static bool get_dpr(struct device *dev, uint64_t *base, uint64_t *size)
+{
+ union dpr_register dpr = { .raw = pci_read_config32(dev, DPR) };
+ *size = dpr.size * MiB;
+ /* DPR base is read as 0s so it is calculated based on the assumption that DPR is below TSEG. */
+ *base = sa_server_get_tseg_base() - *size;
+ return true;
+}
+
+static bool get_tseg(struct device *dev, uint64_t *base, uint64_t *size)
+{
+ *base = sa_server_get_tseg_base();
+ *size = sa_server_get_tseg_size();
+ return true;
+}
+
+void sa_server_soc_add_fixed_mmio_resources(struct device *dev, int *resource_cnt)
+{
+ struct sa_server_mmio_descriptor vtd_descriptor = {
+ .get_resource = get_vtd_bar,
+ .description = "VT-d BAR",
+ };
+
+ sa_server_add_mmio_resources(dev, resource_cnt, &vtd_descriptor, 1);
+
+ if (!sa_server_is_on_pch_domain(dev))
+ return;
+
+ struct sa_server_mmio_descriptor mmio_descriptors[] = {
+ {
+ .get_resource = get_pcie_mmcfg_bar,
+ .description = "PCIe MMCFG BAR",
+ },
+ {
+ .get_resource = get_dpr,
+ .description = "DMA Protection Range",
+ },
+ {
+ .get_resource = get_tseg,
+ .description = "TSEG",
+ },
+ {
+ .base = RESERVED_BASE_ADDRESS,
+ .size = RESERVED_BASE_SIZE,
+ .description = "PCH Reserved",
+ },
+ {
+ .base = IO_APIC_ADDR,
+ .size = 1 * MiB,
+ .description = "I/O APIC",
+ },
+ {
+ .base = HPET_BASE_ADDRESS,
+ .size = 1 * MiB,
+ .description = "HPET/TXT/TPM",
+ },
+ {
+ .base = LAPIC_DEFAULT_BASE,
+ .size = 2 * MiB,
+ .description = "Local APIC",
+ },
+ };
+
+ sa_server_add_mmio_resources(dev, resource_cnt, mmio_descriptors,
+ ARRAY_SIZE(mmio_descriptors));
+}