Add VIA CX700 support, plus VIA vt8454c reference board support.

Signed-off-by: Stefan Reinauer <stepan@coresystems.de>
Acked-by: Uwe Hermann <uwe@hermann-uwe.de>
Acked-by: Ronald G. Minnich <rminnich@gmail.com>



git-svn-id: svn://svn.coreboot.org/coreboot/trunk@4126 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
Stefan Reinauer 2009-04-17 08:37:18 +00:00 committed by Stefan Reinauer
parent 56c51bd120
commit aeba92ab5b
41 changed files with 6243 additions and 6 deletions

View File

@ -0,0 +1,106 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2008 VIA Technologies, Inc.
* (Written by Jason Zhao <jasonzhao@viatech.com.cn> for VIA)
*
* 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; version 2 of the License.
*
* 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
*/
__asm__ volatile (
/*
FIXME : backup stack in CACHE_AS_RAM into mmx and sse and after we get STACK up, we restore that.
It is only needed if we want to go back
*/
/* We don't need cache as ram for now on */
/* disable cache */
"movl %cr0, %eax\n\t"
"orl $(0x1<<30),%eax\n\t"
"movl %eax, %cr0\n\t"
/* Set the default memory type and disable fixed and enable variable MTRRs */
"movl $0x2ff, %ecx\n\t"
//"movl $MTRRdefType_MSR, %ecx\n\t"
"xorl %edx, %edx\n\t"
/* Enable Variable and Disable Fixed MTRRs */
"movl $0x00000800, %eax\n\t"
"wrmsr\n\t"
/* enable caching for first 1M using variable mtrr */
"movl $0x200, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0 | 6), %eax\n\t"
//"movl $(0 | MTRR_TYPE_WRBACK), %eax\n\t"
"wrmsr\n\t"
/*Jasonzhao@viatech.com.cn, I enable cache for 0-7ffff, 80000-9ffff, e0000-fffff;
if 1M cacheable,then when S3 resume, there is stange color on screen for 2 sec.
suppose problem of a0000-dfffff and cache .
and in x86_setup_fixed_mtrrs()(mtrr.c), 0-256M is set cacheable.*/
"movl $0x201, %ecx\n\t"
"movl $0x0000000f, %edx\n\t" /* AMD 40 bit 0xff*/
"movl $((~(( 0 + 0x80000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
"movl $0x202, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0x80000 | 6), %eax\n\t"
"orl $(0 | 6), %eax\n\t"
"wrmsr\n\t"
"movl $0x203, %ecx\n\t"
"movl $0x0000000f, %edx\n\t" /* AMD 40 bit 0xff*/
"movl $((~(( 0 + 0x20000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
"movl $0x204, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $(0xc0000 | 6), %eax\n\t"
"orl $(0 | 6), %eax\n\t"
"wrmsr\n\t"
"movl $0x205, %ecx\n\t"
"movl $0x0000000f, %edx\n\t" /* AMD 40 bit 0xff*/
"movl $((~(( 0 + 0x40000) - 1)) | 0x800), %eax\n\t"
"wrmsr\n\t"
/*jasonzhao@viatech.com.cn add this 2008-11-27, cache XIP_ROM_BASE-SIZE to speedup the coreboot code*/
"movl $0x206, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $XIP_ROM_BASE,%eax\n\t"
"orl $(0 | 6), %eax\n\t"
"wrmsr\n\t"
"movl $0x207, %ecx\n\t"
"xorl %edx, %edx\n\t"
"movl $XIP_ROM_SIZE,%eax\n\t"
"decl %eax\n\t"
"notl %eax\n\t"
"orl $(0 | 0x800), %eax\n\t"
"wrmsr\n\t"
/* enable cache */
"movl %cr0, %eax\n\t"
"andl $0x9fffffff,%eax\n\t"
"movl %eax, %cr0\n\t"
"invd\n\t"
/*
FIXME: I hope we don't need to change esp and ebp value here, so we can restore value from mmx sse back
But the problem is the range is some io related, So don't go back
*/
);

View File

@ -5,8 +5,8 @@
#
# 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.
# published by the Free Software Foundation; version 2 of
# the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,12 @@
/*
* This file is part of the coreboot project.
*
* (C) 2007-2008 coresystems GmbH
* (C) 2007-2009 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.
* published by the Free Software Foundation; version 2 of
* the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -195,6 +195,11 @@ static void model_c7_init(device_t dev)
/* Gear up */
set_c7_speed(c.x86_model);
/* Enable APIC */
msr = rdmsr(0x1107);
msr.lo |= 1<<24;
wrmsr(0x1107, msr);
/* Turn on cache */
x86_enable_cache();

View File

@ -55,6 +55,11 @@ static void copy_and_run(unsigned cpu_reset)
printk_spew("coreboot_ram.bin length = %08x\r\n", olen);
#else
print_spew("coreboot_ram.bin length = "); print_spew_hex32(olen); print_spew("\r\n");
#endif
#ifdef CONFIG_DEACTIVATE_CAR
print_debug("Deactivating CAR");
#include CONFIG_DEACTIVATE_CAR_FILE
print_debug(" - Done.\r\n");
#endif
print_debug("Jumping to coreboot.\r\n");

View File

@ -1 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 PC80_I8259_H
#define PC80_I8259_H
void setup_i8259(void);
#endif /* PC80_I8259_H */

View File

@ -2,6 +2,7 @@
* This file is part of the coreboot project.
*
* Copyright (C) 2007 Advanced Micro Devices, Inc.
* Copyright (C) 2007-2009 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
@ -29,6 +30,7 @@
#define SPD_DIMM_TYPE_uDIMM (1<<3)
#define SPD_DIMM_TYPE_mRDIMM (1<<4)
#define SPD_DIMM_TYPE_mUDIMM (1<<5)
#define SPD_MOD_ATTRIB 21
#define SPD_MOD_ATTRIB_DIFCK 0x20
#define SPD_MOD_ATTRIB_REGADC 0x11 /* x */
@ -39,6 +41,15 @@
#define SPD_DIMM_CONF_TYPE_ECC 0x02
#define SPD_DIMM_CONF_TYPE_ADDR_PARITY 0x04 /* ? */
#define SPD_CAS_LAT_MIN_X_1 23
#define SPD_CAS_LAT_MAX_X_1 24
#define SPD_CAS_LAT_MIN_X_2 25
#define SPD_CAS_LAT_MAX_X_2 26
#define SPD_BURST_LENGTHS 16
#define SPD_BURST_LENGTHS_4 (1<<2)
#define SPD_BURST_LENGTHS_8 (1<<3)
#define SPD_ROW_NUM 3 /* Number of Row addresses */
#define SPD_COL_NUM 4 /* Number of Column addresses */
#define SPD_BANK_NUM 17 /* SDRAM Device attributes - Number of Banks on
@ -82,6 +93,7 @@
#define SPD_TWTR 37 /* x */
#define SPD_TRTP 38 /* x */
#define SPD_EX_TRC_TRFC 40
#define SPD_TRC 41 /* add byte 0x40 bit [3:1] , so final val41+ table[((val40>>1) & 0x7)] ... table[]={0, 0.25, 0.33, 0.5, 0.75, 0, 0}*/
#define SPD_TRFC 42 /* add byte 0x40 bit [6:4] , so final val42+ table[((val40>>4) & 0x7)] + (val40 & 1)*256*/

View File

@ -0,0 +1,198 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of
## the License.
##
## 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
##
##
## Compute the location and size of where this firmware image
## (coreboot plus bootloader) will live in the boot rom chip.
##
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
##
## Compute the start location and size size of
## The coreboot bootloader.
##
default PAYLOAD_SIZE = ( ROM_SECTION_SIZE - ROM_IMAGE_SIZE )
default CONFIG_ROM_PAYLOAD_START = (0xffffffff - ROM_SIZE + ROM_SECTION_OFFSET + 1)
##
## Compute where this copy of coreboot will start in the boot rom
##
default _ROMBASE = ( CONFIG_ROM_PAYLOAD_START + PAYLOAD_SIZE )
##
## Compute a range of ROM that can cached to speed up coreboot,
## execution speed.
##
## XIP_ROM_SIZE must be a power of 2.
## XIP_ROM_BASE must be a multiple of XIP_ROM_SIZE
##
default XIP_ROM_SIZE=65536
default XIP_ROM_BASE = ( _ROMBASE + ROM_IMAGE_SIZE - XIP_ROM_SIZE )
##
## Set all of the defaults for an x86 architecture
##
arch i386 end
##
## Build the objects we have code for in this directory.
##
driver mainboard.o
if HAVE_MP_TABLE
object mptable.o
end
if HAVE_PIRQ_TABLE
object irq_tables.o
end
if HAVE_ACPI_TABLES
object fadt.o
object acpi_tables.o
makerule dsdt.c
depends "$(MAINBOARD)/dsdt.dsl"
action "iasl -p dsdt -tc $(MAINBOARD)/dsdt.dsl"
action "mv dsdt.hex dsdt.c"
end
object ./dsdt.o
end
##
## Romcc output
##
makerule ./auto.inc
depends "$(MAINBOARD)/auto.c option_table.h"
action "$(CC) $(DISTRO_CFLAGS) $(CFLAGS) $(CPPFLAGS) $(DEBUG_CFLAGS) -I$(TOP)/src -I. -nostdinc -nostdlib -fno-builtin -Wall -Os -c -S $(MAINBOARD)/auto.c -o $@"
action "perl -e 's/\.rodata/.rom.data/g' -pi $@"
action "perl -e 's/\.text/.section .rom.text/g' -pi $@"
end
##
## Build our 16 bit and 32 bit coreboot entry code
##
mainboardinit cpu/x86/16bit/entry16.inc
mainboardinit cpu/x86/32bit/entry32.inc
ldscript /cpu/x86/16bit/entry16.lds
ldscript /cpu/x86/32bit/entry32.lds
##
## Build our reset vector (This is where coreboot is entered)
##
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 cpu/via/car/cache_as_ram.inc
##
## Include an id string (For safe flashing)
##
mainboardinit arch/i386/lib/id.inc
ldscript /arch/i386/lib/id.lds
###
### O.k. We aren't just an intermediary anymore!
###
##
## Setup RAM
##
mainboardinit cpu/x86/fpu/enable_fpu.inc
mainboardinit ./auto.inc
##
## Include the secondary Configuration files
##
dir /pc80
config chip.h
chip northbridge/via/cx700
device apic_cluster 0 on
chip cpu/via/model_c7
device apic 0 on end
end
end
device pci_domain 0 on
device pci 0.0 on end # AGP Bridge
device pci 0.1 on end # Error Reporting
device pci 0.2 on end # Host Bus Control
device pci 0.3 on end # Memory Controller
device pci 0.4 on end # Power Management
device pci 0.7 on end # V-Link Controller
device pci 1.0 on # PCI Bridge
chip drivers/pci/onboard
device pci 0.0 on end
#register "rom_address" = "0xfffc0000" #256k image
register "rom_address" = "0xfff80000" #512k image
#register "rom_address" = "0xfff00000" #1024k image
end # Onboard Video
end # PCI Bridge
device pci f.0 on end # IDE/SATA
#device pci f.1 on end # IDE
device pci 10.0 on end # USB 1.1
device pci 10.1 on end # USB 1.1
device pci 10.2 on end # USB 1.1
device pci 10.4 on end # USB 2.0
device pci 11.0 on # Southbridge LPC
chip superio/via/vt1211
device pnp 2e.0 on # Floppy
io 0x60 = 0x3f0
irq 0x70 = 6
drq 0x74 = 2
end
device pnp 2e.1 on # Parallel Port
io 0x60 = 0x378
irq 0x70 = 7
drq 0x74 = 3
end
device pnp 2e.2 on # COM1
io 0x60 = 0x3f8
irq 0x70 = 4
end
device pnp 2e.3 on # COM2
io 0x60 = 0x2f8
irq 0x70 = 3
end
device pnp 2e.b on # HWM
io 0x60 = 0xec00
end
end # superio
end # pci 11.0
# 1-4 non existant
#device pci 11.5 on end # AC97 Audio
#device pci 11.6 off end # AC97 Modem
#device pci 12.0 on end # Ethernet
end # pci domain 0
end # cx700

View File

@ -0,0 +1,246 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of
## the License.
##
## 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 HAVE_MP_TABLE
uses HAVE_PIRQ_TABLE
uses IRQ_SLOT_COUNT
uses HAVE_ACPI_TABLES
uses HAVE_OPTION_TABLE
uses USE_OPTION_TABLE
uses USE_FALLBACK_IMAGE
uses HAVE_FALLBACK_BOOT
uses HAVE_HARD_RESET
uses MAINBOARD
uses MAINBOARD_VENDOR
uses MAINBOARD_PART_NUMBER
uses COREBOOT_EXTRA_VERSION
uses ARCH
uses FALLBACK_SIZE
uses STACK_SIZE
uses HEAP_SIZE
uses ROM_SIZE
uses ROM_SECTION_SIZE
uses ROM_IMAGE_SIZE
uses ROM_SECTION_SIZE
uses ROM_SECTION_OFFSET
uses CONFIG_COMPRESS
uses CONFIG_ROM_PAYLOAD
uses CONFIG_ROM_PAYLOAD_START
uses CONFIG_COMPRESSED_PAYLOAD_NRV2B
uses CONFIG_COMPRESSED_PAYLOAD_LZMA
uses PAYLOAD_SIZE
uses _ROMBASE
uses _RAMBASE
uses XIP_ROM_SIZE
uses XIP_ROM_BASE
uses CONFIG_CBFS
# compiler specifics
uses CROSS_COMPILE
uses CC
uses HOSTCC
uses OBJCOPY
# Console specifics
uses DEFAULT_CONSOLE_LOGLEVEL
uses MAXIMUM_CONSOLE_LOGLEVEL
uses CONFIG_CONSOLE_SERIAL8250
uses TTYS0_BAUD
uses TTYS0_BASE
uses TTYS0_LCS
uses CONFIG_UDELAY_TSC
uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2
uses CONFIG_PCI_ROM_RUN
uses CONFIG_CONSOLE_VGA
uses CONFIG_MAX_PCI_BUSES
uses CONFIG_SMP
uses CONFIG_IOAPIC
uses CONFIG_GDB_STUB
uses USE_DCACHE_RAM
uses DCACHE_RAM_BASE
uses DCACHE_RAM_SIZE
uses CONFIG_USE_PRINTK_IN_CAR
## ROM_SIZE is the size of boot ROM that this board will use.
default ROM_SIZE = 256*1024
default USE_DCACHE_RAM=1
default DCACHE_RAM_BASE=0xffef0000
#default DCACHE_RAM_BASE=0xffbf0000
#default DCACHE_RAM_BASE=0xfec00000
default DCACHE_RAM_SIZE=0x8000
default CONFIG_USE_PRINTK_IN_CAR=1
###
### Leave this to 0; VGA is handled by seperate code.
###
default CONFIG_PCI_ROM_RUN=0
default CONFIG_CONSOLE_VGA=0
##
## Build code for the fallback boot
##
default HAVE_FALLBACK_BOOT=1
##
## Use TSC for udelay.
##
default CONFIG_UDELAY_TSC=1
default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=1
##
## Build code to reset the motherboard from linuxBIOS
##
default HAVE_HARD_RESET=1
##
## Build code to export a programmable irq routing table
##
default HAVE_PIRQ_TABLE=1
default IRQ_SLOT_COUNT=15
##
## Build code to export an x86 MP table
## Useful for specifying IRQ routing values
##
default HAVE_MP_TABLE=1
##
## Build code to load acpi tables
##
default HAVE_ACPI_TABLES=1
##
## Build code to export a CMOS option table
##
default HAVE_OPTION_TABLE=1
##
## Build code to setup a generic IOAPIC
##
default CONFIG_SMP=1
default CONFIG_IOAPIC=1
###
### LinuxBIOS layout values
###
## ROM_IMAGE_SIZE is the amount of space to allow linuxBIOS to occupy.
default ROM_IMAGE_SIZE = 65536
default FALLBACK_SIZE = 131072
##
## Use a small 8K stack
##
default STACK_SIZE=0x2000
##
## Use a small 16K heap
##
default HEAP_SIZE=0x4000
##
## Only use the option table in a normal image
##
#default USE_OPTION_TABLE = !USE_FALLBACK_IMAGE
default USE_OPTION_TABLE = 0
default _RAMBASE = 0x00004000
default CONFIG_ROM_PAYLOAD = 1
##
## The default compiler
##
default CROSS_COMPILE=""
default CC="$(CROSS_COMPILE)gcc -m32"
default HOSTCC="gcc"
##
## Set this to the max PCI bus number you
## would ever use for PCI config IO.
## Setting this number very high will make
## pci_locate_device take a long time when
## it can't find a device.
##
default CONFIG_MAX_PCI_BUSES = 0x80
##
## Disable the gdb stub by default
##
default CONFIG_GDB_STUB=0
##
## The Serial Console
##
# To Enable the Serial Console
default CONFIG_CONSOLE_SERIAL8250=1
## Select the serial console baud rate
default TTYS0_BAUD=115200
#default TTYS0_BAUD=57600
#default TTYS0_BAUD=38400
#default TTYS0_BAUD=19200
#default TTYS0_BAUD=9600
#default TTYS0_BAUD=4800
#default TTYS0_BAUD=2400
#default TTYS0_BAUD=1200
# Select the serial console base port
default TTYS0_BASE=0x3f8
# Select the serial protocol
# This defaults to 8 data bits, 1 stop bit, and no parity
default TTYS0_LCS=0x3
##
## Select the coreboot loglevel
##
## EMERG 1 system is unusable
## ALERT 2 action must be taken immediately
## CRIT 3 critical conditions
## ERR 4 error conditions
## WARNING 5 warning conditions
## NOTICE 6 normal but significant condition
## INFO 7 informational
## DEBUG 8 debug-level messages
## SPEW 9 Way too many details
## Request this level of debugging output
default DEFAULT_CONSOLE_LOGLEVEL=5
## At a maximum only compile in this level of debugging
default MAXIMUM_CONSOLE_LOGLEVEL=5
#
# CBFS
#
default CONFIG_CBFS=0
end

View File

@ -0,0 +1,205 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 <string.h>
#include <console/console.h>
#include <arch/acpi.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
#include "dmi.h"
extern unsigned char AmlCode[];
unsigned long acpi_fill_mcfg(unsigned long current)
{
device_t dev;
u64 mmcfg;
dev = dev_find_device(0x1106, 0x324b, 0); // 0:0x13.0
if (!dev)
return current;
// MMCFG not supported or not enabled.
if ((pci_read_config8(dev, 0x40) & 0xC0) != 0xC0)
return current;
mmcfg = ((u64) pci_read_config8(dev, 0x41)) << 28;
if (!mmcfg)
return current;
current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current, mmcfg, 0x0, 0x0, 0xff);
return current;
}
void acpi_create_via_hpet(acpi_hpet_t * hpet)
{
#define HPET_ADDR 0xfe800000ULL
acpi_header_t *header = &(hpet->header);
acpi_addr_t *addr = &(hpet->addr);
memset((void *) hpet, 0, sizeof(acpi_hpet_t));
/* fill out header fields */
memcpy(header->signature, HPET_NAME, 4);
memcpy(header->oem_id, OEM_ID, 6);
memcpy(header->oem_table_id, "COREBOOT", 8);
memcpy(header->asl_compiler_id, ASLC, 4);
header->length = sizeof(acpi_hpet_t);
header->revision = 1;
/* fill out HPET address */
// XXX factory bios just puts an address here -- who's right?
addr->space_id = 0; /* Memory */
addr->bit_width = 64;
addr->bit_offset = 0;
addr->addrl = HPET_ADDR & 0xffffffff;
addr->addrh = HPET_ADDR >> 32;
hpet->id = 0x11068201; /* VIA */
hpet->number = 0x00;
hpet->min_tick = 0x0090;
header->checksum =
acpi_checksum((void *) hpet, sizeof(acpi_hpet_t));
}
#define IO_APIC_ADDR 0xfec00000UL
unsigned long acpi_fill_madt(unsigned long current)
{
/* Local Apic */
current += acpi_create_madt_lapic((acpi_madt_lapic_t *) current, 0, 0);
/* IOAPIC */
current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current, 2, IO_APIC_ADDR, 0);
/* INT_SRC_OVR */
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 0, 2, 0);
current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *) current, 0, 9, 9, 0x000f); // low/level
/* LAPIC_NMI */
current += acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t *) current, 0, 0x0005, 1); // high/edge
return current;
}
unsigned long acpi_fill_slit(unsigned long current)
{
// Not implemented
return current;
}
unsigned long acpi_fill_srat(unsigned long current)
{
/* No NUMA, no SRAT */
return current;
}
unsigned long write_acpi_tables(unsigned long start)
{
unsigned long current;
acpi_rsdp_t *rsdp;
acpi_rsdt_t *rsdt;
acpi_hpet_t *hpet;
acpi_madt_t *madt;
acpi_mcfg_t *mcfg;
acpi_fadt_t *fadt;
acpi_facs_t *facs;
acpi_header_t *dsdt;
/* Align ACPI tables to 16byte */
start = (start + 0x0f) & -0x10;
current = start;
printk_info("ACPI: Writing ACPI tables at %lx.\n", start);
/* We need at least an RSDP and an RSDT Table */
rsdp = (acpi_rsdp_t *) current;
current += sizeof(acpi_rsdp_t);
rsdt = (acpi_rsdt_t *) current;
current += sizeof(acpi_rsdt_t);
/* clear all table memory */
memset((void *) start, 0, current - start);
acpi_write_rsdp(rsdp, rsdt);
acpi_write_rsdt(rsdt);
/*
* We explicitly add these tables later on:
*/
printk_debug("ACPI: * HPET\n");
hpet = (acpi_hpet_t *) current;
current += sizeof(acpi_hpet_t);
acpi_create_via_hpet(hpet);
acpi_add_table(rsdt, hpet);
/* If we want to use HPET Timers Linux wants an MADT */
printk_debug("ACPI: * MADT\n");
madt = (acpi_madt_t *) current;
acpi_create_madt(madt);
current += madt->header.length;
acpi_add_table(rsdt, madt);
printk_debug("ACPI: * MCFG\n");
mcfg = (acpi_mcfg_t *) current;
acpi_create_mcfg(mcfg);
current += mcfg->header.length;
acpi_add_table(rsdt, mcfg);
printk_debug("ACPI: * FACS\n");
facs = (acpi_facs_t *) current;
current += sizeof(acpi_facs_t);
acpi_create_facs(facs);
dsdt = (acpi_header_t *) current;
current += ((acpi_header_t *) AmlCode)->length;
memcpy((void *) dsdt, (void *) AmlCode,
((acpi_header_t *) AmlCode)->length);
#if DONT_TRUST_IASL
dsdt->checksum = 0; // don't trust intel iasl compiler to get this right
dsdt->checksum = acpi_checksum(dsdt, dsdt->length);
#endif
printk_debug("ACPI: * DSDT @ %08x Length %x\n", dsdt,
dsdt->length);
printk_debug("ACPI: * FADT\n");
fadt = (acpi_fadt_t *) current;
current += sizeof(acpi_fadt_t);
acpi_create_fadt(fadt, facs, dsdt);
acpi_add_table(rsdt, fadt);
printk_debug("ACPI: * DMI (Linux workaround)\n");
memcpy((void *)0xfff80, dmi_table, DMI_TABLE_SIZE);
printk_info("ACPI: done.\n");
return current;
}

View File

@ -0,0 +1,127 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 <device/pci_def.h>
#include <device/pci_ids.h>
#include <arch/io.h>
#include <device/pnp_def.h>
#include <arch/romcc_io.h>
#include <arch/hlt.h>
#include "pc80/serial.c"
#include "arch/i386/lib/console.c"
#include "ram/ramtest.c"
#include "northbridge/via/cx700/raminit.h"
#include "cpu/x86/mtrr/earlymtrr.c"
#include "cpu/x86/bist.h"
#define CONFIG_DEACTIVATE_CAR 1
#define CONFIG_DEACTIVATE_CAR_FILE "cpu/via/car/cache_as_ram_post.c"
#include "cpu/x86/car/copy_and_run.c"
#include "pc80/udelay_io.c"
#include "lib/delay.c"
#include "cpu/x86/lapic/boot_cpu.c"
#include "northbridge/via/cx700/cx700_early_smbus.c"
#include "debug.c"
#include "northbridge/via/cx700/cx700_early_serial.c"
#include "northbridge/via/cx700/raminit.c"
static void enable_mainboard_devices(void)
{
device_t dev;
dev = pci_locate_device(PCI_ID(0x1106, 0x8324), 0);
if (dev == PCI_DEV_INVALID) {
die("LPC bridge not found!!!\n");
}
// Disable GP3
pci_write_config8(dev, 0x98, 0x00);
// Disable mc97
pci_write_config8(dev, 0x50, 0x80);
// Disable internal KBC Configuration
pci_write_config8(dev, 0x51, 0x2d);
pci_write_config8(dev, 0x58, 0x42);
pci_write_config8(dev, 0x59, 0x80);
pci_write_config8(dev, 0x5b, 0x01);
// Enable P2P Bridge Header for External PCI BUS.
dev = pci_locate_device(PCI_ID(0x1106, 0x324e), 0);
if (dev == PCI_DEV_INVALID) {
die("P2P bridge not found!!!\n");
}
pci_write_config8(dev, 0x4f, 0x41);
// Switch SATA to non-RAID mode
dev = pci_locate_device(PCI_ID(0x1106, 0x0581), 0);
if (dev != PCI_DEV_INVALID) {
pci_write_config16(dev, 0xBA, 0x5324);
}
}
static void enable_shadow_ram(const struct mem_controller *ctrl)
{
u8 shadowreg;
pci_write_config8(PCI_DEV(0, 0, 3), 0x80, 0x2a);
/* 0xf0000-0xfffff - ACPI tables */
shadowreg = pci_read_config8(PCI_DEV(0, 0, 3), 0x83);
shadowreg |= 0x30;
pci_write_config8(PCI_DEV(0, 0, 3), 0x83, shadowreg);
}
static void main(unsigned long bist)
{
/* Set statically so it should work with cx700 as well */
static const struct mem_controller cx700[] = {
{
.channel0 = {0x50, 0x51},
},
};
enable_smbus();
enable_cx700_serial();
uart_init();
console_init();
/* Halt if there was a built in self test failure */
report_bist_failure(bist);
enable_mainboard_devices();
/* Allows access to all northbridge devices */
pci_write_config8(PCI_DEV(0, 0, 0), 0x4f, 0x01);
sdram_set_registers(cx700);
enable_shadow_ram(cx700);
sdram_enable(cx700);
copy_and_run(0);
}
void amd64_main(unsigned long bist) {
main(bist);
}

View File

@ -0,0 +1,26 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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_ops;
struct mainboard_config {
int nothing;
};

View File

@ -0,0 +1,67 @@
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of
## the License.
##
## 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
##
entries
#start-bit length config config-ID name
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
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

View File

@ -0,0 +1,108 @@
/*
* This file is part of the coreboot project.
*
* (C) 2007-2009 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; version 2 of
* the License.
*
* 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
*/
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)) {
u32 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)) {
u32 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);
}
}
static void dump_io_resources(unsigned port)
{
int i;
udelay(2000);
print_debug_hex16(port);
print_debug(":\r\n");
for (i = 0; i < 256; i++) {
u8 val;
if ((i & 0x0f) == 0) {
print_debug_hex8(i);
print_debug_char(':');
}
val = inb(port);
print_debug_char(' ');
print_debug_hex8(val);
if ((i & 0x0f) == 0x0f) {
print_debug("\r\n");
}
port++;
}
}

View File

@ -0,0 +1,31 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 DMI_TABLE_SIZE 0x55
static u8 dmi_table[DMI_TABLE_SIZE] = {
0x5f, 0x53, 0x4d, 0x5f, 0x2d, 0x1f, 0x02, 0x03, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x5f, 0x44, 0x4d, 0x49, 0x5f, 0xeb, 0xa8, 0x03, 0xa0, 0xff, 0x0f, 0x00, 0x01, 0x00, 0x23, 0x00,
0x00, 0x14, 0x00, 0x00, 0x01, 0x02, 0x00, 0xe0, 0x03, 0x07, 0x90, 0xde, 0xcb, 0x7f, 0x00, 0x00,
0x00, 0x00, 0x37, 0x01, 0x63, 0x6f, 0x72, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x20,
0x47, 0x6d, 0x62, 0x48, 0x00, 0x32, 0x2e, 0x30, 0x00, 0x30, 0x33, 0x2f, 0x31, 0x33, 0x2f, 0x32,
0x30, 0x30, 0x38, 0x00, 0x00
};

View File

@ -0,0 +1,341 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2004 Nick Barker <Nick.Barker9@btinternet.com>
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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
*/
DefinitionBlock ("dsdt.aml", "DSDT", 1, "CX700 ", "COREBOOT", 0x00000001)
{
/*
* Define the main processor
*/
Scope (\_PR)
{
Processor (\_PR.CPU0, 0x00, 0x00000410, 0x06) {}
}
/* For now only define 2 power states:
* - S0 which is fully on
* - S5 which is soft off
* any others would involve declaring the wake up methods
*/
Name (\_S0, Package () {0x00, 0x00, 0x00, 0x00 })
Name (\_S5, Package () {0x02, 0x02, 0x00, 0x00 })
Scope (\) {
Name (PICF , 0) // Global flag indicating whether to use PIC or APIC mode
Method ( _PIC,1) // The OS is calling this
{
Store( Arg0 , PICF)
}
} // end of \ scope
/* Root of the bus hierarchy */
Scope (\_SB)
{
/* Define how interrupt Link A is plumbed in */
Device (LNKA)
{
Name (_HID, EisaId ("PNP0C0F"))
Name (_UID, 0x01)
/* Status - always return ready */
Method (_STA, 0, NotSerialized)
{
Return (0x0B)
}
/* Current Resources - return irq set up in BIOS */
Method (_CRS, 0, NotSerialized)
{
Name (CRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {11}
})
Name (CRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16}
})
If (LNot (PICF)) {
Return (CRSP)
} Else {
Return (CRSA)
}
}
/* Possible Resources - return the range of irqs
* we are using for PCI - only here to keep Linux ACPI
* happy
*/
Method (_PRS, 0, NotSerialized)
{
Name (PRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {3,4,6,7,10,11,12}
})
Name (PRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16,17,18,19,20,21,22,23}
})
If (LNot (PICF)) {
Return (PRSP)
} Else {
Return (PRSA)
}
}
/* Set Resources - dummy function to keep Linux ACPI happy
* Linux is more than happy not to tinker with irq
* assignments as long as the CRS and STA functions
* return good values
*/
Method (_SRS, 1, NotSerialized ) {}
/* Disable - dummy function to keep Linux ACPI happy */
Method (_DIS, 0, NotSerialized ) {}
} // End of LNKA
/* Define how interrupt Link B is plumbed in */
Device (LNKB)
{
Name (_HID, EisaId ("PNP0C0F"))
Name (_UID, 0x02)
/* Status - always return ready */
Method (_STA, 0, NotSerialized)
{
Return (0x0B)
}
/* Current Resources - return irq set up in BIOS */
Method (_CRS, 0, NotSerialized)
{
Name (CRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {11}
})
Name (CRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {17}
})
If (LNot (PICF)) {
Return (CRSP)
} Else {
Return (CRSA)
}
}
/* Possible Resources - return the range of irqs
* we are using for PCI - only here to keep Linux ACPI
* happy
*/
Method (_PRS, 0, NotSerialized)
{
Name (PRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {3,4,6,7,10,11,12}
})
Name (PRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16,17,18,19,20,21,22,23}
})
If (LNot (PICF)) {
Return (PRSP)
} Else {
Return (PRSA)
}
}
/* Set Resources - dummy function to keep Linux ACPI happy
* Linux is more than happy not to tinker with irq
* assignments as long as the CRS and STA functions
* return good values
*/
Method (_SRS, 1, NotSerialized ) {}
/* Disable - dummy function to keep Linux ACPI happy */
Method (_DIS, 0, NotSerialized ) {}
} // End of LNKB
/* Define how interrupt Link C is plumbed in */
Device (LNKC)
{
Name (_HID, EisaId ("PNP0C0F"))
Name (_UID, 0x03)
/* Status - always return ready */
Method (_STA, 0, NotSerialized)
{
Return (0x0B)
}
/* Current Resources - return irq set up in BIOS */
Method (_CRS, 0, NotSerialized)
{
Name (CRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {10}
})
Name (CRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {18}
})
If (LNot (PICF)) {
Return (CRSP)
} Else {
Return (CRSA)
}
}
/* Possible Resources - return the range of irqs
* we are using for PCI - only here to keep Linux ACPI
* happy
*/
Method (_PRS, 0, NotSerialized)
{
Name (PRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {3,4,6,7,10,11,12}
})
Name (PRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16,17,18,19,20,21,22,23}
})
If (LNot (PICF)) {
Return (PRSP)
} Else {
Return (PRSA)
}
}
/* Set Resources - dummy function to keep Linux ACPI happy
* Linux is more than happy not to tinker with irq
* assignments as long as the CRS and STA functions
* return good values
*/
Method (_SRS, 1, NotSerialized ) {}
/* Disable - dummy function to keep Linux ACPI happy */
Method (_DIS, 0, NotSerialized ) {}
} // End of LNKC
/* Define how interrupt Link D is plumbed in */
Device (LNKD)
{
Name (_HID, EisaId ("PNP0C0F"))
Name (_UID, 0x04)
/* Status - always return ready */
Method (_STA, 0, NotSerialized)
{
Return (0x0B)
}
/* Current Resources - return irq set up in BIOS */
Method (_CRS, 0, NotSerialized)
{
Name (CRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {10}
})
Name (CRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {19}
})
If (LNot (PICF)) {
Return (CRSP)
} Else {
Return (CRSA)
}
}
/* Possible Resources - return the range of irqs
* we are using for PCI - only here to keep Linux ACPI
* happy
*/
Method (_PRS, 0, NotSerialized)
{
Name (PRSP, ResourceTemplate () {
IRQ (Level, ActiveLow, Shared) {3,4,6,7,10,11,12}
})
Name (PRSA, ResourceTemplate () {
Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {16,17,18,19,20,21,22,23}
})
If (LNot (PICF)) {
Return (PRSP)
} Else {
Return (PRSA)
}
}
/* Set Resources - dummy function to keep Linux ACPI happy
* Linux is more than happy not to tinker with irq
* assignments as long as the CRS and STA functions
* return good values
*/
Method (_SRS, 1, NotSerialized ) {}
/* Disable - dummy function to keep Linux ACPI happy */
Method (_DIS, 0, NotSerialized ) {}
} // End of LNKD
/* PCI Root Bridge */
Device (PCI0)
{
Name (_HID, EisaId ("PNP0A08"))
Name (_CID, EisaId ("PNP0A03"))
Name (_ADR, 0x00)
Name (_UID, 0x00)
Name (_BBN, 0x00)
// Mainboard specific IRQ routing
Include ("irq.dsl")
/* PCI Routing Table */
Method (_PRT, 0, NotSerialized)
{
If (LNot (PICF))
{
Return (PICM)
}
Else
{
Return (APIC)
}
}
Device (P2PB) /* PCI to PCI bridge */
{
Name (_ADR, 0x00130001)
Include ("irq-p2p-bridge.dsl")
Method (_PRT, 0, NotSerialized)
{
If (LNot (PICF))
{
Return (PICM)
}
Else
{
Return (APIC)
}
}
/* Status - always return ready */
Method (_STA, 0, NotSerialized)
{
Return (0x0F)
}
}
} // End of PCI0
} // End of _SB
} // End of Definition Block

View File

@ -0,0 +1,156 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 <string.h>
#include <arch/acpi.h>
void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
{
acpi_header_t *header = &(fadt->header);
memset((void *) fadt, 0, sizeof(acpi_fadt_t));
memcpy(header->signature, "FACP", 4);
header->length = 244;
header->revision = 1;
memcpy(header->oem_id, "CX700 ", 6);
memcpy(header->oem_table_id, "COREBOOT", 8);
memcpy(header->asl_compiler_id, "CORE", 4);
header->asl_compiler_revision = 0;
fadt->firmware_ctrl = (unsigned long) facs;
fadt->dsdt = (unsigned long) dsdt;
fadt->preferred_pm_profile = 0;
fadt->sci_int = 0x9;
fadt->smi_cmd = 0x0;
fadt->acpi_enable = 0xA1;
fadt->acpi_disable = 0xA0;
fadt->s4bios_req = 0x0;
fadt->pstate_cnt = 0x0;
fadt->pm1a_evt_blk = 0x400;
fadt->pm1b_evt_blk = 0x0;
fadt->pm1a_cnt_blk = 0x404;
fadt->pm1b_cnt_blk = 0x0;
fadt->pm2_cnt_blk = 0x22;
fadt->pm_tmr_blk = 0x408;
fadt->gpe0_blk = 0x420;
fadt->gpe1_blk = 0x450;
fadt->pm1_evt_len = 4;
fadt->pm1_cnt_len = 2;
fadt->pm2_cnt_len = 1;
fadt->pm_tmr_len = 4;
fadt->gpe0_blk_len = 4;
fadt->gpe1_blk_len = 4;
fadt->gpe1_base = 0x10;
fadt->cst_cnt = 0;
fadt->p_lvl2_lat = 101;
fadt->p_lvl3_lat = 1001;
fadt->flush_size = 0;
fadt->flush_stride = 0;
fadt->duty_offset = 0;
fadt->duty_width = 1;
fadt->day_alrm = 0x7d;
fadt->mon_alrm = 0x7e;
fadt->century = 0x32;
fadt->iapc_boot_arch = 0x0;
fadt->flags = 0x44a5;
fadt->reset_reg.space_id = 0;
fadt->reset_reg.bit_width = 0;
fadt->reset_reg.bit_offset = 0;
fadt->reset_reg.resv = 0;
fadt->reset_reg.addrl = 0x0;
fadt->reset_reg.addrh = 0x0;
fadt->reset_value = 0;
fadt->x_firmware_ctl_l = (unsigned long) facs;
fadt->x_firmware_ctl_h = 0;
fadt->x_dsdt_l = (unsigned long) dsdt;
fadt->x_dsdt_h = 0;
fadt->x_pm1a_evt_blk.space_id = 1;
fadt->x_pm1a_evt_blk.bit_width = 4;
fadt->x_pm1a_evt_blk.bit_offset = 0;
fadt->x_pm1a_evt_blk.resv = 0;
fadt->x_pm1a_evt_blk.addrl = 0x400;
fadt->x_pm1a_evt_blk.addrh = 0x0;
fadt->x_pm1b_evt_blk.space_id = 1;
fadt->x_pm1b_evt_blk.bit_width = 4;
fadt->x_pm1b_evt_blk.bit_offset = 0;
fadt->x_pm1b_evt_blk.resv = 0;
fadt->x_pm1b_evt_blk.addrl = 0x0;
fadt->x_pm1b_evt_blk.addrh = 0x0;
fadt->x_pm1a_cnt_blk.space_id = 1;
fadt->x_pm1a_cnt_blk.bit_width = 2;
fadt->x_pm1a_cnt_blk.bit_offset = 0;
fadt->x_pm1a_cnt_blk.resv = 0;
fadt->x_pm1a_cnt_blk.addrl = 0x404;
fadt->x_pm1a_cnt_blk.addrh = 0x0;
fadt->x_pm1b_cnt_blk.space_id = 1;
fadt->x_pm1b_cnt_blk.bit_width = 2;
fadt->x_pm1b_cnt_blk.bit_offset = 0;
fadt->x_pm1b_cnt_blk.resv = 0;
fadt->x_pm1b_cnt_blk.addrl = 0x0;
fadt->x_pm1b_cnt_blk.addrh = 0x0;
fadt->x_pm2_cnt_blk.space_id = 1;
fadt->x_pm2_cnt_blk.bit_width = 0;
fadt->x_pm2_cnt_blk.bit_offset = 0;
fadt->x_pm2_cnt_blk.resv = 0;
fadt->x_pm2_cnt_blk.addrl = 0x0;
fadt->x_pm2_cnt_blk.addrh = 0x0;
fadt->x_pm_tmr_blk.space_id = 1;
fadt->x_pm_tmr_blk.bit_width = 4;
fadt->x_pm_tmr_blk.bit_offset = 0;
fadt->x_pm_tmr_blk.resv = 0;
fadt->x_pm_tmr_blk.addrl = 0x408;
fadt->x_pm_tmr_blk.addrh = 0x0;
fadt->x_gpe0_blk.space_id = 1;
fadt->x_gpe0_blk.bit_width = 0;
fadt->x_gpe0_blk.bit_offset = 0;
fadt->x_gpe0_blk.resv = 0;
fadt->x_gpe0_blk.addrl = 0x420;
fadt->x_gpe0_blk.addrh = 0x0;
fadt->x_gpe1_blk.space_id = 1;
fadt->x_gpe1_blk.bit_width = 0;
fadt->x_gpe1_blk.bit_offset = 0;
fadt->x_gpe1_blk.resv = 0;
fadt->x_gpe1_blk.addrl = 0x0;
fadt->x_gpe1_blk.addrh = 0x0;
header->checksum =
acpi_checksum((void *) fadt, sizeof(acpi_fadt_t));
}

View File

@ -0,0 +1,88 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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
*/
Name (PICM, Package () {
// _ADR PIN SRC IDX
Package () { 0x0003FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0003FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0003FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0003FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0004FFFF, 0x00, LNKB, 0x00 },
Package () { 0x0004FFFF, 0x01, LNKC, 0x00 },
Package () { 0x0004FFFF, 0x02, LNKD, 0x00 },
Package () { 0x0004FFFF, 0x03, LNKA, 0x00 },
Package () { 0x0005FFFF, 0x00, LNKC, 0x00 },
Package () { 0x0005FFFF, 0x01, LNKD, 0x00 },
Package () { 0x0005FFFF, 0x02, LNKA, 0x00 },
Package () { 0x0005FFFF, 0x03, LNKB, 0x00 },
Package () { 0x0006FFFF, 0x00, LNKD, 0x00 },
Package () { 0x0006FFFF, 0x01, LNKA, 0x00 },
Package () { 0x0006FFFF, 0x02, LNKB, 0x00 },
Package () { 0x0006FFFF, 0x03, LNKC, 0x00 },
Package () { 0x0007FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0007FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0007FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0007FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0008FFFF, 0x00, LNKB, 0x00 },
Package () { 0x0008FFFF, 0x01, LNKC, 0x00 },
Package () { 0x0008FFFF, 0x02, LNKD, 0x00 },
Package () { 0x0008FFFF, 0x03, LNKA, 0x00 },
})
Name (APIC, Package () {
Package () { 0x0003FFFF, 0x00, 0x00, 0x10 },
Package () { 0x0003FFFF, 0x01, 0x00, 0x11 },
Package () { 0x0003FFFF, 0x02, 0x00, 0x12 },
Package () { 0x0003FFFF, 0x03, 0x00, 0x13 },
Package () { 0x0004FFFF, 0x00, 0x00, 0x11 },
Package () { 0x0004FFFF, 0x01, 0x00, 0x12 },
Package () { 0x0004FFFF, 0x02, 0x00, 0x13 },
Package () { 0x0004FFFF, 0x03, 0x00, 0x10 },
Package () { 0x0005FFFF, 0x00, 0x00, 0x12 },
Package () { 0x0005FFFF, 0x01, 0x00, 0x13 },
Package () { 0x0005FFFF, 0x02, 0x00, 0x10 },
Package () { 0x0005FFFF, 0x03, 0x00, 0x11 },
Package () { 0x0006FFFF, 0x00, 0x00, 0x13 },
Package () { 0x0006FFFF, 0x01, 0x00, 0x10 },
Package () { 0x0006FFFF, 0x02, 0x00, 0x11 },
Package () { 0x0006FFFF, 0x03, 0x00, 0x12 },
Package () { 0x0007FFFF, 0x00, 0x00, 0x10 },
Package () { 0x0007FFFF, 0x01, 0x00, 0x11 },
Package () { 0x0007FFFF, 0x02, 0x00, 0x12 },
Package () { 0x0007FFFF, 0x03, 0x00, 0x13 },
Package () { 0x0008FFFF, 0x00, 0x00, 0x11 },
Package () { 0x0008FFFF, 0x01, 0x00, 0x12 },
Package () { 0x0008FFFF, 0x02, 0x00, 0x13 },
Package () { 0x0008FFFF, 0x03, 0x00, 0x10 },
})

View File

@ -0,0 +1,143 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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
*/
Name (PICM, Package () {
// _ADR PIN SRC IDX
Package () { 0x0001FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0001FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0001FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0001FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0008FFFF, 0x00, LNKB, 0x00 },
Package () { 0x0008FFFF, 0x01, LNKC, 0x00 },
Package () { 0x0008FFFF, 0x02, LNKD, 0x00 },
Package () { 0x0008FFFF, 0x03, LNKA, 0x00 },
Package () { 0x0009FFFF, 0x00, LNKC, 0x00 },
Package () { 0x0009FFFF, 0x01, LNKD, 0x00 },
Package () { 0x0009FFFF, 0x02, LNKA, 0x00 },
Package () { 0x0009FFFF, 0x03, LNKB, 0x00 },
Package () { 0x000AFFFF, 0x00, LNKD, 0x00 },
Package () { 0x000AFFFF, 0x01, LNKA, 0x00 },
Package () { 0x000AFFFF, 0x02, LNKB, 0x00 },
Package () { 0x000AFFFF, 0x03, LNKC, 0x00 },
Package () { 0x000BFFFF, 0x00, LNKD, 0x00 },
Package () { 0x000BFFFF, 0x01, LNKA, 0x00 },
Package () { 0x000BFFFF, 0x02, LNKB, 0x00 },
Package () { 0x000BFFFF, 0x03, LNKC, 0x00 },
Package () { 0x000CFFFF, 0x00, LNKA, 0x00 },
Package () { 0x000CFFFF, 0x01, LNKB, 0x00 },
Package () { 0x000CFFFF, 0x02, LNKC, 0x00 },
Package () { 0x000CFFFF, 0x03, LNKD, 0x00 },
Package () { 0x000DFFFF, 0x00, LNKA, 0x00 },
Package () { 0x000DFFFF, 0x01, LNKB, 0x00 },
Package () { 0x000DFFFF, 0x02, LNKC, 0x00 },
Package () { 0x000DFFFF, 0x03, LNKD, 0x00 },
Package () { 0x000FFFFF, 0x00, LNKA, 0x00 },
Package () { 0x000FFFFF, 0x01, LNKB, 0x00 },
Package () { 0x000FFFFF, 0x02, LNKC, 0x00 },
Package () { 0x000FFFFF, 0x03, LNKD, 0x00 },
/* USB controller */
Package () { 0x0010FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0010FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0010FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0010FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0011FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0011FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0011FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0011FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0012FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0012FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0012FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0012FFFF, 0x03, LNKD, 0x00 }
})
Name (APIC, Package () {
Package () { 0x0001FFFF, 0x00, 0x00, 0x10 },
Package () { 0x0001FFFF, 0x01, 0x00, 0x11 },
Package () { 0x0001FFFF, 0x02, 0x00, 0x12 },
Package () { 0x0001FFFF, 0x03, 0x00, 0x13 },
Package () { 0x0008FFFF, 0x00, 0x00, 0x11 },
Package () { 0x0008FFFF, 0x01, 0x00, 0x12 },
Package () { 0x0008FFFF, 0x02, 0x00, 0x13 },
Package () { 0x0008FFFF, 0x03, 0x00, 0x10 },
Package () { 0x0009FFFF, 0x00, 0x00, 0x12 },
Package () { 0x0009FFFF, 0x01, 0x00, 0x13 },
Package () { 0x0009FFFF, 0x02, 0x00, 0x10 },
Package () { 0x0009FFFF, 0x03, 0x00, 0x11 },
Package () { 0x000AFFFF, 0x00, 0x00, 0x13 },
Package () { 0x000AFFFF, 0x01, 0x00, 0x10 },
Package () { 0x000AFFFF, 0x02, 0x00, 0x11 },
Package () { 0x000AFFFF, 0x03, 0x00, 0x12 },
Package () { 0x000BFFFF, 0x00, 0x00, 0x13 },
Package () { 0x000BFFFF, 0x01, 0x00, 0x10 },
Package () { 0x000BFFFF, 0x02, 0x00, 0x11 },
Package () { 0x000BFFFF, 0x03, 0x00, 0x12 },
Package () { 0x000CFFFF, 0x00, 0x00, 0x10 },
Package () { 0x000CFFFF, 0x01, 0x00, 0x11 },
Package () { 0x000CFFFF, 0x02, 0x00, 0x12 },
Package () { 0x000CFFFF, 0x03, 0x00, 0x13 },
Package () { 0x000DFFFF, 0x00, 0x00, 0x10 },
Package () { 0x000DFFFF, 0x01, 0x00, 0x11 },
Package () { 0x000DFFFF, 0x02, 0x00, 0x12 },
Package () { 0x000DFFFF, 0x03, 0x00, 0x13 },
Package () { 0x000FFFFF, 0x00, LNKA, 0x00 },
Package () { 0x000FFFFF, 0x01, LNKA, 0x00 },
Package () { 0x000FFFFF, 0x02, LNKA, 0x00 },
Package () { 0x000FFFFF, 0x03, LNKA, 0x00 },
/* USB controller. Hardwired in internal
APIC mode, see PM pg. 137,
"miscellaneous controls", footnote to
"IDE interrupt select" */
Package () { 0x0010FFFF, 0x00, 0x00, 0x14 },
Package () { 0x0010FFFF, 0x01, 0x00, 0x16 },
Package () { 0x0010FFFF, 0x02, 0x00, 0x15 },
Package () { 0x0010FFFF, 0x03, 0x00, 0x17 },
Package () { 0x0011FFFF, 0x00, LNKA, 0x00 },
Package () { 0x0011FFFF, 0x01, LNKB, 0x00 },
Package () { 0x0011FFFF, 0x02, LNKC, 0x00 },
Package () { 0x0011FFFF, 0x03, LNKD, 0x00 },
Package () { 0x0012FFFF, 0x00, LNKD, 0x00 },
Package () { 0x0012FFFF, 0x01, LNKD, 0x00 },
Package () { 0x0012FFFF, 0x02, LNKD, 0x00 },
Package () { 0x0012FFFF, 0x03, LNKD, 0x00 },
})

View File

@ -0,0 +1,61 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 15 devices on the bus */
0x00, /* Where the interrupt router lies (bus) */
(0x11 << 3) | 0x0, /* Where the interrupt router lies (dev) */
0xc20, /* IRQs devoted exclusively to PCI usage */
0x1106, /* Vendor */
0x596, /* Device */
0, /* Crap (miniport) */
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, /* u8 rfu[11] */
0x84, /* u8 checksum. This has to be 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, (0x08 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x1, 0x0},
{0x00, (0x09 << 3) | 0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0x0deb8}}, 0x2, 0x0},
{0x00, (0x0a << 3) | 0x0, {{0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0x0deb8}}, 0x3, 0x0},
{0x02, (0x03 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x4, 0x0},
{0x02, (0x04 << 3) | 0x0, {{0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0x0deb8}}, 0x5, 0x0},
{0x02, (0x05 << 3) | 0x0, {{0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0x0deb8}}, 0x6, 0x0},
{0x02, (0x06 << 3) | 0x0, {{0x05, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0x0deb8}}, 0x7, 0x0},
{0x02, (0x07 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x8, 0x0},
{0x02, (0x08 << 3) | 0x0, {{0x03, 0xdeb8}, {0x05, 0xdeb8}, {0x01, 0xdeb8}, {0x02, 0x0deb8}}, 0x9, 0x0},
{0x00, (0x01 << 3) | 0x0, {{0x02, 0xdeb8}, {0x02, 0xdeb8}, {0x02, 0xdeb8}, {0x02, 0x0deb8}}, 0x0, 0x0},
{0x80, (0x01 << 3) | 0x0, {{0x02, 0xdeb8}, {0x02, 0xdeb8}, {0x02, 0xdeb8}, {0x02, 0x0deb8}}, 0x0, 0x0},
{0x00, (0x11 << 3) | 0x0, {{0x00, 0xdeb8}, {0x00, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x0, 0x0},
{0x00, (0x0f << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x0, 0x0},
{0x00, (0x01 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x0, 0x0},
{0x00, (0x10 << 3) | 0x0, {{0x01, 0xdeb8}, {0x02, 0xdeb8}, {0x03, 0xdeb8}, {0x05, 0x0deb8}}, 0x0, 0x0}
}
};
inline unsigned long write_pirq_routing_table(unsigned long addr)
{
return copy_pirq_routing_table(addr);
}

View File

@ -0,0 +1,28 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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_ops = {
CHIP_NAME("VIA VT8454c Mainboard")
};

View File

@ -0,0 +1,104 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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 <device/pci.h>
#include <arch/smp/mpspec.h>
#include <cpu/x86/lapic.h>
#include <console/console.h>
#include <string.h>
#include <stdint.h>
void *smp_write_config_table(void *v)
{
static const char sig[4] = MPC_SIGNATURE;
static const char oem[8] = "COREBOOT";
static const char productid[12] = "VIA VT8454C ";
struct mp_config_table *mc;
mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
memset(mc, 0, sizeof(*mc));
memcpy(mc->mpc_signature, sig, sizeof(sig));
mc->mpc_length = sizeof(*mc); /* initially just the header */
mc->mpc_spec = 0x04;
mc->mpc_checksum = 0; /* not yet computed */
memcpy(mc->mpc_oem, oem, sizeof(oem));
memcpy(mc->mpc_productid, productid, sizeof(productid));
mc->mpc_oemptr = 0;
mc->mpc_oemsize = 0;
mc->mpc_entry_count = 0; /* No entries yet... */
mc->mpc_lapic = LAPIC_ADDR;
mc->mpe_length = 0;
mc->mpe_checksum = 0;
mc->reserved = 0;
smp_write_processors(mc);
/*Bus: Bus ID Type */
smp_write_bus(mc, 0, "PCI ");
smp_write_bus(mc, 1, "PCI ");
smp_write_bus(mc, 2, "PCI ");
smp_write_bus(mc, 128, "PCI ");
smp_write_bus(mc, 129, "ISA ");
/* I/O APICs: APIC ID Version State Address */
smp_write_ioapic(mc, 2, 17, 0xfec00000);
/* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x0, 0x40, 0x2, 0x14);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x0, 0x41, 0x2, 0x16);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x0, 0x42, 0x2, 0x15);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x0, 0x43, 0x2, 0x17);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x80, 0x4, 0x2, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x1, 0x0, 0x2, 0x11);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW, 0x2, 0x10, 0x2, 0x11);
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x0, 0x2, 0x0);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x1, 0x2, 0x1);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x0, 0x2, 0x2);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x3, 0x2, 0x3);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x4, 0x2, 0x4);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x6, 0x2, 0x6);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x7, 0x2, 0x7);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, 0x81, 0x8, 0x2, 0x8);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0x9, 0x2, 0x9);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0xc, 0x2, 0xc);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0xd, 0x2, 0xd);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0xe, 0x2, 0xe);
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x81, 0xf, 0x2, 0xf);
/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x0, 0x0, MP_APIC_ALL, 0x0);
smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, 0x0, 0x0, MP_APIC_ALL, 0x1);
/* Compute the checksums */
mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
printk_debug("Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
return smp_next_mpe_entry(mc);
}
unsigned long write_smp_table(unsigned long addr)
{
void *v;
v = smp_write_floating_table(addr);
return (unsigned long)smp_write_config_table(v);
}

View File

@ -0,0 +1,28 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of
* the License.
*
* 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/romcc_io.h"
void hard_reset(void)
{
set_bios_reset();
outb(0x06, 0x0cf9);
}

View File

@ -0,0 +1,28 @@
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of the License.
##
## 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 cx700_reset.o
object northbridge.o
object vgabios.o
driver cx700_agp.o
driver cx700_lpc.o
driver cx700_sata.o
driver cx700_vga.o

View File

@ -0,0 +1,23 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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_via_cx700_config {
};
extern struct chip_operations northbridge_via_cx700_ops;

View File

@ -0,0 +1,91 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
/* This is the AGP 3.0 "bridge" @ Bus 0 Device 1 Func 0 */
static void agp_bridge_init(device_t dev)
{
device_t north_dev;
u8 reg8;
north_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3324, 0);
pci_write_config8(north_dev, 0xa0, 0x1); // Enable CPU Direct Access Frame Buffer
pci_write_config8(north_dev, 0xa2, 0x4a);
reg8 = pci_read_config8(north_dev, 0xc0);
reg8 |= 0x1;
pci_write_config8(north_dev, 0xc0, reg8);
/*
* Since Internal Graphic already set to AGP3.0 compatible in its Capability Pointer
* We must set RAGP8X=1 B0D0F0 Rx84[3]=1 from backdoor register B0D0F0 RxB5[1:0]=11b
*/
north_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x0324, 0);
reg8 = pci_read_config8(north_dev, 0xb5);
reg8 |= 0x3;
pci_write_config8(north_dev, 0xb5, reg8);
pci_write_config8(north_dev, 0x94, 0x20);
pci_write_config8(north_dev, 0x13, 0xd0);
pci_write_config16(dev, 0x4, 0x0007);
pci_write_config8(dev, 0x19, 0x01);
pci_write_config8(dev, 0x1a, 0x01);
pci_write_config8(dev, 0x1c, 0xe0);
pci_write_config8(dev, 0x1d, 0xe0);
pci_write_config16(dev, 0x1e, 0xa220);
pci_write_config16(dev, 0x20, 0xdd00);
pci_write_config16(dev, 0x22, 0xdef0);
pci_write_config16(dev, 0x24, 0xa000);
pci_write_config16(dev, 0x26, 0xbff0);
pci_write_config8(dev, 0x3e, 0x0c);
pci_write_config8(dev, 0x40, 0x8b);
pci_write_config8(dev, 0x41, 0x43);
pci_write_config8(dev, 0x42, 0x62);
pci_write_config8(dev, 0x43, 0x44);
pci_write_config8(dev, 0x44, 0x34);
}
static void cx700_noop(device_t dev)
{
}
static struct device_operations agp_bridge_operations = {
.read_resources = cx700_noop,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_bus_enable_resources,
.init = agp_bridge_init,
.scan_bus = pci_scan_bridge,
};
static const struct pci_driver agp_bridge_driver __pci_driver = {
.ops = &agp_bridge_operations,
.vendor = PCI_VENDOR_ID_VIA,
.device = 0xb198,
};

View File

@ -0,0 +1,102 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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
*/
/*
* Enable the serial devices on the VIA CX700
*/
#include <arch/romcc_io.h>
static void cx700_writepnpaddr(u8 val)
{
outb(val, 0x2e);
outb(val, 0xeb);
}
static void cx700_writepnpdata(u8 val)
{
outb(val, 0x2f);
outb(val, 0xeb);
}
static void cx700_writesiobyte(u16 reg, u8 val)
{
outb(val, reg);
}
static void cx700_writesioword(u16 reg, u16 val)
{
outw(val, reg);
}
static void enable_cx700_serial(void)
{
outb(6, 0x80);
// WTH?
outb(0x03, 0x22);
// Set UART1 I/O Base Address
pci_write_config8(PCI_DEV(0, 17, 0), 0xb4, 0x7e);
// UART1 Enable
pci_write_config8(PCI_DEV(0, 17, 0), 0xb0, 0x10);
// turn on pnp
cx700_writepnpaddr(0x87);
cx700_writepnpaddr(0x87);
// now go ahead and set up com1.
// set address
cx700_writepnpaddr(0x7);
cx700_writepnpdata(0x2);
// enable serial out
cx700_writepnpaddr(0x30);
cx700_writepnpdata(0x1);
// serial port 1 base address (FEh)
cx700_writepnpaddr(0x60);
cx700_writepnpdata(0xfe);
// serial port 1 IRQ (04h)
cx700_writepnpaddr(0x70);
cx700_writepnpdata(0x4);
// serial port 1 control
cx700_writepnpaddr(0xf0);
cx700_writepnpdata(0x2);
// turn of pnp
cx700_writepnpaddr(0xaa);
// XXX This part should be fully taken care of by
// src/pc80/serial.c:uart_init
// set up reg to set baud rate.
cx700_writesiobyte(0x3fb, 0x80);
// Set 115 kb
cx700_writesioword(0x3f8, 1);
// Set 9.6 kb
// cx700_writesioword(0x3f8, 12)
// now set no parity, one stop, 8 bits
cx700_writesiobyte(0x3fb, 3);
// now turn on RTS, DRT
cx700_writesiobyte(0x3fc, 3);
// Enable interrupts
cx700_writesiobyte(0x3f9, 0xf);
// should be done. Dump a char for fun.
cx700_writesiobyte(0x3f8, 48);
outb(7, 0x80);
}

View File

@ -0,0 +1,268 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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
*/
// other bioses use this, too:
#define SMBUS_IO_BASE 0x0500
#define SMBHSTSTAT SMBUS_IO_BASE + 0x0
#define SMBSLVSTAT SMBUS_IO_BASE + 0x1
#define SMBHSTCTL SMBUS_IO_BASE + 0x2
#define SMBHSTCMD SMBUS_IO_BASE + 0x3
#define SMBXMITADD SMBUS_IO_BASE + 0x4
#define SMBHSTDAT0 SMBUS_IO_BASE + 0x5
#define SMBHSTDAT1 SMBUS_IO_BASE + 0x6
#define SMBBLKDAT SMBUS_IO_BASE + 0x7
#define SMBSLVCTL SMBUS_IO_BASE + 0x8
#define SMBTRNSADD SMBUS_IO_BASE + 0x9
#define SMBSLVDATA SMBUS_IO_BASE + 0xa
#define SMLINK_PIN_CTL SMBUS_IO_BASE + 0xe
#define SMBUS_PIN_CTL SMBUS_IO_BASE + 0xf
/* Define register settings */
#define HOST_RESET 0xff
#define DIMM_BASE 0xa0 // 1010000 is base for DIMM in SMBus
#define READ_CMD 0x01 // 1 in the 0 bit of SMBHSTADD states to READ
#define SMBUS_TIMEOUT (100*1000*10)
#define I2C_TRANS_CMD 0x40
#define CLOCK_SLAVE_ADDRESS 0x69
#define SMBUS_DELAY() outb(0x80, 0x80)
/* Debugging macros. */
// #define DEBUG_SMBUS 1
#ifdef DEBUG_SMBUS
#define PRINT_DEBUG(x) print_debug(x)
#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
#else
#define PRINT_DEBUG(x)
#define PRINT_DEBUG_HEX16(x)
#endif
/* Internal functions */
static void smbus_print_error(unsigned char host_status_register, int loops)
{
/* Check if there actually was an error */
if (host_status_register == 0x00 || host_status_register == 0x40 ||
host_status_register == 0x42)
return;
print_err("SMBus Error: ");
print_err_hex8(host_status_register);
print_err("\r\n");
if (loops >= SMBUS_TIMEOUT) {
print_err("SMBus Timout\r\n");
}
if (host_status_register & (1 << 4)) {
print_err("Interrup/SMI# was Failed Bus Transaction\r\n");
}
if (host_status_register & (1 << 3)) {
print_err("Bus Error\r\n");
}
if (host_status_register & (1 << 2)) {
print_err("Device Error\r\n");
}
if (host_status_register & (1 << 1)) {
/* This isn't a real error... */
print_debug("Interrupt/SMI# was Successful Completion\r\n");
}
if (host_status_register & (1 << 0)) {
print_err("Host Busy\r\n");
}
}
static void smbus_wait_until_ready(void)
{
int loops;
loops = 0;
/* Yes, this is a mess, but it's the easiest way to do it */
while (((inb(SMBHSTSTAT) & 1) == 1) && (loops <= SMBUS_TIMEOUT)) {
SMBUS_DELAY();
++loops;
}
#ifdef DEBUG_SMBUS
/* Some systems seem to have a flakey SMBus. No need to spew a lot of
* errors on those, once we know that SMBus access is principally
* working.
*/
smbus_print_error(inb(SMBHSTSTAT), loops);
#endif
}
static void smbus_reset(void)
{
outb(HOST_RESET, SMBHSTSTAT);
}
/* Public functions */
static void set_ics_data(unsigned char dev, int data, char len)
{
//int i;
smbus_reset();
/* clear host data port */
outb(0x00, SMBHSTDAT0);
SMBUS_DELAY();
smbus_wait_until_ready();
/* read to reset block transfer counter */
inb(SMBHSTCTL);
/* fill blocktransfer array */
if (dev = 0xd2) {
//char d2_data[] = {0x0d,0x00,0x3f,0xcd,0x7f,0xbf,0x1a,0x2a,0x01,0x0f,0x0b,0x00,0x8d,0x9b};
outb(0x0d, SMBBLKDAT);
outb(0x00, SMBBLKDAT);
outb(0x3f, SMBBLKDAT);
outb(0xcd, SMBBLKDAT);
outb(0x7f, SMBBLKDAT);
outb(0xbf, SMBBLKDAT);
outb(0x1a, SMBBLKDAT);
outb(0x2a, SMBBLKDAT);
outb(0x01, SMBBLKDAT);
outb(0x0f, SMBBLKDAT);
outb(0x0b, SMBBLKDAT);
outb(0x80, SMBBLKDAT);
outb(0x8d, SMBBLKDAT);
outb(0x9b, SMBBLKDAT);
} else {
//char d4_data[] = {0x08,0xff,0x3f,0x00,0x00,0xff,0xff,0xff,0xff};
outb(0x08, SMBBLKDAT);
outb(0xff, SMBBLKDAT);
outb(0x3f, SMBBLKDAT);
outb(0x00, SMBBLKDAT);
outb(0x00, SMBBLKDAT);
outb(0xff, SMBBLKDAT);
outb(0xff, SMBBLKDAT);
outb(0xff, SMBBLKDAT);
outb(0xff, SMBBLKDAT);
}
//for (i=0; i < len; i++)
// outb(data[i],SMBBLKDAT);
outb(dev, SMBXMITADD);
outb(0, SMBHSTCMD);
outb(len, SMBHSTDAT0);
outb(0x74, SMBHSTCTL);
SMBUS_DELAY();
smbus_wait_until_ready();
smbus_reset();
}
static unsigned int get_spd_data(const struct mem_controller *ctrl, unsigned int dimm,
unsigned int offset)
{
unsigned int val, addr;
smbus_reset();
/* clear host data port */
outb(0x00, SMBHSTDAT0);
SMBUS_DELAY();
smbus_wait_until_ready();
/* Fetch the SMBus address of the SPD ROM from
* the ctrl struct in auto.c in case they are at
* non-standard positions.
* SMBus Address shifted by 1
*/
addr = (ctrl->channel0[dimm]) << 1;
outb(addr | 0x1, SMBXMITADD);
outb(offset, SMBHSTCMD);
outb(0x48, SMBHSTCTL);
SMBUS_DELAY();
smbus_wait_until_ready();
val = inb(SMBHSTDAT0);
smbus_reset();
return val;
}
static void enable_smbus(void)
{
device_t dev;
/* The CX700 ISA Bridge (0x1106, 0x8324) is hardcoded to this location,
* no need to probe.
*/
dev = PCI_DEV(0, 17, 0);
/* SMBus Clock Select: Divider fof 14.318MHz */
pci_write_config8(dev, 0x94, 0x20);
/* SMBus I/O Base, enable SMBus */
pci_write_config16(dev, 0xd0, SMBUS_IO_BASE | 1);
/* SMBus Clock from 128K Source, Enable SMBus Host Controller */
pci_write_config8(dev, 0xd2, 0x05);
/* Enable I/O decoding */
pci_write_config16(dev, 0x04, 0x0003);
/* Setup clock chips */
set_ics_data(0xd2, 0, 14);
set_ics_data(0xd4, 0, 9);
}
/* Debugging Function */
#ifdef DEBUG_SMBUS
static void dump_spd_data(const struct mem_controller *ctrl)
{
int dimm, offset, regs;
unsigned int val;
for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
print_debug("SPD Data for DIMM ");
print_debug_hex8(dimm);
print_debug("\r\n");
val = get_spd_data(ctrl, dimm, 0);
if (val == 0xff) {
regs = 256;
} else if (val == 0x80) {
regs = 128;
} else {
print_debug("No DIMM present\r\n");
regs = 0;
}
for (offset = 0; offset < regs; offset++) {
print_debug(" Offset ");
print_debug_hex8(offset);
print_debug(" = 0x");
print_debug_hex8(get_spd_data(ctrl, dimm, offset));
print_debug("\r\n");
}
}
}
#else
#define dump_spd_data(ctrl)
#endif

View File

@ -0,0 +1,397 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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/io.h>
#include <console/console.h>
#include <device/device.h>
#include <device/pci.h>
#include <device/pci_ops.h>
#include <device/pci_ids.h>
#include <pc80/mc146818rtc.h>
#include <pc80/i8259.h>
#include <pc80/keyboard.h>
#include <pc80/isa-dma.h>
#include <cpu/x86/lapic.h>
#include <stdlib.h>
#define ACPI_IO_BASE 0x400
#define HPET_ADDR 0xfe800000UL
#define IOAPIC_ADDR 0xfec00000ULL
#ifdef CONFIG_IOAPIC
struct ioapicreg {
unsigned int reg;
unsigned int value_low, value_high;
};
static struct ioapicreg ioapicregvalues[] = {
#define ALL (0xff << 24)
#define NONE (0)
#define DISABLED (1 << 16)
#define ENABLED (0 << 16)
#define TRIGGER_EDGE (0 << 15)
#define TRIGGER_LEVEL (1 << 15)
#define POLARITY_HIGH (0 << 13)
#define POLARITY_LOW (1 << 13)
#define PHYSICAL_DEST (0 << 11)
#define LOGICAL_DEST (1 << 11)
#define ExtINT (7 << 8)
#define NMI (4 << 8)
#define SMI (2 << 8)
#define INT (1 << 8)
/* IO-APIC virtual wire mode configuration */
/* mask, trigger, polarity, destination, delivery, vector */
{ 0, ENABLED | TRIGGER_EDGE | POLARITY_HIGH | PHYSICAL_DEST | ExtINT, NONE},
{ 1, DISABLED, NONE},
{ 2, DISABLED, NONE},
{ 3, DISABLED, NONE},
{ 4, DISABLED, NONE},
{ 5, DISABLED, NONE},
{ 6, DISABLED, NONE},
{ 7, DISABLED, NONE},
{ 8, DISABLED, NONE},
{ 9, DISABLED, NONE},
{10, DISABLED, NONE},
{11, DISABLED, NONE},
{12, DISABLED, NONE},
{13, DISABLED, NONE},
{14, DISABLED, NONE},
{15, DISABLED, NONE},
{16, DISABLED, NONE},
{17, DISABLED, NONE},
{18, DISABLED, NONE},
{19, DISABLED, NONE},
{20, DISABLED, NONE},
{21, DISABLED, NONE},
{22, DISABLED, NONE},
{23, DISABLED, NONE},
};
static void setup_ioapic(void)
{
int i;
unsigned long value_low, value_high, val;
unsigned long ioapic_base = IOAPIC_ADDR;
volatile unsigned long *l;
struct ioapicreg *a = ioapicregvalues;
unsigned long bsp_lapicid = lapicid();
l = (unsigned long *)ioapic_base;
/* Set APIC ADDR */
l[0] = 0;
val = l[4];
l[4] = (val & 0xF0FFFF) | (2 << 24); // 2 == ID as programmed elsewhere. should be a define? XXX
/* Set APIC to FSB message bus. */
l[0] = 0x3;
val = l[4];
l[4] = (val & 0xFFFFFE) | 1;
ioapicregvalues[0].value_high = bsp_lapicid << (56 - 32);
printk_debug("IOAPIC: Bootstrap Processor Local APIC ID = %02x\n", bsp_lapicid);
for (i = 0; i < ARRAY_SIZE(ioapicregvalues); i++, a++) {
l[0] = (a->reg * 2) + 0x10;
l[4] = a->value_low;
value_low = l[4];
l[0] = (a->reg * 2) + 0x11;
l[4] = a->value_high;
value_high = l[4];
if ((i == 0) && (value_low == 0xffffffff)) {
printk_warning("IOAPIC is not responding.\n");
return;
}
printk_debug("IOAPIC: IRQ reg 0x%08x value 0x%08x 0x%08x\n",
a->reg, a->value_low, a->value_high);
}
}
#endif
static const unsigned char pci_irqs[4] = { 11, 11, 10, 10 };
static const unsigned char usb_pins[4] = { 'A', 'B', 'C', 'D' };
static const unsigned char vga_pins[4] = { 'A', 'B', 'C', 'D' };
static const unsigned char slot_pins[4] = { 'B', 'C', 'D', 'A' };
static const unsigned char ac97_pins[4] = { 'B', 'C', 'D', 'A' };
static unsigned char *pin_to_irq(const unsigned char *pin)
{
static unsigned char irqs[4];
int i;
for (i = 0; i < 4; i++)
irqs[i] = pci_irqs[pin[i] - 'A'];
return irqs;
}
static void pci_routing_fixup(struct device *dev)
{
printk_debug("%s: device is %p\n", __FUNCTION__, dev);
/* set up PCI IRQ routing */
pci_write_config8(dev, 0x55, pci_irqs[0] << 4);
pci_write_config8(dev, 0x56, pci_irqs[1] | (pci_irqs[2] << 4));
pci_write_config8(dev, 0x57, pci_irqs[3] << 4);
/* Assigning IRQs */
printk_debug("Setting up USB interrupts.\n");
pci_assign_irqs(0, 0x10, pin_to_irq(usb_pins));
printk_debug("Setting up VGA interrupts.\n");
pci_assign_irqs(1, 0x00, pin_to_irq(vga_pins));
printk_debug("Setting up PCI slot interrupts.\n");
pci_assign_irqs(2, 0x04, pin_to_irq(slot_pins));
// more?
printk_debug("Setting up AC97 interrupts.\n");
pci_assign_irqs(0x80, 0x1, pin_to_irq(ac97_pins));
}
/*
* Set up the power management capabilities directly into ACPI mode. This
* avoids having to handle any System Management Interrupts (SMI's) which I
* can't figure out how to do !!!!
*/
void setup_pm(device_t dev)
{
/* Debounce LID and PWRBTN# Inputs for 16ms. */
pci_write_config8(dev, 0x80, 0x20);
/* Set ACPI base address to IO ACPI_IO_BASE */
pci_write_config16(dev, 0x88, ACPI_IO_BASE | 1);
/* set ACPI irq to 9 */
pci_write_config8(dev, 0x82, 0x49);
/* Primary interupt channel, define wake events 0=IRQ0 15=IRQ15 1=en. */
pci_write_config16(dev, 0x84, 0x609a);
/* SMI output level to low, 7.5us throttle clock */
pci_write_config8(dev, 0x8d, 0x18);
/* GP Timer Control 1s */
pci_write_config8(dev, 0x93, 0x88);
/* Power Well */
pci_write_config8(dev, 0x94, 0x20); // 0x20??
/* 7 = stp to sust delay 1msec
* 6 = SUSST# Deasserted Before PWRGD for STD
*/
pci_write_config8(dev, 0x95, 0xc0); // 0xc1??
/* Disable GP2 & GP3 Timer */
pci_write_config8(dev, 0x98, 0);
/* GP2 Timer Counter */
pci_write_config8(dev, 0x99, 0xfb);
/* GP3 Timer Counter */
//pci_write_config8(dev, 0x9a, 0x20);
/* Multi Function Select 1 */
pci_write_config8(dev, 0xe4, 0x00);
/* Multi Function Select 2 */
pci_write_config8(dev, 0xe5, 0x41); //??
/* Enable ACPI access (and setup like award) */
pci_write_config8(dev, 0x81, 0x84);
/* Clear status events. */
outw(0xffff, ACPI_IO_BASE + 0x00);
outw(0xffff, ACPI_IO_BASE + 0x20);
outw(0xffff, ACPI_IO_BASE + 0x28);
outl(0xffffffff, ACPI_IO_BASE + 0x30);
/* Disable SCI on GPIO. */
outw(0x0, ACPI_IO_BASE + 0x22);
/* Disable SMI on GPIO. */
outw(0x0, ACPI_IO_BASE + 0x24);
/* Disable all global enable SMIs. */
outw(0x0, ACPI_IO_BASE + 0x2a);
/* All SMI off, both IDE buses ON, PSON rising edge. */
outw(0x0, ACPI_IO_BASE + 0x2c);
/* Primary activity SMI disable. */
outl(0x0, ACPI_IO_BASE + 0x34);
/* GP timer reload on none. */
outl(0x0, ACPI_IO_BASE + 0x38);
/* Disable extended IO traps. */
outb(0x0, ACPI_IO_BASE + 0x42);
/* SCI is generated for RTC/pwrBtn/slpBtn. */
outw(0x0001, ACPI_IO_BASE + 0x04);
/* Allow SLP# signal to assert LDTSTOP_L.
* Will work for C3 and for FID/VID change.
*/
outb(0x1, ACPI_IO_BASE + 0x11);
}
static void cx700_set_lpc_registers(struct device *dev)
{
unsigned char enables;
printk_debug("VIA CX700 LPC bridge init\n");
// enable the internal I/O decode
enables = pci_read_config8(dev, 0x6C);
enables |= 0x80;
pci_write_config8(dev, 0x6C, enables);
// Map 4MB of FLASH into the address space
// pci_write_config8(dev, 0x41, 0x7f);
// Set bit 6 of 0x40, because Award does it (IO recovery time)
// IMPORTANT FIX - EISA 0x4d0 decoding must be on so that PCI
// interrupts can be properly marked as level triggered.
enables = pci_read_config8(dev, 0x40);
enables |= 0x44;
pci_write_config8(dev, 0x40, enables);
/* DMA Line buffer control */
enables = pci_read_config8(dev, 0x42);
enables |= 0xf0;
pci_write_config8(dev, 0x42, enables);
/* I/O recovery time */
pci_write_config8(dev, 0x4c, 0x44);
/* ROM memory cycles go to LPC. */
pci_write_config8(dev, 0x59, 0x80);
/* Enable SM dynamic clock gating */
pci_write_config8(dev, 0x5b, 0x01);
/* Set Read Pass Write Control Enable */
pci_write_config8(dev, 0x48, 0x0c);
/* Set SM Misc Control: Enable Internal APIC . */
enables = pci_read_config8(dev, 0x58);
enables |= 1 << 6;
pci_write_config8(dev, 0x58, enables);
enables = pci_read_config8(dev, 0x4d);
enables |= 1 << 3;
pci_write_config8(dev, 0x4d, enables);
/* Set bit 3 of 0x4f to match award (use INIT# as cpu reset) */
enables = pci_read_config8(dev, 0x4f);
enables |= 0x08;
pci_write_config8(dev, 0x4f, enables);
/* enable KBC configuration */
pci_write_config8(dev, 0x51, 0x1f);
/* enable serial irq */
pci_write_config8(dev, 0x52, 0x9);
/* dma */
pci_write_config8(dev, 0x53, 0x00);
// Power management setup
setup_pm(dev);
/* set up isa bus -- i/o recovery time, rom write enable, extend-ale */
pci_write_config8(dev, 0x40, 0x54);
/* Enable HPET timer */
pci_write_config32(dev, 0x68, (1 << 31) | (HPET_ADDR >> 8));
}
void cx700_read_resources(device_t dev)
{
struct resource *resource;
/* Make sure we call our childrens set/enable functions - these
* are not called unless this device has a resource to set.
*/
pci_dev_read_resources(dev);
resource = new_resource(dev, 1);
resource->flags |=
IORESOURCE_FIXED | IORESOURCE_ASSIGNED | IORESOURCE_IO | IORESOURCE_STORED;
resource->size = 2;
resource->base = 0x2e;
}
void cx700_set_resources(device_t dev)
{
struct resource *resource;
resource = find_resource(dev, 1);
resource->flags |= IORESOURCE_STORED;
pci_dev_set_resources(dev);
}
void cx700_enable_resources(device_t dev)
{
/* Enable SuperIO decoding */
pci_dev_enable_resources(dev);
enable_childrens_resources(dev);
}
static void cx700_lpc_init(struct device *dev)
{
cx700_set_lpc_registers(dev);
#ifdef CONFIG_IOAPIC
setup_ioapic();
#endif
/* Initialize interrupts */
pci_routing_fixup(dev);
/* make sure interupt controller is configured before keyboard init */
setup_i8259();
/* Start the Real Time Clock */
rtc_init(0);
/* Initialize isa dma */
isa_dma_init();
/* Initialize keyboard controller */
init_pc_keyboard(0x60, 0x64, 0);
}
static struct device_operations cx700_lpc_ops = {
.read_resources = cx700_read_resources,
.set_resources = cx700_set_resources,
.enable_resources = cx700_enable_resources,
.init = &cx700_lpc_init,
.scan_bus = scan_static_bus,
};
static const struct pci_driver lpc_driver __pci_driver = {
.ops = &cx700_lpc_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = 0x8324,
};

View File

@ -0,0 +1,272 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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
*/
/* CX700 has 48 bytes of scratch registers in D0F4 starting at Reg. 0xd0 */
#define SCRATCH_REG_BASE 0xd0
#define SCRATCH_RANK_0 0xd0
#define SCRATCH_RANK_1 0xd1
#define SCRATCH_RANK_2 0xd2
#define SCRATCH_RANK_3 0xd3
#define SCRATCH_DIMM_NUM 0xd4
#define SCRATCH_RANK_NUM 0xd5
#define SCRATCH_RANK_MAP 0xd6
#define SCRATCH_DRAM_FREQ 0xd7
#define SCRATCH_DRAM_NB_ODT 0xd8
#define SCRATCH_RANK0_SIZE_REG 0xe0 /* RxE0~RxE3 */
#define SCRATCH_RANK0_MA_REG 0xe4 /* RxE4~RxE7 */
#define SCRATCH_CHA_DQSI_LOW_REG 0xe8
#define SCRATCH_CHA_DQSI_HIGH_REG 0xe9
#define SCRATCH_ChA_DQSI_REG 0xea
#define SCRATCH_DRAM_256M_BIT 0xee
#define SCRATCH_FLAGS 0xef
static const u8 Reg_Val[] = {
/* REG, VALUE */
0x70, 0x33,
0x71, 0x11,
0x72, 0x33,
0x73, 0x11,
0x74, 0x20,
0x75, 0x2e,
0x76, 0x64,
0x77, 0x00,
0x78, 0x44,
0x79, 0xaa,
0x7a, 0x33,
0x7b, 0xaa,
0x7c, 0x00,
0x7e, 0x33,
0x7f, 0x33,
0x80, 0x44,
0x81, 0x44,
0x82, 0x44,
0x83, 0x02,
0x50, 0x88,
0x51, 0x7b,
0x52, 0x6f,
0x53, 0x88,
0x54, 0x0e,
0x55, 0x00,
0x56, 0x00,
0x59, 0x00,
0x5d, 0x72,
0x5e, 0x88,
0x5f, 0xc7,
0x68, 0x01,
};
/* Host registers initial value */
static const u8 Host_Reg_Val[] = {
/* REG, VALUE */
0x60, 0xff,
0x61, 0xff,
0x62, 0x0f,
0x63, 0xff,
0x64, 0xff,
0x65, 0x0f,
0x66, 0xff,
0x67, 0x30,
};
static const u8 Mem_Reg_Init[] = {
/* REG, AND, OR */
0x50, 0x11, 0x66,
0x51, 0x11, 0x66,
0x52, 0x00, 0x11,
0x53, 0x00, 0x0f,
0x54, 0x00, 0x00,
0x55, 0x00, 0x00,
0x56, 0x00, 0x00,
0x57, 0x00, 0x00,
0x60, 0x00, 0x00,
0x62, 0xf7, 0x08,
0x65, 0x00, 0xd9,
0x66, 0x00, 0x80,
0x67, 0x00, 0x50, /* OR 0x00 ?? */
0x69, 0xf0, 0x00,
0x6a, 0x00, 0x00,
0x6d, 0xcf, 0xc0,
0x6e, 0xff, 0x80,
0x75, 0x0f, 0x40,
0x77, 0x00, 0x00,
0x80, 0x00, 0x00,
0x81, 0x00, 0x00,
0x82, 0x00, 0x00,
0x83, 0x00, 0x00,
0x84, 0x00, 0x00,
0x85, 0x00, 0x00,
0x86, 0xff, 0x2c, /* OR 0x28 if we don't want enable top 1M SM memory */
0x40, 0x00, 0x00,
0x7c, 0x00, 0x00,
0x7e, 0x00, 0x00,
0xa4, 0xfe, 0x00,
0xb0, 0x7f, 0x80,
0xb1, 0x00, 0xaa,
0xb4, 0xfd, 0x02,
0xb8, 0xfe, 0x00,
};
static const u8 Dram_Driving_ODT_CTRL[] = {
/* REG, VALUE */
0xd6, 0xa8,
0xd4, 0x80,
0xd0, 0x88,
0xd3, 0x01,
0xd8, 0x00,
0xda, 0x80,
};
#define Rank0_ODT 0x00
#define Rank1_ODT 0x01
#define Rank2_ODT 0x02
#define Rank3_ODT 0x03
#define NA_ODT 0x00
#define NB_ODT_75ohm 0x00
#define NB_ODT_150ohm 0x01
#define DDR2_ODT_75ohm 0x20
#define DDR2_ODT_150ohm 0x40
static const u8 ODT_TBL[] = {
/* RankMap, ODT Control Bits, DRAM & NB ODT setting */
0x01, ((NA_ODT << 6) | (NA_ODT << 4) | (NA_ODT << 2) | Rank0_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
0x03, ((NA_ODT << 6) | (NA_ODT << 4) | (Rank0_ODT << 2) | Rank1_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
0x04, ((NA_ODT << 6) | (Rank2_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
0x05, ((NA_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
0x07, ((NA_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
0x0c, ((Rank2_ODT << 6) | (Rank3_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
0x0d, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
0x0f, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
};
static const u8 DQS_DQ_TBL[] = {
/* RxE0: DRAM Timing DQS */
/* RxE2: DRAM Timing DQ */
/* RxE0, RxE2 */
0xee, 0xba,
0xee, 0xba,
0xcc, 0xba,
0xcc, 0xba,
};
static const u8 Duty_Control_DDR2[] = {
/* RxEC, RxED, RxEE, RXEF */
/* DDRII533 1~2 rank, DDRII400 */
0x84, 0x10, 0x00, 0x10,
/* DDRII533 3~4 rank */
0x44, 0x10, 0x00, 0x10,
};
static const u8 ChA_Clk_Phase_DDR2_Table[] = {
/* Rx91, Rx92, Rx93 */
/* DDRII533 1 rank */
0x04, 0x05, 0x06,
/* DDRII533 2~4 rank */
0x04, 0x05, 0x05,
/* DDRII400 */
0x02, 0x04, 0x04,
};
static const u8 DQ_DQS_Table[] = {
/* REG, VALUE */
/* DRAM DQ/DQS Output Delay Control */
0xdc, 0x65,
0xdd, 0x01,
0xde, 0xc0,
/* DRAM DQ/DQS input Capture Control */
0x78, 0x83,
0x79, 0x83,
0x7a, 0x00,
};
static const u8 DQSOChA_DDR2_Driving_Table[] = {
/* Rx70, Rx71 */
/* DDRII533 1~2 rank */
0x00, 0x01,
/* DDRII533 3~4 rank */
0x03, 0x00,
/* DDRII400 1~2 rank */
0x00, 0x04,
/* DDRII400 3~4 rank */
0x00, 0x01,
};
/************************************************************************/
/* Chipset Performance UP and other setting after DRAM Sizing Registers */
/************************************************************************/
static const u8 Dram_Table[] = {
/* REG, AND, OR */
0x60, 0xff, 0x03,
0x66, 0xcf, 0x80,
0x68, 0x00, 0x00,
0x69, 0xfd, 0x03,
0x6e, 0xff, 0x01,
0x95, 0xff, 0x40,
};
static const u8 Host_Table[] = {
/* REG, AND, OR */
0x51, 0x81, 0x7a,
0x55, 0xff, 0x06,
0x5e, 0x00, 0x88,
0x5d, 0xff, 0xb2,
};
static const u8 Init_Rank_Reg_Table[] = {
/* Rank Ending Address Registers */
0x40, 0x41, 0x42, 0x43,
/* Rank Beginning Address Registers */
0x48, 0x49, 0x4a, 0x4b,
/* Physical-to-Virtual Rank Mapping Registers */
0x54, 0x55,
};
static const u16 DDR2_MRS_table[] = {
/* CL: 2, 3, 4, 5 */
0x150, 0x1d0, 0x250, 0x2d0, /* BL=4 ;Use 1X-bandwidth MA table to init DRAM */
0x158, 0x1d8, 0x258, 0x2d8, /* BL=8 ;Use 1X-bandwidth MA table to init DRAM */
};
#define MRS_DDR2_TWR2 ((0 << 15) | (0 << 20) | (1 << 12))
#define MRS_DDR2_TWR3 ((0 << 15) | (1 << 20) | (0 << 12))
#define MRS_DDR2_TWR4 ((0 << 15) | (1 << 20) | (1 << 12))
#define MRS_DDR2_TWR5 ((1 << 15) | (0 << 20) | (0 << 12))
static const u32 DDR2_Twr_table[] = {
MRS_DDR2_TWR2,
MRS_DDR2_TWR3,
MRS_DDR2_TWR4,
MRS_DDR2_TWR5,
};
static const u8 DQSI_Rate_Table[] = {
8, /* DDRII 200 */
8, /* DDRII 266 */
8, /* DDRII 333 */
7, /* DDRII 400 */
8, /* DDRII 533 */
8, /* DDRII 666 */
};
static const u8 REFC_Table[] = {
0x65, 0x32, /* DDRII 100 */
0x86, 0x43, /* DDRII 266 */
0xa8, 0x54, /* DDRII 333 */
0xca, 0x65, /* DDRII 400 */
0xca, 0x86, /* DDRII 533 */
0xca, 0xa8, /* DDRII 666 */
};

View File

@ -0,0 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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/io.h>
void hard_reset(void)
{
outb((1 << 2) | (1 << 1), 0xcf9);
}

View File

@ -0,0 +1,160 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
/* IDE specific bits */
#define IDE_MODE_REG 0x09
#define IDE0_NATIVE_MODE (1 << 0)
#define IDE1_NATIVE_MODE (1 << 2)
/* These are default addresses */
#define IDE0_DATA_ADDR 0x1f0
#define IDE0_CONTROL_ADDR 0x3f4
#define IDE1_DATA_ADDR 0x170
#define IDE1_CONTROL_ADDR 0x370
#define BUS_MASTER_ADDR 0xfc00
#define CHANNEL_ENABLE_REG 0x40
#define ENABLE_IDE0 (1 << 0)
#define ENABLE_IDE1 (1 << 1)
/* TODO: better user configuration */
#define DISABLE_SATA 0
static void sata_init(struct device *dev)
{
u8 reg8;
printk_debug("Configuring VIA SATA & EIDE Controller\n");
/* Class IDE Disk, instead of RAID controller */
reg8 = pci_read_config8(dev, 0x45);
reg8 &= 0x7f; /* Sub Class Write Protect off */
pci_write_config8(dev, 0x45, reg8);
pci_write_config8(dev, 0x0a, 0x01);
reg8 |= 0x80; /* Sub Class Write Protect on */
pci_write_config8(dev, 0x45, reg8);
#if defined(DISABLE_SATA) && (DISABLE_SATA == 1)
printk_info("Disabling SATA (Primary Channel)\n");
/* Disable SATA channels */
pci_write_config8(dev, 0x40, 0x00);
#else
pci_write_config8(dev, 0x40, 0x43);
#endif
reg8 = pci_read_config8(dev, 0x6a);
reg8 |= 0x8; /* Mode Select set to Manual Mode */
reg8 &= ~7;
reg8 |= 0x2; /* Manual setting to 50 ohm */
pci_write_config8(dev, 0x6a, reg8);
reg8 = pci_read_config8(dev, 0x6b);
reg8 &= ~7;
reg8 |= 0x01; /* Autocomp of Termination */
pci_write_config8(dev, 0x6b, reg8);
/* Enable EIDE (secondary channel) even if SATA disabled */
reg8 = pci_read_config8(dev, 0xc0);
reg8 |= 0x1;
pci_write_config8(dev, 0xc0, reg8);
// Enable bus mastering, memory space acces, io space access
pci_write_config16(dev, 0x04, 0x0007);
/* Set SATA base ports. */
pci_write_config32(dev, 0x10, 0x01f1);
pci_write_config32(dev, 0x14, 0x03f5);
/* Set EIDE base ports. */
pci_write_config32(dev, 0x18, 0x0171);
pci_write_config32(dev, 0x1c, 0x0375);
/* SATA/EIDE Bus Master mode base address */
pci_write_config32(dev, 0x20, BUS_MASTER_ADDR | 1);
/* Enable read/write prefetch buffers */
reg8 = pci_read_config8(dev, 0xc1);
reg8 |= 0x30;
pci_write_config8(dev, 0xc1, reg8);
/* Set FIFO thresholds like */
pci_write_config8(dev, 0xc3, 0x1); /* FIFO flushed when 1/2 full */
/* EIDE Sector Size */
pci_write_config16(dev, 0xe8, 0x200);
/* Some Miscellaneous Control */
pci_write_config8(dev, 0x44, 0x7);
pci_write_config8(dev, 0x45, 0xaf);
pci_write_config8(dev, 0x46, 0x8);
/* EIDE Configuration */
reg8 = pci_read_config8(dev, 0xc4);
reg8 |= 0x10;
pci_write_config8(dev, 0xc4, reg8);
pci_write_config8(dev, 0xc5, 0xc);
/* Interrupt Line */
reg8 = pci_read_config8(dev, 0x45);
reg8 &= ~(1 << 4); /* Interrupt Line Write Protect off */
pci_write_config8(dev, 0x45, reg8);
pci_write_config8(dev, 0x3c, 0x0e); /* Interrupt */
/* Set the drive timing control */
pci_write_config16(dev, 0x48, 0x5d5d);
/* Enable only compatibility mode. */
reg8 = pci_read_config8(dev, 0x42);
reg8 &= ~0xa0;
pci_write_config8(dev, 0x42, reg8);
reg8 = pci_read_config8(dev, 0x42);
printk_debug("Reg 0x42 read back as 0x%x\n", reg8);
/* Support Staggered Spin-Up */
reg8 = pci_read_config8(dev, 0xb9);
if ((reg8 & 0x8) == 0) {
printk_debug("start OOB sequence on both drives\n");
reg8 |= 0x30;
pci_write_config8(dev, 0xb9, reg8);
}
}
static struct device_operations sata_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = sata_init,
.enable = 0,
.ops_pci = 0,
};
/* When the SATA controller is in IDE mode, the Device ID is 0x5324 */
static const struct pci_driver northbridge_driver __pci_driver = {
.ops = &sata_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = 0x5324,
};

View File

@ -0,0 +1,56 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 <device/device.h>
#include <device/pci.h>
#include <device/pci_ids.h>
static void usb_init(struct device *dev)
{
u32 reg32;
u8 reg8;
/* USB Specification says the device must be Bus Master */
printk_debug("UHCI: Setting up controller.. ");
reg32 = pci_read_config32(dev, PCI_COMMAND);
pci_write_config32(dev, PCI_COMMAND, reg32 | PCI_COMMAND_MASTER);
reg8 = pci_read_config8(dev, 0xca);
reg8 |= (1 << 0);
pci_write_config8(dev, 0xca, reg8);
printk_debug("done.\n");
}
static struct device_operations usb_ops = {
.read_resources = pci_dev_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = usb_init,
.enable = 0,
.ops_pci = 0,
};
static const struct pci_driver via_usb_driver __pci_driver = {
.ops = &usb_ops,
.vendor = PCI_VENDOR_ID_VIA,
.device = 0x3038,
};

View File

@ -0,0 +1,119 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/msr.h>
#include "chip.h"
#include "northbridge.h"
/* PCI Domain 1 Device 0 Function 0 */
#define SR_INDEX 0x3c4
#define SR_DATA 0x3c5
#define CRTM_INDEX 0x3b4
#define CRTM_DATA 0x3b5
#define CRTC_INDEX 0x3d4
#define CRTC_DATA 0x3d5
void setup_realmode_idt(void);
void do_vgabios(void);
void vga_enable_console(void);
void write_protect_vgabios(void)
{
device_t dev;
printk_debug("write_protect_vgabios\n");
dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3324, 0);
if (dev)
pci_write_config8(dev, 0x80, 0xff);
dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x7324, 0);
if (dev)
pci_write_config8(dev, 0x61, 0xff);
}
static void vga_init(device_t dev)
{
u8 reg8;
printk_debug("Initializing VGA...\n");
//*
pci_write_config8(dev, 0x04, 0x07);
pci_write_config8(dev, 0x3e, 0x02);
pci_write_config8(dev, 0x0d, 0x40);
pci_write_config32(dev, 0x10, 0xa0000008);
pci_write_config32(dev, 0x14, 0xdd000000);
pci_write_config8(dev, 0x3c, 0x0b);
//*/
printk_debug("Executing VGA option rom in real mode\n");
setup_realmode_idt();
do_vgabios();
printk_debug("Enable VGA console\n");
vga_enable_console();
/* It's not clear if these need to be programmed before or after
* the VGA bios runs. Try both, clean up later */
/* Set memory rate to 200MHz */
outb(0x3d, CRTM_INDEX);
reg8 = inb(CRTM_DATA);
reg8 &= 0x0f;
reg8 |= (0x3 << 4);
outb(0x3d, CRTM_INDEX);
outb(reg8, CRTM_DATA);
/* Set framebuffer size to 32mb */
reg8 = (32 / 4);
outb(0x39, SR_INDEX);
outb(reg8, SR_DATA);
}
static void vga_read_resources(device_t dev)
{
dev->rom_address = 0xfff80000;
dev->on_mainboard = 1;
pci_dev_read_resources(dev);
}
static struct device_operations vga_operations = {
.read_resources = vga_read_resources,
.set_resources = pci_dev_set_resources,
.enable_resources = pci_dev_enable_resources,
.init = vga_init,
.ops_pci = 0,
};
static const struct pci_driver vga_driver __pci_driver = {
.ops = &vga_operations,
.vendor = PCI_VENDOR_ID_VIA,
.device = 0x3157,
};

View File

@ -0,0 +1,182 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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/hypertransport.h>
#include <device/pci_ids.h>
#include <stdlib.h>
#include <string.h>
#include <bitops.h>
#include <cpu/cpu.h>
#include <cpu/x86/mtrr.h>
#include "chip.h"
#include "northbridge.h"
static void pci_domain_read_resources(device_t dev)
{
struct resource *resource;
/* Initialize the system wide io 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 u32 find_pci_tolm(struct bus *bus)
{
struct resource *min = NULL;
u32 tolm;
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;
u32 pci_tolm;
unsigned char reg;
unsigned long tomk, tolmk;
unsigned char rambits;
int idx;
pci_tolm = find_pci_tolm(&dev->link[0]);
mc_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3324, 0);
rambits = pci_read_config8(mc_dev, 0x88);
rambits >>= 2;
/* Get memory size and frame buffer from northbridge's registers.
*
* If register contains an invalid value we set frame buffer size to a
* default of 32M, but that probably won't happen.
*/
reg = pci_read_config8(mc_dev, 0xa1);
reg &= 0x70;
reg = reg >> 4;
/* TOP 1M SMM Memory */
if (reg == 0x0 || reg == 0x6 || reg == 0x7)
tomk = (((rambits << 6) - 32 - 1) * 1024); // Set frame buffer 32M for default
else
tomk = (((rambits << 6) - (4 << reg) - 1) * 1024);
/* Compute the top of Low memory */
tolmk = pci_tolm >> 10;
if (tolmk >= tomk) {
/* The PCI hole does does not overlap the memory. */
tolmk = tomk;
tolmk -= 1024; // TOP 1M SM Memory
}
/* Report the memory regions */
idx = 10;
/* TODO: Hole needed? Should this go elsewhere? */
ram_resource(dev, idx++, 0, 640); /* first 640k */
ram_resource(dev, idx++, 768, (tolmk - 768)); /* leave a hole for vga */
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)
{
/* Our wonderful device model */
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_via_cx700_ops = {
CHIP_NAME("VIA CX700 Northbridge")
.enable_dev = enable_dev
};

View File

@ -0,0 +1,25 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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_VIA_CX700_H
#define NORTHBRIDGE_VIA_CX700_H
extern unsigned int cx700_scan_root_bus(device_t root, unsigned int max);
#endif /* NORTHBRIDGE_VIA_CX700_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2007-2009 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; version 2 of the License.
*
* 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 RAMINIT_H
#define RAMINIT_H
#define DIMM_SOCKETS 2
struct mem_controller {
u16 channel0[DIMM_SOCKETS];
};
#endif

View File

@ -0,0 +1,783 @@
/*
* This file is part of the coreboot project.
*
* (C) 2007-2009 coresystems GmbH
* (See further copyright notices below)
*
* NOTE: This file is supposed to go away once the generic vm86 handler
* in util/x86emu is able to handle intXX hooks like yabel does.
*
* 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; version 2 of the License.
*
* 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 <device/pci.h>
#include <device/pci_ids.h>
#include <device/pci_ops.h>
#undef __KERNEL__
#include <arch/io.h>
#include <string.h>
void write_protect_vgabios(void);
/* vgabios.c. Derived from: */
/*------------------------------------------------------------ -*- C -*-
* 2 Kernel Monte a.k.a. Linux loading Linux on x86
*
* Erik Arjan Hendriks <hendriks@lanl.gov>
*
* This version is a derivative of the original two kernel monte
* which is (C) 2000 Scyld.
*
* Copyright (C) 2000 Scyld Computing Corporation
*
* Portions related to the alpha architecture are:
*
* Copyright(C) 2001 University of California. LA-CC Number 01-67.
* This software has been authored by an employee or employees of the
* University of California, operator of the Los Alamos National
* Laboratory under Contract No. W-7405-ENG-36 with the U.S.
* Department of Energy. The U.S. Government has rights to use,
* reproduce, and distribute this software. If the software is
* modified to produce derivative works, such modified software should
* be clearly marked, so as not to confuse it with the version
* available from LANL.
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by
* reference to http://www.gnu.org/licenses/gpl.html.
*
* This software is provided by the author(s) "as is" and any express
* or implied warranties, including, but not limited to, the implied
* warranties of merchantability and fitness for a particular purpose
* are disclaimed. In no event shall the author(s) be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability,
* whether in contract, strict liability, or tort (including
* negligence or otherwise) arising in any way out of the use of this
* software, even if advised of the possibility of such damage.
*
*--------------------------------------------------------------------*/
/* Modified to be a self sufficient plug in so that it can be used
without reliance on other parts of core Linuxbios
(C) 2005 Nick.Barker9@btinternet.com
Used initially for epia-m where there are problems getting the bios
emulator to successfully run this bios.
*/
/* Declare a temporary global descriptor table - necessary because the
Core part of the bios no longer sets up any 16 bit segments */
__asm__(
/* pointer to original gdt */
"gdtarg: \n"
" .word gdt_limit \n"
" .long gdt \n"
/* compute the table limit */
"__mygdt_limit = __mygdt_end - __mygdt - 1 \n"
"__mygdtaddr: \n"
" .word __mygdt_limit \n"
" .long __mygdt \n"
"__mygdt: \n"
/* selgdt 0, unused */
" .word 0x0000, 0x0000 \n"
" .byte 0x00, 0x00, 0x00, 0x00 \n"
/* selgdt 8, unused */
" .word 0x0000, 0x0000 \n"
" .byte 0x00, 0x00, 0x00, 0x00 \n"
/* selgdt 0x10, flat code segment */
" .word 0xffff, 0x0000 \n"
" .byte 0x00, 0x9b, 0xcf, 0x00 \n"
/* selgdt 0x18, flat data segment */
" .word 0xffff, 0x0000 \n"
" .byte 0x00, 0x93, 0xcf, 0x00 \n"
/* selgdt 0x20, unused */
" .word 0x0000, 0x0000 \n"
" .byte 0x00, 0x00, 0x00, 0x00 \n"
/* selgdt 0x28 16-bit 64k code at 0x00000000 */
" .word 0xffff, 0x0000 \n"
" .byte 0, 0x9a, 0, 0 \n"
/* selgdt 0x30 16-bit 64k data at 0x00000000 */
" .word 0xffff, 0x0000 \n"
" .byte 0, 0x92, 0, 0 \n"
"__mygdt_end: \n");
/* Declare a pointer to where our idt is going to be i.e. at mem zero */
__asm__("__myidt: \n"
/* 16-bit limit */
" .word 1023 \n"
/* 24-bit base */
" .long 0 \n" " .word 0 \n");
/* The address arguments to this function are PHYSICAL ADDRESSES */
static void real_mode_switch_call_vga(unsigned long devfn)
{
__asm__ __volatile__(
// paranoia -- does ecx get saved? not sure. This is
// the easiest safe thing to do.
" pushal \n"
/* save the stack */
" mov %esp, __stack \n"
" jmp 1f \n"
"__stack: .long 0 \n" "1:\n"
/* get devfn into %ecx */
" movl %esp, %ebp \n"
" movl 8(%ebp), %ecx \n"
/* load 'our' gdt */
" lgdt %cs:__mygdtaddr \n"
/* This configures CS properly for real mode. */
" ljmp $0x28, $__rms_16bit\n"
"__rms_16bit: \n"
" .code16 \n"
/* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
* descriptors. They will retain these configurations (limits,
* writability, etc.) once protected mode is turned off. */
" mov $0x30, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* Turn off protection (bit 0 in CR0) */
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax \n"
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $__rms_real\n"
"__rms_real: \n"
/* put the stack at the end of page zero.
* that way we can easily share it between real and protected,
* since the 16-bit ESP at segment 0 will work for any case.
*/
/* Setup a stack */
" mov $0x0, %ax \n"
" mov %ax, %ss \n"
" movl $0x1000, %eax \n"
" movl %eax, %esp \n"
/* Load our 16 it idt */
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" lidt __myidt \n"
/* Dump zeros in the other segregs */
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov $0x40, %ax \n"
" mov %ax, %ds \n"
" mov %cx, %ax \n"
/* run VGA BIOS at 0xc000:0003 */
" lcall $0xc000, $0x0003\n"
/* if we got here, just about done.
* Need to get back to protected mode */
" movl %cr0, %eax \n" " orl $0x0000001, %eax\n" /* PE = 1 */
" movl %eax, %cr0 \n"
/* Now that we are in protected mode jump to a 32 bit code segment. */
" data32 ljmp $0x10, $vgarestart\n"
"vgarestart:\n"
" .code32\n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* restore proper gdt and idt */
" lgdt %cs:gdtarg \n"
" lidt idtarg \n"
".globl vga_exit \n"
"vga_exit: \n"
" mov __stack, %esp \n"
" popal \n");
}
__asm__(".text\n" "real_mode_switch_end:\n");
extern char real_mode_switch_end[];
/* call vga bios int 10 function 0x4f14 to enable main console
epia-m does not always autosence the main console so forcing it on is good !! */
void vga_enable_console(void)
{
__asm__ __volatile__(
/* paranoia -- does ecx get saved? not sure. This is
* the easiest safe thing to do. */
" pushal \n"
/* save the stack */
" mov %esp, __stack \n"
/* load 'our' gdt */
" lgdt %cs:__mygdtaddr \n"
/* This configures CS properly for real mode. */
" ljmp $0x28, $__vga_ec_16bit\n"
"__vga_ec_16bit: \n"
" .code16 \n"
/* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
* descriptors. They will retain these configurations (limits,
* writability, etc.) once protected mode is turned off. */
" mov $0x30, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* Turn off protection (bit 0 in CR0) */
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax\n"
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $__vga_ec_real \n"
"__vga_ec_real: \n"
/* put the stack at the end of page zero.
* that way we can easily share it between real and protected,
* since the 16-bit ESP at segment 0 will work for any case.
*/
/* Setup a stack */
" mov $0x0, %ax \n"
" mov %ax, %ss \n"
" movl $0x1000, %eax \n"
" movl %eax, %esp \n"
/* debugging for RGM */
" mov $0x11, %al \n"
" outb %al, $0x80 \n"
/* Load our 16 it idt */
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" lidt __myidt \n"
/* Dump zeros in the other segregs */
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
/* ask bios to enable main console */
/* set up for int 10 call - values found from X server
* bios call routines */
" movw $0x4f14,%ax \n"
" movw $0x8003,%bx \n"
" movw $1, %cx \n"
" movw $0, %dx \n"
" movw $0, %di \n"
" int $0x10 \n"
" movb $0x55, %al \n"
" outb %al, $0x80 \n"
/* if we got here, just about done.
* Need to get back to protected mode */
" movl %cr0, %eax \n" " orl $0x0000001, %eax\n" /* PE = 1 */
" movl %eax, %cr0 \n"
/* Now that we are in protected mode jump to a 32 bit code segment. */
" data32 ljmp $0x10, $vga_ec_restart\n"
"vga_ec_restart:\n"
" .code32\n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* restore proper gdt and idt */
" lgdt %cs:gdtarg \n"
" lidt idtarg \n"
" .globl vga__ec_exit \n"
"vga_ec_exit:\n"
" mov __stack, %esp \n"
" popal\n");
}
void do_vgabios(void)
{
device_t dev;
unsigned long busdevfn;
unsigned int rom = 0;
unsigned char *buf;
unsigned int size = 64 * 1024;
int i;
/* clear vga bios data area */
for (i = 0x400; i < 0x500; i++) {
*(unsigned char *)i = 0;
}
dev = dev_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0);
if (!dev) {
printk_debug("NO VGA FOUND\n");
return;
}
printk_debug("found VGA: vid=%x, did=%x\n", dev->vendor, dev->device);
/* declare rom address here - keep any config data out of the way
* of core LXB stuff */
#warning ROM address hardcoded to 512K
rom = 0xfff80000;
pci_write_config32(dev, PCI_ROM_ADDRESS, rom | 1);
printk_debug("rom base, size: %x\n", rom);
buf = (unsigned char *)rom;
if ((buf[0] == 0x55) && (buf[1] == 0xaa)) {
memcpy((void *)0xc0000, buf, size);
write_protect_vgabios(); // in northbridge
// check signature again
buf = (unsigned char *)0xc0000;
if (buf[0] == 0x55 && buf[1] == 0xAA) {
busdevfn =
(dev->bus->secondary << 8) | dev->path.pci.devfn;
printk_debug("bus/devfn = %#x\n", busdevfn);
real_mode_switch_call_vga(busdevfn);
} else
printk_debug("Failed to copy VGA BIOS to 0xc0000\n");
} else
printk_debug("BAD SIGNATURE 0x%x 0x%x\n", buf[0], buf[1]);
pci_write_config32(dev, PCI_ROM_ADDRESS, 0);
}
// we had hoped to avoid this.
// this is a stub IDT only. It's main purpose is to ignore calls
// to the BIOS.
// no longer. Dammit. We have to respond to these.
struct realidt {
unsigned short offset, cs;
};
// from a handy writeup that andrey found.
// handler.
// There are some assumptions we can make here.
// First, the Top Of Stack (TOS) is located on the top of page zero.
// we can share this stack between real and protected mode.
// that simplifies a lot of things ...
// we'll just push all the registers on the stack as longwords,
// and pop to protected mode.
// second, since this only ever runs as part of linuxbios,
// we know all the segment register values -- so we don't save any.
// keep the handler that calls things small. It can do a call to
// more complex code in linuxbios itself. This helps a lot as we don't
// have to do address fixup in this little stub, and calls are absolute
// so the handler is relocatable.
void handler(void)
{
__asm__ __volatile__(" .code16 \n"
"idthandle: \n"
" pushal \n"
" movb $0, %al \n"
" ljmp $0, $callbiosint16\n"
"end_idthandle: \n"
" .code32 \n");
}
void debughandler(void)
{
__asm__ __volatile__(" .code16 \n"
"debughandle: \n"
" pushw %cx \n"
" movw $250, %cx \n"
"dbh1: \n"
" loop dbh1 \n"
" popw %cx \n"
" iret \n"
"end_debughandle: \n" ".code32 \n");
}
// Calling conventions. The first C function is called with this stuff
// on the stack. They look like value parameters, but note that if you
// modify them they will go back to the INTx function modified.
// the C function will call the biosint function with these as
// REFERENCE parameters. In this way, we can easily get
// returns back to the INTx caller (i.e. vgabios)
void callbiosint(void)
{
__asm__ __volatile__(" .code16 \n"
"callbiosint16: \n"
" push %ds \n"
" push %es \n"
" push %fs \n" " push %gs \n"
// clean up the int #. To save space we put it in the lower
// byte. But the top 24 bits are junk.
" andl $0xff, %eax\n"
// this push does two things:
// - put the INT # on the stack as a parameter
// - provides us with a temp for the %cr0 mods.
" pushl %eax \n" " movl %cr0, %eax\n" " orl $0x00000001, %eax\n" /* PE = 1 */
" movl %eax, %cr0\n"
/* Now that we are in protected mode jump to a 32 bit code segment. */
" data32 ljmp $0x10, $biosprotect\n"
"biosprotect: \n"
" .code32 \n"
" movw $0x18, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
" lidt idtarg \n"
" call biosint \n"
// back to real mode ...
" ljmp $0x28, $__rms_16bit2\n"
"__rms_16bit2: \n"
" .code16 \n"
/* 16 bit code from here on... */
/* Load the segment registers w/ properly configured segment
* descriptors. They will retain these configurations (limits,
* writability, etc.) once protected mode is turned off. */
" mov $0x30, %ax \n"
" mov %ax, %ds \n"
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov %ax, %ss \n"
/* Turn off protection (bit 0 in CR0) */
" movl %cr0, %eax \n"
" andl $0xFFFFFFFE, %eax \n"
" movl %eax, %cr0 \n"
/* Now really going into real mode */
" ljmp $0, $__rms_real2 \n"
"__rms_real2: \n"
/* Setup a stack
* FixME: where is esp? */
" mov $0x0, %ax \n"
" mov %ax, %ss \n"
/* ebugging for RGM */
" mov $0x11, %al \n"
" outb %al, $0x80 \n"
/* Load our 16 it idt */
" xor %ax, %ax \n"
" mov %ax, %ds \n"
" lidt __myidt \n"
/* Dump zeros in the other segregs */
" mov %ax, %es \n"
" mov %ax, %fs \n"
" mov %ax, %gs \n"
" mov $0x40, %ax \n"
" mov %ax, %ds \n"
/* pop the INT # that you pushed earlier */
" popl %eax \n"
" pop %gs \n"
" pop %fs \n"
" pop %es \n"
" pop %ds \n"
" popal \n"
" iret \n"
" .code32 \n");
}
enum {
PCIBIOS = 0x1a,
MEMSIZE = 0x12
};
int pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
unsigned long *pecx, unsigned long *peax, unsigned long *pflags);
int handleint21(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
unsigned long *pecx, unsigned long *peax,
unsigned long *pflags);
extern void vga_exit(void);
int biosint(unsigned long intnumber,
unsigned long gsfs, unsigned long dses,
unsigned long edi, unsigned long esi,
unsigned long ebp, unsigned long esp,
unsigned long ebx, unsigned long edx,
unsigned long ecx, unsigned long eax,
unsigned long cs_ip, unsigned short stackflags)
{
unsigned long ip;
unsigned long cs;
unsigned long flags;
int ret = -1;
ip = cs_ip & 0xffff;
cs = cs_ip >> 16;
flags = stackflags;
printk_debug("biosint: INT# 0x%lx\n", intnumber);
printk_debug("biosint: eax 0x%lx ebx 0x%lx ecx 0x%lx edx 0x%lx\n",
eax, ebx, ecx, edx);
printk_debug("biosint: ebp 0x%lx esp 0x%lx edi 0x%lx esi 0x%lx\n",
ebp, esp, edi, esi);
printk_debug("biosint: ip 0x%x cs 0x%x flags 0x%x\n",
ip, cs, flags);
// cases in a good compiler are just as good as your own tables.
switch (intnumber) {
case 0 ... 15:
// These are not BIOS service, but the CPU-generated exceptions
printk_info("biosint: Oops, exception %u\n", intnumber);
if (esp < 0x1000) {
printk_debug("Stack contents: ");
while (esp < 0x1000) {
printk_debug("0x%04x ", *(unsigned short *)esp);
esp += 2;
}
printk_debug("\n");
}
printk_debug("biosint: Bailing out\n");
// "longjmp"
vga_exit();
break;
case PCIBIOS:
ret = pcibios(&edi, &esi, &ebp, &esp,
&ebx, &edx, &ecx, &eax, &flags);
break;
case MEMSIZE:
// who cares.
eax = 64 * 1024;
ret = 0;
break;
case 0x15:
ret = handleint21(&edi, &esi, &ebp, &esp,
&ebx, &edx, &ecx, &eax, &flags);
break;
default:
printk_info("BIOSINT: Unsupport int #0x%x\n", intnumber);
break;
}
if (ret)
flags |= 1; // carry flags
else
flags &= ~1;
stackflags = flags;
return ret;
}
void setup_realmode_idt(void)
{
extern unsigned char idthandle, end_idthandle;
extern unsigned char debughandle, end_debughandle;
int i;
struct realidt *idts = (struct realidt *)0;
int codesize = &end_idthandle - &idthandle;
unsigned char *intbyte, *codeptr;
// for each int, we create a customized little handler
// that just pushes %ax, puts the int # in %al,
// then calls the common interrupt handler.
// this necessitated because intel didn't know much about
// architecture when they did the 8086 (it shows)
// (hmm do they know anymore even now :-)
// obviously you can see I don't really care about memory
// efficiency. If I did I would probe back through the stack
// and get it that way. But that's really disgusting.
for (i = 0; i < 256; i++) {
idts[i].cs = 0;
codeptr = (unsigned char *)4096 + i * codesize;
idts[i].offset = (unsigned)codeptr;
memcpy(codeptr, &idthandle, codesize);
intbyte = codeptr + 3;
*intbyte = i;
}
// fixed entry points
// VGA BIOSes tend to hardcode f000:f065 as the previous handler of
// int10.
// calling convention here is the same as INTs, we can reuse
// the int entry code.
codeptr = (unsigned char *)0xff065;
memcpy(codeptr, &idthandle, codesize);
intbyte = codeptr + 3;
*intbyte = 0x42; /* int42 is the relocated int10 */
// VIA's VBIOS will call f000:f859 instead of sending int15.
codeptr = (unsigned char *)0xff859;
memcpy(codeptr, &idthandle, codesize);
intbyte = codeptr + 3;
*intbyte = 0x15;
/* debug handler - useful to set a programmable delay between instructions if the
TF bit is set upon call to real mode */
idts[1].cs = 0;
idts[1].offset = 16384;
memcpy((void *)16384UL, &debughandle, &end_debughandle - &debughandle);
}
enum {
CHECK = 0xb001,
FINDDEV = 0xb102,
READCONFBYTE = 0xb108,
READCONFWORD = 0xb109,
READCONFDWORD = 0xb10a,
WRITECONFBYTE = 0xb10b,
WRITECONFWORD = 0xb10c,
WRITECONFDWORD = 0xb10d
};
// errors go in AH. Just set these up so that word assigns
// will work. KISS.
enum {
PCIBIOS_NODEV = 0x8600,
PCIBIOS_BADREG = 0x8700
};
int
pcibios(unsigned long *pedi, unsigned long *pesi, unsigned long *pebp,
unsigned long *pesp, unsigned long *pebx, unsigned long *pedx,
unsigned long *pecx, unsigned long *peax, unsigned long *pflags)
{
unsigned short func = (unsigned short)(*peax);
int retval = 0;
unsigned short devid, vendorid, devfn;
short devindex; /* Use short to get rid of garbage in upper half of 32-bit register */
unsigned char bus;
device_t dev;
switch (func) {
case CHECK:
*pedx = 0x4350;
*pecx = 0x2049;
retval = 0;
break;
case FINDDEV:
{
devid = *pecx;
vendorid = *pedx;
devindex = *pesi;
dev = 0;
while ((dev = dev_find_device(vendorid, devid, dev))) {
if (devindex <= 0)
break;
devindex--;
}
if (dev) {
unsigned short busdevfn;
*peax = 0;
// busnum is an unsigned char;
// devfn is an int, so we mask it off.
busdevfn = (dev->bus->secondary << 8)
| (dev->path.pci.devfn & 0xff);
printk_debug("0x%x: return 0x%x\n", func,
busdevfn);
*pebx = busdevfn;
retval = 0;
} else {
*peax = PCIBIOS_NODEV;
retval = -1;
}
}
break;
case READCONFDWORD:
case READCONFWORD:
case READCONFBYTE:
case WRITECONFDWORD:
case WRITECONFWORD:
case WRITECONFBYTE:
{
unsigned long dword;
unsigned short word;
unsigned char byte;
unsigned char reg;
devfn = *pebx & 0xff;
bus = *pebx >> 8;
reg = *pedi;
dev = dev_find_slot(bus, devfn);
if (!dev) {
printk_debug
("0x%x: BAD DEVICE bus %d devfn 0x%x\n",
func, bus, devfn);
// idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
*peax = PCIBIOS_BADREG;
retval = -1;
}
switch (func) {
case READCONFBYTE:
byte = pci_read_config8(dev, reg);
*pecx = byte;
break;
case READCONFWORD:
word = pci_read_config16(dev, reg);
*pecx = word;
break;
case READCONFDWORD:
dword = pci_read_config32(dev, reg);
*pecx = dword;
break;
case WRITECONFBYTE:
byte = *pecx;
pci_write_config8(dev, reg, byte);
break;
case WRITECONFWORD:
word = *pecx;
pci_write_config16(dev, reg, word);
break;
case WRITECONFDWORD:
dword = *pecx;
pci_write_config32(dev, reg, dword);
break;
}
if (retval)
retval = PCIBIOS_BADREG;
printk_debug
("0x%x: bus %d devfn 0x%x reg 0x%x val 0x%lx\n",
func, bus, devfn, reg, *pecx);
*peax = 0;
retval = 0;
}
break;
default:
printk_err("UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
break;
}
return retval;
}
int handleint21(unsigned long *edi, unsigned long *esi, unsigned long *ebp,
unsigned long *esp, unsigned long *ebx, unsigned long *edx,
unsigned long *ecx, unsigned long *eax, unsigned long *flags)
{
int res = -1;
switch (*eax & 0xffff) {
case 0x5f19:
break;
case 0x5f18:
*eax = 0x5f;
*ebx = 0x545; // MCLK = 133, 32M frame buffer, 256 M main memory
*ecx = 0x060;
res = 0;
break;
case 0x5f00:
*eax = 0x8600;
break;
case 0x5f01:
*eax = 0x5f;
*ecx = (*ecx & 0xffffff00) | 2; // panel type = 2 = 1024 * 768
res = 0;
break;
case 0x5f02:
*eax = 0x5f;
*ebx = (*ebx & 0xffff0000) | 2;
*ecx = (*ecx & 0xffff0000) | 0x401; // PAL + crt only
*edx = (*edx & 0xffff0000) | 0; // TV Layout - default
res = 0;
break;
case 0x5f0f:
*eax = 0x860f;
break;
}
return res;
}

View File

@ -1,6 +1,6 @@
#include <arch/io.h>
void udelay(int usecs)
void udelay(unsigned usecs)
{
int i;
for(i = 0; i < usecs; i++)

View File

@ -0,0 +1,44 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of the License.
##
## 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 will make a target directory of ./VENDOR_MAINBOARD
# build a single image coreboot. Only Fallback, no normal.
target VENDOR_MAINBOARD
mainboard VENDOR/MAINBOARD
option CC="CROSSCC"
option CROSS_COMPILE="CROSS_PREFIX"
option HOSTCC="CROSS_HOSTCC"
option ROM_SIZE=(512-64)*1024
option FALLBACK_SIZE=(512-64)*1024
__COMPRESSION__
romimage "fallback"
option USE_FALLBACK_IMAGE=1
option ROM_IMAGE_SIZE=0x15000
option COREBOOT_EXTRA_VERSION=".0-fallback"
payload __PAYLOAD__
end
buildrom ./coreboot.rom ROM_SIZE "fallback"

View File

@ -0,0 +1,45 @@
##
## This file is part of the coreboot project.
##
## Copyright (C) 2007-2009 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; version 2 of the License.
##
## 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 file for VIA VT8454c mainboard
#
target via_vt8454c
mainboard via/vt8454c
option MAXIMUM_CONSOLE_LOGLEVEL=5
option DEFAULT_CONSOLE_LOGLEVEL=5
option ROM_SIZE=(512-64)*1024
romimage "normal"
option USE_FALLBACK_IMAGE=0
option ROM_IMAGE_SIZE=0x14000
option COREBOOT_EXTRA_VERSION=".0-normal"
payload $(HOME)/payload.elf
end
romimage "fallback"
option USE_FALLBACK_IMAGE=1
option ROM_IMAGE_SIZE=0x14000
option COREBOOT_EXTRA_VERSION=".0-fallback"
payload $(HOME)/payload.elf
end
buildrom ./coreboot.rom ROM_SIZE "normal" "fallback"