Initial support for the Intel 82830 northbridge and RCA RM4100 board.

Signed-off-by: Joseph Smith <joe@smittys.pointclark.net>
Acked-by: Uwe Hermann <uwe@hermann-uwe.de>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3129 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Joseph Smith 2008-03-09 13:24:46 +00:00 committed by Uwe Hermann
parent c4f5365688
commit 6a1dc86005
16 changed files with 1604 additions and 0 deletions

View File

@ -0,0 +1,145 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
##
## 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
##
if USE_FALLBACK_IMAGE
default ROM_SECTION_SIZE = FALLBACK_SIZE
default ROM_SECTION_OFFSET = (ROM_SIZE - FALLBACK_SIZE)
else
default ROM_SECTION_SIZE = (ROM_SIZE - FALLBACK_SIZE)
default ROM_SECTION_OFFSET = 0
end
default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
default PAYLOAD_SIZE = (ROM_SECTION_SIZE - ROM_IMAGE_SIZE)
default _ROMBASE = (CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE)
default XIP_ROM_SIZE = 65536
default XIP_ROM_BASE = (_ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE)
arch i386 end
driver mainboard.o
if HAVE_PIRQ_TABLE object irq_tables.o end
# object reset.o
if HAVE_ACPI_TABLES
object fadt.o
object dsdt.o
object acpi_tables.o
end
makerule ./failover.E
depends "$(MAINBOARD)/../../../arch/i386/lib/failover.c ./romcc"
action "./romcc -E -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/../../../arch/i386/lib/failover.c -o $@"
end
makerule ./failover.inc
depends "$(MAINBOARD)/../../../arch/i386/lib/failover.c ./romcc"
action "./romcc -O --label-prefix=failover -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/../../../arch/i386/lib/failover.c -o $@"
end
makerule ./auto.E
# depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
depends "$(MAINBOARD)/auto.c ./romcc"
action "./romcc -E -mcpu=p3 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
makerule ./auto.inc
# depends "$(MAINBOARD)/auto.c option_table.h ./romcc"
depends "$(MAINBOARD)/auto.c ./romcc"
action "./romcc -mcpu=p3 -O -I$(TOP)/src -I. $(CPPFLAGS) $(MAINBOARD)/auto.c -o $@"
end
mainboardinit cpu/x86/16bit/entry16.inc
mainboardinit cpu/x86/32bit/entry32.inc
ldscript /cpu/x86/16bit/entry16.lds
ldscript /cpu/x86/32bit/entry32.lds
if USE_FALLBACK_IMAGE
mainboardinit cpu/x86/16bit/reset16.inc
ldscript /cpu/x86/16bit/reset16.lds
else
mainboardinit cpu/x86/32bit/reset32.inc
ldscript /cpu/x86/32bit/reset32.lds
end
mainboardinit arch/i386/lib/cpu_reset.inc
mainboardinit arch/i386/lib/id.inc
ldscript /arch/i386/lib/id.lds
if USE_FALLBACK_IMAGE
ldscript /arch/i386/lib/failover.lds
mainboardinit ./failover.inc
end
mainboardinit cpu/x86/fpu/enable_fpu.inc
mainboardinit cpu/x86/mmx/enable_mmx.inc
mainboardinit ./auto.inc
mainboardinit cpu/x86/mmx/disable_mmx.inc
dir /pc80
config chip.h
chip northbridge/intel/i82830 # Northbridge
device pci_domain 0 on # PCI domain
device pci 0.0 on end # Host bridge
chip drivers/pci/onboard # Onboard VGA
device pci 2.0 on end # VGA (Intel 82830 CGC)
register "rom_address" = "0xfff00000"
end
chip southbridge/intel/i82801xx # Southbridge
device pci 1d.0 on end # USB UHCI Controller #1
device pci 1d.1 on end # USB UHCI Controller #2
device pci 1d.2 on end # USB UHCI Controller #3
device pci 1d.7 on end # USB2 EHCI Controller
device pci 1e.0 on # PCI bridge
device pci 08.0 on end # Intel 82801DB PRO/100 VE Ethernet
end
device pci 1f.0 on # ISA/LPC bridge
chip superio/smsc/smscsuperio # Super I/O
device pnp 2e.0 off # Floppy
io 0x60 = 0x3f0
irq 0x70 = 6
drq 0x74 = 2
end
device pnp 2e.3 on # Parallel port
io 0x60 = 0x378
irq 0x70 = 7
drq 0x74 = 4
end
device pnp 2e.4 on # Com1
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.5 on # Com2 / IR
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.7 on # PS/2 keyboard/mouse
io 0x60 = 0x60
io 0x62 = 0x64
irq 0x70 = 1 # Keyboard interrupt
irq 0x72 = 12 # Mouse interrupt
end
device pnp 2e.9 off end # Game port
device pnp 2e.a on # PME
io 0x60 = 0x800
end
device pnp 2e.b off end # MPU-401
end
end
device pci 1f.1 on end # IDE
device pci 1f.3 on end # SMBus
device pci 1f.5 on end # AC'97 audio
device pci 1f.6 on end # AC'97 modem
end
end
device apic_cluster 0 on # APIC cluster
chip cpu/intel/socket_PGA370 # Mobile Celeron Micro-FCBGA Socket 479
device apic 0 on end # APIC
end
end
end

View File

@ -0,0 +1,95 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
##
## 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
##
uses CC
uses CONFIG_CONSOLE_SERIAL8250
uses CONFIG_CONSOLE_VGA
uses CONFIG_COMPRESSED_PAYLOAD_LZMA
uses CONFIG_IOAPIC
uses CONFIG_PCI_ROM_RUN
uses CONFIG_ROM_PAYLOAD
uses CONFIG_ROM_PAYLOAD_START
uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
uses CONFIG_UDELAY_TSC
uses CONFIG_VIDEO_MB
uses CROSS_COMPILE
uses DEFAULT_CONSOLE_LOGLEVEL
uses FALLBACK_SIZE
uses HAVE_ACPI_TABLES
uses HAVE_FALLBACK_BOOT
uses HAVE_MP_TABLE
uses HAVE_OPTION_TABLE
uses HAVE_PIRQ_TABLE
uses HEAP_SIZE
uses HOSTCC
uses IRQ_SLOT_COUNT
uses COREBOOT_EXTRA_VERSION
uses MAINBOARD
uses MAINBOARD_VENDOR
uses MAINBOARD_PART_NUMBER
uses MAXIMUM_CONSOLE_LOGLEVEL
uses OBJCOPY
uses PAYLOAD_SIZE
uses _RAMBASE
uses _ROMBASE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_SIZE
uses ROM_SECTION_OFFSET
uses ROM_SIZE
uses STACK_SIZE
uses TTYS0_BASE
uses TTYS0_BAUD
uses TTYS0_LCS
uses USE_FALLBACK_IMAGE
uses USE_OPTION_TABLE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
default ROM_SIZE = 512 * 1024
default ROM_IMAGE_SIZE = 128 * 1024
default HAVE_FALLBACK_BOOT = 1
default FALLBACK_SIZE = 512 * 1024
default CONFIG_UDELAY_TSC = 1
default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 = 1
default HAVE_PIRQ_TABLE = 1
default IRQ_SLOT_COUNT = 10
default HAVE_MP_TABLE = 0
default HAVE_ACPI_TABLES = 0
default CONFIG_IOAPIC = 0
default HAVE_OPTION_TABLE = 0
default CONFIG_CONSOLE_VGA = 0
default CONFIG_PCI_ROM_RUN = 0
default CONFIG_VIDEO_MB = 0
default STACK_SIZE = 0x2000
default HEAP_SIZE = 0x4000
default _RAMBASE = 0x00004000
default USE_OPTION_TABLE = 0
default CONFIG_ROM_PAYLOAD = 1
default CC="$(CROSS_COMPILE)gcc -m32"
default HOSTCC="gcc"
default CONFIG_CONSOLE_SERIAL8250 = 1
default TTYS0_BAUD = 115200
default TTYS0_BASE = 0x3f8
default TTYS0_LCS = 0x3 # 8n1
default DEFAULT_CONSOLE_LOGLEVEL = 9
default MAXIMUM_CONSOLE_LOGLEVEL = 9
default MAINBOARD_VENDOR = "RCA"
default MAINBOARD_PART_NUMBER = "RM4100"
end

View File

@ -0,0 +1,136 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 ASSEMBLY 1
#include <stdint.h>
#include <stdlib.h>
#include <device/pci_def.h>
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <arch/hlt.h>
#include "pc80/serial.c"
#include "pc80/udelay_io.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "superio/smsc/smscsuperio/smscsuperio_early_serial.c"
#include "northbridge/intel/i82830/raminit.h"
#include "southbridge/intel/i82801xx/i82801xx.h"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#include "spd_table.h"
#include "gpio.c"
#define SERIAL_DEV PNP_DEV(0x2e, SMSCSUPERIO_SP1)
#include "southbridge/intel/i82801xx/i82801xx_early_smbus.c"
/**
* The onboard 128MB PC133 memory does not have a SPD EEPROM so the
* values have to be set manually, the SO-DIMM socket is located in
* socket0 (0x50), and the onboard memory is located in socket1 (0x51).
*/
static inline int spd_read_byte(unsigned device, unsigned address)
{
int i;
if (device == 0x50) {
return smbus_read_byte(device, address);
} else if (device == 0x51) {
for (i = 0; i < ARRAY_SIZE(spd_table); i++) {
if (spd_table[i].address == address)
return spd_table[i].data;
}
return 0xFF; /* Return 0xFF when address is not found. */
} else {
return 0xFF; /* Return 0xFF on any failures. */
}
}
#include "northbridge/intel/i82830/raminit.c"
#include "sdram/generic_sdram.c"
/**
* We have to disable the TCO Timer system reboot feature
* or we get several reboots through out the boot processes.
*/
static void disable_tco_timer(void)
{
device_t dev;
u8 reg8;
/* Set the LPC device statically. */
dev = PCI_DEV(0x0, 0x1f, 0x0);
/* Disable the TCO Timer system reboot feature. */
reg8 = pci_read_config8(dev, 0xd4);
reg8 |= (1 << 1);
pci_write_config8(dev, 0xd4, reg8);
}
/**
* The AC'97 Audio Controller I/O space registers are read only by default
* so we need to enable them by setting register 0x41 to 0x01.
*/
static void ac97_io_enable(void)
{
device_t dev;
/* Set the ac97 audio device staticly. */
dev = PCI_DEV(0x0, 0x1f, 0x5);
/* Enable access to the IO space. */
pci_write_config8(dev, 0x41, 0x01);
}
static void main(unsigned long bist)
{
static const struct mem_controller memctrl[] = {
{
.d0 = PCI_DEV(0, 0, 0),
.channel0 = {0x50, 0x51},
}
};
if (bist == 0)
early_mtrr_init();
enable_smbus();
smscsuperio_enable_serial(SERIAL_DEV, TTYS0_BASE);
mb_gpio_init();
uart_init();
console_init();
/* Halt if there was a built in self test failure. */
report_bist_failure(bist);
sdram_set_registers(memctrl);
sdram_set_spd_registers(memctrl);
sdram_enable(0, memctrl);
/* Check RAM. */
/* ram_check(0, 640 * 1024); */
/* ram_check(130048 * 1024, 131072 * 1024); */
disable_tco_timer();
ac97_io_enable();
}

View File

@ -0,0 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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
*/
extern struct chip_operations mainboard_rca_rm4100_ops;
struct mainboard_rca_rm4100_config {
int nothing;
};

View File

@ -0,0 +1,120 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 PME_DEV PNP_DEV(0x2e, 0x0a)
#define PME_IO_BASE_ADDR 0x800 /* Runtime register base address */
#define ICH_IO_BASE_ADDR 0x00000500 /* GPIO base address register */
/* Early mainboard specific GPIO setup. */
static void mb_gpio_init(void)
{
device_t dev;
uint16_t port;
uint32_t set_gpio;
/* Southbridge GPIOs. */
/* Set the LPC device statically. */
dev = PCI_DEV(0x0, 0x1f, 0x0);
/* Set the value for GPIO base address register and enable GPIO. */
pci_write_config32(dev, GPIO_BASE_ICH0_5, (ICH_IO_BASE_ADDR | 1));
pci_write_config8(dev, GPIO_CNTL_ICH0_5, 0x10);
/* Set GPIO25 to input and drive GPIO23 to high,
* this enables the LAN controller.
*/
udelay(10);
set_gpio = 0x0000ffff;
set_gpio |= 1 << 25;
outl(set_gpio, ICH_IO_BASE_ADDR + 0x04);
set_gpio = 0x1b3f0000;
set_gpio |= 1 << 23;
outl(set_gpio, ICH_IO_BASE_ADDR + 0x0c);
/* Super I/O GPIOs. */
dev = PME_DEV;
port = dev >> 8;
outb(0x55, port); /* Enter the configuration state. */
pnp_set_logical_device(dev);
pnp_set_enable(dev, 0);
pnp_set_iobase(dev, PNP_IDX_IO0, PME_IO_BASE_ADDR);
pnp_set_enable(dev, 1);
outl(0x03, PME_IO_BASE_ADDR + 0x1e); /* Force Disk Change */
outl(0x02, PME_IO_BASE_ADDR + 0x1f); /* Floppy Data Rate */
outl(0x81, PME_IO_BASE_ADDR + 0x20); /* UART1 FIFO */
outl(0x00, PME_IO_BASE_ADDR + 0x21); /* UART2 FIFO */
outl(0x00, PME_IO_BASE_ADDR + 0x22); /* Device Disable */
outl(0x01, PME_IO_BASE_ADDR + 0x23); /* GP10 */
outl(0x01, PME_IO_BASE_ADDR + 0x24); /* GP11 */
outl(0x01, PME_IO_BASE_ADDR + 0x25); /* GP12 */
outl(0x01, PME_IO_BASE_ADDR + 0x26); /* GP13 */
outl(0x01, PME_IO_BASE_ADDR + 0x27); /* GP14 */
outl(0x01, PME_IO_BASE_ADDR + 0x28); /* GP15 */
outl(0x01, PME_IO_BASE_ADDR + 0x29); /* GP16 */
outl(0x01, PME_IO_BASE_ADDR + 0x2a); /* GP17 */
outl(0x01, PME_IO_BASE_ADDR + 0x2b); /* GP20 */
outl(0x01, PME_IO_BASE_ADDR + 0x2c); /* GP21 */
outl(0x01, PME_IO_BASE_ADDR + 0x2d); /* GP22 */
outl(0x01, PME_IO_BASE_ADDR + 0x2f); /* GP24 */
outl(0x01, PME_IO_BASE_ADDR + 0x30); /* GP25 */
outl(0x01, PME_IO_BASE_ADDR + 0x31); /* GP26 */
outl(0x01, PME_IO_BASE_ADDR + 0x32); /* GP27 */
outl(0x05, PME_IO_BASE_ADDR + 0x33); /* GP30 */
outl(0x05, PME_IO_BASE_ADDR + 0x34); /* GP31 */
outl(0x00, PME_IO_BASE_ADDR + 0x35); /* GP32 */
outl(0x00, PME_IO_BASE_ADDR + 0x36); /* GP33 */
outl(0x00, PME_IO_BASE_ADDR + 0x37); /* GP34 */
outl(0x04, PME_IO_BASE_ADDR + 0x38); /* GP35 */
outl(0x01, PME_IO_BASE_ADDR + 0x39); /* GP36 */
outl(0x01, PME_IO_BASE_ADDR + 0x3a); /* GP37 */
outl(0x01, PME_IO_BASE_ADDR + 0x3b); /* GP40 */
outl(0x01, PME_IO_BASE_ADDR + 0x3c); /* GP41 */
outl(0x86, PME_IO_BASE_ADDR + 0x3d); /* GP42 */
outl(0x01, PME_IO_BASE_ADDR + 0x3e); /* GP43 */
outl(0x05, PME_IO_BASE_ADDR + 0x3f); /* GP50 */
outl(0x05, PME_IO_BASE_ADDR + 0x40); /* GP51 */
outl(0x05, PME_IO_BASE_ADDR + 0x41); /* GP52 */
outl(0x04, PME_IO_BASE_ADDR + 0x42); /* GP53 */
outl(0x05, PME_IO_BASE_ADDR + 0x43); /* GP54 */
outl(0x04, PME_IO_BASE_ADDR + 0x44); /* GP55 */
outl(0x05, PME_IO_BASE_ADDR + 0x45); /* GP56 */
outl(0x04, PME_IO_BASE_ADDR + 0x46); /* GP57 */
outl(0x01, PME_IO_BASE_ADDR + 0x47); /* GP58 */
outl(0x01, PME_IO_BASE_ADDR + 0x48); /* GP59 */
outl(0x00, PME_IO_BASE_ADDR + 0x4b); /* GP1 */
outl(0x04, PME_IO_BASE_ADDR + 0x4c); /* GP2 */
outl(0xc0, PME_IO_BASE_ADDR + 0x4d); /* GP3 */
outl(0x00, PME_IO_BASE_ADDR + 0x4e); /* GP4 */
outl(0x07, PME_IO_BASE_ADDR + 0x4f); /* GP5 */
outl(0x00, PME_IO_BASE_ADDR + 0x50); /* GP6 */
outl(0x00, PME_IO_BASE_ADDR + 0x56); /* FAN1 */
outl(0x00, PME_IO_BASE_ADDR + 0x57); /* FAN2 */
outl(0x50, PME_IO_BASE_ADDR + 0x58); /* Fan Control */
outl(0xff, PME_IO_BASE_ADDR + 0x59); /* Fan1 Tachometer */
outl(0xff, PME_IO_BASE_ADDR + 0x5a); /* Fan2 Tachometer */
outl(0x00, PME_IO_BASE_ADDR + 0x5b); /* Fan1 Preload */
outl(0x00, PME_IO_BASE_ADDR + 0x5c); /* Fan2 Preload */
outl(0x00, PME_IO_BASE_ADDR + 0x5d); /* LED1 */
outl(0x00, PME_IO_BASE_ADDR + 0x5e); /* LED2 */
outl(0x00, PME_IO_BASE_ADDR + 0x5f); /* Keyboard Scan Code */
outb(0xaa, port); /* Exit the configuration state. */
}

View File

@ -0,0 +1,53 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*IRQ_SLOT_COUNT, /* there can be total 10 devices on the bus */
0x00, /* Where the interrupt router lies (bus) */
(0x1f<<3)|0x0, /* Where the interrupt router lies (dev) */
0, /* IRQs devoted exclusively to PCI usage */
0x8086, /* Vendor */
0x24c0, /* Device */
0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x14, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
/* bus, dev|fn, {link, bitmap}, {link, bitmap}, {link, bitmap}, {link, bitmap}, slot, rfu */
{0x00,(0x1d<<3)|0x0, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x01ef8}}, 0x0, 0x0}, /* [A] USB UHCI Controller #1 */
{0x00,(0x1d<<3)|0x1, {{0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}, {0x60, 0x01ef8}}, 0x0, 0x0}, /* [B] USB UHCI Controller #2 */
{0x00,(0x1d<<3)|0x2, {{0x62, 0x1ef8}, {0x63, 0x1ef8}, {0x60, 0x1ef8}, {0x61, 0x01ef8}}, 0x0, 0x0}, /* [C] USB UHCI Controller #3 */
{0x00,(0x1d<<3)|0x7, {{0x63, 0x1ef8}, {0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x01ef8}}, 0x0, 0x0}, /* [D] USB2 EHCI Controller */
{0x00,(0x1f<<3)|0x1, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x01ef8}}, 0x0, 0x0}, /* [A] IDE Controller */
{0x00,(0x1f<<3)|0x3, {{0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}, {0x60, 0x01ef8}}, 0x0, 0x0}, /* [B] SMBus Controller */
{0x00,(0x02<<3)|0x0, {{0x60, 0x1ef8}, {0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x01ef8}}, 0x0, 0x0}, /* [A] VGA compatible controller */
{0x00,(0x1f<<3)|0x5, {{0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}, {0x60, 0x01ef8}}, 0x0, 0x0}, /* [B] AC'97 Audio Controller */
{0x01,(0x08<<3)|0x0, {{0x68, 0x1ef8}, {0x00, 0x0000}, {0x00, 0x0000}, {0x00, 0x00000}}, 0x0, 0x0}, /* [A] Ethernet controller */
{0x00,(0x1f<<3)|0x6, {{0x61, 0x1ef8}, {0x62, 0x1ef8}, {0x63, 0x1ef8}, {0x64, 0x01ef8}}, 0x0, 0x0}, /* [B] AC'97 Modem Controller */
}
};
unsigned long write_pirq_routing_table(unsigned long addr)
{
return copy_pirq_routing_table(addr);
}

View File

@ -0,0 +1,26 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 <device/device.h>
#include "chip.h"
struct chip_operations mainboard_rca_rm4100_ops = {
CHIP_NAME("RCA RM4100 Mainboard")
};

View File

@ -0,0 +1,40 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 <spd.h>
struct spd_entry {
unsigned int address;
unsigned int data;
};
/*
* The onboard 128MB PC133 memory does not have an SPD EEPROM so the values
* have to be set manually, the onboard memory is located in socket1 (0x51).
*/
const struct spd_entry spd_table [] = {
{SPD_MEMORY_TYPE, 0x04}, /* (Fundamental) memory type */
{SPD_NUM_COLUMNS, 0x09}, /* Number of column address bits */
{SPD_NUM_DIMM_BANKS, 0x01}, /* Number of module rows (banks) */
{SPD_MODULE_DATA_WIDTH_LSB, 0x40}, /* Module data width (LSB) */
{SPD_MIN_CYCLE_TIME_AT_CAS_MAX, 0x75}, /* SDRAM cycle time (highest CAS latency), RAS access time (tRAC) */
{SPD_ACCESS_TIME_FROM_CLOCK, 0x54}, /* SDRAM access time from clock (highest CAS latency), CAS access time (Tac, tCAC) */
{SPD_DENSITY_OF_EACH_ROW_ON_MODULE, 0x20}, /* Density of each row on module */
};

View File

@ -0,0 +1,22 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
##
## 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
##
config chip.h
object northbridge.o

View File

@ -0,0 +1,24 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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
*/
struct northbridge_intel_i82830_config {
};
extern struct chip_operations northbridge_intel_i82830_ops;

View File

@ -0,0 +1,66 @@
static void print_debug_pci_dev(unsigned dev)
{
print_debug("PCI: ");
print_debug_hex8((dev >> 16) & 0xff);
print_debug_char(':');
print_debug_hex8((dev >> 11) & 0x1f);
print_debug_char('.');
print_debug_hex8((dev >> 8) & 7);
}
static void print_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
print_debug_pci_dev(dev);
print_debug("\r\n");
}
}
static void dump_pci_device(unsigned dev)
{
int i;
print_debug_pci_dev(dev);
print_debug("\r\n");
for(i = 0; i <= 255; i++) {
unsigned char val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = pci_read_config8(dev, i);
print_debug_char(' ');
print_debug_hex8(val);
if ((i & 0x0f) == 0x0f) {
print_debug("\r\n");
}
}
}
static void dump_pci_devices(void)
{
device_t dev;
for(dev = PCI_DEV(0, 0, 0);
dev <= PCI_DEV(0, 0x1f, 0x7);
dev += PCI_DEV(0,0,1)) {
uint32_t id;
id = pci_read_config32(dev, PCI_VENDOR_ID);
if (((id & 0xffff) == 0x0000) || ((id & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0xffff) ||
(((id >> 16) & 0xffff) == 0x0000)) {
continue;
}
dump_pci_device(dev);
}
}

View File

@ -0,0 +1,52 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 RRBAR 0x48 /* Register Range Base Address (0x00000000) */
#define GCC0 0x50 /* GMCH Control #0 (0xa072) */
#define GCC1 0x52 /* GMCH Control #1 (0x0000) */
#define FDHC 0x58 /* Fixed DRAM Hole Control (0x00) */
#define PAM0 0x59 /* Programable Attribute Map #0 (0x00) */
#define PAM1 0x5a /* Programable Attribute Map #1 (0x00) */
#define PAM2 0x5b /* Programable Attribute Map #2 (0x00) */
#define PAM3 0x5c /* Programable Attribute Map #3 (0x00) */
#define PAM4 0x5d /* Programable Attribute Map #4 (0x00) */
#define PAM5 0x5e /* Programable Attribute Map #5 (0x00) */
#define PAM6 0x5f /* Programable Attribute Map #6 (0x00) */
#define DRB 0x60 /* DRAM Row Boundary #0 (0x00) */
#define DRB1 0x61 /* DRAM Row Boundary #1 (0x00) */
#define DRB2 0x62 /* DRAM Row Boundary #2 (0x00) */
#define DRB3 0x63 /* DRAM Row Boundary #3 (0x00) */
#define DRA 0x70 /* DRAM Row Attribute #0 (0xff) */
#define DRA1 0x71 /* DRAM Row Attribute #1 (0xff) */
#define DRT 0x78 /* DRAM Timing (0x00000010) */
#define DRC 0x7c /* DRAM Controller Mode #0 (0x00000000) */
#define DRC1 0x7d /* DRAM Controller Mode #1 (0x00000000) */
#define DRC2 0x7e /* DRAM Controller Mode #2 (0x00000000) */
#define DRC3 0x7f /* DRAM Controller Mode #3 (0x00000000) */
#define DTC 0x8c /* DRAM Throttling Control (0x00000000) */
#define SMRAM 0x90 /* System Management RAM Control (0x02) */
#define ESMRAMC 0x91 /* Extended System Management RAM Control Reg. (0x38) */
#define ERRSTS 0x92 /* Error Status (0x0000) */
#define ERRCMD 0x94 /* Error Command (0x0000) */
#define BUFF_SC 0xec /* System Memory Buffer Strength Control (0x00000000) */
#define APBASE 0x10 /* Aperture Base Configuration (0x00000008) */
#define APSIZE 0xb4 /* Apterture Size (0x00) */
#define ATTBASE 0xb8 /* Aperture Translation Table Base (0x00000000) */

View File

@ -0,0 +1,197 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 <console/console.h>
#include <arch/io.h>
#include <stdint.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include "chip.h"
#include "i82830.h"
static void northbridge_init(device_t dev)
{
printk_spew("Northbridge init\n");
}
static struct device_operations northbridge_operations = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = northbridge_init,
.enable = 0,
.ops_pci = 0,
};
static struct pci_driver northbridge_driver __pci_driver = {
.ops = &northbridge_operations,
.vendor = PCI_VENDOR_ID_INTEL,
.device = 0x3575,
};
#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
static void pci_domain_read_resources(device_t dev)
{
struct resource *resource;
/* Initialize the system wide I/O space constraints. */
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
resource->limit = 0xffffUL;
resource->flags =
IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
/* Initialize the system wide memory resources constraints. */
resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
resource->limit = 0xffffffffULL;
resource->flags =
IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
}
static void ram_resource(device_t dev, unsigned long index,
unsigned long basek, unsigned long sizek)
{
struct resource *resource;
if (!sizek)
return;
resource = new_resource(dev, index);
resource->base = ((resource_t) basek) << 10;
resource->size = ((resource_t) sizek) << 10;
resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE |
IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
}
static void tolm_test(void *gp, struct device *dev, struct resource *new)
{
struct resource **best_p = gp;
struct resource *best;
best = *best_p;
if (!best || (best->base > new->base))
best = new;
*best_p = best;
}
static uint32_t find_pci_tolm(struct bus *bus)
{
struct resource *min;
uint32_t tolm;
min = 0;
search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test,
&min);
tolm = 0xffffffffUL;
if (min && tolm > min->base)
tolm = min->base;
return tolm;
}
static void pci_domain_set_resources(device_t dev)
{
device_t mc_dev;
uint32_t pci_tolm;
int igd_memory = 0;
pci_tolm = find_pci_tolm(&dev->link[0]);
mc_dev = dev->link[0].children;
if (mc_dev) {
unsigned long tomk, tolmk;
int idx;
if (CONFIG_VIDEO_MB == 512) {
igd_memory = (CONFIG_VIDEO_MB);
} else {
igd_memory = (CONFIG_VIDEO_MB * 1024);
}
/* Get the value of the highest DRB. This tells the end of
* the physical memory. The units are ticks of 32MB
* i.e. 1 means 32MB.
*/
tomk = ((unsigned long)pci_read_config8(mc_dev, DRB + 3)) << 15;
tomk -= igd_memory;
printk_debug("Setting RAM size to %d\n", tomk);
/* Compute the top of low memory. */
tolmk = pci_tolm >> 10;
if (tolmk >= tomk) {
/* The PCI hole does does not overlap the memory. */
tolmk = tomk;
}
/* Report the memory regions. */
idx = 10;
ram_resource(dev, idx++, 0, 640);
ram_resource(dev, idx++, 1024, tolmk - 1024);
}
assign_resources(&dev->link[0]);
}
static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
{
max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
return max;
}
static struct device_operations pci_domain_ops = {
.read_resources = pci_domain_read_resources,
.set_resources = pci_domain_set_resources,
.enable_resources = enable_childrens_resources,
.init = 0,
.scan_bus = pci_domain_scan_bus,
};
static void cpu_bus_init(device_t dev)
{
initialize_cpus(&dev->link[0]);
}
static void cpu_bus_noop(device_t dev)
{
}
static struct device_operations cpu_bus_ops = {
.read_resources = cpu_bus_noop,
.set_resources = cpu_bus_noop,
.enable_resources = cpu_bus_noop,
.init = cpu_bus_init,
.scan_bus = 0,
};
static void enable_dev(struct device *dev)
{
struct device_path;
/* Set the operations if it is a special bus type. */
if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
dev->ops = &pci_domain_ops;
pci_set_method(dev);
} else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
dev->ops = &cpu_bus_ops;
}
}
struct chip_operations northbridge_intel_i82830_ops = {
CHIP_NAME("Intel 82830 Northbridge")
.enable_dev = enable_dev,
};

View File

@ -0,0 +1,508 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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 <spd.h>
#include <sdram_mode.h>
#include <delay.h>
#include "debug.c"
#include "i82830.h"
/*-----------------------------------------------------------------------------
Macros and definitions.
-----------------------------------------------------------------------------*/
/* Uncomment this to enable debugging output. */
/* #define DEBUG_RAM_SETUP 1 */
/* Debugging macros. */
#if defined(DEBUG_RAM_SETUP)
#define PRINT_DEBUG(x) print_debug(x)
#define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
#define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
#define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
#else
#define PRINT_DEBUG(x)
#define PRINT_DEBUG_HEX8(x)
#define PRINT_DEBUG_HEX16(x)
#define PRINT_DEBUG_HEX32(x)
#define DUMPNORTH()
#endif
/* DRC[10:8] - Refresh Mode Select (RMS).
* 0x0 for Refresh Disabled (Self Refresh)
* 0x1 for Refresh interval 15.6 us for 133MHz
* 0x2 for Refresh interval 7.8 us for 133MHz
* 0x7 /* Refresh interval 128 Clocks. (Fast Refresh Mode)
*/
#define RAM_COMMAND_REFRESH 0x2
/* DRC[6:4] - SDRAM Mode Select (SMS). */
#define RAM_COMMAND_SELF_REFRESH 0x0
#define RAM_COMMAND_NOP 0x1
#define RAM_COMMAND_PRECHARGE 0x2
#define RAM_COMMAND_MRS 0x3
#define RAM_COMMAND_CBR 0x6
#define RAM_COMMAND_NORMAL 0x7
/* DRC[29] - Initialization Complete (IC). */
#define RAM_COMMAND_IC 0x1
/*-----------------------------------------------------------------------------
SDRAM configuration functions.
-----------------------------------------------------------------------------*/
/* Send the specified RAM command to all DIMMs. */
static void do_ram_command(const struct mem_controller *ctrl, uint32_t command,
uint32_t addr_offset)
{
int i;
uint8_t reg8, reg8_2 = 0;
uint32_t reg32;
/* Configure the RAM command. */
reg32 = pci_read_config32(ctrl->d0, DRC);
/* Clear bits 29, 10-8, 6-4. */
reg32 &= 0xdffff88f;
reg32 |= command << 4;
/* If RAM_COMMAND_NORMAL set the refresh mode and IC bit. */
if (command == RAM_COMMAND_NORMAL)
reg32 |= ((RAM_COMMAND_REFRESH << 8) | (RAM_COMMAND_IC << 29));
pci_write_config32(ctrl->d0, DRC, reg32);
/* RAM_COMMAND_NORMAL affects only the memory controller and
doesn't need to be "sent" to the DIMMs. */
/* if (command == RAM_COMMAND_NORMAL) return; */
PRINT_DEBUG(" Sending RAM command 0x");
PRINT_DEBUG_HEX32(reg32);
PRINT_DEBUG(" to 0x");
PRINT_DEBUG_HEX32(0 + addr_offset);
PRINT_DEBUG("\r\n");
/* NOTE: Dual-sided ready. */
read32(0 + addr_offset);
for (i = 0; i < 4; i++) {
reg8 = pci_read_config8(ctrl->d0, DRB + i);
if (reg8 != reg8_2)
read32(reg8 * 32 * 1024 * 1024);
reg8_2 = reg8;
}
}
/*-----------------------------------------------------------------------------
DIMM-independant configuration functions.
-----------------------------------------------------------------------------*/
struct dimm_size {
unsigned long side1;
unsigned long side2;
};
static struct dimm_size spd_get_dimm_size(unsigned device)
{
struct dimm_size sz;
int i, module_density, dimm_banks;
sz.side1 = 0;
module_density = spd_read_byte(device, 31);
dimm_banks = spd_read_byte(device, 5);
/* Find the size of side1. */
/* Find the larger value. The larger value is always side1. */
for (i = 512; i >= 0; i >>= 1) {
if ((module_density & i) == i) {
sz.side1 = i;
break;
}
}
/* Set to 0 in case it's single sided. */
sz.side2 = 0;
/* Test if it's a dual-sided DIMM. */
if (dimm_banks > 1) {
/* Test to see if there's a second value, if so it's asymmetrical. */
if (module_density != i) {
/* Find the second value, picking up where we left off. */
/* i >>= 1 done initially to make sure we don't get the same value again. */
for (i >>= 1; i >= 0; i >>= 1) {
if (module_density == (sz.side1 | i)) {
sz.side2 = i;
break;
}
}
/* If not, it's symmetrical */
} else {
sz.side2 = sz.side1;
}
}
/* SPD byte 31 is the memory size divided by 4 so we
* need to muliply by 4 to get the total size.
*/
sz.side1 *= 4;
sz.side2 *= 4;
return sz;
}
static void spd_set_dram_size(const struct mem_controller *ctrl)
{
int i, value, drb1, drb2;
for (i = 0; i < DIMM_SOCKETS; i++) {
struct dimm_size sz;
unsigned device;
device = ctrl->channel0[i];
drb1 = 0;
drb2 = 0;
/* First check if a DIMM is actually present. */
if (spd_read_byte(device, 2) == 0x4) {
print_debug("Found DIMM in slot ");
print_debug_hex8(i);
print_debug("\r\n");
sz = spd_get_dimm_size(device);
/* WISHLIST: would be nice to display it as decimal? */
print_debug("DIMM is 0x");
print_debug_hex16(sz.side1);
print_debug(" on side 1\r\n");
print_debug("DIMM is 0x");
print_debug_hex16(sz.side2);
print_debug(" on side 2\r\n");
/* Test for PC133 (i82830 only supports PC133) */
/* PC133 SPD9 - cycle time is always 75 */
if (spd_read_byte(device, 9) != 0x75) {
print_err("SPD9 DIMM Is Not PC133 Compatable\r\n");
die("HALT\r\n");
}
/* PC133 SPD10 - access time is always 54 */
if (spd_read_byte(device, 10) != 0x54) {
print_err("SPD10 DIMM Is Not PC133 Compatable\r\n");
die("HALT\r\n");
}
/* The i82830 only supports a symmetrical dual-sided dimms
* and can't handle DIMMs smaller than 32MB per
* side or larger than 256MB per side.
*/
if ((sz.side2 != 0) && (sz.side1 != sz.side2)) {
print_err("This northbridge only supports\r\n");
print_err("symmetrical dual-sided DIMMs\r\n");
print_err("booting as a single-sided DIMM\r\n");
sz.side2 = 0;
}
if ((sz.side1 < 32)) {
print_err("DIMMs smaller than 32MB per side\r\n");
print_err("are not supported on this northbridge\r\n");
die("HALT\r\n");
}
if ((sz.side1 > 256)) {
print_err
("DIMMs larger than 256MB per side\r\n");
print_err
("are not supported on this northbridge\r\n");
die("HALT\r\n");
}
/* We need to divide size by 32 to set up the
* DRB registers.
*/
if (sz.side1)
drb1 = sz.side1 / 32;
if (sz.side2)
drb2 = sz.side2 / 32;
} else {
PRINT_DEBUG("No DIMM found in slot ");
PRINT_DEBUG_HEX8(i);
PRINT_DEBUG("\r\n");
/* If there's no DIMM in the slot, set value to 0. */
drb1 = 0;
drb2 = 0;
}
/* Set the value for DRAM Row Boundary Registers */
if (i == 0) {
pci_write_config8(ctrl->d0, DRB, drb1);
pci_write_config8(ctrl->d0, DRB + 1, drb1 + drb2);
PRINT_DEBUG("DRB 0x");
PRINT_DEBUG_HEX8(DRB);
PRINT_DEBUG(" has been set to 0x");
PRINT_DEBUG_HEX8(drb1);
PRINT_DEBUG("\r\n");
PRINT_DEBUG("DRB1 0x");
PRINT_DEBUG_HEX8(DRB + 1);
PRINT_DEBUG(" has been set to 0x");
PRINT_DEBUG_HEX8(drb1 + drb2);
PRINT_DEBUG("\r\n");
} else if (i == 1) {
value = pci_read_config8(ctrl->d0, DRB + 1);
pci_write_config8(ctrl->d0, DRB + 2, value + drb1);
pci_write_config8(ctrl->d0, DRB + 3,
value + drb1 + drb2);
PRINT_DEBUG("DRB2 0x");
PRINT_DEBUG_HEX8(DRB + 2);
PRINT_DEBUG(" has been set to 0x");
PRINT_DEBUG_HEX8(value + drb1);
PRINT_DEBUG("\r\n");
PRINT_DEBUG("DRB3 0x");
PRINT_DEBUG_HEX8(DRB + 3);
PRINT_DEBUG(" has been set to 0x");
PRINT_DEBUG_HEX8(value + drb1 + drb2);
PRINT_DEBUG("\r\n");
/* We need to set the highest DRB value to 0x64 and 0x65.
* These are supposed to be "Reserved" but memory will
* not initialize properly if we don't.
*/
value = pci_read_config8(ctrl->d0, DRB + 3);
pci_write_config8(ctrl->d0, DRB + 4, value);
pci_write_config8(ctrl->d0, DRB + 5, value);
}
}
}
static void set_dram_row_attributes(const struct mem_controller *ctrl)
{
int i, dra, col, width, value;
for (i = 0; i < DIMM_SOCKETS; i++) {
unsigned device;
device = ctrl->channel0[i];
/* First check if a DIMM is actually present. */
if (spd_read_byte(device, 2) == 0x4) {
print_debug("Found DIMM in slot ");
print_debug_hex8(i);
print_debug(", setting DRA...\r\n");
dra = 0x00;
/* columns */
col = spd_read_byte(device, 4);
/* data width */
width = spd_read_byte(device, 6);
/* calculate page size in bits */
value = ((1 << col) * width);
/* convert to Kilobytes */
dra = ((value / 8) >> 10);
/* # of banks of DIMM (single or double sided) */
value = spd_read_byte(device, 5);
if (value == 1) {
switch (dra) {
case 2: /* 2KB */
dra = 0xF0;
break;
case 4: /* 4KB */
dra = 0xF1;
break;
case 8: /* 8KB */
dra = 0xF2;
break;
case 16: /* 16KB */
dra = 0xF3;
break;
default:
print_err("Page size not supported\r\n");
die("HALT\r\n");
}
} else if (value == 2) {
switch (dra) {
case 2: /* 2KB */
dra = 0x00;
break;
case 4: /* 4KB */
dra = 0x11;
break;
case 8: /* 8KB */
dra = 0x22;
break;
case 16: /* 16KB */
dra = 0x33;
break;
default:
print_err("Page size not supported\r\n");
die("HALT\r\n");
}
} else {
print_err("# of banks of DIMM not supported\r\n");
die("HALT\r\n");
}
} else {
PRINT_DEBUG("No DIMM found in slot ");
PRINT_DEBUG_HEX8(i);
PRINT_DEBUG(", setting DRA to 0xFF\r\n");
/* If there's no DIMM in the slot, set dra value to 0xFF. */
dra = 0xFF;
}
/* Set the value for DRAM Row Attribute Registers */
pci_write_config8(ctrl->d0, DRA + i, dra);
PRINT_DEBUG("DRA 0x");
PRINT_DEBUG_HEX8(DRA + i);
PRINT_DEBUG(" has been set to 0x");
PRINT_DEBUG_HEX8(dra);
PRINT_DEBUG("\r\n");
}
}
static void set_dram_timing(const struct mem_controller *ctrl)
{
/* Set the value for DRAM Timing Register */
/* TODO: Configure the value according to SPD values. */
pci_write_config32(ctrl->d0, DRT, 0x00000010);
}
static void set_dram_buffer_strength(const struct mem_controller *ctrl)
{
/* TODO: This needs to be set according to the DRAM tech
* (x8, x16, or x32). Argh, Intel provides no docs on this!
* Currently, it needs to be pulled from the output of
* lspci -xxx Rx92
*/
/* Set the value for System Memory Buffer Strength Control Registers */
pci_write_config32(ctrl->d0, BUFF_SC, 0xFC9B491B);
}
/*-----------------------------------------------------------------------------
Public interface.
-----------------------------------------------------------------------------*/
static void sdram_set_registers(const struct mem_controller *ctrl)
{
uint16_t value;
int igd_memory = 0;
PRINT_DEBUG("Setting initial registers....\r\n");
/* Set the value for GMCH Control Register #0 */
pci_write_config16(ctrl->d0, GCC0, 0xA072);
/* Set the value for GMCH Control Register #1 */
switch (CONFIG_VIDEO_MB) {
case 512: /* 512K of memory */
igd_memory = 0x2;
break;
case 1: /* 1M of memory */
igd_memory = 0x3;
break;
case 8: /* 8M of memory */
igd_memory = 0x4;
break;
default: /* No memory */
pci_write_config16(ctrl->d0, GCC1, 0x0002);
igd_memory = 0x0;
}
value = pci_read_config16(ctrl->d0, GCC1);
value |= igd_memory << 4;
pci_write_config16(ctrl->d0, GCC1, value);
/* Set the value for Aperture Base Configuration Register */
pci_write_config32(ctrl->d0, APBASE, 0x00000008);
/* Set the value for Register Range Base Address Register */
pci_write_config32(ctrl->d0, RRBAR, 0x00000000);
/* Set the value for Fixed DRAM Hole Control Register */
pci_write_config8(ctrl->d0, FDHC, 0x00);
/* Set the value for Programable Attribute Map Registers
* Ideally, this should be R/W for as many ranges as possible.
*/
pci_write_config8(ctrl->d0, PAM0, 0x30);
pci_write_config8(ctrl->d0, PAM1, 0x33);
pci_write_config8(ctrl->d0, PAM2, 0x33);
pci_write_config8(ctrl->d0, PAM3, 0x33);
pci_write_config8(ctrl->d0, PAM4, 0x33);
pci_write_config8(ctrl->d0, PAM5, 0x33);
pci_write_config8(ctrl->d0, PAM6, 0x33);
/* Set the value for DRAM Throttling Control Register */
pci_write_config32(ctrl->d0, DTC, 0x00000000);
/* Set the value for System Management RAM Control Register */
pci_write_config8(ctrl->d0, SMRAM, 0x02);
/* Set the value for Extended System Management RAM Control Register */
pci_write_config8(ctrl->d0, ESMRAMC, 0x38);
PRINT_DEBUG("Initial registers have been set.\r\n");
}
static void sdram_set_spd_registers(const struct mem_controller *ctrl)
{
spd_set_dram_size(ctrl);
set_dram_row_attributes(ctrl);
set_dram_timing(ctrl);
set_dram_buffer_strength(ctrl);
}
static void sdram_enable(int controllers, const struct mem_controller *ctrl)
{
int i;
/* 0. Wait until power/voltages and clocks are stable (200us). */
udelay(200);
/* 1. Apply NOP. */
PRINT_DEBUG("RAM Enable 1: Apply NOP\r\n");
do_ram_command(ctrl, RAM_COMMAND_NOP, 0);
udelay(200);
/* 2. Precharge all. Wait tRP. */
PRINT_DEBUG("RAM Enable 2: Precharge all\r\n");
do_ram_command(ctrl, RAM_COMMAND_PRECHARGE, 0);
udelay(1);
/* 3. Perform 8 refresh cycles. Wait tRC each time. */
PRINT_DEBUG("RAM Enable 3: CBR\r\n");
for (i = 0; i < 8; i++) {
do_ram_command(ctrl, RAM_COMMAND_CBR, 0);
udelay(1);
}
/* 4. Mode register set. Wait two memory cycles. */
/* TODO: Set offset according to DRT values */
PRINT_DEBUG("RAM Enable 4: Mode register set\r\n");
do_ram_command(ctrl, RAM_COMMAND_MRS, 0x1d0);
udelay(2);
/* 5. Normal operation (enables refresh) */
PRINT_DEBUG("RAM Enable 5: Normal operation\r\n");
do_ram_command(ctrl, RAM_COMMAND_NORMAL, 0);
udelay(1);
PRINT_DEBUG("Northbridge following SDRAM init:\r\n");
DUMPNORTH();
}

View File

@ -0,0 +1,32 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
*
* 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
*/
#ifndef NORTHBRIDGE_INTEL_I82830_RAMINIT_H
#define NORTHBRIDGE_INTEL_I82830_RAMINIT_H
/* The 82830 supports max. 2 dual-sided SO-DIMMs. */
#define DIMM_SOCKETS 2
struct mem_controller {
device_t d0;
uint16_t channel0[DIMM_SOCKETS];
};
#endif /* NORTHBRIDGE_INTEL_I82830_RAMINIT_H */

View File

@ -0,0 +1,63 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2008 Joseph Smith <joe@smittys.pointclark.net>
##
## 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
##
target rm4100
mainboard rca/rm4100
##
## Total number of bytes allocated for coreboot use
## (fallback images and payloads).
##
# option ROM_SIZE = 1024 * 1024
## For VGA BIOS (-64k)
option ROM_SIZE = (1024 * 1024) - (64 * 1024)
##
## VGA Console
## NOTE: to initialize VGA, you need to copy
## the VGA option ROM from the factory BIOS
## 0=disable 1=enable
##
option CONFIG_CONSOLE_VGA = 1
option CONFIG_PCI_ROM_RUN = 1
##
## Choose the amount of memory pre-allocated for VGA
## 0 for No memory pre-allocated (Graphics memory Disabled)
## 512 for DVMT (UMA) mode, 512K of memory pre-allocated for frame buffer
## 1 for DVMT (UMA) mode, 1M of memory pre-allocated for frame buffer
## 8 for DVMT (UMA) mode, 8M of memory pre-allocated for frame buffer
##
option CONFIG_VIDEO_MB = 8
##
## Request this level of debugging output
##
option DEFAULT_CONSOLE_LOGLEVEL = 7
romimage "fallback"
option USE_FALLBACK_IMAGE = 1
option FALLBACK_SIZE = ROM_SIZE
option COREBOOT_EXTRA_VERSION = "_RM4100"
payload /tmp/filo.elf
# payload /tmp/eb-5.4.3-eepro100.elf
end
buildrom ./coreboot.rom ROM_SIZE "fallback"