[LinuxBIOS] PATCH: P64H2 cleanup

Steven J. Magnani steve at digidescorp.com
Mon Sep 12 20:34:40 CEST 2005


This patch does the following:

* Drops hard-coding of P64H2 vendor/subsystem ID
* Replaces magic numbers with standard #defined tags
* Attempts to improve clarity via comments and variable names
* Releases <assert.h> for general use

Except for the vendor/subsystem ID, the changes don't affect the
operation of the code.

PATCH:

--- src/southbridge/intel/i82870/p64h2_ioapic.c.orig	2005-09-08
13:34:48.078125000 -0500
+++ src/southbridge/intel/i82870/p64h2_ioapic.c	2005-09-12
13:22:28.671875000 -0500
@@ -4,72 +4,81 @@
 #include <device/pci_ids.h>
 #include <device/pci_ops.h>
 #include <pc80/mc146818rtc.h>
+#include <assert.h>
 #include "82870.h"
 
-static int ioapic_no = 0;
+static int num_p64h2_ioapics = 0;
 
 static void p64h2_ioapic_enable(device_t dev)
 {
-	uint32_t dword;
-	uint16_t word;
-
 	        /* We have to enable MEM and Bus Master for IOAPIC */
-		word = 0x0146;
-		pci_write_config16(dev, PCICMD, word);
-		dword = 0x358015d9;
-		pci_write_config32(dev, SUBSYS, dword);
+    uint16_t command = PCI_COMMAND_SERR | PCI_COMMAND_PARITY |
PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
 
 
+    pci_write_config16(dev, PCI_COMMAND, command);
 }
 
+//---------------------------------------------------------------------
-------------
+// Function:        p64h2_ioapic_init
+// Parameters:      dev - PCI bus/device/function of P64H2 IOAPIC
+//                  NOTE: There are two IOAPICs per P64H2, at D28:F0
and D30:F0
+// Return Value:    None
+// Description:     Configure one of the IOAPICs in a P64H2.
+//                  Note that a PCI bus scan will detect both IOAPICs,
so this function
+//                  will be called twice for each P64H2 in the system.
+//
 static void p64h2_ioapic_init(device_t dev)
 {
-        uint32_t dword;
-        uint16_t word;
-        int i, addr;
+    uint32_t memoryBase;
+    int apic_index, apic_id;
 
-        volatile uint32_t *ioapic_a;    /* io apic io memory space
command address */
-        volatile uint32_t *ioapic_d;    /* io apic io memory space data
address */
+    volatile uint32_t* pIndexRegister;    /* io apic io memory space
command address */
+    volatile uint32_t* pWindowRegister;    /* io apic io memory space
data address */
 
-        i = ioapic_no++;
+    apic_index = num_p64h2_ioapics;
+    num_p64h2_ioapics++;
 
-                if(i<3)                 /* io apic address numbers are
3,4,5,&8 */
-                        addr=i+3;
+    // A note on IOAPIC addresses:
+    //  0 and 1 are used for the local APICs of the dual virtual 
+	//	(hyper-threaded) CPUs of physical CPU 0
(mainboard/Config.lb).
+    //  6 and 7 are used for the local APICs of the dual virtual 
+	//	(hyper-threaded) CPUs of physical CPU 1
(mainboard/Config.lb).
+    //  2 is used for the IOAPIC in the 82801 Southbridge (hard-coded
in i82801xx_lpc.c)
+
+    // Map APIC index into APIC ID
+    // IDs 3, 4, 5, and 8+ are available (see above note)
+
+    if (apic_index < 3)
+        apic_id = apic_index + 3;
                 else
-                        addr=i+5;
-                /* Read the MBAR address for setting up the io apic in
io memory space */
-                dword = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
-                ioapic_a = (uint32_t *) dword;
-                ioapic_d = ioapic_a +0x04;
+        apic_id = apic_index + 5;
+
+    ASSERT(apic_id < 16);       // ID is only 4 bits
+
+    // Read the MBAR address for setting up the IOAPIC in memory space
+    // NOTE: this address was assigned during enumeration of the bus
+
+    memoryBase = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
+    pIndexRegister  = (volatile uint32_t*) memoryBase;
+    pWindowRegister = (volatile uint32_t*)(memoryBase + 0x10);
+
                 printk_debug("IOAPIC %d at %02x:%02x.%01x  MBAR = %x
DataAddr = %x\n",
-                        addr, dev->bus->secondary,
-                        PCI_SLOT(dev->path.u.pci.devfn),
PCI_FUNC(dev->path.u.pci.devfn),
-                        ioapic_a, ioapic_d);
+                 apic_id, dev->bus->secondary,
PCI_SLOT(dev->path.u.pci.devfn), 
+                 PCI_FUNC(dev->path.u.pci.devfn), pIndexRegister,
pWindowRegister);
 
-#if 0
-                dword = (u32)ioapic_a;
-                word = 0x8000 + ((dword >>8)&0x0fff);
-                pci_write_config_word(dev, ABAR, word);
-#endif
-                /* Set up the io apic for the p64h2 - 1461 */
-                *ioapic_a=0;
-                *ioapic_d=(addr<<24); /* Set the address number */
-                *ioapic_a=3;
-                *ioapic_d=1;    /* Enable the io apic */
+    apic_id <<= 24;             // Convert ID to bitmask
 
-                /* This code test the setup to see if we really found
the io apic */
-                *ioapic_a=0;
-                dword=*ioapic_d;
-                printk_debug("PCI %d apic id = %x\n",addr,dword);
-                if(dword!=(addr<<24))
-                        for(;;);
-                *ioapic_a=3;
-                dword=*ioapic_d;
-                printk_debug("PCI %d apic DT = %x\n",addr,dword);
-                if(dword!=1)
-                        for(;;);
+    *pIndexRegister = 0;        // Select APIC ID register
+    *pWindowRegister = (*pWindowRegister & ~(0xF<<24)) | apic_id;   //
Set the ID
+
+    if ((*pWindowRegister & (0xF<<24)) != apic_id)
+        die("p64h2_ioapic_init failed"); 
 
+    *pIndexRegister  = 3;   // Select Boot Configuration register
+    *pWindowRegister |= 1;  // Use Processor System Bus to deliver
interrupts
 
+    if (!(*pWindowRegister & 1))
+        die("p64h2_ioapic_init failed"); 
 }
 
 static struct device_operations ioapic_ops = {


--- src/southbridge/intel/i82870/82870.h.orig	2005-09-08
13:34:48.140625000 -0500
+++ src/southbridge/intel/i82870/82870.h	2005-07-25
09:40:35.109375000 -0500
@@ -1,6 +1,4 @@
 /* for io apic 1461 */
-#define PCICMD  	0x04
-#define SUBSYS		0x2c
 #define MBAR		0x10
 #define ABAR		0x40
 
@@ -8,3 +6,10 @@
 #define MTT	  	0x042
 #define HCCR	  	0x0f0
 #define ACNF	  	0x0e0
+#define STRP		0x44		// Strap status register
+
+#define STRP_EN133	0x0001		// 133 MHz-capable (Px_133EN)
+#define STRP_HPCAP	0x0002		// Hot-plug capable (Hx_SLOT
zero/nonzero)
+
+#define ACNF_SYNCPH	0x0010		// PCI(-X) input clock is
synchronous to hub input clock
+


--- src/include/assert.h.orig	1969-12-31 18:00:00.000000000 -0600
+++ src/include/assert.h	2005-07-11 11:03:54.000000000 -0500
@@ -0,0 +1,59 @@
+/*
+ * $Header: /home/cvs/BIR/ca-cpu/freebios/src/include/assert.h,v 1.1
2005/07/11 16:03:54 smagnani Exp $
+ *
+ * assert.h: Debugging macros
+ *
+ * Copyright (C) 2005 Digital Design Corporation
+ *
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307
USA
+ *
+ * $Log: assert.h,v $
+ * Revision 1.1  2005/07/11 16:03:54  smagnani
+ * Initial revision.
+ *
+ *
+ */
+
+#ifndef __ASSERT_H_DEFINED
+#define __ASSERT_H_DEFINED
+
+// ROMCC doesn't support __FILE__ or __LINE__  :^{
+
+#if DEBUG
+#ifdef __ROMCC__
+#define ASSERT(x)	{ if (!(x)) die("ASSERT failure!\r\n"); }
+#else
+#define ASSERT(x)	{ 				\
+						if (!(x)) 	\
+						{
\
+
printk_emerg("ASSERT failure: file '%s', line %d\n", __FILE__,
__LINE__); \
+							die(""); \
+						}
\
+					}
+#endif		// __ROMCC__
+#else		// !DEBUG
+#define ASSERT(x)	{ }
+#endif
+
+#ifdef __ROMCC__
+#define BUG()		{ 	die("BUG encountered: system
halted\r\n");  }
+#else
+#define BUG()		{ 				\
+						printk_emerg("BUG: file
'%s', line %d\n", __FILE__, __LINE__); \
+						die(""); \
+					}
+#endif
+					
+#endif 	// __ASSERT_H_DEFINED
------------------------------------------------------------------------
 Steven J. Magnani               "I claim this network for MARS!
 www.digidescorp.com              Earthling, return my space modulator!"
 
 #include <standard.disclaimer>







More information about the coreboot mailing list