summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/intel/baskingridge/romstage.c136
-rw-r--r--src/northbridge/intel/haswell/early_init.c22
-rw-r--r--src/northbridge/intel/haswell/raminit.c17
-rw-r--r--src/southbridge/intel/lynxpoint/Makefile.inc2
-rw-r--r--src/southbridge/intel/lynxpoint/early_pch.c172
-rw-r--r--src/southbridge/intel/lynxpoint/pch.h48
6 files changed, 256 insertions, 141 deletions
diff --git a/src/mainboard/intel/baskingridge/romstage.c b/src/mainboard/intel/baskingridge/romstage.c
index 2a8e910490..9561456ad7 100644
--- a/src/mainboard/intel/baskingridge/romstage.c
+++ b/src/mainboard/intel/baskingridge/romstage.c
@@ -33,7 +33,7 @@
#include "northbridge/intel/haswell/haswell.h"
#include "northbridge/intel/haswell/raminit.h"
#include "southbridge/intel/lynxpoint/pch.h"
-#include "southbridge/intel/lynxpoint/gpio.h"
+#include "southbridge/intel/lynxpoint/me.h"
#include <arch/cpu.h>
#include <cpu/x86/bist.h>
#include <cpu/x86/msr.h>
@@ -42,22 +42,7 @@
#include <vendorcode/google/chromeos/chromeos.h>
#endif
-static void pch_enable_lpc(void)
-{
- device_t dev = PCH_LPC_DEV;
-
- /* Set COM1/COM2 decode range */
- pci_write_config16(dev, LPC_IO_DEC, 0x0010);
-
- /* Enable SuperIO + COM1 + PS/2 Keyboard/Mouse */
- u16 lpc_config = CNF1_LPC_EN | CNF2_LPC_EN | COMA_LPC_EN | KBC_LPC_EN;
- pci_write_config16(dev, LPC_EN, lpc_config);
-}
-
-static void rcba_config(void)
-{
- u32 reg32;
-
+const struct rcba_config_instruction rcba_config[] = {
/*
* GFX INTA -> PIRQA (MSI)
* D28IP_P1IP WLAN INTA -> PIRQB
@@ -71,55 +56,42 @@ static void rcba_config(void)
*/
/* Device interrupt pin register (board specific) */
- RCBA32(D31IP) = (INTC << D31IP_TTIP) | (NOINT << D31IP_SIP2) |
- (INTB << D31IP_SMIP) | (INTA << D31IP_SIP);
- RCBA32(D30IP) = (NOINT << D30IP_PIP);
- RCBA32(D29IP) = (INTA << D29IP_E1P);
- RCBA32(D28IP) = (INTA << D28IP_P1IP) | (INTC << D28IP_P3IP) |
- (INTB << D28IP_P4IP);
- RCBA32(D27IP) = (INTA << D27IP_ZIP);
- RCBA32(D26IP) = (INTA << D26IP_E2P);
- RCBA32(D25IP) = (NOINT << D25IP_LIP);
- RCBA32(D22IP) = (NOINT << D22IP_MEI1IP);
+ RCBA_SET_REG_32(D31IP, (INTC << D31IP_TTIP) | (NOINT << D31IP_SIP2) |
+ (INTB << D31IP_SMIP) | (INTA << D31IP_SIP)),
+ RCBA_SET_REG_32(D30IP, (NOINT << D30IP_PIP)),
+ RCBA_SET_REG_32(D29IP, (INTA << D29IP_E1P)),
+ RCBA_SET_REG_32(D28IP, (INTA << D28IP_P1IP) | (INTC << D28IP_P3IP) |
+ (INTB << D28IP_P4IP)),
+ RCBA_SET_REG_32(D27IP, (INTA << D27IP_ZIP)),
+ RCBA_SET_REG_32(D26IP, (INTA << D26IP_E2P)),
+ RCBA_SET_REG_32(D25IP, (NOINT << D25IP_LIP)),
+ RCBA_SET_REG_32(D22IP, (NOINT << D22IP_MEI1IP)),
/* Device interrupt route registers */
- DIR_ROUTE(D31IR, PIRQF, PIRQG, PIRQH, PIRQA);
- DIR_ROUTE(D29IR, PIRQD, PIRQE, PIRQF, PIRQG);
- DIR_ROUTE(D28IR, PIRQB, PIRQC, PIRQD, PIRQE);
- DIR_ROUTE(D27IR, PIRQG, PIRQH, PIRQA, PIRQB);
- DIR_ROUTE(D26IR, PIRQE, PIRQF, PIRQG, PIRQH);
- DIR_ROUTE(D25IR, PIRQA, PIRQB, PIRQC, PIRQD);
- DIR_ROUTE(D22IR, PIRQA, PIRQB, PIRQC, PIRQD);
-
- /* Enable IOAPIC (generic) */
- RCBA16(OIC) = 0x0100;
- /* PCH BWG says to read back the IOAPIC enable register */
- (void) RCBA16(OIC);
+ RCBA_SET_REG_32(D31IR, DIR_ROUTE(PIRQF, PIRQG, PIRQH, PIRQA)),
+ RCBA_SET_REG_32(D29IR, DIR_ROUTE(PIRQD, PIRQE, PIRQF, PIRQG)),
+ RCBA_SET_REG_32(D28IR, DIR_ROUTE(PIRQB, PIRQC, PIRQD, PIRQE)),
+ RCBA_SET_REG_32(D27IR, DIR_ROUTE(PIRQG, PIRQH, PIRQA, PIRQB)),
+ RCBA_SET_REG_32(D26IR, DIR_ROUTE(PIRQE, PIRQF, PIRQG, PIRQH)),
+ RCBA_SET_REG_32(D25IR, DIR_ROUTE(PIRQA, PIRQB, PIRQC, PIRQD)),
+ RCBA_SET_REG_32(D22IR, DIR_ROUTE(PIRQA, PIRQB, PIRQC, PIRQD)),
/* Disable unused devices (board specific) */
- reg32 = RCBA32(FD);
- reg32 |= PCH_DISABLE_ALWAYS;
- RCBA32(FD) = reg32;
-}
+ RCBA_RMW_REG_32(FD, ~0, PCH_DISABLE_ALWAYS),
-// FIXME, this function is generic code that should go to sb/... or
-// nb/../early_init.c
-static void early_pch_init(void)
-{
- u8 reg8;
+ /* Enable IOAPIC (generic) */
+ RCBA_SET_REG_16(OIC, 0x0100),
+ /* PCH BWG says to read back the IOAPIC enable register */
+ RCBA_READ_REG_16(OIC),
- // reset rtc power status
- reg8 = pci_read_config8(PCH_LPC_DEV, 0xa4);
- reg8 &= ~(1 << 2);
- pci_write_config8(PCH_LPC_DEV, 0xa4, reg8);
-}
+ RCBA_END_CONFIG,
+};
void main(unsigned long bist)
{
int boot_mode = 0;
+ int wake_from_s3;
int cbmem_was_initted;
- u32 pm1_cnt;
- u16 pm1_sts;
#if CONFIG_COLLECT_TIMESTAMPS
tsc_t start_romstage_time;
@@ -180,64 +152,26 @@ void main(unsigned long bist)
if (bist == 0)
enable_lapic();
- pch_enable_lpc();
-
- /* Enable GPIOs */
- pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1);
- pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
- setup_pch_gpios(&mainboard_gpio_map);
-
- /* Early Console setup */
- console_init();
+ wake_from_s3 = early_pch_init(&mainboard_gpio_map, &rcba_config[0]);
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
- /*
- * FIXME: MCHBAR isn't setup yet. It's setup in
- * haswell_early_initialization().
- */
- if (MCHBAR16(SSKPD) == 0xCAFE) {
- printk(BIOS_DEBUG, "soft reset detected\n");
- boot_mode = 1;
-
- /* System is not happy after keyboard reset... */
- printk(BIOS_DEBUG, "Issuing CF9 warm reset\n");
- outb(0x6, 0xcf9);
- while (1) {
- hlt();
- }
- }
-
/* Perform some early chipset initialization required
* before RAM initialization can work
*/
haswell_early_initialization(HASWELL_MOBILE);
printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n");
- /* Check PM1_STS[15] to see if we are waking from Sx */
- pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
-
- /* Read PM1_CNT[12:10] to determine which Sx state */
- pm1_cnt = inl(DEFAULT_PMBASE + PM1_CNT);
-
- if ((pm1_sts & WAK_STS) && ((pm1_cnt >> 10) & 7) == 5) {
+ if (wake_from_s3) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Resume from S3 detected.\n");
boot_mode = 2;
- /* Clear SLP_TYPE. This will break stage2 but
- * we care for that when we get there.
- */
- outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + PM1_CNT);
#else
printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n");
#endif
}
- post_code(0x38);
- /* Enable SPD ROMs and DDR-III DRAM */
- enable_smbus();
-
/* Prepare USB controller early in S3 resume */
if (boot_mode == 2)
enable_usb_bar();
@@ -247,21 +181,17 @@ void main(unsigned long bist)
#if CONFIG_COLLECT_TIMESTAMPS
before_dram_time = rdtsc();
#endif
+
+ report_platform_info();
+
sdram_initialize(&pei_data);
#if CONFIG_COLLECT_TIMESTAMPS
after_dram_time = rdtsc();
#endif
post_code(0x3b);
- /* Perform some initialization that must run before stage2 */
- early_pch_init();
- post_code(0x3c);
- /* This should probably go away. Until now it is required
- * and mainboard specific
- */
- rcba_config();
- post_code(0x3d);
+ intel_early_me_status();
quick_ram_check();
post_code(0x3e);
diff --git a/src/northbridge/intel/haswell/early_init.c b/src/northbridge/intel/haswell/early_init.c
index 505fbf1125..681af42adb 100644
--- a/src/northbridge/intel/haswell/early_init.c
+++ b/src/northbridge/intel/haswell/early_init.c
@@ -29,20 +29,6 @@
static void haswell_setup_bars(void)
{
- /* Setting up Southbridge. In the northbridge code. */
- printk(BIOS_DEBUG, "Setting up static southbridge registers...");
- pci_write_config32(PCI_DEV(0, 0x1f, 0), RCBA, DEFAULT_RCBA | 1);
-
- pci_write_config32(PCI_DEV(0, 0x1f, 0), PMBASE, DEFAULT_PMBASE | 1);
- pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44 /* ACPI_CNTL */ , 0x80); /* Enable ACPI BAR */
-
- printk(BIOS_DEBUG, " done.\n");
-
- printk(BIOS_DEBUG, "Disabling Watchdog reboot...");
- RCBA32(GCS) = RCBA32(GCS) | (1 << 5); /* No reset */
- outw((1 << 11), DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */
- printk(BIOS_DEBUG, " done.\n");
-
printk(BIOS_DEBUG, "Setting up static northbridge registers...");
/* Set up all hardcoded northbridge BARs */
pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR, DEFAULT_EPBAR | 1);
@@ -62,14 +48,6 @@ static void haswell_setup_bars(void)
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33);
printk(BIOS_DEBUG, " done.\n");
-
-#if CONFIG_ELOG_BOOT_COUNT
- /* Increment Boot Counter except when resuming from S3 */
- if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
- ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3)
- return;
- boot_count_increment();
-#endif
}
static void haswell_setup_graphics(void)
diff --git a/src/northbridge/intel/haswell/raminit.c b/src/northbridge/intel/haswell/raminit.c
index 0c68e60707..e2b085b3fd 100644
--- a/src/northbridge/intel/haswell/raminit.c
+++ b/src/northbridge/intel/haswell/raminit.c
@@ -32,8 +32,6 @@
#include "pei_data.h"
#include "haswell.h"
-/* Management Engine is in the southbridge */
-#include "southbridge/intel/lynxpoint/me.h"
#if CONFIG_CHROMEOS
#include <vendorcode/google/chromeos/chromeos.h>
#else
@@ -152,12 +150,6 @@ void sdram_initialize(struct pei_data *pei_data)
struct sys_info sysinfo;
unsigned long entry;
- report_platform_info();
-
- /* Wait for ME to be ready */
- intel_early_me_init();
- intel_early_me_uma_size();
-
printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n");
memset(&sysinfo, 0, sizeof(sysinfo));
@@ -216,8 +208,6 @@ void sdram_initialize(struct pei_data *pei_data)
version >> 24 , (version >> 16) & 0xff,
(version >> 8) & 0xff, version & 0xff);
- intel_early_me_status();
-
report_memory_config();
/* S3 resume: don't save scrambler seed or MRC data */
@@ -232,7 +222,10 @@ struct cbmem_entry *get_cbmem_toc(void)
unsigned long get_top_of_ram(void)
{
- /* Base of TSEG is top of usable DRAM */
+ /*
+ * Base of TSEG is top of usable DRAM below 4GiB. The register has
+ * 1 MiB alignement.
+ */
u32 tom = pci_read_config32(PCI_DEV(0,0,0), TSEG);
- return (unsigned long) tom;
+ return (unsigned long) tom & ~((1 << 20) - 1);
}
diff --git a/src/southbridge/intel/lynxpoint/Makefile.inc b/src/southbridge/intel/lynxpoint/Makefile.inc
index c14a53881d..6e84ce61a8 100644
--- a/src/southbridge/intel/lynxpoint/Makefile.inc
+++ b/src/southbridge/intel/lynxpoint/Makefile.inc
@@ -45,7 +45,7 @@ smm-$(CONFIG_SPI_FLASH_SMM) += spi.c
ramstage-$(CONFIG_HAVE_SMI_HANDLER) += smi.c
smm-$(CONFIG_HAVE_SMI_HANDLER) += smihandler.c me_9.x.c finalize.c
-romstage-y += early_usb.c early_smbus.c early_me.c me_status.c
+romstage-y += early_usb.c early_smbus.c early_me.c me_status.c early_pch.c
romstage-$(CONFIG_USBDEBUG) += usb_debug.c
romstage-y += reset.c early_spi.c
diff --git a/src/southbridge/intel/lynxpoint/early_pch.c b/src/southbridge/intel/lynxpoint/early_pch.c
new file mode 100644
index 0000000000..d0a583fa1b
--- /dev/null
+++ b/src/southbridge/intel/lynxpoint/early_pch.c
@@ -0,0 +1,172 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2012 Google Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+
+#include <console/console.h>
+#include <arch/io.h>
+#include <arch/romcc_io.h>
+#include <device/pci_def.h>
+#include <elog.h>
+#include "pch.h"
+
+#if CONFIG_INTEL_LYNXPOINT_LP
+#include "lp_gpio.h"
+#else
+#include "gpio.h"
+#endif
+
+static void pch_enable_bars(void)
+{
+ /* Setting up Southbridge. In the northbridge code. */
+ pci_write_config32(PCH_LPC_DEV, RCBA, DEFAULT_RCBA | 1);
+
+ pci_write_config32(PCH_LPC_DEV, PMBASE, DEFAULT_PMBASE | 1);
+ /* Enable ACPI BAR */
+ pci_write_config8(PCH_LPC_DEV, ACPI_CNTL, 0x80);
+
+ pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE|1);
+
+ /* Enable GPIO functionality. */
+ pci_write_config8(PCH_LPC_DEV, GPIO_CNTL, 0x10);
+}
+
+static void pch_generic_setup(void)
+{
+ u8 reg8;
+
+ printk(BIOS_DEBUG, "Disabling Watchdog reboot...");
+ RCBA32(GCS) = RCBA32(GCS) | (1 << 5); /* No reset */
+ outw((1 << 11), DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */
+ printk(BIOS_DEBUG, " done.\n");
+
+ // reset rtc power status
+ reg8 = pci_read_config8(PCH_LPC_DEV, GEN_PMCON_3);
+ reg8 &= ~(1 << 2);
+ pci_write_config8(PCH_LPC_DEV, GEN_PMCON_3, reg8);
+}
+
+static int sleep_type_s3(void)
+{
+ u32 pm1_cnt;
+ u16 pm1_sts;
+ int is_s3 = 0;
+
+ /* Check PM1_STS[15] to see if we are waking from Sx */
+ pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
+ if (pm1_sts & WAK_STS) {
+ /* Read PM1_CNT[12:10] to determine which Sx state */
+ pm1_cnt = inl(DEFAULT_PMBASE + PM1_CNT);
+ if (((pm1_cnt >> 10) & 7) == SLP_TYP_S3) {
+ /* Clear SLP_TYPE. */
+ outl(pm1_cnt & ~(7 << 10), DEFAULT_PMBASE + PM1_CNT);
+ is_s3 = 1;
+ }
+ }
+ return is_s3;
+}
+
+static void pch_enable_lpc(void)
+{
+ device_t dev = PCH_LPC_DEV;
+
+ /* Set COM1/COM2 decode range */
+ pci_write_config16(dev, LPC_IO_DEC, 0x0010);
+
+ /* Enable SuperIO + COM1 + PS/2 Keyboard/Mouse */
+ u16 lpc_config = CNF1_LPC_EN | CNF2_LPC_EN | COMA_LPC_EN | KBC_LPC_EN;
+ pci_write_config16(dev, LPC_EN, lpc_config);
+}
+
+static void pch_config_rcba(const struct rcba_config_instruction *rcba_config)
+{
+ const struct rcba_config_instruction *rc;
+ u32 value;
+
+ rc = rcba_config;
+ while (rc->command != RCBA_COMMAND_END)
+ {
+ if ((rc->command & RCBA_REG_SIZE_MASK) == RCBA_REG_SIZE_16) {
+ switch (rc->command & RCBA_COMMAND_MASK) {
+ case RCBA_COMMAND_SET:
+ RCBA16(rc->reg) = (u16)rc->or_value;
+ break;
+ case RCBA_COMMAND_READ:
+ (void)RCBA16(rc->reg);
+ break;
+ case RCBA_COMMAND_RMW:
+ value = RCBA16(rc->reg);
+ value &= rc->mask;
+ value |= rc->or_value;
+ RCBA16(rc->reg) = (u16)value;
+ break;
+ }
+ } else {
+ switch (rc->command & RCBA_COMMAND_MASK) {
+ case RCBA_COMMAND_SET:
+ RCBA32(rc->reg) = rc->or_value;
+ break;
+ case RCBA_COMMAND_READ:
+ (void)RCBA32(rc->reg);
+ break;
+ case RCBA_COMMAND_RMW:
+ value = RCBA32(rc->reg);
+ value &= rc->mask;
+ value |= rc->or_value;
+ RCBA32(rc->reg) = value;
+ break;
+ }
+ }
+ rc++;
+ }
+}
+
+int early_pch_init(const void *gpio_map,
+ const struct rcba_config_instruction *rcba_config)
+{
+ int wake_from_s3;
+
+ pch_enable_lpc();
+
+ pch_enable_bars();
+
+#if CONFIG_INTEL_LYNXPOINT_LP
+ setup_pch_lp_gpios(gpio_map);
+#else
+ setup_pch_gpios(gpio_map);
+#endif
+
+ console_init();
+
+ pch_generic_setup();
+
+ /* Enable SMBus for reading SPDs. */
+ enable_smbus();
+
+ pch_config_rcba(rcba_config);
+
+ wake_from_s3 = sleep_type_s3();
+
+#if CONFIG_ELOG_BOOT_COUNT
+ if (!wake_from_s3)
+ boot_count_increment();
+#endif
+
+ /* Report if we are waking from s3. */
+ return wake_from_s3;
+}
diff --git a/src/southbridge/intel/lynxpoint/pch.h b/src/southbridge/intel/lynxpoint/pch.h
index f265448a6a..f27ae90eab 100644
--- a/src/southbridge/intel/lynxpoint/pch.h
+++ b/src/southbridge/intel/lynxpoint/pch.h
@@ -102,6 +102,48 @@ void enable_smbus(void);
void enable_usb_bar(void);
int smbus_read_byte(unsigned device, unsigned address);
int early_spi_read(u32 offset, u32 size, u8 *buffer);
+
+/* State Machine configuration. */
+#define RCBA_REG_SIZE_MASK 0x8000
+#define RCBA_REG_SIZE_16 0x8000
+#define RCBA_REG_SIZE_32 0x0000
+#define RCBA_COMMAND_MASK 0x000f
+#define RCBA_COMMAND_SET 0x0001
+#define RCBA_COMMAND_READ 0x0002
+#define RCBA_COMMAND_RMW 0x0003
+#define RCBA_COMMAND_END 0x0007
+
+#define RCBA_ENCODE_COMMAND(command_, reg_, mask_, or_value_) \
+ { .command = command_, \
+ .reg = reg_, \
+ .mask = mask_, \
+ .or_value = or_value_ \
+ }
+#define RCBA_SET_REG_32(reg_, value_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_32|RCBA_COMMAND_SET, reg_, 0, value_)
+#define RCBA_READ_REG_32(reg_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_32|RCBA_COMMAND_READ, reg_, 0, 0)
+#define RCBA_RMW_REG_32(reg_, mask_, or_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_32|RCBA_COMMAND_RMW, reg_, mask_, or_)
+#define RCBA_SET_REG_16(reg_, value_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_16|RCBA_COMMAND_SET, reg_, 0, value_)
+#define RCBA_READ_REG_16(reg_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_16|RCBA_COMMAND_READ, reg_, 0, 0)
+#define RCBA_RMW_REG_16(reg_, mask_, or_) \
+ RCBA_ENCODE_COMMAND(RCBA_REG_SIZE_16|RCBA_COMMAND_RMW, reg_, mask_, or_)
+#define RCBA_END_CONFIG \
+ RCBA_ENCODE_COMMAND(RCBA_COMMAND_END, 0, 0, 0)
+
+struct rcba_config_instruction
+{
+ u16 command;
+ u16 reg;
+ u32 mask;
+ u32 or_value;
+};
+
+int early_pch_init(const void *gpio_map,
+ const struct rcba_config_instruction *rcba_config);
#endif
/*
* get GPIO pin value
@@ -460,9 +502,9 @@ unsigned get_gpios(const int *gpio_num_array);
#define SOFT_RESET_CTRL 0x38f4
#define SOFT_RESET_DATA 0x38f8
-#define DIR_ROUTE(x,a,b,c,d) \
- RCBA32(x) = (((d) << DIR_IDR) | ((c) << DIR_ICR) | \
- ((b) << DIR_IBR) | ((a) << DIR_IAR))
+#define DIR_ROUTE(a,b,c,d) \
+ (((d) << DIR_IDR) | ((c) << DIR_ICR) | \
+ ((b) << DIR_IBR) | ((a) << DIR_IAR))
#define RC 0x3400 /* 32bit */
#define HPTC 0x3404 /* 32bit */