This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

section type conflict error [Fwd: PATCH 2.3.41.2: Replace Via support for ACPI]


GCC wizards,

The attached Linux kernel patch, against version 2.3.40 plus
pre-patch-2.3.41-2, causes the kernel build to fail with a "section type
conflict" error.  The compiler is gcc 2.95.2, the host/target is
i686-unknown-linux-gnu.

Can anyone shed any light on why this error occurs?

The key is that the compile dies in place in the code where my patch
does not modify at all.

The Linux kernel uses custom ELF sections to store various bits of code
which are used at special times.  The ".setup.init" section is called
early in the kernel boot, to process the kernel command line.  The
".text.init" section contains code which is only needed at kernel boot
time, and can be dropped from the runtime kernel image as the last step
in the boot process.

My patch adds some code to the existing .text.init section, but should
not disturb the existing .setup.init section at all.  However, it is the
.setup.init section where the compiler dies with a section type
conflict.

Any help or advice appreciated, I'm no ELF guru.  :)

Regards,

	Jeff





-- 
Jeff Garzik         | Andre the Giant has a posse.
Building 1024       |
MandrakeSoft, Inc.  |


Andy,

Attached is a patch against 2.3.41-pre2 which adds back Via support.  It
does so using the new PCI table-driven device matching code, which
should make it easy to add other chipsets.

NOTE that I was not able to get it to compile without #if-0'ing the
__setup function.  I got a section type conflict error which broke the
build.

Nevertheless, once the _unrelated_ setup function was commented out,
everything built just fine.

	Jeff




-- 
Jeff Garzik         | Andre the Giant has a posse.
Building 1024       |
MandrakeSoft, Inc.  |
diff -urN /spare/vanilla/linux-2.3.41-pre2/arch/i386/kernel/acpi.c linux/arch/i386/kernel/acpi.c
--- /spare/vanilla/linux-2.3.41-pre2/arch/i386/kernel/acpi.c	Thu Jan 20 12:51:42 2000
+++ linux/arch/i386/kernel/acpi.c	Sun Jan 23 19:19:12 2000
@@ -519,22 +519,16 @@
 	acpi_unmap_table((struct acpi_table*) acpi_facs);
 }
 
+
 /*
- * Locate PIIX4 device and create a fake FACP
+ * Init PIIX4 device, create a fake FACP
  */
-static int __init acpi_find_piix4(void)
+static int __init acpi_init_piix4 (struct pci_dev *dev)
 {
-	struct pci_dev *dev;
 	u32 base;
 	u16 cmd;
 	u8 pmregmisc;
 
-	dev = pci_find_device(PCI_VENDOR_ID_INTEL,
-			      PCI_DEVICE_ID_INTEL_82371AB_3,
-			      NULL);
-	if (!dev)
-		return -ENODEV;
-	
 	pci_read_config_word(dev, PCI_COMMAND, &cmd);
 	if (!(cmd & PCI_COMMAND_IO))
 		return -ENODEV;
@@ -586,6 +580,111 @@
 	return 0;
 }
 
+
+/*
+ * Init VIA ACPI device and create a fake FACP
+ */
+static int __init acpi_init_via686a (struct pci_dev *dev)
+{
+       u32 base;
+       u8 tmp, irq;
+
+       pci_read_config_byte(dev, 0x41, &tmp);
+       if (!(tmp & 0x80))
+               return -ENODEV;
+
+       pci_read_config_byte(dev, 8, &tmp);
+       tmp = (tmp & 0x10 ? 0x48 : 0x20);
+
+       pci_read_config_dword(dev, tmp, &base);
+       if (!(base & PCI_BASE_ADDRESS_SPACE_IO))
+               return -ENODEV;
+
+       base &= PCI_BASE_ADDRESS_IO_MASK;
+       if (!base)
+               return -ENODEV;
+
+       pci_read_config_byte(dev, 0x42, &irq);
+
+       printk(KERN_INFO "ACPI: found %s at 0x%04x\n", dev->name, base);
+
+       acpi_facp = kmalloc(sizeof(struct acpi_facp), GFP_KERNEL);
+       if (!acpi_facp)
+               return -ENOMEM;
+
+       acpi_fake_facp = 1;
+       memset(acpi_facp, 0, sizeof(struct acpi_facp));
+
+       acpi_facp->int_model = ACPI_VIA_INT_MODEL;
+       acpi_facp->sci_int = irq;
+       acpi_facp->smi_cmd = base + ACPI_VIA_SMI_CMD;
+       acpi_facp->acpi_enable = ACPI_VIA_ACPI_ENABLE;
+       acpi_facp->acpi_disable = ACPI_VIA_ACPI_DISABLE;
+       acpi_facp->pm1a_evt = base + ACPI_PIIX4_PM1_EVT;
+       acpi_facp->pm1a_cnt = base + ACPI_PIIX4_PM1_CNT;
+       acpi_facp->pm_tmr = base + ACPI_VIA_PM_TMR;
+       acpi_facp->gpe0 = base + ACPI_VIA_GPE0;
+
+       acpi_facp->pm1_evt_len = ACPI_VIA_PM1_EVT_LEN;
+       acpi_facp->pm1_cnt_len = ACPI_VIA_PM1_CNT_LEN;
+       acpi_facp->pm_tm_len = ACPI_VIA_PM_TM_LEN;
+       acpi_facp->gpe0_len = ACPI_VIA_GPE0_LEN;
+       acpi_facp->p_lvl2_lat = (__u16) ACPI_INFINITE_LAT;
+       acpi_facp->p_lvl3_lat = (__u16) ACPI_INFINITE_LAT;
+
+       acpi_facp->duty_offset = ACPI_VIA_DUTY_OFFSET;
+       acpi_facp->duty_width = ACPI_VIA_DUTY_WIDTH;
+
+       acpi_facp->day_alarm = ACPI_VIA_DAY_ALARM;
+       acpi_facp->mon_alarm = ACPI_VIA_MON_ALARM;
+       acpi_facp->century = ACPI_VIA_CENTURY;
+
+       acpi_facp_addr = virt_to_phys(acpi_facp);
+       acpi_dsdt_addr = 0;
+
+       acpi_p_blk = base + ACPI_VIA_P_BLK;
+
+       return 0;
+}
+
+
+typedef enum {
+	CH_UNKNOWN = 0,
+	CH_INTEL_PIIX4,
+	CH_VIA_686A,
+} acpi_chip_t;
+
+/* indexed by value of each enum in acpi_chip_t */
+const static struct {
+	acpi_chip_t chip;
+	int (*chip_init) (struct pci_dev *dev);
+} acpi_chip_info[] __initdata = {
+	{ CH_UNKNOWN, },
+	{ CH_INTEL_PIIX4, acpi_init_piix4 },
+	{ CH_VIA_686A, acpi_init_via686a },
+};
+	
+const static struct pci_device_id acpi_pci_tbl[] __initdata = {
+	{ 0x8086, 0x7113, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_INTEL_PIIX4 },
+	{ 0x1106, 0x3057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_VIA_686A },
+	{ 0,}, /* terminate list */
+};
+
+static int __init acpi_find_pcidev (void)
+{
+	struct pci_dev *pdev;
+	const struct pci_device_id *ent;
+
+	pci_for_each_dev (pdev) {
+		ent = pci_match_device (acpi_pci_tbl, pdev);
+		if (ent)
+			return acpi_chip_info[ent->driver_data].chip_init (pdev);
+	}
+	
+	return -ENODEV;
+}
+
+
 /*
  * Handle an ACPI SCI (fixed or general purpose event)
  */
@@ -1208,6 +1307,7 @@
 	return 0;
 }
 
+
 /*
  * Initialize and enable ACPI
  */
@@ -1218,8 +1318,8 @@
 	if (acpi_disabled)
 		return -ENODEV;
 
-	if (acpi_find_tables() && acpi_find_piix4()) {
-		// no ACPI tables and not PIIX4
+	if (acpi_find_tables() && acpi_find_pcidev()) {
+		// no ACPI tables and no supported ACPI devices
 		return -ENODEV;
 	}
 
@@ -1298,6 +1398,7 @@
 	acpi_destroy_tables();
 }
 
+#if 0
 static int __init acpi_setup(char *str)
 {
 	while (str && *str) {
@@ -1313,6 +1414,7 @@
 }
 
 __setup("acpi=", acpi_setup);
+#endif
 
 /*
  * Register a device with the ACPI subsystem



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]