[coreboot] [FILO] r94 - trunk/filo/drivers
svn at coreboot.org
svn at coreboot.org
Wed Apr 29 21:22:07 CEST 2009
Author: stepan
Date: 2009-04-29 21:22:07 +0200 (Wed, 29 Apr 2009)
New Revision: 94
Modified:
trunk/filo/drivers/intel.c
Log:
fix poweroff command on intel platforms, and add bios flash locking example.
Modified: trunk/filo/drivers/intel.c
===================================================================
--- trunk/filo/drivers/intel.c 2009-04-29 19:19:55 UTC (rev 93)
+++ trunk/filo/drivers/intel.c 2009-04-29 19:22:07 UTC (rev 94)
@@ -24,27 +24,141 @@
#define DEBUG_THIS CONFIG_DEBUG_INTEL
#include <debug.h>
+#define DEFAULT_RCBA 0xfed1c000
+
+#define PM1_STS 0x00
+#define PWRBTN_STS (1 << 8)
+#define PM1_EN 0x02
+#define PM1_CNT 0x04
+#define SLP_EN (1 << 13)
+#define SLP_TYP (7 << 10)
+#define SLP_TYP_S0 (0 << 10)
+#define SLP_TYP_S1 (1 << 10)
+#define SLP_TYP_S3 (5 << 10)
+#define SLP_TYP_S4 (6 << 10)
+#define SLP_TYP_S5 (7 << 10)
+#define GPE0_EN 0x2c
+
+#define RCBA8(x) *((volatile u8 *)(DEFAULT_RCBA + x))
+#define RCBA16(x) *((volatile u16 *)(DEFAULT_RCBA + x))
+#define RCBA32(x) *((volatile u32 *)(DEFAULT_RCBA + x))
+
+
+void intel_lockdown_flash(void)
+{
+ u8 reg8;
+ u32 reg32;
+
+ reg32 = pci_read_config32(PCI_DEV(0,0x1f, 0), 0);
+ switch (reg32) {
+ case 0x27b08086:
+ case 0x27b88086:
+ case 0x27b98086:
+ case 0x27bd8086:
+ break;
+ default:
+ debug("Not an ICH7 southbridge\n");
+ return;
+ }
+
+ /* Now try this: */
+ debug("Locking BIOS to read-only... ");
+ reg8 = pci_read_config8(PCI_DEV(0,0x1f,0), 0xdc); /* BIOS_CNTL */
+ debug(" BIOS Lockdown Enable: %s; BIOS Write-Enable: %s\n",
+ (reg8&2)?"on":"off", (reg8&1)?"rw":"ro");
+
+ reg8 &= ~(1 << 0); /* clear BIOSWE */
+ pci_write_config8(PCI_DEV(0,0x1f,0), 0xdc, reg8);
+
+ reg8 |= (1 << 1); /* set BLE */
+ pci_write_config8(PCI_DEV(0,0x1f,0), 0xdc, reg8);
+
+ reg32 = RCBA32(0x3410); /* GCS - General Control and Status */
+ reg32 |= 1; /* BILD - BIOS Interface Lockdown */
+ RCBA32(0x3410) = reg32; /* Set BUC.TS and GCS.BBS to RO */
+
+ debug("BIOS hard locked until next full reset.\n");
+
+}
+
+
+/* We should add some "do this for each pci device" function to libpayload */
+
+static void busmaster_disable_on_bus(int bus)
+{
+ int slot, func;
+ unsigned int val;
+ unsigned char hdr;
+
+ for (slot = 0; slot < 0x20; slot++) {
+ for (func = 0; func < 8; func++) {
+ u32 reg32;
+ pcidev_t dev = PCI_DEV(bus, slot, func);
+
+ val = pci_read_config32(dev, REG_VENDOR_ID);
+
+ if (val == 0xffffffff || val == 0x00000000 ||
+ val == 0x0000ffff || val == 0xffff0000)
+ continue;
+
+ /* Disable Bus Mastering for this one device */
+ reg32 = pci_read_config32(dev, REG_COMMAND);
+ reg32 &= ~REG_COMMAND_BM;
+ pci_write_config32(dev, REG_COMMAND, reg32);
+
+ /* If this is a bridge, then follow it. */
+ hdr = pci_read_config8(dev, REG_HEADER_TYPE);
+ hdr &= 0x7f;
+ if (hdr == HEADER_TYPE_BRIDGE ||
+ hdr == HEADER_TYPE_CARDBUS) {
+ unsigned int buses;
+ buses = pci_read_config32(dev, REG_PRIMARY_BUS);
+ busmaster_disable_on_bus((buses >> 8) & 0xff);
+ }
+ }
+ }
+}
+
+static void busmaster_disable(void)
+{
+ busmaster_disable_on_bus(0);
+}
+
/**
* Mostly for testing purposes without booting an OS
*/
void platform_poweroff(void)
{
- int pmbase;
-
+ u16 pmbase;
+ u32 reg32;
+
pmbase = pci_read_config16(PCI_DEV(0,0x1f, 0), 0x40) & 0xfffe;
- /* XXX The sequence is correct; It works fine under Linux.
- * Yet, it does not power off the system in FILO.
- * Some initialization is missing
- */
+ /* Mask interrupts */
+ asm("cli");
+ /* Turn off all bus master enable bits */
+ busmaster_disable();
+
+ /* avoid any GPI waking the system from S5 */
+ outl(0x00000000, pmbase + GPE0_EN);
+
+ /* Clear Power Button Status */
+ outw(PWRBTN_STS, pmbase + PM1_STS);
+
/* PMBASE + 4, Bit 10-12, Sleeping Type,
* set to 110 -> S5, soft_off */
- outl((6 << 10), pmbase + 0x04);
- outl((1 << 13) | (6 << 10), pmbase + 0x04);
+ reg32 = inl(pmbase + PM1_CNT);
+ reg32 &= ~(SLP_EN | SLP_TYP);
+ reg32 |= SLP_TYP_S5;
+ outl(reg32, pmbase + PM1_CNT);
+
+ reg32 |= SLP_EN;
+ outl(reg32, pmbase + PM1_CNT);
+
for (;;) ;
}
More information about the coreboot
mailing list