soc/amd: commonize generation of the PIC/APIC mapping tables

Now that we have a common init_tables in all mainboards using AMD SoCs,
both the population of the fch_pic_routing and fch_apic_routing arrays
and the definition of those arrays can be moved to the common AMD SoC
code to not have the code duplicated in all mainboards.

BUG=b:182782749

Signed-off-by: Felix Held <felix-coreboot@felixheld.de>
Suggested-by: Kyösti Mälkki <kyosti.malkki@gmail.com>
Change-Id: I8c65eca258272f0ef7dec3ece6236f5d00954c66
Reviewed-on: https://review.coreboot.org/c/coreboot/+/68853
Reviewed-by: Fred Reitberger <reitbergerfred@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/mainboard/amd/bilby/mainboard.c b/src/mainboard/amd/bilby/mainboard.c
index ca85684..a751126 100644
--- a/src/mainboard/amd/bilby/mainboard.c
+++ b/src/mainboard/amd/bilby/mainboard.c
@@ -9,7 +9,6 @@
 #include <soc/southbridge.h>
 #include <soc/pci_devs.h>
 #include <soc/platform_descriptors.h>
-#include <string.h>
 #include <types.h>
 #include <commonlib/helpers.h>
 #include <soc/amd/picasso/chip.h>
@@ -20,17 +19,8 @@
 
 /* TODO: recheck IRQ tables */
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
-
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 static const struct fch_irq_routing fch_irq_map[] = {
 	{ PIRQ_A,	8,		16 },
 	{ PIRQ_B,	10,		17 },
@@ -56,41 +46,12 @@
 	{ PIRQ_MISC2,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void program_display_sel_gpios(void)
 {
 	int idx, port_type;
@@ -125,14 +86,6 @@
 		mainboard_program_emmc_gpios();
 }
 
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/birman/mainboard.c b/src/mainboard/amd/birman/mainboard.c
index 28c289d..6a7343f 100644
--- a/src/mainboard/amd/birman/mainboard.c
+++ b/src/mainboard/amd/birman/mainboard.c
@@ -2,25 +2,15 @@
 
 #include <amdblocks/amd_pci_util.h>
 #include <commonlib/helpers.h>
-#include <console/console.h>
 #include <device/device.h>
 #include <soc/acpi.h>
-#include <string.h>
 #include <types.h>
 #include "gpio.h"
 
 /* TODO: Update for birman */
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -61,54 +51,17 @@
 	{ PIRQ_HPET_H,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_init(void *chip_info)
 {
 	mainboard_program_gpios();
 }
 
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/chausie/mainboard.c b/src/mainboard/amd/chausie/mainboard.c
index 9515f24..17c9d78 100644
--- a/src/mainboard/amd/chausie/mainboard.c
+++ b/src/mainboard/amd/chausie/mainboard.c
@@ -2,23 +2,13 @@
 
 #include <amdblocks/amd_pci_util.h>
 #include <commonlib/helpers.h>
-#include <console/console.h>
 #include <device/device.h>
 #include <soc/acpi.h>
-#include <string.h>
 #include <types.h>
 #include "gpio.h"
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -59,54 +49,17 @@
 	{ PIRQ_HPET_H,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_init(void *chip_info)
 {
 	mainboard_program_gpios();
 }
 
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/gardenia/mainboard.c b/src/mainboard/amd/gardenia/mainboard.c
index 0bbb208..ad95617 100644
--- a/src/mainboard/amd/gardenia/mainboard.c
+++ b/src/mainboard/amd/gardenia/mainboard.c
@@ -3,24 +3,13 @@
 #include <device/device.h>
 #include <amdblocks/agesawrapper.h>
 #include <amdblocks/amd_pci_util.h>
-#include <console/console.h>
 #include <soc/gpio.h>
 #include <soc/southbridge.h>
-#include <string.h>
 
 #include "gpio.h"
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
-
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 static const struct fch_irq_routing fch_irq_map[] = {
 	{ PIRQ_A,	 3,		16 },
 	{ PIRQ_B,	 4,		17 },
@@ -53,42 +42,12 @@
 	{ PIRQ_MISC2,	0x00,	0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-/* PIRQ Setup */
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_init(void *chip_info)
 {
 	size_t num_gpios;
@@ -97,17 +56,6 @@
 	gpio_configure_pads(gpios, num_gpios);
 }
 
-/*************************************************
- * enable the dedicated function in gardenia board.
- *************************************************/
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/majolica/mainboard.c b/src/mainboard/amd/majolica/mainboard.c
index a5e2935..9dbd4e4 100644
--- a/src/mainboard/amd/majolica/mainboard.c
+++ b/src/mainboard/amd/majolica/mainboard.c
@@ -2,22 +2,12 @@
 
 #include <amdblocks/amd_pci_util.h>
 #include <commonlib/helpers.h>
-#include <console/console.h>
 #include <device/device.h>
 #include <soc/acpi.h>
-#include <string.h>
 #include <types.h>
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -59,53 +49,16 @@
 	{ PIRQ_HPET_H,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_init(void *chip_info)
 {
 }
 
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/mandolin/mainboard.c b/src/mainboard/amd/mandolin/mainboard.c
index 397179a..6a27514 100644
--- a/src/mainboard/amd/mandolin/mainboard.c
+++ b/src/mainboard/amd/mandolin/mainboard.c
@@ -7,7 +7,6 @@
 #include <soc/cpu.h>
 #include <soc/southbridge.h>
 #include <soc/pci_devs.h>
-#include <string.h>
 #include <types.h>
 #include <commonlib/helpers.h>
 #include <soc/amd/picasso/chip.h>
@@ -15,17 +14,8 @@
 
 /* TODO: recheck IRQ tables */
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
-
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 static const struct fch_irq_routing fch_irq_map[] = {
 	{ PIRQ_A,	8,		16 },
 	{ PIRQ_B,	10,		17 },
@@ -51,41 +41,12 @@
 	{ PIRQ_MISC2,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_init(void *chip_info)
 {
 	struct soc_amd_picasso_config *cfg = config_of_soc();
@@ -102,14 +63,6 @@
 		mainboard_program_emmc_gpios();
 }
 
-static void mainboard_enable(struct device *dev)
-{
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-}
-
 struct chip_operations mainboard_ops = {
 	.init = mainboard_init,
-	.enable_dev = mainboard_enable,
 };
diff --git a/src/mainboard/amd/pademelon/mainboard.c b/src/mainboard/amd/pademelon/mainboard.c
index 9c55808..12f0443 100644
--- a/src/mainboard/amd/pademelon/mainboard.c
+++ b/src/mainboard/amd/pademelon/mainboard.c
@@ -3,25 +3,14 @@
 #include <device/device.h>
 #include <amdblocks/agesawrapper.h>
 #include <amdblocks/amd_pci_util.h>
-#include <console/console.h>
 #include <soc/gpio.h>
 #include <soc/pci_devs.h>
 #include <soc/southbridge.h>
-#include <string.h>
 
 #include "gpio.h"
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
-
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 static const struct fch_irq_routing fch_irq_map[] = {
 	{ PIRQ_A,	 3,		16 },
 	{ PIRQ_B,	 4,		17 },
@@ -54,35 +43,12 @@
 	{ PIRQ_MISC2,	0x00,	0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
 /*
  * This table defines the index into the picr/intr_data tables for each
  * device.  Any enabled device and slot that uses hardware interrupts should
@@ -113,8 +79,6 @@
 {
 	pirq_data_ptr = mainboard_pirq_data;
 	pirq_data_size = ARRAY_SIZE(mainboard_pirq_data);
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
 }
 
 static void mainboard_init(void *chip_info)
@@ -130,7 +94,6 @@
  *************************************************/
 static void mainboard_enable(struct device *dev)
 {
-	init_tables();
 	/* Initialize the PIRQ data structures for consumption */
 	pirq_setup();
 }
diff --git a/src/mainboard/google/guybrush/mainboard.c b/src/mainboard/google/guybrush/mainboard.c
index 8deb2ac..a7eab08 100644
--- a/src/mainboard/google/guybrush/mainboard.c
+++ b/src/mainboard/google/guybrush/mainboard.c
@@ -12,7 +12,6 @@
 #include <gpio.h>
 #include <soc/acpi.h>
 #include <variant/ec.h>
-#include <string.h>
 
 #define BACKLIGHT_GPIO			GPIO_129
 #define WWAN_AUX_RST_GPIO		GPIO_18
@@ -23,16 +22,8 @@
 #define METHOD_MAINBOARD_PTS		"\\_SB.MPTS"
 #define METHOD_MAINBOARD_S0X		"\\_SB.MS0X"
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -74,41 +65,12 @@
 	{ PIRQ_HPET_H,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_configure_gpios(void)
 {
 	size_t base_num_gpios, override_num_gpios;
@@ -219,10 +181,6 @@
 
 	dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
 
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-
 	/* TODO: b/184678786 - Move into espi_config */
 	/* Unmask eSPI IRQ 1 (Keyboard) */
 	pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1)));
diff --git a/src/mainboard/google/kahlee/mainboard.c b/src/mainboard/google/kahlee/mainboard.c
index 3433f8b..9cbfd4b 100644
--- a/src/mainboard/google/kahlee/mainboard.c
+++ b/src/mainboard/google/kahlee/mainboard.c
@@ -18,17 +18,8 @@
 #include <variant/ec.h>
 #include <variant/thermal.h>
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
-
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 static const struct fch_irq_routing fch_irq_map[] = {
 	{ PIRQ_A,	 3,		16 },
 	{ PIRQ_B,	 4,		17 },
@@ -61,35 +52,12 @@
 	{ PIRQ_MISC2,	0x00,	0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
 /*
  * This table defines the index into the picr/intr_data tables for each
  * device.  Any enabled device and slot that uses hardware interrupts should
@@ -117,8 +85,6 @@
 {
 	pirq_data_ptr = mainboard_pirq_data;
 	pirq_data_size = ARRAY_SIZE(mainboard_pirq_data);
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
 }
 
 void __weak variant_devtree_update(void)
@@ -165,7 +131,6 @@
  *************************************************/
 static void mainboard_enable(struct device *dev)
 {
-	init_tables();
 	/* Initialize the PIRQ data structures for consumption */
 	pirq_setup();
 
diff --git a/src/mainboard/google/skyrim/mainboard.c b/src/mainboard/google/skyrim/mainboard.c
index ca3c9aa..7708488 100644
--- a/src/mainboard/google/skyrim/mainboard.c
+++ b/src/mainboard/google/skyrim/mainboard.c
@@ -6,19 +6,10 @@
 #include <console/console.h>
 #include <device/device.h>
 #include <soc/acpi.h>
-#include <string.h>
 #include <variant/ec.h>
 
-/*
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -60,41 +51,12 @@
 	{ PIRQ_HPET_H,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_configure_gpios(void)
 {
 	size_t base_num_gpios, override_num_gpios;
@@ -117,10 +79,6 @@
 {
 	printk(BIOS_INFO, "Mainboard " CONFIG_MAINBOARD_PART_NUMBER " Enable.\n");
 
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-
 	/* TODO: b/184678786 - Move into espi_config */
 	/* Unmask eSPI IRQ 1 (Keyboard) */
 	pm_write32(PM_ESPI_INTR_CTRL, PM_ESPI_DEV_INTR_MASK & ~(BIT(1)));
diff --git a/src/mainboard/google/zork/mainboard.c b/src/mainboard/google/zork/mainboard.c
index aaa2548..90c74d7 100644
--- a/src/mainboard/google/zork/mainboard.c
+++ b/src/mainboard/google/zork/mainboard.c
@@ -1,6 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-or-later */
 
-#include <string.h>
 #include <console/console.h>
 #include <device/device.h>
 #include <device/mmio.h>
@@ -31,16 +30,8 @@
 #define METHOD_MAINBOARD_WAK       "\\_SB.MWAK"
 #define METHOD_MAINBOARD_PTS       "\\_SB.MPTS"
 
-/***********************************************************
- * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
- * This table is responsible for physically routing the PIC and
- * IOAPIC IRQs to the different PCI devices on the system.  It
- * is read and written via registers 0xC00/0xC01 as an
- * Index/Data pair.  These values are chipset and mainboard
- * dependent and should be updated accordingly.
- */
-static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
-static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
+/* The IRQ mapping in fch_irq_map ends up getting written to the indirect address space that is
+   accessed via I/O ports 0xc00/0xc01. */
 
 /*
  * This controls the device -> IRQ routing.
@@ -78,42 +69,12 @@
 	{ PIRQ_MISC2,	0x00,		0x00 },
 };
 
-static const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length)
 {
 	*length = ARRAY_SIZE(fch_irq_map);
 	return fch_irq_map;
 }
 
-static void init_tables(void)
-{
-	const struct fch_irq_routing *mb_irq_map;
-	size_t mb_fch_irq_mapping_table_size;
-	size_t i;
-
-	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
-
-	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
-	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
-
-	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
-		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
-			printk(BIOS_WARNING,
-			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
-			       mb_irq_map[i].intr_index, i);
-			continue;
-		}
-		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
-		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
-	}
-}
-
-/* PIRQ Setup */
-static void pirq_setup(void)
-{
-	intr_data_ptr = fch_apic_routing;
-	picr_data_ptr = fch_pic_routing;
-}
-
 static void mainboard_configure_gpios(void)
 {
 	size_t base_num_gpios, override_num_gpios;
@@ -205,12 +166,7 @@
  *************************************************/
 static void mainboard_enable(struct device *dev)
 {
-	init_tables();
-	/* Initialize the PIRQ data structures for consumption */
-	pirq_setup();
-
 	dev->ops->acpi_fill_ssdt = mainboard_fill_ssdt;
-
 }
 
 static void mainboard_final(void *chip_info)
diff --git a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h
index c766d50..f862bf9 100644
--- a/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h
+++ b/src/soc/amd/common/block/include/amdblocks/amd_pci_util.h
@@ -19,6 +19,8 @@
 	uint8_t apic_irq_num;
 };
 
+const struct fch_irq_routing *mb_get_fch_irq_mapping(size_t *length);
+
 struct pirq_struct {
 	u8 devfn;
 	u8 PIN[4];	/* PINA/B/C/D are index 0/1/2/3 */
@@ -31,8 +33,6 @@
 
 extern const struct pirq_struct *pirq_data_ptr;
 extern u32 pirq_data_size;
-extern const u8 *intr_data_ptr;
-extern const u8 *picr_data_ptr;
 
 u8 read_pci_int_idx(u8 index, int mode);
 void write_pci_int_idx(u8 index, int mode, u8 data);
diff --git a/src/soc/amd/common/block/pci/amd_pci_util.c b/src/soc/amd/common/block/pci/amd_pci_util.c
index d665a81..ecc0498 100644
--- a/src/soc/amd/common/block/pci/amd_pci_util.c
+++ b/src/soc/amd/common/block/pci/amd_pci_util.c
@@ -7,11 +7,21 @@
 #include <amdblocks/amd_pci_util.h>
 #include <pc80/i8259.h>
 #include <soc/amd_pci_int_defs.h>
+#include <string.h>
+
+/*
+ * These arrays set up the FCH PCI_INTR registers 0xC00/0xC01.
+ * This table is responsible for physically routing the PIC and
+ * IOAPIC IRQs to the different PCI devices on the system.  It
+ * is read and written via registers 0xC00/0xC01 as an
+ * Index/Data pair.  These values are chipset and mainboard
+ * dependent and should be updated accordingly.
+ */
+static uint8_t fch_pic_routing[FCH_IRQ_ROUTING_ENTRIES];
+static uint8_t fch_apic_routing[FCH_IRQ_ROUTING_ENTRIES];
 
 const struct pirq_struct *pirq_data_ptr;
 u32 pirq_data_size;
-const u8 *intr_data_ptr;
-const u8 *picr_data_ptr;
 
 /*
  * Read the FCH PCI_INTR registers 0xC00/0xC01 at a
@@ -33,6 +43,29 @@
 	outb(data, PCI_INTR_DATA);
 }
 
+static void init_fch_irq_map_tables(void)
+{
+	const struct fch_irq_routing *mb_irq_map;
+	size_t mb_fch_irq_mapping_table_size;
+	size_t i;
+
+	mb_irq_map = mb_get_fch_irq_mapping(&mb_fch_irq_mapping_table_size);
+
+	memset(fch_pic_routing, PIRQ_NC, sizeof(fch_pic_routing));
+	memset(fch_apic_routing, PIRQ_NC, sizeof(fch_apic_routing));
+
+	for (i = 0; i < mb_fch_irq_mapping_table_size; i++) {
+		if (mb_irq_map[i].intr_index >= FCH_IRQ_ROUTING_ENTRIES) {
+			printk(BIOS_WARNING,
+			       "Invalid IRQ index %u in FCH IRQ routing table entry %zu\n",
+			       mb_irq_map[i].intr_index, i);
+			continue;
+		}
+		fch_pic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].pic_irq_num;
+		fch_apic_routing[mb_irq_map[i].intr_index] = mb_irq_map[i].apic_irq_num;
+	}
+}
+
 /*
  * Write the FCH PCI_INTR registers 0xC00/0xC01 with values
  * given in global variables intr_data and picr_data.
@@ -44,13 +77,13 @@
 	size_t i, limit;
 	const struct irq_idx_name *idx_name;
 
+	init_fch_irq_map_tables();
+
 	idx_name = sb_get_apic_reg_association(&limit);
-	if (picr_data_ptr == NULL || intr_data_ptr == NULL ||
-	    idx_name == NULL) {
+	if (idx_name == NULL) {
 		printk(BIOS_ERR, "Warning: Can't write PCI_INTR 0xC00/0xC01"
 				" registers because\n"
-				"'mainboard_picr_data' or 'mainboard_intr_data'"
-				" or 'irq_association'\ntables are NULL\n");
+				" 'irq_association'\ntables is NULL\n");
 		return;
 	}
 
@@ -67,11 +100,11 @@
 	 */
 	for (i = 0 ; i < limit; i++) {
 		byte = idx_name[i].index;
-		write_pci_int_idx(byte, 0, (u8)picr_data_ptr[byte]);
+		write_pci_int_idx(byte, 0, fch_pic_routing[byte]);
 		printk(BIOS_DEBUG, "0x%02X\t\t%-20s 0x%02X\t",
 				byte, idx_name[i].name,
 				read_pci_int_idx(byte, 0));
-		write_pci_int_idx(byte, 1, (u8)intr_data_ptr[byte]);
+		write_pci_int_idx(byte, 1, fch_apic_routing[byte]);
 		printk(BIOS_DEBUG, "0x%02X\n", read_pci_int_idx(byte, 1));
 	}
 }