We define IO_APIC_ADDR in <arch/ioapic.h>, let's use it.
[coreboot.git] / src / southbridge / sis / sis966 / sis966_lpc.c
index efb7b2e15186f39f34b9b89d821d33b4d37dba94..c6a1fce20deb7eccac5c61fa14cafe4e3784d6f6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * This file is part of the LinuxBIOS project.
+ * This file is part of the coreboot project.
  *
  * Copyright (C) 2003 Linux Networx
  * Copyright (C) 2003 SuSE Linux AG
 #include <pc80/isa-dma.h>
 #include <bitops.h>
 #include <arch/io.h>
+#include <arch/ioapic.h>
 #include <cpu/x86/lapic.h>
+#include <stdlib.h>
 #include "sis966.h"
 #include <pc80/keyboard.h>
 
 #define NMI_OFF        0
 
-struct ioapicreg {
-       unsigned int reg;
-       unsigned int value_low, value_high;
-};
-
-static struct ioapicreg ioapicregvalues[] = {
-#define ALL            (0xff << 24)
-#define NONE           (0)
-#define DISABLED       (1 << 16)
-#define ENABLED                (0 << 16)
-#define TRIGGER_EDGE   (0 << 15)
-#define TRIGGER_LEVEL  (1 << 15)
-#define POLARITY_HIGH  (0 << 13)
-#define POLARITY_LOW   (1 << 13)
-#define PHYSICAL_DEST  (0 << 11)
-#define LOGICAL_DEST   (1 << 11)
-#define ExtINT         (7 << 8)
-#define NMI            (4 << 8)
-#define SMI            (2 << 8)
-#define INT            (1 << 8)
-       /* IO-APIC virtual wire mode configuration */
-       /* mask, trigger, polarity, destination, delivery, vector */
-       {   0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE},
-       {   1, DISABLED, NONE},
-       {   2, DISABLED, NONE},
-       {   3, DISABLED, NONE},
-       {   4, DISABLED, NONE},
-       {   5, DISABLED, NONE},
-       {   6, DISABLED, NONE},
-       {   7, DISABLED, NONE},
-       {   8, DISABLED, NONE},
-       {   9, DISABLED, NONE},
-       {  10, DISABLED, NONE},
-       {  11, DISABLED, NONE},
-       {  12, DISABLED, NONE},
-       {  13, DISABLED, NONE},
-       {  14, DISABLED, NONE},
-       {  15, DISABLED, NONE},
-       {  16, DISABLED, NONE},
-       {  17, DISABLED, NONE},
-       {  18, DISABLED, NONE},
-       {  19, DISABLED, NONE},
-       {  20, DISABLED, NONE},
-       {  21, DISABLED, NONE},
-       {  22, DISABLED, NONE},
-       {  23, DISABLED, NONE},
-       /* Be careful and don't write past the end... */
-};
-
-static void setup_ioapic(unsigned long ioapic_base)
-{
-       int i;
-       unsigned long value_low, value_high;
-//     unsigned long ioapic_base = 0xfec00000;
-       volatile unsigned long *l;
-       struct ioapicreg *a = ioapicregvalues;
-
-       ioapicregvalues[0].value_high = lapicid()<<(56-32);
-
-       l = (unsigned long *) ioapic_base;
-
-       for (i = 0; i < sizeof(ioapicregvalues) / sizeof(ioapicregvalues[0]);
-            i++, a++) {
-               l[0] = (a->reg * 2) + 0x10;
-               l[4] = a->value_low;
-               value_low = l[4];
-               l[0] = (a->reg *2) + 0x11;
-               l[4] = a->value_high;
-               value_high = l[4];
-               if ((i==0) && (value_low == 0xffffffff)) {
-                       printk_warning("IO APIC not responding.\n");
-                       return;
-               }
-               printk_spew("for IRQ, reg 0x%08x value 0x%08x 0x%08x\n",
-                           a->reg, a->value_low, a->value_high);
-       }
-}
-
 // 0x7a or e3
 #define PREVIOUS_POWER_STATE   0x7A
 
@@ -127,39 +51,31 @@ static void setup_ioapic(unsigned long ioapic_base)
 #define SLOW_CPU_OFF   0
 #define SLOW_CPU__ON   1
 
-#ifndef MAINBOARD_POWER_ON_AFTER_POWER_FAIL
-#define MAINBOARD_POWER_ON_AFTER_POWER_FAIL    MAINBOARD_POWER_ON
+#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
+#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL     MAINBOARD_POWER_ON
 #endif
 
+#undef SLAVE_INIT
+
 static void lpc_common_init(device_t dev)
 {
        uint8_t byte;
-       uint32_t dword;
+       uint32_t ioapic_base;
 
        /* IO APIC initialization */
        byte = pci_read_config8(dev, 0x74);
        byte |= (1<<0); // enable APIC
        pci_write_config8(dev, 0x74, byte);
-       dword = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
-
-       setup_ioapic(dword);
+       ioapic_base = pci_read_config32(dev, PCI_BASE_ADDRESS_1); // 0x14
 
+       setup_ioapic(ioapic_base, 0); // Don't rename IO APIC ID
 }
 
+#ifdef SLAVE_INIT
 static void lpc_slave_init(device_t dev)
 {
        lpc_common_init(dev);
 }
-
-#if 0
-static void enable_hpet(struct device *dev)
-{
-       unsigned long hpet_address;
-
-       pci_write_config32(dev,0x44, 0xfed00001);
-       hpet_address=pci_read_config32(dev,0x44)& 0xfffffffe;
-       printk_debug("enabling HPET @0x%x\n", hpet_address);
-}
 #endif
 
 static void lpc_usb_legacy_init(device_t dev)
@@ -167,66 +83,28 @@ static void lpc_usb_legacy_init(device_t dev)
     uint16_t acpi_base;
 
     acpi_base = (pci_read_config8(dev,0x75) << 8);
-    //printk_debug("ACPI Base Addr=0x%4.4x\n",acpi_base);
-
-    //printk_debug("acpi_base + 0xbb=%.2x\n", inb(acpi_base + 0xbb));
-    //printk_debug("acpi_base + 0xba=%.2x\n", inb(acpi_base + 0xba));
 
     outb(inb(acpi_base + 0xbb) |0x80, acpi_base + 0xbb);
     outb(inb(acpi_base + 0xba) |0x80, acpi_base + 0xba);
-
-    //printk_debug("acpi_base + 0xbb=%.2x\n", inb(acpi_base + 0xbb));
-    //printk_debug("acpi_base + 0xba=%.2x\n", inb(acpi_base + 0xba));
-
-    return;
 }
 
 static void lpc_init(device_t dev)
 {
-       uint8_t byte;
-       uint8_t byte_old;
-       int on;
-       int nmi_option;
-
-        printk_debug("lpc_init -------->\n");
-        init_pc_keyboard(0x60, 0x64, 0);
-
-#if 0
-            {
-            int i;
-            printk_debug("LPC PCI config \n");
-            for(i=0;i<0xFF;i+=4)
-            {
-              if((i%16)==0)
-              {
-                print_debug("\r\n");
-                print_debug_hex8(i);
-                print_debug("  ");}
-                print_debug_hex32(pci_read_config32(dev,i));
-                print_debug("  ");    
-              }
-              print_debug("\r\n");
-            }
-#endif
-            printk_debug("lpc_init <--------\n");
-            lpc_usb_legacy_init(dev);
-            return;
-       
-       printk_debug("lpc_init\r\n");
-       lpc_common_init(dev);
-       printk_debug("lpc_init2\r\n");
+        uint8_t byte;
+        uint8_t byte_old;
+        int on;
+        int nmi_option;
 
+        printk(BIOS_DEBUG, "LPC_INIT -------->\n");
+        pc_keyboard_init(0);
 
-#if 0
-       /* posted memory write enable */
-       byte = pci_read_config8(dev, 0x46);
-       pci_write_config8(dev, 0x46, byte | (1<<0));
+        lpc_usb_legacy_init(dev);
+        lpc_common_init(dev);
 
-#endif
        /* power after power fail */
 
-#if 1
-       on = MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
+
+       on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
        get_option(&on, "power_on_after_fail");
        byte = pci_read_config8(dev, PREVIOUS_POWER_STATE);
        byte &= ~0x40;
@@ -234,8 +112,8 @@ static void lpc_init(device_t dev)
                byte |= 0x40;
        }
        pci_write_config8(dev, PREVIOUS_POWER_STATE, byte);
-       printk_info("set power %s after power fail\n", on?"on":"off");
-#endif
+       printk(BIOS_INFO, "set power %s after power fail\n", on?"on":"off");
+
        /* Throttle the CPU speed down for testing */
        on = SLOW_CPU_OFF;
        get_option(&on, "slow_cpu");
@@ -246,64 +124,63 @@ static void lpc_init(device_t dev)
                outl(((on<<1)+0x10)  ,(pm10_bar + 0x10));
                dword = inl(pm10_bar + 0x10);
                on = 8-on;
-               printk_debug("Throttling CPU %2d.%1.1d percent.\n",
+               printk(BIOS_DEBUG, "Throttling CPU %2d.%1.1d percent.\n",
                                (on*12)+(on>>1),(on&1)*5);
        }
-#if 0
-// default is enabled
-       /* Enable Port 92 fast reset */
-       byte = pci_read_config8(dev, 0xe8);
-       byte |= ~(1 << 3);
-       pci_write_config8(dev, 0xe8, byte);
-#endif
-
-       /* Enable Error reporting */
-       /* Set up sync flood detected */
-       byte = pci_read_config8(dev, 0x47);
-       byte |= (1 << 1);
-       pci_write_config8(dev, 0x47, byte);
-
-       /* Set up NMI on errors */
-       byte = inb(0x70); // RTC70
-       byte_old = byte;
-       nmi_option = NMI_OFF;
-       get_option(&nmi_option, "nmi");
-       if (nmi_option) {
-               byte &= ~(1 << 7); /* set NMI */
-       } else {
-               byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
-       }
-       if( byte != byte_old) {
-               outb(0x70, byte);
-       }
-
-       /* Initialize the real time clock */
-       rtc_init(0);
-
-       /* Initialize isa dma */
-       isa_dma_init();
-
-       /* Initialize the High Precision Event Timers */
-//     enable_hpet(dev);
 
+        /* Enable Error reporting */
+        /* Set up sync flood detected */
+        byte = pci_read_config8(dev, 0x47);
+        byte |= (1 << 1);
+        pci_write_config8(dev, 0x47, byte);
+
+        /* Set up NMI on errors */
+        byte = inb(0x70); // RTC70
+        byte_old = byte;
+        nmi_option = NMI_OFF;
+        get_option(&nmi_option, "nmi");
+        if (nmi_option) {
+                byte &= ~(1 << 7); /* set NMI */
+        } else {
+                byte |= ( 1 << 7); // Can not mask NMI from PCI-E and NMI_NOW
+        }
+        if( byte != byte_old) {
+                outb(byte, 0x70);
+        }
+
+        /* Initialize the real time clock */
+        rtc_init(0);
+
+        /* Initialize isa dma */
+        isa_dma_init();
+
+        printk(BIOS_DEBUG, "LPC_INIT <--------\n");
 }
 
 static void sis966_lpc_read_resources(device_t dev)
 {
        struct resource *res;
-       unsigned long index;
 
        /* Get the normal pci resources of this device */
        pci_dev_read_resources(dev); // We got one for APIC, or one more for TRAP
 
-       /* Add an extra subtractive resource for both memory and I/O */
+       /* Add an extra subtractive resource for both memory and I/O. */
        res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
-       res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
+       res->base = 0;
+       res->size = 0x1000;
+       res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
+                    IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 
        res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
-       res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
-
+       res->base = 0xff800000;
+       res->size = 0x00800000; /* 8 MB for flash */
+       res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
+                    IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
+
+       res = new_resource(dev, 3); /* IOAPIC */
+       res->base = IO_APIC_ADDR;
+       res->size = 0x00001000;
+       res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
 }
 
 /**
@@ -311,36 +188,27 @@ static void sis966_lpc_read_resources(device_t dev)
  *
  * @param dev the device whos children's resources are to be enabled
  *
- * This function is call by the global enable_resources() indirectly via the
- * device_operation::enable_resources() method of devices.
- *
- * Indirect mutual recursion:
- *      enable_childrens_resources() -> enable_resources()
- *      enable_resources() -> device_operation::enable_resources()
- *      device_operation::enable_resources() -> enable_children_resources()
  */
 static void sis966_lpc_enable_childrens_resources(device_t dev)
 {
-       unsigned link;
+       struct bus *link;
        uint32_t reg, reg_var[4];
        int i;
        int var_num = 0;
 
        reg = pci_read_config32(dev, 0xa0);
 
-       for (link = 0; link < dev->links; link++) {
+       for (link = dev->link_list; link; link = link->next) {
                device_t child;
-               for (child = dev->link[link].children; child; child = child->sibling) {
-                       enable_resources(child);
-                       if(child->have_resources && (child->path.type == DEVICE_PATH_PNP)) {
-                               for(i=0;i<child->resources;i++) {
-                                       struct resource *res;
+               for (child = link->children; child; child = child->sibling) {
+                       if(child->enabled && (child->path.type == DEVICE_PATH_PNP)) {
+                               struct resource *res;
+                               for(res = child->resource_list; res; res = res->next) {
                                        unsigned long base, end; // don't need long long
-                                       res = &child->resource[i];
                                        if(!(res->flags & IORESOURCE_IO)) continue;
                                        base = res->base;
                                        end = resource_end(res);
-                                       printk_debug("sis966 lpc decode:%s, base=0x%08x, end=0x%08x\n",dev_path(child),base, end);
+                                       printk(BIOS_DEBUG, "sis966 lpc decode:%s, base=0x%08lx, end=0x%08lx\n",dev_path(child),base, end);
                                        switch(base) {
                                        case 0x3f8: // COM1
                                                reg |= (1<<0);  break;
@@ -397,44 +265,14 @@ static struct device_operations lpc_ops  = {
 //     .enable         = sis966_enable,
        .ops_pci        = &lops_pci,
 };
-static struct pci_driver lpc_driver __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC,
-};
 
-static struct pci_driver lpc_driver_pro __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_PRO,
-};
-
-static struct pci_driver lpc_driver_lpc2 __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC_2,
-};
-static struct pci_driver lpc_driver_lpc3 __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC_3,
-};
-static struct pci_driver lpc_driver_lpc4 __pci_driver = {
+static const struct pci_driver lpc_driver __pci_driver = {
        .ops    = &lpc_ops,
        .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC_4,
-};
-static struct pci_driver lpc_driver_lpc5 __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC_5,
-};
-static struct pci_driver lpc_driver_lpc6 __pci_driver = {
-       .ops    = &lpc_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_LPC_6,
+       .device = PCI_DEVICE_ID_SIS_SIS966_LPC,
 };
 
+#ifdef SLAVE_INIT // No device?
 static struct device_operations lpc_slave_ops  = {
        .read_resources = sis966_lpc_read_resources,
        .set_resources  = pci_dev_set_resources,
@@ -443,9 +281,4 @@ static struct device_operations lpc_slave_ops  = {
 //     .enable         = sis966_enable,
        .ops_pci        = &lops_pci,
 };
-
-static struct pci_driver lpc_driver_slave __pci_driver = {
-       .ops    = &lpc_slave_ops,
-       .vendor = PCI_VENDOR_ID_SIS,
-       .device = PCI_DEVICE_ID_SIS_SIS966_SLAVE,
-};
+#endif