diff --git a/arch/x86/amd/model_fxx/fidvid.c b/arch/x86/amd/model_fxx/fidvid.c index 45a05a8ddc..29f790b33d 100644 --- a/arch/x86/amd/model_fxx/fidvid.c +++ b/arch/x86/amd/model_fxx/fidvid.c @@ -441,6 +441,7 @@ void init_fidvid_bsp(unsigned bsp_apicid) struct msr msr; msr = rdmsr(FIDVID_STATUS); fid_max = ((msr.lo >> 16) & 0x3f); /* max fid */ + printk(BIOS_DEBUG, "init_fidvid_bsp: fid_max is 0x%x\n", fid_max); #if FX_SUPPORT == 1 if (fid_max >= ((25-4) * 2)) { /* FX max fid is 5G */ fid_max = ((msr.lo >> 8) & 0x3f) + 5*2; /* maxFID = minFID + 1G */ diff --git a/device/pci_ops.c b/device/pci_ops.c index 2fee87ab94..3fe9551e3c 100644 --- a/device/pci_ops.c +++ b/device/pci_ops.c @@ -35,6 +35,12 @@ static struct bus *get_pbus(struct device *dev) { struct bus *pbus = dev->bus; while (pbus && pbus->dev && !ops_pci_bus(pbus)) { + if (pbus->dev == dev) { + printk(BIOS_EMERG, "Loop: dev->dtsname dev->bus->dev\n"); + printk(BIOS_EMERG, "To fix this, set ops_pci_bus in dts\n"); + die("loop due to insufficient dts"); + } + pbus = pbus->dev->bus; } if (!pbus || !pbus->dev || !pbus->dev->ops diff --git a/mainboard/Kconfig b/mainboard/Kconfig index 9a63433601..0453841524 100644 --- a/mainboard/Kconfig +++ b/mainboard/Kconfig @@ -37,6 +37,12 @@ config VENDOR_AMD Select this option for various systems from Advanced Micro Devices, Inc. +config VENDOR_AMP + bool "AMP" + help + Select this option for various systems from + Advanced Micro Devices, Inc. + config VENDOR_ARTECGROUP bool "Artec Group" help @@ -61,6 +67,7 @@ endchoice source "mainboard/adl/Kconfig" source "mainboard/amd/Kconfig" +source "mainboard/amp/Kconfig" source "mainboard/artecgroup/Kconfig" source "mainboard/emulation/Kconfig" source "mainboard/gigabyte/Kconfig" diff --git a/mainboard/amd/serengeti/dts b/mainboard/amd/serengeti/dts index 23f1a81936..693804066c 100644 --- a/mainboard/amd/serengeti/dts +++ b/mainboard/amd/serengeti/dts @@ -25,10 +25,11 @@ apic@0 { }; domain@0 { + /config/("northbridge/amd/k8/domain"); pci@1,0{ }; /* guesses; we need a real lspci */ - pci@18,0 { + pci0@18,0 { /config/("northbridge/amd/k8/pci"); pci@0,0 { /config/("southbridge/amd/amd8111/amd8111.dts"); @@ -40,6 +41,15 @@ /config/("southbridge/amd/amd8111/nic.dts"); }; }; + pci1@18,0 { + /config/("northbridge/amd/k8/pci"); + }; + pci2@18,0 { + /config/("northbridge/amd/k8/pci"); + /* just for illustrating link #2 */ + pci@2,0{ + }; + }; ioport@2e { /config/("superio/winbond/w83627hf/dts"); com1enable = "1"; diff --git a/mainboard/amp/Kconfig b/mainboard/amp/Kconfig new file mode 100644 index 0000000000..b749db7398 --- /dev/null +++ b/mainboard/amp/Kconfig @@ -0,0 +1,44 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2007 coresystems GmbH +## (Written by Stefan Reinauer for coresystems GmbH) +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +choice + prompt "Mainboard model" + depends on VENDOR_AMP + +config BOARD_AMP_TINYGX + bool "TinyGX" + select ARCH_X86 + select CPU_AMD_GEODELX + select OPTION_TABLE + select NORTHBRIDGE_AMD_GEODELX + select SOUTHBRIDGE_AMD_CS5536 + select SUPERIO_ITE_IT8716F + select PIRQ_TABLE + help + SMP TinyGX + +endchoice + +config MAINBOARD_DIR + string + default amp/tinygx + depends BOARD_AMP_TINYGX + diff --git a/mainboard/amp/tinygx/Makefile b/mainboard/amp/tinygx/Makefile new file mode 100644 index 0000000000..a8bd1db04f --- /dev/null +++ b/mainboard/amp/tinygx/Makefile @@ -0,0 +1,34 @@ +## +## This file is part of the coreboot project. +## +## Copyright (C) 2006-2007 coresystems GmbH +## (Written by Stefan Reinauer for coresystems GmbH) +## +## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +## + +STAGE0_MAINBOARD_SRC := $(src)/mainboard/$(MAINBOARDDIR)/stage1.c + +INITRAM_SRC = $(src)/mainboard/$(MAINBOARDDIR)/initram.c \ + $(src)/northbridge/amd/geodelx/raminit.c \ + $(src)/southbridge/amd/cs5536/smbus_initram.c \ + $(src)/arch/x86/geodelx/geodelx.c + +STAGE2_MAINBOARD_SRC = + +$(obj)/coreboot.vpd: + $(Q)printf " BUILD DUMMY VPD\n" + $(Q)dd if=/dev/zero of=$(obj)/coreboot.vpd bs=256 count=1 $(SILENT) + diff --git a/mainboard/amp/tinygx/cmos.layout b/mainboard/amp/tinygx/cmos.layout new file mode 100644 index 0000000000..5ba4c032c1 --- /dev/null +++ b/mainboard/amp/tinygx/cmos.layout @@ -0,0 +1,74 @@ +entries + +#start-bit length config config-ID name +#0 8 r 0 seconds +#8 8 r 0 alarm_seconds +#16 8 r 0 minutes +#24 8 r 0 alarm_minutes +#32 8 r 0 hours +#40 8 r 0 alarm_hours +#48 8 r 0 day_of_week +#56 8 r 0 day_of_month +#64 8 r 0 month +#72 8 r 0 year +#80 4 r 0 rate_select +#84 3 r 0 REF_Clock +#87 1 r 0 UIP +#88 1 r 0 auto_switch_DST +#89 1 r 0 24_hour_mode +#90 1 r 0 binary_values_enable +#91 1 r 0 square-wave_out_enable +#92 1 r 0 update_finished_enable +#93 1 r 0 alarm_interrupt_enable +#94 1 r 0 periodic_interrupt_enable +#95 1 r 0 disable_clock_updates +#96 288 r 0 temporary_filler +0 384 r 0 reserved_memory +384 1 e 4 boot_option +385 1 e 4 last_boot +386 1 e 1 ECC_memory +388 4 r 0 reboot_bits +392 3 e 5 baud_rate +400 1 e 1 power_on_after_fail +412 4 e 6 debug_level +416 4 e 7 boot_first +420 4 e 7 boot_second +424 4 e 7 boot_third +428 4 h 0 boot_index +432 8 h 0 boot_countdown +1008 16 h 0 check_sum + +enumerations + +#ID value text +1 0 Disable +1 1 Enable +2 0 Enable +2 1 Disable +4 0 Fallback +4 1 Normal +5 0 115200 +5 1 57600 +5 2 38400 +5 3 19200 +5 4 9600 +5 5 4800 +5 6 2400 +5 7 1200 +6 6 Notice +6 7 Info +6 8 Debug +6 9 Spew +7 0 Network +7 1 HDD +7 2 Floppy +7 8 Fallback_Network +7 9 Fallback_HDD +7 10 Fallback_Floppy +#7 3 ROM + +checksums + +checksum 392 1007 1008 + + diff --git a/mainboard/amp/tinygx/dts b/mainboard/amp/tinygx/dts new file mode 100644 index 0000000000..ec2b86a249 --- /dev/null +++ b/mainboard/amp/tinygx/dts @@ -0,0 +1,60 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Ronald G. Minnich + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/{ + mainboard_vendor = "AMP"; + mainboard_name = "TinyGX"; + mainboard_pci_subsystem_vendor = "0x1022"; + mainboard_pci_subsystem_device = "0x2323"; + cpus { }; + apic@0 { + /config/("northbridge/amd/geodelx/apic"); + }; + domain@0 { + /config/("northbridge/amd/geodelx/domain"); + /* Video RAM has to be in 2MB chunks. */ + geode_video_mb = "8"; + pci@1,0 { + /config/("northbridge/amd/geodelx/pci"); + }; + pci@f,0 { + /config/("southbridge/amd/cs5536/dts"); + /* Interrupt enables for LPC bus. + * Each bit is an IRQ 0-15. */ + lpc_serirq_enable = "0x000010da"; + /* LPC IRQ polarity. Each bit is an IRQ 0-15. */ + lpc_serirq_polarity = "0x0000EF25"; + /* 0:continuous 1:quiet */ + lpc_serirq_mode = "1"; + /* GPIO(0-0x20) for INT D:C:B:A, 0xFF=none. + * See virtual PIC spec. */ + enable_gpio_int_route = "0x0D0C0700"; + enable_USBP4_device = "1"; + }; + pci@f,2 { + /config/("southbridge/amd/cs5536/ide"); + enable_ide = "1"; + }; + ioport@2e { + /config/("superio/ite/it8716f/dts"); + com1enable = "1"; + }; + }; +}; diff --git a/mainboard/amp/tinygx/initram.c b/mainboard/amp/tinygx/initram.c new file mode 100644 index 0000000000..34f3308f18 --- /dev/null +++ b/mainboard/amp/tinygx/initram.c @@ -0,0 +1,118 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Advanced Micro Devices, 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; 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#define _MAINOBJECT + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* #include + * TODO: figure out how smbus functions should be done. See smbus_ops.c + */ +extern int smbus_read_byte(u16 device, u8 address); + +#define MANUALCONF 0 /* Do automatic strapped PLL config */ +#define PLLMSRHI 0x00001490 /* manual settings for the PLL */ +#define PLLMSRLO 0x02000030 +#define DIMM0 ((u8) 0xA0) +#define DIMM1 ((u8) 0xA2) + +/** + * Read a byte from the SPD. + * + * For this board, that is really just saying 'read a byte from SMBus'. + * So we use smbus_read_byte(). Nota Bene: leave this here as a function + * rather than a #define in an obscure location. This function is called + * only a few dozen times, and it's not performance critical. + * + * @param device The device. + * @param address The address. + * @return The data from the SMBus packet area or an error of 0xff (i.e. -1). + */ +u8 spd_read_byte(u16 device, u8 address) +{ + u8 spdbyte; + + printk(BIOS_DEBUG, "spd_read_byte dev %04x\n", device); + + spdbyte = smbus_read_byte(device, address); + + printk(BIOS_DEBUG, " addr %02x returns %02x\n", address, spdbyte); + + return spdbyte; +} + +/** + * Placeholder in case we ever need it. Since this file is a + * template for other motherboards, we want this here and we want the + * call in the right place. + */ + +static void mb_gpio_init(void) +{ + /* Early mainboard specific GPIO setup */ +} + +/** + * main for initram for the AMD DB800 development platform. + * It might seem that you could somehow do these functions in, e.g., the cpu + * code, but the order of operations and what those operations are is VERY + * strongly mainboard dependent. It's best to leave it in the mainboard code. + */ +int main(void) +{ + printk(BIOS_DEBUG, "Hi there from initram (stage1) main!\n"); + post_code(POST_START_OF_MAIN); + + system_preinit(); + printk(BIOS_DEBUG, "done preinit\n"); + + mb_gpio_init(); + printk(BIOS_DEBUG, "done gpio init\n"); + + pll_reset(MANUALCONF, PLLMSRHI, PLLMSRLO); + printk(BIOS_DEBUG, "done pll reset\n"); + + cpu_reg_init(0, DIMM0, DIMM1, DRAM_UNTERMINATED); + printk(BIOS_DEBUG, "done cpu reg init\n"); + + sdram_set_registers(); + printk(BIOS_DEBUG, "done sdram set registers\n"); + + sdram_set_spd_registers(DIMM0, DIMM1); + printk(BIOS_DEBUG, "done sdram set spd registers\n"); + + sdram_enable(DIMM0, DIMM1); + printk(BIOS_DEBUG, "done sdram enable\n"); + + /* Check low memory */ + /*ram_check(0x00000000, 640*1024); */ + + printk(BIOS_DEBUG, "stage1 returns\n"); + return 0; +} diff --git a/mainboard/amp/tinygx/irq_tables.h b/mainboard/amp/tinygx/irq_tables.h new file mode 100644 index 0000000000..874bf6acac --- /dev/null +++ b/mainboard/amp/tinygx/irq_tables.h @@ -0,0 +1,81 @@ +/* +* This file is part of the coreboot project. +* +* Copyright (C) 2007 Advanced Micro Devices, Inc. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 as +* published by the Free Software Foundation. +* +* 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 + +/* Number of slots and devices in the PIR table */ +#define SLOT_COUNT 4 + +/* Platform IRQs */ +#define PIRQA 10 +#define PIRQB 11 +#define PIRQC 10 +#define PIRQD 11 + +/* Map */ +#define M_PIRQA (1 << PIRQA) /* Bitmap of supported IRQs */ +#define M_PIRQB (1 << PIRQB) /* Bitmap of supported IRQs */ +#define M_PIRQC (1 << PIRQC) /* Bitmap of supported IRQs */ +#define M_PIRQD (1 << PIRQD) /* Bitmap of supported IRQs */ + +/* Link */ +#define L_PIRQA 1 /* Means Slot INTx# Connects To Chipset INTA# */ +#define L_PIRQB 2 /* Means Slot INTx# Connects To Chipset INTB# */ +#define L_PIRQC 3 /* Means Slot INTx# Connects To Chipset INTC# */ +#define L_PIRQD 4 /* Means Slot INTx# Connects To Chipset INTD# */ + +/* + * AMD DB800 interrupt wiring. + * + * Devices are: + * + * FIXME + * + */ + +const struct irq_routing_table intel_irq_routing_table = { + PIRQ_SIGNATURE, + PIRQ_VERSION, + 32 + 16 * SLOT_COUNT, /* Max. number of devices on the bus */ + 0x00, /* Where the interrupt router lies (bus) */ + (0x0F << 3) | 0x0, /* Where the interrupt router lies (dev) */ + 0x00, /* IRQs devoted exclusively to PCI usage */ + 0x100B, /* Vendor */ + 0x002B, /* Device */ + 0, /* Crap (miniport) */ + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* u8 rfu[11] */ + 0x00, /* Checksum */ + { + /* If you change the number of entries, change IRQ_SLOT_COUNT above! */ + + /* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */ + + /* CPU */ + {0x00, (0x01 << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* Chipset slots -- f.3 wires to B, and f.4 and f.5 wires to D. */ + {0x00, (0x0F << 3) | 0x0, {{L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}, {L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}}, 0x0, 0x0}, + + /* On-board ethernet */ + {0x00, (0x0D << 3) | 0x0, {{L_PIRQB, M_PIRQB}, {0x00, 0x00}, {0x00, 0x00}, {0x00, 0x00}}, 0x0, 0x0}, + + /* PCI (slot 1) */ + {0x00, (0x0E << 3) | 0x0, {{L_PIRQC, M_PIRQC}, {L_PIRQD, M_PIRQD}, {L_PIRQA, M_PIRQA}, {L_PIRQB, M_PIRQB}}, 0x1, 0x0}, + } +}; diff --git a/mainboard/amp/tinygx/stage1.c b/mainboard/amp/tinygx/stage1.c new file mode 100644 index 0000000000..cc6325774e --- /dev/null +++ b/mainboard/amp/tinygx/stage1.c @@ -0,0 +1,57 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2007 Advanced Micro Devices, 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; 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SERIAL_DEV IT8716F_SP1 +#define SERIAL_IOBASE 0x3f8 + +void hardware_stage1(void) +{ + void it8716f_enable_serial(u8 dev, u8 serial, u16 iobase); + post_code(POST_START_OF_MAIN); + geodelx_msr_init(); + + cs5536_stage1(); + + /* NOTE: must do this AFTER the early_setup! + * it is counting on some early MSR setup + * for cs5536. + */ + cs5536_disable_internal_uart(); + it8716f_enable_serial(0x2e, SERIAL_DEV, SERIAL_IOBASE); + +} + +void mainboard_pre_payload(void) +{ + geode_pre_payload(); + banner(BIOS_DEBUG, "mainboard_pre_payload: done"); +} diff --git a/mainboard/artecgroup/dbe62/initram.c b/mainboard/artecgroup/dbe62/initram.c index 186f27821a..7ab26061cf 100644 --- a/mainboard/artecgroup/dbe62/initram.c +++ b/mainboard/artecgroup/dbe62/initram.c @@ -65,7 +65,7 @@ static const struct spd_entry spd_table[] = { {SPD_tRP, 0x58}, {SPD_PRIMARY_SDRAM_WIDTH, 8}, {SPD_NUM_BANKS_PER_SDRAM, 0x4}, - {SPD_NUM_COLUMNS, 0xa}, /* 8kB */ + {SPD_NUM_COLUMNS, 0x8}, /* 8kB */ {SPD_NUM_DIMM_BANKS, 0x1}, {SPD_REFRESH, 0x82}, {SPD_SDRAM_CYCLE_TIME_2ND, 0x0}, diff --git a/northbridge/amd/geodelx/pci b/northbridge/amd/geodelx/pci index 3039ac0cca..e3a8936a64 100644 --- a/northbridge/amd/geodelx/pci +++ b/northbridge/amd/geodelx/pci @@ -20,5 +20,6 @@ { device_operations = "geodelx_north_pci"; + bridge; }; diff --git a/northbridge/amd/k8/domain.c b/northbridge/amd/k8/domain.c index b6b4fdabab..5f71291d73 100644 --- a/northbridge/amd/k8/domain.c +++ b/northbridge/amd/k8/domain.c @@ -104,6 +104,7 @@ static void k8_pci_domain_read_resources(struct device * dev) unsigned reg; /* Find the already assigned resource pairs */ + printk(BIOS_DEBUG, "k8_pci_domain_read_resources\n"); get_fx_devs(); for(reg = 0x80; reg <= 0xd8; reg+= 0x08) { u32 base, limit; @@ -166,6 +167,7 @@ static void k8_pci_domain_read_resources(struct device * dev) static void k8_pci_domain_set_resources(struct device * dev) { + printk(BIOS_DEBUG, "k8_pci_domain_set_resources\n"); #if CONFIG_HW_MEM_HOLE_SIZEK != 0 struct hw_mem_hole_info get_hw_mem_hole_info(void); void disable_hoist_memory(unsigned long hole_startk, int i); @@ -367,6 +369,7 @@ static unsigned int k8_domain_scan_bus(struct device * dev, unsigned int max) { unsigned reg; int i; + printk(BIOS_DEBUG, "k8_domain_scan_bus\n"); /* Unmap all of the HT chains */ for(reg = 0xe0; reg <= 0xec; reg += 4) { f1_write_config32(reg, 0); @@ -397,7 +400,7 @@ static unsigned int k8_domain_scan_bus(struct device * dev, unsigned int max) return max; } -struct device_operations k8apic_ops = { +struct device_operations k8domain_ops = { .id = {.type = DEVICE_ID_APIC_CLUSTER, {.pci_domain = {.vendor = PCI_VENDOR_ID_AMD, .device = 0x1100}}}, diff --git a/northbridge/amd/k8/pci b/northbridge/amd/k8/pci index 330fcf63bd..071621d16b 100644 --- a/northbridge/amd/k8/pci +++ b/northbridge/amd/k8/pci @@ -20,4 +20,5 @@ { device_operations = "k8_ops"; + bridge; }; diff --git a/northbridge/amd/k8/pci.c b/northbridge/amd/k8/pci.c index 37dfebaae5..387eae811d 100644 --- a/northbridge/amd/k8/pci.c +++ b/northbridge/amd/k8/pci.c @@ -74,6 +74,7 @@ static unsigned int amdk8_scan_chain(struct device * dev, unsigned nodeid, unsig if (!(link_type & LinkConnected)) { return max; } + printk(BIOS_DEBUG, "amdk8_scan_chain: link %d is connected\n", link); do { link_type = pci_read_config32(dev, dev->link[link].cap + 0x18); } while(!(link_type & InitComplete)); @@ -211,6 +212,8 @@ static unsigned int amdk8_scan_chains(struct device * dev, unsigned int max) unsigned offset_unitid = 0; nodeid = amdk8_nodeid(dev); + printk(BIOS_DEBUG, "amdk8_scan_chains\n"); + if(nodeid==0) { sblink = (pci_read_config32(dev, 0x64)>>8) & 3; #if SB_HT_CHAIN_ON_BUS0 > 0 @@ -371,6 +374,7 @@ static void amdk8_link_read_bases(struct device * dev, unsigned nodeid, unsigned static void amdk8_read_resources(struct device * dev) { + printk(BIOS_DEBUG, "amdk8_read_resources\n"); unsigned nodeid, link; nodeid = amdk8_nodeid(dev); for(link = 0; link < dev->links; link++) { @@ -385,7 +389,7 @@ static void amdk8_set_resource(struct device * dev, struct resource *resource, u resource_t rbase, rend; unsigned reg, link; char buf[50]; - + printk(BIOS_DEBUG, "amdk8_set_resource\n"); /* Make certain the resource has actually been set */ if (!(resource->flags & IORESOURCE_ASSIGNED)) { return; @@ -536,6 +540,7 @@ static void amdk8_set_resources(struct device * dev) /* Find the nodeid */ nodeid = amdk8_nodeid(dev); + printk(BIOS_DEBUG, "amdk8_set_resources: nodeid %d\n", nodeid); amdk8_create_vga_resource(dev, nodeid); /* Set each resource we have found */ @@ -554,6 +559,7 @@ static void amdk8_set_resources(struct device * dev) static void amdk8_enable_resources(struct device * dev) { + printk(BIOS_DEBUG, "amdk8_enable_resources\n"); pci_dev_enable_resources(dev); enable_childrens_resources(dev); } @@ -581,4 +587,5 @@ struct device_operations k8_ops = { .phase5_enable_resources = amdk8_enable_resources, .phase6_init = mcf0_control_init, .ops_pci = &pci_dev_ops_pci, + .ops_pci_bus = &pci_cf8_conf1, }; diff --git a/superio/ite/it8716f/dts b/superio/ite/it8716f/dts index 3f9a93afa1..171e964004 100644 --- a/superio/ite/it8716f/dts +++ b/superio/ite/it8716f/dts @@ -1,22 +1,24 @@ -## -## This file is part of the coreboot project. -## -## Copyright (C) 2008 Peter Stuge -## -## 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -## +/* + * + * This file is part of the coreboot project. + * + * Copyright (C) 2008 Peter Stuge + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ { /* Floppy */ floppydev = "0x0"; diff --git a/util/dtc/dtc.h b/util/dtc/dtc.h index a1a09e3838..c06b4dcbc3 100644 --- a/util/dtc/dtc.h +++ b/util/dtc/dtc.h @@ -166,6 +166,10 @@ struct node { int addr_cells, size_cells; char *label; + /* coreboot-specific */ + int linked; /* has this node been added to the links for a bridge? */ + struct node *linknode; /* If I am linked, which node is it? */ + int whichlink; /* which link of the node am I on? */ }; #define for_each_property(n, p) \ @@ -174,6 +178,10 @@ struct node { #define for_each_child(n, c) \ for ((c) = (n)->children; (c); (c) = (c)->next_sibling) +/* N.B.: includes ourselves */ +#define for_all_siblings(n, s) \ + for ((s) = (n->next_sibling); (s); (s) = (s)->next_sibling) + #define for_each_config(n, p) \ for ((p) = (n)->config; (p); (p) = (p)->next) diff --git a/util/dtc/flattree.c b/util/dtc/flattree.c index 6fb34b92c1..e0383e1a53 100644 --- a/util/dtc/flattree.c +++ b/util/dtc/flattree.c @@ -529,6 +529,31 @@ static void coreboot_emit_property(void *e, char *label) fprintf(f, "\tu32 p%d = \tOF_DT_PROP;\n", unique++); } +/* Is the node a bridge? + * If it has children, yes. + * OR if it has a config, if the config has + * the 'bridge' property, yes. + */ +static int is_bridge(struct node *tree) +{ + int bridge = 0; + struct property *prop; + /* simple test: does it have children? If so, it's a bridge */ + if (tree->children) + return 1; + if (tree->config){ + for_each_config(tree, prop) { + if (streq(prop->name, "bridge")){ + bridge = 1; + } + } + } + + return bridge; + +} + + static void coreboot_emit_special(FILE *e, struct node *tree) { FILE *f = e; @@ -538,6 +563,7 @@ static void coreboot_emit_special(FILE *e, struct node *tree) char *configname; char *path; int enabled = 1; + int linkcount = 0; fprintf(f, "struct device dev_%s = {\n", tree->label); /* special case -- the root has a distinguished path */ @@ -609,6 +635,10 @@ static void coreboot_emit_special(FILE *e, struct node *tree) if (streq(prop->name, "device_operations")){ fprintf(f, "\t.ops = &%s,\n", prop->val.val); } + if (streq(prop->name, "ops_pci_bus")){ + fprintf(f, "\t.ops_pci_bus = &%s,\n", clean((char *)prop->val.val, 0)); + ops_set = 1; + } } } /* Process the properties specified in the mainboard dts. @@ -661,23 +691,50 @@ static void coreboot_emit_special(FILE *e, struct node *tree) } if (tree->next_sibling) fprintf(f, "\t.sibling = &dev_%s,\n", tree->next_sibling->label); - /* now do we do next? */ - /* this will need to do a bus for every child. And, below, we're going to need to find which bus we're on*/ - /* for now, let's keep it to the minimum that will work, while we see if we like this. */ - if (tree->children){ - fprintf(f,"\t.links = 1,\n"); + + /* If we are a bridge, and we have not been linked, then set up our links. + * There is a good chance we could expand the for loop to contain this first bit of code. + * OTOH, the compiler can do it for us, and the initial conditions are clearer this way. + */ + if ((! tree->linked) && is_bridge(tree)){ + struct node *siblings; fprintf(f,"\t.link = {\n"); - fprintf(f,"\t\t[0] = {\n"); + fprintf(f,"\t\t[%d] = {\n", linkcount); fprintf(f,"\t\t\t.dev = &dev_%s,\n", tree->label); - fprintf(f,"\t\t\t.link = 0,\n"); - fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label); + fprintf(f,"\t\t\t.link = %d,\n", linkcount); + if (tree->children) + fprintf(f,"\t\t\t.children = &dev_%s\n", tree->children->label); fprintf(f,"\t\t},\n"); + /* now we need to handle our siblings. */ + linkcount++; + for_all_siblings(tree, siblings) { + if (is_bridge(siblings) && (!siblings->linked)){ + fprintf(f,"\t\t[%d] = {\n", linkcount); + fprintf(f,"\t\t\t.dev = &dev_%s,\n", siblings->label); + fprintf(f,"\t\t\t.link = %d,\n", linkcount); + if (siblings->children) { + fprintf(f,"\t\t\t.children = &dev_%s\n", siblings->children->label); + siblings->children->linked = 1; + siblings->children->linknode = tree; + siblings->children->whichlink = linkcount; + } + fprintf(f,"\t\t},\n"); + siblings->linked = 1; + siblings->whichlink = linkcount; + siblings->linknode = tree; + linkcount++; + } + } fprintf(f,"\t},\n"); } + fprintf(f,"\t.links = %d,\n", linkcount); /* fill in the 'bus I am on' entry */ - if (tree->parent) + /* being 'linked' on a bus overrides the parent link */ + if (tree->linked) + fprintf(f, "\t.bus = &dev_%s.link[%d],\n", tree->linknode->label, tree->whichlink); + else if (tree->parent) fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->parent->label); - else + else /* this is a very unusual case: the root */ fprintf(f, "\t.bus = &dev_%s.link[0],\n", tree->label); if (tree->next) @@ -784,6 +841,8 @@ fprintf(stderr, "LEFT OVER CONSTRUCTOR -- FIX ME\n"); } +char *emitted_names[256]; +int emitted_names_count = 0; static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emit, void *etarget, struct data *strbuf, struct version_info *vi) @@ -794,10 +853,24 @@ static void flatten_tree_emit_structdecls(struct node *tree, struct emitter *emi struct node *child; int seen_name_prop = 0; FILE *f = etarget; + int doconfig = 0; + int already_done = 0; if (tree->config){ + int i; // treename = clean(tree->label, 0); treename = toname(tree->config->label, "_config"); + for(i = 0; i < emitted_names_count; i++) + if (!strcmp(treename, emitted_names[i])) + already_done++; + if (! already_done) { + emitted_names[emitted_names_count++] = treename; + doconfig = 1; + } + } + + if (doconfig) { + emit->beginnode(etarget, treename);